hpsa: allow driver requested rescans
authorDon Brace <don.brace@pmcs.com>
Wed, 4 Nov 2015 21:50:37 +0000 (15:50 -0600)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 9 Nov 2015 17:34:19 +0000 (12:34 -0500)
Reviewed-by: Scott Teel <scott.teel@pmcs.com>
Reviewed-by: Justin Lindley <justin.lindley@pmcs.com>
Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Reviewed-by; Hannes Reinecke <hare@suse.de>
Signed-off-by: Don Brace <don.brace@pmcs.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/hpsa.c
drivers/scsi/hpsa.h

index 446816664335c1fc87c319a7bba50e533a455de5..f010b8ec1a2048dd2492cc425b846c7e952594ab 100644 (file)
@@ -1810,6 +1810,7 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h,
                 * since it didn't get added to scsi mid layer
                 */
                fixup_botched_add(h, added[i]);
+               h->drv_req_rescan = 1;
        }
 
 free_and_out:
@@ -3751,9 +3752,13 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
        }
        memset(lunzerobits, 0, sizeof(lunzerobits));
 
+       h->drv_req_rescan = 0; /* cancel scheduled rescan - we're doing it. */
+
        if (hpsa_gather_lun_info(h, physdev_list, &nphysicals,
-                       logdev_list, &nlogicals))
+                       logdev_list, &nlogicals)) {
+               h->drv_req_rescan = 1;
                goto out;
+       }
 
        /* We might see up to the maximum number of logical and physical disks
         * plus external target devices, and a device for the local RAID
@@ -3774,6 +3779,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
                if (!currentsd[i]) {
                        dev_warn(&h->pdev->dev, "out of memory at %s:%d\n",
                                __FILE__, __LINE__);
+                       h->drv_req_rescan = 1;
                        goto out;
                }
                ndev_allocated++;
@@ -3801,8 +3807,10 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
 
                /* Get device type, vendor, model, device id */
                if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice,
-                                                       &is_OBDR))
+                                                       &is_OBDR)) {
+                       h->drv_req_rescan = 1;
                        continue; /* skip it if we can't talk to it. */
+               }
                figure_bus_target_lun(h, lunaddrbytes, tmpdevice);
                hpsa_update_device_supports_aborts(h, tmpdevice, lunaddrbytes);
                this_device = currentsd[ncurrent];
@@ -7862,6 +7870,11 @@ static void hpsa_ack_ctlr_events(struct ctlr_info *h)
  */
 static int hpsa_ctlr_needs_rescan(struct ctlr_info *h)
 {
+       if (h->drv_req_rescan) {
+               h->drv_req_rescan = 0;
+               return 1;
+       }
+
        if (!(h->fw_support & MISC_FW_EVENT_NOTIFY))
                return 0;
 
index d6c4ebf91547209b720c013c5760e7e99e650342..b173c0ee92628912815930c2859414d487a7134b 100644 (file)
@@ -262,6 +262,7 @@ struct ctlr_info {
        spinlock_t offline_device_lock;
        struct list_head offline_device_list;
        int     acciopath_status;
+       int     drv_req_rescan;
        int     raid_offload_debug;
        int     needs_abort_tags_swizzled;
        struct workqueue_struct *resubmit_wq;