int usb_drv_send_nonblocking(int ep, void *ptr, int len) { logf("usb_drv_send_nonblocking(%d,%x,%d): ", ep, (int)ptr, len); ep &= 0x7f; endpoints[ep][0].state |= EP_STATE_ASYNC; ep_send(ep, ptr, len); return 0; }
int usb_drv_send(int endpoint, void *ptr, int length) { endpoint &= 0x7f; endpoints[endpoint].done = false; ep_send(endpoint, ptr, length); while (!endpoints[endpoint].done && endpoints[endpoint].busy) semaphore_wait(&endpoints[endpoint].complete, TIMEOUT_BLOCK); return endpoints[endpoint].rc; }
/* config: ? TODO */ void set_configration(int config) { if (config) { //TODO: add what? } //just response an 0-Byte DATA packet ep_send(0, NULL, 0); }
int usb_drv_send(int ep, void *ptr, int len) { logf("usb_drv_send(%d,%x,%d): ", ep, (int)ptr, len); ep &= 0x7f; if (ep == 0 && got_set_configuration) { got_set_configuration = 0; if (len != 0) panicf("usb_drv_send: GSC, but len!=0"); /* Tell the HW we handled the request */ USB_DEV_CTRL |= USB_DEV_CTRL_APCSR_DONE; return 0; } ep_send(ep, ptr, len); if (semaphore_wait(&endpoints[ep][0].complete, HZ) == OBJ_WAIT_TIMEDOUT) logf("send timed out!\n"); return endpoints[ep][0].rc; }
int usb_drv_send_nonblocking(int endpoint, void *ptr, int length) { ep_send(endpoint & 0x7f, ptr, length); return 0; }
int handle_packet_setup(struct ep_buf *ep) { #define REQUEST_TYPE ((1<<6)|(1<<5)) #define REQUEST_TYPE_STDARD 0 #define REQUEST_TYPE_CLASS ((0<<6)|(1<<5)) #define REQUEST_TYPE_VENDOR ((1<<6)|(0<<5)) #define REQUEST_TYPE_RESERVED ((1<<6)|(1<<5)) int send_len; //<---------------------- rt_uint8_t bmRequestType; rt_uint8_t bRequest; rt_uint16_t wValue; rt_uint16_t wIndex; rt_uint16_t wLength; bmRequestType = ep->buffer[0]; bRequest = ep->buffer[1]; wValue = net2host_16bit(&ep->buffer[2]); wIndex = net2host_16bit(&ep->buffer[4]); wLength = net2host_16bit(&ep->buffer[6]); DUMPHEX(ep->buffer, ep->len); if (bmRequestType & 0x80) { //IN switch (bmRequestType & REQUEST_TYPE) { case REQUEST_TYPE_STDARD: TRACE("USB input stdard reqeust:"); switch(bRequest) { case GET_STATUS : TRACE("get_status\n"); break; case CLEAR_FEATURE : TRACE("clear_feature\n"); break; case SET_FEATURE : TRACE("set_feature\n"); break; case SET_ADDRESS : TRACE("set_address\n"); break; case GET_DESCRIPTOR : { TRACE("get_descriptor: "); switch (wValue >> 8) // descriptor type; { case DESC_DEVICE: { TRACE("device_desc\n"); RT_ASSERT(send_len <= 64); //FIXME ep_send(0, DeviceDesc.desc, DeviceDesc.len); break; } case DESC_CONFIGURATION: TRACE("config_desc [%d]\n", ConfigDesc.len); //send_len = MIN(wLength, ConfigDesc.len); //RT_ASSERT(send_len <= 64); //FIXME //ep_send(0, ConfigDesc.desc, send_len); send_status.ep = 0; send_status.total = MIN(ConfigDesc.len, wLength); send_len = MIN(send_status.total, EP0_PACKET_SIZE); ep_send(0, ConfigDesc.desc, send_len); send_status.sent = send_len; send_status.buf =ConfigDesc.desc; break; case DESC_STRING: TRACE("string_desc:%d-->",(wValue & 0xFF)); if ((wValue & 0xFF) < 4) { static u8 str_buf[256]; static const struct descriptor * p; TRACE("%s\n", str_desc_name_table[wValue & 0xFF]); p = &StringDescTable[(wValue & 0xFF)]; memcpy(str_buf, p->desc, p->len); str_buf[0] = p->len; RT_ASSERT(p->len <= 64); ep_send(0, str_buf, p->len); } else { TRACE("-->bad argument!\n"); } break; case DESC_INTERFACE: TRACE("interface_desc\n"); break; case DESC_ENDPOINT: TRACE("endpoint_desc\n"); break; case DESC_REPORT: TRACE("report_desc [%d]\n", wIndex); //FIXME: refine code if (wIndex >= sizeof(ReportDesc)/sizeof(ReportDesc[0])) { TRACE("\t\t-->invalid number\n"); break; } send_status.ep = 0; send_status.total = ReportDesc[wIndex].len; send_len = MIN(ReportDesc[wIndex].len, EP0_PACKET_SIZE); ep_send(0, ReportDesc[wIndex].desc, send_len); send_status.sent = send_len; send_status.buf = ReportDesc[wIndex].desc; break; default: TRACE("<%d> unknown_desc!\n", wValue >> 8); break; } break; } case SET_DESCRIPTOR : TRACE("set_descriptor\n"); break; case GET_CONFIGURATION : TRACE("get_configuration\n"); break; case SET_CONFIGURATION : TRACE("set_configration\n"); break; case GET_INTERFACE : TRACE("get_interface\n"); break; case SET_INTERFACE : TRACE("set_interface\n"); break; case SYNCH_FRAME : TRACE("synch_frame\n"); break; default: TRACE("unkown!\n"); break; } break; case REQUEST_TYPE_CLASS: TRACE("USB input Class qeuset:"); switch(bRequest) { case GET_REPORT: TRACE("GET_REPORT\n"); break; case GET_IDLE: TRACE("GET_IDLE\n"); break; case GET_PROTOCOL: TRACE("GET_PROTOCOL\n"); break; case SET_REPORT: TRACE("SET_REPORT\n"); break; case SET_IDLE: TRACE("SET_IDLE\n"); break; case SET_PROTOCOL: TRACE("SET_PROTOCOL\n"); break; //for CDC class case CDC_GET_LINE_CODING: TRACE("CDC_GET_LINE_CODING [%d]\n", wLength); { #define UART_BSP 115200 static char vcom_line_coding[7] = { // dwDTERate 4Bytes UART_BSP & 0xFF, UART_BSP >> 8, UART_BSP >> 16, UART_BSP >> 24, 0, // bCharFormat 0, // bParityType 8, // bDataBits }; RT_ASSERT(wLength < EP0_PACKET_SIZE); ep_send(0, vcom_line_coding, wLength); } break; default: TRACE("bad request!\n"); break; } break; case REQUEST_TYPE_VENDOR: TRACE("USB input Vendor qeuset\n"); break; case REQUEST_TYPE_RESERVED: TRACE("USB input Reserved qeuset\n"); break; } } else { //OUT switch (bmRequestType & REQUEST_TYPE)