1 /* libusb/ppdev connector for XILINX impact 
   3  * Copyright (c) 2007 Michael Gernoth <michael@gernoth.net> 
   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: 
  12  * The above copyright notice and this permission notice shall be included in 
  13  * all copies or substantial portions of the Software. 
  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 
  32 #include <sys/types.h> 
  41 #include <sys/ioctl.h> 
  42 #include "usb-driver.h" 
  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 FILE *modulesfp 
= NULL
; 
  51 FILE *baseaddrfp 
= NULL
; 
  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
; 
  64 void hexdump(unsigned char *buf
, int len
) { 
  67         for(i
=0; i
<len
; i
++) { 
  68                 fprintf(stderr
,"%02x ", buf
[i
]); 
  75 int usb_deviceinfo(unsigned char *buf
) { 
  78         WDU_CONFIGURATION 
**pConfigs
, **pActiveConfig
; 
  79         WDU_INTERFACE 
**pActiveInterface
; 
  82                 struct usb_device_info 
*udi 
= (struct usb_device_info
*)(buf
+len
); 
  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
; 
  99                 /* TODO: Fix Pipe0! */ 
 100                 udi
->Pipe0
.dwNumber 
= 0x00; 
 101                 udi
->Pipe0
.dwMaximumPacketSize 
= usbdevice
->descriptor
.bMaxPacketSize0
; 
 103                 udi
->Pipe0
.direction 
= WDU_DIR_IN_OUT
; 
 104                 udi
->Pipe0
.dwInterval 
= 0; 
 106                 pConfigs 
= &(udi
->pConfigs
); 
 107                 pActiveConfig 
= &(udi
->pActiveConfig
); 
 108                 pActiveInterface 
= &(udi
->pActiveInterface
[0]); 
 111         len 
= sizeof(struct usb_device_info
); 
 113         for (i
=0; i
<usbdevice
->descriptor
.bNumConfigurations
; i
++) 
 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
]; 
 121                         WDU_CONFIGURATION 
*cfg 
= (WDU_CONFIGURATION
*)(buf
+len
); 
 124                         *pActiveConfig 
= cfg
; 
 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
; 
 135                         cfg
->dwNumInterfaces 
= conf_desc
->bNumInterfaces
; 
 137                         pInterfaces 
= &(cfg
->pInterfaces
); 
 139                 len 
+= sizeof(WDU_CONFIGURATION
); 
 142                         *pInterfaces 
= (WDU_INTERFACE
*)(buf
+len
); 
 143                         for (j
=0; j
<conf_desc
->bNumInterfaces
; j
++) { 
 144                                 WDU_INTERFACE 
*iface 
= (WDU_INTERFACE
*)(buf
+len
); 
 146                                 pActiveInterface
[j
] = iface
; 
 148                                 pAlternateSettings
[j
] = &(iface
->pAlternateSettings
); 
 149                                 iface
->dwNumAltSettings 
= usbdevice
->config
[i
].interface
[j
].num_altsetting
; 
 150                                 pActiveAltSetting
[j
] = &(iface
->pActiveAltSetting
); 
 152                                 len 
+= sizeof(WDU_INTERFACE
); 
 155                         len 
+= sizeof(WDU_INTERFACE
) * conf_desc
->bNumInterfaces
; 
 158                 for (j
=0; j
<conf_desc
->bNumInterfaces
; j
++) 
 160                         struct usb_interface 
*interface 
= &usbdevice
->config
[i
].interface
[j
]; 
 163                                 *pAlternateSettings
[j
] = (WDU_ALTERNATE_SETTING
*)(buf
+len
); 
 165                                 *pActiveAltSetting
[j
] = (WDU_ALTERNATE_SETTING
*)(buf
+len
); 
 168                         for(k
=0; k
<interface
->num_altsetting
; k
++) 
 170                                 unsigned char bNumEndpoints 
= interface
->altsetting
[k
].bNumEndpoints
; 
 171                                 WDU_ENDPOINT_DESCRIPTOR 
**pEndpointDescriptors
; 
 172                                 WDU_PIPE_INFO 
**pPipes
; 
 175                                         WDU_ALTERNATE_SETTING 
*altset 
= (WDU_ALTERNATE_SETTING
*)(buf
+len
); 
 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
); 
 190                                 len 
+=sizeof(WDU_ALTERNATE_SETTING
); 
 193                                         *pEndpointDescriptors 
= (WDU_ENDPOINT_DESCRIPTOR
*)(buf
+len
); 
 194                                         for (l 
= 0; l 
< bNumEndpoints
; l
++) { 
 195                                                 WDU_ENDPOINT_DESCRIPTOR 
*ed 
= (WDU_ENDPOINT_DESCRIPTOR
*)(buf
+len
); 
 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
; 
 204                                                 len 
+= sizeof(WDU_ENDPOINT_DESCRIPTOR
); 
 207                                         *pPipes 
= (WDU_PIPE_INFO
*)(buf
+len
); 
 208                                         for (l 
= 0; l 
< bNumEndpoints
; l
++) { 
 209                                                 WDU_PIPE_INFO 
*pi 
= (WDU_PIPE_INFO
*)(buf
+len
); 
 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
; 
 218                                                         pi
->direction 
= interface
->altsetting
[k
].endpoint
[l
].bEndpointAddress 
& USB_ENDPOINT_DIR_MASK 
?  WDU_DIR_IN 
: WDU_DIR_OUT
; 
 221                                                 pi
->dwInterval 
= interface
->altsetting
[k
].endpoint
[l
].bInterval
; 
 223                                                 len 
+= sizeof(WDU_PIPE_INFO
); 
 226                                         len 
+=(sizeof(WDU_ENDPOINT_DESCRIPTOR
)+sizeof(WDU_PIPE_INFO
))*bNumEndpoints
; 
 235 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
; 
 240         if (wdheader
->magic 
!= MAGIC
) { 
 241                 fprintf(stderr
,"!!!ERROR: magic header does not match!!!\n"); 
 242                 return (*ioctl_func
) (fd
, request
, wdioctl
); 
 245         switch(request 
& ~(0xc0000000)) { 
 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"); 
 254                         DPRINTF("LICENSE\n"); 
 257                 case CARD_REGISTER_OLD
: 
 259                         DPRINTF("CARD_REGISTER\n"); 
 261                                 struct card_register
* cr 
= (struct card_register
*)(wdheader
->data
); 
 263                                 DPRINTF("Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n", 
 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
); 
 269                                 DPRINTF("Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n", 
 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
); 
 275                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 278                                 pport 
= config_get((unsigned long)cr
->Card
.Item
[0].I
.IO
.dwAddr 
/ 0x10); 
 282                                 ret 
= pport
->open((unsigned long)cr
->Card
.Item
[0].I
.IO
.dwAddr 
/ 0x10); 
 284                                 ppbase 
= (unsigned long)cr
->Card
.Item
[0].I
.IO
.dwAddr
; 
 286                                 if (cr
->Card
.dwItems 
> 1 && cr
->Card
.Item
[1].I
.IO
.dwAddr
) 
 287                                         ecpbase 
= (unsigned long)cr
->Card
.Item
[1].I
.IO
.dwAddr
; 
 295                                 DPRINTF("hCard: %lu\n", cr
->hCard
); 
 300                         DPRINTF("in USB_TRANSFER"); 
 302                                 struct usb_transfer 
*ut 
= (struct usb_transfer
*)(wdheader
->data
); 
 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); 
 311                                 if (!ut
->fRead 
&& ut
->dwBufferSize
) 
 313                                         hexdump(ut
->pBuffer
, ut
->dwBufferSize
); 
 318                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 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
); 
 332                                                 ret 
= usb_bulk_read(usb_devhandle
, ut
->dwPipeNum
, ut
->pBuffer
, ut
->dwBufferSize
, ut
->dwTimeout
); 
 335                                                 ret 
= usb_bulk_write(usb_devhandle
, ut
->dwPipeNum
, ut
->pBuffer
, ut
->dwBufferSize
, ut
->dwTimeout
); 
 340                                         fprintf(stderr
, "usb_transfer: %d (%s)\n", ret
, usb_strerror()); 
 342                                         ut
->dwBytesTransferred 
= ret
; 
 348                                 DPRINTF("Transferred: %lu (%s)\n",ut
->dwBytesTransferred
, (ut
->fRead
?"read":"write")); 
 349                                 if (ut
->fRead 
&& ut
->dwBytesTransferred
) 
 352                                         hexdump(ut
->pBuffer
, ut
->dwBytesTransferred
); 
 360                         DPRINTF("INT_ENABLE\n"); 
 362                                 struct interrupt 
*it 
= (struct interrupt
*)(wdheader
->data
); 
 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
); 
 372                                 pthread_mutex_trylock(&int_wait
); 
 378                         DPRINTF("INT_DISABLE\n"); 
 380                                 struct interrupt 
*it 
= (struct interrupt
*)(wdheader
->data
); 
 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
); 
 387                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 392                                 if (pthread_mutex_trylock(&int_wait
) == EBUSY
) 
 393                                         pthread_mutex_unlock(&int_wait
); 
 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
); 
 402                 case USB_SET_INTERFACE
: 
 403                         DPRINTF("USB_SET_INTERFACE\n"); 
 405                                 struct usb_set_interface 
*usi 
= (struct usb_set_interface
*)(wdheader
->data
); 
 407                                 DPRINTF("unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", 
 408                                 usi
->dwUniqueID
, usi
->dwInterfaceNum
, 
 409                                 usi
->dwAlternateSetting
, usi
->dwOptions
); 
 411                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 415                                                 usb_devhandle 
= usb_open(usbdevice
); 
 417                                         /* FIXME: Select right interface! */ 
 418                                         ret 
= usb_claim_interface(usb_devhandle
, usbdevice
->config
[0].interface
[usi
->dwInterfaceNum
].altsetting
[usi
->dwAlternateSetting
].bInterfaceNumber
); 
 421                                                         usbinterface 
= usbdevice
->config
[0].interface
[usi
->dwInterfaceNum
].altsetting
[usi
->dwAlternateSetting
].bInterfaceNumber
; 
 422                                                         ret 
= usb_set_altinterface(usb_devhandle
, usi
->dwAlternateSetting
); 
 424                                                                 fprintf(stderr
, "usb_set_altinterface: %d\n", ret
); 
 426                                                         fprintf(stderr
, "usb_set_configuration: %d (%s)\n", ret
, usb_strerror()); 
 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()); 
 435                                 DPRINTF("unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", 
 436                                 usi
->dwUniqueID
, usi
->dwInterfaceNum
, 
 437                                 usi
->dwAlternateSetting
, usi
->dwOptions
); 
 441                 case USB_GET_DEVICE_DATA_OLD
: 
 442                 case USB_GET_DEVICE_DATA
: 
 443                         DPRINTF("USB_GET_DEVICE_DATA\n"); 
 445                                 struct usb_get_device_data 
*ugdd 
= (struct usb_get_device_data
*)(wdheader
->data
); 
 448                                 DPRINTF("unique: %lu, bytes: %lu, options: %lx\n", 
 449                                 ugdd
->dwUniqueID
, ugdd
->dwBytes
, 
 452                                 pSize 
= ugdd
->dwBytes
; 
 453                                 if (!ugdd
->dwBytes
) { 
 455                                                 ugdd
->dwBytes 
= usb_deviceinfo(NULL
); 
 458                                         usb_deviceinfo((unsigned char*)ugdd
->pBuf
); 
 463                 case EVENT_REGISTER_OLD
: 
 465                         DPRINTF("EVENT_REGISTER\n"); 
 467                                 struct event 
*e 
= (struct event
*)(wdheader
->data
); 
 470                                 int busnum 
= -1, devnum 
= -1; 
 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
); 
 482                                 devpos 
= getenv("XILINX_USB_DEV"); 
 483                                 if (devpos 
!= NULL
) { 
 485                                         char *devstr 
= NULL
, *remainder
; 
 487                                         DPRINTF("XILINX_USB_DEV=%s\n", devpos
); 
 489                                         for (j 
= 0; j 
< strlen(devpos
) && devpos
[j
] != 0; j
++) { 
 490                                                 if (devpos
[j
] == ':') { 
 492                                                         devstr 
= &(devpos
[j
+1]); 
 496                                         if (devstr 
&& strlen(devstr
) > 0) { 
 497                                                 busnum 
= strtol(devpos
, &remainder
, 10); 
 498                                                 if (devpos 
== remainder
) { 
 501                                                         devnum 
= strtol(devstr
, &remainder
, 10); 
 502                                                         if (devstr 
== remainder
) { 
 505                                                                 fprintf(stderr
,"Using XILINX platform cable USB at %03d:%03d\n", 
 512                                 for (i 
= 0; i 
< e
->dwNumMatchTables
; i
++) { 
 514                                         DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", 
 515                                         e
->matchTables
[i
].VendorId
, 
 516                                         e
->matchTables
[i
].ProductId
, 
 517                                         e
->matchTables
[i
].bDeviceClass
, 
 518                                         e
->matchTables
[i
].bDeviceSubClass
, 
 519                                         e
->matchTables
[i
].bInterfaceClass
, 
 520                                         e
->matchTables
[i
].bInterfaceSubClass
, 
 521                                         e
->matchTables
[i
].bInterfaceProtocol
); 
 523                                         for (bus 
= busses
; bus
; bus 
= bus
->next
) { 
 524                                                 struct usb_device 
*dev
; 
 526                                                 if ((devnum 
!= -1) && (strtol(bus
->dirname
, NULL
, 10) != busnum
)) 
 529                                                 for (dev 
= bus
->devices
; dev
; dev 
= dev
->next
) { 
 530                                                         struct usb_device_descriptor 
*desc 
= &(dev
->descriptor
); 
 532                                                         if((desc
->idVendor 
== e
->matchTables
[i
].VendorId
) && 
 533                                                            (desc
->idProduct 
== e
->matchTables
[i
].ProductId
) && 
 534                                                            (desc
->bDeviceClass 
== e
->matchTables
[i
].bDeviceClass
) && 
 535                                                            (desc
->bDeviceSubClass 
== e
->matchTables
[i
].bDeviceSubClass
) && 
 536                                                            ((devnum 
== -1) || (dev
->devnum 
== devnum
)) ) { 
 538                                                                    for (ac 
= 0; ac 
< desc
->bNumConfigurations
; ac
++) { 
 539                                                                            struct usb_interface 
*interface 
= dev
->config
[ac
].interface
; 
 542                                                                            for (ai 
= 0; ai 
< interface
->num_altsetting
; ai
++) { 
 544                                                                                    DPRINTF("intclass: %x, intsubclass: %x, intproto: %x\n", 
 545                                                                                    interface
->altsetting
[i
].bInterfaceClass
, 
 546                                                                                    interface
->altsetting
[i
].bInterfaceSubClass
, 
 547                                                                                    interface
->altsetting
[i
].bInterfaceProtocol
); 
 549                                                                                    if ((interface
->altsetting
[ai
].bInterfaceSubClass 
== e
->matchTables
[i
].bInterfaceSubClass
) && 
 550                                                                                                    (interface
->altsetting
[ai
].bInterfaceProtocol 
== e
->matchTables
[i
].bInterfaceProtocol
)){ 
 551                                                                                            /* TODO: check interfaceClass! */ 
 552                                                                                            DPRINTF("found device with libusb\n"); 
 554                                                                                            card_type 
= e
->dwCardType
; 
 564                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 570                                 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", 
 571                                 e
->handle
, e
->dwAction
, 
 572                                 e
->dwStatus
, e
->dwEventId
, e
->dwCardType
, 
 573                                 e
->hKernelPlugIn
, e
->dwOptions
, 
 574                                 e
->u
.Usb
.deviceId
.dwVendorId
, 
 575                                 e
->u
.Usb
.deviceId
.dwProductId
, 
 576                                 e
->u
.Usb
.dwUniqueID
, e
->dwEventVer
, 
 577                                 e
->dwNumMatchTables
); 
 579                                 for (i 
= 0; i 
< e
->dwNumMatchTables
; i
++) 
 580                                         DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", 
 581                                         e
->matchTables
[i
].VendorId
, 
 582                                         e
->matchTables
[i
].ProductId
, 
 583                                         e
->matchTables
[i
].bDeviceClass
, 
 584                                         e
->matchTables
[i
].bDeviceSubClass
, 
 585                                         e
->matchTables
[i
].bInterfaceClass
, 
 586                                         e
->matchTables
[i
].bInterfaceSubClass
, 
 587                                         e
->matchTables
[i
].bInterfaceProtocol
); 
 594                         DPRINTF("TRANSFER\n"); 
 596                                 WD_TRANSFER 
*tr 
= (WD_TRANSFER
*)(wdheader
->data
); 
 599                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 601                                 ret 
= pport
->transfer(tr
, fd
, request
, ppbase
, ecpbase
, 1); 
 606                 case MULTI_TRANSFER_OLD
: 
 608                         DPRINTF("MULTI_TRANSFER\n"); 
 610                                 WD_TRANSFER 
*tr 
= (WD_TRANSFER
*)(wdheader
->data
); 
 611                                 unsigned long num 
= wdheader
->size
/sizeof(WD_TRANSFER
); 
 613                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 615                                 ret 
= pport
->transfer(tr
, fd
, request
, ppbase
, ecpbase
, num
); 
 620                 case EVENT_UNREGISTER
: 
 621                         DPRINTF("EVENT_UNREGISTER\n"); 
 623                         ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 628                         DPRINTF("INT_WAIT\n"); 
 630                                 struct interrupt 
*it 
= (struct interrupt
*)(wdheader
->data
); 
 632                                 DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", 
 633                                 it
->hInterrupt
, it
->dwOptions
, 
 634                                 it
->dwCmds
, it
->fEnableOk
, it
->dwCounter
, 
 635                                 it
->dwLost
, it
->fStopped
); 
 638                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 641                                         if (it
->dwCounter 
== 0) { 
 644                                                 pthread_mutex_lock(&int_wait
); 
 645                                                 pthread_mutex_unlock(&int_wait
); 
 648                                         pthread_mutex_lock(&int_wait
); 
 649                                         pthread_mutex_unlock(&int_wait
); 
 653                                 DPRINTF("INT_WAIT_RETURN: Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", 
 654                                 it
->hInterrupt
, it
->dwOptions
, it
->dwCmds
, 
 655                                 it
->fEnableOk
, it
->dwCounter
, it
->dwLost
, 
 660                 case CARD_UNREGISTER
: 
 661                         DPRINTF("CARD_UNREGISTER\n"); 
 663                                 struct card_register
* cr 
= (struct card_register
*)(wdheader
->data
); 
 665                                 DPRINTF("Addr: 0x%lx, bytes: %lu, bar: %lu\n", 
 666                                 (unsigned long)cr
->Card
.Item
[0].I
.IO
.dwAddr
, 
 667                                 cr
->Card
.Item
[0].I
.IO
.dwBytes
, 
 668                                 cr
->Card
.Item
[0].I
.IO
.dwBar
); 
 670                                 DPRINTF("hCard: %lu\n", cr
->hCard
); 
 673                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 676                                         pport
->close(cr
->hCard
); 
 684                         DPRINTF("EVENT_PULL\n"); 
 686                                 struct event 
*e 
= (struct event
*)(wdheader
->data
); 
 690                                 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", 
 691                                 e
->handle
, e
->dwAction
, e
->dwStatus
, 
 692                                 e
->dwEventId
, e
->dwCardType
, e
->hKernelPlugIn
, 
 693                                 e
->dwOptions
, e
->u
.Usb
.deviceId
.dwVendorId
, 
 694                                 e
->u
.Usb
.deviceId
.dwProductId
, 
 695                                 e
->u
.Usb
.dwUniqueID
, e
->dwEventVer
, 
 696                                 e
->dwNumMatchTables
); 
 698                                 for (i 
= 0; i 
< e
->dwNumMatchTables
; i
++) 
 699                                         DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", 
 700                                         e
->matchTables
[i
].VendorId
, 
 701                                         e
->matchTables
[i
].ProductId
, 
 702                                         e
->matchTables
[i
].bDeviceClass
, 
 703                                         e
->matchTables
[i
].bDeviceSubClass
, 
 704                                         e
->matchTables
[i
].bInterfaceClass
, 
 705                                         e
->matchTables
[i
].bInterfaceSubClass
, 
 706                                         e
->matchTables
[i
].bInterfaceProtocol
); 
 710                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 713                                         struct usb_interface 
*interface 
= usbdevice
->config
->interface
; 
 715                                         e
->dwCardType 
= card_type
; 
 718                                         e
->u
.Usb
.dwUniqueID 
= 110; 
 719                                         e
->matchTables
[0].VendorId 
= usbdevice
->descriptor
.idVendor
; 
 720                                         e
->matchTables
[0].ProductId 
= usbdevice
->descriptor
.idProduct
; 
 721                                         e
->matchTables
[0].bDeviceClass 
= usbdevice
->descriptor
.bDeviceClass
; 
 722                                         e
->matchTables
[0].bDeviceSubClass 
= usbdevice
->descriptor
.bDeviceSubClass
; 
 723                                         e
->matchTables
[0].bInterfaceClass 
= interface
->altsetting
[0].bInterfaceClass
; 
 724                                         e
->matchTables
[0].bInterfaceSubClass 
= interface
->altsetting
[0].bInterfaceSubClass
; 
 725                                         e
->matchTables
[0].bInterfaceProtocol 
= interface
->altsetting
[0].bInterfaceProtocol
; 
 730                                 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", 
 731                                 e
->handle
, e
->dwAction
, e
->dwStatus
, 
 732                                 e
->dwEventId
, e
->dwCardType
, e
->hKernelPlugIn
, 
 733                                 e
->dwOptions
, e
->u
.Usb
.deviceId
.dwVendorId
, 
 734                                 e
->u
.Usb
.deviceId
.dwProductId
, 
 735                                 e
->u
.Usb
.dwUniqueID
, e
->dwEventVer
, 
 736                                 e
->dwNumMatchTables
); 
 738                                 for (i 
= 0; i 
< e
->dwNumMatchTables
; i
++) 
 739                                         DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", 
 740                                         e
->matchTables
[i
].VendorId
, 
 741                                         e
->matchTables
[i
].ProductId
, 
 742                                         e
->matchTables
[i
].bDeviceClass
, 
 743                                         e
->matchTables
[i
].bDeviceSubClass
, 
 744                                         e
->matchTables
[i
].bInterfaceClass
, 
 745                                         e
->matchTables
[i
].bInterfaceSubClass
, 
 746                                         e
->matchTables
[i
].bInterfaceProtocol
); 
 753                         fprintf(stderr
,"!!!Unsupported IOCTL: %x!!!\n", request
); 
 755                         ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 763 int ioctl(int fd
, unsigned long int request
, ...) { 
 769                 ioctl_func 
= (int (*) (int, int, void *)) dlsym (RTLD_NEXT
, "ioctl");              
 771         va_start (args
, request
); 
 772         argp 
= va_arg (args
, void *); 
 776                 ret 
= do_wdioctl(fd
, request
, argp
); 
 778                 ret 
= (*ioctl_func
) (fd
, request
, argp
); 
 783 int open (const char *pathname
, int flags
, ...) { 
 784         static int (*func
) (const char *, int, mode_t
) = NULL
; 
 790                 func 
= (int (*) (const char *, int, mode_t
)) dlsym (RTLD_NEXT
, "open"); 
 792         if (flags 
& O_CREAT
) { 
 793                 va_start(args
, flags
); 
 794                 mode 
= va_arg(args
, mode_t
); 
 798         if (!strcmp (pathname
, "/dev/windrvr6")) { 
 799                 DPRINTF("opening windrvr6\n"); 
 801                 windrvrfd 
= fd 
= (*func
) ("/dev/null", flags
, mode
); 
 803                 windrvrfd 
= fd 
= (*func
) (pathname
, flags
, mode
); 
 810                         busses 
= usb_get_busses(); 
 816         return (*func
) (pathname
, flags
, mode
); 
 820         static int (*func
) (int) = NULL
; 
 823                 func 
= (int (*) (int)) dlsym(RTLD_NEXT
, "close"); 
 825         if (fd 
== windrvrfd 
&& windrvrfd 
>= 0) { 
 826                 DPRINTF("close windrvrfd\n"); 
 827                 if (usbinterface 
>= 0) 
 828                         usb_release_interface(usb_devhandle
, usbinterface
); 
 831                         usb_close(usb_devhandle
); 
 833                 usb_devhandle 
= NULL
; 
 841 FILE *fopen(const char *path
, const char *mode
) { 
 843         static FILE* (*func
) (const char*, const char*) = NULL
; 
 848                 func 
= (FILE* (*) (const char*, const char*)) dlsym(RTLD_NEXT
, "fopen"); 
 850         for (i 
= 0; i 
< 4; i
++) { 
 851                 snprintf(buf
, sizeof(buf
), "/proc/sys/dev/parport/parport%d/base-addr", i
); 
 852                 if (!strcmp(path
, buf
)) { 
 853                         DPRINTF("open base-addr of parport%d\n", i
); 
 854                         if (config_is_real_pport(i
)) { 
 855                                 ret 
= (*func
) (path
, mode
); 
 857                                 ret 
= (*func
) ("/dev/null", mode
); 
 869         ret 
= (*func
) (path
, mode
); 
 871         if (!strcmp(path
, "/proc/modules")) { 
 872                 DPRINTF("opening /proc/modules\n"); 
 882 char *fgets(char *s
, int size
, FILE *stream
) { 
 883         static char* (*func
) (char*, int, FILE*) = NULL
; 
 884         const char modules
[][256] = {"windrvr6 1 0 - Live 0xdeadbeef\n", "parport_pc 1 0 - Live 0xdeadbeef\n"}; 
 890                 func 
= (char* (*) (char*, int, FILE*)) dlsym(RTLD_NEXT
, "fgets"); 
 892         if (modulesfp 
== stream
) { 
 893                 if (modules_read 
< sizeof(modules
) / sizeof(modules
[0])) { 
 894                         strcpy(s
, modules
[modules_read
]); 
 898         } else if (baseaddrfp 
== stream
) { 
 899                 snprintf(s
, sizeof(buf
), "%d\t%d\n", 
 900                         (baseaddrnum
) * 0x10, 
 901                         ((baseaddrnum
) * 0x10) + 0x400); 
 904                 ret 
= (*func
)(s
,size
,stream
); 
 910 int fclose(FILE *fp
) { 
 911         static int (*func
) (FILE*) = NULL
; 
 914                 func 
= (int (*) (FILE*)) dlsym(RTLD_NEXT
, "fclose"); 
 916         if (fp 
== modulesfp
) { 
 920         if (fp 
== baseaddrfp
) { 
 927 int access(const char *pathname
, int mode
) { 
 928         static int (*func
) (const char*, int); 
 931                 func 
= (int (*) (const char*, int)) dlsym(RTLD_NEXT
, "access"); 
 933         if (pathname 
&& !strcmp(pathname
, "/dev/windrvr6")) { 
 936                 return (*func
)(pathname
, mode
);