Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 173631
b: refs/heads/master
c: 4e2ef86
h: refs/heads/master
i:
  173629: f46e373
  173627: 6050adc
  173623: e262551
  173615: 45dad5a
  173599: a0e0519
  173567: aa34775
v: v3
  • Loading branch information
Chandra Seetharaman authored and James Bottomley committed Dec 4, 2009
1 parent 48b7e80 commit f02ea17
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 34 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 970f3f47e7c97c0bfe9f91356943b55ac389cb1d
refs/heads/master: 4e2ef86cd5ce057b60acea33bb71c06676e71888
87 changes: 54 additions & 33 deletions trunk/drivers/scsi/device_handler/scsi_dh_hp_sw.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,14 @@ struct hp_sw_dh_data {
unsigned char sense[SCSI_SENSE_BUFFERSIZE];
int path_state;
int retries;
int retry_cnt;
struct scsi_device *sdev;
activate_complete callback_fn;
void *callback_data;
};

static int hp_sw_start_stop(struct hp_sw_dh_data *);

static inline struct hp_sw_dh_data *get_hp_sw_data(struct scsi_device *sdev)
{
struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data;
Expand Down Expand Up @@ -191,19 +197,53 @@ static int start_done(struct scsi_device *sdev, unsigned char *sense)
return rc;
}

static void start_stop_endio(struct request *req, int error)
{
struct hp_sw_dh_data *h = req->end_io_data;
unsigned err = SCSI_DH_OK;

if (error || host_byte(req->errors) != DID_OK ||
msg_byte(req->errors) != COMMAND_COMPLETE) {
sdev_printk(KERN_WARNING, h->sdev,
"%s: sending start_stop_unit failed with %x\n",
HP_SW_NAME, req->errors);
err = SCSI_DH_IO;
goto done;
}

if (req->sense_len > 0) {
err = start_done(h->sdev, h->sense);
if (err == SCSI_DH_RETRY) {
err = SCSI_DH_IO;
if (--h->retry_cnt) {
blk_put_request(req);
err = hp_sw_start_stop(h);
if (err == SCSI_DH_OK)
return;
}
}
}
done:
blk_put_request(req);
if (h->callback_fn) {
h->callback_fn(h->callback_data, err);
h->callback_fn = h->callback_data = NULL;
}
return;

}

/*
* hp_sw_start_stop - Send START STOP UNIT command
* @sdev: sdev command should be sent to
*
* Sending START STOP UNIT activates the SP.
*/
static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h)
static int hp_sw_start_stop(struct hp_sw_dh_data *h)
{
struct request *req;
int ret, retry;

retry:
req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO);
req = blk_get_request(h->sdev->request_queue, WRITE, GFP_ATOMIC);
if (!req)
return SCSI_DH_RES_TEMP_UNAVAIL;

Expand All @@ -217,32 +257,10 @@ static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h)
req->sense = h->sense;
memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
req->sense_len = 0;
retry = h->retries;

ret = blk_execute_rq(req->q, NULL, req, 1);
if (ret == -EIO) {
if (req->sense_len > 0) {
ret = start_done(sdev, h->sense);
} else {
sdev_printk(KERN_WARNING, sdev,
"%s: sending start_stop_unit failed with %x\n",
HP_SW_NAME, req->errors);
ret = SCSI_DH_IO;
}
} else
ret = SCSI_DH_OK;

if (ret == SCSI_DH_RETRY) {
if (--retry) {
blk_put_request(req);
goto retry;
}
ret = SCSI_DH_IO;
}

blk_put_request(req);
req->end_io_data = h;

return ret;
blk_execute_rq_nowait(req->q, NULL, req, 1, start_stop_endio);
return SCSI_DH_OK;
}

static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req)
Expand Down Expand Up @@ -277,11 +295,13 @@ static int hp_sw_activate(struct scsi_device *sdev,
ret = hp_sw_tur(sdev, h);

if (ret == SCSI_DH_OK && h->path_state == HP_SW_PATH_PASSIVE) {
ret = hp_sw_start_stop(sdev, h);
h->retry_cnt = h->retries;
h->callback_fn = fn;
h->callback_data = data;
ret = hp_sw_start_stop(h);
if (ret == SCSI_DH_OK)
sdev_printk(KERN_INFO, sdev,
"%s: activated path\n",
HP_SW_NAME);
return 0;
h->callback_fn = h->callback_data = NULL;
}

if (fn)
Expand Down Expand Up @@ -329,6 +349,7 @@ static int hp_sw_bus_attach(struct scsi_device *sdev)
h = (struct hp_sw_dh_data *) scsi_dh_data->buf;
h->path_state = HP_SW_PATH_UNINITIALIZED;
h->retries = HP_SW_RETRIES;
h->sdev = sdev;

ret = hp_sw_tur(sdev, h);
if (ret != SCSI_DH_OK || h->path_state == HP_SW_PATH_UNINITIALIZED)
Expand Down

0 comments on commit f02ea17

Please sign in to comment.