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 | |
| 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>
| -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 | /** |
