]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/scsi/mpt3sas/mpt3sas_scsih.c
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[mirror_ubuntu-artful-kernel.git] / drivers / scsi / mpt3sas / mpt3sas_scsih.c
index c6d550551504fcb84addc3f92e98a7ceaeeaa820..46e866c36c8a884a98588a8d7a81272aed0ce400 100644 (file)
@@ -1074,6 +1074,26 @@ _scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, u16 smid)
        return ioc->scsi_lookup[smid - 1].scmd;
 }
 
+/**
+ * __scsih_scsi_lookup_get_clear - returns scmd entry without
+ *                                             holding any lock.
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Returns the smid stored scmd pointer.
+ * Then will dereference the stored scmd pointer.
+ */
+static inline struct scsi_cmnd *
+__scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc,
+               u16 smid)
+{
+       struct scsi_cmnd *scmd = NULL;
+
+       swap(scmd, ioc->scsi_lookup[smid - 1].scmd);
+
+       return scmd;
+}
+
 /**
  * _scsih_scsi_lookup_get_clear - returns scmd entry
  * @ioc: per adapter object
@@ -1089,8 +1109,7 @@ _scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc, u16 smid)
        struct scsi_cmnd *scmd;
 
        spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       scmd = ioc->scsi_lookup[smid - 1].scmd;
-       ioc->scsi_lookup[smid - 1].scmd = NULL;
+       scmd = __scsih_scsi_lookup_get_clear(ioc, smid);
        spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
 
        return scmd;
@@ -4661,7 +4680,13 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
        unsigned int sector_sz;
 
        mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
-       scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
+
+       if (ioc->broadcast_aen_busy || ioc->pci_error_recovery ||
+                       ioc->got_task_abort_from_ioctl)
+               scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
+       else
+               scmd = __scsih_scsi_lookup_get_clear(ioc, smid);
+
        if (scmd == NULL)
                return 1;
 
@@ -8044,15 +8069,24 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
        case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
                ActiveCableEventData =
                    (Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData;
-               if (ActiveCableEventData->ReasonCode ==
-                               MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) {
-                       pr_info(MPT3SAS_FMT "Currently an active cable with ReceptacleID %d",
-                           ioc->name, ActiveCableEventData->ReceptacleID);
-                       pr_info("cannot be powered and devices connected to this active cable");
-                       pr_info("will not be seen. This active cable");
-                       pr_info("requires %d mW of power",
-                           ActiveCableEventData->ActiveCablePowerRequirement);
+               switch (ActiveCableEventData->ReasonCode) {
+               case MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER:
+                       pr_notice(MPT3SAS_FMT "Receptacle ID %d: This active cable"
+                                 " requires %d mW of power\n", ioc->name,
+                            ActiveCableEventData->ReceptacleID,
+                            ActiveCableEventData->ActiveCablePowerRequirement);
+                       pr_notice(MPT3SAS_FMT "Receptacle ID %d: Devices connected"
+                                 " to this active cable will not be seen\n",
+                            ioc->name, ActiveCableEventData->ReceptacleID);
+                       break;
+
+               case MPI26_EVENT_ACTIVE_CABLE_DEGRADED:
+                       pr_notice(MPT3SAS_FMT "ReceptacleID %d: This cable",
+                               ioc->name, ActiveCableEventData->ReceptacleID);
+                       pr_notice(" is not running at an optimal speed(12 Gb/s)\n");
+                       break;
                }
+
                break;
 
        default: /* ignore the rest */