Skip to content

Commit b78205c

Browse files
hreineckeaxboe
authored andcommitted
scsi_dh_emc: switch to scsi_execute_req_flags()
Switch to scsi_execute_req_flags() and scsi_get_vpd_page() instead of open-coding it. Using scsi_execute_req_flags() will set REQ_QUIET and REQ_PREEMPT, but this is okay as we're evaluating the errors anyway and should be able to send the command even if the device is quiesced. Signed-off-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Jens Axboe <axboe@fb.com>
1 parent 3278255 commit b78205c

File tree

1 file changed

+56
-191
lines changed

1 file changed

+56
-191
lines changed

drivers/scsi/device_handler/scsi_dh_emc.c

Lines changed: 56 additions & 191 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,6 @@ struct clariion_dh_data {
8787
* I/O buffer for both MODE_SELECT and INQUIRY commands.
8888
*/
8989
unsigned char buffer[CLARIION_BUFFER_SIZE];
90-
/*
91-
* SCSI sense buffer for commands -- assumes serial issuance
92-
* and completion sequence of all commands for same multipath.
93-
*/
94-
unsigned char sense[SCSI_SENSE_BUFFERSIZE];
95-
unsigned int senselen;
9690
/*
9791
* LUN state
9892
*/
@@ -116,44 +110,38 @@ struct clariion_dh_data {
116110
/*
117111
* Parse MODE_SELECT cmd reply.
118112
*/
119-
static int trespass_endio(struct scsi_device *sdev, char *sense)
113+
static int trespass_endio(struct scsi_device *sdev,
114+
struct scsi_sense_hdr *sshdr)
120115
{
121116
int err = SCSI_DH_IO;
122-
struct scsi_sense_hdr sshdr;
123-
124-
if (!scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) {
125-
sdev_printk(KERN_ERR, sdev, "%s: Found valid sense data 0x%2x, "
126-
"0x%2x, 0x%2x while sending CLARiiON trespass "
127-
"command.\n", CLARIION_NAME, sshdr.sense_key,
128-
sshdr.asc, sshdr.ascq);
129117

130-
if ((sshdr.sense_key == 0x05) && (sshdr.asc == 0x04) &&
131-
(sshdr.ascq == 0x00)) {
132-
/*
133-
* Array based copy in progress -- do not send
134-
* mode_select or copy will be aborted mid-stream.
135-
*/
136-
sdev_printk(KERN_INFO, sdev, "%s: Array Based Copy in "
137-
"progress while sending CLARiiON trespass "
138-
"command.\n", CLARIION_NAME);
139-
err = SCSI_DH_DEV_TEMP_BUSY;
140-
} else if ((sshdr.sense_key == 0x02) && (sshdr.asc == 0x04) &&
141-
(sshdr.ascq == 0x03)) {
142-
/*
143-
* LUN Not Ready - Manual Intervention Required
144-
* indicates in-progress ucode upgrade (NDU).
145-
*/
146-
sdev_printk(KERN_INFO, sdev, "%s: Detected in-progress "
147-
"ucode upgrade NDU operation while sending "
148-
"CLARiiON trespass command.\n", CLARIION_NAME);
149-
err = SCSI_DH_DEV_TEMP_BUSY;
150-
} else
151-
err = SCSI_DH_DEV_FAILED;
152-
} else {
153-
sdev_printk(KERN_INFO, sdev,
154-
"%s: failed to send MODE SELECT, no sense available\n",
155-
CLARIION_NAME);
156-
}
118+
sdev_printk(KERN_ERR, sdev, "%s: Found valid sense data 0x%2x, "
119+
"0x%2x, 0x%2x while sending CLARiiON trespass "
120+
"command.\n", CLARIION_NAME, sshdr->sense_key,
121+
sshdr->asc, sshdr->ascq);
122+
123+
if (sshdr->sense_key == 0x05 && sshdr->asc == 0x04 &&
124+
sshdr->ascq == 0x00) {
125+
/*
126+
* Array based copy in progress -- do not send
127+
* mode_select or copy will be aborted mid-stream.
128+
*/
129+
sdev_printk(KERN_INFO, sdev, "%s: Array Based Copy in "
130+
"progress while sending CLARiiON trespass "
131+
"command.\n", CLARIION_NAME);
132+
err = SCSI_DH_DEV_TEMP_BUSY;
133+
} else if (sshdr->sense_key == 0x02 && sshdr->asc == 0x04 &&
134+
sshdr->ascq == 0x03) {
135+
/*
136+
* LUN Not Ready - Manual Intervention Required
137+
* indicates in-progress ucode upgrade (NDU).
138+
*/
139+
sdev_printk(KERN_INFO, sdev, "%s: Detected in-progress "
140+
"ucode upgrade NDU operation while sending "
141+
"CLARiiON trespass command.\n", CLARIION_NAME);
142+
err = SCSI_DH_DEV_TEMP_BUSY;
143+
} else
144+
err = SCSI_DH_DEV_FAILED;
157145
return err;
158146
}
159147

@@ -257,144 +245,53 @@ static char * parse_sp_model(struct scsi_device *sdev, unsigned char *buffer)
257245
return sp_model;
258246
}
259247

260-
/*
261-
* Get block request for REQ_BLOCK_PC command issued to path. Currently
262-
* limited to MODE_SELECT (trespass) and INQUIRY (VPD page 0xC0) commands.
263-
*
264-
* Uses data and sense buffers in hardware handler context structure and
265-
* assumes serial servicing of commands, both issuance and completion.
266-
*/
267-
static struct request *get_req(struct scsi_device *sdev, int cmd,
268-
unsigned char *buffer)
269-
{
270-
struct request *rq;
271-
int len = 0;
272-
273-
rq = blk_get_request(sdev->request_queue,
274-
(cmd != INQUIRY) ? WRITE : READ, GFP_NOIO);
275-
if (IS_ERR(rq)) {
276-
sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed");
277-
return NULL;
278-
}
279-
280-
blk_rq_set_block_pc(rq);
281-
rq->cmd_len = COMMAND_SIZE(cmd);
282-
rq->cmd[0] = cmd;
283-
284-
switch (cmd) {
285-
case MODE_SELECT:
286-
len = sizeof(short_trespass);
287-
rq->cmd[1] = 0x10;
288-
rq->cmd[4] = len;
289-
break;
290-
case MODE_SELECT_10:
291-
len = sizeof(long_trespass);
292-
rq->cmd[1] = 0x10;
293-
rq->cmd[8] = len;
294-
break;
295-
case INQUIRY:
296-
len = CLARIION_BUFFER_SIZE;
297-
rq->cmd[4] = len;
298-
memset(buffer, 0, len);
299-
break;
300-
default:
301-
BUG_ON(1);
302-
break;
303-
}
304-
305-
rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
306-
REQ_FAILFAST_DRIVER;
307-
rq->timeout = CLARIION_TIMEOUT;
308-
rq->retries = CLARIION_RETRIES;
309-
310-
if (blk_rq_map_kern(rq->q, rq, buffer, len, GFP_NOIO)) {
311-
blk_put_request(rq);
312-
return NULL;
313-
}
314-
315-
return rq;
316-
}
317-
318-
static int send_inquiry_cmd(struct scsi_device *sdev, int page,
319-
struct clariion_dh_data *csdev)
320-
{
321-
struct request *rq = get_req(sdev, INQUIRY, csdev->buffer);
322-
int err;
323-
324-
if (!rq)
325-
return SCSI_DH_RES_TEMP_UNAVAIL;
326-
327-
rq->sense = csdev->sense;
328-
memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
329-
rq->sense_len = csdev->senselen = 0;
330-
331-
rq->cmd[0] = INQUIRY;
332-
if (page != 0) {
333-
rq->cmd[1] = 1;
334-
rq->cmd[2] = page;
335-
}
336-
err = blk_execute_rq(sdev->request_queue, NULL, rq, 1);
337-
if (err == -EIO) {
338-
sdev_printk(KERN_INFO, sdev,
339-
"%s: failed to send %s INQUIRY: %x\n",
340-
CLARIION_NAME, page?"EVPD":"standard",
341-
rq->errors);
342-
csdev->senselen = rq->sense_len;
343-
err = SCSI_DH_IO;
344-
}
345-
346-
blk_put_request(rq);
347-
348-
return err;
349-
}
350-
351248
static int send_trespass_cmd(struct scsi_device *sdev,
352249
struct clariion_dh_data *csdev)
353250
{
354-
struct request *rq;
355251
unsigned char *page22;
356-
int err, len, cmd;
252+
unsigned char cdb[COMMAND_SIZE(MODE_SELECT)];
253+
int err, res = SCSI_DH_OK, len;
254+
struct scsi_sense_hdr sshdr;
255+
u64 req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
256+
REQ_FAILFAST_DRIVER;
357257

358258
if (csdev->flags & CLARIION_SHORT_TRESPASS) {
359259
page22 = short_trespass;
360260
if (!(csdev->flags & CLARIION_HONOR_RESERVATIONS))
361261
/* Set Honor Reservations bit */
362262
page22[6] |= 0x80;
363263
len = sizeof(short_trespass);
364-
cmd = MODE_SELECT;
264+
cdb[0] = MODE_SELECT;
265+
cdb[1] = 0x10;
266+
cdb[4] = len;
365267
} else {
366268
page22 = long_trespass;
367269
if (!(csdev->flags & CLARIION_HONOR_RESERVATIONS))
368270
/* Set Honor Reservations bit */
369271
page22[10] |= 0x80;
370272
len = sizeof(long_trespass);
371-
cmd = MODE_SELECT_10;
273+
cdb[0] = MODE_SELECT_10;
274+
cdb[8] = len;
372275
}
373276
BUG_ON((len > CLARIION_BUFFER_SIZE));
374277
memcpy(csdev->buffer, page22, len);
375278

376-
rq = get_req(sdev, cmd, csdev->buffer);
377-
if (!rq)
378-
return SCSI_DH_RES_TEMP_UNAVAIL;
379-
380-
rq->sense = csdev->sense;
381-
memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
382-
rq->sense_len = csdev->senselen = 0;
383-
384-
err = blk_execute_rq(sdev->request_queue, NULL, rq, 1);
385-
if (err == -EIO) {
386-
if (rq->sense_len) {
387-
err = trespass_endio(sdev, csdev->sense);
388-
} else {
279+
err = scsi_execute_req_flags(sdev, cdb, DMA_TO_DEVICE,
280+
csdev->buffer, len, &sshdr,
281+
CLARIION_TIMEOUT * HZ, CLARIION_RETRIES,
282+
NULL, req_flags, 0);
283+
if (err) {
284+
if (scsi_sense_valid(&sshdr))
285+
res = trespass_endio(sdev, &sshdr);
286+
else {
389287
sdev_printk(KERN_INFO, sdev,
390288
"%s: failed to send MODE SELECT: %x\n",
391-
CLARIION_NAME, rq->errors);
289+
CLARIION_NAME, err);
290+
res = SCSI_DH_IO;
392291
}
393292
}
394293

395-
blk_put_request(rq);
396-
397-
return err;
294+
return res;
398295
}
399296

400297
static int clariion_check_sense(struct scsi_device *sdev,
@@ -464,21 +361,7 @@ static int clariion_std_inquiry(struct scsi_device *sdev,
464361
int err;
465362
char *sp_model;
466363

467-
err = send_inquiry_cmd(sdev, 0, csdev);
468-
if (err != SCSI_DH_OK && csdev->senselen) {
469-
struct scsi_sense_hdr sshdr;
470-
471-
if (scsi_normalize_sense(csdev->sense, SCSI_SENSE_BUFFERSIZE,
472-
&sshdr)) {
473-
sdev_printk(KERN_ERR, sdev, "%s: INQUIRY sense code "
474-
"%02x/%02x/%02x\n", CLARIION_NAME,
475-
sshdr.sense_key, sshdr.asc, sshdr.ascq);
476-
}
477-
err = SCSI_DH_IO;
478-
goto out;
479-
}
480-
481-
sp_model = parse_sp_model(sdev, csdev->buffer);
364+
sp_model = parse_sp_model(sdev, sdev->inquiry);
482365
if (!sp_model) {
483366
err = SCSI_DH_DEV_UNSUPP;
484367
goto out;
@@ -500,30 +383,12 @@ static int clariion_std_inquiry(struct scsi_device *sdev,
500383
static int clariion_send_inquiry(struct scsi_device *sdev,
501384
struct clariion_dh_data *csdev)
502385
{
503-
int err, retry = CLARIION_RETRIES;
504-
505-
retry:
506-
err = send_inquiry_cmd(sdev, 0xC0, csdev);
507-
if (err != SCSI_DH_OK && csdev->senselen) {
508-
struct scsi_sense_hdr sshdr;
509-
510-
err = scsi_normalize_sense(csdev->sense, SCSI_SENSE_BUFFERSIZE,
511-
&sshdr);
512-
if (!err)
513-
return SCSI_DH_IO;
514-
515-
err = clariion_check_sense(sdev, &sshdr);
516-
if (retry > 0 && err == ADD_TO_MLQUEUE) {
517-
retry--;
518-
goto retry;
519-
}
520-
sdev_printk(KERN_ERR, sdev, "%s: INQUIRY sense code "
521-
"%02x/%02x/%02x\n", CLARIION_NAME,
522-
sshdr.sense_key, sshdr.asc, sshdr.ascq);
523-
err = SCSI_DH_IO;
524-
} else {
386+
int err = SCSI_DH_IO;
387+
388+
if (!scsi_get_vpd_page(sdev, 0xC0, csdev->buffer,
389+
CLARIION_BUFFER_SIZE))
525390
err = parse_sp_info_reply(sdev, csdev);
526-
}
391+
527392
return err;
528393
}
529394

0 commit comments

Comments
 (0)