Skip to content
Snippets Groups Projects
usb.c 31.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	default:
    		printf("usb_new_device: invalid max packet size\n");
    		return -EIO;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	}
    
    static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,
    			      struct usb_device *parent, int portnr)
    
    
    	/*
    	 * Allocate usb 3.0 device context.
    	 * USB 3.0 (xHCI) protocol tries to allocate device slot
    	 * and related data structures first. This call does that.
    	 * Refer to sec 4.3.2 in xHCI spec rev1.0
    	 */
    
    	err = usb_alloc_device(dev);
    	if (err) {
    
    		printf("Cannot allocate device context to get SLOT_ID\n");
    
    	}
    	err = usb_setup_descriptor(dev, do_read);
    	if (err)
    		return err;
    
    	err = usb_legacy_port_reset(parent, portnr);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	dev->devnum = addr;
    
    	err = usb_set_address(dev); /* set address */
    
    	if (err < 0) {
    
    		printf("\n      USB device not accepting new address " \
    			"(error=%lX)\n", dev->status);
    
    	mdelay(10);	/* Let the SET_ADDRESS settle */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    int usb_select_config(struct usb_device *dev)
    
    {
    	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
    
    	err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE);
    	if (err)
    		return err;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	/* correct le values */
    
    	le16_to_cpus(&dev->descriptor.bcdUSB);
    	le16_to_cpus(&dev->descriptor.idVendor);
    	le16_to_cpus(&dev->descriptor.idProduct);
    	le16_to_cpus(&dev->descriptor.bcdDevice);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	/* only support for one config for now */
    
    	err = usb_get_configuration_no(dev, tmpbuf, 0);
    	if (err < 0) {
    		printf("usb_new_device: Cannot read configuration, " \
    		       "skipping device %04x:%04x\n",
    		       dev->descriptor.idVendor, dev->descriptor.idProduct);
    
    	usb_parse_config(dev, tmpbuf, 0);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	usb_set_maxpacket(dev);
    
    	/*
    	 * we set the default configuration here
    	 * This seems premature. If the driver wants a different configuration
    	 * it will need to select itself.
    	 */
    	err = usb_set_configuration(dev, dev->config.desc.bConfigurationValue);
    	if (err < 0) {
    
    		printf("failed to set default configuration " \
    			"len %d, status %lX\n", dev->act_len, dev->status);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	}
    
    	debug("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
    	      dev->descriptor.iManufacturer, dev->descriptor.iProduct,
    	      dev->descriptor.iSerialNumber);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	memset(dev->mf, 0, sizeof(dev->mf));
    	memset(dev->prod, 0, sizeof(dev->prod));
    	memset(dev->serial, 0, sizeof(dev->serial));
    	if (dev->descriptor.iManufacturer)
    
    		usb_string(dev, dev->descriptor.iManufacturer,
    			   dev->mf, sizeof(dev->mf));
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	if (dev->descriptor.iProduct)
    
    		usb_string(dev, dev->descriptor.iProduct,
    			   dev->prod, sizeof(dev->prod));
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	if (dev->descriptor.iSerialNumber)
    
    		usb_string(dev, dev->descriptor.iSerialNumber,
    			   dev->serial, sizeof(dev->serial));
    
    	debug("Manufacturer %s\n", dev->mf);
    	debug("Product      %s\n", dev->prod);
    	debug("SerialNumber %s\n", dev->serial);
    
    int usb_setup_device(struct usb_device *dev, bool do_read,
    		     struct usb_device *parent, int portnr)
    
    {
    	int addr;
    	int ret;
    
    	/* We still haven't set the Address yet */
    	addr = dev->devnum;
    	dev->devnum = 0;
    
    	ret = usb_prepare_device(dev, addr, do_read, parent, portnr);
    	if (ret)
    		return ret;
    	ret = usb_select_config(dev);
    
    	return ret;
    }
    
    
    /*
     * By the time we get here, the device has gotten a new device ID
     * and is in the default state. We need to identify the thing and
     * get the ball rolling..
     *
     * Returns 0 for success, != 0 for error.
     */
    int usb_new_device(struct usb_device *dev)
    {
    	bool do_read = true;
    	int err;
    
    	/*
    	 * XHCI needs to issue a Address device command to setup
    	 * proper device context structures, before it can interact
    	 * with the device. So a get_descriptor will fail before any
    	 * of that is done for XHCI unlike EHCI.
    	 */
    #ifdef CONFIG_USB_XHCI
    	do_read = false;
    #endif
    	err = usb_setup_device(dev, do_read, dev->parent, dev->portnr);
    	if (err)
    		return err;
    
    	/* Now probe if the device is a hub */
    	err = usb_hub_probe(dev, 0);
    	if (err < 0)
    		return err;
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	return 0;
    }
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    int board_usb_init(int index, enum usb_init_type init)
    
    
    __weak
    int board_usb_cleanup(int index, enum usb_init_type init)
    {
    	return 0;
    }
    
    
    bool usb_device_has_child_on_port(struct usb_device *parent, int port)
    {
    #ifdef CONFIG_DM_USB
    	return false;
    #else
    	return parent->children[port] != NULL;
    #endif
    }
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    /* EOF */