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 <linux/parport.h> 
  43 #include <linux/ppdev.h> 
  44 #include "usb-driver.h" 
  50 static int (*ioctl_func
) (int, int, void *) = NULL
; 
  51 static int windrvrfd 
= -1; 
  52 static int parportfd 
= -1; 
  53 static unsigned long ppbase 
= 0; 
  54 static unsigned long ecpbase 
= 0; 
  55 FILE *modulesfp 
= NULL
; 
  56 FILE *baseaddrfp 
= NULL
; 
  58 static int modules_read 
= 0; 
  59 static struct usb_bus 
*busses 
= NULL
; 
  60 static struct usb_device 
*usbdevice
; 
  61 static usb_dev_handle 
*usb_devhandle 
= NULL
; 
  62 static int usbinterface 
= -1; 
  63 static unsigned long card_type
; 
  64 static int ints_enabled 
= 0; 
  65 static pthread_mutex_t int_wait 
= PTHREAD_MUTEX_INITIALIZER
; 
  69 void hexdump(unsigned char *buf
, int len
) { 
  72         for(i
=0; i
<len
; i
++) { 
  73                 fprintf(stderr
,"%02x ", buf
[i
]); 
  80 int usb_deviceinfo(unsigned char *buf
) { 
  83         WDU_CONFIGURATION 
**pConfigs
, **pActiveConfig
; 
  84         WDU_INTERFACE 
**pActiveInterface
; 
  87                 struct usb_device_info 
*udi 
= (struct usb_device_info
*)(buf
+len
); 
  89                 udi
->Descriptor
.bLength 
= sizeof(WDU_DEVICE_DESCRIPTOR
); 
  90                 udi
->Descriptor
.bDescriptorType 
= usbdevice
->descriptor
.bDescriptorType
; 
  91                 udi
->Descriptor
.bcdUSB 
= usbdevice
->descriptor
.bcdUSB
; 
  92                 udi
->Descriptor
.bDeviceClass 
= usbdevice
->descriptor
.bDeviceClass
; 
  93                 udi
->Descriptor
.bDeviceSubClass 
= usbdevice
->descriptor
.bDeviceSubClass
; 
  94                 udi
->Descriptor
.bDeviceProtocol 
= usbdevice
->descriptor
.bDeviceProtocol
; 
  95                 udi
->Descriptor
.bMaxPacketSize0 
= usbdevice
->descriptor
.bMaxPacketSize0
; 
  96                 udi
->Descriptor
.idVendor 
= usbdevice
->descriptor
.idVendor
; 
  97                 udi
->Descriptor
.idProduct 
= usbdevice
->descriptor
.idProduct
; 
  98                 udi
->Descriptor
.bcdDevice 
= usbdevice
->descriptor
.bcdDevice
; 
  99                 udi
->Descriptor
.iManufacturer 
= usbdevice
->descriptor
.iManufacturer
; 
 100                 udi
->Descriptor
.iProduct 
= usbdevice
->descriptor
.iProduct
; 
 101                 udi
->Descriptor
.iSerialNumber 
= usbdevice
->descriptor
.iSerialNumber
; 
 102                 udi
->Descriptor
.bNumConfigurations 
= usbdevice
->descriptor
.bNumConfigurations
; 
 104                 /* TODO: Fix Pipe0! */ 
 105                 udi
->Pipe0
.dwNumber 
= 0x00; 
 106                 udi
->Pipe0
.dwMaximumPacketSize 
= usbdevice
->descriptor
.bMaxPacketSize0
; 
 108                 udi
->Pipe0
.direction 
= WDU_DIR_IN_OUT
; 
 109                 udi
->Pipe0
.dwInterval 
= 0; 
 111                 pConfigs 
= &(udi
->pConfigs
); 
 112                 pActiveConfig 
= &(udi
->pActiveConfig
); 
 113                 pActiveInterface 
= &(udi
->pActiveInterface
[0]); 
 116         len 
= sizeof(struct usb_device_info
); 
 118         for (i
=0; i
<usbdevice
->descriptor
.bNumConfigurations
; i
++) 
 120                 struct usb_config_descriptor 
*conf_desc 
= &usbdevice
->config
[i
]; 
 121                 WDU_INTERFACE 
**pInterfaces
; 
 122                 WDU_ALTERNATE_SETTING 
**pAlternateSettings
[conf_desc
->bNumInterfaces
]; 
 123                 WDU_ALTERNATE_SETTING 
**pActiveAltSetting
[conf_desc
->bNumInterfaces
]; 
 126                         WDU_CONFIGURATION 
*cfg 
= (WDU_CONFIGURATION
*)(buf
+len
); 
 129                         *pActiveConfig 
= cfg
; 
 131                         cfg
->Descriptor
.bLength 
= conf_desc
->bLength
; 
 132                         cfg
->Descriptor
.bDescriptorType 
= conf_desc
->bDescriptorType
; 
 133                         cfg
->Descriptor
.wTotalLength 
= conf_desc
->wTotalLength
; 
 134                         cfg
->Descriptor
.bNumInterfaces 
= conf_desc
->bNumInterfaces
; 
 135                         cfg
->Descriptor
.bConfigurationValue 
= conf_desc
->bConfigurationValue
; 
 136                         cfg
->Descriptor
.iConfiguration 
= conf_desc
->iConfiguration
; 
 137                         cfg
->Descriptor
.bmAttributes 
= conf_desc
->bmAttributes
; 
 138                         cfg
->Descriptor
.MaxPower 
= conf_desc
->MaxPower
; 
 140                         cfg
->dwNumInterfaces 
= conf_desc
->bNumInterfaces
; 
 142                         pInterfaces 
= &(cfg
->pInterfaces
); 
 144                 len 
+= sizeof(WDU_CONFIGURATION
); 
 147                         *pInterfaces 
= (WDU_INTERFACE
*)(buf
+len
); 
 148                         for (j
=0; j
<conf_desc
->bNumInterfaces
; j
++) { 
 149                                 WDU_INTERFACE 
*iface 
= (WDU_INTERFACE
*)(buf
+len
); 
 151                                 pActiveInterface
[j
] = iface
; 
 153                                 pAlternateSettings
[j
] = &(iface
->pAlternateSettings
); 
 154                                 iface
->dwNumAltSettings 
= usbdevice
->config
[i
].interface
[j
].num_altsetting
; 
 155                                 pActiveAltSetting
[j
] = &(iface
->pActiveAltSetting
); 
 157                                 len 
+= sizeof(WDU_INTERFACE
); 
 160                         len 
+= sizeof(WDU_INTERFACE
) * conf_desc
->bNumInterfaces
; 
 163                 for (j
=0; j
<conf_desc
->bNumInterfaces
; j
++) 
 165                         struct usb_interface 
*interface 
= &usbdevice
->config
[i
].interface
[j
]; 
 168                                 *pAlternateSettings
[j
] = (WDU_ALTERNATE_SETTING
*)(buf
+len
); 
 170                                 *pActiveAltSetting
[j
] = (WDU_ALTERNATE_SETTING
*)(buf
+len
); 
 173                         for(k
=0; k
<interface
->num_altsetting
; k
++) 
 175                                 unsigned char bNumEndpoints 
= interface
->altsetting
[k
].bNumEndpoints
; 
 176                                 WDU_ENDPOINT_DESCRIPTOR 
**pEndpointDescriptors
; 
 177                                 WDU_PIPE_INFO 
**pPipes
; 
 180                                         WDU_ALTERNATE_SETTING 
*altset 
= (WDU_ALTERNATE_SETTING
*)(buf
+len
); 
 182                                         altset
->Descriptor
.bLength 
= interface
->altsetting
[k
].bLength
; 
 183                                         altset
->Descriptor
.bDescriptorType 
= interface
->altsetting
[k
].bDescriptorType
; 
 184                                         altset
->Descriptor
.bInterfaceNumber 
= interface
->altsetting
[k
].bInterfaceNumber
; 
 185                                         altset
->Descriptor
.bAlternateSetting 
= interface
->altsetting
[k
].bAlternateSetting
; 
 186                                         altset
->Descriptor
.bNumEndpoints 
= interface
->altsetting
[k
].bNumEndpoints
; 
 187                                         altset
->Descriptor
.bInterfaceClass 
= interface
->altsetting
[k
].bInterfaceClass
; 
 188                                         altset
->Descriptor
.bInterfaceSubClass 
= interface
->altsetting
[k
].bInterfaceSubClass
; 
 189                                         altset
->Descriptor
.bInterfaceProtocol 
= interface
->altsetting
[k
].bInterfaceProtocol
; 
 190                                         altset
->Descriptor
.iInterface 
= interface
->altsetting
[k
].iInterface
; 
 191                                         pEndpointDescriptors 
= &(altset
->pEndpointDescriptors
); 
 192                                         pPipes 
= &(altset
->pPipes
); 
 195                                 len 
+=sizeof(WDU_ALTERNATE_SETTING
); 
 198                                         *pEndpointDescriptors 
= (WDU_ENDPOINT_DESCRIPTOR
*)(buf
+len
); 
 199                                         for (l 
= 0; l 
< bNumEndpoints
; l
++) { 
 200                                                 WDU_ENDPOINT_DESCRIPTOR 
*ed 
= (WDU_ENDPOINT_DESCRIPTOR
*)(buf
+len
); 
 202                                                 ed
->bLength 
= interface
->altsetting
[k
].endpoint
[l
].bLength
; 
 203                                                 ed
->bDescriptorType 
= interface
->altsetting
[k
].endpoint
[l
].bDescriptorType
; 
 204                                                 ed
->bEndpointAddress 
= interface
->altsetting
[k
].endpoint
[l
].bEndpointAddress
; 
 205                                                 ed
->bmAttributes 
= interface
->altsetting
[k
].endpoint
[l
].bmAttributes
; 
 206                                                 ed
->wMaxPacketSize 
= interface
->altsetting
[k
].endpoint
[l
].wMaxPacketSize
; 
 207                                                 ed
->bInterval 
= interface
->altsetting
[k
].endpoint
[l
].bInterval
; 
 209                                                 len 
+= sizeof(WDU_ENDPOINT_DESCRIPTOR
); 
 212                                         *pPipes 
= (WDU_PIPE_INFO
*)(buf
+len
); 
 213                                         for (l 
= 0; l 
< bNumEndpoints
; l
++) { 
 214                                                 WDU_PIPE_INFO 
*pi 
= (WDU_PIPE_INFO
*)(buf
+len
); 
 216                                                 pi
->dwNumber 
= interface
->altsetting
[k
].endpoint
[l
].bEndpointAddress
; 
 217                                                 pi
->dwMaximumPacketSize 
= WDU_GET_MAX_PACKET_SIZE(interface
->altsetting
[k
].endpoint
[l
].wMaxPacketSize
); 
 218                                                 pi
->type 
= interface
->altsetting
[k
].endpoint
[l
].bmAttributes 
& USB_ENDPOINT_TYPE_MASK
; 
 219                                                 if (pi
->type 
== PIPE_TYPE_CONTROL
) 
 220                                                         pi
->direction 
= WDU_DIR_IN_OUT
; 
 223                                                         pi
->direction 
= interface
->altsetting
[k
].endpoint
[l
].bEndpointAddress 
& USB_ENDPOINT_DIR_MASK 
?  WDU_DIR_IN 
: WDU_DIR_OUT
; 
 226                                                 pi
->dwInterval 
= interface
->altsetting
[k
].endpoint
[l
].bInterval
; 
 228                                                 len 
+= sizeof(WDU_PIPE_INFO
); 
 231                                         len 
+=(sizeof(WDU_ENDPOINT_DESCRIPTOR
)+sizeof(WDU_PIPE_INFO
))*bNumEndpoints
; 
 240 int pp_transfer(WD_TRANSFER 
*tr
, int fd
, unsigned int request
) { 
 242         unsigned long port 
= (unsigned long)tr
->dwPort
; 
 244         static unsigned char last_pp_write 
= 0; 
 246         DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n", 
 247                         (unsigned long)tr
->dwPort
, tr
->cmdTrans
, tr
->dwBytes
, 
 248                         tr
->fAutoinc
, tr
->dwOptions
); 
 253         if (tr
->cmdTrans 
== 13) 
 254                 DPRINTF("write byte: %d\n", val
); 
 260         if (port 
== ppbase 
+ PP_DATA
) { 
 261                 DPRINTF("data port\n"); 
 262                 switch(tr
->cmdTrans
) { 
 264                                 ret 
= 0; /* We don't support reading of the data port */ 
 268                                 ret 
= ioctl(parportfd
, PPWDATA
, &val
); 
 273                                 fprintf(stderr
,"!!!Unsupported TRANSFER command: %lu!!!\n", tr
->cmdTrans
); 
 277         } else if (port 
== ppbase 
+ PP_STATUS
) { 
 278                 DPRINTF("status port (last write: %d)\n", last_pp_write
); 
 279                 switch(tr
->cmdTrans
) { 
 281                                 ret 
= ioctl(parportfd
, PPRSTATUS
, &val
); 
 282 #ifdef FORCE_PC3_IDENT 
 284                                 if (last_pp_write 
& 0x40) 
 292                                 ret 
= 0; /* Status Port is readonly */ 
 296                                 fprintf(stderr
,"!!!Unsupported TRANSFER command: %lu!!!\n", tr
->cmdTrans
); 
 300         } else if (port 
== ppbase 
+ PP_CONTROL
) { 
 301                 DPRINTF("control port\n"); 
 302                 switch(tr
->cmdTrans
) { 
 304                                 ret 
= ioctl(parportfd
, PPRCONTROL
, &val
); 
 308                                 ret 
= ioctl(parportfd
, PPWCONTROL
, &val
); 
 312                                 fprintf(stderr
,"!!!Unsupported TRANSFER command: %lu!!!\n", tr
->cmdTrans
); 
 316         } else if ((port 
== ecpbase 
+ PP_ECP_CFGA
) && ecpbase
) { 
 317                 DPRINTF("ECP_CFGA port\n"); 
 318         } else if ((port 
== ecpbase 
+ PP_ECP_CFGB
) && ecpbase
) { 
 319                 DPRINTF("ECP_CFGB port\n"); 
 320         } else if ((port 
== ecpbase 
+ PP_ECP_ECR
) && ecpbase
) { 
 321                 DPRINTF("ECP_ECR port\n"); 
 323                 DPRINTF("access to unsupported address range!\n"); 
 329         DPRINTF("dwPortReturn: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n", 
 330                         (unsigned long)tr
->dwPort
, tr
->cmdTrans
, tr
->dwBytes
, 
 331                         tr
->fAutoinc
, tr
->dwOptions
); 
 333         if (tr
->cmdTrans 
== 10) 
 334                 DPRINTF("read byte: %d\n", tr
->Data
.Byte
); 
 340 int do_wdioctl(int fd
, unsigned int request
, unsigned char *wdioctl
) { 
 341         struct header_struct
* wdheader 
= (struct header_struct
*)wdioctl
; 
 342         struct version_struct 
*version
; 
 345         if (wdheader
->magic 
!= MAGIC
) { 
 346                 fprintf(stderr
,"!!!ERROR: magic header does not match!!!\n"); 
 347                 return (*ioctl_func
) (fd
, request
, wdioctl
); 
 350         switch(request 
& ~(0xc0000000)) { 
 352                         version 
= (struct version_struct
*)(wdheader
->data
); 
 353                         strcpy(version
->version
, "libusb-driver.so $Revision: 1.66 $"); 
 354                         version
->versionul 
= 802; 
 355                         DPRINTF("VERSION\n"); 
 359                         DPRINTF("LICENSE\n"); 
 362                 case CARD_REGISTER_OLD
: 
 364                         DPRINTF("CARD_REGISTER\n"); 
 366                                 struct card_register
* cr 
= (struct card_register
*)(wdheader
->data
); 
 369                                 DPRINTF("Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n", 
 371                                 (unsigned long)cr
->Card
.Item
[0].I
.IO
.dwAddr
, 
 372                                 cr
->Card
.Item
[0].I
.IO
.dwBytes
, 
 373                                 cr
->Card
.Item
[0].I
.IO
.dwBar
); 
 375                                 DPRINTF("Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n", 
 377                                 (unsigned long)cr
->Card
.Item
[1].I
.IO
.dwAddr
, 
 378                                 cr
->Card
.Item
[1].I
.IO
.dwBytes
, 
 379                                 cr
->Card
.Item
[1].I
.IO
.dwBar
); 
 381                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 385                                 if (!config_is_real_pport((unsigned long)cr
->Card
.Item
[0].I
.IO
.dwAddr 
/ 0x10)) { 
 386                                         int num 
= (unsigned long)cr
->Card
.Item
[0].I
.IO
.dwAddr 
/ 0x10; 
 388                                         ret
=jtagkey_init(config_usb_vid(num
), config_usb_pid(num
)); 
 390                                         ppbase 
= (unsigned long)cr
->Card
.Item
[0].I
.IO
.dwAddr
; 
 399                                         snprintf(ppdev
, sizeof(ppdev
), "/dev/parport%lu", 
 400                                                         (unsigned long)cr
->Card
.Item
[0].I
.IO
.dwAddr 
/ 0x10); 
 401                                         DPRINTF("opening %s\n", ppdev
); 
 402                                         parportfd 
= open(ppdev
, O_RDWR
|O_EXCL
); 
 405                                                 fprintf(stderr
,"Can't open %s: %s\n", ppdev
, strerror(errno
)); 
 408                                 if (parportfd 
>= 0) { 
 411                                         if (ioctl(parportfd
, PPCLAIM
) == -1) 
 415                                         pmode 
= IEEE1284_MODE_COMPAT
; 
 416                                         if (ioctl(parportfd
, PPNEGOT
, &pmode
) == -1) 
 419                                         if (cr
->Card
.dwItems 
> 1 && cr
->Card
.Item
[1].I
.IO
.dwAddr
) { 
 420                                                 DPRINTF("ECP mode requested\n"); 
 421                                                 ecpbase 
= (unsigned long)cr
->Card
.Item
[1].I
.IO
.dwAddr
; 
 422                                                 /* TODO: Implement ECP mode */ 
 424                                                 pmode 
= IEEE1284_MODE_ECP
; 
 426                                                 if (ioctl(parportfd
, PPNEGOT
, &pmode
) == -1) { 
 428                                                         pmode 
= IEEE1284_MODE_COMPAT
; 
 429                                                         if (ioctl(parportfd
, PPNEGOT
, &pmode
) == -1) 
 435                                         cr
->hCard 
= parportfd
; 
 438                                 ppbase 
= (unsigned long)cr
->Card
.Item
[0].I
.IO
.dwAddr
; 
 442                                 DPRINTF("hCard: %lu\n", cr
->hCard
); 
 447                         DPRINTF("in USB_TRANSFER"); 
 449                                 struct usb_transfer 
*ut 
= (struct usb_transfer
*)(wdheader
->data
); 
 452                                 DPRINTF(" unique: %lu, pipe: %lu, read: %lu, options: %lx, size: %lu, timeout: %lx\n", 
 453                                 ut
->dwUniqueID
, ut
->dwPipeNum
, ut
->fRead
, 
 454                                 ut
->dwOptions
, ut
->dwBufferSize
, ut
->dwTimeout
); 
 455                                 DPRINTF("setup packet: "); 
 456                                 hexdump(ut
->SetupPacket
, 8); 
 458                                 if (!ut
->fRead 
&& ut
->dwBufferSize
) 
 460                                         hexdump(ut
->pBuffer
, ut
->dwBufferSize
); 
 465                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 467                                 /* http://www.jungo.com/support/documentation/windriver/802/wdusb_man_mhtml/node55.html#SECTION001213000000000000000 */ 
 468                                 if (ut
->dwPipeNum 
== 0) { /* control pipe */ 
 469                                         int requesttype
, request
, value
, index
, size
; 
 470                                         requesttype 
= ut
->SetupPacket
[0]; 
 471                                         request 
= ut
->SetupPacket
[1]; 
 472                                         value 
= ut
->SetupPacket
[2] | (ut
->SetupPacket
[3] << 8); 
 473                                         index 
= ut
->SetupPacket
[4] | (ut
->SetupPacket
[5] << 8); 
 474                                         size 
= ut
->SetupPacket
[6] | (ut
->SetupPacket
[7] << 8); 
 475                                         DPRINTF("requesttype: %x, request: %x, value: %u, index: %u, size: %u\n", requesttype
, request
, value
, index
, size
); 
 476                                         ret 
= usb_control_msg(usb_devhandle
, requesttype
, request
, value
, index
, ut
->pBuffer
, size
, ut
->dwTimeout
); 
 479                                                 ret 
= usb_bulk_read(usb_devhandle
, ut
->dwPipeNum
, ut
->pBuffer
, ut
->dwBufferSize
, ut
->dwTimeout
); 
 482                                                 ret 
= usb_bulk_write(usb_devhandle
, ut
->dwPipeNum
, ut
->pBuffer
, ut
->dwBufferSize
, ut
->dwTimeout
); 
 487                                         fprintf(stderr
, "usb_transfer: %d (%s)\n", ret
, usb_strerror()); 
 489                                         ut
->dwBytesTransferred 
= ret
; 
 495                                 DPRINTF("Transferred: %lu (%s)\n",ut
->dwBytesTransferred
, (ut
->fRead
?"read":"write")); 
 496                                 if (ut
->fRead 
&& ut
->dwBytesTransferred
) 
 499                                         hexdump(ut
->pBuffer
, ut
->dwBytesTransferred
); 
 507                         DPRINTF("INT_ENABLE\n"); 
 509                                 struct interrupt 
*it 
= (struct interrupt
*)(wdheader
->data
); 
 511                                 DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", 
 512                                 it
->hInterrupt
, it
->dwOptions
, 
 513                                 it
->dwCmds
, it
->fEnableOk
, it
->dwCounter
, 
 514                                 it
->dwLost
, it
->fStopped
); 
 519                                 pthread_mutex_trylock(&int_wait
); 
 525                         DPRINTF("INT_DISABLE\n"); 
 527                                 struct interrupt 
*it 
= (struct interrupt
*)(wdheader
->data
); 
 529                                 DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", 
 530                                 it
->hInterrupt
, it
->dwOptions
, 
 531                                 it
->dwCmds
, it
->fEnableOk
, it
->dwCounter
, 
 532                                 it
->dwLost
, it
->fStopped
); 
 534                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 539                                 if (pthread_mutex_trylock(&int_wait
) == EBUSY
) 
 540                                         pthread_mutex_unlock(&int_wait
); 
 542                                 DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", 
 543                                 it
->hInterrupt
, it
->dwOptions
, 
 544                                 it
->dwCmds
, it
->fEnableOk
, it
->dwCounter
, 
 545                                 it
->dwLost
, it
->fStopped
); 
 549                 case USB_SET_INTERFACE
: 
 550                         DPRINTF("USB_SET_INTERFACE\n"); 
 552                                 struct usb_set_interface 
*usi 
= (struct usb_set_interface
*)(wdheader
->data
); 
 554                                 DPRINTF("unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", 
 555                                 usi
->dwUniqueID
, usi
->dwInterfaceNum
, 
 556                                 usi
->dwAlternateSetting
, usi
->dwOptions
); 
 558                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 562                                                 usb_devhandle 
= usb_open(usbdevice
); 
 564                                         /* FIXME: Select right interface! */ 
 565                                         ret 
= usb_claim_interface(usb_devhandle
, usbdevice
->config
[0].interface
[usi
->dwInterfaceNum
].altsetting
[usi
->dwAlternateSetting
].bInterfaceNumber
); 
 568                                                         usbinterface 
= usbdevice
->config
[0].interface
[usi
->dwInterfaceNum
].altsetting
[usi
->dwAlternateSetting
].bInterfaceNumber
; 
 569                                                         ret 
= usb_set_altinterface(usb_devhandle
, usi
->dwAlternateSetting
); 
 571                                                                 fprintf(stderr
, "usb_set_altinterface: %d\n", ret
); 
 573                                                         fprintf(stderr
, "usb_set_configuration: %d (%s)\n", ret
, usb_strerror()); 
 576                                                 fprintf(stderr
, "usb_claim_interface: %d -> %d (%s)\n", 
 577                                                 usbdevice
->config
[0].interface
[usi
->dwInterfaceNum
].altsetting
[usi
->dwAlternateSetting
].bInterfaceNumber
, 
 578                                                 ret
, usb_strerror()); 
 582                                 DPRINTF("unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", 
 583                                 usi
->dwUniqueID
, usi
->dwInterfaceNum
, 
 584                                 usi
->dwAlternateSetting
, usi
->dwOptions
); 
 588                 case USB_GET_DEVICE_DATA_OLD
: 
 589                 case USB_GET_DEVICE_DATA
: 
 590                         DPRINTF("USB_GET_DEVICE_DATA\n"); 
 592                                 struct usb_get_device_data 
*ugdd 
= (struct usb_get_device_data
*)(wdheader
->data
); 
 595                                 DPRINTF("unique: %lu, bytes: %lu, options: %lx\n", 
 596                                 ugdd
->dwUniqueID
, ugdd
->dwBytes
, 
 599                                 pSize 
= ugdd
->dwBytes
; 
 600                                 if (!ugdd
->dwBytes
) { 
 602                                                 ugdd
->dwBytes 
= usb_deviceinfo(NULL
); 
 605                                         usb_deviceinfo((unsigned char*)ugdd
->pBuf
); 
 610                 case EVENT_REGISTER_OLD
: 
 612                         DPRINTF("EVENT_REGISTER\n"); 
 614                                 struct event 
*e 
= (struct event
*)(wdheader
->data
); 
 618                                 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", 
 619                                 e
->handle
, e
->dwAction
, 
 620                                 e
->dwStatus
, e
->dwEventId
, e
->dwCardType
, 
 621                                 e
->hKernelPlugIn
, e
->dwOptions
, 
 622                                 e
->u
.Usb
.deviceId
.dwVendorId
, 
 623                                 e
->u
.Usb
.deviceId
.dwProductId
, 
 624                                 e
->u
.Usb
.dwUniqueID
, e
->dwEventVer
, 
 625                                 e
->dwNumMatchTables
); 
 627                                 for (i 
= 0; i 
< e
->dwNumMatchTables
; i
++) { 
 629                                         DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", 
 630                                         e
->matchTables
[i
].VendorId
, 
 631                                         e
->matchTables
[i
].ProductId
, 
 632                                         e
->matchTables
[i
].bDeviceClass
, 
 633                                         e
->matchTables
[i
].bDeviceSubClass
, 
 634                                         e
->matchTables
[i
].bInterfaceClass
, 
 635                                         e
->matchTables
[i
].bInterfaceSubClass
, 
 636                                         e
->matchTables
[i
].bInterfaceProtocol
); 
 638                                         for (bus 
= busses
; bus
; bus 
= bus
->next
) { 
 639                                                 struct usb_device 
*dev
; 
 641                                                 for (dev 
= bus
->devices
; dev
; dev 
= dev
->next
) { 
 642                                                         struct usb_device_descriptor 
*desc 
= &(dev
->descriptor
); 
 644                                                         if((desc
->idVendor 
== e
->matchTables
[i
].VendorId
) && 
 645                                                            (desc
->idProduct 
== e
->matchTables
[i
].ProductId
) && 
 646                                                            (desc
->bDeviceClass 
== e
->matchTables
[i
].bDeviceClass
) && 
 647                                                            (desc
->bDeviceSubClass 
== e
->matchTables
[i
].bDeviceSubClass
)) { 
 649                                                                    for (ac 
= 0; ac 
< desc
->bNumConfigurations
; ac
++) { 
 650                                                                            struct usb_interface 
*interface 
= dev
->config
[ac
].interface
; 
 653                                                                            for (ai 
= 0; ai 
< interface
->num_altsetting
; ai
++) { 
 655                                                                                    DPRINTF("intclass: %x, intsubclass: %x, intproto: %x\n", 
 656                                                                                    interface
->altsetting
[i
].bInterfaceClass
, 
 657                                                                                    interface
->altsetting
[i
].bInterfaceSubClass
, 
 658                                                                                    interface
->altsetting
[i
].bInterfaceProtocol
); 
 660                                                                                    if ((interface
->altsetting
[ai
].bInterfaceSubClass 
== e
->matchTables
[i
].bInterfaceSubClass
) && 
 661                                                                                                    (interface
->altsetting
[ai
].bInterfaceProtocol 
== e
->matchTables
[i
].bInterfaceProtocol
)){ 
 662                                                                                            /* TODO: check interfaceClass! */ 
 663                                                                                            DPRINTF("found device with libusb\n"); 
 665                                                                                            card_type 
= e
->dwCardType
; 
 675                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 681                                 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", 
 682                                 e
->handle
, e
->dwAction
, 
 683                                 e
->dwStatus
, e
->dwEventId
, e
->dwCardType
, 
 684                                 e
->hKernelPlugIn
, e
->dwOptions
, 
 685                                 e
->u
.Usb
.deviceId
.dwVendorId
, 
 686                                 e
->u
.Usb
.deviceId
.dwProductId
, 
 687                                 e
->u
.Usb
.dwUniqueID
, e
->dwEventVer
, 
 688                                 e
->dwNumMatchTables
); 
 690                                 for (i 
= 0; i 
< e
->dwNumMatchTables
; i
++) 
 691                                         DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", 
 692                                         e
->matchTables
[i
].VendorId
, 
 693                                         e
->matchTables
[i
].ProductId
, 
 694                                         e
->matchTables
[i
].bDeviceClass
, 
 695                                         e
->matchTables
[i
].bDeviceSubClass
, 
 696                                         e
->matchTables
[i
].bInterfaceClass
, 
 697                                         e
->matchTables
[i
].bInterfaceSubClass
, 
 698                                         e
->matchTables
[i
].bInterfaceProtocol
); 
 705                         DPRINTF("TRANSFER\n"); 
 707                                 WD_TRANSFER 
*tr 
= (WD_TRANSFER
*)(wdheader
->data
); 
 710                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 714                                 if (!config_is_real_pport(ppbase 
/ 0x10)) { 
 715                                         ret 
= jtagkey_transfer(tr
, fd
, request
, ppbase
, ecpbase
, 1); 
 719                                 ret 
= pp_transfer(tr
, fd
, request
); 
 724                 case MULTI_TRANSFER_OLD
: 
 726                         DPRINTF("MULTI_TRANSFER\n"); 
 728                                 WD_TRANSFER 
*tr 
= (WD_TRANSFER
*)(wdheader
->data
); 
 729                                 unsigned long num 
= wdheader
->size
/sizeof(WD_TRANSFER
); 
 732                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 736                                 if (!config_is_real_pport(ppbase 
/ 0x10)) { 
 737                                         ret 
= jtagkey_transfer(tr
, fd
, request
, ppbase
, ecpbase
, num
); 
 742                                 for (i 
= 0; i 
< num
; i
++) { 
 743                                         DPRINTF("Transfer %d:\n", i
+1); 
 744                                         ret 
= pp_transfer(tr 
+ i
, fd
, request
); 
 750                 case EVENT_UNREGISTER
: 
 751                         DPRINTF("EVENT_UNREGISTER\n"); 
 753                         ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 758                         DPRINTF("INT_WAIT\n"); 
 760                                 struct interrupt 
*it 
= (struct interrupt
*)(wdheader
->data
); 
 762                                 DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", 
 763                                 it
->hInterrupt
, it
->dwOptions
, 
 764                                 it
->dwCmds
, it
->fEnableOk
, it
->dwCounter
, 
 765                                 it
->dwLost
, it
->fStopped
); 
 768                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 771                                         if (it
->dwCounter 
== 0) { 
 774                                                 pthread_mutex_lock(&int_wait
); 
 775                                                 pthread_mutex_unlock(&int_wait
); 
 778                                         pthread_mutex_lock(&int_wait
); 
 779                                         pthread_mutex_unlock(&int_wait
); 
 783                                 DPRINTF("INT_WAIT_RETURN: Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", 
 784                                 it
->hInterrupt
, it
->dwOptions
, it
->dwCmds
, 
 785                                 it
->fEnableOk
, it
->dwCounter
, it
->dwLost
, 
 790                 case CARD_UNREGISTER
: 
 791                         DPRINTF("CARD_UNREGISTER\n"); 
 793                                 struct card_register
* cr 
= (struct card_register
*)(wdheader
->data
); 
 795                                 DPRINTF("Addr: 0x%lx, bytes: %lu, bar: %lu\n", 
 796                                 (unsigned long)cr
->Card
.Item
[0].I
.IO
.dwAddr
, 
 797                                 cr
->Card
.Item
[0].I
.IO
.dwBytes
, 
 798                                 cr
->Card
.Item
[0].I
.IO
.dwBar
); 
 800                                 DPRINTF("hCard: %lu\n", cr
->hCard
); 
 803                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 806                                 if (cr
->hCard 
== 0xff) 
 810                                 if (parportfd 
== cr
->hCard 
&& parportfd 
>= 0) { 
 811                                         ioctl(parportfd
, PPRELEASE
); 
 820                         DPRINTF("EVENT_PULL\n"); 
 822                                 struct event 
*e 
= (struct event
*)(wdheader
->data
); 
 826                                 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", 
 827                                 e
->handle
, e
->dwAction
, e
->dwStatus
, 
 828                                 e
->dwEventId
, e
->dwCardType
, e
->hKernelPlugIn
, 
 829                                 e
->dwOptions
, e
->u
.Usb
.deviceId
.dwVendorId
, 
 830                                 e
->u
.Usb
.deviceId
.dwProductId
, 
 831                                 e
->u
.Usb
.dwUniqueID
, e
->dwEventVer
, 
 832                                 e
->dwNumMatchTables
); 
 834                                 for (i 
= 0; i 
< e
->dwNumMatchTables
; i
++) 
 835                                         DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", 
 836                                         e
->matchTables
[i
].VendorId
, 
 837                                         e
->matchTables
[i
].ProductId
, 
 838                                         e
->matchTables
[i
].bDeviceClass
, 
 839                                         e
->matchTables
[i
].bDeviceSubClass
, 
 840                                         e
->matchTables
[i
].bInterfaceClass
, 
 841                                         e
->matchTables
[i
].bInterfaceSubClass
, 
 842                                         e
->matchTables
[i
].bInterfaceProtocol
); 
 846                                 ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 849                                         struct usb_interface 
*interface 
= usbdevice
->config
->interface
; 
 851                                         e
->dwCardType 
= card_type
; 
 854                                         e
->u
.Usb
.dwUniqueID 
= 110; 
 855                                         e
->matchTables
[0].VendorId 
= usbdevice
->descriptor
.idVendor
; 
 856                                         e
->matchTables
[0].ProductId 
= usbdevice
->descriptor
.idProduct
; 
 857                                         e
->matchTables
[0].bDeviceClass 
= usbdevice
->descriptor
.bDeviceClass
; 
 858                                         e
->matchTables
[0].bDeviceSubClass 
= usbdevice
->descriptor
.bDeviceSubClass
; 
 859                                         e
->matchTables
[0].bInterfaceClass 
= interface
->altsetting
[0].bInterfaceClass
; 
 860                                         e
->matchTables
[0].bInterfaceSubClass 
= interface
->altsetting
[0].bInterfaceSubClass
; 
 861                                         e
->matchTables
[0].bInterfaceProtocol 
= interface
->altsetting
[0].bInterfaceProtocol
; 
 866                                 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", 
 867                                 e
->handle
, e
->dwAction
, e
->dwStatus
, 
 868                                 e
->dwEventId
, e
->dwCardType
, e
->hKernelPlugIn
, 
 869                                 e
->dwOptions
, e
->u
.Usb
.deviceId
.dwVendorId
, 
 870                                 e
->u
.Usb
.deviceId
.dwProductId
, 
 871                                 e
->u
.Usb
.dwUniqueID
, e
->dwEventVer
, 
 872                                 e
->dwNumMatchTables
); 
 874                                 for (i 
= 0; i 
< e
->dwNumMatchTables
; i
++) 
 875                                         DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", 
 876                                         e
->matchTables
[i
].VendorId
, 
 877                                         e
->matchTables
[i
].ProductId
, 
 878                                         e
->matchTables
[i
].bDeviceClass
, 
 879                                         e
->matchTables
[i
].bDeviceSubClass
, 
 880                                         e
->matchTables
[i
].bInterfaceClass
, 
 881                                         e
->matchTables
[i
].bInterfaceSubClass
, 
 882                                         e
->matchTables
[i
].bInterfaceProtocol
); 
 889                         fprintf(stderr
,"!!!Unsupported IOCTL: %x!!!\n", request
); 
 891                         ret 
= (*ioctl_func
) (fd
, request
, wdioctl
); 
 899 int ioctl(int fd
, unsigned long int request
, ...) { 
 905                 ioctl_func 
= (int (*) (int, int, void *)) dlsym (RTLD_NEXT
, "ioctl");              
 907         va_start (args
, request
); 
 908         argp 
= va_arg (args
, void *); 
 912                 ret 
= do_wdioctl(fd
, request
, argp
); 
 914                 ret 
= (*ioctl_func
) (fd
, request
, argp
); 
 919 int open (const char *pathname
, int flags
, ...) { 
 920         static int (*func
) (const char *, int, mode_t
) = NULL
; 
 926                 func 
= (int (*) (const char *, int, mode_t
)) dlsym (RTLD_NEXT
, "open"); 
 928         if (flags 
& O_CREAT
) { 
 929                 va_start(args
, flags
); 
 930                 mode 
= va_arg(args
, mode_t
); 
 934         if (!strcmp (pathname
, "/dev/windrvr6")) { 
 935                 DPRINTF("opening windrvr6\n"); 
 937                 windrvrfd 
= fd 
= (*func
) ("/dev/null", flags
, mode
); 
 939                 windrvrfd 
= fd 
= (*func
) (pathname
, flags
, mode
); 
 946                         busses 
= usb_get_busses(); 
 952         return (*func
) (pathname
, flags
, mode
); 
 956         static int (*func
) (int) = NULL
; 
 959                 func 
= (int (*) (int)) dlsym(RTLD_NEXT
, "close"); 
 961         if (fd 
== windrvrfd 
&& windrvrfd 
>= 0) { 
 962                 DPRINTF("close windrvrfd\n"); 
 963                 if (usbinterface 
>= 0) 
 964                         usb_release_interface(usb_devhandle
, usbinterface
); 
 967                         usb_close(usb_devhandle
); 
 969                 usb_devhandle 
= NULL
; 
 977 FILE *fopen(const char *path
, const char *mode
) { 
 979         static FILE* (*func
) (const char*, const char*) = NULL
; 
 984                 func 
= (FILE* (*) (const char*, const char*)) dlsym(RTLD_NEXT
, "fopen"); 
 986         for (i 
= 0; i 
< 4; i
++) { 
 987                 snprintf(buf
, sizeof(buf
), "/proc/sys/dev/parport/parport%d/base-addr", i
); 
 988                 if (!strcmp(path
, buf
)) { 
 989                         DPRINTF("open base-addr of parport%d\n", i
); 
 990                         if (config_is_real_pport(i
)) { 
 991                                 ret 
= (*func
) (path
, mode
); 
 993                                 ret 
= (*func
) ("/dev/null", mode
); 
1005         ret 
= (*func
) (path
, mode
); 
1007         if (!strcmp(path
, "/proc/modules")) { 
1008                 DPRINTF("opening /proc/modules\n"); 
1018 char *fgets(char *s
, int size
, FILE *stream
) { 
1019         static char* (*func
) (char*, int, FILE*) = NULL
; 
1020         const char modules
[][256] = {"windrvr6 1 0 - Live 0xdeadbeef\n", "parport_pc 1 0 - Live 0xdeadbeef\n"}; 
1026                 func 
= (char* (*) (char*, int, FILE*)) dlsym(RTLD_NEXT
, "fgets"); 
1028         if (modulesfp 
== stream
) { 
1029                 if (modules_read 
< sizeof(modules
) / sizeof(modules
[0])) { 
1030                         strcpy(s
, modules
[modules_read
]); 
1034         } else if (baseaddrfp 
== stream
) { 
1035                 snprintf(s
, sizeof(buf
), "%d\t%d\n", 
1036                         (baseaddrnum
) * 0x10, 
1037                         ((baseaddrnum
) * 0x10) + 0x400); 
1040                 ret 
= (*func
)(s
,size
,stream
); 
1046 int fclose(FILE *fp
) { 
1047         static int (*func
) (FILE*) = NULL
; 
1050                 func 
= (int (*) (FILE*)) dlsym(RTLD_NEXT
, "fclose"); 
1052         if (fp 
== modulesfp
) { 
1056         if (fp 
== baseaddrfp
) { 
1063 int access(const char *pathname
, int mode
) { 
1064         static int (*func
) (const char*, int); 
1067                 func 
= (int (*) (const char*, int)) dlsym(RTLD_NEXT
, "access"); 
1069         if (!strcmp(pathname
, "/dev/windrvr6")) { 
1072                 return (*func
)(pathname
, mode
);