pata_efar: fix PIO2 underclocking
[safe/jmp/linux-2.6] / drivers / ata / libata-acpi.c
index 97727be..6273d98 100644 (file)
 #include "libata.h"
 
 #include <acpi/acpi_bus.h>
-#include <acpi/acnames.h>
-#include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
-#include <acpi/acexcep.h>
-#include <acpi/acmacros.h>
-#include <acpi/actypes.h>
 
 enum {
        ATA_ACPI_FILTER_SETXFER = 1 << 0,
@@ -89,7 +83,7 @@ void ata_acpi_associate_sata_port(struct ata_port *ap)
 
                ap->link.device->acpi_handle = NULL;
 
-               ata_port_for_each_link(link, ap) {
+               ata_for_each_link(link, ap, EDGE) {
                        acpi_integer adr = SATA_ADR(ap->port_no, link->pmp);
 
                        link->device->acpi_handle =
@@ -129,8 +123,8 @@ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
                struct ata_link *tlink;
                struct ata_device *tdev;
 
-               ata_port_for_each_link(tlink, ap)
-                       ata_link_for_each_dev(tdev, tlink)
+               ata_for_each_link(tlink, ap, EDGE)
+                       ata_for_each_dev(tdev, tlink, ALL)
                                tdev->flags |= ATA_DFLAG_DETACH;
        }
 
@@ -209,6 +203,46 @@ static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data)
        ata_acpi_handle_hotplug(ap, NULL, event);
 }
 
+static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,
+       u32 event)
+{
+       struct kobject *kobj = NULL;
+       char event_string[20];
+       char *envp[] = { event_string, NULL };
+
+       if (dev) {
+               if (dev->sdev)
+                       kobj = &dev->sdev->sdev_gendev.kobj;
+       } else
+               kobj = &ap->dev->kobj;
+
+       if (kobj) {
+               snprintf(event_string, 20, "BAY_EVENT=%d", event);
+               kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
+       }
+}
+
+static void ata_acpi_ap_uevent(acpi_handle handle, u32 event, void *data)
+{
+       ata_acpi_uevent(data, NULL, event);
+}
+
+static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data)
+{
+       struct ata_device *dev = data;
+       ata_acpi_uevent(dev->link->ap, dev, event);
+}
+
+static struct acpi_dock_ops ata_acpi_dev_dock_ops = {
+       .handler = ata_acpi_dev_notify_dock,
+       .uevent = ata_acpi_dev_uevent,
+};
+
+static struct acpi_dock_ops ata_acpi_ap_dock_ops = {
+       .handler = ata_acpi_ap_notify_dock,
+       .uevent = ata_acpi_ap_uevent,
+};
+
 /**
  * ata_acpi_associate - associate ATA host with ACPI objects
  * @host: target ATA host
@@ -244,7 +278,7 @@ void ata_acpi_associate(struct ata_host *host)
                if (ap->acpi_handle) {
                        /* we might be on a docking station */
                        register_hotplug_dock_device(ap->acpi_handle,
-                                            ata_acpi_ap_notify_dock, ap);
+                                            &ata_acpi_ap_dock_ops, ap);
                }
 
                for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
@@ -253,7 +287,7 @@ void ata_acpi_associate(struct ata_host *host)
                        if (dev->acpi_handle) {
                                /* we might be on a docking station */
                                register_hotplug_dock_device(dev->acpi_handle,
-                                            ata_acpi_dev_notify_dock, dev);
+                                            &ata_acpi_dev_dock_ops, dev);
                        }
                }
        }
@@ -548,12 +582,9 @@ int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm)
 {
        struct ata_device *dev;
 
-       ata_link_for_each_dev(dev, &ap->link) {
+       ata_for_each_dev(dev, &ap->link, ENABLED) {
                unsigned long xfer_mask, udma_mask;
 
-               if (!ata_dev_enabled(dev))
-                       continue;
-
                xfer_mask = ata_acpi_gtm_xfermask(dev, gtm);
                ata_unpack_xfermask(xfer_mask, NULL, NULL, &udma_mask);
 
@@ -853,7 +884,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
                 * use values set by _STM.  Cache _GTF result and
                 * schedule _GTF.
                 */
-               ata_link_for_each_dev(dev, &ap->link) {
+               ata_for_each_dev(dev, &ap->link, ALL) {
                        ata_acpi_clear_gtf(dev);
                        if (ata_dev_enabled(dev) &&
                            ata_dev_get_GTF(dev, NULL) >= 0)
@@ -864,7 +895,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
                 * there's no reason to evaluate IDE _GTF early
                 * without _STM.  Clear cache and schedule _GTF.
                 */
-               ata_link_for_each_dev(dev, &ap->link) {
+               ata_for_each_dev(dev, &ap->link, ALL) {
                        ata_acpi_clear_gtf(dev);
                        if (ata_dev_enabled(dev))
                                dev->flags |= ATA_DFLAG_ACPI_PENDING;
@@ -892,8 +923,8 @@ void ata_acpi_set_state(struct ata_port *ap, pm_message_t state)
        if (state.event == PM_EVENT_ON)
                acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0);
 
-       ata_link_for_each_dev(dev, &ap->link) {
-               if (dev->acpi_handle && ata_dev_enabled(dev))
+       ata_for_each_dev(dev, &ap->link, ENABLED) {
+               if (dev->acpi_handle)
                        acpi_bus_set_power(dev->acpi_handle,
                                state.event == PM_EVENT_ON ?
                                        ACPI_STATE_D0 : ACPI_STATE_D3);