aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-12-15 01:05:05 -0500
committerJeff Garzik <jeff@garzik.org>2007-12-17 20:33:15 -0500
commit0e8634bf8e48e50aa96c7e7becafcf9d98c1a28d (patch)
treeb49e1130fe721d4be4530c5a458b9e39199b4696 /drivers/ata
parent66fa7f2158e84530aa4a1839a3500d6bdb231301 (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.c77
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)
466EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); 466EXPORT_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 */
490static int taskfile_load_raw(struct ata_device *dev, 491static 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/**