diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 642 |
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 | ||
73 | static u8 _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid); | 72 | static u8 _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid); |
74 | 73 | ||
74 | static void _scsih_scan_start(struct Scsi_Host *shost); | ||
75 | static int _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time); | ||
76 | |||
75 | /* global parameters */ | 77 | /* global parameters */ |
76 | LIST_HEAD(mpt2sas_ioc_list); | 78 | LIST_HEAD(mpt2sas_ioc_list); |
77 | 79 | ||
@@ -80,6 +82,7 @@ static u8 scsi_io_cb_idx = -1; | |||
80 | static u8 tm_cb_idx = -1; | 82 | static u8 tm_cb_idx = -1; |
81 | static u8 ctl_cb_idx = -1; | 83 | static u8 ctl_cb_idx = -1; |
82 | static u8 base_cb_idx = -1; | 84 | static u8 base_cb_idx = -1; |
85 | static u8 port_enable_cb_idx = -1; | ||
83 | static u8 transport_cb_idx = -1; | 86 | static u8 transport_cb_idx = -1; |
84 | static u8 scsih_cb_idx = -1; | 87 | static u8 scsih_cb_idx = -1; |
85 | static u8 config_cb_idx = -1; | 88 | static u8 config_cb_idx = -1; |
@@ -104,6 +107,18 @@ static int max_lun = MPT2SAS_MAX_LUN; | |||
104 | module_param(max_lun, int, 0); | 107 | module_param(max_lun, int, 0); |
105 | MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); | 108 | MODULE_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 | */ | ||
117 | static int diag_buffer_enable = -1; | ||
118 | module_param(diag_buffer_enable, int, 0); | ||
119 | MODULE_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 | */ |
1603 | static void | 1651 | static 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 | */ |
2722 | static void | 2798 | static 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 | */ | ||
2821 | void | ||
2822 | mpt2sas_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) | |||
5789 | static void | 5923 | static 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 | } |
6682 | out: | ||
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 | } |
6806 | out: | ||
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 | |||
6963 | static 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 | */ |
6801 | static void | 6991 | static 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) | |||
7489 | static void | 7789 | static 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 | */ | ||
7824 | static 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 | */ | ||
7849 | static 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); |