Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Sun, 15 Jul 2007 23:51:54 +0000 (16:51 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Sun, 15 Jul 2007 23:51:54 +0000 (16:51 -0700)
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (166 commits)
  [SCSI] ibmvscsi: convert to use the data buffer accessors
  [SCSI] dc395x: convert to use the data buffer accessors
  [SCSI] ncr53c8xx: convert to use the data buffer accessors
  [SCSI] sym53c8xx: convert to use the data buffer accessors
  [SCSI] ppa: coding police and printk levels
  [SCSI] aic7xxx_old: remove redundant GFP_ATOMIC from kmalloc
  [SCSI] i2o: remove redundant GFP_ATOMIC from kmalloc from device.c
  [SCSI] remove the dead CYBERSTORMIII_SCSI option
  [SCSI] don't build scsi_dma_{map,unmap} for !HAS_DMA
  [SCSI] Clean up scsi_add_lun a bit
  [SCSI] 53c700: Remove printk, which triggers because of low scsi clock on SNI RMs
  [SCSI] sni_53c710: Cleanup
  [SCSI] qla4xxx: Fix underrun/overrun conditions
  [SCSI] megaraid_mbox: use mutex instead of semaphore
  [SCSI] aacraid: add 51245, 51645 and 52245 adapters to documentation.
  [SCSI] qla2xxx: update version to 8.02.00-k1.
  [SCSI] qla2xxx: add support for NPIV
  [SCSI] stex: use resid for xfer len information
  [SCSI] Add Brownie 1200U3P to blacklist
  [SCSI] scsi.c: convert to use the data buffer accessors
  ...

190 files changed:
Documentation/scsi/aacraid.txt
Documentation/scsi/scsi_fc_transport.txt [new file with mode: 0644]
drivers/block/cciss_scsi.c
drivers/ieee1394/sbp2.c
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/infiniband/ulp/iser/iscsi_iser.h
drivers/infiniband/ulp/iser/iser_initiator.c
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/infiniband/ulp/srp/ib_srp.h
drivers/message/fusion/linux_compat.h [deleted file]
drivers/message/fusion/lsi/mpi.h
drivers/message/fusion/lsi/mpi_cnfg.h
drivers/message/fusion/lsi/mpi_history.txt
drivers/message/fusion/lsi/mpi_inb.h [deleted file]
drivers/message/fusion/lsi/mpi_init.h
drivers/message/fusion/lsi/mpi_ioc.h
drivers/message/fusion/lsi/mpi_raid.h
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptctl.c
drivers/message/fusion/mptctl.h
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptlan.c
drivers/message/fusion/mptlan.h
drivers/message/fusion/mptsas.c
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptscsih.h
drivers/message/fusion/mptspi.c
drivers/message/i2o/device.c
drivers/message/i2o/i2o_scsi.c
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_erp.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-xxxx.c
drivers/scsi/53c700.c
drivers/scsi/53c700.h
drivers/scsi/53c7xx.c [deleted file]
drivers/scsi/53c7xx.h [deleted file]
drivers/scsi/53c7xx.scr [deleted file]
drivers/scsi/53c7xx_d.h_shipped [deleted file]
drivers/scsi/53c7xx_u.h_shipped [deleted file]
drivers/scsi/BusLogic.c
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/NCR5380.c
drivers/scsi/NCR5380.h
drivers/scsi/NCR53c406a.c
drivers/scsi/a100u2w.c
drivers/scsi/a100u2w.h
drivers/scsi/a4000t.c [new file with mode: 0644]
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/commsup.c
drivers/scsi/aacraid/linit.c
drivers/scsi/aacraid/rx.c
drivers/scsi/advansys.c
drivers/scsi/advansys.h [deleted file]
drivers/scsi/aha152x.c
drivers/scsi/aha1740.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic79xx_osm.h
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.h
drivers/scsi/aic7xxx_old.c
drivers/scsi/amiga7xx.c [deleted file]
drivers/scsi/amiga7xx.h [deleted file]
drivers/scsi/arcmsr/arcmsr.h
drivers/scsi/arcmsr/arcmsr_hba.c
drivers/scsi/bvme6000.c [deleted file]
drivers/scsi/bvme6000.h [deleted file]
drivers/scsi/bvme6000_scsi.c [new file with mode: 0644]
drivers/scsi/dc395x.c
drivers/scsi/dpt_i2o.c
drivers/scsi/eata.c
drivers/scsi/esp_scsi.c
drivers/scsi/esp_scsi.h
drivers/scsi/fdomain.c
drivers/scsi/gdth.c
drivers/scsi/hptiop.c
drivers/scsi/ibmmca.c
drivers/scsi/ibmmca.h [deleted file]
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/ibmvscsi/ibmvscsi.h
drivers/scsi/ibmvscsi/rpa_vscsi.c
drivers/scsi/initio.c
drivers/scsi/initio.h
drivers/scsi/ipr.c
drivers/scsi/ips.c
drivers/scsi/ips.h
drivers/scsi/iscsi_tcp.c
drivers/scsi/iscsi_tcp.h
drivers/scsi/jazz_esp.c
drivers/scsi/libiscsi.c
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/lpfc/Makefile
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_ct.c
drivers/scsi/lpfc/lpfc_debugfs.c [new file with mode: 0644]
drivers/scsi/lpfc/lpfc_debugfs.h [new file with mode: 0644]
drivers/scsi/lpfc/lpfc_disc.h
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_hw.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_logmsg.h
drivers/scsi/lpfc/lpfc_mbox.c
drivers/scsi/lpfc/lpfc_mem.c
drivers/scsi/lpfc/lpfc_nportdisc.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_scsi.h
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_sli.h
drivers/scsi/lpfc/lpfc_version.h
drivers/scsi/lpfc/lpfc_vport.c [new file with mode: 0644]
drivers/scsi/lpfc/lpfc_vport.h [new file with mode: 0644]
drivers/scsi/mac53c94.c
drivers/scsi/megaraid.c
drivers/scsi/megaraid/mega_common.h
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/megaraid/megaraid_mbox.h
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/mesh.c
drivers/scsi/mvme16x.c [deleted file]
drivers/scsi/mvme16x.h [deleted file]
drivers/scsi/mvme16x_scsi.c [new file with mode: 0644]
drivers/scsi/ncr53c8xx.c
drivers/scsi/nsp32.c
drivers/scsi/pcmcia/sym53c500_cs.c
drivers/scsi/ppa.c
drivers/scsi/qla2xxx/Makefile
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_dbg.h
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_fw.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_mid.c [new file with mode: 0644]
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/qla4xxx/ql4_dbg.c
drivers/scsi/qla4xxx/ql4_def.h
drivers/scsi/qla4xxx/ql4_fw.h
drivers/scsi/qla4xxx/ql4_glbl.h
drivers/scsi/qla4xxx/ql4_init.c
drivers/scsi/qla4xxx/ql4_iocb.c
drivers/scsi/qla4xxx/ql4_isr.c
drivers/scsi/qla4xxx/ql4_mbx.c
drivers/scsi/qla4xxx/ql4_nvram.c
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/qla4xxx/ql4_version.h
drivers/scsi/qlogicfas408.c
drivers/scsi/scsi.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib_dma.c [new file with mode: 0644]
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/sd.c
drivers/scsi/sg.c
drivers/scsi/sni_53c710.c
drivers/scsi/sr.c
drivers/scsi/stex.c
drivers/scsi/sun_esp.c
drivers/scsi/sym53c416.c
drivers/scsi/sym53c8xx_2/sym_glue.c
drivers/scsi/sym53c8xx_2/sym_glue.h
drivers/scsi/tmscsim.c
drivers/scsi/tmscsim.h
drivers/scsi/u14-34f.c
drivers/scsi/ultrastor.c
drivers/scsi/wd7000.c
drivers/scsi/zorro7xx.c [new file with mode: 0644]
include/scsi/iscsi_if.h
include/scsi/libiscsi.h
include/scsi/scsi_cmnd.h
include/scsi/scsi_device.h
include/scsi/scsi_host.h
include/scsi/scsi_transport_fc.h
include/scsi/scsi_transport_iscsi.h

index ce3cb42507bd1edd5c0495af1a1ba6edb1b764a8..cc12b55d4b3dfc8a544ed8232fa82760b0fecd67 100644 (file)
@@ -50,6 +50,9 @@ Supported Cards/Chipsets
        9005:0285:9005:02be     Adaptec 31605 (Marauder160)
        9005:0285:9005:02c3     Adaptec 51205 (Voodoo120)
        9005:0285:9005:02c4     Adaptec 51605 (Voodoo160)
+       9005:0285:9005:02ce     Adaptec 51245 (Voodoo124)
+       9005:0285:9005:02cf     Adaptec 51645 (Voodoo164)
+       9005:0285:9005:02d0     Adaptec 52445 (Voodoo244)
        1011:0046:9005:0364     Adaptec 5400S (Mustang)
        9005:0287:9005:0800     Adaptec Themisto (Jupiter)
        9005:0200:9005:0200     Adaptec Themisto (Jupiter)
diff --git a/Documentation/scsi/scsi_fc_transport.txt b/Documentation/scsi/scsi_fc_transport.txt
new file mode 100644 (file)
index 0000000..d403e46
--- /dev/null
@@ -0,0 +1,450 @@
+                             SCSI FC Tansport
+                 =============================================
+
+Date:  4/12/2007
+Kernel Revisions for features:
+  rports : <<TBS>>
+  vports : 2.6.22 (? TBD)
+
+
+Introduction
+============
+This file documents the features and components of the SCSI FC Transport.
+It also provides documents the API between the transport and FC LLDDs.
+The FC transport can be found at:
+  drivers/scsi/scsi_transport_fc.c
+  include/scsi/scsi_transport_fc.h
+  include/scsi/scsi_netlink_fc.h
+
+This file is found at Documentation/scsi/scsi_fc_transport.txt
+
+
+FC Remote Ports (rports)
+========================================================================
+<< To Be Supplied >>
+
+
+FC Virtual Ports (vports)
+========================================================================
+
+Overview:
+-------------------------------
+
+  New FC standards have defined mechanisms which allows for a single physical
+  port to appear on as multiple communication ports. Using the N_Port Id
+  Virtualization (NPIV) mechanism, a point-to-point connection to a Fabric
+  can be assigned more than 1 N_Port_ID.  Each N_Port_ID appears as a
+  separate port to other endpoints on the fabric, even though it shares one
+  physical link to the switch for communication. Each N_Port_ID can have a
+  unique view of the fabric based on fabric zoning and array lun-masking
+  (just like a normal non-NPIV adapter).  Using the Virtual Fabric (VF)
+  mechanism, adding a fabric header to each frame allows the port to
+  interact with the Fabric Port to join multiple fabrics. The port will
+  obtain an N_Port_ID on each fabric it joins. Each fabric will have its
+  own unique view of endpoints and configuration parameters.  NPIV may be
+  used together with VF so that the port can obtain multiple N_Port_IDs
+  on each virtual fabric.
+
+  The FC transport is now recognizing a new object - a vport.  A vport is
+  an entity that has a world-wide unique World Wide Port Name (wwpn) and
+  World Wide Node Name (wwnn). The transport also allows for the FC4's to
+  be specified for the vport, with FCP_Initiator being the primary role
+  expected. Once instantiated by one of the above methods, it will have a
+  distinct N_Port_ID and view of fabric endpoints and storage entities.
+  The fc_host associated with the physical adapter will export the ability
+  to create vports. The transport will create the vport object within the
+  Linux device tree, and instruct the fc_host's driver to instantiate the
+  virtual port. Typically, the driver will create a new scsi_host instance
+  on the vport, resulting in a unique <H,C,T,L> namespace for the vport.
+  Thus, whether a FC port is based on a physical port or on a virtual port,
+  each will appear as a unique scsi_host with its own target and lun space.
+
+  Note: At this time, the transport is written to create only NPIV-based
+    vports. However, consideration was given to VF-based vports and it
+    should be a minor change to add support if needed.  The remaining
+    discussion will concentrate on NPIV.
+
+  Note: World Wide Name assignment (and uniqueness guarantees) are left
+    up to an administrative entity controling the vport. For example,
+    if vports are to be associated with virtual machines, a XEN mgmt
+    utility would be responsible for creating wwpn/wwnn's for the vport,
+    using it's own naming authority and OUI. (Note: it already does this
+    for virtual MAC addresses).
+
+
+Device Trees and Vport Objects:
+-------------------------------
+
+  Today, the device tree typically contains the scsi_host object,
+  with rports and scsi target objects underneath it. Currently the FC
+  transport creates the vport object and places it under the scsi_host
+  object corresponding to the physical adapter.  The LLDD will allocate
+  a new scsi_host for the vport and link it's object under the vport.
+  The remainder of the tree under the vports scsi_host is the same
+  as the non-NPIV case. The transport is written currently to easily
+  allow the parent of the vport to be something other than the scsi_host.
+  This could be used in the future to link the object onto a vm-specific
+  device tree. If the vport's parent is not the physical port's scsi_host,
+  a symbolic link to the vport object will be placed in the physical
+  port's scsi_host.
+
+  Here's what to expect in the device tree :
+   The typical Physical Port's Scsi_Host:
+     /sys/devices/.../host17/
+   and it has the typical decendent tree:
+     /sys/devices/.../host17/rport-17:0-0/target17:0:0/17:0:0:0:
+   and then the vport is created on the Physical Port:
+     /sys/devices/.../host17/vport-17:0-0
+   and the vport's Scsi_Host is then created:
+     /sys/devices/.../host17/vport-17:0-0/host18
+   and then the rest of the tree progresses, such as:
+     /sys/devices/.../host17/vport-17:0-0/host18/rport-18:0-0/target18:0:0/18:0:0:0:
+
+  Here's what to expect in the sysfs tree :
+   scsi_hosts:
+     /sys/class/scsi_host/host17                physical port's scsi_host
+     /sys/class/scsi_host/host18                vport's scsi_host
+   fc_hosts:
+     /sys/class/fc_host/host17                  physical port's fc_host
+     /sys/class/fc_host/host18                  vport's fc_host
+   fc_vports:
+     /sys/class/fc_vports/vport-17:0-0          the vport's fc_vport
+   fc_rports:
+     /sys/class/fc_remote_ports/rport-17:0-0    rport on the physical port
+     /sys/class/fc_remote_ports/rport-18:0-0    rport on the vport
+
+
+Vport Attributes:
+-------------------------------
+
+  The new fc_vport class object has the following attributes
+
+     node_name:                                                 Read_Only
+       The WWNN of the vport
+
+     port_name:                                                 Read_Only
+       The WWPN of the vport
+
+     roles:                                                     Read_Only
+       Indicates the FC4 roles enabled on the vport.
+
+     symbolic_name:                                             Read_Write
+       A string, appended to the driver's symbolic port name string, which
+       is registered with the switch to identify the vport. For example,
+       a hypervisor could set this string to "Xen Domain 2 VM 5 Vport 2",
+       and this set of identifiers can be seen on switch management screens
+       to identify the port.
+
+     vport_delete:                                              Write_Only
+       When written with a "1", will tear down the vport.
+
+     vport_disable:                                             Write_Only
+       When written with a "1", will transition the vport to a disabled.
+       state.  The vport will still be instantiated with the Linux kernel,
+       but it will not be active on the FC link.
+       When written with a "0", will enable the vport.
+
+     vport_last_state:                                          Read_Only
+       Indicates the previous state of the vport.  See the section below on
+       "Vport States".
+
+     vport_state:                                               Read_Only
+       Indicates the state of the vport.  See the section below on
+       "Vport States".
+
+     vport_type:                                                Read_Only
+       Reflects the FC mechanism used to create the virtual port.
+       Only NPIV is supported currently.
+
+
+  For the fc_host class object, the following attributes are added for vports:
+
+     max_npiv_vports:                                           Read_Only
+       Indicates the maximum number of NPIV-based vports that the
+       driver/adapter can support on the fc_host.
+
+     npiv_vports_inuse:                                         Read_Only
+       Indicates how many NPIV-based vports have been instantiated on the
+       fc_host.
+
+     vport_create:                                              Write_Only
+       A "simple" create interface to instantiate a vport on an fc_host.
+       A "<WWPN>:<WWNN>" string is written to the attribute. The transport
+       then instantiates the vport object and calls the LLDD to create the
+       vport with the role of FCP_Initiator.  Each WWN is specified as 16
+       hex characters and may *not* contain any prefixes (e.g. 0x, x, etc).
+
+     vport_delete:                                              Write_Only
+        A "simple" delete interface to teardown a vport. A "<WWPN>:<WWNN>"
+        string is written to the attribute. The transport will locate the
+        vport on the fc_host with the same WWNs and tear it down.  Each WWN
+        is specified as 16 hex characters and may *not* contain any prefixes
+        (e.g. 0x, x, etc).
+
+
+Vport States:
+-------------------------------
+
+  Vport instantiation consists of two parts:
+    - Creation with the kernel and LLDD. This means all transport and
+      driver data structures are built up, and device objects created.
+      This is equivalent to a driver "attach" on an adapter, which is
+      independent of the adapter's link state.
+    - Instantiation of the vport on the FC link via ELS traffic, etc.
+      This is equivalent to a "link up" and successfull link initialization.
+  Futher information can be found in the interfaces section below for
+  Vport Creation.
+
+  Once a vport has been instantiated with the kernel/LLDD, a vport state
+  can be reported via the sysfs attribute. The following states exist:
+
+    FC_VPORT_UNKNOWN            - Unknown
+      An temporary state, typically set only while the vport is being
+      instantiated with the kernel and LLDD.
+
+    FC_VPORT_ACTIVE             - Active
+      The vport has been successfully been created on the FC link.
+      It is fully functional.
+
+    FC_VPORT_DISABLED           - Disabled
+      The vport instantiated, but "disabled". The vport is not instantiated
+      on the FC link. This is equivalent to a physical port with the
+      link "down".
+
+    FC_VPORT_LINKDOWN           - Linkdown
+      The vport is not operational as the physical link is not operational.
+
+    FC_VPORT_INITIALIZING       - Initializing
+      The vport is in the process of instantiating on the FC link.
+      The LLDD will set this state just prior to starting the ELS traffic
+      to create the vport. This state will persist until the vport is
+      successfully created (state becomes FC_VPORT_ACTIVE) or it fails
+      (state is one of the values below).  As this state is transitory,
+      it will not be preserved in the "vport_last_state".
+
+    FC_VPORT_NO_FABRIC_SUPP     - No Fabric Support
+      The vport is not operational. One of the following conditions were
+      encountered:
+       - The FC topology is not Point-to-Point
+       - The FC port is not connected to an F_Port
+       - The F_Port has indicated that NPIV is not supported.
+
+    FC_VPORT_NO_FABRIC_RSCS     - No Fabric Resources
+      The vport is not operational. The Fabric failed FDISC with a status
+      indicating that it does not have sufficient resources to complete
+      the operation.
+
+    FC_VPORT_FABRIC_LOGOUT      - Fabric Logout
+      The vport is not operational. The Fabric has LOGO'd the N_Port_ID
+      associated with the vport.
+
+    FC_VPORT_FABRIC_REJ_WWN     - Fabric Rejected WWN
+      The vport is not operational. The Fabric failed FDISC with a status
+      indicating that the WWN's are not valid.
+
+    FC_VPORT_FAILED             - VPort Failed
+      The vport is not operational. This is a catchall for all other
+      error conditions.
+
+
+  The following state table indicates the different state transitions:
+
+    State              Event                            New State
+    --------------------------------------------------------------------
+     n/a                Initialization                  Unknown
+    Unknown:            Link Down                       Linkdown
+                        Link Up & Loop                  No Fabric Support
+                        Link Up & no Fabric             No Fabric Support
+                        Link Up & FLOGI response        No Fabric Support
+                          indicates no NPIV support
+                        Link Up & FDISC being sent      Initializing
+                        Disable request                 Disable
+    Linkdown:           Link Up                         Unknown
+    Initializing:       FDISC ACC                       Active
+                        FDISC LS_RJT w/ no resources    No Fabric Resources
+                        FDISC LS_RJT w/ invalid         Fabric Rejected WWN
+                          pname or invalid nport_id
+                        FDISC LS_RJT failed for         Vport Failed
+                          other reasons
+                        Link Down                       Linkdown
+                        Disable request                 Disable
+    Disable:            Enable request                  Unknown
+    Active:             LOGO received from fabric       Fabric Logout
+                        Link Down                       Linkdown
+                        Disable request                 Disable
+    Fabric Logout:      Link still up                   Unknown
+
+         The following 4 error states all have the same transitions:
+    No Fabric Support:
+    No Fabric Resources:
+    Fabric Rejected WWN:
+    Vport Failed:
+                        Disable request                 Disable
+                        Link goes down                  Linkdown
+
+
+Transport <-> LLDD Interfaces :
+-------------------------------
+
+Vport support by LLDD:
+
+  The LLDD indicates support for vports by supplying a vport_create()
+  function in the transport template.  The presense of this function will
+  cause the creation of the new attributes on the fc_host.  As part of
+  the physical port completing its initialization relative to the
+  transport, it should set the max_npiv_vports attribute to indicate the
+  maximum number of vports the driver and/or adapter supports.
+
+
+Vport Creation:
+
+  The LLDD vport_create() syntax is:
+
+      int vport_create(struct fc_vport *vport, bool disable)
+
+    where:
+      vport:    Is the newly allocated vport object
+      disable:  If "true", the vport is to be created in a disabled stated.
+                If "false", the vport is to be enabled upon creation.
+
+  When a request is made to create a new vport (via sgio/netlink, or the
+  vport_create fc_host attribute), the transport will validate that the LLDD
+  can support another vport (e.g. max_npiv_vports > npiv_vports_inuse).
+  If not, the create request will be failed.  If space remains, the transport
+  will increment the vport count, create the vport object, and then call the
+  LLDD's vport_create() function with the newly allocated vport object.
+
+  As mentioned above, vport creation is divided into two parts:
+    - Creation with the kernel and LLDD. This means all transport and
+      driver data structures are built up, and device objects created.
+      This is equivalent to a driver "attach" on an adapter, which is
+      independent of the adapter's link state.
+    - Instantiation of the vport on the FC link via ELS traffic, etc.
+      This is equivalent to a "link up" and successfull link initialization.
+
+  The LLDD's vport_create() function will not synchronously wait for both
+  parts to be fully completed before returning. It must validate that the
+  infrastructure exists to support NPIV, and complete the first part of
+  vport creation (data structure build up) before returning.  We do not
+  hinge vport_create() on the link-side operation mainly because:
+    - The link may be down. It is not a failure if it is. It simply
+      means the vport is in an inoperable state until the link comes up.
+      This is consistent with the link bouncing post vport creation.
+    - The vport may be created in a disabled state.
+    - This is consistent with a model where:  the vport equates to a
+      FC adapter. The vport_create is synonymous with driver attachment
+      to the adapter, which is independent of link state.
+
+    Note: special error codes have been defined to delineate infrastructure
+      failure cases for quicker resolution.
+
+  The expected behavior for the LLDD's vport_create() function is:
+    - Validate Infrastructure:
+        - If the driver or adapter cannot support another vport, whether
+            due to improper firmware, (a lie about) max_npiv, or a lack of
+            some other resource - return VPCERR_UNSUPPORTED.
+        - If the driver validates the WWN's against those already active on
+            the adapter and detects an overlap - return VPCERR_BAD_WWN.
+        - If the driver detects the topology is loop, non-fabric, or the
+            FLOGI did not support NPIV - return VPCERR_NO_FABRIC_SUPP.
+    - Allocate data structures. If errors are encountered, such as out
+        of memory conditions, return the respective negative Exxx error code.
+    - If the role is FCP Initiator, the LLDD is to :
+        - Call scsi_host_alloc() to allocate a scsi_host for the vport.
+        - Call scsi_add_host(new_shost, &vport->dev) to start the scsi_host
+          and bind it as a child of the vport device.
+        - Initializes the fc_host attribute values.
+    - Kick of further vport state transitions based on the disable flag and
+        link state - and return success (zero).
+
+  LLDD Implementers Notes:
+  - It is suggested that there be a different fc_function_templates for
+    the physical port and the virtual port.  The physical port's template
+    would have the vport_create, vport_delete, and vport_disable functions,
+    while the vports would not.
+  - It is suggested that there be different scsi_host_templates
+    for the physical port and virtual port. Likely, there are driver
+    attributes, embedded into the scsi_host_template, that are applicable
+    for the physical port only (link speed, topology setting, etc). This
+    ensures that the attributes are applicable to the respective scsi_host.
+
+
+Vport Disable/Enable:
+
+  The LLDD vport_disable() syntax is:
+
+      int vport_disable(struct fc_vport *vport, bool disable)
+
+    where:
+      vport:    Is vport to to be enabled or disabled
+      disable:  If "true", the vport is to be disabled.
+                If "false", the vport is to be enabled.
+
+  When a request is made to change the disabled state on a vport, the
+  transport will validate the request against the existing vport state.
+  If the request is to disable and the vport is already disabled, the
+  request will fail. Similarly, if the request is to enable, and the
+  vport is not in a disabled state, the request will fail.  If the request
+  is valid for the vport state, the transport will call the LLDD to
+  change the vport's state.
+
+  Within the LLDD, if a vport is disabled, it remains instantiated with
+  the kernel and LLDD, but it is not active or visible on the FC link in
+  any way. (see Vport Creation and the 2 part instantiation discussion).
+  The vport will remain in this state until it is deleted or re-enabled.
+  When enabling a vport, the LLDD reinstantiates the vport on the FC
+  link - essentially restarting the LLDD statemachine (see Vport States
+  above).
+
+
+Vport Deletion:
+
+  The LLDD vport_delete() syntax is:
+
+      int vport_delete(struct fc_vport *vport)
+
+    where:
+      vport:    Is vport to delete
+
+  When a request is made to delete a vport (via sgio/netlink, or via the
+  fc_host or fc_vport vport_delete attributes), the transport will call
+  the LLDD to terminate the vport on the FC link, and teardown all other
+  datastructures and references.  If the LLDD completes successfully,
+  the transport will teardown the vport objects and complete the vport
+  removal.  If the LLDD delete request fails, the vport object will remain,
+  but will be in an indeterminate state.
+
+  Within the LLDD, the normal code paths for a scsi_host teardown should
+  be followed. E.g. If the vport has a FCP Initiator role, the LLDD
+  will call fc_remove_host() for the vports scsi_host, followed by
+  scsi_remove_host() and scsi_host_put() for the vports scsi_host.
+
+
+Other:
+  fc_host port_type attribute:
+    There is a new fc_host port_type value - FC_PORTTYPE_NPIV. This value
+    must be set on all vport-based fc_hosts.  Normally, on a physical port,
+    the port_type attribute would be set to NPORT, NLPORT, etc based on the
+    topology type and existence of the fabric. As this is not applicable to
+    a vport, it makes more sense to report the FC mechanism used to create
+    the vport.
+
+  Driver unload:
+    FC drivers are required to call fc_remove_host() prior to calling
+    scsi_remove_host().  This allows the fc_host to tear down all remote
+    ports prior the scsi_host being torn down.  The fc_remove_host() call
+    was updated to remove all vports for the fc_host as well.
+
+
+Credits
+=======
+The following people have contributed to this document:
+
+
+
+
+
+
+James Smart
+james.smart@emulex.com
+
index 90961a8ea8953f4b44c4aafeac544a7421d4c437..4aca7ddfdddf9c242730d9cb625eb7b23486f4c3 100644 (file)
@@ -555,7 +555,6 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
 {
        struct scsi_cmnd *cmd;
        ctlr_info_t *ctlr;
-       u64bit addr64;
        ErrorInfo_struct *ei;
 
        ei = cp->err_info;
@@ -569,20 +568,7 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
        cmd = (struct scsi_cmnd *) cp->scsi_cmd;        
        ctlr = hba[cp->ctlr];
 
-       /* undo the DMA mappings */
-
-       if (cmd->use_sg) {
-               pci_unmap_sg(ctlr->pdev,
-                       cmd->request_buffer, cmd->use_sg,
-                               cmd->sc_data_direction); 
-       }
-       else if (cmd->request_bufflen) {
-               addr64.val32.lower = cp->SG[0].Addr.lower;
-                addr64.val32.upper = cp->SG[0].Addr.upper;
-                pci_unmap_single(ctlr->pdev, (dma_addr_t) addr64.val,
-                       cmd->request_bufflen, 
-                               cmd->sc_data_direction);
-       }
+       scsi_dma_unmap(cmd);
 
        cmd->result = (DID_OK << 16);           /* host byte */
        cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
@@ -597,7 +583,7 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
                ei->SenseLen > SCSI_SENSE_BUFFERSIZE ?
                        SCSI_SENSE_BUFFERSIZE : 
                        ei->SenseLen);
-       cmd->resid = ei->ResidualCnt;
+       scsi_set_resid(cmd, ei->ResidualCnt);
 
        if(ei->CommandStatus != 0) 
        { /* an error has occurred */ 
@@ -1204,46 +1190,29 @@ cciss_scatter_gather(struct pci_dev *pdev,
                CommandList_struct *cp, 
                struct scsi_cmnd *cmd)
 {
-       unsigned int use_sg, nsegs=0, len;
-       struct scatterlist *scatter = (struct scatterlist *) cmd->request_buffer;
+       unsigned int len;
+       struct scatterlist *sg;
        __u64 addr64;
-
-       /* is it just one virtual address? */   
-       if (!cmd->use_sg) {
-               if (cmd->request_bufflen) {     /* anything to xfer? */
-
-                       addr64 = (__u64) pci_map_single(pdev, 
-                               cmd->request_buffer, 
-                               cmd->request_bufflen, 
-                               cmd->sc_data_direction); 
-       
-                       cp->SG[0].Addr.lower = 
-                         (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
-                       cp->SG[0].Addr.upper =
-                         (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
-                       cp->SG[0].Len = cmd->request_bufflen;
-                       nsegs=1;
-               }
-       } /* else, must be a list of virtual addresses.... */
-       else if (cmd->use_sg <= MAXSGENTRIES) { /* not too many addrs? */
-
-               use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg,
-                       cmd->sc_data_direction);
-
-               for (nsegs=0; nsegs < use_sg; nsegs++) {
-                       addr64 = (__u64) sg_dma_address(&scatter[nsegs]);
-                       len  = sg_dma_len(&scatter[nsegs]);
-                       cp->SG[nsegs].Addr.lower =
-                         (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
-                       cp->SG[nsegs].Addr.upper =
-                         (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
-                       cp->SG[nsegs].Len = len;
-                       cp->SG[nsegs].Ext = 0;  // we are not chaining
+       int use_sg, i;
+
+       BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);
+
+       use_sg = scsi_dma_map(cmd);
+       if (use_sg) {   /* not too many addrs? */
+               scsi_for_each_sg(cmd, sg, use_sg, i) {
+                       addr64 = (__u64) sg_dma_address(sg);
+                       len  = sg_dma_len(sg);
+                       cp->SG[i].Addr.lower =
+                               (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
+                       cp->SG[i].Addr.upper =
+                               (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
+                       cp->SG[i].Len = len;
+                       cp->SG[i].Ext = 0;  // we are not chaining
                }
-       } else BUG();
+       }
 
-       cp->Header.SGList = (__u8) nsegs;   /* no. SGs contig in this cmd */
-       cp->Header.SGTotal = (__u16) nsegs; /* total sgs in this cmd list */
+       cp->Header.SGList = (__u8) use_sg;   /* no. SGs contig in this cmd */
+       cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */
        return;
 }
 
index e0c385a3b45079efc796904d588733a3f5a08449..e882cb951b474e06a11a861327f8dde7c73d316f 100644 (file)
@@ -1509,69 +1509,6 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
        }
 }
 
-static void sbp2_prep_command_orb_no_sg(struct sbp2_command_orb *orb,
-                                       struct sbp2_fwhost_info *hi,
-                                       struct sbp2_command_info *cmd,
-                                       struct scatterlist *sgpnt,
-                                       u32 orb_direction,
-                                       unsigned int scsi_request_bufflen,
-                                       void *scsi_request_buffer,
-                                       enum dma_data_direction dma_dir)
-{
-       cmd->dma_dir = dma_dir;
-       cmd->dma_size = scsi_request_bufflen;
-       cmd->dma_type = CMD_DMA_SINGLE;
-       cmd->cmd_dma = dma_map_single(hi->host->device.parent,
-                                     scsi_request_buffer,
-                                     cmd->dma_size, cmd->dma_dir);
-       orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
-       orb->misc |= ORB_SET_DIRECTION(orb_direction);
-
-       /* handle case where we get a command w/o s/g enabled
-        * (but check for transfers larger than 64K) */
-       if (scsi_request_bufflen <= SBP2_MAX_SG_ELEMENT_LENGTH) {
-
-               orb->data_descriptor_lo = cmd->cmd_dma;
-               orb->misc |= ORB_SET_DATA_SIZE(scsi_request_bufflen);
-
-       } else {
-               /* The buffer is too large. Turn this into page tables. */
-
-               struct sbp2_unrestricted_page_table *sg_element =
-                                               &cmd->scatter_gather_element[0];
-               u32 sg_count, sg_len;
-               dma_addr_t sg_addr;
-
-               orb->data_descriptor_lo = cmd->sge_dma;
-               orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
-
-               /* fill out our SBP-2 page tables; split up the large buffer */
-               sg_count = 0;
-               sg_len = scsi_request_bufflen;
-               sg_addr = cmd->cmd_dma;
-               while (sg_len) {
-                       sg_element[sg_count].segment_base_lo = sg_addr;
-                       if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
-                               sg_element[sg_count].length_segment_base_hi =
-                                       PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
-                               sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
-                               sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
-                       } else {
-                               sg_element[sg_count].length_segment_base_hi =
-                                       PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
-                               sg_len = 0;
-                       }
-                       sg_count++;
-               }
-
-               orb->misc |= ORB_SET_DATA_SIZE(sg_count);
-
-               sbp2util_cpu_to_be32_buffer(sg_element,
-                               (sizeof(struct sbp2_unrestricted_page_table)) *
-                               sg_count);
-       }
-}
-
 static void sbp2_create_command_orb(struct sbp2_lu *lu,
                                    struct sbp2_command_info *cmd,
                                    unchar *scsi_cmd,
@@ -1615,13 +1552,9 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu,
                orb->data_descriptor_hi = 0x0;
                orb->data_descriptor_lo = 0x0;
                orb->misc |= ORB_SET_DIRECTION(1);
-       } else if (scsi_use_sg)
+       } else
                sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_use_sg, sgpnt,
                                         orb_direction, dma_dir);
-       else
-               sbp2_prep_command_orb_no_sg(orb, hi, cmd, sgpnt, orb_direction,
-                                           scsi_request_bufflen,
-                                           scsi_request_buffer, dma_dir);
 
        sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb));
 
@@ -1710,15 +1643,15 @@ static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt,
                             void (*done)(struct scsi_cmnd *))
 {
        unchar *scsi_cmd = (unchar *)SCpnt->cmnd;
-       unsigned int request_bufflen = SCpnt->request_bufflen;
+       unsigned int request_bufflen = scsi_bufflen(SCpnt);
        struct sbp2_command_info *cmd;
 
        cmd = sbp2util_allocate_command_orb(lu, SCpnt, done);
        if (!cmd)
                return -EIO;
 
-       sbp2_create_command_orb(lu, cmd, scsi_cmd, SCpnt->use_sg,
-                               request_bufflen, SCpnt->request_buffer,
+       sbp2_create_command_orb(lu, cmd, scsi_cmd, scsi_sg_count(SCpnt),
+                               request_bufflen, scsi_sglist(SCpnt),
                                SCpnt->sc_data_direction);
        sbp2_link_orb_command(lu, cmd);
 
index dd221eda3ea63c9a648146d38d5a9269172f9485..effdee299b0c4ff2ade61260d2fe1b7a22509294 100644 (file)
@@ -134,19 +134,9 @@ iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask)
 {
        struct iscsi_iser_conn     *iser_conn  = ctask->conn->dd_data;
        struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
-       struct scsi_cmnd  *sc = ctask->sc;
 
        iser_ctask->command_sent = 0;
        iser_ctask->iser_conn    = iser_conn;
-
-       if (sc->sc_data_direction == DMA_TO_DEVICE) {
-               BUG_ON(ctask->total_length == 0);
-
-               debug_scsi("cmd [itt %x total %d imm %d unsol_data %d\n",
-                          ctask->itt, ctask->total_length, ctask->imm_count,
-                          ctask->unsol_count);
-       }
-
        iser_ctask_rdma_init(iser_ctask);
 }
 
@@ -219,6 +209,14 @@ iscsi_iser_ctask_xmit(struct iscsi_conn *conn,
        struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
        int error = 0;
 
+       if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
+               BUG_ON(scsi_bufflen(ctask->sc) == 0);
+
+               debug_scsi("cmd [itt %x total %d imm %d unsol_data %d\n",
+                          ctask->itt, scsi_bufflen(ctask->sc),
+                          ctask->imm_count, ctask->unsol_count);
+       }
+
        debug_scsi("ctask deq [cid %d itt 0x%x]\n",
                   conn->id, ctask->itt);
 
@@ -375,7 +373,8 @@ static struct iscsi_transport iscsi_iser_transport;
 static struct iscsi_cls_session *
 iscsi_iser_session_create(struct iscsi_transport *iscsit,
                         struct scsi_transport_template *scsit,
-                         uint32_t initial_cmdsn, uint32_t *hostno)
+                        uint16_t cmds_max, uint16_t qdepth,
+                        uint32_t initial_cmdsn, uint32_t *hostno)
 {
        struct iscsi_cls_session *cls_session;
        struct iscsi_session *session;
@@ -386,7 +385,13 @@ iscsi_iser_session_create(struct iscsi_transport *iscsit,
        struct iscsi_iser_cmd_task *iser_ctask;
        struct iser_desc *desc;
 
+       /*
+        * we do not support setting can_queue cmd_per_lun from userspace yet
+        * because we preallocate so many resources
+        */
        cls_session = iscsi_session_setup(iscsit, scsit,
+                                         ISCSI_DEF_XMIT_CMDS_MAX,
+                                         ISCSI_MAX_CMD_PER_LUN,
                                          sizeof(struct iscsi_iser_cmd_task),
                                          sizeof(struct iser_desc),
                                          initial_cmdsn, &hn);
@@ -545,7 +550,7 @@ iscsi_iser_ep_disconnect(__u64 ep_handle)
 static struct scsi_host_template iscsi_iser_sht = {
        .name                   = "iSCSI Initiator over iSER, v." DRV_VER,
        .queuecommand           = iscsi_queuecommand,
-       .can_queue              = ISCSI_XMIT_CMDS_MAX - 1,
+       .can_queue              = ISCSI_DEF_XMIT_CMDS_MAX - 1,
        .sg_tablesize           = ISCSI_ISER_SG_TABLESIZE,
        .max_sectors            = 1024,
        .cmd_per_lun            = ISCSI_MAX_CMD_PER_LUN,
@@ -574,8 +579,12 @@ static struct iscsi_transport iscsi_iser_transport = {
                                  ISCSI_EXP_STATSN |
                                  ISCSI_PERSISTENT_PORT |
                                  ISCSI_PERSISTENT_ADDRESS |
-                                 ISCSI_TARGET_NAME |
-                                 ISCSI_TPGT,
+                                 ISCSI_TARGET_NAME | ISCSI_TPGT |
+                                 ISCSI_USERNAME | ISCSI_PASSWORD |
+                                 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN,
+       .host_param_mask        = ISCSI_HOST_HWADDRESS |
+                                 ISCSI_HOST_NETDEV_NAME |
+                                 ISCSI_HOST_INITIATOR_NAME,
        .host_template          = &iscsi_iser_sht,
        .conndata_size          = sizeof(struct iscsi_conn),
        .max_lun                = ISCSI_ISER_MAX_LUN,
@@ -592,6 +601,9 @@ static struct iscsi_transport iscsi_iser_transport = {
        .get_session_param      = iscsi_session_get_param,
        .start_conn             = iscsi_iser_conn_start,
        .stop_conn              = iscsi_conn_stop,
+       /* iscsi host params */
+       .get_host_param         = iscsi_host_get_param,
+       .set_host_param         = iscsi_host_set_param,
        /* IO */
        .send_pdu               = iscsi_conn_send_pdu,
        .get_stats              = iscsi_iser_conn_get_stats,
index 8960196ffb0fb198f4904384d07588ad9642d478..e2353701e8bbdcfc86bd488bb7090ded9367828c 100644 (file)
@@ -98,7 +98,7 @@
 #define ISER_MAX_TX_MISC_PDUS          6 /* NOOP_OUT(2), TEXT(1),         *
                                           * SCSI_TMFUNC(2), LOGOUT(1) */
 
-#define ISER_QP_MAX_RECV_DTOS          (ISCSI_XMIT_CMDS_MAX + \
+#define ISER_QP_MAX_RECV_DTOS          (ISCSI_DEF_XMIT_CMDS_MAX + \
                                        ISER_MAX_RX_MISC_PDUS    +  \
                                        ISER_MAX_TX_MISC_PDUS)
 
 
 #define ISER_INFLIGHT_DATAOUTS         8
 
-#define ISER_QP_MAX_REQ_DTOS           (ISCSI_XMIT_CMDS_MAX *    \
+#define ISER_QP_MAX_REQ_DTOS           (ISCSI_DEF_XMIT_CMDS_MAX *    \
                                        (1 + ISER_INFLIGHT_DATAOUTS) + \
                                        ISER_MAX_TX_MISC_PDUS        + \
                                        ISER_MAX_RX_MISC_PDUS)
index 3651072f6c1f012b3ecd6a7f097fe3cc9777aa70..9ea5b9aaba7c679059f3b0c8d298506a152facc7 100644 (file)
@@ -351,18 +351,12 @@ int iser_send_command(struct iscsi_conn     *conn,
        else
                data_buf = &iser_ctask->data[ISER_DIR_OUT];
 
-       if (sc->use_sg) { /* using a scatter list */
-               data_buf->buf  = sc->request_buffer;
-               data_buf->size = sc->use_sg;
-       } else if (sc->request_bufflen) {
-               /* using a single buffer - convert it into one entry SG */
-               sg_init_one(&data_buf->sg_single,
-                           sc->request_buffer, sc->request_bufflen);
-               data_buf->buf   = &data_buf->sg_single;
-               data_buf->size  = 1;
+       if (scsi_sg_count(sc)) { /* using a scatter list */
+               data_buf->buf  = scsi_sglist(sc);
+               data_buf->size = scsi_sg_count(sc);
        }
 
-       data_buf->data_len = sc->request_bufflen;
+       data_buf->data_len = scsi_bufflen(sc);
 
        if (hdr->flags & ISCSI_FLAG_CMD_READ) {
                err = iser_prepare_read_cmd(ctask, edtl);
index 3702e2375553eff0517a5ef58418cfa050496bd7..2044de1164ac0e498d242f4908006b889b02f52b 100644 (file)
@@ -155,8 +155,8 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
        params.max_pages_per_fmr = ISCSI_ISER_SG_TABLESIZE + 1;
        /* make the pool size twice the max number of SCSI commands *
         * the ML is expected to queue, watermark for unmap at 50%  */
-       params.pool_size         = ISCSI_XMIT_CMDS_MAX * 2;
-       params.dirty_watermark   = ISCSI_XMIT_CMDS_MAX;
+       params.pool_size         = ISCSI_DEF_XMIT_CMDS_MAX * 2;
+       params.dirty_watermark   = ISCSI_DEF_XMIT_CMDS_MAX;
        params.cache             = 0;
        params.flush_function    = NULL;
        params.access            = (IB_ACCESS_LOCAL_WRITE  |
index 39bf057fbc4306c46112d3ac5e9433578a21f4ba..f01ca182f226a5df9c1d21adf195458ca95325e6 100644 (file)
@@ -455,10 +455,7 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd,
                           struct srp_target_port *target,
                           struct srp_request *req)
 {
-       struct scatterlist *scat;
-       int nents;
-
-       if (!scmnd->request_buffer ||
+       if (!scsi_sglist(scmnd) ||
            (scmnd->sc_data_direction != DMA_TO_DEVICE &&
             scmnd->sc_data_direction != DMA_FROM_DEVICE))
                return;
@@ -468,20 +465,8 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd,
                req->fmr = NULL;
        }
 
-       /*
-        * This handling of non-SG commands can be killed when the
-        * SCSI midlayer no longer generates non-SG commands.
-        */
-       if (likely(scmnd->use_sg)) {
-               nents = scmnd->use_sg;
-               scat  = scmnd->request_buffer;
-       } else {
-               nents = 1;
-               scat  = &req->fake_sg;
-       }
-
-       ib_dma_unmap_sg(target->srp_host->dev->dev, scat, nents,
-                       scmnd->sc_data_direction);
+       ib_dma_unmap_sg(target->srp_host->dev->dev, scsi_sglist(scmnd),
+                       scsi_sg_count(scmnd), scmnd->sc_data_direction);
 }
 
 static void srp_remove_req(struct srp_target_port *target, struct srp_request *req)
@@ -595,6 +580,7 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat,
        int ret;
        struct srp_device *dev = target->srp_host->dev;
        struct ib_device *ibdev = dev->dev;
+       struct scatterlist *sg;
 
        if (!dev->fmr_pool)
                return -ENODEV;
@@ -604,16 +590,16 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat,
                return -EINVAL;
 
        len = page_cnt = 0;
-       for (i = 0; i < sg_cnt; ++i) {
-               unsigned int dma_len = ib_sg_dma_len(ibdev, &scat[i]);
+       scsi_for_each_sg(req->scmnd, sg, sg_cnt, i) {
+               unsigned int dma_len = ib_sg_dma_len(ibdev, sg);
 
-               if (ib_sg_dma_address(ibdev, &scat[i]) & ~dev->fmr_page_mask) {
+               if (ib_sg_dma_address(ibdev, sg) & ~dev->fmr_page_mask) {
                        if (i > 0)
                                return -EINVAL;
                        else
                                ++page_cnt;
                }
-               if ((ib_sg_dma_address(ibdev, &scat[i]) + dma_len) &
+               if ((ib_sg_dma_address(ibdev, sg) + dma_len) &
                    ~dev->fmr_page_mask) {
                        if (i < sg_cnt - 1)
                                return -EINVAL;
@@ -633,12 +619,12 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat,
                return -ENOMEM;
 
        page_cnt = 0;
-       for (i = 0; i < sg_cnt; ++i) {
-               unsigned int dma_len = ib_sg_dma_len(ibdev, &scat[i]);
+       scsi_for_each_sg(req->scmnd, sg, sg_cnt, i) {
+               unsigned int dma_len = ib_sg_dma_len(ibdev, sg);
 
                for (j = 0; j < dma_len; j += dev->fmr_page_size)
                        dma_pages[page_cnt++] =
-                               (ib_sg_dma_address(ibdev, &scat[i]) &
+                               (ib_sg_dma_address(ibdev, sg) &
                                 dev->fmr_page_mask) + j;
        }
 
@@ -673,7 +659,7 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
        struct srp_device *dev;
        struct ib_device *ibdev;
 
-       if (!scmnd->request_buffer || scmnd->sc_data_direction == DMA_NONE)
+       if (!scsi_sglist(scmnd) || scmnd->sc_data_direction == DMA_NONE)
                return sizeof (struct srp_cmd);
 
        if (scmnd->sc_data_direction != DMA_FROM_DEVICE &&
@@ -683,18 +669,8 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
                return -EINVAL;
        }
 
-       /*
-        * This handling of non-SG commands can be killed when the
-        * SCSI midlayer no longer generates non-SG commands.
-        */
-       if (likely(scmnd->use_sg)) {
-               nents = scmnd->use_sg;
-               scat  = scmnd->request_buffer;
-       } else {
-               nents = 1;
-               scat  = &req->fake_sg;
-               sg_init_one(scat, scmnd->request_buffer, scmnd->request_bufflen);
-       }
+       nents = scsi_sg_count(scmnd);
+       scat  = scsi_sglist(scmnd);
 
        dev = target->srp_host->dev;
        ibdev = dev->dev;
@@ -724,6 +700,7 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
                 * descriptor.
                 */
                struct srp_indirect_buf *buf = (void *) cmd->add_data;
+               struct scatterlist *sg;
                u32 datalen = 0;
                int i;
 
@@ -732,11 +709,11 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
                        sizeof (struct srp_indirect_buf) +
                        count * sizeof (struct srp_direct_buf);
 
-               for (i = 0; i < count; ++i) {
-                       unsigned int dma_len = ib_sg_dma_len(ibdev, &scat[i]);
+               scsi_for_each_sg(scmnd, sg, count, i) {
+                       unsigned int dma_len = ib_sg_dma_len(ibdev, sg);
 
                        buf->desc_list[i].va  =
-                               cpu_to_be64(ib_sg_dma_address(ibdev, &scat[i]));
+                               cpu_to_be64(ib_sg_dma_address(ibdev, sg));
                        buf->desc_list[i].key =
                                cpu_to_be32(dev->mr->rkey);
                        buf->desc_list[i].len = cpu_to_be32(dma_len);
@@ -802,9 +779,9 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
                }
 
                if (rsp->flags & (SRP_RSP_FLAG_DOOVER | SRP_RSP_FLAG_DOUNDER))
-                       scmnd->resid = be32_to_cpu(rsp->data_out_res_cnt);
+                       scsi_set_resid(scmnd, be32_to_cpu(rsp->data_out_res_cnt));
                else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER))
-                       scmnd->resid = be32_to_cpu(rsp->data_in_res_cnt);
+                       scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt));
 
                if (!req->tsk_mgmt) {
                        scmnd->host_scribble = (void *) -1L;
index 1d53c7bc368f5d8fa0e2f10f0a1865eadafae6af..e3573e7038c4ea7089f5e257964d75c3f0dbf043 100644 (file)
@@ -106,11 +106,6 @@ struct srp_request {
        struct srp_iu          *cmd;
        struct srp_iu          *tsk_mgmt;
        struct ib_pool_fmr     *fmr;
-       /*
-        * Fake scatterlist used when scmnd->use_sg==0.  Can be killed
-        * when the SCSI midlayer no longer generates non-SG commands.
-        */
-       struct scatterlist      fake_sg;
        struct completion       done;
        short                   index;
        u8                      cmd_done;
diff --git a/drivers/message/fusion/linux_compat.h b/drivers/message/fusion/linux_compat.h
deleted file mode 100644 (file)
index bb2bf5a..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/* drivers/message/fusion/linux_compat.h */
-
-#ifndef FUSION_LINUX_COMPAT_H
-#define FUSION_LINUX_COMPAT_H
-
-#include <linux/version.h>
-#include <scsi/scsi_device.h>
-
-#endif /* _LINUX_COMPAT_H */
index 75223bf24ae86fa8449e19976d09518ba51f7deb..6a92e3d118fed008fd6c93bcb37794b97d25cc21 100644 (file)
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2006 LSI Logic Corporation.
+ *  Copyright (c) 2000-2007 LSI Logic Corporation.
  *
  *
  *           Name:  mpi.h
  *          Title:  MPI Message independent structures and definitions
  *  Creation Date:  July 27, 2000
  *
- *    mpi.h Version:  01.05.12
+ *    mpi.h Version:  01.05.13
  *
  *  Version History
  *  ---------------
@@ -78,6 +78,7 @@
  *  08-30-05  01.05.10  Added 2 new IOCStatus codes for Target.
  *  03-27-06  01.05.11  Bumped MPI_HEADER_VERSION_UNIT.
  *  10-11-06  01.05.12  Bumped MPI_HEADER_VERSION_UNIT.
+ *  05-24-07  01.05.13  Bumped MPI_HEADER_VERSION_UNIT.
  *  --------------------------------------------------------------------------
  */
 
 /* Note: The major versions of 0xe0 through 0xff are reserved */
 
 /* versioning for this MPI header set */
-#define MPI_HEADER_VERSION_UNIT             (0x0E)
+#define MPI_HEADER_VERSION_UNIT             (0x10)
 #define MPI_HEADER_VERSION_DEV              (0x00)
 #define MPI_HEADER_VERSION_UNIT_MASK        (0xFF00)
 #define MPI_HEADER_VERSION_UNIT_SHIFT       (8)
index 0e4c8e77a81dc7efcc8dbf39f1cd4bf0282a57a1..eda769730e39d3e6f789906f4ce27d95d6648e56 100644 (file)
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2006 LSI Logic Corporation.
+ *  Copyright (c) 2000-2007 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_cnfg.h
  *          Title:  MPI Config message, structures, and Pages
  *  Creation Date:  July 27, 2000
  *
- *    mpi_cnfg.h Version:  01.05.13
+ *    mpi_cnfg.h Version:  01.05.15
  *
  *  Version History
  *  ---------------
  *                      Added more AccessStatus values for SAS Device Page 0.
  *                      Added bit for SATA Asynchronous Notification Support in
  *                      Flags field of SAS Device Page 0.
+ *  02-28-07  01.05.14  Added ExtFlags field to Manufacturing Page 4.
+ *                      Added Disable SMART Polling for CapabilitiesFlags of
+ *                      IOC Page 6.
+ *                      Added Disable SMART Polling to DeviceSettings of BIOS
+ *                      Page 1.
+ *                      Added Multi-Port Domain bit for DiscoveryStatus field
+ *                      of SAS IO Unit Page.
+ *                      Added Multi-Port Domain Illegal flag for SAS IO Unit
+ *                      Page 1 AdditionalControlFlags field.
+ *  05-24-07  01.05.15  Added Hide Physical Disks with Non-Integrated RAID
+ *                      Metadata bit to Manufacturing Page 4 ExtFlags field.
+ *                      Added Internal Connector to End Device Present bit to
+ *                      Expander Page 0 Flags field.
+ *                      Fixed define for
+ *                      MPI_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED.
  *  --------------------------------------------------------------------------
  */
 
@@ -639,7 +654,7 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
     U8                              InfoSize1;          /* 0Bh */
     U8                              InquirySize;        /* 0Ch */
     U8                              Flags;              /* 0Dh */
-    U16                             Reserved2;          /* 0Eh */
+    U16                             ExtFlags;           /* 0Eh */
     U8                              InquiryData[56];    /* 10h */
     U32                             ISVolumeSettings;   /* 48h */
     U32                             IMEVolumeSettings;  /* 4Ch */
@@ -658,7 +673,7 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
 } CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
   ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t;
 
-#define MPI_MANUFACTURING4_PAGEVERSION                  (0x04)
+#define MPI_MANUFACTURING4_PAGEVERSION                  (0x05)
 
 /* defines for the Flags field */
 #define MPI_MANPAGE4_FORCE_BAD_BLOCK_TABLE              (0x80)
@@ -670,6 +685,12 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
 #define MPI_MANPAGE4_IM_RESYNC_CACHE_ENABLE             (0x02)
 #define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA                 (0x01)
 
+/* defines for the ExtFlags field */
+#define MPI_MANPAGE4_EXTFLAGS_HIDE_NON_IR_METADATA      (0x0008)
+#define MPI_MANPAGE4_EXTFLAGS_SAS_CACHE_DISABLE         (0x0004)
+#define MPI_MANPAGE4_EXTFLAGS_SATA_CACHE_DISABLE        (0x0002)
+#define MPI_MANPAGE4_EXTFLAGS_LEGACY_MODE               (0x0001)
+
 
 #ifndef MPI_MANPAGE5_NUM_FORCEWWID
 #define MPI_MANPAGE5_NUM_FORCEWWID      (1)
@@ -781,7 +802,7 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_9
 } CONFIG_PAGE_MANUFACTURING_9, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_9,
   ManufacturingPage9_t, MPI_POINTER pManufacturingPage9_t;
 
-#define MPI_MANUFACTURING6_PAGEVERSION                  (0x00)
+#define MPI_MANUFACTURING9_PAGEVERSION                  (0x00)
 
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_10
@@ -1138,6 +1159,8 @@ typedef struct _CONFIG_PAGE_IOC_6
 
 /* IOC Page 6 Capabilities Flags */
 
+#define MPI_IOCPAGE6_CAP_FLAGS_DISABLE_SMART_POLLING    (0x00000008)
+
 #define MPI_IOCPAGE6_CAP_FLAGS_MASK_METADATA_SIZE       (0x00000006)
 #define MPI_IOCPAGE6_CAP_FLAGS_64MB_METADATA_SIZE       (0x00000000)
 #define MPI_IOCPAGE6_CAP_FLAGS_512MB_METADATA_SIZE      (0x00000002)
@@ -1208,6 +1231,7 @@ typedef struct _CONFIG_PAGE_BIOS_1
 #define MPI_BIOSPAGE1_IOCSET_ALTERNATE_CHS              (0x00000008)
 
 /* values for the DeviceSettings field */
+#define MPI_BIOSPAGE1_DEVSET_DISABLE_SMART_POLLING      (0x00000010)
 #define MPI_BIOSPAGE1_DEVSET_DISABLE_SEQ_LUN            (0x00000008)
 #define MPI_BIOSPAGE1_DEVSET_DISABLE_RM_LUN             (0x00000004)
 #define MPI_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN         (0x00000002)
@@ -2281,11 +2305,11 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0
 typedef struct _CONFIG_PAGE_RAID_VOL_1
 {
     CONFIG_PAGE_HEADER      Header;         /* 00h */
-    U8                      VolumeID;       /* 01h */
-    U8                      VolumeBus;      /* 02h */
-    U8                      VolumeIOC;      /* 03h */
-    U8                      Reserved0;      /* 04h */
-    U8                      GUID[24];       /* 05h */
+    U8                      VolumeID;       /* 04h */
+    U8                      VolumeBus;      /* 05h */
+    U8                      VolumeIOC;      /* 06h */
+    U8                      Reserved0;      /* 07h */
+    U8                      GUID[24];       /* 08h */
     U8                      Name[32];       /* 20h */
     U64                     WWID;           /* 40h */
     U32                     Reserved1;      /* 48h */
@@ -2340,7 +2364,7 @@ typedef struct _RAID_PHYS_DISK0_STATUS
 } RAID_PHYS_DISK0_STATUS, MPI_POINTER PTR_RAID_PHYS_DISK0_STATUS,
   RaidPhysDiskStatus_t, MPI_POINTER pRaidPhysDiskStatus_t;
 
-/* RAID Volume 2 IM Physical Disk DiskStatus flags */
+/* RAID Physical Disk PhysDiskStatus flags */
 
 #define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC           (0x01)
 #define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED              (0x02)
@@ -2544,6 +2568,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
 #define MPI_SAS_IOUNIT0_DS_TABLE_LINK                       (0x00000400)
 #define MPI_SAS_IOUNIT0_DS_UNSUPPORTED_DEVICE               (0x00000800)
 #define MPI_SAS_IOUNIT0_DS_MAX_SATA_TARGETS                 (0x00001000)
+#define MPI_SAS_IOUNIT0_DS_MULTI_PORT_DOMAIN                (0x00002000)
 
 
 typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA
@@ -2607,6 +2632,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
 #define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION           (0x0001)
 
 /* values for SAS IO Unit Page 1 AdditionalControlFlags */
+#define MPI_SAS_IOUNIT1_ACONTROL_MULTI_PORT_DOMAIN_ILLEGAL          (0x0080)
 #define MPI_SAS_IOUNIT1_ACONTROL_SATA_ASYNCHROUNOUS_NOTIFICATION    (0x0040)
 #define MPI_SAS_IOUNIT1_ACONTROL_HIDE_NONZERO_ATTACHED_PHY_IDENT    (0x0020)
 #define MPI_SAS_IOUNIT1_ACONTROL_PORT_ENABLE_ONLY_SATA_LINK_RESET   (0x0010)
@@ -2734,6 +2760,7 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_0
 #define MPI_SAS_EXPANDER0_DS_UNSUPPORTED_DEVICE         (0x00000800)
 
 /* values for SAS Expander Page 0 Flags field */
+#define MPI_SAS_EXPANDER0_FLAGS_CONNECTOR_END_DEVICE    (0x04)
 #define MPI_SAS_EXPANDER0_FLAGS_ROUTE_TABLE_CONFIG      (0x02)
 #define MPI_SAS_EXPANDER0_FLAGS_CONFIG_IN_PROGRESS      (0x01)
 
@@ -2774,7 +2801,7 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_1
 /* see mpi_sas.h for values for SAS Expander Page 1 AttachedDeviceInfo values */
 
 /* values for SAS Expander Page 1 DiscoveryInfo field */
-#define MPI_SAS_EXPANDER1_DISCINFO_BAD_PHY DISABLED     (0x04)
+#define MPI_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED     (0x04)
 #define MPI_SAS_EXPANDER1_DISCINFO_LINK_STATUS_CHANGE   (0x02)
 #define MPI_SAS_EXPANDER1_DISCINFO_NO_ROUTING_ENTRIES   (0x01)
 
@@ -2895,11 +2922,11 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0
     U8                                  AttachedPhyIdentifier;  /* 16h */
     U8                                  Reserved2;              /* 17h */
     U32                                 AttachedDeviceInfo;     /* 18h */
-    U8                                  ProgrammedLinkRate;     /* 20h */
-    U8                                  HwLinkRate;             /* 21h */
-    U8                                  ChangeCount;            /* 22h */
-    U8                                  Flags;                  /* 23h */
-    U32                                 PhyInfo;                /* 24h */
+    U8                                  ProgrammedLinkRate;     /* 1Ch */
+    U8                                  HwLinkRate;             /* 1Dh */
+    U8                                  ChangeCount;            /* 1Eh */
+    U8                                  Flags;                  /* 1Fh */
+    U32                                 PhyInfo;                /* 20h */
 } CONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0,
   SasPhyPage0_t, MPI_POINTER pSasPhyPage0_t;
 
index ddc7ae029dd3bb9dc8f61b4e4dd9de5b825bb09d..a1f479057ea3ad1c3d0eabcc4ab907dae391518b 100644 (file)
@@ -3,28 +3,28 @@
  MPI Header File Change History
  ==============================
 
- Copyright (c) 2000-2006 LSI Logic Corporation.
+ Copyright (c) 2000-2007 LSI Logic Corporation.
 
  ---------------------------------------
- Header Set Release Version:    01.05.14
- Header Set Release Date:       10-11-06
+ Header Set Release Version:    01.05.16
+ Header Set Release Date:       05-24-07
  ---------------------------------------
 
  Filename               Current version     Prior version
  ----------             ---------------     -------------
- mpi.h                  01.05.12            01.05.11
- mpi_ioc.h              01.05.12            01.05.11
- mpi_cnfg.h             01.05.13            01.05.12
- mpi_init.h             01.05.08            01.05.07
+ mpi.h                  01.05.13            01.05.12
+ mpi_ioc.h              01.05.14            01.05.13
+ mpi_cnfg.h             01.05.15            01.05.14
+ mpi_init.h             01.05.09            01.05.09
  mpi_targ.h             01.05.06            01.05.06
  mpi_fc.h               01.05.01            01.05.01
  mpi_lan.h              01.05.01            01.05.01
- mpi_raid.h             01.05.02            01.05.02
+ mpi_raid.h             01.05.03            01.05.03
  mpi_tool.h             01.05.03            01.05.03
  mpi_inb.h              01.05.01            01.05.01
- mpi_sas.h              01.05.04            01.05.03
+ mpi_sas.h              01.05.04            01.05.04
  mpi_type.h             01.05.02            01.05.02
- mpi_history.txt        01.05.14            01.05.13
+ mpi_history.txt        01.05.14            01.05.14
 
 
  *  Date      Version   Description
@@ -95,6 +95,7 @@ mpi.h
  *  08-30-05  01.05.10  Added 2 new IOCStatus codes for Target.
  *  03-27-06  01.05.11  Bumped MPI_HEADER_VERSION_UNIT.
  *  10-11-06  01.05.12  Bumped MPI_HEADER_VERSION_UNIT.
+ *  05-24-07  01.05.13  Bumped MPI_HEADER_VERSION_UNIT.
  *  --------------------------------------------------------------------------
 
 mpi_ioc.h
@@ -191,6 +192,13 @@ mpi_ioc.h
  *                      data structure.
  *                      Added new ImageType values for FWDownload and FWUpload
  *                      requests.
+ *  02-28-07  01.05.13  Added MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT for SAS
+ *                      Broadcast Event Data (replacing _RESERVED2).
+ *                      For Discovery Error Event Data DiscoveryStatus field,
+ *                      replaced _MULTPL_PATHS with _UNSUPPORTED_DEVICE and
+ *                      added _MULTI_PORT_DOMAIN.
+ *  05-24-07  01.05.14  Added Common Boot Block type to FWDownload Request.
+ *                      Added Common Boot Block type to FWUpload Request.
  *  --------------------------------------------------------------------------
 
 mpi_cnfg.h
@@ -473,6 +481,21 @@ mpi_cnfg.h
  *                      Added more AccessStatus values for SAS Device Page 0.
  *                      Added bit for SATA Asynchronous Notification Support in
  *                      Flags field of SAS Device Page 0.
+ *  02-28-07  01.05.14  Added ExtFlags field to Manufacturing Page 4.
+ *                      Added Disable SMART Polling for CapabilitiesFlags of
+ *                      IOC Page 6.
+ *                      Added Disable SMART Polling to DeviceSettings of BIOS
+ *                      Page 1.
+ *                      Added Multi-Port Domain bit for DiscoveryStatus field
+ *                      of SAS IO Unit Page.
+ *                      Added Multi-Port Domain Illegal flag for SAS IO Unit
+ *                      Page 1 AdditionalControlFlags field.
+ *  05-24-07  01.05.15  Added Hide Physical Disks with Non-Integrated RAID
+ *                      Metadata bit to Manufacturing Page 4 ExtFlags field.
+ *                      Added Internal Connector to End Device Present bit to
+ *                      Expander Page 0 Flags field.
+ *                      Fixed define for
+ *                      MPI_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED.
  *  --------------------------------------------------------------------------
 
 mpi_init.h
@@ -517,6 +540,8 @@ mpi_init.h
  *                      unique in the first 32 characters.
  *  03-27-06  01.05.07  Added Task Management type of Clear ACA.
  *  10-11-06  01.05.08  Shortened define for Task Management type of Clear ACA.
+ *  02-28-07  01.05.09  Defined two new MsgFlags bits for SCSI Task Management
+ *                      Request: Do Not Send Task IU and Soft Reset Option.
  *  --------------------------------------------------------------------------
 
 mpi_targ.h
@@ -571,7 +596,7 @@ mpi_fc.h
  *  11-02-00  01.01.01  Original release for post 1.0 work
  *  12-04-00  01.01.02  Added messages for Common Transport Send and
  *                      Primitive Send.
- *  01-09-01  01.01.03  Modified some of the new flags to have an MPI prefix
+ *  01-09-01  01.01.03  Modifed some of the new flags to have an MPI prefix
  *                      and modified the FcPrimitiveSend flags.
  *  01-25-01  01.01.04  Move InitiatorIndex in LinkServiceRsp reply to a larger
  *                      field.
@@ -634,6 +659,8 @@ mpi_raid.h
  *  08-19-04  01.05.01  Original release for MPI v1.5.
  *  01-15-05  01.05.02  Added defines for the two new RAID Actions for
  *                      _SET_RESYNC_RATE and _SET_DATA_SCRUB_RATE.
+ *  02-28-07  01.05.03  Added new RAID Action, Device FW Update Mode, and
+ *                      associated defines.
  *  --------------------------------------------------------------------------
 
 mpi_tool.h
@@ -682,7 +709,22 @@ mpi_type.h
 
 mpi_history.txt         Parts list history
 
-Filename    01.05.13   01.05.13   01.05.12   01.05.11   01.05.10   01.05.09
+Filename    01.05.15   01.05.15
+----------  --------   --------
+mpi.h       01.05.12   01.05.13
+mpi_ioc.h   01.05.13   01.05.14
+mpi_cnfg.h  01.05.14   01.05.15
+mpi_init.h  01.05.09   01.05.09
+mpi_targ.h  01.05.06   01.05.06
+mpi_fc.h    01.05.01   01.05.01
+mpi_lan.h   01.05.01   01.05.01
+mpi_raid.h  01.05.03   01.05.03
+mpi_tool.h  01.05.03   01.05.03
+mpi_inb.h   01.05.01   01.05.01
+mpi_sas.h   01.05.04   01.05.04
+mpi_type.h  01.05.02   01.05.02
+
+Filename    01.05.14   01.05.13   01.05.12   01.05.11   01.05.10   01.05.09
 ----------  --------   --------   --------   --------   --------   --------
 mpi.h       01.05.12   01.05.11   01.05.10   01.05.09   01.05.08   01.05.07
 mpi_ioc.h   01.05.12   01.05.11   01.05.10   01.05.09   01.05.09   01.05.08
diff --git a/drivers/message/fusion/lsi/mpi_inb.h b/drivers/message/fusion/lsi/mpi_inb.h
deleted file mode 100644 (file)
index ff16730..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- *  Copyright (c) 2003-2004 LSI Logic Corporation.
- *
- *
- *           Name:  mpi_inb.h
- *          Title:  MPI Inband structures and definitions
- *  Creation Date:  September 30, 2003
- *
- *    mpi_inb.h Version:  01.05.01
- *
- *  Version History
- *  ---------------
- *
- *  Date      Version   Description
- *  --------  --------  ------------------------------------------------------
- *  05-11-04  01.03.01  Original release.
- *  08-19-04  01.05.01  Original release for MPI v1.5.
- *  --------------------------------------------------------------------------
- */
-
-#ifndef MPI_INB_H
-#define MPI_INB_H
-
-/******************************************************************************
-*
-*        I n b a n d    M e s s a g e s
-*
-*******************************************************************************/
-
-
-/****************************************************************************/
-/* Inband Buffer Post Request                                               */
-/****************************************************************************/
-
-typedef struct _MSG_INBAND_BUFFER_POST_REQUEST
-{
-    U8                      Reserved1;          /* 00h */
-    U8                      BufferCount;        /* 01h */
-    U8                      ChainOffset;        /* 02h */
-    U8                      Function;           /* 03h */
-    U16                     Reserved2;          /* 04h */
-    U8                      Reserved3;          /* 06h */
-    U8                      MsgFlags;           /* 07h */
-    U32                     MsgContext;         /* 08h */
-    U32                     Reserved4;          /* 0Ch */
-    SGE_TRANS_SIMPLE_UNION  SGL;                /* 10h */
-} MSG_INBAND_BUFFER_POST_REQUEST, MPI_POINTER PTR_MSG_INBAND_BUFFER_POST_REQUEST,
-  MpiInbandBufferPostRequest_t , MPI_POINTER pMpiInbandBufferPostRequest_t;
-
-
-typedef struct _WWN_FC_FORMAT
-{
-    U64                     NodeName;           /* 00h */
-    U64                     PortName;           /* 08h */
-} WWN_FC_FORMAT, MPI_POINTER PTR_WWN_FC_FORMAT,
-  WwnFcFormat_t, MPI_POINTER pWwnFcFormat_t;
-
-typedef struct _WWN_SAS_FORMAT
-{
-    U64                     WorldWideID;        /* 00h */
-    U32                     Reserved1;          /* 08h */
-    U32                     Reserved2;          /* 0Ch */
-} WWN_SAS_FORMAT, MPI_POINTER PTR_WWN_SAS_FORMAT,
-  WwnSasFormat_t, MPI_POINTER pWwnSasFormat_t;
-
-typedef union _WWN_INBAND_FORMAT
-{
-    WWN_FC_FORMAT           Fc;
-    WWN_SAS_FORMAT          Sas;
-} WWN_INBAND_FORMAT, MPI_POINTER PTR_WWN_INBAND_FORMAT,
-  WwnInbandFormat, MPI_POINTER pWwnInbandFormat;
-
-
-/* Inband Buffer Post reply message */
-
-typedef struct _MSG_INBAND_BUFFER_POST_REPLY
-{
-    U16                     Reserved1;          /* 00h */
-    U8                      MsgLength;          /* 02h */
-    U8                      Function;           /* 03h */
-    U16                     Reserved2;          /* 04h */
-    U8                      Reserved3;          /* 06h */
-    U8                      MsgFlags;           /* 07h */
-    U32                     MsgContext;         /* 08h */
-    U16                     Reserved4;          /* 0Ch */
-    U16                     IOCStatus;          /* 0Eh */
-    U32                     IOCLogInfo;         /* 10h */
-    U32                     TransferLength;     /* 14h */
-    U32                     TransactionContext; /* 18h */
-    WWN_INBAND_FORMAT       Wwn;                /* 1Ch */
-    U32                     IOCIdentifier[4];   /* 2Ch */
-} MSG_INBAND_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_INBAND_BUFFER_POST_REPLY,
-  MpiInbandBufferPostReply_t, MPI_POINTER pMpiInbandBufferPostReply_t;
-
-
-/****************************************************************************/
-/* Inband Send Request                                                      */
-/****************************************************************************/
-
-typedef struct _MSG_INBAND_SEND_REQUEST
-{
-    U16                     Reserved1;          /* 00h */
-    U8                      ChainOffset;        /* 02h */
-    U8                      Function;           /* 03h */
-    U16                     Reserved2;          /* 04h */
-    U8                      Reserved3;          /* 06h */
-    U8                      MsgFlags;           /* 07h */
-    U32                     MsgContext;         /* 08h */
-    U32                     Reserved4;          /* 0Ch */
-    WWN_INBAND_FORMAT       Wwn;                /* 10h */
-    U32                     Reserved5;          /* 20h */
-    SGE_IO_UNION            SGL;                /* 24h */
-} MSG_INBAND_SEND_REQUEST, MPI_POINTER PTR_MSG_INBAND_SEND_REQUEST,
-  MpiInbandSendRequest_t , MPI_POINTER pMpiInbandSendRequest_t;
-
-
-/* Inband Send reply message */
-
-typedef struct _MSG_INBAND_SEND_REPLY
-{
-    U16                     Reserved1;          /* 00h */
-    U8                      MsgLength;          /* 02h */
-    U8                      Function;           /* 03h */
-    U16                     Reserved2;          /* 04h */
-    U8                      Reserved3;          /* 06h */
-    U8                      MsgFlags;           /* 07h */
-    U32                     MsgContext;         /* 08h */
-    U16                     Reserved4;          /* 0Ch */
-    U16                     IOCStatus;          /* 0Eh */
-    U32                     IOCLogInfo;         /* 10h */
-    U32                     ResponseLength;     /* 14h */
-} MSG_INBAND_SEND_REPLY, MPI_POINTER PTR_MSG_INBAND_SEND_REPLY,
-  MpiInbandSendReply_t, MPI_POINTER pMpiInbandSendReply_t;
-
-
-/****************************************************************************/
-/* Inband Response Request                                                  */
-/****************************************************************************/
-
-typedef struct _MSG_INBAND_RSP_REQUEST
-{
-    U16                     Reserved1;          /* 00h */
-    U8                      ChainOffset;        /* 02h */
-    U8                      Function;           /* 03h */
-    U16                     Reserved2;          /* 04h */
-    U8                      Reserved3;          /* 06h */
-    U8                      MsgFlags;           /* 07h */
-    U32                     MsgContext;         /* 08h */
-    U32                     Reserved4;          /* 0Ch */
-    WWN_INBAND_FORMAT       Wwn;                /* 10h */
-    U32                     IOCIdentifier[4];   /* 20h */
-    U32                     ResponseLength;     /* 30h */
-    SGE_IO_UNION            SGL;                /* 34h */
-} MSG_INBAND_RSP_REQUEST, MPI_POINTER PTR_MSG_INBAND_RSP_REQUEST,
-  MpiInbandRspRequest_t , MPI_POINTER pMpiInbandRspRequest_t;
-
-
-/* Inband Response reply message */
-
-typedef struct _MSG_INBAND_RSP_REPLY
-{
-    U16                     Reserved1;          /* 00h */
-    U8                      MsgLength;          /* 02h */
-    U8                      Function;           /* 03h */
-    U16                     Reserved2;          /* 04h */
-    U8                      Reserved3;          /* 06h */
-    U8                      MsgFlags;           /* 07h */
-    U32                     MsgContext;         /* 08h */
-    U16                     Reserved4;          /* 0Ch */
-    U16                     IOCStatus;          /* 0Eh */
-    U32                     IOCLogInfo;         /* 10h */
-} MSG_INBAND_RSP_REPLY, MPI_POINTER PTR_MSG_INBAND_RSP_REPLY,
-  MpiInbandRspReply_t, MPI_POINTER pMpiInbandRspReply_t;
-
-
-/****************************************************************************/
-/* Inband Abort Request                                                     */
-/****************************************************************************/
-
-typedef struct _MSG_INBAND_ABORT_REQUEST
-{
-    U8                      Reserved1;          /* 00h */
-    U8                      AbortType;          /* 01h */
-    U8                      ChainOffset;        /* 02h */
-    U8                      Function;           /* 03h */
-    U16                     Reserved2;          /* 04h */
-    U8                      Reserved3;          /* 06h */
-    U8                      MsgFlags;           /* 07h */
-    U32                     MsgContext;         /* 08h */
-    U32                     Reserved4;          /* 0Ch */
-    U32                     ContextToAbort;     /* 10h */
-} MSG_INBAND_ABORT_REQUEST, MPI_POINTER PTR_MSG_INBAND_ABORT_REQUEST,
-  MpiInbandAbortRequest_t , MPI_POINTER pMpiInbandAbortRequest_t;
-
-#define MPI_INBAND_ABORT_TYPE_ALL_BUFFERS       (0x00)
-#define MPI_INBAND_ABORT_TYPE_EXACT_BUFFER      (0x01)
-#define MPI_INBAND_ABORT_TYPE_SEND_REQUEST      (0x02)
-#define MPI_INBAND_ABORT_TYPE_RESPONSE_REQUEST  (0x03)
-
-
-/* Inband Abort reply message */
-
-typedef struct _MSG_INBAND_ABORT_REPLY
-{
-    U8                      Reserved1;          /* 00h */
-    U8                      AbortType;          /* 01h */
-    U8                      MsgLength;          /* 02h */
-    U8                      Function;           /* 03h */
-    U16                     Reserved2;          /* 04h */
-    U8                      Reserved3;          /* 06h */
-    U8                      MsgFlags;           /* 07h */
-    U32                     MsgContext;         /* 08h */
-    U16                     Reserved4;          /* 0Ch */
-    U16                     IOCStatus;          /* 0Eh */
-    U32                     IOCLogInfo;         /* 10h */
-} MSG_INBAND_ABORT_REPLY, MPI_POINTER PTR_MSG_INBAND_ABORT_REPLY,
-  MpiInbandAbortReply_t, MPI_POINTER pMpiInbandAbortReply_t;
-
-
-#endif
-
index ec9dff2249a7f429e12bbbedb22f45dc7f7f70d3..3a02615f12d6f501eeead8a30e12efc0fe18c473 100644 (file)
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2006 LSI Logic Corporation.
+ *  Copyright (c) 2000-2007 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_init.h
  *          Title:  MPI initiator mode messages and structures
  *  Creation Date:  June 8, 2000
  *
- *    mpi_init.h Version:  01.05.08
+ *    mpi_init.h Version:  01.05.09
  *
  *  Version History
  *  ---------------
@@ -54,6 +54,8 @@
  *                      unique in the first 32 characters.
  *  03-27-06  01.05.07  Added Task Management type of Clear ACA.
  *  10-11-06  01.05.08  Shortened define for Task Management type of Clear ACA.
+ *  02-28-07  01.05.09  Defined two new MsgFlags bits for SCSI Task Management
+ *                      Request: Do Not Send Task IU and Soft Reset Option.
  *  --------------------------------------------------------------------------
  */
 
@@ -432,10 +434,14 @@ typedef struct _MSG_SCSI_TASK_MGMT
 #define MPI_SCSITASKMGMT_TASKTYPE_CLR_ACA               (0x08)
 
 /* MsgFlags bits */
+#define MPI_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU   (0x01)
+
 #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION   (0x00)
 #define MPI_SCSITASKMGMT_MSGFLAGS_LIP_RESET_OPTION      (0x02)
 #define MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION (0x04)
 
+#define MPI_SCSITASKMGMT_MSGFLAGS_SOFT_RESET_OPTION     (0x08)
+
 /* SCSI Task Management Reply */
 typedef struct _MSG_SCSI_TASK_MGMT_REPLY
 {
index 6c33e335337557c65c452e26abaec840449e254c..b1893d185bc43d9d15916c335e41e5cd8cbfa135 100644 (file)
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2006 LSI Logic Corporation.
+ *  Copyright (c) 2000-2007 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_ioc.h
  *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  August 11, 2000
  *
- *    mpi_ioc.h Version:  01.05.12
+ *    mpi_ioc.h Version:  01.05.14
  *
  *  Version History
  *  ---------------
  *                      data structure.
  *                      Added new ImageType values for FWDownload and FWUpload
  *                      requests.
+ *  02-28-07  01.05.13  Added MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT for SAS
+ *                      Broadcast Event Data (replacing _RESERVED2).
+ *                      For Discovery Error Event Data DiscoveryStatus field,
+ *                      replaced _MULTPL_PATHS with _UNSUPPORTED_DEVICE and
+ *                      added _MULTI_PORT_DOMAIN.
+ *  05-24-07  01.05.14  Added Common Boot Block type to FWDownload Request.
+ *                      Added Common Boot Block type to FWUpload Request.
  *  --------------------------------------------------------------------------
  */
 
@@ -792,7 +799,7 @@ typedef struct _EVENT_DATA_SAS_BROADCAST_PRIMITIVE
 
 #define MPI_EVENT_PRIMITIVE_CHANGE              (0x01)
 #define MPI_EVENT_PRIMITIVE_EXPANDER            (0x03)
-#define MPI_EVENT_PRIMITIVE_RESERVED2           (0x04)
+#define MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT  (0x04)
 #define MPI_EVENT_PRIMITIVE_RESERVED3           (0x05)
 #define MPI_EVENT_PRIMITIVE_RESERVED4           (0x06)
 #define MPI_EVENT_PRIMITIVE_CHANGE0_RESERVED    (0x07)
@@ -857,8 +864,9 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR
 #define MPI_EVENT_DSCVRY_ERR_DS_SMP_CRC_ERROR               (0x00000100)
 #define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_SUBTRACTIVE          (0x00000200)
 #define MPI_EVENT_DSCVRY_ERR_DS_TABLE_TO_TABLE              (0x00000400)
-#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS                (0x00000800)
+#define MPI_EVENT_DSCVRY_ERR_DS_UNSUPPORTED_DEVICE          (0x00000800)
 #define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS            (0x00001000)
+#define MPI_EVENT_DSCVRY_ERR_DS_MULTI_PORT_DOMAIN           (0x00002000)
 
 /* SAS SMP Error Event data */
 
@@ -990,6 +998,7 @@ typedef struct _MSG_FW_DOWNLOAD
 #define MPI_FW_DOWNLOAD_ITYPE_CONFIG_1          (0x07)
 #define MPI_FW_DOWNLOAD_ITYPE_CONFIG_2          (0x08)
 #define MPI_FW_DOWNLOAD_ITYPE_MEGARAID          (0x09)
+#define MPI_FW_DOWNLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B)
 
 
 typedef struct _FWDownloadTCSGE
@@ -1038,17 +1047,18 @@ typedef struct _MSG_FW_UPLOAD
 } MSG_FW_UPLOAD, MPI_POINTER PTR_MSG_FW_UPLOAD,
   FWUpload_t, MPI_POINTER pFWUpload_t;
 
-#define MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM      (0x00)
-#define MPI_FW_UPLOAD_ITYPE_FW_FLASH        (0x01)
-#define MPI_FW_UPLOAD_ITYPE_BIOS_FLASH      (0x02)
-#define MPI_FW_UPLOAD_ITYPE_NVDATA          (0x03)
-#define MPI_FW_UPLOAD_ITYPE_BOOTLOADER      (0x04)
-#define MPI_FW_UPLOAD_ITYPE_FW_BACKUP       (0x05)
-#define MPI_FW_UPLOAD_ITYPE_MANUFACTURING   (0x06)
-#define MPI_FW_UPLOAD_ITYPE_CONFIG_1        (0x07)
-#define MPI_FW_UPLOAD_ITYPE_CONFIG_2        (0x08)
-#define MPI_FW_UPLOAD_ITYPE_MEGARAID        (0x09)
-#define MPI_FW_UPLOAD_ITYPE_COMPLETE        (0x0A)
+#define MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM          (0x00)
+#define MPI_FW_UPLOAD_ITYPE_FW_FLASH            (0x01)
+#define MPI_FW_UPLOAD_ITYPE_BIOS_FLASH          (0x02)
+#define MPI_FW_UPLOAD_ITYPE_NVDATA              (0x03)
+#define MPI_FW_UPLOAD_ITYPE_BOOTLOADER          (0x04)
+#define MPI_FW_UPLOAD_ITYPE_FW_BACKUP           (0x05)
+#define MPI_FW_UPLOAD_ITYPE_MANUFACTURING       (0x06)
+#define MPI_FW_UPLOAD_ITYPE_CONFIG_1            (0x07)
+#define MPI_FW_UPLOAD_ITYPE_CONFIG_2            (0x08)
+#define MPI_FW_UPLOAD_ITYPE_MEGARAID            (0x09)
+#define MPI_FW_UPLOAD_ITYPE_COMPLETE            (0x0A)
+#define MPI_FW_UPLOAD_ITYPE_COMMON_BOOT_BLOCK   (0x0B)
 
 typedef struct _FWUploadTCSGE
 {
index 802255d2747c0c64ce519f67de0606c8fb7b4841..32819b1ec8ec5f7f40c36c15c9010282bc5ea2cd 100644 (file)
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2001-2005 LSI Logic Corporation.
+ *  Copyright (c) 2001-2007 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_raid.h
  *          Title:  MPI RAID message and structures
  *  Creation Date:  February 27, 2001
  *
- *    mpi_raid.h Version:  01.05.02
+ *    mpi_raid.h Version:  01.05.03
  *
  *  Version History
  *  ---------------
@@ -32,6 +32,8 @@
  *  08-19-04  01.05.01  Original release for MPI v1.5.
  *  01-15-05  01.05.02  Added defines for the two new RAID Actions for
  *                      _SET_RESYNC_RATE and _SET_DATA_SCRUB_RATE.
+ *  02-28-07  01.05.03  Added new RAID Action, Device FW Update Mode, and
+ *                      associated defines.
  *  --------------------------------------------------------------------------
  */
 
@@ -90,6 +92,7 @@ typedef struct _MSG_RAID_ACTION
 #define MPI_RAID_ACTION_INACTIVATE_VOLUME           (0x12)
 #define MPI_RAID_ACTION_SET_RESYNC_RATE             (0x13)
 #define MPI_RAID_ACTION_SET_DATA_SCRUB_RATE         (0x14)
+#define MPI_RAID_ACTION_DEVICE_FW_UPDATE_MODE       (0x15)
 
 /* ActionDataWord defines for use with MPI_RAID_ACTION_CREATE_VOLUME action */
 #define MPI_RAID_ACTION_ADATA_DO_NOT_SYNC           (0x00000001)
@@ -111,6 +114,10 @@ typedef struct _MSG_RAID_ACTION
 /* ActionDataWord defines for use with MPI_RAID_ACTION_SET_DATA_SCRUB_RATE action */
 #define MPI_RAID_ACTION_ADATA_DATA_SCRUB_RATE_MASK  (0x000000FF)
 
+/* ActionDataWord defines for use with MPI_RAID_ACTION_DEVICE_FW_UPDATE_MODE action */
+#define MPI_RAID_ACTION_ADATA_ENABLE_FW_UPDATE          (0x00000001)
+#define MPI_RAID_ACTION_ADATA_MASK_FW_UPDATE_TIMEOUT    (0x0000FF00)
+#define MPI_RAID_ACTION_ADATA_SHIFT_FW_UPDATE_TIMEOUT   (8)
 
 
 /* RAID Action reply message */
index 5021d1a2a1d4856e058915ea9a0d2fb8309b3f60..5a10c87239c22f0a57072d5b351859ad81236f4f 100644 (file)
@@ -6,7 +6,7 @@
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
  *  Copyright (c) 1999-2007 LSI Logic Corporation
- *  (mailto:mpt_linux_developer@lsi.com)
+ *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -64,6 +64,7 @@
 #endif
 
 #include "mptbase.h"
+#include "lsi/mpi_log_fc.h"
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #define my_NAME                "Fusion MPT base driver"
@@ -6349,14 +6350,37 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
 static void
 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
 {
-       static char *subcl_str[8] = {
-               "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
-               "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
-       };
-       u8 subcl = (log_info >> 24) & 0x7;
+       char *desc = "unknown";
+
+       switch (log_info & 0xFF000000) {
+       case MPI_IOCLOGINFO_FC_INIT_BASE:
+               desc = "FCP Initiator";
+               break;
+       case MPI_IOCLOGINFO_FC_TARGET_BASE:
+               desc = "FCP Target";
+               break;
+       case MPI_IOCLOGINFO_FC_LAN_BASE:
+               desc = "LAN";
+               break;
+       case MPI_IOCLOGINFO_FC_MSG_BASE:
+               desc = "MPI Message Layer";
+               break;
+       case MPI_IOCLOGINFO_FC_LINK_BASE:
+               desc = "FC Link";
+               break;
+       case MPI_IOCLOGINFO_FC_CTX_BASE:
+               desc = "Context Manager";
+               break;
+       case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
+               desc = "Invalid Field Offset";
+               break;
+       case MPI_IOCLOGINFO_FC_STATE_CHANGE:
+               desc = "State Change Info";
+               break;
+       }
 
-       printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
-                       ioc->name, log_info, subcl_str[subcl]);
+       printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
+                       ioc->name, log_info, desc, (log_info & 0xFFFFFF));
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
index 165f81d16d00e98044bb73bc73dea3cffdaeb4ed..05eb6e52875335213531a02fdd25ee483a636af0 100644 (file)
@@ -6,7 +6,7 @@
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
  *  Copyright (c) 1999-2007 LSI Logic Corporation
- *  (mailto:mpt_linux_developer@lsi.com)
+ *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -75,8 +75,8 @@
 #define COPYRIGHT      "Copyright (c) 1999-2007 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON       "3.04.04"
-#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.04.04"
+#define MPT_LINUX_VERSION_COMMON       "3.04.05"
+#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.04.05"
 #define WHAT_MAGIC_STRING              "@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
index 9d0f30478e464d5a08a15ed8bcc07a1ef01fe9c7..58e6c319cc76244db9aab6b6a79eb57e0afaed81 100644 (file)
@@ -5,7 +5,7 @@
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
  *  Copyright (c) 1999-2007 LSI Logic Corporation
- *  (mailto:mpt_linux_developer@lsi.com)
+ *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
index f7e72c5e47de28bbff0263ae1ecb8930bef1aa58..180b3c156247fc158a8b2b80b466239dbdf2e77a 100644 (file)
@@ -6,7 +6,7 @@
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
  *  Copyright (c) 1999-2007 LSI Logic Corporation
- *  (mailto:mpt_linux_developer@lsi.com)
+ *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
index 0caaf64039936eb7690e5fbba93291b8c34058c8..b766445f19aa30050fa60b18d502d1bb0a6ab5e3 100644 (file)
@@ -4,7 +4,7 @@
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
  *  Copyright (c) 1999-2007 LSI Logic Corporation
- *  (mailto:mpt_linux_developer@lsi.com)
+ *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -43,7 +43,6 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#include "linux_compat.h"      /* linux-2.6 tweaks */
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
index 7dd34bd28efc8f63d3a856c8b1d3a155c4aea744..7e8a90cb484e303542f112c29e2221c292dbd76d 100644 (file)
@@ -5,7 +5,7 @@
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
  *  Copyright (c) 2000-2007 LSI Logic Corporation
- *  (mailto:mpt_linux_developer@lsi.com)
+ *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
index fe438bf119f61204b86bc17dc577e86991acfbb7..8d08c2bed24a49c228611af7d866767e45f92016 100644 (file)
@@ -5,7 +5,7 @@
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
  *  Copyright (c) 2000-2007 LSI Logic Corporation
- *  (mailto:mpt_linux_developer@lsi.com)
+ *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
index 1d2d03f77894c75d8b42225da9529479173706c0..9e5424e1871fb61987ea48c73f791245241f39fb 100644 (file)
@@ -4,7 +4,7 @@
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
  *  Copyright (c) 1999-2007 LSI Logic Corporation
- *  (mailto:mpt_linux_developer@lsi.com)
+ *  (mailto:DL-MPTFusionLinux@lsi.com)
  *  Copyright (c) 2005-2007 Dell
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
index 3bd94f11e7d6ef417244f48036e24a9b696aebc0..d35617376f8763568aa62922c7677c262eb5db50 100644 (file)
@@ -4,7 +4,7 @@
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
  *  Copyright (c) 1999-2007 LSI Logic Corporation
- *  (mailto:mpt_linux_developer@lsi.com)
+ *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -44,7 +44,6 @@
 */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#include "linux_compat.h"      /* linux-2.6 tweaks */
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -260,30 +259,13 @@ mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
        /* Map the data portion, if any.
         * sges_left  = 0 if no data transfer.
         */
-       if ( (sges_left = SCpnt->use_sg) ) {
-               sges_left = pci_map_sg(ioc->pcidev,
-                              (struct scatterlist *) SCpnt->request_buffer,
-                              SCpnt->use_sg,
-                              SCpnt->sc_data_direction);
-               if (sges_left == 0)
-                       return FAILED;
-       } else if (SCpnt->request_bufflen) {
-               SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
-                                     SCpnt->request_buffer,
-                                     SCpnt->request_bufflen,
-                                     SCpnt->sc_data_direction);
-               dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
-                               ioc->name, SCpnt, SCpnt->request_bufflen));
-               mptscsih_add_sge((char *) &pReq->SGL,
-                       0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
-                       SCpnt->SCp.dma_handle);
-
-               return SUCCESS;
-       }
+       sges_left = scsi_dma_map(SCpnt);
+       if (sges_left < 0)
+               return FAILED;
 
        /* Handle the SG case.
         */
-       sg = (struct scatterlist *) SCpnt->request_buffer;
+       sg = scsi_sglist(SCpnt);
        sg_done  = 0;
        sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
        chainSge = NULL;
@@ -465,7 +447,12 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
        MPT_FRAME_HDR *mf;
        SEPRequest_t     *SEPMsg;
 
-       if (ioc->bus_type == FC)
+       if (ioc->bus_type != SAS)
+               return;
+
+       /* Not supported for hidden raid components
+        */
+       if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
                return;
 
        if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
@@ -662,7 +649,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                scsi_state = pScsiReply->SCSIState;
                scsi_status = pScsiReply->SCSIStatus;
                xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
-               sc->resid = sc->request_bufflen - xfer_cnt;
+               scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
                log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
 
                /*
@@ -767,7 +754,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                        break;
 
                case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:      /* 0x0049 */
-                       sc->resid = sc->request_bufflen - xfer_cnt;
+                       scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
                        if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
                                sc->result=DID_SOFT_ERROR << 16;
                        else /* Sufficient data transfer occurred */
@@ -816,7 +803,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                        break;
 
                case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:           /* 0x0044 */
-                       sc->resid=0;
+                       scsi_set_resid(sc, 0);
                case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:        /* 0x0040 */
                case MPI_IOCSTATUS_SUCCESS:                     /* 0x0000 */
                        sc->result = (DID_OK << 16) | scsi_status;
@@ -899,23 +886,18 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                            scsi_state, scsi_status, log_info));
 
                        dreplyprintk(("%s: [%d:%d:%d:%d] resid=%d "
-                           "bufflen=%d xfer_cnt=%d\n", __FUNCTION__,
-                           sc->device->host->host_no, sc->device->channel, sc->device->id,
-                           sc->device->lun, sc->resid, sc->request_bufflen,
-                           xfer_cnt));
+                                     "bufflen=%d xfer_cnt=%d\n", __FUNCTION__,
+                                     sc->device->host->host_no,
+                                     sc->device->channel, sc->device->id,
+                                     sc->device->lun, scsi_get_resid(sc),
+                                     scsi_bufflen(sc), xfer_cnt));
                }
 #endif
 
        } /* end of address reply case */
 
        /* Unmap the DMA buffers, if any. */
-       if (sc->use_sg) {
-               pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
-                           sc->use_sg, sc->sc_data_direction);
-       } else if (sc->request_bufflen) {
-               pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
-                               sc->request_bufflen, sc->sc_data_direction);
-       }
+       scsi_dma_unmap(sc);
 
        sc->scsi_done(sc);              /* Issue the command callback */
 
@@ -970,17 +952,8 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
                        /* Set status, free OS resources (SG DMA buffers)
                         * Do OS callback
                         */
-                       if (SCpnt->use_sg) {
-                               pci_unmap_sg(ioc->pcidev,
-                                       (struct scatterlist *) SCpnt->request_buffer,
-                                       SCpnt->use_sg,
-                                       SCpnt->sc_data_direction);
-                       } else if (SCpnt->request_bufflen) {
-                               pci_unmap_single(ioc->pcidev,
-                                       SCpnt->SCp.dma_handle,
-                                       SCpnt->request_bufflen,
-                                       SCpnt->sc_data_direction);
-                       }
+                       scsi_dma_unmap(SCpnt);
+
                        SCpnt->result = DID_RESET << 16;
                        SCpnt->host_scribble = NULL;
 
@@ -1023,14 +996,19 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
                        mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
                        if (mf == NULL)
                                continue;
+                       /* If the device is a hidden raid component, then its
+                        * expected that the mf->function will be RAID_SCSI_IO
+                        */
+                       if (vdevice->vtarget->tflags &
+                           MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
+                           MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
+                               continue;
+
                        int_to_scsilun(vdevice->lun, &lun);
                        if ((mf->Bus != vdevice->vtarget->channel) ||
                            (mf->TargetID != vdevice->vtarget->id) ||
                            memcmp(lun.scsi_lun, mf->LUN, 8))
                                continue;
-                       dsprintk(( "search_running: found (sc=%p, mf = %p) "
-                           "channel %d id %d, lun %d \n", hd->ScsiLookup[ii],
-                           mf, mf->Bus, mf->TargetID, vdevice->lun));
 
                        /* Cleanup
                         */
@@ -1039,19 +1017,12 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
                        mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
                        if ((unsigned char *)mf != sc->host_scribble)
                                continue;
-                       if (sc->use_sg) {
-                               pci_unmap_sg(hd->ioc->pcidev,
-                               (struct scatterlist *) sc->request_buffer,
-                                       sc->use_sg,
-                                       sc->sc_data_direction);
-                       } else if (sc->request_bufflen) {
-                               pci_unmap_single(hd->ioc->pcidev,
-                                       sc->SCp.dma_handle,
-                                       sc->request_bufflen,
-                                       sc->sc_data_direction);
-                       }
+                       scsi_dma_unmap(sc);
                        sc->host_scribble = NULL;
                        sc->result = DID_NO_CONNECT << 16;
+                       dsprintk(( "search_running: found (sc=%p, mf = %p) "
+                           "channel %d id %d, lun %d \n", sc, mf,
+                           vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun));
                        sc->scsi_done(sc);
                }
        }
@@ -1380,10 +1351,10 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
         *    will be no data transfer!  GRRRRR...
         */
        if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
-               datalen = SCpnt->request_bufflen;
+               datalen = scsi_bufflen(SCpnt);
                scsidir = MPI_SCSIIO_CONTROL_READ;      /* DATA IN  (host<--ioc<--dev) */
        } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
-               datalen = SCpnt->request_bufflen;
+               datalen = scsi_bufflen(SCpnt);
                scsidir = MPI_SCSIIO_CONTROL_WRITE;     /* DATA OUT (host-->ioc-->dev) */
        } else {
                datalen = 0;
@@ -1768,20 +1739,45 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
        u32              ctx2abort;
        int              scpnt_idx;
        int              retval;
-       VirtDevice       *vdev;
+       VirtDevice       *vdevice;
        ulong            sn = SCpnt->serial_number;
+       MPT_ADAPTER     *ioc;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
        if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
                SCpnt->result = DID_RESET << 16;
                SCpnt->scsi_done(SCpnt);
-               dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
-                          "Can't locate host! (sc=%p)\n",
-                          SCpnt));
+               dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: Can't locate "
+                   "host! (sc=%p)\n", SCpnt));
                return FAILED;
        }
 
+       ioc = hd->ioc;
+       printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
+              ioc->name, SCpnt);
+       scsi_print_command(SCpnt);
+
+       vdevice = SCpnt->device->hostdata;
+       if (!vdevice || !vdevice->vtarget) {
+               dtmprintk((MYIOC_s_DEBUG_FMT "task abort: device has been "
+                   "deleted (sc=%p)\n", ioc->name, SCpnt));
+               SCpnt->result = DID_NO_CONNECT << 16;
+               SCpnt->scsi_done(SCpnt);
+               retval = 0;
+               goto out;
+       }
+
+       /* Task aborts are not supported for hidden raid components.
+        */
+       if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
+               dtmprintk((MYIOC_s_DEBUG_FMT "task abort: hidden raid "
+                   "component (sc=%p)\n", ioc->name, SCpnt));
+               SCpnt->result = DID_RESET << 16;
+               retval = FAILED;
+               goto out;
+       }
+
        /* Find this command
         */
        if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
@@ -1790,21 +1786,20 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
                 */
                SCpnt->result = DID_RESET << 16;
                dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
-                          "Command not in the active list! (sc=%p)\n",
-                          hd->ioc->name, SCpnt));
-               return SUCCESS;
+                  "Command not in the active list! (sc=%p)\n", ioc->name,
+                  SCpnt));
+               retval = 0;
+               goto out;
        }
 
-       if (hd->resetPending)
-               return FAILED;
+       if (hd->resetPending) {
+               retval = FAILED;
+               goto out;
+       }
 
        if (hd->timeouts < -1)
                hd->timeouts++;
 
-       printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
-              hd->ioc->name, SCpnt);
-       scsi_print_command(SCpnt);
-
        /* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
         * (the IO to be ABORT'd)
         *
@@ -1817,18 +1812,17 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 
        hd->abortSCpnt = SCpnt;
 
-       vdev = SCpnt->device->hostdata;
        retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
-               vdev->vtarget->channel, vdev->vtarget->id, vdev->lun,
-               ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
+           vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun,
+           ctx2abort, mptscsih_get_tm_timeout(ioc));
 
        if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
            SCpnt->serial_number == sn)
                retval = FAILED;
 
-       printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
-               hd->ioc->name,
-               ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+ out:
+       printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n",
+           ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
 
        if (retval == 0)
                return SUCCESS;
@@ -1850,32 +1844,47 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
 {
        MPT_SCSI_HOST   *hd;
        int              retval;
-       VirtDevice       *vdev;
+       VirtDevice       *vdevice;
+       MPT_ADAPTER     *ioc;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
        if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
-               dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
-                          "Can't locate host! (sc=%p)\n",
-                          SCpnt));
+               dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: Can't "
+                   "locate host! (sc=%p)\n", SCpnt));
                return FAILED;
        }
 
-       if (hd->resetPending)
-               return FAILED;
-
-       printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
-              hd->ioc->name, SCpnt);
+       ioc = hd->ioc;
+       printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
+              ioc->name, SCpnt);
        scsi_print_command(SCpnt);
 
-       vdev = SCpnt->device->hostdata;
+       if (hd->resetPending) {
+               retval = FAILED;
+               goto out;
+       }
+
+       vdevice = SCpnt->device->hostdata;
+       if (!vdevice || !vdevice->vtarget) {
+               retval = 0;
+               goto out;
+       }
+
+       /* Target reset to hidden raid component is not supported
+        */
+       if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
+               retval = FAILED;
+               goto out;
+       }
+
        retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
-               vdev->vtarget->channel, vdev->vtarget->id,
-               0, 0, mptscsih_get_tm_timeout(hd->ioc));
+           vdevice->vtarget->channel, vdevice->vtarget->id, 0, 0,
+           mptscsih_get_tm_timeout(ioc));
 
-       printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
-               hd->ioc->name,
-               ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+ out:
+       printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
+           ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
 
        if (retval == 0)
                return SUCCESS;
@@ -1899,18 +1908,19 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
        MPT_SCSI_HOST   *hd;
        int              retval;
        VirtDevice       *vdev;
+       MPT_ADAPTER     *ioc;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
        if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
-               dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
-                          "Can't locate host! (sc=%p)\n",
-                          SCpnt ) );
+               dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: Can't "
+                   "locate host! (sc=%p)\n", SCpnt ));
                return FAILED;
        }
 
-       printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
-              hd->ioc->name, SCpnt);
+       ioc = hd->ioc;
+       printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
+              ioc->name, SCpnt);
        scsi_print_command(SCpnt);
 
        if (hd->timeouts < -1)
@@ -1918,11 +1928,10 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
 
        vdev = SCpnt->device->hostdata;
        retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
-               vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
+           vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(ioc));
 
-       printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
-               hd->ioc->name,
-               ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+       printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
+           ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
 
        if (retval == 0)
                return SUCCESS;
@@ -1943,37 +1952,38 @@ int
 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
 {
        MPT_SCSI_HOST *  hd;
-       int              status = SUCCESS;
+       int              retval;
+       MPT_ADAPTER     *ioc;
 
        /*  If we can't locate the host to reset, then we failed. */
        if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
-               dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
-                            "Can't locate host! (sc=%p)\n",
-                            SCpnt ) );
+               dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: Can't "
+                   "locate host! (sc=%p)\n", SCpnt));
                return FAILED;
        }
 
-       printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
-              hd->ioc->name, SCpnt);
+       ioc = hd->ioc;
+       printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
+           ioc->name, SCpnt);
 
        /*  If our attempts to reset the host failed, then return a failed
         *  status.  The host will be taken off line by the SCSI mid-layer.
         */
-       if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
-               status = FAILED;
+       if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0) {
+               retval = FAILED;
        } else {
                /*  Make sure TM pending is cleared and TM state is set to
                 *  NONE.
                 */
+               retval = 0;
                hd->tmPending = 0;
                hd->tmState = TM_STATE_NONE;
        }
 
-       dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
-                    "Status = %s\n",
-                    (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
+       printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
+           ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
 
-       return status;
+       return retval;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -3150,6 +3160,16 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
 {
        INTERNAL_CMD             iocmd;
 
+       /* Ignore hidden raid components, this is handled when the command
+        * is sent to the volume
+        */
+       if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
+               return;
+
+       if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
+           !vdevice->configured_lun)
+               return;
+
        /* Following parameters will not change
         * in this routine.
         */
@@ -3164,9 +3184,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
        iocmd.id = vdevice->vtarget->id;
        iocmd.lun = vdevice->lun;
 
-       if ((vdevice->vtarget->type == TYPE_DISK) &&
-           (vdevice->configured_lun))
-               mptscsih_do_cmd(hd, &iocmd);
+       mptscsih_do_cmd(hd, &iocmd);
 }
 
 EXPORT_SYMBOL(mptscsih_remove);
index 843c01a6aa0ecc817571629e49dd7bf28ec21ce6..8eccdfe5701af91a169bc456c2f7e637474e7f17 100644 (file)
@@ -6,7 +6,7 @@
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
  *  Copyright (c) 1999-2007 LSI Logic Corporation
- *  (mailto:mpt_linux_developer@lsi.com)
+ *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
index 37bf65348372c8b629651ff2f2c3128182a2e653..6b3e0c00952b69566177fdb97d9d128cf0533a91 100644 (file)
@@ -4,7 +4,7 @@
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
  *  Copyright (c) 1999-2007 LSI Logic Corporation
- *  (mailto:mpt_linux_developer@lsi.com)
+ *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -44,7 +44,6 @@
 */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#include "linux_compat.h"      /* linux-2.6 tweaks */
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
index b9df143e4ff1962cb049ba11e8166425ffdd8b9f..611adc3c0f7443ab1043d2b5b812961b932741ff 100644 (file)
@@ -485,7 +485,7 @@ int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field,
        u8 *resblk;             /* 8 bytes for header */
        int rc;
 
-       resblk = kmalloc(buflen + 8, GFP_KERNEL | GFP_ATOMIC);
+       resblk = kmalloc(buflen + 8, GFP_KERNEL);
        if (!resblk)
                return -ENOMEM;
 
index 1045c8a518bbbdb453ba9e40a951646b48e26bf2..aa6fb9429d58a06f84621324d682c7b25f9edf36 100644 (file)
@@ -377,12 +377,8 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m,
                osm_err("SCSI error %08x\n", error);
 
        dev = &c->pdev->dev;
-       if (cmd->use_sg)
-               dma_unmap_sg(dev, cmd->request_buffer, cmd->use_sg,
-                            cmd->sc_data_direction);
-       else if (cmd->SCp.dma_handle)
-               dma_unmap_single(dev, cmd->SCp.dma_handle, cmd->request_bufflen,
-                                cmd->sc_data_direction);
+
+       scsi_dma_unmap(cmd);
 
        cmd->scsi_done(cmd);
 
@@ -664,21 +660,15 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
 
        if (sgl_offset != SGL_OFFSET_0) {
                /* write size of data addressed by SGL */
-               *mptr++ = cpu_to_le32(SCpnt->request_bufflen);
+               *mptr++ = cpu_to_le32(scsi_bufflen(SCpnt));
 
                /* Now fill in the SGList and command */
-               if (SCpnt->use_sg) {
-                       if (!i2o_dma_map_sg(c, SCpnt->request_buffer,
-                                           SCpnt->use_sg,
+
+               if (scsi_sg_count(SCpnt)) {
+                       if (!i2o_dma_map_sg(c, scsi_sglist(SCpnt),
+                                           scsi_sg_count(SCpnt),
                                            SCpnt->sc_data_direction, &mptr))
                                goto nomem;
-               } else {
-                       SCpnt->SCp.dma_handle =
-                           i2o_dma_map_single(c, SCpnt->request_buffer,
-                                              SCpnt->request_bufflen,
-                                              SCpnt->sc_data_direction, &mptr);
-                       if (dma_mapping_error(SCpnt->SCp.dma_handle))
-                               goto nomem;
                }
        }
 
index 821cde65e3694ecc3ab6f68cb30c168c276581cf..a1db95925138c959cfe5894668289b281fee6a21 100644 (file)
@@ -815,9 +815,7 @@ zfcp_get_adapter_by_busid(char *bus_id)
 struct zfcp_unit *
 zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
 {
-       struct zfcp_unit *unit, *tmp_unit;
-       unsigned int scsi_lun;
-       int found;
+       struct zfcp_unit *unit;
 
        /*
         * check that there is no unit with this FCP_LUN already in list
@@ -863,22 +861,10 @@ zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
        }
 
        zfcp_unit_get(unit);
+       unit->scsi_lun = scsilun_to_int((struct scsi_lun *)&unit->fcp_lun);
 
-       scsi_lun = 0;
-       found = 0;
        write_lock_irq(&zfcp_data.config_lock);
-       list_for_each_entry(tmp_unit, &port->unit_list_head, list) {
-               if (tmp_unit->scsi_lun != scsi_lun) {
-                       found = 1;
-                       break;
-               }
-               scsi_lun++;
-       }
-       unit->scsi_lun = scsi_lun;
-       if (found)
-               list_add_tail(&unit->list, &tmp_unit->list);
-       else
-               list_add_tail(&unit->list, &port->unit_list_head);
+       list_add_tail(&unit->list, &port->unit_list_head);
        atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
        atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);
        write_unlock_irq(&zfcp_data.config_lock);
index aef66bc2b6cac79dff1219b44a287f666a8a4087..4e7cb6dc4d348443c1a4a901dd359e03fcc5588d 100644 (file)
@@ -1986,6 +1986,10 @@ zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close)
  failed_openfcp:
        zfcp_close_fsf(erp_action->adapter);
  failed_qdio:
+       atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
+                         ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
+                         ZFCP_STATUS_ADAPTER_XPORT_OK,
+                         &erp_action->adapter->status);
  out:
        return retval;
 }
@@ -2167,6 +2171,9 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
                sleep *= 2;
        }
 
+       atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
+                         &adapter->status);
+
        if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
                              &adapter->status)) {
                ZFCP_LOG_INFO("error: exchange of configuration data for "
index eb766c3af1c816f30b61c43c0e30a9914c1160c5..76c09097175f131ff9a60b77089a31f8d1932008 100644 (file)
@@ -1306,22 +1306,26 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
                                        wake_up(&tw_dev->ioctl_wqueue);
                                }
                        } else {
+                               struct scsi_cmnd *cmd;
+
+                               cmd = tw_dev->srb[request_id];
+
                                twa_scsiop_execute_scsi_complete(tw_dev, request_id);
                                /* If no error command was a success */
                                if (error == 0) {
-                                       tw_dev->srb[request_id]->result = (DID_OK << 16);
+                                       cmd->result = (DID_OK << 16);
                                }
 
                                /* If error, command failed */
                                if (error == 1) {
                                        /* Ask for a host reset */
-                                       tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
+                                       cmd->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
                                }
 
                                /* Report residual bytes for single sgl */
-                               if ((tw_dev->srb[request_id]->use_sg <= 1) && (full_command_packet->command.newcommand.status == 0)) {
-                                       if (full_command_packet->command.newcommand.sg_list[0].length < tw_dev->srb[request_id]->request_bufflen)
-                                               tw_dev->srb[request_id]->resid = tw_dev->srb[request_id]->request_bufflen - full_command_packet->command.newcommand.sg_list[0].length;
+                               if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
+                                       if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
+                                               scsi_set_resid(cmd, scsi_bufflen(cmd) - full_command_packet->command.newcommand.sg_list[0].length);
                                }
 
                                /* Now complete the io */
@@ -1384,52 +1388,20 @@ static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
 {
        int use_sg;
        struct scsi_cmnd *cmd = tw_dev->srb[request_id];
-       struct pci_dev *pdev = tw_dev->tw_pci_dev;
-       int retval = 0;
-
-       if (cmd->use_sg == 0)
-               goto out;
-
-       use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
 
-       if (use_sg == 0) {
+       use_sg = scsi_dma_map(cmd);
+       if (!use_sg)
+               return 0;
+       else if (use_sg < 0) {
                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list");
-               goto out;
+               return 0;
        }
 
        cmd->SCp.phase = TW_PHASE_SGLIST;
        cmd->SCp.have_data_in = use_sg;
-       retval = use_sg;
-out:
-       return retval;
-} /* End twa_map_scsi_sg_data() */
-
-/* This function will perform a pci-dma map for a single buffer */
-static dma_addr_t twa_map_scsi_single_data(TW_Device_Extension *tw_dev, int request_id)
-{
-       dma_addr_t mapping;
-       struct scsi_cmnd *cmd = tw_dev->srb[request_id];
-       struct pci_dev *pdev = tw_dev->tw_pci_dev;
-       dma_addr_t retval = 0;
-
-       if (cmd->request_bufflen == 0) {
-               retval = 0;
-               goto out;
-       }
-
-       mapping = pci_map_single(pdev, cmd->request_buffer, cmd->request_bufflen, DMA_BIDIRECTIONAL);
-
-       if (mapping == 0) {
-               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Failed to map page");
-               goto out;
-       }
 
-       cmd->SCp.phase = TW_PHASE_SINGLE;
-       cmd->SCp.have_data_in = mapping;
-       retval = mapping;
-out:
-       return retval;
-} /* End twa_map_scsi_single_data() */
+       return use_sg;
+} /* End twa_map_scsi_sg_data() */
 
 /* This function will poll for a response interrupt of a request */
 static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
@@ -1815,15 +1787,13 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
        u32 num_sectors = 0x0;
        int i, sg_count;
        struct scsi_cmnd *srb = NULL;
-       struct scatterlist *sglist = NULL;
-       dma_addr_t buffaddr = 0x0;
+       struct scatterlist *sglist = NULL, *sg;
        int retval = 1;
 
        if (tw_dev->srb[request_id]) {
-               if (tw_dev->srb[request_id]->request_buffer) {
-                       sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
-               }
                srb = tw_dev->srb[request_id];
+               if (scsi_sglist(srb))
+                       sglist = scsi_sglist(srb);
        }
 
        /* Initialize command packet */
@@ -1856,32 +1826,12 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
 
        if (!sglistarg) {
                /* Map sglist from scsi layer to cmd packet */
-               if (tw_dev->srb[request_id]->use_sg == 0) {
-                       if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) {
-                               command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
-                               command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH);
-                               if (tw_dev->srb[request_id]->sc_data_direction == DMA_TO_DEVICE || tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL)
-                                       memcpy(tw_dev->generic_buffer_virt[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen);
-                       } else {
-                               buffaddr = twa_map_scsi_single_data(tw_dev, request_id);
-                               if (buffaddr == 0)
-                                       goto out;
-
-                               command_packet->sg_list[0].address = TW_CPU_TO_SGL(buffaddr);
-                               command_packet->sg_list[0].length = cpu_to_le32(tw_dev->srb[request_id]->request_bufflen);
-                       }
-                       command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), 1));
 
-                       if (command_packet->sg_list[0].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) {
-                               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2d, "Found unaligned address during execute scsi");
-                               goto out;
-                       }
-               }
-
-               if (tw_dev->srb[request_id]->use_sg > 0) {
-                       if ((tw_dev->srb[request_id]->use_sg == 1) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) {
-                               if (tw_dev->srb[request_id]->sc_data_direction == DMA_TO_DEVICE || tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL) {
-                                       struct scatterlist *sg = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
+               if (scsi_sg_count(srb)) {
+                       if ((scsi_sg_count(srb) == 1) &&
+                           (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
+                               if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) {
+                                       struct scatterlist *sg = scsi_sglist(srb);
                                        char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
                                        memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
                                        kunmap_atomic(buf - sg->offset, KM_IRQ0);
@@ -1893,16 +1843,16 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
                                if (sg_count == 0)
                                        goto out;
 
-                               for (i = 0; i < sg_count; i++) {
-                                       command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(&sglist[i]));
-                                       command_packet->sg_list[i].length = cpu_to_le32(sg_dma_len(&sglist[i]));
+                               scsi_for_each_sg(srb, sg, sg_count, i) {
+                                       command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
+                                       command_packet->sg_list[i].length = cpu_to_le32(sg_dma_len(sg));
                                        if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) {
                                                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi");
                                                goto out;
                                        }
                                }
                        }
-                       command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), tw_dev->srb[request_id]->use_sg));
+                       command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
                }
        } else {
                /* Internal cdb post */
@@ -1932,7 +1882,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
 
        /* Update SG statistics */
        if (srb) {
-               tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
+               tw_dev->sgl_entries = scsi_sg_count(tw_dev->srb[request_id]);
                if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
                        tw_dev->max_sgl_entries = tw_dev->sgl_entries;
        }
@@ -1951,16 +1901,13 @@ out:
 /* This function completes an execute scsi operation */
 static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id)
 {
-       if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH &&
-           (tw_dev->srb[request_id]->sc_data_direction == DMA_FROM_DEVICE ||
-            tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL)) {
-               if (tw_dev->srb[request_id]->use_sg == 0) {
-                       memcpy(tw_dev->srb[request_id]->request_buffer,
-                              tw_dev->generic_buffer_virt[request_id],
-                              tw_dev->srb[request_id]->request_bufflen);
-               }
-               if (tw_dev->srb[request_id]->use_sg == 1) {
-                       struct scatterlist *sg = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
+       struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+
+       if (scsi_bufflen(cmd) < TW_MIN_SGL_LENGTH &&
+           (cmd->sc_data_direction == DMA_FROM_DEVICE ||
+            cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
+               if (scsi_sg_count(cmd) == 1) {
+                       struct scatterlist *sg = scsi_sglist(tw_dev->srb[request_id]);
                        char *buf;
                        unsigned long flags = 0;
                        local_irq_save(flags);
@@ -2017,16 +1964,8 @@ static char *twa_string_lookup(twa_message_type *table, unsigned int code)
 static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
 {
        struct scsi_cmnd *cmd = tw_dev->srb[request_id];
-       struct pci_dev *pdev = tw_dev->tw_pci_dev;
 
-       switch(cmd->SCp.phase) {
-       case TW_PHASE_SINGLE:
-               pci_unmap_single(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, DMA_BIDIRECTIONAL);
-               break;
-       case TW_PHASE_SGLIST:
-               pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
-               break;
-       }
+       scsi_dma_unmap(cmd);
 } /* End twa_unmap_scsi_data() */
 
 /* scsi_host_template initializer */
index 656bdb1352d8d8ee44991ecb8e2ca75f0f5b05a6..c7995fc216e8ed43a572ea9e41f482fc7c6a88c8 100644 (file)
@@ -1273,57 +1273,24 @@ static int tw_map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
        int use_sg;
 
        dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data()\n");
-       
-       if (cmd->use_sg == 0)
-               return 0;
 
-       use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
-       
-       if (use_sg == 0) {
+       use_sg = scsi_dma_map(cmd);
+       if (use_sg < 0) {
                printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
                return 0;
        }
 
        cmd->SCp.phase = TW_PHASE_SGLIST;
        cmd->SCp.have_data_in = use_sg;
-       
+
        return use_sg;
 } /* End tw_map_scsi_sg_data() */
 
-static u32 tw_map_scsi_single_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
-{
-       dma_addr_t mapping;
-
-       dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data()\n");
-
-       if (cmd->request_bufflen == 0)
-               return 0;
-
-       mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), offset_in_page(cmd->request_buffer), cmd->request_bufflen, DMA_BIDIRECTIONAL);
-
-       if (mapping == 0) {
-               printk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data(): pci_map_page() failed.\n");
-               return 0;
-       }
-
-       cmd->SCp.phase = TW_PHASE_SINGLE;
-       cmd->SCp.have_data_in = mapping;
-
-       return mapping;
-} /* End tw_map_scsi_single_data() */
-
 static void tw_unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
 {
        dprintk(KERN_WARNING "3w-xxxx: tw_unmap_scsi_data()\n");
 
-       switch(cmd->SCp.phase) {
-               case TW_PHASE_SINGLE:
-                       pci_unmap_page(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, DMA_BIDIRECTIONAL);
-                       break;
-               case TW_PHASE_SGLIST:
-                       pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
-                       break;
-       }
+       scsi_dma_unmap(cmd);
 } /* End tw_unmap_scsi_data() */
 
 /* This function will reset a device extension */
@@ -1499,27 +1466,16 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
        void *buf;
        unsigned int transfer_len;
        unsigned long flags = 0;
+       struct scatterlist *sg = scsi_sglist(cmd);
 
-       if (cmd->use_sg) {
-               struct scatterlist *sg =
-                       (struct scatterlist *)cmd->request_buffer;
-               local_irq_save(flags);
-               buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
-               transfer_len = min(sg->length, len);
-       } else {
-               buf = cmd->request_buffer;
-               transfer_len = min(cmd->request_bufflen, len);
-       }
+       local_irq_save(flags);
+       buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+       transfer_len = min(sg->length, len);
 
        memcpy(buf, data, transfer_len);
-       
-       if (cmd->use_sg) {
-               struct scatterlist *sg;
 
-               sg = (struct scatterlist *)cmd->request_buffer;
-               kunmap_atomic(buf - sg->offset, KM_IRQ0);
-               local_irq_restore(flags);
-       }
+       kunmap_atomic(buf - sg->offset, KM_IRQ0);
+       local_irq_restore(flags);
 }
 
 /* This function is called by the isr to complete an inquiry command */
@@ -1764,19 +1720,20 @@ static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
 {
        TW_Command *command_packet;
        unsigned long command_que_value;
-       u32 lba = 0x0, num_sectors = 0x0, buffaddr = 0x0;
+       u32 lba = 0x0, num_sectors = 0x0;
        int i, use_sg;
        struct scsi_cmnd *srb;
-       struct scatterlist *sglist;
+       struct scatterlist *sglist, *sg;
 
        dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
 
-       if (tw_dev->srb[request_id]->request_buffer == NULL) {
+       srb = tw_dev->srb[request_id];
+
+       sglist = scsi_sglist(srb);
+       if (!sglist) {
                printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
                return 1;
        }
-       sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
-       srb = tw_dev->srb[request_id];
 
        /* Initialize command packet */
        command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
@@ -1819,33 +1776,18 @@ static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
        command_packet->byte8.io.lba = lba;
        command_packet->byte6.block_count = num_sectors;
 
-       /* Do this if there are no sg list entries */
-       if (tw_dev->srb[request_id]->use_sg == 0) {    
-               dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
-               buffaddr = tw_map_scsi_single_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
-               if (buffaddr == 0)
-                       return 1;
+       use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
+       if (!use_sg)
+               return 1;
 
-               command_packet->byte8.io.sgl[0].address = buffaddr;
-               command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
+       scsi_for_each_sg(tw_dev->srb[request_id], sg, use_sg, i) {
+               command_packet->byte8.io.sgl[i].address = sg_dma_address(sg);
+               command_packet->byte8.io.sgl[i].length = sg_dma_len(sg);
                command_packet->size+=2;
        }
 
-       /* Do this if we have multiple sg list entries */
-       if (tw_dev->srb[request_id]->use_sg > 0) {
-               use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
-               if (use_sg == 0)
-                       return 1;
-
-               for (i=0;i<use_sg; i++) {
-                       command_packet->byte8.io.sgl[i].address = sg_dma_address(&sglist[i]);
-                       command_packet->byte8.io.sgl[i].length = sg_dma_len(&sglist[i]);
-                       command_packet->size+=2;
-               }
-       }
-
        /* Update SG statistics */
-       tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
+       tw_dev->sgl_entries = scsi_sg_count(tw_dev->srb[request_id]);
        if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
                tw_dev->max_sgl_entries = tw_dev->sgl_entries;
 
index cb02656eb54c1e9592fd552f1014a556981ca8e0..71ff3fbfce12559d161fed31be5d6d1f90101677 100644 (file)
@@ -267,8 +267,6 @@ NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata,
                offset = max_offset;
        }
        if(XFERP < min_xferp) {
-               printk(KERN_WARNING "53c700: XFERP %d is less than minium, setting to %d\n",
-                      XFERP,  min_xferp);
                XFERP =  min_xferp;
        }
        return (offset & 0x0f) | (XFERP & 0x07)<<4;
@@ -585,16 +583,8 @@ NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, struct scsi_cmnd *SCp,
              struct NCR_700_command_slot *slot)
 {
        if(SCp->sc_data_direction != DMA_NONE &&
-          SCp->sc_data_direction != DMA_BIDIRECTIONAL) {
-               if(SCp->use_sg) {
-                       dma_unmap_sg(hostdata->dev, SCp->request_buffer,
-                                    SCp->use_sg, SCp->sc_data_direction);
-               } else {
-                       dma_unmap_single(hostdata->dev, slot->dma_handle,
-                                        SCp->request_bufflen,
-                                        SCp->sc_data_direction);
-               }
-       }
+          SCp->sc_data_direction != DMA_BIDIRECTIONAL)
+               scsi_dma_unmap(SCp);
 }
 
 STATIC inline void
@@ -661,7 +651,6 @@ NCR_700_chip_setup(struct Scsi_Host *host)
 {
        struct NCR_700_Host_Parameters *hostdata = 
                (struct NCR_700_Host_Parameters *)host->hostdata[0];
-       __u32 dcntl_extra = 0;
        __u8 min_period;
        __u8 min_xferp = (hostdata->chip710 ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP);
 
@@ -686,13 +675,14 @@ NCR_700_chip_setup(struct Scsi_Host *host)
                                burst_disable = BURST_DISABLE;
                                break;
                }
-               dcntl_extra = COMPAT_700_MODE;
+               hostdata->dcntl_extra |= COMPAT_700_MODE;
 
-               NCR_700_writeb(dcntl_extra, host, DCNTL_REG);
+               NCR_700_writeb(hostdata->dcntl_extra, host, DCNTL_REG);
                NCR_700_writeb(burst_length | hostdata->dmode_extra,
                               host, DMODE_710_REG);
-               NCR_700_writeb(burst_disable | (hostdata->differential ? 
-                                               DIFF : 0), host, CTEST7_REG);
+               NCR_700_writeb(burst_disable | hostdata->ctest7_extra |
+                              (hostdata->differential ? DIFF : 0),
+                              host, CTEST7_REG);
                NCR_700_writeb(BTB_TIMER_DISABLE, host, CTEST0_REG);
                NCR_700_writeb(FULL_ARBITRATION | ENABLE_PARITY | PARITY
                               | AUTO_ATN, host, SCNTL0_REG);
@@ -727,13 +717,13 @@ NCR_700_chip_setup(struct Scsi_Host *host)
                 * of spec: sync divider 2, async divider 3 */
                DEBUG(("53c700: sync 2 async 3\n"));
                NCR_700_writeb(SYNC_DIV_2_0, host, SBCL_REG);
-               NCR_700_writeb(ASYNC_DIV_3_0 | dcntl_extra, host, DCNTL_REG);
+               NCR_700_writeb(ASYNC_DIV_3_0 | hostdata->dcntl_extra, host, DCNTL_REG);
                hostdata->sync_clock = hostdata->clock/2;
        } else  if(hostdata->clock > 50  && hostdata->clock <= 75) {
                /* sync divider 1.5, async divider 3 */
                DEBUG(("53c700: sync 1.5 async 3\n"));
                NCR_700_writeb(SYNC_DIV_1_5, host, SBCL_REG);
-               NCR_700_writeb(ASYNC_DIV_3_0 | dcntl_extra, host, DCNTL_REG);
+               NCR_700_writeb(ASYNC_DIV_3_0 | hostdata->dcntl_extra, host, DCNTL_REG);
                hostdata->sync_clock = hostdata->clock*2;
                hostdata->sync_clock /= 3;
                
@@ -741,18 +731,18 @@ NCR_700_chip_setup(struct Scsi_Host *host)
                /* sync divider 1, async divider 2 */
                DEBUG(("53c700: sync 1 async 2\n"));
                NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
-               NCR_700_writeb(ASYNC_DIV_2_0 | dcntl_extra, host, DCNTL_REG);
+               NCR_700_writeb(ASYNC_DIV_2_0 | hostdata->dcntl_extra, host, DCNTL_REG);
                hostdata->sync_clock = hostdata->clock;
        } else if(hostdata->clock > 25 && hostdata->clock <=37) {
                /* sync divider 1, async divider 1.5 */
                DEBUG(("53c700: sync 1 async 1.5\n"));
                NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
-               NCR_700_writeb(ASYNC_DIV_1_5 | dcntl_extra, host, DCNTL_REG);
+               NCR_700_writeb(ASYNC_DIV_1_5 | hostdata->dcntl_extra, host, DCNTL_REG);
                hostdata->sync_clock = hostdata->clock;
        } else {
                DEBUG(("53c700: sync 1 async 1\n"));
                NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
-               NCR_700_writeb(ASYNC_DIV_1_0 | dcntl_extra, host, DCNTL_REG);
+               NCR_700_writeb(ASYNC_DIV_1_0 | hostdata->dcntl_extra, host, DCNTL_REG);
                /* sync divider 1, async divider 1 */
                hostdata->sync_clock = hostdata->clock;
        }
@@ -1263,14 +1253,13 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
                       host->host_no, pun, lun, NCR_700_condition[i],
                       NCR_700_phase[j], dsp - hostdata->pScript);
                if(SCp != NULL) {
-                       scsi_print_command(SCp);
+                       struct scatterlist *sg;
 
-                       if(SCp->use_sg) {
-                               for(i = 0; i < SCp->use_sg + 1; i++) {
-                                       printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->request_buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr);
-                               }
+                       scsi_print_command(SCp);
+                       scsi_for_each_sg(SCp, sg, scsi_sg_count(SCp) + 1, i) {
+                               printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, sg->length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr);
                        }
-               }              
+               }
                NCR_700_internal_bus_reset(host);
        } else if((dsps & 0xfffff000) == A_DEBUG_INTERRUPT) {
                printk(KERN_NOTICE "scsi%d (%d:%d) DEBUG INTERRUPT %d AT %08x[%04x], continuing\n",
@@ -1844,8 +1833,8 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
        }
        /* sanity check: some of the commands generated by the mid-layer
         * have an eccentric idea of their sc_data_direction */
-       if(!SCp->use_sg && !SCp->request_bufflen 
-          && SCp->sc_data_direction != DMA_NONE) {
+       if(!scsi_sg_count(SCp) && !scsi_bufflen(SCp) &&
+          SCp->sc_data_direction != DMA_NONE) {
 #ifdef NCR_700_DEBUG
                printk("53c700: Command");
                scsi_print_command(SCp);
@@ -1887,31 +1876,15 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
                int i;
                int sg_count;
                dma_addr_t vPtr = 0;
+               struct scatterlist *sg;
                __u32 count = 0;
 
-               if(SCp->use_sg) {
-                       sg_count = dma_map_sg(hostdata->dev,
-                                             SCp->request_buffer, SCp->use_sg,
-                                             direction);
-               } else {
-                       vPtr = dma_map_single(hostdata->dev,
-                                             SCp->request_buffer, 
-                                             SCp->request_bufflen,
-                                             direction);
-                       count = SCp->request_bufflen;
-                       slot->dma_handle = vPtr;
-                       sg_count = 1;
-               }
-                       
+               sg_count = scsi_dma_map(SCp);
+               BUG_ON(sg_count < 0);
 
-               for(i = 0; i < sg_count; i++) {
-
-                       if(SCp->use_sg) {
-                               struct scatterlist *sg = SCp->request_buffer;
-
-                               vPtr = sg_dma_address(&sg[i]);
-                               count = sg_dma_len(&sg[i]);
-                       }
+               scsi_for_each_sg(SCp, sg, sg_count, i) {
+                       vPtr = sg_dma_address(sg);
+                       count = sg_dma_len(sg);
 
                        slot->SG[i].ins = bS_to_host(move_ins | count);
                        DEBUG((" scatter block %d: move %d[%08x] from 0x%lx\n",
index 841e1bb27d57eb54ae0142c2c64e4009fdb1cc51..e06bdfeab420013f4655251623a3d6b6f5e56f9b 100644 (file)
@@ -177,6 +177,7 @@ struct NCR_700_command_slot {
        __u8    state;
        #define NCR_700_FLAG_AUTOSENSE  0x01
        __u8    flags;
+       __u8    pad1[2];        /* Needed for m68k where min alignment is 2 bytes */
        int     tag;
        __u32   resume_offset;
        struct scsi_cmnd *cmnd;
@@ -196,6 +197,8 @@ struct NCR_700_Host_Parameters {
        void __iomem    *base;          /* the base for the port (copied to host) */
        struct device   *dev;
        __u32   dmode_extra;    /* adjustable bus settings */
+       __u32   dcntl_extra;    /* adjustable bus settings */
+       __u32   ctest7_extra;   /* adjustable bus settings */
        __u32   differential:1; /* if we are differential */
 #ifdef CONFIG_53C700_LE_ON_BE
        /* This option is for HP only.  Set it if your chip is wired for
@@ -352,6 +355,7 @@ struct NCR_700_Host_Parameters {
 #define                SEL_TIMEOUT_DISABLE     0x10 /* 710 only */
 #define         DFP                     0x08
 #define         EVP                     0x04
+#define         CTEST7_TT1              0x02
 #define                DIFF                    0x01
 #define CTEST6_REG                      0x1A
 #define        TEMP_REG                        0x1C
@@ -385,6 +389,7 @@ struct NCR_700_Host_Parameters {
 #define                SOFTWARE_RESET          0x01
 #define                COMPAT_700_MODE         0x01
 #define        SCRPTS_16BITS           0x20
+#define                EA_710                  0x20
 #define                ASYNC_DIV_2_0           0x00
 #define                ASYNC_DIV_1_5           0x40
 #define                ASYNC_DIV_1_0           0x80
diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c
deleted file mode 100644 (file)
index 93b41f4..0000000
+++ /dev/null
@@ -1,6102 +0,0 @@
-/*
- * 53c710 driver.  Modified from Drew Eckhardts driver
- * for 53c810 by Richard Hirst [richard@sleepie.demon.co.uk]
- * Check out PERM_OPTIONS and EXPECTED_CLOCK, which may be defined in the
- * relevant machine specific file (eg. mvme16x.[ch], amiga7xx.[ch]).
- * There are also currently some defines at the top of 53c7xx.scr.
- * The chip type is #defined in script_asm.pl, as well as the Makefile.
- * Host scsi ID expected to be 7 - see NCR53c7x0_init().
- *
- * I have removed the PCI code and some of the 53c8xx specific code - 
- * simply to make this file smaller and easier to manage.
- *
- * MVME16x issues:
- *   Problems trying to read any chip registers in NCR53c7x0_init(), as they
- *   may never have been set by 16xBug (eg. If kernel has come in over tftp).
- */
-
-/*
- * Adapted for Linux/m68k Amiga platforms for the A4000T/A4091 and
- * WarpEngine SCSI controllers.
- * By Alan Hourihane <alanh@fairlite.demon.co.uk>
- * Thanks to Richard Hirst for making it possible with the MVME additions
- */
-
-/*
- * 53c710 rev 0 doesn't support add with carry.  Rev 1 and 2 does.  To
- * overcome this problem you can define FORCE_DSA_ALIGNMENT, which ensures
- * that the DSA address is always xxxxxx00.  If disconnection is not allowed,
- * then the script only ever tries to add small (< 256) positive offsets to
- * DSA, so lack of carry isn't a problem.  FORCE_DSA_ALIGNMENT can, of course,
- * be defined for all chip revisions at a small cost in memory usage.
- */
-
-#define FORCE_DSA_ALIGNMENT
-
-/*
- * Selection timer does not always work on the 53c710, depending on the
- * timing at the last disconnect, if this is a problem for you, try
- * using validids as detailed below.
- *
- * Options for the NCR7xx driver
- *
- * noasync:0           -       disables sync and asynchronous negotiation
- * nosync:0            -       disables synchronous negotiation (does async)
- * nodisconnect:0      -       disables disconnection
- * validids:0x??       -       Bitmask field that disallows certain ID's.
- *                     -       e.g.    0x03    allows ID 0,1
- *                     -               0x1F    allows ID 0,1,2,3,4
- * opthi:n             -       replace top word of options with 'n'
- * optlo:n             -       replace bottom word of options with 'n'
- *                     -       ALWAYS SPECIFY opthi THEN optlo <<<<<<<<<<
- */
-
-/*
- * PERM_OPTIONS are driver options which will be enabled for all NCR boards
- * in the system at driver initialization time.
- *
- * Don't THINK about touching these in PERM_OPTIONS : 
- *   OPTION_MEMORY_MAPPED 
- *     680x0 doesn't have an IO map!
- *
- *   OPTION_DEBUG_TEST1
- *     Test 1 does bus mastering and interrupt tests, which will help weed 
- *     out brain damaged main boards.
- *
- * Other PERM_OPTIONS settings are listed below.  Note the actual options
- * required are set in the relevant file (mvme16x.c, amiga7xx.c, etc):
- *
- *   OPTION_NO_ASYNC
- *     Don't negotiate for asynchronous transfers on the first command 
- *     when OPTION_ALWAYS_SYNCHRONOUS is set.  Useful for dain bramaged
- *     devices which do something bad rather than sending a MESSAGE 
- *     REJECT back to us like they should if they can't cope.
- *
- *   OPTION_SYNCHRONOUS
- *     Enable support for synchronous transfers.  Target negotiated 
- *     synchronous transfers will be responded to.  To initiate 
- *     a synchronous transfer request,  call 
- *
- *         request_synchronous (hostno, target) 
- *
- *     from within KGDB.
- *
- *   OPTION_ALWAYS_SYNCHRONOUS
- *     Negotiate for synchronous transfers with every target after
- *     driver initialization or a SCSI bus reset.  This is a bit dangerous, 
- *     since there are some dain bramaged SCSI devices which will accept
- *     SDTR messages but keep talking asynchronously.
- *
- *   OPTION_DISCONNECT
- *     Enable support for disconnect/reconnect.  To change the 
- *     default setting on a given host adapter, call
- *
- *         request_disconnect (hostno, allow)
- *
- *     where allow is non-zero to allow, 0 to disallow.
- * 
- *  If you really want to run 10MHz FAST SCSI-II transfers, you should 
- *  know that the NCR driver currently ignores parity information.  Most
- *  systems do 5MHz SCSI fine.  I've seen a lot that have problems faster
- *  than 8MHz.  To play it safe, we only request 5MHz transfers.
- *
- *  If you'd rather get 10MHz transfers, edit sdtr_message and change 
- *  the fourth byte from 50 to 25.
- */
-
-/*
- * Sponsored by 
- *     iX Multiuser Multitasking Magazine
- *     Hannover, Germany
- *     hm@ix.de
- *
- * Copyright 1993, 1994, 1995 Drew Eckhardt
- *      Visionary Computing 
- *      (Unix and Linux consulting and custom programming)
- *      drew@PoohSticks.ORG
- *     +1 (303) 786-7975
- *
- * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
- * 
- * For more information, please consult 
- *
- * NCR53C810 
- * SCSI I/O Processor
- * Programmer's Guide
- *
- * NCR 53C810
- * PCI-SCSI I/O Processor
- * Data Manual
- *
- * NCR 53C810/53C820
- * PCI-SCSI I/O Processor Design In Guide
- *
- * For literature on Symbios Logic Inc. formerly NCR, SCSI, 
- * and Communication products please call (800) 334-5454 or
- * (719) 536-3300. 
- * 
- * PCI BIOS Specification Revision
- * PCI Local Bus Specification
- * PCI System Design Guide
- *
- * PCI Special Interest Group
- * M/S HF3-15A
- * 5200 N.E. Elam Young Parkway
- * Hillsboro, Oregon 97124-6497
- * +1 (503) 696-2000 
- * +1 (800) 433-5177
- */
-
-/*
- * Design issues : 
- * The cumulative latency needed to propagate a read/write request 
- * through the file system, buffer cache, driver stacks, SCSI host, and 
- * SCSI device is ultimately the limiting factor in throughput once we 
- * have a sufficiently fast host adapter.
- *  
- * So, to maximize performance we want to keep the ratio of latency to data 
- * transfer time to a minimum by
- * 1.  Minimizing the total number of commands sent (typical command latency
- *     including drive and bus mastering host overhead is as high as 4.5ms)
- *     to transfer a given amount of data.  
- *
- *      This is accomplished by placing no arbitrary limit on the number
- *     of scatter/gather buffers supported, since we can transfer 1K
- *     per scatter/gather buffer without Eric's cluster patches, 
- *     4K with.  
- *
- * 2.  Minimizing the number of fatal interrupts serviced, since
- *     fatal interrupts halt the SCSI I/O processor.  Basically,
- *     this means offloading the practical maximum amount of processing 
- *     to the SCSI chip.
- * 
- *     On the NCR53c810/820/720,  this is accomplished by using 
- *             interrupt-on-the-fly signals when commands complete, 
- *             and only handling fatal errors and SDTR / WDTR  messages 
- *             in the host code.
- *
- *     On the NCR53c710, interrupts are generated as on the NCR53c8x0,
- *             only the lack of a interrupt-on-the-fly facility complicates
- *             things.   Also, SCSI ID registers and commands are 
- *             bit fielded rather than binary encoded.
- *             
- *     On the NCR53c700 and NCR53c700-66, operations that are done via 
- *             indirect, table mode on the more advanced chips must be
- *             replaced by calls through a jump table which 
- *             acts as a surrogate for the DSA.  Unfortunately, this 
- *             will mean that we must service an interrupt for each 
- *             disconnect/reconnect.
- * 
- * 3.  Eliminating latency by pipelining operations at the different levels.
- *     
- *     This driver allows a configurable number of commands to be enqueued
- *     for each target/lun combination (experimentally, I have discovered
- *     that two seems to work best) and will ultimately allow for 
- *     SCSI-II tagged queuing.
- *     
- *
- * Architecture : 
- * This driver is built around a Linux queue of commands waiting to 
- * be executed, and a shared Linux/NCR array of commands to start.  Commands
- * are transferred to the array  by the run_process_issue_queue() function 
- * which is called whenever a command completes.
- *
- * As commands are completed, the interrupt routine is triggered,
- * looks for commands in the linked list of completed commands with
- * valid status, removes these commands from a list of running commands, 
- * calls the done routine, and flags their target/luns as not busy.
- *
- * Due to limitations in the intelligence of the NCR chips, certain
- * concessions are made.  In many cases, it is easier to dynamically 
- * generate/fix-up code rather than calculate on the NCR at run time.  
- * So, code is generated or fixed up for
- *
- * - Handling data transfers, using a variable number of MOVE instructions
- *     interspersed with CALL MSG_IN, WHEN MSGIN instructions.
- *
- *     The DATAIN and DATAOUT routines are separate, so that an incorrect
- *     direction can be trapped, and space isn't wasted. 
- *
- *     It may turn out that we're better off using some sort 
- *     of table indirect instruction in a loop with a variable
- *     sized table on the NCR53c710 and newer chips.
- *
- * - Checking for reselection (NCR53c710 and better)
- *
- * - Handling the details of SCSI context switches (NCR53c710 and better),
- *     such as reprogramming appropriate synchronous parameters, 
- *     removing the dsa structure from the NCR's queue of outstanding
- *     commands, etc.
- *
- */
-
-#include <linux/module.h>
-
-
-#include <linux/types.h>
-#include <asm/setup.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/delay.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/time.h>
-#include <linux/blkdev.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <asm/pgtable.h>
-
-#ifdef CONFIG_AMIGA
-#include <asm/amigahw.h>
-#include <asm/amigaints.h>
-#include <asm/irq.h>
-
-#define BIG_ENDIAN
-#define NO_IO_SPACE
-#endif
-
-#ifdef CONFIG_MVME16x
-#include <asm/mvme16xhw.h>
-
-#define BIG_ENDIAN
-#define NO_IO_SPACE
-#define VALID_IDS
-#endif
-
-#ifdef CONFIG_BVME6000
-#include <asm/bvme6000hw.h>
-
-#define BIG_ENDIAN
-#define NO_IO_SPACE
-#define VALID_IDS
-#endif
-
-#include "scsi.h"
-#include <scsi/scsi_dbg.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_transport_spi.h>
-#include "53c7xx.h"
-#include <linux/stat.h>
-#include <linux/stddef.h>
-
-#ifdef NO_IO_SPACE
-/*
- * The following make the definitions in 53c7xx.h (write8, etc) smaller,
- * we don't have separate i/o space anyway.
- */
-#undef inb
-#undef outb
-#undef inw
-#undef outw
-#undef inl
-#undef outl
-#define inb(x)          1
-#define inw(x)          1
-#define inl(x)          1
-#define outb(x,y)       1
-#define outw(x,y)       1
-#define outl(x,y)       1
-#endif
-
-static int check_address (unsigned long addr, int size);
-static void dump_events (struct Scsi_Host *host, int count);
-static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host, 
-    int free, int issue);
-static void hard_reset (struct Scsi_Host *host);
-static void ncr_scsi_reset (struct Scsi_Host *host);
-static void print_lots (struct Scsi_Host *host);
-static void set_synchronous (struct Scsi_Host *host, int target, int sxfer, 
-    int scntl3, int now_connected);
-static int datapath_residual (struct Scsi_Host *host);
-static const char * sbcl_to_phase (int sbcl);
-static void print_progress (Scsi_Cmnd *cmd);
-static void print_queues (struct Scsi_Host *host);
-static void process_issue_queue (unsigned long flags);
-static int shutdown (struct Scsi_Host *host);
-static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);
-static int disable (struct Scsi_Host *host);
-static int NCR53c7xx_run_tests (struct Scsi_Host *host);
-static irqreturn_t NCR53c7x0_intr(int irq, void *dev_id);
-static void NCR53c7x0_intfly (struct Scsi_Host *host);
-static int ncr_halt (struct Scsi_Host *host);
-static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd 
-    *cmd);
-static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
-static void print_dsa (struct Scsi_Host *host, u32 *dsa,
-    const char *prefix);
-static int print_insn (struct Scsi_Host *host, const u32 *insn,
-    const char *prefix, int kernel);
-
-static void NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd);
-static void NCR53c7x0_init_fixup (struct Scsi_Host *host);
-static int NCR53c7x0_dstat_sir_intr (struct Scsi_Host *host, struct 
-    NCR53c7x0_cmd *cmd);
-static void NCR53c7x0_soft_reset (struct Scsi_Host *host);
-
-/* Size of event list (per host adapter) */
-static int track_events = 0;
-static struct Scsi_Host *first_host = NULL;    /* Head of list of NCR boards */
-static struct scsi_host_template *the_template = NULL;
-
-/* NCR53c710 script handling code */
-
-#include "53c7xx_d.h"
-#ifdef A_int_debug_sync
-#define DEBUG_SYNC_INTR A_int_debug_sync
-#endif
-int NCR53c7xx_script_len = sizeof (SCRIPT);
-int NCR53c7xx_dsa_len = A_dsa_end + Ent_dsa_zero - Ent_dsa_code_template;
-#ifdef FORCE_DSA_ALIGNMENT
-int CmdPageStart = (0 - Ent_dsa_zero - sizeof(struct NCR53c7x0_cmd)) & 0xff;
-#endif
-
-static char *setup_strings[] =
-       {"","","","","","","",""};
-
-#define MAX_SETUP_STRINGS ARRAY_SIZE(setup_strings)
-#define SETUP_BUFFER_SIZE 200
-static char setup_buffer[SETUP_BUFFER_SIZE];
-static char setup_used[MAX_SETUP_STRINGS];
-
-void ncr53c7xx_setup (char *str, int *ints)
-{
-   int i;
-   char *p1, *p2;
-
-   p1 = setup_buffer;
-   *p1 = '\0';
-   if (str)
-      strncpy(p1, str, SETUP_BUFFER_SIZE - strlen(setup_buffer));
-   setup_buffer[SETUP_BUFFER_SIZE - 1] = '\0';
-   p1 = setup_buffer;
-   i = 0;
-   while (*p1 && (i < MAX_SETUP_STRINGS)) {
-      p2 = strchr(p1, ',');
-      if (p2) {
-         *p2 = '\0';
-         if (p1 != p2)
-            setup_strings[i] = p1;
-         p1 = p2 + 1;
-         i++;
-         }
-      else {
-         setup_strings[i] = p1;
-         break;
-         }
-      }
-   for (i=0; i<MAX_SETUP_STRINGS; i++)
-      setup_used[i] = 0;
-}
-
-
-/* check_setup_strings() returns index if key found, 0 if not
- */
-
-static int check_setup_strings(char *key, int *flags, int *val, char *buf)
-{
-int x;
-char *cp;
-
-   for  (x=0; x<MAX_SETUP_STRINGS; x++) {
-      if (setup_used[x])
-         continue;
-      if (!strncmp(setup_strings[x], key, strlen(key)))
-         break;
-      if (!strncmp(setup_strings[x], "next", strlen("next")))
-         return 0;
-      }
-   if (x == MAX_SETUP_STRINGS)
-      return 0;
-   setup_used[x] = 1;
-   cp = setup_strings[x] + strlen(key);
-   *val = -1;
-   if (*cp != ':')
-      return ++x;
-   cp++;
-   if ((*cp >= '0') && (*cp <= '9')) {
-      *val = simple_strtoul(cp,NULL,0);
-      }
-   return ++x;
-}
-
-
-
-/*
- * KNOWN BUGS :
- * - There is some sort of conflict when the PPP driver is compiled with 
- *     support for 16 channels?
- * 
- * - On systems which predate the 1.3.x initialization order change,
- *      the NCR driver will cause Cannot get free page messages to appear.  
- *      These are harmless, but I don't know of an easy way to avoid them.
- *
- * - With OPTION_DISCONNECT, on two systems under unknown circumstances,
- *     we get a PHASE MISMATCH with DSA set to zero (suggests that we 
- *     are occurring somewhere in the reselection code) where 
- *     DSP=some value DCMD|DBC=same value.  
- *     
- *     Closer inspection suggests that we may be trying to execute
- *     some portion of the DSA?
- * scsi0 : handling residual transfer (+ 0 bytes from DMA FIFO)
- * scsi0 : handling residual transfer (+ 0 bytes from DMA FIFO)
- * scsi0 : no current command : unexpected phase MSGIN.
- *         DSP=0x1c46cc, DCMD|DBC=0x1c46ac, DSA=0x0
- *         DSPS=0x0, TEMP=0x1c3e70, DMODE=0x80
- * scsi0 : DSP->
- * 001c46cc : 0x001c46cc 0x00000000
- * 001c46d4 : 0x001c5ea0 0x000011f8
- *
- *     Changed the print code in the phase_mismatch handler so
- *     that we call print_lots to try to diagnose this.
- *
- */
-
-/* 
- * Possible future direction of architecture for max performance :
- *
- * We're using a single start array for the NCR chip.  This is 
- * sub-optimal, because we cannot add a command which would conflict with 
- * an executing command to this start queue, and therefore must insert the 
- * next command for a given I/T/L combination after the first has completed;
- * incurring our interrupt latency between SCSI commands.
- *
- * To allow further pipelining of the NCR and host CPU operation, we want 
- * to set things up so that immediately on termination of a command destined 
- * for a given LUN, we get that LUN busy again.  
- * 
- * To do this, we need to add a 32 bit pointer to which is jumped to 
- * on completion of a command.  If no new command is available, this 
- * would point to the usual DSA issue queue select routine.
- *
- * If one were, it would point to a per-NCR53c7x0_cmd select routine 
- * which starts execution immediately, inserting the command at the head 
- * of the start queue if the NCR chip is selected or reselected.
- *
- * We would change so that we keep a list of outstanding commands 
- * for each unit, rather than a single running_list.  We'd insert 
- * a new command into the right running list; if the NCR didn't 
- * have something running for that yet, we'd put it in the 
- * start queue as well.  Some magic needs to happen to handle the 
- * race condition between the first command terminating before the 
- * new one is written.
- *
- * Potential for profiling : 
- * Call do_gettimeofday(struct timeval *tv) to get 800ns resolution.
- */
-
-
-/*
- * TODO : 
- * 1.  To support WIDE transfers, not much needs to happen.  We
- *     should do CHMOVE instructions instead of MOVEs when
- *     we have scatter/gather segments of uneven length.  When
- *     we do this, we need to handle the case where we disconnect
- *     between segments.
- * 
- * 2.  Currently, when Icky things happen we do a FATAL().  Instead,
- *     we want to do an integrity check on the parts of the NCR hostdata
- *     structure which were initialized at boot time; FATAL() if that 
- *     fails, and otherwise try to recover.  Keep track of how many
- *     times this has happened within a single SCSI command; if it 
- *     gets excessive, then FATAL().
- *
- * 3.  Parity checking is currently disabled, and a few things should 
- *     happen here now that we support synchronous SCSI transfers :
- *     1.  On soft-reset, we shoould set the EPC (Enable Parity Checking)
- *        and AAP (Assert SATN/ on parity error) bits in SCNTL0.
- *     
- *     2.  We should enable the parity interrupt in the SIEN0 register.
- * 
- *     3.  intr_phase_mismatch() needs to believe that message out is 
- *        always an "acceptable" phase to have a mismatch in.  If 
- *        the old phase was MSG_IN, we should send a MESSAGE PARITY 
- *        error.  If the old phase was something else, we should send
- *        a INITIATOR_DETECTED_ERROR message.  Note that this could
- *        cause a RESTORE POINTERS message; so we should handle that 
- *        correctly first.  Instead, we should probably do an 
- *        initiator_abort.
- *
- * 4.  MPEE bit of CTEST4 should be set so we get interrupted if 
- *     we detect an error.
- *
- *  
- * 5.  The initial code has been tested on the NCR53c810.  I don't 
- *     have access to NCR53c700, 700-66 (Forex boards), NCR53c710
- *     (NCR Pentium systems), NCR53c720, NCR53c820, or NCR53c825 boards to 
- *     finish development on those platforms.
- *
- *     NCR53c820/825/720 - need to add wide transfer support, including WDTR 
- *                     negotiation, programming of wide transfer capabilities
- *             on reselection and table indirect selection.
- *
- *     NCR53c710 - need to add fatal interrupt or GEN code for 
- *             command completion signaling.   Need to modify all 
- *             SDID, SCID, etc. registers, and table indirect select code 
- *             since these use bit fielded (ie 1<<target) instead of 
- *             binary encoded target ids.  Need to accommodate
- *             different register mappings, probably scan through
- *             the SCRIPT code and change the non SFBR register operand
- *             of all MOVE instructions.
- *
- *             It is rather worse than this actually, the 710 corrupts
- *             both TEMP and DSA when you do a MOVE MEMORY.  This
- *             screws you up all over the place.  MOVE MEMORY 4 with a
- *             destination of DSA seems to work OK, which helps some.
- *             Richard Hirst  richard@sleepie.demon.co.uk
- * 
- *     NCR53c700/700-66 - need to add code to refix addresses on 
- *             every nexus change, eliminate all table indirect code,
- *             very messy.
- *
- * 6.  The NCR53c7x0 series is very popular on other platforms that 
- *     could be running Linux - ie, some high performance AMIGA SCSI 
- *     boards use it.  
- *     
- *     So, I should include #ifdef'd code so that it is 
- *     compatible with these systems.
- *     
- *     Specifically, the little Endian assumptions I made in my 
- *     bit fields need to change, and if the NCR doesn't see memory
- *     the right way, we need to provide options to reverse words
- *     when the scripts are relocated.
- *
- * 7.  Use vremap() to access memory mapped boards.  
- */
-
-/* 
- * Allow for simultaneous existence of multiple SCSI scripts so we 
- * can have a single driver binary for all of the family.
- *
- * - one for NCR53c700 and NCR53c700-66 chips  (not yet supported)
- * - one for rest (only the NCR53c810, 815, 820, and 825 are currently 
- *     supported)
- * 
- * So that we only need two SCSI scripts, we need to modify things so
- * that we fixup register accesses in READ/WRITE instructions, and 
- * we'll also have to accommodate the bit vs. binary encoding of IDs
- * with the 7xx chips.
- */
-
-#define ROUNDUP(adr,type)      \
-  ((void *) (((long) (adr) + sizeof(type) - 1) & ~(sizeof(type) - 1)))
-
-
-/*
- * Function: issue_to_cmd
- *
- * Purpose: convert jump instruction in issue array to NCR53c7x0_cmd
- *     structure pointer.  
- *
- * Inputs; issue - pointer to start of NOP or JUMP instruction
- *     in issue array.
- *
- * Returns: pointer to command on success; 0 if opcode is NOP.
- */
-
-static inline struct NCR53c7x0_cmd *
-issue_to_cmd (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
-    u32 *issue)
-{
-    return (issue[0] != hostdata->NOP_insn) ? 
-    /* 
-     * If the IF TRUE bit is set, it's a JUMP instruction.  The
-     * operand is a bus pointer to the dsa_begin routine for this DSA.  The
-     * dsa field of the NCR53c7x0_cmd structure starts with the 
-     * DSA code template.  By converting to a virtual address,
-     * subtracting the code template size, and offset of the 
-     * dsa field, we end up with a pointer to the start of the 
-     * structure (alternatively, we could use the 
-     * dsa_cmnd field, an anachronism from when we weren't
-     * sure what the relationship between the NCR structures
-     * and host structures were going to be.
-     */
-       (struct NCR53c7x0_cmd *) ((char *) bus_to_virt (issue[1]) - 
-           (hostdata->E_dsa_code_begin - hostdata->E_dsa_code_template) -
-           offsetof(struct NCR53c7x0_cmd, dsa)) 
-    /* If the IF TRUE bit is not set, it's a NOP */
-       : NULL;
-}
-
-
-/* 
- * FIXME: we should junk these, in favor of synchronous_want and 
- * wide_want in the NCR53c7x0_hostdata structure.
- */
-
-/* Template for "preferred" synchronous transfer parameters. */
-
-static const unsigned char sdtr_message[] = {
-#ifdef CONFIG_SCSI_NCR53C7xx_FAST
-    EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 25 /* *4ns */, 8 /* off */
-#else
-    EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 50 /* *4ns */, 8 /* off */ 
-#endif
-};
-
-/* Template to request asynchronous transfers */
-
-static const unsigned char async_message[] = {
-    EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 0, 0 /* asynchronous */
-};
-
-/* Template for "preferred" WIDE transfer parameters */
-
-static const unsigned char wdtr_message[] = {
-    EXTENDED_MESSAGE, 2 /* length */, EXTENDED_WDTR, 1 /* 2^1 bytes */
-};
-
-#if 0
-/*
- * Function : struct Scsi_Host *find_host (int host)
- * 
- * Purpose : KGDB support function which translates a host number 
- *     to a host structure. 
- *
- * Inputs : host - number of SCSI host
- *
- * Returns : NULL on failure, pointer to host structure on success.
- */
-
-static struct Scsi_Host *
-find_host (int host) {
-    struct Scsi_Host *h;
-    for (h = first_host; h && h->host_no != host; h = h->next);
-    if (!h) {
-       printk (KERN_ALERT "scsi%d not found\n", host);
-       return NULL;
-    } else if (h->hostt != the_template) {
-       printk (KERN_ALERT "scsi%d is not a NCR board\n", host);
-       return NULL;
-    }
-    return h;
-}
-
-#if 0
-/*
- * Function : request_synchronous (int host, int target)
- * 
- * Purpose : KGDB interface which will allow us to negotiate for 
- *     synchronous transfers.  This ill be replaced with a more 
- *     integrated function; perhaps a new entry in the scsi_host 
- *     structure, accessible via an ioctl() or perhaps /proc/scsi.
- *
- * Inputs : host - number of SCSI host; target - number of target.
- *
- * Returns : 0 when negotiation has been setup for next SCSI command,
- *     -1 on failure.
- */
-
-static int
-request_synchronous (int host, int target) {
-    struct Scsi_Host *h;
-    struct NCR53c7x0_hostdata *hostdata;
-    unsigned long flags;
-    if (target < 0) {
-       printk (KERN_ALERT "target %d is bogus\n", target);
-       return -1;
-    }
-    if (!(h = find_host (host)))
-       return -1;
-    else if (h->this_id == target) {
-       printk (KERN_ALERT "target %d is host ID\n", target);
-       return -1;
-    } 
-    else if (target >= h->max_id) {
-       printk (KERN_ALERT "target %d exceeds maximum of %d\n", target,
-           h->max_id);
-       return -1;
-    }
-    hostdata = (struct NCR53c7x0_hostdata *)h->hostdata[0];
-
-    local_irq_save(flags);
-    if (hostdata->initiate_sdtr & (1 << target)) {
-       local_irq_restore(flags);
-       printk (KERN_ALERT "target %d already doing SDTR\n", target);
-       return -1;
-    } 
-    hostdata->initiate_sdtr |= (1 << target);
-    local_irq_restore(flags);
-    return 0;
-}
-#endif
-
-/*
- * Function : request_disconnect (int host, int on_or_off)
- * 
- * Purpose : KGDB support function, tells us to allow or disallow 
- *     disconnections.
- *
- * Inputs : host - number of SCSI host; on_or_off - non-zero to allow,
- *     zero to disallow.
- *
- * Returns : 0 on success, *   -1 on failure.
- */
-
-static int 
-request_disconnect (int host, int on_or_off) {
-    struct Scsi_Host *h;
-    struct NCR53c7x0_hostdata *hostdata;
-    if (!(h = find_host (host)))
-       return -1;
-    hostdata = (struct NCR53c7x0_hostdata *) h->hostdata[0];
-    if (on_or_off) 
-       hostdata->options |= OPTION_DISCONNECT;
-    else
-       hostdata->options &= ~OPTION_DISCONNECT;
-    return 0;
-}
-#endif
-
-/*
- * Function : static void NCR53c7x0_driver_init (struct Scsi_Host *host)
- *
- * Purpose : Initialize internal structures, as required on startup, or 
- *     after a SCSI bus reset.
- * 
- * Inputs : host - pointer to this host adapter's structure
- */
-
-static void 
-NCR53c7x0_driver_init (struct Scsi_Host *host) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    int i, j;
-    u32 *ncrcurrent;
-
-    for (i = 0; i < 16; ++i) {
-       hostdata->request_sense[i] = 0;
-       for (j = 0; j < 8; ++j) 
-           hostdata->busy[i][j] = 0;
-       set_synchronous (host, i, /* sxfer */ 0, hostdata->saved_scntl3, 0);
-    }
-    hostdata->issue_queue = NULL;
-    hostdata->running_list = hostdata->finished_queue = 
-       hostdata->ncrcurrent = NULL;
-    for (i = 0, ncrcurrent = (u32 *) hostdata->schedule; 
-       i < host->can_queue; ++i, ncrcurrent += 2) {
-       ncrcurrent[0] = hostdata->NOP_insn;
-       ncrcurrent[1] = 0xdeadbeef;
-    }
-    ncrcurrent[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) | DBC_TCI_TRUE;
-    ncrcurrent[1] = (u32) virt_to_bus (hostdata->script) +
-       hostdata->E_wait_reselect;
-    hostdata->reconnect_dsa_head = 0;
-    hostdata->addr_reconnect_dsa_head = (u32) 
-       virt_to_bus((void *) &(hostdata->reconnect_dsa_head));
-    hostdata->expecting_iid = 0;
-    hostdata->expecting_sto = 0;
-    if (hostdata->options & OPTION_ALWAYS_SYNCHRONOUS) 
-       hostdata->initiate_sdtr = 0xffff; 
-    else
-       hostdata->initiate_sdtr = 0;
-    hostdata->talked_to = 0;
-    hostdata->idle = 1;
-}
-
-/* 
- * Function : static int clock_to_ccf_710 (int clock)
- *
- * Purpose :  Return the clock conversion factor for a given SCSI clock.
- *
- * Inputs : clock - SCSI clock expressed in Hz.
- *
- * Returns : ccf on success, -1 on failure.
- */
-
-static int 
-clock_to_ccf_710 (int clock) {
-    if (clock <= 16666666)
-       return -1;
-    if (clock <= 25000000)
-       return 2;       /* Divide by 1.0 */
-    else if (clock <= 37500000)
-       return 1;       /* Divide by 1.5 */
-    else if (clock <= 50000000)
-       return 0;       /* Divide by 2.0 */
-    else if (clock <= 66000000)
-       return 3;       /* Divide by 3.0 */
-    else 
-       return -1;
-}
-    
-/* 
- * Function : static int NCR53c7x0_init (struct Scsi_Host *host)
- *
- * Purpose :  initialize the internal structures for a given SCSI host
- *
- * Inputs : host - pointer to this host adapter's structure
- *
- * Preconditions : when this function is called, the chip_type 
- *     field of the hostdata structure MUST have been set.
- *
- * Returns : 0 on success, -1 on failure.
- */
-
-int 
-NCR53c7x0_init (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    int i, ccf;
-    unsigned char revision;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    /* 
-     * There are some things which we need to know about in order to provide
-     * a semblance of support.  Print 'em if they aren't what we expect, 
-     * otherwise don't add to the noise.
-     * 
-     * -1 means we don't know what to expect.
-     */
-    int val, flags;
-    char buf[32];
-    int expected_id = -1;
-    int expected_clock = -1;
-    int uninitialized = 0;
-#ifdef NO_IO_SPACE
-    int expected_mapping = OPTION_MEMORY_MAPPED;
-#else
-    int expected_mapping = OPTION_IO_MAPPED;
-#endif
-    for (i=0;i<7;i++)
-       hostdata->valid_ids[i] = 1;     /* Default all ID's to scan */
-
-    /* Parse commandline flags */
-    if (check_setup_strings("noasync",&flags,&val,buf))
-    {
-       hostdata->options |= OPTION_NO_ASYNC;
-       hostdata->options &= ~(OPTION_SYNCHRONOUS | OPTION_ALWAYS_SYNCHRONOUS);
-    }
-
-    if (check_setup_strings("nosync",&flags,&val,buf))
-    {
-       hostdata->options &= ~(OPTION_SYNCHRONOUS | OPTION_ALWAYS_SYNCHRONOUS);
-    }
-
-    if (check_setup_strings("nodisconnect",&flags,&val,buf))
-       hostdata->options &= ~OPTION_DISCONNECT;
-
-    if (check_setup_strings("validids",&flags,&val,buf))
-    {
-       for (i=0;i<7;i++) 
-               hostdata->valid_ids[i] = val & (1<<i);
-    }
-    if  ((i = check_setup_strings("next",&flags,&val,buf)))
-    {
-       while (i)
-               setup_used[--i] = 1;
-    }
-
-    if (check_setup_strings("opthi",&flags,&val,buf))
-       hostdata->options = (long long)val << 32;
-    if (check_setup_strings("optlo",&flags,&val,buf))
-       hostdata->options |= val;
-
-    NCR53c7x0_local_setup(host);
-    switch (hostdata->chip) {
-    case 710:
-    case 770:
-       hostdata->dstat_sir_intr = NCR53c7x0_dstat_sir_intr;
-       hostdata->init_save_regs = NULL;
-       hostdata->dsa_fixup = NCR53c7xx_dsa_fixup;
-       hostdata->init_fixup = NCR53c7x0_init_fixup;
-       hostdata->soft_reset = NCR53c7x0_soft_reset;
-       hostdata->run_tests = NCR53c7xx_run_tests;
-       expected_clock = hostdata->scsi_clock;
-       expected_id = 7;
-       break;
-    default:
-       printk ("scsi%d : chip type of %d is not supported yet, detaching.\n",
-           host->host_no, hostdata->chip);
-       scsi_unregister (host);
-       return -1;
-    }
-
-    /* Assign constants accessed by NCR */
-    hostdata->NCR53c7xx_zero = 0;                      
-    hostdata->NCR53c7xx_msg_reject = MESSAGE_REJECT;
-    hostdata->NCR53c7xx_msg_abort = ABORT;
-    hostdata->NCR53c7xx_msg_nop = NOP;
-    hostdata->NOP_insn = (DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24;
-    if (expected_mapping == -1 || 
-       (hostdata->options & (OPTION_MEMORY_MAPPED)) != 
-       (expected_mapping & OPTION_MEMORY_MAPPED))
-       printk ("scsi%d : using %s mapped access\n", host->host_no, 
-           (hostdata->options & OPTION_MEMORY_MAPPED) ? "memory" : 
-           "io");
-
-    hostdata->dmode = (hostdata->chip == 700 || hostdata->chip == 70066) ? 
-       DMODE_REG_00 : DMODE_REG_10;
-    hostdata->istat = ((hostdata->chip / 100) == 8) ? 
-       ISTAT_REG_800 : ISTAT_REG_700;
-
-/* We have to assume that this may be the first access to the chip, so
- * we must set EA in DCNTL. */
-
-    NCR53c7x0_write8 (DCNTL_REG, DCNTL_10_EA|DCNTL_10_COM);
-
-
-/* Only the ISTAT register is readable when the NCR is running, so make 
-   sure it's halted. */
-    ncr_halt(host);
-
-/* 
- * XXX - the NCR53c700 uses bitfielded registers for SCID, SDID, etc,
- *     as does the 710 with one bit per SCSI ID.  Conversely, the NCR
- *     uses a normal, 3 bit binary representation of these values.
- *
- * Get the rest of the NCR documentation, and FIND OUT where the change
- * was.
- */
-
-#if 0
-       /* May not be able to do this - chip my not have been set up yet */
-       tmp = hostdata->this_id_mask = NCR53c7x0_read8(SCID_REG);
-       for (host->this_id = 0; tmp != 1; tmp >>=1, ++host->this_id);
-#else
-       host->this_id = 7;
-#endif
-
-/*
- * Note : we should never encounter a board setup for ID0.  So,
- *     if we see ID0, assume that it was uninitialized and set it
- *     to the industry standard 7.
- */
-    if (!host->this_id) {
-       printk("scsi%d : initiator ID was %d, changing to 7\n",
-           host->host_no, host->this_id);
-       host->this_id = 7;
-       hostdata->this_id_mask = 1 << 7;
-       uninitialized = 1;
-    };
-
-    if (expected_id == -1 || host->this_id != expected_id)
-       printk("scsi%d : using initiator ID %d\n", host->host_no,
-           host->this_id);
-
-    /*
-     * Save important registers to allow a soft reset.
-     */
-
-    /*
-     * CTEST7 controls cache snooping, burst mode, and support for 
-     * external differential drivers.  This isn't currently used - the
-     * default value may not be optimal anyway.
-     * Even worse, it may never have been set up since reset.
-     */
-    hostdata->saved_ctest7 = NCR53c7x0_read8(CTEST7_REG) & CTEST7_SAVE;
-    revision = (NCR53c7x0_read8(CTEST8_REG) & 0xF0) >> 4;
-    switch (revision) {
-       case 1: revision = 0;    break;
-       case 2: revision = 1;    break;
-       case 4: revision = 2;    break;
-       case 8: revision = 3;    break;
-       default: revision = 255; break;
-    }
-    printk("scsi%d: Revision 0x%x\n",host->host_no,revision);
-
-    if ((revision == 0 || revision == 255) && (hostdata->options & (OPTION_SYNCHRONOUS|OPTION_DISCONNECT|OPTION_ALWAYS_SYNCHRONOUS)))
-    {
-       printk ("scsi%d: Disabling sync working and disconnect/reselect\n",
-                                                       host->host_no);
-       hostdata->options &= ~(OPTION_SYNCHRONOUS|OPTION_DISCONNECT|OPTION_ALWAYS_SYNCHRONOUS);
-    }
-
-    /*
-     * On NCR53c700 series chips, DCNTL controls the SCSI clock divisor,
-     * on 800 series chips, it allows for a totem-pole IRQ driver.
-     * NOTE saved_dcntl currently overwritten in init function.
-     * The value read here may be garbage anyway, MVME16x board at least
-     * does not initialise chip if kernel arrived via tftp.
-     */
-
-    hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG);
-
-    /*
-     * DMODE controls DMA burst length, and on 700 series chips,
-     * 286 mode and bus width  
-     * NOTE:  On MVME16x, chip may have been reset, so this could be a
-     * power-on/reset default value.
-     */
-    hostdata->saved_dmode = NCR53c7x0_read8(hostdata->dmode);
-
-    /* 
-     * Now that burst length and enabled/disabled status is known, 
-     * clue the user in on it.  
-     */
-   
-    ccf = clock_to_ccf_710 (expected_clock);
-
-    for (i = 0; i < 16; ++i) 
-       hostdata->cmd_allocated[i] = 0;
-
-    if (hostdata->init_save_regs)
-       hostdata->init_save_regs (host);
-    if (hostdata->init_fixup)
-       hostdata->init_fixup (host);
-
-    if (!the_template) {
-       the_template = host->hostt;
-       first_host = host;
-    }
-
-    /* 
-     * Linux SCSI drivers have always been plagued with initialization 
-     * problems - some didn't work with the BIOS disabled since they expected
-     * initialization from it, some didn't work when the networking code
-     * was enabled and registers got scrambled, etc.
-     *
-     * To avoid problems like this, in the future, we will do a soft 
-     * reset on the SCSI chip, taking it back to a sane state.
-     */
-
-    hostdata->soft_reset (host);
-
-#if 1
-    hostdata->debug_count_limit = -1;
-#else
-    hostdata->debug_count_limit = 1;
-#endif
-    hostdata->intrs = -1;
-    hostdata->resets = -1;
-    memcpy ((void *) hostdata->synchronous_want, (void *) sdtr_message, 
-       sizeof (hostdata->synchronous_want));
-
-    NCR53c7x0_driver_init (host);
-
-    if (request_irq(host->irq, NCR53c7x0_intr, IRQF_SHARED, "53c7xx", host))
-    {
-       printk("scsi%d : IRQ%d not free, detaching\n",
-               host->host_no, host->irq);
-       goto err_unregister;
-    } 
-
-    if ((hostdata->run_tests && hostdata->run_tests(host) == -1) ||
-        (hostdata->options & OPTION_DEBUG_TESTS_ONLY)) {
-       /* XXX Should disable interrupts, etc. here */
-       goto err_free_irq;
-    } else {
-       if (host->io_port)  {
-           host->n_io_port = 128;
-           if (!request_region (host->io_port, host->n_io_port, "ncr53c7xx"))
-               goto err_free_irq;
-       }
-    }
-    
-    if (NCR53c7x0_read8 (SBCL_REG) & SBCL_BSY) {
-       printk ("scsi%d : bus wedge, doing SCSI reset\n", host->host_no);
-       hard_reset (host);
-    }
-    return 0;
-
- err_free_irq:
-    free_irq(host->irq,  NCR53c7x0_intr);
- err_unregister:
-    scsi_unregister(host);
-    return -1;
-}
-
-/* 
- * Function : int ncr53c7xx_init(struct scsi_host_template *tpnt, int board, int chip,
- *     unsigned long base, int io_port, int irq, int dma, long long options,
- *     int clock);
- *
- * Purpose : initializes a NCR53c7,8x0 based on base addresses,
- *     IRQ, and DMA channel.   
- *     
- * Inputs : tpnt - Template for this SCSI adapter, board - board level
- *     product, chip - 710
- * 
- * Returns : 0 on success, -1 on failure.
- *
- */
-
-int 
-ncr53c7xx_init (struct scsi_host_template *tpnt, int board, int chip,
-    unsigned long base, int io_port, int irq, int dma, 
-    long long options, int clock)
-{
-    struct Scsi_Host *instance;
-    struct NCR53c7x0_hostdata *hostdata;
-    char chip_str[80];
-    int script_len = 0, dsa_len = 0, size = 0, max_cmd_size = 0,
-       schedule_size = 0, ok = 0;
-    void *tmp;
-    unsigned long page;
-
-    switch (chip) {
-    case 710:
-    case 770:
-       schedule_size = (tpnt->can_queue + 1) * 8 /* JUMP instruction size */;
-       script_len = NCR53c7xx_script_len;
-       dsa_len = NCR53c7xx_dsa_len;
-       options |= OPTION_INTFLY;
-       sprintf (chip_str, "NCR53c%d", chip);
-       break;
-    default:
-       printk("scsi-ncr53c7xx : unsupported SCSI chip %d\n", chip);
-       return -1;
-    }
-
-    printk("scsi-ncr53c7xx : %s at memory 0x%lx, io 0x%x, irq %d",
-       chip_str, base, io_port, irq);
-    if (dma == DMA_NONE)
-       printk("\n");
-    else 
-       printk(", dma %d\n", dma);
-
-    if (options & OPTION_DEBUG_PROBE_ONLY) {
-       printk ("scsi-ncr53c7xx : probe only enabled, aborting initialization\n");
-       return -1;
-    }
-
-    max_cmd_size = sizeof(struct NCR53c7x0_cmd) + dsa_len +
-       /* Size of dynamic part of command structure : */
-       2 * /* Worst case : we don't know if we need DATA IN or DATA out */
-               ( 2 * /* Current instructions per scatter/gather segment */ 
-                 tpnt->sg_tablesize + 
-                  3 /* Current startup / termination required per phase */
-               ) *
-       8 /* Each instruction is eight bytes */;
-
-    /* Allocate fixed part of hostdata, dynamic part to hold appropriate
-       SCSI SCRIPT(tm) plus a single, maximum-sized NCR53c7x0_cmd structure.
-
-       We need a NCR53c7x0_cmd structure for scan_scsis() when we are 
-       not loaded as a module, and when we're loaded as a module, we 
-       can't use a non-dynamically allocated structure because modules
-       are vmalloc()'d, which can allow structures to cross page 
-       boundaries and breaks our physical/virtual address assumptions
-       for DMA.
-
-       So, we stick it past the end of our hostdata structure.
-
-       ASSUMPTION : 
-                Regardless of how many simultaneous SCSI commands we allow,
-        the probe code only executes a _single_ instruction at a time,
-        so we only need one here, and don't need to allocate NCR53c7x0_cmd
-        structures for each target until we are no longer in scan_scsis
-        and kmalloc() has become functional (memory_init() happens 
-        after all device driver initialization).
-    */
-
-    size = sizeof(struct NCR53c7x0_hostdata) + script_len + 
-    /* Note that alignment will be guaranteed, since we put the command
-       allocated at probe time after the fixed-up SCSI script, which 
-       consists of 32 bit words, aligned on a 32 bit boundary.  But
-       on a 64bit machine we need 8 byte alignment for hostdata->free, so
-       we add in another 4 bytes to take care of potential misalignment
-       */
-       (sizeof(void *) - sizeof(u32)) + max_cmd_size + schedule_size;
-
-    page = __get_free_pages(GFP_ATOMIC,1);
-    if(page==0)
-    {
-       printk(KERN_ERR "53c7xx: out of memory.\n");
-       return -ENOMEM;
-    }
-#ifdef FORCE_DSA_ALIGNMENT
-    /*
-     * 53c710 rev.0 doesn't have an add-with-carry instruction.
-     * Ensure we allocate enough memory to force DSA alignment.
-    */
-    size += 256;
-#endif
-    /* Size should be < 8K, so we can fit it in two pages. */
-    if (size > 8192) {
-      printk(KERN_ERR "53c7xx: hostdata > 8K\n");
-      return -1;
-    }
-
-    instance = scsi_register (tpnt, 4);
-    if (!instance)
-    {
-        free_page(page);
-       return -1;
-    }
-    instance->hostdata[0] = page;
-    memset((void *)instance->hostdata[0], 0, 8192);
-    cache_push(virt_to_phys((void *)(instance->hostdata[0])), 8192);
-    cache_clear(virt_to_phys((void *)(instance->hostdata[0])), 8192);
-    kernel_set_cachemode((void *)instance->hostdata[0], 8192, IOMAP_NOCACHE_SER);
-
-    /* FIXME : if we ever support an ISA NCR53c7xx based board, we
-       need to check if the chip is running in a 16 bit mode, and if so 
-       unregister it if it is past the 16M (0x1000000) mark */
-
-    hostdata = (struct NCR53c7x0_hostdata *)instance->hostdata[0];
-    hostdata->size = size;
-    hostdata->script_count = script_len / sizeof(u32);
-    hostdata->board = board;
-    hostdata->chip = chip;
-
-    /*
-     * Being memory mapped is more desirable, since 
-     *
-     * - Memory accesses may be faster.
-     *
-     * - The destination and source address spaces are the same for 
-     *  all instructions, meaning we don't have to twiddle dmode or 
-     *  any other registers.
-     *
-     * So, we try for memory mapped, and if we don't get it,
-     * we go for port mapped, and that failing we tell the user
-     * it can't work.
-     */
-
-    if (base) {
-       instance->base = base;
-       /* Check for forced I/O mapping */
-       if (!(options & OPTION_IO_MAPPED)) {
-           options |= OPTION_MEMORY_MAPPED;
-           ok = 1;
-       }
-    } else {
-       options &= ~OPTION_MEMORY_MAPPED;
-    }
-
-    if (io_port) {
-       instance->io_port = io_port;
-       options |= OPTION_IO_MAPPED;
-       ok = 1;
-    } else {
-       options &= ~OPTION_IO_MAPPED;
-    }
-
-    if (!ok) {
-       printk ("scsi%d : not initializing, no I/O or memory mapping known \n",
-           instance->host_no);
-       scsi_unregister (instance);
-       return -1;
-    }
-    instance->irq = irq;
-    instance->dma_channel = dma;
-
-    hostdata->options = options;
-    hostdata->dsa_len = dsa_len;
-    hostdata->max_cmd_size = max_cmd_size;
-    hostdata->num_cmds = 1;
-    hostdata->scsi_clock = clock;
-    /* Initialize single command */
-    tmp = (hostdata->script + hostdata->script_count);
-#ifdef FORCE_DSA_ALIGNMENT
-    {
-       void *t = ROUNDUP(tmp, void *);
-       if (((u32)t & 0xff) > CmdPageStart)
-           t = (void *)((u32)t + 255);
-       t = (void *)(((u32)t & ~0xff) + CmdPageStart);
-        hostdata->free = t;
-#if 0
-       printk ("scsi: Registered size increased by 256 to %d\n", size);
-       printk ("scsi: CmdPageStart = 0x%02x\n", CmdPageStart);
-       printk ("scsi: tmp = 0x%08x, hostdata->free set to 0x%08x\n",
-                       (u32)tmp, (u32)t);
-#endif
-    }
-#else
-    hostdata->free = ROUNDUP(tmp, void *);
-#endif
-    hostdata->free->real = tmp;
-    hostdata->free->size = max_cmd_size;
-    hostdata->free->free = NULL;
-    hostdata->free->next = NULL;
-    hostdata->extra_allocate = 0;
-
-    /* Allocate command start code space */
-    hostdata->schedule = (chip == 700 || chip == 70066) ?
-       NULL : (u32 *) ((char *)hostdata->free + max_cmd_size);
-
-/* 
- * For diagnostic purposes, we don't really care how fast things blaze.
- * For profiling, we want to access the 800ns resolution system clock,
- * using a 'C' call on the host processor.
- *
- * Therefore, there's no need for the NCR chip to directly manipulate
- * this data, and we should put it wherever is most convenient for 
- * Linux.
- */
-    if (track_events) 
-       hostdata->events = (struct NCR53c7x0_event *) (track_events ? 
-           vmalloc (sizeof (struct NCR53c7x0_event) * track_events) : NULL);
-    else
-       hostdata->events = NULL;
-
-    if (hostdata->events) {
-       memset ((void *) hostdata->events, 0, sizeof(struct NCR53c7x0_event) *
-           track_events);      
-       hostdata->event_size = track_events;
-       hostdata->event_index = 0;
-    } else 
-       hostdata->event_size = 0;
-
-    return NCR53c7x0_init(instance);
-}
-
-
-/* 
- * Function : static void NCR53c7x0_init_fixup (struct Scsi_Host *host)
- *
- * Purpose :  copy and fixup the SCSI SCRIPTS(tm) code for this device.
- *
- * Inputs : host - pointer to this host adapter's structure
- *
- */
-
-static void 
-NCR53c7x0_init_fixup (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    unsigned char tmp;
-    int i, ncr_to_memory, memory_to_ncr;
-    u32 base;
-    NCR53c7x0_local_setup(host);
-
-
-    /* XXX - NOTE : this code MUST be made endian aware */
-    /*  Copy code into buffer that was allocated at detection time.  */
-    memcpy ((void *) hostdata->script, (void *) SCRIPT, 
-       sizeof(SCRIPT));
-    /* Fixup labels */
-    for (i = 0; i < PATCHES; ++i) 
-       hostdata->script[LABELPATCHES[i]] += 
-           virt_to_bus(hostdata->script);
-    /* Fixup addresses of constants that used to be EXTERNAL */
-
-    patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_abort, 
-       virt_to_bus(&(hostdata->NCR53c7xx_msg_abort)));
-    patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_reject, 
-       virt_to_bus(&(hostdata->NCR53c7xx_msg_reject)));
-    patch_abs_32 (hostdata->script, 0, NCR53c7xx_zero, 
-       virt_to_bus(&(hostdata->NCR53c7xx_zero)));
-    patch_abs_32 (hostdata->script, 0, NCR53c7xx_sink, 
-       virt_to_bus(&(hostdata->NCR53c7xx_sink)));
-    patch_abs_32 (hostdata->script, 0, NOP_insn,
-       virt_to_bus(&(hostdata->NOP_insn)));
-    patch_abs_32 (hostdata->script, 0, schedule,
-       virt_to_bus((void *) hostdata->schedule));
-
-    /* Fixup references to external variables: */
-    for (i = 0; i < EXTERNAL_PATCHES_LEN; ++i)
-       hostdata->script[EXTERNAL_PATCHES[i].offset] +=
-         virt_to_bus(EXTERNAL_PATCHES[i].address);
-
-    /* 
-     * Fixup absolutes set at boot-time.
-     * 
-     * All non-code absolute variables suffixed with "dsa_" and "int_"
-     * are constants, and need no fixup provided the assembler has done 
-     * it for us (I don't know what the "real" NCR assembler does in 
-     * this case, my assembler does the right magic).
-     */
-
-    patch_abs_rwri_data (hostdata->script, 0, dsa_save_data_pointer, 
-       Ent_dsa_code_save_data_pointer - Ent_dsa_zero);
-    patch_abs_rwri_data (hostdata->script, 0, dsa_restore_pointers,
-       Ent_dsa_code_restore_pointers - Ent_dsa_zero);
-    patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect,
-       Ent_dsa_code_check_reselect - Ent_dsa_zero);
-
-    /*
-     * Just for the hell of it, preserve the settings of 
-     * Burst Length and Enable Read Line bits from the DMODE 
-     * register.  Make sure SCRIPTS start automagically.
-     */
-
-#if defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000)
-    /* We know better what we want than 16xBug does! */
-    tmp = DMODE_10_BL_8 | DMODE_10_FC2;
-#else
-    tmp = NCR53c7x0_read8(DMODE_REG_10);
-    tmp &= (DMODE_BL_MASK | DMODE_10_FC2 | DMODE_10_FC1 | DMODE_710_PD |
-                                                               DMODE_710_UO);
-#endif
-
-    if (!(hostdata->options & OPTION_MEMORY_MAPPED)) {
-       base = (u32) host->io_port;
-       memory_to_ncr = tmp|DMODE_800_DIOM;
-       ncr_to_memory = tmp|DMODE_800_SIOM;
-    } else {
-       base = virt_to_bus((void *)host->base);
-       memory_to_ncr = ncr_to_memory = tmp;
-    }
-
-    /* SCRATCHB_REG_10 == SCRATCHA_REG_800, as it happens */
-    patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800);
-    patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG);
-    patch_abs_32 (hostdata->script, 0, addr_dsa, base + DSA_REG);
-
-    /*
-     * I needed some variables in the script to be accessible to 
-     * both the NCR chip and the host processor. For these variables,
-     * I made the arbitrary decision to store them directly in the 
-     * hostdata structure rather than in the RELATIVE area of the 
-     * SCRIPTS.
-     */
-    
-
-    patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_memory, tmp);
-    patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_ncr, memory_to_ncr);
-    patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory);
-
-    patch_abs_32 (hostdata->script, 0, msg_buf, 
-       virt_to_bus((void *)&(hostdata->msg_buf)));
-    patch_abs_32 (hostdata->script, 0, reconnect_dsa_head, 
-       virt_to_bus((void *)&(hostdata->reconnect_dsa_head)));
-    patch_abs_32 (hostdata->script, 0, addr_reconnect_dsa_head, 
-       virt_to_bus((void *)&(hostdata->addr_reconnect_dsa_head)));
-    patch_abs_32 (hostdata->script, 0, reselected_identify, 
-       virt_to_bus((void *)&(hostdata->reselected_identify)));
-/* reselected_tag is currently unused */
-#if 0
-    patch_abs_32 (hostdata->script, 0, reselected_tag, 
-       virt_to_bus((void *)&(hostdata->reselected_tag)));
-#endif
-
-    patch_abs_32 (hostdata->script, 0, test_dest, 
-       virt_to_bus((void*)&hostdata->test_dest));
-    patch_abs_32 (hostdata->script, 0, test_src, 
-       virt_to_bus(&hostdata->test_source));
-    patch_abs_32 (hostdata->script, 0, saved_dsa,
-       virt_to_bus((void *)&hostdata->saved2_dsa));
-    patch_abs_32 (hostdata->script, 0, emulfly,
-       virt_to_bus((void *)&hostdata->emulated_intfly));
-
-    patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect, 
-       (unsigned char)(Ent_dsa_code_check_reselect - Ent_dsa_zero));
-
-/* These are for event logging; the ncr_event enum contains the 
-   actual interrupt numbers. */
-#ifdef A_int_EVENT_SELECT
-   patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT, (u32) EVENT_SELECT);
-#endif
-#ifdef A_int_EVENT_DISCONNECT
-   patch_abs_32 (hostdata->script, 0, int_EVENT_DISCONNECT, (u32) EVENT_DISCONNECT);
-#endif
-#ifdef A_int_EVENT_RESELECT
-   patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT, (u32) EVENT_RESELECT);
-#endif
-#ifdef A_int_EVENT_COMPLETE
-   patch_abs_32 (hostdata->script, 0, int_EVENT_COMPLETE, (u32) EVENT_COMPLETE);
-#endif
-#ifdef A_int_EVENT_IDLE
-   patch_abs_32 (hostdata->script, 0, int_EVENT_IDLE, (u32) EVENT_IDLE);
-#endif
-#ifdef A_int_EVENT_SELECT_FAILED
-   patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT_FAILED, 
-       (u32) EVENT_SELECT_FAILED);
-#endif
-#ifdef A_int_EVENT_BEFORE_SELECT
-   patch_abs_32 (hostdata->script, 0, int_EVENT_BEFORE_SELECT,
-       (u32) EVENT_BEFORE_SELECT);
-#endif
-#ifdef A_int_EVENT_RESELECT_FAILED
-   patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT_FAILED, 
-       (u32) EVENT_RESELECT_FAILED);
-#endif
-
-    /*
-     * Make sure the NCR and Linux code agree on the location of 
-     * certain fields.
-     */
-
-    hostdata->E_accept_message = Ent_accept_message;
-    hostdata->E_command_complete = Ent_command_complete;               
-    hostdata->E_cmdout_cmdout = Ent_cmdout_cmdout;
-    hostdata->E_data_transfer = Ent_data_transfer;
-    hostdata->E_debug_break = Ent_debug_break; 
-    hostdata->E_dsa_code_template = Ent_dsa_code_template;
-    hostdata->E_dsa_code_template_end = Ent_dsa_code_template_end;
-    hostdata->E_end_data_transfer = Ent_end_data_transfer;
-    hostdata->E_initiator_abort = Ent_initiator_abort;
-    hostdata->E_msg_in = Ent_msg_in;
-    hostdata->E_other_transfer = Ent_other_transfer;
-    hostdata->E_other_in = Ent_other_in;
-    hostdata->E_other_out = Ent_other_out;
-    hostdata->E_reject_message = Ent_reject_message;
-    hostdata->E_respond_message = Ent_respond_message;
-    hostdata->E_select = Ent_select;
-    hostdata->E_select_msgout = Ent_select_msgout;
-    hostdata->E_target_abort = Ent_target_abort;
-#ifdef Ent_test_0
-    hostdata->E_test_0 = Ent_test_0;
-#endif
-    hostdata->E_test_1 = Ent_test_1;
-    hostdata->E_test_2 = Ent_test_2;
-#ifdef Ent_test_3
-    hostdata->E_test_3 = Ent_test_3;
-#endif
-    hostdata->E_wait_reselect = Ent_wait_reselect;
-    hostdata->E_dsa_code_begin = Ent_dsa_code_begin;
-
-    hostdata->dsa_cmdout = A_dsa_cmdout;
-    hostdata->dsa_cmnd = A_dsa_cmnd;
-    hostdata->dsa_datain = A_dsa_datain;
-    hostdata->dsa_dataout = A_dsa_dataout;
-    hostdata->dsa_end = A_dsa_end;                     
-    hostdata->dsa_msgin = A_dsa_msgin;
-    hostdata->dsa_msgout = A_dsa_msgout;
-    hostdata->dsa_msgout_other = A_dsa_msgout_other;
-    hostdata->dsa_next = A_dsa_next;
-    hostdata->dsa_select = A_dsa_select;
-    hostdata->dsa_start = Ent_dsa_code_template - Ent_dsa_zero;
-    hostdata->dsa_status = A_dsa_status;
-    hostdata->dsa_jump_dest = Ent_dsa_code_fix_jump - Ent_dsa_zero + 
-       8 /* destination operand */;
-
-    /* sanity check */
-    if (A_dsa_fields_start != Ent_dsa_code_template_end - 
-       Ent_dsa_zero) 
-       printk("scsi%d : NCR dsa_fields start is %d not %d\n",
-           host->host_no, A_dsa_fields_start, Ent_dsa_code_template_end - 
-           Ent_dsa_zero);
-
-    printk("scsi%d : NCR code relocated to 0x%lx (virt 0x%p)\n", host->host_no,
-       virt_to_bus(hostdata->script), hostdata->script);
-}
-
-/*
- * Function : static int NCR53c7xx_run_tests (struct Scsi_Host *host)
- *
- * Purpose : run various verification tests on the NCR chip, 
- *     including interrupt generation, and proper bus mastering
- *     operation.
- * 
- * Inputs : host - a properly initialized Scsi_Host structure
- *
- * Preconditions : the NCR chip must be in a halted state.
- *
- * Returns : 0 if all tests were successful, -1 on error.
- * 
- */
-
-static int 
-NCR53c7xx_run_tests (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    unsigned long timeout;
-    u32 start;
-    int failed, i;
-    unsigned long flags;
-    NCR53c7x0_local_setup(host);
-
-    /* The NCR chip _must_ be idle to run the test scripts */
-
-    local_irq_save(flags);
-    if (!hostdata->idle) {
-       printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
-       local_irq_restore(flags);
-       return -1;
-    }
-
-    /* 
-     * Check for functional interrupts, this could work as an
-     * autoprobe routine.
-     */
-
-    if ((hostdata->options & OPTION_DEBUG_TEST1) && 
-           hostdata->state != STATE_DISABLED) {
-       hostdata->idle = 0;
-       hostdata->test_running = 1;
-       hostdata->test_completed = -1;
-       hostdata->test_dest = 0;
-       hostdata->test_source = 0xdeadbeef;
-       start = virt_to_bus (hostdata->script) + hostdata->E_test_1;
-       hostdata->state = STATE_RUNNING;
-       printk ("scsi%d : test 1", host->host_no);
-       NCR53c7x0_write32 (DSP_REG, start);
-       if (hostdata->options & OPTION_DEBUG_TRACE)
-           NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl | DCNTL_SSM |
-                                               DCNTL_STD);
-       printk (" started\n");
-       local_irq_restore(flags);
-
-       /* 
-        * This is currently a .5 second timeout, since (in theory) no slow 
-        * board will take that long.  In practice, we've seen one 
-        * pentium which occassionally fails with this, but works with 
-        * 10 times as much?
-        */
-
-       timeout = jiffies + 5 * HZ / 10;
-       while ((hostdata->test_completed == -1) && time_before(jiffies, timeout))
-               barrier();
-
-       failed = 1;
-       if (hostdata->test_completed == -1)
-           printk ("scsi%d : driver test 1 timed out%s\n",host->host_no ,
-               (hostdata->test_dest == 0xdeadbeef) ? 
-                   " due to lost interrupt.\n"
-                   "         Please verify that the correct IRQ is being used for your board,\n"
-                   : "");
-       else if (hostdata->test_completed != 1) 
-           printk ("scsi%d : test 1 bad interrupt value (%d)\n", 
-               host->host_no, hostdata->test_completed);
-       else 
-           failed = (hostdata->test_dest != 0xdeadbeef);
-
-       if (hostdata->test_dest != 0xdeadbeef) {
-           printk ("scsi%d : driver test 1 read 0x%x instead of 0xdeadbeef indicating a\n"
-                    "         probable cache invalidation problem.  Please configure caching\n"
-                   "         as write-through or disabled\n",
-               host->host_no, hostdata->test_dest);
-       }
-
-       if (failed) {
-           printk ("scsi%d : DSP = 0x%p (script at 0x%p, start at 0x%x)\n",
-               host->host_no, bus_to_virt(NCR53c7x0_read32(DSP_REG)),
-               hostdata->script, start);
-           printk ("scsi%d : DSPS = 0x%x\n", host->host_no,
-               NCR53c7x0_read32(DSPS_REG));
-           local_irq_restore(flags);
-           return -1;
-       }
-       hostdata->test_running = 0;
-    }
-
-    if ((hostdata->options & OPTION_DEBUG_TEST2) && 
-       hostdata->state != STATE_DISABLED) {
-       u32 dsa[48];
-       unsigned char identify = IDENTIFY(0, 0);
-       unsigned char cmd[6];
-       unsigned char data[36];
-       unsigned char status = 0xff;
-       unsigned char msg = 0xff;
-
-       cmd[0] = INQUIRY;
-       cmd[1] = cmd[2] = cmd[3] = cmd[5] = 0;
-       cmd[4] = sizeof(data); 
-
-       dsa[2] = 1;
-       dsa[3] = virt_to_bus(&identify);
-       dsa[4] = 6;
-       dsa[5] = virt_to_bus(&cmd);
-       dsa[6] = sizeof(data);
-       dsa[7] = virt_to_bus(&data);
-       dsa[8] = 1;
-       dsa[9] = virt_to_bus(&status);
-       dsa[10] = 1;
-       dsa[11] = virt_to_bus(&msg);
-
-       for (i = 0; i < 6; ++i) {
-#ifdef VALID_IDS
-           if (!hostdata->valid_ids[i])
-               continue;
-#endif
-           local_irq_disable();
-           if (!hostdata->idle) {
-               printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
-               local_irq_restore(flags);
-               return -1;
-           }
-
-           /* 710: bit mapped scsi ID, async   */
-            dsa[0] = (1 << i) << 16;
-           hostdata->idle = 0;
-           hostdata->test_running = 2;
-           hostdata->test_completed = -1;
-           start = virt_to_bus(hostdata->script) + hostdata->E_test_2;
-           hostdata->state = STATE_RUNNING;
-           NCR53c7x0_write32 (DSA_REG, virt_to_bus(dsa));
-           NCR53c7x0_write32 (DSP_REG, start);
-           if (hostdata->options & OPTION_DEBUG_TRACE)
-               NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl |
-                               DCNTL_SSM | DCNTL_STD);
-           local_irq_restore(flags);
-
-           timeout = jiffies + 5 * HZ; /* arbitrary */
-           while ((hostdata->test_completed == -1) && time_before(jiffies, timeout))
-               barrier();
-
-           NCR53c7x0_write32 (DSA_REG, 0);
-
-           if (hostdata->test_completed == 2) {
-               data[35] = 0;
-               printk ("scsi%d : test 2 INQUIRY to target %d, lun 0 : %s\n",
-                   host->host_no, i, data + 8);
-               printk ("scsi%d : status ", host->host_no);
-               scsi_print_status (status);
-               printk ("\nscsi%d : message ", host->host_no);
-               spi_print_msg(&msg);
-               printk ("\n");
-           } else if (hostdata->test_completed == 3) {
-               printk("scsi%d : test 2 no connection with target %d\n",
-                   host->host_no, i);
-               if (!hostdata->idle) {
-                   printk("scsi%d : not idle\n", host->host_no);
-                   local_irq_restore(flags);
-                   return -1;
-               }
-           } else if (hostdata->test_completed == -1) {
-               printk ("scsi%d : test 2 timed out\n", host->host_no);
-               local_irq_restore(flags);
-               return -1;
-           } 
-           hostdata->test_running = 0;
-       }
-    }
-
-    local_irq_restore(flags);
-    return 0;
-}
-
-/*
- * Function : static void NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : copy the NCR53c8xx dsa structure into cmd's dsa buffer,
- *     performing all necessary relocation.
- *
- * Inputs : cmd, a NCR53c7x0_cmd structure with a dsa area large
- *     enough to hold the NCR53c8xx dsa.
- */
-
-static void 
-NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
-    Scsi_Cmnd *c = cmd->cmd;
-    struct Scsi_Host *host = c->device->host;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    int i;
-
-    memcpy (cmd->dsa, hostdata->script + (hostdata->E_dsa_code_template / 4),
-       hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template);
-
-    /* 
-     * Note : within the NCR 'C' code, dsa points to the _start_
-     * of the DSA structure, and _not_ the offset of dsa_zero within
-     * that structure used to facilitate shorter signed offsets
-     * for the 8 bit ALU.
-     * 
-     * The implications of this are that 
-     * 
-     * - 32 bit A_dsa_* absolute values require an additional 
-     *          dsa_zero added to their value to be correct, since they are 
-     *   relative to dsa_zero which is in essentially a separate
-     *   space from the code symbols.
-     *
-     * - All other symbols require no special treatment.
-     */
-
-    patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-       dsa_temp_lun, c->device->lun);
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-       dsa_temp_addr_next, virt_to_bus(&cmd->dsa_next_addr));
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-       dsa_temp_next, virt_to_bus(cmd->dsa) + Ent_dsa_zero -
-       Ent_dsa_code_template + A_dsa_next);
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32), 
-       dsa_temp_sync, virt_to_bus((void *)hostdata->sync[c->device->id].script));
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32), 
-       dsa_sscf_710, virt_to_bus((void *)&hostdata->sync[c->device->id].sscf_710));
-    patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-           dsa_temp_target, 1 << c->device->id);
-    /* XXX - new pointer stuff */
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-       dsa_temp_addr_saved_pointer, virt_to_bus(&cmd->saved_data_pointer));
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-       dsa_temp_addr_saved_residual, virt_to_bus(&cmd->saved_residual));
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-       dsa_temp_addr_residual, virt_to_bus(&cmd->residual));
-
-    /*  XXX - new start stuff */
-
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-       dsa_temp_addr_dsa_value, virt_to_bus(&cmd->dsa_addr));
-}
-
-/* 
- * Function : run_process_issue_queue (void)
- * 
- * Purpose : insure that the coroutine is running and will process our 
- *     request.  process_issue_queue_running is checked/set here (in an 
- *     inline function) rather than in process_issue_queue itself to reduce 
- *     the chances of stack overflow.
- *
- */
-
-static volatile int process_issue_queue_running = 0;
-
-static __inline__ void 
-run_process_issue_queue(void) {
-    unsigned long flags;
-    local_irq_save(flags);
-    if (!process_issue_queue_running) {
-       process_issue_queue_running = 1;
-        process_issue_queue(flags);
-       /* 
-         * process_issue_queue_running is cleared in process_issue_queue 
-        * once it can't do more work, and process_issue_queue exits with 
-        * interrupts disabled.
-        */
-    }
-    local_irq_restore(flags);
-}
-
-/*
- * Function : static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int
- *     result)
- *
- * Purpose : mark SCSI command as finished, OR'ing the host portion 
- *     of the result word into the result field of the corresponding
- *     Scsi_Cmnd structure, and removing it from the internal queues.
- *
- * Inputs : cmd - command, result - entire result field
- *
- * Preconditions : the         NCR chip should be in a halted state when 
- *     abnormal_finished is run, since it modifies structures which
- *     the NCR expects to have exclusive access to.
- */
-
-static void 
-abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
-    Scsi_Cmnd *c = cmd->cmd;
-    struct Scsi_Host *host = c->device->host;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    unsigned long flags;
-    int left, found;
-    volatile struct NCR53c7x0_cmd * linux_search;
-    volatile struct NCR53c7x0_cmd * volatile *linux_prev;
-    volatile u32 *ncr_prev, *ncrcurrent, ncr_search;
-
-#if 0
-    printk ("scsi%d: abnormal finished\n", host->host_no);
-#endif
-
-    local_irq_save(flags);
-    found = 0;
-    /* 
-     * Traverse the NCR issue array until we find a match or run out 
-     * of instructions.  Instructions in the NCR issue array are 
-     * either JUMP or NOP instructions, which are 2 words in length.
-     */
-
-
-    for (found = 0, left = host->can_queue, ncrcurrent = hostdata->schedule; 
-       left > 0; --left, ncrcurrent += 2)
-    {
-       if (issue_to_cmd (host, hostdata, (u32 *) ncrcurrent) == cmd) 
-       {
-           ncrcurrent[0] = hostdata->NOP_insn;
-           ncrcurrent[1] = 0xdeadbeef;
-           ++found;
-           break;
-       }
-    }
-       
-    /* 
-     * Traverse the NCR reconnect list of DSA structures until we find 
-     * a pointer to this dsa or have found too many command structures.  
-     * We let prev point at the next field of the previous element or 
-     * head of the list, so we don't do anything different for removing 
-     * the head element.  
-     */
-
-    for (left = host->can_queue,
-           ncr_search = hostdata->reconnect_dsa_head, 
-           ncr_prev = &hostdata->reconnect_dsa_head;
-       left >= 0 && ncr_search && 
-           ((char*)bus_to_virt(ncr_search) + hostdata->dsa_start) 
-               != (char *) cmd->dsa;
-       ncr_prev = (u32*) ((char*)bus_to_virt(ncr_search) + 
-           hostdata->dsa_next), ncr_search = *ncr_prev, --left);
-
-    if (left < 0) 
-       printk("scsi%d: loop detected in ncr reconncect list\n",
-           host->host_no);
-    else if (ncr_search) {
-       if (found)
-           printk("scsi%d: scsi %ld in ncr issue array and reconnect lists\n",
-               host->host_no, c->pid);
-       else {
-           volatile u32 * next = (u32 *) 
-               ((char *)bus_to_virt(ncr_search) + hostdata->dsa_next);
-           *ncr_prev = *next;
-/* If we're at the tail end of the issue queue, update that pointer too. */
-           found = 1;
-       }
-    }
-
-    /*
-     * Traverse the host running list until we find this command or discover
-     * we have too many elements, pointing linux_prev at the next field of the 
-     * linux_previous element or head of the list, search at this element.
-     */
-
-    for (left = host->can_queue, linux_search = hostdata->running_list, 
-           linux_prev = &hostdata->running_list;
-       left >= 0 && linux_search && linux_search != cmd;
-       linux_prev = &(linux_search->next), 
-           linux_search = linux_search->next, --left);
-    
-    if (left < 0) 
-       printk ("scsi%d: loop detected in host running list for scsi pid %ld\n",
-           host->host_no, c->pid);
-    else if (linux_search) {
-       *linux_prev = linux_search->next;
-       --hostdata->busy[c->device->id][c->device->lun];
-    }
-
-    /* Return the NCR command structure to the free list */
-    cmd->next = hostdata->free;
-    hostdata->free = cmd;
-    c->host_scribble = NULL;
-
-    /* And return */
-    c->result = result;
-    c->scsi_done(c);
-
-    local_irq_restore(flags);
-    run_process_issue_queue();
-}
-
-/* 
- * Function : static void intr_break (struct Scsi_Host *host,
- *     struct NCR53c7x0_cmd *cmd)
- *
- * Purpose :  Handler for breakpoint interrupts from a SCSI script
- *
- * Inputs : host - pointer to this host adapter's structure,
- *     cmd - pointer to the command (if any) dsa was pointing 
- *     to.
- *
- */
-
-static void 
-intr_break (struct Scsi_Host *host, struct 
-    NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_break *bp;
-#if 0
-    Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
-#endif
-    u32 *dsp;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];              
-    unsigned long flags;
-    NCR53c7x0_local_setup(host);
-
-    /*
-     * Find the break point corresponding to this address, and 
-     * dump the appropriate debugging information to standard 
-     * output.  
-     */
-    local_irq_save(flags);
-    dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
-    for (bp = hostdata->breakpoints; bp && bp->address != dsp; 
-       bp = bp->next);
-    if (!bp) 
-       panic("scsi%d : break point interrupt from %p with no breakpoint!",
-           host->host_no, dsp);
-
-    /*
-     * Configure the NCR chip for manual start mode, so that we can 
-     * point the DSP register at the instruction that follows the 
-     * INT int_debug_break instruction.
-     */
-
-    NCR53c7x0_write8 (hostdata->dmode, 
-       NCR53c7x0_read8(hostdata->dmode)|DMODE_MAN);
-
-    /*
-     * And update the DSP register, using the size of the old 
-     * instruction in bytes.
-     */
-
-    local_irq_restore(flags);
-}
-/*
- * Function : static void print_synchronous (const char *prefix, 
- *     const unsigned char *msg)
- * 
- * Purpose : print a pretty, user and machine parsable representation
- *     of a SDTR message, including the "real" parameters, data
- *     clock so we can tell transfer rate at a glance.
- *
- * Inputs ; prefix - text to prepend, msg - SDTR message (5 bytes)
- */
-
-static void
-print_synchronous (const char *prefix, const unsigned char *msg) {
-    if (msg[4]) {
-       int Hz = 1000000000 / (msg[3] * 4);
-       int integer = Hz / 1000000;
-       int fraction = (Hz - (integer * 1000000)) / 10000;
-       printk ("%speriod %dns offset %d %d.%02dMHz %s SCSI%s\n",
-           prefix, (int) msg[3] * 4, (int) msg[4], integer, fraction,
-           (((msg[3] * 4) < 200) ? "FAST" : "synchronous"),
-           (((msg[3] * 4) < 200) ? "-II" : ""));
-    } else 
-       printk ("%sasynchronous SCSI\n", prefix);
-}
-
-/*
- * Function : static void set_synchronous (struct Scsi_Host *host, 
- *             int target, int sxfer, int scntl3, int now_connected)
- *
- * Purpose : reprogram transfers between the selected SCSI initiator and 
- *     target with the given register values; in the indirect
- *     select operand, reselection script, and chip registers.
- *
- * Inputs : host - NCR53c7,8xx SCSI host, target - number SCSI target id,
- *     sxfer and scntl3 - NCR registers. now_connected - if non-zero, 
- *     we should reprogram the registers now too.
- *
- *      NOTE:  For 53c710, scntl3 is actually used for SCF bits from
- *     SBCL, as we don't have a SCNTL3.
- */
-
-static void
-set_synchronous (struct Scsi_Host *host, int target, int sxfer, int scntl3,
-    int now_connected) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) 
-       host->hostdata[0];
-    u32 *script;
-    NCR53c7x0_local_setup(host);
-
-    /* These are eight bit registers */
-    sxfer &= 0xff;
-    scntl3 &= 0xff;
-
-    hostdata->sync[target].sxfer_sanity = sxfer;
-    hostdata->sync[target].scntl3_sanity = scntl3;
-
-/* 
- * HARD CODED : synchronous script is EIGHT words long.  This 
- * must agree with 53c7.8xx.h
- */
-
-    if ((hostdata->chip != 700) && (hostdata->chip != 70066)) {
-       hostdata->sync[target].select_indirect = (1 << target) << 16 |
-               (sxfer << 8);
-       hostdata->sync[target].sscf_710 = scntl3;
-
-       script = (u32 *) hostdata->sync[target].script;
-
-       /* XXX - add NCR53c7x0 code to reprogram SCF bits if we want to */
-       script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
-               DCMD_RWRI_OP_MOVE) << 24) |
-               (SBCL_REG << 16) | (scntl3 << 8);
-       script[1] = 0;
-       script += 2;
-
-       script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
-           DCMD_RWRI_OP_MOVE) << 24) |
-               (SXFER_REG << 16) | (sxfer << 8);
-       script[1] = 0;
-       script += 2;
-
-#ifdef DEBUG_SYNC_INTR
-       if (hostdata->options & OPTION_DEBUG_DISCONNECT) {
-           script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_INT) << 24) | DBC_TCI_TRUE;
-           script[1] = DEBUG_SYNC_INTR;
-           script += 2;
-       }
-#endif
-
-       script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_RETURN) << 24) | DBC_TCI_TRUE;
-       script[1] = 0;
-       script += 2;
-    }
-
-    if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS) 
-       printk ("scsi%d : target %d sync parameters are sxfer=0x%x, scntl3=0x%x\n",
-       host->host_no, target, sxfer, scntl3);
-
-    if (now_connected) {
-       NCR53c7x0_write8(SBCL_REG, scntl3);
-       NCR53c7x0_write8(SXFER_REG, sxfer);
-    }
-}
-
-
-/*
- * Function : static int asynchronous (struct Scsi_Host *host, int target)
- *
- * Purpose : reprogram between the selected SCSI Host adapter and target 
- *      (assumed to be currently connected) for asynchronous transfers.
- *
- * Inputs : host - SCSI host structure, target - numeric target ID.
- *
- * Preconditions : the NCR chip should be in one of the halted states
- */
-    
-static void
-asynchronous (struct Scsi_Host *host, int target) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    NCR53c7x0_local_setup(host);
-    set_synchronous (host, target, /* no offset */ 0, hostdata->saved_scntl3,
-       1);
-    printk ("scsi%d : setting target %d to asynchronous SCSI\n",
-       host->host_no, target);
-}
-
-/* 
- * XXX - do we want to go out of our way (ie, add extra code to selection
- *     in the NCR53c710/NCR53c720 script) to reprogram the synchronous
- *     conversion bits, or can we be content in just setting the 
- *     sxfer bits?  I chose to do so [richard@sleepie.demon.co.uk]
- */
-
-/* Table for NCR53c8xx synchronous values */
-
-/* This table is also correct for 710, allowing that scf=4 is equivalent
- * of SSCF=0 (ie use DCNTL, divide by 3) for a 50.01-66.00MHz clock.
- * For any other clock values, we cannot use entries with SCF values of
- * 4.  I guess that for a 66MHz clock, the slowest it will set is 2MHz,
- * and for a 50MHz clock, the slowest will be 2.27Mhz.  Should check
- * that a device doesn't try and negotiate sync below these limits!
- */
-static const struct {
-    int div;           /* Total clock divisor * 10 */
-    unsigned char scf; /* */
-    unsigned char tp;  /* 4 + tp = xferp divisor */
-} syncs[] = {
-/*     div     scf     tp      div     scf     tp      div     scf     tp */
-    {  40,     1,      0}, {   50,     1,      1}, {   60,     1,      2}, 
-    {  70,     1,      3}, {   75,     2,      1}, {   80,     1,      4},
-    {  90,     1,      5}, {   100,    1,      6}, {   105,    2,      3},
-    {  110,    1,      7}, {   120,    2,      4}, {   135,    2,      5},
-    {  140,    3,      3}, {   150,    2,      6}, {   160,    3,      4},
-    {  165,    2,      7}, {   180,    3,      5}, {   200,    3,      6},
-    {  210,    4,      3}, {   220,    3,      7}, {   240,    4,      4},
-    {  270,    4,      5}, {   300,    4,      6}, {   330,    4,      7}
-};
-
-/*
- * Function : static void synchronous (struct Scsi_Host *host, int target, 
- *     char *msg)
- *
- * Purpose : reprogram transfers between the selected SCSI initiator and 
- *     target for synchronous SCSI transfers such that the synchronous 
- *     offset is less than that requested and period at least as long 
- *     as that requested.  Also modify *msg such that it contains 
- *     an appropriate response. 
- *
- * Inputs : host - NCR53c7,8xx SCSI host, target - number SCSI target id,
- *     msg - synchronous transfer request.
- */
-
-
-static void
-synchronous (struct Scsi_Host *host, int target, char *msg) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    int desire, divisor, i, limit;
-    unsigned char scntl3, sxfer;
-/* The diagnostic message fits on one line, even with max. width integers */
-    char buf[80];
-
-/* Desired transfer clock in Hz */
-    desire = 1000000000L / (msg[3] * 4);
-/* Scale the available SCSI clock by 10 so we get tenths */
-    divisor = (hostdata->scsi_clock * 10) / desire;
-
-/* NCR chips can handle at most an offset of 8 */
-    if (msg[4] > 8)
-       msg[4] = 8;
-
-    if (hostdata->options & OPTION_DEBUG_SDTR)
-       printk("scsi%d : optimal synchronous divisor of %d.%01d\n",
-           host->host_no, divisor / 10, divisor % 10);
-
-    limit = ARRAY_SIZE(syncs) - 1;
-    for (i = 0; (i < limit) && (divisor > syncs[i].div); ++i);
-
-    if (hostdata->options & OPTION_DEBUG_SDTR)
-       printk("scsi%d : selected synchronous divisor of %d.%01d\n",
-           host->host_no, syncs[i].div / 10, syncs[i].div % 10);
-
-    msg[3] = ((1000000000L / hostdata->scsi_clock) * syncs[i].div / 10 / 4);
-
-    if (hostdata->options & OPTION_DEBUG_SDTR)
-       printk("scsi%d : selected synchronous period of %dns\n", host->host_no,
-           msg[3] * 4);
-
-    scntl3 = syncs[i].scf;
-    sxfer = (msg[4] << SXFER_MO_SHIFT) | (syncs[i].tp << 4);
-    if (hostdata->options & OPTION_DEBUG_SDTR)
-       printk ("scsi%d : sxfer=0x%x scntl3=0x%x\n", 
-           host->host_no, (int) sxfer, (int) scntl3);
-    set_synchronous (host, target, sxfer, scntl3, 1);
-    sprintf (buf, "scsi%d : setting target %d to ", host->host_no, target);
-    print_synchronous (buf, msg);
-}
-
-/* 
- * Function : static int NCR53c7x0_dstat_sir_intr (struct Scsi_Host *host,
- *     struct NCR53c7x0_cmd *cmd)
- *
- * Purpose :  Handler for INT generated instructions for the 
- *     NCR53c810/820 SCSI SCRIPT
- *
- * Inputs : host - pointer to this host adapter's structure,
- *     cmd - pointer to the command (if any) dsa was pointing 
- *     to.
- *
- */
-
-static int 
-NCR53c7x0_dstat_sir_intr (struct Scsi_Host *host, struct 
-    NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    int print;
-    Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];              
-    u32 dsps,*dsp;     /* Argument of the INT instruction */
-
-    NCR53c7x0_local_setup(host);
-    dsps = NCR53c7x0_read32(DSPS_REG);
-    dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
-
-    /* RGH 150597:  Frig.  Commands which fail with Check Condition are
-     * Flagged as successful - hack dsps to indicate check condition */
-#if 0
-    /* RGH 200597:  Need to disable for BVME6000, as it gets Check Conditions
-     * and then dies.  Seems to handle Check Condition at startup, but
-     * not mid kernel build. */
-    if (dsps == A_int_norm_emulateintfly && cmd && cmd->result == 2)
-        dsps = A_int_err_check_condition;
-#endif
-
-    if (hostdata->options & OPTION_DEBUG_INTR) 
-       printk ("scsi%d : DSPS = 0x%x\n", host->host_no, dsps);
-
-    switch (dsps) {
-    case A_int_msg_1:
-       print = 1;
-       switch (hostdata->msg_buf[0]) {
-       /* 
-        * Unless we've initiated synchronous negotiation, I don't
-        * think that this should happen.
-        */
-       case MESSAGE_REJECT:
-           hostdata->dsp = hostdata->script + hostdata->E_accept_message /
-               sizeof(u32);
-           hostdata->dsp_changed = 1;
-           if (cmd && (cmd->flags & CMD_FLAG_SDTR)) {
-               printk ("scsi%d : target %d rejected SDTR\n", host->host_no, 
-                   c->device->id);
-               cmd->flags &= ~CMD_FLAG_SDTR;
-               asynchronous (host, c->device->id);
-               print = 0;
-           } 
-           break;
-       case INITIATE_RECOVERY:
-           printk ("scsi%d : extended contingent allegiance not supported yet, rejecting\n",
-               host->host_no);
-           /* Fall through to default */
-           hostdata->dsp = hostdata->script + hostdata->E_reject_message /
-               sizeof(u32);
-           hostdata->dsp_changed = 1;
-           break;
-       default:
-           printk ("scsi%d : unsupported message, rejecting\n",
-               host->host_no);
-           hostdata->dsp = hostdata->script + hostdata->E_reject_message /
-               sizeof(u32);
-           hostdata->dsp_changed = 1;
-       }
-       if (print) {
-           printk ("scsi%d : received message", host->host_no);
-           if (c) 
-               printk (" from target %d lun %d ", c->device->id, c->device->lun);
-           spi_print_msg((unsigned char *) hostdata->msg_buf);
-           printk("\n");
-       }
-       
-       return SPECIFIC_INT_NOTHING;
-
-
-    case A_int_msg_sdtr:
-/*
- * At this point, hostdata->msg_buf contains
- * 0 EXTENDED MESSAGE
- * 1 length 
- * 2 SDTR
- * 3 period * 4ns
- * 4 offset
- */
-
-       if (cmd) {
-           char buf[80];
-           sprintf (buf, "scsi%d : target %d %s ", host->host_no, c->device->id,
-               (cmd->flags & CMD_FLAG_SDTR) ? "accepting" : "requesting");
-           print_synchronous (buf, (unsigned char *) hostdata->msg_buf);
-
-       /* 
-        * Initiator initiated, won't happen unless synchronous 
-        *      transfers are enabled.  If we get a SDTR message in
-        *      response to our SDTR, we should program our parameters
-        *      such that 
-        *              offset <= requested offset
-        *              period >= requested period                      
-        */
-           if (cmd->flags & CMD_FLAG_SDTR) {
-               cmd->flags &= ~CMD_FLAG_SDTR; 
-               if (hostdata->msg_buf[4]) 
-                   synchronous (host, c->device->id, (unsigned char *) 
-                       hostdata->msg_buf);
-               else 
-                   asynchronous (host, c->device->id);
-               hostdata->dsp = hostdata->script + hostdata->E_accept_message /
-                   sizeof(u32);
-               hostdata->dsp_changed = 1;
-               return SPECIFIC_INT_NOTHING;
-           } else {
-               if (hostdata->options & OPTION_SYNCHRONOUS)  {
-                   cmd->flags |= CMD_FLAG_DID_SDTR;
-                   synchronous (host, c->device->id, (unsigned char *) 
-                       hostdata->msg_buf);
-               } else {
-                   hostdata->msg_buf[4] = 0;           /* 0 offset = async */
-                   asynchronous (host, c->device->id);
-               }
-               patch_dsa_32 (cmd->dsa, dsa_msgout_other, 0, 5);
-               patch_dsa_32 (cmd->dsa, dsa_msgout_other, 1, (u32) 
-                   virt_to_bus ((void *)&hostdata->msg_buf));
-               hostdata->dsp = hostdata->script + 
-                   hostdata->E_respond_message / sizeof(u32);
-               hostdata->dsp_changed = 1;
-           }
-           return SPECIFIC_INT_NOTHING;
-       }
-       /* Fall through to abort if we couldn't find a cmd, and 
-          therefore a dsa structure to twiddle */
-    case A_int_msg_wdtr:
-       hostdata->dsp = hostdata->script + hostdata->E_reject_message /
-           sizeof(u32);
-       hostdata->dsp_changed = 1;
-       return SPECIFIC_INT_NOTHING;
-    case A_int_err_unexpected_phase:
-       if (hostdata->options & OPTION_DEBUG_INTR) 
-           printk ("scsi%d : unexpected phase\n", host->host_no);
-       return SPECIFIC_INT_ABORT;
-    case A_int_err_selected:
-       if ((hostdata->chip / 100) == 8)
-           printk ("scsi%d : selected by target %d\n", host->host_no,
-               (int) NCR53c7x0_read8(SDID_REG_800) &7);
-       else
-            printk ("scsi%d : selected by target LCRC=0x%02x\n", host->host_no,
-                (int) NCR53c7x0_read8(LCRC_REG_10));
-       hostdata->dsp = hostdata->script + hostdata->E_target_abort / 
-           sizeof(u32);
-       hostdata->dsp_changed = 1;
-       return SPECIFIC_INT_NOTHING;
-    case A_int_err_unexpected_reselect:
-       if ((hostdata->chip / 100) == 8)
-           printk ("scsi%d : unexpected reselect by target %d lun %d\n", 
-               host->host_no, (int) NCR53c7x0_read8(SDID_REG_800) & 7,
-               hostdata->reselected_identify & 7);
-       else
-            printk ("scsi%d : unexpected reselect LCRC=0x%02x\n", host->host_no,
-                (int) NCR53c7x0_read8(LCRC_REG_10));
-       hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
-           sizeof(u32);
-       hostdata->dsp_changed = 1;
-       return SPECIFIC_INT_NOTHING;
-/*
- * Since contingent allegiance conditions are cleared by the next 
- * command issued to a target, we must issue a REQUEST SENSE 
- * command after receiving a CHECK CONDITION status, before
- * another command is issued.
- * 
- * Since this NCR53c7x0_cmd will be freed after use, we don't 
- * care if we step on the various fields, so modify a few things.
- */
-    case A_int_err_check_condition: 
-#if 0
-       if (hostdata->options & OPTION_DEBUG_INTR) 
-#endif
-           printk ("scsi%d : CHECK CONDITION\n", host->host_no);
-       if (!c) {
-           printk("scsi%d : CHECK CONDITION with no SCSI command\n",
-               host->host_no);
-           return SPECIFIC_INT_PANIC;
-       }
-
-       /* 
-        * FIXME : this uses the normal one-byte selection message.
-        *      We may want to renegotiate for synchronous & WIDE transfers
-        *      since these could be the crux of our problem.
-        *
-        hostdata->NOP_insn* FIXME : once SCSI-II tagged queuing is implemented, we'll
-        *      have to set this up so that the rest of the DSA
-        *      agrees with this being an untagged queue'd command.
-        */
-
-       patch_dsa_32 (cmd->dsa, dsa_msgout, 0, 1);
-
-       /* 
-        * Modify the table indirect for COMMAND OUT phase, since 
-        * Request Sense is a six byte command.
-        */
-
-       patch_dsa_32 (cmd->dsa, dsa_cmdout, 0, 6);
-
-        /*
-         * The CDB is now mirrored in our local non-cached
-         * structure, but keep the old structure up to date as well,
-         * just in case anyone looks at it.
-         */
-
-       /*
-        * XXX Need to worry about data buffer alignment/cache state
-        * XXX here, but currently never get A_int_err_check_condition,
-        * XXX so ignore problem for now.
-         */
-       cmd->cmnd[0] = c->cmnd[0] = REQUEST_SENSE;
-       cmd->cmnd[0] = c->cmnd[1] &= 0xe0;      /* Zero all but LUN */
-       cmd->cmnd[0] = c->cmnd[2] = 0;
-       cmd->cmnd[0] = c->cmnd[3] = 0;
-       cmd->cmnd[0] = c->cmnd[4] = sizeof(c->sense_buffer);
-       cmd->cmnd[0] = c->cmnd[5] = 0; 
-
-       /*
-        * Disable dataout phase, and program datain to transfer to the 
-        * sense buffer, and add a jump to other_transfer after the 
-        * command so overflow/underrun conditions are detected.
-        */
-
-       patch_dsa_32 (cmd->dsa, dsa_dataout, 0, 
-           virt_to_bus(hostdata->script) + hostdata->E_other_transfer);
-       patch_dsa_32 (cmd->dsa, dsa_datain, 0, 
-           virt_to_bus(cmd->data_transfer_start));
-       cmd->data_transfer_start[0] = (((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | 
-           DCMD_BMI_IO)) << 24) | sizeof(c->sense_buffer);
-       cmd->data_transfer_start[1] = (u32) virt_to_bus(c->sense_buffer);
-
-       cmd->data_transfer_start[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) 
-           << 24) | DBC_TCI_TRUE;
-       cmd->data_transfer_start[3] = (u32) virt_to_bus(hostdata->script) + 
-           hostdata->E_other_transfer;
-
-       /*
-        * Currently, this command is flagged as completed, ie 
-        * it has valid status and message data.  Reflag it as
-        * incomplete.  Q - need to do something so that original
-        * status, etc are used.
-        */
-
-       cmd->result = cmd->cmd->result = 0xffff;                
-
-       /* 
-        * Restart command as a REQUEST SENSE.
-        */
-       hostdata->dsp = (u32 *) hostdata->script + hostdata->E_select /
-           sizeof(u32);
-       hostdata->dsp_changed = 1;
-       return SPECIFIC_INT_NOTHING;
-    case A_int_debug_break:
-       return SPECIFIC_INT_BREAK;
-    case A_int_norm_aborted:
-       hostdata->dsp = (u32 *) hostdata->schedule;
-       hostdata->dsp_changed = 1;
-       if (cmd)
-           abnormal_finished (cmd, DID_ERROR << 16);
-       return SPECIFIC_INT_NOTHING;
-    case A_int_norm_emulateintfly:
-       NCR53c7x0_intfly(host);
-       return SPECIFIC_INT_NOTHING;
-    case A_int_test_1:
-    case A_int_test_2:
-       hostdata->idle = 1;
-       hostdata->test_completed = (dsps - A_int_test_1) / 0x00010000 + 1;
-       if (hostdata->options & OPTION_DEBUG_INTR)
-           printk("scsi%d : test%d complete\n", host->host_no,
-               hostdata->test_completed);
-       return SPECIFIC_INT_NOTHING;
-#ifdef A_int_debug_reselected_ok
-    case A_int_debug_reselected_ok:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-               OPTION_DEBUG_DISCONNECT)) {
-           /* 
-            * Note - this dsa is not based on location relative to 
-            * the command structure, but to location relative to the 
-            * DSA register 
-            */ 
-           u32 *dsa;
-           dsa = (u32 *) bus_to_virt (NCR53c7x0_read32(DSA_REG));
-
-           printk("scsi%d : reselected_ok (DSA = 0x%x (virt 0x%p)\n", 
-               host->host_no, NCR53c7x0_read32(DSA_REG), dsa);
-           printk("scsi%d : resume address is 0x%x (virt 0x%p)\n",
-                   host->host_no, cmd->saved_data_pointer,
-                   bus_to_virt(cmd->saved_data_pointer));
-           print_insn (host, hostdata->script + Ent_reselected_ok / 
-                   sizeof(u32), "", 1);
-           if ((hostdata->chip / 100) == 8)
-               printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n",
-                   host->host_no, NCR53c7x0_read8(SXFER_REG),
-                   NCR53c7x0_read8(SCNTL3_REG_800));
-           else
-               printk ("scsi%d : sxfer=0x%x, cannot read SBCL\n",
-                   host->host_no, NCR53c7x0_read8(SXFER_REG));
-           if (c) {
-               print_insn (host, (u32 *) 
-                   hostdata->sync[c->device->id].script, "", 1);
-               print_insn (host, (u32 *) 
-                   hostdata->sync[c->device->id].script + 2, "", 1);
-           }
-       }
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_reselect_check
-    case A_int_debug_reselect_check:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-           u32 *dsa;
-#if 0
-           u32 *code;
-#endif
-           /* 
-            * Note - this dsa is not based on location relative to 
-            * the command structure, but to location relative to the 
-            * DSA register 
-            */ 
-           dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG));
-           printk("scsi%d : reselected_check_next (DSA = 0x%lx (virt 0x%p))\n",
-               host->host_no, virt_to_bus(dsa), dsa);
-           if (dsa) {
-               printk("scsi%d : resume address is 0x%x (virt 0x%p)\n",
-                   host->host_no, cmd->saved_data_pointer,
-                   bus_to_virt (cmd->saved_data_pointer));
-#if 0
-               printk("scsi%d : template code :\n", host->host_no);
-               for (code = dsa + (Ent_dsa_code_check_reselect - Ent_dsa_zero) 
-                   / sizeof(u32); code < (dsa + Ent_dsa_zero / sizeof(u32)); 
-                   code += print_insn (host, code, "", 1));
-#endif
-           }
-           print_insn (host, hostdata->script + Ent_reselected_ok / 
-                   sizeof(u32), "", 1);
-       }
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_dsa_schedule
-    case A_int_debug_dsa_schedule:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-           u32 *dsa;
-           /* 
-            * Note - this dsa is not based on location relative to 
-            * the command structure, but to location relative to the 
-            * DSA register 
-            */ 
-           dsa = (u32 *) bus_to_virt (NCR53c7x0_read32(DSA_REG));
-           printk("scsi%d : dsa_schedule (old DSA = 0x%lx (virt 0x%p))\n", 
-               host->host_no, virt_to_bus(dsa), dsa);
-           if (dsa) 
-               printk("scsi%d : resume address is 0x%x (virt 0x%p)\n"
-                      "         (temp was 0x%x (virt 0x%p))\n",
-                   host->host_no, cmd->saved_data_pointer,
-                   bus_to_virt (cmd->saved_data_pointer),
-                   NCR53c7x0_read32 (TEMP_REG),
-                   bus_to_virt (NCR53c7x0_read32(TEMP_REG)));
-       }
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_scheduled
-    case A_int_debug_scheduled:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-           printk("scsi%d : new I/O 0x%x (virt 0x%p) scheduled\n", 
-               host->host_no, NCR53c7x0_read32(DSA_REG),
-               bus_to_virt(NCR53c7x0_read32(DSA_REG)));
-       }
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_idle
-    case A_int_debug_idle:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-           printk("scsi%d : idle\n", host->host_no);
-       }
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_cmd
-    case A_int_debug_cmd:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-           printk("scsi%d : command sent\n");
-       }
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_dsa_loaded
-    case A_int_debug_dsa_loaded:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-           printk("scsi%d : DSA loaded with 0x%x (virt 0x%p)\n", host->host_no,
-               NCR53c7x0_read32(DSA_REG), 
-               bus_to_virt(NCR53c7x0_read32(DSA_REG)));
-       }
-       return SPECIFIC_INT_RESTART; 
-#endif
-#ifdef A_int_debug_reselected
-    case A_int_debug_reselected:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-           OPTION_DEBUG_DISCONNECT)) {
-           if ((hostdata->chip / 100) == 8)
-               printk("scsi%d : reselected by target %d lun %d\n",
-                   host->host_no, (int) NCR53c7x0_read8(SDID_REG_800) & ~0x80, 
-                   (int) hostdata->reselected_identify & 7);
-           else
-               printk("scsi%d : reselected by LCRC=0x%02x lun %d\n",
-                    host->host_no, (int) NCR53c7x0_read8(LCRC_REG_10),
-                    (int) hostdata->reselected_identify & 7);
-           print_queues(host);
-       }
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_disconnect_msg
-    case A_int_debug_disconnect_msg:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-           if (c)
-               printk("scsi%d : target %d lun %d disconnecting\n", 
-                   host->host_no, c->device->id, c->device->lun);
-           else
-               printk("scsi%d : unknown target disconnecting\n",
-                   host->host_no);
-       }
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_disconnected
-    case A_int_debug_disconnected:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-               OPTION_DEBUG_DISCONNECT)) {
-           printk ("scsi%d : disconnected, new queues are\n", 
-               host->host_no);
-           print_queues(host);
-#if 0
-           /* Not valid on ncr53c710! */
-           printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n",
-               host->host_no, NCR53c7x0_read8(SXFER_REG),
-               NCR53c7x0_read8(SCNTL3_REG_800));
-#endif
-           if (c) {
-               print_insn (host, (u32 *) 
-                   hostdata->sync[c->device->id].script, "", 1);
-               print_insn (host, (u32 *) 
-                   hostdata->sync[c->device->id].script + 2, "", 1);
-           }
-       }
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_panic
-    case A_int_debug_panic:
-       printk("scsi%d : int_debug_panic received\n", host->host_no);
-       print_lots (host);
-       return SPECIFIC_INT_PANIC;
-#endif
-#ifdef A_int_debug_saved
-    case A_int_debug_saved:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-           OPTION_DEBUG_DISCONNECT)) {
-           printk ("scsi%d : saved data pointer 0x%x (virt 0x%p)\n",
-               host->host_no, cmd->saved_data_pointer,
-               bus_to_virt (cmd->saved_data_pointer));
-           print_progress (c);
-       }
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_restored
-    case A_int_debug_restored:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-           OPTION_DEBUG_DISCONNECT)) {
-           if (cmd) {
-               int size;
-               printk ("scsi%d : restored data pointer 0x%x (virt 0x%p)\n",
-                   host->host_no, cmd->saved_data_pointer, bus_to_virt (
-                   cmd->saved_data_pointer));
-               size = print_insn (host, (u32 *) 
-                   bus_to_virt(cmd->saved_data_pointer), "", 1);
-               size = print_insn (host, (u32 *) 
-                   bus_to_virt(cmd->saved_data_pointer) + size, "", 1);
-               print_progress (c);
-           }
-#if 0
-           printk ("scsi%d : datapath residual %d\n",
-               host->host_no, datapath_residual (host)) ;
-#endif
-       }
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_sync
-    case A_int_debug_sync:
-       if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-           OPTION_DEBUG_DISCONNECT|OPTION_DEBUG_SDTR)) {
-           unsigned char sxfer = NCR53c7x0_read8 (SXFER_REG), scntl3;
-           if ((hostdata->chip / 100) == 8) {
-               scntl3 = NCR53c7x0_read8 (SCNTL3_REG_800);
-               if (c) {
-                 if (sxfer != hostdata->sync[c->device->id].sxfer_sanity ||
-                   scntl3 != hostdata->sync[c->device->id].scntl3_sanity) {
-                       printk ("scsi%d :  sync sanity check failed sxfer=0x%x, scntl3=0x%x",
-                           host->host_no, sxfer, scntl3);
-                       NCR53c7x0_write8 (SXFER_REG, sxfer);
-                       NCR53c7x0_write8 (SCNTL3_REG_800, scntl3);
-                   }
-               } else 
-                 printk ("scsi%d : unknown command sxfer=0x%x, scntl3=0x%x\n",
-                   host->host_no, (int) sxfer, (int) scntl3);
-           } else {
-               if (c) {
-                 if (sxfer != hostdata->sync[c->device->id].sxfer_sanity) {
-                       printk ("scsi%d :  sync sanity check failed sxfer=0x%x",
-                           host->host_no, sxfer);
-                       NCR53c7x0_write8 (SXFER_REG, sxfer);
-                       NCR53c7x0_write8 (SBCL_REG,
-                               hostdata->sync[c->device->id].sscf_710);
-                   }
-               } else 
-                 printk ("scsi%d : unknown command sxfer=0x%x\n",
-                   host->host_no, (int) sxfer);
-           }
-       }
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_datain
-       case A_int_debug_datain:
-           if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-               OPTION_DEBUG_DISCONNECT|OPTION_DEBUG_SDTR)) {
-               int size;
-               if ((hostdata->chip / 100) == 8)
-                 printk ("scsi%d : In do_datain (%s) sxfer=0x%x, scntl3=0x%x\n"
-                       "         datapath residual=%d\n",
-                   host->host_no, sbcl_to_phase (NCR53c7x0_read8 (SBCL_REG)),
-                   (int) NCR53c7x0_read8(SXFER_REG), 
-                   (int) NCR53c7x0_read8(SCNTL3_REG_800),
-                   datapath_residual (host)) ;
-               else
-                 printk ("scsi%d : In do_datain (%s) sxfer=0x%x\n"
-                       "         datapath residual=%d\n",
-                   host->host_no, sbcl_to_phase (NCR53c7x0_read8 (SBCL_REG)),
-                   (int) NCR53c7x0_read8(SXFER_REG), 
-                   datapath_residual (host)) ;
-               print_insn (host, dsp, "", 1);
-               size = print_insn (host, (u32 *) bus_to_virt(dsp[1]), "", 1);
-               print_insn (host, (u32 *) bus_to_virt(dsp[1]) + size, "", 1);
-          } 
-       return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_check_dsa
-       case A_int_debug_check_dsa:
-           if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) {
-               int sdid;
-               int tmp;
-               char *where;
-               if (hostdata->chip / 100 == 8)
-                   sdid = NCR53c7x0_read8 (SDID_REG_800) & 15;
-               else {
-                   tmp = NCR53c7x0_read8 (SDID_REG_700);
-                   if (!tmp)
-                       panic ("SDID_REG_700 = 0");
-                   tmp >>= 1;
-                   sdid = 0;
-                   while (tmp) {
-                       tmp >>= 1;
-                       sdid++;
-                   }
-               }
-               where = dsp - NCR53c7x0_insn_size(NCR53c7x0_read8 
-                       (DCMD_REG)) == hostdata->script + 
-                       Ent_select_check_dsa / sizeof(u32) ?
-                   "selection" : "reselection";
-               if (c && sdid != c->device->id) {
-                   printk ("scsi%d : SDID target %d != DSA target %d at %s\n",
-                       host->host_no, sdid, c->device->id, where);
-                   print_lots(host);
-                   dump_events (host, 20);
-                   return SPECIFIC_INT_PANIC;
-               }
-           }
-           return SPECIFIC_INT_RESTART;
-#endif
-    default:
-       if ((dsps & 0xff000000) == 0x03000000) {
-            printk ("scsi%d : misc debug interrupt 0x%x\n",
-               host->host_no, dsps);
-           return SPECIFIC_INT_RESTART;
-       } else if ((dsps & 0xff000000) == 0x05000000) {
-           if (hostdata->events) {
-               struct NCR53c7x0_event *event;
-               ++hostdata->event_index;
-               if (hostdata->event_index >= hostdata->event_size)
-                   hostdata->event_index = 0;
-               event = (struct NCR53c7x0_event *) hostdata->events + 
-                   hostdata->event_index;
-               event->event = (enum ncr_event) dsps;
-               event->dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
-               if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) {
-                   if (hostdata->chip / 100 == 8)
-                       event->target = NCR53c7x0_read8(SSID_REG_800);
-                   else {
-                       unsigned char tmp, sdid;
-                       tmp = NCR53c7x0_read8 (SDID_REG_700);
-                       if (!tmp)
-                           panic ("SDID_REG_700 = 0");
-                       tmp >>= 1;
-                       sdid = 0;
-                       while (tmp) {
-                           tmp >>= 1;
-                           sdid++;
-                       }
-                       event->target = sdid;
-                   }
-               }
-               else 
-                       event->target = 255;
-
-               if (event->event == EVENT_RESELECT)
-                   event->lun = hostdata->reselected_identify & 0xf;
-               else if (c)
-                   event->lun = c->device->lun;
-               else
-                   event->lun = 255;
-               do_gettimeofday(&(event->time));
-               if (c) {
-                   event->pid = c->pid;
-                   memcpy ((void *) event->cmnd, (void *) c->cmnd, 
-                       sizeof (event->cmnd));
-               } else {
-                   event->pid = -1;
-               }
-           }
-           return SPECIFIC_INT_RESTART;
-       }
-
-       printk ("scsi%d : unknown user interrupt 0x%x\n", 
-           host->host_no, (unsigned) dsps);
-       return SPECIFIC_INT_PANIC;
-    }
-}
-
-/* 
- * XXX - the stock NCR assembler won't output the scriptu.h file,
- * which undefine's all #define'd CPP symbols from the script.h
- * file, which will create problems if you use multiple scripts
- * with the same  symbol names.
- *
- * If you insist on using NCR's assembler, you could generate
- * scriptu.h from script.h using something like 
- *
- * grep #define script.h | \
- * sed 's/#define[     ][      ]*\([_a-zA-Z][_a-zA-Z0-9]*\).*$/#undefine \1/' \
- * > scriptu.h
- */
-
-#include "53c7xx_u.h"
-
-/* XXX - add alternate script handling code here */
-
-
-/* 
- * Function : static void NCR537xx_soft_reset (struct Scsi_Host *host)
- *
- * Purpose :  perform a soft reset of the NCR53c7xx chip
- *
- * Inputs : host - pointer to this host adapter's structure
- *
- * Preconditions : NCR53c7x0_init must have been called for this 
- *      host.
- * 
- */
-
-static void 
-NCR53c7x0_soft_reset (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    unsigned long flags;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    NCR53c7x0_local_setup(host);
-
-    local_irq_save(flags);
-
-    /* Disable scsi chip and s/w level 7 ints */
-
-#ifdef CONFIG_MVME16x
-    if (MACH_IS_MVME16x)
-    {
-        volatile unsigned long v;
-
-        v = *(volatile unsigned long *)0xfff4006c;
-        v &= ~0x8000;
-        *(volatile unsigned long *)0xfff4006c = v;
-        v = *(volatile unsigned long *)0xfff4202c;
-        v &= ~0x10;
-        *(volatile unsigned long *)0xfff4202c = v;
-    }
-#endif
-    /* Anything specific for your hardware? */
-
-    /*
-     * Do a soft reset of the chip so that everything is 
-     * reinitialized to the power-on state.
-     *
-     * Basically follow the procedure outlined in the NCR53c700
-     * data manual under Chapter Six, How to Use, Steps Necessary to
-     * Start SCRIPTS, with the exception of actually starting the 
-     * script and setting up the synchronous transfer gunk.
-     */
-
-    /* Should we reset the scsi bus here??????????????????? */
-
-    NCR53c7x0_write8(ISTAT_REG_700, ISTAT_10_SRST);
-    NCR53c7x0_write8(ISTAT_REG_700, 0);
-
-    /*
-     * saved_dcntl is set up in NCR53c7x0_init() before it is overwritten
-     * here.  We should have some better way of working out the CF bit
-     * setting..
-     */
-
-    hostdata->saved_dcntl = DCNTL_10_EA|DCNTL_10_COM;
-    if (hostdata->scsi_clock > 50000000)
-       hostdata->saved_dcntl |= DCNTL_700_CF_3;
-    else
-    if (hostdata->scsi_clock > 37500000)
-        hostdata->saved_dcntl |= DCNTL_700_CF_2;
-#if 0
-    else
-       /* Any clocks less than 37.5MHz? */
-#endif
-
-    if (hostdata->options & OPTION_DEBUG_TRACE)
-       NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl | DCNTL_SSM);
-    else
-       NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl);
-    /* Following disables snooping - snooping is not required, as non-
-     * cached pages are used for shared data, and appropriate use is
-     * made of cache_push/cache_clear.  Indeed, for 68060
-     * enabling snooping causes disk corruption of ext2fs free block
-     * bitmaps and the like.  If you have a 68060 with snooping hardwared
-     * on, then you need to enable CONFIG_060_WRITETHROUGH.
-     */
-    NCR53c7x0_write8(CTEST7_REG, CTEST7_10_TT1|CTEST7_STD);
-    /* Actually burst of eight, according to my 53c710 databook */
-    NCR53c7x0_write8(hostdata->dmode, DMODE_10_BL_8 | DMODE_10_FC2);
-    NCR53c7x0_write8(SCID_REG, 1 << host->this_id);
-    NCR53c7x0_write8(SBCL_REG, 0);
-    NCR53c7x0_write8(SCNTL1_REG, SCNTL1_ESR_700);
-    NCR53c7x0_write8(SCNTL0_REG, ((hostdata->options & OPTION_PARITY) ? 
-            SCNTL0_EPC : 0) | SCNTL0_EPG_700 | SCNTL0_ARB1 | SCNTL0_ARB2);
-
-    /*
-     * Enable all interrupts, except parity which we only want when
-     * the user requests it.
-     */
-
-    NCR53c7x0_write8(DIEN_REG, DIEN_700_BF |
-               DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_700_OPC);
-
-    NCR53c7x0_write8(SIEN_REG_700, ((hostdata->options & OPTION_PARITY) ?
-           SIEN_PAR : 0) | SIEN_700_STO | SIEN_RST | SIEN_UDC |
-               SIEN_SGE | SIEN_MA);
-
-#ifdef CONFIG_MVME16x
-    if (MACH_IS_MVME16x)
-    {
-        volatile unsigned long v;
-
-        /* Enable scsi chip and s/w level 7 ints */
-        v = *(volatile unsigned long *)0xfff40080;
-        v = (v & ~(0xf << 28)) | (4 << 28);
-        *(volatile unsigned long *)0xfff40080 = v;
-        v = *(volatile unsigned long *)0xfff4006c;
-        v |= 0x8000;
-        *(volatile unsigned long *)0xfff4006c = v;
-        v = *(volatile unsigned long *)0xfff4202c;
-        v = (v & ~0xff) | 0x10 | 4;
-        *(volatile unsigned long *)0xfff4202c = v;
-    }
-#endif
-    /* Anything needed for your hardware? */
-    local_irq_restore(flags);
-}
-
-
-/*
- * Function static struct NCR53c7x0_cmd *allocate_cmd (Scsi_Cmnd *cmd)
- * 
- * Purpose : Return the first free NCR53c7x0_cmd structure (which are 
- *     reused in a LIFO manner to minimize cache thrashing).
- *
- * Side effects : If we haven't yet scheduled allocation of NCR53c7x0_cmd
- *     structures for this device, do so.  Attempt to complete all scheduled
- *     allocations using get_zeroed_page(), putting NCR53c7x0_cmd structures on
- *     the free list.  Teach programmers not to drink and hack.
- *
- * Inputs : cmd - SCSI command
- *
- * Returns : NCR53c7x0_cmd structure allocated on behalf of cmd;
- *     NULL on failure.
- */
-
-static void
-my_free_page (void *addr, int dummy)
-{
-    /* XXX This assumes default cache mode to be IOMAP_FULL_CACHING, which
-     * XXX may be invalid (CONFIG_060_WRITETHROUGH)
-     */
-    kernel_set_cachemode((void *)addr, 4096, IOMAP_FULL_CACHING);
-    free_page ((u32)addr);
-}
-
-static struct NCR53c7x0_cmd *
-allocate_cmd (Scsi_Cmnd *cmd) {
-    struct Scsi_Host *host = cmd->device->host;
-    struct NCR53c7x0_hostdata *hostdata = 
-