]> git.zerfleddert.de Git - usb-driver/blame_incremental - usb-driver.c
declare variables at the beginning of the scope
[usb-driver] / usb-driver.c
... / ...
CommitLineData
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
50static int (*ioctl_func) (int, int, void *) = NULL;
51static int *windrvrfds = NULL;
52static int windrvrfds_count = 0;
53static unsigned long ppbase = 0;
54static unsigned long ecpbase = 0;
55static struct parport_config *pport = NULL;
56static FILE *modulesfp = NULL;
57static FILE *baseaddrfp = NULL;
58static int baseaddrnum = 0;
59static int modules_read = 0;
60
61#define NO_WINDRVR 1
62
63void 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
76static 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 cr->hCard = 0;
119
120 pport = config_get((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10);
121 if (!pport)
122 break;
123
124 ret = pport->open((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10);
125
126 ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr;
127
128 if (cr->Card.dwItems > 1 && cr->Card.Item[1].I.IO.dwAddr)
129 ecpbase = (unsigned long)cr->Card.Item[1].I.IO.dwAddr;
130
131 if (ret >= 0) {
132 cr->hCard = ret;
133 } else {
134 cr->hCard = 0;
135 }
136#endif
137 DPRINTF("<-hCard: %lu\n", cr->hCard);
138 }
139 break;
140
141 case USB_TRANSFER:
142 DPRINTF("USB_TRANSFER\n");
143 {
144 struct usb_transfer *ut = (struct usb_transfer*)(wdheader->data);
145
146#ifdef DEBUG
147 DPRINTF("-> unique: 0x%lx, pipe: %lu, read: %lu, options: %lx, size: %lu, timeout: %lx\n",
148 ut->dwUniqueID, ut->dwPipeNum, ut->fRead,
149 ut->dwOptions, ut->dwBufferSize, ut->dwTimeout);
150 if (ut->dwPipeNum == 0) {
151 DPRINTF("-> setup packet:");
152 hexdump(ut->SetupPacket, 8, "");
153 }
154
155 if (!ut->fRead && ut->dwBufferSize)
156 {
157 hexdump(ut->pBuffer, ut->dwBufferSize, "->");
158 }
159#endif
160
161#ifndef NO_WINDRVR
162 ret = (*ioctl_func) (fd, request, wdioctl);
163#else
164 ret = xpcu_transfer(ut);
165#endif
166
167#ifdef DEBUG
168 DPRINTF("Transferred: %lu (%s)\n",ut->dwBytesTransferred, (ut->fRead?"read":"write"));
169 if (ut->fRead && ut->dwBytesTransferred)
170 {
171 hexdump(ut->pBuffer, ut->dwBytesTransferred, "<-");
172 }
173#endif
174 }
175 break;
176
177 case INT_ENABLE_OLD:
178 case INT_ENABLE:
179 DPRINTF("INT_ENABLE\n");
180 {
181 struct interrupt *it = (struct interrupt*)(wdheader->data);
182
183 DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
184 it->hInterrupt, it->dwOptions,
185 it->dwCmds, it->fEnableOk, it->dwCounter,
186 it->dwLost, it->fStopped);
187
188#ifndef NO_WINDRVR
189 ret = (*ioctl_func) (fd, request, wdioctl);
190#else
191 ret = xpcu_int_state(it, ENABLE_INTERRUPT);
192#endif
193
194 DPRINTF("<- Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
195 it->hInterrupt, it->dwOptions,
196 it->dwCmds, it->fEnableOk, it->dwCounter,
197 it->dwLost, it->fStopped);
198 }
199
200 break;
201
202 case INT_DISABLE:
203 DPRINTF("INT_DISABLE\n");
204 {
205 struct interrupt *it = (struct interrupt*)(wdheader->data);
206
207 DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
208 it->hInterrupt, it->dwOptions,
209 it->dwCmds, it->fEnableOk, it->dwCounter,
210 it->dwLost, it->fStopped);
211#ifndef NO_WINDRVR
212 ret = (*ioctl_func) (fd, request, wdioctl);
213#else
214 ret = xpcu_int_state(it, DISABLE_INTERRUPT);
215#endif
216 DPRINTF("<- Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
217 it->hInterrupt, it->dwOptions,
218 it->dwCmds, it->fEnableOk, it->dwCounter,
219 it->dwLost, it->fStopped);
220 }
221 break;
222
223 case USB_SET_INTERFACE:
224 DPRINTF("USB_SET_INTERFACE\n");
225 {
226 struct usb_set_interface *usi = (struct usb_set_interface*)(wdheader->data);
227
228 DPRINTF("-> unique: 0x%lx, interfacenum: %lu, alternatesetting: %lu, options: %lx\n",
229 usi->dwUniqueID, usi->dwInterfaceNum,
230 usi->dwAlternateSetting, usi->dwOptions);
231#ifndef NO_WINDRVR
232 ret = (*ioctl_func) (fd, request, wdioctl);
233#else
234 ret = xpcu_set_interface(usi);
235#endif
236 DPRINTF("<- unique: 0x%lx, interfacenum: %lu, alternatesetting: %lu, options: %lx\n",
237 usi->dwUniqueID, usi->dwInterfaceNum,
238 usi->dwAlternateSetting, usi->dwOptions);
239 }
240 break;
241
242 case USB_GET_DEVICE_DATA_OLD:
243 case USB_GET_DEVICE_DATA:
244 DPRINTF("USB_GET_DEVICE_DATA\n");
245 {
246 struct usb_get_device_data *ugdd = (struct usb_get_device_data*)(wdheader->data);
247
248 DPRINTF("-> unique: 0x%lx, bytes: %lu, options: %lx\n",
249 ugdd->dwUniqueID, ugdd->dwBytes,
250 ugdd->dwOptions);
251
252 ret = xpcu_deviceinfo(ugdd);
253
254 }
255 break;
256
257 case EVENT_REGISTER_OLD:
258 case EVENT_REGISTER:
259 DPRINTF("EVENT_REGISTER\n");
260 {
261 struct event *e = (struct event*)(wdheader->data);
262#ifdef DEBUG
263 int i;
264#endif
265
266 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",
267 e->handle, e->dwAction,
268 e->dwStatus, e->dwEventId, e->dwCardType,
269 e->hKernelPlugIn, e->dwOptions,
270 e->u.Usb.deviceId.dwVendorId,
271 e->u.Usb.deviceId.dwProductId,
272 e->u.Usb.dwUniqueID, e->dwEventVer,
273 e->dwNumMatchTables);
274
275#ifndef NO_WINDRVR
276 ret = (*ioctl_func) (fd, request, wdioctl);
277#else
278 ret = xpcu_find(e);
279#endif
280
281#ifdef DEBUG
282 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",
283 e->handle, e->dwAction,
284 e->dwStatus, e->dwEventId, e->dwCardType,
285 e->hKernelPlugIn, e->dwOptions,
286 e->u.Usb.deviceId.dwVendorId,
287 e->u.Usb.deviceId.dwProductId,
288 e->u.Usb.dwUniqueID, e->dwEventVer,
289 e->dwNumMatchTables);
290
291 for (i = 0; i < e->dwNumMatchTables; i++)
292 DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
293 e->matchTables[i].VendorId,
294 e->matchTables[i].ProductId,
295 e->matchTables[i].bDeviceClass,
296 e->matchTables[i].bDeviceSubClass,
297 e->matchTables[i].bInterfaceClass,
298 e->matchTables[i].bInterfaceSubClass,
299 e->matchTables[i].bInterfaceProtocol);
300#endif
301 }
302 break;
303
304 case TRANSFER_OLD:
305 case TRANSFER:
306 DPRINTF("TRANSFER\n");
307 {
308 WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);
309
310#ifndef NO_WINDRVR
311 ret = (*ioctl_func) (fd, request, wdioctl);
312#else
313 ret = pport->transfer(tr, fd, request, ppbase, ecpbase, 1);
314#endif
315 }
316 break;
317
318 case MULTI_TRANSFER_OLD:
319 case MULTI_TRANSFER:
320 DPRINTF("MULTI_TRANSFER\n");
321 {
322 WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);
323 unsigned long num = wdheader->size/sizeof(WD_TRANSFER);
324#ifndef NO_WINDRVR
325 ret = (*ioctl_func) (fd, request, wdioctl);
326#else
327 ret = pport->transfer(tr, fd, request, ppbase, ecpbase, num);
328#endif
329 }
330 break;
331
332 case EVENT_UNREGISTER:
333 {
334 struct event *e = (struct event*)(wdheader->data);
335
336 DPRINTF("EVENT_UNREGISTER\n");
337#ifndef NO_WINDRVR
338 ret = (*ioctl_func) (fd, request, wdioctl);
339#else
340 ret = xpcu_close(e);
341#endif
342 }
343 break;
344
345 case INT_WAIT:
346 DPRINTF("INT_WAIT\n");
347 {
348 struct interrupt *it = (struct interrupt*)(wdheader->data);
349
350 DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
351 it->hInterrupt, it->dwOptions,
352 it->dwCmds, it->fEnableOk, it->dwCounter,
353 it->dwLost, it->fStopped);
354
355#ifndef NO_WINDRVR
356 ret = (*ioctl_func) (fd, request, wdioctl);
357#else
358 ret = xpcu_int_wait(it);
359#endif
360
361 DPRINTF("<- INT_WAIT_RETURN: Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
362 it->hInterrupt, it->dwOptions, it->dwCmds,
363 it->fEnableOk, it->dwCounter, it->dwLost,
364 it->fStopped);
365 }
366 break;
367
368 case CARD_UNREGISTER:
369 DPRINTF("CARD_UNREGISTER\n");
370 {
371 struct card_register* cr = (struct card_register*)(wdheader->data);
372
373 DPRINTF("-> Addr: 0x%lx, bytes: %lu, bar: %lu\n",
374 (unsigned long)cr->Card.Item[0].I.IO.dwAddr,
375 cr->Card.Item[0].I.IO.dwBytes,
376 cr->Card.Item[0].I.IO.dwBar);
377
378 DPRINTF("-> hCard: %lu\n", cr->hCard);
379
380#ifndef NO_WINDRVR
381 ret = (*ioctl_func) (fd, request, wdioctl);
382#else
383 if (pport)
384 pport->close(cr->hCard);
385
386 pport = NULL;
387#endif
388 }
389 break;
390
391 case EVENT_PULL:
392 DPRINTF("EVENT_PULL\n");
393 {
394 struct event *e = (struct event*)(wdheader->data);
395#ifdef DEBUG
396 int i;
397
398 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",
399 e->handle, e->dwAction, e->dwStatus,
400 e->dwEventId, e->dwCardType, e->hKernelPlugIn,
401 e->dwOptions, e->u.Usb.deviceId.dwVendorId,
402 e->u.Usb.deviceId.dwProductId,
403 e->u.Usb.dwUniqueID, e->dwEventVer,
404 e->dwNumMatchTables);
405
406 for (i = 0; i < e->dwNumMatchTables; i++)
407 DPRINTF("-> match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
408 e->matchTables[i].VendorId,
409 e->matchTables[i].ProductId,
410 e->matchTables[i].bDeviceClass,
411 e->matchTables[i].bDeviceSubClass,
412 e->matchTables[i].bInterfaceClass,
413 e->matchTables[i].bInterfaceSubClass,
414 e->matchTables[i].bInterfaceProtocol);
415#endif
416
417#ifndef NO_WINDRVR
418 ret = (*ioctl_func) (fd, request, wdioctl);
419#else
420 ret = xpcu_found(e);
421#endif
422
423#ifdef DEBUG
424 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",
425 e->handle, e->dwAction, e->dwStatus,
426 e->dwEventId, e->dwCardType, e->hKernelPlugIn,
427 e->dwOptions, e->u.Usb.deviceId.dwVendorId,
428 e->u.Usb.deviceId.dwProductId,
429 e->u.Usb.dwUniqueID, e->dwEventVer,
430 e->dwNumMatchTables);
431
432 for (i = 0; i < e->dwNumMatchTables; i++)
433 DPRINTF("<- match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
434 e->matchTables[i].VendorId,
435 e->matchTables[i].ProductId,
436 e->matchTables[i].bDeviceClass,
437 e->matchTables[i].bDeviceSubClass,
438 e->matchTables[i].bInterfaceClass,
439 e->matchTables[i].bInterfaceSubClass,
440 e->matchTables[i].bInterfaceProtocol);
441#endif
442
443 }
444 break;
445
446 default:
447 fprintf(stderr,"!!!Unsupported IOCTL: %x!!!\n", request);
448#ifndef NO_WINDRVR
449 ret = (*ioctl_func) (fd, request, wdioctl);
450#endif
451 break;
452 }
453
454 return ret;
455}
456
457int ioctl(int fd, unsigned long int request, ...) {
458 va_list args;
459 void *argp;
460 int i;
461
462 if (!ioctl_func)
463 ioctl_func = (int (*) (int, int, void *)) dlsym (RTLD_NEXT, "ioctl");
464
465 va_start (args, request);
466 argp = va_arg (args, void *);
467 va_end (args);
468
469 for (i = 0; i < windrvrfds_count; i++) {
470 if (fd == windrvrfds[i])
471 return do_wdioctl(fd, request, argp);
472 }
473
474 return (*ioctl_func) (fd, request, argp);
475}
476
477int open (const char *pathname, int flags, ...) {
478 static int (*func) (const char *, int, mode_t) = NULL;
479 mode_t mode = 0;
480 va_list args;
481 int fd;
482
483 if (!func)
484 func = (int (*) (const char *, int, mode_t)) dlsym (RTLD_NEXT, "open");
485
486 if (flags & O_CREAT) {
487 va_start(args, flags);
488 mode = va_arg(args, mode_t);
489 va_end(args);
490 }
491
492 if (!strcmp (pathname, "/dev/windrvr6")) {
493 DPRINTF("opening windrvr6 (%d)\n", windrvrfds_count);
494 windrvrfds = realloc(windrvrfds, sizeof(int) * (++windrvrfds_count));
495 if (!windrvrfds)
496 return -ENOMEM;
497
498#ifdef NO_WINDRVR
499 windrvrfds[windrvrfds_count-1] = fd = (*func) ("/dev/null", flags, mode);
500#else
501 windrvrfds[windrvrfds_count-1] = fd = (*func) (pathname, flags, mode);
502#endif
503
504 return fd;
505 }
506
507 return (*func) (pathname, flags, mode);
508}
509
510int close(int fd) {
511 static int (*func) (int) = NULL;
512 int i;
513
514 if (!func)
515 func = (int (*) (int)) dlsym(RTLD_NEXT, "close");
516
517 for (i = 0; i < windrvrfds_count; i++) {
518 if (fd == windrvrfds[i] && windrvrfds[i] >= 0) {
519 int remaining = windrvrfds_count - (i + 1);
520 DPRINTF("close windrvr6 (%d)\n", i);
521 if (remaining)
522 memmove(&(windrvrfds[i]), &(windrvrfds[i+1]), remaining * sizeof(int));
523 windrvrfds = realloc(windrvrfds, sizeof(int) * --windrvrfds_count);
524 if (!windrvrfds_count)
525 windrvrfds = NULL;
526 break;
527 }
528 }
529
530 return (*func) (fd);
531}
532
533FILE *fopen(const char *path, const char *mode) {
534 FILE *ret;
535 static FILE* (*func) (const char*, const char*) = NULL;
536 char buf[256];
537 int i;
538
539 if (!func)
540 func = (FILE* (*) (const char*, const char*)) dlsym(RTLD_NEXT, "fopen");
541
542 for (i = 0; i < 4; i++) {
543 snprintf(buf, sizeof(buf), "/proc/sys/dev/parport/parport%d/base-addr", i);
544 if (!strcmp(path, buf)) {
545 DPRINTF("open base-addr of parport%d\n", i);
546 if (config_is_real_pport(i)) {
547 ret = (*func) (path, mode);
548 } else {
549 ret = (*func) ("/dev/null", mode);
550 }
551
552 if (ret) {
553 baseaddrfp = ret;
554 baseaddrnum = i;
555 }
556
557 return ret;
558 }
559 }
560
561 ret = (*func) (path, mode);
562
563 if (!strcmp(path, "/proc/modules")) {
564 DPRINTF("opening /proc/modules\n");
565 if (!ret && errno == ENOENT) {
566 /* Hmm.. there appears to be no /proc/modules file
567 * fake it then */
568 ret = (*func)("/dev/null", mode);
569 DPRINTF("No /proc/modules -- faking\n");
570 }
571#ifdef NO_WINDRVR
572 modulesfp = ret;
573 modules_read = 0;
574#endif
575 }
576
577 return ret;
578}
579
580char *fgets(char *s, int size, FILE *stream) {
581 static char* (*func) (char*, int, FILE*) = NULL;
582 const char modules[][256] = {"windrvr6 1 0 - Live 0xdeadbeef\n", "parport_pc 1 0 - Live 0xdeadbeef\n"};
583 char buf[256];
584 char *ret = NULL;
585
586
587 if (!func)
588 func = (char* (*) (char*, int, FILE*)) dlsym(RTLD_NEXT, "fgets");
589
590 if (modulesfp == stream) {
591 if (modules_read < sizeof(modules) / sizeof(modules[0])) {
592 strcpy(s, modules[modules_read]);
593 ret = s;
594 modules_read++;
595 }
596 } else if (baseaddrfp == stream) {
597 snprintf(s, sizeof(buf), "%d\t%d\n",
598 (baseaddrnum) * 0x10,
599 ((baseaddrnum) * 0x10) + 0x400);
600 ret = s;
601 } else {
602 ret = (*func)(s,size,stream);
603 }
604
605 return ret;
606}
607
608int fclose(FILE *fp) {
609 static int (*func) (FILE*) = NULL;
610
611 if (!func)
612 func = (int (*) (FILE*)) dlsym(RTLD_NEXT, "fclose");
613
614 if (fp == modulesfp) {
615 modulesfp = NULL;
616 }
617
618 if (fp == baseaddrfp) {
619 baseaddrfp = NULL;
620 }
621
622 return (*func)(fp);
623}
624
625int access(const char *pathname, int mode) {
626 static int (*func) (const char*, int);
627
628 if (!func)
629 func = (int (*) (const char*, int)) dlsym(RTLD_NEXT, "access");
630
631 if (pathname && !strcmp(pathname, "/dev/windrvr6")) {
632 return 0;
633 } else {
634 return (*func)(pathname, mode);
635 }
636}
637
638#if 0
639/* USB cable sharing needs to overload semop, TODO! */
640int semop (int __semid, struct sembuf *__sops, size_t __nsops) {
641 static int (*func) (int, struct sembuf*, size_t) = NULL;
642 int i;
643
644 if (!func)
645 func = (int (*) (int, struct sembuf*, size_t)) dlsym(RTLD_NEXT, "semop");
646
647 fprintf(stderr,"semop: semid: 0x%X, elements: %d\n", __semid, __nsops);
648 for (i = 0; i < __nsops; i++) {
649 fprintf(stderr, " num: %u, op: %d, flg: %d\n", __sops[i].sem_num, __sops[i].sem_op, __sops[i].sem_flg);
650 if (__sops[i].sem_op < 0) {
651 fprintf(stderr, "SEMAPHORE LOCK\n");
652 } else {
653 fprintf(stderr, "SEMAPHORE UNLOCK\n");
654 }
655 }
656
657 return (*func)(__semid, __sops, __nsops);
658}
659#endif
660
661/*
662 * Ugly hack for ISE 12. Preload doesn't seem to work correctly for
663 * libImpactComm.so. Even though the file is still read with fopen(),
664 * the version from libc is used and not the one from this file.
665 * Replace the function calling fopen() instead...
666 * echo '_Z14isModuleLoadedPci' | c++filt
667 */
668long int _Z14isModuleLoadedPci(char *module_name, int i) {
669 DPRINTF("_Z14isModuleLoadedPci: Checking for module %s (%d)\n", module_name, i);
670
671 return 1;
672}
673
674static void __attribute__ ((constructor)) libusbdriver_init(void) {
675 int i;
676 char buf[256];
677 char buf2[256];
678
679 for (i = 0; i < 4; i++) {
680 snprintf(buf, sizeof(buf), "XIL_IMPACT_ENV_LPT%d_BASE_ADDRESS", i+1);
681 snprintf(buf2, sizeof(buf2), "%x", 0x10*i);
682 setenv(buf, buf2, 1);
683 snprintf(buf, sizeof(buf), "XIL_IMPACT_ENV_LPT%d_ECP_ADDRESS", i+1);
684 snprintf(buf2, sizeof(buf2), "%x", (0x10*i)+0x400);
685 setenv(buf, buf2, 1);
686 }
687
688 setenv("XIL_IMPACT_USE_LIBUSB", "0", 1);
689 setenv("XIL_IMPACT_USE_WINDRIVER", "1", 1);
690
691 #if __WORDSIZE == 32
692 {
693 struct utsname un;
694 int ret;
695
696 ret = uname(&un);
697
698 if (ret == 0 && (!strcmp(un.machine, "x86_64"))) {
699 DPRINTF("setting 32bit personality\n");
700 (long)syscall(SYS_personality, PER_LINUX32);
701 }
702 }
703 #endif
704}
Impressum, Datenschutz