[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