From owner-freebsd-arch@FreeBSD.ORG Thu Mar 27 20:00:57 2008 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EEAF81065672 for ; Thu, 27 Mar 2008 20:00:57 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from speedfactory.net (mail.speedfactory.net [66.23.216.219]) by mx1.freebsd.org (Postfix) with ESMTP id 8EC0A8FC22 for ; Thu, 27 Mar 2008 20:00:57 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from server.baldwin.cx (unverified [66.23.211.162]) by speedfactory.net (SurgeMail 3.8s) with ESMTP id 236963333-1834499 for multiple; Thu, 27 Mar 2008 15:59:33 -0400 Received: from localhost.corp.yahoo.com (john@localhost [127.0.0.1]) (authenticated bits=0) by server.baldwin.cx (8.14.2/8.14.2) with ESMTP id m2RK0aAb005153; Thu, 27 Mar 2008 16:00:39 -0400 (EDT) (envelope-from jhb@freebsd.org) From: John Baldwin To: freebsd-arch@freebsd.org Date: Thu, 27 Mar 2008 11:05:18 -0400 User-Agent: KMail/1.9.7 References: <20080327.013229.1649766744.imp@bsdimp.com> In-Reply-To: <20080327.013229.1649766744.imp@bsdimp.com> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200803271105.18401.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH authentication, not delayed by milter-greylist-2.0.2 (server.baldwin.cx [127.0.0.1]); Thu, 27 Mar 2008 16:00:40 -0400 (EDT) X-Virus-Scanned: ClamAV 0.91.2/6430/Thu Mar 27 13:39:43 2008 on server.baldwin.cx X-Virus-Status: Clean X-Spam-Status: No, score=-4.1 required=4.2 tests=ALL_TRUSTED,AWL,BAYES_00, DATE_IN_PAST_03_06 autolearn=ham version=3.1.3 X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on server.baldwin.cx Cc: Subject: Re: AsiaBSDCon DEVSUMMIT patch X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Mar 2008 20:00:58 -0000 On Thursday 27 March 2008 03:32:29 am M. Warner Losh wrote: > Greetings, > > We've been talking about the situation with suspend/resume in the > tree. Here's a quick hack to allow one to suspend/resume an > individual device. This may or may not work too well, but it is > offered up for testing and criticism. > > http://people.freebsd.org/~imp/devctl.diff > > devctl -s ath 0 suspend ath0 > devctl -r ath 0 resume ath0 Unfortunately, what you really need is to power down the device to D3 for suspend and then bring it up. Otherwise you might not lose enough state to notice that resume isn't restoring all of it. bge(4) doesn't survive resume on my laptop I think because brgphy doesn't re-patch the firmware on resume, and you'd need a full power down to run into that sort of thing. What I would actually prefer would be this: devctl ath0 power off (maps to D3 on PCI/ACPI) devctl ath0 power D1 (PCI/ACPI-specific) devctl ath0 power on (maps to D0 on PCI/APCI) You'd probably need a 'int BUS_SET_POWERSTATE(device_t parent, device_t child, const char *state)' and implement it for ACPI and PCI. You would then have the ioctl handler do: /* copy in state string */ /* lookup device */ error = BUS_SET_POWERSTATE(device_get_parent(device), device, state); I would also make devctl take a plain device name and figure out the devclass/unit from that. Either that or pass the device name as a string to the kernel and have it do a lookup (for a userland ioctl I don't think an O(n) walk over the device list is all that evil). If you want to do named commands (like 'power') rather than getopt args for everything you can use a linker set to build a table of commands (I've done this for RAID management utils at work) that let you do something like: struct devctl_power_request { const char device[MAXDEVNAME]; const char state[32]; } #define DEVIOC_POWER _IOW('d', 1, struct devctl_power_request) /* av[0] will be 'power' */ static void power_command(int ac, char **av) { struct devctl_power_request req; if (ac != 3) errx(1, "Usage: devctl power "); strlcpy(req.device, av[1], sizeof(req.device)); strlcpy(req.state, av[2], sizeof(req.state)); if (ioctl(fd, DEVIOC_POWER, &req) < 0) err(1, "Set power state failed"); } DEVCTL_COMMAND(power); (Using a linker set makes it easier to add new commands later and have them all be self-contained.) -- John Baldwin