diff options
Diffstat (limited to 'drivers/scsi/device_handler/scsi_dh_alua.c')
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_alua.c | 107 |
1 files changed, 25 insertions, 82 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 6fec9fe5dc39..627f4b5e5176 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -128,43 +128,6 @@ static struct request *get_alua_req(struct scsi_device *sdev, } /* - * submit_std_inquiry - Issue a standard INQUIRY command - * @sdev: sdev the command should be send to - */ -static int submit_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) -{ - struct request *rq; - int err = SCSI_DH_RES_TEMP_UNAVAIL; - - rq = get_alua_req(sdev, h->inq, ALUA_INQUIRY_SIZE, READ); - if (!rq) - goto done; - - /* Prepare the command. */ - rq->cmd[0] = INQUIRY; - rq->cmd[1] = 0; - rq->cmd[2] = 0; - rq->cmd[4] = ALUA_INQUIRY_SIZE; - rq->cmd_len = COMMAND_SIZE(INQUIRY); - - rq->sense = h->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = h->senselen = 0; - - err = blk_execute_rq(rq->q, NULL, rq, 1); - if (err == -EIO) { - sdev_printk(KERN_INFO, sdev, - "%s: std inquiry failed with %x\n", - ALUA_DH_NAME, rq->errors); - h->senselen = rq->sense_len; - err = SCSI_DH_IO; - } - blk_put_request(rq); -done: - return err; -} - -/* * submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command * @sdev: sdev the command should be sent to */ @@ -338,23 +301,17 @@ static unsigned submit_stpg(struct alua_dh_data *h) } /* - * alua_std_inquiry - Evaluate standard INQUIRY command + * alua_check_tpgs - Evaluate TPGS setting * @sdev: device to be checked * - * Just extract the TPGS setting to find out if ALUA + * Examine the TPGS setting of the sdev to find out if ALUA * is supported. */ -static int alua_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) +static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) { - int err; - - err = submit_std_inquiry(sdev, h); - - if (err != SCSI_DH_OK) - return err; + int err = SCSI_DH_OK; - /* Check TPGS setting */ - h->tpgs = (h->inq[5] >> 4) & 0x3; + h->tpgs = scsi_device_tpgs(sdev); switch (h->tpgs) { case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT: sdev_printk(KERN_INFO, sdev, @@ -508,27 +465,28 @@ static int alua_check_sense(struct scsi_device *sdev, * Power On, Reset, or Bus Device Reset, just retry. */ return ADD_TO_MLQUEUE; - if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) { + if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) /* * ALUA state changed */ return ADD_TO_MLQUEUE; - } - if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) { + if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) /* * Implicit ALUA state transition failed */ return ADD_TO_MLQUEUE; - } - if (sense_hdr->asc == 0x3f && sense_hdr->ascq == 0x0e) { + if (sense_hdr->asc == 0x3f && sense_hdr->ascq == 0x03) + /* + * Inquiry data has changed + */ + return ADD_TO_MLQUEUE; + if (sense_hdr->asc == 0x3f && sense_hdr->ascq == 0x0e) /* * REPORTED_LUNS_DATA_HAS_CHANGED is reported * when switching controllers on targets like * Intel Multi-Flex. We can just retry. */ return ADD_TO_MLQUEUE; - } - break; } @@ -547,9 +505,9 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) { struct scsi_sense_hdr sense_hdr; int len, k, off, valid_states = 0; - char *ucp; + unsigned char *ucp; unsigned err; - unsigned long expiry, interval = 10; + unsigned long expiry, interval = 1; expiry = round_jiffies_up(jiffies + ALUA_FAILOVER_TIMEOUT); retry: @@ -610,7 +568,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) case TPGS_STATE_TRANSITIONING: if (time_before(jiffies, expiry)) { /* State transition, retry */ - interval *= 10; + interval *= 2; msleep(interval); goto retry; } @@ -642,7 +600,7 @@ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h) { int err; - err = alua_std_inquiry(sdev, h); + err = alua_check_tpgs(sdev, h); if (err != SCSI_DH_OK) goto out; @@ -674,11 +632,9 @@ static int alua_activate(struct scsi_device *sdev, struct alua_dh_data *h = get_alua_data(sdev); int err = SCSI_DH_OK; - if (h->group_id != -1) { - err = alua_rtpg(sdev, h); - if (err != SCSI_DH_OK) - goto out; - } + err = alua_rtpg(sdev, h); + if (err != SCSI_DH_OK) + goto out; if (h->tpgs & TPGS_MODE_EXPLICIT && h->state != TPGS_STATE_OPTIMIZED && @@ -720,23 +676,10 @@ static int alua_prep_fn(struct scsi_device *sdev, struct request *req) } -static const struct scsi_dh_devlist alua_dev_list[] = { - {"HP", "MSA VOLUME" }, - {"HP", "HSV101" }, - {"HP", "HSV111" }, - {"HP", "HSV200" }, - {"HP", "HSV210" }, - {"HP", "HSV300" }, - {"IBM", "2107900" }, - {"IBM", "2145" }, - {"Pillar", "Axiom" }, - {"Intel", "Multi-Flex"}, - {"NETAPP", "LUN"}, - {"NETAPP", "LUN C-Mode"}, - {"AIX", "NVDISK"}, - {"Promise", "VTrak"}, - {NULL, NULL} -}; +static bool alua_match(struct scsi_device *sdev) +{ + return (scsi_device_tpgs(sdev) != 0); +} static int alua_bus_attach(struct scsi_device *sdev); static void alua_bus_detach(struct scsi_device *sdev); @@ -744,12 +687,12 @@ static void alua_bus_detach(struct scsi_device *sdev); static struct scsi_device_handler alua_dh = { .name = ALUA_DH_NAME, .module = THIS_MODULE, - .devlist = alua_dev_list, .attach = alua_bus_attach, .detach = alua_bus_detach, .prep_fn = alua_prep_fn, .check_sense = alua_check_sense, .activate = alua_activate, + .match = alua_match, }; /* |