Skip to content

Commit

Permalink
[SCSI] sas_ata: Satisfy libata qc function locking requirements
Browse files Browse the repository at this point in the history
ata_qc_complete and ata_sas_queuecmd require that the port lock be held
when they are called.  sas_ata doesn't do this, leading to BUG messages
about qc tags newly allocated qc tags already being in use.  This patch
fixes the locking, which should clean up the rest of those messages.

So far I've tested this against an IBM x206m with two SATA disks with no
BUG messages and no other signs of things going wrong, and the machine
finally passed the pounder stress test.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
  • Loading branch information
Darrick J. Wong authored and James Bottomley committed Jul 18, 2007
1 parent ba330ff commit 3eb7a51
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 0 deletions.
4 changes: 4 additions & 0 deletions drivers/scsi/libsas/sas_ata.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ static void sas_ata_task_done(struct sas_task *task)
struct task_status_struct *stat = &task->task_status;
struct ata_task_resp *resp = (struct ata_task_resp *)stat->buf;
enum ata_completion_errors ac;
unsigned long flags;

spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
if (stat->stat == SAS_PROTO_RESPONSE) {
ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf);
qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command);
Expand All @@ -113,6 +115,8 @@ static void sas_ata_task_done(struct sas_task *task)
}

ata_qc_complete(qc);
spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);

list_del_init(&task->list);
sas_free_task(task);
}
Expand Down
4 changes: 4 additions & 0 deletions drivers/scsi/libsas/sas_scsi_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,12 @@ int sas_queuecommand(struct scsi_cmnd *cmd,
struct sas_task *task;

if (dev_is_sata(dev)) {
unsigned long flags;

spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
res = ata_sas_queuecmd(cmd, scsi_done,
dev->sata_dev.ap);
spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
goto out;
}

Expand Down

0 comments on commit 3eb7a51

Please sign in to comment.