libata-acpi: improve ACPI disabling

* If _GTF evalution fails, it's pointless to retry. If nothing else
is wrong, just ignore the error.

* After disabling ACPI, return success iff the number of executed _GTF
command equals zero. Otherwise, tell EH to retry. This change
fixes bogus 1 return bug where ata_acpi_on_devcfg() expects the
caller to reload IDENTIFY data and continue but the caller
interprets it as an error.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by Tejun Heo and committed by Jeff Garzik 66fa7f21 398e0782

+38 -21
+38 -21
drivers/ata/libata-acpi.c
··· 346 * EH context. 347 * 348 * RETURNS: 349 - * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't 350 - * contain valid data. 351 */ 352 static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) 353 { ··· 380 ata_dev_printk(dev, KERN_WARNING, 381 "_GTF evaluation failed (AE 0x%x)\n", 382 status); 383 } 384 goto out_free; 385 } ··· 392 __FUNCTION__, 393 (unsigned long long)output.length, 394 output.pointer); 395 goto out_free; 396 } 397 ··· 400 ata_dev_printk(dev, KERN_WARNING, 401 "_GTF unexpected object type 0x%x\n", 402 out_obj->type); 403 goto out_free; 404 } 405 ··· 408 ata_dev_printk(dev, KERN_WARNING, 409 "unexpected _GTF length (%d)\n", 410 out_obj->buffer.length); 411 goto out_free; 412 } 413 ··· 535 /** 536 * ata_acpi_exec_tfs - get then write drive taskfile settings 537 * @dev: target ATA device 538 * 539 * Evaluate _GTF and excute returned taskfiles. 540 * ··· 543 * EH context. 544 * 545 * RETURNS: 546 - * Number of executed taskfiles on success, 0 if _GTF doesn't exist or 547 - * doesn't contain valid data. -errno on other errors. 548 */ 549 - static int ata_acpi_exec_tfs(struct ata_device *dev) 550 { 551 struct ata_acpi_gtf *gtf = NULL; 552 int gtf_count, i, rc; 553 554 /* get taskfiles */ 555 - gtf_count = ata_dev_get_GTF(dev, &gtf); 556 557 /* execute them */ 558 for (i = 0, rc = 0; i < gtf_count; i++) { ··· 567 tmp = taskfile_load_raw(dev, gtf++); 568 if (!rc) 569 rc = tmp; 570 } 571 572 ata_acpi_clear_gtf(dev); 573 574 - if (rc == 0) 575 - return gtf_count; 576 return rc; 577 } 578 ··· 708 struct ata_port *ap = dev->link->ap; 709 struct ata_eh_context *ehc = &ap->link.eh_context; 710 int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA; 711 int rc; 712 713 if (!dev->acpi_handle) ··· 727 } 728 729 /* do _GTF */ 730 - rc = ata_acpi_exec_tfs(dev); 731 - if (rc < 0) 732 goto acpi_err; 733 734 dev->flags &= ~ATA_DFLAG_ACPI_PENDING; 735 736 /* refresh IDENTIFY page if any _GTF command has been executed */ 737 - if (rc > 0) { 738 rc = ata_dev_reread_id(dev, 0); 739 if (rc < 0) { 740 ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY " ··· 746 return 0; 747 748 acpi_err: 749 - /* let EH retry on the first failure, disable ACPI on the second */ 750 - if (dev->flags & ATA_DFLAG_ACPI_FAILED) { 751 - ata_dev_printk(dev, KERN_WARNING, "ACPI on devcfg failed the " 752 - "second time, disabling (errno=%d)\n", rc); 753 754 - dev->acpi_handle = NULL; 755 - 756 - /* if port is working, request IDENTIFY reload and continue */ 757 - if (!(ap->pflags & ATA_PFLAG_FROZEN)) 758 - rc = 1; 759 } 760 - dev->flags |= ATA_DFLAG_ACPI_FAILED; 761 return rc; 762 } 763
··· 346 * EH context. 347 * 348 * RETURNS: 349 + * Number of taskfiles on success, 0 if _GTF doesn't exist. -EINVAL 350 + * if _GTF is invalid. 351 */ 352 static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) 353 { ··· 380 ata_dev_printk(dev, KERN_WARNING, 381 "_GTF evaluation failed (AE 0x%x)\n", 382 status); 383 + rc = -EINVAL; 384 } 385 goto out_free; 386 } ··· 391 __FUNCTION__, 392 (unsigned long long)output.length, 393 output.pointer); 394 + rc = -EINVAL; 395 goto out_free; 396 } 397 ··· 398 ata_dev_printk(dev, KERN_WARNING, 399 "_GTF unexpected object type 0x%x\n", 400 out_obj->type); 401 + rc = -EINVAL; 402 goto out_free; 403 } 404 ··· 405 ata_dev_printk(dev, KERN_WARNING, 406 "unexpected _GTF length (%d)\n", 407 out_obj->buffer.length); 408 + rc = -EINVAL; 409 goto out_free; 410 } 411 ··· 531 /** 532 * ata_acpi_exec_tfs - get then write drive taskfile settings 533 * @dev: target ATA device 534 + * @nr_executed: out paramter for the number of executed commands 535 * 536 * Evaluate _GTF and excute returned taskfiles. 537 * ··· 538 * EH context. 539 * 540 * RETURNS: 541 + * Number of executed taskfiles on success, 0 if _GTF doesn't exist. 542 + * -errno on other errors. 543 */ 544 + static int ata_acpi_exec_tfs(struct ata_device *dev, int *nr_executed) 545 { 546 struct ata_acpi_gtf *gtf = NULL; 547 int gtf_count, i, rc; 548 549 /* get taskfiles */ 550 + rc = ata_dev_get_GTF(dev, &gtf); 551 + if (rc < 0) 552 + return rc; 553 + gtf_count = rc; 554 555 /* execute them */ 556 for (i = 0, rc = 0; i < gtf_count; i++) { ··· 559 tmp = taskfile_load_raw(dev, gtf++); 560 if (!rc) 561 rc = tmp; 562 + 563 + (*nr_executed)++; 564 } 565 566 ata_acpi_clear_gtf(dev); 567 568 return rc; 569 } 570 ··· 700 struct ata_port *ap = dev->link->ap; 701 struct ata_eh_context *ehc = &ap->link.eh_context; 702 int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA; 703 + int nr_executed = 0; 704 int rc; 705 706 if (!dev->acpi_handle) ··· 718 } 719 720 /* do _GTF */ 721 + rc = ata_acpi_exec_tfs(dev, &nr_executed); 722 + if (rc) 723 goto acpi_err; 724 725 dev->flags &= ~ATA_DFLAG_ACPI_PENDING; 726 727 /* refresh IDENTIFY page if any _GTF command has been executed */ 728 + if (nr_executed) { 729 rc = ata_dev_reread_id(dev, 0); 730 if (rc < 0) { 731 ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY " ··· 737 return 0; 738 739 acpi_err: 740 + /* ignore evaluation failure if we can continue safely */ 741 + if (rc == -EINVAL && !nr_executed && !(ap->pflags & ATA_PFLAG_FROZEN)) 742 + return 0; 743 744 + /* fail and let EH retry once more for unknown IO errors */ 745 + if (!(dev->flags & ATA_DFLAG_ACPI_FAILED)) { 746 + dev->flags |= ATA_DFLAG_ACPI_FAILED; 747 + return rc; 748 } 749 + 750 + ata_dev_printk(dev, KERN_WARNING, 751 + "ACPI: failed the second time, disabled\n"); 752 + dev->acpi_handle = NULL; 753 + 754 + /* We can safely continue if no _GTF command has been executed 755 + * and port is not frozen. 756 + */ 757 + if (!nr_executed && !(ap->pflags & ATA_PFLAG_FROZEN)) 758 + return 0; 759 + 760 return rc; 761 } 762