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

📄 tor2ee.c

📁 This a SOFTWARE pbx DRIVER
💻 C
📖 第 1 页 / 共 2 页
字号:
	word a,r;	int tries;	int retry=0;attempt_retry:	if (retry > 10) {		fprintf(stderr, "Maximum retries exceeded reading position %04x\n", addr);		exit(1);	}	/* Load the value to be written */	pci_write_long(dev, PLX_PCI_VPD_DATA, val);	/* Be sure we only execute a write */	a = addr | 0x8000;	pci_write_word(dev, PLX_PCI_VPD_ADDR, a);	tries = 0;	/* Wait for write to be validated */	for(;;) {		r = pci_read_word(dev, PLX_PCI_VPD_ADDR);		/* Wait a bit if it's not yet written */		if (r & 0x8000) {			tries++;			if (tries > 10) {				retry++;				goto attempt_retry;			}			usleep(1);		} else 			break;	} 	return 0;}static int read_pci_eeprom(struct pci_dev *dev, struct pci_eeprom *ee){	int x;	u_int32_t v, *tmp;	printf("Reading from EEPROM..");	fflush(stdout);	tmp = (u_int32_t *)(ee->data);	if (manual) {		for (x=0;x<sizeof(ee->data)/2;x++) {			ee->data[x] = plx_read_reg(x);			printf(".");			fflush(stdout);		}	} else {		for (x=0;x<sizeof(ee->data)/4;x++) {			v = read_eeprom_value(dev, x << 2);			ee->data[x * 2] = (v & 0xFFFF0000) >> 16;			ee->data[x * 2 + 1] = v & 0xFFFF;			printf(".");			fflush(stdout);		}	}	printf("Done\n");	return 0;}static int write_pci_eeprom(struct pci_dev *dev, struct pci_eeprom *ee){	int x;	u_int32_t v, *tmp;	int writeboundary;	writeboundary = ((word *)memw)[PLX_LOC_WP_BOUNDARY/2];	printf("Original Writeprotect boundary: %04x\n", writeboundary);	/* Turn off write protect */	((word *)memw)[PLX_LOC_WP_BOUNDARY/2] = 0;	printf("Writing to EEPROM..");	fflush(stdout);	if (manual) {		/* Enable writing */		plx_write_en();		/* Write values */		for (x=sizeof(ee->data)/2-1;x>=0;x--) {			plx_write_reg(x, (int)ee->data[x]);			printf(".");			fflush(stdout);		}	} else {		tmp = (u_int32_t *)(ee->data);		for (x=sizeof(ee->data)/4-1;x>=0;x--) {			v = (ee->data[x * 2] << 16) | ee->data[x * 2 + 1];			write_eeprom_value(dev, x << 2, v);			printf(".");			fflush(stdout);		}	}	printf("Done\n");	/* Restore write protect */	((word *)memw)[PLX_LOC_WP_BOUNDARY/2] = writeboundary;	return 0;}static int reset_pci_eeprom(struct pci_dev *dev){	int writeboundary;	writeboundary = ((word *)memw)[PLX_LOC_WP_BOUNDARY/2];	printf("Original Writeprotect boundary: %04x\n", writeboundary);	/* Turn off write protect */	((word *)memw)[PLX_LOC_WP_BOUNDARY/2] = 0;	printf("Resetting EEPROM..");	fflush(stdout);	/* Enable writing */	plx_write_en();	plx_write_all(0xffff);	printf("Done\n");	/* Restore write protect */	((word *)memw)[PLX_LOC_WP_BOUNDARY/2] = writeboundary;	return 0;}#if 0static void plx_reset(void){	unsigned short tmp;	tmp = ((word *)memw)[0x50/2];	printf("CNTRL: %04x\n", tmp);	tmp |= 0x4000;	printf("Writing: %04x\n", tmp);	tmp = ((word *)memw)[0x50/2];	printf("Readback: %04x\n", tmp);	sleep(1);	tmp = ((word *)memw)[0x50/2];	printf("CNTRL: %04x\n", tmp);	tmp &= ~0x4000;	((word *)memw)[0x50/2] = tmp;	tmp = ((word *)memw)[0x50/2];	printf("CNTRL: %04x\n", tmp);}#endifstatic void plx_manread(void){	int x;	unsigned short reg;#if 0	read_cntrl();	printf("Cntrl is %02x\n", cntrl);	cntrl &= ~0xf0ff;	printf("Clearing all signals\n");	write_cntrl();	fgetc(stdin);	printf("Setting CS\n");	cntrl |= BIT_EE_CS;	write_cntrl();	read_cntrl();	printf("New read: %04x\n", cntrl);	fgetc(stdin);	printf("Setting CLK\n");	cntrl &= ~BIT_EE_CS;	cntrl |= BIT_EE_CLK;	write_cntrl();	fgetc(stdin);	printf("Setting WR\n");	cntrl &= ~BIT_EE_CLK;	cntrl |= BIT_EE_WR;	write_cntrl();	fgetc(stdin);	cntrl &= ~BIT_EE_WR;	write_cntrl();#endif	for (x=0;x<NUM_REGS;x++) {		reg = plx_read_reg(x);		printf("0x%02x: %04x\n", x, reg);	}}static void dump_pci_eeprom(struct pci_eeprom *ee){	int x;	for (x=0;x<NUM_EEREGS;x++) 		printf("%60s(%04x): 0x%04x\n", eeregs[x].name, eeregs[x].pos, ee->data[eeregs[x].pos/2]);}static int read_eeprom_file(char *filename, struct pci_eeprom *ee){	int res,len;	int fd;	len = sizeof(*ee);	fd = open(filename, O_RDONLY);	if (fd < 0) {		fprintf(stderr, "Unable to open %s for input\n", filename);		return -1;	}	printf("Reading from file '%s'....", filename);	fflush(stdout);	res = read(fd, (char *)ee, len);	close(fd);	if (res != len) {		printf("Failed!\n");		if (res < 0) {			fprintf(stderr, "Failed to read from file: %s\n", strerror(errno));		} else {			fprintf(stderr, "Only read %d of %d bytes: %s\n", res, len, strerror(errno));		}		return -1;	}	if (ee->magic != htonl(EEPROM_MAGIC)) {		printf("Failed!\n");		fprintf(stderr, "File '%s' does not appear to be a Tormenta2 EEPROM file\n",			filename);		return -1;	}	if (ee->crc16 != htons(calc_crc16((char *)ee, sizeof(*ee) - 2))) {		printf("Failed!\n");		fprintf(stderr, "File '%s' has improper checksum\n", filename);		return -1;	}	printf("Done.\n");	printf("Read Revision '%s' from file '%s'\n", ee->revision, filename);	return 0;}static int write_eeprom_file(char *filename, char *revision, struct pci_eeprom *ee){	int res;	int len;	int fd;	fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0666);	if (fd < 0) {		fprintf(stderr, "Unable to open %s for output\n", filename);		return -1;	}	/* Record magic */	ee->magic = htonl(EEPROM_MAGIC);	/* Store revision number */	memset(ee->revision, 0, sizeof(ee->revision));	strncpy(ee->revision, revision, sizeof(ee->revision));	/* Calculate FCS on revision and data */	ee->crc16 = htons(calc_crc16((char *)ee, sizeof(*ee) - 2));	len = sizeof(*ee);	printf("Writing Revision '%s' to file '%s'....",	       ee->revision, filename);	fflush(stdout);	res = write(fd, (char *)ee, len);	close(fd);	if (res != len) {		printf("Failed!\n");		if (res < 0) {			fprintf(stderr, "Failed to write to file: %s\n", strerror(errno));		} else {			fprintf(stderr, "Only wrote %d of %d bytes: %s\n", res, len, strerror(errno));		}		return -1;	}	printf("Done.\n");	return 0;}static int openmem(off_t offset, size_t len, int inport){	if (iopl(3)) {		fprintf(stderr, "Unable to set I/O Permissions: %s\n", strerror(errno));		return -1;	}	if (memfd > -1) {		fprintf(stderr, "Huh?  Memory already exists?\n");		return 0;	}	memfd = open("/dev/mem", O_RDWR);	if (memfd < 0) {		fprintf(stderr, "Unable to open /dev/mem: %s\n", strerror(errno));		return -1;	}	memw = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, offset);	if (memw == MAP_FAILED) {		fprintf(stderr, "Memory map failed: %s\n", strerror(errno));		close(memfd);		memfd = -1;		return -1;	}	memlen = len;	port = inport & PCI_ADDR_IO_MASK;	return 0;}static char *makerev(void){	static char rev[32];	time_t t;	struct tm *tm;	t = time(NULL);	tm = localtime(&t);	strftime(rev, sizeof(rev), "Rev[%d/%m/%Y][%T]", tm);	return rev;}static void closemem(void){	if (memfd > -1) {		munmap(memw, memlen);		close(memfd);	}	memfd = -1;	if (pci)		pci_cleanup(pci);}int detect_tormenta2(int index){	/* Detect presense of Tormenta 2 card or return -1. 	   Sets up base addresses, etc as necessary as well. */	int which=0;	char *variant;	pci = pci_alloc();	pci_init(pci);	pci_scan_bus(pci);	dev = pci->devices;	while(dev) {#if 0		printf("[%d:%d:%d] VendorID: %04x DeviceID: %04x\n", 		       dev->bus, dev->dev, dev->func, dev->vendor_id, 		       dev->device_id);#endif		if (tor2_pci_match(dev->vendor_id, dev->device_id, &variant)) 			if (index == which++)				break;		dev = dev->next;	}	if (!dev) {		if (which) 			fprintf(stderr, "Only %d Tormenta2 card(s) found\n", which);		else			fprintf(stderr, "No Tormenta2 card found in system\n");		return -1;	}	printf("Tormenta2 Card (%s) Found!\n"	       "Vendor ID: %04x Device ID: %04x\n"	       "PLX Control Base Address: 0x%08lx [0x%04lx window]\n"	       "PLX Control I/O Space: 0x%lx\n",	       variant,		dev->vendor_id, dev->device_id,	        dev->base_addr[0], dev->size[0], 	        dev->base_addr[1]);	if (!dev->base_addr[0] || !dev->size[0]) {		fprintf(stderr, "Invalid base address info\n");		return -1;	}	if (openmem(dev->base_addr[0], dev->size[0], dev->base_addr[1])) {		fprintf(stderr, "Unable to open memory\n");		return -1;	}	printf("Mapped registers at %p\n", memw);	return 0;}void usage(int exitstatus){	fprintf(stderr, "tor2ee -- Tormenta 2 EEPROM controller\n""Usage: tor2ee command [args...]\n""       tor2ee detect\n""              -- Detect presense of Tormenta 2 card\n""       tor2ee [man]save <filename> [revision]\n""              -- Read contents of eeprom and write to file\n""	tor2ee reset\n""              -- Reset the PLX EEPROM\n""	tor2ee manread\n""	       -- Manually read registers\n""       tor2ee [man]load <filename>\n""              -- Write EEPROM from contents of file\n""       tor2ee modify <filename> [hex offset] [hex value]\n""              -- Change a specific offset and value in a given filename\n""       tor2ee verify <filename>\n""              -- Verify integrity of EEPROM file\n""       tor2ee compare <filename>\n""              -- Compare EEPROM file to current contents\n""       tor2ee dump [filename]\n""              -- Dump current EEPROM contents or filename if specified\n");	exit(exitstatus);}#define MODE_DETECT	0#define MODE_DUMP	1#define MODE_SAVE	2#define MODE_MODIFY	3#define MODE_LOAD	4#define MODE_RESET	5#define MODE_MANREAD	6static void modify(struct pci_eeprom *ee, int reg, int val){	int x;	char *regn = "<Unknown>";	for (x=0;x<NUM_EEREGS;x++) 		if (eeregs[x].pos == reg)			regn = eeregs[x].name;	ee->data[reg/2] = val;	printf("Setting %s to %04x\n", regn, val);}int main(int argc, char *argv[]){	struct pci_eeprom ee;	int mode;	int reg;	int val;	char tmp[32];	char *readfile = NULL;	char *writefile = NULL;	char *revision = NULL;	if (argc < 2) {		usage(1);	}	if (!strcasecmp(argv[1], "dump")) {		mode = MODE_DUMP;		if (argc > 2)			readfile = argv[2];	} else if (!strcasecmp(argv[1], "save") ||		   !strcasecmp(argv[1], "mansave")) {		if (argc < 3)			usage(1);		writefile = argv[2];		if (argc > 3)			revision = argv[3];		else			revision = makerev();		mode = MODE_SAVE;		if (!strcasecmp(argv[1], "mansave"))			manual = 1;	} else if (!strcasecmp(argv[1], "detect")) {		mode = MODE_DETECT;	} else if (!strcasecmp(argv[1], "load") ||		   !strcasecmp(argv[1], "manload")) {		if (argc < 3)			usage(1);		readfile = argv[2];		if (!strcasecmp(argv[1], "manload"))			manual = 1;		mode = MODE_LOAD;	} else if (!strcasecmp(argv[1], "reset"))  {		mode = MODE_RESET;	} else if (!strcasecmp(argv[1], "manread")) {		mode = MODE_MANREAD;	} else if (!strcasecmp(argv[1], "modify")) {		if (argc < 5)			usage(1);		readfile = writefile = argv[2];		if ((sscanf(argv[3], "%x", &reg) != 1) ||		    (reg >= (NUM_REGS) * 2) || (reg < 0)) {			fprintf(stderr, "Invalid register number: %s\n", argv[3]);			usage(1);		}		if (sscanf(argv[4], "%x", &val) != 1) {			fprintf(stderr, "Invalid value number: %s\n", argv[3]);			usage(1);		}		mode = MODE_MODIFY;	} else {		usage(1);	}	if (detect_tormenta2(0)) {		fprintf(stderr, "Tormenta 2 Not found in System\n");		closemem();		exit(1);	}	if (mode == MODE_RESET) {		reset_pci_eeprom(dev);	}	if (mode == MODE_MANREAD) {		plx_manread();	}	if ((mode == MODE_DUMP)) {		if (readfile) {			if (read_eeprom_file(readfile, &ee)) {				fprintf(stderr, "Unable to read EEPROM file\n");				closemem();				exit(1);			}		} else {			if (read_pci_eeprom(dev, &ee)) {				fprintf(stderr, "Unable to read existing EEPROM\n");				closemem();				exit(1);			}		}		dump_pci_eeprom(&ee);	}	if (mode == MODE_SAVE) {		if (read_pci_eeprom(dev, &ee)) {			fprintf(stderr, "Unable to read existiing EEPROM\n");			closemem();			exit(1);		}		if (write_eeprom_file(writefile, revision, &ee)) {			fprintf(stderr, "Unable to save EEPROM contents\n");			closemem();			exit(1);		}	}	if (mode == MODE_MODIFY) {		if (read_eeprom_file(readfile, &ee)) {			fprintf(stderr, "Unable to read EEPROM file\n");			closemem();			exit(1);		}		modify(&ee, reg, val);		strncpy(tmp, ee.revision, sizeof(tmp));		if (write_eeprom_file(writefile, tmp, &ee)) {			fprintf(stderr, "Unable to write EEPROM file\n");			closemem();			exit(1);		}	}	if (mode == MODE_LOAD) {		if (read_eeprom_file(readfile, &ee)) {			fprintf(stderr, "Unable to read EEPROM file\n");			closemem();			exit(1);		}		if (write_pci_eeprom(dev, &ee)) {			fprintf(stderr, "Unable to write to EEPROM\n");			closemem();			exit(1);		}		printf("EEPROM successfully written.  Please reboot to make changes\n");		printf("take effect.\n");	}	closemem();	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -