summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Kukawka <danny.kukawka@web.de>2009-09-22 11:19:55 +0200
committerDanny Kukawka <danny.kukawka@web.de>2009-09-22 11:19:55 +0200
commit4f4ccbdd31edd14bd328d3cefc2fb906223202e1 (patch)
tree090af12bcc8c592c882050fbb1f9a1c9d65a1d30
parent74bf2659a02c5c0cf96121a8d58f0ee530fe9599 (diff)
parent2e5eed0af0761ab6f7a15659ec1efa1f66ef1ea8 (diff)
downloadhal-4f4ccbdd31edd14bd328d3cefc2fb906223202e1.tar.gz
Merge branch 'master' of ssh://dkukawka@git.freedesktop.org/git/hal
-rw-r--r--configure.in32
-rw-r--r--hald/freebsd/Makefile.am7
-rw-r--r--hald/freebsd/addons/Makefile.am10
-rw-r--r--hald/freebsd/addons/addon-mouse.c371
-rw-r--r--hald/freebsd/addons/addon-storage.c246
-rw-r--r--hald/freebsd/hf-acpi.c40
-rw-r--r--hald/freebsd/hf-computer.c9
-rw-r--r--hald/freebsd/hf-devd.c17
-rw-r--r--hald/freebsd/hf-devtree.c39
-rw-r--r--hald/freebsd/hf-scsi.c2
-rw-r--r--hald/freebsd/hf-storage.c96
-rw-r--r--hald/freebsd/hf-storage.h2
-rw-r--r--hald/freebsd/hf-usb.c122
-rw-r--r--hald/freebsd/hf-usb.h3
-rw-r--r--hald/freebsd/hf-usb2.c287
-rw-r--r--hald/freebsd/hf-usb2.h37
-rw-r--r--hald/freebsd/hf-util.c25
-rw-r--r--hald/freebsd/hf-util.h3
-rw-r--r--hald/freebsd/hf-volume.c72
-rw-r--r--hald/freebsd/libprobe/hfp.c32
-rw-r--r--hald/freebsd/libprobe/hfp.h14
-rw-r--r--hald/freebsd/osspec.c9
-rw-r--r--hald/freebsd/probing/Makefile.am35
-rw-r--r--hald/freebsd/probing/probe-hiddev.c26
-rw-r--r--hald/freebsd/probing/probe-mouse.c312
-rw-r--r--hald/freebsd/probing/probe-storage.c23
-rw-r--r--hald/freebsd/probing/probe-usb2-device.c208
-rw-r--r--hald/freebsd/probing/probe-usb2-interface.c140
-rw-r--r--hald/freebsd/probing/probe-volume.c50
-rw-r--r--hald/hald.c23
30 files changed, 2105 insertions, 187 deletions
diff --git a/configure.in b/configure.in
index 2e947a7a..e8aa021e 100644
--- a/configure.in
+++ b/configure.in
@@ -15,6 +15,7 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
glib_module="glib-2.0 >= 2.10.0 gobject-2.0 > 2.10.0 dbus-glib-1 >= 0.61"
dbus_module="dbus-1 >= 0.61"
blkid_module="blkid >= 2.15"
+volume_id_module="libvolume_id >= 0.77"
polkit_module="polkit >= 0.5"
# libtool versioning - this applies to libhal and libhal-storage
@@ -478,6 +479,9 @@ if test "x$with_libpci" != xno ; then
fi
AM_CONDITIONAL([HAVE_LIBPCI], [test "x$USE_LIBPCI" = "xyes"])
+USE_LIBUSB20=no
+USE_LIBUSB=no
+LIBUSB20_LIBS=""
AC_ARG_WITH([backend],
AS_HELP_STRING([--with-backend=<name>],
[backend to use (linux/solaris/freebsd/dummy)]),
@@ -505,6 +509,22 @@ AM_CONDITIONAL(HALD_COMPILE_LINUX, [test x$HALD_BACKEND = xlinux], [Compiling fo
AM_CONDITIONAL(HALD_COMPILE_FREEBSD, [test x$HALD_BACKEND = xfreebsd], [Compiling for FreeBSD])
AM_CONDITIONAL(HALD_COMPILE_SOLARIS, [test x$HALD_BACKEND = xsolaris], [Compiling for Solaris])
AC_SUBST(HALD_BACKEND)
+if test "x$HALD_BACKEND" = "xfreebsd"; then
+ AC_CHECK_LIB([usb20], [libusb20_dev_get_info], [USE_LIBUSB20=yes], [USE_LIBUSB20=no])
+fi
+if test "x$USE_LIBUSB20" = "xno"; then
+ AC_CHECK_LIB([usb], [libusb20_dev_get_info], [USE_LIBUSB=yes], [USE_LIBUSB=no])
+fi
+AM_CONDITIONAL([HAVE_LIBUSB20],[test "x$USE_LIBUSB20" = "xyes"])
+AM_CONDITIONAL([HAVE_LIBUSB20],[test "x$USE_LIBUSB" = "xyes"])
+if test "x$USE_LIBUSB20" = "xyes"; then
+ AC_DEFINE(HAVE_LIBUSB20, 1, [Set if we need libusb20])
+ LIBUSB20_LIBS="-lusb20"
+elif test "x$USE_LIBUSB" = "xyes"; then
+ AC_DEFINE(HAVE_LIBUSB20, 1, [Set if we need libsub20])
+ LIBUSB20_LIBS="-lusb"
+fi
+AC_SUBST(LIBUSB20_LIBS)
dnl DBUS API is subject to changes
AC_DEFINE_UNQUOTED(DBUS_API_SUBJECT_TO_CHANGE, [], [DBUS API is subject to change])
@@ -686,8 +706,20 @@ else
fi
AC_MSG_RESULT($have_glib_2_14)
+case "$host" in
+ *-*-freebsd*)
+ PKG_CHECK_MODULES(VOLUME_ID, [$volume_id_module])
+ AC_SUBST(VOLUME_ID_CFLAGS)
+ AC_SUBST(VOLUME_ID_LIBS)
+ ;;
+ *)
+ ;;
+esac
+
# blkid (util-linux-ng)
case "$host" in
+*-*-freebsd*)
+ ;;
*-*-solaris*)
;;
*)
diff --git a/hald/freebsd/Makefile.am b/hald/freebsd/Makefile.am
index 95d40d46..d3aff6e9 100644
--- a/hald/freebsd/Makefile.am
+++ b/hald/freebsd/Makefile.am
@@ -54,4 +54,11 @@ libhald_freebsd_la_SOURCES = \
libhald_freebsd_la_LDFLAGS = -lcam
+if HAVE_LIBUSB20
+libhald_freebsd_la_SOURCES += \
+ hf-usb2.c \
+ hf-usb2.h
+libhald_freebsd_la_LDFLAGS += @LIBUSB20_LIBS@
+endif
+
EXTRA_DIST = README TODO
diff --git a/hald/freebsd/addons/Makefile.am b/hald/freebsd/addons/Makefile.am
index 25cf0df1..c2a68ba0 100644
--- a/hald/freebsd/addons/Makefile.am
+++ b/hald/freebsd/addons/Makefile.am
@@ -8,9 +8,17 @@ AM_CPPFLAGS = \
@DBUS_CFLAGS@
if HALD_COMPILE_FREEBSD
-libexec_PROGRAMS = hald-addon-storage
+libexec_PROGRAMS = hald-addon-storage \
+ hald-addon-mouse-sysmouse
endif
hald_addon_storage_SOURCES = addon-storage.c
hald_addon_storage_LDADD = \
$(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la
+
+hald_addon_mouse_sysmouse_SOURCES = addon-mouse.c
+hald_addon_mouse_sysmouse_CFLAGS = $(AM_CPPFLAGS) @GLIB_CFLAGS@
+hald_addon_mouse_sysmouse_LDADD = \
+ @GLIB_LIBS@ \
+ -lutil \
+ $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la
diff --git a/hald/freebsd/addons/addon-mouse.c b/hald/freebsd/addons/addon-mouse.c
new file mode 100644
index 00000000..51194cac
--- /dev/null
+++ b/hald/freebsd/addons/addon-mouse.c
@@ -0,0 +1,371 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * addon-mouse.c : poll mice to disable moused(8) owned devices
+ *
+ * Copyright (C) 2008 Joe Marcus Clarke
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#if __FreeBSD_version >= 800058
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+#include <libutil.h>
+#endif
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <glib.h>
+
+#include "libhal/libhal.h"
+
+#include "../libprobe/hfp.h"
+
+#if __FreeBSD_version < 800058
+#define CMD "/usr/bin/fstat %s"
+#endif
+
+#define MOUSED_DEVICE "/dev/sysmouse"
+#define MOUSED_PROC_NAME "moused"
+#define XORG_PROC_NAME "Xorg"
+#define NO_PID -1
+
+static struct
+{
+ const struct timespec update_interval;
+ char *device_file;
+ struct timespec next_update;
+} addon = { { 2, 0 } };
+
+static int kd = -1;
+
+#if __FreeBSD_version >= 800058
+static struct kinfo_proc *
+hfp_kinfo_getproc (int *cntp)
+{
+ int mib[3];
+ int error;
+ int cnt;
+ size_t len;
+ char *buf, *bp, *eb;
+ struct kinfo_proc *kip, *kp, *ki;
+
+ *cntp = 0;
+
+ len = 0;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PROC;
+
+ error = sysctl(mib, 3, NULL, &len, NULL, 0);
+ if (error)
+ return NULL;
+
+ len = len * 4 / 3;
+ buf = (char *) g_malloc(len);
+ if (buf == NULL)
+ return NULL;
+
+ error = sysctl(mib, 3, buf, &len, NULL, 0);
+ if (error)
+ {
+ g_free(buf);
+ return NULL;
+ }
+
+ cnt = 0;
+ bp = buf;
+ eb = buf + len;
+ while (bp < eb)
+ {
+ ki = (struct kinfo_proc *) (uintptr_t) bp;
+ bp += ki->ki_structsize;
+ cnt++;
+ }
+
+ kip = calloc(cnt, sizeof (*kip));
+ if (kip == NULL)
+ {
+ g_free(buf);
+ return NULL;
+ }
+
+ bp = buf;
+ eb = buf + len;
+ kp = kip;
+ while (bp < eb)
+ {
+ ki = (struct kinfo_proc *) (uintptr_t) bp;
+ memcpy(kp, ki, ki->ki_structsize);
+ bp += ki->ki_structsize;
+ kp->ki_structsize = sizeof(*kp);
+ kp++;
+ }
+
+ g_free(buf);
+ *cntp = cnt;
+ return kip;
+}
+
+static gboolean
+device_opened_by_proc (const char *device, const char *proc, pid_t *pid)
+{
+ struct kinfo_proc *kip, *pfreep;
+ int cnt, i;
+
+ *pid = NO_PID;
+
+ pfreep = hfp_kinfo_getproc(&cnt);
+ if (pfreep == NULL)
+ return FALSE;
+
+ for (i = 0; i < cnt; i++)
+ {
+ kip = &pfreep[i];
+
+ if (! strcmp(kip->ki_comm, proc))
+ {
+ struct kinfo_file *kif, *ffreep;
+ int fcnt, j;
+
+ ffreep = kinfo_getfile(kip->ki_pid, &fcnt);
+ if (ffreep == NULL)
+ continue;
+ for (j = 0; j < fcnt; j++)
+ {
+ kif = &ffreep[j];
+
+ if (kif->kf_type == KF_TYPE_VNODE &&
+ ! strcmp(kif->kf_path, device))
+ {
+ *pid = kip->ki_pid;
+ g_free(ffreep);
+ g_free(pfreep);
+ return TRUE;
+ }
+ }
+ g_free(ffreep);
+ }
+ }
+ g_free(pfreep);
+
+ return FALSE;
+}
+#else
+static gboolean
+device_opened_by_proc (const char *device, const char *proc, pid_t *pid)
+{
+ char **lines;
+ char *output = NULL;
+ char *cmd;
+ int i;
+ gboolean found = FALSE;
+
+ cmd = g_strdup_printf(CMD, device);
+ *pid = NO_PID;
+
+ if (! g_spawn_command_line_sync(cmd, &output, NULL, NULL, NULL))
+ {
+ g_free(cmd);
+ goto done;
+ }
+ g_free(cmd);
+
+ if (! output || strlen(output) == 0)
+ goto done;
+
+ lines = g_strsplit(output, "\n", 0);
+ if (g_strv_length(lines) < 2)
+ {
+ g_strfreev(lines);
+ goto done;
+ }
+
+ for (i = 1; lines[i]; i++)
+ {
+ char **fields;
+ guint len;
+ guint j;
+
+ fields = g_strsplit_set(lines[i], " ", 0);
+ len = g_strv_length(fields);
+ if (len < 3)
+ {
+ g_strfreev(fields);
+ continue;
+ }
+ for (j = 1; j < len && fields[j] && *fields[j] == '\0'; j++)
+ ;
+ if (j < len && fields[j] && ! strcmp(fields[j], proc))
+ {
+ found = TRUE;
+ for (++j; j < len && fields[j] && *fields[j] == '\0'; j++)
+ ;
+ if (j < len && fields[j])
+ *pid = atoi(fields[j]);
+ g_strfreev(fields);
+ break;
+ }
+ g_strfreev(fields);
+ }
+
+ g_strfreev(lines);
+
+done:
+ g_free(output);
+
+ return found;
+}
+#endif
+
+static const char *
+get_mouse_device (const char *device, pid_t *pid)
+{
+ if (device_opened_by_proc(device, MOUSED_PROC_NAME, pid))
+ return MOUSED_DEVICE;
+
+ return device;
+}
+
+static void
+poll_for_moused (void)
+{
+ struct kevent ev;
+ const char *device;
+ gboolean found;
+ pid_t pid;
+ char *owner = NULL;
+ char *prev_owner = NULL;
+
+again:
+ device = get_mouse_device(addon.device_file, &pid);
+ if (pid != NO_PID)
+ {
+ EV_SET(&ev, pid, EVFILT_PROC, EV_ADD | EV_ENABLE, NOTE_EXIT, 0, NULL);
+ if (kevent(kd, &ev, 1, NULL, 0, NULL) < 0)
+ return;
+ g_free(owner);
+ owner = g_strdup(MOUSED_PROC_NAME);
+ }
+ else
+ {
+ found = device_opened_by_proc(device, XORG_PROC_NAME, &pid);
+ if (found && pid != NO_PID)
+ {
+ EV_SET(&ev, pid, EVFILT_PROC, EV_ADD | EV_ENABLE, NOTE_EXIT, 0, NULL);
+ if (kevent(kd, &ev, 1, NULL, 0, NULL) < 0)
+ return;
+ g_free(owner);
+ owner = g_strdup(XORG_PROC_NAME);
+ }
+ else
+ goto out;
+ }
+
+ if (owner && prev_owner && strcmp(owner, prev_owner))
+ goto out;
+
+ if (kevent(kd, NULL, 0, &ev, 1, NULL) < 0)
+ return;
+
+ sleep(3);
+ g_free(prev_owner);
+ prev_owner = NULL;
+ if (owner)
+ prev_owner = g_strdup(owner);
+ goto again;
+
+out:
+ if (owner)
+ {
+ libhal_device_reprobe(hfp_ctx, hfp_udi, &hfp_error);
+ dbus_error_free(&hfp_error);
+ }
+ g_free(owner);
+ g_free(prev_owner);
+}
+
+int
+main (int argc, char **argv)
+{
+ DBusConnection *connection;
+
+ if (! hfp_init(argc, argv))
+ goto end;
+
+ addon.device_file = getenv("HAL_PROP_FREEBSD_DEVICE_FILE");
+ if (! addon.device_file)
+ goto end;
+
+ setproctitle("%s", addon.device_file);
+
+ if (! libhal_device_addon_is_ready(hfp_ctx, hfp_udi, &hfp_error))
+ goto end;
+ dbus_error_free(&hfp_error);
+
+ connection = libhal_ctx_get_dbus_connection(hfp_ctx);
+ assert(connection != NULL);
+
+ kd = kqueue();
+ assert(kd > -1);
+
+ while (TRUE)
+ {
+ /* process dbus traffic until update interval has elapsed */
+ while (TRUE)
+ {
+ struct timespec now;
+
+ hfp_clock_gettime(&now);
+ if (hfp_timespeccmp(&now, &addon.next_update, <))
+ {
+ struct timespec timeout;
+
+ timeout = addon.next_update;
+ hfp_timespecsub(&timeout, &now);
+
+ if (timeout.tv_sec < 0) /* current time went backwards */
+ timeout = addon.update_interval;
+
+ dbus_connection_read_write_dispatch(connection, timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000);
+ if (! dbus_connection_get_is_connected(connection))
+ goto end;
+ }
+ else
+ break;
+ }
+
+ poll_for_moused();
+
+ hfp_clock_gettime(&addon.next_update);
+ hfp_timespecadd(&addon.next_update, &addon.update_interval);
+ }
+
+ end:
+ return 0;
+}
diff --git a/hald/freebsd/addons/addon-storage.c b/hald/freebsd/addons/addon-storage.c
index dcd9cdc9..31250373 100644
--- a/hald/freebsd/addons/addon-storage.c
+++ b/hald/freebsd/addons/addon-storage.c
@@ -36,17 +36,24 @@
#include "../libprobe/hfp.h"
#include "../libprobe/hfp-cdrom.h"
+static boolean is_locked_by_hal = FALSE;
+static boolean check_lock_state = TRUE;
+static boolean polling_disabled = FALSE;
+
static struct
{
- const struct timeval update_interval;
+ const struct timespec update_interval;
char *device_file;
char *parent;
boolean is_cdrom;
boolean is_scsi_removable;
boolean had_media;
- struct timeval next_update;
+ struct timespec next_update;
} addon = { { 2, 0 } };
+static void update_proc_title (const char *device);
+static void unmount_volumes (void);
+
/* see MMC-3 Working Draft Revision 10 */
static boolean
hf_addon_storage_cdrom_eject_pressed (HFPCDROM *cdrom)
@@ -144,18 +151,148 @@ hf_addon_storage_update (void)
}
}
- hfp_gettimeofday(&addon.next_update);
- hfp_timevaladd(&addon.next_update, &addon.update_interval);
-
return has_media;
}
+static void
+unmount_volumes (void)
+{
+ int num_volumes;
+ char **volumes;
+
+ if ((volumes = libhal_manager_find_device_string_match(hfp_ctx,
+ "block.storage_device",
+ hfp_udi,
+ &num_volumes,
+ &hfp_error)) != NULL)
+ {
+ int i;
+
+ dbus_error_free(&hfp_error);
+
+ for (i = 0; i < num_volumes; i++)
+ {
+ char *vol_udi;
+
+ vol_udi = volumes[i];
+
+ if (libhal_device_get_property_bool(hfp_ctx, vol_udi, "volume.is_mounted", &hfp_error))
+ {
+ DBusMessage *msg = NULL;
+ DBusMessage *reply = NULL;
+ DBusConnection *dbus_connection;
+ unsigned int num_options = 0;
+ char **options = NULL;
+ char *devfile;
+
+ dbus_error_free(&hfp_error);
+ hfp_info("Forcing unmount of volume '%s'", vol_udi);
+
+ dbus_connection = libhal_ctx_get_dbus_connection(hfp_ctx);
+ msg = dbus_message_new_method_call("org.freedesktop.Hal", vol_udi,
+ "org.freedesktop.Hal.Device.Volume",
+ "Unmount");
+ if (msg == NULL)
+ {
+ hfp_warning("Could not create dbus message for %s", vol_udi);
+ continue;
+ }
+
+ options = calloc(1, sizeof (char *));
+ if (options == NULL)
+ {
+ hfp_warning("Could not allocation memory for options");
+ dbus_message_unref(msg);
+ continue;
+ }
+
+ options[0] = "force";
+ num_options = 1;
+
+ devfile = libhal_device_get_property_string(hfp_ctx, vol_udi, "block.device", NULL);
+ if (devfile != NULL)
+ {
+ hfp_info("Forcibly attempting to unmount %s as media was removed", devfile);
+ libhal_free_string(devfile);
+ }
+
+ if (! dbus_message_append_args(msg, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, num_options, DBUS_TYPE_INVALID))
+ {
+ hfp_warning("Could not append args to dbus message for %s", vol_udi);
+ free(options);
+ dbus_message_unref(msg);
+ continue;
+ }
+
+ if (! (reply = dbus_connection_send_with_reply_and_block(dbus_connection, msg, -1, &hfp_error)))
+ {
+ hfp_warning("Unmount failed for %s: %s: %s", vol_udi, hfp_error.name, hfp_error.message);
+ dbus_error_free(&hfp_error);
+ free(options);
+ dbus_message_unref(msg);
+ continue;
+ }
+
+ if (dbus_error_is_set(&hfp_error))
+ {
+ hfp_warning("Unmount failed for %s: %s : %s", vol_udi, hfp_error.name, hfp_error.message);
+ dbus_error_free(&hfp_error);
+ free(options);
+ dbus_message_unref(msg);
+ dbus_message_unref(reply);
+ continue;
+ }
+
+ hfp_info("Successfully unmounted udi '%s'", vol_udi);
+ free(options);
+ dbus_message_unref(msg);
+ dbus_message_unref(reply);
+ }
+ }
+ libhal_free_string_array(volumes);
+ }
+}
+
static boolean
-poll_for_media (void)
+poll_for_media (boolean check_only, boolean force)
{
boolean has_media;
+ if (check_lock_state)
+ {
+ boolean should_poll;
+
+ check_lock_state = FALSE;
+
+ hfp_info("Checking whether device %s is locked by HAL", addon.device_file);
+ if (libhal_device_is_locked_by_others(hfp_ctx, hfp_udi, "org.freedesktop.Hal.Device.Storage", &hfp_error))
+ {
+ hfp_info("... device %s is locked by HAL", addon.device_file);
+ dbus_error_free(&hfp_error);
+ is_locked_by_hal = TRUE;
+ update_proc_title(addon.device_file);
+ goto skip_check;
+ }
+ else
+ {
+ hfp_info("... device %s is not locked by HAL", addon.device_file);
+ is_locked_by_hal = FALSE;
+ }
+ dbus_error_free(&hfp_error);
+
+ should_poll = libhal_device_get_property_bool(hfp_ctx, hfp_udi, "storage.media_check_enabled", &hfp_error);
+ dbus_error_free(&hfp_error);
+ polling_disabled = ! should_poll;
+ update_proc_title(addon.device_file);
+ }
+
+ if (! force && polling_disabled)
+ goto skip_check;
+
has_media = hf_addon_storage_update();
+ if (check_only)
+ return has_media;
+
if (has_media != addon.had_media)
{
/*
@@ -168,6 +305,14 @@ poll_for_media (void)
* then hung while rebooting and did not unmount my other
* filesystems.
*/
+#if __FreeBSD_version >= 800066
+ /*
+ * With newusb, it is safe to force unmount volumes. This may be
+ * safe on newer versions of the old USB stack, but we'll be
+ * extra cautious.
+ */
+ unmount_volumes();
+#endif
libhal_device_rescan(hfp_ctx, hfp_udi, &hfp_error);
dbus_error_free(&hfp_error);
@@ -175,20 +320,33 @@ poll_for_media (void)
return TRUE;
}
+
+skip_check:
+
return FALSE;
}
static void
-update_proc_title (const char *device, boolean polling_enabled)
+update_proc_title (const char *device)
{
- if (polling_enabled)
- setproctitle("%s", device);
- else
+ if (polling_disabled)
setproctitle("no polling on %s because it is explicitly disabled", device);
+ else if (is_locked_by_hal)
+ setproctitle("no polling on %s because it is locked by HAL", device);
+ else
+ setproctitle("%s", device);
}
static DBusHandlerResult
-filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
+dbus_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ check_lock_state = TRUE;
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+direct_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
{
if (dbus_message_is_method_call(message,
"org.freedesktop.Hal.Device.Storage.Removable",
@@ -199,7 +357,7 @@ filter_function (DBusConnection *connection, DBusMessage *message, void *user_da
hfp_info("Forcing poll for media becusse CheckForMedia() was called");
- had_effect = poll_for_media();
+ had_effect = poll_for_media(FALSE, TRUE);
reply = dbus_message_new_method_return (message);
dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &had_effect, DBUS_TYPE_INVALID);
@@ -217,8 +375,9 @@ main (int argc, char **argv)
char *removable;
char *bus;
char *driver;
- boolean should_poll;
+ char *filter_str;
DBusConnection *connection;
+ DBusConnection *syscon;
if (! hfp_init(argc, argv))
goto end;
@@ -251,16 +410,41 @@ main (int argc, char **argv)
addon.is_scsi_removable = (! strcmp(bus, "scsi") ||
(! strcmp(bus, "usb") && (! strcmp(driver, "da") || ! strcmp(driver, "sa") ||
! strcmp(driver, "cd")))) && ! strcmp(removable, "true");
- addon.had_media = hf_addon_storage_update();
+ addon.had_media = poll_for_media(TRUE, FALSE);
if (! libhal_device_addon_is_ready(hfp_ctx, hfp_udi, &hfp_error))
goto end;
dbus_error_free(&hfp_error);
+ syscon = dbus_bus_get(DBUS_BUS_SYSTEM, &hfp_error);
+ dbus_error_free(&hfp_error);
+ assert(syscon != NULL);
+ dbus_connection_set_exit_on_disconnect(syscon, 0);
+
+ dbus_bus_add_match(syscon,
+ "type='signal'"
+ ",interface='org.freedesktop.Hal.Manager'"
+ ",sender='org.freedesktop.Hal'",
+ NULL);
+ dbus_bus_add_match(syscon,
+ "type='signal'"
+ ",interface='org.freedesktop.Hal.Manager'"
+ ",sender='org.freedesktop.Hal'",
+ NULL);
+ filter_str = hfp_strdup_printf("type='signal'"
+ ",interface='org.freedesktop.Hal.Device'"
+ ",sender='org.freedesktop.Hal'"
+ ",path='%s'",
+ hfp_udi);
+ dbus_bus_add_match(syscon, filter_str, NULL);
+ hfp_free(filter_str);
+
+ dbus_connection_add_filter(syscon, dbus_filter_function, NULL, NULL);
+
connection = libhal_ctx_get_dbus_connection(hfp_ctx);
assert(connection != NULL);
dbus_connection_set_exit_on_disconnect(connection, 0);
- dbus_connection_add_filter(connection, filter_function, NULL, NULL);
+ dbus_connection_add_filter(connection, direct_filter_function, NULL, NULL);
if (! libhal_device_claim_interface(hfp_ctx,
hfp_udi,
@@ -280,40 +464,32 @@ main (int argc, char **argv)
/* process dbus traffic until update interval has elapsed */
while (TRUE)
{
- struct timeval now;
+ struct timespec now;
- hfp_gettimeofday(&now);
- if (hfp_timevalcmp(&now, &addon.next_update, <))
+ hfp_clock_gettime(&now);
+ if (hfp_timespeccmp(&now, &addon.next_update, <))
{
- struct timeval timeout;
+ struct timespec timeout;
timeout = addon.next_update;
- hfp_timevalsub(&timeout, &now);
+ hfp_timespecsub(&timeout, &now);
if (timeout.tv_sec < 0) /* current time went backwards */
timeout = addon.update_interval;
- dbus_connection_read_write_dispatch(connection, timeout.tv_sec * 1000 + timeout.tv_usec / 1000);
- if (! dbus_connection_get_is_connected(connection))
+ dbus_connection_read_write_dispatch(connection, (int) ((timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000) / 2));
+ dbus_connection_read_write_dispatch(syscon, (int) ((timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000) / 2));
+ if (! dbus_connection_get_is_connected(connection) ||
+ ! dbus_connection_get_is_connected(syscon))
goto end;
}
else
break;
}
- should_poll = libhal_device_get_property_bool(hfp_ctx, hfp_udi, "storage.media_check_enabled", &hfp_error);
- dbus_error_free(&hfp_error);
- update_proc_title(addon.device_file, should_poll);
-
- if (should_poll)
- {
- poll_for_media();
- }
- else
- {
- hfp_gettimeofday(&addon.next_update);
- hfp_timevaladd(&addon.next_update, &addon.update_interval);
- }
+ poll_for_media(FALSE, FALSE);
+ hfp_clock_gettime(&addon.next_update);
+ hfp_timespecadd(&addon.next_update, &addon.update_interval);
}
end:
diff --git a/hald/freebsd/hf-acpi.c b/hald/freebsd/hf-acpi.c
index 89243df8..023a4fed 100644
--- a/hald/freebsd/hf-acpi.c
+++ b/hald/freebsd/hf-acpi.c
@@ -54,6 +54,7 @@
static const struct laptop_panel_type {
char *access;
char *name;
+ char *get_sysctl;
char *max_sysctl;
int max_levels;
#define HF_ACPI_IBM_MAX_LEVELS 8
@@ -64,17 +65,29 @@ static const struct laptop_panel_type {
#define HF_ACPI_FUJITSU_MAX_LEVELS 8
/* NOTE: Each new type must also be added to hf-devtree.c */
} laptop_panel_types[] = {
- { "ibm", "IBM", NULL,
+ { "ibm", "IBM",
+ "dev.acpi_ibm.0.lcd_brightness",
+ NULL,
HF_ACPI_IBM_MAX_LEVELS },
- { "toshiba", "Toshiba", NULL,
+ { "toshiba", "Toshiba",
+ "hw.acpi.toshiba.lcd_brightness",
+ NULL,
HF_ACPI_TOSHIBA_MAX_LEVELS },
- { "sony", "Sony", NULL,
+ { "sony", "Sony",
+ "dev.acpi_sony.0.brightness",
+ NULL,
HF_ACPI_SONY_MAX_LEVELS },
- { "panasonic", "Panasonic", "hw.acpi.panasonic.lcd_brightness_max",
+ { "panasonic", "Panasonic",
+ "hw.acpi.panasonic.lcd_brightness",
+ "hw.acpi.panasonic.lcd_brightness_max",
HF_ACPI_PANASONIC_MAX_LEVELS },
- { "asus", "Asus", NULL,
+ { "asus", "Asus",
+ "hw.acpi.asus.lcd_brightness",
+ NULL,
HF_ACPI_ASUS_MAX_LEVELS },
- { "fujitsu", "Fujitsu", NULL,
+ { "fujitsu", "Fujitsu",
+ "hw.acpi.fujitsu.lcd_brightness",
+ NULL,
HF_ACPI_FUJITSU_MAX_LEVELS }
};
@@ -105,6 +118,9 @@ hf_acpi_poll_batt (HalDevice *device)
gboolean ispresent;
union acpi_battery_ioctl_arg battif, battst, battinfo;
+ if (! hf_has_sysctl("hw.acpi.battery.units"))
+ return;
+
battif.unit = battst.unit = battinfo.unit =
hal_device_property_get_int(device, "freebsd.unit");
@@ -497,13 +513,15 @@ hf_acpi_video_device_new (HalDevice *parent, const char *type)
static HalDevice *
hf_acpi_laptop_panel_new (HalDevice *parent, int max_levels,
- const char *max_sysctl, const char *access,
- const char *name)
+ const char *get_sysctl, const char *max_sysctl,
+ const char *access, const char *name)
{
HalDevice *device;
g_return_val_if_fail(HAL_IS_DEVICE(parent), NULL);
+ if (get_sysctl == NULL || ! hf_has_sysctl(get_sysctl))
+ return NULL;
device = hf_device_new(parent);
hf_device_property_set_string_printf(device, "info.product", "Laptop Panel (%s)", name);
@@ -593,11 +611,13 @@ hf_acpi_probe (void)
HalDevice *panel_device;
panel_device = hf_acpi_laptop_panel_new(parent,
- laptop_panel_types[i].max_levels,
+ laptop_panel_types[i].max_levels,
+ laptop_panel_types[i].get_sysctl,
laptop_panel_types[i].max_sysctl,
laptop_panel_types[i].access,
laptop_panel_types[i].name);
- hf_device_preprobe_and_add(panel_device);
+ if (panel_device)
+ hf_device_preprobe_and_add(panel_device);
}
}
}
diff --git a/hald/freebsd/hf-computer.c b/hald/freebsd/hf-computer.c
index 7e9b9de1..e0e53ecb 100644
--- a/hald/freebsd/hf-computer.c
+++ b/hald/freebsd/hf-computer.c
@@ -26,6 +26,7 @@
# include <config.h>
#endif
+#include <stdio.h>
#include <string.h>
#include <sys/utsname.h>
@@ -133,11 +134,11 @@ hf_computer_device_add (void)
if (PACKAGE_VERSION) {
int major, minor, micro;
- hal_device_property_set_string (root, "org.freedesktop.Hal.version", PACKAGE_VERSION);
+ hal_device_property_set_string (device, "org.freedesktop.Hal.version", PACKAGE_VERSION);
if ( sscanf( PACKAGE_VERSION, "%d.%d.%d", &major, &minor, &micro ) == 3 ) {
- hal_device_property_set_int (root, "org.freedesktop.Hal.version.major", major);
- hal_device_property_set_int (root, "org.freedesktop.Hal.version.minor", minor);
- hal_device_property_set_int (root, "org.freedesktop.Hal.version.micro", micro);
+ hal_device_property_set_int (device, "org.freedesktop.Hal.version.major", major);
+ hal_device_property_set_int (device, "org.freedesktop.Hal.version.minor", minor);
+ hal_device_property_set_int (device, "org.freedesktop.Hal.version.micro", micro);
}
}
diff --git a/hald/freebsd/hf-devd.c b/hald/freebsd/hf-devd.c
index d878a458..dbf0202d 100644
--- a/hald/freebsd/hf-devd.c
+++ b/hald/freebsd/hf-devd.c
@@ -28,6 +28,7 @@
#include <string.h>
#include <errno.h>
#include <unistd.h>
+#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
@@ -40,7 +41,11 @@
#include "hf-acpi.h"
#include "hf-net.h"
#include "hf-pcmcia.h"
+#include "hf-storage.h"
#include "hf-usb.h"
+#ifdef HAVE_LIBUSB20
+#include "hf-usb2.h"
+#endif
#include "hf-util.h"
#define HF_DEVD_SOCK_PATH "/var/run/devd.pipe"
@@ -51,10 +56,16 @@
#define HF_DEVD_EVENT_NOMATCH '?'
static HFDevdHandler *handlers[] = {
+#ifdef HAVE_LIBUSB20
+ &hf_usb2_devd_handler,
+#endif
+#if __FreeBSD_version < 800092
&hf_usb_devd_handler,
+#endif
&hf_net_devd_handler,
&hf_acpi_devd_handler,
- &hf_pcmcia_devd_handler
+ &hf_pcmcia_devd_handler,
+ &hf_storage_devd_handler
};
static gboolean hf_devd_inited = FALSE;
@@ -381,13 +392,13 @@ hf_devd_event_cb (GIOChannel *source, GIOCondition condition,
status = g_io_channel_read_line(source, &event, NULL, &terminator, NULL);
- if (status != G_IO_STATUS_NORMAL)
+ if (status == G_IO_STATUS_NORMAL)
{
event[terminator] = 0;
hf_devd_process_event(event);
g_free(event);
}
- else if (status != G_IO_STATUS_AGAIN)
+ else if (status == G_IO_STATUS_AGAIN)
{
hf_devd_init();
if (hf_devd_inited)
diff --git a/hald/freebsd/hf-devtree.c b/hald/freebsd/hf-devtree.c
index 01203f05..7a54feb5 100644
--- a/hald/freebsd/hf-devtree.c
+++ b/hald/freebsd/hf-devtree.c
@@ -86,7 +86,11 @@ hf_devtree_cpu_can_throttle (int cpu)
gboolean can = FALSE;
char *levels;
+#ifdef notyet
levels = hf_get_string_sysctl(NULL, "dev.cpu.%i.freq_levels", cpu);
+#else
+ levels = hf_get_string_sysctl(NULL, "dev.cpu.0.freq_levels");
+#endif
if (levels)
{
char **toks;
@@ -109,7 +113,11 @@ hf_devtree_cpu_get_maxfreq (int cpu)
char *levels;
int freq = -1;
+#ifdef notyet
levels = hf_get_string_sysctl(NULL, "dev.cpu.%i.freq_levels", cpu);
+#else
+ levels = hf_get_string_sysctl(NULL, "dev.cpu.0.freq_levels");
+#endif
if (levels)
{
sscanf(levels, "%i/", &freq);
@@ -186,7 +194,7 @@ hf_devtree_fd_set_properties (HalDevice *device)
static void
hf_devtree_atkbd_set_properties (HalDevice *device)
{
- hf_device_set_input(device, "keyboard", NULL);
+ hf_device_set_input(device, "keyboard", "keys", NULL);
}
static void
@@ -195,7 +203,7 @@ hf_devtree_psm_set_properties (HalDevice *device)
char *devname;
devname = hf_devtree_device_get_name(device);
- hf_device_set_input(device, "mouse", devname);
+ hf_device_set_input(device, "mouse", NULL, devname);
g_free(devname);
}
@@ -205,7 +213,7 @@ hf_devtree_joy_set_properties (HalDevice *device)
char *devname;
devname = hf_devtree_device_get_name(device);
- hf_device_set_input(device, "joystick", devname);
+ hf_device_set_input(device, "joystick", NULL, devname);
g_free(devname);
if (! hal_device_has_property(device, "info.product"))
@@ -379,7 +387,8 @@ static Handler handlers[] = {
{ "pcm", NULL },
{ "psm", hf_devtree_psm_set_properties },
{ "sio", NULL },
- { "speaker", NULL }
+ { "speaker", NULL },
+ { "usbus", NULL }
};
static void
@@ -426,7 +435,13 @@ hf_devtree_probe (void)
HalDevice *device;
device = hf_devtree_device_new(parent, info->handler, info->unit);
- hf_device_preprobe_and_add(device);
+ if (hf_device_preprobe(device))
+ {
+ if (hal_device_has_capability(device, "input.mouse"))
+ hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL);
+
+ hf_device_add(device);
+ }
}
devices = g_slist_delete_link(devices, root);
@@ -434,6 +449,17 @@ hf_devtree_probe (void)
}
}
+static gboolean
+hf_devtree_rescan (HalDevice *device)
+{
+ if (hal_device_has_capability(device, "input.mouse"))
+ {
+ hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL);
+ return TRUE;
+ }
+ return FALSE;
+}
+
HalDevice *
hf_devtree_find_from_name (HalDeviceStore *store, const char *name)
{
@@ -597,5 +623,6 @@ hf_devtree_is_driver (const char *name, const char *driver)
}
HFHandler hf_devtree_handler = {
- .probe = hf_devtree_probe
+ .probe = hf_devtree_probe,
+ .device_rescan = hf_devtree_rescan
};
diff --git a/hald/freebsd/hf-scsi.c b/hald/freebsd/hf-scsi.c
index 7ab753cd..527bc518 100644
--- a/hald/freebsd/hf-scsi.c
+++ b/hald/freebsd/hf-scsi.c
@@ -549,7 +549,7 @@ hf_scsi_probe (void)
break; /* only use the first peripheral */
match = &ccb.cdm.matches[i].result.periph_result;
- if ((int) match->path_id == -1 || ! strcmp(match->periph_name, "pass"))
+ if ((int) match->path_id == -1 || ! strcmp(match->periph_name, "pass") || ! strcmp(match->periph_name, "probe"))
break;
pending_devname = g_strdup_printf("%s%i", match->periph_name, match->unit_number);
diff --git a/hald/freebsd/hf-storage.c b/hald/freebsd/hf-storage.c
index b901d9d3..3bc5ab92 100644
--- a/hald/freebsd/hf-storage.c
+++ b/hald/freebsd/hf-storage.c
@@ -30,6 +30,7 @@
#include <limits.h>
#include <inttypes.h>
#include <string.h>
+#include <sys/param.h>
#include <sys/types.h>
#include <sys/disklabel.h>
@@ -38,6 +39,7 @@
#include "hf-storage.h"
#include "hf-block.h"
+#include "hf-devd.h"
#include "hf-devtree.h"
#include "hf-volume.h"
#include "hf-util.h"
@@ -64,7 +66,7 @@ typedef struct
static GNode *hf_storage_geom_tree = NULL;
static GHashTable *hf_storage_geom_hash = NULL;
-static void hf_storage_init_geom (void);
+static void hf_storage_init_geom (gboolean force);
static gboolean hf_storage_device_has_addon (HalDevice *device);
static void
@@ -104,6 +106,8 @@ hf_storage_class_is_partitionable (const char *geom_class)
{
return (! strcmp(geom_class, "MBR") ||
! strcmp(geom_class, "MBREXT") ||
+ ! strcmp(geom_class, "PART") ||
+ ! strcmp(geom_class, "JOURNAL") ||
! strcmp(geom_class, "GPT") ||
! strcmp(geom_class, "APPLE") || ! strcmp(geom_class, "SUN"));
}
@@ -117,6 +121,7 @@ hf_storage_geom_has_partitions (const Geom_Object *geom_obj, GNode *node)
if (g_node_n_children(node) > 0)
return TRUE;
+ /*
if (hf_storage_class_is_partitionable(geom_obj->class) &&
g_node_next_sibling(node) != NULL)
{
@@ -135,6 +140,7 @@ hf_storage_geom_has_partitions (const Geom_Object *geom_obj, GNode *node)
return TRUE;
}
}
+ */
return FALSE;
}
@@ -294,7 +300,7 @@ hf_storage_device_probe (HalDevice *device, gboolean only_media)
{
g_return_if_fail(HAL_IS_DEVICE(device));
- hf_storage_init_geom();
+ hf_storage_init_geom(TRUE);
if (hf_runner_run_sync(device, 0, "hald-probe-storage",
"HF_HAS_CHILDREN", HF_BOOL_TO_STRING(hf_storage_device_has_partitions(device)),
@@ -403,13 +409,20 @@ hf_storage_parse_conftxt (const char *conftxt)
continue;
}
+ depth = atoi(fields[0]);
+ hash = g_str_hash(fields[2]);
+ if (g_hash_table_lookup(table, GUINT_TO_POINTER(hash)) != NULL)
+ {
+ g_strfreev(fields);
+ curr_depth = depth;
+ continue;
+ }
+
geom_obj = g_new0(Geom_Object, 1);
- depth = atoi(fields[0]);
geom_obj->class = g_strdup(fields[1]);
geom_obj->dev = g_strdup(fields[2]);
geom_obj->type = -1; /* We use -1 here to denote a missing type. */
- hash = g_str_hash(geom_obj->dev);
geom_obj->hash = hash;
if (g_strv_length(fields) >= 5)
@@ -433,6 +446,30 @@ hf_storage_parse_conftxt (const char *conftxt)
if (! strcmp (geom_obj->class, "GPT") ||
! strcmp (geom_obj->class, "APPLE"))
geom_obj->str_type = g_strdup(fields[10]);
+ else if (! strcmp (geom_obj->class, "PART"))
+ {
+ geom_obj->str_type = g_strdup(fields[10]);
+ if (g_strv_length(fields) >= 15)
+ {
+ if (! strcmp(fields[13], "xt"))
+ {
+ geom_obj->type = atoi(fields[14]);
+ if (! strcmp(fields[11], "xs"))
+ {
+ g_free(geom_obj->class);
+ geom_obj->class = g_strdup(fields[12]);
+ }
+ }
+ }
+ }
+ else if (fields[10][0] == '!')
+ {
+ char *nottype;
+
+ nottype = fields[10];
+ nottype++;
+ geom_obj->type = atoi(nottype);
+ }
else
geom_obj->type = atoi(fields[10]);
}
@@ -541,15 +578,20 @@ hf_storage_device_rescan_real (HalDevice *device)
}
static gboolean
-hf_storage_conftxt_timeout_cb (gpointer data)
+hf_storage_devd_notify (const char *system,
+ const char *subsystem,
+ const char *type,
+ const char *data)
{
static GSList *disks = NULL;
static gboolean first = TRUE;
+ gboolean handled = FALSE;
char *conftxt;
GSList *new_disks;
- if (hf_is_waiting)
- return TRUE;
+ if (strcmp(system, "DEVFS") || strcmp(subsystem, "CDEV") ||
+ (strcmp(type, "CREATE") && strcmp(type, "DESTROY")))
+ return FALSE;
conftxt = hf_get_string_sysctl(NULL, "kern.geom.conftxt");
new_disks = hf_storage_parse_conftxt(conftxt);
@@ -572,6 +614,7 @@ hf_storage_conftxt_timeout_cb (gpointer data)
if (! hf_storage_find_disk(disks, disk->name))
{
osspec_probe(); /* catch new disk(s) */
+ handled = TRUE;
break;
}
}
@@ -593,7 +636,10 @@ hf_storage_conftxt_timeout_cb (gpointer data)
device = hf_devtree_find_from_name(hald_get_gdl(), disk->name);
if (device && hal_device_has_capability(device, "storage") &&
! hf_storage_device_has_addon(device))
- hf_storage_device_rescan_real(device);
+ {
+ hf_storage_device_rescan_real(device);
+ handled = TRUE;
+ }
}
}
else
@@ -601,7 +647,10 @@ hf_storage_conftxt_timeout_cb (gpointer data)
/* disk removed */
device = hf_devtree_find_from_name(hald_get_gdl(), disk->name);
if (device && hal_device_has_capability(device, "storage"))
- hf_device_remove_tree(device);
+ {
+ hf_device_remove_tree(device);
+ handled = TRUE;
+ }
}
}
}
@@ -610,17 +659,30 @@ hf_storage_conftxt_timeout_cb (gpointer data)
g_slist_free(disks);
disks = new_disks;
+ return handled;
+}
+
+#if __FreeBSD_version < 700110
+static gboolean
+hf_storage_conftxt_timeout_cb (gpointer data)
+{
+ if (hf_is_waiting)
+ return TRUE;
+
+ hf_storage_devd_notify("DEVFS", "CDEV", "CREATE", NULL);
+
return TRUE;
}
+#endif
static void
-hf_storage_init_geom (void)
+hf_storage_init_geom (gboolean force)
{
char *conftxt;
static gboolean inited = FALSE;
GSList *disks;
- if (inited)
+ if (inited && ! force)
return;
conftxt = hf_get_string_sysctl(NULL, "kern.geom.conftxt");
@@ -636,8 +698,10 @@ hf_storage_init_geom (void)
static void
hf_storage_init (void)
{
- hf_storage_init_geom();
+ hf_storage_init_geom(FALSE);
+#if __FreeBSD_version < 700110
g_timeout_add(3000, hf_storage_conftxt_timeout_cb, NULL);
+#endif
}
void
@@ -719,8 +783,6 @@ hf_storage_device_add (HalDevice *device)
{
g_return_if_fail(HAL_IS_DEVICE(device));
- hf_storage_init_geom();
-
if (hf_device_preprobe(device))
{
hf_storage_device_probe(device, FALSE);
@@ -738,7 +800,7 @@ hf_storage_get_geoms (const char *devname)
g_return_val_if_fail(devname != NULL, NULL);
- hf_storage_init_geom();
+ hf_storage_init_geom(FALSE);
hash = g_str_hash(devname);
node = g_node_find(hf_storage_geom_tree, G_PRE_ORDER, G_TRAVERSE_ALL,
@@ -801,3 +863,7 @@ HFHandler hf_storage_handler = {
.probe = hf_storage_probe,
.device_rescan = hf_storage_device_rescan
};
+
+HFDevdHandler hf_storage_devd_handler = {
+ .notify = hf_storage_devd_notify
+};
diff --git a/hald/freebsd/hf-storage.h b/hald/freebsd/hf-storage.h
index d8b2ff08..0915f1f0 100644
--- a/hald/freebsd/hf-storage.h
+++ b/hald/freebsd/hf-storage.h
@@ -29,8 +29,10 @@
#endif
#include "hf-osspec.h"
+#include "hf-devd.h"
extern HFHandler hf_storage_handler;
+extern HFDevdHandler hf_storage_devd_handler;
void hf_storage_device_enable (HalDevice *device);
void hf_storage_device_enable_tape (HalDevice *device);
diff --git a/hald/freebsd/hf-usb.c b/hald/freebsd/hf-usb.c
index d04f7f29..280e0dbd 100644
--- a/hald/freebsd/hf-usb.c
+++ b/hald/freebsd/hf-usb.c
@@ -25,13 +25,20 @@
# include <config.h>
#endif
+#include <sys/param.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
+#if __FreeBSD_version < 800092
+#if __FreeBSD_version >= 800064
+#include <legacy/dev/usb/usb.h>
+#else
#include <dev/usb/usb.h>
+#endif
+#endif
#include "../logger.h"
#include "../osspec.h"
@@ -40,7 +47,13 @@
#include "hf-devtree.h"
#include "hf-util.h"
+#if __FreeBSD_version < 800092
#define HF_USB_DEVICE "/dev/usb"
+#if __FreeBSD_version < 800066
+#define HF_USB2_DEVICE "/dev/usb "
+#else
+#define HF_USB2_DEVICE "/dev/usbctl"
+#endif
typedef struct
{
@@ -227,51 +240,6 @@ hf_usb_get_full_config_descriptor (int fd,
return NULL;
}
-/*
- * Adapted from usb_compute_udi() in linux2/physdev.c and
- * usbclass_compute_udi() in linux2/classdev.c.
- */
-static void
-hf_usb_device_compute_udi (HalDevice *device)
-{
- g_return_if_fail(HAL_IS_DEVICE(device));
-
- if (hal_device_has_capability(device, "hiddev"))
- hf_device_set_full_udi(device, "%s_hiddev",
- hal_device_property_get_string(device, "info.parent"));
- else if (hal_device_has_capability(device, "video4linux"))
- hf_device_set_full_udi(device, "%s_video4linux",
- hal_device_property_get_string(device, "info.parent"));
- else if (hal_device_has_property(device, "usb.interface.number"))
- hf_device_set_full_udi(device, "%s_if%i",
- hal_device_property_get_string(device, "info.parent"),
- hal_device_property_get_int(device, "usb.interface.number"));
- else
- hf_device_set_udi(device, "usb_device_%x_%x_%s",
- hal_device_property_get_int(device, "usb_device.vendor_id"),
- hal_device_property_get_int(device, "usb_device.product_id"),
- hal_device_has_property(device, "usb_device.serial")
- ? hal_device_property_get_string(device, "usb_device.serial")
- : "noserial");
-}
-
-static void
-hf_usb_add_webcam_properties (HalDevice *device)
-{
- int unit;
-
- g_return_if_fail(HAL_IS_DEVICE(device));
-
- unit = hal_device_property_get_int(device, "freebsd.unit");
- if (unit < 0)
- unit = 0;
-
- hal_device_property_set_string(device, "info.category", "video4linux");
- hal_device_add_capability(device, "video4linux");
- hf_device_property_set_string_printf(device, "video4linux.device", "/dev/video%i", unit);
- hal_device_property_set_string(device, "info.product", "Video Device");
-}
-
/* adapted from usbif_set_name() in linux2/physdev.c */
static const char *
hf_usb_get_interface_name (const usb_interface_descriptor_t *desc)
@@ -424,9 +392,9 @@ hf_usb_device_new (HalDevice *parent,
hf_devtree_device_set_name(device, di->udi_devnames[0]);
if ((devname = hf_usb_get_devname(di, "ukbd"))) /* USB keyboard */
- hf_device_set_input(device, "keyboard", devname);
+ hf_device_set_input(device, "keyboard", "keys", devname);
else if ((devname = hf_usb_get_devname(di, "ums"))) /* USB mouse */
- hf_device_set_input(device, "mouse", devname);
+ hf_device_set_input(device, "mouse", NULL, devname);
else if ((devname = hf_usb_get_devname(di, "uhid"))) /* UHID device */
{
hal_device_property_set_string(device, "info.category", "hiddev");
@@ -575,6 +543,8 @@ hf_usb_probe_device (HalDevice *parent,
{
if (hal_device_has_capability(device, "hiddev"))
hf_runner_run_sync(device, 0, "hald-probe-hiddev", NULL);
+ if (hal_device_has_capability(device, "input.mouse"))
+ hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL);
hf_device_add(device);
}
@@ -633,9 +603,18 @@ hf_usb_privileged_init (void)
{
int i;
+ if (g_file_test(HF_USB2_DEVICE, G_FILE_TEST_EXISTS))
+ {
+ hf_usb_fd = -1;
+ return;
+ }
+
hf_usb_fd = open(HF_USB_DEVICE, O_RDONLY);
if (hf_usb_fd < 0)
- HAL_INFO(("unable to open %s: %s", HF_USB_DEVICE, g_strerror(errno)));
+ {
+ HAL_INFO(("unable to open %s: %s", HF_USB_DEVICE, g_strerror(errno)));
+ return;
+ }
for (i = 0; i < 16; i++)
{
@@ -885,3 +864,50 @@ HFDevdHandler hf_usb_devd_handler = {
.add = hf_usb_devd_add,
.remove = hf_usb_devd_remove
};
+#endif
+
+/*
+ * Adapted from usb_compute_udi() in linux2/physdev.c and
+ * usbclass_compute_udi() in linux2/classdev.c.
+ */
+void
+hf_usb_device_compute_udi (HalDevice *device)
+{
+ g_return_if_fail(HAL_IS_DEVICE(device));
+
+ if (hal_device_has_capability(device, "hiddev"))
+ hf_device_set_full_udi(device, "%s_hiddev",
+ hal_device_property_get_string(device, "info.parent"));
+ else if (hal_device_has_capability(device, "video4linux"))
+ hf_device_set_full_udi(device, "%s_video4linux",
+ hal_device_property_get_string(device, "info.parent"));
+ else if (hal_device_has_property(device, "usb.interface.number"))
+ hf_device_set_full_udi(device, "%s_if%i",
+ hal_device_property_get_string(device, "info.parent"),
+ hal_device_property_get_int(device, "usb.interface.number"));
+ else
+ hf_device_set_udi(device, "usb_device_%x_%x_%s",
+ hal_device_property_get_int(device, "usb_device.vendor_id"),
+ hal_device_property_get_int(device, "usb_device.product_id"),
+ (hal_device_has_property(device, "usb_device.serial") &&
+ strcmp(hal_device_property_get_string(device, "usb_device.serial"), ""))
+ ? hal_device_property_get_string(device, "usb_device.serial")
+ : "noserial");
+}
+
+void
+hf_usb_add_webcam_properties (HalDevice *device)
+{
+ int unit;
+
+ g_return_if_fail(HAL_IS_DEVICE(device));
+
+ unit = hal_device_property_get_int(device, "freebsd.unit");
+ if (unit < 0)
+ unit = 0;
+
+ hal_device_property_set_string(device, "info.category", "video4linux");
+ hal_device_add_capability(device, "video4linux");
+ hf_device_property_set_string_printf(device, "video4linux.device", "/dev/video%i", unit);
+ hal_device_property_set_string(device, "info.product", "Video Device");
+}
diff --git a/hald/freebsd/hf-usb.h b/hald/freebsd/hf-usb.h
index edc9c6cc..37acedc6 100644
--- a/hald/freebsd/hf-usb.h
+++ b/hald/freebsd/hf-usb.h
@@ -34,4 +34,7 @@
extern HFHandler hf_usb_handler;
extern HFDevdHandler hf_usb_devd_handler;
+void hf_usb_device_compute_udi(HalDevice *device);
+void hf_usb_add_webcam_properties(HalDevice *device);
+
#endif /* _HF_USB_H */
diff --git a/hald/freebsd/hf-usb2.c b/hald/freebsd/hf-usb2.c
new file mode 100644
index 00000000..fff49e0a
--- /dev/null
+++ b/hald/freebsd/hf-usb2.c
@@ -0,0 +1,287 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hf-usb.c : USB support
+ *
+ * Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.org>
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libusb20.h>
+
+#include "../logger.h"
+#include "../osspec.h"
+
+#include "hf-usb.h"
+#include "hf-usb2.h"
+#include "hf-devtree.h"
+#include "hf-util.h"
+
+static struct libusb20_backend *hf_usb2_be = NULL;
+
+static void
+hf_usb2_copy_parent (HalDevice *parent,
+ const char *key,
+ gpointer user_data)
+{
+ HalDevice *device;
+
+ g_return_if_fail(HAL_IS_DEVICE(parent));
+ g_return_if_fail(HAL_IS_DEVICE(user_data));
+
+ device = HAL_DEVICE(user_data);
+
+ if (! strncmp(key, "usb_device.", strlen("usb_device.")))
+ hal_device_copy_property(parent, key, device, key);
+}
+
+static void
+hf_usb2_probe_interfaces(HalDevice *parent)
+{
+ int num_interfaces;
+ int i;
+
+ g_return_if_fail(HAL_IS_DEVICE(parent));
+
+ if (hal_device_property_get_bool(parent, "info.ignore"))
+ return;
+
+ num_interfaces = hal_device_property_get_int(parent,
+ "usb_device.num_interfaces");
+
+ for (i = 0; i < num_interfaces; i++)
+ {
+ HalDevice *device;
+
+ device = hf_device_new(parent);
+
+ hal_device_property_set_string(device, "info.subsystem", "usb");
+ hal_device_property_set_int(device, "usb.interface.number", i);
+ hal_device_property_foreach(parent, hf_usb2_copy_parent, device);
+ hal_device_copy_property(parent, "info.product", device, "info.product");
+ hal_device_copy_property(parent, "info.vendor", device, "info.vendor");
+
+ if (hf_device_preprobe(device))
+ {
+ const char *driver, *devname;
+
+ hf_runner_run_sync(device, 0, "hald-probe-usb2-interface", NULL);
+
+ devname = hal_device_property_get_string(device,
+ "usb.freebsd.devname");
+ if (devname)
+ hf_devtree_device_set_name(device, devname);
+
+ driver = hal_device_property_get_string(device, "freebsd.driver");
+ if (driver)
+ {
+ if (! strcmp(driver, "ukbd"))
+ hf_device_set_input(device, "keyboard", NULL);
+ else if (! strcmp(driver, "ums"))
+ {
+ hf_device_set_input(device, "mouse", devname);
+ hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL);
+ }
+ else if (! strcmp(driver, "uhid"))
+ {
+ hal_device_property_set_string(device, "info.category",
+ "hiddev");
+ hal_device_add_capability(device, "hiddev");
+ hf_device_property_set_string_printf(device, "hiddev.device",
+ "/dev/%s", devname);
+ hal_device_copy_property(device, "info.product", device,
+ "hiddev.product");
+ hf_runner_run_sync(device, 0, "hald-probe-hiddev", NULL);
+ }
+ else if (! strcmp(driver, "ldev"))
+ {
+ /* Linux driver (webcam) */
+
+ /*
+ * XXX This is a hack. Currently, all ldev devices are
+ * webcams. That may not always be the case. Hopefully,
+ * when other Linux driver support is added, there will be
+ * a sysctl or some other way to determine device class.
+ */
+ hf_usb_add_webcam_properties(device);
+ }
+ else if (! strcmp(driver, "pwc"))
+ {
+ /* Phillips Web Cam */
+ hf_usb_add_webcam_properties(device);
+ }
+ }
+
+ hf_usb_device_compute_udi(device);
+ hf_device_add(device);
+ }
+ }
+}
+
+static void
+hf_usb2_probe_device (HalDevice *parent, int bus, int addr)
+{
+ HalDevice *device;
+
+ g_return_if_fail(HAL_IS_DEVICE(parent));
+
+ device = hf_device_new(parent);
+
+ hal_device_property_set_string(device, "info.subsystem", "usb_device");
+ hal_device_property_set_int(device, "usb_device.bus_number", bus);
+ hal_device_property_set_int(device, "usb_device.level_number", addr - 1);
+ hal_device_property_set_int(device, "usb_device.port_number", addr);
+
+ if (hf_device_preprobe(device))
+ {
+ hf_runner_run_sync(device, 0, "hald-probe-usb2-device", NULL);
+ hf_usb_device_compute_udi(device);
+
+ hf_device_add(device);
+ }
+ else
+ return;
+
+ hf_usb2_probe_interfaces(device);
+}
+
+static void
+hf_usb2_privileged_init (void)
+{
+ hf_usb2_be = libusb20_be_alloc_default();
+ if (hf_usb2_be == NULL)
+ HAL_INFO(("unable to open USB backend: %s", g_strerror(errno)));
+}
+
+static void
+hf_usb2_probe (void)
+{
+ struct libusb20_device *pdev = NULL;
+
+ if (hf_usb2_be == NULL)
+ return;
+
+ while ((pdev = libusb20_be_device_foreach(hf_usb2_be, pdev)))
+ {
+ HalDevice *parent;
+ int bus, addr;
+
+ bus = libusb20_dev_get_bus_number(pdev);
+ addr = libusb20_dev_get_address(pdev);
+
+ if (addr == 1)
+ parent = hf_devtree_find_parent_from_info(hald_get_gdl(), "usbus", bus);
+ else
+ parent = hf_device_store_match(hald_get_gdl(), "usb_device.bus_number",
+ HAL_PROPERTY_TYPE_INT32, bus, "usb_device.port_number",
+ HAL_PROPERTY_TYPE_INT32, addr - 1, NULL);
+ if (! parent || hal_device_property_get_bool(parent, "info.ignore"))
+ continue;
+
+ hf_usb2_probe_device(parent, bus, addr);
+ }
+
+ libusb20_be_free(hf_usb2_be);
+ hf_usb2_be = NULL;
+}
+
+static gboolean
+hf_usb2_devd_add (const char *name,
+ GHashTable *params,
+ GHashTable *at,
+ const char *parent)
+{
+ HalDevice *parent_device;
+ int bus, addr, pbus, paddr;
+
+ if (strncmp(name, "ugen", strlen("ugen")))
+ return FALSE;
+ else if (strncmp(parent, "ugen", strlen("ugen")))
+ return TRUE;
+
+ if (sscanf(name, "ugen%i.%i", &bus, &addr) != 2)
+ return FALSE;
+
+ if (sscanf(parent, "ugen%i.%i", &pbus, &paddr) != 2)
+ return FALSE;
+
+ HAL_INFO(("received devd add event for device '%s' with parent '%s'",
+ name, parent));
+
+ parent_device = hf_device_store_match(hald_get_gdl(),
+ "usb_device.bus_number", HAL_PROPERTY_TYPE_INT32, pbus,
+ "usb_device.port_number", HAL_PROPERTY_TYPE_INT32, paddr, NULL);
+
+ if (parent_device && ! hal_device_property_get_bool(parent_device,
+ "info.ignore"))
+ {
+ hf_usb2_probe_device(parent_device, bus, addr);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+hf_usb2_devd_remove (const char *name,
+ GHashTable *params,
+ GHashTable *at,
+ const char *parent)
+{
+ HalDevice *device;
+ int bus, addr;
+
+ if (strncmp(name, "ugen", strlen("ugen")))
+ return FALSE;
+ else if (strncmp(parent, "ugen", strlen("ugen")))
+ return TRUE;
+
+ if (sscanf(name, "ugen%i.%i", &bus, &addr) != 2)
+ return FALSE;
+
+ HAL_INFO(("received devd remove event, device %s", name));
+
+ device = hf_device_store_match(hald_get_gdl(), "usb_device.bus_number",
+ HAL_PROPERTY_TYPE_INT32, bus, "usb_device.port_number",
+ HAL_PROPERTY_TYPE_INT32, addr, NULL);
+
+ if (device)
+ {
+ hf_device_remove_tree(device);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+HFHandler hf_usb2_handler = {
+ .privileged_init = hf_usb2_privileged_init,
+ .probe = hf_usb2_probe
+};
+
+HFDevdHandler hf_usb2_devd_handler = {
+ .add = hf_usb2_devd_add,
+ .remove = hf_usb2_devd_remove
+};
diff --git a/hald/freebsd/hf-usb2.h b/hald/freebsd/hf-usb2.h
new file mode 100644
index 00000000..0c2c03bd
--- /dev/null
+++ b/hald/freebsd/hf-usb2.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hf-usb.h : USB support
+ *
+ * Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.org>
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef _HF_USB2_H
+#define _HF_USB2_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "hf-osspec.h"
+#include "hf-devd.h"
+
+extern HFHandler hf_usb2_handler;
+extern HFDevdHandler hf_usb2_devd_handler;
+
+#endif /* _HF_USB2_H */
diff --git a/hald/freebsd/hf-util.c b/hald/freebsd/hf-util.c
index 96063601..aa54f578 100644
--- a/hald/freebsd/hf-util.c
+++ b/hald/freebsd/hf-util.c
@@ -326,24 +326,31 @@ hf_device_property_set_string_printf (HalDevice *device,
void
hf_device_set_input (HalDevice *device,
- const char *class,
+ const char *capability1,
+ const char *capability2,
const char *devname)
{
g_return_if_fail(HAL_IS_DEVICE(device));
hal_device_add_capability(device, "input");
+ if (capability1)
+ {
+ char *capability;
- if (class)
+ capability = g_strdup_printf("input.%s", capability1);
+ hal_device_add_capability(device, capability);
+ g_free(capability);
+ }
+ if (capability2)
{
- char *category;
+ char *capability;
- category = g_strdup_printf("input.%s", class);
- hal_device_property_set_string(device, "info.category", category);
- hal_device_add_capability(device, category);
- g_free(category);
+ capability = g_strdup_printf("input.%s", capability2);
+ hal_device_add_capability(device, capability);
+ g_free(capability);
}
- else
- hal_device_property_set_string(device, "info.category", "input");
+
+ hal_device_property_set_string(device, "info.category", "input");
if (devname)
hf_device_property_set_string_printf(device, "input.device", "/dev/%s", devname);
diff --git a/hald/freebsd/hf-util.h b/hald/freebsd/hf-util.h
index d4590ce6..3ac34b11 100644
--- a/hald/freebsd/hf-util.h
+++ b/hald/freebsd/hf-util.h
@@ -87,7 +87,8 @@ void hf_device_property_set_string_printf (HalDevice *device,
...) G_GNUC_PRINTF(3, 4);
void hf_device_set_input (HalDevice *device,
- const char *class,
+ const char *capability1,
+ const char *capability2,
const char *devname);
HalDevice *hf_device_store_get_parent (HalDeviceStore *store,
diff --git a/hald/freebsd/hf-volume.c b/hald/freebsd/hf-volume.c
index 3512a8aa..249d2bd1 100644
--- a/hald/freebsd/hf-volume.c
+++ b/hald/freebsd/hf-volume.c
@@ -45,6 +45,7 @@
#include "hf-util.h"
#define PROBE_VOLUME_TIMEOUT (HAL_HELPER_TIMEOUT * 6)
+#define HF_VOLUME_FUSE_DB "/tmp/.fuse-mnts"
static void
hf_volume_get_mounts (struct statfs **mounts, int *n_mounts)
@@ -60,6 +61,55 @@ hf_volume_get_mounts (struct statfs **mounts, int *n_mounts)
}
}
+static char *
+hf_volume_resolve_fuse (const char *special)
+{
+ gchar *contents;
+ gchar **lines;
+ gsize len;
+ int i;
+
+ g_return_val_if_fail(special != NULL, NULL);
+
+ if (! g_file_get_contents(HF_VOLUME_FUSE_DB, &contents, &len, NULL))
+ return g_strdup(special);
+
+ lines = g_strsplit(contents, "\n", 0);
+ g_free(contents);
+
+ for (i = 0; lines && lines[i]; i++)
+ {
+ gchar **fields;
+
+ fields = g_strsplit(lines[i], "=", 2);
+ if (fields && g_strv_length(fields) == 2)
+ {
+ if (strcmp(fields[0], special) == 0)
+ {
+ g_strfreev(fields);
+ g_strfreev(lines);
+ return g_strdup(fields[1]);
+ }
+ }
+ g_strfreev(fields);
+ }
+
+ g_strfreev(lines);
+
+ return g_strdup(special);
+}
+
+static char *
+hf_volume_resolve_special (const char *special)
+{
+ g_return_val_if_fail(special != NULL, NULL);
+
+ if (strstr(special, "fuse"))
+ return hf_volume_resolve_fuse(special);
+
+ return g_strdup(special);
+}
+
static const struct statfs *
hf_volume_mounts_find (const struct statfs *mounts,
int n_mounts,
@@ -71,8 +121,18 @@ hf_volume_mounts_find (const struct statfs *mounts,
g_return_val_if_fail(special != NULL, NULL);
for (i = 0; i < n_mounts; i++)
- if (! strcmp(mounts[i].f_mntfromname, special))
- return &mounts[i];
+ {
+ char *resolved;
+
+ resolved = hf_volume_resolve_special(mounts[i].f_mntfromname);
+ if (! strcmp(resolved, special))
+ {
+ g_free(resolved);
+ return &mounts[i];
+ }
+
+ g_free(resolved);
+ }
return NULL;
}
@@ -92,7 +152,13 @@ hf_volume_device_update_mount_properties (HalDevice *device,
special = hal_device_property_get_string(device, "block.device");
if (special)
- mount = hf_volume_mounts_find(mounts, n_mounts, special);
+ {
+ mount = hf_volume_mounts_find(mounts, n_mounts, special);
+ if (mount && strcmp(special, mount->f_mntfromname))
+ hal_device_property_set_string(device, "volume.freebsd.real_mounted_device", mount->f_mntfromname);
+ else
+ hal_device_property_remove(device, "volume.freebsd.real_mounted_device");
+ }
}
hal_device_property_set_bool(device, "volume.is_mounted", mount != NULL);
diff --git a/hald/freebsd/libprobe/hfp.c b/hald/freebsd/libprobe/hfp.c
index 7d16bae9..3c34b756 100644
--- a/hald/freebsd/libprobe/hfp.c
+++ b/hald/freebsd/libprobe/hfp.c
@@ -216,55 +216,59 @@ hfp_getenv_bool (const char *variable)
}
void
-hfp_gettimeofday (struct timeval *t)
+hfp_clock_gettime (struct timespec *t)
{
int status;
assert(t != NULL);
- status = gettimeofday(t, NULL);
+#ifdef CLOCK_MONOTONIC_FAST
+ status = clock_gettime(CLOCK_MONOTONIC_FAST, t);
+#else
+ status = clock_gettime(CLOCK_MONOTONIC, t);
+#endif
assert(status == 0);
}
-/* timeval functions from sys/kern/kern_time.c */
+/* timespec functions from sys/kern/kern_time.c */
static void
-hfp_timevalfix (struct timeval *t)
+hfp_timespecfix (struct timespec *t)
{
assert(t != NULL);
- if (t->tv_usec < 0)
+ if (t->tv_nsec < 0)
{
t->tv_sec--;
- t->tv_usec += 1000000;
+ t->tv_nsec += 1000000000;
}
- if (t->tv_usec >= 1000000)
+ if (t->tv_nsec >= 1000000000)
{
t->tv_sec++;
- t->tv_usec -= 1000000;
+ t->tv_nsec -= 1000000000;
}
}
void
-hfp_timevaladd (struct timeval *t1, const struct timeval *t2)
+hfp_timespecadd (struct timespec *t1, const struct timespec *t2)
{
assert(t1 != NULL);
assert(t2 != NULL);
t1->tv_sec += t2->tv_sec;
- t1->tv_usec += t2->tv_usec;
+ t1->tv_nsec += t2->tv_nsec;
- hfp_timevalfix(t1);
+ hfp_timespecfix(t1);
}
void
-hfp_timevalsub (struct timeval *t1, const struct timeval *t2)
+hfp_timespecsub (struct timespec *t1, const struct timespec *t2)
{
assert(t1 != NULL);
assert(t2 != NULL);
t1->tv_sec -= t2->tv_sec;
- t1->tv_usec -= t2->tv_usec;
+ t1->tv_nsec -= t2->tv_nsec;
- hfp_timevalfix(t1);
+ hfp_timespecfix(t1);
}
diff --git a/hald/freebsd/libprobe/hfp.h b/hald/freebsd/libprobe/hfp.h
index 1d958110..2332588c 100644
--- a/hald/freebsd/libprobe/hfp.h
+++ b/hald/freebsd/libprobe/hfp.h
@@ -29,8 +29,12 @@
#endif
#include <stdarg.h>
+#include <time.h>
#include <sys/types.h>
+#include <sys/param.h>
+#if __FreeBSD_version < 600000
#include <sys/time.h>
+#endif
#include "libhal/libhal.h"
@@ -84,14 +88,14 @@ void volume_id_log (const char *format, ...) HFP_GNUC_PRINTF(1, 2);
boolean hfp_getenv_bool (const char *variable);
-void hfp_gettimeofday (struct timeval *t);
-void hfp_timevaladd (struct timeval *t1, const struct timeval *t2);
-void hfp_timevalsub (struct timeval *t1, const struct timeval *t2);
+void hfp_clock_gettime (struct timespec *t);
+void hfp_timespecadd (struct timespec *t1, const struct timespec *t2);
+void hfp_timespecsub (struct timespec *t1, const struct timespec *t2);
/* from sys/time.h (_KERNEL) */
-#define hfp_timevalcmp(t1, t2, cmp) \
+#define hfp_timespeccmp(t1, t2, cmp) \
(((t1)->tv_sec == (t2)->tv_sec \
- ? ((t1)->tv_usec cmp (t2)->tv_usec) \
+ ? ((t1)->tv_nsec cmp (t2)->tv_nsec) \
: ((t1)->tv_sec cmp (t2)->tv_sec)))
#endif /* _HFP_H */
diff --git a/hald/freebsd/osspec.c b/hald/freebsd/osspec.c
index 38ab1813..0d35ac58 100644
--- a/hald/freebsd/osspec.c
+++ b/hald/freebsd/osspec.c
@@ -25,6 +25,7 @@
# include <config.h>
#endif
+#include <sys/param.h>
#include <string.h>
#include "../ids.h"
@@ -46,13 +47,21 @@
#include "hf-sound.h"
#include "hf-storage.h"
#include "hf-usb.h"
+#ifdef HAVE_LIBUSB20
+#include "hf-usb2.h"
+#endif
#include "hf-volume.h"
/* the order matters: PCI devices must be created before their children, etc */
static HFHandler *handlers[] = {
&hf_pci_handler,
&hf_devtree_handler,
+#if __FreeBSD_version < 800092
&hf_usb_handler,
+#endif
+#ifdef HAVE_LIBUSB20
+ &hf_usb2_handler,
+#endif
&hf_ata_handler,
&hf_scsi_handler,
&hf_storage_handler,
diff --git a/hald/freebsd/probing/Makefile.am b/hald/freebsd/probing/Makefile.am
index fdba1eb7..3e439b5f 100644
--- a/hald/freebsd/probing/Makefile.am
+++ b/hald/freebsd/probing/Makefile.am
@@ -9,11 +9,18 @@ AM_CPPFLAGS = \
if HALD_COMPILE_FREEBSD
libexec_PROGRAMS = \
- hald-probe-hiddev \
- hald-probe-scsi \
- hald-probe-smbios \
- hald-probe-storage \
+ hald-probe-hiddev \
+ hald-probe-mouse \
+ hald-probe-scsi \
+ hald-probe-smbios \
+ hald-probe-storage \
hald-probe-volume
+
+if HAVE_LIBUSB20
+libexec_PROGRAMS += \
+ hald-probe-usb2-device \
+ hald-probe-usb2-interface
+endif
endif
hald_probe_hiddev_SOURCES = probe-hiddev.c
@@ -21,6 +28,25 @@ hald_probe_hiddev_LDADD = \
$(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la \
-lusbhid
+if HAVE_LIBUSB20
+hald_probe_usb2_device_SOURCES = probe-usb2-device.c
+hald_probe_usb2_device_LDADD = \
+ $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la \
+ @LIBUSB20_LIBS@
+
+hald_probe_usb2_interface_SOURCES = probe-usb2-interface.c
+hald_probe_usb2_interface_LDADD = \
+ $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la \
+ @LIBUSB20_LIBS@
+endif
+
+hald_probe_mouse_SOURCES = probe-mouse.c
+hald_probe_mouse_CPPFLAGS = $(AM_CPPFLAGS) @GLIB_CFLAGS@
+hald_probe_mouse_LDADD = \
+ @GLIB_LIBS@ \
+ $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la \
+ -lutil
+
hald_probe_smbios_SOURCES = probe-smbios.c
hald_probe_smbios_LDADD = \
$(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la
@@ -41,4 +67,5 @@ hald_probe_volume_CPPFLAGS = $(AM_CPPFLAGS) @GLIB_CFLAGS@ @VOLUME_ID_CFLAGS@
hald_probe_volume_LDADD = \
@GLIB_LIBS@ \
@VOLUME_ID_LIBS@ \
+ -lufs \
$(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la
diff --git a/hald/freebsd/probing/probe-hiddev.c b/hald/freebsd/probing/probe-hiddev.c
index e9b5016b..f0c598b3 100644
--- a/hald/freebsd/probing/probe-hiddev.c
+++ b/hald/freebsd/probing/probe-hiddev.c
@@ -25,12 +25,21 @@
# include <config.h>
#endif
+#include <sys/param.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
+#ifndef HAVE_LIBUSB20
#include <sys/ioctl.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbhid.h>
+#else
+#if __FreeBSD_version >= 800064
+#include <dev/usb/usbhid.h>
+#else
+#include <dev/usb2/include/usb2_hid.h>
+#endif
+#endif
#include <usbhid.h>
#include "../libprobe/hfp.h"
@@ -65,7 +74,12 @@ main (int argc, char **argv)
/* give a meaningful process title for ps(1) */
setproctitle("%s", device_file);
+#ifdef HAVE_LIBUSB20
+ report_id = hid_get_report_id(fd);
+ if (report_id == -1)
+#else
if (ioctl(fd, USB_GET_REPORT_ID, &report_id) < 0)
+#endif
goto end;
hid_init(NULL);
@@ -118,30 +132,22 @@ main (int argc, char **argv)
hid_dispose_report_desc(report_desc);
- if (is_keyboard || is_mouse || is_joystick)
+ if (is_keyboard || is_mouse || is_joystick || is_keypad)
{
libhal_device_add_capability(hfp_ctx, hfp_udi, "input", &hfp_error);
+ libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "input", &hfp_error);
libhal_device_set_property_string(hfp_ctx, hfp_udi, "input.device", device_file, &hfp_error);
}
if (is_keyboard)
- {
libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keyboard", &hfp_error);
- libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "input.keyboard", &hfp_error);
- }
if (is_keypad)
libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keypad", &hfp_error);
if (is_keyboard || is_keypad)
libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keys", &hfp_error);
if (is_mouse)
- {
libhal_device_add_capability(hfp_ctx, hfp_udi, "input.mouse", &hfp_error);
- libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "input.mouse", &hfp_error);
- }
if (is_joystick)
- {
libhal_device_add_capability(hfp_ctx, hfp_udi, "input.joystick", &hfp_error);
- libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "input.joystick", &hfp_error);
- }
end:
return 0;
diff --git a/hald/freebsd/probing/probe-mouse.c b/hald/freebsd/probing/probe-mouse.c
new file mode 100644
index 00000000..a2cffc10
--- /dev/null
+++ b/hald/freebsd/probing/probe-mouse.c
@@ -0,0 +1,312 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * probe-hiddev.c : Mouse prober
+ *
+ * Copyright (C) 2008 Joe Marcus Clarke <marcus@FreeBSD.org>
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/param.h>
+#if __FreeBSD_version >= 800058
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+#include <libutil.h>
+#endif
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <glib.h>
+
+#include "../libprobe/hfp.h"
+
+#if __FreeBSD_version < 800058
+#define CMD "/usr/bin/fstat %s"
+#endif
+
+#define MOUSE_DRIVER "mouse"
+#define MOUSED_DEVICE "/dev/sysmouse"
+#define MOUSED_PROC_NAME "moused"
+#define XORG_PROC_NAME "Xorg"
+
+#if __FreeBSD_version >= 800058
+static struct kinfo_proc *
+hfp_kinfo_getproc (int *cntp)
+{
+ int mib[3];
+ int error;
+ int cnt;
+ size_t len;
+ char *buf, *bp, *eb;
+ struct kinfo_proc *kip, *kp, *ki;
+
+ *cntp = 0;
+
+ len = 0;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PROC;
+
+ error = sysctl(mib, 3, NULL, &len, NULL, 0);
+ if (error)
+ return NULL;
+
+ len = len * 4 / 3;
+ buf = (char *) g_malloc(len);
+ if (buf == NULL)
+ return NULL;
+
+ error = sysctl(mib, 3, buf, &len, NULL, 0);
+ if (error)
+ {
+ g_free(buf);
+ return NULL;
+ }
+
+ cnt = 0;
+ bp = buf;
+ eb = buf + len;
+ while (bp < eb)
+ {
+ ki = (struct kinfo_proc *) (uintptr_t) bp;
+ bp += ki->ki_structsize;
+ cnt++;
+ }
+
+ kip = calloc(cnt, sizeof (*kip));
+ if (kip == NULL)
+ {
+ g_free(buf);
+ return NULL;
+ }
+
+ bp = buf;
+ eb = buf + len;
+ kp = kip;
+ while (bp < eb)
+ {
+ ki = (struct kinfo_proc *) (uintptr_t) bp;
+ memcpy(kp, ki, ki->ki_structsize);
+ bp += ki->ki_structsize;
+ kp->ki_structsize = sizeof(*kp);
+ kp++;
+ }
+
+ g_free(buf);
+ *cntp = cnt;
+ return kip;
+}
+
+static gboolean
+device_opened_by_proc (const char *device, const char *proc)
+{
+ struct kinfo_proc *kip, *pfreep;
+ int cnt, i;
+
+ pfreep = hfp_kinfo_getproc(&cnt);
+ if (pfreep == NULL)
+ return FALSE;
+
+ for (i = 0; i < cnt; i++)
+ {
+ kip = &pfreep[i];
+
+ if (! strcmp(kip->ki_comm, proc))
+ {
+ struct kinfo_file *kif, *ffreep;
+ int fcnt, j;
+
+ ffreep = kinfo_getfile(kip->ki_pid, &fcnt);
+ if (ffreep == NULL)
+ continue;
+ for (j = 0; j < fcnt; j++)
+ {
+ kif = &ffreep[j];
+
+ if (kif->kf_type == KF_TYPE_VNODE &&
+ ! strcmp(kif->kf_path, device))
+ {
+ g_free(ffreep);
+ g_free(pfreep);
+ return TRUE;
+ }
+ }
+ g_free(ffreep);
+ }
+ }
+ g_free(pfreep);
+
+ return FALSE;
+}
+#else
+static gboolean
+device_opened_by_proc (const char *device, const char *proc)
+{
+ char **lines;
+ char *output = NULL;
+ char *cmd;
+ int i;
+ gboolean found = FALSE;
+
+ cmd = g_strdup_printf(CMD, device);
+
+ if (! g_spawn_command_line_sync(cmd, &output, NULL, NULL, NULL))
+ {
+ g_free(cmd);
+ goto done;
+ }
+ g_free(cmd);
+
+ if (! output || strlen(output) == 0)
+ goto done;
+
+ lines = g_strsplit(output, "\n", 0);
+ if (g_strv_length(lines) < 2)
+ {
+ g_strfreev(lines);
+ goto done;
+ }
+
+ for (i = 1; lines[i]; i++)
+ {
+ char **fields;
+ guint len;
+ guint j;
+
+ fields = g_strsplit_set(lines[i], " ", 0);
+ len = g_strv_length(fields);
+ if (len < 3)
+ {
+ g_strfreev(fields);
+ continue;
+ }
+ for (j = 1; j < len && fields[j] && *fields[j] == '\0'; j++)
+ ;
+ if (j < len && fields[j] && ! strcmp(fields[j], proc))
+ {
+ found = TRUE;
+ g_strfreev(fields);
+ break;
+ }
+ g_strfreev(fields);
+ }
+
+ g_strfreev(lines);
+
+done:
+ g_free(output);
+
+ return found;
+}
+#endif
+
+static void
+probe_mouse (const char *device_file)
+{
+ gboolean found;
+ char **udis;
+ char *driver;
+ int num_udis;
+
+ driver = libhal_device_get_property_string(hfp_ctx, hfp_udi,
+ "input.x11_driver", &hfp_error);
+ dbus_error_free(&hfp_error);
+
+ found = device_opened_by_proc(device_file, XORG_PROC_NAME);
+ if (found)
+ {
+ if (driver)
+ {
+ libhal_device_remove_property(hfp_ctx, hfp_udi, "input.x11_driver",
+ &hfp_error);
+ dbus_error_free(&hfp_error);
+ g_free(driver);
+ }
+ return;
+ }
+
+ found = device_opened_by_proc(device_file, MOUSED_PROC_NAME);
+ if (found)
+ {
+ libhal_device_set_property_string(hfp_ctx, hfp_udi, "input.device",
+ MOUSED_DEVICE, &hfp_error);
+ dbus_error_free(&hfp_error);
+ found = device_opened_by_proc(MOUSED_DEVICE, XORG_PROC_NAME);
+ if (! found)
+ {
+ udis = libhal_manager_find_device_string_match(hfp_ctx,
+ "input.device",
+ MOUSED_DEVICE,
+ &num_udis,
+ &hfp_error);
+ dbus_error_free(&hfp_error);
+ if (num_udis > 0 && udis != NULL && !strcmp(udis[0], hfp_udi)) {
+ libhal_device_set_property_string(hfp_ctx, hfp_udi,
+ "input.x11_driver",
+ MOUSE_DRIVER, &hfp_error);
+ dbus_error_free(&hfp_error);
+ libhal_free_string_array(udis);
+ }
+ }
+ else if (driver)
+ {
+ libhal_device_remove_property(hfp_ctx, hfp_udi, "input.x11_driver",
+ &hfp_error);
+ dbus_error_free(&hfp_error);
+ }
+ }
+ else
+ {
+ libhal_device_set_property_string(hfp_ctx, hfp_udi, "input.device",
+ device_file, &hfp_error);
+ dbus_error_free(&hfp_error);
+ libhal_device_set_property_string(hfp_ctx, hfp_udi, "input.x11_driver",
+ MOUSE_DRIVER, &hfp_error);
+ dbus_error_free(&hfp_error);
+ }
+
+ g_free(driver);
+}
+
+int
+main (int argc, char **argv)
+{
+ char *device_file;
+
+ if (! hfp_init(argc, argv))
+ goto end;
+
+ device_file = getenv("HAL_PROP_FREEBSD_DEVICE_FILE");
+ if (! device_file)
+ goto end;
+
+ /* give a meaningful process title for ps(1) */
+ setproctitle("%s", device_file);
+
+ /* Sleep for a second to give moused a chance to connect. */
+ sleep(1);
+ probe_mouse(device_file);
+
+ end:
+ return 0;
+}
diff --git a/hald/freebsd/probing/probe-storage.c b/hald/freebsd/probing/probe-storage.c
index b9498c4d..a0e7f773 100644
--- a/hald/freebsd/probing/probe-storage.c
+++ b/hald/freebsd/probing/probe-storage.c
@@ -31,6 +31,8 @@
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/disk.h>
#include <netinet/in.h>
#include <glib.h>
#include <libvolume_id.h>
@@ -211,7 +213,26 @@ main (int argc, char **argv)
goto end;
if (hfp_cdrom_test_unit_ready(cdrom))
- ret = 2; /* has media */
+ {
+ int fd;
+ off_t size;
+
+ libhal_device_set_property_bool(hfp_ctx, hfp_udi, "storage.removable.media_available", TRUE, &hfp_error);
+ fd = open(device_file, O_RDONLY | O_NONBLOCK);
+ if (fd > -1)
+ {
+ if (ioctl (fd, DIOCGMEDIASIZE, &size) == 0)
+ {
+ libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "storage.removable.media_size", size, &hfp_error);
+ }
+ close(fd);
+ }
+ ret = 2; /* has media */
+ }
+ else
+ {
+ libhal_device_set_property_bool(hfp_ctx, hfp_udi, "storage.removable.media_available", FALSE, &hfp_error);
+ }
hfp_cdrom_free(cdrom);
}
diff --git a/hald/freebsd/probing/probe-usb2-device.c b/hald/freebsd/probing/probe-usb2-device.c
new file mode 100644
index 00000000..129a1b1f
--- /dev/null
+++ b/hald/freebsd/probing/probe-usb2-device.c
@@ -0,0 +1,208 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * probe-usb2-device.c : USB2 Device poller
+ *
+ * Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.org>
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <libusb20_desc.h>
+#include <libusb20.h>
+#if __FreeBSD_version >= 800064
+#include <dev/usb/usb_ioctl.h>
+#else
+#include <dev/usb2/include/usb2_standard.h>
+#include <dev/usb2/include/usb2_ioctl.h>
+#endif
+
+#include "../libprobe/hfp.h"
+
+int
+main(int argc, char **argv)
+{
+ struct libusb20_backend *pbe = NULL;
+ struct libusb20_device *pdev = NULL;
+ char *busstr, *addrstr;
+ int bus, addr;
+
+ if (! hfp_init(argc, argv))
+ goto end;
+
+ pbe = libusb20_be_alloc_default();
+ if (pbe == NULL)
+ goto end;
+
+ busstr = getenv("HAL_PROP_USB_DEVICE_BUS_NUMBER");
+ if (! busstr)
+ goto end;
+
+ addrstr = getenv("HAL_PROP_USB_DEVICE_PORT_NUMBER");
+ if (! addrstr)
+ goto end;
+
+ bus = atoi(busstr);
+ addr = atoi(addrstr);
+
+ while ((pdev = libusb20_be_device_foreach(pbe, pdev)))
+ {
+ struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
+ struct LIBUSB20_CONFIG_DESC_DECODED *cdesc;
+#if __FreeBSD_version >= 800092
+ struct usb_device_info di;
+#else
+ struct usb2_device_info di;
+#endif
+ struct libusb20_config *pcfg = NULL;
+ int curr_config;
+ int bcdspeed = 0;
+ uint8_t temp_string[256];
+ double speed = 0.0;
+ double version = 1.0;
+
+ if (libusb20_dev_get_bus_number(pdev) != bus ||
+ libusb20_dev_get_address(pdev) != addr)
+ continue;
+
+ if (libusb20_dev_open(pdev, 0))
+ continue;
+
+ ddesc = libusb20_dev_get_device_desc(pdev);
+ curr_config = libusb20_dev_get_config_index(pdev);
+ pcfg = libusb20_dev_alloc_config(pdev, curr_config);
+ cdesc = &(pcfg->desc);
+
+ if (pcfg == NULL || libusb20_dev_get_info(pdev, &di))
+ {
+ free(pcfg);
+ continue;
+ }
+
+ memset(temp_string, 0, sizeof(temp_string));
+
+ if (cdesc->iConfiguration !=0)
+ libusb20_dev_req_string_simple_sync(pdev, cdesc->iConfiguration,
+ temp_string, sizeof(temp_string));
+
+ libhal_device_set_property_string(hfp_ctx, hfp_udi,
+ "usb_device.configuration", (char *) temp_string, &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb_device.configuration_value", cdesc->bConfigurationValue,
+ &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb_device.num_configurations", ddesc->bNumConfigurations,
+ &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb_device.device_class", di.udi_class, &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb_device.device_subclass", di.udi_subclass, &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb_device.device_protocol", di.udi_protocol, &hfp_error);
+ libhal_device_set_property_bool(hfp_ctx, hfp_udi,
+ "usb_device.is_self_powered",
+ di.udi_power == 0 ? TRUE : FALSE, &hfp_error);
+ libhal_device_set_property_bool(hfp_ctx, hfp_udi,
+ "usb_device.can_wake_up",
+ (cdesc->bmAttributes & UC_REMOTE_WAKEUP) != 0 ? TRUE : FALSE,
+ &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb_device.max_power", di.udi_power, &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb_device.num_interfaces", pcfg->num_interface, &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb_device.num_ports", di.udi_nports, &hfp_error);
+
+ switch (libusb20_dev_get_speed(pdev))
+ {
+ case LIBUSB20_SPEED_LOW:
+ speed = 1.5;
+ bcdspeed = 0x00150;
+ break;
+ case LIBUSB20_SPEED_FULL:
+ speed = 12.0;
+ bcdspeed = 0x01200;
+ break;
+ case LIBUSB20_SPEED_HIGH:
+ speed = 480.0;
+ bcdspeed = 0x48000;
+ break;
+ case LIBUSB20_SPEED_SUPER:
+ speed = 4800.0;
+ bcdspeed = 0x480000;
+ break;
+ default:
+ ;
+ }
+
+ libhal_device_set_property_double(hfp_ctx, hfp_udi, "usb_device.speed",
+ speed, &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi, "usb_device.speed_bcd",
+ bcdspeed, &hfp_error);
+
+ switch (ddesc->bcdUSB)
+ {
+ case UD_USB_2_0:
+ version = 2.0;
+ break;
+ case UD_USB_3_0:
+ version = 3.0;
+ break;
+ default:
+ version = 1.0;
+ break;
+ }
+
+ libhal_device_set_property_double(hfp_ctx, hfp_udi,
+ "usb_device.version", version, &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb_device.product_id", di.udi_productNo, &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb_device.vendor_id", di.udi_vendorNo, &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb_device.device_revision_bcd", ddesc->bcdUSB, &hfp_error);
+ libhal_device_set_property_string(hfp_ctx, hfp_udi,
+ "usb_device.serial", di.udi_serial, &hfp_error);
+ libhal_device_set_property_string(hfp_ctx, hfp_udi,
+ "usb_device.product", di.udi_product, &hfp_error);
+ libhal_device_set_property_string(hfp_ctx, hfp_udi,
+ "usb_device.vendor", di.udi_vendor, &hfp_error);
+
+ libhal_device_set_property_string(hfp_ctx, hfp_udi,
+ "info.product", di.udi_product, &hfp_error);
+ libhal_device_set_property_string(hfp_ctx, hfp_udi,
+ "info.vendor", di.udi_vendor, &hfp_error);
+
+ libusb20_dev_close(pdev);
+ free(pcfg);
+ }
+end:
+ if (pbe)
+ libusb20_be_free(pbe);
+
+ return 0;
+}
diff --git a/hald/freebsd/probing/probe-usb2-interface.c b/hald/freebsd/probing/probe-usb2-interface.c
new file mode 100644
index 00000000..f57bb77a
--- /dev/null
+++ b/hald/freebsd/probing/probe-usb2-interface.c
@@ -0,0 +1,140 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * probe-usb2-interface.c : USB2 Interface poller
+ *
+ * Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.org>
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <libusb20_desc.h>
+#include <libusb20.h>
+#if __FreeBSD_version >= 800064
+#include <dev/usb/usb_ioctl.h>
+#else
+#include <dev/usb2/include/usb2_standard.h>
+#include <dev/usb2/include/usb2_ioctl.h>
+#endif
+
+#include "../libprobe/hfp.h"
+
+int
+main(int argc, char **argv)
+{
+ struct libusb20_backend *pbe = NULL;
+ struct libusb20_device *pdev = NULL;
+ char *busstr, *addrstr, *ifacestr;
+ int bus, addr, iface;
+
+ if (! hfp_init(argc, argv))
+ goto end;
+
+ pbe = libusb20_be_alloc_default();
+ if (pbe == NULL)
+ goto end;
+
+ busstr = getenv("HAL_PROP_USB_DEVICE_BUS_NUMBER");
+ if (! busstr)
+ goto end;
+
+ addrstr = getenv("HAL_PROP_USB_DEVICE_PORT_NUMBER");
+ if (! addrstr)
+ goto end;
+
+ ifacestr = getenv("HAL_PROP_USB_INTERFACE_NUMBER");
+ if (! ifacestr)
+ goto end;
+
+ bus = atoi(busstr);
+ addr = atoi(addrstr);
+ iface = atoi(ifacestr);
+
+ while ((pdev = libusb20_be_device_foreach(pbe, pdev)))
+ {
+ struct LIBUSB20_INTERFACE_DESC_DECODED *idesc;
+ struct libusb20_config *pcfg = NULL;
+ struct libusb20_interface *pif;
+ uint8_t temp_string[256];
+ char ifdrv[128];
+ int curr_config;
+
+ if (libusb20_dev_get_bus_number(pdev) != bus ||
+ libusb20_dev_get_address(pdev) != addr)
+ continue;
+
+ if (libusb20_dev_open(pdev, 0))
+ continue;
+
+ curr_config = libusb20_dev_get_config_index(pdev);
+ pcfg = libusb20_dev_alloc_config(pdev, curr_config);
+ if (! pcfg)
+ continue;
+
+ pif = pcfg->interface + iface;
+
+ idesc = &pif->desc;
+
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb.interface.class", idesc->bInterfaceClass, &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb.interface.subclass", idesc->bInterfaceSubClass, &hfp_error);
+ libhal_device_set_property_int(hfp_ctx, hfp_udi,
+ "usb.interface.protocol", idesc->bInterfaceProtocol, &hfp_error);
+
+ memset(temp_string, 0, sizeof(temp_string));
+ if (idesc->iInterface != 0)
+ libusb20_dev_req_string_simple_sync(pdev, idesc->iInterface,
+ temp_string, sizeof(temp_string));
+
+ libhal_device_set_property_string(hfp_ctx, hfp_udi,
+ "usb.interface.description", (char *) temp_string, &hfp_error);
+
+ memset(ifdrv, 0, sizeof(ifdrv));
+ libusb20_dev_get_iface_desc(pdev, iface, ifdrv, sizeof(ifdrv));
+ if (ifdrv[0] != '\0')
+ {
+ char *ifdesc;
+
+ ifdesc = strchr(ifdrv, ':');
+ if (ifdesc)
+ {
+ *ifdesc = '\0';
+ libhal_device_set_property_string(hfp_ctx, hfp_udi,
+ "usb.freebsd.devname", ifdrv, &hfp_error);
+ }
+ }
+
+ free(pcfg);
+ }
+
+end:
+ if (pbe)
+ libusb20_be_free(pbe);
+
+ return 0;
+}
diff --git a/hald/freebsd/probing/probe-volume.c b/hald/freebsd/probing/probe-volume.c
index ee019279..73e03182 100644
--- a/hald/freebsd/probing/probe-volume.c
+++ b/hald/freebsd/probing/probe-volume.c
@@ -36,7 +36,12 @@
#include <sys/disk.h>
#include <sys/cdio.h>
#include <sys/param.h>
+#include <sys/mount.h>
#include <sys/types.h>
+#include <ufs/ufs/ufsmount.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+#include <libufs.h>
#include <isofs/cd9660/iso.h>
#include <glib.h>
#include <libvolume_id.h>
@@ -59,7 +64,7 @@ struct iso_path_table_entry
};
#define ISO_PATH_TABLE_ENTRY_SIZE 8
-#if __FreeBSD_version < 600101
+#if (__FreeBSD_version < 600101) && (__FreeBSD_kernel_version < 600101)
static uint32_t
isonum_731(unsigned char *p)
{
@@ -502,7 +507,8 @@ main (int argc, char **argv)
hfp_cdrom_free(cdrom);
}
- if (has_data)
+ if (has_data && vid && (! strcmp(vid->type, "iso9660") ||
+ ! strcmp(vid->type, "udf")))
hf_probe_volume_advanced_disc_detect(fd);
}
else
@@ -555,6 +561,46 @@ main (int argc, char **argv)
libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", has_children || is_swap, &hfp_error);
+ if (vid && ! strcmp (vid->type, "ufs"))
+ {
+ struct uufsd ufsdisk;
+
+ if (ufs_disk_fillout(&ufsdisk, device_file) == 0)
+ {
+ char ufsid[64];
+ char **ufs_devs = NULL;
+ int num_udis;
+ int i;
+
+ snprintf(ufsid, sizeof(ufsid), "%08x%08x", ufsdisk.d_fs.fs_id[0], ufsdisk.d_fs.fs_id[1]);
+ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.freebsd.ufsid", ufsid, &hfp_error);
+ ufs_devs = libhal_manager_find_device_string_match(hfp_ctx,
+ "volume.freebsd.ufsid",
+ ufsid,
+ &num_udis,
+ &hfp_error);
+ dbus_error_free(&hfp_error);
+ for (i = 0; i < num_udis; i++)
+ {
+ if (ufs_devs[i] != NULL)
+ {
+ gboolean mounted;
+
+ mounted = libhal_device_get_property_bool(hfp_ctx, ufs_devs[i], "volume.is_mounted", &hfp_error);
+ dbus_error_free(&hfp_error);
+ if (mounted)
+ {
+ libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", TRUE, &hfp_error);
+ dbus_error_free(&hfp_error);
+ }
+ }
+ }
+ if (ufs_devs)
+ libhal_free_string_array(ufs_devs);
+ ufs_disk_close(&ufsdisk);
+ }
+ }
+
if (has_children)
usage = "partitiontable";
else if (is_swap)
diff --git a/hald/hald.c b/hald/hald.c
index cc47567a..a7f9c3ad 100644
--- a/hald/hald.c
+++ b/hald/hald.c
@@ -538,8 +538,6 @@ main (int argc, char *argv[])
{
GMainLoop *loop;
guint sigterm_iochn_listener_source_id;
- char *path;
- char newpath[512];
guint opt_child_timeout;
#ifdef HAVE_POLKIT
PolKitError *p_error;
@@ -574,20 +572,15 @@ main (int argc, char *argv[])
* to include this at the end (since we want to overide in
* run-hald.sh and friends)
*/
- path = getenv ("PATH");
- if (path != NULL) {
- g_strlcpy (newpath, path, sizeof (newpath));
- g_strlcat (newpath, ":", sizeof (newpath));
- } else {
- /* No PATH was set */
- newpath[0] = '\0';
- }
-
- g_strlcat (newpath, PACKAGE_LIBEXEC_DIR, sizeof (newpath));
- g_strlcat (newpath, ":", sizeof (newpath));
- g_strlcat (newpath, PACKAGE_SCRIPT_DIR, sizeof (newpath));
+ GString *path = g_string_new(getenv("PATH"));
+ if ( path->len > 0 ) {
+ g_string_append_c(path, ':');
+ }
+
+ g_string_append_printf(path, "%s:%s", PACKAGE_LIBEXEC_DIR, PACKAGE_SCRIPT_DIR);
- setenv ("PATH", newpath, TRUE);
+ setenv ("PATH", path->str, TRUE);
+ g_string_free(path, TRUE);
/* set the default child timeout to 250 seconds */
opt_child_timeout = 250;