⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_recv.c

📁 linux2.4.20下的针对三星公司的s3c2410的usb模块驱动代码
💻 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 + -