diff options
Diffstat (limited to 'drivers/scsi/libata-eh.c')
-rw-r--r-- | drivers/scsi/libata-eh.c | 464 |
1 files changed, 396 insertions, 68 deletions
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c index bf5a72aca8a4..29f59345305d 100644 --- a/drivers/scsi/libata-eh.c +++ b/drivers/scsi/libata-eh.c | |||
@@ -47,6 +47,8 @@ | |||
47 | 47 | ||
48 | static void __ata_port_freeze(struct ata_port *ap); | 48 | static void __ata_port_freeze(struct ata_port *ap); |
49 | static void ata_eh_finish(struct ata_port *ap); | 49 | static void ata_eh_finish(struct ata_port *ap); |
50 | static void ata_eh_handle_port_suspend(struct ata_port *ap); | ||
51 | static void ata_eh_handle_port_resume(struct ata_port *ap); | ||
50 | 52 | ||
51 | static void ata_ering_record(struct ata_ering *ering, int is_io, | 53 | static void ata_ering_record(struct ata_ering *ering, int is_io, |
52 | unsigned int err_mask) | 54 | unsigned int err_mask) |
@@ -190,7 +192,6 @@ enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd) | |||
190 | void ata_scsi_error(struct Scsi_Host *host) | 192 | void ata_scsi_error(struct Scsi_Host *host) |
191 | { | 193 | { |
192 | struct ata_port *ap = ata_shost_to_port(host); | 194 | struct ata_port *ap = ata_shost_to_port(host); |
193 | spinlock_t *ap_lock = ap->lock; | ||
194 | int i, repeat_cnt = ATA_EH_MAX_REPEAT; | 195 | int i, repeat_cnt = ATA_EH_MAX_REPEAT; |
195 | unsigned long flags; | 196 | unsigned long flags; |
196 | 197 | ||
@@ -217,7 +218,7 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
217 | struct scsi_cmnd *scmd, *tmp; | 218 | struct scsi_cmnd *scmd, *tmp; |
218 | int nr_timedout = 0; | 219 | int nr_timedout = 0; |
219 | 220 | ||
220 | spin_lock_irqsave(ap_lock, flags); | 221 | spin_lock_irqsave(ap->lock, flags); |
221 | 222 | ||
222 | list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) { | 223 | list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) { |
223 | struct ata_queued_cmd *qc; | 224 | struct ata_queued_cmd *qc; |
@@ -256,43 +257,49 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
256 | if (nr_timedout) | 257 | if (nr_timedout) |
257 | __ata_port_freeze(ap); | 258 | __ata_port_freeze(ap); |
258 | 259 | ||
259 | spin_unlock_irqrestore(ap_lock, flags); | 260 | spin_unlock_irqrestore(ap->lock, flags); |
260 | } else | 261 | } else |
261 | spin_unlock_wait(ap_lock); | 262 | spin_unlock_wait(ap->lock); |
262 | 263 | ||
263 | repeat: | 264 | repeat: |
264 | /* invoke error handler */ | 265 | /* invoke error handler */ |
265 | if (ap->ops->error_handler) { | 266 | if (ap->ops->error_handler) { |
267 | /* process port resume request */ | ||
268 | ata_eh_handle_port_resume(ap); | ||
269 | |||
266 | /* fetch & clear EH info */ | 270 | /* fetch & clear EH info */ |
267 | spin_lock_irqsave(ap_lock, flags); | 271 | spin_lock_irqsave(ap->lock, flags); |
268 | 272 | ||
269 | memset(&ap->eh_context, 0, sizeof(ap->eh_context)); | 273 | memset(&ap->eh_context, 0, sizeof(ap->eh_context)); |
270 | ap->eh_context.i = ap->eh_info; | 274 | ap->eh_context.i = ap->eh_info; |
271 | memset(&ap->eh_info, 0, sizeof(ap->eh_info)); | 275 | memset(&ap->eh_info, 0, sizeof(ap->eh_info)); |
272 | 276 | ||
273 | ap->flags |= ATA_FLAG_EH_IN_PROGRESS; | 277 | ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS; |
274 | ap->flags &= ~ATA_FLAG_EH_PENDING; | 278 | ap->pflags &= ~ATA_PFLAG_EH_PENDING; |
275 | 279 | ||
276 | spin_unlock_irqrestore(ap_lock, flags); | 280 | spin_unlock_irqrestore(ap->lock, flags); |
277 | 281 | ||
278 | /* invoke EH. if unloading, just finish failed qcs */ | 282 | /* invoke EH, skip if unloading or suspended */ |
279 | if (!(ap->flags & ATA_FLAG_UNLOADING)) | 283 | if (!(ap->pflags & (ATA_PFLAG_UNLOADING | ATA_PFLAG_SUSPENDED))) |
280 | ap->ops->error_handler(ap); | 284 | ap->ops->error_handler(ap); |
281 | else | 285 | else |
282 | ata_eh_finish(ap); | 286 | ata_eh_finish(ap); |
283 | 287 | ||
288 | /* process port suspend request */ | ||
289 | ata_eh_handle_port_suspend(ap); | ||
290 | |||
284 | /* Exception might have happend after ->error_handler | 291 | /* Exception might have happend after ->error_handler |
285 | * recovered the port but before this point. Repeat | 292 | * recovered the port but before this point. Repeat |
286 | * EH in such case. | 293 | * EH in such case. |
287 | */ | 294 | */ |
288 | spin_lock_irqsave(ap_lock, flags); | 295 | spin_lock_irqsave(ap->lock, flags); |
289 | 296 | ||
290 | if (ap->flags & ATA_FLAG_EH_PENDING) { | 297 | if (ap->pflags & ATA_PFLAG_EH_PENDING) { |
291 | if (--repeat_cnt) { | 298 | if (--repeat_cnt) { |
292 | ata_port_printk(ap, KERN_INFO, | 299 | ata_port_printk(ap, KERN_INFO, |
293 | "EH pending after completion, " | 300 | "EH pending after completion, " |
294 | "repeating EH (cnt=%d)\n", repeat_cnt); | 301 | "repeating EH (cnt=%d)\n", repeat_cnt); |
295 | spin_unlock_irqrestore(ap_lock, flags); | 302 | spin_unlock_irqrestore(ap->lock, flags); |
296 | goto repeat; | 303 | goto repeat; |
297 | } | 304 | } |
298 | ata_port_printk(ap, KERN_ERR, "EH pending after %d " | 305 | ata_port_printk(ap, KERN_ERR, "EH pending after %d " |
@@ -302,14 +309,14 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
302 | /* this run is complete, make sure EH info is clear */ | 309 | /* this run is complete, make sure EH info is clear */ |
303 | memset(&ap->eh_info, 0, sizeof(ap->eh_info)); | 310 | memset(&ap->eh_info, 0, sizeof(ap->eh_info)); |
304 | 311 | ||
305 | /* Clear host_eh_scheduled while holding ap_lock such | 312 | /* Clear host_eh_scheduled while holding ap->lock such |
306 | * that if exception occurs after this point but | 313 | * that if exception occurs after this point but |
307 | * before EH completion, SCSI midlayer will | 314 | * before EH completion, SCSI midlayer will |
308 | * re-initiate EH. | 315 | * re-initiate EH. |
309 | */ | 316 | */ |
310 | host->host_eh_scheduled = 0; | 317 | host->host_eh_scheduled = 0; |
311 | 318 | ||
312 | spin_unlock_irqrestore(ap_lock, flags); | 319 | spin_unlock_irqrestore(ap->lock, flags); |
313 | } else { | 320 | } else { |
314 | WARN_ON(ata_qc_from_tag(ap, ap->active_tag) == NULL); | 321 | WARN_ON(ata_qc_from_tag(ap, ap->active_tag) == NULL); |
315 | ap->ops->eng_timeout(ap); | 322 | ap->ops->eng_timeout(ap); |
@@ -321,24 +328,23 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
321 | scsi_eh_flush_done_q(&ap->eh_done_q); | 328 | scsi_eh_flush_done_q(&ap->eh_done_q); |
322 | 329 | ||
323 | /* clean up */ | 330 | /* clean up */ |
324 | spin_lock_irqsave(ap_lock, flags); | 331 | spin_lock_irqsave(ap->lock, flags); |
325 | 332 | ||
326 | if (ap->flags & ATA_FLAG_LOADING) { | 333 | if (ap->pflags & ATA_PFLAG_LOADING) |
327 | ap->flags &= ~ATA_FLAG_LOADING; | 334 | ap->pflags &= ~ATA_PFLAG_LOADING; |
328 | } else { | 335 | else if (ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) |
329 | if (ap->flags & ATA_FLAG_SCSI_HOTPLUG) | 336 | queue_work(ata_aux_wq, &ap->hotplug_task); |
330 | queue_work(ata_aux_wq, &ap->hotplug_task); | ||
331 | if (ap->flags & ATA_FLAG_RECOVERED) | ||
332 | ata_port_printk(ap, KERN_INFO, "EH complete\n"); | ||
333 | } | ||
334 | 337 | ||
335 | ap->flags &= ~(ATA_FLAG_SCSI_HOTPLUG | ATA_FLAG_RECOVERED); | 338 | if (ap->pflags & ATA_PFLAG_RECOVERED) |
339 | ata_port_printk(ap, KERN_INFO, "EH complete\n"); | ||
340 | |||
341 | ap->pflags &= ~(ATA_PFLAG_SCSI_HOTPLUG | ATA_PFLAG_RECOVERED); | ||
336 | 342 | ||
337 | /* tell wait_eh that we're done */ | 343 | /* tell wait_eh that we're done */ |
338 | ap->flags &= ~ATA_FLAG_EH_IN_PROGRESS; | 344 | ap->pflags &= ~ATA_PFLAG_EH_IN_PROGRESS; |
339 | wake_up_all(&ap->eh_wait_q); | 345 | wake_up_all(&ap->eh_wait_q); |
340 | 346 | ||
341 | spin_unlock_irqrestore(ap_lock, flags); | 347 | spin_unlock_irqrestore(ap->lock, flags); |
342 | 348 | ||
343 | DPRINTK("EXIT\n"); | 349 | DPRINTK("EXIT\n"); |
344 | } | 350 | } |
@@ -360,7 +366,7 @@ void ata_port_wait_eh(struct ata_port *ap) | |||
360 | retry: | 366 | retry: |
361 | spin_lock_irqsave(ap->lock, flags); | 367 | spin_lock_irqsave(ap->lock, flags); |
362 | 368 | ||
363 | while (ap->flags & (ATA_FLAG_EH_PENDING | ATA_FLAG_EH_IN_PROGRESS)) { | 369 | while (ap->pflags & (ATA_PFLAG_EH_PENDING | ATA_PFLAG_EH_IN_PROGRESS)) { |
364 | prepare_to_wait(&ap->eh_wait_q, &wait, TASK_UNINTERRUPTIBLE); | 370 | prepare_to_wait(&ap->eh_wait_q, &wait, TASK_UNINTERRUPTIBLE); |
365 | spin_unlock_irqrestore(ap->lock, flags); | 371 | spin_unlock_irqrestore(ap->lock, flags); |
366 | schedule(); | 372 | schedule(); |
@@ -489,7 +495,7 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc) | |||
489 | WARN_ON(!ap->ops->error_handler); | 495 | WARN_ON(!ap->ops->error_handler); |
490 | 496 | ||
491 | qc->flags |= ATA_QCFLAG_FAILED; | 497 | qc->flags |= ATA_QCFLAG_FAILED; |
492 | qc->ap->flags |= ATA_FLAG_EH_PENDING; | 498 | qc->ap->pflags |= ATA_PFLAG_EH_PENDING; |
493 | 499 | ||
494 | /* The following will fail if timeout has already expired. | 500 | /* The following will fail if timeout has already expired. |
495 | * ata_scsi_error() takes care of such scmds on EH entry. | 501 | * ata_scsi_error() takes care of such scmds on EH entry. |
@@ -513,7 +519,7 @@ void ata_port_schedule_eh(struct ata_port *ap) | |||
513 | { | 519 | { |
514 | WARN_ON(!ap->ops->error_handler); | 520 | WARN_ON(!ap->ops->error_handler); |
515 | 521 | ||
516 | ap->flags |= ATA_FLAG_EH_PENDING; | 522 | ap->pflags |= ATA_PFLAG_EH_PENDING; |
517 | scsi_schedule_eh(ap->host); | 523 | scsi_schedule_eh(ap->host); |
518 | 524 | ||
519 | DPRINTK("port EH scheduled\n"); | 525 | DPRINTK("port EH scheduled\n"); |
@@ -578,7 +584,7 @@ static void __ata_port_freeze(struct ata_port *ap) | |||
578 | if (ap->ops->freeze) | 584 | if (ap->ops->freeze) |
579 | ap->ops->freeze(ap); | 585 | ap->ops->freeze(ap); |
580 | 586 | ||
581 | ap->flags |= ATA_FLAG_FROZEN; | 587 | ap->pflags |= ATA_PFLAG_FROZEN; |
582 | 588 | ||
583 | DPRINTK("ata%u port frozen\n", ap->id); | 589 | DPRINTK("ata%u port frozen\n", ap->id); |
584 | } | 590 | } |
@@ -646,7 +652,7 @@ void ata_eh_thaw_port(struct ata_port *ap) | |||
646 | 652 | ||
647 | spin_lock_irqsave(ap->lock, flags); | 653 | spin_lock_irqsave(ap->lock, flags); |
648 | 654 | ||
649 | ap->flags &= ~ATA_FLAG_FROZEN; | 655 | ap->pflags &= ~ATA_PFLAG_FROZEN; |
650 | 656 | ||
651 | if (ap->ops->thaw) | 657 | if (ap->ops->thaw) |
652 | ap->ops->thaw(ap); | 658 | ap->ops->thaw(ap); |
@@ -731,7 +737,7 @@ static void ata_eh_detach_dev(struct ata_device *dev) | |||
731 | 737 | ||
732 | if (ata_scsi_offline_dev(dev)) { | 738 | if (ata_scsi_offline_dev(dev)) { |
733 | dev->flags |= ATA_DFLAG_DETACHED; | 739 | dev->flags |= ATA_DFLAG_DETACHED; |
734 | ap->flags |= ATA_FLAG_SCSI_HOTPLUG; | 740 | ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; |
735 | } | 741 | } |
736 | 742 | ||
737 | /* clear per-dev EH actions */ | 743 | /* clear per-dev EH actions */ |
@@ -758,10 +764,29 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, | |||
758 | unsigned int action) | 764 | unsigned int action) |
759 | { | 765 | { |
760 | unsigned long flags; | 766 | unsigned long flags; |
767 | struct ata_eh_info *ehi = &ap->eh_info; | ||
768 | struct ata_eh_context *ehc = &ap->eh_context; | ||
761 | 769 | ||
762 | spin_lock_irqsave(ap->lock, flags); | 770 | spin_lock_irqsave(ap->lock, flags); |
763 | ata_eh_clear_action(dev, &ap->eh_info, action); | 771 | |
764 | ap->flags |= ATA_FLAG_RECOVERED; | 772 | /* Reset is represented by combination of actions and EHI |
773 | * flags. Suck in all related bits before clearing eh_info to | ||
774 | * avoid losing requested action. | ||
775 | */ | ||
776 | if (action & ATA_EH_RESET_MASK) { | ||
777 | ehc->i.action |= ehi->action & ATA_EH_RESET_MASK; | ||
778 | ehc->i.flags |= ehi->flags & ATA_EHI_RESET_MODIFIER_MASK; | ||
779 | |||
780 | /* make sure all reset actions are cleared & clear EHI flags */ | ||
781 | action |= ATA_EH_RESET_MASK; | ||
782 | ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK; | ||
783 | } | ||
784 | |||
785 | ata_eh_clear_action(dev, ehi, action); | ||
786 | |||
787 | if (!(ehc->i.flags & ATA_EHI_QUIET)) | ||
788 | ap->pflags |= ATA_PFLAG_RECOVERED; | ||
789 | |||
765 | spin_unlock_irqrestore(ap->lock, flags); | 790 | spin_unlock_irqrestore(ap->lock, flags); |
766 | } | 791 | } |
767 | 792 | ||
@@ -780,6 +805,12 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, | |||
780 | static void ata_eh_done(struct ata_port *ap, struct ata_device *dev, | 805 | static void ata_eh_done(struct ata_port *ap, struct ata_device *dev, |
781 | unsigned int action) | 806 | unsigned int action) |
782 | { | 807 | { |
808 | /* if reset is complete, clear all reset actions & reset modifier */ | ||
809 | if (action & ATA_EH_RESET_MASK) { | ||
810 | action |= ATA_EH_RESET_MASK; | ||
811 | ap->eh_context.i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK; | ||
812 | } | ||
813 | |||
783 | ata_eh_clear_action(dev, &ap->eh_context.i, action); | 814 | ata_eh_clear_action(dev, &ap->eh_context.i, action); |
784 | } | 815 | } |
785 | 816 | ||
@@ -1027,7 +1058,7 @@ static void ata_eh_analyze_ncq_error(struct ata_port *ap) | |||
1027 | int tag, rc; | 1058 | int tag, rc; |
1028 | 1059 | ||
1029 | /* if frozen, we can't do much */ | 1060 | /* if frozen, we can't do much */ |
1030 | if (ap->flags & ATA_FLAG_FROZEN) | 1061 | if (ap->pflags & ATA_PFLAG_FROZEN) |
1031 | return; | 1062 | return; |
1032 | 1063 | ||
1033 | /* is it NCQ device error? */ | 1064 | /* is it NCQ device error? */ |
@@ -1266,8 +1297,6 @@ static int ata_eh_speed_down(struct ata_device *dev, int is_io, | |||
1266 | static void ata_eh_autopsy(struct ata_port *ap) | 1297 | static void ata_eh_autopsy(struct ata_port *ap) |
1267 | { | 1298 | { |
1268 | struct ata_eh_context *ehc = &ap->eh_context; | 1299 | struct ata_eh_context *ehc = &ap->eh_context; |
1269 | unsigned int action = ehc->i.action; | ||
1270 | struct ata_device *failed_dev = NULL; | ||
1271 | unsigned int all_err_mask = 0; | 1300 | unsigned int all_err_mask = 0; |
1272 | int tag, is_io = 0; | 1301 | int tag, is_io = 0; |
1273 | u32 serror; | 1302 | u32 serror; |
@@ -1275,13 +1304,16 @@ static void ata_eh_autopsy(struct ata_port *ap) | |||
1275 | 1304 | ||
1276 | DPRINTK("ENTER\n"); | 1305 | DPRINTK("ENTER\n"); |
1277 | 1306 | ||
1307 | if (ehc->i.flags & ATA_EHI_NO_AUTOPSY) | ||
1308 | return; | ||
1309 | |||
1278 | /* obtain and analyze SError */ | 1310 | /* obtain and analyze SError */ |
1279 | rc = sata_scr_read(ap, SCR_ERROR, &serror); | 1311 | rc = sata_scr_read(ap, SCR_ERROR, &serror); |
1280 | if (rc == 0) { | 1312 | if (rc == 0) { |
1281 | ehc->i.serror |= serror; | 1313 | ehc->i.serror |= serror; |
1282 | ata_eh_analyze_serror(ap); | 1314 | ata_eh_analyze_serror(ap); |
1283 | } else if (rc != -EOPNOTSUPP) | 1315 | } else if (rc != -EOPNOTSUPP) |
1284 | action |= ATA_EH_HARDRESET; | 1316 | ehc->i.action |= ATA_EH_HARDRESET; |
1285 | 1317 | ||
1286 | /* analyze NCQ failure */ | 1318 | /* analyze NCQ failure */ |
1287 | ata_eh_analyze_ncq_error(ap); | 1319 | ata_eh_analyze_ncq_error(ap); |
@@ -1302,7 +1334,7 @@ static void ata_eh_autopsy(struct ata_port *ap) | |||
1302 | qc->err_mask |= ehc->i.err_mask; | 1334 | qc->err_mask |= ehc->i.err_mask; |
1303 | 1335 | ||
1304 | /* analyze TF */ | 1336 | /* analyze TF */ |
1305 | action |= ata_eh_analyze_tf(qc, &qc->result_tf); | 1337 | ehc->i.action |= ata_eh_analyze_tf(qc, &qc->result_tf); |
1306 | 1338 | ||
1307 | /* DEV errors are probably spurious in case of ATA_BUS error */ | 1339 | /* DEV errors are probably spurious in case of ATA_BUS error */ |
1308 | if (qc->err_mask & AC_ERR_ATA_BUS) | 1340 | if (qc->err_mask & AC_ERR_ATA_BUS) |
@@ -1316,38 +1348,35 @@ static void ata_eh_autopsy(struct ata_port *ap) | |||
1316 | /* SENSE_VALID trumps dev/unknown error and revalidation */ | 1348 | /* SENSE_VALID trumps dev/unknown error and revalidation */ |
1317 | if (qc->flags & ATA_QCFLAG_SENSE_VALID) { | 1349 | if (qc->flags & ATA_QCFLAG_SENSE_VALID) { |
1318 | qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); | 1350 | qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); |
1319 | action &= ~ATA_EH_REVALIDATE; | 1351 | ehc->i.action &= ~ATA_EH_REVALIDATE; |
1320 | } | 1352 | } |
1321 | 1353 | ||
1322 | /* accumulate error info */ | 1354 | /* accumulate error info */ |
1323 | failed_dev = qc->dev; | 1355 | ehc->i.dev = qc->dev; |
1324 | all_err_mask |= qc->err_mask; | 1356 | all_err_mask |= qc->err_mask; |
1325 | if (qc->flags & ATA_QCFLAG_IO) | 1357 | if (qc->flags & ATA_QCFLAG_IO) |
1326 | is_io = 1; | 1358 | is_io = 1; |
1327 | } | 1359 | } |
1328 | 1360 | ||
1329 | /* enforce default EH actions */ | 1361 | /* enforce default EH actions */ |
1330 | if (ap->flags & ATA_FLAG_FROZEN || | 1362 | if (ap->pflags & ATA_PFLAG_FROZEN || |
1331 | all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) | 1363 | all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) |
1332 | action |= ATA_EH_SOFTRESET; | 1364 | ehc->i.action |= ATA_EH_SOFTRESET; |
1333 | else if (all_err_mask) | 1365 | else if (all_err_mask) |
1334 | action |= ATA_EH_REVALIDATE; | 1366 | ehc->i.action |= ATA_EH_REVALIDATE; |
1335 | 1367 | ||
1336 | /* if we have offending qcs and the associated failed device */ | 1368 | /* if we have offending qcs and the associated failed device */ |
1337 | if (failed_dev) { | 1369 | if (ehc->i.dev) { |
1338 | /* speed down */ | 1370 | /* speed down */ |
1339 | action |= ata_eh_speed_down(failed_dev, is_io, all_err_mask); | 1371 | ehc->i.action |= ata_eh_speed_down(ehc->i.dev, is_io, |
1372 | all_err_mask); | ||
1340 | 1373 | ||
1341 | /* perform per-dev EH action only on the offending device */ | 1374 | /* perform per-dev EH action only on the offending device */ |
1342 | ehc->i.dev_action[failed_dev->devno] |= | 1375 | ehc->i.dev_action[ehc->i.dev->devno] |= |
1343 | action & ATA_EH_PERDEV_MASK; | 1376 | ehc->i.action & ATA_EH_PERDEV_MASK; |
1344 | action &= ~ATA_EH_PERDEV_MASK; | 1377 | ehc->i.action &= ~ATA_EH_PERDEV_MASK; |
1345 | } | 1378 | } |
1346 | 1379 | ||
1347 | /* record autopsy result */ | ||
1348 | ehc->i.dev = failed_dev; | ||
1349 | ehc->i.action = action; | ||
1350 | |||
1351 | DPRINTK("EXIT\n"); | 1380 | DPRINTK("EXIT\n"); |
1352 | } | 1381 | } |
1353 | 1382 | ||
@@ -1385,7 +1414,7 @@ static void ata_eh_report(struct ata_port *ap) | |||
1385 | return; | 1414 | return; |
1386 | 1415 | ||
1387 | frozen = ""; | 1416 | frozen = ""; |
1388 | if (ap->flags & ATA_FLAG_FROZEN) | 1417 | if (ap->pflags & ATA_PFLAG_FROZEN) |
1389 | frozen = " frozen"; | 1418 | frozen = " frozen"; |
1390 | 1419 | ||
1391 | if (ehc->i.dev) { | 1420 | if (ehc->i.dev) { |
@@ -1465,11 +1494,14 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1465 | struct ata_eh_context *ehc = &ap->eh_context; | 1494 | struct ata_eh_context *ehc = &ap->eh_context; |
1466 | unsigned int *classes = ehc->classes; | 1495 | unsigned int *classes = ehc->classes; |
1467 | int tries = ATA_EH_RESET_TRIES; | 1496 | int tries = ATA_EH_RESET_TRIES; |
1468 | int verbose = !(ap->flags & ATA_FLAG_LOADING); | 1497 | int verbose = !(ehc->i.flags & ATA_EHI_QUIET); |
1469 | unsigned int action; | 1498 | unsigned int action; |
1470 | ata_reset_fn_t reset; | 1499 | ata_reset_fn_t reset; |
1471 | int i, did_followup_srst, rc; | 1500 | int i, did_followup_srst, rc; |
1472 | 1501 | ||
1502 | /* about to reset */ | ||
1503 | ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); | ||
1504 | |||
1473 | /* Determine which reset to use and record in ehc->i.action. | 1505 | /* Determine which reset to use and record in ehc->i.action. |
1474 | * prereset() may examine and modify it. | 1506 | * prereset() may examine and modify it. |
1475 | */ | 1507 | */ |
@@ -1518,8 +1550,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1518 | ata_port_printk(ap, KERN_INFO, "%s resetting port\n", | 1550 | ata_port_printk(ap, KERN_INFO, "%s resetting port\n", |
1519 | reset == softreset ? "soft" : "hard"); | 1551 | reset == softreset ? "soft" : "hard"); |
1520 | 1552 | ||
1521 | /* reset */ | 1553 | /* mark that this EH session started with reset */ |
1522 | ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK); | ||
1523 | ehc->i.flags |= ATA_EHI_DID_RESET; | 1554 | ehc->i.flags |= ATA_EHI_DID_RESET; |
1524 | 1555 | ||
1525 | rc = ata_do_reset(ap, reset, classes); | 1556 | rc = ata_do_reset(ap, reset, classes); |
@@ -1582,7 +1613,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1582 | postreset(ap, classes); | 1613 | postreset(ap, classes); |
1583 | 1614 | ||
1584 | /* reset successful, schedule revalidation */ | 1615 | /* reset successful, schedule revalidation */ |
1585 | ata_eh_done(ap, NULL, ATA_EH_RESET_MASK); | 1616 | ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); |
1586 | ehc->i.action |= ATA_EH_REVALIDATE; | 1617 | ehc->i.action |= ATA_EH_REVALIDATE; |
1587 | } | 1618 | } |
1588 | 1619 | ||
@@ -1605,7 +1636,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, | |||
1605 | dev = &ap->device[i]; | 1636 | dev = &ap->device[i]; |
1606 | action = ata_eh_dev_action(dev); | 1637 | action = ata_eh_dev_action(dev); |
1607 | 1638 | ||
1608 | if (action & ATA_EH_REVALIDATE && ata_dev_enabled(dev)) { | 1639 | if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) { |
1609 | if (ata_port_offline(ap)) { | 1640 | if (ata_port_offline(ap)) { |
1610 | rc = -EIO; | 1641 | rc = -EIO; |
1611 | break; | 1642 | break; |
@@ -1636,7 +1667,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, | |||
1636 | } | 1667 | } |
1637 | 1668 | ||
1638 | spin_lock_irqsave(ap->lock, flags); | 1669 | spin_lock_irqsave(ap->lock, flags); |
1639 | ap->flags |= ATA_FLAG_SCSI_HOTPLUG; | 1670 | ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; |
1640 | spin_unlock_irqrestore(ap->lock, flags); | 1671 | spin_unlock_irqrestore(ap->lock, flags); |
1641 | } | 1672 | } |
1642 | } | 1673 | } |
@@ -1648,6 +1679,164 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, | |||
1648 | return rc; | 1679 | return rc; |
1649 | } | 1680 | } |
1650 | 1681 | ||
1682 | /** | ||
1683 | * ata_eh_suspend - handle suspend EH action | ||
1684 | * @ap: target host port | ||
1685 | * @r_failed_dev: result parameter to indicate failing device | ||
1686 | * | ||
1687 | * Handle suspend EH action. Disk devices are spinned down and | ||
1688 | * other types of devices are just marked suspended. Once | ||
1689 | * suspended, no EH action to the device is allowed until it is | ||
1690 | * resumed. | ||
1691 | * | ||
1692 | * LOCKING: | ||
1693 | * Kernel thread context (may sleep). | ||
1694 | * | ||
1695 | * RETURNS: | ||
1696 | * 0 on success, -errno otherwise | ||
1697 | */ | ||
1698 | static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev) | ||
1699 | { | ||
1700 | struct ata_device *dev; | ||
1701 | int i, rc = 0; | ||
1702 | |||
1703 | DPRINTK("ENTER\n"); | ||
1704 | |||
1705 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | ||
1706 | unsigned long flags; | ||
1707 | unsigned int action, err_mask; | ||
1708 | |||
1709 | dev = &ap->device[i]; | ||
1710 | action = ata_eh_dev_action(dev); | ||
1711 | |||
1712 | if (!ata_dev_enabled(dev) || !(action & ATA_EH_SUSPEND)) | ||
1713 | continue; | ||
1714 | |||
1715 | WARN_ON(dev->flags & ATA_DFLAG_SUSPENDED); | ||
1716 | |||
1717 | ata_eh_about_to_do(ap, dev, ATA_EH_SUSPEND); | ||
1718 | |||
1719 | if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) { | ||
1720 | /* flush cache */ | ||
1721 | rc = ata_flush_cache(dev); | ||
1722 | if (rc) | ||
1723 | break; | ||
1724 | |||
1725 | /* spin down */ | ||
1726 | err_mask = ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1); | ||
1727 | if (err_mask) { | ||
1728 | ata_dev_printk(dev, KERN_ERR, "failed to " | ||
1729 | "spin down (err_mask=0x%x)\n", | ||
1730 | err_mask); | ||
1731 | rc = -EIO; | ||
1732 | break; | ||
1733 | } | ||
1734 | } | ||
1735 | |||
1736 | spin_lock_irqsave(ap->lock, flags); | ||
1737 | dev->flags |= ATA_DFLAG_SUSPENDED; | ||
1738 | spin_unlock_irqrestore(ap->lock, flags); | ||
1739 | |||
1740 | ata_eh_done(ap, dev, ATA_EH_SUSPEND); | ||
1741 | } | ||
1742 | |||
1743 | if (rc) | ||
1744 | *r_failed_dev = dev; | ||
1745 | |||
1746 | DPRINTK("EXIT\n"); | ||
1747 | return 0; | ||
1748 | } | ||
1749 | |||
1750 | /** | ||
1751 | * ata_eh_prep_resume - prep for resume EH action | ||
1752 | * @ap: target host port | ||
1753 | * | ||
1754 | * Clear SUSPENDED in preparation for scheduled resume actions. | ||
1755 | * This allows other parts of EH to access the devices being | ||
1756 | * resumed. | ||
1757 | * | ||
1758 | * LOCKING: | ||
1759 | * Kernel thread context (may sleep). | ||
1760 | */ | ||
1761 | static void ata_eh_prep_resume(struct ata_port *ap) | ||
1762 | { | ||
1763 | struct ata_device *dev; | ||
1764 | unsigned long flags; | ||
1765 | int i; | ||
1766 | |||
1767 | DPRINTK("ENTER\n"); | ||
1768 | |||
1769 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | ||
1770 | unsigned int action; | ||
1771 | |||
1772 | dev = &ap->device[i]; | ||
1773 | action = ata_eh_dev_action(dev); | ||
1774 | |||
1775 | if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME)) | ||
1776 | continue; | ||
1777 | |||
1778 | spin_lock_irqsave(ap->lock, flags); | ||
1779 | dev->flags &= ~ATA_DFLAG_SUSPENDED; | ||
1780 | spin_unlock_irqrestore(ap->lock, flags); | ||
1781 | } | ||
1782 | |||
1783 | DPRINTK("EXIT\n"); | ||
1784 | } | ||
1785 | |||
1786 | /** | ||
1787 | * ata_eh_resume - handle resume EH action | ||
1788 | * @ap: target host port | ||
1789 | * @r_failed_dev: result parameter to indicate failing device | ||
1790 | * | ||
1791 | * Handle resume EH action. Target devices are already reset and | ||
1792 | * revalidated. Spinning up is the only operation left. | ||
1793 | * | ||
1794 | * LOCKING: | ||
1795 | * Kernel thread context (may sleep). | ||
1796 | * | ||
1797 | * RETURNS: | ||
1798 | * 0 on success, -errno otherwise | ||
1799 | */ | ||
1800 | static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev) | ||
1801 | { | ||
1802 | struct ata_device *dev; | ||
1803 | int i, rc = 0; | ||
1804 | |||
1805 | DPRINTK("ENTER\n"); | ||
1806 | |||
1807 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | ||
1808 | unsigned int action, err_mask; | ||
1809 | |||
1810 | dev = &ap->device[i]; | ||
1811 | action = ata_eh_dev_action(dev); | ||
1812 | |||
1813 | if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME)) | ||
1814 | continue; | ||
1815 | |||
1816 | ata_eh_about_to_do(ap, dev, ATA_EH_RESUME); | ||
1817 | |||
1818 | if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) { | ||
1819 | err_mask = ata_do_simple_cmd(dev, | ||
1820 | ATA_CMD_IDLEIMMEDIATE); | ||
1821 | if (err_mask) { | ||
1822 | ata_dev_printk(dev, KERN_ERR, "failed to " | ||
1823 | "spin up (err_mask=0x%x)\n", | ||
1824 | err_mask); | ||
1825 | rc = -EIO; | ||
1826 | break; | ||
1827 | } | ||
1828 | } | ||
1829 | |||
1830 | ata_eh_done(ap, dev, ATA_EH_RESUME); | ||
1831 | } | ||
1832 | |||
1833 | if (rc) | ||
1834 | *r_failed_dev = dev; | ||
1835 | |||
1836 | DPRINTK("EXIT\n"); | ||
1837 | return 0; | ||
1838 | } | ||
1839 | |||
1651 | static int ata_port_nr_enabled(struct ata_port *ap) | 1840 | static int ata_port_nr_enabled(struct ata_port *ap) |
1652 | { | 1841 | { |
1653 | int i, cnt = 0; | 1842 | int i, cnt = 0; |
@@ -1673,7 +1862,20 @@ static int ata_eh_skip_recovery(struct ata_port *ap) | |||
1673 | struct ata_eh_context *ehc = &ap->eh_context; | 1862 | struct ata_eh_context *ehc = &ap->eh_context; |
1674 | int i; | 1863 | int i; |
1675 | 1864 | ||
1676 | if (ap->flags & ATA_FLAG_FROZEN || ata_port_nr_enabled(ap)) | 1865 | /* skip if all possible devices are suspended */ |
1866 | for (i = 0; i < ata_port_max_devices(ap); i++) { | ||
1867 | struct ata_device *dev = &ap->device[i]; | ||
1868 | |||
1869 | if (!(dev->flags & ATA_DFLAG_SUSPENDED)) | ||
1870 | break; | ||
1871 | } | ||
1872 | |||
1873 | if (i == ata_port_max_devices(ap)) | ||
1874 | return 1; | ||
1875 | |||
1876 | /* thaw frozen port, resume link and recover failed devices */ | ||
1877 | if ((ap->pflags & ATA_PFLAG_FROZEN) || | ||
1878 | (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap)) | ||
1677 | return 0; | 1879 | return 0; |
1678 | 1880 | ||
1679 | /* skip if class codes for all vacant slots are ATA_DEV_NONE */ | 1881 | /* skip if class codes for all vacant slots are ATA_DEV_NONE */ |
@@ -1744,9 +1946,12 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
1744 | rc = 0; | 1946 | rc = 0; |
1745 | 1947 | ||
1746 | /* if UNLOADING, finish immediately */ | 1948 | /* if UNLOADING, finish immediately */ |
1747 | if (ap->flags & ATA_FLAG_UNLOADING) | 1949 | if (ap->pflags & ATA_PFLAG_UNLOADING) |
1748 | goto out; | 1950 | goto out; |
1749 | 1951 | ||
1952 | /* prep for resume */ | ||
1953 | ata_eh_prep_resume(ap); | ||
1954 | |||
1750 | /* skip EH if possible. */ | 1955 | /* skip EH if possible. */ |
1751 | if (ata_eh_skip_recovery(ap)) | 1956 | if (ata_eh_skip_recovery(ap)) |
1752 | ehc->i.action = 0; | 1957 | ehc->i.action = 0; |
@@ -1774,6 +1979,11 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
1774 | if (rc) | 1979 | if (rc) |
1775 | goto dev_fail; | 1980 | goto dev_fail; |
1776 | 1981 | ||
1982 | /* resume devices */ | ||
1983 | rc = ata_eh_resume(ap, &dev); | ||
1984 | if (rc) | ||
1985 | goto dev_fail; | ||
1986 | |||
1777 | /* configure transfer mode if the port has been reset */ | 1987 | /* configure transfer mode if the port has been reset */ |
1778 | if (ehc->i.flags & ATA_EHI_DID_RESET) { | 1988 | if (ehc->i.flags & ATA_EHI_DID_RESET) { |
1779 | rc = ata_set_mode(ap, &dev); | 1989 | rc = ata_set_mode(ap, &dev); |
@@ -1783,6 +1993,11 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
1783 | } | 1993 | } |
1784 | } | 1994 | } |
1785 | 1995 | ||
1996 | /* suspend devices */ | ||
1997 | rc = ata_eh_suspend(ap, &dev); | ||
1998 | if (rc) | ||
1999 | goto dev_fail; | ||
2000 | |||
1786 | goto out; | 2001 | goto out; |
1787 | 2002 | ||
1788 | dev_fail: | 2003 | dev_fail: |
@@ -1908,11 +2123,124 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
1908 | ata_reset_fn_t softreset, ata_reset_fn_t hardreset, | 2123 | ata_reset_fn_t softreset, ata_reset_fn_t hardreset, |
1909 | ata_postreset_fn_t postreset) | 2124 | ata_postreset_fn_t postreset) |
1910 | { | 2125 | { |
1911 | if (!(ap->flags & ATA_FLAG_LOADING)) { | 2126 | ata_eh_autopsy(ap); |
1912 | ata_eh_autopsy(ap); | 2127 | ata_eh_report(ap); |
1913 | ata_eh_report(ap); | ||
1914 | } | ||
1915 | |||
1916 | ata_eh_recover(ap, prereset, softreset, hardreset, postreset); | 2128 | ata_eh_recover(ap, prereset, softreset, hardreset, postreset); |
1917 | ata_eh_finish(ap); | 2129 | ata_eh_finish(ap); |
1918 | } | 2130 | } |
2131 | |||
2132 | /** | ||
2133 | * ata_eh_handle_port_suspend - perform port suspend operation | ||
2134 | * @ap: port to suspend | ||
2135 | * | ||
2136 | * Suspend @ap. | ||
2137 | * | ||
2138 | * LOCKING: | ||
2139 | * Kernel thread context (may sleep). | ||
2140 | */ | ||
2141 | static void ata_eh_handle_port_suspend(struct ata_port *ap) | ||
2142 | { | ||
2143 | unsigned long flags; | ||
2144 | int rc = 0; | ||
2145 | |||
2146 | /* are we suspending? */ | ||
2147 | spin_lock_irqsave(ap->lock, flags); | ||
2148 | if (!(ap->pflags & ATA_PFLAG_PM_PENDING) || | ||
2149 | ap->pm_mesg.event == PM_EVENT_ON) { | ||
2150 | spin_unlock_irqrestore(ap->lock, flags); | ||
2151 | return; | ||
2152 | } | ||
2153 | spin_unlock_irqrestore(ap->lock, flags); | ||
2154 | |||
2155 | WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); | ||
2156 | |||
2157 | /* suspend */ | ||
2158 | ata_eh_freeze_port(ap); | ||
2159 | |||
2160 | if (ap->ops->port_suspend) | ||
2161 | rc = ap->ops->port_suspend(ap, ap->pm_mesg); | ||
2162 | |||
2163 | /* report result */ | ||
2164 | spin_lock_irqsave(ap->lock, flags); | ||
2165 | |||
2166 | ap->pflags &= ~ATA_PFLAG_PM_PENDING; | ||
2167 | if (rc == 0) | ||
2168 | ap->pflags |= ATA_PFLAG_SUSPENDED; | ||
2169 | else | ||
2170 | ata_port_schedule_eh(ap); | ||
2171 | |||
2172 | if (ap->pm_result) { | ||
2173 | *ap->pm_result = rc; | ||
2174 | ap->pm_result = NULL; | ||
2175 | } | ||
2176 | |||
2177 | spin_unlock_irqrestore(ap->lock, flags); | ||
2178 | |||
2179 | return; | ||
2180 | } | ||
2181 | |||
2182 | /** | ||
2183 | * ata_eh_handle_port_resume - perform port resume operation | ||
2184 | * @ap: port to resume | ||
2185 | * | ||
2186 | * Resume @ap. | ||
2187 | * | ||
2188 | * This function also waits upto one second until all devices | ||
2189 | * hanging off this port requests resume EH action. This is to | ||
2190 | * prevent invoking EH and thus reset multiple times on resume. | ||
2191 | * | ||
2192 | * On DPM resume, where some of devices might not be resumed | ||
2193 | * together, this may delay port resume upto one second, but such | ||
2194 | * DPM resumes are rare and 1 sec delay isn't too bad. | ||
2195 | * | ||
2196 | * LOCKING: | ||
2197 | * Kernel thread context (may sleep). | ||
2198 | */ | ||
2199 | static void ata_eh_handle_port_resume(struct ata_port *ap) | ||
2200 | { | ||
2201 | unsigned long timeout; | ||
2202 | unsigned long flags; | ||
2203 | int i, rc = 0; | ||
2204 | |||
2205 | /* are we resuming? */ | ||
2206 | spin_lock_irqsave(ap->lock, flags); | ||
2207 | if (!(ap->pflags & ATA_PFLAG_PM_PENDING) || | ||
2208 | ap->pm_mesg.event != PM_EVENT_ON) { | ||
2209 | spin_unlock_irqrestore(ap->lock, flags); | ||
2210 | return; | ||
2211 | } | ||
2212 | spin_unlock_irqrestore(ap->lock, flags); | ||
2213 | |||
2214 | /* spurious? */ | ||
2215 | if (!(ap->pflags & ATA_PFLAG_SUSPENDED)) | ||
2216 | goto done; | ||
2217 | |||
2218 | if (ap->ops->port_resume) | ||
2219 | rc = ap->ops->port_resume(ap); | ||
2220 | |||
2221 | /* give devices time to request EH */ | ||
2222 | timeout = jiffies + HZ; /* 1s max */ | ||
2223 | while (1) { | ||
2224 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | ||
2225 | struct ata_device *dev = &ap->device[i]; | ||
2226 | unsigned int action = ata_eh_dev_action(dev); | ||
2227 | |||
2228 | if ((dev->flags & ATA_DFLAG_SUSPENDED) && | ||
2229 | !(action & ATA_EH_RESUME)) | ||
2230 | break; | ||
2231 | } | ||
2232 | |||
2233 | if (i == ATA_MAX_DEVICES || time_after(jiffies, timeout)) | ||
2234 | break; | ||
2235 | msleep(10); | ||
2236 | } | ||
2237 | |||
2238 | done: | ||
2239 | spin_lock_irqsave(ap->lock, flags); | ||
2240 | ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); | ||
2241 | if (ap->pm_result) { | ||
2242 | *ap->pm_result = rc; | ||
2243 | ap->pm_result = NULL; | ||
2244 | } | ||
2245 | spin_unlock_irqrestore(ap->lock, flags); | ||
2246 | } | ||