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