Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 47735
b: refs/heads/master
c: 396819f
h: refs/heads/master
i:
  47733: b7252a7
  47731: 6504629
  47727: c7a6b9a
v: v3
  • Loading branch information
Darrick J. Wong authored and James Bottomley committed Jan 13, 2007
1 parent 18e23a3 commit 161bb80
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 24 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: 3ebf6922b0833807e54c73f4794c74baf9945fc8
refs/heads/master: 396819fba821ad56f1b90090d256f0ab726c89c5
51 changes: 29 additions & 22 deletions trunk/drivers/scsi/libsas/sas_scsi_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
}

spin_lock_irqsave(&task->task_state_lock, flags);
BUG_ON(task->task_state_flags & SAS_TASK_STATE_ABORTED);
if (task->task_state_flags & SAS_TASK_STATE_DONE) {
spin_unlock_irqrestore(&task->task_state_lock, flags);
SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n",
Expand Down Expand Up @@ -830,62 +831,67 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha)
spin_unlock_irqrestore(&core->task_queue_lock, flags);
}

static int do_sas_task_abort(struct sas_task *task)
/*
* Call the LLDD task abort routine directly. This function is intended for
* use by upper layers that need to tell the LLDD to abort a task.
*/
int __sas_task_abort(struct sas_task *task)
{
struct scsi_cmnd *sc = task->uldd_task;
struct sas_internal *si =
to_sas_internal(task->dev->port->ha->core.shost->transportt);
unsigned long flags;
int res;

spin_lock_irqsave(&task->task_state_lock, flags);
if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
if (task->task_state_flags & SAS_TASK_STATE_ABORTED ||
task->task_state_flags & SAS_TASK_STATE_DONE) {
spin_unlock_irqrestore(&task->task_state_lock, flags);
SAS_DPRINTK("%s: Task %p already aborted.\n", __FUNCTION__,
SAS_DPRINTK("%s: Task %p already finished.\n", __FUNCTION__,
task);
return 0;
}

if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
task->task_state_flags |= SAS_TASK_STATE_ABORTED;
task->task_state_flags |= SAS_TASK_STATE_ABORTED;
spin_unlock_irqrestore(&task->task_state_lock, flags);

if (!si->dft->lldd_abort_task)
return -ENODEV;

res = si->dft->lldd_abort_task(task);

spin_lock_irqsave(&task->task_state_lock, flags);
if ((task->task_state_flags & SAS_TASK_STATE_DONE) ||
(res == TMF_RESP_FUNC_COMPLETE))
{
/* SMP commands don't have scsi_cmds(?) */
if (!sc) {
task->task_done(task);
return 0;
}
scsi_req_abort_cmd(sc);
scsi_schedule_eh(sc->device->host);
spin_unlock_irqrestore(&task->task_state_lock, flags);
task->task_done(task);
return 0;
}

spin_lock_irqsave(&task->task_state_lock, flags);
if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
task->task_state_flags &= ~SAS_TASK_STATE_ABORTED;
spin_unlock_irqrestore(&task->task_state_lock, flags);

return -EAGAIN;
}

void sas_task_abort(struct work_struct *work)
/*
* Tell an upper layer that it needs to initiate an abort for a given task.
* This should only ever be called by an LLDD.
*/
void sas_task_abort(struct sas_task *task)
{
struct sas_task *task =
container_of(work, struct sas_task, abort_work);
int i;
struct scsi_cmnd *sc = task->uldd_task;

for (i = 0; i < 5; i++)
if (!do_sas_task_abort(task))
/* Escape for libsas internal commands */
if (!sc) {
if (!del_timer(&task->timer))
return;
task->timer.function(task->timer.data);
return;
}

SAS_DPRINTK("%s: Could not kill task!\n", __FUNCTION__);
scsi_req_abort_cmd(sc);
scsi_schedule_eh(sc->device->host);
}

EXPORT_SYMBOL_GPL(sas_queuecommand);
Expand All @@ -895,6 +901,7 @@ EXPORT_SYMBOL_GPL(sas_slave_destroy);
EXPORT_SYMBOL_GPL(sas_change_queue_depth);
EXPORT_SYMBOL_GPL(sas_change_queue_type);
EXPORT_SYMBOL_GPL(sas_bios_param);
EXPORT_SYMBOL_GPL(__sas_task_abort);
EXPORT_SYMBOL_GPL(sas_task_abort);
EXPORT_SYMBOL_GPL(sas_phy_reset);
EXPORT_SYMBOL_GPL(sas_phy_enable);
3 changes: 2 additions & 1 deletion trunk/include/scsi/libsas.h
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,7 @@ void sas_unregister_dev(struct domain_device *);

void sas_init_dev(struct domain_device *);

void sas_task_abort(struct work_struct *);
void sas_task_abort(struct sas_task *);
int __sas_task_abort(struct sas_task *);

#endif /* _SASLIB_H_ */

0 comments on commit 161bb80

Please sign in to comment.