Skip to content
Snippets Groups Projects
usb.c 31.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • Wolfgang Denk's avatar
    Wolfgang Denk committed
    			usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_ENABLE);
    
    			/* EM interference sometimes causes bad shielded USB devices to
    			 * be shutdown by the hub, this hack enables them again.
    			 * Works at least with mouse driver */
    			if (!(portstatus & USB_PORT_STAT_ENABLE) &&
    				(portstatus & USB_PORT_STAT_CONNECTION) && (dev->children[i])) {
    				USB_HUB_PRINTF("already running port %i disabled by hub (EMI?), re-enabling...\n",
    					i + 1);
    					usb_hub_port_connect_change(dev, i);
    			}
    		}
    		if (portstatus & USB_PORT_STAT_SUSPEND) {
    			USB_HUB_PRINTF("port %d suspend change\n", i + 1);
    			usb_clear_port_feature(dev, i + 1,  USB_PORT_FEAT_SUSPEND);
    		}
    
    		if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
    			USB_HUB_PRINTF("port %d over-current change\n", i + 1);
    			usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_OVER_CURRENT);
    			usb_hub_power_on(hub);
    		}
    
    		if (portchange & USB_PORT_STAT_C_RESET) {
    			USB_HUB_PRINTF("port %d reset change\n", i + 1);
    			usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_RESET);
    		}
    	} /* end for i all ports */
    
    	return 0;
    }
    
    int usb_hub_probe(struct usb_device *dev, int ifnum)
    {
    	struct usb_interface_descriptor *iface;
    	struct usb_endpoint_descriptor *ep;
    	int ret;
    
    	iface = &dev->config.if_desc[ifnum];
    	/* Is it a hub? */
    	if (iface->bInterfaceClass != USB_CLASS_HUB)
    		return 0;
    	/* Some hubs have a subclass of 1, which AFAICT according to the */
    	/*  specs is not defined, but it works */
    	if ((iface->bInterfaceSubClass != 0) &&
    	    (iface->bInterfaceSubClass != 1))
    		return 0;
    	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
    	if (iface->bNumEndpoints != 1)
    		return 0;
    	ep = &iface->ep_desc[0];
    	/* Output endpoint? Curiousier and curiousier.. */
    	if (!(ep->bEndpointAddress & USB_DIR_IN))
    		return 0;
    	/* If it's not an interrupt endpoint, we'd better punt! */
    	if ((ep->bmAttributes & 3) != 3)
    		return 0;
    	/* We found a hub */
    	USB_HUB_PRINTF("USB hub found\n");
    	ret=usb_hub_configure(dev);
    	return ret;
    }
    
    #endif /* (CONFIG_COMMANDS & CFG_CMD_USB) */
    
    /* EOF */