aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_scsih.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c252
1 files changed, 110 insertions, 142 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 2e9a4445596f..774b34525bba 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
@@ -1502,7 +1501,13 @@ _scsih_slave_configure(struct scsi_device *sdev)
1502 break; 1501 break;
1503 case MPI2_RAID_VOL_TYPE_RAID1E: 1502 case MPI2_RAID_VOL_TYPE_RAID1E:
1504 qdepth = MPT2SAS_RAID_QUEUE_DEPTH; 1503 qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
1505 r_level = "RAID1E"; 1504 if (ioc->manu_pg10.OEMIdentifier &&
1505 (ioc->manu_pg10.GenericFlags0 &
1506 MFG10_GF0_R10_DISPLAY) &&
1507 !(raid_device->num_pds % 2))
1508 r_level = "RAID10";
1509 else
1510 r_level = "RAID1E";
1506 break; 1511 break;
1507 case MPI2_RAID_VOL_TYPE_RAID1: 1512 case MPI2_RAID_VOL_TYPE_RAID1:
1508 qdepth = MPT2SAS_RAID_QUEUE_DEPTH; 1513 qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
@@ -1786,17 +1791,18 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1786 u32 ioc_state; 1791 u32 ioc_state;
1787 unsigned long timeleft; 1792 unsigned long timeleft;
1788 u8 VF_ID = 0; 1793 u8 VF_ID = 0;
1789 unsigned long flags;
1790 1794
1791 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 1795 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) {
1792 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED || 1796 printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n",
1793 ioc->shost_recovery) { 1797 __func__, ioc->name);
1794 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 1798 return;
1799 }
1800
1801 if (ioc->shost_recovery) {
1795 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 1802 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1796 __func__, ioc->name); 1803 __func__, ioc->name);
1797 return; 1804 return;
1798 } 1805 }
1799 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
1800 1806
1801 ioc_state = mpt2sas_base_get_iocstate(ioc, 0); 1807 ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
1802 if (ioc_state & MPI2_DOORBELL_USED) { 1808 if (ioc_state & MPI2_DOORBELL_USED) {
@@ -1830,6 +1836,7 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1830 mpi_request->TaskMID = cpu_to_le16(smid_task); 1836 mpi_request->TaskMID = cpu_to_le16(smid_task);
1831 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN); 1837 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
1832 mpt2sas_scsih_set_tm_flag(ioc, handle); 1838 mpt2sas_scsih_set_tm_flag(ioc, handle);
1839 init_completion(&ioc->tm_cmds.done);
1833 mpt2sas_base_put_smid_hi_priority(ioc, smid, VF_ID); 1840 mpt2sas_base_put_smid_hi_priority(ioc, smid, VF_ID);
1834 timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ); 1841 timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
1835 mpt2sas_scsih_clear_tm_flag(ioc, handle); 1842 mpt2sas_scsih_clear_tm_flag(ioc, handle);
@@ -2222,7 +2229,7 @@ _scsih_ublock_io_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2222 MPT2SAS_INFO_FMT "SDEV_RUNNING: " 2229 MPT2SAS_INFO_FMT "SDEV_RUNNING: "
2223 "handle(0x%04x)\n", ioc->name, handle)); 2230 "handle(0x%04x)\n", ioc->name, handle));
2224 sas_device_priv_data->block = 0; 2231 sas_device_priv_data->block = 0;
2225 scsi_device_set_state(sdev, SDEV_RUNNING); 2232 scsi_internal_device_unblock(sdev);
2226 } 2233 }
2227 } 2234 }
2228} 2235}
@@ -2251,7 +2258,7 @@ _scsih_block_io_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2251 MPT2SAS_INFO_FMT "SDEV_BLOCK: " 2258 MPT2SAS_INFO_FMT "SDEV_BLOCK: "
2252 "handle(0x%04x)\n", ioc->name, handle)); 2259 "handle(0x%04x)\n", ioc->name, handle));
2253 sas_device_priv_data->block = 1; 2260 sas_device_priv_data->block = 1;
2254 scsi_device_set_state(sdev, SDEV_BLOCK); 2261 scsi_internal_device_block(sdev);
2255 } 2262 }
2256 } 2263 }
2257} 2264}
@@ -2327,6 +2334,7 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
2327 u16 handle; 2334 u16 handle;
2328 u16 reason_code; 2335 u16 reason_code;
2329 u8 phy_number; 2336 u8 phy_number;
2337 u8 link_rate;
2330 2338
2331 for (i = 0; i < event_data->NumEntries; i++) { 2339 for (i = 0; i < event_data->NumEntries; i++) {
2332 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); 2340 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
@@ -2337,6 +2345,11 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
2337 MPI2_EVENT_SAS_TOPO_RC_MASK; 2345 MPI2_EVENT_SAS_TOPO_RC_MASK;
2338 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING) 2346 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING)
2339 _scsih_block_io_device(ioc, handle); 2347 _scsih_block_io_device(ioc, handle);
2348 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED) {
2349 link_rate = event_data->PHY[i].LinkRate >> 4;
2350 if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
2351 _scsih_ublock_io_device(ioc, handle);
2352 }
2340 } 2353 }
2341} 2354}
2342 2355
@@ -2405,27 +2418,6 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
2405} 2418}
2406 2419
2407/** 2420/**
2408 * _scsih_queue_rescan - queue a topology rescan from user context
2409 * @ioc: per adapter object
2410 *
2411 * Return nothing.
2412 */
2413static 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. 2421 * _scsih_flush_running_cmds - completing outstanding commands.
2430 * @ioc: per adapter object 2422 * @ioc: per adapter object
2431 * 2423 *
@@ -2456,46 +2448,6 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc)
2456} 2448}
2457 2449
2458/** 2450/**
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 */
2470void
2471mpt2sas_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 2451 * _scsih_setup_eedp - setup MPI request for EEDP transfer
2500 * @scmd: pointer to scsi command object 2452 * @scmd: pointer to scsi command object
2501 * @mpi_request: pointer to the SCSI_IO reqest message frame 2453 * @mpi_request: pointer to the SCSI_IO reqest message frame
@@ -2615,7 +2567,6 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2615 Mpi2SCSIIORequest_t *mpi_request; 2567 Mpi2SCSIIORequest_t *mpi_request;
2616 u32 mpi_control; 2568 u32 mpi_control;
2617 u16 smid; 2569 u16 smid;
2618 unsigned long flags;
2619 2570
2620 scmd->scsi_done = done; 2571 scmd->scsi_done = done;
2621 sas_device_priv_data = scmd->device->hostdata; 2572 sas_device_priv_data = scmd->device->hostdata;
@@ -2634,13 +2585,10 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2634 } 2585 }
2635 2586
2636 /* see if we are busy with task managment stuff */ 2587 /* see if we are busy with task managment stuff */
2637 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 2588 if (sas_target_priv_data->tm_busy)
2638 if (sas_target_priv_data->tm_busy || 2589 return SCSI_MLQUEUE_DEVICE_BUSY;
2639 ioc->shost_recovery || ioc->ioc_link_reset_in_progress) { 2590 else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
2640 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
2641 return SCSI_MLQUEUE_HOST_BUSY; 2591 return SCSI_MLQUEUE_HOST_BUSY;
2642 }
2643 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
2644 2592
2645 if (scmd->sc_data_direction == DMA_FROM_DEVICE) 2593 if (scmd->sc_data_direction == DMA_FROM_DEVICE)
2646 mpi_control = MPI2_SCSIIO_CONTROL_READ; 2594 mpi_control = MPI2_SCSIIO_CONTROL_READ;
@@ -3189,25 +3137,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
3189} 3137}
3190 3138
3191/** 3139/**
3192 * _scsih_link_change - process phy link changes
3193 * @ioc: per adapter object
3194 * @handle: phy handle
3195 * @attached_handle: valid for devices attached to link
3196 * @phy_number: phy number
3197 * @link_rate: new link rate
3198 * Context: user.
3199 *
3200 * Return nothing.
3201 */
3202static void
3203_scsih_link_change(struct MPT2SAS_ADAPTER *ioc, u16 handle, u16 attached_handle,
3204 u8 phy_number, u8 link_rate)
3205{
3206 mpt2sas_transport_update_phy_link_change(ioc, handle, attached_handle,
3207 phy_number, link_rate);
3208}
3209
3210/**
3211 * _scsih_sas_host_refresh - refreshing sas host object contents 3140 * _scsih_sas_host_refresh - refreshing sas host object contents
3212 * @ioc: per adapter object 3141 * @ioc: per adapter object
3213 * @update: update link information 3142 * @update: update link information
@@ -3251,7 +3180,8 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update)
3251 le16_to_cpu(sas_iounit_pg0->PhyData[i]. 3180 le16_to_cpu(sas_iounit_pg0->PhyData[i].
3252 ControllerDevHandle); 3181 ControllerDevHandle);
3253 if (update) 3182 if (update)
3254 _scsih_link_change(ioc, 3183 mpt2sas_transport_update_links(
3184 ioc,
3255 ioc->sas_hba.phy[i].handle, 3185 ioc->sas_hba.phy[i].handle,
3256 le16_to_cpu(sas_iounit_pg0->PhyData[i]. 3186 le16_to_cpu(sas_iounit_pg0->PhyData[i].
3257 AttachedDevHandle), i, 3187 AttachedDevHandle), i,
@@ -3436,6 +3366,9 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3436 if (!handle) 3366 if (!handle)
3437 return -1; 3367 return -1;
3438 3368
3369 if (ioc->shost_recovery)
3370 return -1;
3371
3439 if ((mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, 3372 if ((mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
3440 MPI2_SAS_EXPAND_PGAD_FORM_HNDL, handle))) { 3373 MPI2_SAS_EXPAND_PGAD_FORM_HNDL, handle))) {
3441 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 3374 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
@@ -3572,6 +3505,9 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3572 struct _sas_node *sas_expander; 3505 struct _sas_node *sas_expander;
3573 unsigned long flags; 3506 unsigned long flags;
3574 3507
3508 if (ioc->shost_recovery)
3509 return;
3510
3575 spin_lock_irqsave(&ioc->sas_node_lock, flags); 3511 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3576 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle); 3512 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle);
3577 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 3513 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
@@ -3743,6 +3679,8 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3743 mutex_unlock(&ioc->tm_cmds.mutex); 3679 mutex_unlock(&ioc->tm_cmds.mutex);
3744 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset " 3680 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset "
3745 "done: handle(0x%04x)\n", ioc->name, device_handle)); 3681 "done: handle(0x%04x)\n", ioc->name, device_handle));
3682 if (ioc->shost_recovery)
3683 goto out;
3746 } 3684 }
3747 3685
3748 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */ 3686 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */
@@ -3765,6 +3703,9 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3765 le32_to_cpu(mpi_reply.IOCLogInfo))); 3703 le32_to_cpu(mpi_reply.IOCLogInfo)));
3766 3704
3767 out: 3705 out:
3706
3707 _scsih_ublock_io_device(ioc, handle);
3708
3768 mpt2sas_transport_port_remove(ioc, sas_device->sas_address, 3709 mpt2sas_transport_port_remove(ioc, sas_device->sas_address,
3769 sas_device->parent_handle); 3710 sas_device->parent_handle);
3770 3711
@@ -3908,6 +3849,8 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3908 "expander event\n", ioc->name)); 3849 "expander event\n", ioc->name));
3909 return; 3850 return;
3910 } 3851 }
3852 if (ioc->shost_recovery)
3853 return;
3911 if (event_data->PHY[i].PhyStatus & 3854 if (event_data->PHY[i].PhyStatus &
3912 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) 3855 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT)
3913 continue; 3856 continue;
@@ -3923,9 +3866,10 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3923 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 3866 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
3924 if (!parent_handle) { 3867 if (!parent_handle) {
3925 if (phy_number < ioc->sas_hba.num_phys) 3868 if (phy_number < ioc->sas_hba.num_phys)
3926 _scsih_link_change(ioc, 3869 mpt2sas_transport_update_links(
3927 ioc->sas_hba.phy[phy_number].handle, 3870 ioc,
3928 handle, phy_number, link_rate_); 3871 ioc->sas_hba.phy[phy_number].handle,
3872 handle, phy_number, link_rate_);
3929 } else { 3873 } else {
3930 spin_lock_irqsave(&ioc->sas_node_lock, flags); 3874 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3931 sas_expander = 3875 sas_expander =
@@ -3935,17 +3879,14 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3935 flags); 3879 flags);
3936 if (sas_expander) { 3880 if (sas_expander) {
3937 if (phy_number < sas_expander->num_phys) 3881 if (phy_number < sas_expander->num_phys)
3938 _scsih_link_change(ioc, 3882 mpt2sas_transport_update_links(
3939 sas_expander-> 3883 ioc,
3940 phy[phy_number].handle, 3884 sas_expander->
3941 handle, phy_number, 3885 phy[phy_number].handle,
3942 link_rate_); 3886 handle, phy_number,
3887 link_rate_);
3943 } 3888 }
3944 } 3889 }
3945 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED) {
3946 if (link_rate_ >= MPI2_SAS_NEG_LINK_RATE_1_5)
3947 _scsih_ublock_io_device(ioc, handle);
3948 }
3949 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED) { 3890 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED) {
3950 if (link_rate_ < MPI2_SAS_NEG_LINK_RATE_1_5) 3891 if (link_rate_ < MPI2_SAS_NEG_LINK_RATE_1_5)
3951 break; 3892 break;
@@ -4455,7 +4396,7 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
4455 return; 4396 return;
4456 } 4397 }
4457 4398
4458 _scsih_link_change(ioc, 4399 mpt2sas_transport_update_links(ioc,
4459 le16_to_cpu(sas_device_pg0.ParentDevHandle), 4400 le16_to_cpu(sas_device_pg0.ParentDevHandle),
4460 handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); 4401 handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
4461 4402
@@ -4744,7 +4685,7 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4744 return; 4685 return;
4745 } 4686 }
4746 4687
4747 _scsih_link_change(ioc, 4688 mpt2sas_transport_update_links(ioc,
4748 le16_to_cpu(sas_device_pg0.ParentDevHandle), 4689 le16_to_cpu(sas_device_pg0.ParentDevHandle),
4749 handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); 4690 handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
4750 4691
@@ -5156,22 +5097,9 @@ static void
5156_scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc) 5097_scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
5157{ 5098{
5158 struct _sas_device *sas_device, *sas_device_next; 5099 struct _sas_device *sas_device, *sas_device_next;
5159 struct _sas_node *sas_expander, *sas_expander_next; 5100 struct _sas_node *sas_expander;
5160 struct _raid_device *raid_device, *raid_device_next; 5101 struct _raid_device *raid_device, *raid_device_next;
5161 unsigned long flags;
5162 5102
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 5103
5176 list_for_each_entry_safe(sas_device, sas_device_next, 5104 list_for_each_entry_safe(sas_device, sas_device_next,
5177 &ioc->sas_device_list, list) { 5105 &ioc->sas_device_list, list) {
@@ -5207,16 +5135,63 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
5207 _scsih_raid_device_remove(ioc, raid_device); 5135 _scsih_raid_device_remove(ioc, raid_device);
5208 } 5136 }
5209 5137
5210 list_for_each_entry_safe(sas_expander, sas_expander_next, 5138 retry_expander_search:
5211 &ioc->sas_expander_list, list) { 5139 sas_expander = NULL;
5140 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
5212 if (sas_expander->responding) { 5141 if (sas_expander->responding) {
5213 sas_expander->responding = 0; 5142 sas_expander->responding = 0;
5214 continue; 5143 continue;
5215 } 5144 }
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); 5145 _scsih_expander_remove(ioc, sas_expander->handle);
5146 goto retry_expander_search;
5147 }
5148}
5149
5150/**
5151 * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
5152 * @ioc: per adapter object
5153 * @reset_phase: phase
5154 *
5155 * The handler for doing any required cleanup or initialization.
5156 *
5157 * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET,
5158 * MPT2_IOC_DONE_RESET
5159 *
5160 * Return nothing.
5161 */
5162void
5163mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
5164{
5165 switch (reset_phase) {
5166 case MPT2_IOC_PRE_RESET:
5167 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5168 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
5169 _scsih_fw_event_off(ioc);
5170 break;
5171 case MPT2_IOC_AFTER_RESET:
5172 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5173 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
5174 if (ioc->tm_cmds.status & MPT2_CMD_PENDING) {
5175 ioc->tm_cmds.status |= MPT2_CMD_RESET;
5176 mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid);
5177 complete(&ioc->tm_cmds.done);
5178 }
5179 _scsih_fw_event_on(ioc);
5180 _scsih_flush_running_cmds(ioc);
5181 break;
5182 case MPT2_IOC_DONE_RESET:
5183 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5184 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
5185 _scsih_sas_host_refresh(ioc, 0);
5186 _scsih_search_responding_sas_devices(ioc);
5187 _scsih_search_responding_raid_devices(ioc);
5188 _scsih_search_responding_expanders(ioc);
5189 break;
5190 case MPT2_IOC_RUNNING:
5191 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5192 "MPT2_IOC_RUNNING\n", ioc->name, __func__));
5193 _scsih_remove_unresponding_devices(ioc);
5194 break;
5220 } 5195 }
5221} 5196}
5222 5197
@@ -5236,14 +5211,6 @@ _firmware_event_work(struct work_struct *work)
5236 unsigned long flags; 5211 unsigned long flags;
5237 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc; 5212 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
5238 5213
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 */ 5214 /* the queue is being flushed so ignore this event */
5248 spin_lock_irqsave(&ioc->fw_event_lock, flags); 5215 spin_lock_irqsave(&ioc->fw_event_lock, flags);
5249 if (ioc->fw_events_off || ioc->remove_host) { 5216 if (ioc->fw_events_off || ioc->remove_host) {
@@ -5253,13 +5220,10 @@ _firmware_event_work(struct work_struct *work)
5253 } 5220 }
5254 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 5221 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5255 5222
5256 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
5257 if (ioc->shost_recovery) { 5223 if (ioc->shost_recovery) {
5258 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
5259 _scsih_fw_event_requeue(ioc, fw_event, 1000); 5224 _scsih_fw_event_requeue(ioc, fw_event, 1000);
5260 return; 5225 return;
5261 } 5226 }
5262 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
5263 5227
5264 switch (fw_event->event) { 5228 switch (fw_event->event) {
5265 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 5229 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
@@ -5461,6 +5425,8 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5461 if (!sas_device) 5425 if (!sas_device)
5462 continue; 5426 continue;
5463 _scsih_remove_device(ioc, sas_device->handle); 5427 _scsih_remove_device(ioc, sas_device->handle);
5428 if (ioc->shost_recovery)
5429 return;
5464 goto retry_device_search; 5430 goto retry_device_search;
5465 } 5431 }
5466 } 5432 }
@@ -5482,6 +5448,8 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5482 if (!expander_sibling) 5448 if (!expander_sibling)
5483 continue; 5449 continue;
5484 _scsih_expander_remove(ioc, expander_sibling->handle); 5450 _scsih_expander_remove(ioc, expander_sibling->handle);
5451 if (ioc->shost_recovery)
5452 return;
5485 goto retry_expander_search; 5453 goto retry_expander_search;
5486 } 5454 }
5487 } 5455 }