static int is_device(void *x)
{
	struct sysfs_attribute *devpath;
	struct sysfs_device *dev = x;
	int ret = 0;

	devpath = sysfs_get_device_attr(dev, "devpath");
	if (devpath && *devpath->value != '0')
		ret = 1;

	return ret;
}
static int list_devices(bool parsable)
{
	char bus_type[] = "usb";
	char busid[SYSFS_BUS_ID_SIZE];
	char product_name[128];
	struct sysfs_bus *ubus;
	struct sysfs_device *dev;
	struct sysfs_device *intf;
	struct sysfs_attribute *idVendor;
	struct sysfs_attribute *idProduct;
	struct sysfs_attribute *bConfValue;
	struct sysfs_attribute *bNumIntfs;
	struct dlist *devlist;
	int i;
	int ret = -1;

	ubus = sysfs_open_bus(bus_type);
	if (!ubus) {
		err("could not open %s bus: %s", bus_type, strerror(errno));
		return -1;
	}

	devlist = sysfs_get_bus_devices(ubus);
	if (!devlist) {
		err("could not get %s bus devices: %s", bus_type,
		    strerror(errno));
		goto err_out;
	}

	/* remove interfaces and root hubs from device list */
	dlist_filter_sort(devlist, is_device, devcmp);

	if (!parsable) {
		printf("Local USB devices\n");
		printf("=================\n");
	}
	dlist_for_each_data(devlist, dev, struct sysfs_device) {
		idVendor   = sysfs_get_device_attr(dev, "idVendor");
		idProduct  = sysfs_get_device_attr(dev, "idProduct");
		bConfValue = sysfs_get_device_attr(dev, "bConfigurationValue");
		bNumIntfs  = sysfs_get_device_attr(dev, "bNumInterfaces");
		if (!idVendor || !idProduct || !bConfValue || !bNumIntfs) {
			err("problem getting device attributes: %s",
			    strerror(errno));
			goto err_out;
		}

		/* get product name */
		usbip_names_get_product(product_name, sizeof(product_name),
					strtol(idVendor->value, NULL, 16),
					strtol(idProduct->value, NULL, 16));
		print_device(dev->bus_id, idVendor->value, idProduct->value,
			     parsable);
		print_product_name(product_name, parsable);

		for (i = 0; i < atoi(bNumIntfs->value); i++) {
			snprintf(busid, sizeof(busid), "%s:%.1s.%d",
				 dev->bus_id, bConfValue->value, i);
			intf = sysfs_open_device(bus_type, busid);
			if (!intf) {
				err("could not open device interface: %s",
				    strerror(errno));
				goto err_out;
			}
			print_interface(busid, intf->driver_name, parsable);
			sysfs_close_device(intf);
		}
		printf("\n");
	}
Example #3
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;
}
Example #4
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");
            }

        }
Example #5
0
/* buggy driver may cause dead lock */
static int unbind_other(char *busid)
{
	char bus_type[] = "usb";
	char intf_busid[SYSFS_BUS_ID_SIZE];
	struct sysfs_device *busid_dev;
	struct sysfs_device *intf_dev;
	struct sysfs_driver *intf_drv;
	struct sysfs_attribute *unbind_attr;
	struct sysfs_attribute *bConfValue;
	struct sysfs_attribute *bDevClass;
	struct sysfs_attribute *bNumIntfs;
	int i, rc;
	enum unbind_status status = UNBIND_ST_OK;

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

	bConfValue = sysfs_get_device_attr(busid_dev, "bConfigurationValue");
	bDevClass  = sysfs_get_device_attr(busid_dev, "bDeviceClass");
	bNumIntfs  = sysfs_get_device_attr(busid_dev, "bNumInterfaces");
	if (!bConfValue || !bDevClass || !bNumIntfs) {
		dbg("problem getting device attributes: %s",
		    strerror(errno));
		goto err_close_busid_dev;
	}

	if (!strncmp(bDevClass->value, "09", bDevClass->len)) {
		dbg("skip unbinding of hub");
		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);
		intf_dev = sysfs_open_device(bus_type, intf_busid);
		if (!intf_dev) {
			dbg("could not open interface device: %s",
			    strerror(errno));
			goto err_close_busid_dev;
		}

		dbg("%s -> %s", intf_dev->name,  intf_dev->driver_name);

		if (!strncmp("unknown", intf_dev->driver_name, SYSFS_NAME_LEN))
			/* unbound interface */
			continue;

		if (!strncmp(USBIP_HOST_DRV_NAME, intf_dev->driver_name,
			     SYSFS_NAME_LEN)) {
			/* already bound to usbip-host */
			status = UNBIND_ST_USBIP_HOST;
			continue;
		}

		/* unbinding */
		intf_drv = sysfs_open_driver(bus_type, intf_dev->driver_name);
		if (!intf_drv) {
			dbg("could not open interface driver on %s: %s",
			    intf_dev->name, strerror(errno));
			goto err_close_intf_dev;
		}

		unbind_attr = sysfs_get_driver_attr(intf_drv, "unbind");
		if (!unbind_attr) {
			dbg("problem getting interface driver attribute: %s",
			    strerror(errno));
			goto err_close_intf_drv;
		}

		rc = sysfs_write_attribute(unbind_attr, intf_dev->bus_id,
					   SYSFS_BUS_ID_SIZE);
		if (rc < 0) {
			/* NOTE: why keep unbinding other interfaces? */
			dbg("unbind driver at %s failed", intf_dev->bus_id);
			status = UNBIND_ST_FAILED;
		}

		sysfs_close_driver(intf_drv);
		sysfs_close_device(intf_dev);
	}

	goto out;

err_close_intf_drv:
	sysfs_close_driver(intf_drv);
err_close_intf_dev:
	sysfs_close_device(intf_dev);
err_close_busid_dev:
	status = UNBIND_ST_FAILED;
out:
	sysfs_close_device(busid_dev);

	return status;
}