make it possible to return an error everywhere
[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>
f10480d1 36#include <usb.h>
2a7af812 37#include <signal.h>
9ba1e383 38#include <errno.h>
11d01742 39#include <inttypes.h>
54357994 40#include <sys/ioctl.h>
c42237a3
MG
41#include <sys/utsname.h>
42#include <bits/wordsize.h>
2c0c1255 43#include "usb-driver.h"
3e670223 44#include "config.h"
cbfa0ac6 45#include "xpcu.h"
cdc711dc 46
9c9fd67c 47static int (*ioctl_func) (int, int, void *) = NULL;
332ced7a 48static int windrvrfd = -1;
54357994 49static unsigned long ppbase = 0;
50static unsigned long ecpbase = 0;
25ba7a49 51static struct parport_config *pport = NULL;
cbfa0ac6 52static struct xpcu_s *xpcu = NULL;
be59993b
MG
53static FILE *modulesfp = NULL;
54static FILE *baseaddrfp = NULL;
55static int baseaddrnum = 0;
723d9aa0 56static int modules_read = 0;
292160ed 57
795992ad 58#define NO_WINDRVR 1
723d9aa0 59
60void hexdump(unsigned char *buf, int len) {
61 int i;
62
63 for(i=0; i<len; i++) {
64 fprintf(stderr,"%02x ", buf[i]);
65 if ((i % 16) == 15)
66 fprintf(stderr,"\n");
67 }
f1405f13 68 fprintf(stderr,"\n");
723d9aa0 69}
cdc711dc 70
cf55ed64 71
be59993b 72static int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) {
cdc711dc 73 struct header_struct* wdheader = (struct header_struct*)wdioctl;
9c9fd67c 74 struct version_struct *version;
75 int ret = 0;
cdc711dc 76
da3ba95a 77 if (wdheader->magic != MAGIC) {
2c2119eb 78 fprintf(stderr,"!!!ERROR: magic header does not match!!!\n");
79 return (*ioctl_func) (fd, request, wdioctl);
cdc711dc 80 }
81
bdc65937 82 switch(request & ~(0xc0000000)) {
da3ba95a 83 case VERSION:
9c9fd67c 84 version = (struct version_struct*)(wdheader->data);
81cf3658 85 strcpy(version->version, "libusb-driver.so version: " USB_DRIVER_VERSION);
90831fba 86 version->versionul = 802;
f1405f13 87 DPRINTF("VERSION\n");
cdc711dc 88 break;
2c2119eb 89
90 case LICENSE:
f1405f13 91 DPRINTF("LICENSE\n");
2c2119eb 92 break;
93
f152c048 94 case CARD_REGISTER_OLD:
9c9fd67c 95 case CARD_REGISTER:
54357994 96 DPRINTF("CARD_REGISTER\n");
9c9fd67c 97 {
533f4b68 98 struct card_register* cr = (struct card_register*)(wdheader->data);
54357994 99
501f1c21 100 DPRINTF("-> Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n",
54357994 101 cr->Card.dwItems,
102 (unsigned long)cr->Card.Item[0].I.IO.dwAddr,
103 cr->Card.Item[0].I.IO.dwBytes,
104 cr->Card.Item[0].I.IO.dwBar);
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[1].I.IO.dwAddr,
109 cr->Card.Item[1].I.IO.dwBytes,
110 cr->Card.Item[1].I.IO.dwBar);
576995a8 111#ifndef NO_WINDRVR
112 ret = (*ioctl_func) (fd, request, wdioctl);
ac9e3f59 113#else
bccac33b 114
25ba7a49 115 pport = config_get((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10);
61e0de7a 116 if (!pport)
117 break;
118
25ba7a49 119 ret = pport->open((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10);
3e670223 120
5e3d963b 121 ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr;
bccac33b 122
5e3d963b 123 if (cr->Card.dwItems > 1 && cr->Card.Item[1].I.IO.dwAddr)
124 ecpbase = (unsigned long)cr->Card.Item[1].I.IO.dwAddr;
19b2e286 125
5e3d963b 126 if (ret >= 0) {
127 cr->hCard = ret;
128 } else {
19b2e286 129 cr->hCard = 0;
5e3d963b 130 }
576995a8 131#endif
501f1c21 132 DPRINTF("<-hCard: %lu\n", cr->hCard);
9c9fd67c 133 }
da3ba95a 134 break;
2c2119eb 135
da3ba95a 136 case USB_TRANSFER:
501f1c21 137 DPRINTF("USB_TRANSFER\n");
da3ba95a 138 {
139 struct usb_transfer *ut = (struct usb_transfer*)(wdheader->data);
140
723d9aa0 141#ifdef DEBUG
501f1c21 142 DPRINTF("-> unique: 0x%lx, pipe: %lu, read: %lu, options: %lx, size: %lu, timeout: %lx\n",
f1405f13 143 ut->dwUniqueID, ut->dwPipeNum, ut->fRead,
144 ut->dwOptions, ut->dwBufferSize, ut->dwTimeout);
cf55ed64 145 if (ut->dwPipeNum == 0) {
501f1c21 146 DPRINTF("-> setup packet: ");
cf55ed64
MG
147 hexdump(ut->SetupPacket, 8);
148 }
723d9aa0 149
9c9fd67c 150 if (!ut->fRead && ut->dwBufferSize)
151 {
152 hexdump(ut->pBuffer, ut->dwBufferSize);
9c9fd67c 153 }
723d9aa0 154#endif
9c9fd67c 155
795992ad 156#ifndef NO_WINDRVR
9c9fd67c 157 ret = (*ioctl_func) (fd, request, wdioctl);
411af373 158#else
8af4d910 159 ret = xpcu_transfer(xpcu, ut);
292160ed 160#endif
9c9fd67c 161
723d9aa0 162#ifdef DEBUG
f1405f13 163 DPRINTF("Transferred: %lu (%s)\n",ut->dwBytesTransferred, (ut->fRead?"read":"write"));
9c9fd67c 164 if (ut->fRead && ut->dwBytesTransferred)
165 {
501f1c21 166 DPRINTF("<- Read: ");
9c9fd67c 167 hexdump(ut->pBuffer, ut->dwBytesTransferred);
168 }
723d9aa0 169#endif
da3ba95a 170 }
cdc711dc 171 break;
2c2119eb 172
f152c048 173 case INT_ENABLE_OLD:
da3ba95a 174 case INT_ENABLE:
f1405f13 175 DPRINTF("INT_ENABLE\n");
da3ba95a 176 {
9c9fd67c 177 struct interrupt *it = (struct interrupt*)(wdheader->data);
cdc711dc 178
501f1c21 179 DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
f1405f13 180 it->hInterrupt, it->dwOptions,
181 it->dwCmds, it->fEnableOk, it->dwCounter,
182 it->dwLost, it->fStopped);
cdc711dc 183
501f1c21
MG
184#ifndef NO_WINDRVR
185 ret = (*ioctl_func) (fd, request, wdioctl);
186#else
8af4d910 187 ret = xpcu_int_state(xpcu, it, ENABLE_INTERRUPT);
501f1c21
MG
188#endif
189
190 DPRINTF("<- Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
191 it->hInterrupt, it->dwOptions,
192 it->dwCmds, it->fEnableOk, it->dwCounter,
193 it->dwLost, it->fStopped);
9c9fd67c 194 }
cdc711dc 195
cdc711dc 196 break;
9c9fd67c 197
da3ba95a 198 case INT_DISABLE:
f1405f13 199 DPRINTF("INT_DISABLE\n");
da3ba95a 200 {
9c9fd67c 201 struct interrupt *it = (struct interrupt*)(wdheader->data);
da3ba95a 202
501f1c21 203 DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
f1405f13 204 it->hInterrupt, it->dwOptions,
205 it->dwCmds, it->fEnableOk, it->dwCounter,
206 it->dwLost, it->fStopped);
795992ad 207#ifndef NO_WINDRVR
9c9fd67c 208 ret = (*ioctl_func) (fd, request, wdioctl);
e71b6bf3 209#else
8af4d910 210 ret = xpcu_int_state(xpcu, it, DISABLE_INTERRUPT);
292160ed 211#endif
501f1c21 212 DPRINTF("<- Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
f1405f13 213 it->hInterrupt, it->dwOptions,
214 it->dwCmds, it->fEnableOk, it->dwCounter,
215 it->dwLost, it->fStopped);
da3ba95a 216 }
da3ba95a 217 break;
da3ba95a 218
9c9fd67c 219 case USB_SET_INTERFACE:
f1405f13 220 DPRINTF("USB_SET_INTERFACE\n");
da3ba95a 221 {
9c9fd67c 222 struct usb_set_interface *usi = (struct usb_set_interface*)(wdheader->data);
223
501f1c21 224 DPRINTF("-> unique: 0x%lx, interfacenum: %lu, alternatesetting: %lu, options: %lx\n",
f1405f13 225 usi->dwUniqueID, usi->dwInterfaceNum,
226 usi->dwAlternateSetting, usi->dwOptions);
795992ad 227#ifndef NO_WINDRVR
9c9fd67c 228 ret = (*ioctl_func) (fd, request, wdioctl);
2a7af812 229#else
8af4d910 230 ret = xpcu_set_interface(xpcu, usi);
292160ed 231#endif
501f1c21 232 DPRINTF("<- unique: 0x%lx, interfacenum: %lu, alternatesetting: %lu, options: %lx\n",
f1405f13 233 usi->dwUniqueID, usi->dwInterfaceNum,
234 usi->dwAlternateSetting, usi->dwOptions);
da3ba95a 235 }
cdc711dc 236 break;
da3ba95a 237
f152c048 238 case USB_GET_DEVICE_DATA_OLD:
9c9fd67c 239 case USB_GET_DEVICE_DATA:
f1405f13 240 DPRINTF("USB_GET_DEVICE_DATA\n");
9c9fd67c 241 {
242 struct usb_get_device_data *ugdd = (struct usb_get_device_data*)(wdheader->data);
9c9fd67c 243
501f1c21 244 DPRINTF("-> unique: 0x%lx, bytes: %lu, options: %lx\n",
f1405f13 245 ugdd->dwUniqueID, ugdd->dwBytes,
246 ugdd->dwOptions);
247
8af4d910 248 ret = xpcu_deviceinfo(xpcu, ugdd);
f92c0fbc 249
da3ba95a 250 }
9c9fd67c 251 break;
252
f152c048 253 case EVENT_REGISTER_OLD:
b0f621dd 254 case EVENT_REGISTER:
f1405f13 255 DPRINTF("EVENT_REGISTER\n");
b0f621dd 256 {
257 struct event *e = (struct event*)(wdheader->data);
f92c0fbc 258#ifdef DEBUG
b0f621dd 259 int i;
f92c0fbc 260#endif
b0f621dd 261
501f1c21 262 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 263 e->handle, e->dwAction,
264 e->dwStatus, e->dwEventId, e->dwCardType,
265 e->hKernelPlugIn, e->dwOptions,
266 e->u.Usb.deviceId.dwVendorId,
267 e->u.Usb.deviceId.dwProductId,
268 e->u.Usb.dwUniqueID, e->dwEventVer,
269 e->dwNumMatchTables);
270
795992ad 271#ifndef NO_WINDRVR
b0f621dd 272 ret = (*ioctl_func) (fd, request, wdioctl);
2a7af812 273#else
501f1c21 274 xpcu = xpcu_find(e);
292160ed 275#endif
b0f621dd 276
723d9aa0 277#ifdef DEBUG
501f1c21 278 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 279 e->handle, e->dwAction,
280 e->dwStatus, e->dwEventId, e->dwCardType,
281 e->hKernelPlugIn, e->dwOptions,
282 e->u.Usb.deviceId.dwVendorId,
283 e->u.Usb.deviceId.dwProductId,
284 e->u.Usb.dwUniqueID, e->dwEventVer,
285 e->dwNumMatchTables);
286
b0f621dd 287 for (i = 0; i < e->dwNumMatchTables; i++)
f1405f13 288 DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
289 e->matchTables[i].VendorId,
290 e->matchTables[i].ProductId,
291 e->matchTables[i].bDeviceClass,
292 e->matchTables[i].bDeviceSubClass,
293 e->matchTables[i].bInterfaceClass,
294 e->matchTables[i].bInterfaceSubClass,
295 e->matchTables[i].bInterfaceProtocol);
723d9aa0 296#endif
b0f621dd 297 }
298 break;
299
f152c048 300 case TRANSFER_OLD:
da3ba95a 301 case TRANSFER:
f1405f13 302 DPRINTF("TRANSFER\n");
ac9e3f59 303 {
304 WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);
305
1dac5195 306#ifndef NO_WINDRVR
307 ret = (*ioctl_func) (fd, request, wdioctl);
308#else
25ba7a49 309 ret = pport->transfer(tr, fd, request, ppbase, ecpbase, 1);
1dac5195 310#endif
ac9e3f59 311 }
9c9fd67c 312 break;
313
54357994 314 case MULTI_TRANSFER_OLD:
576995a8 315 case MULTI_TRANSFER:
316 DPRINTF("MULTI_TRANSFER\n");
ac9e3f59 317 {
318 WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);
319 unsigned long num = wdheader->size/sizeof(WD_TRANSFER);
1dac5195 320#ifndef NO_WINDRVR
321 ret = (*ioctl_func) (fd, request, wdioctl);
322#else
25ba7a49 323 ret = pport->transfer(tr, fd, request, ppbase, ecpbase, num);
ac9e3f59 324#endif
ac9e3f59 325 }
576995a8 326 break;
327
da3ba95a 328 case EVENT_UNREGISTER:
f92c0fbc
MG
329 {
330 struct event *e = (struct event*)(wdheader->data);
331
332 DPRINTF("EVENT_UNREGISTER\n");
795992ad 333#ifndef NO_WINDRVR
f92c0fbc
MG
334 ret = (*ioctl_func) (fd, request, wdioctl);
335#else
8af4d910 336 ret = xpcu_close(xpcu, e);
292160ed 337#endif
f92c0fbc 338 }
9c9fd67c 339 break;
340
da3ba95a 341 case INT_WAIT:
f1405f13 342 DPRINTF("INT_WAIT\n");
b0f621dd 343 {
344 struct interrupt *it = (struct interrupt*)(wdheader->data);
345
501f1c21 346 DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
f1405f13 347 it->hInterrupt, it->dwOptions,
348 it->dwCmds, it->fEnableOk, it->dwCounter,
349 it->dwLost, it->fStopped);
b0f621dd 350
795992ad 351#ifndef NO_WINDRVR
b0f621dd 352 ret = (*ioctl_func) (fd, request, wdioctl);
292160ed 353#else
8af4d910 354 ret = xpcu_int_wait(xpcu, it);
292160ed 355#endif
356
501f1c21 357 DPRINTF("<- INT_WAIT_RETURN: Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
f1405f13 358 it->hInterrupt, it->dwOptions, it->dwCmds,
359 it->fEnableOk, it->dwCounter, it->dwLost,
360 it->fStopped);
b0f621dd 361 }
9c9fd67c 362 break;
363
da3ba95a 364 case CARD_UNREGISTER:
f1405f13 365 DPRINTF("CARD_UNREGISTER\n");
54357994 366 {
367 struct card_register* cr = (struct card_register*)(wdheader->data);
368
501f1c21 369 DPRINTF("-> Addr: 0x%lx, bytes: %lu, bar: %lu\n",
54357994 370 (unsigned long)cr->Card.Item[0].I.IO.dwAddr,
371 cr->Card.Item[0].I.IO.dwBytes,
372 cr->Card.Item[0].I.IO.dwBar);
373
501f1c21 374 DPRINTF("-> hCard: %lu\n", cr->hCard);
54357994 375
795992ad 376#ifndef NO_WINDRVR
54357994 377 ret = (*ioctl_func) (fd, request, wdioctl);
378#else
72ce448b
MG
379 if (pport)
380 pport->close(cr->hCard);
381
382 pport = NULL;
292160ed 383#endif
54357994 384 }
9c9fd67c 385 break;
386
da3ba95a 387 case EVENT_PULL:
f1405f13 388 DPRINTF("EVENT_PULL\n");
b1831983 389 {
390 struct event *e = (struct event*)(wdheader->data);
723d9aa0 391#ifdef DEBUG
b1831983 392 int i;
393
501f1c21 394 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 395 e->handle, e->dwAction, e->dwStatus,
396 e->dwEventId, e->dwCardType, e->hKernelPlugIn,
397 e->dwOptions, e->u.Usb.deviceId.dwVendorId,
398 e->u.Usb.deviceId.dwProductId,
399 e->u.Usb.dwUniqueID, e->dwEventVer,
400 e->dwNumMatchTables);
401
b1831983 402 for (i = 0; i < e->dwNumMatchTables; i++)
501f1c21 403 DPRINTF("-> match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
f1405f13 404 e->matchTables[i].VendorId,
405 e->matchTables[i].ProductId,
406 e->matchTables[i].bDeviceClass,
407 e->matchTables[i].bDeviceSubClass,
408 e->matchTables[i].bInterfaceClass,
409 e->matchTables[i].bInterfaceSubClass,
410 e->matchTables[i].bInterfaceProtocol);
723d9aa0 411#endif
b1831983 412
795992ad 413#ifndef NO_WINDRVR
b1831983 414 ret = (*ioctl_func) (fd, request, wdioctl);
292160ed 415#else
8af4d910 416 ret = xpcu_found(xpcu, e);
292160ed 417#endif
b1831983 418
723d9aa0 419#ifdef DEBUG
501f1c21 420 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 421 e->handle, e->dwAction, e->dwStatus,
422 e->dwEventId, e->dwCardType, e->hKernelPlugIn,
423 e->dwOptions, e->u.Usb.deviceId.dwVendorId,
424 e->u.Usb.deviceId.dwProductId,
425 e->u.Usb.dwUniqueID, e->dwEventVer,
426 e->dwNumMatchTables);
427
b1831983 428 for (i = 0; i < e->dwNumMatchTables; i++)
501f1c21 429 DPRINTF("<- match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
f1405f13 430 e->matchTables[i].VendorId,
431 e->matchTables[i].ProductId,
432 e->matchTables[i].bDeviceClass,
433 e->matchTables[i].bDeviceSubClass,
434 e->matchTables[i].bInterfaceClass,
435 e->matchTables[i].bInterfaceSubClass,
436 e->matchTables[i].bInterfaceProtocol);
723d9aa0 437#endif
ca18111b 438
b1831983 439 }
9c9fd67c 440 break;
441
da3ba95a 442 default:
292160ed 443 fprintf(stderr,"!!!Unsupported IOCTL: %x!!!\n", request);
795992ad 444#ifndef NO_WINDRVR
9c9fd67c 445 ret = (*ioctl_func) (fd, request, wdioctl);
292160ed 446#endif
447 break;
cdc711dc 448 }
da3ba95a 449
9c9fd67c 450 return ret;
cdc711dc 451}
452
54357994 453int ioctl(int fd, unsigned long int request, ...) {
dbda1264 454 va_list args;
455 void *argp;
456 int ret;
457
458 if (!ioctl_func)
f1405f13 459 ioctl_func = (int (*) (int, int, void *)) dlsym (RTLD_NEXT, "ioctl");
dbda1264 460
461 va_start (args, request);
462 argp = va_arg (args, void *);
463 va_end (args);
464
332ced7a 465 if (fd == windrvrfd)
dbda1264 466 ret = do_wdioctl(fd, request, argp);
467 else
468 ret = (*ioctl_func) (fd, request, argp);
469
470 return ret;
471}
cdc711dc 472
be452175 473int open (const char *pathname, int flags, ...) {
474 static int (*func) (const char *, int, mode_t) = NULL;
cdc711dc 475 mode_t mode = 0;
476 va_list args;
477 int fd;
478
479 if (!func)
f1405f13 480 func = (int (*) (const char *, int, mode_t)) dlsym (RTLD_NEXT, "open");
cdc711dc 481
482 if (flags & O_CREAT) {
483 va_start(args, flags);
484 mode = va_arg(args, mode_t);
485 va_end(args);
486 }
487
cdc711dc 488 if (!strcmp (pathname, "/dev/windrvr6")) {
f1405f13 489 DPRINTF("opening windrvr6\n");
795992ad 490#ifdef NO_WINDRVR
01b99d52 491 windrvrfd = fd = (*func) ("/dev/null", flags, mode);
492#else
493 windrvrfd = fd = (*func) (pathname, flags, mode);
494#endif
723d9aa0 495
496 return fd;
cdc711dc 497 }
498
723d9aa0 499 return (*func) (pathname, flags, mode);
cdc711dc 500}
501
723d9aa0 502int close(int fd) {
503 static int (*func) (int) = NULL;
cdc711dc 504
723d9aa0 505 if (!func)
f1405f13 506 func = (int (*) (int)) dlsym(RTLD_NEXT, "close");
723d9aa0 507
11d01742 508 if (fd == windrvrfd && windrvrfd >= 0) {
f1405f13 509 DPRINTF("close windrvrfd\n");
010cbaa6 510
cbfa0ac6 511 xpcu = NULL;
332ced7a 512 windrvrfd = -1;
cdc711dc 513 }
cdc711dc 514
723d9aa0 515 return (*func) (fd);
cdc711dc 516}
517
723d9aa0 518FILE *fopen(const char *path, const char *mode) {
519 FILE *ret;
520 static FILE* (*func) (const char*, const char*) = NULL;
0dca330e 521 char buf[256];
522 int i;
ca18111b 523
524 if (!func)
f1405f13 525 func = (FILE* (*) (const char*, const char*)) dlsym(RTLD_NEXT, "fopen");
ca18111b 526
3e670223 527 for (i = 0; i < 4; i++) {
528 snprintf(buf, sizeof(buf), "/proc/sys/dev/parport/parport%d/base-addr", i);
529 if (!strcmp(path, buf)) {
530 DPRINTF("open base-addr of parport%d\n", i);
531 if (config_is_real_pport(i)) {
532 ret = (*func) (path, mode);
533 } else {
534 ret = (*func) ("/dev/null", mode);
535 }
536
537 if (ret) {
538 baseaddrfp = ret;
539 baseaddrnum = i;
540 }
541
542 return ret;
543 }
544 }
545
546 ret = (*func) (path, mode);
ca18111b 547
0dca330e 548 if (!strcmp(path, "/proc/modules")) {
f1405f13 549 DPRINTF("opening /proc/modules\n");
723d9aa0 550#ifdef NO_WINDRVR
dbda1264 551 modulesfp = ret;
723d9aa0 552 modules_read = 0;
553#endif
554 }
cdc711dc 555
556 return ret;
557}
558
dbda1264 559char *fgets(char *s, int size, FILE *stream) {
560 static char* (*func) (char*, int, FILE*) = NULL;
16f6b164 561 const char modules[][256] = {"windrvr6 1 0 - Live 0xdeadbeef\n", "parport_pc 1 0 - Live 0xdeadbeef\n"};
0dca330e 562 char buf[256];
dbda1264 563 char *ret = NULL;
564
cdc711dc 565
566 if (!func)
f1405f13 567 func = (char* (*) (char*, int, FILE*)) dlsym(RTLD_NEXT, "fgets");
723d9aa0 568
dbda1264 569 if (modulesfp == stream) {
54357994 570 if (modules_read < sizeof(modules) / sizeof(modules[0])) {
16f6b164 571 strcpy(s, modules[modules_read]);
dbda1264 572 ret = s;
16f6b164 573 modules_read++;
dbda1264 574 }
0dca330e 575 } else if (baseaddrfp == stream) {
576 snprintf(s, sizeof(buf), "%d\t%d\n",
577 (baseaddrnum) * 0x10,
578 ((baseaddrnum) * 0x10) + 0x400);
579 ret = s;
723d9aa0 580 } else {
dbda1264 581 ret = (*func)(s,size,stream);
723d9aa0 582 }
cdc711dc 583
584 return ret;
585}
586
dbda1264 587int fclose(FILE *fp) {
588 static int (*func) (FILE*) = NULL;
cdc711dc 589
dbda1264 590 if (!func)
f1405f13 591 func = (int (*) (FILE*)) dlsym(RTLD_NEXT, "fclose");
cdc711dc 592
dbda1264 593 if (fp == modulesfp) {
594 modulesfp = NULL;
595 }
0dca330e 596
597 if (fp == baseaddrfp) {
598 baseaddrfp = NULL;
599 }
dbda1264 600
601 return (*func)(fp);
cdc711dc 602}
419f2c98 603
604int access(const char *pathname, int mode) {
605 static int (*func) (const char*, int);
606
607 if (!func)
f1405f13 608 func = (int (*) (const char*, int)) dlsym(RTLD_NEXT, "access");
3eee002c 609
b8b756f5 610 if (pathname && !strcmp(pathname, "/dev/windrvr6")) {
419f2c98 611 return 0;
612 } else {
613 return (*func)(pathname, mode);
614 }
615}
c42237a3
MG
616
617#if __WORDSIZE == 32
618int uname (struct utsname *__name) {
619 static int (*func) (struct utsname*);
620 int ret;
621
622 if (!func)
623 func = (int (*) (struct utsname*)) dlsym(RTLD_NEXT, "uname");
624
625 ret = (*func)(__name);
626
627 if (ret == 0 && (!strcmp(__name->machine, "x86_64"))) {
628 strcpy(__name->machine, "i686");
629 }
630
631 return ret;
632}
633#endif
Impressum, Datenschutz