diff options
author | jhb <jhb@FreeBSD.org> | 2015-02-06 16:09:01 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2015-02-06 16:09:01 +0000 |
commit | 571edab7e40427c587347cfdc33ac92bd143836b (patch) | |
tree | c5571a1caff25473e47bc9c6a9b8b5a332646e70 /sys/dev/acpica/acpi.c | |
parent | 51c4218ae3eb8613bc33e463e0d5a7546b667f5a (diff) | |
download | FreeBSD-src-571edab7e40427c587347cfdc33ac92bd143836b.zip FreeBSD-src-571edab7e40427c587347cfdc33ac92bd143836b.tar.gz |
Add a new device control utility for new-bus devices called devctl. This
allows the user to request administrative changes to individual devices
such as attach or detaching drivers or disabling and re-enabling devices.
- Add a new /dev/devctl2 character device which uses ioctls for device
requests. The ioctls use a common 'struct devreq' which is somewhat
similar to 'struct ifreq'.
- The ioctls identify the device to operate on via a string. This
string can either by the device's name, or it can be a bus-specific
address. (For unattached devices, a bus address is the only way to
locate a device.) Bus drivers register an eventhandler to claim
unrecognized device names that the driver recognizes as a valid address.
Two buses currently support addresses: ACPI recognizes any device
in the ACPI namespace via its full path starting with "\" and
the PCI bus driver recognizes an address specification of
'pci[<domain>:]<bus>:<slot>:<func>' (identical to the PCI selector
strings supported by pciconf).
- To make it easier to cut and paste, change the PnP location string
in the PCI bus driver to output a full PCI selector string rather
than 'slot=<slot> function=<func>'.
- Add a devctl(3) interface in libdevctl which provides a wrapper around
the ioctls and is the preferred interface for other userland code.
- Add a devctl(8) program which is a simple wrapper around the requests
supported by devctl(3).
- Add a device_is_suspended() function to check DF_SUSPENDED.
- Add a resource_unset_value() function that can be used to remove a
hint from the kernel environment. This is used to clear a
hint.<driver>.<unit>.disabled hint when re-enabling a boot-time
disabled device.
Reviewed by: imp (parts)
Requested by: imp (changing PCI location string)
Relnotes: yes
Diffstat (limited to 'sys/dev/acpica/acpi.c')
-rw-r--r-- | sys/dev/acpica/acpi.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index a4732c4..bf2cc54 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -101,6 +101,7 @@ int acpi_quirks; /* Supported sleep states. */ static BOOLEAN acpi_sleep_states[ACPI_S_STATE_COUNT]; +static void acpi_lookup(void *arg, const char *name, device_t *dev); static int acpi_modevent(struct module *mod, int event, void *junk); static int acpi_probe(device_t dev); static int acpi_attach(device_t dev); @@ -671,8 +672,10 @@ acpi_attach(device_t dev) /* Register ACPI again to pass the correct argument of pm_func. */ power_pm_register(POWER_PM_TYPE_ACPI, acpi_pm_func, sc); - if (!acpi_disabled("bus")) + if (!acpi_disabled("bus")) { + EVENTHANDLER_REGISTER(dev_lookup, acpi_lookup, NULL, 1000); acpi_probe_children(dev); + } /* Update all GPEs and enable runtime GPEs. */ status = AcpiUpdateAllGpes(); @@ -3401,6 +3404,31 @@ acpi_disabled(char *subsys) return (0); } +static void +acpi_lookup(void *arg, const char *name, device_t *dev) +{ + ACPI_HANDLE handle; + + if (*dev != NULL) + return; + + /* + * Allow any handle name that is specified as an absolute path and + * starts with '\'. We could restrict this to \_SB and friends, + * but see acpi_probe_children() for notes on why we scan the entire + * namespace for devices. + * + * XXX: The pathname argument to AcpiGetHandle() should be fixed to + * be const. + */ + if (name[0] != '\\') + return; + if (ACPI_FAILURE(AcpiGetHandle(ACPI_ROOT_OBJECT, __DECONST(char *, name), + &handle))) + return; + *dev = acpi_get_device(handle); +} + /* * Control interface. * |