From: Tormod Volden <debian.tor...@gmail.com> It should exist both in run-time and DFU mode, and should report the transfer size.
Also print out the device DFU version as reported by the functional descriptor. For DFU 1.0 devices the descriptor does not contain the version field, so set it to 1.00 if the field is missing. Signed-off-by: Tormod Volden <debian.tor...@gmail.com> --- I am pretty sure all supported devices return this descriptor? So we can bail out if we can't retrieve it. The program banner announces it only supports DFU 1.0 but the fact is that it uses a few 1.1-only features. We should try to cover both in the long run, and I think we should also follow the standard strictly, and rather add device-specific quirks if needed. src/main.c | 48 ++++++++++++++++++++++++++++++++++++------------ 1 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/main.c b/src/main.c index 819e26c..f6b0ac8 100644 --- a/src/main.c +++ b/src/main.c @@ -106,6 +106,7 @@ static int find_dfu_if(libusb_device *dev, intf->bInterfaceNumber; dfu_if->altsetting = intf->bAlternateSetting; + /* FIXME: always 0 for DFU 1.0 */ if (intf->bInterfaceProtocol == 2) dfu_if->flags |= DFU_IFF_DFU; else @@ -517,7 +518,7 @@ int main(int argc, char **argv) unsigned int host_page_size; enum mode mode = MODE_NONE; struct dfu_status status; - struct usb_dfu_func_descriptor func_dfu; + struct usb_dfu_func_descriptor func_dfu, func_dfu_rt; libusb_context *ctx; struct dfu_file file; char *alt_name = NULL; /* query alt name if non-NULL */ @@ -682,6 +683,21 @@ int main(int argc, char **argv) /* find set of quirks for this device */ set_quirks(_rt_dif.vendor, _rt_dif.product); + /* Retrieve run-time DFU functional descriptor */ + ret = usb_get_extra_descriptor(&_rt_dif, USB_DT_DFU, _rt_dif.interface, + &func_dfu_rt, sizeof(func_dfu_rt)); + if (ret == 7) { + /* DFU 1.0 does not have this field */ + printf("Deducing device DFU version from functional descriptor " + "length\n"); + func_dfu_rt.bcdDFUVersion = libusb_cpu_to_le16(0x0100); + } else if (ret < 9) { + fprintf(stderr, "Error obtaining DFU functional descriptor\n"); + exit(1); + } + printf("Run-time device DFU version %x\n", + libusb_le16_to_cpu(func_dfu_rt.bcdDFUVersion)); + if (!(_rt_dif.flags & DFU_IFF_DFU)) { /* In the 'first round' during runtime mode, there can only be one * DFU Interface descriptor according to the DFU Spec. */ @@ -888,19 +904,27 @@ status_again: break; } + /* Retrieve DFU mode DFU functional descriptor */ + ret = usb_get_extra_descriptor(dif, USB_DT_DFU, dif->interface, + &func_dfu, sizeof(func_dfu)); + if (ret == 7) { + /* DFU 1.0 does not have this field */ + func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100); + } else if (ret < 9) { + fprintf(stderr, "Error obtaining DFU functional descriptor\n"); + exit(1); + } + if (func_dfu.bcdDFUVersion != func_dfu_rt.bcdDFUVersion) { + fprintf(stderr, "DFU functional descriptor mismatch\n"); + exit(1); + } + + /* if not specified by user */ if (!transfer_size) { - /* Obtain DFU functional descriptor */ - ret = usb_get_extra_descriptor(dif, USB_DT_DFU, - dif->interface, &func_dfu, sizeof(func_dfu)); - if (ret < 0) { - fprintf(stderr, "Error obtaining DFU functional " - "descriptor\n"); - } else { - transfer_size = libusb_le16_to_cpu(func_dfu.wTransferSize); - printf("Device returned transfer size %i\n", - transfer_size); - } + transfer_size = libusb_le16_to_cpu(func_dfu.wTransferSize); + printf("Device reported transfer size %i\n", transfer_size); } + /* if returned zero or not detected (and not user specified) */ if (!transfer_size) { transfer_size = DEFAULT_TRANSFER_SIZE; -- 1.7.5.4 _______________________________________________ devel mailing list devel@lists.openmoko.org https://lists.openmoko.org/mailman/listinfo/devel