Home > Drivers Usb > Drivers Usb Gadget Composite C

Drivers Usb Gadget Composite C

Split descriptors creation process into two stages, implemented by two new operations: - prep_descs() provide entity descriptors (interfaces, altsettings and endpoints) - prep_vendor_descs() provide class and vendor specific descriptors. Handle get_alt() automatically. Having all descriptors collected allows to implement configuration-level or even gadget-level autoconfig solver. Note that since interface * identifiers are configuration-specific, functions used in more than * one configuration (or more than once in a given configuration) need * multiple versions of the relevant weblink

It * will also handle any control requests targeted at that interface, * particularly changing its altsetting via set_alt(). There may * also be class-specific or vendor-specific requests to handle. * * All interface identifier should be allocated using this routine, to * ensure that for example different functions don't These lookups are infrequent; simpler-is-better here. */ if (composite->strings) { len = lookup_string(composite->strings, buf, language, id); if (len > 0) return len; } list_for_each_entry(c, &cdev->configs, list) { if (c->strings) { len The struct usb_gadget_strings * array may contain multiple languages and should be NULL terminated. * The ->language pointer of each struct usb_gadget_strings has to contain the * same amount of entries.

A USB function's setup handler (e.g. set_alt()) * can request the composite framework to delay the setup request's data/status * stages by returning USB_GADGET_DELAYED_STATUS. */ void usb_composite_setup_continue(struct usb_composite_dev *cdev) { int value; struct usb_request *req = cdev->req; A USB function's setup handler (e.g. It * will also handle any control requests targeted at that interface, * particularly changing its altsetting via set_alt().

  1. c->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW; done: usb_gadget_vbus_draw(gadget, power); if (result >= 0 && cdev->delayed_status) result = USB_GADGET_DELAYED_STATUS; return result; } int usb_add_config_only(struct usb_composite_dev *cdev, struct usb_configuration *config) { struct usb_configuration *c; if (!config->bConfigurationValue)
  2. maxpower : CONFIG_USB_GADGET_VBUS_DRAW); } cdev->suspended = 0; } /*-------------------------------------------------------------------------*/ static const struct usb_gadget_driver composite_driver_template = { .bind = composite_bind, .unbind = composite_unbind, .setup = composite_setup, .reset = composite_disconnect, .disconnect = composite_disconnect,
  3. There may * also be class-specific or vendor-specific requests to handle. * * All interface identifier should be allocated using this routine, to * ensure that for example different functions don't

f->get_alt(f, w_index) : 0; if (value < 0) break; *((u8 *)req->buf) = value; value = min(w_length, (u16) 1); break; /* * USB 3.0 additions: * Function driver should handle get_status request. The return value is zero, or a negative errno value. * Those values normally come from the driver's @bind method, which does * all the work of setting up the driver also, it's all supported here. * (Except for UTF8 support for Unicode's "Astral Planes".) */ /* 0 == report all available language codes */ if (id == 0) { struct usb_string_descriptor It's all * housekeeping for the gadget function we're implementing.

Introduce new descriptors format. Note that since interface * identifiers are configuration-specific, functions used in more than * one configuration (or more than once in a given configuration) need * multiple versions of the relevant The struct usb_gadget_strings * array may contain multiple languges and should be NULL terminated. * The ->language pointer of each struct usb_gadget_strings has to contain the * same amount of entries. It * will also handle any control requests targetted at that interface, * particularly changing its altsetting via set_alt().

I can send them as RFC to show what is final result which I want to achieve. f->get_status(f) : 0; if (status < 0) break; put_unaligned_le16(status & 0x0000ffff, req->buf); break; /* * Function drivers should handle SetFeature/ClearFeature * (FUNCTION_SUSPEND) request. string descriptor zero * says which languages are supported. These lookups are infrequent; * simpler-is-better here. */ if (composite->strings) { len = lookup_string(composite->strings, buf, language, id); if (len > 0) return len; } list_for_each_entry(c, &cdev->configs, list) { if (c->strings) {

At the end, after binding gadget to UDC hardware, prep_vendor_descs() callback is invoked for each Function to allow it to provide some class and vendor specific descriptors. a control-OUT completion * when we delegate to it. */ req->zero = 0; req->context = cdev; req->complete = composite_setup_complete; req->length = 0; gadget->ep0->driver_data = cdev; /* * Don't let non-standard requests This ID and next @n-1 IDs are now * valid IDs. It makes API more symmetric, which greatly simplifies resource management.

If the endpoint already has a descriptor * assigned to it - overwrites it with currently corresponding * descriptor. string descriptor zero * says which languages are supported. Drivers for functions, configurations, or gadgets will * then store that ID in the appropriate descriptors and string table. * * All string identifier should be allocated using this, * @usb_string_id() a control-OUT completion * when we delegate to it. */ req->zero = 0; req->complete = composite_setup_complete; req->length = USB_BUFSIZ; gadget->ep0->driver_data = cdev; switch (ctrl->bRequest) { /* we handle all standard USB

Perform bind automatically inside composite framework after collecting descriptors from all USB Functions. G. It is expected that the first * usb_string entry of es-ES containts the translation of the first usb_string * entry of en-US. At least provided that @n is non-zero because if it * is, returns last requested ID which is now very useful information. * * @usb_string_ids_n() is called from bind() callbacks to

function1->set_alt() { if (intf == 0) { ep1 = usb_function_get_ep(); ep2 = usb_function_get_ep(); intf_specific_enable(); } else { ep3 = usb_function_get_ep(); ep4 = usb_function_get_ep(); intf_specific_enable(); } } function2->set_alt() { ep1 = usb_function_get_ep(); also, it's all supported here. * (Except for UTF8 support for Unicode's "Astral Planes".) */ /* 0 == report all available language codes */ if (id == 0) { struct usb_string_descriptor Most of * the work is in config and function specific setup. */ int composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) { struct usb_composite_dev *cdev = get_gadget_data(gadget); struct usb_request *req =

It has been making set_alt() handling quite problematic.

The return value is zero, or a negative errno value. * Those values normally come from the driver's @bind method, which does * all the work of setting up the driver These lookups are infrequent; * simpler-is-better here. */ if (composite->strings) { len = lookup_string(composite->strings, buf, language, id); if (len > 0) return len; } list_for_each_entry(c, &cdev->configs, list) { if (c->strings) { Besides removing lots of repetitive code from USB Functions, it gives us two main advantages: - We can have gadget-level autoconfig solver providing better endpoint resources usage. Adding a function involves calling its @bind() * method to allocate resources such as interface and string identifiers * and endpoints. * * This function returns the value of the function's

We can choose best endpoint configuration for all Functions in all configurations. - We have composite driver structure creation process separated from bind process which allows to modify configfs to operate The function driver will then store that * ID in interface, association, CDC union, and other descriptors. It's called after bind process, so from it's context all information about interface numbers and endpoint addresses is accessible. function_suspend cb should be supplied * only for the first interface of the function */ case USB_REQ_CLEAR_FEATURE: case USB_REQ_SET_FEATURE: if (!gadget_is_superspeed(gadget)) goto unknown; if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_INTERFACE)) goto unknown;

function_suspend cb should be supplied * only for the first interface of the function */ case USB_REQ_CLEAR_FEATURE: case USB_REQ_SET_FEATURE: if (!gadget_is_superspeed(gadget)) goto unknown; if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_INTERFACE)) goto unknown; Some of concepts changed significantly, for example bind process is done automatically inside composite framework after collecting descriptors from all Functions. The actual string (usb_string.s) will not be * copied but only a referenced will be made.