| <?xml version="1.0" encoding="UTF-8"?> | 
 | <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" | 
 | 	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> | 
 |  | 
 | <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>2003-08-11</pubdate> | 
 |  | 
 |   <copyright> | 
 |    <year>2002</year> | 
 |    <year>2003</year> | 
 |    <holder>Douglas Gilbert</holder> | 
 |   </copyright> | 
 |  | 
 |   <legalnotice> | 
 |    <para> | 
 |      This documentation is free software; you can redistribute | 
 |      it and/or modify it under the terms of the GNU General Public | 
 |      License as published by the Free Software Foundation; either | 
 |      version 2 of the License, or (at your option) any later | 
 |      version. | 
 |    </para> | 
 |        | 
 |    <para> | 
 |      This program is distributed in the hope that it will be | 
 |      useful, but WITHOUT ANY WARRANTY; without even the implied | 
 |      warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 
 |      See the GNU General Public License for more details. | 
 |    </para> | 
 |        | 
 |    <para> | 
 |      You should have received a copy of the GNU General Public | 
 |      License along with this program; if not, write to the Free | 
 |      Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 
 |      MA 02111-1307 USA | 
 |    </para> | 
 |        | 
 |    <para> | 
 |      For more details see the file COPYING in the source | 
 |      distribution of Linux. | 
 |    </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>Documentation/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> | 
 | !EDocumentation/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> |