]> git.zerfleddert.de Git - usb-driver/blame - usb-driver.c
Overload XilCommNS::CPortResources::Instance
[usb-driver] / usb-driver.c
CommitLineData
54357994 1/* libusb/ppdev connector for XILINX impact
f1405f13 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 */
cdc711dc 23
24#define _GNU_SOURCE 1
25
cdc711dc 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>
2a7af812 36#include <signal.h>
9ba1e383 37#include <errno.h>
11d01742 38#include <inttypes.h>
54357994 39#include <sys/ioctl.h>
c42237a3
MG
40#include <sys/utsname.h>
41#include <bits/wordsize.h>
1fc8f7a4
MG
42#include <sys/ipc.h>
43#include <sys/sem.h>
daa4fc04
MG
44#include <syscall.h>
45#include <linux/personality.h>
2c0c1255 46#include "usb-driver.h"
3e670223 47#include "config.h"
cbfa0ac6 48#include "xpcu.h"
cdc711dc 49
9c9fd67c 50static int (*ioctl_func) (int, int, void *) = NULL;
9bfaca62
MG
51static int *windrvrfds = NULL;
52static int windrvrfds_count = 0;
54357994 53static unsigned long ppbase = 0;
54static unsigned long ecpbase = 0;
25ba7a49 55static struct parport_config *pport = NULL;
be59993b
MG
56static FILE *modulesfp = NULL;
57static FILE *baseaddrfp = NULL;
58static int baseaddrnum = 0;
723d9aa0 59static int modules_read = 0;
292160ed 60
795992ad 61#define NO_WINDRVR 1
723d9aa0 62
325556c9 63void hexdump(unsigned char *buf, int len, char *prefix) {
765c485a 64 int i = 0;
723d9aa0 65
765c485a
MG
66 fprintf(stderr, "%s %03x: ", prefix, i);
67 for(i = 0; i<len; i++) {
723d9aa0 68 fprintf(stderr,"%02x ", buf[i]);
765c485a
MG
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);
723d9aa0 73 }
f1405f13 74 fprintf(stderr,"\n");
723d9aa0 75}
cdc711dc 76
cf55ed64 77
be59993b 78static int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) {
cdc711dc 79 struct header_struct* wdheader = (struct header_struct*)wdioctl;
9c9fd67c 80 struct version_struct *version;
81 int ret = 0;
cdc711dc 82
da3ba95a 83 if (wdheader->magic != MAGIC) {
2c2119eb 84 fprintf(stderr,"!!!ERROR: magic header does not match!!!\n");
85 return (*ioctl_func) (fd, request, wdioctl);
cdc711dc 86 }
87
bdc65937 88 switch(request & ~(0xc0000000)) {
da3ba95a 89 case VERSION:
9c9fd67c 90 version = (struct version_struct*)(wdheader->data);
81cf3658 91 strcpy(version->version, "libusb-driver.so version: " USB_DRIVER_VERSION);
90831fba 92 version->versionul = 802;
f1405f13 93 DPRINTF("VERSION\n");
cdc711dc 94 break;
2c2119eb 95
96 case LICENSE:
f1405f13 97 DPRINTF("LICENSE\n");
2c2119eb 98 break;
99
f152c048 100 case CARD_REGISTER_OLD:
9c9fd67c 101 case CARD_REGISTER:
54357994 102 DPRINTF("CARD_REGISTER\n");
9c9fd67c 103 {
533f4b68 104 struct card_register* cr = (struct card_register*)(wdheader->data);
54357994 105
501f1c21 106 DPRINTF("-> Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n",
54357994 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
501f1c21 112 DPRINTF("-> Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n",
54357994 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);
576995a8 117#ifndef NO_WINDRVR
118 ret = (*ioctl_func) (fd, request, wdioctl);
ac9e3f59 119#else
4c90fa39 120 cr->hCard = 0;
bccac33b 121
25ba7a49 122 pport = config_get((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10);
61e0de7a 123 if (!pport)
124 break;
125
25ba7a49 126 ret = pport->open((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10);
3e670223 127
5e3d963b 128 ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr;
bccac33b 129
5e3d963b 130 if (cr->Card.dwItems > 1 && cr->Card.Item[1].I.IO.dwAddr)
131 ecpbase = (unsigned long)cr->Card.Item[1].I.IO.dwAddr;
19b2e286 132
5e3d963b 133 if (ret >= 0) {
134 cr->hCard = ret;
135 } else {
19b2e286 136 cr->hCard = 0;
5e3d963b 137 }
576995a8 138#endif
501f1c21 139 DPRINTF("<-hCard: %lu\n", cr->hCard);
9c9fd67c 140 }
da3ba95a 141 break;
2c2119eb 142
da3ba95a 143 case USB_TRANSFER:
501f1c21 144 DPRINTF("USB_TRANSFER\n");
da3ba95a 145 {
146 struct usb_transfer *ut = (struct usb_transfer*)(wdheader->data);
147
723d9aa0 148#ifdef DEBUG
501f1c21 149 DPRINTF("-> unique: 0x%lx, pipe: %lu, read: %lu, options: %lx, size: %lu, timeout: %lx\n",
f1405f13 150 ut->dwUniqueID, ut->dwPipeNum, ut->fRead,
151 ut->dwOptions, ut->dwBufferSize, ut->dwTimeout);
cf55ed64 152 if (ut->dwPipeNum == 0) {
325556c9
MG
153 DPRINTF("-> setup packet:");
154 hexdump(ut->SetupPacket, 8, "");
cf55ed64 155 }
723d9aa0 156
9c9fd67c 157 if (!ut->fRead && ut->dwBufferSize)
158 {
325556c9 159 hexdump(ut->pBuffer, ut->dwBufferSize, "->");
9c9fd67c 160 }
723d9aa0 161#endif
9c9fd67c 162
795992ad 163#ifndef NO_WINDRVR
9c9fd67c 164 ret = (*ioctl_func) (fd, request, wdioctl);
411af373 165#else
19acdb82 166 ret = xpcu_transfer(ut);
292160ed 167#endif
9c9fd67c 168
723d9aa0 169#ifdef DEBUG
f1405f13 170 DPRINTF("Transferred: %lu (%s)\n",ut->dwBytesTransferred, (ut->fRead?"read":"write"));
9c9fd67c 171 if (ut->fRead && ut->dwBytesTransferred)
172 {
325556c9 173 hexdump(ut->pBuffer, ut->dwBytesTransferred, "<-");
9c9fd67c 174 }
723d9aa0 175#endif
da3ba95a 176 }
cdc711dc 177 break;
2c2119eb 178
f152c048 179 case INT_ENABLE_OLD:
da3ba95a 180 case INT_ENABLE:
f1405f13 181 DPRINTF("INT_ENABLE\n");
da3ba95a 182 {
9c9fd67c 183 struct interrupt *it = (struct interrupt*)(wdheader->data);
cdc711dc 184
501f1c21 185 DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
f1405f13 186 it->hInterrupt, it->dwOptions,
187 it->dwCmds, it->fEnableOk, it->dwCounter,
188 it->dwLost, it->fStopped);
cdc711dc 189
501f1c21
MG
190#ifndef NO_WINDRVR
191 ret = (*ioctl_func) (fd, request, wdioctl);
192#else
19acdb82 193 ret = xpcu_int_state(it, ENABLE_INTERRUPT);
501f1c21
MG
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);
9c9fd67c 200 }
cdc711dc 201
cdc711dc 202 break;
9c9fd67c 203
da3ba95a 204 case INT_DISABLE:
f1405f13 205 DPRINTF("INT_DISABLE\n");
da3ba95a 206 {
9c9fd67c 207 struct interrupt *it = (struct interrupt*)(wdheader->data);
da3ba95a 208
501f1c21 209 DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
f1405f13 210 it->hInterrupt, it->dwOptions,
211 it->dwCmds, it->fEnableOk, it->dwCounter,
212 it->dwLost, it->fStopped);
795992ad 213#ifndef NO_WINDRVR
9c9fd67c 214 ret = (*ioctl_func) (fd, request, wdioctl);
e71b6bf3 215#else
19acdb82 216 ret = xpcu_int_state(it, DISABLE_INTERRUPT);
292160ed 217#endif
501f1c21 218 DPRINTF("<- Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
f1405f13 219 it->hInterrupt, it->dwOptions,
220 it->dwCmds, it->fEnableOk, it->dwCounter,
221 it->dwLost, it->fStopped);
da3ba95a 222 }
da3ba95a 223 break;
da3ba95a 224
9c9fd67c 225 case USB_SET_INTERFACE:
f1405f13 226 DPRINTF("USB_SET_INTERFACE\n");
da3ba95a 227 {
9c9fd67c 228 struct usb_set_interface *usi = (struct usb_set_interface*)(wdheader->data);
229
501f1c21 230 DPRINTF("-> unique: 0x%lx, interfacenum: %lu, alternatesetting: %lu, options: %lx\n",
f1405f13 231 usi->dwUniqueID, usi->dwInterfaceNum,
232 usi->dwAlternateSetting, usi->dwOptions);
795992ad 233#ifndef NO_WINDRVR
9c9fd67c 234 ret = (*ioctl_func) (fd, request, wdioctl);
2a7af812 235#else
19acdb82 236 ret = xpcu_set_interface(usi);
292160ed 237#endif
501f1c21 238 DPRINTF("<- unique: 0x%lx, interfacenum: %lu, alternatesetting: %lu, options: %lx\n",
f1405f13 239 usi->dwUniqueID, usi->dwInterfaceNum,
240 usi->dwAlternateSetting, usi->dwOptions);
da3ba95a 241 }
cdc711dc 242 break;
da3ba95a 243
f152c048 244 case USB_GET_DEVICE_DATA_OLD:
9c9fd67c 245 case USB_GET_DEVICE_DATA:
f1405f13 246 DPRINTF("USB_GET_DEVICE_DATA\n");
9c9fd67c 247 {
248 struct usb_get_device_data *ugdd = (struct usb_get_device_data*)(wdheader->data);
9c9fd67c 249
501f1c21 250 DPRINTF("-> unique: 0x%lx, bytes: %lu, options: %lx\n",
f1405f13 251 ugdd->dwUniqueID, ugdd->dwBytes,
252 ugdd->dwOptions);
253
19acdb82 254 ret = xpcu_deviceinfo(ugdd);
f92c0fbc 255
da3ba95a 256 }
9c9fd67c 257 break;
258
f152c048 259 case EVENT_REGISTER_OLD:
b0f621dd 260 case EVENT_REGISTER:
f1405f13 261 DPRINTF("EVENT_REGISTER\n");
b0f621dd 262 {
263 struct event *e = (struct event*)(wdheader->data);
f92c0fbc 264#ifdef DEBUG
b0f621dd 265 int i;
f92c0fbc 266#endif
b0f621dd 267
501f1c21 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",
f1405f13 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
795992ad 277#ifndef NO_WINDRVR
b0f621dd 278 ret = (*ioctl_func) (fd, request, wdioctl);
2a7af812 279#else
19acdb82 280 ret = xpcu_find(e);
292160ed 281#endif
b0f621dd 282
723d9aa0 283#ifdef DEBUG
501f1c21 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",
f1405f13 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
b0f621dd 293 for (i = 0; i < e->dwNumMatchTables; i++)
f1405f13 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);
723d9aa0 302#endif
b0f621dd 303 }
304 break;
305
f152c048 306 case TRANSFER_OLD:
da3ba95a 307 case TRANSFER:
f1405f13 308 DPRINTF("TRANSFER\n");
ac9e3f59 309 {
310 WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);
311
1dac5195 312#ifndef NO_WINDRVR
313 ret = (*ioctl_func) (fd, request, wdioctl);
314#else
25ba7a49 315 ret = pport->transfer(tr, fd, request, ppbase, ecpbase, 1);
1dac5195 316#endif
ac9e3f59 317 }
9c9fd67c 318 break;
319
54357994 320 case MULTI_TRANSFER_OLD:
576995a8 321 case MULTI_TRANSFER:
322 DPRINTF("MULTI_TRANSFER\n");
ac9e3f59 323 {
324 WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);
325 unsigned long num = wdheader->size/sizeof(WD_TRANSFER);
1dac5195 326#ifndef NO_WINDRVR
327 ret = (*ioctl_func) (fd, request, wdioctl);
328#else
25ba7a49 329 ret = pport->transfer(tr, fd, request, ppbase, ecpbase, num);
ac9e3f59 330#endif
ac9e3f59 331 }
576995a8 332 break;
333
da3ba95a 334 case EVENT_UNREGISTER:
f92c0fbc
MG
335 {
336 struct event *e = (struct event*)(wdheader->data);
337
338 DPRINTF("EVENT_UNREGISTER\n");
795992ad 339#ifndef NO_WINDRVR
f92c0fbc
MG
340 ret = (*ioctl_func) (fd, request, wdioctl);
341#else
19acdb82 342 ret = xpcu_close(e);
292160ed 343#endif
f92c0fbc 344 }
9c9fd67c 345 break;
346
da3ba95a 347 case INT_WAIT:
f1405f13 348 DPRINTF("INT_WAIT\n");
b0f621dd 349 {
350 struct interrupt *it = (struct interrupt*)(wdheader->data);
351
501f1c21 352 DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
f1405f13 353 it->hInterrupt, it->dwOptions,
354 it->dwCmds, it->fEnableOk, it->dwCounter,
355 it->dwLost, it->fStopped);
b0f621dd 356
795992ad 357#ifndef NO_WINDRVR
b0f621dd 358 ret = (*ioctl_func) (fd, request, wdioctl);
292160ed 359#else
19acdb82 360 ret = xpcu_int_wait(it);
292160ed 361#endif
362
501f1c21 363 DPRINTF("<- INT_WAIT_RETURN: Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
f1405f13 364 it->hInterrupt, it->dwOptions, it->dwCmds,
365 it->fEnableOk, it->dwCounter, it->dwLost,
366 it->fStopped);
b0f621dd 367 }
9c9fd67c 368 break;
369
da3ba95a 370 case CARD_UNREGISTER:
f1405f13 371 DPRINTF("CARD_UNREGISTER\n");
54357994 372 {
373 struct card_register* cr = (struct card_register*)(wdheader->data);
374
501f1c21 375 DPRINTF("-> Addr: 0x%lx, bytes: %lu, bar: %lu\n",
54357994 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
501f1c21 380 DPRINTF("-> hCard: %lu\n", cr->hCard);
54357994 381
795992ad 382#ifndef NO_WINDRVR
54357994 383 ret = (*ioctl_func) (fd, request, wdioctl);
384#else
72ce448b
MG
385 if (pport)
386 pport->close(cr->hCard);
387
388 pport = NULL;
292160ed 389#endif
54357994 390 }
9c9fd67c 391 break;
392
da3ba95a 393 case EVENT_PULL:
f1405f13 394 DPRINTF("EVENT_PULL\n");
b1831983 395 {
396 struct event *e = (struct event*)(wdheader->data);
723d9aa0 397#ifdef DEBUG
b1831983 398 int i;
399
501f1c21 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",
f1405f13 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
b1831983 408 for (i = 0; i < e->dwNumMatchTables; i++)
501f1c21 409 DPRINTF("-> match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
f1405f13 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);
723d9aa0 417#endif
b1831983 418
795992ad 419#ifndef NO_WINDRVR
b1831983 420 ret = (*ioctl_func) (fd, request, wdioctl);
292160ed 421#else
19acdb82 422 ret = xpcu_found(e);
292160ed 423#endif
b1831983 424
723d9aa0 425#ifdef DEBUG
501f1c21 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",
f1405f13 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
b1831983 434 for (i = 0; i < e->dwNumMatchTables; i++)
501f1c21 435 DPRINTF("<- match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
f1405f13 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);
723d9aa0 443#endif
ca18111b 444
b1831983 445 }
9c9fd67c 446 break;
447
da3ba95a 448 default:
292160ed 449 fprintf(stderr,"!!!Unsupported IOCTL: %x!!!\n", request);
795992ad 450#ifndef NO_WINDRVR
9c9fd67c 451 ret = (*ioctl_func) (fd, request, wdioctl);
292160ed 452#endif
453 break;
cdc711dc 454 }
da3ba95a 455
9c9fd67c 456 return ret;
cdc711dc 457}
458
54357994 459int ioctl(int fd, unsigned long int request, ...) {
dbda1264 460 va_list args;
461 void *argp;
9bfaca62 462 int i;
dbda1264 463
464 if (!ioctl_func)
f1405f13 465 ioctl_func = (int (*) (int, int, void *)) dlsym (RTLD_NEXT, "ioctl");
dbda1264 466
467 va_start (args, request);
468 argp = va_arg (args, void *);
469 va_end (args);
470
9bfaca62
MG
471 for (i = 0; i < windrvrfds_count; i++) {
472 if (fd == windrvrfds[i])
473 return do_wdioctl(fd, request, argp);
474 }
dbda1264 475
9bfaca62 476 return (*ioctl_func) (fd, request, argp);
dbda1264 477}
cdc711dc 478
be452175 479int open (const char *pathname, int flags, ...) {
480 static int (*func) (const char *, int, mode_t) = NULL;
cdc711dc 481 mode_t mode = 0;
482 va_list args;
483 int fd;
484
485 if (!func)
f1405f13 486 func = (int (*) (const char *, int, mode_t)) dlsym (RTLD_NEXT, "open");
cdc711dc 487
488 if (flags & O_CREAT) {
489 va_start(args, flags);
490 mode = va_arg(args, mode_t);
491 va_end(args);
492 }
493
cdc711dc 494 if (!strcmp (pathname, "/dev/windrvr6")) {
9bfaca62
MG
495 DPRINTF("opening windrvr6 (%d)\n", windrvrfds_count);
496 windrvrfds = realloc(windrvrfds, sizeof(int) * (++windrvrfds_count));
497 if (!windrvrfds)
498 return -ENOMEM;
499
795992ad 500#ifdef NO_WINDRVR
9bfaca62 501 windrvrfds[windrvrfds_count-1] = fd = (*func) ("/dev/null", flags, mode);
01b99d52 502#else
9bfaca62 503 windrvrfds[windrvrfds_count-1] = fd = (*func) (pathname, flags, mode);
01b99d52 504#endif
723d9aa0 505
506 return fd;
cdc711dc 507 }
508
723d9aa0 509 return (*func) (pathname, flags, mode);
cdc711dc 510}
511
723d9aa0 512int close(int fd) {
513 static int (*func) (int) = NULL;
9bfaca62 514 int i;
cdc711dc 515
723d9aa0 516 if (!func)
f1405f13 517 func = (int (*) (int)) dlsym(RTLD_NEXT, "close");
723d9aa0 518
9bfaca62
MG
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 }
cdc711dc 530 }
cdc711dc 531
723d9aa0 532 return (*func) (fd);
cdc711dc 533}
534
723d9aa0 535FILE *fopen(const char *path, const char *mode) {
536 FILE *ret;
537 static FILE* (*func) (const char*, const char*) = NULL;
0dca330e 538 char buf[256];
539 int i;
ca18111b 540
541 if (!func)
f1405f13 542 func = (FILE* (*) (const char*, const char*)) dlsym(RTLD_NEXT, "fopen");
ca18111b 543
3e670223 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);
ca18111b 564
0dca330e 565 if (!strcmp(path, "/proc/modules")) {
f1405f13 566 DPRINTF("opening /proc/modules\n");
aed36bb3
MG
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 }
723d9aa0 573#ifdef NO_WINDRVR
dbda1264 574 modulesfp = ret;
723d9aa0 575 modules_read = 0;
576#endif
577 }
cdc711dc 578
579 return ret;
580}
581
dbda1264 582char *fgets(char *s, int size, FILE *stream) {
583 static char* (*func) (char*, int, FILE*) = NULL;
16f6b164 584 const char modules[][256] = {"windrvr6 1 0 - Live 0xdeadbeef\n", "parport_pc 1 0 - Live 0xdeadbeef\n"};
0dca330e 585 char buf[256];
dbda1264 586 char *ret = NULL;
587
cdc711dc 588
589 if (!func)
f1405f13 590 func = (char* (*) (char*, int, FILE*)) dlsym(RTLD_NEXT, "fgets");
723d9aa0 591
dbda1264 592 if (modulesfp == stream) {
54357994 593 if (modules_read < sizeof(modules) / sizeof(modules[0])) {
16f6b164 594 strcpy(s, modules[modules_read]);
dbda1264 595 ret = s;
16f6b164 596 modules_read++;
dbda1264 597 }
0dca330e 598 } else if (baseaddrfp == stream) {
599 snprintf(s, sizeof(buf), "%d\t%d\n",
600 (baseaddrnum) * 0x10,
601 ((baseaddrnum) * 0x10) + 0x400);
602 ret = s;
723d9aa0 603 } else {
dbda1264 604 ret = (*func)(s,size,stream);
723d9aa0 605 }
cdc711dc 606
607 return ret;
608}
609
dbda1264 610int fclose(FILE *fp) {
611 static int (*func) (FILE*) = NULL;
cdc711dc 612
dbda1264 613 if (!func)
f1405f13 614 func = (int (*) (FILE*)) dlsym(RTLD_NEXT, "fclose");
cdc711dc 615
dbda1264 616 if (fp == modulesfp) {
617 modulesfp = NULL;
618 }
0dca330e 619
620 if (fp == baseaddrfp) {
621 baseaddrfp = NULL;
622 }
dbda1264 623
624 return (*func)(fp);
cdc711dc 625}
419f2c98 626
627int access(const char *pathname, int mode) {
628 static int (*func) (const char*, int);
629
630 if (!func)
f1405f13 631 func = (int (*) (const char*, int)) dlsym(RTLD_NEXT, "access");
3eee002c 632
b8b756f5 633 if (pathname && !strcmp(pathname, "/dev/windrvr6")) {
419f2c98 634 return 0;
635 } else {
636 return (*func)(pathname, mode);
637 }
638}
c42237a3 639
1fc8f7a4
MG
640#if 0
641/* USB cable sharing needs to overload semop, TODO! */
642int 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
9f78065e 663/*
b05f6dfe
MG
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...
9f78065e
MG
668 * echo '_Z14isModuleLoadedPci' | c++filt
669 */
80a14787 670long int _Z14isModuleLoadedPci(char *module_name, int i) {
9f78065e 671 DPRINTF("_Z14isModuleLoadedPci: Checking for module %s (%d)\n", module_name, i);
4ba5d6d9
MG
672
673 return 1;
674}
daa4fc04 675
765c485a
MG
676/* XilCommNS::CPortResources::Instance() */
677void* _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
daa4fc04 708static void __attribute__ ((constructor)) libusbdriver_init(void) {
b05f6dfe
MG
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
daa4fc04 725 #if __WORDSIZE == 32
ad0f0d12
MG
726 {
727 struct utsname un;
728 int ret;
daa4fc04 729
ad0f0d12 730 ret = uname(&un);
daa4fc04 731
ad0f0d12
MG
732 if (ret == 0 && (!strcmp(un.machine, "x86_64"))) {
733 DPRINTF("setting 32bit personality\n");
734 (long)syscall(SYS_personality, PER_LINUX32);
735 }
daa4fc04
MG
736 }
737 #endif
738}
Impressum, Datenschutz