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

📄 sl811_usb.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
		usb_settoggle(dev, ep, usb_pipeout(pipe), 1);		while (done < len) {			int res = sl811_send_packet(dev, pipe, (__u8*)buffer+done,						    max > len - done ? len - done : max);			if (res < 0) {				PDEBUG(0, "status data failed!\n");				dev->status = -res;				return 0;			}			done += res;			usb_dotoggle(dev, ep, usb_pipeout(pipe));			if (dir_in && res < max) /* short packet */				break;		}		/* status phase */		sl811_write(SL811_PIDEP_A,			    PIDEP(!dir_in ? USB_PID_IN : USB_PID_OUT, ep));		usb_settoggle(dev, ep, !usb_pipeout(pipe), 1);		if (sl811_send_packet(dev,				      !dir_in ? usb_rcvctrlpipe(dev, ep) :				      usb_sndctrlpipe(dev, ep),				      0, 0) < 0) {			PDEBUG(0, "status phase failed!\n");			dev->status = -1;		}	} else {		PDEBUG(0, "setup phase failed!\n");		dev->status = -1;	}	dev->act_len = done;	return done;}int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,		   int len, int interval){	PDEBUG(0, "dev = %p pipe = %#lx buf = %p size = %d int = %d\n", dev, pipe,	       buffer, len, interval);	return -1;}/* * SL811 Virtual Root Hub *//* Device descriptor */static __u8 sl811_rh_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; */	0x02,	    /*	__u8  iProduct; */	0x01,	    /*	__u8  iSerialNumber; */	0x01	    /*	__u8  bNumConfigurations; */};/* Configuration descriptor */static __u8 sl811_rh_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 */	0x08,	    /*	__u16 ep_wMaxPacketSize; */	0x00,	0xff	    /*	__u8  ep_bInterval; 255 ms */};/* root hub class descriptor*/static __u8 sl811_rh_hub_des[] ={	0x09,			/*  __u8  bLength; */	0x29,			/*  __u8  bDescriptorType; Hub-descriptor */	0x01,			/*  __u8  bNbrPorts; */	0x00,			/* __u16  wHubCharacteristics; */	0x00,	0x50,			/*  __u8  bPwrOn2pwrGood; 2ms */	0x00,			/*  __u8  bHubContrCurrent; 0 mA */	0xfc,			/*  __u8  DeviceRemovable; *** 7 Ports max *** */	0xff			/*  __u8  PortPwrCtrlMask; *** 7 ports max *** */};/* * helper routine for returning string descriptors in UTF-16LE * input can actually be ISO-8859-1; ASCII is its 7-bit subset */static int ascii2utf (char *s, u8 *utf, int utfmax){	int retval;	for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) {		*utf++ = *s++;		*utf++ = 0;	}	return retval;}/* * root_hub_string is used by each host controller's root hub code, * so that they're identified consistently throughout the system. */static int usb_root_hub_string (int id, int serial, char *type, __u8 *data, int len){	char buf [30];	/* assert (len > (2 * (sizeof (buf) + 1)));	   assert (strlen (type) <= 8);*/	/* language ids */	if (id == 0) {		*data++ = 4; *data++ = 3;	/* 4 bytes data */		*data++ = 0; *data++ = 0;	/* some language id */		return 4;	/* serial number */	} else if (id == 1) {		sprintf (buf, "%#x", serial);	/* product description */	} else if (id == 2) {		sprintf (buf, "USB %s Root Hub", type);	/* id 3 == vendor description */	/* unsupported IDs --> "stall" */	} else	    return 0;	ascii2utf (buf, data + 2, len - 2);	data [0] = 2 + strlen(buf) * 2;	data [1] = 3;	return data [0];}/* helper macro */#define OK(x)	len = (x); break/* * This function handles all USB request to the the virtual root hub */static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe,			       void *data, int buf_len, struct devrequest *cmd){	__u8 data_buf[16];	__u8 *bufp = data_buf;	int len = 0;	int status = 0;	__u16 bmRType_bReq;	__u16 wValue;	__u16 wIndex;	__u16 wLength;	if (usb_pipeint(pipe)) {		PDEBUG(0, "interrupt transfer unimplemented!\n");		return 0;	}	bmRType_bReq  = cmd->requesttype | (cmd->request << 8);	wValue	      = le16_to_cpu (cmd->value);	wIndex	      = le16_to_cpu (cmd->index);	wLength	      = le16_to_cpu (cmd->length);	PDEBUG(5, "submit rh urb, req = %d(%x) val = %#x index = %#x len=%d\n",	       bmRType_bReq, bmRType_bReq, wValue, wIndex, wLength);	/* Request Destination:		   without flags: Device,		   USB_RECIP_INTERFACE: interface,		   USB_RECIP_ENDPOINT: endpoint,		   USB_TYPE_CLASS means HUB here,		   USB_RECIP_OTHER | USB_TYPE_CLASS  almost ever means HUB_PORT here	*/	switch (bmRType_bReq) {	case RH_GET_STATUS:		*(__u16 *)bufp = cpu_to_le16(1);		OK(2);	case RH_GET_STATUS | USB_RECIP_INTERFACE:		*(__u16 *)bufp = cpu_to_le16(0);		OK(2);	case RH_GET_STATUS | USB_RECIP_ENDPOINT:		*(__u16 *)bufp = cpu_to_le16(0);		OK(2);	case RH_GET_STATUS | USB_TYPE_CLASS:		*(__u32 *)bufp = cpu_to_le32(0);		OK(4);	case RH_GET_STATUS | USB_RECIP_OTHER | USB_TYPE_CLASS:		*(__u32 *)bufp = cpu_to_le32(rh_status.wPortChange<<16 | rh_status.wPortStatus);		OK(4);	case RH_CLEAR_FEATURE | USB_RECIP_ENDPOINT:		switch (wValue) {		case 1:			OK(0);		}		break;	case RH_CLEAR_FEATURE | USB_TYPE_CLASS:		switch (wValue) {		case C_HUB_LOCAL_POWER:			OK(0);		case C_HUB_OVER_CURRENT:			OK(0);		}		break;	case RH_CLEAR_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:		switch (wValue) {		case USB_PORT_FEAT_ENABLE:			rh_status.wPortStatus &= ~USB_PORT_STAT_ENABLE;			OK(0);		case USB_PORT_FEAT_SUSPEND:			rh_status.wPortStatus &= ~USB_PORT_STAT_SUSPEND;			OK(0);		case USB_PORT_FEAT_POWER:			rh_status.wPortStatus &= ~USB_PORT_STAT_POWER;			OK(0);		case USB_PORT_FEAT_C_CONNECTION:			rh_status.wPortChange &= ~USB_PORT_STAT_C_CONNECTION;			OK(0);		case USB_PORT_FEAT_C_ENABLE:			rh_status.wPortChange &= ~USB_PORT_STAT_C_ENABLE;			OK(0);		case USB_PORT_FEAT_C_SUSPEND:			rh_status.wPortChange &= ~USB_PORT_STAT_C_SUSPEND;			OK(0);		case USB_PORT_FEAT_C_OVER_CURRENT:			rh_status.wPortChange &= ~USB_PORT_STAT_C_OVERCURRENT;			OK(0);		case USB_PORT_FEAT_C_RESET:			rh_status.wPortChange &= ~USB_PORT_STAT_C_RESET;			OK(0);		}		break;	case RH_SET_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:		switch (wValue) {		case USB_PORT_FEAT_SUSPEND:			rh_status.wPortStatus |= USB_PORT_STAT_SUSPEND;			OK(0);		case USB_PORT_FEAT_RESET:			rh_status.wPortStatus |= USB_PORT_STAT_RESET;			rh_status.wPortChange = 0;			rh_status.wPortChange |= USB_PORT_STAT_C_RESET;			rh_status.wPortStatus &= ~USB_PORT_STAT_RESET;			rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;			OK(0);		case USB_PORT_FEAT_POWER:			rh_status.wPortStatus |= USB_PORT_STAT_POWER;			OK(0);		case USB_PORT_FEAT_ENABLE:			rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;			OK(0);		}		break;	case RH_SET_ADDRESS:		root_hub_devnum = wValue;		OK(0);	case RH_GET_DESCRIPTOR:		switch ((wValue & 0xff00) >> 8) {		case USB_DT_DEVICE:			len = sizeof(sl811_rh_dev_des);			bufp = sl811_rh_dev_des;			OK(len);		case USB_DT_CONFIG:			len = sizeof(sl811_rh_config_des);			bufp = sl811_rh_config_des;			OK(len);		case USB_DT_STRING:			len = usb_root_hub_string(wValue & 0xff, (int)(long)0,	"SL811HS", data, wLength);			if (len > 0) {				bufp = data;				OK(len);			}		default:			status = -32;		}		break;	case RH_GET_DESCRIPTOR | USB_TYPE_CLASS:		len = sizeof(sl811_rh_hub_des);		bufp = sl811_rh_hub_des;		OK(len);	case RH_GET_CONFIGURATION:		bufp[0] = 0x01;		OK(1);	case RH_SET_CONFIGURATION:		OK(0);	default:		PDEBUG(1, "unsupported root hub command\n");		status = -32;	}	len = min(len, buf_len);	if (data != bufp)		memcpy(data, bufp, len);	PDEBUG(5, "len = %d, status = %d\n", len, status);	usb_dev->status = status;	usb_dev->act_len = len;	return status == 0 ? len : status;}#endif	/* CONFIG_USB_SL811HS */

⌨️ 快捷键说明

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