]> err.no Git - linux-2.6/blobdiff - drivers/ata/ata_piix.c
V4L/DVB (7849): cx88: fix Kconfig depencencies for FW_LOADER
[linux-2.6] / drivers / ata / ata_piix.c
index e113f2f802756eaca17d481e1feb5f6ccf09053b..a9027b8fbdd53fbb7ea3e2b6257a84924375b9f3 100644 (file)
@@ -165,8 +165,6 @@ static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev);
 static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev);
 static int ich_pata_cable_detect(struct ata_port *ap);
 static u8 piix_vmw_bmdma_status(struct ata_port *ap);
-static int piix_sidpr_hardreset(struct ata_link *link, unsigned int *class,
-                               unsigned long deadline);
 static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val);
 static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val);
 #ifdef CONFIG_PM
@@ -319,7 +317,7 @@ static struct ata_port_operations piix_sata_ops = {
 
 static struct ata_port_operations piix_sidpr_sata_ops = {
        .inherits               = &piix_sata_ops,
-       .hardreset              = piix_sidpr_hardreset,
+       .hardreset              = sata_std_hardreset,
        .scr_read               = piix_sidpr_scr_read,
        .scr_write              = piix_sidpr_scr_write,
 };
@@ -575,6 +573,7 @@ static const struct ich_laptop ich_laptop[] = {
        { 0x27DF, 0x1043, 0x1267 },     /* ICH7 on Asus W5F */
        { 0x27DF, 0x103C, 0x30A1 },     /* ICH7 on HP Compaq nc2400 */
        { 0x24CA, 0x1025, 0x0061 },     /* ICH4 on ACER Aspire 2023WLMi */
+       { 0x2653, 0x1043, 0x82D8 },     /* ICH6M on Asus Eee 701 */
        /* end marker */
        { 0, }
 };
@@ -629,7 +628,7 @@ static int piix_pata_prereset(struct ata_link *link, unsigned long deadline)
 
        if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
                return -ENOENT;
-       return ata_std_prereset(link, deadline);
+       return ata_sff_prereset(link, deadline);
 }
 
 /**
@@ -1015,29 +1014,6 @@ static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val)
        return 0;
 }
 
-static int piix_sidpr_hardreset(struct ata_link *link, unsigned int *class,
-                               unsigned long deadline)
-{
-       const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
-       int rc;
-
-       /* do hardreset */
-       rc = sata_link_hardreset(link, timing, deadline);
-       if (rc) {
-               ata_link_printk(link, KERN_ERR,
-                               "COMRESET failed (errno=%d)\n", rc);
-               return rc;
-       }
-
-       /* TODO: phy layer with polling, timeouts, etc. */
-       if (ata_link_offline(link)) {
-               *class = ATA_DEV_NONE;
-               return 0;
-       }
-
-       return -EAGAIN;
-}
-
 #ifdef CONFIG_PM
 static int piix_broken_suspend(void)
 {
@@ -1372,6 +1348,8 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
 {
        struct pci_dev *pdev = to_pci_dev(host->dev);
        struct piix_host_priv *hpriv = host->private_data;
+       struct ata_device *dev0 = &host->ports[0]->link.device[0];
+       u32 scontrol;
        int i;
 
        /* check for availability */
@@ -1390,6 +1368,29 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
                return;
 
        hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
+
+       /* SCR access via SIDPR doesn't work on some configurations.
+        * Give it a test drive by inhibiting power save modes which
+        * we'll do anyway.
+        */
+       scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
+
+       /* if IPM is already 3, SCR access is probably working.  Don't
+        * un-inhibit power save modes as BIOS might have inhibited
+        * them for a reason.
+        */
+       if ((scontrol & 0xf00) != 0x300) {
+               scontrol |= 0x300;
+               piix_sidpr_write(dev0, SCR_CONTROL, scontrol);
+               scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
+
+               if ((scontrol & 0xf00) != 0x300) {
+                       dev_printk(KERN_INFO, host->dev, "SCR access via "
+                                  "SIDPR is available but doesn't work\n");
+                       return;
+               }
+       }
+
        host->ports[0]->ops = &piix_sidpr_sata_ops;
        host->ports[1]->ops = &piix_sidpr_sata_ops;
 }
@@ -1493,7 +1494,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
                hpriv->map = piix_init_sata_map(pdev, port_info,
                                        piix_map_db_table[ent->driver_data]);
 
-       rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
+       rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
        if (rc)
                return rc;
        host->private_data = hpriv;
@@ -1527,7 +1528,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
        }
 
        pci_set_master(pdev);
-       return ata_pci_activate_sff_host(host, ata_interrupt, &piix_sht);
+       return ata_pci_sff_activate_host(host, ata_sff_interrupt, &piix_sht);
 }
 
 static int __init piix_init(void)