+static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, char *attr)
+{
+ struct sysfs_attribute *tmpattr = NULL;
+ char *c;
+
+ dbg("look for device attribute '%s'", attr);
+ /* try to find the attribute in the class device directory */
+ tmpattr = sysfs_get_classdev_attr(class_dev, attr);
+ if (tmpattr)
+ goto attr_found;
+
+ /* look in the class device directory if present */
+ if (sysfs_device) {
+ tmpattr = sysfs_get_device_attr(sysfs_device, attr);
+ if (tmpattr)
+ goto attr_found;
+ }
+
+ return NULL;
+
+attr_found:
+ c = strchr(tmpattr->value, '\n');
+ if (c != NULL)
+ c[0] = '\0';
+
+ dbg("found attribute '%s'", tmpattr->path);
+ return tmpattr;
+}
+
+static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair)
+{
+ struct sysfs_attribute *tmpattr;
+ int i;
+ int len;
+
+ if ((pair == NULL) || (pair->file[0] == '\0') || (pair->value == '\0'))
+ return -ENODEV;
+
+ tmpattr = find_sysfs_attribute(class_dev, sysfs_device, pair->file);
+ if (tmpattr == NULL)
+ return -ENODEV;
+
+ /* strip trailing whitespace of value, if not asked to match for it */
+ if (! isspace(pair->value[strlen(pair->value)-1])) {
+ i = len = strlen(tmpattr->value);
+ while (i > 0 && isspace(tmpattr->value[i-1]))
+ i--;
+ if (i < len) {
+ tmpattr->value[i] = '\0';
+ dbg("remove %i trailing whitespace chars from '%s'",
+ len - i, tmpattr->value);
+ }
+ }
+
+ dbg("compare attribute '%s' value '%s' with '%s'",
+ pair->file, tmpattr->value, pair->value);
+ if (strcmp_pattern(pair->value, tmpattr->value) != 0)
+ return -ENODEV;
+
+ dbg("found matching attribute '%s' with value '%s'",
+ pair->file, pair->value);
+ return 0;
+}
+
+static int match_sysfs_pairs(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
+{
+ struct sysfs_pair *pair;
+ int i;
+
+ for (i = 0; i < MAX_SYSFS_PAIRS; ++i) {
+ pair = &dev->sysfs_pair[i];
+ if ((pair->file[0] == '\0') || (pair->value[0] == '\0'))
+ break;
+ if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) {
+ dbg("sysfs attribute doesn't match");
+ return -ENODEV;
+ }
+ }
+
+ return 0;
+}
+
+static int match_id(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
+{
+ char path[SYSFS_PATH_MAX];
+ char *temp = NULL;
+
+ /* we have to have a sysfs device for ID to work */
+ if (!sysfs_device)
+ return -ENODEV;
+
+ strfieldcpy(path, sysfs_device->path);
+ temp = strrchr(path, '/');
+ temp++;
+ dbg("search '%s' in '%s', path='%s'", dev->id, temp, path);
+ if (strcmp_pattern(dev->id, temp) != 0)
+ return -ENODEV;
+ else
+ return 0;
+}
+
+static int match_place(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)