Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Mar 2008 14:20:52 -0600 (MDT)
From:      "M. Warner Losh" <imp@bsdimp.com>
To:        jhb@freebsd.org
Cc:        freebsd-arch@freebsd.org
Subject:   Re: AsiaBSDCon DEVSUMMIT patch
Message-ID:  <20080327.142052.-1337017421.imp@bsdimp.com>
In-Reply-To: <200803271105.18401.jhb@freebsd.org>
References:  <20080327.013229.1649766744.imp@bsdimp.com> <200803271105.18401.jhb@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
In message: <200803271105.18401.jhb@freebsd.org>
            John Baldwin <jhb@freebsd.org> 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 <device> <state>");
: 	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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080327.142052.-1337017421.imp>