static void mxc_udc_recv_setup(void) { setup_packet *s = &ep0_urb->device_request; mxc_udc_read_setup_pkt(s); if (s->wLength) { mxc_udc.ep0_dir = (s->bmRequestType & USB_DIR_IN) ? USB_DIR_OUT : USB_DIR_IN; mxc_udc_queue_update(0, NULL, 0, 0xffffffff); } if (ep0_recv_setup(ep0_urb)) { mxc_ep0_stall(); return; } switch (s->bRequest) { case USB_REQ_GET_STATUS: if ((s->bmRequestType & (USB_DIR_IN | USB_TYPE_MASK)) != (USB_DIR_IN | USB_TYPE_STANDARD)) break; ch9getstatus(s->bmRequestType, s->wValue, s->wIndex, s->wLength); return; case USB_REQ_SET_ADDRESS: if (s->bmRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE)) break; mxc_udc.setaddr = 1; mxc_udc.ep0_dir = USB_DIR_IN; mxc_udc_queue_update(0, NULL, 0, 0xffffffff); usbd_device_event_irq(udc_device, DEVICE_ADDRESS_ASSIGNED, 0); return; case USB_REQ_SET_CONFIGURATION: usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0); case USB_REQ_CLEAR_FEATURE: case USB_REQ_SET_FEATURE: { int rc = -1; if ((s->bmRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) rc = 0; else if ((s->bmRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) == (USB_RECIP_DEVICE | USB_TYPE_STANDARD)) rc = 0; else break; if (rc == 0) { mxc_udc.ep0_dir = USB_DIR_IN; mxc_udc_queue_update(0, NULL, 0, 0xffffffff); } return; } default: break; } if (s->wLength) { mxc_udc.ep0_dir = (s->bmRequestType & USB_DIR_IN) ? USB_DIR_IN : USB_DIR_OUT; mxc_udc_queue_update(0, ep0_urb->buffer, ep0_urb->actual_length, 0xffffffff); ep0_urb->actual_length = 0; } else { mxc_udc.ep0_dir = USB_DIR_IN; mxc_udc_queue_update(0, NULL, 0, 0xffffffff); } }
static void mxc_udc_recv_setup(void) { struct usb_device_request *s = &ep0_urb->device_request; mxc_udc_read_setup_pkt(s); if (s->wLength) { /* If has a data phase, * then prime a dtd for status stage which has zero length DATA0. * The direction of status stage should oppsite to direction of data phase. */ mxc_udc.ep0_dir = (s->bmRequestType & USB_DIR_IN) ? USB_DIR_OUT : USB_DIR_IN; mxc_udc_queue_update(0, NULL, 0, 0xffffffff); } if (ep0_recv_setup(ep0_urb)) { mxc_ep0_stall(); return; } switch (s->bRequest) { case USB_REQ_GET_STATUS: if ((s->bmRequestType & (USB_DIR_IN | USB_TYPE_MASK)) != (USB_DIR_IN | USB_TYPE_STANDARD)) break; ch9getstatus(s->bmRequestType, s->wValue, s->wIndex, s->wLength); DBG("[SETUP] REQ_GET_STATUS\n"); return; case USB_REQ_SET_ADDRESS: if (s->bmRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE)) break; mxc_udc.setaddr = 1; mxc_udc.ep0_dir = USB_DIR_IN; mxc_udc_queue_update(0, NULL, 0, 0xffffffff); usbd_device_event_irq(udc_device, DEVICE_ADDRESS_ASSIGNED, 0); DBG("[SETUP] REQ_SET_ADDRESS\n"); return; case USB_REQ_SET_CONFIGURATION: usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0); DBG("[SETUP] REQ_SET_CONFIGURATION\n"); case USB_REQ_CLEAR_FEATURE: case USB_REQ_SET_FEATURE: { int rc = -1; if ((s->bmRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) rc = 0; else if ((s->bmRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) == (USB_RECIP_DEVICE | USB_TYPE_STANDARD)) rc = 0; else break; if (rc == 0) { mxc_udc.ep0_dir = USB_DIR_IN; mxc_udc_queue_update(0, NULL, 0, 0xffffffff); } return; } default: break; } if (s->wLength) { mxc_udc.ep0_dir = (s->bmRequestType & USB_DIR_IN) ? USB_DIR_IN : USB_DIR_OUT; mxc_udc_queue_update(0, ep0_urb->buffer, ep0_urb->actual_length, 0xffffffff); ep0_urb->actual_length = 0; } else { mxc_udc.ep0_dir = USB_DIR_IN; mxc_udc_queue_update(0, NULL, 0, 0xffffffff); } }