aboutsummaryrefslogtreecommitdiff
path: root/Documentation/scsi/scsi_mid_low_api.txt
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/scsi/scsi_mid_low_api.txt')
-rw-r--r--Documentation/scsi/scsi_mid_low_api.txt232
1 files changed, 95 insertions, 137 deletions
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
index 7536823c0cb..d6a9bdeee7f 100644
--- a/Documentation/scsi/scsi_mid_low_api.txt
+++ b/Documentation/scsi/scsi_mid_low_api.txt
@@ -30,7 +30,7 @@ the motherboard (or both). Some aic7xxx based HBAs are dual controllers
and thus represent two hosts. Like most modern HBAs, each aic7xxx host
has its own PCI device address. [The one-to-one correspondence between
a SCSI host and a PCI device is common but not required (e.g. with
-ISA or MCA adapters).]
+ISA adapters).]
The SCSI mid level isolates an LLD from other layers such as the SCSI
upper layer drivers and the block layer.
@@ -43,7 +43,7 @@ There is a SCSI documentation directory within the kernel source tree,
typically Documentation/scsi . Most documents are in plain
(i.e. ASCII) text. This file is named scsi_mid_low_api.txt and can be
found in that directory. A more recent copy of this document may be found
-at http://www.torque.net/scsi/scsi_mid_low_api.txt.gz .
+at http://web.archive.org/web/20070107183357rn_1/sg.torque.net/scsi/.
Many LLDs are documented there (e.g. aic7xxx.txt). The SCSI mid-level is
briefly described in scsi.txt which contains a url to a document
describing the SCSI subsystem in the lk 2.4 series. Two upper level
@@ -55,11 +55,6 @@ or in the same directory as the C source code. For example to find a url
about the USB mass storage driver see the
/usr/src/linux/drivers/usb/storage directory.
-The Linux kernel source Documentation/DocBook/scsidrivers.tmpl file
-refers to this file. With the appropriate DocBook tool-set, this permits
-users to generate html, ps and pdf renderings of information within this
-file (e.g. the interface functions).
-
Driver structure
================
Traditionally an LLD for the SCSI subsystem has been at least two files in
@@ -150,7 +145,8 @@ scsi devices of which only the first 2 respond:
LLD mid level LLD
===-------------------=========--------------------===------
scsi_host_alloc() -->
-scsi_add_host() --------+
+scsi_add_host() ---->
+scsi_scan_host() -------+
|
slave_alloc()
slave_configure() --> scsi_adjust_queue_depth()
@@ -196,7 +192,7 @@ of the issues involved. See the section on reference counting below.
The hotplug concept may be extended to SCSI devices. Currently, when an
-HBA is added, the scsi_add_host() function causes a scan for SCSI devices
+HBA is added, the scsi_scan_host() function causes a scan for SCSI devices
attached to the HBA's SCSI transport. On newer SCSI transports the HBA
may become aware of a new SCSI device _after_ the scan has completed.
An LLD can use this sequence to make the mid level aware of a SCSI device:
@@ -346,7 +342,7 @@ Next, there is a movement to "outlaw" typedefs introducing synonyms for
struct tags. Both can be still found in the SCSI subsystem, but
the typedefs have been moved to a single file, scsi_typedefs.h to
make their future removal easier, for example:
-"typedef struct scsi_host_template Scsi_Host_Template;"
+"typedef struct scsi_cmnd Scsi_Cmnd;"
Also, most C99 enhancements are encouraged to the extent they are supported
by the relevant gcc compilers. So C99 style structure and array
@@ -372,14 +368,11 @@ names all start with "scsi_".
Summary:
scsi_activate_tcq - turn on tag command queueing
scsi_add_device - creates new scsi device (lu) instance
- scsi_add_host - perform sysfs registration and SCSI bus scan.
- scsi_add_timer - (re-)start timer on a SCSI command.
+ scsi_add_host - perform sysfs registration and set up transport class
scsi_adjust_queue_depth - change the queue depth on a SCSI device
- scsi_assign_lock - replace default host_lock with given lock
scsi_bios_ptable - return copy of block device's partition table
scsi_block_requests - prevent further commands being queued to given host
scsi_deactivate_tcq - turn off tag command queueing
- scsi_delete_timer - cancel timer on a SCSI command.
scsi_host_alloc - return a new scsi_host instance whose refcount==1
scsi_host_get - increments Scsi_Host instance's refcount
scsi_host_put - decrements Scsi_Host instance's refcount (free if 0)
@@ -388,6 +381,7 @@ Summary:
scsi_remove_device - detach and remove a SCSI device
scsi_remove_host - detach and remove all SCSI devices owned by host
scsi_report_bus_reset - report scsi _bus_ reset observed
+ scsi_scan_host - scan SCSI bus
scsi_track_queue_full - track successive QUEUE_FULL events
scsi_unblock_requests - allow further commands to be queued to given host
scsi_unregister - [calls scsi_host_put()]
@@ -427,10 +421,10 @@ void scsi_activate_tcq(struct scsi_device *sdev, int depth)
* Might block: yes
*
* Notes: This call is usually performed internally during a scsi
- * bus scan when an HBA is added (i.e. scsi_add_host()). So it
+ * bus scan when an HBA is added (i.e. scsi_scan_host()). So it
* should only be called if the HBA becomes aware of a new scsi
- * device (lu) after scsi_add_host() has completed. If successful
- * this call we lead to slave_alloc() and slave_configure() callbacks
+ * device (lu) after scsi_scan_host() has completed. If successful
+ * this call can lead to slave_alloc() and slave_configure() callbacks
* into the LLD.
*
* Defined in: drivers/scsi/scsi_scan.c
@@ -441,7 +435,7 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
/**
- * scsi_add_host - perform sysfs registration and SCSI bus scan.
+ * scsi_add_host - perform sysfs registration and set up transport class
* @shost: pointer to scsi host instance
* @dev: pointer to struct device of type scsi class
*
@@ -450,7 +444,11 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
* Might block: no
*
* Notes: Only required in "hotplug initialization model" after a
- * successful call to scsi_host_alloc().
+ * successful call to scsi_host_alloc(). This function does not
+ * scan the bus; this can be done by calling scsi_scan_host() or
+ * in some other transport-specific way. The LLD must set up
+ * the transport template before calling this function and may only
+ * access the transport class data after this function has been called.
*
* Defined in: drivers/scsi/hosts.c
**/
@@ -458,27 +456,6 @@ int scsi_add_host(struct Scsi_Host *shost, struct device * dev)
/**
- * scsi_add_timer - (re-)start timer on a SCSI command.
- * @scmd: pointer to scsi command instance
- * @timeout: duration of timeout in "jiffies"
- * @complete: pointer to function to call if timeout expires
- *
- * Returns nothing
- *
- * Might block: no
- *
- * Notes: Each scsi command has its own timer, and as it is added
- * to the queue, we set up the timer. When the command completes,
- * we cancel the timer. An LLD can use this function to change
- * the existing timeout value.
- *
- * Defined in: drivers/scsi/scsi_error.c
- **/
-void scsi_add_timer(struct scsi_cmnd *scmd, int timeout,
- void (*complete)(struct scsi_cmnd *))
-
-
-/**
* scsi_adjust_queue_depth - allow LLD to change queue depth on a SCSI device
* @sdev: pointer to SCSI device to change queue depth on
* @tagged: 0 - no tagged queuing
@@ -506,20 +483,6 @@ void scsi_adjust_queue_depth(struct scsi_device * sdev, int tagged,
/**
- * scsi_assign_lock - replace default host_lock with given lock
- * @shost: a pointer to a scsi host instance
- * @lock: pointer to lock to replace host_lock for this host
- *
- * Returns nothing
- *
- * Might block: no
- *
- * Defined in: include/scsi/scsi_host.h .
- **/
-void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock)
-
-
-/**
* scsi_bios_ptable - return copy of block device's partition table
* @dev: pointer to block device
*
@@ -566,24 +529,6 @@ void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
/**
- * scsi_delete_timer - cancel timer on a SCSI command.
- * @scmd: pointer to scsi command instance
- *
- * Returns 1 if able to cancel timer else 0 (i.e. too late or already
- * cancelled).
- *
- * Might block: no [may in the future if it invokes del_timer_sync()]
- *
- * Notes: All commands issued by upper levels already have a timeout
- * associated with them. An LLD can use this function to cancel the
- * timer.
- *
- * Defined in: drivers/scsi/scsi_error.c
- **/
-int scsi_delete_timer(struct scsi_cmnd *scmd)
-
-
-/**
* scsi_host_alloc - create a scsi host adapter instance and perform basic
* initialization.
* @sht: pointer to scsi host template
@@ -600,7 +545,7 @@ int scsi_delete_timer(struct scsi_cmnd *scmd)
* area for the LLD's exclusive use.
* Both associated refcounting objects have their refcount set to 1.
* Full registration (in sysfs) and a bus scan are performed later when
- * scsi_add_host() is called.
+ * scsi_add_host() and scsi_scan_host() are called.
*
* Defined in: drivers/scsi/hosts.c .
**/
@@ -740,6 +685,19 @@ void scsi_report_bus_reset(struct Scsi_Host * shost, int channel)
/**
+ * scsi_scan_host - scan SCSI bus
+ * @shost: a pointer to a scsi host instance
+ *
+ * Might block: yes
+ *
+ * Notes: Should be called after scsi_add_host()
+ *
+ * Defined in: drivers/scsi/scsi_scan.c
+ **/
+void scsi_scan_host(struct Scsi_Host *shost)
+
+
+/**
* scsi_track_queue_full - track successive QUEUE_FULL events on given
* device to determine if and when there is a need
* to adjust the queue depth on the device.
@@ -759,7 +717,7 @@ void scsi_report_bus_reset(struct Scsi_Host * shost, int channel)
*
* Defined in: drivers/scsi/scsi.c .
**/
-int scsi_track_queue_full(Scsi_Device *sdev, int depth)
+int scsi_track_queue_full(struct scsi_device *sdev, int depth)
/**
@@ -826,7 +784,6 @@ Summary:
eh_bus_reset_handler - issue SCSI bus reset
eh_device_reset_handler - issue SCSI device reset
eh_host_reset_handler - reset host (host bus adapter)
- eh_strategy_handler - driver supplied alternate to scsi_unjam_host()
info - supply information about given host
ioctl - driver can respond to ioctls
proc_info - supports /proc/scsi/{driver_name}/{host_no}
@@ -925,8 +882,11 @@ Details:
*
* Calling context: kernel thread
*
- * Notes: Invoked from scsi_eh thread. No other commands will be
- * queued on current host during eh.
+ * Notes: If 'no_async_abort' is defined this callback
+ * will be invoked from scsi_eh thread. No other commands
+ * will then be queued on current host during eh.
+ * Otherwise it will be called whenever scsi_times_out()
+ * is called due to a command timeout.
*
* Optionally defined in: LLD
**/
@@ -992,24 +952,6 @@ Details:
/**
- * eh_strategy_handler - driver supplied alternate to scsi_unjam_host()
- * @shp: host on which error has occurred
- *
- * Returns TRUE if host unjammed, else FALSE.
- *
- * Locks: none
- *
- * Calling context: kernel thread
- *
- * Notes: Invoked from scsi_eh thread. LLD supplied alternate to
- * scsi_unjam_host() found in scsi_error.c
- *
- * Optionally defined in: LLD
- **/
- 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
@@ -1100,9 +1042,9 @@ Details:
/**
- * queuecommand - queue scsi command, invoke 'done' on completion
+ * queuecommand - queue scsi command, invoke scp->scsi_done on completion
+ * @shost: pointer to the scsi host object
* @scp: pointer to scsi command object
- * @done: function pointer to be invoked on completion
*
* Returns 0 on success.
*
@@ -1130,42 +1072,45 @@ Details:
*
* Other types of errors that are detected immediately may be
* flagged by setting scp->result to an appropriate value,
- * invoking the 'done' callback, and then returning 0 from this
- * function. If the command is not performed immediately (and the
- * LLD is starting (or will start) the given command) then this
- * function should place 0 in scp->result and return 0.
+ * invoking the scp->scsi_done callback, and then returning 0
+ * from this function. If the command is not performed
+ * immediately (and the LLD is starting (or will start) the given
+ * command) then this function should place 0 in scp->result and
+ * return 0.
*
* Command ownership. If the driver returns zero, it owns the
- * command and must take responsibility for ensuring the 'done'
- * callback is executed. Note: the driver may call done before
- * returning zero, but after it has called done, it may not
- * return any value other than zero. If the driver makes a
- * non-zero return, it must not execute the command's done
- * callback at any time.
- *
- * Locks: struct Scsi_Host::host_lock held on entry (with "irqsave")
- * and is expected to be held on return.
+ * command and must take responsibility for ensuring the
+ * scp->scsi_done callback is executed. Note: the driver may
+ * call scp->scsi_done before returning zero, but after it has
+ * called scp->scsi_done, it may not return any value other than
+ * zero. If the driver makes a non-zero return, it must not
+ * execute the command's scsi_done callback at any time.
+ *
+ * Locks: up to and including 2.6.36, struct Scsi_Host::host_lock
+ * held on entry (with "irqsave") and is expected to be
+ * held on return. From 2.6.37 onwards, queuecommand is
+ * called without any locks held.
*
* Calling context: in interrupt (soft irq) or process context
*
- * 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) some time after
- * this function 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.
- * If a status of CHECK CONDITION is placed in "result" when the
- * 'done' callback is invoked, then the LLD driver should
- * perform autosense and fill in the struct scsi_cmnd::sense_buffer
+ * Notes: This function should be relatively fast. Normally it
+ * will not wait for IO to complete. Hence the scp->scsi_done
+ * callback is invoked (often directly from an interrupt service
+ * routine) some time after this function has returned. In some
+ * cases (e.g. pseudo adapter drivers that manufacture the
+ * response to a SCSI INQUIRY) the scp->scsi_done callback may be
+ * invoked before this function returns. If the scp->scsi_done
+ * callback is not invoked within a certain period the SCSI mid
+ * level will commence error processing. If a status of CHECK
+ * CONDITION is placed in "result" when the scp->scsi_done
+ * callback is invoked, then the LLD driver should perform
+ * autosense and fill in the struct scsi_cmnd::sense_buffer
* array. The scsi_cmnd::sense_buffer array is zeroed prior to
* the mid level queuing a command to an LLD.
*
* Defined in: LLD
**/
- int queuecommand(struct scsi_cmnd * scp,
- void (*done)(struct scsi_cmnd *))
+ int queuecommand(struct Scsi_Host *shost, struct scsi_cmnd * scp)
/**
@@ -1315,6 +1260,8 @@ of interest:
address space
use_clustering - 1=>SCSI commands in mid level's queue can be merged,
0=>disallow SCSI command merging
+ no_async_abort - 1=>Asynchronous aborts are not supported
+ 0=>Timed-out commands will be aborted asynchronously
hostt - pointer to driver's struct scsi_host_template from which
this struct Scsi_Host instance was spawned
hostt->proc_name - name of LLD. This is the driver name that sysfs uses
@@ -1327,6 +1274,11 @@ of interest:
hostdata[0] - area reserved for LLD at end of struct Scsi_Host. Size
is set by the second argument (named 'xtr_bytes') to
scsi_host_alloc() or scsi_register().
+ vendor_id - a unique value that identifies the vendor supplying
+ the LLD for the Scsi_Host. Used most often in validating
+ vendor-specific message requests. Value consists of an
+ identifier type and a vendor-specific value.
+ See scsi_netlink.h for a description of valid formats.
The scsi_host structure is defined in include/scsi/scsi_host.h
@@ -1391,7 +1343,7 @@ Members of interest:
underruns (overruns should be rare). If possible an LLD
should set 'resid' prior to invoking 'done'. The most
interesting case is data transfers from a SCSI target
- device device (i.e. READs) that underrun.
+ device (e.g. READs) that underrun.
underflow - LLD should place (DID_ERROR << 16) in 'result' if
actual number of bytes transferred is less than this
figure. Not many LLDs implement this check and some that
@@ -1399,6 +1351,18 @@ Members of interest:
report a DID_ERROR. Better for an LLD to implement
'resid'.
+It is recommended that a LLD set 'resid' on data transfers from a SCSI
+target device (e.g. READs). It is especially important that 'resid' is set
+when such data transfers have sense keys of MEDIUM ERROR and HARDWARE ERROR
+(and possibly RECOVERED ERROR). In these cases if a LLD is in doubt how much
+data has been received then the safest approach is to indicate no bytes have
+been received. For example: to indicate that no valid data has been received
+a LLD might use these helpers:
+ scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
+where 'SCpnt' is a pointer to a scsi_cmnd object. To indicate only three 512
+bytes blocks has been received 'resid' could be set like this:
+ scsi_set_resid(SCpnt, scsi_bufflen(SCpnt) - (3 * 512));
+
The scsi_cmnd structure is defined in include/scsi/scsi_cmnd.h
@@ -1407,17 +1371,11 @@ Locks
Each struct Scsi_Host instance has a spin_lock called struct
Scsi_Host::default_lock which is initialized in scsi_host_alloc() [found in
hosts.c]. Within the same function the struct 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
-struct Scsi_Host::host_lock pointer.
-
-LLDs can override the use of struct 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().
+is initialized to point at default_lock. Thereafter lock and unlock
+operations performed by the mid level use the struct Scsi_Host::host_lock
+pointer. Previously drivers could override the host_lock pointer but
+this is not allowed anymore.
+
Autosense
=========
@@ -1469,12 +1427,12 @@ Credits
=======
The following people have contributed to this document:
Mike Anderson <andmike at us dot ibm dot com>
- James Bottomley <James dot Bottomley at steeleye dot com>
+ James Bottomley <James dot Bottomley at hansenpartnership dot com>
Patrick Mansfield <patmans at us dot ibm dot com>
Christoph Hellwig <hch at infradead dot org>
Doug Ledford <dledford at redhat dot com>
Andries Brouwer <Andries dot Brouwer at cwi dot nl>
- Randy Dunlap <rddunlap at osdl dot org>
+ Randy Dunlap <rdunlap at xenotime dot net>
Alan Stern <stern at rowland dot harvard dot edu>