static void ch9getstatus(u8 request_type, u16 value, u16 index, u16 length) { u16 tmp; if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) { tmp = 1 << 0; /* self powerd */ tmp |= 0 << 1; /* not remote wakeup able */ } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { tmp = 0; } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) { tmp = 0; } mxc_udc.ep0_dir = USB_DIR_IN; mxc_udc_queue_update(0, (u8 *)&tmp, 2, 0xffffffff); }
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); } }
void mxc_udc_rxqueue_update(u8 ep, u32 len) { mxc_udc_queue_update(ep, NULL, len, 0); }
static void mxc_udc_txqueue_update(u8 ep, u8 *data, u32 len) { mxc_udc_queue_update(ep, data, len, 1); }
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); } }
static void mxc_udc_txqueue_update(u8 ep, u8 *data, u32 len) { printf("[SEND DATA] EP= %d, Len = 0x%x\n", ep, len); _dump_buf(data, len); mxc_udc_queue_update(ep, data, len, 1); }