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:
parent
ce66729032
commit
06d497c1af
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=188622
@ -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
|
||||
.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) \
|
||||
|
@ -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)
|
||||
|
@ -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,69 +715,65 @@ 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);
|
||||
}
|
||||
for (i = 0;; i++) {
|
||||
iface = usb2_get_iface(f->udev, i);
|
||||
if (iface == NULL) {
|
||||
break;
|
||||
|
||||
iface = usb2_get_iface(udev, ugd->ugd_iface_index);
|
||||
if ((iface == NULL) || (iface->idesc == NULL)) {
|
||||
/* invalid interface index */
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/* read out device nameunit string, if any */
|
||||
if ((iface->subdev != NULL) &&
|
||||
device_is_attached(iface->subdev)) {
|
||||
ptr = device_get_nameunit(iface->subdev);
|
||||
if (!first) {
|
||||
strlcpy(buf, ", ", sizeof(buf));
|
||||
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 {
|
||||
buf[0] = 0;
|
||||
/* zero length string is default */
|
||||
error = copyout("", ugd->ugd_data, 1);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_gen_fill_deviceinfo
|
||||
@ -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++) {
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)));
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user