85 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| --- a/drivers/usb/core/usb.c
 | |
| +++ b/drivers/usb/core/usb.c
 | |
| @@ -651,6 +651,71 @@ exit:
 | |
|  	return dev;
 | |
|  }
 | |
|  
 | |
| +static struct usb_device *match_device_name(struct usb_device *dev,
 | |
| +					    const char *name)
 | |
| +{
 | |
| +	struct usb_device *ret_dev = NULL;
 | |
| +	int child;
 | |
| +
 | |
| +	dev_dbg(&dev->dev, "check for name %s ...\n", name);
 | |
| +
 | |
| +	/* see if this device matches */
 | |
| +	if (strcmp(dev_name(&dev->dev), name) == 0 ) {
 | |
| +		dev_dbg(&dev->dev, "matched this device!\n");
 | |
| +		ret_dev = usb_get_dev(dev);
 | |
| +		goto exit;
 | |
| +	}
 | |
| +
 | |
| +	/* look through all of the children of this device */
 | |
| +	for (child = 0; child < dev->maxchild; ++child) {
 | |
| +		if (dev->children[child]) {
 | |
| +			usb_lock_device(dev->children[child]);
 | |
| +			ret_dev = match_device_name(dev->children[child], name);
 | |
| +			usb_unlock_device(dev->children[child]);
 | |
| +			if (ret_dev)
 | |
| +				goto exit;
 | |
| +		}
 | |
| +	}
 | |
| +exit:
 | |
| +	return ret_dev;
 | |
| +}
 | |
| +
 | |
| +/**
 | |
| + * usb_find_device_by_name - find a specific usb device in the system
 | |
| + * @name: the name of the device to find
 | |
| + *
 | |
| + * Returns a pointer to a struct usb_device if such a specified usb
 | |
| + * device is present in the system currently.  The usage count of the
 | |
| + * device will be incremented if a device is found.  Make sure to call
 | |
| + * usb_put_dev() when the caller is finished with the device.
 | |
| + *
 | |
| + * If a device with the specified bus id is not found, NULL is returned.
 | |
| + */
 | |
| +struct usb_device *usb_find_device_by_name(const char *name)
 | |
| +{
 | |
| +	struct list_head *buslist;
 | |
| +	struct usb_bus *bus;
 | |
| +	struct usb_device *dev = NULL;
 | |
| +
 | |
| +	mutex_lock(&usb_bus_list_lock);
 | |
| +	for (buslist = usb_bus_list.next;
 | |
| +	     buslist != &usb_bus_list;
 | |
| +	     buslist = buslist->next) {
 | |
| +		bus = container_of(buslist, struct usb_bus, bus_list);
 | |
| +		if (!bus->root_hub)
 | |
| +			continue;
 | |
| +		usb_lock_device(bus->root_hub);
 | |
| +		dev = match_device_name(bus->root_hub, name);
 | |
| +		usb_unlock_device(bus->root_hub);
 | |
| +		if (dev)
 | |
| +			goto exit;
 | |
| +	}
 | |
| +exit:
 | |
| +	mutex_unlock(&usb_bus_list_lock);
 | |
| +	return dev;
 | |
| +}
 | |
| +EXPORT_SYMBOL_GPL(usb_find_device_by_name);
 | |
| +
 | |
|  /**
 | |
|   * usb_get_current_frame_number - return current bus frame number
 | |
|   * @dev: the device whose bus is being queried
 | |
| --- a/include/linux/usb.h
 | |
| +++ b/include/linux/usb.h
 | |
| @@ -540,6 +540,7 @@ extern int usb_reset_device(struct usb_d
 | |
|  extern void usb_queue_reset_device(struct usb_interface *dev);
 | |
|  
 | |
|  extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id);
 | |
| +extern struct usb_device *usb_find_device_by_name(const char *name);
 | |
|  
 | |
|  /* USB autosuspend and autoresume */
 | |
|  #ifdef CONFIG_USB_SUSPEND
 |