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

📄 wmmx.c

📁 S3C2440ARM9开发板的USB驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
					channel = wmmx_usb_dma_configs[phys_ep].dma_channel;					UDCCSN(phys_ep) |= UDCCSR_DME;					wmmx_usb_dma_configs[phys_ep].size = 						endpoint->rcv_packetSize;					/* Listen to the request */					DCSR(channel) = DCSR_NODESC | 							DCSR_EORIRQEN;					DTADR(channel) = wmmx_usb_dma_configs[phys_ep].dma_phys_buffer;					DSADR(channel) = PHYS_UDCDN(phys_ep);					DCMD(channel) = DCMD_INCTRGADDR | 							DCMD_FLOWSRC | 							DCMD_ENDIRQEN | 							DCMD_BURST32 | 							DCMD_WIDTH4 | 							endpoint->rcv_packetSize;					DRCMRUDC(phys_ep) = channel | 							    DRCMR_MAPVLD;					DCSR(channel) |= DCSR_RUN;				}			}#endif			if (!wmmx_usb_dma_configs[phys_ep].dma_enabled) {				wmmx_enable_ep_interrupt(phys_ep, 							 (UDC_INT_FIFOERROR |							  UDC_INT_PACKETCMP));			}		}	}}/* * udc_disable_ep - disable endpoint * @ep: * * Disable specified endpoint  */void udc_disable_ep (unsigned int phys_ep){	dbg_init(1, "udc_disable_ep: disable endpoint %d", phys_ep);	/* if the endpoint use PIO mode, we should disable the endpoint interrupts too. */	if (phys_ep < UDC_MAX_ENDPOINTS) {		struct usb_endpoint_instance *endpoint;		dbg_init(1, "endpoint descr 0x%08x", 			 phys_ep_to_endpoints[phys_ep]);		if ((endpoint = phys_ep_to_endpoints[phys_ep])) {			phys_ep_to_endpoints[phys_ep] = NULL;			usbd_flush_ep (endpoint);		} else {			return;		}		if (phys_ep == 0) {			dbg_init(1, "ep0 - ignore");		} else if (endpoint->endpoint_address & 0x80) { /* IN */			if (wmmx_usb_dma_configs[phys_ep].dma_enabled) {				if (wmmx_usb_dma_configs[phys_ep].dma_buffer) {					consistent_free(wmmx_usb_dma_configs[phys_ep].dma_buffer,							wmmx_usb_dma_configs[phys_ep].endpoint->tx_packetSize, 							wmmx_usb_dma_configs[phys_ep].dma_phys_buffer);					wmmx_usb_dma_configs[phys_ep].dma_buffer = NULL;				}				pxa_free_dma(wmmx_usb_dma_configs[phys_ep].dma_channel);				wmmx_dmach_to_configs[wmmx_usb_dma_configs[phys_ep].dma_channel] = NULL;				wmmx_usb_dma_configs[phys_ep].dma_enabled = 0;			}		} else if (endpoint->endpoint_address) { /* OUT */			if (wmmx_usb_dma_configs[phys_ep].dma_enabled) {				if (wmmx_usb_dma_configs[phys_ep].dma_buffer) {					consistent_free(wmmx_usb_dma_configs[phys_ep].dma_buffer,							wmmx_usb_dma_configs[phys_ep].endpoint->rcv_packetSize, 							wmmx_usb_dma_configs[phys_ep].dma_phys_buffer);					wmmx_usb_dma_configs[phys_ep].dma_buffer = NULL;				}				pxa_free_dma(wmmx_usb_dma_configs[phys_ep].dma_channel);				wmmx_dmach_to_configs[wmmx_usb_dma_configs[phys_ep].dma_channel] = NULL;				wmmx_usb_dma_configs[phys_ep].dma_enabled = 0;			}		}	}}/* * udc_connected - is the USB cable connected * * Return non-zeron if cable is connected. */int udc_connected (void){	return 1;}/* * udc_connect - enable pullup resistor * * Turn on the USB connection by enabling the pullup resistor. */void udc_connect (void){}/* * udc_disconnect - disable pullup resistor * * Turn off the USB connection by disabling the pullup resistor. */void udc_disconnect (void){}/* * udc_enable_interrupts - enable interrupts * * Switch on UDC interrupts. * */void udc_all_interrupts (struct usb_device_instance *device){	int i;	UDCICR1 = (UDCICR1_IESU | 		   UDCICR1_IERU | 		   UDCICR1_IERS | 		   UDCICR1_IECC) & ~UDCICR1_IESOF;	/* always enable control endpoint */	wmmx_enable_ep_interrupt(0, /*UDC_INT_FIFOERROR |*/ UDC_INT_PACKETCMP);	for (i = 1; i < UDC_MAX_ENDPOINTS; i++) {		if (phys_ep_to_endpoints[i] && 		    phys_ep_to_endpoints[i]->endpoint_address) {                        wmmx_enable_ep_interrupt(i, 						 UDC_INT_FIFOERROR |						 UDC_INT_PACKETCMP);		}	} }/* * udc_suspended_interrupts - enable suspended interrupts * * Switch on only UDC resume interrupt. * */void udc_suspended_interrupts (struct usb_device_instance *device){	UDCICR1 = (UDCICR1 | UDCICR1_IERS | UDCICR1_IERU | 		   UDCICR1_IECC | UDCICR1_IESU) & ~UDCICR1_IESOF;}/* * udc_disable_interrupts - disable interrupts. * * switch off interrupts */void udc_disable_interrupts (struct usb_device_instance *device){        /* disable sof interrupt */        /* disable suspend and resume interrupt */	/* disable endpoint interrupts */	UDCICR0 = UDCICR1 = 0x00000000;}/* * udc_ep0_packetsize - return ep0 packetsize */int udc_ep0_packetsize (void){	return EP0_PACKETSIZE;}/* * udc_enable - enable the UDC * * Switch on the UDC */void udc_enable (struct usb_device_instance *device){	udc_device = device;	dbgENTER(dbgflg_usbdbi_init, 1);	if (!ep0_urb) {		ep0_urb = usbd_alloc_urb(device, 					 device->function_instance_array, 					 0, 512);		if (!ep0_urb) {			printk(KERN_ERR "udc_enable: usbd_alloc_urb failed\n");		}	} else {		printk (KERN_ERR "udc_enable: ep0_urb already allocated\n");	}	/* enable UDC clock */	CKEN |= CKEN11_USB;	/* enable UDC controller */	UDCCR = UDCCR_UDE;	/* 	 * If UDCCR_EMCE is set, we should reduce the number of the 	 * configuration automatically or just yelled. 	 */	if ((UDCCR & UDCCR_EMCE) == UDCCR_EMCE) {		printk(KERN_ERR "udc_enable: Endpoint memory configure "				"error\n");		UDCCR = UDCCR_EMCE;	}}/* * udc_disable - disable the UDC * * Switch off the UDC */void udc_disable (void){	dbgENTER(dbgflg_usbdbi_init, 1);	/* disable UDC controller */	UDCCR &= ~(UDCCR_UDE);	/* disable UDC clock */	CKEN &= ~CKEN11_USB;	/* reset device pointer */	udc_device = NULL;	/* ep0 urb */	if (ep0_urb) {		usbd_dealloc_urb (ep0_urb);		ep0_urb = 0;	} else		printk (KERN_ERR "udc_disable: ep0_urb already NULL\n");}/* * udc_startup_events - allow udc code to do any additional startup */void udc_startup_events (struct usb_device_instance *device){	dbgENTER(dbgflg_usbdbi_init, 1);	udc_configuration_enable(device);	usbd_device_event(device, DEVICE_INIT, 0);	usbd_device_event(device, DEVICE_CREATE, 0);	usbd_device_event(device, DEVICE_HUB_CONFIGURED, 0);	usbd_device_event(device, DEVICE_RESET, 0);}/* Proc Filesystem */#ifdef WMMX_TRACE#ifdef CONFIG_USBD_PROCFS/*     * wmmx_proc_read - implement proc file system read. * @file         * @buf          * @count * @pos  *       * Standard proc file system read function. */         static ssize_t wmmx_proc_read(struct file *file, char *buf, 			      size_t count, loff_t * pos){                                  	unsigned long page;	int len = 0;	int index;	int i;	MOD_INC_USE_COUNT;	/* get a page, max 4095 bytes of data... */	if (!(page = get_free_page (GFP_KERNEL))) {		MOD_DEC_USE_COUNT;		return -ENOMEM;	}	len = 0;	index = (*pos)++;	if (index == 0) {		len += sprintf (			(char *) page + len, 			"   Index     Ints     Jifs    Ticks\n");        }       	if (index < trace_next) {		u64 jifs = 1111;		u32 ticks = 2222;		wmmx_trace_t *p = wmmx_traces + index;		unsigned char *cp;		if (index > 0) {			u32 ocsr = wmmx_traces[index-1].ocsr;			ticks = (p->ocsr > ocsr) ? 				(p->ocsr - ocsr) : 				(ocsr - p->ocsr);			jifs = p->jiffies - wmmx_traces[index-1].jiffies;		}                		len += sprintf((char *)page + len, "%8d %8d %8llu ", 			       index, p->interrupts, jifs);		if (ticks > 1024 * 1024) {			len += sprintf((char *)page + len, "%8dM ", 				       ticks>>20);		} else {			len += sprintf((char *)page + len, "%8d  ", ticks);		}		switch (p->trace_type) {		case wmmx_regs:			len += sprintf((char *) page + len, 				       "CS0[%02x] %s\n", 				       p->trace.regs.cs0, p->trace.regs.msg);			break;		case wmmx_setup:			cp = (unsigned char *)&p->trace.setup;			len += sprintf((char *)page + len, 				       " --               request "				       "[%02x %02x %02x %02x %02x %02x %02x "				       "%02x]\n", 				       cp[0], cp[1], cp[2], cp[3], cp[4], 				       cp[5], cp[6], cp[7]);			break;		case wmmx_xmit:			len += sprintf((char *) page + len, 				       " --                   sending [%02x]\n",				       p->trace.xmit.size);			break;		case wmmx_ccr:			len += sprintf((char *) page + len, 				       "CCR[%02x] %s\n", 				       p->trace.ccr.ccr, p->trace.ccr.msg);			break;		case wmmx_iro:			len += sprintf((char *) page + len, 				       "IRO[%02x] %s\n", 				       p->trace.iro.iro, p->trace.iro.msg);			break;		case wmmx_xfer:			cp = (unsigned char *)&p->trace.xfer.data;			len += sprintf((char *)page + len,				       "%s xfer of %d bytes:",				       (p->trace.xfer.dir ==					WMMX_XFER_DIR_OUT) ? "OUT" : "IN",				       p->trace.xfer.size);			for (i = 0;			     i < MIN(p->trace.xfer.size, WMMX_XFER_MAX_TRACE_SIZE);			     i++)			{				len += sprintf((char *)page + len, " %02x",					       (p->trace.xfer.data[i]) & 0xff);			}			len += sprintf((char *)page + len, "\n");			break;		}	}	if (len > count) {		len = -EINVAL;	} else if (len > 0 && copy_to_user (buf, (char *) page, len)) {		len = -EFAULT;	}	free_page (page);	MOD_DEC_USE_COUNT;	return len;}/* * wmmx_proc_write - implement proc file system write. * @file * @buf * @count * @pos * * Proc file system write function, used to signal monitor actions complete. * (Hotplug script (or whatever) writes to the file to signal the completion * of the script.)  An ugly hack. */static ssize_t wmmx_proc_write(struct file *file, const char *buf, 			       size_t count, loff_t * pos){	return count;}static struct file_operations wmmx_proc_operations_functions = {	read:wmmx_proc_read,	write:wmmx_proc_write,};#endif#endif/* * udc_name - return name of USB Device Controller */char *udc_name (void){	return UDC_NAME;}/* * udc_request_udc_irq - request UDC interrupt * * Return non-zero if not successful. */int udc_request_udc_irq (){	dbgENTER(dbgflg_usbdbi_init, 1);	if (request_irq(IRQ_USB, wmmx_int_hndlr, 			SA_INTERRUPT | SA_SAMPLE_RANDOM,			UDC_NAME " USBD Bus Interface", NULL) != 0) {		printk (KERN_INFO "usb_ctl: Couldn't request USB irq\n");		return -EINVAL;	}	return 0;}/* * udc_request_cable_irq - request Cable interrupt * * Return non-zero if not successful. */int udc_request_cable_irq(){	return 0;}/* * udc_request_udc_io - request UDC io region * * Return non-zero if not successful. */int udc_request_io (){#ifdef WMMX_TRACE#ifdef CONFIG_USBD_PROCFS	if (!(wmmx_traces = vmalloc(sizeof(wmmx_trace_t) * TRACE_MAX))) {		printk(KERN_ERR "WMMX_TRACE malloc failed %p %d\n", 		       wmmx_traces, 		       sizeof(wmmx_trace_t) * TRACE_MAX);	} else {		printk(KERN_ERR "WMMX_TRACE malloc ok %p\n", wmmx_traces);        }	WMMX_REGS(0,"init");	WMMX_REGS(0,"test");	{		struct proc_dir_entry *p;		if ((p = create_proc_entry("wmmx", 0, 0)) == NULL) {			printk(KERN_INFO"WMMX PROC FS failed\n");		} else {			printk(KERN_INFO"WMMX PROC FS Created\n");			p->proc_fops = &wmmx_proc_operations_functions;		}	}#endif#endif	return 0;}/* * udc_release_release_io - release UDC io region */void udc_release_io (){#ifdef WMMX_TRACE#ifdef CONFIG_USBD_PROCFS	unsigned long flags;	dbgENTER(dbgflg_usbdbi_init, 1);	save_flags_cli (flags);	remove_proc_entry ("wmmx", NULL);	if (wmmx_traces) {		wmmx_trace_t *p = wmmx_traces;		wmmx_traces = 0;		vfree(p);		dbg_init(1, "trace memory is released");	}	restore_flags (flags);#endif#endif}/* * udc_release_udc_irq - release UDC irq */void udc_release_udc_irq (){	dbgENTER(dbgflg_usbdbi_init, 1);	free_irq (IRQ_USB, NULL);}/* * udc_release_cable_irq - release Cable irq */void udc_release_cable_irq (){}/* * udc_regs - dump registers * * Dump registers with printk */void udc_regs (void){	printk ("[%d:%d] CCR[%08x] UDUICR[%08x %08x] UFN[%08x] UDCCS[%08x]\n", 		udc_interrupts, jifs(), 		UDCCR, 		UDCICR0, UDCICR1, 		UDCFNR, 		UDCCSR0);}void wmmx_print(void){	printk("%08x %08x\n", UDCCSN(1), UDCCSN(2));}

⌨️ 快捷键说明

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