emulate /proc/modules, too
[usb-driver] / usb-driver.c
CommitLineData
cdc711dc 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>
f10480d1 21#include <usb.h>
2a7af812 22#include <signal.h>
da3ba95a 23#include "xilinx.h"
cdc711dc 24
9c9fd67c 25static int (*ioctl_func) (int, int, void *) = NULL;
2c2119eb 26static int windrvrfd = 0;
dbda1264 27FILE *modulesfp;
723d9aa0 28static int modules_read = 0;
f10480d1 29static struct usb_bus *busses = NULL;
2a7af812 30static struct usb_device *usbdevice;
31static usb_dev_handle *usb_devhandle = NULL;
292160ed 32static unsigned long card_type;
ca18111b 33static int ints_enabled = 0;
292160ed 34
795992ad 35#define NO_WINDRVR 1
723d9aa0 36#undef DEBUG
37
38void 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}
cdc711dc 47
f95f1d2e 48int usb_deviceinfo(unsigned char *buf) {
49 int i,j,k,l;
50 int len = 0;
3664a3e3 51 WDU_CONFIGURATION **pConfigs, **pActiveConfig;
52 WDU_INTERFACE **pActiveInterface;
f95f1d2e 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);
2a7af812 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;
f95f1d2e 71
72 /* TODO: Fix Pipe0! */
73 udi->Pipe0.dwNumber = 0x00;
2a7af812 74 udi->Pipe0.dwMaximumPacketSize = usbdevice->descriptor.bMaxPacketSize0;
f95f1d2e 75 udi->Pipe0.type = 0;
76 udi->Pipe0.direction = 3;
77 udi->Pipe0.dwInterval = 0;
3664a3e3 78
79 pConfigs = &(udi->pConfigs);
80 pActiveConfig = &(udi->pActiveConfig);
81 pActiveInterface = &(udi->pActiveInterface[0]);
f95f1d2e 82 }
83
84 len = sizeof(struct usb_device_info);
85
2a7af812 86 for (i=0; i<usbdevice->descriptor.bNumConfigurations; i++)
f95f1d2e 87 {
2a7af812 88 struct usb_config_descriptor *conf_desc = &usbdevice->config[i];
3664a3e3 89 WDU_INTERFACE **pInterfaces;
90 WDU_ALTERNATE_SETTING **pAlternateSettings[conf_desc->bNumInterfaces];
91 WDU_ALTERNATE_SETTING **pActiveAltSetting[conf_desc->bNumInterfaces];
92
f95f1d2e 93 if (buf) {
94 WDU_CONFIGURATION *cfg = (WDU_CONFIGURATION*)(buf+len);
95
3664a3e3 96 *pConfigs = cfg;
97 *pActiveConfig = cfg;
98
f95f1d2e 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;
3664a3e3 109
110 pInterfaces = &(cfg->pInterfaces);
f95f1d2e 111 }
112 len += sizeof(WDU_CONFIGURATION);
3664a3e3 113
f95f1d2e 114 if (buf) {
3664a3e3 115 *pInterfaces = (WDU_INTERFACE*)(buf+len);
f95f1d2e 116 for (j=0; j<conf_desc->bNumInterfaces; j++) {
117 WDU_INTERFACE *iface = (WDU_INTERFACE*)(buf+len);
3664a3e3 118
119 pActiveInterface[j] = iface;
120
121 pAlternateSettings[j] = &(iface->pAlternateSettings);
2a7af812 122 iface->dwNumAltSettings = usbdevice->config[i].interface[j].num_altsetting;
3664a3e3 123 pActiveAltSetting[j] = &(iface->pActiveAltSetting);
f95f1d2e 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 {
2a7af812 133 struct usb_interface *interface = &usbdevice->config[i].interface[j];
3664a3e3 134
135 if (buf) {
136 *pAlternateSettings[j] = (WDU_ALTERNATE_SETTING*)(buf+len);
137 /* FIXME: */
138 *pActiveAltSetting[j] = (WDU_ALTERNATE_SETTING*)(buf+len);
139 }
140
f95f1d2e 141 for(k=0; k<interface->num_altsetting; k++)
142 {
3664a3e3 143 unsigned char bNumEndpoints = interface->altsetting[k].bNumEndpoints;
144 WDU_ENDPOINT_DESCRIPTOR **pEndpointDescriptors;
145 WDU_PIPE_INFO **pPipes;
146
f95f1d2e 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;
3664a3e3 159 pEndpointDescriptors = &(altset->pEndpointDescriptors);
160 pPipes = &(altset->pPipes);
f95f1d2e 161
162 }
163 len +=sizeof(WDU_ALTERNATE_SETTING);
164
165 if (buf) {
3664a3e3 166 *pEndpointDescriptors = (WDU_ENDPOINT_DESCRIPTOR*)(buf+len);
f95f1d2e 167 for (l = 0; l < bNumEndpoints; l++) {
168 WDU_ENDPOINT_DESCRIPTOR *ed = (WDU_ENDPOINT_DESCRIPTOR*)(buf+len);
f95f1d2e 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);
792bf5f2 178 }
f95f1d2e 179
3664a3e3 180 *pPipes = (WDU_PIPE_INFO*)(buf+len);
792bf5f2 181 for (l = 0; l < bNumEndpoints; l++) {
182 WDU_PIPE_INFO *pi = (WDU_PIPE_INFO*)(buf+len);
f95f1d2e 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
9c9fd67c 208int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) {
cdc711dc 209 struct header_struct* wdheader = (struct header_struct*)wdioctl;
9c9fd67c 210 struct version_struct *version;
211 int ret = 0;
cdc711dc 212
da3ba95a 213 if (wdheader->magic != MAGIC) {
2c2119eb 214 fprintf(stderr,"!!!ERROR: magic header does not match!!!\n");
215 return (*ioctl_func) (fd, request, wdioctl);
cdc711dc 216 }
217
cdc711dc 218 switch(request) {
da3ba95a 219 case VERSION:
9c9fd67c 220 version = (struct version_struct*)(wdheader->data);
221 strcpy(version->version, "WinDriver no more");
222 version->versionul = 999;
723d9aa0 223#ifdef DEBUG
9c9fd67c 224 fprintf(stderr,"faking VERSION\n");
723d9aa0 225#endif
cdc711dc 226 break;
2c2119eb 227
228 case LICENSE:
723d9aa0 229#ifdef DEBUG
2c2119eb 230 fprintf(stderr,"faking LICENSE\n");
723d9aa0 231#endif
2c2119eb 232 break;
233
9c9fd67c 234 case CARD_REGISTER:
235 {
2c2119eb 236 //struct card_register* cr = (struct card_register*)(wdheader->data);
9c9fd67c 237 /* Todo: LPT-Port already in use */
238 }
723d9aa0 239#ifdef DEBUG
9c9fd67c 240 fprintf(stderr,"faking CARD_REGISTER\n");
723d9aa0 241#endif
da3ba95a 242 break;
2c2119eb 243
da3ba95a 244 case USB_TRANSFER:
723d9aa0 245#ifdef DEBUG
9c9fd67c 246 fprintf(stderr,"in USB_TRANSFER");
723d9aa0 247#endif
da3ba95a 248 {
249 struct usb_transfer *ut = (struct usb_transfer*)(wdheader->data);
250
723d9aa0 251#ifdef DEBUG
2c2119eb 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);
9c9fd67c 253 fprintf(stderr,"setup packet: ");
254 hexdump(ut->SetupPacket, 8);
255 fprintf(stderr,"\n");
723d9aa0 256
9c9fd67c 257 if (!ut->fRead && ut->dwBufferSize)
258 {
259 hexdump(ut->pBuffer, ut->dwBufferSize);
260 fprintf(stderr,"\n");
261 }
723d9aa0 262#endif
9c9fd67c 263
795992ad 264#ifndef NO_WINDRVR
9c9fd67c 265 ret = (*ioctl_func) (fd, request, wdioctl);
411af373 266#else
267 /* http://www.jungo.com/support/documentation/windriver/802/wdusb_man_mhtml/node55.html#SECTION001213000000000000000 */
a70f4f38 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);
723d9aa0 275#ifdef DEBUG
a70f4f38 276 fprintf(stderr, "requesttype: %x, request: %x, value: %u, index: %u, size: %u\n", requesttype, request, value, index, size);
723d9aa0 277#endif
a70f4f38 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
411af373 288 if (ret < 0) {
a70f4f38 289 fprintf(stderr, "usb_transfer: %d (%s)\n", ret, usb_strerror());
411af373 290 } else {
291 ut->dwBytesTransferred = ret;
292 ret = 0;
293 }
292160ed 294#endif
9c9fd67c 295
723d9aa0 296#ifdef DEBUG
2c2119eb 297 fprintf(stderr,"Transferred: %lu (%s)\n",ut->dwBytesTransferred, (ut->fRead?"read":"write"));
9c9fd67c 298 if (ut->fRead && ut->dwBytesTransferred)
299 {
300 fprintf(stderr,"Read: ");
301 hexdump(ut->pBuffer, ut->dwBytesTransferred);
ca18111b 302 fprintf(stderr,"\n");
9c9fd67c 303 }
723d9aa0 304#endif
da3ba95a 305 }
cdc711dc 306 break;
2c2119eb 307
da3ba95a 308 case INT_ENABLE:
723d9aa0 309#ifdef DEBUG
ca18111b 310 fprintf(stderr,"INT_ENABLE\n");
723d9aa0 311#endif
da3ba95a 312 {
9c9fd67c 313 struct interrupt *it = (struct interrupt*)(wdheader->data);
cdc711dc 314
723d9aa0 315#ifdef DEBUG
53f639f2 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);
723d9aa0 317#endif
cdc711dc 318
9c9fd67c 319 it->fEnableOk = 1;
ca18111b 320 ints_enabled = 1;
9c9fd67c 321 //ret = (*ioctl_func) (fd, request, wdioctl);
322 }
cdc711dc 323
cdc711dc 324 break;
9c9fd67c 325
da3ba95a 326 case INT_DISABLE:
723d9aa0 327#ifdef DEBUG
9c9fd67c 328 fprintf(stderr,"INT_DISABLE\n");
723d9aa0 329#endif
da3ba95a 330 {
9c9fd67c 331 struct interrupt *it = (struct interrupt*)(wdheader->data);
da3ba95a 332
723d9aa0 333#ifdef DEBUG
53f639f2 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);
723d9aa0 335#endif
795992ad 336#ifndef NO_WINDRVR
9c9fd67c 337 ret = (*ioctl_func) (fd, request, wdioctl);
e71b6bf3 338#else
339 it->dwCounter = 0;
340 it->fStopped = 1;
ca18111b 341 ints_enabled = 0;
292160ed 342#endif
723d9aa0 343#ifdef DEBUG
53f639f2 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);
723d9aa0 345#endif
da3ba95a 346 }
da3ba95a 347 break;
da3ba95a 348
9c9fd67c 349 case USB_SET_INTERFACE:
723d9aa0 350#ifdef DEBUG
9c9fd67c 351 fprintf(stderr,"USB_SET_INTERFACE\n");
723d9aa0 352#endif
da3ba95a 353 {
9c9fd67c 354 struct usb_set_interface *usi = (struct usb_set_interface*)(wdheader->data);
355
723d9aa0 356#ifdef DEBUG
2c2119eb 357 fprintf(stderr,"unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", usi->dwUniqueID, usi->dwInterfaceNum, usi->dwAlternateSetting, usi->dwOptions);
723d9aa0 358#endif
795992ad 359#ifndef NO_WINDRVR
9c9fd67c 360 ret = (*ioctl_func) (fd, request, wdioctl);
2a7af812 361#else
362 if (usbdevice) {
2a7af812 363 if (!usb_devhandle)
364 usb_devhandle = usb_open(usbdevice);
d0676964 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) {
411af373 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 }
d0676964 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 }
2a7af812 380 }
292160ed 381#endif
723d9aa0 382#ifdef DEBUG
2a7af812 383 fprintf(stderr,"unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", usi->dwUniqueID, usi->dwInterfaceNum, usi->dwAlternateSetting, usi->dwOptions);
723d9aa0 384#endif
da3ba95a 385 }
cdc711dc 386 break;
da3ba95a 387
9c9fd67c 388 case USB_GET_DEVICE_DATA:
723d9aa0 389#ifdef DEBUG
ca18111b 390 fprintf(stderr,"faking USB_GET_DEVICE_DATA\n");
723d9aa0 391#endif
9c9fd67c 392 {
393 struct usb_get_device_data *ugdd = (struct usb_get_device_data*)(wdheader->data);
394 int pSize;
395
723d9aa0 396#ifdef DEBUG
e71b6bf3 397 fprintf(stderr, "unique: %lu, bytes: %lu, options: %lx\n", ugdd->dwUniqueID, ugdd->dwBytes, ugdd->dwOptions);
723d9aa0 398#endif
9c9fd67c 399 pSize = ugdd->dwBytes;
ca18111b 400 //ret = (*ioctl_func) (fd, request, wdioctl);
e71b6bf3 401 if (!ugdd->dwBytes) {
2a7af812 402 if (usbdevice) {
f95f1d2e 403 ugdd->dwBytes = usb_deviceinfo(NULL);
e71b6bf3 404 }
405 } else {
f95f1d2e 406 usb_deviceinfo((unsigned char*)ugdd->pBuf);
e71b6bf3 407 }
da3ba95a 408 }
9c9fd67c 409 break;
410
b0f621dd 411 case EVENT_REGISTER:
723d9aa0 412#ifdef DEBUG
b0f621dd 413 fprintf(stderr,"EVENT_REGISTER\n");
723d9aa0 414#endif
b0f621dd 415 {
416 struct event *e = (struct event*)(wdheader->data);
ac22d975 417 struct usb_bus *bus;
b0f621dd 418 int i;
419
723d9aa0 420#ifdef DEBUG
b0f621dd 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);
723d9aa0 422#endif
ac22d975 423 for (i = 0; i < e->dwNumMatchTables; i++) {
723d9aa0 424#ifdef DEBUG
e71b6bf3 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);
723d9aa0 426#endif
b0f621dd 427
ac22d975 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)) {
2a7af812 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++) {
723d9aa0 444#ifdef DEBUG
2a7af812 445 fprintf(stderr, "intclass: %x, intsubclass: %x, intproto: %x\n", interface->altsetting[i].bInterfaceClass, interface->altsetting[i].bInterfaceSubClass, interface->altsetting[i].bInterfaceProtocol);
723d9aa0 446#endif
2a7af812 447 if ((interface->altsetting[ai].bInterfaceSubClass == e->matchTables[i].bInterfaceSubClass) &&
448 (interface->altsetting[ai].bInterfaceProtocol == e->matchTables[i].bInterfaceProtocol)){
449 /* TODO: check interfaceClass! */
723d9aa0 450#ifdef DEBUG
2a7af812 451 fprintf(stderr,"!!!FOUND DEVICE WITH LIBUSB!!!\n");
723d9aa0 452#endif
2a7af812 453 usbdevice = dev;
454 card_type = e->dwCardType;
455 }
456 }
457 }
ac22d975 458 }
459 }
460 }
461 }
462
795992ad 463#ifndef NO_WINDRVR
b0f621dd 464 ret = (*ioctl_func) (fd, request, wdioctl);
2a7af812 465#else
2a7af812 466 e->handle++;
292160ed 467#endif
b0f621dd 468
723d9aa0 469#ifdef DEBUG
b0f621dd 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++)
e71b6bf3 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);
723d9aa0 473#endif
b0f621dd 474 }
475 break;
476
da3ba95a 477 case TRANSFER:
9c9fd67c 478 fprintf(stderr,"TRANSFER\n");
795992ad 479#ifndef NO_WINDRVR
9c9fd67c 480 ret = (*ioctl_func) (fd, request, wdioctl);
292160ed 481#endif
9c9fd67c 482 break;
483
da3ba95a 484 case EVENT_UNREGISTER:
723d9aa0 485#ifdef DEBUG
9c9fd67c 486 fprintf(stderr,"EVENT_UNREGISTER\n");
723d9aa0 487#endif
795992ad 488#ifndef NO_WINDRVR
9c9fd67c 489 ret = (*ioctl_func) (fd, request, wdioctl);
292160ed 490#endif
9c9fd67c 491 break;
492
da3ba95a 493 case INT_WAIT:
723d9aa0 494#ifdef DEBUG
9c9fd67c 495 fprintf(stderr,"INT_WAIT\n");
723d9aa0 496#endif
b0f621dd 497 {
498 struct interrupt *it = (struct interrupt*)(wdheader->data);
499
723d9aa0 500#ifdef DEBUG
53f639f2 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);
723d9aa0 502#endif
b0f621dd 503
795992ad 504#ifndef NO_WINDRVR
b0f621dd 505 ret = (*ioctl_func) (fd, request, wdioctl);
292160ed 506#else
2a7af812 507 if (usbdevice) {
508 if (it->dwCounter == 0) {
509 it->dwCounter = 1;
510 } else {
ca18111b 511 while(ints_enabled) {sleep(1);}
2a7af812 512 }
94038a57 513 } else {
ca18111b 514 while(ints_enabled) {sleep(1);}
2a7af812 515 }
292160ed 516#endif
517
723d9aa0 518#ifdef DEBUG
ca18111b 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);
723d9aa0 520#endif
b0f621dd 521 }
9c9fd67c 522 break;
523
da3ba95a 524 case CARD_UNREGISTER:
9c9fd67c 525 fprintf(stderr,"CARD_UNREGISTER\n");
795992ad 526#ifndef NO_WINDRVR
9c9fd67c 527 ret = (*ioctl_func) (fd, request, wdioctl);
292160ed 528#endif
9c9fd67c 529 break;
530
da3ba95a 531 case EVENT_PULL:
723d9aa0 532#ifdef DEBUG
9c9fd67c 533 fprintf(stderr,"EVENT_PULL\n");
723d9aa0 534#endif
b1831983 535 {
536 struct event *e = (struct event*)(wdheader->data);
723d9aa0 537#ifdef DEBUG
b1831983 538 int i;
539
2a7af812 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);
b1831983 541 for (i = 0; i < e->dwNumMatchTables; i++)
e71b6bf3 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);
723d9aa0 543#endif
b1831983 544
795992ad 545#ifndef NO_WINDRVR
b1831983 546 ret = (*ioctl_func) (fd, request, wdioctl);
292160ed 547#else
2a7af812 548 if (usbdevice) {
549 struct usb_interface *interface = usbdevice->config->interface;
292160ed 550
551 e->dwCardType = card_type;
552 e->dwAction = 1;
553 e->dwEventId = 109;
ca18111b 554 e->u.Usb.dwUniqueID = 110;
2a7af812 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;
292160ed 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
b1831983 564
723d9aa0 565#ifdef DEBUG
2a7af812 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);
b1831983 567 for (i = 0; i < e->dwNumMatchTables; i++)
e71b6bf3 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);
723d9aa0 569#endif
ca18111b 570
b1831983 571 }
9c9fd67c 572 break;
573
da3ba95a 574 default:
292160ed 575 fprintf(stderr,"!!!Unsupported IOCTL: %x!!!\n", request);
795992ad 576#ifndef NO_WINDRVR
9c9fd67c 577 ret = (*ioctl_func) (fd, request, wdioctl);
292160ed 578#endif
579 break;
cdc711dc 580 }
da3ba95a 581
9c9fd67c 582 return ret;
cdc711dc 583}
584
dbda1264 585int 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}
cdc711dc 605
606typedef int (*open_funcptr_t) (const char *, int, mode_t);
607
cdc711dc 608int 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
cdc711dc 624 if (!strcmp (pathname, "/dev/windrvr6")) {
723d9aa0 625#ifdef DEBUG
cdc711dc 626 fprintf(stderr,"opening windrvr6\n");
723d9aa0 627#endif
795992ad 628#ifdef NO_WINDRVR
01b99d52 629 windrvrfd = fd = (*func) ("/dev/null", flags, mode);
630#else
631 windrvrfd = fd = (*func) (pathname, flags, mode);
632#endif
f10480d1 633 if (!busses) {
634 usb_init();
635 usb_find_busses();
636 usb_find_devices();
637
638 busses = usb_get_busses();
639 }
723d9aa0 640
641 return fd;
cdc711dc 642 }
643
723d9aa0 644 return (*func) (pathname, flags, mode);
cdc711dc 645}
646
723d9aa0 647int close(int fd) {
648 static int (*func) (int) = NULL;
cdc711dc 649
723d9aa0 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;
cdc711dc 658 }
cdc711dc 659
723d9aa0 660 return (*func) (fd);
cdc711dc 661}
662
723d9aa0 663FILE *fopen(const char *path, const char *mode) {
664 FILE *ret;
665 static FILE* (*func) (const char*, const char*) = NULL;
ca18111b 666
667 if (!func)
723d9aa0 668 func = (FILE* (*) (const char*, const char*)) dlsym(REAL_LIBC, "fopen");
ca18111b 669
723d9aa0 670 ret = (*func) (path, mode);
ca18111b 671
723d9aa0 672 if (!strcmp (path, "/proc/modules")) {
673#ifdef DEBUG
674 fprintf(stderr,"opening /proc/modules\n");
675#endif
676#ifdef NO_WINDRVR
dbda1264 677 modulesfp = ret;
723d9aa0 678 modules_read = 0;
679#endif
680 }
cdc711dc 681
682 return ret;
683}
684
dbda1264 685char *fgets(char *s, int size, FILE *stream) {
686 static char* (*func) (char*, int, FILE*) = NULL;
723d9aa0 687 const char modules[] = "windrvr6 160960 0 - Live 0xf98b0000\n";
dbda1264 688 char *ret = NULL;
689
cdc711dc 690
691 if (!func)
dbda1264 692 func = (char* (*) (char*, int, FILE*)) dlsym(REAL_LIBC, "fgets");
723d9aa0 693
dbda1264 694 if (modulesfp == stream) {
695 if (!modules_read) {
696 strcpy(s, modules);
697 ret = s;
698 modules_read = 1;
699 }
723d9aa0 700 } else {
dbda1264 701 ret = (*func)(s,size,stream);
723d9aa0 702 }
cdc711dc 703
704 return ret;
705}
706
dbda1264 707int fclose(FILE *fp) {
708 static int (*func) (FILE*) = NULL;
cdc711dc 709
dbda1264 710 if (!func)
711 func = (int (*) (FILE*)) dlsym(REAL_LIBC, "fclose");
cdc711dc 712
dbda1264 713 if (fp == modulesfp) {
714 modulesfp = NULL;
715 }
716
717 return (*func)(fp);
cdc711dc 718}
da3ba95a 719#endif
Impressum, Datenschutz