root/tools/usb/usbip/libsrc/usbip_device_driver.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. read_usb_vudc_device
  2. is_my_device
  3. usbip_device_driver_open

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
   4  *               2015 Samsung Electronics
   5  * Author:       Igor Kotrasinski <i.kotrasinsk@samsung.com>
   6  *
   7  * Based on tools/usb/usbip/libsrc/usbip_host_driver.c, which is:
   8  * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
   9  *               2005-2007 Takahiro Hirofuchi
  10  */
  11 
  12 #include <fcntl.h>
  13 #include <string.h>
  14 #include <linux/usb/ch9.h>
  15 
  16 #include <unistd.h>
  17 
  18 #include "usbip_host_common.h"
  19 #include "usbip_device_driver.h"
  20 
  21 #undef  PROGNAME
  22 #define PROGNAME "libusbip"
  23 
  24 #define copy_descr_attr16(dev, descr, attr)                     \
  25                 ((dev)->attr = le16toh((descr)->attr))          \
  26 
  27 #define copy_descr_attr(dev, descr, attr)                       \
  28                 ((dev)->attr = (descr)->attr)                   \
  29 
  30 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
  31 
  32 static struct {
  33         enum usb_device_speed speed;
  34         const char *name;
  35 } speed_names[] = {
  36         {
  37                 .speed = USB_SPEED_UNKNOWN,
  38                 .name = "UNKNOWN",
  39         },
  40         {
  41                 .speed = USB_SPEED_LOW,
  42                 .name = "low-speed",
  43         },
  44         {
  45                 .speed = USB_SPEED_FULL,
  46                 .name = "full-speed",
  47         },
  48         {
  49                 .speed = USB_SPEED_HIGH,
  50                 .name = "high-speed",
  51         },
  52         {
  53                 .speed = USB_SPEED_WIRELESS,
  54                 .name = "wireless",
  55         },
  56         {
  57                 .speed = USB_SPEED_SUPER,
  58                 .name = "super-speed",
  59         },
  60 };
  61 
  62 static
  63 int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev)
  64 {
  65         const char *path, *name;
  66         char filepath[SYSFS_PATH_MAX];
  67         struct usb_device_descriptor descr;
  68         unsigned int i;
  69         FILE *fd = NULL;
  70         struct udev_device *plat;
  71         const char *speed;
  72         size_t ret;
  73 
  74         plat = udev_device_get_parent(sdev);
  75         path = udev_device_get_syspath(plat);
  76         snprintf(filepath, SYSFS_PATH_MAX, "%s/%s",
  77                  path, VUDC_DEVICE_DESCR_FILE);
  78         fd = fopen(filepath, "r");
  79         if (!fd)
  80                 return -1;
  81         ret = fread((char *) &descr, sizeof(descr), 1, fd);
  82         if (ret != 1) {
  83                 err("Cannot read vudc device descr file: %s", strerror(errno));
  84                 goto err;
  85         }
  86         fclose(fd);
  87 
  88         copy_descr_attr(dev, &descr, bDeviceClass);
  89         copy_descr_attr(dev, &descr, bDeviceSubClass);
  90         copy_descr_attr(dev, &descr, bDeviceProtocol);
  91         copy_descr_attr(dev, &descr, bNumConfigurations);
  92         copy_descr_attr16(dev, &descr, idVendor);
  93         copy_descr_attr16(dev, &descr, idProduct);
  94         copy_descr_attr16(dev, &descr, bcdDevice);
  95 
  96         strncpy(dev->path, path, SYSFS_PATH_MAX - 1);
  97         dev->path[SYSFS_PATH_MAX - 1] = '\0';
  98 
  99         dev->speed = USB_SPEED_UNKNOWN;
 100         speed = udev_device_get_sysattr_value(sdev, "current_speed");
 101         if (speed) {
 102                 for (i = 0; i < ARRAY_SIZE(speed_names); i++) {
 103                         if (!strcmp(speed_names[i].name, speed)) {
 104                                 dev->speed = speed_names[i].speed;
 105                                 break;
 106                         }
 107                 }
 108         }
 109 
 110         /* Only used for user output, little sense to output them in general */
 111         dev->bNumInterfaces = 0;
 112         dev->bConfigurationValue = 0;
 113         dev->busnum = 0;
 114 
 115         name = udev_device_get_sysname(plat);
 116         strncpy(dev->busid, name, SYSFS_BUS_ID_SIZE - 1);
 117         dev->busid[SYSFS_BUS_ID_SIZE - 1] = '\0';
 118         return 0;
 119 err:
 120         fclose(fd);
 121         return -1;
 122 }
 123 
 124 static int is_my_device(struct udev_device *dev)
 125 {
 126         const char *driver;
 127 
 128         driver = udev_device_get_property_value(dev, "USB_UDC_NAME");
 129         return driver != NULL && !strcmp(driver, USBIP_DEVICE_DRV_NAME);
 130 }
 131 
 132 static int usbip_device_driver_open(struct usbip_host_driver *hdriver)
 133 {
 134         int ret;
 135 
 136         hdriver->ndevs = 0;
 137         INIT_LIST_HEAD(&hdriver->edev_list);
 138 
 139         ret = usbip_generic_driver_open(hdriver);
 140         if (ret)
 141                 err("please load " USBIP_CORE_MOD_NAME ".ko and "
 142                     USBIP_DEVICE_DRV_NAME ".ko!");
 143 
 144         return ret;
 145 }
 146 
 147 struct usbip_host_driver device_driver = {
 148         .edev_list = LIST_HEAD_INIT(device_driver.edev_list),
 149         .udev_subsystem = "udc",
 150         .ops = {
 151                 .open = usbip_device_driver_open,
 152                 .close = usbip_generic_driver_close,
 153                 .refresh_device_list = usbip_generic_refresh_device_list,
 154                 .get_device = usbip_generic_get_device,
 155                 .read_device = read_usb_vudc_device,
 156                 .is_my_device = is_my_device,
 157         },
 158 };

/* [<][>][^][v][top][bottom][index][help] */