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

📄 dm320.c.svn-base

📁 TI DM320处理器支持的linux usb device侧驱动程序
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
    struct dm320_request    *req;    ep = container_of (_ep, struct dm320_ep, ep);    if (!_ep || !_req)        return;    req = container_of (_req, struct dm320_request, req);    kfree (req);	}static void *dm320_alloc_buffer (struct usb_ep *_ep,unsigned bytes,dma_addr_t *dma,int gfp_flags){    void            *retval;    struct dm320_ep *ep;    ep = container_of (_ep, struct dm320_ep, ep);    if (!_ep)        return NULL;    retval = kmalloc (bytes, gfp_flags);    return retval;}static voiddm320_free_buffer(struct usb_ep *_ep,void *buf,dma_addr_t dma,unsigned bytes){    kfree (buf);}static struct usb_ep_ops dm320_ep_ops = {	.enable		= dm320_enable,	.disable	= dm320_disable,		.alloc_request	= dm320_alloc_request,	.free_request	= dm320_free_request,	.alloc_buffer	= dm320_alloc_buffer,	.free_buffer	= dm320_free_buffer,	.queue		= dm320_queue,	.dequeue	= dm320_dequeue,	.set_halt	= dm320_set_halt,	.fifo_status	= dm320_fifo_status,	.fifo_flush	= dm320_fifo_flush,};/* when a driver is successfully registered, it will receive * control requests including set_configuration(), which enables * non-control requests.  then usb traffic follows until a * disconnect is reported.  then a host may connect again, or * the driver might get unbound. */static int usb_gadget_register_driver (struct usb_gadget_driver *driver){	struct usb_ctrlrequest  r;	int			retval = -22; 	unsigned		i;	if (!driver			|| (driver->speed != USB_SPEED_FULL)			|| !driver->bind			|| !driver->unbind			|| !driver->setup) {		return -EINVAL;	}	if (!the_controller)		return -ENODEV;	if (the_controller->driver)		return -EBUSY;	for (i = 0; i < 4; i++)		the_controller->ep [i].irqs = 0;	/* hook up the driver ... */	the_controller->softconnect = 1;	driver->driver.bus = NULL;		the_controller->driver = driver;	the_controller->gadget.dev.driver = &driver->driver;	retval = driver->bind (&the_controller->gadget);	if (retval) {		DEBUG (the_controller, "bind to driver %s --> %d\n",				driver->driver.name, retval);		the_controller->driver = NULL;		return retval;	}	/* ... then enable host detection and ep0; and we're ready	 * for set_configuration as well as eventual disconnect.	 */	ep0_start (the_controller);	return 0;}EXPORT_SYMBOL (usb_gadget_register_driver);static int usb_gadget_unregister_driver (struct usb_gadget_driver *driver){	struct dm320	*dev = the_controller;	unsigned long	flags;	if (!dev)		return -ENODEV;	if (!driver || driver != dev->driver)		return -EINVAL;	spin_lock_irqsave (&dev->lock, flags);	stop_activity (dev, driver);	spin_unlock_irqrestore (&dev->lock, flags);	//dm320_pullup (&dev->gadget, 0);	driver->unbind (&dev->gadget);	dev->driver = NULL;	printk("unregistered driver '%s'\n", driver->driver.name);	return 0;}EXPORT_SYMBOL (usb_gadget_unregister_driver);static int dm320_get_frame (struct usb_gadget *_gadget){	struct dm320		*dev;	unsigned long		flags;	u16			retval;	if (!_gadget)		return -ENODEV;	dev = container_of (_gadget, struct dm320, gadget);	spin_lock_irqsave (&dev->lock, flags);	retval = readb(USB_FRAME2) << 8;  /*read frame reg: 16bit value */	retval |= readb(USB_FRAME1);	spin_unlock_irqrestore (&dev->lock, flags);	return retval;}static int dm320_wakeup (struct usb_gadget *_gadget){	struct dm320		*dev;	u8			tmp;	unsigned long		flags;	if (!_gadget)		return 0;	dev = container_of (_gadget, struct dm320, gadget);	spin_lock_irqsave (&dev->lock, flags);	writeb (USB_POWER_RESUME,USB_POWER);	spin_unlock_irqrestore (&dev->lock, flags);	return 0;}static int dm320_set_selfpowered (struct usb_gadget *_gadget, int value){	struct dm320		*dev;	if (!_gadget)		return -ENODEV;	dev = container_of (_gadget, struct dm320, gadget);	dev->is_selfpowered = value;	return 0;}static int dm320_pullup (struct usb_gadget *_gadget, int is_on){	struct dm320		*dev;	unsigned long		flags;	if (!_gadget)		return -ENODEV;	dev = container_of (_gadget, struct dm320, gadget);	spin_lock_irqsave (&dev->lock, flags);	dev->softconnect = (is_on != 0);	if (is_on)	{		/* Vishal: Code to enable detectiong of plug/unplug */		gio_set_bitset( GIO_DP_PULLUP );		// set D+ pullup	}	else	{		gio_set_bitclr( GIO_DP_PULLUP );		// clear D+ pullup		/* Vishal: Code to enable detectiong of plug/unplug */	}	spin_unlock_irqrestore (&dev->lock, flags);	return 0;}static const struct usb_gadget_ops dm320_ops = {	.get_frame		= dm320_get_frame,	.wakeup			= dm320_wakeup,	.set_selfpowered	= dm320_set_selfpowered,};static struct dm320_ep *get_ep_by_addr (struct dm320 *dev, u16 wIndex){	struct dm320_ep	*ep;	if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)		return &dev->ep [0];		list_for_each_entry (ep, &dev->gadget.ep_list, ep.ep_list) {		u8	bEndpointAddress;		if (!ep->desc)			continue;		bEndpointAddress = ep->desc->bEndpointAddress;		if ((wIndex ^ bEndpointAddress) & USB_DIR_IN)			continue;		if ((wIndex & 0x0f) == (bEndpointAddress & 0x0f))			return ep;	}	return NULL;}static int    dm320_read_intr_regs( void ){    unsigned int    nIntrTx     = readb( USB_INTRTX1 ) & 0xFF;    unsigned int    nIntrRx     = readb( USB_INTRRX1 ) & 0xFF;    unsigned int    nIntrUSB    = readb( USB_INTRUSB ) & 0xFF;    return( ( nIntrTx << 12 ) + ( ( nIntrRx >> 1 ) << 8 ) + nIntrUSB );}static int     dm320_get_intr_by_priority( int iInterruptFlags ){    if( ( iInterruptFlags & USB_CONNECTED       ) != 0 )        return  USB_CONNECTED;    if( ( iInterruptFlags & USB_DISCONNECTED    ) != 0 )        return  USB_DISCONNECTED;    if( ( iInterruptFlags & USB_RESET           ) != 0 )        return  USB_RESET;              // reset is first for device    if( ( iInterruptFlags & USB_RESUME          ) != 0 )        return  USB_RESUME;    if( ( iInterruptFlags & USB_SESSREQ         ) != 0 )        return  USB_SESSREQ;    if( ( iInterruptFlags & USB_VBUSERR         ) != 0 )        return  USB_VBUSERR;    if( ( iInterruptFlags & USB_SOF             ) != 0 )        return  USB_SOF;    if( ( iInterruptFlags & USB_SUSPEND         ) != 0 )        return  USB_SUSPEND;    if( ( iInterruptFlags & USB_CONTROL         ) != 0 )        return  USB_CONTROL;    if( ( iInterruptFlags & USB_RXFIFO          ) != 0 )        return  USB_RXFIFO;    if( ( iInterruptFlags & USB_TXFIFO          ) != 0 )        return  USB_TXFIFO;    return USB_NO_INTERRUPT;}static uint8_t     dm320_get_peripheral_addr( struct dm320 *dev ){    return dev->peripheral_addr;}static void    dm320_set_addr_reg( unsigned char ucAddress ){	core_debug("dm320: %s:writing new address to the device\n", __FUNCTION__);	    writeb( ucAddress, USB_FADDR );}static void    dm320_set_peripheral_addr( struct dm320 *dev, unsigned char ucNewAddress )  //USB_SetPeripheralAddr{    dev->peripheral_addr  = ucNewAddress;}static void  dm320_reset_service( ){	printk("dm320: %s\n", __FUNCTION__);	flushEPFIFO(0);	flushEPFIFO(1);	flushEPFIFO(2);	flushEPFIFO(3);	return;}static void dm320_control_service(struct dm320 *dev){	struct usb_ctrlrequest  r;    struct dm320_ep	*ep;	u8			num, scratch;	int			tmp = 0;	struct dm320_request		*req;	/* starting a control request? */	if (dev->gadget.speed == USB_SPEED_UNKNOWN) {			dev->gadget.speed = USB_SPEED_FULL;			DEBUG (dev, "%s speed\n",(dev->gadget.speed == USB_SPEED_HIGH)? "high" : "full");		}	ep = &dev->ep[0];	ep->irqs++;		/* make sure any leftover interrupt state is cleared */	while (!list_empty (&ep->queue)) {			req = list_entry (ep->queue.next,					struct dm320_request, queue);			done (ep, req, (req->req.actual == req->req.length)? 0 : -EPROTO);	}	ep->stopped = 0;	dev->protocol_stall = 0;	if( USB_ReadEP( USB_EP0_SELECT, &r, sizeof(struct usb_ctrlrequest ) ) <= 0 )        return;	/* watch control traffic at the token level, and force	 * synchronization before letting the status phase happen.	 */	ep->is_in = (r.bRequestType & USB_DIR_IN) != 0;	if ((r.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD)	{		dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY);		goto delegate;	}		switch (r.bRequest) {		case USB_REQ_GET_STATUS: {			struct dm320_ep	*e;			u16			status = 0;			dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND );			if ((r.bRequestType & USB_RECIP_MASK) 					== USB_RECIP_ENDPOINT) {				if ((e = get_ep_by_addr (dev, r.wIndex)) == 0						|| r.wLength > 2)					goto do_stall;				set_fifo_bytecount (&dev->ep [0], 0);				allow_status (ep);				VDEBUG (dev, "%s stat %02x\n", ep->ep.name,						status);				goto next_endpoints;			} else if ((r.bRequestType & USB_RECIP_MASK)					== USB_RECIP_DEVICE) {				if (r.wLength > 2)					goto do_stall;				if (dev->is_selfpowered)					status = (1 << USB_DEVICE_SELF_POWERED);				set_fifo_bytecount (&dev->ep [0], 0);				allow_status (ep);				VDEBUG (dev, "device stat %02x\n", status);				goto next_endpoints;			} else if ((r.bRequestType & USB_RECIP_MASK)					== USB_RECIP_INTERFACE) {				if (r.wLength > 2)					goto do_stall;				set_fifo_bytecount (&dev->ep [0], 0);				allow_status (ep);				VDEBUG (dev, "interface status %02x\n", status);				goto next_endpoints;			}		}		case USB_REQ_CLEAR_FEATURE: {						struct dm320_ep	*e;			dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND );			if (r.bRequestType != USB_RECIP_ENDPOINT)				goto delegate;			if (r.wValue != USB_ENDPOINT_HALT					|| r.wLength != 0)				goto do_stall;			if ((e = get_ep_by_addr (dev, r.wIndex)) == 0)				goto do_stall;			clear_halt (e);			allow_status (ep);			VDEBUG (dev, "%s clear halt\n", ep->ep.name);				goto next_endpoints;			}		case USB_REQ_SET_FEATURE: {						struct dm320_ep	*e;			dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND );				if (r.bRequestType == USB_RECIP_DEVICE) {				allow_status (ep);				VDEBUG (dev, "test mode: %d\n", r.wIndex);				goto next_endpoints;			} else if (r.bRequestType != USB_RECIP_ENDPOINT)				goto delegate;			if (r.wValue != USB_ENDPOINT_HALT					|| r.wLength != 0)				goto do_stall;			if ((e = get_ep_by_addr (dev, r.wIndex)) == 0)				goto do_stall;			set_halt (e);			allow_status (ep);			VDEBUG (dev, "%s set halt\n", ep->ep.name);			goto next_endpoints;			}		case USB_REQ_SET_ADDRESS: {			dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND );			dm320_set_peripheral_addr(dev,r.wValue & 0xff);			allow_status (ep);			break;			}		case USB_REQ_GET_DESCRIPTOR: {			dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY );			goto delegate;			}		case USB_REQ_SET_DESCRIPTOR: {			dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY );			goto delegate;			}		case USB_REQ_GET_CONFIGURATION: {			dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND);			goto delegate;			}		case USB_REQ_SET_CONFIGURATION: {			dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND);			goto delegate;			}		case USB_REQ_GET_INTERFACE: {			dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND);			goto delegate;			}		case USB_REQ_SET_INTERFACE: {			dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND);			goto delegate;			}		default:			 dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_SENDST );			 break;delegate:			//spin_unlock (&dev->lock);			if(dev)			if(&dev->gadget!= NULL && dev->driver!=NULL)				tmp = dev->driver->setup (&dev->gadget, &r);			else				printk("dm320: Gadget device is NULL!!\n");			//spin_lock (&dev->lock);		}		/* stall ep0 on error */		if (tmp < 0) {do_stall:			dev->protocol_stall = 1;		}next_endpoints:	return;}static int  dm320_rx_service( struct dm320 *dev){     struct dm320_ep *ep;	int count;	int status;     u8          num, scratch;    int         tmp = 0;    struct dm320_request        *req;	struct usb_ep *_ep;	u8		*buf;	int status;    ep = &dev->ep[EP_BULK_OUT_NUM];    ep->irqs++;	if (!list_empty (&ep->queue))	{		req = list_entry (ep->queue.next,			struct dm320_request, queue);	}	else	{		//printk("%s: Pending interrupt\n", __FUNCTION__);		rx_pending = 1 ; 		return 0;	}	read_fifo(ep, req);	return 1;}static int  dm320_tx_service(struct dm320 *dev ){    struct dm320_ep *ep;	int count;	int status;     u8          num, scratch;    int         tmp = 0;    struct dm320_request        *req;	struct usb_ep *_ep;	u8		*buf;#ifdef PIPE_STALL	writeb(EP_BULK_IN_NUM, USB_INDEX );	if( readb(USB_PER_TXCSR1) &  USB_TXCSR1_SENTST)	{		writeb(readb(USB_PER_TXCSR1)& ~USB_TXCSR1_SENTST,USB_PER_TXCSR1);		writeb(readb(USB_PER_TXCSR1)& ~USB_TXCSR1_SENDST,USB_PER_TXCSR1);	 	printk("Bulk IN peipe stalled, clearing SENTST\n");	}#endif    if (dev->gadget.speed == USB_SPEED_UNKNOWN) {            dev->gadget.speed = USB_SPEED_FULL;            DEBUG (dev, "%s speed\n",(dev->gadget.speed == USB_SPEED_HIGH)? "high" : "full");        }    ep = &dev->ep[EP_BULK_IN_NUM];    ep->irqs++;	if (!list_empty (&ep->queue))		req = list_entry (ep->queue.next,			struct dm320_request, queue);	else		return 0;	write_fifo(ep, req);	return 1;}static void dm320_disconnect_service( ){	return;}static void dm320_suspend_service( ){ 	return;}void do_pending_transfers(){#if 0	 writeb( iEndpoint, USB_INDEX );         writeb( readb( USB_PER_RXCSR1 ) & ~(USB_RXCSR1_RXPKTRDY), USB_PER_RXCSR1 );//manually clear RXPKTRDY bit in PER_RXCSR1 register#endif}void do_pending_transfers(){#if 0	 writeb( iEndpoint, USB_INDEX );         writeb( readb( USB_PER_RXCSR1 ) & ~(USB_RXCSR1_RXPKTRDY), USB_PER_RXCSR1 );//manually clear RXPKTRDY bit in PER_RXCSR1 register#endif}static irqreturn_t  handle_core_irqs(int irq, void *dev_id, struct pt_regs *regs )

⌨️ 快捷键说明

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