[RFC] Patch to allow violation of USB specs (low-speed BULK to start with)
Brad Campbell <[email protected]>
| Newsgroups | gmane.linux.usb.devel |
|---|---|
| Message-ID | <[email protected]> |
G'day all,
This has taken a while as I've gone and built some devices to characterise the uhci stack under
extreme duress caused by low-speed bulk devices.
In short, it handles it very well. No bus starvation noticable. Throughput to full-speed devices is
pretty much unworried, latency is not an issue. The uhci stack just throttles the BULK tokens to the
low-speed device back until it's not having any adverse effect to the other devices.
Interestingly enough.. this test hardware turned up some serious bugs in combination with Windows
and old VIA uhci hardware. Linux handles these bugs without comment and just keeps on keeping on.
Very simply.. a single parameter to usbcore to tell it we _do_ want to do nasty things with the
specification. I'm not sure of the best way to do this, so I thought I'd try it first and deal
with the comments as they arise.
diff -ur kernel-clean/drivers/usb/core/config.c kernel-modified/drivers/usb/core/config.c
--- kernel-clean/drivers/usb/core/config.c 2007-09-29 21:00:15.000000000 +0400
+++ kernel-modified/drivers/usb/core/config.c 2007-10-01 15:12:16.000000000 +0400
@@ -13,6 +13,11 @@
#define USB_MAXCONFIG 8 /* Arbitrary limit */
+/* Allow the violation of the USB Specifications */
+static int usb_violate_specs = 0;
+module_param (usb_violate_specs, bool, S_IRUGO);
+MODULE_PARM_DESC (usb_violate_specs, "true to allow the blatant violation of the specifications");
+EXPORT_SYMBOL(usb_violate_specs);
static inline const char *plural(int n)
{
@@ -135,7 +140,8 @@
* them usable, we will try treating them as Interrupt endpoints.
*/
if (to_usb_device(ddev)->speed == USB_SPEED_LOW &&
- usb_endpoint_xfer_bulk(d)) {
+ usb_endpoint_xfer_bulk(d) &&
+ !usb_violate_specs) {
dev_warn(ddev, "config %d interface %d altsetting %d "
"endpoint 0x%X is Bulk; changing to Interrupt\n",
cfgno, inum, asnum, d->bEndpointAddress);
diff -ur kernel-clean/drivers/usb/host/uhci-q.c kernel-modified/drivers/usb/host/uhci-q.c
--- kernel-clean/drivers/usb/host/uhci-q.c 2007-09-29 21:00:15.000000000 +0400
+++ kernel-modified/drivers/usb/host/uhci-q.c 2007-10-01 15:12:28.000000000 +0400
@@ -16,6 +16,7 @@
* (C) Copyright 2004-2007 Alan Stern, [email protected]
*/
+extern int usb_violate_specs;
/*
* Technically, updating td->status here is a race, but it's not really a
@@ -1043,7 +1044,7 @@
int ret;
/* Can't have low-speed bulk transfers */
- if (urb->dev->speed == USB_SPEED_LOW)
+ if (urb->dev->speed == USB_SPEED_LOW && !usb_violate_specs)
return -EINVAL;
if (qh->state != QH_STATE_ACTIVE)
Compiled, tested..
Brad
--
"Human beings, who are almost unique in having the ability
to learn from the experience of others, are also remarkable
for their apparent disinclination to do so." -- Douglas Adams
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel