#include <usb.h>
#include <signal.h>
#include <pthread.h>
+#include <errno.h>
+#include <inttypes.h>
#include "usb-driver.h"
static int (*ioctl_func) (int, int, void *) = NULL;
-static int windrvrfd = 0;
-FILE *modulesfp;
+static int windrvrfd = -1;
+FILE *modulesfp = NULL;
static int modules_read = 0;
static struct usb_bus *busses = NULL;
static struct usb_device *usbdevice;
static usb_dev_handle *usb_devhandle = NULL;
+static int usbinterface = -1;
static unsigned long card_type;
static int ints_enabled = 0;
static pthread_mutex_t int_wait = PTHREAD_MUTEX_INITIALIZER;
#define NO_WINDRVR 1
-#undef DEBUG
+#undef PARPORT
#ifdef DEBUG
#define DPRINTF(format, args...) fprintf(stderr, format, ##args)
return len;
}
+int pp_transfer(WD_TRANSFER *tr, int fd, unsigned int request, unsigned char *wdioctl) {
+ int ret = 0;
+
+ DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
+ (unsigned long)tr->dwPort, tr->cmdTrans, tr->dwBytes,
+ tr->fAutoinc, tr->dwOptions);
+
+#ifdef DEBUG
+ if (tr->cmdTrans == 13)
+ DPRINTF("write byte: %d\n", tr->Data.Byte);
+#endif
+
+#ifndef NO_WINDRVR
+ ret = (*ioctl_func) (fd, request, wdioctl);
+#endif
+
+ DPRINTF("dwPortReturn: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
+ (unsigned long)tr->dwPort, tr->cmdTrans, tr->dwBytes,
+ tr->fAutoinc, tr->dwOptions);
+#ifdef DEBUG
+ if (tr->cmdTrans == 10)
+ DPRINTF("read byte: %d\n", tr->Data.Byte);
+#endif
+
+ return ret;
+}
+
int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) {
struct header_struct* wdheader = (struct header_struct*)wdioctl;
struct version_struct *version;
return (*ioctl_func) (fd, request, wdioctl);
}
- switch(request) {
+ switch(request & ~(0xc0000000)) {
case VERSION:
version = (struct version_struct*)(wdheader->data);
strcpy(version->version, "WinDriver no more");
DPRINTF("LICENSE\n");
break;
+ case CARD_REGISTER_OLD:
case CARD_REGISTER:
/* TODO: Implement for LPT-support */
-#if 0
+#ifdef PARPORT
{
struct card_register* cr = (struct card_register*)(wdheader->data);
+#ifndef NO_WINDRVR
+ ret = (*ioctl_func) (fd, request, wdioctl);
+#else
+ /* TODO: Open /dev/parport, check, ... */
+ cr->hCard = 1;
+#endif
+ DPRINTF("hCard: %lu\n", cr->hCard);
}
#endif
DPRINTF("CARD_REGISTER\n");
}
break;
+ case INT_ENABLE_OLD:
case INT_ENABLE:
DPRINTF("INT_ENABLE\n");
{
it->dwLost, it->fStopped);
it->fEnableOk = 1;
+ it->fStopped = 0;
ints_enabled = 1;
pthread_mutex_trylock(&int_wait);
}
it->dwCounter = 0;
it->fStopped = 1;
ints_enabled = 0;
- pthread_mutex_unlock(&int_wait);
+ if (pthread_mutex_trylock(&int_wait) == EBUSY)
+ pthread_mutex_unlock(&int_wait);
#endif
DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n",
it->hInterrupt, it->dwOptions,
ret = usb_claim_interface(usb_devhandle, usbdevice->config[0].interface[usi->dwInterfaceNum].altsetting[usi->dwAlternateSetting].bInterfaceNumber);
if (!ret) {
if(!ret) {
+ usbinterface = usbdevice->config[0].interface[usi->dwInterfaceNum].altsetting[usi->dwAlternateSetting].bInterfaceNumber;
ret = usb_set_altinterface(usb_devhandle, usi->dwAlternateSetting);
if (ret)
fprintf(stderr, "usb_set_altinterface: %d\n", ret);
}
break;
+ case USB_GET_DEVICE_DATA_OLD:
case USB_GET_DEVICE_DATA:
DPRINTF("USB_GET_DEVICE_DATA\n");
{
}
break;
+ case EVENT_REGISTER_OLD:
case EVENT_REGISTER:
DPRINTF("EVENT_REGISTER\n");
{
}
break;
+ case TRANSFER_OLD:
case TRANSFER:
DPRINTF("TRANSFER\n");
+ {
+ WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);
+
+ ret = pp_transfer(tr, fd, request, wdioctl);
+ }
+ break;
+
+ case MULTI_TRANSFER:
+ DPRINTF("MULTI_TRANSFER\n");
+ {
+ WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);
+ unsigned long num = wdheader->size/sizeof(WD_TRANSFER);
+ int i;
+
+
+ for (i = 0; i < num; i++) {
+ DPRINTF("Transfer %d:\n", i+1);
#ifndef NO_WINDRVR
- ret = (*ioctl_func) (fd, request, wdioctl);
+ wdheader->size = sizeof(WD_TRANSFER);
+ request = TRANSFER;
+ wdheader->data = tr + i;
+#endif
+ ret = pp_transfer(tr + i, fd, request, wdioctl);
+ }
+
+#ifndef NO_WINDRVR
+ wdheader->data = tr;
#endif
+
+ return ret;
+ }
break;
case EVENT_UNREGISTER:
if (!func)
func = (int (*) (int)) dlsym(RTLD_NEXT, "close");
- if (fd == windrvrfd) {
+ if (fd == windrvrfd && windrvrfd >= 0) {
DPRINTF("close windrvrfd\n");
- windrvrfd = 0;
+ if (usbinterface >= 0)
+ usb_release_interface(usb_devhandle, usbinterface);
+
+ if (usb_devhandle)
+ usb_close(usb_devhandle);
+
+ usb_devhandle = NULL;
+ usbinterface = -1;
+ windrvrfd = -1;
}
return (*func) (fd);