📄 usb_ep0.c
字号:
pszMe, req.wValue); } set_ep0_de_out; break; case GET_STATUS: clear_ep0_opr; UD_FIFO0 = device_status; UD_FIFO0 = 0x00; set_ep0_de_in; break; case GET_CONFIGURATION: clear_ep0_opr; UD_FIFO0 = set_configuration; set_ep0_de_in; break; case GET_DESCRIPTOR: get_descriptor(req); break; default: set_ep0_de_out; } break; /* Interface Recipient */ case kTargetInterface: switch (req.bRequest) { case SET_INTERFACE: set_interface = req.wValue; set_ep0_de_out; break; case GET_INTERFACE: clear_ep0_opr; UD_FIFO0 = set_interface; set_ep0_de_in; break; } break; case kTargetEndpoint: switch (req.bRequest) { case SET_FEATURE: set_feature(req); break; case CLEAR_FEATURE: clear_feature(req); break; case GET_STATUS: clear_ep0_opr; e = windex_to_ep_num(req.wIndex); if (e == 0) { UD_FIFO0 = ep0_status; UD_FIFO0 = 0x00; } else if (e == 2) { UD_FIFO0 = ep_bulk_in_status; UD_FIFO0 = 0x00; } else if (e == 1) { UD_FIFO0 = ep_bulk_out_status; UD_FIFO0 = 0x00; } set_ep0_de_in; break; case GET_DESCRIPTOR: get_descriptor(req); break; } }}static voidget_descriptor(usb_dev_request_t req){ string_desc_t *pString; ep_desc_t * pEndpoint = 0; desc_t *pDesc = elfin_usb_get_descriptor_ptr(); int type = req.wValue >> 8; int idx = req.wValue & 0xFF; switch (type) { case USB_DESC_DEVICE: PRINTKD("\nget descriptor() DEV: req.wLengh=%d, pDesc->dev.bength=%d\n\n", req.wLength, pDesc->dev.bLength); clear_ep0_opr; queue_and_start_write(&pDesc->dev, req.wLength, pDesc->dev.bLength); break; case USB_DESC_CONFIG: clear_ep0_opr;#if defined(CONFIG_S3C2440_USB_CDC_ENCM) || defined(CONFIG_S3C2440_USB_CDC_ENCM_MODULE) if (pDesc->dev.bDeviceClass == CDC_DEVICE_CLASS) { queue_and_start_write(&pDesc->cdc_b, req.wLength, sizeof (struct cdc_cdb)); } else { queue_and_start_write(&pDesc->b, req.wLength, sizeof (struct cdb)); }#else queue_and_start_write(&pDesc->b, req.wLength, sizeof (struct cdb));#endif /* CONFIG_S3C2440_USB_CDC_ENCM || CONFIG_S3C2440_USB_CDC_ENCM_MODULE */ PRINTKD("\nget descriptor() CONFIG: req.wLengh=%d, pDesc->dev.bength=%d\n\n", req.wLength, pDesc->dev.bLength); break; case USB_DESC_STRING: PRINTKD("STRING STRING\n"); pString = elfin_usb_get_string_descriptor(idx); if (pString) { if (idx != 0) { // if not language index printk("%sReturn string %d: ", pszMe, idx); psdesc(pString); } PRINTKD("\nget descriptor() String: req.wLengh=%d, pDesc->dev.bength=%d\n\n", req.wLength, pDesc->dev.bLength); clear_ep0_opr; queue_and_start_write(pString, req.wLength, pString->bLength); } break; case USB_DESC_INTERFACE:#if defined(CONFIG_S3C2440_USB_CDC_ENCM) || defined(CONFIG_S3C2440_USB_CDC_ENCM_MODULE) if (pDesc->dev.bDeviceClass == CDC_DEVICE_CLASS) { if (idx == pDesc->cdc_b.comm_intf.bInterfaceNumber) { printk("CDC_DEVICE_CLASS:intf\n"); clear_ep0_opr; queue_and_start_write(&pDesc->cdc_b.comm_intf, req.wLength, pDesc->cdc_b.comm_intf.bLength + pDesc->cdc_b.func.hdr.bLength + pDesc->cdc_b.func.uni.bLength + pDesc->cdc_b.func.eth.bLength); }#ifdef CDC_ALTERNATE_INTERFACE else if (idx == pDesc->cdc_b.data_intf0.bInterfaceNumber) { printk("CDC_DEVICE_CLASS:intf0\n"); clear_ep0_opr; queue_and_start_write(&pDesc->cdc_b.data_intf0, req.wLength, pDesc->cdc_b.data_intf0.bLength); }#endif /* CDC_ALTERNATE_INTERFACE */ else if (idx == pDesc->cdc_b.data_intf1.bInterfaceNumber) { printk("CDC_DEVICE_CLASS:intf1\n"); clear_ep0_opr; queue_and_start_write( &pDesc->cdc_b.data_intf1, req.wLength, pDesc->cdc_b.data_intf1.bLength); } } else { if (idx == pDesc->b.intf.bInterfaceNumber) { printk("intf\n"); clear_ep0_opr; queue_and_start_write(&pDesc->b.intf, req.wLength, pDesc->b.intf.bLength); } }#else if (idx == pDesc->b.intf.bInterfaceNumber) { clear_ep0_opr; queue_and_start_write(&pDesc->b.intf, req.wLength, pDesc->b.intf.bLength); }#endif /* CONFIG_S3C2440_USB_CDC_ENCM || CONFIG_S3C2440_USB_CDC_ENCM_MODULE */ break; case USB_DESC_ENDPOINT: /* correct? 21Feb01ww */ if ( idx == 1 ) pEndpoint = &pDesc->b.ep1; //[BULK_IN1]; else if ( idx == 2 ) pEndpoint = &pDesc->b.ep2; //[BULK_OUT1]; else pEndpoint = NULL; if ( pEndpoint ) { clear_ep0_opr; queue_and_start_write( pEndpoint, req.wLength, pEndpoint->bLength ); } else { printk("%sunkown endpoint index %d Stall.\n", pszMe, idx ); } break; default: clear_ep0_opr; set_ep0_de_in; break; }}static voidep0_transmit(void){ int i, data_length; __u32 reg_ep0_status; __u32 reg_int_status; UD_INDEX = UD_INDEX_EP0; reg_ep0_status = UD_ICSR1; PRINTKD("EP0 want to send : %d byte\n", wr.transfer_length); /* ep0 input fifo check */ if ((reg_ep0_status & EP0_CSR_IPKRDY) == 0) { data_length = wr.transfer_length - wr.transfered_data; data_length = MIN(data_length, EP0_FIFO_SIZE); /* EP0 MAX Packet size */ /* need to check RESET, RESUME and SUSPEND Interrupts */ reg_int_status = UD_USBINT; reg_int_status &= UD_USBINT_RESET | UD_USBINT_RESUM | UD_USBINT_SUSPND; if (reg_int_status == UD_USBINT_RESET) return; PRINTKD(" SENDING... ["); for (i = 0; i < data_length; i++) { UD_FIFO0 = *wr.p; PRINTKD("%2.2X ", *wr.p); wr.p++; wr.transfered_data++; } PRINTKD("] \n"); PRINTKD("EP0 transfered : %d bytes\n", wr.transfered_data); PRINTKD("wr.transfered_data = %d, wr.transfer_length = %d\n", wr.transfered_data, wr.transfer_length); if (wr.transfered_data == wr.transfer_length) { reg_int_status = UD_USBINT; reg_int_status &= UD_USBINT_RESET | UD_USBINT_RESUM | UD_USBINT_SUSPND; if (reg_int_status == UD_USBINT_RESET) return;// if (((wr.transfer_length % 8) == 0) && control_complete == 0) { if (control_complete == 0) { control_complete = 1; set_ep0_ipr; } else { control_complete = 0; set_ep0_de_in; ep0_state = EP0_STATE_IDLE; } return; } set_ep0_ipr; }}static voidset_feature(usb_dev_request_t req){ int ep; switch (req.wValue) { case fEndpoint_Halt: ep = windex_to_ep_num(req.wIndex); if (ep == 0) { printk("%sset feature [endpoint halt] on control\n", pszMe); ep0_status = 0x001; set_ep0_ss; clear_ep0_opr; } else if (ep == 2) { printk("%set feature [endpoint halt] on xmitter\n", pszMe); ep_bulk_in_status = 0x0001; UD_INDEX = UD_INDEX_EP2; UD_ICSR1 |= UD_ICSR1_CLRDT; //ep2_stall(); } else if (ep == 1) { printk("%set feature [endpoint halt] on receiver\n", pszMe); ep_bulk_out_status = 0x0001; UD_INDEX = UD_INDEX_EP1; UD_OCSR1 |= UD_OCSR1_SENDSTL; //ep1_stall(); } else { printk ("%sUnsupported feature selector (%d) in set feature\n", pszMe, req.wValue); set_ep0_de_out; } break; case fDevice_Remote_Wakeup: device_status = 0x02; set_ep0_de_out; break; default: set_ep0_de_out; break; }}static voidclear_feature(usb_dev_request_t req){ int ep; switch (req.wValue) { case fEndpoint_Halt: ep = windex_to_ep_num(req.wIndex); if (ep == 0) // ep0 ep0_status = 0x0000; else if (ep == 2) { // ep2 input ep_bulk_in_status = 0x0000; clear_stall_ep4_out; // ep4?? PRINTKD(__FUNCTION__ "(): confused. - bushi\n"); } else if (ep == 1) { // ep1 output ep_bulk_out_status = 0x0000; clear_stall_ep1_out; //?? } else PRINTKD("%sUnsupported endpoint (%d)\n", pszMe, ep); set_ep0_de_out; break; case fDevice_Remote_Wakeup: device_status = 0x00; set_ep0_de_out; break; default: set_ep0_de_out; break; }}static void queue_and_start_write( void * data, int req, int act ){ PRINTKD( "write start: bytes requested=%d actual=%d\n", req, act); wr.p = (unsigned char*) data; wr.transfer_length = wr.bytes_left = MIN( act, req ); wr.transfered_data = 0; ep0_state = EP0_STATE_TRANSFER; ep0_transmit(); return;}static voidset_descriptor(void){ set_ep0_de_out;}static voidep0_receive(void){}/* * read_fifo() * Read 1-8 bytes out of FIFO and put in request. * Called to do the initial read of setup requests * from the host. Return number of bytes read. * * Like write fifo above, this driver uses multiple * reads checked agains the count register with an * overall timeout. * */static intread_fifo(usb_dev_request_t * request){ int bytes_read = 0; int fifo_count = 0; int i, ep; unsigned char *pOut = (unsigned char *) request; ep = windex_to_ep_num(request->wIndex); PRINTKD(__FUNCTION__ "(): ep = %d\n", ep); switch (ep) { case 0: UD_INDEX = UD_INDEX_EP0; break; case 1: UD_INDEX = UD_INDEX_EP1; break; case 2: UD_INDEX = UD_INDEX_EP2; break; default: PRINTKD(__FUNCTION__ "(): ???? ep = %d\n", ep); UD_INDEX = UD_INDEX_EP0; } fifo_count = ((UD_OFCNTH << 8) | UD_OFCNTL) & 0xffff; ASSERT(fifo_count <= EP0_FIFO_SIZE); PRINTKD(__FUNCTION__ "(): fifo_count =%d ", fifo_count); while (fifo_count--) { i = 0; do { *pOut = (unsigned char) UD_FIFO0; udelay(10); i++; } while ((((UD_OFCNTH << 8) | UD_OFCNTL) & 0xffff) != fifo_count && i < 10); if (i == 10) { printk("%sread_fifo(): read failure\n", pszMe); usbd_info.stats.ep0_fifo_read_failures++; } pOut++; bytes_read++; } PRINTKD("bytes_read=%d\n", bytes_read); usbd_info.stats.ep0_bytes_read++; return bytes_read;}/* end usb_ep0.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -