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

📄 usb.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 3 页
字号:
		"eUSB ATA/ATAPI Adapter",		US_SC_8020, US_PR_CB, NULL, 0},	{ 0x04e6, 0x000a, 0x0200, 0x0200, 		"Shuttle",		"eUSB CompactFlash Adapter",		US_SC_8020, US_PR_CB, NULL, 0},	{ 0x04e6, 0x000B, 0x0100, 0x0100, 		"Shuttle",		"eUSCSI Bridge",		US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init, 		US_FL_SCM_MULT_TARG }, 	{ 0x04e6, 0x000C, 0x0100, 0x0100, 		"Shuttle",		"eUSCSI Bridge",		US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init, 		US_FL_SCM_MULT_TARG }, 	{ 0x04e6, 0x0101, 0x0200, 0x0200, 		"Shuttle",		"CD-RW Device",		US_SC_8020, US_PR_CB, NULL, 0},	{ 0x054c, 0x0010, 0x0106, 0x0210, 		"Sony",		"DSC-S30/S70/505V/F505", 		US_SC_SCSI, US_PR_CB, NULL,		US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_MODE_XLATE },	{ 0x054c, 0x002d, 0x0100, 0x0100, 		"Sony",		"Memorystick MSAC-US1",		US_SC_UFI, US_PR_CB, NULL,		US_FL_SINGLE_LUN | US_FL_START_STOP },	{ 0x057b, 0x0000, 0x0000, 0x0299, 		"Y-E Data",		"Flashbuster-U",		US_SC_UFI,  US_PR_CB, NULL,		US_FL_SINGLE_LUN},	{ 0x057b, 0x0000, 0x0300, 0x9999, 		"Y-E Data",		"Flashbuster-U",		US_SC_UFI,  US_PR_CBI, NULL,		US_FL_SINGLE_LUN},	{ 0x059f, 0xa601, 0x0200, 0x0200, 		"LaCie",		"USB Hard Disk",		US_SC_RBC, US_PR_CB, NULL, 0 }, 	{ 0x05ab, 0x0031, 0x0100, 0x0100, 		"In-System",		"USB/IDE Bridge (ATAPI ONLY!)",		US_SC_8070, US_PR_BULK, NULL, 0 }, 	{ 0x0644, 0x0000, 0x0100, 0x0100, 		"TEAC",		"Floppy Drive",		US_SC_UFI, US_PR_CB, NULL, 0 }, #ifdef CONFIG_USB_STORAGE_SDDR09	{ 0x066b, 0x0105, 0x0100, 0x0100, 		"Olympus",		"Camedia MAUSB-2",		US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,		US_FL_SINGLE_LUN | US_FL_START_STOP },#endif	{ 0x0693, 0x0002, 0x0100, 0x0100, 		"Hagiwara",		"FlashGate SmartMedia",		US_SC_SCSI, US_PR_BULK, NULL, 0 },	{ 0x0693, 0x0005, 0x0100, 0x0100,		"Hagiwara",		"Flashgate",		US_SC_SCSI, US_PR_BULK, NULL, 0 }, 	{ 0x0781, 0x0001, 0x0200, 0x0200, 		"Sandisk",		"ImageMate SDDR-05a",		US_SC_SCSI, US_PR_CB, NULL,		US_FL_SINGLE_LUN | US_FL_START_STOP},        { 0x0781, 0x0100, 0x0100, 0x0100,                "Sandisk",                "ImageMate SDDR-12",                US_SC_SCSI, US_PR_CB, NULL,                US_FL_SINGLE_LUN },#ifdef CONFIG_USB_STORAGE_SDDR09	{ 0x0781, 0x0200, 0x0100, 0x0208, 		"Sandisk",		"ImageMate SDDR-09",		US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,		US_FL_SINGLE_LUN | US_FL_START_STOP },#endif	{ 0x0781, 0x0002, 0x0009, 0x0009, 		"Sandisk",		"ImageMate SDDR-31",		US_SC_SCSI, US_PR_BULK, NULL,		US_FL_IGNORE_SER},	{ 0x07af, 0x0004, 0x0100, 0x0100, 		"Microtech",		"USB-SCSI-DB25",		US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,		US_FL_SCM_MULT_TARG }, #ifdef CONFIG_USB_STORAGE_FREECOM        { 0x07ab, 0xfc01, 0x0000, 0x9999,                "Freecom",                "USB-IDE",                US_SC_QIC, US_PR_FREECOM, freecom_init, 0},#endif	{ 0x07af, 0x0005, 0x0100, 0x0100, 		"Microtech",		"USB-SCSI-HD50",		US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,		US_FL_SCM_MULT_TARG }, #ifdef CONFIG_USB_STORAGE_DPCM 	{ 0x07af, 0x0006, 0x0100, 0x0100,		"Microtech",		"CameraMate (DPCM_USB)", 		US_SC_SCSI, US_PR_DPCM_USB, NULL,		US_FL_START_STOP },#endif	{ 0 }};/* Search our ususual device list, based on vendor/product combinations * to see if we can support this device.  Returns a pointer to a structure * defining how we should support this device, or NULL if it's not in the * list */static struct us_unusual_dev* us_find_dev(u16 idVendor, u16 idProduct, 					  u16 bcdDevice){	struct us_unusual_dev* ptr;	US_DEBUGP("Searching unusual device list for (0x%x, 0x%x, 0x%x)...\n",		  idVendor, idProduct, bcdDevice);	ptr = us_unusual_dev_list;	while ((ptr->idVendor != 0x0000) && 	       !((ptr->idVendor == idVendor) && 		 (ptr->idProduct == idProduct) &&		 (ptr->bcdDeviceMin <= bcdDevice) &&		 (ptr->bcdDeviceMax >= bcdDevice)))		ptr++;	/* if the search ended because we hit the end record, we failed */	if (ptr->idVendor == 0x0000) {		US_DEBUGP("-- did not find a matching device\n");		return NULL;	}	/* otherwise, we found one! */	US_DEBUGP("-- found matching device: %s %s\n", ptr->vendorName,		ptr->productName);	return ptr;}/* Set up the IRQ pipe and handler * Note that this function assumes that all the data in the us_data * strucuture is current.  This includes the ep_int field, which gives us * the endpoint for the interrupt. * Returns non-zero on failure, zero on success */ static int usb_stor_allocate_irq(struct us_data *ss){	unsigned int pipe;	int maxp;	int result;	US_DEBUGP("Allocating IRQ for CBI transport\n");	/* lock access to the data structure */	down(&(ss->irq_urb_sem));	/* allocate the URB */	ss->irq_urb = usb_alloc_urb(0);	if (!ss->irq_urb) {		up(&(ss->irq_urb_sem));		US_DEBUGP("couldn't allocate interrupt URB");		return 1;	}	/* calculate the pipe and max packet size */	pipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int->bEndpointAddress & 			      USB_ENDPOINT_NUMBER_MASK);	maxp = usb_maxpacket(ss->pusb_dev, pipe, usb_pipeout(pipe));	if (maxp > sizeof(ss->irqbuf))		maxp = sizeof(ss->irqbuf);	/* fill in the URB with our data */	FILL_INT_URB(ss->irq_urb, ss->pusb_dev, pipe, ss->irqbuf, maxp, 		     usb_stor_CBI_irq, ss, ss->ep_int->bInterval); 	/* submit the URB for processing */	result = usb_submit_urb(ss->irq_urb);	US_DEBUGP("usb_submit_urb() returns %d\n", result);	if (result) {		usb_free_urb(ss->irq_urb);		up(&(ss->irq_urb_sem));		return 2;	}	/* unlock the data structure and return success */	up(&(ss->irq_urb_sem));	return 0;}/* Probe to see if a new device is actually a SCSI device */static void * storage_probe(struct usb_device *dev, unsigned int ifnum,			    const struct usb_device_id *id){	int i;	char mf[USB_STOR_STRING_LEN];		     /* manufacturer */	char prod[USB_STOR_STRING_LEN];		     /* product */	char serial[USB_STOR_STRING_LEN];	     /* serial number */	GUID(guid);			   /* Global Unique Identifier */	unsigned int flags;	struct us_unusual_dev *unusual_dev;	struct us_data *ss = NULL;#ifdef CONFIG_USB_STORAGE_SDDR09	int result;#endif	/* these are temporary copies -- we test on these, then put them	 * in the us-data structure 	 */	struct usb_endpoint_descriptor *ep_in = NULL;	struct usb_endpoint_descriptor *ep_out = NULL;	struct usb_endpoint_descriptor *ep_int = NULL;	u8 subclass = 0;	u8 protocol = 0;	/* the altsettting 0 on the interface we're probing */	struct usb_interface_descriptor *altsetting = 		&(dev->actconfig->interface[ifnum].altsetting[0]); 	/* clear the temporary strings */	memset(mf, 0, sizeof(mf));	memset(prod, 0, sizeof(prod));	memset(serial, 0, sizeof(serial));	/* search for this device in our unusual device list */	unusual_dev = us_find_dev(dev->descriptor.idVendor, 				  dev->descriptor.idProduct,				  dev->descriptor.bcdDevice);	/* 	 * Can we support this device, either because we know about it	 * from our unusual device list, or because it advertises that it's	 * compliant to the specification?	 */	if (!unusual_dev &&	    !(dev->descriptor.bDeviceClass == 0 &&	      altsetting->bInterfaceClass == USB_CLASS_MASS_STORAGE &&	      altsetting->bInterfaceSubClass >= US_SC_MIN &&	      altsetting->bInterfaceSubClass <= US_SC_MAX)) {		/* if it's not a mass storage, we go no further */		return NULL;	}	/* At this point, we know we've got a live one */	US_DEBUGP("USB Mass Storage device detected\n");	/* Determine subclass and protocol, or copy from the interface */	if (unusual_dev) {		subclass = unusual_dev->useProtocol;		protocol = unusual_dev->useTransport;		flags = unusual_dev->flags;	} else {		subclass = altsetting->bInterfaceSubClass;		protocol = altsetting->bInterfaceProtocol;		flags = 0;	}	/*	 * Find the endpoints we need	 * 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 < altsetting->bNumEndpoints; i++) {		/* is it an BULK endpoint? */		if ((altsetting->endpoint[i].bmAttributes & 		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {			/* BULK in or out? */			if (altsetting->endpoint[i].bEndpointAddress & 			    USB_DIR_IN)				ep_in = &altsetting->endpoint[i];			else				ep_out = &altsetting->endpoint[i];		}		/* is it an interrupt endpoint? */		if ((altsetting->endpoint[i].bmAttributes & 		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {			ep_int = &altsetting->endpoint[i];		}	}	US_DEBUGP("Endpoints: In: 0x%p Out: 0x%p Int: 0x%p (Period %d)\n",		  ep_in, ep_out, ep_int, ep_int ? ep_int->bInterval : 0);#ifdef CONFIG_USB_STORAGE_SDDR09	if (protocol == US_PR_EUSB_SDDR09 || protocol == US_PR_DPCM_USB) {		/* set the configuration -- STALL is an acceptable response here */		result = usb_set_configuration(dev, 1);		US_DEBUGP("Result from usb_set_configuration is %d\n", result);		if (result == -EPIPE) {			US_DEBUGP("-- clearing stall on control interface\n");			usb_clear_halt(dev, usb_sndctrlpipe(dev, 0));		} else if (result != 0) {			/* it's not a stall, but another error -- time to bail */			US_DEBUGP("-- Unknown error.  Rejecting device\n");			return NULL;		}	}#endif	/* Do some basic sanity checks, and bail if we find a problem */	if (!ep_in || !ep_out || (protocol == US_PR_CBI && !ep_int)) {		US_DEBUGP("Sanity check failed.	 Rejecting device.\n");		return NULL;	}	/* At this point, we're committed to using the device */	usb_inc_dev_use(dev);	/* clear the GUID and fetch the strings */	GUID_CLEAR(guid);	if (dev->descriptor.iManufacturer)		usb_string(dev, dev->descriptor.iManufacturer, 			   mf, sizeof(mf));	if (dev->descriptor.iProduct)		usb_string(dev, dev->descriptor.iProduct, 			   prod, sizeof(prod));	if (dev->descriptor.iSerialNumber && !(flags & US_FL_IGNORE_SER))		usb_string(dev, dev->descriptor.iSerialNumber, 			   serial, sizeof(serial));	/* Create a GUID for this device */	if (dev->descriptor.iSerialNumber && serial[0]) {		/* If we have a serial number, and it's a non-NULL string */		make_guid(guid, dev->descriptor.idVendor, 			  dev->descriptor.idProduct, serial);	} else {		/* We don't have a serial number, so we use 0 */		make_guid(guid, dev->descriptor.idVendor, 			  dev->descriptor.idProduct, "0");	}	/*	 * Now check if we have seen this GUID before	 * We're looking for a device with a matching GUID that isn't	 * already on the system	 */	ss = us_list;	while ((ss != NULL) && 	       ((ss->pusb_dev) || !GUID_EQUAL(guid, ss->guid)))		ss = ss->next;	if (ss != NULL) {		/* Existing device -- re-connect */		US_DEBUGP("Found existing GUID " GUID_FORMAT "\n",			  GUID_ARGS(guid));		/* lock the device pointers */		down(&(ss->dev_semaphore));		/* establish the connection to the new device upon reconnect */		ss->ifnum = ifnum;		ss->pusb_dev = dev;		/* copy over the endpoint data */		if (ep_in)			ss->ep_in = ep_in->bEndpointAddress & 				USB_ENDPOINT_NUMBER_MASK;		if (ep_out)			ss->ep_out = ep_out->bEndpointAddress & 				USB_ENDPOINT_NUMBER_MASK;		ss->ep_int = ep_int;		/* allocate an IRQ callback if one is needed */		if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) {			usb_dec_dev_use(dev);

⌨️ 快捷键说明

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