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.c634
1 files changed, 503 insertions, 131 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 1da1aa1a11e2..8889b1babcac 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -71,6 +71,9 @@ static void _firmware_event_work(struct work_struct *work);
71 71
72static u8 _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid); 72static u8 _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid);
73 73
74static void _scsih_scan_start(struct Scsi_Host *shost);
75static int _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time);
76
74/* global parameters */ 77/* global parameters */
75LIST_HEAD(mpt2sas_ioc_list); 78LIST_HEAD(mpt2sas_ioc_list);
76 79
@@ -79,6 +82,7 @@ static u8 scsi_io_cb_idx = -1;
79static u8 tm_cb_idx = -1; 82static u8 tm_cb_idx = -1;
80static u8 ctl_cb_idx = -1; 83static u8 ctl_cb_idx = -1;
81static u8 base_cb_idx = -1; 84static u8 base_cb_idx = -1;
85static u8 port_enable_cb_idx = -1;
82static u8 transport_cb_idx = -1; 86static u8 transport_cb_idx = -1;
83static u8 scsih_cb_idx = -1; 87static u8 scsih_cb_idx = -1;
84static u8 config_cb_idx = -1; 88static u8 config_cb_idx = -1;
@@ -103,6 +107,18 @@ static int max_lun = MPT2SAS_MAX_LUN;
103module_param(max_lun, int, 0); 107module_param(max_lun, int, 0);
104MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); 108MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
105 109
110/* diag_buffer_enable is bitwise
111 * bit 0 set = TRACE
112 * bit 1 set = SNAPSHOT
113 * bit 2 set = EXTENDED
114 *
115 * Either bit can be set, or both
116 */
117static int diag_buffer_enable = -1;
118module_param(diag_buffer_enable, int, 0);
119MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
120 "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
121
106/** 122/**
107 * struct sense_info - common structure for obtaining sense keys 123 * struct sense_info - common structure for obtaining sense keys
108 * @skey: sense key 124 * @skey: sense key
@@ -117,8 +133,8 @@ struct sense_info {
117 133
118 134
119#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC) 135#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC)
120#define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF) 136#define MPT2SAS_PORT_ENABLE_COMPLETE (0xFFFD)
121 137#define MPT2SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF)
122/** 138/**
123 * struct fw_event_work - firmware event struct 139 * struct fw_event_work - firmware event struct
124 * @list: link list framework 140 * @list: link list framework
@@ -372,31 +388,34 @@ _scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle,
372 Mpi2SasDevicePage0_t sas_device_pg0; 388 Mpi2SasDevicePage0_t sas_device_pg0;
373 Mpi2ConfigReply_t mpi_reply; 389 Mpi2ConfigReply_t mpi_reply;
374 u32 ioc_status; 390 u32 ioc_status;
391 *sas_address = 0;
375 392
376 if (handle <= ioc->sas_hba.num_phys) { 393 if (handle <= ioc->sas_hba.num_phys) {
377 *sas_address = ioc->sas_hba.sas_address; 394 *sas_address = ioc->sas_hba.sas_address;
378 return 0; 395 return 0;
379 } else 396 }
380 *sas_address = 0;
381 397
382 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, 398 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
383 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { 399 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
384 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 400 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name,
385 ioc->name, __FILE__, __LINE__, __func__); 401 __FILE__, __LINE__, __func__);
386 return -ENXIO; 402 return -ENXIO;
387 } 403 }
388 404
389 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 405 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
390 MPI2_IOCSTATUS_MASK; 406 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
391 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 407 *sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
392 printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)" 408 return 0;
393 "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
394 __FILE__, __LINE__, __func__);
395 return -EIO;
396 } 409 }
397 410
398 *sas_address = le64_to_cpu(sas_device_pg0.SASAddress); 411 /* we hit this becuase the given parent handle doesn't exist */
399 return 0; 412 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
413 return -ENXIO;
414 /* else error case */
415 printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x), "
416 "failure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
417 __FILE__, __LINE__, __func__);
418 return -EIO;
400} 419}
401 420
402/** 421/**
@@ -424,7 +443,11 @@ _scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc,
424 u16 slot; 443 u16 slot;
425 444
426 /* only process this function when driver loads */ 445 /* only process this function when driver loads */
427 if (!ioc->wait_for_port_enable_to_complete) 446 if (!ioc->is_driver_loading)
447 return;
448
449 /* no Bios, return immediately */
450 if (!ioc->bios_pg3.BiosVersion)
428 return; 451 return;
429 452
430 if (!is_raid) { 453 if (!is_raid) {
@@ -587,8 +610,15 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
587 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 610 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
588 611
589 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 612 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
590 sas_device->sas_address_parent)) 613 sas_device->sas_address_parent)) {
591 _scsih_sas_device_remove(ioc, sas_device); 614 _scsih_sas_device_remove(ioc, sas_device);
615 } else if (!sas_device->starget) {
616 if (!ioc->is_driver_loading)
617 mpt2sas_transport_port_remove(ioc,
618 sas_device->sas_address,
619 sas_device->sas_address_parent);
620 _scsih_sas_device_remove(ioc, sas_device);
621 }
592} 622}
593 623
594/** 624/**
@@ -1400,6 +1430,10 @@ _scsih_slave_destroy(struct scsi_device *sdev)
1400{ 1430{
1401 struct MPT2SAS_TARGET *sas_target_priv_data; 1431 struct MPT2SAS_TARGET *sas_target_priv_data;
1402 struct scsi_target *starget; 1432 struct scsi_target *starget;
1433 struct Scsi_Host *shost;
1434 struct MPT2SAS_ADAPTER *ioc;
1435 struct _sas_device *sas_device;
1436 unsigned long flags;
1403 1437
1404 if (!sdev->hostdata) 1438 if (!sdev->hostdata)
1405 return; 1439 return;
@@ -1407,6 +1441,19 @@ _scsih_slave_destroy(struct scsi_device *sdev)
1407 starget = scsi_target(sdev); 1441 starget = scsi_target(sdev);
1408 sas_target_priv_data = starget->hostdata; 1442 sas_target_priv_data = starget->hostdata;
1409 sas_target_priv_data->num_luns--; 1443 sas_target_priv_data->num_luns--;
1444
1445 shost = dev_to_shost(&starget->dev);
1446 ioc = shost_priv(shost);
1447
1448 if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
1449 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1450 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1451 sas_target_priv_data->sas_address);
1452 if (sas_device)
1453 sas_device->starget = NULL;
1454 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1455 }
1456
1410 kfree(sdev->hostdata); 1457 kfree(sdev->hostdata);
1411 sdev->hostdata = NULL; 1458 sdev->hostdata = NULL;
1412} 1459}
@@ -1598,8 +1645,10 @@ _scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device)
1598 * _scsih_get_volume_capabilities - volume capabilities 1645 * _scsih_get_volume_capabilities - volume capabilities
1599 * @ioc: per adapter object 1646 * @ioc: per adapter object
1600 * @sas_device: the raid_device object 1647 * @sas_device: the raid_device object
1648 *
1649 * Returns 0 for success, else 1
1601 */ 1650 */
1602static void 1651static int
1603_scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc, 1652_scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1604 struct _raid_device *raid_device) 1653 struct _raid_device *raid_device)
1605{ 1654{
@@ -1612,9 +1661,10 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1612 1661
1613 if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle, 1662 if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle,
1614 &num_pds)) || !num_pds) { 1663 &num_pds)) || !num_pds) {
1615 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1664 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1616 ioc->name, __FILE__, __LINE__, __func__); 1665 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1617 return; 1666 __func__));
1667 return 1;
1618 } 1668 }
1619 1669
1620 raid_device->num_pds = num_pds; 1670 raid_device->num_pds = num_pds;
@@ -1622,17 +1672,19 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1622 sizeof(Mpi2RaidVol0PhysDisk_t)); 1672 sizeof(Mpi2RaidVol0PhysDisk_t));
1623 vol_pg0 = kzalloc(sz, GFP_KERNEL); 1673 vol_pg0 = kzalloc(sz, GFP_KERNEL);
1624 if (!vol_pg0) { 1674 if (!vol_pg0) {
1625 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1675 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1626 ioc->name, __FILE__, __LINE__, __func__); 1676 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1627 return; 1677 __func__));
1678 return 1;
1628 } 1679 }
1629 1680
1630 if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0, 1681 if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
1631 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) { 1682 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
1632 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1683 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1633 ioc->name, __FILE__, __LINE__, __func__); 1684 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1685 __func__));
1634 kfree(vol_pg0); 1686 kfree(vol_pg0);
1635 return; 1687 return 1;
1636 } 1688 }
1637 1689
1638 raid_device->volume_type = vol_pg0->VolumeType; 1690 raid_device->volume_type = vol_pg0->VolumeType;
@@ -1652,6 +1704,7 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1652 } 1704 }
1653 1705
1654 kfree(vol_pg0); 1706 kfree(vol_pg0);
1707 return 0;
1655} 1708}
1656/** 1709/**
1657 * _scsih_disable_ddio - Disable direct I/O for all the volumes 1710 * _scsih_disable_ddio - Disable direct I/O for all the volumes
@@ -1922,13 +1975,20 @@ _scsih_slave_configure(struct scsi_device *sdev)
1922 sas_target_priv_data->handle); 1975 sas_target_priv_data->handle);
1923 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1976 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1924 if (!raid_device) { 1977 if (!raid_device) {
1925 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1978 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1926 ioc->name, __FILE__, __LINE__, __func__); 1979 "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
1927 return 0; 1980 __LINE__, __func__));
1981 return 1;
1928 } 1982 }
1929 1983
1930 _scsih_get_volume_capabilities(ioc, raid_device); 1984 _scsih_get_volume_capabilities(ioc, raid_device);
1931 1985
1986 if (_scsih_get_volume_capabilities(ioc, raid_device)) {
1987 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1988 "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
1989 __LINE__, __func__));
1990 return 1;
1991 }
1932 /* 1992 /*
1933 * WARPDRIVE: Initialize the required data for Direct IO 1993 * WARPDRIVE: Initialize the required data for Direct IO
1934 */ 1994 */
@@ -2002,11 +2062,22 @@ _scsih_slave_configure(struct scsi_device *sdev)
2002 if (sas_device) { 2062 if (sas_device) {
2003 if (sas_target_priv_data->flags & 2063 if (sas_target_priv_data->flags &
2004 MPT_TARGET_FLAGS_RAID_COMPONENT) { 2064 MPT_TARGET_FLAGS_RAID_COMPONENT) {
2005 mpt2sas_config_get_volume_handle(ioc, 2065 if (mpt2sas_config_get_volume_handle(ioc,
2006 sas_device->handle, &sas_device->volume_handle); 2066 sas_device->handle, &sas_device->volume_handle)) {
2007 mpt2sas_config_get_volume_wwid(ioc, 2067 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
2068 "failure at %s:%d/%s()!\n", ioc->name,
2069 __FILE__, __LINE__, __func__));
2070 return 1;
2071 }
2072 if (sas_device->volume_handle &&
2073 mpt2sas_config_get_volume_wwid(ioc,
2008 sas_device->volume_handle, 2074 sas_device->volume_handle,
2009 &sas_device->volume_wwid); 2075 &sas_device->volume_wwid)) {
2076 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
2077 "failure at %s:%d/%s()!\n", ioc->name,
2078 __FILE__, __LINE__, __func__));
2079 return 1;
2080 }
2010 } 2081 }
2011 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) { 2082 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
2012 qdepth = MPT2SAS_SAS_QUEUE_DEPTH; 2083 qdepth = MPT2SAS_SAS_QUEUE_DEPTH;
@@ -2035,6 +2106,11 @@ _scsih_slave_configure(struct scsi_device *sdev)
2035 2106
2036 if (!ssp_target) 2107 if (!ssp_target)
2037 _scsih_display_sata_capabilities(ioc, sas_device, sdev); 2108 _scsih_display_sata_capabilities(ioc, sas_device, sdev);
2109 } else {
2110 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
2111 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
2112 __func__));
2113 return 1;
2038 } 2114 }
2039 2115
2040 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); 2116 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
@@ -2714,22 +2790,38 @@ _scsih_fw_event_free(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
2714 2790
2715 2791
2716/** 2792/**
2717 * _scsih_queue_rescan - queue a topology rescan from user context 2793 * _scsih_error_recovery_delete_devices - remove devices not responding
2718 * @ioc: per adapter object 2794 * @ioc: per adapter object
2719 * 2795 *
2720 * Return nothing. 2796 * Return nothing.
2721 */ 2797 */
2722static void 2798static void
2723_scsih_queue_rescan(struct MPT2SAS_ADAPTER *ioc) 2799_scsih_error_recovery_delete_devices(struct MPT2SAS_ADAPTER *ioc)
2724{ 2800{
2725 struct fw_event_work *fw_event; 2801 struct fw_event_work *fw_event;
2726 2802
2727 if (ioc->wait_for_port_enable_to_complete) 2803 if (ioc->is_driver_loading)
2728 return; 2804 return;
2805 fw_event->event = MPT2SAS_REMOVE_UNRESPONDING_DEVICES;
2806 fw_event->ioc = ioc;
2807 _scsih_fw_event_add(ioc, fw_event);
2808}
2809
2810/**
2811 * mpt2sas_port_enable_complete - port enable completed (fake event)
2812 * @ioc: per adapter object
2813 *
2814 * Return nothing.
2815 */
2816void
2817mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc)
2818{
2819 struct fw_event_work *fw_event;
2820
2729 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); 2821 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
2730 if (!fw_event) 2822 if (!fw_event)
2731 return; 2823 return;
2732 fw_event->event = MPT2SAS_RESCAN_AFTER_HOST_RESET; 2824 fw_event->event = MPT2SAS_PORT_ENABLE_COMPLETE;
2733 fw_event->ioc = ioc; 2825 fw_event->ioc = ioc;
2734 _scsih_fw_event_add(ioc, fw_event); 2826 _scsih_fw_event_add(ioc, fw_event);
2735} 2827}
@@ -2977,14 +3069,27 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2977 Mpi2SCSITaskManagementRequest_t *mpi_request; 3069 Mpi2SCSITaskManagementRequest_t *mpi_request;
2978 u16 smid; 3070 u16 smid;
2979 struct _sas_device *sas_device; 3071 struct _sas_device *sas_device;
2980 struct MPT2SAS_TARGET *sas_target_priv_data; 3072 struct MPT2SAS_TARGET *sas_target_priv_data = NULL;
3073 u64 sas_address = 0;
2981 unsigned long flags; 3074 unsigned long flags;
2982 struct _tr_list *delayed_tr; 3075 struct _tr_list *delayed_tr;
3076 u32 ioc_state;
2983 3077
2984 if (ioc->shost_recovery || ioc->remove_host || 3078 if (ioc->remove_host) {
2985 ioc->pci_error_recovery) { 3079 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host has been "
2986 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in " 3080 "removed: handle(0x%04x)\n", __func__, ioc->name, handle));
2987 "progress!\n", __func__, ioc->name)); 3081 return;
3082 } else if (ioc->pci_error_recovery) {
3083 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host in pci "
3084 "error recovery: handle(0x%04x)\n", __func__, ioc->name,
3085 handle));
3086 return;
3087 }
3088 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
3089 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
3090 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host is not "
3091 "operational: handle(0x%04x)\n", __func__, ioc->name,
3092 handle));
2988 return; 3093 return;
2989 } 3094 }
2990 3095
@@ -2998,13 +3103,18 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2998 sas_device->starget->hostdata) { 3103 sas_device->starget->hostdata) {
2999 sas_target_priv_data = sas_device->starget->hostdata; 3104 sas_target_priv_data = sas_device->starget->hostdata;
3000 sas_target_priv_data->deleted = 1; 3105 sas_target_priv_data->deleted = 1;
3001 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT 3106 sas_address = sas_device->sas_address;
3002 "setting delete flag: handle(0x%04x), "
3003 "sas_addr(0x%016llx)\n", ioc->name, handle,
3004 (unsigned long long) sas_device->sas_address));
3005 } 3107 }
3006 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 3108 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3007 3109
3110 if (sas_target_priv_data) {
3111 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "setting delete flag: "
3112 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, handle,
3113 (unsigned long long)sas_address));
3114 _scsih_ublock_io_device(ioc, handle);
3115 sas_target_priv_data->handle = MPT2SAS_INVALID_DEVICE_HANDLE;
3116 }
3117
3008 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); 3118 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
3009 if (!smid) { 3119 if (!smid) {
3010 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); 3120 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
@@ -3185,11 +3295,21 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
3185 mpt2sas_base_get_reply_virt_addr(ioc, reply); 3295 mpt2sas_base_get_reply_virt_addr(ioc, reply);
3186 Mpi2SasIoUnitControlRequest_t *mpi_request; 3296 Mpi2SasIoUnitControlRequest_t *mpi_request;
3187 u16 smid_sas_ctrl; 3297 u16 smid_sas_ctrl;
3298 u32 ioc_state;
3188 3299
3189 if (ioc->shost_recovery || ioc->remove_host || 3300 if (ioc->remove_host) {
3190 ioc->pci_error_recovery) { 3301 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host has been "
3191 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in " 3302 "removed\n", __func__, ioc->name));
3192 "progress!\n", __func__, ioc->name)); 3303 return 1;
3304 } else if (ioc->pci_error_recovery) {
3305 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host in pci "
3306 "error recovery\n", __func__, ioc->name));
3307 return 1;
3308 }
3309 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
3310 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
3311 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host is not "
3312 "operational\n", __func__, ioc->name));
3193 return 1; 3313 return 1;
3194 } 3314 }
3195 3315
@@ -5099,7 +5219,7 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
5099 /* get device name */ 5219 /* get device name */
5100 sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName); 5220 sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName);
5101 5221
5102 if (ioc->wait_for_port_enable_to_complete) 5222 if (ioc->wait_for_discovery_to_complete)
5103 _scsih_sas_device_init_add(ioc, sas_device); 5223 _scsih_sas_device_init_add(ioc, sas_device);
5104 else 5224 else
5105 _scsih_sas_device_add(ioc, sas_device); 5225 _scsih_sas_device_add(ioc, sas_device);
@@ -5135,6 +5255,9 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
5135 if (sas_device_backup.starget && sas_device_backup.starget->hostdata) { 5255 if (sas_device_backup.starget && sas_device_backup.starget->hostdata) {
5136 sas_target_priv_data = sas_device_backup.starget->hostdata; 5256 sas_target_priv_data = sas_device_backup.starget->hostdata;
5137 sas_target_priv_data->deleted = 1; 5257 sas_target_priv_data->deleted = 1;
5258 _scsih_ublock_io_device(ioc, sas_device_backup.handle);
5259 sas_target_priv_data->handle =
5260 MPT2SAS_INVALID_DEVICE_HANDLE;
5138 } 5261 }
5139 5262
5140 _scsih_ublock_io_device(ioc, sas_device_backup.handle); 5263 _scsih_ublock_io_device(ioc, sas_device_backup.handle);
@@ -5288,7 +5411,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
5288 _scsih_sas_topology_change_event_debug(ioc, event_data); 5411 _scsih_sas_topology_change_event_debug(ioc, event_data);
5289#endif 5412#endif
5290 5413
5291 if (ioc->shost_recovery || ioc->remove_host || ioc->pci_error_recovery) 5414 if (ioc->remove_host || ioc->pci_error_recovery)
5292 return; 5415 return;
5293 5416
5294 if (!ioc->sas_hba.num_phys) 5417 if (!ioc->sas_hba.num_phys)
@@ -5349,6 +5472,9 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
5349 switch (reason_code) { 5472 switch (reason_code) {
5350 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 5473 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
5351 5474
5475 if (ioc->shost_recovery)
5476 break;
5477
5352 if (link_rate == prev_link_rate) 5478 if (link_rate == prev_link_rate)
5353 break; 5479 break;
5354 5480
@@ -5362,6 +5488,9 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
5362 break; 5488 break;
5363 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 5489 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
5364 5490
5491 if (ioc->shost_recovery)
5492 break;
5493
5365 mpt2sas_transport_update_links(ioc, sas_address, 5494 mpt2sas_transport_update_links(ioc, sas_address,
5366 handle, phy_number, link_rate); 5495 handle, phy_number, link_rate);
5367 5496
@@ -5622,7 +5751,7 @@ broadcast_aen_retry:
5622 termination_count = 0; 5751 termination_count = 0;
5623 query_count = 0; 5752 query_count = 0;
5624 for (smid = 1; smid <= ioc->scsiio_depth; smid++) { 5753 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
5625 if (ioc->ioc_reset_in_progress_status) 5754 if (ioc->shost_recovery)
5626 goto out; 5755 goto out;
5627 scmd = _scsih_scsi_lookup_get(ioc, smid); 5756 scmd = _scsih_scsi_lookup_get(ioc, smid);
5628 if (!scmd) 5757 if (!scmd)
@@ -5644,7 +5773,7 @@ broadcast_aen_retry:
5644 lun = sas_device_priv_data->lun; 5773 lun = sas_device_priv_data->lun;
5645 query_count++; 5774 query_count++;
5646 5775
5647 if (ioc->ioc_reset_in_progress_status) 5776 if (ioc->shost_recovery)
5648 goto out; 5777 goto out;
5649 5778
5650 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); 5779 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
@@ -5686,7 +5815,7 @@ broadcast_aen_retry:
5686 goto broadcast_aen_retry; 5815 goto broadcast_aen_retry;
5687 } 5816 }
5688 5817
5689 if (ioc->ioc_reset_in_progress_status) 5818 if (ioc->shost_recovery)
5690 goto out_no_lock; 5819 goto out_no_lock;
5691 5820
5692 r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id, 5821 r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
@@ -5725,7 +5854,7 @@ broadcast_aen_retry:
5725 ioc->name, __func__, query_count, termination_count)); 5854 ioc->name, __func__, query_count, termination_count));
5726 5855
5727 ioc->broadcast_aen_busy = 0; 5856 ioc->broadcast_aen_busy = 0;
5728 if (!ioc->ioc_reset_in_progress_status) 5857 if (!ioc->shost_recovery)
5729 _scsih_ublock_io_all_device(ioc); 5858 _scsih_ublock_io_all_device(ioc);
5730 mutex_unlock(&ioc->tm_cmds.mutex); 5859 mutex_unlock(&ioc->tm_cmds.mutex);
5731} 5860}
@@ -5789,8 +5918,11 @@ _scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach)
5789static void 5918static void
5790_scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach) 5919_scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach)
5791{ 5920{
5792 struct MPT2SAS_TARGET *sas_target_priv_data = starget->hostdata; 5921 struct MPT2SAS_TARGET *sas_target_priv_data;
5793 5922
5923 if (starget == NULL)
5924 return;
5925 sas_target_priv_data = starget->hostdata;
5794 if (no_uld_attach) 5926 if (no_uld_attach)
5795 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT; 5927 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
5796 else 5928 else
@@ -5845,7 +5977,7 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
5845 raid_device->handle = handle; 5977 raid_device->handle = handle;
5846 raid_device->wwid = wwid; 5978 raid_device->wwid = wwid;
5847 _scsih_raid_device_add(ioc, raid_device); 5979 _scsih_raid_device_add(ioc, raid_device);
5848 if (!ioc->wait_for_port_enable_to_complete) { 5980 if (!ioc->wait_for_discovery_to_complete) {
5849 rc = scsi_add_device(ioc->shost, RAID_CHANNEL, 5981 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
5850 raid_device->id, 0); 5982 raid_device->id, 0);
5851 if (rc) 5983 if (rc)
@@ -6127,6 +6259,10 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
6127 _scsih_sas_ir_config_change_event_debug(ioc, event_data); 6259 _scsih_sas_ir_config_change_event_debug(ioc, event_data);
6128 6260
6129#endif 6261#endif
6262
6263 if (ioc->shost_recovery)
6264 return;
6265
6130 foreign_config = (le32_to_cpu(event_data->Flags) & 6266 foreign_config = (le32_to_cpu(event_data->Flags) &
6131 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0; 6267 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
6132 6268
@@ -6185,6 +6321,9 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
6185 int rc; 6321 int rc;
6186 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data; 6322 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
6187 6323
6324 if (ioc->shost_recovery)
6325 return;
6326
6188 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED) 6327 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
6189 return; 6328 return;
6190 6329
@@ -6267,6 +6406,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
6267 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data; 6406 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
6268 u64 sas_address; 6407 u64 sas_address;
6269 6408
6409 if (ioc->shost_recovery)
6410 return;
6411
6270 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) 6412 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
6271 return; 6413 return;
6272 6414
@@ -6510,10 +6652,10 @@ _scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6510 u32 device_info; 6652 u32 device_info;
6511 u16 slot; 6653 u16 slot;
6512 6654
6513 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); 6655 printk(MPT2SAS_INFO_FMT "search for end-devices: start\n", ioc->name);
6514 6656
6515 if (list_empty(&ioc->sas_device_list)) 6657 if (list_empty(&ioc->sas_device_list))
6516 return; 6658 goto out;
6517 6659
6518 handle = 0xFFFF; 6660 handle = 0xFFFF;
6519 while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, 6661 while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
@@ -6532,6 +6674,9 @@ _scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6532 _scsih_mark_responding_sas_device(ioc, sas_address, slot, 6674 _scsih_mark_responding_sas_device(ioc, sas_address, slot,
6533 handle); 6675 handle);
6534 } 6676 }
6677out:
6678 printk(MPT2SAS_INFO_FMT "search for end-devices: complete\n",
6679 ioc->name);
6535} 6680}
6536 6681
6537/** 6682/**
@@ -6607,10 +6752,14 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
6607 u16 handle; 6752 u16 handle;
6608 u8 phys_disk_num; 6753 u8 phys_disk_num;
6609 6754
6610 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); 6755 if (!ioc->ir_firmware)
6756 return;
6757
6758 printk(MPT2SAS_INFO_FMT "search for raid volumes: start\n",
6759 ioc->name);
6611 6760
6612 if (list_empty(&ioc->raid_device_list)) 6761 if (list_empty(&ioc->raid_device_list))
6613 return; 6762 goto out;
6614 6763
6615 handle = 0xFFFF; 6764 handle = 0xFFFF;
6616 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, 6765 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
@@ -6649,6 +6798,9 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
6649 set_bit(handle, ioc->pd_handles); 6798 set_bit(handle, ioc->pd_handles);
6650 } 6799 }
6651 } 6800 }
6801out:
6802 printk(MPT2SAS_INFO_FMT "search for responding raid volumes: "
6803 "complete\n", ioc->name);
6652} 6804}
6653 6805
6654/** 6806/**
@@ -6708,10 +6860,10 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
6708 u64 sas_address; 6860 u64 sas_address;
6709 u16 handle; 6861 u16 handle;
6710 6862
6711 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); 6863 printk(MPT2SAS_INFO_FMT "search for expanders: start\n", ioc->name);
6712 6864
6713 if (list_empty(&ioc->sas_expander_list)) 6865 if (list_empty(&ioc->sas_expander_list))
6714 return; 6866 goto out;
6715 6867
6716 handle = 0xFFFF; 6868 handle = 0xFFFF;
6717 while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, 6869 while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
@@ -6730,6 +6882,8 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
6730 _scsih_mark_responding_expander(ioc, sas_address, handle); 6882 _scsih_mark_responding_expander(ioc, sas_address, handle);
6731 } 6883 }
6732 6884
6885 out:
6886 printk(MPT2SAS_INFO_FMT "search for expanders: complete\n", ioc->name);
6733} 6887}
6734 6888
6735/** 6889/**
@@ -6745,6 +6899,8 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6745 struct _sas_node *sas_expander; 6899 struct _sas_node *sas_expander;
6746 struct _raid_device *raid_device, *raid_device_next; 6900 struct _raid_device *raid_device, *raid_device_next;
6747 6901
6902 printk(MPT2SAS_INFO_FMT "removing unresponding devices: start\n",
6903 ioc->name);
6748 6904
6749 list_for_each_entry_safe(sas_device, sas_device_next, 6905 list_for_each_entry_safe(sas_device, sas_device_next,
6750 &ioc->sas_device_list, list) { 6906 &ioc->sas_device_list, list) {
@@ -6764,6 +6920,9 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6764 _scsih_remove_device(ioc, sas_device); 6920 _scsih_remove_device(ioc, sas_device);
6765 } 6921 }
6766 6922
6923 if (!ioc->ir_firmware)
6924 goto retry_expander_search;
6925
6767 list_for_each_entry_safe(raid_device, raid_device_next, 6926 list_for_each_entry_safe(raid_device, raid_device_next,
6768 &ioc->raid_device_list, list) { 6927 &ioc->raid_device_list, list) {
6769 if (raid_device->responding) { 6928 if (raid_device->responding) {
@@ -6790,52 +6949,170 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6790 mpt2sas_expander_remove(ioc, sas_expander->sas_address); 6949 mpt2sas_expander_remove(ioc, sas_expander->sas_address);
6791 goto retry_expander_search; 6950 goto retry_expander_search;
6792 } 6951 }
6952 printk(MPT2SAS_INFO_FMT "removing unresponding devices: complete\n",
6953 ioc->name);
6954 /* unblock devices */
6955 _scsih_ublock_io_all_device(ioc);
6956}
6957
6958static void
6959_scsih_refresh_expander_links(struct MPT2SAS_ADAPTER *ioc,
6960 struct _sas_node *sas_expander, u16 handle)
6961{
6962 Mpi2ExpanderPage1_t expander_pg1;
6963 Mpi2ConfigReply_t mpi_reply;
6964 int i;
6965
6966 for (i = 0 ; i < sas_expander->num_phys ; i++) {
6967 if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply,
6968 &expander_pg1, i, handle))) {
6969 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
6970 ioc->name, __FILE__, __LINE__, __func__);
6971 return;
6972 }
6973
6974 mpt2sas_transport_update_links(ioc, sas_expander->sas_address,
6975 le16_to_cpu(expander_pg1.AttachedDevHandle), i,
6976 expander_pg1.NegotiatedLinkRate >> 4);
6977 }
6793} 6978}
6794 6979
6795/** 6980/**
6796 * _scsih_hide_unhide_sas_devices - add/remove device to/from OS 6981 * _scsih_scan_for_devices_after_reset - scan for devices after host reset
6797 * @ioc: per adapter object 6982 * @ioc: per adapter object
6798 * 6983 *
6799 * Return nothing. 6984 * Return nothing.
6800 */ 6985 */
6801static void 6986static void
6802_scsih_hide_unhide_sas_devices(struct MPT2SAS_ADAPTER *ioc) 6987_scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
6803{ 6988{
6804 struct _sas_device *sas_device, *sas_device_next; 6989 Mpi2ExpanderPage0_t expander_pg0;
6990 Mpi2SasDevicePage0_t sas_device_pg0;
6991 Mpi2RaidVolPage1_t volume_pg1;
6992 Mpi2RaidVolPage0_t volume_pg0;
6993 Mpi2RaidPhysDiskPage0_t pd_pg0;
6994 Mpi2EventIrConfigElement_t element;
6995 Mpi2ConfigReply_t mpi_reply;
6996 u8 phys_disk_num;
6997 u16 ioc_status;
6998 u16 handle, parent_handle;
6999 u64 sas_address;
7000 struct _sas_device *sas_device;
7001 struct _sas_node *expander_device;
7002 static struct _raid_device *raid_device;
6805 7003
6806 if (!ioc->is_warpdrive || ioc->mfg_pg10_hide_flag != 7004 printk(MPT2SAS_INFO_FMT "scan devices: start\n", ioc->name);
6807 MFG_PAGE10_HIDE_IF_VOL_PRESENT)
6808 return;
6809 7005
6810 if (ioc->hide_drives) { 7006 _scsih_sas_host_refresh(ioc);
6811 if (_scsih_get_num_volumes(ioc)) 7007
6812 return; 7008 /* expanders */
6813 ioc->hide_drives = 0; 7009 handle = 0xFFFF;
6814 list_for_each_entry_safe(sas_device, sas_device_next, 7010 while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
6815 &ioc->sas_device_list, list) { 7011 MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
6816 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 7012 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6817 sas_device->sas_address_parent)) { 7013 MPI2_IOCSTATUS_MASK;
6818 _scsih_sas_device_remove(ioc, sas_device); 7014 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
6819 } else if (!sas_device->starget) { 7015 break;
6820 mpt2sas_transport_port_remove(ioc, 7016 handle = le16_to_cpu(expander_pg0.DevHandle);
6821 sas_device->sas_address, 7017 expander_device = mpt2sas_scsih_expander_find_by_sas_address(
6822 sas_device->sas_address_parent); 7018 ioc, le64_to_cpu(expander_pg0.SASAddress));
6823 _scsih_sas_device_remove(ioc, sas_device); 7019 if (expander_device)
6824 } 7020 _scsih_refresh_expander_links(ioc, expander_device,
7021 handle);
7022 else
7023 _scsih_expander_add(ioc, handle);
7024 }
7025
7026 if (!ioc->ir_firmware)
7027 goto skip_to_sas;
7028
7029 /* phys disk */
7030 phys_disk_num = 0xFF;
7031 while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
7032 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
7033 phys_disk_num))) {
7034 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7035 MPI2_IOCSTATUS_MASK;
7036 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7037 break;
7038 phys_disk_num = pd_pg0.PhysDiskNum;
7039 handle = le16_to_cpu(pd_pg0.DevHandle);
7040 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
7041 if (sas_device)
7042 continue;
7043 if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
7044 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
7045 handle) != 0)
7046 continue;
7047 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
7048 if (!_scsih_get_sas_address(ioc, parent_handle,
7049 &sas_address)) {
7050 mpt2sas_transport_update_links(ioc, sas_address,
7051 handle, sas_device_pg0.PhyNum,
7052 MPI2_SAS_NEG_LINK_RATE_1_5);
7053 set_bit(handle, ioc->pd_handles);
7054 _scsih_add_device(ioc, handle, 0, 1);
6825 } 7055 }
6826 } else { 7056 }
6827 if (!_scsih_get_num_volumes(ioc)) 7057
6828 return; 7058 /* volumes */
6829 ioc->hide_drives = 1; 7059 handle = 0xFFFF;
6830 list_for_each_entry_safe(sas_device, sas_device_next, 7060 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
6831 &ioc->sas_device_list, list) { 7061 &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
6832 mpt2sas_transport_port_remove(ioc, 7062 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6833 sas_device->sas_address, 7063 MPI2_IOCSTATUS_MASK;
6834 sas_device->sas_address_parent); 7064 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7065 break;
7066 handle = le16_to_cpu(volume_pg1.DevHandle);
7067 raid_device = _scsih_raid_device_find_by_wwid(ioc,
7068 le64_to_cpu(volume_pg1.WWID));
7069 if (raid_device)
7070 continue;
7071 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply,
7072 &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
7073 sizeof(Mpi2RaidVolPage0_t)))
7074 continue;
7075 if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL ||
7076 volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE ||
7077 volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) {
7078 memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t));
7079 element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED;
7080 element.VolDevHandle = volume_pg1.DevHandle;
7081 _scsih_sas_volume_add(ioc, &element);
6835 } 7082 }
6836 } 7083 }
7084
7085 skip_to_sas:
7086
7087 /* sas devices */
7088 handle = 0xFFFF;
7089 while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
7090 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
7091 handle))) {
7092 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7093 MPI2_IOCSTATUS_MASK;
7094 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7095 break;
7096 handle = le16_to_cpu(sas_device_pg0.DevHandle);
7097 if (!(_scsih_is_end_device(
7098 le32_to_cpu(sas_device_pg0.DeviceInfo))))
7099 continue;
7100 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
7101 le64_to_cpu(sas_device_pg0.SASAddress));
7102 if (sas_device)
7103 continue;
7104 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
7105 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) {
7106 mpt2sas_transport_update_links(ioc, sas_address, handle,
7107 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
7108 _scsih_add_device(ioc, handle, 0, 0);
7109 }
7110 }
7111
7112 printk(MPT2SAS_INFO_FMT "scan devices: complete\n", ioc->name);
6837} 7113}
6838 7114
7115
6839/** 7116/**
6840 * mpt2sas_scsih_reset_handler - reset callback handler (for scsih) 7117 * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
6841 * @ioc: per adapter object 7118 * @ioc: per adapter object
@@ -6871,7 +7148,6 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
6871 } 7148 }
6872 _scsih_fw_event_cleanup_queue(ioc); 7149 _scsih_fw_event_cleanup_queue(ioc);
6873 _scsih_flush_running_cmds(ioc); 7150 _scsih_flush_running_cmds(ioc);
6874 _scsih_queue_rescan(ioc);
6875 break; 7151 break;
6876 case MPT2_IOC_DONE_RESET: 7152 case MPT2_IOC_DONE_RESET:
6877 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " 7153 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
@@ -6881,6 +7157,13 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
6881 _scsih_search_responding_sas_devices(ioc); 7157 _scsih_search_responding_sas_devices(ioc);
6882 _scsih_search_responding_raid_devices(ioc); 7158 _scsih_search_responding_raid_devices(ioc);
6883 _scsih_search_responding_expanders(ioc); 7159 _scsih_search_responding_expanders(ioc);
7160 if (!ioc->is_driver_loading) {
7161 _scsih_prep_device_scan(ioc);
7162 _scsih_search_responding_sas_devices(ioc);
7163 _scsih_search_responding_raid_devices(ioc);
7164 _scsih_search_responding_expanders(ioc);
7165 _scsih_error_recovery_delete_devices(ioc);
7166 }
6884 break; 7167 break;
6885 } 7168 }
6886} 7169}
@@ -6898,7 +7181,6 @@ _firmware_event_work(struct work_struct *work)
6898{ 7181{
6899 struct fw_event_work *fw_event = container_of(work, 7182 struct fw_event_work *fw_event = container_of(work,
6900 struct fw_event_work, delayed_work.work); 7183 struct fw_event_work, delayed_work.work);
6901 unsigned long flags;
6902 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc; 7184 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
6903 7185
6904 /* the queue is being flushed so ignore this event */ 7186 /* the queue is being flushed so ignore this event */
@@ -6908,23 +7190,21 @@ _firmware_event_work(struct work_struct *work)
6908 return; 7190 return;
6909 } 7191 }
6910 7192
6911 if (fw_event->event == MPT2SAS_RESCAN_AFTER_HOST_RESET) { 7193 switch (fw_event->event) {
6912 _scsih_fw_event_free(ioc, fw_event); 7194 case MPT2SAS_REMOVE_UNRESPONDING_DEVICES:
6913 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 7195 while (scsi_host_in_recovery(ioc->shost))
6914 if (ioc->shost_recovery) { 7196 ssleep(1);
6915 init_completion(&ioc->shost_recovery_done);
6916 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
6917 flags);
6918 wait_for_completion(&ioc->shost_recovery_done);
6919 } else
6920 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
6921 flags);
6922 _scsih_remove_unresponding_sas_devices(ioc); 7197 _scsih_remove_unresponding_sas_devices(ioc);
6923 _scsih_hide_unhide_sas_devices(ioc); 7198 _scsih_scan_for_devices_after_reset(ioc);
6924 return; 7199 break;
6925 } 7200 case MPT2SAS_PORT_ENABLE_COMPLETE:
7201 ioc->start_scan = 0;
6926 7202
6927 switch (fw_event->event) { 7203
7204
7205 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "port enable: complete "
7206 "from worker thread\n", ioc->name));
7207 break;
6928 case MPT2SAS_TURN_ON_FAULT_LED: 7208 case MPT2SAS_TURN_ON_FAULT_LED:
6929 _scsih_turn_on_fault_led(ioc, fw_event->device_handle); 7209 _scsih_turn_on_fault_led(ioc, fw_event->device_handle);
6930 break; 7210 break;
@@ -7121,6 +7401,8 @@ static struct scsi_host_template scsih_driver_template = {
7121 .slave_configure = _scsih_slave_configure, 7401 .slave_configure = _scsih_slave_configure,
7122 .target_destroy = _scsih_target_destroy, 7402 .target_destroy = _scsih_target_destroy,
7123 .slave_destroy = _scsih_slave_destroy, 7403 .slave_destroy = _scsih_slave_destroy,
7404 .scan_finished = _scsih_scan_finished,
7405 .scan_start = _scsih_scan_start,
7124 .change_queue_depth = _scsih_change_queue_depth, 7406 .change_queue_depth = _scsih_change_queue_depth,
7125 .change_queue_type = _scsih_change_queue_type, 7407 .change_queue_type = _scsih_change_queue_type,
7126 .eh_abort_handler = _scsih_abort, 7408 .eh_abort_handler = _scsih_abort,
@@ -7381,7 +7663,12 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
7381 unsigned long flags; 7663 unsigned long flags;
7382 int rc; 7664 int rc;
7383 7665
7666 /* no Bios, return immediately */
7667 if (!ioc->bios_pg3.BiosVersion)
7668 return;
7669
7384 device = NULL; 7670 device = NULL;
7671 is_raid = 0;
7385 if (ioc->req_boot_device.device) { 7672 if (ioc->req_boot_device.device) {
7386 device = ioc->req_boot_device.device; 7673 device = ioc->req_boot_device.device;
7387 is_raid = ioc->req_boot_device.is_raid; 7674 is_raid = ioc->req_boot_device.is_raid;
@@ -7417,8 +7704,9 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
7417 sas_device->sas_address_parent)) { 7704 sas_device->sas_address_parent)) {
7418 _scsih_sas_device_remove(ioc, sas_device); 7705 _scsih_sas_device_remove(ioc, sas_device);
7419 } else if (!sas_device->starget) { 7706 } else if (!sas_device->starget) {
7420 mpt2sas_transport_port_remove(ioc, sas_address, 7707 if (!ioc->is_driver_loading)
7421 sas_address_parent); 7708 mpt2sas_transport_port_remove(ioc, sas_address,
7709 sas_address_parent);
7422 _scsih_sas_device_remove(ioc, sas_device); 7710 _scsih_sas_device_remove(ioc, sas_device);
7423 } 7711 }
7424 } 7712 }
@@ -7462,22 +7750,28 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
7462 /* SAS Device List */ 7750 /* SAS Device List */
7463 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, 7751 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
7464 list) { 7752 list) {
7465 spin_lock_irqsave(&ioc->sas_device_lock, flags);
7466 list_move_tail(&sas_device->list, &ioc->sas_device_list);
7467 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
7468 7753
7469 if (ioc->hide_drives) 7754 if (ioc->hide_drives)
7470 continue; 7755 continue;
7471 7756
7472 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 7757 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
7473 sas_device->sas_address_parent)) { 7758 sas_device->sas_address_parent)) {
7474 _scsih_sas_device_remove(ioc, sas_device); 7759 list_del(&sas_device->list);
7760 kfree(sas_device);
7761 continue;
7475 } else if (!sas_device->starget) { 7762 } else if (!sas_device->starget) {
7476 mpt2sas_transport_port_remove(ioc, 7763 if (!ioc->is_driver_loading)
7477 sas_device->sas_address, 7764 mpt2sas_transport_port_remove(ioc,
7478 sas_device->sas_address_parent); 7765 sas_device->sas_address,
7479 _scsih_sas_device_remove(ioc, sas_device); 7766 sas_device->sas_address_parent);
7767 list_del(&sas_device->list);
7768 kfree(sas_device);
7769 continue;
7770
7480 } 7771 }
7772 spin_lock_irqsave(&ioc->sas_device_lock, flags);
7773 list_move_tail(&sas_device->list, &ioc->sas_device_list);
7774 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
7481 } 7775 }
7482} 7776}
7483 7777
@@ -7490,9 +7784,7 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
7490static void 7784static void
7491_scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc) 7785_scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
7492{ 7786{
7493 u16 volume_mapping_flags = 7787 u16 volume_mapping_flags;
7494 le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
7495 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
7496 7788
7497 if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR)) 7789 if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR))
7498 return; /* return when IOC doesn't support initiator mode */ 7790 return; /* return when IOC doesn't support initiator mode */
@@ -7500,18 +7792,93 @@ _scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
7500 _scsih_probe_boot_devices(ioc); 7792 _scsih_probe_boot_devices(ioc);
7501 7793
7502 if (ioc->ir_firmware) { 7794 if (ioc->ir_firmware) {
7503 if ((volume_mapping_flags & 7795 volume_mapping_flags =
7504 MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING)) { 7796 le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
7505 _scsih_probe_sas(ioc); 7797 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
7798 if (volume_mapping_flags ==
7799 MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) {
7506 _scsih_probe_raid(ioc); 7800 _scsih_probe_raid(ioc);
7801 _scsih_probe_sas(ioc);
7507 } else { 7802 } else {
7508 _scsih_probe_raid(ioc);
7509 _scsih_probe_sas(ioc); 7803 _scsih_probe_sas(ioc);
7804 _scsih_probe_raid(ioc);
7510 } 7805 }
7511 } else 7806 } else
7512 _scsih_probe_sas(ioc); 7807 _scsih_probe_sas(ioc);
7513} 7808}
7514 7809
7810
7811/**
7812 * _scsih_scan_start - scsi lld callback for .scan_start
7813 * @shost: SCSI host pointer
7814 *
7815 * The shost has the ability to discover targets on its own instead
7816 * of scanning the entire bus. In our implemention, we will kick off
7817 * firmware discovery.
7818 */
7819static void
7820_scsih_scan_start(struct Scsi_Host *shost)
7821{
7822 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
7823 int rc;
7824
7825 if (diag_buffer_enable != -1 && diag_buffer_enable != 0)
7826 mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
7827
7828 ioc->start_scan = 1;
7829 rc = mpt2sas_port_enable(ioc);
7830
7831 if (rc != 0)
7832 printk(MPT2SAS_INFO_FMT "port enable: FAILED\n", ioc->name);
7833}
7834
7835/**
7836 * _scsih_scan_finished - scsi lld callback for .scan_finished
7837 * @shost: SCSI host pointer
7838 * @time: elapsed time of the scan in jiffies
7839 *
7840 * This function will be called periodically until it returns 1 with the
7841 * scsi_host and the elapsed time of the scan in jiffies. In our implemention,
7842 * we wait for firmware discovery to complete, then return 1.
7843 */
7844static int
7845_scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
7846{
7847 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
7848
7849 if (time >= (300 * HZ)) {
7850 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
7851 printk(MPT2SAS_INFO_FMT "port enable: FAILED with timeout "
7852 "(timeout=300s)\n", ioc->name);
7853 ioc->is_driver_loading = 0;
7854 return 1;
7855 }
7856
7857 if (ioc->start_scan)
7858 return 0;
7859
7860 if (ioc->start_scan_failed) {
7861 printk(MPT2SAS_INFO_FMT "port enable: FAILED with "
7862 "(ioc_status=0x%08x)\n", ioc->name, ioc->start_scan_failed);
7863 ioc->is_driver_loading = 0;
7864 ioc->wait_for_discovery_to_complete = 0;
7865 ioc->remove_host = 1;
7866 return 1;
7867 }
7868
7869 printk(MPT2SAS_INFO_FMT "port enable: SUCCESS\n", ioc->name);
7870 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
7871
7872 if (ioc->wait_for_discovery_to_complete) {
7873 ioc->wait_for_discovery_to_complete = 0;
7874 _scsih_probe_devices(ioc);
7875 }
7876 mpt2sas_base_start_watchdog(ioc);
7877 ioc->is_driver_loading = 0;
7878 return 1;
7879}
7880
7881
7515/** 7882/**
7516 * _scsih_probe - attach and add scsi host 7883 * _scsih_probe - attach and add scsi host
7517 * @pdev: PCI device struct 7884 * @pdev: PCI device struct
@@ -7548,6 +7915,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
7548 ioc->tm_cb_idx = tm_cb_idx; 7915 ioc->tm_cb_idx = tm_cb_idx;
7549 ioc->ctl_cb_idx = ctl_cb_idx; 7916 ioc->ctl_cb_idx = ctl_cb_idx;
7550 ioc->base_cb_idx = base_cb_idx; 7917 ioc->base_cb_idx = base_cb_idx;
7918 ioc->port_enable_cb_idx = port_enable_cb_idx;
7551 ioc->transport_cb_idx = transport_cb_idx; 7919 ioc->transport_cb_idx = transport_cb_idx;
7552 ioc->scsih_cb_idx = scsih_cb_idx; 7920 ioc->scsih_cb_idx = scsih_cb_idx;
7553 ioc->config_cb_idx = config_cb_idx; 7921 ioc->config_cb_idx = config_cb_idx;
@@ -7620,14 +7988,14 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
7620 goto out_thread_fail; 7988 goto out_thread_fail;
7621 } 7989 }
7622 7990
7623 ioc->wait_for_port_enable_to_complete = 1; 7991 ioc->is_driver_loading = 1;
7624 if ((mpt2sas_base_attach(ioc))) { 7992 if ((mpt2sas_base_attach(ioc))) {
7625 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 7993 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
7626 ioc->name, __FILE__, __LINE__, __func__); 7994 ioc->name, __FILE__, __LINE__, __func__);
7627 goto out_attach_fail; 7995 goto out_attach_fail;
7628 } 7996 }
7629 7997
7630 ioc->wait_for_port_enable_to_complete = 0; 7998 scsi_scan_host(shost);
7631 if (ioc->is_warpdrive) { 7999 if (ioc->is_warpdrive) {
7632 if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) 8000 if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS)
7633 ioc->hide_drives = 0; 8001 ioc->hide_drives = 0;
@@ -7650,6 +8018,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
7650 out_thread_fail: 8018 out_thread_fail:
7651 list_del(&ioc->list); 8019 list_del(&ioc->list);
7652 scsi_remove_host(shost); 8020 scsi_remove_host(shost);
8021 scsi_host_put(shost);
7653 out_add_shost_fail: 8022 out_add_shost_fail:
7654 return -ENODEV; 8023 return -ENODEV;
7655} 8024}
@@ -7896,6 +8265,8 @@ _scsih_init(void)
7896 8265
7897 /* base internal commands callback handler */ 8266 /* base internal commands callback handler */
7898 base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done); 8267 base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done);
8268 port_enable_cb_idx = mpt2sas_base_register_callback_handler(
8269 mpt2sas_port_enable_done);
7899 8270
7900 /* transport internal commands callback handler */ 8271 /* transport internal commands callback handler */
7901 transport_cb_idx = mpt2sas_base_register_callback_handler( 8272 transport_cb_idx = mpt2sas_base_register_callback_handler(
@@ -7950,6 +8321,7 @@ _scsih_exit(void)
7950 mpt2sas_base_release_callback_handler(scsi_io_cb_idx); 8321 mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
7951 mpt2sas_base_release_callback_handler(tm_cb_idx); 8322 mpt2sas_base_release_callback_handler(tm_cb_idx);
7952 mpt2sas_base_release_callback_handler(base_cb_idx); 8323 mpt2sas_base_release_callback_handler(base_cb_idx);
8324 mpt2sas_base_release_callback_handler(port_enable_cb_idx);
7953 mpt2sas_base_release_callback_handler(transport_cb_idx); 8325 mpt2sas_base_release_callback_handler(transport_cb_idx);
7954 mpt2sas_base_release_callback_handler(scsih_cb_idx); 8326 mpt2sas_base_release_callback_handler(scsih_cb_idx);
7955 mpt2sas_base_release_callback_handler(config_cb_idx); 8327 mpt2sas_base_release_callback_handler(config_cb_idx);