aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-12-15 01:05:02 -0500
committerJeff Garzik <jeff@garzik.org>2007-12-17 20:33:14 -0500
commitc05e6ff035c1b25d17364a685432b33937d3dc23 (patch)
tree08c9171d024b6659b29a4f9f7d95318430b75b6a /drivers/ata
parent562f0c2d771ee7be6b37fe015f94a929f8056120 (diff)
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>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-acpi.c62
1 files changed, 27 insertions, 35 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 9e5fc5d75b2e..b3aeca368774 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -94,6 +94,9 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
94 94
95 dev->acpi_handle = acpi_get_child(ap->acpi_handle, i); 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
99static void ata_acpi_handle_hotplug(struct ata_port *ap, struct kobject *kobj, 102static void ata_acpi_handle_hotplug(struct ata_port *ap, struct kobject *kobj,
@@ -199,7 +202,18 @@ void ata_acpi_associate(struct ata_host *host)
199 */ 202 */
200void ata_acpi_dissociate(struct ata_host *host) 203void ata_acpi_dissociate(struct ata_host *host)
201{ 204{
202 /* nada */ 205 int i;
206
207 /* Restore initial _GTM values so that driver which attaches
208 * afterward can use them too.
209 */
210 for (i = 0; i < host->n_ports; i++) {
211 struct ata_port *ap = host->ports[i];
212 const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
213
214 if (ap->acpi_handle && gtm)
215 ata_acpi_stm(ap, gtm);
216 }
203} 217}
204 218
205/** 219/**
@@ -409,22 +423,21 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
409 423
410int ata_acpi_cbl_80wire(struct ata_port *ap) 424int ata_acpi_cbl_80wire(struct ata_port *ap)
411{ 425{
412 struct ata_acpi_gtm gtm; 426 const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
413 int valid = 0; 427 int valid = 0;
414 428
415 /* No _GTM data, no information */ 429 if (!gtm)
416 if (ata_acpi_gtm(ap, &gtm) < 0)
417 return 0; 430 return 0;
418 431
419 /* Split timing, DMA enabled */ 432 /* Split timing, DMA enabled */
420 if ((gtm.flags & 0x11) == 0x11 && gtm.drive[0].dma < 55) 433 if ((gtm->flags & 0x11) == 0x11 && gtm->drive[0].dma < 55)
421 valid |= 1; 434 valid |= 1;
422 if ((gtm.flags & 0x14) == 0x14 && gtm.drive[1].dma < 55) 435 if ((gtm->flags & 0x14) == 0x14 && gtm->drive[1].dma < 55)
423 valid |= 2; 436 valid |= 2;
424 /* Shared timing, DMA enabled */ 437 /* Shared timing, DMA enabled */
425 if ((gtm.flags & 0x11) == 0x01 && gtm.drive[0].dma < 55) 438 if ((gtm->flags & 0x11) == 0x01 && gtm->drive[0].dma < 55)
426 valid |= 1; 439 valid |= 1;
427 if ((gtm.flags & 0x14) == 0x04 && gtm.drive[0].dma < 55) 440 if ((gtm->flags & 0x14) == 0x04 && gtm->drive[0].dma < 55)
428 valid |= 2; 441 valid |= 2;
429 442
430 /* Drive check */ 443 /* Drive check */
@@ -612,27 +625,8 @@ static int ata_acpi_push_id(struct ata_device *dev)
612 */ 625 */
613int ata_acpi_on_suspend(struct ata_port *ap) 626int ata_acpi_on_suspend(struct ata_port *ap)
614{ 627{
615 unsigned long flags; 628 /* nada */
616 int rc; 629 return 0;
617
618 /* proceed iff per-port acpi_handle is valid */
619 if (!ap->acpi_handle)
620 return 0;
621 BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
622
623 /* store timing parameters */
624 rc = ata_acpi_gtm(ap, &ap->acpi_gtm);
625
626 spin_lock_irqsave(ap->lock, flags);
627 if (rc == 0)
628 ap->pflags |= ATA_PFLAG_GTM_VALID;
629 else
630 ap->pflags &= ~ATA_PFLAG_GTM_VALID;
631 spin_unlock_irqrestore(ap->lock, flags);
632
633 if (rc == -ENOENT)
634 rc = 0;
635 return rc;
636} 630}
637 631
638/** 632/**
@@ -647,14 +641,12 @@ int ata_acpi_on_suspend(struct ata_port *ap)
647 */ 641 */
648void ata_acpi_on_resume(struct ata_port *ap) 642void ata_acpi_on_resume(struct ata_port *ap)
649{ 643{
644 const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
650 struct ata_device *dev; 645 struct ata_device *dev;
651 646
652 if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) { 647 /* restore timing parameters */
653 BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA); 648 if (ap->acpi_handle && gtm)
654 649 ata_acpi_stm(ap, gtm);
655 /* restore timing parameters */
656 ata_acpi_stm(ap, &ap->acpi_gtm);
657 }
658 650
659 /* schedule _GTF */ 651 /* schedule _GTF */
660 ata_link_for_each_dev(dev, &ap->link) 652 ata_link_for_each_dev(dev, &ap->link)