]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/ide-acpi.c
dz.c: Resource management
[linux-2.6-omap-h63xx.git] / drivers / ide / ide-acpi.c
index 1d5f6823101c26c2e73980c6705878956e68be85..e07b189f3ec8504d7f2b19628253855f884ba2c6 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * ide-acpi.c
  * Provides ACPI support for IDE drives.
  *
  * Copyright (C) 2005 Intel Corp.
@@ -16,6 +15,7 @@
 #include <acpi/acpi.h>
 #include <linux/ide.h>
 #include <linux/pci.h>
+#include <linux/dmi.h>
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acnames.h>
@@ -39,7 +39,6 @@ struct GTM_buffer {
 };
 
 struct ide_acpi_drive_link {
-       ide_drive_t     *drive;
        acpi_handle      obj_handle;
        u8               idbuff[512];
 };
@@ -65,6 +64,39 @@ extern int ide_noacpi;
 extern int ide_noacpitfs;
 extern int ide_noacpionboot;
 
+static bool ide_noacpi_psx;
+static int no_acpi_psx(const struct dmi_system_id *id)
+{
+       ide_noacpi_psx = true;
+       printk(KERN_NOTICE"%s detected - disable ACPI _PSx.\n", id->ident);
+       return 0;
+}
+
+static const struct dmi_system_id ide_acpi_dmi_table[] = {
+       /* Bug 9673. */
+       /* We should check if this is because ACPI NVS isn't save/restored. */
+       {
+               .callback = no_acpi_psx,
+               .ident    = "HP nx9005",
+               .matches  = {
+                       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies Ltd."),
+                       DMI_MATCH(DMI_BIOS_VERSION, "KAM1.60")
+               },
+       },
+
+       { }     /* terminate list */
+};
+
+static int ide_acpi_blacklist(void)
+{
+       static int done;
+       if (done)
+               return 0;
+       done = 1;
+       dmi_check_system(ide_acpi_dmi_table);
+       return 0;
+}
+
 /**
  * ide_get_dev_handle - finds acpi_handle and PCI device.function
  * @dev: device to locate
@@ -139,7 +171,7 @@ err:
 static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif)
 {
        struct device           *dev = hwif->gendev.parent;
-       acpi_handle             dev_handle;
+       acpi_handle             uninitialized_var(dev_handle);
        acpi_integer            pcidevfn;
        acpi_handle             chan_handle;
        int                     err;
@@ -247,16 +279,6 @@ static int do_drive_get_GTF(ide_drive_t *drive,
 
        port = hwif->channel ? drive->dn - 2: drive->dn;
 
-       if (!drive->acpidata) {
-               if (port == 0) {
-                       drive->acpidata = &hwif->acpidata->master;
-                       hwif->acpidata->master.drive = drive;
-               } else {
-                       drive->acpidata = &hwif->acpidata->slave;
-                       hwif->acpidata->slave.drive = drive;
-               }
-       }
-
        DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n",
                 hwif->name, dev->bus_id, port, hwif->channel);
 
@@ -349,27 +371,19 @@ static int taskfile_load_raw(ide_drive_t *drive,
               gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
 
        memset(&args, 0, sizeof(ide_task_t));
-       args.command_type = IDE_DRIVE_TASK_NO_DATA;
-       args.data_phase   = TASKFILE_IN;
-       args.handler      = &task_no_data_intr;
 
        /* convert gtf to IDE Taskfile */
-       args.tfRegister[1] = gtf->tfa[0];       /* 0x1f1 */
-       args.tfRegister[2] = gtf->tfa[1];       /* 0x1f2 */
-       args.tfRegister[3] = gtf->tfa[2];       /* 0x1f3 */
-       args.tfRegister[4] = gtf->tfa[3];       /* 0x1f4 */
-       args.tfRegister[5] = gtf->tfa[4];       /* 0x1f5 */
-       args.tfRegister[6] = gtf->tfa[5];       /* 0x1f6 */
-       args.tfRegister[7] = gtf->tfa[6];       /* 0x1f7 */
+       memcpy(&args.tf_array[7], &gtf->tfa, 7);
+       args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 
        if (ide_noacpitfs) {
                DEBPRINT("_GTF execution disabled\n");
                return err;
        }
 
-       err = ide_raw_taskfile(drive, &args, NULL);
+       err = ide_no_data_taskfile(drive, &args);
        if (err)
-               printk(KERN_ERR "%s: ide_raw_taskfile failed: %u\n",
+               printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n",
                       __FUNCTION__, err);
 
        return err;
@@ -469,7 +483,6 @@ int ide_acpi_exec_tfs(ide_drive_t *drive)
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(ide_acpi_exec_tfs);
 
 /**
  * ide_acpi_get_timing - get the channel (controller) timings
@@ -555,7 +568,6 @@ void ide_acpi_get_timing(ide_hwif_t *hwif)
 
        kfree(output.pointer);
 }
-EXPORT_SYMBOL_GPL(ide_acpi_get_timing);
 
 /**
  * ide_acpi_push_timing - set the channel (controller) timings
@@ -609,7 +621,6 @@ void ide_acpi_push_timing(ide_hwif_t *hwif)
        }
        DEBPRINT("_STM status: %d\n", status);
 }
-EXPORT_SYMBOL_GPL(ide_acpi_push_timing);
 
 /**
  * ide_acpi_set_state - set the channel power state
@@ -623,7 +634,7 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
 {
        int unit;
 
-       if (ide_noacpi)
+       if (ide_noacpi || ide_noacpi_psx)
                return;
 
        DEBPRINT("ENTER:\n");
@@ -663,10 +674,7 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
  */
 void ide_acpi_init(ide_hwif_t *hwif)
 {
-       int unit;
-       int                     err;
-       struct ide_acpi_drive_link      *master;
-       struct ide_acpi_drive_link      *slave;
+       ide_acpi_blacklist();
 
        hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL);
        if (!hwif->acpidata)
@@ -677,40 +685,38 @@ void ide_acpi_init(ide_hwif_t *hwif)
                DEBPRINT("no ACPI object for %s found\n", hwif->name);
                kfree(hwif->acpidata);
                hwif->acpidata = NULL;
-               return;
        }
+}
+
+void ide_acpi_port_init_devices(ide_hwif_t *hwif)
+{
+       ide_drive_t *drive;
+       int i, err;
+
+       if (hwif->acpidata == NULL)
+               return;
 
        /*
         * The ACPI spec mandates that we send information
         * for both drives, regardless whether they are connected
         * or not.
         */
-       hwif->acpidata->master.drive = &hwif->drives[0];
        hwif->drives[0].acpidata = &hwif->acpidata->master;
-       master = &hwif->acpidata->master;
-
-       hwif->acpidata->slave.drive = &hwif->drives[1];
        hwif->drives[1].acpidata = &hwif->acpidata->slave;
-       slave = &hwif->acpidata->slave;
-
 
        /*
         * Send IDENTIFY for each drive
         */
-       if (master->drive->present) {
-               err = taskfile_lib_get_identify(master->drive, master->idbuff);
-               if (err) {
-                       DEBPRINT("identify device %s failed (%d)\n",
-                                master->drive->name, err);
-               }
-       }
+       for (i = 0; i < MAX_DRIVES; i++) {
+               drive = &hwif->drives[i];
 
-       if (slave->drive->present) {
-               err = taskfile_lib_get_identify(slave->drive, slave->idbuff);
-               if (err) {
+               if (!drive->present)
+                       continue;
+
+               err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff);
+               if (err)
                        DEBPRINT("identify device %s failed (%d)\n",
-                                slave->drive->name, err);
-               }
+                                drive->name, err);
        }
 
        if (ide_noacpionboot) {
@@ -726,13 +732,11 @@ void ide_acpi_init(ide_hwif_t *hwif)
        ide_acpi_get_timing(hwif);
        ide_acpi_push_timing(hwif);
 
-       for (unit = 0; unit < MAX_DRIVES; ++unit) {
-               ide_drive_t *drive = &hwif->drives[unit];
+       for (i = 0; i < MAX_DRIVES; i++) {
+               drive = &hwif->drives[i];
 
-               if (drive->present) {
+               if (drive->present)
                        /* Execute ACPI startup code */
                        ide_acpi_exec_tfs(drive);
-               }
        }
 }
-EXPORT_SYMBOL_GPL(ide_acpi_init);