⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb-driver.c

📁 Xilinx USB下载线 Linux驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 + -