📄 usb_recv.c
字号:
/* * * usb_recv.c * */#include <linux/module.h>#include <linux/pci.h>#include <linux/errno.h>#include <asm/dma.h>#include <asm/system.h>#include <linux/delay.h>#include "s3c2440_usb.h"#include "usb_ctl.h"// #define USB_DEBUG 1#ifdef USB_DEBUG#define LOG(arg...) printk(__FILE__":"__FUNCTION__"(): " ##arg)#else#define LOG(arg...) (void)(0)#endifstatic unsigned char *ep1_buf;static unsigned int ep1_len;static usb_callback_t ep1_callback;static unsigned int ep1_curdmalen;static unsigned int ep1_remain;static unsigned int dmachn_rx;static unsigned int rx_pktsize;voidep1_dma_callback(void *buf_id, int size){ LOG("\n");#ifdef USE_USBD_DMA UD_INDEX = UD_INDEX_EP1; UD_OCSR1 |= UD_OCSR1_PKTRDY;#endif}voidep_bulk_out1_state_change_notify(int new_state){}static voidep_bulk_out1_start(void){ LOG("\n");}static voidep_bulk_out1_done(int flag){ int size = ep1_len - ep1_remain; LOG(" start\n"); if (!ep1_len) return; ep1_len = ep1_curdmalen = 0; if (ep1_callback) { ep1_callback(flag, size); } LOG(" end\n");}voidep_bulk_out1_stall(void){ LOG(" start\n"); UD_INDEX = UD_INDEX_EP1; UD_OCSR1 |= UD_OCSR1_SENDSTL; /* send stall, force stall */ LOG(" end\n");}intep_bulk_out1_init(int chn){ desc_t *pd = elfin_usb_get_descriptor_ptr(); LOG(" start\n"); rx_pktsize = __le16_to_cpu(pd->b.ep1.wMaxPacketSize); LOG("rx_pktsize = %d\n", rx_pktsize); dmachn_rx = chn;#if 0 elfin_dma_flush_all(dmachn_rx);#endif ep_bulk_out1_done(-EAGAIN); LOG(" end\n"); return 0;}voidep_bulk_out1_reset(void){ desc_t *pd = elfin_usb_get_descriptor_ptr(); rx_pktsize = __le16_to_cpu(pd->b.ep1.wMaxPacketSize); LOG("rx_pktsize = %d\n", rx_pktsize); UD_INDEX = UD_INDEX_EP1; UD_OCSR1 &= ~(UD_OCSR1_SENDSTL); ep_bulk_out1_done(-EINTR);}voidep_bulk_out1_int_hndlr(int udcsr){ unsigned int len; int status; int recv_cnt; UD_INDEX = UD_INDEX_EP1; status = UD_OCSR1; LOG("0x%02x\n", UD_OCSR1); LOG("0x%02x\n", UD_OCSR2); LOG("0x%02x\n", UD_ICSR1); LOG("0x%02x\n", UD_ICSR2); if (status & UD_OCSR1_SENTSTL) { UD_INDEX = UD_INDEX_EP1; UD_OCSR1 &= ~UD_OCSR1_SENTSTL; LOG("UD_OCSR1_SENTSTL\n"); return; //?? !! } if (status & UD_OCSR1_PKTRDY) { /* sa狼 Receive Packet Complete, s3c2440俊绰 绝促. OPR甫 捞侩茄促. */ LOG("ep1_len=%x\n", ep1_len); if (!ep1_len) { printk("usb_recv: RPC for non-existent buffer\n"); UD_INDEX = UD_INDEX_EP1; UD_OCSR1 |= UD_OCSR1_FFLUSH; //udelay(20); UD_INDEX = UD_INDEX_EP1; UD_OCSR1 &= ~UD_OCSR1_PKTRDY; return; } UD_INDEX = UD_INDEX_EP1; recv_cnt = ((UD_OFCNTH << 8) | UD_OFCNTL) & 0xffff; LOG("recv_count = %d\n", recv_cnt); for (len = 0; len < recv_cnt; len++) { ep1_buf[len] = (u_char) UD_FIFO1; LOG("ep1_buf[%d]=%x\n", len, ep1_buf[len]); } ep1_remain -= recv_cnt; ep_bulk_out1_done(0); UD_INDEX = UD_INDEX_EP1; UD_OCSR1 &= ~UD_OCSR1_PKTRDY; //shaju added for USB last packet loss if(((UD_OCSR1&0x01) == 1) && ((UD_INT &0x8)==0) ) { UD_INDEX = UD_INDEX_EP1; recv_cnt = ((UD_OFCNTH << 8) | UD_OFCNTL) & 0xffff; LOG("recv_count = %d\n", recv_cnt); for (len = 0; len < recv_cnt; len++) { ep1_buf[len] = (u_char) UD_FIFO1; LOG("ep1_buf[%d]=%x\n", len, ep1_buf[len]); } ep1_remain -= recv_cnt; ep_bulk_out1_done(0); UD_INDEX = UD_INDEX_EP1; UD_OCSR1 &= ~UD_OCSR1_PKTRDY; } }}intelfin_usb_recv(char *buf, int len, usb_callback_t callback){ int flags; LOG("\n"); if (ep1_len) return -EBUSY; local_irq_save(flags); ep1_buf = buf; ep1_len = len; ep1_callback = callback; ep1_remain = len; ep_bulk_out1_start(); local_irq_restore(flags); return 0;}voidelfin_usb_recv_reset(void){ LOG("\n"); ep_bulk_out1_reset();}voidelfin_usb_recv_stall(void){ LOG("\n"); ep_bulk_out1_stall();}EXPORT_SYMBOL(elfin_usb_recv);EXPORT_SYMBOL(elfin_usb_recv_reset);EXPORT_SYMBOL(elfin_usb_recv_stall);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -