diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 3 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 1 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 142 |
3 files changed, 57 insertions, 89 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 35a13867495e..cc5a8dae4ae1 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -3536,5 +3536,8 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
3536 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | 3536 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); |
3537 | ioc->ioc_reset_in_progress = 0; | 3537 | ioc->ioc_reset_in_progress = 0; |
3538 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | 3538 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); |
3539 | |||
3540 | if (!r) | ||
3541 | _base_reset_handler(ioc, MPT2_IOC_RUNNING); | ||
3539 | return r; | 3542 | return r; |
3540 | } | 3543 | } |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index acdcff150a35..998a7b847b3d 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
@@ -119,6 +119,7 @@ | |||
119 | #define MPT2_IOC_PRE_RESET 1 /* prior to host reset */ | 119 | #define MPT2_IOC_PRE_RESET 1 /* prior to host reset */ |
120 | #define MPT2_IOC_AFTER_RESET 2 /* just after host reset */ | 120 | #define MPT2_IOC_AFTER_RESET 2 /* just after host reset */ |
121 | #define MPT2_IOC_DONE_RESET 3 /* links re-initialized */ | 121 | #define MPT2_IOC_DONE_RESET 3 /* links re-initialized */ |
122 | #define MPT2_IOC_RUNNING 4 /* shost running */ | ||
122 | 123 | ||
123 | /* | 124 | /* |
124 | * logging format | 125 | * logging format |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 2e9a4445596f..471c3b604596 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -103,7 +103,6 @@ struct sense_info { | |||
103 | }; | 103 | }; |
104 | 104 | ||
105 | 105 | ||
106 | #define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF) | ||
107 | /** | 106 | /** |
108 | * struct fw_event_work - firmware event struct | 107 | * struct fw_event_work - firmware event struct |
109 | * @list: link list framework | 108 | * @list: link list framework |
@@ -2405,27 +2404,6 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc, | |||
2405 | } | 2404 | } |
2406 | 2405 | ||
2407 | /** | 2406 | /** |
2408 | * _scsih_queue_rescan - queue a topology rescan from user context | ||
2409 | * @ioc: per adapter object | ||
2410 | * | ||
2411 | * Return nothing. | ||
2412 | */ | ||
2413 | static void | ||
2414 | _scsih_queue_rescan(struct MPT2SAS_ADAPTER *ioc) | ||
2415 | { | ||
2416 | struct fw_event_work *fw_event; | ||
2417 | |||
2418 | if (ioc->wait_for_port_enable_to_complete) | ||
2419 | return; | ||
2420 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); | ||
2421 | if (!fw_event) | ||
2422 | return; | ||
2423 | fw_event->event = MPT2SAS_RESCAN_AFTER_HOST_RESET; | ||
2424 | fw_event->ioc = ioc; | ||
2425 | _scsih_fw_event_add(ioc, fw_event); | ||
2426 | } | ||
2427 | |||
2428 | /** | ||
2429 | * _scsih_flush_running_cmds - completing outstanding commands. | 2407 | * _scsih_flush_running_cmds - completing outstanding commands. |
2430 | * @ioc: per adapter object | 2408 | * @ioc: per adapter object |
2431 | * | 2409 | * |
@@ -2456,46 +2434,6 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc) | |||
2456 | } | 2434 | } |
2457 | 2435 | ||
2458 | /** | 2436 | /** |
2459 | * mpt2sas_scsih_reset_handler - reset callback handler (for scsih) | ||
2460 | * @ioc: per adapter object | ||
2461 | * @reset_phase: phase | ||
2462 | * | ||
2463 | * The handler for doing any required cleanup or initialization. | ||
2464 | * | ||
2465 | * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET, | ||
2466 | * MPT2_IOC_DONE_RESET | ||
2467 | * | ||
2468 | * Return nothing. | ||
2469 | */ | ||
2470 | void | ||
2471 | mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | ||
2472 | { | ||
2473 | switch (reset_phase) { | ||
2474 | case MPT2_IOC_PRE_RESET: | ||
2475 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | ||
2476 | "MPT2_IOC_PRE_RESET\n", ioc->name, __func__)); | ||
2477 | _scsih_fw_event_off(ioc); | ||
2478 | break; | ||
2479 | case MPT2_IOC_AFTER_RESET: | ||
2480 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | ||
2481 | "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__)); | ||
2482 | if (ioc->tm_cmds.status & MPT2_CMD_PENDING) { | ||
2483 | ioc->tm_cmds.status |= MPT2_CMD_RESET; | ||
2484 | mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid); | ||
2485 | complete(&ioc->tm_cmds.done); | ||
2486 | } | ||
2487 | _scsih_fw_event_on(ioc); | ||
2488 | _scsih_flush_running_cmds(ioc); | ||
2489 | break; | ||
2490 | case MPT2_IOC_DONE_RESET: | ||
2491 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | ||
2492 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); | ||
2493 | _scsih_queue_rescan(ioc); | ||
2494 | break; | ||
2495 | } | ||
2496 | } | ||
2497 | |||
2498 | /** | ||
2499 | * _scsih_setup_eedp - setup MPI request for EEDP transfer | 2437 | * _scsih_setup_eedp - setup MPI request for EEDP transfer |
2500 | * @scmd: pointer to scsi command object | 2438 | * @scmd: pointer to scsi command object |
2501 | * @mpi_request: pointer to the SCSI_IO reqest message frame | 2439 | * @mpi_request: pointer to the SCSI_IO reqest message frame |
@@ -5156,22 +5094,9 @@ static void | |||
5156 | _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc) | 5094 | _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc) |
5157 | { | 5095 | { |
5158 | struct _sas_device *sas_device, *sas_device_next; | 5096 | struct _sas_device *sas_device, *sas_device_next; |
5159 | struct _sas_node *sas_expander, *sas_expander_next; | 5097 | struct _sas_node *sas_expander; |
5160 | struct _raid_device *raid_device, *raid_device_next; | 5098 | struct _raid_device *raid_device, *raid_device_next; |
5161 | unsigned long flags; | ||
5162 | 5099 | ||
5163 | _scsih_search_responding_sas_devices(ioc); | ||
5164 | _scsih_search_responding_raid_devices(ioc); | ||
5165 | _scsih_search_responding_expanders(ioc); | ||
5166 | |||
5167 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | ||
5168 | ioc->shost_recovery = 0; | ||
5169 | if (ioc->shost->shost_state == SHOST_RECOVERY) { | ||
5170 | printk(MPT2SAS_INFO_FMT "putting controller into " | ||
5171 | "SHOST_RUNNING\n", ioc->name); | ||
5172 | scsi_host_set_state(ioc->shost, SHOST_RUNNING); | ||
5173 | } | ||
5174 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | ||
5175 | 5100 | ||
5176 | list_for_each_entry_safe(sas_device, sas_device_next, | 5101 | list_for_each_entry_safe(sas_device, sas_device_next, |
5177 | &ioc->sas_device_list, list) { | 5102 | &ioc->sas_device_list, list) { |
@@ -5207,16 +5132,63 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc) | |||
5207 | _scsih_raid_device_remove(ioc, raid_device); | 5132 | _scsih_raid_device_remove(ioc, raid_device); |
5208 | } | 5133 | } |
5209 | 5134 | ||
5210 | list_for_each_entry_safe(sas_expander, sas_expander_next, | 5135 | retry_expander_search: |
5211 | &ioc->sas_expander_list, list) { | 5136 | sas_expander = NULL; |
5137 | list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { | ||
5212 | if (sas_expander->responding) { | 5138 | if (sas_expander->responding) { |
5213 | sas_expander->responding = 0; | 5139 | sas_expander->responding = 0; |
5214 | continue; | 5140 | continue; |
5215 | } | 5141 | } |
5216 | printk("\tremoving expander: handle(0x%04x), " | ||
5217 | " sas_addr(0x%016llx)\n", sas_expander->handle, | ||
5218 | (unsigned long long)sas_expander->sas_address); | ||
5219 | _scsih_expander_remove(ioc, sas_expander->handle); | 5142 | _scsih_expander_remove(ioc, sas_expander->handle); |
5143 | goto retry_expander_search; | ||
5144 | } | ||
5145 | } | ||
5146 | |||
5147 | /** | ||
5148 | * mpt2sas_scsih_reset_handler - reset callback handler (for scsih) | ||
5149 | * @ioc: per adapter object | ||
5150 | * @reset_phase: phase | ||
5151 | * | ||
5152 | * The handler for doing any required cleanup or initialization. | ||
5153 | * | ||
5154 | * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET, | ||
5155 | * MPT2_IOC_DONE_RESET | ||
5156 | * | ||
5157 | * Return nothing. | ||
5158 | */ | ||
5159 | void | ||
5160 | mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | ||
5161 | { | ||
5162 | switch (reset_phase) { | ||
5163 | case MPT2_IOC_PRE_RESET: | ||
5164 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | ||
5165 | "MPT2_IOC_PRE_RESET\n", ioc->name, __func__)); | ||
5166 | _scsih_fw_event_off(ioc); | ||
5167 | break; | ||
5168 | case MPT2_IOC_AFTER_RESET: | ||
5169 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | ||
5170 | "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__)); | ||
5171 | if (ioc->tm_cmds.status & MPT2_CMD_PENDING) { | ||
5172 | ioc->tm_cmds.status |= MPT2_CMD_RESET; | ||
5173 | mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid); | ||
5174 | complete(&ioc->tm_cmds.done); | ||
5175 | } | ||
5176 | _scsih_fw_event_on(ioc); | ||
5177 | _scsih_flush_running_cmds(ioc); | ||
5178 | break; | ||
5179 | case MPT2_IOC_DONE_RESET: | ||
5180 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | ||
5181 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); | ||
5182 | _scsih_sas_host_refresh(ioc, 0); | ||
5183 | _scsih_search_responding_sas_devices(ioc); | ||
5184 | _scsih_search_responding_raid_devices(ioc); | ||
5185 | _scsih_search_responding_expanders(ioc); | ||
5186 | break; | ||
5187 | case MPT2_IOC_RUNNING: | ||
5188 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | ||
5189 | "MPT2_IOC_RUNNING\n", ioc->name, __func__)); | ||
5190 | _scsih_remove_unresponding_devices(ioc); | ||
5191 | break; | ||
5220 | } | 5192 | } |
5221 | } | 5193 | } |
5222 | 5194 | ||
@@ -5236,14 +5208,6 @@ _firmware_event_work(struct work_struct *work) | |||
5236 | unsigned long flags; | 5208 | unsigned long flags; |
5237 | struct MPT2SAS_ADAPTER *ioc = fw_event->ioc; | 5209 | struct MPT2SAS_ADAPTER *ioc = fw_event->ioc; |
5238 | 5210 | ||
5239 | /* This is invoked by calling _scsih_queue_rescan(). */ | ||
5240 | if (fw_event->event == MPT2SAS_RESCAN_AFTER_HOST_RESET) { | ||
5241 | _scsih_fw_event_free(ioc, fw_event); | ||
5242 | _scsih_sas_host_refresh(ioc, 1); | ||
5243 | _scsih_remove_unresponding_devices(ioc); | ||
5244 | return; | ||
5245 | } | ||
5246 | |||
5247 | /* the queue is being flushed so ignore this event */ | 5211 | /* the queue is being flushed so ignore this event */ |
5248 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 5212 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
5249 | if (ioc->fw_events_off || ioc->remove_host) { | 5213 | if (ioc->fw_events_off || ioc->remove_host) { |