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

📄 usb_storage.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 3 页
字号:
	return USB_STOR_TRANSPORT_FAILED;}static int usb_inquiry(ccb *srb,struct us_data *ss){	int retry,i;	retry=3;	do {		memset(&srb->cmd[0],0,12);		srb->cmd[0]=SCSI_INQUIRY;		srb->cmd[1]=srb->lun<<5;		srb->cmd[4]=36;		srb->datalen=36;		srb->cmdlen=12;		i=ss->transport(srb,ss);		USB_STOR_PRINTF("inquiry returns %d\n",i);		if(i==0)			break;	} while(retry--);	if(!retry) {		printf("error in inquiry\n");		return -1;	}	return 0;}static int usb_request_sense(ccb *srb,struct us_data *ss){	char *ptr;	ptr=srb->pdata;	memset(&srb->cmd[0],0,12);	srb->cmd[0]=SCSI_REQ_SENSE;	srb->cmd[1]=srb->lun<<5;	srb->cmd[4]=18;	srb->datalen=18;	srb->pdata=&srb->sense_buf[0];	srb->cmdlen=12;	ss->transport(srb,ss);	USB_STOR_PRINTF("Request Sense returned %02X %02X %02X\n",srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);	srb->pdata=ptr;	return 0;}static int usb_test_unit_ready(ccb *srb,struct us_data *ss){	int retries=10;	do {		memset(&srb->cmd[0],0,12);		srb->cmd[0]=SCSI_TST_U_RDY;		srb->cmd[1]=srb->lun<<5;		srb->datalen=0;		srb->cmdlen=12;		if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD) {			return 0;		}		usb_request_sense (srb, ss);		wait_ms (100);	} while(retries--);	return -1;}static int usb_read_capacity(ccb *srb,struct us_data *ss){	int retry;	retry=2; /* retries */	do {		memset(&srb->cmd[0],0,12);		srb->cmd[0]=SCSI_RD_CAPAC;		srb->cmd[1]=srb->lun<<5;		srb->datalen=8;		srb->cmdlen=12;		if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD) {			return 0;		}	} while(retry--);	return -1;}static int usb_read_10(ccb *srb,struct us_data *ss, unsigned long start, unsigned short blocks){	memset(&srb->cmd[0],0,12);	srb->cmd[0]=SCSI_READ10;	srb->cmd[1]=srb->lun<<5;	srb->cmd[2]=((unsigned char) (start>>24))&0xff;	srb->cmd[3]=((unsigned char) (start>>16))&0xff;	srb->cmd[4]=((unsigned char) (start>>8))&0xff;	srb->cmd[5]=((unsigned char) (start))&0xff;	srb->cmd[7]=((unsigned char) (blocks>>8))&0xff;	srb->cmd[8]=(unsigned char) blocks & 0xff;	srb->cmdlen=12;	USB_STOR_PRINTF("read10: start %lx blocks %x\n",start,blocks);	return ss->transport(srb,ss);}#define USB_MAX_READ_BLK 20unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, unsigned long *buffer){	unsigned long start,blks, buf_addr;	unsigned short smallblks;	struct usb_device *dev;	int retry,i;	ccb *srb = &usb_ccb;	if (blkcnt == 0)		return 0;	device &= 0xff;	/* Setup  device	 */	USB_STOR_PRINTF("\nusb_read: dev %d \n",device);	dev=NULL;	for(i=0;i<USB_MAX_DEVICE;i++) {		dev=usb_get_dev_index(i);		if(dev==NULL) {			return 0;		}		if(dev->devnum==usb_dev_desc[device].target)			break;	}	usb_disable_asynch(1); /* asynch transfer not allowed */	srb->lun=usb_dev_desc[device].lun;	buf_addr=(unsigned long)buffer;	start=blknr;	blks=blkcnt;	if(usb_test_unit_ready(srb,(struct us_data *)dev->privptr)) {		printf("Device NOT ready\n   Request Sense returned %02X %02X %02X\n",			srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);		return 0;	}	USB_STOR_PRINTF("\nusb_read: dev %d startblk %lx, blccnt %lx buffer %lx\n",device,start,blks, buf_addr);	do {		retry=2;		srb->pdata=(unsigned char *)buf_addr;		if(blks>USB_MAX_READ_BLK) {			smallblks=USB_MAX_READ_BLK;		} else {			smallblks=(unsigned short) blks;		}retry_it:		if(smallblks==USB_MAX_READ_BLK)			usb_show_progress();		srb->datalen=usb_dev_desc[device].blksz * smallblks;		srb->pdata=(unsigned char *)buf_addr;		if(usb_read_10(srb,(struct us_data *)dev->privptr, start, smallblks)) {			USB_STOR_PRINTF("Read ERROR\n");			usb_request_sense(srb,(struct us_data *)dev->privptr);			if(retry--)				goto retry_it;			blkcnt-=blks;			break;		}		start+=smallblks;		blks-=smallblks;		buf_addr+=srb->datalen;	} while(blks!=0);	USB_STOR_PRINTF("usb_read: end startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);	usb_disable_asynch(0); /* asynch transfer allowed */	if(blkcnt>=USB_MAX_READ_BLK)		printf("\n");	return(blkcnt);}/* Probe to see if a new device is actually a Storage device */int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data *ss){	struct usb_interface_descriptor *iface;	int i;	unsigned int flags = 0;	int protocol = 0;	int subclass = 0;	memset(ss, 0, sizeof(struct us_data));	/* let's examine the device now */	iface = &dev->config.if_desc[ifnum];#if 0	/* this is the place to patch some storage devices */	USB_STOR_PRINTF("iVendor %X iProduct %X\n",dev->descriptor.idVendor,dev->descriptor.idProduct);	if ((dev->descriptor.idVendor) == 0x066b && (dev->descriptor.idProduct) == 0x0103) {		USB_STOR_PRINTF("patched for E-USB\n");		protocol = US_PR_CB;		subclass = US_SC_UFI;	    /* an assumption */	}#endif	if (dev->descriptor.bDeviceClass != 0 ||			iface->bInterfaceClass != USB_CLASS_MASS_STORAGE ||			iface->bInterfaceSubClass < US_SC_MIN ||			iface->bInterfaceSubClass > US_SC_MAX) {		/* if it's not a mass storage, we go no further */		return 0;	}	/* At this point, we know we've got a live one */	USB_STOR_PRINTF("\n\nUSB Mass Storage device detected\n");	/* Initialize the us_data structure with some useful info */	ss->flags = flags;	ss->ifnum = ifnum;	ss->pusb_dev = dev;	ss->attention_done = 0;	/* If the device has subclass and protocol, then use that.  Otherwise,	 * take data from the specific interface.	 */	if (subclass) {		ss->subclass = subclass;		ss->protocol = protocol;	} else {		ss->subclass = iface->bInterfaceSubClass;		ss->protocol = iface->bInterfaceProtocol;	}	/* set the handler pointers based on the protocol */	USB_STOR_PRINTF("Transport: ");	switch (ss->protocol) {	case US_PR_CB:		USB_STOR_PRINTF("Control/Bulk\n");		ss->transport = usb_stor_CB_transport;		ss->transport_reset = usb_stor_CB_reset;		break;	case US_PR_CBI:		USB_STOR_PRINTF("Control/Bulk/Interrupt\n");		ss->transport = usb_stor_CB_transport;		ss->transport_reset = usb_stor_CB_reset;		break;	case US_PR_BULK:		USB_STOR_PRINTF("Bulk/Bulk/Bulk\n");		ss->transport = usb_stor_BBB_transport;		ss->transport_reset = usb_stor_BBB_reset;		break;	default:		printf("USB Storage Transport unknown / not yet implemented\n");		return 0;		break;	}	/*	 * We are expecting a minimum of 2 endpoints - in and out (bulk).	 * An optional interrupt is OK (necessary for CBI protocol).	 * We will ignore any others.	 */	for (i = 0; i < iface->bNumEndpoints; i++) {		/* is it an BULK endpoint? */		if ((iface->ep_desc[i].bmAttributes &  USB_ENDPOINT_XFERTYPE_MASK)		    == USB_ENDPOINT_XFER_BULK) {			if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)				ss->ep_in = iface->ep_desc[i].bEndpointAddress &					USB_ENDPOINT_NUMBER_MASK;			else				ss->ep_out = iface->ep_desc[i].bEndpointAddress &					USB_ENDPOINT_NUMBER_MASK;		}		/* is it an interrupt endpoint? */		if ((iface->ep_desc[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)		    == USB_ENDPOINT_XFER_INT) {			ss->ep_int = iface->ep_desc[i].bEndpointAddress &				USB_ENDPOINT_NUMBER_MASK;			ss->irqinterval = iface->ep_desc[i].bInterval;		}	}	USB_STOR_PRINTF("Endpoints In %d Out %d Int %d\n",		  ss->ep_in, ss->ep_out, ss->ep_int);	/* Do some basic sanity checks, and bail if we find a problem */	if (usb_set_interface(dev, iface->bInterfaceNumber, 0) ||	    !ss->ep_in || !ss->ep_out ||	    (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {		USB_STOR_PRINTF("Problems with device\n");		return 0;	}	/* set class specific stuff */	/* We only handle certain protocols.  Currently, these are	 * the only ones.	 * The SFF8070 accepts the requests used in u-boot	 */	if (ss->subclass != US_SC_UFI && ss->subclass != US_SC_SCSI &&	    ss->subclass != US_SC_8070) {		printf("Sorry, protocol %d not yet supported.\n",ss->subclass);		return 0;	}	if(ss->ep_int) { /* we had found an interrupt endpoint, prepare irq pipe */		/* set up the IRQ pipe and handler */		ss->irqinterval = (ss->irqinterval > 0) ? ss->irqinterval : 255;		ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);		ss->irqmaxp = usb_maxpacket(dev, ss->irqpipe);		dev->irq_handle=usb_stor_irq;	}	dev->privptr=(void *)ss;	return 1;}int usb_stor_get_info(struct usb_device *dev,struct us_data *ss,block_dev_desc_t *dev_desc){	unsigned char perq,modi;	unsigned long cap[2];	unsigned long *capacity,*blksz;	ccb *pccb=&usb_ccb;	/* For some mysterious reason the 256MB flash disk of Ours Technology, Inc	 * doesn't survive this reset */	if (dev->descriptor.idVendor != 0xea0 || dev->descriptor.idProduct != 0x6828)		ss->transport_reset(ss);	pccb->pdata=usb_stor_buf;	dev_desc->target=dev->devnum;	pccb->lun=dev_desc->lun;	USB_STOR_PRINTF(" address %d\n",dev_desc->target);	if(usb_inquiry(pccb,ss))		return -1;	perq=usb_stor_buf[0];	modi=usb_stor_buf[1];	if((perq & 0x1f)==0x1f) {		return 0; /* skip unknown devices */	}	if((modi&0x80)==0x80) {/* drive is removable */		dev_desc->removable=1;	}	memcpy(&dev_desc->vendor[0], &usb_stor_buf[8], 8);	memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);	memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);	dev_desc->vendor[8]=0;	dev_desc->product[16]=0;	dev_desc->revision[4]=0;	USB_STOR_PRINTF("ISO Vers %X, Response Data %X\n",usb_stor_buf[2],usb_stor_buf[3]);	if(usb_test_unit_ready(pccb,ss)) {		printf("Device NOT ready\n   Request Sense returned %02X %02X %02X\n",pccb->sense_buf[2],pccb->sense_buf[12],pccb->sense_buf[13]);		if(dev_desc->removable==1) {			dev_desc->type=perq;			return 1;		}		else			return 0;	}	pccb->pdata=(unsigned char *)&cap[0];	memset(pccb->pdata,0,8);	if(usb_read_capacity(pccb,ss)!=0) {		printf("READ_CAP ERROR\n");		cap[0]=2880;		cap[1]=0x200;	}	USB_STOR_PRINTF("Read Capacity returns: 0x%lx, 0x%lx\n",cap[0],cap[1]);#if 0	if(cap[0]>(0x200000 * 10)) /* greater than 10 GByte */		cap[0]>>=16;#endif#ifdef LITTLEENDIAN	cap[0] = ((unsigned long)(		(((unsigned long)(cap[0]) & (unsigned long)0x000000ffUL) << 24) |		(((unsigned long)(cap[0]) & (unsigned long)0x0000ff00UL) <<  8) |		(((unsigned long)(cap[0]) & (unsigned long)0x00ff0000UL) >>  8) |		(((unsigned long)(cap[0]) & (unsigned long)0xff000000UL) >> 24) ));	cap[1] = ((unsigned long)(		(((unsigned long)(cap[1]) & (unsigned long)0x000000ffUL) << 24) |		(((unsigned long)(cap[1]) & (unsigned long)0x0000ff00UL) <<  8) |		(((unsigned long)(cap[1]) & (unsigned long)0x00ff0000UL) >>  8) |		(((unsigned long)(cap[1]) & (unsigned long)0xff000000UL) >> 24) ));#endif	/* this assumes bigendian! */	cap[0]+=1;	capacity=&cap[0];	blksz=&cap[1];	USB_STOR_PRINTF("Capacity = 0x%lx, blocksz = 0x%lx\n",*capacity,*blksz);	dev_desc->lba=*capacity;	dev_desc->blksz=*blksz;	dev_desc->type=perq;	USB_STOR_PRINTF(" address %d\n",dev_desc->target);	USB_STOR_PRINTF("partype: %d\n",dev_desc->part_type);	init_part(dev_desc);	USB_STOR_PRINTF("partype: %d\n",dev_desc->part_type);	return 1;}#endif /* CONFIG_USB_STORAGE */#endif /* CFG_CMD_USB */

⌨️ 快捷键说明

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