1/* 2 * Copyright (C) 2005-2007 Takahiro Hirofuchi 3 */ 4 5#include "usbip_common.h" 6#include "names.h" 7 8#undef PROGNAME 9#define PROGNAME "libusbip" 10 11int usbip_use_syslog = 0; 12int usbip_use_stderr = 0; 13int usbip_use_debug = 0; 14 15struct speed_string { 16 int num; 17 char *speed; 18 char *desc; 19}; 20 21static const struct speed_string speed_strings[] = { 22 { USB_SPEED_UNKNOWN, "unknown", "Unknown Speed"}, 23 { USB_SPEED_LOW, "1.5", "Low Speed(1.5Mbps)" }, 24 { USB_SPEED_FULL, "12", "Full Speed(12Mbps)" }, 25 { USB_SPEED_HIGH, "480", "High Speed(480Mbps)" }, 26 { 0, NULL, NULL } 27}; 28 29struct portst_string { 30 int num; 31 char *desc; 32}; 33 34static struct portst_string portst_strings[] = { 35 { SDEV_ST_AVAILABLE, "Device Available" }, 36 { SDEV_ST_USED, "Device in Use" }, 37 { SDEV_ST_ERROR, "Device Error"}, 38 { VDEV_ST_NULL, "Port Available"}, 39 { VDEV_ST_NOTASSIGNED, "Port Initializing"}, 40 { VDEV_ST_USED, "Port in Use"}, 41 { VDEV_ST_ERROR, "Port Error"}, 42 { 0, NULL} 43}; 44 45const char *usbip_status_string(int32_t status) 46{ 47 for (int i=0; portst_strings[i].desc != NULL; i++) 48 if (portst_strings[i].num == status) 49 return portst_strings[i].desc; 50 51 return "Unknown Status"; 52} 53 54const char *usbip_speed_string(int num) 55{ 56 for (int i=0; speed_strings[i].speed != NULL; i++) 57 if (speed_strings[i].num == num) 58 return speed_strings[i].desc; 59 60 return "Unknown Speed"; 61} 62 63 64#define DBG_UDEV_INTEGER(name)\ 65 dbg("%-20s = %x", to_string(name), (int) udev->name) 66 67#define DBG_UINF_INTEGER(name)\ 68 dbg("%-20s = %x", to_string(name), (int) uinf->name) 69 70void dump_usb_interface(struct usbip_usb_interface *uinf) 71{ 72 char buff[100]; 73 usbip_names_get_class(buff, sizeof(buff), 74 uinf->bInterfaceClass, 75 uinf->bInterfaceSubClass, 76 uinf->bInterfaceProtocol); 77 dbg("%-20s = %s", "Interface(C/SC/P)", buff); 78} 79 80void dump_usb_device(struct usbip_usb_device *udev) 81{ 82 char buff[100]; 83 84 85 dbg("%-20s = %s", "path", udev->path); 86 dbg("%-20s = %s", "busid", udev->busid); 87 88 usbip_names_get_class(buff, sizeof(buff), 89 udev->bDeviceClass, 90 udev->bDeviceSubClass, 91 udev->bDeviceProtocol); 92 dbg("%-20s = %s", "Device(C/SC/P)", buff); 93 94 DBG_UDEV_INTEGER(bcdDevice); 95 96 usbip_names_get_product(buff, sizeof(buff), 97 udev->idVendor, 98 udev->idProduct); 99 dbg("%-20s = %s", "Vendor/Product", buff); 100 101 DBG_UDEV_INTEGER(bNumConfigurations); 102 DBG_UDEV_INTEGER(bNumInterfaces); 103 104 dbg("%-20s = %s", "speed", 105 usbip_speed_string(udev->speed)); 106 107 DBG_UDEV_INTEGER(busnum); 108 DBG_UDEV_INTEGER(devnum); 109} 110 111 112int read_attr_value(struct sysfs_device *dev, const char *name, const char *format) 113{ 114 char attrpath[SYSFS_PATH_MAX]; 115 struct sysfs_attribute *attr; 116 int num = 0; 117 int ret; 118 119 snprintf(attrpath, sizeof(attrpath), "%s/%s", dev->path, name); 120 121 attr = sysfs_open_attribute(attrpath); 122 if (!attr) { 123 dbg("sysfs_open_attribute failed: %s", attrpath); 124 return 0; 125 } 126 127 ret = sysfs_read_attribute(attr); 128 if (ret < 0) { 129 dbg("sysfs_read_attribute failed"); 130 goto err; 131 } 132 133 ret = sscanf(attr->value, format, &num); 134 if (ret < 1) { 135 dbg("sscanf failed"); 136 goto err; 137 } 138 139err: 140 sysfs_close_attribute(attr); 141 142 return num; 143} 144 145 146int read_attr_speed(struct sysfs_device *dev) 147{ 148 char attrpath[SYSFS_PATH_MAX]; 149 struct sysfs_attribute *attr; 150 char speed[100]; 151 int ret; 152 153 snprintf(attrpath, sizeof(attrpath), "%s/%s", dev->path, "speed"); 154 155 attr = sysfs_open_attribute(attrpath); 156 if (!attr) { 157 dbg("sysfs_open_attribute failed: %s", attrpath); 158 return 0; 159 } 160 161 ret = sysfs_read_attribute(attr); 162 if (ret < 0) { 163 dbg("sysfs_read_attribute failed"); 164 goto err; 165 } 166 167 ret = sscanf(attr->value, "%s\n", speed); 168 if (ret < 1) { 169 dbg("sscanf failed"); 170 goto err; 171 } 172err: 173 sysfs_close_attribute(attr); 174 175 for (int i=0; speed_strings[i].speed != NULL; i++) { 176 if (!strcmp(speed, speed_strings[i].speed)) 177 return speed_strings[i].num; 178 } 179 180 return USB_SPEED_UNKNOWN; 181} 182 183#define READ_ATTR(object, type, dev, name, format)\ 184 do { (object)->name = (type) read_attr_value(dev, to_string(name), format); } while (0) 185 186 187int read_usb_device(struct sysfs_device *sdev, struct usbip_usb_device *udev) 188{ 189 uint32_t busnum, devnum; 190 191 READ_ATTR(udev, uint8_t, sdev, bDeviceClass, "%02x\n"); 192 READ_ATTR(udev, uint8_t, sdev, bDeviceSubClass, "%02x\n"); 193 READ_ATTR(udev, uint8_t, sdev, bDeviceProtocol, "%02x\n"); 194 195 READ_ATTR(udev, uint16_t, sdev, idVendor, "%04x\n"); 196 READ_ATTR(udev, uint16_t, sdev, idProduct, "%04x\n"); 197 READ_ATTR(udev, uint16_t, sdev, bcdDevice, "%04x\n"); 198 199 READ_ATTR(udev, uint8_t, sdev, bConfigurationValue, "%02x\n"); 200 READ_ATTR(udev, uint8_t, sdev, bNumConfigurations, "%02x\n"); 201 READ_ATTR(udev, uint8_t, sdev, bNumInterfaces, "%02x\n"); 202 203 READ_ATTR(udev, uint8_t, sdev, devnum, "%d\n"); 204 udev->speed = read_attr_speed(sdev); 205 206 strncpy(udev->path, sdev->path, SYSFS_PATH_MAX); 207 strncpy(udev->busid, sdev->name, SYSFS_BUS_ID_SIZE); 208 209 sscanf(sdev->name, "%u-%u", &busnum, &devnum); 210 udev->busnum = busnum; 211 212 return 0; 213} 214 215int read_usb_interface(struct usbip_usb_device *udev, int i, 216 struct usbip_usb_interface *uinf) 217{ 218 char busid[SYSFS_BUS_ID_SIZE]; 219 struct sysfs_device *sif; 220 221 sprintf(busid, "%s:%d.%d", udev->busid, udev->bConfigurationValue, i); 222 223 sif = sysfs_open_device("usb", busid); 224 if (!sif) { 225 dbg("sysfs_open_device(\"usb\", \"%s\") failed", busid); 226 return -1; 227 } 228 229 READ_ATTR(uinf, uint8_t, sif, bInterfaceClass, "%02x\n"); 230 READ_ATTR(uinf, uint8_t, sif, bInterfaceSubClass, "%02x\n"); 231 READ_ATTR(uinf, uint8_t, sif, bInterfaceProtocol, "%02x\n"); 232 233 sysfs_close_device(sif); 234 235 return 0; 236} 237 238int usbip_names_init(char *f) 239{ 240 return names_init(f); 241} 242 243void usbip_names_free() 244{ 245 names_free(); 246} 247 248void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, uint16_t product) 249{ 250 const char *prod, *vend; 251 252 prod = names_product(vendor, product); 253 if (!prod) 254 prod = "unknown product"; 255 256 257 vend = names_vendor(vendor); 258 if (!vend) 259 vend = "unknown vendor"; 260 261 snprintf(buff, size, "%s : %s (%04x:%04x)", vend, prod, vendor, product); 262} 263 264void usbip_names_get_class(char *buff, size_t size, uint8_t class, uint8_t subclass, uint8_t protocol) 265{ 266 const char *c, *s, *p; 267 268 if (class == 0 && subclass == 0 && protocol == 0) { 269 snprintf(buff, size, "(Defined at Interface level) (%02x/%02x/%02x)", class, subclass, protocol); 270 return; 271 } 272 273 p = names_protocol(class, subclass, protocol); 274 if (!p) 275 p = "unknown protocol"; 276 277 s = names_subclass(class, subclass); 278 if (!s) 279 s = "unknown subclass"; 280 281 c = names_class(class); 282 if (!c) 283 c = "unknown class"; 284 285 snprintf(buff, size, "%s / %s / %s (%02x/%02x/%02x)", c, s, p, class, subclass, protocol); 286} 287