📄 usb_ep2_pxa.c
字号:
/* * Generic receive layer for the PXA USB client function * * This code was loosely inspired by the original version which was * Copyright (c) Compaq Computer Corporation, 1998-1999 * Copyright (c) 2001 by Nicolas Pitre * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * 02-May-2002 * Frank Becker (Intrinsyc) - derived from sa1100 usb_recv.c * * TODO: Add support for DMA. * */#ifdef HAVE_CONFIG_H# include <blob/config.h>#endif#include <blob/arch.h>#include <linux/errno.h>#include "pxa_usb.h"#include "usb_ctl_pxa.h"#if DEBUGstatic unsigned int usb_debug = DEBUG;#else#define usb_debug 0 /* gcc will remove all the debug code for us */#endifstatic char *ep2_buf;static int ep2_len;static int ep2_remain;static usb_callback_t ep2_callback;static int rx_pktsize;static voidep2_start(void){ /* disable DMA, RPC & SST should not be cleared */ UDCCS2 &= ~( UDCCS_BO_DME | UDCCS_BO_RPC | UDCCS_BO_SST ); /* enable interrupts for endpoint 2 (bulk out) */ UICR0 &= ~UICR0_IM2;}static voidep2_done(int flag){ int size = ep2_len - ep2_remain; if (!ep2_len) return; //SerialOutputHex("done\n"); ep2_len = 0; if (ep2_callback) { ep2_callback(flag, size); }}voidep2_state_change_notify( int new_state ){}voidep2_stall( void ){ /* SET_FEATURE force stall at UDC */ UDCCS2 |= UDCCS_BO_FST;}intep2_init(int chn){ /* int i; desc_t * pdesc = pxa_usb_get_descriptor_ptr(); for ( i = 0; i < pdesc->ep_num; i++ ) { if( BULK_OUT1 == ( 0xF & pdesc->ep[i].bEndpointAddress) ) { rx_pktsize = __le16_to_cpu( pdesc->ep[i].wMaxPacketSize ); } } */ /* FIXME */ rx_pktsize = 64; ep2_done(-EAGAIN); return 0;}voidep2_reset(void){ /* int i; desc_t * pdesc = pxa_usb_get_descriptor_ptr(); for ( i = 0; i < pdesc->ep_num; i++ ) { if( BULK_OUT1 == ( 0xF & pdesc->ep[i].bEndpointAddress) ) { rx_pktsize = __le16_to_cpu( pdesc->ep[i].wMaxPacketSize ); } } */ /* FIXME */ rx_pktsize = 64; UDCCS2 &= ~UDCCS_BO_FST; ep2_done(-EINTR);}voidep2_int_hndlr(int udcsr){ int status = UDCCS2; //if( usb_debug) printk("ep2_int_hndlr: UDCCS2=%x\n", status); if( (status & (UDCCS_BO_RNE | UDCCS_BO_RSP)) == UDCCS_BO_RSP) { /* zero-length packet */ } if( status & UDCCS_BO_RNE) { int len; int i; char *buf = ep2_buf + ep2_len - ep2_remain; /* bytes in FIFO */ len = (UBCR2 & 0xff) +1; /* if( usb_debug) printk("usb_recv: " "len=%d out1_len=%d out1_remain=%d\n", len,ep2_len,ep2_remain); */ if( len > ep2_remain) { /* FIXME: if this happens, we need a temporary overflow buffer */ //printk("usb_recv: Buffer overwrite warning...\n"); len = ep2_remain; } /* read data out of fifo */ for( i=0; i<len; i++) { *buf++ = UDDR2 & 0xff; } ep2_remain -= len; ep2_done((len) ? 0 : -EPIPE); } /* ack RPC - FIXME: '|=' we may ack SST here, too */ UDCCS2 |= UDCCS_BO_RPC; return;}intep2_recv(char *buf, int len, usb_callback_t callback){ int flags; if (ep2_len) return -EBUSY; ep2_buf = buf; ep2_len = len; ep2_callback = callback; ep2_remain = len; ep2_start(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -