From owner-freebsd-arch@FreeBSD.ORG Thu Mar 27 20:23:35 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 1B7FC1065673; Thu, 27 Mar 2008 20:23:35 +0000 (UTC) (envelope-from imp@bsdimp.com) Received: from harmony.bsdimp.com (bsdimp.com [199.45.160.85]) by mx1.freebsd.org (Postfix) with ESMTP id C12DA8FC2B; Thu, 27 Mar 2008 20:23:34 +0000 (UTC) (envelope-from imp@bsdimp.com) Received: from localhost (localhost [127.0.0.1]) by harmony.bsdimp.com (8.14.2/8.14.1) with ESMTP id m2RKKBRd050067; Thu, 27 Mar 2008 14:20:12 -0600 (MDT) (envelope-from imp@bsdimp.com) Date: Thu, 27 Mar 2008 14:20:52 -0600 (MDT) Message-Id: <20080327.142052.-1337017421.imp@bsdimp.com> To: jhb@freebsd.org From: "M. Warner Losh" In-Reply-To: <200803271105.18401.jhb@freebsd.org> References: <20080327.013229.1649766744.imp@bsdimp.com> <200803271105.18401.jhb@freebsd.org> X-Mailer: Mew version 5.2 on Emacs 21.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Cc: freebsd-arch@freebsd.org 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:23:35 -0000 In message: <200803271105.18401.jhb@freebsd.org> John Baldwin writes: : 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 Wow, you have a lot of comments for a simple test program :-) : 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. True. I was going to implement this next as a bus method to have the bus to the right 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) I'm not sure I like this at all. This is about completely suspending a device, or completely resuming the device for testing purposes. Randomly putting the device into D1 state is a bad idea. The device driver itself should do that level of detail. : 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). I'll leave that for someone else to implement :-). : 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.) Wow! that's a lot more complicated than I had in mind :-) Warner