Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 77029
b: refs/heads/master
c: 860784c
h: refs/heads/master
i:
  77027: 2104638
v: v3
  • Loading branch information
Robert Jennings authored and James Bottomley committed Jan 12, 2008
1 parent 3ef6944 commit cc1dda8
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 56 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: dc8875e1078961591af4fbf9556c44648bf28d11
refs/heads/master: 860784c8a2b077157b6a51fb8749524d0363cc49
151 changes: 96 additions & 55 deletions trunk/drivers/scsi/ibmvscsi/ibmvscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,16 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
list_del(&evt_struct->list);
del_timer(&evt_struct->timer);

/* If send_crq returns H_CLOSED, return SCSI_MLQUEUE_HOST_BUSY.
* Firmware will send a CRQ with a transport event (0xFF) to
* tell this client what has happened to the transport. This
* will be handled in ibmvscsi_handle_crq()
*/
if (rc == H_CLOSED) {
dev_warn(hostdata->dev, "send warning. "
"Receive queue closed, will retry.\n");
goto send_busy;
}
dev_err(hostdata->dev, "send error %d\n", rc);
atomic_inc(&hostdata->request_limit);
goto send_error;
Expand Down Expand Up @@ -976,58 +986,74 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd)
int rsp_rc;
unsigned long flags;
u16 lun = lun_from_dev(cmd->device);
unsigned long wait_switch = 0;

/* First, find this command in our sent list so we can figure
* out the correct tag
*/
spin_lock_irqsave(hostdata->host->host_lock, flags);
found_evt = NULL;
list_for_each_entry(tmp_evt, &hostdata->sent, list) {
if (tmp_evt->cmnd == cmd) {
found_evt = tmp_evt;
break;
wait_switch = jiffies + (init_timeout * HZ);
do {
found_evt = NULL;
list_for_each_entry(tmp_evt, &hostdata->sent, list) {
if (tmp_evt->cmnd == cmd) {
found_evt = tmp_evt;
break;
}
}
}

if (!found_evt) {
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
return SUCCESS;
}
if (!found_evt) {
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
return SUCCESS;
}

evt = get_event_struct(&hostdata->pool);
if (evt == NULL) {
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
sdev_printk(KERN_ERR, cmd->device, "failed to allocate abort event\n");
return FAILED;
}
evt = get_event_struct(&hostdata->pool);
if (evt == NULL) {
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
sdev_printk(KERN_ERR, cmd->device,
"failed to allocate abort event\n");
return FAILED;
}

init_event_struct(evt,
sync_completion,
VIOSRP_SRP_FORMAT,
init_timeout);
init_event_struct(evt,
sync_completion,
VIOSRP_SRP_FORMAT,
init_timeout);

tsk_mgmt = &evt->iu.srp.tsk_mgmt;
tsk_mgmt = &evt->iu.srp.tsk_mgmt;

/* Set up an abort SRP command */
memset(tsk_mgmt, 0x00, sizeof(*tsk_mgmt));
tsk_mgmt->opcode = SRP_TSK_MGMT;
tsk_mgmt->lun = ((u64) lun) << 48;
tsk_mgmt->tsk_mgmt_func = SRP_TSK_ABORT_TASK;
tsk_mgmt->task_tag = (u64) found_evt;

sdev_printk(KERN_INFO, cmd->device, "aborting command. lun 0x%lx, tag 0x%lx\n",
tsk_mgmt->lun, tsk_mgmt->task_tag);

evt->sync_srp = &srp_rsp;
init_completion(&evt->comp);
rsp_rc = ibmvscsi_send_srp_event(evt, hostdata, init_timeout * 2);
/* Set up an abort SRP command */
memset(tsk_mgmt, 0x00, sizeof(*tsk_mgmt));
tsk_mgmt->opcode = SRP_TSK_MGMT;
tsk_mgmt->lun = ((u64) lun) << 48;
tsk_mgmt->tsk_mgmt_func = SRP_TSK_ABORT_TASK;
tsk_mgmt->task_tag = (u64) found_evt;

evt->sync_srp = &srp_rsp;

init_completion(&evt->comp);
rsp_rc = ibmvscsi_send_srp_event(evt, hostdata, init_timeout * 2);

if (rsp_rc != SCSI_MLQUEUE_HOST_BUSY)
break;

spin_unlock_irqrestore(hostdata->host->host_lock, flags);
msleep(10);
spin_lock_irqsave(hostdata->host->host_lock, flags);
} while (time_before(jiffies, wait_switch));

spin_unlock_irqrestore(hostdata->host->host_lock, flags);

if (rsp_rc != 0) {
sdev_printk(KERN_ERR, cmd->device,
"failed to send abort() event. rc=%d\n", rsp_rc);
return FAILED;
}

sdev_printk(KERN_INFO, cmd->device,
"aborting command. lun 0x%lx, tag 0x%lx\n",
(((u64) lun) << 48), (u64) found_evt);

wait_for_completion(&evt->comp);

/* make sure we got a good response */
Expand Down Expand Up @@ -1099,41 +1125,56 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
int rsp_rc;
unsigned long flags;
u16 lun = lun_from_dev(cmd->device);
unsigned long wait_switch = 0;

spin_lock_irqsave(hostdata->host->host_lock, flags);
evt = get_event_struct(&hostdata->pool);
if (evt == NULL) {
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
sdev_printk(KERN_ERR, cmd->device, "failed to allocate reset event\n");
return FAILED;
}
wait_switch = jiffies + (init_timeout * HZ);
do {
evt = get_event_struct(&hostdata->pool);
if (evt == NULL) {
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
sdev_printk(KERN_ERR, cmd->device,
"failed to allocate reset event\n");
return FAILED;
}

init_event_struct(evt,
sync_completion,
VIOSRP_SRP_FORMAT,
init_timeout);
init_event_struct(evt,
sync_completion,
VIOSRP_SRP_FORMAT,
init_timeout);

tsk_mgmt = &evt->iu.srp.tsk_mgmt;
tsk_mgmt = &evt->iu.srp.tsk_mgmt;

/* Set up a lun reset SRP command */
memset(tsk_mgmt, 0x00, sizeof(*tsk_mgmt));
tsk_mgmt->opcode = SRP_TSK_MGMT;
tsk_mgmt->lun = ((u64) lun) << 48;
tsk_mgmt->tsk_mgmt_func = SRP_TSK_LUN_RESET;
/* Set up a lun reset SRP command */
memset(tsk_mgmt, 0x00, sizeof(*tsk_mgmt));
tsk_mgmt->opcode = SRP_TSK_MGMT;
tsk_mgmt->lun = ((u64) lun) << 48;
tsk_mgmt->tsk_mgmt_func = SRP_TSK_LUN_RESET;

sdev_printk(KERN_INFO, cmd->device, "resetting device. lun 0x%lx\n",
tsk_mgmt->lun);
evt->sync_srp = &srp_rsp;

init_completion(&evt->comp);
rsp_rc = ibmvscsi_send_srp_event(evt, hostdata, init_timeout * 2);

if (rsp_rc != SCSI_MLQUEUE_HOST_BUSY)
break;

spin_unlock_irqrestore(hostdata->host->host_lock, flags);
msleep(10);
spin_lock_irqsave(hostdata->host->host_lock, flags);
} while (time_before(jiffies, wait_switch));

evt->sync_srp = &srp_rsp;
init_completion(&evt->comp);
rsp_rc = ibmvscsi_send_srp_event(evt, hostdata, init_timeout * 2);
spin_unlock_irqrestore(hostdata->host->host_lock, flags);

if (rsp_rc != 0) {
sdev_printk(KERN_ERR, cmd->device,
"failed to send reset event. rc=%d\n", rsp_rc);
return FAILED;
}

sdev_printk(KERN_INFO, cmd->device, "resetting device. lun 0x%lx\n",
(((u64) lun) << 48));

wait_for_completion(&evt->comp);

/* make sure we got a good response */
Expand Down

0 comments on commit cc1dda8

Please sign in to comment.