From owner-p4-projects@FreeBSD.ORG Sat Feb 14 15:57:51 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5EAF31065673; Sat, 14 Feb 2009 15:57:50 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1A8E61065670 for ; Sat, 14 Feb 2009 15:57:50 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 06D418FC1E for ; Sat, 14 Feb 2009 15:57:50 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n1EFvn1K096082 for ; Sat, 14 Feb 2009 15:57:49 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n1EFvnFR096080 for perforce@freebsd.org; Sat, 14 Feb 2009 15:57:49 GMT (envelope-from hselasky@FreeBSD.org) Date: Sat, 14 Feb 2009 15:57:49 GMT Message-Id: <200902141557.n1EFvnFR096080@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 157699 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 Feb 2009 15:57:51 -0000 http://perforce.freebsd.org/chv.cgi?CH=157699 Change 157699 by hselasky@hselasky_laptop001 on 2009/02/14 15:57:12 Add two new functions to the libusb20 API and required kernel ioctls. - libusb20_dev_get_iface_desc - libusb20_dev_get_info New command to usbconfig, "show_ifdrv", which will print out the kernel driver attached to the given USB device aswell. See "man libusb20" for a detailed description. Some minor style corrections long-line wrapping. Requested by: Joe Marcus Clarke Affected files ... .. //depot/projects/usb/src/lib/libusb20/libusb20.3#6 edit .. //depot/projects/usb/src/lib/libusb20/libusb20.c#14 edit .. //depot/projects/usb/src/lib/libusb20/libusb20.h#10 edit .. //depot/projects/usb/src/lib/libusb20/libusb20_int.h#7 edit .. //depot/projects/usb/src/lib/libusb20/libusb20_ugen20.c#13 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#43 edit .. //depot/projects/usb/src/sys/dev/usb2/include/usb2_ioctl.h#29 edit .. //depot/projects/usb/src/usr.sbin/usbconfig/dump.c#10 edit .. //depot/projects/usb/src/usr.sbin/usbconfig/dump.h#5 edit .. //depot/projects/usb/src/usr.sbin/usbconfig/usbconfig.c#12 edit Differences ... ==== //depot/projects/usb/src/lib/libusb20/libusb20.3#6 (text+ko) ==== @@ -26,7 +26,7 @@ .\" .\" $FreeBSD: src/lib/libusb20/libusb20.3,v 1.1 2008/11/04 02:31:03 alfred Exp $ .\" -.Dd Oct 23, 2008 +.Dd Feb 14, 2009 .Dt LIBUSB20 3 .Os .Sh NAME @@ -308,8 +308,32 @@ . .Pp . +.Fn libusb20_dev_get_info pdev pinfo +This function retrives the BSD specific usb2_device_info structure into the memory location given by +.Fa pinfo . +The USB device given by +.Fa pdev +must be opened before this function will succeed. +This function returns zero on success else a LIBUSB20_ERROR value is returned. +. +.Pp +. +.Fn libusb20_dev_get_iface_desc pdev iface_index pbuf len +This function retrieves the kernel interface description for the given USB +.Fa iface_index . +The format of the USB interface description is: "drivername: " +The description string is always zero terminated. +A zero length string is written in case no driver is attached to the given interface. +The USB device given by +.Fa pdev +must be opened before this function will succeed. +This function returns zero on success else a LIBUSB20_ERROR value is returned. +. +.Pp +. .Fn libusb20_dev_get_desc pdev This function returns a zero terminated string describing the given USB device. +The format of the string is: "drivername: " . .Pp . ==== //depot/projects/usb/src/lib/libusb20/libusb20.c#14 (text+ko) ==== @@ -78,6 +78,8 @@ #define dummy_tr_close (void *)dummy_int #define dummy_tr_clear_stall_sync (void *)dummy_int #define dummy_process (void *)dummy_int +#define dummy_dev_info (void *)dummy_int +#define dummy_dev_get_iface_driver (void *)dummy_int #define dummy_tr_submit (void *)dummy_void #define dummy_tr_cancel_async (void *)dummy_void @@ -99,7 +101,7 @@ xfer->is_pending = 0; } - (xfer->callback) (xfer); + xfer->callback(xfer); if (xfer->is_restart) { xfer->is_restart = 0; @@ -109,7 +111,7 @@ (!xfer->is_pending)) { xfer->is_draining = 0; xfer->status = LIBUSB20_TRANSFER_DRAINED; - (xfer->callback) (xfer); + xfer->callback(xfer); } return; } @@ -122,7 +124,7 @@ if (!xfer->is_opened) { return (LIBUSB20_ERROR_OTHER); } - error = (xfer->pdev->methods->tr_close) (xfer); + error = xfer->pdev->methods->tr_close(xfer); if (xfer->pLength) { free(xfer->pLength); @@ -168,7 +170,7 @@ } memset(xfer->ppBuffer, 0, size); - error = (xfer->pdev->methods->tr_open) (xfer, MaxBufSize, + error = xfer->pdev->methods->tr_open(xfer, MaxBufSize, MaxFrameCount, ep_no); if (error) { @@ -273,7 +275,7 @@ } xfer->is_cancel = 1; /* we are cancelling */ - (xfer->pdev->methods->tr_cancel_async) (xfer); + xfer->pdev->methods->tr_cancel_async(xfer); return; } @@ -292,7 +294,7 @@ void libusb20_tr_clear_stall_sync(struct libusb20_transfer *xfer) { - (xfer->pdev->methods->tr_clear_stall_sync) (xfer); + xfer->pdev->methods->tr_clear_stall_sync(xfer); return; } @@ -420,7 +422,7 @@ xfer->is_cancel = 0; /* not cancelling */ xfer->is_restart = 0; /* not restarting */ - (xfer->pdev->methods->tr_submit) (xfer); + xfer->pdev->methods->tr_submit(xfer); return; } @@ -452,7 +454,7 @@ } else if (pdev->claimed_interfaces & (1 << ifaceIndex)) { error = LIBUSB20_ERROR_NOT_FOUND; } else { - error = (pdev->methods->claim_interface) (pdev, ifaceIndex); + error = pdev->methods->claim_interface(pdev, ifaceIndex); } if (!error) { pdev->claimed_interfaces |= (1 << ifaceIndex); @@ -480,7 +482,7 @@ free(pdev->pTransfer); pdev->pTransfer = NULL; } - error = (pdev->beMethods->close_device) (pdev); + error = pdev->beMethods->close_device(pdev); pdev->methods = &libusb20_dummy_methods; @@ -496,7 +498,7 @@ { int error; - error = (pdev->methods->detach_kernel_driver) (pdev, ifaceIndex); + error = pdev->methods->detach_kernel_driver(pdev, ifaceIndex); return (error); } @@ -517,7 +519,7 @@ { int error; - error = (pdev->methods->kernel_driver_active) (pdev, ifaceIndex); + error = pdev->methods->kernel_driver_active(pdev, ifaceIndex); return (error); } @@ -555,7 +557,7 @@ /* set "nTransfer" early */ pdev->nTransfer = nTransferMax; - error = (pdev->beMethods->open_device) (pdev, nTransferMax); + error = pdev->beMethods->open_device(pdev, nTransferMax); if (error) { if (pdev->pTransfer != NULL) { @@ -581,7 +583,7 @@ } else if (!(pdev->claimed_interfaces & (1 << ifaceIndex))) { error = LIBUSB20_ERROR_NOT_FOUND; } else { - error = (pdev->methods->release_interface) (pdev, ifaceIndex); + error = pdev->methods->release_interface(pdev, ifaceIndex); } if (!error) { pdev->claimed_interfaces &= ~(1 << ifaceIndex); @@ -594,7 +596,7 @@ { int error; - error = (pdev->methods->reset_device) (pdev); + error = pdev->methods->reset_device(pdev); return (error); } @@ -603,7 +605,7 @@ { int error; - error = (pdev->methods->set_power_mode) (pdev, power_mode); + error = pdev->methods->set_power_mode(pdev, power_mode); return (error); } @@ -613,7 +615,7 @@ int error; uint8_t power_mode; - error = (pdev->methods->get_power_mode) (pdev, &power_mode); + error = pdev->methods->get_power_mode(pdev, &power_mode); if (error) power_mode = LIBUSB20_POWER_ON; /* fake power mode */ return (power_mode); @@ -624,7 +626,7 @@ { int error; - error = (pdev->methods->set_alt_index) (pdev, ifaceIndex, altIndex); + error = pdev->methods->set_alt_index(pdev, ifaceIndex, altIndex); return (error); } @@ -633,7 +635,7 @@ { int error; - error = (pdev->methods->set_config_index) (pdev, configIndex); + error = pdev->methods->set_config_index(pdev, configIndex); return (error); } @@ -644,7 +646,7 @@ { int error; - error = (pdev->methods->do_request_sync) (pdev, + error = pdev->methods->do_request_sync(pdev, setup, data, pactlen, timeout, flags); return (error); } @@ -799,7 +801,7 @@ } else { do_close = 0; } - error = (pdev->methods->get_config_desc_full) (pdev, + error = pdev->methods->get_config_desc_full(pdev, &ptr, &len, configIndex); if (error) { @@ -853,7 +855,7 @@ do_close = 0; } - error = (pdev->methods->get_config_index) (pdev, &cfg_index); + error = pdev->methods->get_config_index(pdev, &cfg_index); if (error) { cfg_index = 0 - 1; /* current config index */ } @@ -883,7 +885,7 @@ { int error; - error = (pdev->methods->process) (pdev); + error = pdev->methods->process(pdev); return (error); } @@ -921,10 +923,20 @@ return; } +int +libusb20_dev_get_info(struct libusb20_device *pdev, + struct usb2_device_info *pinfo) +{ + if (pinfo == NULL) + return (LIBUSB20_ERROR_INVALID_PARAM); + + return (pdev->beMethods->dev_get_info(pdev, pinfo)); +} + const char * libusb20_dev_get_backend_name(struct libusb20_device *pdev) { - return ((pdev->beMethods->get_backend_name) ()); + return (pdev->beMethods->get_backend_name()); } const char * @@ -961,25 +973,29 @@ int libusb20_dev_set_owner(struct libusb20_device *pdev, uid_t user, gid_t group) { - return ((pdev->beMethods->dev_set_owner) (pdev, user, group)); + return (pdev->beMethods->dev_set_owner(pdev, user, group)); } int libusb20_dev_set_perm(struct libusb20_device *pdev, mode_t mode) { - return ((pdev->beMethods->dev_set_perm) (pdev, mode)); + return (pdev->beMethods->dev_set_perm(pdev, mode)); } int -libusb20_dev_set_iface_owner(struct libusb20_device *pdev, uint8_t iface_index, uid_t user, gid_t group) +libusb20_dev_set_iface_owner(struct libusb20_device *pdev, + uint8_t iface_index, uid_t user, gid_t group) { - return ((pdev->beMethods->dev_set_iface_owner) (pdev, iface_index, user, group)); + return (pdev->beMethods->dev_set_iface_owner( + pdev, iface_index, user, group)); } int -libusb20_dev_set_iface_perm(struct libusb20_device *pdev, uint8_t iface_index, mode_t mode) +libusb20_dev_set_iface_perm(struct libusb20_device *pdev, + uint8_t iface_index, mode_t mode) { - return ((pdev->beMethods->dev_set_iface_perm) (pdev, iface_index, mode)); + return (pdev->beMethods->dev_set_iface_perm( + pdev, iface_index, mode)); } int @@ -993,7 +1009,7 @@ if (group == NULL) group = &b; - return ((pdev->beMethods->dev_get_owner) (pdev, user, group)); + return (pdev->beMethods->dev_get_owner(pdev, user, group)); } int @@ -1003,11 +1019,12 @@ if (mode == NULL) mode = &a; - return ((pdev->beMethods->dev_get_perm) (pdev, mode)); + return (pdev->beMethods->dev_get_perm(pdev, mode)); } int -libusb20_dev_get_iface_owner(struct libusb20_device *pdev, uint8_t iface_index, uid_t *user, gid_t *group) +libusb20_dev_get_iface_owner(struct libusb20_device *pdev, + uint8_t iface_index, uid_t *user, gid_t *group) { uid_t a; gid_t b; @@ -1017,35 +1034,51 @@ if (group == NULL) group = &b; - return ((pdev->beMethods->dev_get_iface_owner) (pdev, iface_index, user, group)); + return (pdev->beMethods->dev_get_iface_owner( + pdev, iface_index, user, group)); } int -libusb20_dev_get_iface_perm(struct libusb20_device *pdev, uint8_t iface_index, mode_t *mode) +libusb20_dev_get_iface_perm(struct libusb20_device *pdev, + uint8_t iface_index, mode_t *mode) { mode_t a; if (mode == NULL) mode = &a; - return ((pdev->beMethods->dev_get_iface_perm) (pdev, iface_index, mode)); + return (pdev->beMethods->dev_get_iface_perm( + pdev, iface_index, mode)); +} + +int +libusb20_dev_get_iface_desc(struct libusb20_device *pdev, + uint8_t iface_index, char *buf, uint8_t len) +{ + if ((buf == NULL) || (len == 0)) + return (LIBUSB20_ERROR_INVALID_PARAM); + + return (pdev->beMethods->dev_get_iface_desc( + pdev, iface_index, buf, len)); } /* USB bus operations */ int -libusb20_bus_set_owner(struct libusb20_backend *pbe, uint8_t bus, uid_t user, gid_t group) +libusb20_bus_set_owner(struct libusb20_backend *pbe, + uint8_t bus, uid_t user, gid_t group) { - return ((pbe->methods->bus_set_owner) (pbe, bus, user, group)); + return (pbe->methods->bus_set_owner(pbe, bus, user, group)); } int libusb20_bus_set_perm(struct libusb20_backend *pbe, uint8_t bus, mode_t mode) { - return ((pbe->methods->bus_set_perm) (pbe, bus, mode)); + return (pbe->methods->bus_set_perm(pbe, bus, mode)); } int -libusb20_bus_get_owner(struct libusb20_backend *pbe, uint8_t bus, uid_t *user, gid_t *group) +libusb20_bus_get_owner(struct libusb20_backend *pbe, + uint8_t bus, uid_t *user, gid_t *group) { uid_t a; gid_t b; @@ -1054,7 +1087,7 @@ user = &a; if (group == NULL) group = &b; - return ((pbe->methods->bus_get_owner) (pbe, bus, user, group)); + return (pbe->methods->bus_get_owner(pbe, bus, user, group)); } int @@ -1064,7 +1097,7 @@ if (mode == NULL) mode = &a; - return ((pbe->methods->bus_get_perm) (pbe, bus, mode)); + return (pbe->methods->bus_get_perm(pbe, bus, mode)); } /* USB backend operations */ @@ -1073,40 +1106,40 @@ libusb20_be_get_dev_quirk(struct libusb20_backend *pbe, uint16_t quirk_index, struct libusb20_quirk *pq) { - return ((pbe->methods->root_get_dev_quirk) (pbe, quirk_index, pq)); + return (pbe->methods->root_get_dev_quirk(pbe, quirk_index, pq)); } int libusb20_be_get_quirk_name(struct libusb20_backend *pbe, uint16_t quirk_index, struct libusb20_quirk *pq) { - return ((pbe->methods->root_get_quirk_name) (pbe, quirk_index, pq)); + return (pbe->methods->root_get_quirk_name(pbe, quirk_index, pq)); } int libusb20_be_add_dev_quirk(struct libusb20_backend *pbe, struct libusb20_quirk *pq) { - return ((pbe->methods->root_add_dev_quirk) (pbe, pq)); + return (pbe->methods->root_add_dev_quirk(pbe, pq)); } int libusb20_be_remove_dev_quirk(struct libusb20_backend *pbe, struct libusb20_quirk *pq) { - return ((pbe->methods->root_remove_dev_quirk) (pbe, pq)); + return (pbe->methods->root_remove_dev_quirk(pbe, pq)); } int libusb20_be_set_owner(struct libusb20_backend *pbe, uid_t user, gid_t group) { - return ((pbe->methods->root_set_owner) (pbe, user, group)); + return (pbe->methods->root_set_owner(pbe, user, group)); } int libusb20_be_set_perm(struct libusb20_backend *pbe, mode_t mode) { - return ((pbe->methods->root_set_perm) (pbe, mode)); + return (pbe->methods->root_set_perm(pbe, mode)); } int @@ -1119,7 +1152,7 @@ user = &a; if (group == NULL) group = &b; - return ((pbe->methods->root_get_owner) (pbe, user, group)); + return (pbe->methods->root_get_owner(pbe, user, group)); } int @@ -1129,7 +1162,7 @@ if (mode == NULL) mode = &a; - return ((pbe->methods->root_get_perm) (pbe, mode)); + return (pbe->methods->root_get_perm(pbe, mode)); } struct libusb20_device * @@ -1162,7 +1195,7 @@ /* do the initial device scan */ if (pbe->methods->init_backend) { - (pbe->methods->init_backend) (pbe); + pbe->methods->init_backend(pbe); } return (pbe); } @@ -1223,7 +1256,7 @@ libusb20_dev_free(pdev); } if (pbe->methods->exit_backend) { - (pbe->methods->exit_backend) (pbe); + pbe->methods->exit_backend(pbe); } return; } ==== //depot/projects/usb/src/lib/libusb20/libusb20.h#10 (text+ko) ==== @@ -175,6 +175,7 @@ LIBUSB20_POWER_RESUME, }; +struct usb2_device_info; struct libusb20_transfer; struct libusb20_backend; struct libusb20_backend_methods; @@ -260,6 +261,8 @@ int libusb20_dev_get_perm(struct libusb20_device *pdev, mode_t *mode); int libusb20_dev_get_iface_owner(struct libusb20_device *pdev, uint8_t iface_index, uid_t *user, gid_t *group); int libusb20_dev_get_iface_perm(struct libusb20_device *pdev, uint8_t iface_index, mode_t *mode); +int libusb20_dev_get_info(struct libusb20_device *pdev, struct usb2_device_info *pinfo); +int libusb20_dev_get_iface_desc(struct libusb20_device *pdev, uint8_t iface_index, char *buf, uint8_t len); struct LIBUSB20_DEVICE_DESC_DECODED *libusb20_dev_get_device_desc(struct libusb20_device *pdev); struct libusb20_config *libusb20_dev_alloc_config(struct libusb20_device *pdev, uint8_t config_index); ==== //depot/projects/usb/src/lib/libusb20/libusb20_int.h#7 (text+ko) ==== @@ -57,6 +57,8 @@ typedef int (libusb20_dev_get_iface_perm_t)(struct libusb20_device *pdev, uint8_t iface_index, mode_t *mode); typedef int (libusb20_dev_get_owner_t)(struct libusb20_device *pdev, uid_t *user, gid_t *group); typedef int (libusb20_dev_get_perm_t)(struct libusb20_device *pdev, mode_t *mode); +typedef int (libusb20_dev_get_info_t)(struct libusb20_device *pdev, struct usb2_device_info *pinfo); +typedef int (libusb20_dev_get_iface_desc_t)(struct libusb20_device *pdev, uint8_t iface_index, char *buf, uint8_t len); typedef int (libusb20_dev_set_iface_owner_t)(struct libusb20_device *pdev, uint8_t iface_index, uid_t user, gid_t group); typedef int (libusb20_dev_set_iface_perm_t)(struct libusb20_device *pdev, uint8_t iface_index, mode_t mode); typedef int (libusb20_dev_set_owner_t)(struct libusb20_device *pdev, uid_t user, gid_t group); @@ -85,8 +87,10 @@ m(n, bus_get_owner) \ m(n, bus_set_perm) \ m(n, bus_get_perm) \ + m(n, dev_get_info) \ m(n, dev_get_iface_owner) \ m(n, dev_get_iface_perm) \ + m(n, dev_get_iface_desc) \ m(n, dev_get_owner) \ m(n, dev_get_perm) \ m(n, dev_set_iface_owner) \ ==== //depot/projects/usb/src/lib/libusb20/libusb20_ugen20.c#13 (text+ko) ==== @@ -58,6 +58,8 @@ static libusb20_dev_get_iface_perm_t ugen20_dev_get_iface_perm; static libusb20_dev_get_owner_t ugen20_dev_get_owner; static libusb20_dev_get_perm_t ugen20_dev_get_perm; +static libusb20_dev_get_iface_desc_t ugen20_dev_get_iface_desc; +static libusb20_dev_get_info_t ugen20_dev_get_info; static libusb20_dev_set_iface_owner_t ugen20_dev_set_iface_owner; static libusb20_dev_set_iface_perm_t ugen20_dev_set_iface_perm; static libusb20_dev_set_owner_t ugen20_dev_set_owner; @@ -954,6 +956,34 @@ } static int +ugen20_dev_get_iface_desc(struct libusb20_device *pdev, + uint8_t iface_index, char *buf, uint8_t len) +{ + struct usb2_gen_descriptor ugd; + + memset(&ugd, 0, sizeof(ugd)); + + ugd.ugd_data = buf; + ugd.ugd_maxlen = len; + ugd.ugd_iface_index = iface_index; + + if (ioctl(pdev->file, USB_GET_IFACE_DRIVER, &ugd)) { + return (LIBUSB20_ERROR_INVALID_PARAM); + } + return (0); +} + +static int +ugen20_dev_get_info(struct libusb20_device *pdev, + struct usb2_device_info *pinfo) +{ + if (ioctl(pdev->file, USB_GET_DEVICEINFO, pinfo)) { + return (LIBUSB20_ERROR_INVALID_PARAM); + } + return (0); +} + +static int ugen20_dev_get_iface_owner(struct libusb20_device *pdev, uint8_t iface_index, uid_t *user, gid_t *group) { ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#43 (text+ko) ==== @@ -80,6 +80,7 @@ static int ugen_set_interface(struct usb2_fifo *, uint8_t, uint8_t); static int ugen_get_cdesc(struct usb2_fifo *, struct usb2_gen_descriptor *); static int ugen_get_sdesc(struct usb2_fifo *, struct usb2_gen_descriptor *); +static int ugen_get_iface_driver(struct usb2_fifo *f, struct usb2_gen_descriptor *ugd); static int usb2_gen_fill_deviceinfo(struct usb2_fifo *, struct usb2_device_info *); static int ugen_re_enumerate(struct usb2_fifo *); @@ -714,68 +715,64 @@ } /*------------------------------------------------------------------------* - * usb2_gen_fill_devicenames + * ugen_get_iface_driver * - * This function dumps information about an USB device names to - * userland. + * This function generates an USB interface description for userland. * * Returns: * 0: Success * Else: Failure *------------------------------------------------------------------------*/ static int -usb2_gen_fill_devicenames(struct usb2_fifo *f, struct usb2_device_names *dn) +ugen_get_iface_driver(struct usb2_fifo *f, struct usb2_gen_descriptor *ugd) { + struct usb2_device *udev = f->udev; struct usb2_interface *iface; const char *ptr; - char *dst; - char buf[32]; - int error = 0; - int len; - int max_len; - uint8_t i; - uint8_t first = 1; + const char *desc; + unsigned int len; + unsigned int maxlen; + char buf[128]; + int error; - max_len = dn->udn_devnames_len; - dst = dn->udn_devnames_ptr; + DPRINTFN(6, "\n"); - if (max_len == 0) { + if ((ugd->ugd_data == NULL) || (ugd->ugd_maxlen == 0)) { + /* userland pointer should not be zero */ return (EINVAL); } - /* put a zero there */ - error = copyout("", dst, 1); - if (error) { - return (error); + + iface = usb2_get_iface(udev, ugd->ugd_iface_index); + if ((iface == NULL) || (iface->idesc == NULL)) { + /* invalid interface index */ + return (EINVAL); } - for (i = 0;; i++) { - iface = usb2_get_iface(f->udev, i); - if (iface == NULL) { - break; - } - if ((iface->subdev != NULL) && - device_is_attached(iface->subdev)) { - ptr = device_get_nameunit(iface->subdev); - if (!first) { - strlcpy(buf, ", ", sizeof(buf)); - } else { - buf[0] = 0; - } - strlcat(buf, ptr, sizeof(buf)); - len = strlen(buf) + 1; - if (len > max_len) { - break; - } - error = copyout(buf, dst, len); - if (error) { - return (error); - } - len--; - dst += len; - max_len -= len; - first = 0; - } + + /* read out device nameunit string, if any */ + if ((iface->subdev != NULL) && + device_is_attached(iface->subdev) && + (ptr = device_get_nameunit(iface->subdev)) && + (desc = device_get_desc(iface->subdev))) { + + /* print description */ + snprintf(buf, sizeof(buf), "%s: <%s>", ptr, desc); + + /* range checks */ + maxlen = ugd->ugd_maxlen - 1; + len = strlen(buf); + if (len > maxlen) + len = maxlen; + + /* update actual length, including terminating zero */ + ugd->ugd_actlen = len + 1; + + /* copy out interface description */ + error = copyout(buf, ugd->ugd_data, ugd->ugd_actlen); + } else { + /* zero length string is default */ + error = copyout("", ugd->ugd_data, 1); } - return (0); + return (error); } /*------------------------------------------------------------------------* @@ -2046,6 +2043,10 @@ error = ugen_get_sdesc(f, addr); break; + case USB_GET_IFACE_DRIVER: + error = ugen_get_iface_driver(f, addr); + break; + case USB_REQUEST: case USB_DO_REQUEST: if (!(fflags & FWRITE)) { @@ -2060,10 +2061,6 @@ error = usb2_gen_fill_deviceinfo(f, addr); break; - case USB_GET_DEVICENAMES: - error = usb2_gen_fill_devicenames(f, addr); - break; - case USB_DEVICESTATS: for (n = 0; n != 4; n++) { ==== //depot/projects/usb/src/sys/dev/usb2/include/usb2_ioctl.h#29 (text+ko) ==== @@ -77,13 +77,6 @@ uint8_t reserved[8]; }; -struct usb2_device_names { - char *udn_devnames_ptr; /* userland pointer to comma separated - * list of device names */ - uint16_t udn_devnames_len; /* maximum string length including - * terminating zero */ -}; - struct usb2_device_info { uint16_t udi_productNo; uint16_t udi_vendorNo; @@ -249,7 +242,7 @@ #define USB_SET_RX_BUFFER_SIZE _IOW ('U', 118, int) #define USB_SET_RX_STALL_FLAG _IOW ('U', 119, int) #define USB_SET_TX_STALL_FLAG _IOW ('U', 120, int) -#define USB_GET_DEVICENAMES _IOW ('U', 121, struct usb2_device_names) +#define USB_GET_IFACE_DRIVER _IOWR('U', 121, struct usb2_gen_descriptor) #define USB_CLAIM_INTERFACE _IOW ('U', 122, int) #define USB_RELEASE_INTERFACE _IOW ('U', 123, int) #define USB_IFACE_DRIVER_ACTIVE _IOW ('U', 124, int) ==== //depot/projects/usb/src/usr.sbin/usbconfig/dump.c#10 (text+ko) ==== @@ -176,15 +176,30 @@ } void -dump_device_info(struct libusb20_device *pdev) +dump_device_info(struct libusb20_device *pdev, uint8_t show_ifdrv) { + char buf[128]; + uint8_t n; + printf("%s, cfg=%u md=%s spd=%s pwr=%s\n", libusb20_dev_get_desc(pdev), libusb20_dev_get_config_index(pdev), dump_mode(libusb20_dev_get_mode(pdev)), dump_speed(libusb20_dev_get_speed(pdev)), dump_power_mode(libusb20_dev_get_power_mode(pdev))); - return; + + if (!show_ifdrv) + return; + + for (n = 0; n != 255; n++) { + if (libusb20_dev_get_iface_desc(pdev, n, buf, sizeof(buf))) + break; + if (buf[0] == 0) + continue; + printf("ugen%u.%u.%u: %s\n", + libusb20_dev_get_bus_number(pdev), + libusb20_dev_get_address(pdev), n, buf); + } } void @@ -339,7 +354,8 @@ owner = (pw = getpwuid(uid)) ? pw->pw_name : "UNKNOWN"; group = (gr = getgrgid(gid)) ? gr->gr_name : "UNKNOWN"; - printf(" " "Interface %u Access: %s:%s 0%o\n", iface, owner, group, mode); + printf(" " "Interface %u Access: %s:%s 0%o\n", + iface, owner, group, mode); } else { printf(" " "Interface %u Access: \n", iface); } ==== //depot/projects/usb/src/usr.sbin/usbconfig/dump.h#5 (text+ko) ==== @@ -27,7 +27,7 @@ const char *dump_mode(uint8_t value); const char *dump_speed(uint8_t value); const char *dump_power_mode(uint8_t value); -void dump_device_info(struct libusb20_device *pdev); +void dump_device_info(struct libusb20_device *pdev, uint8_t show_drv); void dump_be_access(struct libusb20_backend *pbe); void dump_be_quirk_names(struct libusb20_backend *pbe); void dump_be_dev_quirks(struct libusb20_backend *pbe); ==== //depot/projects/usb/src/usr.sbin/usbconfig/usbconfig.c#12 (text+ko) ==== @@ -78,6 +78,7 @@ uint8_t got_dump_all_config:1; uint8_t got_dump_info:1; uint8_t got_dump_access:1; + uint8_t got_show_iface_driver:1; uint8_t got_remove_device_quirk:1; uint8_t got_add_device_quirk:1; uint8_t got_dump_string:1; @@ -100,6 +101,7 @@ T_SET_PERM, T_ADD_DEVICE_QUIRK, T_REMOVE_DEVICE_QUIRK, + T_SHOW_IFACE_DRIVER, T_DUMP_QUIRK_NAMES, T_DUMP_DEVICE_QUIRKS, T_DUMP_DEVICE_DESC, @@ -138,6 +140,7 @@ {"dump_string", T_DUMP_STRING, 1}, {"dump_access", T_DUMP_ACCESS, 0}, {"dump_info", T_DUMP_INFO, 0}, + {"show_ifdrv", T_SHOW_IFACE_DRIVER, 0}, {"suspend", T_SUSPEND, 0}, {"resume", T_RESUME, 0}, {"power_off", T_POWER_OFF, 0}, @@ -290,6 +293,7 @@ " dump_string " "\n" " dump_access" "\n" " dump_info" "\n" + " show_ifdrv" "\n" " suspend" "\n" " resume" "\n" " power_off" "\n" @@ -535,7 +539,8 @@ opt->got_dump_access); if (opt->got_list || dump_any) { - dump_device_info(pdev); + dump_device_info(pdev, + opt->got_show_iface_driver); } if (opt->got_dump_access) { printf("\n"); @@ -632,6 +637,10 @@ opt->got_any++; break; + case T_SHOW_IFACE_DRIVER: + opt->got_show_iface_driver = 1; + break; + case T_UNIT: if (opt->got_any) { /* allow multiple commands on the same line */