aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@us.ibm.com>2007-01-30 04:18:35 -0500
committerJames Bottomley <jejb@mulgrave.localdomain>2007-07-18 12:14:55 -0400
commit3eb7a51a3ae0ed0227e051ecf75199fccbb4cc73 (patch)
tree656ac071a158ad355b936999a30548a1f575d339 /drivers/scsi/libsas
parentba330ffebb43c37cabc765c7cb0a80df01554657 (diff)
[SCSI] sas_ata: Satisfy libata qc function locking requirements
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>
Diffstat (limited to 'drivers/scsi/libsas')
-rw-r--r--drivers/scsi/libsas/sas_ata.c4
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c4
2 files changed, 8 insertions, 0 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index de42b5b801cd..0bb1a149a9c2 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -92,7 +92,9 @@ static void sas_ata_task_done(struct sas_task *task)
92 struct task_status_struct *stat = &task->task_status; 92 struct task_status_struct *stat = &task->task_status;
93 struct ata_task_resp *resp = (struct ata_task_resp *)stat->buf; 93 struct ata_task_resp *resp = (struct ata_task_resp *)stat->buf;
94 enum ata_completion_errors ac; 94 enum ata_completion_errors ac;
95 unsigned long flags;
95 96
97 spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
96 if (stat->stat == SAS_PROTO_RESPONSE) { 98 if (stat->stat == SAS_PROTO_RESPONSE) {
97 ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf); 99 ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf);
98 qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command); 100 qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command);
@@ -113,6 +115,8 @@ static void sas_ata_task_done(struct sas_task *task)
113 } 115 }
114 116
115 ata_qc_complete(qc); 117 ata_qc_complete(qc);
118 spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
119
116 list_del_init(&task->list); 120 list_del_init(&task->list);
117 sas_free_task(task); 121 sas_free_task(task);
118} 122}
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index dbc2a912114f..ba5c91b81312 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -216,8 +216,12 @@ int sas_queuecommand(struct scsi_cmnd *cmd,
216 struct sas_task *task; 216 struct sas_task *task;
217 217
218 if (dev_is_sata(dev)) { 218 if (dev_is_sata(dev)) {
219 unsigned long flags;
220
221 spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
219 res = ata_sas_queuecmd(cmd, scsi_done, 222 res = ata_sas_queuecmd(cmd, scsi_done,
220 dev->sata_dev.ap); 223 dev->sata_dev.ap);
224 spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
221 goto out; 225 goto out;
222 } 226 }
223 227