Johannes:
Here is a revised version of a patch I sent you earlier. It fixes the
implementation of the Changed-Port-Reset bit flags, which currently is
totally broken. It simplifies things a little by converting wIndex to
origin 0. Also, I audited the code for unchecked uses of wIndex and
added a test in one spot.
If this looks okay, please let Greg know he can apply it.
Alan Stern
# This is a BitKeeper generated patch for the following project:
# Project Name: greg k-h's linux 2.5 USB kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1657 -> 1.1658
# drivers/usb/host/uhci-hub.c 1.3 -> 1.4
# drivers/usb/host/uhci-hcd.h 1.14 -> 1.15
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/08/04 [EMAIL PROTECTED] 1.1658
# Implement Changed-Port-Reset flags correctly.
# Convert wIndex to origin 0 and audit unchecked uses.
# --------------------------------------------
#
diff -Nru a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
--- a/drivers/usb/host/uhci-hcd.h Mon Aug 4 12:28:34 2003
+++ b/drivers/usb/host/uhci-hcd.h Mon Aug 4 12:28:34 2003
@@ -341,6 +341,7 @@
enum uhci_state state; /* FIXME: needs a spinlock */
unsigned long state_end; /* Time of next transition */
int resume_detect; /* Need a Global Resume */
+ unsigned long c_p_r; /* Changed-Port-Reset bits */
/* Main list of URB's currently controlled by this HC */
spinlock_t urb_list_lock;
diff -Nru a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
--- a/drivers/usb/host/uhci-hub.c Mon Aug 4 12:28:34 2003
+++ b/drivers/usb/host/uhci-hub.c Mon Aug 4 12:28:34 2003
@@ -32,7 +32,9 @@
*buf = 0;
for (i = 0; i < uhci->rh_numports; i++) {
- *buf |= ((inw(io_addr + USBPORTSC1 + i * 2) & 0xa) > 0 ? (1 << (i +
1)) : 0);
+ *buf |= ((inw(io_addr + USBPORTSC1 + i * 2) & 0xa) > 0 ||
+ test_bit(i, &uhci->c_p_r)
+ ? (1 << (i + 1)) : 0);
len = (i + 1) / 8 + 1;
}
@@ -42,14 +44,14 @@
#define OK(x) len = (x); break
#define CLR_RH_PORTSTAT(x) \
- status = inw(io_addr + USBPORTSC1 + 2 * (wIndex-1)); \
+ status = inw(io_addr + USBPORTSC1 + 2 * wIndex); \
status = (status & 0xfff5) & ~(x); \
- outw(status, io_addr + USBPORTSC1 + 2 * (wIndex-1))
+ outw(status, io_addr + USBPORTSC1 + 2 * wIndex)
#define SET_RH_PORTSTAT(x) \
- status = inw(io_addr + USBPORTSC1 + 2 * (wIndex-1)); \
+ status = inw(io_addr + USBPORTSC1 + 2 * wIndex); \
status = (status & 0xfff5) | (x); \
- outw(status, io_addr + USBPORTSC1 + 2 * (wIndex-1))
+ outw(status, io_addr + USBPORTSC1 + 2 * wIndex)
/* size of returned buffer is part of USB spec */
@@ -57,13 +59,12 @@
u16 wIndex, char *buf, u16 wLength)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
- int i, status, retval = 0, len = 0;
+ int status, retval = 0, len = 0;
unsigned int io_addr = uhci->io_addr;
__u16 cstatus;
- char c_p_r[8];
- for (i = 0; i < 8; i++)
- c_p_r[i] = 0;
+ /* Convert wIndex to origin 0; if it was 0, it will wrap around */
+ --wIndex;
switch (typeReq) {
/* Request Destination:
@@ -78,11 +79,14 @@
*(__u32 *)buf = cpu_to_le32(0);
OK(4); /* hub power */
case GetPortStatus:
- status = inw(io_addr + USBPORTSC1 + 2 * (wIndex - 1));
+ if (wIndex >= uhci->rh_numports)
+ goto err;
+
+ status = inw(io_addr + USBPORTSC1 + 2 * wIndex);
cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) |
((status & USBPORTSC_PEC) >> (3 - 1)) |
- (c_p_r[wIndex - 1] << (0 + 4));
- status = (status & USBPORTSC_CCS) |
+ (!!test_bit(wIndex, &uhci->c_p_r) << (0 + 4));
+ status = (status & USBPORTSC_CCS) |
((status & USBPORTSC_PE) >> (2 - 1)) |
((status & USBPORTSC_SUSP) >> (12 - 2)) |
((status & USBPORTSC_PR) >> (9 - 4)) |
@@ -110,7 +114,7 @@
}
break;
case SetPortFeature:
- if (!wIndex || wIndex > uhci->rh_numports)
+ if (wIndex >= uhci->rh_numports)
goto err;
switch (wValue) {
@@ -120,7 +124,7 @@
case USB_PORT_FEAT_RESET:
SET_RH_PORTSTAT(USBPORTSC_PR);
mdelay(50); /* USB v1.1 7.1.7.3 */
- c_p_r[wIndex - 1] = 1;
+ set_bit(wIndex, &uhci->c_p_r);
CLR_RH_PORTSTAT(USBPORTSC_PR);
udelay(10);
SET_RH_PORTSTAT(USBPORTSC_PE);
@@ -137,7 +141,7 @@
}
break;
case ClearPortFeature:
- if (!wIndex || wIndex > uhci->rh_numports)
+ if (wIndex >= uhci->rh_numports)
goto err;
switch (wValue) {
@@ -161,7 +165,7 @@
case USB_PORT_FEAT_C_OVER_CURRENT:
OK(0); /* port power over current */
case USB_PORT_FEAT_C_RESET:
- c_p_r[wIndex - 1] = 0;
+ clear_bit(wIndex, &uhci->c_p_r);
OK(0);
default:
goto err;
-------------------------------------------------------
This SF.Net email sponsored by: Free pre-built ASP.NET sites including
Data Reports, E-commerce, Portals, and Forums are available now.
Download today and enter to win an XBOX or Visual Studio .NET.
http://aspnet.click-url.com/go/psa00100003ave/direct;at.aspnet_072303_01/01
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel