~ubuntu-branches/ubuntu/precise/virtualbox/precise-updates

« back to all changes in this revision

Viewing changes to src/VBox/Main/src-server/linux/USBGetDevices.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-07-04 13:02:31 UTC
  • mfrom: (3.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20110704130231-l843es6wqhx614n7
Tags: 4.0.10-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Add the Modaliases control field manually for maximum backportability.

Show diffs side-by-side

added added

removed removed

Lines of Context:
824
824
 
825
825
#define USBDEVICE_MAJOR 189
826
826
 
827
 
/** Deduce the bus that a USB device is plugged into from the device node
828
 
 * number.  See drivers/usb/core/hub.c:usb_new_device as of Linux 2.6.20. */
829
 
static unsigned usbBusFromDevNum(dev_t devNum)
830
 
{
831
 
    AssertReturn(devNum, 0);
832
 
    AssertReturn(major(devNum) == USBDEVICE_MAJOR, 0);
833
 
    return (minor(devNum) >> 7) + 1;
834
 
}
835
 
 
836
 
 
837
 
/** Deduce the device number of a USB device on the bus from the device node
838
 
 * number.  See drivers/usb/core/hub.c:usb_new_device as of Linux 2.6.20. */
839
 
static unsigned usbDeviceFromDevNum(dev_t devNum)
840
 
{
841
 
    AssertReturn(devNum, 0);
842
 
    AssertReturn(major(devNum) == USBDEVICE_MAJOR, 0);
843
 
    return (minor(devNum) & 127) + 1;
844
 
}
845
 
 
 
827
/** Calculate the bus (a.k.a root hub) number of a USB device from it's sysfs
 
828
 * path.  sysfs nodes representing root hubs have file names of the form
 
829
 * usb<n>, where n is the bus number; other devices start with that number.
 
830
 * See [http://www.linux-usb.org/FAQ.html#i6] and
 
831
 * [http://www.kernel.org/doc/Documentation/usb/proc_usb_info.txt] for
 
832
 * equivalent information about usbfs.
 
833
 * @returns a bus number greater than 0 on success or 0 on failure.
 
834
 */
 
835
static unsigned usbGetBusFromSysfsPath(const char *pcszPath)
 
836
{
 
837
    const char *pcszFile = strrchr(pcszPath, '/');
 
838
    if (!pcszFile)
 
839
        return 0;
 
840
    unsigned bus = RTStrToUInt32(pcszFile + 1);
 
841
    if (   !bus
 
842
        && pcszFile[1] == 'u' && pcszFile[2] == 's' && pcszFile[3] == 'b')
 
843
    bus = RTStrToUInt32(pcszFile + 4);
 
844
    return bus;
 
845
}
 
846
 
 
847
/** Calculate the device number of a USB device.  See
 
848
 * drivers/usb/core/hub.c:usb_new_device as of Linux 2.6.20. */
 
849
static dev_t usbMakeDevNum(unsigned bus, unsigned device)
 
850
{
 
851
    AssertReturn(bus > 0, 0);
 
852
    AssertReturn(((device - 1) & ~127) == 0, 0);
 
853
    AssertReturn(device > 0, 0);
 
854
    return makedev(USBDEVICE_MAJOR, ((bus - 1) << 7) + device - 1);
 
855
}
846
856
 
847
857
/**
848
858
 * If a file @a pcszNode from /sys/bus/usb/devices is a device rather than an
853
863
                       VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo)
854
864
{
855
865
    const char *pcszFile = strrchr(pcszNode, '/');
 
866
    if (!pcszFile)
 
867
        return VERR_INVALID_PARAMETER;
856
868
    if (strchr(pcszFile, ':'))
857
869
        return VINF_SUCCESS;
858
 
    dev_t devnum = RTLinuxSysFsReadDevNumFile("%s/dev", pcszNode);
859
 
    /* Sanity test of our static helpers */
860
 
    Assert(usbBusFromDevNum(makedev(USBDEVICE_MAJOR, 517)) == 5);
861
 
    Assert(usbDeviceFromDevNum(makedev(USBDEVICE_MAJOR, 517)) == 6);
 
870
    unsigned bus = usbGetBusFromSysfsPath(pcszNode);
 
871
    if (!bus)
 
872
        return VINF_SUCCESS;
 
873
    unsigned device = RTLinuxSysFsReadIntFile(10, "%s/devnum", pcszNode);
 
874
    dev_t devnum = usbMakeDevNum(bus, device);
862
875
    if (!devnum)
863
876
        return VINF_SUCCESS;
864
877
    char szDevPath[RTPATH_MAX];
866
879
    cchDevPath = RTLinuxFindDevicePath(devnum, RTFS_TYPE_DEV_CHAR,
867
880
                                       szDevPath, sizeof(szDevPath),
868
881
                                       "%s/%.3d/%.3d",
869
 
                                       pcszDevicesRoot,
870
 
                                       usbBusFromDevNum(devnum),
871
 
                                       usbDeviceFromDevNum(devnum));
 
882
                                       pcszDevicesRoot, bus, device);
872
883
    if (cchDevPath < 0)
873
884
        return VINF_SUCCESS;
874
885
 
1225
1236
 
1226
1237
    /* Fill in the simple fields */
1227
1238
    Dev->enmState           = USBDEVICESTATE_UNUSED;
1228
 
    Dev->bBus               = RTLinuxSysFsReadIntFile(10, "%s/busnum", pszSysfsPath);
 
1239
    Dev->bBus               = usbGetBusFromSysfsPath(pszSysfsPath);
1229
1240
    Dev->bDeviceClass       = RTLinuxSysFsReadIntFile(16, "%s/bDeviceClass", pszSysfsPath);
1230
1241
    Dev->bDeviceSubClass    = RTLinuxSysFsReadIntFile(16, "%s/bDeviceSubClass", pszSysfsPath);
1231
1242
    Dev->bDeviceProtocol    = RTLinuxSysFsReadIntFile(16, "%s/bDeviceProtocol", pszSysfsPath);