summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usb_generic.c
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2013-05-03 07:44:58 +0000
committerhselasky <hselasky@FreeBSD.org>2013-05-03 07:44:58 +0000
commitb7fe9e8c88a6ebaed1f12f93bed79ac371986463 (patch)
treebae81f1e85342c7dae2df723f345aafb486ea339 /sys/dev/usb/usb_generic.c
parent94808df525c90765b05fb81ccdba2e49721b5e97 (diff)
downloadFreeBSD-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.c45
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;
OpenPOWER on IntegriCloud