diff options
| -rw-r--r-- | Documentation/DocBook/Makefile | 5 | ||||
| -rw-r--r-- | Documentation/DocBook/scsidrivers.tmpl | 172 | ||||
| -rw-r--r-- | drivers/scsi/scsi_mid_low_api.txt | 535 |
3 files changed, 711 insertions, 1 deletions
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index 2e0281850aa2..d33c40c3187c 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -2,7 +2,7 @@ BOOKS := wanbook.sgml z8530book.sgml mcabook.sgml videobook.sgml \ kernel-api.sgml parportbook.sgml kernel-hacking.sgml \ kernel-locking.sgml via-audio.sgml mousedrivers.sgml sis900.sgml \ deviceiobook.sgml procfs-guide.sgml tulip-user.sgml \ - writing_usb_driver.sgml + writing_usb_driver.sgml scsidrivers.sgml PS := $(patsubst %.sgml, %.ps, $(BOOKS)) PDF := $(patsubst %.sgml, %.pdf, $(BOOKS)) @@ -69,6 +69,9 @@ tulip-user.sgml: tulip-user.tmpl writing_usb_driver.sgml: writing_usb_driver.tmpl $(TOPDIR)/scripts/docgen <$< >$@ +scsidrivers.sgml : scsidrivers.tmpl + $(TOPDIR)/scripts/docgen <$< >$@ + sis900.sgml: sis900.tmpl $(TOPDIR)/drivers/net/sis900.c $(TOPDIR)/scripts/docgen $(TOPDIR)/drivers/net/sis900.c \ <sis900.tmpl >sis900.sgml diff --git a/Documentation/DocBook/scsidrivers.tmpl b/Documentation/DocBook/scsidrivers.tmpl new file mode 100644 index 000000000000..b4549c1454e3 --- /dev/null +++ b/Documentation/DocBook/scsidrivers.tmpl @@ -0,0 +1,172 @@ +<!-- -*- sgml -*- --> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN"[]> + +<book id="scsidrivers"> + <bookinfo> + <title>SCSI Subsystem Interfaces</title> + + <authorgroup> + <author> + <firstname>Douglas</firstname> + <surname>Gilbert</surname> + <affiliation> + <address> + <email>dgilbert@interlog.com</email> + </address> + </affiliation> + </author> + </authorgroup> + <pubdate>2002-04-27</pubdate> + + <copyright> + <year>2002</year> + <holder>Douglas Gilbert</holder> + </copyright> + <legalnotice> + <para> + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.1 or any later version published by the Free Software + Foundation; with no Invariant Sections, with no Front-Cover Texts, + and with no Back-Cover Texts. A copy of the license is included + in the section entitled "GNU Free Documentation License". + </para> + </legalnotice> + + </bookinfo> + +<toc></toc> + + <chapter id="intro"> + <title>Introduction</title> + <para> +This document outlines the interface between the Linux scsi mid level +and lower level drivers. Lower level drivers are variously called HBA +(host bus adapter) drivers, host drivers (HD) or pseudo adapter drivers. +The latter alludes to the fact that a lower level driver may be a +bridge to another IO subsystem (and the "ide-scsi" driver is an example +of this). There can be many lower level drivers active in a running +system, but only one per hardware type. For example, the aic7xxx driver +controls adaptec controllers based on the 7xxx chip series. Most lower +level drivers can control one or more scsi hosts (a.k.a. scsi initiators). + </para> +<para> +This document can been found in an ASCII text file in the linux kernel +source: <filename>drivers/scsi/scsi_mid_low_api.txt</filename> . +It currently hold a little more information than this document. The +<filename>drivers/scsi/hosts.h</filename> and <filename> +drivers/scsi/scsi.h</filename> headers contain descriptions of members +of important structures for the scsi subsystem. +</para> + </chapter> + + <chapter id="driver_struct"> + <title>Driver structure</title> + <para> +Traditionally a lower level driver for the scsi subsystem has been +at least two files in the drivers/scsi directory. For example, a +driver called "xyz" has a header file "xyz.h" and a source file +"xyz.c". [Actually there is no good reason why this couldn't all +be in one file.] Some drivers that have been ported to several operating +systems (e.g. aic7xxx which has separate files for generic and +OS-specific code) have more than two files. Such drivers tend to have +their own directory under the drivers/scsi directory. + </para> + <para> +scsi_module.c is normally included at the end of a lower +level driver. For it to work a declaration like this is needed before +it is included: +<programlisting> + static Scsi_Host_Template driver_template = DRIVER_TEMPLATE; + /* DRIVER_TEMPLATE should contain pointers to supported interface + functions. Scsi_Host_Template is defined hosts.h */ + #include "scsi_module.c" +</programlisting> + </para> + <para> +The scsi_module.c assumes the name "driver_template" is appropriately +defined. It contains 2 functions: +<orderedlist> +<listitem><para> + init_this_scsi_driver() called during builtin and module driver + initialization: invokes mid level's scsi_register_host() +</para></listitem> +<listitem><para> + exit_this_scsi_driver() called during closedown: invokes + mid level's scsi_unregister_host() +</para></listitem> +</orderedlist> + </para> +<para> +When a new, lower level driver is being added to Linux, the following +files (all found in the drivers/scsi directory) will need some attention: +Makefile, Config.help and Config.in . It is probably best to look at what +an existing lower level driver does in this regard. +</para> + </chapter> + + <chapter id="intfunctions"> + <title>Interface Functions</title> +!Edrivers/scsi/scsi_mid_low_api.txt + </chapter> + + <chapter id="locks"> + <title>Locks</title> +<para> +Each Scsi_Host instance has a spin_lock called Scsi_Host::default_lock +which is initialized in scsi_register() [found in hosts.c]. Within the +same function the Scsi_Host::host_lock pointer is initialized to point +at default_lock with the scsi_assign_lock() function. Thereafter +lock and unlock operations performed by the mid level use the +Scsi_Host::host_lock pointer. +</para> +<para> +Lower level drivers can override the use of Scsi_Host::default_lock by +using scsi_assign_lock(). The earliest opportunity to do this would +be in the detect() function after it has invoked scsi_register(). It +could be replaced by a coarser grain lock (e.g. per driver) or a +lock of equal granularity (i.e. per host). Using finer grain locks +(e.g. per scsi device) may be possible by juggling locks in +queuecommand(). +</para> + </chapter> + + <chapter id="changes"> + <title>Changes since lk 2.4 series</title> +<para> +io_request_lock has been replaced by several finer grained locks. The lock +relevant to lower level drivers is Scsi_Host::host_lock and there is one +per scsi host. +</para> +<para> +The older error handling mechanism has been removed. This means the +lower level interface functions abort() and reset() have been removed. +</para> +<para> +In the 2.4 series the scsi subsystem configuration descriptions were +aggregated with the configuration descriptions from all other Linux +subsystems in the Documentation/Configure.help file. In the 2.5 series, +the scsi subsystem now has its own (much smaller) drivers/scsi/Config.help +file. +</para> + </chapter> + + <chapter id="credits"> + <title>Credits</title> +<para> +The following people have contributed to this document: +<orderedlist> +<listitem><para> +Mike Anderson <email>andmike@us.ibm.com</email> +</para></listitem> +<listitem><para> +James Bottomley <email>James.Bottomley@steeleye.com</email> +</para></listitem> +<listitem><para> +Patrick Mansfield <email>patmans@us.ibm.com</email> +</para></listitem> +</orderedlist> +</para> + </chapter> + +</book> diff --git a/drivers/scsi/scsi_mid_low_api.txt b/drivers/scsi/scsi_mid_low_api.txt new file mode 100644 index 000000000000..8af86db6d3f2 --- /dev/null +++ b/drivers/scsi/scsi_mid_low_api.txt @@ -0,0 +1,535 @@ + Linux Kernel 2.5 series + SCSI mid_level - lower_level interface + ====================================== + +Introduction +============ +This document outlines the interface between the Linux scsi mid level +and lower level drivers. Lower level drivers are variously called HBA +(host bus adapter) drivers, host drivers (HD) or pseudo adapter drivers. +The latter alludes to the fact that a lower level driver may be a +bridge to another IO subsystem (and the "ide-scsi" driver is an example +of this). There can be many lower level drivers active in a running +system, but only one per hardware type. For example, the aic7xxx driver +controls adaptec controllers based on the 7xxx chip series. Most lower +level drivers can control one or more scsi hosts (a.k.a. scsi initiators). + +The Linux kernel source Documentation/DocBook/scsidrivers.tmpl file +refers to this file. With the appropriate DocBook toolset, this permits +users to generate html, ps and pdf renderings of information within this +file (e.g. the interface functions). + +Driver structure +================ +Traditionally a lower level driver for the scsi subsystem has been +at least two files in the drivers/scsi directory. For example, a +driver called "xyz" has a header file "xyz.h" and a source file +"xyz.c". [Actually there is no good reason why this couldn't all +be in one file.] Some drivers that have been ported to several operating +systems (e.g. aic7xxx which has separate files for generic and +OS-specific code) have more than two files. Such drivers tend to have +their own directory under the drivers/scsi directory. + +scsi_module.c is normally included at the end of a lower +level driver. For it to work a declaration like this is needed before +it is included: + static Scsi_Host_Template driver_template = DRIVER_TEMPLATE; + /* DRIVER_TEMPLATE should contain pointers to supported interface + functions. Scsi_Host_Template is defined in hosts.h */ + #include "scsi_module.c" + +The scsi_module.c assumes the name "driver_template" is appropriately +defined. It contains 2 functions: + 1) init_this_scsi_driver() called during builtin and module driver + initialization: invokes mid level's scsi_register_host() + 2) exit_this_scsi_driver() called during closedown: invokes + mid level's scsi_unregister_host() + +When a new, lower level driver is being added to Linux, the following +files (all found in the drivers/scsi directory) will need some attention: +Makefile, Config.help and Config.in . It is probably best to look at what +an existing lower level driver does in this regard. + + + +Interface Functions +=================== +Interface functions should be declared static. The accepted convention +is that driver "xyz" will declare its detect() function as: + static int xyz_detect(Scsi_Host_Template * shtp); + +A pointer to this function should be placed in the 'detect' member of +a Scsi_Host_Template instance. A pointer to such an instance should +passed to the mid level's scsi_register_host(). + +The interface functions are listed below in alphabetical order. + + +/** + * bios_param - fetch head, sector, cylinder info for a disk + * @sdkp: pointer to disk structure (defined in sd.h) + * @dev: corresponds to dev_t of device file name (e.g. /dev/sdb) + * @params: three element array to place output: + * params[0] number of heads + * params[1] number of sectors + * params[2] number of cylinders + * + * Return value is ignored + * + * Required: no + * + * Locks: none + * + * Notes: sd driver will make up geometry (based on READ CAPACITY) + * if this function is not provided. The params array is + * pre-initialized with made up values just in case this function + * doesn't output anything. + **/ + int bios_param(Scsi_Disk * sdkp, kdev_t dev, int params[3]); + + +/** + * command - send scsi command to device, wait for reply + * @scp: pointer to scsi command object + * + * Returns an int with four component bytes: scsi_byte, msg_byte, + * host_byte, driver_byte (status_byte is in the lsb). A value of + * 0 is an unqualified success. + * + * Required: if Scsi_Host::can_queue can ever by cleared (zero) + * then this function is required. + * + * Locks: Scsi_Host::host_lock held on entry (with "irqsave") and + * is expected to be held on return. + * + * Notes: Drivers tend to be dropping support for this function and + * rather supporting queuecommand(). + **/ + int command(Scsi_Cmnd * scp); + + +/** + * detect - detects HBAs this driver wants to control + * @shtp: host template for this driver. + * + * Returns number of hosts this driver wants to control. 0 means no + * suitable hosts found. + * + * Required: yes + * + * Locks: none held + * + * Notes: First function called from the scsi mid level on this + * driver. Upper level drivers (e.g. sd) may not (yet) be present. + * For each host found, this method should call scsi_register() + * [see hosts.c]. + **/ + int detect(Scsi_Host_Template * shtp); + + +/** + * eh_abort_handler - abort command associated with scp + * @scp: identifies command to be aborted + * + * Returns SUCCESS if command aborted else FAILED + * + * Required: no + * + * Locks: Scsi_Host::host_lock held (with irqsave) on entry and assumed + * to be held on return. + * + * Notes: Invoked from scsi_eh thread. No other commands will be + * queued on current host during eh. + **/ + int eh_abort_handler(Scsi_Cmnd * scp); + + +/** + * eh_device_reset_handler - issue scsi device reset + * @scp: identifies scsi device to be reset + * + * Returns SUCCESS if command aborted else FAILED + * + * Required: no + * + * Locks: Scsi_Host::host_lock held (with irqsave) on entry and assumed + * to be held on return. + * + * Notes: Invoked from scsi_eh thread. No other commands will be + * queued on current host during eh. + **/ + int eh_device_reset_handler(Scsi_Cmnd * scp); + + +/** + * eh_bus_reset_handler - issue scsi bus reset + * @scp: scsi bus that contains this device should be reset + * + * Returns SUCCESS if command aborted else FAILED + * + * Required: no + * + * Locks: Scsi_Host::host_lock held (with irqsave) on entry and assumed + * to be held on return. + * + * Notes: Invoked from scsi_eh thread. No other commands will be + * queued on current host during eh. + **/ + int eh_bus_reset_handler(Scsi_Cmnd * scp); + + +/** + * eh_host_reset_handler - reset host (host bus adapter) + * @scp: scsi host that contains this device should be reset + * + * Returns SUCCESS if command aborted else FAILED + * + * Required: no + * + * Locks: Scsi_Host::host_lock held (with irqsave) on entry and assumed + * to be held on return. + * + * Notes: Invoked from scsi_eh thread. No other commands will be + * queued on current host during eh. + * With the default eh_strategy in place, if none of the _abort_, + * _device_reset_, _bus_reset_ or this eh handler function are + * defined (or they all return FAILED) then the device in question + * will be set offline whenever eh is invoked. + **/ + int eh_host_reset_handler(Scsi_Cmnd * scp); + + +/** + * eh_strategy_handler - driver supplied alternate to scsi_unjam_host() + * @shp: host on which error has occurred + * + * Returns TRUE if host unjammed, else FALSE. + * + * Required: no + * + * Locks: none + * + * Notes: Invoked from scsi_eh thread. Driver supplied alternate to + * scsi_unjam_host() found in scsi_error.c + **/ + int eh_strategy_handler(struct Scsi_Host * shp); + + +/** + * info - supply information about given host: driver name plus data + * to distinguish given host + * @shp: host to supply information about + * + * Return ASCII null terminated string. [This driver is assumed to + * manage the memory pointed to and maintain it, typically for the + * lifetime of this host.] + * + * Required: no + * + * Locks: none + * + * Notes: Often supplies PCI or ISA information such as IO addresses + * and interrupt numbers. If not supplied Scsi_Host::name used + * instead. It is assumed the returned information fits on one line + * (i.e. does not included embedded newlines). + * The SCSI_IOCTL_PROBE_HOST ioctl yields the string returned by this + * function (or Scsi_Host::name if this function is not available). + * In a similar manner, scsi_register_host() outputs to the console + * each host's "info" (or name) for the driver it is registering. + * Also if proc_info() is not supplied, the output of this function + * is used instead. + **/ + const char * info(struct Scsi_Host * shp); + + +/** + * ioctl - driver can respond to ioctls + * @sdp: device that ioctl was issued for + * @cmd: ioctl number + * @arg: pointer to read or write data from. Since it points to + * user space, should use appropriate kernel functions + * (e.g. copy_from_user() ). In the Unix style this argument + * can also be viewed as an unsigned long. + * + * Returns negative "errno" value when there is a problem. 0 or a + * positive value indicates success and is returned to the user space. + * + * Required: no + * + * Locks: none + * + * Notes: The scsi subsystem uses a "trickle down" ioctl model. + * The user issues an ioctl() against an upper level driver + * (e.g. /dev/sdc) and if the upper level driver doesn't recognize + * the 'cmd' then it is passed to the scsi mid level. If the scsi + * mid level does not recognize it, then the lower driver that controls + * the device receives the ioctl. According to recent Unix standards + * unsupported ioctl() 'cmd' numbers should return -ENOTTY. + * However the mid level returns -EINVAL for unrecognized 'cmd' + * numbers when this function is not supplied by the driver. + **/ + int ioctl(Scsi_Device *sdp, int cmd, void *arg); + + +/** + * proc_info - supports /proc/scsi/{driver_name}/{host_no} + * @buffer: anchor point to output to (0==writeto1_read0) or fetch from + * (1==writeto1_read0). + * @start: where "interesting" data is written to. Ignored when + * 1==writeto1_read0. + * @offset: offset within buffer 0==writeto1_read0 is actually + * interested in. Ignored when 1==writeto1_read0 . + * @length: maximum (or actual) extent of buffer + * @host_no: host number of interest (Scsi_Host::host_no) + * @writeto1_read0: 1 -> data coming from user space towards driver + * (e.g. "echo some_string > /proc/scsi/xyz/2") + * 0 -> user what data from this driver + * (e.g. "cat /proc/scsi/xyz/2") + * + * Returns length when 1==writeto1_read0. Otherwise number of chars + * output to buffer past offset. + * + * Required: no + * + * Locks: none held + * + * Notes: Driven from scsi_proc.c which interfaces to proc_fs + **/ +int proc_info(char * buffer, char ** start, off_t offset, + int length, int hostno, int writeto1_read0); + + +/** + * queuecommand - queue scsi command, invoke 'done' on completion + * @scp: pointer to scsi command object + * @done: function pointer to be invoked on completion + * + * Returns 1 if the adapter is busy, else returns 0. + * + * Required: if Scsi_Host::can_queue is ever non-zero + * then this function is required. + * + * Locks: Scsi_Host::host_lock held on entry (with "irqsave") and + * is expected to be held on return. + * + * Notes: This function should be relatively fast. Normally it will + * not wait for IO to complete. Hence the 'done' callback is invoked + * (often directly from an interrupt service routine) sometime after + * this command has returned. In some cases (e.g. pseudo adapter + * drivers that manufacture the response to a scsi INQUIRY) + * the 'done' callback may be invoked before this function returns. + * If the 'done' callback is not invoked within a certain period + * the scsi mid level will commence error processing. + * The integer with 4 component bytes that command() uses as its + * return value should be generated by this function. However, in + * this case, it should be placed in scp->result before this function + * returns. + **/ + int queuecommand(Scsi_Cmnd * scp, void (*done)(Scsi_Cmnd *)); + + +/** + * release - release all resources associated with given host + * @shp: host to be released. + * + * Return value ignored. + * + * Required: no + * + * Locks: lock_kernel() active on entry and expected to be active + * on return. + * + * Notes: Invoked from mid level's scsi_unregister_host(). When a + * host is being unregistered the mid level does not bother to + * call revoke() on the devices it controls. + * This function should call scsi_unregister(shp) [found in hosts.c] + * prior to returning. + **/ + int release(struct Scsi_Host * shp); + + +/** + * revoke - indicate disinterest in a scsi device + * @sdp: host template for this driver. + * + * Return value ignored. + * + * Required: no + * + * Locks: none held + * + * Notes: Called when "scsi remove-single-device <h> <b> <t> <l>" + * is written to /proc/scsi/scsi to indicate the device is no longer + * required. It is called after the upper level drivers have detached + * this device and before the device name (e.g. /dev/sdc) is + * unregistered and the resources associated with it are freed. + **/ + int revoke(Scsi_device * sdp); + + +/** + * select_queue_depths - calculate allowable number of scsi commands + * that can be queued on each device (disk) + * on the given host + * @shp: host containing device + * @sdp: first device to examine [start of list] + * + * Returns nothing + * + * Required: no + * + * Locks: none + * + * Notes: This function should examine all devices on the given host. + * The next device can be fetched with sdp->next (NULL when finished). + * Queue depths should be placed in Scsi_Device::queue_depth . + **/ + void select_queue_depths(struct Scsi_Host * shp, Scsi_Device * sdp); + + +Data Structures +=============== +Scsi_Host_Template +------------------ +There is one Scsi_Host_Template instance per lower level driver. It is +typically initialized as a file scope static in a driver's header file. That +way members that are not explicitly initialized will be set to 0 or NULL. +Member of interest: + name - name of driver (should only use characters that are + permitted in a unix file name) + proc_name - name used in "/proc/scsi/<proc_name>/<host_no>" +The structure is defined and commented in hosts.h + +Scsi_Host +--------- +There is one Scsi_Host instance per host (HBA) that a lower level driver +controls. The Scsi_Host structure has many members in common with the +Scsi_Host_Template. When a new Scsi_Host instance is created (in +scsi_register() in hosts.c) those common members are initialized from +the driver's Scsi_Host_Template instance. Members of interest: + host_no - system wide unique number that is used for identifying + this host. Issued in ascending order from 0 (and the + positioning can be influenced by the scsihosts + kernel boot (or module) parameter) + can_queue - 0->use command(), greater than 0->use queuecommand() and do + not send more than can_queue commands to the adapter. + this_id - scsi id of host (scsi initiator) or -1 if not known + sg_tablesize - maximum scatter gather elements allowed by host. + 0 implies scatter gather not supported by host + max_sectors - maximum number of sectors (usually 512 bytes) allowed + in a single scsi command. 0 implies no maximum. + cmd_per_lun - maximum number of command that can be queued on devices + controlled by the host. Used if select_queue_depths() + not defined or yields 0. + unchecked_isa_dma - 1->only use bottom 16 MB of ram (ISA DMA addressing + restriction), 0->can use full 32 bit (or better) DMA + address space + use_clustering - 1->scsi commands in mid level's queue can be merged, + 0->disallow scsi command merging + highmem_io - 1->can DMA in to or out of high memory, + 0->use bounce buffers if data is in high memory + hostt - pointer to driver's Scsi_Host_Template from which this + Scsi_Host instance was spawned + host_queue - deceptively named pointer to the start of a double linked + list of Scsi_Device instances that belong to this host. +The structure is defined in hosts.h + +Scsi_Device +----------- +Generally, there is one instance of this structure for each scsi logical unit +on a host. Scsi devices are uniquely identified within a host by bus number, +target id and logical unit number (lun). +The structure is defined in scsi.h + +Scsi_Cmnd +--------- +Instances of this structure convey scsi commands to the lower level +driver. Each scsi device has a pool of Scsi_Cmnd instances whose size +is determined by select_queue_depths (or Scsi_Host::cmd_per_lun). There +will be at least one instance of Scsi_Cmnd for each scsi device. +The structure is defined in scsi.h + +Scsi_Disk +--------- +It is a bit strange that this structure is exposed to a lower level +driver in the bios_param() function. It is defined in sd.h and is only +relevant to the sd upper level driver. The sd driver invokes bios_param() +is response to the HD_GETGEO and HD_GETGEO_BIG ioctls. + + +Flow of control during initialization +===================================== + +Lower level driver mid level +------------------ --------- + +init_this_scsi_driver() [1] -----+ + <scsi_modules.c> | + v + scsi_register_host() + | +detect() [2] <--+ + | +queuecommand()** [3] <--+ + | +select_queue_depths()* <--+ + + +Notes +----- +[1] invoked during kernel initialization when built in or during module + initialization. The scsi mid level will already be initialized. +[2] detect() calls scsi_register() for each HBA it wants to control + (if not, scsi_register_host() will do it instead) +[3] called as part of scsi bus scan during discovery of devices. This scan + will be done for each host. Scsi commands such as INQUIRY, MODE SENSE + and REPORT LUNS will be sent during device discovery +* invoked for each host controlled by the lower level driver +** invoked for each device of each host controlled by the driver + + +Locks +===== +Each Scsi_Host instance has a spin_lock called Scsi_Host::default_lock +which is initialized in scsi_register() [found in hosts.c]. Within the +same function the Scsi_Host::host_lock pointer is initialized to point +at default_lock with the scsi_assign_lock() function. Thereafter +lock and unlock operations performed by the mid level use the +Scsi_Host::host_lock pointer. + +Lower level drivers can override the use of Scsi_Host::default_lock by +using scsi_assign_lock(). The earliest opportunity to do this would +be in the detect() function after it has invoked scsi_register(). It +could be replaced by a coarser grain lock (e.g. per driver) or a +lock of equal granularity (i.e. per host). Using finer grain locks +(e.g. per scsi device) may be possible by juggling locks in +queuecommand(). + + +Changes since lk 2.4 series +=========================== +io_request_lock has been replaced by several finer grained locks. The lock +relevant to lower level drivers is Scsi_Host::host_lock and there is one +per scsi host. + +The older error handling mechanism has been removed. This means the +lower level interface functions abort() and reset() have been removed. + +In the 2.4 series the scsi subsystem configuration descriptions were +aggregated with the configuration descriptions from all other Linux +subsystems in the Documentation/Configure.help file. In the 2.5 series, +the scsi subsystem now has its own (much smaller) drivers/scsi/Config.help +file. + + +Credits +======= +The following people have contributed to this document: + Mike Anderson <andmike@us.ibm.com> + James Bottomley <James.Bottomley@steeleye.com> + Patrick Mansfield <patmans@us.ibm.com> + + +Douglas Gilbert +dgilbert@interlog.com +27th April 2002 |
