From e5bc4241a19c8680a68411ec5ba420fb25b58ad9 Mon Sep 17 00:00:00 2001 From: Tzafrir Cohen Date: Thu, 15 Mar 2012 20:45:57 +0000 Subject: xpp: clobber fpga_load * It was replaced long ago by astribank_hexload/astribank_tool/astribank_allow * It hasn't been used for several releases now, nor updated. * Time to move into the eternal bit-bucket. * Left (very) few strings as a tribute... Signed-off-by: Oron Peled Acked-by: Tzafrir Cohen git-svn-id: http://svn.asterisk.org/svn/dahdi/tools/trunk@10504 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- xpp/fpga_load.c | 1052 ------------------------------------------------------- 1 file changed, 1052 deletions(-) delete mode 100644 xpp/fpga_load.c (limited to 'xpp/fpga_load.c') diff --git a/xpp/fpga_load.c b/xpp/fpga_load.c deleted file mode 100644 index e120b26..0000000 --- a/xpp/fpga_load.c +++ /dev/null @@ -1,1052 +0,0 @@ -/* - * Written by Oron Peled - * Copyright (C) 2006-2008, Xorcom - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "hexfile.h" - -static const char rcsid[] = "$Id$"; - -#define ERR(fmt, arg...) do { \ - if(verbose >= LOG_ERR) \ - fprintf(stderr, "%s: ERROR (%d): " fmt, \ - progname, __LINE__, ## arg); \ - } while(0); -#define INFO(fmt, arg...) do { \ - if(verbose >= LOG_INFO) \ - fprintf(stderr, "%s: " fmt, \ - progname, ## arg); \ - } while(0); -#define DBG(fmt, arg...) do { \ - if(verbose >= LOG_DEBUG) \ - fprintf(stderr, "%s: DBG: " fmt, \ - progname, ## arg); \ - } while(0); - -static int verbose = LOG_WARNING; -static char *progname; -static int disconnected = 0; - -#define MAX_HEX_LINES 10000 -#define PACKET_SIZE 512 -#define EEPROM_SIZE 16 -#define LABEL_SIZE 8 -#define TIMEOUT 5000 - - -/* My device parameters */ -#define MY_EP_OUT 0x04 -#define MY_EP_IN 0x88 - -#define FPGA_EP_OUT 0x02 -#define FPGA_EP_IN 0x86 - -/* USB firmware types */ -#define USB_11xx 0 -#define USB_FIRMWARE_II 1 - -#define TYPE_ENTRY(t,ni,n,ne,out,in,...) \ - [t] = { \ - .type_code = (t), \ - .num_interfaces = (ni), \ - .my_interface_num = (n), \ - .num_endpoints = (ne), \ - .my_ep_in = (in), \ - .my_ep_out = (out), \ - .name = #t, \ - .endpoints = { __VA_ARGS__ }, \ - } - -static const struct astribank_type { - int type_code; - int num_interfaces; - int my_interface_num; - int num_endpoints; - int my_ep_out; - int my_ep_in; - char *name; - int endpoints[4]; /* for matching */ -} astribank_types[] = { - TYPE_ENTRY(USB_11xx, 1, 0, 4, MY_EP_OUT, MY_EP_IN, - FPGA_EP_OUT, - MY_EP_OUT, - FPGA_EP_IN, - MY_EP_IN), - TYPE_ENTRY(USB_FIRMWARE_II, 2, 1, 2, MY_EP_OUT, MY_EP_IN, - MY_EP_OUT, - MY_EP_IN), -}; -#undef TYPE_ENTRY - -enum fpga_load_packet_types { - PT_STATUS_REPLY = 0x01, - PT_DATA_PACKET = 0x01, -#ifdef XORCOM_INTERNAL - PT_EEPROM_SET = 0x04, -#endif - PT_EEPROM_GET = 0x08, - PT_RENUMERATE = 0x10, - PT_RESET = 0x20, - PT_BAD_COMMAND = 0xAA -}; - -struct myeeprom { - uint8_t source; - uint16_t vendor; - uint16_t product; - uint8_t release_major; - uint8_t release_minor; - uint8_t reserved; - uint8_t label[LABEL_SIZE]; -} PACKED; - -struct fpga_packet_header { - struct { - uint8_t op; - } PACKED header; - union { - struct { - uint16_t seq; - uint8_t status; - } PACKED status_reply; - struct { - uint16_t seq; - uint8_t reserved; - uint8_t data[ZERO_SIZE]; - } PACKED data_packet; - struct { - struct myeeprom data; - } PACKED eeprom_set; - struct { - struct myeeprom data; - } PACKED eeprom_get; - } d; -} PACKED; - -enum fpga_load_status { - FW_FAIL_RESET = 1, - FW_FAIL_TRANS = 2, - FW_TRANS_OK = 4, - FW_CONFIG_DONE = 8 -}; - -struct my_usb_device { - struct usb_device *dev; - usb_dev_handle *handle; - int my_interface_num; - int my_ep_out; - int my_ep_in; - char iManufacturer[BUFSIZ]; - char iProduct[BUFSIZ]; - char iSerialNumber[BUFSIZ]; - char iInterface[BUFSIZ]; - int is_usb2; - struct myeeprom eeprom; - const struct astribank_type *abtype; -}; - -const char *load_status2str(enum fpga_load_status s) -{ - switch(s) { - case FW_FAIL_RESET: return "FW_FAIL_RESET"; - case FW_FAIL_TRANS: return "FW_FAIL_TRANS"; - case FW_TRANS_OK: return "FW_TRANS_OK"; - case FW_CONFIG_DONE: return "FW_CONFIG_DONE"; - default: return "UNKNOWN"; - } -} - -/* return 1 if: - * - str has a number - * - It is larger than 0 - * - It equals num - */ -int num_matches(int num, const char* str) { - int str_val = atoi(str); - if (str_val <= 0) - return 0; - return (str_val == num); -} - -struct usb_device *dev_of_path(const char *path) -{ - struct usb_bus *bus; - struct usb_device *dev; - char dirname[PATH_MAX]; - char filename[PATH_MAX]; - const char *p; - int bnum; - int dnum; - int ret; - - assert(path != NULL); - if(access(path, F_OK) < 0) { - perror(path); - return NULL; - } - /* Find last '/' */ - if((p = (const char *)memrchr(path, '/', strlen(path))) == NULL) { - ERR("Missing a '/' in %s\n", path); - return NULL; - } - /* Get the device number */ - ret = sscanf(p + 1, "%d", &dnum); - if(ret != 1) { - ERR("Path tail is not a device number: '%s'\n", p); - return NULL; - } - /* Search for a '/' before that */ - p = (const char *)memrchr(path, '/', p - path); - if(p == NULL) - p = path; /* Relative path */ - else - p++; /* skip '/' */ - /* Get the bus number */ - ret = sscanf(p, "%d", &bnum); - if(ret != 1) { - ERR("Path tail is not a bus number: '%s'\n", p); - return NULL; - } - sprintf(dirname, "%03d", bnum); - sprintf(filename, "%03d", dnum); - for (bus = usb_busses; bus; bus = bus->next) { - if (! num_matches(bnum, bus->dirname)) - //if(strcmp(bus->dirname, dirname) != 0) - continue; - for (dev = bus->devices; dev; dev = dev->next) { - //if(strcmp(dev->filename, filename) == 0) - if (num_matches(dnum, dev->filename)) - return dev; - } - } - ERR("no usb device match '%s'\n", path); - return NULL; -} - -int get_usb_string(char *buf, unsigned int len, uint16_t item, usb_dev_handle *handle) -{ - char tmp[BUFSIZ]; - int ret; - - if (!item) - return 0; - ret = usb_get_string_simple(handle, item, tmp, BUFSIZ); - if (ret <= 0) - return ret; - return snprintf(buf, len, "%s", tmp); -} - -void my_usb_device_cleanup(struct my_usb_device *mydev) -{ - assert(mydev != NULL); - if(!mydev->handle) { - return; /* Nothing to do */ - } - if(!disconnected) { - if(usb_release_interface(mydev->handle, mydev->abtype->my_interface_num) != 0) { - ERR("Releasing interface: usb: %s\n", usb_strerror()); - } - } - if(usb_close(mydev->handle) != 0) { - ERR("Closing device: usb: %s\n", usb_strerror()); - } - disconnected = 1; - mydev->handle = NULL; -} - -static void show_device_info(const struct my_usb_device *mydev) -{ - const struct myeeprom *eeprom; - uint8_t data[LABEL_SIZE + 1]; - - assert(mydev != NULL); - eeprom = &mydev->eeprom; - memset(data, 0, LABEL_SIZE + 1); - memcpy(data, eeprom->label, LABEL_SIZE); - printf("USB Firmware Type: [%s]\n", mydev->abtype->name); - printf("USB iManufacturer: [%s]\n", mydev->iManufacturer); - printf("USB iProduct: [%s]\n", mydev->iProduct); - printf("USB iSerialNumber: [%s]\n", mydev->iSerialNumber); - printf("EEPROM Source: 0x%02X\n", eeprom->source); - printf("EEPROM Vendor: 0x%04X\n", eeprom->vendor); - printf("EEPROM Product: 0x%04X\n", eeprom->product); - printf("EEPROM Release: %d.%03d\n", eeprom->release_major, eeprom->release_minor); - printf("EEPROM Label: HEX(%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X) [%s]\n", - data[0], data[1], data[2], data[3], - data[4], data[5], data[6], data[7], data); -} - -void dump_packet(const char *msg, const char *buf, int len) -{ - int i; - - for(i = 0; i < len; i++) - INFO("%s: %2d> 0x%02X\n", msg, i, (uint8_t)buf[i]); -} - -int send_usb(const char *msg, struct my_usb_device *mydev, struct fpga_packet_header *phead, int len, int timeout) -{ - char *p = (char *)phead; - int ret; - - if(verbose >= LOG_DEBUG) - dump_packet(msg, p, len); - if(mydev->my_ep_out & USB_ENDPOINT_IN) { - ERR("send_usb called with an input endpoint 0x%x\n", mydev->my_ep_out); - return -EINVAL; - } - ret = usb_bulk_write(mydev->handle, mydev->my_ep_out, p, len, timeout); - if(ret < 0) { - /* - * If the device was gone, it may be the - * result of renumeration. Ignore it. - */ - if(ret != -ENODEV) { - ERR("bulk_write to endpoint 0x%x failed: %s\n", mydev->my_ep_out, usb_strerror()); - dump_packet("send_usb[ERR]", p, len); - } else { - disconnected = 1; - my_usb_device_cleanup(mydev); - } - return ret; - } else if(ret != len) { - ERR("bulk_write to endpoint 0x%x short write: %s\n", mydev->my_ep_out, usb_strerror()); - dump_packet("send_usb[ERR]", p, len); - return -EFAULT; - } - return ret; -} - -int recv_usb(const char *msg, struct my_usb_device *mydev, char *buf, size_t len, int timeout) -{ - int ret; - - if(mydev->my_ep_in & USB_ENDPOINT_OUT) { - ERR("recv_usb called with an output endpoint 0x%x\n", mydev->my_ep_in); - return -EINVAL; - } - ret = usb_bulk_read(mydev->handle, mydev->my_ep_in, buf, len, timeout); - if(ret < 0) { - ERR("bulk_read from endpoint 0x%x failed: %s\n", mydev->my_ep_in, usb_strerror()); - return ret; - } - if(verbose >= LOG_DEBUG) - dump_packet(msg, buf, ret); - return ret; -} - -int flush_read(struct my_usb_device *mydev) -{ - char tmpbuf[BUFSIZ]; - int ret; - - memset(tmpbuf, 0, BUFSIZ); - ret = recv_usb("flush_read", mydev, tmpbuf, sizeof(tmpbuf), TIMEOUT); - if(ret < 0 && ret != -ETIMEDOUT) { - ERR("ret=%d\n", ret); - return ret; - } else if(ret > 0) { - DBG("Got %d bytes:\n", ret); - dump_packet(__FUNCTION__, tmpbuf, ret); - } - return 0; -} - -#ifdef XORCOM_INTERNAL -int eeprom_set(struct my_usb_device *mydev, const struct myeeprom *eeprom) -{ - int ret; - int len; - char buf[PACKET_SIZE]; - struct fpga_packet_header *phead = (struct fpga_packet_header *)buf; - - DBG("%s Start...\n", __FUNCTION__); - assert(mydev != NULL); - 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); - ret = send_usb("eeprom_set[W]", mydev, phead, len, TIMEOUT); - if(ret < 0) - return ret; - ret = recv_usb("eeprom_set[R]", mydev, buf, sizeof(buf), TIMEOUT); - if(ret <= 0) - return ret; - phead = (struct fpga_packet_header *)buf; - if(phead->header.op == PT_BAD_COMMAND) { - ERR("Firmware rejected PT_EEPROM_SET command\n"); - return -EINVAL; - } else if(phead->header.op != PT_EEPROM_SET) { - ERR("Got unexpected reply op=%d\n", phead->header.op); - return -EINVAL; - } - return 0; -} -#endif - -int eeprom_get(struct my_usb_device *mydev) -{ - int ret; - int len; - char buf[PACKET_SIZE]; - struct fpga_packet_header *phead = (struct fpga_packet_header *)buf; - struct myeeprom *eeprom; - - assert(mydev != NULL); - eeprom = &mydev->eeprom; - DBG("%s Start...\n", __FUNCTION__); - phead->header.op = PT_EEPROM_GET; - len = sizeof(phead->header.op); /* warning: sending small packet */ - ret = send_usb("eeprom_get[W]", mydev, phead, len, TIMEOUT); - if(ret < 0) - return ret; - ret = recv_usb("eeprom_get[R]", mydev, buf, sizeof(buf), TIMEOUT); - if(ret <= 0) - return ret; - phead = (struct fpga_packet_header *)buf; - if(phead->header.op == PT_BAD_COMMAND) { - ERR("PT_BAD_COMMAND\n"); - return -EINVAL; - } else if(phead->header.op != PT_EEPROM_GET) { - ERR("Got unexpected reply op=%d\n", phead->header.op); - return -EINVAL; - } - memcpy(eeprom, &phead->d.eeprom_get.data, EEPROM_SIZE); - return 0; -} - -int send_hexline(struct my_usb_device *mydev, struct hexline *hexline, int seq) -{ - int ret; - int len; - uint8_t *data; - char buf[PACKET_SIZE]; - struct fpga_packet_header *phead = (struct fpga_packet_header *)buf; - enum fpga_load_status status; - - assert(mydev != NULL); - assert(hexline != NULL); - if(hexline->d.content.header.tt != TT_DATA) { - DBG("Non data record %d type = %d\n", seq, hexline->d.content.header.tt); - return 0; - } - len = hexline->d.content.header.ll; /* don't send checksum */ - data = hexline->d.content.tt_data.data; - 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 = send_usb("hexline[W]", mydev, phead, len, TIMEOUT); - if(ret < 0) - return ret; - ret = recv_usb("hexline[R]", mydev, buf, sizeof(buf), TIMEOUT); - if(ret <= 0) - return ret; - DBG("%04d-\r", seq); - phead = (struct fpga_packet_header *)buf; - 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; - switch(status) { - case FW_TRANS_OK: - case FW_CONFIG_DONE: - break; - case FW_FAIL_RESET: - case FW_FAIL_TRANS: - ERR("status reply %s (%d)\n", load_status2str(status), status); - dump_packet("hexline[ERR]", buf, ret); - return -EPROTO; - default: - ERR("Unknown status reply %d\n", status); - dump_packet("hexline[ERR]", buf, ret); - return -EPROTO; - } - return 0; -} - -//. returns > 0 - ok, the number of lines sent -//. returns < 0 - error number -int send_splited_hexline(struct my_usb_device *mydev, struct hexline *hexline, int seq, uint8_t maxwidth) -{ - struct hexline *extraline; - int linessent = 0; - int allocsize; - int extra_offset = 0; - unsigned int this_line = 0; - uint8_t bytesleft = 0; - - assert(mydev != NULL); - if(!hexline) { - ERR("Bad record %d type = %d\n", seq, hexline->d.content.header.tt); - return -EINVAL; - } - bytesleft = hexline->d.content.header.ll; - // split the line into several lines - while (bytesleft > 0) { - int status; - this_line = (bytesleft >= maxwidth) ? maxwidth : bytesleft; - allocsize = sizeof(struct hexline) + this_line + 1; - // generate the new line - if((extraline = (struct hexline *)malloc(allocsize)) == NULL) { - ERR("Not enough memory for spliting the lines\n" ); - return -EINVAL; - } - memset(extraline, 0, allocsize); - extraline->d.content.header.ll = this_line; - extraline->d.content.header.offset = hexline->d.content.header.offset + extra_offset; - extraline->d.content.header.tt = hexline->d.content.header.tt; - memcpy( extraline->d.content.tt_data.data, hexline->d.content.tt_data.data+extra_offset, this_line); - status = send_hexline(mydev, extraline, seq+linessent ); - // cleanups - free(extraline); - extra_offset += this_line; - bytesleft -= this_line; - if (status) - return status; - linessent++; - } - return linessent; -} - -int match_usb_device_identity(const struct usb_config_descriptor *config_desc, - const struct astribank_type *ab) -{ - struct usb_interface *interface; - struct usb_interface_descriptor *iface_desc; - - if(config_desc->bNumInterfaces <= ab->my_interface_num) - return 0; - interface = &config_desc->interface[ab->my_interface_num]; - iface_desc = interface->altsetting; - - return iface_desc->bInterfaceClass == 0xFF && - iface_desc->bInterfaceNumber == ab->my_interface_num && - iface_desc->bNumEndpoints == ab->num_endpoints; -} - -const struct astribank_type *my_usb_device_identify(const char devpath[], struct my_usb_device *mydev) -{ - struct usb_device_descriptor *dev_desc; - struct usb_config_descriptor *config_desc; - int i; - - assert(mydev != NULL); - usb_init(); - usb_find_busses(); - usb_find_devices(); - mydev->dev = dev_of_path(devpath); - if(!mydev->dev) { - ERR("Bailing out\n"); - return 0; - } - dev_desc = &mydev->dev->descriptor; - config_desc = mydev->dev->config; - for(i = 0; i < sizeof(astribank_types)/sizeof(astribank_types[0]); i++) { - if(match_usb_device_identity(config_desc, &astribank_types[i])) { - DBG("Identified[%d]: interfaces=%d endpoints=%d: \"%s\"\n", - i, - astribank_types[i].num_interfaces, - astribank_types[i].num_endpoints, - astribank_types[i].name); - return &astribank_types[i]; - } - } - return NULL; -} - -int my_usb_device_init(const char devpath[], struct my_usb_device *mydev, const struct astribank_type *abtype) -{ - struct usb_device_descriptor *dev_desc; - struct usb_config_descriptor *config_desc; - struct usb_interface *interface; - struct usb_interface_descriptor *iface_desc; - struct usb_endpoint_descriptor *endpoint; - int ret; - int i; - - assert(mydev != NULL); - usb_init(); - usb_find_busses(); - usb_find_devices(); - mydev->dev = dev_of_path(devpath); - if(!mydev->dev) { - ERR("Bailing out\n"); - return 0; - } - mydev->handle = usb_open(mydev->dev); - if(!mydev->handle) { - ERR("Failed to open usb device '%s/%s': %s\n", mydev->dev->bus->dirname, mydev->dev->filename, usb_strerror()); - return 0; - } - if(usb_claim_interface(mydev->handle, abtype->my_interface_num) != 0) { - ERR("usb_claim_interface: %s\n", usb_strerror()); - return 0; - } - dev_desc = &mydev->dev->descriptor; - config_desc = mydev->dev->config; - if (!config_desc) { - ERR("usb interface without a configuration\n"); - return 0; - } - interface = &config_desc->interface[abtype->my_interface_num]; - iface_desc = interface->altsetting; - endpoint = iface_desc->endpoint; - mydev->is_usb2 = (endpoint->wMaxPacketSize == 512); - for(i = 0; i < iface_desc->bNumEndpoints; i++, endpoint++) { - if(endpoint->bEndpointAddress != abtype->endpoints[i]) { - ERR("Wrong endpoint 0x%X (at index %d)\n", endpoint->bEndpointAddress, i); - return 0; - } - if(endpoint->bEndpointAddress == MY_EP_OUT || endpoint->bEndpointAddress == MY_EP_IN) { - if(endpoint->wMaxPacketSize > PACKET_SIZE) { - ERR("Endpoint #%d wMaxPacketSize too large (%d)\n", i, endpoint->wMaxPacketSize); - return 0; - } - } - } - mydev->abtype = abtype; - mydev->my_ep_in = abtype->my_ep_in; - mydev->my_ep_out = abtype->my_ep_out; - ret = get_usb_string(mydev->iManufacturer, BUFSIZ, dev_desc->iManufacturer, mydev->handle); - ret = get_usb_string(mydev->iProduct, BUFSIZ, dev_desc->iProduct, mydev->handle); - ret = get_usb_string(mydev->iSerialNumber, BUFSIZ, dev_desc->iSerialNumber, mydev->handle); - ret = get_usb_string(mydev->iInterface, BUFSIZ, iface_desc->iInterface, mydev->handle); - INFO("ID=%04X:%04X Manufacturer=[%s] Product=[%s] SerialNumber=[%s] Interface=[%s]\n", - dev_desc->idVendor, - dev_desc->idProduct, - mydev->iManufacturer, - mydev->iProduct, - mydev->iSerialNumber, - mydev->iInterface); - if(usb_clear_halt(mydev->handle, mydev->my_ep_out) != 0) { - ERR("Clearing output endpoint: %s\n", usb_strerror()); - return 0; - } - if(usb_clear_halt(mydev->handle, mydev->my_ep_in) != 0) { - ERR("Clearing input endpoint: %s\n", usb_strerror()); - return 0; - } - if(flush_read(mydev) < 0) { - ERR("flush_read failed\n"); - return 0; - } - return 1; -} - -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 with 0x%X\n", pt); - phead->header.op = pt; - ret = send_usb("renumerate[W]", mydev, phead, 1, TIMEOUT); - if(ret < 0 && ret != -ENODEV) - return ret; -#if 0 - /* - * FIXME: we count on our USB firmware to reset the device... should we? - */ - ret = usb_reset(mydev->handle); - if(ret < 0) { - ERR("usb_reset: %s\n", usb_strerror()); - return -ENODEV; - } -#endif - return 0; -} - -/* - * Returns: true on success, false on failure - */ -int fpga_load(struct my_usb_device *mydev, const struct hexdata *hexdata) -{ - unsigned int i; - unsigned int j = 0; - int ret; - int finished = 0; - const char *v = hexdata->version_info; - - v = (v[0]) ? v : "Unknown"; - assert(mydev != NULL); - INFO("FPGA_LOAD (version %s)\n", v); - /* - * i - is the line number - * j - is the sequence number, on USB 2, i=j, but on - * USB 1 send_splited_hexline may increase the sequence - * number, as it needs - */ - for(i = 0; i < hexdata->maxlines; i++) { - struct hexline *hexline = hexdata->lines[i]; - - if(!hexline) - break; - if(finished) { - ERR("Extra data after End Of Data Record (line %d)\n", i); - return 0; - } - if(hexline->d.content.header.tt == TT_EOF) { - DBG("End of data\n"); - finished = 1; - continue; - } - if(mydev->is_usb2) { - if((ret = send_hexline(mydev, hexline, i)) != 0) { - perror("Failed sending hexline"); - return 0; - } - } else { - if((ret = send_splited_hexline(mydev, hexline, j, 60)) < 0) { - perror("Failed sending hexline (splitting did not help)"); - return 0; - } - j += ret; - } - } - DBG("Finished...\n"); - return 1; -} - -#include - -void usage() -{ - fprintf(stderr, "Usage: %s -D {/proc/bus/usb|/dev/bus/usb}// [options...]\n", progname); - fprintf(stderr, "\tOptions:\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[-H ] # Output to ('-' is stdout)\n"); - fprintf(stderr, "\t\t[-i] # Show hexfile information\n"); - fprintf(stderr, "\t\t[-g] # Get eeprom from device\n"); - fprintf(stderr, "\t\t[-v] # Increase verbosity\n"); -#ifdef XORCOM_INTERNAL - fprintf(stderr, "\t\t[-C srC byte] # Set Address sourCe (default: C0)\n"); - fprintf(stderr, "\t\t[-V vendorid] # Set Vendor id on device\n"); - fprintf(stderr, "\t\t[-P productid] # Set Product id on device\n"); - fprintf(stderr, "\t\t[-R release] # Set Release. 2 dot separated decimals\n"); - fprintf(stderr, "\t\t[-L label] # Set label.\n"); -#endif - exit(1); -} - -static void parse_report_func(int level, const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - if(level <= verbose) - vfprintf(stderr, msg, ap); - va_end(ap); -} - -#ifdef XORCOM_INTERNAL -static void eeprom_fill(struct myeeprom *myeeprom, - const char vendor[], - const char product[], - const char release[], - const char label[], - const char source[]) -{ - // FF: address source is from device. C0: from eeprom - if (source) - myeeprom->source = strtoul(source, NULL, 0); - else - myeeprom->source = 0xC0; - if(vendor) - myeeprom->vendor = strtoul(vendor, NULL, 0); - if(product) - myeeprom->product = strtoul(product, NULL, 0); - if(release) { - int release_major = 0; - int release_minor = 0; - - sscanf(release, "%d.%d", &release_major, &release_minor); - myeeprom->release_major = release_major; - myeeprom->release_minor = release_minor; - } - if(label) { - /* padding */ - memset(myeeprom->label, 0, LABEL_SIZE); - memcpy(myeeprom->label, label, strlen(label)); - } -} -#endif - -int main(int argc, char *argv[]) -{ - const struct astribank_type *abtype; - struct my_usb_device mydev; - const char *devpath = NULL; - const char *binfile = NULL; - const char *inhexfile = NULL; - const char *outhexfile = NULL; - struct hexdata *hexdata = NULL; - int opt_reset = 0; - int opt_info = 0; - int opt_read_eeprom = 0; - int opt_output_width = 0; - int output_is_set = 0; -#ifdef XORCOM_INTERNAL - int opt_write_eeprom = 0; - char *vendor = NULL; - char *source = NULL; - char *product = NULL; - char *release = NULL; - char *label = NULL; - const char options[] = "rib:D:ghH:I:vw:C:V:P:R:S:"; -#else - const char options[] = "rib:D:ghH:I:vw:"; -#endif - int ret = 0; - - progname = argv[0]; - assert(sizeof(struct fpga_packet_header) <= PACKET_SIZE); - assert(sizeof(struct myeeprom) == EEPROM_SIZE); - while (1) { - int c; - - c = getopt (argc, argv, options); - if (c == -1) - break; - - switch (c) { - case 'D': - devpath = optarg; - if(output_is_set++) { - ERR("Cannot set -D. Another output option is already selected\n"); - return 1; - } - break; - case 'r': - opt_reset = 1; - break; - case 'i': - opt_info = 1; - break; - case 'b': - binfile = optarg; - if(output_is_set++) { - ERR("Cannot set -b. Another output option is already selected\n"); - return 1; - } - break; - case 'g': - opt_read_eeprom = 1; - break; - case 'H': - outhexfile = optarg; - if(output_is_set++) { - ERR("Cannot set -H. Another output option is already selected\n"); - return 1; - } - break; - case 'I': - inhexfile = optarg; - break; -#ifdef XORCOM_INTERNAL - case 'V': - vendor = optarg; - break; - case 'C': - source = optarg; - break; - case 'P': - product = optarg; - break; - case 'R': - release = optarg; - break; - case 'S': - label = optarg; - { - const char GOOD_CHARS[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789" - "-_."; - int len = strlen(label); - int goodlen = strspn(label, GOOD_CHARS); - - if(len > LABEL_SIZE) { - ERR("Label too long (%d > %d)\n", len, LABEL_SIZE); - usage(); - } - if(goodlen != len) { - ERR("Bad character in label number (pos=%d)\n", goodlen); - usage(); - } - } - break; -#endif - case 'w': - opt_output_width = strtoul(optarg, NULL, 0); - break; - case 'v': - verbose++; - break; - case 'h': - default: - ERR("Unknown option '%c'\n", c); - usage(); - } - } - - if (optind != argc) { - usage(); - } - if(inhexfile) { -#ifdef XORCOM_INTERNAL - if(vendor || product || release || label || source ) { - ERR("The -I option is exclusive of -[VPRSC]\n"); - return 1; - } -#endif - parse_hexfile_set_reporting(parse_report_func); - hexdata = parse_hexfile(inhexfile, MAX_HEX_LINES); - if(!hexdata) { - ERR("Bailing out\n"); - exit(1); - } - if(opt_info) { - printf("%s: Version=%s Checksum=%d\n", - inhexfile, hexdata->version_info, - bsd_checksum(hexdata)); - } - if(binfile) { - dump_binary(hexdata, binfile); - return 0; - } - if(outhexfile) { - if(opt_output_width) - dump_hexfile2(hexdata, outhexfile, opt_output_width); - else - dump_hexfile(hexdata, outhexfile); - return 0; - } - } -#ifdef XORCOM_INTERNAL - else if(vendor || product || release || label || source ) { - if(outhexfile) { - FILE *fp; - - if(strcmp(outhexfile, "-") == 0) - fp = stdout; - else if((fp = fopen(outhexfile, "w")) == NULL) { - perror(outhexfile); - return 1; - } - memset(&mydev.eeprom, 0, sizeof(struct myeeprom)); - eeprom_fill(&mydev.eeprom, vendor, product, release, label, source); - gen_hexline((uint8_t *)&mydev.eeprom, 0, sizeof(mydev.eeprom), fp); - gen_hexline(NULL, 0, 0, fp); /* EOF */ - return 0; - } - } -#endif - if(!devpath) { - ERR("Missing device path\n"); - usage(); - } - DBG("Startup %s\n", devpath); - if((abtype = my_usb_device_identify(devpath, &mydev)) == NULL) { - ERR("Bad device. Does not match our types.\n"); - usage(); - } - INFO("FIRMWARE: %s (type=%d)\n", abtype->name, abtype->type_code); - if(!my_usb_device_init(devpath, &mydev, abtype)) { - ERR("Failed to initialize USB device '%s'\n", devpath); - ret = -ENODEV; - goto dev_err; - } - ret = eeprom_get(&mydev); - if(ret < 0) { - ERR("Failed reading eeprom\n"); - goto dev_err; - } -#ifdef XORCOM_INTERNAL - if(vendor || product || release || label || source ) { - eeprom_fill(&mydev.eeprom, vendor, product, release, label, source); - opt_write_eeprom = 1; - opt_read_eeprom = 1; - } -#endif - if(opt_read_eeprom) { - show_device_info(&mydev); - } - if(hexdata) { - if (!mydev.is_usb2) - INFO("Warning: working on a low end USB1 backend\n"); - if(!fpga_load(&mydev, hexdata)) { - ERR("FPGA loading failed\n"); - ret = -ENODEV; - goto dev_err; - } - ret = renumerate_device(&mydev, PT_RENUMERATE); - if(ret < 0) { - ERR("Renumeration failed: errno=%d\n", ret); - goto dev_err; - } - } -#ifdef XORCOM_INTERNAL - else if(opt_write_eeprom) { - if(abtype->type_code == USB_FIRMWARE_II) { - ERR("No EEPROM burning command in %s. Use fxload for that\n", - abtype->name); - goto dev_err; - } - ret = eeprom_set(&mydev, &mydev.eeprom); - if(ret < 0) { - ERR("Failed writing eeprom: %s\n", strerror(-ret)); - goto dev_err; - } - printf("------- RESULTS -------\n"); - 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); - return ret; -} -- cgit v1.2.3