It looks like this may be my problem, is there a kernel patch about?

http://sourceforge.net/mailarchive/message.php?msg_id=2307801


From: Duncan Sands <[EMAIL PROTECTED]> 
 VIA workaround, was: unending timeouts   
2002-10-21 01:04 
 SUMMARY: I have found a workaround for a hardware problem
 with my VIA USB hub (PCI ID: 1106 VIA, 3038 USB hub).  I
 need help integrating it into the UHCI hcd.
 
 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.
 
 Inserting the same sequence in uhci.c fixes the problem under linux.
 Here is some example code (in rh_submit_urb, uhci.c, kernel 2.4.19).
 I replaced the writes to port 0x80 with a five millisecond delay, since
 that is how long those writes take on my machine.  It is possible that
 writing to port 0x80 is also used to slow down traffic on the bus, but
 on my machine the delay works OK.
 
                case RH_PORT_RESET:
                         status = inb(io_addr); /* USBCMD */
                         status &= 0xFE; /* clear run/stop */
                         outb(status, io_addr);
 /*                        for(i=0; i < 1024; i++) outl(i, 0x80);*/
                         mdelay(5);
                         status = inb(io_addr); /* USBCMD */
                         status |= 0x08; /* set EGSM */
                         outb(status, io_addr);
 
                        /* usual port reset */
                        SET_RH_PORTSTAT(USBPORTSC_PR);
                        mdelay(50);     /* USB v1.1 7.1.7.3 */
                        uhci->rh.c_p_r[wIndex - 1] = 1;
                        CLR_RH_PORTSTAT(USBPORTSC_PR);
                        udelay(10);
                        SET_RH_PORTSTAT(USBPORTSC_PE);
                        mdelay(10);
                        SET_RH_PORTSTAT(0xa);
 
                         status = inb(io_addr); /* USBCMD */
                         status &= 0xEF; /* clear FGR */
                         outb(status, io_addr);
                         status = inb(io_addr);
                         status |= 0x18; /* set FGR and EGSM */
                         outb(status, io_addr);
 /*                        for(i=0; i < 1024; i++) outl(i, 0x80);*/
                         mdelay(5);
                         status = inb(io_addr); /* USBCMD */
                         status &= 0xE7; /* clear FGR and EGSM */
                         status |= 0x01; /* set run/stop */
                         outb(status, io_addr);
 
                        OK(0);
 
 TO DO (need help): this workaround needs to be properly integrated
 into the uhci hcd code.
 
 (1) this code should only be run when using this VIA USB controller.
 (2) probably a generic hcd suspend / resume function should be used
 instead of this do-it-yourself suspend/resume sequence.
 (3) locking?
 (4) need to make sure this does not collide with other code, for example
 if I put this code in usb-uhci.c then the suspend state is detected and
 cleared ("Host controller halted, trying to restart").  This doesn't seem to
 hurt by the way.
 
 Please help!
 
 Thanks,
 
 Duncan.
 
 PS: Here is how windows does it, note the hardcoded values:
 
 mov    al, 80h
 out    dx, al  /* write to USBCMD */
 push   dx
 xor    eax, eax
 mov    dx, 80h /* port 0x80 */
 
 A: inc eax
 out    dx, eax
 cmp    eax, 400h
 jb     short A
 pop    dx
 mov    al, 88h
 out    dx, al
 
 ... peform port reset ...
 
 mov    al, 88h
 out    dx, al  /* write to USBCMD */
 mov    al, 98h
 out    dx, al
 push   dx
 xor    eax, eax
 mov    dx, 80h /* port 0x80 */
 
 B: inc eax
 out    dx, eax
 cmp    eax, 400h
 jb     short B
 pop    dx
 mov    al, 81h
 out    dx, al
 
 



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-users

Reply via email to