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

📄 usb_send.c

📁 linux2.4.20下的针对三星公司的s3c2410的usb模块驱动代码
💻 C
字号:
/* * * usb_send.c  * */#include <linux/module.h>#include <linux/pci.h>#include <linux/errno.h>#include <linux/delay.h>#include <asm/hardware.h>#include <asm/dma.h>#include <asm/system.h>#include <asm/byteorder.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 char *ep2_buf;static int ep2_len;static usb_callback_t ep2_callback;#ifdef USE_USBD_DMAstatic dma_addr_t ep2_dma;static dma_addr_t ep2_curdmapos;#elsestatic char *ep2_curbufpos;#endifstatic int ep2_curdmalen;static int ep2_remain;static int dmachn_tx;static int tx_pktsize;voidep2_dma_callback(void *buf_id, int size){	LOG("\n");#ifdef USE_USBD_DMA	UD_INDEX = UD_INDEX_EP2;	UD_ICSR1 |= UD_ICSR1_PKTRDY;#endif}/* device state is changing, async */voidep_bulk_in1_state_change_notify(int new_state){}/* set feature stall executing, async */voidep_bulk_in1_stall(void){	LOG("\n");	UD_INDEX = UD_INDEX_EP2;	UD_ICSR1 |= UD_ICSR1_SENDSTL;	/* send stall, force stall */}static voidep_bulk_in1_start(void){#ifndef USE_USBD_DMA	int i;#endif	LOG("\n");	if (!ep2_len) {		LOG("!ep2_len\n");		return;	}	ep2_curdmalen = tx_pktsize;	/* 64 */	if (ep2_curdmalen > ep2_remain)		ep2_curdmalen = ep2_remain;	LOG("ep2_curdmalen = %d\n", ep2_curdmalen);#ifdef USE_USBD_DMA	UD_DMAUC1 = 0x01;	UD_DMAFC1 = (u_char) ep2_curdmalen & UD_DMAFCx_DATA;	backup = UD_INDEX;	UD_INDEX = UD_INDEX_EP2;	UD_ICSR1 &= ~UD_ICSR1_CLRDT;	UD_INDEX = backup;	UD_DMACON1 = UD_DMACONx_DMAMDOE | UD_DMACONx_IRUN;	elfin_dma_queue_buffer(dmachn_tx, NULL, ep2_curdmapos, ep2_curdmalen,				 DMA_BUF_WR);#else	for (i = 0; i < ep2_curdmalen; i++) {		LOG("ep2_curbufpos[i] = 0x%02x\n", ep2_curbufpos[i]);		UD_FIFO2 = (u_char) ep2_curbufpos[i] & UD_FIFO2_DATA;	}	UD_INDEX = UD_INDEX_EP2;	UD_ICSR1 |= UD_ICSR1_PKTRDY;#endif}static voidep_bulk_in1_done(int flag){	int size = ep2_len - ep2_remain;	LOG("ep2_len = %d, ep2_remain = %d\n", ep2_len, ep2_remain);	if (ep2_len) {#ifdef USE_USBD_DMA		pci_unmap_single(NULL, ep2_dma, ep2_len, PCI_DMA_TODEVICE);#endif		ep2_len = 0;		if (ep2_callback)			ep2_callback(flag, size);	}}intep_bulk_in1_init(int chn){	desc_t *pd = elfin_usb_get_descriptor_ptr();	tx_pktsize = __le16_to_cpu(pd->b.ep2.wMaxPacketSize);	/* 64 */	LOG("tx_pktsize = %d\n", tx_pktsize);	dmachn_tx = chn;#ifdef USE_USBD_DMA	elfin_dma_flush_all(dmachn_tx);#endif	ep_bulk_in1_done(-EAGAIN);	return 0;}voidep_bulk_in1_reset(void){	desc_t *pd = elfin_usb_get_descriptor_ptr();	tx_pktsize = __le16_to_cpu(pd->b.ep2.wMaxPacketSize);	/* 64 */	LOG("tx_pktsize = %d\n", tx_pktsize);	UD_INDEX = UD_INDEX_EP2;	UD_ICSR1 &= ~(UD_ICSR1_SENDSTL);	// write 0 to clear#ifdef USE_USBD_DMA	elfin_dma_flush_all(dmachn_tx);#endif	ep_bulk_in1_done(-EINTR);}voidep_bulk_in1_int_hndlr(int udcsr){	int status;	UD_INDEX = UD_INDEX_EP2;	status = UD_ICSR1;	LOG("status = 0x%08x\n", status);	if (status & UD_ICSR1_SENTSTL) {		UD_INDEX = UD_INDEX_EP2;		UD_ICSR1 &= ~UD_ICSR1_SENTSTL;	// clear_ep1_sent_stall;		return;	}	LOG("[%d]\n", __LINE__);	if (!(status & UD_ICSR1_PKTRDY)) {		LOG("[%d]\n", __LINE__);#ifdef USE_USBD_DMA		elfin_dma_flush_all(dmachn_tx);		ep2_curdmapos += ep2_curdmalen;#else		ep2_curbufpos += ep2_curdmalen;#endif		ep2_remain -= ep2_curdmalen;		if (ep2_remain != 0) {			LOG("[%d]\n", __LINE__);			ep_bulk_in1_start();		} else {			LOG("[%d]\n", __LINE__);			ep_bulk_in1_done(0);		}	}}intelfin_usb_send(char *buf, int len, usb_callback_t callback){	int flags;	LOG("[%d]\n", __LINE__);	if (usbd_info.state != USB_STATE_CONFIGURED)		return -ENODEV;	if (ep2_len)		return -EBUSY;	local_irq_save(flags);	ep2_buf = buf;	ep2_len = len;#ifdef USE_USBD_DMA	ep2_dma = pci_map_single(NULL, ep2_buf, ep2_len, PCI_DMA_TODEVICE);	ep2_curdmapos = ep2_dma;#else	ep2_curbufpos = ep2_buf;#endif	ep2_callback = callback;	ep2_remain = len;	ep_bulk_in1_start();	local_irq_restore(flags);	return 0;}voidelfin_usb_send_reset(void){	LOG("\n");	ep_bulk_in1_reset();}intelfin_usb_xmitter_avail(void){	LOG("\n");	if (usbd_info.state != USB_STATE_CONFIGURED) {		LOG("[%d]\n", __LINE__);		return -ENODEV;	}	if (ep2_len) {		LOG("[%d]\n", __LINE__);		return -EBUSY;	}	return 0;}EXPORT_SYMBOL(elfin_usb_xmitter_avail);EXPORT_SYMBOL(elfin_usb_send);EXPORT_SYMBOL(elfin_usb_send_reset);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -