kbuild: fix segfault in modpost
[safe/jmp/linux-2.6] / drivers / ata / ata_piix.c
index 127deb8..92c2d50 100644 (file)
@@ -94,7 +94,7 @@
 #include <linux/dmi.h>
 
 #define DRV_NAME       "ata_piix"
-#define DRV_VERSION    "2.11"
+#define DRV_VERSION    "2.12"
 
 enum {
        PIIX_IOCFG              = 0x54, /* IDE I/O configuration register */
@@ -919,7 +919,14 @@ static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev)
 #ifdef CONFIG_PM
 static int piix_broken_suspend(void)
 {
-       static struct dmi_system_id sysids[] = {
+       static const struct dmi_system_id sysids[] = {
+               {
+                       .ident = "TECRA M3",
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M3"),
+                       },
+               },
                {
                        .ident = "TECRA M5",
                        .matches = {
@@ -935,6 +942,13 @@ static int piix_broken_suspend(void)
                        },
                },
                {
+                       .ident = "Satellite U200",
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U200"),
+                       },
+               },
+               {
                        .ident = "Satellite U205",
                        .matches = {
                                DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
@@ -948,7 +962,8 @@ static int piix_broken_suspend(void)
                                DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M500"),
                        },
                },
-               { }
+
+               { }     /* terminate list */
        };
        static const char *oemstrs[] = {
                "Tecra M3,",
@@ -1166,6 +1181,41 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev,
        hpriv->map = map;
 }
 
+static void piix_iocfg_bit18_quirk(struct pci_dev *pdev)
+{
+       static const struct dmi_system_id sysids[] = {
+               {
+                       /* Clevo M570U sets IOCFG bit 18 if the cdrom
+                        * isn't used to boot the system which
+                        * disables the channel.
+                        */
+                       .ident = "M570U",
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "Clevo Co."),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "M570U"),
+                       },
+               },
+
+               { }     /* terminate list */
+       };
+       u32 iocfg;
+
+       if (!dmi_check_system(sysids))
+               return;
+
+       /* The datasheet says that bit 18 is NOOP but certain systems
+        * seem to use it to disable a channel.  Clear the bit on the
+        * affected systems.
+        */
+       pci_read_config_dword(pdev, PIIX_IOCFG, &iocfg);
+       if (iocfg & (1 << 18)) {
+               dev_printk(KERN_INFO, &pdev->dev,
+                          "applying IOCFG bit18 quirk\n");
+               iocfg &= ~(1 << 18);
+               pci_write_config_dword(pdev, PIIX_IOCFG, iocfg);
+       }
+}
+
 /**
  *     piix_init_one - Register PIIX ATA PCI device with kernel services
  *     @pdev: PCI device to register
@@ -1227,6 +1277,9 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                              piix_map_db_table[ent->driver_data]);
        }
 
+       /* apply IOCFG bit18 quirk */
+       piix_iocfg_bit18_quirk(pdev);
+
        /* On ICH5, some BIOSen disable the interrupt using the
         * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.
         * On ICH6, this bit has the same effect, but only when