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