[PATCH] pata_jmicron: fix JMB368 support, add suspend/resume handling
Alan [Wed, 22 Nov 2006 17:18:30 +0000 (17:18 +0000)]
This (and the pci resume quirk code) get the JMicron controllers to
resume properly. Without this patch the drive mapping changes when you
suspend/resume which is not good at all....

Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

drivers/ata/pata_jmicron.c

index 0210b10..c9f0a54 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/ata.h>
 
 #define DRV_NAME       "pata_jmicron"
-#define DRV_VERSION    "0.1.2"
+#define DRV_VERSION    "0.1.4"
 
 typedef enum {
        PORT_PATA0 = 0,
@@ -213,12 +213,11 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
 
                /* FIXME: We may want a way to override this in future */
                pci_write_config_byte(pdev, 0x41, 0xa1);
-       }
-
-       /* PATA controller is fn 1, AHCI is fn 0 */
-       if (PCI_FUNC(pdev->devfn) != 1)
-               return -ENODEV;
 
+               /* PATA controller is fn 1, AHCI is fn 0 */
+               if (PCI_FUNC(pdev->devfn) != 1)
+                       return -ENODEV;
+       }
        if ( id->driver_data == 365 || id->driver_data == 366) {
                /* The 365/66 have two PATA channels, redirect the second */
                pci_read_config_dword(pdev, 0x80, &reg);
@@ -229,6 +228,27 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
        return ata_pci_init_one(pdev, port_info, 2);
 }
 
+static int jmicron_reinit_one(struct pci_dev *pdev)
+{
+       u32 reg;
+       
+       switch(pdev->device) {
+               case PCI_DEVICE_ID_JMICRON_JMB368:
+                       break;
+               case PCI_DEVICE_ID_JMICRON_JMB365:
+               case PCI_DEVICE_ID_JMICRON_JMB366:
+                       /* Restore mapping or disks swap and boy does it get ugly */
+                       pci_read_config_dword(pdev, 0x80, &reg);
+                       reg |= (1 << 24);       /* IDE1 to PATA IDE secondary */
+                       pci_write_config_dword(pdev, 0x80, reg);
+                       /* Fall through */
+               default:
+                       /* Make sure AHCI is turned back on */
+                       pci_write_config_byte(pdev, 0x41, 0xa1);
+       }
+       return ata_pci_device_resume(pdev);
+}
+
 static const struct pci_device_id jmicron_pci_tbl[] = {
        { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361},
        { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363},
@@ -244,6 +264,8 @@ static struct pci_driver jmicron_pci_driver = {
        .id_table               = jmicron_pci_tbl,
        .probe                  = jmicron_init_one,
        .remove                 = ata_pci_remove_one,
+       .suspend                = ata_pci_device_suspend,
+       .resume                 = jmicron_reinit_one,
 };
 
 static int __init jmicron_init(void)