The usbfs interface does not provide any way for the user to learn the speed at which a device is connected. The current API includes a USBDEVFS_CONNECTINFO ioctl, but all it provides is the device's address and a one-bit value indicating whether the connection is low speed. That may have sufficed in the era of USB-1.1, but it isn't good enough today. This patch introduces a new ioctl, USBDEVFS_GET_SPEED, which returns a numeric value indicating the speed of the connection: unknown, low, full, high, wireless, super, or super-plus. Similar information (not exactly the same) is available through sysfs, but it seems reasonable to provide the actual value in usbfs. Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> Reported-by: Reinhard Huck <reinhard.huck@xxxxxxxxxxx> --- [as1832] drivers/usb/core/devio.c | 24 ++++++++++++++++++++++++ include/uapi/linux/usbdevice_fs.h | 10 ++++++++++ 2 files changed, 34 insertions(+) Index: usb-4.x/drivers/usb/core/devio.c =================================================================== --- usb-4.x.orig/drivers/usb/core/devio.c +++ usb-4.x/drivers/usb/core/devio.c @@ -1322,6 +1322,27 @@ static int proc_connectinfo(struct usb_d return 0; } +static int proc_get_speed(struct usb_dev_state *ps) +{ + switch (ps->dev->speed) { + case USB_SPEED_UNKNOWN: + return USBDEVFS_SPEED_UNKNOWN; + case USB_SPEED_LOW: + return USBDEVFS_SPEED_LOW; + case USB_SPEED_FULL: + return USBDEVFS_SPEED_FULL; + case USB_SPEED_HIGH: + return USBDEVFS_SPEED_HIGH; + case USB_SPEED_WIRELESS: + return USBDEVFS_SPEED_WIRELESS; + case USB_SPEED_SUPER: + return USBDEVFS_SPEED_SUPER; + case USB_SPEED_SUPER_PLUS: + return USBDEVFS_SPEED_SUPER_PLUS; + } + return -ERANGE; +} + static int proc_resetdevice(struct usb_dev_state *ps) { struct usb_host_config *actconfig = ps->dev->actconfig; @@ -2537,6 +2558,9 @@ static long usbdev_do_ioctl(struct file case USBDEVFS_DROP_PRIVILEGES: ret = proc_drop_privileges(ps, p); break; + case USBDEVFS_GET_SPEED: + ret = proc_get_speed(ps); + break; } done: Index: usb-4.x/include/uapi/linux/usbdevice_fs.h =================================================================== --- usb-4.x.orig/include/uapi/linux/usbdevice_fs.h +++ usb-4.x/include/uapi/linux/usbdevice_fs.h @@ -156,6 +156,15 @@ struct usbdevfs_streams { unsigned char eps[0]; }; +/* connection speed values used by USBDEVFS_GET_SPEED */ +#define USBDEVFS_SPEED_UNKNOWN 0 +#define USBDEVFS_SPEED_LOW 1 +#define USBDEVFS_SPEED_FULL 2 +#define USBDEVFS_SPEED_HIGH 3 +#define USBDEVFS_SPEED_WIRELESS 4 +#define USBDEVFS_SPEED_SUPER 5 +#define USBDEVFS_SPEED_SUPER_PLUS 6 + #define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer) #define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32) #define USBDEVFS_BULK _IOWR('U', 2, struct usbdevfs_bulktransfer) @@ -190,5 +199,6 @@ struct usbdevfs_streams { #define USBDEVFS_ALLOC_STREAMS _IOR('U', 28, struct usbdevfs_streams) #define USBDEVFS_FREE_STREAMS _IOR('U', 29, struct usbdevfs_streams) #define USBDEVFS_DROP_PRIVILEGES _IOW('U', 30, __u32) +#define USBDEVFS_GET_SPEED _IO('U', 31) #endif /* _UAPI_LINUX_USBDEVICE_FS_H */ -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html