Esempio n. 1
0
static int __init zero_bind(struct usb_gadget *gadget)
{
    struct zero_dev		*dev;
    struct usb_ep		*ep;
    int			gcnum;

    /* FIXME this can't yet work right with SH ... it has only
     * one configuration, numbered one.
     */
    if (gadget_is_sh(gadget))
        return -ENODEV;

    /* Bulk-only drivers like this one SHOULD be able to
     * autoconfigure on any sane usb controller driver,
     * but there may also be important quirks to address.
     */
    usb_ep_autoconfig_reset(gadget);
    ep = usb_ep_autoconfig(gadget, &fs_source_desc);
    if (!ep) {
autoconf_fail:
        pr_err("%s: can't autoconfigure on %s\n",
               shortname, gadget->name);
        return -ENODEV;
    }
    EP_IN_NAME = ep->name;
    ep->driver_data = ep;	/* claim */

    ep = usb_ep_autoconfig(gadget, &fs_sink_desc);
    if (!ep)
        goto autoconf_fail;
    EP_OUT_NAME = ep->name;
    ep->driver_data = ep;	/* claim */

    gcnum = usb_gadget_controller_number(gadget);
    if (gcnum >= 0)
        device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
    else {
        /* gadget zero is so simple (for now, no altsettings) that
         * it SHOULD NOT have problems with bulk-capable hardware.
         * so warn about unrcognized controllers, don't panic.
         *
         * things like configuration and altsetting numbering
         * can need hardware-specific attention though.
         */
        pr_warning("%s: controller '%s' not recognized\n",
                   shortname, gadget->name);
        device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
    }


    /* ok, we made sense of the hardware ... */
    dev = kzalloc(sizeof(*dev), GFP_KERNEL);
    if (!dev)
        return -ENOMEM;
    spin_lock_init(&dev->lock);
    dev->gadget = gadget;
    set_gadget_data(gadget, dev);

    init_timer(&dev->resume);
    dev->resume.function = zero_autoresume;
    dev->resume.data = (unsigned long) dev;

    /* preallocate control response and buffer */
    dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL);
    if (!dev->req)
        goto enomem;
    dev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL);
    if (!dev->req->buf)
        goto enomem;

    dev->req->complete = zero_setup_complete;

    device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;

    if (gadget_is_dualspeed(gadget)) {
        /* assume ep0 uses the same value for both speeds ... */
        dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;

        /* and that all endpoints are dual-speed */
        hs_source_desc.bEndpointAddress =
            fs_source_desc.bEndpointAddress;
        hs_sink_desc.bEndpointAddress =
            fs_sink_desc.bEndpointAddress;
    }

    if (gadget_is_otg(gadget)) {
        otg_descriptor.bmAttributes |= USB_OTG_HNP,
                                       source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
        loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
    }

    usb_gadget_set_selfpowered(gadget);

    if (autoresume) {
        source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
        loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
    }

    gadget->ep0->driver_data = dev;

    INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname);
    INFO(dev, "using %s, OUT %s IN %s\n", gadget->name,
         EP_OUT_NAME, EP_IN_NAME);

    snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
             init_utsname()->sysname, init_utsname()->release,
             gadget->name);

    return 0;

enomem:
    zero_unbind(gadget);
    return -ENOMEM;
}
Esempio n. 2
0
static int __init zero_bind(struct usb_composite_dev *cdev)
{
	int			gcnum;
	struct usb_gadget	*gadget = cdev->gadget;
	int			id;

	/* Allocate string descriptor numbers ... note that string
	 * contents can be overridden by the composite_dev glue.
	 */
	id = usb_string_id(cdev);
	if (id < 0)
		return id;
	strings_dev[STRING_MANUFACTURER_IDX].id = id;
	device_desc.iManufacturer = id;

	id = usb_string_id(cdev);
	if (id < 0)
		return id;
	strings_dev[STRING_PRODUCT_IDX].id = id;
	device_desc.iProduct = id;

	id = usb_string_id(cdev);
	if (id < 0)
		return id;
	strings_dev[STRING_SERIAL_IDX].id = id;
	device_desc.iSerialNumber = id;

	/* Register primary, then secondary configuration.  Note that
	 * SH3 only allows one config...
	 */
	if (loopdefault) {
		loopback_add(cdev);
		if (!gadget_is_sh(gadget))
			sourcesink_add(cdev);
	} else {
		sourcesink_add(cdev);
		if (!gadget_is_sh(gadget))
			loopback_add(cdev);
	}

	gcnum = usb_gadget_controller_number(gadget);
	if (gcnum >= 0)
		device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
	else {
		/* gadget zero is so simple (for now, no altsettings) that
		 * it SHOULD NOT have problems with bulk-capable hardware.
		 * so just warn about unrcognized controllers -- don't panic.
		 *
		 * things like configuration and altsetting numbering
		 * can need hardware-specific attention though.
		 */
		pr_warning("%s: controller '%s' not recognized\n",
			longname, gadget->name);
		device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
	}


	INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname);

	snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
		init_utsname()->sysname, init_utsname()->release,
		gadget->name);

	return 0;
}