int main(int argc, char * const argv[]) { struct sdp_dev *p_id; struct mach_id *mach; libusb_device **devs; libusb_device *dev; int r; int err; ssize_t cnt; libusb_device_handle *h = NULL; int config = 0; int verify = 0; struct sdp_work *curr; struct sdp_work *cmd_head = NULL; char const *conf; char const *base_path = get_base_path(argv[0]); char const *conf_path = "/etc/imx-loader.d/"; err = parse_opts(argc, argv, &conf_path, &verify, &cmd_head); if (err < 0) return -1; // Get list of machines... conf = conf_file_name("imx_usb.conf", base_path, conf_path); if (conf == NULL) return -1; struct mach_id *list = parse_imx_conf(conf); if (!list) return -1; r = libusb_init(NULL); if (r < 0) goto out; cnt = libusb_get_device_list(NULL, &devs); if (cnt < 0) goto out; // print_devs(devs); dev = find_imx_dev(devs, &mach, list); if (dev) { err = libusb_open(dev, &h); if (err) printf("%s:Could not open device vid=0x%x pid=0x%x err=%d\n", __func__, mach->vid, mach->pid, err); } libusb_free_device_list(devs, 1); if (!h) goto out; // Get machine specific configuration file.. conf = conf_file_name(mach->file_name, base_path, conf_path); if (conf == NULL) goto out; p_id = parse_conf(conf); if (!p_id) goto out; if (p_id->mode == MODE_HID) p_id->transfer = &transfer_hid; if (p_id->mode == MODE_BULK) p_id->transfer = &transfer_bulk; // USB private pointer is libusb device handle... p_id->priv = h; libusb_get_configuration(h, &config); printf("%04x:%04x(%s) bConfigurationValue =%x\n", mach->vid, mach->pid, p_id->name, config); if (libusb_kernel_driver_active(h, 0)) libusb_detach_kernel_driver(h, 0); err = libusb_claim_interface(h, 0); if (err) { printf("Claim failed\n"); goto out; } printf("Interface 0 claimed\n"); err = do_status(p_id); if (err) { printf("status failed\n"); goto out; } // By default, use work from config file... curr = p_id->work; if (cmd_head != NULL) curr = cmd_head; if (curr == NULL) { printf("no job found\n"); goto out; } while (curr) { if (curr->mem) perform_mem_work(p_id, curr->mem); // printf("jump_mode %x\n", curr->jump_mode); if (curr->filename[0]) { err = DoIRomDownload(p_id, curr, verify); } if (err) { err = do_status(p_id); break; } if (!curr->next && (!curr->plug || curr != cmd_head)) break; err = do_status(p_id); printf("jump_mode %x plug=%i err=%i\n", curr->jump_mode, curr->plug, err); if (err) { int retry; /* Rediscovers device */ libusb_release_interface(h, 0); libusb_close(h); libusb_exit(NULL); for (retry = 0; retry < 10; retry++) { printf("sleeping\n"); sleep(3); printf("done sleeping\n"); h = open_vid_pid(mach, p_id); if (h) break; } if (!h) goto out; } if (curr == cmd_head && curr->plug) { curr->plug = 0; continue; } curr = curr->next; } exit: libusb_release_interface(h, 0); out: if (h) libusb_close(h); libusb_exit(NULL); return 0; }
int do_autodetect_dev(char const *base_path, char const *conf_path, struct mach_id *list, int verify, struct sdp_work *cmd_head) { struct sdp_dev *p_id; struct mach_id *mach; libusb_device **devs; libusb_device *dev; int err = 0; ssize_t cnt; struct sdp_work *curr; libusb_device_handle *h = NULL; char const *conf; int retry; err = libusb_init(NULL); if (err < 0) return err; cnt = libusb_get_device_list(NULL, &devs); if (cnt < 0) { err = LIBUSB_ERROR_NO_DEVICE; goto out_deinit_usb; } // print_devs(devs); dev = find_imx_dev(devs, &mach, list); if (!dev) { libusb_free_device_list(devs, 1); err = LIBUSB_ERROR_NO_DEVICE; goto out_deinit_usb; } err = libusb_open(dev, &h); libusb_free_device_list(devs, 1); if (err < 0) { fprintf(stderr, "Could not open device vid=0x%x pid=0x%x: %s, err=%d\n", mach->vid, mach->pid, libusb_strerror(err), err); goto out_deinit_usb; } // Get machine specific configuration file.. conf = conf_file_name(mach->file_name, base_path, conf_path); if (conf == NULL) { err = LIBUSB_ERROR_OTHER; goto out_close_usb; } p_id = parse_conf(conf); if (!p_id) { err = LIBUSB_ERROR_OTHER; goto out_close_usb; } if (p_id->mode == MODE_HID) p_id->transfer = &transfer_hid; if (p_id->mode == MODE_BULK) p_id->transfer = &transfer_bulk; // By default, use work from config file... curr = p_id->work; if (cmd_head != NULL) curr = cmd_head; if (curr == NULL) { fprintf(stderr, "no job found\n"); err = LIBUSB_ERROR_OTHER; goto out_close_usb; } retry: // USB private pointer is libusb device handle... p_id->priv = h; err = do_work(p_id, &curr, verify); dbg_printf("do_work finished with err=%d, curr=%p\n", err, curr); out_close_usb: libusb_close(h); /* More work to do? Try to rediscover the same device */ if (curr && !(err < 0)) { for (retry = 0; retry < 10; retry++) { msleep(3000); h = libusb_open_device_with_vid_pid(NULL, mach->vid, mach->pid); if (h) goto retry; fprintf(stderr, "Could not open device vid=0x%x pid=0x%x err=%d\n", mach->vid, mach->pid, err); } } out_deinit_usb: libusb_exit(NULL); return err; }