aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_scsih.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2012-01-09 02:38:23 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-01-09 02:38:23 -0500
commitda733563be5a9da26fe81d9f007262d00b846e22 (patch)
treedb28291df94a2043af2123911984c5c173da4e6f /drivers/scsi/mpt2sas/mpt2sas_scsih.c
parent6ccbcf2cb41131f8d56ef0723bf3f7c1f8486076 (diff)
parentdab78d7924598ea4031663dd10db814e2e324928 (diff)
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c642
1 files changed, 510 insertions, 132 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 6abd2fcc43e2..4e041f6d808c 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -41,7 +41,6 @@
41 * USA. 41 * USA.
42 */ 42 */
43 43
44#include <linux/version.h>
45#include <linux/module.h> 44#include <linux/module.h>
46#include <linux/kernel.h> 45#include <linux/kernel.h>
47#include <linux/init.h> 46#include <linux/init.h>
@@ -72,6 +71,9 @@ static void _firmware_event_work(struct work_struct *work);
72 71
73static 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);
74 73
74static void _scsih_scan_start(struct Scsi_Host *shost);
75static int _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time);
76
75/* global parameters */ 77/* global parameters */
76LIST_HEAD(mpt2sas_ioc_list); 78LIST_HEAD(mpt2sas_ioc_list);
77 79
@@ -80,6 +82,7 @@ static u8 scsi_io_cb_idx = -1;
80static u8 tm_cb_idx = -1; 82static u8 tm_cb_idx = -1;
81static u8 ctl_cb_idx = -1; 83static u8 ctl_cb_idx = -1;
82static u8 base_cb_idx = -1; 84static u8 base_cb_idx = -1;
85static u8 port_enable_cb_idx = -1;
83static u8 transport_cb_idx = -1; 86static u8 transport_cb_idx = -1;
84static u8 scsih_cb_idx = -1; 87static u8 scsih_cb_idx = -1;
85static u8 config_cb_idx = -1; 88static u8 config_cb_idx = -1;
@@ -104,6 +107,18 @@ static int max_lun = MPT2SAS_MAX_LUN;
104module_param(max_lun, int, 0); 107module_param(max_lun, int, 0);
105MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); 108MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
106 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
107/** 122/**
108 * struct sense_info - common structure for obtaining sense keys 123 * struct sense_info - common structure for obtaining sense keys
109 * @skey: sense key 124 * @skey: sense key
@@ -118,8 +133,8 @@ struct sense_info {
118 133
119 134
120#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC) 135#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC)
121#define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF) 136#define MPT2SAS_PORT_ENABLE_COMPLETE (0xFFFD)
122 137#define MPT2SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF)
123/** 138/**
124 * struct fw_event_work - firmware event struct 139 * struct fw_event_work - firmware event struct
125 * @list: link list framework 140 * @list: link list framework
@@ -373,31 +388,34 @@ _scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle,
373 Mpi2SasDevicePage0_t sas_device_pg0; 388 Mpi2SasDevicePage0_t sas_device_pg0;
374 Mpi2ConfigReply_t mpi_reply; 389 Mpi2ConfigReply_t mpi_reply;
375 u32 ioc_status; 390 u32 ioc_status;
391 *sas_address = 0;
376 392
377 if (handle <= ioc->sas_hba.num_phys) { 393 if (handle <= ioc->sas_hba.num_phys) {
378 *sas_address = ioc->sas_hba.sas_address; 394 *sas_address = ioc->sas_hba.sas_address;
379 return 0; 395 return 0;
380 } else 396 }
381 *sas_address = 0;
382 397
383 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,
384 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { 399 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
385 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 400 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name,
386 ioc->name, __FILE__, __LINE__, __func__); 401 __FILE__, __LINE__, __func__);
387 return -ENXIO; 402 return -ENXIO;
388 } 403 }
389 404
390 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 405 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
391 MPI2_IOCSTATUS_MASK; 406 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
392 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 407 *sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
393 printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)" 408 return 0;
394 "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
395 __FILE__, __LINE__, __func__);
396 return -EIO;
397 } 409 }
398 410
399 *sas_address = le64_to_cpu(sas_device_pg0.SASAddress); 411 /* we hit this becuase the given parent handle doesn't exist */
400 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;
401} 419}
402 420
403/** 421/**
@@ -425,7 +443,11 @@ _scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc,
425 u16 slot; 443 u16 slot;
426 444
427 /* only process this function when driver loads */ 445 /* only process this function when driver loads */
428 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)
429 return; 451 return;
430 452
431 if (!is_raid) { 453 if (!is_raid) {
@@ -588,8 +610,15 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
588 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 610 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
589 611
590 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 612 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
591 sas_device->sas_address_parent)) 613 sas_device->sas_address_parent)) {
592 _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 }
593} 622}
594 623
595/** 624/**
@@ -1401,6 +1430,10 @@ _scsih_slave_destroy(struct scsi_device *sdev)
1401{ 1430{
1402 struct MPT2SAS_TARGET *sas_target_priv_data; 1431 struct MPT2SAS_TARGET *sas_target_priv_data;
1403 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;
1404 1437
1405 if (!sdev->hostdata) 1438 if (!sdev->hostdata)
1406 return; 1439 return;
@@ -1408,6 +1441,19 @@ _scsih_slave_destroy(struct scsi_device *sdev)
1408 starget = scsi_target(sdev); 1441 starget = scsi_target(sdev);
1409 sas_target_priv_data = starget->hostdata; 1442 sas_target_priv_data = starget->hostdata;
1410 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
1411 kfree(sdev->hostdata); 1457 kfree(sdev->hostdata);
1412 sdev->hostdata = NULL; 1458 sdev->hostdata = NULL;
1413} 1459}
@@ -1599,8 +1645,10 @@ _scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device)
1599 * _scsih_get_volume_capabilities - volume capabilities 1645 * _scsih_get_volume_capabilities - volume capabilities
1600 * @ioc: per adapter object 1646 * @ioc: per adapter object
1601 * @sas_device: the raid_device object 1647 * @sas_device: the raid_device object
1648 *
1649 * Returns 0 for success, else 1
1602 */ 1650 */
1603static void 1651static int
1604_scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc, 1652_scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1605 struct _raid_device *raid_device) 1653 struct _raid_device *raid_device)
1606{ 1654{
@@ -1613,9 +1661,10 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1613 1661
1614 if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle, 1662 if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle,
1615 &num_pds)) || !num_pds) { 1663 &num_pds)) || !num_pds) {
1616 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1664 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1617 ioc->name, __FILE__, __LINE__, __func__); 1665 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1618 return; 1666 __func__));
1667 return 1;
1619 } 1668 }
1620 1669
1621 raid_device->num_pds = num_pds; 1670 raid_device->num_pds = num_pds;
@@ -1623,17 +1672,19 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1623 sizeof(Mpi2RaidVol0PhysDisk_t)); 1672 sizeof(Mpi2RaidVol0PhysDisk_t));
1624 vol_pg0 = kzalloc(sz, GFP_KERNEL); 1673 vol_pg0 = kzalloc(sz, GFP_KERNEL);
1625 if (!vol_pg0) { 1674 if (!vol_pg0) {
1626 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1675 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1627 ioc->name, __FILE__, __LINE__, __func__); 1676 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1628 return; 1677 __func__));
1678 return 1;
1629 } 1679 }
1630 1680
1631 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,
1632 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) { 1682 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
1633 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1683 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1634 ioc->name, __FILE__, __LINE__, __func__); 1684 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1685 __func__));
1635 kfree(vol_pg0); 1686 kfree(vol_pg0);
1636 return; 1687 return 1;
1637 } 1688 }
1638 1689
1639 raid_device->volume_type = vol_pg0->VolumeType; 1690 raid_device->volume_type = vol_pg0->VolumeType;
@@ -1653,6 +1704,7 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1653 } 1704 }
1654 1705
1655 kfree(vol_pg0); 1706 kfree(vol_pg0);
1707 return 0;
1656} 1708}
1657/** 1709/**
1658 * _scsih_disable_ddio - Disable direct I/O for all the volumes 1710 * _scsih_disable_ddio - Disable direct I/O for all the volumes
@@ -1923,13 +1975,20 @@ _scsih_slave_configure(struct scsi_device *sdev)
1923 sas_target_priv_data->handle); 1975 sas_target_priv_data->handle);
1924 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1976 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1925 if (!raid_device) { 1977 if (!raid_device) {
1926 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1978 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1927 ioc->name, __FILE__, __LINE__, __func__); 1979 "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
1928 return 0; 1980 __LINE__, __func__));
1981 return 1;
1929 } 1982 }
1930 1983
1931 _scsih_get_volume_capabilities(ioc, raid_device); 1984 _scsih_get_volume_capabilities(ioc, raid_device);
1932 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 }
1933 /* 1992 /*
1934 * WARPDRIVE: Initialize the required data for Direct IO 1993 * WARPDRIVE: Initialize the required data for Direct IO
1935 */ 1994 */
@@ -2003,11 +2062,22 @@ _scsih_slave_configure(struct scsi_device *sdev)
2003 if (sas_device) { 2062 if (sas_device) {
2004 if (sas_target_priv_data->flags & 2063 if (sas_target_priv_data->flags &
2005 MPT_TARGET_FLAGS_RAID_COMPONENT) { 2064 MPT_TARGET_FLAGS_RAID_COMPONENT) {
2006 mpt2sas_config_get_volume_handle(ioc, 2065 if (mpt2sas_config_get_volume_handle(ioc,
2007 sas_device->handle, &sas_device->volume_handle); 2066 sas_device->handle, &sas_device->volume_handle)) {
2008 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,
2009 sas_device->volume_handle, 2074 sas_device->volume_handle,
2010 &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 }
2011 } 2081 }
2012 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) { 2082 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
2013 qdepth = MPT2SAS_SAS_QUEUE_DEPTH; 2083 qdepth = MPT2SAS_SAS_QUEUE_DEPTH;
@@ -2036,6 +2106,11 @@ _scsih_slave_configure(struct scsi_device *sdev)
2036 2106
2037 if (!ssp_target) 2107 if (!ssp_target)
2038 _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;
2039 } 2114 }
2040 2115
2041 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); 2116 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
@@ -2162,6 +2237,7 @@ _scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
2162 return 1; 2237 return 1;
2163 if (ioc->tm_cmds.smid != smid) 2238 if (ioc->tm_cmds.smid != smid)
2164 return 1; 2239 return 1;
2240 mpt2sas_base_flush_reply_queues(ioc);
2165 ioc->tm_cmds.status |= MPT2_CMD_COMPLETE; 2241 ioc->tm_cmds.status |= MPT2_CMD_COMPLETE;
2166 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 2242 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
2167 if (mpi_reply) { 2243 if (mpi_reply) {
@@ -2714,22 +2790,43 @@ _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)
2804 return;
2805
2806 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
2807 if (!fw_event)
2728 return; 2808 return;
2809
2810 fw_event->event = MPT2SAS_REMOVE_UNRESPONDING_DEVICES;
2811 fw_event->ioc = ioc;
2812 _scsih_fw_event_add(ioc, fw_event);
2813}
2814
2815/**
2816 * mpt2sas_port_enable_complete - port enable completed (fake event)
2817 * @ioc: per adapter object
2818 *
2819 * Return nothing.
2820 */
2821void
2822mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc)
2823{
2824 struct fw_event_work *fw_event;
2825
2729 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); 2826 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
2730 if (!fw_event) 2827 if (!fw_event)
2731 return; 2828 return;
2732 fw_event->event = MPT2SAS_RESCAN_AFTER_HOST_RESET; 2829 fw_event->event = MPT2SAS_PORT_ENABLE_COMPLETE;
2733 fw_event->ioc = ioc; 2830 fw_event->ioc = ioc;
2734 _scsih_fw_event_add(ioc, fw_event); 2831 _scsih_fw_event_add(ioc, fw_event);
2735} 2832}
@@ -2977,14 +3074,27 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2977 Mpi2SCSITaskManagementRequest_t *mpi_request; 3074 Mpi2SCSITaskManagementRequest_t *mpi_request;
2978 u16 smid; 3075 u16 smid;
2979 struct _sas_device *sas_device; 3076 struct _sas_device *sas_device;
2980 struct MPT2SAS_TARGET *sas_target_priv_data; 3077 struct MPT2SAS_TARGET *sas_target_priv_data = NULL;
3078 u64 sas_address = 0;
2981 unsigned long flags; 3079 unsigned long flags;
2982 struct _tr_list *delayed_tr; 3080 struct _tr_list *delayed_tr;
3081 u32 ioc_state;
2983 3082
2984 if (ioc->shost_recovery || ioc->remove_host || 3083 if (ioc->remove_host) {
2985 ioc->pci_error_recovery) { 3084 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host has been "
2986 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in " 3085 "removed: handle(0x%04x)\n", __func__, ioc->name, handle));
2987 "progress!\n", __func__, ioc->name)); 3086 return;
3087 } else if (ioc->pci_error_recovery) {
3088 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host in pci "
3089 "error recovery: handle(0x%04x)\n", __func__, ioc->name,
3090 handle));
3091 return;
3092 }
3093 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
3094 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
3095 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host is not "
3096 "operational: handle(0x%04x)\n", __func__, ioc->name,
3097 handle));
2988 return; 3098 return;
2989 } 3099 }
2990 3100
@@ -2998,13 +3108,18 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2998 sas_device->starget->hostdata) { 3108 sas_device->starget->hostdata) {
2999 sas_target_priv_data = sas_device->starget->hostdata; 3109 sas_target_priv_data = sas_device->starget->hostdata;
3000 sas_target_priv_data->deleted = 1; 3110 sas_target_priv_data->deleted = 1;
3001 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT 3111 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 } 3112 }
3006 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 3113 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3007 3114
3115 if (sas_target_priv_data) {
3116 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "setting delete flag: "
3117 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, handle,
3118 (unsigned long long)sas_address));
3119 _scsih_ublock_io_device(ioc, handle);
3120 sas_target_priv_data->handle = MPT2SAS_INVALID_DEVICE_HANDLE;
3121 }
3122
3008 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); 3123 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
3009 if (!smid) { 3124 if (!smid) {
3010 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); 3125 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
@@ -3185,11 +3300,21 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
3185 mpt2sas_base_get_reply_virt_addr(ioc, reply); 3300 mpt2sas_base_get_reply_virt_addr(ioc, reply);
3186 Mpi2SasIoUnitControlRequest_t *mpi_request; 3301 Mpi2SasIoUnitControlRequest_t *mpi_request;
3187 u16 smid_sas_ctrl; 3302 u16 smid_sas_ctrl;
3303 u32 ioc_state;
3188 3304
3189 if (ioc->shost_recovery || ioc->remove_host || 3305 if (ioc->remove_host) {
3190 ioc->pci_error_recovery) { 3306 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host has been "
3191 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in " 3307 "removed\n", __func__, ioc->name));
3192 "progress!\n", __func__, ioc->name)); 3308 return 1;
3309 } else if (ioc->pci_error_recovery) {
3310 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host in pci "
3311 "error recovery\n", __func__, ioc->name));
3312 return 1;
3313 }
3314 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
3315 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
3316 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host is not "
3317 "operational\n", __func__, ioc->name));
3193 return 1; 3318 return 1;
3194 } 3319 }
3195 3320
@@ -5099,7 +5224,7 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
5099 /* get device name */ 5224 /* get device name */
5100 sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName); 5225 sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName);
5101 5226
5102 if (ioc->wait_for_port_enable_to_complete) 5227 if (ioc->wait_for_discovery_to_complete)
5103 _scsih_sas_device_init_add(ioc, sas_device); 5228 _scsih_sas_device_init_add(ioc, sas_device);
5104 else 5229 else
5105 _scsih_sas_device_add(ioc, sas_device); 5230 _scsih_sas_device_add(ioc, sas_device);
@@ -5135,6 +5260,9 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
5135 if (sas_device_backup.starget && sas_device_backup.starget->hostdata) { 5260 if (sas_device_backup.starget && sas_device_backup.starget->hostdata) {
5136 sas_target_priv_data = sas_device_backup.starget->hostdata; 5261 sas_target_priv_data = sas_device_backup.starget->hostdata;
5137 sas_target_priv_data->deleted = 1; 5262 sas_target_priv_data->deleted = 1;
5263 _scsih_ublock_io_device(ioc, sas_device_backup.handle);
5264 sas_target_priv_data->handle =
5265 MPT2SAS_INVALID_DEVICE_HANDLE;
5138 } 5266 }
5139 5267
5140 _scsih_ublock_io_device(ioc, sas_device_backup.handle); 5268 _scsih_ublock_io_device(ioc, sas_device_backup.handle);
@@ -5288,7 +5416,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
5288 _scsih_sas_topology_change_event_debug(ioc, event_data); 5416 _scsih_sas_topology_change_event_debug(ioc, event_data);
5289#endif 5417#endif
5290 5418
5291 if (ioc->shost_recovery || ioc->remove_host || ioc->pci_error_recovery) 5419 if (ioc->remove_host || ioc->pci_error_recovery)
5292 return; 5420 return;
5293 5421
5294 if (!ioc->sas_hba.num_phys) 5422 if (!ioc->sas_hba.num_phys)
@@ -5349,6 +5477,9 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
5349 switch (reason_code) { 5477 switch (reason_code) {
5350 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 5478 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
5351 5479
5480 if (ioc->shost_recovery)
5481 break;
5482
5352 if (link_rate == prev_link_rate) 5483 if (link_rate == prev_link_rate)
5353 break; 5484 break;
5354 5485
@@ -5362,6 +5493,9 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
5362 break; 5493 break;
5363 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 5494 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
5364 5495
5496 if (ioc->shost_recovery)
5497 break;
5498
5365 mpt2sas_transport_update_links(ioc, sas_address, 5499 mpt2sas_transport_update_links(ioc, sas_address,
5366 handle, phy_number, link_rate); 5500 handle, phy_number, link_rate);
5367 5501
@@ -5622,7 +5756,7 @@ broadcast_aen_retry:
5622 termination_count = 0; 5756 termination_count = 0;
5623 query_count = 0; 5757 query_count = 0;
5624 for (smid = 1; smid <= ioc->scsiio_depth; smid++) { 5758 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
5625 if (ioc->ioc_reset_in_progress_status) 5759 if (ioc->shost_recovery)
5626 goto out; 5760 goto out;
5627 scmd = _scsih_scsi_lookup_get(ioc, smid); 5761 scmd = _scsih_scsi_lookup_get(ioc, smid);
5628 if (!scmd) 5762 if (!scmd)
@@ -5644,7 +5778,7 @@ broadcast_aen_retry:
5644 lun = sas_device_priv_data->lun; 5778 lun = sas_device_priv_data->lun;
5645 query_count++; 5779 query_count++;
5646 5780
5647 if (ioc->ioc_reset_in_progress_status) 5781 if (ioc->shost_recovery)
5648 goto out; 5782 goto out;
5649 5783
5650 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); 5784 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
@@ -5686,7 +5820,7 @@ broadcast_aen_retry:
5686 goto broadcast_aen_retry; 5820 goto broadcast_aen_retry;
5687 } 5821 }
5688 5822
5689 if (ioc->ioc_reset_in_progress_status) 5823 if (ioc->shost_recovery)
5690 goto out_no_lock; 5824 goto out_no_lock;
5691 5825
5692 r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id, 5826 r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
@@ -5725,7 +5859,7 @@ broadcast_aen_retry:
5725 ioc->name, __func__, query_count, termination_count)); 5859 ioc->name, __func__, query_count, termination_count));
5726 5860
5727 ioc->broadcast_aen_busy = 0; 5861 ioc->broadcast_aen_busy = 0;
5728 if (!ioc->ioc_reset_in_progress_status) 5862 if (!ioc->shost_recovery)
5729 _scsih_ublock_io_all_device(ioc); 5863 _scsih_ublock_io_all_device(ioc);
5730 mutex_unlock(&ioc->tm_cmds.mutex); 5864 mutex_unlock(&ioc->tm_cmds.mutex);
5731} 5865}
@@ -5789,8 +5923,11 @@ _scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach)
5789static void 5923static void
5790_scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach) 5924_scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach)
5791{ 5925{
5792 struct MPT2SAS_TARGET *sas_target_priv_data = starget->hostdata; 5926 struct MPT2SAS_TARGET *sas_target_priv_data;
5793 5927
5928 if (starget == NULL)
5929 return;
5930 sas_target_priv_data = starget->hostdata;
5794 if (no_uld_attach) 5931 if (no_uld_attach)
5795 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT; 5932 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
5796 else 5933 else
@@ -5845,7 +5982,7 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
5845 raid_device->handle = handle; 5982 raid_device->handle = handle;
5846 raid_device->wwid = wwid; 5983 raid_device->wwid = wwid;
5847 _scsih_raid_device_add(ioc, raid_device); 5984 _scsih_raid_device_add(ioc, raid_device);
5848 if (!ioc->wait_for_port_enable_to_complete) { 5985 if (!ioc->wait_for_discovery_to_complete) {
5849 rc = scsi_add_device(ioc->shost, RAID_CHANNEL, 5986 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
5850 raid_device->id, 0); 5987 raid_device->id, 0);
5851 if (rc) 5988 if (rc)
@@ -6127,6 +6264,10 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
6127 _scsih_sas_ir_config_change_event_debug(ioc, event_data); 6264 _scsih_sas_ir_config_change_event_debug(ioc, event_data);
6128 6265
6129#endif 6266#endif
6267
6268 if (ioc->shost_recovery)
6269 return;
6270
6130 foreign_config = (le32_to_cpu(event_data->Flags) & 6271 foreign_config = (le32_to_cpu(event_data->Flags) &
6131 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0; 6272 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
6132 6273
@@ -6185,6 +6326,9 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
6185 int rc; 6326 int rc;
6186 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data; 6327 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
6187 6328
6329 if (ioc->shost_recovery)
6330 return;
6331
6188 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED) 6332 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
6189 return; 6333 return;
6190 6334
@@ -6267,6 +6411,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
6267 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data; 6411 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
6268 u64 sas_address; 6412 u64 sas_address;
6269 6413
6414 if (ioc->shost_recovery)
6415 return;
6416
6270 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) 6417 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
6271 return; 6418 return;
6272 6419
@@ -6510,10 +6657,10 @@ _scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6510 u32 device_info; 6657 u32 device_info;
6511 u16 slot; 6658 u16 slot;
6512 6659
6513 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); 6660 printk(MPT2SAS_INFO_FMT "search for end-devices: start\n", ioc->name);
6514 6661
6515 if (list_empty(&ioc->sas_device_list)) 6662 if (list_empty(&ioc->sas_device_list))
6516 return; 6663 goto out;
6517 6664
6518 handle = 0xFFFF; 6665 handle = 0xFFFF;
6519 while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, 6666 while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
@@ -6532,6 +6679,9 @@ _scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6532 _scsih_mark_responding_sas_device(ioc, sas_address, slot, 6679 _scsih_mark_responding_sas_device(ioc, sas_address, slot,
6533 handle); 6680 handle);
6534 } 6681 }
6682out:
6683 printk(MPT2SAS_INFO_FMT "search for end-devices: complete\n",
6684 ioc->name);
6535} 6685}
6536 6686
6537/** 6687/**
@@ -6607,10 +6757,14 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
6607 u16 handle; 6757 u16 handle;
6608 u8 phys_disk_num; 6758 u8 phys_disk_num;
6609 6759
6610 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); 6760 if (!ioc->ir_firmware)
6761 return;
6762
6763 printk(MPT2SAS_INFO_FMT "search for raid volumes: start\n",
6764 ioc->name);
6611 6765
6612 if (list_empty(&ioc->raid_device_list)) 6766 if (list_empty(&ioc->raid_device_list))
6613 return; 6767 goto out;
6614 6768
6615 handle = 0xFFFF; 6769 handle = 0xFFFF;
6616 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, 6770 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
@@ -6649,6 +6803,9 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
6649 set_bit(handle, ioc->pd_handles); 6803 set_bit(handle, ioc->pd_handles);
6650 } 6804 }
6651 } 6805 }
6806out:
6807 printk(MPT2SAS_INFO_FMT "search for responding raid volumes: "
6808 "complete\n", ioc->name);
6652} 6809}
6653 6810
6654/** 6811/**
@@ -6708,10 +6865,10 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
6708 u64 sas_address; 6865 u64 sas_address;
6709 u16 handle; 6866 u16 handle;
6710 6867
6711 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); 6868 printk(MPT2SAS_INFO_FMT "search for expanders: start\n", ioc->name);
6712 6869
6713 if (list_empty(&ioc->sas_expander_list)) 6870 if (list_empty(&ioc->sas_expander_list))
6714 return; 6871 goto out;
6715 6872
6716 handle = 0xFFFF; 6873 handle = 0xFFFF;
6717 while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, 6874 while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
@@ -6730,6 +6887,8 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
6730 _scsih_mark_responding_expander(ioc, sas_address, handle); 6887 _scsih_mark_responding_expander(ioc, sas_address, handle);
6731 } 6888 }
6732 6889
6890 out:
6891 printk(MPT2SAS_INFO_FMT "search for expanders: complete\n", ioc->name);
6733} 6892}
6734 6893
6735/** 6894/**
@@ -6745,6 +6904,8 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6745 struct _sas_node *sas_expander; 6904 struct _sas_node *sas_expander;
6746 struct _raid_device *raid_device, *raid_device_next; 6905 struct _raid_device *raid_device, *raid_device_next;
6747 6906
6907 printk(MPT2SAS_INFO_FMT "removing unresponding devices: start\n",
6908 ioc->name);
6748 6909
6749 list_for_each_entry_safe(sas_device, sas_device_next, 6910 list_for_each_entry_safe(sas_device, sas_device_next,
6750 &ioc->sas_device_list, list) { 6911 &ioc->sas_device_list, list) {
@@ -6764,6 +6925,9 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6764 _scsih_remove_device(ioc, sas_device); 6925 _scsih_remove_device(ioc, sas_device);
6765 } 6926 }
6766 6927
6928 if (!ioc->ir_firmware)
6929 goto retry_expander_search;
6930
6767 list_for_each_entry_safe(raid_device, raid_device_next, 6931 list_for_each_entry_safe(raid_device, raid_device_next,
6768 &ioc->raid_device_list, list) { 6932 &ioc->raid_device_list, list) {
6769 if (raid_device->responding) { 6933 if (raid_device->responding) {
@@ -6790,52 +6954,170 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6790 mpt2sas_expander_remove(ioc, sas_expander->sas_address); 6954 mpt2sas_expander_remove(ioc, sas_expander->sas_address);
6791 goto retry_expander_search; 6955 goto retry_expander_search;
6792 } 6956 }
6957 printk(MPT2SAS_INFO_FMT "removing unresponding devices: complete\n",
6958 ioc->name);
6959 /* unblock devices */
6960 _scsih_ublock_io_all_device(ioc);
6961}
6962
6963static void
6964_scsih_refresh_expander_links(struct MPT2SAS_ADAPTER *ioc,
6965 struct _sas_node *sas_expander, u16 handle)
6966{
6967 Mpi2ExpanderPage1_t expander_pg1;
6968 Mpi2ConfigReply_t mpi_reply;
6969 int i;
6970
6971 for (i = 0 ; i < sas_expander->num_phys ; i++) {
6972 if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply,
6973 &expander_pg1, i, handle))) {
6974 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
6975 ioc->name, __FILE__, __LINE__, __func__);
6976 return;
6977 }
6978
6979 mpt2sas_transport_update_links(ioc, sas_expander->sas_address,
6980 le16_to_cpu(expander_pg1.AttachedDevHandle), i,
6981 expander_pg1.NegotiatedLinkRate >> 4);
6982 }
6793} 6983}
6794 6984
6795/** 6985/**
6796 * _scsih_hide_unhide_sas_devices - add/remove device to/from OS 6986 * _scsih_scan_for_devices_after_reset - scan for devices after host reset
6797 * @ioc: per adapter object 6987 * @ioc: per adapter object
6798 * 6988 *
6799 * Return nothing. 6989 * Return nothing.
6800 */ 6990 */
6801static void 6991static void
6802_scsih_hide_unhide_sas_devices(struct MPT2SAS_ADAPTER *ioc) 6992_scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
6803{ 6993{
6804 struct _sas_device *sas_device, *sas_device_next; 6994 Mpi2ExpanderPage0_t expander_pg0;
6995 Mpi2SasDevicePage0_t sas_device_pg0;
6996 Mpi2RaidVolPage1_t volume_pg1;
6997 Mpi2RaidVolPage0_t volume_pg0;
6998 Mpi2RaidPhysDiskPage0_t pd_pg0;
6999 Mpi2EventIrConfigElement_t element;
7000 Mpi2ConfigReply_t mpi_reply;
7001 u8 phys_disk_num;
7002 u16 ioc_status;
7003 u16 handle, parent_handle;
7004 u64 sas_address;
7005 struct _sas_device *sas_device;
7006 struct _sas_node *expander_device;
7007 static struct _raid_device *raid_device;
6805 7008
6806 if (!ioc->is_warpdrive || ioc->mfg_pg10_hide_flag != 7009 printk(MPT2SAS_INFO_FMT "scan devices: start\n", ioc->name);
6807 MFG_PAGE10_HIDE_IF_VOL_PRESENT)
6808 return;
6809 7010
6810 if (ioc->hide_drives) { 7011 _scsih_sas_host_refresh(ioc);
6811 if (_scsih_get_num_volumes(ioc)) 7012
6812 return; 7013 /* expanders */
6813 ioc->hide_drives = 0; 7014 handle = 0xFFFF;
6814 list_for_each_entry_safe(sas_device, sas_device_next, 7015 while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
6815 &ioc->sas_device_list, list) { 7016 MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
6816 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 7017 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6817 sas_device->sas_address_parent)) { 7018 MPI2_IOCSTATUS_MASK;
6818 _scsih_sas_device_remove(ioc, sas_device); 7019 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
6819 } else if (!sas_device->starget) { 7020 break;
6820 mpt2sas_transport_port_remove(ioc, 7021 handle = le16_to_cpu(expander_pg0.DevHandle);
6821 sas_device->sas_address, 7022 expander_device = mpt2sas_scsih_expander_find_by_sas_address(
6822 sas_device->sas_address_parent); 7023 ioc, le64_to_cpu(expander_pg0.SASAddress));
6823 _scsih_sas_device_remove(ioc, sas_device); 7024 if (expander_device)
6824 } 7025 _scsih_refresh_expander_links(ioc, expander_device,
7026 handle);
7027 else
7028 _scsih_expander_add(ioc, handle);
7029 }
7030
7031 if (!ioc->ir_firmware)
7032 goto skip_to_sas;
7033
7034 /* phys disk */
7035 phys_disk_num = 0xFF;
7036 while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
7037 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
7038 phys_disk_num))) {
7039 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7040 MPI2_IOCSTATUS_MASK;
7041 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7042 break;
7043 phys_disk_num = pd_pg0.PhysDiskNum;
7044 handle = le16_to_cpu(pd_pg0.DevHandle);
7045 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
7046 if (sas_device)
7047 continue;
7048 if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
7049 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
7050 handle) != 0)
7051 continue;
7052 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
7053 if (!_scsih_get_sas_address(ioc, parent_handle,
7054 &sas_address)) {
7055 mpt2sas_transport_update_links(ioc, sas_address,
7056 handle, sas_device_pg0.PhyNum,
7057 MPI2_SAS_NEG_LINK_RATE_1_5);
7058 set_bit(handle, ioc->pd_handles);
7059 _scsih_add_device(ioc, handle, 0, 1);
6825 } 7060 }
6826 } else { 7061 }
6827 if (!_scsih_get_num_volumes(ioc)) 7062
6828 return; 7063 /* volumes */
6829 ioc->hide_drives = 1; 7064 handle = 0xFFFF;
6830 list_for_each_entry_safe(sas_device, sas_device_next, 7065 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
6831 &ioc->sas_device_list, list) { 7066 &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
6832 mpt2sas_transport_port_remove(ioc, 7067 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6833 sas_device->sas_address, 7068 MPI2_IOCSTATUS_MASK;
6834 sas_device->sas_address_parent); 7069 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7070 break;
7071 handle = le16_to_cpu(volume_pg1.DevHandle);
7072 raid_device = _scsih_raid_device_find_by_wwid(ioc,
7073 le64_to_cpu(volume_pg1.WWID));
7074 if (raid_device)
7075 continue;
7076 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply,
7077 &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
7078 sizeof(Mpi2RaidVolPage0_t)))
7079 continue;
7080 if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL ||
7081 volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE ||
7082 volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) {
7083 memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t));
7084 element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED;
7085 element.VolDevHandle = volume_pg1.DevHandle;
7086 _scsih_sas_volume_add(ioc, &element);
7087 }
7088 }
7089
7090 skip_to_sas:
7091
7092 /* sas devices */
7093 handle = 0xFFFF;
7094 while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
7095 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
7096 handle))) {
7097 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7098 MPI2_IOCSTATUS_MASK;
7099 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7100 break;
7101 handle = le16_to_cpu(sas_device_pg0.DevHandle);
7102 if (!(_scsih_is_end_device(
7103 le32_to_cpu(sas_device_pg0.DeviceInfo))))
7104 continue;
7105 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
7106 le64_to_cpu(sas_device_pg0.SASAddress));
7107 if (sas_device)
7108 continue;
7109 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
7110 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) {
7111 mpt2sas_transport_update_links(ioc, sas_address, handle,
7112 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
7113 _scsih_add_device(ioc, handle, 0, 0);
6835 } 7114 }
6836 } 7115 }
7116
7117 printk(MPT2SAS_INFO_FMT "scan devices: complete\n", ioc->name);
6837} 7118}
6838 7119
7120
6839/** 7121/**
6840 * mpt2sas_scsih_reset_handler - reset callback handler (for scsih) 7122 * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
6841 * @ioc: per adapter object 7123 * @ioc: per adapter object
@@ -6871,7 +7153,6 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
6871 } 7153 }
6872 _scsih_fw_event_cleanup_queue(ioc); 7154 _scsih_fw_event_cleanup_queue(ioc);
6873 _scsih_flush_running_cmds(ioc); 7155 _scsih_flush_running_cmds(ioc);
6874 _scsih_queue_rescan(ioc);
6875 break; 7156 break;
6876 case MPT2_IOC_DONE_RESET: 7157 case MPT2_IOC_DONE_RESET:
6877 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " 7158 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
@@ -6881,6 +7162,13 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
6881 _scsih_search_responding_sas_devices(ioc); 7162 _scsih_search_responding_sas_devices(ioc);
6882 _scsih_search_responding_raid_devices(ioc); 7163 _scsih_search_responding_raid_devices(ioc);
6883 _scsih_search_responding_expanders(ioc); 7164 _scsih_search_responding_expanders(ioc);
7165 if (!ioc->is_driver_loading) {
7166 _scsih_prep_device_scan(ioc);
7167 _scsih_search_responding_sas_devices(ioc);
7168 _scsih_search_responding_raid_devices(ioc);
7169 _scsih_search_responding_expanders(ioc);
7170 _scsih_error_recovery_delete_devices(ioc);
7171 }
6884 break; 7172 break;
6885 } 7173 }
6886} 7174}
@@ -6898,7 +7186,6 @@ _firmware_event_work(struct work_struct *work)
6898{ 7186{
6899 struct fw_event_work *fw_event = container_of(work, 7187 struct fw_event_work *fw_event = container_of(work,
6900 struct fw_event_work, delayed_work.work); 7188 struct fw_event_work, delayed_work.work);
6901 unsigned long flags;
6902 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc; 7189 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
6903 7190
6904 /* the queue is being flushed so ignore this event */ 7191 /* the queue is being flushed so ignore this event */
@@ -6908,23 +7195,21 @@ _firmware_event_work(struct work_struct *work)
6908 return; 7195 return;
6909 } 7196 }
6910 7197
6911 if (fw_event->event == MPT2SAS_RESCAN_AFTER_HOST_RESET) { 7198 switch (fw_event->event) {
6912 _scsih_fw_event_free(ioc, fw_event); 7199 case MPT2SAS_REMOVE_UNRESPONDING_DEVICES:
6913 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 7200 while (scsi_host_in_recovery(ioc->shost))
6914 if (ioc->shost_recovery) { 7201 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); 7202 _scsih_remove_unresponding_sas_devices(ioc);
6923 _scsih_hide_unhide_sas_devices(ioc); 7203 _scsih_scan_for_devices_after_reset(ioc);
6924 return; 7204 break;
6925 } 7205 case MPT2SAS_PORT_ENABLE_COMPLETE:
7206 ioc->start_scan = 0;
6926 7207
6927 switch (fw_event->event) { 7208
7209
7210 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "port enable: complete "
7211 "from worker thread\n", ioc->name));
7212 break;
6928 case MPT2SAS_TURN_ON_FAULT_LED: 7213 case MPT2SAS_TURN_ON_FAULT_LED:
6929 _scsih_turn_on_fault_led(ioc, fw_event->device_handle); 7214 _scsih_turn_on_fault_led(ioc, fw_event->device_handle);
6930 break; 7215 break;
@@ -7121,6 +7406,8 @@ static struct scsi_host_template scsih_driver_template = {
7121 .slave_configure = _scsih_slave_configure, 7406 .slave_configure = _scsih_slave_configure,
7122 .target_destroy = _scsih_target_destroy, 7407 .target_destroy = _scsih_target_destroy,
7123 .slave_destroy = _scsih_slave_destroy, 7408 .slave_destroy = _scsih_slave_destroy,
7409 .scan_finished = _scsih_scan_finished,
7410 .scan_start = _scsih_scan_start,
7124 .change_queue_depth = _scsih_change_queue_depth, 7411 .change_queue_depth = _scsih_change_queue_depth,
7125 .change_queue_type = _scsih_change_queue_type, 7412 .change_queue_type = _scsih_change_queue_type,
7126 .eh_abort_handler = _scsih_abort, 7413 .eh_abort_handler = _scsih_abort,
@@ -7354,6 +7641,7 @@ _scsih_remove(struct pci_dev *pdev)
7354 } 7641 }
7355 7642
7356 sas_remove_host(shost); 7643 sas_remove_host(shost);
7644 mpt2sas_base_detach(ioc);
7357 list_del(&ioc->list); 7645 list_del(&ioc->list);
7358 scsi_remove_host(shost); 7646 scsi_remove_host(shost);
7359 scsi_host_put(shost); 7647 scsi_host_put(shost);
@@ -7380,7 +7668,12 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
7380 unsigned long flags; 7668 unsigned long flags;
7381 int rc; 7669 int rc;
7382 7670
7671 /* no Bios, return immediately */
7672 if (!ioc->bios_pg3.BiosVersion)
7673 return;
7674
7383 device = NULL; 7675 device = NULL;
7676 is_raid = 0;
7384 if (ioc->req_boot_device.device) { 7677 if (ioc->req_boot_device.device) {
7385 device = ioc->req_boot_device.device; 7678 device = ioc->req_boot_device.device;
7386 is_raid = ioc->req_boot_device.is_raid; 7679 is_raid = ioc->req_boot_device.is_raid;
@@ -7416,8 +7709,9 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
7416 sas_device->sas_address_parent)) { 7709 sas_device->sas_address_parent)) {
7417 _scsih_sas_device_remove(ioc, sas_device); 7710 _scsih_sas_device_remove(ioc, sas_device);
7418 } else if (!sas_device->starget) { 7711 } else if (!sas_device->starget) {
7419 mpt2sas_transport_port_remove(ioc, sas_address, 7712 if (!ioc->is_driver_loading)
7420 sas_address_parent); 7713 mpt2sas_transport_port_remove(ioc, sas_address,
7714 sas_address_parent);
7421 _scsih_sas_device_remove(ioc, sas_device); 7715 _scsih_sas_device_remove(ioc, sas_device);
7422 } 7716 }
7423 } 7717 }
@@ -7461,22 +7755,28 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
7461 /* SAS Device List */ 7755 /* SAS Device List */
7462 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, 7756 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
7463 list) { 7757 list) {
7464 spin_lock_irqsave(&ioc->sas_device_lock, flags);
7465 list_move_tail(&sas_device->list, &ioc->sas_device_list);
7466 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
7467 7758
7468 if (ioc->hide_drives) 7759 if (ioc->hide_drives)
7469 continue; 7760 continue;
7470 7761
7471 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 7762 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
7472 sas_device->sas_address_parent)) { 7763 sas_device->sas_address_parent)) {
7473 _scsih_sas_device_remove(ioc, sas_device); 7764 list_del(&sas_device->list);
7765 kfree(sas_device);
7766 continue;
7474 } else if (!sas_device->starget) { 7767 } else if (!sas_device->starget) {
7475 mpt2sas_transport_port_remove(ioc, 7768 if (!ioc->is_driver_loading)
7476 sas_device->sas_address, 7769 mpt2sas_transport_port_remove(ioc,
7477 sas_device->sas_address_parent); 7770 sas_device->sas_address,
7478 _scsih_sas_device_remove(ioc, sas_device); 7771 sas_device->sas_address_parent);
7772 list_del(&sas_device->list);
7773 kfree(sas_device);
7774 continue;
7775
7479 } 7776 }
7777 spin_lock_irqsave(&ioc->sas_device_lock, flags);
7778 list_move_tail(&sas_device->list, &ioc->sas_device_list);
7779 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
7480 } 7780 }
7481} 7781}
7482 7782
@@ -7489,9 +7789,7 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
7489static void 7789static void
7490_scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc) 7790_scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
7491{ 7791{
7492 u16 volume_mapping_flags = 7792 u16 volume_mapping_flags;
7493 le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
7494 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
7495 7793
7496 if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR)) 7794 if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR))
7497 return; /* return when IOC doesn't support initiator mode */ 7795 return; /* return when IOC doesn't support initiator mode */
@@ -7499,18 +7797,93 @@ _scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
7499 _scsih_probe_boot_devices(ioc); 7797 _scsih_probe_boot_devices(ioc);
7500 7798
7501 if (ioc->ir_firmware) { 7799 if (ioc->ir_firmware) {
7502 if ((volume_mapping_flags & 7800 volume_mapping_flags =
7503 MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING)) { 7801 le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
7504 _scsih_probe_sas(ioc); 7802 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
7803 if (volume_mapping_flags ==
7804 MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) {
7505 _scsih_probe_raid(ioc); 7805 _scsih_probe_raid(ioc);
7806 _scsih_probe_sas(ioc);
7506 } else { 7807 } else {
7507 _scsih_probe_raid(ioc);
7508 _scsih_probe_sas(ioc); 7808 _scsih_probe_sas(ioc);
7809 _scsih_probe_raid(ioc);
7509 } 7810 }
7510 } else 7811 } else
7511 _scsih_probe_sas(ioc); 7812 _scsih_probe_sas(ioc);
7512} 7813}
7513 7814
7815
7816/**
7817 * _scsih_scan_start - scsi lld callback for .scan_start
7818 * @shost: SCSI host pointer
7819 *
7820 * The shost has the ability to discover targets on its own instead
7821 * of scanning the entire bus. In our implemention, we will kick off
7822 * firmware discovery.
7823 */
7824static void
7825_scsih_scan_start(struct Scsi_Host *shost)
7826{
7827 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
7828 int rc;
7829
7830 if (diag_buffer_enable != -1 && diag_buffer_enable != 0)
7831 mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
7832
7833 ioc->start_scan = 1;
7834 rc = mpt2sas_port_enable(ioc);
7835
7836 if (rc != 0)
7837 printk(MPT2SAS_INFO_FMT "port enable: FAILED\n", ioc->name);
7838}
7839
7840/**
7841 * _scsih_scan_finished - scsi lld callback for .scan_finished
7842 * @shost: SCSI host pointer
7843 * @time: elapsed time of the scan in jiffies
7844 *
7845 * This function will be called periodically until it returns 1 with the
7846 * scsi_host and the elapsed time of the scan in jiffies. In our implemention,
7847 * we wait for firmware discovery to complete, then return 1.
7848 */
7849static int
7850_scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
7851{
7852 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
7853
7854 if (time >= (300 * HZ)) {
7855 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
7856 printk(MPT2SAS_INFO_FMT "port enable: FAILED with timeout "
7857 "(timeout=300s)\n", ioc->name);
7858 ioc->is_driver_loading = 0;
7859 return 1;
7860 }
7861
7862 if (ioc->start_scan)
7863 return 0;
7864
7865 if (ioc->start_scan_failed) {
7866 printk(MPT2SAS_INFO_FMT "port enable: FAILED with "
7867 "(ioc_status=0x%08x)\n", ioc->name, ioc->start_scan_failed);
7868 ioc->is_driver_loading = 0;
7869 ioc->wait_for_discovery_to_complete = 0;
7870 ioc->remove_host = 1;
7871 return 1;
7872 }
7873
7874 printk(MPT2SAS_INFO_FMT "port enable: SUCCESS\n", ioc->name);
7875 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
7876
7877 if (ioc->wait_for_discovery_to_complete) {
7878 ioc->wait_for_discovery_to_complete = 0;
7879 _scsih_probe_devices(ioc);
7880 }
7881 mpt2sas_base_start_watchdog(ioc);
7882 ioc->is_driver_loading = 0;
7883 return 1;
7884}
7885
7886
7514/** 7887/**
7515 * _scsih_probe - attach and add scsi host 7888 * _scsih_probe - attach and add scsi host
7516 * @pdev: PCI device struct 7889 * @pdev: PCI device struct
@@ -7547,6 +7920,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
7547 ioc->tm_cb_idx = tm_cb_idx; 7920 ioc->tm_cb_idx = tm_cb_idx;
7548 ioc->ctl_cb_idx = ctl_cb_idx; 7921 ioc->ctl_cb_idx = ctl_cb_idx;
7549 ioc->base_cb_idx = base_cb_idx; 7922 ioc->base_cb_idx = base_cb_idx;
7923 ioc->port_enable_cb_idx = port_enable_cb_idx;
7550 ioc->transport_cb_idx = transport_cb_idx; 7924 ioc->transport_cb_idx = transport_cb_idx;
7551 ioc->scsih_cb_idx = scsih_cb_idx; 7925 ioc->scsih_cb_idx = scsih_cb_idx;
7552 ioc->config_cb_idx = config_cb_idx; 7926 ioc->config_cb_idx = config_cb_idx;
@@ -7619,14 +7993,14 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
7619 goto out_thread_fail; 7993 goto out_thread_fail;
7620 } 7994 }
7621 7995
7622 ioc->wait_for_port_enable_to_complete = 1; 7996 ioc->is_driver_loading = 1;
7623 if ((mpt2sas_base_attach(ioc))) { 7997 if ((mpt2sas_base_attach(ioc))) {
7624 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 7998 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
7625 ioc->name, __FILE__, __LINE__, __func__); 7999 ioc->name, __FILE__, __LINE__, __func__);
7626 goto out_attach_fail; 8000 goto out_attach_fail;
7627 } 8001 }
7628 8002
7629 ioc->wait_for_port_enable_to_complete = 0; 8003 scsi_scan_host(shost);
7630 if (ioc->is_warpdrive) { 8004 if (ioc->is_warpdrive) {
7631 if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) 8005 if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS)
7632 ioc->hide_drives = 0; 8006 ioc->hide_drives = 0;
@@ -7649,6 +8023,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
7649 out_thread_fail: 8023 out_thread_fail:
7650 list_del(&ioc->list); 8024 list_del(&ioc->list);
7651 scsi_remove_host(shost); 8025 scsi_remove_host(shost);
8026 scsi_host_put(shost);
7652 out_add_shost_fail: 8027 out_add_shost_fail:
7653 return -ENODEV; 8028 return -ENODEV;
7654} 8029}
@@ -7895,6 +8270,8 @@ _scsih_init(void)
7895 8270
7896 /* base internal commands callback handler */ 8271 /* base internal commands callback handler */
7897 base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done); 8272 base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done);
8273 port_enable_cb_idx = mpt2sas_base_register_callback_handler(
8274 mpt2sas_port_enable_done);
7898 8275
7899 /* transport internal commands callback handler */ 8276 /* transport internal commands callback handler */
7900 transport_cb_idx = mpt2sas_base_register_callback_handler( 8277 transport_cb_idx = mpt2sas_base_register_callback_handler(
@@ -7949,6 +8326,7 @@ _scsih_exit(void)
7949 mpt2sas_base_release_callback_handler(scsi_io_cb_idx); 8326 mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
7950 mpt2sas_base_release_callback_handler(tm_cb_idx); 8327 mpt2sas_base_release_callback_handler(tm_cb_idx);
7951 mpt2sas_base_release_callback_handler(base_cb_idx); 8328 mpt2sas_base_release_callback_handler(base_cb_idx);
8329 mpt2sas_base_release_callback_handler(port_enable_cb_idx);
7952 mpt2sas_base_release_callback_handler(transport_cb_idx); 8330 mpt2sas_base_release_callback_handler(transport_cb_idx);
7953 mpt2sas_base_release_callback_handler(scsih_cb_idx); 8331 mpt2sas_base_release_callback_handler(scsih_cb_idx);
7954 mpt2sas_base_release_callback_handler(config_cb_idx); 8332 mpt2sas_base_release_callback_handler(config_cb_idx);