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

📄 pxa.c

📁 Linux2.4.20针对三星公司的s3c2440内核基础上的一些设备驱动代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			pxa_ep0xmit(endpoint, UDCCS0);                        // Clear SA and OPR bits                        UDCCS0 = UDCCS0_SA | UDCCS0_OPR;                        PXA_REGS(UDCCS0,"      <-- setup data");                }        }}static __inline__ void pxa_ep0(struct usb_endpoint_instance *endpoint, volatile u32 udccs0){        int j = 0;        PXA_REGS(udccs0,"  --> ep0");        if (udccs0 & UDCCS0_SST) {                pxa_ep_reset_irs(0);                UDCCS0 = UDCCS0_SST;                PXA_REGS(udccs0,"  --> ep0 clear SST");                if (endpoint) {                        endpoint->state = WAIT_FOR_SETUP;                        endpoint->tx_urb = NULL;                }                return;        }        if (!endpoint) {                printk(KERN_INFO"ep0[%d:%d] endpoint Zero is NULL CS0[%02x]\n", udc_interrupts, jifs(), UDCCS0);                pxa_ep_reset_irs(0);                UDCCS0 = UDCCS0_IPR | UDCCS0_OPR | UDCCS0_SA;                PXA_REGS(UDCCS0,"  ep0 NULL");                return;        }        if (endpoint->tx_urb) {                usbd_tx_complete_irq (endpoint, 0);                if (!endpoint->tx_urb) {                        if (endpoint->state != DATA_STATE_NEED_ZLP) {                                endpoint->state = WAIT_FOR_OUT_STATUS;                        }                }        }        if ((endpoint->state != WAIT_FOR_SETUP) && (udccs0 & UDCCS0_SA)) {                PXA_REGS(udccs0,"  --> ep0 early SA");                endpoint->state = WAIT_FOR_SETUP;                endpoint->tx_urb = NULL;        }        switch (endpoint->state) {        case DATA_STATE_NEED_ZLP:                UDCCS0 = UDCCS0_IPR;                endpoint->state = WAIT_FOR_OUT_STATUS;                break;        case WAIT_FOR_OUT_STATUS:                if ((udccs0 & (UDCCS0_OPR | UDCCS0_SA)) == UDCCS0_OPR) {                        UDCCS0 |= UDCCS0_OPR;                }                PXA_REGS(UDCCS0,"  --> ep0 WAIT for STATUS");                endpoint->state = WAIT_FOR_SETUP;        case WAIT_FOR_SETUP:                do {                        pxa_ep0setup(endpoint, UDCCS0);                        if (udccs0 & UDCCS0_SST) {                                pxa_ep_reset_irs(0);                                UDCCS0 = UDCCS0_SST | UDCCS0_OPR | UDCCS0_SA;                                PXA_REGS(udccs0,"  --> ep0 clear SST");                                if (endpoint) {                                        endpoint->state = WAIT_FOR_SETUP;                                        endpoint->tx_urb = NULL;                                }                                return;                        }                        if (j++ > 2) {                                u32 udccs0 = UDCCS0;                                PXA_REGS(udccs0,"  ep0 wait");                                if ((udccs0 & (UDCCS0_OPR | UDCCS0_SA | UDCCS0_RNE)) == (UDCCS0_OPR | UDCCS0_SA)) {                                        UDCCS0 = UDCCS0_OPR | UDCCS0_SA;                                        PXA_REGS(UDCCS0,"  ep0 force");                                }                                else {                                        UDCCS0 = UDCCS0_OPR | UDCCS0_SA;                                        PXA_REGS(UDCCS0,"  ep0 force and return");                                        break;                                }                        }                } while (UDCCS0 & (UDCCS0_OPR | UDCCS0_RNE));                break;        case DATA_STATE_XMIT:                pxa_ep0xmit(endpoint, UDCCS0);                break;#ifdef CONFIG_USBD_EP0_SUPPORT	case DATA_STATE_RECV:		pxa_ep0recv(endpoint, UDCCS0);		break;#endif        }        pxa_ep_reset_irs(0);        PXA_REGS(UDCCS0,"  <-- ep0");}/* ********************************************************************************************* *//* Interrupt Handler *//** * int_hndlr - interrupt handler * */static void int_hndlr (int irq, void *dev_id, struct pt_regs *regs){        int usiro;        int udccr;        int ep;        int_oscr = OSCR;	udc_interrupts++;        // check for common, high priority interrupts first, i.e. per endpoint service requests        // XXX if ISO supported it might be necessary to give the ISO endpoints priority                while ((usiro = USIR0)) {                u32 udccs0 = UDCCS0;                PXA_IRO(usiro, "------------------------> Interrupt");                for (ep = 0; usiro; usiro >>= 1, ep++) {                        if (usiro & 1) {                                switch (ep_maps[ep].eptype) {                                case ep_control:                                        pxa_ep0(ep_endpoints[0], udccs0);                                        //PXA_IRO(USIRO, "<-- Interrupt");                                        break;                                case ep_bulk_in:                                case ep_interrupt:                                        pxa_in_n(ep, ep_endpoints[ep]);                                        break;                                case ep_bulk_out:#ifdef CONFIG_USBD_PXA_DMA_OUT					printk (KERN_WARNING "PXA: bulk out with DMA out, ep %d - may be a bug\n", ep);#else					pxa_out_n(ep, ep_endpoints[ep]);#endif					pxa_ep_reset_irs(ep);					break;                                case ep_iso_in:                                case ep_iso_out:                                        pxa_ep_reset_irs(ep);                                        break;                                }                        }                }        }        // sof interrupt        if (UFNHR & UFNHR_SIR) {                UFNHR = UFNHR_SIR;        }        // uncommon interrupts        if ((udccr = UDCCR) & (UDCCR_RSTIR | UDCCR_RESIR | UDCCR_SUSIR)) {                // UDC Reset                if (udccr & UDCCR_RSTIR) {                        PXA_CCR(udccr, "------------------------> Reset");                        //printk(KERN_INFO"int_hndlr[%d:%d] Reset\n", udc_interrupts, jifs());                                                                udc_suspended = 0;                        usbd_device_event (udc_device, DEVICE_RESET, 0);                        usbd_device_event (udc_device, DEVICE_ADDRESS_ASSIGNED, 0);	                        UDCCR |= UDCCR_RSTIR;                }                // UDC Resume                if (udccr & UDCCR_RESIR) {                        PXA_CCR(udccr, "------------------------> Resume");                        if (udc_suspended) {                                udc_suspended = 0;                                usbd_device_event (udc_device, DEVICE_BUS_ACTIVITY, 0);                        }                        UDCCR |= UDCCR_RESIR;                }                // UDC Suspend                if (udccr & UDCCR_SUSIR) {                        PXA_CCR(udccr, "------------------------> Suspend");                        if (!udc_suspended) {                                udc_suspended = 1;                                usbd_device_event (udc_device, DEVICE_BUS_INACTIVE, 0);                        }                        UDCCR |= UDCCR_SUSIR;                }        }        PXA_CCR(UDCCR, "<-- Interrupt");}/* ********************************************************************************************* *//* ********************************************************************************************* *//* * Start of public functions. *//** * udc_start_in_irq - start transmit * @eendpoint: endpoint instance * * Called by bus interface driver to see if we need to start a data transmission. */void udc_start_in_irq (struct usb_endpoint_instance *endpoint){        if (UDCCSN(endpoint->endpoint_address & 0xf) & UDCCS_BI_TFS) {#ifdef CONFIG_USBD_PXA_DMA_IN                if (usb_pxa_dma_in.dma_buf) /* Buffer ok, use DMA */                        pxa_start_n_dma (endpoint->endpoint_address & 0xf, endpoint);                else /* Buffer is not allocated, switch to polling mode */                        pxa_start_n (endpoint->endpoint_address & 0xf, endpoint);#else                pxa_start_n (endpoint->endpoint_address & 0xf, endpoint);#endif        }}/** * udc_init - initialize * * Return non-zero if we cannot see device. **/int udc_init (void){        udc_disable_interrupts (NULL);#ifdef CONFIG_USBD_PXA_DMA_IN        if (!(usb_pxa_dma_in.dma_buf = (unsigned char *)consistent_alloc               (GFP_KERNEL, DMA_IN_BUFSIZE, &usb_pxa_dma_in.dma_buf_phys))) {                /* Can't allocate DMAable memory... Make a warning and not use DMA */                printk (KERN_WARNING "PXA: can't allocate consistent memory for USB DMA IN\n");                printk (KERN_WARNING "PXA: USB DMA IN is disabled\n");        }#endif#ifdef CONFIG_USBD_PXA_DMA_OUT        if (!(usb_pxa_dma_out.dma_buf = (unsigned char *)consistent_alloc               (GFP_KERNEL, DMA_OUT_BUFSIZE, &usb_pxa_dma_out.dma_buf_phys))) {                /* The same as above */                printk (KERN_WARNING "PXA: can't allocate consistent memory for USB DMA OUT\n");                printk (KERN_WARNING "PXA: USB DMA OUT is disabled\n");        }#endif	return 0;}/** * udc_start_in - start transmit * @eendpoint: endpoint instance * * Called by bus interface driver to see if we need to start a data transmission. */void udc_start_in (struct usb_endpoint_instance *endpoint){	if (endpoint) {		unsigned long flags;		local_irq_save (flags);                udc_start_in_irq(endpoint);		local_irq_restore (flags);	}}/** * udc_stall_ep - stall endpoint * @ep: physical endpoint * * Stall the endpoint. */void udc_stall_ep (unsigned int ep){	if (ep < UDC_MAX_ENDPOINTS) {		// stall	}}/** * udc_reset_ep - reset endpoint * @ep: physical endpoint * reset the endpoint. * * returns : 0 if ok, -1 otherwise */void udc_reset_ep (unsigned int ep){	if (ep < UDC_MAX_ENDPOINTS) {	}}/** * udc_endpoint_halted - is endpoint halted * @ep: * * Return non-zero if endpoint is halted */int udc_endpoint_halted (unsigned int ep){	return 0;}/** * udc_set_address - set the USB address for this device * @address: * * Called from control endpoint function after it decodes a set address setup packet. */void udc_set_address (unsigned char address){}/** * udc_serial_init - set a serial number if available */int __init udc_serial_init (struct usb_bus_instance *bus){	return -EINVAL;}/* ********************************************************************************************* *//** * udc_max_endpoints - max physical endpoints  * * Return number of physical endpoints. */int udc_max_endpoints (void){	return UDC_MAX_ENDPOINTS;}/** * udc_check_ep - check logical endpoint  * @lep: * * Return physical endpoint number to use for this logical endpoint or zero if not valid. */int udc_check_ep (int logical_endpoint, int packetsize){        // XXX check ep table        return ( ((logical_endpoint & 0xf) >= UDC_MAX_ENDPOINTS) || (packetsize > 64))                 ?  0 : (logical_endpoint & 0xf);}/** * udc_set_ep - setup endpoint  * @ep: * @endpoint: * * Associate a physical endpoint with endpoint_instance */void udc_setup_ep (struct usb_device_instance *device, unsigned int ep,		   struct usb_endpoint_instance *endpoint){	if (ep < UDC_MAX_ENDPOINTS) {		ep_endpoints[ep] = endpoint;		// ep0		if (ep == 0) {		}		// IN		else if (endpoint->endpoint_address & 0x80) {#ifdef CONFIG_USBD_PXA_DMA_IN                        if (ep == IN_ENDPOINT && usb_pxa_dma_in.dmach == -1 &&                            /* No DMA IN if we can't allocate DMAable buffer in udc_init() */                            usb_pxa_dma_in.dma_buf) {                                /* Get DMA irq */                                if ((usb_pxa_dma_in.dmach = pxa_request_dma                                     ("USB DMA IN", DMA_PRIO_HIGH, pxa_tx_dma_irq,				      (void *)&usb_pxa_dma_in)) < 0) {					printk (KERN_WARNING "PXA: can't allocate DMA IRQ for USB DMA IN\n");					printk (KERN_WARNING "PXA: USB DMA IN is disabled\n");					consistent_free (usb_pxa_dma_in.dma_buf,							 DMA_IN_BUFSIZE, usb_pxa_dma_in.dma_buf_phys);					usb_pxa_dma_in.dma_buf = NULL;				}				else					DMA_TRACEMSG (KERN_DEBUG "PXA: USB IN DMA channel %d\n", usb_pxa_dma_in.dmach);                        }#endif /* CONFIG_USBD_PXA_DMA_IN */		}		// OUT		else if (endpoint->endpoint_address) {			usbd_fill_rcv (device, endpoint, 5);			endpoint->rcv_urb = first_urb_detached (&endpoint->rdy);#ifdef CONFIG_USBD_PXA_DMA_OUT                        if (ep == OUT_ENDPOINT && usb_pxa_dma_out.dmach == -1 &&                            /* Again, no DMA OUT if we can't allocate DMAable buffer in udc_init() */                            usb_pxa_dma_out.dma_buf) {                                /* Get DMA irq */                                if ((usb_pxa_dma_out.dmach = pxa_request_dma                                     ("USB DMA OUT", DMA_PRIO_HIGH, pxa_rx_dma_irq,				      (void *)&usb_pxa_dma_out)) < 0) {					printk (KERN_WARNING "PXA: can't allocate DMA IRQ for USB DMA OUT\n");					printk (KERN_WARNING "PXA: USB DMA OUT is disabled\n");					consistent_free (usb_pxa_dma_out.dma_buf,							 DMA_OUT_BUFSIZE, usb_pxa_dma_out.dma_buf_phys);					usb_pxa_dma_out.dma_buf = NULL;				}				else {					DMA_TRACEMSG (KERN_DEBUG "PXA: USB OUT DMA channel %d\n", usb_pxa_dma_out.dmach);					usb_pxa_dma_out.ep = ep;					usb_pxa_dma_out.endpoint = endpoint;					usb_pxa_dma_out.size = DMA_OUT_BUFSIZE;										pxa_rx_dma_hw_init ();					/* Enable DME for BULK OUT endpoint */					UDCCS2 |= UDCCS_BO_DME;					DMA_TRACEMSG ("PXA: enable DME\n");					/* Start DMA */					DCSR(usb_pxa_dma_out.dmach) |= DCSR_RUN;					DMA_TRACEMSG ("PXA: OUT DMA started [ep %d]\n", ep);				}			}#endif /* CONFIG_USBD_PXA_DMA_OUT */		}		pxa_enable_ep_interrupt(ep_endpoints[ep]->endpoint_address);	}}/** * udc_disable_ep - disable endpoint * @ep: * * Disable specified endpoint  */void udc_disable_ep (unsigned int ep){	if (ep < UDC_MAX_ENDPOINTS) {		struct usb_endpoint_instance *endpoint;		if ((endpoint = ep_endpoints[ep])) {			ep_endpoints[ep] = NULL;			usbd_flush_ep (endpoint);		}		if (ep == 0) {                        //printk(KERN_INFO"udc_setup_ep: 0 do nothing\n");		}		// IN		else if (endpoint && endpoint->endpoint_address & 0x80) {#ifdef CONFIG_USBD_PXA_DMA_IN                        if (ep == IN_ENDPOINT && usb_pxa_dma_in.dmach != -1) {				pxa_free_dma (usb_pxa_dma_in.dmach);				usb_pxa_dma_in.dmach = -1;			}#endif		}		// OUT		else if (endpoint && endpoint->endpoint_address) {#ifdef CONFIG_USBD_PXA_DMA_OUT                        if (ep == OUT_ENDPOINT && usb_pxa_dma_out.dmach != -1) {				pxa_free_dma (usb_pxa_dma_out.dmach);				usb_pxa_dma_out.dmach = -1;			}#endif		}	}}/* ********************************************************************************************* *//** * udc_connected - is the USB cable connected * * Return non-zeron if cable is connected. */

⌨️ 快捷键说明

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