Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 360269
b: refs/heads/master
c: c50bd44
h: refs/heads/master
i:
  360267: 05f824d
v: v3
  • Loading branch information
K. Y. Srinivasan authored and James Bottomley committed Feb 24, 2013
1 parent 617d9de commit 3829de7
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 43 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: 3e8f4f4065901c8dfc51407e1984495e1748c090
refs/heads/master: c50bd4481707cef2a81c648f6e28e7a0a5f21129
101 changes: 59 additions & 42 deletions trunk/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 3829de7

Please sign in to comment.