By the way ... I think this would be very good to see aversion of this go
into the 2.4 tree too. I was glad to see it finally land in 2.5.8 ...
The original patch dates to something like January 2000 (2.4.0 :) and the
functionality will be useful for folk doing things like writing user mode
drivers that will work on both 2.4 and 2.5 kernels (where we're starting
to phase out some kernel device support), as well as for special cases
like vmware (debugging device drivers in user user mode).
- Dave
----- Original Message -----
From: "Greg KH" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Monday, April 08, 2002 3:55 PM
Subject: [linux-usb-devel] Re: [BK PATCH] USB changes for 2.5.8-pre2
> # This is a BitKeeper generated patch for the following project:
> # Project Name: Linux kernel tree
> # This patch format is intended for GNU patch command version 2.5 or higher.
> # This patch includes the following deltas:
> # ChangeSet 1.593 -> 1.594
> # include/linux/usbdevice_fs.h 1.4 -> 1.5
> # include/linux/usb.h 1.23 -> 1.24
> # drivers/usb/core/devio.c 1.23 -> 1.24
> # drivers/usb/core/usb.c 1.38 -> 1.39
> #
> # The following is the BitKeeper ChangeSet Log
> # --------------------------------------------
> # 02/04/08 [EMAIL PROTECTED] 1.594
> # [PATCH] usbfs disconnect
> #
> # This was originally created by David many months ago and posted to the
> # list, but not put into the kernel.
> #
> # I modified the original patch to:
> # -patch against the 2.5.7 kernel
> # -use the 'real' interface number, not position (to do this I added 2
> # methods in usb.c)
> # --------------------------------------------
> #
> diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
> --- a/drivers/usb/core/devio.c Mon Apr 8 15:49:14 2002
> +++ b/drivers/usb/core/devio.c Mon Apr 8 15:49:14 2002
> @@ -1057,6 +1057,8 @@
> int size;
> void *buf = 0;
> int retval = 0;
> + struct usb_interface *ifp = 0;
> + struct usb_driver *driver = 0;
>
> /* get input parameters and alloc buffer */
> if (copy_from_user(&ctrl, (void *) arg, sizeof (ctrl)))
> @@ -1074,33 +1076,41 @@
> }
> }
>
> - /* ioctl to device */
> - if (ctrl.ifno < 0) {
> - switch (ctrl.ioctl_code) {
> - /* access/release token for issuing control messages
> - * ask a particular driver to bind/unbind, ... etc
> - */
> - }
> - retval = -ENOSYS;
> + if (!ps->dev)
> + retval = -ENODEV;
> + else if (!(ifp = usb_ifnum_to_if (ps->dev, ctrl.ifno)))
> + retval = -EINVAL;
> + else switch (ctrl.ioctl_code) {
>
> - /* ioctl to the driver which has claimed a given interface */
> - } else {
> - struct usb_interface *ifp = 0;
> - if (!ps->dev)
> - retval = -ENODEV;
> - else if (ctrl.ifno >= ps->dev->actconfig->bNumInterfaces)
> + /* disconnect kernel driver from interface, leaving it unbound. */
> + case USBDEVFS_DISCONNECT:
> + driver = ifp->driver;
> + if (driver) {
> + down (&driver->serialize);
> + dbg ("disconnect '%s' from dev %d interface %d",
> + driver->name, ps->dev->devnum, ctrl.ifno);
> + driver->disconnect (ps->dev, ifp->private_data);
> + usb_driver_release_interface (driver, ifp);
> + up (&driver->serialize);
> + } else
> retval = -EINVAL;
> + break;
> +
> + /* let kernel drivers try to (re)bind to the interface */
> + case USBDEVFS_CONNECT:
> + usb_find_interface_driver_for_ifnum (ps->dev, ctrl.ifno);
> + break;
> +
> + /* talk directly to the interface's driver */
> + default:
> + driver = ifp->driver;
> + if (driver == 0 || driver->ioctl == 0)
> + retval = -ENOSYS;
> else {
> - if (!(ifp = usb_ifnum_to_if (ps->dev, ctrl.ifno)))
> - retval = -EINVAL;
> - else if (ifp->driver == 0 || ifp->driver->ioctl == 0)
> - retval = -ENOSYS;
> - }
> - if (retval == 0) {
> if (ifp->driver->owner)
> __MOD_INC_USE_COUNT(ifp->driver->owner);
> /* ifno might usefully be passed ... */
> - retval = ifp->driver->ioctl (ps->dev, ctrl.ioctl_code, buf);
> + retval = driver->ioctl (ps->dev, ctrl.ioctl_code, buf);
> /* size = min_t(int, size, retval)? */
> if (ifp->driver->owner)
> __MOD_DEC_USE_COUNT(ifp->driver->owner);
> diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
> --- a/drivers/usb/core/usb.c Mon Apr 8 15:49:14 2002
> +++ b/drivers/usb/core/usb.c Mon Apr 8 15:49:14 2002
> @@ -196,6 +196,26 @@
> usbfs_update_special();
> }
>
> +/*
> + * usb_ifnum_to_ifpos - convert the interface _number_ (as in
>interface.bInterfaceNumber)
> + * to the interface _position_ (as in dev->actconfig->interface + position)
> + * @dev: the device to use
> + * @ifnum: the interface number (bInterfaceNumber); not interface position
> + *
> + * Note that the number is the same as the position for all interfaces _except_
> + * devices with interfaces not sequentially numbered (e.g., 0, 2, 3, etc).
> + */
> +int usb_ifnum_to_ifpos(struct usb_device *dev, unsigned ifnum)
> +{
> + int i;
> +
> + for (i = 0; i < dev->actconfig->bNumInterfaces; i++)
> + if (dev->actconfig->interface[i].altsetting[0].bInterfaceNumber == ifnum)
> + return i;
> +
> + return -EINVAL;
> +}
> +
> /**
> * usb_ifnum_to_if - get the interface object with a given interface number
> * @dev: the device whose current configuration is considered
> @@ -570,6 +590,23 @@
> return -1;
> }
>
> +/*
> + * usb_find_interface_driver_for_ifnum - convert ifnum to ifpos via
> + * usb_ifnum_to_ifpos and call usb_find_interface_driver().
> + * @dev: the device to use
> + * @ifnum: the interface number (bInterfaceNumber); not interface position!
> + *
> + * Note usb_find_interface_driver's ifnum parameter is actually interface position.
> + */
> +int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned ifnum)
> +{
> + int ifpos = usb_ifnum_to_ifpos(dev, ifnum);
> +
> + if (0 > ifpos)
> + return -EINVAL;
> +
> + return usb_find_interface_driver(dev, ifpos);
> +}
>
> #ifdef CONFIG_HOTPLUG
>
> @@ -2636,6 +2673,7 @@
> * into the kernel, and other device drivers are built as modules,
> * then these symbols need to be exported for the modules to use.
> */
> +EXPORT_SYMBOL(usb_ifnum_to_ifpos);
> EXPORT_SYMBOL(usb_ifnum_to_if);
> EXPORT_SYMBOL(usb_epnum_to_ep_desc);
>
> @@ -2647,6 +2685,7 @@
> EXPORT_SYMBOL(usb_free_dev);
> EXPORT_SYMBOL(usb_inc_dev_use);
>
> +EXPORT_SYMBOL(usb_find_interface_driver_for_ifnum);
> EXPORT_SYMBOL(usb_driver_claim_interface);
> EXPORT_SYMBOL(usb_interface_claimed);
> EXPORT_SYMBOL(usb_driver_release_interface);
> diff -Nru a/include/linux/usb.h b/include/linux/usb.h
> --- a/include/linux/usb.h Mon Apr 8 15:49:14 2002
> +++ b/include/linux/usb.h Mon Apr 8 15:49:14 2002
> @@ -305,6 +305,7 @@
> } __attribute__ ((packed));
>
> /* helpers for driver access to descriptors */
> +extern int usb_ifnum_to_ifpos(struct usb_device *dev, unsigned ifnum);
> extern struct usb_interface *
> usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum);
> extern struct usb_endpoint_descriptor *
> @@ -1052,6 +1053,7 @@
> #define usb_dec_dev_use usb_free_dev
>
> /* used these for multi-interface device registration */
> +extern int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned int
>ifnum);
> extern void usb_driver_claim_interface(struct usb_driver *driver,
> struct usb_interface *iface, void* priv);
> extern int usb_interface_claimed(struct usb_interface *iface);
> diff -Nru a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h
> --- a/include/linux/usbdevice_fs.h Mon Apr 8 15:49:14 2002
> +++ b/include/linux/usbdevice_fs.h Mon Apr 8 15:49:14 2002
> @@ -142,6 +142,8 @@
> #define USBDEVFS_HUB_PORTINFO _IOR('U', 19, struct usbdevfs_hub_portinfo)
> #define USBDEVFS_RESET _IO('U', 20)
> #define USBDEVFS_CLEAR_HALT _IOR('U', 21, unsigned int)
> +#define USBDEVFS_DISCONNECT _IO('U', 22)
> +#define USBDEVFS_CONNECT _IO('U', 23)
>
> /* --------------------------------------------------------------------- */
>
>
> _______________________________________________
> [EMAIL PROTECTED]
> To unsubscribe, use the last form field at:
> https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
>
> Sponsored by http://www.ThinkGeek.com/
>
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel