Пример #1
0
/**
 * read_dir_subdirs: grabs subdirs in a specific directory
 * @sysdir: sysfs directory to read
 * returns list of directory names with success and NULL with error.
 */
struct sysfs_device *sysfs_read_dir_subdirs(const char *path)
{
	DIR *dir = NULL;
	struct dirent *dirent = NULL;
	char file_path[SYSFS_PATH_MAX];
	struct sysfs_device *dev = NULL;

	if (!path) {
		errno = EINVAL;
		return NULL;
	}

	dev = sysfs_open_device_path(path);

	dir = opendir(path);
	if (!dir) {
		dprintf("Error opening directory %s\n", path);
		return NULL;
	}
	while ((dirent = readdir(dir)) != NULL) {
		if (0 == strcmp(dirent->d_name, "."))
			 continue;
		if (0 == strcmp(dirent->d_name, ".."))
			continue;
		memset(file_path, 0, SYSFS_PATH_MAX);
		safestrcpy(file_path, path);
		safestrcat(file_path, "/");
		safestrcat(file_path, dirent->d_name);
		if (!sysfs_path_is_dir(file_path))
			add_subdirectory(dev, file_path);
	}
	closedir(dir);
	return dev;
}
Пример #2
0
/**
 * sysfs_get_bus_devices: gets all devices for bus
 * @bus: bus to get devices for
 * returns dlist of devices with success and NULL with failure
 */
struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus)
{
	struct sysfs_device *dev;
	struct dlist *linklist;
	char path[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX];
	char target[SYSFS_PATH_MAX];
	char *curlink;

	if (!bus) {
		errno = EINVAL;
		return NULL;
	}
	memset(path, 0, SYSFS_PATH_MAX);
	safestrcpy(path, bus->path);
	safestrcat(path, "/");
	safestrcat(path, SYSFS_DEVICES_NAME);

	linklist = read_dir_links(path);
	if (linklist) {
		dlist_for_each_data(linklist, curlink, char) {
			if (bus->devices) {
				dev = (struct sysfs_device *)
					dlist_find_custom(bus->devices,
					(void *)curlink, name_equal);
				if (dev)
					continue;
			}
			safestrcpy(devpath, path);
			safestrcat(devpath, "/");
			safestrcat(devpath, curlink);
			if (sysfs_get_link(devpath, target, SYSFS_PATH_MAX)) {
				dprintf("Error getting link - %s\n", devpath);
				continue;
			}
			dev = sysfs_open_device_path(target);
			if (!dev) {
				dprintf("Error opening device at %s\n",
								target);
				continue;
			}
			if (!bus->devices)
				bus->devices = dlist_new_with_delete
					(sizeof(struct sysfs_device),
					 		sysfs_close_dev);
			dlist_unshift_sorted(bus->devices, dev, sort_list);
		}
		sysfs_close_list(linklist);
	}
	return (bus->devices);
}
static struct usbip_exported_device *usbip_exported_device_new(char *sdevpath)
{
	struct usbip_exported_device *edev = NULL;
	size_t size;
	int i;

	edev = calloc(1, sizeof(*edev));
	if (!edev) {
		dbg("calloc failed");
		return NULL;
	}

	edev->sudev = sysfs_open_device_path(sdevpath);
	if (!edev->sudev) {
		dbg("sysfs_open_device_path failed: %s", sdevpath);
		goto err;
	}

	read_usb_device(edev->sudev, &edev->udev);

	edev->status = read_attr_usbip_status(&edev->udev);
	if (edev->status < 0)
		goto err;

	/* reallocate buffer to include usb interface data */
	size = sizeof(*edev) + edev->udev.bNumInterfaces *
		sizeof(struct usbip_usb_interface);

	edev = realloc(edev, size);
	if (!edev) {
		dbg("realloc failed");
		goto err;
	}

	for (i = 0; i < edev->udev.bNumInterfaces; i++)
		read_usb_interface(&edev->udev, i, &edev->uinf[i]);

	return edev;
err:
	if (edev && edev->sudev)
		sysfs_close_device(edev->sudev);
	if (edev)
		free(edev);

	return NULL;
}
Пример #4
0
int add_subdirectory(struct sysfs_device *dev, char *path)
{
	struct sysfs_device *newdev;

	if (!path)
		return -1;

	newdev = sysfs_open_device_path(path);
	if (newdev == NULL)
		return -1;

	if (dev->children == NULL)
		dev->children = dlist_new_with_delete(
			sizeof(struct sysfs_device), sysfs_close_dev_tree);

	dlist_unshift_sorted(dev->children, newdev, sort_list);
	return 0;
}
Пример #5
0
/**
 * sysfs_get_bus_device: Get specific device on bus using device's id
 * @bus: bus to find device on
 * @id: bus_id for device
 * returns struct sysfs_device reference or NULL if not found.
 */
struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus,
		const char *id)
{
	struct sysfs_device *dev = NULL;
	char devpath[SYSFS_PATH_MAX], target[SYSFS_PATH_MAX];

	if (!bus || !id) {
		errno = EINVAL;
		return NULL;
	}

	if (bus->devices) {
		dev = (struct sysfs_device *)dlist_find_custom
			(bus->devices, (void *)id, name_equal);
		if (dev)
			return dev;
	}
	safestrcpy(devpath, bus->path);
	safestrcat(devpath, "/");
	safestrcat(devpath, SYSFS_DEVICES_NAME);
	safestrcat(devpath, "/");
	safestrcat(devpath, id);
	if (sysfs_path_is_link(devpath)) {
		dprintf("No such device %s on bus %s?\n", id, bus->name);
		return NULL;
	}
	if (!sysfs_get_link(devpath, target, SYSFS_PATH_MAX)) {
		dev = sysfs_open_device_path(target);
		if (!dev) {
			dprintf("Error opening device at %s\n", target);
			return NULL;
		}
		if (!bus->devices)
			bus->devices = dlist_new_with_delete
					(sizeof(struct sysfs_device),
					 		sysfs_close_dev);
		dlist_unshift_sorted(bus->devices, dev, sort_list);
	}
	return dev;
}
Пример #6
0
/**
 * sysfs_get_classdev_device: gets the sysfs_device associated with the
 * 	given sysfs_class_device
 * @clsdev: class device whose associated sysfs_device is needed
 * returns struct sysfs_device * on success or NULL on error
 */
struct sysfs_device *sysfs_get_classdev_device
(struct sysfs_class_device *clsdev)
{
    char linkpath[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX];

    if (!clsdev) {
        errno = EINVAL;
        return NULL;
    }

    if (clsdev->sysdevice)
        return clsdev->sysdevice;

    memset(linkpath, 0, SYSFS_PATH_MAX);
    safestrcpy(linkpath, clsdev->path);
    safestrcat(linkpath, "/device");
    if (!sysfs_path_is_link(linkpath)) {
        memset(devpath, 0, SYSFS_PATH_MAX);
        if (!sysfs_get_link(linkpath, devpath, SYSFS_PATH_MAX))
            clsdev->sysdevice = sysfs_open_device_path(devpath);
    }
    return clsdev->sysdevice;
}
Пример #7
0
void get_usb_devs(hd_data_t *hd_data)
{
    uint64_t ul0;
    unsigned u1, u2, u3;
    hd_t *hd, *hd1;
    usb_t *usb;
    str_list_t *sl, *usb_devs = NULL;
    char *s, *s1, *t;
    hd_res_t *res;
    size_t l;

    struct sysfs_bus *sf_bus;
    struct dlist *sf_dev_list;
    struct sysfs_device *sf_dev;
    struct sysfs_device *sf_dev_2;

    sf_bus = sysfs_open_bus("usb");

    if(!sf_bus) {
        ADD2LOG("sysfs: no such bus: usb\n");
        return;
    }

    sf_dev_list = sysfs_get_bus_devices(sf_bus);

    if(sf_dev_list) dlist_for_each_data(sf_dev_list, sf_dev, struct sysfs_device) {
        if(hd_attr_uint(sysfs_get_device_attr(sf_dev, "bNumInterfaces"), &ul0, 0)) {
            add_str_list(&usb_devs, sf_dev->path);
            ADD2LOG("  usb dev: %s\n", hd_sysfs_id(sf_dev->path));
        }
    }

    if(sf_dev_list) dlist_for_each_data(sf_dev_list, sf_dev, struct sysfs_device) {
        ADD2LOG(
            "  usb device: name = %s, bus_id = %s, bus = %s\n    path = %s\n",
            sf_dev->name,
            sf_dev->bus_id,
            sf_dev->bus,
            hd_sysfs_id(sf_dev->path)
        );

        if(
            hd_attr_uint(sysfs_get_device_attr(sf_dev, "bInterfaceNumber"), &ul0, 16)
        ) {
            hd = add_hd_entry(hd_data, __LINE__, 0);

            hd->detail = new_mem(sizeof *hd->detail);
            hd->detail->type = hd_detail_usb;
            hd->detail->usb.data = usb = new_mem(sizeof *usb);

            hd->sysfs_id = new_str(hd_sysfs_id(sf_dev->path));
            hd->sysfs_bus_id = new_str(sf_dev->bus_id);

            hd->bus.id = bus_usb;
            hd->func = ul0;

            usb->ifdescr = ul0;

            if((s = hd_attr_str(sysfs_get_device_attr(sf_dev, "modalias")))) {
                s = canon_str(s, strlen(s));
                ADD2LOG("    modalias = \"%s\"\n", s);
                if(s && *s) {
                    hd->modalias = s;
                    s = NULL;
                }
                s = free_mem(s);
            }

            ADD2LOG("    bInterfaceNumber = %u\n", hd->func);

            if(hd_attr_uint(sysfs_get_device_attr(sf_dev, "bInterfaceClass"), &ul0, 16)) {
                usb->i_cls = ul0;
                ADD2LOG("    bInterfaceClass = %u\n", usb->i_cls);
            }

            if(hd_attr_uint(sysfs_get_device_attr(sf_dev, "bInterfaceSubClass"), &ul0, 16)) {
                usb->i_sub = ul0;
                ADD2LOG("    bInterfaceSubClass = %u\n", usb->i_sub);
            }

            if(hd_attr_uint(sysfs_get_device_attr(sf_dev, "bInterfaceProtocol"), &ul0, 16)) {
                usb->i_prot = ul0;
                ADD2LOG("    bInterfaceProtocol = %u\n", usb->i_prot);
            }

            /* device has longest matching sysfs id */
            u2 = strlen(sf_dev->path);
            s = NULL;
            for(u3 = 0, sl = usb_devs; sl; sl = sl->next) {
                u1 = strlen(sl->str);
                if(u1 > u3 && u1 <= u2 && !strncmp(sf_dev->path, sl->str, u1)) {
                    u3 = u1;
                    s = sl->str;
                }
            }

            if(s) {
                ADD2LOG("    if: %s @ %s\n", hd->sysfs_bus_id, hd_sysfs_id(s));
                sf_dev_2 = sysfs_open_device_path(s);
                if(sf_dev_2) {

                    if(hd_attr_uint(sysfs_get_device_attr(sf_dev_2, "bDeviceClass"), &ul0, 16)) {
                        usb->d_cls = ul0;
                        ADD2LOG("    bDeviceClass = %u\n", usb->d_cls);
                    }

                    if(hd_attr_uint(sysfs_get_device_attr(sf_dev_2, "bDeviceSubClass"), &ul0, 16)) {
                        usb->d_sub = ul0;
                        ADD2LOG("    bDeviceSubClass = %u\n", usb->d_sub);
                    }

                    if(hd_attr_uint(sysfs_get_device_attr(sf_dev_2, "bDeviceProtocol"), &ul0, 16)) {
                        usb->d_prot = ul0;
                        ADD2LOG("    bDeviceProtocol = %u\n", usb->d_prot);
                    }

                    if(hd_attr_uint(sysfs_get_device_attr(sf_dev_2, "idVendor"), &ul0, 16)) {
                        usb->vendor = ul0;
                        ADD2LOG("    idVendor = 0x%04x\n", usb->vendor);
                    }

                    if(hd_attr_uint(sysfs_get_device_attr(sf_dev_2, "idProduct"), &ul0, 16)) {
                        usb->device = ul0;
                        ADD2LOG("    idProduct = 0x%04x\n", usb->device);
                    }

                    if((s = hd_attr_str(sysfs_get_device_attr(sf_dev_2, "manufacturer")))) {
                        usb->manufact = canon_str(s, strlen(s));
                        ADD2LOG("    manufacturer = \"%s\"\n", usb->manufact);
                    }

                    if((s = hd_attr_str(sysfs_get_device_attr(sf_dev_2, "product")))) {
                        usb->product = canon_str(s, strlen(s));
                        ADD2LOG("    product = \"%s\"\n", usb->product);
                    }

                    if((s = hd_attr_str(sysfs_get_device_attr(sf_dev_2, "serial")))) {
                        usb->serial = canon_str(s, strlen(s));
                        ADD2LOG("    serial = \"%s\"\n", usb->serial);
                    }

                    if(hd_attr_uint(sysfs_get_device_attr(sf_dev_2, "bcdDevice"), &ul0, 16)) {
                        usb->rev = ul0;
                        ADD2LOG("    bcdDevice = %04x\n", usb->rev);
                    }

                    if((s = hd_attr_str(sysfs_get_device_attr(sf_dev_2, "speed")))) {
                        s = canon_str(s, strlen(s));
                        if(!strcmp(s, "1.5")) usb->speed = 15*100000;
                        else if(!strcmp(s, "12")) usb->speed = 12*1000000;
                        else if(!strcmp(s, "480")) usb->speed = 480*1000000;
                        ADD2LOG("    speed = \"%s\"\n", s);
                        s = free_mem(s);
                    }

                    sysfs_close_device(sf_dev_2);
                }
            }

            if(usb->vendor || usb->device) {
                hd->vendor.id = MAKE_ID(TAG_USB, usb->vendor);
                hd->device.id = MAKE_ID(TAG_USB, usb->device);
            }

            if(usb->manufact) hd->vendor.name = new_str(usb->manufact);
            if(usb->product) hd->device.name = new_str(usb->product);
            if(usb->serial) hd->serial = new_str(usb->serial);

            if(usb->rev) str_printf(&hd->revision.name, 0, "%x.%02x", usb->rev >> 8, usb->rev & 0xff);

            if(usb->speed) {
                res = add_res_entry(&hd->res, new_mem(sizeof *res));
                res->baud.type = res_baud;
                res->baud.speed = usb->speed;
            }

            s = hd_sysfs_find_driver(hd_data, hd->sysfs_id, 1);
            if(s) add_str_list(&hd->drivers, s);

            set_class_entries(hd_data, hd, usb);

            if(!hd_data->scanner_db) {
                hd_data->scanner_db = hd_module_list(hd_data, 1);
            }

            if(
                hd->drivers &&
                search_str_list(hd_data->scanner_db, hd->drivers->str)
            ) {
                hd->base_class.id = bc_scanner;
            }

            // ###### FIXME
            if(hd->base_class.id == bc_modem) {
                hd->unix_dev_name = new_str("/dev/ttyACM0");
            }

        }