From owner-freebsd-current@FreeBSD.ORG Wed Mar 28 13:02:41 2007 Return-Path: X-Original-To: freebsd-current@freebsd.org Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 941DE16A404; Wed, 28 Mar 2007 13:02:41 +0000 (UTC) (envelope-from a.bittau@cs.ucl.ac.uk) Received: from darkircop.org (tapir.cs.ucl.ac.uk [128.16.66.93]) by mx1.freebsd.org (Postfix) with ESMTP id 4BB4913C4BB; Wed, 28 Mar 2007 13:02:41 +0000 (UTC) (envelope-from a.bittau@cs.ucl.ac.uk) Received: by darkircop.org (Postfix, from userid 0) id B83C46EFB6; Wed, 28 Mar 2007 13:55:42 +0100 (BST) Date: Wed, 28 Mar 2007 13:55:42 +0100 From: Andrea Bittau To: freebsd-current@freebsd.org Message-ID: <20070328125542.GA5457@shorty.sorbonet.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.1i X-Echelon: Bush Bomb War KGB X-Mailman-Approved-At: Wed, 28 Mar 2007 13:55:32 +0000 Cc: sos@freebsd.org Subject: attempt to fix suspend/resume of AHCI SATA X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Mar 2007 13:02:41 -0000 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 #include #include +#include /* 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),