libata-acpi: implement and use ata_acpi_init_gtm()

_GTM fetches currently configured transfer mode while _STM configures
controller according to _GTM parameter and prepares transfer mode
configuration TFs for _GTF. In many cases _GTM and _STM
implementations are quite brittle and can't cope with configuration
changed by libata.

libata does not depend on ATA ACPI to configure devices. The only
reason libata performs _GTM and _STM are to make _GTF evaluation
succeed and libata also doesn't care about how _GTF TFs configure
transfer mode. It overrides that configuration anyway, so from
libata's POV, it doesn't matter what value is feeded to _STM as long
as evaluation succeeds for _STM and following _GTF.

This patch adds dev->__acpi_init_gtm and store initial _GTM values on
host initialization before modified by reset and mode configuration.
If the field is valid, ata_acpi_init_gtm() returns pointer to the
saved _GTM structure; otherwise, NULL.

This saved value is used for _STM during resume and peek at
BIOS/firmware programmed initial timing for later use. The accessor
is there to make building w/o ACPI easy as dev->__acpi_init doesn't
exist if ACPI is not enabled.

On driver detach, the initial BIOS configuration is restored by
executing _STM with the initial _GTM values such that the next driver
can also use the initial BIOS configured values.

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 c05e6ff0 562f0c2d

+39 -37
+27 -35
drivers/ata/libata-acpi.c
··· 94 94 95 95 dev->acpi_handle = acpi_get_child(ap->acpi_handle, i); 96 96 } 97 + 98 + if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) 99 + ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; 97 100 } 98 101 99 102 static void ata_acpi_handle_hotplug(struct ata_port *ap, struct kobject *kobj, ··· 202 199 */ 203 200 void ata_acpi_dissociate(struct ata_host *host) 204 201 { 205 - /* nada */ 202 + int i; 203 + 204 + /* Restore initial _GTM values so that driver which attaches 205 + * afterward can use them too. 206 + */ 207 + for (i = 0; i < host->n_ports; i++) { 208 + struct ata_port *ap = host->ports[i]; 209 + const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); 210 + 211 + if (ap->acpi_handle && gtm) 212 + ata_acpi_stm(ap, gtm); 213 + } 206 214 } 207 215 208 216 /** ··· 423 409 424 410 int ata_acpi_cbl_80wire(struct ata_port *ap) 425 411 { 426 - struct ata_acpi_gtm gtm; 412 + const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); 427 413 int valid = 0; 428 414 429 - /* No _GTM data, no information */ 430 - if (ata_acpi_gtm(ap, &gtm) < 0) 415 + if (!gtm) 431 416 return 0; 432 417 433 418 /* Split timing, DMA enabled */ 434 - if ((gtm.flags & 0x11) == 0x11 && gtm.drive[0].dma < 55) 419 + if ((gtm->flags & 0x11) == 0x11 && gtm->drive[0].dma < 55) 435 420 valid |= 1; 436 - if ((gtm.flags & 0x14) == 0x14 && gtm.drive[1].dma < 55) 421 + if ((gtm->flags & 0x14) == 0x14 && gtm->drive[1].dma < 55) 437 422 valid |= 2; 438 423 /* Shared timing, DMA enabled */ 439 - if ((gtm.flags & 0x11) == 0x01 && gtm.drive[0].dma < 55) 424 + if ((gtm->flags & 0x11) == 0x01 && gtm->drive[0].dma < 55) 440 425 valid |= 1; 441 - if ((gtm.flags & 0x14) == 0x04 && gtm.drive[0].dma < 55) 426 + if ((gtm->flags & 0x14) == 0x04 && gtm->drive[0].dma < 55) 442 427 valid |= 2; 443 428 444 429 /* Drive check */ ··· 625 612 */ 626 613 int ata_acpi_on_suspend(struct ata_port *ap) 627 614 { 628 - unsigned long flags; 629 - int rc; 630 - 631 - /* proceed iff per-port acpi_handle is valid */ 632 - if (!ap->acpi_handle) 633 - return 0; 634 - BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA); 635 - 636 - /* store timing parameters */ 637 - rc = ata_acpi_gtm(ap, &ap->acpi_gtm); 638 - 639 - spin_lock_irqsave(ap->lock, flags); 640 - if (rc == 0) 641 - ap->pflags |= ATA_PFLAG_GTM_VALID; 642 - else 643 - ap->pflags &= ~ATA_PFLAG_GTM_VALID; 644 - spin_unlock_irqrestore(ap->lock, flags); 645 - 646 - if (rc == -ENOENT) 647 - rc = 0; 648 - return rc; 615 + /* nada */ 616 + return 0; 649 617 } 650 618 651 619 /** ··· 641 647 */ 642 648 void ata_acpi_on_resume(struct ata_port *ap) 643 649 { 650 + const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); 644 651 struct ata_device *dev; 645 652 646 - if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) { 647 - BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA); 648 - 649 - /* restore timing parameters */ 650 - ata_acpi_stm(ap, &ap->acpi_gtm); 651 - } 653 + /* restore timing parameters */ 654 + if (ap->acpi_handle && gtm) 655 + ata_acpi_stm(ap, gtm); 652 656 653 657 /* schedule _GTF */ 654 658 ata_link_for_each_dev(dev, &ap->link)
+12 -2
include/linux/libata.h
··· 211 211 212 212 ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ 213 213 ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ 214 - ATA_PFLAG_GTM_VALID = (1 << 19), /* acpi_gtm data valid */ 214 + ATA_PFLAG_INIT_GTM_VALID = (1 << 19), /* initial gtm data valid */ 215 215 216 216 /* struct ata_queued_cmd flags */ 217 217 ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ ··· 653 653 654 654 #ifdef CONFIG_ATA_ACPI 655 655 acpi_handle acpi_handle; 656 - struct ata_acpi_gtm acpi_gtm; 656 + struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ 657 657 #endif 658 658 u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */ 659 659 }; ··· 939 939 940 940 /* libata-acpi.c */ 941 941 #ifdef CONFIG_ATA_ACPI 942 + static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) 943 + { 944 + if (ap->pflags & ATA_PFLAG_INIT_GTM_VALID) 945 + return &ap->__acpi_init_gtm; 946 + return NULL; 947 + } 942 948 extern int ata_acpi_cbl_80wire(struct ata_port *ap); 943 949 int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm); 944 950 int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *stm); 945 951 #else 952 + static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) 953 + { 954 + return NULL; 955 + } 946 956 static inline int ata_acpi_cbl_80wire(struct ata_port *ap) { return 0; } 947 957 #endif 948 958