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

📄 usbdcore_omap1510.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 3 页
字号:
					       DEVICE_HUB_CONFIGURED, 0);			if (final == STATE_POWERED)				break;		case STATE_POWERED:			usbd_device_event_irq (udc_device, DEVICE_RESET, 0);			if (final == STATE_DEFAULT)				break;		case STATE_DEFAULT:			usbd_device_event_irq (udc_device,					       DEVICE_ADDRESS_ASSIGNED, 0);			if (final == STATE_ADDRESSED)				break;		case STATE_ADDRESSED:			usbd_device_event_irq (udc_device, DEVICE_CONFIGURED,					       0);		case STATE_CONFIGURED:			break;		default:			break;		}	}}static void udc_state_transition_down (usb_device_state_t initial,				       usb_device_state_t final){	if (initial > final) {		switch (initial) {		case STATE_CONFIGURED:			usbd_device_event_irq (udc_device, DEVICE_DE_CONFIGURED, 0);			if (final == STATE_ADDRESSED)				break;		case STATE_ADDRESSED:			usbd_device_event_irq (udc_device, DEVICE_RESET, 0);			if (final == STATE_DEFAULT)				break;		case STATE_DEFAULT:			usbd_device_event_irq (udc_device, DEVICE_POWER_INTERRUPTION, 0);			if (final == STATE_POWERED)				break;		case STATE_POWERED:			usbd_device_event_irq (udc_device, DEVICE_HUB_RESET, 0);		case STATE_ATTACHED:			break;		default:			break;		}	}}/* Handle all device state changes. * This function implements TRM Figure 14-21. */static void omap1510_udc_state_changed (void){	u16 bits;	u16 devstat = inw (UDC_DEVSTAT);	UDCDBGA ("state changed, devstat %x, old %x", devstat, udc_devstat);	bits = devstat ^ udc_devstat;	if (bits) {		if (bits & UDC_ATT) {			if (devstat & UDC_ATT) {				UDCDBG ("device attached and powered");				udc_state_transition_up (udc_device->device_state, STATE_POWERED);			} else {				UDCDBG ("device detached or unpowered");				udc_state_transition_down (udc_device->device_state, STATE_ATTACHED);			}		}		if (bits & UDC_USB_Reset) {			if (devstat & UDC_USB_Reset) {				UDCDBG ("device reset in progess");				udc_state_transition_down (udc_device->device_state, STATE_POWERED);			} else {				UDCDBG ("device reset completed");			}		}		if (bits & UDC_DEF) {			if (devstat & UDC_DEF) {				UDCDBG ("device entering default state");				udc_state_transition_up (udc_device->device_state, STATE_DEFAULT);			} else {				UDCDBG ("device leaving default state");				udc_state_transition_down (udc_device->device_state, STATE_POWERED);			}		}		if (bits & UDC_SUS) {			if (devstat & UDC_SUS) {				UDCDBG ("entering suspended state");				usbd_device_event_irq (udc_device, DEVICE_BUS_INACTIVE, 0);			} else {				UDCDBG ("leaving suspended state");				usbd_device_event_irq (udc_device, DEVICE_BUS_ACTIVITY, 0);			}		}		if (bits & UDC_R_WK_OK) {			UDCDBGA ("remote wakeup %s", (devstat & UDC_R_WK_OK)				 ? "enabled" : "disabled");		}		if (bits & UDC_ADD) {			if (devstat & UDC_ADD) {				UDCDBG ("default -> addressed");				udc_state_transition_up (udc_device->device_state, STATE_ADDRESSED);			} else {				UDCDBG ("addressed -> default");				udc_state_transition_down (udc_device->device_state, STATE_DEFAULT);			}		}		if (bits & UDC_CFG) {			if (devstat & UDC_CFG) {				UDCDBG ("device configured");				/* The ep0_recv_setup function generates the				 * DEVICE_CONFIGURED event when a				 * USB_REQ_SET_CONFIGURATION setup packet is				 * received, so we should already be in the				 * state STATE_CONFIGURED.				 */				udc_state_transition_up (udc_device->device_state, STATE_CONFIGURED);			} else {				UDCDBG ("device deconfigured");				udc_state_transition_down (udc_device->device_state, STATE_ADDRESSED);			}		}	}	/* Clear interrupt source */	outw (UDC_DS_Chg, UDC_IRQ_SRC);	/* Save current DEVSTAT */	udc_devstat = devstat;}/* Handle SETUP USB interrupt. * This function implements TRM Figure 14-14. */static void omap1510_udc_setup (struct usb_endpoint_instance *endpoint){	UDCDBG ("-> Entering device setup");	do {		const int setup_pktsize = 8;		unsigned char *datap =			(unsigned char *) &ep0_urb->device_request;		/* Gain access to EP 0 setup FIFO */		outw (UDC_Setup_Sel, UDC_EP_NUM);		/* Read control request data */		insb (UDC_DATA, datap, setup_pktsize);		UDCDBGA ("EP0 setup read [%x %x %x %x %x %x %x %x]",			 *(datap + 0), *(datap + 1), *(datap + 2),			 *(datap + 3), *(datap + 4), *(datap + 5),			 *(datap + 6), *(datap + 7));		/* Reset EP0 setup FIFO */		outw (0, UDC_EP_NUM);	} while (inw (UDC_IRQ_SRC) & UDC_Setup);	/* Try to process setup packet */	if (ep0_recv_setup (ep0_urb)) {		/* Not a setup packet, stall next EP0 transaction */		udc_stall_ep (0);		UDCDBG ("can't parse setup packet, still waiting for setup");		return;	}	/* Check direction */	if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)	    == USB_REQ_HOST2DEVICE) {		UDCDBG ("control write on EP0");		if (le16_to_cpu (ep0_urb->device_request.wLength)) {			/* We don't support control write data stages.			 * The only standard control write request with a data			 * stage is SET_DESCRIPTOR, and ep0_recv_setup doesn't			 * support that so we just stall those requests.  A			 * function driver might support a non-standard			 * write request with a data stage, but it isn't			 * obvious what we would do with the data if we read it			 * so we'll just stall it.  It seems like the API isn't			 * quite right here.			 */#if 0			/* Here is what we would do if we did support control			 * write data stages.			 */			ep0_urb->actual_length = 0;			outw (0, UDC_EP_NUM);			/* enable the EP0 rx FIFO */			outw (UDC_Set_FIFO_En, UDC_CTRL);#else			/* Stall this request */			UDCDBG ("Stalling unsupported EP0 control write data "				"stage.");			udc_stall_ep (0);#endif		} else {			omap1510_prepare_for_control_write_status (ep0_urb);		}	} else {		UDCDBG ("control read on EP0");		/* The ep0_recv_setup function has already placed our response		 * packet data in ep0_urb->buffer and the packet length in		 * ep0_urb->actual_length.		 */		endpoint->tx_urb = ep0_urb;		endpoint->sent = 0;		/* select the EP0 tx FIFO */		outw (UDC_EP_Dir | UDC_EP_Sel, UDC_EP_NUM);		/* Write packet data to the FIFO.  omap1510_write_noniso_tx_fifo		 * will update endpoint->last with the number of bytes written		 * to the FIFO.		 */		omap1510_write_noniso_tx_fifo (endpoint);		/* enable the FIFO to start the packet transmission */		outw (UDC_Set_FIFO_En, UDC_CTRL);		/* deselect the EP0 tx FIFO */		outw (UDC_EP_Dir, UDC_EP_NUM);	}	UDCDBG ("<- Leaving device setup");}/* Handle endpoint 0 RX interrupt * This routine implements TRM Figure 14-16. */static void omap1510_udc_ep0_rx (struct usb_endpoint_instance *endpoint){	unsigned short status;	UDCDBG ("RX on EP0");	/* select EP0 rx FIFO */	outw (UDC_EP_Sel, UDC_EP_NUM);	status = inw (UDC_STAT_FLG);	if (status & UDC_ACK) {		/* Check direction */		if ((ep0_urb->device_request.bmRequestType		     & USB_REQ_DIRECTION_MASK) == USB_REQ_HOST2DEVICE) {			/* This rx interrupt must be for a control write data			 * stage packet.			 *			 * We don't support control write data stages.			 * We should never end up here.			 */			/* clear the EP0 rx FIFO */			outw (UDC_Clr_EP, UDC_CTRL);			/* deselect the EP0 rx FIFO */			outw (0, UDC_EP_NUM);			UDCDBG ("Stalling unexpected EP0 control write "				"data stage packet");			udc_stall_ep (0);		} else {			/* This rx interrupt must be for a control read status			 * stage packet.			 */			UDCDBG ("ACK on EP0 control read status stage packet");			/* deselect EP0 rx FIFO */			outw (0, UDC_EP_NUM);		}	} else if (status & UDC_STALL) {		UDCDBG ("EP0 stall during RX");		/* deselect EP0 rx FIFO */		outw (0, UDC_EP_NUM);	} else {		/* deselect EP0 rx FIFO */		outw (0, UDC_EP_NUM);	}}/* Handle endpoint 0 TX interrupt * This routine implements TRM Figure 14-18. */static void omap1510_udc_ep0_tx (struct usb_endpoint_instance *endpoint){	unsigned short status;	struct usb_device_request *request = &ep0_urb->device_request;	UDCDBG ("TX on EP0");	/* select EP0 TX FIFO */	outw (UDC_EP_Dir | UDC_EP_Sel, UDC_EP_NUM);	status = inw (UDC_STAT_FLG);	if (status & UDC_ACK) {		/* Check direction */		if ((request->bmRequestType & USB_REQ_DIRECTION_MASK) ==		    USB_REQ_HOST2DEVICE) {			/* This tx interrupt must be for a control write status			 * stage packet.			 */			UDCDBG ("ACK on EP0 control write status stage packet");			/* deselect EP0 TX FIFO */			outw (UDC_EP_Dir, UDC_EP_NUM);		} else {			/* This tx interrupt must be for a control read data			 * stage packet.			 */			int wLength = le16_to_cpu (request->wLength);			/* Update our count of bytes sent so far in this			 * transfer.			 */			endpoint->sent += endpoint->last;			/* We are finished with this transfer if we have sent			 * all of the bytes in our tx urb (urb->actual_length)			 * unless we need a zero-length terminating packet.  We			 * need a zero-length terminating packet if we returned			 * fewer bytes than were requested (wLength) by the host,			 * and the number of bytes we returned is an exact			 * multiple of the packet size endpoint->tx_packetSize.			 */			if ((endpoint->sent == ep0_urb->actual_length)			    && ((ep0_urb->actual_length == wLength)				|| (endpoint->last !=				    endpoint->tx_packetSize))) {				/* Done with control read data stage. */				UDCDBG ("control read data stage complete");				/* deselect EP0 TX FIFO */				outw (UDC_EP_Dir, UDC_EP_NUM);				/* select EP0 RX FIFO to prepare for control				 * read status stage.				 */				outw (UDC_EP_Sel, UDC_EP_NUM);				/* clear the EP0 RX FIFO */				outw (UDC_Clr_EP, UDC_CTRL);				/* enable the EP0 RX FIFO */				outw (UDC_Set_FIFO_En, UDC_CTRL);				/* deselect the EP0 RX FIFO */				outw (0, UDC_EP_NUM);			} else {				/* We still have another packet of data to send				 * in this control read data stage or else we				 * need a zero-length terminating packet.				 */				UDCDBG ("ACK control read data stage packet");				omap1510_write_noniso_tx_fifo (endpoint);				/* enable the EP0 tx FIFO to start transmission */				outw (UDC_Set_FIFO_En, UDC_CTRL);				/* deselect EP0 TX FIFO */				outw (UDC_EP_Dir, UDC_EP_NUM);			}		}	} else if (status & UDC_STALL) {		UDCDBG ("EP0 stall during TX");		/* deselect EP0 TX FIFO */		outw (UDC_EP_Dir, UDC_EP_NUM);	} else {		/* deselect EP0 TX FIFO */		outw (UDC_EP_Dir, UDC_EP_NUM);	}}/* Handle RX transaction on non-ISO endpoint. * This function implements TRM Figure 14-27. * The ep argument is a physical endpoint number for a non-ISO OUT endpoint * in the range 1 to 15. */static void omap1510_udc_epn_rx (int ep){	unsigned short status;	/* Check endpoint status */	status = inw (UDC_STAT_FLG);	if (status & UDC_ACK) {		int nbytes;		struct usb_endpoint_instance *endpoint =			omap1510_find_ep (ep);		nbytes = omap1510_read_noniso_rx_fifo (endpoint);		usbd_rcv_complete (endpoint, nbytes, 0);		/* enable rx FIFO to prepare for next packet */		outw (UDC_Set_FIFO_En, UDC_CTRL);	} else if (status & UDC_STALL) {		UDCDBGA ("STALL on RX endpoint %d", ep);	} else if (status & UDC_NAK) {		UDCDBGA ("NAK on RX ep %d", ep);	} else {		serial_printf ("omap-bi: RX on ep %d with status %x", ep,			       status);	}}/* Handle TX transaction on non-ISO endpoint. * This function implements TRM Figure 14-29. * The ep argument is a physical endpoint number for a non-ISO IN endpoint * in the range 16 to 30. */static void omap1510_udc_epn_tx (int ep){	unsigned short status;	/*serial_printf("omap1510_udc_epn_tx( %x )\n",ep); */	/* Check endpoint status */	status = inw (UDC_STAT_FLG);	if (status & UDC_ACK) {		struct usb_endpoint_instance *endpoint =			omap1510_find_ep (ep);		/* We need to transmit a terminating zero-length packet now if		 * we have sent all of the data in this URB and the transfer		 * size was an exact multiple of the packet size.		 */		if (endpoint->tx_urb		    && (endpoint->last == endpoint->tx_packetSize)		    && (endpoint->tx_urb->actual_length - endpoint->sent -			endpoint->last == 0)) {			/* Prepare to transmit a zero-length packet. */			endpoint->sent += endpoint->last;			/* write 0 bytes of data to FIFO */			omap1510_write_noniso_tx_fifo (endpoint);			/* enable tx FIFO to start transmission */			outw (UDC_Set_FIFO_En, UDC_CTRL);		} else if (endpoint->tx_urb			   && endpoint->tx_urb->actual_length) {			/* retire the data that was just sent */			usbd_tx_complete (endpoint);			/* Check to see if we have more data ready to transmit			 * now.			 */			if (endpoint->tx_urb			    && endpoint->tx_urb->actual_length) {				/* write data to FIFO */				omap1510_write_noniso_tx_fifo (endpoint);				/* enable tx FIFO to start transmission */				outw (UDC_Set_FIFO_En, UDC_CTRL);			}		}	} else if (status & UDC_STALL) {		UDCDBGA ("STALL on TX endpoint %d", ep);	} else if (status & UDC_NAK) {		UDCDBGA ("NAK on TX endpoint %d", ep);	} else {		/*serial_printf("omap-bi: TX on ep %d with status %x\n", ep, status); */	}}/*-------------------------------------------------------------------------------*//* Handle general USB interrupts and dispatch according to type. * This function implements TRM Figure 14-13. */void omap1510_udc_irq (void){	u16 irq_src = inw (UDC_IRQ_SRC);	int valid_irq = 0;	if (!(irq_src & ~UDC_SOF_Flg))	/* ignore SOF interrupts ) */		return;	UDCDBGA ("< IRQ #%d start >- %x", udc_interrupts, irq_src);	/*serial_printf("< IRQ #%d start >- %x\n", udc_interrupts, irq_src); */	if (irq_src & UDC_DS_Chg) {		/* Device status changed */		omap1510_udc_state_changed ();		valid_irq++;	}	if (irq_src & UDC_EP0_RX) {		/* Endpoint 0 receive */		outw (UDC_EP0_RX, UDC_IRQ_SRC); /* ack interrupt */		omap1510_udc_ep0_rx (udc_device->bus->endpoint_array + 0);		valid_irq++;	}	if (irq_src & UDC_EP0_TX) {		/* Endpoint 0 transmit */		outw (UDC_EP0_TX, UDC_IRQ_SRC); /* ack interrupt */		omap1510_udc_ep0_tx (udc_device->bus->endpoint_array + 0);		valid_irq++;	}	if (irq_src & UDC_Setup) {		/* Device setup */		omap1510_udc_setup (udc_device->bus->endpoint_array + 0);		valid_irq++;	}	/*if (!valid_irq) */	/*	serial_printf("unknown interrupt, IRQ_SRC %.4x\n", irq_src); */	UDCDBGA ("< IRQ #%d end >", udc_interrupts);	udc_interrupts++;}/* This function implements TRM Figure 14-26. */void omap1510_udc_noniso_irq (void){	unsigned short epnum;	unsigned short irq_src = inw (UDC_IRQ_SRC);	int valid_irq = 0;	if (!(irq_src & (UDC_EPn_RX | UDC_EPn_TX)))		return;	UDCDBGA ("non-ISO IRQ, IRQ_SRC %x", inw (UDC_IRQ_SRC));	if (irq_src & UDC_EPn_RX) {	/* Endpoint N OUT transaction */

⌨️ 快捷键说明

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