Rogério:

I just came across some new information that might be relevant for your 
problem.  Do you remember if your desktop system uses a USB controller by 
VIA?  If it does, that would explain a lot.  VIA controllers have a bug 
that causes them to shut down when they receive a packet that's too large 
("babble"), and your internal port generates just such bad packets from 
time to time.  They showed up in both the Windows and Linux logs.

Just out of curiosity, maybe you can try this patch and see what shows up 
in the debugging log.  It enlarges the size of the packets the system asks 
for; maybe that will prevent the controller from shutting down.

Alan Stern


--- 2.6/drivers/usb/core/hub.h.orig     Tue Feb  3 10:58:00 2004
+++ 2.6/drivers/usb/core/hub.h  Tue Feb  3 10:58:38 2004
@@ -175,8 +175,8 @@
        struct completion       *urb_complete;  /* wait for urb to end */
        unsigned int            urb_active:1;
 
-       /* buffer for urb ... 1 bit each for hub and children, rounded up */
-       char                    (*buffer)[(USB_MAXCHILDREN + 1 + 7) / 8];
+       /* buffer for urb ... max is 64 bytes for full speed */
+       char                    (*buffer)[64];
        dma_addr_t              buffer_dma;     /* DMA address for buffer */
        union {
                struct usb_hub_status   hub;
--- 2.6/drivers/usb/core/hub.c.orig     Tue Jan 20 16:10:29 2004
+++ 2.6/drivers/usb/core/hub.c  Tue Feb  3 10:57:44 2004
@@ -154,6 +154,8 @@
                break;
        }
 
+       if (urb->actual_length > 1)
+               dev_dbg(&hub->intf->dev, "int length %d\n", urb->actual_length);
        hub->nerrors = 0;
 
        /* Something happened, let khubd figure it out */
@@ -270,13 +272,17 @@
 {
        struct usb_device *dev;
        int i;
+       int ret;
 
        /* Enable power to the ports */
        dev_dbg(hubdev(interface_to_usbdev(hub->intf)),
                "enabling power on all ports\n");
        dev = interface_to_usbdev(hub->intf);
-       for (i = 0; i < hub->descriptor->bNbrPorts; i++)
-               set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
+       for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
+               ret = set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
+               dev_dbg(hubdev(interface_to_usbdev(hub->intf)),
+                       "port %d power on: %d\n", i+1, ret);
+       }
 
        /* Wait for power to be enabled */
        wait_ms(hub->descriptor->bPwrOn2PwrGood * 2);
@@ -741,6 +747,8 @@
 
                /* read and decode port status */
                ret = hub_port_status(hub, port, &portstatus, &portchange);
+               dev_dbg(hubdev(hub), "wait_reset %d, port %d, status %x, change %x\n",
+                               ret, port+1, portstatus, portchange);
                if (ret < 0) {
                        return -1;
                }
@@ -785,7 +793,8 @@
 
        /* Reset the port */
        for (i = 0; i < HUB_RESET_TRIES; i++) {
-               set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET);
+               status = set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET);
+               dev_dbg(hubdev(hub), "port reset = %d\n", status);
 
                /* return on disconnect or reset */
                status = hub_port_wait_reset(hub, port, dev, delay);
@@ -855,6 +864,8 @@
                wait_ms(HUB_DEBOUNCE_STEP);
 
                ret = hub_port_status(hub, port, &portstatus, &portchange);
+               dev_dbg(hubdev(hub), "port_status= %d, port %d status %x change %x\n",
+                       ret, port+1, portstatus, portchange);
                if (ret < 0)
                        return -1;
 
@@ -869,7 +880,8 @@
                connection = portstatus & USB_PORT_STAT_CONNECTION;
 
                if ((portchange & USB_PORT_STAT_C_CONNECTION)) {
-                       clear_port_feature(hub, port+1, USB_PORT_FEAT_C_CONNECTION);
+                       ret = clear_port_feature(hub, port+1, 
USB_PORT_FEAT_C_CONNECTION);
+                       dev_dbg(hubdev(hub), "clear C_CONNECTION2 = %d\n", ret);
                }
        }
 
@@ -893,7 +905,8 @@
                port + 1, portstatus, portchange, portspeed (portstatus));
 
        /* Clear the connection change status */
-       clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);
+       i = clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);
+       dev_dbg(&hubstate->intf->dev, "clear C_CONNECTION1 = %d\n", i);
 
        /* Disconnect any existing devices under this port */
        if (hub->children[port])
@@ -1064,6 +1077,8 @@
 
                for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
                        ret = hub_port_status(dev, i, &portstatus, &portchange);
+                       dev_dbg(hubdev(dev),
+                               "initial port %d status: ret = %d\n", i+1, ret);
                        if (ret < 0) {
                                continue;
                        }



-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to