MFp4 //depot/projects/usb@157699

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.

Submitted by:	Hans Petter Selasky
This commit is contained in:
Andrew Thompson 2009-02-14 23:20:00 +00:00
parent ce66729032
commit 06d497c1af
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=188622
10 changed files with 224 additions and 115 deletions

View File

@ -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<unit>: <description>"
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<unit>: <description>"
.
.Pp
.

View File

@ -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;
}

View File

@ -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);

View File

@ -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) \

View File

@ -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)

View File

@ -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++) {

View File

@ -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)

View File

@ -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: <not set>\n", iface);
}

View File

@ -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);

View File

@ -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 <index>" "\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 */