Merge branch 'master'
[sfrench/cifs-2.6.git] / drivers / scsi / ipr.c
index fa2cb3582cfa5a2c1348d974bcfa3566e5e47d73..2bba5e55d7bc6110d44aa6720280e12d4b79cbe6 100644 (file)
@@ -2132,7 +2132,7 @@ restart:
        }
 
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-       kobject_uevent(&ioa_cfg->host->shost_classdev.kobj, KOBJ_CHANGE, NULL);
+       kobject_uevent(&ioa_cfg->host->shost_classdev.kobj, KOBJ_CHANGE);
        LEAVE;
 }
 
@@ -4235,35 +4235,6 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
                ipr_erp_start(ioa_cfg, ipr_cmd);
 }
 
-/**
- * ipr_save_ioafp_mode_select - Save adapters mode select data
- * @ioa_cfg:   ioa config struct
- * @scsi_cmd:  scsi command struct
- *
- * This function saves mode select data for the adapter to
- * use following an adapter reset.
- *
- * Return value:
- *     0 on success / SCSI_MLQUEUE_HOST_BUSY on failure
- **/
-static int ipr_save_ioafp_mode_select(struct ipr_ioa_cfg *ioa_cfg,
-                                      struct scsi_cmnd *scsi_cmd)
-{
-       if (!ioa_cfg->saved_mode_pages) {
-               ioa_cfg->saved_mode_pages  = kmalloc(sizeof(struct ipr_mode_pages),
-                                                    GFP_ATOMIC);
-               if (!ioa_cfg->saved_mode_pages) {
-                       dev_err(&ioa_cfg->pdev->dev,
-                               "IOA mode select buffer allocation failed\n");
-                       return SCSI_MLQUEUE_HOST_BUSY;
-               }
-       }
-
-       memcpy(ioa_cfg->saved_mode_pages, scsi_cmd->buffer, scsi_cmd->cmnd[4]);
-       ioa_cfg->saved_mode_page_len = scsi_cmd->cmnd[4];
-       return 0;
-}
-
 /**
  * ipr_queuecommand - Queue a mid-layer request
  * @scsi_cmd:  scsi command struct
@@ -4338,9 +4309,6 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
            (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE))
                ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
 
-       if (ipr_is_ioa_resource(res) && scsi_cmd->cmnd[0] == MODE_SELECT)
-               rc = ipr_save_ioafp_mode_select(ioa_cfg, scsi_cmd);
-
        if (likely(rc == 0))
                rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
 
@@ -4829,17 +4797,11 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd)
        int length;
 
        ENTER;
-       if (ioa_cfg->saved_mode_pages) {
-               memcpy(mode_pages, ioa_cfg->saved_mode_pages,
-                      ioa_cfg->saved_mode_page_len);
-               length = ioa_cfg->saved_mode_page_len;
-       } else {
-               ipr_scsi_bus_speed_limit(ioa_cfg);
-               ipr_check_term_power(ioa_cfg, mode_pages);
-               ipr_modify_ioafp_mode_page_28(ioa_cfg, mode_pages);
-               length = mode_pages->hdr.length + 1;
-               mode_pages->hdr.length = 0;
-       }
+       ipr_scsi_bus_speed_limit(ioa_cfg);
+       ipr_check_term_power(ioa_cfg, mode_pages);
+       ipr_modify_ioafp_mode_page_28(ioa_cfg, mode_pages);
+       length = mode_pages->hdr.length + 1;
+       mode_pages->hdr.length = 0;
 
        ipr_build_mode_select(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), 0x11,
                              ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages),
@@ -5887,7 +5849,12 @@ static int __devinit ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg)
        ENTER;
        spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
        dev_dbg(&ioa_cfg->pdev->dev, "ioa_cfg adx: 0x%p\n", ioa_cfg);
-       _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, IPR_SHUTDOWN_NONE);
+       if (ioa_cfg->needs_hard_reset) {
+               ioa_cfg->needs_hard_reset = 0;
+               ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
+       } else
+               _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa,
+                                       IPR_SHUTDOWN_NONE);
 
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
        wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
@@ -5964,7 +5931,6 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg)
        }
 
        ipr_free_dump(ioa_cfg);
-       kfree(ioa_cfg->saved_mode_pages);
        kfree(ioa_cfg->trace);
 }
 
@@ -6264,6 +6230,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
        unsigned long ipr_regs_pci;
        void __iomem *ipr_regs;
        u32 rc = PCIBIOS_SUCCESSFUL;
+       volatile u32 mask, uproc;
 
        ENTER;
 
@@ -6356,6 +6323,15 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
                goto cleanup_nomem;
        }
 
+       /*
+        * If HRRQ updated interrupt is not masked, or reset alert is set,
+        * the card is in an unknown state and needs a hard reset
+        */
+       mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+       uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg);
+       if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT))
+               ioa_cfg->needs_hard_reset = 1;
+
        ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
        rc = request_irq(pdev->irq, ipr_isr, SA_SHIRQ, IPR_NAME, ioa_cfg);