]> err.no Git - linux-2.6/blobdiff - drivers/scsi/ipr.c
[SCSI] ipr: Fix for oops following SATA request sense
[linux-2.6] / drivers / scsi / ipr.c
index 6bd64d4edcdc77081874f7aad084e6a809ce5df6..fc1171c7def40aafc1cb5bd3c1499bb6a52318b2 100644 (file)
@@ -3846,6 +3846,8 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
                if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
                        if (ipr_cmd->scsi_cmd)
                                ipr_cmd->done = ipr_scsi_eh_done;
+                       if (ipr_cmd->qc)
+                               ipr_cmd->done = ipr_sata_eh_done;
                        if (ipr_cmd->qc && !(ipr_cmd->qc->flags & ATA_QCFLAG_FAILED)) {
                                ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT;
                                ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED;
@@ -4453,12 +4455,13 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg,
 {
        int i;
        u16 data_len;
-       u32 ioasc;
+       u32 ioasc, fd_ioasc;
        struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
        __be32 *ioasa_data = (__be32 *)ioasa;
        int error_index;
 
        ioasc = be32_to_cpu(ioasa->ioasc) & IPR_IOASC_IOASC_MASK;
+       fd_ioasc = be32_to_cpu(ioasa->fd_ioasc) & IPR_IOASC_IOASC_MASK;
 
        if (0 == ioasc)
                return;
@@ -4466,13 +4469,19 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg,
        if (ioa_cfg->log_level < IPR_DEFAULT_LOG_LEVEL)
                return;
 
-       error_index = ipr_get_error(ioasc);
+       if (ioasc == IPR_IOASC_BUS_WAS_RESET && fd_ioasc)
+               error_index = ipr_get_error(fd_ioasc);
+       else
+               error_index = ipr_get_error(ioasc);
 
        if (ioa_cfg->log_level < IPR_MAX_LOG_LEVEL) {
                /* Don't log an error if the IOA already logged one */
                if (ioasa->ilid != 0)
                        return;
 
+               if (!ipr_is_gscsi(res))
+                       return;
+
                if (ipr_error_table[error_index].log_ioasa == 0)
                        return;
        }
@@ -4632,11 +4641,11 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
                return;
        }
 
-       if (ipr_is_gscsi(res))
-               ipr_dump_ioasa(ioa_cfg, ipr_cmd, res);
-       else
+       if (!ipr_is_gscsi(res))
                ipr_gen_sense(ipr_cmd);
 
+       ipr_dump_ioasa(ioa_cfg, ipr_cmd, res);
+
        switch (ioasc & IPR_IOASC_IOASC_MASK) {
        case IPR_IOASC_ABORTED_CMD_TERM_BY_HOST:
                if (ipr_is_naca_model(res))
@@ -7557,6 +7566,13 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
        { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN,
              PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0,
              IPR_USE_LONG_TRANSOP_TIMEOUT },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
+             PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0, 0 },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
+             PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0,
+             IPR_USE_LONG_TRANSOP_TIMEOUT },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
+             PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 },
        { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
              PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0,
              IPR_USE_LONG_TRANSOP_TIMEOUT },
@@ -7570,6 +7586,9 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
        { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP,
                PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0,
                IPR_USE_LONG_TRANSOP_TIMEOUT },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SCAMP_E,
+               PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0,
+               IPR_USE_LONG_TRANSOP_TIMEOUT },
        { }
 };
 MODULE_DEVICE_TABLE(pci, ipr_pci_table);