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

📄 usb_ohci.c

📁 arm920t内核linux操作系统U-BOOT引导程序中usb相关部分的程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/* replies to the request have to be on a FIFO basis so * we reverse the reversed done-list */static td_t * dl_reverse_done_list (ohci_t *ohci){	__u32 td_list_hc;	td_t *td_rev = NULL;	td_t *td_list = NULL;	urb_priv_t *lurb_priv = NULL;	td_list_hc = m32_swap (ohci->hcca->done_head) & 0xfffffff0;	ohci->hcca->done_head = 0;	while (td_list_hc) {		td_list = (td_t *)td_list_hc;		if (TD_CC_GET (m32_swap (td_list->hwINFO))) {			lurb_priv = td_list->ed->purb;			dbg(" USB-error/status: %x : %p",					TD_CC_GET (m32_swap (td_list->hwINFO)), td_list);			if (td_list->ed->hwHeadP & m32_swap (0x1)) {				if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) {					td_list->ed->hwHeadP =						(lurb_priv->td[lurb_priv->length - 1]->hwNextTD & m32_swap (0xfffffff0)) |									(td_list->ed->hwHeadP & m32_swap (0x2));					lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1;				} else					td_list->ed->hwHeadP &= m32_swap (0xfffffff2);			}#ifdef CONFIG_MPC5200			td_list->hwNextTD = 0;#endif		}		td_list->next_dl_td = td_rev;		td_rev = td_list;		td_list_hc = m32_swap (td_list->hwNextTD) & 0xfffffff0;	}	return td_list;}/*-------------------------------------------------------------------------*//* td done list */static int dl_done_list (ohci_t *ohci, td_t *td_list){	td_t *td_list_next = NULL;	ed_t *ed;	int cc = 0;	int stat = 0;	/* urb_t *urb; */	urb_priv_t *lurb_priv;	__u32 tdINFO, edHeadP, edTailP;	while (td_list) {		td_list_next = td_list->next_dl_td;		tdINFO = m32_swap (td_list->hwINFO);		ed = td_list->ed;		lurb_priv = ed->purb;		dl_transfer_length(td_list);		/* error code of transfer */		cc = TD_CC_GET (tdINFO);		if (cc != 0) {			dbg("ConditionCode %#x", cc);			stat = cc_to_error[cc];		}		/* see if this done list makes for all TD's of current URB,		 * and mark the URB finished if so */		if (++(lurb_priv->td_cnt) == lurb_priv->length) {#if 1			if ((ed->state & (ED_OPER | ED_UNLINK)) &&			    (lurb_priv->state != URB_DEL))#else			if ((ed->state & (ED_OPER | ED_UNLINK)))#endif				lurb_priv->finished = sohci_return_job(ohci,						lurb_priv);			else				dbg("dl_done_list: strange.., ED state %x, ed->state\n");		} else			dbg("dl_done_list: processing TD %x, len %x\n", lurb_priv->td_cnt,				lurb_priv->length);		if (ed->state != ED_NEW &&			  (usb_pipetype (lurb_priv->pipe) != PIPE_INTERRUPT)) {			edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0;			edTailP = m32_swap (ed->hwTailP);			/* unlink eds if they are not busy */			if ((edHeadP == edTailP) && (ed->state == ED_OPER))				ep_unlink (ohci, ed);		}		td_list = td_list_next;	}	return stat;}/*-------------------------------------------------------------------------* * Virtual Root Hub *-------------------------------------------------------------------------*//* Device descriptor */static __u8 root_hub_dev_des[] ={	0x12,	    /*	__u8  bLength; */	0x01,	    /*	__u8  bDescriptorType; Device */	0x10,	    /*	__u16 bcdUSB; v1.1 */	0x01,	0x09,	    /*	__u8  bDeviceClass; HUB_CLASSCODE */	0x00,	    /*	__u8  bDeviceSubClass; */	0x00,	    /*	__u8  bDeviceProtocol; */	0x08,	    /*	__u8  bMaxPacketSize0; 8 Bytes */	0x00,	    /*	__u16 idVendor; */	0x00,	0x00,	    /*	__u16 idProduct; */	0x00,	0x00,	    /*	__u16 bcdDevice; */	0x00,	0x00,	    /*	__u8  iManufacturer; */	0x01,	    /*	__u8  iProduct; */	0x00,	    /*	__u8  iSerialNumber; */	0x01	    /*	__u8  bNumConfigurations; */};/* Configuration descriptor */static __u8 root_hub_config_des[] ={	0x09,	    /*	__u8  bLength; */	0x02,	    /*	__u8  bDescriptorType; Configuration */	0x19,	    /*	__u16 wTotalLength; */	0x00,	0x01,	    /*	__u8  bNumInterfaces; */	0x01,	    /*	__u8  bConfigurationValue; */	0x00,	    /*	__u8  iConfiguration; */	0x40,	    /*	__u8  bmAttributes;		 Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */	0x00,	    /*	__u8  MaxPower; */	/* interface */	0x09,	    /*	__u8  if_bLength; */	0x04,	    /*	__u8  if_bDescriptorType; Interface */	0x00,	    /*	__u8  if_bInterfaceNumber; */	0x00,	    /*	__u8  if_bAlternateSetting; */	0x01,	    /*	__u8  if_bNumEndpoints; */	0x09,	    /*	__u8  if_bInterfaceClass; HUB_CLASSCODE */	0x00,	    /*	__u8  if_bInterfaceSubClass; */	0x00,	    /*	__u8  if_bInterfaceProtocol; */	0x00,	    /*	__u8  if_iInterface; */	/* endpoint */	0x07,	    /*	__u8  ep_bLength; */	0x05,	    /*	__u8  ep_bDescriptorType; Endpoint */	0x81,	    /*	__u8  ep_bEndpointAddress; IN Endpoint 1 */	0x03,	    /*	__u8  ep_bmAttributes; Interrupt */	0x02,	    /*	__u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */	0x00,	0xff	    /*	__u8  ep_bInterval; 255 ms */};static unsigned char root_hub_str_index0[] ={	0x04,			/*  __u8  bLength; */	0x03,			/*  __u8  bDescriptorType; String-descriptor */	0x09,			/*  __u8  lang ID */	0x04,			/*  __u8  lang ID */};static unsigned char root_hub_str_index1[] ={	28,			/*  __u8  bLength; */	0x03,			/*  __u8  bDescriptorType; String-descriptor */	'O',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */	'H',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */	'C',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */	'I',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */	' ',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */	'R',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */	'o',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */	'o',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */	't',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */	' ',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */	'H',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */	'u',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */	'b',			/*  __u8  Unicode */	0,				/*  __u8  Unicode */};/* Hub class-specific descriptor is constructed dynamically *//*-------------------------------------------------------------------------*/#define OK(x)			len = (x); break#ifdef DEBUG#define WR_RH_STAT(x)		{info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);}#define WR_RH_PORTSTAT(x)	{info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);}#else#define WR_RH_STAT(x)		writel((x), &gohci.regs->roothub.status)#define WR_RH_PORTSTAT(x)	writel((x), &gohci.regs->roothub.portstatus[wIndex-1])#endif#define RD_RH_STAT		roothub_status(&gohci)#define RD_RH_PORTSTAT		roothub_portstatus(&gohci,wIndex-1)/* request to virtual root hub */int rh_check_port_status(ohci_t *controller){	__u32 temp, ndp, i;	int res;	res = -1;	temp = roothub_a (controller);	ndp = (temp & RH_A_NDP);#ifdef CONFIG_AT91C_PQFP_UHPBUG	ndp = (ndp == 2) ? 1:0;#endif	for (i = 0; i < ndp; i++) {		temp = roothub_portstatus (controller, i);		/* check for a device disconnect */		if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==			(RH_PS_PESC | RH_PS_CSC)) &&			((temp & RH_PS_CCS) == 0)) {			res = i;			break;		}	}	return res;}static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,		void *buffer, int transfer_len, struct devrequest *cmd){	void * data = buffer;	int leni = transfer_len;	int len = 0;	int stat = 0;	__u32 datab[4];	__u8 *data_buf = (__u8 *)datab;	__u16 bmRType_bReq;	__u16 wValue;	__u16 wIndex;	__u16 wLength;#ifdef DEBUGpkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));#else	wait_ms(1);#endif	if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {		info("Root-Hub submit IRQ: NOT implemented");		return 0;	}	bmRType_bReq  = cmd->requesttype | (cmd->request << 8);	wValue	      = cpu_to_le16 (cmd->value);	wIndex	      = cpu_to_le16 (cmd->index);	wLength	      = cpu_to_le16 (cmd->length);	info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",		dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);	switch (bmRType_bReq) {	/* Request Destination:	   without flags: Device,	   RH_INTERFACE: interface,	   RH_ENDPOINT: endpoint,	   RH_CLASS means HUB here,	   RH_OTHER | RH_CLASS	almost ever means HUB_PORT here	*/	case RH_GET_STATUS:			*(__u16 *) data_buf = cpu_to_le16 (1); OK (2);	case RH_GET_STATUS | RH_INTERFACE:			*(__u16 *) data_buf = cpu_to_le16 (0); OK (2);	case RH_GET_STATUS | RH_ENDPOINT:			*(__u16 *) data_buf = cpu_to_le16 (0); OK (2);	case RH_GET_STATUS | RH_CLASS:			*(__u32 *) data_buf = cpu_to_le32 (				RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));			OK (4);	case RH_GET_STATUS | RH_OTHER | RH_CLASS:			*(__u32 *) data_buf = cpu_to_le32 (RD_RH_PORTSTAT); OK (4);	case RH_CLEAR_FEATURE | RH_ENDPOINT:		switch (wValue) {			case (RH_ENDPOINT_STALL): OK (0);		}		break;	case RH_CLEAR_FEATURE | RH_CLASS:		switch (wValue) {			case RH_C_HUB_LOCAL_POWER:				OK(0);			case (RH_C_HUB_OVER_CURRENT):					WR_RH_STAT(RH_HS_OCIC); OK (0);		}		break;	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:		switch (wValue) {			case (RH_PORT_ENABLE):					WR_RH_PORTSTAT (RH_PS_CCS ); OK (0);			case (RH_PORT_SUSPEND):					WR_RH_PORTSTAT (RH_PS_POCI); OK (0);			case (RH_PORT_POWER):					WR_RH_PORTSTAT (RH_PS_LSDA); OK (0);			case (RH_C_PORT_CONNECTION):					WR_RH_PORTSTAT (RH_PS_CSC ); OK (0);			case (RH_C_PORT_ENABLE):					WR_RH_PORTSTAT (RH_PS_PESC); OK (0);			case (RH_C_PORT_SUSPEND):					WR_RH_PORTSTAT (RH_PS_PSSC); OK (0);			case (RH_C_PORT_OVER_CURRENT):					WR_RH_PORTSTAT (RH_PS_OCIC); OK (0);			case (RH_C_PORT_RESET):					WR_RH_PORTSTAT (RH_PS_PRSC); OK (0);		}		break;	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:		switch (wValue) {			case (RH_PORT_SUSPEND):					WR_RH_PORTSTAT (RH_PS_PSS ); OK (0);			case (RH_PORT_RESET): /* BUG IN HUP CODE *********/					if (RD_RH_PORTSTAT & RH_PS_CCS)					    WR_RH_PORTSTAT (RH_PS_PRS);					OK (0);			case (RH_PORT_POWER):					WR_RH_PORTSTAT (RH_PS_PPS );					wait_ms(100);					OK (0);			case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/					if (RD_RH_PORTSTAT & RH_PS_CCS)					    WR_RH_PORTSTAT (RH_PS_PES );					OK (0);		}		break;	case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0);	case RH_GET_DESCRIPTOR:		switch ((wValue & 0xff00) >> 8) {			case (0x01): /* device descriptor */				len = min_t(unsigned int,					  leni,					  min_t(unsigned int,					      sizeof (root_hub_dev_des),					      wLength));				data_buf = root_hub_dev_des; OK(len);			case (0x02): /* configuration descriptor */				len = min_t(unsigned int,					  leni,					  min_t(unsigned int,					      sizeof (root_hub_config_des),					      wLength));				data_buf = root_hub_config_des; OK(len);			case (0x03): /* string descriptors */				if(wValue==0x0300) {					len = min_t(unsigned int,						  leni,						  min_t(unsigned int,						      sizeof (root_hub_str_index0),						      wLength));					data_buf = root_hub_str_index0;					OK(len);				}				if(wValue==0x0301) {					len = min_t(unsigned int,						  leni,						  min_t(unsigned int,						      sizeof (root_hub_str_index1),						      wLength));					data_buf = root_hub_str_index1;					OK(len);			}			default:				stat = USB_ST_STALLED;		}		break;	case RH_GET_DESCRIPTOR | RH_CLASS:	{		__u32 temp = roothub_a (&gohci);		data_buf [0] = 9;		/* min length; */		data_buf [1] = 0x29;		data_buf [2] = temp & RH_A_NDP;#ifdef CONFIG_AT91C_PQFP_UHPBUG		data_buf [2] = (data_buf [2] == 2) ? 1:0;#endif		data_buf [3] = 0;		if (temp & RH_A_PSM)	/* per-port power switching? */			data_buf [3] |= 0x1;		if (temp & RH_A_NOCP)	/* no overcurrent reporting? */			data_buf [3] |= 0x10;		else if (temp & RH_A_OCPM)	/* per-port overcurrent reporting? */			data_buf [3] |= 0x8;		/* corresponds to data_buf[4-7] */		datab [1] = 0;		data_buf [5] = (temp & RH_A_POTPGT) >> 24;		temp = roothub_b (&gohci);		data_buf [7] = temp & RH_B_DR;		if (data_buf [2] < 7) {			data_buf [8] = 0xff;		} else {			data_buf [0] += 2;			data_buf [8] = (temp & RH_B_DR) >> 8;			data_buf [10] = data_buf [9] = 0xff;		}		len = min_t(unsigned int, leni,			    min_t(unsigned int, data_buf [0], wLength));		OK (len);	}	case RH_GET_CONFIGURATION:	*(__u8 *) data_buf = 0x01; OK (1);	case RH_SET_CONFIGURATION:	WR_RH_STAT (0x10000); OK (0);	default:		dbg ("unsupported root hub command");		stat = USB_ST_STALLED;	}#ifdef	DEBUG	ohci_dump_roothub (&gohci, 1);#else	wait_ms(1);#endif	len = min_t(int, len, leni);	if (data != data_buf)	    memcpy (data, data_buf, len);	dev->act_len = len;	dev->status = stat;#ifdef DEBUG	pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);#else	wait_ms(1);#endif	return stat;}/*-------------------------------------------------------------------------*//* common code for handling submit messages - used for all but root hub *//* accesses. */int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,		int transfer_len, struct devrequest *setup, int interval){	int stat = 0;	int maxsize = usb_maxpacket(dev, pipe);	int timeout;	urb_priv_t *urb;	urb = malloc(sizeof(urb_priv_t));	memset(urb, 0, sizeof(urb_priv_t));	urb->dev = dev;	urb->pipe = pipe;	urb->transfer_buffer = buffer;	urb->transfer_buffer_length = transfer_len;	urb->interval = interval;

⌨️ 快捷键说明

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