Skip to content

Commit

Permalink
[SCSI] storvsc: Restructure error handling code on command completion
Browse files Browse the repository at this point in the history
In preparation for handling additional sense codes, restructure and cleanup
the error handling code in the command completion code path.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
K. Y. Srinivasan authored and James Bottomley committed Feb 24, 2013
1 parent 3e8f4f4 commit c50bd44
Showing 1 changed file with 59 additions and 42 deletions.
101 changes: 59 additions & 42 deletions drivers/scsi/storvsc_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,55 @@ static int storvsc_channel_init(struct hv_device *device)
return ret;
}

static void storvsc_handle_error(struct vmscsi_request *vm_srb,
struct scsi_cmnd *scmnd,
struct Scsi_Host *host,
u8 asc, u8 ascq)
{
struct storvsc_scan_work *wrk;
void (*process_err_fn)(struct work_struct *work);
bool do_work = false;

switch (vm_srb->srb_status) {
case SRB_STATUS_ERROR:
/*
* If there is an error; offline the device since all
* error recovery strategies would have already been
* deployed on the host side. However, if the command
* were a pass-through command deal with it appropriately.
*/
switch (scmnd->cmnd[0]) {
case ATA_16:
case ATA_12:
set_host_byte(scmnd, DID_PASSTHROUGH);
break;
default:
set_host_byte(scmnd, DID_TARGET_FAILURE);
}
break;
case SRB_STATUS_INVALID_LUN:
do_work = true;
process_err_fn = storvsc_remove_lun;
break;
}
if (!do_work)
return;

/*
* We need to schedule work to process this error; schedule it.
*/
wrk = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC);
if (!wrk) {
set_host_byte(scmnd, DID_TARGET_FAILURE);
return;
}

wrk->host = host;
wrk->lun = vm_srb->lun;
INIT_WORK(&wrk->work, process_err_fn);
schedule_work(&wrk->work);
}


static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
{
Expand All @@ -769,8 +818,13 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
void (*scsi_done_fn)(struct scsi_cmnd *);
struct scsi_sense_hdr sense_hdr;
struct vmscsi_request *vm_srb;
struct storvsc_scan_work *wrk;
struct stor_mem_pools *memp = scmnd->device->hostdata;
struct Scsi_Host *host;
struct storvsc_device *stor_dev;
struct hv_device *dev = host_dev->dev;

stor_dev = get_in_stor_device(dev);
host = stor_dev->host;

vm_srb = &cmd_request->vstor_packet.vm_srb;
if (cmd_request->bounce_sgl_count) {
Expand All @@ -783,55 +837,18 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
cmd_request->bounce_sgl_count);
}

/*
* If there is an error; offline the device since all
* error recovery strategies would have already been
* deployed on the host side. However, if the command
* were a pass-through command deal with it appropriately.
*/
scmnd->result = vm_srb->scsi_status;

if (vm_srb->srb_status == SRB_STATUS_ERROR) {
switch (scmnd->cmnd[0]) {
case ATA_16:
case ATA_12:
set_host_byte(scmnd, DID_PASSTHROUGH);
break;
default:
set_host_byte(scmnd, DID_TARGET_FAILURE);
}
}


/*
* If the LUN is invalid; remove the device.
*/
if (vm_srb->srb_status == SRB_STATUS_INVALID_LUN) {
struct storvsc_device *stor_dev;
struct hv_device *dev = host_dev->dev;
struct Scsi_Host *host;

stor_dev = get_in_stor_device(dev);
host = stor_dev->host;

wrk = kmalloc(sizeof(struct storvsc_scan_work),
GFP_ATOMIC);
if (!wrk) {
scmnd->result = DID_TARGET_FAILURE << 16;
} else {
wrk->host = host;
wrk->lun = vm_srb->lun;
INIT_WORK(&wrk->work, storvsc_remove_lun);
schedule_work(&wrk->work);
}
}

if (scmnd->result) {
if (scsi_normalize_sense(scmnd->sense_buffer,
SCSI_SENSE_BUFFERSIZE, &sense_hdr))
scsi_print_sense_hdr("storvsc", &sense_hdr);
}

if (vm_srb->srb_status != SRB_STATUS_SUCCESS)
storvsc_handle_error(vm_srb, scmnd, host, sense_hdr.asc,
sense_hdr.ascq);

scsi_set_resid(scmnd,
cmd_request->data_buffer.len -
vm_srb->data_transfer_length);
Expand Down

0 comments on commit c50bd44

Please sign in to comment.