]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'linus'
authorJames Bottomley <jejb@mulgrave.il.steeleye.com>
Wed, 31 Jan 2007 17:24:00 +0000 (11:24 -0600)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Wed, 31 Jan 2007 17:24:00 +0000 (11:24 -0600)
1  2 
drivers/scsi/Kconfig
drivers/scsi/aacraid/linit.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gbl.h
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/scsi_scan.c

diff --combined drivers/scsi/Kconfig
index 0133f3a6977da4bccf9a08da4adcaf5cdb1820e5,7869c34a4a3eed46f82c281adc238aa48e5591df..5bf3f07870ba14f86a5805e3e9f13260420ba564
@@@ -973,15 -973,6 +973,15 @@@ config SCSI_LASI70
          many PA-RISC workstations & servers.  If you do not know whether you
          have a Lasi chip, it is safe to say "Y" here.
  
 +config SCSI_SNI_53C710
 +      tristate "SNI RM SCSI support for 53c710"
 +      depends on SNI_RM && SCSI
 +      select SCSI_SPI_ATTRS
 +      select 53C700_LE_ON_BE
 +      help
 +        This is a driver for the onboard SCSI controller found in older
 +        SNI RM workstations & servers.
 +
  config 53C700_LE_ON_BE
        bool
        depends on SCSI_LASI700
@@@ -1312,7 -1303,7 +1312,7 @@@ config SCSI_LPF
  
  config SCSI_SEAGATE
        tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support"
-       depends on X86 && ISA && SCSI && BROKEN
+       depends on X86 && ISA && SCSI
        ---help---
          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,
index 1feda449aedc9244f42ee94b32173d76334cec31,d2cf875af59b6139fa99f63257b1e189fc22551a..a9734e08fe28a7cf35d01727a0ab509c0aff7da3
@@@ -117,8 -117,8 +117,8 @@@ static struct pci_device_id aac_pci_tbl
        { 0x9005, 0x0286, 0x9005, 0x029b, 0, 0, 22 }, /* AAR-2820SA (Intruder) */
        { 0x9005, 0x0286, 0x9005, 0x029c, 0, 0, 23 }, /* AAR-2620SA (Intruder) */
        { 0x9005, 0x0286, 0x9005, 0x029d, 0, 0, 24 }, /* AAR-2420SA (Intruder) */
-       { 0x9005, 0x0286, 0x9005, 0x029e, 0, 0, 25 }, /* ICP9024R0 (Lancer) */
-       { 0x9005, 0x0286, 0x9005, 0x029f, 0, 0, 26 }, /* ICP9014R0 (Lancer) */
+       { 0x9005, 0x0286, 0x9005, 0x029e, 0, 0, 25 }, /* ICP9024RO (Lancer) */
+       { 0x9005, 0x0286, 0x9005, 0x029f, 0, 0, 26 }, /* ICP9014RO (Lancer) */
        { 0x9005, 0x0286, 0x9005, 0x02a0, 0, 0, 27 }, /* ICP9047MA (Lancer) */
        { 0x9005, 0x0286, 0x9005, 0x02a1, 0, 0, 28 }, /* ICP9087MA (Lancer) */
        { 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5445AU (Hurricane44) */
        { 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 41 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
        { 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 42 }, /* AAR-2610SA PCI SATA 6ch */
        { 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 43 }, /* ASR-2240S (SabreExpress) */
-       { 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 44 }, /* ASR-4005SAS */
+       { 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 44 }, /* ASR-4005 */
        { 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 45 }, /* IBM 8i (AvonPark) */
        { 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 45 }, /* IBM 8i (AvonPark Lite) */
        { 0x9005, 0x0286, 0x1014, 0x9580, 0, 0, 46 }, /* IBM 8k/8k-l8 (Aurora) */
        { 0x9005, 0x0286, 0x1014, 0x9540, 0, 0, 47 }, /* IBM 8k/8k-l4 (Aurora Lite) */
-       { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 }, /* ASR-4000SAS (BlackBird) */
+       { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 }, /* ASR-4000 (BlackBird) */
        { 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 49 }, /* ASR-4800SAS (Marauder-X) */
        { 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 50 }, /* ASR-4805SAS (Marauder-E) */
-       { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-3800SAS (Hurricane44) */
+       { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-3800 (Hurricane44) */
  
        { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 52 }, /* Perc 320/DC*/
        { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 53 }, /* Adaptec 5400S (Mustang)*/
        { 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 58 }, /* Legend Catchall */
        { 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 59 }, /* Adaptec Catch All */
        { 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 60 }, /* Adaptec Rocket Catch All */
 +      { 0x9005, 0x0288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 61 }, /* Adaptec NEMER/ARK Catch All */
        { 0,}
  };
  MODULE_DEVICE_TABLE(pci, aac_pci_tbl);
@@@ -194,8 -193,8 +194,8 @@@ static struct aac_driver_ident aac_driv
        { aac_rkt_init, "aacraid",  "ADAPTEC ", "AAR-2820SA      ", 1 }, /* AAR-2820SA (Intruder) */
        { aac_rkt_init, "aacraid",  "ADAPTEC ", "AAR-2620SA      ", 1 }, /* AAR-2620SA (Intruder) */
        { aac_rkt_init, "aacraid",  "ADAPTEC ", "AAR-2420SA      ", 1 }, /* AAR-2420SA (Intruder) */
-       { aac_rkt_init, "aacraid",  "ICP     ", "ICP9024R0       ", 2 }, /* ICP9024R0 (Lancer) */
-       { aac_rkt_init, "aacraid",  "ICP     ", "ICP9014R0       ", 1 }, /* ICP9014R0 (Lancer) */
+       { aac_rkt_init, "aacraid",  "ICP     ", "ICP9024RO       ", 2 }, /* ICP9024RO (Lancer) */
+       { aac_rkt_init, "aacraid",  "ICP     ", "ICP9014RO       ", 1 }, /* ICP9014RO (Lancer) */
        { aac_rkt_init, "aacraid",  "ICP     ", "ICP9047MA       ", 1 }, /* ICP9047MA (Lancer) */
        { aac_rkt_init, "aacraid",  "ICP     ", "ICP9087MA       ", 1 }, /* ICP9087MA (Lancer) */
        { aac_rkt_init, "aacraid",  "ICP     ", "ICP5445AU       ", 1 }, /* ICP5445AU (Hurricane44) */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2026ZCR     ", 1 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-2610SA      ", 1 }, /* SATA 6Ch (Bearcat) */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2240S       ", 1 }, /* ASR-2240S (SabreExpress) */
-       { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4005SAS     ", 1 }, /* ASR-4005SAS */
+       { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4005        ", 1 }, /* ASR-4005 */
        { aac_rx_init, "ServeRAID","IBM     ", "ServeRAID 8i    ", 1 }, /* IBM 8i (AvonPark) */
        { aac_rkt_init, "ServeRAID","IBM     ", "ServeRAID 8k-l8 ", 1 }, /* IBM 8k/8k-l8 (Aurora) */
        { aac_rkt_init, "ServeRAID","IBM     ", "ServeRAID 8k-l4 ", 1 }, /* IBM 8k/8k-l4 (Aurora Lite) */
-       { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4000SAS     ", 1 }, /* ASR-4000SAS (BlackBird & AvonPark) */
+       { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4000        ", 1 }, /* ASR-4000 (BlackBird & AvonPark) */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4800SAS     ", 1 }, /* ASR-4800SAS (Marauder-X) */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4805SAS     ", 1 }, /* ASR-4805SAS (Marauder-E) */
-       { aac_rkt_init, "aacraid",  "ADAPTEC ", "ASR-3800SAS     ", 1 }, /* ASR-3800SAS (Hurricane44) */
+       { aac_rkt_init, "aacraid",  "ADAPTEC ", "ASR-3800        ", 1 }, /* ASR-3800 (Hurricane44) */
  
        { aac_rx_init, "percraid", "DELL    ", "PERC 320/DC     ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/
        { aac_sa_init, "aacraid",  "ADAPTEC ", "Adaptec 5400S   ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
        { aac_rx_init, "aacraid",  "DELL    ", "RAID            ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Dell Catchall */
        { aac_rx_init, "aacraid",  "Legend  ", "RAID            ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend Catchall */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "RAID            ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec Catch All */
 -      { aac_rkt_init, "aacraid", "ADAPTEC ", "RAID            ", 2 } /* Adaptec Rocket Catch All */
 +      { aac_rkt_init, "aacraid", "ADAPTEC ", "RAID            ", 2 }, /* Adaptec Rocket Catch All */
 +      { aac_nark_init, "aacraid", "ADAPTEC ", "RAID            ", 2 } /* Adaptec NEMER/ARK Catch All */
  };
  
  /**
@@@ -398,15 -396,11 +398,15 @@@ static int aac_slave_configure(struct s
                sdev->skip_ms_page_3f = 1;
        }
        if ((sdev->type == TYPE_DISK) &&
 -                      !expose_physicals &&
                        (sdev_channel(sdev) != CONTAINER_CHANNEL)) {
 -              struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
 -              if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))
 -                      sdev->no_uld_attach = 1;
 +              if (expose_physicals == 0)
 +                      return -ENXIO;
 +              if (expose_physicals < 0) {
 +                      struct aac_dev *aac =
 +                              (struct aac_dev *)sdev->host->hostdata;
 +                      if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))
 +                              sdev->no_uld_attach = 1;
 +              }
        }
        if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
                        (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
@@@ -810,6 -804,7 +810,6 @@@ static struct scsi_host_template aac_dr
        .emulated                       = 1,
  };
  
 -
  static int __devinit aac_probe_one(struct pci_dev *pdev,
                const struct pci_device_id *id)
  {
index e83e4a34725a6be2c35470bf8431afd012d4770c,2c10130d9e03fe2a037f361ed80ef80963aa8f8b..05f4f2a378eb6d14635f2e8e7ee5f0db904565d4
@@@ -1602,6 -1602,7 +1602,7 @@@ typedef struct fc_port 
  
  #define CT_REJECT_RESPONSE    0x8001
  #define CT_ACCEPT_RESPONSE    0x8002
+ #define CT_REASON_INVALID_COMMAND_CODE        0x01
  #define CT_REASON_CANNOT_PERFORM      0x09
  #define CT_EXPL_ALREADY_REGISTERED    0x10
  
@@@ -2044,29 -2045,6 +2045,29 @@@ struct isp_operations 
                uint32_t, uint32_t);
        int (*write_optrom) (struct scsi_qla_host *, uint8_t *, uint32_t,
                uint32_t);
 +
 +      int (*get_flash_version) (struct scsi_qla_host *, void *);
 +};
 +
 +/* MSI-X Support *************************************************************/
 +
 +#define QLA_MSIX_CHIP_REV_24XX        3
 +#define QLA_MSIX_FW_MODE(m)   (((m) & (BIT_7|BIT_8|BIT_9)) >> 7)
 +#define QLA_MSIX_FW_MODE_1(m) (QLA_MSIX_FW_MODE(m) == 1)
 +
 +#define QLA_MSIX_DEFAULT      0x00
 +#define QLA_MSIX_RSP_Q                0x01
 +
 +#define QLA_MSIX_ENTRIES      2
 +#define QLA_MIDX_DEFAULT      0
 +#define QLA_MIDX_RSP_Q                1
 +
 +struct scsi_qla_host;
 +
 +struct qla_msix_entry {
 +      int have_irq;
 +      uint16_t msix_vector;
 +      uint16_t msix_entry;
  };
  
  /*
@@@ -2099,10 -2077,10 +2100,11 @@@ typedef struct scsi_qla_host 
                uint32_t        enable_lip_full_login   :1;
                uint32_t        enable_target_reset     :1;
                uint32_t        enable_led_scheme       :1;
 +              uint32_t        inta_enabled            :1;
                uint32_t        msi_enabled             :1;
                uint32_t        msix_enabled            :1;
                uint32_t        disable_serdes          :1;
+               uint32_t        gpsc_supported          :1;
        } flags;
  
        atomic_t        loop_state;
  #define MBX_INTR_WAIT 2
  #define MBX_UPDATE_FLASH_ACTIVE       3
  
 -      spinlock_t      mbx_reg_lock;   /* Mbx Cmd Register Lock */
 -
        struct semaphore mbx_cmd_sem;   /* Serialialize mbx access */
        struct semaphore mbx_intr_sem;  /* Used for completion notification */
  
  
        uint8_t         host_str[16];
        uint32_t        pci_attr;
 +      uint16_t        chip_revision;
  
        uint16_t        product_id[4];
  
  #define QLA_SREADING  1
  #define QLA_SWRITING  2
  
 +        /* PCI expansion ROM image information. */
 +#define ROM_CODE_TYPE_BIOS    0
 +#define ROM_CODE_TYPE_FCODE   1
 +#define ROM_CODE_TYPE_EFI     3
 +      uint8_t         bios_revision[2];
 +      uint8_t         efi_revision[2];
 +      uint8_t         fcode_revision[16];
 +      uint32_t        fw_revision[4];
 +
        /* Needed for BEACON */
        uint16_t        beacon_blink_led;
        uint8_t         beacon_color_state;
        uint16_t        zio_mode;
        uint16_t        zio_timer;
        struct fc_host_statistics fc_host_stat;
 +
 +      struct qla_msix_entry msix_entries[QLA_MSIX_ENTRIES];
  } scsi_qla_host_t;
  
  
index f8bddec4fe85ec19bc8b3f738ed7c2fce692e5d2,e4dd12f4b80eaf014d84f9e837a9cc8c3901ab12..74544ae4b0e270128de9976c4397b31703802dad
@@@ -45,7 -45,6 +45,6 @@@ extern void qla2x00_update_fcports(scsi
  extern int qla2x00_abort_isp(scsi_qla_host_t *);
  
  extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
- extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *);
  
  extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
  extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
@@@ -225,9 -224,6 +224,9 @@@ extern irqreturn_t qla24xx_intr_handler
  extern void qla2x00_process_response_queue(struct scsi_qla_host *);
  extern void qla24xx_process_response_queue(struct scsi_qla_host *);
  
 +extern int qla2x00_request_irqs(scsi_qla_host_t *);
 +extern void qla2x00_free_irqs(scsi_qla_host_t *);
 +
  /*
   * Global Function Prototypes in qla_sup.c source file.
   */
@@@ -263,9 -259,6 +262,9 @@@ extern uint8_t *qla24xx_read_optrom_dat
  extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *,
      uint32_t, uint32_t);
  
 +extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *);
 +extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
 +
  /*
   * Global Function Prototypes in qla_dbg.c source file.
   */
index ef87d81935d2e295291d77e859148b21ed1d2b98,b3dac26ddba3e50767c852aecaf07921bf4f363a..98c01cd5e1a82a954eef3822ecde52689459d84d
@@@ -65,7 -65,7 +65,7 @@@ qla2x00_initialize_adapter(scsi_qla_hos
        ha->flags.reset_active = 0;
        atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
        atomic_set(&ha->loop_state, LOOP_DOWN);
 -      ha->device_flags = 0;
 +      ha->device_flags = DFLG_NO_CABLE;
        ha->dpc_flags = 0;
        ha->flags.management_server_logged_in = 0;
        ha->marker_needed = 0;
        qla_printk(KERN_INFO, ha, "Configuring PCI space...\n");
        rval = ha->isp_ops.pci_config(ha);
        if (rval) {
 -              DEBUG2(printk("scsi(%ld): Unable to configure PCI space=n",
 +              DEBUG2(printk("scsi(%ld): Unable to configure PCI space.\n",
                    ha->host_no));
                return (rval);
        }
  
        ha->isp_ops.reset_chip(ha);
  
 +      ha->isp_ops.get_flash_version(ha, ha->request_ring);
 +
        qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n");
  
 -      ha->isp_ops.nvram_config(ha);
 +      rval = ha->isp_ops.nvram_config(ha);
 +      if (rval) {
 +              DEBUG2(printk("scsi(%ld): Unable to verify NVRAM data.\n",
 +                  ha->host_no));
 +              return rval;
 +      }
  
        if (ha->flags.disable_serdes) {
                /* Mask HBA via NVRAM settings? */
@@@ -300,8 -293,6 +300,8 @@@ qla24xx_pci_config(scsi_qla_host_t *ha
        d &= ~PCI_ROM_ADDRESS_ENABLE;
        pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d);
  
 +      pci_read_config_word(ha->pdev, PCI_REVISION_ID, &ha->chip_revision);
 +
        /* Get PCI bus information. */
        spin_lock_irqsave(&ha->hardware_lock, flags);
        ha->pci_attr = RD_REG_DWORD(&reg->ctrl_status);
@@@ -1360,39 -1351,6 +1360,39 @@@ qla2x00_configure_hba(scsi_qla_host_t *
        return(rval);
  }
  
 +static inline void
 +qla2x00_set_model_info(scsi_qla_host_t *ha, uint8_t *model, size_t len, char *def)
 +{
 +      char *st, *en;
 +      uint16_t index;
 +
 +      if (memcmp(model, BINZERO, len) != 0) {
 +              strncpy(ha->model_number, model, len);
 +              st = en = ha->model_number;
 +              en += len - 1;
 +              while (en > st) {
 +                      if (*en != 0x20 && *en != 0x00)
 +                              break;
 +                      *en-- = '\0';
 +              }
 +
 +              index = (ha->pdev->subsystem_device & 0xff);
 +              if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
 +                  index < QLA_MODEL_NAMES)
 +                      ha->model_desc = qla2x00_model_name[index * 2 + 1];
 +      } else {
 +              index = (ha->pdev->subsystem_device & 0xff);
 +              if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
 +                  index < QLA_MODEL_NAMES) {
 +                      strcpy(ha->model_number,
 +                          qla2x00_model_name[index * 2]);
 +                      ha->model_desc = qla2x00_model_name[index * 2 + 1];
 +              } else {
 +                      strcpy(ha->model_number, def);
 +              }
 +      }
 +}
 +
  /*
  * NVRAM configuration for ISP 2xxx
  *
  int
  qla2x00_nvram_config(scsi_qla_host_t *ha)
  {
 -      int             rval;
        uint8_t         chksum = 0;
        uint16_t        cnt;
        uint8_t         *dptr1, *dptr2;
        uint8_t         *ptr = (uint8_t *)ha->request_ring;
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
  
 -      rval = QLA_SUCCESS;
 -
        /* Determine NVRAM starting address. */
        ha->nvram_size = sizeof(nvram_t);
        ha->nvram_base = 0;
                qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: "
                    "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0],
                    nv->nvram_version);
 -              qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet "
 -                  "invalid -- WWPN) defaults.\n");
 -
 -              /*
 -               * Set default initialization control block.
 -               */
 -              memset(nv, 0, ha->nvram_size);
 -              nv->parameter_block_version = ICB_VERSION;
 -
 -              if (IS_QLA23XX(ha)) {
 -                      nv->firmware_options[0] = BIT_2 | BIT_1;
 -                      nv->firmware_options[1] = BIT_7 | BIT_5;
 -                      nv->add_firmware_options[0] = BIT_5;
 -                      nv->add_firmware_options[1] = BIT_5 | BIT_4;
 -                      nv->frame_payload_size = __constant_cpu_to_le16(2048);
 -                      nv->special_options[1] = BIT_7;
 -              } else if (IS_QLA2200(ha)) {
 -                      nv->firmware_options[0] = BIT_2 | BIT_1;
 -                      nv->firmware_options[1] = BIT_7 | BIT_5;
 -                      nv->add_firmware_options[0] = BIT_5;
 -                      nv->add_firmware_options[1] = BIT_5 | BIT_4;
 -                      nv->frame_payload_size = __constant_cpu_to_le16(1024);
 -              } else if (IS_QLA2100(ha)) {
 -                      nv->firmware_options[0] = BIT_3 | BIT_1;
 -                      nv->firmware_options[1] = BIT_5;
 -                      nv->frame_payload_size = __constant_cpu_to_le16(1024);
 -              }
 -
 -              nv->max_iocb_allocation = __constant_cpu_to_le16(256);
 -              nv->execution_throttle = __constant_cpu_to_le16(16);
 -              nv->retry_count = 8;
 -              nv->retry_delay = 1;
 -
 -              nv->port_name[0] = 33;
 -              nv->port_name[3] = 224;
 -              nv->port_name[4] = 139;
 -
 -              nv->login_timeout = 4;
 -
 -              /*
 -               * Set default host adapter parameters
 -               */
 -              nv->host_p[1] = BIT_2;
 -              nv->reset_delay = 5;
 -              nv->port_down_retry_count = 8;
 -              nv->max_luns_per_target = __constant_cpu_to_le16(8);
 -              nv->link_down_timeout = 60;
 -
 -              rval = 1;
 +              return QLA_FUNCTION_FAILED;
        }
  
  #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
                                strcpy(ha->model_number, "QLA2300");
                        }
                } else {
 -                      if (rval == 0 &&
 -                          memcmp(nv->model_number, BINZERO,
 -                                  sizeof(nv->model_number)) != 0) {
 -                              char *st, *en;
 -
 -                              strncpy(ha->model_number, nv->model_number,
 -                                  sizeof(nv->model_number));
 -                              st = en = ha->model_number;
 -                              en += sizeof(nv->model_number) - 1;
 -                              while (en > st) {
 -                                      if (*en != 0x20 && *en != 0x00)
 -                                              break;
 -                                      *en-- = '\0';
 -                              }
 -                      } else {
 -                              uint16_t        index;
 -
 -                              index = (ha->pdev->subsystem_device & 0xff);
 -                              if (index < QLA_MODEL_NAMES) {
 -                                      strcpy(ha->model_number,
 -                                          qla2x00_model_name[index * 2]);
 -                                      ha->model_desc =
 -                                          qla2x00_model_name[index * 2 + 1];
 -                              } else {
 -                                      strcpy(ha->model_number, "QLA23xx");
 -                              }
 -                      }
 +                      qla2x00_set_model_info(ha, nv->model_number,
 +                          sizeof(nv->model_number), "QLA23xx");
                }
        } else if (IS_QLA2200(ha)) {
                nv->firmware_options[0] |= BIT_2;
                }
        }
  
 -      if (rval) {
 -              DEBUG2_3(printk(KERN_WARNING
 -                  "scsi(%ld): NVRAM configuration failed!\n", ha->host_no));
 -      }
 -      return (rval);
 +      return QLA_SUCCESS;
  }
  
  static void
@@@ -2065,40 -2103,7 +2065,7 @@@ qla2x00_iidma_fcport(scsi_qla_host_t *h
        }
  }
  
- /*
-  * qla2x00_update_fcport
-  *    Updates device on list.
-  *
-  * Input:
-  *    ha = adapter block pointer.
-  *    fcport = port structure pointer.
-  *
-  * Return:
-  *    0  - Success
-  *  BIT_0 - error
-  *
-  * Context:
-  *    Kernel context.
-  */
- void
- qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
- {
-       fcport->ha = ha;
-       fcport->login_retry = 0;
-       fcport->port_login_retry_count = ha->port_down_retry_count *
-           PORT_RETRY_TIME;
-       atomic_set(&fcport->port_down_timer, ha->port_down_retry_count *
-           PORT_RETRY_TIME);
-       fcport->flags &= ~FCF_LOGIN_NEEDED;
-       qla2x00_iidma_fcport(ha, fcport);
-       atomic_set(&fcport->state, FCS_ONLINE);
-       qla2x00_reg_remote_port(ha, fcport);
- }
- void
+ static void
  qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
  {
        struct fc_rport_identifiers rport_ids;
                fcport->os_target_id = rport->scsi_target_id;
  }
  
+ /*
+  * qla2x00_update_fcport
+  *    Updates device on list.
+  *
+  * Input:
+  *    ha = adapter block pointer.
+  *    fcport = port structure pointer.
+  *
+  * Return:
+  *    0  - Success
+  *  BIT_0 - error
+  *
+  * Context:
+  *    Kernel context.
+  */
+ void
+ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
+ {
+       fcport->ha = ha;
+       fcport->login_retry = 0;
+       fcport->port_login_retry_count = ha->port_down_retry_count *
+           PORT_RETRY_TIME;
+       atomic_set(&fcport->port_down_timer, ha->port_down_retry_count *
+           PORT_RETRY_TIME);
+       fcport->flags &= ~FCF_LOGIN_NEEDED;
+       qla2x00_iidma_fcport(ha, fcport);
+       atomic_set(&fcport->state, FCS_ONLINE);
+       qla2x00_reg_remote_port(ha, fcport);
+ }
  /*
   * qla2x00_configure_fabric
   *      Setup SNS devices with loop ID's.
@@@ -3069,11 -3107,7 +3069,11 @@@ qla2x00_abort_isp(scsi_qla_host_t *ha
                }
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
  
 -              ha->isp_ops.nvram_config(ha);
 +              ha->isp_ops.get_flash_version(ha, ha->request_ring);
 +
 +              rval = ha->isp_ops.nvram_config(ha);
 +              if (rval)
 +                      goto isp_abort_retry;
  
                if (!qla2x00_restart_isp(ha)) {
                        clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
                                }
                        }
                } else {        /* failed the ISP abort */
 +isp_abort_retry:
                        ha->flags.online = 1;
                        if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) {
                                if (ha->isp_abort_cnt == 0) {
@@@ -3293,6 -3326,7 +3293,6 @@@ qla24xx_reset_adapter(scsi_qla_host_t *
  int
  qla24xx_nvram_config(scsi_qla_host_t *ha)
  {
 -      int   rval;
        struct init_cb_24xx *icb;
        struct nvram_24xx *nv;
        uint32_t *dptr;
        uint32_t chksum;
        uint16_t cnt;
  
 -      rval = QLA_SUCCESS;
        icb = (struct init_cb_24xx *)ha->init_cb;
        nv = (struct nvram_24xx *)ha->request_ring;
  
                qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: "
                    "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0],
                    le16_to_cpu(nv->nvram_version));
 -              qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet "
 -                  "invalid -- WWPN) defaults.\n");
 -
 -              /*
 -               * Set default initialization control block.
 -               */
 -              memset(nv, 0, ha->nvram_size);
 -              nv->nvram_version = __constant_cpu_to_le16(ICB_VERSION);
 -              nv->version = __constant_cpu_to_le16(ICB_VERSION);
 -              nv->frame_payload_size = __constant_cpu_to_le16(2048);
 -              nv->execution_throttle = __constant_cpu_to_le16(0xFFFF);
 -              nv->exchange_count = __constant_cpu_to_le16(0);
 -              nv->hard_address = __constant_cpu_to_le16(124);
 -              nv->port_name[0] = 0x21;
 -              nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn);
 -              nv->port_name[2] = 0x00;
 -              nv->port_name[3] = 0xe0;
 -              nv->port_name[4] = 0x8b;
 -              nv->port_name[5] = 0x1c;
 -              nv->port_name[6] = 0x55;
 -              nv->port_name[7] = 0x86;
 -              nv->node_name[0] = 0x20;
 -              nv->node_name[1] = 0x00;
 -              nv->node_name[2] = 0x00;
 -              nv->node_name[3] = 0xe0;
 -              nv->node_name[4] = 0x8b;
 -              nv->node_name[5] = 0x1c;
 -              nv->node_name[6] = 0x55;
 -              nv->node_name[7] = 0x86;
 -              nv->login_retry_count = __constant_cpu_to_le16(8);
 -              nv->interrupt_delay_timer = __constant_cpu_to_le16(0);
 -              nv->login_timeout = __constant_cpu_to_le16(0);
 -              nv->firmware_options_1 =
 -                  __constant_cpu_to_le32(BIT_14|BIT_13|BIT_2|BIT_1);
 -              nv->firmware_options_2 = __constant_cpu_to_le32(2 << 4);
 -              nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_12);
 -              nv->firmware_options_3 = __constant_cpu_to_le32(2 << 13);
 -              nv->host_p = __constant_cpu_to_le32(BIT_11|BIT_10);
 -              nv->efi_parameters = __constant_cpu_to_le32(0);
 -              nv->reset_delay = 5;
 -              nv->max_luns_per_target = __constant_cpu_to_le16(128);
 -              nv->port_down_retry_count = __constant_cpu_to_le16(30);
 -              nv->link_down_timeout = __constant_cpu_to_le16(30);
 -
 -              rval = 1;
 +              return QLA_FUNCTION_FAILED;
        }
  
        /* Reset Initialization control block */
        /*
         * Setup driver NVRAM options.
         */
 -      if (memcmp(nv->model_name, BINZERO, sizeof(nv->model_name)) != 0) {
 -              char *st, *en;
 -              uint16_t index;
 -
 -              strncpy(ha->model_number, nv->model_name,
 -                  sizeof(nv->model_name));
 -              st = en = ha->model_number;
 -              en += sizeof(nv->model_name) - 1;
 -              while (en > st) {
 -                      if (*en != 0x20 && *en != 0x00)
 -                              break;
 -                      *en-- = '\0';
 -              }
 -
 -              index = (ha->pdev->subsystem_device & 0xff);
 -              if (index < QLA_MODEL_NAMES)
 -                      ha->model_desc = qla2x00_model_name[index * 2 + 1];
 -      } else
 -              strcpy(ha->model_number, "QLA2462");
 +      qla2x00_set_model_info(ha, nv->model_name, sizeof(nv->model_name),
 +          "QLA2462");
  
        /* Use alternate WWN? */
        if (nv->host_p & __constant_cpu_to_le32(BIT_15)) {
  
        /* Set host adapter parameters. */
        ha->flags.disable_risc_code_load = 0;
-       ha->flags.enable_lip_reset = 1;
-       ha->flags.enable_lip_full_login = 1;
-       ha->flags.enable_target_reset = 1;
+       ha->flags.enable_lip_reset = 0;
+       ha->flags.enable_lip_full_login =
+           le32_to_cpu(nv->host_p) & BIT_10 ? 1: 0;
+       ha->flags.enable_target_reset =
+           le32_to_cpu(nv->host_p) & BIT_11 ? 1: 0;
        ha->flags.enable_led_scheme = 0;
        ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0;
  
                ha->flags.process_response_queue = 1;
        }
  
 -      if (rval) {
 -              DEBUG2_3(printk(KERN_WARNING
 -                  "scsi(%ld): NVRAM configuration failed!\n", ha->host_no));
 -      }
 -      return (rval);
 +      return QLA_SUCCESS;
  }
  
  static int
index c948a8ce723299f5d4a28d9981323c1707ac3d03,39fd17b05be5ada3d3da55515c2d89bba857cd71..d4885616cd39c19077e72b2f083f563ec5cb2ad9
@@@ -86,8 -86,12 +86,8 @@@ qla2100_intr_handler(int irq, void *dev
  
        if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
            (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
 -              spin_lock_irqsave(&ha->mbx_reg_lock, flags);
 -
                set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
                up(&ha->mbx_intr_sem);
 -
 -              spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
        }
  
        return (IRQ_HANDLED);
@@@ -130,11 -134,11 +130,11 @@@ qla2300_intr_handler(int irq, void *dev
                if (stat & HSR_RISC_PAUSED) {
                        hccr = RD_REG_WORD(&reg->hccr);
                        if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8))
-                               qla_printk(KERN_INFO, ha,
-                                   "Parity error -- HCCR=%x.\n", hccr);
+                               qla_printk(KERN_INFO, ha, "Parity error -- "
+                                   "HCCR=%x, Dumping firmware!\n", hccr);
                        else
-                               qla_printk(KERN_INFO, ha,
-                                   "RISC paused -- HCCR=%x.\n", hccr);
+                               qla_printk(KERN_INFO, ha, "RISC paused -- "
+                                   "HCCR=%x, Dumping firmware!\n", hccr);
  
                        /*
                         * Issue a "HARD" reset in order for the RISC
                         */
                        WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
                        RD_REG_WORD(&reg->hccr);
+                       ha->isp_ops.fw_dump(ha, 1);
                        set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
                        break;
                } else if ((stat & HSR_RISC_INT) == 0)
  
        if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
            (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
 -              spin_lock_irqsave(&ha->mbx_reg_lock, flags);
 -
                set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
                up(&ha->mbx_intr_sem);
 -
 -              spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
        }
  
        return (IRQ_HANDLED);
@@@ -467,6 -477,8 +469,8 @@@ qla2x00_async_event(scsi_qla_host_t *ha
                        set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
                }
                set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
+               ha->flags.gpsc_supported = 1;
                break;
  
        case MBA_CHG_IN_CONNECTION:     /* Change in connection mode */
@@@ -642,8 -654,10 +646,8 @@@ qla2x00_ramp_up_queue_depth(scsi_qla_ho
            fcport->last_queue_full + ql2xqfullrampup * HZ))
                return;
  
 -      spin_unlock_irq(&ha->hardware_lock);
        starget_for_each_device(sdev->sdev_target, fcport,
            qla2x00_adjust_sdev_qdepth_up);
 -      spin_lock_irq(&ha->hardware_lock);
  }
  
  /**
@@@ -913,8 -927,10 +917,8 @@@ qla2x00_status_entry(scsi_qla_host_t *h
  
                        /* Adjust queue depth for all luns on the port. */
                        fcport->last_queue_full = jiffies;
 -                      spin_unlock_irq(&ha->hardware_lock);
                        starget_for_each_device(cp->device->sdev_target,
                            fcport, qla2x00_adjust_sdev_qdepth_down);
 -                      spin_lock_irq(&ha->hardware_lock);
                        break;
                }
                if (lscsi_status != SS_CHECK_CONDITION)
                if (lscsi_status != 0) {
                        cp->result = DID_OK << 16 | lscsi_status;
  
 +                      if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
 +                              DEBUG2(printk(KERN_INFO
 +                                  "scsi(%ld): QUEUE FULL status detected "
 +                                  "0x%x-0x%x.\n", ha->host_no, comp_status,
 +                                  scsi_status));
 +
 +                              /*
 +                               * Adjust queue depth for all luns on the
 +                               * port.
 +                               */
 +                              fcport->last_queue_full = jiffies;
 +                              starget_for_each_device(
 +                                  cp->device->sdev_target, fcport,
 +                                  qla2x00_adjust_sdev_qdepth_down);
 +                              break;
 +                      }
                        if (lscsi_status != SS_CHECK_CONDITION)
                                break;
  
@@@ -1444,8 -1444,7 +1448,7 @@@ qla24xx_intr_handler(int irq, void *dev
  
                        qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
                            "Dumping firmware!\n", hccr);
-                       qla24xx_fw_dump(ha, 1);
+                       ha->isp_ops.fw_dump(ha, 1);
                        set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
                        break;
                } else if ((stat & HSRX_RISC_INT) == 0)
  
        if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
            (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
 -              spin_lock_irqsave(&ha->mbx_reg_lock, flags);
 -
                set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
                up(&ha->mbx_intr_sem);
 -
 -              spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
        }
  
        return IRQ_HANDLED;
@@@ -1533,216 -1536,3 +1536,216 @@@ qla24xx_ms_entry(scsi_qla_host_t *ha, s
        qla2x00_sp_compl(ha, sp);
  }
  
 +static irqreturn_t
 +qla24xx_msix_rsp_q(int irq, void *dev_id)
 +{
 +      scsi_qla_host_t *ha;
 +      struct device_reg_24xx __iomem *reg;
 +      unsigned long flags;
 +
 +      ha = dev_id;
 +      reg = &ha->iobase->isp24;
 +
 +      spin_lock_irqsave(&ha->hardware_lock, flags);
 +
 +      qla24xx_process_response_queue(ha);
 +
 +      WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
 +      RD_REG_DWORD_RELAXED(&reg->hccr);
 +
 +      spin_unlock_irqrestore(&ha->hardware_lock, flags);
 +
 +      return IRQ_HANDLED;
 +}
 +
 +static irqreturn_t
 +qla24xx_msix_default(int irq, void *dev_id)
 +{
 +      scsi_qla_host_t *ha;
 +      struct device_reg_24xx __iomem *reg;
 +      int             status;
 +      unsigned long   flags;
 +      unsigned long   iter;
 +      uint32_t        stat;
 +      uint32_t        hccr;
 +      uint16_t        mb[4];
 +
 +      ha = dev_id;
 +      reg = &ha->iobase->isp24;
 +      status = 0;
 +
 +      spin_lock_irqsave(&ha->hardware_lock, flags);
 +      for (iter = 50; iter--; ) {
 +              stat = RD_REG_DWORD(&reg->host_status);
 +              if (stat & HSRX_RISC_PAUSED) {
 +                      hccr = RD_REG_DWORD(&reg->hccr);
 +
 +                      qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
 +                          "Dumping firmware!\n", hccr);
 +                      ha->isp_ops.fw_dump(ha, 1);
 +                      set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 +                      break;
 +              } else if ((stat & HSRX_RISC_INT) == 0)
 +                      break;
 +
 +              switch (stat & 0xff) {
 +              case 0x1:
 +              case 0x2:
 +              case 0x10:
 +              case 0x11:
 +                      qla24xx_mbx_completion(ha, MSW(stat));
 +                      status |= MBX_INTERRUPT;
 +
 +                      break;
 +              case 0x12:
 +                      mb[0] = MSW(stat);
 +                      mb[1] = RD_REG_WORD(&reg->mailbox1);
 +                      mb[2] = RD_REG_WORD(&reg->mailbox2);
 +                      mb[3] = RD_REG_WORD(&reg->mailbox3);
 +                      qla2x00_async_event(ha, mb);
 +                      break;
 +              case 0x13:
 +                      qla24xx_process_response_queue(ha);
 +                      break;
 +              default:
 +                      DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
 +                          "(%d).\n",
 +                          ha->host_no, stat & 0xff));
 +                      break;
 +              }
 +              WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
 +              RD_REG_DWORD_RELAXED(&reg->hccr);
 +      }
 +      spin_unlock_irqrestore(&ha->hardware_lock, flags);
 +
 +      if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 +          (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
 +              set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
 +              up(&ha->mbx_intr_sem);
 +      }
 +
 +      return IRQ_HANDLED;
 +}
 +
 +/* Interrupt handling helpers. */
 +
 +struct qla_init_msix_entry {
 +      uint16_t entry;
 +      uint16_t index;
 +      const char *name;
 +      irqreturn_t (*handler)(int, void *);
 +};
 +
 +static struct qla_init_msix_entry imsix_entries[QLA_MSIX_ENTRIES] = {
 +      { QLA_MSIX_DEFAULT, QLA_MIDX_DEFAULT,
 +              "qla2xxx (default)", qla24xx_msix_default },
 +
 +      { QLA_MSIX_RSP_Q, QLA_MIDX_RSP_Q,
 +              "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
 +};
 +
 +static void
 +qla24xx_disable_msix(scsi_qla_host_t *ha)
 +{
 +      int i;
 +      struct qla_msix_entry *qentry;
 +
 +      for (i = 0; i < QLA_MSIX_ENTRIES; i++) {
 +              qentry = &ha->msix_entries[imsix_entries[i].index];
 +              if (qentry->have_irq)
 +                      free_irq(qentry->msix_vector, ha);
 +      }
 +      pci_disable_msix(ha->pdev);
 +}
 +
 +static int
 +qla24xx_enable_msix(scsi_qla_host_t *ha)
 +{
 +      int i, ret;
 +      struct msix_entry entries[QLA_MSIX_ENTRIES];
 +      struct qla_msix_entry *qentry;
 +
 +      for (i = 0; i < QLA_MSIX_ENTRIES; i++)
 +              entries[i].entry = imsix_entries[i].entry;
 +
 +      ret = pci_enable_msix(ha->pdev, entries, ARRAY_SIZE(entries));
 +      if (ret) {
 +              qla_printk(KERN_WARNING, ha,
 +                  "MSI-X: Failed to enable support -- %d/%d\n",
 +                  QLA_MSIX_ENTRIES, ret);
 +              goto msix_out;
 +      }
 +      ha->flags.msix_enabled = 1;
 +
 +      for (i = 0; i < QLA_MSIX_ENTRIES; i++) {
 +              qentry = &ha->msix_entries[imsix_entries[i].index];
 +              qentry->msix_vector = entries[i].vector;
 +              qentry->msix_entry = entries[i].entry;
 +              qentry->have_irq = 0;
 +              ret = request_irq(qentry->msix_vector,
 +                  imsix_entries[i].handler, 0, imsix_entries[i].name, ha);
 +              if (ret) {
 +                      qla_printk(KERN_WARNING, ha,
 +                          "MSI-X: Unable to register handler -- %x/%d.\n",
 +                          imsix_entries[i].index, ret);
 +                      qla24xx_disable_msix(ha);
 +                      goto msix_out;
 +              }
 +              qentry->have_irq = 1;
 +      }
 +
 +msix_out:
 +      return ret;
 +}
 +
 +int
 +qla2x00_request_irqs(scsi_qla_host_t *ha)
 +{
 +      int ret;
 +
 +      /* If possible, enable MSI-X. */
 +      if (!IS_QLA2432(ha))
 +              goto skip_msix;
 +
 +        if (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX ||
 +          !QLA_MSIX_FW_MODE_1(ha->fw_attributes)) {
 +              DEBUG2(qla_printk(KERN_WARNING, ha,
 +                  "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n",
 +                  ha->chip_revision, ha->fw_attributes));
 +
 +              goto skip_msix;
 +      }
 +
 +      ret = qla24xx_enable_msix(ha);
 +      if (!ret) {
 +              DEBUG2(qla_printk(KERN_INFO, ha,
 +                  "MSI-X: Enabled (0x%X, 0x%X).\n", ha->chip_revision,
 +                  ha->fw_attributes));
 +              return ret;
 +      }
 +      qla_printk(KERN_WARNING, ha,
 +          "MSI-X: Falling back-to INTa mode -- %d.\n", ret);
 +skip_msix:
 +      ret = request_irq(ha->pdev->irq, ha->isp_ops.intr_handler,
 +          IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha);
 +      if (!ret) {
 +              ha->flags.inta_enabled = 1;
 +              ha->host->irq = ha->pdev->irq;
 +      } else {
 +              qla_printk(KERN_WARNING, ha,
 +                  "Failed to reserve interrupt %d already in use.\n",
 +                  ha->pdev->irq);
 +      }
 +
 +      return ret;
 +}
 +
 +void
 +qla2x00_free_irqs(scsi_qla_host_t *ha)
 +{
 +
 +      if (ha->flags.msix_enabled)
 +              qla24xx_disable_msix(ha);
 +      else if (ha->flags.inta_enabled)
 +              free_irq(ha->host->irq, ha);
 +}
index c6f0cdf4cdc4b5b5c64eae567ce13eca3e60c753,077e5789beeb0870742c5720e8d13e5a5d58c9bf..83376f6ac3dbb0c108e9ed5fd986dcc879d06739
@@@ -55,6 -55,7 +55,6 @@@ qla2x00_mailbox_command(scsi_qla_host_
        uint16_t __iomem *optr;
        uint32_t        cnt;
        uint32_t        mboxes;
 -      unsigned long   mbx_flags = 0;
        unsigned long   wait_time;
  
        rval = QLA_SUCCESS;
        /* Save mailbox command for debug */
        ha->mcp = mcp;
  
 -      /* Try to get mailbox register access */
 -      if (!abort_active)
 -              spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);
 -
        DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n",
            ha->host_no, mcp->mb[0]));
  
                        WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
  
 -              if (!abort_active)
 -                      spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
 -
                /* Wait for either the timer to expire
                 * or the mbox completion interrupt
                 */
                else
                        WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
 -              if (!abort_active)
 -                      spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
  
                wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
                while (!ha->flags.mbox_int) {
                } /* while */
        }
  
 -      if (!abort_active)
 -              spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);
 -
        /* Check whether we timed out */
        if (ha->flags.mbox_int) {
                uint16_t *iptr2;
                rval = QLA_FUNCTION_TIMEOUT;
        }
  
 -      if (!abort_active)
 -              spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
 -
        ha->flags.mbox_busy = 0;
  
        /* Clean up */
@@@ -1323,9 -1339,9 +1323,9 @@@ qla2x00_lip_reset(scsi_qla_host_t *ha
  
        if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
                mcp->mb[0] = MBC_LIP_FULL_LOGIN;
-               mcp->mb[1] = BIT_0;
-               mcp->mb[2] = 0xff;
-               mcp->mb[3] = 0;
+               mcp->mb[1] = BIT_6;
+               mcp->mb[2] = 0;
+               mcp->mb[3] = ha->loop_reset_delay;
                mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
        } else {
                mcp->mb[0] = MBC_LIP_RESET;
@@@ -1697,7 -1713,7 +1697,7 @@@ qla24xx_fabric_logout(scsi_qla_host_t *
        lg->entry_count = 1;
        lg->nport_handle = cpu_to_le16(loop_id);
        lg->control_flags =
 -          __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_EXPL_LOGO);
 +          __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
        lg->port_id[0] = al_pa;
        lg->port_id[1] = area;
        lg->port_id[2] = domain;
@@@ -1807,8 -1823,8 +1807,8 @@@ qla2x00_full_login_lip(scsi_qla_host_t 
            ha->host_no));
  
        mcp->mb[0] = MBC_LIP_FULL_LOGIN;
-       mcp->mb[1] = 0;
-       mcp->mb[2] = 0xff;
+       mcp->mb[1] = IS_QLA24XX(ha) || IS_QLA54XX(ha) ? BIT_3: 0;
+       mcp->mb[2] = 0;
        mcp->mb[3] = 0;
        mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
        mcp->in_mb = MBX_0;
@@@ -2470,7 -2486,7 +2470,7 @@@ qla2x00_trace_control(scsi_qla_host_t *
                mcp->mb[4] = LSW(MSD(eft_dma));
                mcp->mb[5] = MSW(MSD(eft_dma));
                mcp->mb[6] = buffers;
-               mcp->mb[7] = buffers;
+               mcp->mb[7] = 0;
                mcp->out_mb |= MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2;
        }
        mcp->tov = 30;
index 6f161d3f661b3a332156d8350316fe7d622d4b59,d6445ae841ba965896c8993fce3ab38ae899f0e4..68f5d24b938b06c28ecf177c6ad6ae71a55a257a
@@@ -1037,48 -1037,49 +1037,49 @@@ eh_host_reset_lock
  static int
  qla2x00_loop_reset(scsi_qla_host_t *ha)
  {
-       int status = QLA_SUCCESS;
+       int ret;
        struct fc_port *fcport;
  
+       if (ha->flags.enable_lip_full_login) {
+               ret = qla2x00_full_login_lip(ha);
+               if (ret != QLA_SUCCESS) {
+                       DEBUG2_3(printk("%s(%ld): bus_reset failed: "
+                           "full_login_lip=%d.\n", __func__, ha->host_no,
+                           ret));
+               }
+               atomic_set(&ha->loop_state, LOOP_DOWN);
+               atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
+               qla2x00_mark_all_devices_lost(ha, 0);
+               qla2x00_wait_for_loop_ready(ha);
+       }
        if (ha->flags.enable_lip_reset) {
-               status = qla2x00_lip_reset(ha);
+               ret = qla2x00_lip_reset(ha);
+               if (ret != QLA_SUCCESS) {
+                       DEBUG2_3(printk("%s(%ld): bus_reset failed: "
+                           "lip_reset=%d.\n", __func__, ha->host_no, ret));
+               }
+               qla2x00_wait_for_loop_ready(ha);
        }
  
-       if (status == QLA_SUCCESS && ha->flags.enable_target_reset) {
+       if (ha->flags.enable_target_reset) {
                list_for_each_entry(fcport, &ha->fcports, list) {
                        if (fcport->port_type != FCT_TARGET)
                                continue;
  
-                       status = qla2x00_device_reset(ha, fcport);
-                       if (status != QLA_SUCCESS)
-                               break;
+                       ret = qla2x00_device_reset(ha, fcport);
+                       if (ret != QLA_SUCCESS) {
+                               DEBUG2_3(printk("%s(%ld): bus_reset failed: "
+                                   "target_reset=%d d_id=%x.\n", __func__,
+                                   ha->host_no, ret, fcport->d_id.b24));
+                       }
                }
        }
  
-       if (status == QLA_SUCCESS &&
-               ((!ha->flags.enable_target_reset &&
-                 !ha->flags.enable_lip_reset) ||
-               ha->flags.enable_lip_full_login)) {
-               status = qla2x00_full_login_lip(ha);
-       }
        /* Issue marker command only when we are going to start the I/O */
        ha->marker_needed = 1;
  
-       if (status) {
-               /* Empty */
-               DEBUG2_3(printk("%s(%ld): **** FAILED ****\n",
-                               __func__,
-                               ha->host_no));
-       } else {
-               /* Empty */
-               DEBUG3(printk("%s(%ld): exiting normally.\n",
-                               __func__,
-                               ha->host_no));
-       }
-       return(status);
+       return QLA_SUCCESS;
  }
  
  /*
@@@ -1413,7 -1414,9 +1414,9 @@@ qla2x00_probe_one(struct pci_dev *pdev
  
        sht = &qla2x00_driver_template;
        if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
-           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 ||
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432)
                sht = &qla24xx_driver_template;
        host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
        if (host == NULL) {
        ha->isp_ops.fw_dump             = qla2100_fw_dump;
        ha->isp_ops.read_optrom         = qla2x00_read_optrom_data;
        ha->isp_ops.write_optrom        = qla2x00_write_optrom_data;
 +      ha->isp_ops.get_flash_version   = qla2x00_get_flash_version;
        if (IS_QLA2100(ha)) {
                host->max_id = MAX_TARGETS_2100;
                ha->mbx_count = MAILBOX_REGISTER_COUNT_2100;
                ha->isp_ops.beacon_on = qla24xx_beacon_on;
                ha->isp_ops.beacon_off = qla24xx_beacon_off;
                ha->isp_ops.beacon_blink = qla24xx_beacon_blink;
 +              ha->isp_ops.get_flash_version = qla24xx_get_flash_version;
                ha->gid_list_info_size = 8;
                ha->optrom_size = OPTROM_SIZE_24XX;
        }
        INIT_LIST_HEAD(&ha->list);
        INIT_LIST_HEAD(&ha->fcports);
  
 -      /*
 -       * These locks are used to prevent more than one CPU
 -       * from modifying the queue at the same time. The
 -       * higher level "host_lock" will reduce most
 -       * contention for these locks.
 -       */
 -      spin_lock_init(&ha->mbx_reg_lock);
 -
        qla2x00_config_dma_addressing(ha);
        if (qla2x00_mem_alloc(ha)) {
                qla_printk(KERN_WARNING, ha,
        host->max_lun = MAX_LUNS;
        host->transportt = qla2xxx_transport_template;
  
 -      ret = request_irq(pdev->irq, ha->isp_ops.intr_handler,
 -          IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha);
 -      if (ret) {
 -              qla_printk(KERN_WARNING, ha,
 -                  "Failed to reserve interrupt %d already in use.\n",
 -                  pdev->irq);
 +      ret = qla2x00_request_irqs(ha);
 +      if (ret)
                goto probe_failed;
 -      }
 -      host->irq = pdev->irq;
  
        /* Initialized the timer */
        qla2x00_start_timer(ha, qla2x00_timer, WATCH_INTERVAL);
@@@ -1738,7 -1753,9 +1741,7 @@@ qla2x00_free_device(scsi_qla_host_t *ha
  
        qla2x00_mem_free(ha);
  
 -      /* Detach interrupts */
 -      if (ha->host->irq)
 -              free_irq(ha->host->irq, ha);
 +      qla2x00_free_irqs(ha);
  
        /* release io space registers  */
        if (ha->iobase)
diff --combined drivers/scsi/scsi_scan.c
index b8f0cab5781388823d2cc841188f1f88aeab0911,b83d03c4deef1934e051358082805b93627aa4e0..8160c00d1092b1bc77d9b4cbf0c497afc60dee08
@@@ -133,12 -133,10 +133,10 @@@ struct async_scan_data 
  /**
   * scsi_complete_async_scans - Wait for asynchronous scans to complete
   *
-  * Asynchronous scans add themselves to the scanning_hosts list.  Once
-  * that list is empty, we know that the scans are complete.  Rather than
-  * waking up periodically to check the state of the list, we pretend to be
-  * a scanning task by adding ourselves at the end of the list and going to
-  * sleep.  When the task before us wakes us up, we take ourselves off the
-  * list and return.
+  * When this function returns, any host which started scanning before
+  * this function was called will have finished its scan.  Hosts which
+  * started scanning after this function was called may or may not have
+  * finished.
   */
  int scsi_complete_async_scans(void)
  {
  
        spin_lock(&async_scan_lock);
        list_del(&data->list);
+       if (!list_empty(&scanning_hosts)) {
+               struct async_scan_data *next = list_entry(scanning_hosts.next,
+                               struct async_scan_data, list);
+               complete(&next->prev_finished);
+       }
   done:
        spin_unlock(&async_scan_lock);
  
@@@ -739,6 -742,14 +742,14 @@@ static int scsi_add_lun(struct scsi_dev
                sdev->no_uld_attach = 1;
  
        switch (sdev->type = (inq_result[0] & 0x1f)) {
+       case TYPE_RBC:
+               /* RBC devices can return SCSI-3 compliance and yet
+                * still not support REPORT LUNS, so make them act as
+                * BLIST_NOREPORTLUN unless BLIST_REPORTLUN2 is
+                * specifically set */
+               if ((*bflags & BLIST_REPORTLUN2) == 0)
+                       *bflags |= BLIST_NOREPORTLUN;
+               /* fall through */
        case TYPE_TAPE:
        case TYPE_DISK:
        case TYPE_PRINTER:
        case TYPE_ENCLOSURE:
        case TYPE_COMM:
        case TYPE_RAID:
-       case TYPE_RBC:
                sdev->writeable = 1;
                break;
-       case TYPE_WORM:
        case TYPE_ROM:
+               /* MMC devices can return SCSI-3 compliance and yet
+                * still not support REPORT LUNS, so make them act as
+                * BLIST_NOREPORTLUN unless BLIST_REPORTLUN2 is
+                * specifically set */
+               if ((*bflags & BLIST_REPORTLUN2) == 0)
+                       *bflags |= BLIST_NOREPORTLUN;
+               /* fall through */
+       case TYPE_WORM:
                sdev->writeable = 0;
                break;
        default:
@@@ -1012,7 -1029,7 +1029,7 @@@ static int scsi_probe_and_add_lun(struc
  
                                sdev_printk(KERN_INFO, sdev,
                                        "scsi scan: consider passing scsi_mod."
 -                                      "dev_flags=%s:%s:0x240 or 0x800240\n",
 +                                      "dev_flags=%s:%s:0x240 or 0x1000240\n",
                                        scsi_inq_str(vend, result, 8, 16),
                                        scsi_inq_str(mod, result, 16, 32));
                        });