1. 程式人生 > >Linux Kernel裝置驅動模型之匯流排查詢裝置

Linux Kernel裝置驅動模型之匯流排查詢裝置

裝置驅動模型之匯流排查詢裝置:
/**
 * bus_find_device - device iterator for locating a particular device.
 * @bus: bus type
 * @start: Device to begin with
 * @data: Data to pass to match function
 * @match: Callback function to check device
 *
 * This is similar to the bus_for_each_dev() function above, but it
 * returns a reference to a device that is 'found' for later use, as
 * determined by the @match callback.
 *
 * The callback should return 0 if the device doesn't match and non-zero
 * if it does.  If the callback returns non-zero, this function will
 * return to the caller and not iterate over any more devices.
 */
struct device *bus_find_device(struct bus_type *bus,
          struct device *start, void *data,
          int (*match)(struct device *dev, void *data))
{  struct klist_iter i;  struct device *dev;

 if (!bus || !bus->p)   return NULL;

 klist_iter_init_node(&bus->p->klist_devices, &i,         (start ? &start->p->knode_bus : NULL));  while ((dev = next_device(&i)))   if (match(dev, data) && get_device(dev))    break;  klist_iter_exit(&i);  return dev; }

根據名字查詢裝置:

/**  * bus_find_device_by_name - device iterator for locating a particular device of a specific name  * @bus: bus type  * @start: Device to begin with  * @name: name of the device to match  *  * This is similar to the bus_find_device() function above, but it handles  * searching by a name automatically, no need to write another strcmp matching  * function.  */ struct device *bus_find_device_by_name(struct bus_type *bus,            struct device *start, const char *name)

{  return bus_find_device(bus, start, (void *)name, match_name); } EXPORT_SYMBOL_GPL(bus_find_device_by_name);

總線上迭代裝置:

/**  * bus_for_each_dev - device iterator.  * @bus: bus type.  * @start: device to start iterating from.  * @data: data for the callback.  * @fn: function to be called for each device.  *  * Iterate over @bus's list of devices, and call @fn for each,  * passing it @data. If @start is not NULL, we use that device to  * begin iterating from.  *  * We check the return of @fn each time. If it returns anything  * other than 0, we break out and return that value.  *  * NOTE: The device that returns a non-zero value is not retained  * in any way, nor is its refcount incremented. If the caller needs  * to retain this data, it should do so, and increment the reference  * count in the supplied callback.  */ int bus_for_each_dev(struct bus_type *bus, struct device *start,        void *data, int (*fn)(struct device *, void *)) {  struct klist_iter i;  struct device *dev;  int error = 0;

 if (!bus || !bus->p)   return -EINVAL;

 klist_iter_init_node(&bus->p->klist_devices, &i,         (start ? &start->p->knode_bus : NULL));  while ((dev = next_device(&i)) && !error)   error = fn(dev, data);  klist_iter_exit(&i);  return error; }

根據id查詢裝置:

/**  * subsys_find_device_by_id - find a device with a specific enumeration number  * @subsys: subsystem  * @id: index 'id' in struct device  * @hint: device to check first  *  * Check the hint's next object and if it is a match return it directly,  * otherwise, fall back to a full list search. Either way a reference for  * the returned object is taken.  */ struct device *subsys_find_device_by_id(struct bus_type *subsys, unsigned int id,      struct device *hint) {  struct klist_iter i;  struct device *dev;

 if (!subsys)   return NULL;

 if (hint) {   klist_iter_init_node(&subsys->p->klist_devices, &i, &hint->p->knode_bus);   dev = next_device(&i);   if (dev && dev->id == id && get_device(dev)) {    klist_iter_exit(&i);    return dev;   }   klist_iter_exit(&i);  }

 klist_iter_init_node(&subsys->p->klist_devices, &i, NULL);  while ((dev = next_device(&i))) {   if (dev->id == id && get_device(dev)) {    klist_iter_exit(&i);    return dev;   }  }  klist_iter_exit(&i);  return NULL; }