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

📄 usbd-bus.c

📁 Linux2.4.20针对三星公司的s3c2440内核基础上的一些设备驱动代码
💻 C
📖 第 1 页 / 共 2 页
字号:
                struct usb_endpoint_instance *endpoint = device->bus->endpoint_array + 0;                // process event urbs                struct urb *urb;                while ((urb = first_urb_detached (&endpoint->events))) {                        if (device->status != USBD_CLOSING) {                                if (device->function_instance_array &&                                         (device->function_instance_array + 0)->function_driver->ops->event)                                 {                                        (device->function_instance_array + 0)->function_driver->ops->event                                                 (device, urb->event, urb->data);                                }                        }                        usbd_dealloc_urb (urb);                }                if (device->status == USBD_CLOSING) {                        device->function_bh.data = NULL;                }        }        // Not an error if closing in progress        else {                dbg_init (1, "usbd_function_bh: device NULL");        }}EXPORT_SYMBOL(usbd_function_bh);/* usb-device USB BUS INTERFACE generic functions ******************************************** *//** * usbd_register_bus - called by a USB BUS INTERFACE driver to register a bus driver * @driver: pointer to bus driver structure * * Used by a USB Bus interface driver to register itself with the usb device * layer. */EXPORT_SYMBOL(usbd_register_bus);struct __devinit usb_bus_instance *usbd_register_bus (struct usb_bus_driver *driver){	struct usb_bus_instance *bus;	int i;	dbg_init (2, "-");	if ((bus = ckmalloc (sizeof (struct usb_bus_instance), GFP_ATOMIC)) == NULL) {		return NULL;	}	bus->driver = driver;	if (!	    (bus->endpoint_array =	     ckmalloc (sizeof (struct usb_endpoint_instance) * bus->driver->max_endpoints,		       GFP_ATOMIC))) {		kfree (bus);		return NULL;	}	for (i = 0; i < bus->driver->max_endpoints; i++) {		struct usb_endpoint_instance *endpoint = bus->endpoint_array + i;		urb_link_init (&endpoint->events);		urb_link_init (&endpoint->rcv);		urb_link_init (&endpoint->rdy);		urb_link_init (&endpoint->tx);		urb_link_init (&endpoint->done);	}	return bus;}/** * usbd_deregister_bus - called by a USB BUS INTERFACE driver to deregister a bus driver * @bus: pointer to bus driver instance * * Used by a USB Bus interface driver to de-register itself with the usb device * layer. */EXPORT_SYMBOL(usbd_deregister_bus);void __exit usbd_deregister_bus (struct usb_bus_instance *bus){	dbg_init (3, "%s", bus->driver->name);	kfree (bus->endpoint_array);	kfree (bus);}/* usb-device USB Device generic functions *************************************************** *//** * usbd_register_device - called to create a virtual device * @name: name * @bus: pointer to struct usb_device_instance * @maxpacketsize: ep0 maximum packetsize * * Used by a USB Bus interface driver to create a virtual device. */EXPORT_SYMBOL(usbd_register_device);struct usb_device_instance *__devinit usbd_register_device (char *name, struct usb_bus_instance *bus,							 int maxpacketsize){	struct usb_device_instance *device;	struct usb_function_instance *function_instance_array;	struct list_head *lhd;	int num = usb_devices++;	char buf[32];	int function;	dbg_init (3, "-      -       -       -       -       -       -");	// allocate a usb_device_instance structure	if (!(device = ckmalloc (sizeof (struct usb_device_instance), GFP_ATOMIC))) {		dbg_init (0, "ckmalloc device failed");		return NULL;	}	// create a name	if (!name || !strlen (name)) {		sprintf (buf, "usb%d", num);		name = buf;	}	if ((device->name = strdup (name)) == NULL) {		kfree (device);		dbg_init (0, "strdup name failed");		return NULL;	}	device->device_state = STATE_CREATED;	device->status = USBD_OPENING;	// allocate a usb_function_instance for ep0 default control function driver	if ((device->ep0 = ckmalloc (sizeof (struct usb_function_instance), GFP_ATOMIC)) == NULL) {		kfree (device->name);		kfree (device);		dbg_init (0, "ckmalloc device failed");		return NULL;	}	device->ep0->function_driver = &ep0_driver;	// allocate an array of usb configuration instances	if ((function_instance_array =	     ckmalloc (sizeof (struct usb_function_instance) * registered_functions,		       GFP_ATOMIC)) == NULL) {		kfree (device->ep0);		kfree (device->name);		kfree (device);		dbg_init (0, "ckmalloc function_instance_array failed");		return NULL;	}	device->functions = registered_functions;	device->function_instance_array = function_instance_array;	dbg_init (2, "device: %p function_instance[]: %p registered_functions: %d",		  device, device->function_instance_array, registered_functions);	// connect us to bus	device->bus = bus;	// iterate across all of the function drivers to construct a complete list of configuration descriptors	// XXX there is currently only one XXX	function = 0;	dbg_init (1, "function init");	list_for_each (lhd, &function_drivers) {		struct usb_function_driver *function_driver;		function_driver = list_entry_func (lhd);		// build descriptors		dbg_init (1, "calling function_init");		usbd_function_init (bus, device, function_driver);		// save 		function_instance_array[function].function_driver = function_driver;	}	// device bottom half	device->device_bh.routine = usbd_device_bh;	device->device_bh.data = device;	// XXX device->device_bh.sync = 0;	// function bottom half	device->function_bh.routine = usbd_function_bh;	device->function_bh.data = device;	// XXX device->function_bh.sync = 0;	dbg_init (3, "%p %p", device, device->device_bh.data);	// add to devices queue	list_add_tail (&device->devices, &devices);	registered_devices++;	dbg_init (3, "%s finished", bus->driver->name);	return device;}/** * usbd_deregister_device - called by a USB BUS INTERFACE driver to deregister a physical interface * @device: pointer to struct usb_device_instance * * Used by a USB Bus interface driver to destroy a virtual device. */EXPORT_SYMBOL(usbd_deregister_device);void __exit usbd_deregister_device (struct usb_device_instance *device){	struct usb_function_instance *function_instance;	dbg_init (3, "%s start", device->bus->driver->name);	// prevent any more bottom half scheduling	device->status = USBD_CLOSING;#ifdef USBD_CONFIG_NOWAIT_DEREGISTER_DEVICE        /* We need to run the bottom halves at least once with the           status == USBD_CLOSING in order to make sure all the           URBS are freed (otherwise we have a memleak).  The           bh's set the data pointer to NULL when they notice           the USBD_CLOSING status. */	if (device->device_bh.sync) {        	// There is a bh queued.  The only way deal with this other		// than waiting is to do the task.		run_task_queue(&tq_immediate);	}	// Verify the status flag was detected.	if (NULL != device->device_bh.data) {		// It hasn't been detected yet, so queue the bh fn,		queue_task(&device->device_bh, &tq_immediate);		// then run it.		run_task_queue(&tq_immediate);		/* If the second time fails, something is wrong. */		if (NULL != device->device_bh.data) {			dbg_init(0, "run_task_queue(&tq_immediate) fails to clear device_bh");		}	}	// Similar logic but a different queue for the function bh.	if (device->function_bh.sync) {		flush_scheduled_tasks();        }	if (NULL != device->function_bh.data) {		schedule_task(&device->function_bh);		flush_scheduled_tasks();		/* If the second time fails, something is wrong. */		if (NULL != device->function_bh.data) {			dbg_init (0,"flush_scheduled_tasks() fails to clear function_bh");		}	}	/* Leave the wait in as paranoia - in case one of the task operations	   above fails to clear the queued task.  It should never happen, but ... */#endif	// wait for pending device and function bottom halfs to finish	//while (device->device_bh.sync || device->function_bh.sync) {	while (device->device_bh.data || device->function_bh.data) {                if (device->device_bh.data) {                        dbg_init(0, "waiting for usbd_device_bh %ld %p", device->device_bh.sync, device->device_bh.data);			// This can probably be either, but for consistency's sake...			queue_task(&device->device_bh, &tq_immediate);                        // schedule_task(&device->device_bh);                }                if (device->function_bh.data) {                        dbg_init(0, "waiting for usbd_function_bh %ld %p", device->function_bh.sync, device->function_bh.data);                        schedule_task(&device->function_bh);                }		schedule_timeout (10 * HZ);	}	// tell the function driver to close	usbd_function_close (device);	// disconnect from bus	device->bus = NULL;	// remove from devices queue	list_del (&device->devices);	// free function_instances	if ((function_instance = device->function_instance_array)) {		device->function_instance_array = NULL;		dbg_init (3, "freeing function instances: %p", function_instance);		kfree (function_instance);	}	// de-configured ep0	if ((function_instance = device->ep0)) {		device->ep0 = NULL;		dbg_init (3, "freeing ep0 instance: %p", function_instance);		kfree (function_instance);	}	kfree (device->name);	kfree (device);	registered_devices--;	dbg_init (3, "finished");}

⌨️ 快捷键说明

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