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

📄 usb.c

📁 LINUX下USB驱动程序的开发
💻 C
📖 第 1 页 / 共 3 页
字号:
		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;		/* establish the connection to the new device */		ss->ifnum = ifnum;		ss->pusb_dev = dev;		/* copy over the identifiying strings */		strncpy(ss->vendor, mf, USB_STOR_STRING_LEN);		strncpy(ss->product, prod, USB_STOR_STRING_LEN);		strncpy(ss->serial, serial, USB_STOR_STRING_LEN);		if (strlen(ss->vendor) == 0) {			if (unusual_dev->vendorName)				strncpy(ss->vendor, unusual_dev->vendorName,					USB_STOR_STRING_LEN);			else				strncpy(ss->vendor, "Unknown",					USB_STOR_STRING_LEN);		}		if (strlen(ss->product) == 0) {			if (unusual_dev->productName)				strncpy(ss->product, unusual_dev->productName,					USB_STOR_STRING_LEN);			else				strncpy(ss->product, "Unknown",					USB_STOR_STRING_LEN);		}		if (strlen(ss->serial) == 0)			strncpy(ss->serial, "None", USB_STOR_STRING_LEN);		/* copy the GUID we created before */		memcpy(ss->guid, guid, sizeof(guid));		/* 		 * Set the handler pointers based on the protocol		 * Again, this data is persistant across reattachments		 */		switch (ss->protocol) {		case US_PR_CB:			ss->transport_name = "Control/Bulk";			ss->transport = usb_stor_CB_transport;			ss->transport_reset = usb_stor_CB_reset;			ss->max_lun = 7;			break;		case US_PR_CBI:			ss->transport_name = "Control/Bulk/Interrupt";			ss->transport = usb_stor_CBI_transport;			ss->transport_reset = usb_stor_CB_reset;			ss->max_lun = 7;			break;		case US_PR_BULK:			ss->transport_name = "Bulk";			ss->transport = usb_stor_Bulk_transport;			ss->transport_reset = usb_stor_Bulk_reset;			ss->max_lun = usb_stor_Bulk_max_lun(ss);			break;#ifdef CONFIG_USB_STORAGE_HP8200e		case US_PR_SCM_ATAPI:			ss->transport_name = "SCM/ATAPI";			ss->transport = hp8200e_transport;			ss->transport_reset = usb_stor_CB_reset;			ss->max_lun = 1;			break;#endif#ifdef CONFIG_USB_STORAGE_SDDR09		case US_PR_EUSB_SDDR09:			ss->transport_name = "EUSB/SDDR09";			ss->transport = sddr09_transport;			ss->transport_reset = usb_stor_CB_reset;			ss->max_lun = 0;			break;#endif#ifdef CONFIG_USB_STORAGE_SDDR55		case US_PR_SDDR55:			ss->transport_name = "SDDR55";			ss->transport = sddr55_transport;			ss->transport_reset = sddr55_reset;			ss->max_lun = 0;			break;#endif#ifdef CONFIG_USB_STORAGE_DPCM		case US_PR_DPCM_USB:			ss->transport_name = "Control/Bulk-EUSB/SDDR09";			ss->transport = dpcm_transport;			ss->transport_reset = usb_stor_CB_reset;			ss->max_lun = 1;			break;#endif#ifdef CONFIG_USB_STORAGE_FREECOM                case US_PR_FREECOM:                        ss->transport_name = "Freecom";                        ss->transport = freecom_transport;                        ss->transport_reset = usb_stor_freecom_reset;                        ss->max_lun = 0;                        break;#endif#ifdef CONFIG_USB_STORAGE_DATAFAB                case US_PR_DATAFAB:                        ss->transport_name  = "Datafab Bulk-Only";                        ss->transport = datafab_transport;                        ss->transport_reset = usb_stor_Bulk_reset;                        ss->max_lun = 1;                        break;#endif#ifdef CONFIG_USB_STORAGE_JUMPSHOT                case US_PR_JUMPSHOT:                        ss->transport_name  = "Lexar Jumpshot Control/Bulk";                        ss->transport = jumpshot_transport;                        ss->transport_reset = usb_stor_Bulk_reset;                        ss->max_lun = 1;                        break;#endif		default:			ss->transport_name = "Unknown";			kfree(ss->current_urb);			kfree(ss);			usb_dec_dev_use(dev);			return NULL;			break;		}		US_DEBUGP("Transport: %s\n", ss->transport_name);		/* fix for single-lun devices */		if (ss->flags & US_FL_SINGLE_LUN)			ss->max_lun = 0;		switch (ss->subclass) {		case US_SC_RBC:			ss->protocol_name = "Reduced Block Commands (RBC)";			ss->proto_handler = usb_stor_transparent_scsi_command;			break;		case US_SC_8020:			ss->protocol_name = "8020i";			ss->proto_handler = usb_stor_ATAPI_command;			ss->max_lun = 0;			break;		case US_SC_QIC:			ss->protocol_name = "QIC-157";			ss->proto_handler = usb_stor_qic157_command;			ss->max_lun = 0;			break;		case US_SC_8070:			ss->protocol_name = "8070i";			ss->proto_handler = usb_stor_ATAPI_command;			ss->max_lun = 0;			break;		case US_SC_SCSI:			ss->protocol_name = "Transparent SCSI";			ss->proto_handler = usb_stor_transparent_scsi_command;			break;		case US_SC_UFI:			ss->protocol_name = "Uniform Floppy Interface (UFI)";			ss->proto_handler = usb_stor_ufi_command;			break;#ifdef CONFIG_USB_STORAGE_ISD200                case US_SC_ISD200:                        ss->protocol_name = "ISD200 ATA/ATAPI";                        ss->proto_handler = isd200_ata_command;                        break;#endif		default:			ss->protocol_name = "Unknown";			kfree(ss->current_urb);			kfree(ss);			usb_dec_dev_use(dev);			return NULL;			break;		}		US_DEBUGP("Protocol: %s\n", ss->protocol_name);		/* allocate an IRQ callback if one is needed */		if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) {			kfree(ss->current_urb);			kfree(ss);			usb_dec_dev_use(dev);			return NULL;		}		/*		 * Since this is a new device, we need to generate a scsi 		 * host definition, and register with the higher SCSI layers		 */		/* Initialize the host template based on the default one */		memcpy(&(ss->htmplt), &usb_stor_host_template, 		       sizeof(usb_stor_host_template));		/* Grab the next host number */		ss->host_number = my_host_number++;		/* We abuse this pointer so we can pass the ss pointer to 		 * the host controller thread in us_detect.  But how else are		 * we to do it?		 */		ss->htmplt.proc_dir = (void *)ss; 		/* According to the technical support people at Genesys Logic,		 * devices using their chips have problems transferring more		 * than 32 KB at a time.  In practice people have found that		 * 64 KB works okay and that's what Windows does.  But we'll		 * be conservative.		 */		if (ss->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS)			ss->htmplt.max_sectors = 64;		/* Just before we start our control thread, initialize		 * the device if it needs initialization */		if (unusual_dev && unusual_dev->initFunction)			unusual_dev->initFunction(ss);		/* start up our control thread */		ss->pid = kernel_thread(usb_stor_control_thread, ss,					CLONE_VM);		if (ss->pid < 0) {			printk(KERN_WARNING USB_STORAGE 			       "Unable to start control thread\n");			kfree(ss->current_urb);			kfree(ss);			usb_dec_dev_use(dev);			return NULL;		}		/* wait for the thread to start */		wait_for_completion(&(ss->notify));		/* now register	 - our detect function will be called */		ss->htmplt.module = THIS_MODULE;		scsi_register_module(MODULE_SCSI_HA, &(ss->htmplt));		/* lock access to the data structures */		down(&us_list_semaphore);		/* put us in the list */		ss->next = us_list;		us_list = ss;		/* release the data structure lock */		up(&us_list_semaphore);	}	printk(KERN_DEBUG 	       "WARNING: USB Mass Storage data integrity not assured\n");	printk(KERN_DEBUG 	       "USB Mass Storage device found at %d\n", dev->devnum);	/* return a pointer for the disconnect function */	return ss;}/* Handle a disconnect event from the USB core */static void storage_disconnect(struct usb_device *dev, void *ptr){	struct us_data *ss = ptr;	int result;	US_DEBUGP("storage_disconnect() called\n");	/* this is the odd case -- we disconnected but weren't using it */	if (!ss) {		US_DEBUGP("-- device was not in use\n");		return;	}	/* lock access to the device data structure */	down(&(ss->dev_semaphore));	/* release the IRQ, if we have one */	if (ss->irq_urb) {		US_DEBUGP("-- releasing irq URB\n");		result = usb_unlink_urb(ss->irq_urb);		US_DEBUGP("-- usb_unlink_urb() returned %d\n", result);		usb_free_urb(ss->irq_urb);		ss->irq_urb = NULL;	}	/* free up the main URB for this device */	US_DEBUGP("-- releasing main URB\n");	result = usb_unlink_urb(ss->current_urb);	US_DEBUGP("-- usb_unlink_urb() returned %d\n", result);	usb_free_urb(ss->current_urb);	ss->current_urb = NULL;	/* mark the device as gone */	usb_dec_dev_use(ss->pusb_dev);	ss->pusb_dev = NULL;	/* unlock access to the device data structure */	up(&(ss->dev_semaphore));}/*********************************************************************** * Initialization and registration ***********************************************************************/int __init usb_stor_init(void){	printk(KERN_INFO "Initializing USB Mass Storage driver...\n");	/* initialize internal global data elements */	us_list = NULL;	init_MUTEX(&us_list_semaphore);	my_host_number = 0;	/* register the driver, return -1 if error */	if (usb_register(&usb_storage_driver) < 0)		return -1;	/* we're all set */	printk(KERN_INFO "USB Mass Storage support registered.\n");	return 0;}void __exit usb_stor_exit(void){	struct us_data *next;	US_DEBUGP("usb_stor_exit() called\n");	/* Deregister the driver	 * This eliminates races with probes and disconnects 	 */	US_DEBUGP("-- calling usb_deregister()\n");	usb_deregister(&usb_storage_driver) ;	/* While there are still virtual hosts, unregister them	 * Note that it's important to do this completely before removing	 * the structures because of possible races with the /proc	 * interface	 */	for (next = us_list; next; next = next->next) {		US_DEBUGP("-- calling scsi_unregister_module()\n");		scsi_unregister_module(MODULE_SCSI_HA, &(next->htmplt));	}	/* While there are still structures, free them.  Note that we are	 * now race-free, since these structures can no longer be accessed	 * from either the SCSI command layer or the /proc interface	 */	while (us_list) {		/* keep track of where the next one is */		next = us_list->next;		/* If there's extra data in the us_data structure then		 * free that first */		if (us_list->extra) {			/* call the destructor routine, if it exists */			if (us_list->extra_destructor) {				US_DEBUGP("-- calling extra_destructor()\n");				us_list->extra_destructor(us_list->extra);			}			/* destroy the extra data */			US_DEBUGP("-- freeing the data structure\n");			kfree(us_list->extra);		}		/* free the structure itself */                kfree (us_list);		/* advance the list pointer */		us_list = next;	}}module_init(usb_stor_init);module_exit(usb_stor_exit);

⌨️ 快捷键说明

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