patch-2.4.19 linux-2.4.19/drivers/usb/devices.c
Next file: linux-2.4.19/drivers/usb/devio.c
Previous file: linux-2.4.19/drivers/usb/catc.c
Back to the patch index
Back to the overall index
- Lines: 206
- Date:
Fri Aug 2 17:39:44 2002
- Orig file:
linux-2.4.18/drivers/usb/devices.c
- Orig date:
Fri Dec 21 09:41:55 2001
diff -urN linux-2.4.18/drivers/usb/devices.c linux-2.4.19/drivers/usb/devices.c
@@ -105,8 +105,8 @@
"I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n";
static char *format_endpt =
-/* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddms */
- "E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%3dms\n";
+/* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */
+ "E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n";
/*
@@ -166,24 +166,71 @@
return (clas_info[ix].class_name);
}
-static char *usb_dump_endpoint_descriptor(char *start, char *end, const struct usb_endpoint_descriptor *desc)
-{
- char *EndpointType [4] = {"Ctrl", "Isoc", "Bulk", "Int."};
+static char *usb_dump_endpoint_descriptor (
+ int speed,
+ char *start,
+ char *end,
+ const struct usb_endpoint_descriptor *desc
+)
+{
+ char dir, unit, *type;
+ unsigned interval, in, bandwidth = 1;
if (start > end)
return start;
- start += sprintf(start, format_endpt, desc->bEndpointAddress,
- (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_CONTROL
- ? 'B' : /* bidirectional */
- (desc->bEndpointAddress & USB_DIR_IN) ? 'I' : 'O',
- desc->bmAttributes, EndpointType[desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK],
- desc->wMaxPacketSize, desc->bInterval);
- return start;
-}
+ in = (desc->bEndpointAddress & USB_DIR_IN);
+ dir = in ? 'I' : 'O';
+ if (speed == USB_SPEED_HIGH) {
+ switch (desc->wMaxPacketSize & (0x03 << 11)) {
+ case 1 << 11: bandwidth = 2; break;
+ case 2 << 11: bandwidth = 3; break;
+ }
+ }
-static char *usb_dump_endpoint(char *start, char *end, const struct usb_endpoint_descriptor *endpoint)
-{
- return usb_dump_endpoint_descriptor(start, end, endpoint);
+ /* this isn't checking for illegal values */
+ switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ case USB_ENDPOINT_XFER_CONTROL:
+ type = "Ctrl";
+ if (speed == USB_SPEED_HIGH) /* uframes per NAK */
+ interval = desc->bInterval;
+ else
+ interval = 0;
+ dir = 'B'; /* ctrl is bidirectional */
+ break;
+ case USB_ENDPOINT_XFER_ISOC:
+ type = "Isoc";
+ interval = 1 << (desc->bInterval - 1);
+ break;
+ case USB_ENDPOINT_XFER_BULK:
+ type = "Bulk";
+ if (speed == USB_SPEED_HIGH && !in) /* uframes per NAK */
+ interval = desc->bInterval;
+ else
+ interval = 0;
+ break;
+ case USB_ENDPOINT_XFER_INT:
+ type = "Int.";
+ if (speed == USB_SPEED_HIGH) {
+ interval = 1 << (desc->bInterval - 1);
+ } else
+ interval = desc->bInterval;
+ break;
+ default: /* "can't happen" */
+ return start;
+ }
+ interval *= (speed == USB_SPEED_HIGH) ? 125 : 1000;
+ if (interval % 1000)
+ unit = 'u';
+ else {
+ unit = 'm';
+ interval /= 1000;
+ }
+
+ start += sprintf(start, format_endpt, desc->bEndpointAddress, dir,
+ desc->bmAttributes, type,
+ (desc->wMaxPacketSize & 0x07ff) * bandwidth,
+ interval, unit);
+ return start;
}
static char *usb_dump_interface_descriptor(char *start, char *end, const struct usb_interface *iface, int setno)
@@ -204,8 +251,13 @@
return start;
}
-static char *usb_dump_interface(char *start, char *end, const struct usb_interface *iface, int setno)
-{
+static char *usb_dump_interface(
+ int speed,
+ char *start,
+ char *end,
+ const struct usb_interface *iface,
+ int setno
+) {
struct usb_interface_descriptor *desc = &iface->altsetting[setno];
int i;
@@ -213,7 +265,8 @@
for (i = 0; i < desc->bNumEndpoints; i++) {
if (start > end)
return start;
- start = usb_dump_endpoint(start, end, desc->endpoint + i);
+ start = usb_dump_endpoint_descriptor(speed,
+ start, end, desc->endpoint + i);
}
return start;
}
@@ -238,7 +291,13 @@
return start;
}
-static char *usb_dump_config(char *start, char *end, const struct usb_config_descriptor *config, int active)
+static char *usb_dump_config (
+ int speed,
+ char *start,
+ char *end,
+ const struct usb_config_descriptor *config,
+ int active
+)
{
int i, j;
struct usb_interface *interface;
@@ -255,7 +314,8 @@
for (j = 0; j < interface->num_altsetting; j++) {
if (start > end)
return start;
- start = usb_dump_interface(start, end, interface, j);
+ start = usb_dump_interface(speed,
+ start, end, interface, j);
}
}
return start;
@@ -336,8 +396,10 @@
for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
if (start > end)
return start;
- start = usb_dump_config(start, end, dev->config + i,
- (dev->config + i) == dev->actconfig); /* active ? */
+ start = usb_dump_config(dev->speed,
+ start, end, dev->config + i,
+ /* active ? */
+ (dev->config + i) == dev->actconfig);
}
return start;
}
@@ -429,12 +491,26 @@
* count = device count at this level
*/
/* If this is the root hub, display the bandwidth information */
- if (level == 0)
- data_end += sprintf(data_end, format_bandwidth, bus->bandwidth_allocated,
- FRAME_TIME_MAX_USECS_ALLOC,
- (100 * bus->bandwidth_allocated + FRAME_TIME_MAX_USECS_ALLOC / 2) / FRAME_TIME_MAX_USECS_ALLOC,
- bus->bandwidth_int_reqs, bus->bandwidth_isoc_reqs);
-
+ if (level == 0) {
+ int max;
+
+ /* high speed reserves 80%, full/low reserves 90% */
+ if (usbdev->speed == USB_SPEED_HIGH)
+ max = 800;
+ else
+ max = FRAME_TIME_MAX_USECS_ALLOC;
+
+ /* report "average" periodic allocation over a microsecond.
+ * the schedules are actually bursty, HCDs need to deal with
+ * that and just compute/report this average.
+ */
+ data_end += sprintf(data_end, format_bandwidth,
+ bus->bandwidth_allocated, max,
+ (100 * bus->bandwidth_allocated + max / 2)
+ / max,
+ bus->bandwidth_int_reqs,
+ bus->bandwidth_isoc_reqs);
+ }
data_end = usb_dump_desc(data_end, pages_start + (2 * PAGE_SIZE) - 256, usbdev);
if (data_end > (pages_start + (2 * PAGE_SIZE) - 256))
@@ -497,8 +573,10 @@
bus = list_entry(buslist, struct usb_bus, bus_list);
/* recurse through all children of the root hub */
ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
- if (ret < 0)
+ if (ret < 0) {
+ up(&usb_bus_list_lock);
return ret;
+ }
total_written += ret;
}
up (&usb_bus_list_lock);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)