X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=libsysfs%2Fsysfs_driver.c;h=a4440cfdf9f9e5daa4a7f42c1f4682e8192b0de8;hb=a695feaeff0551745e1a397be2daa61b8cd0cc42;hp=4372b19f10f6c033fa8653390fa3fa7e01230c6c;hpb=5d4754f19521568b775ba7a31465d3af192ce382;p=elogind.git diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index 4372b19f1..a4440cfdf 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -65,29 +65,6 @@ static int open_driver_dir(struct sysfs_driver *driver) return 0; } -/** - * read_driver_dir: Read driver directory's subdirs and links - * @driver: Driver to read - * Returns 0 on success and 1 on failure - */ -static int read_driver_dir(struct sysfs_driver *driver) -{ - if (driver == NULL) { - errno = EINVAL; - return 1; - } - if (driver->directory == NULL) { - if ((open_driver_dir(driver)) == 1) - return 1; - } - if ((sysfs_read_directory(driver->directory)) != 0) { - dprintf("Error reading driver directory at %s\n", - driver->path); - return 1; - } - return 0; -} - /** * alloc_driver: allocates and initializes driver * returns struct sysfs_driver with success and NULL with error. @@ -98,11 +75,11 @@ static struct sysfs_driver *alloc_driver(void) } /** - * sysfs_open_driver: opens and initializes driver structure + * sysfs_open_driver_path: opens and initializes driver structure * @path: path to driver directory * returns struct sysfs_driver with success and NULL with error */ -struct sysfs_driver *sysfs_open_driver(const unsigned char *path) +struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path) { struct sysfs_driver *driver = NULL; @@ -126,6 +103,11 @@ struct sysfs_driver *sysfs_open_driver(const unsigned char *path) return NULL; } strcpy(driver->path, path); + if ((sysfs_remove_trailing_slash(driver->path)) != 0) { + dprintf("Invalid path to driver %s\n", driver->path); + sysfs_close_driver(driver); + return NULL; + } return driver; } @@ -148,25 +130,37 @@ struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver) return NULL; } if (driver->directory->attributes == NULL) { - if ((sysfs_read_dir_attributes(driver->directory)) != 0) { - dprintf("Error reading driver attributes\n"); + if ((sysfs_read_dir_attributes(driver->directory)) != 0) return NULL; - } - } else { - if ((sysfs_path_is_dir(driver->path)) != 0) { - dprintf("Driver at %s no longer exists\n", - driver->path); - return NULL; - } - if ((sysfs_refresh_attributes - (driver->directory->attributes)) != 0) { - dprintf("Error refreshing driver attributes\n"); - return NULL; - } } return(driver->directory->attributes); } +/** + * sysfs_refresh_driver_attributes: refreshes the driver's list of attributes + * @driver: sysfs_driver whose attributes to refresh + * + * NOTE: Upon return, prior references to sysfs_attributes for this driver + * _may_ not be valid + * + * Returns list of attributes on success and NULL on failure + */ +struct dlist *sysfs_refresh_driver_attributes(struct sysfs_driver *driver) +{ + if (driver == NULL) { + errno = EINVAL; + return NULL; + } + if (driver->directory == NULL) + return (sysfs_get_driver_attributes(driver)); + + if ((sysfs_refresh_dir_attributes(driver->directory)) != 0) { + dprintf("Error refreshing driver attributes\n"); + return NULL; + } + return (driver->directory->attributes); +} + /** * sysfs_get_driver_attr: searches driver's attributes by name * @drv: driver to look through @@ -176,7 +170,6 @@ struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver) struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, const unsigned char *name) { - struct sysfs_attribute *cur = NULL; struct dlist *attrlist = NULL; if (drv == NULL) { @@ -185,13 +178,11 @@ struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, } attrlist = sysfs_get_driver_attributes(drv); - if (attrlist != NULL) { - cur = sysfs_get_directory_attribute(drv->directory, + if (attrlist != NULL) + return NULL; + + return sysfs_get_directory_attribute(drv->directory, (unsigned char *)name); - if (cur != NULL) - return cur; - } - return NULL; } /** @@ -209,7 +200,7 @@ struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver) if (driver->directory == NULL) { if ((open_driver_dir(driver)) == 1) return NULL; - if ((read_driver_dir(driver)) != 0) + if ((sysfs_read_dir_links(driver->directory)) != 0) return NULL; } return(driver->directory->links); @@ -236,13 +227,13 @@ struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver) if (driver->directory == NULL) { if ((open_driver_dir(driver)) == 1) return NULL; - if ((read_driver_dir(driver)) != 0) + if ((sysfs_read_dir_links(driver->directory)) != 0) return NULL; } if (driver->directory->links != NULL) { dlist_for_each_data(driver->directory->links, curlink, struct sysfs_link) { - device = sysfs_open_device(curlink->target); + device = sysfs_open_device_path(curlink->target); if (device == NULL) { dprintf("Error opening device at %s\n", curlink->target); @@ -259,6 +250,38 @@ struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver) return (driver->devices); } +/** + * sysfs_refresh_driver_devices: Refreshes drivers list of devices + * @driver: sysfs_driver whose devices list needs to be refreshed + * + * NOTE: Upon return from this function, prior sysfs_device references from + * this driver's list of devices _may_ not be valid + * + * Returns dlist of devices on success and NULL on failure + */ +struct dlist *sysfs_refresh_driver_devices(struct sysfs_driver *driver) +{ + if (driver == NULL) { + errno = EINVAL; + return NULL; + } + + if (driver->devices != NULL) { + dlist_destroy(driver->devices); + driver->devices = NULL; + } + + if (driver->directory == NULL) + return (sysfs_get_driver_devices(driver)); + + if ((sysfs_refresh_dir_links(driver->directory)) != 0) { + dprintf("Error refreshing driver links\n"); + return NULL; + } + + return (sysfs_get_driver_devices(driver)); +} + /** * sysfs_get_driver_device: looks up a device from a list of driver's devices * and returns its sysfs_device corresponding to it @@ -311,8 +334,7 @@ static int get_driver_path(const unsigned char *bus, dprintf("Error getting sysfs mount path\n"); return -1; } - if (sysfs_trailing_slash(path) == 0) - strcat(path, "/"); + strcat(path, "/"); strcat(path, SYSFS_BUS_NAME); strcat(path, "/"); strcat(path, bus); @@ -345,7 +367,7 @@ struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, return NULL; } - memset(path, 0, SYSFS_NAME_LEN); + memset(path, 0, SYSFS_PATH_MAX); if ((get_driver_path(bus, drv, path, SYSFS_PATH_MAX)) != 0) { dprintf("Error getting to driver %s\n", drv); return NULL; @@ -367,3 +389,33 @@ struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, return attribute; } +/** + * sysfs_open_driver: open driver by name, given its bus + * @drv_name: Name of the driver + * @bus_name: Name of the bus + * Returns the sysfs_driver reference on success and NULL on failure + */ +struct sysfs_driver *sysfs_open_driver(const unsigned char *drv_name, + const unsigned char *bus_name) +{ + unsigned char path[SYSFS_PATH_MAX]; + struct sysfs_driver *driver = NULL; + + if (drv_name == NULL || bus_name == NULL) { + errno = EINVAL; + return NULL; + } + + memset(path, 0, SYSFS_PATH_MAX); + if ((get_driver_path(bus_name, drv_name, path, SYSFS_PATH_MAX)) != 0) { + dprintf("Error getting to driver %s\n", drv_name); + return NULL; + } + driver = sysfs_open_driver_path(path); + if (driver == NULL) { + dprintf("Error opening driver at %s\n", path); + return NULL; + } + return driver; +} +