On Thu, 1 Jun 2017, Reinhard Huck wrote:
> Hi,
>
> Currently, in an usbdevfs-based application it is not possible to know
> the speed the device is operating at. But this information is sometime
> required, for example to interpret the bInterval and wMaxPacketSize
> fields of interrupt/isochronous endpoint descriptors. Specifically, it
> is a problem to differentiate between full and high speed because this
> is not indicated in descriptors.
>
> We suggest to add a new IOCTL (e.g. USBDEVFS_GET_SPEED) which reports
> the speed as an int value as one of the following constants:
>
> #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
>
> Alternatively you could introduce IOCTL USBDEVFS_CONNECTINFO_2 and
> struct usbdevfs_connectinfo_2.
That's a good idea. The connection speed is available in sysfs but not
in usbfs (at least, not since the days of USB-1.1).
How does this patch look?
Alan Stern
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,16 @@ 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 +200,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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html