[SCSI] Merge up to linux-2.6 head
authorJames Bottomley <jejb@mulgrave.il.steeleye.com>
Thu, 31 May 2007 04:57:05 +0000 (23:57 -0500)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Thu, 31 May 2007 04:57:05 +0000 (23:57 -0500)
Conflicts:

drivers/scsi/jazz_esp.c

Same changes made by both SCSI and SPARC trees: problem with UTF-8
conversion in the copyright.

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
84 files changed:
Documentation/scsi/scsi_fc_transport.txt [new file with mode: 0644]
drivers/block/cciss_scsi.c
drivers/ieee1394/sbp2.c
drivers/message/fusion/mptscsih.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-xxxx.c
drivers/scsi/53c700.c
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/aacraid/aachba.c
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/linit.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_hba.c
drivers/scsi/bvme6000.c [deleted file]
drivers/scsi/bvme6000.h [deleted file]
drivers/scsi/eata.c
drivers/scsi/fdomain.c
drivers/scsi/gdth.c
drivers/scsi/ibmmca.c
drivers/scsi/ibmmca.h [deleted file]
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/ibmvscsi/ibmvscsi.h
drivers/scsi/initio.c
drivers/scsi/initio.h
drivers/scsi/ipr.c
drivers/scsi/ips.c
drivers/scsi/ips.h
drivers/scsi/jazz_esp.c
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/mac53c94.c
drivers/scsi/megaraid.c
drivers/scsi/mvme16x.c [deleted file]
drivers/scsi/mvme16x.h [deleted file]
drivers/scsi/nsp32.c
drivers/scsi/pcmcia/sym53c500_cs.c
drivers/scsi/qla2xxx/qla_isr.c
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_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/sd.c
drivers/scsi/sg.c
drivers/scsi/stex.c
drivers/scsi/sym53c416.c
drivers/scsi/tmscsim.c
drivers/scsi/u14-34f.c
drivers/scsi/ultrastor.c
drivers/scsi/wd7000.c
include/scsi/scsi_cmnd.h
include/scsi/scsi_host.h
include/scsi/scsi_transport_fc.h

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 90961a8..4aca7dd 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 875eadd..ce86ff2 100644 (file)
@@ -1489,69 +1489,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,
@@ -1595,13 +1532,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));
 
@@ -1690,15 +1623,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 3bd94f1..bc740a6 100644 (file)
@@ -260,30 +260,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;
@@ -662,7 +645,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 +750,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 +799,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 +882,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 +948,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;
 
@@ -1039,17 +1008,8 @@ 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;
                        sc->scsi_done(sc);
@@ -1380,10 +1340,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;
index eb766c3..113aaed 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,19 @@ 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,
+       struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+       int use_sg = scsi_sg_count(cmd);
+
+       if (scsi_bufflen(cmd) < TW_MIN_SGL_LENGTH &&
+           (cmd->sc_data_direction == DMA_FROM_DEVICE ||
+            cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
+               if (!use_sg)
+                       memcpy(scsi_sglist(cmd),
                               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;
+                              scsi_bufflen(cmd));
+
+               if (use_sg == 1) {
+                       struct scatterlist *sg = scsi_sglist(tw_dev->srb[request_id]);
                        char *buf;
                        unsigned long flags = 0;
                        local_irq_save(flags);
@@ -2017,16 +1970,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 656bdb1..c7995fc 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 cb02656..405d9d6 100644 (file)
@@ -585,16 +585,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
@@ -1263,14 +1255,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 +1835,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 +1878,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",
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 = 
-       (struct NCR53c7x0_hostdata *) host->hostdata[0];
-    u32 real;                  /* Real address */
-    int size;                  /* Size of *tmp */
-    struct NCR53c7x0_cmd *tmp;
-    unsigned long flags;
-
-    if (hostdata->options & OPTION_DEBUG_ALLOCATION)
-       printk ("scsi%d : num_cmds = %d, can_queue = %d\n"
-               "         target = %d, lun = %d, %s\n",
-           host->host_no, hostdata->num_cmds, host->can_queue,
-           cmd->device->id, cmd->device->lun, (hostdata->cmd_allocated[cmd->device->id] &
-               (1 << cmd->device->lun)) ? "already allocated" : "not allocated");
-
-/*
- * If we have not yet reserved commands for this I_T_L nexus, and
- * the device exists (as indicated by permanent Scsi_Cmnd structures
- * being allocated under 1.3.x, or being outside of scan_scsis in
- * 1.2.x), do so now.
- */
-    if (!(hostdata->cmd_allocated[cmd->device->id] & (1 << cmd->device->lun)) &&
-                               cmd->device && cmd->device->has_cmdblocks) {
-      if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue)
-          hostdata->extra_allocate += host->cmd_per_lun;
-      hostdata->cmd_allocated[cmd->device->id] |= (1 << cmd->device->lun);
-    }
-
-    for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate, 
-       ++hostdata->num_cmds) {
-    /* historically, kmalloc has returned unaligned addresses; pad so we
-       have enough room to ROUNDUP */
-       size = hostdata->max_cmd_size + sizeof (void *);
-#ifdef FORCE_DSA_ALIGNMENT
-       /*
-        * 53c710 rev.0 doesn't have an add-with-carry instruction.
-        * Ensure we allocate enough memory to force alignment.
-        */
-       size += 256;
-#endif
-/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
-
-        if (size > 4096) {
-            printk (KERN_ERR "53c7xx: allocate_cmd size > 4K\n");
-           return NULL;
-       }
-        real = get_zeroed_page(GFP_ATOMIC);
-        if (real == 0)
-               return NULL;
-        cache_push(virt_to_phys((void *)real), 4096);
-        cache_clear(virt_to_phys((void *)real), 4096);
-        kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER);
-       tmp = ROUNDUP(real, void *);
-#ifdef FORCE_DSA_ALIGNMENT
-       {
-           if (((u32)tmp & 0xff) > CmdPageStart)
-               tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255);
-           tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart);
-#if 0
-           printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n",
-                       size, real, (u32)tmp);
-#endif
-       }
-#endif
-       tmp->real = (void *)real;
-       tmp->size = size;                       
-       tmp->free = ((void (*)(void *, int)) my_free_page);
-       local_irq_save(flags);
-       tmp->next = hostdata->free;
-       hostdata->free = tmp;
-       local_irq_restore(flags);
-    }
-    local_irq_save(flags);
-    tmp = (struct NCR53c7x0_cmd *) hostdata->free;
-    if (tmp) {
-       hostdata->free = tmp->next;
-    }
-    local_irq_restore(flags);
-    if (!tmp)
-       printk ("scsi%d : can't allocate command for target %d lun %d\n",
-           host->host_no, cmd->device->id, cmd->device->lun);
-    return tmp;
-}
-
-/*
- * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) 
- *
- *
- * Purpose : allocate a NCR53c7x0_cmd structure, initialize it based on the 
- *     Scsi_Cmnd structure passed in cmd, including dsa and Linux field 
- *     initialization, and dsa code relocation.
- *
- * Inputs : cmd - SCSI command
- *
- * Returns : NCR53c7x0_cmd structure corresponding to cmd,
- *     NULL on failure.
- */
-static struct NCR53c7x0_cmd *
-create_cmd (Scsi_Cmnd *cmd) {
-    NCR53c7x0_local_declare();
-    struct Scsi_Host *host = cmd->device->host;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-        host->hostdata[0];     
-    struct NCR53c7x0_cmd *tmp;         /* NCR53c7x0_cmd structure for this command */
-    int datain,                /* Number of instructions per phase */
-       dataout;
-    int data_transfer_instructions, /* Count of dynamic instructions */
-       i;                      /* Counter */
-    u32 *cmd_datain,           /* Address of datain/dataout code */
-       *cmd_dataout;           /* Incremented as we assemble */
-#ifdef notyet
-    unsigned char *msgptr;     /* Current byte in select message */
-    int msglen;                        /* Length of whole select message */
-#endif
-    unsigned long flags;
-    u32 exp_select_indirect;   /* Used in sanity check */
-    NCR53c7x0_local_setup(cmd->device->host);
-
-    if (!(tmp = allocate_cmd (cmd)))
-       return NULL;
-
-    /*
-     * Copy CDB and initialised result fields from Scsi_Cmnd to NCR53c7x0_cmd.
-     * We do this because NCR53c7x0_cmd may have a special cache mode
-     * selected to cope with lack of bus snooping, etc.
-     */
-
-    memcpy(tmp->cmnd, cmd->cmnd, 12);
-    tmp->result = cmd->result;
-
-    /*
-     * Decide whether we need to generate commands for DATA IN,
-     * DATA OUT, neither, or both based on the SCSI command 
-     */
-
-    switch (cmd->cmnd[0]) {
-    /* These commands do DATA IN */
-    case INQUIRY:
-    case MODE_SENSE:
-    case READ_6:
-    case READ_10:
-    case READ_CAPACITY:
-    case REQUEST_SENSE:
-    case READ_BLOCK_LIMITS:
-    case READ_TOC:
-       datain = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
-       dataout = 0;
-       break;
-    /* These commands do DATA OUT */
-    case MODE_SELECT: 
-    case WRITE_6:
-    case WRITE_10:
-#if 0
-       printk("scsi%d : command is ", host->host_no);
-       __scsi_print_command(cmd->cmnd);
-#endif
-#if 0
-       printk ("scsi%d : %d scatter/gather segments\n", host->host_no,
-           cmd->use_sg);
-#endif
-       datain = 0;
-       dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
-#if 0
-       hostdata->options |= OPTION_DEBUG_INTR;
-#endif
-       break;
-    /* 
-     * These commands do no data transfer, we should force an
-     * interrupt if a data phase is attempted on them.
-     */
-    case TEST_UNIT_READY:
-    case ALLOW_MEDIUM_REMOVAL:
-    case START_STOP:
-       datain = dataout = 0;
-       break;
-    /*
-     * We don't know about these commands, so generate code to handle
-     * both DATA IN and DATA OUT phases.  More efficient to identify them
-     * and add them to the above cases.
-     */
-    default:
-       printk("scsi%d : datain+dataout for command ", host->host_no);
-       __scsi_print_command(cmd->cmnd);
-       datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
-    }
-
-    /*
-     * New code : so that active pointers work correctly regardless
-     *         of where the saved data pointer is at, we want to immediately
-     *         enter the dynamic code after selection, and on a non-data
-     *         phase perform a CALL to the non-data phase handler, with
-     *         returns back to this address.
-     *
-     *         If a phase mismatch is encountered in the middle of a 
-     *         Block MOVE instruction, we want to _leave_ that instruction
-     * unchanged as the current case is, modify a temporary buffer,
-     * and point the active pointer (TEMP) at that.
-     *
-     *         Furthermore, we want to implement a saved data pointer, 
-     *         set by the SAVE_DATA_POINTERs message.
-     *
-     *         So, the data transfer segments will change to 
-     *         CALL data_transfer, WHEN NOT data phase
-     *         MOVE x, x, WHEN data phase
-     *         ( repeat )
-     *         JUMP other_transfer
-     */
-
-    data_transfer_instructions = datain + dataout;
-
-    /*
-     * When we perform a request sense, we overwrite various things,
-     * including the data transfer code.  Make sure we have enough
-     * space to do that.
-     */
-
-    if (data_transfer_instructions < 2)
-       data_transfer_instructions = 2;
-
-
-    /*
-     * The saved data pointer is set up so that a RESTORE POINTERS message 
-     * will start the data transfer over at the beginning.
-     */
-
-    tmp->saved_data_pointer = virt_to_bus (hostdata->script) + 
-       hostdata->E_data_transfer;
-
-    /*
-     * Initialize Linux specific fields.
-     */
-
-    tmp->cmd = cmd;
-    tmp->next = NULL;
-    tmp->flags = 0;
-    tmp->dsa_next_addr = virt_to_bus(tmp->dsa) + hostdata->dsa_next - 
-       hostdata->dsa_start;
-    tmp->dsa_addr = virt_to_bus(tmp->dsa) - hostdata->dsa_start;
-
-    /* 
-     * Calculate addresses of dynamic code to fill in DSA
-     */
-
-    tmp->data_transfer_start = tmp->dsa + (hostdata->dsa_end - 
-       hostdata->dsa_start) / sizeof(u32);
-    tmp->data_transfer_end = tmp->data_transfer_start + 
-       2 * data_transfer_instructions;
-
-    cmd_datain = datain ? tmp->data_transfer_start : NULL;
-    cmd_dataout = dataout ? (datain ? cmd_datain + 2 * datain : tmp->
-       data_transfer_start) : NULL;
-
-    /*
-     * Fill in the NCR53c7x0_cmd structure as follows
-     * dsa, with fixed up DSA code
-     * datain code
-     * dataout code
-     */
-
-    /* Copy template code into dsa and perform all necessary fixups */
-    if (hostdata->dsa_fixup)
-       hostdata->dsa_fixup(tmp);
-
-    patch_dsa_32(tmp->dsa, dsa_next, 0, 0);
-    /*
-     * XXX is this giving 53c710 access to the Scsi_Cmnd in some way?
-     * Do we need to change it for caching reasons?
-     */
-    patch_dsa_32(tmp->dsa, dsa_cmnd, 0, virt_to_bus(cmd));
-
-    if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS) {
-
-       exp_select_indirect = ((1 << cmd->device->id) << 16) |
-                       (hostdata->sync[cmd->device->id].sxfer_sanity << 8);
-
-       if (hostdata->sync[cmd->device->id].select_indirect !=
-                               exp_select_indirect) {
-           printk ("scsi%d :  sanity check failed select_indirect=0x%x\n",
-               host->host_no, hostdata->sync[cmd->device->id].select_indirect);
-           FATAL(host);
-
-       }
-    }
-
-    patch_dsa_32(tmp->dsa, dsa_select, 0,
-               hostdata->sync[cmd->device->id].select_indirect);
-
-    /*
-     * Right now, we'll do the WIDE and SYNCHRONOUS negotiations on
-     * different commands; although it should be trivial to do them
-     * both at the same time.
-     */
-    if (hostdata->initiate_wdtr & (1 << cmd->device->id)) {
-       memcpy ((void *) (tmp->select + 1), (void *) wdtr_message,
-           sizeof(wdtr_message));
-       patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(wdtr_message));
-       local_irq_save(flags);
-       hostdata->initiate_wdtr &= ~(1 << cmd->device->id);
-       local_irq_restore(flags);
-    } else if (hostdata->initiate_sdtr & (1 << cmd->device->id)) {
-       memcpy ((void *) (tmp->select + 1), (void *) sdtr_message, 
-           sizeof(sdtr_message));
-       patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(sdtr_message));
-       tmp->flags |= CMD_FLAG_SDTR;
-       local_irq_save(flags);
-       hostdata->initiate_sdtr &= ~(1 << cmd->device->id);
-       local_irq_restore(flags);
-    
-    }
-#if 1
-    else if (!(hostdata->talked_to & (1 << cmd->device->id)) &&
-               !(hostdata->options & OPTION_NO_ASYNC)) {
-
-       memcpy ((void *) (tmp->select + 1), (void *) async_message, 
-           sizeof(async_message));
-       patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(async_message));
-       tmp->flags |= CMD_FLAG_SDTR;
-    } 
-#endif
-    else 
-       patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
-
-    hostdata->talked_to |= (1 << cmd->device->id);
-    tmp->select[0] = (hostdata->options & OPTION_DISCONNECT) ? 
-       IDENTIFY (1, cmd->device->lun) : IDENTIFY (0, cmd->device->lun);
-    patch_dsa_32(tmp->dsa, dsa_msgout, 1, virt_to_bus(tmp->select));
-    patch_dsa_32(tmp->dsa, dsa_cmdout, 0, cmd->cmd_len);
-    patch_dsa_32(tmp->dsa, dsa_cmdout, 1, virt_to_bus(tmp->cmnd));
-    patch_dsa_32(tmp->dsa, dsa_dataout, 0, cmd_dataout ? 
-           virt_to_bus (cmd_dataout)
-       : virt_to_bus (hostdata->script) + hostdata->E_other_transfer);
-    patch_dsa_32(tmp->dsa, dsa_datain, 0, cmd_datain ? 
-           virt_to_bus (cmd_datain) 
-       : virt_to_bus (hostdata->script) + hostdata->E_other_transfer);
-    /* 
-     * XXX - need to make endian aware, should use separate variables
-     * for both status and message bytes.
-     */
-    patch_dsa_32(tmp->dsa, dsa_msgin, 0, 1);
-/* 
- * FIXME : these only works for little endian.  We probably want to 
- *     provide message and status fields in the NCR53c7x0_cmd 
- *     structure, and assign them to cmd->result when we're done.
- */
-#ifdef BIG_ENDIAN
-    patch_dsa_32(tmp->dsa, dsa_msgin, 1, virt_to_bus(&tmp->result) + 2);
-    patch_dsa_32(tmp->dsa, dsa_status, 0, 1);
-    patch_dsa_32(tmp->dsa, dsa_status, 1, virt_to_bus(&tmp->result) + 3);
-#else
-    patch_dsa_32(tmp->dsa, dsa_msgin, 1, virt_to_bus(&tmp->result) + 1);
-    patch_dsa_32(tmp->dsa, dsa_status, 0, 1);
-    patch_dsa_32(tmp->dsa, dsa_status, 1, virt_to_bus(&tmp->result));
-#endif
-    patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, 1);
-    patch_dsa_32(tmp->dsa, dsa_msgout_other, 1, 
-       virt_to_bus(&(hostdata->NCR53c7xx_msg_nop)));
-    
-    /*
-     * Generate code for zero or more of the DATA IN, DATA OUT phases 
-     * in the format 
-     *
-     * CALL data_transfer, WHEN NOT phase
-     * MOVE first buffer length, first buffer address, WHEN phase
-     * ...
-     * MOVE last buffer length, last buffer address, WHEN phase
-     * JUMP other_transfer
-     */
-
-/* 
- * See if we're getting to data transfer by generating an unconditional 
- * interrupt.
- */
-#if 0
-    if (datain) {
-       cmd_datain[0] = 0x98080000;
-       cmd_datain[1] = 0x03ffd00d;
-       cmd_datain += 2;
-    }
-#endif
-
-/* 
- * XXX - I'm undecided whether all of this nonsense is faster
- * in the long run, or whether I should just go and implement a loop
- * on the NCR chip using table indirect mode?
- *
- * In any case, this is how it _must_ be done for 53c700/700-66 chips,
- * so this stays even when we come up with something better.
- *
- * When we're limited to 1 simultaneous command, no overlapping processing,
- * we're seeing 630K/sec, with 7% CPU usage on a slow Syquest 45M
- * drive.
- *
- * Not bad, not good. We'll see.
- */
-
-    tmp->bounce.len = 0;       /* Assume aligned buffer */
-
-    for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4, 
-       cmd_dataout += 4, ++i) {
-       u32 vbuf = cmd->use_sg
-           ? (u32)page_address(((struct scatterlist *)cmd->request_buffer)[i].page)+
-             ((struct scatterlist *)cmd->request_buffer)[i].offset
-           : (u32)(cmd->request_buffer);
-       u32 bbuf = virt_to_bus((void *)vbuf);
-       u32 count = cmd->use_sg ?
-           ((struct scatterlist *)cmd->request_buffer)[i].length :
-           cmd->request_bufflen;
-
-       /*
-        * If we have buffers which are not aligned with 16 byte cache
-        * lines, then we just hope nothing accesses the other parts of
-        * those cache lines while the transfer is in progress.  That would
-        * fill the cache, and subsequent reads of the dma data would pick
-        * up the wrong thing.
-        * XXX We need a bounce buffer to handle that correctly.
-        */
-
-       if (((bbuf & 15) || (count & 15)) && (datain || dataout))
-       {
-           /* Bounce buffer needed */
-           if (cmd->use_sg)
-               printk ("53c7xx: Non-aligned buffer with use_sg\n");
-           else if (datain && dataout)
-                printk ("53c7xx: Non-aligned buffer with datain && dataout\n");
-            else if (count > 256)
-               printk ("53c7xx: Non-aligned transfer > 256 bytes\n");
-           else
-           {
-                   if (datain)
-                   {
-                       tmp->bounce.len = count;
-                       tmp->bounce.addr = vbuf;
-                       bbuf = virt_to_bus(tmp->bounce.buf);
-                       tmp->bounce.buf[0] = 0xff;
-                       tmp->bounce.buf[1] = 0xfe;
-                       tmp->bounce.buf[2] = 0xfd;
-                       tmp->bounce.buf[3] = 0xfc;
-                   }
-                   if (dataout)
-                   {
-                       memcpy ((void *)tmp->bounce.buf, (void *)vbuf, count);
-                       bbuf = virt_to_bus(tmp->bounce.buf);
-                   }
-           }
-       }
-
-       if (datain) {
-            cache_clear(virt_to_phys((void *)vbuf), count);
-           /* CALL other_in, WHEN NOT DATA_IN */  
-           cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | 
-               DCMD_TCI_IO) << 24) | 
-               DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
-           cmd_datain[1] = virt_to_bus (hostdata->script) + 
-               hostdata->E_other_in;
-           /* MOVE count, buf, WHEN DATA_IN */
-           cmd_datain[2] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | DCMD_BMI_IO) 
-               << 24) | count;
-           cmd_datain[3] = bbuf;
-#if 0
-           print_insn (host, cmd_datain, "dynamic ", 1);
-           print_insn (host, cmd_datain + 2, "dynamic ", 1);
-#endif
-       }
-       if (dataout) {
-            cache_push(virt_to_phys((void *)vbuf), count);
-           /* CALL other_out, WHEN NOT DATA_OUT */
-           cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL) << 24) | 
-               DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
-           cmd_dataout[1] = virt_to_bus(hostdata->script) + 
-               hostdata->E_other_out;
-           /* MOVE count, buf, WHEN DATA+OUT */
-           cmd_dataout[2] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I) << 24) 
-               | count;
-           cmd_dataout[3] = bbuf;
-#if 0
-           print_insn (host, cmd_dataout, "dynamic ", 1);
-           print_insn (host, cmd_dataout + 2, "dynamic ", 1);
-#endif
-       }
-    }
-
-    /*
-     * Install JUMP instructions after the data transfer routines to return
-     * control to the do_other_transfer routines.
-     */
-  
-    
-    if (datain) {
-       cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
-           DBC_TCI_TRUE;
-       cmd_datain[1] = virt_to_bus(hostdata->script) + 
-           hostdata->E_other_transfer;
-#if 0
-       print_insn (host, cmd_datain, "dynamic jump ", 1);
-#endif
-       cmd_datain += 2; 
-    }
-#if 0
-    if (datain) {
-       cmd_datain[0] = 0x98080000;
-       cmd_datain[1] = 0x03ffdeed;
-       cmd_datain += 2;
-    }
-#endif
-    if (dataout) {
-       cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
-           DBC_TCI_TRUE;
-       cmd_dataout[1] = virt_to_bus(hostdata->script) + 
-           hostdata->E_other_transfer;
-#if 0
-       print_insn (host, cmd_dataout, "dynamic jump ", 1);
-#endif
-       cmd_dataout += 2;
-    }
-
-    return tmp;
-}
-
-/*
- * Function : int NCR53c7xx_queue_command (Scsi_Cmnd *cmd,
- *      void (*done)(Scsi_Cmnd *))
- *
- * Purpose :  enqueues a SCSI command
- *
- * Inputs : cmd - SCSI command, done - function called on completion, with
- *      a pointer to the command descriptor.
- *
- * Returns : 0
- *
- * Side effects :
- *      cmd is added to the per instance driver issue_queue, with major
- *      twiddling done to the host specific fields of cmd.  If the
- *      process_issue_queue coroutine isn't running, it is restarted.
- * 
- * NOTE : we use the host_scribble field of the Scsi_Cmnd structure to 
- *     hold our own data, and pervert the ptr field of the SCp field
- *     to create a linked list.
- */
-
-int
-NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
-    struct Scsi_Host *host = cmd->device->host;
-    struct NCR53c7x0_hostdata *hostdata = 
-       (struct NCR53c7x0_hostdata *) host->hostdata[0];
-    unsigned long flags;
-    Scsi_Cmnd *tmp;
-
-    cmd->scsi_done = done;
-    cmd->host_scribble = NULL;
-    cmd->SCp.ptr = NULL;
-    cmd->SCp.buffer = NULL;
-
-#ifdef VALID_IDS
-    /* Ignore commands on invalid IDs */
-    if (!hostdata->valid_ids[cmd->device->id]) {
-        printk("scsi%d : ignoring target %d lun %d\n", host->host_no,
-            cmd->device->id, cmd->device->lun);
-        cmd->result = (DID_BAD_TARGET << 16);
-        done(cmd);
-        return 0;
-    }
-#endif
-
-    local_irq_save(flags);
-    if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY)) 
-       || ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
-           !(hostdata->debug_lun_limit[cmd->device->id] & (1 << cmd->device->lun)))
-#ifdef LINUX_1_2
-       || cmd->device->id > 7
-#else
-       || cmd->device->id >= host->max_id
-#endif
-       || cmd->device->id == host->this_id
-       || hostdata->state == STATE_DISABLED) {
-       printk("scsi%d : disabled or bad target %d lun %d\n", host->host_no,
-           cmd->device->id, cmd->device->lun);
-       cmd->result = (DID_BAD_TARGET << 16);
-       done(cmd);
-       local_irq_restore(flags);
-       return 0;
-    }
-
-    if ((hostdata->options & OPTION_DEBUG_NCOMMANDS_LIMIT) &&
-       (hostdata->debug_count_limit == 0)) {
-       printk("scsi%d : maximum commands exceeded\n", host->host_no);
-       cmd->result = (DID_BAD_TARGET << 16);
-       done(cmd);
-       local_irq_restore(flags);
-       return 0;
-    }
-
-    if (hostdata->options & OPTION_DEBUG_READ_ONLY) {
-       switch (cmd->cmnd[0]) {
-       case WRITE_6:
-       case WRITE_10:
-           printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
-               host->host_no);
-           cmd->result = (DID_BAD_TARGET << 16);
-           done(cmd);
-           local_irq_restore(flags);
-           return 0;
-       }
-    }
-
-    if ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
-           hostdata->debug_count_limit != -1) 
-       --hostdata->debug_count_limit;
-
-    cmd->result = 0xffff;      /* The NCR will overwrite message
-                                      and status with valid data */
-    cmd->host_scribble = (unsigned char *) tmp = create_cmd (cmd);
-
-    /*
-     * REQUEST SENSE commands are inserted at the head of the queue 
-     * so that we do not clear the contingent allegiance condition
-     * they may be looking at.
-     */
-
-    if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-       cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
-       hostdata->issue_queue = cmd;
-    } else {
-       for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->SCp.ptr; 
-               tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
-       tmp->SCp.ptr = (unsigned char *) cmd;
-    }
-    local_irq_restore(flags);
-    run_process_issue_queue();
-    return 0;
-}
-
-/*
- * Function : void to_schedule_list (struct Scsi_Host *host,
- *     struct NCR53c7x0_hostdata * hostdata, Scsi_Cmnd *cmd)
- *
- * Purpose : takes a SCSI command which was just removed from the 
- *     issue queue, and deals with it by inserting it in the first
- *     free slot in the schedule list or by terminating it immediately.
- *
- * Inputs : 
- *     host - SCSI host adapter; hostdata - hostdata structure for 
- *     this adapter; cmd - a pointer to the command; should have 
- *     the host_scribble field initialized to point to a valid 
- *     
- * Side effects : 
- *      cmd is added to the per instance schedule list, with minor 
- *      twiddling done to the host specific fields of cmd.
- *
- */
-
-static __inline__ void
-to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
-    struct NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    Scsi_Cmnd *tmp = cmd->cmd;
-    unsigned long flags;
-    /* dsa start is negative, so subtraction is used */
-    volatile u32 *ncrcurrent;
-
-    int i;
-    NCR53c7x0_local_setup(host);
-#if 0
-    printk("scsi%d : new dsa is 0x%lx (virt 0x%p)\n", host->host_no, 
-       virt_to_bus(hostdata->dsa), hostdata->dsa);
-#endif
-
-    local_irq_save(flags);
-    
-    /* 
-     * Work around race condition : if an interrupt fired and we 
-     * got disabled forget about this command.
-     */
-
-    if (hostdata->state == STATE_DISABLED) {
-       printk("scsi%d : driver disabled\n", host->host_no);
-       tmp->result = (DID_BAD_TARGET << 16);
-       cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
-       hostdata->free = cmd;
-       tmp->scsi_done(tmp);
-       local_irq_restore(flags);
-       return;
-    }
-
-    for (i = host->can_queue, ncrcurrent = hostdata->schedule; 
-       i > 0  && ncrcurrent[0] != hostdata->NOP_insn;
-       --i, ncrcurrent += 2 /* JUMP instructions are two words */);
-
-    if (i > 0) {
-       ++hostdata->busy[tmp->device->id][tmp->device->lun];
-       cmd->next = hostdata->running_list;
-       hostdata->running_list = cmd;
-
-       /* Restore this instruction to a NOP once the command starts */
-       cmd->dsa [(hostdata->dsa_jump_dest - hostdata->dsa_start) / 
-           sizeof(u32)] = (u32) virt_to_bus ((void *)ncrcurrent);
-       /* Replace the current jump operand.  */
-       ncrcurrent[1] =
-           virt_to_bus ((void *) cmd->dsa) + hostdata->E_dsa_code_begin -
-           hostdata->E_dsa_code_template;
-       /* Replace the NOP instruction with a JUMP */
-       ncrcurrent[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) |
-           DBC_TCI_TRUE;
-    }  else {
-       printk ("scsi%d: no free slot\n", host->host_no);
-       disable(host);
-       tmp->result = (DID_ERROR << 16);
-       cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
-       hostdata->free = cmd;
-       tmp->scsi_done(tmp);
-       local_irq_restore(flags);
-       return;
-    }
-
-    /* 
-     * If the NCR chip is in an idle state, start it running the scheduler
-     * immediately.  Otherwise, signal the chip to jump to schedule as 
-     * soon as it is idle.
-     */
-
-    if (hostdata->idle) {
-       hostdata->idle = 0;
-       hostdata->state = STATE_RUNNING;
-       NCR53c7x0_write32 (DSP_REG,  virt_to_bus ((void *)hostdata->schedule));
-       if (hostdata->options & OPTION_DEBUG_TRACE)
-           NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl |
-                               DCNTL_SSM | DCNTL_STD);
-    } else {
-       NCR53c7x0_write8(hostdata->istat, ISTAT_10_SIGP);
-    }
-
-    local_irq_restore(flags);
-}
-
-/*
- * Function : busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata 
- *     *hostdata, Scsi_Cmnd *cmd)
- *
- * Purpose : decide if we can pass the given SCSI command on to the 
- *     device in question or not.
- *  
- * Returns : non-zero when we're busy, 0 when we aren't.
- */
-
-static __inline__ int
-busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata, 
-    Scsi_Cmnd *cmd) {
-    /* FIXME : in the future, this needs to accommodate SCSI-II tagged
-       queuing, and we may be able to play with fairness here a bit.
-     */
-    return hostdata->busy[cmd->device->id][cmd->device->lun];
-}
-
-/*
- * Function : process_issue_queue (void)
- *
- * Purpose : transfer commands from the issue queue to NCR start queue 
- *     of each NCR53c7/8xx in the system, avoiding kernel stack 
- *     overflows when the scsi_done() function is invoked recursively.
- * 
- * NOTE : process_issue_queue exits with interrupts *disabled*, so the 
- *     caller must reenable them if it desires.
- * 
- * NOTE : process_issue_queue should be called from both 
- *     NCR53c7x0_queue_command() and from the interrupt handler 
- *     after command completion in case NCR53c7x0_queue_command()
- *     isn't invoked again but we've freed up resources that are
- *     needed.
- */
-
-static void 
-process_issue_queue (unsigned long flags) {
-    Scsi_Cmnd *tmp, *prev;
-    struct Scsi_Host *host;
-    struct NCR53c7x0_hostdata *hostdata;
-    int done;
-
-    /*
-     * We run (with interrupts disabled) until we're sure that none of 
-     * the host adapters have anything that can be done, at which point 
-     * we set process_issue_queue_running to 0 and exit.
-     *
-     * Interrupts are enabled before doing various other internal 
-     * instructions, after we've decided that we need to run through
-     * the loop again.
-     *
-     */
-
-    do {
-       local_irq_disable(); /* Freeze request queues */
-       done = 1;
-       for (host = first_host; host && host->hostt == the_template;
-           host = host->next) {
-           hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
-           local_irq_disable();
-           if (hostdata->issue_queue) {
-               if (hostdata->state == STATE_DISABLED) {
-                   tmp = (Scsi_Cmnd *) hostdata->issue_queue;
-                   hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
-                   tmp->result = (DID_BAD_TARGET << 16);
-                   if (tmp->host_scribble) {
-                       ((struct NCR53c7x0_cmd *)tmp->host_scribble)->next = 
-                           hostdata->free;
-                       hostdata->free = 
-                           (struct NCR53c7x0_cmd *)tmp->host_scribble;
-                       tmp->host_scribble = NULL;
-                   }
-                   tmp->scsi_done (tmp);
-                   done = 0;
-               } else 
-                   for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, 
-                       prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) 
-                       tmp->SCp.ptr) 
-                       if (!tmp->host_scribble || 
-                           !busyp (host, hostdata, tmp)) {
-                               if (prev)
-                                   prev->SCp.ptr = tmp->SCp.ptr;
-                               else
-                                   hostdata->issue_queue = (Scsi_Cmnd *) 
-                                       tmp->SCp.ptr;
-                           tmp->SCp.ptr = NULL;
-                           if (tmp->host_scribble) {
-                               if (hostdata->options & OPTION_DEBUG_QUEUES) 
-                                   printk ("scsi%d : moving command for target %d lun %d to start list\n",
-                                       host->host_no, tmp->device->id, tmp->device->lun);
-               
-
-                               to_schedule_list (host, hostdata, 
-                                   (struct NCR53c7x0_cmd *)
-                                   tmp->host_scribble);
-                           } else {
-                               if (((tmp->result & 0xff) == 0xff) ||
-                                   ((tmp->result & 0xff00) == 0xff00)) {
-                                   printk ("scsi%d : danger Will Robinson!\n",
-                                       host->host_no);
-                                   tmp->result = DID_ERROR << 16;
-                                   disable (host);
-                               }
-                               tmp->scsi_done(tmp);
-                           }
-                           done = 0;
-                       } /* if target/lun is not busy */
-           } /* if hostdata->issue_queue */
-           if (!done)
-               local_irq_restore(flags);
-       } /* for host */
-    } while (!done);
-    process_issue_queue_running = 0;
-}
-
-/*
- * Function : static void intr_scsi (struct Scsi_Host *host, 
- *     struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : handle all SCSI interrupts, indicated by the setting 
- *     of the SIP bit in the ISTAT register.
- *
- * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
- *     may be NULL.
- */
-
-static void 
-intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = 
-       (struct NCR53c7x0_hostdata *) host->hostdata[0];
-    unsigned char sstat0_sist0, sist1,                 /* Registers */
-           fatal;                              /* Did a fatal interrupt 
-                                                  occur ? */
-   
-    NCR53c7x0_local_setup(host);
-
-    fatal = 0;
-
-    sstat0_sist0 = NCR53c7x0_read8(SSTAT0_REG);
-    sist1 = 0;
-
-    if (hostdata->options & OPTION_DEBUG_INTR) 
-       printk ("scsi%d : SIST0 0x%0x, SIST1 0x%0x\n", host->host_no,
-           sstat0_sist0, sist1);
-
-    /* 250ms selection timeout */
-    if (sstat0_sist0 & SSTAT0_700_STO) {
-       fatal = 1;
-       if (hostdata->options & OPTION_DEBUG_INTR) {
-           printk ("scsi%d : Selection Timeout\n", host->host_no);
-           if (cmd) {
-               printk("scsi%d : target %d, lun %d, command ",
-                   host->host_no, cmd->cmd->device->id, cmd->cmd->device->lun);
-               __scsi_print_command (cmd->cmd->cmnd);
-               printk("scsi%d : dsp = 0x%x (virt 0x%p)\n", host->host_no,
-                   NCR53c7x0_read32(DSP_REG),
-                   bus_to_virt(NCR53c7x0_read32(DSP_REG)));
-           } else {
-               printk("scsi%d : no command\n", host->host_no);
-           }
-       }
-/*
- * XXX - question : how do we want to handle the Illegal Instruction
- *     interrupt, which may occur before or after the Selection Timeout
- *     interrupt?
- */
-
-       if (1) {
-           hostdata->idle = 1;
-           hostdata->expecting_sto = 0;
-
-           if (hostdata->test_running) {
-               hostdata->test_running = 0;
-               hostdata->test_completed = 3;
-           } else if (cmd) {
-               abnormal_finished(cmd, DID_BAD_TARGET << 16);
-           }
-#if 0      
-           hostdata->intrs = 0;
-#endif
-       }
-    } 
-
-/*
- * FIXME : in theory, we can also get a UDC when a STO occurs.
- */
-    if (sstat0_sist0 & SSTAT0_UDC) {
-       fatal = 1;
-       if (cmd) {
-           printk("scsi%d : target %d lun %d unexpected disconnect\n",
-               host->host_no, cmd->cmd->device->id, cmd->cmd->device->lun);
-           print_lots (host);
-           abnormal_finished(cmd, DID_ERROR << 16);
-       } else 
-            printk("scsi%d : unexpected disconnect (no command)\n",
-               host->host_no);
-
-       hostdata->dsp = (u32 *) hostdata->schedule;
-       hostdata->dsp_changed = 1;
-    }
-
-    /* SCSI PARITY error */
-    if (sstat0_sist0 & SSTAT0_PAR) {
-       fatal = 1;
-       if (cmd && cmd->cmd) {
-           printk("scsi%d : target %d lun %d parity error.\n",
-               host->host_no, cmd->cmd->device->id, cmd->cmd->device->lun);
-           abnormal_finished (cmd, DID_PARITY << 16); 
-       } else
-           printk("scsi%d : parity error\n", host->host_no);
-       /* Should send message out, parity error */
-
-       /* XXX - Reduce synchronous transfer rate! */
-       hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
-           sizeof(u32);
-       hostdata->dsp_changed = 1; 
-    /* SCSI GROSS error */
-    } 
-
-    if (sstat0_sist0 & SSTAT0_SGE) {
-       fatal = 1;
-       printk("scsi%d : gross error, saved2_dsa = 0x%x\n", host->host_no,
-                                       (unsigned int)hostdata->saved2_dsa);
-       print_lots (host);
-       
-       /* 
-         * A SCSI gross error may occur when we have 
-        *
-        * - A synchronous offset which causes the SCSI FIFO to be overwritten.
-        *
-        * - A REQ which causes the maximum synchronous offset programmed in 
-        *      the SXFER register to be exceeded.
-        *
-        * - A phase change with an outstanding synchronous offset.
-        *
-        * - Residual data in the synchronous data FIFO, with a transfer
-        *      other than a synchronous receive is started.$#
-        */
-               
-
-       /* XXX Should deduce synchronous transfer rate! */
-       hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
-           sizeof(u32);
-       hostdata->dsp_changed = 1;
-    /* Phase mismatch */
-    } 
-
-    if (sstat0_sist0 & SSTAT0_MA) {
-       fatal = 1;
-       if (hostdata->options & OPTION_DEBUG_INTR)
-           printk ("scsi%d : SSTAT0_MA\n", host->host_no);
-       intr_phase_mismatch (host, cmd);
-    }
-
-#if 0
-    if (sstat0_sist0 & SIST0_800_RSL) 
-       printk ("scsi%d : Oh no Mr. Bill!\n", host->host_no);
-#endif
-    
-/*
- * If a fatal SCSI interrupt occurs, we must insure that the DMA and
- * SCSI FIFOs were flushed.
- */
-
-    if (fatal) {
-       if (!hostdata->dstat_valid) {
-           hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
-           hostdata->dstat_valid = 1;
-       }
-
-       if (!(hostdata->dstat & DSTAT_DFE)) {
-         printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
-         /*
-          * Really need to check this code for 710  RGH.
-          * Havn't seen any problems, but maybe we should FLUSH before
-          * clearing sometimes.
-          */
-          NCR53c7x0_write8 (CTEST8_REG, CTEST8_10_CLF);
-          while (NCR53c7x0_read8 (CTEST8_REG) & CTEST8_10_CLF)
-               ;
-         hostdata->dstat |= DSTAT_DFE;
-       }
-    }
-}
-
-#ifdef CYCLIC_TRACE
-
-/*
- * The following implements a cyclic log of instructions executed, if you turn
- * TRACE on.  It will also print the log for you.  Very useful when debugging
- * 53c710 support, possibly not really needed any more.
- */
-
-u32 insn_log[4096];
-u32 insn_log_index = 0;
-
-void log1 (u32 i)
-{
-       insn_log[insn_log_index++] = i;
-       if (insn_log_index == 4096)
-               insn_log_index = 0;
-}
-
-void log_insn (u32 *ip)
-{
-       log1 ((u32)ip);
-       log1 (*ip);
-       log1 (*(ip+1));
-       if (((*ip >> 24) & DCMD_TYPE_MASK) == DCMD_TYPE_MMI)
-               log1 (*(ip+2));
-}
-
-void dump_log(void)
-{
-       int cnt = 0;
-       int i = insn_log_index;
-       int size;
-       struct Scsi_Host *host = first_host;
-
-       while (cnt < 4096) {
-               printk ("%08x (+%6x): ", insn_log[i], (insn_log[i] - (u32)&(((struct NCR53c7x0_hostdata *)host->hostdata[0])->script))/4);
-               if (++i == 4096)
-                       i = 0;
-               cnt++;
-               if (((insn_log[i]  >> 24) & DCMD_TYPE_MASK) == DCMD_TYPE_MMI) 
-                       size = 3;
-               else
-                       size = 2;
-               while (size--) {
-                       printk ("%08x ", insn_log[i]);
-                       if (++i == 4096)
-                               i = 0;
-                       cnt++;
-               }
-               printk ("\n");
-       }
-}
-#endif
-
-
-/*
- * Function : static void NCR53c7x0_intfly (struct Scsi_Host *host)
- *
- * Purpose : Scan command queue for specified host, looking for completed
- *           commands.
- * 
- * Inputs : Scsi_Host pointer.
- *
- *     This is called from the interrupt handler, when a simulated INTFLY
- *     interrupt occurs.
- */
-
-static void
-NCR53c7x0_intfly (struct Scsi_Host *host)
-{
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata;       /* host->hostdata[0] */
-    struct NCR53c7x0_cmd *cmd,                 /* command which halted */
-       **cmd_prev_ptr;
-    unsigned long flags;                               
-    char search_found = 0;                     /* Got at least one ? */
-
-    hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
-    NCR53c7x0_local_setup(host);
-
-    if (hostdata->options & OPTION_DEBUG_INTR)
-    printk ("scsi%d : INTFLY\n", host->host_no); 
-
-    /*
-    * Traverse our list of running commands, and look
-    * for those with valid (non-0xff ff) status and message
-    * bytes encoded in the result which signify command
-    * completion.
-    */
-
-    local_irq_save(flags);
-restart:
-    for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)&(hostdata->running_list),
-       cmd = (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
-       cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next), 
-       cmd = (struct NCR53c7x0_cmd *) cmd->next)
-    {
-       Scsi_Cmnd *tmp;
-
-       if (!cmd) {
-           printk("scsi%d : very weird.\n", host->host_no);
-           break;
-       }
-
-       if (!(tmp = cmd->cmd)) {
-           printk("scsi%d : weird.  NCR53c7x0_cmd has no Scsi_Cmnd\n",
-                   host->host_no);
-           continue;
-       }
-       /* Copy the result over now; may not be complete,
-        * but subsequent tests may as well be done on
-        * cached memory.
-        */
-       tmp->result = cmd->result;
-
-       if (((tmp->result & 0xff) == 0xff) ||
-                           ((tmp->result & 0xff00) == 0xff00))
-           continue;
-
-       search_found = 1;
-
-       if (cmd->bounce.len)
-           memcpy ((void *)cmd->bounce.addr,
-                               (void *)cmd->bounce.buf, cmd->bounce.len);
-
-       /* Important - remove from list _before_ done is called */
-       if (cmd_prev_ptr)
-           *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next;
-
-       --hostdata->busy[tmp->device->id][tmp->device->lun];
-       cmd->next = hostdata->free;
-       hostdata->free = cmd;
-
-       tmp->host_scribble = NULL;
-
-       if (hostdata->options & OPTION_DEBUG_INTR) {
-           printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 0x%x ", 
-                 host->host_no, tmp->pid, tmp->device->id, tmp->device->lun, tmp->result);
-           __scsi_print_command (tmp->cmnd);
-       }
-
-       tmp->scsi_done(tmp);
-       goto restart;
-    }
-    local_irq_restore(flags);
-
-    if (!search_found)  {
-       printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
-                           host->host_no);
-    } else {
-       run_process_issue_queue();
-    }
-    return;
-}
-
-/*
- * Function : static irqreturn_t NCR53c7x0_intr (int irq, void *dev_id)
- *
- * Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing
- *     the same IRQ line.  
- * 
- * Inputs : Since we're using the IRQF_DISABLED interrupt handler
- *     semantics, irq indicates the interrupt which invoked 
- *     this handler.  
- *
- * On the 710 we simualte an INTFLY with a script interrupt, and the
- * script interrupt handler will call back to this function.
- */
-
-static irqreturn_t
-NCR53c7x0_intr (int irq, void *dev_id)
-{
-    NCR53c7x0_local_declare();
-    struct Scsi_Host *host;                    /* Host we are looking at */
-    unsigned char istat;                       /* Values of interrupt regs */
-    struct NCR53c7x0_hostdata *hostdata;       /* host->hostdata[0] */
-    struct NCR53c7x0_cmd *cmd;                 /* command which halted */
-    u32 *dsa;                                  /* DSA */
-    int handled = 0;
-
-#ifdef NCR_DEBUG
-    char buf[80];                              /* Debugging sprintf buffer */
-    size_t buflen;                             /* Length of same */
-#endif
-
-    host     = (struct Scsi_Host *)dev_id;
-    hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
-    NCR53c7x0_local_setup(host);
-
-    /*
-     * Only read istat once per loop, since reading it again will unstack
-     * interrupts
-     */
-
-    while ((istat = NCR53c7x0_read8(hostdata->istat)) & (ISTAT_SIP|ISTAT_DIP)) {
-       handled = 1;
-       hostdata->dsp_changed = 0;
-       hostdata->dstat_valid = 0;
-       hostdata->state = STATE_HALTED;
-
-       if (NCR53c7x0_read8 (SSTAT2_REG) & SSTAT2_FF_MASK) 
-           printk ("scsi%d : SCSI FIFO not empty\n", host->host_no);
-
-       /*
-        * NCR53c700 and NCR53c700-66 change the current SCSI
-        * process, hostdata->ncrcurrent, in the Linux driver so
-        * cmd = hostdata->ncrcurrent.
-        *
-        * With other chips, we must look through the commands
-        * executing and find the command structure which 
-        * corresponds to the DSA register.
-        */
-
-       if (hostdata->options & OPTION_700) {
-           cmd = (struct NCR53c7x0_cmd *) hostdata->ncrcurrent;
-       } else {
-           dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
-           for (cmd = (struct NCR53c7x0_cmd *) hostdata->running_list;
-               cmd && (dsa + (hostdata->dsa_start / sizeof(u32))) != cmd->dsa;
-                   cmd = (struct NCR53c7x0_cmd *)(cmd->next))
-               ;
-       }
-       if (hostdata->options & OPTION_DEBUG_INTR) {
-           if (cmd) {
-               printk("scsi%d : interrupt for pid %lu, id %d, lun %d ", 
-                   host->host_no, cmd->cmd->pid, (int) cmd->cmd->device->id,
-                   (int) cmd->cmd->device->lun);
-               __scsi_print_command (cmd->cmd->cmnd);
-           } else {
-               printk("scsi%d : no active command\n", host->host_no);
-           }
-       }
-       
-       if (istat & ISTAT_SIP) {
-           if (hostdata->options & OPTION_DEBUG_INTR) 
-               printk ("scsi%d : ISTAT_SIP\n", host->host_no);
-           intr_scsi (host, cmd);
-       }
-       
-       if (istat & ISTAT_DIP) {
-           if (hostdata->options & OPTION_DEBUG_INTR) 
-               printk ("scsi%d : ISTAT_DIP\n", host->host_no);
-           intr_dma (host, cmd);
-       }
-       
-       if (!hostdata->dstat_valid) {
-           hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
-           hostdata->dstat_valid = 1;
-       }
-       
-       if (!(hostdata->dstat & DSTAT_DFE)) {
-           printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
-           /* Really need to check this out for 710 RGH */
-           NCR53c7x0_write8 (CTEST8_REG, CTEST8_10_CLF);
-           while (NCR53c7x0_read8 (CTEST8_REG) & CTEST8_10_CLF)
-               ;
-           hostdata->dstat |= DSTAT_DFE;
-       }
-
-       if (!hostdata->idle && hostdata->state == STATE_HALTED) {
-           if (!hostdata->dsp_changed)
-               hostdata->dsp = (u32 *)bus_to_virt(NCR53c7x0_read32(DSP_REG));
-#if 0
-           printk("scsi%d : new dsp is 0x%lx (virt 0x%p)\n",
-               host->host_no,  virt_to_bus(hostdata->dsp), hostdata->dsp);
-#endif
-               
-           hostdata->state = STATE_RUNNING;
-           NCR53c7x0_write32 (DSP_REG, virt_to_bus(hostdata->dsp));
-           if (hostdata->options & OPTION_DEBUG_TRACE) {
-#ifdef CYCLIC_TRACE
-               log_insn (hostdata->dsp);
-#else
-               print_insn (host, hostdata->dsp, "t ", 1);
-#endif
-               NCR53c7x0_write8 (DCNTL_REG,
-                       hostdata->saved_dcntl | DCNTL_SSM | DCNTL_STD);
-           }
-       }
-    }
-    return IRQ_HANDLED;
-}
-
-
-/* 
- * Function : static int abort_connected (struct Scsi_Host *host)
- *
- * Purpose : Assuming that the NCR SCSI processor is currently 
- *     halted, break the currently established nexus.  Clean
- *     up of the NCR53c7x0_cmd and Scsi_Cmnd structures should
- *     be done on receipt of the abort interrupt.
- *
- * Inputs : host - SCSI host
- *
- */
-
-static int 
-abort_connected (struct Scsi_Host *host) {
-#ifdef NEW_ABORT
-    NCR53c7x0_local_declare();
-#endif
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-/* FIXME : this probably should change for production kernels; at the 
-   least, counter should move to a per-host structure. */
-    static int counter = 5;
-#ifdef NEW_ABORT
-    int sstat, phase, offset;
-    u32 *script;
-    NCR53c7x0_local_setup(host);
-#endif
-
-    if (--counter <= 0) {
-       disable(host);
-       return 0;
-    }
-
-    printk ("scsi%d : DANGER : abort_connected() called \n",
-       host->host_no);
-
-#ifdef NEW_ABORT
-
-/*
- * New strategy : Rather than using a generic abort routine,
- * we'll specifically try to source or sink the appropriate
- * amount of data for the phase we're currently in (taking into 
- * account the current synchronous offset) 
- */
-
-    sstat = NCR53c8x0_read8 (SSTAT2_REG);
-    offset = OFFSET (sstat & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
-    phase = sstat & SSTAT2_PHASE_MASK;
-
-/*
- * SET ATN
- * MOVE source_or_sink, WHEN CURRENT PHASE 
- * < repeat for each outstanding byte >
- * JUMP send_abort_message
- */
-
-    script = hostdata->abort_script = kmalloc (
-       8  /* instruction size */ * (
-           1 /* set ATN */ +
-           (!offset ? 1 : offset) /* One transfer per outstanding byte */ +
-           1 /* send abort message */),
-       GFP_ATOMIC);
-
-
-#else /* def NEW_ABORT */
-    hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
-           sizeof(u32);
-#endif /* def NEW_ABORT */
-    hostdata->dsp_changed = 1;
-
-/* XXX - need to flag the command as aborted after the abort_connected
-        code runs 
- */
-    return 0;
-}
-
-/*
- * Function : static int datapath_residual (Scsi_Host *host)
- *
- * Purpose : return residual data count of what's in the chip.
- *
- * Inputs : host - SCSI host
- */
-
-static int
-datapath_residual (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    int count, synchronous, sstat;
-    unsigned int ddir;
-
-    NCR53c7x0_local_setup(host);
-    /* COMPAT : the 700 and 700-66 need to use DFIFO_00_BO_MASK */
-    count = ((NCR53c7x0_read8 (DFIFO_REG) & DFIFO_10_BO_MASK) -
-       (NCR53c7x0_read32 (DBC_REG) & DFIFO_10_BO_MASK)) & DFIFO_10_BO_MASK;
-    synchronous = NCR53c7x0_read8 (SXFER_REG) & SXFER_MO_MASK;
-    /* COMPAT : DDIR is elsewhere on non-'8xx chips. */
-    ddir = NCR53c7x0_read8 (CTEST0_REG_700) & CTEST0_700_DDIR;
-
-    if (ddir) {
-    /* Receive */
-       if (synchronous) 
-           count += (NCR53c7x0_read8 (SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
-       else
-           if (NCR53c7x0_read8 (SSTAT1_REG) & SSTAT1_ILF)
-               ++count;
-    } else {
-    /* Send */
-       sstat = NCR53c7x0_read8 (SSTAT1_REG);
-       if (sstat & SSTAT1_OLF)
-           ++count;
-       if (synchronous && (sstat & SSTAT1_ORF))
-           ++count;
-    }
-    return count;
-}
-
-/* 
- * Function : static const char * sbcl_to_phase (int sbcl)_
- *
- * Purpose : Convert SBCL register to user-parsable phase representation
- *
- * Inputs : sbcl - value of sbcl register
- */
-
-
-static const char *
-sbcl_to_phase (int sbcl) {
-    switch (sbcl & SBCL_PHASE_MASK) {
-    case SBCL_PHASE_DATAIN:
-       return "DATAIN";
-    case SBCL_PHASE_DATAOUT:
-       return "DATAOUT";
-    case SBCL_PHASE_MSGIN:
-       return "MSGIN";
-    case SBCL_PHASE_MSGOUT:
-       return "MSGOUT";
-    case SBCL_PHASE_CMDOUT:
-       return "CMDOUT";
-    case SBCL_PHASE_STATIN:
-       return "STATUSIN";
-    default:
-       return "unknown";
-    }
-}
-
-/* 
- * Function : static const char * sstat2_to_phase (int sstat)_
- *
- * Purpose : Convert SSTAT2 register to user-parsable phase representation
- *
- * Inputs : sstat - value of sstat register
- */
-
-
-static const char *
-sstat2_to_phase (int sstat) {
-    switch (sstat & SSTAT2_PHASE_MASK) {
-    case SSTAT2_PHASE_DATAIN:
-       return "DATAIN";
-    case SSTAT2_PHASE_DATAOUT:
-       return "DATAOUT";
-    case SSTAT2_PHASE_MSGIN:
-       return "MSGIN";
-    case SSTAT2_PHASE_MSGOUT:
-       return "MSGOUT";
-    case SSTAT2_PHASE_CMDOUT:
-       return "CMDOUT";
-    case SSTAT2_PHASE_STATIN:
-       return "STATUSIN";
-    default:
-       return "unknown";
-    }
-}
-
-/* 
- * Function : static void intr_phase_mismatch (struct Scsi_Host *host, 
- *     struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : Handle phase mismatch interrupts
- *
- * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
- *     may be NULL.
- *
- * Side effects : The abort_connected() routine is called or the NCR chip 
- *     is restarted, jumping to the command_complete entry point, or 
- *     patching the address and transfer count of the current instruction 
- *     and calling the msg_in entry point as appropriate.
- */
-
-static void 
-intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    u32 dbc_dcmd, *dsp, *dsp_next;
-    unsigned char dcmd, sbcl;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    int residual;
-    enum {ACTION_ABORT, ACTION_ABORT_PRINT, ACTION_CONTINUE} action = 
-       ACTION_ABORT_PRINT;
-    const char *where = NULL;
-
-    NCR53c7x0_local_setup(host);
-
-    /*
-     * Corrective action is based on where in the SCSI SCRIPT(tm) the error 
-     * occurred, as well as which SCSI phase we are currently in.
-     */
-    dsp_next = bus_to_virt(NCR53c7x0_read32(DSP_REG));
-
-    /* 
-     * Fetch the current instruction, and remove the operands for easier 
-     * interpretation.
-     */
-    dbc_dcmd = NCR53c7x0_read32(DBC_REG);
-    dcmd = (dbc_dcmd & 0xff000000) >> 24;
-    /*
-     * Like other processors, the NCR adjusts the instruction pointer before
-     * instruction decode.  Set the DSP address back to what it should
-     * be for this instruction based on its size (2 or 3 32 bit words).
-     */
-    dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
-
-
-    /*
-     * Read new SCSI phase from the SBCL lines.  Since all of our code uses 
-     * a WHEN conditional instead of an IF conditional, we don't need to 
-     * wait for a new REQ.
-     */
-    sbcl = NCR53c7x0_read8(SBCL_REG) & SBCL_PHASE_MASK;
-
-    if (!cmd) {
-       action = ACTION_ABORT_PRINT;
-       where = "no current command";
-    /*
-     * The way my SCSI SCRIPTS(tm) are architected, recoverable phase
-     * mismatches should only occur where we're doing a multi-byte  
-     * BMI instruction.  Specifically, this means 
-     *
-     *  - select messages (a SCSI-I target may ignore additional messages
-     *                 after the IDENTIFY; any target may reject a SDTR or WDTR)
-     *
-     *  - command out (targets may send a message to signal an error 
-     *                 condition, or go into STATUSIN after they've decided 
-     *         they don't like the command.
-     *
-     * - reply_message (targets may reject a multi-byte message in the 
-     *         middle)
-     *
-     *         - data transfer routines (command completion with buffer space
-     *         left, disconnect message, or error message)
-     */
-    } else if (((dsp >= cmd->data_transfer_start && 
-       dsp < cmd->data_transfer_end)) || dsp == (cmd->residual + 2)) {
-       if ((dcmd & (DCMD_TYPE_MASK|DCMD_BMI_OP_MASK|DCMD_BMI_INDIRECT|
-               DCMD_BMI_MSG|DCMD_BMI_CD)) == (DCMD_TYPE_BMI|
-               DCMD_BMI_OP_MOVE_I)) {
-           residual = datapath_residual (host);
-           if (hostdata->options & OPTION_DEBUG_DISCONNECT)
-               printk ("scsi%d : handling residual transfer (+ %d bytes from DMA FIFO)\n", 
-                   host->host_no, residual);
-
-           /*
-            * The first instruction is a CALL to the alternate handler for 
-            * this data transfer phase, so we can do calls to 
-            * munge_msg_restart as we would if control were passed 
-            * from normal dynamic code.
-            */
-           if (dsp != cmd->residual + 2) {
-               cmd->residual[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
-                       ((dcmd & DCMD_BMI_IO) ? DCMD_TCI_IO : 0)) << 24) | 
-                   DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
-               cmd->residual[1] = virt_to_bus(hostdata->script)
-                   + ((dcmd & DCMD_BMI_IO)
-                      ? hostdata->E_other_in : hostdata->E_other_out);
-           }
-
-           /*
-            * The second instruction is the a data transfer block
-            * move instruction, reflecting the pointer and count at the 
-            * time of the phase mismatch.
-            */
-           cmd->residual[2] = dbc_dcmd + residual;
-           cmd->residual[3] = NCR53c7x0_read32(DNAD_REG) - residual;
-
-           /*
-            * The third and final instruction is a jump to the instruction
-            * which follows the instruction which had to be 'split'
-            */
-           if (dsp != cmd->residual + 2) {
-               cmd->residual[4] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) 
-                   << 24) | DBC_TCI_TRUE;
-               cmd->residual[5] = virt_to_bus(dsp_next);
-           }
-
-           /*
-            * For the sake of simplicity, transfer control to the 
-            * conditional CALL at the start of the residual buffer.
-            */
-           hostdata->dsp = cmd->residual;
-           hostdata->dsp_changed = 1;
-           action = ACTION_CONTINUE;
-       } else {
-           where = "non-BMI dynamic DSA code";
-           action = ACTION_ABORT_PRINT;
-       }
-    } else if (dsp == (hostdata->script + hostdata->E_select_msgout / 4 + 2)) {
-       /* RGH 290697:  Added +2 above, to compensate for the script
-        * instruction which disables the selection timer. */
-       /* Release ATN */
-       NCR53c7x0_write8 (SOCL_REG, 0);
-       switch (sbcl) {
-    /* 
-     * Some devices (SQ555 come to mind) grab the IDENTIFY message
-     * sent on selection, and decide to go into COMMAND OUT phase
-     * rather than accepting the rest of the messages or rejecting
-     * them.  Handle these devices gracefully.
-     */
-       case SBCL_PHASE_CMDOUT:
-           hostdata->dsp = dsp + 2 /* two _words_ */;
-           hostdata->dsp_changed = 1;
-           printk ("scsi%d : target %d ignored SDTR and went into COMMAND OUT\n", 
-               host->host_no, cmd->cmd->device->id);
-           cmd->flags &= ~CMD_FLAG_SDTR;
-           action = ACTION_CONTINUE;
-           break;
-       case SBCL_PHASE_MSGIN:
-           hostdata->dsp = hostdata->script + hostdata->E_msg_in / 
-               sizeof(u32);
-           hostdata->dsp_changed = 1;
-           action = ACTION_CONTINUE;
-           break;
-       default:
-           where="select message out";
-           action = ACTION_ABORT_PRINT;
-       }
-    /*
-     * Some SCSI devices will interpret a command as they read the bytes
-     * off the SCSI bus, and may decide that the command is Bogus before 
-     * they've read the entire command off the bus.
-     */
-    } else if (dsp == hostdata->script + hostdata->E_cmdout_cmdout / sizeof 
-       (u32)) {
-       hostdata->dsp = hostdata->script + hostdata->E_data_transfer /
-           sizeof (u32);
-       hostdata->dsp_changed = 1;
-       action = ACTION_CONTINUE;
-    /* FIXME : we need to handle message reject, etc. within msg_respond. */
-#ifdef notyet
-    } else if (dsp == hostdata->script + hostdata->E_reply_message) {
-       switch (sbcl) {
-    /* Any other phase mismatches abort the currently executing command.  */
-#endif
-    } else {
-       where = "unknown location";
-       action = ACTION_ABORT_PRINT;
-    }
-
-    /* Flush DMA FIFO */
-    if (!hostdata->dstat_valid) {
-       hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
-       hostdata->dstat_valid = 1;
-    }
-    if (!(hostdata->dstat & DSTAT_DFE)) {
-      /* Really need to check this out for 710 RGH */
-      NCR53c7x0_write8 (CTEST8_REG, CTEST8_10_CLF);
-      while (NCR53c7x0_read8 (CTEST8_REG) & CTEST8_10_CLF);
-      hostdata->dstat |= DSTAT_DFE;
-    }
-
-    switch (action) {
-    case ACTION_ABORT_PRINT:
-       printk("scsi%d : %s : unexpected phase %s.\n",
-            host->host_no, where ? where : "unknown location", 
-            sbcl_to_phase(sbcl));
-       print_lots (host);
-    /* Fall through to ACTION_ABORT */
-    case ACTION_ABORT:
-       abort_connected (host);
-       break;
-    case ACTION_CONTINUE:
-       break;
-    }
-
-#if 0
-    if (hostdata->dsp_changed) {
-       printk("scsi%d: new dsp 0x%p\n", host->host_no, hostdata->dsp);
-       print_insn (host, hostdata->dsp, "", 1);
-    }
-#endif
-}
-
-/*
- * Function : static void intr_bf (struct Scsi_Host *host, 
- *     struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : handle BUS FAULT interrupts 
- *
- * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
- *     may be NULL.
- */
-
-static void
-intr_bf (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    u32 *dsp,
-       *next_dsp,              /* Current dsp */
-       *dsa,
-       dbc_dcmd;               /* DCMD (high eight bits) + DBC */
-    char *reason = NULL;
-    /* Default behavior is for a silent error, with a retry until we've
-       exhausted retries. */
-    enum {MAYBE, ALWAYS, NEVER} retry = MAYBE;
-    int report = 0;
-    NCR53c7x0_local_setup(host);
-
-    dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
-    next_dsp = bus_to_virt (NCR53c7x0_read32(DSP_REG));
-    dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
-/* FIXME - check chip type  */
-    dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG));
-
-    /*
-     * Bus faults can be caused by either a Bad Address or 
-     * Target Abort. We should check the Received Target Abort
-     * bit of the PCI status register and Master Abort Bit.
-     *
-     *         - Master Abort bit indicates that no device claimed
-     *         the address with DEVSEL within five clocks
-     *
-     * - Target Abort bit indicates that a target claimed it,
-     *         but changed its mind once it saw the byte enables.
-     *
-     */
-
-    /* 53c710, not PCI system */
-    report = 1;
-    reason = "Unknown";
-
-#ifndef notyet
-    report = 1;
-#endif
-    if (report && reason)
-    {
-       printk(KERN_ALERT "scsi%d : BUS FAULT reason = %s\n",
-            host->host_no, reason ? reason : "unknown");
-       print_lots (host);
-    }
-
-#ifndef notyet
-    retry = NEVER;
-#endif
-
-    /* 
-     * TODO : we should attempt to recover from any spurious bus 
-     * faults.  After X retries, we should figure that things are 
-     * sufficiently wedged, and call NCR53c7xx_reset.
-     *
-     * This code should only get executed once we've decided that we 
-     * cannot retry.
-     */
-
-    if (retry == NEVER) {
-       printk(KERN_ALERT "          mail richard@sleepie.demon.co.uk\n");
-       FATAL (host);
-    }
-}
-
-/*
- * Function : static void intr_dma (struct Scsi_Host *host, 
- *     struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : handle all DMA interrupts, indicated by the setting 
- *     of the DIP bit in the ISTAT register.
- *
- * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
- *     may be NULL.
- */
-
-static void 
-intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    unsigned char dstat;       /* DSTAT */     
-    u32 *dsp,
-       *next_dsp,              /* Current dsp */
-       *dsa,
-       dbc_dcmd;               /* DCMD (high eight bits) + DBC */
-    int tmp;
-    unsigned long flags;
-    NCR53c7x0_local_setup(host);
-
-    if (!hostdata->dstat_valid) {
-       hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
-       hostdata->dstat_valid = 1;
-    }
-    
-    dstat = hostdata->dstat;
-    
-    if (hostdata->options & OPTION_DEBUG_INTR)
-       printk("scsi%d : DSTAT=0x%x\n", host->host_no, (int) dstat);
-
-    dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
-    next_dsp = bus_to_virt(NCR53c7x0_read32(DSP_REG));
-    dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
-/* XXX - check chip type */
-    dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
-
-    /*
-     * DSTAT_ABRT is the aborted interrupt.  This is set whenever the 
-     * SCSI chip is aborted.  
-     * 
-     * With NCR53c700 and NCR53c700-66 style chips, we should only 
-     * get this when the chip is currently running the accept 
-     * reselect/select code and we have set the abort bit in the 
-     * ISTAT register.
-     *
-     */
-    
-    if (dstat & DSTAT_ABRT) {
-#if 0
-       /* XXX - add code here to deal with normal abort */
-       if ((hostdata->options & OPTION_700) && (hostdata->state ==
-           STATE_ABORTING)) {
-       } else 
-#endif
-       {
-           printk(KERN_ALERT "scsi%d : unexpected abort interrupt at\n" 
-                  "         ", host->host_no);
-           print_insn (host, dsp, KERN_ALERT "s ", 1);
-           FATAL (host);
-       }
-    }
-
-    /*
-     * DSTAT_SSI is the single step interrupt.  Should be generated 
-     * whenever we have single stepped or are tracing.
-     */
-
-    if (dstat & DSTAT_SSI) {
-       if (hostdata->options & OPTION_DEBUG_TRACE) {
-           /* Don't print instr. until we write DSP at end of intr function */
-       } else if (hostdata->options & OPTION_DEBUG_SINGLE) {
-           print_insn (host, dsp, "s ", 0);
-           local_irq_save(flags);
-/* XXX - should we do this, or can we get away with writing dsp? */
-
-           NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) & 
-               ~DCNTL_SSM) | DCNTL_STD);
-           local_irq_restore(flags);
-       } else {
-           printk(KERN_ALERT "scsi%d : unexpected single step interrupt at\n"
-                  "         ", host->host_no);
-           print_insn (host, dsp, KERN_ALERT "", 1);
-           printk(KERN_ALERT "         mail drew@PoohSticks.ORG\n");
-           FATAL (host);
-       }
-    }
-
-    /*
-     * DSTAT_IID / DSTAT_OPC (same bit, same meaning, only the name 
-     * is different) is generated whenever an illegal instruction is 
-     * encountered.  
-     * 
-     * XXX - we may want to emulate INTFLY here, so we can use 
-     *    the same SCSI SCRIPT (tm) for NCR53c710 through NCR53c810  
-     *   chips.
-     */
-
-    if (dstat & DSTAT_OPC) {
-    /* 
-     * Ascertain if this IID interrupts occurred before or after a STO 
-     * interrupt.  Since the interrupt handling code now leaves 
-     * DSP unmodified until _after_ all stacked interrupts have been
-     * processed, reading the DSP returns the original DSP register.
-     * This means that if dsp lies between the select code, and 
-     * message out following the selection code (where the IID interrupt
-     * would have to have occurred by due to the implicit wait for REQ),
-     * we have an IID interrupt resulting from a STO condition and 
-     * can ignore it.
-     */
-
-       if (((dsp >= (hostdata->script + hostdata->E_select / sizeof(u32))) &&
-           (dsp <= (hostdata->script + hostdata->E_select_msgout / 
-           sizeof(u32) + 8))) || (hostdata->test_running == 2)) {
-           if (hostdata->options & OPTION_DEBUG_INTR) 
-               printk ("scsi%d : ignoring DSTAT_IID for SSTAT_STO\n",
-                   host->host_no);
-           if (hostdata->expecting_iid) {
-               hostdata->expecting_iid = 0;
-               hostdata->idle = 1;
-               if (hostdata->test_running == 2) {
-                   hostdata->test_running = 0;
-                   hostdata->test_completed = 3;
-               } else if (cmd) 
-                       abnormal_finished (cmd, DID_BAD_TARGET << 16);
-           } else {
-               hostdata->expecting_sto = 1;
-           }
-    /*
-     * We can't guarantee we'll be able to execute the WAIT DISCONNECT
-     * instruction within the 3.4us of bus free and arbitration delay
-     * that a target can RESELECT in and assert REQ after we've dropped
-     * ACK.  If this happens, we'll get an illegal instruction interrupt.
-     * Doing away with the WAIT DISCONNECT instructions broke everything,
-     * so instead I'll settle for moving one WAIT DISCONNECT a few 
-     * instructions closer to the CLEAR ACK before it to minimize the
-     * chances of this happening, and handle it if it occurs anyway.
-     *
-     * Simply continue with what we were doing, and control should
-     * be transferred to the schedule routine which will ultimately
-     * pass control onto the reselection or selection (not yet)
-     * code.
-     */
-       } else if (dbc_dcmd == 0x48000000 && (NCR53c7x0_read8 (SBCL_REG) &
-           SBCL_REQ)) {
-           if (!(hostdata->options & OPTION_NO_PRINT_RACE))
-           {
-               printk("scsi%d: REQ before WAIT DISCONNECT IID\n", 
-                   host->host_no);
-               hostdata->options |= OPTION_NO_PRINT_RACE;
-           }
-       } else {
-           printk(KERN_ALERT "scsi%d : invalid instruction\n", host->host_no);
-           print_lots (host);
-           printk(KERN_ALERT "         mail Richard@sleepie.demon.co.uk with ALL\n"
-                             "         boot messages and diagnostic output\n");
-           FATAL (host);
-       }
-    }
-
-    /* 
-     * DSTAT_BF are bus fault errors.  DSTAT_800_BF is valid for 710 also.
-     */
-    
-    if (dstat & DSTAT_800_BF) {
-       intr_bf (host, cmd);
-    }
-       
-
-    /* 
-     * DSTAT_SIR interrupts are generated by the execution of 
-     * the INT instruction.  Since the exact values available 
-     * are determined entirely by the SCSI script running, 
-     * and are local to a particular script, a unique handler
-     * is called for each script.
-     */
-
-    if (dstat & DSTAT_SIR) {
-       if (hostdata->options & OPTION_DEBUG_INTR)
-           printk ("scsi%d : DSTAT_SIR\n", host->host_no);
-       switch ((tmp = hostdata->dstat_sir_intr (host, cmd))) {
-       case SPECIFIC_INT_NOTHING:
-       case SPECIFIC_INT_RESTART:
-           break;
-       case SPECIFIC_INT_ABORT:
-           abort_connected(host);
-           break;
-       case SPECIFIC_INT_PANIC:
-           printk(KERN_ALERT "scsi%d : failure at ", host->host_no);
-           print_insn (host, dsp, KERN_ALERT "", 1);
-           printk(KERN_ALERT "          dstat_sir_intr() returned SPECIFIC_INT_PANIC\n");
-           FATAL (host);
-           break;
-       case SPECIFIC_INT_BREAK:
-           intr_break (host, cmd);
-           break;
-       default:
-           printk(KERN_ALERT "scsi%d : failure at ", host->host_no);
-           print_insn (host, dsp, KERN_ALERT "", 1);
-           printk(KERN_ALERT"          dstat_sir_intr() returned unknown value %d\n", 
-               tmp);
-           FATAL (host);
-       }
-    } 
-}
-
-/*
- * Function : static int print_insn (struct Scsi_Host *host, 
- *     u32 *insn, int kernel)
- *
- * Purpose : print numeric representation of the instruction pointed
- *     to by insn to the debugging or kernel message buffer
- *     as appropriate.  
- *
- *     If desired, a user level program can interpret this 
- *     information.
- *
- * Inputs : host, insn - host, pointer to instruction, prefix - 
- *     string to prepend, kernel - use printk instead of debugging buffer.
- *
- * Returns : size, in u32s, of instruction printed.
- */
-
-/*
- * FIXME: should change kernel parameter so that it takes an ENUM
- *     specifying severity - either KERN_ALERT or KERN_PANIC so
- *     all panic messages are output with the same severity.
- */
-
-static int 
-print_insn (struct Scsi_Host *host, const u32 *insn, 
-    const char *prefix, int kernel) {
-    char buf[160],             /* Temporary buffer and pointer.  ICKY 
-                                  arbitrary length.  */
-
-               
-       *tmp;                   
-    unsigned char dcmd;                /* dcmd register for *insn */
-    int size;
-
-    /* 
-     * Check to see if the instruction pointer is not bogus before 
-     * indirecting through it; avoiding red-zone at start of 
-     * memory.
-     *
-     * FIXME: icky magic needs to happen here on non-intel boxes which
-     * don't have kernel memory mapped in like this.  Might be reasonable
-     * to use vverify()?
-     */
-
-    if (virt_to_phys((void *)insn) < PAGE_SIZE || 
-       virt_to_phys((void *)(insn + 8)) > virt_to_phys(high_memory) ||
-       ((((dcmd = (insn[0] >> 24) & 0xff) & DCMD_TYPE_MMI) == DCMD_TYPE_MMI) &&
-       virt_to_phys((void *)(insn + 12)) > virt_to_phys(high_memory))) {
-       size = 0;
-       sprintf (buf, "%s%p: address out of range\n",
-           prefix, insn);
-    } else {
-/* 
- * FIXME : (void *) cast in virt_to_bus should be unnecessary, because
- *     it should take const void * as argument.
- */
-#if !defined(CONFIG_MVME16x) && !defined(CONFIG_BVME6000)
-       sprintf(buf, "%s0x%lx (virt 0x%p) : 0x%08x 0x%08x (virt 0x%p)", 
-           (prefix ? prefix : ""), virt_to_bus((void *) insn), insn,  
-           insn[0], insn[1], bus_to_virt (insn[1]));
-#else
-       /* Remove virtual addresses to reduce output, as they are the same */
-       sprintf(buf, "%s0x%x (+%x) : 0x%08x 0x%08x", 
-           (prefix ? prefix : ""), (u32)insn, ((u32)insn -
-               (u32)&(((struct NCR53c7x0_hostdata *)host->hostdata[0])->script))/4, 
-           insn[0], insn[1]);
-#endif
-       tmp = buf + strlen(buf);
-       if ((dcmd & DCMD_TYPE_MASK) == DCMD_TYPE_MMI)  {
-#if !defined(CONFIG_MVME16x) && !defined(CONFIG_BVME6000)
-           sprintf (tmp, " 0x%08x (virt 0x%p)\n", insn[2], 
-               bus_to_virt(insn[2]));
-#else
-           /* Remove virtual addr to reduce output, as it is the same */
-           sprintf (tmp, " 0x%08x\n", insn[2]);
-#endif
-           size = 3;
-       } else {
-           sprintf (tmp, "\n");
-           size = 2;
-       }
-    }
-
-    if (kernel) 
-       printk ("%s", buf);
-#ifdef NCR_DEBUG
-    else {
-       size_t len = strlen(buf);
-       debugger_kernel_write(host, buf, len);
-    }
-#endif
-    return size;
-}
-
-/*
- * Function : int NCR53c7xx_abort (Scsi_Cmnd *cmd)
- * 
- * Purpose : Abort an errant SCSI command, doing all necessary
- *     cleanup of the issue_queue, running_list, shared Linux/NCR
- *     dsa issue and reconnect queues.
- *
- * Inputs : cmd - command to abort, code - entire result field
- *
- * Returns : 0 on success, -1 on failure.
- */
-
-int 
-NCR53c7xx_abort (Scsi_Cmnd *cmd) {
-    NCR53c7x0_local_declare();
-    struct Scsi_Host *host = cmd->device->host;
-    struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *) 
-       host->hostdata[0] : NULL;
-    unsigned long flags;
-    struct NCR53c7x0_cmd *curr, **prev;
-    Scsi_Cmnd *me, **last;
-#if 0
-    static long cache_pid = -1;
-#endif
-
-
-    if (!host) {
-       printk ("Bogus SCSI command pid %ld; no host structure\n",
-           cmd->pid);
-       return SCSI_ABORT_ERROR;
-    } else if (!hostdata) {
-       printk ("Bogus SCSI host %d; no hostdata\n", host->host_no);
-       return SCSI_ABORT_ERROR;
-    }
-    NCR53c7x0_local_setup(host);
-
-/*
- * CHECK : I don't think that reading ISTAT will unstack any interrupts,
- *     since we need to write the INTF bit to clear it, and SCSI/DMA
- *     interrupts don't clear until we read SSTAT/SIST and DSTAT registers.
- *     
- *     See that this is the case.  Appears to be correct on the 710, at least.
- *
- * I suspect that several of our failures may be coming from a new fatal
- * interrupt (possibly due to a phase mismatch) happening after we've left
- * the interrupt handler, but before the PIC has had the interrupt condition
- * cleared.
- */
-
-    if (NCR53c7x0_read8(hostdata->istat) & (ISTAT_DIP|ISTAT_SIP)) {
-       printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no,
-           cmd->pid);
-       NCR53c7x0_intr (host->irq, NULL, NULL);
-       return SCSI_ABORT_BUSY;
-    }
-       
-    local_irq_save(flags);
-#if 0
-    if (cache_pid == cmd->pid) 
-       panic ("scsi%d : bloody fetus %d\n", host->host_no, cmd->pid);
-    else
-       cache_pid = cmd->pid;
-#endif
-       
-
-/*
- * The command could be hiding in the issue_queue.  This would be very
- * nice, as commands can't be moved from the high level driver's issue queue 
- * into the shared queue until an interrupt routine is serviced, and this
- * moving is atomic.  
- *
- * If this is the case, we don't have to worry about anything - we simply
- * pull the command out of the old queue, and call it aborted.
- */
-
-    for (me = (Scsi_Cmnd *) hostdata->issue_queue, 
-         last = (Scsi_Cmnd **) &(hostdata->issue_queue);
-        me && me != cmd;  last = (Scsi_Cmnd **)&(me->SCp.ptr), 
-        me = (Scsi_Cmnd *)me->SCp.ptr);
-
-    if (me) {
-       *last = (Scsi_Cmnd *) me->SCp.ptr;
-       if (me->host_scribble) {
-           ((struct NCR53c7x0_cmd *)me->host_scribble)->next = hostdata->free;
-           hostdata->free = (struct NCR53c7x0_cmd *) me->host_scribble;
-           me->host_scribble = NULL;
-       }
-       cmd->result = DID_ABORT << 16;
-       cmd->scsi_done(cmd);
-       printk ("scsi%d : found command %ld in Linux issue queue\n", 
-           host->host_no, me->pid);
-       local_irq_restore(flags);
-       run_process_issue_queue();
-       return SCSI_ABORT_SUCCESS;
-    }
-
-/* 
- * That failing, the command could be in our list of already executing 
- * commands.  If this is the case, drastic measures are called for.  
- */ 
-
-    for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list, 
-        prev = (struct NCR53c7x0_cmd **) &(hostdata->running_list);
-        curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **) 
-         &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
-
-    if (curr) {
-       if ((curr->result & 0xff) != 0xff && (curr->result & 0xff00) != 0xff00) {
-            cmd->result = curr->result;
-           if (prev)
-               *prev = (struct NCR53c7x0_cmd *) curr->next;
-           curr->next = (struct NCR53c7x0_cmd *) hostdata->free;
-           cmd->host_scribble = NULL;
-           hostdata->free = curr;
-           cmd->scsi_done(cmd);
-       printk ("scsi%d : found finished command %ld in running list\n", 
-           host->host_no, cmd->pid);
-           local_irq_restore(flags);
-           return SCSI_ABORT_NOT_RUNNING;
-       } else {
-           printk ("scsi%d : DANGER : command running, can not abort.\n",
-               cmd->device->host->host_no);
-           local_irq_restore(flags);
-           return SCSI_ABORT_BUSY;
-       }
-    }
-
-/* 
- * And if we couldn't find it in any of our queues, it must have been 
- * a dropped interrupt.
- */
-
-    curr = (struct NCR53c7x0_cmd *) cmd->host_scribble;
-    if (curr) {
-       curr->next = hostdata->free;
-       hostdata->free = curr;
-       cmd->host_scribble = NULL;
-    }
-
-    if (curr == NULL || ((curr->result & 0xff00) == 0xff00) ||
-               ((curr->result & 0xff) == 0xff)) {
-       printk ("scsi%d : did this command ever run?\n", host->host_no);
-           cmd->result = DID_ABORT << 16;
-    } else {
-       printk ("scsi%d : probably lost INTFLY, normal completion\n", 
-           host->host_no);
-        cmd->result = curr->result;
-/* 
- * FIXME : We need to add an additional flag which indicates if a 
- * command was ever counted as BUSY, so if we end up here we can
- * decrement the busy count if and only if it is necessary.
- */
-        --hostdata->busy[cmd->device->id][cmd->device->lun];
-    }
-    local_irq_restore(flags);
-    cmd->scsi_done(cmd);
-
-/* 
- * We need to run process_issue_queue since termination of this command 
- * may allow another queued command to execute first? 
- */
-    return SCSI_ABORT_NOT_RUNNING;
-}
-
-/*
- * Function : int NCR53c7xx_reset (Scsi_Cmnd *cmd) 
- * 
- * Purpose : perform a hard reset of the SCSI bus and NCR
- *     chip.
- *
- * Inputs : cmd - command which caused the SCSI RESET
- *
- * Returns : 0 on success.
- */
-int 
-NCR53c7xx_reset (Scsi_Cmnd *cmd, unsigned int reset_flags) {
-    NCR53c7x0_local_declare();
-    unsigned long flags;
-    int found = 0;
-    struct NCR53c7x0_cmd * c;
-    Scsi_Cmnd *tmp;
-    /*
-     * When we call scsi_done(), it's going to wake up anything sleeping on the
-     * resources which were in use by the aborted commands, and we'll start to 
-     * get new commands.
-     *
-     * We can't let this happen until after we've re-initialized the driver
-     * structures, and can't reinitialize those structures until after we've 
-     * dealt with their contents.
-     *
-     * So, we need to find all of the commands which were running, stick
-     * them on a linked list of completed commands (we'll use the host_scribble
-     * pointer), do our reinitialization, and then call the done function for
-     * each command.  
-     */
-    Scsi_Cmnd *nuke_list = NULL;
-    struct Scsi_Host *host = cmd->device->host;
-    struct NCR53c7x0_hostdata *hostdata = 
-       (struct NCR53c7x0_hostdata *) host->hostdata[0];
-
-    NCR53c7x0_local_setup(host);
-    local_irq_save(flags);
-    ncr_halt (host);
-    print_lots (host);
-    dump_events (host, 30);
-    ncr_scsi_reset (host);
-    for (tmp = nuke_list = return_outstanding_commands (host, 1 /* free */,
-       0 /* issue */ ); tmp; tmp = (Scsi_Cmnd *) tmp->SCp.buffer)
-       if (tmp == cmd) {
-           found = 1;
-           break;
-       }
-           
-    /* 
-     * If we didn't find the command which caused this reset in our running
-     * list, then we've lost it.  See that it terminates normally anyway.
-     */
-    if (!found) {
-       c = (struct NCR53c7x0_cmd *) cmd->host_scribble;
-       if (c) {
-           cmd->host_scribble = NULL;
-           c->next = hostdata->free;
-           hostdata->free = c;
-       } else
-           printk ("scsi%d: lost command %ld\n", host->host_no, cmd->pid);
-       cmd->SCp.buffer = (struct scatterlist *) nuke_list;
-       nuke_list = cmd;
-    }
-
-    NCR53c7x0_driver_init (host);
-    hostdata->soft_reset (host);
-    if (hostdata->resets == 0) 
-       disable(host);
-    else if (hostdata->resets != -1)
-       --hostdata->resets;
-    local_irq_restore(flags);
-    for (; nuke_list; nuke_list = tmp) {
-       tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
-       nuke_list->result = DID_RESET << 16;
-       nuke_list->scsi_done (nuke_list);
-    }
-    local_irq_restore(flags);
-    return SCSI_RESET_SUCCESS;
-}
-
-/*
- * The NCR SDMS bios follows Annex A of the SCSI-CAM draft, and 
- * therefore shares the scsicam_bios_param function.
- */
-
-/*
- * Function : int insn_to_offset (Scsi_Cmnd *cmd, u32 *insn)
- *
- * Purpose : convert instructions stored at NCR pointer into data 
- *     pointer offset.
- * 
- * Inputs : cmd - SCSI command; insn - pointer to instruction.  Either current
- *     DSP, or saved data pointer.
- *
- * Returns : offset on success, -1 on failure.
- */
-
-
-static int 
-insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
-    struct NCR53c7x0_hostdata *hostdata = 
-       (struct NCR53c7x0_hostdata *) cmd->device->host->hostdata[0];
-    struct NCR53c7x0_cmd *ncmd = 
-       (struct NCR53c7x0_cmd *) cmd->host_scribble;
-    int offset = 0, buffers;
-    struct scatterlist *segment;
-    char *ptr;
-    int found = 0;
-
-/*
- * With the current code implementation, if the insn is inside dynamically 
- * generated code, the data pointer will be the instruction preceding 
- * the next transfer segment.
- */
-
-    if (!check_address ((unsigned long) ncmd, sizeof (struct NCR53c7x0_cmd)) &&
-       ((insn >= ncmd->data_transfer_start &&  
-           insn < ncmd->data_transfer_end) ||
-       (insn >= ncmd->residual &&
-           insn < (ncmd->residual + 
-               sizeof(ncmd->residual))))) {
-           ptr = bus_to_virt(insn[3]);
-
-           if ((buffers = cmd->use_sg)) {
-               for (offset = 0, 
-                       segment = (struct scatterlist *) cmd->request_buffer;
-                    buffers && !((found = ((ptr >= (char *)page_address(segment->page)+segment->offset) && 
-                           (ptr < ((char *)page_address(segment->page)+segment->offset+segment->length)))));
-                    --buffers, offset += segment->length, ++segment)
-#if 0
-                   printk("scsi%d: comparing 0x%p to 0x%p\n", 
-                       cmd->device->host->host_no, saved, page_address(segment->page+segment->offset));
-#else
-                   ;
-#endif
-                   offset += ptr - ((char *)page_address(segment->page)+segment->offset);
-           } else {
-               found = 1;
-               offset = ptr - (char *) (cmd->request_buffer);
-           }
-    } else if ((insn >= hostdata->script + 
-               hostdata->E_data_transfer / sizeof(u32)) &&
-              (insn <= hostdata->script +
-               hostdata->E_end_data_transfer / sizeof(u32))) {
-       found = 1;
-       offset = 0;
-    }
-    return found ? offset : -1;
-}
-
-
-
-/*
- * Function : void print_progress (Scsi_Cmnd *cmd) 
- * 
- * Purpose : print the current location of the saved data pointer
- *
- * Inputs : cmd - command we are interested in
- *
- */
-
-static void 
-print_progress (Scsi_Cmnd *cmd) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_cmd *ncmd = 
-       (struct NCR53c7x0_cmd *) cmd->host_scribble;
-    int offset, i;
-    char *where;
-    u32 *ptr;
-    NCR53c7x0_local_setup (cmd->device->host);
-
-    if (check_address ((unsigned long) ncmd,sizeof (struct NCR53c7x0_cmd)) == 0)
-    {
-       printk("\nNCR53c7x0_cmd fields:\n");
-       printk("  bounce.len=0x%x, addr=0x%0x, buf[]=0x%02x %02x %02x %02x\n",
-           ncmd->bounce.len, ncmd->bounce.addr, ncmd->bounce.buf[0],
-           ncmd->bounce.buf[1], ncmd->bounce.buf[2], ncmd->bounce.buf[3]);
-       printk("  result=%04x, cdb[0]=0x%02x\n", ncmd->result, ncmd->cmnd[0]);
-    }
-
-    for (i = 0; i < 2; ++i) {
-       if (check_address ((unsigned long) ncmd, 
-           sizeof (struct NCR53c7x0_cmd)) == -1) 
-           continue;
-       if (!i) {
-           where = "saved";
-           ptr = bus_to_virt(ncmd->saved_data_pointer);
-       } else {
-           where = "active";
-           ptr = bus_to_virt (NCR53c7x0_read32 (DSP_REG) -
-               NCR53c7x0_insn_size (NCR53c7x0_read8 (DCMD_REG)) *
-               sizeof(u32));
-       } 
-       offset = insn_to_offset (cmd, ptr);
-
-       if (offset != -1) 
-           printk ("scsi%d : %s data pointer at offset %d\n",
-               cmd->device->host->host_no, where, offset);
-       else {
-           int size;
-           printk ("scsi%d : can't determine %s data pointer offset\n",
-               cmd->device->host->host_no, where);
-           if (ncmd) {
-               size = print_insn (cmd->device->host,
-                   bus_to_virt(ncmd->saved_data_pointer), "", 1);
-               print_insn (cmd->device->host,
-                   bus_to_virt(ncmd->saved_data_pointer) + size * sizeof(u32),
-                   "", 1);
-           }
-       }
-    }
-}
-
-
-static void 
-print_dsa (struct Scsi_Host *host, u32 *dsa, const char *prefix) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    int i, len;
-    char *ptr;
-    Scsi_Cmnd *cmd;
-
-    if (check_address ((unsigned long) dsa, hostdata->dsa_end - 
-       hostdata->dsa_start) == -1) {
-       printk("scsi%d : bad dsa virt 0x%p\n", host->host_no, dsa);
-       return;
-    }
-    printk("%sscsi%d : dsa at phys 0x%lx (virt 0x%p)\n"
-           "        + %d : dsa_msgout length = %u, data = 0x%x (virt 0x%p)\n" ,
-           prefix ? prefix : "",
-           host->host_no,  virt_to_bus (dsa), dsa, hostdata->dsa_msgout,
-           dsa[hostdata->dsa_msgout / sizeof(u32)],
-           dsa[hostdata->dsa_msgout / sizeof(u32) + 1],
-           bus_to_virt (dsa[hostdata->dsa_msgout / sizeof(u32) + 1]));
-
-    /* 
-     * Only print messages if they're sane in length so we don't
-     * blow the kernel printk buffer on something which won't buy us
-     * anything.
-     */
-
-    if (dsa[hostdata->dsa_msgout / sizeof(u32)] < 
-           sizeof (hostdata->free->select)) 
-       for (i = dsa[hostdata->dsa_msgout / sizeof(u32)],
-           ptr = bus_to_virt (dsa[hostdata->dsa_msgout / sizeof(u32) + 1]); 
-           i > 0 && !check_address ((unsigned long) ptr, 1);
-           ptr += len, i -= len) {
-           printk("               ");
-           len = spi_print_msg(ptr);
-           printk("\n");
-           if (!len)
-               break;
-       }
-
-    printk("        + %d : select_indirect = 0x%x\n",
-       hostdata->dsa_select, dsa[hostdata->dsa_select / sizeof(u32)]);
-    cmd = (Scsi_Cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
-    printk("        + %d : dsa_cmnd = 0x%x ", hostdata->dsa_cmnd,
-          (u32) virt_to_bus(cmd));
-    /* XXX Maybe we should access cmd->host_scribble->result here. RGH */
-    if (cmd) {
-       printk("               result = 0x%x, target = %d, lun = %d, cmd = ",
-           cmd->result, cmd->device->id, cmd->device->lun);
-       __scsi_print_command(cmd->cmnd);
-    } else
-       printk("\n");
-    printk("        + %d : dsa_next = 0x%x\n", hostdata->dsa_next,
-       dsa[hostdata->dsa_next / sizeof(u32)]);
-    if (cmd) { 
-       printk("scsi%d target %d : sxfer_sanity = 0x%x, scntl3_sanity = 0x%x\n"
-              "                   script : ",
-           host->host_no, cmd->device->id,
-           hostdata->sync[cmd->device->id].sxfer_sanity,
-           hostdata->sync[cmd->device->id].scntl3_sanity);
-       for (i = 0; i < (sizeof(hostdata->sync[cmd->device->id].script) / 4); ++i)
-           printk ("0x%x ", hostdata->sync[cmd->device->id].script[i]);
-       printk ("\n");
-       print_progress (cmd);
-    }
-}
-/*
- * Function : void print_queues (Scsi_Host *host) 
- * 
- * Purpose : print the contents of the NCR issue and reconnect queues
- *
- * Inputs : host - SCSI host we are interested in
- *
- */
-
-static void 
-print_queues (struct Scsi_Host *host) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    u32 *dsa, *next_dsa;
-    volatile u32 *ncrcurrent;
-    int left;
-    Scsi_Cmnd *cmd, *next_cmd;
-    unsigned long flags;
-
-    printk ("scsi%d : issue queue\n", host->host_no);
-
-    for (left = host->can_queue, cmd = (Scsi_Cmnd *) hostdata->issue_queue; 
-           left >= 0 && cmd; 
-           cmd = next_cmd) {
-       next_cmd = (Scsi_Cmnd *) cmd->SCp.ptr;
-       local_irq_save(flags);
-       if (cmd->host_scribble) {
-           if (check_address ((unsigned long) (cmd->host_scribble), 
-               sizeof (cmd->host_scribble)) == -1)
-               printk ("scsi%d: scsi pid %ld bad pointer to NCR53c7x0_cmd\n",
-                   host->host_no, cmd->pid);
-           /* print_dsa does sanity check on address, no need to check */
-           else
-               print_dsa (host, ((struct NCR53c7x0_cmd *) cmd->host_scribble)
-                   -> dsa, "");
-       } else 
-           printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n",
-               host->host_no, cmd->pid, cmd->device->id, cmd->device->lun);
-       local_irq_restore(flags);
-    }
-
-    if (left <= 0) {
-       printk ("scsi%d : loop detected in issue queue\n",
-           host->host_no);
-    }
-
-    /*
-     * Traverse the NCR reconnect and start DSA structures, printing out 
-     * each element until we hit the end or detect a loop.  Currently,
-     * the reconnect structure is a linked list; and the start structure
-     * is an array.  Eventually, the reconnect structure will become a 
-     * list as well, since this simplifies the code.
-     */
-
-    printk ("scsi%d : schedule dsa array :\n", host->host_no);
-    for (left = host->can_queue, ncrcurrent = hostdata->schedule;
-           left > 0; ncrcurrent += 2, --left)
-       if (ncrcurrent[0] != hostdata->NOP_insn) 
-/* FIXME : convert pointer to dsa_begin to pointer to dsa. */
-           print_dsa (host, bus_to_virt (ncrcurrent[1] - 
-               (hostdata->E_dsa_code_begin - 
-               hostdata->E_dsa_code_template)), "");
-    printk ("scsi%d : end schedule dsa array\n", host->host_no);
-    
-    printk ("scsi%d : reconnect_dsa_head :\n", host->host_no);
-           
-    for (left = host->can_queue, 
-       dsa = bus_to_virt (hostdata->reconnect_dsa_head);
-       left >= 0 && dsa; 
-       dsa = next_dsa) {
-       local_irq_save(flags);
-       if (check_address ((unsigned long) dsa, sizeof(dsa)) == -1) {
-           printk ("scsi%d: bad DSA pointer 0x%p", host->host_no,
-               dsa);
-           next_dsa = NULL;
-       }
-       else 
-       {
-           next_dsa = bus_to_virt(dsa[hostdata->dsa_next / sizeof(u32)]);
-           print_dsa (host, dsa, "");
-       }
-       local_irq_restore(flags);
-    }
-    printk ("scsi%d : end reconnect_dsa_head\n", host->host_no);
-    if (left < 0)
-       printk("scsi%d: possible loop in ncr reconnect list\n",
-           host->host_no);
-}
-
-static void
-print_lots (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = 
-       (struct NCR53c7x0_hostdata *) host->hostdata[0];
-    u32 *dsp_next, *dsp, *dsa, dbc_dcmd;
-    unsigned char dcmd, sbcl;
-    int i, size;
-    NCR53c7x0_local_setup(host);
-
-    if ((dsp_next = bus_to_virt(NCR53c7x0_read32 (DSP_REG)))) {
-       dbc_dcmd = NCR53c7x0_read32(DBC_REG);
-       dcmd = (dbc_dcmd & 0xff000000) >> 24;
-       dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
-       dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
-       sbcl = NCR53c7x0_read8 (SBCL_REG);
-           
-       /*
-        * For the 53c710, the following will report value 0 for SCNTL3
-        * and STEST0 - we don't have these registers.
-        */
-       printk ("scsi%d : DCMD|DBC=0x%x, DNAD=0x%x (virt 0x%p)\n"
-               "         DSA=0x%lx (virt 0x%p)\n"
-               "         DSPS=0x%x, TEMP=0x%x (virt 0x%p), DMODE=0x%x\n"
-               "         SXFER=0x%x, SCNTL3=0x%x\n"
-               "         %s%s%sphase=%s, %d bytes in SCSI FIFO\n"
-               "         SCRATCH=0x%x, saved2_dsa=0x%0lx\n",
-           host->host_no, dbc_dcmd, NCR53c7x0_read32(DNAD_REG),
-               bus_to_virt(NCR53c7x0_read32(DNAD_REG)),
-           virt_to_bus(dsa), dsa,
-           NCR53c7x0_read32(DSPS_REG), NCR53c7x0_read32(TEMP_REG), 
-           bus_to_virt (NCR53c7x0_read32(TEMP_REG)),
-           (int) NCR53c7x0_read8(hostdata->dmode),
-           (int) NCR53c7x0_read8(SXFER_REG), 
-           ((hostdata->chip / 100) == 8) ?
-               (int) NCR53c7x0_read8(SCNTL3_REG_800) : 0,
-           (sbcl & SBCL_BSY) ? "BSY " : "",
-           (sbcl & SBCL_SEL) ? "SEL " : "",
-           (sbcl & SBCL_REQ) ? "REQ " : "",
-           sstat2_to_phase(NCR53c7x0_read8 (((hostdata->chip / 100) == 8) ?
-               SSTAT1_REG : SSTAT2_REG)),
-           (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ? 
-               SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT,
-           ((hostdata->chip / 100) == 8) ? NCR53c7x0_read8 (STEST0_REG_800) :
-               NCR53c7x0_read32(SCRATCHA_REG_800),
-           hostdata->saved2_dsa);
-       printk ("scsi%d : DSP 0x%lx (virt 0x%p) ->\n", host->host_no, 
-           virt_to_bus(dsp), dsp);
-       for (i = 6; i > 0; --i, dsp += size)
-           size = print_insn (host, dsp, "", 1);
-       if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON)  {
-           if ((hostdata->chip / 100) == 8)
-               printk ("scsi%d : connected (SDID=0x%x, SSID=0x%x)\n",
-                   host->host_no, NCR53c7x0_read8 (SDID_REG_800),
-                   NCR53c7x0_read8 (SSID_REG_800));
-           else
-               printk ("scsi%d : connected (SDID=0x%x)\n",
-                   host->host_no, NCR53c7x0_read8 (SDID_REG_700));
-           print_dsa (host, dsa, "");
-       }
-
-#if 1
-       print_queues (host);
-#endif
-    }
-}
-
-/*
- * Function : static int shutdown (struct Scsi_Host *host)
- * 
- * Purpose : does a clean (we hope) shutdown of the NCR SCSI 
- *     chip.  Use prior to dumping core, unloading the NCR driver,
- * 
- * Returns : 0 on success
- */
-static int 
-shutdown (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);
-/* Get in a state where we can reset the SCSI bus */
-    ncr_halt (host);
-    ncr_scsi_reset (host);
-    hostdata->soft_reset(host);
-
-    disable (host);
-    local_irq_restore(flags);
-    return 0;
-}
-
-/*
- * Function : void ncr_scsi_reset (struct Scsi_Host *host)
- *
- * Purpose : reset the SCSI bus.
- */
-
-static void 
-ncr_scsi_reset (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    unsigned long flags;
-    NCR53c7x0_local_setup(host);
-    local_irq_save(flags);
-    NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
-    udelay(25);        /* Minimum amount of time to assert RST */
-    NCR53c7x0_write8(SCNTL1_REG, 0);
-    local_irq_restore(flags);
-}
-
-/* 
- * Function : void hard_reset (struct Scsi_Host *host)
- *
- */
-
-static void 
-hard_reset (struct Scsi_Host *host) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    unsigned long flags;
-    local_irq_save(flags);
-    ncr_scsi_reset(host);
-    NCR53c7x0_driver_init (host);
-    if (hostdata->soft_reset)
-       hostdata->soft_reset (host);
-    local_irq_restore(flags);
-}
-
-
-/*
- * Function : Scsi_Cmnd *return_outstanding_commands (struct Scsi_Host *host,
- *     int free, int issue)
- *
- * Purpose : return a linked list (using the SCp.buffer field as next,
- *     so we don't perturb hostdata.  We don't use a field of the 
- *     NCR53c7x0_cmd structure since we may not have allocated one 
- *     for the command causing the reset.) of Scsi_Cmnd structures that 
- *     had propagated below the Linux issue queue level.  If free is set, 
- *     free the NCR53c7x0_cmd structures which are associated with 
- *     the Scsi_Cmnd structures, and clean up any internal 
- *     NCR lists that the commands were on.  If issue is set,
- *     also return commands in the issue queue.
- *
- * Returns : linked list of commands
- *
- * NOTE : the caller should insure that the NCR chip is halted
- *     if the free flag is set. 
- */
-
-static Scsi_Cmnd *
-return_outstanding_commands (struct Scsi_Host *host, int free, int issue) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    struct NCR53c7x0_cmd *c;
-    int i;
-    u32 *ncrcurrent;
-    Scsi_Cmnd *list = NULL, *tmp;
-    for (c = (struct NCR53c7x0_cmd *) hostdata->running_list; c; 
-       c = (struct NCR53c7x0_cmd *) c->next)  {
-       if (c->cmd->SCp.buffer) {
-           printk ("scsi%d : loop detected in running list!\n", host->host_no);
-           break;
-       } else {
-           printk ("Duh? Bad things happening in the NCR driver\n");
-           break;
-       }
-
-       c->cmd->SCp.buffer = (struct scatterlist *) list;
-       list = c->cmd;
-       if (free) {
-           c->next = hostdata->free;
-           hostdata->free = c;
-       }
-    }
-
-    if (free) { 
-       for (i = 0, ncrcurrent = (u32 *) hostdata->schedule; 
-           i < host->can_queue; ++i, ncrcurrent += 2) {
-           ncrcurrent[0] = hostdata->NOP_insn;
-           ncrcurrent[1] = 0xdeadbeef;
-       }
-       hostdata->ncrcurrent = NULL;
-    }
-
-    if (issue) {
-       for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; tmp = tmp->next) {
-           if (tmp->SCp.buffer) {
-               printk ("scsi%d : loop detected in issue queue!\n", 
-                       host->host_no);
-               break;
-           }
-           tmp->SCp.buffer = (struct scatterlist *) list;
-           list = tmp;
-       }
-       if (free)
-           hostdata->issue_queue = NULL;
-               
-    }
-    return list;
-}
-
-/* 
- * Function : static int disable (struct Scsi_Host *host)
- *
- * Purpose : disables the given NCR host, causing all commands
- *     to return a driver error.  Call this so we can unload the
- *     module during development and try again.  Eventually, 
- *     we should be able to find clean workarounds for these
- *     problems.
- *
- * Inputs : host - hostadapter to twiddle
- *
- * Returns : 0 on success.
- */
-
-static int 
-disable (struct Scsi_Host *host) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    unsigned long flags;
-    Scsi_Cmnd *nuke_list, *tmp;
-    local_irq_save(flags);
-    if (hostdata->state != STATE_HALTED)
-       ncr_halt (host);
-    nuke_list = return_outstanding_commands (host, 1 /* free */, 1 /* issue */);
-    hard_reset (host);
-    hostdata->state = STATE_DISABLED;
-    local_irq_restore(flags);
-    printk ("scsi%d : nuking commands\n", host->host_no);
-    for (; nuke_list; nuke_list = tmp) {
-           tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
-           nuke_list->result = DID_ERROR << 16;
-           nuke_list->scsi_done(nuke_list);
-    }
-    printk ("scsi%d : done. \n", host->host_no);
-    printk (KERN_ALERT "scsi%d : disabled.  Unload and reload\n",
-       host->host_no);
-    return 0;
-}
-
-/*
- * Function : static int ncr_halt (struct Scsi_Host *host)
- * 
- * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
- *
- * Inputs : host - SCSI chip to halt
- *
- * Returns : 0 on success
- */
-
-static int 
-ncr_halt (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    unsigned long flags;
-    unsigned char istat, tmp;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    int stage;
-    NCR53c7x0_local_setup(host);
-
-    local_irq_save(flags);
-    /* Stage 0 : eat all interrupts
-       Stage 1 : set ABORT
-       Stage 2 : eat all but abort interrupts
-       Stage 3 : eat all interrupts
-     */
-    for (stage = 0;;) {
-       if (stage == 1) {
-           NCR53c7x0_write8(hostdata->istat, ISTAT_ABRT);
-           ++stage;
-       }
-       istat = NCR53c7x0_read8 (hostdata->istat);
-       if (istat & ISTAT_SIP) {
-           tmp = NCR53c7x0_read8(SSTAT0_REG);
-       } else if (istat & ISTAT_DIP) {
-           tmp = NCR53c7x0_read8(DSTAT_REG);
-           if (stage == 2) {
-               if (tmp & DSTAT_ABRT) {
-                   NCR53c7x0_write8(hostdata->istat, 0);
-                   ++stage;
-               } else {
-                   printk(KERN_ALERT "scsi%d : could not halt NCR chip\n", 
-                       host->host_no);
-                   disable (host);
-               }
-           }
-       }
-       if (!(istat & (ISTAT_SIP|ISTAT_DIP))) {
-           if (stage == 0)
-               ++stage;
-           else if (stage == 3)
-               break;
-       }
-    }
-    hostdata->state = STATE_HALTED;
-    local_irq_restore(flags);
-#if 0
-    print_lots (host);
-#endif
-    return 0;
-}
-
-/* 
- * Function: event_name (int event)
- * 
- * Purpose: map event enum into user-readable strings.
- */
-
-static const char *
-event_name (int event) {
-    switch (event) {
-    case EVENT_NONE:           return "none";
-    case EVENT_ISSUE_QUEUE:    return "to issue queue";
-    case EVENT_START_QUEUE:    return "to start queue";
-    case EVENT_SELECT:         return "selected";
-    case EVENT_DISCONNECT:     return "disconnected";
-    case EVENT_RESELECT:       return "reselected";
-    case EVENT_COMPLETE:       return "completed";
-    case EVENT_IDLE:           return "idle";
-    case EVENT_SELECT_FAILED:  return "select failed";
-    case EVENT_BEFORE_SELECT:  return "before select";
-    case EVENT_RESELECT_FAILED:        return "reselect failed";
-    default:                   return "unknown";
-    }
-}
-
-/*
- * Function : void dump_events (struct Scsi_Host *host, count)
- *
- * Purpose : print last count events which have occurred.
- */ 
-static void
-dump_events (struct Scsi_Host *host, int count) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-       host->hostdata[0];
-    struct NCR53c7x0_event event;
-    int i;
-    unsigned long flags;
-    if (hostdata->events) {
-       if (count > hostdata->event_size)
-           count = hostdata->event_size;
-       for (i = hostdata->event_index; count > 0; 
-           i = (i ? i - 1 : hostdata->event_size -1), --count) {
-/*
- * By copying the event we're currently examining with interrupts
- * disabled, we can do multiple printk(), etc. operations and 
- * still be guaranteed that they're happening on the same 
- * event structure.
- */
-           local_irq_save(flags);
-#if 0
-           event = hostdata->events[i];
-#else
-           memcpy ((void *) &event, (void *) &(hostdata->events[i]),
-               sizeof(event));
-#endif
-
-           local_irq_restore(flags);
-           printk ("scsi%d : %s event %d at %ld secs %ld usecs target %d lun %d\n",
-               host->host_no, event_name (event.event), count,
-               (long) event.time.tv_sec, (long) event.time.tv_usec,
-               event.target, event.lun);
-           if (event.dsa) 
-               printk ("         event for dsa 0x%lx (virt 0x%p)\n", 
-                   virt_to_bus(event.dsa), event.dsa);
-           if (event.pid != -1) {
-               printk ("         event for pid %ld ", event.pid);
-               __scsi_print_command (event.cmnd);
-           }
-       }
-    }
-}
-
-/*
- * Function: check_address
- *
- * Purpose: Check to see if a possibly corrupt pointer will fault the 
- *     kernel.
- *
- * Inputs: addr - address; size - size of area
- *
- * Returns: 0 if area is OK, -1 on error.
- *
- * NOTES: should be implemented in terms of vverify on kernels 
- *     that have it.
- */
-
-static int 
-check_address (unsigned long addr, int size) {
-    return (virt_to_phys((void *)addr) < PAGE_SIZE || virt_to_phys((void *)(addr + size)) > virt_to_phys(high_memory) ?  -1 : 0);
-}
-
-#ifdef MODULE
-int 
-NCR53c7x0_release(struct Scsi_Host *host) {
-    struct NCR53c7x0_hostdata *hostdata = 
-       (struct NCR53c7x0_hostdata *) host->hostdata[0];
-    struct NCR53c7x0_cmd *cmd, *tmp;
-    shutdown (host);
-    if (host->irq != SCSI_IRQ_NONE)
-       {
-           int irq_count;
-           struct Scsi_Host *tmp;
-           for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
-               if (tmp->hostt == the_template && tmp->irq == host->irq)
-                   ++irq_count;
-           if (irq_count == 1)
-               free_irq(host->irq, NULL);
-       }
-    if (host->dma_channel != DMA_NONE)
-       free_dma(host->dma_channel);
-    if (host->io_port)
-       release_region(host->io_port, host->n_io_port);
-    
-    for (cmd = (struct NCR53c7x0_cmd *) hostdata->free; cmd; cmd = tmp, 
-       --hostdata->num_cmds) {
-       tmp = (struct NCR53c7x0_cmd *) cmd->next;
-    /* 
-     * If we're going to loop, try to stop it to get a more accurate
-     * count of the leaked commands.
-     */
-       cmd->next = NULL;
-       if (cmd->free)
-           cmd->free ((void *) cmd->real, cmd->size);
-    }
-    if (hostdata->num_cmds)
-       printk ("scsi%d : leaked %d NCR53c7x0_cmd structures\n",
-           host->host_no, hostdata->num_cmds);
-
-    vfree(hostdata->events);
-
-    /* XXX This assumes default cache mode to be IOMAP_FULL_CACHING, which
-     * XXX may be invalid (CONFIG_060_WRITETHROUGH)
-     */
-    kernel_set_cachemode((void *)hostdata, 8192, IOMAP_FULL_CACHING);
-    free_pages ((u32)hostdata, 1);
-    return 1;
-}
-#endif /* def MODULE */
diff --git a/drivers/scsi/53c7xx.h b/drivers/scsi/53c7xx.h
deleted file mode 100644 (file)
index 218f3b9..0000000
+++ /dev/null
@@ -1,1608 +0,0 @@
-/*
- * 53c710 driver.  Modified from Drew Eckhardts driver
- * for 53c810 by Richard Hirst [richard@sleepie.demon.co.uk]
- *
- * I have left the code for the 53c8xx family in here, because it didn't
- * seem worth removing it.  The possibility of IO_MAPPED chips rather
- * than MEMORY_MAPPED remains, in case someone wants to add support for
- * 53c710 chips on Intel PCs (some older machines have them on the
- * motherboard).
- *
- * NOTE THERE MAY BE PROBLEMS WITH CASTS IN read8 AND Co.
- */
-
-/*
- * NCR 53c{7,8}0x0 driver, header file
- *
- * 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.
- * 
- * PRE-ALPHA
- *
- * For more information, please consult 
- *
- * NCR 53C700/53C700-66
- * SCSI I/O Processor
- * Data Manual
- *
- * NCR 53C810
- * PCI-SCSI I/O Processor 
- * Data Manual
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * +1 (719) 578-3400
- *
- * Toll free literature number
- * +1 (800) 334-5454
- *
- */
-
-#ifndef NCR53c710_H
-#define NCR53c710_H
-
-#ifndef HOSTS_C
-
-/* SCSI control 0 rw, default = 0xc0 */ 
-#define SCNTL0_REG             0x00    
-#define SCNTL0_ARB1            0x80    /* 0 0 = simple arbitration */
-#define SCNTL0_ARB2            0x40    /* 1 1 = full arbitration */
-#define SCNTL0_STRT            0x20    /* Start Sequence */
-#define SCNTL0_WATN            0x10    /* Select with ATN */
-#define SCNTL0_EPC             0x08    /* Enable parity checking */
-/* Bit 2 is reserved on 800 series chips */
-#define SCNTL0_EPG_700         0x04    /* Enable parity generation */
-#define SCNTL0_AAP             0x02    /*  ATN/ on parity error */
-#define SCNTL0_TRG             0x01    /* Target mode */
-
-/* SCSI control 1 rw, default = 0x00 */
-
-#define SCNTL1_REG             0x01    
-#define SCNTL1_EXC             0x80    /* Extra Clock Cycle of Data setup */
-#define SCNTL1_ADB             0x40    /*  contents of SODL on bus */
-#define SCNTL1_ESR_700         0x20    /* Enable SIOP response to selection 
-                                          and reselection */
-#define SCNTL1_DHP_800         0x20    /* Disable halt on parity error or ATN
-                                          target mode only */
-#define SCNTL1_CON             0x10    /* Connected */
-#define SCNTL1_RST             0x08    /* SCSI RST/ */
-#define SCNTL1_AESP            0x04    /* Force bad parity */
-#define SCNTL1_SND_700         0x02    /* Start SCSI send */
-#define SCNTL1_IARB_800                0x02    /* Immediate Arbitration, start
-                                          arbitration immediately after
-                                          busfree is detected */
-#define SCNTL1_RCV_700         0x01    /* Start SCSI receive */
-#define SCNTL1_SST_800         0x01    /* Start SCSI transfer */
-
-/* SCSI control 2 rw, */
-
-#define SCNTL2_REG_800         0x02    
-#define SCNTL2_800_SDU         0x80    /* SCSI disconnect unexpected */
-
-/* SCSI control 3 rw */
-
-#define SCNTL3_REG_800                 0x03    
-#define SCNTL3_800_SCF_SHIFT   4
-#define SCNTL3_800_SCF_MASK    0x70
-#define SCNTL3_800_SCF2                0x40    /* Synchronous divisor */
-#define SCNTL3_800_SCF1                0x20    /* 0x00 = SCLK/3 */
-#define SCNTL3_800_SCF0                0x10    /* 0x10 = SCLK/1 */
-                                       /* 0x20 = SCLK/1.5 
-                                          0x30 = SCLK/2 
-                                          0x40 = SCLK/3 */
-           
-#define SCNTL3_800_CCF_SHIFT   0
-#define SCNTL3_800_CCF_MASK    0x07
-#define SCNTL3_800_CCF2                0x04    /* 0x00 50.01 to 66 */
-#define SCNTL3_800_CCF1                0x02    /* 0x01 16.67 to 25 */
-#define SCNTL3_800_CCF0                0x01    /* 0x02 25.01 - 37.5 
-                                          0x03 37.51 - 50 
-                                          0x04 50.01 - 66 */
-
-/*  
- * SCSI destination ID rw - the appropriate bit is set for the selected
- * target ID.  This is written by the SCSI SCRIPTS processor.
- * default = 0x00
- */
-#define SDID_REG_700           0x02    
-#define SDID_REG_800           0x06
-
-#define GP_REG_800             0x07    /* General purpose IO */
-#define GP_800_IO1             0x02
-#define GP_800_IO2             0x01
-
-/* SCSI interrupt enable rw, default = 0x00 */
-#define SIEN_REG_700           0x03    
-#define SIEN0_REG_800          0x40
-#define SIEN_MA                        0x80    /* Phase mismatch (ini) or ATN (tgt) */
-#define SIEN_FC                        0x40    /* Function complete */
-#define SIEN_700_STO           0x20    /* Selection or reselection timeout */
-#define SIEN_800_SEL           0x20    /* Selected */
-#define SIEN_700_SEL           0x10    /* Selected or reselected */
-#define SIEN_800_RESEL         0x10    /* Reselected */
-#define SIEN_SGE               0x08    /* SCSI gross error */
-#define SIEN_UDC               0x04    /* Unexpected disconnect */
-#define SIEN_RST               0x02    /* SCSI RST/ received */
-#define SIEN_PAR               0x01    /* Parity error */
-
-/* 
- * SCSI chip ID rw
- * NCR53c700 : 
- *     When arbitrating, the highest bit is used, when reselection or selection
- *     occurs, the chip responds to all IDs for which a bit is set.
- *     default = 0x00 
- * NCR53c810 : 
- *     Uses bit mapping
- */
-#define SCID_REG               0x04    
-/* Bit 7 is reserved on 800 series chips */
-#define SCID_800_RRE           0x40    /* Enable response to reselection */
-#define SCID_800_SRE           0x20    /* Enable response to selection */
-/* Bits four and three are reserved on 800 series chips */
-#define SCID_800_ENC_MASK      0x07    /* Encoded SCSI ID */
-
-/* SCSI transfer rw, default = 0x00 */
-#define SXFER_REG              0x05
-#define SXFER_DHP              0x80    /* Disable halt on parity */
-
-#define SXFER_TP2              0x40    /* Transfer period msb */
-#define SXFER_TP1              0x20
-#define SXFER_TP0              0x10    /* lsb */
-#define SXFER_TP_MASK          0x70
-/* FIXME : SXFER_TP_SHIFT == 5 is right for '8xx chips */
-#define SXFER_TP_SHIFT         5
-#define SXFER_TP_4             0x00    /* Divisors */
-#define SXFER_TP_5             0x10<<1
-#define SXFER_TP_6             0x20<<1
-#define SXFER_TP_7             0x30<<1
-#define SXFER_TP_8             0x40<<1
-#define SXFER_TP_9             0x50<<1
-#define SXFER_TP_10            0x60<<1
-#define SXFER_TP_11            0x70<<1
-
-#define SXFER_MO3              0x08    /* Max offset msb */
-#define SXFER_MO2              0x04
-#define SXFER_MO1              0x02
-#define SXFER_MO0              0x01    /* lsb */
-#define SXFER_MO_MASK          0x0f
-#define SXFER_MO_SHIFT         0
-
-/* 
- * SCSI output data latch rw
- * The contents of this register are driven onto the SCSI bus when 
- * the Assert Data Bus bit of the SCNTL1 register is set and 
- * the CD, IO, and MSG bits of the SOCL register match the SCSI phase
- */
-#define SODL_REG_700           0x06    
-#define SODL_REG_800           0x54
-
-
-/* 
- * SCSI output control latch rw, default = 0 
- * Note that when the chip is being manually programmed as an initiator,
- * the MSG, CD, and IO bits must be set correctly for the phase the target
- * is driving the bus in.  Otherwise no data transfer will occur due to 
- * phase mismatch.
- */
-
-#define SOCL_REG               0x07
-#define SOCL_REQ               0x80    /*  REQ */
-#define SOCL_ACK               0x40    /*  ACK */
-#define SOCL_BSY               0x20    /*  BSY */
-#define SOCL_SEL               0x10    /*  SEL */
-#define SOCL_ATN               0x08    /*  ATN */
-#define SOCL_MSG               0x04    /*  MSG */
-#define SOCL_CD                        0x02    /*  C/D */
-#define SOCL_IO                        0x01    /*  I/O */
-
-/* 
- * SCSI first byte received latch ro 
- * This register contains the first byte received during a block MOVE 
- * SCSI SCRIPTS instruction, including
- * 
- * Initiator mode      Target mode
- * Message in          Command
- * Status              Message out
- * Data in             Data out
- *
- * It also contains the selecting or reselecting device's ID and our 
- * ID.
- *
- * Note that this is the register the various IF conditionals can 
- * operate on.
- */
-#define SFBR_REG               0x08    
-
-/* 
- * SCSI input data latch ro
- * In initiator mode, data is latched into this register on the rising
- * edge of REQ/. In target mode, data is latched on the rising edge of 
- * ACK/
- */
-#define SIDL_REG_700           0x09
-#define SIDL_REG_800           0x50
-
-/* 
- * SCSI bus data lines ro 
- * This register reflects the instantaneous status of the SCSI data 
- * lines.  Note that SCNTL0 must be set to disable parity checking, 
- * otherwise reading this register will latch new parity.
- */
-#define SBDL_REG_700           0x0a
-#define SBDL_REG_800           0x58
-
-#define SSID_REG_800           0x0a
-#define SSID_800_VAL           0x80    /* Exactly two bits asserted at sel */
-#define SSID_800_ENCID_MASK    0x07    /* Device which performed operation */
-
-
-/* 
- * SCSI bus control lines rw, 
- * instantaneous readout of control lines 
- */
-#define SBCL_REG               0x0b    
-#define SBCL_REQ               0x80    /*  REQ ro */
-#define SBCL_ACK               0x40    /*  ACK ro */
-#define SBCL_BSY               0x20    /*  BSY ro */
-#define SBCL_SEL               0x10    /*  SEL ro */
-#define SBCL_ATN               0x08    /*  ATN ro */
-#define SBCL_MSG               0x04    /*  MSG ro */
-#define SBCL_CD                        0x02    /*  C/D ro */
-#define SBCL_IO                        0x01    /*  I/O ro */
-#define SBCL_PHASE_CMDOUT      SBCL_CD
-#define SBCL_PHASE_DATAIN      SBCL_IO
-#define SBCL_PHASE_DATAOUT     0
-#define SBCL_PHASE_MSGIN       (SBCL_CD|SBCL_IO|SBCL_MSG)
-#define SBCL_PHASE_MSGOUT      (SBCL_CD|SBCL_MSG)
-#define SBCL_PHASE_STATIN      (SBCL_CD|SBCL_IO)
-#define SBCL_PHASE_MASK                (SBCL_CD|SBCL_IO|SBCL_MSG)
-/* 
- * Synchronous SCSI Clock Control bits 
- * 0 - set by DCNTL 
- * 1 - SCLK / 1.0
- * 2 - SCLK / 1.5
- * 3 - SCLK / 2.0 
- */
-#define SBCL_SSCF1             0x02    /* wo, -66 only */
-#define SBCL_SSCF0             0x01    /* wo, -66 only */
-#define SBCL_SSCF_MASK         0x03
-
-/* 
- * XXX note : when reading the DSTAT and STAT registers to clear interrupts,
- * insure that 10 clocks elapse between the two  
- */
-/* DMA status ro */
-#define DSTAT_REG              0x0c    
-#define DSTAT_DFE              0x80    /* DMA FIFO empty */
-#define DSTAT_800_MDPE         0x40    /* Master Data Parity Error */
-#define DSTAT_800_BF           0x20    /* Bus Fault */
-#define DSTAT_ABRT             0x10    /* Aborted - set on error */
-#define DSTAT_SSI              0x08    /* SCRIPTS single step interrupt */
-#define DSTAT_SIR              0x04    /* SCRIPTS interrupt received - 
-                                          set when INT instruction is 
-                                          executed */
-#define DSTAT_WTD              0x02    /* Watchdog timeout detected */
-#define DSTAT_OPC              0x01    /* Illegal instruction */
-#define DSTAT_800_IID          0x01    /* Same thing, different name */
-
-
-/* NCR53c800 moves this stuff into SIST0 */
-#define SSTAT0_REG             0x0d    /* SCSI status 0 ro */
-#define SIST0_REG_800          0x42    
-#define SSTAT0_MA              0x80    /* ini : phase mismatch,
-                                        * tgt : ATN/ asserted 
-                                        */
-#define SSTAT0_CMP             0x40    /* function complete */
-#define SSTAT0_700_STO         0x20    /* Selection or reselection timeout */
-#define SIST0_800_SEL          0x20    /* Selected */
-#define SSTAT0_700_SEL         0x10    /* Selected or reselected */
-#define SIST0_800_RSL          0x10    /* Reselected */
-#define SSTAT0_SGE             0x08    /* SCSI gross error */
-#define SSTAT0_UDC             0x04    /* Unexpected disconnect */
-#define SSTAT0_RST             0x02    /* SCSI RST/ received */
-#define SSTAT0_PAR             0x01    /* Parity error */
-
-/* And uses SSTAT0 for what was SSTAT1 */
-
-#define SSTAT1_REG             0x0e    /* SCSI status 1 ro */
-#define SSTAT1_ILF             0x80    /* SIDL full */
-#define SSTAT1_ORF             0x40    /* SODR full */
-#define SSTAT1_OLF             0x20    /* SODL full */
-#define SSTAT1_AIP             0x10    /* Arbitration in progress */
-#define SSTAT1_LOA             0x08    /* Lost arbitration */
-#define SSTAT1_WOA             0x04    /* Won arbitration */
-#define SSTAT1_RST             0x02    /* Instant readout of RST/ */
-#define SSTAT1_SDP             0x01    /* Instant readout of SDP/ */
-
-#define SSTAT2_REG             0x0f    /* SCSI status 2 ro */
-#define SSTAT2_FF3             0x80    /* number of bytes in synchronous */
-#define SSTAT2_FF2             0x40    /* data FIFO */
-#define SSTAT2_FF1             0x20    
-#define SSTAT2_FF0             0x10
-#define SSTAT2_FF_MASK         0xf0
-#define SSTAT2_FF_SHIFT                4
-
-/* 
- * Latched signals, latched on the leading edge of REQ/ for initiators,
- * ACK/ for targets.
- */
-#define SSTAT2_SDP             0x08    /* SDP */
-#define SSTAT2_MSG             0x04    /* MSG */
-#define SSTAT2_CD              0x02    /* C/D */
-#define SSTAT2_IO              0x01    /* I/O */
-#define SSTAT2_PHASE_CMDOUT    SSTAT2_CD
-#define SSTAT2_PHASE_DATAIN    SSTAT2_IO
-#define SSTAT2_PHASE_DATAOUT   0
-#define SSTAT2_PHASE_MSGIN     (SSTAT2_CD|SSTAT2_IO|SSTAT2_MSG)
-#define SSTAT2_PHASE_MSGOUT    (SSTAT2_CD|SSTAT2_MSG)
-#define SSTAT2_PHASE_STATIN    (SSTAT2_CD|SSTAT2_IO)
-#define SSTAT2_PHASE_MASK      (SSTAT2_CD|SSTAT2_IO|SSTAT2_MSG)
-
-
-/* NCR53c700-66 only */
-#define SCRATCHA_REG_00                0x10    /* through  0x13 Scratch A rw */
-/* NCR53c710 and higher */
-#define DSA_REG                        0x10    /* DATA structure address */
-
-#define CTEST0_REG_700         0x14    /* Chip test 0 ro */
-#define CTEST0_REG_800         0x18    /* Chip test 0 rw, general purpose */
-/* 0x80 - 0x04 are reserved */
-#define CTEST0_700_RTRG                0x02    /* Real target mode */
-#define CTEST0_700_DDIR                0x01    /* Data direction, 1 = 
-                                        * SCSI bus to host, 0  =
-                                        * host to SCSI.
-                                        */
-
-#define CTEST1_REG_700         0x15    /* Chip test 1 ro */
-#define CTEST1_REG_800         0x19    /* Chip test 1 ro */
-#define CTEST1_FMT3            0x80    /* Identify which byte lanes are empty */
-#define CTEST1_FMT2            0x40    /* in the DMA FIFO */
-#define CTEST1_FMT1            0x20
-#define CTEST1_FMT0            0x10
-
-#define CTEST1_FFL3            0x08    /* Identify which bytes lanes are full */
-#define CTEST1_FFL2            0x04    /* in the DMA FIFO */
-#define CTEST1_FFL1            0x02
-#define CTEST1_FFL0            0x01
-
-#define CTEST2_REG_700         0x16    /* Chip test 2 ro */
-#define CTEST2_REG_800         0x1a    /* Chip test 2 ro */
-
-#define CTEST2_800_DDIR                0x80    /* 1 = SCSI->host */
-#define CTEST2_800_SIGP                0x40    /* A copy of SIGP in ISTAT.
-                                          Reading this register clears */
-#define CTEST2_800_CIO         0x20    /* Configured as IO */.
-#define CTEST2_800_CM          0x10    /* Configured as memory */
-
-/* 0x80 - 0x40 are reserved on 700 series chips */
-#define CTEST2_700_SOFF                0x20    /* SCSI Offset Compare,
-                                        * As an initiator, this bit is 
-                                        * one when the synchronous offset
-                                        * is zero, as a target this bit 
-                                        * is one when the synchronous 
-                                        * offset is at the maximum
-                                        * defined in SXFER
-                                        */
-#define CTEST2_700_SFP         0x10    /* SCSI FIFO parity bit,
-                                        * reading CTEST3 unloads a byte
-                                        * from the FIFO and sets this
-                                        */
-#define CTEST2_700_DFP         0x08    /* DMA FIFO parity bit,
-                                        * reading CTEST6 unloads a byte
-                                        * from the FIFO and sets this
-                                        */
-#define CTEST2_TEOP            0x04    /* SCSI true end of process,
-                                        * indicates a totally finished
-                                        * transfer
-                                        */
-#define CTEST2_DREQ            0x02    /* Data request signal */
-/* 0x01 is reserved on 700 series chips */
-#define CTEST2_800_DACK                0x01    
-
-/* 
- * Chip test 3 ro 
- * Unloads the bottom byte of the eight deep SCSI synchronous FIFO,
- * check SSTAT2 FIFO full bits to determine size.  Note that a GROSS
- * error results if a read is attempted on this register.  Also note 
- * that 16 and 32 bit reads of this register will cause corruption.
- */
-#define CTEST3_REG_700         0x17    
-/*  Chip test 3 rw */
-#define CTEST3_REG_800         0x1b
-#define CTEST3_800_V3          0x80    /* Chip revision */
-#define CTEST3_800_V2          0x40
-#define CTEST3_800_V1          0x20
-#define CTEST3_800_V0          0x10
-#define CTEST3_800_FLF         0x08    /* Flush DMA FIFO */
-#define CTEST3_800_CLF         0x04    /* Clear DMA FIFO */
-#define CTEST3_800_FM          0x02    /* Fetch mode pin */
-/* bit 0 is reserved on 800 series chips */
-
-#define CTEST4_REG_700         0x18    /* Chip test 4 rw */
-#define CTEST4_REG_800         0x21    /* Chip test 4 rw */
-/* 0x80 is reserved on 700 series chips */
-#define CTEST4_800_BDIS                0x80    /* Burst mode disable */
-#define CTEST4_ZMOD            0x40    /* High impedance mode */
-#define CTEST4_SZM             0x20    /* SCSI bus high impedance */
-#define CTEST4_700_SLBE                0x10    /* SCSI loopback enabled */
-#define CTEST4_800_SRTM                0x10    /* Shadow Register Test Mode */
-#define CTEST4_700_SFWR                0x08    /* SCSI FIFO write enable, 
-                                        * redirects writes from SODL
-                                        * to the SCSI FIFO.
-                                        */
-#define CTEST4_800_MPEE                0x08    /* Enable parity checking
-                                          during master cycles on PCI
-                                          bus */
-
-/* 
- * These bits send the contents of the CTEST6 register to the appropriate
- * byte lane of the 32 bit DMA FIFO.  Normal operation is zero, otherwise 
- * the high bit means the low two bits select the byte lane.
- */
-#define CTEST4_FBL2            0x04    
-#define CTEST4_FBL1            0x02
-#define CTEST4_FBL0            0x01    
-#define CTEST4_FBL_MASK                0x07
-#define CTEST4_FBL_0           0x04    /* Select DMA FIFO byte lane 0 */
-#define CTEST4_FBL_1           0x05    /* Select DMA FIFO byte lane 1 */
-#define CTEST4_FBL_2           0x06    /* Select DMA FIFO byte lane 2 */
-#define CTEST4_FBL_3           0x07    /* Select DMA FIFO byte lane 3 */
-#define CTEST4_800_SAVE                (CTEST4_800_BDIS)
-
-
-#define CTEST5_REG_700         0x19    /* Chip test 5 rw */
-#define CTEST5_REG_800         0x22    /* Chip test 5 rw */
-/* 
- * Clock Address Incrementor.  When set, it increments the 
- * DNAD register to the next bus size boundary.  It automatically 
- * resets itself when the operation is complete.
- */
-#define CTEST5_ADCK            0x80
-/*
- * Clock Byte Counter.  When set, it decrements the DBC register to
- * the next bus size boundary.
- */
-#define CTEST5_BBCK            0x40
-/*
- * Reset SCSI Offset.  Setting this bit to 1 clears the current offset
- * pointer in the SCSI synchronous offset counter (SSTAT).  This bit
- * is set to 1 if a SCSI Gross Error Condition occurs.  The offset should
- * be cleared when a synchronous transfer fails.  When written, it is 
- * automatically cleared after the SCSI synchronous offset counter is 
- * reset.
- */
-/* Bit 5 is reserved on 800 series chips */
-#define CTEST5_700_ROFF                0x20
-/* 
- * Master Control for Set or Reset pulses. When 1, causes the low 
- * four bits of register to set when set, 0 causes the low bits to
- * clear when set.
- */
-#define CTEST5_MASR            0x10    
-#define CTEST5_DDIR            0x08    /* DMA direction */
-/*
- * Bits 2-0 are reserved on 800 series chips
- */
-#define CTEST5_700_EOP         0x04    /* End of process */
-#define CTEST5_700_DREQ                0x02    /* Data request */
-#define CTEST5_700_DACK                0x01    /* Data acknowledge */
-
-/* 
- * Chip test 6 rw - writing to this register writes to the byte 
- * lane in the DMA FIFO as determined by the FBL bits in the CTEST4
- * register.
- */
-#define CTEST6_REG_700         0x1a
-#define CTEST6_REG_800         0x23
-
-#define CTEST7_REG             0x1b    /* Chip test 7 rw */
-/* 0x80 - 0x40 are reserved on NCR53c700 and NCR53c700-66 chips */
-#define CTEST7_10_CDIS         0x80    /* Cache burst disable */
-#define CTEST7_10_SC1          0x40    /* Snoop control bits */
-#define CTEST7_10_SC0          0x20    
-#define CTEST7_10_SC_MASK      0x60
-/* 0x20 is reserved on the NCR53c700 */
-#define CTEST7_0060_FM         0x20    /* Fetch mode */
-#define CTEST7_STD             0x10    /* Selection timeout disable */
-#define CTEST7_DFP             0x08    /* DMA FIFO parity bit for CTEST6 */
-#define CTEST7_EVP             0x04    /* 1 = host bus even parity, 0 = odd */
-#define CTEST7_10_TT1          0x02    /* Transfer type */
-#define CTEST7_00_DC           0x02    /* Set to drive DC low during instruction 
-                                          fetch */
-#define CTEST7_DIFF            0x01    /* Differential mode */
-
-#define CTEST7_SAVE ( CTEST7_EVP | CTEST7_DIFF )
-
-
-#define TEMP_REG               0x1c    /* through 0x1f Temporary stack rw */
-
-#define DFIFO_REG              0x20    /* DMA FIFO rw */
-/* 
- * 0x80 is reserved on the NCR53c710, the CLF and FLF bits have been
- * moved into the CTEST8 register.
- */
-#define DFIFO_00_FLF           0x80    /* Flush DMA FIFO to memory */
-#define DFIFO_00_CLF           0x40    /* Clear DMA and SCSI FIFOs */
-#define DFIFO_BO6              0x40
-#define DFIFO_BO5              0x20
-#define DFIFO_BO4              0x10
-#define DFIFO_BO3              0x08
-#define DFIFO_BO2              0x04 
-#define DFIFO_BO1              0x02
-#define DFIFO_BO0              0x01
-#define DFIFO_10_BO_MASK       0x7f    /* 7 bit counter */
-#define DFIFO_00_BO_MASK       0x3f    /* 6 bit counter */
-
-/* 
- * Interrupt status rw 
- * Note that this is the only register which can be read while SCSI
- * SCRIPTS are being executed.
- */
-#define ISTAT_REG_700          0x21
-#define ISTAT_REG_800          0x14
-#define ISTAT_ABRT             0x80    /* Software abort, write 
-                                        *1 to abort, wait for interrupt. */
-/* 0x40 and 0x20 are reserved on NCR53c700 and NCR53c700-66 chips */
-#define ISTAT_10_SRST          0x40    /* software reset */
-#define ISTAT_10_SIGP          0x20    /* signal script */
-/* 0x10 is reserved on NCR53c700 series chips */
-#define ISTAT_800_SEM          0x10    /* semaphore */
-#define ISTAT_CON              0x08    /* 1 when connected */
-#define ISTAT_800_INTF         0x04    /* Interrupt on the fly */
-#define ISTAT_700_PRE          0x04    /* Pointer register empty.
-                                        * Set to 1 when DSPS and DSP
-                                        * registers are empty in pipeline
-                                        * mode, always set otherwise.
-                                        */
-#define ISTAT_SIP              0x02    /* SCSI interrupt pending from
-                                        * SCSI portion of SIOP see
-                                        * SSTAT0
-                                        */
-#define ISTAT_DIP              0x01    /* DMA interrupt pending 
-                                        * see DSTAT
-                                        */
-
-/* NCR53c700-66 and NCR53c710 only */
-#define CTEST8_REG             0x22    /* Chip test 8 rw */
-#define CTEST8_0066_EAS                0x80    /* Enable alternate SCSI clock,
-                                        * ie read from SCLK/ rather than CLK/
-                                        */
-#define CTEST8_0066_EFM                0x40    /* Enable fetch and master outputs */
-#define CTEST8_0066_GRP                0x20    /* Generate Receive Parity for 
-                                        * pass through.  This insures that 
-                                        * bad parity won't reach the host 
-                                        * bus.
-                                        */
-#define CTEST8_0066_TE         0x10    /* TolerANT enable.  Enable 
-                                        * active negation, should only
-                                        * be used for slow SCSI 
-                                        * non-differential.
-                                        */
-#define CTEST8_0066_HSC                0x08    /* Halt SCSI clock */
-#define CTEST8_0066_SRA                0x04    /* Shorten REQ/ACK filtering,
-                                        * must be set for fast SCSI-II
-                                        * speeds.
-                                        */
-#define CTEST8_0066_DAS                0x02    /* Disable automatic target/initiator
-                                        * switching.
-                                        */
-#define CTEST8_0066_LDE                0x01    /* Last disconnect enable.
-                                        * The status of pending 
-                                        * disconnect is maintained by
-                                        * the core, eliminating
-                                        * the possibility of missing a 
-                                        * selection or reselection
-                                        * while waiting to fetch a 
-                                        * WAIT DISCONNECT opcode.
-                                        */
-
-#define CTEST8_10_V3           0x80    /* Chip revision */
-#define CTEST8_10_V2           0x40
-#define CTEST8_10_V1           0x20    
-#define CTEST8_10_V0           0x10
-#define CTEST8_10_V_MASK       0xf0    
-#define CTEST8_10_FLF          0x08    /* Flush FIFOs */
-#define CTEST8_10_CLF          0x04    /* Clear FIFOs */
-#define CTEST8_10_FM           0x02    /* Fetch pin mode */
-#define CTEST8_10_SM           0x01    /* Snoop pin mode */
-
-
-/* 
- * The CTEST9 register may be used to differentiate between a
- * NCR53c700 and a NCR53c710.  
- *
- * Write 0xff to this register.
- * Read it.
- * If the contents are 0xff, it is a NCR53c700
- * If the contents are 0x00, it is a NCR53c700-66 first revision
- * If the contents are some other value, it is some other NCR53c700-66
- */
-#define CTEST9_REG_00          0x23    /* Chip test 9 ro */
-#define LCRC_REG_10            0x23    
-
-/*
- * 0x24 through 0x27 are the DMA byte counter register.  Instructions
- * write their high 8 bits into the DCMD register, the low 24 bits into
- * the DBC register.
- *
- * Function is dependent on the command type being executed.
- */
-
-#define DBC_REG                        0x24
-/* 
- * For Block Move Instructions, DBC is a 24 bit quantity representing 
- *     the number of bytes to transfer.
- * For Transfer Control Instructions, DBC is bit fielded as follows : 
- */
-/* Bits 20 - 23 should be clear */
-#define DBC_TCI_TRUE           (1 << 19)       /* Jump when true */
-#define DBC_TCI_COMPARE_DATA   (1 << 18)       /* Compare data */
-#define DBC_TCI_COMPARE_PHASE  (1 << 17)       /* Compare phase with DCMD field */
-#define DBC_TCI_WAIT_FOR_VALID (1 << 16)       /* Wait for REQ */
-/* Bits 8 - 15 are reserved on some implementations ? */
-#define DBC_TCI_MASK_MASK      0xff00          /* Mask for data compare */
-#define DBC_TCI_MASK_SHIFT     8
-#define DBC_TCI_DATA_MASK      0xff            /* Data to be compared */ 
-#define DBC_TCI_DATA_SHIFT     0
-
-#define DBC_RWRI_IMMEDIATE_MASK        0xff00          /* Immediate data */
-#define DBC_RWRI_IMMEDIATE_SHIFT 8             /* Amount to shift */
-#define DBC_RWRI_ADDRESS_MASK  0x3f0000        /* Register address */
-#define DBC_RWRI_ADDRESS_SHIFT         16
-
-
-/*
- * DMA command r/w
- */
-#define DCMD_REG               0x27    
-#define DCMD_TYPE_MASK         0xc0    /* Masks off type */
-#define DCMD_TYPE_BMI          0x00    /* Indicates a Block Move instruction */
-#define DCMD_BMI_IO            0x01    /* I/O, CD, and MSG bits selecting   */
-#define DCMD_BMI_CD            0x02    /* the phase for the block MOVE      */
-#define DCMD_BMI_MSG           0x04    /* instruction                       */
-
-#define DCMD_BMI_OP_MASK       0x18    /* mask for opcode */
-#define DCMD_BMI_OP_MOVE_T     0x00    /* MOVE */
-#define DCMD_BMI_OP_MOVE_I     0x08    /* MOVE Initiator */
-
-#define DCMD_BMI_INDIRECT      0x20    /*  Indirect addressing */
-
-#define DCMD_TYPE_TCI          0x80    /* Indicates a Transfer Control 
-                                          instruction */
-#define DCMD_TCI_IO            0x01    /* I/O, CD, and MSG bits selecting   */
-#define DCMD_TCI_CD            0x02    /* the phase for the block MOVE      */
-#define DCMD_TCI_MSG           0x04    /* instruction                       */
-#define DCMD_TCI_OP_MASK       0x38    /* mask for opcode */
-#define DCMD_TCI_OP_JUMP       0x00    /* JUMP */
-#define DCMD_TCI_OP_CALL       0x08    /* CALL */
-#define DCMD_TCI_OP_RETURN     0x10    /* RETURN */
-#define DCMD_TCI_OP_INT                0x18    /* INT */
-
-#define DCMD_TYPE_RWRI         0x40    /* Indicates I/O or register Read/Write
-                                          instruction */
-#define DCMD_RWRI_OPC_MASK     0x38    /* Opcode mask */
-#define DCMD_RWRI_OPC_WRITE    0x28    /* Write SFBR to register */
-#define DCMD_RWRI_OPC_READ     0x30    /* Read register to SFBR */
-#define DCMD_RWRI_OPC_MODIFY   0x38    /* Modify in place */
-
-#define DCMD_RWRI_OP_MASK      0x07
-#define DCMD_RWRI_OP_MOVE      0x00
-#define DCMD_RWRI_OP_SHL       0x01
-#define DCMD_RWRI_OP_OR                0x02
-#define DCMD_RWRI_OP_XOR       0x03
-#define DCMD_RWRI_OP_AND       0x04
-#define DCMD_RWRI_OP_SHR       0x05
-#define DCMD_RWRI_OP_ADD       0x06
-#define DCMD_RWRI_OP_ADDC      0x07
-
-#define DCMD_TYPE_MMI          0xc0    /* Indicates a Memory Move instruction 
-                                          (three words) */
-
-
-#define DNAD_REG               0x28    /* through 0x2b DMA next address for 
-                                          data */
-#define DSP_REG                        0x2c    /* through 0x2f DMA SCRIPTS pointer rw */
-#define DSPS_REG               0x30    /* through 0x33 DMA SCRIPTS pointer 
-                                          save rw */
-#define DMODE_REG_00           0x34    /* DMA mode rw */
-#define DMODE_00_BL1   0x80    /* Burst length bits */
-#define DMODE_00_BL0   0x40
-#define DMODE_BL_MASK  0xc0
-/* Burst lengths (800) */
-#define DMODE_BL_2     0x00    /* 2 transfer */
-#define DMODE_BL_4     0x40    /* 4 transfers */
-#define DMODE_BL_8     0x80    /* 8 transfers */
-#define DMODE_BL_16    0xc0    /* 16 transfers */
-
-#define DMODE_10_BL_1  0x00    /* 1 transfer */
-#define DMODE_10_BL_2  0x40    /* 2 transfers */
-#define DMODE_10_BL_4  0x80    /* 4 transfers */
-#define DMODE_10_BL_8  0xc0    /* 8 transfers */
-#define DMODE_10_FC2   0x20    /* Driven to FC2 pin */
-#define DMODE_10_FC1   0x10    /* Driven to FC1 pin */
-#define DMODE_710_PD   0x08    /* Program/data on FC0 pin */
-#define DMODE_710_UO   0x02    /* User prog. output */
-
-#define DMODE_700_BW16 0x20    /* Host buswidth = 16 */
-#define DMODE_700_286  0x10    /* 286 mode */
-#define DMODE_700_IOM  0x08    /* Transfer to IO port */
-#define DMODE_700_FAM  0x04    /* Fixed address mode */
-#define DMODE_700_PIPE 0x02    /* Pipeline mode disables 
-                                        * automatic fetch / exec 
-                                        */
-#define DMODE_MAN      0x01            /* Manual start mode, 
-                                        * requires a 1 to be written
-                                        * to the start DMA bit in the DCNTL
-                                        * register to run scripts 
-                                        */
-
-#define DMODE_700_SAVE ( DMODE_00_BL_MASK | DMODE_00_BW16 | DMODE_00_286 )
-
-/* NCR53c800 series only */
-#define SCRATCHA_REG_800       0x34    /* through 0x37 Scratch A rw */
-/* NCR53c710 only */
-#define SCRATCHB_REG_10                0x34    /* through 0x37 scratch B rw */
-
-#define DMODE_REG_10           0x38    /* DMA mode rw, NCR53c710 and newer */
-#define DMODE_800_SIOM         0x20    /* Source IO = 1 */
-#define DMODE_800_DIOM         0x10    /* Destination IO = 1 */
-#define DMODE_800_ERL          0x08    /* Enable Read Line */
-
-/* 35-38 are reserved on 700 and 700-66 series chips */
-#define DIEN_REG               0x39    /* DMA interrupt enable rw */
-/* 0x80, 0x40, and 0x20 are reserved on 700-series chips */
-#define DIEN_800_MDPE          0x40    /* Master data parity error */
-#define DIEN_800_BF            0x20    /* BUS fault */
-#define DIEN_700_BF            0x20    /* BUS fault */
-#define DIEN_ABRT              0x10    /* Enable aborted interrupt */
-#define DIEN_SSI               0x08    /* Enable single step interrupt */
-#define DIEN_SIR               0x04    /* Enable SCRIPTS INT command 
-                                        * interrupt
-                                        */
-/* 0x02 is reserved on 800 series chips */
-#define DIEN_700_WTD           0x02    /* Enable watchdog timeout interrupt */
-#define DIEN_700_OPC           0x01    /* Enable illegal instruction 
-                                        * interrupt 
-                                        */
-#define DIEN_800_IID           0x01    /*  Same meaning, different name */ 
-
-/*
- * DMA watchdog timer rw
- * set in 16 CLK input periods.
- */
-#define DWT_REG                        0x3a
-
-/* DMA control rw */
-#define DCNTL_REG              0x3b
-#define DCNTL_700_CF1          0x80    /* Clock divisor bits */
-#define DCNTL_700_CF0          0x40
-#define DCNTL_700_CF_MASK      0xc0
-/* Clock divisors                         Divisor SCLK range (MHZ) */
-#define DCNTL_700_CF_2         0x00    /* 2.0     37.51-50.00 */
-#define DCNTL_700_CF_1_5       0x40    /* 1.5     25.01-37.50 */
-#define DCNTL_700_CF_1         0x80    /* 1.0     16.67-25.00 */
-#define DCNTL_700_CF_3         0xc0    /* 3.0     50.01-66.67 (53c700-66) */
-
-#define DCNTL_700_S16          0x20    /* Load scripts 16 bits at a time */
-#define DCNTL_SSM              0x10    /* Single step mode */
-#define DCNTL_700_LLM          0x08    /* Low level mode, can only be set 
-                                        * after selection */
-#define DCNTL_800_IRQM         0x08    /* Totem pole IRQ pin */
-#define DCNTL_STD              0x04    /* Start DMA / SCRIPTS */
-/* 0x02 is reserved */
-#define DCNTL_00_RST           0x01    /* Software reset, resets everything
-                                        * but 286 mode bit  in DMODE. On the
-                                        * NCR53c710, this bit moved to CTEST8
-                                        */
-#define DCNTL_10_COM           0x01    /* 700 software compatibility mode */
-#define DCNTL_10_EA            0x20    /* Enable Ack - needed for MVME16x */
-
-#define DCNTL_700_SAVE ( DCNTL_CF_MASK | DCNTL_S16)
-
-
-/* NCR53c700-66 only */
-#define SCRATCHB_REG_00                0x3c    /* through 0x3f scratch b rw */
-#define SCRATCHB_REG_800       0x5c    /* through 0x5f scratch b rw */
-/* NCR53c710 only */
-#define ADDER_REG_10           0x3c    /* Adder, NCR53c710 only */
-
-#define SIEN1_REG_800          0x41
-#define SIEN1_800_STO          0x04    /* selection/reselection timeout */
-#define SIEN1_800_GEN          0x02    /* general purpose timer */
-#define SIEN1_800_HTH          0x01    /* handshake to handshake */
-
-#define SIST1_REG_800          0x43
-#define SIST1_800_STO          0x04    /* selection/reselection timeout */
-#define SIST1_800_GEN          0x02    /* general purpose timer */
-#define SIST1_800_HTH          0x01    /* handshake to handshake */
-
-#define SLPAR_REG_800          0x44    /* Parity */
-
-#define MACNTL_REG_800         0x46    /* Memory access control */
-#define MACNTL_800_TYP3                0x80
-#define MACNTL_800_TYP2                0x40
-#define MACNTL_800_TYP1                0x20
-#define MACNTL_800_TYP0                0x10
-#define MACNTL_800_DWR         0x08
-#define MACNTL_800_DRD         0x04
-#define MACNTL_800_PSCPT       0x02
-#define MACNTL_800_SCPTS       0x01
-
-#define GPCNTL_REG_800         0x47    /* General Purpose Pin Control */
-
-/* Timeouts are expressed such that 0=off, 1=100us, doubling after that */
-#define STIME0_REG_800         0x48    /* SCSI Timer Register 0 */
-#define STIME0_800_HTH_MASK    0xf0    /* Handshake to Handshake timeout */
-#define STIME0_800_HTH_SHIFT   4
-#define STIME0_800_SEL_MASK    0x0f    /* Selection timeout */
-#define STIME0_800_SEL_SHIFT   0
-
-#define STIME1_REG_800         0x49
-#define STIME1_800_GEN_MASK    0x0f    /* General purpose timer */
-
-#define RESPID_REG_800         0x4a    /* Response ID, bit fielded.  8
-                                          bits on narrow chips, 16 on WIDE */
-
-#define STEST0_REG_800         0x4c    
-#define STEST0_800_SLT         0x08    /* Selection response logic test */
-#define STEST0_800_ART         0x04    /* Arbitration priority encoder test */
-#define STEST0_800_SOZ         0x02    /* Synchronous offset zero */
-#define STEST0_800_SOM         0x01    /* Synchronous offset maximum */
-
-#define STEST1_REG_800         0x4d
-#define STEST1_800_SCLK                0x80    /* Disable SCSI clock */
-
-#define STEST2_REG_800         0x4e    
-#define STEST2_800_SCE         0x80    /* Enable SOCL/SODL */
-#define STEST2_800_ROF         0x40    /* Reset SCSI sync offset */
-#define STEST2_800_SLB         0x10    /* Enable SCSI loopback mode */
-#define STEST2_800_SZM         0x08    /* SCSI high impedance mode */
-#define STEST2_800_EXT         0x02    /* Extend REQ/ACK filter 30 to 60ns */
-#define STEST2_800_LOW         0x01    /* SCSI low level mode */
-
-#define STEST3_REG_800         0x4f     
-#define STEST3_800_TE          0x80    /* Enable active negation */
-#define STEST3_800_STR         0x40    /* SCSI FIFO test read */
-#define STEST3_800_HSC         0x20    /* Halt SCSI clock */
-#define STEST3_800_DSI         0x10    /* Disable single initiator response */
-#define STEST3_800_TTM         0x04    /* Time test mode */
-#define STEST3_800_CSF         0x02    /* Clear SCSI FIFO */
-#define STEST3_800_STW         0x01    /* SCSI FIFO test write */
-
-#define OPTION_PARITY          0x1     /* Enable parity checking */
-#define OPTION_TAGGED_QUEUE    0x2     /* Enable SCSI-II tagged queuing */
-#define OPTION_700             0x8     /* Always run NCR53c700 scripts */
-#define OPTION_INTFLY          0x10    /* Use INTFLY interrupts */
-#define OPTION_DEBUG_INTR      0x20    /* Debug interrupts */
-#define OPTION_DEBUG_INIT_ONLY 0x40    /* Run initialization code and 
-                                          simple test code, return
-                                          DID_NO_CONNECT if any SCSI
-                                          commands are attempted. */
-#define OPTION_DEBUG_READ_ONLY 0x80    /* Return DID_ERROR if any 
-                                          SCSI write is attempted */
-#define OPTION_DEBUG_TRACE     0x100   /* Animated trace mode, print 
-                                          each address and instruction 
-                                          executed to debug buffer. */
-#define OPTION_DEBUG_SINGLE    0x200   /* stop after executing one 
-                                          instruction */
-#define OPTION_SYNCHRONOUS     0x400   /* Enable sync SCSI.  */
-#define OPTION_MEMORY_MAPPED   0x800   /* NCR registers have valid 
-                                          memory mapping */
-#define OPTION_IO_MAPPED       0x1000  /* NCR registers have valid
-                                            I/O mapping */
-#define OPTION_DEBUG_PROBE_ONLY        0x2000  /* Probe only, don't even init */
-#define OPTION_DEBUG_TESTS_ONLY        0x4000  /* Probe, init, run selected tests */
-#define OPTION_DEBUG_TEST0     0x08000 /* Run test 0 */
-#define OPTION_DEBUG_TEST1     0x10000 /* Run test 1 */
-#define OPTION_DEBUG_TEST2     0x20000 /* Run test 2 */
-#define OPTION_DEBUG_DUMP      0x40000 /* Dump commands */
-#define OPTION_DEBUG_TARGET_LIMIT 0x80000 /* Only talk to target+luns specified */
-#define OPTION_DEBUG_NCOMMANDS_LIMIT 0x100000 /* Limit the number of commands */
-#define OPTION_DEBUG_SCRIPT 0x200000 /* Print when checkpoints are passed */
-#define OPTION_DEBUG_FIXUP 0x400000 /* print fixup values */
-#define OPTION_DEBUG_DSA 0x800000
-#define OPTION_DEBUG_CORRUPTION        0x1000000       /* Detect script corruption */
-#define OPTION_DEBUG_SDTR       0x2000000      /* Debug SDTR problem */
-#define OPTION_DEBUG_MISMATCH  0x4000000       /* Debug phase mismatches */
-#define OPTION_DISCONNECT      0x8000000       /* Allow disconnect */
-#define OPTION_DEBUG_DISCONNECT 0x10000000     
-#define OPTION_ALWAYS_SYNCHRONOUS 0x20000000   /* Negotiate sync. transfers
-                                                  on power up */
-#define OPTION_DEBUG_QUEUES    0x80000000      
-#define OPTION_DEBUG_ALLOCATION 0x100000000LL
-#define OPTION_DEBUG_SYNCHRONOUS 0x200000000LL /* Sanity check SXFER and 
-                                                  SCNTL3 registers */
-#define OPTION_NO_ASYNC        0x400000000LL           /* Don't automagically send
-                                                  SDTR for async transfers when
-                                                  we haven't been told to do
-                                                  a synchronous transfer. */
-#define OPTION_NO_PRINT_RACE 0x800000000LL     /* Don't print message when
-                                                  the reselect/WAIT DISCONNECT
-                                                  race condition hits */
-#if !defined(PERM_OPTIONS)
-#define PERM_OPTIONS 0
-#endif
-                               
-/*
- * Some data which is accessed by the NCR chip must be 4-byte aligned.
- * For some hosts the default is less than that (eg. 68K uses 2-byte).
- * Alignment has only been forced where it is important; also if one
- * 32 bit structure field is aligned then it is assumed that following
- * 32 bit fields are also aligned.  Take care when adding fields
- * which are other than 32 bit.
- */
-
-struct NCR53c7x0_synchronous {
-    u32 select_indirect                        /* Value used for indirect selection */
-       __attribute__ ((aligned (4)));
-    u32 sscf_710;                      /* Used to set SSCF bits for 710 */
-    u32 script[8];                     /* Size ?? Script used when target is 
-                                               reselected */
-    unsigned char synchronous_want[5]; /* Per target desired SDTR */
-/* 
- * Set_synchronous programs these, select_indirect and current settings after
- * int_debug_should show a match.
- */
-    unsigned char sxfer_sanity, scntl3_sanity;
-};
-
-#define CMD_FLAG_SDTR          1       /* Initiating synchronous 
-                                          transfer negotiation */
-#define CMD_FLAG_WDTR          2       /* Initiating wide transfer
-                                          negotiation */
-#define CMD_FLAG_DID_SDTR      4       /* did SDTR */
-#define CMD_FLAG_DID_WDTR      8       /* did WDTR */
-
-struct NCR53c7x0_table_indirect {
-    u32 count;
-    void *address;
-};
-
-enum ncr_event { 
-    EVENT_NONE = 0,
-/* 
- * Order is IMPORTANT, since these must correspond to the event interrupts
- * in 53c7,8xx.scr 
- */
-
-    EVENT_ISSUE_QUEUE = 0x5000000,     /* 0 Command was added to issue queue */
-    EVENT_START_QUEUE,                 /* 1 Command moved to start queue */
-    EVENT_SELECT,                      /* 2 Command completed selection */
-    EVENT_DISCONNECT,                  /* 3 Command disconnected */
-    EVENT_RESELECT,                    /* 4 Command reselected */
-    EVENT_COMPLETE,                    /* 5 Command completed */
-    EVENT_IDLE,                                /* 6 */
-    EVENT_SELECT_FAILED,               /* 7 */
-    EVENT_BEFORE_SELECT,               /* 8 */
-    EVENT_RESELECT_FAILED              /* 9 */
-};
-
-struct NCR53c7x0_event {
-    enum ncr_event event;      /* What type of event */
-    unsigned char target;
-    unsigned char lun;
-    struct timeval time;       
-    u32 *dsa;                  /* What's in the DSA register now (virt) */
-/* 
- * A few things from that SCSI pid so we know what happened after 
- * the Scsi_Cmnd structure in question may have disappeared.
- */
-    unsigned long pid;         /* The SCSI PID which caused this 
-                                  event */
-    unsigned char cmnd[12];
-};
-
-/*
- * Things in the NCR53c7x0_cmd structure are split into two parts :
- *
- * 1.  A fixed portion, for things which are not accessed directly by static NCR
- *     code (ie, are referenced only by the Linux side of the driver,
- *     or only by dynamically generated code).  
- *
- * 2.  The DSA portion, for things which are accessed directly by static NCR
- *     code.
- *
- * This is a little ugly, but it 
- * 1.  Avoids conflicts between the NCR code's picture of the structure, and 
- *     Linux code's idea of what it looks like.
- *
- * 2.  Minimizes the pain in the Linux side of the code needed 
- *     to calculate real dsa locations for things, etc.
- * 
- */
-
-struct NCR53c7x0_cmd {
-    void *real;                                /* Real, unaligned address for
-                                          free function */
-    void (* free)(void *, int);                /* Command to deallocate; NULL
-                                          for structures allocated with
-                                          scsi_register, etc. */
-    Scsi_Cmnd *cmd;                    /* Associated Scsi_Cmnd 
-                                          structure, Scsi_Cmnd points
-                                          at NCR53c7x0_cmd using 
-                                          host_scribble structure */
-
-    int size;                          /* scsi_malloc'd size of this 
-                                          structure */
-
-    int flags;                         /* CMD_* flags */
-
-    unsigned char      cmnd[12];       /* CDB, copied from Scsi_Cmnd */
-    int                result;         /* Copy to Scsi_Cmnd when done */
-
-    struct {                           /* Private non-cached bounce buffer */
-        unsigned char buf[256];
-       u32           addr;
-        u32           len;
-    } bounce;
-
-/*
- * SDTR and WIDE messages are an either/or affair
- * in this message, since we will go into message out and send
- * _the whole mess_ without dropping out of message out to 
- * let the target go into message in after sending the first 
- * message.
- */
-
-    unsigned char select[11];          /* Select message, includes
-                                          IDENTIFY
-                                          (optional) QUEUE TAG
-                                          (optional) SDTR or WDTR
-                                        */
-
-
-    volatile struct NCR53c7x0_cmd *next; /* Linux maintained lists (free,
-                                           running, eventually finished */
-                                        
-
-    u32 *data_transfer_start;          /* Start of data transfer routines */
-    u32 *data_transfer_end;            /* Address after end of data transfer o
-                                          routines */
-/* 
- * The following three fields were moved from the DSA proper to here
- * since only dynamically generated NCR code refers to them, meaning
- * we don't need dsa_* absolutes, and it is simpler to let the 
- * host code refer to them directly.
- */
-
-/* 
- * HARD CODED : residual and saved_residual need to agree with the sizes
- * used in NCR53c7,8xx.scr.  
- * 
- * FIXME: we want to consider the case where we have odd-length 
- *     scatter/gather buffers and a WIDE transfer, in which case 
- *     we'll need to use the CHAIN MOVE instruction.  Ick.
- */
-    u32 residual[6] __attribute__ ((aligned (4)));
-                                       /* Residual data transfer which
-                                          allows pointer code to work
-                                          right.
-
-                                           [0-1] : Conditional call to 
-                                               appropriate other transfer 
-                                               routine.
-                                           [2-3] : Residual block transfer
-                                               instruction.
-                                           [4-5] : Jump to instruction
-                                               after splice.
-                                        */
-    u32 saved_residual[6];             /* Copy of old residual, so we 
-                                          can get another partial 
-                                          transfer and still recover 
-                                        */
-               
-    u32 saved_data_pointer;            /* Saved data pointer */
-
-    u32 dsa_next_addr;                 /* _Address_ of dsa_next field  
-                                          in this dsa for RISCy 
-                                          style constant. */
-
-    u32 dsa_addr;                      /* Address of dsa; RISCy style
-                                          constant */
-
-    u32 dsa[0];                                /* Variable length (depending
-                                          on host type, number of scatter /
-                                          gather buffers, etc).  */
-};
-
-struct NCR53c7x0_break {
-    u32 *address, old_instruction[2];
-    struct NCR53c7x0_break *next;
-    unsigned char old_size;            /* Size of old instruction */
-};
-
-/* Indicates that the NCR is not executing code */
-#define STATE_HALTED   0               
-/* 
- * Indicates that the NCR is executing the wait for select / reselect 
- * script.  Only used when running NCR53c700 compatible scripts, only 
- * state during which an ABORT is _not_ considered an error condition.
- */
-#define STATE_WAITING  1               
-/* Indicates that the NCR is executing other code. */
-#define STATE_RUNNING  2               
-/* 
- * Indicates that the NCR was being aborted.
- */
-#define STATE_ABORTING 3
-/* Indicates that the NCR was successfully aborted. */
-#define STATE_ABORTED 4
-/* Indicates that the NCR has been disabled due to a fatal error */
-#define STATE_DISABLED 5
-
-/* 
- * Where knowledge of SCSI SCRIPT(tm) specified values are needed 
- * in an interrupt handler, an interrupt handler exists for each 
- * different SCSI script so we don't have name space problems.
- * 
- * Return values of these handlers are as follows : 
- */
-#define SPECIFIC_INT_NOTHING   0       /* don't even restart */
-#define SPECIFIC_INT_RESTART   1       /* restart at the next instruction */
-#define SPECIFIC_INT_ABORT     2       /* recoverable error, abort cmd */
-#define SPECIFIC_INT_PANIC     3       /* unrecoverable error, panic */
-#define SPECIFIC_INT_DONE      4       /* normal command completion */
-#define SPECIFIC_INT_BREAK     5       /* break point encountered */
-
-struct NCR53c7x0_hostdata {
-    int size;                          /* Size of entire Scsi_Host
-                                          structure */
-    int board;                         /* set to board type, useful if 
-                                          we have host specific things,
-                                          ie, a general purpose I/O 
-                                          bit is being used to enable
-                                          termination, etc. */
-
-    int chip;                          /* set to chip type; 700-66 is
-                                          700-66, rest are last three
-                                          digits of part number */
-
-    char valid_ids[8];                 /* Valid SCSI ID's for adapter */
-
-    u32 *dsp;                          /* dsp to restart with after
-                                          all stacked interrupts are
-                                          handled. */
-
-    unsigned dsp_changed:1;            /* Has dsp changed within this
-                                          set of stacked interrupts ? */
-
-    unsigned char dstat;               /* Most recent value of dstat */
-    unsigned dstat_valid:1;
-
-    unsigned expecting_iid:1;          /* Expect IID interrupt */
-    unsigned expecting_sto:1;          /* Expect STO interrupt */
-    
-    /* 
-     * The code stays cleaner if we use variables with function
-     * pointers and offsets that are unique for the different
-     * scripts rather than having a slew of switch(hostdata->chip) 
-     * statements.
-     * 
-     * It also means that the #defines from the SCSI SCRIPTS(tm)
-     * don't have to be visible outside of the script-specific
-     * instructions, preventing name space pollution.
-     */
-
-    void (* init_fixup)(struct Scsi_Host *host);
-    void (* init_save_regs)(struct Scsi_Host *host);
-    void (* dsa_fixup)(struct NCR53c7x0_cmd *cmd);
-    void (* soft_reset)(struct Scsi_Host *host);
-    int (* run_tests)(struct Scsi_Host *host);
-
-    /*
-     * Called when DSTAT_SIR is set, indicating an interrupt generated
-     * by the INT instruction, where values are unique for each SCSI
-     * script.  Should return one of the SPEC_* values.
-     */
-
-    int (* dstat_sir_intr)(struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
-
-    int dsa_len; /* Size of DSA structure */
-
-    /*
-     * Location of DSA fields for the SCSI SCRIPT corresponding to this 
-     * chip.  
-     */
-
-    s32 dsa_start;                     
-    s32 dsa_end;                       
-    s32 dsa_next;
-    s32 dsa_prev;
-    s32 dsa_cmnd;
-    s32 dsa_select;
-    s32 dsa_msgout;
-    s32 dsa_cmdout;
-    s32 dsa_dataout;
-    s32 dsa_datain;
-    s32 dsa_msgin;
-    s32 dsa_msgout_other;
-    s32 dsa_write_sync;
-    s32 dsa_write_resume;
-    s32 dsa_check_reselect;
-    s32 dsa_status;
-    s32 dsa_saved_pointer;
-    s32 dsa_jump_dest;
-
-    /* 
-     * Important entry points that generic fixup code needs
-     * to know about, fixed up.
-     */
-
-    s32 E_accept_message;
-    s32 E_command_complete;            
-    s32 E_data_transfer;
-    s32 E_dsa_code_template;
-    s32 E_dsa_code_template_end;
-    s32 E_end_data_transfer;
-    s32 E_msg_in;
-    s32 E_initiator_abort;
-    s32 E_other_transfer;
-    s32 E_other_in;
-    s32 E_other_out;
-    s32 E_target_abort;
-    s32 E_debug_break; 
-    s32 E_reject_message;
-    s32 E_respond_message;
-    s32 E_select;
-    s32 E_select_msgout;
-    s32 E_test_0;
-    s32 E_test_1;
-    s32 E_test_2;
-    s32 E_test_3;
-    s32 E_dsa_zero;
-    s32 E_cmdout_cmdout;
-    s32 E_wait_reselect;
-    s32 E_dsa_code_begin;
-
-    long long options;                 /* Bitfielded set of options enabled */
-    volatile u32 test_completed;       /* Test completed */
-    int test_running;                  /* Test currently running */
-    s32 test_source
-       __attribute__ ((aligned (4)));
-    volatile s32 test_dest;
-
-    volatile int state;                        /* state of driver, only used for 
-                                          OPTION_700 */
-
-    unsigned char  dmode;              /* 
-                                        * set to the address of the DMODE 
-                                        * register for this chip.
-                                        */
-    unsigned char istat;               /* 
-                                        * set to the address of the ISTAT 
-                                        * register for this chip.
-                                        */
-  
-    int scsi_clock;                    /* 
-                                        * SCSI clock in HZ. 0 may be used 
-                                        * for unknown, although this will
-                                        * disable synchronous negotiation.
-                                        */
-
-    volatile int intrs;                        /* Number of interrupts */
-    volatile int resets;               /* Number of SCSI resets */
-    unsigned char saved_dmode; 
-    unsigned char saved_ctest4;
-    unsigned char saved_ctest7;
-    unsigned char saved_dcntl;
-    unsigned char saved_scntl3;
-
-    unsigned char this_id_mask;
-
-    /* Debugger information */
-    struct NCR53c7x0_break *breakpoints, /* Linked list of all break points */
-       *breakpoint_current;            /* Current breakpoint being stepped 
-                                          through, NULL if we are running 
-                                          normally. */
-#ifdef NCR_DEBUG
-    int debug_size;                    /* Size of debug buffer */
-    volatile int debug_count;          /* Current data count */
-    volatile char *debug_buf;          /* Output ring buffer */
-    volatile char *debug_write;                /* Current write pointer */
-    volatile char *debug_read;         /* Current read pointer */
-#endif /* def NCR_DEBUG */
-
-    /* XXX - primitive debugging junk, remove when working ? */
-    int debug_print_limit;             /* Number of commands to print
-                                          out exhaustive debugging
-                                          information for if 
-                                          OPTION_DEBUG_DUMP is set */ 
-
-    unsigned char debug_lun_limit[16]; /* If OPTION_DEBUG_TARGET_LIMIT
-                                          set, puke if commands are sent
-                                          to other target/lun combinations */
-
-    int debug_count_limit;             /* Number of commands to execute
-                                          before puking to limit debugging 
-                                          output */
-                                   
-
-    volatile unsigned idle:1;                  /* set to 1 if idle */
-
-    /* 
-     * Table of synchronous+wide transfer parameters set on a per-target
-     * basis.
-     */
-    
-    volatile struct NCR53c7x0_synchronous sync[16]
-       __attribute__ ((aligned (4)));
-
-    volatile Scsi_Cmnd *issue_queue
-       __attribute__ ((aligned (4)));
-                                               /* waiting to be issued by
-                                                  Linux driver */
-    volatile struct NCR53c7x0_cmd *running_list;       
-                                               /* commands running, maintained
-                                                  by Linux driver */
-
-    volatile struct NCR53c7x0_cmd *ncrcurrent; /* currently connected 
-                                                  nexus, ONLY valid for
-                                                  NCR53c700/NCR53c700-66
-                                                */
-
-    volatile struct NCR53c7x0_cmd *spare;      /* pointer to spare,
-                                                  allocated at probe time,
-                                                  which we can use for 
-                                                  initialization */
-    volatile struct NCR53c7x0_cmd *free;
-    int max_cmd_size;                          /* Maximum size of NCR53c7x0_cmd
-                                                  based on number of 
-                                                  scatter/gather segments, etc.
-                                                  */
-    volatile int num_cmds;                     /* Number of commands 
-                                                  allocated */
-    volatile int extra_allocate;
-    volatile unsigned char cmd_allocated[16];  /* Have we allocated commands
-                                                  for this target yet?  If not,
-                                                  do so ASAP */
-    volatile unsigned char busy[16][8];        /* number of commands 
-                                                  executing on each target
-                                                */
-    /* 
-     * Eventually, I'll switch to a coroutine for calling 
-     * cmd->done(cmd), etc. so that we can overlap interrupt
-     * processing with this code for maximum performance.
-     */
-    
-    volatile struct NCR53c7x0_cmd *finished_queue;     
-                                               
-    /* Shared variables between SCRIPT and host driver */
-    volatile u32 *schedule
-       __attribute__ ((aligned (4)));          /* Array of JUMPs to dsa_begin
-                                                  routines of various DSAs.  
-                                                  When not in use, replace
-                                                  with jump to next slot */
-
-
-    volatile unsigned char msg_buf[16];                /* buffer for messages
-                                                  other than the command
-                                                  complete message */
-
-    /* Per-target default synchronous and WIDE messages */
-    volatile unsigned char synchronous_want[16][5];
-    volatile unsigned char wide_want[16][4];
-
-    /* Bit fielded set of targets we want to speak synchronously with */ 
-    volatile u16 initiate_sdtr;        
-    /* Bit fielded set of targets we want to speak wide with */
-    volatile u16 initiate_wdtr;
-    /* Bit fielded list of targets we've talked to. */
-    volatile u16 talked_to;
-
-    /* Array of bit-fielded lun lists that we need to request_sense */
-    volatile unsigned char request_sense[16];
-
-    u32 addr_reconnect_dsa_head
-       __attribute__ ((aligned (4)));          /* RISCy style constant,
-                                                  address of following */
-    volatile u32 reconnect_dsa_head;   
-    /* Data identifying nexus we are trying to match during reselection */
-    volatile unsigned char reselected_identify; /* IDENTIFY message */
-    volatile unsigned char reselected_tag;     /* second byte of queue tag 
-                                                  message or 0 */
-
-    /* These were static variables before we moved them */
-
-    s32 NCR53c7xx_zero
-       __attribute__ ((aligned (4)));
-    s32 NCR53c7xx_sink;
-    u32 NOP_insn;
-    char NCR53c7xx_msg_reject;
-    char NCR53c7xx_msg_abort;
-    char NCR53c7xx_msg_nop;
-
-    /*
-     * Following item introduced by RGH to support NCRc710, which is
-     * VERY brain-dead when it come to memory moves
-     */
-
-                         /* DSA save area used only by the NCR chip */
-    volatile unsigned long saved2_dsa
-       __attribute__ ((aligned (4)));
-
-    volatile unsigned long emulated_intfly
-       __attribute__ ((aligned (4)));
-
-    volatile int event_size, event_index;
-    volatile struct NCR53c7x0_event *events;
-
-    /* If we need to generate code to kill off the currently connected 
-       command, this is where we do it. Should have a BMI instruction
-       to source or sink the current data, followed by a JUMP
-       to abort_connected */
-
-    u32 *abort_script;
-
-    int script_count;                          /* Size of script in words */
-    u32 script[0];                             /* Relocated SCSI script */
-
-};
-
-#define SCSI_IRQ_NONE  255
-#define DMA_NONE       255
-#define IRQ_AUTO       254
-#define DMA_AUTO       254
-
-#define BOARD_GENERIC  0
-
-#define NCR53c7x0_insn_size(insn)                                      \
-    (((insn) & DCMD_TYPE_MASK) == DCMD_TYPE_MMI ? 3 : 2)
-    
-
-#define NCR53c7x0_local_declare()                                      \
-    volatile unsigned char *NCR53c7x0_address_memory;                  \
-    unsigned int NCR53c7x0_address_io;                                 \
-    int NCR53c7x0_memory_mapped
-
-#define NCR53c7x0_local_setup(host)                                    \
-    NCR53c7x0_address_memory = (void *) (host)->base;                  \
-    NCR53c7x0_address_io = (unsigned int) (host)->io_port;             \
-    NCR53c7x0_memory_mapped = ((struct NCR53c7x0_hostdata *)           \
-       host->hostdata[0])-> options & OPTION_MEMORY_MAPPED 
-
-#ifdef BIG_ENDIAN
-/* These could be more efficient, given that we are always memory mapped,
- * but they don't give the same problems as the write macros, so leave
- * them. */
-#ifdef __mc68000__
-#define NCR53c7x0_read8(address)                                       \
-    ((unsigned int)raw_inb((u32)NCR53c7x0_address_memory + ((u32)(address)^3)) )
-
-#define NCR53c7x0_read16(address)                                      \
-    ((unsigned int)raw_inw((u32)NCR53c7x0_address_memory + ((u32)(address)^2)))
-#else
-#define NCR53c7x0_read8(address)                                       \
-    (NCR53c7x0_memory_mapped ?                                                 \
-       (unsigned int)readb((u32)NCR53c7x0_address_memory + ((u32)(address)^3)) :       \
-       inb(NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_read16(address)                                      \
-    (NCR53c7x0_memory_mapped ?                                                 \
-       (unsigned int)readw((u32)NCR53c7x0_address_memory + ((u32)(address)^2)) :       \
-       inw(NCR53c7x0_address_io + (address)))
-#endif /* mc68000 */
-#else
-#define NCR53c7x0_read8(address)                                       \
-    (NCR53c7x0_memory_mapped ?                                                 \
-       (unsigned int)readb((u32)NCR53c7x0_address_memory + (u32)(address)) :   \
-       inb(NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_read16(address)                                      \
-    (NCR53c7x0_memory_mapped ?                                                 \
-       (unsigned int)readw((u32)NCR53c7x0_address_memory + (u32)(address)) :   \
-       inw(NCR53c7x0_address_io + (address)))
-#endif
-
-#ifdef __mc68000__
-#define NCR53c7x0_read32(address)                                      \
-    ((unsigned int) raw_inl((u32)NCR53c7x0_address_memory + (u32)(address)))
-#else
-#define NCR53c7x0_read32(address)                                      \
-    (NCR53c7x0_memory_mapped ?                                                 \
-       (unsigned int) readl((u32)NCR53c7x0_address_memory + (u32)(address)) :  \
-       inl(NCR53c7x0_address_io + (address)))
-#endif /* mc68000*/
-
-#ifdef BIG_ENDIAN
-/* If we are big-endian, then we are not Intel, so probably don't have
- * an i/o map as well as a memory map.  So, let's assume memory mapped.
- * Also, I am having terrible problems trying to persuade the compiler
- * not to lay down code which does a read after write for these macros.
- * If you remove 'volatile' from writeb() and friends it is ok....
- */
-
-#define NCR53c7x0_write8(address,value)                                \
-       *(volatile unsigned char *)                                     \
-               ((u32)NCR53c7x0_address_memory + ((u32)(address)^3)) = (value)
-
-#define NCR53c7x0_write16(address,value)                               \
-       *(volatile unsigned short *)                                    \
-               ((u32)NCR53c7x0_address_memory + ((u32)(address)^2)) = (value)
-
-#define NCR53c7x0_write32(address,value)                               \
-       *(volatile unsigned long *)                                     \
-               ((u32)NCR53c7x0_address_memory + ((u32)(address))) = (value)
-
-#else
-
-#define NCR53c7x0_write8(address,value)                                \
-    (NCR53c7x0_memory_mapped ?                                                 \
-     ({writeb((value), (u32)NCR53c7x0_address_memory + (u32)(address)); mb();}) :      \
-       outb((value), NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_write16(address,value)                               \
-    (NCR53c7x0_memory_mapped ?                                                 \
-     ({writew((value), (u32)NCR53c7x0_address_memory + (u32)(address)); mb();}) :      \
-       outw((value), NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_write32(address,value)                               \
-    (NCR53c7x0_memory_mapped ?                                                 \
-     ({writel((value), (u32)NCR53c7x0_address_memory + (u32)(address)); mb();}) :      \
-       outl((value), NCR53c7x0_address_io + (address)))
-
-#endif
-
-/* Patch arbitrary 32 bit words in the script */
-#define patch_abs_32(script, offset, symbol, value)                    \
-       for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof            \
-           (u32)); ++i) {                                      \
-           (script)[A_##symbol##_used[i] - (offset)] += (value);       \
-           if (hostdata->options & OPTION_DEBUG_FIXUP)                 \
-             printk("scsi%d : %s reference %d at 0x%x in %s is now 0x%x\n",\
-               host->host_no, #symbol, i, A_##symbol##_used[i] -       \
-               (int)(offset), #script, (script)[A_##symbol##_used[i] - \
-               (offset)]);                                             \
-       }
-
-/* Patch read/write instruction immediate field */
-#define patch_abs_rwri_data(script, offset, symbol, value)             \
-       for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof            \
-           (u32)); ++i)                                        \
-           (script)[A_##symbol##_used[i] - (offset)] =                 \
-               ((script)[A_##symbol##_used[i] - (offset)] &            \
-               ~DBC_RWRI_IMMEDIATE_MASK) |                             \
-               (((value) << DBC_RWRI_IMMEDIATE_SHIFT) &                \
-                DBC_RWRI_IMMEDIATE_MASK)
-
-/* Patch transfer control instruction data field */
-#define patch_abs_tci_data(script, offset, symbol, value)              \
-       for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof            \
-           (u32)); ++i)                                        \
-           (script)[A_##symbol##_used[i] - (offset)] =                 \
-               ((script)[A_##symbol##_used[i] - (offset)] &            \
-               ~DBC_TCI_DATA_MASK) |                                   \
-               (((value) << DBC_TCI_DATA_SHIFT) &                      \
-                DBC_TCI_DATA_MASK)
-
-/* Patch field in dsa structure (assignment should be +=?) */
-#define patch_dsa_32(dsa, symbol, word, value)                         \
-       {                                                               \
-       (dsa)[(hostdata->##symbol - hostdata->dsa_start) / sizeof(u32)  \
-           + (word)] = (value);                                        \
-       if (hostdata->options & OPTION_DEBUG_DSA)                       \
-           printk("scsi : dsa %s symbol %s(%d) word %d now 0x%x\n",    \
-               #dsa, #symbol, hostdata->##symbol,                      \
-               (word), (u32) (value));                                 \
-       }
-
-/* Paranoid people could use panic() here. */
-#define FATAL(host) shutdown((host));
-
-extern 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);
-
-#endif /* NCR53c710_C */
-#endif /* NCR53c710_H */
diff --git a/drivers/scsi/53c7xx.scr b/drivers/scsi/53c7xx.scr
deleted file mode 100644 (file)
index 9c5694a..0000000
+++ /dev/null
@@ -1,1591 +0,0 @@
-#undef DEBUG
-#undef EVENTS
-#undef NO_SELECTION_TIMEOUT
-#define BIG_ENDIAN
-
-; 53c710 driver.  Modified from Drew Eckhardts driver
-; for 53c810 by Richard Hirst [richard@sleepie.demon.co.uk]
-;
-; I have left the script for the 53c8xx family in here, as it is likely
-; to be useful to see what I changed when bug hunting.
-
-; NCR 53c810 driver, main script
-; Sponsored by 
-;      iX Multiuser Multitasking Magazine
-;      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.
-;
-; PRE-ALPHA
-;
-; For more information, please consult 
-;
-; NCR 53C810
-; PCI-SCSI I/O Processor
-; Data Manual
-;
-; NCR 53C710 
-; SCSI I/O Processor
-; Programmers Guide
-;
-; NCR Microelectronics
-; 1635 Aeroplaza Drive
-; Colorado Springs, CO 80916
-; 1+ (719) 578-3400
-;
-; Toll free literature number
-; +1 (800) 334-5454
-;
-; IMPORTANT : This code is self modifying due to the limitations of 
-;      the NCR53c7,8xx series chips.  Persons debugging this code with
-;      the remote debugger should take this into account, and NOT set
-;      breakpoints in modified instructions.
-;
-; Design:
-; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard 
-; microcontroller using a simple instruction set.   
-;
-; So, to minimize the effects of interrupt latency, and to maximize 
-; throughput, this driver offloads the practical maximum amount 
-; of processing to the SCSI chip while still maintaining a common
-; structure.
-;
-; Where tradeoffs were needed between efficiency on the older
-; chips and the newer NCR53c800 series, the NCR53c800 series 
-; was chosen.
-;
-; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully
-; automate SCSI transfers without host processor intervention, this 
-; isn't the case with the NCR53c710 and newer chips which allow 
-;
-; - reads and writes to the internal registers from within the SCSI
-;      scripts, allowing the SCSI SCRIPTS(tm) code to save processor
-;      state so that multiple threads of execution are possible, and also
-;      provide an ALU for loop control, etc.
-; 
-; - table indirect addressing for some instructions. This allows 
-;      pointers to be located relative to the DSA ((Data Structure
-;      Address) register.
-;
-; These features make it possible to implement a mailbox style interface,
-; where the same piece of code is run to handle I/O for multiple threads
-; at once minimizing our need to relocate code.  Since the NCR53c700/
-; NCR53c800 series have a unique combination of features, making a 
-; a standard ingoing/outgoing mailbox system, costly, I've modified it.
-;
-; - Mailboxes are a mixture of code and data.  This lets us greatly
-;      simplify the NCR53c810 code and do things that would otherwise
-;      not be possible.
-;
-; The saved data pointer is now implemented as follows :
-;
-;      Control flow has been architected such that if control reaches
-;      munge_save_data_pointer, on a restore pointers message or 
-;      reconnection, a jump to the address formerly in the TEMP register
-;      will allow the SCSI command to resume execution.
-;
-
-;
-; Note : the DSA structures must be aligned on 32 bit boundaries,
-; since the source and destination of MOVE MEMORY instructions 
-; must share the same alignment and this is the alignment of the
-; NCR registers.
-;
-
-; For some systems (MVME166, for example) dmode is always the same, so don't
-; waste time writing it
-
-#if 1
-#define DMODE_MEMORY_TO_NCR
-#define DMODE_MEMORY_TO_MEMORY
-#define DMODE_NCR_TO_MEMORY
-#else
-#define DMODE_MEMORY_TO_NCR    MOVE dmode_memory_to_ncr TO DMODE
-#define DMODE_MEMORY_TO_MEMORY MOVE dmode_memory_to_memory TO DMODE
-#define DMODE_NCR_TO_MEMORY    MOVE dmode_ncr_to_memory TO DMODE
-#endif
-
-ABSOLUTE dsa_temp_lun = 0              ; Patch to lun for current dsa
-ABSOLUTE dsa_temp_next = 0             ; Patch to dsa next for current dsa
-ABSOLUTE dsa_temp_addr_next = 0                ; Patch to address of dsa next address 
-                                       ;       for current dsa
-ABSOLUTE dsa_temp_sync = 0             ; Patch to address of per-target
-                                       ;       sync routine
-ABSOLUTE dsa_sscf_710 = 0              ; Patch to address of per-target
-                                       ;       sscf value (53c710)
-ABSOLUTE dsa_temp_target = 0           ; Patch to id for current dsa
-ABSOLUTE dsa_temp_addr_saved_pointer = 0; Patch to address of per-command
-                                       ;       saved data pointer
-ABSOLUTE dsa_temp_addr_residual = 0    ; Patch to address of per-command
-                                       ;       current residual code
-ABSOLUTE dsa_temp_addr_saved_residual = 0; Patch to address of per-command
-                                       ; saved residual code
-ABSOLUTE dsa_temp_addr_new_value = 0   ; Address of value for JUMP operand
-ABSOLUTE dsa_temp_addr_array_value = 0         ; Address to copy to
-ABSOLUTE dsa_temp_addr_dsa_value = 0   ; Address of this DSA value
-
-;
-; Once a device has initiated reselection, we need to compare it 
-; against the singly linked list of commands which have disconnected
-; and are pending reselection.  These commands are maintained in 
-; an unordered singly linked list of DSA structures, through the
-; DSA pointers at their 'centers' headed by the reconnect_dsa_head
-; pointer.
-; 
-; To avoid complications in removing commands from the list,
-; I minimize the amount of expensive (at eight operations per
-; addition @ 500-600ns each) pointer operations which must
-; be done in the NCR driver by precomputing them on the 
-; host processor during dsa structure generation.
-;
-; The fixed-up per DSA code knows how to recognize the nexus
-; associated with the corresponding SCSI command, and modifies
-; the source and destination pointers for the MOVE MEMORY 
-; instruction which is executed when reselected_ok is called
-; to remove the command from the list.  Similarly, DSA is 
-; loaded with the address of the next DSA structure and
-; reselected_check_next is called if a failure occurs.
-;
-; Perhaps more concisely, the net effect of the mess is 
-;
-; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head, 
-;     src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) {
-;      src = &dsa->next;
-;      if (target_id == dsa->id && target_lun == dsa->lun) {
-;              *dest = *src;
-;              break;
-;         }    
-; }
-;
-; if (!dsa)
-;           error (int_err_unexpected_reselect);
-; else  
-;     longjmp (dsa->jump_resume, 0);
-;
-;      
-
-#if (CHIP != 700) && (CHIP != 70066)
-; Define DSA structure used for mailboxes
-ENTRY dsa_code_template
-dsa_code_template:
-ENTRY dsa_code_begin
-dsa_code_begin:
-; RGH: Don't care about TEMP and DSA here
-       DMODE_MEMORY_TO_NCR
-       MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch
-       DMODE_MEMORY_TO_MEMORY
-#if (CHIP == 710)
-       MOVE MEMORY 4, addr_scratch, saved_dsa
-       ; We are about to go and select the device, so must set SSCF bits
-       MOVE MEMORY 4, dsa_sscf_710, addr_scratch
-#ifdef BIG_ENDIAN
-       MOVE SCRATCH3 TO SFBR
-#else
-       MOVE SCRATCH0 TO SFBR
-#endif
-       MOVE SFBR TO SBCL
-       MOVE MEMORY 4, saved_dsa, addr_dsa
-#else
-       CALL scratch_to_dsa
-#endif
-       CALL select
-; Handle the phase mismatch which may have resulted from the 
-; MOVE FROM dsa_msgout if we returned here.  The CLEAR ATN 
-; may or may not be necessary, and we should update script_asm.pl
-; to handle multiple pieces.
-    CLEAR ATN
-    CLEAR ACK
-
-; Replace second operand with address of JUMP instruction dest operand
-; in schedule table for this DSA.  Becomes dsa_jump_dest in 53c7,8xx.c.
-ENTRY dsa_code_fix_jump
-dsa_code_fix_jump:
-       MOVE MEMORY 4, NOP_insn, 0
-       JUMP select_done
-
-; wrong_dsa loads the DSA register with the value of the dsa_next
-; field.
-;
-wrong_dsa:
-#if (CHIP == 710)
-;                NOTE DSA is corrupt when we arrive here!
-#endif
-;              Patch the MOVE MEMORY INSTRUCTION such that 
-;              the destination address is the address of the OLD 
-;              next pointer.
-;
-       MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok_patch + 8
-       DMODE_MEMORY_TO_NCR
-;
-;      Move the _contents_ of the next pointer into the DSA register as 
-;      the next I_T_L or I_T_L_Q tupple to check against the established
-;      nexus.
-;
-       MOVE MEMORY 4, dsa_temp_next, addr_scratch
-       DMODE_MEMORY_TO_MEMORY
-#if (CHIP == 710)
-       MOVE MEMORY 4, addr_scratch, saved_dsa
-       MOVE MEMORY 4, saved_dsa, addr_dsa
-#else
-       CALL scratch_to_dsa
-#endif
-       JUMP reselected_check_next
-
-ABSOLUTE dsa_save_data_pointer = 0
-ENTRY dsa_code_save_data_pointer
-dsa_code_save_data_pointer:
-#if (CHIP == 710)
-       ; When we get here, TEMP has been saved in jump_temp+4, DSA is corrupt
-       ; We MUST return with DSA correct
-       MOVE MEMORY 4, jump_temp+4, dsa_temp_addr_saved_pointer
-; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
-       MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual
-        CLEAR ACK
-#ifdef DEBUG
-        INT int_debug_saved
-#endif
-       MOVE MEMORY 4, saved_dsa, addr_dsa
-       JUMP jump_temp
-#else
-       DMODE_NCR_TO_MEMORY
-       MOVE MEMORY 4, addr_temp, dsa_temp_addr_saved_pointer
-       DMODE_MEMORY_TO_MEMORY
-; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
-       MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual
-        CLEAR ACK
-#ifdef DEBUG
-        INT int_debug_saved
-#endif
-       RETURN
-#endif
-ABSOLUTE dsa_restore_pointers = 0
-ENTRY dsa_code_restore_pointers
-dsa_code_restore_pointers:
-#if (CHIP == 710)
-       ; TEMP and DSA are corrupt when we get here, but who cares!
-       MOVE MEMORY 4, dsa_temp_addr_saved_pointer, jump_temp + 4
-; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
-       MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual
-        CLEAR ACK
-       ; Restore DSA, note we don't care about TEMP
-       MOVE MEMORY 4, saved_dsa, addr_dsa
-#ifdef DEBUG
-        INT int_debug_restored
-#endif
-       JUMP jump_temp
-#else
-       DMODE_MEMORY_TO_NCR
-       MOVE MEMORY 4, dsa_temp_addr_saved_pointer, addr_temp
-       DMODE_MEMORY_TO_MEMORY
-; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
-       MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual
-        CLEAR ACK
-#ifdef DEBUG
-        INT int_debug_restored
-#endif
-       RETURN
-#endif
-
-ABSOLUTE dsa_check_reselect = 0
-; dsa_check_reselect determines whether or not the current target and
-; lun match the current DSA
-ENTRY dsa_code_check_reselect
-dsa_code_check_reselect:
-#if (CHIP == 710)
-       /* Arrives here with DSA correct */
-       /* Assumes we are always ID 7 */
-       MOVE LCRC TO SFBR               ; LCRC has our ID and his ID bits set
-       JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0x80
-#else
-       MOVE SSID TO SFBR               ; SSID contains 3 bit target ID
-; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips
-       JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0xf8
-#endif
-;
-; Hack - move to scratch first, since SFBR is not writeable
-;      via the CPU and hence a MOVE MEMORY instruction.
-;
-       DMODE_MEMORY_TO_NCR
-       MOVE MEMORY 1, reselected_identify, addr_scratch
-       DMODE_MEMORY_TO_MEMORY
-#ifdef BIG_ENDIAN
-       ; BIG ENDIAN ON MVME16x
-       MOVE SCRATCH3 TO SFBR
-#else
-       MOVE SCRATCH0 TO SFBR
-#endif
-; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips
-; Are you sure about that?  richard@sleepie.demon.co.uk
-       JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 0xf8
-;              Patch the MOVE MEMORY INSTRUCTION such that
-;              the source address is the address of this dsa's
-;              next pointer.
-       MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok_patch + 4
-       CALL reselected_ok
-#if (CHIP == 710)
-;      Restore DSA following memory moves in reselected_ok
-;      dsa_temp_sync doesn't really care about DSA, but it has an
-;      optional debug INT so a valid DSA is a good idea.
-       MOVE MEMORY 4, saved_dsa, addr_dsa
-#endif
-       CALL dsa_temp_sync      
-; Release ACK on the IDENTIFY message _after_ we've set the synchronous 
-; transfer parameters! 
-       CLEAR ACK
-; Implicitly restore pointers on reselection, so a RETURN
-; will transfer control back to the right spot.
-       CALL REL (dsa_code_restore_pointers)
-       RETURN
-ENTRY dsa_zero
-dsa_zero:
-ENTRY dsa_code_template_end
-dsa_code_template_end:
-
-; Perform sanity check for dsa_fields_start == dsa_code_template_end - 
-; dsa_zero, puke.
-
-ABSOLUTE dsa_fields_start =  0 ; Sanity marker
-                               ;       pad 48 bytes (fix this RSN)
-ABSOLUTE dsa_next = 48         ; len 4 Next DSA
-                               ; del 4 Previous DSA address
-ABSOLUTE dsa_cmnd = 56         ; len 4 Scsi_Cmnd * for this thread.
-ABSOLUTE dsa_select = 60       ; len 4 Device ID, Period, Offset for 
-                               ;       table indirect select
-ABSOLUTE dsa_msgout = 64       ; len 8 table indirect move parameter for 
-                               ;       select message
-ABSOLUTE dsa_cmdout = 72       ; len 8 table indirect move parameter for 
-                               ;       command
-ABSOLUTE dsa_dataout = 80      ; len 4 code pointer for dataout
-ABSOLUTE dsa_datain = 84       ; len 4 code pointer for datain
-ABSOLUTE dsa_msgin = 88                ; len 8 table indirect move for msgin
-ABSOLUTE dsa_status = 96       ; len 8 table indirect move for status byte
-ABSOLUTE dsa_msgout_other = 104        ; len 8 table indirect for normal message out
-                               ; (Synchronous transfer negotiation, etc).
-ABSOLUTE dsa_end = 112
-
-ABSOLUTE schedule = 0          ; Array of JUMP dsa_begin or JUMP (next),
-                               ; terminated by a call to JUMP wait_reselect
-
-; Linked lists of DSA structures
-ABSOLUTE reconnect_dsa_head = 0        ; Link list of DSAs which can reconnect
-ABSOLUTE addr_reconnect_dsa_head = 0 ; Address of variable containing
-                               ; address of reconnect_dsa_head
-
-; These select the source and destination of a MOVE MEMORY instruction
-ABSOLUTE dmode_memory_to_memory = 0x0
-ABSOLUTE dmode_memory_to_ncr = 0x0
-ABSOLUTE dmode_ncr_to_memory = 0x0
-
-ABSOLUTE addr_scratch = 0x0
-ABSOLUTE addr_temp = 0x0
-#if (CHIP == 710)
-ABSOLUTE saved_dsa = 0x0
-ABSOLUTE emulfly = 0x0
-ABSOLUTE addr_dsa = 0x0
-#endif
-#endif /* CHIP != 700 && CHIP != 70066 */
-
-; Interrupts - 
-; MSB indicates type
-; 0    handle error condition
-; 1    handle message 
-; 2    handle normal condition
-; 3    debugging interrupt
-; 4    testing interrupt 
-; Next byte indicates specific error
-
-; XXX not yet implemented, I'm not sure if I want to - 
-; Next byte indicates the routine the error occurred in
-; The LSB indicates the specific place the error occurred
-ABSOLUTE int_err_unexpected_phase = 0x00000000 ; Unexpected phase encountered
-ABSOLUTE int_err_selected = 0x00010000         ; SELECTED (nee RESELECTED)
-ABSOLUTE int_err_unexpected_reselect = 0x00020000 
-ABSOLUTE int_err_check_condition = 0x00030000  
-ABSOLUTE int_err_no_phase = 0x00040000
-ABSOLUTE int_msg_wdtr = 0x01000000             ; WDTR message received
-ABSOLUTE int_msg_sdtr = 0x01010000             ; SDTR received
-ABSOLUTE int_msg_1 = 0x01020000                        ; single byte special message
-                                               ; received
-
-ABSOLUTE int_norm_select_complete = 0x02000000 ; Select complete, reprogram
-                                               ; registers.
-ABSOLUTE int_norm_reselect_complete = 0x02010000       ; Nexus established
-ABSOLUTE int_norm_command_complete = 0x02020000 ; Command complete
-ABSOLUTE int_norm_disconnected = 0x02030000    ; Disconnected 
-ABSOLUTE int_norm_aborted =0x02040000          ; Aborted *dsa
-ABSOLUTE int_norm_reset = 0x02050000           ; Generated BUS reset.
-ABSOLUTE int_norm_emulateintfly = 0x02060000   ; 53C710 Emulated intfly
-ABSOLUTE int_debug_break = 0x03000000          ; Break point
-#ifdef DEBUG
-ABSOLUTE int_debug_scheduled = 0x03010000      ; new I/O scheduled 
-ABSOLUTE int_debug_idle = 0x03020000           ; scheduler is idle
-ABSOLUTE int_debug_dsa_loaded = 0x03030000     ; dsa reloaded
-ABSOLUTE int_debug_reselected = 0x03040000     ; NCR reselected
-ABSOLUTE int_debug_head = 0x03050000           ; issue head overwritten
-ABSOLUTE int_debug_disconnected = 0x03060000   ; disconnected
-ABSOLUTE int_debug_disconnect_msg = 0x03070000 ; got message to disconnect
-ABSOLUTE int_debug_dsa_schedule = 0x03080000   ; in dsa_schedule
-ABSOLUTE int_debug_reselect_check = 0x03090000  ; Check for reselection of DSA
-ABSOLUTE int_debug_reselected_ok = 0x030a0000  ; Reselection accepted
-#endif
-ABSOLUTE int_debug_panic = 0x030b0000          ; Panic driver
-#ifdef DEBUG
-ABSOLUTE int_debug_saved = 0x030c0000          ; save/restore pointers
-ABSOLUTE int_debug_restored = 0x030d0000
-ABSOLUTE int_debug_sync = 0x030e0000           ; Sanity check synchronous 
-                                               ; parameters. 
-ABSOLUTE int_debug_datain = 0x030f0000         ; going into data in phase 
-                                               ; now.
-ABSOLUTE int_debug_check_dsa = 0x03100000      ; Sanity check DSA against
-                                               ; SDID.
-#endif
-
-ABSOLUTE int_test_1 = 0x04000000               ; Test 1 complete
-ABSOLUTE int_test_2 = 0x04010000               ; Test 2 complete
-ABSOLUTE int_test_3 = 0x04020000               ; Test 3 complete
-
-
-; These should start with 0x05000000, with low bits incrementing for 
-; each one.
-
-#ifdef EVENTS
-ABSOLUTE int_EVENT_SELECT = 0
-ABSOLUTE int_EVENT_DISCONNECT = 0
-ABSOLUTE int_EVENT_RESELECT = 0
-ABSOLUTE int_EVENT_COMPLETE = 0
-ABSOLUTE int_EVENT_IDLE = 0
-ABSOLUTE int_EVENT_SELECT_FAILED = 0
-ABSOLUTE int_EVENT_BEFORE_SELECT = 0
-ABSOLUTE int_EVENT_RESELECT_FAILED = 0
-#endif
-                                               
-ABSOLUTE NCR53c7xx_msg_abort = 0       ; Pointer to abort message
-ABSOLUTE NCR53c7xx_msg_reject = 0       ; Pointer to reject message
-ABSOLUTE NCR53c7xx_zero        = 0             ; long with zero in it, use for source
-ABSOLUTE NCR53c7xx_sink = 0            ; long to dump worthless data in
-ABSOLUTE NOP_insn = 0                  ; NOP instruction
-
-; Pointer to message, potentially multi-byte
-ABSOLUTE msg_buf = 0
-
-; Pointer to holding area for reselection information
-ABSOLUTE reselected_identify = 0
-ABSOLUTE reselected_tag = 0
-
-; Request sense command pointer, it's a 6 byte command, should
-; be constant for all commands since we always want 16 bytes of 
-; sense and we don't need to change any fields as we did under 
-; SCSI-I when we actually cared about the LUN field.
-;EXTERNAL NCR53c7xx_sense              ; Request sense command
-
-#if (CHIP != 700) && (CHIP != 70066)
-; dsa_schedule  
-; PURPOSE : after a DISCONNECT message has been received, and pointers
-;      saved, insert the current DSA structure at the head of the 
-;      disconnected queue and fall through to the scheduler.
-;
-; CALLS : OK
-;
-; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list
-;      of disconnected commands
-;
-; MODIFIES : SCRATCH, reconnect_dsa_head
-; 
-; EXITS : always passes control to schedule
-
-ENTRY dsa_schedule
-dsa_schedule:
-#ifdef DEBUG
-    INT int_debug_dsa_schedule
-#endif
-
-;
-; Calculate the address of the next pointer within the DSA 
-; structure of the command that is currently disconnecting
-;
-#if (CHIP == 710)
-    ; Read what should be the current DSA from memory - actual DSA
-    ; register is probably corrupt
-    MOVE MEMORY 4, saved_dsa, addr_scratch
-#else
-    CALL dsa_to_scratch
-#endif
-    MOVE SCRATCH0 + dsa_next TO SCRATCH0
-    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
-    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
-    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
-
-; Point the next field of this DSA structure at the current disconnected 
-; list
-    DMODE_NCR_TO_MEMORY
-    MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8
-    DMODE_MEMORY_TO_MEMORY
-dsa_schedule_insert:
-    MOVE MEMORY 4, reconnect_dsa_head, 0 
-
-; And update the head pointer.
-#if (CHIP == 710)
-    ; Read what should be the current DSA from memory - actual DSA
-    ; register is probably corrupt
-    MOVE MEMORY 4, saved_dsa, addr_scratch
-#else
-    CALL dsa_to_scratch
-#endif
-    DMODE_NCR_TO_MEMORY
-    MOVE MEMORY 4, addr_scratch, reconnect_dsa_head
-    DMODE_MEMORY_TO_MEMORY
-/* Temporarily, see what happens. */
-#ifndef ORIGINAL
-#if (CHIP != 710)
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-#endif
-    CLEAR ACK
-#endif
-#if (CHIP == 710)
-    ; Time to correct DSA following memory move
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-#endif
-    WAIT DISCONNECT
-#ifdef EVENTS
-    INT int_EVENT_DISCONNECT;
-#endif
-#ifdef DEBUG
-    INT int_debug_disconnected
-#endif
-    JUMP schedule
-#endif 
-
-;
-; select
-;
-; PURPOSE : establish a nexus for the SCSI command referenced by DSA.
-;      On success, the current DSA structure is removed from the issue 
-;      queue.  Usually, this is entered as a fall-through from schedule,
-;      although the contingent allegiance handling code will write
-;      the select entry address to the DSP to restart a command as a 
-;      REQUEST SENSE.  A message is sent (usually IDENTIFY, although
-;      additional SDTR or WDTR messages may be sent).  COMMAND OUT
-;      is handled.
-;
-; INPUTS : DSA - SCSI command, issue_dsa_head
-;
-; CALLS : NOT OK
-;
-; MODIFIES : SCRATCH, issue_dsa_head
-;
-; EXITS : on reselection or selection, go to select_failed
-;      otherwise, RETURN so control is passed back to 
-;      dsa_begin.
-;
-
-ENTRY select
-select:
-
-#ifdef EVENTS
-    INT int_EVENT_BEFORE_SELECT
-#endif
-
-#ifdef DEBUG
-    INT int_debug_scheduled
-#endif
-    CLEAR TARGET
-
-; XXX
-;
-; In effect, SELECTION operations are backgrounded, with execution
-; continuing until code which waits for REQ or a fatal interrupt is 
-; encountered.
-;
-; So, for more performance, we could overlap the code which removes 
-; the command from the NCRs issue queue with the selection, but 
-; at this point I don't want to deal with the error recovery.
-;
-
-#if (CHIP != 700) && (CHIP != 70066)
-#if (CHIP == 710)
-    ; Enable selection timer
-#ifdef NO_SELECTION_TIMEOUT
-    MOVE CTEST7 & 0xff TO CTEST7
-#else
-    MOVE CTEST7 & 0xef TO CTEST7
-#endif
-#endif
-    SELECT ATN FROM dsa_select, select_failed
-    JUMP select_msgout, WHEN MSG_OUT
-ENTRY select_msgout
-select_msgout:
-#if (CHIP == 710)
-    ; Disable selection timer
-    MOVE CTEST7 | 0x10 TO CTEST7
-#endif
-    MOVE FROM dsa_msgout, WHEN MSG_OUT
-#else
-ENTRY select_msgout
-    SELECT ATN 0, select_failed
-select_msgout:
-    MOVE 0, 0, WHEN MSGOUT
-#endif
-
-#ifdef EVENTS
-   INT int_EVENT_SELECT
-#endif
-   RETURN
-
-; 
-; select_done
-; 
-; PURPOSE: continue on to normal data transfer; called as the exit 
-;      point from dsa_begin.
-;
-; INPUTS: dsa
-;
-; CALLS: OK
-;
-;
-
-select_done:
-#if (CHIP == 710)
-; NOTE DSA is corrupt when we arrive here!
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-#endif
-
-#ifdef DEBUG
-ENTRY select_check_dsa
-select_check_dsa:
-    INT int_debug_check_dsa
-#endif
-
-; After a successful selection, we should get either a CMD phase or 
-; some transfer request negotiation message.
-
-    JUMP cmdout, WHEN CMD
-    INT int_err_unexpected_phase, WHEN NOT MSG_IN 
-
-select_msg_in:
-    CALL msg_in, WHEN MSG_IN
-    JUMP select_msg_in, WHEN MSG_IN
-
-cmdout:
-    INT int_err_unexpected_phase, WHEN NOT CMD
-#if (CHIP == 700)
-    INT int_norm_selected
-#endif
-ENTRY cmdout_cmdout
-cmdout_cmdout:
-#if (CHIP != 700) && (CHIP != 70066)
-    MOVE FROM dsa_cmdout, WHEN CMD
-#else
-    MOVE 0, 0, WHEN CMD
-#endif /* (CHIP != 700) && (CHIP != 70066) */
-
-;
-; data_transfer  
-; other_out
-; other_in
-; other_transfer
-;
-; PURPOSE : handle the main data transfer for a SCSI command in 
-;      several parts.  In the first part, data_transfer, DATA_IN
-;      and DATA_OUT phases are allowed, with the user provided
-;      code (usually dynamically generated based on the scatter/gather
-;      list associated with a SCSI command) called to handle these 
-;      phases.
-;
-;      After control has passed to one of the user provided 
-;      DATA_IN or DATA_OUT routines, back calls are made to 
-;      other_transfer_in or other_transfer_out to handle non-DATA IN
-;      and DATA OUT phases respectively, with the state of the active
-;      data pointer being preserved in TEMP.
-;
-;      On completion, the user code passes control to other_transfer
-;      which causes DATA_IN and DATA_OUT to result in unexpected_phase
-;      interrupts so that data overruns may be trapped.
-;
-; INPUTS : DSA - SCSI command
-;
-; CALLS : OK in data_transfer_start, not ok in other_out and other_in, ok in
-;      other_transfer
-;
-; MODIFIES : SCRATCH
-;
-; EXITS : if STATUS IN is detected, signifying command completion,
-;      the NCR jumps to command_complete.  If MSG IN occurs, a 
-;      CALL is made to msg_in.  Otherwise, other_transfer runs in 
-;      an infinite loop.
-;      
-
-ENTRY data_transfer
-data_transfer:
-    JUMP cmdout_cmdout, WHEN CMD
-    CALL msg_in, WHEN MSG_IN
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-    JUMP do_dataout, WHEN DATA_OUT
-    JUMP do_datain, WHEN DATA_IN
-    JUMP command_complete, WHEN STATUS
-    JUMP data_transfer
-ENTRY end_data_transfer
-end_data_transfer:
-
-;
-; FIXME: On NCR53c700 and NCR53c700-66 chips, do_dataout/do_datain 
-; should be fixed up whenever the nexus changes so it can point to the 
-; correct routine for that command.
-;
-
-#if (CHIP != 700) && (CHIP != 70066)
-; Nasty jump to dsa->dataout
-do_dataout:
-#if (CHIP == 710)
-    MOVE MEMORY 4, saved_dsa, addr_scratch
-#else
-    CALL dsa_to_scratch
-#endif
-    MOVE SCRATCH0 + dsa_dataout TO SCRATCH0    
-    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY 
-    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY 
-    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY 
-    DMODE_NCR_TO_MEMORY
-    MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4
-    DMODE_MEMORY_TO_MEMORY
-dataout_to_jump:
-    MOVE MEMORY 4, 0, dataout_jump + 4 
-#if (CHIP == 710)
-    ; Time to correct DSA following memory move
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-#endif
-dataout_jump:
-    JUMP 0
-
-; Nasty jump to dsa->dsain
-do_datain:
-#if (CHIP == 710)
-    MOVE MEMORY 4, saved_dsa, addr_scratch
-#else
-    CALL dsa_to_scratch
-#endif
-    MOVE SCRATCH0 + dsa_datain TO SCRATCH0     
-    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY 
-    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY 
-    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY 
-    DMODE_NCR_TO_MEMORY
-    MOVE MEMORY 4, addr_scratch, datain_to_jump + 4
-    DMODE_MEMORY_TO_MEMORY
-ENTRY datain_to_jump
-datain_to_jump:
-    MOVE MEMORY 4, 0, datain_jump + 4
-#if (CHIP == 710)
-    ; Time to correct DSA following memory move
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-#endif
-#ifdef DEBUG
-    INT int_debug_datain
-#endif
-datain_jump:
-    JUMP 0
-#endif /* (CHIP != 700) && (CHIP != 70066) */
-
-
-; Note that other_out and other_in loop until a non-data phase
-; is discovered, so we only execute return statements when we
-; can go on to the next data phase block move statement.
-
-ENTRY other_out
-other_out:
-#if 0
-    INT 0x03ffdead
-#endif
-    INT int_err_unexpected_phase, WHEN CMD
-    JUMP msg_in_restart, WHEN MSG_IN 
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-    INT int_err_unexpected_phase, WHEN DATA_IN
-    JUMP command_complete, WHEN STATUS
-    JUMP other_out, WHEN NOT DATA_OUT
-#if (CHIP == 710)
-; TEMP should be OK, as we got here from a call in the user dataout code.
-#endif
-    RETURN
-
-ENTRY other_in
-other_in:
-#if 0
-    INT 0x03ffdead
-#endif
-    INT int_err_unexpected_phase, WHEN CMD
-    JUMP msg_in_restart, WHEN MSG_IN 
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-    INT int_err_unexpected_phase, WHEN DATA_OUT
-    JUMP command_complete, WHEN STATUS
-    JUMP other_in, WHEN NOT DATA_IN
-#if (CHIP == 710)
-; TEMP should be OK, as we got here from a call in the user datain code.
-#endif
-    RETURN
-
-
-ENTRY other_transfer
-other_transfer:
-    INT int_err_unexpected_phase, WHEN CMD
-    CALL msg_in, WHEN MSG_IN
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-    INT int_err_unexpected_phase, WHEN DATA_OUT
-    INT int_err_unexpected_phase, WHEN DATA_IN
-    JUMP command_complete, WHEN STATUS
-    JUMP other_transfer
-
-;
-; msg_in_restart
-; msg_in
-; munge_msg
-;
-; PURPOSE : process messages from a target.  msg_in is called when the 
-;      caller hasn't read the first byte of the message.  munge_message
-;      is called when the caller has read the first byte of the message,
-;      and left it in SFBR.  msg_in_restart is called when the caller 
-;      hasn't read the first byte of the message, and wishes RETURN
-;      to transfer control back to the address of the conditional
-;      CALL instruction rather than to the instruction after it.
-;
-;      Various int_* interrupts are generated when the host system
-;      needs to intervene, as is the case with SDTR, WDTR, and
-;      INITIATE RECOVERY messages.
-;
-;      When the host system handles one of these interrupts,
-;      it can respond by reentering at reject_message, 
-;      which rejects the message and returns control to
-;      the caller of msg_in or munge_msg, accept_message
-;      which clears ACK and returns control, or reply_message
-;      which sends the message pointed to by the DSA 
-;      msgout_other table indirect field.
-;
-;      DISCONNECT messages are handled by moving the command
-;      to the reconnect_dsa_queue.
-#if (CHIP == 710)
-; NOTE: DSA should be valid when we get here - we cannot save both it
-;      and TEMP in this routine.
-#endif
-;
-; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg
-;      only)
-;
-; CALLS : NO.  The TEMP register isn't backed up to allow nested calls.
-;
-; MODIFIES : SCRATCH, DSA on DISCONNECT
-;
-; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS,
-;      and normal return from message handlers running under
-;      Linux, control is returned to the caller.  Receipt
-;      of DISCONNECT messages pass control to dsa_schedule.
-;
-ENTRY msg_in_restart
-msg_in_restart:
-; XXX - hackish
-;
-; Since it's easier to debug changes to the statically 
-; compiled code, rather than the dynamically generated 
-; stuff, such as
-;
-;      MOVE x, y, WHEN data_phase
-;      CALL other_z, WHEN NOT data_phase
-;      MOVE x, y, WHEN data_phase
-;
-; I'd like to have certain routines (notably the message handler)
-; restart on the conditional call rather than the next instruction.
-;
-; So, subtract 8 from the return address
-
-    MOVE TEMP0 + 0xf8 TO TEMP0
-    MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY
-    MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY
-    MOVE TEMP3 + 0xff TO TEMP3 WITH CARRY
-
-ENTRY msg_in
-msg_in:
-    MOVE 1, msg_buf, WHEN MSG_IN
-
-munge_msg:
-    JUMP munge_extended, IF 0x01               ; EXTENDED MESSAGE
-    JUMP munge_2, IF 0x20, AND MASK 0xdf       ; two byte message
-;
-; XXX - I've seen a handful of broken SCSI devices which fail to issue
-;      a SAVE POINTERS message before disconnecting in the middle of 
-;      a transfer, assuming that the DATA POINTER will be implicitly 
-;      restored.  
-;
-; Historically, I've often done an implicit save when the DISCONNECT
-; message is processed.  We may want to consider having the option of 
-; doing that here. 
-;
-    JUMP munge_save_data_pointer, IF 0x02      ; SAVE DATA POINTER
-    JUMP munge_restore_pointers, IF 0x03       ; RESTORE POINTERS 
-    JUMP munge_disconnect, IF 0x04             ; DISCONNECT
-    INT int_msg_1, IF 0x07                     ; MESSAGE REJECT
-    INT int_msg_1, IF 0x0f                     ; INITIATE RECOVERY
-#ifdef EVENTS 
-    INT int_EVENT_SELECT_FAILED 
-#endif
-    JUMP reject_message
-
-munge_2:
-    JUMP reject_message
-;
-; The SCSI standard allows targets to recover from transient 
-; error conditions by backing up the data pointer with a 
-; RESTORE POINTERS message.  
-;      
-; So, we must save and restore the _residual_ code as well as 
-; the current instruction pointer.  Because of this messiness,
-; it is simpler to put dynamic code in the dsa for this and to
-; just do a simple jump down there. 
-;
-
-munge_save_data_pointer:
-#if (CHIP == 710)
-    ; We have something in TEMP here, so first we must save that
-    MOVE TEMP0 TO SFBR
-    MOVE SFBR TO SCRATCH0
-    MOVE TEMP1 TO SFBR
-    MOVE SFBR TO SCRATCH1
-    MOVE TEMP2 TO SFBR
-    MOVE SFBR TO SCRATCH2
-    MOVE TEMP3 TO SFBR
-    MOVE SFBR TO SCRATCH3
-    MOVE MEMORY 4, addr_scratch, jump_temp + 4
-    ; Now restore DSA
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-#endif
-    MOVE DSA0 + dsa_save_data_pointer TO SFBR
-    MOVE SFBR TO SCRATCH0
-    MOVE DSA1 + 0xff TO SFBR WITH CARRY
-    MOVE SFBR TO SCRATCH1
-    MOVE DSA2 + 0xff TO SFBR WITH CARRY 
-    MOVE SFBR TO SCRATCH2
-    MOVE DSA3 + 0xff TO SFBR WITH CARRY
-    MOVE SFBR TO SCRATCH3
-
-    DMODE_NCR_TO_MEMORY
-    MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4
-    DMODE_MEMORY_TO_MEMORY
-jump_dsa_save:
-    JUMP 0
-
-munge_restore_pointers:
-#if (CHIP == 710)
-    ; The code at dsa_restore_pointers will RETURN, but we don't care
-    ; about TEMP here, as it will overwrite it anyway.
-#endif
-    MOVE DSA0 + dsa_restore_pointers TO SFBR
-    MOVE SFBR TO SCRATCH0
-    MOVE DSA1 + 0xff TO SFBR WITH CARRY
-    MOVE SFBR TO SCRATCH1
-    MOVE DSA2 + 0xff TO SFBR WITH CARRY
-    MOVE SFBR TO SCRATCH2
-    MOVE DSA3 + 0xff TO SFBR WITH CARRY
-    MOVE SFBR TO SCRATCH3
-
-    DMODE_NCR_TO_MEMORY
-    MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4
-    DMODE_MEMORY_TO_MEMORY
-jump_dsa_restore:
-    JUMP 0
-
-
-munge_disconnect:
-#ifdef DEBUG
-    INT int_debug_disconnect_msg
-#endif
-
-/* 
- * Before, we overlapped processing with waiting for disconnect, but
- * debugging was beginning to appear messy.  Temporarily move things
- * to just before the WAIT DISCONNECT.
- */
-#ifdef ORIGINAL
-#if (CHIP == 710)
-; Following clears Unexpected Disconnect bit.  What do we do?
-#else
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-#endif
-    CLEAR ACK
-#endif
-
-#if (CHIP != 700) && (CHIP != 70066)
-    JUMP dsa_schedule
-#else
-    WAIT DISCONNECT
-    INT int_norm_disconnected
-#endif
-
-munge_extended:
-    CLEAR ACK
-    INT int_err_unexpected_phase, WHEN NOT MSG_IN
-    MOVE 1, msg_buf + 1, WHEN MSG_IN
-    JUMP munge_extended_2, IF 0x02
-    JUMP munge_extended_3, IF 0x03 
-    JUMP reject_message
-
-munge_extended_2:
-    CLEAR ACK
-    MOVE 1, msg_buf + 2, WHEN MSG_IN
-    JUMP reject_message, IF NOT 0x02   ; Must be WDTR
-    CLEAR ACK
-    MOVE 1, msg_buf + 3, WHEN MSG_IN
-    INT int_msg_wdtr
-
-munge_extended_3:
-    CLEAR ACK
-    MOVE 1, msg_buf + 2, WHEN MSG_IN
-    JUMP reject_message, IF NOT 0x01   ; Must be SDTR
-    CLEAR ACK
-    MOVE 2, msg_buf + 3, WHEN MSG_IN
-    INT int_msg_sdtr
-
-ENTRY reject_message
-reject_message:
-    SET ATN
-    CLEAR ACK
-    MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
-    RETURN
-
-ENTRY accept_message
-accept_message:
-    CLEAR ATN
-    CLEAR ACK
-    RETURN
-
-ENTRY respond_message
-respond_message:
-    SET ATN
-    CLEAR ACK
-    MOVE FROM dsa_msgout_other, WHEN MSG_OUT
-    RETURN
-
-;
-; command_complete
-;
-; PURPOSE : handle command termination when STATUS IN is detected by reading
-;      a status byte followed by a command termination message. 
-;
-;      Normal termination results in an INTFLY instruction, and 
-;      the host system can pick out which command terminated by 
-;      examining the MESSAGE and STATUS buffers of all currently 
-;      executing commands;
-;
-;      Abnormal (CHECK_CONDITION) termination results in an
-;      int_err_check_condition interrupt so that a REQUEST SENSE
-;      command can be issued out-of-order so that no other command
-;      clears the contingent allegiance condition.
-;      
-;
-; INPUTS : DSA - command       
-;
-; CALLS : OK
-;
-; EXITS : On successful termination, control is passed to schedule.
-;      On abnormal termination, the user will usually modify the 
-;      DSA fields and corresponding buffers and return control
-;      to select.
-;
-
-ENTRY command_complete
-command_complete:
-    MOVE FROM dsa_status, WHEN STATUS
-#if (CHIP != 700) && (CHIP != 70066)
-    MOVE SFBR TO SCRATCH0              ; Save status
-#endif /* (CHIP != 700) && (CHIP != 70066) */
-ENTRY command_complete_msgin
-command_complete_msgin:
-    MOVE FROM dsa_msgin, WHEN MSG_IN
-; Indicate that we should be expecting a disconnect
-#if (CHIP != 710)
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-#else
-    ; Above code cleared the Unexpected Disconnect bit, what do we do?
-#endif
-    CLEAR ACK
-#if (CHIP != 700) && (CHIP != 70066)
-    WAIT DISCONNECT
-
-;
-; The SCSI specification states that when a UNIT ATTENTION condition
-; is pending, as indicated by a CHECK CONDITION status message,
-; the target shall revert to asynchronous transfers.  Since
-; synchronous transfers parameters are maintained on a per INITIATOR/TARGET 
-; basis, and returning control to our scheduler could work on a command
-; running on another lun on that target using the old parameters, we must
-; interrupt the host processor to get them changed, or change them ourselves.
-;
-; Once SCSI-II tagged queueing is implemented, things will be even more
-; hairy, since contingent allegiance conditions exist on a per-target/lun
-; basis, and issuing a new command with a different tag would clear it.
-; In these cases, we must interrupt the host processor to get a request 
-; added to the HEAD of the queue with the request sense command, or we
-; must automatically issue the request sense command.
-
-#if 0
-    MOVE SCRATCH0 TO SFBR                      
-    JUMP command_failed, IF 0x02
-#endif
-#if (CHIP == 710)
-#if defined(MVME16x_INTFLY)
-; For MVME16x (ie CHIP=710) we will force an INTFLY by triggering a software
-; interrupt (SW7).  We can use SCRATCH, as we are about to jump to
-; schedule, which corrupts it anyway.  Will probably remove this later,
-; but want to check performance effects first.
-
-#define INTFLY_ADDR     0xfff40070
-
-    MOVE 0 TO SCRATCH0
-    MOVE 0x80 TO SCRATCH1
-    MOVE 0 TO SCRATCH2
-    MOVE 0 TO SCRATCH3
-    MOVE MEMORY 4, addr_scratch, INTFLY_ADDR
-#else
-    INT int_norm_emulateintfly
-#endif
-#else
-    INTFLY
-#endif
-#endif /* (CHIP != 700) && (CHIP != 70066) */
-#if (CHIP == 710)
-    ; Time to correct DSA following memory move
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-#endif
-#ifdef EVENTS
-    INT int_EVENT_COMPLETE
-#endif
-#if (CHIP != 700) && (CHIP != 70066)
-    JUMP schedule
-command_failed:
-    INT int_err_check_condition
-#else
-    INT int_norm_command_complete
-#endif
-
-;
-; wait_reselect
-;
-; PURPOSE : This is essentially the idle routine, where control lands
-;      when there are no new processes to schedule.  wait_reselect
-;      waits for reselection, selection, and new commands.
-;
-;      When a successful reselection occurs, with the aid 
-;      of fixed up code in each DSA, wait_reselect walks the 
-;      reconnect_dsa_queue, asking each dsa if the target ID
-;      and LUN match its.
-;
-;      If a match is found, a call is made back to reselected_ok,
-;      which through the miracles of self modifying code, extracts
-;      the found DSA from the reconnect_dsa_queue and then 
-;      returns control to the DSAs thread of execution.
-;
-; INPUTS : NONE
-;
-; CALLS : OK
-;
-; MODIFIES : DSA,
-;
-; EXITS : On successful reselection, control is returned to the 
-;      DSA which called reselected_ok.  If the WAIT RESELECT
-;      was interrupted by a new commands arrival signaled by 
-;      SIG_P, control is passed to schedule.  If the NCR is 
-;      selected, the host system is interrupted with an 
-;      int_err_selected which is usually responded to by
-;      setting DSP to the target_abort address.
-
-ENTRY wait_reselect
-wait_reselect:
-#ifdef EVENTS
-    int int_EVENT_IDLE
-#endif
-#ifdef DEBUG
-    int int_debug_idle
-#endif
-    WAIT RESELECT wait_reselect_failed
-
-reselected:
-#ifdef EVENTS
-    int int_EVENT_RESELECT
-#endif
-    CLEAR TARGET
-    DMODE_MEMORY_TO_MEMORY
-    ; Read all data needed to reestablish the nexus - 
-    MOVE 1, reselected_identify, WHEN MSG_IN
-    ; We used to CLEAR ACK here.
-#if (CHIP != 700) && (CHIP != 70066)
-#ifdef DEBUG
-    int int_debug_reselected
-#endif
-
-    ; Point DSA at the current head of the disconnected queue.
-    DMODE_MEMORY_TO_NCR
-    MOVE MEMORY 4, reconnect_dsa_head, addr_scratch
-    DMODE_MEMORY_TO_MEMORY
-#if (CHIP == 710)
-    MOVE MEMORY 4, addr_scratch, saved_dsa
-#else
-    CALL scratch_to_dsa
-#endif
-
-    ; Fix the update-next pointer so that the reconnect_dsa_head
-    ; pointer is the one that will be updated if this DSA is a hit 
-    ; and we remove it from the queue.
-
-    MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok_patch + 8
-#if (CHIP == 710)
-    ; Time to correct DSA following memory move
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-#endif
-
-ENTRY reselected_check_next
-reselected_check_next:
-#ifdef DEBUG
-    INT int_debug_reselect_check
-#endif
-    ; Check for a NULL pointer.
-    MOVE DSA0 TO SFBR
-    JUMP reselected_not_end, IF NOT 0
-    MOVE DSA1 TO SFBR
-    JUMP reselected_not_end, IF NOT 0
-    MOVE DSA2 TO SFBR
-    JUMP reselected_not_end, IF NOT 0
-    MOVE DSA3 TO SFBR
-    JUMP reselected_not_end, IF NOT 0
-    INT int_err_unexpected_reselect
-
-reselected_not_end:
-    ;
-    ; XXX the ALU is only eight bits wide, and the assembler
-    ; wont do the dirt work for us.  As long as dsa_check_reselect
-    ; is negative, we need to sign extend with 1 bits to the full
-    ; 32 bit width of the address.
-    ;
-    ; A potential work around would be to have a known alignment 
-    ; of the DSA structure such that the base address plus 
-    ; dsa_check_reselect doesn't require carrying from bytes 
-    ; higher than the LSB.
-    ;
-
-    MOVE DSA0 TO SFBR
-    MOVE SFBR + dsa_check_reselect TO SCRATCH0
-    MOVE DSA1 TO SFBR
-    MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY
-    MOVE DSA2 TO SFBR
-    MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY
-    MOVE DSA3 TO SFBR
-    MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY
-
-    DMODE_NCR_TO_MEMORY
-    MOVE MEMORY 4, addr_scratch, reselected_check + 4
-    DMODE_MEMORY_TO_MEMORY
-#if (CHIP == 710)
-    ; Time to correct DSA following memory move
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-#endif
-reselected_check:
-    JUMP 0
-
-
-;
-;
-#if (CHIP == 710)
-; We have problems here - the memory move corrupts TEMP and DSA.  This
-; routine is called from DSA code, and patched from many places.  Scratch
-; is probably free when it is called.
-; We have to:
-;   copy temp to scratch, one byte at a time
-;   write scratch to patch a jump in place of the return
-;   do the move memory
-;   jump to the patched in return address
-; DSA is corrupt when we get here, and can be left corrupt
-
-ENTRY reselected_ok
-reselected_ok:
-    MOVE TEMP0 TO SFBR
-    MOVE SFBR TO SCRATCH0
-    MOVE TEMP1 TO SFBR
-    MOVE SFBR TO SCRATCH1
-    MOVE TEMP2 TO SFBR
-    MOVE SFBR TO SCRATCH2
-    MOVE TEMP3 TO SFBR
-    MOVE SFBR TO SCRATCH3
-    MOVE MEMORY 4, addr_scratch, reselected_ok_jump + 4
-reselected_ok_patch:
-    MOVE MEMORY 4, 0, 0
-reselected_ok_jump:
-    JUMP 0
-#else
-ENTRY reselected_ok
-reselected_ok:
-reselected_ok_patch:
-    MOVE MEMORY 4, 0, 0                                ; Patched : first word
-                                               ;       is address of 
-                                               ;       successful dsa_next
-                                               ; Second word is last 
-                                               ;       unsuccessful dsa_next,
-                                               ;       starting with 
-                                               ;       dsa_reconnect_head
-    ; We used to CLEAR ACK here.
-#ifdef DEBUG
-    INT int_debug_reselected_ok
-#endif
-#ifdef DEBUG
-    INT int_debug_check_dsa
-#endif
-    RETURN                                     ; Return control to where
-#endif
-#else
-    INT int_norm_reselected
-#endif /* (CHIP != 700) && (CHIP != 70066) */
-
-selected:
-    INT int_err_selected;
-
-;
-; A select or reselect failure can be caused by one of two conditions : 
-; 1.  SIG_P was set.  This will be the case if the user has written
-;      a new value to a previously NULL head of the issue queue.
-;
-; 2.  The NCR53c810 was selected or reselected by another device.
-;
-; 3.  The bus was already busy since we were selected or reselected
-;      before starting the command.
-
-wait_reselect_failed:
-#ifdef EVENTS 
-       INT int_EVENT_RESELECT_FAILED
-#endif
-; Check selected bit.  
-#if (CHIP == 710)
-    ; Must work out how to tell if we are selected....
-#else
-    MOVE SIST0 & 0x20 TO SFBR
-    JUMP selected, IF 0x20
-#endif
-; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
-    MOVE CTEST2 & 0x40 TO SFBR 
-    JUMP schedule, IF 0x40
-; Check connected bit.  
-; FIXME: this needs to change if we support target mode
-    MOVE ISTAT & 0x08 TO SFBR
-    JUMP reselected, IF 0x08
-; FIXME : Something bogus happened, and we shouldn't fail silently.
-#if 0
-    JUMP schedule
-#else
-    INT int_debug_panic
-#endif
-
-
-select_failed:
-#if (CHIP == 710)
-    ; Disable selection timer
-    MOVE CTEST7 | 0x10 TO CTEST7
-#endif
-#ifdef EVENTS
-  int int_EVENT_SELECT_FAILED
-#endif
-; Otherwise, mask the selected and reselected bits off SIST0
-#if (CHIP ==710)
-    ; Let's assume we don't get selected for now
-    MOVE SSTAT0 & 0x10 TO SFBR
-#else
-    MOVE SIST0 & 0x30 TO SFBR
-    JUMP selected, IF 0x20
-#endif
-    JUMP reselected, IF 0x10 
-; If SIGP is set, the user just gave us another command, and
-; we should restart or return to the scheduler.
-; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
-    MOVE CTEST2 & 0x40 TO SFBR 
-    JUMP select, IF 0x40
-; Check connected bit.  
-; FIXME: this needs to change if we support target mode
-; FIXME: is this really necessary? 
-    MOVE ISTAT & 0x08 TO SFBR
-    JUMP reselected, IF 0x08
-; FIXME : Something bogus happened, and we shouldn't fail silently.
-#if 0
-    JUMP schedule
-#else
-    INT int_debug_panic
-#endif
-
-;
-; test_1
-; test_2
-;
-; PURPOSE : run some verification tests on the NCR.  test_1
-;      copies test_src to test_dest and interrupts the host
-;      processor, testing for cache coherency and interrupt
-;      problems in the processes.
-;
-;      test_2 runs a command with offsets relative to the 
-;      DSA on entry, and is useful for miscellaneous experimentation.
-;
-
-; Verify that interrupts are working correctly and that we don't 
-; have a cache invalidation problem.
-
-ABSOLUTE test_src = 0, test_dest = 0
-ENTRY test_1
-test_1:
-    MOVE MEMORY 4, test_src, test_dest
-    INT int_test_1
-
-;
-; Run arbitrary commands, with test code establishing a DSA
-;
-ENTRY test_2
-test_2:
-    CLEAR TARGET
-#if (CHIP == 710)
-    ; Enable selection timer
-#ifdef NO_SELECTION_TIMEOUT
-    MOVE CTEST7 & 0xff TO CTEST7
-#else
-    MOVE CTEST7 & 0xef TO CTEST7
-#endif
-#endif
-    SELECT ATN FROM 0, test_2_fail
-    JUMP test_2_msgout, WHEN MSG_OUT
-ENTRY test_2_msgout
-test_2_msgout:
-#if (CHIP == 710)
-    ; Disable selection timer
-    MOVE CTEST7 | 0x10 TO CTEST7
-#endif
-    MOVE FROM 8, WHEN MSG_OUT
-    MOVE FROM 16, WHEN CMD 
-    MOVE FROM 24, WHEN DATA_IN
-    MOVE FROM 32, WHEN STATUS
-    MOVE FROM 40, WHEN MSG_IN
-#if (CHIP != 710)
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-#endif
-    CLEAR ACK
-    WAIT DISCONNECT
-test_2_fail:
-#if (CHIP == 710)
-    ; Disable selection timer
-    MOVE CTEST7 | 0x10 TO CTEST7
-#endif
-    INT int_test_2
-
-ENTRY debug_break
-debug_break:
-    INT int_debug_break
-
-;
-; initiator_abort
-; target_abort
-;
-; PURPOSE : Abort the currently established nexus from with initiator
-;      or target mode.
-;
-;  
-
-ENTRY target_abort
-target_abort:
-    SET TARGET
-    DISCONNECT
-    CLEAR TARGET
-    JUMP schedule
-    
-ENTRY initiator_abort
-initiator_abort:
-    SET ATN
-;
-; The SCSI-I specification says that targets may go into MSG out at 
-; their leisure upon receipt of the ATN single.  On all versions of the 
-; specification, we can't change phases until REQ transitions true->false, 
-; so we need to sink/source one byte of data to allow the transition.
-;
-; For the sake of safety, we'll only source one byte of data in all 
-; cases, but to accommodate the SCSI-I dain bramage, we'll sink an  
-; arbitrary number of bytes.
-    JUMP spew_cmd, WHEN CMD
-    JUMP eat_msgin, WHEN MSG_IN
-    JUMP eat_datain, WHEN DATA_IN
-    JUMP eat_status, WHEN STATUS
-    JUMP spew_dataout, WHEN DATA_OUT
-    JUMP sated
-spew_cmd:
-    MOVE 1, NCR53c7xx_zero, WHEN CMD
-    JUMP sated
-eat_msgin:
-    MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
-    JUMP eat_msgin, WHEN MSG_IN
-    JUMP sated
-eat_status:
-    MOVE 1, NCR53c7xx_sink, WHEN STATUS
-    JUMP eat_status, WHEN STATUS
-    JUMP sated
-eat_datain:
-    MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
-    JUMP eat_datain, WHEN DATA_IN
-    JUMP sated
-spew_dataout:
-    MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
-sated:
-#if (CHIP != 710)
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-#endif
-    MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
-    WAIT DISCONNECT
-    INT int_norm_aborted
-
-#if (CHIP != 710)
-;
-; dsa_to_scratch
-; scratch_to_dsa
-;
-; PURPOSE :
-;      The NCR chips cannot do a move memory instruction with the DSA register 
-;      as the source or destination.  So, we provide a couple of subroutines
-;      that let us switch between the DSA register and scratch register.
-;
-;      Memory moves to/from the DSPS  register also don't work, but we 
-;      don't use them.
-;
-;
-
-dsa_to_scratch:
-    MOVE DSA0 TO SFBR
-    MOVE SFBR TO SCRATCH0
-    MOVE DSA1 TO SFBR
-    MOVE SFBR TO SCRATCH1
-    MOVE DSA2 TO SFBR
-    MOVE SFBR TO SCRATCH2
-    MOVE DSA3 TO SFBR
-    MOVE SFBR TO SCRATCH3
-    RETURN
-
-scratch_to_dsa:
-    MOVE SCRATCH0 TO SFBR
-    MOVE SFBR TO DSA0
-    MOVE SCRATCH1 TO SFBR
-    MOVE SFBR TO DSA1
-    MOVE SCRATCH2 TO SFBR
-    MOVE SFBR TO DSA2
-    MOVE SCRATCH3 TO SFBR
-    MOVE SFBR TO DSA3
-    RETURN
-#endif
-#if (CHIP == 710)
-; Little patched jump, used to overcome problems with TEMP getting
-; corrupted on memory moves.
-
-jump_temp:
-    JUMP 0
-#endif
diff --git a/drivers/scsi/53c7xx_d.h_shipped b/drivers/scsi/53c7xx_d.h_shipped
deleted file mode 100644 (file)
index 21d31b0..0000000
+++ /dev/null
@@ -1,2874 +0,0 @@
-/* DO NOT EDIT - Generated automatically by script_asm.pl */
-static u32 SCRIPT[] = {
-/*
-
-
-
-
-
-; 53c710 driver.  Modified from Drew Eckhardts driver
-; for 53c810 by Richard Hirst [richard@sleepie.demon.co.uk]
-;
-; I have left the script for the 53c8xx family in here, as it is likely
-; to be useful to see what I changed when bug hunting.
-
-; NCR 53c810 driver, main script
-; Sponsored by 
-;      iX Multiuser Multitasking Magazine
-;      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.
-;
-; PRE-ALPHA
-;
-; For more information, please consult 
-;
-; NCR 53C810
-; PCI-SCSI I/O Processor
-; Data Manual
-;
-; NCR 53C710 
-; SCSI I/O Processor
-; Programmers Guide
-;
-; NCR Microelectronics
-; 1635 Aeroplaza Drive
-; Colorado Springs, CO 80916
-; 1+ (719) 578-3400
-;
-; Toll free literature number
-; +1 (800) 334-5454
-;
-; IMPORTANT : This code is self modifying due to the limitations of 
-;      the NCR53c7,8xx series chips.  Persons debugging this code with
-;      the remote debugger should take this into account, and NOT set
-;      breakpoints in modified instructions.
-;
-; Design:
-; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard 
-; microcontroller using a simple instruction set.   
-;
-; So, to minimize the effects of interrupt latency, and to maximize 
-; throughput, this driver offloads the practical maximum amount 
-; of processing to the SCSI chip while still maintaining a common
-; structure.
-;
-; Where tradeoffs were needed between efficiency on the older
-; chips and the newer NCR53c800 series, the NCR53c800 series 
-; was chosen.
-;
-; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully
-; automate SCSI transfers without host processor intervention, this 
-; isn't the case with the NCR53c710 and newer chips which allow 
-;
-; - reads and writes to the internal registers from within the SCSI
-;      scripts, allowing the SCSI SCRIPTS(tm) code to save processor
-;      state so that multiple threads of execution are possible, and also
-;      provide an ALU for loop control, etc.
-; 
-; - table indirect addressing for some instructions. This allows 
-;      pointers to be located relative to the DSA ((Data Structure
-;      Address) register.
-;
-; These features make it possible to implement a mailbox style interface,
-; where the same piece of code is run to handle I/O for multiple threads
-; at once minimizing our need to relocate code.  Since the NCR53c700/
-; NCR53c800 series have a unique combination of features, making a 
-; a standard ingoing/outgoing mailbox system, costly, I've modified it.
-;
-; - Mailboxes are a mixture of code and data.  This lets us greatly
-;      simplify the NCR53c810 code and do things that would otherwise
-;      not be possible.
-;
-; The saved data pointer is now implemented as follows :
-;
-;      Control flow has been architected such that if control reaches
-;      munge_save_data_pointer, on a restore pointers message or 
-;      reconnection, a jump to the address formerly in the TEMP register
-;      will allow the SCSI command to resume execution.
-;
-
-;
-; Note : the DSA structures must be aligned on 32 bit boundaries,
-; since the source and destination of MOVE MEMORY instructions 
-; must share the same alignment and this is the alignment of the
-; NCR registers.
-;
-
-; For some systems (MVME166, for example) dmode is always the same, so don't
-; waste time writing it
-
-
-
-
-
-
-
-
-
-
-
-ABSOLUTE dsa_temp_lun = 0              ; Patch to lun for current dsa
-ABSOLUTE dsa_temp_next = 0             ; Patch to dsa next for current dsa
-ABSOLUTE dsa_temp_addr_next = 0                ; Patch to address of dsa next address 
-                                       ;       for current dsa
-ABSOLUTE dsa_temp_sync = 0             ; Patch to address of per-target
-                                       ;       sync routine
-ABSOLUTE dsa_sscf_710 = 0              ; Patch to address of per-target
-                                       ;       sscf value (53c710)
-ABSOLUTE dsa_temp_target = 0           ; Patch to id for current dsa
-ABSOLUTE dsa_temp_addr_saved_pointer = 0; Patch to address of per-command
-                                       ;       saved data pointer
-ABSOLUTE dsa_temp_addr_residual = 0    ; Patch to address of per-command
-                                       ;       current residual code
-ABSOLUTE dsa_temp_addr_saved_residual = 0; Patch to address of per-command
-                                       ; saved residual code
-ABSOLUTE dsa_temp_addr_new_value = 0   ; Address of value for JUMP operand
-ABSOLUTE dsa_temp_addr_array_value = 0         ; Address to copy to
-ABSOLUTE dsa_temp_addr_dsa_value = 0   ; Address of this DSA value
-
-;
-; Once a device has initiated reselection, we need to compare it 
-; against the singly linked list of commands which have disconnected
-; and are pending reselection.  These commands are maintained in 
-; an unordered singly linked list of DSA structures, through the
-; DSA pointers at their 'centers' headed by the reconnect_dsa_head
-; pointer.
-; 
-; To avoid complications in removing commands from the list,
-; I minimize the amount of expensive (at eight operations per
-; addition @ 500-600ns each) pointer operations which must
-; be done in the NCR driver by precomputing them on the 
-; host processor during dsa structure generation.
-;
-; The fixed-up per DSA code knows how to recognize the nexus
-; associated with the corresponding SCSI command, and modifies
-; the source and destination pointers for the MOVE MEMORY 
-; instruction which is executed when reselected_ok is called
-; to remove the command from the list.  Similarly, DSA is 
-; loaded with the address of the next DSA structure and
-; reselected_check_next is called if a failure occurs.
-;
-; Perhaps more concisely, the net effect of the mess is 
-;
-; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head, 
-;     src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) {
-;      src = &dsa->next;
-;      if (target_id == dsa->id && target_lun == dsa->lun) {
-;              *dest = *src;
-;              break;
-;         }    
-; }
-;
-; if (!dsa)
-;           error (int_err_unexpected_reselect);
-; else  
-;     longjmp (dsa->jump_resume, 0);
-;
-;      
-
-
-; Define DSA structure used for mailboxes
-ENTRY dsa_code_template
-dsa_code_template:
-ENTRY dsa_code_begin
-dsa_code_begin:
-; RGH: Don't care about TEMP and DSA here
-       
-       MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch
-
-at 0x00000000 : */     0xc0000004,0x00000000,0x00000000,
-/*
-       
-
-       MOVE MEMORY 4, addr_scratch, saved_dsa
-
-at 0x00000003 : */     0xc0000004,0x00000000,0x00000000,
-/*
-       ; We are about to go and select the device, so must set SSCF bits
-       MOVE MEMORY 4, dsa_sscf_710, addr_scratch
-
-at 0x00000006 : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-       MOVE SCRATCH3 TO SFBR
-
-at 0x00000009 : */     0x72370000,0x00000000,
-/*
-
-
-
-       MOVE SFBR TO SBCL
-
-at 0x0000000b : */     0x6a0b0000,0x00000000,
-/*
-       MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x0000000d : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-
-
-       CALL select
-
-at 0x00000010 : */     0x88080000,0x000001f8,
-/*
-; Handle the phase mismatch which may have resulted from the 
-; MOVE FROM dsa_msgout if we returned here.  The CLEAR ATN 
-; may or may not be necessary, and we should update script_asm.pl
-; to handle multiple pieces.
-    CLEAR ATN
-
-at 0x00000012 : */     0x60000008,0x00000000,
-/*
-    CLEAR ACK
-
-at 0x00000014 : */     0x60000040,0x00000000,
-/*
-
-; Replace second operand with address of JUMP instruction dest operand
-; in schedule table for this DSA.  Becomes dsa_jump_dest in 53c7,8xx.c.
-ENTRY dsa_code_fix_jump
-dsa_code_fix_jump:
-       MOVE MEMORY 4, NOP_insn, 0
-
-at 0x00000016 : */     0xc0000004,0x00000000,0x00000000,
-/*
-       JUMP select_done
-
-at 0x00000019 : */     0x80080000,0x00000230,
-/*
-
-; wrong_dsa loads the DSA register with the value of the dsa_next
-; field.
-;
-wrong_dsa:
-
-;                NOTE DSA is corrupt when we arrive here!
-
-;              Patch the MOVE MEMORY INSTRUCTION such that 
-;              the destination address is the address of the OLD 
-;              next pointer.
-;
-       MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok_patch + 8
-
-at 0x0000001b : */     0xc0000004,0x00000000,0x000007ec,
-/*
-       
-;
-;      Move the _contents_ of the next pointer into the DSA register as 
-;      the next I_T_L or I_T_L_Q tupple to check against the established
-;      nexus.
-;
-       MOVE MEMORY 4, dsa_temp_next, addr_scratch
-
-at 0x0000001e : */     0xc0000004,0x00000000,0x00000000,
-/*
-       
-
-       MOVE MEMORY 4, addr_scratch, saved_dsa
-
-at 0x00000021 : */     0xc0000004,0x00000000,0x00000000,
-/*
-       MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x00000024 : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-
-
-       JUMP reselected_check_next
-
-at 0x00000027 : */     0x80080000,0x000006f0,
-/*
-
-ABSOLUTE dsa_save_data_pointer = 0
-ENTRY dsa_code_save_data_pointer
-dsa_code_save_data_pointer:
-
-       ; When we get here, TEMP has been saved in jump_temp+4, DSA is corrupt
-       ; We MUST return with DSA correct
-       MOVE MEMORY 4, jump_temp+4, dsa_temp_addr_saved_pointer
-
-at 0x00000029 : */     0xc0000004,0x000009c8,0x00000000,
-/*
-; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
-       MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual
-
-at 0x0000002c : */     0xc0000018,0x00000000,0x00000000,
-/*
-        CLEAR ACK
-
-at 0x0000002f : */     0x60000040,0x00000000,
-/*
-
-
-
-       MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x00000031 : */     0xc0000004,0x00000000,0x00000000,
-/*
-       JUMP jump_temp
-
-at 0x00000034 : */     0x80080000,0x000009c4,
-/*
-
-ABSOLUTE dsa_restore_pointers = 0
-ENTRY dsa_code_restore_pointers
-dsa_code_restore_pointers:
-
-       ; TEMP and DSA are corrupt when we get here, but who cares!
-       MOVE MEMORY 4, dsa_temp_addr_saved_pointer, jump_temp + 4
-
-at 0x00000036 : */     0xc0000004,0x00000000,0x000009c8,
-/*
-; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
-       MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual
-
-at 0x00000039 : */     0xc0000018,0x00000000,0x00000000,
-/*
-        CLEAR ACK
-
-at 0x0000003c : */     0x60000040,0x00000000,
-/*
-       ; Restore DSA, note we don't care about TEMP
-       MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x0000003e : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-
-
-       JUMP jump_temp
-
-at 0x00000041 : */     0x80080000,0x000009c4,
-/*
-
-
-ABSOLUTE dsa_check_reselect = 0
-; dsa_check_reselect determines whether or not the current target and
-; lun match the current DSA
-ENTRY dsa_code_check_reselect
-dsa_code_check_reselect:
-
-       
-       
-       MOVE LCRC TO SFBR               ; LCRC has our ID and his ID bits set
-
-at 0x00000043 : */     0x72230000,0x00000000,
-/*
-       JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0x80
-
-at 0x00000045 : */     0x80848000,0x00ffff50,
-/*
-
-
-
-
-
-;
-; Hack - move to scratch first, since SFBR is not writeable
-;      via the CPU and hence a MOVE MEMORY instruction.
-;
-       
-       MOVE MEMORY 1, reselected_identify, addr_scratch
-
-at 0x00000047 : */     0xc0000001,0x00000000,0x00000000,
-/*
-       
-
-       ; BIG ENDIAN ON MVME16x
-       MOVE SCRATCH3 TO SFBR
-
-at 0x0000004a : */     0x72370000,0x00000000,
-/*
-
-
-
-; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips
-; Are you sure about that?  richard@sleepie.demon.co.uk
-       JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 0xf8
-
-at 0x0000004c : */     0x8084f800,0x00ffff34,
-/*
-;              Patch the MOVE MEMORY INSTRUCTION such that
-;              the source address is the address of this dsa's
-;              next pointer.
-       MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok_patch + 4
-
-at 0x0000004e : */     0xc0000004,0x00000000,0x000007e8,
-/*
-       CALL reselected_ok
-
-at 0x00000051 : */     0x88080000,0x00000798,
-/*
-
-;      Restore DSA following memory moves in reselected_ok
-;      dsa_temp_sync doesn't really care about DSA, but it has an
-;      optional debug INT so a valid DSA is a good idea.
-       MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x00000053 : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-       CALL dsa_temp_sync      
-
-at 0x00000056 : */     0x88080000,0x00000000,
-/*
-; Release ACK on the IDENTIFY message _after_ we've set the synchronous 
-; transfer parameters! 
-       CLEAR ACK
-
-at 0x00000058 : */     0x60000040,0x00000000,
-/*
-; Implicitly restore pointers on reselection, so a RETURN
-; will transfer control back to the right spot.
-       CALL REL (dsa_code_restore_pointers)
-
-at 0x0000005a : */     0x88880000,0x00ffff68,
-/*
-       RETURN
-
-at 0x0000005c : */     0x90080000,0x00000000,
-/*
-ENTRY dsa_zero
-dsa_zero:
-ENTRY dsa_code_template_end
-dsa_code_template_end:
-
-; Perform sanity check for dsa_fields_start == dsa_code_template_end - 
-; dsa_zero, puke.
-
-ABSOLUTE dsa_fields_start =  0 ; Sanity marker
-                               ;       pad 48 bytes (fix this RSN)
-ABSOLUTE dsa_next = 48         ; len 4 Next DSA
-                               ; del 4 Previous DSA address
-ABSOLUTE dsa_cmnd = 56         ; len 4 Scsi_Cmnd * for this thread.
-ABSOLUTE dsa_select = 60       ; len 4 Device ID, Period, Offset for 
-                               ;       table indirect select
-ABSOLUTE dsa_msgout = 64       ; len 8 table indirect move parameter for 
-                               ;       select message
-ABSOLUTE dsa_cmdout = 72       ; len 8 table indirect move parameter for 
-                               ;       command
-ABSOLUTE dsa_dataout = 80      ; len 4 code pointer for dataout
-ABSOLUTE dsa_datain = 84       ; len 4 code pointer for datain
-ABSOLUTE dsa_msgin = 88                ; len 8 table indirect move for msgin
-ABSOLUTE dsa_status = 96       ; len 8 table indirect move for status byte
-ABSOLUTE dsa_msgout_other = 104        ; len 8 table indirect for normal message out
-                               ; (Synchronous transfer negotiation, etc).
-ABSOLUTE dsa_end = 112
-
-ABSOLUTE schedule = 0          ; Array of JUMP dsa_begin or JUMP (next),
-                               ; terminated by a call to JUMP wait_reselect
-
-; Linked lists of DSA structures
-ABSOLUTE reconnect_dsa_head = 0        ; Link list of DSAs which can reconnect
-ABSOLUTE addr_reconnect_dsa_head = 0 ; Address of variable containing
-                               ; address of reconnect_dsa_head
-
-; These select the source and destination of a MOVE MEMORY instruction
-ABSOLUTE dmode_memory_to_memory = 0x0
-ABSOLUTE dmode_memory_to_ncr = 0x0
-ABSOLUTE dmode_ncr_to_memory = 0x0
-
-ABSOLUTE addr_scratch = 0x0
-ABSOLUTE addr_temp = 0x0
-
-ABSOLUTE saved_dsa = 0x0
-ABSOLUTE emulfly = 0x0
-ABSOLUTE addr_dsa = 0x0
-
-
-
-; Interrupts - 
-; MSB indicates type
-; 0    handle error condition
-; 1    handle message 
-; 2    handle normal condition
-; 3    debugging interrupt
-; 4    testing interrupt 
-; Next byte indicates specific error
-
-; XXX not yet implemented, I'm not sure if I want to - 
-; Next byte indicates the routine the error occurred in
-; The LSB indicates the specific place the error occurred
-ABSOLUTE int_err_unexpected_phase = 0x00000000 ; Unexpected phase encountered
-ABSOLUTE int_err_selected = 0x00010000         ; SELECTED (nee RESELECTED)
-ABSOLUTE int_err_unexpected_reselect = 0x00020000 
-ABSOLUTE int_err_check_condition = 0x00030000  
-ABSOLUTE int_err_no_phase = 0x00040000
-ABSOLUTE int_msg_wdtr = 0x01000000             ; WDTR message received
-ABSOLUTE int_msg_sdtr = 0x01010000             ; SDTR received
-ABSOLUTE int_msg_1 = 0x01020000                        ; single byte special message
-                                               ; received
-
-ABSOLUTE int_norm_select_complete = 0x02000000 ; Select complete, reprogram
-                                               ; registers.
-ABSOLUTE int_norm_reselect_complete = 0x02010000       ; Nexus established
-ABSOLUTE int_norm_command_complete = 0x02020000 ; Command complete
-ABSOLUTE int_norm_disconnected = 0x02030000    ; Disconnected 
-ABSOLUTE int_norm_aborted =0x02040000          ; Aborted *dsa
-ABSOLUTE int_norm_reset = 0x02050000           ; Generated BUS reset.
-ABSOLUTE int_norm_emulateintfly = 0x02060000   ; 53C710 Emulated intfly
-ABSOLUTE int_debug_break = 0x03000000          ; Break point
-
-ABSOLUTE int_debug_panic = 0x030b0000          ; Panic driver
-
-
-ABSOLUTE int_test_1 = 0x04000000               ; Test 1 complete
-ABSOLUTE int_test_2 = 0x04010000               ; Test 2 complete
-ABSOLUTE int_test_3 = 0x04020000               ; Test 3 complete
-
-
-; These should start with 0x05000000, with low bits incrementing for 
-; each one.
-
-
-                                               
-ABSOLUTE NCR53c7xx_msg_abort = 0       ; Pointer to abort message
-ABSOLUTE NCR53c7xx_msg_reject = 0       ; Pointer to reject message
-ABSOLUTE NCR53c7xx_zero        = 0             ; long with zero in it, use for source
-ABSOLUTE NCR53c7xx_sink = 0            ; long to dump worthless data in
-ABSOLUTE NOP_insn = 0                  ; NOP instruction
-
-; Pointer to message, potentially multi-byte
-ABSOLUTE msg_buf = 0
-
-; Pointer to holding area for reselection information
-ABSOLUTE reselected_identify = 0
-ABSOLUTE reselected_tag = 0
-
-; Request sense command pointer, it's a 6 byte command, should
-; be constant for all commands since we always want 16 bytes of 
-; sense and we don't need to change any fields as we did under 
-; SCSI-I when we actually cared about the LUN field.
-;EXTERNAL NCR53c7xx_sense              ; Request sense command
-
-
-; dsa_schedule  
-; PURPOSE : after a DISCONNECT message has been received, and pointers
-;      saved, insert the current DSA structure at the head of the 
-;      disconnected queue and fall through to the scheduler.
-;
-; CALLS : OK
-;
-; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list
-;      of disconnected commands
-;
-; MODIFIES : SCRATCH, reconnect_dsa_head
-; 
-; EXITS : always passes control to schedule
-
-ENTRY dsa_schedule
-dsa_schedule:
-
-
-
-
-;
-; Calculate the address of the next pointer within the DSA 
-; structure of the command that is currently disconnecting
-;
-
-    ; Read what should be the current DSA from memory - actual DSA
-    ; register is probably corrupt
-    MOVE MEMORY 4, saved_dsa, addr_scratch
-
-at 0x0000005e : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-
-
-    MOVE SCRATCH0 + dsa_next TO SCRATCH0
-
-at 0x00000061 : */     0x7e343000,0x00000000,
-/*
-    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
-
-at 0x00000063 : */     0x7f350000,0x00000000,
-/*
-    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
-
-at 0x00000065 : */     0x7f360000,0x00000000,
-/*
-    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
-
-at 0x00000067 : */     0x7f370000,0x00000000,
-/*
-
-; Point the next field of this DSA structure at the current disconnected 
-; list
-    
-    MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8
-
-at 0x00000069 : */     0xc0000004,0x00000000,0x000001b8,
-/*
-    
-dsa_schedule_insert:
-    MOVE MEMORY 4, reconnect_dsa_head, 0 
-
-at 0x0000006c : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-; And update the head pointer.
-
-    ; Read what should be the current DSA from memory - actual DSA
-    ; register is probably corrupt
-    MOVE MEMORY 4, saved_dsa, addr_scratch
-
-at 0x0000006f : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-
-
-    
-    MOVE MEMORY 4, addr_scratch, reconnect_dsa_head
-
-at 0x00000072 : */     0xc0000004,0x00000000,0x00000000,
-/*
-    
-
-
-
-
-
-    CLEAR ACK
-
-at 0x00000075 : */     0x60000040,0x00000000,
-/*
-
-
-    ; Time to correct DSA following memory move
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x00000077 : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-    WAIT DISCONNECT
-
-at 0x0000007a : */     0x48000000,0x00000000,
-/*
-
-
-
-
-
-
-    JUMP schedule
-
-at 0x0000007c : */     0x80080000,0x00000000,
-/*
-
-
-;
-; select
-;
-; PURPOSE : establish a nexus for the SCSI command referenced by DSA.
-;      On success, the current DSA structure is removed from the issue 
-;      queue.  Usually, this is entered as a fall-through from schedule,
-;      although the contingent allegiance handling code will write
-;      the select entry address to the DSP to restart a command as a 
-;      REQUEST SENSE.  A message is sent (usually IDENTIFY, although
-;      additional SDTR or WDTR messages may be sent).  COMMAND OUT
-;      is handled.
-;
-; INPUTS : DSA - SCSI command, issue_dsa_head
-;
-; CALLS : NOT OK
-;
-; MODIFIES : SCRATCH, issue_dsa_head
-;
-; EXITS : on reselection or selection, go to select_failed
-;      otherwise, RETURN so control is passed back to 
-;      dsa_begin.
-;
-
-ENTRY select
-select:
-
-
-
-
-
-
-
-
-    CLEAR TARGET
-
-at 0x0000007e : */     0x60000200,0x00000000,
-/*
-
-; XXX
-;
-; In effect, SELECTION operations are backgrounded, with execution
-; continuing until code which waits for REQ or a fatal interrupt is 
-; encountered.
-;
-; So, for more performance, we could overlap the code which removes 
-; the command from the NCRs issue queue with the selection, but 
-; at this point I don't want to deal with the error recovery.
-;
-
-
-
-    ; Enable selection timer
-
-
-
-    MOVE CTEST7 & 0xef TO CTEST7
-
-at 0x00000080 : */     0x7c1bef00,0x00000000,
-/*
-
-
-    SELECT ATN FROM dsa_select, select_failed
-
-at 0x00000082 : */     0x4300003c,0x00000828,
-/*
-    JUMP select_msgout, WHEN MSG_OUT
-
-at 0x00000084 : */     0x860b0000,0x00000218,
-/*
-ENTRY select_msgout
-select_msgout:
-
-    ; Disable selection timer
-    MOVE CTEST7 | 0x10 TO CTEST7
-
-at 0x00000086 : */     0x7a1b1000,0x00000000,
-/*
-
-    MOVE FROM dsa_msgout, WHEN MSG_OUT
-
-at 0x00000088 : */     0x1e000000,0x00000040,
-/*
-
-
-
-
-
-
-
-
-
-
-   RETURN
-
-at 0x0000008a : */     0x90080000,0x00000000,
-/*
-
-; 
-; select_done
-; 
-; PURPOSE: continue on to normal data transfer; called as the exit 
-;      point from dsa_begin.
-;
-; INPUTS: dsa
-;
-; CALLS: OK
-;
-;
-
-select_done:
-
-; NOTE DSA is corrupt when we arrive here!
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x0000008c : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-
-
-
-
-
-
-
-; After a successful selection, we should get either a CMD phase or 
-; some transfer request negotiation message.
-
-    JUMP cmdout, WHEN CMD
-
-at 0x0000008f : */     0x820b0000,0x0000025c,
-/*
-    INT int_err_unexpected_phase, WHEN NOT MSG_IN 
-
-at 0x00000091 : */     0x9f030000,0x00000000,
-/*
-
-select_msg_in:
-    CALL msg_in, WHEN MSG_IN
-
-at 0x00000093 : */     0x8f0b0000,0x0000041c,
-/*
-    JUMP select_msg_in, WHEN MSG_IN
-
-at 0x00000095 : */     0x870b0000,0x0000024c,
-/*
-
-cmdout:
-    INT int_err_unexpected_phase, WHEN NOT CMD
-
-at 0x00000097 : */     0x9a030000,0x00000000,
-/*
-
-
-
-ENTRY cmdout_cmdout
-cmdout_cmdout:
-
-    MOVE FROM dsa_cmdout, WHEN CMD
-
-at 0x00000099 : */     0x1a000000,0x00000048,
-/*
-
-
-
-
-;
-; data_transfer  
-; other_out
-; other_in
-; other_transfer
-;
-; PURPOSE : handle the main data transfer for a SCSI command in 
-;      several parts.  In the first part, data_transfer, DATA_IN
-;      and DATA_OUT phases are allowed, with the user provided
-;      code (usually dynamically generated based on the scatter/gather
-;      list associated with a SCSI command) called to handle these 
-;      phases.
-;
-;      After control has passed to one of the user provided 
-;      DATA_IN or DATA_OUT routines, back calls are made to 
-;      other_transfer_in or other_transfer_out to handle non-DATA IN
-;      and DATA OUT phases respectively, with the state of the active
-;      data pointer being preserved in TEMP.
-;
-;      On completion, the user code passes control to other_transfer
-;      which causes DATA_IN and DATA_OUT to result in unexpected_phase
-;      interrupts so that data overruns may be trapped.
-;
-; INPUTS : DSA - SCSI command
-;
-; CALLS : OK in data_transfer_start, not ok in other_out and other_in, ok in
-;      other_transfer
-;
-; MODIFIES : SCRATCH
-;
-; EXITS : if STATUS IN is detected, signifying command completion,
-;      the NCR jumps to command_complete.  If MSG IN occurs, a 
-;      CALL is made to msg_in.  Otherwise, other_transfer runs in 
-;      an infinite loop.
-;      
-
-ENTRY data_transfer
-data_transfer:
-    JUMP cmdout_cmdout, WHEN CMD
-
-at 0x0000009b : */     0x820b0000,0x00000264,
-/*
-    CALL msg_in, WHEN MSG_IN
-
-at 0x0000009d : */     0x8f0b0000,0x0000041c,
-/*
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-
-at 0x0000009f : */     0x9e0b0000,0x00000000,
-/*
-    JUMP do_dataout, WHEN DATA_OUT
-
-at 0x000000a1 : */     0x800b0000,0x000002a4,
-/*
-    JUMP do_datain, WHEN DATA_IN
-
-at 0x000000a3 : */     0x810b0000,0x000002fc,
-/*
-    JUMP command_complete, WHEN STATUS
-
-at 0x000000a5 : */     0x830b0000,0x0000065c,
-/*
-    JUMP data_transfer
-
-at 0x000000a7 : */     0x80080000,0x0000026c,
-/*
-ENTRY end_data_transfer
-end_data_transfer:
-
-;
-; FIXME: On NCR53c700 and NCR53c700-66 chips, do_dataout/do_datain 
-; should be fixed up whenever the nexus changes so it can point to the 
-; correct routine for that command.
-;
-
-
-; Nasty jump to dsa->dataout
-do_dataout:
-
-    MOVE MEMORY 4, saved_dsa, addr_scratch
-
-at 0x000000a9 : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-
-
-    MOVE SCRATCH0 + dsa_dataout TO SCRATCH0    
-
-at 0x000000ac : */     0x7e345000,0x00000000,
-/*
-    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY 
-
-at 0x000000ae : */     0x7f350000,0x00000000,
-/*
-    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY 
-
-at 0x000000b0 : */     0x7f360000,0x00000000,
-/*
-    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY 
-
-at 0x000000b2 : */     0x7f370000,0x00000000,
-/*
-    
-    MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4
-
-at 0x000000b4 : */     0xc0000004,0x00000000,0x000002e0,
-/*
-    
-dataout_to_jump:
-    MOVE MEMORY 4, 0, dataout_jump + 4 
-
-at 0x000000b7 : */     0xc0000004,0x00000000,0x000002f8,
-/*
-
-    ; Time to correct DSA following memory move
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x000000ba : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-dataout_jump:
-    JUMP 0
-
-at 0x000000bd : */     0x80080000,0x00000000,
-/*
-
-; Nasty jump to dsa->dsain
-do_datain:
-
-    MOVE MEMORY 4, saved_dsa, addr_scratch
-
-at 0x000000bf : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-
-
-    MOVE SCRATCH0 + dsa_datain TO SCRATCH0     
-
-at 0x000000c2 : */     0x7e345400,0x00000000,
-/*
-    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY 
-
-at 0x000000c4 : */     0x7f350000,0x00000000,
-/*
-    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY 
-
-at 0x000000c6 : */     0x7f360000,0x00000000,
-/*
-    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY 
-
-at 0x000000c8 : */     0x7f370000,0x00000000,
-/*
-    
-    MOVE MEMORY 4, addr_scratch, datain_to_jump + 4
-
-at 0x000000ca : */     0xc0000004,0x00000000,0x00000338,
-/*
-    
-ENTRY datain_to_jump
-datain_to_jump:
-    MOVE MEMORY 4, 0, datain_jump + 4
-
-at 0x000000cd : */     0xc0000004,0x00000000,0x00000350,
-/*
-
-    ; Time to correct DSA following memory move
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x000000d0 : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-
-
-
-datain_jump:
-    JUMP 0
-
-at 0x000000d3 : */     0x80080000,0x00000000,
-/*
-
-
-
-; Note that other_out and other_in loop until a non-data phase
-; is discovered, so we only execute return statements when we
-; can go on to the next data phase block move statement.
-
-ENTRY other_out
-other_out:
-
-
-
-    INT int_err_unexpected_phase, WHEN CMD
-
-at 0x000000d5 : */     0x9a0b0000,0x00000000,
-/*
-    JUMP msg_in_restart, WHEN MSG_IN 
-
-at 0x000000d7 : */     0x870b0000,0x000003fc,
-/*
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-
-at 0x000000d9 : */     0x9e0b0000,0x00000000,
-/*
-    INT int_err_unexpected_phase, WHEN DATA_IN
-
-at 0x000000db : */     0x990b0000,0x00000000,
-/*
-    JUMP command_complete, WHEN STATUS
-
-at 0x000000dd : */     0x830b0000,0x0000065c,
-/*
-    JUMP other_out, WHEN NOT DATA_OUT
-
-at 0x000000df : */     0x80030000,0x00000354,
-/*
-
-; TEMP should be OK, as we got here from a call in the user dataout code.
-
-    RETURN
-
-at 0x000000e1 : */     0x90080000,0x00000000,
-/*
-
-ENTRY other_in
-other_in:
-
-
-
-    INT int_err_unexpected_phase, WHEN CMD
-
-at 0x000000e3 : */     0x9a0b0000,0x00000000,
-/*
-    JUMP msg_in_restart, WHEN MSG_IN 
-
-at 0x000000e5 : */     0x870b0000,0x000003fc,
-/*
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-
-at 0x000000e7 : */     0x9e0b0000,0x00000000,
-/*
-    INT int_err_unexpected_phase, WHEN DATA_OUT
-
-at 0x000000e9 : */     0x980b0000,0x00000000,
-/*
-    JUMP command_complete, WHEN STATUS
-
-at 0x000000eb : */     0x830b0000,0x0000065c,
-/*
-    JUMP other_in, WHEN NOT DATA_IN
-
-at 0x000000ed : */     0x81030000,0x0000038c,
-/*
-
-; TEMP should be OK, as we got here from a call in the user datain code.
-
-    RETURN
-
-at 0x000000ef : */     0x90080000,0x00000000,
-/*
-
-
-ENTRY other_transfer
-other_transfer:
-    INT int_err_unexpected_phase, WHEN CMD
-
-at 0x000000f1 : */     0x9a0b0000,0x00000000,
-/*
-    CALL msg_in, WHEN MSG_IN
-
-at 0x000000f3 : */     0x8f0b0000,0x0000041c,
-/*
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-
-at 0x000000f5 : */     0x9e0b0000,0x00000000,
-/*
-    INT int_err_unexpected_phase, WHEN DATA_OUT
-
-at 0x000000f7 : */     0x980b0000,0x00000000,
-/*
-    INT int_err_unexpected_phase, WHEN DATA_IN
-
-at 0x000000f9 : */     0x990b0000,0x00000000,
-/*
-    JUMP command_complete, WHEN STATUS
-
-at 0x000000fb : */     0x830b0000,0x0000065c,
-/*
-    JUMP other_transfer
-
-at 0x000000fd : */     0x80080000,0x000003c4,
-/*
-
-;
-; msg_in_restart
-; msg_in
-; munge_msg
-;
-; PURPOSE : process messages from a target.  msg_in is called when the 
-;      caller hasn't read the first byte of the message.  munge_message
-;      is called when the caller has read the first byte of the message,
-;      and left it in SFBR.  msg_in_restart is called when the caller 
-;      hasn't read the first byte of the message, and wishes RETURN
-;      to transfer control back to the address of the conditional
-;      CALL instruction rather than to the instruction after it.
-;
-;      Various int_* interrupts are generated when the host system
-;      needs to intervene, as is the case with SDTR, WDTR, and
-;      INITIATE RECOVERY messages.
-;
-;      When the host system handles one of these interrupts,
-;      it can respond by reentering at reject_message, 
-;      which rejects the message and returns control to
-;      the caller of msg_in or munge_msg, accept_message
-;      which clears ACK and returns control, or reply_message
-;      which sends the message pointed to by the DSA 
-;      msgout_other table indirect field.
-;
-;      DISCONNECT messages are handled by moving the command
-;      to the reconnect_dsa_queue.
-
-; NOTE: DSA should be valid when we get here - we cannot save both it
-;      and TEMP in this routine.
-
-;
-; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg
-;      only)
-;
-; CALLS : NO.  The TEMP register isn't backed up to allow nested calls.
-;
-; MODIFIES : SCRATCH, DSA on DISCONNECT
-;
-; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS,
-;      and normal return from message handlers running under
-;      Linux, control is returned to the caller.  Receipt
-;      of DISCONNECT messages pass control to dsa_schedule.
-;
-ENTRY msg_in_restart
-msg_in_restart:
-; XXX - hackish
-;
-; Since it's easier to debug changes to the statically 
-; compiled code, rather than the dynamically generated 
-; stuff, such as
-;
-;      MOVE x, y, WHEN data_phase
-;      CALL other_z, WHEN NOT data_phase
-;      MOVE x, y, WHEN data_phase
-;
-; I'd like to have certain routines (notably the message handler)
-; restart on the conditional call rather than the next instruction.
-;
-; So, subtract 8 from the return address
-
-    MOVE TEMP0 + 0xf8 TO TEMP0
-
-at 0x000000ff : */     0x7e1cf800,0x00000000,
-/*
-    MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY
-
-at 0x00000101 : */     0x7f1dff00,0x00000000,
-/*
-    MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY
-
-at 0x00000103 : */     0x7f1eff00,0x00000000,
-/*
-    MOVE TEMP3 + 0xff TO TEMP3 WITH CARRY
-
-at 0x00000105 : */     0x7f1fff00,0x00000000,
-/*
-
-ENTRY msg_in
-msg_in:
-    MOVE 1, msg_buf, WHEN MSG_IN
-
-at 0x00000107 : */     0x0f000001,0x00000000,
-/*
-
-munge_msg:
-    JUMP munge_extended, IF 0x01               ; EXTENDED MESSAGE
-
-at 0x00000109 : */     0x800c0001,0x00000574,
-/*
-    JUMP munge_2, IF 0x20, AND MASK 0xdf       ; two byte message
-
-at 0x0000010b : */     0x800cdf20,0x00000464,
-/*
-;
-; XXX - I've seen a handful of broken SCSI devices which fail to issue
-;      a SAVE POINTERS message before disconnecting in the middle of 
-;      a transfer, assuming that the DATA POINTER will be implicitly 
-;      restored.  
-;
-; Historically, I've often done an implicit save when the DISCONNECT
-; message is processed.  We may want to consider having the option of 
-; doing that here. 
-;
-    JUMP munge_save_data_pointer, IF 0x02      ; SAVE DATA POINTER
-
-at 0x0000010d : */     0x800c0002,0x0000046c,
-/*
-    JUMP munge_restore_pointers, IF 0x03       ; RESTORE POINTERS 
-
-at 0x0000010f : */     0x800c0003,0x00000518,
-/*
-    JUMP munge_disconnect, IF 0x04             ; DISCONNECT
-
-at 0x00000111 : */     0x800c0004,0x0000056c,
-/*
-    INT int_msg_1, IF 0x07                     ; MESSAGE REJECT
-
-at 0x00000113 : */     0x980c0007,0x01020000,
-/*
-    INT int_msg_1, IF 0x0f                     ; INITIATE RECOVERY
-
-at 0x00000115 : */     0x980c000f,0x01020000,
-/*
-
-
-
-    JUMP reject_message
-
-at 0x00000117 : */     0x80080000,0x00000604,
-/*
-
-munge_2:
-    JUMP reject_message
-
-at 0x00000119 : */     0x80080000,0x00000604,
-/*
-;
-; The SCSI standard allows targets to recover from transient 
-; error conditions by backing up the data pointer with a 
-; RESTORE POINTERS message.  
-;      
-; So, we must save and restore the _residual_ code as well as 
-; the current instruction pointer.  Because of this messiness,
-; it is simpler to put dynamic code in the dsa for this and to
-; just do a simple jump down there. 
-;
-
-munge_save_data_pointer:
-
-    ; We have something in TEMP here, so first we must save that
-    MOVE TEMP0 TO SFBR
-
-at 0x0000011b : */     0x721c0000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH0
-
-at 0x0000011d : */     0x6a340000,0x00000000,
-/*
-    MOVE TEMP1 TO SFBR
-
-at 0x0000011f : */     0x721d0000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH1
-
-at 0x00000121 : */     0x6a350000,0x00000000,
-/*
-    MOVE TEMP2 TO SFBR
-
-at 0x00000123 : */     0x721e0000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH2
-
-at 0x00000125 : */     0x6a360000,0x00000000,
-/*
-    MOVE TEMP3 TO SFBR
-
-at 0x00000127 : */     0x721f0000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH3
-
-at 0x00000129 : */     0x6a370000,0x00000000,
-/*
-    MOVE MEMORY 4, addr_scratch, jump_temp + 4
-
-at 0x0000012b : */     0xc0000004,0x00000000,0x000009c8,
-/*
-    ; Now restore DSA
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x0000012e : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-    MOVE DSA0 + dsa_save_data_pointer TO SFBR
-
-at 0x00000131 : */     0x76100000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH0
-
-at 0x00000133 : */     0x6a340000,0x00000000,
-/*
-    MOVE DSA1 + 0xff TO SFBR WITH CARRY
-
-at 0x00000135 : */     0x7711ff00,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH1
-
-at 0x00000137 : */     0x6a350000,0x00000000,
-/*
-    MOVE DSA2 + 0xff TO SFBR WITH CARRY 
-
-at 0x00000139 : */     0x7712ff00,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH2
-
-at 0x0000013b : */     0x6a360000,0x00000000,
-/*
-    MOVE DSA3 + 0xff TO SFBR WITH CARRY
-
-at 0x0000013d : */     0x7713ff00,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH3
-
-at 0x0000013f : */     0x6a370000,0x00000000,
-/*
-
-    
-    MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4
-
-at 0x00000141 : */     0xc0000004,0x00000000,0x00000514,
-/*
-    
-jump_dsa_save:
-    JUMP 0
-
-at 0x00000144 : */     0x80080000,0x00000000,
-/*
-
-munge_restore_pointers:
-
-    ; The code at dsa_restore_pointers will RETURN, but we don't care
-    ; about TEMP here, as it will overwrite it anyway.
-
-    MOVE DSA0 + dsa_restore_pointers TO SFBR
-
-at 0x00000146 : */     0x76100000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH0
-
-at 0x00000148 : */     0x6a340000,0x00000000,
-/*
-    MOVE DSA1 + 0xff TO SFBR WITH CARRY
-
-at 0x0000014a : */     0x7711ff00,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH1
-
-at 0x0000014c : */     0x6a350000,0x00000000,
-/*
-    MOVE DSA2 + 0xff TO SFBR WITH CARRY
-
-at 0x0000014e : */     0x7712ff00,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH2
-
-at 0x00000150 : */     0x6a360000,0x00000000,
-/*
-    MOVE DSA3 + 0xff TO SFBR WITH CARRY
-
-at 0x00000152 : */     0x7713ff00,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH3
-
-at 0x00000154 : */     0x6a370000,0x00000000,
-/*
-
-    
-    MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4
-
-at 0x00000156 : */     0xc0000004,0x00000000,0x00000568,
-/*
-    
-jump_dsa_restore:
-    JUMP 0
-
-at 0x00000159 : */     0x80080000,0x00000000,
-/*
-
-
-munge_disconnect:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    JUMP dsa_schedule
-
-at 0x0000015b : */     0x80080000,0x00000178,
-/*
-
-
-
-
-
-munge_extended:
-    CLEAR ACK
-
-at 0x0000015d : */     0x60000040,0x00000000,
-/*
-    INT int_err_unexpected_phase, WHEN NOT MSG_IN
-
-at 0x0000015f : */     0x9f030000,0x00000000,
-/*
-    MOVE 1, msg_buf + 1, WHEN MSG_IN
-
-at 0x00000161 : */     0x0f000001,0x00000001,
-/*
-    JUMP munge_extended_2, IF 0x02
-
-at 0x00000163 : */     0x800c0002,0x000005a4,
-/*
-    JUMP munge_extended_3, IF 0x03 
-
-at 0x00000165 : */     0x800c0003,0x000005d4,
-/*
-    JUMP reject_message
-
-at 0x00000167 : */     0x80080000,0x00000604,
-/*
-
-munge_extended_2:
-    CLEAR ACK
-
-at 0x00000169 : */     0x60000040,0x00000000,
-/*
-    MOVE 1, msg_buf + 2, WHEN MSG_IN
-
-at 0x0000016b : */     0x0f000001,0x00000002,
-/*
-    JUMP reject_message, IF NOT 0x02   ; Must be WDTR
-
-at 0x0000016d : */     0x80040002,0x00000604,
-/*
-    CLEAR ACK
-
-at 0x0000016f : */     0x60000040,0x00000000,
-/*
-    MOVE 1, msg_buf + 3, WHEN MSG_IN
-
-at 0x00000171 : */     0x0f000001,0x00000003,
-/*
-    INT int_msg_wdtr
-
-at 0x00000173 : */     0x98080000,0x01000000,
-/*
-
-munge_extended_3:
-    CLEAR ACK
-
-at 0x00000175 : */     0x60000040,0x00000000,
-/*
-    MOVE 1, msg_buf + 2, WHEN MSG_IN
-
-at 0x00000177 : */     0x0f000001,0x00000002,
-/*
-    JUMP reject_message, IF NOT 0x01   ; Must be SDTR
-
-at 0x00000179 : */     0x80040001,0x00000604,
-/*
-    CLEAR ACK
-
-at 0x0000017b : */     0x60000040,0x00000000,
-/*
-    MOVE 2, msg_buf + 3, WHEN MSG_IN
-
-at 0x0000017d : */     0x0f000002,0x00000003,
-/*
-    INT int_msg_sdtr
-
-at 0x0000017f : */     0x98080000,0x01010000,
-/*
-
-ENTRY reject_message
-reject_message:
-    SET ATN
-
-at 0x00000181 : */     0x58000008,0x00000000,
-/*
-    CLEAR ACK
-
-at 0x00000183 : */     0x60000040,0x00000000,
-/*
-    MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
-
-at 0x00000185 : */     0x0e000001,0x00000000,
-/*
-    RETURN
-
-at 0x00000187 : */     0x90080000,0x00000000,
-/*
-
-ENTRY accept_message
-accept_message:
-    CLEAR ATN
-
-at 0x00000189 : */     0x60000008,0x00000000,
-/*
-    CLEAR ACK
-
-at 0x0000018b : */     0x60000040,0x00000000,
-/*
-    RETURN
-
-at 0x0000018d : */     0x90080000,0x00000000,
-/*
-
-ENTRY respond_message
-respond_message:
-    SET ATN
-
-at 0x0000018f : */     0x58000008,0x00000000,
-/*
-    CLEAR ACK
-
-at 0x00000191 : */     0x60000040,0x00000000,
-/*
-    MOVE FROM dsa_msgout_other, WHEN MSG_OUT
-
-at 0x00000193 : */     0x1e000000,0x00000068,
-/*
-    RETURN
-
-at 0x00000195 : */     0x90080000,0x00000000,
-/*
-
-;
-; command_complete
-;
-; PURPOSE : handle command termination when STATUS IN is detected by reading
-;      a status byte followed by a command termination message. 
-;
-;      Normal termination results in an INTFLY instruction, and 
-;      the host system can pick out which command terminated by 
-;      examining the MESSAGE and STATUS buffers of all currently 
-;      executing commands;
-;
-;      Abnormal (CHECK_CONDITION) termination results in an
-;      int_err_check_condition interrupt so that a REQUEST SENSE
-;      command can be issued out-of-order so that no other command
-;      clears the contingent allegiance condition.
-;      
-;
-; INPUTS : DSA - command       
-;
-; CALLS : OK
-;
-; EXITS : On successful termination, control is passed to schedule.
-;      On abnormal termination, the user will usually modify the 
-;      DSA fields and corresponding buffers and return control
-;      to select.
-;
-
-ENTRY command_complete
-command_complete:
-    MOVE FROM dsa_status, WHEN STATUS
-
-at 0x00000197 : */     0x1b000000,0x00000060,
-/*
-
-    MOVE SFBR TO SCRATCH0              ; Save status
-
-at 0x00000199 : */     0x6a340000,0x00000000,
-/*
-
-ENTRY command_complete_msgin
-command_complete_msgin:
-    MOVE FROM dsa_msgin, WHEN MSG_IN
-
-at 0x0000019b : */     0x1f000000,0x00000058,
-/*
-; Indicate that we should be expecting a disconnect
-
-
-
-    ; Above code cleared the Unexpected Disconnect bit, what do we do?
-
-    CLEAR ACK
-
-at 0x0000019d : */     0x60000040,0x00000000,
-/*
-
-    WAIT DISCONNECT
-
-at 0x0000019f : */     0x48000000,0x00000000,
-/*
-
-;
-; The SCSI specification states that when a UNIT ATTENTION condition
-; is pending, as indicated by a CHECK CONDITION status message,
-; the target shall revert to asynchronous transfers.  Since
-; synchronous transfers parameters are maintained on a per INITIATOR/TARGET 
-; basis, and returning control to our scheduler could work on a command
-; running on another lun on that target using the old parameters, we must
-; interrupt the host processor to get them changed, or change them ourselves.
-;
-; Once SCSI-II tagged queueing is implemented, things will be even more
-; hairy, since contingent allegiance conditions exist on a per-target/lun
-; basis, and issuing a new command with a different tag would clear it.
-; In these cases, we must interrupt the host processor to get a request 
-; added to the HEAD of the queue with the request sense command, or we
-; must automatically issue the request sense command.
-
-
-
-
-
-
-
-    INT int_norm_emulateintfly
-
-at 0x000001a1 : */     0x98080000,0x02060000,
-/*
-
-
-
-
-
-
-    ; Time to correct DSA following memory move
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x000001a3 : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-
-
-
-
-    JUMP schedule
-
-at 0x000001a6 : */     0x80080000,0x00000000,
-/*
-command_failed:
-    INT int_err_check_condition
-
-at 0x000001a8 : */     0x98080000,0x00030000,
-/*
-
-
-
-
-;
-; wait_reselect
-;
-; PURPOSE : This is essentially the idle routine, where control lands
-;      when there are no new processes to schedule.  wait_reselect
-;      waits for reselection, selection, and new commands.
-;
-;      When a successful reselection occurs, with the aid 
-;      of fixed up code in each DSA, wait_reselect walks the 
-;      reconnect_dsa_queue, asking each dsa if the target ID
-;      and LUN match its.
-;
-;      If a match is found, a call is made back to reselected_ok,
-;      which through the miracles of self modifying code, extracts
-;      the found DSA from the reconnect_dsa_queue and then 
-;      returns control to the DSAs thread of execution.
-;
-; INPUTS : NONE
-;
-; CALLS : OK
-;
-; MODIFIES : DSA,
-;
-; EXITS : On successful reselection, control is returned to the 
-;      DSA which called reselected_ok.  If the WAIT RESELECT
-;      was interrupted by a new commands arrival signaled by 
-;      SIG_P, control is passed to schedule.  If the NCR is 
-;      selected, the host system is interrupted with an 
-;      int_err_selected which is usually responded to by
-;      setting DSP to the target_abort address.
-
-ENTRY wait_reselect
-wait_reselect:
-
-
-
-
-
-
-    WAIT RESELECT wait_reselect_failed
-
-at 0x000001aa : */     0x50000000,0x00000800,
-/*
-
-reselected:
-
-
-
-    CLEAR TARGET
-
-at 0x000001ac : */     0x60000200,0x00000000,
-/*
-    
-    ; Read all data needed to reestablish the nexus - 
-    MOVE 1, reselected_identify, WHEN MSG_IN
-
-at 0x000001ae : */     0x0f000001,0x00000000,
-/*
-    ; We used to CLEAR ACK here.
-
-
-
-
-
-    ; Point DSA at the current head of the disconnected queue.
-    
-    MOVE MEMORY 4, reconnect_dsa_head, addr_scratch
-
-at 0x000001b0 : */     0xc0000004,0x00000000,0x00000000,
-/*
-    
-
-    MOVE MEMORY 4, addr_scratch, saved_dsa
-
-at 0x000001b3 : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-
-
-
-    ; Fix the update-next pointer so that the reconnect_dsa_head
-    ; pointer is the one that will be updated if this DSA is a hit 
-    ; and we remove it from the queue.
-
-    MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok_patch + 8
-
-at 0x000001b6 : */     0xc0000004,0x00000000,0x000007ec,
-/*
-
-    ; Time to correct DSA following memory move
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x000001b9 : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-
-ENTRY reselected_check_next
-reselected_check_next:
-
-
-
-    ; Check for a NULL pointer.
-    MOVE DSA0 TO SFBR
-
-at 0x000001bc : */     0x72100000,0x00000000,
-/*
-    JUMP reselected_not_end, IF NOT 0
-
-at 0x000001be : */     0x80040000,0x00000738,
-/*
-    MOVE DSA1 TO SFBR
-
-at 0x000001c0 : */     0x72110000,0x00000000,
-/*
-    JUMP reselected_not_end, IF NOT 0
-
-at 0x000001c2 : */     0x80040000,0x00000738,
-/*
-    MOVE DSA2 TO SFBR
-
-at 0x000001c4 : */     0x72120000,0x00000000,
-/*
-    JUMP reselected_not_end, IF NOT 0
-
-at 0x000001c6 : */     0x80040000,0x00000738,
-/*
-    MOVE DSA3 TO SFBR
-
-at 0x000001c8 : */     0x72130000,0x00000000,
-/*
-    JUMP reselected_not_end, IF NOT 0
-
-at 0x000001ca : */     0x80040000,0x00000738,
-/*
-    INT int_err_unexpected_reselect
-
-at 0x000001cc : */     0x98080000,0x00020000,
-/*
-
-reselected_not_end:
-    ;
-    ; XXX the ALU is only eight bits wide, and the assembler
-    ; wont do the dirt work for us.  As long as dsa_check_reselect
-    ; is negative, we need to sign extend with 1 bits to the full
-    ; 32 bit width of the address.
-    ;
-    ; A potential work around would be to have a known alignment 
-    ; of the DSA structure such that the base address plus 
-    ; dsa_check_reselect doesn't require carrying from bytes 
-    ; higher than the LSB.
-    ;
-
-    MOVE DSA0 TO SFBR
-
-at 0x000001ce : */     0x72100000,0x00000000,
-/*
-    MOVE SFBR + dsa_check_reselect TO SCRATCH0
-
-at 0x000001d0 : */     0x6e340000,0x00000000,
-/*
-    MOVE DSA1 TO SFBR
-
-at 0x000001d2 : */     0x72110000,0x00000000,
-/*
-    MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY
-
-at 0x000001d4 : */     0x6f35ff00,0x00000000,
-/*
-    MOVE DSA2 TO SFBR
-
-at 0x000001d6 : */     0x72120000,0x00000000,
-/*
-    MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY
-
-at 0x000001d8 : */     0x6f36ff00,0x00000000,
-/*
-    MOVE DSA3 TO SFBR
-
-at 0x000001da : */     0x72130000,0x00000000,
-/*
-    MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY
-
-at 0x000001dc : */     0x6f37ff00,0x00000000,
-/*
-
-    
-    MOVE MEMORY 4, addr_scratch, reselected_check + 4
-
-at 0x000001de : */     0xc0000004,0x00000000,0x00000794,
-/*
-    
-
-    ; Time to correct DSA following memory move
-    MOVE MEMORY 4, saved_dsa, addr_dsa
-
-at 0x000001e1 : */     0xc0000004,0x00000000,0x00000000,
-/*
-
-reselected_check:
-    JUMP 0
-
-at 0x000001e4 : */     0x80080000,0x00000000,
-/*
-
-
-;
-;
-
-; We have problems here - the memory move corrupts TEMP and DSA.  This
-; routine is called from DSA code, and patched from many places.  Scratch
-; is probably free when it is called.
-; We have to:
-;   copy temp to scratch, one byte at a time
-;   write scratch to patch a jump in place of the return
-;   do the move memory
-;   jump to the patched in return address
-; DSA is corrupt when we get here, and can be left corrupt
-
-ENTRY reselected_ok
-reselected_ok:
-    MOVE TEMP0 TO SFBR
-
-at 0x000001e6 : */     0x721c0000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH0
-
-at 0x000001e8 : */     0x6a340000,0x00000000,
-/*
-    MOVE TEMP1 TO SFBR
-
-at 0x000001ea : */     0x721d0000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH1
-
-at 0x000001ec : */     0x6a350000,0x00000000,
-/*
-    MOVE TEMP2 TO SFBR
-
-at 0x000001ee : */     0x721e0000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH2
-
-at 0x000001f0 : */     0x6a360000,0x00000000,
-/*
-    MOVE TEMP3 TO SFBR
-
-at 0x000001f2 : */     0x721f0000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH3
-
-at 0x000001f4 : */     0x6a370000,0x00000000,
-/*
-    MOVE MEMORY 4, addr_scratch, reselected_ok_jump + 4
-
-at 0x000001f6 : */     0xc0000004,0x00000000,0x000007f4,
-/*
-reselected_ok_patch:
-    MOVE MEMORY 4, 0, 0
-
-at 0x000001f9 : */     0xc0000004,0x00000000,0x00000000,
-/*
-reselected_ok_jump:
-    JUMP 0
-
-at 0x000001fc : */     0x80080000,0x00000000,
-/*
-
-
-
-
-
-selected:
-    INT int_err_selected;
-
-at 0x000001fe : */     0x98080000,0x00010000,
-/*
-
-;
-; A select or reselect failure can be caused by one of two conditions : 
-; 1.  SIG_P was set.  This will be the case if the user has written
-;      a new value to a previously NULL head of the issue queue.
-;
-; 2.  The NCR53c810 was selected or reselected by another device.
-;
-; 3.  The bus was already busy since we were selected or reselected
-;      before starting the command.
-
-wait_reselect_failed:
-
-
-
-; Check selected bit.  
-
-    ; Must work out how to tell if we are selected....
-
-
-
-
-; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
-    MOVE CTEST2 & 0x40 TO SFBR 
-
-at 0x00000200 : */     0x74164000,0x00000000,
-/*
-    JUMP schedule, IF 0x40
-
-at 0x00000202 : */     0x800c0040,0x00000000,
-/*
-; Check connected bit.  
-; FIXME: this needs to change if we support target mode
-    MOVE ISTAT & 0x08 TO SFBR
-
-at 0x00000204 : */     0x74210800,0x00000000,
-/*
-    JUMP reselected, IF 0x08
-
-at 0x00000206 : */     0x800c0008,0x000006b0,
-/*
-; FIXME : Something bogus happened, and we shouldn't fail silently.
-
-
-
-    INT int_debug_panic
-
-at 0x00000208 : */     0x98080000,0x030b0000,
-/*
-
-
-
-select_failed:
-
-    ; Disable selection timer
-    MOVE CTEST7 | 0x10 TO CTEST7
-
-at 0x0000020a : */     0x7a1b1000,0x00000000,
-/*
-
-
-
-
-; Otherwise, mask the selected and reselected bits off SIST0
-
-    ; Let's assume we don't get selected for now
-    MOVE SSTAT0 & 0x10 TO SFBR
-
-at 0x0000020c : */     0x740d1000,0x00000000,
-/*
-
-
-
-
-    JUMP reselected, IF 0x10 
-
-at 0x0000020e : */     0x800c0010,0x000006b0,
-/*
-; If SIGP is set, the user just gave us another command, and
-; we should restart or return to the scheduler.
-; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
-    MOVE CTEST2 & 0x40 TO SFBR 
-
-at 0x00000210 : */     0x74164000,0x00000000,
-/*
-    JUMP select, IF 0x40
-
-at 0x00000212 : */     0x800c0040,0x000001f8,
-/*
-; Check connected bit.  
-; FIXME: this needs to change if we support target mode
-; FIXME: is this really necessary? 
-    MOVE ISTAT & 0x08 TO SFBR
-
-at 0x00000214 : */     0x74210800,0x00000000,
-/*
-    JUMP reselected, IF 0x08
-
-at 0x00000216 : */     0x800c0008,0x000006b0,
-/*
-; FIXME : Something bogus happened, and we shouldn't fail silently.
-
-
-
-    INT int_debug_panic
-
-at 0x00000218 : */     0x98080000,0x030b0000,
-/*
-
-
-;
-; test_1
-; test_2
-;
-; PURPOSE : run some verification tests on the NCR.  test_1
-;      copies test_src to test_dest and interrupts the host
-;      processor, testing for cache coherency and interrupt
-;      problems in the processes.
-;
-;      test_2 runs a command with offsets relative to the 
-;      DSA on entry, and is useful for miscellaneous experimentation.
-;
-
-; Verify that interrupts are working correctly and that we don't 
-; have a cache invalidation problem.
-
-ABSOLUTE test_src = 0, test_dest = 0
-ENTRY test_1
-test_1:
-    MOVE MEMORY 4, test_src, test_dest
-
-at 0x0000021a : */     0xc0000004,0x00000000,0x00000000,
-/*
-    INT int_test_1
-
-at 0x0000021d : */     0x98080000,0x04000000,
-/*
-
-;
-; Run arbitrary commands, with test code establishing a DSA
-;
-ENTRY test_2
-test_2:
-    CLEAR TARGET
-
-at 0x0000021f : */     0x60000200,0x00000000,
-/*
-
-    ; Enable selection timer
-
-
-
-    MOVE CTEST7 & 0xef TO CTEST7
-
-at 0x00000221 : */     0x7c1bef00,0x00000000,
-/*
-
-
-    SELECT ATN FROM 0, test_2_fail
-
-at 0x00000223 : */     0x43000000,0x000008dc,
-/*
-    JUMP test_2_msgout, WHEN MSG_OUT
-
-at 0x00000225 : */     0x860b0000,0x0000089c,
-/*
-ENTRY test_2_msgout
-test_2_msgout:
-
-    ; Disable selection timer
-    MOVE CTEST7 | 0x10 TO CTEST7
-
-at 0x00000227 : */     0x7a1b1000,0x00000000,
-/*
-
-    MOVE FROM 8, WHEN MSG_OUT
-
-at 0x00000229 : */     0x1e000000,0x00000008,
-/*
-    MOVE FROM 16, WHEN CMD 
-
-at 0x0000022b : */     0x1a000000,0x00000010,
-/*
-    MOVE FROM 24, WHEN DATA_IN
-
-at 0x0000022d : */     0x19000000,0x00000018,
-/*
-    MOVE FROM 32, WHEN STATUS
-
-at 0x0000022f : */     0x1b000000,0x00000020,
-/*
-    MOVE FROM 40, WHEN MSG_IN
-
-at 0x00000231 : */     0x1f000000,0x00000028,
-/*
-
-
-
-    CLEAR ACK
-
-at 0x00000233 : */     0x60000040,0x00000000,
-/*
-    WAIT DISCONNECT
-
-at 0x00000235 : */     0x48000000,0x00000000,
-/*
-test_2_fail:
-
-    ; Disable selection timer
-    MOVE CTEST7 | 0x10 TO CTEST7
-
-at 0x00000237 : */     0x7a1b1000,0x00000000,
-/*
-
-    INT int_test_2
-
-at 0x00000239 : */     0x98080000,0x04010000,
-/*
-
-ENTRY debug_break
-debug_break:
-    INT int_debug_break
-
-at 0x0000023b : */     0x98080000,0x03000000,
-/*
-
-;
-; initiator_abort
-; target_abort
-;
-; PURPOSE : Abort the currently established nexus from with initiator
-;      or target mode.
-;
-;  
-
-ENTRY target_abort
-target_abort:
-    SET TARGET
-
-at 0x0000023d : */     0x58000200,0x00000000,
-/*
-    DISCONNECT
-
-at 0x0000023f : */     0x48000000,0x00000000,
-/*
-    CLEAR TARGET
-
-at 0x00000241 : */     0x60000200,0x00000000,
-/*
-    JUMP schedule
-
-at 0x00000243 : */     0x80080000,0x00000000,
-/*
-    
-ENTRY initiator_abort
-initiator_abort:
-    SET ATN
-
-at 0x00000245 : */     0x58000008,0x00000000,
-/*
-;
-; The SCSI-I specification says that targets may go into MSG out at 
-; their leisure upon receipt of the ATN single.  On all versions of the 
-; specification, we can't change phases until REQ transitions true->false, 
-; so we need to sink/source one byte of data to allow the transition.
-;
-; For the sake of safety, we'll only source one byte of data in all 
-; cases, but to accommodate the SCSI-I dain bramage, we'll sink an  
-; arbitrary number of bytes.
-    JUMP spew_cmd, WHEN CMD
-
-at 0x00000247 : */     0x820b0000,0x0000094c,
-/*
-    JUMP eat_msgin, WHEN MSG_IN
-
-at 0x00000249 : */     0x870b0000,0x0000095c,
-/*
-    JUMP eat_datain, WHEN DATA_IN
-
-at 0x0000024b : */     0x810b0000,0x0000098c,
-/*
-    JUMP eat_status, WHEN STATUS
-
-at 0x0000024d : */     0x830b0000,0x00000974,
-/*
-    JUMP spew_dataout, WHEN DATA_OUT
-
-at 0x0000024f : */     0x800b0000,0x000009a4,
-/*
-    JUMP sated
-
-at 0x00000251 : */     0x80080000,0x000009ac,
-/*
-spew_cmd:
-    MOVE 1, NCR53c7xx_zero, WHEN CMD
-
-at 0x00000253 : */     0x0a000001,0x00000000,
-/*
-    JUMP sated
-
-at 0x00000255 : */     0x80080000,0x000009ac,
-/*
-eat_msgin:
-    MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
-
-at 0x00000257 : */     0x0f000001,0x00000000,
-/*
-    JUMP eat_msgin, WHEN MSG_IN
-
-at 0x00000259 : */     0x870b0000,0x0000095c,
-/*
-    JUMP sated
-
-at 0x0000025b : */     0x80080000,0x000009ac,
-/*
-eat_status:
-    MOVE 1, NCR53c7xx_sink, WHEN STATUS
-
-at 0x0000025d : */     0x0b000001,0x00000000,
-/*
-    JUMP eat_status, WHEN STATUS
-
-at 0x0000025f : */     0x830b0000,0x00000974,
-/*
-    JUMP sated
-
-at 0x00000261 : */     0x80080000,0x000009ac,
-/*
-eat_datain:
-    MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
-
-at 0x00000263 : */     0x09000001,0x00000000,
-/*
-    JUMP eat_datain, WHEN DATA_IN
-
-at 0x00000265 : */     0x810b0000,0x0000098c,
-/*
-    JUMP sated
-
-at 0x00000267 : */     0x80080000,0x000009ac,
-/*
-spew_dataout:
-    MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
-
-at 0x00000269 : */     0x08000001,0x00000000,
-/*
-sated:
-
-
-
-    MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
-
-at 0x0000026b : */     0x0e000001,0x00000000,
-/*
-    WAIT DISCONNECT
-
-at 0x0000026d : */     0x48000000,0x00000000,
-/*
-    INT int_norm_aborted
-
-at 0x0000026f : */     0x98080000,0x02040000,
-/*
-
-
-
-; Little patched jump, used to overcome problems with TEMP getting
-; corrupted on memory moves.
-
-jump_temp:
-    JUMP 0
-
-at 0x00000271 : */     0x80080000,0x00000000,
-};
-
-#define A_NCR53c7xx_msg_abort  0x00000000
-static u32 A_NCR53c7xx_msg_abort_used[] __attribute((unused)) = {
-       0x0000026c,
-};
-
-#define A_NCR53c7xx_msg_reject 0x00000000
-static u32 A_NCR53c7xx_msg_reject_used[] __attribute((unused)) = {
-       0x00000186,
-};
-
-#define A_NCR53c7xx_sink       0x00000000
-static u32 A_NCR53c7xx_sink_used[] __attribute((unused)) = {
-       0x00000258,
-       0x0000025e,
-       0x00000264,
-};
-
-#define A_NCR53c7xx_zero       0x00000000
-static u32 A_NCR53c7xx_zero_used[] __attribute((unused)) = {
-       0x00000254,
-       0x0000026a,
-};
-
-#define A_NOP_insn     0x00000000
-static u32 A_NOP_insn_used[] __attribute((unused)) = {
-       0x00000017,
-};
-
-#define A_addr_dsa     0x00000000
-static u32 A_addr_dsa_used[] __attribute((unused)) = {
-       0x0000000f,
-       0x00000026,
-       0x00000033,
-       0x00000040,
-       0x00000055,
-       0x00000079,
-       0x0000008e,
-       0x000000bc,
-       0x000000d2,
-       0x00000130,
-       0x000001a5,
-       0x000001bb,
-       0x000001e3,
-};
-
-#define A_addr_reconnect_dsa_head      0x00000000
-static u32 A_addr_reconnect_dsa_head_used[] __attribute((unused)) = {
-       0x000001b7,
-};
-
-#define A_addr_scratch 0x00000000
-static u32 A_addr_scratch_used[] __attribute((unused)) = {
-       0x00000002,
-       0x00000004,
-       0x00000008,
-       0x00000020,
-       0x00000022,
-       0x00000049,
-       0x00000060,
-       0x0000006a,
-       0x00000071,
-       0x00000073,
-       0x000000ab,
-       0x000000b5,
-       0x000000c1,
-       0x000000cb,
-       0x0000012c,
-       0x00000142,
-       0x00000157,
-       0x000001b2,
-       0x000001b4,
-       0x000001df,
-       0x000001f7,
-};
-
-#define A_addr_temp    0x00000000
-static u32 A_addr_temp_used[] __attribute((unused)) = {
-};
-
-#define A_dmode_memory_to_memory       0x00000000
-static u32 A_dmode_memory_to_memory_used[] __attribute((unused)) = {
-};
-
-#define A_dmode_memory_to_ncr  0x00000000
-static u32 A_dmode_memory_to_ncr_used[] __attribute((unused)) = {
-};
-
-#define A_dmode_ncr_to_memory  0x00000000
-static u32 A_dmode_ncr_to_memory_used[] __attribute((unused)) = {
-};
-
-#define A_dsa_check_reselect   0x00000000
-static u32 A_dsa_check_reselect_used[] __attribute((unused)) = {
-       0x000001d0,
-};
-
-#define A_dsa_cmdout   0x00000048
-static u32 A_dsa_cmdout_used[] __attribute((unused)) = {
-       0x0000009a,
-};
-
-#define A_dsa_cmnd     0x00000038
-static u32 A_dsa_cmnd_used[] __attribute((unused)) = {
-};
-
-#define A_dsa_datain   0x00000054
-static u32 A_dsa_datain_used[] __attribute((unused)) = {
-       0x000000c2,
-};
-
-#define A_dsa_dataout  0x00000050
-static u32 A_dsa_dataout_used[] __attribute((unused)) = {
-       0x000000ac,
-};
-
-#define A_dsa_end      0x00000070
-static u32 A_dsa_end_used[] __attribute((unused)) = {
-};
-
-#define A_dsa_fields_start     0x00000000
-static u32 A_dsa_fields_start_used[] __attribute((unused)) = {
-};
-
-#define A_dsa_msgin    0x00000058
-static u32 A_dsa_msgin_used[] __attribute((unused)) = {
-       0x0000019c,
-};
-
-#define A_dsa_msgout   0x00000040
-static u32 A_dsa_msgout_used[] __attribute((unused)) = {
-       0x00000089,
-};
-
-#define A_dsa_msgout_other     0x00000068
-static u32 A_dsa_msgout_other_used[] __attribute((unused)) = {
-       0x00000194,
-};
-
-#define A_dsa_next     0x00000030
-static u32 A_dsa_next_used[] __attribute((unused)) = {
-       0x00000061,
-};
-
-#define A_dsa_restore_pointers 0x00000000
-static u32 A_dsa_restore_pointers_used[] __attribute((unused)) = {
-       0x00000146,
-};
-
-#define A_dsa_save_data_pointer        0x00000000
-static u32 A_dsa_save_data_pointer_used[] __attribute((unused)) = {
-       0x00000131,
-};
-
-#define A_dsa_select   0x0000003c
-static u32 A_dsa_select_used[] __attribute((unused)) = {
-       0x00000082,
-};
-
-#define A_dsa_sscf_710 0x00000000
-static u32 A_dsa_sscf_710_used[] __attribute((unused)) = {
-       0x00000007,
-};
-
-#define A_dsa_status   0x00000060
-static u32 A_dsa_status_used[] __attribute((unused)) = {
-       0x00000198,
-};
-
-#define A_dsa_temp_addr_array_value    0x00000000
-static u32 A_dsa_temp_addr_array_value_used[] __attribute((unused)) = {
-};
-
-#define A_dsa_temp_addr_dsa_value      0x00000000
-static u32 A_dsa_temp_addr_dsa_value_used[] __attribute((unused)) = {
-       0x00000001,
-};
-
-#define A_dsa_temp_addr_new_value      0x00000000
-static u32 A_dsa_temp_addr_new_value_used[] __attribute((unused)) = {
-};
-
-#define A_dsa_temp_addr_next   0x00000000
-static u32 A_dsa_temp_addr_next_used[] __attribute((unused)) = {
-       0x0000001c,
-       0x0000004f,
-};
-
-#define A_dsa_temp_addr_residual       0x00000000
-static u32 A_dsa_temp_addr_residual_used[] __attribute((unused)) = {
-       0x0000002d,
-       0x0000003b,
-};
-
-#define A_dsa_temp_addr_saved_pointer  0x00000000
-static u32 A_dsa_temp_addr_saved_pointer_used[] __attribute((unused)) = {
-       0x0000002b,
-       0x00000037,
-};
-
-#define A_dsa_temp_addr_saved_residual 0x00000000
-static u32 A_dsa_temp_addr_saved_residual_used[] __attribute((unused)) = {
-       0x0000002e,
-       0x0000003a,
-};
-
-#define A_dsa_temp_lun 0x00000000
-static u32 A_dsa_temp_lun_used[] __attribute((unused)) = {
-       0x0000004c,
-};
-
-#define A_dsa_temp_next        0x00000000
-static u32 A_dsa_temp_next_used[] __attribute((unused)) = {
-       0x0000001f,
-};
-
-#define A_dsa_temp_sync        0x00000000
-static u32 A_dsa_temp_sync_used[] __attribute((unused)) = {
-       0x00000057,
-};
-
-#define A_dsa_temp_target      0x00000000
-static u32 A_dsa_temp_target_used[] __attribute((unused)) = {
-       0x00000045,
-};
-
-#define A_emulfly      0x00000000
-static u32 A_emulfly_used[] __attribute((unused)) = {
-};
-
-#define A_int_debug_break      0x03000000
-static u32 A_int_debug_break_used[] __attribute((unused)) = {
-       0x0000023c,
-};
-
-#define A_int_debug_panic      0x030b0000
-static u32 A_int_debug_panic_used[] __attribute((unused)) = {
-       0x00000209,
-       0x00000219,
-};
-
-#define A_int_err_check_condition      0x00030000
-static u32 A_int_err_check_condition_used[] __attribute((unused)) = {
-       0x000001a9,
-};
-
-#define A_int_err_no_phase     0x00040000
-static u32 A_int_err_no_phase_used[] __attribute((unused)) = {
-};
-
-#define A_int_err_selected     0x00010000
-static u32 A_int_err_selected_used[] __attribute((unused)) = {
-       0x000001ff,
-};
-
-#define A_int_err_unexpected_phase     0x00000000
-static u32 A_int_err_unexpected_phase_used[] __attribute((unused)) = {
-       0x00000092,
-       0x00000098,
-       0x000000a0,
-       0x000000d6,
-       0x000000da,
-       0x000000dc,
-       0x000000e4,
-       0x000000e8,
-       0x000000ea,
-       0x000000f2,
-       0x000000f6,
-       0x000000f8,
-       0x000000fa,
-       0x00000160,
-};
-
-#define A_int_err_unexpected_reselect  0x00020000
-static u32 A_int_err_unexpected_reselect_used[] __attribute((unused)) = {
-       0x000001cd,
-};
-
-#define A_int_msg_1    0x01020000
-static u32 A_int_msg_1_used[] __attribute((unused)) = {
-       0x00000114,
-       0x00000116,
-};
-
-#define A_int_msg_sdtr 0x01010000
-static u32 A_int_msg_sdtr_used[] __attribute((unused)) = {
-       0x00000180,
-};
-
-#define A_int_msg_wdtr 0x01000000
-static u32 A_int_msg_wdtr_used[] __attribute((unused)) = {
-       0x00000174,
-};
-
-#define A_int_norm_aborted     0x02040000
-static u32 A_int_norm_aborted_used[] __attribute((unused)) = {
-       0x00000270,
-};
-
-#define A_int_norm_command_complete    0x02020000
-static u32 A_int_norm_command_complete_used[] __attribute((unused)) = {
-};
-
-#define A_int_norm_disconnected        0x02030000
-static u32 A_int_norm_disconnected_used[] __attribute((unused)) = {
-};
-
-#define A_int_norm_emulateintfly       0x02060000
-static u32 A_int_norm_emulateintfly_used[] __attribute((unused)) = {
-       0x000001a2,
-};
-
-#define A_int_norm_reselect_complete   0x02010000
-static u32 A_int_norm_reselect_complete_used[] __attribute((unused)) = {
-};
-
-#define A_int_norm_reset       0x02050000
-static u32 A_int_norm_reset_used[] __attribute((unused)) = {
-};
-
-#define A_int_norm_select_complete     0x02000000
-static u32 A_int_norm_select_complete_used[] __attribute((unused)) = {
-};
-
-#define A_int_test_1   0x04000000
-static u32 A_int_test_1_used[] __attribute((unused)) = {
-       0x0000021e,
-};
-
-#define A_int_test_2   0x04010000
-static u32 A_int_test_2_used[] __attribute((unused)) = {
-       0x0000023a,
-};
-
-#define A_int_test_3   0x04020000
-static u32 A_int_test_3_used[] __attribute((unused)) = {
-};
-
-#define A_msg_buf      0x00000000
-static u32 A_msg_buf_used[] __attribute((unused)) = {
-       0x00000108,
-       0x00000162,
-       0x0000016c,
-       0x00000172,
-       0x00000178,
-       0x0000017e,
-};
-
-#define A_reconnect_dsa_head   0x00000000
-static u32 A_reconnect_dsa_head_used[] __attribute((unused)) = {
-       0x0000006d,
-       0x00000074,
-       0x000001b1,
-};
-
-#define A_reselected_identify  0x00000000
-static u32 A_reselected_identify_used[] __attribute((unused)) = {
-       0x00000048,
-       0x000001af,
-};
-
-#define A_reselected_tag       0x00000000
-static u32 A_reselected_tag_used[] __attribute((unused)) = {
-};
-
-#define A_saved_dsa    0x00000000
-static u32 A_saved_dsa_used[] __attribute((unused)) = {
-       0x00000005,
-       0x0000000e,
-       0x00000023,
-       0x00000025,
-       0x00000032,
-       0x0000003f,
-       0x00000054,
-       0x0000005f,
-       0x00000070,
-       0x00000078,
-       0x0000008d,
-       0x000000aa,
-       0x000000bb,
-       0x000000c0,
-       0x000000d1,
-       0x0000012f,
-       0x000001a4,
-       0x000001b5,
-       0x000001ba,
-       0x000001e2,
-};
-
-#define A_schedule     0x00000000
-static u32 A_schedule_used[] __attribute((unused)) = {
-       0x0000007d,
-       0x000001a7,
-       0x00000203,
-       0x00000244,
-};
-
-#define A_test_dest    0x00000000
-static u32 A_test_dest_used[] __attribute((unused)) = {
-       0x0000021c,
-};
-
-#define A_test_src     0x00000000
-static u32 A_test_src_used[] __attribute((unused)) = {
-       0x0000021b,
-};
-
-#define Ent_accept_message     0x00000624
-#define Ent_cmdout_cmdout      0x00000264
-#define Ent_command_complete   0x0000065c
-#define Ent_command_complete_msgin     0x0000066c
-#define Ent_data_transfer      0x0000026c
-#define Ent_datain_to_jump     0x00000334
-#define Ent_debug_break        0x000008ec
-#define Ent_dsa_code_begin     0x00000000
-#define Ent_dsa_code_check_reselect    0x0000010c
-#define Ent_dsa_code_fix_jump  0x00000058
-#define Ent_dsa_code_restore_pointers  0x000000d8
-#define Ent_dsa_code_save_data_pointer 0x000000a4
-#define Ent_dsa_code_template  0x00000000
-#define Ent_dsa_code_template_end      0x00000178
-#define Ent_dsa_schedule       0x00000178
-#define Ent_dsa_zero   0x00000178
-#define Ent_end_data_transfer  0x000002a4
-#define Ent_initiator_abort    0x00000914
-#define Ent_msg_in     0x0000041c
-#define Ent_msg_in_restart     0x000003fc
-#define Ent_other_in   0x0000038c
-#define Ent_other_out  0x00000354
-#define Ent_other_transfer     0x000003c4
-#define Ent_reject_message     0x00000604
-#define Ent_reselected_check_next      0x000006f0
-#define Ent_reselected_ok      0x00000798
-#define Ent_respond_message    0x0000063c
-#define Ent_select     0x000001f8
-#define Ent_select_msgout      0x00000218
-#define Ent_target_abort       0x000008f4
-#define Ent_test_1     0x00000868
-#define Ent_test_2     0x0000087c
-#define Ent_test_2_msgout      0x0000089c
-#define Ent_wait_reselect      0x000006a8
-static u32 LABELPATCHES[] __attribute((unused)) = {
-       0x00000011,
-       0x0000001a,
-       0x0000001d,
-       0x00000028,
-       0x0000002a,
-       0x00000035,
-       0x00000038,
-       0x00000042,
-       0x00000050,
-       0x00000052,
-       0x0000006b,
-       0x00000083,
-       0x00000085,
-       0x00000090,
-       0x00000094,
-       0x00000096,
-       0x0000009c,
-       0x0000009e,
-       0x000000a2,
-       0x000000a4,
-       0x000000a6,
-       0x000000a8,
-       0x000000b6,
-       0x000000b9,
-       0x000000cc,
-       0x000000cf,
-       0x000000d8,
-       0x000000de,
-       0x000000e0,
-       0x000000e6,
-       0x000000ec,
-       0x000000ee,
-       0x000000f4,
-       0x000000fc,
-       0x000000fe,
-       0x0000010a,
-       0x0000010c,
-       0x0000010e,
-       0x00000110,
-       0x00000112,
-       0x00000118,
-       0x0000011a,
-       0x0000012d,
-       0x00000143,
-       0x00000158,
-       0x0000015c,
-       0x00000164,
-       0x00000166,
-       0x00000168,
-       0x0000016e,
-       0x0000017a,
-       0x000001ab,
-       0x000001b8,
-       0x000001bf,
-       0x000001c3,
-       0x000001c7,
-       0x000001cb,
-       0x000001e0,
-       0x000001f8,
-       0x00000207,
-       0x0000020f,
-       0x00000213,
-       0x00000217,
-       0x00000224,
-       0x00000226,
-       0x00000248,
-       0x0000024a,
-       0x0000024c,
-       0x0000024e,
-       0x00000250,
-       0x00000252,
-       0x00000256,
-       0x0000025a,
-       0x0000025c,
-       0x00000260,
-       0x00000262,
-       0x00000266,
-       0x00000268,
-};
-
-static struct {
-       u32     offset;
-       void            *address;
-} EXTERNAL_PATCHES[] __attribute((unused)) = {
-};
-
-static u32 INSTRUCTIONS __attribute((unused))  = 290;
-static u32 PATCHES __attribute((unused))       = 78;
-static u32 EXTERNAL_PATCHES_LEN __attribute((unused))  = 0;
diff --git a/drivers/scsi/53c7xx_u.h_shipped b/drivers/scsi/53c7xx_u.h_shipped
deleted file mode 100644 (file)
index 7b33717..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-#undef A_NCR53c7xx_msg_abort
-#undef A_NCR53c7xx_msg_reject
-#undef A_NCR53c7xx_sink
-#undef A_NCR53c7xx_zero
-#undef A_NOP_insn
-#undef A_addr_dsa
-#undef A_addr_reconnect_dsa_head
-#undef A_addr_scratch
-#undef A_addr_temp
-#undef A_dmode_memory_to_memory
-#undef A_dmode_memory_to_ncr
-#undef A_dmode_ncr_to_memory
-#undef A_dsa_check_reselect
-#undef A_dsa_cmdout
-#undef A_dsa_cmnd
-#undef A_dsa_datain
-#undef A_dsa_dataout
-#undef A_dsa_end
-#undef A_dsa_fields_start
-#undef A_dsa_msgin
-#undef A_dsa_msgout
-#undef A_dsa_msgout_other
-#undef A_dsa_next
-#undef A_dsa_restore_pointers
-#undef A_dsa_save_data_pointer
-#undef A_dsa_select
-#undef A_dsa_sscf_710
-#undef A_dsa_status
-#undef A_dsa_temp_addr_array_value
-#undef A_dsa_temp_addr_dsa_value
-#undef A_dsa_temp_addr_new_value
-#undef A_dsa_temp_addr_next
-#undef A_dsa_temp_addr_residual
-#undef A_dsa_temp_addr_saved_pointer
-#undef A_dsa_temp_addr_saved_residual
-#undef A_dsa_temp_lun
-#undef A_dsa_temp_next
-#undef A_dsa_temp_sync
-#undef A_dsa_temp_target
-#undef A_emulfly
-#undef A_int_debug_break
-#undef A_int_debug_panic
-#undef A_int_err_check_condition
-#undef A_int_err_no_phase
-#undef A_int_err_selected
-#undef A_int_err_unexpected_phase
-#undef A_int_err_unexpected_reselect
-#undef A_int_msg_1
-#undef A_int_msg_sdtr
-#undef A_int_msg_wdtr
-#undef A_int_norm_aborted
-#undef A_int_norm_command_complete
-#undef A_int_norm_disconnected
-#undef A_int_norm_emulateintfly
-#undef A_int_norm_reselect_complete
-#undef A_int_norm_reset
-#undef A_int_norm_select_complete
-#undef A_int_test_1
-#undef A_int_test_2
-#undef A_int_test_3
-#undef A_msg_buf
-#undef A_reconnect_dsa_head
-#undef A_reselected_identify
-#undef A_reselected_tag
-#undef A_saved_dsa
-#undef A_schedule
-#undef A_test_dest
-#undef A_test_src
-#undef Ent_accept_message
-#undef Ent_cmdout_cmdout
-#undef Ent_command_complete
-#undef Ent_command_complete_msgin
-#undef Ent_data_transfer
-#undef Ent_datain_to_jump
-#undef Ent_debug_break
-#undef Ent_dsa_code_begin
-#undef Ent_dsa_code_check_reselect
-#undef Ent_dsa_code_fix_jump
-#undef Ent_dsa_code_restore_pointers
-#undef Ent_dsa_code_save_data_pointer
-#undef Ent_dsa_code_template
-#undef Ent_dsa_code_template_end
-#undef Ent_dsa_schedule
-#undef Ent_dsa_zero
-#undef Ent_end_data_transfer
-#undef Ent_initiator_abort
-#undef Ent_msg_in
-#undef Ent_msg_in_restart
-#undef Ent_other_in
-#undef Ent_other_out
-#undef Ent_other_transfer
-#undef Ent_reject_message
-#undef Ent_reselected_check_next
-#undef Ent_reselected_ok
-#undef Ent_respond_message
-#undef Ent_select
-#undef Ent_select_msgout
-#undef Ent_target_abort
-#undef Ent_test_1
-#undef Ent_test_2
-#undef Ent_test_2_msgout
-#undef Ent_wait_reselect
index 96f4cab..9b20617 100644 (file)
@@ -304,18 +304,10 @@ static struct BusLogic_CCB *BusLogic_AllocateCCB(struct BusLogic_HostAdapter
 static void BusLogic_DeallocateCCB(struct BusLogic_CCB *CCB)
 {
        struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
-       struct scsi_cmnd *cmd = CCB->Command;
 
-       if (cmd->use_sg != 0) {
-               pci_unmap_sg(HostAdapter->PCI_Device,
-                               (struct scatterlist *)cmd->request_buffer,
-                               cmd->use_sg, cmd->sc_data_direction);
-       } else if (cmd->request_bufflen != 0) {
-               pci_unmap_single(HostAdapter->PCI_Device, CCB->DataPointer,
-                               CCB->DataLength, cmd->sc_data_direction);
-       }
+       scsi_dma_unmap(CCB->Command);
        pci_unmap_single(HostAdapter->PCI_Device, CCB->SenseDataPointer,
-                       CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
+                        CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
 
        CCB->Command = NULL;
        CCB->Status = BusLogic_CCB_Free;
@@ -2648,7 +2640,8 @@ static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapt
                         */
                        if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 && CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally) {
                                struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[CCB->TargetID];
-                               struct SCSI_Inquiry *InquiryResult = (struct SCSI_Inquiry *) Command->request_buffer;
+                               struct SCSI_Inquiry *InquiryResult =
+                                       (struct SCSI_Inquiry *) scsi_sglist(Command);
                                TargetFlags->TargetExists = true;
                                TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
                                TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
@@ -2819,9 +2812,8 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
        int CDB_Length = Command->cmd_len;
        int TargetID = Command->device->id;
        int LogicalUnit = Command->device->lun;
-       void *BufferPointer = Command->request_buffer;
-       int BufferLength = Command->request_bufflen;
-       int SegmentCount = Command->use_sg;
+       int BufferLength = scsi_bufflen(Command);
+       int Count;
        struct BusLogic_CCB *CCB;
        /*
           SCSI REQUEST_SENSE commands will be executed automatically by the Host
@@ -2851,36 +2843,35 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
                        return 0;
                }
        }
+
        /*
           Initialize the fields in the BusLogic Command Control Block (CCB).
         */
-       if (SegmentCount == 0 && BufferLength != 0) {
-               CCB->Opcode = BusLogic_InitiatorCCB;
-               CCB->DataLength = BufferLength;
-               CCB->DataPointer = pci_map_single(HostAdapter->PCI_Device,
-                               BufferPointer, BufferLength,
-                               Command->sc_data_direction);
-       } else if (SegmentCount != 0) {
-               struct scatterlist *ScatterList = (struct scatterlist *) BufferPointer;
-               int Segment, Count;
-
-               Count = pci_map_sg(HostAdapter->PCI_Device, ScatterList, SegmentCount,
-                               Command->sc_data_direction);
+       Count = scsi_dma_map(Command);
+       BUG_ON(Count < 0);
+       if (Count) {
+               struct scatterlist *sg;
+               int i;
+
                CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
                CCB->DataLength = Count * sizeof(struct BusLogic_ScatterGatherSegment);
                if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
                        CCB->DataPointer = (unsigned int) CCB->DMA_Handle + ((unsigned long) &CCB->ScatterGatherList - (unsigned long) CCB);
                else
                        CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
-               for (Segment = 0; Segment < Count; Segment++) {
-                       CCB->ScatterGatherList[Segment].SegmentByteCount = sg_dma_len(ScatterList + Segment);
-                       CCB->ScatterGatherList[Segment].SegmentDataPointer = sg_dma_address(ScatterList + Segment);
+
+               scsi_for_each_sg(Command, sg, Count, i) {
+                       CCB->ScatterGatherList[i].SegmentByteCount =
+                               sg_dma_len(sg);
+                       CCB->ScatterGatherList[i].SegmentDataPointer =
+                               sg_dma_address(sg);
                }
-       } else {
+       } else if (!Count) {
                CCB->Opcode = BusLogic_InitiatorCCB;
                CCB->DataLength = BufferLength;
                CCB->DataPointer = 0;
        }
+
        switch (CDB[0]) {
        case READ_6:
        case READ_10:
index 572034c..aac9cd9 100644 (file)
@@ -738,7 +738,7 @@ config SCSI_GENERIC_NCR53C400
 
 config SCSI_IBMMCA
        tristate "IBMMCA SCSI support"
-       depends on MCA_LEGACY && SCSI
+       depends on MCA && SCSI
        ---help---
          This is support for the IBM SCSI adapter found in many of the PS/2
          series computers.  These machines have an MCA bus, so you need to
index b1b6327..cba3967 100644 (file)
@@ -37,7 +37,6 @@ obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas/
 
 obj-$(CONFIG_ISCSI_TCP)        += libiscsi.o   iscsi_tcp.o
 obj-$(CONFIG_INFINIBAND_ISER)  += libiscsi.o
-obj-$(CONFIG_SCSI_AMIGA7XX)    += amiga7xx.o   53c7xx.o
 obj-$(CONFIG_A3000_SCSI)       += a3000.o      wd33c93.o
 obj-$(CONFIG_A2091_SCSI)       += a2091.o      wd33c93.o
 obj-$(CONFIG_GVP11_SCSI)       += gvp11.o      wd33c93.o
@@ -53,8 +52,6 @@ obj-$(CONFIG_ATARI_SCSI)      += atari_scsi.o
 obj-$(CONFIG_MAC_SCSI)         += mac_scsi.o
 obj-$(CONFIG_SCSI_MAC_ESP)     += mac_esp.o    NCR53C9x.o
 obj-$(CONFIG_SUN3_SCSI)                += sun3_scsi.o  sun3_scsi_vme.o
-obj-$(CONFIG_MVME16x_SCSI)     += mvme16x.o    53c7xx.o
-obj-$(CONFIG_BVME6000_SCSI)    += bvme6000.o   53c7xx.o
 obj-$(CONFIG_SCSI_SIM710)      += 53c700.o     sim710.o
 obj-$(CONFIG_SCSI_ADVANSYS)    += advansys.o
 obj-$(CONFIG_SCSI_PSI240I)     += psi240i.o
@@ -168,10 +165,8 @@ NCR_Q720_mod-objs  := NCR_Q720.o ncr53c8xx.o
 oktagon_esp_mod-objs   := oktagon_esp.o oktagon_io.o
 
 # Files generated that shall be removed upon make clean
-clean-files := 53c7xx_d.h 53c700_d.h   \
-               53c7xx_u.h 53c700_u.h
+clean-files := 53c700_d.h 53c700_u.h
 
-$(obj)/53c7xx.o:   $(obj)/53c7xx_d.h $(obj)/53c7xx_u.h
 $(obj)/53c700.o $(MODVERDIR)/$(obj)/53c700.ver: $(obj)/53c700_d.h
 
 # If you want to play with the firmware, uncomment
@@ -179,11 +174,6 @@ $(obj)/53c700.o $(MODVERDIR)/$(obj)/53c700.ver: $(obj)/53c700_d.h
 
 ifdef GENERATE_FIRMWARE
 
-$(obj)/53c7xx_d.h: $(src)/53c7xx.scr $(src)/script_asm.pl
-       $(CPP) -traditional -DCHIP=710 - < $< | grep -v '^#' | $(PERL) -s $(src)/script_asm.pl -ncr7x0_family $@ $(@:_d.h=_u.h)
-
-$(obj)/53c7xx_u.h: $(obj)/53c7xx_d.h
-
 $(obj)/53c700_d.h: $(src)/53c700.scr $(src)/script_asm.pl
        $(PERL) -s $(src)/script_asm.pl -ncr7x0_family $@ $(@:_d.h=_u.h) < $<
 
index bb3cb33..37de6b3 100644 (file)
@@ -347,7 +347,7 @@ static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, i
                if((r & bit) == val)
                        return 0;
                if(!in_interrupt())
-                       yield();
+                       cond_resched();
                else
                        cpu_relax();
        }
@@ -357,7 +357,7 @@ static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, i
 static struct {
        unsigned char value;
        const char *name;
-} phases[] = {
+} phases[] __maybe_unused = {
        {PHASE_DATAOUT, "DATAOUT"}, 
        {PHASE_DATAIN, "DATAIN"}, 
        {PHASE_CMDOUT, "CMDOUT"}, 
@@ -575,7 +575,8 @@ static irqreturn_t __init probe_intr(int irq, void *dev_id)
  *     Locks: none, irqs must be enabled on entry
  */
 
-static int __init NCR5380_probe_irq(struct Scsi_Host *instance, int possible)
+static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
+                                               int possible)
 {
        NCR5380_local_declare();
        struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
@@ -629,7 +630,8 @@ static int __init NCR5380_probe_irq(struct Scsi_Host *instance, int possible)
  *     Locks: none
  */
 
-static void __init NCR5380_print_options(struct Scsi_Host *instance)
+static void __init __maybe_unused
+NCR5380_print_options(struct Scsi_Host *instance)
 {
        printk(" generic options"
 #ifdef AUTOPROBE_IRQ
@@ -703,8 +705,8 @@ char *lprint_command(unsigned char *cmd, char *pos, char *buffer, int len);
 static
 char *lprint_opcode(int opcode, char *pos, char *buffer, int length);
 
-static
-int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, char **start, off_t offset, int length, int inout)
+static int __maybe_unused NCR5380_proc_info(struct Scsi_Host *instance,
+       char *buffer, char **start, off_t offset, int length, int inout)
 {
        char *pos = buffer;
        struct NCR5380_hostdata *hostdata;
index 713a108..bccf13f 100644 (file)
@@ -299,7 +299,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance);
 static irqreturn_t NCR5380_intr(int irq, void *dev_id);
 #endif
 static void NCR5380_main(struct work_struct *work);
-static void NCR5380_print_options(struct Scsi_Host *instance);
+static void __maybe_unused NCR5380_print_options(struct Scsi_Host *instance);
 #ifdef NDEBUG
 static void NCR5380_print_phase(struct Scsi_Host *instance);
 static void NCR5380_print(struct Scsi_Host *instance);
@@ -307,8 +307,8 @@ static void NCR5380_print(struct Scsi_Host *instance);
 static int NCR5380_abort(Scsi_Cmnd * cmd);
 static int NCR5380_bus_reset(Scsi_Cmnd * cmd);
 static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
-static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
-off_t offset, int length, int inout);
+static int __maybe_unused NCR5380_proc_info(struct Scsi_Host *instance,
+       char *buffer, char **start, off_t offset, int length, int inout);
 
 static void NCR5380_reselect(struct Scsi_Host *instance);
 static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag);
index 7c0b17f..eda8c48 100644 (file)
@@ -698,7 +698,7 @@ static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
        int i;
 
        VDEB(printk("NCR53c406a_queue called\n"));
-       DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n", SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->target, SCpnt->lun, SCpnt->request_bufflen));
+       DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n", SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->target, SCpnt->lun, scsi_bufflen(SCpnt)));
 
 #if 0
        VDEB(for (i = 0; i < SCpnt->cmd_len; i++)
@@ -785,8 +785,8 @@ static void NCR53c406a_intr(void *dev_id)
        unsigned char status, int_reg;
 #if USE_PIO
        unsigned char pio_status;
-       struct scatterlist *sglist;
-       unsigned int sgcount;
+       struct scatterlist *sg;
+        int i;
 #endif
 
        VDEB(printk("NCR53c406a_intr called\n"));
@@ -866,22 +866,18 @@ static void NCR53c406a_intr(void *dev_id)
                        current_SC->SCp.phase = data_out;
                        VDEB(printk("NCR53c406a: Data-Out phase\n"));
                        outb(FLUSH_FIFO, CMD_REG);
-                       LOAD_DMA_COUNT(current_SC->request_bufflen);    /* Max transfer size */
+                       LOAD_DMA_COUNT(scsi_bufflen(current_SC));       /* Max transfer size */
 #if USE_DMA                    /* No s/g support for DMA */
-                       NCR53c406a_dma_write(current_SC->request_buffer, current_SC->request_bufflen);
+                       NCR53c406a_dma_write(scsi_sglist(current_SC),
+                                             scsdi_bufflen(current_SC));
+
 #endif                         /* USE_DMA */
                        outb(TRANSFER_INFO | DMA_OP, CMD_REG);
 #if USE_PIO
-                       if (!current_SC->use_sg)        /* Don't use scatter-gather */
-                               NCR53c406a_pio_write(current_SC->request_buffer, current_SC->request_bufflen);
-                       else {  /* use scatter-gather */
-                               sgcount = current_SC->use_sg;
-                               sglist = current_SC->request_buffer;
-                               while (sgcount--) {
-                                       NCR53c406a_pio_write(page_address(sglist->page) + sglist->offset, sglist->length);
-                                       sglist++;
-                               }
-                       }
+                        scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
+                                NCR53c406a_pio_write(page_address(sg->page) + sg->offset,
+                                                     sg->length);
+                        }
                        REG0;
 #endif                         /* USE_PIO */
                }
@@ -893,22 +889,17 @@ static void NCR53c406a_intr(void *dev_id)
                        current_SC->SCp.phase = data_in;
                        VDEB(printk("NCR53c406a: Data-In phase\n"));
                        outb(FLUSH_FIFO, CMD_REG);
-                       LOAD_DMA_COUNT(current_SC->request_bufflen);    /* Max transfer size */
+                       LOAD_DMA_COUNT(scsi_bufflen(current_SC));       /* Max transfer size */
 #if USE_DMA                    /* No s/g support for DMA */
-                       NCR53c406a_dma_read(current_SC->request_buffer, current_SC->request_bufflen);
+                       NCR53c406a_dma_read(scsi_sglist(current_SC),
+                                            scsdi_bufflen(current_SC));
 #endif                         /* USE_DMA */
                        outb(TRANSFER_INFO | DMA_OP, CMD_REG);
 #if USE_PIO
-                       if (!current_SC->use_sg)        /* Don't use scatter-gather */
-                               NCR53c406a_pio_read(current_SC->request_buffer, current_SC->request_bufflen);
-                       else {  /* Use scatter-gather */
-                               sgcount = current_SC->use_sg;
-                               sglist = current_SC->request_buffer;
-                               while (sgcount--) {
-                                       NCR53c406a_pio_read(page_address(sglist->page) + sglist->offset, sglist->length);
-                                       sglist++;
-                               }
-                       }
+                        scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
+                                NCR53c406a_pio_read(page_address(sg->page) + sg->offset,
+                                                    sg->length);
+                        }
                        REG0;
 #endif                         /* USE_PIO */
                }
index 7f4241b..7cedc72 100644 (file)
@@ -796,7 +796,7 @@ static void orc_interrupt(
 *****************************************************************************/
 static void inia100BuildSCB(ORC_HCS * pHCB, ORC_SCB * pSCB, struct scsi_cmnd * SCpnt)
 {                              /* Create corresponding SCB     */
-       struct scatterlist *pSrbSG;
+       struct scatterlist *sg;
        ORC_SG *pSG;            /* Pointer to SG list           */
        int i, count_sg;
        ESCB *pEScb;
@@ -813,30 +813,22 @@ static void inia100BuildSCB(ORC_HCS * pHCB, ORC_SCB * pSCB, struct scsi_cmnd * S
        pSCB->SCB_Reserved1 = 0;
        pSCB->SCB_SGLen = 0;
 
-       if ((pSCB->SCB_XferLen = (U32) SCpnt->request_bufflen)) {
-               pSG = (ORC_SG *) & pEScb->ESCB_SGList[0];
-               if (SCpnt->use_sg) {
-                       pSrbSG = (struct scatterlist *) SCpnt->request_buffer;
-                       count_sg = pci_map_sg(pHCB->pdev, pSrbSG, SCpnt->use_sg,
-                                       SCpnt->sc_data_direction);
-                       pSCB->SCB_SGLen = (U32) (count_sg * 8);
-                       for (i = 0; i < count_sg; i++, pSG++, pSrbSG++) {
-                               pSG->SG_Ptr = (U32) sg_dma_address(pSrbSG);
-                               pSG->SG_Len = (U32) sg_dma_len(pSrbSG);
-                       }
-               } else if (SCpnt->request_bufflen != 0) {/* Non SG */
-                       pSCB->SCB_SGLen = 0x8;
-                       SCpnt->SCp.dma_handle = pci_map_single(pHCB->pdev,
-                                       SCpnt->request_buffer,
-                                       SCpnt->request_bufflen,
-                                       SCpnt->sc_data_direction);
-                       pSG->SG_Ptr = (U32) SCpnt->SCp.dma_handle;
-                       pSG->SG_Len = (U32) SCpnt->request_bufflen;
-               } else {
-                       pSCB->SCB_SGLen = 0;
-                       pSG->SG_Ptr = 0;
-                       pSG->SG_Len = 0;
+       pSCB->SCB_XferLen = (U32) scsi_bufflen(SCpnt);
+       pSG = (ORC_SG *) & pEScb->ESCB_SGList[0];
+
+       count_sg = scsi_dma_map(SCpnt);
+       BUG_ON(count_sg < 0);
+       if (count_sg) {
+               pSCB->SCB_SGLen = (U32) (count_sg * 8);
+               scsi_for_each_sg(SCpnt, sg, count_sg, i) {
+                       pSG->SG_Ptr = (U32) sg_dma_address(sg);
+                       pSG->SG_Len = (U32) sg_dma_len(sg);
+                       pSG++;
                }
+       } else {
+               pSCB->SCB_SGLen = 0;
+               pSG->SG_Ptr = 0;
+               pSG->SG_Len = 0;
        }
        pSCB->SCB_SGPAddr = (U32) pSCB->SCB_SensePAddr;
        pSCB->SCB_HaStat = 0;
@@ -995,15 +987,7 @@ static void inia100SCBPost(BYTE * pHcb, BYTE * pScb)
        }
        pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16);
 
-       if (pSRB->use_sg) {
-               pci_unmap_sg(pHCB->pdev,
-                            (struct scatterlist *)pSRB->request_buffer,
-                            pSRB->use_sg, pSRB->sc_data_direction);
-       } else if (pSRB->request_bufflen != 0) {
-               pci_unmap_single(pHCB->pdev, pSRB->SCp.dma_handle,
-                                pSRB->request_bufflen,
-                                pSRB->sc_data_direction);
-       }
+       scsi_dma_unmap(pSRB);
 
        pSRB->scsi_done(pSRB);  /* Notify system DONE           */
 
index 8dcfe4e..47014be 100644 (file)
@@ -825,7 +825,7 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
        readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
        readcmd->count = cpu_to_le32(count<<9);
        readcmd->cid = cpu_to_le16(scmd_id(cmd));
-       readcmd->flags = cpu_to_le16(1);
+       readcmd->flags = cpu_to_le16(IO_TYPE_READ);
        readcmd->bpTotal = 0;
        readcmd->bpComplete = 0;
 
@@ -904,7 +904,7 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32
                          (void *) cmd);
 }
 
-static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
 {
        u16 fibsize;
        struct aac_raw_io *writecmd;
@@ -914,7 +914,9 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
        writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
        writecmd->count = cpu_to_le32(count<<9);
        writecmd->cid = cpu_to_le16(scmd_id(cmd));
-       writecmd->flags = 0;
+       writecmd->flags = fua ?
+               cpu_to_le16(IO_TYPE_WRITE|IO_SUREWRITE) :
+               cpu_to_le16(IO_TYPE_WRITE);
        writecmd->bpTotal = 0;
        writecmd->bpComplete = 0;
 
@@ -933,7 +935,7 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
                          (void *) cmd);
 }
 
-static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
 {
        u16 fibsize;
        struct aac_write64 *writecmd;
@@ -964,7 +966,7 @@ static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba,
                          (void *) cmd);
 }
 
-static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
 {
        u16 fibsize;
        struct aac_write *writecmd;
@@ -1498,6 +1500,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
 {
        u64 lba;
        u32 count;
+       int fua;
        int status;
        struct aac_dev *dev;
        struct fib * cmd_fibcontext;
@@ -1512,6 +1515,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
                count = scsicmd->cmnd[4];
                if (count == 0)
                        count = 256;
+               fua = 0;
        } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */
                dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", scmd_id(scsicmd)));
 
@@ -1524,6 +1528,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
                        (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
                count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) |
                        (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];
+               fua = scsicmd->cmnd[1] & 0x8;
        } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */
                dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", scmd_id(scsicmd)));
 
@@ -1531,10 +1536,12 @@ static int aac_write(struct scsi_cmnd * scsicmd)
                    | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
                count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16)
                      | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
+               fua = scsicmd->cmnd[1] & 0x8;
        } else {
                dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", scmd_id(scsicmd)));
                lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
                count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
+               fua = scsicmd->cmnd[1] & 0x8;
        }
        dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n",
          smp_processor_id(), (unsigned long long)lba, jiffies));
@@ -1549,7 +1556,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
                return 0;
        }
 
-       status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count);
+       status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
 
        /*
         *      Check that the command queued to the controller
@@ -1886,15 +1893,29 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 
        case MODE_SENSE:
        {
-               char mode_buf[4];
+               char mode_buf[7];
+               int mode_buf_length = 4;
 
                dprintk((KERN_DEBUG "MODE SENSE command.\n"));
                mode_buf[0] = 3;        /* Mode data length */
                mode_buf[1] = 0;        /* Medium type - default */
-               mode_buf[2] = 0;        /* Device-specific param, bit 8: 0/1 = write enabled/protected */
+               mode_buf[2] = 0;        /* Device-specific param,
+                                          bit 8: 0/1 = write enabled/protected
+                                          bit 4: 0/1 = FUA enabled */
+               if (dev->raw_io_interface)
+                       mode_buf[2] = 0x10;
                mode_buf[3] = 0;        /* Block descriptor length */
-
-               aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));
+               if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
+                 ((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
+                       mode_buf[0] = 6;
+                       mode_buf[4] = 8;
+                       mode_buf[5] = 1;
+                       mode_buf[6] = 0x04; /* WCE */
+                       mode_buf_length = 7;
+                       if (mode_buf_length > scsicmd->cmnd[4])
+                               mode_buf_length = scsicmd->cmnd[4];
+               }
+               aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length);
                scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
                scsicmd->scsi_done(scsicmd);
 
@@ -1902,18 +1923,33 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
        }
        case MODE_SENSE_10:
        {
-               char mode_buf[8];
+               char mode_buf[11];
+               int mode_buf_length = 8;
 
                dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n"));
                mode_buf[0] = 0;        /* Mode data length (MSB) */
                mode_buf[1] = 6;        /* Mode data length (LSB) */
                mode_buf[2] = 0;        /* Medium type - default */
-               mode_buf[3] = 0;        /* Device-specific param, bit 8: 0/1 = write enabled/protected */
+               mode_buf[3] = 0;        /* Device-specific param,
+                                          bit 8: 0/1 = write enabled/protected
+                                          bit 4: 0/1 = FUA enabled */
+               if (dev->raw_io_interface)
+                       mode_buf[3] = 0x10;
                mode_buf[4] = 0;        /* reserved */
                mode_buf[5] = 0;        /* reserved */
                mode_buf[6] = 0;        /* Block descriptor length (MSB) */
                mode_buf[7] = 0;        /* Block descriptor length (LSB) */
-               aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));
+               if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
+                 ((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
+                       mode_buf[1] = 9;
+                       mode_buf[8] = 8;
+                       mode_buf[9] = 1;
+                       mode_buf[10] = 0x04; /* WCE */
+                       mode_buf_length = 11;
+                       if (mode_buf_length > scsicmd->cmnd[8])
+                               mode_buf_length = scsicmd->cmnd[8];
+               }
+               aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length);
 
                scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
                scsicmd->scsi_done(scsicmd);
index c81edf3..fdbedb1 100644 (file)
@@ -464,12 +464,12 @@ struct adapter_ops
        int  (*adapter_restart)(struct aac_dev *dev, int bled);
        /* Transport operations */
        int  (*adapter_ioremap)(struct aac_dev * dev, u32 size);
-       irqreturn_t (*adapter_intr)(int irq, void *dev_id);
+       irq_handler_t adapter_intr;
        /* Packet operations */
        int  (*adapter_deliver)(struct fib * fib);
        int  (*adapter_bounds)(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba);
        int  (*adapter_read)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count);
-       int  (*adapter_write)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count);
+       int  (*adapter_write)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua);
        int  (*adapter_scsi)(struct fib * fib, struct scsi_cmnd * cmd);
        /* Administrative operations */
        int  (*adapter_comm)(struct aac_dev * dev, int comm);
@@ -1054,8 +1054,8 @@ struct aac_dev
 #define aac_adapter_read(fib,cmd,lba,count) \
        ((fib)->dev)->a_ops.adapter_read(fib,cmd,lba,count)
 
-#define aac_adapter_write(fib,cmd,lba,count) \
-       ((fib)->dev)->a_ops.adapter_write(fib,cmd,lba,count)
+#define aac_adapter_write(fib,cmd,lba,count,fua) \
+       ((fib)->dev)->a_ops.adapter_write(fib,cmd,lba,count,fua)
 
 #define aac_adapter_scsi(fib,cmd) \
        ((fib)->dev)->a_ops.adapter_scsi(fib,cmd)
@@ -1213,6 +1213,9 @@ struct aac_write64
        __le32          block;
        __le16          pad;
        __le16          flags;
+#define        IO_TYPE_WRITE 0x00000000
+#define        IO_TYPE_READ  0x00000001
+#define        IO_SUREWRITE  0x00000008
        struct sgmap64  sg;     // Must be last in struct because it is variable
 };
 struct aac_write_reply
index 350ea7f..a270a3f 100644 (file)
@@ -403,10 +403,6 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
 
 static int aac_slave_configure(struct scsi_device *sdev)
 {
-       if (sdev_channel(sdev) == CONTAINER_CHANNEL) {
-               sdev->skip_ms_page_8 = 1;
-               sdev->skip_ms_page_3f = 1;
-       }
        if ((sdev->type == TYPE_DISK) &&
                        (sdev_channel(sdev) != CONTAINER_CHANNEL)) {
                if (expose_physicals == 0)
index 9b3303b..2b66897 100644 (file)
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
-#include "advansys.h"
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
 #endif /* CONFIG_PCI */
@@ -2014,7 +2013,7 @@ STATIC int       AscSgListToQueue(int);
 STATIC void      AscEnableIsaDma(uchar);
 #endif /* CONFIG_ISA */
 STATIC ASC_DCNT  AscGetMaxDmaCount(ushort);
-
+static const char *advansys_info(struct Scsi_Host *shp);
 
 /*
  * --- Adv Library Constants and Macros
@@ -3970,10 +3969,6 @@ STATIC ushort asc_bus[ASC_NUM_BUS] __initdata = {
     ASC_IS_PCI,
 };
 
-/*
- * Used with the LILO 'advansys' option to eliminate or
- * limit I/O port probing at boot time, cf. advansys_setup().
- */
 STATIC int asc_iopflag = ASC_FALSE;
 STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
 
@@ -4055,10 +4050,6 @@ STATIC void         asc_prt_hex(char *f, uchar *, int);
 #endif /* ADVANSYS_DEBUG */
 
 
-/*
- * --- Linux 'struct scsi_host_template' and advansys_setup() Functions
- */
-
 #ifdef CONFIG_PROC_FS
 /*
  * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
@@ -4080,7 +4071,7 @@ STATIC void         asc_prt_hex(char *f, uchar *, int);
  * if 'prtbuf' is too small it will not be overwritten. Instead the
  * user just won't get all the available statistics.
  */
-int
+static int
 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
                off_t offset, int length, int inout)
 {
@@ -4296,7 +4287,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
  * it must not call SCSI mid-level functions including scsi_malloc()
  * and scsi_free().
  */
-int __init
+static int __init
 advansys_detect(struct scsi_host_template *tpnt)
 {
     static int          detect_called = ASC_FALSE;
@@ -5428,7 +5419,7 @@ advansys_detect(struct scsi_host_template *tpnt)
  *
  * Release resources allocated for a single AdvanSys adapter.
  */
-int
+static int
 advansys_release(struct Scsi_Host *shp)
 {
     asc_board_t    *boardp;
@@ -5475,7 +5466,7 @@ advansys_release(struct Scsi_Host *shp)
  * Note: The information line should not exceed ASC_INFO_SIZE bytes,
  * otherwise the static 'info' array will be overrun.
  */
-const char *
+static const char *
 advansys_info(struct Scsi_Host *shp)
 {
     static char     info[ASC_INFO_SIZE];
@@ -5568,7 +5559,7 @@ advansys_info(struct Scsi_Host *shp)
  * This function always returns 0. Command return status is saved
  * in the 'scp' result field.
  */
-int
+static int
 advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
 {
     struct Scsi_Host    *shp;
@@ -5656,7 +5647,7 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
  * sleeping is allowed and no locking other than for host structures is
  * required. Returns SUCCESS or FAILED.
  */
-int
+static int
 advansys_reset(struct scsi_cmnd *scp)
 {
     struct Scsi_Host     *shp;
@@ -5841,7 +5832,7 @@ advansys_reset(struct scsi_cmnd *scp)
  * ip[1]: sectors
  * ip[2]: cylinders
  */
-int
+static int
 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
                sector_t capacity, int ip[])
 {
@@ -5874,82 +5865,6 @@ advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
     return 0;
 }
 
-/*
- * advansys_setup()
- *
- * This function is called from init/main.c at boot time.
- * It it passed LILO parameters that can be set from the
- * LILO command line or in /etc/lilo.conf.
- *
- * It is used by the AdvanSys driver to either disable I/O
- * port scanning or to limit scanning to 1 - 4 I/O ports.
- * Regardless of the option setting EISA and PCI boards
- * will still be searched for and detected. This option
- * only affects searching for ISA and VL boards.
- *
- * If ADVANSYS_DEBUG is defined the driver debug level may
- * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
- *
- * Examples:
- * 1. Eliminate I/O port scanning:
- *         boot: linux advansys=
- *       or
- *         boot: linux advansys=0x0
- * 2. Limit I/O port scanning to one I/O port:
- *        boot: linux advansys=0x110
- * 3. Limit I/O port scanning to four I/O ports:
- *        boot: linux advansys=0x110,0x210,0x230,0x330
- * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
- *    set the driver debug level to 2.
- *        boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
- *
- * ints[0] - number of arguments
- * ints[1] - first argument
- * ints[2] - second argument
- * ...
- */
-void __init
-advansys_setup(char *str, int *ints)
-{
-    int    i;
-
-    if (asc_iopflag == ASC_TRUE) {
-        printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
-        return;
-    }
-
-    asc_iopflag = ASC_TRUE;
-
-    if (ints[0] > ASC_NUM_IOPORT_PROBE) {
-#ifdef ADVANSYS_DEBUG
-        if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
-            (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
-            asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
-        } else {
-#endif /* ADVANSYS_DEBUG */
-            printk("AdvanSys SCSI: only %d I/O ports accepted\n",
-                ASC_NUM_IOPORT_PROBE);
-#ifdef ADVANSYS_DEBUG
-        }
-#endif /* ADVANSYS_DEBUG */
-    }
-
-#ifdef ADVANSYS_DEBUG
-    ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
-    for (i = 1; i < ints[0]; i++) {
-        ASC_DBG2(1, " ints[%d] 0x%x", i, ints[i]);
-    }
-    ASC_DBG(1, "\n");
-#endif /* ADVANSYS_DEBUG */
-
-    for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
-        asc_ioport[i-1] = ints[i];
-        ASC_DBG2(1, "advansys_setup: asc_ioport[%d] 0x%x\n",
-            i - 1, asc_ioport[i-1]);
-    }
-}
-
-
 /*
  * --- Loadable Driver Support
  */
diff --git a/drivers/scsi/advansys.h b/drivers/scsi/advansys.h
deleted file mode 100644 (file)
index 8ee7fb1..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * advansys.h - Linux Host Driver for AdvanSys SCSI Adapters
- * 
- * Copyright (c) 1995-2000 Advanced System Products, Inc.
- * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that redistributions of source
- * code retain the above copyright notice and this comment without
- * modification.
- *
- * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
- * changed its name to ConnectCom Solutions, Inc.
- *
- */
-
-#ifndef _ADVANSYS_H
-#define _ADVANSYS_H
-
-/*
- * struct scsi_host_template function prototypes.
- */
-int advansys_detect(struct scsi_host_template *);
-int advansys_release(struct Scsi_Host *);
-const char *advansys_info(struct Scsi_Host *);
-int advansys_queuecommand(struct scsi_cmnd *, void (* done)(struct scsi_cmnd *));
-int advansys_reset(struct scsi_cmnd *);
-int advansys_biosparam(struct scsi_device *, struct block_device *,
-               sector_t, int[]);
-static int advansys_slave_configure(struct scsi_device *);
-
-/* init/main.c setup function */
-void advansys_setup(char *, int *);
-
-#endif /* _ADVANSYS_H */
index 4b4d123..85f2394 100644 (file)
 #include <linux/io.h>
 #include <linux/blkdev.h>
 #include <asm/system.h>
+#include <linux/completion.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/wait.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
 #include <linux/list.h>
-#include <asm/semaphore.h>
 #include <scsi/scsicam.h>
 
 #include "scsi.h"
@@ -551,7 +551,7 @@ struct aha152x_hostdata {
  */
 struct aha152x_scdata {
        Scsi_Cmnd *next;        /* next sc in queue */
-       struct semaphore *sem;  /* semaphore to block on */
+       struct completion *done;/* semaphore to block on */
        unsigned char cmd_len;
        unsigned char cmnd[MAX_COMMAND_SIZE];
        unsigned short use_sg;
@@ -608,7 +608,7 @@ struct aha152x_scdata {
 
 #define SCDATA(SCpnt)          ((struct aha152x_scdata *) (SCpnt)->host_scribble)
 #define SCNEXT(SCpnt)          SCDATA(SCpnt)->next
-#define SCSEM(SCpnt)           SCDATA(SCpnt)->sem
+#define SCSEM(SCpnt)           SCDATA(SCpnt)->done
 
 #define SG_ADDRESS(buffer)     ((char *) (page_address((buffer)->page)+(buffer)->offset))
 
@@ -969,7 +969,8 @@ static int setup_expected_interrupts(struct Scsi_Host *shpnt)
 /* 
  *  Queue a command and setup interrupts for a free bus.
  */
-static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int phase, void (*done)(Scsi_Cmnd *))
+static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete,
+               int phase, void (*done)(Scsi_Cmnd *))
 {
        struct Scsi_Host *shpnt = SCpnt->device->host;
        unsigned long flags;
@@ -1013,7 +1014,7 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int p
        }
 
        SCNEXT(SCpnt)           = NULL;
-       SCSEM(SCpnt)            = sem;
+       SCSEM(SCpnt)            = complete;
 
        /* setup scratch area
           SCp.ptr              : buffer pointer
@@ -1084,9 +1085,9 @@ static void reset_done(Scsi_Cmnd *SCpnt)
        DPRINTK(debug_eh, INFO_LEAD "reset_done called\n", CMDINFO(SCpnt));
 #endif
        if(SCSEM(SCpnt)) {
-               up(SCSEM(SCpnt));
+               complete(SCSEM(SCpnt));
        } else {
-               printk(KERN_ERR "aha152x: reset_done w/o semaphore\n");
+               printk(KERN_ERR "aha152x: reset_done w/o completion\n");
        }
 }
 
@@ -1139,21 +1140,6 @@ static int aha152x_abort(Scsi_Cmnd *SCpnt)
        return FAILED;
 }
 
-static void timer_expired(unsigned long p)
-{
-       Scsi_Cmnd        *SCp   = (Scsi_Cmnd *)p;
-       struct semaphore *sem   = SCSEM(SCp);
-       struct Scsi_Host *shpnt = SCp->device->host;
-       unsigned long flags;
-
-       /* remove command from issue queue */
-       DO_LOCK(flags);
-       remove_SC(&ISSUE_SC, SCp);
-       DO_UNLOCK(flags);
-
-       up(sem);
-}
-
 /*
  * Reset a device
  *
@@ -1161,14 +1147,14 @@ static void timer_expired(unsigned long p)
 static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
 {
        struct Scsi_Host *shpnt = SCpnt->device->host;
-       DECLARE_MUTEX_LOCKED(sem);
-       struct timer_list timer;
+       DECLARE_COMPLETION(done);
        int ret, issued, disconnected;
        unsigned char old_cmd_len = SCpnt->cmd_len;
        unsigned short old_use_sg = SCpnt->use_sg;
        void *old_buffer = SCpnt->request_buffer;
        unsigned old_bufflen = SCpnt->request_bufflen;
        unsigned long flags;
+       unsigned long timeleft;
 
 #if defined(AHA152X_DEBUG)
        if(HOSTDATA(shpnt)->debug & debug_eh) {
@@ -1192,15 +1178,15 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
        SCpnt->request_buffer  = NULL;
        SCpnt->request_bufflen = 0;
 
-       init_timer(&timer);
-       timer.data     = (unsigned long) SCpnt;
-       timer.expires  = jiffies + 100*HZ;   /* 10s */
-       timer.function = (void (*)(unsigned long)) timer_expired;
+       aha152x_internal_queue(SCpnt, &done, resetting, reset_done);
 
-       aha152x_internal_queue(SCpnt, &sem, resetting, reset_done);
-       add_timer(&timer);
-       down(&sem);
-       del_timer(&timer);
+       timeleft = wait_for_completion_timeout(&done, 100*HZ);
+       if (!timeleft) {
+               /* remove command from issue queue */
+               DO_LOCK(flags);
+               remove_SC(&ISSUE_SC, SCpnt);
+               DO_UNLOCK(flags);
+       }
 
        SCpnt->cmd_len         = old_cmd_len;
        SCpnt->use_sg          = old_use_sg;
index d7af9c6..e4a4f3a 100644 (file)
@@ -271,20 +271,8 @@ static irqreturn_t aha1740_intr_handle(int irq, void *dev_id)
                                continue;
                        }
                        sgptr = (struct aha1740_sg *) SCtmp->host_scribble;
-                       if (SCtmp->use_sg) {
-                               /* We used scatter-gather.
-                                  Do the unmapping dance. */
-                               dma_unmap_sg (&edev->dev,
-                                             (struct scatterlist *) SCtmp->request_buffer,
-                                             SCtmp->use_sg,
-                                             SCtmp->sc_data_direction);
-                       } else {
-                               dma_unmap_single (&edev->dev,
-                                                 sgptr->buf_dma_addr,
-                                                 SCtmp->request_bufflen,
-                                                 DMA_BIDIRECTIONAL);
-                       }
-           
+                       scsi_dma_unmap(SCtmp);
+
                        /* Free the sg block */
                        dma_free_coherent (&edev->dev,
                                           sizeof (struct aha1740_sg),
@@ -349,11 +337,9 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
        unchar target = scmd_id(SCpnt);
        struct aha1740_hostdata *host = HOSTDATA(SCpnt->device->host);
        unsigned long flags;
-       void *buff = SCpnt->request_buffer;
-       int bufflen = SCpnt->request_bufflen;
        dma_addr_t sg_dma;
        struct aha1740_sg *sgptr;
-       int ecbno;
+       int ecbno, nseg;
        DEB(int i);
 
        if(*cmd == REQUEST_SENSE) {
@@ -423,24 +409,23 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
        }
        sgptr = (struct aha1740_sg *) SCpnt->host_scribble;
        sgptr->sg_dma_addr = sg_dma;
-    
-       if (SCpnt->use_sg) {
-               struct scatterlist * sgpnt;
+
+       nseg = scsi_dma_map(SCpnt);
+       BUG_ON(nseg < 0);
+       if (nseg) {
+               struct scatterlist *sg;
                struct aha1740_chain * cptr;
-               int i, count;
+               int i;
                DEB(unsigned char * ptr);
 
                host->ecb[ecbno].sg = 1;  /* SCSI Initiator Command
                                           * w/scatter-gather*/
-               sgpnt = (struct scatterlist *) SCpnt->request_buffer;
                cptr = sgptr->sg_chain;
-               count = dma_map_sg (&host->edev->dev, sgpnt, SCpnt->use_sg,
-                                   SCpnt->sc_data_direction);
-               for(i=0; i < count; i++) {
-                       cptr[i].datalen = sg_dma_len (sgpnt + i);
-                       cptr[i].dataptr = sg_dma_address (sgpnt + i);
+               scsi_for_each_sg(SCpnt, sg, nseg, i) {
+                       cptr[i].datalen = sg_dma_len (sg);
+                       cptr[i].dataptr = sg_dma_address (sg);
                }
-               host->ecb[ecbno].datalen = count*sizeof(struct aha1740_chain);
+               host->ecb[ecbno].datalen = nseg * sizeof(struct aha1740_chain);
                host->ecb[ecbno].dataptr = sg_dma;
 #ifdef DEBUG
                printk("cptr %x: ",cptr);
@@ -448,11 +433,8 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
                for(i=0;i<24;i++) printk("%02x ", ptr[i]);
 #endif
        } else {
-               host->ecb[ecbno].datalen = bufflen;
-               sgptr->buf_dma_addr =  dma_map_single (&host->edev->dev,
-                                                      buff, bufflen,
-                                                      DMA_BIDIRECTIONAL);
-               host->ecb[ecbno].dataptr = sgptr->buf_dma_addr;
+               host->ecb[ecbno].datalen = 0;
+               host->ecb[ecbno].dataptr = 0;
        }
        host->ecb[ecbno].lun = SCpnt->device->lun;
        host->ecb[ecbno].ses = 1; /* Suppress underrun errors */
index 6054881..286ab83 100644 (file)
@@ -376,21 +376,10 @@ static __inline void
 ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
 {
        struct scsi_cmnd *cmd;
-       int direction;
 
        cmd = scb->io_ctx;
-       direction = cmd->sc_data_direction;
        ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
-       if (cmd->use_sg != 0) {
-               struct scatterlist *sg;
-
-               sg = (struct scatterlist *)cmd->request_buffer;
-               pci_unmap_sg(ahd->dev_softc, sg, cmd->use_sg, direction);
-       } else if (cmd->request_bufflen != 0) {
-               pci_unmap_single(ahd->dev_softc,
-                                scb->platform_data->buf_busaddr,
-                                cmd->request_bufflen, direction);
-       }
+       scsi_dma_unmap(cmd);
 }
 
 /******************************** Macros **************************************/
@@ -1422,6 +1411,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
        u_int    col_idx;
        uint16_t mask;
        unsigned long flags;
+       int nseg;
 
        ahd_lock(ahd, &flags);
 
@@ -1494,18 +1484,17 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
        ahd_set_residual(scb, 0);
        ahd_set_sense_residual(scb, 0);
        scb->sg_count = 0;
-       if (cmd->use_sg != 0) {
-               void    *sg;
-               struct   scatterlist *cur_seg;
-               u_int    nseg;
-               int      dir;
-
-               cur_seg = (struct scatterlist *)cmd->request_buffer;
-               dir = cmd->sc_data_direction;
-               nseg = pci_map_sg(ahd->dev_softc, cur_seg,
-                                 cmd->use_sg, dir);
+
+       nseg = scsi_dma_map(cmd);
+       BUG_ON(nseg < 0);
+       if (nseg > 0) {
+               void *sg = scb->sg_list;
+               struct scatterlist *cur_seg;
+               int i;
+
                scb->platform_data->xfer_len = 0;
-               for (sg = scb->sg_list; nseg > 0; nseg--, cur_seg++) {
+
+               scsi_for_each_sg(cmd, cur_seg, nseg, i) {
                        dma_addr_t addr;
                        bus_size_t len;
 
@@ -1513,22 +1502,8 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
                        len = sg_dma_len(cur_seg);
                        scb->platform_data->xfer_len += len;
                        sg = ahd_sg_setup(ahd, scb, sg, addr, len,
-                                         /*last*/nseg == 1);
+                                         i == (nseg - 1));
                }
-       } else if (cmd->request_bufflen != 0) {
-               void *sg;
-               dma_addr_t addr;
-               int dir;
-
-               sg = scb->sg_list;
-               dir = cmd->sc_data_direction;
-               addr = pci_map_single(ahd->dev_softc,
-                                     cmd->request_buffer,
-                                     cmd->request_bufflen, dir);
-               scb->platform_data->xfer_len = cmd->request_bufflen;
-               scb->platform_data->buf_busaddr = addr;
-               sg = ahd_sg_setup(ahd, scb, sg, addr,
-                                 cmd->request_bufflen, /*last*/TRUE);
        }
 
        LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
index ad9761b..853998b 100644 (file)
@@ -781,7 +781,7 @@ int ahd_get_transfer_dir(struct scb *scb)
 static __inline
 void ahd_set_residual(struct scb *scb, u_long resid)
 {
-       scb->io_ctx->resid = resid;
+       scsi_set_resid(scb->io_ctx, resid);
 }
 
 static __inline
@@ -793,7 +793,7 @@ void ahd_set_sense_residual(struct scb *scb, u_long resid)
 static __inline
 u_long ahd_get_residual(struct scb *scb)
 {
-       return (scb->io_ctx->resid);
+       return scsi_get_resid(scb->io_ctx);
 }
 
 static __inline
index 660f26e..1803ab6 100644 (file)
@@ -402,18 +402,8 @@ ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb)
 
        cmd = scb->io_ctx;
        ahc_sync_sglist(ahc, scb, BUS_DMASYNC_POSTWRITE);
-       if (cmd->use_sg != 0) {
-               struct scatterlist *sg;
-
-               sg = (struct scatterlist *)cmd->request_buffer;
-               pci_unmap_sg(ahc->dev_softc, sg, cmd->use_sg,
-                            cmd->sc_data_direction);
-       } else if (cmd->request_bufflen != 0) {
-               pci_unmap_single(ahc->dev_softc,
-                                scb->platform_data->buf_busaddr,
-                                cmd->request_bufflen,
-                                cmd->sc_data_direction);
-       }
+
+       scsi_dma_unmap(cmd);
 }
 
 static __inline int
@@ -1381,6 +1371,7 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
        struct   ahc_tmode_tstate *tstate;
        uint16_t mask;
        struct scb_tailq *untagged_q = NULL;
+       int nseg;
 
        /*
         * Schedule us to run later.  The only reason we are not
@@ -1472,23 +1463,21 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
        ahc_set_residual(scb, 0);
        ahc_set_sense_residual(scb, 0);
        scb->sg_count = 0;
-       if (cmd->use_sg != 0) {
+
+       nseg = scsi_dma_map(cmd);
+       BUG_ON(nseg < 0);
+       if (nseg > 0) {
                struct  ahc_dma_seg *sg;
                struct  scatterlist *cur_seg;
-               struct  scatterlist *end_seg;
-               int     nseg;
+               int i;
 
-               cur_seg = (struct scatterlist *)cmd->request_buffer;
-               nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
-                                 cmd->sc_data_direction);
-               end_seg = cur_seg + nseg;
                /* Copy the segments into the SG list. */
                sg = scb->sg_list;
                /*
                 * The sg_count may be larger than nseg if
                 * a transfer crosses a 32bit page.
-                */ 
-               while (cur_seg < end_seg) {
+                */
+               scsi_for_each_sg(cmd, cur_seg, nseg, i) {
                        dma_addr_t addr;
                        bus_size_t len;
                        int consumed;
@@ -1499,7 +1488,6 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
                                                     sg, addr, len);
                        sg += consumed;
                        scb->sg_count += consumed;
-                       cur_seg++;
                }
                sg--;
                sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
@@ -1516,33 +1504,6 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
                 */
                scb->hscb->dataptr = scb->sg_list->addr;
                scb->hscb->datacnt = scb->sg_list->len;
-       } else if (cmd->request_bufflen != 0) {
-               struct   ahc_dma_seg *sg;
-               dma_addr_t addr;
-
-               sg = scb->sg_list;
-               addr = pci_map_single(ahc->dev_softc,
-                                     cmd->request_buffer,
-                                     cmd->request_bufflen,
-                                     cmd->sc_data_direction);
-               scb->platform_data->buf_busaddr = addr;
-               scb->sg_count = ahc_linux_map_seg(ahc, scb,
-                                                 sg, addr,
-                                                 cmd->request_bufflen);
-               sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
-
-               /*
-                * Reset the sg list pointer.
-                */
-               scb->hscb->sgptr =
-                       ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
-
-               /*
-                * Copy the first SG into the "current"
-                * data pointer area.
-                */
-               scb->hscb->dataptr = sg->addr;
-               scb->hscb->datacnt = sg->len;
        } else {
                scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
                scb->hscb->dataptr = 0;
index 8fee7ed..b48dab4 100644 (file)
@@ -751,7 +751,7 @@ int ahc_get_transfer_dir(struct scb *scb)
 static __inline
 void ahc_set_residual(struct scb *scb, u_long resid)
 {
-       scb->io_ctx->resid = resid;
+       scsi_set_resid(scb->io_ctx, resid);
 }
 
 static __inline
@@ -763,7 +763,7 @@ void ahc_set_sense_residual(struct scb *scb, u_long resid)
 static __inline
 u_long ahc_get_residual(struct scb *scb)
 {
-       return (scb->io_ctx->resid);
+       return scsi_get_resid(scb->io_ctx);
 }
 
 static __inline
index a988d5a..f5e3c6b 100644 (file)
@@ -2690,17 +2690,8 @@ aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
        struct aic7xxx_scb *scbp;
        unsigned char queue_depth;
 
-  if (cmd->use_sg > 1)
-  {
-    struct scatterlist *sg;
+        scsi_dma_unmap(cmd);
 
-    sg = (struct scatterlist *)cmd->request_buffer;
-    pci_unmap_sg(p->pdev, sg, cmd->use_sg, cmd->sc_data_direction);
-  }
-  else if (cmd->request_bufflen)
-    pci_unmap_single(p->pdev, aic7xxx_mapping(cmd),
-                    cmd->request_bufflen,
-                     cmd->sc_data_direction);
   if (scb->flags & SCB_SENSE)
   {
     pci_unmap_single(p->pdev,
@@ -3869,7 +3860,7 @@ aic7xxx_calculate_residual (struct aic7xxx_host *p, struct aic7xxx_scb *scb)
        * the mid layer didn't check residual data counts to see if the
        * command needs retried.
        */
-      cmd->resid = scb->sg_length - actual;
+      scsi_set_resid(cmd, scb->sg_length - actual);
       aic7xxx_status(cmd) = hscb->target_status;
     }
   }
@@ -10137,6 +10128,7 @@ static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd,
   struct scsi_device *sdptr = cmd->device;
   unsigned char tindex = TARGET_INDEX(cmd);
   struct request *req = cmd->request;
+  int use_sg;
 
   mask = (0x01 << tindex);
   hscb = scb->hscb;
@@ -10209,8 +10201,10 @@ static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd,
   memcpy(scb->cmnd, cmd->cmnd, cmd->cmd_len);
   hscb->SCSI_cmd_pointer = cpu_to_le32(SCB_DMA_ADDR(scb, scb->cmnd));
 
-  if (cmd->use_sg)
-  {
+  use_sg = scsi_dma_map(cmd);
+  BUG_ON(use_sg < 0);
+
+  if (use_sg) {
     struct scatterlist *sg;  /* Must be mid-level SCSI code scatterlist */
 
     /*
@@ -10219,11 +10213,11 @@ static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd,
      * differences and the kernel SG list uses virtual addresses where
      * we need physical addresses.
      */
-    int i, use_sg;
+    int i;
 
-    sg = (struct scatterlist *)cmd->request_buffer;
     scb->sg_length = 0;
-    use_sg = pci_map_sg(p->pdev, sg, cmd->use_sg, cmd->sc_data_direction);
+
+
     /*
      * Copy the segments into the SG array.  NOTE!!! - We used to
      * have the first entry both in the data_pointer area and the first
@@ -10231,10 +10225,9 @@ static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd,
      * entry in both places, but now we download the address of
      * scb->sg_list[1] instead of 0 to the sg pointer in the hscb.
      */
-    for (i = 0; i < use_sg; i++)
-    {
-      unsigned int len = sg_dma_len(sg+i);
-      scb->sg_list[i].address = cpu_to_le32(sg_dma_address(sg+i));
+    scsi_for_each_sg(cmd, sg, use_sg, i) {
+      unsigned int len = sg_dma_len(sg);
+      scb->sg_list[i].address = cpu_to_le32(sg_dma_address(sg));
       scb->sg_list[i].length = cpu_to_le32(len);
       scb->sg_length += len;
     }
@@ -10244,33 +10237,13 @@ static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd,
     scb->sg_count = i;
     hscb->SG_segment_count = i;
     hscb->SG_list_pointer = cpu_to_le32(SCB_DMA_ADDR(scb, &scb->sg_list[1]));
-  }
-  else
-  {
-    if (cmd->request_bufflen)
-    {
-      unsigned int address = pci_map_single(p->pdev, cmd->request_buffer,
-                                           cmd->request_bufflen,
-                                            cmd->sc_data_direction);
-      aic7xxx_mapping(cmd) = address;
-      scb->sg_list[0].address = cpu_to_le32(address);
-      scb->sg_list[0].length = cpu_to_le32(cmd->request_bufflen);
-      scb->sg_count = 1;
-      scb->sg_length = cmd->request_bufflen;
-      hscb->SG_segment_count = 1;
-      hscb->SG_list_pointer = cpu_to_le32(SCB_DMA_ADDR(scb, &scb->sg_list[0]));
-      hscb->data_count = scb->sg_list[0].length;
-      hscb->data_pointer = scb->sg_list[0].address;
-    }
-    else
-    {
+  } else {
       scb->sg_count = 0;
       scb->sg_length = 0;
       hscb->SG_segment_count = 0;
       hscb->SG_list_pointer = 0;
       hscb->data_count = 0;
       hscb->data_pointer = 0;
-    }
   }
 }
 
diff --git a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c
deleted file mode 100644 (file)
index d5d3c4d..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Detection routine for the NCR53c710 based Amiga SCSI Controllers for Linux.
- *             Amiga MacroSystemUS WarpEngine SCSI controller.
- *             Amiga Technologies A4000T SCSI controller.
- *             Amiga Technologies/DKB A4091 SCSI controller.
- *
- * Written 1997 by Alan Hourihane <alanh@fairlite.demon.co.uk>
- * plus modifications of the 53c7xx.c driver to support the Amiga.
- */
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/blkdev.h>
-#include <linux/zorro.h>
-#include <linux/stat.h>
-
-#include <asm/setup.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/amigaints.h>
-#include <asm/amigahw.h>
-#include <asm/dma.h>
-#include <asm/irq.h>
-
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "53c7xx.h"
-#include "amiga7xx.h"
-
-
-static int amiga7xx_register_one(struct scsi_host_template *tpnt,
-                                unsigned long address)
-{
-    long long options;
-    int clock;
-
-    if (!request_mem_region(address, 0x1000, "ncr53c710"))
-       return 0;
-
-    address = (unsigned long)z_ioremap(address, 0x1000);
-    options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | OPTION_INTFLY |
-             OPTION_SYNCHRONOUS | OPTION_ALWAYS_SYNCHRONOUS |
-             OPTION_DISCONNECT;
-    clock = 50000000;  /* 50 MHz SCSI Clock */
-    ncr53c7xx_init(tpnt, 0, 710, address, 0, IRQ_AMIGA_PORTS, DMA_NONE,
-                  options, clock);
-    return 1;
-}
-
-
-#ifdef CONFIG_ZORRO
-
-static struct {
-    zorro_id id;
-    unsigned long offset;
-    int absolute;      /* offset is absolute address */
-} amiga7xx_table[] = {
-    { .id = ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS, .offset = 0xf40000,
-      .absolute = 1 },
-    { .id = ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx, .offset = 0x40000 },
-    { .id = ZORRO_PROD_CBM_A4091_1, .offset = 0x800000 },
-    { .id = ZORRO_PROD_CBM_A4091_2, .offset = 0x800000 },
-    { .id = ZORRO_PROD_GVP_GFORCE_040_060, .offset = 0x40000 },
-    { 0 }
-};
-
-static int __init amiga7xx_zorro_detect(struct scsi_host_template *tpnt)
-{
-    int num = 0, i;
-    struct zorro_dev *z = NULL;
-    unsigned long address;
-
-    while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
-       for (i = 0; amiga7xx_table[i].id; i++)
-           if (z->id == amiga7xx_table[i].id)
-               break;
-       if (!amiga7xx_table[i].id)
-           continue;
-       if (amiga7xx_table[i].absolute)
-           address = amiga7xx_table[i].offset;
-       else
-           address = z->resource.start + amiga7xx_table[i].offset;
-       num += amiga7xx_register_one(tpnt, address);
-    }
-    return num;
-}
-
-#endif /* CONFIG_ZORRO */
-
-
-int __init amiga7xx_detect(struct scsi_host_template *tpnt)
-{
-    static unsigned char called = 0;
-    int num = 0;
-
-    if (called || !MACH_IS_AMIGA)
-       return 0;
-
-    tpnt->proc_name = "Amiga7xx";
-
-    if (AMIGAHW_PRESENT(A4000_SCSI))
-       num += amiga7xx_register_one(tpnt, 0xdd0040);
-
-#ifdef CONFIG_ZORRO
-    num += amiga7xx_zorro_detect(tpnt);
-#endif
-
-    called = 1;
-    return num;
-}
-
-static int amiga7xx_release(struct Scsi_Host *shost)
-{
-       if (shost->irq)
-               free_irq(shost->irq, NULL);
-       if (shost->dma_channel != 0xff)
-               free_dma(shost->dma_channel);
-       if (shost->io_port && shost->n_io_port)
-               release_region(shost->io_port, shost->n_io_port);
-       scsi_unregister(shost);
-       return 0;
-}
-
-static struct scsi_host_template driver_template = {
-       .name                   = "Amiga NCR53c710 SCSI",
-       .detect                 = amiga7xx_detect,
-       .release                = amiga7xx_release,
-       .queuecommand           = NCR53c7xx_queue_command,
-       .abort                  = NCR53c7xx_abort,
-       .reset                  = NCR53c7xx_reset,
-       .can_queue              = 24,
-       .this_id                = 7,
-       .sg_tablesize           = 63,
-       .cmd_per_lun            = 3,
-       .use_clustering         = DISABLE_CLUSTERING
-};
-
-
-#include "scsi_module.c"
diff --git a/drivers/scsi/amiga7xx.h b/drivers/scsi/amiga7xx.h
deleted file mode 100644 (file)
index 7cd63a9..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef AMIGA7XX_H
-
-#include <linux/types.h>
-
-int amiga7xx_detect(struct scsi_host_template *);
-const char *NCR53c7x0_info(void);
-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int NCR53c7xx_abort(Scsi_Cmnd *);
-int NCR53c7x0_release (struct Scsi_Host *);
-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
-void NCR53c7x0_intr(int irq, void *dev_id);
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 3
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 24
-#endif
-
-#include <scsi/scsicam.h>
-
-#endif /* AMIGA7XX_H */
index 8b46158..672df79 100644 (file)
@@ -369,19 +369,9 @@ static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
 
 static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb)
 {
-       struct AdapterControlBlock *acb = ccb->acb;
        struct scsi_cmnd *pcmd = ccb->pcmd;
 
-       if (pcmd->use_sg != 0) {
-               struct scatterlist *sl;
-
-               sl = (struct scatterlist *)pcmd->request_buffer;
-               pci_unmap_sg(acb->pdev, sl, pcmd->use_sg, pcmd->sc_data_direction);
-       }
-       else if (pcmd->request_bufflen != 0)
-               pci_unmap_single(acb->pdev,
-                       pcmd->SCp.dma_handle,
-                       pcmd->request_bufflen, pcmd->sc_data_direction);
+       scsi_dma_unmap(pcmd);
 }
 
 static void arcmsr_ccb_complete(struct CommandControlBlock *ccb, int stand_flag)
@@ -551,6 +541,7 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb,
        int8_t *psge = (int8_t *)&arcmsr_cdb->u;
        uint32_t address_lo, address_hi;
        int arccdbsize = 0x30;
+       int nseg;
 
        ccb->pcmd = pcmd;
        memset(arcmsr_cdb, 0, sizeof (struct ARCMSR_CDB));
@@ -561,20 +552,20 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb,
        arcmsr_cdb->CdbLength = (uint8_t)pcmd->cmd_len;
        arcmsr_cdb->Context = (unsigned long)arcmsr_cdb;
        memcpy(arcmsr_cdb->Cdb, pcmd->cmnd, pcmd->cmd_len);
-       if (pcmd->use_sg) {
-               int length, sgcount, i, cdb_sgcount = 0;
-               struct scatterlist *sl;
-
-               /* Get Scatter Gather List from scsiport. */
-               sl = (struct scatterlist *) pcmd->request_buffer;
-               sgcount = pci_map_sg(acb->pdev, sl, pcmd->use_sg,
-                               pcmd->sc_data_direction);
+
+       nseg = scsi_dma_map(pcmd);
+       BUG_ON(nseg < 0);
+
+       if (nseg) {
+               int length, i, cdb_sgcount = 0;
+               struct scatterlist *sg;
+
                /* map stor port SG list to our iop SG List. */
-               for (i = 0; i < sgcount; i++) {
+               scsi_for_each_sg(pcmd, sg, nseg, i) {
                        /* Get the physical address of the current data pointer */
-                       length = cpu_to_le32(sg_dma_len(sl));
-                       address_lo = cpu_to_le32(dma_addr_lo32(sg_dma_address(sl)));
-                       address_hi = cpu_to_le32(dma_addr_hi32(sg_dma_address(sl)));
+                       length = cpu_to_le32(sg_dma_len(sg));
+                       address_lo = cpu_to_le32(dma_addr_lo32(sg_dma_address(sg)));
+                       address_hi = cpu_to_le32(dma_addr_hi32(sg_dma_address(sg)));
                        if (address_hi == 0) {
                                struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge;
 
@@ -591,32 +582,12 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb,
                                psge += sizeof (struct SG64ENTRY);
                                arccdbsize += sizeof (struct SG64ENTRY);
                        }
-                       sl++;
                        cdb_sgcount++;
                }
                arcmsr_cdb->sgcount = (uint8_t)cdb_sgcount;
-               arcmsr_cdb->DataLength = pcmd->request_bufflen;
+               arcmsr_cdb->DataLength = scsi_bufflen(pcmd);
                if ( arccdbsize > 256)
                        arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE;
-       } else if (pcmd->request_bufflen) {
-               dma_addr_t dma_addr;
-               dma_addr = pci_map_single(acb->pdev, pcmd->request_buffer,
-                               pcmd->request_bufflen, pcmd->sc_data_direction);
-               pcmd->SCp.dma_handle = dma_addr;
-               address_lo = cpu_to_le32(dma_addr_lo32(dma_addr));
-               address_hi = cpu_to_le32(dma_addr_hi32(dma_addr));
-               if (address_hi == 0) {
-                       struct  SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge;
-                       pdma_sg->address = address_lo;
-                       pdma_sg->length = pcmd->request_bufflen;
-               } else {
-                       struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge;
-                       pdma_sg->addresshigh = address_hi;
-                       pdma_sg->address = address_lo;
-                       pdma_sg->length = pcmd->request_bufflen|IS_SG64_ADDR;
-               }
-               arcmsr_cdb->sgcount = 1;
-               arcmsr_cdb->DataLength = pcmd->request_bufflen;
        }
        if (pcmd->sc_data_direction == DMA_TO_DEVICE ) {
                arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE;
@@ -848,24 +819,21 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_
        struct CMD_MESSAGE_FIELD *pcmdmessagefld;
        int retvalue = 0, transfer_len = 0;
        char *buffer;
+       struct scatterlist *sg;
        uint32_t controlcode = (uint32_t ) cmd->cmnd[5] << 24 |
                                                (uint32_t ) cmd->cmnd[6] << 16 |
                                                (uint32_t ) cmd->cmnd[7] << 8  |
                                                (uint32_t ) cmd->cmnd[8];
                                        /* 4 bytes: Areca io control code */
-       if (cmd->use_sg) {
-               struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
 
-               buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
-               if (cmd->use_sg > 1) {
-                       retvalue = ARCMSR_MESSAGE_FAIL;
-                       goto message_out;
-               }
-               transfer_len += sg->length;
-       } else {
-               buffer = cmd->request_buffer;
-               transfer_len = cmd->request_bufflen;
+       sg = scsi_sglist(cmd);
+       buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+       if (scsi_sg_count(cmd) > 1) {
+               retvalue = ARCMSR_MESSAGE_FAIL;
+               goto message_out;
        }
+       transfer_len += sg->length;
+
        if (transfer_len > sizeof(struct CMD_MESSAGE_FIELD)) {
                retvalue = ARCMSR_MESSAGE_FAIL;
                goto message_out;
@@ -1057,12 +1025,9 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_
                retvalue = ARCMSR_MESSAGE_FAIL;
        }
  message_out:
-       if (cmd->use_sg) {
-               struct scatterlist *sg;
+       sg = scsi_sglist(cmd);
+       kunmap_atomic(buffer - sg->offset, KM_IRQ0);
 
-               sg = (struct scatterlist *) cmd->request_buffer;
-               kunmap_atomic(buffer - sg->offset, KM_IRQ0);
-       }
        return retvalue;
 }
 
@@ -1085,6 +1050,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
        case INQUIRY: {
                unsigned char inqdata[36];
                char *buffer;
+               struct scatterlist *sg;
 
                if (cmd->device->lun) {
                        cmd->result = (DID_TIME_OUT << 16);
@@ -1104,21 +1070,14 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
                strncpy(&inqdata[16], "RAID controller ", 16);
                /* Product Identification */
                strncpy(&inqdata[32], "R001", 4); /* Product Revision */
-               if (cmd->use_sg) {
-                       struct scatterlist *sg;
 
-                       sg = (struct scatterlist *) cmd->request_buffer;
-                       buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
-               } else {
-                       buffer = cmd->request_buffer;
-               }
+               sg = scsi_sglist(cmd);
+               buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+
                memcpy(buffer, inqdata, sizeof(inqdata));
-               if (cmd->use_sg) {
-                       struct scatterlist *sg;
+               sg = scsi_sglist(cmd);
+               kunmap_atomic(buffer - sg->offset, KM_IRQ0);
 
-                       sg = (struct scatterlist *) cmd->request_buffer;
-                       kunmap_atomic(buffer - sg->offset, KM_IRQ0);
-               }
                cmd->scsi_done(cmd);
        }
        break;
diff --git a/drivers/scsi/bvme6000.c b/drivers/scsi/bvme6000.c
deleted file mode 100644 (file)
index 599b400..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Detection routine for the NCR53c710 based BVME6000 SCSI Controllers for Linux.
- *
- * Based on work by Alan Hourihane
- */
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/blkdev.h>
-#include <linux/zorro.h>
-
-#include <asm/setup.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/bvme6000hw.h>
-#include <asm/irq.h>
-
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "53c7xx.h"
-#include "bvme6000.h"
-
-#include<linux/stat.h>
-
-
-int bvme6000_scsi_detect(struct scsi_host_template *tpnt)
-{
-    static unsigned char called = 0;
-    int clock;
-    long long options;
-
-    if (called)
-       return 0;
-    if (!MACH_IS_BVME6000)
-       return 0;
-
-    tpnt->proc_name = "BVME6000";
-
-    options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT;
-
-    clock = 40000000;  /* 66MHz SCSI Clock */
-
-    ncr53c7xx_init(tpnt, 0, 710, (unsigned long)BVME_NCR53C710_BASE,
-                       0, BVME_IRQ_SCSI, DMA_NONE,
-                       options, clock);
-    called = 1;
-    return 1;
-}
-
-static int bvme6000_scsi_release(struct Scsi_Host *shost)
-{
-       if (shost->irq)
-               free_irq(shost->irq, NULL);
-       if (shost->dma_channel != 0xff)
-               free_dma(shost->dma_channel);
-       if (shost->io_port && shost->n_io_port)
-               release_region(shost->io_port, shost->n_io_port);
-       scsi_unregister(shost);
-       return 0;
-}
-
-static struct scsi_host_template driver_template = {
-       .name                   = "BVME6000 NCR53c710 SCSI",
-       .detect                 = bvme6000_scsi_detect,
-       .release                = bvme6000_scsi_release,
-       .queuecommand           = NCR53c7xx_queue_command,
-       .abort                  = NCR53c7xx_abort,
-       .reset                  = NCR53c7xx_reset,
-       .can_queue              = 24,
-       .this_id                = 7,
-       .sg_tablesize           = 63,
-       .cmd_per_lun            = 3,
-       .use_clustering         = DISABLE_CLUSTERING
-};
-
-
-#include "scsi_module.c"
diff --git a/drivers/scsi/bvme6000.h b/drivers/scsi/bvme6000.h
deleted file mode 100644 (file)
index ea3e4b2..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef BVME6000_SCSI_H
-#define BVME6000_SCSI_H
-
-#include <linux/types.h>
-
-int bvme6000_scsi_detect(struct scsi_host_template *);
-const char *NCR53c7x0_info(void);
-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int NCR53c7xx_abort(Scsi_Cmnd *);
-int NCR53c7x0_release (struct Scsi_Host *);
-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
-void NCR53c7x0_intr(int irq, void *dev_id);
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 3
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 24
-#endif
-
-#include <scsi/scsicam.h>
-
-#endif /* BVME6000_SCSI_H */
index 2d38025..a83e9f1 100644 (file)
@@ -1609,8 +1609,9 @@ static int eata2x_detect(struct scsi_host_template *tpnt)
 
 static void map_dma(unsigned int i, struct hostdata *ha)
 {
-       unsigned int k, count, pci_dir;
-       struct scatterlist *sgpnt;
+       unsigned int k, pci_dir;
+       int count;
+       struct scatterlist *sg;
        struct mscp *cpp;
        struct scsi_cmnd *SCpnt;
 
@@ -1625,38 +1626,19 @@ static void map_dma(unsigned int i, struct hostdata *ha)
 
        cpp->sense_len = sizeof SCpnt->sense_buffer;
 
-       if (!SCpnt->use_sg) {
-
-               /* If we get here with PCI_DMA_NONE, pci_map_single triggers a BUG() */
-               if (!SCpnt->request_bufflen)
-                       pci_dir = PCI_DMA_BIDIRECTIONAL;
-
-               if (SCpnt->request_buffer)
-                       cpp->data_address = H2DEV(pci_map_single(ha->pdev,
-                                                                SCpnt->
-                                                                request_buffer,
-                                                                SCpnt->
-                                                                request_bufflen,
-                                                                pci_dir));
-
-               cpp->data_len = H2DEV(SCpnt->request_bufflen);
-               return;
-       }
-
-       sgpnt = (struct scatterlist *)SCpnt->request_buffer;
-       count = pci_map_sg(ha->pdev, sgpnt, SCpnt->use_sg, pci_dir);
-
-       for (k = 0; k < count; k++) {
-               cpp->sglist[k].address = H2DEV(sg_dma_address(&sgpnt[k]));
-               cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(&sgpnt[k]));
+       count = scsi_dma_map(SCpnt);
+       BUG_ON(count < 0);
+       scsi_for_each_sg(SCpnt, sg, count, k) {
+               cpp->sglist[k].address = H2DEV(sg_dma_address(sg));
+               cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(sg));
        }
 
        cpp->sg = 1;
        cpp->data_address = H2DEV(pci_map_single(ha->pdev, cpp->sglist,
-                                                SCpnt->use_sg *
+                                                scsi_sg_count(SCpnt) *
                                                 sizeof(struct sg_list),
                                                 pci_dir));
-       cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list)));
+       cpp->data_len = H2DEV((scsi_sg_count(SCpnt) * sizeof(struct sg_list)));
 }
 
 static void unmap_dma(unsigned int i, struct hostdata *ha)
@@ -1673,9 +1655,7 @@ static void unmap_dma(unsigned int i, struct hostdata *ha)
                pci_unmap_single(ha->pdev, DEV2H(cpp->sense_addr),
                                 DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
 
-       if (SCpnt->use_sg)
-               pci_unmap_sg(ha->pdev, SCpnt->request_buffer, SCpnt->use_sg,
-                            pci_dir);
+       scsi_dma_unmap(SCpnt);
 
        if (!DEV2H(cpp->data_len))
                pci_dir = PCI_DMA_BIDIRECTIONAL;
@@ -1700,9 +1680,9 @@ static void sync_dma(unsigned int i, struct hostdata *ha)
                                            DEV2H(cpp->sense_len),
                                            PCI_DMA_FROMDEVICE);
 
-       if (SCpnt->use_sg)
-               pci_dma_sync_sg_for_cpu(ha->pdev, SCpnt->request_buffer,
-                                       SCpnt->use_sg, pci_dir);
+       if (scsi_sg_count(SCpnt))
+               pci_dma_sync_sg_for_cpu(ha->pdev, scsi_sglist(SCpnt),
+                                       scsi_sg_count(SCpnt), pci_dir);
 
        if (!DEV2H(cpp->data_len))
                pci_dir = PCI_DMA_BIDIRECTIONAL;
index 5d4ea6f..36169d5 100644 (file)
@@ -410,6 +410,8 @@ static irqreturn_t       do_fdomain_16x0_intr( int irq, void *dev_id );
 static char * fdomain = NULL;
 module_param(fdomain, charp, 0);
 
+#ifndef PCMCIA
+
 static unsigned long addresses[] = {
    0xc8000,
    0xca000,
@@ -426,6 +428,8 @@ static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
 
 static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
 
+#endif /* !PCMCIA */
+
 /*
 
   READ THIS BEFORE YOU ADD A SIGNATURE!
@@ -458,6 +462,8 @@ static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
 
 */
 
+#ifndef PCMCIA
+
 static struct signature {
    const char *signature;
    int  sig_offset;
@@ -503,6 +509,8 @@ static struct signature {
 
 #define SIGNATURE_COUNT ARRAY_SIZE(signatures)
 
+#endif /* !PCMCIA */
+
 static void print_banner( struct Scsi_Host *shpnt )
 {
    if (!shpnt) return;         /* This won't ever happen */
@@ -633,6 +641,8 @@ static int fdomain_test_loopback( void )
    return 0;
 }
 
+#ifndef PCMCIA
+
 /* fdomain_get_irq assumes that we have a valid MCA ID for a
    TMC-1660/TMC-1680 Future Domain board.  Now, check to be sure the
    bios_base matches these ports.  If someone was unlucky enough to have
@@ -667,7 +677,6 @@ static int fdomain_get_irq( int base )
 
 static int fdomain_isa_detect( int *irq, int *iobase )
 {
-#ifndef PCMCIA
    int i, j;
    int base = 0xdeadbeef;
    int flag = 0;
@@ -786,11 +795,22 @@ found:
    *iobase = base;
 
    return 1;                   /* success */
-#else
-   return 0;
-#endif
 }
 
+#else /* PCMCIA */
+
+static int fdomain_isa_detect( int *irq, int *iobase )
+{
+       if (irq)
+               *irq = 0;
+       if (iobase)
+               *iobase = 0;
+       return 0;
+}
+
+#endif /* !PCMCIA */
+
+
 /* PCI detection function: int fdomain_pci_bios_detect(int* irq, int*
    iobase) This function gets the Interrupt Level and I/O base address from
    the PCI configuration registers. */
@@ -1345,16 +1365,15 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 
 #if ERRORS_ONLY
       if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
-        if ((unsigned char)(*((char *)current_SC->request_buffer+2)) & 0x0f) {
+             char *buf = scsi_sglist(current_SC);
+        if ((unsigned char)(*(buf + 2)) & 0x0f) {
            unsigned char key;
            unsigned char code;
            unsigned char qualifier;
 
-           key = (unsigned char)(*((char *)current_SC->request_buffer + 2))
-                 & 0x0f;
-           code = (unsigned char)(*((char *)current_SC->request_buffer + 12));
-           qualifier = (unsigned char)(*((char *)current_SC->request_buffer
-                                         + 13));
+           key = (unsigned char)(*(buf + 2)) & 0x0f;
+           code = (unsigned char)(*(buf + 12));
+           qualifier = (unsigned char)(*(buf + 13));
 
            if (key != UNIT_ATTENTION
                && !(key == NOT_READY
@@ -1405,8 +1424,8 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
    printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
           SCpnt->target,
           *(unsigned char *)SCpnt->cmnd,
-          SCpnt->use_sg,
-          SCpnt->request_bufflen );
+          scsi_sg_count(SCpnt),
+          scsi_bufflen(SCpnt));
 #endif
 
    fdomain_make_bus_idle();
@@ -1416,20 +1435,19 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
 
    /* Initialize static data */
 
-   if (current_SC->use_sg) {
-      current_SC->SCp.buffer =
-           (struct scatterlist *)current_SC->request_buffer;
-      current_SC->SCp.ptr              = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
-      current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
-      current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
+   if (scsi_sg_count(current_SC)) {
+          current_SC->SCp.buffer = scsi_sglist(current_SC);
+          current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page)
+                  + current_SC->SCp.buffer->offset;
+          current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
+          current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
    } else {
-      current_SC->SCp.ptr              = (char *)current_SC->request_buffer;
-      current_SC->SCp.this_residual    = current_SC->request_bufflen;
-      current_SC->SCp.buffer           = NULL;
-      current_SC->SCp.buffers_residual = 0;
+          current_SC->SCp.ptr              = 0;
+          current_SC->SCp.this_residual    = 0;
+          current_SC->SCp.buffer           = NULL;
+          current_SC->SCp.buffers_residual = 0;
    }
-        
-   
+
    current_SC->SCp.Status              = 0;
    current_SC->SCp.Message             = 0;
    current_SC->SCp.have_data_in        = 0;
@@ -1472,8 +1490,8 @@ static void print_info(struct scsi_cmnd *SCpnt)
           SCpnt->SCp.phase,
           SCpnt->device->id,
           *(unsigned char *)SCpnt->cmnd,
-          SCpnt->use_sg,
-          SCpnt->request_bufflen );
+          scsi_sg_count(SCpnt),
+          scsi_bufflen(SCpnt));
    printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
           SCpnt->SCp.sent_command,
           SCpnt->SCp.have_data_in,
index 60446b8..d0b95ce 100644 (file)
@@ -876,7 +876,7 @@ static int __init gdth_search_pci(gdth_pci_str *pcistr)
 /* Vortex only makes RAID controllers.
  * We do not really want to specify all 550 ids here, so wildcard match.
  */
-static struct pci_device_id gdthtable[] __attribute_used__ = {
+static struct pci_device_id gdthtable[] __maybe_unused = {
     {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID},
     {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID}, 
     {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID}, 
@@ -1955,7 +1955,7 @@ static int __init gdth_search_drives(int hanum)
         for (j = 0; j < 12; ++j) 
             rtc[j] = CMOS_READ(j);
     } while (rtc[0] != CMOS_READ(0));
-    spin_lock_irqrestore(&rtc_lock, flags);
+    spin_unlock_irqrestore(&rtc_lock, flags);
     TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(ulong32 *)&rtc[0],
             *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]));
     /* 3. send to controller firmware */
index 0e57fb6..4275d1b 100644 (file)
 #include <linux/mca.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>
-#include <linux/mca-legacy.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 
 #include "scsi.h"
 #include <scsi/scsi_host.h>
-#include "ibmmca.h"
+
+/* Common forward declarations for all Linux-versions: */
+static int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
+static int ibmmca_abort (Scsi_Cmnd *);
+static int ibmmca_host_reset (Scsi_Cmnd *);
+static int ibmmca_biosparam (struct scsi_device *, struct block_device *, sector_t, int *);
+static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout);
+
+
 
 /* current version of this driver-source: */
 #define IBMMCA_SCSI_DRIVER_VERSION "4.0b-ac"
 #define IM_DEBUG_CMD_DEVICE    TYPE_TAPE
 
 /* relative addresses of hardware registers on a subsystem */
-#define IM_CMD_REG(hi) (hosts[(hi)]->io_port)  /*Command Interface, (4 bytes long) */
-#define IM_ATTN_REG(hi)        (hosts[(hi)]->io_port+4)        /*Attention (1 byte) */
-#define IM_CTR_REG(hi) (hosts[(hi)]->io_port+5)        /*Basic Control (1 byte) */
-#define IM_INTR_REG(hi)        (hosts[(hi)]->io_port+6)        /*Interrupt Status (1 byte, r/o) */
-#define IM_STAT_REG(hi)        (hosts[(hi)]->io_port+7)        /*Basic Status (1 byte, read only) */
+#define IM_CMD_REG(h)  ((h)->io_port)  /*Command Interface, (4 bytes long) */
+#define IM_ATTN_REG(h) ((h)->io_port+4)        /*Attention (1 byte) */
+#define IM_CTR_REG(h)  ((h)->io_port+5)        /*Basic Control (1 byte) */
+#define IM_INTR_REG(h) ((h)->io_port+6)        /*Interrupt Status (1 byte, r/o) */
+#define IM_STAT_REG(h) ((h)->io_port+7)        /*Basic Status (1 byte, read only) */
 
 /* basic I/O-port of first adapter */
 #define IM_IO_PORT     0x3540
@@ -266,30 +273,36 @@ static int global_adapter_speed = 0;      /* full speed by default */
     if ((display_mode & LED_ACTIVITY)||(!display_mode)) \
     outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR); }
 
-/*list of supported subsystems */
-struct subsys_list_struct {
-       unsigned short mca_id;
-       char *description;
-};
-
 /* types of different supported hardware that goes to hostdata special */
 #define IBM_SCSI2_FW     0
 #define IBM_7568_WCACHE  1
 #define IBM_EXP_UNIT     2
 #define IBM_SCSI_WCACHE  3
 #define IBM_SCSI         4
+#define IBM_INTEGSCSI   5
 
 /* other special flags for hostdata structure */
 #define FORCED_DETECTION         100
 #define INTEGRATED_SCSI          101
 
 /* List of possible IBM-SCSI-adapters */
-static struct subsys_list_struct subsys_list[] = {
-       {0x8efc, "IBM SCSI-2 F/W Adapter"},     /* special = 0 */
-       {0x8efd, "IBM 7568 Industrial Computer SCSI Adapter w/Cache"},  /* special = 1 */
-       {0x8ef8, "IBM Expansion Unit SCSI Controller"}, /* special = 2 */
-       {0x8eff, "IBM SCSI Adapter w/Cache"},   /* special = 3 */
-       {0x8efe, "IBM SCSI Adapter"},   /* special = 4 */
+static short ibmmca_id_table[] = {
+       0x8efc,
+       0x8efd,
+       0x8ef8,
+       0x8eff,
+       0x8efe,
+       /* No entry for integrated SCSI, that's part of the register */
+       0
+};
+
+static const char *ibmmca_description[] = {
+       "IBM SCSI-2 F/W Adapter",       /* special = 0 */
+       "IBM 7568 Industrial Computer SCSI Adapter w/Cache",    /* special = 1 */
+       "IBM Expansion Unit SCSI Controller",   /* special = 2 */
+       "IBM SCSI Adapter w/Cache",     /* special = 3 */
+       "IBM SCSI Adapter",     /* special = 4 */
+       "IBM Integrated SCSI Controller", /* special = 5 */
 };
 
 /* Max number of logical devices (can be up from 0 to 14).  15 is the address
@@ -375,30 +388,30 @@ struct ibmmca_hostdata {
 };
 
 /* macros to access host data structure */
-#define subsystem_pun(hi) (hosts[(hi)]->this_id)
-#define subsystem_maxid(hi) (hosts[(hi)]->max_id)
-#define ld(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_ld)
-#define get_ldn(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_get_ldn)
-#define get_scsi(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_get_scsi)
-#define local_checking_phase_flag(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_local_checking_phase_flag)
-#define got_interrupt(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_got_interrupt)
-#define stat_result(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_stat_result)
-#define reset_status(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_reset_status)
-#define last_scsi_command(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_command)
-#define last_scsi_type(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_type)
-#define last_scsi_blockcount(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_blockcount)
-#define last_scsi_logical_block(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_logical_block)
-#define last_scsi_type(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_type)
-#define next_ldn(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_next_ldn)
-#define IBM_DS(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_IBM_DS)
-#define special(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_special)
-#define subsystem_connector_size(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_connector_size)
-#define adapter_speed(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_adapter_speed)
-#define pos2(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[2])
-#define pos3(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[3])
-#define pos4(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[4])
-#define pos5(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[5])
-#define pos6(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[6])
+#define subsystem_pun(h) ((h)->this_id)
+#define subsystem_maxid(h) ((h)->max_id)
+#define ld(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_ld)
+#define get_ldn(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_get_ldn)
+#define get_scsi(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_get_scsi)
+#define local_checking_phase_flag(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_local_checking_phase_flag)
+#define got_interrupt(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_got_interrupt)
+#define stat_result(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_stat_result)
+#define reset_status(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_reset_status)
+#define last_scsi_command(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_last_scsi_command)
+#define last_scsi_type(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_last_scsi_type)
+#define last_scsi_blockcount(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_last_scsi_blockcount)
+#define last_scsi_logical_block(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_last_scsi_logical_block)
+#define last_scsi_type(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_last_scsi_type)
+#define next_ldn(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_next_ldn)
+#define IBM_DS(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_IBM_DS)
+#define special(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_special)
+#define subsystem_connector_size(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_connector_size)
+#define adapter_speed(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_adapter_speed)
+#define pos2(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_pos[2])
+#define pos3(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_pos[3])
+#define pos4(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_pos[4])
+#define pos5(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_pos[5])
+#define pos6(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_pos[6])
 
 /* Define a arbitrary number as subsystem-marker-type. This number is, as
    described in the ANSI-SCSI-standard, not occupied by other device-types. */
@@ -459,11 +472,6 @@ MODULE_LICENSE("GPL");
 /*counter of concurrent disk read/writes, to turn on/off disk led */
 static int disk_rw_in_progress = 0;
 
-/* host information */
-static int found = 0;
-static struct Scsi_Host *hosts[IM_MAX_HOSTS + 1] = {
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
 static unsigned int pos[8];    /* whole pos register-line for diagnosis */
 /* Taking into account the additions, made by ZP Gu.
  * This selects now the preset value from the configfile and
@@ -474,70 +482,68 @@ static char ibm_ansi_order = 1;
 static char ibm_ansi_order = 0;
 #endif
 
-static void issue_cmd(int, unsigned long, unsigned char);
+static void issue_cmd(struct Scsi_Host *, unsigned long, unsigned char);
 static void internal_done(Scsi_Cmnd * cmd);
-static void check_devices(int, int);
-static int immediate_assign(int, unsigned int, unsigned int, unsigned int, unsigned int);
-static int immediate_feature(int, unsigned int, unsigned int);
+static void check_devices(struct Scsi_Host *, int);
+static int immediate_assign(struct Scsi_Host *, unsigned int, unsigned int, unsigned int, unsigned int);
+static int immediate_feature(struct Scsi_Host *, unsigned int, unsigned int);
 #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
-static int immediate_reset(int, unsigned int);
+static int immediate_reset(struct Scsi_Host *, unsigned int);
 #endif
-static int device_inquiry(int, int);
-static int read_capacity(int, int);
-static int get_pos_info(int);
+static int device_inquiry(struct Scsi_Host *, int);
+static int read_capacity(struct Scsi_Host *, int);
+static int get_pos_info(struct Scsi_Host *);
 static char *ti_p(int);
 static char *ti_l(int);
 static char *ibmrate(unsigned int, int);
 static int probe_display(int);
-static int probe_bus_mode(int);
-static int device_exists(int, int, int *, int *);
-static struct Scsi_Host *ibmmca_register(struct scsi_host_template *, int, int, int, char *);
+static int probe_bus_mode(struct Scsi_Host *);
+static int device_exists(struct Scsi_Host *, int, int *, int *);
 static int option_setup(char *);
 /* local functions needed for proc_info */
-static int ldn_access_load(int, int);
-static int ldn_access_total_read_write(int);
+static int ldn_access_load(struct Scsi_Host *, int);
+static int ldn_access_total_read_write(struct Scsi_Host *);
 
 static irqreturn_t interrupt_handler(int irq, void *dev_id)
 {
-       int host_index, ihost_index;
        unsigned int intr_reg;
        unsigned int cmd_result;
        unsigned int ldn;
+       unsigned long flags;
        Scsi_Cmnd *cmd;
        int lastSCSI;
-       struct Scsi_Host *dev = dev_id;
+       struct device *dev = dev_id;
+       struct Scsi_Host *shpnt = dev_get_drvdata(dev);
 
-       spin_lock(dev->host_lock);
-           /* search for one adapter-response on shared interrupt */
-           for (host_index = 0; hosts[host_index] && !(inb(IM_STAT_REG(host_index)) & IM_INTR_REQUEST); host_index++);
-       /* return if some other device on this IRQ caused the interrupt */
-       if (!hosts[host_index]) {
-               spin_unlock(dev->host_lock);
+       spin_lock_irqsave(shpnt->host_lock, flags);
+
+       if(!(inb(IM_STAT_REG(shpnt)) & IM_INTR_REQUEST)) {
+               spin_unlock_irqrestore(shpnt->host_lock, flags);
                return IRQ_NONE;
        }
 
        /* the reset-function already did all the job, even ints got
           renabled on the subsystem, so just return */
-       if ((reset_status(host_index) == IM_RESET_NOT_IN_PROGRESS_NO_INT) || (reset_status(host_index) == IM_RESET_FINISHED_OK_NO_INT)) {
-               reset_status(host_index) = IM_RESET_NOT_IN_PROGRESS;
-               spin_unlock(dev->host_lock);
+       if ((reset_status(shpnt) == IM_RESET_NOT_IN_PROGRESS_NO_INT) || (reset_status(shpnt) == IM_RESET_FINISHED_OK_NO_INT)) {
+               reset_status(shpnt) = IM_RESET_NOT_IN_PROGRESS;
+               spin_unlock_irqrestore(shpnt->host_lock, flags);
                return IRQ_HANDLED;
        }
 
        /*must wait for attention reg not busy, then send EOI to subsystem */
        while (1) {
-               if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY))
+               if (!(inb(IM_STAT_REG(shpnt)) & IM_BUSY))
                        break;
                cpu_relax();
        }
-       ihost_index = host_index;
+
        /*get command result and logical device */
-       intr_reg = (unsigned char) (inb(IM_INTR_REG(ihost_index)));
+       intr_reg = (unsigned char) (inb(IM_INTR_REG(shpnt)));
        cmd_result = intr_reg & 0xf0;
        ldn = intr_reg & 0x0f;
        /* get the last_scsi_command here */
-       lastSCSI = last_scsi_command(ihost_index)[ldn];
-       outb(IM_EOI | ldn, IM_ATTN_REG(ihost_index));
+       lastSCSI = last_scsi_command(shpnt)[ldn];
+       outb(IM_EOI | ldn, IM_ATTN_REG(shpnt));
        
        /*these should never happen (hw fails, or a local programming bug) */
        if (!global_command_error_excuse) {
@@ -547,38 +553,38 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id)
                case IM_SOFTWARE_SEQUENCING_ERROR:
                case IM_CMD_ERROR:
                        printk(KERN_ERR "IBM MCA SCSI: Fatal Subsystem ERROR!\n");
-                       printk(KERN_ERR "              Last cmd=0x%x, ena=%x, len=", lastSCSI, ld(ihost_index)[ldn].scb.enable);
-                       if (ld(ihost_index)[ldn].cmd)
-                               printk("%ld/%ld,", (long) (ld(ihost_index)[ldn].cmd->request_bufflen), (long) (ld(ihost_index)[ldn].scb.sys_buf_length));
+                       printk(KERN_ERR "              Last cmd=0x%x, ena=%x, len=", lastSCSI, ld(shpnt)[ldn].scb.enable);
+                       if (ld(shpnt)[ldn].cmd)
+                               printk("%ld/%ld,", (long) (scsi_bufflen(ld(shpnt)[ldn].cmd)), (long) (ld(shpnt)[ldn].scb.sys_buf_length));
                        else
                                printk("none,");
-                       if (ld(ihost_index)[ldn].cmd)
-                               printk("Blocksize=%d", ld(ihost_index)[ldn].scb.u2.blk.length);
+                       if (ld(shpnt)[ldn].cmd)
+                               printk("Blocksize=%d", ld(shpnt)[ldn].scb.u2.blk.length);
                        else
                                printk("Blocksize=none");
-                       printk(", host=0x%x, ldn=0x%x\n", ihost_index, ldn);
-                       if (ld(ihost_index)[ldn].cmd) {
-                               printk(KERN_ERR "Blockcount=%d/%d\n", last_scsi_blockcount(ihost_index)[ldn], ld(ihost_index)[ldn].scb.u2.blk.count);
-                               printk(KERN_ERR "Logical block=%lx/%lx\n", last_scsi_logical_block(ihost_index)[ldn], ld(ihost_index)[ldn].scb.u1.log_blk_adr);
+                       printk(", host=%p, ldn=0x%x\n", shpnt, ldn);
+                       if (ld(shpnt)[ldn].cmd) {
+                               printk(KERN_ERR "Blockcount=%d/%d\n", last_scsi_blockcount(shpnt)[ldn], ld(shpnt)[ldn].scb.u2.blk.count);
+                               printk(KERN_ERR "Logical block=%lx/%lx\n", last_scsi_logical_block(shpnt)[ldn], ld(shpnt)[ldn].scb.u1.log_blk_adr);
                        }
                        printk(KERN_ERR "Reason given: %s\n", (cmd_result == IM_ADAPTER_HW_FAILURE) ? "HARDWARE FAILURE" : (cmd_result == IM_SOFTWARE_SEQUENCING_ERROR) ? "SOFTWARE SEQUENCING ERROR" : (cmd_result == IM_CMD_ERROR) ? "COMMAND ERROR" : "UNKNOWN");
                        /* if errors appear, enter this section to give detailed info */
                        printk(KERN_ERR "IBM MCA SCSI: Subsystem Error-Status follows:\n");
-                       printk(KERN_ERR "              Command Type................: %x\n", last_scsi_type(ihost_index)[ldn]);
-                       printk(KERN_ERR "              Attention Register..........: %x\n", inb(IM_ATTN_REG(ihost_index)));
-                       printk(KERN_ERR "              Basic Control Register......: %x\n", inb(IM_CTR_REG(ihost_index)));
+                       printk(KERN_ERR "              Command Type................: %x\n", last_scsi_type(shpnt)[ldn]);
+                       printk(KERN_ERR "              Attention Register..........: %x\n", inb(IM_ATTN_REG(shpnt)));
+                       printk(KERN_ERR "              Basic Control Register......: %x\n", inb(IM_CTR_REG(shpnt)));
                        printk(KERN_ERR "              Interrupt Status Register...: %x\n", intr_reg);
-                       printk(KERN_ERR "              Basic Status Register.......: %x\n", inb(IM_STAT_REG(ihost_index)));
-                       if ((last_scsi_type(ihost_index)[ldn] == IM_SCB) || (last_scsi_type(ihost_index)[ldn] == IM_LONG_SCB)) {
-                               printk(KERN_ERR "              SCB-Command.................: %x\n", ld(ihost_index)[ldn].scb.command);
-                               printk(KERN_ERR "              SCB-Enable..................: %x\n", ld(ihost_index)[ldn].scb.enable);
-                               printk(KERN_ERR "              SCB-logical block address...: %lx\n", ld(ihost_index)[ldn].scb.u1.log_blk_adr);
-                               printk(KERN_ERR "              SCB-system buffer address...: %lx\n", ld(ihost_index)[ldn].scb.sys_buf_adr);
-                               printk(KERN_ERR "              SCB-system buffer length....: %lx\n", ld(ihost_index)[ldn].scb.sys_buf_length);
-                               printk(KERN_ERR "              SCB-tsb address.............: %lx\n", ld(ihost_index)[ldn].scb.tsb_adr);
-                               printk(KERN_ERR "              SCB-Chain address...........: %lx\n", ld(ihost_index)[ldn].scb.scb_chain_adr);
-                               printk(KERN_ERR "              SCB-block count.............: %x\n", ld(ihost_index)[ldn].scb.u2.blk.count);
-                               printk(KERN_ERR "              SCB-block length............: %x\n", ld(ihost_index)[ldn].scb.u2.blk.length);
+                       printk(KERN_ERR "              Basic Status Register.......: %x\n", inb(IM_STAT_REG(shpnt)));
+                       if ((last_scsi_type(shpnt)[ldn] == IM_SCB) || (last_scsi_type(shpnt)[ldn] == IM_LONG_SCB)) {
+                               printk(KERN_ERR "              SCB-Command.................: %x\n", ld(shpnt)[ldn].scb.command);
+                               printk(KERN_ERR "              SCB-Enable..................: %x\n", ld(shpnt)[ldn].scb.enable);
+                               printk(KERN_ERR "              SCB-logical block address...: %lx\n", ld(shpnt)[ldn].scb.u1.log_blk_adr);
+                               printk(KERN_ERR "              SCB-system buffer address...: %lx\n", ld(shpnt)[ldn].scb.sys_buf_adr);
+                               printk(KERN_ERR "              SCB-system buffer length....: %lx\n", ld(shpnt)[ldn].scb.sys_buf_length);
+                               printk(KERN_ERR "              SCB-tsb address.............: %lx\n", ld(shpnt)[ldn].scb.tsb_adr);
+                               printk(KERN_ERR "              SCB-Chain address...........: %lx\n", ld(shpnt)[ldn].scb.scb_chain_adr);
+                               printk(KERN_ERR "              SCB-block count.............: %x\n", ld(shpnt)[ldn].scb.u2.blk.count);
+                               printk(KERN_ERR "              SCB-block length............: %x\n", ld(shpnt)[ldn].scb.u2.blk.length);
                        }
                        printk(KERN_ERR "              Send this report to the maintainer.\n");
                        panic("IBM MCA SCSI: Fatal error message from the subsystem (0x%X,0x%X)!\n", lastSCSI, cmd_result);
@@ -600,72 +606,73 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id)
                }
        }
        /* if no panic appeared, increase the interrupt-counter */
-       IBM_DS(ihost_index).total_interrupts++;
+       IBM_DS(shpnt).total_interrupts++;
        /*only for local checking phase */
-       if (local_checking_phase_flag(ihost_index)) {
-               stat_result(ihost_index) = cmd_result;
-               got_interrupt(ihost_index) = 1;
-               reset_status(ihost_index) = IM_RESET_FINISHED_OK;
-               last_scsi_command(ihost_index)[ldn] = NO_SCSI;
-               spin_unlock(dev->host_lock);
+       if (local_checking_phase_flag(shpnt)) {
+               stat_result(shpnt) = cmd_result;
+               got_interrupt(shpnt) = 1;
+               reset_status(shpnt) = IM_RESET_FINISHED_OK;
+               last_scsi_command(shpnt)[ldn] = NO_SCSI;
+               spin_unlock_irqrestore(shpnt->host_lock, flags);
                return IRQ_HANDLED;
        }
        /* handling of commands coming from upper level of scsi driver */
-       if (last_scsi_type(ihost_index)[ldn] == IM_IMM_CMD) {
+       if (last_scsi_type(shpnt)[ldn] == IM_IMM_CMD) {
                /* verify ldn, and may handle rare reset immediate command */
-               if ((reset_status(ihost_index) == IM_RESET_IN_PROGRESS) && (last_scsi_command(ihost_index)[ldn] == IM_RESET_IMM_CMD)) {
+               if ((reset_status(shpnt) == IM_RESET_IN_PROGRESS) && (last_scsi_command(shpnt)[ldn] == IM_RESET_IMM_CMD)) {
                        if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE) {
                                disk_rw_in_progress = 0;
                                PS2_DISK_LED_OFF();
-                               reset_status(ihost_index) = IM_RESET_FINISHED_FAIL;
+                               reset_status(shpnt) = IM_RESET_FINISHED_FAIL;
                        } else {
                                /*reset disk led counter, turn off disk led */
                                disk_rw_in_progress = 0;
                                PS2_DISK_LED_OFF();
-                               reset_status(ihost_index) = IM_RESET_FINISHED_OK;
+                               reset_status(shpnt) = IM_RESET_FINISHED_OK;
                        }
-                       stat_result(ihost_index) = cmd_result;
-                       last_scsi_command(ihost_index)[ldn] = NO_SCSI;
-                       last_scsi_type(ihost_index)[ldn] = 0;
-                       spin_unlock(dev->host_lock);
+                       stat_result(shpnt) = cmd_result;
+                       last_scsi_command(shpnt)[ldn] = NO_SCSI;
+                       last_scsi_type(shpnt)[ldn] = 0;
+                       spin_unlock_irqrestore(shpnt->host_lock, flags);
                        return IRQ_HANDLED;
-               } else if (last_scsi_command(ihost_index)[ldn] == IM_ABORT_IMM_CMD) {
+               } else if (last_scsi_command(shpnt)[ldn] == IM_ABORT_IMM_CMD) {
                        /* react on SCSI abort command */
 #ifdef IM_DEBUG_PROBE
                        printk("IBM MCA SCSI: Interrupt from SCSI-abort.\n");
 #endif
                        disk_rw_in_progress = 0;
                        PS2_DISK_LED_OFF();
-                       cmd = ld(ihost_index)[ldn].cmd;
-                       ld(ihost_index)[ldn].cmd = NULL;
+                       cmd = ld(shpnt)[ldn].cmd;
+                       ld(shpnt)[ldn].cmd = NULL;
                        if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE)
                                cmd->result = DID_NO_CONNECT << 16;
                        else
                                cmd->result = DID_ABORT << 16;
-                       stat_result(ihost_index) = cmd_result;
-                       last_scsi_command(ihost_index)[ldn] = NO_SCSI;
-                       last_scsi_type(ihost_index)[ldn] = 0;
+                       stat_result(shpnt) = cmd_result;
+                       last_scsi_command(shpnt)[ldn] = NO_SCSI;
+                       last_scsi_type(shpnt)[ldn] = 0;
                        if (cmd->scsi_done)
                                (cmd->scsi_done) (cmd); /* should be the internal_done */
-                       spin_unlock(dev->host_lock);
+                       spin_unlock_irqrestore(shpnt->host_lock, flags);
                        return IRQ_HANDLED;
                } else {
                        disk_rw_in_progress = 0;
                        PS2_DISK_LED_OFF();
-                       reset_status(ihost_index) = IM_RESET_FINISHED_OK;
-                       stat_result(ihost_index) = cmd_result;
-                       last_scsi_command(ihost_index)[ldn] = NO_SCSI;
-                       spin_unlock(dev->host_lock);
+                       reset_status(shpnt) = IM_RESET_FINISHED_OK;
+                       stat_result(shpnt) = cmd_result;
+                       last_scsi_command(shpnt)[ldn] = NO_SCSI;
+                       spin_unlock_irqrestore(shpnt->host_lock, flags);
                        return IRQ_HANDLED;
                }
        }
-       last_scsi_command(ihost_index)[ldn] = NO_SCSI;
-       last_scsi_type(ihost_index)[ldn] = 0;
-       cmd = ld(ihost_index)[ldn].cmd;
-       ld(ihost_index)[ldn].cmd = NULL;
+       last_scsi_command(shpnt)[ldn] = NO_SCSI;
+       last_scsi_type(shpnt)[ldn] = 0;
+       cmd = ld(shpnt)[ldn].cmd;
+       ld(shpnt)[ldn].cmd = NULL;
 #ifdef IM_DEBUG_TIMEOUT
        if (cmd) {
                if ((cmd->target == TIMEOUT_PUN) && (cmd->device->lun == TIMEOUT_LUN)) {
+                       spin_unlock_irqsave(shpnt->host_lock, flags);
                        printk("IBM MCA SCSI: Ignoring interrupt from pun=%x, lun=%x.\n", cmd->target, cmd->device->lun);
                        return IRQ_HANDLED;
                }
@@ -674,15 +681,15 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id)
        /*if no command structure, just return, else clear cmd */
        if (!cmd)
        {
-               spin_unlock(dev->host_lock);
+               spin_unlock_irqrestore(shpnt->host_lock, flags);
                return IRQ_HANDLED;
        }
 
 #ifdef IM_DEBUG_INT
-       printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n", cmd->cmnd[0], intr_reg, ld(ihost_index)[ldn].tsb.dev_status, ld(ihost_index)[ldn].tsb.cmd_status, ld(ihost_index)[ldn].tsb.dev_error, ld(ihost_index)[ldn].tsb.cmd_error);
+       printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n", cmd->cmnd[0], intr_reg, ld(shpnt)[ldn].tsb.dev_status, ld(shpnt)[ldn].tsb.cmd_status, ld(shpnt)[ldn].tsb.dev_error, ld(shpnt)[ldn].tsb.cmd_error);
 #endif
        /*if this is end of media read/write, may turn off PS/2 disk led */
-       if ((ld(ihost_index)[ldn].device_type != TYPE_NO_LUN) && (ld(ihost_index)[ldn].device_type != TYPE_NO_DEVICE)) {
+       if ((ld(shpnt)[ldn].device_type != TYPE_NO_LUN) && (ld(shpnt)[ldn].device_type != TYPE_NO_DEVICE)) {
                /* only access this, if there was a valid device addressed */
                if (--disk_rw_in_progress == 0)
                        PS2_DISK_LED_OFF();
@@ -693,8 +700,8 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id)
         * adapters do not support CMD_TERMINATED, TASK_SET_FULL and
         * ACA_ACTIVE as returning statusbyte information. (ML) */
        if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE) {
-               cmd->result = (unsigned char) (ld(ihost_index)[ldn].tsb.dev_status & 0x1e);
-               IBM_DS(ihost_index).total_errors++;
+               cmd->result = (unsigned char) (ld(shpnt)[ldn].tsb.dev_status & 0x1e);
+               IBM_DS(shpnt).total_errors++;
        } else
                cmd->result = 0;
        /* write device status into cmd->result, and call done function */
@@ -705,24 +712,25 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id)
                cmd->result |= DID_OK << 16;
        if (cmd->scsi_done)
                (cmd->scsi_done) (cmd);
-       spin_unlock(dev->host_lock);
+       spin_unlock_irqrestore(shpnt->host_lock, flags);
        return IRQ_HANDLED;
 }
 
-static void issue_cmd(int host_index, unsigned long cmd_reg, unsigned char attn_reg)
+static void issue_cmd(struct Scsi_Host *shpnt, unsigned long cmd_reg,
+                     unsigned char attn_reg)
 {
        unsigned long flags;
        /* must wait for attention reg not busy */
        while (1) {
-               spin_lock_irqsave(hosts[host_index]->host_lock, flags);
-               if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY))
+               spin_lock_irqsave(shpnt->host_lock, flags);
+               if (!(inb(IM_STAT_REG(shpnt)) & IM_BUSY))
                        break;
-               spin_unlock_irqrestore(hosts[host_index]->host_lock, flags);
+               spin_unlock_irqrestore(shpnt->host_lock, flags);
        }
        /* write registers and enable system interrupts */
-       outl(cmd_reg, IM_CMD_REG(host_index));
-       outb(attn_reg, IM_ATTN_REG(host_index));
-       spin_unlock_irqrestore(hosts[host_index]->host_lock, flags);
+       outl(cmd_reg, IM_CMD_REG(shpnt));
+       outb(attn_reg, IM_ATTN_REG(shpnt));
+       spin_unlock_irqrestore(shpnt->host_lock, flags);
 }
 
 static void internal_done(Scsi_Cmnd * cmd)
@@ -732,34 +740,34 @@ static void internal_done(Scsi_Cmnd * cmd)
 }
 
 /* SCSI-SCB-command for device_inquiry */
-static int device_inquiry(int host_index, int ldn)
+static int device_inquiry(struct Scsi_Host *shpnt, int ldn)
 {
        int retr;
        struct im_scb *scb;
        struct im_tsb *tsb;
        unsigned char *buf;
 
-       scb = &(ld(host_index)[ldn].scb);
-       tsb = &(ld(host_index)[ldn].tsb);
-       buf = (unsigned char *) (&(ld(host_index)[ldn].buf));
-       ld(host_index)[ldn].tsb.dev_status = 0; /* prepare statusblock */
+       scb = &(ld(shpnt)[ldn].scb);
+       tsb = &(ld(shpnt)[ldn].tsb);
+       buf = (unsigned char *) (&(ld(shpnt)[ldn].buf));
+       ld(shpnt)[ldn].tsb.dev_status = 0;      /* prepare statusblock */
        for (retr = 0; retr < 3; retr++) {
                /* fill scb with inquiry command */
                scb->command = IM_DEVICE_INQUIRY_CMD | IM_NO_DISCONNECT;
                scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_RETRY_ENABLE | IM_BYPASS_BUFFER;
-               last_scsi_command(host_index)[ldn] = IM_DEVICE_INQUIRY_CMD;
-               last_scsi_type(host_index)[ldn] = IM_SCB;
+               last_scsi_command(shpnt)[ldn] = IM_DEVICE_INQUIRY_CMD;
+               last_scsi_type(shpnt)[ldn] = IM_SCB;
                scb->sys_buf_adr = isa_virt_to_bus(buf);
                scb->sys_buf_length = 255;      /* maximum bufferlength gives max info */
                scb->tsb_adr = isa_virt_to_bus(tsb);
                /* issue scb to passed ldn, and busy wait for interrupt */
-               got_interrupt(host_index) = 0;
-               issue_cmd(host_index, isa_virt_to_bus(scb), IM_SCB | ldn);
-               while (!got_interrupt(host_index))
+               got_interrupt(shpnt) = 0;
+               issue_cmd(shpnt, isa_virt_to_bus(scb), IM_SCB | ldn);
+               while (!got_interrupt(shpnt))
                        barrier();
 
                /*if command successful, break */
-               if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED) || (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
+               if ((stat_result(shpnt) == IM_SCB_CMD_COMPLETED) || (stat_result(shpnt) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
                        return 1;
        }
        /*if all three retries failed, return "no device at this ldn" */
@@ -769,34 +777,34 @@ static int device_inquiry(int host_index, int ldn)
                return 1;
 }
 
-static int read_capacity(int host_index, int ldn)
+static int read_capacity(struct Scsi_Host *shpnt, int ldn)
 {
        int retr;
        struct im_scb *scb;
        struct im_tsb *tsb;
        unsigned char *buf;
 
-       scb = &(ld(host_index)[ldn].scb);
-       tsb = &(ld(host_index)[ldn].tsb);
-       buf = (unsigned char *) (&(ld(host_index)[ldn].buf));
-       ld(host_index)[ldn].tsb.dev_status = 0;
+       scb = &(ld(shpnt)[ldn].scb);
+       tsb = &(ld(shpnt)[ldn].tsb);
+       buf = (unsigned char *) (&(ld(shpnt)[ldn].buf));
+       ld(shpnt)[ldn].tsb.dev_status = 0;
        for (retr = 0; retr < 3; retr++) {
                /*fill scb with read capacity command */
                scb->command = IM_READ_CAPACITY_CMD;
                scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_RETRY_ENABLE | IM_BYPASS_BUFFER;
-               last_scsi_command(host_index)[ldn] = IM_READ_CAPACITY_CMD;
-               last_scsi_type(host_index)[ldn] = IM_SCB;
+               last_scsi_command(shpnt)[ldn] = IM_READ_CAPACITY_CMD;
+               last_scsi_type(shpnt)[ldn] = IM_SCB;
                scb->sys_buf_adr = isa_virt_to_bus(buf);
                scb->sys_buf_length = 8;
                scb->tsb_adr = isa_virt_to_bus(tsb);
                /*issue scb to passed ldn, and busy wait for interrupt */
-               got_interrupt(host_index) = 0;
-               issue_cmd(host_index, isa_virt_to_bus(scb), IM_SCB | ldn);
-               while (!got_interrupt(host_index))
+               got_interrupt(shpnt) = 0;
+               issue_cmd(shpnt, isa_virt_to_bus(scb), IM_SCB | ldn);
+               while (!got_interrupt(shpnt))
                        barrier();
 
                /*if got capacity, get block length and return one device found */
-               if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED) || (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
+               if ((stat_result(shpnt) == IM_SCB_CMD_COMPLETED) || (stat_result(shpnt) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
                        return 1;
        }
        /*if all three retries failed, return "no device at this ldn" */
@@ -806,39 +814,39 @@ static int read_capacity(int host_index, int ldn)
                return 1;
 }
 
-static int get_pos_info(int host_index)
+static int get_pos_info(struct Scsi_Host *shpnt)
 {
        int retr;
        struct im_scb *scb;
        struct im_tsb *tsb;
        unsigned char *buf;
 
-       scb = &(ld(host_index)[MAX_LOG_DEV].scb);
-       tsb = &(ld(host_index)[MAX_LOG_DEV].tsb);
-       buf = (unsigned char *) (&(ld(host_index)[MAX_LOG_DEV].buf));
-       ld(host_index)[MAX_LOG_DEV].tsb.dev_status = 0;
+       scb = &(ld(shpnt)[MAX_LOG_DEV].scb);
+       tsb = &(ld(shpnt)[MAX_LOG_DEV].tsb);
+       buf = (unsigned char *) (&(ld(shpnt)[MAX_LOG_DEV].buf));
+       ld(shpnt)[MAX_LOG_DEV].tsb.dev_status = 0;
        for (retr = 0; retr < 3; retr++) {
                /*fill scb with get_pos_info command */
                scb->command = IM_GET_POS_INFO_CMD;
                scb->enable = IM_READ_CONTROL | IM_REPORT_TSB_ONLY_ON_ERROR | IM_RETRY_ENABLE | IM_BYPASS_BUFFER;
-               last_scsi_command(host_index)[MAX_LOG_DEV] = IM_GET_POS_INFO_CMD;
-               last_scsi_type(host_index)[MAX_LOG_DEV] = IM_SCB;
+               last_scsi_command(shpnt)[MAX_LOG_DEV] = IM_GET_POS_INFO_CMD;
+               last_scsi_type(shpnt)[MAX_LOG_DEV] = IM_SCB;
                scb->sys_buf_adr = isa_virt_to_bus(buf);
-               if (special(host_index) == IBM_SCSI2_FW)
+               if (special(shpnt) == IBM_SCSI2_FW)
                        scb->sys_buf_length = 256;      /* get all info from F/W adapter */
                else
                        scb->sys_buf_length = 18;       /* get exactly 18 bytes for other SCSI */
                scb->tsb_adr = isa_virt_to_bus(tsb);
                /*issue scb to ldn=15, and busy wait for interrupt */
-               got_interrupt(host_index) = 0;
-               issue_cmd(host_index, isa_virt_to_bus(scb), IM_SCB | MAX_LOG_DEV);
+               got_interrupt(shpnt) = 0;
+               issue_cmd(shpnt, isa_virt_to_bus(scb), IM_SCB | MAX_LOG_DEV);
                
                /* FIXME: timeout */
-               while (!got_interrupt(host_index))
+               while (!got_interrupt(shpnt))
                        barrier();
 
                /*if got POS-stuff, get block length and return one device found */
-               if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED) || (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
+               if ((stat_result(shpnt) == IM_SCB_CMD_COMPLETED) || (stat_result(shpnt) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
                        return 1;
        }
        /* if all three retries failed, return "no device at this ldn" */
@@ -851,14 +859,16 @@ static int get_pos_info(int host_index)
 /* SCSI-immediate-command for assign. This functions maps/unmaps specific
  ldn-numbers on SCSI (PUN,LUN). It is needed for presetting of the
  subsystem and for dynamical remapping od ldns. */
-static int immediate_assign(int host_index, unsigned int pun, unsigned int lun, unsigned int ldn, unsigned int operation)
+static int immediate_assign(struct Scsi_Host *shpnt, unsigned int pun,
+                           unsigned int lun, unsigned int ldn,
+                           unsigned int operation)
 {
        int retr;
        unsigned long imm_cmd;
 
        for (retr = 0; retr < 3; retr++) {
                /* select mutation level of the SCSI-adapter */
-               switch (special(host_index)) {
+               switch (special(shpnt)) {
                case IBM_SCSI2_FW:
                        imm_cmd = (unsigned long) (IM_ASSIGN_IMM_CMD);
                        imm_cmd |= (unsigned long) ((lun & 7) << 24);
@@ -867,7 +877,7 @@ static int immediate_assign(int host_index, unsigned int pun, unsigned int lun,
                        imm_cmd |= (unsigned long) ((ldn & 15) << 16);
                        break;
                default:
-                       imm_cmd = inl(IM_CMD_REG(host_index));
+                       imm_cmd = inl(IM_CMD_REG(shpnt));
                        imm_cmd &= (unsigned long) (0xF8000000);        /* keep reserved bits */
                        imm_cmd |= (unsigned long) (IM_ASSIGN_IMM_CMD);
                        imm_cmd |= (unsigned long) ((lun & 7) << 24);
@@ -876,15 +886,15 @@ static int immediate_assign(int host_index, unsigned int pun, unsigned int lun,
                        imm_cmd |= (unsigned long) ((ldn & 15) << 16);
                        break;
                }
-               last_scsi_command(host_index)[MAX_LOG_DEV] = IM_ASSIGN_IMM_CMD;
-               last_scsi_type(host_index)[MAX_LOG_DEV] = IM_IMM_CMD;
-               got_interrupt(host_index) = 0;
-               issue_cmd(host_index, (unsigned long) (imm_cmd), IM_IMM_CMD | MAX_LOG_DEV);
-               while (!got_interrupt(host_index))
+               last_scsi_command(shpnt)[MAX_LOG_DEV] = IM_ASSIGN_IMM_CMD;
+               last_scsi_type(shpnt)[MAX_LOG_DEV] = IM_IMM_CMD;
+               got_interrupt(shpnt) = 0;
+               issue_cmd(shpnt, (unsigned long) (imm_cmd), IM_IMM_CMD | MAX_LOG_DEV);
+               while (!got_interrupt(shpnt))
                        barrier();
 
                /*if command successful, break */
-               if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
+               if (stat_result(shpnt) == IM_IMMEDIATE_CMD_COMPLETED)
                        return 1;
        }
        if (retr >= 3)
@@ -893,7 +903,7 @@ static int immediate_assign(int host_index, unsigned int pun, unsigned int lun,
                return 1;
 }
 
-static int immediate_feature(int host_index, unsigned int speed, unsigned int timeout)
+static int immediate_feature(struct Scsi_Host *shpnt, unsigned int speed, unsigned int timeout)
 {
        int retr;
        unsigned long imm_cmd;
@@ -903,16 +913,16 @@ static int immediate_feature(int host_index, unsigned int speed, unsigned int ti
                imm_cmd = IM_FEATURE_CTR_IMM_CMD;
                imm_cmd |= (unsigned long) ((speed & 0x7) << 29);
                imm_cmd |= (unsigned long) ((timeout & 0x1fff) << 16);
-               last_scsi_command(host_index)[MAX_LOG_DEV] = IM_FEATURE_CTR_IMM_CMD;
-               last_scsi_type(host_index)[MAX_LOG_DEV] = IM_IMM_CMD;
-               got_interrupt(host_index) = 0;
+               last_scsi_command(shpnt)[MAX_LOG_DEV] = IM_FEATURE_CTR_IMM_CMD;
+               last_scsi_type(shpnt)[MAX_LOG_DEV] = IM_IMM_CMD;
+               got_interrupt(shpnt) = 0;
                /* we need to run into command errors in order to probe for the
                 * right speed! */
                global_command_error_excuse = 1;
-               issue_cmd(host_index, (unsigned long) (imm_cmd), IM_IMM_CMD | MAX_LOG_DEV);
+               issue_cmd(shpnt, (unsigned long) (imm_cmd), IM_IMM_CMD | MAX_LOG_DEV);
                
                /* FIXME: timeout */
-               while (!got_interrupt(host_index))
+               while (!got_interrupt(shpnt))
                        barrier();
                if (global_command_error_excuse == CMD_FAIL) {
                        global_command_error_excuse = 0;
@@ -920,7 +930,7 @@ static int immediate_feature(int host_index, unsigned int speed, unsigned int ti
                } else
                        global_command_error_excuse = 0;
                /*if command successful, break */
-               if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
+               if (stat_result(shpnt) == IM_IMMEDIATE_CMD_COMPLETED)
                        return 1;
        }
        if (retr >= 3)
@@ -930,35 +940,35 @@ static int immediate_feature(int host_index, unsigned int speed, unsigned int ti
 }
 
 #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
-static int immediate_reset(int host_index, unsigned int ldn)
+static int immediate_reset(struct Scsi_Host *shpnt, unsigned int ldn)
 {
        int retries;
        int ticks;
        unsigned long imm_command;
 
        for (retries = 0; retries < 3; retries++) {
-               imm_command = inl(IM_CMD_REG(host_index));
+               imm_command = inl(IM_CMD_REG(shpnt));
                imm_command &= (unsigned long) (0xFFFF0000);    /* keep reserved bits */
                imm_command |= (unsigned long) (IM_RESET_IMM_CMD);
-               last_scsi_command(host_index)[ldn] = IM_RESET_IMM_CMD;
-               last_scsi_type(host_index)[ldn] = IM_IMM_CMD;
-               got_interrupt(host_index) = 0;
-               reset_status(host_index) = IM_RESET_IN_PROGRESS;
-               issue_cmd(host_index, (unsigned long) (imm_command), IM_IMM_CMD | ldn);
+               last_scsi_command(shpnt)[ldn] = IM_RESET_IMM_CMD;
+               last_scsi_type(shpnt)[ldn] = IM_IMM_CMD;
+               got_interrupt(shpnt) = 0;
+               reset_status(shpnt) = IM_RESET_IN_PROGRESS;
+               issue_cmd(shpnt, (unsigned long) (imm_command), IM_IMM_CMD | ldn);
                ticks = IM_RESET_DELAY * HZ;
-               while (reset_status(host_index) == IM_RESET_IN_PROGRESS && --ticks) {
+               while (reset_status(shpnt) == IM_RESET_IN_PROGRESS && --ticks) {
                        udelay((1 + 999 / HZ) * 1000);
                        barrier();
                }
                /* if reset did not complete, just complain */
                if (!ticks) {
                        printk(KERN_ERR "IBM MCA SCSI: reset did not complete within %d seconds.\n", IM_RESET_DELAY);
-                       reset_status(host_index) = IM_RESET_FINISHED_OK;
+                       reset_status(shpnt) = IM_RESET_FINISHED_OK;
                        /* did not work, finish */
                        return 1;
                }
                /*if command successful, break */
-               if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
+               if (stat_result(shpnt) == IM_IMMEDIATE_CMD_COMPLETED)
                        return 1;
        }
        if (retries >= 3)
@@ -1060,35 +1070,35 @@ static int probe_display(int what)
        return 0;
 }
 
-static int probe_bus_mode(int host_index)
+static int probe_bus_mode(struct Scsi_Host *shpnt)
 {
        struct im_pos_info *info;
        int num_bus = 0;
        int ldn;
 
-       info = (struct im_pos_info *) (&(ld(host_index)[MAX_LOG_DEV].buf));
-       if (get_pos_info(host_index)) {
+       info = (struct im_pos_info *) (&(ld(shpnt)[MAX_LOG_DEV].buf));
+       if (get_pos_info(shpnt)) {
                if (info->connector_size & 0xf000)
-                       subsystem_connector_size(host_index) = 16;
+                       subsystem_connector_size(shpnt) = 16;
                else
-                       subsystem_connector_size(host_index) = 32;
+                       subsystem_connector_size(shpnt) = 32;
                num_bus |= (info->pos_4b & 8) >> 3;
                for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) {
-                       if ((special(host_index) == IBM_SCSI_WCACHE) || (special(host_index) == IBM_7568_WCACHE)) {
+                       if ((special(shpnt) == IBM_SCSI_WCACHE) || (special(shpnt) == IBM_7568_WCACHE)) {
                                if (!((info->cache_stat >> ldn) & 1))
-                                       ld(host_index)[ldn].cache_flag = 0;
+                                       ld(shpnt)[ldn].cache_flag = 0;
                        }
                        if (!((info->retry_stat >> ldn) & 1))
-                               ld(host_index)[ldn].retry_flag = 0;
+                               ld(shpnt)[ldn].retry_flag = 0;
                }
 #ifdef IM_DEBUG_PROBE
                printk("IBM MCA SCSI: SCSI-Cache bits: ");
                for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) {
-                       printk("%d", ld(host_index)[ldn].cache_flag);
+                       printk("%d", ld(shpnt)[ldn].cache_flag);
                }
                printk("\nIBM MCA SCSI: SCSI-Retry bits: ");
                for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) {
-                       printk("%d", ld(host_index)[ldn].retry_flag);
+                       printk("%d", ld(shpnt)[ldn].retry_flag);
                }
                printk("\n");
 #endif
@@ -1097,7 +1107,7 @@ static int probe_bus_mode(int host_index)
 }
 
 /* probing scsi devices */
-static void check_devices(int host_index, int adaptertype)
+static void check_devices(struct Scsi_Host *shpnt, int adaptertype)
 {
        int id, lun, ldn, ticks;
        int count_devices;      /* local counter for connected device */
@@ -1108,24 +1118,24 @@ static void check_devices(int host_index, int adaptertype)
        /* assign default values to certain variables */
        ticks = 0;
        count_devices = 0;
-       IBM_DS(host_index).dyn_flag = 0;        /* normally no need for dynamical ldn management */
-       IBM_DS(host_index).total_errors = 0;    /* set errorcounter to 0 */
-       next_ldn(host_index) = 7;       /* next ldn to be assigned is 7, because 0-6 is 'hardwired' */
+       IBM_DS(shpnt).dyn_flag = 0;     /* normally no need for dynamical ldn management */
+       IBM_DS(shpnt).total_errors = 0; /* set errorcounter to 0 */
+       next_ldn(shpnt) = 7;    /* next ldn to be assigned is 7, because 0-6 is 'hardwired' */
 
        /* initialize the very important driver-informational arrays/structs */
-       memset(ld(host_index), 0, sizeof(ld(host_index)));
+       memset(ld(shpnt), 0, sizeof(ld(shpnt)));
        for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) {
-               last_scsi_command(host_index)[ldn] = NO_SCSI;   /* emptify last SCSI-command storage */
-               last_scsi_type(host_index)[ldn] = 0;
-               ld(host_index)[ldn].cache_flag = 1;
-               ld(host_index)[ldn].retry_flag = 1;
+               last_scsi_command(shpnt)[ldn] = NO_SCSI;        /* emptify last SCSI-command storage */
+               last_scsi_type(shpnt)[ldn] = 0;
+               ld(shpnt)[ldn].cache_flag = 1;
+               ld(shpnt)[ldn].retry_flag = 1;
        }
-       memset(get_ldn(host_index), TYPE_NO_DEVICE, sizeof(get_ldn(host_index)));       /* this is essential ! */
-       memset(get_scsi(host_index), TYPE_NO_DEVICE, sizeof(get_scsi(host_index)));     /* this is essential ! */
+       memset(get_ldn(shpnt), TYPE_NO_DEVICE, sizeof(get_ldn(shpnt))); /* this is essential ! */
+       memset(get_scsi(shpnt), TYPE_NO_DEVICE, sizeof(get_scsi(shpnt)));       /* this is essential ! */
        for (lun = 0; lun < 8; lun++) {
                /* mark the adapter at its pun on all luns */
-               get_scsi(host_index)[subsystem_pun(host_index)][lun] = TYPE_IBM_SCSI_ADAPTER;
-               get_ldn(host_index)[subsystem_pun(host_index)][lun] = MAX_LOG_DEV;      /* make sure, the subsystem
+               get_scsi(shpnt)[subsystem_pun(shpnt)][lun] = TYPE_IBM_SCSI_ADAPTER;
+               get_ldn(shpnt)[subsystem_pun(shpnt)][lun] = MAX_LOG_DEV;        /* make sure, the subsystem
                                                                                           ldn is active for all
                                                                                           luns. */
        }
@@ -1134,9 +1144,9 @@ static void check_devices(int host_index, int adaptertype)
        /* monitor connected on model XX95. */
 
        /* STEP 1: */
-       adapter_speed(host_index) = global_adapter_speed;
-       speedrun = adapter_speed(host_index);
-       while (immediate_feature(host_index, speedrun, adapter_timeout) == 2) {
+       adapter_speed(shpnt) = global_adapter_speed;
+       speedrun = adapter_speed(shpnt);
+       while (immediate_feature(shpnt, speedrun, adapter_timeout) == 2) {
                probe_display(1);
                if (speedrun == 7)
                        panic("IBM MCA SCSI: Cannot set Synchronous-Transfer-Rate!\n");
@@ -1144,30 +1154,30 @@ static void check_devices(int host_index, int adaptertype)
                if (speedrun > 7)
                        speedrun = 7;
        }
-       adapter_speed(host_index) = speedrun;
+       adapter_speed(shpnt) = speedrun;
        /* Get detailed information about the current adapter, necessary for
         * device operations: */
-       num_bus = probe_bus_mode(host_index);
+       num_bus = probe_bus_mode(shpnt);
 
        /* num_bus contains only valid data for the F/W adapter! */
        if (adaptertype == IBM_SCSI2_FW) {      /* F/W SCSI adapter: */
                /* F/W adapter PUN-space extension evaluation: */
                if (num_bus) {
                        printk(KERN_INFO "IBM MCA SCSI: Separate bus mode (wide-addressing enabled)\n");
-                       subsystem_maxid(host_index) = 16;
+                       subsystem_maxid(shpnt) = 16;
                } else {
                        printk(KERN_INFO "IBM MCA SCSI: Combined bus mode (wide-addressing disabled)\n");
-                       subsystem_maxid(host_index) = 8;
+                       subsystem_maxid(shpnt) = 8;
                }
                printk(KERN_INFO "IBM MCA SCSI: Sync.-Rate (F/W: 20, Int.: 10, Ext.: %s) MBytes/s\n", ibmrate(speedrun, adaptertype));
        } else                  /* all other IBM SCSI adapters: */
                printk(KERN_INFO "IBM MCA SCSI: Synchronous-SCSI-Transfer-Rate: %s MBytes/s\n", ibmrate(speedrun, adaptertype));
 
        /* assign correct PUN device space */
-       max_pun = subsystem_maxid(host_index);
+       max_pun = subsystem_maxid(shpnt);
 
 #ifdef IM_DEBUG_PROBE
-       printk("IBM MCA SCSI: Current SCSI-host index: %d\n", host_index);
+       printk("IBM MCA SCSI: Current SCSI-host index: %d\n", shpnt);
        printk("IBM MCA SCSI: Removing default logical SCSI-device mapping.");
 #else
        printk(KERN_INFO "IBM MCA SCSI: Dev. Order: %s, Mapping (takes <2min): ", (ibm_ansi_order) ? "ANSI" : "New");
@@ -1177,7 +1187,7 @@ static void check_devices(int host_index, int adaptertype)
 #ifdef IM_DEBUG_PROBE
                printk(".");
 #endif
-               immediate_assign(host_index, 0, 0, ldn, REMOVE_LDN);    /* remove ldn (wherever) */
+               immediate_assign(shpnt, 0, 0, ldn, REMOVE_LDN); /* remove ldn (wherever) */
        }
        lun = 0;                /* default lun is 0 */
 #ifndef IM_DEBUG_PROBE
@@ -1196,18 +1206,18 @@ static void check_devices(int host_index, int adaptertype)
 #ifdef IM_DEBUG_PROBE
                        printk(".");
 #endif
-                       if (id != subsystem_pun(host_index)) {
+                       if (id != subsystem_pun(shpnt)) {
                                /* if pun is not the adapter: */
                                /* set ldn=0 to pun,lun */
-                               immediate_assign(host_index, id, lun, PROBE_LDN, SET_LDN);
-                               if (device_inquiry(host_index, PROBE_LDN)) {    /* probe device */
-                                       get_scsi(host_index)[id][lun] = (unsigned char) (ld(host_index)[PROBE_LDN].buf[0]);
+                               immediate_assign(shpnt, id, lun, PROBE_LDN, SET_LDN);
+                               if (device_inquiry(shpnt, PROBE_LDN)) { /* probe device */
+                                       get_scsi(shpnt)[id][lun] = (unsigned char) (ld(shpnt)[PROBE_LDN].buf[0]);
                                        /* entry, even for NO_LUN */
-                                       if (ld(host_index)[PROBE_LDN].buf[0] != TYPE_NO_LUN)
+                                       if (ld(shpnt)[PROBE_LDN].buf[0] != TYPE_NO_LUN)
                                                count_devices++;        /* a existing device is found */
                                }
                                /* remove ldn */
-                               immediate_assign(host_index, id, lun, PROBE_LDN, REMOVE_LDN);
+                               immediate_assign(shpnt, id, lun, PROBE_LDN, REMOVE_LDN);
                        }
                }
 #ifndef IM_DEBUG_PROBE
@@ -1227,16 +1237,16 @@ static void check_devices(int host_index, int adaptertype)
 #ifdef IM_DEBUG_PROBE
                        printk(".");
 #endif
-                       if (id != subsystem_pun(host_index)) {
-                               if (get_scsi(host_index)[id][lun] != TYPE_NO_LUN && get_scsi(host_index)[id][lun] != TYPE_NO_DEVICE) {
+                       if (id != subsystem_pun(shpnt)) {
+                               if (get_scsi(shpnt)[id][lun] != TYPE_NO_LUN && get_scsi(shpnt)[id][lun] != TYPE_NO_DEVICE) {
                                        /* Only map if accepted type. Always enter for
                                           lun == 0 to get no gaps into ldn-mapping for ldn<7. */
-                                       immediate_assign(host_index, id, lun, ldn, SET_LDN);
-                                       get_ldn(host_index)[id][lun] = ldn;     /* map ldn */
-                                       if (device_exists(host_index, ldn, &ld(host_index)[ldn].block_length, &ld(host_index)[ldn].device_type)) {
+                                       immediate_assign(shpnt, id, lun, ldn, SET_LDN);
+                                       get_ldn(shpnt)[id][lun] = ldn;  /* map ldn */
+                                       if (device_exists(shpnt, ldn, &ld(shpnt)[ldn].block_length, &ld(shpnt)[ldn].device_type)) {
 #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
                                                printk("resetting device at ldn=%x ... ", ldn);
-                                               immediate_reset(host_index, ldn);
+                                               immediate_reset(shpnt, ldn);
 #endif
                                                ldn++;
                                        } else {
@@ -1244,15 +1254,15 @@ static void check_devices(int host_index, int adaptertype)
                                                 * handle it or because it has problems */
                                                if (lun > 0) {
                                                        /* remove mapping */
-                                                       get_ldn(host_index)[id][lun] = TYPE_NO_DEVICE;
-                                                       immediate_assign(host_index, 0, 0, ldn, REMOVE_LDN);
+                                                       get_ldn(shpnt)[id][lun] = TYPE_NO_DEVICE;
+                                                       immediate_assign(shpnt, 0, 0, ldn, REMOVE_LDN);
                                                } else
                                                        ldn++;
                                        }
                                } else if (lun == 0) {
                                        /* map lun == 0, even if no device exists */
-                                       immediate_assign(host_index, id, lun, ldn, SET_LDN);
-                                       get_ldn(host_index)[id][lun] = ldn;     /* map ldn */
+                                       immediate_assign(shpnt, id, lun, ldn, SET_LDN);
+                                       get_ldn(shpnt)[id][lun] = ldn;  /* map ldn */
                                        ldn++;
                                }
                        }
@@ -1262,14 +1272,14 @@ static void check_devices(int host_index, int adaptertype)
        /* map remaining ldns to non-existing devices */
        for (lun = 1; lun < 8 && ldn < MAX_LOG_DEV; lun++)
                for (id = 0; id < max_pun && ldn < MAX_LOG_DEV; id++) {
-                       if (get_scsi(host_index)[id][lun] == TYPE_NO_LUN || get_scsi(host_index)[id][lun] == TYPE_NO_DEVICE) {
+                       if (get_scsi(shpnt)[id][lun] == TYPE_NO_LUN || get_scsi(shpnt)[id][lun] == TYPE_NO_DEVICE) {
                                probe_display(1);
                                /* Map remaining ldns only to NON-existing pun,lun
                                   combinations to make sure an inquiry will fail.
                                   For MULTI_LUN, it is needed to avoid adapter autonome
                                   SCSI-remapping. */
-                               immediate_assign(host_index, id, lun, ldn, SET_LDN);
-                               get_ldn(host_index)[id][lun] = ldn;
+                               immediate_assign(shpnt, id, lun, ldn, SET_LDN);
+                               get_ldn(shpnt)[id][lun] = ldn;
                                ldn++;
                        }
                }
@@ -1292,51 +1302,51 @@ static void check_devices(int host_index, int adaptertype)
        for (id = 0; id < max_pun; id++) {
                printk("%2d     ", id);
                for (lun = 0; lun < 8; lun++)
-                       printk("%2s ", ti_p(get_scsi(host_index)[id][lun]));
+                       printk("%2s ", ti_p(get_scsi(shpnt)[id][lun]));
                printk("      %2d     ", id);
                for (lun = 0; lun < 8; lun++)
-                       printk("%2s ", ti_l(get_ldn(host_index)[id][lun]));
+                       printk("%2s ", ti_l(get_ldn(shpnt)[id][lun]));
                printk("\n");
        }
 #endif
 
        /* assign total number of found SCSI-devices to the statistics struct */
-       IBM_DS(host_index).total_scsi_devices = count_devices;
+       IBM_DS(shpnt).total_scsi_devices = count_devices;
 
        /* decide for output in /proc-filesystem, if the configuration of
           SCSI-devices makes dynamical reassignment of devices necessary */
        if (count_devices >= MAX_LOG_DEV)
-               IBM_DS(host_index).dyn_flag = 1;        /* dynamical assignment is necessary */
+               IBM_DS(shpnt).dyn_flag = 1;     /* dynamical assignment is necessary */
        else
-               IBM_DS(host_index).dyn_flag = 0;        /* dynamical assignment is not necessary */
+               IBM_DS(shpnt).dyn_flag = 0;     /* dynamical assignment is not necessary */
 
        /* If no SCSI-devices are assigned, return 1 in order to cause message. */
        if (ldn == 0)
                printk("IBM MCA SCSI: Warning: No SCSI-devices found/assigned!\n");
 
        /* reset the counters for statistics on the current adapter */
-       IBM_DS(host_index).scbs = 0;
-       IBM_DS(host_index).long_scbs = 0;
-       IBM_DS(host_index).total_accesses = 0;
-       IBM_DS(host_index).total_interrupts = 0;
-       IBM_DS(host_index).dynamical_assignments = 0;
-       memset(IBM_DS(host_index).ldn_access, 0x0, sizeof(IBM_DS(host_index).ldn_access));
-       memset(IBM_DS(host_index).ldn_read_access, 0x0, sizeof(IBM_DS(host_index).ldn_read_access));
-       memset(IBM_DS(host_index).ldn_write_access, 0x0, sizeof(IBM_DS(host_index).ldn_write_access));
-       memset(IBM_DS(host_index).ldn_inquiry_access, 0x0, sizeof(IBM_DS(host_index).ldn_inquiry_access));
-       memset(IBM_DS(host_index).ldn_modeselect_access, 0x0, sizeof(IBM_DS(host_index).ldn_modeselect_access));
-       memset(IBM_DS(host_index).ldn_assignments, 0x0, sizeof(IBM_DS(host_index).ldn_assignments));
+       IBM_DS(shpnt).scbs = 0;
+       IBM_DS(shpnt).long_scbs = 0;
+       IBM_DS(shpnt).total_accesses = 0;
+       IBM_DS(shpnt).total_interrupts = 0;
+       IBM_DS(shpnt).dynamical_assignments = 0;
+       memset(IBM_DS(shpnt).ldn_access, 0x0, sizeof(IBM_DS(shpnt).ldn_access));
+       memset(IBM_DS(shpnt).ldn_read_access, 0x0, sizeof(IBM_DS(shpnt).ldn_read_access));
+       memset(IBM_DS(shpnt).ldn_write_access, 0x0, sizeof(IBM_DS(shpnt).ldn_write_access));
+       memset(IBM_DS(shpnt).ldn_inquiry_access, 0x0, sizeof(IBM_DS(shpnt).ldn_inquiry_access));
+       memset(IBM_DS(shpnt).ldn_modeselect_access, 0x0, sizeof(IBM_DS(shpnt).ldn_modeselect_access));
+       memset(IBM_DS(shpnt).ldn_assignments, 0x0, sizeof(IBM_DS(shpnt).ldn_assignments));
        probe_display(0);
        return;
 }
 
-static int device_exists(int host_index, int ldn, int *block_length, int *device_type)
+static int device_exists(struct Scsi_Host *shpnt, int ldn, int *block_length, int *device_type)
 {
        unsigned char *buf;
        /* if no valid device found, return immediately with 0 */
-       if (!(device_inquiry(host_index, ldn)))
+       if (!(device_inquiry(shpnt, ldn)))
                return 0;
-       buf = (unsigned char *) (&(ld(host_index)[ldn].buf));
+       buf = (unsigned char *) (&(ld(shpnt)[ldn].buf));
        if (*buf == TYPE_ROM) {
                *device_type = TYPE_ROM;
                *block_length = 2048;   /* (standard blocksize for yellow-/red-book) */
@@ -1349,7 +1359,7 @@ static int device_exists(int host_index, int ldn, int *block_length, int *device
        }
        if (*buf == TYPE_DISK) {
                *device_type = TYPE_DISK;
-               if (read_capacity(host_index, ldn)) {
+               if (read_capacity(shpnt, ldn)) {
                        *block_length = *(buf + 7) + (*(buf + 6) << 8) + (*(buf + 5) << 16) + (*(buf + 4) << 24);
                        return 1;
                } else
@@ -1357,7 +1367,7 @@ static int device_exists(int host_index, int ldn, int *block_length, int *device
        }
        if (*buf == TYPE_MOD) {
                *device_type = TYPE_MOD;
-               if (read_capacity(host_index, ldn)) {
+               if (read_capacity(shpnt, ldn)) {
                        *block_length = *(buf + 7) + (*(buf + 6) << 8) + (*(buf + 5) << 16) + (*(buf + 4) << 24);
                        return 1;
                } else
@@ -1430,6 +1440,9 @@ static void internal_ibmmca_scsi_setup(char *str, int *ints)
        return;
 }
 
+#if 0
+ FIXME NEED TO MOVE TO SYSFS
+
 static int ibmmca_getinfo(char *buf, int slot, void *dev_id)
 {
        struct Scsi_Host *shpnt;
@@ -1480,58 +1493,34 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id)
 
        return len;
 }
+#endif
 
-int ibmmca_detect(struct scsi_host_template * scsi_template)
+static struct scsi_host_template ibmmca_driver_template = {
+          .proc_name      = "ibmmca",
+         .proc_info      = ibmmca_proc_info,
+          .name           = "IBM SCSI-Subsystem",
+          .queuecommand   = ibmmca_queuecommand,
+         .eh_abort_handler = ibmmca_abort,
+         .eh_host_reset_handler = ibmmca_host_reset,
+          .bios_param     = ibmmca_biosparam,
+          .can_queue      = 16,
+          .this_id        = 7,
+          .sg_tablesize   = 16,
+          .cmd_per_lun    = 1,
+          .use_clustering = ENABLE_CLUSTERING,
+};
+
+static int ibmmca_probe(struct device *dev)
 {
        struct Scsi_Host *shpnt;
-       int port, id, i, j, k, slot;
-       int devices_on_irq_11 = 0;
-       int devices_on_irq_14 = 0;
-       int IRQ14_registered = 0;
-       int IRQ11_registered = 0;
-
-       found = 0;              /* make absolutely sure, that found is set to 0 */
+       int port, id, i, j, k, irq, enabled, ret = -EINVAL;
+       struct mca_device *mca_dev = to_mca_device(dev);
+       const char *description = ibmmca_description[mca_dev->index];
 
        /* First of all, print the version number of the driver. This is
         * important to allow better user bugreports in case of already
         * having problems with the MCA_bus probing. */
        printk(KERN_INFO "IBM MCA SCSI: Version %s\n", IBMMCA_SCSI_DRIVER_VERSION);
-       /* if this is not MCA machine, return "nothing found" */
-       if (!MCA_bus) {
-               printk(KERN_INFO "IBM MCA SCSI:  No Microchannel-bus present --> Aborting.\n" "              This machine does not have any IBM MCA-bus\n" "                 or the MCA-Kernel-support is not enabled!\n");
-               return 0;
-       }
-
-#ifdef MODULE
-       /* If the driver is run as module, read from conf.modules or cmd-line */
-       if (boot_options)
-               option_setup(boot_options);
-#endif
-
-       /* get interrupt request level */
-       if (request_irq(IM_IRQ, interrupt_handler, IRQF_SHARED, "ibmmcascsi", hosts)) {
-               printk(KERN_ERR "IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ);
-               return 0;
-       } else
-               IRQ14_registered++;
-
-       /* if ibmmcascsi setup option was passed to kernel, return "found" */
-       for (i = 0; i < IM_MAX_HOSTS; i++)
-               if (io_port[i] > 0 && scsi_id[i] >= 0 && scsi_id[i] < 8) {
-                       printk("IBM MCA SCSI: forced detected SCSI Adapter, io=0x%x, scsi id=%d.\n", io_port[i], scsi_id[i]);
-                       if ((shpnt = ibmmca_register(scsi_template, io_port[i], scsi_id[i], FORCED_DETECTION, "forced detected SCSI Adapter"))) {
-                               for (k = 2; k < 7; k++)
-                                       ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = 0;
-                               ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = FORCED_DETECTION;
-                               mca_set_adapter_name(MCA_INTEGSCSI, "forced detected SCSI Adapter");
-                               mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo, shpnt);
-                               mca_mark_as_used(MCA_INTEGSCSI);
-                               devices_on_irq_14++;
-                       }
-               }
-       if (found)
-               return found;
-
        /* The POS2-register of all PS/2 model SCSI-subsystems has the following
         * interpretation of bits:
         *                             Bit 7 - 4 : Chip Revision ID (Release)
@@ -1558,7 +1547,14 @@ int ibmmca_detect(struct scsi_host_template * scsi_template)
 
        /* first look for the IBM SCSI integrated subsystem on the motherboard */
        for (j = 0; j < 8; j++) /* read the pos-information */
-               pos[j] = mca_read_stored_pos(MCA_INTEGSCSI, j);
+               pos[j] = mca_device_read_pos(mca_dev, j);
+       id = (pos[3] & 0xe0) >> 5; /* this is correct and represents the PUN */
+       enabled = (pos[2] &0x01);
+       if (!enabled) {
+               printk(KERN_WARNING "IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
+               printk(KERN_WARNING "              SCSI-operations may not work.\n");
+       }
+
        /* pos2 = pos3 = 0xff if there is no integrated SCSI-subsystem present, but
         * if we ignore the settings of all surrounding pos registers, it is not
         * completely sufficient to only check pos2 and pos3. */
@@ -1566,232 +1562,137 @@ int ibmmca_detect(struct scsi_host_template * scsi_template)
         * make sure, we see a real integrated onboard SCSI-interface and no
         * internal system information, which gets mapped to some pos registers
         * on models 95xx. */
-       if ((!pos[0] && !pos[1] && pos[2] > 0 && pos[3] > 0 && !pos[4] && !pos[5] && !pos[6] && !pos[7]) || (pos[0] == 0xff && pos[1] == 0xff && pos[2] < 0xff && pos[3] < 0xff && pos[4] == 0xff && pos[5] == 0xff && pos[6] == 0xff && pos[7] == 0xff)) {
-               if ((pos[2] & 1) == 1)  /* is the subsystem chip enabled ? */
-                       port = IM_IO_PORT;
-               else {          /* if disabled, no IRQs will be generated, as the chip won't
-                                * listen to the incoming commands and will do really nothing,
-                                * except for listening to the pos-register settings. If this
-                                * happens, I need to hugely think about it, as one has to
-                                * write something to the MCA-Bus pos register in order to
-                                * enable the chip. Normally, IBM-SCSI won't pass the POST,
-                                * when the chip is disabled (see IBM tech. ref.). */
-                       port = IM_IO_PORT;      /* anyway, set the portnumber and warn */
-                       printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n" "              SCSI-operations may not work.\n");
+       if (mca_dev->slot == MCA_INTEGSCSI &&
+           ((!pos[0] && !pos[1] && pos[2] > 0 &&
+             pos[3] > 0 && !pos[4] && !pos[5] &&
+             !pos[6] && !pos[7]) ||
+            (pos[0] == 0xff && pos[1] == 0xff &&
+             pos[2] < 0xff && pos[3] < 0xff &&
+             pos[4] == 0xff && pos[5] == 0xff &&
+             pos[6] == 0xff && pos[7] == 0xff))) {
+               irq = IM_IRQ;
+               port = IM_IO_PORT;
+       } else {
+               irq = IM_IRQ;
+               port = IM_IO_PORT + ((pos[2] &0x0e) << 2);
+               if ((mca_dev->index == IBM_SCSI2_FW) && (pos[6] != 0)) {
+                       printk(KERN_ERR "IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n");
+                       printk(KERN_ERR "              Impossible to determine adapter PUN!\n");
+                       printk(KERN_ERR "              Guessing adapter PUN = 7.\n");
+                       id = 7;
+               } else {
+                       id = (pos[3] & 0xe0) >> 5;      /* get subsystem PUN */
+                       if (mca_dev->index == IBM_SCSI2_FW) {
+                               id |= (pos[3] & 0x10) >> 1;     /* get subsystem PUN high-bit
+                                                                * for F/W adapters */
+                       }
                }
-               id = (pos[3] & 0xe0) >> 5;      /* this is correct and represents the PUN */
-               /* give detailed information on the subsystem. This helps me
-                * additionally during debugging and analyzing bug-reports. */
-               printk(KERN_INFO "IBM MCA SCSI: IBM Integrated SCSI Controller ffound, io=0x%x, scsi id=%d,\n", port, id);
-               printk(KERN_INFO "              chip rev.=%d, 8K NVRAM=%s, subsystem=%s\n", ((pos[2] & 0xf0) >> 4), (pos[2] & 2) ? "locked" : "accessible", (pos[2] & 1) ? "enabled." : "disabled.");
-
-               /* register the found integrated SCSI-subsystem */
-               if ((shpnt = ibmmca_register(scsi_template, port, id, INTEGRATED_SCSI, "IBM Integrated SCSI Controller"))) 
-               {
-                       for (k = 2; k < 7; k++)
-                               ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = pos[k];
-                       ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = INTEGRATED_SCSI;
-                       mca_set_adapter_name(MCA_INTEGSCSI, "IBM Integrated SCSI Controller");
-                       mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo, shpnt);
-                       mca_mark_as_used(MCA_INTEGSCSI);
-                       devices_on_irq_14++;
+               if ((mca_dev->index == IBM_SCSI2_FW) &&
+                   (pos[4] & 0x01) && (pos[6] == 0)) {
+                       /* IRQ11 is used by SCSI-2 F/W Adapter/A */
+                       printk(KERN_DEBUG "IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n");
+                       irq = IM_IRQ_FW;
                }
        }
 
-       /* now look for other adapters in MCA slots, */
-       /* determine the number of known IBM-SCSI-subsystem types */
-       /* see the pos[2] dependence to get the adapter port-offset. */
-       for (i = 0; i < ARRAY_SIZE(subsys_list); i++) {
-               /* scan each slot for a fitting adapter id */
-               slot = 0;       /* start at slot 0 */
-               while ((slot = mca_find_adapter(subsys_list[i].mca_id, slot))
-                      != MCA_NOTFOUND) {       /* scan through all slots */
-                       for (j = 0; j < 8; j++) /* read the pos-information */
-                               pos[j] = mca_read_stored_pos(slot, j);
-                       if ((pos[2] & 1) == 1)
-                               /* is the subsystem chip enabled ? */
-                               /* (explanations see above) */
-                               port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
-                       else {
-                               /* anyway, set the portnumber and warn */
-                               port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
-                               printk(KERN_WARNING "IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
-                               printk(KERN_WARNING "              SCSI-operations may not work.\n");
-                       }
-                       if ((i == IBM_SCSI2_FW) && (pos[6] != 0)) {
-                               printk(KERN_ERR "IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n");
-                               printk(KERN_ERR "              Impossible to determine adapter PUN!\n");
-                               printk(KERN_ERR "              Guessing adapter PUN = 7.\n");
-                               id = 7;
-                       } else {
-                               id = (pos[3] & 0xe0) >> 5;      /* get subsystem PUN */
-                               if (i == IBM_SCSI2_FW) {
-                                       id |= (pos[3] & 0x10) >> 1;     /* get subsystem PUN high-bit
-                                                                        * for F/W adapters */
-                               }
-                       }
-                       if ((i == IBM_SCSI2_FW) && (pos[4] & 0x01) && (pos[6] == 0)) {
-                               /* IRQ11 is used by SCSI-2 F/W Adapter/A */
-                               printk(KERN_DEBUG "IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n");
-                               /* get interrupt request level */
-                               if (request_irq(IM_IRQ_FW, interrupt_handler, IRQF_SHARED, "ibmmcascsi", hosts)) {
-                                       printk(KERN_ERR "IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ_FW);
-                               } else
-                                       IRQ11_registered++;
-                       }
-                       printk(KERN_INFO "IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d,\n", subsys_list[i].description, slot + 1, port, id);
-                       if ((pos[2] & 0xf0) == 0xf0)
-                               printk(KERN_DEBUG"              ROM Addr.=off,");
-                       else
-                               printk(KERN_DEBUG "              ROM Addr.=0x%x,", ((pos[2] & 0xf0) << 13) + 0xc0000);
-                       printk(KERN_DEBUG " port-offset=0x%x, subsystem=%s\n", ((pos[2] & 0x0e) << 2), (pos[2] & 1) ? "enabled." : "disabled.");
-
-                       /* register the hostadapter */
-                       if ((shpnt = ibmmca_register(scsi_template, port, id, i, subsys_list[i].description))) {
-                               for (k = 2; k < 8; k++)
-                                       ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = pos[k];
-                               ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = i;
-                               mca_set_adapter_name(slot, subsys_list[i].description);
-                               mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmmca_getinfo, shpnt);
-                               mca_mark_as_used(slot);
-                               if ((i == IBM_SCSI2_FW) && (pos[4] & 0x01) && (pos[6] == 0))
-                                       devices_on_irq_11++;
-                               else
-                                       devices_on_irq_14++;
-                       }
-                       slot++; /* advance to next slot */
-               }               /* advance to next adapter id in the list of IBM-SCSI-subsystems */
-       }
 
-       /* now check for SCSI-adapters, mapped to the integrated SCSI
-        * area. E.g. a W/Cache in MCA-slot 9(!). Do the check correct here,
-        * as this is a known effect on some models 95xx. */
-       for (i = 0; i < ARRAY_SIZE(subsys_list); i++) {
-               /* scan each slot for a fitting adapter id */
-               slot = mca_find_adapter(subsys_list[i].mca_id, MCA_INTEGSCSI);
-               if (slot != MCA_NOTFOUND) {     /* scan through all slots */
-                       for (j = 0; j < 8; j++) /* read the pos-information */
-                               pos[j] = mca_read_stored_pos(slot, j);
-                       if ((pos[2] & 1) == 1) {        /* is the subsystem chip enabled ? */
-                               /* (explanations see above) */
-                               port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
-                       } else {        /* anyway, set the portnumber and warn */
-                               port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
-                               printk(KERN_WARNING "IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
-                               printk(KERN_WARNING "              SCSI-operations may not work.\n");
-                       }
-                       if ((i == IBM_SCSI2_FW) && (pos[6] != 0)) {
-                               printk(KERN_ERR "IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n");
-                               printk(KERN_ERR  "              Impossible to determine adapter PUN!\n");
-                               printk(KERN_ERR "              Guessing adapter PUN = 7.\n");
-                               id = 7;
-                       } else {
-                               id = (pos[3] & 0xe0) >> 5;      /* get subsystem PUN */
-                               if (i == IBM_SCSI2_FW)
-                                       id |= (pos[3] & 0x10) >> 1;     /* get subsystem PUN high-bit
-                                                                        * for F/W adapters */
-                       }
-                       if ((i == IBM_SCSI2_FW) && (pos[4] & 0x01) && (pos[6] == 0)) {
-                               /* IRQ11 is used by SCSI-2 F/W Adapter/A */
-                               printk(KERN_DEBUG  "IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n");
-                               /* get interrupt request level */
-                               if (request_irq(IM_IRQ_FW, interrupt_handler, IRQF_SHARED, "ibmmcascsi", hosts))
-                                       printk(KERN_ERR "IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ_FW);
-                               else
-                                       IRQ11_registered++;
-                       }
-                       printk(KERN_INFO "IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d,\n", subsys_list[i].description, slot + 1, port, id);
-                       if ((pos[2] & 0xf0) == 0xf0)
-                               printk(KERN_DEBUG "              ROM Addr.=off,");
-                       else
-                               printk(KERN_DEBUG "              ROM Addr.=0x%x,", ((pos[2] & 0xf0) << 13) + 0xc0000);
-                       printk(KERN_DEBUG " port-offset=0x%x, subsystem=%s\n", ((pos[2] & 0x0e) << 2), (pos[2] & 1) ? "enabled." : "disabled.");
-
-                       /* register the hostadapter */
-                       if ((shpnt = ibmmca_register(scsi_template, port, id, i, subsys_list[i].description))) {
-                               for (k = 2; k < 7; k++)
-                                       ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = pos[k];
-                               ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = i;
-                               mca_set_adapter_name(slot, subsys_list[i].description);
-                               mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmmca_getinfo, shpnt);
-                               mca_mark_as_used(slot);
-                               if ((i == IBM_SCSI2_FW) && (pos[4] & 0x01) && (pos[6] == 0))
-                                       devices_on_irq_11++;
-                               else
-                                       devices_on_irq_14++;
-                       }
-                       slot++; /* advance to next slot */
-               }               /* advance to next adapter id in the list of IBM-SCSI-subsystems */
-       }
-       if (IRQ11_registered && !devices_on_irq_11)
-               free_irq(IM_IRQ_FW, hosts);     /* no devices on IRQ 11 */
-       if (IRQ14_registered && !devices_on_irq_14)
-               free_irq(IM_IRQ, hosts);        /* no devices on IRQ 14 */
-       if (!devices_on_irq_11 && !devices_on_irq_14)
-               printk(KERN_WARNING "IBM MCA SCSI: No IBM SCSI-subsystem adapter attached.\n");
-       return found;           /* return the number of found SCSI hosts. Should be 1 or 0. */
-}
 
-static struct Scsi_Host *ibmmca_register(struct scsi_host_template * scsi_template, int port, int id, int adaptertype, char *hostname)
-{
-       struct Scsi_Host *shpnt;
-       int i, j;
-       unsigned int ctrl;
+       /* give detailed information on the subsystem. This helps me
+        * additionally during debugging and analyzing bug-reports. */
+       printk(KERN_INFO "IBM MCA SCSI: %s found, io=0x%x, scsi id=%d,\n",
+              description, port, id);
+       if (mca_dev->slot == MCA_INTEGSCSI)
+               printk(KERN_INFO "              chip rev.=%d, 8K NVRAM=%s, subsystem=%s\n", ((pos[2] & 0xf0) >> 4), (pos[2] & 2) ? "locked" : "accessible", (pos[2] & 1) ? "enabled." : "disabled.");
+       else {
+               if ((pos[2] & 0xf0) == 0xf0)
+                       printk(KERN_DEBUG "              ROM Addr.=off,");
+               else
+                       printk(KERN_DEBUG "              ROM Addr.=0x%x,", ((pos[2] & 0xf0) << 13) + 0xc0000);
+
+               printk(KERN_DEBUG " port-offset=0x%x, subsystem=%s\n", ((pos[2] & 0x0e) << 2), (pos[2] & 1) ? "enabled." : "disabled.");
+       }
 
        /* check I/O region */
-       if (!request_region(port, IM_N_IO_PORT, hostname)) {
+       if (!request_region(port, IM_N_IO_PORT, description)) {
                printk(KERN_ERR "IBM MCA SCSI: Unable to get I/O region 0x%x-0x%x (%d ports).\n", port, port + IM_N_IO_PORT - 1, IM_N_IO_PORT);
-               return NULL;
+               goto out_fail;
        }
 
        /* register host */
-       shpnt = scsi_register(scsi_template, sizeof(struct ibmmca_hostdata));
+       shpnt = scsi_host_alloc(&ibmmca_driver_template,
+                               sizeof(struct ibmmca_hostdata));
        if (!shpnt) {
                printk(KERN_ERR "IBM MCA SCSI: Unable to register host.\n");
-               release_region(port, IM_N_IO_PORT);
-               return NULL;
+               goto out_release;
+       }
+
+       dev_set_drvdata(dev, shpnt);
+       if(request_irq(irq, interrupt_handler, IRQF_SHARED, description, dev)) {
+               printk(KERN_ERR "IBM MCA SCSI: failed to request interrupt %d\n", irq);
+               goto out_free_host;
        }
 
        /* request I/O region */
-       hosts[found] = shpnt;   /* add new found hostadapter to the list */
-       special(found) = adaptertype;   /* important assignment or else crash! */
-       subsystem_connector_size(found) = 0;    /* preset slot-size */
-       shpnt->irq = IM_IRQ;    /* assign necessary stuff for the adapter */
+       special(shpnt) = mca_dev->index;        /* important assignment or else crash! */
+       subsystem_connector_size(shpnt) = 0;    /* preset slot-size */
+       shpnt->irq = irq;       /* assign necessary stuff for the adapter */
        shpnt->io_port = port;
        shpnt->n_io_port = IM_N_IO_PORT;
        shpnt->this_id = id;
        shpnt->max_id = 8;      /* 8 PUNs are default */
        /* now, the SCSI-subsystem is connected to Linux */
 
-       ctrl = (unsigned int) (inb(IM_CTR_REG(found))); /* get control-register status */
 #ifdef IM_DEBUG_PROBE
+       ctrl = (unsigned int) (inb(IM_CTR_REG(found))); /* get control-register status */
        printk("IBM MCA SCSI: Control Register contents: %x, status: %x\n", ctrl, inb(IM_STAT_REG(found)));
        printk("IBM MCA SCSI: This adapters' POS-registers: ");
        for (i = 0; i < 8; i++)
                printk("%x ", pos[i]);
        printk("\n");
 #endif
-       reset_status(found) = IM_RESET_NOT_IN_PROGRESS;
+       reset_status(shpnt) = IM_RESET_NOT_IN_PROGRESS;
 
        for (i = 0; i < 16; i++)        /* reset the tables */
                for (j = 0; j < 8; j++)
-                       get_ldn(found)[i][j] = MAX_LOG_DEV;
+                       get_ldn(shpnt)[i][j] = MAX_LOG_DEV;
 
        /* check which logical devices exist */
        /* after this line, local interrupting is possible: */
-       local_checking_phase_flag(found) = 1;
-       check_devices(found, adaptertype);      /* call by value, using the global variable hosts */
-       local_checking_phase_flag(found) = 0;
-       found++;                /* now increase index to be prepared for next found subsystem */
+       local_checking_phase_flag(shpnt) = 1;
+       check_devices(shpnt, mca_dev->index);   /* call by value, using the global variable hosts */
+       local_checking_phase_flag(shpnt) = 0;
+
        /* an ibm mca subsystem has been detected */
-       return shpnt;
+
+       for (k = 2; k < 7; k++)
+               ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = pos[k];
+       ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = INTEGRATED_SCSI;
+       mca_device_set_name(mca_dev, description);
+       /* FIXME: NEED TO REPLUMB TO SYSFS
+          mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo, shpnt);
+       */
+       mca_device_set_claim(mca_dev, 1);
+       if (scsi_add_host(shpnt, dev)) {
+               dev_printk(KERN_ERR, dev, "IBM MCA SCSI: scsi_add_host failed\n");
+               goto out_free_host;
+       }
+       scsi_scan_host(shpnt);
+
+       return 0;
+ out_free_host:
+       scsi_host_put(shpnt);
+ out_release:
+       release_region(port, IM_N_IO_PORT);
+ out_fail:
+       return ret;
 }
 
-static int ibmmca_release(struct Scsi_Host *shpnt)
+static int __devexit ibmmca_remove(struct device *dev)
 {
+       struct Scsi_Host *shpnt = dev_get_drvdata(dev);
+       scsi_remove_host(shpnt);
        release_region(shpnt->io_port, shpnt->n_io_port);
-       if (!(--found))
-               free_irq(shpnt->irq, hosts);
+       free_irq(shpnt->irq, dev);
        return 0;
 }
 
@@ -1805,33 +1706,24 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        int current_ldn;
        int id, lun;
        int target;
-       int host_index;
        int max_pun;
        int i;
-       struct scatterlist *sl;
+       struct scatterlist *sg;
 
        shpnt = cmd->device->host;
-       /* search for the right hostadapter */
-       for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
 
-       if (!hosts[host_index]) {       /* invalid hostadapter descriptor address */
-               cmd->result = DID_NO_CONNECT << 16;
-               if (done)
-                       done(cmd);
-               return 0;
-       }
-       max_pun = subsystem_maxid(host_index);
+       max_pun = subsystem_maxid(shpnt);
        if (ibm_ansi_order) {
                target = max_pun - 1 - cmd->device->id;
-               if ((target <= subsystem_pun(host_index)) && (cmd->device->id <= subsystem_pun(host_index)))
+               if ((target <= subsystem_pun(shpnt)) && (cmd->device->id <= subsystem_pun(shpnt)))
                        target--;
-               else if ((target >= subsystem_pun(host_index)) && (cmd->device->id >= subsystem_pun(host_index)))
+               else if ((target >= subsystem_pun(shpnt)) && (cmd->device->id >= subsystem_pun(shpnt)))
                        target++;
        } else
                target = cmd->device->id;
 
        /* if (target,lun) is NO LUN or not existing at all, return error */
-       if ((get_scsi(host_index)[target][cmd->device->lun] == TYPE_NO_LUN) || (get_scsi(host_index)[target][cmd->device->lun] == TYPE_NO_DEVICE)) {
+       if ((get_scsi(shpnt)[target][cmd->device->lun] == TYPE_NO_LUN) || (get_scsi(shpnt)[target][cmd->device->lun] == TYPE_NO_DEVICE)) {
                cmd->result = DID_NO_CONNECT << 16;
                if (done)
                        done(cmd);
@@ -1839,16 +1731,16 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        }
 
        /*if (target,lun) unassigned, do further checks... */
-       ldn = get_ldn(host_index)[target][cmd->device->lun];
+       ldn = get_ldn(shpnt)[target][cmd->device->lun];
        if (ldn >= MAX_LOG_DEV) {       /* on invalid ldn do special stuff */
                if (ldn > MAX_LOG_DEV) {        /* dynamical remapping if ldn unassigned */
-                       current_ldn = next_ldn(host_index);     /* stop-value for one circle */
-                       while (ld(host_index)[next_ldn(host_index)].cmd) {      /* search for a occupied, but not in */
+                       current_ldn = next_ldn(shpnt);  /* stop-value for one circle */
+                       while (ld(shpnt)[next_ldn(shpnt)].cmd) {        /* search for a occupied, but not in */
                                /* command-processing ldn. */
-                               next_ldn(host_index)++;
-                               if (next_ldn(host_index) >= MAX_LOG_DEV)
-                                       next_ldn(host_index) = 7;
-                               if (current_ldn == next_ldn(host_index)) {      /* One circle done ? */
+                               next_ldn(shpnt)++;
+                               if (next_ldn(shpnt) >= MAX_LOG_DEV)
+                                       next_ldn(shpnt) = 7;
+                               if (current_ldn == next_ldn(shpnt)) {   /* One circle done ? */
                                        /* no non-processing ldn found */
                                        scmd_printk(KERN_WARNING, cmd,
        "IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n"
@@ -1864,56 +1756,56 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                        /* unmap non-processing ldn */
                        for (id = 0; id < max_pun; id++)
                                for (lun = 0; lun < 8; lun++) {
-                                       if (get_ldn(host_index)[id][lun] == next_ldn(host_index)) {
-                                               get_ldn(host_index)[id][lun] = TYPE_NO_DEVICE;
-                                               get_scsi(host_index)[id][lun] = TYPE_NO_DEVICE;
+                                       if (get_ldn(shpnt)[id][lun] == next_ldn(shpnt)) {
+                                               get_ldn(shpnt)[id][lun] = TYPE_NO_DEVICE;
+                                               get_scsi(shpnt)[id][lun] = TYPE_NO_DEVICE;
                                                /* unmap entry */
                                        }
                                }
                        /* set reduced interrupt_handler-mode for checking */
-                       local_checking_phase_flag(host_index) = 1;
+                       local_checking_phase_flag(shpnt) = 1;
                        /* map found ldn to pun,lun */
-                       get_ldn(host_index)[target][cmd->device->lun] = next_ldn(host_index);
+                       get_ldn(shpnt)[target][cmd->device->lun] = next_ldn(shpnt);
                        /* change ldn to the right value, that is now next_ldn */
-                       ldn = next_ldn(host_index);
+                       ldn = next_ldn(shpnt);
                        /* unassign all ldns (pun,lun,ldn does not matter for remove) */
-                       immediate_assign(host_index, 0, 0, 0, REMOVE_LDN);
+                       immediate_assign(shpnt, 0, 0, 0, REMOVE_LDN);
                        /* set only LDN for remapped device */
-                       immediate_assign(host_index, target, cmd->device->lun, ldn, SET_LDN);
+                       immediate_assign(shpnt, target, cmd->device->lun, ldn, SET_LDN);
                        /* get device information for ld[ldn] */
-                       if (device_exists(host_index, ldn, &ld(host_index)[ldn].block_length, &ld(host_index)[ldn].device_type)) {
-                               ld(host_index)[ldn].cmd = NULL; /* To prevent panic set 0, because
+                       if (device_exists(shpnt, ldn, &ld(shpnt)[ldn].block_length, &ld(shpnt)[ldn].device_type)) {
+                               ld(shpnt)[ldn].cmd = NULL;      /* To prevent panic set 0, because
                                                                   devices that were not assigned,
                                                                   should have nothing in progress. */
-                               get_scsi(host_index)[target][cmd->device->lun] = ld(host_index)[ldn].device_type;
+                               get_scsi(shpnt)[target][cmd->device->lun] = ld(shpnt)[ldn].device_type;
                                /* increase assignment counters for statistics in /proc */
-                               IBM_DS(host_index).dynamical_assignments++;
-                               IBM_DS(host_index).ldn_assignments[ldn]++;
+                               IBM_DS(shpnt).dynamical_assignments++;
+                               IBM_DS(shpnt).ldn_assignments[ldn]++;
                        } else
                                /* panic here, because a device, found at boottime has
                                   vanished */
                                panic("IBM MCA SCSI: ldn=0x%x, SCSI-device on (%d,%d) vanished!\n", ldn, target, cmd->device->lun);
                        /* unassign again all ldns (pun,lun,ldn does not matter for remove) */
-                       immediate_assign(host_index, 0, 0, 0, REMOVE_LDN);
+                       immediate_assign(shpnt, 0, 0, 0, REMOVE_LDN);
                        /* remap all ldns, as written in the pun/lun table */
                        lun = 0;
 #ifdef CONFIG_SCSI_MULTI_LUN
                        for (lun = 0; lun < 8; lun++)
 #endif
                                for (id = 0; id < max_pun; id++) {
-                                       if (get_ldn(host_index)[id][lun] <= MAX_LOG_DEV)
-                                               immediate_assign(host_index, id, lun, get_ldn(host_index)[id][lun], SET_LDN);
+                                       if (get_ldn(shpnt)[id][lun] <= MAX_LOG_DEV)
+                                               immediate_assign(shpnt, id, lun, get_ldn(shpnt)[id][lun], SET_LDN);
                                }
                        /* set back to normal interrupt_handling */
-                       local_checking_phase_flag(host_index) = 0;
+                       local_checking_phase_flag(shpnt) = 0;
 #ifdef IM_DEBUG_PROBE
                        /* Information on syslog terminal */
                        printk("IBM MCA SCSI: ldn=0x%x dynamically reassigned to (%d,%d).\n", ldn, target, cmd->device->lun);
 #endif
                        /* increase next_ldn for next dynamical assignment */
-                       next_ldn(host_index)++;
-                       if (next_ldn(host_index) >= MAX_LOG_DEV)
-                               next_ldn(host_index) = 7;
+                       next_ldn(shpnt)++;
+                       if (next_ldn(shpnt) >= MAX_LOG_DEV)
+                               next_ldn(shpnt) = 7;
                } else {        /* wall against Linux accesses to the subsystem adapter */
                        cmd->result = DID_BAD_TARGET << 16;
                        if (done)
@@ -1923,34 +1815,32 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        }
 
        /*verify there is no command already in progress for this log dev */
-       if (ld(host_index)[ldn].cmd)
+       if (ld(shpnt)[ldn].cmd)
                panic("IBM MCA SCSI: cmd already in progress for this ldn.\n");
 
        /*save done in cmd, and save cmd for the interrupt handler */
        cmd->scsi_done = done;
-       ld(host_index)[ldn].cmd = cmd;
+       ld(shpnt)[ldn].cmd = cmd;
 
        /*fill scb information independent of the scsi command */
-       scb = &(ld(host_index)[ldn].scb);
-       ld(host_index)[ldn].tsb.dev_status = 0;
+       scb = &(ld(shpnt)[ldn].scb);
+       ld(shpnt)[ldn].tsb.dev_status = 0;
        scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_RETRY_ENABLE;
-       scb->tsb_adr = isa_virt_to_bus(&(ld(host_index)[ldn].tsb));
+       scb->tsb_adr = isa_virt_to_bus(&(ld(shpnt)[ldn].tsb));
        scsi_cmd = cmd->cmnd[0];
 
-       if (cmd->use_sg) {
-               i = cmd->use_sg;
-               sl = (struct scatterlist *) (cmd->request_buffer);
-               if (i > 16)
-                       panic("IBM MCA SCSI: scatter-gather list too long.\n");
-               while (--i >= 0) {
-                       ld(host_index)[ldn].sge[i].address = (void *) (isa_page_to_bus(sl[i].page) + sl[i].offset);
-                       ld(host_index)[ldn].sge[i].byte_length = sl[i].length;
+       if (scsi_sg_count(cmd)) {
+               BUG_ON(scsi_sg_count(cmd) > 16);
+
+               scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) {
+                       ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg->page) + sg->offset);
+                       ld(shpnt)[ldn].sge[i].byte_length = sg->length;
                }
                scb->enable |= IM_POINTER_TO_LIST;
-               scb->sys_buf_adr = isa_virt_to_bus(&(ld(host_index)[ldn].sge[0]));
-               scb->sys_buf_length = cmd->use_sg * sizeof(struct im_sge);
+               scb->sys_buf_adr = isa_virt_to_bus(&(ld(shpnt)[ldn].sge[0]));
+               scb->sys_buf_length = scsi_sg_count(cmd) * sizeof(struct im_sge);
        } else {
-               scb->sys_buf_adr = isa_virt_to_bus(cmd->request_buffer);
+               scb->sys_buf_adr = isa_virt_to_bus(scsi_sglist(cmd));
                /* recent Linux midlevel SCSI places 1024 byte for inquiry
                 * command. Far too much for old PS/2 hardware. */
                switch (scsi_cmd) {
@@ -1961,16 +1851,16 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                case REQUEST_SENSE:
                case MODE_SENSE:
                case MODE_SELECT:
-                       if (cmd->request_bufflen > 255)
+                       if (scsi_bufflen(cmd) > 255)
                                scb->sys_buf_length = 255;
                        else
-                               scb->sys_buf_length = cmd->request_bufflen;
+                               scb->sys_buf_length = scsi_bufflen(cmd);
                        break;
                case TEST_UNIT_READY:
                        scb->sys_buf_length = 0;
                        break;
                default:
-                       scb->sys_buf_length = cmd->request_bufflen;
+                       scb->sys_buf_length = scsi_bufflen(cmd);
                        break;
                }
        }
@@ -1982,16 +1872,16 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 
        /* for specific device-type debugging: */
 #ifdef IM_DEBUG_CMD_SPEC_DEV
-       if (ld(host_index)[ldn].device_type == IM_DEBUG_CMD_DEVICE)
-               printk("(SCSI-device-type=0x%x) issue scsi cmd=%02x to ldn=%d\n", ld(host_index)[ldn].device_type, scsi_cmd, ldn);
+       if (ld(shpnt)[ldn].device_type == IM_DEBUG_CMD_DEVICE)
+               printk("(SCSI-device-type=0x%x) issue scsi cmd=%02x to ldn=%d\n", ld(shpnt)[ldn].device_type, scsi_cmd, ldn);
 #endif
 
        /* for possible panics store current command */
-       last_scsi_command(host_index)[ldn] = scsi_cmd;
-       last_scsi_type(host_index)[ldn] = IM_SCB;
+       last_scsi_command(shpnt)[ldn] = scsi_cmd;
+       last_scsi_type(shpnt)[ldn] = IM_SCB;
        /* update statistical info */
-       IBM_DS(host_index).total_accesses++;
-       IBM_DS(host_index).ldn_access[ldn]++;
+       IBM_DS(shpnt).total_accesses++;
+       IBM_DS(shpnt).ldn_access[ldn]++;
 
        switch (scsi_cmd) {
        case READ_6:
@@ -2003,17 +1893,17 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                /* Distinguish between disk and other devices. Only disks (that are the
                   most frequently accessed devices) should be supported by the
                   IBM-SCSI-Subsystem commands. */
-               switch (ld(host_index)[ldn].device_type) {
+               switch (ld(shpnt)[ldn].device_type) {
                case TYPE_DISK: /* for harddisks enter here ... */
                case TYPE_MOD:  /* ... try it also for MO-drives (send flames as */
                        /*     you like, if this won't work.) */
                        if (scsi_cmd == READ_6 || scsi_cmd == READ_10 || scsi_cmd == READ_12) {
                                /* read command preparations */
                                scb->enable |= IM_READ_CONTROL;
-                               IBM_DS(host_index).ldn_read_access[ldn]++;      /* increase READ-access on ldn stat. */
+                               IBM_DS(shpnt).ldn_read_access[ldn]++;   /* increase READ-access on ldn stat. */
                                scb->command = IM_READ_DATA_CMD | IM_NO_DISCONNECT;
                        } else {        /* write command preparations */
-                               IBM_DS(host_index).ldn_write_access[ldn]++;     /* increase write-count on ldn stat. */
+                               IBM_DS(shpnt).ldn_write_access[ldn]++;  /* increase write-count on ldn stat. */
                                scb->command = IM_WRITE_DATA_CMD | IM_NO_DISCONNECT;
                        }
                        if (scsi_cmd == READ_6 || scsi_cmd == WRITE_6) {
@@ -2023,9 +1913,9 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                                scb->u1.log_blk_adr = (((unsigned) cmd->cmnd[5]) << 0) | (((unsigned) cmd->cmnd[4]) << 8) | (((unsigned) cmd->cmnd[3]) << 16) | (((unsigned) cmd->cmnd[2]) << 24);
                                scb->u2.blk.count = (((unsigned) cmd->cmnd[8]) << 0) | (((unsigned) cmd->cmnd[7]) << 8);
                        }
-                       last_scsi_logical_block(host_index)[ldn] = scb->u1.log_blk_adr;
-                       last_scsi_blockcount(host_index)[ldn] = scb->u2.blk.count;
-                       scb->u2.blk.length = ld(host_index)[ldn].block_length;
+                       last_scsi_logical_block(shpnt)[ldn] = scb->u1.log_blk_adr;
+                       last_scsi_blockcount(shpnt)[ldn] = scb->u2.blk.count;
+                       scb->u2.blk.length = ld(shpnt)[ldn].block_length;
                        break;
                        /* for other devices, enter here. Other types are not known by
                           Linux! TYPE_NO_LUN is forbidden as valid device. */
@@ -2046,14 +1936,14 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                        scb->enable |= IM_BYPASS_BUFFER;
                        scb->u1.scsi_cmd_length = cmd->cmd_len;
                        memcpy(scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
-                       last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
+                       last_scsi_type(shpnt)[ldn] = IM_LONG_SCB;
                        /* Read/write on this non-disk devices is also displayworthy,
                           so flash-up the LED/display. */
                        break;
                }
                break;
        case INQUIRY:
-               IBM_DS(host_index).ldn_inquiry_access[ldn]++;
+               IBM_DS(shpnt).ldn_inquiry_access[ldn]++;
                scb->command = IM_DEVICE_INQUIRY_CMD;
                scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
                scb->u1.log_blk_adr = 0;
@@ -2064,7 +1954,7 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                scb->u1.log_blk_adr = 0;
                scb->u1.scsi_cmd_length = 6;
                memcpy(scb->u2.scsi_command, cmd->cmnd, 6);
-               last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
+               last_scsi_type(shpnt)[ldn] = IM_LONG_SCB;
                break;
        case READ_CAPACITY:
                /* the length of system memory buffer must be exactly 8 bytes */
@@ -2081,12 +1971,12 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                /* Commands that need write-only-mode (system -> device): */
        case MODE_SELECT:
        case MODE_SELECT_10:
-               IBM_DS(host_index).ldn_modeselect_access[ldn]++;
+               IBM_DS(shpnt).ldn_modeselect_access[ldn]++;
                scb->command = IM_OTHER_SCSI_CMD_CMD;
                scb->enable |= IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;   /*Select needs WRITE-enabled */
                scb->u1.scsi_cmd_length = cmd->cmd_len;
                memcpy(scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
-               last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
+               last_scsi_type(shpnt)[ldn] = IM_LONG_SCB;
                break;
                /* For other commands, read-only is useful. Most other commands are
                   running without an input-data-block. */
@@ -2095,19 +1985,19 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
                scb->u1.scsi_cmd_length = cmd->cmd_len;
                memcpy(scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
-               last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
+               last_scsi_type(shpnt)[ldn] = IM_LONG_SCB;
                break;
        }
        /*issue scb command, and return */
        if (++disk_rw_in_progress == 1)
                PS2_DISK_LED_ON(shpnt->host_no, target);
 
-       if (last_scsi_type(host_index)[ldn] == IM_LONG_SCB) {
-               issue_cmd(host_index, isa_virt_to_bus(scb), IM_LONG_SCB | ldn);
-               IBM_DS(host_index).long_scbs++;
+       if (last_scsi_type(shpnt)[ldn] == IM_LONG_SCB) {
+               issue_cmd(shpnt, isa_virt_to_bus(scb), IM_LONG_SCB | ldn);
+               IBM_DS(shpnt).long_scbs++;
        } else {
-               issue_cmd(host_index, isa_virt_to_bus(scb), IM_SCB | ldn);
-               IBM_DS(host_index).scbs++;
+               issue_cmd(shpnt, isa_virt_to_bus(scb), IM_SCB | ldn);
+               IBM_DS(shpnt).scbs++;
        }
        return 0;
 }
@@ -2122,7 +2012,6 @@ static int __ibmmca_abort(Scsi_Cmnd * cmd)
        unsigned int ldn;
        void (*saved_done) (Scsi_Cmnd *);
        int target;
-       int host_index;
        int max_pun;
        unsigned long imm_command;
 
@@ -2131,35 +2020,23 @@ static int __ibmmca_abort(Scsi_Cmnd * cmd)
 #endif
 
        shpnt = cmd->device->host;
-       /* search for the right hostadapter */
-       for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
 
-       if (!hosts[host_index]) {       /* invalid hostadapter descriptor address */
-               cmd->result = DID_NO_CONNECT << 16;
-               if (cmd->scsi_done)
-                       (cmd->scsi_done) (cmd);
-               shpnt = cmd->device->host;
-#ifdef IM_DEBUG_PROBE
-               printk(KERN_DEBUG "IBM MCA SCSI: Abort adapter selection failed!\n");
-#endif
-               return SUCCESS;
-       }
-       max_pun = subsystem_maxid(host_index);
+       max_pun = subsystem_maxid(shpnt);
        if (ibm_ansi_order) {
                target = max_pun - 1 - cmd->device->id;
-               if ((target <= subsystem_pun(host_index)) && (cmd->device->id <= subsystem_pun(host_index)))
+               if ((target <= subsystem_pun(shpnt)) && (cmd->device->id <= subsystem_pun(shpnt)))
                        target--;
-               else if ((target >= subsystem_pun(host_index)) && (cmd->device->id >= subsystem_pun(host_index)))
+               else if ((target >= subsystem_pun(shpnt)) && (cmd->device->id >= subsystem_pun(shpnt)))
                        target++;
        } else
                target = cmd->device->id;
 
        /* get logical device number, and disable system interrupts */
        printk(KERN_WARNING "IBM MCA SCSI: Sending abort to device pun=%d, lun=%d.\n", target, cmd->device->lun);
-       ldn = get_ldn(host_index)[target][cmd->device->lun];
+       ldn = get_ldn(shpnt)[target][cmd->device->lun];
 
        /*if cmd for this ldn has already finished, no need to abort */
-       if (!ld(host_index)[ldn].cmd) {
+       if (!ld(shpnt)[ldn].cmd) {
                    return SUCCESS;
        }
 
@@ -2170,20 +2047,20 @@ static int __ibmmca_abort(Scsi_Cmnd * cmd)
        saved_done = cmd->scsi_done;
        cmd->scsi_done = internal_done;
        cmd->SCp.Status = 0;
-       last_scsi_command(host_index)[ldn] = IM_ABORT_IMM_CMD;
-       last_scsi_type(host_index)[ldn] = IM_IMM_CMD;
-       imm_command = inl(IM_CMD_REG(host_index));
+       last_scsi_command(shpnt)[ldn] = IM_ABORT_IMM_CMD;
+       last_scsi_type(shpnt)[ldn] = IM_IMM_CMD;
+       imm_command = inl(IM_CMD_REG(shpnt));
        imm_command &= (unsigned long) (0xffff0000);    /* mask reserved stuff */
        imm_command |= (unsigned long) (IM_ABORT_IMM_CMD);
        /* must wait for attention reg not busy */
        /* FIXME - timeout, politeness */
        while (1) {
-               if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY))
+               if (!(inb(IM_STAT_REG(shpnt)) & IM_BUSY))
                        break;
        }
        /* write registers and enable system interrupts */
-       outl(imm_command, IM_CMD_REG(host_index));
-       outb(IM_IMM_CMD | ldn, IM_ATTN_REG(host_index));
+       outl(imm_command, IM_CMD_REG(shpnt));
+       outb(IM_IMM_CMD | ldn, IM_ATTN_REG(shpnt));
 #ifdef IM_DEBUG_PROBE
        printk("IBM MCA SCSI: Abort queued to adapter...\n");
 #endif
@@ -2202,7 +2079,7 @@ static int __ibmmca_abort(Scsi_Cmnd * cmd)
                cmd->result |= DID_ABORT << 16;
                if (cmd->scsi_done)
                        (cmd->scsi_done) (cmd);
-               ld(host_index)[ldn].cmd = NULL;
+               ld(shpnt)[ldn].cmd = NULL;
 #ifdef IM_DEBUG_PROBE
                printk("IBM MCA SCSI: Abort finished with success.\n");
 #endif
@@ -2211,7 +2088,7 @@ static int __ibmmca_abort(Scsi_Cmnd * cmd)
                cmd->result |= DID_NO_CONNECT << 16;
                if (cmd->scsi_done)
                        (cmd->scsi_done) (cmd);
-               ld(host_index)[ldn].cmd = NULL;
+               ld(shpnt)[ldn].cmd = NULL;
 #ifdef IM_DEBUG_PROBE
                printk("IBM MCA SCSI: Abort failed.\n");
 #endif
@@ -2236,71 +2113,65 @@ static int __ibmmca_host_reset(Scsi_Cmnd * cmd)
        struct Scsi_Host *shpnt;
        Scsi_Cmnd *cmd_aid;
        int ticks, i;
-       int host_index;
        unsigned long imm_command;
 
        BUG_ON(cmd == NULL);
 
        ticks = IM_RESET_DELAY * HZ;
        shpnt = cmd->device->host;
-       /* search for the right hostadapter */
-       for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
-
-       if (!hosts[host_index]) /* invalid hostadapter descriptor address */
-               return FAILED;
 
-       if (local_checking_phase_flag(host_index)) {
+       if (local_checking_phase_flag(shpnt)) {
                printk(KERN_WARNING "IBM MCA SCSI: unable to reset while checking devices.\n");
                return FAILED;
        }
 
        /* issue reset immediate command to subsystem, and wait for interrupt */
        printk("IBM MCA SCSI: resetting all devices.\n");
-       reset_status(host_index) = IM_RESET_IN_PROGRESS;
-       last_scsi_command(host_index)[0xf] = IM_RESET_IMM_CMD;
-       last_scsi_type(host_index)[0xf] = IM_IMM_CMD;
-       imm_command = inl(IM_CMD_REG(host_index));
+       reset_status(shpnt) = IM_RESET_IN_PROGRESS;
+       last_scsi_command(shpnt)[0xf] = IM_RESET_IMM_CMD;
+       last_scsi_type(shpnt)[0xf] = IM_IMM_CMD;
+       imm_command = inl(IM_CMD_REG(shpnt));
        imm_command &= (unsigned long) (0xffff0000);    /* mask reserved stuff */
        imm_command |= (unsigned long) (IM_RESET_IMM_CMD);
        /* must wait for attention reg not busy */
        while (1) {
-               if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY))
+               if (!(inb(IM_STAT_REG(shpnt)) & IM_BUSY))
                        break;
                spin_unlock_irq(shpnt->host_lock);
                yield();
                spin_lock_irq(shpnt->host_lock);
        }
        /*write registers and enable system interrupts */
-       outl(imm_command, IM_CMD_REG(host_index));
-       outb(IM_IMM_CMD | 0xf, IM_ATTN_REG(host_index));
+       outl(imm_command, IM_CMD_REG(shpnt));
+       outb(IM_IMM_CMD | 0xf, IM_ATTN_REG(shpnt));
        /* wait for interrupt finished or intr_stat register to be set, as the
         * interrupt will not be executed, while we are in here! */
         
        /* FIXME: This is really really icky we so want a sleeping version of this ! */
-       while (reset_status(host_index) == IM_RESET_IN_PROGRESS && --ticks && ((inb(IM_INTR_REG(host_index)) & 0x8f) != 0x8f)) {
+       while (reset_status(shpnt) == IM_RESET_IN_PROGRESS && --ticks && ((inb(IM_INTR_REG(shpnt)) & 0x8f) != 0x8f)) {
                udelay((1 + 999 / HZ) * 1000);
                barrier();
        }
        /* if reset did not complete, just return an error */
        if (!ticks) {
                printk(KERN_ERR "IBM MCA SCSI: reset did not complete within %d seconds.\n", IM_RESET_DELAY);
-               reset_status(host_index) = IM_RESET_FINISHED_FAIL;
+               reset_status(shpnt) = IM_RESET_FINISHED_FAIL;
                return FAILED;
        }
 
-       if ((inb(IM_INTR_REG(host_index)) & 0x8f) == 0x8f) {
+       if ((inb(IM_INTR_REG(shpnt)) & 0x8f) == 0x8f) {
                /* analysis done by this routine and not by the intr-routine */
-               if (inb(IM_INTR_REG(host_index)) == 0xaf)
-                       reset_status(host_index) = IM_RESET_FINISHED_OK_NO_INT;
-               else if (inb(IM_INTR_REG(host_index)) == 0xcf)
-                       reset_status(host_index) = IM_RESET_FINISHED_FAIL;
+               if (inb(IM_INTR_REG(shpnt)) == 0xaf)
+                       reset_status(shpnt) = IM_RESET_FINISHED_OK_NO_INT;
+               else if (inb(IM_INTR_REG(shpnt)) == 0xcf)
+                       reset_status(shpnt) = IM_RESET_FINISHED_FAIL;
                else            /* failed, 4get it */
-                       reset_status(host_index) = IM_RESET_NOT_IN_PROGRESS_NO_INT;
-               outb(IM_EOI | 0xf, IM_ATTN_REG(host_index));
+                       reset_status(shpnt) = IM_RESET_NOT_IN_PROGRESS_NO_INT;
+               outb(IM_EOI | 0xf, IM_ATTN_REG(shpnt));
        }
 
        /* if reset failed, just return an error */
-       if (reset_status(host_index) == IM_RESET_FINISHED_FAIL) {
+       if (reset_status(shpnt) == IM_RESET_FINISHED_FAIL) {
                printk(KERN_ERR "IBM MCA SCSI: reset failed.\n");
                return FAILED;
        }
@@ -2308,9 +2179,9 @@ static int __ibmmca_host_reset(Scsi_Cmnd * cmd)
        /* so reset finished ok - call outstanding done's, and return success */
        printk(KERN_INFO "IBM MCA SCSI: Reset successfully completed.\n");
        for (i = 0; i < MAX_LOG_DEV; i++) {
-               cmd_aid = ld(host_index)[i].cmd;
+               cmd_aid = ld(shpnt)[i].cmd;
                if (cmd_aid && cmd_aid->scsi_done) {
-                       ld(host_index)[i].cmd = NULL;
+                       ld(shpnt)[i].cmd = NULL;
                        cmd_aid->result = DID_RESET << 16;
                }
        }
@@ -2351,46 +2222,46 @@ static int ibmmca_biosparam(struct scsi_device *sdev, struct block_device *bdev,
 }
 
 /* calculate percentage of total accesses on a ldn */
-static int ldn_access_load(int host_index, int ldn)
+static int ldn_access_load(struct Scsi_Host *shpnt, int ldn)
 {
-       if (IBM_DS(host_index).total_accesses == 0)
+       if (IBM_DS(shpnt).total_accesses == 0)
                return (0);
-       if (IBM_DS(host_index).ldn_access[ldn] == 0)
+       if (IBM_DS(shpnt).ldn_access[ldn] == 0)
                return (0);
-       return (IBM_DS(host_index).ldn_access[ldn] * 100) / IBM_DS(host_index).total_accesses;
+       return (IBM_DS(shpnt).ldn_access[ldn] * 100) / IBM_DS(shpnt).total_accesses;
 }
 
 /* calculate total amount of r/w-accesses */
-static int ldn_access_total_read_write(int host_index)
+static int ldn_access_total_read_write(struct Scsi_Host *shpnt)
 {
        int a;
        int i;
 
        a = 0;
        for (i = 0; i <= MAX_LOG_DEV; i++)
-               a += IBM_DS(host_index).ldn_read_access[i] + IBM_DS(host_index).ldn_write_access[i];
+               a += IBM_DS(shpnt).ldn_read_access[i] + IBM_DS(shpnt).ldn_write_access[i];
        return (a);
 }
 
-static int ldn_access_total_inquiry(int host_index)
+static int ldn_access_total_inquiry(struct Scsi_Host *shpnt)
 {
        int a;
        int i;
 
        a = 0;
        for (i = 0; i <= MAX_LOG_DEV; i++)
-               a += IBM_DS(host_index).ldn_inquiry_access[i];
+               a += IBM_DS(shpnt).ldn_inquiry_access[i];
        return (a);
 }
 
-static int ldn_access_total_modeselect(int host_index)
+static int ldn_access_total_modeselect(struct Scsi_Host *shpnt)
 {
        int a;
        int i;
 
        a = 0;
        for (i = 0; i <= MAX_LOG_DEV; i++)
-               a += IBM_DS(host_index).ldn_modeselect_access[i];
+               a += IBM_DS(shpnt).ldn_modeselect_access[i];
        return (a);
 }
 
@@ -2398,19 +2269,14 @@ static int ldn_access_total_modeselect(int host_index)
 static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout)
 {
        int len = 0;
-       int i, id, lun, host_index;
+       int i, id, lun;
        unsigned long flags;
        int max_pun;
 
-       for (i = 0; hosts[i] && hosts[i] != shpnt; i++);
        
-       spin_lock_irqsave(hosts[i]->host_lock, flags);  /* Check it */
-       host_index = i;
-       if (!shpnt) {
-               len += sprintf(buffer + len, "\nIBM MCA SCSI: Can't find adapter");
-               return len;
-       }
-       max_pun = subsystem_maxid(host_index);
+       spin_lock_irqsave(shpnt->host_lock, flags);     /* Check it */
+
+       max_pun = subsystem_maxid(shpnt);
 
        len += sprintf(buffer + len, "\n             IBM-SCSI-Subsystem-Linux-Driver, Version %s\n\n\n", IBMMCA_SCSI_DRIVER_VERSION);
        len += sprintf(buffer + len, " SCSI Access-Statistics:\n");
@@ -2421,40 +2287,40 @@ static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start,
        len += sprintf(buffer + len, "               Multiple LUN probing.....: No\n");
 #endif
        len += sprintf(buffer + len, "               This Hostnumber..........: %d\n", shpnt->host_no);
-       len += sprintf(buffer + len, "               Base I/O-Port............: 0x%x\n", (unsigned int) (IM_CMD_REG(host_index)));
+       len += sprintf(buffer + len, "               Base I/O-Port............: 0x%x\n", (unsigned int) (IM_CMD_REG(shpnt)));
        len += sprintf(buffer + len, "               (Shared) IRQ.............: %d\n", IM_IRQ);
-       len += sprintf(buffer + len, "               Total Interrupts.........: %d\n", IBM_DS(host_index).total_interrupts);
-       len += sprintf(buffer + len, "               Total SCSI Accesses......: %d\n", IBM_DS(host_index).total_accesses);
-       len += sprintf(buffer + len, "               Total short SCBs.........: %d\n", IBM_DS(host_index).scbs);
-       len += sprintf(buffer + len, "               Total long SCBs..........: %d\n", IBM_DS(host_index).long_scbs);
-       len += sprintf(buffer + len, "                 Total SCSI READ/WRITE..: %d\n", ldn_access_total_read_write(host_index));
-       len += sprintf(buffer + len, "                 Total SCSI Inquiries...: %d\n", ldn_access_total_inquiry(host_index));
-       len += sprintf(buffer + len, "                 Total SCSI Modeselects.: %d\n", ldn_access_total_modeselect(host_index));
-       len += sprintf(buffer + len, "                 Total SCSI other cmds..: %d\n", IBM_DS(host_index).total_accesses - ldn_access_total_read_write(host_index)
-                      - ldn_access_total_modeselect(host_index)
-                      - ldn_access_total_inquiry(host_index));
-       len += sprintf(buffer + len, "               Total SCSI command fails.: %d\n\n", IBM_DS(host_index).total_errors);
+       len += sprintf(buffer + len, "               Total Interrupts.........: %d\n", IBM_DS(shpnt).total_interrupts);
+       len += sprintf(buffer + len, "               Total SCSI Accesses......: %d\n", IBM_DS(shpnt).total_accesses);
+       len += sprintf(buffer + len, "               Total short SCBs.........: %d\n", IBM_DS(shpnt).scbs);
+       len += sprintf(buffer + len, "               Total long SCBs..........: %d\n", IBM_DS(shpnt).long_scbs);
+       len += sprintf(buffer + len, "                 Total SCSI READ/WRITE..: %d\n", ldn_access_total_read_write(shpnt));
+       len += sprintf(buffer + len, "                 Total SCSI Inquiries...: %d\n", ldn_access_total_inquiry(shpnt));
+       len += sprintf(buffer + len, "                 Total SCSI Modeselects.: %d\n", ldn_access_total_modeselect(shpnt));
+       len += sprintf(buffer + len, "                 Total SCSI other cmds..: %d\n", IBM_DS(shpnt).total_accesses - ldn_access_total_read_write(shpnt)
+                      - ldn_access_total_modeselect(shpnt)
+                      - ldn_access_total_inquiry(shpnt));
+       len += sprintf(buffer + len, "               Total SCSI command fails.: %d\n\n", IBM_DS(shpnt).total_errors);
        len += sprintf(buffer + len, " Logical-Device-Number (LDN) Access-Statistics:\n");
        len += sprintf(buffer + len, "         LDN | Accesses [%%] |   READ    |   WRITE   | ASSIGNMENTS\n");
        len += sprintf(buffer + len, "        -----|--------------|-----------|-----------|--------------\n");
        for (i = 0; i <= MAX_LOG_DEV; i++)
-               len += sprintf(buffer + len, "         %2X  |    %3d       |  %8d |  %8d | %8d\n", i, ldn_access_load(host_index, i), IBM_DS(host_index).ldn_read_access[i], IBM_DS(host_index).ldn_write_access[i], IBM_DS(host_index).ldn_assignments[i]);
+               len += sprintf(buffer + len, "         %2X  |    %3d       |  %8d |  %8d | %8d\n", i, ldn_access_load(shpnt, i), IBM_DS(shpnt).ldn_read_access[i], IBM_DS(shpnt).ldn_write_access[i], IBM_DS(shpnt).ldn_assignments[i]);
        len += sprintf(buffer + len, "        -----------------------------------------------------------\n\n");
        len += sprintf(buffer + len, " Dynamical-LDN-Assignment-Statistics:\n");
-       len += sprintf(buffer + len, "               Number of physical SCSI-devices..: %d (+ Adapter)\n", IBM_DS(host_index).total_scsi_devices);
-       len += sprintf(buffer + len, "               Dynamical Assignment necessary...: %s\n", IBM_DS(host_index).dyn_flag ? "Yes" : "No ");
-       len += sprintf(buffer + len, "               Next LDN to be assigned..........: 0x%x\n", next_ldn(host_index));
-       len += sprintf(buffer + len, "               Dynamical assignments done yet...: %d\n", IBM_DS(host_index).dynamical_assignments);
+       len += sprintf(buffer + len, "               Number of physical SCSI-devices..: %d (+ Adapter)\n", IBM_DS(shpnt).total_scsi_devices);
+       len += sprintf(buffer + len, "               Dynamical Assignment necessary...: %s\n", IBM_DS(shpnt).dyn_flag ? "Yes" : "No ");
+       len += sprintf(buffer + len, "               Next LDN to be assigned..........: 0x%x\n", next_ldn(shpnt));
+       len += sprintf(buffer + len, "               Dynamical assignments done yet...: %d\n", IBM_DS(shpnt).dynamical_assignments);
        len += sprintf(buffer + len, "\n Current SCSI-Device-Mapping:\n");
        len += sprintf(buffer + len, "        Physical SCSI-Device Map               Logical SCSI-Device Map\n");
        len += sprintf(buffer + len, "    ID\\LUN  0  1  2  3  4  5  6  7       ID\\LUN  0  1  2  3  4  5  6  7\n");
        for (id = 0; id < max_pun; id++) {
                len += sprintf(buffer + len, "    %2d     ", id);
                for (lun = 0; lun < 8; lun++)
-                       len += sprintf(buffer + len, "%2s ", ti_p(get_scsi(host_index)[id][lun]));
+                       len += sprintf(buffer + len, "%2s ", ti_p(get_scsi(shpnt)[id][lun]));
                len += sprintf(buffer + len, "      %2d     ", id);
                for (lun = 0; lun < 8; lun++)
-                       len += sprintf(buffer + len, "%2s ", ti_l(get_ldn(host_index)[id][lun]));
+                       len += sprintf(buffer + len, "%2s ", ti_l(get_ldn(shpnt)[id][lun]));
                len += sprintf(buffer + len, "\n");
        }
 
@@ -2488,20 +2354,31 @@ static int option_setup(char *str)
 
 __setup("ibmmcascsi=", option_setup);
 
-static struct scsi_host_template driver_template = {
-          .proc_name      = "ibmmca",
-         .proc_info      = ibmmca_proc_info,
-          .name           = "IBM SCSI-Subsystem",
-          .detect         = ibmmca_detect,
-          .release        = ibmmca_release,
-          .queuecommand   = ibmmca_queuecommand,
-         .eh_abort_handler = ibmmca_abort,
-         .eh_host_reset_handler = ibmmca_host_reset,
-          .bios_param     = ibmmca_biosparam,
-          .can_queue      = 16,
-          .this_id        = 7,
-          .sg_tablesize   = 16,
-          .cmd_per_lun    = 1,
-          .use_clustering = ENABLE_CLUSTERING,
+static struct mca_driver ibmmca_driver = {
+       .id_table = ibmmca_id_table,
+       .driver = {
+               .name   = "ibmmca",
+               .bus    = &mca_bus_type,
+               .probe  = ibmmca_probe,
+               .remove = __devexit_p(ibmmca_remove),
+       },
 };
-#include "scsi_module.c"
+
+static int __init ibmmca_init(void)
+{
+#ifdef MODULE
+       /* If the driver is run as module, read from conf.modules or cmd-line */
+       if (boot_options)
+               option_setup(boot_options);
+#endif
+
+       return mca_register_driver_integrated(&ibmmca_driver, MCA_INTEGSCSI);
+}
+
+static void __exit ibmmca_exit(void)
+{
+       mca_unregister_driver(&ibmmca_driver);
+}
+
+module_init(ibmmca_init);
+module_exit(ibmmca_exit);
diff --git a/drivers/scsi/ibmmca.h b/drivers/scsi/ibmmca.h
deleted file mode 100644 (file)
index 017ee2f..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Low Level Driver for the IBM Microchannel SCSI Subsystem
- * (Headerfile, see Documentation/scsi/ibmmca.txt for description of the
- * IBM MCA SCSI-driver.
- * For use under the GNU General Public License within the Linux-kernel project.
- * This include file works only correctly with kernel 2.4.0 or higher!!! */
-
-#ifndef _IBMMCA_H
-#define _IBMMCA_H
-
-/* Common forward declarations for all Linux-versions: */
-
-/* Interfaces to the midlevel Linux SCSI driver */
-static int ibmmca_detect (struct scsi_host_template *);
-static int ibmmca_release (struct Scsi_Host *);
-static int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
-static int ibmmca_abort (Scsi_Cmnd *);
-static int ibmmca_host_reset (Scsi_Cmnd *);
-static int ibmmca_biosparam (struct scsi_device *, struct block_device *, sector_t, int *);
-
-#endif /* _IBMMCA_H */
index b10eefe..b580af9 100644 (file)
@@ -1375,6 +1375,23 @@ static int ibmvscsi_slave_configure(struct scsi_device *sdev)
        return 0;
 }
 
+/**
+ * ibmvscsi_change_queue_depth - Change the device's queue depth
+ * @sdev:      scsi device struct
+ * @qdepth:    depth to set
+ *
+ * Return value:
+ *     actual depth set
+ **/
+static int ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth)
+{
+       if (qdepth > IBMVSCSI_MAX_CMDS_PER_LUN)
+               qdepth = IBMVSCSI_MAX_CMDS_PER_LUN;
+
+       scsi_adjust_queue_depth(sdev, 0, qdepth);
+       return sdev->queue_depth;
+}
+
 /* ------------------------------------------------------------
  * sysfs attributes
  */
@@ -1521,6 +1538,7 @@ static struct scsi_host_template driver_template = {
        .eh_abort_handler = ibmvscsi_eh_abort_handler,
        .eh_device_reset_handler = ibmvscsi_eh_device_reset_handler,
        .slave_configure = ibmvscsi_slave_configure,
+       .change_queue_depth = ibmvscsi_change_queue_depth,
        .cmd_per_lun = 16,
        .can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT,
        .this_id = -1,
index 77cc1d4..727ca7c 100644 (file)
@@ -45,6 +45,7 @@ struct Scsi_Host;
 #define MAX_INDIRECT_BUFS 10
 
 #define IBMVSCSI_MAX_REQUESTS_DEFAULT 100
+#define IBMVSCSI_MAX_CMDS_PER_LUN 64
 
 /* ------------------------------------------------------------
  * Data Structures
index 7e7635c..d9dfb69 100644 (file)
@@ -3,7 +3,8 @@
  *
  * Copyright (c) 1994-1998 Initio Corporation
  * Copyright (c) 1998 Bas Vermeulen <bvermeul@blackstar.xs4all.nl>
- * All rights reserved.
+ * Copyright (c) 2004 Christoph Hellwig <hch@lst.de>
+ * Copyright (c) 2007 Red Hat <alan@redhat.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * along with this program; see the file COPYING.  If not, write to
  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * --------------------------------------------------------------------------
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification, immediately at the beginning of the file.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * Where this Software is combined with software released under the terms of 
- * the GNU General Public License ("GPL") and the terms of the GPL would require the 
- * combined work to also be released under the terms of the GPL, the terms
- * and conditions of this License will apply in addition to those of the
- * GPL with the exception of any terms or conditions of this License that
- * conflict with, or are expressly prohibited by, the GPL.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
  *
  *************************************************************************
  *
  *             - Fix memory allocation problem
  * 03/04/98 hc - v1.01l
  *             - Fix tape rewind which will hang the system problem
- *             - Set can_queue to tul_num_scb
+ *             - Set can_queue to initio_num_scb
  * 06/25/98 hc - v1.01m
  *             - Get it work for kernel version >= 2.1.75
- *             - Dynamic assign SCSI bus reset holding time in init_tulip()
+ *             - Dynamic assign SCSI bus reset holding time in initio_init()
  * 07/02/98 hc - v1.01n
  *             - Support 0002134A
  * 08/07/98 hc  - v1.01o
- *             - Change the tul_abort_srb routine to use scsi_done. <01>
+ *             - Change the initio_abort_srb routine to use scsi_done. <01>
  * 09/07/98 hl  - v1.02
  *              - Change the INI9100U define and proc_dir_entry to
  *                reflect the newer Kernel 2.1.118, but the v1.o1o
 static unsigned int i91u_debug = DEBUG_DEFAULT;
 #endif
 
-#define TUL_RDWORD(x,y)         (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) ))
-
-typedef struct PCI_ID_Struc {
-       unsigned short vendor_id;
-       unsigned short device_id;
-} PCI_ID;
-
-static int tul_num_ch = 4;     /* Maximum 4 adapters           */
-static int tul_num_scb;
-static int tul_tag_enable = 1;
-static SCB *tul_scb;
+static int initio_tag_enable = 1;
 
 #ifdef DEBUG_i91u
 static int setup_debug = 0;
 #endif
 
-static void i91uSCBPost(BYTE * pHcb, BYTE * pScb);
+static void i91uSCBPost(u8 * pHcb, u8 * pScb);
 
 /* PCI Devices supported by this driver */
 static struct pci_device_id i91u_pci_devices[] = {
@@ -184,74 +143,66 @@ MODULE_DEVICE_TABLE(pci, i91u_pci_devices);
 #define DEBUG_STATE     0
 #define INT_DISC       0
 
-/*--- external functions --*/
-static void tul_se2_wait(void);
-
-/*--- forward refrence ---*/
-static SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun);
-static SCB *tul_find_done_scb(HCS * pCurHcb);
-
-static int tulip_main(HCS * pCurHcb);
-
-static int tul_next_state(HCS * pCurHcb);
-static int tul_state_1(HCS * pCurHcb);
-static int tul_state_2(HCS * pCurHcb);
-static int tul_state_3(HCS * pCurHcb);
-static int tul_state_4(HCS * pCurHcb);
-static int tul_state_5(HCS * pCurHcb);
-static int tul_state_6(HCS * pCurHcb);
-static int tul_state_7(HCS * pCurHcb);
-static int tul_xfer_data_in(HCS * pCurHcb);
-static int tul_xfer_data_out(HCS * pCurHcb);
-static int tul_xpad_in(HCS * pCurHcb);
-static int tul_xpad_out(HCS * pCurHcb);
-static int tul_status_msg(HCS * pCurHcb);
-
-static int tul_msgin(HCS * pCurHcb);
-static int tul_msgin_sync(HCS * pCurHcb);
-static int tul_msgin_accept(HCS * pCurHcb);
-static int tul_msgout_reject(HCS * pCurHcb);
-static int tul_msgin_extend(HCS * pCurHcb);
-
-static int tul_msgout_ide(HCS * pCurHcb);
-static int tul_msgout_abort_targ(HCS * pCurHcb);
-static int tul_msgout_abort_tag(HCS * pCurHcb);
-
-static int tul_bus_device_reset(HCS * pCurHcb);
-static void tul_select_atn(HCS * pCurHcb, SCB * pCurScb);
-static void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb);
-static void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb);
-static int int_tul_busfree(HCS * pCurHcb);
-static int int_tul_scsi_rst(HCS * pCurHcb);
-static int int_tul_bad_seq(HCS * pCurHcb);
-static int int_tul_resel(HCS * pCurHcb);
-static int tul_sync_done(HCS * pCurHcb);
-static int wdtr_done(HCS * pCurHcb);
-static int wait_tulip(HCS * pCurHcb);
-static int tul_wait_done_disc(HCS * pCurHcb);
-static int tul_wait_disc(HCS * pCurHcb);
-static void tulip_scsi(HCS * pCurHcb);
-static int tul_post_scsi_rst(HCS * pCurHcb);
-
-static void tul_se2_ew_en(WORD CurBase);
-static void tul_se2_ew_ds(WORD CurBase);
-static int tul_se2_rd_all(WORD CurBase);
-static void tul_se2_update_all(WORD CurBase);  /* setup default pattern */
-static void tul_read_eeprom(WORD CurBase);
-
-                               /* ---- INTERNAL VARIABLES ---- */
-static HCS tul_hcs[MAX_SUPPORTED_ADAPTERS];
-static INI_ADPT_STRUCT i91u_adpt[MAX_SUPPORTED_ADAPTERS];
-
-/*NVRAM nvram, *nvramp = &nvram; */
+/*--- forward references ---*/
+static struct scsi_ctrl_blk *initio_find_busy_scb(struct initio_host * host, u16 tarlun);
+static struct scsi_ctrl_blk *initio_find_done_scb(struct initio_host * host);
+
+static int tulip_main(struct initio_host * host);
+
+static int initio_next_state(struct initio_host * host);
+static int initio_state_1(struct initio_host * host);
+static int initio_state_2(struct initio_host * host);
+static int initio_state_3(struct initio_host * host);
+static int initio_state_4(struct initio_host * host);
+static int initio_state_5(struct initio_host * host);
+static int initio_state_6(struct initio_host * host);
+static int initio_state_7(struct initio_host * host);
+static int initio_xfer_data_in(struct initio_host * host);
+static int initio_xfer_data_out(struct initio_host * host);
+static int initio_xpad_in(struct initio_host * host);
+static int initio_xpad_out(struct initio_host * host);
+static int initio_status_msg(struct initio_host * host);
+
+static int initio_msgin(struct initio_host * host);
+static int initio_msgin_sync(struct initio_host * host);
+static int initio_msgin_accept(struct initio_host * host);
+static int initio_msgout_reject(struct initio_host * host);
+static int initio_msgin_extend(struct initio_host * host);
+
+static int initio_msgout_ide(struct initio_host * host);
+static int initio_msgout_abort_targ(struct initio_host * host);
+static int initio_msgout_abort_tag(struct initio_host * host);
+
+static int initio_bus_device_reset(struct initio_host * host);
+static void initio_select_atn(struct initio_host * host, struct scsi_ctrl_blk * scb);
+static void initio_select_atn3(struct initio_host * host, struct scsi_ctrl_blk * scb);
+static void initio_select_atn_stop(struct initio_host * host, struct scsi_ctrl_blk * scb);
+static int int_initio_busfree(struct initio_host * host);
+static int int_initio_scsi_rst(struct initio_host * host);
+static int int_initio_bad_seq(struct initio_host * host);
+static int int_initio_resel(struct initio_host * host);
+static int initio_sync_done(struct initio_host * host);
+static int wdtr_done(struct initio_host * host);
+static int wait_tulip(struct initio_host * host);
+static int initio_wait_done_disc(struct initio_host * host);
+static int initio_wait_disc(struct initio_host * host);
+static void tulip_scsi(struct initio_host * host);
+static int initio_post_scsi_rst(struct initio_host * host);
+
+static void initio_se2_ew_en(unsigned long base);
+static void initio_se2_ew_ds(unsigned long base);
+static int initio_se2_rd_all(unsigned long base);
+static void initio_se2_update_all(unsigned long base); /* setup default pattern */
+static void initio_read_eeprom(unsigned long base);
+
+/* ---- INTERNAL VARIABLES ---- */
+
 static NVRAM i91unvram;
 static NVRAM *i91unvramp;
 
-
-
-static UCHAR i91udftNvRam[64] =
+static u8 i91udftNvRam[64] =
 {
-/*----------- header -----------*/
+       /*----------- header -----------*/
        0x25, 0xc9,             /* Signature    */
        0x40,                   /* Size         */
        0x01,                   /* Revision     */
@@ -289,7 +240,7 @@ static UCHAR i91udftNvRam[64] =
        0, 0};                  /*      - CheckSum -            */
 
 
-static UCHAR tul_rate_tbl[8] = /* fast 20      */
+static u8 initio_rate_tbl[8] = /* fast 20      */
 {
                                /* nanosecond devide by 4 */
        12,                     /* 50ns,  20M   */
@@ -302,53 +253,17 @@ static UCHAR tul_rate_tbl[8] =    /* fast 20      */
        62                      /* 250ns, 4M    */
 };
 
-static void tul_do_pause(unsigned amount)
-{                              /* Pause for amount jiffies */
+static void initio_do_pause(unsigned amount)
+{
+       /* Pause for amount jiffies */
        unsigned long the_time = jiffies + amount;
 
-       while (time_before_eq(jiffies, the_time));
+       while (time_before_eq(jiffies, the_time))
+               cpu_relax();
 }
 
 /*-- forward reference --*/
 
-/*******************************************************************
-       Use memeory refresh time        ~ 15us * 2
-********************************************************************/
-void tul_se2_wait(void)
-{
-#if 1
-       udelay(30);
-#else
-       UCHAR readByte;
-
-       readByte = TUL_RD(0, 0x61);
-       if ((readByte & 0x10) == 0x10) {
-               for (;;) {
-                       readByte = TUL_RD(0, 0x61);
-                       if ((readByte & 0x10) == 0x10)
-                               break;
-               }
-               for (;;) {
-                       readByte = TUL_RD(0, 0x61);
-                       if ((readByte & 0x10) != 0x10)
-                               break;
-               }
-       } else {
-               for (;;) {
-                       readByte = TUL_RD(0, 0x61);
-                       if ((readByte & 0x10) == 0x10)
-                               break;
-               }
-               for (;;) {
-                       readByte = TUL_RD(0, 0x61);
-                       if ((readByte & 0x10) != 0x10)
-                               break;
-               }
-       }
-#endif
-}
-
-
 /******************************************************************
  Input: instruction for  Serial E2PROM
 
@@ -379,1174 +294,1019 @@ void tul_se2_wait(void)
 
 
 ******************************************************************/
-static void tul_se2_instr(WORD CurBase, UCHAR instr)
+
+/**
+ *     initio_se2_instr        -       bitbang an instruction
+ *     @base: Base of InitIO controller
+ *     @instr: Instruction for serial E2PROM
+ *
+ *     Bitbang an instruction out to the serial E2Prom
+ */
+
+static void initio_se2_instr(unsigned long base, u8 instr)
 {
        int i;
-       UCHAR b;
+       u8 b;
 
-       TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2DO);     /* cs+start bit */
-       tul_se2_wait();
-       TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK | SE2DO);    /* +CLK */
-       tul_se2_wait();
+       outb(SE2CS | SE2DO, base + TUL_NVRAM);          /* cs+start bit */
+       udelay(30);
+       outb(SE2CS | SE2CLK | SE2DO, base + TUL_NVRAM); /* +CLK */
+       udelay(30);
 
        for (i = 0; i < 8; i++) {
                if (instr & 0x80)
-                       b = SE2CS | SE2DO;      /* -CLK+dataBit */
+                       b = SE2CS | SE2DO;              /* -CLK+dataBit */
                else
-                       b = SE2CS;      /* -CLK */
-               TUL_WR(CurBase + TUL_NVRAM, b);
-               tul_se2_wait();
-               TUL_WR(CurBase + TUL_NVRAM, b | SE2CLK);        /* +CLK */
-               tul_se2_wait();
+                       b = SE2CS;                      /* -CLK */
+               outb(b, base + TUL_NVRAM);
+               udelay(30);
+               outb(b | SE2CLK, base + TUL_NVRAM);     /* +CLK */
+               udelay(30);
                instr <<= 1;
        }
-       TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK */
-       tul_se2_wait();
-       return;
+       outb(SE2CS, base + TUL_NVRAM);                  /* -CLK */
+       udelay(30);
 }
 
 
-/******************************************************************
- Function name  : tul_se2_ew_en
- Description    : Enable erase/write state of serial EEPROM
-******************************************************************/
-void tul_se2_ew_en(WORD CurBase)
+/**
+ *     initio_se2_ew_en        -       Enable erase/write
+ *     @base: Base address of InitIO controller
+ *
+ *     Enable erase/write state of serial EEPROM
+ */
+void initio_se2_ew_en(unsigned long base)
 {
-       tul_se2_instr(CurBase, 0x30);   /* EWEN */
-       TUL_WR(CurBase + TUL_NVRAM, 0);         /* -CS  */
-       tul_se2_wait();
-       return;
+       initio_se2_instr(base, 0x30);   /* EWEN */
+       outb(0, base + TUL_NVRAM);      /* -CS  */
+       udelay(30);
 }
 
 
-/************************************************************************
- Disable erase/write state of serial EEPROM
-*************************************************************************/
-void tul_se2_ew_ds(WORD CurBase)
+/**
+ *     initio_se2_ew_ds        -       Disable erase/write
+ *     @base: Base address of InitIO controller
+ *
+ *     Disable erase/write state of serial EEPROM
+ */
+void initio_se2_ew_ds(unsigned long base)
 {
-       tul_se2_instr(CurBase, 0);      /* EWDS */
-       TUL_WR(CurBase + TUL_NVRAM, 0);         /* -CS  */
-       tul_se2_wait();
-       return;
+       initio_se2_instr(base, 0);      /* EWDS */
+       outb(0, base + TUL_NVRAM);      /* -CS  */
+       udelay(30);
 }
 
 
-/******************************************************************
-       Input  :address of Serial E2PROM
-       Output :value stored in  Serial E2PROM
-*******************************************************************/
-static USHORT tul_se2_rd(WORD CurBase, ULONG adr)
+/**
+ *     initio_se2_rd           -       read E2PROM word
+ *     @base: Base of InitIO controller
+ *     @addr: Address of word in E2PROM
+ *
+ *     Read a word from the NV E2PROM device
+ */
+static u16 initio_se2_rd(unsigned long base, u8 addr)
 {
-       UCHAR instr, readByte;
-       USHORT readWord;
+       u8 instr, rb;
+       u16 val = 0;
        int i;
 
-       instr = (UCHAR) (adr | 0x80);
-       tul_se2_instr(CurBase, instr);  /* READ INSTR */
-       readWord = 0;
+       instr = (u8) (addr | 0x80);
+       initio_se2_instr(base, instr);  /* READ INSTR */
 
        for (i = 15; i >= 0; i--) {
-               TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK);    /* +CLK */
-               tul_se2_wait();
-               TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK */
+               outb(SE2CS | SE2CLK, base + TUL_NVRAM); /* +CLK */
+               udelay(30);
+               outb(SE2CS, base + TUL_NVRAM);          /* -CLK */
 
                /* sample data after the following edge of clock  */
-               readByte = TUL_RD(CurBase, TUL_NVRAM);
-               readByte &= SE2DI;
-               readWord += (readByte << i);
-               tul_se2_wait(); /* 6/20/95 */
+               rb = inb(base + TUL_NVRAM);
+               rb &= SE2DI;
+               val += (rb << i);
+               udelay(30);     /* 6/20/95 */
        }
 
-       TUL_WR(CurBase + TUL_NVRAM, 0);         /* no chip select */
-       tul_se2_wait();
-       return readWord;
+       outb(0, base + TUL_NVRAM);              /* no chip select */
+       udelay(30);
+       return val;
 }
 
-
-/******************************************************************
- Input: new value in  Serial E2PROM, address of Serial E2PROM
-*******************************************************************/
-static void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord)
+/**
+ *     initio_se2_wr           -       read E2PROM word
+ *     @base: Base of InitIO controller
+ *     @addr: Address of word in E2PROM
+ *     @val: Value to write
+ *
+ *     Write a word to the NV E2PROM device. Used when recovering from
+ *     a problem with the NV.
+ */
+static void initio_se2_wr(unsigned long base, u8 addr, u16 val)
 {
-       UCHAR readByte;
-       UCHAR instr;
+       u8 rb;
+       u8 instr;
        int i;
 
-       instr = (UCHAR) (adr | 0x40);
-       tul_se2_instr(CurBase, instr);  /* WRITE INSTR */
+       instr = (u8) (addr | 0x40);
+       initio_se2_instr(base, instr);  /* WRITE INSTR */
        for (i = 15; i >= 0; i--) {
-               if (writeWord & 0x8000)
-                       TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2DO);     /* -CLK+dataBit 1 */
+               if (val & 0x8000)
+                       outb(SE2CS | SE2DO, base + TUL_NVRAM);  /* -CLK+dataBit 1 */
                else
-                       TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK+dataBit 0 */
-               tul_se2_wait();
-               TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK);    /* +CLK */
-               tul_se2_wait();
-               writeWord <<= 1;
+                       outb(SE2CS, base + TUL_NVRAM);          /* -CLK+dataBit 0 */
+               udelay(30);
+               outb(SE2CS | SE2CLK, base + TUL_NVRAM);         /* +CLK */
+               udelay(30);
+               val <<= 1;
        }
-       TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK */
-       tul_se2_wait();
-       TUL_WR(CurBase + TUL_NVRAM, 0);         /* -CS  */
-       tul_se2_wait();
+       outb(SE2CS, base + TUL_NVRAM);                          /* -CLK */
+       udelay(30);
+       outb(0, base + TUL_NVRAM);                              /* -CS  */
+       udelay(30);
 
-       TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* +CS  */
-       tul_se2_wait();
+       outb(SE2CS, base + TUL_NVRAM);                          /* +CS  */
+       udelay(30);
 
        for (;;) {
-               TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK);    /* +CLK */
-               tul_se2_wait();
-               TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK */
-               tul_se2_wait();
-               if ((readByte = TUL_RD(CurBase, TUL_NVRAM)) & SE2DI)
+               outb(SE2CS | SE2CLK, base + TUL_NVRAM);         /* +CLK */
+               udelay(30);
+               outb(SE2CS, base + TUL_NVRAM);                  /* -CLK */
+               udelay(30);
+               if ((rb = inb(base + TUL_NVRAM)) & SE2DI)
                        break;  /* write complete */
        }
-       TUL_WR(CurBase + TUL_NVRAM, 0);         /* -CS */
-       return;
+       outb(0, base + TUL_NVRAM);                              /* -CS */
 }
 
+/**
+ *     initio_se2_rd_all       -       read hostadapter NV configuration
+ *     @base: Base address of InitIO controller
+ *
+ *     Reads the E2PROM data into main memory. Ensures that the checksum
+ *     and header marker are valid. Returns 1 on success -1 on error.
+ */
 
-/***********************************************************************
- Read SCSI H/A configuration parameters from serial EEPROM
-************************************************************************/
-int tul_se2_rd_all(WORD CurBase)
+static int initio_se2_rd_all(unsigned long base)
 {
        int i;
-       ULONG chksum = 0;
-       USHORT *np;
+       u16 chksum = 0;
+       u16 *np;
 
        i91unvramp = &i91unvram;
-       np = (USHORT *) i91unvramp;
-       for (i = 0; i < 32; i++) {
-               *np++ = tul_se2_rd(CurBase, i);
-       }
+       np = (u16 *) i91unvramp;
+       for (i = 0; i < 32; i++)
+               *np++ = initio_se2_rd(base, i);
 
-/*--------------------Is signature "ini" ok ? ----------------*/
+       /* Is signature "ini" ok ? */
        if (i91unvramp->NVM_Signature != INI_SIGNATURE)
                return -1;
-/*---------------------- Is ckecksum ok ? ----------------------*/
-       np = (USHORT *) i91unvramp;
+       /* Is ckecksum ok ? */
+       np = (u16 *) i91unvramp;
        for (i = 0; i < 31; i++)
                chksum += *np++;
-       if (i91unvramp->NVM_CheckSum != (USHORT) chksum)
+       if (i91unvramp->NVM_CheckSum != chksum)
                return -1;
        return 1;
 }
 
-
-/***********************************************************************
- Update SCSI H/A configuration parameters from serial EEPROM
-************************************************************************/
-void tul_se2_update_all(WORD CurBase)
+/**
+ *     initio_se2_update_all           -       Update E2PROM
+ *     @base: Base of InitIO controller
+ *
+ *     Update the E2PROM by wrting any changes into the E2PROM
+ *     chip, rewriting the checksum.
+ */
+static void initio_se2_update_all(unsigned long base)
 {                              /* setup default pattern */
        int i;
-       ULONG chksum = 0;
-       USHORT *np, *np1;
+       u16 chksum = 0;
+       u16 *np, *np1;
 
        i91unvramp = &i91unvram;
        /* Calculate checksum first */
-       np = (USHORT *) i91udftNvRam;
+       np = (u16 *) i91udftNvRam;
        for (i = 0; i < 31; i++)
                chksum += *np++;
-       *np = (USHORT) chksum;
-       tul_se2_ew_en(CurBase); /* Enable write  */
+       *np = chksum;
+       initio_se2_ew_en(base); /* Enable write  */
 
-       np = (USHORT *) i91udftNvRam;
-       np1 = (USHORT *) i91unvramp;
+       np = (u16 *) i91udftNvRam;
+       np1 = (u16 *) i91unvramp;
        for (i = 0; i < 32; i++, np++, np1++) {
-               if (*np != *np1) {
-                       tul_se2_wr(CurBase, i, *np);
-               }
+               if (*np != *np1)
+                       initio_se2_wr(base, i, *np);
        }
-
-       tul_se2_ew_ds(CurBase); /* Disable write   */
-       return;
+       initio_se2_ew_ds(base); /* Disable write   */
 }
 
-/*************************************************************************
- Function name  : read_eeprom
-**************************************************************************/
-void tul_read_eeprom(WORD CurBase)
-{
-       UCHAR gctrl;
-
-       i91unvramp = &i91unvram;
-/*------Enable EEProm programming ---*/
-       gctrl = TUL_RD(CurBase, TUL_GCTRL);
-       TUL_WR(CurBase + TUL_GCTRL, gctrl | TUL_GCTRL_EEPROM_BIT);
-       if (tul_se2_rd_all(CurBase) != 1) {
-               tul_se2_update_all(CurBase);    /* setup default pattern */
-               tul_se2_rd_all(CurBase);        /* load again  */
-       }
-/*------ Disable EEProm programming ---*/
-       gctrl = TUL_RD(CurBase, TUL_GCTRL);
-       TUL_WR(CurBase + TUL_GCTRL, gctrl & ~TUL_GCTRL_EEPROM_BIT);
-}                              /* read_eeprom */
+/**
+ *     initio_read_eeprom              -       Retrieve configuration
+ *     @base: Base of InitIO Host Adapter
+ *
+ *     Retrieve the host adapter configuration data from E2Prom. If the
+ *     data is invalid then the defaults are used and are also restored
+ *     into the E2PROM. This forms the access point for the SCSI driver
+ *     into the E2PROM layer, the other functions for the E2PROM are all
+ *     internal use.
+ *
+ *     Must be called single threaded, uses a shared global area.
+ */
 
-static int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
-                                     BYTE bBus, BYTE bDevice)
+static void initio_read_eeprom(unsigned long base)
 {
-       int i, j;
+       u8 gctrl;
 
-       for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) {
-               if (i91u_adpt[i].ADPT_BIOS < wBIOS)
-                       continue;
-               if (i91u_adpt[i].ADPT_BIOS == wBIOS) {
-                       if (i91u_adpt[i].ADPT_BASE == wBASE) {
-                               if (i91u_adpt[i].ADPT_Bus != 0xFF)
-                                       return 1;
-                       } else if (i91u_adpt[i].ADPT_BASE < wBASE)
-                                       continue;
-               }
-               for (j = MAX_SUPPORTED_ADAPTERS - 1; j > i; j--) {
-                       i91u_adpt[j].ADPT_BASE = i91u_adpt[j - 1].ADPT_BASE;
-                       i91u_adpt[j].ADPT_INTR = i91u_adpt[j - 1].ADPT_INTR;
-                       i91u_adpt[j].ADPT_BIOS = i91u_adpt[j - 1].ADPT_BIOS;
-                       i91u_adpt[j].ADPT_Bus = i91u_adpt[j - 1].ADPT_Bus;
-                       i91u_adpt[j].ADPT_Device = i91u_adpt[j - 1].ADPT_Device;
-               }
-               i91u_adpt[i].ADPT_BASE = wBASE;
-               i91u_adpt[i].ADPT_INTR = bInterrupt;
-               i91u_adpt[i].ADPT_BIOS = wBIOS;
-               i91u_adpt[i].ADPT_Bus = bBus;
-               i91u_adpt[i].ADPT_Device = bDevice;
-               return 0;
+       i91unvramp = &i91unvram;
+       /* Enable EEProm programming */
+       gctrl = inb(base + TUL_GCTRL);
+       outb(gctrl | TUL_GCTRL_EEPROM_BIT, base + TUL_GCTRL);
+       if (initio_se2_rd_all(base) != 1) {
+               initio_se2_update_all(base);    /* setup default pattern */
+               initio_se2_rd_all(base);        /* load again  */
        }
-       return 1;
+       /* Disable EEProm programming */
+       gctrl = inb(base + TUL_GCTRL);
+       outb(gctrl & ~TUL_GCTRL_EEPROM_BIT, base + TUL_GCTRL);
 }
 
-static void init_i91uAdapter_table(void)
-{
-       int i;
-
-       for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) {  /* Initialize adapter structure */
-               i91u_adpt[i].ADPT_BIOS = 0xffff;
-               i91u_adpt[i].ADPT_BASE = 0xffff;
-               i91u_adpt[i].ADPT_INTR = 0xff;
-               i91u_adpt[i].ADPT_Bus = 0xff;
-               i91u_adpt[i].ADPT_Device = 0xff;
-       }
-       return;
-}
+/**
+ *     initio_stop_bm          -       stop bus master
+ *     @host: InitIO we are stopping
+ *
+ *     Stop any pending DMA operation, aborting the DMA if neccessary
+ */
 
-static void tul_stop_bm(HCS * pCurHcb)
+static void initio_stop_bm(struct initio_host * host)
 {
 
-       if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) {   /* if DMA xfer is pending, abort DMA xfer */
-               TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT | TAX_X_CLR_FIFO);
+       if (inb(host->addr + TUL_XStatus) & XPEND) {    /* if DMA xfer is pending, abort DMA xfer */
+               outb(TAX_X_ABT | TAX_X_CLR_FIFO, host->addr + TUL_XCmd);
                /* wait Abort DMA xfer done */
-               while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & XABT) == 0);
+               while ((inb(host->addr + TUL_Int) & XABT) == 0)
+                       cpu_relax();
        }
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
+       outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
 }
 
-/***************************************************************************/
-static void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx)
-{
-       pCurHcb->HCS_Base = i91u_adpt[ch_idx].ADPT_BASE;        /* Supply base address  */
-       pCurHcb->HCS_BIOS = i91u_adpt[ch_idx].ADPT_BIOS;        /* Supply BIOS address  */
-       pCurHcb->HCS_Intr = i91u_adpt[ch_idx].ADPT_INTR;        /* Supply interrupt line */
-       return;
-}
+/**
+ *     initio_reset_scsi               -       Reset SCSI host controller
+ *     @host: InitIO host to reset
+ *     @seconds: Recovery time
+ *
+ *     Perform a full reset of the SCSI subsystem.
+ */
 
-/***************************************************************************/
-static int tul_reset_scsi(HCS * pCurHcb, int seconds)
+static int initio_reset_scsi(struct initio_host * host, int seconds)
 {
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_BUS);
+       outb(TSC_RST_BUS, host->addr + TUL_SCtrl0);
 
-       while (!((pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt)) & TSS_SCSIRST_INT));
-       /* reset tulip chip */
+       while (!((host->jsint = inb(host->addr + TUL_SInt)) & TSS_SCSIRST_INT))
+               cpu_relax();
 
-       TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, 0);
+       /* reset tulip chip */
+       outb(0, host->addr + TUL_SSignal);
 
        /* Stall for a while, wait for target's firmware ready,make it 2 sec ! */
        /* SONY 5200 tape drive won't work if only stall for 1 sec */
-       tul_do_pause(seconds * HZ);
-
-       TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
+       /* FIXME: this is a very long busy wait right now */
+       initio_do_pause(seconds * HZ);
 
-       return (SCSI_RESET_SUCCESS);
+       inb(host->addr + TUL_SInt);
+       return SCSI_RESET_SUCCESS;
 }
 
-/***************************************************************************/
-static int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb,
-                     BYTE * pbBiosAdr, int seconds)
+/**
+ *     initio_init             -       set up an InitIO host adapter
+ *     @host: InitIO host adapter
+ *     @num_scbs: Number of SCBS
+ *     @bios_addr: BIOS address
+ *
+ *     Set up the host adapter and devices according to the configuration
+ *     retrieved from the E2PROM.
+ *
+ *     Locking: Calls E2PROM layer code which is not re-enterable so must
+ *     run single threaded for now.
+ */
+
+static void initio_init(struct initio_host * host, u8 *bios_addr)
 {
        int i;
-       BYTE *pwFlags;
-       BYTE *pbHeads;
-       SCB *pTmpScb, *pPrevScb = NULL;
-
-       pCurHcb->HCS_NumScbs = tul_num_scb;
-       pCurHcb->HCS_Semaph = 1;
-       spin_lock_init(&pCurHcb->HCS_SemaphLock);
-       pCurHcb->HCS_JSStatus0 = 0;
-       pCurHcb->HCS_Scb = scbp;
-       pCurHcb->HCS_NxtPend = scbp;
-       pCurHcb->HCS_NxtAvail = scbp;
-       for (i = 0, pTmpScb = scbp; i < tul_num_scb; i++, pTmpScb++) {
-               pTmpScb->SCB_TagId = i;
-               if (i != 0)
-                       pPrevScb->SCB_NxtScb = pTmpScb;
-               pPrevScb = pTmpScb;
-       }
-       pPrevScb->SCB_NxtScb = NULL;
-       pCurHcb->HCS_ScbEnd = pTmpScb;
-       pCurHcb->HCS_FirstAvail = scbp;
-       pCurHcb->HCS_LastAvail = pPrevScb;
-       spin_lock_init(&pCurHcb->HCS_AvailLock);
-       pCurHcb->HCS_FirstPend = NULL;
-       pCurHcb->HCS_LastPend = NULL;
-       pCurHcb->HCS_FirstBusy = NULL;
-       pCurHcb->HCS_LastBusy = NULL;
-       pCurHcb->HCS_FirstDone = NULL;
-       pCurHcb->HCS_LastDone = NULL;
-       pCurHcb->HCS_ActScb = NULL;
-       pCurHcb->HCS_ActTcs = NULL;
-
-       tul_read_eeprom(pCurHcb->HCS_Base);
-/*---------- get H/A configuration -------------*/
+       u8 *flags;
+       u8 *heads;
+
+       /* Get E2Prom configuration */
+       initio_read_eeprom(host->addr);
        if (i91unvramp->NVM_SCSIInfo[0].NVM_NumOfTarg == 8)
-               pCurHcb->HCS_MaxTar = 8;
+               host->max_tar = 8;
        else
-               pCurHcb->HCS_MaxTar = 16;
+               host->max_tar = 16;
 
-       pCurHcb->HCS_Config = i91unvramp->NVM_SCSIInfo[0].NVM_ChConfig1;
+       host->config = i91unvramp->NVM_SCSIInfo[0].NVM_ChConfig1;
 
-       pCurHcb->HCS_SCSI_ID = i91unvramp->NVM_SCSIInfo[0].NVM_ChSCSIID;
-       pCurHcb->HCS_IdMask = ~(1 << pCurHcb->HCS_SCSI_ID);
+       host->scsi_id = i91unvramp->NVM_SCSIInfo[0].NVM_ChSCSIID;
+       host->idmask = ~(1 << host->scsi_id);
 
 #ifdef CHK_PARITY
        /* Enable parity error response */
-       TUL_WR(pCurHcb->HCS_Base + TUL_PCMD, TUL_RD(pCurHcb->HCS_Base, TUL_PCMD) | 0x40);
+       outb(inb(host->addr + TUL_PCMD) | 0x40, host->addr + TUL_PCMD);
 #endif
 
        /* Mask all the interrupt       */
-       TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
+       outb(0x1F, host->addr + TUL_Mask);
 
-       tul_stop_bm(pCurHcb);
+       initio_stop_bm(host);
        /* --- Initialize the tulip --- */
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_CHIP);
+       outb(TSC_RST_CHIP, host->addr + TUL_SCtrl0);
 
        /* program HBA's SCSI ID        */
-       TUL_WR(pCurHcb->HCS_Base + TUL_SScsiId, pCurHcb->HCS_SCSI_ID << 4);
+       outb(host->scsi_id << 4, host->addr + TUL_SScsiId);
 
        /* Enable Initiator Mode ,phase latch,alternate sync period mode,
           disable SCSI reset */
-       if (pCurHcb->HCS_Config & HCC_EN_PAR)
-               pCurHcb->HCS_SConf1 = (TSC_INITDEFAULT | TSC_EN_SCSI_PAR);
+       if (host->config & HCC_EN_PAR)
+               host->sconf1 = (TSC_INITDEFAULT | TSC_EN_SCSI_PAR);
        else
-               pCurHcb->HCS_SConf1 = (TSC_INITDEFAULT);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_SConf1);
+               host->sconf1 = (TSC_INITDEFAULT);
+       outb(host->sconf1, host->addr + TUL_SConfig);
 
-       /* Enable HW reselect           */
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);
+       /* Enable HW reselect */
+       outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1);
 
-       TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, 0);
+       outb(0, host->addr + TUL_SPeriod);
 
        /* selection time out = 250 ms */
-       TUL_WR(pCurHcb->HCS_Base + TUL_STimeOut, 153);
+       outb(153, host->addr + TUL_STimeOut);
 
-/*--------- Enable SCSI terminator -----*/
-       TUL_WR(pCurHcb->HCS_Base + TUL_XCtrl, (pCurHcb->HCS_Config & (HCC_ACT_TERM1 | HCC_ACT_TERM2)));
-       TUL_WR(pCurHcb->HCS_Base + TUL_GCTRL1,
-              ((pCurHcb->HCS_Config & HCC_AUTO_TERM) >> 4) | (TUL_RD(pCurHcb->HCS_Base, TUL_GCTRL1) & 0xFE));
+       /* Enable SCSI terminator */
+       outb((host->config & (HCC_ACT_TERM1 | HCC_ACT_TERM2)),
+               host->addr + TUL_XCtrl);
+       outb(((host->config & HCC_AUTO_TERM) >> 4) |
+               (inb(host->addr + TUL_GCTRL1) & 0xFE),
+               host->addr + TUL_GCTRL1);
 
        for (i = 0,
-            pwFlags = & (i91unvramp->NVM_SCSIInfo[0].NVM_Targ0Config),
-            pbHeads = pbBiosAdr + 0x180;
-            i < pCurHcb->HCS_MaxTar;
-            i++, pwFlags++) {
-               pCurHcb->HCS_Tcs[i].TCS_Flags = *pwFlags & ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
-               if (pCurHcb->HCS_Tcs[i].TCS_Flags & TCF_EN_255)
-                       pCurHcb->HCS_Tcs[i].TCS_DrvFlags = TCF_DRV_255_63;
+            flags = & (i91unvramp->NVM_SCSIInfo[0].NVM_Targ0Config),
+            heads = bios_addr + 0x180;
+            i < host->max_tar;
+            i++, flags++) {
+               host->targets[i].flags = *flags & ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
+               if (host->targets[i].flags & TCF_EN_255)
+                       host->targets[i].drv_flags = TCF_DRV_255_63;
                else
-                       pCurHcb->HCS_Tcs[i].TCS_DrvFlags = 0;
-               pCurHcb->HCS_Tcs[i].TCS_JS_Period = 0;
-               pCurHcb->HCS_Tcs[i].TCS_SConfig0 = pCurHcb->HCS_SConf1;
-               pCurHcb->HCS_Tcs[i].TCS_DrvHead = *pbHeads++;
-               if (pCurHcb->HCS_Tcs[i].TCS_DrvHead == 255)
-                       pCurHcb->HCS_Tcs[i].TCS_DrvFlags = TCF_DRV_255_63;
+                       host->targets[i].drv_flags = 0;
+               host->targets[i].js_period = 0;
+               host->targets[i].sconfig0 = host->sconf1;
+               host->targets[i].heads = *heads++;
+               if (host->targets[i].heads == 255)
+                       host->targets[i].drv_flags = TCF_DRV_255_63;
                else
-                       pCurHcb->HCS_Tcs[i].TCS_DrvFlags = 0;
-               pCurHcb->HCS_Tcs[i].TCS_DrvSector = *pbHeads++;
-               pCurHcb->HCS_Tcs[i].TCS_Flags &= ~TCF_BUSY;
-               pCurHcb->HCS_ActTags[i] = 0;
-               pCurHcb->HCS_MaxTags[i] = 0xFF;
+                       host->targets[i].drv_flags = 0;
+               host->targets[i].sectors = *heads++;
+               host->targets[i].flags &= ~TCF_BUSY;
+               host->act_tags[i] = 0;
+               host->max_tags[i] = 0xFF;
        }                       /* for                          */
        printk("i91u: PCI Base=0x%04X, IRQ=%d, BIOS=0x%04X0, SCSI ID=%d\n",
-              pCurHcb->HCS_Base, pCurHcb->HCS_Intr,
-              pCurHcb->HCS_BIOS, pCurHcb->HCS_SCSI_ID);
-/*------------------- reset SCSI Bus ---------------------------*/
-       if (pCurHcb->HCS_Config & HCC_SCSI_RESET) {
-               printk("i91u: Reset SCSI Bus ... \n");
-               tul_reset_scsi(pCurHcb, seconds);
+              host->addr, host->irq,
+              host->bios_addr, host->scsi_id);
+       /* Reset SCSI Bus */
+       if (host->config & HCC_SCSI_RESET) {
+               printk(KERN_INFO "i91u: Reset SCSI Bus ... \n");
+               initio_reset_scsi(host, 10);
        }
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCFG1, 0x17);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SIntEnable, 0xE9);
-       return (0);
+       outb(0x17, host->addr + TUL_SCFG1);
+       outb(0xE9, host->addr + TUL_SIntEnable);
 }
 
-/***************************************************************************/
-static SCB *tul_alloc_scb(HCS * hcsp)
+/**
+ *     initio_alloc_scb                -       Allocate an SCB
+ *     @host: InitIO host we are allocating for
+ *
+ *     Walk the SCB list for the controller and allocate a free SCB if
+ *     one exists.
+ */
+static struct scsi_ctrl_blk *initio_alloc_scb(struct initio_host *host)
 {
-       SCB *pTmpScb;
-       ULONG flags;
-       spin_lock_irqsave(&(hcsp->HCS_AvailLock), flags);
-       if ((pTmpScb = hcsp->HCS_FirstAvail) != NULL) {
+       struct scsi_ctrl_blk *scb;
+       unsigned long flags;
+
+       spin_lock_irqsave(&host->avail_lock, flags);
+       if ((scb = host->first_avail) != NULL) {
 #if DEBUG_QUEUE
-               printk("find scb at %08lx\n", (ULONG) pTmpScb);
+               printk("find scb at %p\n", scb);
 #endif
-               if ((hcsp->HCS_FirstAvail = pTmpScb->SCB_NxtScb) == NULL)
-                       hcsp->HCS_LastAvail = NULL;
-               pTmpScb->SCB_NxtScb = NULL;
-               pTmpScb->SCB_Status = SCB_RENT;
+               if ((host->first_avail = scb->next) == NULL)
+                       host->last_avail = NULL;
+               scb->next = NULL;
+               scb->status = SCB_RENT;
        }
-       spin_unlock_irqrestore(&(hcsp->HCS_AvailLock), flags);
-       return (pTmpScb);
+       spin_unlock_irqrestore(&host->avail_lock, flags);
+       return scb;
 }
 
-/***************************************************************************/
-static void tul_release_scb(HCS * hcsp, SCB * scbp)
+/**
+ *     initio_release_scb              -       Release an SCB
+ *     @host: InitIO host that owns the SCB
+ *     @cmnd: SCB command block being returned
+ *
+ *     Return an allocated SCB to the host free list
+ */
+
+static void initio_release_scb(struct initio_host * host, struct scsi_ctrl_blk * cmnd)
 {
-       ULONG flags;
+       unsigned long flags;
 
 #if DEBUG_QUEUE
-       printk("Release SCB %lx; ", (ULONG) scbp);
+       printk("Release SCB %p; ", cmnd);
 #endif
-       spin_lock_irqsave(&(hcsp->HCS_AvailLock), flags);
-       scbp->SCB_Srb = NULL;
-       scbp->SCB_Status = 0;
-       scbp->SCB_NxtScb = NULL;
-       if (hcsp->HCS_LastAvail != NULL) {
-               hcsp->HCS_LastAvail->SCB_NxtScb = scbp;
-               hcsp->HCS_LastAvail = scbp;
+       spin_lock_irqsave(&(host->avail_lock), flags);
+       cmnd->srb = NULL;
+       cmnd->status = 0;
+       cmnd->next = NULL;
+       if (host->last_avail != NULL) {
+               host->last_avail->next = cmnd;
+               host->last_avail = cmnd;
        } else {
-               hcsp->HCS_FirstAvail = scbp;
-               hcsp->HCS_LastAvail = scbp;
+               host->first_avail = cmnd;
+               host->last_avail = cmnd;
        }
-       spin_unlock_irqrestore(&(hcsp->HCS_AvailLock), flags);
+       spin_unlock_irqrestore(&(host->avail_lock), flags);
 }
 
 /***************************************************************************/
-static void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp)
+static void initio_append_pend_scb(struct initio_host * host, struct scsi_ctrl_blk * scbp)
 {
 
 #if DEBUG_QUEUE
-       printk("Append pend SCB %lx; ", (ULONG) scbp);
+       printk("Append pend SCB %p; ", scbp);
 #endif
-       scbp->SCB_Status = SCB_PEND;
-       scbp->SCB_NxtScb = NULL;
-       if (pCurHcb->HCS_LastPend != NULL) {
-               pCurHcb->HCS_LastPend->SCB_NxtScb = scbp;
-               pCurHcb->HCS_LastPend = scbp;
+       scbp->status = SCB_PEND;
+       scbp->next = NULL;
+       if (host->last_pending != NULL) {
+               host->last_pending->next = scbp;
+               host->last_pending = scbp;
        } else {
-               pCurHcb->HCS_FirstPend = scbp;
-               pCurHcb->HCS_LastPend = scbp;
+               host->first_pending = scbp;
+               host->last_pending = scbp;
        }
 }
 
 /***************************************************************************/
-static void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp)
+static void initio_push_pend_scb(struct initio_host * host, struct scsi_ctrl_blk * scbp)
 {
 
 #if DEBUG_QUEUE
-       printk("Push pend SCB %lx; ", (ULONG) scbp);
+       printk("Push pend SCB %p; ", scbp);
 #endif
-       scbp->SCB_Status = SCB_PEND;
-       if ((scbp->SCB_NxtScb = pCurHcb->HCS_FirstPend) != NULL) {
-               pCurHcb->HCS_FirstPend = scbp;
+       scbp->status = SCB_PEND;
+       if ((scbp->next = host->first_pending) != NULL) {
+               host->first_pending = scbp;
        } else {
-               pCurHcb->HCS_FirstPend = scbp;
-               pCurHcb->HCS_LastPend = scbp;
+               host->first_pending = scbp;
+               host->last_pending = scbp;
        }
 }
 
-/***************************************************************************/
-static SCB *tul_find_first_pend_scb(HCS * pCurHcb)
+static struct scsi_ctrl_blk *initio_find_first_pend_scb(struct initio_host * host)
 {
-       SCB *pFirstPend;
+       struct scsi_ctrl_blk *first;
 
 
-       pFirstPend = pCurHcb->HCS_FirstPend;
-       while (pFirstPend != NULL) {
-               if (pFirstPend->SCB_Opcode != ExecSCSI) {
-                       return (pFirstPend);
-               }
-               if (pFirstPend->SCB_TagMsg == 0) {
-                       if ((pCurHcb->HCS_ActTags[pFirstPend->SCB_Target] == 0) &&
-                           !(pCurHcb->HCS_Tcs[pFirstPend->SCB_Target].TCS_Flags & TCF_BUSY)) {
-                               return (pFirstPend);
-                       }
+       first = host->first_pending;
+       while (first != NULL) {
+               if (first->opcode != ExecSCSI)
+                       return first;
+               if (first->tagmsg == 0) {
+                       if ((host->act_tags[first->target] == 0) &&
+                           !(host->targets[first->target].flags & TCF_BUSY))
+                               return first;
                } else {
-                       if ((pCurHcb->HCS_ActTags[pFirstPend->SCB_Target] >=
-                         pCurHcb->HCS_MaxTags[pFirstPend->SCB_Target]) |
-                           (pCurHcb->HCS_Tcs[pFirstPend->SCB_Target].TCS_Flags & TCF_BUSY)) {
-                               pFirstPend = pFirstPend->SCB_NxtScb;
+                       if ((host->act_tags[first->target] >=
+                         host->max_tags[first->target]) |
+                           (host->targets[first->target].flags & TCF_BUSY)) {
+                               first = first->next;
                                continue;
                        }
-                       return (pFirstPend);
+                       return first;
                }
-               pFirstPend = pFirstPend->SCB_NxtScb;
+               first = first->next;
        }
-
-
-       return (pFirstPend);
+       return first;
 }
-/***************************************************************************/
-static void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb)
+
+static void initio_unlink_pend_scb(struct initio_host * host, struct scsi_ctrl_blk * scb)
 {
-       SCB *pTmpScb, *pPrevScb;
+       struct scsi_ctrl_blk *tmp, *prev;
 
 #if DEBUG_QUEUE
-       printk("unlink pend SCB %lx; ", (ULONG) pCurScb);
+       printk("unlink pend SCB %p; ", scb);
 #endif
 
-       pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend;
-       while (pTmpScb != NULL) {
-               if (pCurScb == pTmpScb) {       /* Unlink this SCB              */
-                       if (pTmpScb == pCurHcb->HCS_FirstPend) {
-                               if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL)
-                                       pCurHcb->HCS_LastPend = NULL;
+       prev = tmp = host->first_pending;
+       while (tmp != NULL) {
+               if (scb == tmp) {       /* Unlink this SCB              */
+                       if (tmp == host->first_pending) {
+                               if ((host->first_pending = tmp->next) == NULL)
+                                       host->last_pending = NULL;
                        } else {
-                               pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
-                               if (pTmpScb == pCurHcb->HCS_LastPend)
-                                       pCurHcb->HCS_LastPend = pPrevScb;
+                               prev->next = tmp->next;
+                               if (tmp == host->last_pending)
+                                       host->last_pending = prev;
                        }
-                       pTmpScb->SCB_NxtScb = NULL;
+                       tmp->next = NULL;
                        break;
                }
-               pPrevScb = pTmpScb;
-               pTmpScb = pTmpScb->SCB_NxtScb;
+               prev = tmp;
+               tmp = tmp->next;
        }
-       return;
 }
-/***************************************************************************/
-static void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp)
+
+static void initio_append_busy_scb(struct initio_host * host, struct scsi_ctrl_blk * scbp)
 {
 
 #if DEBUG_QUEUE
-       printk("append busy SCB %lx; ", (ULONG) scbp);
+       printk("append busy SCB %o; ", scbp);
 #endif
-       if (scbp->SCB_TagMsg)
-               pCurHcb->HCS_ActTags[scbp->SCB_Target]++;
+       if (scbp->tagmsg)
+               host->act_tags[scbp->target]++;
        else
-               pCurHcb->HCS_Tcs[scbp->SCB_Target].TCS_Flags |= TCF_BUSY;
-       scbp->SCB_Status = SCB_BUSY;
-       scbp->SCB_NxtScb = NULL;
-       if (pCurHcb->HCS_LastBusy != NULL) {
-               pCurHcb->HCS_LastBusy->SCB_NxtScb = scbp;
-               pCurHcb->HCS_LastBusy = scbp;
+               host->targets[scbp->target].flags |= TCF_BUSY;
+       scbp->status = SCB_BUSY;
+       scbp->next = NULL;
+       if (host->last_busy != NULL) {
+               host->last_busy->next = scbp;
+               host->last_busy = scbp;
        } else {
-               pCurHcb->HCS_FirstBusy = scbp;
-               pCurHcb->HCS_LastBusy = scbp;
+               host->first_busy = scbp;
+               host->last_busy = scbp;
        }
 }
 
 /***************************************************************************/
-static SCB *tul_pop_busy_scb(HCS * pCurHcb)
+static struct scsi_ctrl_blk *initio_pop_busy_scb(struct initio_host * host)
 {
-       SCB *pTmpScb;
+       struct scsi_ctrl_blk *tmp;
 
 
-       if ((pTmpScb = pCurHcb->HCS_FirstBusy) != NULL) {
-               if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
-                       pCurHcb->HCS_LastBusy = NULL;
-               pTmpScb->SCB_NxtScb = NULL;
-               if (pTmpScb->SCB_TagMsg)
-                       pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--;
+       if ((tmp = host->first_busy) != NULL) {
+               if ((host->first_busy = tmp->next) == NULL)
+                       host->last_busy = NULL;
+               tmp->next = NULL;
+               if (tmp->tagmsg)
+                       host->act_tags[tmp->target]--;
                else
-                       pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY;
+                       host->targets[tmp->target].flags &= ~TCF_BUSY;
        }
 #if DEBUG_QUEUE
-       printk("Pop busy SCB %lx; ", (ULONG) pTmpScb);
+       printk("Pop busy SCB %p; ", tmp);
 #endif
-       return (pTmpScb);
+       return tmp;
 }
 
 /***************************************************************************/
-static void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb)
+static void initio_unlink_busy_scb(struct initio_host * host, struct scsi_ctrl_blk * scb)
 {
-       SCB *pTmpScb, *pPrevScb;
+       struct scsi_ctrl_blk *tmp, *prev;
 
 #if DEBUG_QUEUE
-       printk("unlink busy SCB %lx; ", (ULONG) pCurScb);
+       printk("unlink busy SCB %p; ", scb);
 #endif
 
-       pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;
-       while (pTmpScb != NULL) {
-               if (pCurScb == pTmpScb) {       /* Unlink this SCB              */
-                       if (pTmpScb == pCurHcb->HCS_FirstBusy) {
-                               if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
-                                       pCurHcb->HCS_LastBusy = NULL;
+       prev = tmp = host->first_busy;
+       while (tmp != NULL) {
+               if (scb == tmp) {       /* Unlink this SCB              */
+                       if (tmp == host->first_busy) {
+                               if ((host->first_busy = tmp->next) == NULL)
+                                       host->last_busy = NULL;
                        } else {
-                               pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
-                               if (pTmpScb == pCurHcb->HCS_LastBusy)
-                                       pCurHcb->HCS_LastBusy = pPrevScb;
+                               prev->next = tmp->next;
+                               if (tmp == host->last_busy)
+                                       host->last_busy = prev;
                        }
-                       pTmpScb->SCB_NxtScb = NULL;
-                       if (pTmpScb->SCB_TagMsg)
-                               pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--;
+                       tmp->next = NULL;
+                       if (tmp->tagmsg)
+                               host->act_tags[tmp->target]--;
                        else
-                               pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY;
+                               host->targets[tmp->target].flags &= ~TCF_BUSY;
                        break;
                }
-               pPrevScb = pTmpScb;
-               pTmpScb = pTmpScb->SCB_NxtScb;
+               prev = tmp;
+               tmp = tmp->next;
        }
        return;
 }
 
-/***************************************************************************/
-SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun)
+struct scsi_ctrl_blk *initio_find_busy_scb(struct initio_host * host, u16 tarlun)
 {
-       SCB *pTmpScb, *pPrevScb;
-       WORD scbp_tarlun;
+       struct scsi_ctrl_blk *tmp, *prev;
+       u16 scbp_tarlun;
 
 
-       pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;
-       while (pTmpScb != NULL) {
-               scbp_tarlun = (pTmpScb->SCB_Lun << 8) | (pTmpScb->SCB_Target);
+       prev = tmp = host->first_busy;
+       while (tmp != NULL) {
+               scbp_tarlun = (tmp->lun << 8) | (tmp->target);
                if (scbp_tarlun == tarlun) {    /* Unlink this SCB              */
                        break;
                }
-               pPrevScb = pTmpScb;
-               pTmpScb = pTmpScb->SCB_NxtScb;
+               prev = tmp;
+               tmp = tmp->next;
        }
 #if DEBUG_QUEUE
-       printk("find busy SCB %lx; ", (ULONG) pTmpScb);
+       printk("find busy SCB %p; ", tmp);
 #endif
-       return (pTmpScb);
+       return tmp;
 }
 
-/***************************************************************************/
-static void tul_append_done_scb(HCS * pCurHcb, SCB * scbp)
+static void initio_append_done_scb(struct initio_host * host, struct scsi_ctrl_blk * scbp)
 {
-
 #if DEBUG_QUEUE
-       printk("append done SCB %lx; ", (ULONG) scbp);
+       printk("append done SCB %p; ", scbp);
 #endif
 
-       scbp->SCB_Status = SCB_DONE;
-       scbp->SCB_NxtScb = NULL;
-       if (pCurHcb->HCS_LastDone != NULL) {
-               pCurHcb->HCS_LastDone->SCB_NxtScb = scbp;
-               pCurHcb->HCS_LastDone = scbp;
+       scbp->status = SCB_DONE;
+       scbp->next = NULL;
+       if (host->last_done != NULL) {
+               host->last_done->next = scbp;
+               host->last_done = scbp;
        } else {
-               pCurHcb->HCS_FirstDone = scbp;
-               pCurHcb->HCS_LastDone = scbp;
+               host->first_done = scbp;
+               host->last_done = scbp;
        }
 }
 
-/***************************************************************************/
-SCB *tul_find_done_scb(HCS * pCurHcb)
+struct scsi_ctrl_blk *initio_find_done_scb(struct initio_host * host)
 {
-       SCB *pTmpScb;
+       struct scsi_ctrl_blk *tmp;
 
-
-       if ((pTmpScb = pCurHcb->HCS_FirstDone) != NULL) {
-               if ((pCurHcb->HCS_FirstDone = pTmpScb->SCB_NxtScb) == NULL)
-                       pCurHcb->HCS_LastDone = NULL;
-               pTmpScb->SCB_NxtScb = NULL;
+       if ((tmp = host->first_done) != NULL) {
+               if ((host->first_done = tmp->next) == NULL)
+                       host->last_done = NULL;
+               tmp->next = NULL;
        }
 #if DEBUG_QUEUE
-       printk("find done SCB %lx; ", (ULONG) pTmpScb);
+       printk("find done SCB %p; ",tmp);
 #endif
-       return (pTmpScb);
+       return tmp;
 }
 
-/***************************************************************************/
-static int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp)
+static int initio_abort_srb(struct initio_host * host, struct scsi_cmnd *srbp)
 {
-       ULONG flags;
-       SCB *pTmpScb, *pPrevScb;
+       unsigned long flags;
+       struct scsi_ctrl_blk *tmp, *prev;
 
-       spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
+       spin_lock_irqsave(&host->semaph_lock, flags);
 
-       if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) {
-               TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
+       if ((host->semaph == 0) && (host->active == NULL)) {
                /* disable Jasmin SCSI Int        */
-
-                spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
-
-               tulip_main(pCurHcb);
-
-               spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
-
-               pCurHcb->HCS_Semaph = 1;
-               TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
-
-               spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
-
+               outb(0x1F, host->addr + TUL_Mask);
+               spin_unlock_irqrestore(&host->semaph_lock, flags);
+               /* FIXME: synchronize_irq needed ? */
+               tulip_main(host);
+               spin_lock_irqsave(&host->semaph_lock, flags);
+               host->semaph = 1;
+               outb(0x0F, host->addr + TUL_Mask);
+               spin_unlock_irqrestore(&host->semaph_lock, flags);
                return SCSI_ABORT_SNOOZE;
        }
-       pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend;    /* Check Pend queue */
-       while (pTmpScb != NULL) {
+       prev = tmp = host->first_pending;       /* Check Pend queue */
+       while (tmp != NULL) {
                /* 07/27/98 */
-               if (pTmpScb->SCB_Srb == srbp) {
-                       if (pTmpScb == pCurHcb->HCS_ActScb) {
-                               spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
+               if (tmp->srb == srbp) {
+                       if (tmp == host->active) {
+                               spin_unlock_irqrestore(&host->semaph_lock, flags);
                                return SCSI_ABORT_BUSY;
-                       } else if (pTmpScb == pCurHcb->HCS_FirstPend) {
-                               if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL)
-                                       pCurHcb->HCS_LastPend = NULL;
+                       } else if (tmp == host->first_pending) {
+                               if ((host->first_pending = tmp->next) == NULL)
+                                       host->last_pending = NULL;
                        } else {
-                               pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
-                               if (pTmpScb == pCurHcb->HCS_LastPend)
-                                       pCurHcb->HCS_LastPend = pPrevScb;
+                               prev->next = tmp->next;
+                               if (tmp == host->last_pending)
+                                       host->last_pending = prev;
                        }
-                       pTmpScb->SCB_HaStat = HOST_ABORTED;
-                       pTmpScb->SCB_Flags |= SCF_DONE;
-                       if (pTmpScb->SCB_Flags & SCF_POST)
-                               (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb);
-                       spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
+                       tmp->hastat = HOST_ABORTED;
+                       tmp->flags |= SCF_DONE;
+                       if (tmp->flags & SCF_POST)
+                               (*tmp->post) ((u8 *) host, (u8 *) tmp);
+                       spin_unlock_irqrestore(&host->semaph_lock, flags);
                        return SCSI_ABORT_SUCCESS;
                }
-               pPrevScb = pTmpScb;
-               pTmpScb = pTmpScb->SCB_NxtScb;
+               prev = tmp;
+               tmp = tmp->next;
        }
 
-       pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;    /* Check Busy queue */
-       while (pTmpScb != NULL) {
-
-               if (pTmpScb->SCB_Srb == srbp) {
-
-                       if (pTmpScb == pCurHcb->HCS_ActScb) {
-                               spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
+       prev = tmp = host->first_busy;  /* Check Busy queue */
+       while (tmp != NULL) {
+               if (tmp->srb == srbp) {
+                       if (tmp == host->active) {
+                               spin_unlock_irqrestore(&host->semaph_lock, flags);
                                return SCSI_ABORT_BUSY;
-                       } else if (pTmpScb->SCB_TagMsg == 0) {
-                               spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
+                       } else if (tmp->tagmsg == 0) {
+                               spin_unlock_irqrestore(&host->semaph_lock, flags);
                                return SCSI_ABORT_BUSY;
                        } else {
-                               pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--;
-                               if (pTmpScb == pCurHcb->HCS_FirstBusy) {
-                                       if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
-                                               pCurHcb->HCS_LastBusy = NULL;
+                               host->act_tags[tmp->target]--;
+                               if (tmp == host->first_busy) {
+                                       if ((host->first_busy = tmp->next) == NULL)
+                                               host->last_busy = NULL;
                                } else {
-                                       pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
-                                       if (pTmpScb == pCurHcb->HCS_LastBusy)
-                                               pCurHcb->HCS_LastBusy = pPrevScb;
+                                       prev->next = tmp->next;
+                                       if (tmp == host->last_busy)
+                                               host->last_busy = prev;
                                }
-                               pTmpScb->SCB_NxtScb = NULL;
+                               tmp->next = NULL;
 
 
-                               pTmpScb->SCB_HaStat = HOST_ABORTED;
-                               pTmpScb->SCB_Flags |= SCF_DONE;
-                               if (pTmpScb->SCB_Flags & SCF_POST)
-                                       (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb);
-                               spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
+                               tmp->hastat = HOST_ABORTED;
+                               tmp->flags |= SCF_DONE;
+                               if (tmp->flags & SCF_POST)
+                                       (*tmp->post) ((u8 *) host, (u8 *) tmp);
+                               spin_unlock_irqrestore(&host->semaph_lock, flags);
                                return SCSI_ABORT_SUCCESS;
                        }
                }
-               pPrevScb = pTmpScb;
-               pTmpScb = pTmpScb->SCB_NxtScb;
+               prev = tmp;
+               tmp = tmp->next;
        }
-       spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
-       return (SCSI_ABORT_NOT_RUNNING);
+       spin_unlock_irqrestore(&host->semaph_lock, flags);
+       return SCSI_ABORT_NOT_RUNNING;
 }
 
 /***************************************************************************/
-static int tul_bad_seq(HCS * pCurHcb)
+static int initio_bad_seq(struct initio_host * host)
 {
-       SCB *pCurScb;
-
-       printk("tul_bad_seg c=%d\n", pCurHcb->HCS_Index);
-
-       if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) {
-               tul_unlink_busy_scb(pCurHcb, pCurScb);
-               pCurScb->SCB_HaStat = HOST_BAD_PHAS;
-               pCurScb->SCB_TaStat = 0;
-               tul_append_done_scb(pCurHcb, pCurScb);
-       }
-       tul_stop_bm(pCurHcb);
-
-       tul_reset_scsi(pCurHcb, 8);     /* 7/29/98 */
-
-       return (tul_post_scsi_rst(pCurHcb));
-}
-
-#if 0
-
-/************************************************************************/
-static int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
-                           unsigned int target, unsigned int ResetFlags)
-{
-       ULONG flags;
-       SCB *pScb;
-       spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
-
-       if (ResetFlags & SCSI_RESET_ASYNCHRONOUS) {
-
-               if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) {
-                       TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
-                       /* disable Jasmin SCSI Int        */
-
-                       spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
-
-                       tulip_main(pCurHcb);
-
-                       spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
-
-                       pCurHcb->HCS_Semaph = 1;
-                       TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
-
-                       spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
-
-                       return SCSI_RESET_SNOOZE;
-               }
-               pScb = pCurHcb->HCS_FirstBusy;  /* Check Busy queue */
-               while (pScb != NULL) {
-                       if (pScb->SCB_Srb == pSrb)
-                               break;
-                       pScb = pScb->SCB_NxtScb;
-               }
-               if (pScb == NULL) {
-                       printk("Unable to Reset - No SCB Found\n");
-
-                       spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
-                       return SCSI_RESET_NOT_RUNNING;
-               }
-       }
-       if ((pScb = tul_alloc_scb(pCurHcb)) == NULL) {
-               spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
-               return SCSI_RESET_NOT_RUNNING;
-       }
-       pScb->SCB_Opcode = BusDevRst;
-       pScb->SCB_Flags = SCF_POST;
-       pScb->SCB_Target = target;
-       pScb->SCB_Mode = 0;
-
-       pScb->SCB_Srb = NULL;
-       if (ResetFlags & SCSI_RESET_SYNCHRONOUS) {
-               pScb->SCB_Srb = pSrb;
-       }
-       tul_push_pend_scb(pCurHcb, pScb);       /* push this SCB to Pending queue */
-
-       if (pCurHcb->HCS_Semaph == 1) {
-               TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
-               /* disable Jasmin SCSI Int        */
-               pCurHcb->HCS_Semaph = 0;
-
-               spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
+       struct scsi_ctrl_blk *scb;
 
-               tulip_main(pCurHcb);
+       printk("initio_bad_seg c=%d\n", host->index);
 
-                spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
-
-               pCurHcb->HCS_Semaph = 1;
-               TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
+       if ((scb = host->active) != NULL) {
+               initio_unlink_busy_scb(host, scb);
+               scb->hastat = HOST_BAD_PHAS;
+               scb->tastat = 0;
+               initio_append_done_scb(host, scb);
        }
-       spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
-       return SCSI_RESET_PENDING;
+       initio_stop_bm(host);
+       initio_reset_scsi(host, 8);     /* 7/29/98 */
+       return initio_post_scsi_rst(host);
 }
 
-static int tul_reset_scsi_bus(HCS * pCurHcb)
-{
-       ULONG flags;
-
-       spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
-       TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
-       pCurHcb->HCS_Semaph = 0;
-
-       spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
-
-       tul_stop_bm(pCurHcb);
-
-       tul_reset_scsi(pCurHcb, 2);     /* 7/29/98 */
-
-       spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
-       tul_post_scsi_rst(pCurHcb);
-
-        spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
-
-       tulip_main(pCurHcb);
-
-        spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
-
-       pCurHcb->HCS_Semaph = 1;
-       TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
-       spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
-       return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET);
-}
-
-#endif  /*  0  */
 
 /************************************************************************/
-static void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb)
+static void initio_exec_scb(struct initio_host * host, struct scsi_ctrl_blk * scb)
 {
-       ULONG flags;
+       unsigned long flags;
 
-       pCurScb->SCB_Mode = 0;
+       scb->mode = 0;
 
-       pCurScb->SCB_SGIdx = 0;
-       pCurScb->SCB_SGMax = pCurScb->SCB_SGLen;
+       scb->sgidx = 0;
+       scb->sgmax = scb->sglen;
 
-       spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
+       spin_lock_irqsave(&host->semaph_lock, flags);
 
-       tul_append_pend_scb(pCurHcb, pCurScb);  /* Append this SCB to Pending queue */
+       initio_append_pend_scb(host, scb);      /* Append this SCB to Pending queue */
 
 /* VVVVV 07/21/98 */
-       if (pCurHcb->HCS_Semaph == 1) {
-               TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
-               /* disable Jasmin SCSI Int        */
-               pCurHcb->HCS_Semaph = 0;
-
-               spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
+       if (host->semaph == 1) {
+               /* Disable Jasmin SCSI Int */
+               outb(0x1F, host->addr + TUL_Mask);
+               host->semaph = 0;
+               spin_unlock_irqrestore(&host->semaph_lock, flags);
 
-               tulip_main(pCurHcb);
+               tulip_main(host);
 
-               spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
-
-               pCurHcb->HCS_Semaph = 1;
-               TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
+               spin_lock_irqsave(&host->semaph_lock, flags);
+               host->semaph = 1;
+               outb(0x0F, host->addr + TUL_Mask);
        }
-       spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
+       spin_unlock_irqrestore(&host->semaph_lock, flags);
        return;
 }
 
 /***************************************************************************/
-static int tul_isr(HCS * pCurHcb)
+static int initio_isr(struct initio_host * host)
 {
-       /* Enter critical section       */
-
-       if (TUL_RD(pCurHcb->HCS_Base, TUL_Int) & TSS_INT_PENDING) {
-               if (pCurHcb->HCS_Semaph == 1) {
-                       TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
+       if (inb(host->addr + TUL_Int) & TSS_INT_PENDING) {
+               if (host->semaph == 1) {
+                       outb(0x1F, host->addr + TUL_Mask);
                        /* Disable Tulip SCSI Int */
-                       pCurHcb->HCS_Semaph = 0;
+                       host->semaph = 0;
 
-                       tulip_main(pCurHcb);
+                       tulip_main(host);
 
-                       pCurHcb->HCS_Semaph = 1;
-                       TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
-                       return (1);
+                       host->semaph = 1;
+                       outb(0x0F, host->addr + TUL_Mask);
+                       return 1;
                }
        }
-       return (0);
+       return 0;
 }
 
-/***************************************************************************/
-int tulip_main(HCS * pCurHcb)
+static int tulip_main(struct initio_host * host)
 {
-       SCB *pCurScb;
+       struct scsi_ctrl_blk *scb;
 
        for (;;) {
-
-               tulip_scsi(pCurHcb);    /* Call tulip_scsi              */
-
-               while ((pCurScb = tul_find_done_scb(pCurHcb)) != NULL) {        /* find done entry */
-                       if (pCurScb->SCB_TaStat == INI_QUEUE_FULL) {
-                               pCurHcb->HCS_MaxTags[pCurScb->SCB_Target] =
-                                   pCurHcb->HCS_ActTags[pCurScb->SCB_Target] - 1;
-                               pCurScb->SCB_TaStat = 0;
-                               tul_append_pend_scb(pCurHcb, pCurScb);
+               tulip_scsi(host);       /* Call tulip_scsi              */
+
+               /* Walk the list of completed SCBs */
+               while ((scb = initio_find_done_scb(host)) != NULL) {    /* find done entry */
+                       if (scb->tastat == INI_QUEUE_FULL) {
+                               host->max_tags[scb->target] =
+                                   host->act_tags[scb->target] - 1;
+                               scb->tastat = 0;
+                               initio_append_pend_scb(host, scb);
                                continue;
                        }
-                       if (!(pCurScb->SCB_Mode & SCM_RSENS)) {         /* not in auto req. sense mode */
-                               if (pCurScb->SCB_TaStat == 2) {
+                       if (!(scb->mode & SCM_RSENS)) {         /* not in auto req. sense mode */
+                               if (scb->tastat == 2) {
 
                                        /* clr sync. nego flag */
 
-                                       if (pCurScb->SCB_Flags & SCF_SENSE) {
-                                               BYTE len;
-                                               len = pCurScb->SCB_SenseLen;
+                                       if (scb->flags & SCF_SENSE) {
+                                               u8 len;
+                                               len = scb->senselen;
                                                if (len == 0)
                                                        len = 1;
-                                               pCurScb->SCB_BufLen = pCurScb->SCB_SenseLen;
-                                               pCurScb->SCB_BufPtr = pCurScb->SCB_SensePtr;
-                                               pCurScb->SCB_Flags &= ~(SCF_SG | SCF_DIR);      /* for xfer_data_in */
-/*                      pCurScb->SCB_Flags |= SCF_NO_DCHK;      */
-                                               /* so, we won't report worng direction in xfer_data_in,
+                                               scb->buflen = scb->senselen;
+                                               scb->bufptr = scb->senseptr;
+                                               scb->flags &= ~(SCF_SG | SCF_DIR);      /* for xfer_data_in */
+                                               /* so, we won't report wrong direction in xfer_data_in,
                                                   and won't report HOST_DO_DU in state_6 */
-                                               pCurScb->SCB_Mode = SCM_RSENS;
-                                               pCurScb->SCB_Ident &= 0xBF;     /* Disable Disconnect */
-                                               pCurScb->SCB_TagMsg = 0;
-                                               pCurScb->SCB_TaStat = 0;
-                                               pCurScb->SCB_CDBLen = 6;
-                                               pCurScb->SCB_CDB[0] = SCSICMD_RequestSense;
-                                               pCurScb->SCB_CDB[1] = 0;
-                                               pCurScb->SCB_CDB[2] = 0;
-                                               pCurScb->SCB_CDB[3] = 0;
-                                               pCurScb->SCB_CDB[4] = len;
-                                               pCurScb->SCB_CDB[5] = 0;
-                                               tul_push_pend_scb(pCurHcb, pCurScb);
+                                               scb->mode = SCM_RSENS;
+                                               scb->ident &= 0xBF;     /* Disable Disconnect */
+                                               scb->tagmsg = 0;
+                                               scb->tastat = 0;
+                                               scb->cdblen = 6;
+                                               scb->cdb[0] = SCSICMD_RequestSense;
+                                               scb->cdb[1] = 0;
+                                               scb->cdb[2] = 0;
+                                               scb->cdb[3] = 0;
+                                               scb->cdb[4] = len;
+                                               scb->cdb[5] = 0;
+                                               initio_push_pend_scb(host, scb);
                                                break;
                                        }
                                }
                        } else {        /* in request sense mode */
 
-                               if (pCurScb->SCB_TaStat == 2) {         /* check contition status again after sending
+                               if (scb->tastat == 2) {         /* check contition status again after sending
                                                                           requset sense cmd 0x3 */
-                                       pCurScb->SCB_HaStat = HOST_BAD_PHAS;
+                                       scb->hastat = HOST_BAD_PHAS;
                                }
-                               pCurScb->SCB_TaStat = 2;
+                               scb->tastat = 2;
                        }
-                       pCurScb->SCB_Flags |= SCF_DONE;
-                       if (pCurScb->SCB_Flags & SCF_POST) {
-                               (*pCurScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pCurScb);
+                       scb->flags |= SCF_DONE;
+                       if (scb->flags & SCF_POST) {
+                               /* FIXME: only one post method and lose casts */
+                               (*scb->post) ((u8 *) host, (u8 *) scb);
                        }
                }               /* while */
-
                /* find_active: */
-               if (TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0) & TSS_INT_PENDING)
+               if (inb(host->addr + TUL_SStatus0) & TSS_INT_PENDING)
                        continue;
-
-               if (pCurHcb->HCS_ActScb) {      /* return to OS and wait for xfer_done_ISR/Selected_ISR */
+               if (host->active)       /* return to OS and wait for xfer_done_ISR/Selected_ISR */
                        return 1;       /* return to OS, enable interrupt */
-               }
                /* Check pending SCB            */
-               if (tul_find_first_pend_scb(pCurHcb) == NULL) {
+               if (initio_find_first_pend_scb(host) == NULL)
                        return 1;       /* return to OS, enable interrupt */
-               }
        }                       /* End of for loop */
        /* statement won't reach here */
 }
 
-
-
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-/***************************************************************************/
-/***************************************************************************/
-/***************************************************************************/
-/***************************************************************************/
-
-/***************************************************************************/
-void tulip_scsi(HCS * pCurHcb)
+static void tulip_scsi(struct initio_host * host)
 {
-       SCB *pCurScb;
-       TCS *pCurTcb;
+       struct scsi_ctrl_blk *scb;
+       struct target_control *active_tc;
 
        /* make sure to service interrupt asap */
-
-       if ((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0)) & TSS_INT_PENDING) {
-
-               pCurHcb->HCS_Phase = pCurHcb->HCS_JSStatus0 & TSS_PH_MASK;
-               pCurHcb->HCS_JSStatus1 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1);
-               pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
-               if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) {     /* SCSI bus reset detected      */
-                       int_tul_scsi_rst(pCurHcb);
+       if ((host->jsstatus0 = inb(host->addr + TUL_SStatus0)) & TSS_INT_PENDING) {
+               host->phase = host->jsstatus0 & TSS_PH_MASK;
+               host->jsstatus1 = inb(host->addr + TUL_SStatus1);
+               host->jsint = inb(host->addr + TUL_SInt);
+               if (host->jsint & TSS_SCSIRST_INT) {    /* SCSI bus reset detected      */
+                       int_initio_scsi_rst(host);
                        return;
                }
-               if (pCurHcb->HCS_JSInt & TSS_RESEL_INT) {       /* if selected/reselected interrupt */
-                       if (int_tul_resel(pCurHcb) == 0)
-                               tul_next_state(pCurHcb);
+               if (host->jsint & TSS_RESEL_INT) {      /* if selected/reselected interrupt */
+                       if (int_initio_resel(host) == 0)
+                               initio_next_state(host);
                        return;
                }
-               if (pCurHcb->HCS_JSInt & TSS_SEL_TIMEOUT) {
-                       int_tul_busfree(pCurHcb);
+               if (host->jsint & TSS_SEL_TIMEOUT) {
+                       int_initio_busfree(host);
                        return;
                }
-               if (pCurHcb->HCS_JSInt & TSS_DISC_INT) {        /* BUS disconnection            */
-                       int_tul_busfree(pCurHcb);       /* unexpected bus free or sel timeout */
+               if (host->jsint & TSS_DISC_INT) {       /* BUS disconnection            */
+                       int_initio_busfree(host);       /* unexpected bus free or sel timeout */
                        return;
                }
-               if (pCurHcb->HCS_JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) {      /* func complete or Bus service */
-                       if ((pCurScb = pCurHcb->HCS_ActScb) != NULL)
-                               tul_next_state(pCurHcb);
+               if (host->jsint & (TSS_FUNC_COMP | TSS_BUS_SERV)) {     /* func complete or Bus service */
+                       if ((scb = host->active) != NULL)
+                               initio_next_state(host);
                        return;
                }
        }
-       if (pCurHcb->HCS_ActScb != NULL)
+       if (host->active != NULL)
                return;
 
-       if ((pCurScb = tul_find_first_pend_scb(pCurHcb)) == NULL)
+       if ((scb = initio_find_first_pend_scb(host)) == NULL)
                return;
 
        /* program HBA's SCSI ID & target SCSI ID */
-       TUL_WR(pCurHcb->HCS_Base + TUL_SScsiId,
-            (pCurHcb->HCS_SCSI_ID << 4) | (pCurScb->SCB_Target & 0x0F));
-       if (pCurScb->SCB_Opcode == ExecSCSI) {
-               pCurTcb = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
+       outb((host->scsi_id << 4) | (scb->target & 0x0F),
+               host->addr + TUL_SScsiId);
+       if (scb->opcode == ExecSCSI) {
+               active_tc = &host->targets[scb->target];
 
-               if (pCurScb->SCB_TagMsg)
-                       pCurTcb->TCS_DrvFlags |= TCF_DRV_EN_TAG;
+               if (scb->tagmsg)
+                       active_tc->drv_flags |= TCF_DRV_EN_TAG;
                else
-                       pCurTcb->TCS_DrvFlags &= ~TCF_DRV_EN_TAG;
+                       active_tc->drv_flags &= ~TCF_DRV_EN_TAG;
 
-               TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurTcb->TCS_JS_Period);
-               if ((pCurTcb->TCS_Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {        /* do wdtr negotiation          */
-                       tul_select_atn_stop(pCurHcb, pCurScb);
+               outb(active_tc->js_period, host->addr + TUL_SPeriod);
+               if ((active_tc->flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {  /* do wdtr negotiation          */
+                       initio_select_atn_stop(host, scb);
                } else {
-                       if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {   /* do sync negotiation          */
-                               tul_select_atn_stop(pCurHcb, pCurScb);
+                       if ((active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {     /* do sync negotiation          */
+                               initio_select_atn_stop(host, scb);
                        } else {
-                               if (pCurScb->SCB_TagMsg)
-                                       tul_select_atn3(pCurHcb, pCurScb);
+                               if (scb->tagmsg)
+                                       initio_select_atn3(host, scb);
                                else
-                                       tul_select_atn(pCurHcb, pCurScb);
+                                       initio_select_atn(host, scb);
                        }
                }
-               if (pCurScb->SCB_Flags & SCF_POLL) {
-                       while (wait_tulip(pCurHcb) != -1) {
-                               if (tul_next_state(pCurHcb) == -1)
+               if (scb->flags & SCF_POLL) {
+                       while (wait_tulip(host) != -1) {
+                               if (initio_next_state(host) == -1)
                                        break;
                        }
                }
-       } else if (pCurScb->SCB_Opcode == BusDevRst) {
-               tul_select_atn_stop(pCurHcb, pCurScb);
-               pCurScb->SCB_NxtStat = 8;
-               if (pCurScb->SCB_Flags & SCF_POLL) {
-                       while (wait_tulip(pCurHcb) != -1) {
-                               if (tul_next_state(pCurHcb) == -1)
+       } else if (scb->opcode == BusDevRst) {
+               initio_select_atn_stop(host, scb);
+               scb->next_state = 8;
+               if (scb->flags & SCF_POLL) {
+                       while (wait_tulip(host) != -1) {
+                               if (initio_next_state(host) == -1)
                                        break;
                        }
                }
-       } else if (pCurScb->SCB_Opcode == AbortCmd) {
-               if (tul_abort_srb(pCurHcb, pCurScb->SCB_Srb) != 0) {
-
-
-                       tul_unlink_pend_scb(pCurHcb, pCurScb);
-
-                       tul_release_scb(pCurHcb, pCurScb);
+       } else if (scb->opcode == AbortCmd) {
+               if (initio_abort_srb(host, scb->srb) != 0) {
+                       initio_unlink_pend_scb(host, scb);
+                       initio_release_scb(host, scb);
                } else {
-                       pCurScb->SCB_Opcode = BusDevRst;
-                       tul_select_atn_stop(pCurHcb, pCurScb);
-                       pCurScb->SCB_NxtStat = 8;
+                       scb->opcode = BusDevRst;
+                       initio_select_atn_stop(host, scb);
+                       scb->next_state = 8;
                }
-
-/* 08/03/98 */
        } else {
-               tul_unlink_pend_scb(pCurHcb, pCurScb);
-               pCurScb->SCB_HaStat = 0x16;     /* bad command */
-               tul_append_done_scb(pCurHcb, pCurScb);
+               initio_unlink_pend_scb(host, scb);
+               scb->hastat = 0x16;     /* bad command */
+               initio_append_done_scb(host, scb);
        }
        return;
 }
 
+/**
+ *     initio_next_state               -       Next SCSI state
+ *     @host: InitIO host we are processing
+ *
+ *     Progress the active command block along the state machine
+ *     until we hit a state which we must wait for activity to occur.
+ *
+ *     Returns zero or a negative code.
+ */
 
-/***************************************************************************/
-int tul_next_state(HCS * pCurHcb)
+static int initio_next_state(struct initio_host * host)
 {
        int next;
 
-       next = pCurHcb->HCS_ActScb->SCB_NxtStat;
+       next = host->active->next_state;
        for (;;) {
                switch (next) {
                case 1:
-                       next = tul_state_1(pCurHcb);
+                       next = initio_state_1(host);
                        break;
                case 2:
-                       next = tul_state_2(pCurHcb);
+                       next = initio_state_2(host);
                        break;
                case 3:
-                       next = tul_state_3(pCurHcb);
+                       next = initio_state_3(host);
                        break;
                case 4:
-                       next = tul_state_4(pCurHcb);
+                       next = initio_state_4(host);
                        break;
                case 5:
-                       next = tul_state_5(pCurHcb);
+                       next = initio_state_5(host);
                        break;
                case 6:
-                       next = tul_state_6(pCurHcb);
+                       next = initio_state_6(host);
                        break;
                case 7:
-                       next = tul_state_7(pCurHcb);
+                       next = initio_state_7(host);
                        break;
                case 8:
-                       return (tul_bus_device_reset(pCurHcb));
+                       return initio_bus_device_reset(host);
                default:
-                       return (tul_bad_seq(pCurHcb));
+                       return initio_bad_seq(host);
                }
                if (next <= 0)
                        return next;
@@ -1554,338 +1314,363 @@ int tul_next_state(HCS * pCurHcb)
 }
 
 
-/***************************************************************************/
-/* sTate after selection with attention & stop */
-int tul_state_1(HCS * pCurHcb)
+/**
+ *     initio_state_1          -       SCSI state machine
+ *     @host: InitIO host we are controlling
+ *
+ *     Perform SCSI state processing for Select/Attention/Stop
+ */
+
+static int initio_state_1(struct initio_host * host)
 {
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
-       TCS *pCurTcb = pCurHcb->HCS_ActTcs;
+       struct scsi_ctrl_blk *scb = host->active;
+       struct target_control *active_tc = host->active_tc;
 #if DEBUG_STATE
        printk("-s1-");
 #endif
 
-       tul_unlink_pend_scb(pCurHcb, pCurScb);
-       tul_append_busy_scb(pCurHcb, pCurScb);
+       /* Move the SCB from pending to busy */
+       initio_unlink_pend_scb(host, scb);
+       initio_append_busy_scb(host, scb);
 
-       TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0);
+       outb(active_tc->sconfig0, host->addr + TUL_SConfig );
        /* ATN on */
-       if (pCurHcb->HCS_Phase == MSG_OUT) {
-
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, (TSC_EN_BUS_IN | TSC_HW_RESELECT));
-
-               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident);
-
-               if (pCurScb->SCB_TagMsg) {
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagMsg);
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagId);
-               }
-               if ((pCurTcb->TCS_Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {
-
-                       pCurTcb->TCS_Flags |= TCF_WDTR_DONE;
-
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 2);       /* Extended msg length */
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);       /* Sync request */
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);       /* Start from 16 bits */
-               } else if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {
-
-                       pCurTcb->TCS_Flags |= TCF_SYNC_DONE;
-
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);       /* extended msg length */
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);       /* sync request */
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, tul_rate_tbl[pCurTcb->TCS_Flags & TCF_SCSI_RATE]);
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MAX_OFFSET);      /* REQ/ACK offset */
-               }
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-               if (wait_tulip(pCurHcb) == -1)
-                       return (-1);
-       }
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)));
-       return (3);
-}
-
+       if (host->phase == MSG_OUT) {
+               outb(TSC_EN_BUS_IN | TSC_HW_RESELECT, host->addr + TUL_SCtrl1);
+               outb(scb->ident, host->addr + TUL_SFifo);
+
+               if (scb->tagmsg) {
+                       outb(scb->tagmsg, host->addr + TUL_SFifo);
+                       outb(scb->tagid, host->addr + TUL_SFifo);
+               }
+               if ((active_tc->flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {
+                       active_tc->flags |= TCF_WDTR_DONE;
+                       outb(MSG_EXTEND, host->addr + TUL_SFifo);
+                       outb(2, host->addr + TUL_SFifo);        /* Extended msg length */
+                       outb(3, host->addr + TUL_SFifo);        /* Sync request */
+                       outb(1, host->addr + TUL_SFifo);        /* Start from 16 bits */
+               } else if ((active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {
+                       active_tc->flags |= TCF_SYNC_DONE;
+                       outb(MSG_EXTEND, host->addr + TUL_SFifo);
+                       outb(3, host->addr + TUL_SFifo);        /* extended msg length */
+                       outb(1, host->addr + TUL_SFifo);        /* sync request */
+                       outb(initio_rate_tbl[active_tc->flags & TCF_SCSI_RATE], host->addr + TUL_SFifo);
+                       outb(MAX_OFFSET, host->addr + TUL_SFifo);       /* REQ/ACK offset */
+               }
+               outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+               if (wait_tulip(host) == -1)
+                       return -1;
+       }
+       outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
+       outb((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)), host->addr + TUL_SSignal);
+       /* Into before CDB xfer */
+       return 3;
+}
+
+
+/**
+ *     initio_state_2          -       SCSI state machine
+ *     @host: InitIO host we are controlling
+ *
+ * state after selection with attention
+ * state after selection with attention3
+ */
 
-/***************************************************************************/
-/* state after selection with attention */
-/* state after selection with attention3 */
-int tul_state_2(HCS * pCurHcb)
+static int initio_state_2(struct initio_host * host)
 {
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
-       TCS *pCurTcb = pCurHcb->HCS_ActTcs;
+       struct scsi_ctrl_blk *scb = host->active;
+       struct target_control *active_tc = host->active_tc;
 #if DEBUG_STATE
        printk("-s2-");
 #endif
 
-       tul_unlink_pend_scb(pCurHcb, pCurScb);
-       tul_append_busy_scb(pCurHcb, pCurScb);
+       initio_unlink_pend_scb(host, scb);
+       initio_append_busy_scb(host, scb);
 
-       TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0);
+       outb(active_tc->sconfig0, host->addr + TUL_SConfig);
 
-       if (pCurHcb->HCS_JSStatus1 & TSS_CMD_PH_CMP) {
-               return (4);
-       }
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)));
-       return (3);
+       if (host->jsstatus1 & TSS_CMD_PH_CMP)
+               return 4;
+
+       outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
+       outb((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)), host->addr + TUL_SSignal);
+       /* Into before CDB xfer */
+       return 3;
 }
 
-/***************************************************************************/
-/* state before CDB xfer is done */
-int tul_state_3(HCS * pCurHcb)
+/**
+ *     initio_state_3          -       SCSI state machine
+ *     @host: InitIO host we are controlling
+ *
+ * state before CDB xfer is done
+ */
+
+static int initio_state_3(struct initio_host * host)
 {
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
-       TCS *pCurTcb = pCurHcb->HCS_ActTcs;
+       struct scsi_ctrl_blk *scb = host->active;
+       struct target_control *active_tc = host->active_tc;
        int i;
 
 #if DEBUG_STATE
        printk("-s3-");
 #endif
        for (;;) {
-               switch (pCurHcb->HCS_Phase) {
+               switch (host->phase) {
                case CMD_OUT:   /* Command out phase            */
-                       for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++)
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]);
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-                       if (wait_tulip(pCurHcb) == -1)
-                               return (-1);
-                       if (pCurHcb->HCS_Phase == CMD_OUT) {
-                               return (tul_bad_seq(pCurHcb));
-                       }
-                       return (4);
+                       for (i = 0; i < (int) scb->cdblen; i++)
+                               outb(scb->cdb[i], host->addr + TUL_SFifo);
+                       outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+                       if (wait_tulip(host) == -1)
+                               return -1;
+                       if (host->phase == CMD_OUT)
+                               return initio_bad_seq(host);
+                       return 4;
 
                case MSG_IN:    /* Message in phase             */
-                       pCurScb->SCB_NxtStat = 3;
-                       if (tul_msgin(pCurHcb) == -1)
-                               return (-1);
+                       scb->next_state = 3;
+                       if (initio_msgin(host) == -1)
+                               return -1;
                        break;
 
                case STATUS_IN: /* Status phase                 */
-                       if (tul_status_msg(pCurHcb) == -1)
-                               return (-1);
+                       if (initio_status_msg(host) == -1)
+                               return -1;
                        break;
 
                case MSG_OUT:   /* Message out phase            */
-                       if (pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) {
-
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);         /* msg nop */
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-                               if (wait_tulip(pCurHcb) == -1)
-                                       return (-1);
-
+                       if (active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) {
+                               outb(MSG_NOP, host->addr + TUL_SFifo);          /* msg nop */
+                               outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+                               if (wait_tulip(host) == -1)
+                                       return -1;
                        } else {
-                               pCurTcb->TCS_Flags |= TCF_SYNC_DONE;
-
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);       /* ext. msg len */
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);       /* sync request */
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, tul_rate_tbl[pCurTcb->TCS_Flags & TCF_SCSI_RATE]);
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MAX_OFFSET);      /* REQ/ACK offset */
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-                               if (wait_tulip(pCurHcb) == -1)
-                                       return (-1);
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7));
+                               active_tc->flags |= TCF_SYNC_DONE;
+
+                               outb(MSG_EXTEND, host->addr + TUL_SFifo);
+                               outb(3, host->addr + TUL_SFifo);        /* ext. msg len */
+                               outb(1, host->addr + TUL_SFifo);        /* sync request */
+                               outb(initio_rate_tbl[active_tc->flags & TCF_SCSI_RATE], host->addr + TUL_SFifo);
+                               outb(MAX_OFFSET, host->addr + TUL_SFifo);       /* REQ/ACK offset */
+                               outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+                               if (wait_tulip(host) == -1)
+                                       return -1;
+                               outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
+                               outb(inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7), host->addr + TUL_SSignal);
 
                        }
                        break;
-
                default:
-                       return (tul_bad_seq(pCurHcb));
+                       return initio_bad_seq(host);
                }
        }
 }
 
+/**
+ *     initio_state_4          -       SCSI state machine
+ *     @host: InitIO host we are controlling
+ *
+ *     SCSI state machine. State 4
+ */
 
-/***************************************************************************/
-int tul_state_4(HCS * pCurHcb)
+static int initio_state_4(struct initio_host * host)
 {
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
+       struct scsi_ctrl_blk *scb = host->active;
 
 #if DEBUG_STATE
        printk("-s4-");
 #endif
-       if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_NO_XF) {
-               return (6);     /* Go to state 6                */
+       if ((scb->flags & SCF_DIR) == SCF_NO_XF) {
+               return 6;       /* Go to state 6 (After data) */
        }
        for (;;) {
-               if (pCurScb->SCB_BufLen == 0)
-                       return (6);     /* Go to state 6                */
+               if (scb->buflen == 0)
+                       return 6;
 
-               switch (pCurHcb->HCS_Phase) {
+               switch (host->phase) {
 
                case STATUS_IN: /* Status phase                 */
-                       if ((pCurScb->SCB_Flags & SCF_DIR) != 0) {      /* if direction bit set then report data underrun */
-                               pCurScb->SCB_HaStat = HOST_DO_DU;
-                       }
-                       if ((tul_status_msg(pCurHcb)) == -1)
-                               return (-1);
+                       if ((scb->flags & SCF_DIR) != 0)        /* if direction bit set then report data underrun */
+                               scb->hastat = HOST_DO_DU;
+                       if ((initio_status_msg(host)) == -1)
+                               return -1;
                        break;
 
                case MSG_IN:    /* Message in phase             */
-                       pCurScb->SCB_NxtStat = 0x4;
-                       if (tul_msgin(pCurHcb) == -1)
-                               return (-1);
+                       scb->next_state = 0x4;
+                       if (initio_msgin(host) == -1)
+                               return -1;
                        break;
 
                case MSG_OUT:   /* Message out phase            */
-                       if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {
-                               pCurScb->SCB_BufLen = 0;
-                               pCurScb->SCB_HaStat = HOST_DO_DU;
-                               if (tul_msgout_ide(pCurHcb) == -1)
-                                       return (-1);
-                               return (6);     /* Go to state 6                */
+                       if (host->jsstatus0 & TSS_PAR_ERROR) {
+                               scb->buflen = 0;
+                               scb->hastat = HOST_DO_DU;
+                               if (initio_msgout_ide(host) == -1)
+                                       return -1;
+                               return 6;
                        } else {
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);         /* msg nop */
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-                               if (wait_tulip(pCurHcb) == -1)
-                                       return (-1);
+                               outb(MSG_NOP, host->addr + TUL_SFifo);          /* msg nop */
+                               outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+                               if (wait_tulip(host) == -1)
+                                       return -1;
                        }
                        break;
 
                case DATA_IN:   /* Data in phase                */
-                       return (tul_xfer_data_in(pCurHcb));
+                       return initio_xfer_data_in(host);
 
                case DATA_OUT:  /* Data out phase               */
-                       return (tul_xfer_data_out(pCurHcb));
+                       return initio_xfer_data_out(host);
 
                default:
-                       return (tul_bad_seq(pCurHcb));
+                       return initio_bad_seq(host);
                }
        }
 }
 
 
-/***************************************************************************/
-/* state after dma xfer done or phase change before xfer done */
-int tul_state_5(HCS * pCurHcb)
+/**
+ *     initio_state_5          -       SCSI state machine
+ *     @host: InitIO host we are controlling
+ *
+ *     State after dma xfer done or phase change before xfer done
+ */
+
+static int initio_state_5(struct initio_host * host)
 {
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
+       struct scsi_ctrl_blk *scb = host->active;
        long cnt, xcnt;         /* cannot use unsigned !! code: if (xcnt < 0) */
 
 #if DEBUG_STATE
        printk("-s5-");
 #endif
-/*------ get remaining count -------*/
-
-       cnt = TUL_RDLONG(pCurHcb->HCS_Base, TUL_SCnt0) & 0x0FFFFFF;
+       /*------ get remaining count -------*/
+       cnt = inl(host->addr + TUL_SCnt0) & 0x0FFFFFF;
 
-       if (TUL_RD(pCurHcb->HCS_Base, TUL_XCmd) & 0x20) {
+       if (inb(host->addr + TUL_XCmd) & 0x20) {
                /* ----------------------- DATA_IN ----------------------------- */
                /* check scsi parity error */
-               if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {
-                       pCurScb->SCB_HaStat = HOST_DO_DU;
-               }
-               if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) {   /* DMA xfer pending, Send STOP  */
+               if (host->jsstatus0 & TSS_PAR_ERROR)
+                       scb->hastat = HOST_DO_DU;
+               if (inb(host->addr + TUL_XStatus) & XPEND) {    /* DMA xfer pending, Send STOP  */
                        /* tell Hardware  scsi xfer has been terminated */
-                       TUL_WR(pCurHcb->HCS_Base + TUL_XCtrl, TUL_RD(pCurHcb->HCS_Base, TUL_XCtrl) | 0x80);
+                       outb(inb(host->addr + TUL_XCtrl) | 0x80, host->addr + TUL_XCtrl);
                        /* wait until DMA xfer not pending */
-                       while (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND);
+                       while (inb(host->addr + TUL_XStatus) & XPEND)
+                               cpu_relax();
                }
        } else {
-/*-------- DATA OUT -----------*/
-               if ((TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1) & TSS_XFER_CMP) == 0) {
-                       if (pCurHcb->HCS_ActTcs->TCS_JS_Period & TSC_WIDE_SCSI)
-                               cnt += (TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F) << 1;
+               /*-------- DATA OUT -----------*/
+               if ((inb(host->addr + TUL_SStatus1) & TSS_XFER_CMP) == 0) {
+                       if (host->active_tc->js_period & TSC_WIDE_SCSI)
+                               cnt += (inb(host->addr + TUL_SFifoCnt) & 0x1F) << 1;
                        else
-                               cnt += (TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F);
+                               cnt += (inb(host->addr + TUL_SFifoCnt) & 0x1F);
                }
-               if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) {   /* if DMA xfer is pending, abort DMA xfer */
-                       TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT);
+               if (inb(host->addr + TUL_XStatus) & XPEND) {    /* if DMA xfer is pending, abort DMA xfer */
+                       outb(TAX_X_ABT, host->addr + TUL_XCmd);
                        /* wait Abort DMA xfer done */
-                       while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & XABT) == 0);
+                       while ((inb(host->addr + TUL_Int) & XABT) == 0)
+                               cpu_relax();
                }
-               if ((cnt == 1) && (pCurHcb->HCS_Phase == DATA_OUT)) {
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-                       if (wait_tulip(pCurHcb) == -1) {
-                               return (-1);
-                       }
+               if ((cnt == 1) && (host->phase == DATA_OUT)) {
+                       outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+                       if (wait_tulip(host) == -1)
+                               return -1;
                        cnt = 0;
                } else {
-                       if ((TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1) & TSS_XFER_CMP) == 0)
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
+                       if ((inb(host->addr + TUL_SStatus1) & TSS_XFER_CMP) == 0)
+                               outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
                }
        }
-
        if (cnt == 0) {
-               pCurScb->SCB_BufLen = 0;
-               return (6);     /* Go to state 6                */
+               scb->buflen = 0;
+               return 6;       /* After Data */
        }
        /* Update active data pointer */
-       xcnt = (long) pCurScb->SCB_BufLen - cnt;        /* xcnt== bytes already xferred */
-       pCurScb->SCB_BufLen = (U32) cnt;        /* cnt == bytes left to be xferred */
-       if (pCurScb->SCB_Flags & SCF_SG) {
-               register SG *sgp;
-               ULONG i;
-
-               sgp = &pCurScb->SCB_SGList[pCurScb->SCB_SGIdx];
-               for (i = pCurScb->SCB_SGIdx; i < pCurScb->SCB_SGMax; sgp++, i++) {
-                       xcnt -= (long) sgp->SG_Len;
+       xcnt = (long) scb->buflen - cnt;        /* xcnt== bytes already xferred */
+       scb->buflen = (u32) cnt;                /* cnt == bytes left to be xferred */
+       if (scb->flags & SCF_SG) {
+               struct sg_entry *sgp;
+               unsigned long i;
+
+               sgp = &scb->sglist[scb->sgidx];
+               for (i = scb->sgidx; i < scb->sgmax; sgp++, i++) {
+                       xcnt -= (long) sgp->len;
                        if (xcnt < 0) {         /* this sgp xfer half done */
-                               xcnt += (long) sgp->SG_Len;     /* xcnt == bytes xferred in this sgp */
-                               sgp->SG_Ptr += (U32) xcnt;      /* new ptr to be xfer */
-                               sgp->SG_Len -= (U32) xcnt;      /* new len to be xfer */
-                               pCurScb->SCB_BufPtr += ((U32) (i - pCurScb->SCB_SGIdx) << 3);
+                               xcnt += (long) sgp->len;        /* xcnt == bytes xferred in this sgp */
+                               sgp->data += (u32) xcnt;        /* new ptr to be xfer */
+                               sgp->len -= (u32) xcnt; /* new len to be xfer */
+                               scb->bufptr += ((u32) (i - scb->sgidx) << 3);
                                /* new SG table ptr */
-                               pCurScb->SCB_SGLen = (BYTE) (pCurScb->SCB_SGMax - i);
+                               scb->sglen = (u8) (scb->sgmax - i);
                                /* new SG table len */
-                               pCurScb->SCB_SGIdx = (WORD) i;
+                               scb->sgidx = (u16) i;
                                /* for next disc and come in this loop */
-                               return (4);     /* Go to state 4                */
+                               return 4;       /* Go to state 4                */
                        }
                        /* else (xcnt >= 0 , i.e. this sgp already xferred */
                }               /* for */
-               return (6);     /* Go to state 6                */
+               return 6;       /* Go to state 6                */
        } else {
-               pCurScb->SCB_BufPtr += (U32) xcnt;
+               scb->bufptr += (u32) xcnt;
        }
-       return (4);             /* Go to state 4                */
+       return 4;               /* Go to state 4                */
 }
 
-/***************************************************************************/
-/* state after Data phase */
-int tul_state_6(HCS * pCurHcb)
+/**
+ *     initio_state_6          -       SCSI state machine
+ *     @host: InitIO host we are controlling
+ *
+ *     State after Data phase
+ */
+
+static int initio_state_6(struct initio_host * host)
 {
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
+       struct scsi_ctrl_blk *scb = host->active;
 
 #if DEBUG_STATE
        printk("-s6-");
 #endif
        for (;;) {
-               switch (pCurHcb->HCS_Phase) {
+               switch (host->phase) {
                case STATUS_IN: /* Status phase                 */
-                       if ((tul_status_msg(pCurHcb)) == -1)
-                               return (-1);
+                       if ((initio_status_msg(host)) == -1)
+                               return -1;
                        break;
 
                case MSG_IN:    /* Message in phase             */
-                       pCurScb->SCB_NxtStat = 6;
-                       if ((tul_msgin(pCurHcb)) == -1)
-                               return (-1);
+                       scb->next_state = 6;
+                       if ((initio_msgin(host)) == -1)
+                               return -1;
                        break;
 
                case MSG_OUT:   /* Message out phase            */
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);         /* msg nop */
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-                       if (wait_tulip(pCurHcb) == -1)
-                               return (-1);
+                       outb(MSG_NOP, host->addr + TUL_SFifo);          /* msg nop */
+                       outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+                       if (wait_tulip(host) == -1)
+                               return -1;
                        break;
 
                case DATA_IN:   /* Data in phase                */
-                       return (tul_xpad_in(pCurHcb));
+                       return initio_xpad_in(host);
 
                case DATA_OUT:  /* Data out phase               */
-                       return (tul_xpad_out(pCurHcb));
+                       return initio_xpad_out(host);
 
                default:
-                       return (tul_bad_seq(pCurHcb));
+                       return initio_bad_seq(host);
                }
        }
 }
 
-/***************************************************************************/
-int tul_state_7(HCS * pCurHcb)
+/**
+ *     initio_state_7          -       SCSI state machine
+ *     @host: InitIO host we are controlling
+ *
+ */
+
+int initio_state_7(struct initio_host * host)
 {
        int cnt, i;
 
@@ -1893,1139 +1678,1029 @@ int tul_state_7(HCS * pCurHcb)
        printk("-s7-");
 #endif
        /* flush SCSI FIFO */
-       cnt = TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F;
+       cnt = inb(host->addr + TUL_SFifoCnt) & 0x1F;
        if (cnt) {
                for (i = 0; i < cnt; i++)
-                       TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
+                       inb(host->addr + TUL_SFifo);
        }
-       switch (pCurHcb->HCS_Phase) {
+       switch (host->phase) {
        case DATA_IN:           /* Data in phase                */
        case DATA_OUT:          /* Data out phase               */
-               return (tul_bad_seq(pCurHcb));
+               return initio_bad_seq(host);
        default:
-               return (6);     /* Go to state 6                */
+               return 6;       /* Go to state 6                */
        }
 }
 
-/***************************************************************************/
-int tul_xfer_data_in(HCS * pCurHcb)
+/**
+ *     initio_xfer_data_in     -       Commence data input
+ *     @host: InitIO host in use
+ *
+ *     Commence a block of data transfer. The transfer itself will
+ *     be managed by the controller and we will get a completion (or
+ *     failure) interrupt.
+ */
+static int initio_xfer_data_in(struct initio_host * host)
 {
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
+       struct scsi_ctrl_blk *scb = host->active;
 
-       if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_DOUT) {
-               return (6);     /* wrong direction */
-       }
-       TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, pCurScb->SCB_BufLen);
+       if ((scb->flags & SCF_DIR) == SCF_DOUT)
+               return 6;       /* wrong direction */
 
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_DMA_IN);    /* 7/25/95 */
+       outl(scb->buflen, host->addr + TUL_SCnt0);
+       outb(TSC_XF_DMA_IN, host->addr + TUL_SCmd);     /* 7/25/95 */
 
-       if (pCurScb->SCB_Flags & SCF_SG) {      /* S/G xfer */
-               TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, ((ULONG) pCurScb->SCB_SGLen) << 3);
-               TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
-               TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_SG_IN);
+       if (scb->flags & SCF_SG) {      /* S/G xfer */
+               outl(((u32) scb->sglen) << 3, host->addr + TUL_XCntH);
+               outl(scb->bufptr, host->addr + TUL_XAddH);
+               outb(TAX_SG_IN, host->addr + TUL_XCmd);
        } else {
-               TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, pCurScb->SCB_BufLen);
-               TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
-               TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_IN);
+               outl(scb->buflen, host->addr + TUL_XCntH);
+               outl(scb->bufptr, host->addr + TUL_XAddH);
+               outb(TAX_X_IN, host->addr + TUL_XCmd);
        }
-       pCurScb->SCB_NxtStat = 0x5;
-       return (0);             /* return to OS, wait xfer done , let jas_isr come in */
+       scb->next_state = 0x5;
+       return 0;               /* return to OS, wait xfer done , let jas_isr come in */
 }
 
+/**
+ *     initio_xfer_data_out    -       Commence data output
+ *     @host: InitIO host in use
+ *
+ *     Commence a block of data transfer. The transfer itself will
+ *     be managed by the controller and we will get a completion (or
+ *     failure) interrupt.
+ */
 
-/***************************************************************************/
-int tul_xfer_data_out(HCS * pCurHcb)
+static int initio_xfer_data_out(struct initio_host * host)
 {
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
+       struct scsi_ctrl_blk *scb = host->active;
 
-       if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_DIN) {
-               return (6);     /* wrong direction */
-       }
-       TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, pCurScb->SCB_BufLen);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_DMA_OUT);
+       if ((scb->flags & SCF_DIR) == SCF_DIN)
+               return 6;       /* wrong direction */
 
-       if (pCurScb->SCB_Flags & SCF_SG) {      /* S/G xfer */
-               TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, ((ULONG) pCurScb->SCB_SGLen) << 3);
-               TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
-               TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_SG_OUT);
+       outl(scb->buflen, host->addr + TUL_SCnt0);
+       outb(TSC_XF_DMA_OUT, host->addr + TUL_SCmd);
+
+       if (scb->flags & SCF_SG) {      /* S/G xfer */
+               outl(((u32) scb->sglen) << 3, host->addr + TUL_XCntH);
+               outl(scb->bufptr, host->addr + TUL_XAddH);
+               outb(TAX_SG_OUT, host->addr + TUL_XCmd);
        } else {
-               TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, pCurScb->SCB_BufLen);
-               TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
-               TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_OUT);
+               outl(scb->buflen, host->addr + TUL_XCntH);
+               outl(scb->bufptr, host->addr + TUL_XAddH);
+               outb(TAX_X_OUT, host->addr + TUL_XCmd);
        }
 
-       pCurScb->SCB_NxtStat = 0x5;
-       return (0);             /* return to OS, wait xfer done , let jas_isr come in */
+       scb->next_state = 0x5;
+       return 0;               /* return to OS, wait xfer done , let jas_isr come in */
 }
 
-
-/***************************************************************************/
-int tul_xpad_in(HCS * pCurHcb)
+int initio_xpad_in(struct initio_host * host)
 {
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
-       TCS *pCurTcb = pCurHcb->HCS_ActTcs;
+       struct scsi_ctrl_blk *scb = host->active;
+       struct target_control *active_tc = host->active_tc;
 
-       if ((pCurScb->SCB_Flags & SCF_DIR) != SCF_NO_DCHK) {
-               pCurScb->SCB_HaStat = HOST_DO_DU;       /* over run             */
-       }
+       if ((scb->flags & SCF_DIR) != SCF_NO_DCHK)
+               scb->hastat = HOST_DO_DU;       /* over run             */
        for (;;) {
-               if (pCurTcb->TCS_JS_Period & TSC_WIDE_SCSI)
-                       TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 2);
+               if (active_tc->js_period & TSC_WIDE_SCSI)
+                       outl(2, host->addr + TUL_SCnt0);
                else
-                       TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
+                       outl(1, host->addr + TUL_SCnt0);
 
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
-               if ((wait_tulip(pCurHcb)) == -1) {
-                       return (-1);
+               outb(TSC_XF_FIFO_IN, host->addr + TUL_SCmd);
+               if (wait_tulip(host) == -1)
+                       return -1;
+               if (host->phase != DATA_IN) {
+                       outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
+                       return 6;
                }
-               if (pCurHcb->HCS_Phase != DATA_IN) {
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
-                       return (6);
-               }
-               TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
+               inb(host->addr + TUL_SFifo);
        }
 }
 
-int tul_xpad_out(HCS * pCurHcb)
+int initio_xpad_out(struct initio_host * host)
 {
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
-       TCS *pCurTcb = pCurHcb->HCS_ActTcs;
+       struct scsi_ctrl_blk *scb = host->active;
+       struct target_control *active_tc = host->active_tc;
 
-       if ((pCurScb->SCB_Flags & SCF_DIR) != SCF_NO_DCHK) {
-               pCurScb->SCB_HaStat = HOST_DO_DU;       /* over run             */
-       }
+       if ((scb->flags & SCF_DIR) != SCF_NO_DCHK)
+               scb->hastat = HOST_DO_DU;       /* over run             */
        for (;;) {
-               if (pCurTcb->TCS_JS_Period & TSC_WIDE_SCSI)
-                       TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 2);
+               if (active_tc->js_period & TSC_WIDE_SCSI)
+                       outl(2, host->addr + TUL_SCnt0);
                else
-                       TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
+                       outl(1, host->addr + TUL_SCnt0);
 
-               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 0);
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-               if ((wait_tulip(pCurHcb)) == -1) {
-                       return (-1);
-               }
-               if (pCurHcb->HCS_Phase != DATA_OUT) {   /* Disable wide CPU to allow read 16 bits */
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
-                       return (6);
+               outb(0, host->addr + TUL_SFifo);
+               outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+               if ((wait_tulip(host)) == -1)
+                       return -1;
+               if (host->phase != DATA_OUT) {  /* Disable wide CPU to allow read 16 bits */
+                       outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1);
+                       outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
+                       return 6;
                }
        }
 }
 
-
-/***************************************************************************/
-int tul_status_msg(HCS * pCurHcb)
+int initio_status_msg(struct initio_host * host)
 {                              /* status & MSG_IN */
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
-       BYTE msg;
+       struct scsi_ctrl_blk *scb = host->active;
+       u8 msg;
+
+       outb(TSC_CMD_COMP, host->addr + TUL_SCmd);
+       if (wait_tulip(host) == -1)
+               return -1;
 
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_CMD_COMP);
-       if ((wait_tulip(pCurHcb)) == -1) {
-               return (-1);
-       }
        /* get status */
-       pCurScb->SCB_TaStat = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
+       scb->tastat = inb(host->addr + TUL_SFifo);
 
-       if (pCurHcb->HCS_Phase == MSG_OUT) {
-               if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_PARITY);
-               } else {
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);
-               }
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-               return (wait_tulip(pCurHcb));
-       }
-       if (pCurHcb->HCS_Phase == MSG_IN) {
-               msg = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
-               if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {   /* Parity error                 */
-                       if ((tul_msgin_accept(pCurHcb)) == -1)
-                               return (-1);
-                       if (pCurHcb->HCS_Phase != MSG_OUT)
-                               return (tul_bad_seq(pCurHcb));
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_PARITY);
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-                       return (wait_tulip(pCurHcb));
+       if (host->phase == MSG_OUT) {
+               if (host->jsstatus0 & TSS_PAR_ERROR)
+                       outb(MSG_PARITY, host->addr + TUL_SFifo);
+               else
+                       outb(MSG_NOP, host->addr + TUL_SFifo);
+               outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+               return wait_tulip(host);
+       }
+       if (host->phase == MSG_IN) {
+               msg = inb(host->addr + TUL_SFifo);
+               if (host->jsstatus0 & TSS_PAR_ERROR) {  /* Parity error                 */
+                       if ((initio_msgin_accept(host)) == -1)
+                               return -1;
+                       if (host->phase != MSG_OUT)
+                               return initio_bad_seq(host);
+                       outb(MSG_PARITY, host->addr + TUL_SFifo);
+                       outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+                       return wait_tulip(host);
                }
                if (msg == 0) { /* Command complete             */
 
-                       if ((pCurScb->SCB_TaStat & 0x18) == 0x10) {     /* No link support              */
-                               return (tul_bad_seq(pCurHcb));
-                       }
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
-                       return tul_wait_done_disc(pCurHcb);
+                       if ((scb->tastat & 0x18) == 0x10)       /* No link support              */
+                               return initio_bad_seq(host);
+                       outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
+                       outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
+                       return initio_wait_done_disc(host);
 
                }
-               if ((msg == MSG_LINK_COMP) || (msg == MSG_LINK_FLAG)) {
-                       if ((pCurScb->SCB_TaStat & 0x18) == 0x10)
-                               return (tul_msgin_accept(pCurHcb));
+               if (msg == MSG_LINK_COMP || msg == MSG_LINK_FLAG) {
+                       if ((scb->tastat & 0x18) == 0x10)
+                               return initio_msgin_accept(host);
                }
        }
-       return (tul_bad_seq(pCurHcb));
+       return initio_bad_seq(host);
 }
 
 
-/***************************************************************************/
 /* scsi bus free */
-int int_tul_busfree(HCS * pCurHcb)
+int int_initio_busfree(struct initio_host * host)
 {
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
+       struct scsi_ctrl_blk *scb = host->active;
 
-       if (pCurScb != NULL) {
-               if (pCurScb->SCB_Status & SCB_SELECT) {         /* selection timeout */
-                       tul_unlink_pend_scb(pCurHcb, pCurScb);
-                       pCurScb->SCB_HaStat = HOST_SEL_TOUT;
-                       tul_append_done_scb(pCurHcb, pCurScb);
+       if (scb != NULL) {
+               if (scb->status & SCB_SELECT) {         /* selection timeout */
+                       initio_unlink_pend_scb(host, scb);
+                       scb->hastat = HOST_SEL_TOUT;
+                       initio_append_done_scb(host, scb);
                } else {        /* Unexpected bus free          */
-                       tul_unlink_busy_scb(pCurHcb, pCurScb);
-                       pCurScb->SCB_HaStat = HOST_BUS_FREE;
-                       tul_append_done_scb(pCurHcb, pCurScb);
+                       initio_unlink_busy_scb(host, scb);
+                       scb->hastat = HOST_BUS_FREE;
+                       initio_append_done_scb(host, scb);
                }
-               pCurHcb->HCS_ActScb = NULL;
-               pCurHcb->HCS_ActTcs = NULL;
+               host->active = NULL;
+               host->active_tc = NULL;
        }
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
-       TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
-       return (-1);
+       outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);          /* Flush SCSI FIFO  */
+       outb(TSC_INITDEFAULT, host->addr + TUL_SConfig);
+       outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1); /* Enable HW reselect       */
+       return -1;
 }
 
 
-/***************************************************************************/
-/* scsi bus reset */
-static int int_tul_scsi_rst(HCS * pCurHcb)
+/**
+ *     int_initio_scsi_rst     -       SCSI reset occurred
+ *     @host: Host seeing the reset
+ *
+ *     A SCSI bus reset has occurred. Clean up any pending transfer
+ *     the hardware is doing by DMA and then abort all active and
+ *     disconnected commands. The mid layer should sort the rest out
+ *     for us
+ */
+
+static int int_initio_scsi_rst(struct initio_host * host)
 {
-       SCB *pCurScb;
+       struct scsi_ctrl_blk *scb;
        int i;
 
        /* if DMA xfer is pending, abort DMA xfer */
-       if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & 0x01) {
-               TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT | TAX_X_CLR_FIFO);
+       if (inb(host->addr + TUL_XStatus) & 0x01) {
+               outb(TAX_X_ABT | TAX_X_CLR_FIFO, host->addr + TUL_XCmd);
                /* wait Abort DMA xfer done */
-               while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & 0x04) == 0);
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
+               while ((inb(host->addr + TUL_Int) & 0x04) == 0)
+                       cpu_relax();
+               outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
        }
        /* Abort all active & disconnected scb */
-       while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) {
-               pCurScb->SCB_HaStat = HOST_BAD_PHAS;
-               tul_append_done_scb(pCurHcb, pCurScb);
+       while ((scb = initio_pop_busy_scb(host)) != NULL) {
+               scb->hastat = HOST_BAD_PHAS;
+               initio_append_done_scb(host, scb);
        }
-       pCurHcb->HCS_ActScb = NULL;
-       pCurHcb->HCS_ActTcs = NULL;
+       host->active = NULL;
+       host->active_tc = NULL;
 
        /* clr sync nego. done flag */
-       for (i = 0; i < pCurHcb->HCS_MaxTar; i++) {
-               pCurHcb->HCS_Tcs[i].TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
-       }
-       return (-1);
+       for (i = 0; i < host->max_tar; i++)
+               host->targets[i].flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
+       return -1;
 }
 
+/**
+ *     int_initio_scsi_resel   -       Reselection occured
+ *     @host: InitIO host adapter
+ *
+ *     A SCSI reselection event has been signalled and the interrupt
+ *     is now being processed. Work out which command block needs attention
+ *     and continue processing that command.
+ */
 
-/***************************************************************************/
-/* scsi reselection */
-int int_tul_resel(HCS * pCurHcb)
+int int_initio_resel(struct initio_host * host)
 {
-       SCB *pCurScb;
-       TCS *pCurTcb;
-       BYTE tag, msg = 0;
-       BYTE tar, lun;
+       struct scsi_ctrl_blk *scb;
+       struct target_control *active_tc;
+       u8 tag, msg = 0;
+       u8 tar, lun;
 
-       if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) {
-               if (pCurScb->SCB_Status & SCB_SELECT) {         /* if waiting for selection complete */
-                       pCurScb->SCB_Status &= ~SCB_SELECT;
-               }
-               pCurHcb->HCS_ActScb = NULL;
+       if ((scb = host->active) != NULL) {
+               /* FIXME: Why check and not just clear ? */
+               if (scb->status & SCB_SELECT)           /* if waiting for selection complete */
+                       scb->status &= ~SCB_SELECT;
+               host->active = NULL;
        }
        /* --------- get target id---------------------- */
-       tar = TUL_RD(pCurHcb->HCS_Base, TUL_SBusId);
+       tar = inb(host->addr + TUL_SBusId);
        /* ------ get LUN from Identify message----------- */
-       lun = TUL_RD(pCurHcb->HCS_Base, TUL_SIdent) & 0x0F;
+       lun = inb(host->addr + TUL_SIdent) & 0x0F;
        /* 07/22/98 from 0x1F -> 0x0F */
-       pCurTcb = &pCurHcb->HCS_Tcs[tar];
-       pCurHcb->HCS_ActTcs = pCurTcb;
-       TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurTcb->TCS_JS_Period);
-
+       active_tc = &host->targets[tar];
+       host->active_tc = active_tc;
+       outb(active_tc->sconfig0, host->addr + TUL_SConfig);
+       outb(active_tc->js_period, host->addr + TUL_SPeriod);
 
        /* ------------- tag queueing ? ------------------- */
-       if (pCurTcb->TCS_DrvFlags & TCF_DRV_EN_TAG) {
-               if ((tul_msgin_accept(pCurHcb)) == -1)
-                       return (-1);
-               if (pCurHcb->HCS_Phase != MSG_IN)
+       if (active_tc->drv_flags & TCF_DRV_EN_TAG) {
+               if ((initio_msgin_accept(host)) == -1)
+                       return -1;
+               if (host->phase != MSG_IN)
                        goto no_tag;
-               TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
-               if ((wait_tulip(pCurHcb)) == -1)
-                       return (-1);
-               msg = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);     /* Read Tag Message    */
+               outl(1, host->addr + TUL_SCnt0);
+               outb(TSC_XF_FIFO_IN, host->addr + TUL_SCmd);
+               if (wait_tulip(host) == -1)
+                       return -1;
+               msg = inb(host->addr + TUL_SFifo);      /* Read Tag Message    */
 
-               if ((msg < MSG_STAG) || (msg > MSG_OTAG))       /* Is simple Tag      */
+               if (msg < MSG_STAG || msg > MSG_OTAG)           /* Is simple Tag      */
                        goto no_tag;
 
-               if ((tul_msgin_accept(pCurHcb)) == -1)
-                       return (-1);
+               if (initio_msgin_accept(host) == -1)
+                       return -1;
 
-               if (pCurHcb->HCS_Phase != MSG_IN)
+               if (host->phase != MSG_IN)
                        goto no_tag;
 
-               TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
-               if ((wait_tulip(pCurHcb)) == -1)
-                       return (-1);
-               tag = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);     /* Read Tag ID       */
-               pCurScb = pCurHcb->HCS_Scb + tag;
-               if ((pCurScb->SCB_Target != tar) || (pCurScb->SCB_Lun != lun)) {
-                       return tul_msgout_abort_tag(pCurHcb);
-               }
-               if (pCurScb->SCB_Status != SCB_BUSY) {  /* 03/24/95             */
-                       return tul_msgout_abort_tag(pCurHcb);
-               }
-               pCurHcb->HCS_ActScb = pCurScb;
-               if ((tul_msgin_accept(pCurHcb)) == -1)
-                       return (-1);
+               outl(1, host->addr + TUL_SCnt0);
+               outb(TSC_XF_FIFO_IN, host->addr + TUL_SCmd);
+               if (wait_tulip(host) == -1)
+                       return -1;
+               tag = inb(host->addr + TUL_SFifo);      /* Read Tag ID       */
+               scb = host->scb + tag;
+               if (scb->target != tar || scb->lun != lun) {
+                       return initio_msgout_abort_tag(host);
+               }
+               if (scb->status != SCB_BUSY) {  /* 03/24/95             */
+                       return initio_msgout_abort_tag(host);
+               }
+               host->active = scb;
+               if ((initio_msgin_accept(host)) == -1)
+                       return -1;
        } else {                /* No tag               */
              no_tag:
-               if ((pCurScb = tul_find_busy_scb(pCurHcb, tar | (lun << 8))) == NULL) {
-                       return tul_msgout_abort_targ(pCurHcb);
+               if ((scb = initio_find_busy_scb(host, tar | (lun << 8))) == NULL) {
+                       return initio_msgout_abort_targ(host);
                }
-               pCurHcb->HCS_ActScb = pCurScb;
-               if (!(pCurTcb->TCS_DrvFlags & TCF_DRV_EN_TAG)) {
-                       if ((tul_msgin_accept(pCurHcb)) == -1)
-                               return (-1);
+               host->active = scb;
+               if (!(active_tc->drv_flags & TCF_DRV_EN_TAG)) {
+                       if ((initio_msgin_accept(host)) == -1)
+                               return -1;
                }
        }
        return 0;
 }
 
+/**
+ *     int_initio_bad_seq              -       out of phase
+ *     @host: InitIO host flagging event
+ *
+ *     We have ended up out of phase somehow. Reset the host controller
+ *     and throw all our toys out of the pram. Let the midlayer clean up
+ */
 
-/***************************************************************************/
-static int int_tul_bad_seq(HCS * pCurHcb)
+static int int_initio_bad_seq(struct initio_host * host)
 {                              /* target wrong phase           */
-       SCB *pCurScb;
+       struct scsi_ctrl_blk *scb;
        int i;
 
-       tul_reset_scsi(pCurHcb, 10);
+       initio_reset_scsi(host, 10);
 
-       while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) {
-               pCurScb->SCB_HaStat = HOST_BAD_PHAS;
-               tul_append_done_scb(pCurHcb, pCurScb);
-       }
-       for (i = 0; i < pCurHcb->HCS_MaxTar; i++) {
-               pCurHcb->HCS_Tcs[i].TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
+       while ((scb = initio_pop_busy_scb(host)) != NULL) {
+               scb->hastat = HOST_BAD_PHAS;
+               initio_append_done_scb(host, scb);
        }
-       return (-1);
+       for (i = 0; i < host->max_tar; i++)
+               host->targets[i].flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
+       return -1;
 }
 
 
-/***************************************************************************/
-int tul_msgout_abort_targ(HCS * pCurHcb)
+/**
+ *     initio_msgout_abort_targ                -       abort a tag
+ *     @host: InitIO host
+ *
+ *     Abort when the target/lun does not match or when our SCB is not
+ *     busy. Used by untagged commands.
+ */
+
+static int initio_msgout_abort_targ(struct initio_host * host)
 {
 
-       TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
-       if (tul_msgin_accept(pCurHcb) == -1)
-               return (-1);
-       if (pCurHcb->HCS_Phase != MSG_OUT)
-               return (tul_bad_seq(pCurHcb));
+       outb(((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN), host->addr + TUL_SSignal);
+       if (initio_msgin_accept(host) == -1)
+               return -1;
+       if (host->phase != MSG_OUT)
+               return initio_bad_seq(host);
 
-       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_ABORT);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
+       outb(MSG_ABORT, host->addr + TUL_SFifo);
+       outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
 
-       return tul_wait_disc(pCurHcb);
+       return initio_wait_disc(host);
 }
 
-/***************************************************************************/
-int tul_msgout_abort_tag(HCS * pCurHcb)
+/**
+ *     initio_msgout_abort_tag         -       abort a tag
+ *     @host: InitIO host
+ *
+ *     Abort when the target/lun does not match or when our SCB is not
+ *     busy. Used for tagged commands.
+ */
+
+static int initio_msgout_abort_tag(struct initio_host * host)
 {
 
-       TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
-       if (tul_msgin_accept(pCurHcb) == -1)
-               return (-1);
-       if (pCurHcb->HCS_Phase != MSG_OUT)
-               return (tul_bad_seq(pCurHcb));
+       outb(((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN), host->addr + TUL_SSignal);
+       if (initio_msgin_accept(host) == -1)
+               return -1;
+       if (host->phase != MSG_OUT)
+               return initio_bad_seq(host);
 
-       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_ABORT_TAG);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
+       outb(MSG_ABORT_TAG, host->addr + TUL_SFifo);
+       outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
 
-       return tul_wait_disc(pCurHcb);
+       return initio_wait_disc(host);
 
 }
 
-/***************************************************************************/
-int tul_msgin(HCS * pCurHcb)
+/**
+ *     initio_msgin            -       Message in
+ *     @host: InitIO Host
+ *
+ *     Process incoming message
+ */
+static int initio_msgin(struct initio_host * host)
 {
-       TCS *pCurTcb;
+       struct target_control *active_tc;
 
        for (;;) {
+               outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
 
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
-
-               TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
-               if ((wait_tulip(pCurHcb)) == -1)
-                       return (-1);
+               outl(1, host->addr + TUL_SCnt0);
+               outb(TSC_XF_FIFO_IN, host->addr + TUL_SCmd);
+               if (wait_tulip(host) == -1)
+                       return -1;
 
-               switch (TUL_RD(pCurHcb->HCS_Base, TUL_SFifo)) {
+               switch (inb(host->addr + TUL_SFifo)) {
                case MSG_DISC:  /* Disconnect msg */
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
-
-                       return tul_wait_disc(pCurHcb);
-
+                       outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
+                       return initio_wait_disc(host);
                case MSG_SDP:
                case MSG_RESTORE:
                case MSG_NOP:
-                       tul_msgin_accept(pCurHcb);
+                       initio_msgin_accept(host);
                        break;
-
                case MSG_REJ:   /* Clear ATN first              */
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SSignal,
-                              (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)));
-                       pCurTcb = pCurHcb->HCS_ActTcs;
-                       if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {   /* do sync nego */
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
-                       }
-                       tul_msgin_accept(pCurHcb);
+                       outb((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)),
+                               host->addr + TUL_SSignal);
+                       active_tc = host->active_tc;
+                       if ((active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0)       /* do sync nego */
+                               outb(((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN),
+                                       host->addr + TUL_SSignal);
+                       initio_msgin_accept(host);
                        break;
-
                case MSG_EXTEND:        /* extended msg */
-                       tul_msgin_extend(pCurHcb);
+                       initio_msgin_extend(host);
                        break;
-
                case MSG_IGNOREWIDE:
-                       tul_msgin_accept(pCurHcb);
+                       initio_msgin_accept(host);
                        break;
-
-                       /* get */
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
-                       if (wait_tulip(pCurHcb) == -1)
-                               return -1;
-
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 0);       /* put pad  */
-                       TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);   /* get IGNORE field */
-                       TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);   /* get pad */
-
-                       tul_msgin_accept(pCurHcb);
-                       break;
-
                case MSG_COMP:
-                       {
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
-                               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
-                               return tul_wait_done_disc(pCurHcb);
-                       }
+                       outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
+                       outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
+                       return initio_wait_done_disc(host);
                default:
-                       tul_msgout_reject(pCurHcb);
+                       initio_msgout_reject(host);
                        break;
                }
-               if (pCurHcb->HCS_Phase != MSG_IN)
-                       return (pCurHcb->HCS_Phase);
+               if (host->phase != MSG_IN)
+                       return host->phase;
        }
        /* statement won't reach here */
 }
 
-
-
-
-/***************************************************************************/
-int tul_msgout_reject(HCS * pCurHcb)
+static int initio_msgout_reject(struct initio_host * host)
 {
+       outb(((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN), host->addr + TUL_SSignal);
 
-       TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
-
-       if ((tul_msgin_accept(pCurHcb)) == -1)
-               return (-1);
+       if (initio_msgin_accept(host) == -1)
+               return -1;
 
-       if (pCurHcb->HCS_Phase == MSG_OUT) {
-               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_REJ);         /* Msg reject           */
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-               return (wait_tulip(pCurHcb));
+       if (host->phase == MSG_OUT) {
+               outb(MSG_REJ, host->addr + TUL_SFifo);          /* Msg reject           */
+               outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+               return wait_tulip(host);
        }
-       return (pCurHcb->HCS_Phase);
+       return host->phase;
 }
 
-
-
-/***************************************************************************/
-int tul_msgout_ide(HCS * pCurHcb)
+static int initio_msgout_ide(struct initio_host * host)
 {
-       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_IDE);         /* Initiator Detected Error */
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-       return (wait_tulip(pCurHcb));
+       outb(MSG_IDE, host->addr + TUL_SFifo);          /* Initiator Detected Error */
+       outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+       return wait_tulip(host);
 }
 
-
-/***************************************************************************/
-int tul_msgin_extend(HCS * pCurHcb)
+static int initio_msgin_extend(struct initio_host * host)
 {
-       BYTE len, idx;
+       u8 len, idx;
 
-       if (tul_msgin_accept(pCurHcb) != MSG_IN)
-               return (pCurHcb->HCS_Phase);
+       if (initio_msgin_accept(host) != MSG_IN)
+               return host->phase;
 
        /* Get extended msg length      */
-       TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
-       if (wait_tulip(pCurHcb) == -1)
-               return (-1);
+       outl(1, host->addr + TUL_SCnt0);
+       outb(TSC_XF_FIFO_IN, host->addr + TUL_SCmd);
+       if (wait_tulip(host) == -1)
+               return -1;
 
-       len = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
-       pCurHcb->HCS_Msg[0] = len;
+       len = inb(host->addr + TUL_SFifo);
+       host->msg[0] = len;
        for (idx = 1; len != 0; len--) {
 
-               if ((tul_msgin_accept(pCurHcb)) != MSG_IN)
-                       return (pCurHcb->HCS_Phase);
-               TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
-               if (wait_tulip(pCurHcb) == -1)
-                       return (-1);
-               pCurHcb->HCS_Msg[idx++] = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
-       }
-       if (pCurHcb->HCS_Msg[1] == 1) {         /* if it's synchronous data transfer request */
-               if (pCurHcb->HCS_Msg[0] != 3)   /* if length is not right */
-                       return (tul_msgout_reject(pCurHcb));
-               if (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_SYNC_NEGO) {        /* Set OFFSET=0 to do async, nego back */
-                       pCurHcb->HCS_Msg[3] = 0;
+               if ((initio_msgin_accept(host)) != MSG_IN)
+                       return host->phase;
+               outl(1, host->addr + TUL_SCnt0);
+               outb(TSC_XF_FIFO_IN, host->addr + TUL_SCmd);
+               if (wait_tulip(host) == -1)
+                       return -1;
+               host->msg[idx++] = inb(host->addr + TUL_SFifo);
+       }
+       if (host->msg[1] == 1) {                /* if it's synchronous data transfer request */
+               u8 r;
+               if (host->msg[0] != 3)  /* if length is not right */
+                       return initio_msgout_reject(host);
+               if (host->active_tc->flags & TCF_NO_SYNC_NEGO) {        /* Set OFFSET=0 to do async, nego back */
+                       host->msg[3] = 0;
                } else {
-                       if ((tul_msgin_sync(pCurHcb) == 0) &&
-                           (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_SYNC_DONE)) {
-                               tul_sync_done(pCurHcb);
-                               return (tul_msgin_accept(pCurHcb));
+                       if (initio_msgin_sync(host) == 0 &&
+                           (host->active_tc->flags & TCF_SYNC_DONE)) {
+                               initio_sync_done(host);
+                               return initio_msgin_accept(host);
                        }
                }
 
-               TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
-               if ((tul_msgin_accept(pCurHcb)) != MSG_OUT)
-                       return (pCurHcb->HCS_Phase);
+               r = inb(host->addr + TUL_SSignal);
+               outb((r & (TSC_SET_ACK | 7)) | TSC_SET_ATN,
+                       host->addr + TUL_SSignal);
+               if (initio_msgin_accept(host) != MSG_OUT)
+                       return host->phase;
                /* sync msg out */
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
+               outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
 
-               tul_sync_done(pCurHcb);
+               initio_sync_done(host);
 
-               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
-               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);
-               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);
-               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[2]);
-               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[3]);
-
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-               return (wait_tulip(pCurHcb));
+               outb(MSG_EXTEND, host->addr + TUL_SFifo);
+               outb(3, host->addr + TUL_SFifo);
+               outb(1, host->addr + TUL_SFifo);
+               outb(host->msg[2], host->addr + TUL_SFifo);
+               outb(host->msg[3], host->addr + TUL_SFifo);
+               outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+               return wait_tulip(host);
        }
-       if ((pCurHcb->HCS_Msg[0] != 2) || (pCurHcb->HCS_Msg[1] != 3))
-               return (tul_msgout_reject(pCurHcb));
+       if (host->msg[0] != 2 || host->msg[1] != 3)
+               return initio_msgout_reject(host);
        /* if it's WIDE DATA XFER REQ   */
-       if (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_WDTR) {
-               pCurHcb->HCS_Msg[2] = 0;
+       if (host->active_tc->flags & TCF_NO_WDTR) {
+               host->msg[2] = 0;
        } else {
-               if (pCurHcb->HCS_Msg[2] > 2)    /* > 32 bits            */
-                       return (tul_msgout_reject(pCurHcb));
-               if (pCurHcb->HCS_Msg[2] == 2) {         /* == 32                */
-                       pCurHcb->HCS_Msg[2] = 1;
+               if (host->msg[2] > 2)   /* > 32 bits            */
+                       return initio_msgout_reject(host);
+               if (host->msg[2] == 2) {                /* == 32                */
+                       host->msg[2] = 1;
                } else {
-                       if ((pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_WDTR) == 0) {
-                               wdtr_done(pCurHcb);
-                               if ((pCurHcb->HCS_ActTcs->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0)
-                                       TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
-                               return (tul_msgin_accept(pCurHcb));
+                       if ((host->active_tc->flags & TCF_NO_WDTR) == 0) {
+                               wdtr_done(host);
+                               if ((host->active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0)
+                                       outb(((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN), host->addr + TUL_SSignal);
+                               return initio_msgin_accept(host);
                        }
                }
        }
-       TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
+       outb(((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN), host->addr + TUL_SSignal);
 
-       if (tul_msgin_accept(pCurHcb) != MSG_OUT)
-               return (pCurHcb->HCS_Phase);
+       if (initio_msgin_accept(host) != MSG_OUT)
+               return host->phase;
        /* WDTR msg out                 */
-       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 2);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[2]);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-       return (wait_tulip(pCurHcb));
+       outb(MSG_EXTEND, host->addr + TUL_SFifo);
+       outb(2, host->addr + TUL_SFifo);
+       outb(3, host->addr + TUL_SFifo);
+       outb(host->msg[2], host->addr + TUL_SFifo);
+       outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+       return wait_tulip(host);
 }
 
-/***************************************************************************/
-int tul_msgin_sync(HCS * pCurHcb)
+static int initio_msgin_sync(struct initio_host * host)
 {
        char default_period;
 
-       default_period = tul_rate_tbl[pCurHcb->HCS_ActTcs->TCS_Flags & TCF_SCSI_RATE];
-       if (pCurHcb->HCS_Msg[3] > MAX_OFFSET) {
-               pCurHcb->HCS_Msg[3] = MAX_OFFSET;
-               if (pCurHcb->HCS_Msg[2] < default_period) {
-                       pCurHcb->HCS_Msg[2] = default_period;
+       default_period = initio_rate_tbl[host->active_tc->flags & TCF_SCSI_RATE];
+       if (host->msg[3] > MAX_OFFSET) {
+               host->msg[3] = MAX_OFFSET;
+               if (host->msg[2] < default_period) {
+                       host->msg[2] = default_period;
                        return 1;
                }
-               if (pCurHcb->HCS_Msg[2] >= 59) {        /* Change to async              */
-                       pCurHcb->HCS_Msg[3] = 0;
-               }
+               if (host->msg[2] >= 59) /* Change to async              */
+                       host->msg[3] = 0;
                return 1;
        }
        /* offset requests asynchronous transfers ? */
-       if (pCurHcb->HCS_Msg[3] == 0) {
+       if (host->msg[3] == 0) {
                return 0;
        }
-       if (pCurHcb->HCS_Msg[2] < default_period) {
-               pCurHcb->HCS_Msg[2] = default_period;
+       if (host->msg[2] < default_period) {
+               host->msg[2] = default_period;
                return 1;
        }
-       if (pCurHcb->HCS_Msg[2] >= 59) {
-               pCurHcb->HCS_Msg[3] = 0;
+       if (host->msg[2] >= 59) {
+               host->msg[3] = 0;
                return 1;
        }
        return 0;
 }
 
-
-/***************************************************************************/
-int wdtr_done(HCS * pCurHcb)
+static int wdtr_done(struct initio_host * host)
 {
-       pCurHcb->HCS_ActTcs->TCS_Flags &= ~TCF_SYNC_DONE;
-       pCurHcb->HCS_ActTcs->TCS_Flags |= TCF_WDTR_DONE;
+       host->active_tc->flags &= ~TCF_SYNC_DONE;
+       host->active_tc->flags |= TCF_WDTR_DONE;
 
-       pCurHcb->HCS_ActTcs->TCS_JS_Period = 0;
-       if (pCurHcb->HCS_Msg[2]) {      /* if 16 bit */
-               pCurHcb->HCS_ActTcs->TCS_JS_Period |= TSC_WIDE_SCSI;
-       }
-       pCurHcb->HCS_ActTcs->TCS_SConfig0 &= ~TSC_ALT_PERIOD;
-       TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_ActTcs->TCS_SConfig0);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurHcb->HCS_ActTcs->TCS_JS_Period);
+       host->active_tc->js_period = 0;
+       if (host->msg[2])       /* if 16 bit */
+               host->active_tc->js_period |= TSC_WIDE_SCSI;
+       host->active_tc->sconfig0 &= ~TSC_ALT_PERIOD;
+       outb(host->active_tc->sconfig0, host->addr + TUL_SConfig);
+       outb(host->active_tc->js_period, host->addr + TUL_SPeriod);
 
        return 1;
 }
 
-/***************************************************************************/
-int tul_sync_done(HCS * pCurHcb)
+static int initio_sync_done(struct initio_host * host)
 {
        int i;
 
-       pCurHcb->HCS_ActTcs->TCS_Flags |= TCF_SYNC_DONE;
+       host->active_tc->flags |= TCF_SYNC_DONE;
 
-       if (pCurHcb->HCS_Msg[3]) {
-               pCurHcb->HCS_ActTcs->TCS_JS_Period |= pCurHcb->HCS_Msg[3];
+       if (host->msg[3]) {
+               host->active_tc->js_period |= host->msg[3];
                for (i = 0; i < 8; i++) {
-                       if (tul_rate_tbl[i] >= pCurHcb->HCS_Msg[2])     /* pick the big one */
+                       if (initio_rate_tbl[i] >= host->msg[2]) /* pick the big one */
                                break;
                }
-               pCurHcb->HCS_ActTcs->TCS_JS_Period |= (i << 4);
-               pCurHcb->HCS_ActTcs->TCS_SConfig0 |= TSC_ALT_PERIOD;
+               host->active_tc->js_period |= (i << 4);
+               host->active_tc->sconfig0 |= TSC_ALT_PERIOD;
        }
-       TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_ActTcs->TCS_SConfig0);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurHcb->HCS_ActTcs->TCS_JS_Period);
+       outb(host->active_tc->sconfig0, host->addr + TUL_SConfig);
+       outb(host->active_tc->js_period, host->addr + TUL_SPeriod);
 
-       return (-1);
+       return -1;
 }
 
 
-int tul_post_scsi_rst(HCS * pCurHcb)
+static int initio_post_scsi_rst(struct initio_host * host)
 {
-       SCB *pCurScb;
-       TCS *pCurTcb;
+       struct scsi_ctrl_blk *scb;
+       struct target_control *active_tc;
        int i;
 
-       pCurHcb->HCS_ActScb = NULL;
-       pCurHcb->HCS_ActTcs = NULL;
-       pCurHcb->HCS_Flags = 0;
+       host->active = NULL;
+       host->active_tc = NULL;
+       host->flags = 0;
 
-       while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) {
-               pCurScb->SCB_HaStat = HOST_BAD_PHAS;
-               tul_append_done_scb(pCurHcb, pCurScb);
+       while ((scb = initio_pop_busy_scb(host)) != NULL) {
+               scb->hastat = HOST_BAD_PHAS;
+               initio_append_done_scb(host, scb);
        }
        /* clear sync done flag         */
-       pCurTcb = &pCurHcb->HCS_Tcs[0];
-       for (i = 0; i < pCurHcb->HCS_MaxTar; pCurTcb++, i++) {
-               pCurTcb->TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
+       active_tc = &host->targets[0];
+       for (i = 0; i < host->max_tar; active_tc++, i++) {
+               active_tc->flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
                /* Initialize the sync. xfer register values to an asyn xfer */
-               pCurTcb->TCS_JS_Period = 0;
-               pCurTcb->TCS_SConfig0 = pCurHcb->HCS_SConf1;
-               pCurHcb->HCS_ActTags[0] = 0;    /* 07/22/98 */
-               pCurHcb->HCS_Tcs[i].TCS_Flags &= ~TCF_BUSY;     /* 07/22/98 */
+               active_tc->js_period = 0;
+               active_tc->sconfig0 = host->sconf1;
+               host->act_tags[0] = 0;  /* 07/22/98 */
+               host->targets[i].flags &= ~TCF_BUSY;    /* 07/22/98 */
        }                       /* for */
 
-       return (-1);
+       return -1;
 }
 
-/***************************************************************************/
-void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb)
+static void initio_select_atn_stop(struct initio_host * host, struct scsi_ctrl_blk * scb)
 {
-       pCurScb->SCB_Status |= SCB_SELECT;
-       pCurScb->SCB_NxtStat = 0x1;
-       pCurHcb->HCS_ActScb = pCurScb;
-       pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SELATNSTOP);
-       return;
+       scb->status |= SCB_SELECT;
+       scb->next_state = 0x1;
+       host->active = scb;
+       host->active_tc = &host->targets[scb->target];
+       outb(TSC_SELATNSTOP, host->addr + TUL_SCmd);
 }
 
 
-/***************************************************************************/
-void tul_select_atn(HCS * pCurHcb, SCB * pCurScb)
+static void initio_select_atn(struct initio_host * host, struct scsi_ctrl_blk * scb)
 {
        int i;
 
-       pCurScb->SCB_Status |= SCB_SELECT;
-       pCurScb->SCB_NxtStat = 0x2;
+       scb->status |= SCB_SELECT;
+       scb->next_state = 0x2;
 
-       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident);
-       for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++)
-               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]);
-       pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
-       pCurHcb->HCS_ActScb = pCurScb;
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SEL_ATN);
-       return;
+       outb(scb->ident, host->addr + TUL_SFifo);
+       for (i = 0; i < (int) scb->cdblen; i++)
+               outb(scb->cdb[i], host->addr + TUL_SFifo);
+       host->active_tc = &host->targets[scb->target];
+       host->active = scb;
+       outb(TSC_SEL_ATN, host->addr + TUL_SCmd);
 }
 
-/***************************************************************************/
-void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb)
+static void initio_select_atn3(struct initio_host * host, struct scsi_ctrl_blk * scb)
 {
        int i;
 
-       pCurScb->SCB_Status |= SCB_SELECT;
-       pCurScb->SCB_NxtStat = 0x2;
-
-       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagMsg);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagId);
-       for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++)
-               TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]);
-       pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
-       pCurHcb->HCS_ActScb = pCurScb;
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SEL_ATN3);
-       return;
+       scb->status |= SCB_SELECT;
+       scb->next_state = 0x2;
+
+       outb(scb->ident, host->addr + TUL_SFifo);
+       outb(scb->tagmsg, host->addr + TUL_SFifo);
+       outb(scb->tagid, host->addr + TUL_SFifo);
+       for (i = 0; i < scb->cdblen; i++)
+               outb(scb->cdb[i], host->addr + TUL_SFifo);
+       host->active_tc = &host->targets[scb->target];
+       host->active = scb;
+       outb(TSC_SEL_ATN3, host->addr + TUL_SCmd);
 }
 
-/***************************************************************************/
-/* SCSI Bus Device Reset */
-int tul_bus_device_reset(HCS * pCurHcb)
+/**
+ *     initio_bus_device_reset -        SCSI Bus Device Reset
+ *     @host: InitIO host to reset
+ *
+ *     Perform a device reset and abort all pending SCBs for the
+ *     victim device
+ */
+int initio_bus_device_reset(struct initio_host * host)
 {
-       SCB *pCurScb = pCurHcb->HCS_ActScb;
-       TCS *pCurTcb = pCurHcb->HCS_ActTcs;
-       SCB *pTmpScb, *pPrevScb;
-       BYTE tar;
+       struct scsi_ctrl_blk *scb = host->active;
+       struct target_control *active_tc = host->active_tc;
+       struct scsi_ctrl_blk *tmp, *prev;
+       u8 tar;
 
-       if (pCurHcb->HCS_Phase != MSG_OUT) {
-               return (int_tul_bad_seq(pCurHcb));      /* Unexpected phase             */
-       }
-       tul_unlink_pend_scb(pCurHcb, pCurScb);
-       tul_release_scb(pCurHcb, pCurScb);
+       if (host->phase != MSG_OUT)
+               return int_initio_bad_seq(host);        /* Unexpected phase */
+
+       initio_unlink_pend_scb(host, scb);
+       initio_release_scb(host, scb);
 
 
-       tar = pCurScb->SCB_Target;      /* target                       */
-       pCurTcb->TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE | TCF_BUSY);
+       tar = scb->target;      /* target                       */
+       active_tc->flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE | TCF_BUSY);
        /* clr sync. nego & WDTR flags  07/22/98 */
 
        /* abort all SCB with same target */
-       pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;    /* Check Busy queue */
-       while (pTmpScb != NULL) {
-
-               if (pTmpScb->SCB_Target == tar) {
+       prev = tmp = host->first_busy;  /* Check Busy queue */
+       while (tmp != NULL) {
+               if (tmp->target == tar) {
                        /* unlink it */
-                       if (pTmpScb == pCurHcb->HCS_FirstBusy) {
-                               if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
-                                       pCurHcb->HCS_LastBusy = NULL;
+                       if (tmp == host->first_busy) {
+                               if ((host->first_busy = tmp->next) == NULL)
+                                       host->last_busy = NULL;
                        } else {
-                               pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
-                               if (pTmpScb == pCurHcb->HCS_LastBusy)
-                                       pCurHcb->HCS_LastBusy = pPrevScb;
+                               prev->next = tmp->next;
+                               if (tmp == host->last_busy)
+                                       host->last_busy = prev;
                        }
-                       pTmpScb->SCB_HaStat = HOST_ABORTED;
-                       tul_append_done_scb(pCurHcb, pTmpScb);
+                       tmp->hastat = HOST_ABORTED;
+                       initio_append_done_scb(host, tmp);
                }
                /* Previous haven't change      */
                else {
-                       pPrevScb = pTmpScb;
+                       prev = tmp;
                }
-               pTmpScb = pTmpScb->SCB_NxtScb;
+               tmp = tmp->next;
        }
-
-       TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_DEVRST);
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
-
-       return tul_wait_disc(pCurHcb);
+       outb(MSG_DEVRST, host->addr + TUL_SFifo);
+       outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
+       return initio_wait_disc(host);
 
 }
 
-/***************************************************************************/
-int tul_msgin_accept(HCS * pCurHcb)
+static int initio_msgin_accept(struct initio_host * host)
 {
-       TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
-       return (wait_tulip(pCurHcb));
+       outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
+       return wait_tulip(host);
 }
 
-/***************************************************************************/
-int wait_tulip(HCS * pCurHcb)
+static int wait_tulip(struct initio_host * host)
 {
 
-       while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0))
-                & TSS_INT_PENDING));
+       while (!((host->jsstatus0 = inb(host->addr + TUL_SStatus0))
+                & TSS_INT_PENDING))
+                       cpu_relax();
 
-       pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
-       pCurHcb->HCS_Phase = pCurHcb->HCS_JSStatus0 & TSS_PH_MASK;
-       pCurHcb->HCS_JSStatus1 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1);
+       host->jsint = inb(host->addr + TUL_SInt);
+       host->phase = host->jsstatus0 & TSS_PH_MASK;
+       host->jsstatus1 = inb(host->addr + TUL_SStatus1);
 
-       if (pCurHcb->HCS_JSInt & TSS_RESEL_INT) {       /* if SCSI bus reset detected   */
-               return (int_tul_resel(pCurHcb));
-       }
-       if (pCurHcb->HCS_JSInt & TSS_SEL_TIMEOUT) {     /* if selected/reselected timeout interrupt */
-               return (int_tul_busfree(pCurHcb));
-       }
-       if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) {     /* if SCSI bus reset detected   */
-               return (int_tul_scsi_rst(pCurHcb));
-       }
-       if (pCurHcb->HCS_JSInt & TSS_DISC_INT) {        /* BUS disconnection            */
-               if (pCurHcb->HCS_Flags & HCF_EXPECT_DONE_DISC) {
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
-                       tul_unlink_busy_scb(pCurHcb, pCurHcb->HCS_ActScb);
-                       pCurHcb->HCS_ActScb->SCB_HaStat = 0;
-                       tul_append_done_scb(pCurHcb, pCurHcb->HCS_ActScb);
-                       pCurHcb->HCS_ActScb = NULL;
-                       pCurHcb->HCS_ActTcs = NULL;
-                       pCurHcb->HCS_Flags &= ~HCF_EXPECT_DONE_DISC;
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
-                       return (-1);
+       if (host->jsint & TSS_RESEL_INT)        /* if SCSI bus reset detected */
+               return int_initio_resel(host);
+       if (host->jsint & TSS_SEL_TIMEOUT)      /* if selected/reselected timeout interrupt */
+               return int_initio_busfree(host);
+       if (host->jsint & TSS_SCSIRST_INT)      /* if SCSI bus reset detected   */
+               return int_initio_scsi_rst(host);
+
+       if (host->jsint & TSS_DISC_INT) {       /* BUS disconnection            */
+               if (host->flags & HCF_EXPECT_DONE_DISC) {
+                       outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0); /* Flush SCSI FIFO */
+                       initio_unlink_busy_scb(host, host->active);
+                       host->active->hastat = 0;
+                       initio_append_done_scb(host, host->active);
+                       host->active = NULL;
+                       host->active_tc = NULL;
+                       host->flags &= ~HCF_EXPECT_DONE_DISC;
+                       outb(TSC_INITDEFAULT, host->addr + TUL_SConfig);
+                       outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1); /* Enable HW reselect */
+                       return -1;
                }
-               if (pCurHcb->HCS_Flags & HCF_EXPECT_DISC) {
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
-                       pCurHcb->HCS_ActScb = NULL;
-                       pCurHcb->HCS_ActTcs = NULL;
-                       pCurHcb->HCS_Flags &= ~HCF_EXPECT_DISC;
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
-                       TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
-                       return (-1);
+               if (host->flags & HCF_EXPECT_DISC) {
+                       outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0); /* Flush SCSI FIFO */
+                       host->active = NULL;
+                       host->active_tc = NULL;
+                       host->flags &= ~HCF_EXPECT_DISC;
+                       outb(TSC_INITDEFAULT, host->addr + TUL_SConfig);
+                       outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1); /* Enable HW reselect */
+                       return -1;
                }
-               return (int_tul_busfree(pCurHcb));
-       }
-       if (pCurHcb->HCS_JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) {
-               return (pCurHcb->HCS_Phase);
+               return int_initio_busfree(host);
        }
-       return (pCurHcb->HCS_Phase);
+       /* The old code really does the below. Can probably be removed */
+       if (host->jsint & (TSS_FUNC_COMP | TSS_BUS_SERV))
+               return host->phase;
+       return host->phase;
 }
-/***************************************************************************/
-int tul_wait_disc(HCS * pCurHcb)
-{
-
-       while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0))
-                & TSS_INT_PENDING));
 
+static int initio_wait_disc(struct initio_host * host)
+{
+       while (!((host->jsstatus0 = inb(host->addr + TUL_SStatus0)) & TSS_INT_PENDING))
+               cpu_relax();
 
-       pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
+       host->jsint = inb(host->addr + TUL_SInt);
 
-       if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) {     /* if SCSI bus reset detected   */
-               return (int_tul_scsi_rst(pCurHcb));
-       }
-       if (pCurHcb->HCS_JSInt & TSS_DISC_INT) {        /* BUS disconnection            */
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
-               TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
-               pCurHcb->HCS_ActScb = NULL;
-               return (-1);
+       if (host->jsint & TSS_SCSIRST_INT)      /* if SCSI bus reset detected */
+               return int_initio_scsi_rst(host);
+       if (host->jsint & TSS_DISC_INT) {       /* BUS disconnection */
+               outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0); /* Flush SCSI FIFO */
+               outb(TSC_INITDEFAULT, host->addr + TUL_SConfig);
+               outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1); /* Enable HW reselect */
+               host->active = NULL;
+               return -1;
        }
-       return (tul_bad_seq(pCurHcb));
+       return initio_bad_seq(host);
 }
 
-/***************************************************************************/
-int tul_wait_done_disc(HCS * pCurHcb)
+static int initio_wait_done_disc(struct initio_host * host)
 {
+       while (!((host->jsstatus0 = inb(host->addr + TUL_SStatus0))
+                & TSS_INT_PENDING))
+                cpu_relax();
 
+       host->jsint = inb(host->addr + TUL_SInt);
 
-       while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0))
-                & TSS_INT_PENDING));
-
-       pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
-
-
-       if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) {     /* if SCSI bus reset detected   */
-               return (int_tul_scsi_rst(pCurHcb));
-       }
-       if (pCurHcb->HCS_JSInt & TSS_DISC_INT) {        /* BUS disconnection            */
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
-               TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
-               TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
-               tul_unlink_busy_scb(pCurHcb, pCurHcb->HCS_ActScb);
+       if (host->jsint & TSS_SCSIRST_INT)      /* if SCSI bus reset detected */
+               return int_initio_scsi_rst(host);
+       if (host->jsint & TSS_DISC_INT) {       /* BUS disconnection */
+               outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);          /* Flush SCSI FIFO */
+               outb(TSC_INITDEFAULT, host->addr + TUL_SConfig);
+               outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1);         /* Enable HW reselect */
+               initio_unlink_busy_scb(host, host->active);
 
-               tul_append_done_scb(pCurHcb, pCurHcb->HCS_ActScb);
-               pCurHcb->HCS_ActScb = NULL;
-               return (-1);
+               initio_append_done_scb(host, host->active);
+               host->active = NULL;
+               return -1;
        }
-       return (tul_bad_seq(pCurHcb));
+       return initio_bad_seq(host);
 }
 
+/**
+ *     i91u_intr               -       IRQ handler
+ *     @irqno: IRQ number
+ *     @dev_id: IRQ identifier
+ *
+ *     Take the relevant locks and then invoke the actual isr processing
+ *     code under the lock.
+ */
+
 static irqreturn_t i91u_intr(int irqno, void *dev_id)
 {
        struct Scsi_Host *dev = dev_id;
        unsigned long flags;
+       int r;
        
        spin_lock_irqsave(dev->host_lock, flags);
-       tul_isr((HCS *)dev->base);
+       r = initio_isr((struct initio_host *)dev->hostdata);
        spin_unlock_irqrestore(dev->host_lock, flags);
-       return IRQ_HANDLED;
-}
-
-static int tul_NewReturnNumberOfAdapters(void)
-{
-       struct pci_dev *pDev = NULL;    /* Start from none              */
-       int iAdapters = 0;
-       long dRegValue;
-       WORD wBIOS;
-       int i = 0;
-
-       init_i91uAdapter_table();
-
-       for (i = 0; i < ARRAY_SIZE(i91u_pci_devices); i++)
-       {
-               while ((pDev = pci_find_device(i91u_pci_devices[i].vendor, i91u_pci_devices[i].device, pDev)) != NULL) {
-                       if (pci_enable_device(pDev))
-                               continue;
-                       pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue);
-                       wBIOS = (UWORD) (dRegValue & 0xFF);
-                       if (((dRegValue & 0xFF00) >> 8) == 0xFF)
-                               dRegValue = 0;
-                       wBIOS = (wBIOS << 8) + ((UWORD) ((dRegValue & 0xFF00) >> 8));
-                       if (pci_set_dma_mask(pDev, DMA_32BIT_MASK)) {
-                               printk(KERN_WARNING 
-                                      "i91u: Could not set 32 bit DMA mask\n");
-                               continue;
-                       }
-
-                       if (Addi91u_into_Adapter_table(wBIOS,
-                                                       (pDev->resource[0].start),
-                                                       pDev->irq,
-                                                       pDev->bus->number,
-                                                       (pDev->devfn >> 3)
-                               ) == 0)
-                               iAdapters++;
-               }
-       }
-
-       return (iAdapters);
+       if (r)
+               return IRQ_HANDLED;
+       else
+               return IRQ_NONE;
 }
 
-static int i91u_detect(struct scsi_host_template * tpnt)
-{
-       HCS *pHCB;
-       struct Scsi_Host *hreg;
-       unsigned long i;        /* 01/14/98                     */
-       int ok = 0, iAdapters;
-       ULONG dBiosAdr;
-       BYTE *pbBiosAdr;
-
-       /* Get total number of adapters in the motherboard */
-       iAdapters = tul_NewReturnNumberOfAdapters();
-       if (iAdapters == 0)     /* If no tulip founded, return */
-               return (0);
-
-       tul_num_ch = (iAdapters > tul_num_ch) ? tul_num_ch : iAdapters;
-       /* Update actually channel number */
-       if (tul_tag_enable) {   /* 1.01i                  */
-               tul_num_scb = MAX_TARGETS * i91u_MAXQUEUE;
-       } else {
-               tul_num_scb = MAX_TARGETS + 3;  /* 1-tape, 1-CD_ROM, 1- extra */
-       }                       /* Update actually SCBs per adapter */
-
-       /* Get total memory needed for HCS */
-       i = tul_num_ch * sizeof(HCS);
-       memset((unsigned char *) &tul_hcs[0], 0, i);    /* Initialize tul_hcs 0 */
-       /* Get total memory needed for SCB */
-
-       for (; tul_num_scb >= MAX_TARGETS + 3; tul_num_scb--) {
-               i = tul_num_ch * tul_num_scb * sizeof(SCB);
-               if ((tul_scb = kmalloc(i, GFP_ATOMIC | GFP_DMA)) != NULL)
-                       break;
-       }
-       if (tul_scb == NULL) {
-               printk("i91u: SCB memory allocation error\n");
-               return (0);
-       }
-       memset((unsigned char *) tul_scb, 0, i);
 
-       for (i = 0, pHCB = &tul_hcs[0];         /* Get pointer for control block */
-            i < tul_num_ch;
-            i++, pHCB++) {
-               get_tulipPCIConfig(pHCB, i);
-
-               dBiosAdr = pHCB->HCS_BIOS;
-               dBiosAdr = (dBiosAdr << 4);
-
-               pbBiosAdr = phys_to_virt(dBiosAdr);
-
-               init_tulip(pHCB, tul_scb + (i * tul_num_scb), tul_num_scb, pbBiosAdr, 10);
-               request_region(pHCB->HCS_Base, 256, "i91u"); /* Register */ 
-
-               pHCB->HCS_Index = i;    /* 7/29/98 */
-               hreg = scsi_register(tpnt, sizeof(HCS));
-               if(hreg == NULL) {
-                       release_region(pHCB->HCS_Base, 256);
-                       return 0;
-               }
-               hreg->io_port = pHCB->HCS_Base;
-               hreg->n_io_port = 0xff;
-               hreg->can_queue = tul_num_scb;  /* 03/05/98                      */
-               hreg->unique_id = pHCB->HCS_Base;
-               hreg->max_id = pHCB->HCS_MaxTar;
-               hreg->max_lun = 32;     /* 10/21/97                     */
-               hreg->irq = pHCB->HCS_Intr;
-               hreg->this_id = pHCB->HCS_SCSI_ID;      /* Assign HCS index           */
-               hreg->base = (unsigned long)pHCB;
-               hreg->sg_tablesize = TOTAL_SG_ENTRY;    /* Maximun support is 32 */
-
-               /* Initial tulip chip           */
-               ok = request_irq(pHCB->HCS_Intr, i91u_intr, IRQF_DISABLED | IRQF_SHARED, "i91u", hreg);
-               if (ok < 0) {
-                       printk(KERN_WARNING "i91u: unable to request IRQ %d\n\n", pHCB->HCS_Intr);
-                       return 0;
-               }
-       }
-
-       tpnt->this_id = -1;
-       tpnt->can_queue = 1;
-
-       return 1;
-}
+/**
+ *     initio_build_scb                -       Build the mappings and SCB
+ *     @host: InitIO host taking the command
+ *     @cblk: Firmware command block
+ *     @cmnd: SCSI midlayer command block
+ *
+ *     Translate the abstract SCSI command into a firmware command block
+ *     suitable for feeding to the InitIO host controller. This also requires
+ *     we build the scatter gather lists and ensure they are mapped properly.
+ */
 
-static void i91uBuildSCB(HCS * pHCB, SCB * pSCB, struct scsi_cmnd * SCpnt)
+static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * cblk, struct scsi_cmnd * cmnd)
 {                              /* Create corresponding SCB     */
-       struct scatterlist *pSrbSG;
-       SG *pSG;                /* Pointer to SG list           */
-       int i;
-       long TotalLen;
+       struct scatterlist *sglist;
+       struct sg_entry *sg;            /* Pointer to SG list           */
+       int i, nseg;
+       long total_len;
        dma_addr_t dma_addr;
 
-       pSCB->SCB_Post = i91uSCBPost;   /* i91u's callback routine      */
-       pSCB->SCB_Srb = SCpnt;
-       pSCB->SCB_Opcode = ExecSCSI;
-       pSCB->SCB_Flags = SCF_POST;     /* After SCSI done, call post routine */
-       pSCB->SCB_Target = SCpnt->device->id;
-       pSCB->SCB_Lun = SCpnt->device->lun;
-       pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW;
-
-       pSCB->SCB_Flags |= SCF_SENSE;   /* Turn on auto request sense   */
-       dma_addr = dma_map_single(&pHCB->pci_dev->dev, SCpnt->sense_buffer,
-                                 SENSE_SIZE, DMA_FROM_DEVICE);
-       pSCB->SCB_SensePtr = cpu_to_le32((u32)dma_addr);
-       pSCB->SCB_SenseLen = cpu_to_le32(SENSE_SIZE);
-       SCpnt->SCp.ptr = (char *)(unsigned long)dma_addr;
+       /* Fill in the command headers */
+       cblk->post = i91uSCBPost;       /* i91u's callback routine      */
+       cblk->srb = cmnd;
+       cblk->opcode = ExecSCSI;
+       cblk->flags = SCF_POST; /* After SCSI done, call post routine */
+       cblk->target = cmnd->device->id;
+       cblk->lun = cmnd->device->lun;
+       cblk->ident = cmnd->device->lun | DISC_ALLOW;
 
-       pSCB->SCB_CDBLen = SCpnt->cmd_len;
-       pSCB->SCB_HaStat = 0;
-       pSCB->SCB_TaStat = 0;
-       memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, SCpnt->cmd_len);
+       cblk->flags |= SCF_SENSE;       /* Turn on auto request sense   */
 
-       if (SCpnt->device->tagged_supported) {  /* Tag Support                  */
-               pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG;    /* Do simple tag only   */
+       /* Map the sense buffer into bus memory */
+       dma_addr = dma_map_single(&host->pci_dev->dev, cmnd->sense_buffer,
+                                 SENSE_SIZE, DMA_FROM_DEVICE);
+       cblk->senseptr = cpu_to_le32((u32)dma_addr);
+       cblk->senselen = cpu_to_le32(SENSE_SIZE);
+       cmnd->SCp.ptr = (char *)(unsigned long)dma_addr;
+       cblk->cdblen = cmnd->cmd_len;
+
+       /* Clear the returned status */
+       cblk->hastat = 0;
+       cblk->tastat = 0;
+       /* Command the command */
+       memcpy(&cblk->cdb[0], &cmnd->cmnd, cmnd->cmd_len);
+
+       /* Set up tags */
+       if (cmnd->device->tagged_supported) {   /* Tag Support                  */
+               cblk->tagmsg = SIMPLE_QUEUE_TAG;        /* Do simple tag only   */
        } else {
-               pSCB->SCB_TagMsg = 0;   /* No tag support               */
+               cblk->tagmsg = 0;       /* No tag support               */
        }
+
        /* todo handle map_sg error */
-       if (SCpnt->use_sg) {
-               dma_addr = dma_map_single(&pHCB->pci_dev->dev, &pSCB->SCB_SGList[0],
-                                         sizeof(struct SG_Struc) * TOTAL_SG_ENTRY,
+       nseg = scsi_dma_map(cmnd);
+       BUG_ON(nseg < 0);
+       if (nseg) {
+               dma_addr = dma_map_single(&host->pci_dev->dev, &cblk->sglist[0],
+                                         sizeof(struct sg_entry) * TOTAL_SG_ENTRY,
                                          DMA_BIDIRECTIONAL);
-               pSCB->SCB_BufPtr = cpu_to_le32((u32)dma_addr);
-               SCpnt->SCp.dma_handle = dma_addr;
-
-               pSrbSG = (struct scatterlist *) SCpnt->request_buffer;
-               pSCB->SCB_SGLen = dma_map_sg(&pHCB->pci_dev->dev, pSrbSG,
-                                            SCpnt->use_sg, SCpnt->sc_data_direction);
-
-               pSCB->SCB_Flags |= SCF_SG;      /* Turn on SG list flag       */
-               for (i = 0, TotalLen = 0, pSG = &pSCB->SCB_SGList[0];   /* 1.01g */
-                    i < pSCB->SCB_SGLen; i++, pSG++, pSrbSG++) {
-                       pSG->SG_Ptr = cpu_to_le32((u32)sg_dma_address(pSrbSG));
-                       TotalLen += pSG->SG_Len = cpu_to_le32((u32)sg_dma_len(pSrbSG));
+               cblk->bufptr = cpu_to_le32((u32)dma_addr);
+               cmnd->SCp.dma_handle = dma_addr;
+
+
+               cblk->flags |= SCF_SG;  /* Turn on SG list flag       */
+               total_len = 0;
+               sg = &cblk->sglist[0];
+               scsi_for_each_sg(cmnd, sglist, cblk->sglen, i) {
+                       sg->data = cpu_to_le32((u32)sg_dma_address(sglist));
+                       total_len += sg->len = cpu_to_le32((u32)sg_dma_len(sglist));
                }
 
-               pSCB->SCB_BufLen = (SCpnt->request_bufflen > TotalLen) ?
-                   TotalLen : SCpnt->request_bufflen;
-       } else if (SCpnt->request_bufflen) {            /* Non SG */
-               dma_addr = dma_map_single(&pHCB->pci_dev->dev, SCpnt->request_buffer,
-                                         SCpnt->request_bufflen,
-                                         SCpnt->sc_data_direction);
-               SCpnt->SCp.dma_handle = dma_addr;
-               pSCB->SCB_BufPtr = cpu_to_le32((u32)dma_addr);
-               pSCB->SCB_BufLen = cpu_to_le32((u32)SCpnt->request_bufflen);
-               pSCB->SCB_SGLen = 0;
-       } else {
-               pSCB->SCB_BufLen = 0;
-               pSCB->SCB_SGLen = 0;
+               cblk->buflen = (scsi_bufflen(cmnd) > total_len) ?
+                       total_len : scsi_bufflen(cmnd);
+       } else {        /* No data transfer required */
+               cblk->buflen = 0;
+               cblk->sglen = 0;
        }
 }
 
+/**
+ *     i91u_queuecommand       -       Queue a new command if possible
+ *     @cmd: SCSI command block from the mid layer
+ *     @done: Completion handler
+ *
+ *     Attempts to queue a new command with the host adapter. Will return
+ *     zero if successful or indicate a host busy condition if not (which
+ *     will cause the mid layer to call us again later with the command)
+ */
+
 static int i91u_queuecommand(struct scsi_cmnd *cmd,
                void (*done)(struct scsi_cmnd *))
 {
-       HCS *pHCB = (HCS *) cmd->device->host->base;
-       register SCB *pSCB;
+       struct initio_host *host = (struct initio_host *) cmd->device->host->hostdata;
+       struct scsi_ctrl_blk *cmnd;
 
        cmd->scsi_done = done;
 
-       pSCB = tul_alloc_scb(pHCB);
-       if (!pSCB)
+       cmnd = initio_alloc_scb(host);
+       if (!cmnd)
                return SCSI_MLQUEUE_HOST_BUSY;
 
-       i91uBuildSCB(pHCB, pSCB, cmd);
-       tul_exec_scb(pHCB, pSCB);
+       initio_build_scb(host, cmnd, cmd);
+       initio_exec_scb(host, cmnd);
        return 0;
 }
 
-#if 0 /* no new EH yet */
-/*
- *  Abort a queued command
- *  (commands that are on the bus can't be aborted easily)
- */
-static int i91u_abort(struct scsi_cmnd * SCpnt)
-{
-       HCS *pHCB;
-
-       pHCB = (HCS *) SCpnt->device->host->base;
-       return tul_abort_srb(pHCB, SCpnt);
-}
-
-/*
- *  Reset registers, reset a hanging bus and
- *  kill active and disconnected commands for target w/o soft reset
+/**
+ *     i91u_bus_reset          -       reset the SCSI bus
+ *     @cmnd: Command block we want to trigger the reset for
+ *
+ *     Initiate a SCSI bus reset sequence
  */
-static int i91u_reset(struct scsi_cmnd * SCpnt, unsigned int reset_flags)
-{                              /* I need Host Control Block Information */
-       HCS *pHCB;
-
-       pHCB = (HCS *) SCpnt->device->host->base;
 
-       if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET))
-               return tul_reset_scsi_bus(pHCB);
-       else
-               return tul_device_reset(pHCB, SCpnt, SCpnt->device->id, reset_flags);
-}
-#endif
-
-static int i91u_bus_reset(struct scsi_cmnd * SCpnt)
+static int i91u_bus_reset(struct scsi_cmnd * cmnd)
 {
-       HCS *pHCB;
+       struct initio_host *host;
 
-       pHCB = (HCS *) SCpnt->device->host->base;
+       host = (struct initio_host *) cmnd->device->host->hostdata;
 
-       spin_lock_irq(SCpnt->device->host->host_lock);
-       tul_reset_scsi(pHCB, 0);
-       spin_unlock_irq(SCpnt->device->host->host_lock);
+       spin_lock_irq(cmnd->device->host->host_lock);
+       initio_reset_scsi(host, 0);
+       spin_unlock_irq(cmnd->device->host->host_lock);
 
        return SUCCESS;
 }
 
-/*
- * Return the "logical geometry"
+/**
+ *     i91u_biospararm                 -       return the "logical geometry
+ *     @sdev: SCSI device
+ *     @dev; Matching block device
+ *     @capacity: Sector size of drive
+ *     @info_array: Return space for BIOS geometry
+ *
+ *     Map the device geometry in a manner compatible with the host
+ *     controller BIOS behaviour.
+ *
+ *     FIXME: limited to 2^32 sector devices.
  */
+
 static int i91u_biosparam(struct scsi_device *sdev, struct block_device *dev,
                sector_t capacity, int *info_array)
 {
-       HCS *pHcb;              /* Point to Host adapter control block */
-       TCS *pTcb;
+       struct initio_host *host;               /* Point to Host adapter control block */
+       struct target_control *tc;
 
-       pHcb = (HCS *) sdev->host->base;
-       pTcb = &pHcb->HCS_Tcs[sdev->id];
+       host = (struct initio_host *) sdev->host->hostdata;
+       tc = &host->targets[sdev->id];
 
-       if (pTcb->TCS_DrvHead) {
-               info_array[0] = pTcb->TCS_DrvHead;
-               info_array[1] = pTcb->TCS_DrvSector;
-               info_array[2] = (unsigned long)capacity / pTcb->TCS_DrvHead / pTcb->TCS_DrvSector;
+       if (tc->heads) {
+               info_array[0] = tc->heads;
+               info_array[1] = tc->sectors;
+               info_array[2] = (unsigned long)capacity / tc->heads / tc->sectors;
        } else {
-               if (pTcb->TCS_DrvFlags & TCF_DRV_255_63) {
+               if (tc->drv_flags & TCF_DRV_255_63) {
                        info_array[0] = 255;
                        info_array[1] = 63;
                        info_array[2] = (unsigned long)capacity / 255 / 63;
@@ -3047,7 +2722,16 @@ static int i91u_biosparam(struct scsi_device *sdev, struct block_device *dev,
        return 0;
 }
 
-static void i91u_unmap_cmnd(struct pci_dev *pci_dev, struct scsi_cmnd *cmnd)
+/**
+ *     i91u_unmap_scb          -       Unmap a command
+ *     @pci_dev: PCI device the command is for
+ *     @cmnd: The command itself
+ *
+ *     Unmap any PCI mapping/IOMMU resources allocated when the command
+ *     was mapped originally as part of initio_build_scb
+ */
+
+static void i91u_unmap_scb(struct pci_dev *pci_dev, struct scsi_cmnd *cmnd)
 {
        /* auto sense buffer */
        if (cmnd->SCp.ptr) {
@@ -3058,65 +2742,63 @@ static void i91u_unmap_cmnd(struct pci_dev *pci_dev, struct scsi_cmnd *cmnd)
        }
 
        /* request buffer */
-       if (cmnd->use_sg) {
+       if (scsi_sg_count(cmnd)) {
                dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle,
-                                sizeof(struct SG_Struc) * TOTAL_SG_ENTRY,
+                                sizeof(struct sg_entry) * TOTAL_SG_ENTRY,
                                 DMA_BIDIRECTIONAL);
 
-               dma_unmap_sg(&pci_dev->dev, cmnd->request_buffer,
-                            cmnd->use_sg,
-                            cmnd->sc_data_direction);
-       } else if (cmnd->request_bufflen) {
-               dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle,
-                                cmnd->request_bufflen,
-                                cmnd->sc_data_direction);
+               scsi_dma_unmap(cmnd);
        }
 }
 
-/*****************************************************************************
- Function name  : i91uSCBPost
- Description    : This is callback routine be called when tulip finish one
-                       SCSI command.
- Input          : pHCB  -       Pointer to host adapter control block.
-                 pSCB  -       Pointer to SCSI control block.
- Output         : None.
- Return         : None.
-*****************************************************************************/
-static void i91uSCBPost(BYTE * pHcb, BYTE * pScb)
-{
-       struct scsi_cmnd *pSRB; /* Pointer to SCSI request block */
-       HCS *pHCB;
-       SCB *pSCB;
+/**
+ *     i91uSCBPost             -       SCSI callback
+ *     @host: Pointer to host adapter control block.
+ *     @cmnd: Pointer to SCSI control block.
+ *
+ *     This is callback routine be called when tulip finish one
+ *     SCSI command.
+ */
 
-       pHCB = (HCS *) pHcb;
-       pSCB = (SCB *) pScb;
-       if ((pSRB = pSCB->SCB_Srb) == 0) {
-               printk("i91uSCBPost: SRB pointer is empty\n");
+static void i91uSCBPost(u8 * host_mem, u8 * cblk_mem)
+{
+       struct scsi_cmnd *cmnd; /* Pointer to SCSI request block */
+       struct initio_host *host;
+       struct scsi_ctrl_blk *cblk;
 
-               tul_release_scb(pHCB, pSCB);    /* Release SCB for current channel */
+       host = (struct initio_host *) host_mem;
+       cblk = (struct scsi_ctrl_blk *) cblk_mem;
+       if ((cmnd = cblk->srb) == NULL) {
+               printk(KERN_ERR "i91uSCBPost: SRB pointer is empty\n");
+               WARN_ON(1);
+               initio_release_scb(host, cblk); /* Release SCB for current channel */
                return;
        }
-       switch (pSCB->SCB_HaStat) {
+
+       /*
+        *      Remap the firmware error status into a mid layer one
+        */
+       switch (cblk->hastat) {
        case 0x0:
        case 0xa:               /* Linked command complete without error and linked normally */
        case 0xb:               /* Linked command complete without error interrupt generated */
-               pSCB->SCB_HaStat = 0;
+               cblk->hastat = 0;
                break;
 
        case 0x11:              /* Selection time out-The initiator selection or target
                                   reselection was not complete within the SCSI Time out period */
-               pSCB->SCB_HaStat = DID_TIME_OUT;
+               cblk->hastat = DID_TIME_OUT;
                break;
 
        case 0x14:              /* Target bus phase sequence failure-An invalid bus phase or bus
                                   phase sequence was requested by the target. The host adapter
                                   will generate a SCSI Reset Condition, notifying the host with
                                   a SCRD interrupt */
-               pSCB->SCB_HaStat = DID_RESET;
+               cblk->hastat = DID_RESET;
                break;
 
        case 0x1a:              /* SCB Aborted. 07/21/98 */
-               pSCB->SCB_HaStat = DID_ABORT;
+               cblk->hastat = DID_ABORT;
                break;
 
        case 0x12:              /* Data overrun/underrun-The target attempted to transfer more data
@@ -3126,49 +2808,196 @@ static void i91uSCBPost(BYTE * pHcb, BYTE * pScb)
        case 0x16:              /* Invalid SCB Operation Code. */
 
        default:
-               printk("ini9100u: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat);
-               pSCB->SCB_HaStat = DID_ERROR;   /* Couldn't find any better */
+               printk("ini9100u: %x %x\n", cblk->hastat, cblk->tastat);
+               cblk->hastat = DID_ERROR;       /* Couldn't find any better */
                break;
        }
 
-       pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16);
+       cmnd->result = cblk->tastat | (cblk->hastat << 16);
+       WARN_ON(cmnd == NULL);
+       i91u_unmap_scb(host->pci_dev, cmnd);
+       cmnd->scsi_done(cmnd);  /* Notify system DONE           */
+       initio_release_scb(host, cblk); /* Release SCB for current channel */
+}
+
+static struct scsi_host_template initio_template = {
+       .proc_name              = "INI9100U",
+       .name                   = "Initio INI-9X00U/UW SCSI device driver",
+       .queuecommand           = i91u_queuecommand,
+       .eh_bus_reset_handler   = i91u_bus_reset,
+       .bios_param             = i91u_biosparam,
+       .can_queue              = MAX_TARGETS * i91u_MAXQUEUE,
+       .this_id                = 1,
+       .sg_tablesize           = SG_ALL,
+       .cmd_per_lun            = 1,
+       .use_clustering         = ENABLE_CLUSTERING,
+};
+
+static int initio_probe_one(struct pci_dev *pdev,
+       const struct pci_device_id *id)
+{
+       struct Scsi_Host *shost;
+       struct initio_host *host;
+       u32 reg;
+       u16 bios_seg;
+       struct scsi_ctrl_blk *scb, *tmp, *prev = NULL /* silence gcc */;
+       int num_scb, i, error;
+
+       error = pci_enable_device(pdev);
+       if (error)
+               return error;
+
+       pci_read_config_dword(pdev, 0x44, (u32 *) & reg);
+       bios_seg = (u16) (reg & 0xFF);
+       if (((reg & 0xFF00) >> 8) == 0xFF)
+               reg = 0;
+       bios_seg = (bios_seg << 8) + ((u16) ((reg & 0xFF00) >> 8));
+
+       if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+               printk(KERN_WARNING  "i91u: Could not set 32 bit DMA mask\n");
+               error = -ENODEV;
+               goto out_disable_device;
+       }
+       shost = scsi_host_alloc(&initio_template, sizeof(struct initio_host));
+       if (!shost) {
+               printk(KERN_WARNING "initio: Could not allocate host structure.\n");
+               error = -ENOMEM;
+               goto out_disable_device;
+       }
+       host = (struct initio_host *)shost->hostdata;
+       memset(host, 0, sizeof(struct initio_host));
 
-       if (pSRB == NULL) {
-               printk("pSRB is NULL\n");
+       if (!request_region(host->addr, 256, "i91u")) {
+               printk(KERN_WARNING "initio: I/O port range 0x%x is busy.\n", host->addr);
+               error = -ENODEV;
+               goto out_host_put;
        }
 
-       i91u_unmap_cmnd(pHCB->pci_dev, pSRB);
-       pSRB->scsi_done(pSRB);  /* Notify system DONE           */
+       if (initio_tag_enable)  /* 1.01i */
+               num_scb = MAX_TARGETS * i91u_MAXQUEUE;
+       else
+               num_scb = MAX_TARGETS + 3;      /* 1-tape, 1-CD_ROM, 1- extra */
 
-       tul_release_scb(pHCB, pSCB);    /* Release SCB for current channel */
-}
+       for (; num_scb >= MAX_TARGETS + 3; num_scb--) {
+               i = num_scb * sizeof(struct scsi_ctrl_blk);
+               if ((scb = kzalloc(i, GFP_DMA)) != NULL)
+                       break;
+       }
+
+       if (!scb) {
+               printk(KERN_WARNING "initio: Cannot allocate SCB array.\n");
+               error = -ENOMEM;
+               goto out_release_region;
+       }
 
-/*
- * Release ressources
+       host->num_scbs = num_scb;
+       host->scb = scb;
+       host->next_pending = scb;
+       host->next_avail = scb;
+       for (i = 0, tmp = scb; i < num_scb; i++, tmp++) {
+               tmp->tagid = i;
+               if (i != 0)
+                       prev->next = tmp;
+               prev = tmp;
+       }
+       prev->next = NULL;
+       host->scb_end = tmp;
+       host->first_avail = scb;
+       host->last_avail = prev;
+
+       initio_init(host, phys_to_virt(bios_seg << 4));
+
+       host->jsstatus0 = 0;
+
+       shost->io_port = host->addr;
+       shost->n_io_port = 0xff;
+       shost->can_queue = num_scb;             /* 03/05/98                      */
+       shost->unique_id = host->addr;
+       shost->max_id = host->max_tar;
+       shost->max_lun = 32;    /* 10/21/97                     */
+       shost->irq = pdev->irq;
+       shost->this_id = host->scsi_id; /* Assign HCS index           */
+       shost->base = host->addr;
+       shost->sg_tablesize = TOTAL_SG_ENTRY;
+
+       error = request_irq(pdev->irq, i91u_intr, IRQF_DISABLED|IRQF_SHARED, "i91u", shost);
+       if (error < 0) {
+               printk(KERN_WARNING "initio: Unable to request IRQ %d\n", pdev->irq);
+               goto out_free_scbs;
+       }
+
+       pci_set_drvdata(pdev, shost);
+       host->pci_dev = pdev;
+
+       error = scsi_add_host(shost, &pdev->dev);
+       if (error)
+               goto out_free_irq;
+       scsi_scan_host(shost);
+       return 0;
+out_free_irq:
+       free_irq(pdev->irq, shost);
+out_free_scbs:
+       kfree(host->scb);
+out_release_region:
+       release_region(host->addr, 256);
+out_host_put:
+       scsi_host_put(shost);
+out_disable_device:
+       pci_disable_device(pdev);
+       return error;
+}
+
+/**
+ *     initio_remove_one       -       control shutdown
+ *     @pdev:  PCI device being released
+ *
+ *     Release the resources assigned to this adapter after it has
+ *     finished being used.
  */
-static int i91u_release(struct Scsi_Host *hreg)
+
+static void initio_remove_one(struct pci_dev *pdev)
 {
-       free_irq(hreg->irq, hreg);
-       release_region(hreg->io_port, 256);
-       return 0;
+       struct Scsi_Host *host = pci_get_drvdata(pdev);
+       struct initio_host *s = (struct initio_host *)host->hostdata;
+       scsi_remove_host(host);
+       free_irq(pdev->irq, host);
+       release_region(s->addr, 256);
+       scsi_host_put(host);
+       pci_disable_device(pdev);
 }
-MODULE_LICENSE("Dual BSD/GPL");
-
-static struct scsi_host_template driver_template = {
-       .proc_name      = "INI9100U",
-       .name           = i91u_REVID,
-       .detect         = i91u_detect,
-       .release        = i91u_release,
-       .queuecommand   = i91u_queuecommand,
-//     .abort          = i91u_abort,
-//     .reset          = i91u_reset,
-       .eh_bus_reset_handler = i91u_bus_reset,
-       .bios_param     = i91u_biosparam,
-       .can_queue      = 1,
-       .this_id        = 1,
-       .sg_tablesize   = SG_ALL,
-       .cmd_per_lun    = 1,
-       .use_clustering = ENABLE_CLUSTERING,
+
+MODULE_LICENSE("GPL");
+
+static struct pci_device_id initio_pci_tbl[] = {
+       {PCI_VENDOR_ID_INIT, 0x9500, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {PCI_VENDOR_ID_INIT, 0x9400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {PCI_VENDOR_ID_INIT, 0x9401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {PCI_VENDOR_ID_INIT, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {PCI_VENDOR_ID_DOMEX, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {0,}
+};
+MODULE_DEVICE_TABLE(pci, initio_pci_tbl);
+
+static struct pci_driver initio_pci_driver = {
+       .name           = "initio",
+       .id_table       = initio_pci_tbl,
+       .probe          = initio_probe_one,
+       .remove         = __devexit_p(initio_remove_one),
 };
-#include "scsi_module.c"
 
+static int __init initio_init_driver(void)
+{
+       return pci_register_driver(&initio_pci_driver);
+}
+
+static void __exit initio_exit_driver(void)
+{
+       pci_unregister_driver(&initio_pci_driver);
+}
+
+MODULE_DESCRIPTION("Initio INI-9X00U/UW SCSI device driver");
+MODULE_AUTHOR("Initio Corporation");
+MODULE_LICENSE("GPL");
+
+module_init(initio_init_driver);
+module_exit(initio_exit_driver);
index acb67a4..cb48efa 100644 (file)
@@ -4,6 +4,8 @@
  * Copyright (c) 1994-1998 Initio Corporation
  * All rights reserved.
  *
+ * Cleanups (c) Copyright 2007 Red Hat <alan@redhat.com>
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * along with this program; see the file COPYING.  If not, write to
  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * --------------------------------------------------------------------------
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification, immediately at the beginning of the file.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * Where this Software is combined with software released under the terms of 
- * the GNU General Public License ("GPL") and the terms of the GPL would require the 
- * combined work to also be released under the terms of the GPL, the terms
- * and conditions of this License will apply in addition to those of the
- * GPL with the exception of any terms or conditions of this License that
- * conflict with, or are expressly prohibited by, the GPL.
- *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
 #include <linux/types.h>
 
-#define ULONG   unsigned long
-#define USHORT  unsigned short
-#define UCHAR   unsigned char
-#define BYTE    unsigned char
-#define WORD    unsigned short
-#define DWORD   unsigned long
-#define UBYTE   unsigned char
-#define UWORD   unsigned short
-#define UDWORD  unsigned long
-#define U32     u32
-
 #define TOTAL_SG_ENTRY         32
 #define MAX_SUPPORTED_ADAPTERS  8
 #define MAX_OFFSET             15
@@ -368,55 +338,55 @@ typedef struct {
 /************************************************************************/
 /*              Scatter-Gather Element Structure                        */
 /************************************************************************/
-typedef struct SG_Struc {
-       U32 SG_Ptr;             /* Data Pointer */
-       U32 SG_Len;             /* Data Length */
-} SG;
+struct sg_entry {
+       u32 data;               /* Data Pointer */
+       u32 len;                /* Data Length */
+};
 
 /***********************************************************************
                SCSI Control Block
 ************************************************************************/
-typedef struct Scsi_Ctrl_Blk {
-       struct Scsi_Ctrl_Blk *SCB_NxtScb;
-       UBYTE SCB_Status;       /*4 */
-       UBYTE SCB_NxtStat;      /*5 */
-       UBYTE SCB_Mode;         /*6 */
-       UBYTE SCB_Msgin;        /*7 SCB_Res0 */
-       UWORD SCB_SGIdx;        /*8 */
-       UWORD SCB_SGMax;        /*A */
+struct scsi_ctrl_blk {
+       struct scsi_ctrl_blk *next;
+       u8 status;      /*4 */
+       u8 next_state;  /*5 */
+       u8 mode;                /*6 */
+       u8 msgin;       /*7 SCB_Res0 */
+       u16 sgidx;      /*8 */
+       u16 sgmax;      /*A */
 #ifdef ALPHA
-       U32 SCB_Reserved[2];    /*C */
+       u32 reserved[2];        /*C */
 #else
-       U32 SCB_Reserved[3];    /*C */
+       u32 reserved[3];        /*C */
 #endif
 
-       U32 SCB_XferLen;        /*18 Current xfer len           */
-       U32 SCB_TotXLen;        /*1C Total xfer len             */
-       U32 SCB_PAddr;          /*20 SCB phy. Addr. */
-
-       UBYTE SCB_Opcode;       /*24 SCB command code */
-       UBYTE SCB_Flags;        /*25 SCB Flags */
-       UBYTE SCB_Target;       /*26 Target Id */
-       UBYTE SCB_Lun;          /*27 Lun */
-       U32 SCB_BufPtr;         /*28 Data Buffer Pointer */
-       U32 SCB_BufLen;         /*2C Data Allocation Length */
-       UBYTE SCB_SGLen;        /*30 SG list # */
-       UBYTE SCB_SenseLen;     /*31 Sense Allocation Length */
-       UBYTE SCB_HaStat;       /*32 */
-       UBYTE SCB_TaStat;       /*33 */
-       UBYTE SCB_CDBLen;       /*34 CDB Length */
-       UBYTE SCB_Ident;        /*35 Identify */
-       UBYTE SCB_TagMsg;       /*36 Tag Message */
-       UBYTE SCB_TagId;        /*37 Queue Tag */
-       UBYTE SCB_CDB[12];      /*38 */
-       U32 SCB_SGPAddr;        /*44 SG List/Sense Buf phy. Addr. */
-       U32 SCB_SensePtr;       /*48 Sense data pointer */
-       void (*SCB_Post) (BYTE *, BYTE *);      /*4C POST routine */
-       struct scsi_cmnd *SCB_Srb;      /*50 SRB Pointer */
-       SG SCB_SGList[TOTAL_SG_ENTRY];  /*54 Start of SG list */
-} SCB;
-
-/* Bit Definition for SCB_Status */
+       u32 xferlen;    /*18 Current xfer len           */
+       u32 totxlen;    /*1C Total xfer len             */
+       u32 paddr;              /*20 SCB phy. Addr. */
+
+       u8 opcode;      /*24 SCB command code */
+       u8 flags;       /*25 SCB Flags */
+       u8 target;      /*26 Target Id */
+       u8 lun;         /*27 Lun */
+       u32 bufptr;             /*28 Data Buffer Pointer */
+       u32 buflen;             /*2C Data Allocation Length */
+       u8 sglen;       /*30 SG list # */
+       u8 senselen;    /*31 Sense Allocation Length */
+       u8 hastat;      /*32 */
+       u8 tastat;      /*33 */
+       u8 cdblen;      /*34 CDB Length */
+       u8 ident;       /*35 Identify */
+       u8 tagmsg;      /*36 Tag Message */
+       u8 tagid;       /*37 Queue Tag */
+       u8 cdb[12];     /*38 */
+       u32 sgpaddr;    /*44 SG List/Sense Buf phy. Addr. */
+       u32 senseptr;   /*48 Sense data pointer */
+       void (*post) (u8 *, u8 *);      /*4C POST routine */
+       struct scsi_cmnd *srb;  /*50 SRB Pointer */
+       struct sg_entry sglist[TOTAL_SG_ENTRY]; /*54 Start of SG list */
+};
+
+/* Bit Definition for status */
 #define SCB_RENT        0x01
 #define SCB_PEND        0x02
 #define SCB_CONTIG      0x04   /* Contigent Allegiance */
@@ -425,17 +395,17 @@ typedef struct Scsi_Ctrl_Blk {
 #define SCB_DONE        0x20
 
 
-/* Opcodes of SCB_Opcode */
+/* Opcodes for opcode */
 #define ExecSCSI        0x1
 #define BusDevRst       0x2
 #define AbortCmd        0x3
 
 
-/* Bit Definition for SCB_Mode */
+/* Bit Definition for mode */
 #define SCM_RSENS       0x01   /* request sense mode */
 
 
-/* Bit Definition for SCB_Flags */
+/* Bit Definition for flags */
 #define SCF_DONE        0x01
 #define SCF_POST        0x02
 #define SCF_SENSE       0x04
@@ -492,15 +462,14 @@ typedef struct Scsi_Ctrl_Blk {
                Target Device Control Structure
 **********************************************************************/
 
-typedef struct Tar_Ctrl_Struc {
-       UWORD TCS_Flags;        /* 0 */
-       UBYTE TCS_JS_Period;    /* 2 */
-       UBYTE TCS_SConfig0;     /* 3 */
-
-       UWORD TCS_DrvFlags;     /* 4 */
-       UBYTE TCS_DrvHead;      /* 6 */
-       UBYTE TCS_DrvSector;    /* 7 */
-} TCS;
+struct target_control {
+       u16 flags;
+       u8 js_period;
+       u8 sconfig0;
+       u16 drv_flags;
+       u8 heads;
+       u8 sectors;
+};
 
 /***********************************************************************
                Target Device Control Structure
@@ -523,62 +492,53 @@ typedef struct Tar_Ctrl_Struc {
 #define TCF_DRV_EN_TAG          0x0800
 #define TCF_DRV_255_63          0x0400
 
-typedef struct I91u_Adpt_Struc {
-       UWORD ADPT_BIOS;        /* 0 */
-       UWORD ADPT_BASE;        /* 1 */
-       UBYTE ADPT_Bus;         /* 2 */
-       UBYTE ADPT_Device;      /* 3 */
-       UBYTE ADPT_INTR;        /* 4 */
-} INI_ADPT_STRUCT;
-
-
 /***********************************************************************
              Host Adapter Control Structure
 ************************************************************************/
-typedef struct Ha_Ctrl_Struc {
-       UWORD HCS_Base;         /* 00 */
-       UWORD HCS_BIOS;         /* 02 */
-       UBYTE HCS_Intr;         /* 04 */
-       UBYTE HCS_SCSI_ID;      /* 05 */
-       UBYTE HCS_MaxTar;       /* 06 */
-       UBYTE HCS_NumScbs;      /* 07 */
-
-       UBYTE HCS_Flags;        /* 08 */
-       UBYTE HCS_Index;        /* 09 */
-       UBYTE HCS_HaId;         /* 0A */
-       UBYTE HCS_Config;       /* 0B */
-       UWORD HCS_IdMask;       /* 0C */
-       UBYTE HCS_Semaph;       /* 0E */
-       UBYTE HCS_Phase;        /* 0F */
-       UBYTE HCS_JSStatus0;    /* 10 */
-       UBYTE HCS_JSInt;        /* 11 */
-       UBYTE HCS_JSStatus1;    /* 12 */
-       UBYTE HCS_SConf1;       /* 13 */
-
-       UBYTE HCS_Msg[8];       /* 14 */
-       SCB *HCS_NxtAvail;      /* 1C */
-       SCB *HCS_Scb;           /* 20 */
-       SCB *HCS_ScbEnd;        /* 24 */
-       SCB *HCS_NxtPend;       /* 28 */
-       SCB *HCS_NxtContig;     /* 2C */
-       SCB *HCS_ActScb;        /* 30 */
-       TCS *HCS_ActTcs;        /* 34 */
-
-       SCB *HCS_FirstAvail;    /* 38 */
-       SCB *HCS_LastAvail;     /* 3C */
-       SCB *HCS_FirstPend;     /* 40 */
-       SCB *HCS_LastPend;      /* 44 */
-       SCB *HCS_FirstBusy;     /* 48 */
-       SCB *HCS_LastBusy;      /* 4C */
-       SCB *HCS_FirstDone;     /* 50 */
-       SCB *HCS_LastDone;      /* 54 */
-       UBYTE HCS_MaxTags[16];  /* 58 */
-       UBYTE HCS_ActTags[16];  /* 68 */
-       TCS HCS_Tcs[MAX_TARGETS];       /* 78 */
-       spinlock_t HCS_AvailLock;
-       spinlock_t HCS_SemaphLock;
+struct initio_host {
+       u16 addr;               /* 00 */
+       u16 bios_addr;          /* 02 */
+       u8 irq;                 /* 04 */
+       u8 scsi_id;             /* 05 */
+       u8 max_tar;             /* 06 */
+       u8 num_scbs;            /* 07 */
+
+       u8 flags;               /* 08 */
+       u8 index;               /* 09 */
+       u8 ha_id;               /* 0A */
+       u8 config;              /* 0B */
+       u16 idmask;             /* 0C */
+       u8 semaph;              /* 0E */
+       u8 phase;               /* 0F */
+       u8 jsstatus0;           /* 10 */
+       u8 jsint;               /* 11 */
+       u8 jsstatus1;           /* 12 */
+       u8 sconf1;              /* 13 */
+
+       u8 msg[8];              /* 14 */
+       struct scsi_ctrl_blk *next_avail;       /* 1C */
+       struct scsi_ctrl_blk *scb;              /* 20 */
+       struct scsi_ctrl_blk *scb_end;          /* 24 */ /*UNUSED*/
+       struct scsi_ctrl_blk *next_pending;     /* 28 */
+       struct scsi_ctrl_blk *next_contig;      /* 2C */ /*UNUSED*/
+       struct scsi_ctrl_blk *active;           /* 30 */
+       struct target_control *active_tc;       /* 34 */
+
+       struct scsi_ctrl_blk *first_avail;      /* 38 */
+       struct scsi_ctrl_blk *last_avail;       /* 3C */
+       struct scsi_ctrl_blk *first_pending;    /* 40 */
+       struct scsi_ctrl_blk *last_pending;     /* 44 */
+       struct scsi_ctrl_blk *first_busy;       /* 48 */
+       struct scsi_ctrl_blk *last_busy;        /* 4C */
+       struct scsi_ctrl_blk *first_done;       /* 50 */
+       struct scsi_ctrl_blk *last_done;        /* 54 */
+       u8 max_tags[16];        /* 58 */
+       u8 act_tags[16];        /* 68 */
+       struct target_control targets[MAX_TARGETS];     /* 78 */
+       spinlock_t avail_lock;
+       spinlock_t semaph_lock;
        struct pci_dev *pci_dev;
-} HCS;
+};
 
 /* Bit Definition for HCB_Config */
 #define HCC_SCSI_RESET          0x01
@@ -599,47 +559,47 @@ typedef struct Ha_Ctrl_Struc {
 *******************************************************************/
 
 typedef struct _NVRAM_SCSI {   /* SCSI channel configuration   */
-       UCHAR NVM_ChSCSIID;     /* 0Ch -> Channel SCSI ID       */
-       UCHAR NVM_ChConfig1;    /* 0Dh -> Channel config 1      */
-       UCHAR NVM_ChConfig2;    /* 0Eh -> Channel config 2      */
-       UCHAR NVM_NumOfTarg;    /* 0Fh -> Number of SCSI target */
+       u8 NVM_ChSCSIID;        /* 0Ch -> Channel SCSI ID       */
+       u8 NVM_ChConfig1;       /* 0Dh -> Channel config 1      */
+       u8 NVM_ChConfig2;       /* 0Eh -> Channel config 2      */
+       u8 NVM_NumOfTarg;       /* 0Fh -> Number of SCSI target */
        /* SCSI target configuration    */
-       UCHAR NVM_Targ0Config;  /* 10h -> Target 0 configuration */
-       UCHAR NVM_Targ1Config;  /* 11h -> Target 1 configuration */
-       UCHAR NVM_Targ2Config;  /* 12h -> Target 2 configuration */
-       UCHAR NVM_Targ3Config;  /* 13h -> Target 3 configuration */
-       UCHAR NVM_Targ4Config;  /* 14h -> Target 4 configuration */
-       UCHAR NVM_Targ5Config;  /* 15h -> Target 5 configuration */
-       UCHAR NVM_Targ6Config;  /* 16h -> Target 6 configuration */
-       UCHAR NVM_Targ7Config;  /* 17h -> Target 7 configuration */
-       UCHAR NVM_Targ8Config;  /* 18h -> Target 8 configuration */
-       UCHAR NVM_Targ9Config;  /* 19h -> Target 9 configuration */
-       UCHAR NVM_TargAConfig;  /* 1Ah -> Target A configuration */
-       UCHAR NVM_TargBConfig;  /* 1Bh -> Target B configuration */
-       UCHAR NVM_TargCConfig;  /* 1Ch -> Target C configuration */
-       UCHAR NVM_TargDConfig;  /* 1Dh -> Target D configuration */
-       UCHAR NVM_TargEConfig;  /* 1Eh -> Target E configuration */
-       UCHAR NVM_TargFConfig;  /* 1Fh -> Target F configuration */
+       u8 NVM_Targ0Config;     /* 10h -> Target 0 configuration */
+       u8 NVM_Targ1Config;     /* 11h -> Target 1 configuration */
+       u8 NVM_Targ2Config;     /* 12h -> Target 2 configuration */
+       u8 NVM_Targ3Config;     /* 13h -> Target 3 configuration */
+       u8 NVM_Targ4Config;     /* 14h -> Target 4 configuration */
+       u8 NVM_Targ5Config;     /* 15h -> Target 5 configuration */
+       u8 NVM_Targ6Config;     /* 16h -> Target 6 configuration */
+       u8 NVM_Targ7Config;     /* 17h -> Target 7 configuration */
+       u8 NVM_Targ8Config;     /* 18h -> Target 8 configuration */
+       u8 NVM_Targ9Config;     /* 19h -> Target 9 configuration */
+       u8 NVM_TargAConfig;     /* 1Ah -> Target A configuration */
+       u8 NVM_TargBConfig;     /* 1Bh -> Target B configuration */
+       u8 NVM_TargCConfig;     /* 1Ch -> Target C configuration */
+       u8 NVM_TargDConfig;     /* 1Dh -> Target D configuration */
+       u8 NVM_TargEConfig;     /* 1Eh -> Target E configuration */
+       u8 NVM_TargFConfig;     /* 1Fh -> Target F configuration */
 } NVRAM_SCSI;
 
 typedef struct _NVRAM {
 /*----------header ---------------*/
-       USHORT NVM_Signature;   /* 0,1: Signature */
-       UCHAR NVM_Size;         /* 2:   Size of data structure */
-       UCHAR NVM_Revision;     /* 3:   Revision of data structure */
+       u16 NVM_Signature;      /* 0,1: Signature */
+       u8 NVM_Size;            /* 2:   Size of data structure */
+       u8 NVM_Revision;        /* 3:   Revision of data structure */
        /* ----Host Adapter Structure ---- */
-       UCHAR NVM_ModelByte0;   /* 4:   Model number (byte 0) */
-       UCHAR NVM_ModelByte1;   /* 5:   Model number (byte 1) */
-       UCHAR NVM_ModelInfo;    /* 6:   Model information         */
-       UCHAR NVM_NumOfCh;      /* 7:   Number of SCSI channel */
-       UCHAR NVM_BIOSConfig1;  /* 8:   BIOS configuration 1  */
-       UCHAR NVM_BIOSConfig2;  /* 9:   BIOS configuration 2  */
-       UCHAR NVM_HAConfig1;    /* A:   Hoat adapter configuration 1 */
-       UCHAR NVM_HAConfig2;    /* B:   Hoat adapter configuration 2 */
+       u8 NVM_ModelByte0;      /* 4:   Model number (byte 0) */
+       u8 NVM_ModelByte1;      /* 5:   Model number (byte 1) */
+       u8 NVM_ModelInfo;       /* 6:   Model information         */
+       u8 NVM_NumOfCh; /* 7:   Number of SCSI channel */
+       u8 NVM_BIOSConfig1;     /* 8:   BIOS configuration 1  */
+       u8 NVM_BIOSConfig2;     /* 9:   BIOS configuration 2  */
+       u8 NVM_HAConfig1;       /* A:   Hoat adapter configuration 1 */
+       u8 NVM_HAConfig2;       /* B:   Hoat adapter configuration 2 */
        NVRAM_SCSI NVM_SCSIInfo[2];
-       UCHAR NVM_reserved[10];
+       u8 NVM_reserved[10];
        /* ---------- CheckSum ----------       */
-       USHORT NVM_CheckSum;    /* 0x3E, 0x3F: Checksum of NVRam        */
+       u16 NVM_CheckSum;       /* 0x3E, 0x3F: Checksum of NVRam        */
 } NVRAM, *PNVRAM;
 
 /* Bios Configuration for nvram->BIOSConfig1                            */
@@ -681,19 +641,6 @@ typedef struct _NVRAM {
 #define DISC_ALLOW              0xC0   /* Disconnect is allowed        */
 #define SCSICMD_RequestSense    0x03
 
-typedef struct _HCSinfo {
-       ULONG base;
-       UCHAR vec;
-       UCHAR bios;             /* High byte of BIOS address */
-       USHORT BaseAndBios;     /* high byte: pHcsInfo->bios,low byte:pHcsInfo->base */
-} HCSINFO;
-
-#define TUL_RD(x,y)             (UCHAR)(inb(  (int)((ULONG)(x+y)) ))
-#define TUL_RDLONG(x,y)         (ULONG)(inl((int)((ULONG)(x+y)) ))
-#define TUL_WR(     adr,data)   outb( (UCHAR)(data), (int)(adr))
-#define TUL_WRSHORT(adr,data)   outw( (UWORD)(data), (int)(adr))
-#define TUL_WRLONG( adr,data)   outl( (ULONG)(data), (int)(adr))
-
 #define SCSI_ABORT_SNOOZE 0
 #define SCSI_ABORT_SUCCESS 1
 #define SCSI_ABORT_PENDING 2
index fa6ff29..072f577 100644 (file)
@@ -539,32 +539,6 @@ struct ipr_cmnd *ipr_get_free_ipr_cmnd(struct ipr_ioa_cfg *ioa_cfg)
        return ipr_cmd;
 }
 
-/**
- * ipr_unmap_sglist - Unmap scatterlist if mapped
- * @ioa_cfg:   ioa config struct
- * @ipr_cmd:   ipr command struct
- *
- * Return value:
- *     nothing
- **/
-static void ipr_unmap_sglist(struct ipr_ioa_cfg *ioa_cfg,
-                            struct ipr_cmnd *ipr_cmd)
-{
-       struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
-
-       if (ipr_cmd->dma_use_sg) {
-               if (scsi_cmd->use_sg > 0) {
-                       pci_unmap_sg(ioa_cfg->pdev, scsi_cmd->request_buffer,
-                                    scsi_cmd->use_sg,
-                                    scsi_cmd->sc_data_direction);
-               } else {
-                       pci_unmap_single(ioa_cfg->pdev, ipr_cmd->dma_handle,
-                                        scsi_cmd->request_bufflen,
-                                        scsi_cmd->sc_data_direction);
-               }
-       }
-}
-
 /**
  * ipr_mask_and_clear_interrupts - Mask all and clear specified interrupts
  * @ioa_cfg:   ioa config struct
@@ -677,7 +651,7 @@ static void ipr_scsi_eh_done(struct ipr_cmnd *ipr_cmd)
 
        scsi_cmd->result |= (DID_ERROR << 16);
 
-       ipr_unmap_sglist(ioa_cfg, ipr_cmd);
+       scsi_dma_unmap(ipr_cmd->scsi_cmd);
        scsi_cmd->scsi_done(scsi_cmd);
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
 }
@@ -4292,93 +4266,55 @@ static irqreturn_t ipr_isr(int irq, void *devp)
 static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
                           struct ipr_cmnd *ipr_cmd)
 {
-       int i;
-       struct scatterlist *sglist;
+       int i, nseg;
+       struct scatterlist *sg;
        u32 length;
        u32 ioadl_flags = 0;
        struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
        struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
 
-       length = scsi_cmd->request_bufflen;
-
-       if (length == 0)
+       length = scsi_bufflen(scsi_cmd);
+       if (!length)
                return 0;
 
-       if (scsi_cmd->use_sg) {
-               ipr_cmd->dma_use_sg = pci_map_sg(ioa_cfg->pdev,
-                                                scsi_cmd->request_buffer,
-                                                scsi_cmd->use_sg,
-                                                scsi_cmd->sc_data_direction);
-
-               if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
-                       ioadl_flags = IPR_IOADL_FLAGS_WRITE;
-                       ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
-                       ioarcb->write_data_transfer_length = cpu_to_be32(length);
-                       ioarcb->write_ioadl_len =
-                               cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
-               } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) {
-                       ioadl_flags = IPR_IOADL_FLAGS_READ;
-                       ioarcb->read_data_transfer_length = cpu_to_be32(length);
-                       ioarcb->read_ioadl_len =
-                               cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
-               }
-
-               sglist = scsi_cmd->request_buffer;
+       nseg = scsi_dma_map(scsi_cmd);
+       if (nseg < 0) {
+               dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
+               return -1;
+       }
 
-               if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) {
-                       ioadl = ioarcb->add_data.u.ioadl;
-                       ioarcb->write_ioadl_addr =
-                               cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) +
-                                           offsetof(struct ipr_ioarcb, add_data));
-                       ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
-               }
+       ipr_cmd->dma_use_sg = nseg;
 
-               for (i = 0; i < ipr_cmd->dma_use_sg; i++) {
-                       ioadl[i].flags_and_data_len =
-                               cpu_to_be32(ioadl_flags | sg_dma_len(&sglist[i]));
-                       ioadl[i].address =
-                               cpu_to_be32(sg_dma_address(&sglist[i]));
-               }
+       if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
+               ioadl_flags = IPR_IOADL_FLAGS_WRITE;
+               ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
+               ioarcb->write_data_transfer_length = cpu_to_be32(length);
+               ioarcb->write_ioadl_len =
+                       cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
+       } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) {
+               ioadl_flags = IPR_IOADL_FLAGS_READ;
+               ioarcb->read_data_transfer_length = cpu_to_be32(length);
+               ioarcb->read_ioadl_len =
+                       cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
+       }
 
-               if (likely(ipr_cmd->dma_use_sg)) {
-                       ioadl[i-1].flags_and_data_len |=
-                               cpu_to_be32(IPR_IOADL_FLAGS_LAST);
-                       return 0;
-               } else
-                       dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
-       } else {
-               if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
-                       ioadl_flags = IPR_IOADL_FLAGS_WRITE;
-                       ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
-                       ioarcb->write_data_transfer_length = cpu_to_be32(length);
-                       ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-               } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) {
-                       ioadl_flags = IPR_IOADL_FLAGS_READ;
-                       ioarcb->read_data_transfer_length = cpu_to_be32(length);
-                       ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-               }
+       if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) {
+               ioadl = ioarcb->add_data.u.ioadl;
+               ioarcb->write_ioadl_addr =
+                       cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) +
+                                   offsetof(struct ipr_ioarcb, add_data));
+               ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+       }
 
-               ipr_cmd->dma_handle = pci_map_single(ioa_cfg->pdev,
-                                                    scsi_cmd->request_buffer, length,
-                                                    scsi_cmd->sc_data_direction);
-
-               if (likely(!pci_dma_mapping_error(ipr_cmd->dma_handle))) {
-                       ioadl = ioarcb->add_data.u.ioadl;
-                       ioarcb->write_ioadl_addr =
-                               cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) +
-                                           offsetof(struct ipr_ioarcb, add_data));
-                       ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
-                       ipr_cmd->dma_use_sg = 1;
-                       ioadl[0].flags_and_data_len =
-                               cpu_to_be32(ioadl_flags | length | IPR_IOADL_FLAGS_LAST);
-                       ioadl[0].address = cpu_to_be32(ipr_cmd->dma_handle);
-                       return 0;
-               } else
-                       dev_err(&ioa_cfg->pdev->dev, "pci_map_single failed!\n");
+       scsi_for_each_sg(scsi_cmd, sg, ipr_cmd->dma_use_sg, i) {
+               ioadl[i].flags_and_data_len =
+                       cpu_to_be32(ioadl_flags | sg_dma_len(sg));
+               ioadl[i].address = cpu_to_be32(sg_dma_address(sg));
        }
 
-       return -1;
+       ioadl[i-1].flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+       return 0;
 }
 
 /**
@@ -4441,7 +4377,7 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd)
                        res->needs_sync_complete = 1;
                res->in_erp = 0;
        }
-       ipr_unmap_sglist(ioa_cfg, ipr_cmd);
+       scsi_dma_unmap(ipr_cmd->scsi_cmd);
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
        scsi_cmd->scsi_done(scsi_cmd);
 }
@@ -4819,7 +4755,7 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
                break;
        }
 
-       ipr_unmap_sglist(ioa_cfg, ipr_cmd);
+       scsi_dma_unmap(ipr_cmd->scsi_cmd);
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
        scsi_cmd->scsi_done(scsi_cmd);
 }
@@ -4840,10 +4776,10 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
        struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
        u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
 
-       scsi_cmd->resid = be32_to_cpu(ipr_cmd->ioasa.residual_data_len);
+       scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->ioasa.residual_data_len));
 
        if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) {
-               ipr_unmap_sglist(ioa_cfg, ipr_cmd);
+               scsi_dma_unmap(ipr_cmd->scsi_cmd);
                list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
                scsi_cmd->scsi_done(scsi_cmd);
        } else
index 8b704f7..84f4f5d 100644 (file)
@@ -211,19 +211,6 @@ module_param(ips, charp, 0);
 #warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
 #endif
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-#include <linux/blk.h>
-#include "sd.h"
-#define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags)
-#define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags)
-#ifndef __devexit_p
-#define __devexit_p(x) x
-#endif
-#else
-#define IPS_LOCK_SAVE(lock,flags) do{spin_lock(lock);(void)flags;}while(0)
-#define IPS_UNLOCK_RESTORE(lock,flags) do{spin_unlock(lock);(void)flags;}while(0)
-#endif
-
 #define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \
                          DMA_NONE == scb->scsi_cmd->sc_data_direction) ? \
                          PCI_DMA_BIDIRECTIONAL : \
@@ -381,24 +368,13 @@ static struct scsi_host_template ips_driver_template = {
        .eh_abort_handler       = ips_eh_abort,
        .eh_host_reset_handler  = ips_eh_reset,
        .proc_name              = "ips",
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
        .proc_info              = ips_proc_info,
        .slave_configure        = ips_slave_configure,
-#else
-       .proc_info              = ips_proc24_info,
-       .select_queue_depths    = ips_select_queue_depth,
-#endif
        .bios_param             = ips_biosparam,
        .this_id                = -1,
        .sg_tablesize           = IPS_MAX_SG,
        .cmd_per_lun            = 3,
        .use_clustering         = ENABLE_CLUSTERING,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       .use_new_eh_code        = 1,
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)  &&  LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-    .highmem_io          = 1,   
-#endif
 };
 
 
@@ -731,7 +707,7 @@ ips_release(struct Scsi_Host *sh)
        /* free IRQ */
        free_irq(ha->irq, ha);
 
-       IPS_REMOVE_HOST(sh);
+       scsi_remove_host(sh);
        scsi_host_put(sh);
 
        ips_released_controllers++;
@@ -813,7 +789,6 @@ int ips_eh_abort(struct scsi_cmnd *SC)
        ips_ha_t *ha;
        ips_copp_wait_item_t *item;
        int ret;
-       unsigned long cpu_flags;
        struct Scsi_Host *host;
 
        METHOD_TRACE("ips_eh_abort", 1);
@@ -830,7 +805,7 @@ int ips_eh_abort(struct scsi_cmnd *SC)
        if (!ha->active)
                return (FAILED);
 
-       IPS_LOCK_SAVE(host->host_lock, cpu_flags);
+       spin_lock(host->host_lock);
 
        /* See if the command is on the copp queue */
        item = ha->copp_waitlist.head;
@@ -851,7 +826,7 @@ int ips_eh_abort(struct scsi_cmnd *SC)
                ret = (FAILED);
        }
 
-       IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
+       spin_unlock(host->host_lock);
        return ret;
 }
 
@@ -1176,18 +1151,10 @@ static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
 /*   Set bios geometry for the controller                                   */
 /*                                                                          */
 /****************************************************************************/
-static int
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-ips_biosparam(Disk * disk, kdev_t dev, int geom[])
-{
-       ips_ha_t *ha = (ips_ha_t *) disk->device->host->hostdata;
-       unsigned long capacity = disk->capacity;
-#else
-ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
-             sector_t capacity, int geom[])
+static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
+                        sector_t capacity, int geom[])
 {
        ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata;
-#endif
        int heads;
        int sectors;
        int cylinders;
@@ -1225,70 +1192,6 @@ ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
        return (0);
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-
-/* ips_proc24_info is a wrapper around ips_proc_info *
- * for compatibility with the 2.4 scsi parameters    */
-static int
-ips_proc24_info(char *buffer, char **start, off_t offset, int length,
-                             int hostno, int func)
-{
-       int i;
-
-       for (i = 0; i < ips_next_controller; i++) {
-               if (ips_sh[i] && ips_sh[i]->host_no == hostno) {
-                       return ips_proc_info(ips_sh[i], buffer, start,
-                                            offset, length, func);
-               }
-       }
-       return -EINVAL; 
-}
-
-/****************************************************************************/
-/*                                                                          */
-/* Routine Name: ips_select_queue_depth                                     */
-/*                                                                          */
-/* Routine Description:                                                     */
-/*                                                                          */
-/*   Select queue depths for the devices on the contoller                   */
-/*                                                                          */
-/****************************************************************************/
-static void
-ips_select_queue_depth(struct Scsi_Host *host, struct scsi_device * scsi_devs)
-{
-       struct scsi_device *device;
-       ips_ha_t *ha;
-       int count = 0;
-       int min;
-
-       ha = IPS_HA(host);
-       min = ha->max_cmds / 4;
-
-       for (device = scsi_devs; device; device = device->next) {
-               if (device->host == host) {
-                       if ((device->channel == 0) && (device->type == 0))
-                               count++;
-               }
-       }
-
-       for (device = scsi_devs; device; device = device->next) {
-               if (device->host == host) {
-                       if ((device->channel == 0) && (device->type == 0)) {
-                               device->queue_depth =
-                                   (ha->max_cmds - 1) / count;
-                               if (device->queue_depth < min)
-                                       device->queue_depth = min;
-                       } else {
-                               device->queue_depth = 2;
-                       }
-
-                       if (device->queue_depth < 2)
-                               device->queue_depth = 2;
-               }
-       }
-}
-
-#else
 /****************************************************************************/
 /*                                                                          */
 /* Routine Name: ips_slave_configure                                        */
@@ -1316,7 +1219,6 @@ ips_slave_configure(struct scsi_device * SDptr)
        SDptr->skip_ms_page_3f = 1;
        return 0;
 }
-#endif
 
 /****************************************************************************/
 /*                                                                          */
@@ -1331,7 +1233,6 @@ static irqreturn_t
 do_ipsintr(int irq, void *dev_id)
 {
        ips_ha_t *ha;
-       unsigned long cpu_flags;
        struct Scsi_Host *host;
        int irqstatus;
 
@@ -1347,16 +1248,16 @@ do_ipsintr(int irq, void *dev_id)
                return IRQ_HANDLED;
        }
 
-       IPS_LOCK_SAVE(host->host_lock, cpu_flags);
+       spin_lock(host->host_lock);
 
        if (!ha->active) {
-               IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
+               spin_unlock(host->host_lock);
                return IRQ_HANDLED;
        }
 
        irqstatus = (*ha->func.intr) (ha);
 
-       IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
+       spin_unlock(host->host_lock);
 
        /* start the next command */
        ips_next(ha, IPS_INTR_ON);
@@ -2730,7 +2631,6 @@ ips_next(ips_ha_t * ha, int intr)
        struct scsi_cmnd *q;
        ips_copp_wait_item_t *item;
        int ret;
-       unsigned long cpu_flags = 0;
        struct Scsi_Host *host;
        METHOD_TRACE("ips_next", 1);
 
@@ -2742,7 +2642,7 @@ ips_next(ips_ha_t * ha, int intr)
         * this command won't time out
         */
        if (intr == IPS_INTR_ON)
-               IPS_LOCK_SAVE(host->host_lock, cpu_flags);
+               spin_lock(host->host_lock);
 
        if ((ha->subsys->param[3] & 0x300000)
            && (ha->scb_activelist.count == 0)) {
@@ -2769,14 +2669,14 @@ ips_next(ips_ha_t * ha, int intr)
                item = ips_removeq_copp_head(&ha->copp_waitlist);
                ha->num_ioctl++;
                if (intr == IPS_INTR_ON)
-                       IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
+                       spin_unlock(host->host_lock);
                scb->scsi_cmd = item->scsi_cmd;
                kfree(item);
 
                ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
 
                if (intr == IPS_INTR_ON)
-                       IPS_LOCK_SAVE(host->host_lock, cpu_flags);
+                       spin_lock(host->host_lock);
                switch (ret) {
                case IPS_FAILURE:
                        if (scb->scsi_cmd) {
@@ -2846,7 +2746,7 @@ ips_next(ips_ha_t * ha, int intr)
                SC = ips_removeq_wait(&ha->scb_waitlist, q);
 
                if (intr == IPS_INTR_ON)
-                       IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* Unlock HA after command is taken off queue */
+                       spin_unlock(host->host_lock);   /* Unlock HA after command is taken off queue */
 
                SC->result = DID_OK;
                SC->host_scribble = NULL;
@@ -2919,7 +2819,7 @@ ips_next(ips_ha_t * ha, int intr)
                        scb->dcdb.transfer_length = 0;
                }
                if (intr == IPS_INTR_ON)
-                       IPS_LOCK_SAVE(host->host_lock, cpu_flags);
+                       spin_lock(host->host_lock);
 
                ret = ips_send_cmd(ha, scb);
 
@@ -2958,7 +2858,7 @@ ips_next(ips_ha_t * ha, int intr)
        }                       /* end while */
 
        if (intr == IPS_INTR_ON)
-               IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
+               spin_unlock(host->host_lock);
 }
 
 /****************************************************************************/
@@ -7004,7 +6904,6 @@ ips_register_scsi(int index)
        kfree(oldha);
        ips_sh[index] = sh;
        ips_ha[index] = ha;
-       IPS_SCSI_SET_DEVICE(sh, ha);
 
        /* Store away needed values for later use */
        sh->io_port = ha->io_addr;
@@ -7016,17 +6915,16 @@ ips_register_scsi(int index)
        sh->cmd_per_lun = sh->hostt->cmd_per_lun;
        sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
        sh->use_clustering = sh->hostt->use_clustering;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
        sh->max_sectors = 128;
-#endif
 
        sh->max_id = ha->ntargets;
        sh->max_lun = ha->nlun;
        sh->max_channel = ha->nbus - 1;
        sh->can_queue = ha->max_cmds - 1;
 
-       IPS_ADD_HOST(sh, NULL);
+       scsi_add_host(sh, NULL);
+       scsi_scan_host(sh);
+
        return 0;
 }
 
@@ -7069,7 +6967,7 @@ ips_module_init(void)
                return -ENODEV;
        ips_driver_template.module = THIS_MODULE;
        ips_order_controllers();
-       if (IPS_REGISTER_HOSTS(&ips_driver_template)) {
+       if (!ips_detect(&ips_driver_template)) {
                pci_unregister_driver(&ips_pci_driver);
                return -ENODEV;
        }
@@ -7087,7 +6985,6 @@ ips_module_init(void)
 static void __exit
 ips_module_exit(void)
 {
-       IPS_UNREGISTER_HOSTS(&ips_driver_template);
        pci_unregister_driver(&ips_pci_driver);
        unregister_reboot_notifier(&ips_notifier);
 }
@@ -7443,15 +7340,9 @@ ips_init_phase2(int index)
        return SUCCESS;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
 MODULE_LICENSE("GPL");
-#endif
-
 MODULE_DESCRIPTION("IBM ServeRAID Adapter Driver " IPS_VER_STRING);
-
-#ifdef MODULE_VERSION
 MODULE_VERSION(IPS_VER_STRING);
-#endif
 
 
 /*
index b726dcc..24123d5 100644 (file)
    /*
     * Some handy macros
     */
-   #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) || defined CONFIG_HIGHIO
-      #define IPS_HIGHIO
-   #endif
-
    #define IPS_HA(x)                   ((ips_ha_t *) x->hostdata)
    #define IPS_COMMAND_ID(ha, scb)     (int) (scb - ha->scbs)
    #define IPS_IS_TROMBONE(ha)         (((ha->device_id == IPS_DEVICEID_COPPERHEAD) && \
     #define IPS_SGLIST_SIZE(ha)       (IPS_USE_ENH_SGLIST(ha) ? \
                                          sizeof(IPS_ENH_SG_LIST) : sizeof(IPS_STD_SG_LIST))
 
-   #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
-      #define pci_set_dma_mask(dev,mask) ( mask > 0xffffffff ? 1:0 )
-      #define scsi_set_pci_device(sh,dev) (0)
-   #endif
-
-   #ifndef IRQ_NONE
-      typedef void irqreturn_t;
-      #define IRQ_NONE
-      #define IRQ_HANDLED
-      #define IRQ_RETVAL(x)
-   #endif
-   
-   #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-      #define IPS_REGISTER_HOSTS(SHT)      scsi_register_module(MODULE_SCSI_HA,SHT)
-      #define IPS_UNREGISTER_HOSTS(SHT)    scsi_unregister_module(MODULE_SCSI_HA,SHT)
-      #define IPS_ADD_HOST(shost,device)
-      #define IPS_REMOVE_HOST(shost)
-      #define IPS_SCSI_SET_DEVICE(sh,ha)   scsi_set_pci_device(sh, (ha)->pcidev)
-      #define IPS_PRINTK(level, pcidev, format, arg...)                 \
-            printk(level "%s %s:" format , "ips" ,     \
-            (pcidev)->slot_name , ## arg)
-      #define scsi_host_alloc(sh,size)         scsi_register(sh,size)
-      #define scsi_host_put(sh)             scsi_unregister(sh)
-   #else
-      #define IPS_REGISTER_HOSTS(SHT)      (!ips_detect(SHT))
-      #define IPS_UNREGISTER_HOSTS(SHT)
-      #define IPS_ADD_HOST(shost,device)   do { scsi_add_host(shost,device); scsi_scan_host(shost); } while (0)
-      #define IPS_REMOVE_HOST(shost)       scsi_remove_host(shost)
-      #define IPS_SCSI_SET_DEVICE(sh,ha)   do { } while (0)
-      #define IPS_PRINTK(level, pcidev, format, arg...)                 \
+  #define IPS_PRINTK(level, pcidev, format, arg...)                 \
             dev_printk(level , &((pcidev)->dev) , format , ## arg)
-   #endif
 
    #define MDELAY(n)                   \
        do {                            \
    #define pci_dma_hi32(a)         ((a >> 16) >> 16)
    #define pci_dma_lo32(a)         (a & 0xffffffff)
 
-   #if (BITS_PER_LONG > 32) || (defined CONFIG_HIGHMEM64G && defined IPS_HIGHIO)
+   #if (BITS_PER_LONG > 32) || defined(CONFIG_HIGHMEM64G)
       #define IPS_ENABLE_DMA64        (1)
    #else
       #define IPS_ENABLE_DMA64        (0)
    /*
     * Scsi_Host Template
     */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-   static int ips_proc24_info(char *, char **, off_t, int, int, int);
-   static void ips_select_queue_depth(struct Scsi_Host *, struct scsi_device *);
-   static int ips_biosparam(Disk *disk, kdev_t dev, int geom[]);
-#else
    static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
    static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
                sector_t capacity, int geom[]);
    static int ips_slave_configure(struct scsi_device *SDptr);
-#endif
 
 /*
  * Raid Command Formats
index 81e497d..0140766 100644 (file)
@@ -1,6 +1,6 @@
 /* jazz_esp.c: ESP front-end for MIPS JAZZ systems.
  *
- * Copyright (C) 2007 Thomas Bogendörfer (tsbogend@alpha.frankende)
+ * Copyright (C) 2007 Thomas Bogendörfer (tsbogend@alpha.frankende)
  */
 
 #include <linux/kernel.h>
index b4b5269..d70ddfd 100644 (file)
@@ -76,8 +76,8 @@ static void sas_scsi_task_done(struct sas_task *task)
                        hs = DID_NO_CONNECT;
                        break;
                case SAS_DATA_UNDERRUN:
-                       sc->resid = ts->residual;
-                       if (sc->request_bufflen - sc->resid < sc->underflow)
+                       scsi_set_resid(sc, ts->residual);
+                       if (scsi_bufflen(sc) - scsi_get_resid(sc) < sc->underflow)
                                hs = DID_ERROR;
                        break;
                case SAS_DATA_OVERRUN:
@@ -161,9 +161,9 @@ static struct sas_task *sas_create_task(struct scsi_cmnd *cmd,
        task->ssp_task.task_attr = sas_scsi_get_task_attr(cmd);
        memcpy(task->ssp_task.cdb, cmd->cmnd, 16);
 
-       task->scatter = cmd->request_buffer;
-       task->num_scatter = cmd->use_sg;
-       task->total_xfer_len = cmd->request_bufflen;
+       task->scatter = scsi_sglist(cmd);
+       task->num_scatter = scsi_sg_count(cmd);
+       task->total_xfer_len = scsi_bufflen(cmd);
        task->data_dir = cmd->sc_data_direction;
 
        task->task_done = sas_scsi_task_done;
index 5806ede..b12ad7c 100644 (file)
@@ -77,7 +77,7 @@ static int mac53c94_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *
                for (i = 0; i < cmd->cmd_len; ++i)
                        printk(" %.2x", cmd->cmnd[i]);
                printk("\n" KERN_DEBUG "use_sg=%d request_bufflen=%d request_buffer=%p\n",
-                      cmd->use_sg, cmd->request_bufflen, cmd->request_buffer);
+                      scsi_sg_count(cmd), scsi_bufflen(cmd), scsi_sglist(cmd));
        }
 #endif
 
@@ -173,8 +173,7 @@ static void mac53c94_start(struct fsc_state *state)
        writeb(CMD_SELECT, &regs->command);
        state->phase = selecting;
 
-       if (cmd->use_sg > 0 || cmd->request_bufflen != 0)
-               set_dma_cmds(state, cmd);
+       set_dma_cmds(state, cmd);
 }
 
 static irqreturn_t do_mac53c94_interrupt(int irq, void *dev_id)
@@ -262,7 +261,7 @@ static void mac53c94_interrupt(int irq, void *dev_id)
                writeb(CMD_NOP, &regs->command);
                /* set DMA controller going if any data to transfer */
                if ((stat & (STAT_MSG|STAT_CD)) == 0
-                   && (cmd->use_sg > 0 || cmd->request_bufflen != 0)) {
+                   && (scsi_sg_count(cmd) > 0 || scsi_bufflen(cmd))) {
                        nb = cmd->SCp.this_residual;
                        if (nb > 0xfff0)
                                nb = 0xfff0;
@@ -310,14 +309,7 @@ static void mac53c94_interrupt(int irq, void *dev_id)
                        printk(KERN_DEBUG "intr %x before data xfer complete\n", intr);
                }
                writel(RUN << 16, &dma->control);       /* stop dma */
-               if (cmd->use_sg != 0) {
-                       pci_unmap_sg(state->pdev,
-                               (struct scatterlist *)cmd->request_buffer,
-                               cmd->use_sg, cmd->sc_data_direction);
-               } else {
-                       pci_unmap_single(state->pdev, state->dma_addr,
-                               cmd->request_bufflen, cmd->sc_data_direction);
-               }
+               scsi_dma_unmap(cmd);
                /* should check dma status */
                writeb(CMD_I_COMPLETE, &regs->command);
                state->phase = completing;
@@ -365,47 +357,35 @@ static void cmd_done(struct fsc_state *state, int result)
  */
 static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd)
 {
-       int i, dma_cmd, total;
+       int i, dma_cmd, total, nseg;
        struct scatterlist *scl;
        struct dbdma_cmd *dcmds;
        dma_addr_t dma_addr;
        u32 dma_len;
 
+       nseg = scsi_dma_map(cmd);
+       BUG_ON(nseg < 0);
+       if (!nseg)
+               return;
+
        dma_cmd = cmd->sc_data_direction == DMA_TO_DEVICE ?
                        OUTPUT_MORE : INPUT_MORE;
        dcmds = state->dma_cmds;
-       if (cmd->use_sg > 0) {
-               int nseg;
-
-               total = 0;
-               scl = (struct scatterlist *) cmd->request_buffer;
-               nseg = pci_map_sg(state->pdev, scl, cmd->use_sg,
-                               cmd->sc_data_direction);
-               for (i = 0; i < nseg; ++i) {
-                       dma_addr = sg_dma_address(scl);
-                       dma_len = sg_dma_len(scl);
-                       if (dma_len > 0xffff)
-                               panic("mac53c94: scatterlist element >= 64k");
-                       total += dma_len;
-                       st_le16(&dcmds->req_count, dma_len);
-                       st_le16(&dcmds->command, dma_cmd);
-                       st_le32(&dcmds->phy_addr, dma_addr);
-                       dcmds->xfer_status = 0;
-                       ++scl;
-                       ++dcmds;
-               }
-       } else {
-               total = cmd->request_bufflen;
-               if (total > 0xffff)
-                       panic("mac53c94: transfer size >= 64k");
-               dma_addr = pci_map_single(state->pdev, cmd->request_buffer,
-                                         total, cmd->sc_data_direction);
-               state->dma_addr = dma_addr;
-               st_le16(&dcmds->req_count, total);
+       total = 0;
+
+       scsi_for_each_sg(cmd, scl, nseg, i) {
+               dma_addr = sg_dma_address(scl);
+               dma_len = sg_dma_len(scl);
+               if (dma_len > 0xffff)
+                       panic("mac53c94: scatterlist element >= 64k");
+               total += dma_len;
+               st_le16(&dcmds->req_count, dma_len);
+               st_le16(&dcmds->command, dma_cmd);
                st_le32(&dcmds->phy_addr, dma_addr);
                dcmds->xfer_status = 0;
                ++dcmds;
        }
+
        dma_cmd += OUTPUT_LAST - OUTPUT_MORE;
        st_le16(&dcmds[-1].command, dma_cmd);
        st_le16(&dcmds->command, DBDMA_STOP);
index 3cce75d..40ee07d 100644 (file)
@@ -3571,7 +3571,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
                        /*
                         * The user passthru structure
                         */
-                       upthru = (mega_passthru __user *)MBOX(uioc)->xferaddr;
+                       upthru = (mega_passthru __user *)(unsigned long)MBOX(uioc)->xferaddr;
 
                        /*
                         * Copy in the user passthru here.
@@ -3623,7 +3623,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
                                /*
                                 * Get the user data
                                 */
-                               if( copy_from_user(data, (char __user *)uxferaddr,
+                               if( copy_from_user(data, (char __user *)(unsigned long) uxferaddr,
                                                        pthru->dataxferlen) ) {
                                        rval = (-EFAULT);
                                        goto freemem_and_return;
@@ -3649,7 +3649,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
                         * Is data going up-stream
                         */
                        if( pthru->dataxferlen && (uioc.flags & UIOC_RD) ) {
-                               if( copy_to_user((char __user *)uxferaddr, data,
+                               if( copy_to_user((char __user *)(unsigned long) uxferaddr, data,
                                                        pthru->dataxferlen) ) {
                                        rval = (-EFAULT);
                                }
@@ -3702,7 +3702,7 @@ freemem_and_return:
                                /*
                                 * Get the user data
                                 */
-                               if( copy_from_user(data, (char __user *)uxferaddr,
+                               if( copy_from_user(data, (char __user *)(unsigned long) uxferaddr,
                                                        uioc.xferlen) ) {
 
                                        pci_free_consistent(pdev,
@@ -3742,7 +3742,7 @@ freemem_and_return:
                         * Is data going up-stream
                         */
                        if( uioc.xferlen && (uioc.flags & UIOC_RD) ) {
-                               if( copy_to_user((char __user *)uxferaddr, data,
+                               if( copy_to_user((char __user *)(unsigned long) uxferaddr, data,
                                                        uioc.xferlen) ) {
 
                                        rval = (-EFAULT);
diff --git a/drivers/scsi/mvme16x.c b/drivers/scsi/mvme16x.c
deleted file mode 100644 (file)
index 575fe6f..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Detection routine for the NCR53c710 based MVME16x SCSI Controllers for Linux.
- *
- * Based on work by Alan Hourihane
- */
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/blkdev.h>
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/mvme16xhw.h>
-#include <asm/irq.h>
-
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "53c7xx.h"
-#include "mvme16x.h"
-
-#include<linux/stat.h>
-
-
-int mvme16x_scsi_detect(struct scsi_host_template *tpnt)
-{
-    static unsigned char called = 0;
-    int clock;
-    long long options;
-
-    if (!MACH_IS_MVME16x)
-               return 0;
-    if (mvme16x_config & MVME16x_CONFIG_NO_SCSICHIP) {
-       printk ("SCSI detection disabled, SCSI chip not present\n");
-       return 0;
-    }
-    if (called)
-       return 0;
-
-    tpnt->proc_name = "MVME16x";
-
-    options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT;
-
-    clock = 66000000;  /* 66MHz SCSI Clock */
-
-    ncr53c7xx_init(tpnt, 0, 710, (unsigned long)0xfff47000,
-                       0, MVME16x_IRQ_SCSI, DMA_NONE,
-                       options, clock);
-    called = 1;
-    return 1;
-}
-
-static int mvme16x_scsi_release(struct Scsi_Host *shost)
-{
-       if (shost->irq)
-               free_irq(shost->irq, NULL);
-       if (shost->dma_channel != 0xff)
-               free_dma(shost->dma_channel);
-       if (shost->io_port && shost->n_io_port)
-               release_region(shost->io_port, shost->n_io_port);
-       scsi_unregister(shost);
-       return 0;
-}
-
-static struct scsi_host_template driver_template = {
-       .name                   = "MVME16x NCR53c710 SCSI",
-       .detect                 = mvme16x_scsi_detect,
-       .release                = mvme16x_scsi_release,
-       .queuecommand           = NCR53c7xx_queue_command,
-       .abort                  = NCR53c7xx_abort,
-       .reset                  = NCR53c7xx_reset,
-       .can_queue              = 24,
-       .this_id                = 7,
-       .sg_tablesize           = 63,
-       .cmd_per_lun            = 3,
-       .use_clustering         = DISABLE_CLUSTERING
-};
-
-
-#include "scsi_module.c"
diff --git a/drivers/scsi/mvme16x.h b/drivers/scsi/mvme16x.h
deleted file mode 100644 (file)
index 73e33b3..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef MVME16x_SCSI_H
-#define MVME16x_SCSI_H
-
-#include <linux/types.h>
-
-int mvme16x_scsi_detect(struct scsi_host_template *);
-const char *NCR53c7x0_info(void);
-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int NCR53c7xx_abort(Scsi_Cmnd *);
-int NCR53c7x0_release (struct Scsi_Host *);
-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
-void NCR53c7x0_intr(int irq, void *dev_id);
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 3
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 24
-#endif
-
-#include <scsi/scsicam.h>
-
-#endif /* MVME16x_SCSI_H */
index f6f561d..8cc9e64 100644 (file)
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_ioctl.h>
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
-# include <linux/blk.h>
-#endif
-
 #include "nsp32.h"
 
 
@@ -199,17 +195,9 @@ static int  __init    init_nsp32  (void);
 static void __exit    exit_nsp32  (void);
 
 /* struct struct scsi_host_template */
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
 static int         nsp32_proc_info   (struct Scsi_Host *, char *, char **, off_t, int, int);
-#else
-static int         nsp32_proc_info   (char *, char **, off_t, int, int, int);
-#endif
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
 static int         nsp32_detect      (struct pci_dev *pdev);
-#else
-static int         nsp32_detect      (struct scsi_host_template *);
-#endif
 static int         nsp32_queuecommand(struct scsi_cmnd *,
                void (*done)(struct scsi_cmnd *));
 static const char *nsp32_info        (struct Scsi_Host *);
@@ -296,15 +284,7 @@ static struct scsi_host_template nsp32_template = {
        .eh_abort_handler               = nsp32_eh_abort,
        .eh_bus_reset_handler           = nsp32_eh_bus_reset,
        .eh_host_reset_handler          = nsp32_eh_host_reset,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74))
-       .detect                         = nsp32_detect,
-       .release                        = nsp32_release,
-#endif
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
-       .use_new_eh_code                = 1,
-#else
 /*     .highmem_io                     = 1, */
-#endif
 };
 
 #include "nsp32_io.h"
@@ -739,7 +719,7 @@ static int nsp32_selection_autoscsi(struct scsi_cmnd *SCpnt)
        command = 0;
        command |= (TRANSFER_GO | ALL_COUNTER_CLR);
        if (data->trans_method & NSP32_TRANSFER_BUSMASTER) {
-               if (SCpnt->request_bufflen > 0) {
+               if (scsi_bufflen(SCpnt) > 0) {
                        command |= BM_START;
                }
        } else if (data->trans_method & NSP32_TRANSFER_MMIO) {
@@ -888,31 +868,28 @@ static int nsp32_reselection(struct scsi_cmnd *SCpnt, unsigned char newlun)
 static int nsp32_setup_sg_table(struct scsi_cmnd *SCpnt)
 {
        nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
-       struct scatterlist   *sgl;
+       struct scatterlist *sg;
        nsp32_sgtable *sgt = data->cur_lunt->sglun->sgt;
        int num, i;
        u32_le l;
 
-       if (SCpnt->request_bufflen == 0) {
-               return TRUE;
-       }
-
        if (sgt == NULL) {
                nsp32_dbg(NSP32_DEBUG_SGLIST, "SGT == null");
                return FALSE;
        }
 
-       if (SCpnt->use_sg) {
-               sgl = (struct scatterlist *)SCpnt->request_buffer;
-               num = pci_map_sg(data->Pci, sgl, SCpnt->use_sg,
-                                SCpnt->sc_data_direction);
-               for (i = 0; i < num; i++) {
+       num = scsi_dma_map(SCpnt);
+       if (!num)
+               return TRUE;
+       else if (num < 0)
+               return FALSE;
+       else {
+               scsi_for_each_sg(SCpnt, sg, num, i) {
                        /*
                         * Build nsp32_sglist, substitute sg dma addresses.
                         */
-                       sgt[i].addr = cpu_to_le32(sg_dma_address(sgl));
-                       sgt[i].len  = cpu_to_le32(sg_dma_len(sgl));
-                       sgl++;
+                       sgt[i].addr = cpu_to_le32(sg_dma_address(sg));
+                       sgt[i].len  = cpu_to_le32(sg_dma_len(sg));
 
                        if (le32_to_cpu(sgt[i].len) > 0x10000) {
                                nsp32_msg(KERN_ERR,
@@ -929,23 +906,6 @@ static int nsp32_setup_sg_table(struct scsi_cmnd *SCpnt)
                /* set end mark */
                l = le32_to_cpu(sgt[num-1].len);
                sgt[num-1].len = cpu_to_le32(l | SGTEND);
-
-       } else {
-               SCpnt->SCp.have_data_in = pci_map_single(data->Pci,
-                       SCpnt->request_buffer, SCpnt->request_bufflen,
-                       SCpnt->sc_data_direction);
-
-               sgt[0].addr = cpu_to_le32(SCpnt->SCp.have_data_in);
-               sgt[0].len  = cpu_to_le32(SCpnt->request_bufflen | SGTEND); /* set end mark */
-
-               if (SCpnt->request_bufflen > 0x10000) {
-                       nsp32_msg(KERN_ERR,
-                                 "can't transfer over 64KB at a time, size=0x%lx", SCpnt->request_bufflen);
-                       return FALSE;
-               }
-               nsp32_dbg(NSP32_DEBUG_SGLIST, "single : addr 0x%lx len=0x%lx",
-                         le32_to_cpu(sgt[0].addr),
-                         le32_to_cpu(sgt[0].len ));
        }
 
        return TRUE;
@@ -962,7 +922,7 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
                  "enter. target: 0x%x LUN: 0x%x cmnd: 0x%x cmndlen: 0x%x "
                  "use_sg: 0x%x reqbuf: 0x%lx reqlen: 0x%x",
                  SCpnt->device->id, SCpnt->device->lun, SCpnt->cmnd[0], SCpnt->cmd_len,
-                 SCpnt->use_sg, SCpnt->request_buffer, SCpnt->request_bufflen);
+                 scsi_sg_count(SCpnt), scsi_sglist(SCpnt), scsi_bufflen(SCpnt));
 
        if (data->CurrentSC != NULL) {
                nsp32_msg(KERN_ERR, "Currentsc != NULL. Cancel this command request");
@@ -994,10 +954,10 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
        data->CurrentSC      = SCpnt;
        SCpnt->SCp.Status    = CHECK_CONDITION;
        SCpnt->SCp.Message   = 0;
-       SCpnt->resid         = SCpnt->request_bufflen;
+       scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
 
-       SCpnt->SCp.ptr              = (char *) SCpnt->request_buffer;
-       SCpnt->SCp.this_residual    = SCpnt->request_bufflen;
+       SCpnt->SCp.ptr              = (char *)scsi_sglist(SCpnt);
+       SCpnt->SCp.this_residual    = scsi_bufflen(SCpnt);
        SCpnt->SCp.buffer           = NULL;
        SCpnt->SCp.buffers_residual = 0;
 
@@ -1210,13 +1170,9 @@ static irqreturn_t do_nsp32_isr(int irq, void *dev_id)
        unsigned long flags;
        int ret;
        int handled = 0;
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
        struct Scsi_Host *host = data->Host;
+
        spin_lock_irqsave(host->host_lock, flags);
-#else
-       spin_lock_irqsave(&io_request_lock, flags);
-#endif
 
        /*
         * IRQ check, then enable IRQ mask
@@ -1312,7 +1268,7 @@ static irqreturn_t do_nsp32_isr(int irq, void *dev_id)
                }
 
                if ((auto_stat & DATA_IN_PHASE) &&
-                   (SCpnt->resid > 0) &&
+                   (scsi_get_resid(SCpnt) > 0) &&
                    ((nsp32_read2(base, FIFO_REST_CNT) & FIFO_REST_MASK) != 0)) {
                        printk( "auto+fifo\n");
                        //nsp32_pio_read(SCpnt);
@@ -1333,7 +1289,7 @@ static irqreturn_t do_nsp32_isr(int irq, void *dev_id)
                        nsp32_dbg(NSP32_DEBUG_INTR, "SSACK=0x%lx", 
                                    nsp32_read4(base, SAVED_SACK_CNT));
 
-                       SCpnt->resid = 0; /* all data transfered! */
+                       scsi_set_resid(SCpnt, 0); /* all data transfered! */
                }
 
                /*
@@ -1480,11 +1436,7 @@ static irqreturn_t do_nsp32_isr(int irq, void *dev_id)
        nsp32_write2(base, IRQ_CONTROL, 0);
 
  out2:
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
        spin_unlock_irqrestore(host->host_lock, flags);
-#else
-       spin_unlock_irqrestore(&io_request_lock, flags);
-#endif
 
        nsp32_dbg(NSP32_DEBUG_INTR, "exit");
 
@@ -1499,28 +1451,15 @@ static irqreturn_t do_nsp32_isr(int irq, void *dev_id)
                        nsp32_dbg(NSP32_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length,  length - (pos - buffer));\
                } \
        } while(0)
-static int nsp32_proc_info(
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) 
-       struct Scsi_Host *host,
-#endif
-       char             *buffer,
-       char            **start,
-       off_t             offset,
-       int               length,
-#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) 
-       int               hostno,
-#endif
-       int               inout)
+
+static int nsp32_proc_info(struct Scsi_Host *host, char *buffer, char **start,
+                          off_t offset, int length, int inout)
 {
        char             *pos = buffer;
        int               thislength;
        unsigned long     flags;
        nsp32_hw_data    *data;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) 
        int               hostno;
-#else
-       struct Scsi_Host *host;
-#endif
        unsigned int      base;
        unsigned char     mode_reg;
        int               id, speed;
@@ -1531,15 +1470,7 @@ static int nsp32_proc_info(
                return -EINVAL;
        }
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) 
        hostno = host->host_no;
-#else
-       /* search this HBA host */
-       host = scsi_host_hn_get(hostno);
-       if (host == NULL) {
-               return -ESRCH;
-       }
-#endif
        data = (nsp32_hw_data *)host->hostdata;
        base = host->io_port;
 
@@ -1626,25 +1557,8 @@ static void nsp32_scsi_done(struct scsi_cmnd *SCpnt)
        nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
        unsigned int   base = SCpnt->device->host->io_port;
 
-       /*
-        * unmap pci
-        */
-       if (SCpnt->request_bufflen == 0) {
-               goto skip;
-       }
+       scsi_dma_unmap(SCpnt);
 
-       if (SCpnt->use_sg) {
-               pci_unmap_sg(data->Pci,
-                            (struct scatterlist *)SCpnt->request_buffer,
-                            SCpnt->use_sg, SCpnt->sc_data_direction);
-       } else {
-               pci_unmap_single(data->Pci,
-                                (u32)SCpnt->SCp.have_data_in,
-                                SCpnt->request_bufflen,
-                                SCpnt->sc_data_direction);
-       }
-
- skip:
        /*
         * clear TRANSFERCONTROL_BM_START
         */
@@ -1800,7 +1714,7 @@ static int nsp32_busfree_occur(struct scsi_cmnd *SCpnt, unsigned short execph)
                SCpnt->SCp.Message = 0;
                nsp32_dbg(NSP32_DEBUG_BUSFREE, 
                          "normal end stat=0x%x resid=0x%x\n",
-                         SCpnt->SCp.Status, SCpnt->resid);
+                         SCpnt->SCp.Status, scsi_get_resid(SCpnt));
                SCpnt->result = (DID_OK             << 16) |
                                (SCpnt->SCp.Message <<  8) |
                                (SCpnt->SCp.Status  <<  0);
@@ -1844,7 +1758,7 @@ static void nsp32_adjust_busfree(struct scsi_cmnd *SCpnt, unsigned int s_sacklen
        unsigned int          restlen, sentlen;
        u32_le                len, addr;
 
-       nsp32_dbg(NSP32_DEBUG_SGLIST, "old resid=0x%x", SCpnt->resid);
+       nsp32_dbg(NSP32_DEBUG_SGLIST, "old resid=0x%x", scsi_get_resid(SCpnt));
 
        /* adjust saved SACK count with 4 byte start address boundary */
        s_sacklen -= le32_to_cpu(sgt[old_entry].addr) & 3;
@@ -1888,12 +1802,12 @@ static void nsp32_adjust_busfree(struct scsi_cmnd *SCpnt, unsigned int s_sacklen
        return;
 
  last:
-       if (SCpnt->resid < sentlen) {
+       if (scsi_get_resid(SCpnt) < sentlen) {
                nsp32_msg(KERN_ERR, "resid underflow");
        }
 
-       SCpnt->resid -= sentlen;
-       nsp32_dbg(NSP32_DEBUG_SGLIST, "new resid=0x%x", SCpnt->resid);
+       scsi_set_resid(SCpnt, scsi_get_resid(SCpnt) - sentlen);
+       nsp32_dbg(NSP32_DEBUG_SGLIST, "new resid=0x%x", scsi_get_resid(SCpnt));
 
        /* update hostdata and lun */
 
@@ -2022,7 +1936,7 @@ static void nsp32_restart_autoscsi(struct scsi_cmnd *SCpnt, unsigned short comma
        transfer = 0;
        transfer |= (TRANSFER_GO | ALL_COUNTER_CLR);
        if (data->trans_method & NSP32_TRANSFER_BUSMASTER) {
-               if (SCpnt->request_bufflen > 0) {
+               if (scsi_bufflen(SCpnt) > 0) {
                        transfer |= BM_START;
                }
        } else if (data->trans_method & NSP32_TRANSFER_MMIO) {
@@ -2674,17 +2588,7 @@ static void nsp32_sack_negate(nsp32_hw_data *data)
  *     0x900-0xbff: (map same 0x800-0x8ff I/O port image repeatedly)
  *     0xc00-0xfff: CardBus status registers
  */
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
-#define DETECT_OK 0
-#define DETECT_NG 1
-#define PCIDEV    pdev
 static int nsp32_detect(struct pci_dev *pdev)
-#else
-#define DETECT_OK 1
-#define DETECT_NG 0
-#define PCIDEV    (data->Pci)
-static int nsp32_detect(struct scsi_host_template *sht)
-#endif
 {
        struct Scsi_Host *host; /* registered host structure */
        struct resource  *res;
@@ -2697,11 +2601,7 @@ static int nsp32_detect(struct scsi_host_template *sht)
        /*
         * register this HBA as SCSI device
         */
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
        host = scsi_host_alloc(&nsp32_template, sizeof(nsp32_hw_data));
-#else
-       host = scsi_register(sht, sizeof(nsp32_hw_data));
-#endif
        if (host == NULL) {
                nsp32_msg (KERN_ERR, "failed to scsi register");
                goto err;
@@ -2719,9 +2619,6 @@ static int nsp32_detect(struct scsi_host_template *sht)
        host->unique_id = data->BaseAddress;
        host->n_io_port = data->NumAddress;
        host->base      = (unsigned long)data->MmioAddress;
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,63))
-       scsi_set_pci_device(host, PCIDEV);
-#endif
 
        data->Host      = host;
        spin_lock_init(&(data->Lock));
@@ -2776,7 +2673,7 @@ static int nsp32_detect(struct scsi_host_template *sht)
        /*
         * setup DMA 
         */
-       if (pci_set_dma_mask(PCIDEV, DMA_32BIT_MASK) != 0) {
+       if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) {
                nsp32_msg (KERN_ERR, "failed to set PCI DMA mask");
                goto scsi_unregister;
        }
@@ -2784,7 +2681,7 @@ static int nsp32_detect(struct scsi_host_template *sht)
        /*
         * allocate autoparam DMA resource.
         */
-       data->autoparam = pci_alloc_consistent(PCIDEV, sizeof(nsp32_autoparam), &(data->auto_paddr));
+       data->autoparam = pci_alloc_consistent(pdev, sizeof(nsp32_autoparam), &(data->auto_paddr));
        if (data->autoparam == NULL) {
                nsp32_msg(KERN_ERR, "failed to allocate DMA memory");
                goto scsi_unregister;
@@ -2793,7 +2690,7 @@ static int nsp32_detect(struct scsi_host_template *sht)
        /*
         * allocate scatter-gather DMA resource.
         */
-       data->sg_list = pci_alloc_consistent(PCIDEV, NSP32_SG_TABLE_SIZE,
+       data->sg_list = pci_alloc_consistent(pdev, NSP32_SG_TABLE_SIZE,
                                             &(data->sg_paddr));
        if (data->sg_list == NULL) {
                nsp32_msg(KERN_ERR, "failed to allocate DMA memory");
@@ -2883,16 +2780,14 @@ static int nsp32_detect(struct scsi_host_template *sht)
                goto free_irq;
         }
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
-       ret = scsi_add_host(host, &PCIDEV->dev);
+       ret = scsi_add_host(host, &pdev->dev);
        if (ret) {
                nsp32_msg(KERN_ERR, "failed to add scsi host");
                goto free_region;
        }
        scsi_scan_host(host);
-#endif
-       pci_set_drvdata(PCIDEV, host);
-       return DETECT_OK;
+       pci_set_drvdata(pdev, host);
+       return 0;
 
  free_region:
        release_region(host->io_port, host->n_io_port);
@@ -2901,22 +2796,19 @@ static int nsp32_detect(struct scsi_host_template *sht)
        free_irq(host->irq, data);
 
  free_sg_list:
-       pci_free_consistent(PCIDEV, NSP32_SG_TABLE_SIZE,
+       pci_free_consistent(pdev, NSP32_SG_TABLE_SIZE,
                            data->sg_list, data->sg_paddr);
 
  free_autoparam:
-       pci_free_consistent(PCIDEV, sizeof(nsp32_autoparam),
+       pci_free_consistent(pdev, sizeof(nsp32_autoparam),
                            data->autoparam, data->auto_paddr);
        
  scsi_unregister:
        scsi_host_put(host);
 
  err:
-       return DETECT_NG;
+       return 1;
 }
-#undef DETECT_OK
-#undef DETECT_NG
-#undef PCIDEV
 
 static int nsp32_release(struct Scsi_Host *host)
 {
@@ -3525,11 +3417,7 @@ static int __devinit nsp32_probe(struct pci_dev *pdev, const struct pci_device_i
 
        pci_set_master(pdev);
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
        ret = nsp32_detect(pdev);
-#else
-       ret = scsi_register_host(&nsp32_template);
-#endif
 
        nsp32_msg(KERN_INFO, "irq: %i mmio: %p+0x%lx slot: %s model: %s",
                  pdev->irq,
@@ -3544,25 +3432,17 @@ static int __devinit nsp32_probe(struct pci_dev *pdev, const struct pci_device_i
 
 static void __devexit nsp32_remove(struct pci_dev *pdev)
 {
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
        struct Scsi_Host *host = pci_get_drvdata(pdev);
-#endif
 
        nsp32_dbg(NSP32_DEBUG_REGISTER, "enter");
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
         scsi_remove_host(host);
 
        nsp32_release(host);
 
        scsi_host_put(host);
-#else
-       scsi_unregister_host(&nsp32_template);  
-#endif
 }
 
-
-
 static struct pci_driver nsp32_driver = {
        .name           = "nsp32",
        .id_table       = nsp32_pci_table,
index ffe75c4..2695b71 100644 (file)
@@ -370,8 +370,6 @@ SYM53C500_intr(int irq, void *dev_id)
        DEB(unsigned char seq_reg;)
        unsigned char status, int_reg;
        unsigned char pio_status;
-       struct scatterlist *sglist;
-       unsigned int sgcount;
        int port_base = dev->io_port;
        struct sym53c500_data *data =
            (struct sym53c500_data *)dev->hostdata;
@@ -434,20 +432,19 @@ SYM53C500_intr(int irq, void *dev_id)
        switch (status & 0x07) {        /* scsi phase */
        case 0x00:                      /* DATA-OUT */
                if (int_reg & 0x10) {   /* Target requesting info transfer */
+                       struct scatterlist *sg;
+                       int i;
+
                        curSC->SCp.phase = data_out;
                        VDEB(printk("SYM53C500: Data-Out phase\n"));
                        outb(FLUSH_FIFO, port_base + CMD_REG);
-                       LOAD_DMA_COUNT(port_base, curSC->request_bufflen);      /* Max transfer size */
+                       LOAD_DMA_COUNT(port_base, scsi_bufflen(curSC)); /* Max transfer size */
                        outb(TRANSFER_INFO | DMA_OP, port_base + CMD_REG);
-                       if (!curSC->use_sg)     /* Don't use scatter-gather */
-                               SYM53C500_pio_write(fast_pio, port_base, curSC->request_buffer, curSC->request_bufflen);
-                       else {  /* use scatter-gather */
-                               sgcount = curSC->use_sg;
-                               sglist = curSC->request_buffer;
-                               while (sgcount--) {
-                                       SYM53C500_pio_write(fast_pio, port_base, page_address(sglist->page) + sglist->offset, sglist->length);
-                                       sglist++;
-                               }
+
+                       scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
+                               SYM53C500_pio_write(fast_pio, port_base,
+                                                   page_address(sg->page) + sg->offset,
+                                                   sg->length);
                        }
                        REG0(port_base);
                }
@@ -455,20 +452,19 @@ SYM53C500_intr(int irq, void *dev_id)
 
        case 0x01:              /* DATA-IN */
                if (int_reg & 0x10) {   /* Target requesting info transfer */
+                       struct scatterlist *sg;
+                       int i;
+
                        curSC->SCp.phase = data_in;
                        VDEB(printk("SYM53C500: Data-In phase\n"));
                        outb(FLUSH_FIFO, port_base + CMD_REG);
-                       LOAD_DMA_COUNT(port_base, curSC->request_bufflen);      /* Max transfer size */
+                       LOAD_DMA_COUNT(port_base, scsi_bufflen(curSC)); /* Max transfer size */
                        outb(TRANSFER_INFO | DMA_OP, port_base + CMD_REG);
-                       if (!curSC->use_sg)     /* Don't use scatter-gather */
-                               SYM53C500_pio_read(fast_pio, port_base, curSC->request_buffer, curSC->request_bufflen);
-                       else {  /* Use scatter-gather */
-                               sgcount = curSC->use_sg;
-                               sglist = curSC->request_buffer;
-                               while (sgcount--) {
-                                       SYM53C500_pio_read(fast_pio, port_base, page_address(sglist->page) + sglist->offset, sglist->length);
-                                       sglist++;
-                               }
+
+                       scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
+                               SYM53C500_pio_read(fast_pio, port_base,
+                                                  page_address(sg->page) + sg->offset,
+                                                  sg->length);
                        }
                        REG0(port_base);
                }
@@ -578,7 +574,7 @@ SYM53C500_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 
        DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n", 
            SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->device->id, 
-           SCpnt->device->lun,  SCpnt->request_bufflen));
+           SCpnt->device->lun,  scsi_bufflen(SCpnt)));
 
        VDEB(for (i = 0; i < SCpnt->cmd_len; i++)
            printk("cmd[%d]=%02x  ", i, SCpnt->cmnd[i]));
index ca46346..0f04258 100644 (file)
@@ -1633,7 +1633,7 @@ struct qla_init_msix_entry {
        uint16_t entry;
        uint16_t index;
        const char *name;
-       irqreturn_t (*handler)(int, void *);
+       irq_handler_t handler;
 };
 
 static struct qla_init_msix_entry imsix_entries[QLA_MSIX_ENTRIES] = {
index 6437d02..fcc184c 100644 (file)
@@ -6,176 +6,9 @@
  */
 
 #include "ql4_def.h"
-#include <scsi/scsi_dbg.h>
-
-#if 0
-
-static void qla4xxx_print_srb_info(struct srb * srb)
-{
-       printk("%s: srb = 0x%p, flags=0x%02x\n", __func__, srb, srb->flags);
-       printk("%s: cmd = 0x%p, saved_dma_handle = 0x%lx\n",
-              __func__, srb->cmd, (unsigned long) srb->dma_handle);
-       printk("%s: fw_ddb_index = %d, lun = %d\n",
-              __func__, srb->fw_ddb_index, srb->cmd->device->lun);
-       printk("%s: iocb_tov = %d\n",
-              __func__, srb->iocb_tov);
-       printk("%s: cc_stat = 0x%x, r_start = 0x%lx, u_start = 0x%lx\n\n",
-              __func__, srb->cc_stat, srb->r_start, srb->u_start);
-}
-
-void qla4xxx_print_scsi_cmd(struct scsi_cmnd *cmd)
-{
-       printk("SCSI Command = 0x%p, Handle=0x%p\n", cmd, cmd->host_scribble);
-       printk("  b=%d, t=%02xh, l=%02xh, cmd_len = %02xh\n",
-              cmd->device->channel, cmd->device->id, cmd->device->lun,
-              cmd->cmd_len);
-       scsi_print_command(cmd);
-       printk("  seg_cnt = %d\n", cmd->use_sg);
-       printk("  request buffer = 0x%p, request buffer len = 0x%x\n",
-              cmd->request_buffer, cmd->request_bufflen);
-       if (cmd->use_sg) {
-               struct scatterlist *sg;
-               sg = (struct scatterlist *)cmd->request_buffer;
-               printk("  SG buffer: \n");
-               qla4xxx_dump_buffer((caddr_t) sg,
-                                   (cmd->use_sg * sizeof(*sg)));
-       }
-       printk("  tag = %d, transfersize = 0x%x \n", cmd->tag,
-              cmd->transfersize);
-       printk("  Pid = %d, SP = 0x%p\n", (int)cmd->pid, cmd->SCp.ptr);
-       printk("  underflow size = 0x%x, direction=0x%x\n", cmd->underflow,
-              cmd->sc_data_direction);
-       printk("  Current time (jiffies) = 0x%lx, "
-              "timeout expires = 0x%lx\n", jiffies, cmd->eh_timeout.expires);
-       qla4xxx_print_srb_info((struct srb *) cmd->SCp.ptr);
-}
-
-void __dump_registers(struct scsi_qla_host *ha)
-{
-       uint8_t i;
-       for (i = 0; i < MBOX_REG_COUNT; i++) {
-               printk(KERN_INFO "0x%02X mailbox[%d]      = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg, mailbox[i]), i,
-                      readw(&ha->reg->mailbox[i]));
-       }
-       printk(KERN_INFO "0x%02X flash_address   = 0x%08X\n",
-              (uint8_t) offsetof(struct isp_reg, flash_address),
-              readw(&ha->reg->flash_address));
-       printk(KERN_INFO "0x%02X flash_data      = 0x%08X\n",
-              (uint8_t) offsetof(struct isp_reg, flash_data),
-              readw(&ha->reg->flash_data));
-       printk(KERN_INFO "0x%02X ctrl_status     = 0x%08X\n",
-              (uint8_t) offsetof(struct isp_reg, ctrl_status),
-              readw(&ha->reg->ctrl_status));
-       if (is_qla4010(ha)) {
-               printk(KERN_INFO "0x%02X nvram           = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg, u1.isp4010.nvram),
-                      readw(&ha->reg->u1.isp4010.nvram));
-       }
-
-       else if (is_qla4022(ha) | is_qla4032(ha)) {
-               printk(KERN_INFO "0x%02X intr_mask       = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u1.isp4022.intr_mask),
-                      readw(&ha->reg->u1.isp4022.intr_mask));
-               printk(KERN_INFO "0x%02X nvram           = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg, u1.isp4022.nvram),
-                      readw(&ha->reg->u1.isp4022.nvram));
-               printk(KERN_INFO "0x%02X semaphore       = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u1.isp4022.semaphore),
-                      readw(&ha->reg->u1.isp4022.semaphore));
-       }
-       printk(KERN_INFO "0x%02X req_q_in        = 0x%08X\n",
-              (uint8_t) offsetof(struct isp_reg, req_q_in),
-              readw(&ha->reg->req_q_in));
-       printk(KERN_INFO "0x%02X rsp_q_out       = 0x%08X\n",
-              (uint8_t) offsetof(struct isp_reg, rsp_q_out),
-              readw(&ha->reg->rsp_q_out));
-       if (is_qla4010(ha)) {
-               printk(KERN_INFO "0x%02X ext_hw_conf     = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u2.isp4010.ext_hw_conf),
-                      readw(&ha->reg->u2.isp4010.ext_hw_conf));
-               printk(KERN_INFO "0x%02X port_ctrl       = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u2.isp4010.port_ctrl),
-                      readw(&ha->reg->u2.isp4010.port_ctrl));
-               printk(KERN_INFO "0x%02X port_status     = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u2.isp4010.port_status),
-                      readw(&ha->reg->u2.isp4010.port_status));
-               printk(KERN_INFO "0x%02X req_q_out       = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u2.isp4010.req_q_out),
-                      readw(&ha->reg->u2.isp4010.req_q_out));
-               printk(KERN_INFO "0x%02X gp_out          = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_out),
-                      readw(&ha->reg->u2.isp4010.gp_out));
-               printk(KERN_INFO "0x%02X gp_in           = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_in),
-                      readw(&ha->reg->u2.isp4010.gp_in));
-               printk(KERN_INFO "0x%02X port_err_status = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u2.isp4010.port_err_status),
-                      readw(&ha->reg->u2.isp4010.port_err_status));
-       }
-
-       else if (is_qla4022(ha) | is_qla4032(ha)) {
-               printk(KERN_INFO "Page 0 Registers:\n");
-               printk(KERN_INFO "0x%02X ext_hw_conf     = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u2.isp4022.p0.ext_hw_conf),
-                      readw(&ha->reg->u2.isp4022.p0.ext_hw_conf));
-               printk(KERN_INFO "0x%02X port_ctrl       = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u2.isp4022.p0.port_ctrl),
-                      readw(&ha->reg->u2.isp4022.p0.port_ctrl));
-               printk(KERN_INFO "0x%02X port_status     = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u2.isp4022.p0.port_status),
-                      readw(&ha->reg->u2.isp4022.p0.port_status));
-               printk(KERN_INFO "0x%02X gp_out          = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u2.isp4022.p0.gp_out),
-                      readw(&ha->reg->u2.isp4022.p0.gp_out));
-               printk(KERN_INFO "0x%02X gp_in           = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg, u2.isp4022.p0.gp_in),
-                      readw(&ha->reg->u2.isp4022.p0.gp_in));
-               printk(KERN_INFO "0x%02X port_err_status = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u2.isp4022.p0.port_err_status),
-                      readw(&ha->reg->u2.isp4022.p0.port_err_status));
-               printk(KERN_INFO "Page 1 Registers:\n");
-               writel(HOST_MEM_CFG_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT),
-                      &ha->reg->ctrl_status);
-               printk(KERN_INFO "0x%02X req_q_out       = 0x%08X\n",
-                      (uint8_t) offsetof(struct isp_reg,
-                                         u2.isp4022.p1.req_q_out),
-                      readw(&ha->reg->u2.isp4022.p1.req_q_out));
-               writel(PORT_CTRL_STAT_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT),
-                      &ha->reg->ctrl_status);
-       }
-}
-
-void qla4xxx_dump_mbox_registers(struct scsi_qla_host *ha)
-{
-       unsigned long flags = 0;
-       int i = 0;
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       for (i = 1; i < MBOX_REG_COUNT; i++)
-               printk(KERN_INFO "  Mailbox[%d] = %08x\n", i,
-                      readw(&ha->reg->mailbox[i]));
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
-}
-
-void qla4xxx_dump_registers(struct scsi_qla_host *ha)
-{
-       unsigned long flags = 0;
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       __dump_registers(ha);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
-}
+#include "ql4_glbl.h"
+#include "ql4_dbg.h"
+#include "ql4_inline.h"
 
 void qla4xxx_dump_buffer(void *b, uint32_t size)
 {
@@ -198,4 +31,3 @@ void qla4xxx_dump_buffer(void *b, uint32_t size)
                printk(KERN_DEBUG "\n");
 }
 
-#endif  /*  0  */
index 6f4cf2d..accaf69 100644 (file)
 
 #define ISCSI_IPADDR_SIZE              4       /* IP address size */
 #define ISCSI_ALIAS_SIZE               32      /* ISCSI Alais name size */
-#define ISCSI_NAME_SIZE                        255     /* ISCSI Name size -
-                                                * usually a string */
+#define ISCSI_NAME_SIZE                        0xE0    /* ISCSI Name size */
 
 #define LSDW(x) ((u32)((u64)(x)))
 #define MSDW(x) ((u32)((((u64)(x)) >> 16) >> 16))
@@ -187,9 +186,21 @@ struct srb {
        u_long u_start;         /* Time when we handed the cmd to F/W */
 };
 
-       /*
-        * Device Database (DDB) structure
-        */
+/*
+ * Asynchronous Event Queue structure
+ */
+struct aen {
+        uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
+};
+
+struct ql4_aen_log {
+        int count;
+        struct aen entry[MAX_AEN_ENTRIES];
+};
+
+/*
+ * Device Database (DDB) structure
+ */
 struct ddb_entry {
        struct list_head list;  /* ddb list */
        struct scsi_qla_host *ha;
@@ -254,13 +265,6 @@ struct ddb_entry {
 #define DF_ISNS_DISCOVERED     2       /* Device was discovered via iSNS */
 #define DF_FO_MASKED           3
 
-/*
- * Asynchronous Event Queue structure
- */
-struct aen {
-       uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
-};
-
 
 #include "ql4_fw.h"
 #include "ql4_nvram.h"
@@ -270,31 +274,31 @@ struct aen {
  */
 struct scsi_qla_host {
        /* Linux adapter configuration data */
-       struct Scsi_Host *host; /* pointer to host data */
-       uint32_t tot_ddbs;
        unsigned long flags;
 
-#define AF_ONLINE                    0 /* 0x00000001 */
-#define AF_INIT_DONE                 1 /* 0x00000002 */
-#define AF_MBOX_COMMAND                      2 /* 0x00000004 */
-#define AF_MBOX_COMMAND_DONE         3 /* 0x00000008 */
-#define AF_INTERRUPTS_ON             6 /* 0x00000040 Not Used */
-#define AF_GET_CRASH_RECORD          7 /* 0x00000080 */
-#define AF_LINK_UP                   8 /* 0x00000100 */
-#define AF_IRQ_ATTACHED                     10 /* 0x00000400 */
-#define AF_ISNS_CMD_IN_PROCESS      12 /* 0x00001000 */
-#define AF_ISNS_CMD_DONE            13 /* 0x00002000 */
+#define AF_ONLINE                      0 /* 0x00000001 */
+#define AF_INIT_DONE                   1 /* 0x00000002 */
+#define AF_MBOX_COMMAND                        2 /* 0x00000004 */
+#define AF_MBOX_COMMAND_DONE           3 /* 0x00000008 */
+#define AF_INTERRUPTS_ON               6 /* 0x00000040 */
+#define AF_GET_CRASH_RECORD            7 /* 0x00000080 */
+#define AF_LINK_UP                     8 /* 0x00000100 */
+#define AF_IRQ_ATTACHED                        10 /* 0x00000400 */
+#define AF_DISABLE_ACB_COMPLETE                11 /* 0x00000800 */
 
        unsigned long dpc_flags;
 
-#define DPC_RESET_HA                 1 /* 0x00000002 */
-#define DPC_RETRY_RESET_HA           2 /* 0x00000004 */
-#define DPC_RELOGIN_DEVICE           3 /* 0x00000008 */
-#define DPC_RESET_HA_DESTROY_DDB_LIST 4 /* 0x00000010 */
-#define DPC_RESET_HA_INTR            5 /* 0x00000020 */
-#define DPC_ISNS_RESTART             7 /* 0x00000080 */
-#define DPC_AEN                              9 /* 0x00000200 */
-#define DPC_GET_DHCP_IP_ADDR        15 /* 0x00008000 */
+#define DPC_RESET_HA                   1 /* 0x00000002 */
+#define DPC_RETRY_RESET_HA             2 /* 0x00000004 */
+#define DPC_RELOGIN_DEVICE             3 /* 0x00000008 */
+#define DPC_RESET_HA_DESTROY_DDB_LIST  4 /* 0x00000010 */
+#define DPC_RESET_HA_INTR              5 /* 0x00000020 */
+#define DPC_ISNS_RESTART               7 /* 0x00000080 */
+#define DPC_AEN                                9 /* 0x00000200 */
+#define DPC_GET_DHCP_IP_ADDR           15 /* 0x00008000 */
+
+       struct Scsi_Host *host; /* pointer to host data */
+       uint32_t tot_ddbs;
 
        uint16_t        iocb_cnt;
        uint16_t        iocb_hiwat;
@@ -344,6 +348,7 @@ struct scsi_qla_host {
        uint32_t firmware_version[2];
        uint32_t patch_number;
        uint32_t build_number;
+       uint32_t board_id;
 
        /* --- From Init_FW --- */
        /* init_cb_t *init_cb; */
@@ -363,7 +368,6 @@ struct scsi_qla_host {
 
        /* --- From GetFwState --- */
        uint32_t firmware_state;
-       uint32_t board_id;
        uint32_t addl_fw_state;
 
        /* Linux kernel thread */
@@ -414,6 +418,8 @@ struct scsi_qla_host {
        uint16_t aen_out;
        struct aen aen_q[MAX_AEN_ENTRIES];
 
+       struct ql4_aen_log aen_log;/* tracks all aens */
+
        /* This mutex protects several threads to do mailbox commands
         * concurrently.
         */
@@ -585,10 +591,4 @@ static inline void ql4xxx_unlock_drvr(struct scsi_qla_host *a)
 #define FLUSH_DDB_CHANGED_AENS  1
 #define RELOGIN_DDB_CHANGED_AENS 2
 
-#include "ql4_version.h"
-#include "ql4_glbl.h"
-#include "ql4_dbg.h"
-#include "ql4_inline.h"
-
-
 #endif /*_QLA4XXX_H */
index 4eea8c5..9bb3d1d 100644 (file)
  *************************************************************************/
 
 struct port_ctrl_stat_regs {
-       __le32 ext_hw_conf;     /*  80 x50  R/W */
-       __le32 intChipConfiguration; /*  84 x54 */
-       __le32 port_ctrl;       /*  88 x58 */
-       __le32 port_status;     /*  92 x5c */
-       __le32 HostPrimMACHi;   /*  96 x60 */
-       __le32 HostPrimMACLow;  /* 100 x64 */
-       __le32 HostSecMACHi;    /* 104 x68 */
-       __le32 HostSecMACLow;   /* 108 x6c */
-       __le32 EPPrimMACHi;     /* 112 x70 */
-       __le32 EPPrimMACLow;    /* 116 x74 */
-       __le32 EPSecMACHi;      /* 120 x78 */
-       __le32 EPSecMACLow;     /* 124 x7c */
-       __le32 HostPrimIPHi;    /* 128 x80 */
-       __le32 HostPrimIPMidHi; /* 132 x84 */
-       __le32 HostPrimIPMidLow;        /* 136 x88 */
-       __le32 HostPrimIPLow;   /* 140 x8c */
-       __le32 HostSecIPHi;     /* 144 x90 */
-       __le32 HostSecIPMidHi;  /* 148 x94 */
-       __le32 HostSecIPMidLow; /* 152 x98 */
-       __le32 HostSecIPLow;    /* 156 x9c */
-       __le32 EPPrimIPHi;      /* 160 xa0 */
-       __le32 EPPrimIPMidHi;   /* 164 xa4 */
-       __le32 EPPrimIPMidLow;  /* 168 xa8 */
-       __le32 EPPrimIPLow;     /* 172 xac */
-       __le32 EPSecIPHi;       /* 176 xb0 */
-       __le32 EPSecIPMidHi;    /* 180 xb4 */
-       __le32 EPSecIPMidLow;   /* 184 xb8 */
-       __le32 EPSecIPLow;      /* 188 xbc */
-       __le32 IPReassemblyTimeout; /* 192 xc0 */
-       __le32 EthMaxFramePayload; /* 196 xc4 */
-       __le32 TCPMaxWindowSize; /* 200 xc8 */
-       __le32 TCPCurrentTimestampHi; /* 204 xcc */
-       __le32 TCPCurrentTimestampLow; /* 208 xd0 */
-       __le32 LocalRAMAddress; /* 212 xd4 */
-       __le32 LocalRAMData;    /* 216 xd8 */
-       __le32 PCSReserved1;    /* 220 xdc */
-       __le32 gp_out;          /* 224 xe0 */
-       __le32 gp_in;           /* 228 xe4 */
-       __le32 ProbeMuxAddr;    /* 232 xe8 */
-       __le32 ProbeMuxData;    /* 236 xec */
-       __le32 ERMQueueBaseAddr0; /* 240 xf0 */
-       __le32 ERMQueueBaseAddr1; /* 244 xf4 */
-       __le32 MACConfiguration; /* 248 xf8 */
-       __le32 port_err_status; /* 252 xfc  COR */
+       __le32 ext_hw_conf;     /* 0x50  R/W */
+       __le32 rsrvd0;          /* 0x54 */
+       __le32 port_ctrl;       /* 0x58 */
+       __le32 port_status;     /* 0x5c */
+       __le32 rsrvd1[32];      /* 0x60-0xdf */
+       __le32 gp_out;          /* 0xe0 */
+       __le32 gp_in;           /* 0xe4 */
+       __le32 rsrvd2[5];       /* 0xe8-0xfb */
+       __le32 port_err_status; /* 0xfc */
 };
 
 struct host_mem_cfg_regs {
-       __le32 NetRequestQueueOut; /*  80 x50 */
-       __le32 NetRequestQueueOutAddrHi; /*  84 x54 */
-       __le32 NetRequestQueueOutAddrLow; /*  88 x58 */
-       __le32 NetRequestQueueBaseAddrHi; /*  92 x5c */
-       __le32 NetRequestQueueBaseAddrLow; /*  96 x60 */
-       __le32 NetRequestQueueLength; /* 100 x64 */
-       __le32 NetResponseQueueIn; /* 104 x68 */
-       __le32 NetResponseQueueInAddrHi; /* 108 x6c */
-       __le32 NetResponseQueueInAddrLow; /* 112 x70 */
-       __le32 NetResponseQueueBaseAddrHi; /* 116 x74 */
-       __le32 NetResponseQueueBaseAddrLow; /* 120 x78 */
-       __le32 NetResponseQueueLength; /* 124 x7c */
-       __le32 req_q_out;       /* 128 x80 */
-       __le32 RequestQueueOutAddrHi; /* 132 x84 */
-       __le32 RequestQueueOutAddrLow; /* 136 x88 */
-       __le32 RequestQueueBaseAddrHi; /* 140 x8c */
-       __le32 RequestQueueBaseAddrLow; /* 144 x90 */
-       __le32 RequestQueueLength; /* 148 x94 */
-       __le32 ResponseQueueIn; /* 152 x98 */
-       __le32 ResponseQueueInAddrHi; /* 156 x9c */
-       __le32 ResponseQueueInAddrLow; /* 160 xa0 */
-       __le32 ResponseQueueBaseAddrHi; /* 164 xa4 */
-       __le32 ResponseQueueBaseAddrLow; /* 168 xa8 */
-       __le32 ResponseQueueLength; /* 172 xac */
-       __le32 NetRxLargeBufferQueueOut; /* 176 xb0 */
-       __le32 NetRxLargeBufferQueueBaseAddrHi; /* 180 xb4 */
-       __le32 NetRxLargeBufferQueueBaseAddrLow; /* 184 xb8 */
-       __le32 NetRxLargeBufferQueueLength; /* 188 xbc */
-       __le32 NetRxLargeBufferLength; /* 192 xc0 */
-       __le32 NetRxSmallBufferQueueOut; /* 196 xc4 */
-       __le32 NetRxSmallBufferQueueBaseAddrHi; /* 200 xc8 */
-       __le32 NetRxSmallBufferQueueBaseAddrLow; /* 204 xcc */
-       __le32 NetRxSmallBufferQueueLength; /* 208 xd0 */
-       __le32 NetRxSmallBufferLength; /* 212 xd4 */
-       __le32 HMCReserved0[10]; /* 216 xd8 */
+       __le32 rsrvd0[12];      /* 0x50-0x79 */
+       __le32 req_q_out;       /* 0x80 */
+       __le32 rsrvd1[31];      /* 0x84-0xFF */
 };
 
-struct local_ram_cfg_regs {
-       __le32 BufletSize;      /*  80 x50 */
-       __le32 BufletMaxCount;  /*  84 x54 */
-       __le32 BufletCurrCount; /*  88 x58 */
-       __le32 BufletPauseThresholdCount; /*  92 x5c */
-       __le32 BufletTCPWinThresholdHi; /*  96 x60 */
-       __le32 BufletTCPWinThresholdLow; /* 100 x64 */
-       __le32 IPHashTableBaseAddr; /* 104 x68 */
-       __le32 IPHashTableSize; /* 108 x6c */
-       __le32 TCPHashTableBaseAddr; /* 112 x70 */
-       __le32 TCPHashTableSize; /* 116 x74 */
-       __le32 NCBAreaBaseAddr; /* 120 x78 */
-       __le32 NCBMaxCount;     /* 124 x7c */
-       __le32 NCBCurrCount;    /* 128 x80 */
-       __le32 DRBAreaBaseAddr; /* 132 x84 */
-       __le32 DRBMaxCount;     /* 136 x88 */
-       __le32 DRBCurrCount;    /* 140 x8c */
-       __le32 LRCReserved[28]; /* 144 x90 */
-};
-
-struct prot_stat_regs {
-       __le32 MACTxFrameCount; /*  80 x50   R */
-       __le32 MACTxByteCount;  /*  84 x54   R */
-       __le32 MACRxFrameCount; /*  88 x58   R */
-       __le32 MACRxByteCount;  /*  92 x5c   R */
-       __le32 MACCRCErrCount;  /*  96 x60   R */
-       __le32 MACEncErrCount;  /* 100 x64   R */
-       __le32 MACRxLengthErrCount; /* 104 x68   R */
-       __le32 IPTxPacketCount; /* 108 x6c   R */
-       __le32 IPTxByteCount;   /* 112 x70   R */
-       __le32 IPTxFragmentCount; /* 116 x74   R */
-       __le32 IPRxPacketCount; /* 120 x78   R */
-       __le32 IPRxByteCount;   /* 124 x7c   R */
-       __le32 IPRxFragmentCount; /* 128 x80   R */
-       __le32 IPDatagramReassemblyCount; /* 132 x84   R */
-       __le32 IPV6RxPacketCount; /* 136 x88   R */
-       __le32 IPErrPacketCount; /* 140 x8c   R */
-       __le32 IPReassemblyErrCount; /* 144 x90   R */
-       __le32 TCPTxSegmentCount; /* 148 x94   R */
-       __le32 TCPTxByteCount;  /* 152 x98   R */
-       __le32 TCPRxSegmentCount; /* 156 x9c   R */
-       __le32 TCPRxByteCount;  /* 160 xa0   R */
-       __le32 TCPTimerExpCount; /* 164 xa4   R */
-       __le32 TCPRxAckCount;   /* 168 xa8   R */
-       __le32 TCPTxAckCount;   /* 172 xac   R */
-       __le32 TCPRxErrOOOCount; /* 176 xb0   R */
-       __le32 PSReserved0;     /* 180 xb4 */
-       __le32 TCPRxWindowProbeUpdateCount; /* 184 xb8   R */
-       __le32 ECCErrCorrectionCount; /* 188 xbc   R */
-       __le32 PSReserved1[16]; /* 192 xc0 */
-};
-
-
 /*  remote register set (access via PCI memory read/write) */
 struct isp_reg {
 #define MBOX_REG_COUNT 8
@@ -207,11 +87,7 @@ struct isp_reg {
                        union {
                                struct port_ctrl_stat_regs p0;
                                struct host_mem_cfg_regs p1;
-                               struct local_ram_cfg_regs p2;
-                               struct prot_stat_regs p3;
-                               __le32 r_union[44];
                        };
-
                } __attribute__ ((packed)) isp4022;
        } u2;
 };                             /* 256 x100 */
@@ -296,6 +172,7 @@ static inline uint32_t clr_rmask(uint32_t val)
 /*  ISP Semaphore definitions */
 
 /*  ISP General Purpose Output definitions */
+#define GPOR_TOPCAT_RESET                      0x00000004
 
 /*  shadow registers (DMA'd from HA to system memory.  read only) */
 struct shadow_regs {
@@ -337,6 +214,7 @@ union external_hw_config_reg {
 
 /*  Mailbox command definitions */
 #define MBOX_CMD_ABOUT_FW                      0x0009
+#define MBOX_CMD_PING                          0x000B
 #define MBOX_CMD_LUN_RESET                     0x0016
 #define MBOX_CMD_GET_MANAGEMENT_DATA           0x001E
 #define MBOX_CMD_GET_FW_STATUS                 0x001F
@@ -364,6 +242,17 @@ union external_hw_config_reg {
 #define MBOX_CMD_GET_FW_STATE                  0x0069
 #define MBOX_CMD_GET_INIT_FW_CTRL_BLOCK_DEFAULTS 0x006A
 #define MBOX_CMD_RESTORE_FACTORY_DEFAULTS      0x0087
+#define MBOX_CMD_SET_ACB                       0x0088
+#define MBOX_CMD_GET_ACB                       0x0089
+#define MBOX_CMD_DISABLE_ACB                   0x008A
+#define MBOX_CMD_GET_IPV6_NEIGHBOR_CACHE       0x008B
+#define MBOX_CMD_GET_IPV6_DEST_CACHE           0x008C
+#define MBOX_CMD_GET_IPV6_DEF_ROUTER_LIST      0x008D
+#define MBOX_CMD_GET_IPV6_LCL_PREFIX_LIST      0x008E
+#define MBOX_CMD_SET_IPV6_NEIGHBOR_CACHE       0x0090
+#define MBOX_CMD_GET_IP_ADDR_STATE             0x0091
+#define MBOX_CMD_SEND_IPV6_ROUTER_SOL          0x0092
+#define MBOX_CMD_GET_DB_ENTRY_CURRENT_IP_ADDR  0x0093
 
 /* Mailbox 1 */
 #define FW_STATE_READY                         0x0000
@@ -409,6 +298,16 @@ union external_hw_config_reg {
 #define MBOX_ASTS_DHCP_LEASE_EXPIRED           0x801D
 #define MBOX_ASTS_DHCP_LEASE_ACQUIRED          0x801F
 #define MBOX_ASTS_ISNS_UNSOLICITED_PDU_RECEIVED 0x8021
+#define MBOX_ASTS_DUPLICATE_IP                 0x8025
+#define MBOX_ASTS_ARP_COMPLETE                 0x8026
+#define MBOX_ASTS_SUBNET_STATE_CHANGE          0x8027
+#define MBOX_ASTS_RESPONSE_QUEUE_FULL          0x8028
+#define MBOX_ASTS_IP_ADDR_STATE_CHANGED                0x8029
+#define MBOX_ASTS_IPV6_PREFIX_EXPIRED          0x802B
+#define MBOX_ASTS_IPV6_ND_PREFIX_IGNORED       0x802C
+#define MBOX_ASTS_IPV6_LCL_PREFIX_IGNORED      0x802D
+#define MBOX_ASTS_ICMPV6_ERROR_MSG_RCVD                0x802E
+
 #define ISNS_EVENT_DATA_RECEIVED               0x0000
 #define ISNS_EVENT_CONNECTION_OPENED           0x0001
 #define ISNS_EVENT_CONNECTION_FAILED           0x0002
@@ -418,137 +317,166 @@ union external_hw_config_reg {
 /*************************************************************************/
 
 /* Host Adapter Initialization Control Block (from host) */
-struct init_fw_ctrl_blk {
-       uint8_t Version;        /* 00 */
-       uint8_t Control;        /* 01 */
+struct addr_ctrl_blk {
+       uint8_t version;        /* 00 */
+       uint8_t control;        /* 01 */
 
-       uint16_t FwOptions;     /* 02-03 */
+       uint16_t fw_options;    /* 02-03 */
 #define         FWOPT_HEARTBEAT_ENABLE           0x1000
 #define         FWOPT_SESSION_MODE               0x0040
 #define         FWOPT_INITIATOR_MODE             0x0020
 #define         FWOPT_TARGET_MODE                0x0010
 
-       uint16_t ExecThrottle;  /* 04-05 */
-       uint8_t RetryCount;     /* 06 */
-       uint8_t RetryDelay;     /* 07 */
-       uint16_t MaxEthFrPayloadSize;   /* 08-09 */
-       uint16_t AddFwOptions;  /* 0A-0B */
-
-       uint8_t HeartbeatInterval;      /* 0C */
-       uint8_t InstanceNumber; /* 0D */
-       uint16_t RES2;          /* 0E-0F */
-       uint16_t ReqQConsumerIndex;     /* 10-11 */
-       uint16_t ComplQProducerIndex;   /* 12-13 */
-       uint16_t ReqQLen;       /* 14-15 */
-       uint16_t ComplQLen;     /* 16-17 */
-       uint32_t ReqQAddrLo;    /* 18-1B */
-       uint32_t ReqQAddrHi;    /* 1C-1F */
-       uint32_t ComplQAddrLo;  /* 20-23 */
-       uint32_t ComplQAddrHi;  /* 24-27 */
-       uint32_t ShadowRegBufAddrLo;    /* 28-2B */
-       uint32_t ShadowRegBufAddrHi;    /* 2C-2F */
-
-       uint16_t iSCSIOptions;  /* 30-31 */
-
-       uint16_t TCPOptions;    /* 32-33 */
-
-       uint16_t IPOptions;     /* 34-35 */
-
-       uint16_t MaxPDUSize;    /* 36-37 */
-       uint16_t RcvMarkerInt;  /* 38-39 */
-       uint16_t SndMarkerInt;  /* 3A-3B */
-       uint16_t InitMarkerlessInt;     /* 3C-3D */
-       uint16_t FirstBurstSize;        /* 3E-3F */
-       uint16_t DefaultTime2Wait;      /* 40-41 */
-       uint16_t DefaultTime2Retain;    /* 42-43 */
-       uint16_t MaxOutStndngR2T;       /* 44-45 */
-       uint16_t KeepAliveTimeout;      /* 46-47 */
-       uint16_t PortNumber;    /* 48-49 */
-       uint16_t MaxBurstSize;  /* 4A-4B */
-       uint32_t RES4;          /* 4C-4F */
-       uint8_t IPAddr[4];      /* 50-53 */
-       uint8_t RES5[12];       /* 54-5F */
-       uint8_t SubnetMask[4];  /* 60-63 */
-       uint8_t RES6[12];       /* 64-6F */
-       uint8_t GatewayIPAddr[4];       /* 70-73 */
-       uint8_t RES7[12];       /* 74-7F */
-       uint8_t PriDNSIPAddr[4];        /* 80-83 */
-       uint8_t SecDNSIPAddr[4];        /* 84-87 */
-       uint8_t RES8[8];        /* 88-8F */
-       uint8_t Alias[32];      /* 90-AF */
-       uint8_t TargAddr[8];    /* B0-B7 *//* /FIXME: Remove?? */
-       uint8_t CHAPNameSecretsTable[8];        /* B8-BF */
-       uint8_t EthernetMACAddr[6];     /* C0-C5 */
-       uint16_t TargetPortalGroup;     /* C6-C7 */
-       uint8_t SendScale;      /* C8    */
-       uint8_t RecvScale;      /* C9    */
-       uint8_t TypeOfService;  /* CA    */
-       uint8_t Time2Live;      /* CB    */
-       uint16_t VLANPriority;  /* CC-CD */
-       uint16_t Reserved8;     /* CE-CF */
-       uint8_t SecIPAddr[4];   /* D0-D3 */
-       uint8_t Reserved9[12];  /* D4-DF */
-       uint8_t iSNSIPAddr[4];  /* E0-E3 */
-       uint16_t iSNSServerPortNumber;  /* E4-E5 */
-       uint8_t Reserved10[10]; /* E6-EF */
-       uint8_t SLPDAIPAddr[4]; /* F0-F3 */
-       uint8_t Reserved11[12]; /* F4-FF */
-       uint8_t iSCSINameString[256];   /* 100-1FF */
+       uint16_t exec_throttle; /* 04-05 */
+       uint8_t zio_count;      /* 06 */
+       uint8_t res0;   /* 07 */
+       uint16_t eth_mtu_size;  /* 08-09 */
+       uint16_t add_fw_options;        /* 0A-0B */
+
+       uint8_t hb_interval;    /* 0C */
+       uint8_t inst_num; /* 0D */
+       uint16_t res1;          /* 0E-0F */
+       uint16_t rqq_consumer_idx;      /* 10-11 */
+       uint16_t compq_producer_idx;    /* 12-13 */
+       uint16_t rqq_len;       /* 14-15 */
+       uint16_t compq_len;     /* 16-17 */
+       uint32_t rqq_addr_lo;   /* 18-1B */
+       uint32_t rqq_addr_hi;   /* 1C-1F */
+       uint32_t compq_addr_lo; /* 20-23 */
+       uint32_t compq_addr_hi; /* 24-27 */
+       uint32_t shdwreg_addr_lo;       /* 28-2B */
+       uint32_t shdwreg_addr_hi;       /* 2C-2F */
+
+       uint16_t iscsi_opts;    /* 30-31 */
+       uint16_t ipv4_tcp_opts; /* 32-33 */
+       uint16_t ipv4_ip_opts;  /* 34-35 */
+
+       uint16_t iscsi_max_pdu_size;    /* 36-37 */
+       uint8_t ipv4_tos;       /* 38 */
+       uint8_t ipv4_ttl;       /* 39 */
+       uint8_t acb_version;    /* 3A */
+       uint8_t res2;   /* 3B */
+       uint16_t def_timeout;   /* 3C-3D */
+       uint16_t iscsi_fburst_len;      /* 3E-3F */
+       uint16_t iscsi_def_time2wait;   /* 40-41 */
+       uint16_t iscsi_def_time2retain; /* 42-43 */
+       uint16_t iscsi_max_outstnd_r2t; /* 44-45 */
+       uint16_t conn_ka_timeout;       /* 46-47 */
+       uint16_t ipv4_port;     /* 48-49 */
+       uint16_t iscsi_max_burst_len;   /* 4A-4B */
+       uint32_t res5;          /* 4C-4F */
+       uint8_t ipv4_addr[4];   /* 50-53 */
+       uint16_t ipv4_vlan_tag; /* 54-55 */
+       uint8_t ipv4_addr_state;        /* 56 */
+       uint8_t ipv4_cacheid;   /* 57 */
+       uint8_t res6[8];        /* 58-5F */
+       uint8_t ipv4_subnet[4]; /* 60-63 */
+       uint8_t res7[12];       /* 64-6F */
+       uint8_t ipv4_gw_addr[4];        /* 70-73 */
+       uint8_t res8[0xc];      /* 74-7F */
+       uint8_t pri_dns_srvr_ip[4];/* 80-83 */
+       uint8_t sec_dns_srvr_ip[4];/* 84-87 */
+       uint16_t min_eph_port;  /* 88-89 */
+       uint16_t max_eph_port;  /* 8A-8B */
+       uint8_t res9[4];        /* 8C-8F */
+       uint8_t iscsi_alias[32];/* 90-AF */
+       uint8_t res9_1[0x16];   /* B0-C5 */
+       uint16_t tgt_portal_grp;/* C6-C7 */
+       uint8_t abort_timer;    /* C8    */
+       uint8_t ipv4_tcp_wsf;   /* C9    */
+       uint8_t res10[6];       /* CA-CF */
+       uint8_t ipv4_sec_ip_addr[4];    /* D0-D3 */
+       uint8_t ipv4_dhcp_vid_len;      /* D4 */
+       uint8_t ipv4_dhcp_vid[11];      /* D5-DF */
+       uint8_t res11[20];      /* E0-F3 */
+       uint8_t ipv4_dhcp_alt_cid_len;  /* F4 */
+       uint8_t ipv4_dhcp_alt_cid[11];  /* F5-FF */
+       uint8_t iscsi_name[224];        /* 100-1DF */
+       uint8_t res12[32];      /* 1E0-1FF */
+       uint32_t cookie;        /* 200-203 */
+       uint16_t ipv6_port;     /* 204-205 */
+       uint16_t ipv6_opts;     /* 206-207 */
+       uint16_t ipv6_addtl_opts;       /* 208-209 */
+       uint16_t ipv6_tcp_opts; /* 20A-20B */
+       uint8_t ipv6_tcp_wsf;   /* 20C */
+       uint16_t ipv6_flow_lbl; /* 20D-20F */
+       uint8_t ipv6_gw_addr[16];       /* 210-21F */
+       uint16_t ipv6_vlan_tag; /* 220-221 */
+       uint8_t ipv6_lnk_lcl_addr_state;/* 222 */
+       uint8_t ipv6_addr0_state;       /* 223 */
+       uint8_t ipv6_addr1_state;       /* 224 */
+       uint8_t ipv6_gw_state;  /* 225 */
+       uint8_t ipv6_traffic_class;     /* 226 */
+       uint8_t ipv6_hop_limit; /* 227 */
+       uint8_t ipv6_if_id[8];  /* 228-22F */
+       uint8_t ipv6_addr0[16]; /* 230-23F */
+       uint8_t ipv6_addr1[16]; /* 240-24F */
+       uint32_t ipv6_nd_reach_time;    /* 250-253 */
+       uint32_t ipv6_nd_rexmit_timer;  /* 254-257 */
+       uint32_t ipv6_nd_stale_timeout; /* 258-25B */
+       uint8_t ipv6_dup_addr_detect_count;     /* 25C */
+       uint8_t ipv6_cache_id;  /* 25D */
+       uint8_t res13[18];      /* 25E-26F */
+       uint32_t ipv6_gw_advrt_mtu;     /* 270-273 */
+       uint8_t res14[140];     /* 274-2FF */
+};
+
+struct init_fw_ctrl_blk {
+       struct addr_ctrl_blk pri;
+       struct addr_ctrl_blk sec;
 };
 
 /*************************************************************************/
 
 struct dev_db_entry {
-       uint8_t options;        /* 00 */
+       uint16_t options;       /* 00-01 */
 #define DDB_OPT_DISC_SESSION  0x10
 #define DDB_OPT_TARGET       0x02 /* device is a target */
 
-       uint8_t control;        /* 01 */
-
-       uint16_t exeThrottle;   /* 02-03 */
-       uint16_t exeCount;      /* 04-05 */
-       uint8_t retryCount;     /* 06    */
-       uint8_t retryDelay;     /* 07    */
-       uint16_t iSCSIOptions;  /* 08-09 */
-
-       uint16_t TCPOptions;    /* 0A-0B */
-
-       uint16_t IPOptions;     /* 0C-0D */
-
-       uint16_t maxPDUSize;    /* 0E-0F */
-       uint16_t rcvMarkerInt;  /* 10-11 */
-       uint16_t sndMarkerInt;  /* 12-13 */
-       uint16_t iSCSIMaxSndDataSegLen; /* 14-15 */
-       uint16_t firstBurstSize;        /* 16-17 */
-       uint16_t minTime2Wait;  /* 18-19 : RA :default_time2wait */
-       uint16_t maxTime2Retain;        /* 1A-1B */
-       uint16_t maxOutstndngR2T;       /* 1C-1D */
-       uint16_t keepAliveTimeout;      /* 1E-1F */
-       uint8_t ISID[6];        /* 20-25 big-endian, must be converted
+       uint16_t exec_throttle; /* 02-03 */
+       uint16_t exec_count;    /* 04-05 */
+       uint16_t res0;  /* 06-07 */
+       uint16_t iscsi_options; /* 08-09 */
+       uint16_t tcp_options;   /* 0A-0B */
+       uint16_t ip_options;    /* 0C-0D */
+       uint16_t iscsi_max_rcv_data_seg_len;    /* 0E-0F */
+       uint32_t res1;  /* 10-13 */
+       uint16_t iscsi_max_snd_data_seg_len;    /* 14-15 */
+       uint16_t iscsi_first_burst_len; /* 16-17 */
+       uint16_t iscsi_def_time2wait;   /* 18-19 */
+       uint16_t iscsi_def_time2retain; /* 1A-1B */
+       uint16_t iscsi_max_outsnd_r2t;  /* 1C-1D */
+       uint16_t ka_timeout;    /* 1E-1F */
+       uint8_t isid[6];        /* 20-25 big-endian, must be converted
                                 * to little-endian */
-       uint16_t TSID;          /* 26-27 */
-       uint16_t portNumber;    /* 28-29 */
-       uint16_t maxBurstSize;  /* 2A-2B */
-       uint16_t taskMngmntTimeout;     /* 2C-2D */
-       uint16_t reserved1;     /* 2E-2F */
-       uint8_t ipAddr[0x10];   /* 30-3F */
-       uint8_t iSCSIAlias[0x20];       /* 40-5F */
-       uint8_t targetAddr[0x20];       /* 60-7F */
-       uint8_t userID[0x20];   /* 80-9F */
-       uint8_t password[0x20]; /* A0-BF */
-       uint8_t iscsiName[0x100];       /* C0-1BF : xxzzy Make this a
+       uint16_t tsid;          /* 26-27 */
+       uint16_t port;  /* 28-29 */
+       uint16_t iscsi_max_burst_len;   /* 2A-2B */
+       uint16_t def_timeout;   /* 2C-2D */
+       uint16_t res2;  /* 2E-2F */
+       uint8_t ip_addr[0x10];  /* 30-3F */
+       uint8_t iscsi_alias[0x20];      /* 40-5F */
+       uint8_t tgt_addr[0x20]; /* 60-7F */
+       uint16_t mss;   /* 80-81 */
+       uint16_t res3;  /* 82-83 */
+       uint16_t lcl_port;      /* 84-85 */
+       uint8_t ipv4_tos;       /* 86 */
+       uint16_t ipv6_flow_lbl; /* 87-89 */
+       uint8_t res4[0x36];     /* 8A-BF */
+       uint8_t iscsi_name[0xE0];       /* C0-19F : xxzzy Make this a
                                         * pointer to a string so we
                                         * don't have to reserve soooo
                                         * much RAM */
-       uint16_t ddbLink;       /* 1C0-1C1 */
-       uint16_t CHAPTableIndex; /* 1C2-1C3 */
-       uint16_t TargetPortalGroup; /* 1C4-1C5 */
-       uint16_t reserved2[2];  /* 1C6-1C7 */
-       uint32_t statSN;        /* 1C8-1CB */
-       uint32_t expStatSN;     /* 1CC-1CF */
-       uint16_t reserved3[0x2C]; /* 1D0-1FB */
-       uint16_t ddbValidCookie; /* 1FC-1FD */
-       uint16_t ddbValidSize;  /* 1FE-1FF */
+       uint8_t ipv6_addr[0x10];/* 1A0-1AF */
+       uint8_t res5[0x10];     /* 1B0-1BF */
+       uint16_t ddb_link;      /* 1C0-1C1 */
+       uint16_t chap_tbl_idx;  /* 1C2-1C3 */
+       uint16_t tgt_portal_grp; /* 1C4-1C5 */
+       uint8_t tcp_xmt_wsf;    /* 1C6 */
+       uint8_t tcp_rcv_wsf;    /* 1C7 */
+       uint32_t stat_sn;       /* 1C8-1CB */
+       uint32_t exp_stat_sn;   /* 1CC-1CF */
+       uint8_t res6[0x30];     /* 1D0-1FF */
 };
 
 /*************************************************************************/
index 5b00cb0..a3608e0 100644 (file)
@@ -8,6 +8,9 @@
 #ifndef __QLA4x_GBL_H
 #define        __QLA4x_GBL_H
 
+struct iscsi_cls_conn;
+
+void qla4xxx_hw_reset(struct scsi_qla_host *ha);
 int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a);
 int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port);
 int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb);
@@ -58,11 +61,13 @@ int qla4xxx_get_fw_version(struct scsi_qla_host * ha);
 void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha,
                                       uint32_t intr_status);
 int qla4xxx_init_rings(struct scsi_qla_host * ha);
-struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, uint32_t index);
+struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha,
+                                       uint32_t index);
 void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb);
 int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host * ha);
 int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha,
                                uint32_t fw_ddb_index, uint32_t state);
+void qla4xxx_dump_buffer(void *b, uint32_t size);
 
 extern int ql4xextended_error_logging;
 extern int ql4xdiscoverywait;
index 6365df2..d8c064c 100644 (file)
@@ -6,6 +6,9 @@
  */
 
 #include "ql4_def.h"
+#include "ql4_glbl.h"
+#include "ql4_dbg.h"
+#include "ql4_inline.h"
 
 static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha,
                                            uint32_t fw_ddb_index);
@@ -300,12 +303,12 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha)
        if (!qla4xxx_fw_ready(ha))
                return status;
 
-       set_bit(AF_ONLINE, &ha->flags);
        return qla4xxx_get_firmware_status(ha);
 }
 
 static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha,
-                                              uint32_t fw_ddb_index)
+                                               uint32_t fw_ddb_index,
+                                               uint32_t *new_tgt)
 {
        struct dev_db_entry *fw_ddb_entry = NULL;
        dma_addr_t fw_ddb_entry_dma;
@@ -313,6 +316,7 @@ static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha,
        int found = 0;
        uint32_t device_state;
 
+       *new_tgt = 0;
        /* Make sure the dma buffer is valid */
        fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,
                                          sizeof(*fw_ddb_entry),
@@ -337,7 +341,7 @@ static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha,
        DEBUG2(printk("scsi%ld: %s: Looking for ddb[%d]\n", ha->host_no,
                      __func__, fw_ddb_index));
        list_for_each_entry(ddb_entry, &ha->ddb_list, list) {
-               if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsiName,
+               if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name,
                           ISCSI_NAME_SIZE) == 0) {
                        found++;
                        break;
@@ -348,6 +352,7 @@ static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha,
                DEBUG2(printk("scsi%ld: %s: ddb[%d] not found - allocating "
                              "new ddb\n", ha->host_no, __func__,
                              fw_ddb_index));
+               *new_tgt = 1;
                ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index);
        }
 
@@ -409,26 +414,26 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha,
        }
 
        status = QLA_SUCCESS;
-       ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->TSID);
+       ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->tsid);
        ddb_entry->task_mgmt_timeout =
-               le16_to_cpu(fw_ddb_entry->taskMngmntTimeout);
+               le16_to_cpu(fw_ddb_entry->def_timeout);
        ddb_entry->CmdSn = 0;
-       ddb_entry->exe_throttle = le16_to_cpu(fw_ddb_entry->exeThrottle);
+       ddb_entry->exe_throttle = le16_to_cpu(fw_ddb_entry->exec_throttle);
        ddb_entry->default_relogin_timeout =
-               le16_to_cpu(fw_ddb_entry->taskMngmntTimeout);
-       ddb_entry->default_time2wait = le16_to_cpu(fw_ddb_entry->minTime2Wait);
+               le16_to_cpu(fw_ddb_entry->def_timeout);
+       ddb_entry->default_time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait);
 
        /* Update index in case it changed */
        ddb_entry->fw_ddb_index = fw_ddb_index;
        ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry;
 
-       ddb_entry->port = le16_to_cpu(fw_ddb_entry->portNumber);
-       ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->TargetPortalGroup);
-       memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsiName[0],
+       ddb_entry->port = le16_to_cpu(fw_ddb_entry->port);
+       ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);
+       memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsi_name[0],
               min(sizeof(ddb_entry->iscsi_name),
-                  sizeof(fw_ddb_entry->iscsiName)));
-       memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ipAddr[0],
-              min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ipAddr)));
+                  sizeof(fw_ddb_entry->iscsi_name)));
+       memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ip_addr[0],
+              min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ip_addr)));
 
        DEBUG2(printk("scsi%ld: %s: ddb[%d] - State= %x status= %d.\n",
                      ha->host_no, __func__, fw_ddb_index,
@@ -495,6 +500,7 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha)
        uint32_t ddb_state;
        uint32_t conn_err, err_code;
        struct ddb_entry *ddb_entry;
+       uint32_t new_tgt;
 
        dev_info(&ha->pdev->dev, "Initializing DDBs ...\n");
        for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES;
@@ -526,8 +532,19 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha)
                                              "completed "
                                              "or access denied failure\n",
                                              ha->host_no, __func__));
-                       } else
+                       } else {
                                qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0);
+                               if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index,
+                                       NULL, 0, NULL, &next_fw_ddb_index,
+                                       &ddb_state, &conn_err, NULL, NULL)
+                                       == QLA_ERROR) {
+                                       DEBUG2(printk("scsi%ld: %s:"
+                                               "get_ddb_entry %d failed\n",
+                                               ha->host_no,
+                                               __func__, fw_ddb_index));
+                                       return QLA_ERROR;
+                               }
+                       }
                }
 
                if (ddb_state != DDB_DS_SESSION_ACTIVE)
@@ -540,7 +557,7 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha)
                              ha->host_no, __func__, fw_ddb_index));
 
                /* Add DDB to internal our ddb list. */
-               ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index);
+               ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index, &new_tgt);
                if (ddb_entry == NULL) {
                        DEBUG2(printk("scsi%ld: %s: Unable to allocate memory "
                                      "for device at fw_ddb_index %d\n",
@@ -865,21 +882,19 @@ static int qla4xxx_config_nvram(struct scsi_qla_host *ha)
 
 static void qla4x00_pci_config(struct scsi_qla_host *ha)
 {
-       uint16_t w, mwi;
+       uint16_t w;
 
        dev_info(&ha->pdev->dev, "Configuring PCI space...\n");
 
        pci_set_master(ha->pdev);
-       mwi = 0;
-       if (pci_set_mwi(ha->pdev))
-               mwi = PCI_COMMAND_INVALIDATE;
+       pci_set_mwi(ha->pdev);
        /*
         * We want to respect framework's setting of PCI configuration space
         * command register and also want to make sure that all bits of
         * interest to us are properly set in command register.
         */
        pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
-       w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
+       w |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
        w &= ~PCI_COMMAND_INTX_DISABLE;
        pci_write_config_word(ha->pdev, PCI_COMMAND, w);
 }
@@ -911,6 +926,9 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha)
                writel(set_rmask(NVR_WRITE_ENABLE),
                       &ha->reg->u1.isp4022.nvram);
 
+        writel(2, &ha->reg->mailbox[6]);
+        readl(&ha->reg->mailbox[6]);
+
        writel(set_rmask(CSR_BOOT_ENABLE), &ha->reg->ctrl_status);
        readl(&ha->reg->ctrl_status);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -958,25 +976,25 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha)
        return status;
 }
 
-int ql4xxx_lock_drvr_wait(struct scsi_qla_host *ha)
+int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a)
 {
-#define QL4_LOCK_DRVR_WAIT     30
+#define QL4_LOCK_DRVR_WAIT     60
 #define QL4_LOCK_DRVR_SLEEP    1
 
        int drvr_wait = QL4_LOCK_DRVR_WAIT;
        while (drvr_wait) {
-               if (ql4xxx_lock_drvr(ha) == 0) {
+               if (ql4xxx_lock_drvr(a) == 0) {
                        ssleep(QL4_LOCK_DRVR_SLEEP);
                        if (drvr_wait) {
                                DEBUG2(printk("scsi%ld: %s: Waiting for "
-                                             "Global Init Semaphore(%d)...n",
-                                             ha->host_no,
+                                             "Global Init Semaphore(%d)...\n",
+                                             a->host_no,
                                              __func__, drvr_wait));
                        }
                        drvr_wait -= QL4_LOCK_DRVR_SLEEP;
                } else {
                        DEBUG2(printk("scsi%ld: %s: Global Init Semaphore "
-                                     "acquired.n", ha->host_no, __func__));
+                                     "acquired\n", a->host_no, __func__));
                        return QLA_SUCCESS;
                }
        }
@@ -1142,8 +1160,10 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha,
         * the ddb_list and wait for DHCP lease acquired aen to come in
         * followed by 0x8014 aen" to trigger the tgt discovery process.
         */
-       if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS)
+       if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS){
+               set_bit(AF_ONLINE, &ha->flags);
                return status;
+       }
 
        /* Skip device discovery if ip and subnet is zero */
        if (memcmp(ha->ip_address, ip_address, IP_ADDR_LEN) == 0 ||
@@ -1177,6 +1197,7 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha,
                              ha->host_no));
        }
 
+       set_bit(AF_ONLINE, &ha->flags);
  exit_init_hba:
        return status;
 
@@ -1193,9 +1214,10 @@ static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha,
                                           uint32_t fw_ddb_index)
 {
        struct ddb_entry * ddb_entry;
+       uint32_t new_tgt;
 
        /* First allocate a device structure */
-       ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index);
+       ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index, &new_tgt);
        if (ddb_entry == NULL) {
                DEBUG2(printk(KERN_WARNING
                              "scsi%ld: Unable to allocate memory to add "
@@ -1203,6 +1225,18 @@ static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha,
                return;
        }
 
+       if (!new_tgt && (ddb_entry->fw_ddb_index != fw_ddb_index)) {
+               /* Target has been bound to a new fw_ddb_index */
+               qla4xxx_free_ddb(ha, ddb_entry);
+               ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index);
+               if (ddb_entry == NULL) {
+                       DEBUG2(printk(KERN_WARNING
+                               "scsi%ld: Unable to allocate memory"
+                               " to add fw_ddb_index %d\n",
+                               ha->host_no, fw_ddb_index));
+                       return;
+               }
+       }
        if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) ==
                                    QLA_ERROR) {
                ha->fw_ddb_index_map[fw_ddb_index] =
index a216a17..5006ecb 100644 (file)
@@ -6,6 +6,10 @@
  */
 
 #include "ql4_def.h"
+#include "ql4_glbl.h"
+#include "ql4_dbg.h"
+#include "ql4_inline.h"
+
 
 #include <scsi/scsi_tcq.h>
 
@@ -141,11 +145,13 @@ static void qla4xxx_build_scsi_iocbs(struct srb *srb,
        uint16_t avail_dsds;
        struct data_seg_a64 *cur_dsd;
        struct scsi_cmnd *cmd;
+       struct scatterlist *sg;
+       int i;
 
        cmd = srb->cmd;
        ha = srb->ha;
 
-       if (cmd->request_bufflen == 0 || cmd->sc_data_direction == DMA_NONE) {
+       if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
                /* No data being transferred */
                cmd_entry->ttlByteCnt = __constant_cpu_to_le32(0);
                return;
@@ -154,40 +160,27 @@ static void qla4xxx_build_scsi_iocbs(struct srb *srb,
        avail_dsds = COMMAND_SEG;
        cur_dsd = (struct data_seg_a64 *) & (cmd_entry->dataseg[0]);
 
-       /* Load data segments */
-       if (cmd->use_sg) {
-               struct scatterlist *cur_seg;
-               struct scatterlist *end_seg;
-
-               cur_seg = (struct scatterlist *)cmd->request_buffer;
-               end_seg = cur_seg + tot_dsds;
-               while (cur_seg < end_seg) {
-                       dma_addr_t sle_dma;
-
-                       /* Allocate additional continuation packets? */
-                       if (avail_dsds == 0) {
-                               struct continuation_t1_entry *cont_entry;
-
-                               cont_entry = qla4xxx_alloc_cont_entry(ha);
-                               cur_dsd =
-                                       (struct data_seg_a64 *)
-                                       &cont_entry->dataseg[0];
-                               avail_dsds = CONTINUE_SEG;
-                       }
-
-                       sle_dma = sg_dma_address(cur_seg);
-                       cur_dsd->base.addrLow = cpu_to_le32(LSDW(sle_dma));
-                       cur_dsd->base.addrHigh = cpu_to_le32(MSDW(sle_dma));
-                       cur_dsd->count = cpu_to_le32(sg_dma_len(cur_seg));
-                       avail_dsds--;
-
-                       cur_dsd++;
-                       cur_seg++;
+       scsi_for_each_sg(cmd, sg, tot_dsds, i) {
+               dma_addr_t sle_dma;
+
+               /* Allocate additional continuation packets? */
+               if (avail_dsds == 0) {
+                       struct continuation_t1_entry *cont_entry;
+
+                       cont_entry = qla4xxx_alloc_cont_entry(ha);
+                       cur_dsd =
+                               (struct data_seg_a64 *)
+                               &cont_entry->dataseg[0];
+                       avail_dsds = CONTINUE_SEG;
                }
-       } else {
-               cur_dsd->base.addrLow = cpu_to_le32(LSDW(srb->dma_handle));
-               cur_dsd->base.addrHigh = cpu_to_le32(MSDW(srb->dma_handle));
-               cur_dsd->count = cpu_to_le32(cmd->request_bufflen);
+
+               sle_dma = sg_dma_address(sg);
+               cur_dsd->base.addrLow = cpu_to_le32(LSDW(sle_dma));
+               cur_dsd->base.addrHigh = cpu_to_le32(MSDW(sle_dma));
+               cur_dsd->count = cpu_to_le32(sg_dma_len(sg));
+               avail_dsds--;
+
+               cur_dsd++;
        }
 }
 
@@ -204,8 +197,8 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
        struct scsi_cmnd *cmd = srb->cmd;
        struct ddb_entry *ddb_entry;
        struct command_t3_entry *cmd_entry;
-       struct scatterlist *sg = NULL;
 
+       int nseg;
        uint16_t tot_dsds;
        uint16_t req_cnt;
 
@@ -233,24 +226,11 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
        index = (uint32_t)cmd->request->tag;
 
        /* Calculate the number of request entries needed. */
-       if (cmd->use_sg) {
-               sg = (struct scatterlist *)cmd->request_buffer;
-               tot_dsds = pci_map_sg(ha->pdev, sg, cmd->use_sg,
-                                     cmd->sc_data_direction);
-               if (tot_dsds == 0)
-                       goto queuing_error;
-       } else if (cmd->request_bufflen) {
-               dma_addr_t      req_dma;
-
-               req_dma = pci_map_single(ha->pdev, cmd->request_buffer,
-                                        cmd->request_bufflen,
-                                        cmd->sc_data_direction);
-               if (dma_mapping_error(req_dma))
-                       goto queuing_error;
-
-               srb->dma_handle = req_dma;
-               tot_dsds = 1;
-       }
+       nseg = scsi_dma_map(cmd);
+       if (nseg < 0)
+               goto queuing_error;
+       tot_dsds = nseg;
+
        req_cnt = qla4xxx_calc_request_entries(tot_dsds);
 
        if (ha->req_q_count < (req_cnt + 2)) {
@@ -279,7 +259,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
 
        int_to_scsilun(cmd->device->lun, &cmd_entry->lun);
        cmd_entry->cmdSeqNum = cpu_to_le32(ddb_entry->CmdSn);
-       cmd_entry->ttlByteCnt = cpu_to_le32(cmd->request_bufflen);
+       cmd_entry->ttlByteCnt = cpu_to_le32(scsi_bufflen(cmd));
        memcpy(cmd_entry->cdb, cmd->cmnd, cmd->cmd_len);
        cmd_entry->dataSegCnt = cpu_to_le16(tot_dsds);
        cmd_entry->hdr.entryCount = req_cnt;
@@ -289,13 +269,13 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
         *       transferred, as the data direction bit is sometimed filled
         *       in when there is no data to be transferred */
        cmd_entry->control_flags = CF_NO_DATA;
-       if (cmd->request_bufflen) {
+       if (scsi_bufflen(cmd)) {
                if (cmd->sc_data_direction == DMA_TO_DEVICE)
                        cmd_entry->control_flags = CF_WRITE;
                else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
                        cmd_entry->control_flags = CF_READ;
 
-               ha->bytes_xfered += cmd->request_bufflen;
+               ha->bytes_xfered += scsi_bufflen(cmd);
                if (ha->bytes_xfered & ~0xFFFFF){
                        ha->total_mbytes_xferred += ha->bytes_xfered >> 20;
                        ha->bytes_xfered &= 0xFFFFF;
@@ -359,14 +339,9 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
        return QLA_SUCCESS;
 
 queuing_error:
+       if (tot_dsds)
+               scsi_dma_unmap(cmd);
 
-       if (cmd->use_sg && tot_dsds) {
-               sg = (struct scatterlist *) cmd->request_buffer;
-               pci_unmap_sg(ha->pdev, sg, cmd->use_sg,
-                            cmd->sc_data_direction);
-       } else if (tot_dsds)
-               pci_unmap_single(ha->pdev, srb->dma_handle,
-                                cmd->request_bufflen, cmd->sc_data_direction);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        return QLA_ERROR;
index 35b9e36..b47bd85 100644 (file)
@@ -6,6 +6,9 @@
  */
 
 #include "ql4_def.h"
+#include "ql4_glbl.h"
+#include "ql4_dbg.h"
+#include "ql4_inline.h"
 
 /**
  * qla2x00_process_completed_request() - Process a Fast Post response.
@@ -92,7 +95,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
 
                if (sts_entry->iscsiFlags &
                    (ISCSI_FLAG_RESIDUAL_OVER|ISCSI_FLAG_RESIDUAL_UNDER))
-                       cmd->resid = residual;
+                       scsi_set_resid(cmd, residual);
 
                cmd->result = DID_OK << 16 | scsi_status;
 
@@ -176,14 +179,14 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
                         * Firmware detected a SCSI transport underrun
                         * condition
                         */
-                       cmd->resid = residual;
+                       scsi_set_resid(cmd, residual);
                        DEBUG2(printk("scsi%ld:%d:%d:%d: %s: UNDERRUN status "
                                      "detected, xferlen = 0x%x, residual = "
                                      "0x%x\n",
                                      ha->host_no, cmd->device->channel,
                                      cmd->device->id,
                                      cmd->device->lun, __func__,
-                                     cmd->request_bufflen,
+                                     scsi_bufflen(cmd),
                                      residual));
                }
 
@@ -227,7 +230,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
                        if ((sts_entry->iscsiFlags &
                             ISCSI_FLAG_RESIDUAL_UNDER) == 0) {
                                cmd->result = DID_BUS_BUSY << 16;
-                       } else if ((cmd->request_bufflen - residual) <
+                       } else if ((scsi_bufflen(cmd) - residual) <
                                   cmd->underflow) {
                                /*
                                 * Handle mid-layer underflow???
@@ -248,7 +251,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
                                              cmd->device->channel,
                                              cmd->device->id,
                                              cmd->device->lun, __func__,
-                                             cmd->request_bufflen, residual));
+                                             scsi_bufflen(cmd), residual));
 
                                cmd->result = DID_ERROR << 16;
                        } else {
@@ -417,6 +420,7 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
                                       uint32_t mbox_status)
 {
        int i;
+       uint32_t mbox_stat2, mbox_stat3;
 
        if ((mbox_status == MBOX_STS_BUSY) ||
            (mbox_status == MBOX_STS_INTERMEDIATE_COMPLETION) ||
@@ -437,6 +441,12 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
        } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) {
                /* Immediately process the AENs that don't require much work.
                 * Only queue the database_changed AENs */
+               if (ha->aen_log.count < MAX_AEN_ENTRIES) {
+                       for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
+                               ha->aen_log.entry[ha->aen_log.count].mbox_sts[i] =
+                                       readl(&ha->reg->mailbox[i]);
+                       ha->aen_log.count++;
+               }
                switch (mbox_status) {
                case MBOX_ASTS_SYSTEM_ERROR:
                        /* Log Mailbox registers */
@@ -493,6 +503,16 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
                                      mbox_status));
                        break;
 
+               case MBOX_ASTS_IP_ADDR_STATE_CHANGED:
+                       mbox_stat2 = readl(&ha->reg->mailbox[2]);
+                       mbox_stat3 = readl(&ha->reg->mailbox[3]);
+
+                       if ((mbox_stat3 == 5) && (mbox_stat2 == 3))
+                               set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
+                       else if ((mbox_stat3 == 2) && (mbox_stat2 == 5))
+                               set_bit(DPC_RESET_HA, &ha->dpc_flags);
+                       break;
+
                case MBOX_ASTS_MAC_ADDRESS_CHANGED:
                case MBOX_ASTS_DNS:
                        /* No action */
@@ -518,11 +538,6 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
                        /* Queue AEN information and process it in the DPC
                         * routine */
                        if (ha->aen_q_count > 0) {
-                               /* advance pointer */
-                               if (ha->aen_in == (MAX_AEN_ENTRIES - 1))
-                                       ha->aen_in = 0;
-                               else
-                                       ha->aen_in++;
 
                                /* decrement available counter */
                                ha->aen_q_count--;
@@ -542,6 +557,10 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
                                              ha->aen_q[ha->aen_in].mbox_sts[2],
                                              ha->aen_q[ha->aen_in].mbox_sts[3],
                                              ha->aen_q[ha->aen_in].  mbox_sts[4]));
+                               /* advance pointer */
+                               ha->aen_in++;
+                               if (ha->aen_in == MAX_AEN_ENTRIES)
+                                       ha->aen_in = 0;
 
                                /* The DPC routine will process the aen */
                                set_bit(DPC_AEN, &ha->dpc_flags);
@@ -724,25 +743,24 @@ void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen)
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
        while (ha->aen_out != ha->aen_in) {
-               /* Advance pointers for next entry */
-               if (ha->aen_out == (MAX_AEN_ENTRIES - 1))
-                       ha->aen_out = 0;
-               else
-                       ha->aen_out++;
-
-               ha->aen_q_count++;
                aen = &ha->aen_q[ha->aen_out];
-
                /* copy aen information to local structure */
                for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
                        mbox_sts[i] = aen->mbox_sts[i];
 
+               ha->aen_q_count++;
+               ha->aen_out++;
+
+               if (ha->aen_out == MAX_AEN_ENTRIES)
+                       ha->aen_out = 0;
+
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-               DEBUG(printk("scsi%ld: AEN[%d] %04x, index [%d] state=%04x "
-                            "mod=%x conerr=%08x \n", ha->host_no, ha->aen_out,
-                            mbox_sts[0], mbox_sts[2], mbox_sts[3],
-                            mbox_sts[1], mbox_sts[4]));
+               DEBUG2(printk("qla4xxx(%ld): AEN[%d]=0x%08x, mbx1=0x%08x mbx2=0x%08x"
+                       " mbx3=0x%08x mbx4=0x%08x\n", ha->host_no,
+                       (ha->aen_out ? (ha->aen_out-1): (MAX_AEN_ENTRIES-1)),
+                       mbox_sts[0], mbox_sts[1], mbox_sts[2],
+                       mbox_sts[3], mbox_sts[4]));
 
                switch (mbox_sts[0]) {
                case MBOX_ASTS_DATABASE_CHANGED:
@@ -792,6 +810,5 @@ void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen)
                spin_lock_irqsave(&ha->hardware_lock, flags);
        }
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
 }
 
index f116ff9..35cd73c 100644 (file)
@@ -6,6 +6,9 @@
  */
 
 #include "ql4_def.h"
+#include "ql4_glbl.h"
+#include "ql4_dbg.h"
+#include "ql4_inline.h"
 
 
 /**
@@ -169,84 +172,6 @@ mbox_exit:
        return status;
 }
 
-
-#if 0
-
-/**
- * qla4xxx_issue_iocb - issue mailbox iocb command
- * @ha: adapter state pointer.
- * @buffer: buffer pointer.
- * @phys_addr: physical address of buffer.
- * @size: size of buffer.
- *
- * Issues iocbs via mailbox commands.
- * TARGET_QUEUE_LOCK must be released.
- * ADAPTER_STATE_LOCK must be released.
- **/
-int
-qla4xxx_issue_iocb(struct scsi_qla_host * ha, void *buffer,
-                  dma_addr_t phys_addr, size_t size)
-{
-       uint32_t mbox_cmd[MBOX_REG_COUNT];
-       uint32_t mbox_sts[MBOX_REG_COUNT];
-       int status;
-
-       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
-       memset(&mbox_sts, 0, sizeof(mbox_sts));
-       mbox_cmd[0] = MBOX_CMD_EXECUTE_IOCB_A64;
-       mbox_cmd[1] = 0;
-       mbox_cmd[2] = LSDW(phys_addr);
-       mbox_cmd[3] = MSDW(phys_addr);
-       status = qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]);
-       return status;
-}
-
-int qla4xxx_conn_close_sess_logout(struct scsi_qla_host * ha,
-                                  uint16_t fw_ddb_index,
-                                  uint16_t connection_id,
-                                  uint16_t option)
-{
-       uint32_t mbox_cmd[MBOX_REG_COUNT];
-       uint32_t mbox_sts[MBOX_REG_COUNT];
-
-       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
-       memset(&mbox_sts, 0, sizeof(mbox_sts));
-       mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT;
-       mbox_cmd[1] = fw_ddb_index;
-       mbox_cmd[2] = connection_id;
-       mbox_cmd[3] = LOGOUT_OPTION_RELOGIN;
-       if (qla4xxx_mailbox_command(ha, 4, 2, &mbox_cmd[0], &mbox_sts[0]) !=
-           QLA_SUCCESS) {
-               DEBUG2(printk("scsi%ld: %s: MBOX_CMD_CONN_CLOSE_SESS_LOGOUT "
-                             "option %04x failed sts %04X %04X",
-                             ha->host_no, __func__,
-                             option, mbox_sts[0], mbox_sts[1]));
-               if (mbox_sts[0] == 0x4005)
-                       DEBUG2(printk("%s reason %04X\n", __func__,
-                                     mbox_sts[1]));
-       }
-       return QLA_SUCCESS;
-}
-
-int qla4xxx_clear_database_entry(struct scsi_qla_host * ha,
-                                uint16_t fw_ddb_index)
-{
-       uint32_t mbox_cmd[MBOX_REG_COUNT];
-       uint32_t mbox_sts[MBOX_REG_COUNT];
-
-       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
-       memset(&mbox_sts, 0, sizeof(mbox_sts));
-       mbox_cmd[0] = MBOX_CMD_CLEAR_DATABASE_ENTRY;
-       mbox_cmd[1] = fw_ddb_index;
-       if (qla4xxx_mailbox_command(ha, 2, 5, &mbox_cmd[0], &mbox_sts[0]) !=
-           QLA_SUCCESS)
-               return QLA_ERROR;
-
-       return QLA_SUCCESS;
-}
-
-#endif  /*  0  */
-
 /**
  * qla4xxx_initialize_fw_cb - initializes firmware control block.
  * @ha: Pointer to host adapter structure.
@@ -272,10 +197,13 @@ int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
        /* Get Initialize Firmware Control Block. */
        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
        memset(&mbox_sts, 0, sizeof(mbox_sts));
+
        mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
        mbox_cmd[2] = LSDW(init_fw_cb_dma);
        mbox_cmd[3] = MSDW(init_fw_cb_dma);
-       if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) !=
+       mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk);
+
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
            QLA_SUCCESS) {
                dma_free_coherent(&ha->pdev->dev,
                                  sizeof(struct init_fw_ctrl_blk),
@@ -287,51 +215,56 @@ int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
        qla4xxx_init_rings(ha);
 
        /* Fill in the request and response queue information. */
-       init_fw_cb->ReqQConsumerIndex = cpu_to_le16(ha->request_out);
-       init_fw_cb->ComplQProducerIndex = cpu_to_le16(ha->response_in);
-       init_fw_cb->ReqQLen = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH);
-       init_fw_cb->ComplQLen = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH);
-       init_fw_cb->ReqQAddrLo = cpu_to_le32(LSDW(ha->request_dma));
-       init_fw_cb->ReqQAddrHi = cpu_to_le32(MSDW(ha->request_dma));
-       init_fw_cb->ComplQAddrLo = cpu_to_le32(LSDW(ha->response_dma));
-       init_fw_cb->ComplQAddrHi = cpu_to_le32(MSDW(ha->response_dma));
-       init_fw_cb->ShadowRegBufAddrLo =
+       init_fw_cb->pri.rqq_consumer_idx = cpu_to_le16(ha->request_out);
+       init_fw_cb->pri.compq_producer_idx = cpu_to_le16(ha->response_in);
+       init_fw_cb->pri.rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH);
+       init_fw_cb->pri.compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH);
+       init_fw_cb->pri.rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma));
+       init_fw_cb->pri.rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma));
+       init_fw_cb->pri.compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma));
+       init_fw_cb->pri.compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma));
+       init_fw_cb->pri.shdwreg_addr_lo =
                cpu_to_le32(LSDW(ha->shadow_regs_dma));
-       init_fw_cb->ShadowRegBufAddrHi =
+       init_fw_cb->pri.shdwreg_addr_hi =
                cpu_to_le32(MSDW(ha->shadow_regs_dma));
 
        /* Set up required options. */
-       init_fw_cb->FwOptions |=
+       init_fw_cb->pri.fw_options |=
                __constant_cpu_to_le16(FWOPT_SESSION_MODE |
                                       FWOPT_INITIATOR_MODE);
-       init_fw_cb->FwOptions &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE);
+       init_fw_cb->pri.fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE);
 
        /* Save some info in adapter structure. */
-       ha->firmware_options = le16_to_cpu(init_fw_cb->FwOptions);
-       ha->tcp_options = le16_to_cpu(init_fw_cb->TCPOptions);
-       ha->heartbeat_interval = init_fw_cb->HeartbeatInterval;
-       memcpy(ha->ip_address, init_fw_cb->IPAddr,
-              min(sizeof(ha->ip_address), sizeof(init_fw_cb->IPAddr)));
-       memcpy(ha->subnet_mask, init_fw_cb->SubnetMask,
-              min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->SubnetMask)));
-       memcpy(ha->gateway, init_fw_cb->GatewayIPAddr,
-              min(sizeof(ha->gateway), sizeof(init_fw_cb->GatewayIPAddr)));
-       memcpy(ha->name_string, init_fw_cb->iSCSINameString,
+       ha->firmware_options = le16_to_cpu(init_fw_cb->pri.fw_options);
+       ha->tcp_options = le16_to_cpu(init_fw_cb->pri.ipv4_tcp_opts);
+       ha->heartbeat_interval = init_fw_cb->pri.hb_interval;
+       memcpy(ha->ip_address, init_fw_cb->pri.ipv4_addr,
+              min(sizeof(ha->ip_address), sizeof(init_fw_cb->pri.ipv4_addr)));
+       memcpy(ha->subnet_mask, init_fw_cb->pri.ipv4_subnet,
+              min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->pri.ipv4_subnet)));
+       memcpy(ha->gateway, init_fw_cb->pri.ipv4_gw_addr,
+              min(sizeof(ha->gateway), sizeof(init_fw_cb->pri.ipv4_gw_addr)));
+       memcpy(ha->name_string, init_fw_cb->pri.iscsi_name,
               min(sizeof(ha->name_string),
-                  sizeof(init_fw_cb->iSCSINameString)));
-       memcpy(ha->alias, init_fw_cb->Alias,
-              min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));
+                  sizeof(init_fw_cb->pri.iscsi_name)));
+       /*memcpy(ha->alias, init_fw_cb->Alias,
+              min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/
 
        /* Save Command Line Paramater info */
-       ha->port_down_retry_count = le16_to_cpu(init_fw_cb->KeepAliveTimeout);
+       ha->port_down_retry_count = le16_to_cpu(init_fw_cb->pri.conn_ka_timeout);
        ha->discovery_wait = ql4xdiscoverywait;
 
        /* Send Initialize Firmware Control Block. */
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+
        mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;
        mbox_cmd[1] = 0;
        mbox_cmd[2] = LSDW(init_fw_cb_dma);
        mbox_cmd[3] = MSDW(init_fw_cb_dma);
-       if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) ==
+       mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk);
+
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) ==
            QLA_SUCCESS)
                status = QLA_SUCCESS;
         else {
@@ -368,12 +301,14 @@ int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha)
        /* Get Initialize Firmware Control Block. */
        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
        memset(&mbox_sts, 0, sizeof(mbox_sts));
+
        memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk));
        mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
        mbox_cmd[2] = LSDW(init_fw_cb_dma);
        mbox_cmd[3] = MSDW(init_fw_cb_dma);
+       mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk);
 
-       if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) !=
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
            QLA_SUCCESS) {
                DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
                              ha->host_no, __func__));
@@ -384,12 +319,12 @@ int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha)
        }
 
        /* Save IP Address. */
-       memcpy(ha->ip_address, init_fw_cb->IPAddr,
-              min(sizeof(ha->ip_address), sizeof(init_fw_cb->IPAddr)));
-       memcpy(ha->subnet_mask, init_fw_cb->SubnetMask,
-              min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->SubnetMask)));
-       memcpy(ha->gateway, init_fw_cb->GatewayIPAddr,
-              min(sizeof(ha->gateway), sizeof(init_fw_cb->GatewayIPAddr)));
+       memcpy(ha->ip_address, init_fw_cb->pri.ipv4_addr,
+              min(sizeof(ha->ip_address), sizeof(init_fw_cb->pri.ipv4_addr)));
+       memcpy(ha->subnet_mask, init_fw_cb->pri.ipv4_subnet,
+              min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->pri.ipv4_subnet)));
+       memcpy(ha->gateway, init_fw_cb->pri.ipv4_gw_addr,
+              min(sizeof(ha->gateway), sizeof(init_fw_cb->pri.ipv4_gw_addr)));
 
        dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk),
                          init_fw_cb, init_fw_cb_dma);
@@ -409,8 +344,10 @@ int qla4xxx_get_firmware_state(struct scsi_qla_host * ha)
        /* Get firmware version */
        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
        memset(&mbox_sts, 0, sizeof(mbox_sts));
+
        mbox_cmd[0] = MBOX_CMD_GET_FW_STATE;
-       if (qla4xxx_mailbox_command(ha, 1, 4, &mbox_cmd[0], &mbox_sts[0]) !=
+
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 4, &mbox_cmd[0], &mbox_sts[0]) !=
            QLA_SUCCESS) {
                DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ "
                              "status %04X\n", ha->host_no, __func__,
@@ -438,8 +375,10 @@ int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)
        /* Get firmware version */
        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
        memset(&mbox_sts, 0, sizeof(mbox_sts));
+
        mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS;
-       if (qla4xxx_mailbox_command(ha, 1, 3, &mbox_cmd[0], &mbox_sts[0]) !=
+
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) !=
            QLA_SUCCESS) {
                DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ "
                              "status %04X\n", ha->host_no, __func__,
@@ -491,11 +430,14 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
        }
        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
        memset(&mbox_sts, 0, sizeof(mbox_sts));
+
        mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY;
        mbox_cmd[1] = (uint32_t) fw_ddb_index;
        mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
        mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
-       if (qla4xxx_mailbox_command(ha, 4, 7, &mbox_cmd[0], &mbox_sts[0]) ==
+       mbox_cmd[4] = sizeof(struct dev_db_entry);
+
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 7, &mbox_cmd[0], &mbox_sts[0]) ==
            QLA_ERROR) {
                DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed"
                              " with status 0x%04X\n", ha->host_no, __func__,
@@ -512,11 +454,11 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
                dev_info(&ha->pdev->dev, "DDB[%d] MB0 %04x Tot %d Next %d "
                           "State %04x ConnErr %08x %d.%d.%d.%d:%04d \"%s\"\n",
                           fw_ddb_index, mbox_sts[0], mbox_sts[2], mbox_sts[3],
-                          mbox_sts[4], mbox_sts[5], fw_ddb_entry->ipAddr[0],
-                          fw_ddb_entry->ipAddr[1], fw_ddb_entry->ipAddr[2],
-                          fw_ddb_entry->ipAddr[3],
-                          le16_to_cpu(fw_ddb_entry->portNumber),
-                          fw_ddb_entry->iscsiName);
+                          mbox_sts[4], mbox_sts[5], fw_ddb_entry->ip_addr[0],
+                          fw_ddb_entry->ip_addr[1], fw_ddb_entry->ip_addr[2],
+                          fw_ddb_entry->ip_addr[3],
+                          le16_to_cpu(fw_ddb_entry->port),
+                          fw_ddb_entry->iscsi_name);
        }
        if (num_valid_ddb_entries)
                *num_valid_ddb_entries = mbox_sts[2];
@@ -571,35 +513,10 @@ int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
        mbox_cmd[1] = (uint32_t) fw_ddb_index;
        mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
        mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
-       return qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]);
-}
+       mbox_cmd[4] = sizeof(struct dev_db_entry);
 
-#if 0
-int qla4xxx_conn_open_session_login(struct scsi_qla_host * ha,
-                                   uint16_t fw_ddb_index)
-{
-       int status = QLA_ERROR;
-       uint32_t mbox_cmd[MBOX_REG_COUNT];
-       uint32_t mbox_sts[MBOX_REG_COUNT];
-
-       /* Do not wait for completion. The firmware will send us an
-        * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status.
-        */
-       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
-       memset(&mbox_sts, 0, sizeof(mbox_sts));
-       mbox_cmd[0] = MBOX_CMD_CONN_OPEN_SESS_LOGIN;
-       mbox_cmd[1] = (uint32_t) fw_ddb_index;
-       mbox_cmd[2] = 0;
-       mbox_cmd[3] = 0;
-       mbox_cmd[4] = 0;
-       status = qla4xxx_mailbox_command(ha, 4, 0, &mbox_cmd[0], &mbox_sts[0]);
-       DEBUG2(printk("%s fw_ddb_index=%d status=%d mbx0_1=0x%x :0x%x\n",
-                     __func__, fw_ddb_index, status, mbox_sts[0],
-                     mbox_sts[1]);)
-
-               return status;
+       return qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]);
 }
-#endif  /*  0  */
 
 /**
  * qla4xxx_get_crash_record - retrieves crash record.
@@ -614,12 +531,14 @@ void qla4xxx_get_crash_record(struct scsi_qla_host * ha)
        struct crash_record *crash_record = NULL;
        dma_addr_t crash_record_dma = 0;
        uint32_t crash_record_size = 0;
+
        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
        memset(&mbox_sts, 0, sizeof(mbox_cmd));
 
        /* Get size of crash record. */
        mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
-       if (qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]) !=
+
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
            QLA_SUCCESS) {
                DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n",
                              ha->host_no, __func__));
@@ -639,11 +558,15 @@ void qla4xxx_get_crash_record(struct scsi_qla_host * ha)
                goto exit_get_crash_record;
 
        /* Get Crash Record. */
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_cmd));
+
        mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
        mbox_cmd[2] = LSDW(crash_record_dma);
        mbox_cmd[3] = MSDW(crash_record_dma);
        mbox_cmd[4] = crash_record_size;
-       if (qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]) !=
+
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
            QLA_SUCCESS)
                goto exit_get_crash_record;
 
@@ -655,7 +578,6 @@ exit_get_crash_record:
                                  crash_record, crash_record_dma);
 }
 
-#if 0
 /**
  * qla4xxx_get_conn_event_log - retrieves connection event log
  * @ha: Pointer to host adapter structure.
@@ -678,7 +600,8 @@ void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha)
 
        /* Get size of crash record. */
        mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
-       if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) !=
+
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
            QLA_SUCCESS)
                goto exit_get_event_log;
 
@@ -693,10 +616,14 @@ void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha)
                goto exit_get_event_log;
 
        /* Get Crash Record. */
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_cmd));
+
        mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
        mbox_cmd[2] = LSDW(event_log_dma);
        mbox_cmd[3] = MSDW(event_log_dma);
-       if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) !=
+
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
            QLA_SUCCESS) {
                DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event "
                              "log!\n", ha->host_no, __func__));
@@ -745,7 +672,6 @@ exit_get_event_log:
                dma_free_coherent(&ha->pdev->dev, event_log_size, event_log,
                                  event_log_dma);
 }
-#endif  /*  0  */
 
 /**
  * qla4xxx_reset_lun - issues LUN Reset
@@ -773,11 +699,13 @@ int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
         */
        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
        memset(&mbox_sts, 0, sizeof(mbox_sts));
+
        mbox_cmd[0] = MBOX_CMD_LUN_RESET;
        mbox_cmd[1] = ddb_entry->fw_ddb_index;
        mbox_cmd[2] = lun << 8;
        mbox_cmd[5] = 0x01;     /* Immediate Command Enable */
-       qla4xxx_mailbox_command(ha, 6, 1, &mbox_cmd[0], &mbox_sts[0]);
+
+       qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]);
        if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
            mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
                status = QLA_ERROR;
@@ -794,12 +722,14 @@ int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr,
 
        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
        memset(&mbox_sts, 0, sizeof(mbox_sts));
+
        mbox_cmd[0] = MBOX_CMD_READ_FLASH;
        mbox_cmd[1] = LSDW(dma_addr);
        mbox_cmd[2] = MSDW(dma_addr);
        mbox_cmd[3] = offset;
        mbox_cmd[4] = len;
-       if (qla4xxx_mailbox_command(ha, 5, 2, &mbox_cmd[0], &mbox_sts[0]) !=
+
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], &mbox_sts[0]) !=
            QLA_SUCCESS) {
                DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ "
                    "status %04X %04X, offset %08x, len %08x\n", ha->host_no,
@@ -825,8 +755,10 @@ int qla4xxx_get_fw_version(struct scsi_qla_host * ha)
        /* Get firmware version. */
        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
        memset(&mbox_sts, 0, sizeof(mbox_sts));
+
        mbox_cmd[0] = MBOX_CMD_ABOUT_FW;
-       if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) !=
+
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
            QLA_SUCCESS) {
                DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ "
                    "status %04X\n", ha->host_no, __func__, mbox_sts[0]));
@@ -855,7 +787,7 @@ static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha,
        mbox_cmd[2] = LSDW(dma_addr);
        mbox_cmd[3] = MSDW(dma_addr);
 
-       if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) !=
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
            QLA_SUCCESS) {
                DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
                     ha->host_no, __func__, mbox_sts[0]));
@@ -875,7 +807,7 @@ static int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index)
        mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY;
        mbox_cmd[1] = MAX_PRST_DEV_DB_ENTRIES;
 
-       if (qla4xxx_mailbox_command(ha, 2, 3, &mbox_cmd[0], &mbox_sts[0]) !=
+       if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) !=
            QLA_SUCCESS) {
                if (mbox_sts[0] == MBOX_STS_COMMAND_ERROR) {
                        *ddb_index = mbox_sts[2];
@@ -918,23 +850,23 @@ int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port)
        if (ret_val != QLA_SUCCESS)
                goto qla4xxx_send_tgts_exit;
 
-       memset((void *)fw_ddb_entry->iSCSIAlias, 0,
-              sizeof(fw_ddb_entry->iSCSIAlias));
+       memset(fw_ddb_entry->iscsi_alias, 0,
+              sizeof(fw_ddb_entry->iscsi_alias));
 
-       memset((void *)fw_ddb_entry->iscsiName, 0,
-              sizeof(fw_ddb_entry->iscsiName));
+       memset(fw_ddb_entry->iscsi_name, 0,
+              sizeof(fw_ddb_entry->iscsi_name));
 
-       memset((void *)fw_ddb_entry->ipAddr, 0, sizeof(fw_ddb_entry->ipAddr));
-       memset((void *)fw_ddb_entry->targetAddr, 0,
-              sizeof(fw_ddb_entry->targetAddr));
+       memset(fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr));
+       memset(fw_ddb_entry->tgt_addr, 0,
+              sizeof(fw_ddb_entry->tgt_addr));
 
        fw_ddb_entry->options = (DDB_OPT_DISC_SESSION | DDB_OPT_TARGET);
-       fw_ddb_entry->portNumber = cpu_to_le16(ntohs(port));
+       fw_ddb_entry->port = cpu_to_le16(ntohs(port));
 
-       fw_ddb_entry->ipAddr[0] = *ip;
-       fw_ddb_entry->ipAddr[1] = *(ip + 1);
-       fw_ddb_entry->ipAddr[2] = *(ip + 2);
-       fw_ddb_entry->ipAddr[3] = *(ip + 3);
+       fw_ddb_entry->ip_addr[0] = *ip;
+       fw_ddb_entry->ip_addr[1] = *(ip + 1);
+       fw_ddb_entry->ip_addr[2] = *(ip + 2);
+       fw_ddb_entry->ip_addr[3] = *(ip + 3);
 
        ret_val = qla4xxx_set_ddb_entry(ha, ddb_index, fw_ddb_entry_dma);
 
index 58afd13..7fe0482 100644 (file)
@@ -6,6 +6,9 @@
  */
 
 #include "ql4_def.h"
+#include "ql4_glbl.h"
+#include "ql4_dbg.h"
+#include "ql4_inline.h"
 
 static inline void eeprom_cmd(uint32_t cmd, struct scsi_qla_host *ha)
 {
index da21f5f..e09fc42 100644 (file)
 #include <scsi/scsicam.h>
 
 #include "ql4_def.h"
+#include "ql4_version.h"
+#include "ql4_glbl.h"
+#include "ql4_dbg.h"
+#include "ql4_inline.h"
 
 /*
  * Driver version
@@ -369,14 +373,7 @@ static void qla4xxx_srb_free_dma(struct scsi_qla_host *ha, struct srb *srb)
        struct scsi_cmnd *cmd = srb->cmd;
 
        if (srb->flags & SRB_DMA_VALID) {
-               if (cmd->use_sg) {
-                       pci_unmap_sg(ha->pdev, cmd->request_buffer,
-                                    cmd->use_sg, cmd->sc_data_direction);
-               } else if (cmd->request_bufflen) {
-                       pci_unmap_single(ha->pdev, srb->dma_handle,
-                                        cmd->request_bufflen,
-                                        cmd->sc_data_direction);
-               }
+               scsi_dma_unmap(cmd);
                srb->flags &= ~SRB_DMA_VALID;
        }
        cmd->SCp.ptr = NULL;
@@ -711,7 +708,7 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha)
        return stat;
 }
 
-static void qla4xxx_hw_reset(struct scsi_qla_host *ha)
+void qla4xxx_hw_reset(struct scsi_qla_host *ha)
 {
        uint32_t ctrl_status;
        unsigned long flags = 0;
@@ -1081,13 +1078,13 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
        if (ha->timer_active)
                qla4xxx_stop_timer(ha);
 
-       /* free extra memory */
-       qla4xxx_mem_free(ha);
-
        /* Detach interrupts */
        if (test_and_clear_bit(AF_IRQ_ATTACHED, &ha->flags))
                free_irq(ha->pdev->irq, ha);
 
+       /* free extra memory */
+       qla4xxx_mem_free(ha);
+
        pci_disable_device(ha->pdev);
 
 }
@@ -1332,6 +1329,11 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev)
 
        ha = pci_get_drvdata(pdev);
 
+       qla4xxx_disable_intrs(ha);
+
+       while (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags))
+               ssleep(1);
+
        /* remove devs from iscsi_sessions to scsi_devices */
        qla4xxx_free_ddb_list(ha);
 
index e5183a6..2149069 100644 (file)
@@ -5,4 +5,5 @@
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
 
-#define QLA4XXX_DRIVER_VERSION "5.00.07-k1"
+#define QLA4XXX_DRIVER_VERSION "5.01.00-k7"
+
index 2e7db18..2bfbf26 100644 (file)
@@ -265,8 +265,6 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
        unsigned int message;   /* scsi returned message */
        unsigned int phase;     /* recorded scsi phase */
        unsigned int reqlen;    /* total length of transfer */
-       struct scatterlist *sglist;     /* scatter-gather list pointer */
-       unsigned int sgcount;   /* sg counter */
        char *buf;
        struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
        int qbase = priv->qbase;
@@ -301,9 +299,10 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
        if (inb(qbase + 7) & 0x1f)      /* if some bytes in fifo */
                outb(1, qbase + 3);     /* clear fifo */
        /* note that request_bufflen is the total xfer size when sg is used */
-       reqlen = cmd->request_bufflen;
+       reqlen = scsi_bufflen(cmd);
        /* note that it won't work if transfers > 16M are requested */
        if (reqlen && !((phase = inb(qbase + 4)) & 6)) {        /* data phase */
+               struct scatterlist *sg;
                rtrc(2)
                outb(reqlen, qbase);    /* low-mid xfer cnt */
                outb(reqlen >> 8, qbase + 1);   /* low-mid xfer cnt */
@@ -311,23 +310,16 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
                outb(0x90, qbase + 3);  /* command do xfer */
                /* PIO pseudo DMA to buffer or sglist */
                REG1;
-               if (!cmd->use_sg)
-                       ql_pdma(priv, phase, cmd->request_buffer,
-                               cmd->request_bufflen);
-               else {
-                       sgcount = cmd->use_sg;
-                       sglist = cmd->request_buffer;
-                       while (sgcount--) {
-                               if (priv->qabort) {
-                                       REG0;
-                                       return ((priv->qabort == 1 ?
-                                               DID_ABORT : DID_RESET) << 16);
-                               }
-                               buf = page_address(sglist->page) + sglist->offset;
-                               if (ql_pdma(priv, phase, buf, sglist->length))
-                                       break;
-                               sglist++;
+
+               scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) {
+                       if (priv->qabort) {
+                               REG0;
+                               return ((priv->qabort == 1 ?
+                                        DID_ABORT : DID_RESET) << 16);
                        }
+                       buf = page_address(sg->page) + sg->offset;
+                       if (ql_pdma(priv, phase, buf, sg->length))
+                               break;
                }
                REG0;
                rtrc(2)
index e8350c5..9adb64a 100644 (file)
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/interrupt.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/scatterlist.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -640,16 +640,8 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
        memcpy(scmd->cmnd, cmnd, cmnd_size);
 
        if (copy_sense) {
-               gfp_t gfp_mask = GFP_ATOMIC;
-
-               if (shost->hostt->unchecked_isa_dma)
-                       gfp_mask |= __GFP_DMA;
-
-               sgl.page = alloc_page(gfp_mask);
-               if (!sgl.page)
-                       return FAILED;
-               sgl.offset = 0;
-               sgl.length = 252;
+               sg_init_one(&sgl, scmd->sense_buffer,
+                           sizeof(scmd->sense_buffer));
 
                scmd->sc_data_direction = DMA_FROM_DEVICE;
                scmd->request_bufflen = sgl.length;
@@ -719,18 +711,6 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
        }
 
 
-       /*
-        * Last chance to have valid sense data.
-        */
-       if (copy_sense) {
-               if (!SCSI_SENSE_VALID(scmd)) {
-                       memcpy(scmd->sense_buffer, page_address(sgl.page),
-                              sizeof(scmd->sense_buffer));
-               }
-               __free_page(sgl.page);
-       }
-
-
        /*
         * Restore original data
         */
index 1f5a07b..70454b4 100644 (file)
@@ -2290,3 +2290,41 @@ void scsi_kunmap_atomic_sg(void *virt)
        kunmap_atomic(virt, KM_BIO_SRC_IRQ);
 }
 EXPORT_SYMBOL(scsi_kunmap_atomic_sg);
+
+/**
+ * scsi_dma_map - perform DMA mapping against command's sg lists
+ * @cmd:       scsi command
+ *
+ * Returns the number of sg lists actually used, zero if the sg lists
+ * is NULL, or -ENOMEM if the mapping failed.
+ */
+int scsi_dma_map(struct scsi_cmnd *cmd)
+{
+       int nseg = 0;
+
+       if (scsi_sg_count(cmd)) {
+               struct device *dev = cmd->device->host->shost_gendev.parent;
+
+               nseg = dma_map_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
+                                 cmd->sc_data_direction);
+               if (unlikely(!nseg))
+                       return -ENOMEM;
+       }
+       return nseg;
+}
+EXPORT_SYMBOL(scsi_dma_map);
+
+/**
+ * scsi_dma_unmap - unmap command's sg lists mapped by scsi_dma_map
+ * @cmd:       scsi command
+ */
+void scsi_dma_unmap(struct scsi_cmnd *cmd)
+{
+       if (scsi_sg_count(cmd)) {
+               struct device *dev = cmd->device->host->shost_gendev.parent;
+
+               dma_unmap_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
+                            cmd->sc_data_direction);
+       }
+}
+EXPORT_SYMBOL(scsi_dma_unmap);
index 67a38a1..ed72086 100644 (file)
@@ -293,30 +293,18 @@ static int scsi_bus_suspend(struct device * dev, pm_message_t state)
 {
        struct device_driver *drv = dev->driver;
        struct scsi_device *sdev = to_scsi_device(dev);
-       struct scsi_host_template *sht = sdev->host->hostt;
        int err;
 
        err = scsi_device_quiesce(sdev);
        if (err)
                return err;
 
-       /* call HLD suspend first */
        if (drv && drv->suspend) {
                err = drv->suspend(dev, state);
                if (err)
                        return err;
        }
 
-       /* then, call host suspend */
-       if (sht->suspend) {
-               err = sht->suspend(sdev, state);
-               if (err) {
-                       if (drv && drv->resume)
-                               drv->resume(dev);
-                       return err;
-               }
-       }
-
        return 0;
 }
 
@@ -324,21 +312,14 @@ static int scsi_bus_resume(struct device * dev)
 {
        struct device_driver *drv = dev->driver;
        struct scsi_device *sdev = to_scsi_device(dev);
-       struct scsi_host_template *sht = sdev->host->hostt;
-       int err = 0, err2 = 0;
-
-       /* call host resume first */
-       if (sht->resume)
-               err = sht->resume(sdev);
+       int err = 0;
 
-       /* then, call HLD resume */
        if (drv && drv->resume)
-               err2 = drv->resume(dev);
+               err = drv->resume(dev);
 
        scsi_device_resume(sdev);
 
-       /* favor LLD failure */
-       return err ? err : err2;;
+       return err;
 }
 
 struct bus_type scsi_bus_type = {
index b4d1ece..4953f0d 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  *  FiberChannel transport specific attributes exported to sysfs.
  *
  *  Copyright (c) 2003 Silicon Graphics, Inc.  All rights reserved.
  *
  *  ========
  *
- *  Copyright (C) 2004-2005   James Smart, Emulex Corporation
+ *  Copyright (C) 2004-2007   James Smart, Emulex Corporation
  *    Rewrite for host, target, device, and remote port attributes,
  *    statistics, and service functions...
+ *    Add vports, etc
  *
  */
 #include <linux/module.h>
 #include "scsi_priv.h"
 
 static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
+static void fc_vport_sched_delete(struct work_struct *work);
+
+/*
+ * This is a temporary carrier for creating a vport. It will eventually
+ * be replaced  by a real message definition for sgio or netlink.
+ *
+ * fc_vport_identifiers: This set of data contains all elements
+ * to uniquely identify and instantiate a FC virtual port.
+ *
+ * Notes:
+ *   symbolic_name: The driver is to append the symbolic_name string data
+ *      to the symbolic_node_name data that it generates by default.
+ *      the resulting combination should then be registered with the switch.
+ *      It is expected that things like Xen may stuff a VM title into
+ *      this field.
+ */
+struct fc_vport_identifiers {
+       u64 node_name;
+       u64 port_name;
+       u32 roles;
+       bool disable;
+       enum fc_port_type vport_type;   /* only FC_PORTTYPE_NPIV allowed */
+       char symbolic_name[FC_VPORT_SYMBOLIC_NAMELEN];
+};
+
+static int fc_vport_create(struct Scsi_Host *shost, int channel,
+       struct device *pdev, struct fc_vport_identifiers  *ids,
+       struct fc_vport **vport);
 
 /*
  * Redefine so that we can have same named attributes in the
@@ -90,10 +119,14 @@ static struct {
        { FC_PORTTYPE_NLPORT,   "NLPort (fabric via loop)" },
        { FC_PORTTYPE_LPORT,    "LPort (private loop)" },
        { FC_PORTTYPE_PTP,      "Point-To-Point (direct nport connection" },
+       { FC_PORTTYPE_NPIV,             "NPIV VPORT" },
 };
 fc_enum_name_search(port_type, fc_port_type, fc_port_type_names)
 #define FC_PORTTYPE_MAX_NAMELEN                50
 
+/* Reuse fc_port_type enum function for vport_type */
+#define get_fc_vport_type_name get_fc_port_type_name
+
 
 /* Convert fc_host_event_code values to ascii string name */
 static const struct {
@@ -139,6 +172,29 @@ fc_enum_name_search(port_state, fc_port_state, fc_port_state_names)
 #define FC_PORTSTATE_MAX_NAMELEN       20
 
 
+/* Convert fc_vport_state values to ascii string name */
+static struct {
+       enum fc_vport_state     value;
+       char                    *name;
+} fc_vport_state_names[] = {
+       { FC_VPORT_UNKNOWN,             "Unknown" },
+       { FC_VPORT_ACTIVE,              "Active" },
+       { FC_VPORT_DISABLED,            "Disabled" },
+       { FC_VPORT_LINKDOWN,            "Linkdown" },
+       { FC_VPORT_INITIALIZING,        "Initializing" },
+       { FC_VPORT_NO_FABRIC_SUPP,      "No Fabric Support" },
+       { FC_VPORT_NO_FABRIC_RSCS,      "No Fabric Resources" },
+       { FC_VPORT_FABRIC_LOGOUT,       "Fabric Logout" },
+       { FC_VPORT_FABRIC_REJ_WWN,      "Fabric Rejected WWN" },
+       { FC_VPORT_FAILED,              "VPort Failed" },
+};
+fc_enum_name_search(vport_state, fc_vport_state, fc_vport_state_names)
+#define FC_VPORTSTATE_MAX_NAMELEN      24
+
+/* Reuse fc_vport_state enum function for vport_last_state */
+#define get_fc_vport_last_state_name get_fc_vport_state_name
+
+
 /* Convert fc_tgtid_binding_type values to ascii string name */
 static const struct {
        enum fc_tgtid_binding_type      value;
@@ -219,16 +275,16 @@ show_fc_fc4s (char *buf, u8 *fc4_list)
 }
 
 
-/* Convert FC_RPORT_ROLE bit values to ascii string name */
+/* Convert FC_PORT_ROLE bit values to ascii string name */
 static const struct {
        u32                     value;
        char                    *name;
-} fc_remote_port_role_names[] = {
-       { FC_RPORT_ROLE_FCP_TARGET,     "FCP Target" },
-       { FC_RPORT_ROLE_FCP_INITIATOR,  "FCP Initiator" },
-       { FC_RPORT_ROLE_IP_PORT,        "IP Port" },
+} fc_port_role_names[] = {
+       { FC_PORT_ROLE_FCP_TARGET,      "FCP Target" },
+       { FC_PORT_ROLE_FCP_INITIATOR,   "FCP Initiator" },
+       { FC_PORT_ROLE_IP_PORT,         "IP Port" },
 };
-fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names)
+fc_bitfield_name_search(port_roles, fc_port_role_names)
 
 /*
  * Define roles that are specific to port_id. Values are relative to ROLE_MASK.
@@ -252,7 +308,8 @@ static void fc_scsi_scan_rport(struct work_struct *work);
  */
 #define FC_STARGET_NUM_ATTRS   3
 #define FC_RPORT_NUM_ATTRS     10
-#define FC_HOST_NUM_ATTRS      17
+#define FC_VPORT_NUM_ATTRS     9
+#define FC_HOST_NUM_ATTRS      21
 
 struct fc_internal {
        struct scsi_transport_template t;
@@ -278,6 +335,10 @@ struct fc_internal {
        struct transport_container rport_attr_cont;
        struct class_device_attribute private_rport_attrs[FC_RPORT_NUM_ATTRS];
        struct class_device_attribute *rport_attrs[FC_RPORT_NUM_ATTRS + 1];
+
+       struct transport_container vport_attr_cont;
+       struct class_device_attribute private_vport_attrs[FC_VPORT_NUM_ATTRS];
+       struct class_device_attribute *vport_attrs[FC_VPORT_NUM_ATTRS + 1];
 };
 
 #define to_fc_internal(tmpl)   container_of(tmpl, struct fc_internal, t)
@@ -318,7 +379,7 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
        struct Scsi_Host *shost = dev_to_shost(dev);
        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
 
-       /* 
+       /*
         * Set default values easily detected by the midlayer as
         * failure cases.  The scsi lldd is responsible for initializing
         * all transport attributes to valid values per host.
@@ -331,6 +392,7 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
                sizeof(fc_host->supported_fc4s));
        fc_host->supported_speeds = FC_PORTSPEED_UNKNOWN;
        fc_host->maxframe_size = -1;
+       fc_host->max_npiv_vports = 0;
        memset(fc_host->serial_number, 0,
                sizeof(fc_host->serial_number));
 
@@ -348,8 +410,11 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
 
        INIT_LIST_HEAD(&fc_host->rports);
        INIT_LIST_HEAD(&fc_host->rport_bindings);
+       INIT_LIST_HEAD(&fc_host->vports);
        fc_host->next_rport_number = 0;
        fc_host->next_target_id = 0;
+       fc_host->next_vport_number = 0;
+       fc_host->npiv_vports_inuse = 0;
 
        snprintf(fc_host->work_q_name, KOBJ_NAME_LEN, "fc_wq_%d",
                shost->host_no);
@@ -387,6 +452,16 @@ static DECLARE_TRANSPORT_CLASS(fc_rport_class,
                               NULL,
                               NULL);
 
+/*
+ * Setup and Remove actions for virtual ports are handled
+ * in the service functions below.
+ */
+static DECLARE_TRANSPORT_CLASS(fc_vport_class,
+                              "fc_vports",
+                              NULL,
+                              NULL,
+                              NULL);
+
 /*
  * Module Parameters
  */
@@ -583,6 +658,9 @@ static __init int fc_transport_init(void)
        atomic_set(&fc_event_seq, 0);
 
        error = transport_class_register(&fc_host_class);
+       if (error)
+               return error;
+       error = transport_class_register(&fc_vport_class);
        if (error)
                return error;
        error = transport_class_register(&fc_rport_class);
@@ -596,6 +674,7 @@ static void __exit fc_transport_exit(void)
        transport_class_unregister(&fc_transport_class);
        transport_class_unregister(&fc_rport_class);
        transport_class_unregister(&fc_host_class);
+       transport_class_unregister(&fc_vport_class);
 }
 
 /*
@@ -800,9 +879,9 @@ show_fc_rport_roles (struct class_device *cdev, char *buf)
                        return snprintf(buf, 30, "Unknown Fabric Entity\n");
                }
        } else {
-               if (rport->roles == FC_RPORT_ROLE_UNKNOWN)
+               if (rport->roles == FC_PORT_ROLE_UNKNOWN)
                        return snprintf(buf, 20, "unknown\n");
-               return get_fc_remote_port_roles_names(rport->roles, buf);
+               return get_fc_port_roles_names(rport->roles, buf);
        }
 }
 static FC_CLASS_DEVICE_ATTR(rport, roles, S_IRUGO,
@@ -857,7 +936,7 @@ static FC_CLASS_DEVICE_ATTR(rport, fast_io_fail_tmo, S_IRUGO | S_IWUSR,
 
 /*
  * Note: in the target show function we recognize when the remote
- *  port is in the hierarchy and do not allow the driver to get
+ *  port is in the heirarchy and do not allow the driver to get
  *  involved in sysfs functions. The driver only gets involved if
  *  it's the "old" style that doesn't use rports.
  */
@@ -911,6 +990,257 @@ fc_starget_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
 fc_starget_rd_attr(port_id, "0x%06x\n", 20);
 
 
+/*
+ * FC Virtual Port Attribute Management
+ */
+
+#define fc_vport_show_function(field, format_string, sz, cast)         \
+static ssize_t                                                         \
+show_fc_vport_##field (struct class_device *cdev, char *buf)           \
+{                                                                      \
+       struct fc_vport *vport = transport_class_to_vport(cdev);        \
+       struct Scsi_Host *shost = vport_to_shost(vport);                \
+       struct fc_internal *i = to_fc_internal(shost->transportt);      \
+       if ((i->f->get_vport_##field) &&                                \
+           !(vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)))       \
+               i->f->get_vport_##field(vport);                         \
+       return snprintf(buf, sz, format_string, cast vport->field);     \
+}
+
+#define fc_vport_store_function(field)                                 \
+static ssize_t                                                         \
+store_fc_vport_##field(struct class_device *cdev, const char *buf,     \
+                          size_t count)                                \
+{                                                                      \
+       int val;                                                        \
+       struct fc_vport *vport = transport_class_to_vport(cdev);        \
+       struct Scsi_Host *shost = vport_to_shost(vport);                \
+       struct fc_internal *i = to_fc_internal(shost->transportt);      \
+       char *cp;                                                       \
+       if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))  \
+               return -EBUSY;                                          \
+       val = simple_strtoul(buf, &cp, 0);                              \
+       if (*cp && (*cp != '\n'))                                       \
+               return -EINVAL;                                         \
+       i->f->set_vport_##field(vport, val);                            \
+       return count;                                                   \
+}
+
+#define fc_vport_store_str_function(field, slen)                       \
+static ssize_t                                                         \
+store_fc_vport_##field(struct class_device *cdev, const char *buf,     \
+                          size_t count)                                \
+{                                                                      \
+       struct fc_vport *vport = transport_class_to_vport(cdev);        \
+       struct Scsi_Host *shost = vport_to_shost(vport);                \
+       struct fc_internal *i = to_fc_internal(shost->transportt);      \
+       unsigned int cnt=count;                                         \
+                                                                       \
+       /* count may include a LF at end of string */                   \
+       if (buf[cnt-1] == '\n')                                         \
+               cnt--;                                                  \
+       if (cnt > ((slen) - 1))                                         \
+               return -EINVAL;                                         \
+       memcpy(vport->field, buf, cnt);                                 \
+       i->f->set_vport_##field(vport);                                 \
+       return count;                                                   \
+}
+
+#define fc_vport_rd_attr(field, format_string, sz)                     \
+       fc_vport_show_function(field, format_string, sz, )              \
+static FC_CLASS_DEVICE_ATTR(vport, field, S_IRUGO,                     \
+                        show_fc_vport_##field, NULL)
+
+#define fc_vport_rd_attr_cast(field, format_string, sz, cast)          \
+       fc_vport_show_function(field, format_string, sz, (cast))        \
+static FC_CLASS_DEVICE_ATTR(vport, field, S_IRUGO,                     \
+                         show_fc_vport_##field, NULL)
+
+#define fc_vport_rw_attr(field, format_string, sz)                     \
+       fc_vport_show_function(field, format_string, sz, )              \
+       fc_vport_store_function(field)                                  \
+static FC_CLASS_DEVICE_ATTR(vport, field, S_IRUGO | S_IWUSR,           \
+                       show_fc_vport_##field,                          \
+                       store_fc_vport_##field)
+
+#define fc_private_vport_show_function(field, format_string, sz, cast) \
+static ssize_t                                                         \
+show_fc_vport_##field (struct class_device *cdev, char *buf)           \
+{                                                                      \
+       struct fc_vport *vport = transport_class_to_vport(cdev);        \
+       return snprintf(buf, sz, format_string, cast vport->field);     \
+}
+
+#define fc_private_vport_store_u32_function(field)                     \
+static ssize_t                                                         \
+store_fc_vport_##field(struct class_device *cdev, const char *buf,     \
+                          size_t count)                                \
+{                                                                      \
+       u32 val;                                                        \
+       struct fc_vport *vport = transport_class_to_vport(cdev);        \
+       char *cp;                                                       \
+       if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))          \
+               return -EBUSY;                                          \
+       val = simple_strtoul(buf, &cp, 0);                              \
+       if (*cp && (*cp != '\n'))                                       \
+               return -EINVAL;                                         \
+       vport->field = val;                                             \
+       return count;                                                   \
+}
+
+
+#define fc_private_vport_rd_attr(field, format_string, sz)             \
+       fc_private_vport_show_function(field, format_string, sz, )      \
+static FC_CLASS_DEVICE_ATTR(vport, field, S_IRUGO,                     \
+                        show_fc_vport_##field, NULL)
+
+#define fc_private_vport_rd_attr_cast(field, format_string, sz, cast)  \
+       fc_private_vport_show_function(field, format_string, sz, (cast)) \
+static FC_CLASS_DEVICE_ATTR(vport, field, S_IRUGO,                     \
+                         show_fc_vport_##field, NULL)
+
+#define fc_private_vport_rw_u32_attr(field, format_string, sz)         \
+       fc_private_vport_show_function(field, format_string, sz, )      \
+       fc_private_vport_store_u32_function(field)                      \
+static FC_CLASS_DEVICE_ATTR(vport, field, S_IRUGO | S_IWUSR,           \
+                       show_fc_vport_##field,                          \
+                       store_fc_vport_##field)
+
+
+#define fc_private_vport_rd_enum_attr(title, maxlen)                   \
+static ssize_t                                                         \
+show_fc_vport_##title (struct class_device *cdev, char *buf)           \
+{                                                                      \
+       struct fc_vport *vport = transport_class_to_vport(cdev);        \
+       const char *name;                                               \
+       name = get_fc_##title##_name(vport->title);                     \
+       if (!name)                                                      \
+               return -EINVAL;                                         \
+       return snprintf(buf, maxlen, "%s\n", name);                     \
+}                                                                      \
+static FC_CLASS_DEVICE_ATTR(vport, title, S_IRUGO,                     \
+                       show_fc_vport_##title, NULL)
+
+
+#define SETUP_VPORT_ATTRIBUTE_RD(field)                                        \
+       i->private_vport_attrs[count] = class_device_attr_vport_##field; \
+       i->private_vport_attrs[count].attr.mode = S_IRUGO;              \
+       i->private_vport_attrs[count].store = NULL;                     \
+       i->vport_attrs[count] = &i->private_vport_attrs[count];         \
+       if (i->f->get_##field)                                          \
+               count++
+       /* NOTE: Above MACRO differs: checks function not show bit */
+
+#define SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(field)                                \
+       i->private_vport_attrs[count] = class_device_attr_vport_##field; \
+       i->private_vport_attrs[count].attr.mode = S_IRUGO;              \
+       i->private_vport_attrs[count].store = NULL;                     \
+       i->vport_attrs[count] = &i->private_vport_attrs[count];         \
+       count++
+
+#define SETUP_VPORT_ATTRIBUTE_WR(field)                                        \
+       i->private_vport_attrs[count] = class_device_attr_vport_##field; \
+       i->vport_attrs[count] = &i->private_vport_attrs[count];         \
+       if (i->f->field)                                                \
+               count++
+       /* NOTE: Above MACRO differs: checks function */
+
+#define SETUP_VPORT_ATTRIBUTE_RW(field)                                        \
+       i->private_vport_attrs[count] = class_device_attr_vport_##field; \
+       if (!i->f->set_vport_##field) {                                 \
+               i->private_vport_attrs[count].attr.mode = S_IRUGO;      \
+               i->private_vport_attrs[count].store = NULL;             \
+       }                                                               \
+       i->vport_attrs[count] = &i->private_vport_attrs[count];         \
+       count++
+       /* NOTE: Above MACRO differs: does not check show bit */
+
+#define SETUP_PRIVATE_VPORT_ATTRIBUTE_RW(field)                                \
+{                                                                      \
+       i->private_vport_attrs[count] = class_device_attr_vport_##field; \
+       i->vport_attrs[count] = &i->private_vport_attrs[count];         \
+       count++;                                                        \
+}
+
+
+/* The FC Transport Virtual Port Attributes: */
+
+/* Fixed Virtual Port Attributes */
+
+/* Dynamic Virtual Port Attributes */
+
+/* Private Virtual Port Attributes */
+
+fc_private_vport_rd_enum_attr(vport_state, FC_VPORTSTATE_MAX_NAMELEN);
+fc_private_vport_rd_enum_attr(vport_last_state, FC_VPORTSTATE_MAX_NAMELEN);
+fc_private_vport_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
+fc_private_vport_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
+
+static ssize_t
+show_fc_vport_roles (struct class_device *cdev, char *buf)
+{
+       struct fc_vport *vport = transport_class_to_vport(cdev);
+
+       if (vport->roles == FC_PORT_ROLE_UNKNOWN)
+               return snprintf(buf, 20, "unknown\n");
+       return get_fc_port_roles_names(vport->roles, buf);
+}
+static FC_CLASS_DEVICE_ATTR(vport, roles, S_IRUGO, show_fc_vport_roles, NULL);
+
+fc_private_vport_rd_enum_attr(vport_type, FC_PORTTYPE_MAX_NAMELEN);
+
+fc_private_vport_show_function(symbolic_name, "%s\n",
+               FC_VPORT_SYMBOLIC_NAMELEN + 1, )
+fc_vport_store_str_function(symbolic_name, FC_VPORT_SYMBOLIC_NAMELEN)
+static FC_CLASS_DEVICE_ATTR(vport, symbolic_name, S_IRUGO | S_IWUSR,
+               show_fc_vport_symbolic_name, store_fc_vport_symbolic_name);
+
+static ssize_t
+store_fc_vport_delete(struct class_device *cdev, const char *buf,
+                          size_t count)
+{
+       struct fc_vport *vport = transport_class_to_vport(cdev);
+       struct Scsi_Host *shost = vport_to_shost(vport);
+
+       fc_queue_work(shost, &vport->vport_delete_work);
+       return count;
+}
+static FC_CLASS_DEVICE_ATTR(vport, vport_delete, S_IWUSR,
+                       NULL, store_fc_vport_delete);
+
+
+/*
+ * Enable/Disable vport
+ *  Write "1" to disable, write "0" to enable
+ */
+static ssize_t
+store_fc_vport_disable(struct class_device *cdev, const char *buf,
+                          size_t count)
+{
+       struct fc_vport *vport = transport_class_to_vport(cdev);
+       struct Scsi_Host *shost = vport_to_shost(vport);
+       struct fc_internal *i = to_fc_internal(shost->transportt);
+       int stat;
+
+       if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))
+               return -EBUSY;
+
+       if (*buf == '0') {
+               if (vport->vport_state != FC_VPORT_DISABLED)
+                       return -EALREADY;
+       } else if (*buf == '1') {
+               if (vport->vport_state == FC_VPORT_DISABLED)
+                       return -EALREADY;
+       } else
+               return -EINVAL;
+
+       stat = i->f->vport_disable(vport, ((*buf == '0') ? false : true));
+       return stat ? stat : count;
+}
+static FC_CLASS_DEVICE_ATTR(vport, vport_disable, S_IWUSR,
+                       NULL, store_fc_vport_disable);
+
+
 /*
  * Host Attribute Management
  */
@@ -1003,6 +1333,13 @@ static FC_CLASS_DEVICE_ATTR(host, title, S_IRUGO, show_fc_host_##title, NULL)
        if (i->f->show_host_##field)                                    \
                count++
 
+#define SETUP_HOST_ATTRIBUTE_RD_NS(field)                              \
+       i->private_host_attrs[count] = class_device_attr_host_##field;  \
+       i->private_host_attrs[count].attr.mode = S_IRUGO;               \
+       i->private_host_attrs[count].store = NULL;                      \
+       i->host_attrs[count] = &i->private_host_attrs[count];           \
+       count++
+
 #define SETUP_HOST_ATTRIBUTE_RW(field)                                 \
        i->private_host_attrs[count] = class_device_attr_host_##field;  \
        if (!i->f->set_host_##field) {                                  \
@@ -1090,6 +1427,7 @@ fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
 fc_private_host_rd_attr_cast(permanent_port_name, "0x%llx\n", 20,
                             unsigned long long);
 fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20);
+fc_private_host_rd_attr(max_npiv_vports, "%u\n", 20);
 fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1));
 
 
@@ -1210,6 +1548,9 @@ store_fc_private_host_issue_lip(struct class_device *cdev,
 static FC_CLASS_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL,
                        store_fc_private_host_issue_lip);
 
+fc_private_host_rd_attr(npiv_vports_inuse, "%u\n", 20);
+
+
 /*
  * Host Statistics Management
  */
@@ -1285,7 +1626,6 @@ fc_reset_statistics(struct class_device *cdev, const char *buf,
 static FC_CLASS_DEVICE_ATTR(host, reset_statistics, S_IWUSR, NULL,
                                fc_reset_statistics);
 
-
 static struct attribute *fc_statistics_attrs[] = {
        &class_device_attr_host_seconds_since_last_reset.attr,
        &class_device_attr_host_tx_frames.attr,
@@ -1316,6 +1656,142 @@ static struct attribute_group fc_statistics_group = {
        .attrs = fc_statistics_attrs,
 };
 
+
+/* Host Vport Attributes */
+
+static int
+fc_parse_wwn(const char *ns, u64 *nm)
+{
+       unsigned int i, j;
+       u8 wwn[8];
+
+       memset(wwn, 0, sizeof(wwn));
+
+       /* Validate and store the new name */
+       for (i=0, j=0; i < 16; i++) {
+               if ((*ns >= 'a') && (*ns <= 'f'))
+                       j = ((j << 4) | ((*ns++ -'a') + 10));
+               else if ((*ns >= 'A') && (*ns <= 'F'))
+                       j = ((j << 4) | ((*ns++ -'A') + 10));
+               else if ((*ns >= '0') && (*ns <= '9'))
+                       j = ((j << 4) | (*ns++ -'0'));
+               else
+                       return -EINVAL;
+               if (i % 2) {
+                       wwn[i/2] = j & 0xff;
+                       j = 0;
+               }
+       }
+
+       *nm = wwn_to_u64(wwn);
+
+       return 0;
+}
+
+
+/*
+ * "Short-cut" sysfs variable to create a new vport on a FC Host.
+ * Input is a string of the form "<WWPN>:<WWNN>". Other attributes
+ * will default to a NPIV-based FCP_Initiator; The WWNs are specified
+ * as hex characters, and may *not* contain any prefixes (e.g. 0x, x, etc)
+ */
+static ssize_t
+store_fc_host_vport_create(struct class_device *cdev, const char *buf,
+                          size_t count)
+{
+       struct Scsi_Host *shost = transport_class_to_shost(cdev);
+       struct fc_vport_identifiers vid;
+       struct fc_vport *vport;
+       unsigned int cnt=count;
+       int stat;
+
+       memset(&vid, 0, sizeof(vid));
+
+       /* count may include a LF at end of string */
+       if (buf[cnt-1] == '\n')
+               cnt--;
+
+       /* validate we have enough characters for WWPN */
+       if ((cnt != (16+1+16)) || (buf[16] != ':'))
+               return -EINVAL;
+
+       stat = fc_parse_wwn(&buf[0], &vid.port_name);
+       if (stat)
+               return stat;
+
+       stat = fc_parse_wwn(&buf[17], &vid.node_name);
+       if (stat)
+               return stat;
+
+       vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
+       vid.vport_type = FC_PORTTYPE_NPIV;
+       /* vid.symbolic_name is already zero/NULL's */
+       vid.disable = false;            /* always enabled */
+
+       /* we only allow support on Channel 0 !!! */
+       stat = fc_vport_create(shost, 0, &shost->shost_gendev, &vid, &vport);
+       return stat ? stat : count;
+}
+static FC_CLASS_DEVICE_ATTR(host, vport_create, S_IWUSR, NULL,
+                       store_fc_host_vport_create);
+
+
+/*
+ * "Short-cut" sysfs variable to delete a vport on a FC Host.
+ * Vport is identified by a string containing "<WWPN>:<WWNN>".
+ * The WWNs are specified as hex characters, and may *not* contain
+ * any prefixes (e.g. 0x, x, etc)
+ */
+static ssize_t
+store_fc_host_vport_delete(struct class_device *cdev, const char *buf,
+                          size_t count)
+{
+       struct Scsi_Host *shost = transport_class_to_shost(cdev);
+       struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
+       struct fc_vport *vport;
+       u64 wwpn, wwnn;
+       unsigned long flags;
+       unsigned int cnt=count;
+       int stat, match;
+
+       /* count may include a LF at end of string */
+       if (buf[cnt-1] == '\n')
+               cnt--;
+
+       /* validate we have enough characters for WWPN */
+       if ((cnt != (16+1+16)) || (buf[16] != ':'))
+               return -EINVAL;
+
+       stat = fc_parse_wwn(&buf[0], &wwpn);
+       if (stat)
+               return stat;
+
+       stat = fc_parse_wwn(&buf[17], &wwnn);
+       if (stat)
+               return stat;
+
+       spin_lock_irqsave(shost->host_lock, flags);
+       match = 0;
+       /* we only allow support on Channel 0 !!! */
+       list_for_each_entry(vport, &fc_host->vports, peers) {
+               if ((vport->channel == 0) &&
+                   (vport->port_name == wwpn) && (vport->node_name == wwnn)) {
+                       match = 1;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(shost->host_lock, flags);
+
+       if (!match)
+               return -ENODEV;
+
+       stat = fc_vport_terminate(vport);
+       return stat ? stat : count;
+}
+static FC_CLASS_DEVICE_ATTR(host, vport_delete, S_IWUSR, NULL,
+                       store_fc_host_vport_delete);
+
+
 static int fc_host_match(struct attribute_container *cont,
                          struct device *dev)
 {
@@ -1387,6 +1863,40 @@ static int fc_rport_match(struct attribute_container *cont,
 }
 
 
+static void fc_vport_dev_release(struct device *dev)
+{
+       struct fc_vport *vport = dev_to_vport(dev);
+       put_device(dev->parent);                /* release kobj parent */
+       kfree(vport);
+}
+
+int scsi_is_fc_vport(const struct device *dev)
+{
+       return dev->release == fc_vport_dev_release;
+}
+EXPORT_SYMBOL(scsi_is_fc_vport);
+
+static int fc_vport_match(struct attribute_container *cont,
+                           struct device *dev)
+{
+       struct fc_vport *vport;
+       struct Scsi_Host *shost;
+       struct fc_internal *i;
+
+       if (!scsi_is_fc_vport(dev))
+               return 0;
+       vport = dev_to_vport(dev);
+
+       shost = vport_to_shost(vport);
+       if (!shost->transportt  || shost->transportt->host_attrs.ac.class
+           != &fc_host_class.class)
+               return 0;
+
+       i = to_fc_internal(shost->transportt);
+       return &i->vport_attr_cont.ac == cont;
+}
+
+
 /**
  * fc_timed_out - FC Transport I/O timeout intercept handler
  *
@@ -1472,6 +1982,11 @@ fc_attach_transport(struct fc_function_template *ft)
        i->rport_attr_cont.ac.match = fc_rport_match;
        transport_container_register(&i->rport_attr_cont);
 
+       i->vport_attr_cont.ac.attrs = &i->vport_attrs[0];
+       i->vport_attr_cont.ac.class = &fc_vport_class.class;
+       i->vport_attr_cont.ac.match = fc_vport_match;
+       transport_container_register(&i->vport_attr_cont);
+
        i->f = ft;
 
        /* Transport uses the shost workq for scsi scanning */
@@ -1480,7 +1995,7 @@ fc_attach_transport(struct fc_function_template *ft)
        i->t.eh_timed_out = fc_timed_out;
 
        i->t.user_scan = fc_user_scan;
-       
+
        /*
         * Setup SCSI Target Attributes.
         */
@@ -1505,6 +2020,10 @@ fc_attach_transport(struct fc_function_template *ft)
        SETUP_HOST_ATTRIBUTE_RD(supported_fc4s);
        SETUP_HOST_ATTRIBUTE_RD(supported_speeds);
        SETUP_HOST_ATTRIBUTE_RD(maxframe_size);
+       if (ft->vport_create) {
+               SETUP_HOST_ATTRIBUTE_RD_NS(max_npiv_vports);
+               SETUP_HOST_ATTRIBUTE_RD_NS(npiv_vports_inuse);
+       }
        SETUP_HOST_ATTRIBUTE_RD(serial_number);
 
        SETUP_HOST_ATTRIBUTE_RD(port_id);
@@ -1520,6 +2039,10 @@ fc_attach_transport(struct fc_function_template *ft)
        SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
        if (ft->issue_fc_host_lip)
                SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
+       if (ft->vport_create)
+               SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_create);
+       if (ft->vport_delete)
+               SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_delete);
 
        BUG_ON(count > FC_HOST_NUM_ATTRS);
 
@@ -1545,6 +2068,24 @@ fc_attach_transport(struct fc_function_template *ft)
 
        i->rport_attrs[count] = NULL;
 
+       /*
+        * Setup Virtual Port Attributes.
+        */
+       count=0;
+       SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_state);
+       SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_last_state);
+       SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(node_name);
+       SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(port_name);
+       SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(roles);
+       SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_type);
+       SETUP_VPORT_ATTRIBUTE_RW(symbolic_name);
+       SETUP_VPORT_ATTRIBUTE_WR(vport_delete);
+       SETUP_VPORT_ATTRIBUTE_WR(vport_disable);
+
+       BUG_ON(count > FC_VPORT_NUM_ATTRS);
+
+       i->vport_attrs[count] = NULL;
+
        return &i->t;
 }
 EXPORT_SYMBOL(fc_attach_transport);
@@ -1556,6 +2097,7 @@ void fc_release_transport(struct scsi_transport_template *t)
        transport_container_unregister(&i->t.target_attrs);
        transport_container_unregister(&i->t.host_attrs);
        transport_container_unregister(&i->rport_attr_cont);
+       transport_container_unregister(&i->vport_attr_cont);
 
        kfree(i);
 }
@@ -1667,9 +2209,17 @@ fc_flush_devloss(struct Scsi_Host *shost)
 void
 fc_remove_host(struct Scsi_Host *shost)
 {
-       struct fc_rport *rport, *next_rport;
+       struct fc_vport *vport = NULL, *next_vport = NULL;
+       struct fc_rport *rport = NULL, *next_rport = NULL;
        struct workqueue_struct *work_q;
        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
+       unsigned long flags;
+
+       spin_lock_irqsave(shost->host_lock, flags);
+
+       /* Remove any vports */
+       list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers)
+               fc_queue_work(shost, &vport->vport_delete_work);
 
        /* Remove any remote ports */
        list_for_each_entry_safe(rport, next_rport,
@@ -1686,6 +2236,8 @@ fc_remove_host(struct Scsi_Host *shost)
                fc_queue_work(shost, &rport->rport_delete_work);
        }
 
+       spin_unlock_irqrestore(shost->host_lock, flags);
+
        /* flush all scan work items */
        scsi_flush_work(shost);
 
@@ -1744,7 +2296,7 @@ fc_rport_final_delete(struct work_struct *work)
        unsigned long flags;
 
        /*
-        * if a scan is pending, flush the SCSI Host work_q so that 
+        * if a scan is pending, flush the SCSI Host work_q so that
         * that we can reclaim the rport scan work element.
         */
        if (rport->flags & FC_RPORT_SCAN_PENDING)
@@ -1844,7 +2396,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
        spin_lock_irqsave(shost->host_lock, flags);
 
        rport->number = fc_host->next_rport_number++;
-       if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
+       if (rport->roles & FC_PORT_ROLE_FCP_TARGET)
                rport->scsi_target_id = fc_host->next_target_id++;
        else
                rport->scsi_target_id = -1;
@@ -1869,7 +2421,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
        transport_add_device(dev);
        transport_configure_device(dev);
 
-       if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) {
+       if (rport->roles & FC_PORT_ROLE_FCP_TARGET) {
                /* initiate a scan of the target */
                rport->flags |= FC_RPORT_SCAN_PENDING;
                scsi_queue_work(shost, &rport->scan_work);
@@ -2003,7 +2555,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
 
                                /* was a target, not in roles */
                                if ((rport->scsi_target_id != -1) &&
-                                   (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET)))
+                                   (!(ids->roles & FC_PORT_ROLE_FCP_TARGET)))
                                        return rport;
 
                                /*
@@ -2086,7 +2638,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
                                memset(rport->dd_data, 0,
                                                fci->f->dd_fcrport_size);
 
-                       if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) {
+                       if (rport->roles & FC_PORT_ROLE_FCP_TARGET) {
                                /* initiate a scan of the target */
                                rport->flags |= FC_RPORT_SCAN_PENDING;
                                scsi_queue_work(shost, &rport->scan_work);
@@ -2243,11 +2795,11 @@ fc_remote_port_rolechg(struct fc_rport  *rport, u32 roles)
        int create = 0;
 
        spin_lock_irqsave(shost->host_lock, flags);
-       if (roles & FC_RPORT_ROLE_FCP_TARGET) {
+       if (roles & FC_PORT_ROLE_FCP_TARGET) {
                if (rport->scsi_target_id == -1) {
                        rport->scsi_target_id = fc_host->next_target_id++;
                        create = 1;
-               } else if (!(rport->roles & FC_RPORT_ROLE_FCP_TARGET))
+               } else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET))
                        create = 1;
        }
 
@@ -2294,7 +2846,7 @@ EXPORT_SYMBOL(fc_remote_port_rolechg);
  * fc_timeout_deleted_rport - Timeout handler for a deleted remote port,
  *                     which we blocked, and has now failed to return
  *                     in the allotted time.
- * 
+ *
  * @work:      rport target that failed to reappear in the allotted time.
  **/
 static void
@@ -2317,7 +2869,7 @@ fc_timeout_deleted_rport(struct work_struct *work)
         */
        if ((rport->port_state == FC_PORTSTATE_ONLINE) &&
            (rport->scsi_target_id != -1) &&
-           !(rport->roles & FC_RPORT_ROLE_FCP_TARGET)) {
+           !(rport->roles & FC_PORT_ROLE_FCP_TARGET)) {
                dev_printk(KERN_ERR, &rport->dev,
                        "blocked FC remote port time out: no longer"
                        " a FCP target, removing starget\n");
@@ -2367,7 +2919,7 @@ fc_timeout_deleted_rport(struct work_struct *work)
         */
        rport->maxframe_size = -1;
        rport->supported_classes = FC_COS_UNSPECIFIED;
-       rport->roles = FC_RPORT_ROLE_UNKNOWN;
+       rport->roles = FC_PORT_ROLE_UNKNOWN;
        rport->port_state = FC_PORTSTATE_NOTPRESENT;
 
        /* remove the identifiers that aren't used in the consisting binding */
@@ -2436,7 +2988,7 @@ fc_scsi_scan_rport(struct work_struct *work)
        unsigned long flags;
 
        if ((rport->port_state == FC_PORTSTATE_ONLINE) &&
-           (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) {
+           (rport->roles & FC_PORT_ROLE_FCP_TARGET)) {
                scsi_scan_target(&rport->dev, rport->channel,
                        rport->scsi_target_id, SCAN_WILD_CARD, 1);
        }
@@ -2447,7 +2999,227 @@ fc_scsi_scan_rport(struct work_struct *work)
 }
 
 
-MODULE_AUTHOR("Martin Hicks");
+/**
+ * fc_vport_create - allocates and creates a FC virtual port.
+ * @shost:     scsi host the virtual port is connected to.
+ * @channel:   Channel on shost port connected to.
+ * @pdev:      parent device for vport
+ * @ids:       The world wide names, FC4 port roles, etc for
+ *              the virtual port.
+ * @ret_vport: The pointer to the created vport.
+ *
+ * Allocates and creates the vport structure, calls the parent host
+ * to instantiate the vport, the completes w/ class and sysfs creation.
+ *
+ * Notes:
+ *     This routine assumes no locks are held on entry.
+ **/
+static int
+fc_vport_create(struct Scsi_Host *shost, int channel, struct device *pdev,
+       struct fc_vport_identifiers  *ids, struct fc_vport **ret_vport)
+{
+       struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
+       struct fc_internal *fci = to_fc_internal(shost->transportt);
+       struct fc_vport *vport;
+       struct device *dev;
+       unsigned long flags;
+       size_t size;
+       int error;
+
+       *ret_vport = NULL;
+
+       if ( ! fci->f->vport_create)
+               return -ENOENT;
+
+       size = (sizeof(struct fc_vport) + fci->f->dd_fcvport_size);
+       vport = kzalloc(size, GFP_KERNEL);
+       if (unlikely(!vport)) {
+               printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);
+               return -ENOMEM;
+       }
+
+       vport->vport_state = FC_VPORT_UNKNOWN;
+       vport->vport_last_state = FC_VPORT_UNKNOWN;
+       vport->node_name = ids->node_name;
+       vport->port_name = ids->port_name;
+       vport->roles = ids->roles;
+       vport->vport_type = ids->vport_type;
+       if (fci->f->dd_fcvport_size)
+               vport->dd_data = &vport[1];
+       vport->shost = shost;
+       vport->channel = channel;
+       vport->flags = FC_VPORT_CREATING;
+       INIT_WORK(&vport->vport_delete_work, fc_vport_sched_delete);
+
+       spin_lock_irqsave(shost->host_lock, flags);
+
+       if (fc_host->npiv_vports_inuse >= fc_host->max_npiv_vports) {
+               spin_unlock_irqrestore(shost->host_lock, flags);
+               kfree(vport);
+               return -ENOSPC;
+       }
+       fc_host->npiv_vports_inuse++;
+       vport->number = fc_host->next_vport_number++;
+       list_add_tail(&vport->peers, &fc_host->vports);
+       get_device(&shost->shost_gendev);       /* for fc_host->vport list */
+
+       spin_unlock_irqrestore(shost->host_lock, flags);
+
+       dev = &vport->dev;
+       device_initialize(dev);                 /* takes self reference */
+       dev->parent = get_device(pdev);         /* takes parent reference */
+       dev->release = fc_vport_dev_release;
+       sprintf(dev->bus_id, "vport-%d:%d-%d",
+               shost->host_no, channel, vport->number);
+       transport_setup_device(dev);
+
+       error = device_add(dev);
+       if (error) {
+               printk(KERN_ERR "FC Virtual Port device_add failed\n");
+               goto delete_vport;
+       }
+       transport_add_device(dev);
+       transport_configure_device(dev);
+
+       error = fci->f->vport_create(vport, ids->disable);
+       if (error) {
+               printk(KERN_ERR "FC Virtual Port LLDD Create failed\n");
+               goto delete_vport_all;
+       }
+
+       /*
+        * if the parent isn't the physical adapter's Scsi_Host, ensure
+        * the Scsi_Host at least contains ia symlink to the vport.
+        */
+       if (pdev != &shost->shost_gendev) {
+               error = sysfs_create_link(&shost->shost_gendev.kobj,
+                                &dev->kobj, dev->bus_id);
+               if (error)
+                       printk(KERN_ERR
+                               "%s: Cannot create vport symlinks for "
+                               "%s, err=%d\n",
+                               __FUNCTION__, dev->bus_id, error);
+       }
+       spin_lock_irqsave(shost->host_lock, flags);
+       vport->flags &= ~FC_VPORT_CREATING;
+       spin_unlock_irqrestore(shost->host_lock, flags);
+
+       dev_printk(KERN_NOTICE, pdev,
+                       "%s created via shost%d channel %d\n", dev->bus_id,
+                       shost->host_no, channel);
+
+       *ret_vport = vport;
+
+       return 0;
+
+delete_vport_all:
+       transport_remove_device(dev);
+       device_del(dev);
+delete_vport:
+       transport_destroy_device(dev);
+       spin_lock_irqsave(shost->host_lock, flags);
+       list_del(&vport->peers);
+       put_device(&shost->shost_gendev);       /* for fc_host->vport list */
+       fc_host->npiv_vports_inuse--;
+       spin_unlock_irqrestore(shost->host_lock, flags);
+       put_device(dev->parent);
+       kfree(vport);
+
+       return error;
+}
+
+
+/**
+ * fc_vport_terminate - Admin App or LLDD requests termination of a vport
+ * @vport:     fc_vport to be terminated
+ *
+ * Calls the LLDD vport_delete() function, then deallocates and removes
+ * the vport from the shost and object tree.
+ *
+ * Notes:
+ *     This routine assumes no locks are held on entry.
+ **/
+int
+fc_vport_terminate(struct fc_vport *vport)
+{
+       struct Scsi_Host *shost = vport_to_shost(vport);
+       struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
+       struct fc_internal *i = to_fc_internal(shost->transportt);
+       struct device *dev = &vport->dev;
+       unsigned long flags;
+       int stat;
+
+       spin_lock_irqsave(shost->host_lock, flags);
+       if (vport->flags & FC_VPORT_CREATING) {
+               spin_unlock_irqrestore(shost->host_lock, flags);
+               return -EBUSY;
+       }
+       if (vport->flags & (FC_VPORT_DEL)) {
+               spin_unlock_irqrestore(shost->host_lock, flags);
+               return -EALREADY;
+       }
+       vport->flags |= FC_VPORT_DELETING;
+       spin_unlock_irqrestore(shost->host_lock, flags);
+
+       if (i->f->vport_delete)
+               stat = i->f->vport_delete(vport);
+       else
+               stat = -ENOENT;
+
+       spin_lock_irqsave(shost->host_lock, flags);
+       vport->flags &= ~FC_VPORT_DELETING;
+       if (!stat) {
+               vport->flags |= FC_VPORT_DELETED;
+               list_del(&vport->peers);
+               fc_host->npiv_vports_inuse--;
+               put_device(&shost->shost_gendev);  /* for fc_host->vport list */
+       }
+       spin_unlock_irqrestore(shost->host_lock, flags);
+
+       if (stat)
+               return stat;
+
+       if (dev->parent != &shost->shost_gendev)
+               sysfs_remove_link(&shost->shost_gendev.kobj, dev->bus_id);
+       transport_remove_device(dev);
+       device_del(dev);
+       transport_destroy_device(dev);
+
+       /*
+        * Removing our self-reference should mean our
+        * release function gets called, which will drop the remaining
+        * parent reference and free the data structure.
+        */
+       put_device(dev);                        /* for self-reference */
+
+       return 0; /* SUCCESS */
+}
+EXPORT_SYMBOL(fc_vport_terminate);
+
+/**
+ * fc_vport_sched_delete - workq-based delete request for a vport
+ *
+ * @work:      vport to be deleted.
+ **/
+static void
+fc_vport_sched_delete(struct work_struct *work)
+{
+       struct fc_vport *vport =
+               container_of(work, struct fc_vport, vport_delete_work);
+       int stat;
+
+       stat = fc_vport_terminate(vport);
+       if (stat)
+               dev_printk(KERN_ERR, vport->dev.parent,
+                       "%s: %s could not be deleted created via "
+                       "shost%d channel %d - error %d\n", __FUNCTION__,
+                       vport->dev.bus_id, vport->shost->host_no,
+                       vport->channel, stat);
+}
+
+
+/* Original Author:  Martin Hicks */
+MODULE_AUTHOR("James Smart");
 MODULE_DESCRIPTION("FC Transport Attributes");
 MODULE_LICENSE("GPL");
 
index 3d8c9cb..448d316 100644 (file)
@@ -1515,7 +1515,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
        if (!scsi_device_online(sdp))
                goto out;
 
-       buffer = kmalloc(SD_BUF_SIZE, GFP_KERNEL | __GFP_DMA);
+       buffer = kmalloc(SD_BUF_SIZE, GFP_KERNEL);
        if (!buffer) {
                sd_printk(KERN_WARNING, sdkp, "sd_revalidate_disk: Memory "
                          "allocation failure.\n");
index 0c691a6..85d3894 100644 (file)
@@ -1842,7 +1842,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
        int blk_size = buff_size;
        struct page *p = NULL;
 
-       if ((blk_size < 0) || (!sfp))
+       if (blk_size < 0)
                return -EFAULT;
        if (0 == blk_size)
                ++blk_size;     /* don't know why */
index 9ac83ab..adda296 100644 (file)
@@ -395,53 +395,34 @@ static struct req_msg *stex_alloc_req(struct st_hba *hba)
 static int stex_map_sg(struct st_hba *hba,
        struct req_msg *req, struct st_ccb *ccb)
 {
-       struct pci_dev *pdev = hba->pdev;
        struct scsi_cmnd *cmd;
-       dma_addr_t dma_handle;
-       struct scatterlist *src;
+       struct scatterlist *sg;
        struct st_sgtable *dst;
-       int i;
+       int i, nseg;
 
        cmd = ccb->cmd;
        dst = (struct st_sgtable *)req->variable;
        dst->max_sg_count = cpu_to_le16(ST_MAX_SG);
-       dst->sz_in_byte = cpu_to_le32(cmd->request_bufflen);
-
-       if (cmd->use_sg) {
-               int n_elem;
+       dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd));
 
-               src = (struct scatterlist *) cmd->request_buffer;
-               n_elem = pci_map_sg(pdev, src,
-                       cmd->use_sg, cmd->sc_data_direction);
-               if (n_elem <= 0)
-                       return -EIO;
+       nseg = scsi_dma_map(cmd);
+       if (nseg < 0)
+               return -EIO;
+       if (nseg) {
+               ccb->sg_count = nseg;
+               dst->sg_count = cpu_to_le16((u16)nseg);
 
-               ccb->sg_count = n_elem;
-               dst->sg_count = cpu_to_le16((u16)n_elem);
-
-               for (i = 0; i < n_elem; i++, src++) {
-                       dst->table[i].count = cpu_to_le32((u32)sg_dma_len(src));
+               scsi_for_each_sg(cmd, sg, nseg, i) {
+                       dst->table[i].count = cpu_to_le32((u32)sg_dma_len(sg));
                        dst->table[i].addr =
-                               cpu_to_le32(sg_dma_address(src) & 0xffffffff);
+                               cpu_to_le32(sg_dma_address(sg) & 0xffffffff);
                        dst->table[i].addr_hi =
-                               cpu_to_le32((sg_dma_address(src) >> 16) >> 16);
+                               cpu_to_le32((sg_dma_address(sg) >> 16) >> 16);
                        dst->table[i].ctrl = SG_CF_64B | SG_CF_HOST;
                }
                dst->table[--i].ctrl |= SG_CF_EOT;
-               return 0;
        }
 
-       dma_handle = pci_map_single(pdev, cmd->request_buffer,
-               cmd->request_bufflen, cmd->sc_data_direction);
-       cmd->SCp.dma_handle = dma_handle;
-
-       ccb->sg_count = 1;
-       dst->sg_count = cpu_to_le16(1);
-       dst->table[0].addr = cpu_to_le32(dma_handle & 0xffffffff);
-       dst->table[0].addr_hi = cpu_to_le32((dma_handle >> 16) >> 16);
-       dst->table[0].count = cpu_to_le32((u32)cmd->request_bufflen);
-       dst->table[0].ctrl = SG_CF_EOT | SG_CF_64B | SG_CF_HOST;
-
        return 0;
 }
 
@@ -451,24 +432,24 @@ static void stex_internal_copy(struct scsi_cmnd *cmd,
        size_t lcount;
        size_t len;
        void *s, *d, *base = NULL;
-       if (*count > cmd->request_bufflen)
-               *count = cmd->request_bufflen;
+       size_t offset;
+
+       if (*count > scsi_bufflen(cmd))
+               *count = scsi_bufflen(cmd);
        lcount = *count;
        while (lcount) {
                len = lcount;
                s = (void *)src;
-               if (cmd->use_sg) {
-                       size_t offset = *count - lcount;
-                       s += offset;
-                       base = scsi_kmap_atomic_sg(cmd->request_buffer,
-                               sg_count, &offset, &len);
-                       if (base == NULL) {
-                               *count -= lcount;
-                               return;
-                       }
-                       d = base + offset;
-               } else
-                       d = cmd->request_buffer;
+
+               offset = *count - lcount;
+               s += offset;
+               base = scsi_kmap_atomic_sg(scsi_sglist(cmd),
+                                          sg_count, &offset, &len);
+               if (!base) {
+                       *count -= lcount;
+                       return;
+               }
+               d = base + offset;
 
                if (direction == ST_TO_CMD)
                        memcpy(d, s, len);
@@ -476,30 +457,24 @@ static void stex_internal_copy(struct scsi_cmnd *cmd,
                        memcpy(s, d, len);
 
                lcount -= len;
-               if (cmd->use_sg)
-                       scsi_kunmap_atomic_sg(base);
+               scsi_kunmap_atomic_sg(base);
        }
 }
 
 static int stex_direct_copy(struct scsi_cmnd *cmd,
        const void *src, size_t count)
 {
-       struct st_hba *hba = (struct st_hba *) &cmd->device->host->hostdata[0];
        size_t cp_len = count;
        int n_elem = 0;
 
-       if (cmd->use_sg) {
-               n_elem = pci_map_sg(hba->pdev, cmd->request_buffer,
-                       cmd->use_sg, cmd->sc_data_direction);
-               if (n_elem <= 0)
-                       return 0;
-       }
+       n_elem = scsi_dma_map(cmd);
+       if (n_elem < 0)
+               return 0;
 
        stex_internal_copy(cmd, src, &cp_len, n_elem, ST_TO_CMD);
 
-       if (cmd->use_sg)
-               pci_unmap_sg(hba->pdev, cmd->request_buffer,
-                       cmd->use_sg, cmd->sc_data_direction);
+       scsi_dma_unmap(cmd);
+
        return cp_len == count;
 }
 
@@ -678,18 +653,6 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
        return 0;
 }
 
-static void stex_unmap_sg(struct st_hba *hba, struct scsi_cmnd *cmd)
-{
-       if (cmd->sc_data_direction != DMA_NONE) {
-               if (cmd->use_sg)
-                       pci_unmap_sg(hba->pdev, cmd->request_buffer,
-                               cmd->use_sg, cmd->sc_data_direction);
-               else
-                       pci_unmap_single(hba->pdev, cmd->SCp.dma_handle,
-                               cmd->request_bufflen, cmd->sc_data_direction);
-       }
-}
-
 static void stex_scsi_done(struct st_ccb *ccb)
 {
        struct scsi_cmnd *cmd = ccb->cmd;
@@ -756,7 +719,7 @@ static void stex_ys_commands(struct st_hba *hba,
 
        if (ccb->cmd->cmnd[0] == MGT_CMD &&
                resp->scsi_status != SAM_STAT_CHECK_CONDITION) {
-               ccb->cmd->request_bufflen =
+               scsi_bufflen(ccb->cmd) =
                        le32_to_cpu(*(__le32 *)&resp->variable[0]);
                return;
        }
@@ -855,7 +818,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
                                ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER))
                                stex_controller_info(hba, ccb);
 
-                       stex_unmap_sg(hba, ccb->cmd);
+                       scsi_dma_unmap(ccb->cmd);
                        stex_scsi_done(ccb);
                        hba->out_req_cnt--;
                } else if (ccb->req_type & PASSTHRU_REQ_TYPE) {
@@ -1028,7 +991,7 @@ static int stex_abort(struct scsi_cmnd *cmd)
        }
 
 fail_out:
-       stex_unmap_sg(hba, cmd);
+       scsi_dma_unmap(cmd);
        hba->wait_ccb->req = NULL; /* nullify the req's future return */
        hba->wait_ccb = NULL;
        result = FAILED;
index 2ca9505..92bfaea 100644 (file)
@@ -332,8 +332,7 @@ static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id)
        int i;
        unsigned long flags = 0;
        unsigned char status_reg, pio_int_reg, int_reg;
-       struct scatterlist *sglist;
-       unsigned int sgcount;
+       struct scatterlist *sg;
        unsigned int tot_trans = 0;
 
        /* We search the base address of the host adapter which caused the interrupt */
@@ -429,19 +428,15 @@ static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id)
                        {
                                current_command->SCp.phase = data_out;
                                outb(FLUSH_FIFO, base + COMMAND_REG);
-                               sym53c416_set_transfer_counter(base, current_command->request_bufflen);
+                               sym53c416_set_transfer_counter(base,
+                                                              scsi_bufflen(current_command));
                                outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG);
-                               if(!current_command->use_sg)
-                                       tot_trans = sym53c416_write(base, current_command->request_buffer, current_command->request_bufflen);
-                               else
-                               {
-                                       sgcount = current_command->use_sg;
-                                       sglist = current_command->request_buffer;
-                                       while(sgcount--)
-                                       {
-                                               tot_trans += sym53c416_write(base, SG_ADDRESS(sglist), sglist->length);
-                                               sglist++;
-                                       }
+
+                               scsi_for_each_sg(current_command,
+                                                sg, scsi_sg_count(current_command), i) {
+                                       tot_trans += sym53c416_write(base,
+                                                                    SG_ADDRESS(sg),
+                                                                    sg->length);
                                }
                                if(tot_trans < current_command->underflow)
                                        printk(KERN_WARNING "sym53c416: Underflow, wrote %d bytes, request for %d bytes.\n", tot_trans, current_command->underflow);
@@ -455,19 +450,16 @@ static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id)
                        {
                                current_command->SCp.phase = data_in;
                                outb(FLUSH_FIFO, base + COMMAND_REG);
-                               sym53c416_set_transfer_counter(base, current_command->request_bufflen);
+                               sym53c416_set_transfer_counter(base,
+                                                              scsi_bufflen(current_command));
+
                                outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG);
-                               if(!current_command->use_sg)
-                                       tot_trans = sym53c416_read(base, current_command->request_buffer, current_command->request_bufflen);
-                               else
-                               {
-                                       sgcount = current_command->use_sg;
-                                       sglist = current_command->request_buffer;
-                                       while(sgcount--)
-                                       {
-                                               tot_trans += sym53c416_read(base, SG_ADDRESS(sglist), sglist->length);
-                                               sglist++;
-                                       }
+
+                               scsi_for_each_sg(current_command,
+                                                sg, scsi_sg_count(current_command), i) {
+                                       tot_trans += sym53c416_read(base,
+                                                                   SG_ADDRESS(sg),
+                                                                   sg->length);
                                }
                                if(tot_trans < current_command->underflow)
                                        printk(KERN_WARNING "sym53c416: Underflow, read %d bytes, request for %d bytes.\n", tot_trans, current_command->underflow);
index e7b85e8..73c5ca0 100644 (file)
@@ -457,28 +457,21 @@ static int dc390_pci_map (struct dc390_srb* pSRB)
                        error = 1;
                DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __FUNCTION__, pcmd->sense_buffer, cmdp->saved_dma_handle));
        /* Map SG list */
-       } else if (pcmd->use_sg) {
-               pSRB->pSegmentList      = (struct scatterlist *) pcmd->request_buffer;
-               pSRB->SGcount           = pci_map_sg(pdev, pSRB->pSegmentList, pcmd->use_sg,
-                                                    pcmd->sc_data_direction);
+       } else if (scsi_sg_count(pcmd)) {
+               int nseg;
+
+               nseg = scsi_dma_map(pcmd);
+
+               pSRB->pSegmentList      = scsi_sglist(pcmd);
+               pSRB->SGcount           = nseg;
+
                /* TODO: error handling */
-               if (!pSRB->SGcount)
+               if (nseg < 0)
                        error = 1;
                DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n",\
-                             __FUNCTION__, pcmd->request_buffer, pSRB->SGcount, pcmd->use_sg));
+                             __FUNCTION__, scsi_sglist(pcmd), nseg, scsi_sg_count(pcmd)));
        /* Map single segment */
-       } else if (pcmd->request_buffer && pcmd->request_bufflen) {
-               pSRB->pSegmentList      = dc390_sg_build_single(&pSRB->Segmentx, pcmd->request_buffer, pcmd->request_bufflen);
-               pSRB->SGcount           = pci_map_sg(pdev, pSRB->pSegmentList, 1,
-                                                    pcmd->sc_data_direction);
-               cmdp->saved_dma_handle  = sg_dma_address(pSRB->pSegmentList);
-
-               /* TODO: error handling */
-               if (pSRB->SGcount != 1)
-                       error = 1;
-               DEBUG1(printk("%s(): Mapped request buffer %p at %x\n", __FUNCTION__, pcmd->request_buffer, cmdp->saved_dma_handle));
-       /* No mapping !? */     
-       } else
+       } else
                pSRB->SGcount = 0;
 
        return error;
@@ -494,12 +487,10 @@ static void dc390_pci_unmap (struct dc390_srb* pSRB)
        if (pSRB->SRBFlag) {
                pci_unmap_sg(pdev, &pSRB->Segmentx, 1, DMA_FROM_DEVICE);
                DEBUG1(printk("%s(): Unmapped sense buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle));
-       } else if (pcmd->use_sg) {
-               pci_unmap_sg(pdev, pcmd->request_buffer, pcmd->use_sg, pcmd->sc_data_direction);
-               DEBUG1(printk("%s(): Unmapped SG at %p with %d elements\n", __FUNCTION__, pcmd->request_buffer, pcmd->use_sg));
-       } else if (pcmd->request_buffer && pcmd->request_bufflen) {
-               pci_unmap_sg(pdev, &pSRB->Segmentx, 1, pcmd->sc_data_direction);
-               DEBUG1(printk("%s(): Unmapped request buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle));
+       } else {
+               scsi_dma_unmap(pcmd);
+               DEBUG1(printk("%s(): Unmapped SG at %p with %d elements\n",
+                             __FUNCTION__, scsi_sglist(pcmd), scsi_sg_count(pcmd)));
        }
 }
 
@@ -1153,9 +1144,9 @@ dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB)
     struct scatterlist *psgl;
     pSRB->TotalXferredLen = 0;
     pSRB->SGIndex = 0;
-    if (pcmd->use_sg) {
+    if (scsi_sg_count(pcmd)) {
        size_t saved;
-       pSRB->pSegmentList = (struct scatterlist *)pcmd->request_buffer;
+       pSRB->pSegmentList = scsi_sglist(pcmd);
        psgl = pSRB->pSegmentList;
        //dc390_pci_sync(pSRB);
 
@@ -1179,12 +1170,6 @@ dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB)
        printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n",
                pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr);
 
-    } else if(pcmd->request_buffer) {
-       //dc390_pci_sync(pSRB);
-
-       sg_dma_len(&pSRB->Segmentx) = pcmd->request_bufflen - pSRB->Saved_Ptr;
-       pSRB->SGcount = 1;
-       pSRB->pSegmentList = (struct scatterlist *) &pSRB->Segmentx;
     } else {
         pSRB->SGcount = 0;
         printk (KERN_INFO "DC390: RESTORE_PTR message for Transfer without Scatter-Gather ??\n");
@@ -1612,7 +1597,7 @@ dc390_Reselect( struct dc390_acb* pACB )
        if( !( pACB->scan_devices ) )
        {
            struct scsi_cmnd *pcmd = pSRB->pcmd;
-           pcmd->resid = pcmd->request_bufflen;
+           scsi_set_resid(pcmd, scsi_bufflen(pcmd));
            SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
            dc390_Going_remove(pDCB, pSRB);
            dc390_Free_insert(pACB, pSRB);
@@ -1695,7 +1680,7 @@ dc390_RequestSense(struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_
                              pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN));
 
        pSRB->SRBFlag |= AUTO_REQSENSE;
-       pSRB->SavedSGCount = pcmd->use_sg;
+       pSRB->SavedSGCount = scsi_sg_count(pcmd);
        pSRB->SavedTotXLen = pSRB->TotalXferredLen;
        pSRB->AdaptStatus = 0;
        pSRB->TargetStatus = 0; /* CHECK_CONDITION<<1; */
@@ -1743,7 +1728,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb*
                       (u32) pcmd->result, (u32) pSRB->TotalXferredLen));
            } else {
                SET_RES_DRV(pcmd->result, DRIVER_SENSE);
-               pcmd->use_sg = pSRB->SavedSGCount;
+               scsi_sg_count(pcmd) = pSRB->SavedSGCount;
                //pSRB->ScsiCmdLen       = (u8) (pSRB->Segment1[0] >> 8);
                DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
                pSRB->TotalXferredLen = 0;
@@ -1765,7 +1750,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb*
        else if( status_byte(status) == QUEUE_FULL )
        {
            scsi_track_queue_full(pcmd->device, pDCB->GoingSRBCnt - 1);
-           pcmd->use_sg = pSRB->SavedSGCount;
+           scsi_sg_count(pcmd) = pSRB->SavedSGCount;
            DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
            pSRB->TotalXferredLen = 0;
            SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
@@ -1816,7 +1801,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb*
     }
 
 cmd_done:
-    pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;
+    scsi_set_resid(pcmd, scsi_bufflen(pcmd) - pSRB->TotalXferredLen);
 
     dc390_Going_remove (pDCB, pSRB);
     /* Add to free list */
index 3de08a1..9e8232a 100644 (file)
@@ -1111,7 +1111,7 @@ static int u14_34f_detect(struct scsi_host_template *tpnt) {
 static void map_dma(unsigned int i, unsigned int j) {
    unsigned int data_len = 0;
    unsigned int k, count, pci_dir;
-   struct scatterlist *sgpnt;
+   struct scatterlist *sg;
    struct mscp *cpp;
    struct scsi_cmnd *SCpnt;
 
@@ -1124,33 +1124,28 @@ static void map_dma(unsigned int i, unsigned int j) {
 
    cpp->sense_len = sizeof SCpnt->sense_buffer;
 
-   if (!SCpnt->use_sg) {
-
-      /* If we get here with PCI_DMA_NONE, pci_map_single triggers a BUG() */
-      if (!SCpnt->request_bufflen) pci_dir = PCI_DMA_BIDIRECTIONAL;
-
-      if (SCpnt->request_buffer)
-         cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev,
-                  SCpnt->request_buffer, SCpnt->request_bufflen, pci_dir));
-
-      cpp->data_len = H2DEV(SCpnt->request_bufflen);
-      return;
-      }
-
-   sgpnt = (struct scatterlist *) SCpnt->request_buffer;
-   count = pci_map_sg(HD(j)->pdev, sgpnt, SCpnt->use_sg, pci_dir);
-
-   for (k = 0; k < count; k++) {
-      cpp->sglist[k].address = H2DEV(sg_dma_address(&sgpnt[k]));
-      cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(&sgpnt[k]));
-      data_len += sgpnt[k].length;
-      }
-
-   cpp->sg = TRUE;
-   cpp->use_sg = SCpnt->use_sg;
-   cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev, cpp->sglist,
-                             SCpnt->use_sg * sizeof(struct sg_list), pci_dir));
-   cpp->data_len = H2DEV(data_len);
+   if (scsi_bufflen(SCpnt)) {
+          count = scsi_dma_map(SCpnt);
+          BUG_ON(count < 0);
+
+          scsi_for_each_sg(SCpnt, sg, count, k) {
+                  cpp->sglist[k].address = H2DEV(sg_dma_address(sg));
+                  cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(sg));
+                  data_len += sg->length;
+          }
+
+          cpp->sg = TRUE;
+          cpp->use_sg = scsi_sg_count(SCpnt);
+          cpp->data_address =
+                  H2DEV(pci_map_single(HD(j)->pdev, cpp->sglist,
+                                       cpp->use_sg * sizeof(struct sg_list),
+                                       pci_dir));
+          cpp->data_len = H2DEV(data_len);
+
+   } else {
+          pci_dir = PCI_DMA_BIDIRECTIONAL;
+          cpp->data_len = H2DEV(scsi_bufflen(SCpnt));
+   }
 }
 
 static void unmap_dma(unsigned int i, unsigned int j) {
@@ -1165,8 +1160,7 @@ static void unmap_dma(unsigned int i, unsigned int j) {
       pci_unmap_single(HD(j)->pdev, DEV2H(cpp->sense_addr),
                        DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
 
-   if (SCpnt->use_sg)
-      pci_unmap_sg(HD(j)->pdev, SCpnt->request_buffer, SCpnt->use_sg, pci_dir);
+   scsi_dma_unmap(SCpnt);
 
    if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL;
 
@@ -1187,9 +1181,9 @@ static void sync_dma(unsigned int i, unsigned int j) {
       pci_dma_sync_single_for_cpu(HD(j)->pdev, DEV2H(cpp->sense_addr),
                           DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
 
-   if (SCpnt->use_sg)
-      pci_dma_sync_sg_for_cpu(HD(j)->pdev, SCpnt->request_buffer,
-                         SCpnt->use_sg, pci_dir);
+   if (scsi_sg_count(SCpnt))
+          pci_dma_sync_sg_for_cpu(HD(j)->pdev, scsi_sglist(SCpnt),
+                                  scsi_sg_count(SCpnt), pci_dir);
 
    if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL;
 
index 56906ab..c08235d 100644 (file)
@@ -675,16 +675,15 @@ static const char *ultrastor_info(struct Scsi_Host * shpnt)
 
 static inline void build_sg_list(struct mscp *mscp, struct scsi_cmnd *SCpnt)
 {
-       struct scatterlist *sl;
+       struct scatterlist *sg;
        long transfer_length = 0;
        int i, max;
 
-       sl = (struct scatterlist *) SCpnt->request_buffer;
-       max = SCpnt->use_sg;
-       for (i = 0; i < max; i++) {
-               mscp->sglist[i].address = isa_page_to_bus(sl[i].page) + sl[i].offset;
-               mscp->sglist[i].num_bytes = sl[i].length;
-               transfer_length += sl[i].length;
+       max = scsi_sg_count(SCpnt);
+       scsi_for_each_sg(SCpnt, sg, max, i) {
+               mscp->sglist[i].address = isa_page_to_bus(sg->page) + sg->offset;
+               mscp->sglist[i].num_bytes = sg->length;
+               transfer_length += sg->length;
        }
        mscp->number_of_sg_list = max;
        mscp->transfer_data = isa_virt_to_bus(mscp->sglist);
@@ -730,15 +729,15 @@ static int ultrastor_queuecommand(struct scsi_cmnd *SCpnt,
     my_mscp->target_id = SCpnt->device->id;
     my_mscp->ch_no = 0;
     my_mscp->lun = SCpnt->device->lun;
-    if (SCpnt->use_sg) {
+    if (scsi_sg_count(SCpnt)) {
        /* Set scatter/gather flag in SCSI command packet */
        my_mscp->sg = TRUE;
        build_sg_list(my_mscp, SCpnt);
     } else {
        /* Unset scatter/gather flag in SCSI command packet */
        my_mscp->sg = FALSE;
-       my_mscp->transfer_data = isa_virt_to_bus(SCpnt->request_buffer);
-       my_mscp->transfer_data_length = SCpnt->request_bufflen;
+       my_mscp->transfer_data = isa_virt_to_bus(scsi_sglist(SCpnt));
+       my_mscp->transfer_data_length = scsi_bufflen(SCpnt);
     }
     my_mscp->command_link = 0;         /*???*/
     my_mscp->scsi_command_link_id = 0; /*???*/
index 30be765..d6fd425 100644 (file)
@@ -1091,6 +1091,7 @@ static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
        unchar *cdb = (unchar *) SCpnt->cmnd;
        unchar idlun;
        short cdblen;
+       int nseg;
        Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
 
        cdblen = SCpnt->cmd_len;
@@ -1106,28 +1107,29 @@ static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
        SCpnt->host_scribble = (unchar *) scb;
        scb->host = host;
 
-       if (SCpnt->use_sg) {
-               struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer;
+       nseg = scsi_sg_count(SCpnt);
+       if (nseg) {
+               struct scatterlist *sg;
                unsigned i;
 
                if (SCpnt->device->host->sg_tablesize == SG_NONE) {
                        panic("wd7000_queuecommand: scatter/gather not supported.\n");
                }
-               dprintk("Using scatter/gather with %d elements.\n", SCpnt->use_sg);
+               dprintk("Using scatter/gather with %d elements.\n", nseg);
 
                sgb = scb->sgb;
                scb->op = 1;
                any2scsi(scb->dataptr, (int) sgb);
-               any2scsi(scb->maxlen, SCpnt->use_sg * sizeof(Sgb));
+               any2scsi(scb->maxlen, nseg * sizeof(Sgb));
 
-               for (i = 0; i < SCpnt->use_sg; i++) {
-                       any2scsi(sgb[i].ptr, isa_page_to_bus(sg[i].page) + sg[i].offset);
-                       any2scsi(sgb[i].len, sg[i].length);
+               scsi_for_each_sg(SCpnt, sg, nseg, i) {
+                       any2scsi(sgb[i].ptr, isa_page_to_bus(sg->page) + sg->offset);
+                       any2scsi(sgb[i].len, sg->length);
                }
        } else {
                scb->op = 0;
-               any2scsi(scb->dataptr, isa_virt_to_bus(SCpnt->request_buffer));
-               any2scsi(scb->maxlen, SCpnt->request_bufflen);
+               any2scsi(scb->dataptr, isa_virt_to_bus(scsi_sglist(SCpnt)));
+               any2scsi(scb->maxlen, scsi_bufflen(SCpnt));
        }
 
        /* FIXME: drop lock and yield here ? */
index a2e0c10..53e1705 100644 (file)
@@ -135,4 +135,24 @@ extern void scsi_kunmap_atomic_sg(void *virt);
 extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t);
 extern void scsi_free_sgtable(struct scatterlist *, int);
 
+extern int scsi_dma_map(struct scsi_cmnd *cmd);
+extern void scsi_dma_unmap(struct scsi_cmnd *cmd);
+
+#define scsi_sg_count(cmd) ((cmd)->use_sg)
+#define scsi_sglist(cmd) ((struct scatterlist *)(cmd)->request_buffer)
+#define scsi_bufflen(cmd) ((cmd)->request_bufflen)
+
+static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid)
+{
+       cmd->resid = resid;
+}
+
+static inline int scsi_get_resid(struct scsi_cmnd *cmd)
+{
+       return cmd->resid;
+}
+
+#define scsi_for_each_sg(cmd, sg, nseg, __i)                   \
+       for (__i = 0, sg = scsi_sglist(cmd); __i < (nseg); __i++, (sg)++)
+
 #endif /* _SCSI_SCSI_CMND_H */
index 68f461b..4a2e490 100644 (file)
@@ -338,12 +338,6 @@ struct scsi_host_template {
         */
        enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *);
 
-       /*
-        * suspend support
-        */
-       int (*resume)(struct scsi_device *);
-       int (*suspend)(struct scsi_device *, pm_message_t state);
-
        /*
         * Name of proc directory
         */
index 1e79730..a0d80bc 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  *  FiberChannel transport specific attributes exported to sysfs.
  *
  *  Copyright (c) 2003 Silicon Graphics, Inc.  All rights reserved.
@@ -19,7 +19,7 @@
  *
  *  ========
  *
- *  Copyright (C) 2004-2005   James Smart, Emulex Corporation
+ *  Copyright (C) 2004-2007   James Smart, Emulex Corporation
  *    Rewrite for host, target, device, and remote port attributes,
  *    statistics, and service functions...
  *
@@ -62,8 +62,10 @@ enum fc_port_type {
        FC_PORTTYPE_NLPORT,             /* (Public) Loop w/ FLPort */
        FC_PORTTYPE_LPORT,              /* (Private) Loop w/o FLPort */
        FC_PORTTYPE_PTP,                /* Point to Point w/ another NPort */
+       FC_PORTTYPE_NPIV,               /* VPORT based on NPIV */
 };
 
+
 /*
  * fc_port_state: If you alter this, you also need to alter scsi_transport_fc.c
  * (for the ascii descriptions).
@@ -83,7 +85,26 @@ enum fc_port_state {
 };
 
 
-/* 
+/*
+ * fc_vport_state: If you alter this, you also need to alter
+ * scsi_transport_fc.c (for the ascii descriptions).
+ */
+enum fc_vport_state {
+       FC_VPORT_UNKNOWN,
+       FC_VPORT_ACTIVE,
+       FC_VPORT_DISABLED,
+       FC_VPORT_LINKDOWN,
+       FC_VPORT_INITIALIZING,
+       FC_VPORT_NO_FABRIC_SUPP,
+       FC_VPORT_NO_FABRIC_RSCS,
+       FC_VPORT_FABRIC_LOGOUT,
+       FC_VPORT_FABRIC_REJ_WWN,
+       FC_VPORT_FAILED,
+};
+
+
+
+/*
  * FC Classes of Service
  * Note: values are not enumerated, as they can be "or'd" together
  * for reporting (e.g. report supported_classes). If you alter this list,
@@ -96,7 +117,7 @@ enum fc_port_state {
 #define FC_COS_CLASS4                  0x10
 #define FC_COS_CLASS6                  0x40
 
-/* 
+/*
  * FC Port Speeds
  * Note: values are not enumerated, as they can be "or'd" together
  * for reporting (e.g. report supported_speeds). If you alter this list,
@@ -124,16 +145,114 @@ enum fc_tgtid_binding_type  {
 };
 
 /*
- * FC Remote Port Roles
+ * FC Port Roles
  * Note: values are not enumerated, as they can be "or'd" together
  * for reporting (e.g. report roles). If you alter this list,
  * you also need to alter scsi_transport_fc.c (for the ascii descriptions).
  */
-#define FC_RPORT_ROLE_UNKNOWN                  0x00
-#define FC_RPORT_ROLE_FCP_TARGET               0x01
-#define FC_RPORT_ROLE_FCP_INITIATOR            0x02
-#define FC_RPORT_ROLE_IP_PORT                  0x04
+#define FC_PORT_ROLE_UNKNOWN                   0x00
+#define FC_PORT_ROLE_FCP_TARGET                        0x01
+#define FC_PORT_ROLE_FCP_INITIATOR             0x02
+#define FC_PORT_ROLE_IP_PORT                   0x04
+
+/* The following are for compatibility */
+#define FC_RPORT_ROLE_UNKNOWN                  FC_PORT_ROLE_UNKNOWN
+#define FC_RPORT_ROLE_FCP_TARGET               FC_PORT_ROLE_FCP_TARGET
+#define FC_RPORT_ROLE_FCP_INITIATOR            FC_PORT_ROLE_FCP_INITIATOR
+#define FC_RPORT_ROLE_IP_PORT                  FC_PORT_ROLE_IP_PORT
+
+
+/* Macro for use in defining Virtual Port attributes */
+#define FC_VPORT_ATTR(_name,_mode,_show,_store)                                \
+struct class_device_attribute class_device_attr_vport_##_name =        \
+       __ATTR(_name,_mode,_show,_store)
+
+
+/*
+ * FC Virtual Port Attributes
+ *
+ * This structure exists for each FC port is a virtual FC port. Virtual
+ * ports share the physical link with the Physical port. Each virtual
+ * ports has a unique presense on the SAN, and may be instantiated via
+ * NPIV, Virtual Fabrics, or via additional ALPAs. As the vport is a
+ * unique presense, each vport has it's own view of the fabric,
+ * authentication priviledge, and priorities.
+ *
+ * A virtual port may support 1 or more FC4 roles. Typically it is a
+ * FCP Initiator. It could be a FCP Target, or exist sole for an IP over FC
+ * roles. FC port attributes for the vport will be reported on any
+ * fc_host class object allocated for an FCP Initiator.
+ *
+ * --
+ *
+ * Fixed attributes are not expected to change. The driver is
+ * expected to set these values after receiving the fc_vport structure
+ * via the vport_create() call from the transport.
+ * The transport fully manages all get functions w/o driver interaction.
+ *
+ * Dynamic attributes are expected to change. The driver participates
+ * in all get/set operations via functions provided by the driver.
+ *
+ * Private attributes are transport-managed values. They are fully
+ * managed by the transport w/o driver interaction.
+ */
 
+#define FC_VPORT_SYMBOLIC_NAMELEN              64
+struct fc_vport {
+       /* Fixed Attributes */
+
+       /* Dynamic Attributes */
+
+       /* Private (Transport-managed) Attributes */
+       enum fc_vport_state vport_state;
+       enum fc_vport_state vport_last_state;
+       u64 node_name;
+       u64 port_name;
+       u32 roles;
+       u32 vport_id;           /* Admin Identifier for the vport */
+       enum fc_port_type vport_type;
+       char symbolic_name[FC_VPORT_SYMBOLIC_NAMELEN];
+
+       /* exported data */
+       void *dd_data;                  /* Used for driver-specific storage */
+
+       /* internal data */
+       struct Scsi_Host *shost;        /* Physical Port Parent */
+       unsigned int channel;
+       u32 number;
+       u8 flags;
+       struct list_head peers;
+       struct device dev;
+       struct work_struct vport_delete_work;
+} __attribute__((aligned(sizeof(unsigned long))));
+
+/* bit field values for struct fc_vport "flags" field: */
+#define FC_VPORT_CREATING              0x01
+#define FC_VPORT_DELETING              0x02
+#define FC_VPORT_DELETED               0x04
+#define FC_VPORT_DEL                   0x06    /* Any DELETE state */
+
+#define        dev_to_vport(d)                         \
+       container_of(d, struct fc_vport, dev)
+#define transport_class_to_vport(classdev)     \
+       dev_to_vport(classdev->dev)
+#define vport_to_shost(v)                      \
+       (v->shost)
+#define vport_to_shost_channel(v)              \
+       (v->channel)
+#define vport_to_parent(v)                     \
+       (v->dev.parent)
+
+
+/* Error return codes for vport_create() callback */
+#define VPCERR_UNSUPPORTED             -ENOSYS         /* no driver/adapter
+                                                          support */
+#define VPCERR_BAD_WWN                 -ENOTUNIQ       /* driver validation
+                                                          of WWNs failed */
+#define VPCERR_NO_FABRIC_SUPP          -EOPNOTSUPP     /* Fabric connection
+                                                          is loop or the
+                                                          Fabric Port does
+                                                          not support NPIV */
 
 /*
  * fc_rport_identifiers: This set of data contains all elements
@@ -149,6 +268,7 @@ struct fc_rport_identifiers {
        u32 roles;
 };
 
+
 /* Macro for use in defining Remote Port attributes */
 #define FC_RPORT_ATTR(_name,_mode,_show,_store)                                \
 struct class_device_attribute class_device_attr_rport_##_name =        \
@@ -278,7 +398,7 @@ struct fc_host_statistics {
        u64 prim_seq_protocol_err_count;
        u64 invalid_tx_word_count;
        u64 invalid_crc_count;
-       
+
        /* fc4 statistics  (only FCP supported currently) */
        u64 fcp_input_requests;
        u64 fcp_output_requests;
@@ -343,6 +463,7 @@ struct fc_host_attrs {
        u8  supported_fc4s[FC_FC4_LIST_SIZE];
        u32 supported_speeds;
        u32 maxframe_size;
+       u16 max_npiv_vports;
        char serial_number[FC_SERIAL_NUMBER_SIZE];
 
        /* Dynamic Attributes */
@@ -361,8 +482,11 @@ struct fc_host_attrs {
        /* internal data */
        struct list_head rports;
        struct list_head rport_bindings;
+       struct list_head vports;
        u32 next_rport_number;
        u32 next_target_id;
+       u32 next_vport_number;
+       u16 npiv_vports_inuse;
 
        /* work queues for rport state manipulation */
        char work_q_name[KOBJ_NAME_LEN];
@@ -388,6 +512,8 @@ struct fc_host_attrs {
        (((struct fc_host_attrs *)(x)->shost_data)->supported_speeds)
 #define fc_host_maxframe_size(x)       \
        (((struct fc_host_attrs *)(x)->shost_data)->maxframe_size)
+#define fc_host_max_npiv_vports(x)     \
+       (((struct fc_host_attrs *)(x)->shost_data)->max_npiv_vports)
 #define fc_host_serial_number(x)       \
        (((struct fc_host_attrs *)(x)->shost_data)->serial_number)
 #define fc_host_port_id(x)     \
@@ -412,10 +538,16 @@ struct fc_host_attrs {
        (((struct fc_host_attrs *)(x)->shost_data)->rports)
 #define fc_host_rport_bindings(x) \
        (((struct fc_host_attrs *)(x)->shost_data)->rport_bindings)
+#define fc_host_vports(x) \
+       (((struct fc_host_attrs *)(x)->shost_data)->vports)
 #define fc_host_next_rport_number(x) \
        (((struct fc_host_attrs *)(x)->shost_data)->next_rport_number)
 #define fc_host_next_target_id(x) \
        (((struct fc_host_attrs *)(x)->shost_data)->next_target_id)
+#define fc_host_next_vport_number(x) \
+       (((struct fc_host_attrs *)(x)->shost_data)->next_vport_number)
+#define fc_host_npiv_vports_inuse(x)   \
+       (((struct fc_host_attrs *)(x)->shost_data)->npiv_vports_inuse)
 #define fc_host_work_q_name(x) \
        (((struct fc_host_attrs *)(x)->shost_data)->work_q_name)
 #define fc_host_work_q(x) \
@@ -452,14 +584,20 @@ struct fc_function_template {
        void    (*dev_loss_tmo_callbk)(struct fc_rport *);
        void    (*terminate_rport_io)(struct fc_rport *);
 
+       void    (*set_vport_symbolic_name)(struct fc_vport *);
+       int     (*vport_create)(struct fc_vport *, bool);
+       int     (*vport_disable)(struct fc_vport *, bool);
+       int     (*vport_delete)(struct fc_vport *);
+
        /* allocation lengths for host-specific data */
        u32                             dd_fcrport_size;
+       u32                             dd_fcvport_size;
 
-       /* 
+       /*
         * The driver sets these to tell the transport class it
         * wants the attributes displayed in sysfs.  If the show_ flag
         * is not set, the attribute will be private to the transport
-        * class 
+        * class
         */
 
        /* remote port fixed attributes */
@@ -512,7 +650,7 @@ fc_remote_port_chkready(struct fc_rport *rport)
 
        switch (rport->port_state) {
        case FC_PORTSTATE_ONLINE:
-               if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
+               if (rport->roles & FC_PORT_ROLE_FCP_TARGET)
                        result = 0;
                else if (rport->flags & FC_RPORT_DEVLOSS_PENDING)
                        result = DID_IMM_RETRY << 16;
@@ -549,6 +687,27 @@ static inline void u64_to_wwn(u64 inm, u8 *wwn)
        wwn[7] = inm & 0xff;
 }
 
+/**
+ * fc_vport_set_state() - called to set a vport's state. Saves the old state,
+ *   excepting the transitory states of initializing and sending the ELS
+ *   traffic to instantiate the vport on the link.
+ *
+ * Assumes the driver has surrounded this with the proper locking to ensure
+ * a coherent state change.
+ *
+ * @vport:     virtual port whose state is changing
+ * @new_state:  new state
+ **/
+static inline void
+fc_vport_set_state(struct fc_vport *vport, enum fc_vport_state new_state)
+{
+       if ((new_state != FC_VPORT_UNKNOWN) &&
+           (new_state != FC_VPORT_INITIALIZING))
+               vport->vport_last_state = vport->vport_state;
+       vport->vport_state = new_state;
+}
+
+
 struct scsi_transport_template *fc_attach_transport(
                        struct fc_function_template *);
 void fc_release_transport(struct scsi_transport_template *);
@@ -567,5 +726,6 @@ void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
         *   be sure to read the Vendor Type and ID formatting requirements
         *   specified in scsi_netlink.h
         */
+int fc_vport_terminate(struct fc_vport *vport);
 
 #endif /* SCSI_TRANSPORT_FC_H */