Example #1
0
/**
 * sysfs_read_attribute_value: given path to attribute, return its value.
 *	values can be up to a pagesize, if buffer is smaller the value will 
 *	be truncated. 
 * @attrpath: sysfs path to attribute
 * @value: buffer to put value
 * @vsize: size of value buffer
 * returns 0 with success and -1 with error.
 */
int sysfs_read_attribute_value(const char *attrpath, 
					char *value, size_t vsize)
{
	struct sysfs_attribute *attr = NULL;
	size_t length = 0;

	if (attrpath == NULL || value == NULL || vsize == 0) {
		errno = EINVAL;
		return -1;
	}

	attr = sysfs_open_attribute(attrpath);
	if (attr == NULL) {
		dprintf("Invalid attribute path %s\n", attrpath);
		errno = EINVAL;
		return -1;
	}
	if((sysfs_read_attribute(attr)) != 0 || attr->value == NULL) {
		dprintf("Error reading from attribute %s\n", attrpath);
		sysfs_close_attribute(attr);
		return -1;
	}
	length = strlen(attr->value);
	if (length > vsize) 
		dprintf("Value length %d is larger than supplied buffer %d\n",
			length, vsize);
	safestrcpymax(value, attr->value, vsize);
	sysfs_close_attribute(attr);

	return 0;
}
Example #2
0
static int br_set(const char *bridge, const char *name, unsigned long value, unsigned long oldcode)
{
	int ret = -1;

#ifdef HAVE_LIBSYSFS
	struct sysfs_class_device *dev;

	dev = sysfs_get_class_device(br_class_net, bridge);
	if (dev) {
		struct sysfs_attribute *attr;
		char buf[32];
		char path[SYSFS_PATH_MAX];

		snprintf(buf, sizeof(buf), "%ld\n", value);
		snprintf(path, SYSFS_PATH_MAX, "%s/bridge/%s", dev->path, name);

		attr = sysfs_open_attribute(path);
		if (attr) {
			ret = sysfs_write_attribute(attr, buf, strlen(buf));
			sysfs_close_attribute(attr);
		}
		sysfs_close_class_device(dev);
	} else
#endif
	{
		struct ifreq ifr;
		unsigned long args[4] = { oldcode, value, 0, 0 };

		strncpy(ifr.ifr_name, bridge, IFNAMSIZ);
		ifr.ifr_data = (char *)&args;
		ret = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr);
	}

	return ret < 0 ? errno : 0;
}
Example #3
0
// added by zl 2011-2-12
int read_attr_string(struct sysfs_device *dev, char * string, const char * name)
{
    char attrpath[SYSFS_PATH_MAX];
    struct sysfs_attribute *attr;
    int ret;
    int len = STRING_MAXLEN;

    string[0] = 0;

    snprintf(attrpath, sizeof(attrpath), "%s/%s", dev->path, name);

    attr = sysfs_open_attribute(attrpath);
    if(!attr) {
        err("open attr");
        return 0;
    }

    ret = sysfs_read_attribute(attr);
    if(ret < 0) {
        err("read attr");
        goto err;
    }

    len = (len < attr->len? len: attr->len);
    if(len > 0)
    {
        memcpy(string, attr->value, len);
    }
    
err:
    sysfs_close_attribute(attr);

    return 0;
}
Example #4
0
int read_attr_value(struct sysfs_device *dev, const char *name, const char *format)
{
	char attrpath[SYSFS_PATH_MAX];
	struct sysfs_attribute *attr;
	int num = 0;
	int ret;

	snprintf(attrpath, sizeof(attrpath), "%s/%s", dev->path, name);

	attr = sysfs_open_attribute(attrpath);
	if(!attr) {
		err("open attr %s", attrpath);
		return 0;
	}

	ret = sysfs_read_attribute(attr);
	if(ret < 0) {
		err("read attr");
		goto err;
	}

	ret = sscanf(attr->value, format, &num);
	if(ret < 1) {
		err("sscanf");
		goto err;
	}

err:
	sysfs_close_attribute(attr);

	return num;
}
Example #5
0
/**
 * sysfs_open_attribute: creates sysfs_attribute structure
 * @path: path to attribute.
 * returns sysfs_attribute struct with success and NULL with error.
 */
struct sysfs_attribute *sysfs_open_attribute(const char *path)
{
	struct sysfs_attribute *sysattr = NULL;
	struct stat fileinfo;
	
	if (path == NULL) {
		errno = EINVAL;
		return NULL;
	}
	sysattr = alloc_attribute();
	if (sysattr == NULL) {
		dprintf("Error allocating attribute at %s\n", path);
		return NULL;
	}
	if (sysfs_get_name_from_path(path, sysattr->name, 
				SYSFS_NAME_LEN) != 0) {
		dprintf("Error retrieving attrib name from path: %s\n", path);
		sysfs_close_attribute(sysattr);
		return NULL;
	}
	safestrcpy(sysattr->path, path);
	if ((stat(sysattr->path, &fileinfo)) != 0) {
		dprintf("Stat failed: No such attribute?\n");
		sysattr->method = 0;
		free(sysattr);
		sysattr = NULL;
	} else {
		if (fileinfo.st_mode & S_IRUSR)
			sysattr->method |= SYSFS_METHOD_SHOW;
		if (fileinfo.st_mode & S_IWUSR)
			sysattr->method |= SYSFS_METHOD_STORE;
	}

	return sysattr;
}
Example #6
0
/**
 * add_attribute: open and add attribute at path to given directory
 * @dev: device whose attribute is to be added
 * @path: path to attribute
 * returns pointer to attr added with success and NULL with error.
 */
static struct sysfs_attribute *add_attribute(void *dev, const char *path)
{
	struct sysfs_attribute *attr;

	attr = sysfs_open_attribute(path);
	if (!attr) {
		dprintf("Error opening attribute %s\n",	path);
		return NULL;
	}
	if (attr->method & SYSFS_METHOD_SHOW) {
		if (sysfs_read_attribute(attr)) {
			dprintf("Error reading attribute %s\n",	path);
			sysfs_close_attribute(attr);
			return NULL;
		}
	}

	if (!((struct sysfs_device *)dev)->attrlist) {
		((struct sysfs_device *)dev)->attrlist = dlist_new_with_delete
			(sizeof(struct sysfs_attribute), sysfs_del_attribute);
	}
	dlist_unshift_sorted(((struct sysfs_device *)dev)->attrlist,
			attr, sort_list);

	return attr;
}
Example #7
0
int usbip_stub_export_device(struct usbip_exported_device *edev, int sockfd)
{
	char attrpath[SYSFS_PATH_MAX];
	struct sysfs_attribute *attr;
	char sockfd_buff[30];
	int ret;


	if (edev->status != SDEV_ST_AVAILABLE) {
		info("device not available, %s", edev->udev.busid);
		switch( edev->status ) {
			case SDEV_ST_ERROR:
				info("     status SDEV_ST_ERROR");
				break;
			case SDEV_ST_USED:
				info("     status SDEV_ST_USED");
				break;
			default:
				info("     status unknown: 0x%x", edev->status);
		}
		return -1;
	}

	/* only the first interface is true */
	snprintf(attrpath, sizeof(attrpath), "%s/%s:%d.%d/%s",
			edev->udev.path,
			edev->udev.busid,
			edev->udev.bConfigurationValue, 0,
			"usbip_sockfd");

	attr = sysfs_open_attribute(attrpath);
	if (!attr) {
		err("open %s", attrpath);
		return -1;
	}

	snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd);

	dbg("write: %s", sockfd_buff);

	ret = sysfs_write_attribute(attr, sockfd_buff, strlen(sockfd_buff));
	if (ret < 0) {
		err("write sockfd %s to %s", sockfd_buff, attrpath);
		goto err_write_sockfd;
	}

	info("connect %s", edev->udev.busid);

err_write_sockfd:
	sysfs_close_attribute(attr);

	return ret;
}
Example #8
0
int modify_match_busid(char *busid, int add)
{
	char bus_type[] = "usb";
	char attr_name[] = "match_busid";
	char buff[SYSFS_BUS_ID_SIZE + 4];
	char sysfs_mntpath[SYSFS_PATH_MAX];
	char match_busid_attr_path[SYSFS_PATH_MAX];
	struct sysfs_attribute *match_busid_attr;
	int rc, ret = 0;

	if (strnlen(busid, SYSFS_BUS_ID_SIZE) > SYSFS_BUS_ID_SIZE - 1) {
		dbg("busid is too long");
		return -1;
	}

	rc = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
	if (rc < 0) {
		err("sysfs must be mounted: %s", strerror(errno));
		return -1;
	}

	snprintf(match_busid_attr_path, sizeof(match_busid_attr_path),
		 "%s/%s/%s/%s/%s/%s", sysfs_mntpath, SYSFS_BUS_NAME, bus_type,
		 SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME, attr_name);

	match_busid_attr = sysfs_open_attribute(match_busid_attr_path);
	if (!match_busid_attr) {
		dbg("problem getting match_busid attribute: %s",
		    strerror(errno));
		return -1;
	}

	if (add)
		snprintf(buff, SYSFS_BUS_ID_SIZE + 4, "add %s", busid);
	else
		snprintf(buff, SYSFS_BUS_ID_SIZE + 4, "del %s", busid);

	dbg("write \"%s\" to %s", buff, match_busid_attr->path);

	rc = sysfs_write_attribute(match_busid_attr, buff, sizeof(buff));
	if (rc < 0) {
		dbg("failed to write match_busid: %s", strerror(errno));
		ret = -1;
	}

	sysfs_close_attribute(match_busid_attr);

	return ret;
}
Example #9
0
int read_attr_speed(struct sysfs_device *dev)
{
	char attrpath[SYSFS_PATH_MAX];
	struct sysfs_attribute *attr;
	char speed[100];
	int ret;

	snprintf(attrpath, sizeof(attrpath), "%s/%s", dev->path, "speed");

	attr = sysfs_open_attribute(attrpath);
	if(!attr) {
		err("open attr");
		return 0;
	}

	ret = sysfs_read_attribute(attr);
	if(ret < 0) {
		err("read attr");
		goto err;
	}

	ret = sscanf(attr->value, "%s\n", speed);
	if(ret < 1) {
		err("sscanf");
		goto err;
	}
err:
	sysfs_close_attribute(attr);

	for(int i=0; speed_strings[i].speed != NULL; i++) {
		if(!strcmp(speed, speed_strings[i].speed))
			return speed_strings[i].num;
	}

	return USB_SPEED_UNKNOWN;
}
/* only the first interface value is true! */
static int32_t read_attr_usbip_status(struct usbip_usb_device *udev)
{
	char attrpath[SYSFS_PATH_MAX];
	struct sysfs_attribute *attr;
	int value = 0;
	int rc;
	struct stat s;
	int retries = SYSFS_OPEN_RETRIES;

	/* This access is racy!
	 *
	 * Just after detach, our driver removes the sysfs
	 * files and recreates them.
	 *
	 * We may try and fail to open the usbip_status of
	 * an exported device in the (short) window where
	 * it has been removed and not yet recreated.
	 *
	 * This is a bug in the interface. Nothing we can do
	 * except work around it here by polling for the sysfs
	 * usbip_status to reappear.
	 */

	snprintf(attrpath, SYSFS_PATH_MAX, "%s/%s:%d.%d/usbip_status",
		 udev->path, udev->busid, udev->bConfigurationValue, 0);

	while (retries > 0) {
		if (stat(attrpath, &s) == 0)
			break;

		if (errno != ENOENT) {
			dbg("stat failed: %s", attrpath);
			return -1;
		}

		usleep(10000); /* 10ms */
		retries--;
	}

	if (retries == 0)
		dbg("usbip_status not ready after %d retries",
		    SYSFS_OPEN_RETRIES);
	else if (retries < SYSFS_OPEN_RETRIES)
		dbg("warning: usbip_status ready after %d retries",
		    SYSFS_OPEN_RETRIES - retries);

	attr = sysfs_open_attribute(attrpath);
	if (!attr) {
		dbg("sysfs_open_attribute failed: %s", attrpath);
		return -1;
	}

	rc = sysfs_read_attribute(attr);
	if (rc) {
		dbg("sysfs_read_attribute failed: %s", attrpath);
		sysfs_close_attribute(attr);
		return -1;
	}

	value = atoi(attr->value);

	sysfs_close_attribute(attr);

	return value;
}
Example #11
0
int main(int argc, char *argv[])
{
	struct sysfs_class *sf_class;
	struct sysfs_device *sf_dev;
	struct sysfs_class_device *sf_cdev;
	struct dlist *sf_cdev_list = NULL;
	char buffer[64];
	int port;

	struct sysfs_attribute *sf_attr;
	struct sysfs_attribute *sf_part;
	struct dlist *sf_part_list = NULL;

	sf_class = sysfs_open_class("block");

	if (sf_class != NULL)
	{
		sf_cdev_list = sysfs_get_class_devices(sf_class);
		if (sf_cdev_list != NULL)
		{
			dlist_for_each_data(sf_cdev_list, sf_cdev, struct sysfs_class_device)
			{
				sf_dev = sysfs_get_classdev_device(sf_cdev);
				if (sf_dev != NULL)
				{
					port = *(strstr(sf_dev->path, "/usb1/") + 8) - 48;
					if ((port != 1) && (port != 2))
					{
						port = -1;
					}

					printf("%s, USB port %d\n", sf_cdev->name, port);

					/* size */
					snprintf(buffer, 64, "%s/size", sf_cdev->path);

					sf_attr = sysfs_open_attribute(buffer);
					if (sf_attr != NULL)
					{
						if (sysfs_read_attribute(sf_attr) == 0)
						{
							printf("size: %s", sf_attr->value);
						}
						sysfs_close_attribute(sf_attr);
					}

					/* vendor */
					snprintf(buffer, 64, "%s/device/vendor", sf_cdev->path);

					sf_attr = sysfs_open_attribute(buffer);
					if (sf_attr != NULL)
					{
						if (sysfs_read_attribute(sf_attr) == 0)
						{
							printf("vendor: %s", sf_attr->value);
						}
						sysfs_close_attribute(sf_attr);
					}

					/* model */
					snprintf(buffer, 64, "%s/device/model", sf_cdev->path);

					sf_attr = sysfs_open_attribute(buffer);
					if (sf_attr != NULL)
					{
						if (sysfs_read_attribute(sf_attr) == 0)
						{
							printf("model: %s", sf_attr->value);
						}
						sysfs_close_attribute(sf_attr);
					}

					sf_part_list = sysfs_open_directory_list(sf_cdev->path);
					if (sf_part_list != NULL)
					{
						dlist_for_each_data(sf_part_list, sf_part, struct sysfs_attribute)
						{
							if (strncmp("queue", (char *) sf_part, 5) != 0)
							{
								snprintf(buffer, 64, "%s/%s/size", sf_cdev->path, sf_part);

								sf_attr = sysfs_open_attribute(buffer);
								if (sf_attr != NULL)
								{
									if (sysfs_read_attribute(sf_attr) == 0)
									{
										printf("%s - size: %s", sf_part, sf_attr->value);
									}
									sysfs_close_attribute(sf_attr);
								}
							}
						}
					}
Example #12
0
/**
 * sysfs_del_attribute: routine for dlist integration
 */
static void sysfs_del_attribute(void *attr)
{
        sysfs_close_attribute((struct sysfs_attribute *)attr);
}
Example #13
0
/* call at unbound state */
static int bind_usbip(char *busid)
{
	char bus_type[] = "usb";
	char attr_name[] = "bind";
	char sysfs_mntpath[SYSFS_PATH_MAX];
	char bind_attr_path[SYSFS_PATH_MAX];
	char intf_busid[SYSFS_BUS_ID_SIZE];
	struct sysfs_device *busid_dev;
	struct sysfs_attribute *bind_attr;
	struct sysfs_attribute *bConfValue;
	struct sysfs_attribute *bNumIntfs;
	int i, failed = 0;
	int rc, ret = -1;

	rc = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
	if (rc < 0) {
		err("sysfs must be mounted: %s", strerror(errno));
		return -1;
	}

	snprintf(bind_attr_path, sizeof(bind_attr_path), "%s/%s/%s/%s/%s/%s",
		 sysfs_mntpath, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME,
		 USBIP_HOST_DRV_NAME, attr_name);

	bind_attr = sysfs_open_attribute(bind_attr_path);
	if (!bind_attr) {
		dbg("problem getting bind attribute: %s", strerror(errno));
		return -1;
	}

	busid_dev = sysfs_open_device(bus_type, busid);
	if (!busid_dev) {
		dbg("sysfs_open_device %s failed: %s", busid, strerror(errno));
		goto err_close_bind_attr;
	}

	bConfValue = sysfs_get_device_attr(busid_dev, "bConfigurationValue");
	bNumIntfs  = sysfs_get_device_attr(busid_dev, "bNumInterfaces");

	if (!bConfValue || !bNumIntfs) {
		dbg("problem getting device attributes: %s",
		    strerror(errno));
		goto err_close_busid_dev;
	}

	for (i = 0; i < atoi(bNumIntfs->value); i++) {
		snprintf(intf_busid, SYSFS_BUS_ID_SIZE, "%s:%.1s.%d", busid,
			 bConfValue->value, i);

		rc = sysfs_write_attribute(bind_attr, intf_busid,
					   SYSFS_BUS_ID_SIZE);
		if (rc < 0) {
			dbg("bind driver at %s failed", intf_busid);
			failed = 1;
		}
	}

	if (!failed)
		ret = 0;

err_close_busid_dev:
	sysfs_close_device(busid_dev);
err_close_bind_attr:
	sysfs_close_attribute(bind_attr);

	return ret;
}