diff --git a/lib/libusb20/libusb20.3 b/lib/libusb20/libusb20.3 index 414c81f24706..8b7639aaa34f 100644 --- a/lib/libusb20/libusb20.3 +++ b/lib/libusb20/libusb20.3 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd Oct 23, 2008 +.Dd Feb 14, 2009 .Dt LIBUSB20 3 .Os .Sh NAME @@ -308,8 +308,32 @@ This function returns a zero terminated string describing the backend used. . .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 . diff --git a/lib/libusb20/libusb20.c b/lib/libusb20/libusb20.c index e9ef1fc3166f..814bd26fe2d1 100644 --- a/lib/libusb20/libusb20.c +++ b/lib/libusb20/libusb20.c @@ -78,6 +78,8 @@ dummy_callback(struct libusb20_transfer *xfer) #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 @@ libusb20_tr_callback_wrapper(struct libusb20_transfer *xfer) xfer->is_pending = 0; } - (xfer->callback) (xfer); + xfer->callback(xfer); if (xfer->is_restart) { xfer->is_restart = 0; @@ -109,7 +111,7 @@ libusb20_tr_callback_wrapper(struct libusb20_transfer *xfer) (!xfer->is_pending)) { xfer->is_draining = 0; xfer->status = LIBUSB20_TRANSFER_DRAINED; - (xfer->callback) (xfer); + xfer->callback(xfer); } return; } @@ -122,7 +124,7 @@ libusb20_tr_close(struct libusb20_transfer *xfer) 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 @@ libusb20_tr_open(struct libusb20_transfer *xfer, uint32_t MaxBufSize, } 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 @@ libusb20_tr_stop(struct libusb20_transfer *xfer) } 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 @@ libusb20_tr_drain(struct libusb20_transfer *xfer) 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 @@ libusb20_tr_submit(struct libusb20_transfer *xfer) 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 @@ libusb20_dev_claim_interface(struct libusb20_device *pdev, uint8_t ifaceIndex) } 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 @@ libusb20_dev_close(struct libusb20_device *pdev) 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 @@ libusb20_dev_detach_kernel_driver(struct libusb20_device *pdev, uint8_t ifaceInd { int error; - error = (pdev->methods->detach_kernel_driver) (pdev, ifaceIndex); + error = pdev->methods->detach_kernel_driver(pdev, ifaceIndex); return (error); } @@ -517,7 +519,7 @@ libusb20_dev_kernel_driver_active(struct libusb20_device *pdev, uint8_t ifaceInd { int error; - error = (pdev->methods->kernel_driver_active) (pdev, ifaceIndex); + error = pdev->methods->kernel_driver_active(pdev, ifaceIndex); return (error); } @@ -555,7 +557,7 @@ libusb20_dev_open(struct libusb20_device *pdev, uint16_t nTransferMax) /* 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 @@ libusb20_dev_release_interface(struct libusb20_device *pdev, uint8_t ifaceIndex) } 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 @@ libusb20_dev_reset(struct libusb20_device *pdev) { int error; - error = (pdev->methods->reset_device) (pdev); + error = pdev->methods->reset_device(pdev); return (error); } @@ -603,7 +605,7 @@ libusb20_dev_set_power_mode(struct libusb20_device *pdev, uint8_t power_mode) { 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 @@ libusb20_dev_get_power_mode(struct libusb20_device *pdev) 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 @@ libusb20_dev_set_alt_index(struct libusb20_device *pdev, uint8_t ifaceIndex, uin { 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 @@ libusb20_dev_set_config_index(struct libusb20_device *pdev, uint8_t configIndex) { int error; - error = (pdev->methods->set_config_index) (pdev, configIndex); + error = pdev->methods->set_config_index(pdev, configIndex); return (error); } @@ -644,7 +646,7 @@ libusb20_dev_request_sync(struct libusb20_device *pdev, { 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 @@ libusb20_dev_alloc_config(struct libusb20_device *pdev, uint8_t configIndex) } 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 @@ libusb20_dev_get_config_index(struct libusb20_device *pdev) 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 @@ libusb20_dev_process(struct libusb20_device *pdev) { int error; - error = (pdev->methods->process) (pdev); + error = pdev->methods->process(pdev); return (error); } @@ -921,10 +923,20 @@ libusb20_dev_free(struct libusb20_device *pdev) 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 @@ libusb20_dev_get_bus_number(struct libusb20_device *pdev) 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 @@ libusb20_dev_get_owner(struct libusb20_device *pdev, uid_t *user, gid_t *group) 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 @@ libusb20_dev_get_perm(struct libusb20_device *pdev, mode_t *mode) 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 @@ libusb20_dev_get_iface_owner(struct libusb20_device *pdev, uint8_t iface_index, 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 @@ libusb20_bus_get_owner(struct libusb20_backend *pbe, uint8_t bus, uid_t *user, g 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 @@ libusb20_bus_get_perm(struct libusb20_backend *pbe, uint8_t bus, mode_t *mode) 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 @@ int 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 @@ libusb20_be_get_owner(struct libusb20_backend *pbe, uid_t *user, gid_t *group) 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 @@ libusb20_be_get_perm(struct libusb20_backend *pbe, mode_t *mode) 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 @@ libusb20_be_alloc(const struct libusb20_backend_methods *methods) /* 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_be_free(struct libusb20_backend *pbe) libusb20_dev_free(pdev); } if (pbe->methods->exit_backend) { - (pbe->methods->exit_backend) (pbe); + pbe->methods->exit_backend(pbe); } return; } diff --git a/lib/libusb20/libusb20.h b/lib/libusb20/libusb20.h index d696b634116c..051548ecd6ea 100644 --- a/lib/libusb20/libusb20.h +++ b/lib/libusb20/libusb20.h @@ -175,6 +175,7 @@ enum { 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_owner(struct libusb20_device *pdev, uid_t *user, gid_t *gro 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); diff --git a/lib/libusb20/libusb20_int.h b/lib/libusb20/libusb20_int.h index 6c849b9396b5..5e89bfe1cced 100644 --- a/lib/libusb20/libusb20_int.h +++ b/lib/libusb20/libusb20_int.h @@ -57,6 +57,8 @@ typedef int (libusb20_dev_get_iface_owner_t)(struct libusb20_device *pdev, uint8 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 @@ typedef void (libusb20_exit_backend_t)(struct libusb20_backend *pbe); 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) \ diff --git a/lib/libusb20/libusb20_ugen20.c b/lib/libusb20/libusb20_ugen20.c index 3646a59a9285..c148790d7462 100644 --- a/lib/libusb20/libusb20_ugen20.c +++ b/lib/libusb20/libusb20_ugen20.c @@ -58,6 +58,8 @@ static libusb20_dev_get_iface_owner_t ugen20_dev_get_iface_owner; 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; @@ -953,6 +955,34 @@ ugen20_bus_get_perm(struct libusb20_backend *pbe, bus, 0, 0, NULL, NULL, mode)); } +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) diff --git a/sys/dev/usb2/core/usb2_generic.c b/sys/dev/usb2/core/usb2_generic.c index 79bfc2ffbb52..49f683d8c417 100644 --- a/sys/dev/usb2/core/usb2_generic.c +++ b/sys/dev/usb2/core/usb2_generic.c @@ -80,6 +80,7 @@ static int ugen_set_config(struct usb2_fifo *, uint8_t); 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 @@ ugen_get_sdesc(struct usb2_fifo *f, struct usb2_gen_descriptor *ugd) } /*------------------------------------------------------------------------* - * 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 @@ ugen_ioctl_post(struct usb2_fifo *f, u_long cmd, void *addr, int fflags, 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 @@ ugen_ioctl_post(struct usb2_fifo *f, u_long cmd, void *addr, int fflags, 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++) { diff --git a/sys/dev/usb2/include/usb2_ioctl.h b/sys/dev/usb2/include/usb2_ioctl.h index eeafd27e169e..58c392af1b7b 100644 --- a/sys/dev/usb2/include/usb2_ioctl.h +++ b/sys/dev/usb2/include/usb2_ioctl.h @@ -77,13 +77,6 @@ struct usb2_gen_descriptor { 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 @@ struct usb2_gen_quirk { #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) diff --git a/usr.sbin/usbconfig/dump.c b/usr.sbin/usbconfig/dump.c index ffa8b2c8d9fd..01c55d29cf43 100644 --- a/usr.sbin/usbconfig/dump.c +++ b/usr.sbin/usbconfig/dump.c @@ -176,15 +176,30 @@ dump_iface(struct libusb20_device *pdev, } 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 @@ dump_device_iface_access(struct libusb20_device *pdev, uint8_t iface) 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); } diff --git a/usr.sbin/usbconfig/dump.h b/usr.sbin/usbconfig/dump.h index 95ef7209d0d0..87e9a4d4332d 100644 --- a/usr.sbin/usbconfig/dump.h +++ b/usr.sbin/usbconfig/dump.h @@ -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); diff --git a/usr.sbin/usbconfig/usbconfig.c b/usr.sbin/usbconfig/usbconfig.c index e0f03dd56770..4b69dc5123fe 100644 --- a/usr.sbin/usbconfig/usbconfig.c +++ b/usr.sbin/usbconfig/usbconfig.c @@ -78,6 +78,7 @@ struct options { 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 @@ enum { 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 @@ static const struct token token[] = { {"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 @@ usage(void) " dump_string " "\n" " dump_access" "\n" " dump_info" "\n" + " show_ifdrv" "\n" " suspend" "\n" " resume" "\n" " power_off" "\n" @@ -535,7 +539,8 @@ flush_command(struct libusb20_backend *pbe, struct options *opt) 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 @@ main(int argc, char **argv) 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 */