Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Thu, 5 Oct 2006 01:57:35 +0000 (18:57 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 5 Oct 2006 01:57:35 +0000 (18:57 -0700)
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (54 commits)
  [SCSI] Initial Commit of qla4xxx
  [SCSI] raid class: handle component-add errors
  [SCSI] SCSI megaraid_sas: handle thrown errors
  [SCSI] SCSI aic94xx: handle sysfs errors
  [SCSI] SCSI st: fix error handling in module init, sysfs
  [SCSI] SCSI sd: fix module init/exit error handling
  [SCSI] SCSI osst: add error handling to module init, sysfs
  [SCSI] scsi: remove hosts.h
  [SCSI] scsi: Scsi_Cmnd convertion in aic7xxx_old.c
  [SCSI] megaraid_sas: sets ioctl timeout and updates version,changelog
  [SCSI] megaraid_sas: adds tasklet for cmd completion
  [SCSI] megaraid_sas: prints pending cmds before setting hw_crit_error
  [SCSI] megaraid_sas: function pointer for disable interrupt
  [SCSI] megaraid_sas: frame count optimization
  [SCSI] megaraid_sas: FW transition and q size changes
  [SCSI] qla2xxx: Update version number to 8.01.07-k2.
  [SCSI] qla2xxx: Stall mid-layer error handlers while rport is blocked.
  [SCSI] qla2xxx: Add MODULE_FIRMWARE tags.
  [SCSI] qla2xxx: Add support for host port state FC transport attribute.
  [SCSI] qla2xxx: Add support for fabric name FC transport attribute.
  ...

80 files changed:
Documentation/scsi/ChangeLog.megaraid_sas
drivers/message/fusion/linux_compat.h
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-xxxx.c
drivers/scsi/3w-xxxx.h
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/a100u2w.c
drivers/scsi/aic7xxx/aic79xx_inline.h
drivers/scsi/aic7xxx/aic79xx_osm_pci.c
drivers/scsi/aic7xxx/aic7xxx_inline.h
drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
drivers/scsi/aic7xxx_old.c
drivers/scsi/aic94xx/Kconfig
drivers/scsi/aic94xx/aic94xx_init.c
drivers/scsi/arm/acornscsi.c
drivers/scsi/arm/acornscsi.h
drivers/scsi/arm/fas216.c
drivers/scsi/arm/fas216.h
drivers/scsi/arm/queue.c
drivers/scsi/arm/queue.h
drivers/scsi/arm/scsi.h
drivers/scsi/dc395x.c
drivers/scsi/dmx3191d.c
drivers/scsi/dpt/dpti_i2o.h
drivers/scsi/dpt_i2o.c
drivers/scsi/dpti.h
drivers/scsi/gdth.h
drivers/scsi/hosts.h [deleted file]
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/ips.c
drivers/scsi/ips.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/megaraid/mega_common.h
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/nsp32.c
drivers/scsi/nsp32.h
drivers/scsi/osst.c
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/qla1280.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/qla4xxx/Kconfig [new file with mode: 0644]
drivers/scsi/qla4xxx/Makefile [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_dbg.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_dbg.h [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_def.h [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_fw.h [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_glbl.h [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_init.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_inline.h [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_iocb.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_isr.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_mbx.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_nvram.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_nvram.h [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_os.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_version.h [new file with mode: 0644]
drivers/scsi/raid_class.c
drivers/scsi/scsi.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/scsi_lib.c
drivers/scsi/sd.c
drivers/scsi/seagate.c
drivers/scsi/seagate.h [deleted file]
drivers/scsi/sg.c
drivers/scsi/st.c
drivers/scsi/stex.c
drivers/scsi/tmscsim.c
include/linux/raid_class.h
include/scsi/sg.h

index d9e5960dafd5b2fee860552edac5f92b4e3bec42..5eb92754499098eaddaec839cb5d913157837fd1 100644 (file)
@@ -1,4 +1,49 @@
 
+1 Release Date    : Mon Oct 02 11:21:32 PDT 2006 - Sumant Patro <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.03.05
+3 Older Version   : 00.00.03.04
+
+i.     PCI_DEVICE macro used
+
+       Convert the pci_device_id-table of the megaraid_sas-driver to the PCI_DEVICE-macro, to safe some lines.
+
+               - Henrik Kretzschmar <henne@nachtwindheim.de>
+ii.    All compiler warnings removed
+iii.   megasas_ctrl_info struct reverted to 3.02 release
+iv.    Default value of megasas_dbg_lvl set to 0
+v.     Removing in megasas_exit the sysfs entry created for megasas_dbg_lvl
+vi.    In megasas_teardown_frame_pool(), cmd->frame was passed instead of
+       cmd->sense to pci_pool_free. Fixed. Bug was pointed out by
+       Eric Sesterhenn
+
+1 Release Date    : Wed Sep 13 14:22:51 PDT 2006 - Sumant Patro <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.03.04
+3 Older Version   : 00.00.03.03
+
+i.     Added Reboot notify
+ii.    Reduced by 1 max cmds sent to FW from Driver to make the reply_q_sz same
+       as Max Cmds FW can support
+
+1 Release Date    : Tue Aug 22 16:33:14 PDT 2006 - Sumant Patro <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.03.03
+3 Older Version   : 00.00.03.02
+
+i.     Send stop adapter to FW & Dump pending FW cmds before declaring adapter dead.
+       New varible added to set dbg level.
+ii.    Disable interrupt made as fn pointer as they are different for 1068 / 1078
+iii.   Frame count optimization. Main frame can contain 2 SGE for 64 bit SGLs and
+       3 SGE for 32 bit SGL
+iv.    Tasklet added for cmd completion
+v.     If FW in operational state before firing INIT, now we send RESET Flag to FW instead of just READY. This is used to do soft reset.
+vi.    megasas_ctrl_prop structure updated (based on FW struct)
+vii.   Added print : FW now in Ready State during initialization
+
+1 Release Date    : Sun Aug 06 22:49:52 PDT 2006 - Sumant Patro <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.03.02
+3 Older Version   : 00.00.03.01
+
+i.     Added FW tranistion state for Hotplug scenario
+
 1 Release Date    : Sun May 14 22:49:52 PDT 2006 - Sumant Patro <Sumant.Patro@lsil.com>
 2 Current Version : 00.00.03.01
 3 Older Version   : 00.00.02.04
index 048b5b8610e3f395d3e7cfcc32cee151eef64446..bb2bf5aa0b62bfa27ffcf4e22bca83e56459b95a 100644 (file)
@@ -6,13 +6,4 @@
 #include <linux/version.h>
 #include <scsi/scsi_device.h>
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,6))
-static int inline scsi_device_online(struct scsi_device *sdev)
-{
-       return sdev->online;
-}
-#endif
-
-
-/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #endif /* _LINUX_COMPAT_H */
index 5a9475e56d0eb7baea0b33d0188787aaffb799c0..da173159cedbcec2ff43267b237c7e41514f5bd0 100644 (file)
@@ -2211,7 +2211,7 @@ static int __init twa_init(void)
 {
        printk(KERN_WARNING "3ware 9000 Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
 
-       return pci_module_init(&twa_driver);
+       return pci_register_driver(&twa_driver);
 } /* End twa_init() */
 
 /* This function is called on driver exit */
index f3a5f422a8e4d5f11f636a5c5ef798d239b82392..2d4cb6721fa6688132446f4e4b12772e7f55d77f 100644 (file)
@@ -2486,7 +2486,7 @@ static int __init tw_init(void)
 {
        printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
 
-       return pci_module_init(&tw_driver);
+       return pci_register_driver(&tw_driver);
 } /* End tw_init() */
 
 /* This function is called on driver exit */
index 31fe5ea159205bb15b861a615d39b7405679c728..bbd654a2b9b1e5e15562cbbb1d3915b7e961b227 100644 (file)
@@ -74,7 +74,7 @@ static char *tw_aen_string[] = {
        [0x00D] = "ERROR: Logical unit deleted: Unit #",
        [0x00F] = "WARNING: SMART threshold exceeded: Port #",
        [0x021] = "WARNING: ATA UDMA downgrade: Port #",
-       [0x021] = "WARNING: ATA UDMA upgrade: Port #",
+       [0x022] = "WARNING: ATA UDMA upgrade: Port #",
        [0x023] = "WARNING: Sector repair occurred: Port #",
        [0x024] = "ERROR: SBUF integrity check failure",
        [0x025] = "ERROR: Lost cached write: Port #",
index c6dfb6fa13bf4192583a52556867374d570374ec..9540eb8efdcbfc5b6db2051470bf9a203112fe59 100644 (file)
@@ -1016,7 +1016,7 @@ config SCSI_SYM53C8XX_MMIO
 
 config SCSI_IPR
        tristate "IBM Power Linux RAID adapter support"
-       depends on PCI && SCSI
+       depends on PCI && SCSI && ATA
        select FW_LOADER
        ---help---
          This driver supports the IBM Power Linux family RAID adapters.
@@ -1246,6 +1246,7 @@ config SCSI_QLOGICPTI
          module will be called qlogicpti.
 
 source "drivers/scsi/qla2xxx/Kconfig"
+source "drivers/scsi/qla4xxx/Kconfig"
 
 config SCSI_LPFC
        tristate "Emulex LightPulse Fibre Channel Support"
@@ -1262,8 +1263,8 @@ config SCSI_SEAGATE
          These are 8-bit SCSI controllers; the ST-01 is also supported by
          this driver.  It is explained in section 3.9 of the SCSI-HOWTO,
          available from <http://www.tldp.org/docs.html#howto>.  If it
-         doesn't work out of the box, you may have to change some settings in
-         <file:drivers/scsi/seagate.h>.
+         doesn't work out of the box, you may have to change some macros at
+         compiletime, which are described in <file:drivers/scsi/seagate.c>.
 
          To compile this driver as a module, choose M here: the
          module will be called seagate.
index 1ef951be7a5d1a5ff0716fa3f640df16386ab215..bcca39c3bcbf33096bb3fdc5c9a493996c2c9492 100644 (file)
@@ -84,6 +84,7 @@ obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o       qlogicfas.o
 obj-$(CONFIG_PCMCIA_QLOGIC)    += qlogicfas408.o
 obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o 
 obj-$(CONFIG_SCSI_QLA_FC)      += qla2xxx/
+obj-$(CONFIG_SCSI_QLA_ISCSI)   += qla4xxx/
 obj-$(CONFIG_SCSI_LPFC)                += lpfc/
 obj-$(CONFIG_SCSI_PAS16)       += pas16.o
 obj-$(CONFIG_SCSI_SEAGATE)     += seagate.o
index d7e9fab54c60eb5a4ff1ae6505ecc72b1b702311..2684150917e690e033d9fc27d91087f09ba5bc6e 100644 (file)
@@ -1187,7 +1187,7 @@ static struct pci_driver inia100_pci_driver = {
 
 static int __init inia100_init(void)
 {
-       return pci_module_init(&inia100_pci_driver);
+       return pci_register_driver(&inia100_pci_driver);
 }
 
 static void __exit inia100_exit(void)
index 8ad3ce945b9e5f36b20953af23ff1717d64403a4..a3266e066c00ca707a856f6035aca10198779433 100644 (file)
@@ -527,7 +527,8 @@ ahd_inw(struct ahd_softc *ahd, u_int port)
         * or have other side effects when the low byte is
         * read.
         */
-       return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port));
+       uint16_t r = ahd_inb(ahd, port+1) << 8;
+       return r | ahd_inb(ahd, port);
 }
 
 static __inline void
index 50a41eda580eb4daebac5be164fa8db2f8c8ebc2..4b53542018073c3dd1bd17f003648cbbc451d9e5 100644 (file)
@@ -198,7 +198,7 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 int
 ahd_linux_pci_init(void)
 {
-       return (pci_module_init(&aic79xx_pci_driver));
+       return pci_register_driver(&aic79xx_pci_driver);
 }
 
 void
index 2cc8a17ed8b4a565f7051fcef8238fe8329d8b38..8e1954cdd84f67cd114491ad0c0072d3aaec175f 100644 (file)
@@ -300,7 +300,8 @@ ahc_fetch_transinfo(struct ahc_softc *ahc, char channel, u_int our_id,
 static __inline uint16_t
 ahc_inw(struct ahc_softc *ahc, u_int port)
 {
-       return ((ahc_inb(ahc, port+1) << 8) | ahc_inb(ahc, port));
+       uint16_t r = ahc_inb(ahc, port+1) << 8;
+       return r | ahc_inb(ahc, port);
 }
 
 static __inline void
index 7e42f07a27f3d2879aec66a395f6504afe6a6fb0..d20ca514e9f36f11ba120dbe132338fa9c7f8ce6 100644 (file)
@@ -246,8 +246,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 int
 ahc_linux_pci_init(void)
 {
-       /* Translate error or zero return into zero or one */
-       return pci_module_init(&aic7xxx_pci_driver) ? 0 : 1;
+       return pci_register_driver(&aic7xxx_pci_driver);
 }
 
 void
index 10353379a0741e5f4f4f784ad230c4cba6249192..3eae8062a02ec56b511d944ebfecfbad71b5868a 100644 (file)
@@ -780,24 +780,26 @@ typedef enum {
 } ahc_bugs;
 
 struct aic7xxx_scb {
-        struct aic7xxx_hwscb  *hscb;          /* corresponding hardware scb */
-        Scsi_Cmnd             *cmd;              /* Scsi_Cmnd for this scb */
-        struct aic7xxx_scb    *q_next;        /* next scb in queue */
-        volatile scb_flag_type flags;         /* current state of scb */
-        struct hw_scatterlist *sg_list;       /* SG list in adapter format */
-        unsigned char          tag_action;
-        unsigned char          sg_count;
-        unsigned char          *sense_cmd;    /*
-                                               * Allocate 6 characters for
-                                               * sense command.
-                                               */
-       unsigned char          *cmnd;
-        unsigned int           sg_length; /* We init this during buildscb so we
-                                           * don't have to calculate anything
-                                           * during underflow/overflow/stat code
-                                           */
-        void                  *kmalloc_ptr;
-       struct aic7xxx_scb_dma *scb_dma;
+       struct aic7xxx_hwscb    *hscb;          /* corresponding hardware scb */
+       struct scsi_cmnd        *cmd;           /* scsi_cmnd for this scb */
+       struct aic7xxx_scb      *q_next;        /* next scb in queue */
+       volatile scb_flag_type  flags;          /* current state of scb */
+       struct hw_scatterlist   *sg_list;       /* SG list in adapter format */
+       unsigned char           tag_action;
+       unsigned char           sg_count;
+       unsigned char           *sense_cmd;     /*
+                                                * Allocate 6 characters for
+                                                * sense command.
+                                                */
+       unsigned char           *cmnd;
+       unsigned int            sg_length;      /*
+                                                * We init this during
+                                                * buildscb so we don't have
+                                                * to calculate anything during
+                                                * underflow/overflow/stat code
+                                                */
+       void                    *kmalloc_ptr;
+       struct aic7xxx_scb_dma  *scb_dma;
 };
 
 /*
@@ -918,79 +920,77 @@ struct aic7xxx_host {
    * We are grouping things here....first, items that get either read or
    * written with nearly every interrupt
    */
-  volatile long            flags;
-  ahc_feature              features;         /* chip features */
-  unsigned long            base;             /* card base address */
-  volatile unsigned char  __iomem *maddr;            /* memory mapped address */
-  unsigned long            isr_count;        /* Interrupt count */
-  unsigned long            spurious_int;
-  scb_data_type           *scb_data;
-  struct aic7xxx_cmd_queue {
-    Scsi_Cmnd *head;
-    Scsi_Cmnd *tail;
-  } completeq;
+       volatile long   flags;
+       ahc_feature     features;       /* chip features */
+       unsigned long   base;           /* card base address */
+       volatile unsigned char  __iomem *maddr; /* memory mapped address */
+       unsigned long   isr_count;      /* Interrupt count */
+       unsigned long   spurious_int;
+       scb_data_type   *scb_data;
+       struct aic7xxx_cmd_queue {
+               struct scsi_cmnd *head;
+               struct scsi_cmnd *tail;
+       } completeq;
 
-  /*
-   * Things read/written on nearly every entry into aic7xxx_queue()
-   */
-  volatile scb_queue_type  waiting_scbs;
-  unsigned char            unpause;          /* unpause value for HCNTRL */
-  unsigned char            pause;            /* pause value for HCNTRL */
-  volatile unsigned char   qoutfifonext;
-  volatile unsigned char   activescbs;       /* active scbs */
-  volatile unsigned char   max_activescbs;
-  volatile unsigned char   qinfifonext;
-  volatile unsigned char  *untagged_scbs;
-  volatile unsigned char  *qoutfifo;
-  volatile unsigned char  *qinfifo;
-
-  unsigned char            dev_last_queue_full[MAX_TARGETS];
-  unsigned char            dev_last_queue_full_count[MAX_TARGETS];
-  unsigned short          ultraenb;         /* Gets downloaded to card as a
-                                               bitmap */
-  unsigned short          discenable;       /* Gets downloaded to card as a
-                                               bitmap */
-  transinfo_type           user[MAX_TARGETS];
-
-  unsigned char            msg_buf[13];      /* The message for the target */
-  unsigned char            msg_type;
+       /*
+       * Things read/written on nearly every entry into aic7xxx_queue()
+       */
+       volatile scb_queue_type waiting_scbs;
+       unsigned char   unpause;        /* unpause value for HCNTRL */
+       unsigned char   pause;          /* pause value for HCNTRL */
+       volatile unsigned char  qoutfifonext;
+       volatile unsigned char  activescbs;     /* active scbs */
+       volatile unsigned char  max_activescbs;
+       volatile unsigned char  qinfifonext;
+       volatile unsigned char  *untagged_scbs;
+       volatile unsigned char  *qoutfifo;
+       volatile unsigned char  *qinfifo;
+
+       unsigned char   dev_last_queue_full[MAX_TARGETS];
+       unsigned char   dev_last_queue_full_count[MAX_TARGETS];
+       unsigned short  ultraenb; /* Gets downloaded to card as a bitmap */
+       unsigned short  discenable; /* Gets downloaded to card as a bitmap */
+       transinfo_type  user[MAX_TARGETS];
+
+       unsigned char   msg_buf[13];    /* The message for the target */
+       unsigned char   msg_type;
 #define MSG_TYPE_NONE              0x00
 #define MSG_TYPE_INITIATOR_MSGOUT  0x01
 #define MSG_TYPE_INITIATOR_MSGIN   0x02
-  unsigned char            msg_len;          /* Length of message */
-  unsigned char            msg_index;        /* Index into msg_buf array */
+       unsigned char   msg_len;        /* Length of message */
+       unsigned char   msg_index;      /* Index into msg_buf array */
 
 
-  /*
-   * We put the less frequently used host structure items after the more
-   * frequently used items to try and ease the burden on the cache subsystem.
-   * These entries are not *commonly* accessed, whereas the preceding entries
-   * are accessed very often.
-   */
-
-  unsigned int             irq;              /* IRQ for this adapter */
-  int                      instance;         /* aic7xxx instance number */
-  int                      scsi_id;          /* host adapter SCSI ID */
-  int                      scsi_id_b;        /* channel B for twin adapters */
-  unsigned int             bios_address;
-  int                      board_name_index;
-  unsigned short           bios_control;     /* bios control - SEEPROM */
-  unsigned short           adapter_control;  /* adapter control - SEEPROM */
-  struct pci_dev         *pdev;
-  unsigned char            pci_bus;
-  unsigned char            pci_device_fn;
-  struct seeprom_config    sc;
-  unsigned short           sc_type;
-  unsigned short           sc_size;
-  struct aic7xxx_host     *next;             /* allow for multiple IRQs */
-  struct Scsi_Host        *host;             /* pointer to scsi host */
-  struct list_head        aic_devs;         /* all aic_dev structs on host */
-  int                      host_no;          /* SCSI host number */
-  unsigned long            mbase;            /* I/O memory address */
-  ahc_chip                 chip;             /* chip type */
-  ahc_bugs                 bugs;
-  dma_addr_t              fifo_dma;         /* DMA handle for fifo arrays */
+       /*
+        * We put the less frequently used host structure items
+        * after the more frequently used items to try and ease
+        * the burden on the cache subsystem.
+        * These entries are not *commonly* accessed, whereas
+        * the preceding entries are accessed very often.
+        */
 
+       unsigned int    irq;            /* IRQ for this adapter */
+       int             instance;       /* aic7xxx instance number */
+       int             scsi_id;        /* host adapter SCSI ID */
+       int             scsi_id_b;      /* channel B for twin adapters */
+       unsigned int    bios_address;
+       int             board_name_index;
+       unsigned short  bios_control;           /* bios control - SEEPROM */
+       unsigned short  adapter_control;        /* adapter control - SEEPROM */
+       struct pci_dev  *pdev;
+       unsigned char   pci_bus;
+       unsigned char   pci_device_fn;
+       struct seeprom_config   sc;
+       unsigned short  sc_type;
+       unsigned short  sc_size;
+       struct aic7xxx_host     *next;  /* allow for multiple IRQs */
+       struct Scsi_Host        *host;  /* pointer to scsi host */
+       struct list_head         aic_devs; /* all aic_dev structs on host */
+       int             host_no;        /* SCSI host number */
+       unsigned long   mbase;          /* I/O memory address */
+       ahc_chip        chip;           /* chip type */
+       ahc_bugs        bugs;
+       dma_addr_t      fifo_dma;       /* DMA handle for fifo arrays */
 };
 
 /*
@@ -1271,7 +1271,7 @@ static void aic7xxx_set_syncrate(struct aic7xxx_host *p,
 static void aic7xxx_set_width(struct aic7xxx_host *p, int target, int channel,
                int lun, unsigned int width, unsigned int type,
                struct aic_dev_data *aic_dev);
-static void aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd);
+static void aic7xxx_panic_abort(struct aic7xxx_host *p, struct scsi_cmnd *cmd);
 static void aic7xxx_print_card(struct aic7xxx_host *p);
 static void aic7xxx_print_scratch_ram(struct aic7xxx_host *p);
 static void aic7xxx_print_sequencer(struct aic7xxx_host *p, int downloaded);
@@ -2626,7 +2626,7 @@ aic7xxx_allocate_scb(struct aic7xxx_host *p)
  *   we're finished.  This function queues the completed commands.
  *-F*************************************************************************/
 static void
-aic7xxx_queue_cmd_complete(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
+aic7xxx_queue_cmd_complete(struct aic7xxx_host *p, struct scsi_cmnd *cmd)
 {
   aic7xxx_position(cmd) = SCB_LIST_NULL;
   cmd->host_scribble = (char *)p->completeq.head;
@@ -2640,18 +2640,16 @@ aic7xxx_queue_cmd_complete(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
  * Description:
  *   Process the completed command queue.
  *-F*************************************************************************/
-static void
-aic7xxx_done_cmds_complete(struct aic7xxx_host *p)
+static void aic7xxx_done_cmds_complete(struct aic7xxx_host *p)
 {
-  Scsi_Cmnd *cmd;
-  
-  while (p->completeq.head != NULL)
-  {
-    cmd = p->completeq.head;
-    p->completeq.head = (Scsi_Cmnd *)cmd->host_scribble;
-    cmd->host_scribble = NULL;
-    cmd->scsi_done(cmd);
-  }
+       struct scsi_cmnd *cmd;
+
+       while (p->completeq.head != NULL) {
+               cmd = p->completeq.head;
+               p->completeq.head = (struct scsi_Cmnd *) cmd->host_scribble;
+               cmd->host_scribble = NULL;
+               cmd->scsi_done(cmd);
+       }
 }
 
 /*+F*************************************************************************
@@ -2687,11 +2685,11 @@ aic7xxx_free_scb(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
 static void
 aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
 {
-  Scsi_Cmnd *cmd = scb->cmd;
-  struct aic_dev_data *aic_dev = cmd->device->hostdata;
-  int tindex = TARGET_INDEX(cmd);
-  struct aic7xxx_scb *scbp;
-  unsigned char queue_depth;
+       struct scsi_cmnd *cmd = scb->cmd;
+       struct aic_dev_data *aic_dev = cmd->device->hostdata;
+       int tindex = TARGET_INDEX(cmd);
+       struct aic7xxx_scb *scbp;
+       unsigned char queue_depth;
 
   if (cmd->use_sg > 1)
   {
@@ -2891,7 +2889,7 @@ aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
  *   aic7xxx_run_done_queue
  *
  * Description:
- *   Calls the aic7xxx_done() for the Scsi_Cmnd of each scb in the
+ *   Calls the aic7xxx_done() for the scsi_cmnd of each scb in the
  *   aborted list, and adds each scb to the free list.  If complete
  *   is TRUE, we also process the commands complete list.
  *-F*************************************************************************/
@@ -3826,9 +3824,9 @@ aic7xxx_construct_wdtr(struct aic7xxx_host *p, unsigned char bus_width)
 static void
 aic7xxx_calculate_residual (struct aic7xxx_host *p, struct aic7xxx_scb *scb)
 {
-  struct aic7xxx_hwscb *hscb;
-  Scsi_Cmnd *cmd;
-  int actual, i;
+       struct aic7xxx_hwscb *hscb;
+       struct scsi_cmnd *cmd;
+       int actual, i;
 
   cmd = scb->cmd;
   hscb = scb->hscb;
@@ -4219,20 +4217,20 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat)
 
     case BAD_STATUS:
       {
-        unsigned char scb_index;
-        struct aic7xxx_hwscb *hscb;
-        Scsi_Cmnd *cmd;
-
-        /* The sequencer will notify us when a command has an error that
-         * would be of interest to the kernel.  This allows us to leave
-         * the sequencer running in the common case of command completes
-         * without error.  The sequencer will have DMA'd the SCB back
-         * up to us, so we can reference the drivers SCB array.
-         *
-         * Set the default return value to 0 indicating not to send
-         * sense.  The sense code will change this if needed and this
-         * reduces code duplication.
-         */
+       unsigned char scb_index;
+       struct aic7xxx_hwscb *hscb;
+       struct scsi_cmnd *cmd;
+
+       /* The sequencer will notify us when a command has an error that
+        * would be of interest to the kernel.  This allows us to leave
+        * the sequencer running in the common case of command completes
+        * without error.  The sequencer will have DMA'd the SCB back
+        * up to us, so we can reference the drivers SCB array.
+        *
+        * Set the default return value to 0 indicating not to send
+        * sense.  The sense code will change this if needed and this
+        * reduces code duplication.
+        */
         aic_outb(p, 0, RETURN_1);
         scb_index = aic_inb(p, SCB_TAG);
         if (scb_index > p->scb_data->numscbs)
@@ -5800,9 +5798,9 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat)
   }
   else if ((status & SELTO) != 0)
   {
-    unsigned char scbptr;
-    unsigned char nextscb;
-    Scsi_Cmnd *cmd;
+       unsigned char scbptr;
+       unsigned char nextscb;
+       struct scsi_cmnd *cmd;
 
     scbptr = aic_inb(p, WAITING_SCBH);
     if (scbptr > p->scb_data->maxhscbs)
@@ -5941,11 +5939,11 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat)
     /*
      * Determine the bus phase and queue an appropriate message.
      */
-    char  *phase;
-    Scsi_Cmnd *cmd;
-    unsigned char mesg_out = MSG_NOOP;
-    unsigned char lastphase = aic_inb(p, LASTPHASE);
-    unsigned char sstat2 = aic_inb(p, SSTAT2);
+       char  *phase;
+       struct scsi_cmnd *cmd;
+       unsigned char mesg_out = MSG_NOOP;
+       unsigned char lastphase = aic_inb(p, LASTPHASE);
+       unsigned char sstat2 = aic_inb(p, SSTAT2);
 
     cmd = scb->cmd;
     switch (lastphase)
@@ -6248,10 +6246,10 @@ aic7xxx_check_scbs(struct aic7xxx_host *p, char *buffer)
 static void
 aic7xxx_handle_command_completion_intr(struct aic7xxx_host *p)
 {
-  struct aic7xxx_scb *scb = NULL;
-  struct aic_dev_data *aic_dev;
-  Scsi_Cmnd *cmd;
-  unsigned char scb_index, tindex;
+       struct aic7xxx_scb *scb = NULL;
+       struct aic_dev_data *aic_dev;
+       struct scsi_cmnd *cmd;
+       unsigned char scb_index, tindex;
 
 #ifdef AIC7XXX_VERBOSE_DEBUGGING
   if( (p->isr_count < 16) && (aic7xxx_verbose > 0xffff) )
@@ -10131,9 +10129,8 @@ skip_pci_controller:
  * Description:
  *   Build a SCB.
  *-F*************************************************************************/
-static void
-aic7xxx_buildscb(struct aic7xxx_host *p, Scsi_Cmnd *cmd,
-    struct aic7xxx_scb *scb)
+static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd,
+                            struct aic7xxx_scb *scb)
 {
   unsigned short mask;
   struct aic7xxx_hwscb *hscb;
@@ -10285,8 +10282,7 @@ aic7xxx_buildscb(struct aic7xxx_host *p, Scsi_Cmnd *cmd,
  * Description:
  *   Queue a SCB to the controller.
  *-F*************************************************************************/
-static int
-aic7xxx_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
+static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
 {
   struct aic7xxx_host *p;
   struct aic7xxx_scb *scb;
@@ -10319,11 +10315,11 @@ aic7xxx_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
   }
   scb->cmd = cmd;
 
-  /*
-   * Make sure the Scsi_Cmnd pointer is saved, the struct it points to
-   * is set up properly, and the parity error flag is reset, then send
-   * the SCB to the sequencer and watch the fun begin.
-   */
+       /*
+       * Make sure the scsi_cmnd pointer is saved, the struct it points to
+       * is set up properly, and the parity error flag is reset, then send
+       * the SCB to the sequencer and watch the fun begin.
+       */
   aic7xxx_position(cmd) = scb->hscb->tag;
   cmd->scsi_done = fn;
   cmd->result = DID_OK;
@@ -10356,8 +10352,7 @@ aic7xxx_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
  *   aborted, then we will reset the channel and have all devices renegotiate.
  *   Returns an enumerated type that indicates the status of the operation.
  *-F*************************************************************************/
-static int
-__aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
+static int __aic7xxx_bus_device_reset(struct scsi_cmnd *cmd)
 {
   struct aic7xxx_host  *p;
   struct aic7xxx_scb   *scb;
@@ -10550,8 +10545,7 @@ __aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
     return SUCCESS;
 }
 
-static int
-aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
+static int aic7xxx_bus_device_reset(struct scsi_cmnd *cmd)
 {
       int rc;
 
@@ -10570,8 +10564,7 @@ aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
  * Description:
  *   Abort the current SCSI command(s).
  *-F*************************************************************************/
-static void
-aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
+static void aic7xxx_panic_abort(struct aic7xxx_host *p, struct scsi_cmnd *cmd)
 {
 
   printk("aic7xxx driver version %s\n", AIC7XXX_C_VERSION);
@@ -10595,8 +10588,7 @@ aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
  * Description:
  *   Abort the current SCSI command(s).
  *-F*************************************************************************/
-static int
-__aic7xxx_abort(Scsi_Cmnd *cmd)
+static int __aic7xxx_abort(struct scsi_cmnd *cmd)
 {
   struct aic7xxx_scb  *scb = NULL;
   struct aic7xxx_host *p;
@@ -10813,8 +10805,7 @@ success:
   return SUCCESS;
 }
 
-static int
-aic7xxx_abort(Scsi_Cmnd *cmd)
+static int aic7xxx_abort(struct scsi_cmnd *cmd)
 {
        int rc;
 
@@ -10836,8 +10827,7 @@ aic7xxx_abort(Scsi_Cmnd *cmd)
  *   DEVICE RESET message - on the offending target before pulling
  *   the SCSI bus reset line.
  *-F*************************************************************************/
-static int
-aic7xxx_reset(Scsi_Cmnd *cmd)
+static int aic7xxx_reset(struct scsi_cmnd *cmd)
 {
   struct aic7xxx_scb *scb;
   struct aic7xxx_host *p;
index 0ed391d8ee84b5f51e4514131d31c7ea7935a962..c83fe751d0bb43941212d27385a90adad3a33b5b 100644 (file)
@@ -28,6 +28,7 @@ config SCSI_AIC94XX
        tristate "Adaptec AIC94xx SAS/SATA support"
        depends on PCI
        select SCSI_SAS_LIBSAS
+       select FW_LOADER
        help
                This driver supports Adaptec's SAS/SATA 3Gb/s 64 bit PCI-X
                AIC94xx chip based host adapters.
index 734adc9d5206c1f84177a5fadccc197264ffa0c5..99743ca29ca147df75dacd12396be71da90266c9 100644 (file)
@@ -309,11 +309,29 @@ static ssize_t asd_show_dev_pcba_sn(struct device *dev,
 }
 static DEVICE_ATTR(pcba_sn, S_IRUGO, asd_show_dev_pcba_sn, NULL);
 
-static void asd_create_dev_attrs(struct asd_ha_struct *asd_ha)
+static int asd_create_dev_attrs(struct asd_ha_struct *asd_ha)
 {
-       device_create_file(&asd_ha->pcidev->dev, &dev_attr_revision);
-       device_create_file(&asd_ha->pcidev->dev, &dev_attr_bios_build);
-       device_create_file(&asd_ha->pcidev->dev, &dev_attr_pcba_sn);
+       int err;
+
+       err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_revision);
+       if (err)
+               return err;
+
+       err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_bios_build);
+       if (err)
+               goto err_rev;
+
+       err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_pcba_sn);
+       if (err)
+               goto err_biosb;
+
+       return 0;
+
+err_biosb:
+       device_remove_file(&asd_ha->pcidev->dev, &dev_attr_bios_build);
+err_rev:
+       device_remove_file(&asd_ha->pcidev->dev, &dev_attr_revision);
+       return err;
 }
 
 static void asd_remove_dev_attrs(struct asd_ha_struct *asd_ha)
@@ -645,7 +663,9 @@ static int __devinit asd_pci_probe(struct pci_dev *dev,
        }
        ASD_DPRINTK("escbs posted\n");
 
-       asd_create_dev_attrs(asd_ha);
+       err = asd_create_dev_attrs(asd_ha);
+       if (err)
+               goto Err_dev_attrs;
 
        err = asd_register_sas_ha(asd_ha);
        if (err)
@@ -668,6 +688,7 @@ Err_en_phys:
        asd_unregister_sas_ha(asd_ha);
 Err_reg_sas:
        asd_remove_dev_attrs(asd_ha);
+Err_dev_attrs:
 Err_escbs:
        asd_disable_ints(asd_ha);
        free_irq(dev->irq, asd_ha);
@@ -754,9 +775,9 @@ static ssize_t asd_version_show(struct device_driver *driver, char *buf)
 }
 static DRIVER_ATTR(version, S_IRUGO, asd_version_show, NULL);
 
-static void asd_create_driver_attrs(struct device_driver *driver)
+static int asd_create_driver_attrs(struct device_driver *driver)
 {
-       driver_create_file(driver, &driver_attr_version);
+       return driver_create_file(driver, &driver_attr_version);
 }
 
 static void asd_remove_driver_attrs(struct device_driver *driver)
@@ -834,10 +855,14 @@ static int __init aic94xx_init(void)
        if (err)
                goto out_release_transport;
 
-       asd_create_driver_attrs(&aic94xx_pci_driver.driver);
+       err = asd_create_driver_attrs(&aic94xx_pci_driver.driver);
+       if (err)
+               goto out_unregister_pcidrv;
 
        return err;
 
+ out_unregister_pcidrv:
+       pci_unregister_driver(&aic94xx_pci_driver);
  out_release_transport:
        sas_release_transport(aic94xx_transport_template);
  out_destroy_caches:
index 7621e3fa37b15fb96333eea7ed6cd2e6b89948b1..0525d672e1e60c5aca68ffaff242eb5c1736ad7b 100644 (file)
 unsigned int sdtr_period = SDTR_PERIOD;
 unsigned int sdtr_size   = SDTR_SIZE;
 
-static void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result);
+static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
+                          unsigned int result);
 static int acornscsi_reconnect_finish(AS_Host *host);
 static void acornscsi_dma_cleanup(AS_Host *host);
 static void acornscsi_abortcmd(AS_Host *host, unsigned char tag);
@@ -712,7 +713,7 @@ static
 intr_ret_t acornscsi_kick(AS_Host *host)
 {
     int from_queue = 0;
-    Scsi_Cmnd *SCpnt;
+    struct scsi_cmnd *SCpnt;
 
     /* first check to see if a command is waiting to be executed */
     SCpnt = host->origSCpnt;
@@ -796,15 +797,15 @@ intr_ret_t acornscsi_kick(AS_Host *host)
 }    
 
 /*
- * Function: void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result)
+ * Function: void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, unsigned int result)
  * Purpose : complete processing for command
  * Params  : host   - interface that completed
  *          result - driver byte of result
  */
-static
-void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result)
+static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
+                          unsigned int result)
 {
-    Scsi_Cmnd *SCpnt = *SCpntp;
+       struct scsi_cmnd *SCpnt = *SCpntp;
 
     /* clean up */
     sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
@@ -1318,7 +1319,7 @@ acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int
 static void
 acornscsi_sendcommand(AS_Host *host)
 {
-    Scsi_Cmnd *SCpnt = host->SCpnt;
+       struct scsi_cmnd *SCpnt = host->SCpnt;
 
     sbic_arm_write(host->scsi.io_port, SBIC_TRANSCNTH, 0);
     sbic_arm_writenext(host->scsi.io_port, 0);
@@ -1693,7 +1694,7 @@ void acornscsi_message(AS_Host *host)
                acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
                msgqueue_addmsg(&host->scsi.msgs, 1, ABORT);
            } else {
-               Scsi_Cmnd *SCpnt = host->SCpnt;
+               struct scsi_cmnd *SCpnt = host->SCpnt;
 
                acornscsi_dma_cleanup(host);
 
@@ -2509,13 +2510,14 @@ acornscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
  */
 
 /*
- * Function : acornscsi_queuecmd(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+ * Function : acornscsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
  * Purpose  : queues a SCSI command
  * Params   : cmd  - SCSI command
  *           done - function called on completion, with pointer to command descriptor
  * Returns  : 0, or < 0 on error.
  */
-int acornscsi_queuecmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
+                      void (*done)(struct scsi_cmnd *))
 {
     AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
 
@@ -2565,17 +2567,18 @@ int acornscsi_queuecmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 }
 
 /*
- * Prototype: void acornscsi_reportstatus(Scsi_Cmnd **SCpntp1, Scsi_Cmnd **SCpntp2, int result)
+ * Prototype: void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, struct scsi_cmnd **SCpntp2, int result)
  * Purpose  : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2
  * Params   : SCpntp1 - pointer to command to return
  *           SCpntp2 - pointer to command to check
  *           result  - result to pass back to mid-level done function
  * Returns  : *SCpntp2 = NULL if *SCpntp1 is the same command structure as *SCpntp2.
  */
-static inline
-void acornscsi_reportstatus(Scsi_Cmnd **SCpntp1, Scsi_Cmnd **SCpntp2, int result)
+static inline void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1,
+                                         struct scsi_cmnd **SCpntp2,
+                                         int result)
 {
-    Scsi_Cmnd *SCpnt = *SCpntp1;
+       struct scsi_cmnd *SCpnt = *SCpntp1;
 
     if (SCpnt) {
        *SCpntp1 = NULL;
@@ -2591,13 +2594,12 @@ void acornscsi_reportstatus(Scsi_Cmnd **SCpntp1, Scsi_Cmnd **SCpntp2, int result
 enum res_abort { res_not_running, res_success, res_success_clear, res_snooze };
 
 /*
- * Prototype: enum res acornscsi_do_abort(Scsi_Cmnd *SCpnt)
+ * Prototype: enum res acornscsi_do_abort(struct scsi_cmnd *SCpnt)
  * Purpose  : abort a command on this host
  * Params   : SCpnt - command to abort
  * Returns  : our abort status
  */
-static enum res_abort
-acornscsi_do_abort(AS_Host *host, Scsi_Cmnd *SCpnt)
+static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt)
 {
        enum res_abort res = res_not_running;
 
@@ -2684,12 +2686,12 @@ acornscsi_do_abort(AS_Host *host, Scsi_Cmnd *SCpnt)
 }
 
 /*
- * Prototype: int acornscsi_abort(Scsi_Cmnd *SCpnt)
+ * Prototype: int acornscsi_abort(struct scsi_cmnd *SCpnt)
  * Purpose  : abort a command on this host
  * Params   : SCpnt - command to abort
  * Returns  : one of SCSI_ABORT_ macros
  */
-int acornscsi_abort(Scsi_Cmnd *SCpnt)
+int acornscsi_abort(struct scsi_cmnd *SCpnt)
 {
        AS_Host *host = (AS_Host *) SCpnt->device->host->hostdata;
        int result;
@@ -2770,16 +2772,16 @@ int acornscsi_abort(Scsi_Cmnd *SCpnt)
 }
 
 /*
- * Prototype: int acornscsi_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
+ * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
  * Purpose  : reset a command on this host/reset this host
  * Params   : SCpnt  - command causing reset
  *           result - what type of reset to perform
  * Returns  : one of SCSI_RESET_ macros
  */
-int acornscsi_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
+int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
 {
-    AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
-    Scsi_Cmnd *SCptr;
+       AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
+       struct scsi_cmnd *SCptr;
     
     host->stats.resets += 1;
 
index 2142290f84046b42ed89b2ef57774ff7a4ea4151..d11424b89f4237627bbf88c216c25fad2559f32f 100644 (file)
@@ -277,8 +277,8 @@ struct status_entry {
 typedef struct acornscsi_hostdata {
     /* miscellaneous */
     struct Scsi_Host   *host;                  /* host                                 */
-    Scsi_Cmnd          *SCpnt;                 /* currently processing command         */
-    Scsi_Cmnd          *origSCpnt;             /* original connecting command          */
+    struct scsi_cmnd   *SCpnt;                 /* currently processing command         */
+    struct scsi_cmnd   *origSCpnt;             /* original connecting command          */
 
     /* driver information */
     struct {
index 4cf7afc31cc7f00e24414f7a08d1cd3e8733ed7b..e05f0c2fc9123a7948216d785c0c6d36e172b533 100644 (file)
@@ -297,8 +297,8 @@ fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap)
        printk("scsi%d.%c: %s", info->host->host_no, target, buf);
 }
 
-static void
-fas216_log_command(FAS216_Info *info, int level, Scsi_Cmnd *SCpnt, char *fmt, ...)
+static void fas216_log_command(FAS216_Info *info, int level,
+                              struct scsi_cmnd *SCpnt, char *fmt, ...)
 {
        va_list args;
 
@@ -1662,7 +1662,7 @@ irqreturn_t fas216_intr(FAS216_Info *info)
        return handled;
 }
 
-static void __fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+static void __fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt)
 {
        int tot_msglen;
 
@@ -1754,7 +1754,7 @@ static int parity_test(FAS216_Info *info, int target)
        return info->device[target].parity_check;
 }
 
-static void fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+static void fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt)
 {
        int disconnect_ok;
 
@@ -1808,7 +1808,7 @@ static void fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
        __fas216_start_command(info, SCpnt);
 }
 
-static void fas216_allocate_tag(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+static void fas216_allocate_tag(FAS216_Info *info, struct scsi_cmnd *SCpnt)
 {
 #ifdef SCSI2_TAG
        /*
@@ -1842,7 +1842,8 @@ static void fas216_allocate_tag(FAS216_Info *info, Scsi_Cmnd *SCpnt)
        }
 }
 
-static void fas216_do_bus_device_reset(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+static void fas216_do_bus_device_reset(FAS216_Info *info,
+                                      struct scsi_cmnd *SCpnt)
 {
        struct message *msg;
 
@@ -1890,7 +1891,7 @@ static void fas216_do_bus_device_reset(FAS216_Info *info, Scsi_Cmnd *SCpnt)
  */
 static void fas216_kick(FAS216_Info *info)
 {
-       Scsi_Cmnd *SCpnt = NULL;
+       struct scsi_cmnd *SCpnt = NULL;
 #define TYPE_OTHER     0
 #define TYPE_RESET     1
 #define TYPE_QUEUE     2
@@ -1978,8 +1979,8 @@ static void fas216_kick(FAS216_Info *info)
 /*
  * Clean up from issuing a BUS DEVICE RESET message to a device.
  */
-static void
-fas216_devicereset_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
+static void fas216_devicereset_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
+                                   unsigned int result)
 {
        fas216_log(info, LOG_ERROR, "fas216 device reset complete");
 
@@ -1996,8 +1997,8 @@ fas216_devicereset_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result
  *
  * Finish processing automatic request sense command
  */
-static void
-fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
+static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
+                              unsigned int result)
 {
        fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
                   "request sense complete, result=0x%04x%02x%02x",
@@ -2030,7 +2031,7 @@ fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
  * Finish processing of standard command
  */
 static void
-fas216_std_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
+fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result)
 {
        info->stats.fins += 1;
 
@@ -2142,8 +2143,8 @@ request_sense:
  */
 static void fas216_done(FAS216_Info *info, unsigned int result)
 {
-       void (*fn)(FAS216_Info *, Scsi_Cmnd *, unsigned int);
-       Scsi_Cmnd *SCpnt;
+       void (*fn)(FAS216_Info *, struct scsi_cmnd *, unsigned int);
+       struct scsi_cmnd *SCpnt;
        unsigned long flags;
 
        fas216_checkmagic(info);
@@ -2182,7 +2183,7 @@ static void fas216_done(FAS216_Info *info, unsigned int result)
        info->device[SCpnt->device->id].parity_check = 0;
        clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, info->busyluns);
 
-       fn = (void (*)(FAS216_Info *, Scsi_Cmnd *, unsigned int))SCpnt->host_scribble;
+       fn = (void (*)(FAS216_Info *, struct scsi_cmnd *, unsigned int))SCpnt->host_scribble;
        fn(info, SCpnt, result);
 
        if (info->scsi.irq != NO_IRQ) {
@@ -2207,7 +2208,8 @@ no_command:
  * Returns: 0 on success, else error.
  * Notes: io_request_lock is held, interrupts are disabled.
  */
-int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+int fas216_queue_command(struct scsi_cmnd *SCpnt,
+                        void (*done)(struct scsi_cmnd *))
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
        int result;
@@ -2254,7 +2256,7 @@ int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
  *
  * Trigger restart of a waiting thread in fas216_command
  */
-static void fas216_internal_done(Scsi_Cmnd *SCpnt)
+static void fas216_internal_done(struct scsi_cmnd *SCpnt)
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
 
@@ -2271,7 +2273,8 @@ static void fas216_internal_done(Scsi_Cmnd *SCpnt)
  * Returns: scsi result code.
  * Notes: io_request_lock is held, interrupts are disabled.
  */
-int fas216_noqueue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
+                          void (*done)(struct scsi_cmnd *))
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
 
@@ -2350,7 +2353,8 @@ enum res_find {
  * Decide how to abort a command.
  * Returns: abort status
  */
-static enum res_find fas216_find_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+static enum res_find fas216_find_command(FAS216_Info *info,
+                                        struct scsi_cmnd *SCpnt)
 {
        enum res_find res = res_failed;
 
@@ -2417,7 +2421,7 @@ static enum res_find fas216_find_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
  * Returns: FAILED if unable to abort
  * Notes: io_request_lock is taken, and irqs are disabled
  */
-int fas216_eh_abort(Scsi_Cmnd *SCpnt)
+int fas216_eh_abort(struct scsi_cmnd *SCpnt)
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
        int result = FAILED;
@@ -2474,7 +2478,7 @@ int fas216_eh_abort(Scsi_Cmnd *SCpnt)
  * Notes: We won't be re-entered, so we'll only have one device
  * reset on the go at one time.
  */
-int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
+int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
        unsigned long flags;
@@ -2555,7 +2559,7 @@ int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
  * Returns: FAILED if unable to reset.
  * Notes: Further commands are blocked.
  */
-int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
+int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt)
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
        unsigned long flags;
@@ -2655,7 +2659,7 @@ static void fas216_init_chip(FAS216_Info *info)
  * Returns: FAILED if unable to reset.
  * Notes: io_request_lock is taken, and irqs are disabled
  */
-int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
+int fas216_eh_host_reset(struct scsi_cmnd *SCpnt)
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
 
index 540914d6fd32dc3a0ad29fad7c5330e387f4ec7c..00e5f055afdc5fff16d80cf7e15ab123dd209b3f 100644 (file)
@@ -218,11 +218,11 @@ typedef struct {
        unsigned long           magic_start;
        spinlock_t              host_lock;
        struct Scsi_Host        *host;                  /* host                                 */
-       Scsi_Cmnd               *SCpnt;                 /* currently processing command         */
-       Scsi_Cmnd               *origSCpnt;             /* original connecting command          */
-       Scsi_Cmnd               *reqSCpnt;              /* request sense command                */
-       Scsi_Cmnd               *rstSCpnt;              /* reset command                        */
-       Scsi_Cmnd               *pending_SCpnt[8];      /* per-device pending commands          */
+       struct scsi_cmnd        *SCpnt;                 /* currently processing command         */
+       struct scsi_cmnd        *origSCpnt;             /* original connecting command          */
+       struct scsi_cmnd        *reqSCpnt;              /* request sense command                */
+       struct scsi_cmnd        *rstSCpnt;              /* reset command                        */
+       struct scsi_cmnd        *pending_SCpnt[8];      /* per-device pending commands          */
        int                     next_pending;           /* next pending device                  */
 
        /*
@@ -328,21 +328,23 @@ extern int fas216_init (struct Scsi_Host *instance);
  */
 extern int fas216_add (struct Scsi_Host *instance, struct device *dev);
 
-/* Function: int fas216_queue_command (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+/* Function: int fas216_queue_command(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
  * Purpose : queue a command for adapter to process.
  * Params  : SCpnt - Command to queue
  *          done  - done function to call once command is complete
  * Returns : 0 - success, else error
  */
-extern int fas216_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+extern int fas216_queue_command(struct scsi_cmnd *,
+                               void (*done)(struct scsi_cmnd *));
 
-/* Function: int fas216_noqueue_command (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+/* Function: int fas216_noqueue_command(istruct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
  * Purpose : queue a command for adapter to process, and process it to completion.
  * Params  : SCpnt - Command to queue
  *          done  - done function to call once command is complete
  * Returns : 0 - success, else error
  */
-extern int fas216_noqueue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+extern int fas216_noqueue_command(struct scsi_cmnd *,
+                                 void (*done)(struct scsi_cmnd *));
 
 /* Function: irqreturn_t fas216_intr (FAS216_Info *info)
  * Purpose : handle interrupts from the interface to progress a command
@@ -363,32 +365,32 @@ extern int fas216_print_host(FAS216_Info *info, char *buffer);
 extern int fas216_print_stats(FAS216_Info *info, char *buffer);
 extern int fas216_print_devices(FAS216_Info *info, char *buffer);
 
-/* Function: int fas216_eh_abort(Scsi_Cmnd *SCpnt)
+/* Function: int fas216_eh_abort(struct scsi_cmnd *SCpnt)
  * Purpose : abort this command
  * Params  : SCpnt - command to abort
  * Returns : FAILED if unable to abort
  */
-extern int fas216_eh_abort(Scsi_Cmnd *SCpnt);
+extern int fas216_eh_abort(struct scsi_cmnd *SCpnt);
 
-/* Function: int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
+/* Function: int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
  * Purpose : Reset the device associated with this command
  * Params  : SCpnt - command specifing device to reset
  * Returns : FAILED if unable to reset
  */
-extern int fas216_eh_device_reset(Scsi_Cmnd *SCpnt);
+extern int fas216_eh_device_reset(struct scsi_cmnd *SCpnt);
 
-/* Function: int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
+/* Function: int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt)
  * Purpose : Reset the complete bus associated with this command
  * Params  : SCpnt - command specifing bus to reset
  * Returns : FAILED if unable to reset
  */
-extern int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt);
+extern int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt);
 
-/* Function: int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
+/* Function: int fas216_eh_host_reset(struct scsi_cmnd *SCpnt)
  * Purpose : Reset the host associated with this command
  * Params  : SCpnt - command specifing host to reset
  * Returns : FAILED if unable to reset
  */
-extern int fas216_eh_host_reset(Scsi_Cmnd *SCpnt);
+extern int fas216_eh_host_reset(struct scsi_cmnd *SCpnt);
 
 #endif /* FAS216_H */
index 8caa5903ce3841d3ee9c4b3f7f1443ce7fb349b9..cb11ccef54e5104d2825d4e6bfdfcefa8260672c 100644 (file)
@@ -29,7 +29,7 @@
 
 typedef struct queue_entry {
        struct list_head   list;
-       Scsi_Cmnd          *SCpnt;
+       struct scsi_cmnd   *SCpnt;
 #ifdef DEBUG
        unsigned long      magic;
 #endif
@@ -96,14 +96,14 @@ void queue_free (Queue_t *queue)
      
 
 /*
- * Function: int queue_add_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt, int head)
+ * Function: int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head)
  * Purpose : Add a new command onto a queue, adding REQUEST_SENSE to head.
  * Params  : queue - destination queue
  *          SCpnt - command to add
  *          head  - add command to head of queue
  * Returns : 0 on error, !0 on success
  */
-int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head)
+int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head)
 {
        unsigned long flags;
        struct list_head *l;
@@ -134,7 +134,7 @@ empty:
        return ret;
 }
 
-static Scsi_Cmnd *__queue_remove(Queue_t *queue, struct list_head *ent)
+static struct scsi_cmnd *__queue_remove(Queue_t *queue, struct list_head *ent)
 {
        QE_t *q;
 
@@ -152,17 +152,17 @@ static Scsi_Cmnd *__queue_remove(Queue_t *queue, struct list_head *ent)
 }
 
 /*
- * Function: Scsi_Cmnd *queue_remove_exclude (queue, exclude)
+ * Function: struct scsi_cmnd *queue_remove_exclude (queue, exclude)
  * Purpose : remove a SCSI command from a queue
  * Params  : queue   - queue to remove command from
  *          exclude - bit array of target&lun which is busy
- * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available
+ * Returns : struct scsi_cmnd if successful (and a reference), or NULL if no command available
  */
-Scsi_Cmnd *queue_remove_exclude(Queue_t *queue, unsigned long *exclude)
+struct scsi_cmnd *queue_remove_exclude(Queue_t *queue, unsigned long *exclude)
 {
        unsigned long flags;
        struct list_head *l;
-       Scsi_Cmnd *SCpnt = NULL;
+       struct scsi_cmnd *SCpnt = NULL;
 
        spin_lock_irqsave(&queue->queue_lock, flags);
        list_for_each(l, &queue->head) {
@@ -178,15 +178,15 @@ Scsi_Cmnd *queue_remove_exclude(Queue_t *queue, unsigned long *exclude)
 }
 
 /*
- * Function: Scsi_Cmnd *queue_remove (queue)
+ * Function: struct scsi_cmnd *queue_remove (queue)
  * Purpose : removes first SCSI command from a queue
  * Params  : queue   - queue to remove command from
- * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available
+ * Returns : struct scsi_cmnd if successful (and a reference), or NULL if no command available
  */
-Scsi_Cmnd *queue_remove(Queue_t *queue)
+struct scsi_cmnd *queue_remove(Queue_t *queue)
 {
        unsigned long flags;
-       Scsi_Cmnd *SCpnt = NULL;
+       struct scsi_cmnd *SCpnt = NULL;
 
        spin_lock_irqsave(&queue->queue_lock, flags);
        if (!list_empty(&queue->head))
@@ -197,19 +197,20 @@ Scsi_Cmnd *queue_remove(Queue_t *queue)
 }
 
 /*
- * Function: Scsi_Cmnd *queue_remove_tgtluntag (queue, target, lun, tag)
+ * Function: struct scsi_cmnd *queue_remove_tgtluntag (queue, target, lun, tag)
  * Purpose : remove a SCSI command from the queue for a specified target/lun/tag
  * Params  : queue  - queue to remove command from
  *          target - target that we want
  *          lun    - lun on device
  *          tag    - tag on device
- * Returns : Scsi_Cmnd if successful, or NULL if no command satisfies requirements
+ * Returns : struct scsi_cmnd if successful, or NULL if no command satisfies requirements
  */
-Scsi_Cmnd *queue_remove_tgtluntag (Queue_t *queue, int target, int lun, int tag)
+struct scsi_cmnd *queue_remove_tgtluntag(Queue_t *queue, int target, int lun,
+                                        int tag)
 {
        unsigned long flags;
        struct list_head *l;
-       Scsi_Cmnd *SCpnt = NULL;
+       struct scsi_cmnd *SCpnt = NULL;
 
        spin_lock_irqsave(&queue->queue_lock, flags);
        list_for_each(l, &queue->head) {
@@ -275,13 +276,13 @@ int queue_probetgtlun (Queue_t *queue, int target, int lun)
 }
 
 /*
- * Function: int queue_remove_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt)
+ * Function: int queue_remove_cmd(Queue_t *queue, struct scsi_cmnd *SCpnt)
  * Purpose : remove a specific command from the queues
  * Params  : queue - queue to look in
  *          SCpnt - command to find
  * Returns : 0 if not found
  */
-int queue_remove_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt)
+int queue_remove_cmd(Queue_t *queue, struct scsi_cmnd *SCpnt)
 {
        unsigned long flags;
        struct list_head *l;
index 0c9dec4c1716a14903162ddd18be0388ecc700ee..3c519c9237b27410f07376efa5cf91dbe96916e4 100644 (file)
@@ -32,46 +32,48 @@ extern int queue_initialise (Queue_t *queue);
 extern void queue_free (Queue_t *queue);
 
 /*
- * Function: Scsi_Cmnd *queue_remove (queue)
+ * Function: struct scsi_cmnd *queue_remove (queue)
  * Purpose : removes first SCSI command from a queue
  * Params  : queue   - queue to remove command from
- * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available
+ * Returns : struct scsi_cmnd if successful (and a reference), or NULL if no command available
  */
-extern Scsi_Cmnd *queue_remove (Queue_t *queue);
+extern struct scsi_cmnd *queue_remove (Queue_t *queue);
 
 /*
- * Function: Scsi_Cmnd *queue_remove_exclude_ref (queue, exclude)
+ * Function: struct scsi_cmnd *queue_remove_exclude_ref (queue, exclude)
  * Purpose : remove a SCSI command from a queue
  * Params  : queue   - queue to remove command from
  *          exclude - array of busy LUNs
- * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available
+ * Returns : struct scsi_cmnd if successful (and a reference), or NULL if no command available
  */
-extern Scsi_Cmnd *queue_remove_exclude (Queue_t *queue, unsigned long *exclude);
+extern struct scsi_cmnd *queue_remove_exclude(Queue_t *queue,
+                                             unsigned long *exclude);
 
 #define queue_add_cmd_ordered(queue,SCpnt) \
        __queue_add(queue,SCpnt,(SCpnt)->cmnd[0] == REQUEST_SENSE)
 #define queue_add_cmd_tail(queue,SCpnt) \
        __queue_add(queue,SCpnt,0)
 /*
- * Function: int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head)
+ * Function: int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head)
  * Purpose : Add a new command onto a queue
  * Params  : queue - destination queue
  *          SCpnt - command to add
  *          head  - add command to head of queue
  * Returns : 0 on error, !0 on success
  */
-extern int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head);
+extern int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head);
 
 /*
- * Function: Scsi_Cmnd *queue_remove_tgtluntag (queue, target, lun, tag)
+ * Function: struct scsi_cmnd *queue_remove_tgtluntag (queue, target, lun, tag)
  * Purpose : remove a SCSI command from the queue for a specified target/lun/tag
  * Params  : queue  - queue to remove command from
  *          target - target that we want
  *          lun    - lun on device
  *          tag    - tag on device
- * Returns : Scsi_Cmnd if successful, or NULL if no command satisfies requirements
+ * Returns : struct scsi_cmnd if successful, or NULL if no command satisfies requirements
  */
-extern Scsi_Cmnd *queue_remove_tgtluntag (Queue_t *queue, int target, int lun, int tag);
+extern struct scsi_cmnd *queue_remove_tgtluntag(Queue_t *queue, int target,
+                                               int lun, int tag);
 
 /*
  * Function: queue_remove_all_target(queue, target)
@@ -94,12 +96,12 @@ extern void queue_remove_all_target(Queue_t *queue, int target);
 extern int queue_probetgtlun (Queue_t *queue, int target, int lun);
 
 /*
- * Function: int queue_remove_cmd (Queue_t *queue, Scsi_Cmnd *SCpnt)
+ * Function: int queue_remove_cmd (Queue_t *queue, struct scsi_cmnd *SCpnt)
  * Purpose : remove a specific command from the queues
  * Params  : queue - queue to look in
  *          SCpnt - command to find
  * Returns : 0 if not found
  */
-int queue_remove_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt);
+int queue_remove_cmd(Queue_t *queue, struct scsi_cmnd *SCpnt);
 
 #endif /* QUEUE_H */
index 8c2600ffc6afec68e270f224ea4ba17a4d3fb7b4..3a39579bd08e9841064e012d0bb2579beb363452 100644 (file)
@@ -66,7 +66,7 @@ static inline void put_next_SCp_byte(struct scsi_pointer *SCp, unsigned char c)
        SCp->this_residual -= 1;
 }
 
-static inline void init_SCp(Scsi_Cmnd *SCpnt)
+static inline void init_SCp(struct scsi_cmnd *SCpnt)
 {
        memset(&SCpnt->SCp, 0, sizeof(struct scsi_pointer));
 
index ff2b1796fa34634ac95b3eee22051743dc706819..c6118d99385e8d711939c93fc679995b48d36c1c 100644 (file)
@@ -1219,7 +1219,7 @@ static void dump_register_info(struct AdapterCtlBlk *acb,
                                srb, srb->cmd, srb->cmd->pid,
                                srb->cmd->cmnd[0], srb->cmd->device->id,
                                srb->cmd->device->lun);
-               printk("  sglist=%p cnt=%i idx=%i len=%i\n",
+               printk("  sglist=%p cnt=%i idx=%i len=%Zd\n",
                       srb->segment_x, srb->sg_count, srb->sg_index,
                       srb->total_xfer_length);
                printk("  state=0x%04x status=0x%02x phase=0x%02x (%sconn.)\n",
@@ -4949,7 +4949,7 @@ static struct pci_driver dc395x_driver = {
  **/
 static int __init dc395x_module_init(void)
 {
-       return pci_module_init(&dc395x_driver);
+       return pci_register_driver(&dc395x_driver);
 }
 
 
index 879a2665767611dc6749df5111f6d3b6341c6ee1..fa738ec8692a24d2882901cf2d6c618a3eb05e6a 100644 (file)
@@ -155,7 +155,7 @@ static struct pci_driver dmx3191d_pci_driver = {
 
 static int __init dmx3191d_init(void)
 {
-       return pci_module_init(&dmx3191d_pci_driver);
+       return pci_register_driver(&dmx3191d_pci_driver);
 }
 
 static void __exit dmx3191d_exit(void)
index d84a281ad944a518987c28cebefddd9d11da7bdb..b3fa7ed71faf2ffdebef04f0bc3ff46a33340651 100644 (file)
  *     I2O Interface Objects
  */
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-
-#define DECLARE_MUTEX(name) struct semaphore name=MUTEX
-
-typedef struct wait_queue *adpt_wait_queue_head_t;
-#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) adpt_wait_queue_head_t wait = NULL
-typedef struct wait_queue adpt_wait_queue_t;
-#else
-
 #include <linux/wait.h>
 typedef wait_queue_head_t adpt_wait_queue_head_t;
 #define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD(wait)
 typedef wait_queue_t adpt_wait_queue_t;
 
-#endif
 /*
  * message structures
  */
index 7b3bd34faf47e6857afcc8310e1cb696158b09c7..b20b37661d6f398ed0aa9ecdea4770990f9c22a0 100644 (file)
@@ -2212,7 +2212,7 @@ static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
         */
        host->io_port = 0;
        host->n_io_port = 0;
-                               /* see comments in hosts.h */
+                               /* see comments in scsi_host.h */
        host->max_id = 16;
        host->max_lun = 256;
        host->max_channel = pHba->top_scsi_channel + 1;
index 2ad2a89b5db4b2d15eaccd91a97d7219be4584fa..2899832649295d9162bfa466b83289b0d90ca4d1 100644 (file)
@@ -44,7 +44,7 @@ static int adpt_device_reset(struct scsi_cmnd* cmd);
 
 
 /*
- * struct scsi_host_template (see hosts.h)
+ * struct scsi_host_template (see scsi/scsi_host.h)
  */
 
 #define DPT_DRIVER_NAME        "Adaptec I2O RAID"
index 47eae0299750db54b79d9428959c218f8e036b05..8c29eafd51c5f34fe57cf582e9eccc9f1e57b9c4 100644 (file)
@@ -936,18 +936,12 @@ typedef struct {
     gdth_binfo_str      binfo;                  /* controller info */
     gdth_evt_data       dvr;                    /* event structure */
     spinlock_t          smp_lock;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     struct pci_dev      *pdev;
-#endif
     char                oem_name[8];
 #ifdef GDTH_DMA_STATISTICS
     ulong               dma32_cnt, dma64_cnt;   /* statistics: DMA buffer */
 #endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     struct scsi_device         *sdev;
-#else
-    struct scsi_device         sdev;
-#endif
 } gdth_ha_str;
 
 /* structure for scsi_register(), SCSI bus != 0 */
@@ -1029,10 +1023,6 @@ typedef struct {
 
 /* function prototyping */
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 int gdth_proc_info(struct Scsi_Host *, char *,char **,off_t,int,int);
-#else
-int gdth_proc_info(char *,char **,off_t,int,int,int);
-#endif
 
 #endif
diff --git a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
deleted file mode 100644 (file)
index c27264b..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#warning "This file is obsolete, please use <scsi/scsi_host.h> instead"
-#include <scsi/scsi_host.h>
index 7ed4eef8347b2f719d132407886549a0563bd318..e1fe9494125b1ea6927e92a2c61f3019eedf0b44 100644 (file)
@@ -70,6 +70,7 @@
 #include <linux/firmware.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/libata.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
@@ -78,6 +79,7 @@
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_transport.h>
 #include "ipr.h"
 
 /*
@@ -199,6 +201,8 @@ struct ipr_error_table_t ipr_error_table[] = {
        "FFFA: Undefined device response recovered by the IOA"},
        {0x014A0000, 1, 1,
        "FFF6: Device bus error, message or command phase"},
+       {0x014A8000, 0, 1,
+       "FFFE: Task Management Function failed"},
        {0x015D0000, 0, 1,
        "FFF6: Failure prediction threshold exceeded"},
        {0x015D9200, 0, 1,
@@ -261,6 +265,8 @@ struct ipr_error_table_t ipr_error_table[] = {
        "Device bus status error"},
        {0x04448600, 0, 1,
        "8157: IOA error requiring IOA reset to recover"},
+       {0x04448700, 0, 0,
+       "ATA device status error"},
        {0x04490000, 0, 0,
        "Message reject received from the device"},
        {0x04449200, 0, 1,
@@ -273,6 +279,8 @@ struct ipr_error_table_t ipr_error_table[] = {
        "9082: IOA detected device error"},
        {0x044A0000, 1, 1,
        "3110: Device bus error, message or command phase"},
+       {0x044A8000, 1, 1,
+       "3110: SAS Command / Task Management Function failed"},
        {0x04670400, 0, 1,
        "9091: Incorrect hardware configuration change has been detected"},
        {0x04678000, 0, 1,
@@ -453,7 +461,8 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd,
        trace_entry->time = jiffies;
        trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0];
        trace_entry->type = type;
-       trace_entry->cmd_index = ipr_cmd->cmd_index;
+       trace_entry->ata_op_code = ipr_cmd->ioarcb.add_data.u.regs.command;
+       trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff;
        trace_entry->res_handle = ipr_cmd->ioarcb.res_handle;
        trace_entry->u.add_data = add_data;
 }
@@ -480,8 +489,10 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
        ioarcb->read_ioadl_len = 0;
        ioasa->ioasc = 0;
        ioasa->residual_data_len = 0;
+       ioasa->u.gata.status = 0;
 
        ipr_cmd->scsi_cmd = NULL;
+       ipr_cmd->qc = NULL;
        ipr_cmd->sense_buffer[0] = 0;
        ipr_cmd->dma_use_sg = 0;
 }
@@ -625,6 +636,28 @@ static int ipr_set_pcix_cmd_reg(struct ipr_ioa_cfg *ioa_cfg)
        return 0;
 }
 
+/**
+ * ipr_sata_eh_done - done function for aborted SATA commands
+ * @ipr_cmd:   ipr command struct
+ *
+ * This function is invoked for ops generated to SATA
+ * devices which are being aborted.
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_sata_eh_done(struct ipr_cmnd *ipr_cmd)
+{
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+       struct ata_queued_cmd *qc = ipr_cmd->qc;
+       struct ipr_sata_port *sata_port = qc->ap->private_data;
+
+       qc->err_mask |= AC_ERR_OTHER;
+       sata_port->ioasa.status |= ATA_BUSY;
+       list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+       ata_qc_complete(qc);
+}
+
 /**
  * ipr_scsi_eh_done - mid-layer done function for aborted ops
  * @ipr_cmd:   ipr command struct
@@ -669,6 +702,8 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg)
 
                if (ipr_cmd->scsi_cmd)
                        ipr_cmd->done = ipr_scsi_eh_done;
+               else if (ipr_cmd->qc)
+                       ipr_cmd->done = ipr_sata_eh_done;
 
                ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH, IPR_IOASC_IOA_WAS_RESET);
                del_timer(&ipr_cmd->timer);
@@ -825,6 +860,7 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res)
        res->del_from_ml = 0;
        res->resetting_device = 0;
        res->sdev = NULL;
+       res->sata_port = NULL;
 }
 
 /**
@@ -1316,7 +1352,7 @@ static u32 ipr_get_error(u32 ioasc)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(ipr_error_table); i++)
-               if (ipr_error_table[i].ioasc == ioasc)
+               if (ipr_error_table[i].ioasc == (ioasc & IPR_IOASC_IOASC_MASK))
                        return i;
 
        return 0;
@@ -3051,6 +3087,17 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) { return 0; };
  **/
 static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth)
 {
+       struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
+       struct ipr_resource_entry *res;
+       unsigned long lock_flags = 0;
+
+       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+       res = (struct ipr_resource_entry *)sdev->hostdata;
+
+       if (res && ipr_is_gata(res) && qdepth > IPR_MAX_CMD_PER_ATA_LUN)
+               qdepth = IPR_MAX_CMD_PER_ATA_LUN;
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+
        scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
        return sdev->queue_depth;
 }
@@ -3165,6 +3212,122 @@ static int ipr_biosparam(struct scsi_device *sdev,
        return 0;
 }
 
+/**
+ * ipr_find_starget - Find target based on bus/target.
+ * @starget:   scsi target struct
+ *
+ * Return value:
+ *     resource entry pointer if found / NULL if not found
+ **/
+static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+       struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;
+       struct ipr_resource_entry *res;
+
+       list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
+               if ((res->cfgte.res_addr.bus == starget->channel) &&
+                   (res->cfgte.res_addr.target == starget->id) &&
+                   (res->cfgte.res_addr.lun == 0)) {
+                       return res;
+               }
+       }
+
+       return NULL;
+}
+
+static struct ata_port_info sata_port_info;
+
+/**
+ * ipr_target_alloc - Prepare for commands to a SCSI target
+ * @starget:   scsi target struct
+ *
+ * If the device is a SATA device, this function allocates an
+ * ATA port with libata, else it does nothing.
+ *
+ * Return value:
+ *     0 on success / non-0 on failure
+ **/
+static int ipr_target_alloc(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+       struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;
+       struct ipr_sata_port *sata_port;
+       struct ata_port *ap;
+       struct ipr_resource_entry *res;
+       unsigned long lock_flags;
+
+       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+       res = ipr_find_starget(starget);
+       starget->hostdata = NULL;
+
+       if (res && ipr_is_gata(res)) {
+               spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+               sata_port = kzalloc(sizeof(*sata_port), GFP_KERNEL);
+               if (!sata_port)
+                       return -ENOMEM;
+
+               ap = ata_sas_port_alloc(&ioa_cfg->ata_host, &sata_port_info, shost);
+               if (ap) {
+                       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+                       sata_port->ioa_cfg = ioa_cfg;
+                       sata_port->ap = ap;
+                       sata_port->res = res;
+
+                       res->sata_port = sata_port;
+                       ap->private_data = sata_port;
+                       starget->hostdata = sata_port;
+               } else {
+                       kfree(sata_port);
+                       return -ENOMEM;
+               }
+       }
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+
+       return 0;
+}
+
+/**
+ * ipr_target_destroy - Destroy a SCSI target
+ * @starget:   scsi target struct
+ *
+ * If the device was a SATA device, this function frees the libata
+ * ATA port, else it does nothing.
+ *
+ **/
+static void ipr_target_destroy(struct scsi_target *starget)
+{
+       struct ipr_sata_port *sata_port = starget->hostdata;
+
+       if (sata_port) {
+               starget->hostdata = NULL;
+               ata_sas_port_destroy(sata_port->ap);
+               kfree(sata_port);
+       }
+}
+
+/**
+ * ipr_find_sdev - Find device based on bus/target/lun.
+ * @sdev:      scsi device struct
+ *
+ * Return value:
+ *     resource entry pointer if found / NULL if not found
+ **/
+static struct ipr_resource_entry *ipr_find_sdev(struct scsi_device *sdev)
+{
+       struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) sdev->host->hostdata;
+       struct ipr_resource_entry *res;
+
+       list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
+               if ((res->cfgte.res_addr.bus == sdev->channel) &&
+                   (res->cfgte.res_addr.target == sdev->id) &&
+                   (res->cfgte.res_addr.lun == sdev->lun))
+                       return res;
+       }
+
+       return NULL;
+}
+
 /**
  * ipr_slave_destroy - Unconfigure a SCSI device
  * @sdev:      scsi device struct
@@ -3183,8 +3346,11 @@ static void ipr_slave_destroy(struct scsi_device *sdev)
        spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
        res = (struct ipr_resource_entry *) sdev->hostdata;
        if (res) {
+               if (res->sata_port)
+                       ata_port_disable(res->sata_port->ap);
                sdev->hostdata = NULL;
                res->sdev = NULL;
+               res->sata_port = NULL;
        }
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 }
@@ -3219,12 +3385,44 @@ static int ipr_slave_configure(struct scsi_device *sdev)
                }
                if (ipr_is_vset_device(res) || ipr_is_scsi_disk(res))
                        sdev->allow_restart = 1;
-               scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
+               if (ipr_is_gata(res) && res->sata_port) {
+                       scsi_adjust_queue_depth(sdev, 0, IPR_MAX_CMD_PER_ATA_LUN);
+                       ata_sas_slave_configure(sdev, res->sata_port->ap);
+               } else {
+                       scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
+               }
        }
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
        return 0;
 }
 
+/**
+ * ipr_ata_slave_alloc - Prepare for commands to a SATA device
+ * @sdev:      scsi device struct
+ *
+ * This function initializes an ATA port so that future commands
+ * sent through queuecommand will work.
+ *
+ * Return value:
+ *     0 on success
+ **/
+static int ipr_ata_slave_alloc(struct scsi_device *sdev)
+{
+       struct ipr_sata_port *sata_port = NULL;
+       int rc = -ENXIO;
+
+       ENTER;
+       if (sdev->sdev_target)
+               sata_port = sdev->sdev_target->hostdata;
+       if (sata_port)
+               rc = ata_sas_port_init(sata_port->ap);
+       if (rc)
+               ipr_slave_destroy(sdev);
+
+       LEAVE;
+       return rc;
+}
+
 /**
  * ipr_slave_alloc - Prepare for commands to a device.
  * @sdev:      scsi device struct
@@ -3248,18 +3446,18 @@ static int ipr_slave_alloc(struct scsi_device *sdev)
 
        spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
 
-       list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-               if ((res->cfgte.res_addr.bus == sdev->channel) &&
-                   (res->cfgte.res_addr.target == sdev->id) &&
-                   (res->cfgte.res_addr.lun == sdev->lun)) {
-                       res->sdev = sdev;
-                       res->add_to_ml = 0;
-                       res->in_erp = 0;
-                       sdev->hostdata = res;
-                       if (!ipr_is_naca_model(res))
-                               res->needs_sync_complete = 1;
-                       rc = 0;
-                       break;
+       res = ipr_find_sdev(sdev);
+       if (res) {
+               res->sdev = sdev;
+               res->add_to_ml = 0;
+               res->in_erp = 0;
+               sdev->hostdata = res;
+               if (!ipr_is_naca_model(res))
+                       res->needs_sync_complete = 1;
+               rc = 0;
+               if (ipr_is_gata(res)) {
+                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+                       return ipr_ata_slave_alloc(sdev);
                }
        }
 
@@ -3314,7 +3512,8 @@ static int ipr_eh_host_reset(struct scsi_cmnd * cmd)
  * This function issues a device reset to the affected device.
  * If the device is a SCSI device, a LUN reset will be sent
  * to the device first. If that does not work, a target reset
- * will be sent.
+ * will be sent. If the device is a SATA device, a PHY reset will
+ * be sent.
  *
  * Return value:
  *     0 on success / non-zero on failure
@@ -3325,25 +3524,78 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
        struct ipr_cmnd *ipr_cmd;
        struct ipr_ioarcb *ioarcb;
        struct ipr_cmd_pkt *cmd_pkt;
+       struct ipr_ioarcb_ata_regs *regs;
        u32 ioasc;
 
        ENTER;
        ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
        ioarcb = &ipr_cmd->ioarcb;
        cmd_pkt = &ioarcb->cmd_pkt;
+       regs = &ioarcb->add_data.u.regs;
 
        ioarcb->res_handle = res->cfgte.res_handle;
        cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
        cmd_pkt->cdb[0] = IPR_RESET_DEVICE;
+       if (ipr_is_gata(res)) {
+               cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET;
+               ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(regs->flags));
+               regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
+       }
 
        ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT);
        ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+       if (ipr_is_gata(res) && res->sata_port && ioasc != IPR_IOASC_IOA_WAS_RESET)
+               memcpy(&res->sata_port->ioasa, &ipr_cmd->ioasa.u.gata,
+                      sizeof(struct ipr_ioasa_gata));
 
        LEAVE;
        return (IPR_IOASC_SENSE_KEY(ioasc) ? -EIO : 0);
 }
 
+/**
+ * ipr_sata_reset - Reset the SATA port
+ * @ap:                SATA port to reset
+ * @classes:   class of the attached device
+ *
+ * This function issues a SATA phy reset to the affected ATA port.
+ *
+ * Return value:
+ *     0 on success / non-zero on failure
+ **/
+static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes)
+{
+       struct ipr_sata_port *sata_port = ap->private_data;
+       struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;
+       struct ipr_resource_entry *res;
+       unsigned long lock_flags = 0;
+       int rc = -ENXIO;
+
+       ENTER;
+       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+       res = sata_port->res;
+       if (res) {
+               rc = ipr_device_reset(ioa_cfg, res);
+               switch(res->cfgte.proto) {
+               case IPR_PROTO_SATA:
+               case IPR_PROTO_SAS_STP:
+                       *classes = ATA_DEV_ATA;
+                       break;
+               case IPR_PROTO_SATA_ATAPI:
+               case IPR_PROTO_SAS_STP_ATAPI:
+                       *classes = ATA_DEV_ATAPI;
+                       break;
+               default:
+                       *classes = ATA_DEV_UNKNOWN;
+                       break;
+               };
+       }
+
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+       LEAVE;
+       return rc;
+}
+
 /**
  * ipr_eh_dev_reset - Reset the device
  * @scsi_cmd:  scsi command struct
@@ -3360,7 +3612,8 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
        struct ipr_cmnd *ipr_cmd;
        struct ipr_ioa_cfg *ioa_cfg;
        struct ipr_resource_entry *res;
-       int rc;
+       struct ata_port *ap;
+       int rc = 0;
 
        ENTER;
        ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
@@ -3388,7 +3641,14 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
 
        res->resetting_device = 1;
        scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n");
-       rc = ipr_device_reset(ioa_cfg, res);
+
+       if (ipr_is_gata(res) && res->sata_port) {
+               ap = res->sata_port->ap;
+               spin_unlock_irq(scsi_cmd->device->host->host_lock);
+               ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL);
+               spin_lock_irq(scsi_cmd->device->host->host_lock);
+       } else
+               rc = ipr_device_reset(ioa_cfg, res);
        res->resetting_device = 0;
 
        LEAVE;
@@ -4300,6 +4560,9 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
                return 0;
        }
 
+       if (ipr_is_gata(res) && res->sata_port)
+               return ata_sas_queuecmd(scsi_cmd, done, res->sata_port->ap);
+
        ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
        ioarcb = &ipr_cmd->ioarcb;
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
@@ -4344,6 +4607,26 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
        return 0;
 }
 
+/**
+ * ipr_ioctl - IOCTL handler
+ * @sdev:      scsi device struct
+ * @cmd:       IOCTL cmd
+ * @arg:       IOCTL arg
+ *
+ * Return value:
+ *     0 on success / other on failure
+ **/
+int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
+{
+       struct ipr_resource_entry *res;
+
+       res = (struct ipr_resource_entry *)sdev->hostdata;
+       if (res && ipr_is_gata(res))
+               return ata_scsi_ioctl(sdev, cmd, arg);
+
+       return -EINVAL;
+}
+
 /**
  * ipr_info - Get information about the card/driver
  * @scsi_host: scsi host struct
@@ -4366,10 +4649,45 @@ static const char * ipr_ioa_info(struct Scsi_Host *host)
        return buffer;
 }
 
+/**
+ * ipr_scsi_timed_out - Handle scsi command timeout
+ * @scsi_cmd:  scsi command struct
+ *
+ * Return value:
+ *     EH_NOT_HANDLED
+ **/
+enum scsi_eh_timer_return ipr_scsi_timed_out(struct scsi_cmnd *scsi_cmd)
+{
+       struct ipr_ioa_cfg *ioa_cfg;
+       struct ipr_cmnd *ipr_cmd;
+       unsigned long flags;
+
+       ENTER;
+       spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags);
+       ioa_cfg = (struct ipr_ioa_cfg *)scsi_cmd->device->host->hostdata;
+
+       list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
+               if (ipr_cmd->qc && ipr_cmd->qc->scsicmd == scsi_cmd) {
+                       ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT;
+                       ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED;
+                       break;
+               }
+       }
+
+       spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags);
+       LEAVE;
+       return EH_NOT_HANDLED;
+}
+
+static struct scsi_transport_template ipr_transport_template = {
+       .eh_timed_out = ipr_scsi_timed_out
+};
+
 static struct scsi_host_template driver_template = {
        .module = THIS_MODULE,
        .name = "IPR",
        .info = ipr_ioa_info,
+       .ioctl = ipr_ioctl,
        .queuecommand = ipr_queuecommand,
        .eh_abort_handler = ipr_eh_abort,
        .eh_device_reset_handler = ipr_eh_dev_reset,
@@ -4377,6 +4695,8 @@ static struct scsi_host_template driver_template = {
        .slave_alloc = ipr_slave_alloc,
        .slave_configure = ipr_slave_configure,
        .slave_destroy = ipr_slave_destroy,
+       .target_alloc = ipr_target_alloc,
+       .target_destroy = ipr_target_destroy,
        .change_queue_depth = ipr_change_queue_depth,
        .change_queue_type = ipr_change_queue_type,
        .bios_param = ipr_biosparam,
@@ -4391,6 +4711,330 @@ static struct scsi_host_template driver_template = {
        .proc_name = IPR_NAME
 };
 
+/**
+ * ipr_ata_phy_reset - libata phy_reset handler
+ * @ap:                ata port to reset
+ *
+ **/
+static void ipr_ata_phy_reset(struct ata_port *ap)
+{
+       unsigned long flags;
+       struct ipr_sata_port *sata_port = ap->private_data;
+       struct ipr_resource_entry *res = sata_port->res;
+       struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;
+       int rc;
+
+       ENTER;
+       spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
+       while(ioa_cfg->in_reset_reload) {
+               spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+               wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
+               spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
+       }
+
+       if (!ioa_cfg->allow_cmds)
+               goto out_unlock;
+
+       rc = ipr_device_reset(ioa_cfg, res);
+
+       if (rc) {
+               ap->ops->port_disable(ap);
+               goto out_unlock;
+       }
+
+       switch(res->cfgte.proto) {
+       case IPR_PROTO_SATA:
+       case IPR_PROTO_SAS_STP:
+               ap->device[0].class = ATA_DEV_ATA;
+               break;
+       case IPR_PROTO_SATA_ATAPI:
+       case IPR_PROTO_SAS_STP_ATAPI:
+               ap->device[0].class = ATA_DEV_ATAPI;
+               break;
+       default:
+               ap->device[0].class = ATA_DEV_UNKNOWN;
+               ap->ops->port_disable(ap);
+               break;
+       };
+
+out_unlock:
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+       LEAVE;
+}
+
+/**
+ * ipr_ata_post_internal - Cleanup after an internal command
+ * @qc:        ATA queued command
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_ata_post_internal(struct ata_queued_cmd *qc)
+{
+       struct ipr_sata_port *sata_port = qc->ap->private_data;
+       struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;
+       struct ipr_cmnd *ipr_cmd;
+       unsigned long flags;
+
+       spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
+       list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
+               if (ipr_cmd->qc == qc) {
+                       ipr_device_reset(ioa_cfg, sata_port->res);
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+}
+
+/**
+ * ipr_tf_read - Read the current ATA taskfile for the ATA port
+ * @ap:        ATA port
+ * @tf:        destination ATA taskfile
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+       struct ipr_sata_port *sata_port = ap->private_data;
+       struct ipr_ioasa_gata *g = &sata_port->ioasa;
+
+       tf->feature = g->error;
+       tf->nsect = g->nsect;
+       tf->lbal = g->lbal;
+       tf->lbam = g->lbam;
+       tf->lbah = g->lbah;
+       tf->device = g->device;
+       tf->command = g->status;
+       tf->hob_nsect = g->hob_nsect;
+       tf->hob_lbal = g->hob_lbal;
+       tf->hob_lbam = g->hob_lbam;
+       tf->hob_lbah = g->hob_lbah;
+       tf->ctl = g->alt_status;
+}
+
+/**
+ * ipr_copy_sata_tf - Copy a SATA taskfile to an IOA data structure
+ * @regs:      destination
+ * @tf:        source ATA taskfile
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_copy_sata_tf(struct ipr_ioarcb_ata_regs *regs,
+                            struct ata_taskfile *tf)
+{
+       regs->feature = tf->feature;
+       regs->nsect = tf->nsect;
+       regs->lbal = tf->lbal;
+       regs->lbam = tf->lbam;
+       regs->lbah = tf->lbah;
+       regs->device = tf->device;
+       regs->command = tf->command;
+       regs->hob_feature = tf->hob_feature;
+       regs->hob_nsect = tf->hob_nsect;
+       regs->hob_lbal = tf->hob_lbal;
+       regs->hob_lbam = tf->hob_lbam;
+       regs->hob_lbah = tf->hob_lbah;
+       regs->ctl = tf->ctl;
+}
+
+/**
+ * ipr_sata_done - done function for SATA commands
+ * @ipr_cmd:   ipr command struct
+ *
+ * This function is invoked by the interrupt handler for
+ * ops generated by the SCSI mid-layer to SATA devices
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_sata_done(struct ipr_cmnd *ipr_cmd)
+{
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+       struct ata_queued_cmd *qc = ipr_cmd->qc;
+       struct ipr_sata_port *sata_port = qc->ap->private_data;
+       struct ipr_resource_entry *res = sata_port->res;
+       u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+
+       memcpy(&sata_port->ioasa, &ipr_cmd->ioasa.u.gata,
+              sizeof(struct ipr_ioasa_gata));
+       ipr_dump_ioasa(ioa_cfg, ipr_cmd, res);
+
+       if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET)
+               scsi_report_device_reset(ioa_cfg->host, res->cfgte.res_addr.bus,
+                                        res->cfgte.res_addr.target);
+
+       if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR)
+               qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status);
+       else
+               qc->err_mask |= ac_err_mask(ipr_cmd->ioasa.u.gata.status);
+       list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+       ata_qc_complete(qc);
+}
+
+/**
+ * ipr_build_ata_ioadl - Build an ATA scatter/gather list
+ * @ipr_cmd:   ipr command struct
+ * @qc:                ATA queued command
+ *
+ **/
+static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
+                               struct ata_queued_cmd *qc)
+{
+       u32 ioadl_flags = 0;
+       struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+       struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+       int len = qc->nbytes + qc->pad_len;
+       struct scatterlist *sg;
+
+       if (len == 0)
+               return;
+
+       if (qc->dma_dir == 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(len);
+               ioarcb->write_ioadl_len =
+                       cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
+       } else if (qc->dma_dir == DMA_FROM_DEVICE) {
+               ioadl_flags = IPR_IOADL_FLAGS_READ;
+               ioarcb->read_data_transfer_length = cpu_to_be32(len);
+               ioarcb->read_ioadl_len =
+                       cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
+       }
+
+       ata_for_each_sg(sg, qc) {
+               ioadl->flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(sg));
+               ioadl->address = cpu_to_be32(sg_dma_address(sg));
+               if (ata_sg_is_last(sg, qc))
+                       ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+               else
+                       ioadl++;
+       }
+}
+
+/**
+ * ipr_qc_issue - Issue a SATA qc to a device
+ * @qc:        queued command
+ *
+ * Return value:
+ *     0 if success
+ **/
+static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct ipr_sata_port *sata_port = ap->private_data;
+       struct ipr_resource_entry *res = sata_port->res;
+       struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;
+       struct ipr_cmnd *ipr_cmd;
+       struct ipr_ioarcb *ioarcb;
+       struct ipr_ioarcb_ata_regs *regs;
+
+       if (unlikely(!ioa_cfg->allow_cmds || ioa_cfg->ioa_is_dead))
+               return -EIO;
+
+       ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
+       ioarcb = &ipr_cmd->ioarcb;
+       regs = &ioarcb->add_data.u.regs;
+
+       memset(&ioarcb->add_data, 0, sizeof(ioarcb->add_data));
+       ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(ioarcb->add_data.u.regs));
+
+       list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
+       ipr_cmd->qc = qc;
+       ipr_cmd->done = ipr_sata_done;
+       ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle;
+       ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU;
+       ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
+       ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
+       ipr_cmd->dma_use_sg = qc->pad_len ? qc->n_elem + 1 : qc->n_elem;
+
+       ipr_build_ata_ioadl(ipr_cmd, qc);
+       regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
+       ipr_copy_sata_tf(regs, &qc->tf);
+       memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN);
+       ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr));
+
+       switch (qc->tf.protocol) {
+       case ATA_PROT_NODATA:
+       case ATA_PROT_PIO:
+               break;
+
+       case ATA_PROT_DMA:
+               regs->flags |= IPR_ATA_FLAG_XFER_TYPE_DMA;
+               break;
+
+       case ATA_PROT_ATAPI:
+       case ATA_PROT_ATAPI_NODATA:
+               regs->flags |= IPR_ATA_FLAG_PACKET_CMD;
+               break;
+
+       case ATA_PROT_ATAPI_DMA:
+               regs->flags |= IPR_ATA_FLAG_PACKET_CMD;
+               regs->flags |= IPR_ATA_FLAG_XFER_TYPE_DMA;
+               break;
+
+       default:
+               WARN_ON(1);
+               return -1;
+       }
+
+       mb();
+       writel(be32_to_cpu(ioarcb->ioarcb_host_pci_addr),
+              ioa_cfg->regs.ioarrin_reg);
+       return 0;
+}
+
+/**
+ * ipr_ata_check_status - Return last ATA status
+ * @ap:        ATA port
+ *
+ * Return value:
+ *     ATA status
+ **/
+static u8 ipr_ata_check_status(struct ata_port *ap)
+{
+       struct ipr_sata_port *sata_port = ap->private_data;
+       return sata_port->ioasa.status;
+}
+
+/**
+ * ipr_ata_check_altstatus - Return last ATA altstatus
+ * @ap:        ATA port
+ *
+ * Return value:
+ *     Alt ATA status
+ **/
+static u8 ipr_ata_check_altstatus(struct ata_port *ap)
+{
+       struct ipr_sata_port *sata_port = ap->private_data;
+       return sata_port->ioasa.alt_status;
+}
+
+static struct ata_port_operations ipr_sata_ops = {
+       .port_disable = ata_port_disable,
+       .check_status = ipr_ata_check_status,
+       .check_altstatus = ipr_ata_check_altstatus,
+       .dev_select = ata_noop_dev_select,
+       .phy_reset = ipr_ata_phy_reset,
+       .post_internal_cmd = ipr_ata_post_internal,
+       .tf_read = ipr_tf_read,
+       .qc_prep = ata_noop_qc_prep,
+       .qc_issue = ipr_qc_issue,
+       .port_start = ata_sas_port_start,
+       .port_stop = ata_sas_port_stop
+};
+
+static struct ata_port_info sata_port_info = {
+       .flags  = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET |
+       ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
+       .pio_mask       = 0x10, /* pio4 */
+       .mwdma_mask = 0x07,
+       .udma_mask      = 0x7f, /* udma0-6 */
+       .port_ops       = &ipr_sata_ops
+};
+
 #ifdef CONFIG_PPC_PSERIES
 static const u16 ipr_blocked_processors[] = {
        PV_NORTHSTAR,
@@ -6352,7 +6996,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
        struct Scsi_Host *host;
        unsigned long ipr_regs_pci;
        void __iomem *ipr_regs;
-       u32 rc = PCIBIOS_SUCCESSFUL;
+       int rc = PCIBIOS_SUCCESSFUL;
        volatile u32 mask, uproc;
 
        ENTER;
@@ -6374,6 +7018,9 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
 
        ioa_cfg = (struct ipr_ioa_cfg *)host->hostdata;
        memset(ioa_cfg, 0, sizeof(struct ipr_ioa_cfg));
+       host->transportt = &ipr_transport_template;
+       ata_host_init(&ioa_cfg->ata_host, &pdev->dev,
+                     sata_port_info.flags, &ipr_sata_ops);
 
        ioa_cfg->chip_cfg = ipr_get_chip_cfg(dev_id);
 
@@ -6749,7 +7396,7 @@ static int __init ipr_init(void)
        ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n",
                 IPR_DRIVER_VERSION, IPR_DRIVER_DATE);
 
-       return pci_module_init(&ipr_driver);
+       return pci_register_driver(&ipr_driver);
 }
 
 /**
index 11eaff524327a60fafb0066058887152dc0843f0..6d035283af0843f00a54caa75fa7ee94d19c86f0 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/types.h>
 #include <linux/completion.h>
+#include <linux/libata.h>
 #include <linux/list.h>
 #include <linux/kref.h>
 #include <scsi/scsi.h>
@@ -36,8 +37,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.1.4"
-#define IPR_DRIVER_DATE "(August 2, 2006)"
+#define IPR_DRIVER_VERSION "2.2.0"
+#define IPR_DRIVER_DATE "(September 25, 2006)"
 
 /*
  * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -849,6 +850,13 @@ struct ipr_bus_attributes {
        u32 max_xfer_rate;
 };
 
+struct ipr_sata_port {
+       struct ipr_ioa_cfg *ioa_cfg;
+       struct ata_port *ap;
+       struct ipr_resource_entry *res;
+       struct ipr_ioasa_gata ioasa;
+};
+
 struct ipr_resource_entry {
        struct ipr_config_table_entry cfgte;
        u8 needs_sync_complete:1;
@@ -858,6 +866,7 @@ struct ipr_resource_entry {
        u8 resetting_device:1;
 
        struct scsi_device *sdev;
+       struct ipr_sata_port *sata_port;
        struct list_head queue;
 };
 
@@ -928,10 +937,11 @@ struct ipr_trace_entry {
        u32 time;
 
        u8 op_code;
+       u8 ata_op_code;
        u8 type;
 #define IPR_TRACE_START                        0x00
 #define IPR_TRACE_FINISH               0xff
-       u16 cmd_index;
+       u8 cmd_index;
 
        __be32 res_handle;
        union {
@@ -1073,6 +1083,7 @@ struct ipr_ioa_cfg {
 
        struct ipr_cmnd *reset_cmd;
 
+       struct ata_host ata_host;
        char ipr_cmd_label[8];
 #define IPR_CMD_LABEL          "ipr_cmnd"
        struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS];
@@ -1085,6 +1096,7 @@ struct ipr_cmnd {
        struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES];
        struct list_head queue;
        struct scsi_cmnd *scsi_cmd;
+       struct ata_queued_cmd *qc;
        struct completion completion;
        struct timer_list timer;
        void (*done) (struct ipr_cmnd *);
index 3c639286ec1edeb7496e5d11aa47422da0a6c4a0..9a9ab297cf17b8eaf3466197a6236532a878613b 100644 (file)
 #include <linux/dma-mapping.h>
 
 #include <scsi/sg.h>
-
 #include "scsi.h"
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-#include "hosts.h"
-#else
 #include <scsi/scsi_host.h>
-#endif
 
 #include "ips.h"
 
@@ -250,9 +244,9 @@ module_param(ips, charp, 0);
  */
 static int ips_detect(struct scsi_host_template *);
 static int ips_release(struct Scsi_Host *);
-static int ips_eh_abort(Scsi_Cmnd *);
-static int ips_eh_reset(Scsi_Cmnd *);
-static int ips_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
+static int ips_eh_abort(struct scsi_cmnd *);
+static int ips_eh_reset(struct scsi_cmnd *);
+static int ips_queue(struct scsi_cmnd *, void (*)(struct scsi_cmnd *));
 static const char *ips_info(struct Scsi_Host *);
 static irqreturn_t do_ipsintr(int, void *, struct pt_regs *);
 static int ips_hainit(ips_ha_t *);
@@ -325,24 +319,26 @@ static uint32_t ips_statupd_copperhead_memio(ips_ha_t *);
 static uint32_t ips_statupd_morpheus(ips_ha_t *);
 static ips_scb_t *ips_getscb(ips_ha_t *);
 static void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
-static void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *);
+static void ips_putq_wait_tail(ips_wait_queue_t *, struct scsi_cmnd *);
 static void ips_putq_copp_tail(ips_copp_queue_t *,
                                      ips_copp_wait_item_t *);
 static ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *);
 static ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
-static Scsi_Cmnd *ips_removeq_wait_head(ips_wait_queue_t *);
-static Scsi_Cmnd *ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *);
+static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *);
+static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *,
+                                         struct scsi_cmnd *);
 static ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *,
                                                     ips_copp_wait_item_t *);
 static ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *);
 
-static int ips_is_passthru(Scsi_Cmnd *);
-static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int);
+static int ips_is_passthru(struct scsi_cmnd *);
+static int ips_make_passthru(ips_ha_t *, struct scsi_cmnd *, ips_scb_t *, int);
 static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
 static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
-static void ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data,
+static void ips_scmd_buf_write(struct scsi_cmnd * scmd, void *data,
                               unsigned int count);
-static void ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned int count);
+static void ips_scmd_buf_read(struct scsi_cmnd * scmd, void *data,
+                             unsigned int count);
 
 static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 static int ips_host_info(ips_ha_t *, char *, off_t, int);
@@ -812,8 +808,7 @@ ips_halt(struct notifier_block *nb, ulong event, void *buf)
 /*   Abort a command (using the new error code stuff)                       */
 /* Note: this routine is called under the io_request_lock                   */
 /****************************************************************************/
-int
-ips_eh_abort(Scsi_Cmnd * SC)
+int ips_eh_abort(struct scsi_cmnd *SC)
 {
        ips_ha_t *ha;
        ips_copp_wait_item_t *item;
@@ -871,8 +866,7 @@ ips_eh_abort(Scsi_Cmnd * SC)
 /* NOTE: this routine is called under the io_request_lock spinlock          */
 /*                                                                          */
 /****************************************************************************/
-static int
-__ips_eh_reset(Scsi_Cmnd * SC)
+static int __ips_eh_reset(struct scsi_cmnd *SC)
 {
        int ret;
        int i;
@@ -968,7 +962,7 @@ __ips_eh_reset(Scsi_Cmnd * SC)
        ret = (*ha->func.reset) (ha);
 
        if (!ret) {
-               Scsi_Cmnd *scsi_cmd;
+               struct scsi_cmnd *scsi_cmd;
 
                IPS_PRINTK(KERN_NOTICE, ha->pcidev,
                           "Controller reset failed - controller now offline.\n");
@@ -997,7 +991,7 @@ __ips_eh_reset(Scsi_Cmnd * SC)
        }
 
        if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
-               Scsi_Cmnd *scsi_cmd;
+               struct scsi_cmnd *scsi_cmd;
 
                IPS_PRINTK(KERN_NOTICE, ha->pcidev,
                           "Controller reset failed - controller now offline.\n");
@@ -1059,8 +1053,7 @@ __ips_eh_reset(Scsi_Cmnd * SC)
 
 }
 
-static int
-ips_eh_reset(Scsi_Cmnd * SC)
+static int ips_eh_reset(struct scsi_cmnd *SC)
 {
        int rc;
 
@@ -1083,8 +1076,7 @@ ips_eh_reset(Scsi_Cmnd * SC)
 /*    Linux obtains io_request_lock before calling this function            */
 /*                                                                          */
 /****************************************************************************/
-static int
-ips_queue(Scsi_Cmnd * SC, void (*done) (Scsi_Cmnd *))
+static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
 {
        ips_ha_t *ha;
        ips_passthru_t *pt;
@@ -1602,8 +1594,7 @@ ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
 /*   Determine if the specified SCSI command is really a passthru command   */
 /*                                                                          */
 /****************************************************************************/
-static int
-ips_is_passthru(Scsi_Cmnd * SC)
+static int ips_is_passthru(struct scsi_cmnd *SC)
 {
        unsigned long flags;
 
@@ -1685,7 +1676,7 @@ ips_alloc_passthru_buffer(ips_ha_t * ha, int length)
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_make_passthru(ips_ha_t * ha, Scsi_Cmnd * SC, ips_scb_t * scb, int intr)
+ips_make_passthru(ips_ha_t *ha, struct scsi_cmnd *SC, ips_scb_t *scb, int intr)
 {
        ips_passthru_t *pt;
        int length = 0;
@@ -2734,9 +2725,9 @@ static void
 ips_next(ips_ha_t * ha, int intr)
 {
        ips_scb_t *scb;
-       Scsi_Cmnd *SC;
-       Scsi_Cmnd *p;
-       Scsi_Cmnd *q;
+       struct scsi_cmnd *SC;
+       struct scsi_cmnd *p;
+       struct scsi_cmnd *q;
        ips_copp_wait_item_t *item;
        int ret;
        unsigned long cpu_flags = 0;
@@ -2847,7 +2838,7 @@ ips_next(ips_ha_t * ha, int intr)
                        dcdb_active[scmd_channel(p) -
                                    1] & (1 << scmd_id(p)))) {
                        ips_freescb(ha, scb);
-                       p = (Scsi_Cmnd *) p->host_scribble;
+                       p = (struct scsi_cmnd *) p->host_scribble;
                        continue;
                }
 
@@ -2962,7 +2953,7 @@ ips_next(ips_ha_t * ha, int intr)
                        break;
                }               /* end case */
 
-               p = (Scsi_Cmnd *) p->host_scribble;
+               p = (struct scsi_cmnd *) p->host_scribble;
 
        }                       /* end while */
 
@@ -3090,8 +3081,7 @@ ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item)
 /* ASSUMED to be called from within the HA lock                             */
 /*                                                                          */
 /****************************************************************************/
-static void
-ips_putq_wait_tail(ips_wait_queue_t * queue, Scsi_Cmnd * item)
+static void ips_putq_wait_tail(ips_wait_queue_t *queue, struct scsi_cmnd *item)
 {
        METHOD_TRACE("ips_putq_wait_tail", 1);
 
@@ -3122,10 +3112,9 @@ ips_putq_wait_tail(ips_wait_queue_t * queue, Scsi_Cmnd * item)
 /* ASSUMED to be called from within the HA lock                             */
 /*                                                                          */
 /****************************************************************************/
-static Scsi_Cmnd *
-ips_removeq_wait_head(ips_wait_queue_t * queue)
+static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *queue)
 {
-       Scsi_Cmnd *item;
+       struct scsi_cmnd *item;
 
        METHOD_TRACE("ips_removeq_wait_head", 1);
 
@@ -3135,7 +3124,7 @@ ips_removeq_wait_head(ips_wait_queue_t * queue)
                return (NULL);
        }
 
-       queue->head = (Scsi_Cmnd *) item->host_scribble;
+       queue->head = (struct scsi_cmnd *) item->host_scribble;
        item->host_scribble = NULL;
 
        if (queue->tail == item)
@@ -3157,10 +3146,10 @@ ips_removeq_wait_head(ips_wait_queue_t * queue)
 /* ASSUMED to be called from within the HA lock                             */
 /*                                                                          */
 /****************************************************************************/
-static Scsi_Cmnd *
-ips_removeq_wait(ips_wait_queue_t * queue, Scsi_Cmnd * item)
+static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *queue,
+                                         struct scsi_cmnd *item)
 {
-       Scsi_Cmnd *p;
+       struct scsi_cmnd *p;
 
        METHOD_TRACE("ips_removeq_wait", 1);
 
@@ -3173,8 +3162,8 @@ ips_removeq_wait(ips_wait_queue_t * queue, Scsi_Cmnd * item)
 
        p = queue->head;
 
-       while ((p) && (item != (Scsi_Cmnd *) p->host_scribble))
-               p = (Scsi_Cmnd *) p->host_scribble;
+       while ((p) && (item != (struct scsi_cmnd *) p->host_scribble))
+               p = (struct scsi_cmnd *) p->host_scribble;
 
        if (p) {
                /* found a match */
@@ -3659,11 +3648,10 @@ ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
 /* Routine Name: ips_scmd_buf_write                                         */
 /*                                                                          */
 /* Routine Description:                                                     */
-/*  Write data to Scsi_Cmnd request_buffer at proper offsets                */
+/*  Write data to struct scsi_cmnd request_buffer at proper offsets        */
 /****************************************************************************/
 static void
-ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned
-                  int count)
+ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
 {
        if (scmd->use_sg) {
                int i;
@@ -3698,11 +3686,10 @@ ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned
 /* Routine Name: ips_scmd_buf_read                                          */
 /*                                                                          */
 /* Routine Description:                                                     */
-/*  Copy data from a Scsi_Cmnd to a new, linear buffer                      */
+/*  Copy data from a struct scsi_cmnd to a new, linear buffer              */
 /****************************************************************************/
 static void
-ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned
-                 int count)
+ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
 {
        if (scmd->use_sg) {
                int i;
@@ -7078,7 +7065,7 @@ ips_remove_device(struct pci_dev *pci_dev)
 static int __init
 ips_module_init(void)
 {
-       if (pci_module_init(&ips_pci_driver) < 0)
+       if (pci_register_driver(&ips_pci_driver) < 0)
                return -ENODEV;
        ips_driver_template.module = THIS_MODULE;
        ips_order_controllers();
index f46c382e5599aa022c87631a55f81dcdef17fb6c..34680f3dd4523e10662aa03f6605478c2a72b262 100644 (file)
@@ -6,7 +6,7 @@
 /*             David Jeffery, Adaptec, Inc.                                  */
 /*                                                                           */
 /* Copyright (C) 1999 IBM Corporation                                        */
-/* Copyright (C) 2003 Adaptec, Inc.                                          */ 
+/* Copyright (C) 2003 Adaptec, Inc.                                          */
 /*                                                                           */
 /* 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      */
@@ -1033,14 +1033,14 @@ typedef struct ips_scb_queue {
  * Wait queue_format
  */
 typedef struct ips_wait_queue {
-   Scsi_Cmnd      *head;
-   Scsi_Cmnd      *tail;
-   int             count;
+       struct scsi_cmnd *head;
+       struct scsi_cmnd *tail;
+       int count;
 } ips_wait_queue_t;
 
 typedef struct ips_copp_wait_item {
-   Scsi_Cmnd                 *scsi_cmd;
-   struct ips_copp_wait_item *next;
+       struct scsi_cmnd *scsi_cmd;
+       struct ips_copp_wait_item *next;
 } ips_copp_wait_item_t;
 
 typedef struct ips_copp_queue {
@@ -1149,7 +1149,7 @@ typedef struct ips_scb {
    uint32_t          flags;
    uint32_t          op_code;
    IPS_SG_LIST       sg_list;
-   Scsi_Cmnd        *scsi_cmd;
+   struct scsi_cmnd *scsi_cmd;
    struct ips_scb   *q_next;
    ips_scb_callback  callback;
    uint32_t          sg_busaddr;
@@ -1175,7 +1175,7 @@ typedef struct ips_scb_pt {
    uint32_t          flags;
    uint32_t          op_code;
    IPS_SG_LIST      *sg_list;
-   Scsi_Cmnd        *scsi_cmd;
+   struct scsi_cmnd *scsi_cmd;
    struct ips_scb   *q_next;
    ips_scb_callback  callback;
 } ips_scb_pt_t;
index 4cdf3464267fd7decee3cfff83c9082d3050b8a8..a5723ad0a0992c9026e759c7a5899cac4f51ea96 100644 (file)
@@ -389,7 +389,8 @@ lpfc_config_port_post(struct lpfc_hba * phba)
 
        lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
        pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
-       if (lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT) != MBX_SUCCESS) {
+       rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+       if (rc != MBX_SUCCESS) {
                lpfc_printf_log(phba,
                                KERN_ERR,
                                LOG_INIT,
@@ -406,7 +407,8 @@ lpfc_config_port_post(struct lpfc_hba * phba)
                readl(phba->HAregaddr); /* flush */
 
                phba->hba_state = LPFC_HBA_ERROR;
-               mempool_free(pmb, phba->mbox_mem_pool);
+               if (rc != MBX_BUSY)
+                       mempool_free(pmb, phba->mbox_mem_pool);
                return -EIO;
        }
        /* MBOX buffer will be freed in mbox compl */
index 8cd0bd1d0f7c1b65393e8bf240e6ac8fdd28a37b..b50e27e660244ebf6e11a79adb8543557981742b 100644 (file)
@@ -175,7 +175,7 @@ typedef struct {
        uint8_t                 max_lun;
 
        uint32_t                unique_id;
-       uint8_t                 irq;
+       int                     irq;
        uint8_t                 ito;
        caddr_t                 ibuf;
        dma_addr_t              ibuf_dma_h;
index 4cab5b534b259acab51f1f1697e4f72c95f7dbc3..977b6e8d852578d39673748c7a5cde33a7ef0b97 100644 (file)
@@ -10,7 +10,7 @@
  *        2 of the License, or (at your option) any later version.
  *
  * FILE                : megaraid_sas.c
- * Version     : v00.00.03.01
+ * Version     : v00.00.03.05
  *
  * Authors:
  *     Sreenivas Bagalkote     <Sreenivas.Bagalkote@lsil.com>
@@ -71,6 +71,8 @@ static struct megasas_mgmt_info megasas_mgmt_info;
 static struct fasync_struct *megasas_async_queue;
 static DEFINE_MUTEX(megasas_async_queue_mutex);
 
+static u32 megasas_dbg_lvl;
+
 /**
  * megasas_get_cmd -   Get a command from the free pool
  * @instance:          Adapter soft state
@@ -134,6 +136,19 @@ megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs)
        readl(&regs->outbound_intr_mask);
 }
 
+/**
+ * megasas_disable_intr_xscale -Disables interrupt
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_disable_intr_xscale(struct megasas_register_set __iomem * regs)
+{
+       u32 mask = 0x1f;
+       writel(mask, &regs->outbound_intr_mask);
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
 /**
  * megasas_read_fw_status_reg_xscale - returns the current FW status value
  * @regs:                      MFI register set
@@ -185,6 +200,7 @@ static struct megasas_instance_template megasas_instance_template_xscale = {
 
        .fire_cmd = megasas_fire_cmd_xscale,
        .enable_intr = megasas_enable_intr_xscale,
+       .disable_intr = megasas_disable_intr_xscale,
        .clear_intr = megasas_clear_intr_xscale,
        .read_fw_status_reg = megasas_read_fw_status_reg_xscale,
 };
@@ -214,6 +230,19 @@ megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs)
        readl(&regs->outbound_intr_mask);
 }
 
+/**
+ * megasas_disable_intr_ppc -  Disable interrupt
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_disable_intr_ppc(struct megasas_register_set __iomem * regs)
+{
+       u32 mask = 0xFFFFFFFF;
+       writel(mask, &regs->outbound_intr_mask);
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
 /**
  * megasas_read_fw_status_reg_ppc - returns the current FW status value
  * @regs:                      MFI register set
@@ -265,6 +294,7 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
        
        .fire_cmd = megasas_fire_cmd_ppc,
        .enable_intr = megasas_enable_intr_ppc,
+       .disable_intr = megasas_disable_intr_ppc,
        .clear_intr = megasas_clear_intr_ppc,
        .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
 };
@@ -274,25 +304,6 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
 *      specific to ppc (deviceid : 0x60) controllers
 */
 
-/**
- * megasas_disable_intr -      Disables interrupts
- * @regs:                      MFI register set
- */
-static inline void
-megasas_disable_intr(struct megasas_instance *instance)
-{
-       u32 mask = 0x1f; 
-       struct megasas_register_set __iomem *regs = instance->reg_set;
-
-       if(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078R)
-               mask = 0xffffffff;
-
-       writel(mask, &regs->outbound_intr_mask);
-
-       /* Dummy readl to force pci flush */
-       readl(&regs->outbound_intr_mask);
-}
-
 /**
  * megasas_issue_polled -      Issues a polling command
  * @instance:                  Adapter soft state
@@ -336,6 +347,7 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
  * @cmd:                       Command to be issued
  *
  * This function waits on an event for the command to be returned from ISR.
+ * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
  * Used to issue ioctl commands.
  */
 static int
@@ -346,7 +358,8 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance,
 
        instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
 
-       wait_event(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA));
+       wait_event_timeout(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA),
+               MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ);
 
        return 0;
 }
@@ -358,7 +371,8 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance,
  *
  * MFI firmware can abort previously issued AEN comamnd (automatic event
  * notification). The megasas_issue_blocked_abort_cmd() issues such abort
- * cmd and blocks till it is completed.
+ * cmd and waits for return status.
+ * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
  */
 static int
 megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
@@ -392,7 +406,8 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
        /*
         * Wait for this cmd to complete
         */
-       wait_event(instance->abort_cmd_wait_q, (cmd->cmd_status != 0xFF));
+       wait_event_timeout(instance->abort_cmd_wait_q, (cmd->cmd_status != 0xFF),
+               MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ);
 
        megasas_return_cmd(instance, cmd);
        return 0;
@@ -495,6 +510,46 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
        return sge_count;
 }
 
+ /**
+ * megasas_get_frame_count - Computes the number of frames
+ * @sge_count          : number of sg elements
+ *
+ * Returns the number of frames required for numnber of sge's (sge_count)
+ */
+
+u32 megasas_get_frame_count(u8 sge_count)
+{
+       int num_cnt;
+       int sge_bytes;
+       u32 sge_sz;
+       u32 frame_count=0;
+
+       sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
+           sizeof(struct megasas_sge32);
+
+       /*
+       * Main frame can contain 2 SGEs for 64-bit SGLs and
+       * 3 SGEs for 32-bit SGLs
+       */
+       if (IS_DMA64)
+               num_cnt = sge_count - 2;
+       else
+               num_cnt = sge_count - 3;
+
+       if(num_cnt>0){
+               sge_bytes = sge_sz * num_cnt;
+
+               frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
+                   ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ;
+       }
+       /* Main frame */
+       frame_count +=1;
+
+       if (frame_count > 7)
+               frame_count = 8;
+       return frame_count;
+}
+
 /**
  * megasas_build_dcdb -        Prepares a direct cdb (DCDB) command
  * @instance:          Adapter soft state
@@ -508,8 +563,6 @@ static int
 megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
                   struct megasas_cmd *cmd)
 {
-       u32 sge_sz;
-       int sge_bytes;
        u32 is_logical;
        u32 device_id;
        u16 flags = 0;
@@ -544,9 +597,6 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
        /*
         * Construct SGL
         */
-       sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
-           sizeof(struct megasas_sge32);
-
        if (IS_DMA64) {
                pthru->flags |= MFI_FRAME_SGL64;
                pthru->sge_count = megasas_make_sgl64(instance, scp,
@@ -562,17 +612,11 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
        pthru->sense_buf_phys_addr_hi = 0;
        pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
 
-       sge_bytes = sge_sz * pthru->sge_count;
-
        /*
         * Compute the total number of frames this command consumes. FW uses
         * this number to pull sufficient number of frames from host memory.
         */
-       cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
-           ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) + 1;
-
-       if (cmd->frame_count > 7)
-               cmd->frame_count = 8;
+       cmd->frame_count = megasas_get_frame_count(pthru->sge_count);
 
        return cmd->frame_count;
 }
@@ -589,8 +633,6 @@ static int
 megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
                   struct megasas_cmd *cmd)
 {
-       u32 sge_sz;
-       int sge_bytes;
        u32 device_id;
        u8 sc = scp->cmnd[0];
        u16 flags = 0;
@@ -605,7 +647,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
                flags = MFI_FRAME_DIR_READ;
 
        /*
-        * Preare the Logical IO frame: 2nd bit is zero for all read cmds
+        * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
         */
        ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ;
        ldio->cmd_status = 0x0;
@@ -674,9 +716,6 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
        /*
         * Construct SGL
         */
-       sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
-           sizeof(struct megasas_sge32);
-
        if (IS_DMA64) {
                ldio->flags |= MFI_FRAME_SGL64;
                ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
@@ -690,13 +729,11 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
        ldio->sense_buf_phys_addr_hi = 0;
        ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
 
-       sge_bytes = sge_sz * ldio->sge_count;
-
-       cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
-           ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) + 1;
-
-       if (cmd->frame_count > 7)
-               cmd->frame_count = 8;
+       /*
+        * Compute the total number of frames this command consumes. FW uses
+        * this number to pull sufficient number of frames from host memory.
+        */
+       cmd->frame_count = megasas_get_frame_count(ldio->sge_count);
 
        return cmd->frame_count;
 }
@@ -727,6 +764,69 @@ static inline int megasas_is_ldio(struct scsi_cmnd *cmd)
        }
 }
 
+ /**
+ * megasas_dump_pending_frames -       Dumps the frame address of all pending cmds
+ *                                     in FW
+ * @instance:                          Adapter soft state
+ */
+static inline void
+megasas_dump_pending_frames(struct megasas_instance *instance)
+{
+       struct megasas_cmd *cmd;
+       int i,n;
+       union megasas_sgl *mfi_sgl;
+       struct megasas_io_frame *ldio;
+       struct megasas_pthru_frame *pthru;
+       u32 sgcount;
+       u32 max_cmd = instance->max_fw_cmds;
+
+       printk(KERN_ERR "\nmegasas[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no);
+       printk(KERN_ERR "megasas[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding));
+       if (IS_DMA64)
+               printk(KERN_ERR "\nmegasas[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no);
+       else
+               printk(KERN_ERR "\nmegasas[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no);
+
+       printk(KERN_ERR "megasas[%d]: Pending OS cmds in FW : \n",instance->host->host_no);
+       for (i = 0; i < max_cmd; i++) {
+               cmd = instance->cmd_list[i];
+               if(!cmd->scmd)
+                       continue;
+               printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr);
+               if (megasas_is_ldio(cmd->scmd)){
+                       ldio = (struct megasas_io_frame *)cmd->frame;
+                       mfi_sgl = &ldio->sgl;
+                       sgcount = ldio->sge_count;
+                       printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, lba lo : 0x%x, lba_hi : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",instance->host->host_no, cmd->frame_count,ldio->cmd,ldio->target_id, ldio->start_lba_lo,ldio->start_lba_hi,ldio->sense_buf_phys_addr_lo,sgcount);
+               }
+               else {
+                       pthru = (struct megasas_pthru_frame *) cmd->frame;
+                       mfi_sgl = &pthru->sgl;
+                       sgcount = pthru->sge_count;
+                       printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, lun : 0x%x, cdb_len : 0x%x, data xfer len : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",instance->host->host_no,cmd->frame_count,pthru->cmd,pthru->target_id,pthru->lun,pthru->cdb_len , pthru->data_xfer_len,pthru->sense_buf_phys_addr_lo,sgcount);
+               }
+       if(megasas_dbg_lvl & MEGASAS_DBG_LVL){
+               for (n = 0; n < sgcount; n++){
+                       if (IS_DMA64)
+                               printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%08lx ",mfi_sgl->sge64[n].length , (unsigned long)mfi_sgl->sge64[n].phys_addr) ;
+                       else
+                               printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%x ",mfi_sgl->sge32[n].length , mfi_sgl->sge32[n].phys_addr) ;
+                       }
+               }
+               printk(KERN_ERR "\n");
+       } /*for max_cmd*/
+       printk(KERN_ERR "\nmegasas[%d]: Pending Internal cmds in FW : \n",instance->host->host_no);
+       for (i = 0; i < max_cmd; i++) {
+
+               cmd = instance->cmd_list[i];
+
+               if(cmd->sync_cmd == 1){
+                       printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
+               }
+       }
+       printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
+}
+
 /**
  * megasas_queue_command -     Queue entry point
  * @scmd:                      SCSI command to be queued
@@ -832,6 +932,13 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
        }
 
        if (atomic_read(&instance->fw_outstanding)) {
+               /*
+               * Send signal to FW to stop processing any pending cmds.
+               * The controller will be taken offline by the OS now.
+               */
+               writel(MFI_STOP_ADP,
+                               &instance->reg_set->inbound_doorbell);
+               megasas_dump_pending_frames(instance);
                instance->hw_crit_error = 1;
                return FAILED;
        }
@@ -1168,11 +1275,6 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
 static int
 megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
 {
-       u32 producer;
-       u32 consumer;
-       u32 context;
-       struct megasas_cmd *cmd;
-
        /*
         * Check if it is our interrupt
         * Clear the interrupt 
@@ -1180,23 +1282,10 @@ megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
        if(instance->instancet->clear_intr(instance->reg_set))
                return IRQ_NONE;
 
-       producer = *instance->producer;
-       consumer = *instance->consumer;
-
-       while (consumer != producer) {
-               context = instance->reply_queue[consumer];
-
-               cmd = instance->cmd_list[context];
-
-               megasas_complete_cmd(instance, cmd, alt_status);
-
-               consumer++;
-               if (consumer == (instance->max_fw_cmds + 1)) {
-                       consumer = 0;
-               }
-       }
-
-       *instance->consumer = producer;
+        /*
+        * Schedule the tasklet for cmd completion
+        */
+       tasklet_schedule(&instance->isr_tasklet);
 
        return IRQ_HANDLED;
 }
@@ -1229,10 +1318,12 @@ megasas_transition_to_ready(struct megasas_instance* instance)
 
        fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
 
+       if (fw_state != MFI_STATE_READY)
+               printk(KERN_INFO "megasas: Waiting for FW to come to ready"
+                      " state\n");
+
        while (fw_state != MFI_STATE_READY) {
 
-               printk(KERN_INFO "megasas: Waiting for FW to come to ready"
-                      " state\n");
                switch (fw_state) {
 
                case MFI_STATE_FAULT:
@@ -1244,19 +1335,27 @@ megasas_transition_to_ready(struct megasas_instance* instance)
                        /*
                         * Set the CLR bit in inbound doorbell
                         */
-                       writel(MFI_INIT_CLEAR_HANDSHAKE,
+                       writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
                                &instance->reg_set->inbound_doorbell);
 
                        max_wait = 2;
                        cur_state = MFI_STATE_WAIT_HANDSHAKE;
                        break;
 
+               case MFI_STATE_BOOT_MESSAGE_PENDING:
+                       writel(MFI_INIT_HOTPLUG,
+                               &instance->reg_set->inbound_doorbell);
+
+                       max_wait = 10;
+                       cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
+                       break;
+
                case MFI_STATE_OPERATIONAL:
                        /*
-                        * Bring it to READY state; assuming max wait 2 secs
+                        * Bring it to READY state; assuming max wait 10 secs
                         */
-                       megasas_disable_intr(instance);
-                       writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell);
+                       instance->instancet->disable_intr(instance->reg_set);
+                       writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
 
                        max_wait = 10;
                        cur_state = MFI_STATE_OPERATIONAL;
@@ -1323,6 +1422,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
                        return -ENODEV;
                }
        };
+       printk(KERN_INFO "megasas: FW now in Ready state\n");
 
        return 0;
 }
@@ -1352,7 +1452,7 @@ static void megasas_teardown_frame_pool(struct megasas_instance *instance)
                                      cmd->frame_phys_addr);
 
                if (cmd->sense)
-                       pci_pool_free(instance->sense_dma_pool, cmd->frame,
+                       pci_pool_free(instance->sense_dma_pool, cmd->sense,
                                      cmd->sense_phys_addr);
        }
 
@@ -1627,6 +1727,39 @@ megasas_get_ctrl_info(struct megasas_instance *instance,
        return ret;
 }
 
+/**
+ * megasas_complete_cmd_dpc     -      Returns FW's controller structure
+ * @instance_addr:                     Address of adapter soft state
+ *
+ * Tasklet to complete cmds
+ */
+void megasas_complete_cmd_dpc(unsigned long instance_addr)
+{
+       u32 producer;
+       u32 consumer;
+       u32 context;
+       struct megasas_cmd *cmd;
+       struct megasas_instance *instance = (struct megasas_instance *)instance_addr;
+
+       producer = *instance->producer;
+       consumer = *instance->consumer;
+
+       while (consumer != producer) {
+               context = instance->reply_queue[consumer];
+
+               cmd = instance->cmd_list[context];
+
+               megasas_complete_cmd(instance, cmd, DID_OK);
+
+               consumer++;
+               if (consumer == (instance->max_fw_cmds + 1)) {
+                       consumer = 0;
+               }
+       }
+
+       *instance->consumer = producer;
+}
+
 /**
  * megasas_init_mfi -  Initializes the FW
  * @instance:          Adapter soft state
@@ -1690,6 +1823,12 @@ static int megasas_init_mfi(struct megasas_instance *instance)
         * Get various operational parameters from status register
         */
        instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
+       /*
+        * Reduce the max supported cmds by 1. This is to ensure that the
+        * reply_q_sz (1 more than the max cmd that driver may send)
+        * does not exceed max cmds that the FW can support
+        */
+       instance->max_fw_cmds = instance->max_fw_cmds-1;
        instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> 
                                        0x10;
        /*
@@ -1754,7 +1893,7 @@ static int megasas_init_mfi(struct megasas_instance *instance)
        /*
         * disable the intr before firing the init frame to FW
         */
-       megasas_disable_intr(instance);
+       instance->instancet->disable_intr(instance->reg_set);
 
        /*
         * Issue the init frame in polled mode
@@ -1791,6 +1930,12 @@ static int megasas_init_mfi(struct megasas_instance *instance)
 
        kfree(ctrl_info);
 
+        /*
+       * Setup tasklet for cmd completion
+       */
+
+        tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
+                        (unsigned long)instance);
        return 0;
 
       fail_fw_init:
@@ -2182,6 +2327,8 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
        instance->init_id = MEGASAS_DEFAULT_INIT_ID;
 
+       megasas_dbg_lvl = 0;
+
        /*
         * Initialize MFI Firmware
         */
@@ -2234,7 +2381,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        megasas_mgmt_info.max_index--;
 
        pci_set_drvdata(pdev, NULL);
-       megasas_disable_intr(instance);
+       instance->instancet->disable_intr(instance->reg_set);
        free_irq(instance->pdev->irq, instance);
 
        megasas_release_mfi(instance);
@@ -2348,6 +2495,7 @@ static void megasas_detach_one(struct pci_dev *pdev)
        scsi_remove_host(instance->host);
        megasas_flush_cache(instance);
        megasas_shutdown_controller(instance);
+       tasklet_kill(&instance->isr_tasklet);
 
        /*
         * Take the instance off the instance array. Note that we will not
@@ -2364,7 +2512,7 @@ static void megasas_detach_one(struct pci_dev *pdev)
 
        pci_set_drvdata(instance->pdev, NULL);
 
-       megasas_disable_intr(instance);
+       instance->instancet->disable_intr(instance->reg_set);
 
        free_irq(instance->pdev->irq, instance);
 
@@ -2716,7 +2864,8 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
        int i;
        int error = 0;
 
-       clear_user(ioc, sizeof(*ioc));
+       if (clear_user(ioc, sizeof(*ioc)))
+               return -EFAULT;
 
        if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) ||
            copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) ||
@@ -2808,6 +2957,26 @@ megasas_sysfs_show_release_date(struct device_driver *dd, char *buf)
 static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date,
                   NULL);
 
+static ssize_t
+megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
+{
+       return sprintf(buf,"%u",megasas_dbg_lvl);
+}
+
+static ssize_t
+megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t count)
+{
+       int retval = count;
+       if(sscanf(buf,"%u",&megasas_dbg_lvl)<1){
+               printk(KERN_ERR "megasas: could not set dbg_lvl\n");
+               retval = -EINVAL;
+       }
+       return retval;
+}
+
+static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUGO, megasas_sysfs_show_dbg_lvl,
+                  megasas_sysfs_set_dbg_lvl);
+
 /**
  * megasas_init - Driver load entry point
  */
@@ -2842,14 +3011,33 @@ static int __init megasas_init(void)
 
        if (rval) {
                printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n");
-               unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
-       }
-
-       driver_create_file(&megasas_pci_driver.driver, &driver_attr_version);
-       driver_create_file(&megasas_pci_driver.driver,
-                          &driver_attr_release_date);
+               goto err_pcidrv;
+       }
+
+       rval = driver_create_file(&megasas_pci_driver.driver,
+                                 &driver_attr_version);
+       if (rval)
+               goto err_dcf_attr_ver;
+       rval = driver_create_file(&megasas_pci_driver.driver,
+                                 &driver_attr_release_date);
+       if (rval)
+               goto err_dcf_rel_date;
+       rval = driver_create_file(&megasas_pci_driver.driver,
+                                 &driver_attr_dbg_lvl);
+       if (rval)
+               goto err_dcf_dbg_lvl;
 
        return rval;
+err_dcf_dbg_lvl:
+       driver_remove_file(&megasas_pci_driver.driver,
+                          &driver_attr_release_date);
+err_dcf_rel_date:
+       driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
+err_dcf_attr_ver:
+       pci_unregister_driver(&megasas_pci_driver);
+err_pcidrv:
+       unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
+       return rval;
 }
 
 /**
@@ -2857,9 +3045,11 @@ static int __init megasas_init(void)
  */
 static void __exit megasas_exit(void)
 {
-       driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
+       driver_remove_file(&megasas_pci_driver.driver,
+                          &driver_attr_dbg_lvl);
        driver_remove_file(&megasas_pci_driver.driver,
                           &driver_attr_release_date);
+       driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
 
        pci_unregister_driver(&megasas_pci_driver);
        unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
index 3531a14222a737780f8574eae0e010a71c6fd137..55eddcf8eb156896138d07e75ce79f362e65aadf 100644 (file)
@@ -18,9 +18,9 @@
 /**
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                                "00.00.03.01"
-#define MEGASAS_RELDATE                                "May 14, 2006"
-#define MEGASAS_EXT_VERSION                    "Sun May 14 22:49:52 PDT 2006"
+#define MEGASAS_VERSION                                "00.00.03.05"
+#define MEGASAS_RELDATE                                "Oct 02, 2006"
+#define MEGASAS_EXT_VERSION                    "Mon Oct 02 11:21:32 PDT 2006"
 
 /*
  * Device IDs
@@ -50,6 +50,7 @@
 #define MFI_STATE_WAIT_HANDSHAKE               0x60000000
 #define MFI_STATE_FW_INIT_2                    0x70000000
 #define MFI_STATE_DEVICE_SCAN                  0x80000000
+#define MFI_STATE_BOOT_MESSAGE_PENDING         0x90000000
 #define MFI_STATE_FLUSH_CACHE                  0xA0000000
 #define MFI_STATE_READY                                0xB0000000
 #define MFI_STATE_OPERATIONAL                  0xC0000000
  * READY       : Move from OPERATIONAL to READY state; discard queue info
  * MFIMODE     : Discard (possible) low MFA posted in 64-bit mode (??)
  * CLR_HANDSHAKE: FW is waiting for HANDSHAKE from BIOS or Driver
+ * HOTPLUG     : Resume from Hotplug
+ * MFI_STOP_ADP        : Send signal to FW to stop processing
  */
-#define MFI_INIT_ABORT                         0x00000000
+#define MFI_INIT_ABORT                         0x00000001
 #define MFI_INIT_READY                         0x00000002
 #define MFI_INIT_MFIMODE                       0x00000004
 #define MFI_INIT_CLEAR_HANDSHAKE               0x00000008
-#define MFI_RESET_FLAGS                                MFI_INIT_READY|MFI_INIT_MFIMODE
+#define MFI_INIT_HOTPLUG                       0x00000010
+#define MFI_STOP_ADP                           0x00000020
+#define MFI_RESET_FLAGS                                MFI_INIT_READY| \
+                                               MFI_INIT_MFIMODE| \
+                                               MFI_INIT_ABORT
 
 /**
  * MFI frame flags
@@ -530,6 +537,8 @@ struct megasas_ctrl_info {
 #define MEGASAS_MAX_LUN                                8
 #define MEGASAS_MAX_LD                         64
 
+#define MEGASAS_DBG_LVL                                1
+
 /*
  * When SCSI mid-layer calls driver's reset routine, driver waits for
  * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note
@@ -538,6 +547,7 @@ struct megasas_ctrl_info {
  * every MEGASAS_RESET_NOTICE_INTERVAL seconds
  */
 #define MEGASAS_RESET_WAIT_TIME                        180
+#define MEGASAS_INTERNAL_CMD_WAIT_TIME         180
 #define        MEGASAS_RESET_NOTICE_INTERVAL           5
 
 #define MEGASAS_IOCTL_CMD                      0
@@ -1042,6 +1052,7 @@ struct megasas_evt_detail {
        void (*fire_cmd)(dma_addr_t ,u32 ,struct megasas_register_set __iomem *);
 
        void (*enable_intr)(struct megasas_register_set __iomem *) ;
+       void (*disable_intr)(struct megasas_register_set __iomem *);
 
        int (*clear_intr)(struct megasas_register_set __iomem *);
 
@@ -1092,6 +1103,7 @@ struct megasas_instance {
        u32 hw_crit_error;
 
        struct megasas_instance_template *instancet;
+       struct tasklet_struct isr_tasklet;
 };
 
 #define MEGASAS_IS_LOGICAL(scp)                                                \
index bfb4f49e125d28b82a5dea1472641c1d43e45339..1c624ce8189761595acb49b4d2dcea049d95fd75 100644 (file)
@@ -3581,7 +3581,7 @@ static struct pci_driver nsp32_driver = {
  */
 static int __init init_nsp32(void) {
        nsp32_msg(KERN_INFO, "loading...");
-       return pci_module_init(&nsp32_driver);
+       return pci_register_driver(&nsp32_driver);
 }
 
 static void __exit exit_nsp32(void) {
index 5addf9fb1e156b774edf4ee41d72016776333714..a976e8193d163d1ff983fb405d16d7a981a8e8c1 100644 (file)
@@ -619,47 +619,5 @@ typedef struct _nsp32_hw_data {
 #define REQSACK_TIMEOUT_TIME   10000   /* max wait time for REQ/SACK assertion
                                           or negation, 10000us == 10ms */
 
-/**************************************************************************
- * Compatibility functions
- */
-
-/* for Kernel 2.4 */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
-# define scsi_register_host(template)  scsi_register_module(MODULE_SCSI_HA, template)
-# define scsi_unregister_host(template) scsi_unregister_module(MODULE_SCSI_HA, template)
-# define scsi_host_put(host)            scsi_unregister(host)
-# define pci_name(pci_dev)              ((pci_dev)->slot_name)
-
-typedef void irqreturn_t;
-# define IRQ_NONE      /* */
-# define IRQ_HANDLED   /* */
-# define IRQ_RETVAL(x) /* */
-
-/* This is ad-hoc version of scsi_host_get_next() */
-static inline struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *host)
-{
-       if (host == NULL) {
-               return scsi_hostlist;
-       } else {
-               return host->next;
-       }
-}
-
-/* This is ad-hoc version of scsi_host_hn_get() */
-static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno)
-{
-       struct Scsi_Host *host;
-
-       for (host = scsi_host_get_next(NULL); host != NULL;
-            host = scsi_host_get_next(host)) {
-               if (host->host_no == hostno) {
-                       break;
-               }
-       }
-
-       return host;
-}
-#endif
-
 #endif /* _NSP32_H */
 /* end */
index 4a2fed350d4e21620b134d2afac1244cb87670e0..824fe080d1dc2b9d0b2e1a35b2e1a64464e615b9 100644 (file)
@@ -4843,8 +4843,7 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp)
 static int osst_ioctl(struct inode * inode,struct file * file,
         unsigned int cmd_in, unsigned long arg)
 {
-       int                   i, cmd_nr, cmd_type, retval = 0;
-       unsigned int          blk;
+       int                   i, cmd_nr, cmd_type, blk, retval = 0;
        struct st_modedef   * STm;
        struct st_partstat  * STps;
        struct osst_request * SRpnt = NULL;
@@ -5207,12 +5206,12 @@ static struct osst_buffer * new_tape_buffer( int from_initialization, int need_d
                priority = GFP_KERNEL;
 
        i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
-       tb = (struct osst_buffer *)kmalloc(i, priority);
+       tb = kzalloc(i, priority);
        if (!tb) {
                printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
                return NULL;
        }
-       memset(tb, 0, i);
+
        tb->sg_segs = tb->orig_sg_segs = 0;
        tb->use_sg = max_sg;
        tb->in_use = 1;
@@ -5575,9 +5574,9 @@ static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
 
 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
 
-static void osst_create_driverfs_files(struct device_driver *driverfs)
+static int osst_create_driverfs_files(struct device_driver *driverfs)
 {
-       driver_create_file(driverfs, &driver_attr_version);
+       return driver_create_file(driverfs, &driver_attr_version);
 }
 
 static void osst_remove_driverfs_files(struct device_driver *driverfs)
@@ -5663,50 +5662,70 @@ CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
 
 static struct class *osst_sysfs_class;
 
-static int osst_sysfs_valid = 0;
-
-static void osst_sysfs_init(void)
+static int osst_sysfs_init(void)
 {
        osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
-       if ( IS_ERR(osst_sysfs_class) )
-               printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
-       else
-               osst_sysfs_valid = 1;
+       if (IS_ERR(osst_sysfs_class)) {
+               printk(KERN_ERR "osst :W: Unable to register sysfs class\n");
+               return PTR_ERR(osst_sysfs_class);
+       }
+
+       return 0;
 }
 
-static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
+static void osst_sysfs_destroy(dev_t dev)
 {
-       struct class_device *osst_class_member;
+       class_device_destroy(osst_sysfs_class, dev);
+}
 
-       if (!osst_sysfs_valid) return;
+static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
+{
+       struct class_device *osst_class_member;
+       int err;
 
-       osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name);
+       osst_class_member = class_device_create(osst_sysfs_class, NULL, dev,
+                                               device, "%s", name);
        if (IS_ERR(osst_class_member)) {
                printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
-               return;
+               return PTR_ERR(osst_class_member);
        }
+
        class_set_devdata(osst_class_member, STp);
-       class_device_create_file(osst_class_member, &class_device_attr_ADR_rev);
-       class_device_create_file(osst_class_member, &class_device_attr_media_version);
-       class_device_create_file(osst_class_member, &class_device_attr_capacity);
-       class_device_create_file(osst_class_member, &class_device_attr_BOT_frame);
-       class_device_create_file(osst_class_member, &class_device_attr_EOD_frame);
-       class_device_create_file(osst_class_member, &class_device_attr_file_count);
-}
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_ADR_rev);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_media_version);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_capacity);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_BOT_frame);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_EOD_frame);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_file_count);
+       if (err)
+               goto err_out;
 
-static void osst_sysfs_destroy(dev_t dev)
-{
-       if (!osst_sysfs_valid) return; 
+       return 0;
 
-       class_device_destroy(osst_sysfs_class, dev);
+err_out:
+       osst_sysfs_destroy(dev);
+       return err;
 }
 
 static void osst_sysfs_cleanup(void)
 {
-       if (osst_sysfs_valid) {
-               class_destroy(osst_sysfs_class);
-               osst_sysfs_valid = 0;
-       }
+       class_destroy(osst_sysfs_class);
 }
 
 /*
@@ -5721,7 +5740,7 @@ static int osst_probe(struct device *dev)
        struct st_partstat * STps;
        struct osst_buffer * buffer;
        struct gendisk     * drive;
-       int                  i, dev_num;
+       int                  i, dev_num, err = -ENODEV;
 
        if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
                return -ENODEV;
@@ -5849,13 +5868,20 @@ static int osst_probe(struct device *dev)
        init_MUTEX(&tpnt->lock);
        osst_nr_dev++;
        write_unlock(&os_scsi_tapes_lock);
+
        {
                char name[8];
+
                /*  Rewind entry  */
-               osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
+               err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
+               if (err)
+                       goto out_free_buffer;
+
                /*  No-rewind entry  */
                snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
-               osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
+               err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
+               if (err)
+                       goto out_free_sysfs1;
        }
 
        sdev_printk(KERN_INFO, SDp,
@@ -5864,9 +5890,13 @@ static int osst_probe(struct device *dev)
 
        return 0;
 
+out_free_sysfs1:
+       osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num));
+out_free_buffer:
+       kfree(buffer);
 out_put_disk:
         put_disk(drive);
-        return -ENODEV;
+        return err;
 };
 
 static int osst_remove(struct device *dev)
@@ -5903,19 +5933,39 @@ static int osst_remove(struct device *dev)
 
 static int __init init_osst(void) 
 {
+       int err;
+
        printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
 
        validate_options();
-       osst_sysfs_init();
 
-       if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
+       err = osst_sysfs_init();
+       if (err)
+               return err;
+
+       err = register_chrdev(OSST_MAJOR, "osst", &osst_fops);
+       if (err < 0) {
                printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
-               osst_sysfs_cleanup();
-               return 1;
+               goto err_out;
        }
-       osst_create_driverfs_files(&osst_template.gendrv);
+
+       err = scsi_register_driver(&osst_template.gendrv);
+       if (err)
+               goto err_out_chrdev;
+
+       err = osst_create_driverfs_files(&osst_template.gendrv);
+       if (err)
+               goto err_out_scsidrv;
 
        return 0;
+
+err_out_scsidrv:
+       scsi_unregister_driver(&osst_template.gendrv);
+err_out_chrdev:
+       unregister_chrdev(OSST_MAJOR, "osst");
+err_out:
+       osst_sysfs_cleanup();
+       return err;
 }
 
 static void __exit exit_osst (void)
index 0d4c04e1f3de3f941655ec67a023992e77d46f04..053303d361186b7f18025f5967a6900e2503a094 100644 (file)
@@ -80,7 +80,6 @@ static int       free_ports = 0;
 module_param(free_ports, bool, 0);
 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
 
-/* /usr/src/linux/drivers/scsi/hosts.h */
 static struct scsi_host_template nsp_driver_template = {
        .proc_name               = "nsp_cs",
        .proc_info               = nsp_proc_info,
index 332151e2a0189eb57a529eb4461afc218811a492..9f33e5946c0d869e03f755bce135926ef74ca1e5 100644 (file)
@@ -2862,7 +2862,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
        memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
 
        /* Set ISP command timeout. */
-       pkt->timeout = cpu_to_le16(30);
+       pkt->timeout = cpu_to_le16(cmd->timeout_per_command/HZ);
 
        /* Set device target ID and LUN */
        pkt->lun = SCSI_LUN_32(cmd);
@@ -3161,7 +3161,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
        memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
 
        /* Set ISP command timeout. */
-       pkt->timeout = cpu_to_le16(30);
+       pkt->timeout = cpu_to_le16(cmd->timeout_per_command/HZ);
 
        /* Set device target ID and LUN */
        pkt->lun = SCSI_LUN_32(cmd);
@@ -4484,7 +4484,7 @@ qla1280_init(void)
                qla1280_setup(qla1280);
 #endif
 
-       return pci_module_init(&qla1280_pci_driver);
+       return pci_register_driver(&qla1280_pci_driver);
 }
 
 static void __exit
index 87f90c4f08e94e07ae7cab8353ce67998a677a41..ee75a71f3c6608be7a4eb314284e127c6f999d03 100644 (file)
@@ -691,13 +691,13 @@ qla2x00_get_host_speed(struct Scsi_Host *shost)
        uint32_t speed = 0;
 
        switch (ha->link_data_rate) {
-       case LDR_1GB:
+       case PORT_SPEED_1GB:
                speed = 1;
                break;
-       case LDR_2GB:
+       case PORT_SPEED_2GB:
                speed = 2;
                break;
-       case LDR_4GB:
+       case PORT_SPEED_4GB:
                speed = 4;
                break;
        }
@@ -849,6 +849,49 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
        return pfc_host_stat;
 }
 
+static void
+qla2x00_get_host_symbolic_name(struct Scsi_Host *shost)
+{
+       scsi_qla_host_t *ha = to_qla_host(shost);
+
+       qla2x00_get_sym_node_name(ha, fc_host_symbolic_name(shost));
+}
+
+static void
+qla2x00_set_host_system_hostname(struct Scsi_Host *shost)
+{
+       scsi_qla_host_t *ha = to_qla_host(shost);
+
+       set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
+}
+
+static void
+qla2x00_get_host_fabric_name(struct Scsi_Host *shost)
+{
+       scsi_qla_host_t *ha = to_qla_host(shost);
+       u64 node_name;
+
+       if (ha->device_flags & SWITCH_FOUND)
+               node_name = wwn_to_u64(ha->fabric_node_name);
+       else
+               node_name = wwn_to_u64(ha->node_name);
+
+       fc_host_fabric_name(shost) = node_name;
+}
+
+static void
+qla2x00_get_host_port_state(struct Scsi_Host *shost)
+{
+       scsi_qla_host_t *ha = to_qla_host(shost);
+
+       if (!ha->flags.online)
+               fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
+       else if (atomic_read(&ha->loop_state) == LOOP_TIMEOUT)
+               fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
+       else
+               fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
+}
+
 struct fc_function_template qla2xxx_transport_functions = {
 
        .show_host_node_name = 1,
@@ -861,6 +904,14 @@ struct fc_function_template qla2xxx_transport_functions = {
        .show_host_speed = 1,
        .get_host_port_type = qla2x00_get_host_port_type,
        .show_host_port_type = 1,
+       .get_host_symbolic_name = qla2x00_get_host_symbolic_name,
+       .show_host_symbolic_name = 1,
+       .set_host_system_hostname = qla2x00_set_host_system_hostname,
+       .show_host_system_hostname = 1,
+       .get_host_fabric_name = qla2x00_get_host_fabric_name,
+       .show_host_fabric_name = 1,
+       .get_host_port_state = qla2x00_get_host_port_state,
+       .show_host_port_state = 1,
 
        .dd_fcrport_size = sizeof(struct fc_port *),
        .show_rport_supported_classes = 1,
index 0930260aec2cd89e272387c487c4a1156b661cf7..c37a30aa2146f1fd69b28ad36f0ca1cede8631f0 100644 (file)
@@ -608,6 +608,7 @@ typedef struct {
  */
 #define MBC_SERDES_PARAMS              0x10    /* Serdes Tx Parameters. */
 #define MBC_GET_IOCB_STATUS            0x12    /* Get IOCB status command. */
+#define MBC_PORT_PARAMS                        0x1A    /* Port iDMA Parameters. */
 #define MBC_GET_TIMEOUT_PARAMS         0x22    /* Get FW timeouts. */
 #define MBC_TRACE_CONTROL              0x27    /* Trace control command. */
 #define MBC_GEN_SYSTEM_ERROR           0x2a    /* Generate System Error. */
@@ -1497,6 +1498,9 @@ typedef struct {
        port_id_t d_id;
        uint8_t node_name[WWN_SIZE];
        uint8_t port_name[WWN_SIZE];
+       uint8_t fabric_port_name[WWN_SIZE];
+       uint16_t fp_speeds;
+       uint16_t fp_speed;
 } sw_info_t;
 
 /*
@@ -1524,6 +1528,9 @@ typedef struct fc_port {
        uint16_t loop_id;
        uint16_t old_loop_id;
 
+       uint8_t fabric_port_name[WWN_SIZE];
+       uint16_t fp_speed;
+
        fc_port_type_t port_type;
 
        atomic_t state;
@@ -1635,6 +1642,15 @@ typedef struct fc_port {
 #define        RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255)
 #define        RSNN_NN_RSP_SIZE 16
 
+#define        GFPN_ID_CMD     0x11C
+#define        GFPN_ID_REQ_SIZE (16 + 4)
+#define        GFPN_ID_RSP_SIZE (16 + 8)
+
+#define        GPSC_CMD        0x127
+#define        GPSC_REQ_SIZE   (16 + 8)
+#define        GPSC_RSP_SIZE   (16 + 2 + 2)
+
+
 /*
  * HBA attribute types.
  */
@@ -1748,7 +1764,7 @@ struct ct_sns_req {
        uint8_t reserved[3];
 
        union {
-               /* GA_NXT, GPN_ID, GNN_ID, GFT_ID */
+               /* GA_NXT, GPN_ID, GNN_ID, GFT_ID, GFPN_ID */
                struct {
                        uint8_t reserved;
                        uint8_t port_id[3];
@@ -1823,6 +1839,10 @@ struct ct_sns_req {
                struct {
                        uint8_t port_name[8];
                } dpa;
+
+               struct {
+                       uint8_t port_name[8];
+               } gpsc;
        } req;
 };
 
@@ -1886,6 +1906,15 @@ struct ct_sns_rsp {
                        uint8_t port_name[8];
                        struct ct_fdmi_hba_attributes attrs;
                } ghat;
+
+               struct {
+                       uint8_t port_name[8];
+               } gfpn_id;
+
+               struct {
+                       uint16_t speeds;
+                       uint16_t speed;
+               } gpsc;
        } rsp;
 };
 
@@ -2182,11 +2211,11 @@ typedef struct scsi_qla_host {
        uint16_t        max_public_loop_ids;
        uint16_t        min_external_loopid;    /* First external loop Id */
 
+#define PORT_SPEED_UNKNOWN 0xFFFF
+#define PORT_SPEED_1GB 0x00
+#define PORT_SPEED_2GB 0x01
+#define PORT_SPEED_4GB 0x03
        uint16_t        link_data_rate;         /* F/W operating speed */
-#define LDR_1GB                0
-#define LDR_2GB                1
-#define LDR_4GB                3
-#define LDR_UNKNOWN    0xFFFF
 
        uint8_t         current_topology;
        uint8_t         prev_topology;
@@ -2333,6 +2362,7 @@ typedef struct scsi_qla_host {
 
        uint8_t         *node_name;
        uint8_t         *port_name;
+       uint8_t         fabric_node_name[WWN_SIZE];
        uint32_t    isp_abort_cnt;
 
        /* Option ROM information. */
index 8311ac2b93a858c7ca5d20131e90588e6e74d15f..bef7011378c637070262d7a3f3b53ef445eb008b 100644 (file)
@@ -208,6 +208,12 @@ qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t);
 extern int
 qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
 
+extern int
+qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t *, uint16_t *);
+
+extern int
+qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
+
 /*
  * Global Function Prototypes in qla_isr.c source file.
  */
@@ -279,6 +285,9 @@ extern int qla2x00_rsnn_nn(scsi_qla_host_t *);
 extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
 extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
 extern int qla2x00_fdmi_register(scsi_qla_host_t *);
+extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *);
+extern int qla2x00_gpsc(scsi_qla_host_t *, sw_info_t *);
+extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *);
 
 /*
  * Global Function Prototypes in qla_attr.c source file.
index 2ebf259fccb25902a94fcf8bb17504187eacad84..97fbc62ec66958ac4319aea507e2e4750c1ddb10 100644 (file)
@@ -612,6 +612,14 @@ qla2x00_rnn_id(scsi_qla_host_t *ha)
        return (rval);
 }
 
+void
+qla2x00_get_sym_node_name(scsi_qla_host_t *ha, uint8_t *snn)
+{
+       sprintf(snn, "%s FW:v%d.%02d.%02d DVR:v%s",ha->model_number,
+           ha->fw_major_version, ha->fw_minor_version,
+           ha->fw_subminor_version, qla2x00_version_str);
+}
+
 /**
  * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
  * @ha: HA context
@@ -622,9 +630,6 @@ int
 qla2x00_rsnn_nn(scsi_qla_host_t *ha)
 {
        int             rval;
-       uint8_t         *snn;
-       uint8_t         version[20];
-
        ms_iocb_entry_t *ms_pkt;
        struct ct_sns_req       *ct_req;
        struct ct_sns_rsp       *ct_rsp;
@@ -649,20 +654,11 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
        memcpy(ct_req->req.rsnn_nn.node_name, ha->node_name, WWN_SIZE);
 
        /* Prepare the Symbolic Node Name */
-       /* Board type */
-       snn = ct_req->req.rsnn_nn.sym_node_name;
-       strcpy(snn, ha->model_number);
-       /* Firmware version */
-       strcat(snn, " FW:v");
-       sprintf(version, "%d.%02d.%02d", ha->fw_major_version,
-           ha->fw_minor_version, ha->fw_subminor_version);
-       strcat(snn, version);
-       /* Driver version */
-       strcat(snn, " DVR:v");
-       strcat(snn, qla2x00_version_str);
+       qla2x00_get_sym_node_name(ha, ct_req->req.rsnn_nn.sym_node_name);
 
        /* Calculate SNN length */
-       ct_req->req.rsnn_nn.name_len = (uint8_t)strlen(snn);
+       ct_req->req.rsnn_nn.name_len =
+           (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
 
        /* Update MS IOCB request */
        ms_pkt->req_bytecount =
@@ -687,7 +683,6 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
        return (rval);
 }
 
-
 /**
  * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
  * @ha: HA context
@@ -1585,6 +1580,21 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
        DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no,
            eiter->a.os_dev_name));
 
+       /* Hostname. */
+       if (strlen(fc_host_system_hostname(ha->host))) {
+               eiter = (struct ct_fdmi_port_attr *) (entries + size);
+               eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME);
+               snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
+                   "%s", fc_host_system_hostname(ha->host));
+               alen = strlen(eiter->a.host_name);
+               alen += (alen & 3) ? (4 - (alen & 3)) : 4;
+               eiter->len = cpu_to_be16(4 + alen);
+               size += 4 + alen;
+
+               DEBUG13(printk("%s(%ld): HOSTNAME=%s.\n", __func__,
+                   ha->host_no, eiter->a.host_name));
+       }
+
        /* Update MS request size. */
        qla2x00_update_ms_fdmi_iocb(ha, size + 16);
 
@@ -1647,3 +1657,189 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha)
 
        return rval;
 }
+
+/**
+ * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
+ * @ha: HA context
+ * @list: switch info entries to populate
+ *
+ * Returns 0 on success.
+ */
+int
+qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list)
+{
+       int             rval;
+       uint16_t        i;
+
+       ms_iocb_entry_t *ms_pkt;
+       struct ct_sns_req       *ct_req;
+       struct ct_sns_rsp       *ct_rsp;
+
+       if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+               return QLA_FUNCTION_FAILED;
+
+       for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+               /* Issue GFPN_ID */
+               memset(list[i].fabric_port_name, 0, WWN_SIZE);
+
+               /* Prepare common MS IOCB */
+               ms_pkt = qla2x00_prep_ms_iocb(ha, GFPN_ID_REQ_SIZE,
+                   GFPN_ID_RSP_SIZE);
+
+               /* Prepare CT request */
+               ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD,
+                   GFPN_ID_RSP_SIZE);
+               ct_rsp = &ha->ct_sns->p.rsp;
+
+               /* Prepare CT arguments -- port_id */
+               ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
+               ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
+               ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
+
+               /* Execute MS IOCB */
+               rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
+                   sizeof(ms_iocb_entry_t));
+               if (rval != QLA_SUCCESS) {
+                       /*EMPTY*/
+                       DEBUG2_3(printk("scsi(%ld): GFPN_ID issue IOCB "
+                           "failed (%d).\n", ha->host_no, rval));
+               } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp,
+                   "GFPN_ID") != QLA_SUCCESS) {
+                       rval = QLA_FUNCTION_FAILED;
+               } else {
+                       /* Save fabric portname */
+                       memcpy(list[i].fabric_port_name,
+                           ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
+               }
+
+               /* Last device exit. */
+               if (list[i].d_id.b.rsvd_1 != 0)
+                       break;
+       }
+
+       return (rval);
+}
+
+static inline void *
+qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size,
+    uint32_t rsp_size)
+{
+       struct ct_entry_24xx *ct_pkt;
+
+       ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
+       memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
+
+       ct_pkt->entry_type = CT_IOCB_TYPE;
+       ct_pkt->entry_count = 1;
+       ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id);
+       ct_pkt->timeout = __constant_cpu_to_le16(59);
+       ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
+       ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
+       ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
+       ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
+
+       ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
+       ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
+       ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
+
+       ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
+       ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
+       ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
+
+       return ct_pkt;
+}
+
+
+static inline struct ct_sns_req *
+qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd,
+    uint16_t rsp_size)
+{
+       memset(ct_req, 0, sizeof(struct ct_sns_pkt));
+
+       ct_req->header.revision = 0x01;
+       ct_req->header.gs_type = 0xFA;
+       ct_req->header.gs_subtype = 0x01;
+       ct_req->command = cpu_to_be16(cmd);
+       ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
+
+       return ct_req;
+}
+
+/**
+ * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
+ * @ha: HA context
+ * @list: switch info entries to populate
+ *
+ * Returns 0 on success.
+ */
+int
+qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list)
+{
+       int             rval;
+       uint16_t        i;
+
+       ms_iocb_entry_t *ms_pkt;
+       struct ct_sns_req       *ct_req;
+       struct ct_sns_rsp       *ct_rsp;
+
+       if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+               return QLA_FUNCTION_FAILED;
+
+       rval = qla2x00_mgmt_svr_login(ha);
+       if (rval)
+               return rval;
+
+       for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+               /* Issue GFPN_ID */
+               list[i].fp_speeds = list[i].fp_speed = 0;
+
+               /* Prepare common MS IOCB */
+               ms_pkt = qla24xx_prep_ms_fm_iocb(ha, GPSC_REQ_SIZE,
+                   GPSC_RSP_SIZE);
+
+               /* Prepare CT request */
+               ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req,
+                   GPSC_CMD, GPSC_RSP_SIZE);
+               ct_rsp = &ha->ct_sns->p.rsp;
+
+               /* Prepare CT arguments -- port_name */
+               memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
+                   WWN_SIZE);
+
+               /* Execute MS IOCB */
+               rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
+                   sizeof(ms_iocb_entry_t));
+               if (rval != QLA_SUCCESS) {
+                       /*EMPTY*/
+                       DEBUG2_3(printk("scsi(%ld): GPSC issue IOCB "
+                           "failed (%d).\n", ha->host_no, rval));
+               } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp,
+                   "GPSC") != QLA_SUCCESS) {
+                       rval = QLA_FUNCTION_FAILED;
+               } else {
+                       /* Save portname */
+                       list[i].fp_speeds = ct_rsp->rsp.gpsc.speeds;
+                       list[i].fp_speed = ct_rsp->rsp.gpsc.speed;
+
+                       DEBUG2_3(printk("scsi(%ld): GPSC ext entry - "
+                           "fpn %02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x "
+                           "speed=%04x.\n", ha->host_no,
+                           list[i].fabric_port_name[0],
+                           list[i].fabric_port_name[1],
+                           list[i].fabric_port_name[2],
+                           list[i].fabric_port_name[3],
+                           list[i].fabric_port_name[4],
+                           list[i].fabric_port_name[5],
+                           list[i].fabric_port_name[6],
+                           list[i].fabric_port_name[7],
+                           be16_to_cpu(list[i].fp_speeds),
+                           be16_to_cpu(list[i].fp_speed)));
+               }
+
+               /* Last device exit. */
+               if (list[i].d_id.b.rsvd_1 != 0)
+                       break;
+       }
+
+       return (rval);
+}
index 859649160caaa795b4fe3213e98e27fa98849913..d5d26273c04e504a0a188ec3a0e777921b3ff323 100644 (file)
@@ -2074,6 +2074,19 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
                        new_fcport->flags &= ~FCF_FABRIC_DEVICE;
                }
 
+               /* Base iIDMA settings on HBA port speed. */
+               switch (ha->link_data_rate) {
+               case PORT_SPEED_1GB:
+                       fcport->fp_speed = cpu_to_be16(BIT_15);
+                       break;
+               case PORT_SPEED_2GB:
+                       fcport->fp_speed = cpu_to_be16(BIT_14);
+                       break;
+               case PORT_SPEED_4GB:
+                       fcport->fp_speed = cpu_to_be16(BIT_13);
+                       break;
+               }
+
                qla2x00_update_fcport(ha, fcport);
 
                found_devs++;
@@ -2109,6 +2122,62 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
        }
 }
 
+static void
+qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
+{
+#define LS_UNKNOWN      2
+       static char *link_speeds[5] = { "1", "2", "?", "4" };
+       int rval;
+       uint16_t port_speed, mb[6];
+
+       if (!IS_QLA24XX(ha))
+               return;
+
+       switch (be16_to_cpu(fcport->fp_speed)) {
+       case BIT_15:
+               port_speed = PORT_SPEED_1GB;
+               break;
+       case BIT_14:
+               port_speed = PORT_SPEED_2GB;
+               break;
+       case BIT_13:
+               port_speed = PORT_SPEED_4GB;
+               break;
+       default:
+               DEBUG2(printk("scsi(%ld): %02x%02x%02x%02x%02x%02x%02x%02x -- "
+                   "unsupported FM port operating speed (%04x).\n",
+                   ha->host_no, fcport->port_name[0], fcport->port_name[1],
+                   fcport->port_name[2], fcport->port_name[3],
+                   fcport->port_name[4], fcport->port_name[5],
+                   fcport->port_name[6], fcport->port_name[7],
+                   be16_to_cpu(fcport->fp_speed)));
+               port_speed = PORT_SPEED_UNKNOWN;
+               break;
+       }
+       if (port_speed == PORT_SPEED_UNKNOWN)
+               return;
+
+       rval = qla2x00_set_idma_speed(ha, fcport->loop_id, port_speed, mb);
+       if (rval != QLA_SUCCESS) {
+               DEBUG2(printk("scsi(%ld): Unable to adjust iIDMA "
+                   "%02x%02x%02x%02x%02x%02x%02x%02x -- %04x %x %04x %04x.\n",
+                   ha->host_no, fcport->port_name[0], fcport->port_name[1],
+                   fcport->port_name[2], fcport->port_name[3],
+                   fcport->port_name[4], fcport->port_name[5],
+                   fcport->port_name[6], fcport->port_name[7], rval,
+                   port_speed, mb[0], mb[1]));
+       } else {
+               DEBUG2(qla_printk(KERN_INFO, ha,
+                   "iIDMA adjusted to %s GB/s on "
+                   "%02x%02x%02x%02x%02x%02x%02x%02x.\n",
+                   link_speeds[port_speed], fcport->port_name[0],
+                   fcport->port_name[1], fcport->port_name[2],
+                   fcport->port_name[3], fcport->port_name[4],
+                   fcport->port_name[5], fcport->port_name[6],
+                   fcport->port_name[7]));
+       }
+}
+
 /*
  * qla2x00_update_fcport
  *     Updates device on list.
@@ -2135,6 +2204,8 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
            PORT_RETRY_TIME);
        fcport->flags &= ~FCF_LOGIN_NEEDED;
 
+       qla2x00_iidma_fcport(ha, fcport);
+
        atomic_set(&fcport->state, FCS_ONLINE);
 
        if (ha->flags.init_done)
@@ -2209,7 +2280,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
                loop_id = NPH_F_PORT;
        else
                loop_id = SNS_FL_PORT;
-       rval = qla2x00_get_port_name(ha, loop_id, NULL, 0);
+       rval = qla2x00_get_port_name(ha, loop_id, ha->fabric_node_name, 1);
        if (rval != QLA_SUCCESS) {
                DEBUG2(printk("scsi(%ld): MBC_GET_PORT_NAME Failed, No FL "
                    "Port\n", ha->host_no));
@@ -2217,6 +2288,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
                ha->device_flags &= ~SWITCH_FOUND;
                return (QLA_SUCCESS);
        }
+       ha->device_flags |= SWITCH_FOUND;
 
        /* Mark devices that need re-synchronization. */
        rval2 = qla2x00_device_resync(ha);
@@ -2416,6 +2488,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
                } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) {
                        kfree(swl);
                        swl = NULL;
+               } else if (qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) {
+                       qla2x00_gpsc(ha, swl);
                }
        }
        swl_idx = 0;
@@ -2450,6 +2524,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
                                    swl[swl_idx].node_name, WWN_SIZE);
                                memcpy(new_fcport->port_name,
                                    swl[swl_idx].port_name, WWN_SIZE);
+                               memcpy(new_fcport->fabric_port_name,
+                                   swl[swl_idx].fabric_port_name, WWN_SIZE);
+                               new_fcport->fp_speed = swl[swl_idx].fp_speed;
 
                                if (swl[swl_idx].d_id.b.rsvd_1 != 0) {
                                        last_dev = 1;
@@ -2507,6 +2584,11 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
 
                        found++;
 
+                       /* Update port state. */
+                       memcpy(fcport->fabric_port_name,
+                           new_fcport->fabric_port_name, WWN_SIZE);
+                       fcport->fp_speed = new_fcport->fp_speed;
+
                        /*
                         * If address the same and state FCS_ONLINE, nothing
                         * changed.
index de0613135f702b42096786172f4063aa4fe66c10..5fa933cda992bcfc718dbb7b6199de16955121bf 100644 (file)
@@ -400,7 +400,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
        case MBA_LOOP_UP:               /* Loop Up Event */
                if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
                        link_speed = link_speeds[0];
-                       ha->link_data_rate = LDR_1GB;
+                       ha->link_data_rate = PORT_SPEED_1GB;
                } else {
                        link_speed = link_speeds[LS_UNKNOWN];
                        if (mb[1] < 5)
@@ -429,7 +429,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                }
 
                ha->flags.management_server_logged_in = 0;
-               ha->link_data_rate = LDR_UNKNOWN;
+               ha->link_data_rate = PORT_SPEED_UNKNOWN;
                if (ql2xfdmienable)
                        set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
                break;
index 879f281e2ea219a0cb580157a8ba8e99a6c66fc9..4cde76c85cb39a72610e2183fd7dc82fd6b7db95 100644 (file)
@@ -2540,3 +2540,89 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr,
 
        return rval;
 }
+
+int
+qla2x00_get_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id,
+    uint16_t *port_speed, uint16_t *mb)
+{
+       int rval;
+       mbx_cmd_t mc;
+       mbx_cmd_t *mcp = &mc;
+
+       if (!IS_QLA24XX(ha))
+               return QLA_FUNCTION_FAILED;
+
+       DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
+
+       mcp->mb[0] = MBC_PORT_PARAMS;
+       mcp->mb[1] = loop_id;
+       mcp->mb[2] = mcp->mb[3] = mcp->mb[4] = mcp->mb[5] = 0;
+       mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
+       mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
+       mcp->tov = 30;
+       mcp->flags = 0;
+       rval = qla2x00_mailbox_command(ha, mcp);
+
+       /* Return mailbox statuses. */
+       if (mb != NULL) {
+               mb[0] = mcp->mb[0];
+               mb[1] = mcp->mb[1];
+               mb[3] = mcp->mb[3];
+               mb[4] = mcp->mb[4];
+               mb[5] = mcp->mb[5];
+       }
+
+       if (rval != QLA_SUCCESS) {
+               DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
+                   ha->host_no, rval));
+       } else {
+               DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
+               if (port_speed)
+                       *port_speed = mcp->mb[3];
+       }
+
+       return rval;
+}
+
+int
+qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id,
+    uint16_t port_speed, uint16_t *mb)
+{
+       int rval;
+       mbx_cmd_t mc;
+       mbx_cmd_t *mcp = &mc;
+
+       if (!IS_QLA24XX(ha))
+               return QLA_FUNCTION_FAILED;
+
+       DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
+
+       mcp->mb[0] = MBC_PORT_PARAMS;
+       mcp->mb[1] = loop_id;
+       mcp->mb[2] = BIT_0;
+       mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
+       mcp->mb[4] = mcp->mb[5] = 0;
+       mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
+       mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
+       mcp->tov = 30;
+       mcp->flags = 0;
+       rval = qla2x00_mailbox_command(ha, mcp);
+
+       /* Return mailbox statuses. */
+       if (mb != NULL) {
+               mb[0] = mcp->mb[0];
+               mb[1] = mcp->mb[1];
+               mb[3] = mcp->mb[3];
+               mb[4] = mcp->mb[4];
+               mb[5] = mcp->mb[5];
+       }
+
+       if (rval != QLA_SUCCESS) {
+               DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
+                   ha->host_no, rval));
+       } else {
+               DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
+       }
+
+       return rval;
+}
index 65cbe2f5eea24c110438c4404e85e5cba09214bc..3ba8c239f171ec961c15aa6e64a17ae91aed9e9f 100644 (file)
@@ -589,6 +589,23 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha)
        return (return_status);
 }
 
+static void
+qla2x00_block_error_handler(struct scsi_cmnd *cmnd)
+{
+       struct Scsi_Host *shost = cmnd->device->host;
+       struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+       unsigned long flags;
+
+       spin_lock_irqsave(shost->host_lock, flags);
+       while (rport->port_state == FC_PORTSTATE_BLOCKED) {
+               spin_unlock_irqrestore(shost->host_lock, flags);
+               msleep(1000);
+               spin_lock_irqsave(shost->host_lock, flags);
+       }
+       spin_unlock_irqrestore(shost->host_lock, flags);
+       return;
+}
+
 /**************************************************************************
 * qla2xxx_eh_abort
 *
@@ -615,6 +632,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        unsigned long flags;
        int wait = 0;
 
+       qla2x00_block_error_handler(cmd);
+
        if (!CMD_SP(cmd))
                return SUCCESS;
 
@@ -748,6 +767,8 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
        unsigned int id, lun;
        unsigned long serial;
 
+       qla2x00_block_error_handler(cmd);
+
        ret = FAILED;
 
        id = cmd->device->id;
@@ -877,6 +898,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
        unsigned int id, lun;
        unsigned long serial;
 
+       qla2x00_block_error_handler(cmd);
+
        ret = FAILED;
 
        id = cmd->device->id;
@@ -936,6 +959,8 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
        unsigned int id, lun;
        unsigned long serial;
 
+       qla2x00_block_error_handler(cmd);
+
        ret = FAILED;
 
        id = cmd->device->id;
@@ -1385,7 +1410,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        ha->prev_topology = 0;
        ha->init_cb_size = sizeof(init_cb_t);
        ha->mgmt_svr_loop_id = MANAGEMENT_SERVER;
-       ha->link_data_rate = LDR_UNKNOWN;
+       ha->link_data_rate = PORT_SPEED_UNKNOWN;
        ha->optrom_size = OPTROM_SIZE_2300;
 
        /* Assign ISP specific operations. */
@@ -2564,14 +2589,20 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
 #define FW_ISP2322     3
 #define FW_ISP24XX     4
 
+#define FW_FILE_ISP21XX        "ql2100_fw.bin"
+#define FW_FILE_ISP22XX        "ql2200_fw.bin"
+#define FW_FILE_ISP2300        "ql2300_fw.bin"
+#define FW_FILE_ISP2322        "ql2322_fw.bin"
+#define FW_FILE_ISP24XX        "ql2400_fw.bin"
+
 static DECLARE_MUTEX(qla_fw_lock);
 
 static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
-       { .name = "ql2100_fw.bin", .segs = { 0x1000, 0 }, },
-       { .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, },
-       { .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, },
-       { .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
-       { .name = "ql2400_fw.bin", },
+       { .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, },
+       { .name = FW_FILE_ISP22XX, .segs = { 0x1000, 0 }, },
+       { .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, },
+       { .name = FW_FILE_ISP2322, .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
+       { .name = FW_FILE_ISP24XX, },
 };
 
 struct fw_blob *
@@ -2702,3 +2733,8 @@ MODULE_AUTHOR("QLogic Corporation");
 MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(QLA2XXX_VERSION);
+MODULE_FIRMWARE(FW_FILE_ISP21XX);
+MODULE_FIRMWARE(FW_FILE_ISP22XX);
+MODULE_FIRMWARE(FW_FILE_ISP2300);
+MODULE_FIRMWARE(FW_FILE_ISP2322);
+MODULE_FIRMWARE(FW_FILE_ISP24XX);
index 971259032ef71b9a0caaea13e1512e3e5c7f7d17..e57bf45a33936d29aea8fcc90c1450329ce8cec5 100644 (file)
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.01.07-k1"
+#define QLA2XXX_VERSION      "8.01.07-k2"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   1
diff --git a/drivers/scsi/qla4xxx/Kconfig b/drivers/scsi/qla4xxx/Kconfig
new file mode 100644 (file)
index 0000000..08a07f0
--- /dev/null
@@ -0,0 +1,7 @@
+config SCSI_QLA_ISCSI
+       tristate "QLogic ISP4XXX host adapter family support"
+       depends on PCI && SCSI
+       select SCSI_ISCSI_ATTRS
+       ---help---
+       This driver supports the QLogic 40xx (ISP4XXX) iSCSI host
+       adapter family.
diff --git a/drivers/scsi/qla4xxx/Makefile b/drivers/scsi/qla4xxx/Makefile
new file mode 100644 (file)
index 0000000..86ea37b
--- /dev/null
@@ -0,0 +1,5 @@
+qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \
+               ql4_nvram.o ql4_dbg.o
+
+obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx.o
+
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.c b/drivers/scsi/qla4xxx/ql4_dbg.c
new file mode 100644 (file)
index 0000000..752031f
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#include "ql4_def.h"
+#include <scsi/scsi_dbg.h>
+
+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)) {
+               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)) {
+               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);
+}
+
+void qla4xxx_dump_buffer(void *b, uint32_t size)
+{
+       uint32_t cnt;
+       uint8_t *c = b;
+
+       printk(" 0   1   2   3   4   5   6   7   8   9  Ah  Bh  Ch  Dh  Eh  "
+              "Fh\n");
+       printk("------------------------------------------------------------"
+              "--\n");
+       for (cnt = 0; cnt < size; cnt++, c++) {
+               printk(KERN_DEBUG "%02x", *c);
+               if (!(cnt % 16))
+                       printk(KERN_DEBUG "\n");
+
+               else
+                       printk(KERN_DEBUG "  ");
+       }
+       if (cnt % 16)
+               printk(KERN_DEBUG "\n");
+}
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.h b/drivers/scsi/qla4xxx/ql4_dbg.h
new file mode 100644 (file)
index 0000000..56ddc22
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+/*
+ * Driver debug definitions.
+ */
+/* #define QL_DEBUG  */                        /* DEBUG messages */
+/* #define QL_DEBUG_LEVEL_3  */                /* Output function tracing */
+/* #define QL_DEBUG_LEVEL_4  */
+/* #define QL_DEBUG_LEVEL_5  */
+/* #define QL_DEBUG_LEVEL_9  */
+
+#define QL_DEBUG_LEVEL_2       /* ALways enable error messagess */
+#if defined(QL_DEBUG)
+#define DEBUG(x)   do {x;} while (0);
+#else
+#define DEBUG(x)       do {} while (0);
+#endif
+
+#if defined(QL_DEBUG_LEVEL_2)
+#define DEBUG2(x)      do {if(extended_error_logging == 2) x;} while (0);
+#define DEBUG2_3(x)   do {x;} while (0);
+#else                          /*  */
+#define DEBUG2(x)      do {} while (0);
+#endif                         /*  */
+
+#if defined(QL_DEBUG_LEVEL_3)
+#define DEBUG3(x)      do {if(extended_error_logging == 3) x;} while (0);
+#else                          /*  */
+#define DEBUG3(x)      do {} while (0);
+#if !defined(QL_DEBUG_LEVEL_2)
+#define DEBUG2_3(x)    do {} while (0);
+#endif                         /*  */
+#endif                         /*  */
+#if defined(QL_DEBUG_LEVEL_4)
+#define DEBUG4(x)      do {x;} while (0);
+#else                          /*  */
+#define DEBUG4(x)      do {} while (0);
+#endif                         /*  */
+
+#if defined(QL_DEBUG_LEVEL_5)
+#define DEBUG5(x)      do {x;} while (0);
+#else                          /*  */
+#define DEBUG5(x)      do {} while (0);
+#endif                         /*  */
+
+#if defined(QL_DEBUG_LEVEL_9)
+#define DEBUG9(x)      do {x;} while (0);
+#else                          /*  */
+#define DEBUG9(x)      do {} while (0);
+#endif                         /*  */
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
new file mode 100644 (file)
index 0000000..a7f6c7b
--- /dev/null
@@ -0,0 +1,586 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#ifndef __QL4_DEF_H
+#define __QL4_DEF_H
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/dmapool.h>
+#include <linux/mempool.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+
+#include <net/tcp.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_iscsi.h>
+
+
+#ifndef PCI_DEVICE_ID_QLOGIC_ISP4010
+#define PCI_DEVICE_ID_QLOGIC_ISP4010   0x4010
+#endif
+
+#ifndef PCI_DEVICE_ID_QLOGIC_ISP4022
+#define PCI_DEVICE_ID_QLOGIC_ISP4022   0x4022
+#endif                         /*  */
+
+#define QLA_SUCCESS                    0
+#define QLA_ERROR                      1
+
+/*
+ * Data bit definitions
+ */
+#define BIT_0  0x1
+#define BIT_1  0x2
+#define BIT_2  0x4
+#define BIT_3  0x8
+#define BIT_4  0x10
+#define BIT_5  0x20
+#define BIT_6  0x40
+#define BIT_7  0x80
+#define BIT_8  0x100
+#define BIT_9  0x200
+#define BIT_10 0x400
+#define BIT_11 0x800
+#define BIT_12 0x1000
+#define BIT_13 0x2000
+#define BIT_14 0x4000
+#define BIT_15 0x8000
+#define BIT_16 0x10000
+#define BIT_17 0x20000
+#define BIT_18 0x40000
+#define BIT_19 0x80000
+#define BIT_20 0x100000
+#define BIT_21 0x200000
+#define BIT_22 0x400000
+#define BIT_23 0x800000
+#define BIT_24 0x1000000
+#define BIT_25 0x2000000
+#define BIT_26 0x4000000
+#define BIT_27 0x8000000
+#define BIT_28 0x10000000
+#define BIT_29 0x20000000
+#define BIT_30 0x40000000
+#define BIT_31 0x80000000
+
+/*
+ * Host adapter default definitions
+ ***********************************/
+#define MAX_HBAS               16
+#define MAX_BUSES              1
+#define MAX_TARGETS            (MAX_PRST_DEV_DB_ENTRIES +  MAX_DEV_DB_ENTRIES)
+#define MAX_LUNS               0xffff
+#define MAX_AEN_ENTRIES                256 /* should be > EXT_DEF_MAX_AEN_QUEUE */
+#define MAX_DDB_ENTRIES                (MAX_PRST_DEV_DB_ENTRIES + MAX_DEV_DB_ENTRIES)
+#define MAX_PDU_ENTRIES                32
+#define INVALID_ENTRY          0xFFFF
+#define MAX_CMDS_TO_RISC       1024
+#define MAX_SRBS               MAX_CMDS_TO_RISC
+#define MBOX_AEN_REG_COUNT     5
+#define MAX_INIT_RETRIES       5
+#define IOCB_HIWAT_CUSHION     16
+
+/*
+ * Buffer sizes
+ */
+#define REQUEST_QUEUE_DEPTH            MAX_CMDS_TO_RISC
+#define RESPONSE_QUEUE_DEPTH           64
+#define QUEUE_SIZE                     64
+#define DMA_BUFFER_SIZE                        512
+
+/*
+ * Misc
+ */
+#define MAC_ADDR_LEN                   6       /* in bytes */
+#define IP_ADDR_LEN                    4       /* in bytes */
+#define DRIVER_NAME                    "qla4xxx"
+
+#define MAX_LINKED_CMDS_PER_LUN                3
+#define MAX_REQS_SERVICED_PER_INTR     16
+
+#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 LSDW(x) ((u32)((u64)(x)))
+#define MSDW(x) ((u32)((((u64)(x)) >> 16) >> 16))
+
+/*
+ * Retry & Timeout Values
+ */
+#define MBOX_TOV                       60
+#define SOFT_RESET_TOV                 30
+#define RESET_INTR_TOV                 3
+#define SEMAPHORE_TOV                  10
+#define ADAPTER_INIT_TOV               120
+#define ADAPTER_RESET_TOV              180
+#define EXTEND_CMD_TOV                 60
+#define WAIT_CMD_TOV                   30
+#define EH_WAIT_CMD_TOV                        120
+#define FIRMWARE_UP_TOV                        60
+#define RESET_FIRMWARE_TOV             30
+#define LOGOUT_TOV                     10
+#define IOCB_TOV_MARGIN                        10
+#define RELOGIN_TOV                    18
+#define ISNS_DEREG_TOV                 5
+
+#define MAX_RESET_HA_RETRIES           2
+
+/*
+ * SCSI Request Block structure         (srb)  that is placed
+ * on cmd->SCp location of every I/O    [We have 22 bytes available]
+ */
+struct srb {
+       struct list_head list;  /* (8)   */
+       struct scsi_qla_host *ha;       /* HA the SP is queued on */
+       struct ddb_entry        *ddb;
+       uint16_t flags;         /* (1) Status flags. */
+
+#define SRB_DMA_VALID          BIT_3   /* DMA Buffer mapped. */
+#define SRB_GOT_SENSE          BIT_4   /* sense data recieved. */
+       uint8_t state;          /* (1) Status flags. */
+
+#define SRB_NO_QUEUE_STATE      0      /* Request is in between states */
+#define SRB_FREE_STATE          1
+#define SRB_ACTIVE_STATE        3
+#define SRB_ACTIVE_TIMEOUT_STATE 4
+#define SRB_SUSPENDED_STATE     7      /* Request in suspended state */
+
+       struct scsi_cmnd *cmd;  /* (4) SCSI command block */
+       dma_addr_t dma_handle;  /* (4) for unmap of single transfers */
+       atomic_t ref_count;     /* reference count for this srb */
+       uint32_t fw_ddb_index;
+       uint8_t err_id;         /* error id */
+#define SRB_ERR_PORT      1    /* Request failed because "port down" */
+#define SRB_ERR_LOOP      2    /* Request failed because "loop down" */
+#define SRB_ERR_DEVICE    3    /* Request failed because "device error" */
+#define SRB_ERR_OTHER     4
+
+       uint16_t reserved;
+       uint16_t iocb_tov;
+       uint16_t iocb_cnt;      /* Number of used iocbs */
+       uint16_t cc_stat;
+       u_long r_start;         /* Time we recieve a cmd from OS */
+       u_long u_start;         /* Time when we handed the cmd to F/W */
+};
+
+       /*
+        * Device Database (DDB) structure
+        */
+struct ddb_entry {
+       struct list_head list;  /* ddb list */
+       struct scsi_qla_host *ha;
+       struct iscsi_cls_session *sess;
+       struct iscsi_cls_conn *conn;
+
+       atomic_t state;         /* DDB State */
+
+       unsigned long flags;    /* DDB Flags */
+
+       unsigned long dev_scan_wait_to_start_relogin;
+       unsigned long dev_scan_wait_to_complete_relogin;
+
+       uint16_t os_target_id;  /* Target ID */
+       uint16_t fw_ddb_index;  /* DDB firmware index */
+       uint8_t reserved[2];
+       uint32_t fw_ddb_device_state; /* F/W Device State  -- see ql4_fw.h */
+
+       uint32_t CmdSn;
+       uint16_t target_session_id;
+       uint16_t connection_id;
+       uint16_t exe_throttle;  /* Max mumber of cmds outstanding
+                                * simultaneously */
+       uint16_t task_mgmt_timeout; /* Min time for task mgmt cmds to
+                                    * complete */
+       uint16_t default_relogin_timeout; /*  Max time to wait for
+                                          *  relogin to complete */
+       uint16_t tcp_source_port_num;
+       uint32_t default_time2wait; /* Default Min time between
+                                    * relogins (+aens) */
+
+       atomic_t port_down_timer; /* Device connection timer */
+       atomic_t retry_relogin_timer; /* Min Time between relogins
+                                      * (4000 only) */
+       atomic_t relogin_timer; /* Max Time to wait for relogin to complete */
+       atomic_t relogin_retry_count; /* Num of times relogin has been
+                                      * retried */
+
+       uint16_t port;
+       uint32_t tpgt;
+       uint8_t ip_addr[ISCSI_IPADDR_SIZE];
+       uint8_t iscsi_name[ISCSI_NAME_SIZE];    /* 72 x48 */
+       uint8_t iscsi_alias[0x20];
+};
+
+/*
+ * DDB states.
+ */
+#define DDB_STATE_DEAD         0       /* We can no longer talk to
+                                        * this device */
+#define DDB_STATE_ONLINE       1       /* Device ready to accept
+                                        * commands */
+#define DDB_STATE_MISSING      2       /* Device logged off, trying
+                                        * to re-login */
+
+/*
+ * DDB flags.
+ */
+#define DF_RELOGIN             0       /* Relogin to device */
+#define DF_NO_RELOGIN          1       /* Do not relogin if IOCTL
+                                        * logged it out */
+#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"
+
+/*
+ * Linux Host Adapter structure
+ */
+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_TOPCAT_CHIP_PRESENT       9 /* 0x00000200 */
+#define AF_IRQ_ATTACHED                     10 /* 0x00000400 */
+#define AF_ISNS_CMD_IN_PROCESS      12 /* 0x00001000 */
+#define AF_ISNS_CMD_DONE            13 /* 0x00002000 */
+
+       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 */
+
+       uint16_t        iocb_cnt;
+       uint16_t        iocb_hiwat;
+
+       /* SRB cache. */
+#define SRB_MIN_REQ    128
+       mempool_t *srb_mempool;
+
+       /* pci information */
+       struct pci_dev *pdev;
+
+       struct isp_reg __iomem *reg; /* Base I/O address */
+       unsigned long pio_address;
+       unsigned long pio_length;
+#define MIN_IOBASE_LEN         0x100
+
+       uint16_t req_q_count;
+       uint8_t marker_needed;
+       uint8_t rsvd1;
+
+       unsigned long host_no;
+
+       /* NVRAM registers */
+       struct eeprom_data *nvram;
+       spinlock_t hardware_lock ____cacheline_aligned;
+       spinlock_t list_lock;
+       uint32_t   eeprom_cmd_data;
+
+       /* Counters for general statistics */
+       uint64_t adapter_error_count;
+       uint64_t device_error_count;
+       uint64_t total_io_count;
+       uint64_t total_mbytes_xferred;
+       uint64_t link_failure_count;
+       uint64_t invalid_crc_count;
+       uint32_t spurious_int_count;
+       uint32_t aborted_io_count;
+       uint32_t io_timeout_count;
+       uint32_t mailbox_timeout_count;
+       uint32_t seconds_since_last_intr;
+       uint32_t seconds_since_last_heartbeat;
+       uint32_t mac_index;
+
+       /* Info Needed for Management App */
+       /* --- From GetFwVersion --- */
+       uint32_t firmware_version[2];
+       uint32_t patch_number;
+       uint32_t build_number;
+
+       /* --- From Init_FW --- */
+       /* init_cb_t *init_cb; */
+       uint16_t firmware_options;
+       uint16_t tcp_options;
+       uint8_t ip_address[IP_ADDR_LEN];
+       uint8_t subnet_mask[IP_ADDR_LEN];
+       uint8_t gateway[IP_ADDR_LEN];
+       uint8_t alias[32];
+       uint8_t name_string[256];
+       uint8_t heartbeat_interval;
+       uint8_t rsvd;
+
+       /* --- From FlashSysInfo --- */
+       uint8_t my_mac[MAC_ADDR_LEN];
+       uint8_t serial_number[16];
+
+       /* --- From GetFwState --- */
+       uint32_t firmware_state;
+       uint32_t board_id;
+       uint32_t addl_fw_state;
+
+       /* Linux kernel thread */
+       struct workqueue_struct *dpc_thread;
+       struct work_struct dpc_work;
+
+       /* Linux timer thread */
+       struct timer_list timer;
+       uint32_t timer_active;
+
+       /* Recovery Timers */
+       uint32_t port_down_retry_count;
+       uint32_t discovery_wait;
+       atomic_t check_relogin_timeouts;
+       uint32_t retry_reset_ha_cnt;
+       uint32_t isp_reset_timer;       /* reset test timer */
+       uint32_t nic_reset_timer;       /* simulated nic reset test timer */
+       int eh_start;
+       struct list_head free_srb_q;
+       uint16_t free_srb_q_count;
+       uint16_t num_srbs_allocated;
+
+       /* DMA Memory Block */
+       void *queues;
+       dma_addr_t queues_dma;
+       unsigned long queues_len;
+
+#define MEM_ALIGN_VALUE \
+           ((max(REQUEST_QUEUE_DEPTH, RESPONSE_QUEUE_DEPTH)) * \
+            sizeof(struct queue_entry))
+       /* request and response queue variables */
+       dma_addr_t request_dma;
+       struct queue_entry *request_ring;
+       struct queue_entry *request_ptr;
+       dma_addr_t response_dma;
+       struct queue_entry *response_ring;
+       struct queue_entry *response_ptr;
+       dma_addr_t shadow_regs_dma;
+       struct shadow_regs *shadow_regs;
+       uint16_t request_in;    /* Current indexes. */
+       uint16_t request_out;
+       uint16_t response_in;
+       uint16_t response_out;
+
+       /* aen queue variables */
+       uint16_t aen_q_count;   /* Number of available aen_q entries */
+       uint16_t aen_in;        /* Current indexes */
+       uint16_t aen_out;
+       struct aen aen_q[MAX_AEN_ENTRIES];
+
+       /* This mutex protects several threads to do mailbox commands
+        * concurrently.
+        */
+       struct mutex  mbox_sem;
+       wait_queue_head_t mailbox_wait_queue;
+
+       /* temporary mailbox status registers */
+       volatile uint8_t mbox_status_count;
+       volatile uint32_t mbox_status[MBOX_REG_COUNT];
+
+       /* local device database list (contains internal ddb entries) */
+       struct list_head ddb_list;
+
+       /* Map ddb_list entry by FW ddb index */
+       struct ddb_entry *fw_ddb_index_map[MAX_DDB_ENTRIES];
+
+};
+
+static inline int is_qla4010(struct scsi_qla_host *ha)
+{
+       return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4010;
+}
+
+static inline int is_qla4022(struct scsi_qla_host *ha)
+{
+       return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4022;
+}
+
+static inline int adapter_up(struct scsi_qla_host *ha)
+{
+       return (test_bit(AF_ONLINE, &ha->flags) != 0) &&
+               (test_bit(AF_LINK_UP, &ha->flags) != 0);
+}
+
+static inline struct scsi_qla_host* to_qla_host(struct Scsi_Host *shost)
+{
+       return (struct scsi_qla_host *)shost->hostdata;
+}
+
+static inline void __iomem* isp_semaphore(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u1.isp4022.semaphore :
+               &ha->reg->u1.isp4010.nvram);
+}
+
+static inline void __iomem* isp_nvram(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u1.isp4022.nvram :
+               &ha->reg->u1.isp4010.nvram);
+}
+
+static inline void __iomem* isp_ext_hw_conf(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u2.isp4022.p0.ext_hw_conf :
+               &ha->reg->u2.isp4010.ext_hw_conf);
+}
+
+static inline void __iomem* isp_port_status(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u2.isp4022.p0.port_status :
+               &ha->reg->u2.isp4010.port_status);
+}
+
+static inline void __iomem* isp_port_ctrl(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u2.isp4022.p0.port_ctrl :
+               &ha->reg->u2.isp4010.port_ctrl);
+}
+
+static inline void __iomem* isp_port_error_status(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u2.isp4022.p0.port_err_status :
+               &ha->reg->u2.isp4010.port_err_status);
+}
+
+static inline void __iomem * isp_gp_out(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u2.isp4022.p0.gp_out :
+               &ha->reg->u2.isp4010.gp_out);
+}
+
+static inline int eeprom_ext_hw_conf_offset(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               offsetof(struct eeprom_data, isp4022.ext_hw_conf) / 2 :
+               offsetof(struct eeprom_data, isp4010.ext_hw_conf) / 2);
+}
+
+int ql4xxx_sem_spinlock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits);
+void ql4xxx_sem_unlock(struct scsi_qla_host * ha, u32 sem_mask);
+int ql4xxx_sem_lock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits);
+
+static inline int ql4xxx_lock_flash(struct scsi_qla_host *a)
+{
+       if (is_qla4022(a))
+               return ql4xxx_sem_spinlock(a, QL4022_FLASH_SEM_MASK,
+                                          (QL4022_RESOURCE_BITS_BASE_CODE |
+                                           (a->mac_index)) << 13);
+       else
+               return ql4xxx_sem_spinlock(a, QL4010_FLASH_SEM_MASK,
+                                          QL4010_FLASH_SEM_BITS);
+}
+
+static inline void ql4xxx_unlock_flash(struct scsi_qla_host *a)
+{
+       if (is_qla4022(a))
+               ql4xxx_sem_unlock(a, QL4022_FLASH_SEM_MASK);
+       else
+               ql4xxx_sem_unlock(a, QL4010_FLASH_SEM_MASK);
+}
+
+static inline int ql4xxx_lock_nvram(struct scsi_qla_host *a)
+{
+       if (is_qla4022(a))
+               return ql4xxx_sem_spinlock(a, QL4022_NVRAM_SEM_MASK,
+                                          (QL4022_RESOURCE_BITS_BASE_CODE |
+                                           (a->mac_index)) << 10);
+       else
+               return ql4xxx_sem_spinlock(a, QL4010_NVRAM_SEM_MASK,
+                                          QL4010_NVRAM_SEM_BITS);
+}
+
+static inline void ql4xxx_unlock_nvram(struct scsi_qla_host *a)
+{
+       if (is_qla4022(a))
+               ql4xxx_sem_unlock(a, QL4022_NVRAM_SEM_MASK);
+       else
+               ql4xxx_sem_unlock(a, QL4010_NVRAM_SEM_MASK);
+}
+
+static inline int ql4xxx_lock_drvr(struct scsi_qla_host *a)
+{
+       if (is_qla4022(a))
+               return ql4xxx_sem_lock(a, QL4022_DRVR_SEM_MASK,
+                                      (QL4022_RESOURCE_BITS_BASE_CODE |
+                                       (a->mac_index)) << 1);
+       else
+               return ql4xxx_sem_lock(a, QL4010_DRVR_SEM_MASK,
+                                      QL4010_DRVR_SEM_BITS);
+}
+
+static inline void ql4xxx_unlock_drvr(struct scsi_qla_host *a)
+{
+       if (is_qla4022(a))
+               ql4xxx_sem_unlock(a, QL4022_DRVR_SEM_MASK);
+       else
+               ql4xxx_sem_unlock(a, QL4010_DRVR_SEM_MASK);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */
+#define PRESERVE_DDB_LIST      0
+#define REBUILD_DDB_LIST       1
+
+/* Defines for process_aen() */
+#define PROCESS_ALL_AENS        0
+#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 */
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
new file mode 100644 (file)
index 0000000..427489d
--- /dev/null
@@ -0,0 +1,843 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#ifndef _QLA4X_FW_H
+#define _QLA4X_FW_H
+
+
+#define MAX_PRST_DEV_DB_ENTRIES                64
+#define MIN_DISC_DEV_DB_ENTRY          MAX_PRST_DEV_DB_ENTRIES
+#define MAX_DEV_DB_ENTRIES 512
+
+/*************************************************************************
+ *
+ *             ISP 4010 I/O Register Set Structure and Definitions
+ *
+ *************************************************************************/
+
+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 */
+};
+
+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 */
+};
+
+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
+       __le32 mailbox[MBOX_REG_COUNT];
+
+       __le32 flash_address;   /* 0x20 */
+       __le32 flash_data;
+       __le32 ctrl_status;
+
+       union {
+               struct {
+                       __le32 nvram;
+                       __le32 reserved1[2]; /* 0x30 */
+               } __attribute__ ((packed)) isp4010;
+               struct {
+                       __le32 intr_mask;
+                       __le32 nvram; /* 0x30 */
+                       __le32 semaphore;
+               } __attribute__ ((packed)) isp4022;
+       } u1;
+
+       __le32 req_q_in;    /* SCSI Request Queue Producer Index */
+       __le32 rsp_q_out;   /* SCSI Completion Queue Consumer Index */
+
+       __le32 reserved2[4];    /* 0x40 */
+
+       union {
+               struct {
+                       __le32 ext_hw_conf; /* 0x50 */
+                       __le32 flow_ctrl;
+                       __le32 port_ctrl;
+                       __le32 port_status;
+
+                       __le32 reserved3[8]; /* 0x60 */
+
+                       __le32 req_q_out; /* 0x80 */
+
+                       __le32 reserved4[23]; /* 0x84 */
+
+                       __le32 gp_out; /* 0xe0 */
+                       __le32 gp_in;
+
+                       __le32 reserved5[5];
+
+                       __le32 port_err_status; /* 0xfc */
+               } __attribute__ ((packed)) isp4010;
+               struct {
+                       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 */
+
+
+/* Semaphore Defines for 4010 */
+#define QL4010_DRVR_SEM_BITS   0x00000030
+#define QL4010_GPIO_SEM_BITS   0x000000c0
+#define QL4010_SDRAM_SEM_BITS  0x00000300
+#define QL4010_PHY_SEM_BITS    0x00000c00
+#define QL4010_NVRAM_SEM_BITS  0x00003000
+#define QL4010_FLASH_SEM_BITS  0x0000c000
+
+#define QL4010_DRVR_SEM_MASK   0x00300000
+#define QL4010_GPIO_SEM_MASK   0x00c00000
+#define QL4010_SDRAM_SEM_MASK  0x03000000
+#define QL4010_PHY_SEM_MASK    0x0c000000
+#define QL4010_NVRAM_SEM_MASK  0x30000000
+#define QL4010_FLASH_SEM_MASK  0xc0000000
+
+/* Semaphore Defines for 4022 */
+#define QL4022_RESOURCE_MASK_BASE_CODE 0x7
+#define QL4022_RESOURCE_BITS_BASE_CODE 0x4
+
+
+#define QL4022_DRVR_SEM_MASK   (QL4022_RESOURCE_MASK_BASE_CODE << (1+16))
+#define QL4022_DDR_RAM_SEM_MASK (QL4022_RESOURCE_MASK_BASE_CODE << (4+16))
+#define QL4022_PHY_GIO_SEM_MASK (QL4022_RESOURCE_MASK_BASE_CODE << (7+16))
+#define QL4022_NVRAM_SEM_MASK  (QL4022_RESOURCE_MASK_BASE_CODE << (10+16))
+#define QL4022_FLASH_SEM_MASK  (QL4022_RESOURCE_MASK_BASE_CODE << (13+16))
+
+
+
+/* Page # defines for 4022 */
+#define PORT_CTRL_STAT_PAGE                    0       /* 4022 */
+#define HOST_MEM_CFG_PAGE                      1       /* 4022 */
+#define LOCAL_RAM_CFG_PAGE                     2       /* 4022 */
+#define PROT_STAT_PAGE                         3       /* 4022 */
+
+/* Register Mask - sets corresponding mask bits in the upper word */
+static inline uint32_t set_rmask(uint32_t val)
+{
+       return (val & 0xffff) | (val << 16);
+}
+
+
+static inline uint32_t clr_rmask(uint32_t val)
+{
+       return 0 | (val << 16);
+}
+
+/*  ctrl_status definitions */
+#define CSR_SCSI_PAGE_SELECT                   0x00000003
+#define CSR_SCSI_INTR_ENABLE                   0x00000004      /* 4010 */
+#define CSR_SCSI_RESET_INTR                    0x00000008
+#define CSR_SCSI_COMPLETION_INTR               0x00000010
+#define CSR_SCSI_PROCESSOR_INTR                        0x00000020
+#define CSR_INTR_RISC                          0x00000040
+#define CSR_BOOT_ENABLE                                0x00000080
+#define CSR_NET_PAGE_SELECT                    0x00000300      /* 4010 */
+#define CSR_FUNC_NUM                           0x00000700      /* 4022 */
+#define CSR_NET_RESET_INTR                     0x00000800      /* 4010 */
+#define CSR_FORCE_SOFT_RESET                   0x00002000      /* 4022 */
+#define CSR_FATAL_ERROR                                0x00004000
+#define CSR_SOFT_RESET                         0x00008000
+#define ISP_CONTROL_FN_MASK                    CSR_FUNC_NUM
+#define ISP_CONTROL_FN0_SCSI                   0x0500
+#define ISP_CONTROL_FN1_SCSI                   0x0700
+
+#define INTR_PENDING                           (CSR_SCSI_COMPLETION_INTR |\
+                                                CSR_SCSI_PROCESSOR_INTR |\
+                                                CSR_SCSI_RESET_INTR)
+
+/* ISP InterruptMask definitions */
+#define IMR_SCSI_INTR_ENABLE                   0x00000004      /* 4022 */
+
+/* ISP 4022 nvram definitions */
+#define NVR_WRITE_ENABLE                       0x00000010      /* 4022 */
+
+/*  ISP port_status definitions */
+
+/*  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 {
+       /* SCSI Request Queue Consumer Index */
+       __le32 req_q_out;       /*  0 x0   R */
+
+       /* SCSI Completion Queue Producer Index */
+       __le32 rsp_q_in;        /*  4 x4   R */
+};               /*  8 x8 */
+
+
+/*  External hardware configuration register */
+union external_hw_config_reg {
+       struct {
+               /* FIXME: Do we even need this?  All values are
+                * referred to by 16 bit quantities.  Platform and
+                * endianess issues. */
+               __le32 bReserved0:1;
+               __le32 bSDRAMProtectionMethod:2;
+               __le32 bSDRAMBanks:1;
+               __le32 bSDRAMChipWidth:1;
+               __le32 bSDRAMChipSize:2;
+               __le32 bParityDisable:1;
+               __le32 bExternalMemoryType:1;
+               __le32 bFlashBIOSWriteEnable:1;
+               __le32 bFlashUpperBankSelect:1;
+               __le32 bWriteBurst:2;
+               __le32 bReserved1:3;
+               __le32 bMask:16;
+       };
+       uint32_t Asuint32_t;
+};
+
+/*************************************************************************
+ *
+ *             Mailbox Commands Structures and Definitions
+ *
+ *************************************************************************/
+
+/*  Mailbox command definitions */
+#define MBOX_CMD_ABOUT_FW                      0x0009
+#define MBOX_CMD_LUN_RESET                     0x0016
+#define MBOX_CMD_GET_FW_STATUS                 0x001F
+#define MBOX_CMD_SET_ISNS_SERVICE              0x0021
+#define ISNS_DISABLE                           0
+#define ISNS_ENABLE                            1
+#define MBOX_CMD_READ_FLASH                    0x0026
+#define MBOX_CMD_CLEAR_DATABASE_ENTRY          0x0031
+#define MBOX_CMD_CONN_CLOSE_SESS_LOGOUT                0x0056
+#define LOGOUT_OPTION_CLOSE_SESSION            0x01
+#define LOGOUT_OPTION_RELOGIN                  0x02
+#define MBOX_CMD_EXECUTE_IOCB_A64              0x005A
+#define MBOX_CMD_INITIALIZE_FIRMWARE           0x0060
+#define MBOX_CMD_GET_INIT_FW_CTRL_BLOCK                0x0061
+#define MBOX_CMD_REQUEST_DATABASE_ENTRY                0x0062
+#define MBOX_CMD_SET_DATABASE_ENTRY            0x0063
+#define MBOX_CMD_GET_DATABASE_ENTRY            0x0064
+#define DDB_DS_UNASSIGNED                      0x00
+#define DDB_DS_NO_CONNECTION_ACTIVE            0x01
+#define DDB_DS_SESSION_ACTIVE                  0x04
+#define DDB_DS_SESSION_FAILED                  0x06
+#define DDB_DS_LOGIN_IN_PROCESS                        0x07
+#define MBOX_CMD_GET_FW_STATE                  0x0069
+
+/* Mailbox 1 */
+#define FW_STATE_READY                         0x0000
+#define FW_STATE_CONFIG_WAIT                   0x0001
+#define FW_STATE_ERROR                         0x0004
+#define FW_STATE_DHCP_IN_PROGRESS              0x0008
+
+/* Mailbox 3 */
+#define FW_ADDSTATE_OPTICAL_MEDIA              0x0001
+#define FW_ADDSTATE_DHCP_ENABLED               0x0002
+#define FW_ADDSTATE_LINK_UP                    0x0010
+#define FW_ADDSTATE_ISNS_SVC_ENABLED           0x0020
+#define MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS   0x006B
+#define MBOX_CMD_CONN_OPEN_SESS_LOGIN          0x0074
+#define MBOX_CMD_GET_CRASH_RECORD              0x0076  /* 4010 only */
+#define MBOX_CMD_GET_CONN_EVENT_LOG            0x0077
+
+/*  Mailbox status definitions */
+#define MBOX_COMPLETION_STATUS                 4
+#define MBOX_STS_BUSY                          0x0007
+#define MBOX_STS_INTERMEDIATE_COMPLETION       0x1000
+#define MBOX_STS_COMMAND_COMPLETE              0x4000
+#define MBOX_STS_COMMAND_ERROR                 0x4005
+
+#define MBOX_ASYNC_EVENT_STATUS                        8
+#define MBOX_ASTS_SYSTEM_ERROR                 0x8002
+#define MBOX_ASTS_REQUEST_TRANSFER_ERROR       0x8003
+#define MBOX_ASTS_RESPONSE_TRANSFER_ERROR      0x8004
+#define MBOX_ASTS_PROTOCOL_STATISTIC_ALARM     0x8005
+#define MBOX_ASTS_SCSI_COMMAND_PDU_REJECTED    0x8006
+#define MBOX_ASTS_LINK_UP                      0x8010
+#define MBOX_ASTS_LINK_DOWN                    0x8011
+#define MBOX_ASTS_DATABASE_CHANGED             0x8014
+#define MBOX_ASTS_UNSOLICITED_PDU_RECEIVED     0x8015
+#define MBOX_ASTS_SELF_TEST_FAILED             0x8016
+#define MBOX_ASTS_LOGIN_FAILED                 0x8017
+#define MBOX_ASTS_DNS                          0x8018
+#define MBOX_ASTS_HEARTBEAT                    0x8019
+#define MBOX_ASTS_NVRAM_INVALID                        0x801A
+#define MBOX_ASTS_MAC_ADDRESS_CHANGED          0x801B
+#define MBOX_ASTS_IP_ADDRESS_CHANGED           0x801C
+#define MBOX_ASTS_DHCP_LEASE_EXPIRED           0x801D
+#define MBOX_ASTS_DHCP_LEASE_ACQUIRED          0x801F
+#define MBOX_ASTS_ISNS_UNSOLICITED_PDU_RECEIVED 0x8021
+#define ISNS_EVENT_DATA_RECEIVED               0x0000
+#define ISNS_EVENT_CONNECTION_OPENED           0x0001
+#define ISNS_EVENT_CONNECTION_FAILED           0x0002
+#define MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR     0x8022
+#define MBOX_ASTS_SUBNET_STATE_CHANGE          0x8027
+
+/*************************************************************************/
+
+/* Host Adapter Initialization Control Block (from host) */
+struct init_fw_ctrl_blk {
+       uint8_t Version;        /* 00 */
+       uint8_t Control;        /* 01 */
+
+       uint16_t FwOptions;     /* 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 */
+};
+
+/*************************************************************************/
+
+struct dev_db_entry {
+       uint8_t options;        /* 00 */
+#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
+                                * 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
+                                        * 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 */
+};
+
+/*************************************************************************/
+
+/* Flash definitions */
+
+#define FLASH_OFFSET_SYS_INFO  0x02000000
+#define FLASH_DEFAULTBLOCKSIZE 0x20000
+#define FLASH_EOF_OFFSET       (FLASH_DEFAULTBLOCKSIZE-8) /* 4 bytes
+                                                           * for EOF
+                                                           * signature */
+
+struct sys_info_phys_addr {
+       uint8_t address[6];     /* 00-05 */
+       uint8_t filler[2];      /* 06-07 */
+};
+
+struct flash_sys_info {
+       uint32_t cookie;        /* 00-03 */
+       uint32_t physAddrCount; /* 04-07 */
+       struct sys_info_phys_addr physAddr[4]; /* 08-27 */
+       uint8_t vendorId[128];  /* 28-A7 */
+       uint8_t productId[128]; /* A8-127 */
+       uint32_t serialNumber;  /* 128-12B */
+
+       /*  PCI Configuration values */
+       uint32_t pciDeviceVendor;       /* 12C-12F */
+       uint32_t pciDeviceId;   /* 130-133 */
+       uint32_t pciSubsysVendor;       /* 134-137 */
+       uint32_t pciSubsysId;   /* 138-13B */
+
+       /*  This validates version 1. */
+       uint32_t crumbs;        /* 13C-13F */
+
+       uint32_t enterpriseNumber;      /* 140-143 */
+
+       uint32_t mtu;           /* 144-147 */
+       uint32_t reserved0;     /* 148-14b */
+       uint32_t crumbs2;       /* 14c-14f */
+       uint8_t acSerialNumber[16];     /* 150-15f */
+       uint32_t crumbs3;       /* 160-16f */
+
+       /* Leave this last in the struct so it is declared invalid if
+        * any new items are added.
+        */
+       uint32_t reserved1[39]; /* 170-1ff */
+};     /* 200 */
+
+struct crash_record {
+       uint16_t fw_major_version;      /* 00 - 01 */
+       uint16_t fw_minor_version;      /* 02 - 03 */
+       uint16_t fw_patch_version;      /* 04 - 05 */
+       uint16_t fw_build_version;      /* 06 - 07 */
+
+       uint8_t build_date[16]; /* 08 - 17 */
+       uint8_t build_time[16]; /* 18 - 27 */
+       uint8_t build_user[16]; /* 28 - 37 */
+       uint8_t card_serial_num[16];    /* 38 - 47 */
+
+       uint32_t time_of_crash_in_secs; /* 48 - 4B */
+       uint32_t time_of_crash_in_ms;   /* 4C - 4F */
+
+       uint16_t out_RISC_sd_num_frames;        /* 50 - 51 */
+       uint16_t OAP_sd_num_words;      /* 52 - 53 */
+       uint16_t IAP_sd_num_frames;     /* 54 - 55 */
+       uint16_t in_RISC_sd_num_words;  /* 56 - 57 */
+
+       uint8_t reserved1[28];  /* 58 - 7F */
+
+       uint8_t out_RISC_reg_dump[256]; /* 80 -17F */
+       uint8_t in_RISC_reg_dump[256];  /*180 -27F */
+       uint8_t in_out_RISC_stack_dump[0];      /*280 - ??? */
+};
+
+struct conn_event_log_entry {
+#define MAX_CONN_EVENT_LOG_ENTRIES     100
+       uint32_t timestamp_sec; /* 00 - 03 seconds since boot */
+       uint32_t timestamp_ms;  /* 04 - 07 milliseconds since boot */
+       uint16_t device_index;  /* 08 - 09  */
+       uint16_t fw_conn_state; /* 0A - 0B  */
+       uint8_t event_type;     /* 0C - 0C  */
+       uint8_t error_code;     /* 0D - 0D  */
+       uint16_t error_code_detail;     /* 0E - 0F  */
+       uint8_t num_consecutive_events; /* 10 - 10  */
+       uint8_t rsvd[3];        /* 11 - 13  */
+};
+
+/*************************************************************************
+ *
+ *                             IOCB Commands Structures and Definitions
+ *
+ *************************************************************************/
+#define IOCB_MAX_CDB_LEN           16  /* Bytes in a CBD */
+#define IOCB_MAX_SENSEDATA_LEN     32  /* Bytes of sense data */
+
+/* IOCB header structure */
+struct qla4_header {
+       uint8_t entryType;
+#define ET_STATUS               0x03
+#define ET_MARKER               0x04
+#define ET_CONT_T1              0x0A
+#define ET_STATUS_CONTINUATION  0x10
+#define ET_CMND_T3              0x19
+#define ET_PASSTHRU0            0x3A
+#define ET_PASSTHRU_STATUS      0x3C
+
+       uint8_t entryStatus;
+       uint8_t systemDefined;
+       uint8_t entryCount;
+
+       /* SyetemDefined definition */
+};
+
+/* Generic queue entry structure*/
+struct queue_entry {
+       uint8_t data[60];
+       uint32_t signature;
+
+};
+
+/* 64 bit addressing segment counts*/
+
+#define COMMAND_SEG_A64          1
+#define CONTINUE_SEG_A64  5
+
+/* 64 bit addressing segment definition*/
+
+struct data_seg_a64 {
+       struct {
+               uint32_t addrLow;
+               uint32_t addrHigh;
+
+       } base;
+
+       uint32_t count;
+
+};
+
+/* Command Type 3 entry structure*/
+
+struct command_t3_entry {
+       struct qla4_header hdr; /* 00-03 */
+
+       uint32_t handle;        /* 04-07 */
+       uint16_t target;        /* 08-09 */
+       uint16_t connection_id; /* 0A-0B */
+
+       uint8_t control_flags;  /* 0C */
+
+       /* data direction  (bits 5-6) */
+#define CF_WRITE               0x20
+#define CF_READ                        0x40
+#define CF_NO_DATA             0x00
+
+       /* task attributes (bits 2-0) */
+#define CF_HEAD_TAG            0x03
+#define CF_ORDERED_TAG         0x02
+#define CF_SIMPLE_TAG          0x01
+
+       /* STATE FLAGS FIELD IS A PLACE HOLDER. THE FW WILL SET BITS
+        * IN THIS FIELD AS THE COMMAND IS PROCESSED. WHEN THE IOCB IS
+        * CHANGED TO AN IOSB THIS FIELD WILL HAVE THE STATE FLAGS SET
+        * PROPERLY.
+        */
+       uint8_t state_flags;    /* 0D */
+       uint8_t cmdRefNum;      /* 0E */
+       uint8_t reserved1;      /* 0F */
+       uint8_t cdb[IOCB_MAX_CDB_LEN];  /* 10-1F */
+       struct scsi_lun lun;    /* FCP LUN (BE). */
+       uint32_t cmdSeqNum;     /* 28-2B */
+       uint16_t timeout;       /* 2C-2D */
+       uint16_t dataSegCnt;    /* 2E-2F */
+       uint32_t ttlByteCnt;    /* 30-33 */
+       struct data_seg_a64 dataseg[COMMAND_SEG_A64];   /* 34-3F */
+
+};
+
+
+/* Continuation Type 1 entry structure*/
+struct continuation_t1_entry {
+       struct qla4_header hdr;
+
+       struct data_seg_a64 dataseg[CONTINUE_SEG_A64];
+
+};
+
+/* Parameterize for 64 or 32 bits */
+#define COMMAND_SEG    COMMAND_SEG_A64
+#define CONTINUE_SEG   CONTINUE_SEG_A64
+
+#define ET_COMMAND     ET_CMND_T3
+#define ET_CONTINUE    ET_CONT_T1
+
+/* Marker entry structure*/
+struct marker_entry {
+       struct qla4_header hdr; /* 00-03 */
+
+       uint32_t system_defined; /* 04-07 */
+       uint16_t target;        /* 08-09 */
+       uint16_t modifier;      /* 0A-0B */
+#define MM_LUN_RESET        0
+
+       uint16_t flags;         /* 0C-0D */
+       uint16_t reserved1;     /* 0E-0F */
+       struct scsi_lun lun;    /* FCP LUN (BE). */
+       uint64_t reserved2;     /* 18-1F */
+       uint64_t reserved3;     /* 20-27 */
+       uint64_t reserved4;     /* 28-2F */
+       uint64_t reserved5;     /* 30-37 */
+       uint64_t reserved6;     /* 38-3F */
+};
+
+/* Status entry structure*/
+struct status_entry {
+       struct qla4_header hdr; /* 00-03 */
+
+       uint32_t handle;        /* 04-07 */
+
+       uint8_t scsiStatus;     /* 08 */
+#define SCSI_CHECK_CONDITION             0x02
+
+       uint8_t iscsiFlags;     /* 09 */
+#define ISCSI_FLAG_RESIDUAL_UNDER        0x02
+#define ISCSI_FLAG_RESIDUAL_OVER         0x04
+
+       uint8_t iscsiResponse;  /* 0A */
+
+       uint8_t completionStatus;       /* 0B */
+#define SCS_COMPLETE                     0x00
+#define SCS_INCOMPLETE                   0x01
+#define SCS_RESET_OCCURRED               0x04
+#define SCS_ABORTED                      0x05
+#define SCS_TIMEOUT                      0x06
+#define SCS_DATA_OVERRUN                 0x07
+#define SCS_DATA_UNDERRUN                0x15
+#define SCS_QUEUE_FULL                   0x1C
+#define SCS_DEVICE_UNAVAILABLE           0x28
+#define SCS_DEVICE_LOGGED_OUT            0x29
+
+       uint8_t reserved1;      /* 0C */
+
+       /* state_flags MUST be at the same location as state_flags in
+        * the Command_T3/4_Entry */
+       uint8_t state_flags;    /* 0D */
+
+       uint16_t senseDataByteCnt;      /* 0E-0F */
+       uint32_t residualByteCnt;       /* 10-13 */
+       uint32_t bidiResidualByteCnt;   /* 14-17 */
+       uint32_t expSeqNum;     /* 18-1B */
+       uint32_t maxCmdSeqNum;  /* 1C-1F */
+       uint8_t senseData[IOCB_MAX_SENSEDATA_LEN];      /* 20-3F */
+
+};
+
+struct passthru0 {
+       struct qla4_header hdr;                /* 00-03 */
+       uint32_t handle;        /* 04-07 */
+       uint16_t target;        /* 08-09 */
+       uint16_t connectionID;  /* 0A-0B */
+#define ISNS_DEFAULT_SERVER_CONN_ID    ((uint16_t)0x8000)
+
+       uint16_t controlFlags;  /* 0C-0D */
+#define PT_FLAG_ETHERNET_FRAME         0x8000
+#define PT_FLAG_ISNS_PDU               0x8000
+#define PT_FLAG_SEND_BUFFER            0x0200
+#define PT_FLAG_WAIT_4_RESPONSE                0x0100
+
+       uint16_t timeout;       /* 0E-0F */
+#define PT_DEFAULT_TIMEOUT             30 /* seconds */
+
+       struct data_seg_a64 outDataSeg64;       /* 10-1B */
+       uint32_t res1;          /* 1C-1F */
+       struct data_seg_a64 inDataSeg64;        /* 20-2B */
+       uint8_t res2[20];       /* 2C-3F */
+};
+
+struct passthru_status {
+       struct qla4_header hdr;                /* 00-03 */
+       uint32_t handle;        /* 04-07 */
+       uint16_t target;        /* 08-09 */
+       uint16_t connectionID;  /* 0A-0B */
+
+       uint8_t completionStatus;       /* 0C */
+#define PASSTHRU_STATUS_COMPLETE               0x01
+
+       uint8_t residualFlags;  /* 0D */
+
+       uint16_t timeout;       /* 0E-0F */
+       uint16_t portNumber;    /* 10-11 */
+       uint8_t res1[10];       /* 12-1B */
+       uint32_t outResidual;   /* 1C-1F */
+       uint8_t res2[12];       /* 20-2B */
+       uint32_t inResidual;    /* 2C-2F */
+       uint8_t res4[16];       /* 30-3F */
+};
+
+#endif /*  _QLA4X_FW_H */
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
new file mode 100644 (file)
index 0000000..418fb7a
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#ifndef __QLA4x_GBL_H
+#define        __QLA4x_GBL_H
+
+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);
+int qla4xxx_initialize_adapter(struct scsi_qla_host * ha,
+                              uint8_t renew_ddb_list);
+int qla4xxx_soft_reset(struct scsi_qla_host *ha);
+irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id, struct pt_regs *regs);
+
+void qla4xxx_free_ddb_list(struct scsi_qla_host * ha);
+void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen);
+
+int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha);
+int qla4xxx_relogin_device(struct scsi_qla_host * ha,
+                          struct ddb_entry * ddb_entry);
+int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
+                     int lun);
+int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr,
+                     uint32_t offset, uint32_t len);
+int qla4xxx_get_firmware_status(struct scsi_qla_host * ha);
+int qla4xxx_get_firmware_state(struct scsi_qla_host * ha);
+int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha);
+
+/* FIXME: Goodness!  this really wants a small struct to hold the
+ * parameters. On x86 the args will get passed on the stack! */
+int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
+                           uint16_t fw_ddb_index,
+                           struct dev_db_entry *fw_ddb_entry,
+                           dma_addr_t fw_ddb_entry_dma,
+                           uint32_t *num_valid_ddb_entries,
+                           uint32_t *next_ddb_index,
+                           uint32_t *fw_ddb_device_state,
+                           uint32_t *conn_err_detail,
+                           uint16_t *tcp_source_port_num,
+                           uint16_t *connection_id);
+
+struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host * ha,
+                                    uint32_t fw_ddb_index);
+int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
+                         dma_addr_t fw_ddb_entry_dma);
+
+void qla4xxx_mark_device_missing(struct scsi_qla_host *ha,
+                                struct ddb_entry *ddb_entry);
+u16 rd_nvram_word(struct scsi_qla_host * ha, int offset);
+void qla4xxx_get_crash_record(struct scsi_qla_host * ha);
+struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha);
+int qla4xxx_add_sess(struct ddb_entry *);
+void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry);
+int qla4xxx_conn_close_sess_logout(struct scsi_qla_host * ha,
+                                  uint16_t fw_ddb_index,
+                                  uint16_t connection_id,
+                                  uint16_t option);
+int qla4xxx_clear_database_entry(struct scsi_qla_host * ha,
+                                uint16_t fw_ddb_index);
+int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host * ha);
+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);
+void qla4xxx_dump_buffer(void *b, uint32_t size);
+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);
+
+extern int extended_error_logging;
+extern int ql4xdiscoverywait;
+extern int ql4xdontresethba;
+#endif                         /* _QLA4x_GBL_H */
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
new file mode 100644 (file)
index 0000000..bb3a1c1
--- /dev/null
@@ -0,0 +1,1340 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#include "ql4_def.h"
+
+/*
+ * QLogic ISP4xxx Hardware Support Function Prototypes.
+ */
+
+static void ql4xxx_set_mac_number(struct scsi_qla_host *ha)
+{
+       uint32_t value;
+       uint8_t func_number;
+       unsigned long flags;
+
+       /* Get the function number */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       value = readw(&ha->reg->ctrl_status);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       func_number = (uint8_t) ((value >> 4) & 0x30);
+       switch (value & ISP_CONTROL_FN_MASK) {
+       case ISP_CONTROL_FN0_SCSI:
+               ha->mac_index = 1;
+               break;
+       case ISP_CONTROL_FN1_SCSI:
+               ha->mac_index = 3;
+               break;
+       default:
+               DEBUG2(printk("scsi%ld: %s: Invalid function number, "
+                             "ispControlStatus = 0x%x\n", ha->host_no,
+                             __func__, value));
+               break;
+       }
+       DEBUG2(printk("scsi%ld: %s: mac_index %d.\n", ha->host_no, __func__,
+                     ha->mac_index));
+}
+
+/**
+ * qla4xxx_free_ddb - deallocate ddb
+ * @ha: pointer to host adapter structure.
+ * @ddb_entry: pointer to device database entry
+ *
+ * This routine deallocates and unlinks the specified ddb_entry from the
+ * adapter's
+ **/
+void qla4xxx_free_ddb(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry)
+{
+       /* Remove device entry from list */
+       list_del_init(&ddb_entry->list);
+
+       /* Remove device pointer from index mapping arrays */
+       ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] =
+               (struct ddb_entry *) INVALID_ENTRY;
+       ha->tot_ddbs--;
+
+       /* Free memory and scsi-ml struct for device entry */
+       qla4xxx_destroy_sess(ddb_entry);
+}
+
+/**
+ * qla4xxx_free_ddb_list - deallocate all ddbs
+ * @ha: pointer to host adapter structure.
+ *
+ * This routine deallocates and removes all devices on the sppecified adapter.
+ **/
+void qla4xxx_free_ddb_list(struct scsi_qla_host *ha)
+{
+       struct list_head *ptr;
+       struct ddb_entry *ddb_entry;
+
+       while (!list_empty(&ha->ddb_list)) {
+               ptr = ha->ddb_list.next;
+               /* Free memory for device entry and remove */
+               ddb_entry = list_entry(ptr, struct ddb_entry, list);
+               qla4xxx_free_ddb(ha, ddb_entry);
+       }
+}
+
+/**
+ * qla4xxx_init_rings - initialize hw queues
+ * @ha: pointer to host adapter structure.
+ *
+ * This routine initializes the internal queues for the specified adapter.
+ * The QLA4010 requires us to restart the queues at index 0.
+ * The QLA4000 doesn't care, so just default to QLA4010's requirement.
+ **/
+int qla4xxx_init_rings(struct scsi_qla_host *ha)
+{
+       unsigned long flags = 0;
+
+       /* Initialize request queue. */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       ha->request_out = 0;
+       ha->request_in = 0;
+       ha->request_ptr = &ha->request_ring[ha->request_in];
+       ha->req_q_count = REQUEST_QUEUE_DEPTH;
+
+       /* Initialize response queue. */
+       ha->response_in = 0;
+       ha->response_out = 0;
+       ha->response_ptr = &ha->response_ring[ha->response_out];
+
+       /*
+        * Initialize DMA Shadow registers.  The firmware is really supposed to
+        * take care of this, but on some uniprocessor systems, the shadow
+        * registers aren't cleared-- causing the interrupt_handler to think
+        * there are responses to be processed when there aren't.
+        */
+       ha->shadow_regs->req_q_out = __constant_cpu_to_le32(0);
+       ha->shadow_regs->rsp_q_in = __constant_cpu_to_le32(0);
+       wmb();
+
+       writel(0, &ha->reg->req_q_in);
+       writel(0, &ha->reg->rsp_q_out);
+       readl(&ha->reg->rsp_q_out);
+
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       return QLA_SUCCESS;
+}
+
+/**
+ * qla4xxx_validate_mac_address - validate adapter MAC address(es)
+ * @ha: pointer to host adapter structure.
+ *
+ **/
+static int qla4xxx_validate_mac_address(struct scsi_qla_host *ha)
+{
+       struct flash_sys_info *sys_info;
+       dma_addr_t sys_info_dma;
+       int status = QLA_ERROR;
+
+       sys_info = dma_alloc_coherent(&ha->pdev->dev, sizeof(*sys_info),
+                                     &sys_info_dma, GFP_KERNEL);
+       if (sys_info == NULL) {
+               DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n",
+                             ha->host_no, __func__));
+
+               goto exit_validate_mac_no_free;
+       }
+       memset(sys_info, 0, sizeof(*sys_info));
+
+       /* Get flash sys info */
+       if (qla4xxx_get_flash(ha, sys_info_dma, FLASH_OFFSET_SYS_INFO,
+                             sizeof(*sys_info)) != QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s: get_flash FLASH_OFFSET_SYS_INFO "
+                             "failed\n", ha->host_no, __func__));
+
+               goto exit_validate_mac;
+       }
+
+       /* Save M.A.C. address & serial_number */
+       memcpy(ha->my_mac, &sys_info->physAddr[0].address[0],
+              min(sizeof(ha->my_mac),
+                  sizeof(sys_info->physAddr[0].address)));
+       memcpy(ha->serial_number, &sys_info->acSerialNumber,
+              min(sizeof(ha->serial_number),
+                  sizeof(sys_info->acSerialNumber)));
+
+       status = QLA_SUCCESS;
+
+ exit_validate_mac:
+       dma_free_coherent(&ha->pdev->dev, sizeof(*sys_info), sys_info,
+                         sys_info_dma);
+
+ exit_validate_mac_no_free:
+       return status;
+}
+
+/**
+ * qla4xxx_init_local_data - initialize adapter specific local data
+ * @ha: pointer to host adapter structure.
+ *
+ **/
+static int qla4xxx_init_local_data(struct scsi_qla_host *ha)
+{
+       /* Initilize aen queue */
+       ha->aen_q_count = MAX_AEN_ENTRIES;
+
+       return qla4xxx_get_firmware_status(ha);
+}
+
+static int qla4xxx_fw_ready(struct scsi_qla_host *ha)
+{
+       uint32_t timeout_count;
+       int ready = 0;
+
+       DEBUG2(dev_info(&ha->pdev->dev, "Waiting for Firmware Ready..\n"));
+       for (timeout_count = ADAPTER_INIT_TOV; timeout_count > 0;
+            timeout_count--) {
+               if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags))
+                       qla4xxx_get_dhcp_ip_address(ha);
+
+               /* Get firmware state. */
+               if (qla4xxx_get_firmware_state(ha) != QLA_SUCCESS) {
+                       DEBUG2(printk("scsi%ld: %s: unable to get firmware "
+                                     "state\n", ha->host_no, __func__));
+                       break;
+
+               }
+
+               if (ha->firmware_state & FW_STATE_ERROR) {
+                       DEBUG2(printk("scsi%ld: %s: an unrecoverable error has"
+                                     " occurred\n", ha->host_no, __func__));
+                       break;
+
+               }
+               if (ha->firmware_state & FW_STATE_CONFIG_WAIT) {
+                       /*
+                        * The firmware has not yet been issued an Initialize
+                        * Firmware command, so issue it now.
+                        */
+                       if (qla4xxx_initialize_fw_cb(ha) == QLA_ERROR)
+                               break;
+
+                       /* Go back and test for ready state - no wait. */
+                       continue;
+               }
+
+               if (ha->firmware_state == FW_STATE_READY) {
+                       DEBUG2(dev_info(&ha->pdev->dev, "Firmware Ready..\n"));
+                       /* The firmware is ready to process SCSI commands. */
+                       DEBUG2(dev_info(&ha->pdev->dev,
+                                         "scsi%ld: %s: MEDIA TYPE - %s\n",
+                                         ha->host_no,
+                                         __func__, (ha->addl_fw_state &
+                                                    FW_ADDSTATE_OPTICAL_MEDIA)
+                                         != 0 ? "OPTICAL" : "COPPER"));
+                       DEBUG2(dev_info(&ha->pdev->dev,
+                                         "scsi%ld: %s: DHCP STATE Enabled "
+                                         "%s\n",
+                                         ha->host_no, __func__,
+                                         (ha->addl_fw_state &
+                                          FW_ADDSTATE_DHCP_ENABLED) != 0 ?
+           &nbs