attempt to fix suspend/resume of AHCI SATA
Andrea Bittau
a.bittau at cs.ucl.ac.uk
Wed Mar 28 13:02:41 UTC 2007
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
@@ -49,6 +49,7 @@ __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;
@@ -293,11 +294,16 @@ 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
@@ -286,6 +286,11 @@ 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);
@@ -304,6 +309,7 @@ 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
@@ -251,6 +251,19 @@ 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)
@@ -510,7 +523,7 @@ 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),
More information about the freebsd-current
mailing list