?? usb-driver.c
字號:
/* libusb/ppdev connector for XILINX impact * * Copyright (c) 2007 Michael Gernoth <michael@gernoth.net> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */#define _GNU_SOURCE 1#include <dlfcn.h>#include <stdarg.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/time.h>#include <stdio.h>#include <signal.h>#include <errno.h>#include <inttypes.h>#include <sys/ioctl.h>#include <sys/utsname.h>#include <bits/wordsize.h>#include <sys/ipc.h>#include <sys/sem.h>#include "usb-driver.h"#include "config.h"#include "xpcu.h"static int (*ioctl_func) (int, int, void *) = NULL;static int *windrvrfds = NULL;static int windrvrfds_count = 0;static unsigned long ppbase = 0;static unsigned long ecpbase = 0;static struct parport_config *pport = NULL;static FILE *modulesfp = NULL;static FILE *baseaddrfp = NULL;static int baseaddrnum = 0;static int modules_read = 0;#define NO_WINDRVR 1void hexdump(unsigned char *buf, int len, char *prefix) { int i; fprintf(stderr, "%s ", prefix); for(i=0; i<len; i++) { fprintf(stderr,"%02x ", buf[i]); if ((i % 16) == 15) fprintf(stderr,"\n%s ", prefix); } fprintf(stderr,"\n");}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; if (wdheader->magic != MAGIC) { fprintf(stderr,"!!!ERROR: magic header does not match!!!\n"); return (*ioctl_func) (fd, request, wdioctl); } switch(request & ~(0xc0000000)) { case VERSION: version = (struct version_struct*)(wdheader->data); strcpy(version->version, "libusb-driver.so version: " USB_DRIVER_VERSION); version->versionul = 802; DPRINTF("VERSION\n"); break; case LICENSE: DPRINTF("LICENSE\n"); break; case CARD_REGISTER_OLD: case CARD_REGISTER: DPRINTF("CARD_REGISTER\n"); { struct card_register* cr = (struct card_register*)(wdheader->data); DPRINTF("-> Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n", cr->Card.dwItems, (unsigned long)cr->Card.Item[0].I.IO.dwAddr, cr->Card.Item[0].I.IO.dwBytes, cr->Card.Item[0].I.IO.dwBar); DPRINTF("-> Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n", cr->Card.dwItems, (unsigned long)cr->Card.Item[1].I.IO.dwAddr, cr->Card.Item[1].I.IO.dwBytes, cr->Card.Item[1].I.IO.dwBar);#ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl);#else pport = config_get((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10); if (!pport) break; ret = pport->open((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10); ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr; if (cr->Card.dwItems > 1 && cr->Card.Item[1].I.IO.dwAddr) ecpbase = (unsigned long)cr->Card.Item[1].I.IO.dwAddr; if (ret >= 0) { cr->hCard = ret; } else { cr->hCard = 0; }#endif DPRINTF("<-hCard: %lu\n", cr->hCard); } break; case USB_TRANSFER: DPRINTF("USB_TRANSFER\n"); { struct usb_transfer *ut = (struct usb_transfer*)(wdheader->data);#ifdef DEBUG DPRINTF("-> unique: 0x%lx, pipe: %lu, read: %lu, options: %lx, size: %lu, timeout: %lx\n", ut->dwUniqueID, ut->dwPipeNum, ut->fRead, ut->dwOptions, ut->dwBufferSize, ut->dwTimeout); if (ut->dwPipeNum == 0) { DPRINTF("-> setup packet:"); hexdump(ut->SetupPacket, 8, ""); } if (!ut->fRead && ut->dwBufferSize) { hexdump(ut->pBuffer, ut->dwBufferSize, "->"); }#endif#ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl);#else ret = xpcu_transfer(ut);#endif#ifdef DEBUG DPRINTF("Transferred: %lu (%s)\n",ut->dwBytesTransferred, (ut->fRead?"read":"write")); if (ut->fRead && ut->dwBytesTransferred) { hexdump(ut->pBuffer, ut->dwBytesTransferred, "<-"); }#endif } break; case INT_ENABLE_OLD: case INT_ENABLE: DPRINTF("INT_ENABLE\n"); { struct interrupt *it = (struct interrupt*)(wdheader->data); DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped);#ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl);#else ret = xpcu_int_state(it, ENABLE_INTERRUPT);#endif DPRINTF("<- Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped); } break; case INT_DISABLE: DPRINTF("INT_DISABLE\n"); { struct interrupt *it = (struct interrupt*)(wdheader->data); DPRINTF("-> Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped);#ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl);#else ret = xpcu_int_state(it, DISABLE_INTERRUPT);#endif DPRINTF("<- Handle: 0x%lx, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped); } break; case USB_SET_INTERFACE: DPRINTF("USB_SET_INTERFACE\n"); { struct usb_set_interface *usi = (struct usb_set_interface*)(wdheader->data); DPRINTF("-> unique: 0x%lx, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", usi->dwUniqueID, usi->dwInterfaceNum, usi->dwAlternateSetting, usi->dwOptions);#ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl);#else ret = xpcu_set_interface(usi);#endif DPRINTF("<- unique: 0x%lx, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", usi->dwUniqueID, usi->dwInterfaceNum, usi->dwAlternateSetting, usi->dwOptions); } break; case USB_GET_DEVICE_DATA_OLD: case USB_GET_DEVICE_DATA: DPRINTF("USB_GET_DEVICE_DATA\n"); { struct usb_get_device_data *ugdd = (struct usb_get_device_data*)(wdheader->data); DPRINTF("-> unique: 0x%lx, bytes: %lu, options: %lx\n", ugdd->dwUniqueID, ugdd->dwBytes, ugdd->dwOptions); ret = xpcu_deviceinfo(ugdd); } break; case EVENT_REGISTER_OLD: case EVENT_REGISTER: DPRINTF("EVENT_REGISTER\n"); { struct event *e = (struct event*)(wdheader->data);#ifdef DEBUG int i;#endif DPRINTF("-> handle: 0x%lx, action: %lu, status: %lu, eventid: %lu, cardtype: %lu, kplug: %lu, options: %lu, dev: %lx:%lx, unique: 0x%lx, ver: %lu, nummatch: %lu\n", e->handle, e->dwAction, e->dwStatus, e->dwEventId, e->dwCardType, e->hKernelPlugIn, e->dwOptions, e->u.Usb.deviceId.dwVendorId, e->u.Usb.deviceId.dwProductId, e->u.Usb.dwUniqueID, e->dwEventVer, e->dwNumMatchTables);#ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl);#else ret = xpcu_find(e);#endif#ifdef DEBUG DPRINTF("<- handle: 0x%lx, action: %lu, status: %lu, eventid: %lu, cardtype: %lu, kplug: %lu, options: %lu, dev: %lx:%lx, unique: 0x%lx, ver: %lu, nummatch: %lu\n", e->handle, e->dwAction, e->dwStatus, e->dwEventId, e->dwCardType, e->hKernelPlugIn, e->dwOptions, e->u.Usb.deviceId.dwVendorId, e->u.Usb.deviceId.dwProductId, e->u.Usb.dwUniqueID, e->dwEventVer, e->dwNumMatchTables); for (i = 0; i < e->dwNumMatchTables; i++) DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", e->matchTables[i].VendorId, e->matchTables[i].ProductId, e->matchTables[i].bDeviceClass, e->matchTables[i].bDeviceSubClass, e->matchTables[i].bInterfaceClass, e->matchTables[i].bInterfaceSubClass, e->matchTables[i].bInterfaceProtocol);#endif } break; case TRANSFER_OLD: case TRANSFER: DPRINTF("TRANSFER\n"); { WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data);#ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl);#else ret = pport->transfer(tr, fd, request, ppbase, ecpbase, 1);#endif } break; case MULTI_TRANSFER_OLD: case MULTI_TRANSFER: DPRINTF("MULTI_TRANSFER\n"); { WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data); unsigned long num = wdheader->size/sizeof(WD_TRANSFER);#ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl);#else ret = pport->transfer(tr, fd, request, ppbase, ecpbase, num);#endif } break; case EVENT_UNREGISTER: { struct event *e = (struct event*)(wdheader->data); DPRINTF("EVENT_UNREGISTER\n");#ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl);#else ret = xpcu_close(e);#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -