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

📄 pxa2xx_udc.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				 */				stop_activity (dev, dev->driver);			} else {				INFO("USB reset\n");				dev->gadget.speed = USB_SPEED_FULL;				LED_CONNECTED_ON;				memset(&dev->stats, 0, sizeof dev->stats);				/* driver and endpoints are still reset */				enable_disconnect_irq();			}		} else {			u32	usir0 = USIR0 & ~UICR0;			u32	usir1 = USIR1 & ~UICR1;			int	i;			if (unlikely (!usir0 && !usir1))				continue;			DBG(DBG_VERY_NOISY, "irq %02x.%02x\n", usir1, usir0);			/* control traffic */			if (usir0 & USIR0_IR0) {				dev->ep[0].pio_irqs++;				handle_ep0(dev);				handled = 1;			}			/* endpoint data transfers */			for (i = 0; i < 8; i++) {				u32	tmp = 1 << i;				if (i && (usir0 & tmp)) {					handle_ep(&dev->ep[i]);					USIR0 |= tmp;					handled = 1;				}				if (usir1 & tmp) {					handle_ep(&dev->ep[i+8]);					USIR1 |= tmp;					handled = 1;				}			}		}		/* we could also ask for 1 msec SOF (SIR) interrupts */	} while (handled);	return IRQ_HANDLED;}/*-------------------------------------------------------------------------*/static void nop_release (struct device *dev){	DMSG("%s %s\n", __FUNCTION__, dev->bus_id);}/* this uses load-time allocation and initialization (instead of * doing it at run-time) to save code, eliminate fault paths, and * be more obviously correct. */static struct pxa2xx_udc memory = {	.gadget = {		.ops		= &pxa2xx_udc_ops,		.ep0		= &memory.ep[0].ep,		.name		= driver_name,		.dev = {			.bus_id		= "gadget",			.release	= nop_release,		},	},	/* control endpoint */	.ep[0] = {		.ep = {			.name		= ep0name,			.ops		= &pxa2xx_ep_ops,			.maxpacket	= EP0_FIFO_SIZE,		},		.dev		= &memory,		.reg_udccs	= &UDCCS0,		.reg_uddr	= &UDDR0,	},	/* first group of endpoints */	.ep[1] = {		.ep = {			.name		= "ep1in-bulk",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= BULK_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= BULK_FIFO_SIZE,		.bEndpointAddress = USB_DIR_IN | 1,		.bmAttributes	= USB_ENDPOINT_XFER_BULK,		.reg_udccs	= &UDCCS1,		.reg_uddr	= &UDDR1,		drcmr (25)	},	.ep[2] = {		.ep = {			.name		= "ep2out-bulk",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= BULK_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= BULK_FIFO_SIZE,		.bEndpointAddress = 2,		.bmAttributes	= USB_ENDPOINT_XFER_BULK,		.reg_udccs	= &UDCCS2,		.reg_ubcr	= &UBCR2,		.reg_uddr	= &UDDR2,		drcmr (26)	},#ifndef CONFIG_USB_PXA2XX_SMALL	.ep[3] = {		.ep = {			.name		= "ep3in-iso",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= ISO_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= ISO_FIFO_SIZE,		.bEndpointAddress = USB_DIR_IN | 3,		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,		.reg_udccs	= &UDCCS3,		.reg_uddr	= &UDDR3,		drcmr (27)	},	.ep[4] = {		.ep = {			.name		= "ep4out-iso",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= ISO_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= ISO_FIFO_SIZE,		.bEndpointAddress = 4,		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,		.reg_udccs	= &UDCCS4,		.reg_ubcr	= &UBCR4,		.reg_uddr	= &UDDR4,		drcmr (28)	},	.ep[5] = {		.ep = {			.name		= "ep5in-int",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= INT_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= INT_FIFO_SIZE,		.bEndpointAddress = USB_DIR_IN | 5,		.bmAttributes	= USB_ENDPOINT_XFER_INT,		.reg_udccs	= &UDCCS5,		.reg_uddr	= &UDDR5,	},	/* second group of endpoints */	.ep[6] = {		.ep = {			.name		= "ep6in-bulk",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= BULK_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= BULK_FIFO_SIZE,		.bEndpointAddress = USB_DIR_IN | 6,		.bmAttributes	= USB_ENDPOINT_XFER_BULK,		.reg_udccs	= &UDCCS6,		.reg_uddr	= &UDDR6,		drcmr (30)	},	.ep[7] = {		.ep = {			.name		= "ep7out-bulk",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= BULK_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= BULK_FIFO_SIZE,		.bEndpointAddress = 7,		.bmAttributes	= USB_ENDPOINT_XFER_BULK,		.reg_udccs	= &UDCCS7,		.reg_ubcr	= &UBCR7,		.reg_uddr	= &UDDR7,		drcmr (31)	},	.ep[8] = {		.ep = {			.name		= "ep8in-iso",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= ISO_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= ISO_FIFO_SIZE,		.bEndpointAddress = USB_DIR_IN | 8,		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,		.reg_udccs	= &UDCCS8,		.reg_uddr	= &UDDR8,		drcmr (32)	},	.ep[9] = {		.ep = {			.name		= "ep9out-iso",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= ISO_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= ISO_FIFO_SIZE,		.bEndpointAddress = 9,		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,		.reg_udccs	= &UDCCS9,		.reg_ubcr	= &UBCR9,		.reg_uddr	= &UDDR9,		drcmr (33)	},	.ep[10] = {		.ep = {			.name		= "ep10in-int",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= INT_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= INT_FIFO_SIZE,		.bEndpointAddress = USB_DIR_IN | 10,		.bmAttributes	= USB_ENDPOINT_XFER_INT,		.reg_udccs	= &UDCCS10,		.reg_uddr	= &UDDR10,	},	/* third group of endpoints */	.ep[11] = {		.ep = {			.name		= "ep11in-bulk",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= BULK_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= BULK_FIFO_SIZE,		.bEndpointAddress = USB_DIR_IN | 11,		.bmAttributes	= USB_ENDPOINT_XFER_BULK,		.reg_udccs	= &UDCCS11,		.reg_uddr	= &UDDR11,		drcmr (35)	},	.ep[12] = {		.ep = {			.name		= "ep12out-bulk",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= BULK_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= BULK_FIFO_SIZE,		.bEndpointAddress = 12,		.bmAttributes	= USB_ENDPOINT_XFER_BULK,		.reg_udccs	= &UDCCS12,		.reg_ubcr	= &UBCR12,		.reg_uddr	= &UDDR12,		drcmr (36)	},	.ep[13] = {		.ep = {			.name		= "ep13in-iso",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= ISO_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= ISO_FIFO_SIZE,		.bEndpointAddress = USB_DIR_IN | 13,		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,		.reg_udccs	= &UDCCS13,		.reg_uddr	= &UDDR13,		drcmr (37)	},	.ep[14] = {		.ep = {			.name		= "ep14out-iso",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= ISO_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= ISO_FIFO_SIZE,		.bEndpointAddress = 14,		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,		.reg_udccs	= &UDCCS14,		.reg_ubcr	= &UBCR14,		.reg_uddr	= &UDDR14,		drcmr (38)	},	.ep[15] = {		.ep = {			.name		= "ep15in-int",			.ops		= &pxa2xx_ep_ops,			.maxpacket	= INT_FIFO_SIZE,		},		.dev		= &memory,		.fifo_size	= INT_FIFO_SIZE,		.bEndpointAddress = USB_DIR_IN | 15,		.bmAttributes	= USB_ENDPOINT_XFER_INT,		.reg_udccs	= &UDCCS15,		.reg_uddr	= &UDDR15,	},#endif /* !CONFIG_USB_PXA2XX_SMALL */};#define CP15R0_VENDOR_MASK	0xffffe000#if	defined(CONFIG_ARCH_PXA)#define CP15R0_XSCALE_VALUE	0x69052000	/* intel/arm/xscale */#elif	defined(CONFIG_ARCH_IXP4XX)#define CP15R0_XSCALE_VALUE	0x69054000	/* intel/arm/ixp4xx */#endif#define CP15R0_PROD_MASK	0x000003f0#define PXA25x			0x00000100	/* and PXA26x */#define PXA210			0x00000120#define CP15R0_REV_MASK		0x0000000f#define CP15R0_PRODREV_MASK	(CP15R0_PROD_MASK | CP15R0_REV_MASK)#define PXA255_A0		0x00000106	/* or PXA260_B1 */#define PXA250_C0		0x00000105	/* or PXA26x_B0 */#define PXA250_B2		0x00000104#define PXA250_B1		0x00000103	/* or PXA260_A0 */#define PXA250_B0		0x00000102#define PXA250_A1		0x00000101#define PXA250_A0		0x00000100#define PXA210_C0		0x00000125#define PXA210_B2		0x00000124#define PXA210_B1		0x00000123#define PXA210_B0		0x00000122#define IXP425_A0		0x000001c1/* * 	probe - binds to the platform device */static int __init pxa2xx_udc_probe(struct device *_dev){	struct pxa2xx_udc *dev = &memory;	int retval, out_dma = 1;	u32 chiprev;	/* insist on Intel/ARM/XScale */	/* FIXME: the system freeze when build as non module without CONFIG_USB_ETH_RNDIS on Lubbock */#if	defined(CONFIG_USB_ETH_RNDIS)	asm("mrc%? p15, 0, %0, c0, c0" : "=r" (chiprev));#else		chiprev=0x69052D05; /* Captured value on my Lubbock Board */#endif	if ((chiprev & CP15R0_VENDOR_MASK) != CP15R0_XSCALE_VALUE) {		printk(KERN_ERR "%s: not XScale!\n", driver_name);		return -ENODEV;	}	/* trigger chiprev-specific logic */	switch (chiprev & CP15R0_PRODREV_MASK) {#if	defined(CONFIG_ARCH_PXA)	case PXA255_A0:		dev->has_cfr = 1;		break;	case PXA250_A0:	case PXA250_A1:		/* A0/A1 "not released"; ep 13, 15 unusable */		/* fall through */	case PXA250_B2: case PXA210_B2:	case PXA250_B1: case PXA210_B1:	case PXA250_B0: case PXA210_B0:		out_dma = 0;		/* fall through */	case PXA250_C0: case PXA210_C0:		break;#elif	defined(CONFIG_ARCH_IXP4XX)	case IXP425_A0:		out_dma = 0;		break;#endif	default:		out_dma = 0;		printk(KERN_ERR "%s: unrecognized processor: %08x\n",			driver_name, chiprev);		/* iop3xx, ixp4xx, ... */		return -ENODEV;	}	pr_debug("%s: IRQ %d%s%s%s\n", driver_name, IRQ_USB,		dev->has_cfr ? "" : " (!cfr)",		out_dma ? "" : " (broken dma-out)",		SIZE_STR DMASTR		);#ifdef	USE_DMA#ifndef	USE_OUT_DMA	out_dma = 0;#endif	/* pxa 250 erratum 130 prevents using OUT dma (fixed C0) */	if (!out_dma) {		DMSG("disabled OUT dma\n");		dev->ep[ 2].reg_drcmr = dev->ep[ 4].reg_drcmr = 0;		dev->ep[ 7].reg_drcmr = dev->ep[ 9].reg_drcmr = 0;		dev->ep[12].reg_drcmr = dev->ep[14].reg_drcmr = 0;	}#endif	/* other non-static parts of init */	dev->dev = _dev;	dev->mach = _dev->platform_data;	init_timer(&dev->timer);	dev->timer.function = udc_watchdog;	dev->timer.data = (unsigned long) dev;	device_initialize(&dev->gadget.dev);	dev->gadget.dev.parent = _dev;	dev->gadget.dev.dma_mask = _dev->dma_mask;	the_controller = dev;	dev_set_drvdata(_dev, dev);	udc_disable(dev);	udc_reinit(dev);	/* irq setup after old hardware state is cleaned up */	retval = request_irq(IRQ_USB, pxa2xx_udc_irq,			SA_INTERRUPT, driver_name, dev);	if (retval != 0) {		printk(KERN_ERR "%s: can't get irq %i, err %d\n",			driver_name, IRQ_USB, retval);		return -EBUSY;	}	dev->got_irq = 1;#ifdef CONFIG_ARCH_LUBBOCK#ifndef	CONFIG_ARCH_FS_PXA255	if (machine_is_lubbock()) {		disable_irq(LUBBOCK_USB_DISC_IRQ);		retval = request_irq(LUBBOCK_USB_DISC_IRQ,				usb_connection_irq,				SA_INTERRUPT /* OOPSING | SA_SAMPLE_RANDOM */,				driver_name, dev);		if (retval != 0) {			enable_irq(LUBBOCK_USB_DISC_IRQ);			printk(KERN_ERR "%s: can't get irq %i, err %d\n",				driver_name, LUBBOCK_USB_DISC_IRQ, retval);			return -EBUSY;		}		dev->got_disc = 1;	}#endif#endif	create_proc_files();	return 0;}static int __exit pxa2xx_udc_remove(struct device *_dev){	struct pxa2xx_udc *dev = _dev->driver_data;	udc_disable(dev);	remove_proc_files();	usb_gadget_unregister_driver(dev->driver);	if (dev->got_irq) {		free_irq(IRQ_USB, dev);		dev->got_irq = 0;	}	if (machine_is_lubbock() && dev->got_disc) {		free_irq(LUBBOCK_USB_DISC_IRQ, dev);		dev->got_disc = 0;	}	dev_set_drvdata(_dev, 0);	the_controller = 0;	return 0;}/*-------------------------------------------------------------------------*/static struct device_driver udc_driver = {	.name		= (char *) driver_name,	.bus		= &platform_bus_type,	.probe		= pxa2xx_udc_probe,	.remove		= __exit_p(pxa2xx_udc_remove),	// FIXME power management support	// .suspend = ... disable UDC	// .resume = ... re-enable UDC};static int __init udc_init(void){	printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION);	return driver_register(&udc_driver);}module_init(udc_init);static void __exit udc_exit(void){	driver_unregister(&udc_driver);}module_exit(udc_exit);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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