Caribe Schreiber | 1 Jun 03:14 2006

Re: SOLVED: Memory leak in usb_os_find_devices() on darwin

Hello all,

It appears that there is an extra pointer in the usb_device struct that is used on the darwin port to hold the device's address (which is malloc()'d and populated in the segment referenced below).  It looks like handling this port specific data was lost in the destructor

I made some very minor changes and have a patch for the 1.1.10a version as well as the 1.1.12 version.  Both patches are enclosed below.

~Caribe

Version:1.1.10a File:usb.c
___begin___
14a15
> #include "config.h"
293a295,299
>
>   #ifdef DARWIN_API
>     //we need to free the device address data that is allocated in the darwin port here
>     free(dev->dev);
>   #endif
___end___


Version 1.1.12 File:usb.c
___begin___
15a16,17
> #include "config.h"
>
294a297,300
>   #ifdef DARWIN_API
>     //we need to free the device address data that is allocated in the darwin port here
>     free(dev->dev);
>   #endif
___end___



On May 31, 2006, at 11:56 AM, Caribe Schreiber wrote:

Hello all,

I noted that there appears to be a memory leak in the usb_os_find_devices() function in the darwin port.  The function seems to leak several 4 byte allocations each time it's called (looks like <num_devices_on_bus> + 1 allocations are leaked).  Has anyone else noted this?  It seems like the problem lies with this alloc on line 1288 of darwin.c:

      dev->dev = (USBDeviceAddress *)malloc(4);
      memcpy(dev->dev, &location, 4);

but I don't know the internals well enough to know if they're getting freed somewhere else (or more accurately where they should be free()'d). When I change the malloc to do a 5 byte malloc the leaked segments are increased to 5 bytes, so this is definitely the culprit.

I've been working with the 1.1.10a tree since it seems that parts of the 1.1.12 darwin implementation are broken (namely bulk_read()), but I've tried this against 1.1.12 as well and found the same leak behavior.

Are there any darwin gurus out there that can shed some light on this behavior?

~Caribe
===================
Caribe Schreiber
IT Engineer
C&C Solutions, Inc.
Quote of the week:
"He has never been known to use a word that might send a reader to the dictionary."
--William Faulkner (about Ernest Hemingway)
"Poor Faulkner.  Does he really think big emotions come from big words?"
--Ernest Hemingway (about William Faulkner)






===================
Caribe Schreiber
IT Engineer
C&C Solutions, Inc.
Quote of the week:
"He has never been known to use a word that might send a reader to the dictionary."
--William Faulkner (about Ernest Hemingway)
"Poor Faulkner.  Does he really think big emotions come from big words?"
--Ernest Hemingway (about William Faulkner)





Marcus Meissner | 1 Jun 07:52 2006
Picon

Re: using /dev/bus/usb vs. /proc/bus/usb

On Wed, May 31, 2006 at 03:31:20PM -0700, Eric Hawkins wrote:
> Hello-
> 
> I am using FC5 with libusb to interface to a scientific camera.  I have udev
> and pam rules to configure the device node for the camera appropriately when
> it is plugged in, but permissions on the /proc/bus/usb entries still
> restrict non-root users from accessing the camera.  How can I make libusb
> ignore the /proc device tree in favor of the appropriately permissioned /dev
> tree?  Or do I need to modify permissions on the /proc tree as part of my
> udev rules?

Just umount /proc/bus/usb ? 

Or use the USB_DEVFS_PATH environment variable.

Ciao, Marcus

-------------------------------------------------------
All the advantages of Linux Managed Hosting--Without the Cost and Risk!
Fully trained technicians. The highest number of Red Hat certifications in
the hosting industry. Fanatical Support. Click to learn more
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=107521&bid=248729&dat=121642
Linus Walleij | 1 Jun 10:09 2006
Picon
Picon
Picon

Re: using /dev/bus/usb vs. /proc/bus/usb

On Wed, 31 May 2006, Eric Hawkins wrote:

> I am using FC5 with libusb to interface to a scientific camera.  I have udev
> and pam rules to configure the device node for the camera appropriately when
> it is plugged in,

Hi Eric, please read the attached file which I've sent around a bit.

FC5 does not use /proc/bus/usb but rather /dev/bus/usb for userspace 
access. Then as you say PAM to lift permissions for desktop access for 
example (in my experience 9 out of 10 libusb user wants this).

Example:

/etc/udev/rules.d/foo.rules:
SUBSYSTEM=="usb_device", ACTION=="add" \
SYSFS{idVendor}=="1234", SYSFS{idProduct}=="1234", SYMLINK+="foo-%k"

/etc/security/console.perms.d/foo.perms:
<foo>=/dev/foo*
<console> 0600 <foo> 0600 root

Simple?

Linus
Linux specific installation information
=======================================

Since libusb is accessing the raw device nodes exported by the kernel
in order to identify connected USB busses, functions and such, it 
needs to find these nodes. During the history of the Linux kernel,
the placement and the way of accessing these nodes have changed.

This placement is closely related to hotplugging: i.e. addition and
removal of USB functions at runtime.


Most current solution: use udev
===============================

The latest and greatest way of managing hotplugged (and cold-plugged)
devices under Linux is called "udev". This is a development of the
older "hotplug" system (see below).

When a device is connected, the kernel will call the program
/sbin/udev in order to create a device node in the /dev/ file 
hirerarchy. It will also remove devices from this hierarchy when
they are unplugged.

Traditionally, all devices plugged into a Linux system are expected
to have a kernel device driver, or to load one on-the-fly when a
new device is connected. Libusb cannot use these device drivers, 
instead it attempts to access the raw device nodes from user mode,
not as a kernel module.

In order for libusb to find the device node, it needs to locate it
in the /dev filesystem. The recommended way to let udev create nodes
in the /dev filesystem is to add a udev rule like the following into
some foo.rules file inside the /etc/udev/rules.d/ directory:

# usbfs-like devices
SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; \
  printf bus/usb/%%03i/%%03i $${K%%%%.*} $${K#*.}'", \
  NAME="%c"

This layout is used by for example the Debian distribution. This
rule creates a device tree identical to the earlier /proc/bus/usb/
tree, but under /dev/bus/usb/ instead. If this device tree exists,
libusb will default to use it. It will look like this:

/dev
  /bus
    /usb
      /001
        /001
        /002
        /003
     /002
        /001
        /002
        ...

However notice that the permissions on the nodes will be default
permissions: often this means they are only accessible for writing 
by the root user, whereas non-root users often can access it 
read-only.

The way of controlling access to a device node differs between 
systems, but a typical way of complementing udev rules with
apropriate permissions is to use PAM (pluggable Authentication
Modules), with some sort of configuration under /etc/security/.
The use of /dev nodes is also different from the old usbfs
solution in that it enables the use of ACL:s (Access Control
Lists) to control acces for the USB device nodes.

A less good alternative that may however be useful for debugging
would be to supply the argument MODE="666" to the above udev
rule, or, slightly better, to tag on:

MODE="660", GROUP="foo"

where "foo" is a group of users (e.g. desktop users) that need
to access the device in read/write mode.

If libusb cannot find a device hierarchy below /dev/bus/usb/ 
(as is the case if you are not using udev, or not using it with
the above rule), it will fall back on using /proc/bus/usb/ 
instead.

Additionally, you may want to trigger unique actions for your
device at the same time. To do this, create a rules file
/etc/udev/rules.d/bar.rules with these lines:

SUBSYSTEM=="usb_device", ACTION=="add", SYSFS{idVendor}=="1234", \
SYSFS{idProduct}=="4321"

At the end of this line you can then tag on any device-specific
actions for device 1234/4321, for example:

MODE="660", GROUP="baz"   to set mode and group
RUN="/usr/local/bin/baz"  to run a script on plug-in
SYMLINK+="foo"            to create a symlink device node with 
                          this name in /dev

You can read more about udev in its own documentation.


Previous solution: use hotplug
==============================

Before udev another system, generally considered less elegant,
known simply as "hotplug" was used. In this case the program 
/sbin/hotplug would be called whenever devices were connected
or removed from the system, and the corresponding configuration
lives in /etc/hotplug/.

With hotplug not using udev at the same time, all devices are
accessed using the usbfs hierarchy below /proc/bus/usb/. Again,
this will be used by libusb, since libusb does not use any device
drivers. The hierarchy will look like this:

/proc
  /bus
    /usb
      /001
        /001
        /002
        /003
     /002
        /001
        /002
        ...

When USB devices are plugged in, their corresponding device 
node is created in /proc/bus/usb/ by the kernel, without any
external program intervention (as is the case with udev).

However, to correct the permissions on these device nodes, if
your device requires anything else than read access, you need
to supply a script in /etc/hotplug/usb/ that detects your
device and change its permissions, for example this 
/etc/hotplug/usb/foo.usermap

# Foo device with VID=1234 and PID=4321
bar 0x0003 0x1234 0x4321 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000

(All this need to be in one line.)

The first string "bar" points out the name of a script placed
in /etc/hotplug/usb/bar, with for example the following contents:

#!/bin/bash
if [ "${ACTION}" = "add" ] && [ -f "${DEVICE}" ]
then
  chgrp baz "${DEVICE}"
  chmod 660 "${DEVICE}"
fi

to let users in the group "baz" access the device for reading
and writing.

You can read more about hotplug and its usermaps in the 
hotplug documentation.
Eric Hawkins | 1 Jun 16:57 2006
Picon

Re: using /dev/bus/usb vs. /proc/bus/usb

Thanks for the help guys.  I've got it all worked out now.

FC5 does use /proc/bus/usb, at least it gets mounted at boot and older libusb implementations default to using it.  However, with the USB_DEVFS_PATH variable you can instruct libusb to use the /dev/bus/usb tree instead.  My problem was that I'm stuck with libusb-0.1.8 for now so I need to use the environment variable in order to use the /dev tree, which is being properly configured and permissioned through udev and PAM rules.

Thanks again.

-Eric

On 6/1/06, Linus Walleij <triad <at> df.lth.se> wrote:
On Wed, 31 May 2006, Eric Hawkins wrote:

> I am using FC5 with libusb to interface to a scientific camera.  I have udev
> and pam rules to configure the device node for the camera appropriately when
> it is plugged in,

Hi Eric, please read the attached file which I've sent around a bit.

FC5 does not use /proc/bus/usb but rather /dev/bus/usb for userspace
access. Then as you say PAM to lift permissions for desktop access for
example (in my experience 9 out of 10 libusb user wants this).

Example:

/etc/udev/rules.d/foo.rules:
SUBSYSTEM=="usb_device", ACTION=="add" \
SYSFS{idVendor}=="1234", SYSFS{idProduct}=="1234", SYMLINK+="foo-%k"

/etc/security/console.perms.d/foo.perms:
<foo>=/dev/foo*
<console> 0600 <foo> 0600 root

Simple?

Linus


<div>
<p>Thanks for the help guys.&nbsp; I've got it all worked out now.<br><br>FC5 does use /proc/bus/usb, at least it gets mounted at boot and older libusb implementations default to using it.&nbsp; However, with the USB_DEVFS_PATH variable you can instruct libusb to use the /dev/bus/usb tree instead.&nbsp; My problem was that I'm stuck with 
libusb-0.1.8 for now so I need to use the environment variable in order to use the /dev tree, which is being properly configured and permissioned through udev and PAM rules.<br><br>Thanks again.<br><br>-Eric<br><br></p>
<div>
<span class="gmail_quote">
On 6/1/06, Linus Walleij &lt;<a href="mailto:triad <at> df.lth.se">triad <at> df.lth.se</a>&gt; wrote:</span><blockquote class="gmail_quote">
On Wed, 31 May 2006, Eric Hawkins wrote:<br><br>&gt; I am using FC5 with libusb to interface to a scientific camera.&nbsp;&nbsp;I have udev<br>&gt; and pam rules to configure the device node for the camera appropriately when<br>&gt; it is plugged in,
<br><br>Hi Eric, please read the attached file which I've sent around a bit.<br><br>FC5 does not use /proc/bus/usb but rather /dev/bus/usb for userspace<br>access. Then as you say PAM to lift permissions for desktop access for
<br>example (in my experience 9 out of 10 libusb user wants this).<br><br>Example:<br><br>/etc/udev/rules.d/foo.rules:<br>SUBSYSTEM=="usb_device", ACTION=="add" \<br>SYSFS{idVendor}=="1234", SYSFS{idProduct}=="1234", SYMLINK+="foo-%k"
<br><br>/etc/security/console.perms.d/foo.perms:<br>&lt;foo&gt;=/dev/foo*<br>&lt;console&gt; 0600 &lt;foo&gt; 0600 root<br><br>Simple?<br><br>Linus<br><br>
</blockquote>
</div>
<br>
</div>
_______________________________________________
Libusb-devel mailing list
Libusb-devel <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Tim Roberts | 2 Jun 00:22 2006

Re: using /dev/bus/usb vs. /proc/bus/usb

Eric Hawkins wrote:

> Thanks for the help guys.  I've got it all worked out now.
>
> FC5 does use /proc/bus/usb, at least it gets mounted at boot and older
> libusb implementations default to using it.  However, with the
> USB_DEVFS_PATH variable you can instruct libusb to use the
> /dev/bus/usb tree instead.  My problem was that I'm stuck with
> libusb-0.1.8 for now so I need to use the environment variable in
> order to use the /dev tree, which is being properly configured and
> permissioned through udev and PAM rules.

Perhaps someone can help me understand this little better.  I happen to
be using a Ubuntu system, which uses /proc/bus/usb.  I naïvely thought
this was the "latest and greatest" in USB support.  On those FC5
systems, does /dev/bus/usb have the same functionality?  That is, is
there a "devices" file, and files like "004/003" with a default driver
that responds to the same ioctls that my /proc/bus/usb device responds to?

In summary, is that just "usbfs" but mounted at a different root?

--

-- 
Tim Roberts, timr <at> probo.com
Providenza & Boekelheide, Inc.
Chris Frey | 2 Jun 00:26 2006
Picon

[patch] wait, poll, and abort support

Hi,

Below is one patch that contains all my previous patches, plus support
for libusb_poll() and libusb_abort().

Johannes:  If you want me to break these into multiple patches, let me know.

This compiles, but I don't have my USB equipment here to test with.
That's hopefully tomorrow.  In the meantime, I'm hoping someone with more
knowledge of the code that me will give me feedback on what I may have
done wrong.

Locking is likely a weak point.  Also, there was no support for tag
lookups, so I added that as a device operation, since io is OS-specific.
I don't know what Johannes had in mind for that.

Consider this pre-alpha code. :-)

- Chris

Index: linux.c
===================================================================
--- linux.c     (revision 640)
+++ linux.c     (working copy)
 <at>  <at>  -346,6 +346,54  <at>  <at> 
   return 0;
 }

+static struct usbi_io* linux_find_usbi_io(struct usbi_dev_handle *hdev, unsigned int tag)
+{
+  struct usbi_io *io;
+  list_for_each_entry(io, &hdev->ios, list) {
+    unsigned int iotag;
+    switch( io->type )
+    {
+    case USBI_IO_CONTROL:
+        iotag = io->ctrl.request->tag;
+        break;
+
+    case USBI_IO_INTERRUPT:
+        iotag = io->intr.request->tag;
+        break;
+
+    case USBI_IO_BULK:
+        iotag = io->bulk.request->tag;
+        break;
+
+    case USBI_IO_ISOCHRONOUS:
+        iotag = io->isoc.request->tag;
+        break;
+
+    default:
+        /* make sure it doesn't match */
+        iotag = ~tag;
+        break;
+    }
+
+    if( iotag == tag )
+      return io;
+  }
+  return 0;
+}
+
+static int linux_io_wait(struct usbi_dev_handle *hdev, unsigned int tag)
+{
+  struct usbi_io *io = hdev->idev->ops->find_usbi_io(hdev, tag);
+  if( !io ) {
+    pthread_mutex_lock(&io->lock);
+    if( io->inprogress )
+        pthread_cond_wait(&io->cond, &io->lock);
+    pthread_mutex_unlock(&io->lock);
+    return LIBUSB_SUCCESS;
+  }
+  return LIBUSB_UNKNOWN_TAG;
+}
+
 static void *poll_events(void *unused)
 {
   char filename[PATH_MAX + 1];
 <at>  <at>  -1019,7 +1067,9  <at>  <at> 
     .submit_intr               = linux_submit_intr,
     .submit_bulk               = linux_submit_bulk,
     .submit_isoc               = linux_submit_isoc,
+    .find_usbi_io              = linux_find_usbi_io,
     .io_cancel                 = linux_io_cancel,
+    .io_wait                   = linux_io_wait,
   },
 };

Index: usbi.h
===================================================================
--- usbi.h      (revision 640)
+++ usbi.h      (working copy)
 <at>  <at>  -256,7 +256,9  <at>  <at> 
   int (*submit_intr)(struct usbi_dev_handle *hdev, struct usbi_io *io);
   int (*submit_bulk)(struct usbi_dev_handle *hdev, struct usbi_io *io);
   int (*submit_isoc)(struct usbi_dev_handle *hdev, struct usbi_io *io);
+  struct usbi_io* (*find_usbi_io)(struct usbi_dev_handle *hdev, unsigned int tag);
   int (*io_cancel)(struct usbi_io *io);
+  int (*io_wait)(struct usbi_dev_handle *hdev, unsigned int tag);
 };

 struct usbi_backend_ops {
Index: api.c
===================================================================
--- api.c       (revision 640)
+++ api.c       (working copy)
 <at>  <at>  -107,3 +107,50  <at>  <at> 
   return hdev->idev->ops->detach_kernel_driver_np(hdev, interface);
 }

+int libusb_abort(libusb_dev_handle_t dev, unsigned int tag)
+{
+  struct usbi_dev_handle *hdev;
+
+  hdev = usbi_find_dev_handle(dev);
+  if (!hdev)
+    return LIBUSB_UNKNOWN_DEVICE;
+
+  struct usbi_io *io = hdev->idev->ops->find_usbi_io(hdev, tag);
+  if (!hdev)
+    return LIBUSB_UNKNOWN_TAG;
+
+  return hdev->idev->ops->io_cancel(io);
+}
+
+int libusb_wait(libusb_dev_handle_t dev, unsigned int tag)
+{
+  struct usbi_dev_handle *hdev;
+
+  hdev = usbi_find_dev_handle(dev);
+  if (!hdev)
+    return LIBUSB_UNKNOWN_DEVICE;
+
+  return hdev->idev->ops->io_wait(hdev, tag);
+}
+
+int libusb_poll(libusb_dev_handle_t dev, unsigned int num_tags,
+       unsigned int *tags, unsigned int *tag)
+{
+  struct usbi_dev_handle *hdev;
+  unsigned int i;
+
+  hdev = usbi_find_dev_handle(dev);
+  if (!hdev)
+    return LIBUSB_UNKNOWN_DEVICE;
+
+  for( i = 0; i < num_tags; i++ ) {
+    struct usbi_io *io = hdev->idev->ops->find_usbi_io(hdev, tags[i]);
+    if( io && !io->inprogress ) {
+      *tag = tags[i];
+      return LIBUSB_SUCCESS;
+    }
+  }
+
+  return LIBUSB_FAILURE;
+}
+
Index: libusb.h.in
===================================================================
--- libusb.h.in (revision 640)
+++ libusb.h.in (working copy)
 <at>  <at>  -183,6 +183,7  <at>  <at> 
 #define LIBUSB_NOACCESS                        -9      /* Access to device denied */
 #define LIBUSB_PARSE_ERROR             -10     /* Data could not be parsed */
 #define LIBUSB_UNKNOWN_DEVICE          -11     /* Device id is stale or invalid */
+#define LIBUSB_UNKNOWN_TAG             -12     /* Tag ID not found */

 #define LIBUSB_IO_STALL                        -50     /* Endpoint stalled */
 #define LIBUSB_IO_CRC_ERROR            -51     /* CRC error */
 <at>  <at>  -797,6 +798,7  <at>  <at> 
  *
  *   Arguments:
  *     usb_ctrl_req      - Pointer to USB control request
+ *                         request object must exist for the lifetime of IO
  *     residue           - transfer residue
  *     callback          - callback handler
  *     arg               - caller defined
 <at>  <at>  -839,6 +841,7  <at>  <at> 
  *   Arguments:
  *     libusb_intr_req   - Pointer to USB intr request
  *                              (EP direction determines R/W)
+ *                         request object must exist for the lifetime of IO
  *     residue           - transfer residue
  *     callback          - callback handler
  *     arg               - caller defined
 <at>  <at>  -880,6 +883,7  <at>  <at> 
  *   Arguments:
  *     libusb_bulk_req   -  Pointer to USB bulk request
  *                              (EP direction determines R/W)
+ *                         request object must exist for the lifetime of IO
  *     residue           - transfer residue
  *     callback          - callback handler
  *     arg               - caller defined
 <at>  <at>  -930,6 +934,7  <at>  <at> 
  *   Arguments:
  *     libusb_isoc_req   - Pointer to USB isoc request
  *                              (EP direction determines R/W)
+ *                         request object must exist for the lifetime of IO
  *     residue           - transfer residue
  *     callback          - callback handler
  *     arg               - caller defined
 <at>  <at>  -984,7 +989,7  <at>  <at> 
  *
  * NOT Implemented
  */
-int libusb_abort(unsigned int tag);
+int libusb_abort(libusb_dev_handle_t dev, unsigned int tag);

 /*
  * I/O Support:
 <at>  <at>  -1006,10 +1011,9  <at>  <at> 
  *
  * NOT Implemented
  */
-int libusb_wait(unsigned int num_tags, unsigned int *tags,
-       unsigned int *tag);
-int libusb_poll(unsigned int num_tags, unsigned int *tags,
-       unsigned int *tag);
+int libusb_wait(libusb_dev_handle_t dev, unsigned int tag);
+int libusb_poll(libusb_dev_handle_t dev, unsigned int num_tags,
+       unsigned int *tags, unsigned int *tag);

 #ifdef __cplusplus
 }
Index: async.c
===================================================================
--- async.c     (revision 640)
+++ async.c     (working copy)
 <at>  <at>  -93,19 +93,6  <at>  <at> 
 /* Helper routine. To be called from the various ports */
 void usbi_io_complete(struct usbi_io *io, int status, size_t transferred_bytes)
 {
-  pthread_mutex_lock(&io->lock);
-  io->inprogress = 0;
-  pthread_mutex_unlock(&io->lock);
-
-  /* Add completion for later retrieval */
-  pthread_mutex_lock(&completion_lock);
-  list_add(&io->list, &completions);
-  pthread_mutex_unlock(&completion_lock);
-
-  pthread_mutex_lock(&io->lock);
-  pthread_cond_broadcast(&io->cond);
-  pthread_mutex_unlock(&io->lock);
-
   switch (io->type) {
   case USBI_IO_CONTROL:
     io->ctrl.callback(io->ctrl.request, io->ctrl.arg, status, transferred_bytes);
 <at>  <at>  -120,6 +107,19  <at>  <at> 
     /* FIXME: Implement */
     break;
   }
+
+  pthread_mutex_lock(&io->lock);
+  io->inprogress = 0;
+  pthread_mutex_unlock(&io->lock);
+
+  /* Add completion for later retrieval */
+  pthread_mutex_lock(&completion_lock);
+  list_add(&io->list, &completions);
+  pthread_mutex_unlock(&completion_lock);
+
+  pthread_mutex_lock(&io->lock);
+  pthread_cond_broadcast(&io->cond);
+  pthread_mutex_unlock(&io->lock);
 }

 /*
Linus Walleij | 2 Jun 09:24 2006
Picon
Picon
Picon

Re: using /dev/bus/usb vs. /proc/bus/usb

On Thu, 1 Jun 2006, Eric Hawkins wrote:

> FC5 does use /proc/bus/usb, at least it gets mounted at boot and older
> libusb implementations default to using it.

Yes. Thr problem is that FC5 does not ship with the old hotplug scripts 
that are needed to change permissions on /proc/bus/usb when a device is 
plugged in.

FC5's idea of how to change permissions is to use PAM after creating 
device nodes using udev, as described previously.

Linus
Linus Walleij | 2 Jun 09:28 2006
Picon
Picon
Picon

Re: using /dev/bus/usb vs. /proc/bus/usb

On Thu, 1 Jun 2006, Tim Roberts wrote:

[answers as seen from my point of view]

> Perhaps someone can help me understand this little better.  I happen to
> be using a Ubuntu system, which uses /proc/bus/usb.  I naïvely thought
> this was the "latest and greatest" in USB support.

No that's actually old. The latest and greatest is to not even mount 
/proc/bus/usb and use udev exclusively to create device nodes under /dev 
(where they ought to be). However removing that is usually not wise for 
distributions.

> On those FC5
> systems, does /dev/bus/usb have the same functionality?

Yes it is supposed to be a 1-to-1 mapping of the stuff previously in 
/proc/bus/usb.

>  That is, is
> there a "devices" file, and files like "004/003" with a default driver
> that responds to the same ioctls that my /proc/bus/usb device responds to?

Yes.

> In summary, is that just "usbfs" but mounted at a different root?

No, it is not usbfs. It is ordinary device files, just created in a 
directory hierarchy under /dev that has the same layout as it used to 
have in /proc. There are even a few things /proc/bus/usb can do which 
/dev/bus/usb can't, but it's quite esoteric so I don't know the exact 
details...

Linus
Xiaofan Chen | 2 Jun 14:18 2006
Picon

Re: using /dev/bus/usb vs. /proc/bus/usb

On 6/1/06, Linus Walleij <triad <at> df.lth.se> wrote:
> On Wed, 31 May 2006, Eric Hawkins wrote:
>
> > I am using FC5 with libusb to interface to a scientific camera.  I have udev
> > and pam rules to configure the device node for the camera appropriately when
> > it is plugged in,
>
> Hi Eric, please read the attached file which I've sent around a bit.

The document is really very helpful. Could you please update it a bit
to include the followed PAM rules? It would be nice that you put
your name and the version of the documentation as well. Thanks.
I was sending this file to the pickit-devel group but I need to
search the archive to know that it is from you...

> FC5 does not use /proc/bus/usb but rather /dev/bus/usb for userspace
> access. Then as you say PAM to lift permissions for desktop access for
> example (in my experience 9 out of 10 libusb user wants this).
>
> Example:
>
> /etc/udev/rules.d/foo.rules:
> SUBSYSTEM=="usb_device", ACTION=="add" \
> SYSFS{idVendor}=="1234", SYSFS{idProduct}=="1234", SYMLINK+="foo-%k"
>
> /etc/security/console.perms.d/foo.perms:
> <foo>=/dev/foo*
> <console> 0600 <foo> 0600 root

Yes this works for me. You just solved my problem to get PICkit 2 (a
USB PIC MCU programmer from Microchip) to work under Linux without
being root. Thanks a lot!

Under Ubuntu Breezy and FC4, I use hotplug scripts but that does not
work with FC5.

Regards,
XIaofan
Graeme Gill | 2 Jun 16:29 2006

Re: using /dev/bus/usb vs. /proc/bus/usb

Xiaofan Chen wrote:

>>/etc/udev/rules.d/foo.rules:
>>SUBSYSTEM=="usb_device", ACTION=="add" \
>>SYSFS{idVendor}=="1234", SYSFS{idProduct}=="1234", SYMLINK+="foo-%k"

I tried this sort of thing on my Whitebox Linux (a Redhat clone),
and it barfed on things like "==". I don't think "Action=" was
valid either. Whether this is an older or newer version of udev
I don't know, and even after correcting the syntax errors, it
still didn't work, possibly due to a bug in udev. My conclusion
was that Linux udev seems to be rather unstable.
Luckily the system supports hotplug, which worked
as advertised..

Graeme GIll.

Gmane