pata_via: Handle laptops via DMI
[sfrench/cifs-2.6.git] / drivers / ata / pata_via.c
index 96b71791d2f48edc8109d606a7a7d76c074df51b..708dfc0c716b3fb34dfc717f60731cb6e064c7dc 100644 (file)
@@ -60,6 +60,7 @@
 #include <linux/delay.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
+#include <linux/dmi.h>
 
 #define DRV_NAME "pata_via"
 #define DRV_VERSION "0.3.1"
@@ -122,6 +123,31 @@ static const struct via_isa_bridge {
        { NULL }
 };
 
+
+/*
+ *     Cable special cases
+ */
+
+static struct dmi_system_id cable_dmi_table[] = {
+       {
+               .ident = "Acer Ferrari 3400",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Acer,Inc."),
+                       DMI_MATCH(DMI_BOARD_NAME, "Ferrari 3400"),
+               },
+       },
+       { }
+};
+
+static int via_cable_override(struct pci_dev *pdev)
+{
+       /* Systems by DMI */
+       if (dmi_check_system(cable_dmi_table))
+               return 1;
+       return 0;
+}
+
+
 /**
  *     via_cable_detect        -       cable detection
  *     @ap: ATA port
@@ -139,6 +165,9 @@ static int via_cable_detect(struct ata_port *ap) {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u32 ata66;
 
+       if (via_cable_override(pdev))
+               return ATA_CBL_PATA40_SHORT;
+
        /* Early chips are 40 wire */
        if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
                return ATA_CBL_PATA40;
@@ -154,7 +183,7 @@ static int via_cable_detect(struct ata_port *ap) {
        return ATA_CBL_PATA40;
 }
 
-static int via_pre_reset(struct ata_port *ap)
+static int via_pre_reset(struct ata_port *ap, unsigned long deadline)
 {
        const struct via_isa_bridge *config = ap->host->private_data;
 
@@ -167,7 +196,8 @@ static int via_pre_reset(struct ata_port *ap)
                if (!pci_test_config_bits(pdev, &via_enable_bits[ap->port_no]))
                        return -ENOENT;
        }
-       return ata_std_prereset(ap);
+
+       return ata_std_prereset(ap, deadline);
 }
 
 
@@ -300,10 +330,6 @@ static struct scsi_host_template via_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations via_port_ops = {
@@ -424,7 +450,7 @@ static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
 static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        /* Early VIA without UDMA support */
-       static struct ata_port_info via_mwdma_info = {
+       static const struct ata_port_info via_mwdma_info = {
                .sht = &via_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
                .pio_mask = 0x1f,
@@ -432,7 +458,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &via_port_ops
        };
        /* Ditto with IRQ masking required */
-       static struct ata_port_info via_mwdma_info_borked = {
+       static const struct ata_port_info via_mwdma_info_borked = {
                .sht = &via_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
                .pio_mask = 0x1f,
@@ -440,7 +466,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &via_port_ops_noirq,
        };
        /* VIA UDMA 33 devices (and borked 66) */
-       static struct ata_port_info via_udma33_info = {
+       static const struct ata_port_info via_udma33_info = {
                .sht = &via_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
                .pio_mask = 0x1f,
@@ -449,7 +475,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &via_port_ops
        };
        /* VIA UDMA 66 devices */
-       static struct ata_port_info via_udma66_info = {
+       static const struct ata_port_info via_udma66_info = {
                .sht = &via_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
                .pio_mask = 0x1f,
@@ -458,7 +484,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &via_port_ops
        };
        /* VIA UDMA 100 devices */
-       static struct ata_port_info via_udma100_info = {
+       static const struct ata_port_info via_udma100_info = {
                .sht = &via_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
                .pio_mask = 0x1f,
@@ -467,7 +493,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &via_port_ops
        };
        /* UDMA133 with bad AST (All current 133) */
-       static struct ata_port_info via_udma133_info = {
+       static const struct ata_port_info via_udma133_info = {
                .sht = &via_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
                .pio_mask = 0x1f,
@@ -475,7 +501,8 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .udma_mask = 0x7f,      /* FIXME: should check north bridge */
                .port_ops = &via_port_ops
        };
-       struct ata_port_info *port_info[2], *type;
+       struct ata_port_info type;
+       const struct ata_port_info *ppi[] = { &type, NULL };
        struct pci_dev *isa = NULL;
        const struct via_isa_bridge *config;
        static int printed_version;
@@ -520,25 +547,25 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        switch(config->flags & VIA_UDMA) {
                case VIA_UDMA_NONE:
                        if (config->flags & VIA_NO_UNMASK)
-                               type = &via_mwdma_info_borked;
+                               type = via_mwdma_info_borked;
                        else
-                               type = &via_mwdma_info;
+                               type = via_mwdma_info;
                        break;
                case VIA_UDMA_33:
-                       type = &via_udma33_info;
+                       type = via_udma33_info;
                        break;
                case VIA_UDMA_66:
-                       type = &via_udma66_info;
+                       type = via_udma66_info;
                        /* The 66 MHz devices require we enable the clock */
                        pci_read_config_dword(pdev, 0x50, &timing);
                        timing |= 0x80008;
                        pci_write_config_dword(pdev, 0x50, timing);
                        break;
                case VIA_UDMA_100:
-                       type = &via_udma100_info;
+                       type = via_udma100_info;
                        break;
                case VIA_UDMA_133:
-                       type = &via_udma133_info;
+                       type = via_udma133_info;
                        break;
                default:
                        WARN_ON(1);
@@ -553,10 +580,9 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        }
 
        /* We have established the device type, now fire it up */
-       type->private_data = (void *)config;
+       type.private_data = (void *)config;
 
-       port_info[0] = port_info[1] = type;
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 #ifdef CONFIG_PM