Am Tue, 27 Jan 2009 10:56:35 -0200
schrieb Mauro Carvalho Chehab <mche...@infradead.org>:

> On Thu, 22 Jan 2009 22:12:08 +0100
> Thierry Merle <thierry.me...@free.fr> wrote:
> 
> > Laurent Pinchart a écrit :
> > > On Thursday 22 January 2009, Carsten Meier wrote:
> > >> Am Thu, 22 Jan 2009 00:20:00 +0100
> > >>
> > >> schrieb Laurent Pinchart <laurent.pinch...@skynet.be>:
> > >>> Hi Carsten,
> > >>>
> > >>> On Wednesday 21 January 2009, Carsten Meier wrote:
> > >>>> now I want to translate bus_info into a sysfs-path to obtain
> > >>>> device-info like serial numbers. Given a device reports
> > >>>> "usb-0000:00:1d.2-2" as bus_info, then the device-info is
> > >>>> located under "/sys/bus/usb/devices/2-2", which is a symlink
> > >>>> to the appropriate /sys/devices/ directory, right?
> > >>> I'm afraid not. In the above bus_info value, 0000:00:1d.2 is
> > >>> the PCI bus path of your USB controller, and the last digit
> > >>> after the dash is the USB device path.
> > >>>
> > >>>> All I have to do is to compare the first 4 chars of bus_info
> > >>>> against "usb-", get the chars after "." and append it to
> > >>>> "/sys/bus/usb/devices/" to obatin a sysfs-path, right?
> > >>>>
> > >>>> Is there a more elegant solution or already a function for
> > >>>> this? Can the "." appear more than once before the last one?
> > >>> Probably not before, but definitely after.
> > >>>
> > >>> Root hubs get a USB device path set to '0'. Every other device
> > >>> is numbered according to the hub port number it is connected
> > >>> to. If you have an external hub connected on port 2 of your
> > >>> root hub, and have a webcam connected to port 3 of the external
> > >>> hub, usb_make_path() will return "usb-0000:00:1d.2-2.3".
> > >>>
> > >>> Cheers,
> > >>>
> > >>> Laurent Pinchart
> > >> Hi,
> > >>
> > >> On my machine, my pvrusb2 (connected directly to my mini-pc)
> > >> shows up under "/sys/bus/usb/devices/7-2/" which is a symbolic
> > >> link to "../../../devices/pci0000:00/0000:00:1d.7/usb7/7-2"
> > > 
> > > You're just lucky that USB bus 7 (usb7/7) is connected to the 7th
> > > function of your USB host controller (1d.7).
> > > 
> > > Here's an example of what I get on my computer:
> > > 
> > > /sys/bus/usb/devices/4-2
> > > -> ../../../devices/pci0000:00/0000:00:1d.2/usb4/4-2
> > > 
> > >> I can't test for the new bus_info-string, because it's not fixed
> > >> yet in the driver. But if I got it correctly it should be
> > >> "usb-0000:00:1d.7-7.2" ?
> > > 
> > > I think you will get usb-0000:00:1d.7-2
> > > 
> > >> Then I've to simply take the string after the last dash, replace
> > >> "." by "-" and append it to "/sys/bus/usb/devices/" for a
> > >> sysfs-path?
> > > 
> > > Unfortunately the mapping is not that direct. The part before the
> > > last dash identifies the USB host controller. The part after the
> > > last dash identifies the device path related to the controller,
> > > expressed as a combination of port numbers.
> > > 
> > > The sysfs device path /sys/bus/usb/devices/7-2/ includes a USB
> > > bus number (in this case 7) that is not present in
> > > usb_make_path()'s output.
> > > 
> > > To find the sysfs path of your USB peripheral, you will have to
> > > find out which bus number the bus name (0000:00:1d.7) corresponds
> > > to. You might be able to find that by checking each usb[0-9]+
> > > links in /sys/bus/usb/devices and comparing the link's target
> > > with the bus name.
> > > 
> > To ease this processing, using libsysfs can be a good idea...
> > On my system, the documentation of libsysfs is here:
> > /usr/doc/sysfsutils-2.1.0/libsysfs.txt
> > Knowing the bus-id, it won't be hard to look at it in data
> > structures. Just my 2 cents.
> 
> Hi Thierry,
> 
> It may be a good idea to add some code at the v4l2-apps dir for
> retrieving the sysfs place. Maybe we may add it at qv4l2 and at
> v4l2-ctl.
> 
> Cheers,
> Mauro

Hi,

here is code which I've written for it. It is in C++ with Boost, but
adaption to C shouldn't be hard. It's not extensively tested and put
into the public domain.




#include <stdexcept>
#include <string>
#include <boost/lexical_cast.hpp>
#include <cstdio>

extern "C" {
#include <sysfs/libsysfs.h>
}


bool obtain_usb_sysfs_path(
        const char *busname, const char *usbpath, string &sysfspath_out)
{
        bool rc = false;

        ::sysfs_device *usbctl = NULL;
        ::sysfs_bus *usb = NULL;
        try
        {
                // open usb host controller

                usbctl = ::sysfs_open_device("pci", busname);
                if(!usbctl)
                        throw runtime_error(
                                "Unable to open usb host controller");

                // find matching usb bus

                usb = ::sysfs_open_bus("usb");
                if(!usb)
                        throw runtime_error("Unable to open usb");

                ::dlist *usbdevs = ::sysfs_get_bus_devices(usb);
                if(!usbdevs)
                        throw runtime_error("Unable to get usb devices");

                ::sysfs_device *usbdev = NULL;
                dlist_for_each_data(
                        usbdevs, usbdev, struct sysfs_device)
                {
                        // compare pathes of usb host controller and
                        // parent of enumerated usb devices

                        ::sysfs_device *pdev =
                                ::sysfs_get_device_parent(usbdev);
                        if(!pdev)
                                continue;

                        if(strcmp(usbctl->path, pdev->path) == 0)
                                break;
                }

                ::sysfs_close_device(usbctl);
                usbctl = NULL;

                // assemble usb device path

                if(usbdev)
                {
                        ::sysfs_attribute *busnumattr =
                                ::sysfs_get_device_attr(usbdev, "busnum");
                        if(!busnumattr)
                                throw runtime_error(
                                        "Unable to get usb bus number");

                        string str(busnumattr->value, busnumattr->len);
                        unsigned int busnum;
                        if(sscanf(str.c_str(), "%u", &busnum) != 1)
                                throw runtime_error(
                                        "Unable to parse usb bus number");
                        
                        sysfspath_out = usbdev->path;
                        sysfspath_out += '/';
                        sysfspath_out += lexical_cast<string>(busnum);
                        sysfspath_out += '-';
                        sysfspath_out += usbpath;
                        rc = true;
                }

                ::sysfs_close_bus(usb);
                usb = NULL;
        }
        catch(...)
        {
                if(usb)
                        ::sysfs_close_bus(usb);
                if(usbctl)
                        ::sysfs_close_device(usbctl);
                throw;
        }

        return rc;
}




Maybe it is of use for one or another.

Cheers,
Carsten
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to