attempt to fix suspend/resume of AHCI SATA

From: Andrea Bittau <a.bittau_at_cs.ucl.ac.uk>
Date: Wed, 28 Mar 2007 13:55:42 +0100
I have a rough patch for fixing suspend/resume of AHCI SATA.  Perhaps someone
with more knowledge could write a proper patch.  In short, this needs fixing:

1) Restore controller registers
2) Restore channel registers
3) Do-not reattach stuff [e.g. HDD] when receiving a phy-change/attach interrupt
   on resume.

---

Index: ata-all.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/ata-all.c,v
retrieving revision 1.279
diff -u -p -r1.279 ata-all.c
--- ata-all.c	23 Feb 2007 16:25:08 -0000	1.279
+++ ata-all.c	28 Mar 2007 12:55:03 -0000
_at__at_ -49,6 +49,7 _at__at_ __FBSDID("$FreeBSD: src/sys/dev/ata/ata-
 #include <sys/rman.h>
 #include <dev/ata/ata-all.h>
 #include <ata_if.h>
+#include <dev/ata/ata-pci.h>
 
 /* device structure */
 static  d_ioctl_t       ata_ioctl;
_at__at_ -293,11 +294,16 _at__at_ int
 ata_resume(device_t dev)
 {
     struct ata_channel *ch;
+    struct ata_pci_controller *ctlr;
     int error;
 
     /* check for valid device */
     if (!dev || !(ch = device_get_softc(dev)))
 	return ENXIO;
+
+    ctlr = device_get_softc(device_get_parent(dev));
+    if ((error = ctlr->allocate(dev)))
+    	return error;
 
     /* reinit the devices, we dont know what mode/state they are in */
     error = ata_reinit(dev);
Index: ata-chipset.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/ata-chipset.c,v
retrieving revision 1.192
diff -u -p -r1.192 ata-chipset.c
--- ata-chipset.c	12 Mar 2007 15:34:08 -0000	1.192
+++ ata-chipset.c	28 Mar 2007 12:55:05 -0000
_at__at_ -286,6 +286,11 _at__at_ ata_sata_phy_event(void *context, int du
 
     mtx_lock(&Giant);   /* newbus suckage it needs Giant */
     if (tp->action == ATA_C_ATTACH) {
+    	/* XXX */
+        if (!device_get_children(tp->dev, &children, &nchildren)) {
+		device_printf(tp->dev, "Assuming resume attach skipped\n");
+		goto out;
+	}
 	if (bootverbose)
 	    device_printf(tp->dev, "CONNECTED\n");
 	ATA_RESET(tp->dev);
_at__at_ -304,6 +309,7 _at__at_ ata_sata_phy_event(void *context, int du
 	if (bootverbose)
 	    device_printf(tp->dev, "DISCONNECTED\n");
     }
+out:
     mtx_unlock(&Giant); /* suckage code dealt with, release Giant */
     free(tp, M_ATA);
 }
Index: ata-pci.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/ata-pci.c,v
retrieving revision 1.121
diff -u -p -r1.121 ata-pci.c
--- ata-pci.c	23 Feb 2007 12:18:33 -0000	1.121
+++ ata-pci.c	28 Mar 2007 12:55:05 -0000
_at__at_ -251,6 +251,19 _at__at_ ata_pci_detach(device_t dev)
     return 0;
 }
 
+static int
+ata_pci_resume(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(dev);
+    int rc;
+
+    rc = ctlr->chipinit(dev);
+    if (rc)
+    	return rc;
+
+    return bus_generic_resume(dev);
+}
+
 struct resource *
 ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
 		       u_long start, u_long end, u_long count, u_int flags)
_at__at_ -510,7 +523,7 _at__at_ static device_method_t ata_pci_methods[]
     DEVMETHOD(device_detach,            ata_pci_detach),
     DEVMETHOD(device_shutdown,          bus_generic_shutdown),
     DEVMETHOD(device_suspend,           bus_generic_suspend),
-    DEVMETHOD(device_resume,            bus_generic_resume),
+    DEVMETHOD(device_resume,            ata_pci_resume),
 
     /* bus methods */
     DEVMETHOD(bus_alloc_resource,       ata_pci_alloc_resource),
Received on Wed Mar 28 2007 - 11:02:41 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:07 UTC