Ok. How about this? Couple of cleanups, and leaves the possibility for 
drivers to pass in their own gtf structure.

diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 0bd4789..b434c39 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -291,13 +291,12 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
                        unsigned long *obj_loc)
 {
        acpi_status                     status;
-       acpi_handle                     dev_handle = NULL;
-       acpi_handle                     chan_handle, drive_handle;
-       acpi_integer                    pcidevfn = 0;
+       acpi_handle                     drive_handle;
        u32                             dev_adr;
        struct acpi_buffer              output;
        union acpi_object               *out_obj;
        struct device                   *dev = ap->host->dev;
+       struct ata_acpi_port_link           *acpidata = ap->acpi_port_link;
        struct ata_device               *atadev = &ap->device[ix];
        int                             err = -ENODEV;
 
@@ -321,47 +320,12 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
                goto out;
        }
 
-       /* Don't continue if device has no _ADR method.
-        * _GTF is intended for known motherboard devices. */
-       if (!(ap->cbl == ATA_CBL_SATA)) {
-               err = pata_get_dev_handle(dev, &dev_handle, &pcidevfn);
-               if (err < 0) {
-                       if (ata_msg_probe(ap))
-                               ata_dev_printk(atadev, KERN_DEBUG,
-                                       "%s: pata_get_dev_handle failed (%d)\n",
-                                       __FUNCTION__, err);
-                       goto out;
-               }
-       } else {
-               err = sata_get_dev_handle(dev, &dev_handle, &pcidevfn);
-               if (err < 0) {
-                       if (ata_msg_probe(ap))
-                               ata_dev_printk(atadev, KERN_DEBUG,
-                                       "%s: sata_get_dev_handle failed (%d\n",
-                                       __FUNCTION__, err);
-                       goto out;
-               }
-       }
-
        /* Get this drive's _ADR info. if not already known. */
        if (!atadev->obj_handle) {
-               if (!(ap->cbl == ATA_CBL_SATA)) {
-                       /* get child objects of dev_handle == channel objects,
-                        * + _their_ children == drive objects */
-                       /* channel is ap->port_no */
-                       chan_handle = acpi_get_child(dev_handle,
-                                               ap->port_no);
-                       if (ata_msg_probe(ap))
-                               ata_dev_printk(atadev, KERN_DEBUG,
-                                       "%s: chan adr=%d: chan_handle=0x%p\n",
-                                       __FUNCTION__, ap->port_no,
-                                       chan_handle);
-                       if (!chan_handle) {
-                               err = -ENODEV;
-                               goto out;
-                       }
+               if (acpidata->is_pata) {
                        /* TBD: could also check ACPI object VALID bits */
-                       drive_handle = acpi_get_child(chan_handle, ix);
+                       drive_handle = 
+                               acpi_get_child(acpidata->handle, ix);
                        if (!drive_handle) {
                                err = -ENODEV;
                                goto out;
@@ -370,8 +334,9 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
                        atadev->obj_handle = drive_handle;
                } else {        /* for SATA mode */
                        dev_adr = SATA_ADR_RSVD;
-                       err = get_sata_adr(dev, dev_handle, pcidevfn, 0,
-                                       ap, atadev, &dev_adr);
+                       err = get_sata_adr(dev, acpidata->handle, 
+                                          acpidata->devfn, 0, ap, atadev, 
+                                          &dev_adr);
                }
                if (err < 0 || dev_adr == SATA_ADR_RSVD ||
                    !atadev->obj_handle) {
@@ -526,12 +491,13 @@ static int do_drive_set_taskfiles(struct ata_port *ap,
        int                     gtf_count = gtf_length / REGS_PER_GTF;
        int                     ix;
        struct taskfile_array   *gtf;
+       struct ata_acpi_port_link   *acpidata = ap->acpi_port_link;
 
        if (ata_msg_probe(ap))
                ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
                               __FUNCTION__, ap->port_no);
 
-       if (noacpi || !(ap->cbl == ATA_CBL_SATA))
+       if (noacpi || !acpidata || acpidata->is_pata)
                return 0;
 
        if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED))
@@ -573,6 +539,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
        unsigned int    gtf_length;
        unsigned long   gtf_address;
        unsigned long   obj_loc;
+       struct ata_acpi_port_link *acpidata = ap->acpi_port_link;
 
        if (noacpi)
                return 0;
@@ -581,7 +548,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
         * we should not run GTF on PATA devices since some
         * PATA require execution of GTM/STM before GTF.
         */
-       if (!(ap->cbl == ATA_CBL_SATA))
+       if (!acpidata || acpidata->is_pata)
                return 0;
 
        for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
@@ -626,8 +593,6 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
  */
 int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
 {
-       acpi_handle                     handle;
-       acpi_integer                    pcidevfn;
        int                             err;
        struct device                   *dev = ap->host->dev;
        struct ata_device               *atadev = &ap->device[ix];
@@ -635,38 +600,20 @@ int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
        acpi_status                     status;
        struct acpi_object_list         input;
        union acpi_object               in_params[1];
+       struct ata_acpi_port_link           *acpidata = ap->acpi_port_link;
 
-       if (noacpi)
+       if (noacpi || !acpidata || acpidata->is_pata)
                return 0;
 
        if (ata_msg_probe(ap))
                ata_dev_printk(atadev, KERN_DEBUG, "%s: ix = %d, port#: %d\n",
                               __FUNCTION__, ix, ap->port_no);
 
-       /* Don't continue if not a SATA device. */
-       if (!(ap->cbl == ATA_CBL_SATA)) {
-               if (ata_msg_probe(ap))
-                       ata_dev_printk(atadev, KERN_DEBUG,
-                               "%s: Not a SATA device\n", __FUNCTION__);
-               goto out;
-       }
-
-       /* Don't continue if device has no _ADR method.
-        * _SDD is intended for known motherboard devices. */
-       err = sata_get_dev_handle(dev, &handle, &pcidevfn);
-       if (err < 0) {
-               if (ata_msg_probe(ap))
-                       ata_dev_printk(atadev, KERN_DEBUG,
-                               "%s: sata_get_dev_handle failed (%d\n",
-                               __FUNCTION__, err);
-               goto out;
-       }
-
        /* Get this drive's _ADR info, if not already known */
        if (!atadev->obj_handle) {
                dev_adr = SATA_ADR_RSVD;
-               err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev,
-                                       &dev_adr);
+               err = get_sata_adr(dev, acpidata->handle, acpidata->devfn, ix,
+                                  ap, atadev, &dev_adr);
                if (err < 0 || dev_adr == SATA_ADR_RSVD ||
                        !atadev->obj_handle) {
                        if (ata_msg_probe(ap))
@@ -706,16 +653,19 @@ out:
        return 0;
 }
 
-
-int ata_acpi_gtm(const struct ata_port *ap, void *handle, struct acpi_gtm *gtm)
+int ata_acpi_gtm(const struct ata_port *ap, struct acpi_gtm *gtm)
 {
        acpi_status status;
        struct acpi_buffer output;
+       struct ata_acpi_port_link *acpidata = ap->acpi_port_link;
+
+       if (!acpidata || !acpidata->is_pata)
+               return -ENODEV;
 
        output.length = ACPI_ALLOCATE_BUFFER;
        output.pointer = NULL;
 
-       status = acpi_evaluate_object(handle, "_GTM", NULL, &output);
+       status = acpi_evaluate_object(acpidata->handle, "_GTM", NULL, &output);
 
        if (ACPI_FAILURE(status)) {
                ata_port_printk(ap, KERN_ERR, "ACPI get timing mode failed.\n");
@@ -730,11 +680,15 @@ int ata_acpi_gtm(const struct ata_port *ap, void *handle, 
struct acpi_gtm *gtm)
        return 0;
 }
 
-int ata_acpi_stm(const struct ata_port *ap, void *handle, struct acpi_gtm *stm)
+int ata_acpi_stm(const struct ata_port *ap, struct acpi_gtm *stm)
 {
        acpi_status status;
        struct acpi_object_list         input;
        union acpi_object               in_params[3];
+       struct ata_acpi_port_link       *acpidata = ap->acpi_port_link;
+
+       if (!acpidata || !acpidata->is_pata)
+               return -ENODEV;
 
        in_params[0].type = ACPI_TYPE_BUFFER;
        in_params[0].buffer.length = sizeof(struct acpi_gtm);
@@ -750,7 +704,7 @@ int ata_acpi_stm(const struct ata_port *ap, void *handle, 
struct acpi_gtm *stm)
        input.count = 3;
        input.pointer = in_params;
 
-       status = acpi_evaluate_object(handle, "_STM", &input, NULL);
+       status = acpi_evaluate_object(acpidata->handle, "_STM", &input, NULL);
 
        if (ACPI_FAILURE(status)) {
                ata_port_printk(ap, KERN_ERR, "ACPI set timing mode failed.\n");
@@ -787,8 +741,61 @@ int ata_pata_acpi_present(struct pci_dev *pdev)
        return present;
 }
 
+static void *ata_sata_find_handle(struct device *dev, int port)
+{
+       acpi_handle handle;
+       acpi_integer devfn;
+
+       if (noacpi)
+               return NULL;
+       if (sata_get_dev_handle(dev, &handle, &devfn) < 0)
+               return NULL;
+       return acpi_get_child(handle, port);
+}
+
+int ata_sata_acpi_present(struct pci_dev *pdev)
+{
+       if (ata_sata_find_handle(&pdev->dev, 0))
+               return 1;
+       return 0;
+}
+
+void ata_acpi_setup(struct ata_port *ap)
+{
+       struct device *dev = ap->host->dev;     
+       struct pci_dev *pci_dev;
+       struct ata_acpi_port_link *acpidata;
+       int pata;
+
+       if (!is_pci_dev (dev))
+               return;
+
+       pci_dev = to_pci_dev(dev);
+
+       if (ata_pata_acpi_present(pci_dev))
+               pata = 1;
+       else if (ata_sata_acpi_present(pci_dev)) 
+               pata = 0;
+       else
+               return;
+
+       acpidata = kzalloc(sizeof(struct ata_acpi_port_link), GFP_KERNEL);
+       acpidata->is_pata = pata;
+       acpidata->devfn = (PCI_SLOT(pci_dev->devfn) << 16) | 
+               PCI_FUNC(pci_dev->devfn);
+       if (pata) {
+               acpidata->handle = 
+                       ata_pata_find_handle(ap->host->dev, ap->port_no);
+               ap->gtm = kzalloc(sizeof(struct acpi_gtm), GFP_KERNEL);
+       } else
+               acpidata->handle = 
+                       ata_sata_find_handle(ap->host->dev, ap->port_no);
+
+       ap->acpi_port_link = acpidata;
+}
 
 EXPORT_SYMBOL_GPL(ata_acpi_gtm);
 EXPORT_SYMBOL_GPL(ata_acpi_stm);
 EXPORT_SYMBOL_GPL(ata_pata_acpi_handle);
 EXPORT_SYMBOL_GPL(ata_pata_acpi_present);
+EXPORT_SYMBOL_GPL(ata_acpi_setup);
diff --git a/drivers/ata/libata-acpi.h b/drivers/ata/libata-acpi.h
index d630ec3..5948310 100644
--- a/drivers/ata/libata-acpi.h
+++ b/drivers/ata/libata-acpi.h
@@ -39,9 +39,48 @@ struct acpi_gtm {
        u32 flags;
 };
 
-extern int ata_acpi_gtm(const struct ata_port *p, void *handle, struct 
acpi_gtm *gtm);
-extern int ata_acpi_stm(const struct ata_port *ap, void *handle, struct 
acpi_gtm *stm);
+struct ata_acpi_port_link {
+       int is_pata;
+       acpi_handle *handle;
+       acpi_integer devfn;
+};
+
+#ifdef CONFIG_SATA_ACPI
+extern int ata_acpi_exec_tfs(struct ata_port *ap);
+extern int ata_acpi_push_id(struct ata_port *ap, unsigned int ix);
+extern int ata_acpi_gtm(const struct ata_port *p, struct acpi_gtm *gtm);
+extern int ata_acpi_stm(const struct ata_port *ap, struct acpi_gtm *stm);
 extern void *ata_pata_acpi_handle(const struct ata_port *ap);
 extern int ata_pata_acpi_present(struct pci_dev *pdev);
-
+extern void ata_acpi_setup(struct ata_port *ap);
+#else
+static inline int ata_acpi_exec_tfs(struct ata_port *ap)
+{
+        return 0;
+}
+static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
+{
+        return 0;
+}
+extern inline int ata_acpi_gtm(const struct ata_port *p, struct acpi_gtm *gtm)
+{
+       return 0;
+}
+extern inline int ata_acpi_stm(const struct ata_port *ap, struct acpi_gtm *stm)
+{
+       return 0;
+}
+extern inline void *ata_pata_acpi_handle(const struct ata_port *ap)
+{
+       return 0;
+}
+extern inline int ata_pata_acpi_present(struct pci_dev *pdev)
+{
+       return 0;
+}
+extern inline void ata_acpi_setup(struct ata_port *ap)
+{
+       return;
+}
+#endif /* CONFIG_SATA_ACPI */
 #endif
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bf327d4..a7258b6 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -58,6 +58,7 @@
 #include <asm/byteorder.h>
 
 #include "libata.h"
+#include "libata-acpi.h"
 
 #define DRV_VERSION    "2.20"  /* must be exactly four chars */
 
@@ -5444,6 +5445,8 @@ int ata_host_suspend(struct ata_host *host, pm_message_t 
mesg)
                                goto fail;
                        }
                }
+
+               ata_acpi_gtm(ap, ap->gtm);
        }
 
        host->dev->power.power_state = mesg;
@@ -5467,6 +5470,12 @@ int ata_host_suspend(struct ata_host *host, pm_message_t 
mesg)
  */
 void ata_host_resume(struct ata_host *host)
 {
+       int i;
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+               ata_acpi_stm(ap, ap->gtm);
+       }
+
        ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET,
                            ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
        host->dev->power.power_state = PMSG_ON;
@@ -5917,6 +5926,7 @@ int ata_device_add(const struct ata_probe_ent *ent)
                struct ata_port *ap = host->ports[i];
 
                ata_scsi_scan_host(ap);
+               ata_acpi_setup(ap);
        }
 
        VPRINTK("EXIT, returning %u\n", ent->n_ports);
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index c426714..eb41263 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -97,21 +97,6 @@ extern void ata_port_init(struct ata_port *ap, struct 
ata_host *host,
 extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev,
                                                 const struct ata_port_info 
*port);
 
-/* libata-acpi.c */
-#ifdef CONFIG_SATA_ACPI
-extern int ata_acpi_exec_tfs(struct ata_port *ap);
-extern int ata_acpi_push_id(struct ata_port *ap, unsigned int ix);
-#else
-static inline int ata_acpi_exec_tfs(struct ata_port *ap)
-{
-       return 0;
-}
-static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
-{
-       return 0;
-}
-#endif
-
 /* libata-scsi.c */
 extern struct scsi_transport_template ata_scsi_transport_template;
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index e3f32f3..4774c08 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -590,6 +590,10 @@ struct ata_port {
        void                    *private_data;
 
        u8                      sector_buf[ATA_SECT_SIZE]; /* owned by EH */
+       struct acpi_gtm         *gtm;
+#ifdef CONFIG_SATA_ACPI
+       struct ata_acpi_port_link *acpi_port_link;
+#endif
 };
 
 struct ata_port_operations {

-- 
Matthew Garrett | [EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to