/* * one config, two interfaces: control, data. * complications: class descriptors, and an altsetting. */ static int config_buf(struct usb_gadget *g, u8 * buf, u8 type, unsigned index, int is_otg) { int len; const struct usb_config_descriptor *config; const struct usb_descriptor_header **function; int hs = 0; if (gadget_is_dualspeed(g)) { hs = (g->speed == USB_SPEED_HIGH); if (type == USB_DT_OTHER_SPEED_CONFIG) hs = !hs; } #define which_fn(t) (hs ? hs_ ## t ## _function : fs_ ## t ## _function) debug("%s , type :%d, index %d\n", __func__, type, index); if (index >= device_desc.bNumConfigurations) return -EINVAL; config = &fastboot_config; function = which_fn(fastboot); /* for now, don't advertise srp-only devices */ /* if (!is_otg) function++; */ len = usb_gadget_config_buf(config, buf, USB_BUFSIZ, function); if (len < 0) return len; ((struct usb_config_descriptor *)buf)->bDescriptorType = type; return len; }
static int config_buf(struct usb_gadget *gadget, u8 *buf, u8 type, unsigned index) { int len; /* only one configuration */ if (index != 0) { return -EINVAL; } len = usb_gadget_config_buf(&config_desc, buf, USB_BUFSIZ, gmidi_function); if (len < 0) { return len; } ((struct usb_config_descriptor *)buf)->bDescriptorType = type; return len; }
/* * config descriptors are also handcrafted. these must agree with code * that sets configurations, and with code managing interfaces and their * altsettings. other complexity may come from: * * - high speed support, including "other speed config" rules * - multiple configurations * - interfaces with alternate settings * - embedded class or vendor-specific descriptors * * this handles high speed, and has a second config that could as easily * have been an alternate interface setting (on most hardware). * * NOTE: to demonstrate (and test) more USB capabilities, this driver * should include an altsetting to test interrupt transfers, including * high bandwidth modes at high speed. (Maybe work like Intel's test * device?) */ static int config_buf(struct usb_gadget *gadget, u8 *buf, u8 type, unsigned index) { int is_source_sink; int len; const struct usb_descriptor_header **function; int hs = 0; /* two configurations will always be index 0 and index 1 */ if (index > 1) return -EINVAL; is_source_sink = loopdefault ? (index == 1) : (index == 0); if (gadget_is_dualspeed(gadget)) { hs = (gadget->speed == USB_SPEED_HIGH); if (type == USB_DT_OTHER_SPEED_CONFIG) hs = !hs; } if (hs) function = is_source_sink ? hs_source_sink_function : hs_loopback_function; else function = is_source_sink ? fs_source_sink_function : fs_loopback_function; /* for now, don't advertise srp-only devices */ if (!gadget_is_otg(gadget)) function++; len = usb_gadget_config_buf(is_source_sink ? &source_sink_config : &loopback_config, buf, USB_BUFSIZ, function); if (len < 0) return len; ((struct usb_config_descriptor *) buf)->bDescriptorType = type; return len; }