diff options
author | hselasky <hselasky@FreeBSD.org> | 2013-05-03 07:44:58 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2013-05-03 07:44:58 +0000 |
commit | b7fe9e8c88a6ebaed1f12f93bed79ac371986463 (patch) | |
tree | bae81f1e85342c7dae2df723f345aafb486ea339 /sys/dev/usb/usb_generic.c | |
parent | 94808df525c90765b05fb81ccdba2e49721b5e97 (diff) | |
download | FreeBSD-src-b7fe9e8c88a6ebaed1f12f93bed79ac371986463.zip FreeBSD-src-b7fe9e8c88a6ebaed1f12f93bed79ac371986463.tar.gz |
Add new USB API to get the port path of a USB device.
MFC after: 2 weeks
Requested by: emaste @
Diffstat (limited to 'sys/dev/usb/usb_generic.c')
-rw-r--r-- | sys/dev/usb/usb_generic.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c index 9557686..013210a 100644 --- a/sys/dev/usb/usb_generic.c +++ b/sys/dev/usb/usb_generic.c @@ -1841,6 +1841,46 @@ ugen_get_power_mode(struct usb_fifo *f) } static int +ugen_get_port_path(struct usb_fifo *f, struct usb_device_port_path *dpp) +{ + struct usb_device *udev = f->udev; + struct usb_device *next; + unsigned int nlevel = 0; + + if (udev == NULL) + goto error; + + dpp->udp_bus = device_get_unit(udev->bus->bdev); + dpp->udp_index = udev->device_index; + + /* count port levels */ + next = udev; + while (next->parent_hub != NULL) { + nlevel++; + next = next->parent_hub; + } + + /* check if too many levels */ + if (nlevel > USB_DEVICE_PORT_PATH_MAX) + goto error; + + /* store port index array */ + next = udev; + while (next->parent_hub != NULL) { + nlevel--; + + dpp->udp_port_no[nlevel] = next->port_no; + dpp->udp_port_level = nlevel; + + next = next->parent_hub; + } + return (0); /* success */ + +error: + return (EINVAL); /* failure */ +} + +static int ugen_get_power_usage(struct usb_fifo *f) { struct usb_device *udev = f->udev; @@ -2041,6 +2081,7 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags) struct usb_device_stats *stat; struct usb_fs_init *pinit; struct usb_fs_uninit *puninit; + struct usb_device_port_path *dpp; uint32_t *ptime; void *addr; int *pint; @@ -2213,6 +2254,10 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags) *u.pint = ugen_get_power_mode(f); break; + case USB_GET_DEV_PORT_PATH: + error = ugen_get_port_path(f, u.dpp); + break; + case USB_GET_POWER_USAGE: *u.pint = ugen_get_power_usage(f); break; |