b92c9516a6e8f35c989f4a5b407690194bf94ac9
[usb-driver] / usb-driver.c
1 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
2
3 #define _GNU_SOURCE 1
4
5 #if defined(RTLD_NEXT)
6 #define REAL_LIBC RTLD_NEXT
7 #else
8 #define REAL_LIBC ((void *) -1L)
9 #endif
10
11 #include <dlfcn.h>
12 #include <stdarg.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include <fcntl.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <sys/time.h>
20 #include <stdio.h>
21 #include <usb.h>
22 #include <signal.h>
23 #include "xilinx.h"
24
25 static int (*ioctl_func) (int, int, void *) = NULL;
26 static int windrvrfd = 0;
27 FILE *modulesfp;
28 static int modules_read = 0;
29 static struct usb_bus *busses = NULL;
30 static struct usb_device *usbdevice;
31 static usb_dev_handle *usb_devhandle = NULL;
32 static unsigned long card_type;
33 static int ints_enabled = 0;
34
35 #define NO_WINDRVR 1
36 #undef DEBUG
37
38 void hexdump(unsigned char *buf, int len) {
39 int i;
40
41 for(i=0; i<len; i++) {
42 fprintf(stderr,"%02x ", buf[i]);
43 if ((i % 16) == 15)
44 fprintf(stderr,"\n");
45 }
46 }
47
48 int usb_deviceinfo(unsigned char *buf) {
49 int i,j,k,l;
50 int len = 0;
51 WDU_CONFIGURATION **pConfigs, **pActiveConfig;
52 WDU_INTERFACE **pActiveInterface;
53
54 if (buf) {
55 struct usb_device_info *udi = (struct usb_device_info*)(buf+len);
56
57 udi->Descriptor.bLength = sizeof(WDU_DEVICE_DESCRIPTOR);
58 udi->Descriptor.bDescriptorType = usbdevice->descriptor.bDescriptorType;
59 udi->Descriptor.bcdUSB = usbdevice->descriptor.bcdUSB;
60 udi->Descriptor.bDeviceClass = usbdevice->descriptor.bDeviceClass;
61 udi->Descriptor.bDeviceSubClass = usbdevice->descriptor.bDeviceSubClass;
62 udi->Descriptor.bDeviceProtocol = usbdevice->descriptor.bDeviceProtocol;
63 udi->Descriptor.bMaxPacketSize0 = usbdevice->descriptor.bMaxPacketSize0;
64 udi->Descriptor.idVendor = usbdevice->descriptor.idVendor;
65 udi->Descriptor.idProduct = usbdevice->descriptor.idProduct;
66 udi->Descriptor.bcdDevice = usbdevice->descriptor.bcdDevice;
67 udi->Descriptor.iManufacturer = usbdevice->descriptor.iManufacturer;
68 udi->Descriptor.iProduct = usbdevice->descriptor.iProduct;
69 udi->Descriptor.iSerialNumber = usbdevice->descriptor.iSerialNumber;
70 udi->Descriptor.bNumConfigurations = usbdevice->descriptor.bNumConfigurations;
71
72 /* TODO: Fix Pipe0! */
73 udi->Pipe0.dwNumber = 0x00;
74 udi->Pipe0.dwMaximumPacketSize = usbdevice->descriptor.bMaxPacketSize0;
75 udi->Pipe0.type = 0;
76 udi->Pipe0.direction = 3;
77 udi->Pipe0.dwInterval = 0;
78
79 pConfigs = &(udi->pConfigs);
80 pActiveConfig = &(udi->pActiveConfig);
81 pActiveInterface = &(udi->pActiveInterface[0]);
82 }
83
84 len = sizeof(struct usb_device_info);
85
86 for (i=0; i<usbdevice->descriptor.bNumConfigurations; i++)
87 {
88 struct usb_config_descriptor *conf_desc = &usbdevice->config[i];
89 WDU_INTERFACE **pInterfaces;
90 WDU_ALTERNATE_SETTING **pAlternateSettings[conf_desc->bNumInterfaces];
91 WDU_ALTERNATE_SETTING **pActiveAltSetting[conf_desc->bNumInterfaces];
92
93 if (buf) {
94 WDU_CONFIGURATION *cfg = (WDU_CONFIGURATION*)(buf+len);
95
96 *pConfigs = cfg;
97 *pActiveConfig = cfg;
98
99 cfg->Descriptor.bLength = conf_desc->bLength;
100 cfg->Descriptor.bDescriptorType = conf_desc->bDescriptorType;
101 cfg->Descriptor.wTotalLength = conf_desc->wTotalLength;
102 cfg->Descriptor.bNumInterfaces = conf_desc->bNumInterfaces;
103 cfg->Descriptor.bConfigurationValue = conf_desc->bConfigurationValue;
104 cfg->Descriptor.iConfiguration = conf_desc->iConfiguration;
105 cfg->Descriptor.bmAttributes = conf_desc->bmAttributes;
106 cfg->Descriptor.MaxPower = conf_desc->MaxPower;
107
108 cfg->dwNumInterfaces = conf_desc->bNumInterfaces;
109
110 pInterfaces = &(cfg->pInterfaces);
111 }
112 len += sizeof(WDU_CONFIGURATION);
113
114 if (buf) {
115 *pInterfaces = (WDU_INTERFACE*)(buf+len);
116 for (j=0; j<conf_desc->bNumInterfaces; j++) {
117 WDU_INTERFACE *iface = (WDU_INTERFACE*)(buf+len);
118
119 pActiveInterface[j] = iface;
120
121 pAlternateSettings[j] = &(iface->pAlternateSettings);
122 iface->dwNumAltSettings = usbdevice->config[i].interface[j].num_altsetting;
123 pActiveAltSetting[j] = &(iface->pActiveAltSetting);
124
125 len += sizeof(WDU_INTERFACE);
126 }
127 } else {
128 len += sizeof(WDU_INTERFACE) * conf_desc->bNumInterfaces;
129 }
130
131 for (j=0; j<conf_desc->bNumInterfaces; j++)
132 {
133 struct usb_interface *interface = &usbdevice->config[i].interface[j];
134
135 if (buf) {
136 *pAlternateSettings[j] = (WDU_ALTERNATE_SETTING*)(buf+len);
137 /* FIXME: */
138 *pActiveAltSetting[j] = (WDU_ALTERNATE_SETTING*)(buf+len);
139 }
140
141 for(k=0; k<interface->num_altsetting; k++)
142 {
143 unsigned char bNumEndpoints = interface->altsetting[k].bNumEndpoints;
144 WDU_ENDPOINT_DESCRIPTOR **pEndpointDescriptors;
145 WDU_PIPE_INFO **pPipes;
146
147 if (buf) {
148 WDU_ALTERNATE_SETTING *altset = (WDU_ALTERNATE_SETTING*)(buf+len);
149
150 altset->Descriptor.bLength = interface->altsetting[k].bLength;
151 altset->Descriptor.bDescriptorType = interface->altsetting[k].bDescriptorType;
152 altset->Descriptor.bInterfaceNumber = interface->altsetting[k].bInterfaceNumber;
153 altset->Descriptor.bAlternateSetting = interface->altsetting[k].bAlternateSetting;
154 altset->Descriptor.bNumEndpoints = interface->altsetting[k].bNumEndpoints;
155 altset->Descriptor.bInterfaceClass = interface->altsetting[k].bInterfaceClass;
156 altset->Descriptor.bInterfaceSubClass = interface->altsetting[k].bInterfaceSubClass;
157 altset->Descriptor.bInterfaceProtocol = interface->altsetting[k].bInterfaceProtocol;
158 altset->Descriptor.iInterface = interface->altsetting[k].iInterface;
159 pEndpointDescriptors = &(altset->pEndpointDescriptors);
160 pPipes = &(altset->pPipes);
161
162 }
163 len +=sizeof(WDU_ALTERNATE_SETTING);
164
165 if (buf) {
166 *pEndpointDescriptors = (WDU_ENDPOINT_DESCRIPTOR*)(buf+len);
167 for (l = 0; l < bNumEndpoints; l++) {
168 WDU_ENDPOINT_DESCRIPTOR *ed = (WDU_ENDPOINT_DESCRIPTOR*)(buf+len);
169
170 ed->bLength = interface->altsetting[k].endpoint[l].bLength;
171 ed->bDescriptorType = interface->altsetting[k].endpoint[l].bDescriptorType;
172 ed->bEndpointAddress = interface->altsetting[k].endpoint[l].bEndpointAddress;
173 ed->bmAttributes = interface->altsetting[k].endpoint[l].bmAttributes;
174 ed->wMaxPacketSize = interface->altsetting[k].endpoint[l].wMaxPacketSize;
175 ed->bInterval = interface->altsetting[k].endpoint[l].bInterval;
176
177 len += sizeof(WDU_ENDPOINT_DESCRIPTOR);
178 }
179
180 *pPipes = (WDU_PIPE_INFO*)(buf+len);
181 for (l = 0; l < bNumEndpoints; l++) {
182 WDU_PIPE_INFO *pi = (WDU_PIPE_INFO*)(buf+len);
183
184 pi->dwNumber = interface->altsetting[k].endpoint[l].bEndpointAddress;
185 pi->dwMaximumPacketSize = WDU_GET_MAX_PACKET_SIZE(interface->altsetting[k].endpoint[l].wMaxPacketSize);
186 pi->type = interface->altsetting[k].endpoint[l].bmAttributes & USB_ENDPOINT_TYPE_MASK;
187 if (pi->type == PIPE_TYPE_CONTROL)
188 pi->direction = WDU_DIR_IN_OUT;
189 else
190 {
191 pi->direction = interface->altsetting[k].endpoint[l].bEndpointAddress & USB_ENDPOINT_DIR_MASK ? WDU_DIR_IN : WDU_DIR_OUT;
192 }
193
194 pi->dwInterval = interface->altsetting[k].endpoint[l].bInterval;
195
196 len += sizeof(WDU_PIPE_INFO);
197 }
198 } else {
199 len +=(sizeof(WDU_ENDPOINT_DESCRIPTOR)+sizeof(WDU_PIPE_INFO))*bNumEndpoints;
200 }
201 }
202 }
203 }
204
205 return len;
206 }
207
208 int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) {
209 struct header_struct* wdheader = (struct header_struct*)wdioctl;
210 struct version_struct *version;
211 int ret = 0;
212
213 if (wdheader->magic != MAGIC) {
214 fprintf(stderr,"!!!ERROR: magic header does not match!!!\n");
215 return (*ioctl_func) (fd, request, wdioctl);
216 }
217
218 switch(request) {
219 case VERSION:
220 version = (struct version_struct*)(wdheader->data);
221 strcpy(version->version, "WinDriver no more");
222 version->versionul = 999;
223 #ifdef DEBUG
224 fprintf(stderr,"faking VERSION\n");
225 #endif
226 break;
227
228 case LICENSE:
229 #ifdef DEBUG
230 fprintf(stderr,"faking LICENSE\n");
231 #endif
232 break;
233
234 case CARD_REGISTER:
235 {
236 //struct card_register* cr = (struct card_register*)(wdheader->data);
237 /* Todo: LPT-Port already in use */
238 }
239 #ifdef DEBUG
240 fprintf(stderr,"faking CARD_REGISTER\n");
241 #endif
242 break;
243
244 case USB_TRANSFER:
245 #ifdef DEBUG
246 fprintf(stderr,"in USB_TRANSFER");
247 #endif
248 {
249 struct usb_transfer *ut = (struct usb_transfer*)(wdheader->data);
250
251 #ifdef DEBUG
252 fprintf(stderr," unique: %lu, pipe: %lu, read: %lu, options: %lx, size: %lu, timeout: %lx\n", ut->dwUniqueID, ut->dwPipeNum, ut->fRead, ut->dwOptions, ut->dwBufferSize, ut->dwTimeout);
253 fprintf(stderr,"setup packet: ");
254 hexdump(ut->SetupPacket, 8);
255 fprintf(stderr,"\n");
256
257 if (!ut->fRead && ut->dwBufferSize)
258 {
259 hexdump(ut->pBuffer, ut->dwBufferSize);
260 fprintf(stderr,"\n");
261 }
262 #endif
263
264 #ifndef NO_WINDRVR
265 ret = (*ioctl_func) (fd, request, wdioctl);
266 #else
267 /* http://www.jungo.com/support/documentation/windriver/802/wdusb_man_mhtml/node55.html#SECTION001213000000000000000 */
268 if (ut->dwPipeNum == 0) { /* control pipe */
269 int requesttype, request, value, index, size;
270 requesttype = ut->SetupPacket[0];
271 request = ut->SetupPacket[1];
272 value = ut->SetupPacket[2] | (ut->SetupPacket[3] << 8);
273 index = ut->SetupPacket[4] | (ut->SetupPacket[5] << 8);
274 size = ut->SetupPacket[6] | (ut->SetupPacket[7] << 8);
275 #ifdef DEBUG
276 fprintf(stderr, "requesttype: %x, request: %x, value: %u, index: %u, size: %u\n", requesttype, request, value, index, size);
277 #endif
278 ret = usb_control_msg(usb_devhandle, requesttype, request, value, index, ut->pBuffer, size, ut->dwTimeout);
279 } else {
280 if (ut->fRead) {
281 ret = usb_bulk_read(usb_devhandle, ut->dwPipeNum, ut->pBuffer, ut->dwBufferSize, ut->dwTimeout);
282
283 } else {
284 ret = usb_bulk_write(usb_devhandle, ut->dwPipeNum, ut->pBuffer, ut->dwBufferSize, ut->dwTimeout);
285 }
286 }
287
288 if (ret < 0) {
289 fprintf(stderr, "usb_transfer: %d (%s)\n", ret, usb_strerror());
290 } else {
291 ut->dwBytesTransferred = ret;
292 ret = 0;
293 }
294 #endif
295
296 #ifdef DEBUG
297 fprintf(stderr,"Transferred: %lu (%s)\n",ut->dwBytesTransferred, (ut->fRead?"read":"write"));
298 if (ut->fRead && ut->dwBytesTransferred)
299 {
300 fprintf(stderr,"Read: ");
301 hexdump(ut->pBuffer, ut->dwBytesTransferred);
302 fprintf(stderr,"\n");
303 }
304 #endif
305 }
306 break;
307
308 case INT_ENABLE:
309 #ifdef DEBUG
310 fprintf(stderr,"INT_ENABLE\n");
311 #endif
312 {
313 struct interrupt *it = (struct interrupt*)(wdheader->data);
314
315 #ifdef DEBUG
316 fprintf(stderr,"Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped);
317 #endif
318
319 it->fEnableOk = 1;
320 ints_enabled = 1;
321 //ret = (*ioctl_func) (fd, request, wdioctl);
322 }
323
324 break;
325
326 case INT_DISABLE:
327 #ifdef DEBUG
328 fprintf(stderr,"INT_DISABLE\n");
329 #endif
330 {
331 struct interrupt *it = (struct interrupt*)(wdheader->data);
332
333 #ifdef DEBUG
334 fprintf(stderr,"Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped);
335 #endif
336 #ifndef NO_WINDRVR
337 ret = (*ioctl_func) (fd, request, wdioctl);
338 #else
339 it->dwCounter = 0;
340 it->fStopped = 1;
341 ints_enabled = 0;
342 #endif
343 #ifdef DEBUG
344 fprintf(stderr,"Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped);
345 #endif
346 }
347 break;
348
349 case USB_SET_INTERFACE:
350 #ifdef DEBUG
351 fprintf(stderr,"USB_SET_INTERFACE\n");
352 #endif
353 {
354 struct usb_set_interface *usi = (struct usb_set_interface*)(wdheader->data);
355
356 #ifdef DEBUG
357 fprintf(stderr,"unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", usi->dwUniqueID, usi->dwInterfaceNum, usi->dwAlternateSetting, usi->dwOptions);
358 #endif
359 #ifndef NO_WINDRVR
360 ret = (*ioctl_func) (fd, request, wdioctl);
361 #else
362 if (usbdevice) {
363 if (!usb_devhandle)
364 usb_devhandle = usb_open(usbdevice);
365
366 /* FIXME: Select right interface! */
367 ret = usb_claim_interface(usb_devhandle, usbdevice->config[0].interface[usi->dwInterfaceNum].altsetting[usi->dwAlternateSetting].bInterfaceNumber);
368 if (!ret) {
369 //ret = usb_set_configuration(usb_devhandle, usbdevice->config[0].bConfigurationValue);
370 if(!ret) {
371 ret = usb_set_altinterface(usb_devhandle, usi->dwAlternateSetting);
372 if (ret)
373 fprintf(stderr, "usb_set_altinterface: %d\n", ret);
374 } else {
375 fprintf(stderr, "usb_set_configuration: %d (%s)\n", ret, usb_strerror());
376 }
377 } else {
378 fprintf(stderr, "usb_claim_interface: %d -> %d (%s)\n", usbdevice->config[0].interface[usi->dwInterfaceNum].altsetting[usi->dwAlternateSetting].bInterfaceNumber, ret, usb_strerror());
379 }
380 }
381 #endif
382 #ifdef DEBUG
383 fprintf(stderr,"unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", usi->dwUniqueID, usi->dwInterfaceNum, usi->dwAlternateSetting, usi->dwOptions);
384 #endif
385 }
386 break;
387
388 case USB_GET_DEVICE_DATA:
389 #ifdef DEBUG
390 fprintf(stderr,"faking USB_GET_DEVICE_DATA\n");
391 #endif
392 {
393 struct usb_get_device_data *ugdd = (struct usb_get_device_data*)(wdheader->data);
394 int pSize;
395
396 #ifdef DEBUG
397 fprintf(stderr, "unique: %lu, bytes: %lu, options: %lx\n", ugdd->dwUniqueID, ugdd->dwBytes, ugdd->dwOptions);
398 #endif
399 pSize = ugdd->dwBytes;
400 //ret = (*ioctl_func) (fd, request, wdioctl);
401 if (!ugdd->dwBytes) {
402 if (usbdevice) {
403 ugdd->dwBytes = usb_deviceinfo(NULL);
404 }
405 } else {
406 usb_deviceinfo((unsigned char*)ugdd->pBuf);
407 }
408 }
409 break;
410
411 case EVENT_REGISTER:
412 #ifdef DEBUG
413 fprintf(stderr,"EVENT_REGISTER\n");
414 #endif
415 {
416 struct event *e = (struct event*)(wdheader->data);
417 struct usb_bus *bus;
418 int i;
419
420 #ifdef DEBUG
421 fprintf(stderr,"handle: %lu, action: %lu, status: %lu, eventid: %lu, cardtype: %lu, kplug: %lu, options: %lu, dev: %lx:%lx, unique: %lu, ver: %lu, nummatch: %lu\n", e->handle, e->dwAction, e->dwStatus, e->dwEventId, e->dwCardType, e->hKernelPlugIn, e->dwOptions, e->u.Usb.deviceId.dwVendorId, e->u.Usb.deviceId.dwProductId, e->u.Usb.dwUniqueID, e->dwEventVer, e->dwNumMatchTables);
422 #endif
423 for (i = 0; i < e->dwNumMatchTables; i++) {
424 #ifdef DEBUG
425 fprintf(stderr,"match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", e->matchTables[i].VendorId, e->matchTables[i].ProductId, e->matchTables[i].bDeviceClass, e->matchTables[i].bDeviceSubClass, e->matchTables[i].bInterfaceClass, e->matchTables[i].bInterfaceSubClass, e->matchTables[i].bInterfaceProtocol);
426 #endif
427
428 for (bus = busses; bus; bus = bus->next) {
429 struct usb_device *dev;
430
431 for (dev = bus->devices; dev; dev = dev->next) {
432 struct usb_device_descriptor *desc = &(dev->descriptor);
433
434 if((desc->idVendor == e->matchTables[i].VendorId) &&
435 (desc->idProduct == e->matchTables[i].ProductId) &&
436 (desc->bDeviceClass == e->matchTables[i].bDeviceClass) &&
437 (desc->bDeviceSubClass == e->matchTables[i].bDeviceSubClass)) {
438 int ac;
439 for (ac = 0; ac < desc->bNumConfigurations; ac++) {
440 struct usb_interface *interface = dev->config[ac].interface;
441 int ai;
442
443 for (ai = 0; ai < interface->num_altsetting; ai++) {
444 #ifdef DEBUG
445 fprintf(stderr, "intclass: %x, intsubclass: %x, intproto: %x\n", interface->altsetting[i].bInterfaceClass, interface->altsetting[i].bInterfaceSubClass, interface->altsetting[i].bInterfaceProtocol);
446 #endif
447 if ((interface->altsetting[ai].bInterfaceSubClass == e->matchTables[i].bInterfaceSubClass) &&
448 (interface->altsetting[ai].bInterfaceProtocol == e->matchTables[i].bInterfaceProtocol)){
449 /* TODO: check interfaceClass! */
450 #ifdef DEBUG
451 fprintf(stderr,"!!!FOUND DEVICE WITH LIBUSB!!!\n");
452 #endif
453 usbdevice = dev;
454 card_type = e->dwCardType;
455 }
456 }
457 }
458 }
459 }
460 }
461 }
462
463 #ifndef NO_WINDRVR
464 ret = (*ioctl_func) (fd, request, wdioctl);
465 #else
466 e->handle++;
467 #endif
468
469 #ifdef DEBUG
470 fprintf(stderr,"handle: %lu, action: %lu, status: %lu, eventid: %lu, cardtype: %lu, kplug: %lu, options: %lu, dev: %lx:%lx, unique: %lu, ver: %lu, nummatch: %lu\n", e->handle, e->dwAction, e->dwStatus, e->dwEventId, e->dwCardType, e->hKernelPlugIn, e->dwOptions, e->u.Usb.deviceId.dwVendorId, e->u.Usb.deviceId.dwProductId, e->u.Usb.dwUniqueID, e->dwEventVer, e->dwNumMatchTables);
471 for (i = 0; i < e->dwNumMatchTables; i++)
472 fprintf(stderr,"match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", e->matchTables[i].VendorId, e->matchTables[i].ProductId, e->matchTables[i].bDeviceClass, e->matchTables[i].bDeviceSubClass, e->matchTables[i].bInterfaceClass, e->matchTables[i].bInterfaceSubClass, e->matchTables[i].bInterfaceProtocol);
473 #endif
474 }
475 break;
476
477 case TRANSFER:
478 fprintf(stderr,"TRANSFER\n");
479 #ifndef NO_WINDRVR
480 ret = (*ioctl_func) (fd, request, wdioctl);
481 #endif
482 break;
483
484 case EVENT_UNREGISTER:
485 #ifdef DEBUG
486 fprintf(stderr,"EVENT_UNREGISTER\n");
487 #endif
488 #ifndef NO_WINDRVR
489 ret = (*ioctl_func) (fd, request, wdioctl);
490 #endif
491 break;
492
493 case INT_WAIT:
494 #ifdef DEBUG
495 fprintf(stderr,"INT_WAIT\n");
496 #endif
497 {
498 struct interrupt *it = (struct interrupt*)(wdheader->data);
499
500 #ifdef DEBUG
501 fprintf(stderr,"Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped);
502 #endif
503
504 #ifndef NO_WINDRVR
505 ret = (*ioctl_func) (fd, request, wdioctl);
506 #else
507 if (usbdevice) {
508 if (it->dwCounter == 0) {
509 it->dwCounter = 1;
510 } else {
511 while(ints_enabled) {sleep(1);}
512 }
513 } else {
514 while(ints_enabled) {sleep(1);}
515 }
516 #endif
517
518 #ifdef DEBUG
519 fprintf(stderr,"INT_WAIT_RETURN: Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped);
520 #endif
521 }
522 break;
523
524 case CARD_UNREGISTER:
525 fprintf(stderr,"CARD_UNREGISTER\n");
526 #ifndef NO_WINDRVR
527 ret = (*ioctl_func) (fd, request, wdioctl);
528 #endif
529 break;
530
531 case EVENT_PULL:
532 #ifdef DEBUG
533 fprintf(stderr,"EVENT_PULL\n");
534 #endif
535 {
536 struct event *e = (struct event*)(wdheader->data);
537 #ifdef DEBUG
538 int i;
539
540 fprintf(stderr,"handle: %lu, action: %lu, status: %lu, eventid: %lu, cardtype: %lx, kplug: %lu, options: %lu, dev: %lx:%lx, unique: %lu, ver: %lu, nummatch: %lu\n", e->handle, e->dwAction, e->dwStatus, e->dwEventId, e->dwCardType, e->hKernelPlugIn, e->dwOptions, e->u.Usb.deviceId.dwVendorId, e->u.Usb.deviceId.dwProductId, e->u.Usb.dwUniqueID, e->dwEventVer, e->dwNumMatchTables);
541 for (i = 0; i < e->dwNumMatchTables; i++)
542 fprintf(stderr,"match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", e->matchTables[i].VendorId, e->matchTables[i].ProductId, e->matchTables[i].bDeviceClass, e->matchTables[i].bDeviceSubClass, e->matchTables[i].bInterfaceClass, e->matchTables[i].bInterfaceSubClass, e->matchTables[i].bInterfaceProtocol);
543 #endif
544
545 #ifndef NO_WINDRVR
546 ret = (*ioctl_func) (fd, request, wdioctl);
547 #else
548 if (usbdevice) {
549 struct usb_interface *interface = usbdevice->config->interface;
550
551 e->dwCardType = card_type;
552 e->dwAction = 1;
553 e->dwEventId = 109;
554 e->u.Usb.dwUniqueID = 110;
555 e->matchTables[0].VendorId = usbdevice->descriptor.idVendor;
556 e->matchTables[0].ProductId = usbdevice->descriptor.idProduct;
557 e->matchTables[0].bDeviceClass = usbdevice->descriptor.bDeviceClass;
558 e->matchTables[0].bDeviceSubClass = usbdevice->descriptor.bDeviceSubClass;
559 e->matchTables[0].bInterfaceClass = interface->altsetting[0].bInterfaceClass;
560 e->matchTables[0].bInterfaceSubClass = interface->altsetting[0].bInterfaceSubClass;
561 e->matchTables[0].bInterfaceProtocol = interface->altsetting[0].bInterfaceProtocol;
562 }
563 #endif
564
565 #ifdef DEBUG
566 fprintf(stderr,"handle: %lu, action: %lu, status: %lu, eventid: %lu, cardtype: %lx, kplug: %lu, options: %lu, dev: %lx:%lx, unique: %lu, ver: %lu, nummatch: %lu\n", e->handle, e->dwAction, e->dwStatus, e->dwEventId, e->dwCardType, e->hKernelPlugIn, e->dwOptions, e->u.Usb.deviceId.dwVendorId, e->u.Usb.deviceId.dwProductId, e->u.Usb.dwUniqueID, e->dwEventVer, e->dwNumMatchTables);
567 for (i = 0; i < e->dwNumMatchTables; i++)
568 fprintf(stderr,"match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", e->matchTables[i].VendorId, e->matchTables[i].ProductId, e->matchTables[i].bDeviceClass, e->matchTables[i].bDeviceSubClass, e->matchTables[i].bInterfaceClass, e->matchTables[i].bInterfaceSubClass, e->matchTables[i].bInterfaceProtocol);
569 #endif
570
571 }
572 break;
573
574 default:
575 fprintf(stderr,"!!!Unsupported IOCTL: %x!!!\n", request);
576 #ifndef NO_WINDRVR
577 ret = (*ioctl_func) (fd, request, wdioctl);
578 #endif
579 break;
580 }
581
582 return ret;
583 }
584
585 int ioctl(int fd, int request, ...)
586 {
587 va_list args;
588 void *argp;
589 int ret;
590
591 if (!ioctl_func)
592 ioctl_func = (int (*) (int, int, void *)) dlsym (REAL_LIBC, "ioctl");
593
594 va_start (args, request);
595 argp = va_arg (args, void *);
596 va_end (args);
597
598 if (fd == windrvrfd)
599 ret = do_wdioctl(fd, request, argp);
600 else
601 ret = (*ioctl_func) (fd, request, argp);
602
603 return ret;
604 }
605
606 typedef int (*open_funcptr_t) (const char *, int, mode_t);
607
608 int open (const char *pathname, int flags, ...)
609 {
610 static open_funcptr_t func = NULL;
611 mode_t mode = 0;
612 va_list args;
613 int fd;
614
615 if (!func)
616 func = (open_funcptr_t) dlsym (REAL_LIBC, "open");
617
618 if (flags & O_CREAT) {
619 va_start(args, flags);
620 mode = va_arg(args, mode_t);
621 va_end(args);
622 }
623
624 if (!strcmp (pathname, "/dev/windrvr6")) {
625 #ifdef DEBUG
626 fprintf(stderr,"opening windrvr6\n");
627 #endif
628 #ifdef NO_WINDRVR
629 windrvrfd = fd = (*func) ("/dev/null", flags, mode);
630 #else
631 windrvrfd = fd = (*func) (pathname, flags, mode);
632 #endif
633 if (!busses) {
634 usb_init();
635 usb_find_busses();
636 usb_find_devices();
637
638 busses = usb_get_busses();
639 }
640
641 return fd;
642 }
643
644 return (*func) (pathname, flags, mode);
645 }
646
647 int close(int fd) {
648 static int (*func) (int) = NULL;
649
650 if (!func)
651 func = (int (*) (int)) dlsym(REAL_LIBC, "close");
652
653 if (fd == windrvrfd) {
654 #ifdef DEBUG
655 fprintf(stderr,"close windrvrfd\n");
656 #endif
657 windrvrfd = 0;
658 }
659
660 return (*func) (fd);
661 }
662
663 FILE *fopen(const char *path, const char *mode) {
664 FILE *ret;
665 static FILE* (*func) (const char*, const char*) = NULL;
666
667 if (!func)
668 func = (FILE* (*) (const char*, const char*)) dlsym(REAL_LIBC, "fopen");
669
670 ret = (*func) (path, mode);
671
672 if (!strcmp (path, "/proc/modules")) {
673 #ifdef DEBUG
674 fprintf(stderr,"opening /proc/modules\n");
675 #endif
676 #ifdef NO_WINDRVR
677 modulesfp = ret;
678 modules_read = 0;
679 #endif
680 }
681
682 return ret;
683 }
684
685 char *fgets(char *s, int size, FILE *stream) {
686 static char* (*func) (char*, int, FILE*) = NULL;
687 const char modules[] = "windrvr6 160960 0 - Live 0xf98b0000\n";
688 char *ret = NULL;
689
690
691 if (!func)
692 func = (char* (*) (char*, int, FILE*)) dlsym(REAL_LIBC, "fgets");
693
694 if (modulesfp == stream) {
695 if (!modules_read) {
696 strcpy(s, modules);
697 ret = s;
698 modules_read = 1;
699 }
700 } else {
701 ret = (*func)(s,size,stream);
702 }
703
704 return ret;
705 }
706
707 int fclose(FILE *fp) {
708 static int (*func) (FILE*) = NULL;
709
710 if (!func)
711 func = (int (*) (FILE*)) dlsym(REAL_LIBC, "fclose");
712
713 if (fp == modulesfp) {
714 modulesfp = NULL;
715 }
716
717 return (*func)(fp);
718 }
719 #endif
Impressum, Datenschutz