diff options
author | Tejun Heo <htejun@gmail.com> | 2007-12-15 01:05:05 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-12-17 20:33:15 -0500 |
commit | 0e8634bf8e48e50aa96c7e7becafcf9d98c1a28d (patch) | |
tree | b49e1130fe721d4be4530c5a458b9e39199b4696 /drivers/ata | |
parent | 66fa7f2158e84530aa4a1839a3500d6bdb231301 (diff) |
libata-acpi: improve _GTF execution error handling and reporting
As _GTF commands can't transfer data, device error never signals
transfer error. It indicates that the device vetoed the operation, so
it's meaningless to retry.
This patch makes libata-acpi to report and continue on device errors
when executing _GTF commands. Also commands rejected by device don't
contribute to the number of _GTF commands executed.
While at it, update _GTF execution reporting such that all successful
commands are logged at KERN_DEBUG and rename taskfile_load_raw() to
ata_acpi_run_tf() for consistency.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-acpi.c | 77 |
1 files changed, 46 insertions, 31 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 5932ae24ddc1..d4cb557a727d 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -466,7 +466,7 @@ int ata_acpi_cbl_80wire(struct ata_port *ap) | |||
466 | EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); | 466 | EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); |
467 | 467 | ||
468 | /** | 468 | /** |
469 | * taskfile_load_raw - send taskfile registers to host controller | 469 | * ata_acpi_run_tf - send taskfile registers to host controller |
470 | * @dev: target ATA device | 470 | * @dev: target ATA device |
471 | * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7) | 471 | * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7) |
472 | * | 472 | * |
@@ -485,14 +485,17 @@ EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); | |||
485 | * EH context. | 485 | * EH context. |
486 | * | 486 | * |
487 | * RETURNS: | 487 | * RETURNS: |
488 | * 0 on success, -errno on failure. | 488 | * 1 if command is executed successfully. 0 if ignored or rejected, |
489 | * -errno on other errors. | ||
489 | */ | 490 | */ |
490 | static int taskfile_load_raw(struct ata_device *dev, | 491 | static int ata_acpi_run_tf(struct ata_device *dev, |
491 | const struct ata_acpi_gtf *gtf) | 492 | const struct ata_acpi_gtf *gtf) |
492 | { | 493 | { |
493 | struct ata_port *ap = dev->link->ap; | ||
494 | struct ata_taskfile tf, rtf; | 494 | struct ata_taskfile tf, rtf; |
495 | unsigned int err_mask; | 495 | unsigned int err_mask; |
496 | const char *level; | ||
497 | char msg[60]; | ||
498 | int rc; | ||
496 | 499 | ||
497 | if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0) | 500 | if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0) |
498 | && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0) | 501 | && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0) |
@@ -512,24 +515,39 @@ static int taskfile_load_raw(struct ata_device *dev, | |||
512 | tf.device = gtf->tf[5]; /* 0x1f6 */ | 515 | tf.device = gtf->tf[5]; /* 0x1f6 */ |
513 | tf.command = gtf->tf[6]; /* 0x1f7 */ | 516 | tf.command = gtf->tf[6]; /* 0x1f7 */ |
514 | 517 | ||
515 | if (ata_msg_probe(ap)) | ||
516 | ata_dev_printk(dev, KERN_DEBUG, "executing ACPI cmd " | ||
517 | "%02x/%02x:%02x:%02x:%02x:%02x:%02x\n", | ||
518 | tf.command, tf.feature, tf.nsect, | ||
519 | tf.lbal, tf.lbam, tf.lbah, tf.device); | ||
520 | |||
521 | rtf = tf; | 518 | rtf = tf; |
522 | err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0, 0); | 519 | err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0, 0); |
523 | if (err_mask) { | 520 | |
524 | ata_dev_printk(dev, KERN_ERR, | 521 | switch (err_mask) { |
525 | "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed " | 522 | case 0: |
526 | "(Emask=0x%x Stat=0x%02x Err=0x%02x)\n", | 523 | level = KERN_DEBUG; |
527 | tf.command, tf.feature, tf.nsect, tf.lbal, tf.lbam, | 524 | snprintf(msg, sizeof(msg), "succeeded"); |
528 | tf.lbah, tf.device, err_mask, rtf.command, rtf.feature); | 525 | rc = 1; |
529 | return -EIO; | 526 | break; |
527 | |||
528 | case AC_ERR_DEV: | ||
529 | level = KERN_INFO; | ||
530 | snprintf(msg, sizeof(msg), | ||
531 | "rejected by device (Stat=0x%02x Err=0x%02x)", | ||
532 | rtf.command, rtf.feature); | ||
533 | rc = 0; | ||
534 | break; | ||
535 | |||
536 | default: | ||
537 | level = KERN_ERR; | ||
538 | snprintf(msg, sizeof(msg), | ||
539 | "failed (Emask=0x%x Stat=0x%02x Err=0x%02x)", | ||
540 | err_mask, rtf.command, rtf.feature); | ||
541 | rc = -EIO; | ||
542 | break; | ||
530 | } | 543 | } |
531 | 544 | ||
532 | return 0; | 545 | ata_dev_printk(dev, level, |
546 | "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x %s\n", | ||
547 | tf.command, tf.feature, tf.nsect, tf.lbal, | ||
548 | tf.lbam, tf.lbah, tf.device, msg); | ||
549 | |||
550 | return rc; | ||
533 | } | 551 | } |
534 | 552 | ||
535 | /** | 553 | /** |
@@ -558,22 +576,19 @@ static int ata_acpi_exec_tfs(struct ata_device *dev, int *nr_executed) | |||
558 | gtf_count = rc; | 576 | gtf_count = rc; |
559 | 577 | ||
560 | /* execute them */ | 578 | /* execute them */ |
561 | for (i = 0, rc = 0; i < gtf_count; i++) { | 579 | for (i = 0; i < gtf_count; i++) { |
562 | int tmp; | 580 | rc = ata_acpi_run_tf(dev, gtf++); |
563 | 581 | if (rc < 0) | |
564 | /* ACPI errors are eventually ignored. Run till the | 582 | break; |
565 | * end even after errors. | 583 | if (rc) |
566 | */ | 584 | (*nr_executed)++; |
567 | tmp = taskfile_load_raw(dev, gtf++); | ||
568 | if (!rc) | ||
569 | rc = tmp; | ||
570 | |||
571 | (*nr_executed)++; | ||
572 | } | 585 | } |
573 | 586 | ||
574 | ata_acpi_clear_gtf(dev); | 587 | ata_acpi_clear_gtf(dev); |
575 | 588 | ||
576 | return rc; | 589 | if (rc < 0) |
590 | return rc; | ||
591 | return 0; | ||
577 | } | 592 | } |
578 | 593 | ||
579 | /** | 594 | /** |