Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 22 Dec 2012 18:17:15 +0800
From:      Xiaofan Chen <xiaofanc@gmail.com>
To:        Hans Petter Selasky <hselasky@c2i.net>
Cc:        "Wojciech A. Koszek" <wkoszek@freebsd.org>, freebsd-usb@freebsd.org
Subject:   Re: usb/173666: [USB, LIBUSB] usb_reset() behavior different between GNU/Linux and FreeBSD
Message-ID:  <CAGjSPUCuDUTMTn427v=GWdLqm3LcSM7OR1nFpVoyXgba%2BtX3dQ@mail.gmail.com>
In-Reply-To: <201212210838.32260.hselasky@c2i.net>
References:  <201211162247.qAGMlTm2057387@red.freebsd.org> <201211171319.34781.hselasky@c2i.net> <CAGjSPUAw5P_qJu%2BZVGHn5yQuR33zchjgB7WfQvN=7TDq99N_Fg@mail.gmail.com> <201212210838.32260.hselasky@c2i.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, Dec 21, 2012 at 3:38 PM, Hans Petter Selasky <hselasky@c2i.net> wrote:
> If you look in the old libusb-0.1 code you'll see something different I think.
> Could you check that?

Not much differences in reality. I believe it is a document bug for the
libusb-0.1.

Both old libusb-0.1 code and libusb-1.0 use the same IOCTL under Linux
and the behavior should be similar.

Please refer to the following code listing and take note even though
the name of the IOCTL is different but they are the same if you
look at the defines.

On the other hand, libusb-win32's usb_reset will cause re-enumeration.

>From libusb-0.1.12 source (linux.c)
int usb_reset(usb_dev_handle *dev)
{
  int ret;

  ret = ioctl(dev->fd, IOCTL_USB_RESET, NULL);
  if (ret)
     USB_ERROR_STR(-errno, "could not reset: %s", strerror(errno));

  return 0;
}

>From libusb.org libusb.git (libusb-1.0) souce:

static int op_reset_device(struct libusb_device_handle *handle)
{
	int fd = _device_handle_priv(handle)->fd;
	int i, r, ret = 0;

	/* Doing a device reset will cause the usbfs driver to get unbound
	   from any interfaces it is bound to. By voluntarily unbinding
	   the usbfs driver ourself, we stop the kernel from rebinding
	   the interface after reset (which would end up with the interface
	   getting bound to the in kernel driver if any). */
	for (i = 0; i < USB_MAXINTERFACES; i++) {
		if (handle->claimed_interfaces & (1L << i)) {
			op_release_interface(handle, i);
		}
	}

	usbi_mutex_lock(&handle->lock);
	r = ioctl(fd, IOCTL_USBFS_RESET, NULL);
	if (r) {
		if (errno == ENODEV) {
			ret = LIBUSB_ERROR_NOT_FOUND;
			goto out;
		}

		usbi_err(HANDLE_CTX(handle),
			"reset failed error %d errno %d", r, errno);
		ret = LIBUSB_ERROR_OTHER;
		goto out;
	}

	/* And re-claim any interfaces which were claimed before the reset */
	for (i = 0; i < USB_MAXINTERFACES; i++) {
		if (handle->claimed_interfaces & (1L << i)) {
			r = op_claim_interface(handle, i);
			if (r) {
				usbi_warn(HANDLE_CTX(handle),
					"failed to re-claim interface %d after reset", i);
				handle->claimed_interfaces &= ~(1L << i);
			}
		}
	}
out:
	usbi_mutex_unlock(&handle->lock);
	return ret;
}


-- 
Xiaofan



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAGjSPUCuDUTMTn427v=GWdLqm3LcSM7OR1nFpVoyXgba%2BtX3dQ>