Skip to content

Commit 80e1836

Browse files
hreineckeaxboe
authored andcommitted
scsi_dh_hp_sw: switch to scsi_execute_req_flags()
Switch to scsi_execute_req_flags() instead of using the block interface directly. This 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 b78205c commit 80e1836

File tree

1 file changed

+65
-157
lines changed

1 file changed

+65
-157
lines changed

drivers/scsi/device_handler/scsi_dh_hp_sw.c

Lines changed: 65 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,10 @@
3838
#define HP_SW_PATH_PASSIVE 1
3939

4040
struct hp_sw_dh_data {
41-
unsigned char sense[SCSI_SENSE_BUFFERSIZE];
4241
int path_state;
4342
int retries;
4443
int retry_cnt;
4544
struct scsi_device *sdev;
46-
activate_complete callback_fn;
47-
void *callback_data;
4845
};
4946

5047
static int hp_sw_start_stop(struct hp_sw_dh_data *);
@@ -56,43 +53,34 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *);
5653
*
5754
* Returns SCSI_DH_DEV_OFFLINED if the sdev is on the passive path
5855
*/
59-
static int tur_done(struct scsi_device *sdev, unsigned char *sense)
56+
static int tur_done(struct scsi_device *sdev, struct hp_sw_dh_data *h,
57+
struct scsi_sense_hdr *sshdr)
6058
{
61-
struct scsi_sense_hdr sshdr;
62-
int ret;
59+
int ret = SCSI_DH_IO;
6360

64-
ret = scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr);
65-
if (!ret) {
66-
sdev_printk(KERN_WARNING, sdev,
67-
"%s: sending tur failed, no sense available\n",
68-
HP_SW_NAME);
69-
ret = SCSI_DH_IO;
70-
goto done;
71-
}
72-
switch (sshdr.sense_key) {
61+
switch (sshdr->sense_key) {
7362
case UNIT_ATTENTION:
7463
ret = SCSI_DH_IMM_RETRY;
7564
break;
7665
case NOT_READY:
77-
if ((sshdr.asc == 0x04) && (sshdr.ascq == 2)) {
66+
if (sshdr->asc == 0x04 && sshdr->ascq == 2) {
7867
/*
7968
* LUN not ready - Initialization command required
8069
*
8170
* This is the passive path
8271
*/
83-
ret = SCSI_DH_DEV_OFFLINED;
72+
h->path_state = HP_SW_PATH_PASSIVE;
73+
ret = SCSI_DH_OK;
8474
break;
8575
}
8676
/* Fallthrough */
8777
default:
8878
sdev_printk(KERN_WARNING, sdev,
8979
"%s: sending tur failed, sense %x/%x/%x\n",
90-
HP_SW_NAME, sshdr.sense_key, sshdr.asc,
91-
sshdr.ascq);
80+
HP_SW_NAME, sshdr->sense_key, sshdr->asc,
81+
sshdr->ascq);
9282
break;
9383
}
94-
95-
done:
9684
return ret;
9785
}
9886

@@ -105,130 +93,35 @@ static int tur_done(struct scsi_device *sdev, unsigned char *sense)
10593
*/
10694
static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
10795
{
108-
struct request *req;
109-
int ret;
96+
unsigned char cmd[6] = { TEST_UNIT_READY };
97+
struct scsi_sense_hdr sshdr;
98+
int ret = SCSI_DH_OK, res;
99+
u64 req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
100+
REQ_FAILFAST_DRIVER;
110101

111102
retry:
112-
req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO);
113-
if (IS_ERR(req))
114-
return SCSI_DH_RES_TEMP_UNAVAIL;
115-
116-
blk_rq_set_block_pc(req);
117-
req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
118-
REQ_FAILFAST_DRIVER;
119-
req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY);
120-
req->cmd[0] = TEST_UNIT_READY;
121-
req->timeout = HP_SW_TIMEOUT;
122-
req->sense = h->sense;
123-
memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
124-
req->sense_len = 0;
125-
126-
ret = blk_execute_rq(req->q, NULL, req, 1);
127-
if (ret == -EIO) {
128-
if (req->sense_len > 0) {
129-
ret = tur_done(sdev, h->sense);
130-
} else {
103+
res = scsi_execute_req_flags(sdev, cmd, DMA_NONE, NULL, 0, &sshdr,
104+
HP_SW_TIMEOUT, HP_SW_RETRIES,
105+
NULL, req_flags, 0);
106+
if (res) {
107+
if (scsi_sense_valid(&sshdr))
108+
ret = tur_done(sdev, h, &sshdr);
109+
else {
131110
sdev_printk(KERN_WARNING, sdev,
132111
"%s: sending tur failed with %x\n",
133-
HP_SW_NAME, req->errors);
112+
HP_SW_NAME, res);
134113
ret = SCSI_DH_IO;
135114
}
136115
} else {
137116
h->path_state = HP_SW_PATH_ACTIVE;
138117
ret = SCSI_DH_OK;
139118
}
140-
if (ret == SCSI_DH_IMM_RETRY) {
141-
blk_put_request(req);
119+
if (ret == SCSI_DH_IMM_RETRY)
142120
goto retry;
143-
}
144-
if (ret == SCSI_DH_DEV_OFFLINED) {
145-
h->path_state = HP_SW_PATH_PASSIVE;
146-
ret = SCSI_DH_OK;
147-
}
148-
149-
blk_put_request(req);
150121

151122
return ret;
152123
}
153124

154-
/*
155-
* start_done - Handle START STOP UNIT return status
156-
* @sdev: sdev the command has been sent to
157-
* @errors: blk error code
158-
*/
159-
static int start_done(struct scsi_device *sdev, unsigned char *sense)
160-
{
161-
struct scsi_sense_hdr sshdr;
162-
int rc;
163-
164-
rc = scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr);
165-
if (!rc) {
166-
sdev_printk(KERN_WARNING, sdev,
167-
"%s: sending start_stop_unit failed, "
168-
"no sense available\n",
169-
HP_SW_NAME);
170-
return SCSI_DH_IO;
171-
}
172-
switch (sshdr.sense_key) {
173-
case NOT_READY:
174-
if ((sshdr.asc == 0x04) && (sshdr.ascq == 3)) {
175-
/*
176-
* LUN not ready - manual intervention required
177-
*
178-
* Switch-over in progress, retry.
179-
*/
180-
rc = SCSI_DH_RETRY;
181-
break;
182-
}
183-
/* fall through */
184-
default:
185-
sdev_printk(KERN_WARNING, sdev,
186-
"%s: sending start_stop_unit failed, sense %x/%x/%x\n",
187-
HP_SW_NAME, sshdr.sense_key, sshdr.asc,
188-
sshdr.ascq);
189-
rc = SCSI_DH_IO;
190-
}
191-
192-
return rc;
193-
}
194-
195-
static void start_stop_endio(struct request *req, int error)
196-
{
197-
struct hp_sw_dh_data *h = req->end_io_data;
198-
unsigned err = SCSI_DH_OK;
199-
200-
if (error || host_byte(req->errors) != DID_OK ||
201-
msg_byte(req->errors) != COMMAND_COMPLETE) {
202-
sdev_printk(KERN_WARNING, h->sdev,
203-
"%s: sending start_stop_unit failed with %x\n",
204-
HP_SW_NAME, req->errors);
205-
err = SCSI_DH_IO;
206-
goto done;
207-
}
208-
209-
if (req->sense_len > 0) {
210-
err = start_done(h->sdev, h->sense);
211-
if (err == SCSI_DH_RETRY) {
212-
err = SCSI_DH_IO;
213-
if (--h->retry_cnt) {
214-
blk_put_request(req);
215-
err = hp_sw_start_stop(h);
216-
if (err == SCSI_DH_OK)
217-
return;
218-
}
219-
}
220-
}
221-
done:
222-
req->end_io_data = NULL;
223-
__blk_put_request(req->q, req);
224-
if (h->callback_fn) {
225-
h->callback_fn(h->callback_data, err);
226-
h->callback_fn = h->callback_data = NULL;
227-
}
228-
return;
229-
230-
}
231-
232125
/*
233126
* hp_sw_start_stop - Send START STOP UNIT command
234127
* @sdev: sdev command should be sent to
@@ -237,26 +130,48 @@ static void start_stop_endio(struct request *req, int error)
237130
*/
238131
static int hp_sw_start_stop(struct hp_sw_dh_data *h)
239132
{
240-
struct request *req;
241-
242-
req = blk_get_request(h->sdev->request_queue, WRITE, GFP_ATOMIC);
243-
if (IS_ERR(req))
244-
return SCSI_DH_RES_TEMP_UNAVAIL;
245-
246-
blk_rq_set_block_pc(req);
247-
req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
248-
REQ_FAILFAST_DRIVER;
249-
req->cmd_len = COMMAND_SIZE(START_STOP);
250-
req->cmd[0] = START_STOP;
251-
req->cmd[4] = 1; /* Start spin cycle */
252-
req->timeout = HP_SW_TIMEOUT;
253-
req->sense = h->sense;
254-
memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
255-
req->sense_len = 0;
256-
req->end_io_data = h;
133+
unsigned char cmd[6] = { START_STOP, 0, 0, 0, 1, 0 };
134+
struct scsi_sense_hdr sshdr;
135+
struct scsi_device *sdev = h->sdev;
136+
int res, rc = SCSI_DH_OK;
137+
int retry_cnt = HP_SW_RETRIES;
138+
u64 req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
139+
REQ_FAILFAST_DRIVER;
257140

258-
blk_execute_rq_nowait(req->q, NULL, req, 1, start_stop_endio);
259-
return SCSI_DH_OK;
141+
retry:
142+
res = scsi_execute_req_flags(sdev, cmd, DMA_NONE, NULL, 0, &sshdr,
143+
HP_SW_TIMEOUT, HP_SW_RETRIES,
144+
NULL, req_flags, 0);
145+
if (res) {
146+
if (!scsi_sense_valid(&sshdr)) {
147+
sdev_printk(KERN_WARNING, sdev,
148+
"%s: sending start_stop_unit failed, "
149+
"no sense available\n", HP_SW_NAME);
150+
return SCSI_DH_IO;
151+
}
152+
switch (sshdr.sense_key) {
153+
case NOT_READY:
154+
if (sshdr.asc == 0x04 && sshdr.ascq == 3) {
155+
/*
156+
* LUN not ready - manual intervention required
157+
*
158+
* Switch-over in progress, retry.
159+
*/
160+
if (--retry_cnt)
161+
goto retry;
162+
rc = SCSI_DH_RETRY;
163+
break;
164+
}
165+
/* fall through */
166+
default:
167+
sdev_printk(KERN_WARNING, sdev,
168+
"%s: sending start_stop_unit failed, "
169+
"sense %x/%x/%x\n", HP_SW_NAME,
170+
sshdr.sense_key, sshdr.asc, sshdr.ascq);
171+
rc = SCSI_DH_IO;
172+
}
173+
}
174+
return rc;
260175
}
261176

262177
static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req)
@@ -290,15 +205,8 @@ static int hp_sw_activate(struct scsi_device *sdev,
290205

291206
ret = hp_sw_tur(sdev, h);
292207

293-
if (ret == SCSI_DH_OK && h->path_state == HP_SW_PATH_PASSIVE) {
294-
h->retry_cnt = h->retries;
295-
h->callback_fn = fn;
296-
h->callback_data = data;
208+
if (ret == SCSI_DH_OK && h->path_state == HP_SW_PATH_PASSIVE)
297209
ret = hp_sw_start_stop(h);
298-
if (ret == SCSI_DH_OK)
299-
return 0;
300-
h->callback_fn = h->callback_data = NULL;
301-
}
302210

303211
if (fn)
304212
fn(data, ret);

0 commit comments

Comments
 (0)