in arch/arm/src/stm32f7/stm32_otgdev.c [2237:2604]
static inline void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv,
struct stm32_ctrlreq_s *ctrlreq)
{
struct stm32_ep_s *privep;
/* Handle standard request */
switch (ctrlreq->req)
{
case USB_REQ_GETSTATUS:
{
/* type: device-to-host; recipient = device, interface, endpoint
* value: 0
* index: zero interface endpoint
* len: 2; data = status
*/
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0);
if (!priv->addressed ||
ctrlreq->len != 2 ||
USB_REQ_ISOUT(ctrlreq->type) || ctrlreq->value != 0)
{
priv->stalled = true;
}
else
{
switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK)
{
case USB_REQ_RECIPIENT_ENDPOINT:
{
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), 0);
privep = stm32_ep_findbyaddr(priv, ctrlreq->index);
if (!privep)
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS),
0);
priv->stalled = true;
}
else
{
if (privep->stalled)
{
priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT);
}
else
{
priv->ep0data[0] = 0; /* Not stalled */
}
priv->ep0data[1] = 0;
stm32_ep0in_setupresponse(priv, priv->ep0data, 2);
}
}
break;
case USB_REQ_RECIPIENT_DEVICE:
{
if (ctrlreq->index == 0)
{
usbtrace(
TRACE_INTDECODE(STM32_TRACEINTID_DEVGETSTATUS),
0);
/* Features: Remote Wakeup and self-powered */
priv->ep0data[0] =
(priv->selfpowered << USB_FEATURE_SELFPOWERED);
priv->ep0data[0] |=
(priv->wakeup << USB_FEATURE_REMOTEWAKEUP);
priv->ep0data[1] = 0;
stm32_ep0in_setupresponse(priv, priv->ep0data, 2);
}
else
{
usbtrace(
TRACE_DEVERROR(STM32_TRACEERR_BADDEVGETSTATUS),
0);
priv->stalled = true;
}
}
break;
case USB_REQ_RECIPIENT_INTERFACE:
{
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), 0);
priv->ep0data[0] = 0;
priv->ep0data[1] = 0;
stm32_ep0in_setupresponse(priv, priv->ep0data, 2);
}
break;
default:
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), 0);
priv->stalled = true;
}
break;
}
}
}
break;
case USB_REQ_CLEARFEATURE:
{
/* type: host-to-device; recipient = device, interface or endpoint
* value: feature selector
* index: zero interface endpoint;
* len: zero, data = none
*/
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0);
if (priv->addressed != 0 && ctrlreq->len == 0)
{
uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK;
if (recipient == USB_REQ_RECIPIENT_ENDPOINT &&
ctrlreq->value == USB_FEATURE_ENDPOINTHALT &&
(privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL)
{
stm32_ep_clrstall(privep);
stm32_ep0in_transmitzlp(priv);
}
else if (recipient == USB_REQ_RECIPIENT_DEVICE &&
ctrlreq->value == USB_FEATURE_REMOTEWAKEUP)
{
priv->wakeup = 0;
stm32_ep0in_transmitzlp(priv);
}
else
{
/* Actually, I think we could just stall here. */
stm32_req_dispatch(priv, &priv->ctrlreq);
}
}
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0);
priv->stalled = true;
}
}
break;
case USB_REQ_SETFEATURE:
{
/* type: host-to-device; recipient = device, interface, endpoint
* value: feature selector
* index: zero interface endpoint;
* len: 0; data = none
*/
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0);
if (priv->addressed != 0 && ctrlreq->len == 0)
{
uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK;
if (recipient == USB_REQ_RECIPIENT_ENDPOINT &&
ctrlreq->value == USB_FEATURE_ENDPOINTHALT &&
(privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL)
{
stm32_ep_setstall(privep);
stm32_ep0in_transmitzlp(priv);
}
else if (recipient == USB_REQ_RECIPIENT_DEVICE &&
ctrlreq->value == USB_FEATURE_REMOTEWAKEUP)
{
priv->wakeup = 1;
stm32_ep0in_transmitzlp(priv);
}
else if (recipient == USB_REQ_RECIPIENT_DEVICE &&
ctrlreq->value == USB_FEATURE_TESTMODE &&
((ctrlreq->index & 0xff) == 0))
{
stm32_ep0out_testmode(priv, ctrlreq->index);
}
else if (priv->configured)
{
/* Actually, I think we could just stall here. */
stm32_req_dispatch(priv, &priv->ctrlreq);
}
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0);
priv->stalled = true;
}
}
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0);
priv->stalled = true;
}
}
break;
case USB_REQ_SETADDRESS:
{
/* type: host-to-device; recipient = device
* value: device address
* index: 0
* len: 0; data = none
*/
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS),
ctrlreq->value);
if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) ==
USB_REQ_RECIPIENT_DEVICE
&& ctrlreq->index == 0 && ctrlreq->len == 0
&& ctrlreq->value < 128
&& priv->devstate != DEVSTATE_CONFIGURED)
{
/* Save the address. We cannot actually change to the next
* address until the completion of the status phase.
*/
stm32_setaddress(priv, (uint16_t) priv->ctrlreq.value[0]);
stm32_ep0in_transmitzlp(priv);
}
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0);
priv->stalled = true;
}
}
break;
case USB_REQ_GETDESCRIPTOR:
/* type: device-to-host; recipient = device, interface
* value: descriptor type and index
* index: 0 or language ID;
* len: descriptor len; data = descriptor
*/
case USB_REQ_SETDESCRIPTOR:
/* type: host-to-device; recipient = device
* value: descriptor type and index
* index: 0 or language ID;
* len: descriptor len; data = descriptor
*/
{
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0);
if (((ctrlreq->type & USB_REQ_RECIPIENT_MASK) ==
USB_REQ_RECIPIENT_DEVICE) ||
((ctrlreq->type & USB_REQ_RECIPIENT_MASK) ==
USB_REQ_RECIPIENT_INTERFACE))
{
stm32_req_dispatch(priv, &priv->ctrlreq);
}
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0);
priv->stalled = true;
}
}
break;
case USB_REQ_GETCONFIGURATION:
/* type: device-to-host; recipient = device
* value: 0;
* index: 0;
* len: 1; data = configuration value
*/
{
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0);
if (priv->addressed &&
(ctrlreq->type & USB_REQ_RECIPIENT_MASK) ==
USB_REQ_RECIPIENT_DEVICE
&& ctrlreq->value == 0 && ctrlreq->index == 0
&& ctrlreq->len == 1)
{
stm32_req_dispatch(priv, &priv->ctrlreq);
}
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0);
priv->stalled = true;
}
}
break;
case USB_REQ_SETCONFIGURATION:
/* type: host-to-device; recipient = device
* value: configuration value
* index: 0;
* len: 0; data = none
*/
{
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0);
if (priv->addressed &&
(ctrlreq->type & USB_REQ_RECIPIENT_MASK) ==
USB_REQ_RECIPIENT_DEVICE
&& ctrlreq->index == 0 && ctrlreq->len == 0)
{
/* Give the configuration to the class driver */
int ret = stm32_req_dispatch(priv, &priv->ctrlreq);
/* If the class driver accepted the configuration, then mark the
* device state as configured (or not, depending on the
* configuration).
*/
if (ret == OK)
{
uint8_t cfg = (uint8_t) ctrlreq->value;
if (cfg != 0)
{
priv->devstate = DEVSTATE_CONFIGURED;
priv->configured = true;
}
else
{
priv->devstate = DEVSTATE_ADDRESSED;
priv->configured = false;
}
}
}
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0);
priv->stalled = true;
}
}
break;
case USB_REQ_GETINTERFACE:
/* type: device-to-host; recipient = interface
* value: 0
* index: interface;
* len: 1; data = alt interface
*/
case USB_REQ_SETINTERFACE:
/* type: host-to-device; recipient = interface
* value: alternate setting
* index: interface;
* len: 0; data = none
*/
{
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0);
stm32_req_dispatch(priv, &priv->ctrlreq);
}
break;
case USB_REQ_SYNCHFRAME:
/* type: device-to-host; recipient = endpoint
* value: 0
* index: endpoint;
* len: 2; data = frame number
*/
{
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0);
}
break;
default:
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0);
priv->stalled = true;
}
break;
}
}