diff options
Diffstat (limited to 'xpp/utils/fpga_load.c')
-rw-r--r-- | xpp/utils/fpga_load.c | 404 |
1 files changed, 276 insertions, 128 deletions
diff --git a/xpp/utils/fpga_load.c b/xpp/utils/fpga_load.c index cc9cf81..c7ce907 100644 --- a/xpp/utils/fpga_load.c +++ b/xpp/utils/fpga_load.c @@ -29,7 +29,7 @@ static const char rcsid[] = "$Id$"; static int verbose = LOG_WARNING; static char *progname; -#define MAX_HEX_LINES 2000 +#define MAX_HEX_LINES 10000 #define PACKET_SIZE 512 #define EEPROM_SIZE 16 #define SERIAL_SIZE 8 @@ -89,9 +89,13 @@ enum fpga_load_status { 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; }; @@ -188,32 +192,58 @@ int get_usb_string(char *buf, unsigned int len, uint16_t item, usb_dev_handle *h } /* My device parameters */ -#define MY_CONFIG 1 -#define MY_INTERFACE 0 -#define MY_ENDPOINTS 4 - #define MY_EP_OUT 0x04 #define MY_EP_IN 0x88 #define FPGA_EP_OUT 0x02 #define FPGA_EP_IN 0x86 -#define TIMEOUT 5000 +/* 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 int my_endpoints[MY_ENDPOINTS] = { - FPGA_EP_OUT, - MY_EP_OUT, - FPGA_EP_IN, - MY_EP_IN +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 -void my_usb_device_cleanup(struct my_usb_device *mydev) +#define TIMEOUT 5000 + +void my_usb_device_cleanup(struct my_usb_device *mydev, const struct astribank_type *abtype) { assert(mydev != NULL); if(!mydev->handle) { return; /* Nothing to do */ } - if(usb_release_interface(mydev->handle, MY_INTERFACE) != 0) { + if(usb_release_interface(mydev->handle, abtype->my_interface_num) != 0) { ERR("Releasing interface: usb: %s\n", usb_strerror()); } if(usb_close(mydev->handle) != 0) { @@ -224,11 +254,12 @@ void my_usb_device_cleanup(struct my_usb_device *mydev) static void show_device_info(const struct my_usb_device *mydev) { const struct myeeprom *eeprom; - const uint8_t *data = eeprom->serial; + uint8_t data[SERIAL_SIZE + 1]; assert(mydev != NULL); eeprom = &mydev->eeprom; - data = eeprom->serial; + memset(data, 0, SERIAL_SIZE + 1); + memcpy(data, eeprom->serial, SERIAL_SIZE); printf("USB iManufacturer: [%s]\n", mydev->iManufacturer); printf("USB iProduct: [%s]\n", mydev->iProduct); printf("USB iSerialNumber: [%s]\n", mydev->iSerialNumber); @@ -236,9 +267,9 @@ static void show_device_info(const struct my_usb_device *mydev) 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 Serial: 0x[%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X]\n", + printf("EEPROM Serial: 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[4], data[5], data[6], data[7], data); } void dump_packet(const char *msg, const char *buf, int len) @@ -249,38 +280,45 @@ void dump_packet(const char *msg, const char *buf, int len) 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) +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); - ret = usb_bulk_write(mydev->handle, endpoint, p, len, timeout); + 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) { - ERR("bulk_write failed: %s\n", usb_strerror()); + ERR("bulk_write to endpoint 0x%x failed: %s\n", mydev->my_ep_out, usb_strerror()); dump_packet("send_usb[ERR]", p, len); return ret; } else if(ret != len) { - ERR("bulk_write short write: %s\n", usb_strerror()); + 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, int endpoint, char *buf, size_t len, int timeout) +int recv_usb(const char *msg, struct my_usb_device *mydev, 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(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 failed: %s\n", usb_strerror()); - dump_packet("recv_usb[ERR]", buf, len); + 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; } @@ -297,10 +335,10 @@ int eeprom_set(struct my_usb_device *mydev, const struct myeeprom *eeprom) 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, MY_EP_OUT, phead, len, TIMEOUT); + ret = send_usb("eeprom_set[W]", mydev, phead, len, TIMEOUT); if(ret < 0) return ret; - ret = recv_usb("eeprom_set[R]", mydev, MY_EP_IN, buf, sizeof(buf), TIMEOUT); + ret = recv_usb("eeprom_set[R]", mydev, buf, sizeof(buf), TIMEOUT); if(ret <= 0) return ret; phead = (struct fpga_packet_header *)buf; @@ -328,10 +366,10 @@ int eeprom_get(struct my_usb_device *mydev) 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, MY_EP_OUT, phead, len, TIMEOUT); + ret = send_usb("eeprom_get[W]", mydev, phead, len, TIMEOUT); if(ret < 0) return ret; - ret = recv_usb("eeprom_get[R]", mydev, MY_EP_IN, buf, sizeof(buf), TIMEOUT); + ret = recv_usb("eeprom_get[R]", mydev, buf, sizeof(buf), TIMEOUT); if(ret <= 0) return ret; phead = (struct fpga_packet_header *)buf; @@ -357,22 +395,22 @@ int send_hexline(struct my_usb_device *mydev, struct hexline *hexline, int seq) assert(mydev != NULL); assert(hexline != NULL); - len = hexline->d.content.header.ll; /* don't send checksum */ - data = hexline->d.content.tt_data.data; if(hexline->d.content.header.tt != TT_DATA) { - ERR("Bad record %d type = %d\n", seq, hexline->d.content.header.tt); - return -EINVAL; + 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, MY_EP_OUT, phead, len, TIMEOUT); + ret = send_usb("hexline[W]", mydev, phead, len, TIMEOUT); if(ret < 0) return ret; - ret = recv_usb("hexline[R]", mydev, MY_EP_IN, buf, sizeof(buf), TIMEOUT); + ret = recv_usb("hexline[R]", mydev, buf, sizeof(buf), TIMEOUT); if(ret <= 0) return ret; DBG("%04d-\r", seq); @@ -427,7 +465,7 @@ int send_splited_hexline(struct my_usb_device *mydev, struct hexline *hexline, i ERR("Not enough memory for spliting the lines\n" ); return -EINVAL; } - memset( extraline, 0, allocsize ); + 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; @@ -444,7 +482,53 @@ int send_splited_hexline(struct my_usb_device *mydev, struct hexline *hexline, i return linessent; } -int my_usb_device_init(const char devpath[], struct my_usb_device *mydev) +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; @@ -468,44 +552,23 @@ 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_set_configuration(mydev->handle, MY_CONFIG) != 0) { - ERR("usb: %s\n", usb_strerror()); - return 0; - } - if(usb_claim_interface(mydev->handle, MY_INTERFACE) != 0) { - ERR("usb: %s\n", usb_strerror()); + if(usb_claim_interface(mydev->handle, abtype->my_interface_num) != 0) { + ERR("usb_claim_interface: %s\n", usb_strerror()); return 0; } if(usb_reset(mydev->handle) != 0) { - ERR("Reseting device: usb: %s\n", usb_strerror()); + ERR("usb_reset: %s\n", usb_strerror()); return 0; } dev_desc = &mydev->dev->descriptor; config_desc = mydev->dev->config; - interface = &config_desc->interface[MY_INTERFACE]; + interface = &config_desc->interface[abtype->my_interface_num]; iface_desc = interface->altsetting; - INFO("Vendor:Product=%04X:%04X Class=%d (endpoints=%d)\n", - dev_desc->idVendor, - dev_desc->idProduct, - dev_desc->bDeviceClass, - iface_desc->bNumEndpoints); - if(iface_desc->bInterfaceClass != 0xFF) { - ERR("Wrong Interface class %d\n", iface_desc->bInterfaceClass); - return 0; - } - if(iface_desc->bInterfaceNumber != MY_INTERFACE) { - ERR("Wrong Interface number %d\n", iface_desc->bInterfaceNumber); - return 0; - } - if(iface_desc->bNumEndpoints != MY_ENDPOINTS) { - ERR("Wrong number of endpoints: %d\n", iface_desc->bNumEndpoints); - return 0; - } endpoint = iface_desc->endpoint; mydev->is_usb2 = (endpoint->wMaxPacketSize == 512); for(i = 0; i < iface_desc->bNumEndpoints; i++, endpoint++) { - if(endpoint->bEndpointAddress != my_endpoints[i]) { - ERR("Wrong endpoint %d: address = 0x%X\n", i, endpoint->bEndpointAddress); + 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) { @@ -515,17 +578,27 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev) } } } - if(usb_resetep(mydev->handle, MY_EP_OUT) != 0) { + 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_resetep(mydev->handle, mydev->my_ep_out) != 0) { ERR("Failed to reset usb output endpoint: %s\n", usb_strerror()); return 0; } - if(usb_resetep(mydev->handle, MY_EP_IN) != 0) { + if(usb_resetep(mydev->handle, mydev->my_ep_in) != 0) { ERR("Failed to reset usb input endpoint: %s\n", usb_strerror()); return 0; } - 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); return 1; } @@ -538,7 +611,7 @@ int renumerate_device(struct my_usb_device *mydev, enum fpga_load_packet_types p assert(mydev != NULL); DBG("Renumerating with 0x%X\n", pt); phead->header.op = pt; - ret = send_usb("renumerate[W]", mydev, MY_EP_OUT, phead, 1, TIMEOUT); + ret = send_usb("renumerate[W]", mydev, phead, 1, TIMEOUT); if(ret < 0) return ret; return 0; @@ -604,8 +677,10 @@ void usage() fprintf(stderr, "\t\t[-r] # Reset the device\n"); fprintf(stderr, "\t\t[-b <binfile>] # Output to <binfile>\n"); fprintf(stderr, "\t\t[-I <hexfile>] # Input from <hexfile>\n"); + fprintf(stderr, "\t\t[-H <hexfile>] # Output to <hexfile> ('-' 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"); @@ -626,28 +701,63 @@ static void parse_report_func(int level, const char *msg, ...) va_end(ap); } +#ifdef XORCOM_INTERNAL +static void eeprom_fill(struct myeeprom *myeeprom, + const char vendor[], + const char product[], + const char release[], + const char serial[], + 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(serial) { + /* padding */ + memset(myeeprom->serial, 0, SERIAL_SIZE); + memcpy(myeeprom->serial, serial, strlen(serial)); + } +} +#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 *hexfile = 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; - int is_source_given = 0; char *product = NULL; char *release = NULL; char *serial = NULL; - uint8_t serial_buf[SERIAL_SIZE]; - const char options[] = "rib:C:D:ghI:vV:P:R:S:"; + const char options[] = "rib:D:ghH:I:vw:C:V:P:R:S:"; #else - const char options[] = "rib:D:ghI:v"; + const char options[] = "rib:D:ghH:I:vw:"; #endif int ret = 0; @@ -664,6 +774,10 @@ int main(int argc, char *argv[]) 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; @@ -673,12 +787,23 @@ int main(int argc, char *argv[]) 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': - hexfile = optarg; + inhexfile = optarg; break; #ifdef XORCOM_INTERNAL case 'V': @@ -686,7 +811,6 @@ int main(int argc, char *argv[]) break; case 'C': source = optarg; - is_source_given = 1; break; case 'P': product = optarg; @@ -697,28 +821,28 @@ int main(int argc, char *argv[]) case 'S': serial = optarg; { - int i; - char *p; - unsigned long val; - - p = strtok(serial, ","); - for(i = 0; i < SERIAL_SIZE && p; i++) { - val = strtoul(p, NULL, 0); - if(val > 0xFF) { - ERR("Value #%d for -S option is too large (%lu)\n", i+1, val); - usage(); - } - serial_buf[i] = val; - p = strtok(NULL, ","); + const char GOOD_CHARS[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "-_."; + int len = strlen(serial); + int goodlen = strspn(serial, GOOD_CHARS); + + if(len > SERIAL_SIZE) { + ERR("Serial number too long (%d > %d)\n", len, SERIAL_SIZE); + usage(); } - if(i < SERIAL_SIZE) { - ERR("got only %d values for -S option. Need %d\n", i, SERIAL_SIZE); + if(goodlen != len) { + ERR("Bad character in serial number (pos=%d)\n", goodlen); usage(); } } - break; #endif + case 'w': + opt_output_width = strtoul(optarg, NULL, 0); + break; case 'v': verbose++; break; @@ -732,34 +856,66 @@ int main(int argc, char *argv[]) if (optind != argc) { usage(); } - if(hexfile) { + if(inhexfile) { +#ifdef XORCOM_INTERNAL + if(vendor || product || release || serial || source ) { + ERR("The -I option is exclusive of -[VPRSC]\n"); + return 1; + } +#endif parse_hexfile_set_reporting(parse_report_func); - hexdata = parse_hexfile(hexfile, MAX_HEX_LINES); + 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", - hexfile, hexdata->version_info, - calc_checksum(hexdata)); + inhexfile, hexdata->version_info, + bsd_checksum(hexdata)); } - if(binfile) + if(binfile) { dump_binary(hexdata, binfile); - if(!devpath) 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 || serial || 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, serial, 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(); } -#ifdef XORCOM_INTERNAL - if(vendor || product || release || serial || source ) - opt_read_eeprom = opt_write_eeprom = 1; -#endif DBG("Startup %s\n", devpath); - - if(!my_usb_device_init(devpath, &mydev)) { + 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; @@ -769,6 +925,13 @@ int main(int argc, char *argv[]) ERR("Failed reading eeprom\n"); goto dev_err; } +#ifdef XORCOM_INTERNAL + if(vendor || product || release || serial || source ) { + eeprom_fill(&mydev.eeprom, vendor, product, release, serial, source); + opt_write_eeprom = 1; + opt_read_eeprom = 1; + } +#endif if(opt_read_eeprom) { show_device_info(&mydev); } @@ -787,26 +950,11 @@ int main(int argc, char *argv[]) } } #ifdef XORCOM_INTERNAL - if(opt_write_eeprom) { - // FF: address source is from device. C0: from eeprom - if (is_source_given) - mydev.eeprom.source = strtoul(source, NULL, 0); - else - mydev.eeprom.source = 0xC0; - if(vendor) - mydev.eeprom.vendor = strtoul(vendor, NULL, 0); - if(product) - mydev.eeprom.product = strtoul(product, NULL, 0); - if(release) { - int release_major = 0; - int release_minor = 0; - - sscanf(release, "%d.%d", &release_major, &release_minor); - mydev.eeprom.release_major = release_major; - mydev.eeprom.release_minor = release_minor; - } - if(serial) { - memcpy(&mydev.eeprom.serial, serial_buf, SERIAL_SIZE); + 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) { @@ -827,6 +975,6 @@ int main(int argc, char *argv[]) } DBG("Exiting\n"); dev_err: - my_usb_device_cleanup(&mydev); + my_usb_device_cleanup(&mydev, abtype); return ret; } |