NCC clean newCell
[fleet.git] / misc / usb-driver.c
1 /* libusb/ppdev connector for XILINX impact
2  *
3  * Copyright (c) 2007 Michael Gernoth <michael@gernoth.net>
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to
7  * deal in the Software without restriction, including without limitation the
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9  * sell copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23
24 #define _GNU_SOURCE 1
25
26 #include <dlfcn.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/time.h>
35 #include <stdio.h>
36 #include <usb.h>
37 #include <signal.h>
38 #include <pthread.h>
39 #include <errno.h>
40 #include <inttypes.h>
41 #include <sys/ioctl.h>
42 #include "usb-driver.h"
43 #include "config.h"
44
45 static int (*ioctl_func) (int, int, void *) = NULL;
46 static int windrvrfd = -1;
47 static unsigned long ppbase = 0;
48 static unsigned long ecpbase = 0;
49 static struct parport_config *pport = NULL;
50 static FILE *modulesfp = NULL;
51 static FILE *baseaddrfp = NULL;
52 static int baseaddrnum = 0;
53 static int modules_read = 0;
54 static struct usb_bus *busses = NULL;
55 static struct usb_device *usbdevice;
56 static usb_dev_handle *usb_devhandle = NULL;
57 static int usbinterface = -1;
58 static unsigned long card_type;
59 static int ints_enabled = 0;
60 static pthread_mutex_t int_wait = PTHREAD_MUTEX_INITIALIZER;
61
62 #define NO_WINDRVR 1
63
64 void hexdump(unsigned char *buf, int len) {
65         int i;
66
67         for(i=0; i<len; i++) {
68                 fprintf(stderr,"%02x ", buf[i]);
69                 if ((i % 16) == 15)
70                         fprintf(stderr,"\n");
71         }
72         fprintf(stderr,"\n");
73 }
74
75 static int usb_deviceinfo(unsigned char *buf) {
76         int i,j,k,l;
77         int len = 0;
78         WDU_CONFIGURATION **pConfigs, **pActiveConfig;
79         WDU_INTERFACE **pActiveInterface;
80
81         if (buf) {
82                 struct usb_device_info *udi = (struct usb_device_info*)(buf+len);
83
84                 udi->Descriptor.bLength = sizeof(WDU_DEVICE_DESCRIPTOR);
85                 udi->Descriptor.bDescriptorType = usbdevice->descriptor.bDescriptorType;
86                 udi->Descriptor.bcdUSB = usbdevice->descriptor.bcdUSB;
87                 udi->Descriptor.bDeviceClass = usbdevice->descriptor.bDeviceClass;
88                 udi->Descriptor.bDeviceSubClass = usbdevice->descriptor.bDeviceSubClass;
89                 udi->Descriptor.bDeviceProtocol = usbdevice->descriptor.bDeviceProtocol;
90                 udi->Descriptor.bMaxPacketSize0 = usbdevice->descriptor.bMaxPacketSize0;
91                 udi->Descriptor.idVendor = usbdevice->descriptor.idVendor;
92                 udi->Descriptor.idProduct = usbdevice->descriptor.idProduct;
93                 udi->Descriptor.bcdDevice = usbdevice->descriptor.bcdDevice;
94                 udi->Descriptor.iManufacturer = usbdevice->descriptor.iManufacturer;
95                 udi->Descriptor.iProduct = usbdevice->descriptor.iProduct;
96                 udi->Descriptor.iSerialNumber = usbdevice->descriptor.iSerialNumber;
97                 udi->Descriptor.bNumConfigurations = usbdevice->descriptor.bNumConfigurations;
98
99                 /* TODO: Fix Pipe0! */
100                 udi->Pipe0.dwNumber = 0x00;
101                 udi->Pipe0.dwMaximumPacketSize = usbdevice->descriptor.bMaxPacketSize0;
102                 udi->Pipe0.type = 0;
103                 udi->Pipe0.direction = WDU_DIR_IN_OUT;
104                 udi->Pipe0.dwInterval = 0;
105
106                 pConfigs = &(udi->pConfigs);
107                 pActiveConfig = &(udi->pActiveConfig);
108                 pActiveInterface = &(udi->pActiveInterface[0]);
109         }
110
111         len = sizeof(struct usb_device_info);
112
113         for (i=0; i<usbdevice->descriptor.bNumConfigurations; i++)
114         {
115                 struct usb_config_descriptor *conf_desc = &usbdevice->config[i];
116                 WDU_INTERFACE **pInterfaces;
117                 WDU_ALTERNATE_SETTING **pAlternateSettings[conf_desc->bNumInterfaces];
118                 WDU_ALTERNATE_SETTING **pActiveAltSetting[conf_desc->bNumInterfaces];
119
120                 if (buf) {
121                         WDU_CONFIGURATION *cfg = (WDU_CONFIGURATION*)(buf+len);
122
123                         *pConfigs = cfg;
124                         *pActiveConfig = cfg;
125
126                         cfg->Descriptor.bLength = conf_desc->bLength;
127                         cfg->Descriptor.bDescriptorType = conf_desc->bDescriptorType;
128                         cfg->Descriptor.wTotalLength = conf_desc->wTotalLength;
129                         cfg->Descriptor.bNumInterfaces = conf_desc->bNumInterfaces;
130                         cfg->Descriptor.bConfigurationValue = conf_desc->bConfigurationValue;
131                         cfg->Descriptor.iConfiguration = conf_desc->iConfiguration;
132                         cfg->Descriptor.bmAttributes = conf_desc->bmAttributes;
133                         cfg->Descriptor.MaxPower = conf_desc->MaxPower;
134
135                         cfg->dwNumInterfaces = conf_desc->bNumInterfaces;
136
137                         pInterfaces = &(cfg->pInterfaces);
138                 }
139                 len += sizeof(WDU_CONFIGURATION);
140
141                 if (buf) {
142                         *pInterfaces = (WDU_INTERFACE*)(buf+len);
143                         for (j=0; j<conf_desc->bNumInterfaces; j++) {
144                                 WDU_INTERFACE *iface = (WDU_INTERFACE*)(buf+len);
145
146                                 pActiveInterface[j] = iface;
147
148                                 pAlternateSettings[j] = &(iface->pAlternateSettings);
149                                 iface->dwNumAltSettings = usbdevice->config[i].interface[j].num_altsetting;
150                                 pActiveAltSetting[j] = &(iface->pActiveAltSetting);
151
152                                 len += sizeof(WDU_INTERFACE);
153                         }
154                 } else {
155                         len += sizeof(WDU_INTERFACE) * conf_desc->bNumInterfaces;
156                 }
157
158                 for (j=0; j<conf_desc->bNumInterfaces; j++)
159                 {
160                         struct usb_interface *interface = &usbdevice->config[i].interface[j];
161
162                         if (buf) {
163                                 *pAlternateSettings[j] = (WDU_ALTERNATE_SETTING*)(buf+len);
164                                 /* FIXME: */
165                                 *pActiveAltSetting[j] = (WDU_ALTERNATE_SETTING*)(buf+len);
166                         }
167
168                         for(k=0; k<interface->num_altsetting; k++)
169                         {
170                                 unsigned char bNumEndpoints = interface->altsetting[k].bNumEndpoints;
171                                 WDU_ENDPOINT_DESCRIPTOR **pEndpointDescriptors;
172                                 WDU_PIPE_INFO **pPipes;
173
174                                 if (buf) {
175                                         WDU_ALTERNATE_SETTING *altset = (WDU_ALTERNATE_SETTING*)(buf+len);
176
177                                         altset->Descriptor.bLength = interface->altsetting[k].bLength;
178                                         altset->Descriptor.bDescriptorType = interface->altsetting[k].bDescriptorType;
179                                         altset->Descriptor.bInterfaceNumber = interface->altsetting[k].bInterfaceNumber;
180                                         altset->Descriptor.bAlternateSetting = interface->altsetting[k].bAlternateSetting;
181                                         altset->Descriptor.bNumEndpoints = interface->altsetting[k].bNumEndpoints;
182                                         altset->Descriptor.bInterfaceClass = interface->altsetting[k].bInterfaceClass;
183                                         altset->Descriptor.bInterfaceSubClass = interface->altsetting[k].bInterfaceSubClass;
184                                         altset->Descriptor.bInterfaceProtocol = interface->altsetting[k].bInterfaceProtocol;
185                                         altset->Descriptor.iInterface = interface->altsetting[k].iInterface;
186                                         pEndpointDescriptors = &(altset->pEndpointDescriptors);
187                                         pPipes = &(altset->pPipes);
188
189                                 }
190                                 len +=sizeof(WDU_ALTERNATE_SETTING);
191
192                                 if (buf) {
193                                         *pEndpointDescriptors = (WDU_ENDPOINT_DESCRIPTOR*)(buf+len);
194                                         for (l = 0; l < bNumEndpoints; l++) {
195                                                 WDU_ENDPOINT_DESCRIPTOR *ed = (WDU_ENDPOINT_DESCRIPTOR*)(buf+len);
196
197                                                 ed->bLength = interface->altsetting[k].endpoint[l].bLength;
198                                                 ed->bDescriptorType = interface->altsetting[k].endpoint[l].bDescriptorType;
199                                                 ed->bEndpointAddress = interface->altsetting[k].endpoint[l].bEndpointAddress;
200                                                 ed->bmAttributes = interface->altsetting[k].endpoint[l].bmAttributes;
201                                                 ed->wMaxPacketSize = interface->altsetting[k].endpoint[l].wMaxPacketSize;
202                                                 ed->bInterval = interface->altsetting[k].endpoint[l].bInterval;
203
204                                                 len += sizeof(WDU_ENDPOINT_DESCRIPTOR);
205                                         }
206                                                 
207                                         *pPipes = (WDU_PIPE_INFO*)(buf+len);
208                                         for (l = 0; l < bNumEndpoints; l++) {
209                                                 WDU_PIPE_INFO *pi = (WDU_PIPE_INFO*)(buf+len);
210
211                                                 pi->dwNumber = interface->altsetting[k].endpoint[l].bEndpointAddress;
212                                                 pi->dwMaximumPacketSize = WDU_GET_MAX_PACKET_SIZE(interface->altsetting[k].endpoint[l].wMaxPacketSize);
213                                                 pi->type = interface->altsetting[k].endpoint[l].bmAttributes & USB_ENDPOINT_TYPE_MASK;
214                                                 if (pi->type == PIPE_TYPE_CONTROL)
215                                                         pi->direction = WDU_DIR_IN_OUT;
216                                                 else
217                                                 {
218                                                         pi->direction = interface->altsetting[k].endpoint[l].bEndpointAddress & USB_ENDPOINT_DIR_MASK ?  WDU_DIR_IN : WDU_DIR_OUT;
219                                                 }
220
221                                                 pi->dwInterval = interface->altsetting[k].endpoint[l].bInterval;
222
223                                                 len += sizeof(WDU_PIPE_INFO);
224                                         }
225                                 } else {
226                                         len +=(sizeof(WDU_ENDPOINT_DESCRIPTOR)+sizeof(WDU_PIPE_INFO))*bNumEndpoints;
227                                 }
228                         }
229                 }
230         }
231
232         return len;
233 }
234
235 static int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) {
236         struct header_struct* wdheader = (struct header_struct*)wdioctl;
237         struct version_struct *version;
238         int ret = 0;
239
240         if (wdheader->magic != MAGIC) {
241                 fprintf(stderr,"!!!ERROR: magic header does not match!!!\n");
242                 return (*ioctl_func) (fd, request, wdioctl);
243         }
244
245         switch(request & ~(0xc0000000)) {
246                 case VERSION:
247                         version = (struct version_struct*)(wdheader->data);
248                         strcpy(version->version, "libusb-driver.so version: " USB_DRIVER_VERSION);
249                         version->versionul = 802;
250                         DPRINTF("VERSION\n");
251                         break;
252
253                 case LICENSE:
254                         DPRINTF("LICENSE\n");
255                         break;
256
257                 case CARD_REGISTER_OLD:
258                 case CARD_REGISTER:
259                         DPRINTF("CARD_REGISTER\n");
260                         {
261                                 struct card_register* cr = (struct card_register*)(wdheader->data);
262
263                                 DPRINTF("Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n",
264                                 cr->Card.dwItems,
265                                 (unsigned long)cr->Card.Item[0].I.IO.dwAddr,
266                                 cr->Card.Item[0].I.IO.dwBytes,
267                                 cr->Card.Item[0].I.IO.dwBar);
268                                 
269                                 DPRINTF("Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n",
270                                 cr->Card.dwItems,
271                                 (unsigned long)cr->Card.Item[1].I.IO.dwAddr,
272                                 cr->Card.Item[1].I.IO.dwBytes,
273                                 cr->Card.Item[1].I.IO.dwBar);
274 #ifndef NO_WINDRVR
275                                 ret = (*ioctl_func) (fd, request, wdioctl);
276 #else
277
278                                 pport = config_get((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10);
279                                 if (!pport)
280                                         break;
281
282                                 ret = pport->open((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10);
283
284                                 ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr;
285
286                                 if (cr->Card.dwItems > 1 && cr->Card.Item[1].I.IO.dwAddr)
287                                         ecpbase = (unsigned long)cr->Card.Item[1].I.IO.dwAddr;
288
289                                 if (ret >= 0) {
290                                         cr->hCard = ret;
291                                 } else {
292                                         cr->hCard = 0;
293                                 }
294 #endif
295                                 DPRINTF("hCard: %lu\n", cr->hCard);
296                         }
297                         break;
298
299                 case USB_TRANSFER:
300                         DPRINTF("in USB_TRANSFER");
301                         {
302                                 struct usb_transfer *ut = (struct usb_transfer*)(wdheader->data);
303
304 #ifdef DEBUG
305                                 DPRINTF(" unique: %lu, pipe: %lu, read: %lu, options: %lx, size: %lu, timeout: %lx\n",
306                                 ut->dwUniqueID, ut->dwPipeNum, ut->fRead,
307                                 ut->dwOptions, ut->dwBufferSize, ut->dwTimeout);
308                                 DPRINTF("setup packet: ");
309                                 hexdump(ut->SetupPacket, 8);
310
311                                 if (!ut->fRead && ut->dwBufferSize)
312                                 {
313                                         hexdump(ut->pBuffer, ut->dwBufferSize);
314                                 }
315 #endif
316
317 #ifndef NO_WINDRVR
318                                 ret = (*ioctl_func) (fd, request, wdioctl);
319 #else
320                                 /* http://www.jungo.com/support/documentation/windriver/802/wdusb_man_mhtml/node55.html#SECTION001213000000000000000 */
321                                 if (ut->dwPipeNum == 0) { /* control pipe */
322                                         int requesttype, request, value, index, size;
323                                         requesttype = ut->SetupPacket[0];
324                                         request = ut->SetupPacket[1];
325                                         value = ut->SetupPacket[2] | (ut->SetupPacket[3] << 8);
326                                         index = ut->SetupPacket[4] | (ut->SetupPacket[5] << 8);
327                                         size = ut->SetupPacket[6] | (ut->SetupPacket[7] << 8);
328                                         DPRINTF("requesttype: %x, request: %x, value: %u, index: %u, size: %u\n", requesttype, request, value, index, size);
329                                         ret = usb_control_msg(usb_devhandle, requesttype, request, value, index, ut->pBuffer, size, ut->dwTimeout);
330                                 } else {
331                                         if (ut->fRead) {
332                                                 ret = usb_bulk_read(usb_devhandle, ut->dwPipeNum, ut->pBuffer, ut->dwBufferSize, ut->dwTimeout);
333
334                                         } else {
335                                                 ret = usb_bulk_write(usb_devhandle, ut->dwPipeNum, ut->pBuffer, ut->dwBufferSize, ut->dwTimeout);
336                                         }
337                                 }
338
339                                 if (ret < 0) {
340                                         fprintf(stderr, "usb_transfer: %d (%s)\n", ret, usb_strerror());
341                                 } else {
342                                         ut->dwBytesTransferred = ret;
343                                         ret = 0;
344                                 }
345 #endif
346
347 #ifdef DEBUG
348                                 DPRINTF("Transferred: %lu (%s)\n",ut->dwBytesTransferred, (ut->fRead?"read":"write"));
349                                 if (ut->fRead && ut->dwBytesTransferred)
350                                 {
351                                         DPRINTF("Read: ");
352                                         hexdump(ut->pBuffer, ut->dwBytesTransferred);
353                                 }
354 #endif
355                         }
356                         break;
357
358                 case INT_ENABLE_OLD:
359                 case INT_ENABLE:
360                         DPRINTF("INT_ENABLE\n");
361                         {
362                                 struct interrupt *it = (struct interrupt*)(wdheader->data);
363
364                                 DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
365                                 it->hInterrupt, it->dwOptions,
366                                 it->dwCmds, it->fEnableOk, it->dwCounter,
367                                 it->dwLost, it->fStopped);
368
369                                 it->fEnableOk = 1;
370                                 it->fStopped = 0;
371                                 ints_enabled = 1;
372                                 pthread_mutex_trylock(&int_wait);
373                         }
374
375                         break;
376                         
377                 case INT_DISABLE:
378                         DPRINTF("INT_DISABLE\n");
379                         {
380                                 struct interrupt *it = (struct interrupt*)(wdheader->data);
381
382                                 DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
383                                 it->hInterrupt, it->dwOptions,
384                                 it->dwCmds, it->fEnableOk, it->dwCounter,
385                                 it->dwLost, it->fStopped);
386 #ifndef NO_WINDRVR
387                                 ret = (*ioctl_func) (fd, request, wdioctl);
388 #else
389                                 it->dwCounter = 0;
390                                 it->fStopped = 1;
391                                 ints_enabled = 0;
392                                 if (pthread_mutex_trylock(&int_wait) == EBUSY)
393                                         pthread_mutex_unlock(&int_wait);
394 #endif
395                                 DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
396                                 it->hInterrupt, it->dwOptions,
397                                 it->dwCmds, it->fEnableOk, it->dwCounter,
398                                 it->dwLost, it->fStopped);
399                         }
400                         break;
401
402                 case USB_SET_INTERFACE:
403                         DPRINTF("USB_SET_INTERFACE\n");
404                         {
405                                 struct usb_set_interface *usi = (struct usb_set_interface*)(wdheader->data);
406
407                                 DPRINTF("unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n",
408                                 usi->dwUniqueID, usi->dwInterfaceNum,
409                                 usi->dwAlternateSetting, usi->dwOptions);
410 #ifndef NO_WINDRVR
411                                 ret = (*ioctl_func) (fd, request, wdioctl);
412 #else
413                                 if (usbdevice) {
414                                   if (!usb_devhandle)
415                                     usb_devhandle = usb_open(usbdevice);
416
417                                         /* FIXME: Select right interface! */
418                                         ret = usb_claim_interface(usb_devhandle, usbdevice->config[0].interface[usi->dwInterfaceNum].altsetting[usi->dwAlternateSetting].bInterfaceNumber);
419                                         if (!ret) {
420                                                 if(!ret) {
421                                                         usbinterface = usbdevice->config[0].interface[usi->dwInterfaceNum].altsetting[usi->dwAlternateSetting].bInterfaceNumber;
422                                                         ret = usb_set_altinterface(usb_devhandle, usi->dwAlternateSetting);
423                                                         if (ret)
424                                                                 fprintf(stderr, "usb_set_altinterface: %d\n", ret);
425                                                 } else {
426                                                         fprintf(stderr, "usb_set_configuration: %d (%s)\n", ret, usb_strerror());
427                                                 }
428                                         } else {
429                                                 fprintf(stderr, "usb_claim_interface: %d -> %d (%s)\n",
430                                                 usbdevice->config[0].interface[usi->dwInterfaceNum].altsetting[usi->dwAlternateSetting].bInterfaceNumber,
431                                                 ret, usb_strerror());
432                                         }
433                                 }
434 #endif
435                                 DPRINTF("unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n",
436                                 usi->dwUniqueID, usi->dwInterfaceNum,
437                                 usi->dwAlternateSetting, usi->dwOptions);
438                         }
439                         break;
440
441                 case USB_GET_DEVICE_DATA_OLD:
442                 case USB_GET_DEVICE_DATA:
443                         DPRINTF("USB_GET_DEVICE_DATA\n");
444                         {
445                                 struct usb_get_device_data *ugdd = (struct usb_get_device_data*)(wdheader->data);
446                                 int pSize;
447
448                                 DPRINTF("unique: %lu, bytes: %lu, options: %lx\n",
449                                 ugdd->dwUniqueID, ugdd->dwBytes,
450                                 ugdd->dwOptions);
451
452                                 pSize = ugdd->dwBytes;
453                                 if (!ugdd->dwBytes) {
454                                         if (usbdevice) {
455                                                 ugdd->dwBytes = usb_deviceinfo(NULL);
456                                         }
457                                 } else {
458                                         usb_deviceinfo((unsigned char*)ugdd->pBuf);
459                                 }
460                         }
461                         break;
462
463                 case EVENT_REGISTER_OLD:
464                 case EVENT_REGISTER:
465                         DPRINTF("EVENT_REGISTER\n");
466                         {
467                                 struct event *e = (struct event*)(wdheader->data);
468                                 struct usb_bus *bus;
469                                 char* devpos;
470                                 int busnum = -1, devnum = -1;
471                                 int i;
472
473                                 DPRINTF("handle: %lu, action: %lu, status: %lu, eventid: %lu, cardtype: %lu, kplug: %lu, options: %lu, dev: %lx:%lx, unique: %lu, ver: %lu, nummatch: %lu\n",
474                                 e->handle, e->dwAction,
475                                 e->dwStatus, e->dwEventId, e->dwCardType,
476                                 e->hKernelPlugIn, e->dwOptions,
477                                 e->u.Usb.deviceId.dwVendorId,
478                                 e->u.Usb.deviceId.dwProductId,
479                                 e->u.Usb.dwUniqueID, e->dwEventVer,
480                                 e->dwNumMatchTables);
481
482                                 devpos = getenv("XILINX_USB_DEV");
483                                 if (devpos != NULL) {
484                                         int j;
485                                         char *devstr = NULL, *remainder;
486
487                                         DPRINTF("XILINX_USB_DEV=%s\n", devpos);
488
489                                         for (j = 0; j < strlen(devpos) && devpos[j] != 0; j++) {
490                                                 if (devpos[j] == ':') {
491                                                         devpos[j] = 0;
492                                                         devstr = &(devpos[j+1]);
493                                                 }
494                                         }
495
496                                         if (devstr && strlen(devstr) > 0) {
497                                                 busnum = strtol(devpos, &remainder, 10);
498                                                 if (devpos == remainder) {
499                                                         busnum = -1;
500                                                 } else {
501                                                         devnum = strtol(devstr, &remainder, 10);
502                                                         if (devstr == remainder) {
503                                                                 busnum = -1;
504                                                                 devnum = -1;
505                                                         } else {
506                                                                 fprintf(stderr,"Using XILINX platform cable USB at %03d:%03d\n",
507                                                                 busnum, devnum);
508                                                         }
509                                                 }
510                                         }
511                                 }
512
513                                 for (i = 0; i < e->dwNumMatchTables; i++) {
514
515                                         DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
516                                         e->matchTables[i].VendorId,
517                                         e->matchTables[i].ProductId,
518                                         e->matchTables[i].bDeviceClass,
519                                         e->matchTables[i].bDeviceSubClass,
520                                         e->matchTables[i].bInterfaceClass,
521                                         e->matchTables[i].bInterfaceSubClass,
522                                         e->matchTables[i].bInterfaceProtocol);
523
524                                         for (bus = busses; bus; bus = bus->next) {
525                                                 struct usb_device *dev;
526
527                                                 if ((devnum != -1) && (strtol(bus->dirname, NULL, 10) != busnum))
528                                                         continue;
529
530                                                 for (dev = bus->devices; dev; dev = dev->next) {
531                                                         struct usb_device_descriptor *desc = &(dev->descriptor);
532
533                                                         if((desc->idVendor == e->matchTables[i].VendorId) &&
534                                                            (desc->idProduct == e->matchTables[i].ProductId) &&
535                                                            (desc->bDeviceClass == e->matchTables[i].bDeviceClass) &&
536                                                            (desc->bDeviceSubClass == e->matchTables[i].bDeviceSubClass) &&
537                                                            ((devnum == -1) || (strtol(dev->filename, NULL, 10) == devnum)) ) {
538                                                                    int ac;
539                                                                    for (ac = 0; ac < desc->bNumConfigurations; ac++) {
540                                                                            struct usb_interface *interface = dev->config[ac].interface;
541                                                                            int ai;
542
543                                                                            for (ai = 0; ai < interface->num_altsetting; ai++) {
544
545                                                                                    DPRINTF("intclass: %x, intsubclass: %x, intproto: %x\n",
546                                                                                    interface->altsetting[i].bInterfaceClass,
547                                                                                    interface->altsetting[i].bInterfaceSubClass,
548                                                                                    interface->altsetting[i].bInterfaceProtocol);
549
550                                                                                    if ((interface->altsetting[ai].bInterfaceSubClass == e->matchTables[i].bInterfaceSubClass) &&
551                                                                                                    (interface->altsetting[ai].bInterfaceProtocol == e->matchTables[i].bInterfaceProtocol)){
552                                                                                            /* TODO: check interfaceClass! */
553                                                                                            DPRINTF("found device with libusb\n");
554                                                                                            usbdevice = dev;
555                                                                                            card_type = e->dwCardType;
556                                                                                    }
557                                                                            }
558                                                                    }
559                                                         }
560                                                 }
561                                         }
562                                 }
563
564 #ifndef NO_WINDRVR
565                                 ret = (*ioctl_func) (fd, request, wdioctl);
566 #else
567                                 e->handle++;
568 #endif
569
570 #ifdef DEBUG
571                                 DPRINTF("handle: %lu, action: %lu, status: %lu, eventid: %lu, cardtype: %lu, kplug: %lu, options: %lu, dev: %lx:%lx, unique: %lu, ver: %lu, nummatch: %lu\n",
572                                 e->handle, e->dwAction,
573                                 e->dwStatus, e->dwEventId, e->dwCardType,
574                                 e->hKernelPlugIn, e->dwOptions,
575                                 e->u.Usb.deviceId.dwVendorId,
576                                 e->u.Usb.deviceId.dwProductId,
577                                 e->u.Usb.dwUniqueID, e->dwEventVer,
578                                 e->dwNumMatchTables);
579
580                                 for (i = 0; i < e->dwNumMatchTables; i++)
581                                         DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
582                                         e->matchTables[i].VendorId,
583                                         e->matchTables[i].ProductId,
584                                         e->matchTables[i].bDeviceClass,
585                                         e->matchTables[i].bDeviceSubClass,
586                                         e->matchTables[i].bInterfaceClass,
587                                         e->matchTables[i].bInterfaceSubClass,
588                                         e->matchTables[i].bInterfaceProtocol);
589 #endif
590                         }
591                         break;
592
593                 case TRANSFER_OLD:
594                 case TRANSFER:
595                         DPRINTF("TRANSFER\n");
596                         {
597                                 WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);
598
599 #ifndef NO_WINDRVR
600                                 ret = (*ioctl_func) (fd, request, wdioctl);
601 #else
602                                 ret = pport->transfer(tr, fd, request, ppbase, ecpbase, 1);
603 #endif
604                         }
605                         break;
606
607                 case MULTI_TRANSFER_OLD:
608                 case MULTI_TRANSFER:
609                         DPRINTF("MULTI_TRANSFER\n");
610                         {
611                                 WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);
612                                 unsigned long num = wdheader->size/sizeof(WD_TRANSFER);
613 #ifndef NO_WINDRVR
614                                 ret = (*ioctl_func) (fd, request, wdioctl);
615 #else
616                                 ret = pport->transfer(tr, fd, request, ppbase, ecpbase, num);
617 #endif
618                         }
619                         break;
620
621                 case EVENT_UNREGISTER:
622                         DPRINTF("EVENT_UNREGISTER\n");
623 #ifndef NO_WINDRVR
624                         ret = (*ioctl_func) (fd, request, wdioctl);
625 #endif
626                         break;
627
628                 case INT_WAIT:
629                         DPRINTF("INT_WAIT\n");
630                         {
631                                 struct interrupt *it = (struct interrupt*)(wdheader->data);
632
633                                 DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
634                                 it->hInterrupt, it->dwOptions,
635                                 it->dwCmds, it->fEnableOk, it->dwCounter,
636                                 it->dwLost, it->fStopped);
637
638 #ifndef NO_WINDRVR
639                                 ret = (*ioctl_func) (fd, request, wdioctl);
640 #else
641                                 if (usbdevice) {
642                                         if (it->dwCounter == 0) {
643                                                 it->dwCounter = 1;
644                                         } else {
645                                                 pthread_mutex_lock(&int_wait);
646                                                 pthread_mutex_unlock(&int_wait);
647                                         }
648                                 } else {
649                                         pthread_mutex_lock(&int_wait);
650                                         pthread_mutex_unlock(&int_wait);
651                                 }
652 #endif
653
654                                 DPRINTF("INT_WAIT_RETURN: Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
655                                 it->hInterrupt, it->dwOptions, it->dwCmds,
656                                 it->fEnableOk, it->dwCounter, it->dwLost,
657                                 it->fStopped);
658                         }
659                         break;
660
661                 case CARD_UNREGISTER:
662                         DPRINTF("CARD_UNREGISTER\n");
663                         {
664                                 struct card_register* cr = (struct card_register*)(wdheader->data);
665
666                                 DPRINTF("Addr: 0x%lx, bytes: %lu, bar: %lu\n",
667                                 (unsigned long)cr->Card.Item[0].I.IO.dwAddr,
668                                 cr->Card.Item[0].I.IO.dwBytes,
669                                 cr->Card.Item[0].I.IO.dwBar);
670
671                                 DPRINTF("hCard: %lu\n", cr->hCard);
672
673 #ifndef NO_WINDRVR
674                                 ret = (*ioctl_func) (fd, request, wdioctl);
675 #else
676                                 if (pport)
677                                         pport->close(cr->hCard);
678
679                                 pport = NULL;
680 #endif
681                         }
682                         break;
683
684                 case EVENT_PULL:
685                         DPRINTF("EVENT_PULL\n");
686                         {
687                                 struct event *e = (struct event*)(wdheader->data);
688 #ifdef DEBUG
689                                 int i;
690
691                                 DPRINTF("handle: %lu, action: %lu, status: %lu, eventid: %lu, cardtype: %lx, kplug: %lu, options: %lu, dev: %lx:%lx, unique: %lu, ver: %lu, nummatch: %lu\n",
692                                 e->handle, e->dwAction, e->dwStatus,
693                                 e->dwEventId, e->dwCardType, e->hKernelPlugIn,
694                                 e->dwOptions, e->u.Usb.deviceId.dwVendorId,
695                                 e->u.Usb.deviceId.dwProductId,
696                                 e->u.Usb.dwUniqueID, e->dwEventVer,
697                                 e->dwNumMatchTables);
698
699                                 for (i = 0; i < e->dwNumMatchTables; i++)
700                                         DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
701                                         e->matchTables[i].VendorId,
702                                         e->matchTables[i].ProductId,
703                                         e->matchTables[i].bDeviceClass,
704                                         e->matchTables[i].bDeviceSubClass,
705                                         e->matchTables[i].bInterfaceClass,
706                                         e->matchTables[i].bInterfaceSubClass,
707                                         e->matchTables[i].bInterfaceProtocol);
708 #endif
709
710 #ifndef NO_WINDRVR
711                                 ret = (*ioctl_func) (fd, request, wdioctl);
712 #else
713                                 if (usbdevice) {
714                                         struct usb_interface *interface = usbdevice->config->interface;
715
716                                         e->dwCardType = card_type;
717                                         e->dwAction = 1;
718                                         e->dwEventId = 109;
719                                         e->u.Usb.dwUniqueID = 110;
720                                         e->matchTables[0].VendorId = usbdevice->descriptor.idVendor;
721                                         e->matchTables[0].ProductId = usbdevice->descriptor.idProduct;
722                                         e->matchTables[0].bDeviceClass = usbdevice->descriptor.bDeviceClass;
723                                         e->matchTables[0].bDeviceSubClass = usbdevice->descriptor.bDeviceSubClass;
724                                         e->matchTables[0].bInterfaceClass = interface->altsetting[0].bInterfaceClass;
725                                         e->matchTables[0].bInterfaceSubClass = interface->altsetting[0].bInterfaceSubClass;
726                                         e->matchTables[0].bInterfaceProtocol = interface->altsetting[0].bInterfaceProtocol;
727                                 }
728 #endif
729
730 #ifdef DEBUG
731                                 DPRINTF("handle: %lu, action: %lu, status: %lu, eventid: %lu, cardtype: %lx, kplug: %lu, options: %lu, dev: %lx:%lx, unique: %lu, ver: %lu, nummatch: %lu\n",
732                                 e->handle, e->dwAction, e->dwStatus,
733                                 e->dwEventId, e->dwCardType, e->hKernelPlugIn,
734                                 e->dwOptions, e->u.Usb.deviceId.dwVendorId,
735                                 e->u.Usb.deviceId.dwProductId,
736                                 e->u.Usb.dwUniqueID, e->dwEventVer,
737                                 e->dwNumMatchTables);
738
739                                 for (i = 0; i < e->dwNumMatchTables; i++)
740                                         DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n",
741                                         e->matchTables[i].VendorId,
742                                         e->matchTables[i].ProductId,
743                                         e->matchTables[i].bDeviceClass,
744                                         e->matchTables[i].bDeviceSubClass,
745                                         e->matchTables[i].bInterfaceClass,
746                                         e->matchTables[i].bInterfaceSubClass,
747                                         e->matchTables[i].bInterfaceProtocol);
748 #endif
749
750                         }
751                         break;
752
753                 default:
754                         fprintf(stderr,"!!!Unsupported IOCTL: %x!!!\n", request);
755 #ifndef NO_WINDRVR
756                         ret = (*ioctl_func) (fd, request, wdioctl);
757 #endif
758                         break;
759         }
760
761         return ret;
762 }
763
764 int ioctl(int fd, unsigned long int request, ...) {
765         va_list args;
766         void *argp;
767         int ret;
768
769         if (!ioctl_func)                                                                    
770                 ioctl_func = (int (*) (int, int, void *)) dlsym (RTLD_NEXT, "ioctl");             
771
772         va_start (args, request);
773         argp = va_arg (args, void *);
774         va_end (args);
775
776         if (fd == windrvrfd)
777                 ret = do_wdioctl(fd, request, argp);
778         else
779                 ret = (*ioctl_func) (fd, request, argp);
780
781         return ret;
782 }
783
784 int open (const char *pathname, int flags, ...) {
785         static int (*func) (const char *, int, mode_t) = NULL;
786         mode_t mode = 0;
787         va_list args;
788         int fd;
789
790         if (!func)
791                 func = (int (*) (const char *, int, mode_t)) dlsym (RTLD_NEXT, "open");
792
793         if (flags & O_CREAT) {
794                 va_start(args, flags);
795                 mode = va_arg(args, mode_t);
796                 va_end(args);
797         }
798
799         if (!strcmp (pathname, "/dev/windrvr6")) {
800                 DPRINTF("opening windrvr6\n");
801 #ifdef NO_WINDRVR
802                 windrvrfd = fd = (*func) ("/dev/null", flags, mode);
803 #else
804                 windrvrfd = fd = (*func) (pathname, flags, mode);
805 #endif
806                 if (!busses) {
807                         usb_init();
808                         usb_find_busses();
809                         usb_find_devices();
810
811                         busses = usb_get_busses();
812                 }
813
814                 return fd;
815         }
816
817         return (*func) (pathname, flags, mode);
818 }
819
820 int close(int fd) {
821         static int (*func) (int) = NULL;
822
823         if (!func)
824                 func = (int (*) (int)) dlsym(RTLD_NEXT, "close");
825         
826         if (fd == windrvrfd && windrvrfd >= 0) {
827                 DPRINTF("close windrvrfd\n");
828                 if (usbinterface >= 0)
829                         usb_release_interface(usb_devhandle, usbinterface);
830
831                 if (usb_devhandle)
832                         usb_close(usb_devhandle);
833
834                 usb_devhandle = NULL;
835                 usbinterface = -1;
836                 windrvrfd = -1;
837         }
838
839         return (*func) (fd);
840 }
841
842 FILE *fopen(const char *path, const char *mode) {
843         FILE *ret;
844         static FILE* (*func) (const char*, const char*) = NULL;
845         char buf[256];
846         int i;
847
848         if (!func)
849                 func = (FILE* (*) (const char*, const char*)) dlsym(RTLD_NEXT, "fopen");
850
851         for (i = 0; i < 4; i++) {
852                 snprintf(buf, sizeof(buf), "/proc/sys/dev/parport/parport%d/base-addr", i);
853                 if (!strcmp(path, buf)) {
854                         DPRINTF("open base-addr of parport%d\n", i);
855                         if (config_is_real_pport(i)) {
856                                 ret = (*func) (path, mode);
857                         } else {
858                                 ret = (*func) ("/dev/null", mode);
859                         }
860
861                         if (ret) {
862                                 baseaddrfp = ret;
863                                 baseaddrnum = i;
864                         }
865
866                         return ret;
867                 }
868         }
869
870         ret = (*func) (path, mode);
871
872         if (!strcmp(path, "/proc/modules")) {
873                 DPRINTF("opening /proc/modules\n");
874 #ifdef NO_WINDRVR
875                 modulesfp = ret;
876                 modules_read = 0;
877 #endif
878         }
879
880         return ret;
881 }
882
883 char *fgets(char *s, int size, FILE *stream) {
884         static char* (*func) (char*, int, FILE*) = NULL;
885         const char modules[][256] = {"windrvr6 1 0 - Live 0xdeadbeef\n", "parport_pc 1 0 - Live 0xdeadbeef\n"};
886         char buf[256];
887         char *ret = NULL;
888
889
890         if (!func)
891                 func = (char* (*) (char*, int, FILE*)) dlsym(RTLD_NEXT, "fgets");
892         
893         if (modulesfp == stream) {
894                 if (modules_read < sizeof(modules) / sizeof(modules[0])) {
895                         strcpy(s, modules[modules_read]);
896                         ret = s;
897                         modules_read++;
898                 }
899         } else if (baseaddrfp == stream) {
900                 snprintf(s, sizeof(buf), "%d\t%d\n",
901                         (baseaddrnum) * 0x10,
902                         ((baseaddrnum) * 0x10) + 0x400);
903                 ret = s;
904         } else {
905                 ret = (*func)(s,size,stream);
906         }
907
908         return ret;
909 }
910
911 int fclose(FILE *fp) {
912         static int (*func) (FILE*) = NULL;
913
914         if (!func)
915                 func = (int (*) (FILE*)) dlsym(RTLD_NEXT, "fclose");
916
917         if (fp == modulesfp) {
918                 modulesfp = NULL;
919         }
920
921         if (fp == baseaddrfp) {
922                 baseaddrfp = NULL;
923         }
924         
925         return (*func)(fp);
926 }
927
928 int access(const char *pathname, int mode) {
929         static int (*func) (const char*, int);
930
931         if (!func)
932                 func = (int (*) (const char*, int)) dlsym(RTLD_NEXT, "access");
933
934         if (pathname && !strcmp(pathname, "/dev/windrvr6")) {
935                 return 0;
936         } else {
937                 return (*func)(pathname, mode);
938         }
939 }