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