regulator: da9211: Fix a bug in update of mask bit
[sfrench/cifs-2.6.git] / drivers / staging / usbip / userspace / libsrc / names.c
1 /*
2  *      names.c  --  USB name database manipulation routines
3  *
4  *      Copyright (C) 1999, 2000  Thomas Sailer (sailer@ife.ee.ethz.ch)
5  *
6  *      This program is free software; you can redistribute it and/or modify
7  *      it under the terms of the GNU General Public License as published by
8  *      the Free Software Foundation; either version 2 of the License, or
9  *      (at your option) any later version.
10  *
11  *      This program is distributed in the hope that it will be useful,
12  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *      GNU General Public License for more details.
15  *
16  *      You should have received a copy of the GNU General Public License
17  *      along with this program; if not, write to the Free Software
18  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  *
21  *
22  *
23  *
24  *      Copyright (C) 2005 Takahiro Hirofuchi
25  *              - names_deinit() is added.
26  *
27  */
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <dirent.h>
33 #include <string.h>
34 #include <errno.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <stdio.h>
38 #include <ctype.h>
39
40 #include "names.h"
41 #include "usbip_common.h"
42
43 struct vendor {
44         struct vendor *next;
45         u_int16_t vendorid;
46         char name[1];
47 };
48
49 struct product {
50         struct product *next;
51         u_int16_t vendorid, productid;
52         char name[1];
53 };
54
55 struct class {
56         struct class *next;
57         u_int8_t classid;
58         char name[1];
59 };
60
61 struct subclass {
62         struct subclass *next;
63         u_int8_t classid, subclassid;
64         char name[1];
65 };
66
67 struct protocol {
68         struct protocol *next;
69         u_int8_t classid, subclassid, protocolid;
70         char name[1];
71 };
72
73 struct genericstrtable {
74         struct genericstrtable *next;
75         unsigned int num;
76         char name[1];
77 };
78
79
80 #define HASH1  0x10
81 #define HASH2  0x02
82 #define HASHSZ 16
83
84 static unsigned int hashnum(unsigned int num)
85 {
86         unsigned int mask1 = HASH1 << 27, mask2 = HASH2 << 27;
87
88         for (; mask1 >= HASH1; mask1 >>= 1, mask2 >>= 1)
89                 if (num & mask1)
90                         num ^= mask2;
91         return num & (HASHSZ-1);
92 }
93
94
95 static struct vendor *vendors[HASHSZ] = { NULL, };
96 static struct product *products[HASHSZ] = { NULL, };
97 static struct class *classes[HASHSZ] = { NULL, };
98 static struct subclass *subclasses[HASHSZ] = { NULL, };
99 static struct protocol *protocols[HASHSZ] = { NULL, };
100
101 const char *names_vendor(u_int16_t vendorid)
102 {
103         struct vendor *v;
104
105         v = vendors[hashnum(vendorid)];
106         for (; v; v = v->next)
107                 if (v->vendorid == vendorid)
108                         return v->name;
109         return NULL;
110 }
111
112 const char *names_product(u_int16_t vendorid, u_int16_t productid)
113 {
114         struct product *p;
115
116         p = products[hashnum((vendorid << 16) | productid)];
117         for (; p; p = p->next)
118                 if (p->vendorid == vendorid && p->productid == productid)
119                         return p->name;
120         return NULL;
121 }
122
123 const char *names_class(u_int8_t classid)
124 {
125         struct class *c;
126
127         c = classes[hashnum(classid)];
128         for (; c; c = c->next)
129                 if (c->classid == classid)
130                         return c->name;
131         return NULL;
132 }
133
134 const char *names_subclass(u_int8_t classid, u_int8_t subclassid)
135 {
136         struct subclass *s;
137
138         s = subclasses[hashnum((classid << 8) | subclassid)];
139         for (; s; s = s->next)
140                 if (s->classid == classid && s->subclassid == subclassid)
141                         return s->name;
142         return NULL;
143 }
144
145 const char *names_protocol(u_int8_t classid, u_int8_t subclassid,
146                            u_int8_t protocolid)
147 {
148         struct protocol *p;
149
150         p = protocols[hashnum((classid << 16) | (subclassid << 8)
151                               | protocolid)];
152         for (; p; p = p->next)
153                 if (p->classid == classid && p->subclassid == subclassid &&
154                     p->protocolid == protocolid)
155                         return p->name;
156         return NULL;
157 }
158
159 /* add a cleanup function by takahiro */
160 struct pool {
161         struct pool *next;
162         void *mem;
163 };
164
165 static struct pool *pool_head;
166
167 static void *my_malloc(size_t size)
168 {
169         struct pool *p;
170
171         p = calloc(1, sizeof(struct pool));
172         if (!p)
173                 return NULL;
174
175         p->mem = calloc(1, size);
176         if (!p->mem) {
177                 free(p);
178                 return NULL;
179         }
180
181         p->next = pool_head;
182         pool_head = p;
183
184         return p->mem;
185 }
186
187 void names_free(void)
188 {
189         struct pool *pool;
190
191         if (!pool_head)
192                 return;
193
194         for (pool = pool_head; pool != NULL; ) {
195                 struct pool *tmp;
196
197                 if (pool->mem)
198                         free(pool->mem);
199
200                 tmp = pool;
201                 pool = pool->next;
202                 free(tmp);
203         }
204 }
205
206 static int new_vendor(const char *name, u_int16_t vendorid)
207 {
208         struct vendor *v;
209         unsigned int h = hashnum(vendorid);
210
211         v = vendors[h];
212         for (; v; v = v->next)
213                 if (v->vendorid == vendorid)
214                         return -1;
215         v = my_malloc(sizeof(struct vendor) + strlen(name));
216         if (!v)
217                 return -1;
218         strcpy(v->name, name);
219         v->vendorid = vendorid;
220         v->next = vendors[h];
221         vendors[h] = v;
222         return 0;
223 }
224
225 static int new_product(const char *name, u_int16_t vendorid,
226                        u_int16_t productid)
227 {
228         struct product *p;
229         unsigned int h = hashnum((vendorid << 16) | productid);
230
231         p = products[h];
232         for (; p; p = p->next)
233                 if (p->vendorid == vendorid && p->productid == productid)
234                         return -1;
235         p = my_malloc(sizeof(struct product) + strlen(name));
236         if (!p)
237                 return -1;
238         strcpy(p->name, name);
239         p->vendorid = vendorid;
240         p->productid = productid;
241         p->next = products[h];
242         products[h] = p;
243         return 0;
244 }
245
246 static int new_class(const char *name, u_int8_t classid)
247 {
248         struct class *c;
249         unsigned int h = hashnum(classid);
250
251         c = classes[h];
252         for (; c; c = c->next)
253                 if (c->classid == classid)
254                         return -1;
255         c = my_malloc(sizeof(struct class) + strlen(name));
256         if (!c)
257                 return -1;
258         strcpy(c->name, name);
259         c->classid = classid;
260         c->next = classes[h];
261         classes[h] = c;
262         return 0;
263 }
264
265 static int new_subclass(const char *name, u_int8_t classid, u_int8_t subclassid)
266 {
267         struct subclass *s;
268         unsigned int h = hashnum((classid << 8) | subclassid);
269
270         s = subclasses[h];
271         for (; s; s = s->next)
272                 if (s->classid == classid && s->subclassid == subclassid)
273                         return -1;
274         s = my_malloc(sizeof(struct subclass) + strlen(name));
275         if (!s)
276                 return -1;
277         strcpy(s->name, name);
278         s->classid = classid;
279         s->subclassid = subclassid;
280         s->next = subclasses[h];
281         subclasses[h] = s;
282         return 0;
283 }
284
285 static int new_protocol(const char *name, u_int8_t classid, u_int8_t subclassid,
286                         u_int8_t protocolid)
287 {
288         struct protocol *p;
289         unsigned int h = hashnum((classid << 16) | (subclassid << 8)
290                                  | protocolid);
291
292         p = protocols[h];
293         for (; p; p = p->next)
294                 if (p->classid == classid && p->subclassid == subclassid
295                     && p->protocolid == protocolid)
296                         return -1;
297         p = my_malloc(sizeof(struct protocol) + strlen(name));
298         if (!p)
299                 return -1;
300         strcpy(p->name, name);
301         p->classid = classid;
302         p->subclassid = subclassid;
303         p->protocolid = protocolid;
304         p->next = protocols[h];
305         protocols[h] = p;
306         return 0;
307 }
308
309 static void parse(FILE *f)
310 {
311         char buf[512], *cp;
312         unsigned int linectr = 0;
313         int lastvendor = -1;
314         int lastclass = -1;
315         int lastsubclass = -1;
316         int lasthut = -1;
317         int lastlang = -1;
318         unsigned int u;
319
320         while (fgets(buf, sizeof(buf), f)) {
321                 linectr++;
322                 /* remove line ends */
323                 cp = strchr(buf, '\r');
324                 if (cp)
325                         *cp = 0;
326                 cp = strchr(buf, '\n');
327                 if (cp)
328                         *cp = 0;
329                 if (buf[0] == '#' || !buf[0])
330                         continue;
331                 cp = buf;
332                 if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' &&
333                     buf[3] == 'S' && buf[4] == 'D' &&
334                     buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/
335                     buf[7] == ' ') {
336                         continue;
337                 }
338                 if (buf[0] == 'P' && buf[1] == 'H' &&
339                     buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') {
340                         continue;
341                 }
342                 if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' &&
343                     buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') {
344                         continue;
345                 }
346                 if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') {
347                         lasthut = lastclass = lastvendor = lastsubclass = -1;
348                         /*
349                          * set 1 as pseudo-id to indicate that the parser is
350                          * in a `L' section.
351                          */
352                         lastlang = 1;
353                         continue;
354                 }
355                 if (buf[0] == 'C' && /*isspace(buf[1])*/ buf[1] == ' ') {
356                         /* class spec */
357                         cp = buf+2;
358                         while (isspace(*cp))
359                                 cp++;
360                         if (!isxdigit(*cp)) {
361                                 err("Invalid class spec at line %u", linectr);
362                                 continue;
363                         }
364                         u = strtoul(cp, &cp, 16);
365                         while (isspace(*cp))
366                                 cp++;
367                         if (!*cp) {
368                                 err("Invalid class spec at line %u", linectr);
369                                 continue;
370                         }
371                         if (new_class(cp, u))
372                                 err("Duplicate class spec at line %u class %04x %s",
373                                     linectr, u, cp);
374                         dbg("line %5u class %02x %s", linectr, u, cp);
375                         lasthut = lastlang = lastvendor = lastsubclass = -1;
376                         lastclass = u;
377                         continue;
378                 }
379                 if (buf[0] == 'A' && buf[1] == 'T' && isspace(buf[2])) {
380                         /* audio terminal type spec */
381                         continue;
382                 }
383                 if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C'
384                     && isspace(buf[3])) {
385                         /* HID Descriptor bCountryCode */
386                         continue;
387                 }
388                 if (isxdigit(*cp)) {
389                         /* vendor */
390                         u = strtoul(cp, &cp, 16);
391                         while (isspace(*cp))
392                                 cp++;
393                         if (!*cp) {
394                                 err("Invalid vendor spec at line %u", linectr);
395                                 continue;
396                         }
397                         if (new_vendor(cp, u))
398                                 err("Duplicate vendor spec at line %u vendor %04x %s",
399                                     linectr, u, cp);
400                         dbg("line %5u vendor %04x %s", linectr, u, cp);
401                         lastvendor = u;
402                         lasthut = lastlang = lastclass = lastsubclass = -1;
403                         continue;
404                 }
405                 if (buf[0] == '\t' && isxdigit(buf[1])) {
406                         /* product or subclass spec */
407                         u = strtoul(buf+1, &cp, 16);
408                         while (isspace(*cp))
409                                 cp++;
410                         if (!*cp) {
411                                 err("Invalid product/subclass spec at line %u",
412                                     linectr);
413                                 continue;
414                         }
415                         if (lastvendor != -1) {
416                                 if (new_product(cp, lastvendor, u))
417                                         err("Duplicate product spec at line %u product %04x:%04x %s",
418                                             linectr, lastvendor, u, cp);
419                                 dbg("line %5u product %04x:%04x %s", linectr,
420                                     lastvendor, u, cp);
421                                 continue;
422                         }
423                         if (lastclass != -1) {
424                                 if (new_subclass(cp, lastclass, u))
425                                         err("Duplicate subclass spec at line %u class %02x:%02x %s",
426                                             linectr, lastclass, u, cp);
427                                 dbg("line %5u subclass %02x:%02x %s", linectr,
428                                     lastclass, u, cp);
429                                 lastsubclass = u;
430                                 continue;
431                         }
432                         if (lasthut != -1) {
433                                 /* do not store hut */
434                                 continue;
435                         }
436                         if (lastlang != -1) {
437                                 /* do not store langid */
438                                 continue;
439                         }
440                         err("Product/Subclass spec without prior Vendor/Class spec at line %u",
441                             linectr);
442                         continue;
443                 }
444                 if (buf[0] == '\t' && buf[1] == '\t' && isxdigit(buf[2])) {
445                         /* protocol spec */
446                         u = strtoul(buf+2, &cp, 16);
447                         while (isspace(*cp))
448                                 cp++;
449                         if (!*cp) {
450                                 err("Invalid protocol spec at line %u",
451                                     linectr);
452                                 continue;
453                         }
454                         if (lastclass != -1 && lastsubclass != -1) {
455                                 if (new_protocol(cp, lastclass, lastsubclass,
456                                                  u))
457                                         err("Duplicate protocol spec at line %u class %02x:%02x:%02x %s",
458                                             linectr, lastclass, lastsubclass,
459                                             u, cp);
460                                 dbg("line %5u protocol %02x:%02x:%02x %s",
461                                     linectr, lastclass, lastsubclass, u, cp);
462                                 continue;
463                         }
464                         err("Protocol spec without prior Class and Subclass spec at line %u",
465                             linectr);
466                         continue;
467                 }
468                 if (buf[0] == 'H' && buf[1] == 'I' &&
469                     buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') {
470                         continue;
471                 }
472                 if (buf[0] == 'H' && buf[1] == 'U' &&
473                     buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') {
474                         lastlang = lastclass = lastvendor = lastsubclass = -1;
475                         /*
476                          * set 1 as pseudo-id to indicate that the parser is
477                          * in a `HUT' section.
478                          */
479                         lasthut = 1;
480                         continue;
481                 }
482                 if (buf[0] == 'R' && buf[1] == ' ')
483                         continue;
484
485                 if (buf[0] == 'V' && buf[1] == 'T')
486                         continue;
487
488                 err("Unknown line at line %u", linectr);
489         }
490 }
491
492
493 int names_init(char *n)
494 {
495         FILE *f;
496
497         f = fopen(n, "r");
498         if (!f)
499                 return errno;
500
501         parse(f);
502         fclose(f);
503         return 0;
504 }