X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/usb-driver/blobdiff_plain/77683ab696f183c63e8695063c8107d26809ed99..74ed4fbde86ab4aaa5e3480d66b510b771c7bd1e:/usb-driver.c diff --git a/usb-driver.c b/usb-driver.c index 929c101..1162d51 100644 --- a/usb-driver.c +++ b/usb-driver.c @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include "usb-driver.h" #include "config.h" @@ -47,14 +49,15 @@ static int windrvrfd = -1; static unsigned long ppbase = 0; static unsigned long ecpbase = 0; static struct parport_config *pport = NULL; -FILE *modulesfp = NULL; -FILE *baseaddrfp = NULL; -int baseaddrnum = 0; +static FILE *modulesfp = NULL; +static FILE *baseaddrfp = NULL; +static int baseaddrnum = 0; 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 int usbalternate = -1; static unsigned long card_type; static int ints_enabled = 0; static pthread_mutex_t int_wait = PTHREAD_MUTEX_INITIALIZER; @@ -72,7 +75,7 @@ void hexdump(unsigned char *buf, int len) { fprintf(stderr,"\n"); } -int usb_deviceinfo(unsigned char *buf) { +static int usb_deviceinfo(unsigned char *buf) { int i,j,k,l; int len = 0; WDU_CONFIGURATION **pConfigs, **pActiveConfig; @@ -232,7 +235,40 @@ int usb_deviceinfo(unsigned char *buf) { return len; } -int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { +static int usb_claim(int claim) { + int ret = 0; + static int claimed = 0; + + if (usbinterface < 0) + return -1; + + if (claim) { + if (claimed) + return 0; + + ret = usb_claim_interface(usb_devhandle, usbinterface); + if (!ret) { + claimed = 1; + ret = usb_set_altinterface(usb_devhandle, usbalternate); + if (ret) + fprintf(stderr, "usb_set_altinterface: %d\n", ret); + } else { + fprintf(stderr, "usb_claim_interface: %d -> %d (%s)\n", + usbinterface, ret, usb_strerror()); + } + } else { + if (!claimed) + return 0; + + ret = usb_release_interface(usb_devhandle, usbinterface); + if (!ret) + claimed = 0; + } + + return ret; +} + +static int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { struct header_struct* wdheader = (struct header_struct*)wdioctl; struct version_struct *version; int ret = 0; @@ -305,8 +341,10 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { DPRINTF(" unique: %lu, pipe: %lu, read: %lu, options: %lx, size: %lu, timeout: %lx\n", ut->dwUniqueID, ut->dwPipeNum, ut->fRead, ut->dwOptions, ut->dwBufferSize, ut->dwTimeout); - DPRINTF("setup packet: "); - hexdump(ut->SetupPacket, 8); + if (ut->dwPipeNum == 0) { + DPRINTF("setup packet: "); + hexdump(ut->SetupPacket, 8); + } if (!ut->fRead && ut->dwBufferSize) { @@ -317,6 +355,7 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else + usb_claim(1); /* http://www.jungo.com/support/documentation/windriver/802/wdusb_man_mhtml/node55.html#SECTION001213000000000000000 */ if (ut->dwPipeNum == 0) { /* control pipe */ int requesttype, request, value, index, size; @@ -330,10 +369,10 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { } else { if (ut->fRead) { ret = usb_bulk_read(usb_devhandle, ut->dwPipeNum, ut->pBuffer, ut->dwBufferSize, ut->dwTimeout); - } else { ret = usb_bulk_write(usb_devhandle, ut->dwPipeNum, ut->pBuffer, ut->dwBufferSize, ut->dwTimeout); } + usb_claim(0); } if (ret < 0) { @@ -411,25 +450,18 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { ret = (*ioctl_func) (fd, request, wdioctl); #else if (usbdevice) { - if (!usb_devhandle) + if (!usb_devhandle) { usb_devhandle = usb_open(usbdevice); - - /* FIXME: Select right interface! */ - 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); - } else { - fprintf(stderr, "usb_set_configuration: %d (%s)\n", ret, usb_strerror()); +#ifndef NO_USB_RESET + if (usb_devhandle) { + usb_reset(usb_devhandle); + usb_devhandle = usb_open(usbdevice); } - } else { - fprintf(stderr, "usb_claim_interface: %d -> %d (%s)\n", - usbdevice->config[0].interface[usi->dwInterfaceNum].altsetting[usi->dwAlternateSetting].bInterfaceNumber, - ret, usb_strerror()); +#endif } + + usbinterface = usbdevice->config[0].interface[usi->dwInterfaceNum].altsetting[usi->dwAlternateSetting].bInterfaceNumber; + usbalternate = usi->dwAlternateSetting; } #endif DPRINTF("unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", @@ -534,7 +566,7 @@ int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { (desc->idProduct == e->matchTables[i].ProductId) && (desc->bDeviceClass == e->matchTables[i].bDeviceClass) && (desc->bDeviceSubClass == e->matchTables[i].bDeviceSubClass) && - ((devnum == -1) || (dev->devnum == devnum)) ) { + ((devnum == -1) || (strtol(dev->filename, NULL, 10) == devnum)) ) { int ac; for (ac = 0; ac < desc->bNumConfigurations; ac++) { struct usb_interface *interface = dev->config[ac].interface; @@ -825,11 +857,11 @@ int close(int fd) { if (fd == windrvrfd && windrvrfd >= 0) { DPRINTF("close windrvrfd\n"); - if (usbinterface >= 0) - usb_release_interface(usb_devhandle, usbinterface); - if (usb_devhandle) + if (usb_devhandle) { + usb_claim(0); usb_close(usb_devhandle); + } usb_devhandle = NULL; usbinterface = -1; @@ -937,3 +969,21 @@ int access(const char *pathname, int mode) { return (*func)(pathname, mode); } } + +#if __WORDSIZE == 32 +int uname (struct utsname *__name) { + static int (*func) (struct utsname*); + int ret; + + if (!func) + func = (int (*) (struct utsname*)) dlsym(RTLD_NEXT, "uname"); + + ret = (*func)(__name); + + if (ret == 0 && (!strcmp(__name->machine, "x86_64"))) { + strcpy(__name->machine, "i686"); + } + + return ret; +} +#endif