summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hpsa.c
diff options
context:
space:
mode:
authorBader Ali Saleh <bader.alisaleh@microsemi.com>2017-10-20 16:51:32 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2017-10-25 04:55:18 -0400
commit4e1881840933587f42e3ad3788f2c392d19827a6 (patch)
treeaf71cfb020f8099f5d1a3f1c4faa8a0540b04c69 /drivers/scsi/hpsa.c
parentb9b08cade0a6a523c185c5e371f05df63c623c34 (diff)
downloadlinux-4e1881840933587f42e3ad3788f2c392d19827a6.tar.gz
linux-4e1881840933587f42e3ad3788f2c392d19827a6.tar.bz2
linux-4e1881840933587f42e3ad3788f2c392d19827a6.zip
scsi: hpsa: update discovery polling
Correct a corner case where newly created volumes are not detected automatically on an external RAID controller that has no configured volumes during initial device discovery. The fix is to set the discovery_polling flag when an external RAID controller is detected. This causes a device rescan every 20-30 seconds, so that newly created volumes will be detected automatically. Reviewed-by: Scott Benesh <scott.benesh@microsemi.com> Reviewed-by: Scott Teel <scott.teel@microsemi.com> Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com> Signed-off-by: Don Brace <don.brace@microsemi.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r--drivers/scsi/hpsa.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9c491c507092..6056bbdbfcaa 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3472,6 +3472,30 @@ static void hpsa_get_sas_address(struct ctlr_info *h, unsigned char *scsi3addr,
dev->sas_address = sa;
}
+static void hpsa_ext_ctrl_present(struct ctlr_info *h,
+ struct ReportExtendedLUNdata *physdev)
+{
+ u32 nphysicals;
+ int i;
+
+ if (h->discovery_polling)
+ return;
+
+ nphysicals = (get_unaligned_be32(physdev->LUNListLength) / 24) + 1;
+
+ for (i = 0; i < nphysicals; i++) {
+ if (physdev->LUN[i].device_type ==
+ BMIC_DEVICE_TYPE_CONTROLLER
+ && !is_hba_lunid(physdev->LUN[i].lunid)) {
+ dev_info(&h->pdev->dev,
+ "External controller present, activate discovery polling and disable rld caching\n");
+ hpsa_disable_rld_caching(h);
+ h->discovery_polling = 1;
+ break;
+ }
+ }
+}
+
/* Get a device id from inquiry page 0x83 */
static bool hpsa_vpd_page_supported(struct ctlr_info *h,
unsigned char scsi3addr[], u8 page)
@@ -4228,6 +4252,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
*/
ndevs_to_allocate = nphysicals + nlogicals + MAX_EXT_TARGETS + 1;
+ hpsa_ext_ctrl_present(h, physdev_list);
+
/* Allocate the per device structures */
for (i = 0; i < ndevs_to_allocate; i++) {
if (i >= HPSA_MAX_DEVICES) {
@@ -4298,18 +4324,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
figure_bus_target_lun(h, lunaddrbytes, tmpdevice);
this_device = currentsd[ncurrent];
- /* Turn on discovery_polling if there are ext target devices.
- * Event-based change notification is unreliable for those.
- */
- if (!h->discovery_polling) {
- if (tmpdevice->external) {
- h->discovery_polling = 1;
- dev_info(&h->pdev->dev,
- "External target, activate discovery polling.\n");
- }
- }
-
-
*this_device = *tmpdevice;
this_device->physical_device = physical_device;
@@ -8247,7 +8261,6 @@ static void hpsa_rescan_ctlr_worker(struct work_struct *work)
if (h->drv_req_rescan || hpsa_offline_devices_ready(h)) {
hpsa_perform_rescan(h);
} else if (h->discovery_polling) {
- hpsa_disable_rld_caching(h);
if (hpsa_luns_changed(h)) {
dev_info(&h->pdev->dev,
"driver discovery polling rescan.\n");