> Back last fall you mentioned something about needing to add a workaround > to the UHCI driver's port reset code for VIA hardware. It had to do with > making sure the controller was suspended before doing the reset. Can you > remember the details? Is it still needed?
Hi Alan, this work around is still needed with the latest 2.6 kernels (which is not surprising since it is a hardware problem). It is only needed for the VIA hub with PCI id 1106, 3038. Here is an extract from my original email (http://sourceforge.net/mailarchive/message.php?msg_id=2307801): > THE PROBLEM: plugging in a new device, with a device already > plugged in, causes the existing device to malfunction, either by > causing some urbs to fail (the case with my webcam) or all urbs > to fail from then on (the case with my speedtouch modem). > > THE SOLUTION: this problem does not occur with windows. By > observing reads and writes to the USB I/O registers I found > that some VIA specific code (viausb.sys) does the following > on a PORT_RESET: > > Clears the run/stop bit in USBCMD. > Writes the numbers 0 to 1023 consecutively to port 0x80. > Sets the enter global suspend mode bit in USBCMD. > Calls the standard port reset function in uhcd.sys. > Clears the force global resume bit in USBCMD. > Sets the force global resume and enter global suspend mode bits in USBCMD. > Writes the numbers 0 to 1023 consecutively to port 0x80. > Clears the force global resume and enter global suspend mode bits, and > sets the run/stop bit in USBCMD. > > In essence: the host controller is suspended before the port reset, and > woken up afterwards. The following patch worked most of the time (not all of the time, presumably because it was sometimes being un-suspended in the middle): --- linux/drivers/usb/uhci.c.orig 2002-10-25 22:54:25.000000000 +0200 +++ linux/drivers/usb/uhci.c 2002-10-26 00:20:11.000000000 +0200 @@ -2184,6 +2184,9 @@ SET_RH_PORTSTAT(USBPORTSC_SUSP); OK(0); case RH_PORT_RESET: + if (uhci->rh.needs_suspend) + suspend_hc (uhci); + SET_RH_PORTSTAT(USBPORTSC_PR); mdelay(50); /* USB v1.1 7.1.7.3 */ uhci->rh.c_p_r[wIndex - 1] = 1; @@ -2192,6 +2195,10 @@ SET_RH_PORTSTAT(USBPORTSC_PE); mdelay(10); SET_RH_PORTSTAT(0xa); + + if (uhci->rh.needs_suspend) + wakeup_hc (uhci); + OK(0); case RH_PORT_POWER: OK(0); /* port power ** */ @@ -2817,6 +2824,11 @@ uhci->rh.numports = port; + uhci->rh.needs_suspend = 0; + + if ((dev->vendor == 0x1106) && (dev->device == 0x3038)) + uhci->rh.needs_suspend = 1; + uhci->bus->root_hub = uhci->rh.dev = usb_alloc_dev(NULL, uhci->bus); if (!uhci->rh.dev) { err("unable to allocate root hub"); --- linux/drivers/usb/uhci.h.orig 2002-10-25 22:54:20.000000000 +0200 +++ linux/drivers/usb/uhci.h 2002-10-25 22:55:57.000000000 +0200 @@ -274,6 +274,7 @@ int send; int interval; int numports; + int needs_suspend; int c_p_r[8]; struct timer_list rh_int_timer; }; I should mention (down here at the bottom of the email where hopefully no-one from VIA is going to notice :) ), that I did quite a bit of rummaging around inside VIA's "filter driver" for windows. This driver (which you can get from their website) basically contains a bunch of workarounds for various hardware problems. It checks your hardware against a list of PCI ids and turns on various hacks depending on what you have. I was only concerned about the hardware I had at that time, but it seems clear to me that one way to get better support for VIA hardware would be to implement those hacks in linux. I used to have a nicely annotated decompilation at one point... All the best, Duncan. ------------------------------------------------------- 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_id56&alloc_id438&op=click _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel