diff options
Diffstat (limited to 'drivers/scsi/libsas/sas_ata.c')
-rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 828 |
1 files changed, 397 insertions, 431 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index db9238f2ecb8..bc0cecc6ad62 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -23,6 +23,8 @@ | |||
23 | 23 | ||
24 | #include <linux/scatterlist.h> | 24 | #include <linux/scatterlist.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/async.h> | ||
27 | #include <linux/export.h> | ||
26 | 28 | ||
27 | #include <scsi/sas_ata.h> | 29 | #include <scsi/sas_ata.h> |
28 | #include "sas_internal.h" | 30 | #include "sas_internal.h" |
@@ -93,22 +95,47 @@ static enum ata_completion_errors sas_to_ata_err(struct task_status_struct *ts) | |||
93 | static void sas_ata_task_done(struct sas_task *task) | 95 | static void sas_ata_task_done(struct sas_task *task) |
94 | { | 96 | { |
95 | struct ata_queued_cmd *qc = task->uldd_task; | 97 | struct ata_queued_cmd *qc = task->uldd_task; |
96 | struct domain_device *dev; | 98 | struct domain_device *dev = task->dev; |
97 | struct task_status_struct *stat = &task->task_status; | 99 | struct task_status_struct *stat = &task->task_status; |
98 | struct ata_task_resp *resp = (struct ata_task_resp *)stat->buf; | 100 | struct ata_task_resp *resp = (struct ata_task_resp *)stat->buf; |
99 | struct sas_ha_struct *sas_ha; | 101 | struct sas_ha_struct *sas_ha = dev->port->ha; |
100 | enum ata_completion_errors ac; | 102 | enum ata_completion_errors ac; |
101 | unsigned long flags; | 103 | unsigned long flags; |
102 | struct ata_link *link; | 104 | struct ata_link *link; |
105 | struct ata_port *ap; | ||
106 | |||
107 | spin_lock_irqsave(&dev->done_lock, flags); | ||
108 | if (test_bit(SAS_HA_FROZEN, &sas_ha->state)) | ||
109 | task = NULL; | ||
110 | else if (qc && qc->scsicmd) | ||
111 | ASSIGN_SAS_TASK(qc->scsicmd, NULL); | ||
112 | spin_unlock_irqrestore(&dev->done_lock, flags); | ||
113 | |||
114 | /* check if libsas-eh got to the task before us */ | ||
115 | if (unlikely(!task)) | ||
116 | return; | ||
103 | 117 | ||
104 | if (!qc) | 118 | if (!qc) |
105 | goto qc_already_gone; | 119 | goto qc_already_gone; |
106 | 120 | ||
107 | dev = qc->ap->private_data; | 121 | ap = qc->ap; |
108 | sas_ha = dev->port->ha; | 122 | link = &ap->link; |
109 | link = &dev->sata_dev.ap->link; | 123 | |
124 | spin_lock_irqsave(ap->lock, flags); | ||
125 | /* check if we lost the race with libata/sas_ata_post_internal() */ | ||
126 | if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) { | ||
127 | spin_unlock_irqrestore(ap->lock, flags); | ||
128 | if (qc->scsicmd) | ||
129 | goto qc_already_gone; | ||
130 | else { | ||
131 | /* if eh is not involved and the port is frozen then the | ||
132 | * ata internal abort process has taken responsibility | ||
133 | * for this sas_task | ||
134 | */ | ||
135 | return; | ||
136 | } | ||
137 | } | ||
110 | 138 | ||
111 | spin_lock_irqsave(dev->sata_dev.ap->lock, flags); | ||
112 | if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD || | 139 | if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD || |
113 | ((stat->stat == SAM_STAT_CHECK_CONDITION && | 140 | ((stat->stat == SAM_STAT_CHECK_CONDITION && |
114 | dev->sata_dev.command_set == ATAPI_COMMAND_SET))) { | 141 | dev->sata_dev.command_set == ATAPI_COMMAND_SET))) { |
@@ -121,10 +148,6 @@ static void sas_ata_task_done(struct sas_task *task) | |||
121 | if (unlikely(link->eh_info.err_mask)) | 148 | if (unlikely(link->eh_info.err_mask)) |
122 | qc->flags |= ATA_QCFLAG_FAILED; | 149 | qc->flags |= ATA_QCFLAG_FAILED; |
123 | } | 150 | } |
124 | |||
125 | dev->sata_dev.sstatus = resp->sstatus; | ||
126 | dev->sata_dev.serror = resp->serror; | ||
127 | dev->sata_dev.scontrol = resp->scontrol; | ||
128 | } else { | 151 | } else { |
129 | ac = sas_to_ata_err(stat); | 152 | ac = sas_to_ata_err(stat); |
130 | if (ac) { | 153 | if (ac) { |
@@ -144,24 +167,8 @@ static void sas_ata_task_done(struct sas_task *task) | |||
144 | } | 167 | } |
145 | 168 | ||
146 | qc->lldd_task = NULL; | 169 | qc->lldd_task = NULL; |
147 | if (qc->scsicmd) | ||
148 | ASSIGN_SAS_TASK(qc->scsicmd, NULL); | ||
149 | ata_qc_complete(qc); | 170 | ata_qc_complete(qc); |
150 | spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags); | 171 | spin_unlock_irqrestore(ap->lock, flags); |
151 | |||
152 | /* | ||
153 | * If the sas_task has an ata qc, a scsi_cmnd and the aborted | ||
154 | * flag is set, then we must have come in via the libsas EH | ||
155 | * functions. When we exit this function, we need to put the | ||
156 | * scsi_cmnd on the list of finished errors. The ata_qc_complete | ||
157 | * call cleans up the libata side of things but we're protected | ||
158 | * from the scsi_cmnd going away because the scsi_cmnd is owned | ||
159 | * by the EH, making libata's call to scsi_done a NOP. | ||
160 | */ | ||
161 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
162 | if (qc->scsicmd && task->task_state_flags & SAS_TASK_STATE_ABORTED) | ||
163 | scsi_eh_finish_cmd(qc->scsicmd, &sas_ha->eh_done_q); | ||
164 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
165 | 172 | ||
166 | qc_already_gone: | 173 | qc_already_gone: |
167 | list_del_init(&task->list); | 174 | list_del_init(&task->list); |
@@ -170,23 +177,30 @@ qc_already_gone: | |||
170 | 177 | ||
171 | static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) | 178 | static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) |
172 | { | 179 | { |
173 | int res; | 180 | unsigned long flags; |
174 | struct sas_task *task; | 181 | struct sas_task *task; |
175 | struct domain_device *dev = qc->ap->private_data; | 182 | struct scatterlist *sg; |
183 | int ret = AC_ERR_SYSTEM; | ||
184 | unsigned int si, xfer = 0; | ||
185 | struct ata_port *ap = qc->ap; | ||
186 | struct domain_device *dev = ap->private_data; | ||
176 | struct sas_ha_struct *sas_ha = dev->port->ha; | 187 | struct sas_ha_struct *sas_ha = dev->port->ha; |
177 | struct Scsi_Host *host = sas_ha->core.shost; | 188 | struct Scsi_Host *host = sas_ha->core.shost; |
178 | struct sas_internal *i = to_sas_internal(host->transportt); | 189 | struct sas_internal *i = to_sas_internal(host->transportt); |
179 | struct scatterlist *sg; | 190 | |
180 | unsigned int xfer = 0; | 191 | /* TODO: audit callers to ensure they are ready for qc_issue to |
181 | unsigned int si; | 192 | * unconditionally re-enable interrupts |
193 | */ | ||
194 | local_irq_save(flags); | ||
195 | spin_unlock(ap->lock); | ||
182 | 196 | ||
183 | /* If the device fell off, no sense in issuing commands */ | 197 | /* If the device fell off, no sense in issuing commands */ |
184 | if (dev->gone) | 198 | if (test_bit(SAS_DEV_GONE, &dev->state)) |
185 | return AC_ERR_SYSTEM; | 199 | goto out; |
186 | 200 | ||
187 | task = sas_alloc_task(GFP_ATOMIC); | 201 | task = sas_alloc_task(GFP_ATOMIC); |
188 | if (!task) | 202 | if (!task) |
189 | return AC_ERR_SYSTEM; | 203 | goto out; |
190 | task->dev = dev; | 204 | task->dev = dev; |
191 | task->task_proto = SAS_PROTOCOL_STP; | 205 | task->task_proto = SAS_PROTOCOL_STP; |
192 | task->task_done = sas_ata_task_done; | 206 | task->task_done = sas_ata_task_done; |
@@ -231,21 +245,24 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) | |||
231 | ASSIGN_SAS_TASK(qc->scsicmd, task); | 245 | ASSIGN_SAS_TASK(qc->scsicmd, task); |
232 | 246 | ||
233 | if (sas_ha->lldd_max_execute_num < 2) | 247 | if (sas_ha->lldd_max_execute_num < 2) |
234 | res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC); | 248 | ret = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC); |
235 | else | 249 | else |
236 | res = sas_queue_up(task); | 250 | ret = sas_queue_up(task); |
237 | 251 | ||
238 | /* Examine */ | 252 | /* Examine */ |
239 | if (res) { | 253 | if (ret) { |
240 | SAS_DPRINTK("lldd_execute_task returned: %d\n", res); | 254 | SAS_DPRINTK("lldd_execute_task returned: %d\n", ret); |
241 | 255 | ||
242 | if (qc->scsicmd) | 256 | if (qc->scsicmd) |
243 | ASSIGN_SAS_TASK(qc->scsicmd, NULL); | 257 | ASSIGN_SAS_TASK(qc->scsicmd, NULL); |
244 | sas_free_task(task); | 258 | sas_free_task(task); |
245 | return AC_ERR_SYSTEM; | 259 | ret = AC_ERR_SYSTEM; |
246 | } | 260 | } |
247 | 261 | ||
248 | return 0; | 262 | out: |
263 | spin_lock(ap->lock); | ||
264 | local_irq_restore(flags); | ||
265 | return ret; | ||
249 | } | 266 | } |
250 | 267 | ||
251 | static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc) | 268 | static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc) |
@@ -256,83 +273,222 @@ static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc) | |||
256 | return true; | 273 | return true; |
257 | } | 274 | } |
258 | 275 | ||
259 | static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class, | 276 | static struct sas_internal *dev_to_sas_internal(struct domain_device *dev) |
260 | unsigned long deadline) | 277 | { |
278 | return to_sas_internal(dev->port->ha->core.shost->transportt); | ||
279 | } | ||
280 | |||
281 | static void sas_get_ata_command_set(struct domain_device *dev); | ||
282 | |||
283 | int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy) | ||
261 | { | 284 | { |
285 | if (phy->attached_tproto & SAS_PROTOCOL_STP) | ||
286 | dev->tproto = phy->attached_tproto; | ||
287 | if (phy->attached_sata_dev) | ||
288 | dev->tproto |= SATA_DEV; | ||
289 | |||
290 | if (phy->attached_dev_type == SATA_PENDING) | ||
291 | dev->dev_type = SATA_PENDING; | ||
292 | else { | ||
293 | int res; | ||
294 | |||
295 | dev->dev_type = SATA_DEV; | ||
296 | res = sas_get_report_phy_sata(dev->parent, phy->phy_id, | ||
297 | &dev->sata_dev.rps_resp); | ||
298 | if (res) { | ||
299 | SAS_DPRINTK("report phy sata to %016llx:0x%x returned " | ||
300 | "0x%x\n", SAS_ADDR(dev->parent->sas_addr), | ||
301 | phy->phy_id, res); | ||
302 | return res; | ||
303 | } | ||
304 | memcpy(dev->frame_rcvd, &dev->sata_dev.rps_resp.rps.fis, | ||
305 | sizeof(struct dev_to_host_fis)); | ||
306 | /* TODO switch to ata_dev_classify() */ | ||
307 | sas_get_ata_command_set(dev); | ||
308 | } | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static int sas_ata_clear_pending(struct domain_device *dev, struct ex_phy *phy) | ||
313 | { | ||
314 | int res; | ||
315 | |||
316 | /* we weren't pending, so successfully end the reset sequence now */ | ||
317 | if (dev->dev_type != SATA_PENDING) | ||
318 | return 1; | ||
319 | |||
320 | /* hmmm, if this succeeds do we need to repost the domain_device to the | ||
321 | * lldd so it can pick up new parameters? | ||
322 | */ | ||
323 | res = sas_get_ata_info(dev, phy); | ||
324 | if (res) | ||
325 | return 0; /* retry */ | ||
326 | else | ||
327 | return 1; | ||
328 | } | ||
329 | |||
330 | static int smp_ata_check_ready(struct ata_link *link) | ||
331 | { | ||
332 | int res; | ||
262 | struct ata_port *ap = link->ap; | 333 | struct ata_port *ap = link->ap; |
263 | struct domain_device *dev = ap->private_data; | 334 | struct domain_device *dev = ap->private_data; |
264 | struct sas_internal *i = | 335 | struct domain_device *ex_dev = dev->parent; |
265 | to_sas_internal(dev->port->ha->core.shost->transportt); | 336 | struct sas_phy *phy = sas_get_local_phy(dev); |
266 | int res = TMF_RESP_FUNC_FAILED; | 337 | struct ex_phy *ex_phy = &ex_dev->ex_dev.ex_phy[phy->number]; |
267 | int ret = 0; | ||
268 | 338 | ||
269 | if (i->dft->lldd_I_T_nexus_reset) | 339 | res = sas_ex_phy_discover(ex_dev, phy->number); |
270 | res = i->dft->lldd_I_T_nexus_reset(dev); | 340 | sas_put_local_phy(phy); |
271 | 341 | ||
272 | if (res != TMF_RESP_FUNC_COMPLETE) { | 342 | /* break the wait early if the expander is unreachable, |
273 | SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __func__); | 343 | * otherwise keep polling |
274 | ret = -EAGAIN; | 344 | */ |
345 | if (res == -ECOMM) | ||
346 | return res; | ||
347 | if (res != SMP_RESP_FUNC_ACC) | ||
348 | return 0; | ||
349 | |||
350 | switch (ex_phy->attached_dev_type) { | ||
351 | case SATA_PENDING: | ||
352 | return 0; | ||
353 | case SAS_END_DEV: | ||
354 | if (ex_phy->attached_sata_dev) | ||
355 | return sas_ata_clear_pending(dev, ex_phy); | ||
356 | default: | ||
357 | return -ENODEV; | ||
275 | } | 358 | } |
359 | } | ||
276 | 360 | ||
277 | switch (dev->sata_dev.command_set) { | 361 | static int local_ata_check_ready(struct ata_link *link) |
278 | case ATA_COMMAND_SET: | 362 | { |
279 | SAS_DPRINTK("%s: Found ATA device.\n", __func__); | 363 | struct ata_port *ap = link->ap; |
280 | *class = ATA_DEV_ATA; | 364 | struct domain_device *dev = ap->private_data; |
281 | break; | 365 | struct sas_internal *i = dev_to_sas_internal(dev); |
282 | case ATAPI_COMMAND_SET: | 366 | |
283 | SAS_DPRINTK("%s: Found ATAPI device.\n", __func__); | 367 | if (i->dft->lldd_ata_check_ready) |
284 | *class = ATA_DEV_ATAPI; | 368 | return i->dft->lldd_ata_check_ready(dev); |
285 | break; | 369 | else { |
286 | default: | 370 | /* lldd's that don't implement 'ready' checking get the |
287 | SAS_DPRINTK("%s: Unknown SATA command set: %d.\n", | 371 | * old default behavior of not coordinating reset |
288 | __func__, | 372 | * recovery with libata |
289 | dev->sata_dev.command_set); | 373 | */ |
290 | *class = ATA_DEV_UNKNOWN; | 374 | return 1; |
291 | break; | ||
292 | } | 375 | } |
376 | } | ||
293 | 377 | ||
294 | ap->cbl = ATA_CBL_SATA; | 378 | static int sas_ata_printk(const char *level, const struct domain_device *ddev, |
295 | return ret; | 379 | const char *fmt, ...) |
380 | { | ||
381 | struct ata_port *ap = ddev->sata_dev.ap; | ||
382 | struct device *dev = &ddev->rphy->dev; | ||
383 | struct va_format vaf; | ||
384 | va_list args; | ||
385 | int r; | ||
386 | |||
387 | va_start(args, fmt); | ||
388 | |||
389 | vaf.fmt = fmt; | ||
390 | vaf.va = &args; | ||
391 | |||
392 | r = printk("%ssas: ata%u: %s: %pV", | ||
393 | level, ap->print_id, dev_name(dev), &vaf); | ||
394 | |||
395 | va_end(args); | ||
396 | |||
397 | return r; | ||
296 | } | 398 | } |
297 | 399 | ||
298 | static int sas_ata_soft_reset(struct ata_link *link, unsigned int *class, | 400 | static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class, |
299 | unsigned long deadline) | 401 | unsigned long deadline) |
300 | { | 402 | { |
403 | int ret = 0, res; | ||
404 | struct sas_phy *phy; | ||
301 | struct ata_port *ap = link->ap; | 405 | struct ata_port *ap = link->ap; |
406 | int (*check_ready)(struct ata_link *link); | ||
302 | struct domain_device *dev = ap->private_data; | 407 | struct domain_device *dev = ap->private_data; |
303 | struct sas_internal *i = | 408 | struct sas_internal *i = dev_to_sas_internal(dev); |
304 | to_sas_internal(dev->port->ha->core.shost->transportt); | ||
305 | int res = TMF_RESP_FUNC_FAILED; | ||
306 | int ret = 0; | ||
307 | 409 | ||
308 | if (i->dft->lldd_ata_soft_reset) | 410 | res = i->dft->lldd_I_T_nexus_reset(dev); |
309 | res = i->dft->lldd_ata_soft_reset(dev); | 411 | if (res == -ENODEV) |
412 | return res; | ||
310 | 413 | ||
311 | if (res != TMF_RESP_FUNC_COMPLETE) { | 414 | if (res != TMF_RESP_FUNC_COMPLETE) |
312 | SAS_DPRINTK("%s: Unable to soft reset\n", __func__); | 415 | sas_ata_printk(KERN_DEBUG, dev, "Unable to reset ata device?\n"); |
313 | ret = -EAGAIN; | 416 | |
314 | } | 417 | phy = sas_get_local_phy(dev); |
418 | if (scsi_is_sas_phy_local(phy)) | ||
419 | check_ready = local_ata_check_ready; | ||
420 | else | ||
421 | check_ready = smp_ata_check_ready; | ||
422 | sas_put_local_phy(phy); | ||
423 | |||
424 | ret = ata_wait_after_reset(link, deadline, check_ready); | ||
425 | if (ret && ret != -EAGAIN) | ||
426 | sas_ata_printk(KERN_ERR, dev, "reset failed (errno=%d)\n", ret); | ||
315 | 427 | ||
428 | /* XXX: if the class changes during the reset the upper layer | ||
429 | * should be informed, if the device has gone away we assume | ||
430 | * libsas will eventually delete it | ||
431 | */ | ||
316 | switch (dev->sata_dev.command_set) { | 432 | switch (dev->sata_dev.command_set) { |
317 | case ATA_COMMAND_SET: | 433 | case ATA_COMMAND_SET: |
318 | SAS_DPRINTK("%s: Found ATA device.\n", __func__); | ||
319 | *class = ATA_DEV_ATA; | 434 | *class = ATA_DEV_ATA; |
320 | break; | 435 | break; |
321 | case ATAPI_COMMAND_SET: | 436 | case ATAPI_COMMAND_SET: |
322 | SAS_DPRINTK("%s: Found ATAPI device.\n", __func__); | ||
323 | *class = ATA_DEV_ATAPI; | 437 | *class = ATA_DEV_ATAPI; |
324 | break; | 438 | break; |
325 | default: | ||
326 | SAS_DPRINTK("%s: Unknown SATA command set: %d.\n", | ||
327 | __func__, dev->sata_dev.command_set); | ||
328 | *class = ATA_DEV_UNKNOWN; | ||
329 | break; | ||
330 | } | 439 | } |
331 | 440 | ||
332 | ap->cbl = ATA_CBL_SATA; | 441 | ap->cbl = ATA_CBL_SATA; |
333 | return ret; | 442 | return ret; |
334 | } | 443 | } |
335 | 444 | ||
445 | /* | ||
446 | * notify the lldd to forget the sas_task for this internal ata command | ||
447 | * that bypasses scsi-eh | ||
448 | */ | ||
449 | static void sas_ata_internal_abort(struct sas_task *task) | ||
450 | { | ||
451 | struct sas_internal *si = dev_to_sas_internal(task->dev); | ||
452 | unsigned long flags; | ||
453 | int res; | ||
454 | |||
455 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
456 | if (task->task_state_flags & SAS_TASK_STATE_ABORTED || | ||
457 | task->task_state_flags & SAS_TASK_STATE_DONE) { | ||
458 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
459 | SAS_DPRINTK("%s: Task %p already finished.\n", __func__, | ||
460 | task); | ||
461 | goto out; | ||
462 | } | ||
463 | task->task_state_flags |= SAS_TASK_STATE_ABORTED; | ||
464 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
465 | |||
466 | res = si->dft->lldd_abort_task(task); | ||
467 | |||
468 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
469 | if (task->task_state_flags & SAS_TASK_STATE_DONE || | ||
470 | res == TMF_RESP_FUNC_COMPLETE) { | ||
471 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
472 | goto out; | ||
473 | } | ||
474 | |||
475 | /* XXX we are not prepared to deal with ->lldd_abort_task() | ||
476 | * failures. TODO: lldds need to unconditionally forget about | ||
477 | * aborted ata tasks, otherwise we (likely) leak the sas task | ||
478 | * here | ||
479 | */ | ||
480 | SAS_DPRINTK("%s: Task %p leaked.\n", __func__, task); | ||
481 | |||
482 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) | ||
483 | task->task_state_flags &= ~SAS_TASK_STATE_ABORTED; | ||
484 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
485 | |||
486 | return; | ||
487 | out: | ||
488 | list_del_init(&task->list); | ||
489 | sas_free_task(task); | ||
490 | } | ||
491 | |||
336 | static void sas_ata_post_internal(struct ata_queued_cmd *qc) | 492 | static void sas_ata_post_internal(struct ata_queued_cmd *qc) |
337 | { | 493 | { |
338 | if (qc->flags & ATA_QCFLAG_FAILED) | 494 | if (qc->flags & ATA_QCFLAG_FAILED) |
@@ -340,30 +496,35 @@ static void sas_ata_post_internal(struct ata_queued_cmd *qc) | |||
340 | 496 | ||
341 | if (qc->err_mask) { | 497 | if (qc->err_mask) { |
342 | /* | 498 | /* |
343 | * Find the sas_task and kill it. By this point, | 499 | * Find the sas_task and kill it. By this point, libata |
344 | * libata has decided to kill the qc, so we needn't | 500 | * has decided to kill the qc and has frozen the port. |
345 | * bother with sas_ata_task_done. But we still | 501 | * In this state sas_ata_task_done() will no longer free |
346 | * ought to abort the task. | 502 | * the sas_task, so we need to notify the lldd (via |
503 | * ->lldd_abort_task) that the task is dead and free it | ||
504 | * ourselves. | ||
347 | */ | 505 | */ |
348 | struct sas_task *task = qc->lldd_task; | 506 | struct sas_task *task = qc->lldd_task; |
349 | unsigned long flags; | ||
350 | 507 | ||
351 | qc->lldd_task = NULL; | 508 | qc->lldd_task = NULL; |
352 | if (task) { | 509 | if (!task) |
353 | /* Should this be a AT(API) device reset? */ | 510 | return; |
354 | spin_lock_irqsave(&task->task_state_lock, flags); | 511 | task->uldd_task = NULL; |
355 | task->task_state_flags |= SAS_TASK_NEED_DEV_RESET; | 512 | sas_ata_internal_abort(task); |
356 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
357 | |||
358 | task->uldd_task = NULL; | ||
359 | __sas_task_abort(task); | ||
360 | } | ||
361 | } | 513 | } |
362 | } | 514 | } |
363 | 515 | ||
516 | |||
517 | static void sas_ata_set_dmamode(struct ata_port *ap, struct ata_device *ata_dev) | ||
518 | { | ||
519 | struct domain_device *dev = ap->private_data; | ||
520 | struct sas_internal *i = dev_to_sas_internal(dev); | ||
521 | |||
522 | if (i->dft->lldd_ata_set_dmamode) | ||
523 | i->dft->lldd_ata_set_dmamode(dev); | ||
524 | } | ||
525 | |||
364 | static struct ata_port_operations sas_sata_ops = { | 526 | static struct ata_port_operations sas_sata_ops = { |
365 | .prereset = ata_std_prereset, | 527 | .prereset = ata_std_prereset, |
366 | .softreset = sas_ata_soft_reset, | ||
367 | .hardreset = sas_ata_hard_reset, | 528 | .hardreset = sas_ata_hard_reset, |
368 | .postreset = ata_std_postreset, | 529 | .postreset = ata_std_postreset, |
369 | .error_handler = ata_std_error_handler, | 530 | .error_handler = ata_std_error_handler, |
@@ -374,6 +535,7 @@ static struct ata_port_operations sas_sata_ops = { | |||
374 | .qc_fill_rtf = sas_ata_qc_fill_rtf, | 535 | .qc_fill_rtf = sas_ata_qc_fill_rtf, |
375 | .port_start = ata_sas_port_start, | 536 | .port_start = ata_sas_port_start, |
376 | .port_stop = ata_sas_port_stop, | 537 | .port_stop = ata_sas_port_stop, |
538 | .set_dmamode = sas_ata_set_dmamode, | ||
377 | }; | 539 | }; |
378 | 540 | ||
379 | static struct ata_port_info sata_port_info = { | 541 | static struct ata_port_info sata_port_info = { |
@@ -384,11 +546,10 @@ static struct ata_port_info sata_port_info = { | |||
384 | .port_ops = &sas_sata_ops | 546 | .port_ops = &sas_sata_ops |
385 | }; | 547 | }; |
386 | 548 | ||
387 | int sas_ata_init_host_and_port(struct domain_device *found_dev, | 549 | int sas_ata_init_host_and_port(struct domain_device *found_dev) |
388 | struct scsi_target *starget) | ||
389 | { | 550 | { |
390 | struct Scsi_Host *shost = dev_to_shost(&starget->dev); | 551 | struct sas_ha_struct *ha = found_dev->port->ha; |
391 | struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); | 552 | struct Scsi_Host *shost = ha->core.shost; |
392 | struct ata_port *ap; | 553 | struct ata_port *ap; |
393 | 554 | ||
394 | ata_host_init(&found_dev->sata_dev.ata_host, | 555 | ata_host_init(&found_dev->sata_dev.ata_host, |
@@ -406,6 +567,8 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev, | |||
406 | ap->private_data = found_dev; | 567 | ap->private_data = found_dev; |
407 | ap->cbl = ATA_CBL_SATA; | 568 | ap->cbl = ATA_CBL_SATA; |
408 | ap->scsi_host = shost; | 569 | ap->scsi_host = shost; |
570 | /* publish initialized ata port */ | ||
571 | smp_wmb(); | ||
409 | found_dev->sata_dev.ap = ap; | 572 | found_dev->sata_dev.ap = ap; |
410 | 573 | ||
411 | return 0; | 574 | return 0; |
@@ -436,168 +599,14 @@ void sas_ata_task_abort(struct sas_task *task) | |||
436 | complete(waiting); | 599 | complete(waiting); |
437 | } | 600 | } |
438 | 601 | ||
439 | static void sas_task_timedout(unsigned long _task) | ||
440 | { | ||
441 | struct sas_task *task = (void *) _task; | ||
442 | unsigned long flags; | ||
443 | |||
444 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
445 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) | ||
446 | task->task_state_flags |= SAS_TASK_STATE_ABORTED; | ||
447 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
448 | |||
449 | complete(&task->completion); | ||
450 | } | ||
451 | |||
452 | static void sas_disc_task_done(struct sas_task *task) | ||
453 | { | ||
454 | if (!del_timer(&task->timer)) | ||
455 | return; | ||
456 | complete(&task->completion); | ||
457 | } | ||
458 | |||
459 | #define SAS_DEV_TIMEOUT 10 | ||
460 | |||
461 | /** | ||
462 | * sas_execute_task -- Basic task processing for discovery | ||
463 | * @task: the task to be executed | ||
464 | * @buffer: pointer to buffer to do I/O | ||
465 | * @size: size of @buffer | ||
466 | * @dma_dir: DMA direction. DMA_xxx | ||
467 | */ | ||
468 | static int sas_execute_task(struct sas_task *task, void *buffer, int size, | ||
469 | enum dma_data_direction dma_dir) | ||
470 | { | ||
471 | int res = 0; | ||
472 | struct scatterlist *scatter = NULL; | ||
473 | struct task_status_struct *ts = &task->task_status; | ||
474 | int num_scatter = 0; | ||
475 | int retries = 0; | ||
476 | struct sas_internal *i = | ||
477 | to_sas_internal(task->dev->port->ha->core.shost->transportt); | ||
478 | |||
479 | if (dma_dir != DMA_NONE) { | ||
480 | scatter = kzalloc(sizeof(*scatter), GFP_KERNEL); | ||
481 | if (!scatter) | ||
482 | goto out; | ||
483 | |||
484 | sg_init_one(scatter, buffer, size); | ||
485 | num_scatter = 1; | ||
486 | } | ||
487 | |||
488 | task->task_proto = task->dev->tproto; | ||
489 | task->scatter = scatter; | ||
490 | task->num_scatter = num_scatter; | ||
491 | task->total_xfer_len = size; | ||
492 | task->data_dir = dma_dir; | ||
493 | task->task_done = sas_disc_task_done; | ||
494 | if (dma_dir != DMA_NONE && | ||
495 | sas_protocol_ata(task->task_proto)) { | ||
496 | task->num_scatter = dma_map_sg(task->dev->port->ha->dev, | ||
497 | task->scatter, | ||
498 | task->num_scatter, | ||
499 | task->data_dir); | ||
500 | } | ||
501 | |||
502 | for (retries = 0; retries < 5; retries++) { | ||
503 | task->task_state_flags = SAS_TASK_STATE_PENDING; | ||
504 | init_completion(&task->completion); | ||
505 | |||
506 | task->timer.data = (unsigned long) task; | ||
507 | task->timer.function = sas_task_timedout; | ||
508 | task->timer.expires = jiffies + SAS_DEV_TIMEOUT*HZ; | ||
509 | add_timer(&task->timer); | ||
510 | |||
511 | res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); | ||
512 | if (res) { | ||
513 | del_timer(&task->timer); | ||
514 | SAS_DPRINTK("executing SAS discovery task failed:%d\n", | ||
515 | res); | ||
516 | goto ex_err; | ||
517 | } | ||
518 | wait_for_completion(&task->completion); | ||
519 | res = -ECOMM; | ||
520 | if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { | ||
521 | int res2; | ||
522 | SAS_DPRINTK("task aborted, flags:0x%x\n", | ||
523 | task->task_state_flags); | ||
524 | res2 = i->dft->lldd_abort_task(task); | ||
525 | SAS_DPRINTK("came back from abort task\n"); | ||
526 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { | ||
527 | if (res2 == TMF_RESP_FUNC_COMPLETE) | ||
528 | continue; /* Retry the task */ | ||
529 | else | ||
530 | goto ex_err; | ||
531 | } | ||
532 | } | ||
533 | if (task->task_status.stat == SAM_STAT_BUSY || | ||
534 | task->task_status.stat == SAM_STAT_TASK_SET_FULL || | ||
535 | task->task_status.stat == SAS_QUEUE_FULL) { | ||
536 | SAS_DPRINTK("task: q busy, sleeping...\n"); | ||
537 | schedule_timeout_interruptible(HZ); | ||
538 | } else if (task->task_status.stat == SAM_STAT_CHECK_CONDITION) { | ||
539 | struct scsi_sense_hdr shdr; | ||
540 | |||
541 | if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size, | ||
542 | &shdr)) { | ||
543 | SAS_DPRINTK("couldn't normalize sense\n"); | ||
544 | continue; | ||
545 | } | ||
546 | if ((shdr.sense_key == 6 && shdr.asc == 0x29) || | ||
547 | (shdr.sense_key == 2 && shdr.asc == 4 && | ||
548 | shdr.ascq == 1)) { | ||
549 | SAS_DPRINTK("device %016llx LUN: %016llx " | ||
550 | "powering up or not ready yet, " | ||
551 | "sleeping...\n", | ||
552 | SAS_ADDR(task->dev->sas_addr), | ||
553 | SAS_ADDR(task->ssp_task.LUN)); | ||
554 | |||
555 | schedule_timeout_interruptible(5*HZ); | ||
556 | } else if (shdr.sense_key == 1) { | ||
557 | res = 0; | ||
558 | break; | ||
559 | } else if (shdr.sense_key == 5) { | ||
560 | break; | ||
561 | } else { | ||
562 | SAS_DPRINTK("dev %016llx LUN: %016llx " | ||
563 | "sense key:0x%x ASC:0x%x ASCQ:0x%x" | ||
564 | "\n", | ||
565 | SAS_ADDR(task->dev->sas_addr), | ||
566 | SAS_ADDR(task->ssp_task.LUN), | ||
567 | shdr.sense_key, | ||
568 | shdr.asc, shdr.ascq); | ||
569 | } | ||
570 | } else if (task->task_status.resp != SAS_TASK_COMPLETE || | ||
571 | task->task_status.stat != SAM_STAT_GOOD) { | ||
572 | SAS_DPRINTK("task finished with resp:0x%x, " | ||
573 | "stat:0x%x\n", | ||
574 | task->task_status.resp, | ||
575 | task->task_status.stat); | ||
576 | goto ex_err; | ||
577 | } else { | ||
578 | res = 0; | ||
579 | break; | ||
580 | } | ||
581 | } | ||
582 | ex_err: | ||
583 | if (dma_dir != DMA_NONE) { | ||
584 | if (sas_protocol_ata(task->task_proto)) | ||
585 | dma_unmap_sg(task->dev->port->ha->dev, | ||
586 | task->scatter, task->num_scatter, | ||
587 | task->data_dir); | ||
588 | kfree(scatter); | ||
589 | } | ||
590 | out: | ||
591 | return res; | ||
592 | } | ||
593 | |||
594 | /* ---------- SATA ---------- */ | ||
595 | |||
596 | static void sas_get_ata_command_set(struct domain_device *dev) | 602 | static void sas_get_ata_command_set(struct domain_device *dev) |
597 | { | 603 | { |
598 | struct dev_to_host_fis *fis = | 604 | struct dev_to_host_fis *fis = |
599 | (struct dev_to_host_fis *) dev->frame_rcvd; | 605 | (struct dev_to_host_fis *) dev->frame_rcvd; |
600 | 606 | ||
607 | if (dev->dev_type == SATA_PENDING) | ||
608 | return; | ||
609 | |||
601 | if ((fis->sector_count == 1 && /* ATA */ | 610 | if ((fis->sector_count == 1 && /* ATA */ |
602 | fis->lbal == 1 && | 611 | fis->lbal == 1 && |
603 | fis->lbam == 0 && | 612 | fis->lbam == 0 && |
@@ -636,224 +645,152 @@ static void sas_get_ata_command_set(struct domain_device *dev) | |||
636 | dev->sata_dev.command_set = ATAPI_COMMAND_SET; | 645 | dev->sata_dev.command_set = ATAPI_COMMAND_SET; |
637 | } | 646 | } |
638 | 647 | ||
639 | /** | 648 | void sas_probe_sata(struct asd_sas_port *port) |
640 | * sas_issue_ata_cmd -- Basic SATA command processing for discovery | ||
641 | * @dev: the device to send the command to | ||
642 | * @command: the command register | ||
643 | * @features: the features register | ||
644 | * @buffer: pointer to buffer to do I/O | ||
645 | * @size: size of @buffer | ||
646 | * @dma_dir: DMA direction. DMA_xxx | ||
647 | */ | ||
648 | static int sas_issue_ata_cmd(struct domain_device *dev, u8 command, | ||
649 | u8 features, void *buffer, int size, | ||
650 | enum dma_data_direction dma_dir) | ||
651 | { | ||
652 | int res = 0; | ||
653 | struct sas_task *task; | ||
654 | struct dev_to_host_fis *d2h_fis = (struct dev_to_host_fis *) | ||
655 | &dev->frame_rcvd[0]; | ||
656 | |||
657 | res = -ENOMEM; | ||
658 | task = sas_alloc_task(GFP_KERNEL); | ||
659 | if (!task) | ||
660 | goto out; | ||
661 | |||
662 | task->dev = dev; | ||
663 | |||
664 | task->ata_task.fis.fis_type = 0x27; | ||
665 | task->ata_task.fis.command = command; | ||
666 | task->ata_task.fis.features = features; | ||
667 | task->ata_task.fis.device = d2h_fis->device; | ||
668 | task->ata_task.retry_count = 1; | ||
669 | |||
670 | res = sas_execute_task(task, buffer, size, dma_dir); | ||
671 | |||
672 | sas_free_task(task); | ||
673 | out: | ||
674 | return res; | ||
675 | } | ||
676 | |||
677 | #define ATA_IDENTIFY_DEV 0xEC | ||
678 | #define ATA_IDENTIFY_PACKET_DEV 0xA1 | ||
679 | #define ATA_SET_FEATURES 0xEF | ||
680 | #define ATA_FEATURE_PUP_STBY_SPIN_UP 0x07 | ||
681 | |||
682 | /** | ||
683 | * sas_discover_sata_dev -- discover a STP/SATA device (SATA_DEV) | ||
684 | * @dev: STP/SATA device of interest (ATA/ATAPI) | ||
685 | * | ||
686 | * The LLDD has already been notified of this device, so that we can | ||
687 | * send FISes to it. Here we try to get IDENTIFY DEVICE or IDENTIFY | ||
688 | * PACKET DEVICE, if ATAPI device, so that the LLDD can fine-tune its | ||
689 | * performance for this device. | ||
690 | */ | ||
691 | static int sas_discover_sata_dev(struct domain_device *dev) | ||
692 | { | 649 | { |
693 | int res; | 650 | struct domain_device *dev, *n; |
694 | __le16 *identify_x; | 651 | int err; |
695 | u8 command; | ||
696 | 652 | ||
697 | identify_x = kzalloc(512, GFP_KERNEL); | 653 | mutex_lock(&port->ha->disco_mutex); |
698 | if (!identify_x) | 654 | list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) { |
699 | return -ENOMEM; | 655 | if (!dev_is_sata(dev)) |
700 | 656 | continue; | |
701 | if (dev->sata_dev.command_set == ATA_COMMAND_SET) { | ||
702 | dev->sata_dev.identify_device = identify_x; | ||
703 | command = ATA_IDENTIFY_DEV; | ||
704 | } else { | ||
705 | dev->sata_dev.identify_packet_device = identify_x; | ||
706 | command = ATA_IDENTIFY_PACKET_DEV; | ||
707 | } | ||
708 | 657 | ||
709 | res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512, | 658 | err = sas_ata_init_host_and_port(dev); |
710 | DMA_FROM_DEVICE); | 659 | if (err) |
711 | if (res) | 660 | sas_fail_probe(dev, __func__, err); |
712 | goto out_err; | 661 | else |
713 | 662 | ata_sas_async_port_init(dev->sata_dev.ap); | |
714 | /* lives on the media? */ | ||
715 | if (le16_to_cpu(identify_x[0]) & 4) { | ||
716 | /* incomplete response */ | ||
717 | SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to " | ||
718 | "dev %llx\n", SAS_ADDR(dev->sas_addr)); | ||
719 | if (!(identify_x[83] & cpu_to_le16(1<<6))) | ||
720 | goto cont1; | ||
721 | res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES, | ||
722 | ATA_FEATURE_PUP_STBY_SPIN_UP, | ||
723 | NULL, 0, DMA_NONE); | ||
724 | if (res) | ||
725 | goto cont1; | ||
726 | |||
727 | schedule_timeout_interruptible(5*HZ); /* More time? */ | ||
728 | res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512, | ||
729 | DMA_FROM_DEVICE); | ||
730 | if (res) | ||
731 | goto out_err; | ||
732 | } | 663 | } |
733 | cont1: | 664 | mutex_unlock(&port->ha->disco_mutex); |
734 | /* XXX Hint: register this SATA device with SATL. | ||
735 | When this returns, dev->sata_dev->lu is alive and | ||
736 | present. | ||
737 | sas_satl_register_dev(dev); | ||
738 | */ | ||
739 | 665 | ||
740 | sas_fill_in_rphy(dev, dev->rphy); | 666 | list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) { |
667 | if (!dev_is_sata(dev)) | ||
668 | continue; | ||
741 | 669 | ||
742 | return 0; | 670 | sas_ata_wait_eh(dev); |
743 | out_err: | ||
744 | dev->sata_dev.identify_packet_device = NULL; | ||
745 | dev->sata_dev.identify_device = NULL; | ||
746 | kfree(identify_x); | ||
747 | return res; | ||
748 | } | ||
749 | 671 | ||
750 | static int sas_discover_sata_pm(struct domain_device *dev) | 672 | /* if libata could not bring the link up, don't surface |
751 | { | 673 | * the device |
752 | return -ENODEV; | 674 | */ |
675 | if (ata_dev_disabled(sas_to_ata_dev(dev))) | ||
676 | sas_fail_probe(dev, __func__, -ENODEV); | ||
677 | } | ||
753 | } | 678 | } |
754 | 679 | ||
755 | /** | 680 | /** |
756 | * sas_discover_sata -- discover an STP/SATA domain device | 681 | * sas_discover_sata -- discover an STP/SATA domain device |
757 | * @dev: pointer to struct domain_device of interest | 682 | * @dev: pointer to struct domain_device of interest |
758 | * | 683 | * |
759 | * First we notify the LLDD of this device, so we can send frames to | 684 | * Devices directly attached to a HA port, have no parents. All other |
760 | * it. Then depending on the type of device we call the appropriate | 685 | * devices do, and should have their "parent" pointer set appropriately |
761 | * discover functions. Once device discover is done, we notify the | 686 | * before calling this function. |
762 | * LLDD so that it can fine-tune its parameters for the device, by | ||
763 | * removing it and then adding it. That is, the second time around, | ||
764 | * the driver would have certain fields, that it is looking at, set. | ||
765 | * Finally we initialize the kobj so that the device can be added to | ||
766 | * the system at registration time. Devices directly attached to a HA | ||
767 | * port, have no parents. All other devices do, and should have their | ||
768 | * "parent" pointer set appropriately before calling this function. | ||
769 | */ | 687 | */ |
770 | int sas_discover_sata(struct domain_device *dev) | 688 | int sas_discover_sata(struct domain_device *dev) |
771 | { | 689 | { |
772 | int res; | 690 | int res; |
773 | 691 | ||
692 | if (dev->dev_type == SATA_PM) | ||
693 | return -ENODEV; | ||
694 | |||
774 | sas_get_ata_command_set(dev); | 695 | sas_get_ata_command_set(dev); |
696 | sas_fill_in_rphy(dev, dev->rphy); | ||
775 | 697 | ||
776 | res = sas_notify_lldd_dev_found(dev); | 698 | res = sas_notify_lldd_dev_found(dev); |
777 | if (res) | 699 | if (res) |
778 | return res; | 700 | return res; |
779 | 701 | ||
780 | switch (dev->dev_type) { | 702 | sas_discover_event(dev->port, DISCE_PROBE); |
781 | case SATA_DEV: | 703 | return 0; |
782 | res = sas_discover_sata_dev(dev); | ||
783 | break; | ||
784 | case SATA_PM: | ||
785 | res = sas_discover_sata_pm(dev); | ||
786 | break; | ||
787 | default: | ||
788 | break; | ||
789 | } | ||
790 | sas_notify_lldd_dev_gone(dev); | ||
791 | if (!res) { | ||
792 | sas_notify_lldd_dev_found(dev); | ||
793 | res = sas_rphy_add(dev->rphy); | ||
794 | } | ||
795 | |||
796 | return res; | ||
797 | } | 704 | } |
798 | 705 | ||
799 | void sas_ata_strategy_handler(struct Scsi_Host *shost) | 706 | static void async_sas_ata_eh(void *data, async_cookie_t cookie) |
800 | { | 707 | { |
801 | struct scsi_device *sdev; | 708 | struct domain_device *dev = data; |
709 | struct ata_port *ap = dev->sata_dev.ap; | ||
710 | struct sas_ha_struct *ha = dev->port->ha; | ||
802 | 711 | ||
803 | shost_for_each_device(sdev, shost) { | 712 | /* hold a reference over eh since we may be racing with final |
804 | struct domain_device *ddev = sdev_to_domain_dev(sdev); | 713 | * remove once all commands are completed |
805 | struct ata_port *ap = ddev->sata_dev.ap; | 714 | */ |
715 | kref_get(&dev->kref); | ||
716 | sas_ata_printk(KERN_DEBUG, dev, "dev error handler\n"); | ||
717 | ata_scsi_port_error_handler(ha->core.shost, ap); | ||
718 | sas_put_device(dev); | ||
719 | } | ||
806 | 720 | ||
807 | if (!dev_is_sata(ddev)) | 721 | static bool sas_ata_dev_eh_valid(struct domain_device *dev) |
808 | continue; | 722 | { |
723 | struct ata_port *ap; | ||
809 | 724 | ||
810 | ata_port_printk(ap, KERN_DEBUG, "sas eh calling libata port error handler"); | 725 | if (!dev_is_sata(dev)) |
811 | ata_scsi_port_error_handler(shost, ap); | 726 | return false; |
812 | } | 727 | ap = dev->sata_dev.ap; |
728 | /* consume fully initialized ata ports */ | ||
729 | smp_rmb(); | ||
730 | return !!ap; | ||
813 | } | 731 | } |
814 | 732 | ||
815 | int sas_ata_timed_out(struct scsi_cmnd *cmd, struct sas_task *task, | 733 | void sas_ata_strategy_handler(struct Scsi_Host *shost) |
816 | enum blk_eh_timer_return *rtn) | ||
817 | { | 734 | { |
818 | struct domain_device *ddev = cmd_to_domain_dev(cmd); | 735 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); |
736 | LIST_HEAD(async); | ||
737 | int i; | ||
738 | |||
739 | /* it's ok to defer revalidation events during ata eh, these | ||
740 | * disks are in one of three states: | ||
741 | * 1/ present for initial domain discovery, and these | ||
742 | * resets will cause bcn flutters | ||
743 | * 2/ hot removed, we'll discover that after eh fails | ||
744 | * 3/ hot added after initial discovery, lost the race, and need | ||
745 | * to catch the next train. | ||
746 | */ | ||
747 | sas_disable_revalidation(sas_ha); | ||
819 | 748 | ||
820 | if (!dev_is_sata(ddev) || task) | 749 | spin_lock_irq(&sas_ha->phy_port_lock); |
821 | return 0; | 750 | for (i = 0; i < sas_ha->num_phys; i++) { |
751 | struct asd_sas_port *port = sas_ha->sas_port[i]; | ||
752 | struct domain_device *dev; | ||
822 | 753 | ||
823 | /* we're a sata device with no task, so this must be a libata | 754 | spin_lock(&port->dev_list_lock); |
824 | * eh timeout. Ideally should hook into libata timeout | 755 | list_for_each_entry(dev, &port->dev_list, dev_list_node) { |
825 | * handling, but there's no point, it just wants to activate | 756 | if (!sas_ata_dev_eh_valid(dev)) |
826 | * the eh thread */ | 757 | continue; |
827 | *rtn = BLK_EH_NOT_HANDLED; | 758 | async_schedule_domain(async_sas_ata_eh, dev, &async); |
828 | return 1; | 759 | } |
760 | spin_unlock(&port->dev_list_lock); | ||
761 | } | ||
762 | spin_unlock_irq(&sas_ha->phy_port_lock); | ||
763 | |||
764 | async_synchronize_full_domain(&async); | ||
765 | |||
766 | sas_enable_revalidation(sas_ha); | ||
829 | } | 767 | } |
830 | 768 | ||
831 | int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, | 769 | void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, |
832 | struct list_head *done_q) | 770 | struct list_head *done_q) |
833 | { | 771 | { |
834 | int rtn = 0; | ||
835 | struct scsi_cmnd *cmd, *n; | 772 | struct scsi_cmnd *cmd, *n; |
836 | struct ata_port *ap; | 773 | struct domain_device *eh_dev; |
837 | 774 | ||
838 | do { | 775 | do { |
839 | LIST_HEAD(sata_q); | 776 | LIST_HEAD(sata_q); |
840 | 777 | eh_dev = NULL; | |
841 | ap = NULL; | ||
842 | 778 | ||
843 | list_for_each_entry_safe(cmd, n, work_q, eh_entry) { | 779 | list_for_each_entry_safe(cmd, n, work_q, eh_entry) { |
844 | struct domain_device *ddev = cmd_to_domain_dev(cmd); | 780 | struct domain_device *ddev = cmd_to_domain_dev(cmd); |
845 | 781 | ||
846 | if (!dev_is_sata(ddev) || TO_SAS_TASK(cmd)) | 782 | if (!dev_is_sata(ddev) || TO_SAS_TASK(cmd)) |
847 | continue; | 783 | continue; |
848 | if (ap && ap != ddev->sata_dev.ap) | 784 | if (eh_dev && eh_dev != ddev) |
849 | continue; | 785 | continue; |
850 | ap = ddev->sata_dev.ap; | 786 | eh_dev = ddev; |
851 | rtn = 1; | ||
852 | list_move(&cmd->eh_entry, &sata_q); | 787 | list_move(&cmd->eh_entry, &sata_q); |
853 | } | 788 | } |
854 | 789 | ||
855 | if (!list_empty(&sata_q)) { | 790 | if (!list_empty(&sata_q)) { |
856 | ata_port_printk(ap, KERN_DEBUG, "sas eh calling libata cmd error handler\n"); | 791 | struct ata_port *ap = eh_dev->sata_dev.ap; |
792 | |||
793 | sas_ata_printk(KERN_DEBUG, eh_dev, "cmd error handler\n"); | ||
857 | ata_scsi_cmd_error_handler(shost, ap, &sata_q); | 794 | ata_scsi_cmd_error_handler(shost, ap, &sata_q); |
858 | /* | 795 | /* |
859 | * ata's error handler may leave the cmd on the list | 796 | * ata's error handler may leave the cmd on the list |
@@ -869,7 +806,36 @@ int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, | |||
869 | while (!list_empty(&sata_q)) | 806 | while (!list_empty(&sata_q)) |
870 | list_del_init(sata_q.next); | 807 | list_del_init(sata_q.next); |
871 | } | 808 | } |
872 | } while (ap); | 809 | } while (eh_dev); |
810 | } | ||
811 | |||
812 | void sas_ata_schedule_reset(struct domain_device *dev) | ||
813 | { | ||
814 | struct ata_eh_info *ehi; | ||
815 | struct ata_port *ap; | ||
816 | unsigned long flags; | ||
817 | |||
818 | if (!dev_is_sata(dev)) | ||
819 | return; | ||
820 | |||
821 | ap = dev->sata_dev.ap; | ||
822 | ehi = &ap->link.eh_info; | ||
823 | |||
824 | spin_lock_irqsave(ap->lock, flags); | ||
825 | ehi->err_mask |= AC_ERR_TIMEOUT; | ||
826 | ehi->action |= ATA_EH_RESET; | ||
827 | ata_port_schedule_eh(ap); | ||
828 | spin_unlock_irqrestore(ap->lock, flags); | ||
829 | } | ||
830 | EXPORT_SYMBOL_GPL(sas_ata_schedule_reset); | ||
831 | |||
832 | void sas_ata_wait_eh(struct domain_device *dev) | ||
833 | { | ||
834 | struct ata_port *ap; | ||
835 | |||
836 | if (!dev_is_sata(dev)) | ||
837 | return; | ||
873 | 838 | ||
874 | return rtn; | 839 | ap = dev->sata_dev.ap; |
840 | ata_port_wait_eh(ap); | ||
875 | } | 841 | } |