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

📄 usb.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * (C) Copyright 2001 * Denis Peter, MPL AG Switzerland * * Most of this source has been derived from the Linux USB * project. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * *//* * How it works: * * Since this is a bootloader, the devices will not be automatic * (re)configured on hotplug, but after a restart of the USB the * device should work. * * For each transfer (except "Interrupt") we wait for completion. */#include <common.h>#include <command.h>#include <asm/processor.h>#if (CONFIG_COMMANDS & CFG_CMD_USB)#include <usb.h>#ifdef CONFIG_4xx#include <405gp_pci.h>#endif/* #define USB_DEBUG */#ifdef	USB_DEBUG#define	USB_PRINTF(fmt,args...)	printf (fmt ,##args)#else#define USB_PRINTF(fmt,args...)#endif#define USB_BUFSIZ	512static struct usb_device usb_dev[USB_MAX_DEVICE];static int dev_index;static int running;static int asynch_allowed;static struct devrequest setup_packet;/********************************************************************** * some forward declerations... */void usb_scan_devices(void);int usb_hub_probe(struct usb_device *dev, int ifnum);void usb_hub_reset(void);/*********************************************************************** * wait_ms */void __inline__ wait_ms(unsigned long ms){	while(ms-->0)		udelay(1000);}/*************************************************************************** * Init USB Device */int usb_init(void){	int result;	running=0;	dev_index=0;	asynch_allowed=1;	usb_hub_reset();	/* init low_level USB */	printf("USB:   ");	result = usb_lowlevel_init();	/* if lowlevel init is OK, scan the bus for devices i.e. search HUBs and configure them */	if(result==0) {		printf("scanning bus for devices... ");		running=1;		usb_scan_devices();		return 0;	}	else {		printf("Error, couldn't init Lowlevel part\n");		return -1;	}}/****************************************************************************** * Stop USB this stops the LowLevel Part and deregisters USB devices. */int usb_stop(void){	asynch_allowed=1;	usb_hub_reset();	return usb_lowlevel_stop();}/* * disables the asynch behaviour of the control message. This is used for data * transfers that uses the exclusiv access to the control and bulk messages. */void usb_disable_asynch(int disable){	asynch_allowed=!disable;}/*------------------------------------------------------------------- * Message wrappers. * *//* * submits an Interrupt Message */int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe,			void *buffer,int transfer_len, int interval){	return submit_int_msg(dev,pipe,buffer,transfer_len,interval);}/* * submits a control message and waits for comletion (at least timeout * 1ms) * If timeout is 0, we don't wait for completion (used as example to set and * clear keyboards LEDs). For data transfers, (storage transfers) we don't * allow control messages with 0 timeout, by previousely resetting the flag * asynch_allowed (usb_disable_asynch(1)). * returns the transfered length if OK or -1 if error. The transfered length * and the current status are stored in the dev->act_len and dev->status. */int usb_control_msg(struct usb_device *dev, unsigned int pipe,			unsigned char request, unsigned char requesttype,			unsigned short value, unsigned short index,			void *data, unsigned short size, int timeout){	if((timeout==0)&&(!asynch_allowed)) /* request for a asynch control pipe is not allowed */		return -1;	/* set setup command */	setup_packet.requesttype = requesttype;	setup_packet.request = request;	setup_packet.value = swap_16(value);	setup_packet.index = swap_16(index);	setup_packet.length = swap_16(size); 	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X\nvalue 0x%X index 0x%X length 0x%X\n",		request,requesttype,value,index,size);	dev->status=USB_ST_NOT_PROC; /*not yet processed */	submit_control_msg(dev,pipe,data,size,&setup_packet);	if(timeout==0) {		return (int)size;	}	while(timeout--) {		if(!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))			break;		wait_ms(1);	}	if(dev->status==0)		return dev->act_len;	else {		return -1;	}}/*------------------------------------------------------------------- * submits bulk message, and waits for completion. returns 0 if Ok or * -1 if Error. * synchronous behavior */int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,			void *data, int len, int *actual_length, int timeout){	if (len < 0)		return -1;	dev->status=USB_ST_NOT_PROC; /*not yet processed */	submit_bulk_msg(dev,pipe,data,len);	while(timeout--) {		if(!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))			break;		wait_ms(1);	}	*actual_length=dev->act_len;	if(dev->status==0)		return 0;	else		return -1;}/*------------------------------------------------------------------- * Max Packet stuff *//* * returns the max packet size, depending on the pipe direction and * the configurations values */int usb_maxpacket(struct usb_device *dev,unsigned long pipe){	if((pipe & USB_DIR_IN)==0) /* direction is out -> use emaxpacket out */		return(dev->epmaxpacketout[((pipe>>15) & 0xf)]);	else		return(dev->epmaxpacketin[((pipe>>15) & 0xf)]);}/* * set the max packed value of all endpoints in the given configuration */int usb_set_maxpacket(struct usb_device *dev){	int i,ii,b;	struct usb_endpoint_descriptor *ep;	for(i=0; i<dev->config.bNumInterfaces;i++) {		for(ii=0; ii<dev->config.if_desc[i].bNumEndpoints; ii++) {			ep=&dev->config.if_desc[i].ep_desc[ii];			b=ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;			if((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)==USB_ENDPOINT_XFER_CONTROL) {	/* Control => bidirectional */				dev->epmaxpacketout[b] = ep->wMaxPacketSize;				dev->epmaxpacketin [b] = ep->wMaxPacketSize;				USB_PRINTF("##Control EP epmaxpacketout/in[%d] = %d\n",b,dev->epmaxpacketin[b]);			}			else {				if ((ep->bEndpointAddress & 0x80)==0) { /* OUT Endpoint */					if(ep->wMaxPacketSize > dev->epmaxpacketout[b]) {						dev->epmaxpacketout[b] = ep->wMaxPacketSize;						USB_PRINTF("##EP epmaxpacketout[%d] = %d\n",b,dev->epmaxpacketout[b]);					}				}				else  { /* IN Endpoint */					if(ep->wMaxPacketSize > dev->epmaxpacketin[b]) {						dev->epmaxpacketin[b] = ep->wMaxPacketSize;						USB_PRINTF("##EP epmaxpacketin[%d] = %d\n",b,dev->epmaxpacketin[b]);					}				} /* if out */			} /* if control */		} /* for each endpoint */	}	return 0;}/******************************************************************************* * Parse the config, located in buffer, and fills the dev->config structure. * Note that all little/big endian swapping are done automatically. */int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno){	struct usb_descriptor_header *head;	int index,ifno,epno;	ifno=-1;	epno=-1;	dev->configno=cfgno;	head =(struct usb_descriptor_header *)&buffer[0];	if(head->bDescriptorType!=USB_DT_CONFIG) {		printf(" ERROR: NOT USB_CONFIG_DESC %x\n",head->bDescriptorType);		return -1;	}	memcpy(&dev->config,buffer,buffer[0]);	dev->config.wTotalLength=swap_16(dev->config.wTotalLength);	dev->config.no_of_if=0;	index=dev->config.bLength;	/* Ok the first entry must be a configuration entry, now process the others */	head=(struct usb_descriptor_header *)&buffer[index];	while(index+1 < dev->config.wTotalLength) {		switch(head->bDescriptorType) {			case USB_DT_INTERFACE:				ifno=dev->config.no_of_if;				dev->config.no_of_if++; /* found an interface desc, increase numbers */				memcpy(&dev->config.if_desc[ifno],&buffer[index],buffer[index]); /* copy new desc */				dev->config.if_desc[ifno].no_of_ep=0;				break;			case USB_DT_ENDPOINT:				epno=dev->config.if_desc[ifno].no_of_ep;				dev->config.if_desc[ifno].no_of_ep++; /* found an endpoint */				memcpy(&dev->config.if_desc[ifno].ep_desc[epno],&buffer[index],buffer[index]);				dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize					=swap_16(dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize);				USB_PRINTF("if %d, ep %d\n",ifno,epno);				break;			default:				if(head->bLength==0)					return 1;				USB_PRINTF("unknown Description Type : %x\n",head->bDescriptorType);				{					int i;					unsigned char *ch;					ch=(unsigned char *)head;					for(i=0;i<head->bLength; i++)						USB_PRINTF("%02X ",*ch++);					USB_PRINTF("\n\n\n");				}				break;		}		index+=head->bLength;		head=(struct usb_descriptor_header *)&buffer[index];	}	return 1;}/*********************************************************************** * Clears an endpoint * endp: endpoint number in bits 0-3; * direction flag in bit 7 (1 = IN, 0 = OUT) */int usb_clear_halt(struct usb_device *dev, int pipe){	int result;	unsigned short status;	int endp=usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7);	result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),		USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0, USB_CNTL_TIMEOUT * 3);	/* don't clear if failed */	if (result < 0)		return result;	result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp,		&status, sizeof(status), USB_CNTL_TIMEOUT * 3);	if (result < 0)		return result;	USB_PRINTF("usb_clear_halt: status 0x%x\n",status);	if (status & 1)		return -1;		/* still halted */	usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));	/* toggle is reset on clear */	usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);	return 0;}/********************************************************************** * get_descriptor type */int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size){	int res; 	res = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),			USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,			(type << 8) + index, 0,

⌨️ 快捷键说明

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