Exemplo n.º 1
0
static struct usbip_imported_device *imported_device_init(struct usbip_vhci_driver *driver, 
		struct usbip_imported_device *idev, char *busid)
{
	struct sysfs_device *sudev;

	sudev = sysfs_open_device("usb", busid);
	if(!sudev) {
		err("sysfs_open_device %s", busid);
		goto err;
	}
	read_usb_device(sudev, &idev->udev);
	sysfs_close_device(sudev);

	/* add class devices of this imported device */
	struct class_device *cdev;
	dlist_for_each_data(driver->cdev_list, cdev, struct class_device) {
		if(!strncmp(cdev->devpath, idev->udev.path, strlen(idev->udev.path))) {
			struct class_device *new_cdev;

			/* alloc and copy because dlist is linked from only one list */
			new_cdev = calloc(1, sizeof(*new_cdev));
			if(!new_cdev) 
				goto err;

			memcpy(new_cdev, cdev, sizeof(*new_cdev));
			dlist_unshift(idev->cdev_list, (void*) new_cdev);
		}
	}

	return idev;

err:
	return NULL;
}
Exemplo n.º 2
0
static void usbip_exported_device_delete(void *dev)
{
	struct usbip_exported_device *edev =
		(struct usbip_exported_device *) dev;

	sysfs_close_device(edev->sudev);
	free(dev);
}
Exemplo n.º 3
0
int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev)
{
	char product_name[100];
	char host[NI_MAXHOST] = "unknown host";
	char serv[NI_MAXSERV] = "unknown port";
	char remote_busid[SYSFS_BUS_ID_SIZE];
	int ret;
	int i;

	if (idev->status == VDEV_ST_NULL || idev->status == VDEV_ST_NOTASSIGNED) {
		info("Port %02d: <%s>", idev->port, usbip_status_string(idev->status));
		return 0;
	}

	ret = read_record(idev->port, host, serv, remote_busid);
	if (ret) {
		err("read_record");
		return -1;
	}

	info("Port %02d: <%s> at %s", idev->port,
			usbip_status_string(idev->status), usbip_speed_string(idev->udev.speed));

	usbip_names_get_product(product_name, sizeof(product_name),
			idev->udev.idVendor, idev->udev.idProduct);

	info("       %s",  product_name);

	info("%10s -> usbip://%s:%s/%s  (remote devid %08x (bus/dev %03d/%03d))",
			idev->udev.busid, host, serv, remote_busid,
			idev->devid,
			idev->busnum, idev->devnum);

	for (i=0; i < idev->udev.bNumInterfaces; i++) {
		/* show interface information */
		struct sysfs_device *suinf;

		suinf = open_usb_interface(&idev->udev, i);
		if (!suinf)
			continue;

		info("       %6s used by %-17s", suinf->bus_id, suinf->driver_name);
		sysfs_close_device(suinf);

		/* show class device information */
		struct class_device *cdev;

		dlist_for_each_data(idev->cdev_list, cdev, struct class_device) {
			int ifnum = get_interface_number(cdev->devpath);
			if (ifnum == i) {
				info("           %s", cdev->clspath);
			}
		}
	}

	return 0;
}
Exemplo n.º 4
0
/**
 * sysfs_close_class_device: closes a single class device.
 * @dev: class device to close.
 */
void sysfs_close_class_device(struct sysfs_class_device *dev)
{
    if (dev) {
        if (dev->parent)
            sysfs_close_class_device(dev->parent);
        if (dev->sysdevice)
            sysfs_close_device(dev->sysdevice);
        if (dev->attrlist)
            dlist_destroy(dev->attrlist);
        free(dev);
    }
}
Exemplo n.º 5
0
static struct usbip_imported_device *usbip_imported_device_new(struct usbip_vhci_driver *driver, char *busid)
{
	struct usbip_imported_device *idev = NULL;
	struct sysfs_device *sudev;

	idev = (struct usbip_imported_device *) calloc(1, sizeof(*idev));
	if(!idev) 
		return NULL;

	/*
	 * The members of idev->cdev_list are also linked from
	 * driver->cdev_list. They are freed by destroy of driver->cdev_list.
	 * */
	idev->cdev_list = dlist_new(sizeof(struct class_device));
	if(!idev->cdev_list)
		goto err;

	sudev = sysfs_open_device("usb", busid);
	if(!sudev) {
		err("sysfs_open_device %s", busid);
		goto err;
	}
	read_usb_device(sudev, &idev->udev);
	sysfs_close_device(sudev);

	/* add class devices of this imported device */
	struct class_device *cdev;
	dlist_for_each_data(driver->cdev_list, cdev, struct class_device) {
		if(!strncmp(cdev->devpath, idev->udev.path, strlen(idev->udev.path))) {
			struct class_device *new_cdev;

			new_cdev = calloc(1, sizeof(*new_cdev));
			if(!new_cdev) 
				goto err;

			memcpy(new_cdev, cdev, sizeof(*new_cdev));
			dlist_unshift(idev->cdev_list, (void*) new_cdev);
		}
	}

	return idev;


err:
	if(idev->cdev_list)
		dlist_destroy(idev->cdev_list);
	if(idev)
		free(idev);
	return NULL;
}
Exemplo n.º 6
0
const char *lookup_bus(const char *dname,topdev_info *tinf){
	struct sysfs_device *dev;
	const struct bus *b;

	free(tinf->devname);
	tinf->devname = NULL;
	for(b = buses ; b->bus ; ++b){
		if( (dev = sysfs_open_device(b->bus,dname)) ){
			if(b->bus_lookup){
				b->bus_lookup(dname,dev,tinf);
			}
			sysfs_close_device(dev);
			return b->bus;
		}
	}
	return NULL;
}
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;
}
Exemplo n.º 8
0
int read_usb_interface(struct usb_device *udev, int i, struct usb_interface *uinf)
{
	char busid[SYSFS_BUS_ID_SIZE];
	struct sysfs_device *sif;

	sprintf(busid, "%s:%d.%d", udev->busid, udev->bConfigurationValue, i);

	sif = sysfs_open_device("usb", busid);
	if(!sif) {
		err("open sif of %s", busid);
		return -1;
	}

	READ_ATTR(uinf, uint8_t,  sif, bInterfaceClass,		"%02x\n");
	READ_ATTR(uinf, uint8_t,  sif, bInterfaceSubClass,	"%02x\n");
	READ_ATTR(uinf, uint8_t,  sif, bInterfaceProtocol,	"%02x\n");

	sysfs_close_device(sif);

	return 0;
}
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");
	}
Exemplo n.º 10
0
static void sysfs_close_driver_device(void *device)
{
	sysfs_close_device((struct sysfs_device *)device);
}
Exemplo n.º 11
0
static void sysfs_close_dev(void *dev)
{
	sysfs_close_device((struct sysfs_device *)dev);
}
Exemplo n.º 12
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");
            }

        }
Exemplo n.º 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;
}
Exemplo n.º 14
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;
}