]> git.zerfleddert.de Git - usb-driver/blob - usb-driver.c
55a74637991af424a683168c3b29d1bef882fd6f
[usb-driver] / usb-driver.c
1 /* libusb/ppdev connector for XILINX impact
2 *
3 * Copyright (c) 2007 Michael Gernoth <michael@gernoth.net>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #define _GNU_SOURCE 1
25
26 #include <dlfcn.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/time.h>
35 #include <stdio.h>
36 #include <signal.h>
37 #include <errno.h>
38 #include <inttypes.h>
39 #include <sys/ioctl.h>
40 #include <sys/utsname.h>
41 #include <bits/wordsize.h>
42 #include <sys/ipc.h>
43 #include <sys/sem.h>
44 #include <syscall.h>
45 #include <linux/personality.h>
46 #include "usb-driver.h"
47 #include "config.h"
48 #include "xpcu.h"
49
50 static int (*ioctl_func) (int, int, void *) = NULL;
51 static int *windrvrfds = NULL;
52 static int windrvrfds_count = 0;
53 static unsigned long ppbase = 0;
54 static unsigned long ecpbase = 0;
55 static struct parport_config *pport = NULL;
56 static FILE *modulesfp = NULL;
57 static FILE *baseaddrfp = NULL;
58 static int baseaddrnum = 0;
59 static int modules_read = 0;
60
61 #define NO_WINDRVR 1
62
63 void hexdump(unsigned char *buf, int len, char *prefix) {
64 int i;
65
66 fprintf(stderr, "%s ", prefix);
67 for(i=0; i<len; i++) {
68 fprintf(stderr,"%02x ", buf[i]);
69 if ((i % 16) == 15)
70 fprintf(stderr,"\n%s ", prefix);
71 }
72 fprintf(stderr,"\n");
73 }
74
75
76 static int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) {
77 struct header_struct* wdheader = (struct header_struct*)wdioctl;
78 struct version_struct *version;
79 int ret = 0;
80
81 if (wdheader->magic != MAGIC) {
82 fprintf(stderr,"!!!ERROR: magic header does not match!!!\n");
83 return (*ioctl_func) (fd, request, wdioctl);
84 }
85
86 switch(request & ~(0xc0000000)) {
87 case VERSION:
88 version = (struct version_struct*)(wdheader->data);
89 strcpy(version->version, "libusb-driver.so version: " USB_DRIVER_VERSION);
90 version->versionul = 802;
91 DPRINTF("VERSION\n");
92 break;
93
94 case LICENSE:
95 DPRINTF("LICENSE\n");
96 break;
97
98 case CARD_REGISTER_OLD:
99 case CARD_REGISTER:
100 DPRINTF("CARD_REGISTER\n");
101 {
102 struct card_register* cr = (struct card_register*)(wdheader->data);
103
104 DPRINTF("-> Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n",
105 cr->Card.dwItems,
106 (unsigned long)cr->Card.Item[0].I.IO.dwAddr,
107 cr->Card.Item[0].I.IO.dwBytes,
108 cr->Card.Item[0].I.IO.dwBar);
109
110 DPRINTF("-> Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n",
111 cr->Card.dwItems,
112 (unsigned long)cr->Card.Item[1].I.IO.dwAddr,
113 cr->Card.Item[1].I.IO.dwBytes,
114 cr->Card.Item[1].I.IO.dwBar);
115 #ifndef NO_WINDRVR
116 ret = (*ioctl_func) (fd, request, wdioctl);
117 #else
118
119 pport = config_get((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10);
120 if (!pport)
121 break;
122
123 ret = pport->open((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10);
124
125 ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr;
126
127 if (cr->Card.dwItems > 1 && cr->Card.Item[1].I.IO.dwAddr)
128 ecpbase = (unsigned long)cr->Card.Item[1].I.IO.dwAddr;
129
130 if (ret >= 0) {
131 cr->hCard = ret;
132 } else {
133 cr->hCard = 0;
134 }
135 #endif
136 DPRINTF("<-hCard: %lu\n", cr->hCard);
137 }
138 break;
139
140 case USB_TRANSFER:
141 DPRINTF("USB_TRANSFER\n");
142 {
143 struct usb_transfer *ut = (struct usb_transfer*)(wdheader->data);
144
145 #ifdef DEBUG
146 DPRINTF("-> unique: 0x%lx, pipe: %lu, read: %lu, options: %lx, size: %lu, timeout: %lx\n",
147 ut->dwUniqueID, ut->dwPipeNum, ut->fRead,
148 ut->dwOptions, ut->dwBufferSize, ut->dwTimeout);
149 if (ut->dwPipeNum == 0) {
150 DPRINTF("-> setup packet:");
151 hexdump(ut->SetupPacket, 8, "");
152 }
153
154 if (!ut->fRead && ut->dwBufferSize)
155 {
156 hexdump(ut->pBuffer, ut->dwBufferSize, "->");
157 }
158 #endif
159
160 #ifndef NO_WINDRVR
161 ret = (*ioctl_func) (fd, request, wdioctl);
162 #else
163 ret = xpcu_transfer(ut);
164 #endif
165
166 #ifdef DEBUG
167 DPRINTF("Transferred: %lu (%s)\n",ut->dwBytesTransferred, (ut->fRead?"read":"write"));
168 if (ut->fRead && ut->dwBytesTransferred)
169 {
170 hexdump(ut->pBuffer, ut->dwBytesTransferred, "<-");
171 }
172 #endif
173 }
174 break;
175
176 case INT_ENABLE_OLD:
177 case INT_ENABLE:
178 DPRINTF("INT_ENABLE\n");
179 {
180 struct interrupt *it = (struct interrupt*)(wdheader->data);
181
182 DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
183 it->hInterrupt, it->dwOptions,
184 it->dwCmds, it->fEnableOk, it->dwCounter,
185 it->dwLost, it->fStopped);
186
187 #ifndef NO_WINDRVR
188 ret = (*ioctl_func) (fd, request, wdioctl);
189 #else
190 ret = xpcu_int_state(it, ENABLE_INTERRUPT);
191 #endif
192
193 DPRINTF("<- Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
194 it->hInterrupt, it->dwOptions,
195 it->dwCmds, it->fEnableOk, it->dwCounter,
196 it->dwLost, it->fStopped);
197 }
198
199 break;
200
201 case INT_DISABLE:
202 DPRINTF("INT_DISABLE\n");
203 {
204 struct interrupt *it = (struct interrupt*)(wdheader->data);
205
206 DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
207 it->hInterrupt, it->dwOptions,
208 it->dwCmds, it->fEnableOk, it->dwCounter,
209 it->dwLost, it->fStopped);
210 #ifndef NO_WINDRVR
211 ret = (*ioctl_func) (fd, request, wdioctl);
212 #else
213 ret = xpcu_int_state(it, DISABLE_INTERRUPT);
214 #endif
215 DPRINTF("<- Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
216 it->hInterrupt, it->dwOptions,
217 it->dwCmds, it->fEnableOk, it->dwCounter,
218 it->dwLost, it->fStopped);
219 }
220 break;
221
222 case USB_SET_INTERFACE:
223 DPRINTF("USB_SET_INTERFACE\n");
224 {
225 struct usb_set_interface *usi = (struct usb_set_interface*)(wdheader->data);
226
227 DPRINTF("-> unique: 0x%lx, interfacenum: %lu, alternatesetting: %lu, options: %lx\n",
228 usi->dwUniqueID, usi->dwInterfaceNum,
229 usi->dwAlternateSetting, usi->dwOptions);
230 #ifndef NO_WINDRVR
231 ret = (*ioctl_func) (fd, request, wdioctl);
232 #else
233 ret = xpcu_set_interface(usi);
234 #endif
235 DPRINTF("<- unique: 0x%lx, interfacenum: %lu, alternatesetting: %lu, options: %lx\n",
236 usi->dwUniqueID, usi->dwInterfaceNum,
237 usi->dwAlternateSetting, usi->dwOptions);
238 }
239 break;
240
241 case USB_GET_DEVICE_DATA_OLD:
242 case USB_GET_DEVICE_DATA:
243 DPRINTF("USB_GET_DEVICE_DATA\n");
244 {
245 struct usb_get_device_data *ugdd = (struct usb_get_device_data*)(wdheader->data);
246
247 DPRINTF("-> unique: 0x%lx, bytes: %lu, options: %lx\n",
248 ugdd->dwUniqueID, ugdd->dwBytes,
249 ugdd->dwOptions);
250
251 ret = xpcu_deviceinfo(ugdd);
252
253 }
254 break;
255
256 case EVENT_REGISTER_OLD:
257 case EVENT_REGISTER:
258 DPRINTF("EVENT_REGISTER\n");
259 {
260 struct event *e = (struct event*)(wdheader->data);
261 #ifdef DEBUG
262 int i;
263 #endif
264
265 DPRINTF("-> handle: 0x%lx, action: %lu, status: %lu, eventid: %lu, cardtype: %lu, kplug: %lu, options: %lu, dev: %lx:%lx, unique: 0x%lx, ver: %lu, nummatch: %lu\n",
266 e->handle, e->dwAction,
267 e->dwStatus, e->dwEventId, e->dwCardType,
268 e->hKernelPlugIn, e->dwOptions,
269 e->u.Usb.deviceId.dwVendorId,
270 e->u.Usb.deviceId.dwProductId,
271 e->u.Usb.dwUniqueID, e->dwEventVer,
272 e->dwNumMatchTables);
273
274 #ifndef NO_WINDRVR
275 ret = (*ioctl_func) (fd, request, wdioctl);
276 #else
277 ret = xpcu_find(e);
278 #endif
279
280 #ifdef DEBUG
281 DPRINTF("<- handle: 0x%lx, action: %lu, status: %lu, eventid: %lu, cardtype: %lu, kplug: %lu, options: %lu, dev: %lx:%lx, unique: 0x%lx, ver: %lu, nummatch: %lu\n",
282 e->handle, e->dwAction,
283 e->dwStatus, e->dwEventId, e->dwCardType,
284 e->hKernelPlugIn, e->dwOptions,
285 e->u.Usb.deviceId.dwVendorId,
286 e->u.Usb.deviceId.dwProductId,
287 e->u.Usb.dwUniqueID, e->dwEventVer,
288 e->dwNumMatchTables);
289
290 for (i = 0; i < e->dwNumMatchTables; i++)
291 DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
292 e->matchTables[i].VendorId,
293 e->matchTables[i].ProductId,
294 e->matchTables[i].bDeviceClass,
295 e->matchTables[i].bDeviceSubClass,
296 e->matchTables[i].bInterfaceClass,
297 e->matchTables[i].bInterfaceSubClass,
298 e->matchTables[i].bInterfaceProtocol);
299 #endif
300 }
301 break;
302
303 case TRANSFER_OLD:
304 case TRANSFER:
305 DPRINTF("TRANSFER\n");
306 {
307 WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);
308
309 #ifndef NO_WINDRVR
310 ret = (*ioctl_func) (fd, request, wdioctl);
311 #else
312 ret = pport->transfer(tr, fd, request, ppbase, ecpbase, 1);
313 #endif
314 }
315 break;
316
317 case MULTI_TRANSFER_OLD:
318 case MULTI_TRANSFER:
319 DPRINTF("MULTI_TRANSFER\n");
320 {
321 WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);
322 unsigned long num = wdheader->size/sizeof(WD_TRANSFER);
323 #ifndef NO_WINDRVR
324 ret = (*ioctl_func) (fd, request, wdioctl);
325 #else
326 ret = pport->transfer(tr, fd, request, ppbase, ecpbase, num);
327 #endif
328 }
329 break;
330
331 case EVENT_UNREGISTER:
332 {
333 struct event *e = (struct event*)(wdheader->data);
334
335 DPRINTF("EVENT_UNREGISTER\n");
336 #ifndef NO_WINDRVR
337 ret = (*ioctl_func) (fd, request, wdioctl);
338 #else
339 ret = xpcu_close(e);
340 #endif
341 }
342 break;
343
344 case INT_WAIT:
345 DPRINTF("INT_WAIT\n");
346 {
347 struct interrupt *it = (struct interrupt*)(wdheader->data);
348
349 DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
350 it->hInterrupt, it->dwOptions,
351 it->dwCmds, it->fEnableOk, it->dwCounter,
352 it->dwLost, it->fStopped);
353
354 #ifndef NO_WINDRVR
355 ret = (*ioctl_func) (fd, request, wdioctl);
356 #else
357 ret = xpcu_int_wait(it);
358 #endif
359
360 DPRINTF("<- INT_WAIT_RETURN: Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
361 it->hInterrupt, it->dwOptions, it->dwCmds,
362 it->fEnableOk, it->dwCounter, it->dwLost,
363 it->fStopped);
364 }
365 break;
366
367 case CARD_UNREGISTER:
368 DPRINTF("CARD_UNREGISTER\n");
369 {
370 struct card_register* cr = (struct card_register*)(wdheader->data);
371
372 DPRINTF("-> Addr: 0x%lx, bytes: %lu, bar: %lu\n",
373 (unsigned long)cr->Card.Item[0].I.IO.dwAddr,
374 cr->Card.Item[0].I.IO.dwBytes,
375 cr->Card.Item[0].I.IO.dwBar);
376
377 DPRINTF("-> hCard: %lu\n", cr->hCard);
378
379 #ifndef NO_WINDRVR
380 ret = (*ioctl_func) (fd, request, wdioctl);
381 #else
382 if (pport)
383 pport->close(cr->hCard);
384
385 pport = NULL;
386 #endif
387 }
388 break;
389
390 case EVENT_PULL:
391 DPRINTF("EVENT_PULL\n");
392 {
393 struct event *e = (struct event*)(wdheader->data);
394 #ifdef DEBUG
395 int i;
396
397 DPRINTF("-> handle: 0x%lx, action: %lu, status: %lu, eventid: %lu, cardtype: %lx, kplug: %lu, options: %lu, dev: %lx:%lx, unique: 0x%lx, ver: %lu, nummatch: %lu\n",
398 e->handle, e->dwAction, e->dwStatus,
399 e->dwEventId, e->dwCardType, e->hKernelPlugIn,
400 e->dwOptions, e->u.Usb.deviceId.dwVendorId,
401 e->u.Usb.deviceId.dwProductId,
402 e->u.Usb.dwUniqueID, e->dwEventVer,
403 e->dwNumMatchTables);
404
405 for (i = 0; i < e->dwNumMatchTables; i++)
406 DPRINTF("-> match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
407 e->matchTables[i].VendorId,
408 e->matchTables[i].ProductId,
409 e->matchTables[i].bDeviceClass,
410 e->matchTables[i].bDeviceSubClass,
411 e->matchTables[i].bInterfaceClass,
412 e->matchTables[i].bInterfaceSubClass,
413 e->matchTables[i].bInterfaceProtocol);
414 #endif
415
416 #ifndef NO_WINDRVR
417 ret = (*ioctl_func) (fd, request, wdioctl);
418 #else
419 ret = xpcu_found(e);
420 #endif
421
422 #ifdef DEBUG
423 DPRINTF("<- handle: 0x%lx, action: %lu, status: %lu, eventid: %lu, cardtype: %lx, kplug: %lu, options: %lu, dev: %lx:%lx, unique: 0x%lx, ver: %lu, nummatch: %lu\n",
424 e->handle, e->dwAction, e->dwStatus,
425 e->dwEventId, e->dwCardType, e->hKernelPlugIn,
426 e->dwOptions, e->u.Usb.deviceId.dwVendorId,
427 e->u.Usb.deviceId.dwProductId,
428 e->u.Usb.dwUniqueID, e->dwEventVer,
429 e->dwNumMatchTables);
430
431 for (i = 0; i < e->dwNumMatchTables; i++)
432 DPRINTF("<- match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
433 e->matchTables[i].VendorId,
434 e->matchTables[i].ProductId,
435 e->matchTables[i].bDeviceClass,
436 e->matchTables[i].bDeviceSubClass,
437 e->matchTables[i].bInterfaceClass,
438 e->matchTables[i].bInterfaceSubClass,
439 e->matchTables[i].bInterfaceProtocol);
440 #endif
441
442 }
443 break;
444
445 default:
446 fprintf(stderr,"!!!Unsupported IOCTL: %x!!!\n", request);
447 #ifndef NO_WINDRVR
448 ret = (*ioctl_func) (fd, request, wdioctl);
449 #endif
450 break;
451 }
452
453 return ret;
454 }
455
456 int ioctl(int fd, unsigned long int request, ...) {
457 va_list args;
458 void *argp;
459 int i;
460
461 if (!ioctl_func)
462 ioctl_func = (int (*) (int, int, void *)) dlsym (RTLD_NEXT, "ioctl");
463
464 va_start (args, request);
465 argp = va_arg (args, void *);
466 va_end (args);
467
468 for (i = 0; i < windrvrfds_count; i++) {
469 if (fd == windrvrfds[i])
470 return do_wdioctl(fd, request, argp);
471 }
472
473 return (*ioctl_func) (fd, request, argp);
474 }
475
476 int open (const char *pathname, int flags, ...) {
477 static int (*func) (const char *, int, mode_t) = NULL;
478 mode_t mode = 0;
479 va_list args;
480 int fd;
481
482 if (!func)
483 func = (int (*) (const char *, int, mode_t)) dlsym (RTLD_NEXT, "open");
484
485 if (flags & O_CREAT) {
486 va_start(args, flags);
487 mode = va_arg(args, mode_t);
488 va_end(args);
489 }
490
491 if (!strcmp (pathname, "/dev/windrvr6")) {
492 DPRINTF("opening windrvr6 (%d)\n", windrvrfds_count);
493 windrvrfds = realloc(windrvrfds, sizeof(int) * (++windrvrfds_count));
494 if (!windrvrfds)
495 return -ENOMEM;
496
497 #ifdef NO_WINDRVR
498 windrvrfds[windrvrfds_count-1] = fd = (*func) ("/dev/null", flags, mode);
499 #else
500 windrvrfds[windrvrfds_count-1] = fd = (*func) (pathname, flags, mode);
501 #endif
502
503 return fd;
504 }
505
506 return (*func) (pathname, flags, mode);
507 }
508
509 int close(int fd) {
510 static int (*func) (int) = NULL;
511 int i;
512
513 if (!func)
514 func = (int (*) (int)) dlsym(RTLD_NEXT, "close");
515
516 for (i = 0; i < windrvrfds_count; i++) {
517 if (fd == windrvrfds[i] && windrvrfds[i] >= 0) {
518 int remaining = windrvrfds_count - (i + 1);
519 DPRINTF("close windrvr6 (%d)\n", i);
520 if (remaining)
521 memmove(&(windrvrfds[i]), &(windrvrfds[i+1]), remaining * sizeof(int));
522 windrvrfds = realloc(windrvrfds, sizeof(int) * --windrvrfds_count);
523 if (!windrvrfds_count)
524 windrvrfds = NULL;
525 break;
526 }
527 }
528
529 return (*func) (fd);
530 }
531
532 FILE *fopen(const char *path, const char *mode) {
533 FILE *ret;
534 static FILE* (*func) (const char*, const char*) = NULL;
535 char buf[256];
536 int i;
537
538 if (!func)
539 func = (FILE* (*) (const char*, const char*)) dlsym(RTLD_NEXT, "fopen");
540
541 for (i = 0; i < 4; i++) {
542 snprintf(buf, sizeof(buf), "/proc/sys/dev/parport/parport%d/base-addr", i);
543 if (!strcmp(path, buf)) {
544 DPRINTF("open base-addr of parport%d\n", i);
545 if (config_is_real_pport(i)) {
546 ret = (*func) (path, mode);
547 } else {
548 ret = (*func) ("/dev/null", mode);
549 }
550
551 if (ret) {
552 baseaddrfp = ret;
553 baseaddrnum = i;
554 }
555
556 return ret;
557 }
558 }
559
560 ret = (*func) (path, mode);
561
562 if (!strcmp(path, "/proc/modules")) {
563 DPRINTF("opening /proc/modules\n");
564 if (!ret && errno == ENOENT) {
565 /* Hmm.. there appears to be no /proc/modules file
566 * fake it then */
567 ret = (*func)("/dev/null", mode);
568 DPRINTF("No /proc/modules -- faking\n");
569 }
570 #ifdef NO_WINDRVR
571 modulesfp = ret;
572 modules_read = 0;
573 #endif
574 }
575
576 return ret;
577 }
578
579 char *fgets(char *s, int size, FILE *stream) {
580 static char* (*func) (char*, int, FILE*) = NULL;
581 const char modules[][256] = {"windrvr6 1 0 - Live 0xdeadbeef\n", "parport_pc 1 0 - Live 0xdeadbeef\n"};
582 char buf[256];
583 char *ret = NULL;
584
585
586 if (!func)
587 func = (char* (*) (char*, int, FILE*)) dlsym(RTLD_NEXT, "fgets");
588
589 if (modulesfp == stream) {
590 if (modules_read < sizeof(modules) / sizeof(modules[0])) {
591 strcpy(s, modules[modules_read]);
592 ret = s;
593 modules_read++;
594 }
595 } else if (baseaddrfp == stream) {
596 snprintf(s, sizeof(buf), "%d\t%d\n",
597 (baseaddrnum) * 0x10,
598 ((baseaddrnum) * 0x10) + 0x400);
599 ret = s;
600 } else {
601 ret = (*func)(s,size,stream);
602 }
603
604 return ret;
605 }
606
607 int fclose(FILE *fp) {
608 static int (*func) (FILE*) = NULL;
609
610 if (!func)
611 func = (int (*) (FILE*)) dlsym(RTLD_NEXT, "fclose");
612
613 if (fp == modulesfp) {
614 modulesfp = NULL;
615 }
616
617 if (fp == baseaddrfp) {
618 baseaddrfp = NULL;
619 }
620
621 return (*func)(fp);
622 }
623
624 int access(const char *pathname, int mode) {
625 static int (*func) (const char*, int);
626
627 if (!func)
628 func = (int (*) (const char*, int)) dlsym(RTLD_NEXT, "access");
629
630 if (pathname && !strcmp(pathname, "/dev/windrvr6")) {
631 return 0;
632 } else {
633 return (*func)(pathname, mode);
634 }
635 }
636
637 #if 0
638 /* USB cable sharing needs to overload semop, TODO! */
639 int semop (int __semid, struct sembuf *__sops, size_t __nsops) {
640 static int (*func) (int, struct sembuf*, size_t) = NULL;
641 int i;
642
643 if (!func)
644 func = (int (*) (int, struct sembuf*, size_t)) dlsym(RTLD_NEXT, "semop");
645
646 fprintf(stderr,"semop: semid: 0x%X, elements: %d\n", __semid, __nsops);
647 for (i = 0; i < __nsops; i++) {
648 fprintf(stderr, " num: %u, op: %d, flg: %d\n", __sops[i].sem_num, __sops[i].sem_op, __sops[i].sem_flg);
649 if (__sops[i].sem_op < 0) {
650 fprintf(stderr, "SEMAPHORE LOCK\n");
651 } else {
652 fprintf(stderr, "SEMAPHORE UNLOCK\n");
653 }
654 }
655
656 return (*func)(__semid, __sops, __nsops);
657 }
658 #endif
659
660 /*
661 * Ugly hack for ISE 12. They don't seem to open /proc/modules with
662 * open() anymore...
663 * echo '_Z14isModuleLoadedPci' | c++filt
664 */
665 long int _Z14isModuleLoadedPci(char *module_name, int i) {
666 DPRINTF("_Z14isModuleLoadedPci: Checking for module %s (%d)\n", module_name, i);
667
668 return 1;
669 }
670
671 static void __attribute__ ((constructor)) libusbdriver_init(void) {
672 #if __WORDSIZE == 32
673 struct utsname un;
674 int ret;
675
676 ret = uname(&un);
677
678 if (ret == 0 && (!strcmp(un.machine, "x86_64"))) {
679 DPRINTF("setting 32bit personality\n");
680 (long)syscall(SYS_personality, PER_LINUX32);
681 }
682 #endif
683 }
Impressum, Datenschutz