[PATCH] Fix build on FreeBSD 8.0+.
Raphael Kubo da Costa
kubito at gmail.com
Sun Oct 4 07:40:32 CEST 2009
Version 8.0 of FreeBSD got a completely reworked USB stack, which means
the old code previously present in usbdevice.cpp doesn't work anymore.
That legacy code (which isn't legacy in NetBSD ;) has been moved to
usbdevices_bsd.cpp, and code supporting FreeBSD 8.0 has been put in
usbdevices_freebsd8.cpp.
The code for FreeBSD 8.0 was based on a patch by Dima Panov originally
written by Hans Petter Selasky.
CCMAIL: kde-freebsd at kde.org
---
CMakeLists.txt | 15 ++++-
usbdevices.cpp | 121 +------------------------------------
usbdevices.h | 17 +++++-
usbdevices_bsd.cpp | 155 +++++++++++++++++++++++++++++++++++++++++++++++
usbdevices_freebsd8.cpp | 112 ++++++++++++++++++++++++++++++++++
5 files changed, 297 insertions(+), 123 deletions(-)
create mode 100644 usbdevices_bsd.cpp
create mode 100644 usbdevices_freebsd8.cpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 87bb256..a04ec8c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,12 +5,23 @@
set(kcm_usb_PART_SRCS kcmusb.cpp usbdevices.cpp usbdb.cpp )
-
kde4_add_plugin(kcm_usb ${kcm_usb_PART_SRCS})
-
target_link_libraries(kcm_usb ${KDE4_KDEUI_LIBS} ${QT_QTGUI_LIBRARY})
+if (Q_OS_FREEBSD OR Q_OS_NETBSD)
+ include(CheckSymbolExists)
+
+ check_symbol_exists(__FreeBSD_version "sys/param.h" FREEBSD_VERSION)
+
+ if (FREEBSD_VERSION less 800100)
+ set(kcm_usb_PART_SRCS ${kcm_usb_PART_SRCS} usbdevices_bsd.cpp)
+ else (FREEBSD_VERSION)
+ set(kcm_usb_PART_SRCS ${kcm_usb_PART_SRCS} usbdevices_freebsd8.cpp)
+ target_link_libraries(kcm_usb -lusb)
+ endif (FREEBSD_VERSION)
+endif (Q_OS_FREEBSD OR Q_OS_NETBSD)
+
install(TARGETS kcm_usb DESTINATION ${PLUGIN_INSTALL_DIR} )
diff --git a/usbdevices.cpp b/usbdevices.cpp
index 07889c6..e3e52a3 100644
--- a/usbdevices.cpp
+++ b/usbdevices.cpp
@@ -27,11 +27,6 @@
#include <math.h>
-#if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#endif
-
QList<USBDevice*> USBDevice::_devices;
USBDB *USBDevice::_db;
@@ -290,118 +285,4 @@ bool USBDevice::parseSys(const QString &dname) {
return d.count();
}
-#else
-
-/*
- * FreeBSD support by Markus Brueffer <markus at brueffer.de>
- *
- * Basic idea and some code fragments were taken from FreeBSD's usbdevs(8),
- * originally developed for NetBSD, so this code should work with no or
- * only little modification on NetBSD.
- */
-
-void USBDevice::collectData( int fd, int level, usb_device_info &di, int parent)
-{
- // determine data for this device
- _level = level;
- _parent = parent;
-
- _bus = di.udi_bus;
- _device = di.udi_addr;
- _product = QLatin1String(di.udi_product);
- if ( _device == 1 )
- _product += ' ' + QString::number( _bus );
- _manufacturer = QLatin1String(di.udi_vendor);
- _prodID = di.udi_productNo;
- _vendorID = di.udi_vendorNo;
- _class = di.udi_class;
- _sub = di.udi_subclass;
- _prot = di.udi_protocol;
- _power = di.udi_power;
- _channels = di.udi_nports;
-
- // determine the speed
-#if defined(__DragonFly__) || (defined(Q_OS_FREEBSD) && __FreeBSD_version > 490102) || defined(Q_OS_NETBSD)
- switch (di.udi_speed) {
- case USB_SPEED_LOW: _speed = 1.5; break;
- case USB_SPEED_FULL: _speed = 12.0; break;
- case USB_SPEED_HIGH: _speed = 480.0; break;
- }
-#else
- _speed = di.udi_lowspeed ? 1.5 : 12.0;
-#endif
-
- // Get all attached devicenodes
- for ( int i = 0; i < USB_MAX_DEVNAMES; ++i )
- if ( di.udi_devnames[i][0] )
- _devnodes << di.udi_devnames[i];
-
- // For compatibility, split the revision number
- sscanf( di.udi_release, "%x.%x", &_revMajor, &_revMinor );
-
- // Cycle through the attached devices if there are any
- for ( int p = 0; p < di.udi_nports; ++p ) {
- // Get data for device
- struct usb_device_info di2;
-
- di2.udi_addr = di.udi_ports[p];
-
- if ( di2.udi_addr >= USB_MAX_DEVICES )
- continue;
-
- if ( ioctl(fd, USB_DEVICEINFO, &di2) == -1 )
- continue;
-
- // Only add the device if we didn't detect it, yet
- if (!find( di2.udi_bus, di2.udi_addr ) )
- {
- USBDevice *device = new USBDevice();
- device->collectData( fd, level + 1, di2, di.udi_addr );
- }
- }
-}
-
-bool USBDevice::parse(const QString &fname)
-{
- static bool showErrorMessage = true;
- bool error = false;
- _devices.clear();
-
- QFile controller("/dev/usb0");
- int i = 1;
- while ( controller.exists() )
- {
- // If the devicenode exists, continue with further inspection
- if ( controller.open(QIODevice::ReadOnly) )
- {
- for ( int addr = 1; addr < USB_MAX_DEVICES; ++addr )
- {
- struct usb_device_info di;
-
- di.udi_addr = addr;
- if ( ioctl(controller.handle(), USB_DEVICEINFO, &di) != -1 )
- {
- if (!find( di.udi_bus, di.udi_addr ) )
- {
- USBDevice *device = new USBDevice();
- device->collectData( controller.handle(), 0, di, 0);
- }
- }
- }
- controller.close();
-#ifndef Q_OS_NETBSD
- } else {
- error = true;
-#endif
- }
- controller.setFileName( QString::fromLocal8Bit("/dev/usb%1").arg(i++) );
- }
-
- if ( showErrorMessage && error ) {
- showErrorMessage = false;
- KMessageBox::error( 0, i18n("Could not open one or more USB controller. Make sure, you have read access to all USB controllers that should be listed here."));
- }
-
- return true;
-}
-#endif
+#endif // !(defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD))
diff --git a/usbdevices.h b/usbdevices.h
index 61e3980..f125c54 100644
--- a/usbdevices.h
+++ b/usbdevices.h
@@ -18,7 +18,18 @@
#include <bus/usb/usb.h>
#include <QStringList>
#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
-#include <dev/usb/usb.h>
+#include <sys/param.h>
+# if defined(Q_OS_FREEBSD) && __FreeBSD_version >= 800090
+# include <libusb20.h>
+# include <dev/usb/usb_ioctl.h>
+# if __FreeBSD_version >= 800100
+# include <dev/usb/usbdi.h>
+# else
+# include <dev/usb/usb_revision.h>
+# endif
+# else
+# include <dev/usb/usb.h>
+# endif
#include <QStringList>
#endif
@@ -77,7 +88,11 @@ private:
unsigned int _vendorID, _prodID, _revMajor, _revMinor;
#if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
+# if defined(Q_OS_FREEBSD) && __FreeBSD_version >= 800090
+ void collectData( struct libusb20_backend *pbe, struct libusb20_backend *pbdev );
+# else
void collectData( int fd, int level, usb_device_info &di, int parent );
+# endif
QStringList _devnodes;
#endif
};
diff --git a/usbdevices_bsd.cpp b/usbdevices_bsd.cpp
new file mode 100644
index 0000000..7549909
--- /dev/null
+++ b/usbdevices_bsd.cpp
@@ -0,0 +1,155 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2009 Raphael Kubo da Costa <kubito at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+/*
+ * usbdevices_bsd.cpp
+ *
+ * This file implements {DragonFly,FreeBSD,NetBSD}-specific code.
+ *
+ * More specifically, it is used only by FreeBSD versions earlier
+ * than 8.0, which has a completely reworked USB stack code, whereas
+ * previously it had borrowed its code from NetBSD.
+ *
+ * For FreeBSD 8.0+ code, see usbdevices_bsd8.cpp
+ */
+
+/*
+ * FreeBSD support by Markus Brueffer <markus at brueffer.de>
+ *
+ * Basic idea and some code fragments were taken from FreeBSD's usbdevs(8),
+ * originally developed for NetBSD, so this code should work with no or
+ * only little modification on NetBSD.
+ */
+
+#include "usbdevice.h"
+
+#include <stdio.h>
+
+#include <sys/ioctl.h>
+#include <sys/param.h>
+
+#include <qfile.h>
+
+#include <kmessagebox.h>
+
+void USBDevice::collectData( int fd, int level, usb_device_info &di, int parent)
+{
+ // determine data for this device
+ _level = level;
+ _parent = parent;
+
+ _bus = di.udi_bus;
+ _device = di.udi_addr;
+ _product = QLatin1String(di.udi_product);
+ if ( _device == 1 )
+ _product += ' ' + QString::number( _bus );
+ _manufacturer = QLatin1String(di.udi_vendor);
+ _prodID = di.udi_productNo;
+ _vendorID = di.udi_vendorNo;
+ _class = di.udi_class;
+ _sub = di.udi_subclass;
+ _prot = di.udi_protocol;
+ _power = di.udi_power;
+ _channels = di.udi_nports;
+
+ // determine the speed
+#if defined(__DragonFly__) || (defined(Q_OS_FREEBSD) && __FreeBSD_version > 490102) || defined(Q_OS_NETBSD)
+ switch (di.udi_speed) {
+ case USB_SPEED_LOW: _speed = 1.5; break;
+ case USB_SPEED_FULL: _speed = 12.0; break;
+ case USB_SPEED_HIGH: _speed = 480.0; break;
+ }
+#else
+ _speed = di.udi_lowspeed ? 1.5 : 12.0;
+#endif
+
+ // Get all attached devicenodes
+ for ( int i = 0; i < USB_MAX_DEVNAMES; ++i )
+ if ( di.udi_devnames[i][0] )
+ _devnodes << di.udi_devnames[i];
+
+ // For compatibility, split the revision number
+ sscanf( di.udi_release, "%x.%x", &_revMajor, &_revMinor );
+
+ // Cycle through the attached devices if there are any
+ for ( int p = 0; p < di.udi_nports; ++p ) {
+ // Get data for device
+ struct usb_device_info di2;
+
+ di2.udi_addr = di.udi_ports[p];
+
+ if ( di2.udi_addr >= USB_MAX_DEVICES )
+ continue;
+
+ if ( ioctl(fd, USB_DEVICEINFO, &di2) == -1 )
+ continue;
+
+ // Only add the device if we didn't detect it, yet
+ if (!find( di2.udi_bus, di2.udi_addr ) )
+ {
+ USBDevice *device = new USBDevice();
+ device->collectData( fd, level + 1, di2, di.udi_addr );
+ }
+ }
+}
+
+bool USBDevice::parse(const QString &fname)
+{
+ static bool showErrorMessage = true;
+ bool error = false;
+ _devices.clear();
+
+ QFile controller("/dev/usb0");
+ int i = 1;
+ while ( controller.exists() )
+ {
+ // If the devicenode exists, continue with further inspection
+ if ( controller.open(QIODevice::ReadOnly) )
+ {
+ for ( int addr = 1; addr < USB_MAX_DEVICES; ++addr )
+ {
+ struct usb_device_info di;
+
+ di.udi_addr = addr;
+ if ( ioctl(controller.handle(), USB_DEVICEINFO, &di) != -1 )
+ {
+ if (!find( di.udi_bus, di.udi_addr ) )
+ {
+ USBDevice *device = new USBDevice();
+ device->collectData( controller.handle(), 0, di, 0);
+ }
+ }
+ }
+ controller.close();
+#ifndef Q_OS_NETBSD
+ } else {
+ error = true;
+#endif
+ }
+ controller.setFileName( QString::fromLocal8Bit("/dev/usb%1").arg(i++) );
+ }
+
+ if ( showErrorMessage && error ) {
+ showErrorMessage = false;
+ KMessageBox::error( 0, i18n("Could not open one or more USB controller. Make sure, you have read access to all USB controllers that should be listed here."));
+ }
+
+ return true;
+}
diff --git a/usbdevices_freebsd8.cpp b/usbdevices_freebsd8.cpp
new file mode 100644
index 0000000..4a95f11
--- /dev/null
+++ b/usbdevices_freebsd8.cpp
@@ -0,0 +1,112 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2009 Raphael Kubo da Costa <kubito at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+/*
+ * usbdevices_freebsd8.cpp
+ *
+ * This file implements code specific to FreeBSD 8.0+.
+ *
+ * From 8.0 on, the USB stack code was reworked, so the previous
+ * code (usbdevices_bsd.cpp) doesn't work anymore.
+ *
+ * Based on a FreeBSD area51 patch by Dima Panov <Fluffy at fluffy.khv.ru>
+ * originally written by Hans Petter Selasky <hselasky at freebsd.org>
+ */
+
+#include "usbdevice.h"
+
+#include <stdio.h>
+
+#include <sys/ioctl.h>
+#include <sys/param.h>
+
+void USBDevice::collectData(struct libusb20_backend *pbe,
+ struct libusb20_device *pdev)
+{
+ struct usb_device_info di;
+ if (libusb20_dev_get_info(pdev, &di))
+ memset(&di, 0, sizeof(di));
+ else
+ return;
+
+ // determine data for this device
+ _level = 0;
+ _parent = 0;
+
+ _bus = di.udi_bus;
+ _device = di.udi_addr;
+ _product = QLatin1String(di.udi_product);
+ if ( _device == 1 )
+ _product += ' ' + QString::number( _bus );
+ _manufacturer = QLatin1String(di.udi_vendor);
+ _prodID = di.udi_productNo;
+ _vendorID = di.udi_vendorNo;
+ _class = di.udi_class;
+ _sub = di.udi_subclass;
+ _prot = di.udi_protocol;
+ _power = di.udi_power;
+ _channels = di.udi_nports;
+
+ switch (di.udi_speed) {
+ case USB_SPEED_LOW: _speed = 1.5; break;
+ case USB_SPEED_FULL: _speed = 12.0; break;
+ case USB_SPEED_HIGH: _speed = 480.0; break;
+ case USB_SPEED_VARIABLE: _speed = 480.0; break;
+ case USB_SPEED_SUPER: _speed = 4800.0; break;
+ default: _speed = 480.0; break;
+ }
+
+ char tempbuf[32];
+
+ // Get all attached devicenodes
+ for ( int i = 0; i < 32; ++i ) {
+ if (libusb20_dev_get_iface_desc(
+ pdev, i, tempbuf, sizeof(tempbuf)) == 0) {
+ _devnodes << tempbuf;
+ } else {
+ break;
+ }
+ }
+
+ // For compatibility, split the revision number
+ sscanf(di.udi_release, "%x.%x", &_revMajor, &_revMinor);
+}
+
+bool USBDevice::parse(const QString &fname)
+{
+ struct libusb20_backend *pbe;
+ struct libusb20_device *pdev;
+ _devices.clear();
+
+ pbe = libusb20_be_alloc_default();
+ if (pbe == NULL)
+ return false;
+
+ pdev = NULL;
+
+ while ((pdev = libusb20_be_device_foreach(pbe, pdev))) {
+ USBDevice *device = new USBDevice();
+ device->collectData(pbe, pdev);
+ }
+
+ libusb20_be_free(pbe);
+
+ return true;
+}
--
1.6.4.4
--MP_/jbz9HWI2VbfZFUDgSW8.RhP--
More information about the kde-freebsd
mailing list