コード例 #1
0
ファイル: imx_usb.c プロジェクト: hikob/imx_usb_loader
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;
}
コード例 #2
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;
}