From 21263d58b5659eb42d200a38b17da18fce49a881 Mon Sep 17 00:00:00 2001 From: tzafrir Date: Sun, 29 Apr 2007 22:44:32 +0000 Subject: xpp rev. 3814: * Protocol no. 2.6: syncing improvements. * Support for 8-port Astribank BRI. * Firmware unloading now works: rmmod xpp_usb; /etc/hotplug/usb/xpp_fxloader reset * Defaults of kernel parameters are now part of parameter description. * World-readable kernel parameters. * No need for extra patch beyond bristuff for Astribank BRI. * Default poll intervals changed: 500 in BRI and FXO. * Allow changing FXS polls interval at run time. * BRI initalization fixed on SUSE (path to logger). * When using the SUSE zaptel rpm package, set modules_var=ZAPTEL_MODULES in /etc/sysconfig/zaptel . * zt_registration not verbose by default. * xpp_sync warns if FXO is sync slave. * Fixed genzaptelconf -z (zapscan output emulation). * PCM fixes. * Solves "multiple ticks" bug. No need for pcm_tasklets workaround. git-svn-id: http://svn.digium.com/svn/zaptel/trunk@2478 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- xpp/utils/fpga_load.c | 217 ++++++++++++++++++++++++++------------------------ 1 file changed, 115 insertions(+), 102 deletions(-) (limited to 'xpp/utils/fpga_load.c') diff --git a/xpp/utils/fpga_load.c b/xpp/utils/fpga_load.c index 2c03704..1cbd749 100644 --- a/xpp/utils/fpga_load.c +++ b/xpp/utils/fpga_load.c @@ -12,8 +12,8 @@ static const char rcsid[] = "$Id$"; #define ERR(fmt, arg...) do { \ if(verbose >= LOG_ERR) \ - fprintf(stderr, "%s: ERROR: " fmt, \ - progname, ## arg); \ + fprintf(stderr, "%s: ERROR (%d): " fmt, \ + progname, __LINE__, ## arg); \ } while(0); #define INFO(fmt, arg...) do { \ if(verbose >= LOG_INFO) \ @@ -35,14 +35,15 @@ static char *progname; #define SERIAL_SIZE 8 enum fpga_load_packet_types { - STATUS_REPLY = 0x01, - DATA_PACKET = 0x01, + PT_STATUS_REPLY = 0x01, + PT_DATA_PACKET = 0x01, #ifdef XORCOM_INTERNAL - EEPROM_SET = 0x04, + PT_EEPROM_SET = 0x04, #endif - EEPROM_GET = 0x08, - RENUMERATE = 0x10, - BAD_COMMAND = 0xAA + PT_EEPROM_GET = 0x08, + PT_RENUMERATE = 0x10, + PT_RESET = 0x20, + PT_BAD_COMMAND = 0xAA }; struct myeeprom { @@ -173,8 +174,8 @@ int get_usb_string(char *buf, unsigned int len, uint16_t item, usb_dev_handle *h } /* My device parameters */ -#define MY_INTERFACE 0 #define MY_CONFIG 1 +#define MY_INTERFACE 0 #define MY_ENDPOINTS 4 #define MY_EP_OUT 0x04 @@ -186,10 +187,10 @@ int get_usb_string(char *buf, unsigned int len, uint16_t item, usb_dev_handle *h #define TIMEOUT 5000 static const int my_endpoints[MY_ENDPOINTS] = { - 0x02, - 0x04, - 0x86, - 0x88 + FPGA_EP_OUT, + MY_EP_OUT, + FPGA_EP_IN, + MY_EP_IN }; void my_usb_device_cleanup(struct my_usb_device *mydev) @@ -226,12 +227,47 @@ static void show_device_info(const struct my_usb_device *mydev) data[4], data[5], data[6], data[7]); } -void dump_packet(const char *buf, int len) +void dump_packet(const char *msg, const char *buf, int len) { int i; for(i = 0; i < len; i++) - INFO("dump: %2d> 0x%02X\n", i, (uint8_t)buf[i]); + INFO("%s: %2d> 0x%02X\n", msg, i, (uint8_t)buf[i]); +} + +int send_usb(const char *msg, struct my_usb_device *mydev, int endpoint, struct fpga_packet_header *phead, int len, int timeout) +{ + char *p = (char *)phead; + int ret; + + if(verbose >= LOG_DEBUG) + dump_packet(msg, p, len); + ret = usb_bulk_write(mydev->handle, endpoint, p, len, timeout); + if(ret < 0) { + ERR("bulk_write failed: %s\n", usb_strerror()); + dump_packet("send_usb[ERR]", p, len); + return ret; + } else if(ret != len) { + ERR("bulk_write short write: %s\n", usb_strerror()); + dump_packet("send_usb[ERR]", p, len); + return -EFAULT; + } + return ret; +} + +int recv_usb(const char *msg, struct my_usb_device *mydev, int endpoint, char *buf, size_t len, int timeout) +{ + int ret; + + if(verbose >= LOG_DEBUG) + dump_packet(msg, buf, len); + ret = usb_bulk_read(mydev->handle, endpoint, buf, len, timeout); + if(ret < 0) { + ERR("bulk_read failed: %s\n", usb_strerror()); + dump_packet("recv_usb[ERR]", buf, len); + return ret; + } + return ret; } #ifdef XORCOM_INTERNAL @@ -244,39 +280,23 @@ int eeprom_set(struct my_usb_device *mydev, const struct myeeprom *eeprom) DBG("%s Start...\n", __FUNCTION__); assert(mydev != NULL); - phead->header.op = EEPROM_SET; + phead->header.op = PT_EEPROM_SET; memcpy(&phead->d.eeprom_set.data, eeprom, EEPROM_SIZE); len = sizeof(phead->d.eeprom_set) + sizeof(phead->header.op); - if(verbose >= LOG_DEBUG) { - DBG("%s write %d bytes\n", __FUNCTION__, len); - dump_packet((char *)phead, len); - } - ret = usb_bulk_write(mydev->handle, MY_EP_OUT, (char *)phead, len, TIMEOUT); - if(ret < 0) { - ERR("bulk_write failed: %s\n", usb_strerror()); + ret = send_usb("eeprom_set[W]", mydev, MY_EP_OUT, phead, len, TIMEOUT); + if(ret < 0) return ret; - } else if(ret != len) { - ERR("bulk_write short write: %s\n", usb_strerror()); - return -EFAULT; - } - ret = usb_bulk_read(mydev->handle, MY_EP_IN, buf, sizeof(buf), TIMEOUT); - if(ret < 0) { - ERR("bulk_read failed: %s\n", usb_strerror()); + ret = recv_usb("eeprom_set[R]", mydev, MY_EP_IN, buf, sizeof(buf), TIMEOUT); + if(ret <= 0) return ret; - } else if(ret == 0) - return 0; phead = (struct fpga_packet_header *)buf; - if(phead->header.op == BAD_COMMAND) { - ERR("Firmware rejected EEPROM_SET command\n"); + if(phead->header.op == PT_BAD_COMMAND) { + ERR("Firmware rejected PT_EEPROM_SET command\n"); return -EINVAL; - } else if(phead->header.op != EEPROM_SET) { + } else if(phead->header.op != PT_EEPROM_SET) { ERR("Got unexpected reply op=%d\n", phead->header.op); return -EINVAL; } - if(verbose >= LOG_DEBUG) { - DBG("%s read %d bytes\n", __FUNCTION__, ret); - dump_packet(buf, ret); - } return 0; } #endif @@ -292,38 +312,22 @@ int eeprom_get(struct my_usb_device *mydev) assert(mydev != NULL); eeprom = &mydev->eeprom; DBG("%s Start...\n", __FUNCTION__); - phead->header.op = EEPROM_GET; + phead->header.op = PT_EEPROM_GET; len = sizeof(phead->header.op); /* warning: sending small packet */ - if(verbose >= LOG_DEBUG) { - DBG("%s write %d bytes\n", __FUNCTION__, len); - dump_packet(buf, len); - } - ret = usb_bulk_write(mydev->handle, MY_EP_OUT, (char *)phead, len, TIMEOUT); - if(ret < 0) { - ERR("bulk_write failed: %s\n", usb_strerror()); + ret = send_usb("eeprom_get[W]", mydev, MY_EP_OUT, phead, len, TIMEOUT); + if(ret < 0) return ret; - } else if(ret != len) { - ERR("bulk_write short write: %s\n", usb_strerror()); - return -EFAULT; - } - ret = usb_bulk_read(mydev->handle, MY_EP_IN, buf, sizeof(buf), TIMEOUT); - if(ret < 0) { - ERR("bulk_read failed: %s\n", usb_strerror()); + ret = recv_usb("eeprom_get[R]", mydev, MY_EP_IN, buf, sizeof(buf), TIMEOUT); + if(ret <= 0) return ret; - } else if(ret == 0) - return 0; phead = (struct fpga_packet_header *)buf; - if(phead->header.op == BAD_COMMAND) { - ERR("BAD_COMMAND\n"); + if(phead->header.op == PT_BAD_COMMAND) { + ERR("PT_BAD_COMMAND\n"); return -EINVAL; - } else if(phead->header.op != EEPROM_GET) { + } else if(phead->header.op != PT_EEPROM_GET) { ERR("Got unexpected reply op=%d\n", phead->header.op); return -EINVAL; } - if(verbose >= LOG_DEBUG) { - DBG("%s read %d bytes\n", __FUNCTION__, ret); - dump_packet(buf, ret); - } memcpy(eeprom, &phead->d.eeprom_get.data, EEPROM_SIZE); return 0; } @@ -345,32 +349,23 @@ int send_hexline(struct my_usb_device *mydev, struct hexline *hexline, int seq) ERR("Bad record %d type = %d\n", seq, hexline->d.content.header.tt); return -EINVAL; } - phead->header.op = DATA_PACKET; + phead->header.op = PT_DATA_PACKET; phead->d.data_packet.seq = seq; phead->d.data_packet.reserved = 0x00; memcpy(phead->d.data_packet.data, data, len); len += sizeof(hexline->d.content.header); DBG("%04d+\r", seq); - ret = usb_bulk_write(mydev->handle, MY_EP_OUT, (char *)phead, len, TIMEOUT); - if(ret < 0) { - ERR("bulk_write failed: %s\n", usb_strerror()); + ret = send_usb("hexline[W]", mydev, MY_EP_OUT, phead, len, TIMEOUT); + if(ret < 0) return ret; - } else if(ret != len) { - ERR("bulk_write short write: %s\n", usb_strerror()); - return -EFAULT; - } - if (verbose >= LOG_DEBUG) - dump_packet((char*)phead, len); - ret = usb_bulk_read(mydev->handle, MY_EP_IN, buf, sizeof(buf), TIMEOUT); - if(ret < 0) { - ERR("bulk_read failed: %s\n", usb_strerror()); + ret = recv_usb("hexline[R]", mydev, MY_EP_IN, buf, sizeof(buf), TIMEOUT); + if(ret <= 0) return ret; - } else if(ret == 0) - return 0; DBG("%04d-\r", seq); phead = (struct fpga_packet_header *)buf; - if(phead->header.op != STATUS_REPLY) { + if(phead->header.op != PT_STATUS_REPLY) { ERR("Got unexpected reply op=%d\n", phead->header.op); + dump_packet("hexline[ERR]", buf, ret); return -EINVAL; } status = (enum fpga_load_status)phead->d.status_reply.status; @@ -381,11 +376,11 @@ int send_hexline(struct my_usb_device *mydev, struct hexline *hexline, int seq) case FW_FAIL_RESET: case FW_FAIL_TRANS: ERR("status reply %s (%d)\n", load_status2str(status), status); - dump_packet(buf, ret); + dump_packet("hexline[ERR]", buf, ret); return -EPROTO; default: ERR("Unknown status reply %d\n", status); - dump_packet(buf, ret); + dump_packet("hexline[ERR]", buf, ret); return -EPROTO; } return 0; @@ -459,10 +454,6 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev) ERR("Failed to open usb device '%s/%s': %s\n", mydev->dev->bus->dirname, mydev->dev->filename, usb_strerror()); return 0; } - if(usb_reset(mydev->handle) != 0) { - ERR("Reseting device: usb: %s\n", usb_strerror()); - return 0; - } if(usb_set_configuration(mydev->handle, MY_CONFIG) != 0) { ERR("usb: %s\n", usb_strerror()); return 0; @@ -471,9 +462,13 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev) ERR("usb: %s\n", usb_strerror()); return 0; } + if(usb_reset(mydev->handle) != 0) { + ERR("Reseting device: usb: %s\n", usb_strerror()); + return 0; + } dev_desc = &mydev->dev->descriptor; config_desc = mydev->dev->config; - interface = config_desc->interface; + interface = &config_desc->interface[MY_INTERFACE]; iface_desc = interface->altsetting; INFO("Vendor:Product=%04X:%04X Class=%d (endpoints=%d)\n", dev_desc->idVendor, @@ -520,23 +515,18 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev) return 1; } -int renumerate_device(struct my_usb_device *mydev) +int renumerate_device(struct my_usb_device *mydev, enum fpga_load_packet_types pt) { char buf[PACKET_SIZE]; struct fpga_packet_header *phead = (struct fpga_packet_header *)buf; int ret; assert(mydev != NULL); - DBG("Renumerating\n"); - phead->header.op = RENUMERATE; - ret = usb_bulk_write(mydev->handle, MY_EP_OUT, (char *)phead, 1, TIMEOUT); - if(ret < 0) { - ERR("bulk_write failed: %s\n", usb_strerror()); + DBG("Renumerating with 0x%X\n", pt); + phead->header.op = pt; + ret = send_usb("renumerate[W]", mydev, MY_EP_OUT, phead, 1, TIMEOUT); + if(ret < 0) return ret; - } else if(ret != 1) { - ERR("bulk_write short write: %s\n", usb_strerror()); - return -EFAULT; - } return 0; } @@ -597,8 +587,10 @@ void usage() { fprintf(stderr, "Usage: %s -D {/proc/bus/usb|/dev/bus/usb}// [options...]\n", progname); fprintf(stderr, "\tOptions:\n"); - fprintf(stderr, "\t\t[-b ] # output to \n"); + fprintf(stderr, "\t\t[-r] # Reset the device\n"); + fprintf(stderr, "\t\t[-b ] # Output to \n"); fprintf(stderr, "\t\t[-I ] # Input from \n"); + fprintf(stderr, "\t\t[-i] # Show hexfile information\n"); fprintf(stderr, "\t\t[-g] # Get eeprom from device\n"); #ifdef XORCOM_INTERNAL fprintf(stderr, "\t\t[-C srC byte] # Set Address sourCe (default: C0)\n"); @@ -627,6 +619,8 @@ int main(int argc, char *argv[]) const char *binfile = NULL; const char *hexfile = NULL; struct hexdata *hexdata = NULL; + int opt_reset = 0; + int opt_info = 0; int opt_read_eeprom = 0; #ifdef XORCOM_INTERNAL int opt_write_eeprom = 0; @@ -637,9 +631,9 @@ int main(int argc, char *argv[]) char *release = NULL; char *serial = NULL; uint8_t serial_buf[SERIAL_SIZE]; - const char options[] = "b:C:D:ghI:vV:P:R:S:"; + const char options[] = "rib:C:D:ghI:vV:P:R:S:"; #else - const char options[] = "b:D:ghI:v"; + const char options[] = "rib:D:ghI:v"; #endif int ret = 0; @@ -657,6 +651,12 @@ int main(int argc, char *argv[]) case 'D': devpath = optarg; break; + case 'r': + opt_reset = 1; + break; + case 'i': + opt_info = 1; + break; case 'b': binfile = optarg; break; @@ -725,10 +725,15 @@ int main(int argc, char *argv[]) ERR("Bailing out\n"); exit(1); } - if(binfile) { + if(opt_info) { + printf("%s: Version=%s Checksum=%d\n", + hexfile, hexdata->version_info, + calc_checksum(hexdata)); + } + if(binfile) dump_binary(hexdata, binfile); + if(!devpath) return 0; - } } if(!devpath) { ERR("Missing device path\n"); @@ -761,7 +766,7 @@ int main(int argc, char *argv[]) ret = -ENODEV; goto dev_err; } - ret = renumerate_device(&mydev); + ret = renumerate_device(&mydev, PT_RENUMERATE); if(ret < 0) { ERR("Renumeration failed: errno=%d\n", ret); goto dev_err; @@ -798,6 +803,14 @@ int main(int argc, char *argv[]) show_device_info(&mydev); } #endif + if(opt_reset) { + DBG("Reseting to default\n"); + ret = renumerate_device(&mydev, PT_RESET); + if(ret < 0) { + ERR("Renumeration to default failed: errno=%d\n", ret); + goto dev_err; + } + } DBG("Exiting\n"); dev_err: my_usb_device_cleanup(&mydev); -- cgit v1.2.3