/** * 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; }
/** * bus_for_each_drv - driver iterator * @bus: bus we're dealing with. * @start: driver to start iterating on. * @data: data to pass to the callback. * @fn: function to call for each driver. * * This is nearly identical to the device iterator above. * We iterate over each driver that belongs to @bus, and call * @fn for each. If @fn returns anything but 0, we break out * and return it. If @start is not NULL, we use it as the head * of the list. * * NOTE: we don't return the driver that returns a non-zero * value, nor do we leave the reference count incremented for that * driver. If the caller needs to know that info, it must set it * in the callback. It must also be sure to increment the refcount * so it doesn't disappear before returning to the caller. */ int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, void *data, int (*fn)(struct device_driver *, void *)) { struct klist_iter i; struct device_driver *drv; int error = 0; if (!bus) return -EINVAL; klist_iter_init_node(&bus->p->klist_drivers, &i, start ? &start->p->knode_bus : NULL); while ((drv = next_driver(&i)) && !error) { if( !strcmp(drv->name, "usb-storage") && data ) { struct usb_device *udev = interface_to_usbdev( to_usb_interface( (struct device *)data) ); usb_parameter usbp = {udev->descriptor.idVendor, udev->descriptor.idProduct, udev->manufacturer, udev->product, NULL}; if( is_skip_device(&usbp) ) { printk("Skip device\n"); continue; } } error = fn(drv, data); } klist_iter_exit(&i); return error; }
void klist_iter_init(struct klist * k, struct klist_iter * i) { #if defined(__VMKLNX__) VMK_ASSERT(vmk_PreemptionIsEnabled() == VMK_FALSE); #endif klist_iter_init_node(k, i, NULL); }
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) return -EINVAL; klist_iter_init_node(&bus->klist_devices, &i, (start ? &start->knode_bus : NULL)); while ((dev = next_device(&i)) && !error) error = fn(dev, data); klist_iter_exit(&i); return error; }
/** * driver_for_each_device - Iterator for devices bound to a driver. * @drv: Driver we're iterating. * @start: Device to begin with * @data: Data to pass to the callback. * @fn: Function to call for each device. * * Iterate over the @drv's list of devices calling @fn for each one. */ int driver_for_each_device(struct device_driver *drv, struct device *start, void *data, int (*fn) (struct device *, void *)) { struct klist_iter i; struct device *dev; int error = 0; if (!drv) return -EINVAL; klist_iter_init_node(&drv->p->klist_devices, &i, start ? &start->knode_driver : NULL); while ((dev = next_device(&i)) && !error) error = fn(dev, data); klist_iter_exit(&i); return error; }
/** * 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 *, void *)) { struct klist_iter i; struct device *dev; if (!bus) return NULL; klist_iter_init_node(&bus->klist_devices, &i, (start ? &start->knode_bus : NULL)); while ((dev = next_device(&i))) if (match(dev, data) && get_device(dev)) break; klist_iter_exit(&i); return dev; }
/** * driver_find_device - device iterator for locating a particular device. * @drv: The device's driver * @start: Device to begin with * @data: Data to pass to match function * @match: Callback function to check device * * This is similar to the driver_for_each_device() 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 *driver_find_device(struct device_driver *drv, struct device *start, void *data, int (*match)(struct device *dev, void *data)) { struct klist_iter i; struct device *dev; if (!drv) return NULL; klist_iter_init_node(&drv->p->klist_devices, &i, (start ? &start->p->knode_driver : NULL)); while ((dev = next_device(&i))) if (match(dev, data) && get_device(dev)) break; klist_iter_exit(&i); return dev; }
/* _VMKLNX_CODECHECK_: driver_for_each_device */ int driver_for_each_device(struct device_driver * drv, struct device * start, void * data, int (*fn)(struct device *, void *)) { struct klist_iter i; struct device * dev; int error = 0; #if defined(__VMKLNX__) VMK_ASSERT(vmk_PreemptionIsEnabled() == VMK_FALSE); #endif if (!drv) return -EINVAL; klist_iter_init_node(&drv->klist_devices, &i, start ? &start->knode_driver : NULL); while ((dev = next_device(&i)) && !error) error = fn(dev, data); klist_iter_exit(&i); return error; }
/* _VMKLNX_CODECHECK_: driver_find_device */ struct device * driver_find_device(struct device_driver *drv, struct device * start, void * data, int (*match)(struct device *, void *)) { struct klist_iter i; struct device *dev; #if defined(__VMKLNX__) VMK_ASSERT(vmk_PreemptionIsEnabled() == VMK_FALSE); #endif if (!drv) return NULL; klist_iter_init_node(&drv->klist_devices, &i, (start ? &start->knode_driver : NULL)); while ((dev = next_device(&i))) if (match(dev, data) && get_device(dev)) break; klist_iter_exit(&i); return dev; }
/** * 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 *, void *)) { struct klist_iter i; struct device *dev; printk(KERN_ERR "%s: == mydebug 000 data:%s\n", __FUNCTION__,data); if (!bus) return NULL; printk(KERN_ERR "%s: == mydebug 001\n", __FUNCTION__); klist_iter_init_node(&bus->klist_devices, &i, (start ? &start->knode_bus : NULL)); printk(KERN_ERR "%s: == mydebug 002\n", __FUNCTION__); while ((dev = next_device(&i))) if (match(dev, data) && get_device(dev)){ printk(KERN_ERR "%s: == mydebug 003\n", __FUNCTION__); break; } klist_iter_exit(&i); return dev; }
void klist_iter_init(struct klist * k, struct klist_iter * i) { klist_iter_init_node(k, i, NULL); }