Implement new libusb v2.0 API function, libusb20_dev_get_stats().
This function is useful when debugging USB device issues. MFC after: 1 week Sponsored by: Mellanox Technologies
This commit is contained in:
parent
7082625d97
commit
34b0ca243f
@ -219,6 +219,7 @@ MLINKS += libusb20.3 libusb20_dev_get_backend_name.3
|
|||||||
MLINKS += libusb20.3 libusb20_dev_get_info.3
|
MLINKS += libusb20.3 libusb20_dev_get_info.3
|
||||||
MLINKS += libusb20.3 libusb20_dev_get_iface_desc.3
|
MLINKS += libusb20.3 libusb20_dev_get_iface_desc.3
|
||||||
MLINKS += libusb20.3 libusb20_dev_get_desc.3
|
MLINKS += libusb20.3 libusb20_dev_get_desc.3
|
||||||
|
MLINKS += libusb20.3 libusb20_dev_get_stats.3
|
||||||
MLINKS += libusb20.3 libusb20_dev_close.3
|
MLINKS += libusb20.3 libusb20_dev_close.3
|
||||||
MLINKS += libusb20.3 libusb20_dev_detach_kernel_driver.3
|
MLINKS += libusb20.3 libusb20_dev_detach_kernel_driver.3
|
||||||
MLINKS += libusb20.3 libusb20_dev_set_config_index.3
|
MLINKS += libusb20.3 libusb20_dev_set_config_index.3
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2008 Hans Petter Selasky
|
.\" Copyright (c) 2008-2019 Hans Petter Selasky
|
||||||
.\"
|
.\"
|
||||||
.\" All rights reserved.
|
.\" All rights reserved.
|
||||||
.\"
|
.\"
|
||||||
@ -26,7 +26,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd May 3, 2013
|
.Dd December 27, 2019
|
||||||
.Dt LIBUSB20 3
|
.Dt LIBUSB20 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -122,6 +122,8 @@ USB access library (libusb -lusb)
|
|||||||
.Ft const char *
|
.Ft const char *
|
||||||
.Fn libusb20_dev_get_desc "struct libusb20_device *pdev"
|
.Fn libusb20_dev_get_desc "struct libusb20_device *pdev"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn libusb20_dev_get_stats "struct libusb20_device *pdev" "struct libusb20_device_stats *pstats"
|
||||||
|
.Ft int
|
||||||
.Fn libusb20_dev_close "struct libusb20_device *pdev"
|
.Fn libusb20_dev_close "struct libusb20_device *pdev"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn libusb20_dev_detach_kernel_driver "struct libusb20_device *pdev" "uint8_t iface_index"
|
.Fn libusb20_dev_detach_kernel_driver "struct libusb20_device *pdev" "uint8_t iface_index"
|
||||||
@ -597,6 +599,14 @@ The format of the string is: "drivername<unit>: <description>"
|
|||||||
.
|
.
|
||||||
.Pp
|
.Pp
|
||||||
.
|
.
|
||||||
|
.Fn libusb20_dev_get_stats
|
||||||
|
retrieves the device statistics into the structure pointed to by the
|
||||||
|
.Fa pstats
|
||||||
|
argument.
|
||||||
|
This function returns zero on success else a LIBUSB20_ERROR value is returned.
|
||||||
|
.
|
||||||
|
.Pp
|
||||||
|
.
|
||||||
.Fn libusb20_dev_close
|
.Fn libusb20_dev_close
|
||||||
will close the given USB device.
|
will close the given USB device.
|
||||||
.
|
.
|
||||||
|
@ -78,6 +78,7 @@ dummy_callback(struct libusb20_transfer *xfer)
|
|||||||
#define dummy_set_power_mode (void *)dummy_int
|
#define dummy_set_power_mode (void *)dummy_int
|
||||||
#define dummy_get_power_mode (void *)dummy_int
|
#define dummy_get_power_mode (void *)dummy_int
|
||||||
#define dummy_get_power_usage (void *)dummy_int
|
#define dummy_get_power_usage (void *)dummy_int
|
||||||
|
#define dummy_get_stats (void *)dummy_int
|
||||||
#define dummy_kernel_driver_active (void *)dummy_int
|
#define dummy_kernel_driver_active (void *)dummy_int
|
||||||
#define dummy_detach_kernel_driver (void *)dummy_int
|
#define dummy_detach_kernel_driver (void *)dummy_int
|
||||||
#define dummy_do_request_sync (void *)dummy_int
|
#define dummy_do_request_sync (void *)dummy_int
|
||||||
@ -1049,6 +1050,31 @@ libusb20_dev_get_speed(struct libusb20_device *pdev)
|
|||||||
return (pdev->usb_speed);
|
return (pdev->usb_speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
libusb20_dev_get_stats(struct libusb20_device *pdev, struct libusb20_device_stats *pstats)
|
||||||
|
{
|
||||||
|
uint8_t do_close;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (!pdev->is_opened) {
|
||||||
|
error = libusb20_dev_open(pdev, 0);
|
||||||
|
if (error == 0) {
|
||||||
|
do_close = 1;
|
||||||
|
} else {
|
||||||
|
do_close = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
do_close = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = pdev->methods->get_stats(pdev, pstats);
|
||||||
|
|
||||||
|
if (do_close)
|
||||||
|
(void) libusb20_dev_close(pdev);
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
/* if this function returns an error, the device is gone */
|
/* if this function returns an error, the device is gone */
|
||||||
int
|
int
|
||||||
libusb20_dev_process(struct libusb20_device *pdev)
|
libusb20_dev_process(struct libusb20_device *pdev)
|
||||||
|
@ -195,6 +195,12 @@ struct libusb20_quirk {
|
|||||||
char quirkname[64 - 12];
|
char quirkname[64 - 12];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct libusb20_device_stats {
|
||||||
|
uint64_t xfer_ok[4]; /* sorted by USB transfer type, UE_XXX */
|
||||||
|
uint64_t xfer_fail[4]; /* sorted by USB transfer type, UE_XXX */
|
||||||
|
uint64_t xfer_reserved[24]; /* reserved */
|
||||||
|
};
|
||||||
|
|
||||||
#define LIBUSB20_MAX_FRAME_PRE_SCALE (1U << 31)
|
#define LIBUSB20_MAX_FRAME_PRE_SCALE (1U << 31)
|
||||||
|
|
||||||
/* USB transfer operations */
|
/* USB transfer operations */
|
||||||
@ -243,6 +249,7 @@ int libusb20_dev_detach_kernel_driver(struct libusb20_device *pdev, uint8_t ifac
|
|||||||
int libusb20_dev_set_config_index(struct libusb20_device *pdev, uint8_t configIndex);
|
int libusb20_dev_set_config_index(struct libusb20_device *pdev, uint8_t configIndex);
|
||||||
int libusb20_dev_get_debug(struct libusb20_device *pdev);
|
int libusb20_dev_get_debug(struct libusb20_device *pdev);
|
||||||
int libusb20_dev_get_fd(struct libusb20_device *pdev);
|
int libusb20_dev_get_fd(struct libusb20_device *pdev);
|
||||||
|
int libusb20_dev_get_stats(struct libusb20_device *pdev, struct libusb20_device_stats *pstat);
|
||||||
int libusb20_dev_kernel_driver_active(struct libusb20_device *pdev, uint8_t iface_index);
|
int libusb20_dev_kernel_driver_active(struct libusb20_device *pdev, uint8_t iface_index);
|
||||||
int libusb20_dev_open(struct libusb20_device *pdev, uint16_t transfer_max);
|
int libusb20_dev_open(struct libusb20_device *pdev, uint16_t transfer_max);
|
||||||
int libusb20_dev_process(struct libusb20_device *pdev);
|
int libusb20_dev_process(struct libusb20_device *pdev);
|
||||||
|
@ -108,10 +108,12 @@ typedef int (libusb20_reset_device_t)(struct libusb20_device *pdev);
|
|||||||
typedef int (libusb20_set_power_mode_t)(struct libusb20_device *pdev, uint8_t power_mode);
|
typedef int (libusb20_set_power_mode_t)(struct libusb20_device *pdev, uint8_t power_mode);
|
||||||
typedef int (libusb20_get_power_mode_t)(struct libusb20_device *pdev, uint8_t *power_mode);
|
typedef int (libusb20_get_power_mode_t)(struct libusb20_device *pdev, uint8_t *power_mode);
|
||||||
typedef int (libusb20_get_power_usage_t)(struct libusb20_device *pdev, uint16_t *power_usage);
|
typedef int (libusb20_get_power_usage_t)(struct libusb20_device *pdev, uint16_t *power_usage);
|
||||||
|
typedef int (libusb20_get_stats_t)(struct libusb20_device *pdev, struct libusb20_device_stats *pstats);
|
||||||
typedef int (libusb20_set_alt_index_t)(struct libusb20_device *pdev, uint8_t iface_index, uint8_t alt_index);
|
typedef int (libusb20_set_alt_index_t)(struct libusb20_device *pdev, uint8_t iface_index, uint8_t alt_index);
|
||||||
typedef int (libusb20_set_config_index_t)(struct libusb20_device *pdev, uint8_t index);
|
typedef int (libusb20_set_config_index_t)(struct libusb20_device *pdev, uint8_t index);
|
||||||
typedef int (libusb20_check_connected_t)(struct libusb20_device *pdev);
|
typedef int (libusb20_check_connected_t)(struct libusb20_device *pdev);
|
||||||
|
|
||||||
|
|
||||||
/* USB transfer specific */
|
/* USB transfer specific */
|
||||||
typedef int (libusb20_tr_open_t)(struct libusb20_transfer *xfer, uint32_t MaxBufSize, uint32_t MaxFrameCount, uint8_t ep_no, uint16_t stream_id, uint8_t pre_scale);
|
typedef int (libusb20_tr_open_t)(struct libusb20_transfer *xfer, uint32_t MaxBufSize, uint32_t MaxFrameCount, uint8_t ep_no, uint16_t stream_id, uint8_t pre_scale);
|
||||||
typedef int (libusb20_tr_close_t)(struct libusb20_transfer *xfer);
|
typedef int (libusb20_tr_close_t)(struct libusb20_transfer *xfer);
|
||||||
@ -131,6 +133,7 @@ typedef void (libusb20_tr_cancel_async_t)(struct libusb20_transfer *xfer);
|
|||||||
m(n, set_power_mode) \
|
m(n, set_power_mode) \
|
||||||
m(n, get_power_mode) \
|
m(n, get_power_mode) \
|
||||||
m(n, get_power_usage) \
|
m(n, get_power_usage) \
|
||||||
|
m(n, get_stats) \
|
||||||
m(n, set_alt_index) \
|
m(n, set_alt_index) \
|
||||||
m(n, set_config_index) \
|
m(n, set_config_index) \
|
||||||
m(n, tr_cancel_async) \
|
m(n, tr_cancel_async) \
|
||||||
|
@ -80,6 +80,7 @@ static libusb20_check_connected_t ugen20_check_connected;
|
|||||||
static libusb20_set_power_mode_t ugen20_set_power_mode;
|
static libusb20_set_power_mode_t ugen20_set_power_mode;
|
||||||
static libusb20_get_power_mode_t ugen20_get_power_mode;
|
static libusb20_get_power_mode_t ugen20_get_power_mode;
|
||||||
static libusb20_get_power_usage_t ugen20_get_power_usage;
|
static libusb20_get_power_usage_t ugen20_get_power_usage;
|
||||||
|
static libusb20_get_stats_t ugen20_get_stats;
|
||||||
static libusb20_kernel_driver_active_t ugen20_kernel_driver_active;
|
static libusb20_kernel_driver_active_t ugen20_kernel_driver_active;
|
||||||
static libusb20_detach_kernel_driver_t ugen20_detach_kernel_driver;
|
static libusb20_detach_kernel_driver_t ugen20_detach_kernel_driver;
|
||||||
static libusb20_do_request_sync_t ugen20_do_request_sync;
|
static libusb20_do_request_sync_t ugen20_do_request_sync;
|
||||||
@ -669,6 +670,29 @@ ugen20_get_power_usage(struct libusb20_device *pdev, uint16_t *power_usage)
|
|||||||
return (0); /* success */
|
return (0); /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ugen20_get_stats(struct libusb20_device *pdev, struct libusb20_device_stats *pstats)
|
||||||
|
{
|
||||||
|
struct usb_device_stats st;
|
||||||
|
|
||||||
|
if (ioctl(pdev->file_ctrl, IOUSB(USB_DEVICESTATS), &st))
|
||||||
|
return (LIBUSB20_ERROR_OTHER);
|
||||||
|
|
||||||
|
memset(pstats, 0, sizeof(*pstats));
|
||||||
|
|
||||||
|
pstats->xfer_ok[0] = st.uds_requests_ok[0];
|
||||||
|
pstats->xfer_ok[1] = st.uds_requests_ok[1];
|
||||||
|
pstats->xfer_ok[2] = st.uds_requests_ok[2];
|
||||||
|
pstats->xfer_ok[3] = st.uds_requests_ok[3];
|
||||||
|
|
||||||
|
pstats->xfer_fail[0] = st.uds_requests_fail[0];
|
||||||
|
pstats->xfer_fail[1] = st.uds_requests_fail[1];
|
||||||
|
pstats->xfer_fail[2] = st.uds_requests_fail[2];
|
||||||
|
pstats->xfer_fail[3] = st.uds_requests_fail[3];
|
||||||
|
|
||||||
|
return (0); /* success */
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ugen20_kernel_driver_active(struct libusb20_device *pdev,
|
ugen20_kernel_driver_active(struct libusb20_device *pdev,
|
||||||
uint8_t iface_index)
|
uint8_t iface_index)
|
||||||
|
Loading…
Reference in New Issue
Block a user