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