aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-acpi.c62
-rw-r--r--include/linux/libata.h14
2 files changed, 39 insertions, 37 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)
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 3784af395576..ba84d8a37545 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -211,7 +211,7 @@ enum {
211 211
212 ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ 212 ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */
213 ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ 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 /* struct ata_queued_cmd flags */ 216 /* struct ata_queued_cmd flags */
217 ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ 217 ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */
@@ -653,7 +653,7 @@ struct ata_port {
653 653
654#ifdef CONFIG_ATA_ACPI 654#ifdef CONFIG_ATA_ACPI
655 acpi_handle acpi_handle; 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#endif 657#endif
658 u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */ 658 u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */
659}; 659};
@@ -939,10 +939,20 @@ enum {
939 939
940/* libata-acpi.c */ 940/* libata-acpi.c */
941#ifdef CONFIG_ATA_ACPI 941#ifdef CONFIG_ATA_ACPI
942static 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}
942extern int ata_acpi_cbl_80wire(struct ata_port *ap); 948extern int ata_acpi_cbl_80wire(struct ata_port *ap);
943int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm); 949int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm);
944int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *stm); 950int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *stm);
945#else 951#else
952static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap)
953{
954 return NULL;
955}
946static inline int ata_acpi_cbl_80wire(struct ata_port *ap) { return 0; } 956static inline int ata_acpi_cbl_80wire(struct ata_port *ap) { return 0; }
947#endif 957#endif
948 958