Greg:
This adds some minor improvements to the UHCI root hub code. The only
important change is that it handles the overcurrent indicator bits on VIA
controllers properly; they are reported using the opposite sense from
Intel controllers.
Please apply.
Alan Stern
Report the OverCurrent status bits in the /proc debugging file
and spontaneously change the use of whitespace.
Remove unused variable in uhci_hub_status_data().
Report OverCurrent status for VIA controllers properly (the
meaning of the status bit is inverted with respect to Intel
controllers).
Save the port status I/O address in a variable rather than
recalculating it many times.
Merge code for handling SetHubFeature and ClearHubFeature since
we don't implement either one.
Remove some unnecessary comments.
Remove redundant min_t calculation.
diff -Nru a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
--- a/drivers/usb/host/uhci-debug.c Wed Feb 18 14:50:31 2004
+++ b/drivers/usb/host/uhci-debug.c Wed Feb 18 14:50:31 2004
@@ -225,20 +225,22 @@
char *out = buf;
/* Try to make sure there's enough memory */
- if (len < 80)
+ if (len < 160)
return 0;
- out += sprintf(out, " stat%d = %04x %s%s%s%s%s%s%s%s\n",
+ out += sprintf(out, " stat%d = %04x %s%s%s%s%s%s%s%s%s%s\n",
port,
status,
- (status & USBPORTSC_SUSP) ? "PortSuspend " : "",
- (status & USBPORTSC_PR) ? "PortReset " : "",
- (status & USBPORTSC_LSDA) ? "LowSpeed " : "",
- (status & USBPORTSC_RD) ? "ResumeDetect " : "",
- (status & USBPORTSC_PEC) ? "EnableChange " : "",
- (status & USBPORTSC_PE) ? "PortEnabled " : "",
- (status & USBPORTSC_CSC) ? "ConnectChange " : "",
- (status & USBPORTSC_CCS) ? "PortConnected " : "");
+ (status & USBPORTSC_SUSP) ? " Suspend" : "",
+ (status & USBPORTSC_OCC) ? " OverCurrentChange" : "",
+ (status & USBPORTSC_OC) ? " OverCurrent" : "",
+ (status & USBPORTSC_PR) ? " Reset" : "",
+ (status & USBPORTSC_LSDA) ? " LowSpeed" : "",
+ (status & USBPORTSC_RD) ? " ResumeDetect" : "",
+ (status & USBPORTSC_PEC) ? " EnableChange" : "",
+ (status & USBPORTSC_PE) ? " Enabled" : "",
+ (status & USBPORTSC_CSC) ? " ConnectChange" : "",
+ (status & USBPORTSC_CCS) ? " Connected" : "");
return out - buf;
}
diff -Nru a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
--- a/drivers/usb/host/uhci-hub.c Wed Feb 18 14:50:31 2004
+++ b/drivers/usb/host/uhci-hub.c Wed Feb 18 14:50:31 2004
@@ -36,33 +36,30 @@
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
unsigned int io_addr = uhci->io_addr;
- int i, len = 1;
+ int i;
*buf = 0;
for (i = 0; i < uhci->rh_numports; i++) {
- *buf |= (inw(io_addr + USBPORTSC1 + i * 2) & RWC_BITS) != 0
- ? (1 << (i + 1))
- : 0;
- len = (i + 1) / 8 + 1;
+ if (inw(io_addr + USBPORTSC1 + i * 2) & RWC_BITS)
+ *buf |= (1 << (i + 1));
}
-
return !!*buf;
}
#define OK(x) len = (x); break
#define CLR_RH_PORTSTAT(x) \
- status = inw(io_addr + USBPORTSC1 + 2 * (wIndex-1)); \
+ status = inw(port_addr); \
status &= ~(RWC_BITS|WZ_BITS); \
status &= ~(x); \
status |= RWC_BITS & (x); \
- outw(status, io_addr + USBPORTSC1 + 2 * (wIndex-1))
+ outw(status, port_addr)
#define SET_RH_PORTSTAT(x) \
- status = inw(io_addr + USBPORTSC1 + 2 * (wIndex-1)); \
+ status = inw(port_addr); \
status |= (x); \
status &= ~(RWC_BITS|WZ_BITS); \
- outw(status, io_addr + USBPORTSC1 + 2 * (wIndex-1))
+ outw(status, port_addr)
/* size of returned buffer is part of USB spec */
@@ -71,8 +68,8 @@
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
int status, retval = 0, len = 0;
- unsigned int io_addr = uhci->io_addr;
- u16 wPortChange, wPortStatus;
+ unsigned int port_addr = uhci->io_addr + USBPORTSC1 + 2 * (wIndex-1);
+ __u16 wPortChange, wPortStatus;
switch (typeReq) {
/* Request Destination:
@@ -87,9 +84,19 @@
*(__u32 *)buf = cpu_to_le32(0);
OK(4); /* hub power */
case GetPortStatus:
- status = inw(io_addr + USBPORTSC1 + 2 * (wIndex - 1));
+ if (!wIndex || wIndex > uhci->rh_numports)
+ goto err;
+ status = inw(port_addr);
+
+ /* Intel controllers report the OverCurrent bit active on.
+ * VIA controllers report it active off, so we'll adjust the
+ * bit value. (It's not standardized in the UHCI spec.)
+ */
+ if (to_pci_dev(hcd->self.controller)->vendor ==
+ PCI_VENDOR_ID_VIA)
+ status ^= USBPORTSC_OC;
- /* C_SUSPEND and C_RESET are always false */
+ /* UHCI doesn't support C_SUSPEND and C_RESET (always false) */
wPortChange = 0;
if (status & USBPORTSC_CSC)
wPortChange |= 1 << (USB_PORT_FEAT_C_CONNECTION - 16);
@@ -122,20 +129,12 @@
*(__u16 *)buf = cpu_to_le16(wPortStatus);
*(__u16 *)(buf + 2) = cpu_to_le16(wPortChange);
OK(4);
- case SetHubFeature:
- switch (wValue) {
- case C_HUB_OVER_CURRENT:
- case C_HUB_LOCAL_POWER:
- break;
- default:
- goto err;
- }
- break;
+ case SetHubFeature: /* We don't implement these */
case ClearHubFeature:
switch (wValue) {
case C_HUB_OVER_CURRENT:
case C_HUB_LOCAL_POWER:
- OK(0); /* hub power over current */
+ OK(0);
default:
goto err;
}
@@ -159,7 +158,7 @@
OK(0);
case USB_PORT_FEAT_POWER:
/* UHCI has no power switching */
- OK(0); /* port power ** */
+ OK(0);
default:
goto err;
}
@@ -189,7 +188,7 @@
OK(0);
case USB_PORT_FEAT_C_OVER_CURRENT:
CLR_RH_PORTSTAT(USBPORTSC_OCC);
- OK(0); /* port power over current */
+ OK(0);
case USB_PORT_FEAT_C_RESET:
/* this driver won't report these */
OK(0);
@@ -198,8 +197,7 @@
}
break;
case GetHubDescriptor:
- len = min_t(unsigned int, wLength,
- min_t(unsigned int, sizeof(root_hub_hub_des), wLength));
+ len = min_t(unsigned int, sizeof(root_hub_hub_des), wLength);
memcpy(buf, root_hub_hub_des, len);
if (len > 2)
buf[2] = uhci->rh_numports;
-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel