|
@@ -103,7 +103,6 @@ struct sense_info {
|
|
|
};
|
|
|
|
|
|
|
|
|
-#define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF)
|
|
|
/**
|
|
|
* struct fw_event_work - firmware event struct
|
|
|
* @list: link list framework
|
|
@@ -2404,27 +2403,6 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
|
|
|
spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * _scsih_queue_rescan - queue a topology rescan from user context
|
|
|
- * @ioc: per adapter object
|
|
|
- *
|
|
|
- * Return nothing.
|
|
|
- */
|
|
|
-static void
|
|
|
-_scsih_queue_rescan(struct MPT2SAS_ADAPTER *ioc)
|
|
|
-{
|
|
|
- struct fw_event_work *fw_event;
|
|
|
-
|
|
|
- if (ioc->wait_for_port_enable_to_complete)
|
|
|
- return;
|
|
|
- fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
|
|
|
- if (!fw_event)
|
|
|
- return;
|
|
|
- fw_event->event = MPT2SAS_RESCAN_AFTER_HOST_RESET;
|
|
|
- fw_event->ioc = ioc;
|
|
|
- _scsih_fw_event_add(ioc, fw_event);
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* _scsih_flush_running_cmds - completing outstanding commands.
|
|
|
* @ioc: per adapter object
|
|
@@ -2455,46 +2433,6 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc)
|
|
|
ioc->name, count));
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
|
|
|
- * @ioc: per adapter object
|
|
|
- * @reset_phase: phase
|
|
|
- *
|
|
|
- * The handler for doing any required cleanup or initialization.
|
|
|
- *
|
|
|
- * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET,
|
|
|
- * MPT2_IOC_DONE_RESET
|
|
|
- *
|
|
|
- * Return nothing.
|
|
|
- */
|
|
|
-void
|
|
|
-mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
|
|
|
-{
|
|
|
- switch (reset_phase) {
|
|
|
- case MPT2_IOC_PRE_RESET:
|
|
|
- dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
|
|
|
- "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
|
|
|
- _scsih_fw_event_off(ioc);
|
|
|
- break;
|
|
|
- case MPT2_IOC_AFTER_RESET:
|
|
|
- dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
|
|
|
- "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
|
|
|
- if (ioc->tm_cmds.status & MPT2_CMD_PENDING) {
|
|
|
- ioc->tm_cmds.status |= MPT2_CMD_RESET;
|
|
|
- mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid);
|
|
|
- complete(&ioc->tm_cmds.done);
|
|
|
- }
|
|
|
- _scsih_fw_event_on(ioc);
|
|
|
- _scsih_flush_running_cmds(ioc);
|
|
|
- break;
|
|
|
- case MPT2_IOC_DONE_RESET:
|
|
|
- dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
|
|
|
- "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
|
|
|
- _scsih_queue_rescan(ioc);
|
|
|
- break;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* _scsih_setup_eedp - setup MPI request for EEDP transfer
|
|
|
* @scmd: pointer to scsi command object
|
|
@@ -5156,22 +5094,9 @@ static void
|
|
|
_scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
|
{
|
|
|
struct _sas_device *sas_device, *sas_device_next;
|
|
|
- struct _sas_node *sas_expander, *sas_expander_next;
|
|
|
+ struct _sas_node *sas_expander;
|
|
|
struct _raid_device *raid_device, *raid_device_next;
|
|
|
- unsigned long flags;
|
|
|
|
|
|
- _scsih_search_responding_sas_devices(ioc);
|
|
|
- _scsih_search_responding_raid_devices(ioc);
|
|
|
- _scsih_search_responding_expanders(ioc);
|
|
|
-
|
|
|
- spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
|
|
|
- ioc->shost_recovery = 0;
|
|
|
- if (ioc->shost->shost_state == SHOST_RECOVERY) {
|
|
|
- printk(MPT2SAS_INFO_FMT "putting controller into "
|
|
|
- "SHOST_RUNNING\n", ioc->name);
|
|
|
- scsi_host_set_state(ioc->shost, SHOST_RUNNING);
|
|
|
- }
|
|
|
- spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
|
|
|
|
|
|
list_for_each_entry_safe(sas_device, sas_device_next,
|
|
|
&ioc->sas_device_list, list) {
|
|
@@ -5207,16 +5132,63 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
|
_scsih_raid_device_remove(ioc, raid_device);
|
|
|
}
|
|
|
|
|
|
- list_for_each_entry_safe(sas_expander, sas_expander_next,
|
|
|
- &ioc->sas_expander_list, list) {
|
|
|
+ retry_expander_search:
|
|
|
+ sas_expander = NULL;
|
|
|
+ list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
|
|
|
if (sas_expander->responding) {
|
|
|
sas_expander->responding = 0;
|
|
|
continue;
|
|
|
}
|
|
|
- printk("\tremoving expander: handle(0x%04x), "
|
|
|
- " sas_addr(0x%016llx)\n", sas_expander->handle,
|
|
|
- (unsigned long long)sas_expander->sas_address);
|
|
|
_scsih_expander_remove(ioc, sas_expander->handle);
|
|
|
+ goto retry_expander_search;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
|
|
|
+ * @ioc: per adapter object
|
|
|
+ * @reset_phase: phase
|
|
|
+ *
|
|
|
+ * The handler for doing any required cleanup or initialization.
|
|
|
+ *
|
|
|
+ * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET,
|
|
|
+ * MPT2_IOC_DONE_RESET
|
|
|
+ *
|
|
|
+ * Return nothing.
|
|
|
+ */
|
|
|
+void
|
|
|
+mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
|
|
|
+{
|
|
|
+ switch (reset_phase) {
|
|
|
+ case MPT2_IOC_PRE_RESET:
|
|
|
+ dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
|
|
|
+ "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
|
|
|
+ _scsih_fw_event_off(ioc);
|
|
|
+ break;
|
|
|
+ case MPT2_IOC_AFTER_RESET:
|
|
|
+ dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
|
|
|
+ "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
|
|
|
+ if (ioc->tm_cmds.status & MPT2_CMD_PENDING) {
|
|
|
+ ioc->tm_cmds.status |= MPT2_CMD_RESET;
|
|
|
+ mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid);
|
|
|
+ complete(&ioc->tm_cmds.done);
|
|
|
+ }
|
|
|
+ _scsih_fw_event_on(ioc);
|
|
|
+ _scsih_flush_running_cmds(ioc);
|
|
|
+ break;
|
|
|
+ case MPT2_IOC_DONE_RESET:
|
|
|
+ dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
|
|
|
+ "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
|
|
|
+ _scsih_sas_host_refresh(ioc, 0);
|
|
|
+ _scsih_search_responding_sas_devices(ioc);
|
|
|
+ _scsih_search_responding_raid_devices(ioc);
|
|
|
+ _scsih_search_responding_expanders(ioc);
|
|
|
+ break;
|
|
|
+ case MPT2_IOC_RUNNING:
|
|
|
+ dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
|
|
|
+ "MPT2_IOC_RUNNING\n", ioc->name, __func__));
|
|
|
+ _scsih_remove_unresponding_devices(ioc);
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -5236,14 +5208,6 @@ _firmware_event_work(struct work_struct *work)
|
|
|
unsigned long flags;
|
|
|
struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
|
|
|
|
|
|
- /* This is invoked by calling _scsih_queue_rescan(). */
|
|
|
- if (fw_event->event == MPT2SAS_RESCAN_AFTER_HOST_RESET) {
|
|
|
- _scsih_fw_event_free(ioc, fw_event);
|
|
|
- _scsih_sas_host_refresh(ioc, 1);
|
|
|
- _scsih_remove_unresponding_devices(ioc);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
/* the queue is being flushed so ignore this event */
|
|
|
spin_lock_irqsave(&ioc->fw_event_lock, flags);
|
|
|
if (ioc->fw_events_off || ioc->remove_host) {
|