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

📄 usb.c

📁 嵌入式试验箱S3C2410的bootloader源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		USB_PRINTF("usb_get_configuration_no: failed to get descriptor - too long: %d\n",			tmp);		return -1;	}	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, tmp);	USB_PRINTF("get_conf_no %d Result %d, wLength %d\n",cfgno,result,tmp);	return result;}/******************************************************************** * set address of a device to the value in dev->devnum. * This can only be done by addressing the device via the default address (0) */int usb_set_address(struct usb_device *dev){	int res;	USB_PRINTF("set address %d\n",dev->devnum);	res=usb_control_msg(dev, usb_snddefctrl(dev),		USB_REQ_SET_ADDRESS, 0,		(dev->devnum),0,		NULL,0, USB_CNTL_TIMEOUT);	return res;}/******************************************************************** * set interface number to interface */int usb_set_interface(struct usb_device *dev, int interface, int alternate){	struct usb_interface_descriptor *if_face = NULL;	int ret, i;	for (i = 0; i < dev->config.bNumInterfaces; i++) {		if (dev->config.if_desc[i].bInterfaceNumber == interface) {			if_face = &dev->config.if_desc[i];			break;		}	}	if (!if_face) {		printf("selecting invalid interface %d", interface);		return -1;	}	/*	 * We should return now for devices with only one alternate setting.	 * According to 9.4.10 of the Universal Serial Bus Specification Revision 2.0	 * such devices can return with a STALL. This results in some USB sticks	 * timeouting during initialization and then being unusable in U-Boot.	 */	if (if_face->num_altsetting == 1)		return 0;	if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),	    USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate,	    interface, NULL, 0, USB_CNTL_TIMEOUT * 5)) < 0)		return ret;	return 0;}/******************************************************************** * set configuration number to configuration */int usb_set_configuration(struct usb_device *dev, int configuration){	int res;	USB_PRINTF("set configuration %d\n",configuration);	/* set setup command */	res=usb_control_msg(dev, usb_sndctrlpipe(dev,0),		USB_REQ_SET_CONFIGURATION, 0,		configuration,0,		NULL,0, USB_CNTL_TIMEOUT);	if(res==0) {		dev->toggle[0] = 0;		dev->toggle[1] = 0;		return 0;	}	else		return -1;}/******************************************************************** * set protocol to protocol */int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol){	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),		USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE,		protocol, ifnum, NULL, 0, USB_CNTL_TIMEOUT);}/******************************************************************** * set idle */int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id){	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),		USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE,		(duration << 8) | report_id, ifnum, NULL, 0, USB_CNTL_TIMEOUT);}/******************************************************************** * get report */int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size){	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),		USB_REQ_GET_REPORT, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,		(type << 8) + id, ifnum, buf, size, USB_CNTL_TIMEOUT);}/******************************************************************** * get class descriptor */int usb_get_class_descriptor(struct usb_device *dev, int ifnum,		unsigned char type, unsigned char id, void *buf, int size){	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),		USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,		(type << 8) + id, ifnum, buf, size, USB_CNTL_TIMEOUT);}/******************************************************************** * get string index in buffer */int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size){	int i;	int result;	for (i = 0; i < 3; ++i) {		/* some devices are flaky */		result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),			USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,			(USB_DT_STRING << 8) + index, langid, buf, size,			USB_CNTL_TIMEOUT);		if (result > 0)			break;	}	return result;}static void usb_try_string_workarounds(unsigned char *buf, int *length){	int newlength, oldlength = *length;	for (newlength = 2; newlength + 1 < oldlength; newlength += 2)		if (!isprint(buf[newlength]) || buf[newlength + 1])			break;	if (newlength > 2) {		buf[0] = newlength;		*length = newlength;	}}static int usb_string_sub(struct usb_device *dev, unsigned int langid,		unsigned int index, unsigned char *buf){	int rc;	/* Try to read the string descriptor by asking for the maximum	 * possible number of bytes */	rc = usb_get_string(dev, langid, index, buf, 255);	/* If that failed try to read the descriptor length, then	 * ask for just that many bytes */	if (rc < 2) {		rc = usb_get_string(dev, langid, index, buf, 2);		if (rc == 2)			rc = usb_get_string(dev, langid, index, buf, buf[0]);	}	if (rc >= 2) {		if (!buf[0] && !buf[1])			usb_try_string_workarounds(buf, &rc);		/* There might be extra junk at the end of the descriptor */		if (buf[0] < rc)			rc = buf[0];		rc = rc - (rc & 1); /* force a multiple of two */	}	if (rc < 2)		rc = -1;	return rc;}/******************************************************************** * usb_string: * Get string index and translate it to ascii. * returns string length (> 0) or error (< 0) */int usb_string(struct usb_device *dev, int index, char *buf, size_t size){	unsigned char mybuf[USB_BUFSIZ];	unsigned char *tbuf;	int err;	unsigned int u, idx;	if (size <= 0 || !buf || !index)		return -1;	buf[0] = 0;	tbuf=&mybuf[0];	/* get langid for strings if it's not yet known */	if (!dev->have_langid) {		err = usb_string_sub(dev, 0, 0, tbuf);		if (err < 0) {			USB_PRINTF("error getting string descriptor 0 (error=%x)\n",dev->status);			return -1;		} else if (tbuf[0] < 4) {			USB_PRINTF("string descriptor 0 too short\n");			return -1;		} else {			dev->have_langid = -1;			dev->string_langid = tbuf[2] | (tbuf[3]<< 8);				/* always use the first langid listed */			USB_PRINTF("USB device number %d default language ID 0x%x\n",				dev->devnum, dev->string_langid);		}	}	err = usb_string_sub(dev, dev->string_langid, index, tbuf);	if (err < 0)		return err;	size--;		/* leave room for trailing NULL char in output buffer */	for (idx = 0, u = 2; u < err; u += 2) {		if (idx >= size)			break;		if (tbuf[u+1])			/* high byte */			buf[idx++] = '?';  /* non-ASCII character */		else			buf[idx++] = tbuf[u];	}	buf[idx] = 0;	err = idx;	return err;}/******************************************************************** * USB device handling: * the USB device are static allocated [USB_MAX_DEVICE]. *//* returns a pointer to the device with the index [index]. * if the device is not assigned (dev->devnum==-1) returns NULL */struct usb_device * usb_get_dev_index(int index){	if(usb_dev[index].devnum==-1)		return NULL;	else		return &usb_dev[index];}/* returns a pointer of a new device structure or NULL, if * no device struct is available */struct usb_device * usb_alloc_new_device(void){	int i;	USB_PRINTF("New Device %d\n",dev_index);	if(dev_index==USB_MAX_DEVICE) {		printf("ERROR, too many USB Devices, max=%d\n",USB_MAX_DEVICE);		return NULL;	}	usb_dev[dev_index].devnum=dev_index+1; /* default Address is 0, real addresses start with 1 */	usb_dev[dev_index].maxchild=0;	for(i=0;i<USB_MAXCHILDREN;i++)		usb_dev[dev_index].children[i]=NULL;	usb_dev[dev_index].parent=NULL;	dev_index++;	return &usb_dev[dev_index-1];}/* * By the time we get here, the device has gotten a new device ID * and is in the default state. We need to identify the thing and * get the ball rolling.. * * Returns 0 for success, != 0 for error. */int usb_new_device(struct usb_device *dev){	int addr, err;	int tmp;	unsigned char tmpbuf[USB_BUFSIZ];	dev->descriptor.bMaxPacketSize0 = 8;  /* Start off at 8 bytes  */	dev->maxpacketsize = 0;		/* Default to 8 byte max packet size */	dev->epmaxpacketin [0] = 8;	dev->epmaxpacketout[0] = 8;	/* We still haven't set the Address yet */	addr = dev->devnum;	dev->devnum = 0;#undef NEW_INIT_SEQ#ifdef NEW_INIT_SEQ	/* this is a Windows scheme of initialization sequence, with double	 * reset of the device. Some equipment is said to work only with such	 * init sequence; this patch is based on the work by Alan Stern:	 * http://sourceforge.net/mailarchive/forum.php?thread_id=5729457&forum_id=5398	 */	int j;	struct usb_device_descriptor *desc;	int port = -1;	struct usb_device *parent = dev->parent;	unsigned short portstatus;	/* send 64-byte GET-DEVICE-DESCRIPTOR request.  Since the descriptor is	 * only 18 bytes long, this will terminate with a short packet.  But if	 * the maxpacket size is 8 or 16 the device may be waiting to transmit	 * some more. */	desc = (struct usb_device_descriptor *)tmpbuf;	desc->bMaxPacketSize0 = 0;	for (j = 0; j < 3; ++j) {		err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);		if (err < 0) {			USB_PRINTF("usb_new_device: 64 byte descr\n");			break;		}	}	dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0;	/* find the port number we're at */	if (parent) {		for (j = 0; j < parent->maxchild; j++) {			if (parent->children[j] == dev) {				port = j;				break;			}		}		if (port < 0) {			printf("usb_new_device: cannot locate device's port..\n");			return 1;		}		/* reset the port for the second time */		err = hub_port_reset(dev->parent, port, &portstatus);		if (err < 0) {			printf("\n     Couldn't reset port %i\n", port);			return 1;		}	}#else	/* and this is the old and known way of initializing devices */	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);	if (err < 8) {		printf("\n      USB device not responding, giving up (status=%lX)\n",dev->status);		return 1;	}#endif	dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;	dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;	switch (dev->descriptor.bMaxPacketSize0) {		case 8: dev->maxpacketsize = 0; break;		case 16: dev->maxpacketsize = 1; break;		case 32: dev->maxpacketsize = 2; break;		case 64: dev->maxpacketsize = 3; break;	}	dev->devnum = addr;	err = usb_set_address(dev); /* set address */	if (err < 0) {		printf("\n      USB device not accepting new address (error=%lX)\n", dev->status);		return 1;	}	wait_ms(10);	/* Let the SET_ADDRESS settle */	tmp = sizeof(dev->descriptor);	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, sizeof(dev->descriptor));	if (err < tmp) {		if (err < 0)			printf("unable to get device descriptor (error=%d)\n",err);		else			printf("USB device descriptor short read (expected %i, got %i)\n",tmp,err);		return 1;	}	/* correct le values */	dev->descriptor.bcdUSB=swap_16(dev->descriptor.bcdUSB);	dev->descriptor.idVendor=swap_16(dev->descriptor.idVendor);	dev->descriptor.idProduct=swap_16(dev->descriptor.idProduct);	dev->descriptor.bcdDevice=swap_16(dev->descriptor.bcdDevice);	/* only support for one config for now */	usb_get_configuration_no(dev,&tmpbuf[0],0);	usb_parse_config(dev,&tmpbuf[0],0);	usb_set_maxpacket(dev);	/* we set the default configuration here */	if (usb_set_configuration(dev, dev->config.bConfigurationValue)) {		printf("failed to set default configuration len %d, status %lX\n",dev->act_len,dev->status);		return -1;	}	USB_PRINTF("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",		dev->descriptor.iManufacturer, dev->descriptor.iProduct, dev->descriptor.iSerialNumber);	memset(dev->mf, 0, sizeof(dev->mf));	memset(dev->prod, 0, sizeof(dev->prod));	memset(dev->serial, 0, sizeof(dev->serial));

⌨️ 快捷键说明

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