int16_t usbmsc_mkcfgdesc(uint8_t *buf) #endif { #ifdef CONFIG_USBDEV_DUALSPEED FAR const struct usb_epdesc_s *epdesc; bool hispeed = (speed == USB_SPEED_HIGH); uint16_t bulkmxpacket; #endif /* Configuration descriptor. If the USB mass storage device is * configured as part of a composite device, then the configuration * descriptor will be provided by the composite device logic. */ #ifndef CONFIG_USBMSC_COMPOSITE memcpy(buf, &g_cfgdesc, USB_SIZEOF_CFGDESC); buf += USB_SIZEOF_CFGDESC; #endif /* Copy the canned interface descriptor */ memcpy(buf, &g_ifdesc, USB_SIZEOF_IFDESC); buf += USB_SIZEOF_IFDESC; /* Make the two endpoint configurations */ #ifdef CONFIG_USBDEV_DUALSPEED /* Check for switches between high and full speed */ hispeed = (speed == USB_SPEED_HIGH); if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG) { hispeed = !hispeed; } bulkmxpacket = USBMSC_BULKMAXPACKET(hispeed); epdesc = USBMSC_EPBULKINDESC(hispeed); memcpy(buf, epdesc, USB_SIZEOF_EPDESC); buf += USB_SIZEOF_EPDESC; epdesc = USBMSC_EPBULKOUTDESC(hispeed); memcpy(buf, epdesc, USB_SIZEOF_EPDESC); #else memcpy(buf, &g_fsepbulkoutdesc, USB_SIZEOF_EPDESC); buf += USB_SIZEOF_EPDESC; memcpy(buf, &g_fsepbulkindesc, USB_SIZEOF_EPDESC); #endif return SIZEOF_USBMSC_CFGDESC; }
int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config) { FAR struct usbmsc_req_s *privreq; FAR struct usbdev_req_s *req; #ifdef CONFIG_USBDEV_DUALSPEED FAR const struct usb_epdesc_s *epdesc; bool hispeed = (priv->usbdev->speed == USB_SPEED_HIGH); #endif int i; int ret = 0; #ifdef CONFIG_DEBUG if (priv == NULL) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SETCONFIGINVALIDARGS), 0); return -EIO; } #endif if (config == priv->config) { /* Already configured -- Do nothing */ usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALREADYCONFIGURED), 0); return OK; } /* Discard the previous configuration data */ usbmsc_resetconfig(priv); /* Was this a request to simply discard the current configuration? */ if (config == USBMSC_CONFIGIDNONE) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CONFIGNONE), 0); return OK; } /* We only accept one configuration */ if (config != USBMSC_CONFIGID) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CONFIGIDBAD), 0); return -EINVAL; } /* Configure the IN bulk endpoint */ #ifdef CONFIG_USBDEV_DUALSPEED epdesc = USBMSC_EPBULKINDESC(hispeed); ret = EP_CONFIGURE(priv->epbulkin, epdesc, false); #else ret = EP_CONFIGURE(priv->epbulkin, usbmsc_getepdesc(USBMSC_EPFSBULKIN), false); #endif if (ret < 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKINCONFIGFAIL), 0); goto errout; } priv->epbulkin->priv = priv; /* Configure the OUT bulk endpoint */ #ifdef CONFIG_USBDEV_DUALSPEED epdesc = USBMSC_EPBULKOUTDESC(hispeed); ret = EP_CONFIGURE(priv->epbulkout, epdesc, true); #else ret = EP_CONFIGURE(priv->epbulkout, usbmsc_getepdesc(USBMSC_EPFSBULKOUT), true); #endif if (ret < 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKOUTCONFIGFAIL), 0); goto errout; } priv->epbulkout->priv = priv; /* Queue read requests in the bulk OUT endpoint */ for (i = 0; i < CONFIG_USBMSC_NRDREQS; i++) { privreq = &priv->rdreqs[i]; req = privreq->req; req->len = CONFIG_USBMSC_BULKOUTREQLEN; req->priv = privreq; req->callback = usbmsc_rdcomplete; ret = EP_SUBMIT(priv->epbulkout, req); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_RDSUBMIT), (uint16_t)-ret); goto errout; } } priv->config = config; return OK; errout: usbmsc_resetconfig(priv); return ret; }