diff options
Diffstat (limited to 'drivers/scsi/libsas/sas_ata.c')
-rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 83118d0b6d0c..81ce39d166d1 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -166,23 +166,30 @@ qc_already_gone: | |||
166 | 166 | ||
167 | static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) | 167 | static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) |
168 | { | 168 | { |
169 | int res; | 169 | unsigned long flags; |
170 | struct sas_task *task; | 170 | struct sas_task *task; |
171 | struct domain_device *dev = qc->ap->private_data; | 171 | struct scatterlist *sg; |
172 | int ret = AC_ERR_SYSTEM; | ||
173 | unsigned int si, xfer = 0; | ||
174 | struct ata_port *ap = qc->ap; | ||
175 | struct domain_device *dev = ap->private_data; | ||
172 | struct sas_ha_struct *sas_ha = dev->port->ha; | 176 | struct sas_ha_struct *sas_ha = dev->port->ha; |
173 | struct Scsi_Host *host = sas_ha->core.shost; | 177 | struct Scsi_Host *host = sas_ha->core.shost; |
174 | struct sas_internal *i = to_sas_internal(host->transportt); | 178 | struct sas_internal *i = to_sas_internal(host->transportt); |
175 | struct scatterlist *sg; | 179 | |
176 | unsigned int xfer = 0; | 180 | /* TODO: audit callers to ensure they are ready for qc_issue to |
177 | unsigned int si; | 181 | * unconditionally re-enable interrupts |
182 | */ | ||
183 | local_irq_save(flags); | ||
184 | spin_unlock(ap->lock); | ||
178 | 185 | ||
179 | /* If the device fell off, no sense in issuing commands */ | 186 | /* If the device fell off, no sense in issuing commands */ |
180 | if (dev->gone) | 187 | if (dev->gone) |
181 | return AC_ERR_SYSTEM; | 188 | goto out; |
182 | 189 | ||
183 | task = sas_alloc_task(GFP_ATOMIC); | 190 | task = sas_alloc_task(GFP_ATOMIC); |
184 | if (!task) | 191 | if (!task) |
185 | return AC_ERR_SYSTEM; | 192 | goto out; |
186 | task->dev = dev; | 193 | task->dev = dev; |
187 | task->task_proto = SAS_PROTOCOL_STP; | 194 | task->task_proto = SAS_PROTOCOL_STP; |
188 | task->task_done = sas_ata_task_done; | 195 | task->task_done = sas_ata_task_done; |
@@ -227,21 +234,24 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) | |||
227 | ASSIGN_SAS_TASK(qc->scsicmd, task); | 234 | ASSIGN_SAS_TASK(qc->scsicmd, task); |
228 | 235 | ||
229 | if (sas_ha->lldd_max_execute_num < 2) | 236 | if (sas_ha->lldd_max_execute_num < 2) |
230 | res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC); | 237 | ret = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC); |
231 | else | 238 | else |
232 | res = sas_queue_up(task); | 239 | ret = sas_queue_up(task); |
233 | 240 | ||
234 | /* Examine */ | 241 | /* Examine */ |
235 | if (res) { | 242 | if (ret) { |
236 | SAS_DPRINTK("lldd_execute_task returned: %d\n", res); | 243 | SAS_DPRINTK("lldd_execute_task returned: %d\n", ret); |
237 | 244 | ||
238 | if (qc->scsicmd) | 245 | if (qc->scsicmd) |
239 | ASSIGN_SAS_TASK(qc->scsicmd, NULL); | 246 | ASSIGN_SAS_TASK(qc->scsicmd, NULL); |
240 | sas_free_task(task); | 247 | sas_free_task(task); |
241 | return AC_ERR_SYSTEM; | 248 | ret = AC_ERR_SYSTEM; |
242 | } | 249 | } |
243 | 250 | ||
244 | return 0; | 251 | out: |
252 | spin_lock(ap->lock); | ||
253 | local_irq_restore(flags); | ||
254 | return ret; | ||
245 | } | 255 | } |
246 | 256 | ||
247 | static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc) | 257 | static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc) |