]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
[SCSI] hpsa: hide logical drives with format in progress from linux
authorStephen M. Cameron <scameron@beardog.cce.hp.com>
Mon, 23 Sep 2013 18:34:01 +0000 (13:34 -0500)
committerJames Bottomley <JBottomley@Parallels.com>
Mon, 16 Dec 2013 18:57:53 +0000 (10:57 -0800)
SCSI mid layer doesn't seem to handle logical drives undergoing format
very well.  scsi_add_device on such devices seems to result in hitting
those devices with a TUR at a rate of 3Hz for awhile, transitioning
to hitting them with a READ(10) at a much higher rate indefinitely,
and at boot time, this prevents the system from coming up.  If we
do not expose such devices to the kernel, it isn't bothered by them.

Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/hpsa.c
drivers/scsi/hpsa.h

index 6cc91f83aa699b6cc9be0559c3ac7f8af4d351be..0085eff4b39d10433e0a368cdff6b507972d1706 100644 (file)
@@ -1010,6 +1010,20 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
        for (i = 0; i < nsds; i++) {
                if (!sd[i]) /* if already added above. */
                        continue;
+
+               /* Don't add devices which are NOT READY, FORMAT IN PROGRESS
+                * as the SCSI mid-layer does not handle such devices well.
+                * It relentlessly loops sending TUR at 3Hz, then READ(10)
+                * at 160Hz, and prevents the system from coming up.
+                */
+               if (sd[i]->format_in_progress) {
+                       dev_info(&h->pdev->dev,
+                               "Logical drive format in progress, device c%db%dt%dl%d offline.\n",
+                               h->scsi_host->host_no,
+                               sd[i]->bus, sd[i]->target, sd[i]->lun);
+                       continue;
+               }
+
                device_change = hpsa_scsi_find_entry(sd[i], h->dev,
                                        h->ndevices, &entry);
                if (device_change == DEVICE_NOT_FOUND) {
@@ -1715,6 +1729,34 @@ static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device,
        device->lun = lun;
 }
 
+static unsigned char hpsa_format_in_progress(struct ctlr_info *h,
+               unsigned char scsi3addr[])
+{
+       struct CommandList *c;
+       unsigned char *sense, sense_key, asc, ascq;
+#define ASC_LUN_NOT_READY 0x04
+#define ASCQ_LUN_NOT_READY_FORMAT_IN_PROGRESS 0x04
+
+
+       c = cmd_special_alloc(h);
+       if (!c)
+               return 0;
+       fill_cmd(c, TEST_UNIT_READY, h, NULL, 0, 0, scsi3addr, TYPE_CMD);
+       hpsa_scsi_do_simple_cmd_core(h, c);
+       sense = c->err_info->SenseInfo;
+       sense_key = sense[2];
+       asc = sense[12];
+       ascq = sense[13];
+       if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
+               c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION &&
+               sense_key == NOT_READY &&
+               asc == ASC_LUN_NOT_READY &&
+               ascq == ASCQ_LUN_NOT_READY_FORMAT_IN_PROGRESS)
+               return 1;
+       cmd_special_free(h, c);
+       return 0;
+}
+
 static int hpsa_update_device_info(struct ctlr_info *h,
        unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device,
        unsigned char *is_OBDR_device)
@@ -1753,10 +1795,14 @@ static int hpsa_update_device_info(struct ctlr_info *h,
                sizeof(this_device->device_id));
 
        if (this_device->devtype == TYPE_DISK &&
-               is_logical_dev_addr_mode(scsi3addr))
+               is_logical_dev_addr_mode(scsi3addr)) {
                hpsa_get_raid_level(h, scsi3addr, &this_device->raid_level);
-       else
+               this_device->format_in_progress =
+                       hpsa_format_in_progress(h, scsi3addr);
+       } else {
                this_device->raid_level = RAID_UNKNOWN;
+               this_device->format_in_progress = 0;
+       }
 
        if (is_OBDR_device) {
                /* See if this is a One-Button-Disaster-Recovery device
index bc85e7244f4049530ade90c558815b25d9ecce4e..4fd0d45296b499bb9e3f3f580cd0353923c0c0db 100644 (file)
@@ -46,6 +46,7 @@ struct hpsa_scsi_dev_t {
        unsigned char vendor[8];        /* bytes 8-15 of inquiry data */
        unsigned char model[16];        /* bytes 16-31 of inquiry data */
        unsigned char raid_level;       /* from inquiry page 0xC1 */
+       unsigned char format_in_progress;
 };
 
 struct reply_pool {