summaryrefslogtreecommitdiff
path: root/xpp/utils/fpga_load.c
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/utils/fpga_load.c')
-rw-r--r--xpp/utils/fpga_load.c404
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;
}