pkgsrc-WIP-changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Modify drvctl.c to not read from /dev/drvctl but use information from devpubd because information of device-attach/device-detach sequence is missing, when devpubd is used this way, a fifo is created in /tmp the /libexec/devpubd-hooks/03-hal pushes correct sequence of attach/detach device into the fifo, than it is read by drvctl.c. Also a new /etc/rc.d/hal is modified so that drvctl.c does not block on read from an empty fifo. the Patch is in the patches directory => patch-hald_netbsd_drvctl.c
- To: pkgsrc-wip-changes%NetBSD.org@localhost
- Subject: Modify drvctl.c to not read from /dev/drvctl but use information from devpubd because information of device-attach/device-detach sequence is missing, when devpubd is used this way, a fifo is created in /tmp the /libexec/devpubd-hooks/03-hal pushes correct sequence of attach/detach device into the fifo, than it is read by drvctl.c. Also a new /etc/rc.d/hal is modified so that drvctl.c does not block on read from an empty fifo. the Patch is in the patches directory => patch-hald_netbsd_drvctl.c
- From: sergio lenzi <nervoso%k1.com.br@localhost>
- Date: Tue, 29 Sep 2020 20:03:56 +0000
Module Name: pkgsrc-wip
Committed By: sergio lenzi <nervoso%k1.com.br@localhost>
Pushed By: lenzi.sergio
Date: Tue Sep 29 17:03:56 2020 -0300
Changeset: cdb3d27492001f3f3ec7415cabb2eaf65f5d2d63
Added Files:
hal/DESCR
hal/MESSAGE.NetBSD
hal/Makefile
hal/PLIST
hal/PLIST.DragonFly
hal/PLIST.FreeBSD
hal/PLIST.Linux
hal/PLIST.NetBSD
hal/buildlink3.mk
hal/distinfo
hal/files/03-hal
hal/files/hal.sh
hal/files/hald-netbsd/Makefile.am
hal/files/hald-netbsd/addons/Makefile.am
hal/files/hald-netbsd/addons/addon-storage.c
hal/files/hald-netbsd/devinfo.c
hal/files/hald-netbsd/devinfo.h
hal/files/hald-netbsd/devinfo_acpi.h
hal/files/hald-netbsd/devinfo_audio.c
hal/files/hald-netbsd/devinfo_audio.h
hal/files/hald-netbsd/devinfo_cpu.h
hal/files/hald-netbsd/devinfo_mass.c
hal/files/hald-netbsd/devinfo_mass.h
hal/files/hald-netbsd/devinfo_misc.c
hal/files/hald-netbsd/devinfo_misc.h
hal/files/hald-netbsd/devinfo_optical.c
hal/files/hald-netbsd/devinfo_optical.h
hal/files/hald-netbsd/devinfo_pci.c
hal/files/hald-netbsd/devinfo_pci.h
hal/files/hald-netbsd/devinfo_storage.c
hal/files/hald-netbsd/devinfo_storage.h
hal/files/hald-netbsd/devinfo_usb.c
hal/files/hald-netbsd/devinfo_usb.h
hal/files/hald-netbsd/devinfo_video.c
hal/files/hald-netbsd/devinfo_video.h
hal/files/hald-netbsd/drvctl.c
hal/files/hald-netbsd/drvctl.h
hal/files/hald-netbsd/envsys.c
hal/files/hald-netbsd/envsys.h
hal/files/hald-netbsd/hal-file-monitor.c
hal/files/hald-netbsd/hotplug.c
hal/files/hald-netbsd/hotplug.h
hal/files/hald-netbsd/osspec.c
hal/files/hald-netbsd/osspec_netbsd.h
hal/files/hald-netbsd/probing/Makefile.am
hal/files/hald-netbsd/probing/cdutils.c
hal/files/hald-netbsd/probing/cdutils.h
hal/files/hald-netbsd/probing/fsutils.c
hal/files/hald-netbsd/probing/fsutils.h
hal/files/hald-netbsd/probing/probe-storage.c
hal/files/hald-netbsd/probing/probe-volume.c
hal/files/hald-netbsd/vfsstat.c
hal/files/hald-netbsd/vfsstat.h
hal/files/smf/hal.sh
hal/files/smf/manifest.xml
hal/files/tools-netbsd/Makefile.am
hal/files/tools-netbsd/hal-system-power-reboot-netbsd
hal/files/tools-netbsd/hal-system-power-shutdown-netbsd
hal/files/tools-netbsd/hal-system-power-suspend-netbsd
hal/patches/patch-Makefile.am
hal/patches/patch-configure.in
hal/patches/patch-fdi_policy_10osvendor_20-storage-methods.fdi
hal/patches/patch-hald_Makefile.am
hal/patches/patch-hald_device__info.c
hal/patches/patch-hald_freebsd_addons_addon-mouse.c
hal/patches/patch-hald_freebsd_addons_addon-storage.c
hal/patches/patch-hald_freebsd_hf-ata.c
hal/patches/patch-hald_freebsd_hf-devd.c
hal/patches/patch-hald_freebsd_hf-pci.c
hal/patches/patch-hald_freebsd_hf-storage.c
hal/patches/patch-hald_freebsd_hf-usb.c
hal/patches/patch-hald_freebsd_hf-usb2.c
hal/patches/patch-hald_freebsd_hf-volume.c
hal/patches/patch-hald_freebsd_libprobe_hfp-cdrom.c
hal/patches/patch-hald_freebsd_probing_Makefile.am
hal/patches/patch-hald_freebsd_probing_probe-hiddev.c
hal/patches/patch-hald_freebsd_probing_probe-storage.c
hal/patches/patch-hald_freebsd_probing_probe-usb2-device.c
hal/patches/patch-hald_freebsd_probing_probe-usb2-interface.c
hal/patches/patch-hald_freebsd_probing_probe-volume.c
hal/patches/patch-hald_linux_addons_addon-acpi-buttons-toshiba.c
hal/patches/patch-hald_linux_addons_addon-cpufreq.c
hal/patches/patch-hald_linux_addons_addon-dell-backlight.cpp
hal/patches/patch-hald_linux_addons_addon-generic-backlight.c
hal/patches/patch-hald_linux_addons_addon-imac-backlight.c
hal/patches/patch-hald_linux_addons_addon-input.c
hal/patches/patch-hald_linux_addons_addon-ipw-killswitch.c
hal/patches/patch-hald_linux_addons_addon-leds.c
hal/patches/patch-hald_linux_addons_addon-macbookpro-backlight.c
hal/patches/patch-hald_linux_addons_addon-omap-backlight.c
hal/patches/patch-hald_linux_addons_addon-rfkill-killswitch.c
hal/patches/patch-hald_linux_addons_addon-storage.c
hal/patches/patch-hald_linux_addons_addon-usb-csr.c
hal/patches/patch-hald_linux_probing_probe-video4linux.c
hal/patches/patch-hald_netbsd_devinfo__mass.c
hal/patches/patch-hald_netbsd_drvctl.c
hal/patches/patch-libhal_libhal.c
hal/patches/patch-policy_Makefile.am
hal/patches/patch-tools_Makefile.am
hal/patches/patch-tools_hal-luks-setup
hal/patches/patch-tools_hal-luks-teardown
hal/patches/patch-tools_hal-storage-mount.c
hal/patches/patch-tools_hal-storage-shared.c
hal/patches/patch-tools_hal-storage-unmount.c
hal/patches/patch-tools_hal-system-power-pmu.c
hal/patches/patch-tools_linux_Makefile.am
Log Message:
Modify drvctl.c to not read from /dev/drvctl but use information from devpubd because
information of device-attach/device-detach sequence is missing, when devpubd is used
this way, a fifo is created in /tmp the /libexec/devpubd-hooks/03-hal pushes correct
sequence of attach/detach device into the fifo, than it is read by drvctl.c. Also a new
/etc/rc.d/hal is modified so that drvctl.c does not block on read from an empty fifo.
the Patch is in the patches directory => patch-hald_netbsd_drvctl.c
To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=cdb3d27492001f3f3ec7415cabb2eaf65f5d2d63
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
diffstat:
hal/DESCR | 15 +
hal/MESSAGE.NetBSD | 16 +
hal/Makefile | 144 ++
hal/PLIST | 108 ++
hal/PLIST.DragonFly | 15 +
hal/PLIST.FreeBSD | 17 +
hal/PLIST.Linux | 46 +
hal/PLIST.NetBSD | 8 +
hal/buildlink3.mk | 16 +
hal/distinfo | 53 +
hal/files/03-hal | 26 +
hal/files/hal.sh | 25 +
hal/files/hald-netbsd/Makefile.am | 27 +
hal/files/hald-netbsd/addons/Makefile.am | 17 +
hal/files/hald-netbsd/addons/addon-storage.c | 516 ++++++
hal/files/hald-netbsd/devinfo.c | 418 +++++
hal/files/hald-netbsd/devinfo.h | 72 +
hal/files/hald-netbsd/devinfo_acpi.h | 44 +
hal/files/hald-netbsd/devinfo_audio.c | 233 +++
hal/files/hald-netbsd/devinfo_audio.h | 38 +
hal/files/hald-netbsd/devinfo_cpu.h | 19 +
hal/files/hald-netbsd/devinfo_mass.c | 418 +++++
hal/files/hald-netbsd/devinfo_mass.h | 37 +
hal/files/hald-netbsd/devinfo_misc.c | 168 ++
hal/files/hald-netbsd/devinfo_misc.h | 21 +
hal/files/hald-netbsd/devinfo_optical.c | 485 ++++++
hal/files/hald-netbsd/devinfo_optical.h | 20 +
hal/files/hald-netbsd/devinfo_pci.c | 122 ++
hal/files/hald-netbsd/devinfo_pci.h | 21 +
hal/files/hald-netbsd/devinfo_storage.c | 1671 ++++++++++++++++++++
hal/files/hald-netbsd/devinfo_storage.h | 30 +
hal/files/hald-netbsd/devinfo_usb.c | 229 +++
hal/files/hald-netbsd/devinfo_usb.h | 23 +
hal/files/hald-netbsd/devinfo_video.c | 125 ++
hal/files/hald-netbsd/devinfo_video.h | 36 +
hal/files/hald-netbsd/drvctl.c | 303 ++++
hal/files/hald-netbsd/drvctl.h | 24 +
hal/files/hald-netbsd/envsys.c | 249 +++
hal/files/hald-netbsd/envsys.h | 36 +
hal/files/hald-netbsd/hal-file-monitor.c | 821 ++++++++++
hal/files/hald-netbsd/hotplug.c | 204 +++
hal/files/hald-netbsd/hotplug.h | 58 +
hal/files/hald-netbsd/osspec.c | 183 +++
hal/files/hald-netbsd/osspec_netbsd.h | 21 +
hal/files/hald-netbsd/probing/Makefile.am | 20 +
hal/files/hald-netbsd/probing/cdutils.c | 379 +++++
hal/files/hald-netbsd/probing/cdutils.h | 61 +
hal/files/hald-netbsd/probing/fsutils.c | 217 +++
hal/files/hald-netbsd/probing/fsutils.h | 25 +
hal/files/hald-netbsd/probing/probe-storage.c | 414 +++++
hal/files/hald-netbsd/probing/probe-volume.c | 629 ++++++++
hal/files/hald-netbsd/vfsstat.c | 157 ++
hal/files/hald-netbsd/vfsstat.h | 36 +
hal/files/smf/hal.sh | 35 +
hal/files/smf/manifest.xml | 79 +
hal/files/tools-netbsd/Makefile.am | 40 +
.../tools-netbsd/hal-system-power-reboot-netbsd | 19 +
.../tools-netbsd/hal-system-power-shutdown-netbsd | 19 +
.../tools-netbsd/hal-system-power-suspend-netbsd | 29 +
hal/patches/patch-Makefile.am | 13 +
hal/patches/patch-configure.in | 100 ++
...ch-fdi_policy_10osvendor_20-storage-methods.fdi | 98 ++
hal/patches/patch-hald_Makefile.am | 12 +
hal/patches/patch-hald_device__info.c | 20 +
.../patch-hald_freebsd_addons_addon-mouse.c | 14 +
.../patch-hald_freebsd_addons_addon-storage.c | 140 ++
hal/patches/patch-hald_freebsd_hf-ata.c | 16 +
hal/patches/patch-hald_freebsd_hf-devd.c | 40 +
hal/patches/patch-hald_freebsd_hf-pci.c | 16 +
hal/patches/patch-hald_freebsd_hf-storage.c | 14 +
hal/patches/patch-hald_freebsd_hf-usb.c | 47 +
hal/patches/patch-hald_freebsd_hf-usb2.c | 415 +++++
hal/patches/patch-hald_freebsd_hf-volume.c | 18 +
.../patch-hald_freebsd_libprobe_hfp-cdrom.c | 16 +
hal/patches/patch-hald_freebsd_probing_Makefile.am | 11 +
.../patch-hald_freebsd_probing_probe-hiddev.c | 18 +
.../patch-hald_freebsd_probing_probe-storage.c | 44 +
.../patch-hald_freebsd_probing_probe-usb2-device.c | 44 +
...tch-hald_freebsd_probing_probe-usb2-interface.c | 18 +
.../patch-hald_freebsd_probing_probe-volume.c | 127 ++
...-hald_linux_addons_addon-acpi-buttons-toshiba.c | 13 +
.../patch-hald_linux_addons_addon-cpufreq.c | 12 +
...atch-hald_linux_addons_addon-dell-backlight.cpp | 13 +
...tch-hald_linux_addons_addon-generic-backlight.c | 13 +
.../patch-hald_linux_addons_addon-imac-backlight.c | 13 +
hal/patches/patch-hald_linux_addons_addon-input.c | 14 +
.../patch-hald_linux_addons_addon-ipw-killswitch.c | 13 +
hal/patches/patch-hald_linux_addons_addon-leds.c | 13 +
...-hald_linux_addons_addon-macbookpro-backlight.c | 13 +
.../patch-hald_linux_addons_addon-omap-backlight.c | 13 +
...tch-hald_linux_addons_addon-rfkill-killswitch.c | 13 +
.../patch-hald_linux_addons_addon-storage.c | 13 +
.../patch-hald_linux_addons_addon-usb-csr.c | 13 +
.../patch-hald_linux_probing_probe-video4linux.c | 43 +
hal/patches/patch-hald_netbsd_devinfo__mass.c | 12 +
hal/patches/patch-hald_netbsd_drvctl.c | 111 ++
hal/patches/patch-libhal_libhal.c | 15 +
hal/patches/patch-policy_Makefile.am | 13 +
hal/patches/patch-tools_Makefile.am | 30 +
hal/patches/patch-tools_hal-luks-setup | 22 +
hal/patches/patch-tools_hal-luks-teardown | 22 +
hal/patches/patch-tools_hal-storage-mount.c | 134 ++
hal/patches/patch-tools_hal-storage-shared.c | 138 ++
hal/patches/patch-tools_hal-storage-unmount.c | 23 +
hal/patches/patch-tools_hal-system-power-pmu.c | 37 +
hal/patches/patch-tools_linux_Makefile.am | 12 +
106 files changed, 11359 insertions(+)
diffs:
diff --git a/hal/DESCR b/hal/DESCR
new file mode 100644
index 0000000000..988d7b66d9
--- /dev/null
+++ b/hal/DESCR
@@ -0,0 +1,15 @@
+What is the point of HAL?
+
+To merge information from various sources such that desktop applications can
+locate and use hardware devices. The point is that the exact set of
+information to merge varies by device and bus type. In order to do this, we
+need to define a format for the information, hence the HAL specification.
+
+We may read some stuff from the hardware itself, then add some info provided
+by the kernel, then add some metadata from some systemwide files, then add
+some data that has been obtained by the desktop and stored per-user, then
+look at some blacklist, and finally we have a complete picture of everything
+known about that particular device.
+
+An extra value is that we can do this in an operating system independent way.
+Stuff like this is important to the major desktop environments.
diff --git a/hal/MESSAGE.NetBSD b/hal/MESSAGE.NetBSD
new file mode 100644
index 0000000000..055de4ab32
--- /dev/null
+++ b/hal/MESSAGE.NetBSD
@@ -0,0 +1,16 @@
+===========================================================================
+$NetBSD: MESSAGE.NetBSD,v 1.2 2008/12/24 13:55:24 wiz Exp $
+
+For the NetBSD 5.0+ HAL backend to function properly, your kernel needs
+to include /dev/drvctl support. If the /dev/drvctl device node does not
+exist, run the following command:
+
+ # cd /dev
+ # sh MAKEDEV drvctl
+
+For proper kernel support, the following directive must be in your kernel
+config:
+
+ pseudo-device drvctl
+
+===========================================================================
diff --git a/hal/Makefile b/hal/Makefile
new file mode 100644
index 0000000000..be04e32924
--- /dev/null
+++ b/hal/Makefile
@@ -0,0 +1,144 @@
+# $NetBSD: Makefile,v 1.78 2016/09/17 15:33:59 richard Exp $
+
+DISTNAME= hal-0.5.14
+PKGREVISION= 18
+CATEGORIES?= sysutils mate
+MASTER_SITES= http://hal.freedesktop.org/releases/
+EXTRACT_SUFX= .tar.bz2
+
+MAINTAINER= nervoso%k1.com.br@localhost
+HOMEPAGE= http://hal.freedesktop.org/
+COMMENT= FreeDesktop hardware abstraction layer
+LICENSE= gnu-gpl-v2
+
+DEPENDS+= pciids-[0-9]*:../../misc/pciids
+
+BUILD_DEFS+= VARBASE PKG_SYSCONFBASE
+
+GNU_CONFIGURE= YES
+USE_PKGLOCALEDIR= YES
+USE_TOOLS+= gmake intltool msgfmt perl pkg-config
+USE_TOOLS+= autoconf automake autoreconf
+USE_LIBTOOL= YES
+USE_LANGUAGES+= c c++
+
+MAKE_DIRS+= /media
+MAKE_DIRS+= ${VARBASE}/cache/hald
+SPECIAL_PERMS+= ${VARBASE}/cache/hald ${HAL_USER} ${HAL_GROUP} 0644
+
+EGDIR= ${PREFIX}/share/examples/hal
+
+CONF_FILES+= ${EGDIR}/hal.conf ${PKG_SYSCONFBASE}/dbus-1/system.d/hal.conf
+CONF_FILES_PERMS+= ${EGDIR}/03-hal /libexec/devpubd-hooks/03-hal \
+ ${REAL_ROOT_USER} ${REAL_ROOT_GROUP} 0755
+
+CONFIGURE_ARGS+= --sysconfdir=${PKG_SYSCONFBASE}
+CONFIGURE_ARGS+= --localstatedir=${VARBASE}
+CONFIGURE_ARGS+= --with-pci-ids=${PREFIX}/share/pciids
+CONFIGURE_ARGS+= --with-usb-ids=${PREFIX}/share/usbids
+CONFIGURE_ARGS+= --without-os-type
+CONFIGURE_ARGS+= --disable-console-kit
+CONFIGURE_ARGS+= --disable-policy-kit
+
+.include "../../mk/bsd.prefs.mk"
+
+.if ${OPSYS} == "DragonFly"
+.include "../../devel/libvolume_id/buildlink3.mk"
+CONFIGURE_ARGS+= --with-eject=/usr/sbin/cdcontrol
+CONFIGURE_ARGS+= --with-backend=freebsd
+PLIST_SRC= PLIST.DragonFly PLIST
+
+.elif ${OPSYS} == "FreeBSD"
+.include "../../devel/libvolume_id/buildlink3.mk"
+CONFIGURE_ARGS+= --with-eject=/usr/sbin/cdcontrol
+CONFIGURE_ARGS+= --with-backend=freebsd
+PLIST_SRC= PLIST.FreeBSD PLIST
+
+.elif !empty(MACHINE_PLATFORM:MNetBSD-[5-9]*)
+.include "../../devel/libvolume_id/buildlink3.mk"
+CONFIGURE_ARGS+= --with-backend=netbsd
+HAL_GROUP= operator
+
+.elif ${OPSYS} == "Linux"
+.include "../../devel/gperf/buildlink3.mk"
+.include "../../devel/libblkid/buildlink3.mk"
+.include "../../devel/libvolume_id/buildlink3.mk"
+.include "../../sysutils/pciutils/buildlink3.mk"
+CONFIGURE_ARGS+= --with-backend=linux
+MAKE_DIRS+= /etc/udev
+MAKE_DIRS+= /etc/udev/rules.d
+CONF_FILES+= ${EGDIR}/90-hal.rules \
+ /etc/udev/rules.d/90-hal.rules
+PLIST_VARS+= imac
+.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "x86_64"
+PLIST.imac= yes
+CONFIGURE_ARGS+= --with-imac
+.else
+CONFIGURE_ARGS+= --without-imac
+.endif
+.else # Unsupported systems
+# Pull in the dummy backend
+.include "../../devel/libvolume_id/buildlink3.mk"
+CONFIGURE_ARGS+= --with-backend=dummy
+PLIST_SRC= PLIST
+.endif
+
+CFLAGS.SunOS+= -Du_int32_t=uint32_t
+
+BUILDLINK_TRANSFORM.Darwin+= rm:-Wl,--as-needed
+BUILDLINK_TRANSFORM.SunOS+= opt:-Wl,--as-needed:-Wl,-zignore
+
+REPLACE_INTERPRETER+= bash
+REPLACE.bash.old= /bin/bash
+REPLACE.bash.new= ${SH}
+.for halscript in luks-remove luks-setup luks-teardown system-wol-enable system-wol-enabled system-wol-supported
+REPLACE_FILES.bash+= tools/hal-${halscript}
+.endfor
+
+HAL_USER?= haldaemon
+HAL_GROUP?= haldaemon
+CONFIGURE_ARGS+= --with-hal-user=${HAL_USER}
+CONFIGURE_ARGS+= --with-hal-group=${HAL_GROUP}
+CONFIGURE_ARGS+= --disable-pmu
+
+RCD_SCRIPTS= hal
+SMF_METHODS= hal
+
+.if ${HAL_GROUP} != "operator"
+PKG_GROUPS= ${HAL_GROUP}
+.endif
+PKG_USERS= ${HAL_USER}:${HAL_GROUP}
+PKG_HOME.haldaemon= ${VARBASE}/run/hald
+
+FILES_SUBST+= HAL_USER=${HAL_USER}
+FILES_SUBST+= HAL_GROUP=${HAL_GROUP}
+FILES_SUBST+= PKG_HOME.haldaemon=${PKG_HOME.haldaemon}
+
+PLIST_SUBST+= PKG_SYSCONFDIR=${PKG_SYSCONFDIR}
+
+TEST_TARGET= check
+
+post-extract:
+ ${CP} -r ${FILESDIR}/hald-netbsd ${WRKSRC}/hald/netbsd
+ ${CP} -r ${FILESDIR}/tools-netbsd ${WRKSRC}/tools/netbsd
+
+CONFIGURE_ARGS+= --disable-silent-rules
+
+INSTALLATION_DIRS+= share/examples/hal
+
+post-install:
+ ${INSTALL_SCRIPT} ${FILESDIR}/03-hal ${DESTDIR}${EGDIR}
+ cd ${WRKSRC}/fdi;gmake
+ cd ${WRKSRC}/fdi;gmake install
+
+pre-configure:
+ cd ${WRKSRC} && autoreconf -vi ${AUTORECONF_ARGS}
+
+.include "../../devel/GConf/schemas.mk"
+.include "../../devel/glib2/buildlink3.mk"
+.include "../../misc/usbids/buildlink3.mk"
+.include "../../sysutils/dbus/buildlink3.mk"
+.include "../../sysutils/dbus-glib/buildlink3.mk"
+.include "../../wip/hal-info/buildlink3.mk"
+.include "../../textproc/expat/buildlink3.mk"
+.include "../../mk/bsd.pkg.mk"
diff --git a/hal/PLIST b/hal/PLIST
new file mode 100644
index 0000000000..772ad0c011
--- /dev/null
+++ b/hal/PLIST
@@ -0,0 +1,108 @@
+@comment $NetBSD$
+bin/hal-device
+bin/hal-disable-polling
+bin/hal-find-by-capability
+bin/hal-find-by-property
+bin/hal-get-property
+bin/hal-is-caller-locked-out
+bin/hal-lock
+bin/hal-set-property
+bin/lshal
+include/hal/libhal-storage.h
+include/hal/libhal.h
+lib/libhal-storage.la
+lib/libhal.la
+lib/pkgconfig/hal-storage.pc
+lib/pkgconfig/hal.pc
+libexec/hal-storage-cleanup-all-mountpoints
+libexec/hal-storage-cleanup-mountpoint
+libexec/hal-storage-closetray
+libexec/hal-storage-eject
+libexec/hal-storage-mount
+libexec/hal-storage-unmount
+libexec/hal-system-power-pm-is-supported
+libexec/hal-system-setserial
+libexec/hald-addon-storage
+libexec/hald-generate-fdi-cache
+libexec/hald-probe-storage
+libexec/hald-probe-volume
+libexec/hald-runner
+libexec/scripts/hal-dockstation-undock
+libexec/scripts/hal-functions
+libexec/scripts/hal-luks-remove
+libexec/scripts/hal-luks-setup
+libexec/scripts/hal-luks-teardown
+libexec/scripts/hal-system-killswitch-get-power
+libexec/scripts/hal-system-killswitch-set-power
+libexec/scripts/hal-system-lcd-get-brightness
+libexec/scripts/hal-system-lcd-set-brightness
+libexec/scripts/hal-system-power-hibernate
+libexec/scripts/hal-system-power-reboot
+libexec/scripts/hal-system-power-set-power-save
+libexec/scripts/hal-system-power-shutdown
+libexec/scripts/hal-system-power-suspend
+libexec/scripts/hal-system-power-suspend-hybrid
+libexec/scripts/hal-system-wol-enable
+libexec/scripts/hal-system-wol-enabled
+libexec/scripts/hal-system-wol-supported
+libexec/scripts/netbsd/hal-system-power-reboot-netbsd
+libexec/scripts/netbsd/hal-system-power-shutdown-netbsd
+libexec/scripts/netbsd/hal-system-power-suspend-netbsd
+man/man1/hal-disable-polling.1
+man/man1/hal-find-by-capability.1
+man/man1/hal-find-by-property.1
+man/man1/hal-get-property.1
+man/man1/hal-is-caller-locked-out.1
+man/man1/hal-lock.1
+man/man1/hal-set-property.1
+man/man1/lshal.1
+man/man8/hald.8
+sbin/hald
+share/examples/hal/hal.conf
+share/gtk-doc/html/libhal-storage/home.png
+share/gtk-doc/html/libhal-storage/index.html
+share/gtk-doc/html/libhal-storage/index.sgml
+share/gtk-doc/html/libhal-storage/ix01.html
+share/gtk-doc/html/libhal-storage/left.png
+share/gtk-doc/html/libhal-storage/libhal-storage-libhal-storage.html
+share/gtk-doc/html/libhal-storage/libhal-storage.devhelp
+share/gtk-doc/html/libhal-storage/libhal-storage.devhelp2
+share/gtk-doc/html/libhal-storage/license.html
+share/gtk-doc/html/libhal-storage/right.png
+share/gtk-doc/html/libhal-storage/rn01.html
+share/gtk-doc/html/libhal-storage/style.css
+share/gtk-doc/html/libhal-storage/up.png
+share/gtk-doc/html/libhal-storage/version.xml
+share/gtk-doc/html/libhal/home.png
+share/gtk-doc/html/libhal/index.html
+share/gtk-doc/html/libhal/index.sgml
+share/gtk-doc/html/libhal/ix01.html
+share/gtk-doc/html/libhal/left.png
+share/gtk-doc/html/libhal/libhal-libhal.html
+share/gtk-doc/html/libhal/libhal.devhelp
+share/gtk-doc/html/libhal/libhal.devhelp2
+share/gtk-doc/html/libhal/license.html
+share/gtk-doc/html/libhal/right.png
+share/gtk-doc/html/libhal/rn01.html
+share/gtk-doc/html/libhal/style.css
+share/gtk-doc/html/libhal/up.png
+share/hal/fdi/fdi.dtd
+share/hal/fdi/policy/10osvendor/10-dockstation.fdi
+share/hal/fdi/policy/10osvendor/10-input-policy.fdi
+share/hal/fdi/policy/10osvendor/10-laptop-panel-mgmt-policy.fdi
+share/hal/fdi/policy/10osvendor/10-leds.fdi
+share/hal/fdi/policy/10osvendor/10-power-mgmt-policy.fdi
+share/hal/fdi/policy/10osvendor/10-rfkill-switch.fdi
+share/hal/fdi/policy/10osvendor/10-tabletPCs.fdi
+share/hal/fdi/policy/10osvendor/10-x11-input.fdi
+share/hal/fdi/policy/10osvendor/15-storage-luks.fdi
+share/hal/fdi/policy/10osvendor/20-storage-methods.fdi
+share/hal/fdi/policy/10osvendor/30-wol.fdi
+@exec ${MKDIR} ${PKG_SYSCONFDIR}/hal/fdi/information
+@exec ${MKDIR} ${PKG_SYSCONFDIR}/hal/fdi/policy
+@exec ${MKDIR} ${PKG_SYSCONFDIR}/hal/fdi/preprobe
+@unexec ${RMDIR} ${PKG_SYSCONFDIR}/hal/fdi/preprobe 2>/dev/null || ${TRUE}
+@unexec ${RMDIR} ${PKG_SYSCONFDIR}/hal/fdi/policy 2>/dev/null || ${TRUE}
+@unexec ${RMDIR} ${PKG_SYSCONFDIR}/hal/fdi/information 2>/dev/null || ${TRUE}
+@unexec ${RMDIR} ${PKG_SYSCONFDIR}/hal/fdi 2>/dev/null || ${TRUE}
+@unexec ${RMDIR} ${PKG_SYSCONFDIR}/hal 2>/dev/null || ${TRUE}
diff --git a/hal/PLIST.DragonFly b/hal/PLIST.DragonFly
new file mode 100755
index 0000000000..2d7baf7c73
--- /dev/null
+++ b/hal/PLIST.DragonFly
@@ -0,0 +1,15 @@
+@comment $NetBSD: PLIST.DragonFly,v 1.1 2012/03/31 16:06:56 ryoon Exp $
+libexec/hald-addon-mouse-sysmouse
+libexec/hald-addon-storage
+libexec/hald-probe-hiddev
+libexec/hald-probe-mouse
+libexec/hald-probe-scsi
+libexec/hald-probe-smbios
+libexec/hald-probe-storage
+libexec/hald-probe-volume
+libexec/scripts/freebsd/hal-system-lcd-get-brightness-freebsd
+libexec/scripts/freebsd/hal-system-lcd-set-brightness-freebsd
+libexec/scripts/freebsd/hal-system-power-reboot-freebsd
+libexec/scripts/freebsd/hal-system-power-set-power-save-freebsd
+libexec/scripts/freebsd/hal-system-power-shutdown-freebsd
+libexec/scripts/freebsd/hal-system-power-suspend-freebsd
diff --git a/hal/PLIST.FreeBSD b/hal/PLIST.FreeBSD
new file mode 100644
index 0000000000..f1b79972ef
--- /dev/null
+++ b/hal/PLIST.FreeBSD
@@ -0,0 +1,17 @@
+@comment $NetBSD: PLIST.FreeBSD,v 1.4 2012/03/31 16:06:56 ryoon Exp $
+libexec/hald-addon-mouse-sysmouse
+libexec/hald-addon-storage
+libexec/hald-probe-hiddev
+libexec/hald-probe-mouse
+libexec/hald-probe-scsi
+libexec/hald-probe-smbios
+libexec/hald-probe-storage
+libexec/hald-probe-usb2-device
+libexec/hald-probe-usb2-interface
+libexec/hald-probe-volume
+libexec/scripts/freebsd/hal-system-lcd-get-brightness-freebsd
+libexec/scripts/freebsd/hal-system-lcd-set-brightness-freebsd
+libexec/scripts/freebsd/hal-system-power-reboot-freebsd
+libexec/scripts/freebsd/hal-system-power-set-power-save-freebsd
+libexec/scripts/freebsd/hal-system-power-shutdown-freebsd
+libexec/scripts/freebsd/hal-system-power-suspend-freebsd
diff --git a/hal/PLIST.Linux b/hal/PLIST.Linux
new file mode 100644
index 0000000000..f7cc3b5220
--- /dev/null
+++ b/hal/PLIST.Linux
@@ -0,0 +1,46 @@
+@comment $NetBSD: PLIST.Linux,v 1.6 2016/09/17 15:33:59 richard Exp $
+bin/hal-setup-keymap
+libexec/hal-system-sonypic
+libexec/hald-addon-acpi
+libexec/hald-addon-cpufreq
+libexec/hald-addon-generic-backlight
+libexec/hald-addon-hid-ups
+${PLIST.imac}libexec/hald-addon-imac-backlight
+libexec/hald-addon-input
+libexec/hald-addon-ipw-killswitch
+libexec/hald-addon-leds
+libexec/hald-addon-rfkill-killswitch
+libexec/hald-addon-storage
+libexec/hald-probe-hiddev
+libexec/hald-probe-ieee1394-unit
+libexec/hald-probe-input
+libexec/hald-probe-net-bluetooth
+libexec/hald-probe-pc-floppy
+libexec/hald-probe-printer
+libexec/hald-probe-serial
+libexec/hald-probe-smbios
+libexec/hald-probe-storage
+libexec/hald-probe-video4linux
+libexec/hald-probe-volume
+libexec/scripts/linux/hal-dockstation-undock-linux
+libexec/scripts/linux/hal-luks-remove-linux
+libexec/scripts/linux/hal-luks-setup-linux
+libexec/scripts/linux/hal-luks-teardown-linux
+libexec/scripts/linux/hal-system-killswitch-get-power-linux
+libexec/scripts/linux/hal-system-killswitch-set-power-linux
+libexec/scripts/linux/hal-system-lcd-get-brightness-linux
+libexec/scripts/linux/hal-system-lcd-set-brightness-linux
+libexec/scripts/linux/hal-system-power-hibernate-linux
+libexec/scripts/linux/hal-system-power-reboot-linux
+libexec/scripts/linux/hal-system-power-set-power-save-linux
+libexec/scripts/linux/hal-system-power-shutdown-linux
+libexec/scripts/linux/hal-system-power-suspend-hybrid-linux
+libexec/scripts/linux/hal-system-power-suspend-linux
+libexec/scripts/linux/hal-system-wol-enable-linux
+libexec/scripts/linux/hal-system-wol-enabled-linux
+libexec/scripts/linux/hal-system-wol-linux
+libexec/scripts/linux/hal-system-wol-supported-linux
+share/examples/hal/90-hal.rules
+share/hal/fdi/policy/10osvendor/10-cpufreq.fdi
+${PLIST.imac}share/hal/fdi/policy/10osvendor/10-imac-backlight.fdi
+share/hal/fdi/policy/10osvendor/10-keymap.fdi
diff --git a/hal/PLIST.NetBSD b/hal/PLIST.NetBSD
new file mode 100644
index 0000000000..b469c19149
--- /dev/null
+++ b/hal/PLIST.NetBSD
@@ -0,0 +1,8 @@
+@comment $NetBSD: PLIST.NetBSD,v 1.4 2011/01/08 13:39:08 obache Exp $
+libexec/hald-addon-storage
+libexec/hald-probe-storage
+libexec/hald-probe-volume
+libexec/scripts/netbsd/hal-system-power-reboot-netbsd
+libexec/scripts/netbsd/hal-system-power-shutdown-netbsd
+libexec/scripts/netbsd/hal-system-power-suspend-netbsd
+share/examples/hal/03-hal
diff --git a/hal/buildlink3.mk b/hal/buildlink3.mk
new file mode 100644
index 0000000000..9addba73d2
--- /dev/null
+++ b/hal/buildlink3.mk
@@ -0,0 +1,16 @@
+# $NetBSD: buildlink3.mk,v 1.7 2012/09/15 10:06:27 obache Exp $
+
+BUILDLINK_TREE+= hal
+
+.if !defined(HAL_BUILDLINK3_MK)
+HAL_BUILDLINK3_MK:=
+
+BUILDLINK_API_DEPENDS.hal+= hal>=0.5.11
+BUILDLINK_ABI_DEPENDS.hal+= hal>=0.5.14nb8
+BUILDLINK_PKGSRCDIR.hal?= ../../wip/hal
+
+.include "../../sysutils/dbus/buildlink3.mk"
+.include "../../sysutils/dbus-glib/buildlink3.mk"
+.endif # HAL_BUILDLINK3_MK
+
+BUILDLINK_TREE+= -hal
diff --git a/hal/distinfo b/hal/distinfo
new file mode 100644
index 0000000000..4b275e9f76
--- /dev/null
+++ b/hal/distinfo
@@ -0,0 +1,53 @@
+$NetBSD: distinfo,v 1.26 2016/09/17 15:33:59 richard Exp $
+
+SHA1 (hal-0.5.14.tar.bz2) = a6ec098d78112e18e2773afa5f9ed642b00c4c59
+RMD160 (hal-0.5.14.tar.bz2) = 0314dace9512bf49a62bd1556963fc60a6c9caf9
+SHA512 (hal-0.5.14.tar.bz2) = fe34e0dd0a630b943ea1ce2a2af71260309144fb76ae0f482c475610f0347f403f2a3bac81d27a95868bf640fca78e6e8de0051e8e1a3f39ff6804232ecc333c
+Size (hal-0.5.14.tar.bz2) = 942954 bytes
+SHA1 (patch-Makefile.am) = abf9318414838890c0eb344b6b15a8ec3a2600ef
+SHA1 (patch-configure.in) = 7b17a5bef17a030eca69f11843fb35957e66fd76
+SHA1 (patch-fdi_policy_10osvendor_20-storage-methods.fdi) = 0dff37971d139198d286b5970b2d5435cb7044cc
+SHA1 (patch-hald_Makefile.am) = db979b9ed3246a0fb3ed9d86dfcf60a40a48812a
+SHA1 (patch-hald_device__info.c) = b88a1ee1ae06cee798a9c46f963e86d41e6ac8d8
+SHA1 (patch-hald_freebsd_addons_addon-mouse.c) = a6319e523affc90701f09266949cb7891c044ba7
+SHA1 (patch-hald_freebsd_addons_addon-storage.c) = 209d7558e35644a68cb5feaf8e59c08e0ef563e1
+SHA1 (patch-hald_freebsd_hf-ata.c) = d8d72c49cb528d3b34a4ab369d07fa0278c4c9aa
+SHA1 (patch-hald_freebsd_hf-devd.c) = 5003677cbe438a7fa1429a77b27f3824b3207b8a
+SHA1 (patch-hald_freebsd_hf-pci.c) = 040a018a7be5b28a0dc23dd66a0c10bbb0abc6bf
+SHA1 (patch-hald_freebsd_hf-storage.c) = f20e4b1286d177e53a550b2ba1608d22e4b5c609
+SHA1 (patch-hald_freebsd_hf-usb.c) = 4323ab79fe068cfe4098ecc84923b14b37ff8537
+SHA1 (patch-hald_freebsd_hf-usb2.c) = de4dbe7ceadf462bf9e4b2f9ceffa499df7e9aad
+SHA1 (patch-hald_freebsd_hf-volume.c) = 5b17c899c3cf6ef1c825a18bd8571383b00bc770
+SHA1 (patch-hald_freebsd_libprobe_hfp-cdrom.c) = b6d8a2f5fe06120bae22608d065395e1ed43a19c
+SHA1 (patch-hald_freebsd_probing_Makefile.am) = c9e843f57b8a31f1bdc42478d450ea5606b4d7db
+SHA1 (patch-hald_freebsd_probing_probe-hiddev.c) = fe567d7504e961cb623e492f8dc155ef2f3b4c9e
+SHA1 (patch-hald_freebsd_probing_probe-storage.c) = bf44c939b338359f18457b1e65434731c3605130
+SHA1 (patch-hald_freebsd_probing_probe-usb2-device.c) = 6c9dc4b65c507ac2ce7896d8019fa5335aa1275c
+SHA1 (patch-hald_freebsd_probing_probe-usb2-interface.c) = 3e18a3861a2ba21de5a7718c890e653bd0f6825d
+SHA1 (patch-hald_freebsd_probing_probe-volume.c) = 2964207f8907229b5d00ecce7f56fb3359d01f0d
+SHA1 (patch-hald_linux_addons_addon-acpi-buttons-toshiba.c) = 82f266ac27c290470adedfe1ba820a0b5a8e1d27
+SHA1 (patch-hald_linux_addons_addon-cpufreq.c) = 1e94d9a00f57fa4197f460953ba540564fa1441c
+SHA1 (patch-hald_linux_addons_addon-dell-backlight.cpp) = 72bd150adff60dfeca4a261ee9387783a5e99262
+SHA1 (patch-hald_linux_addons_addon-generic-backlight.c) = ebf060a72948e4301477eedbbcaaa766d88265b5
+SHA1 (patch-hald_linux_addons_addon-imac-backlight.c) = c594f0dfb2b659faee9f88a0254db3e9180c2b3d
+SHA1 (patch-hald_linux_addons_addon-input.c) = c893c803e2870af97cdcae23f3c6f66e45234888
+SHA1 (patch-hald_linux_addons_addon-ipw-killswitch.c) = d3d8270dddaa132c3fefbc667f315f697c900245
+SHA1 (patch-hald_linux_addons_addon-leds.c) = e56747b39bf5e6e03286fedcb73ef226c0231bbd
+SHA1 (patch-hald_linux_addons_addon-macbookpro-backlight.c) = c508a7b9070c319679b8b8e715d29410957ba41a
+SHA1 (patch-hald_linux_addons_addon-omap-backlight.c) = 72ba398a1d661fb726778bf7df7460735fee988f
+SHA1 (patch-hald_linux_addons_addon-rfkill-killswitch.c) = 800fac10408b65b12cd644b93b8612c8b2970da0
+SHA1 (patch-hald_linux_addons_addon-storage.c) = 9949c8768395295f27aebc792b8b8091e988d2d9
+SHA1 (patch-hald_linux_addons_addon-usb-csr.c) = 34b5be5ff308f9aafcf505b303d36cbc2483d015
+SHA1 (patch-hald_linux_probing_probe-video4linux.c) = 023c679c42802dac6970ac0843c3244d274ba6bd
+SHA1 (patch-hald_netbsd_devinfo__mass.c) = 9fd6cfcd04211a87e810536216fab3443ad08bd1
+SHA1 (patch-hald_netbsd_drvctl.c) = b6e5d08735233cfb17b30740673324a0b080b61e
+SHA1 (patch-libhal_libhal.c) = 78013280a42c68150ea926366f085ede84b94958
+SHA1 (patch-policy_Makefile.am) = 075ab5e265be4733d856a17184129d0b301bc0b8
+SHA1 (patch-tools_Makefile.am) = ebbac0ca2995a1dd5d72206f6a89e5d820677e81
+SHA1 (patch-tools_hal-luks-setup) = cccc411359aa6ada37496923fe3bec883076d78d
+SHA1 (patch-tools_hal-luks-teardown) = e5346dcbbbd11b726174b99cb7a64647d7a35062
+SHA1 (patch-tools_hal-storage-mount.c) = 83d20e99943be5c4e9eaeff7a86d79a8912d9c99
+SHA1 (patch-tools_hal-storage-shared.c) = f76078748c3a8f64c4811da2b43c8635c90249b3
+SHA1 (patch-tools_hal-storage-unmount.c) = 1a1307b1448880dbdd0cec5731790985cbfea140
+SHA1 (patch-tools_hal-system-power-pmu.c) = d1ccd7c21008304998293031632f572f250033c1
+SHA1 (patch-tools_linux_Makefile.am) = 00143e34bee7010dd6c0e6be5ecb4fef31212381
diff --git a/hal/files/03-hal b/hal/files/03-hal
new file mode 100755
index 0000000000..3968f52832
--- /dev/null
+++ b/hal/files/03-hal
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# signal devices to hal daemon
+#
+FIFO=/tmp/halfifo
+ACTION=$1
+DEV=$2
+
+/usr/bin/logger $0 $*
+
+if [ -p $FIFO ]
+then
+ (echo $1 $2 >> $FIFO)&
+fi
+
+case ${ACTION} in
+device-attach)
+ case ${DEV} in
+ sd*)
+ pkill -hup gvfs-hal-volume-monitor
+ ;;
+ esac
+;;
+device-detach)
+;;
+esac
diff --git a/hal/files/hal.sh b/hal/files/hal.sh
new file mode 100644
index 0000000000..cfcbd81798
--- /dev/null
+++ b/hal/files/hal.sh
@@ -0,0 +1,25 @@
+#!@RCD_SCRIPTS_SHELL@
+#
+# $NetBSD: hal.sh,v 1.3 2015/09/25 16:26:16 richard Exp $
+#
+# PROVIDE: hal
+# REQUIRE: dbus
+# KEYWORD: shutdown
+
+. /etc/rc.subr
+
+name="hal"
+rcvar=$name
+command="@PREFIX@/sbin/hald"
+start_precmd=hal_prestart
+
+hal_prestart() {
+ /usr/bin/mkfifo -m 600 /tmp/halfifo
+ (echo "ping" > /tmp/halfifo)&
+ @MKDIR@ -m 0755 $dir "@VARBASE@/cache/hald" "@PKG_HOME.haldaemon@"
+ @CHOWN@ -R @HAL_USER@:@HAL_GROUP@ "@PKG_HOME.haldaemon@" "@VARBASE@/cache/hald"
+ sleep 3
+}
+
+load_rc_config $name
+run_rc_command "$1"
diff --git a/hal/files/hald-netbsd/Makefile.am b/hal/files/hald-netbsd/Makefile.am
new file mode 100644
index 0000000000..c5ba9a9163
--- /dev/null
+++ b/hal/files/hald-netbsd/Makefile.am
@@ -0,0 +1,27 @@
+
+SUBDIRS = probing addons .
+
+AM_CPPFLAGS = \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
+ -I$(top_srcdir) -I.. \
+ @GLIB_CFLAGS@ @DBUS_CFLAGS@ @POLKIT_CFLAGS@ @VOLUME_ID_CFLAGS@
+
+if HALD_COMPILE_NETBSD
+noinst_LTLIBRARIES = libhald_netbsd.la
+endif
+
+libhald_netbsd_la_SOURCES = \
+ osspec.c drvctl.c envsys.c vfsstat.c \
+ devinfo.c devinfo_misc.c devinfo_audio.c devinfo_video.c \
+ devinfo_mass.c \
+ hotplug.c hal-file-monitor.c \
+ devinfo_optical.c
+# devinfo_scsipi.c
+# devinfo_usb.c \
+# devinfo_pci.c
+
+libhald_netbsd_la_LDFLAGS = -lprop @VOLUME_ID_LIBS@
diff --git a/hal/files/hald-netbsd/addons/Makefile.am b/hal/files/hald-netbsd/addons/Makefile.am
new file mode 100644
index 0000000000..8434fb0334
--- /dev/null
+++ b/hal/files/hald-netbsd/addons/Makefile.am
@@ -0,0 +1,17 @@
+
+AM_CPPFLAGS = \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
+ -I$(top_srcdir) -I$(top_srcdir)/hald -I$(top_srcdir)/libhal -I$(top_srcdir)/libhal-storage \
+ @GLIB_CFLAGS@ @DBUS_CFLAGS@
+
+if HALD_COMPILE_NETBSD
+libexec_PROGRAMS = hald-addon-storage
+endif
+
+hald_addon_storage_SOURCES = addon-storage.c ../../logger.c
+hald_addon_storage_LDADD = $(top_builddir)/libhal/libhal.la
+
diff --git a/hal/files/hald-netbsd/addons/addon-storage.c b/hal/files/hald-netbsd/addons/addon-storage.c
new file mode 100644
index 0000000000..ed20019728
--- /dev/null
+++ b/hal/files/hald-netbsd/addons/addon-storage.c
@@ -0,0 +1,516 @@
+/***************************************************************************
+ *
+ * addon-storage.c : watch removable media state changes
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/statvfs.h>
+#include <sys/dkio.h>
+#include <dev/scsipi/scsi_spc.h>
+#include <dev/scsipi/scsipi_all.h>
+#include <dev/scsipi/scsipi_cd.h>
+#include <sys/scsiio.h>
+
+#include <libhal.h>
+
+#include <logger.h>
+
+#define SLEEP_PERIOD 5
+
+#define _EXPOSE_MMC
+#include <sys/cdio.h>
+
+
+enum discstate {
+ DISC_INSERTED,
+ DISC_EJECTED,
+ DISC_NONE,
+ DISC_UNKNOWN
+};
+
+static enum discstate
+scsi_test_unit_ready (int fd)
+{
+ struct scsi_test_unit_ready tur;
+ scsireq_t req;
+
+ memset(&tur, 0, sizeof(tur));
+ tur.opcode = SCSI_TEST_UNIT_READY;
+
+ memset(&req, 0, sizeof(req));
+ memcpy(req.cmd, &tur, sizeof(tur));
+ req.cmdlen = sizeof(tur);
+ req.databuf = NULL;
+ req.datalen = 0;
+ req.timeout = 10000;
+ req.flags = SCCMD_READ;
+ req.senselen = SENSEBUFLEN;
+
+ if (ioctl(fd, SCIOCCOMMAND, &req) == -1)
+ return DISC_UNKNOWN;
+ if (req.retsts == SCCMD_OK)
+ return DISC_INSERTED;
+ return DISC_EJECTED;
+}
+
+static void
+my_dbus_error_free(DBusError *error)
+{
+ if (dbus_error_is_set(error)) {
+ dbus_error_free(error);
+ }
+}
+
+static void
+force_unmount (LibHalContext *ctx, const char *udi)
+{
+ DBusError error;
+ DBusMessage *msg = NULL;
+ DBusMessage *reply = NULL;
+ char **options = NULL;
+ unsigned int num_options = 0;
+ DBusConnection *dbus_connection;
+ char *device_file;
+
+ dbus_error_init (&error);
+
+ dbus_connection = libhal_ctx_get_dbus_connection (ctx);
+
+ msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device.Volume",
+ "Unmount");
+ if (msg == NULL) {
+ HAL_DEBUG (("Could not create dbus message for %s", udi));
+ goto out;
+ }
+
+
+ options = calloc (1, sizeof (char *));
+ if (options == NULL) {
+ HAL_DEBUG (("Could not allocate options array"));
+ goto out;
+ }
+
+ device_file = libhal_device_get_property_string (ctx, udi, "block.device", &error);
+ if (device_file != NULL) {
+ libhal_free_string (device_file);
+ }
+ dbus_error_free (&error);
+
+ if (!dbus_message_append_args (msg,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, num_options,
+ DBUS_TYPE_INVALID)) {
+ HAL_DEBUG (("Could not append args to dbus message for %s", udi));
+ goto out;
+ }
+
+ if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, msg, -1, &error))) {
+ HAL_DEBUG (("Unmount failed for %s: %s : %s\n", udi, error.name, error.message));
+ goto out;
+ }
+
+ if (dbus_error_is_set (&error)) {
+ HAL_DEBUG (("Unmount failed for %s\n%s : %s\n", udi, error.name, error.message));
+ goto out;
+ }
+
+ HAL_DEBUG (("Succesfully unmounted udi '%s'", udi));
+
+out:
+ dbus_error_free (&error);
+ if (options != NULL)
+ free (options);
+ if (msg != NULL)
+ dbus_message_unref (msg);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+}
+
+static void
+unmount_childs (LibHalContext *ctx, const char *udi)
+{
+ DBusError error;
+ int num_volumes;
+ char **volumes;
+
+ dbus_error_init (&error);
+
+ /* need to force unmount all partitions */
+ if ((volumes = libhal_manager_find_device_string_match (
+ ctx, "block.storage_device", udi, &num_volumes, &error)) != NULL) {
+ dbus_error_free (&error);
+ int i;
+
+ for (i = 0; i < num_volumes; i++) {
+ char *vol_udi;
+
+ vol_udi = volumes[i];
+ if (libhal_device_get_property_bool (ctx, vol_udi, "block.is_volume", &error)) {
+ dbus_error_free (&error);
+ if (libhal_device_get_property_bool (ctx, vol_udi, "volume.is_mounted", &error)) {
+ dbus_error_free (&error);
+ HAL_DEBUG (("Forcing unmount of child '%s'", vol_udi));
+ force_unmount (ctx, vol_udi);
+ }
+ }
+ }
+ libhal_free_string_array (volumes);
+ }
+ my_dbus_error_free (&error);
+}
+
+/** Check if a filesystem on a special device file is mounted
+ *
+ * @param device_file Special device file, e.g. /dev/cdrom
+ * @return TRUE iff there is a filesystem system mounted
+ * on the special device file
+ */
+static dbus_bool_t
+is_mounted (const char *device_file)
+{
+ int count;
+ struct statvfs *statvfs;
+
+ count = getmntinfo(&statvfs, ST_WAIT);
+ while (count-- > 0) {
+ if (strcmp(statvfs->f_mntfromname, device_file) == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+close_device (int *fd)
+{
+ if (*fd > 0) {
+ close (*fd);
+ *fd = -1;
+ }
+}
+
+
+/* XXX why not share this further */
+static char const *
+get_profile_typestring(int profile)
+{
+ switch (profile) {
+ case 0x00 : return "unknown"; // "Unknown[0] profile";
+ case 0x01 : return "unknown"; // "Non removeable disc";
+ case 0x02 : return "unknown"; // "Removable disc";
+ case 0x03 : return "mo"; // Magneto Optical with sector erase";
+ case 0x04 : return "mo"; // "Magneto Optical write once";
+ case 0x05 : return "mo"; // "Advance Storage Magneto Optical";
+ case 0x08 : return "cd_rom"; // "CD-ROM"; no writing
+ case 0x09 : return "cd_r"; // "CD-R recordable";
+ case 0x0a : return "cd_rw"; // "CD-RW rewritable";
+ case 0x10 : return "dvd_rom"; // "DVD-ROM"; no writing
+ case 0x11 : return "dvd_r"; // "DVD-R sequential";
+ case 0x12 : return "dvd_ram"; // "DVD-RAM rewritable";
+ case 0x13 : return "dvd_rw"; // "DVD-RW restricted overwrite";
+ case 0x14 : return "dvd_rw"; // "DVD-RW sequential";
+ case 0x15 : return "dvd_r"; // "DVD-R dual layer sequential";
+ case 0x16 : return "dvd_r"; // "DVD-R dual layer jump";
+ case 0x17 : return "dvd_rw"; // "DVD-RW dual layer";
+ case 0x18 : return "unknown"; // "DVD-Download disc"; UNKNOWN
+ case 0x1a : return "dvd_plus_rw"; // "DVD+RW rewritable";
+ case 0x1b : return "dvd_plus_r"; // "DVD+R recordable";
+ case 0x20 : return "ddcd_rom"; // "DDCD readonly (retracted)"; no writing
+ case 0x21 : return "ddcd_r"; // "DDCD-R recordable (retracted)"; OK?
+ case 0x22 : return "ddcd_rw"; // "DDCD-RW rewritable (retracted)"; OK?
+ case 0x2a : return "dvd_plus_rw_dl";//"DVD+RW double layer";
+ case 0x2b : return "dvd_plus_r_dl";// "DVD+R double layer";
+ case 0x40 : return "bd_rom"; // "BD-ROM";
+ case 0x41 : return "bd_r"; // "BD-R Sequential Recording (SRM)";
+ case 0x42 : return "bd_r"; // "BD-R Random Recording (RRM)";
+ case 0x43 : return "bd_re"; // "BD-RE rewritable";
+ case 0x50 : return "hddvd_rom"; // "HD DVD-ROM (retracted)";
+ case 0x51 : return "hddvd_r"; // "HD DVD-R (retracted)";
+ case 0x52 : return "hddvd_ram"; // "HD DVD-RAM (retracted)";
+ case 0x53 : return "hddvd_rw"; // "HD DVD-RW (retracted)";
+ case 0x58 : return "hddvd_r_dl"; // "HD DVD-R dual layer (retracted)";
+ case 0x5a : return "hddvd_rw_dl"; // "HD DVD-RW dual layer (retracted)";
+ }
+ /* reserved */
+ return "unknown";
+}
+
+
+static void
+set_volume_properties(int fd, LibHalContext *ctx, char *udi, int state)
+{
+ struct mmc_discinfo di;
+ struct mmc_trackinfo ti;
+ struct volume_id *vid;
+ DBusError error;
+ uint64_t capacity;
+ char const *disc_type;
+ char *disc_fstype, *disc_label;
+ int has_audio, has_data, is_vcd, is_svcd, is_videodvd, is_appendable, is_blank, is_rewritable;
+ int tracknr, err;
+
+ disc_fstype = "";
+ disc_label = "";
+ disc_type = "unknown";
+ has_audio = has_data = is_vcd = is_svcd = is_videodvd = is_appendable = is_blank = is_rewritable = 0;
+ capacity = 0;
+
+ dbus_error_init (&error);
+ if (state == DISC_INSERTED) {
+ /* fetch new values */
+ memset(&di, 0, sizeof(struct mmc_discinfo));
+ err = ioctl(fd, MMCGETDISCINFO, &di);
+ if (!err) {
+ disc_type = get_profile_typestring(di.mmc_profile);
+ is_rewritable = di.mmc_cur & MMC_CAP_REWRITABLE;
+ is_blank = (di.disc_state == MMC_STATE_EMPTY);
+ is_appendable = (di.disc_state != MMC_STATE_FULL);
+
+ /* can't check is_videodvd, is_svcd, is_vcd (yet); use volume lib */
+ disc_fstype = "cd9660";
+ disc_label = "label";
+vid = NULL;
+#if 0
+ vid = volume_id_open_fd (fd);
+ if (vid) {
+ if (volume_id_probe_all (vid, 0, psize) == 0) {
+ hal_device_property_set_string (d, "volume.label", vid->label);
+ hal_device_property_set_string (d, "volume.partition.label", vid->label);
+ hal_device_property_set_string (d, "volume.uuid", vid->uuid);
+ hal_device_property_set_string (d, "volume.partition.uuid", vid->uuid);
+ }
+ volume_id_close (vid);
+ }
+#endif
+ for (tracknr = di.first_track; tracknr <= di.last_track_last_session; tracknr++) {
+ memset(&ti, 0, sizeof(struct mmc_trackinfo));
+ ti.tracknr = tracknr;
+ err = ioctl(fd, MMCGETTRACKINFO, &ti);
+ if (err)
+ break;
+ if (!(ti.flags & MMC_TRACKINFO_BLANK)) {
+ if (ti.flags & MMC_TRACKINFO_DATA)
+ has_data = TRUE;
+ if (ti.flags & MMC_TRACKINFO_AUDIO)
+ has_audio = TRUE;
+ }
+ capacity += (ti.track_size + ti.free_blocks) * di.sector_size;
+ }
+ }
+ }
+
+ /* add volume properties (ignoring dbus errors) */
+ libhal_device_set_property_bool (ctx, udi, "volume.ignore", FALSE, &error); /* make visible */
+ libhal_device_set_property_bool (ctx, udi, "volume.is_mounted", FALSE, &error); /* XXX fixme XXX */
+ libhal_device_set_property_bool (ctx, udi, "volume.is_mounted_readonly", FALSE, &error); /* XXX fixme XXX */
+ libhal_device_set_property_string (ctx, udi, "volume.fsusage", "filesystem", &error);
+ libhal_device_set_property_string (ctx, udi, "volume.fstype", disc_fstype, &error);
+ libhal_device_set_property_string (ctx, udi, "volume.label", disc_label, &error);
+ libhal_device_set_property_string (ctx, udi, "volume.uuid", "", &error);
+ libhal_device_set_property_uint64 (ctx, udi, "volume.size", capacity, &error);
+
+ /* add volume.disc properties (ignoring dbus errors) */
+ libhal_device_set_property_bool (ctx, udi, "volume.disc.has_audio", has_audio, &error);
+ libhal_device_set_property_bool (ctx, udi, "volume.disc.has_data", has_data, &error);
+ libhal_device_set_property_bool (ctx, udi, "volume.disc.is_vcd", is_vcd, &error);
+ libhal_device_set_property_bool (ctx, udi, "volume.disc.is_svcd", is_svcd, &error);
+ libhal_device_set_property_bool (ctx, udi, "volume.disc.is_videodvd", is_videodvd, &error);
+ libhal_device_set_property_bool (ctx, udi, "volume.disc.is_appendable", is_appendable, &error);
+ libhal_device_set_property_bool (ctx, udi, "volume.disc.is_blank", is_blank, &error);
+ libhal_device_set_property_bool (ctx, udi, "volume.disc.is_rewritable", is_rewritable, &error);
+
+ libhal_device_set_property_string (ctx, udi, "volume.disc.type", disc_type, &error);
+ libhal_device_set_property_uint64 (ctx, udi, "volume.disc.capacity", capacity, &error);
+
+ my_dbus_error_free (&error);
+}
+
+
+static void
+update_disc_volume_properties(int fd, LibHalContext *ctx, const char *udi, int state)
+{
+ DBusError error;
+ char **volumes;
+ char *vol_udi;
+ int num_volumes, i;
+
+ dbus_error_init (&error);
+
+ /* update volume children */
+ if ((volumes = libhal_manager_find_device_string_match (
+ ctx, "info.parent", udi, &num_volumes, &error)) != NULL) {
+ dbus_error_free (&error);
+
+ for (i = 0; i < num_volumes; i++) {
+ vol_udi = volumes[i];
+ if (libhal_device_get_property_bool (ctx, vol_udi, "block.is_volume", &error)) {
+ dbus_error_free (&error);
+ HAL_DEBUG(("Updating child %s of %s\n", udi, vol_udi));
+ set_volume_properties(fd, ctx, vol_udi, state);
+
+#if 0
+ if (libhal_device_get_property_bool (ctx, vol_udi, "volume.is_mounted", &error)) {
+ dbus_error_free (&error);
+ HAL_DEBUG (("Forcing unmount of child '%s'", vol_udi));
+ force_unmount (ctx, vol_udi);
+ }
+#endif
+ }
+ }
+ libhal_free_string_array (volumes);
+ }
+ my_dbus_error_free (&error);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ char *udi;
+ char *device_file, *raw_device_file;
+ LibHalContext *ctx = NULL;
+ DBusError error;
+ char *bus;
+ char *drive_type;
+ int state, last_state;
+ char *support_media_changed_str;
+ int support_media_changed;
+ int fd = -1;
+
+ if ((udi = getenv ("UDI")) == NULL)
+ goto out;
+ if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL)
+ goto out;
+ if ((raw_device_file = getenv ("HAL_PROP_BLOCK_NETBSD_RAW_DEVICE")) == NULL)
+ goto out;
+ if ((bus = getenv ("HAL_PROP_STORAGE_BUS")) == NULL)
+ goto out;
+ if ((drive_type = getenv ("HAL_PROP_STORAGE_DRIVE_TYPE")) == NULL)
+ goto out;
+
+ setup_logger ();
+
+ support_media_changed_str = getenv ("HAL_PROP_STORAGE_CDROM_SUPPORT_MEDIA_CHANGED");
+ if (support_media_changed_str != NULL && strcmp (support_media_changed_str, "true") == 0)
+ support_media_changed = TRUE;
+ else
+ support_media_changed = FALSE;
+
+ dbus_error_init (&error);
+
+ if ((ctx = libhal_ctx_init_direct (&error)) == NULL) {
+ goto out;
+ }
+ my_dbus_error_free (&error);
+
+ if (!libhal_device_addon_is_ready (ctx, udi, &error)) {
+ goto out;
+ }
+ my_dbus_error_free (&error);
+
+ printf ("Doing addon-storage for %s (bus %s) (drive_type %s) (udi %s)\n", device_file, bus, drive_type, udi);
+
+ last_state = state = DISC_NONE;
+
+ /* Linux version of this addon attempts to re-open the device O_EXCL
+ * every 2 seconds, trying to figure out if some other app,
+ * like a cd burner, is using the device. Aside from questionable
+ * value of this (apps should use HAL's locked property or/and
+ * Solaris in_use facility), but also frequent opens/closes
+ * keeps media constantly spun up. All this needs more thought.
+ */
+ for (;;) {
+ sleep (SLEEP_PERIOD);
+ if (is_mounted (device_file)) {
+ close_device (&fd);
+ } else if ((fd < 0) && ((fd = open (raw_device_file, O_RDONLY | O_NONBLOCK)) < 0)) {
+ HAL_DEBUG (("open failed for %s: %s", raw_device_file, strerror (errno)));
+ } else {
+ /* Check if a disc is in the drive */
+ state = scsi_test_unit_ready (fd);
+
+ if (state == last_state) {
+ HAL_DEBUG (("state has not changed %d %s", state, device_file));
+ /* TODO check if eject button was pressed */
+ /* see linux addons/addon-storage.c */
+ continue;
+ } else {
+ HAL_DEBUG (("new state %d %s", state, device_file));
+ }
+
+ switch (state) {
+ case DISC_EJECTED:
+ HAL_DEBUG (("Media removal detected on %s", device_file));
+ last_state = state;
+
+ libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, &error);
+ my_dbus_error_free (&error);
+
+ /* attempt to unmount all childs */
+ unmount_childs (ctx, udi);
+
+ update_disc_volume_properties(fd, ctx, udi, state);
+
+ /* could have a fs on the main block device; do a rescan to remove it */
+ libhal_device_rescan (ctx, udi, &error);
+ my_dbus_error_free (&error);
+ break;
+
+ case DISC_INSERTED:
+ HAL_DEBUG (("Media insertion detected on %s", device_file));
+ last_state = state;
+
+ libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", TRUE, &error);
+ my_dbus_error_free (&error);
+
+ update_disc_volume_properties(fd, ctx, udi, state);
+
+ /* could have a fs on the main block device; do a rescan to add it */
+ libhal_device_rescan (ctx, udi, &error);
+ my_dbus_error_free (&error);
+ break;
+
+ case DISC_UNKNOWN:
+ default:
+ HAL_DEBUG (("Device gone detected on %s", device_file));
+ last_state = state;
+
+ unmount_childs (ctx, udi);
+ close_device (&fd);
+ goto out;
+
+ }
+ }
+ }
+
+out:
+ if (ctx != NULL) {
+ my_dbus_error_free (&error);
+ libhal_ctx_shutdown (ctx, &error);
+ libhal_ctx_free (ctx);
+ }
+
+ return 0;
+}
diff --git a/hal/files/hald-netbsd/devinfo.c b/hal/files/hald-netbsd/devinfo.c
new file mode 100644
index 0000000000..7e47383675
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo.c
@@ -0,0 +1,418 @@
+/***************************************************************************
+ *
+ * devinfo.c : main file for drvctl-based device enumeration
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/drvctlio.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../hald_runner.h"
+#include "osspec_netbsd.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "devinfo_audio.h"
+#include "devinfo_video.h"
+#include "devinfo_pci.h"
+#include "devinfo_storage.h"
+#include "devinfo_mass.h"
+#include "devinfo_usb.h"
+#include "devinfo_misc.h"
+#include "devinfo_cpu.h"
+#include "devinfo_optical.h"
+/* #include "devinfo_scsipi.h" */
+#include "drvctl.h"
+
+void devinfo_add_subtree(HalDevice *parent, const char *devnode, gboolean is_root);
+
+void
+devinfo_add(HalDevice *parent, gchar *name)
+{
+ devinfo_add_subtree (parent, name, TRUE);
+}
+
+void
+devinfo_add_subtree(HalDevice *parent, const char *devnode, gboolean is_root)
+{
+ HalDevice *d;
+ struct devlistargs laa;
+ int i;
+
+ HAL_INFO (("add_subtree: %s", devnode));
+
+ if (parent == NULL) {
+ parent = devinfo_add_node (NULL, devnode);
+ }
+
+ if (drvctl_list (devnode, &laa) == -1) {
+ HAL_INFO (("devinfo_add_subtree: drvctl_list failed"));
+ return;
+ }
+
+ for (i = 0; i < laa.l_children; i++) {
+ d = devinfo_add_node (parent, laa.l_childname[i]);
+ if (d)
+ devinfo_add_subtree (d, laa.l_childname[i], FALSE);
+ }
+
+ if (laa.l_childname)
+ free(laa.l_childname);
+}
+
+void
+devinfo_set_default_properties (HalDevice *d, HalDevice *parent, const char *devnode, char *devfs_path)
+{
+ char *driver_name, *s;
+ const char *s1;
+ char udi[HAL_PATH_MAX];
+
+ if (parent != NULL) {
+ char *pdevice = hal_device_property_get_string (parent, "netbsd.device");
+ if (pdevice) {
+ gchar *path;
+ if (strcmp (pdevice, "mainbus0") == 0)
+ pdevice = "computer";
+ path = g_strdup_printf ("/org/freedesktop/Hal/devices/%s", pdevice);
+ hal_device_property_set_string (d, "info.parent", path);
+ g_free (path);
+ }
+ } else {
+ gchar pdevnode[512];
+ char *pdevice = pdevnode;
+ if (drvctl_find_parent (devnode, pdevnode) == TRUE) {
+ gchar *path;
+ if (strcmp (pdevnode, "mainbus0") == 0)
+ pdevice = "computer";
+ path = g_strdup_printf ("/org/freedesktop/Hal/devices/%s", pdevice);
+ hal_device_property_set_string (d, "info.parent", path);
+ g_free (path);
+ } else
+ hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/local");
+ }
+
+ hald_compute_udi (udi, sizeof (udi),
+ "/org/freedesktop/Hal/devices/%s", devnode);
+ hal_device_set_udi (d, udi);
+
+#if notyet
+ if (di_prop_lookup_strings (DDI_DEV_T_ANY, node, "model", &s) > 0) {
+ hal_device_property_set_string (d, "info.product", s);
+ } else {
+ hal_device_property_set_string (d, "info.product", di_node_name (node));
+ }
+#else
+ hal_device_property_set_string (d, "info.product", devnode);
+#endif
+
+ hal_device_property_set_string (d, "netbsd.device", devnode);
+
+#if notyet
+ if ((driver_name = di_driver_name (node)) != NULL) {
+ hal_device_property_set_string (d, "info.solaris.driver",
+ driver_name);
+ }
+
+ /* inherit parent's claim attributes */
+ if (hal_device_property_get_bool (parent, "info.claimed")) {
+ s1 = hal_device_property_get_string (parent, "info.claimed.service");
+ if (s1 != NULL) {
+ hal_device_property_set_bool (d, "info.claimed", TRUE);
+ hal_device_property_set_string (d, "info.claimed.service", s1);
+ }
+ }
+#endif
+}
+
+/* device handlers, ordered specific to generic */
+static DevinfoDevHandler *devinfo_handlers[] = {
+ &devinfo_computer_handler,
+ &devinfo_cpu_handler,
+ &devinfo_optical_handler,
+#if notyet
+ &devinfo_scsipi_handler,
+ &devinfo_ide_handler,
+ &devinfo_scsi_handler,
+ &devinfo_floppy_handler,
+ &devinfo_usb_handler,
+ &devinfo_pci_handler,
+ &devinfo_lofi_handler,
+#endif
+ &devinfo_audio_handler,
+ &devinfo_audio_mixer_handler,
+ &devinfo_audio_dsp_handler,
+ &devinfo_video_handler,
+ &devinfo_mass_handler,
+ &devinfo_default_handler,
+ NULL
+};
+
+HalDevice *
+devinfo_add_node(HalDevice *parent, const char *devnode)
+{
+ HalDevice *d = NULL;
+ char *devfs_path;
+ char *device_type = NULL;
+ DevinfoDevHandler *handler;
+ int i;
+
+ devfs_path = g_strdup_printf ("%s", devnode);
+
+#if notyet
+ (void) di_prop_lookup_strings (DDI_DEV_T_ANY, node, "device_type",
+ &device_type);
+#else
+ device_type = "unknown";
+#endif
+
+ for (i = 0; (d == NULL) && (devinfo_handlers[i] != NULL); i++) {
+ handler = devinfo_handlers[i];
+ d = handler->add (parent, devnode, devfs_path, device_type);
+ }
+
+ g_free(devfs_path);
+
+ HAL_INFO (("add_node: %s", d ? hal_device_get_udi (d) : "none"));
+ return (d);
+}
+
+void
+devinfo_hotplug_enqueue(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler, int action, int front)
+{
+ HotplugEvent *hotplug_event;
+
+ hotplug_event = g_new0 (HotplugEvent, 1);
+ hotplug_event->action = action;
+ hotplug_event->type = HOTPLUG_EVENT_DEVFS;
+ hotplug_event->d = d;
+ strlcpy (hotplug_event->un.devfs.devfs_path, devfs_path,
+ sizeof (hotplug_event->un.devfs.devfs_path));
+ hotplug_event->un.devfs.handler = handler;
+
+ hotplug_event_enqueue (hotplug_event, front);
+}
+
+void
+devinfo_add_enqueue(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler)
+{
+ devinfo_hotplug_enqueue (d, devfs_path, handler, HOTPLUG_ACTION_ADD, 0);
+}
+
+void
+devinfo_add_enqueue_at_front(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler)
+{
+ devinfo_hotplug_enqueue (d, devfs_path, handler, HOTPLUG_ACTION_ADD, 1);
+}
+
+void
+devinfo_remove_enqueue(gchar *devfs_path, DevinfoDevHandler *handler)
+{
+ devinfo_hotplug_enqueue (NULL, devfs_path, handler, HOTPLUG_ACTION_REMOVE, 0);
+}
+
+void
+devinfo_callouts_add_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+
+ /* Move from temporary to global device store */
+ hal_device_store_remove (hald_get_tdl (), d);
+ hal_device_store_add (hald_get_gdl (), d);
+
+ hotplug_event_end (end_token);
+}
+
+void
+devinfo_callouts_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+
+ /* Discard device if probing reports failure */
+ if (exit_type != HALD_RUN_SUCCESS || (return_code != 0)) {
+ HAL_INFO (("Probing for %s failed %d", hal_device_get_udi (d), return_code));
+ hal_device_store_remove (hald_get_tdl (), d);
+ g_object_unref (d);
+ hotplug_event_end (end_token);
+ return;
+ }
+
+ /* Merge properties from .fdi files */
+ di_search_and_merge (d, DEVICE_INFO_TYPE_INFORMATION);
+ di_search_and_merge (d, DEVICE_INFO_TYPE_POLICY);
+
+ hal_util_callout_device_add (d, devinfo_callouts_add_done, end_token, NULL);
+}
+
+void
+devinfo_callouts_preprobing_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+ DevinfoDevHandler *handler = (DevinfoDevHandler *) userdata2;
+ void (*probing_done) (HalDevice *, guint32, gint, char **, gpointer, gpointer);
+ const gchar *prober;
+ int prober_timeout;
+
+ if (hal_device_property_get_bool (d, "info.ignore")) {
+ HAL_INFO (("Preprobing merged info.ignore==TRUE"));
+
+ /* Leave device with info.ignore==TRUE so we won't pick up children */
+ hal_device_property_remove (d, "info.category");
+ hal_device_property_remove (d, "info.capabilities");
+
+ hal_device_store_remove (hald_get_tdl (), d);
+ hal_device_store_add (hald_get_gdl (), d);
+
+ hotplug_event_end (end_token);
+ return;
+ }
+
+ if (handler != NULL && handler->get_prober != NULL) {
+ prober = handler->get_prober (d, &prober_timeout);
+ } else {
+ prober = NULL;
+ }
+
+ if (handler->probing_done != NULL) {
+ probing_done = handler->probing_done;
+ } else {
+ probing_done = devinfo_callouts_probing_done;
+ }
+
+ if (prober != NULL) {
+ /* probe the device */
+ HAL_INFO(("Probing udi=%s", hal_device_get_udi (d)));
+ hald_runner_run (d,
+ prober, NULL,
+ prober_timeout,
+ probing_done,
+ (gpointer) end_token, (gpointer) handler);
+ } else {
+ probing_done (d, 0, 0, NULL, userdata1, userdata2);
+ }
+}
+
+/* This is the beginning of hotplug even handling */
+void
+hotplug_event_begin_add_devinfo (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token)
+{
+ HAL_INFO(("Preprobing udi=%s", hal_device_get_udi (d)));
+
+ if (parent != NULL && hal_device_property_get_bool (parent, "info.ignore")) {
+ HAL_INFO (("Ignoring device since parent has info.ignore==TRUE"));
+
+ hotplug_event_end (end_token);
+ return;
+ }
+
+ /* add to TDL so preprobing callouts and prober can access it */
+ hal_device_store_add (hald_get_tdl (), d);
+
+#if 0
+ /* Process preprobe fdi files */
+ di_search_and_merge (d, DEVICE_INFO_TYPE_PREPROBE);
+#endif
+
+ /* Run preprobe callouts */
+ hal_util_callout_device_preprobe (d, devinfo_callouts_preprobing_done, end_token, handler);
+}
+
+void
+devinfo_remove (gchar *devfs_path)
+{
+ devinfo_remove_enqueue ((gchar *)devfs_path, NULL);
+}
+
+/* generate hotplug event for each device in this branch */
+void
+devinfo_remove_branch (gchar *devnode, HalDevice *d)
+{
+ GSList *i;
+ GSList *children;
+ HalDevice *child;
+ char *child_devfs_path;
+
+ if (d == NULL) {
+ d = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "netbsd.device", devnode);
+ if (d == NULL)
+ return;
+ }
+
+ HAL_INFO (("remove_branch: %s %s\n", devnode, hal_device_get_udi (d)));
+
+ /* first remove children */
+ children = hal_device_store_match_multiple_key_value_string (hald_get_gdl(),
+ "info.parent", hal_device_get_udi (d));
+ for (i = children; i != NULL; i = g_slist_next (i)) {
+ child = HAL_DEVICE (i->data);
+ HAL_INFO (("remove_branch: child %s\n", hal_device_get_udi (child)));
+ devinfo_remove_branch ((gchar *)hal_device_property_get_string (child, "netbsd.device"), child);
+ }
+ g_slist_free (children);
+ HAL_INFO (("remove_branch: done with children"));
+
+ /* then remove self */
+ HAL_INFO (("remove_branch: queueing %s", devnode));
+ devinfo_remove_enqueue (devnode, NULL);
+}
+
+void
+devinfo_callouts_remove_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+
+ HAL_INFO (("Remove callouts completed udi=%s", hal_device_get_udi (d)));
+
+ if (!hal_device_store_remove (hald_get_gdl (), d)) {
+ HAL_WARNING (("Error removing device"));
+ }
+ g_object_unref (d);
+
+ hotplug_event_end (end_token);
+}
+
+void
+hotplug_event_begin_remove_devinfo (HalDevice *d, gchar *devfs_path, void *end_token)
+{
+#if notyet
+ if (hal_device_has_capability (d, "volume")) {
+ devinfo_volume_hotplug_begin_remove (d, devfs_path, end_token);
+ } else {
+ hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
+ }
+#else
+#warning hotplug_event_begin_remove_devinfo TODO
+ hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
+#endif
+}
+
+gboolean
+devinfo_device_rescan (HalDevice *d)
+{
+#if notyet
+ if (hal_device_has_capability (d, "block")) {
+ return (devinfo_storage_device_rescan (d));
+ } else {
+ return (FALSE);
+ }
+#else
+#warning devinfo_device_rescan TODO
+ return FALSE;
+#endif
+}
diff --git a/hal/files/hald-netbsd/devinfo.h b/hal/files/hald-netbsd/devinfo.h
new file mode 100644
index 0000000000..6ed0dd0f5e
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ *
+ * devinfo.h : definitions for libdevinfo-based device enumeration
+ *
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifndef DEVINFO_H
+#define DEVINFO_H
+
+#include <glib.h>
+
+#include <prop/proplib.h>
+
+#include "../hald.h"
+#include "../device_info.h"
+
+typedef struct DevinfoDevHandler_s
+{
+ HalDevice *(*add) (HalDevice *parent, const char *devnode, char *devfs_path, char *device_type);
+
+ /* yet unused */
+ void (*remove) (char *devfs_path);
+
+ void (*hotplug_begin_add) (HalDevice *d, HalDevice *parent, struct DevinfoDevHandler_s *handler, void *end_token);
+
+ void (*hotplug_begin_remove) (HalDevice *d, struct DevinfoDevHandler_s *handler, void *end_token);
+
+ void (*probing_done) (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2);
+
+ const gchar *(*get_prober) (HalDevice *d, int *timeout);
+} DevinfoDevHandler;
+
+#define PROP_INT(d, node, v, diprop, halprop) \
+ if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, diprop, &(v)) > 0) { \
+ hal_device_property_set_int (d, halprop, *(v)); \
+ }
+
+#define PROP_STR(d, node, v, diprop, halprop) \
+ if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, diprop, &(v)) > 0) { \
+ hal_device_property_set_string (d, halprop, v); \
+ }
+
+#define PROP_BOOL(d, node, v, diprop, halprop) \
+ hal_device_property_set_bool (d, halprop, \
+ (di_prop_lookup_ints(DDI_DEV_T_ANY, node, diprop, &(v)) >= 0));
+
+#define NELEM(a) (sizeof (a) / sizeof (*(a)))
+
+void devinfo_add (HalDevice *parent, gchar *path);
+HalDevice *devinfo_add_node(HalDevice *parent, const char *devnode);
+void devinfo_set_default_properties (HalDevice *d, HalDevice *parent, const char *devnode, char *devfs_path);
+void devinfo_callouts_preprobing_done (HalDevice *d, gpointer userdata1, gpointer userdata2);
+void devinfo_callouts_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error,
+ gpointer userdata1, gpointer userdata2);
+void devinfo_callouts_add_done (HalDevice *d, gpointer userdata1, gpointer userdata2);
+void devinfo_callouts_remove_done (HalDevice *d, gpointer userdata1, gpointer userdata2);
+void hotplug_event_begin_add_devinfo (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token);
+void devinfo_remove (gchar *path);
+void devinfo_remove_branch (gchar *path, HalDevice *d);
+void hotplug_event_begin_remove_devinfo (HalDevice *d, gchar *devfs_path, void *end_token);
+void devinfo_hotplug_enqueue(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler, int action, int front);
+void devinfo_add_enqueue(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler);
+void devinfo_add_enqueue_at_front(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler);
+void devinfo_remove_enqueue(gchar *devfs_path, DevinfoDevHandler *handler);
+gboolean devinfo_device_rescan (HalDevice *d);
+
+#endif /* DEVINFO_H */
diff --git a/hal/files/hald-netbsd/devinfo_acpi.h b/hal/files/hald-netbsd/devinfo_acpi.h
new file mode 100644
index 0000000000..6e841cc48e
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_acpi.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ *
+ * devinfo_acpi.h : definitions for acpi devices
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifndef DEVINFO_ACPI_H
+#define DEVINFO_ACPI_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_acpi_handler;
+extern DevinfoDevHandler devinfo_power_button_handler;
+
+#define MINOR_SHIFT 8
+#define MINOR2TYPE(minor) ((minor) >> MINOR_SHIFT)
+
+/* Battery device types */
+enum batt_type {
+ BATT_TYPE_UNKNOWN = -1,
+ BATT_TYPE_CBAT,
+ BATT_TYPE_AC,
+ BATT_TYPE_SBAT
+};
+
+HalDevice *devinfo_battery_add_major(HalDevice *parent, const char *devnode,
+ char *devfs_path, char *device_type, gboolean rescan, HalDevice *battery_d);
+void devinfo_acpi_add_minor(HalDevice *parent, const char *devnode,
+ char *minor_path, dev_t dev);
+void devinfo_battery_remove_minor(char *parent_devfs_path, gchar *udi);
+void devinfo_battery_rescan(char *parent_devfs_path, gchar *udi);
+const gchar *devinfo_acpi_get_prober(HalDevice *d, int *timeout);
+void devinfo_power_button_event(void);
+void devinfo_brightness_hotkeys_event(char *subclass);
+
+void devinfo_lid_event(char *subclass, gchar *udi);
+gboolean devinfo_lid_rescan(HalDevice *d);
+
+#endif /* DEVINFO_ACPI_H */
diff --git a/hal/files/hald-netbsd/devinfo_audio.c b/hal/files/hald-netbsd/devinfo_audio.c
new file mode 100644
index 0000000000..faf0063fe6
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_audio.c
@@ -0,0 +1,233 @@
+/* $NetBSD: devinfo_audio.c,v 1.2 2008/11/27 18:00:44 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2008 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/audioio.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <paths.h>
+#include <unistd.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../ids.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "devinfo_audio.h"
+#include "drvctl.h"
+
+HalDevice *devinfo_audio_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type);
+HalDevice *devinfo_audio_mixer_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type);
+HalDevice *devinfo_audio_dsp_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type);
+
+DevinfoDevHandler devinfo_audio_handler = {
+ devinfo_audio_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_audio_mixer_handler = {
+ devinfo_audio_mixer_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_audio_dsp_handler = {
+ devinfo_audio_dsp_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+HalDevice *
+devinfo_audio_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type)
+{
+ HalDevice *d = NULL, *mixer, *dsp;
+ prop_dictionary_t dict;
+ const char *driver, *parent_udi;
+ char *childnode;
+ int16_t unit;
+ char *audioctl;
+ struct audio_device audiodev;
+ int fd;
+
+ if (drvctl_find_device (devnode, &dict) == FALSE || dict == NULL)
+ return NULL;
+
+ if (prop_dictionary_get_int16 (dict, "device-unit", &unit) == false ||
+ prop_dictionary_get_cstring_nocopy (dict, "device-driver", &driver) == false) {
+ prop_object_release (dict);
+ return NULL;
+ }
+
+ if (strcmp (driver, "audio") != 0) {
+ prop_object_release (dict);
+ return NULL;
+ }
+
+ audioctl = g_strdup_printf (_PATH_AUDIOCTL "%d", unit);
+ fd = open (audioctl, O_RDONLY);
+ if (fd < 0) {
+ HAL_WARNING (("couldn't open %s: %s", audioctl, strerror(errno)));
+ goto done;
+ }
+
+ if (ioctl (fd, AUDIO_GETDEV, &audiodev) == -1) {
+ HAL_WARNING (("couldn't query %s: %s", audioctl, strerror(errno)));
+ goto done;
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, devnode, devfs_path);
+ hal_device_add_capability (d, "sound");
+ hal_device_property_set_string (d, "info.category", "sound");
+ hal_device_property_set_string (d, "info.subsystem", "sound");
+
+ hal_device_property_set_int (d, "sound.card", unit);
+ hal_device_property_set_string (d, "sound.card_id", audiodev.name);
+ hal_device_property_set_string (d, "netbsd.sound.hardware", audiodev.config);
+
+ parent_udi = hal_device_property_get_string (parent, "info.udi");
+ if (parent_udi)
+ hal_device_property_set_string (d, "sound.originating_device", parent_udi);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_audio_handler);
+
+ childnode = g_strdup_printf ("oss_mixer_%d", unit);
+ devinfo_add_node (d, childnode);
+ g_free (childnode);
+
+ childnode = g_strdup_printf ("oss_dsp_%d", unit);
+ devinfo_add_node (d, childnode);
+ g_free (childnode);
+
+done:
+ if (dict)
+ prop_object_release (dict);
+ if (audioctl)
+ g_free (audioctl);
+ if (fd >= 0)
+ close (fd);
+
+ return d;
+}
+
+HalDevice *
+devinfo_audio_mixer_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type)
+{
+ HalDevice *d = NULL;
+ char *device_file, *parent_udi, *card_id, *device_id;
+ int16_t unit;
+
+ if (strstr (devnode, "oss_mixer_") != devnode)
+ return NULL;
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, devnode, devfs_path);
+ hal_device_add_capability (d, "oss");
+ hal_device_property_set_string (d, "info.category", "oss");
+ hal_device_property_set_string (d, "info.subsystem", "sound");
+
+ card_id = hal_device_property_get_string (parent, "sound.card_id");
+ hal_device_property_set_string (d, "oss.card_id", card_id);
+ unit = hal_device_property_get_int (parent, "sound.card");
+ hal_device_property_set_int (d, "oss.card", unit);
+ hal_device_property_set_int (d, "oss.device", unit + 16);
+ device_id = hal_device_property_get_string (parent, "netbsd.sound.hardware");
+ hal_device_property_set_string (d, "oss.device_id", device_id);
+ hal_device_property_set_string (d, "oss.type", "mixer");
+
+ device_file = g_strdup_printf (_PATH_MIXER "%d", unit);
+ hal_device_property_set_string (d, "oss.device_file", device_file);
+ g_free (device_file);
+
+ parent_udi = hal_device_property_get_string (parent, "info.udi");
+ if (parent_udi)
+ hal_device_property_set_string (d, "sound.originating_device", parent_udi);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_audio_mixer_handler);
+
+ return d;
+}
+
+HalDevice *
+devinfo_audio_dsp_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type)
+{
+ HalDevice *d = NULL;
+ char *device_file, *parent_udi, *card_id, *device_id;
+ int16_t unit;
+
+ if (strstr (devnode, "oss_dsp_") != devnode)
+ return NULL;
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, devnode, devfs_path);
+ hal_device_add_capability (d, "oss");
+ hal_device_property_set_string (d, "info.category", "oss");
+ hal_device_property_set_string (d, "info.subsystem", "sound");
+
+ card_id = hal_device_property_get_string (parent, "sound.card_id");
+ hal_device_property_set_string (d, "oss.card_id", card_id);
+ unit = hal_device_property_get_int (parent, "sound.card");
+ hal_device_property_set_int (d, "oss.card", unit);
+ hal_device_property_set_int (d, "oss.device", unit);
+ device_id = hal_device_property_get_string (parent, "netbsd.sound.hardware");
+ hal_device_property_set_string (d, "oss.device_id", device_id);
+ hal_device_property_set_string (d, "oss.type", "pcm");
+
+ device_file = g_strdup_printf (_PATH_SOUND "%d", unit);
+ hal_device_property_set_string (d, "oss.device_file", device_file);
+ g_free (device_file);
+
+ parent_udi = hal_device_property_get_string (parent, "info.udi");
+ if (parent_udi)
+ hal_device_property_set_string (d, "sound.originating_device", parent_udi);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_audio_dsp_handler);
+
+ return d;
+}
diff --git a/hal/files/hald-netbsd/devinfo_audio.h b/hal/files/hald-netbsd/devinfo_audio.h
new file mode 100644
index 0000000000..0c60623bcd
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_audio.h
@@ -0,0 +1,38 @@
+/* $NetBSD: devinfo_audio.h,v 1.1 2008/11/27 16:07:14 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2008 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DEVINFO_AUDIO_H
+#define DEVINFO_AUDIO_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_audio_handler;
+extern DevinfoDevHandler devinfo_audio_mixer_handler;
+extern DevinfoDevHandler devinfo_audio_dsp_handler;
+
+#endif /* DEVINFO_AUDIO_H */
diff --git a/hal/files/hald-netbsd/devinfo_cpu.h b/hal/files/hald-netbsd/devinfo_cpu.h
new file mode 100644
index 0000000000..441acdf10e
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_cpu.h
@@ -0,0 +1,19 @@
+/***************************************************************************
+ *
+ * devinfo_cpu.h : definition for cpu devices
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifndef DEVINFO_CPU_H
+#define DEVINFO_CPU_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_cpu_handler;
+
+#endif /* DEVINFO_CPU_H */
diff --git a/hal/files/hald-netbsd/devinfo_mass.c b/hal/files/hald-netbsd/devinfo_mass.c
new file mode 100644
index 0000000000..4c125752dc
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_mass.c
@@ -0,0 +1,418 @@
+/* $NetBSD: devinfo_mass.c,v 1.6 2015/01/31 12:08:55 wiz Exp $ */
+
+/*-
+ * Copyright (c) 2008 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/disklabel.h>
+#include <sys/bootblock.h>
+#include <sys/ioctl.h>
+#include <sys/scsiio.h>
+#include <dev/scsipi/scsipi_all.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <paths.h>
+#include <unistd.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../ids.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "devinfo_mass.h"
+#include "drvctl.h"
+
+#include <libvolume_id.h>
+
+HalDevice *devinfo_mass_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type);
+HalDevice *devinfo_mass_disklabel_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type);
+
+/* XXX from devinfo_optical */
+extern bool scsi_command(int, void *, size_t, void *, size_t, int, int);
+
+DevinfoDevHandler devinfo_mass_handler = {
+ devinfo_mass_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_mass_disklabel_handler = {
+ devinfo_mass_disklabel_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static char *
+rtrim_copy(char *src, int len)
+{
+ char *dst, *p;
+
+ if (len == 0) {
+ len = strlen(src);
+ }
+ if ((dst = calloc(1, len + 1)) != NULL) {
+ strncpy(dst, src, len);
+ p = dst + len - 1;
+ while ((p >= dst) && (isspace((int)*p))) {
+ *p-- = '\0';
+ }
+ }
+ return (dst);
+}
+
+static const char *
+devinfo_mass_get_fstype(uint8_t fstype)
+{
+ switch (fstype) {
+ case FS_BSDFFS:
+ return "ffs";
+ case FS_MSDOS:
+ return "vfat";
+ case FS_EX2FS:
+ return "ext2";
+ case FS_NTFS:
+ return "ntfs";
+ case FS_APPLEUFS:
+ return "ffs";
+ default:
+ return NULL;
+ }
+}
+
+static uint8_t
+devinfo_mass_get_mbrtype(uint8_t fstype)
+{
+ switch (fstype) {
+ case FS_BSDFFS:
+ return MBR_PTYPE_NETBSD;
+ case FS_MSDOS:
+ return MBR_PTYPE_FAT32; /* XXX */
+ case FS_EX2FS:
+ return MBR_PTYPE_LNXEXT2;
+ case FS_NTFS:
+ return MBR_PTYPE_NTFS;
+ case FS_APPLEUFS:
+ return MBR_PTYPE_APPLE_UFS;
+ default:
+ return MBR_PTYPE_UNUSED;
+ }
+}
+
+HalDevice *
+devinfo_mass_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type)
+{
+ HalDevice *d = NULL, *gparent = NULL;
+ prop_dictionary_t dict;
+ struct disklabel label;
+ struct stat st;
+ const char *driver;
+ char *rdevpath, *devpath;
+ char *childnode;
+ char *parent_devnode, *gparent_devnode = NULL;
+ char *gparent_udi;
+ int16_t unit;
+ int i, fd;
+ struct scsipi_inquiry_data inqbuf;
+ struct scsipi_inquiry cmd;
+ bool scsiinq_status;
+ char *storage_model = NULL, *storage_vendor = NULL;
+
+ if (drvctl_find_device (devnode, &dict) == FALSE || dict == NULL)
+ return NULL;
+
+ if (prop_dictionary_get_int16 (dict, "device-unit", &unit) == false ||
+ prop_dictionary_get_cstring_nocopy (dict, "device-driver", &driver) == false) {
+ prop_object_release (dict);
+ return NULL;
+ }
+
+ if (strcmp (driver, "wd") != 0 && strcmp (driver, "sd") != 0 &&
+ strcmp (driver, "ld") != 0) {
+ prop_object_release (dict);
+ return NULL;
+ }
+
+ sleep (1);
+
+ devpath = g_strdup_printf ("/dev/%s%c", devnode, RAW_PART + 'a');
+ rdevpath = g_strdup_printf ("/dev/r%s%c", devnode, RAW_PART + 'a');
+ HAL_INFO ((" going to open %s", rdevpath));
+ fd = open (rdevpath, O_RDONLY);
+ if (fd < 0) {
+ HAL_WARNING (("couldn't open %s: %s", rdevpath, strerror (errno)));
+ g_free (rdevpath);
+ g_free (devpath);
+ return NULL;
+ }
+
+ HAL_INFO ((" going to DIOCGDINFO %s", rdevpath));
+ if (ioctl (fd, DIOCGDINFO, &label) == -1) {
+ HAL_WARNING (("DIOCGDINFO failed on %s: %s", rdevpath, strerror (errno)));
+ g_free (rdevpath);
+ g_free (devpath);
+ close (fd);
+ return NULL;
+ }
+
+ if (strcmp (driver, "sd") == 0) {
+ memset(&cmd, 0, sizeof (cmd));
+ memset(&inqbuf, 0, sizeof (inqbuf));
+ cmd.opcode = INQUIRY;
+ cmd.length = sizeof (inqbuf);
+
+ scsiinq_status = scsi_command (fd, &cmd, sizeof (cmd), &inqbuf, sizeof (inqbuf), 10000, SCCMD_READ);
+ } else
+ scsiinq_status = false;
+
+ close (fd);
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, devnode, devfs_path);
+
+ hal_device_add_capability (d, "block");
+ hal_device_property_set_string (d, "info.subsystem", "block");
+ hal_device_property_set_string (d, "block.device", devpath);
+ if (stat (devpath, &st) == 0) {
+ hal_device_property_set_int (d, "block.major", major (st.st_rdev));
+ hal_device_property_set_int (d, "block.minor", minor (st.st_rdev));
+ }
+ hal_device_property_set_bool (d, "block.is_volume", FALSE);
+ hal_device_property_set_bool (d, "block.no_partitions", FALSE);
+ hal_device_property_set_bool (d, "block.have_scanned", TRUE);
+
+ hal_device_add_capability (d, "storage");
+ hal_device_property_set_string (d, "info.category", "storage");
+ parent_devnode = hal_device_property_get_string (parent, "netbsd.device");
+ gparent_udi = hal_device_property_get_string (parent, "info.parent");
+ if (gparent_udi) {
+ gparent = hal_device_store_find (hald_get_gdl (), gparent_udi);
+ if (gparent)
+ gparent_devnode = hal_device_property_get_string (gparent, "netbsd.device");
+ }
+ if (gparent_devnode && strstr (gparent_devnode, "umass") == gparent_devnode)
+ hal_device_property_set_string (d, "storage.bus", "usb");
+ else if (parent_devnode && strstr (parent_devnode, "atabus") == parent_devnode)
+ hal_device_property_set_string (d, "storage.bus", "ide");
+ else
+ hal_device_property_set_string (d, "storage.bus", "scsi");
+ hal_device_property_set_string (d, "storage.device_type", "disk");
+ hal_device_property_set_bool (d, "storage.removable", label.d_flags & D_REMOVABLE ? TRUE : FALSE);
+ if (label.d_flags & D_REMOVABLE) {
+ hal_device_property_set_bool (d, "storage.removable.media_available", TRUE);
+ hal_device_property_set_uint64 (d, "storage.removable.media_size",
+ (uint64_t)label.d_secsize * (uint64_t)label.d_secperunit);
+ hal_device_property_set_uint64 (d, "storage.size", 0);
+ hal_device_property_set_bool (d, "storage.hotpluggable", TRUE);
+ hal_device_property_set_bool (d, "storage.automount_enabled_hint", TRUE);
+ } else {
+ hal_device_property_set_bool (d, "storage.removable.media_available", FALSE);
+ hal_device_property_set_uint64 (d, "storage.removable.media_size", 0);
+ hal_device_property_set_uint64 (d, "storage.size",
+ (uint64_t)label.d_secsize * (uint64_t)label.d_secperunit);
+ hal_device_property_set_bool (d, "storage.hotpluggable", FALSE);
+ hal_device_property_set_bool (d, "storage.automount_enabled_hint", FALSE);
+ }
+ hal_device_property_set_bool (d, "storage.no_partitions_hint", FALSE);
+ hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
+ hal_device_property_set_bool (d, "storage.removable.support_async_notification", FALSE);
+ hal_device_property_set_string (d, "storage.partitioning_scheme", "mbr");
+ hal_device_property_set_string (d, "storage.originating_device",
+ hal_device_property_get_string (d, "info.udi"));
+
+ if (scsiinq_status == true) {
+ storage_model = rtrim_copy(inqbuf.product, sizeof (inqbuf.product));
+ storage_vendor = rtrim_copy(inqbuf.vendor, sizeof (inqbuf.vendor));
+ }
+
+ if (storage_model) {
+ hal_device_property_set_string (d, "storage.model", storage_model);
+ free (storage_model);
+ } else
+ hal_device_property_set_string (d, "storage.model", label.d_packname);
+
+ if (storage_vendor) {
+ hal_device_property_set_string (d, "storage.vendor", storage_vendor);
+ free (storage_vendor);
+ } else
+ hal_device_property_set_string (d, "storage.vendor", label.d_typename);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_mass_handler);
+
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ const char *fstype;
+
+ fstype = devinfo_mass_get_fstype(label.d_partitions[i].p_fstype);
+ if (fstype == NULL)
+ continue;
+
+ childnode = g_strdup_printf ("%s%c", devnode, 'a' + i);
+ HAL_INFO ((" adding %s on %s", childnode, rdevpath));
+ devinfo_mass_disklabel_add (d, childnode, childnode, childnode);
+ g_free (childnode);
+ }
+
+ HAL_INFO ((" returning"));
+ g_free (rdevpath);
+ g_free (devpath);
+
+done:
+ prop_object_release (dict);
+
+ return d;
+}
+
+HalDevice *
+devinfo_mass_disklabel_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type)
+{
+ HalDevice *d = NULL;
+ struct disklabel label;
+ struct partition *part;
+ struct stat st;
+ const char *driver;
+ char *devpath, *rdevpath, *partname;
+ char *childnode;
+ char unit;
+ struct volume_id *vid;
+ uint64_t psize, msize;
+ int i, fd;
+
+ partname = devnode;
+ unit = partname[strlen (partname) - 1] - 'a';
+
+ if (unit >= MAXPARTITIONS)
+ return NULL;
+
+ devpath = g_strdup_printf ("/dev/%s", partname);
+ rdevpath = g_strdup_printf ("/dev/r%s", partname);
+ fd = open (rdevpath, O_RDONLY);
+ if (fd < 0) {
+ HAL_WARNING (("couldn't open %s: %s", rdevpath, strerror (errno)));
+ g_free (rdevpath);
+ return NULL;
+ }
+
+ if (ioctl (fd, DIOCGDINFO, &label) == -1) {
+ HAL_WARNING (("DIOCGDINFO failed on %s: %s", rdevpath, strerror (errno)));
+ g_free (rdevpath);
+ close (fd);
+ return NULL;
+ }
+ part = &label.d_partitions[unit];
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, devnode, devfs_path);
+
+ hal_device_add_capability (d, "block");
+ hal_device_property_set_string (d, "info.subsystem", "block");
+ hal_device_property_set_string (d, "info.category", "volume");
+ hal_device_property_set_string (d, "block.device", devpath);
+ hal_device_property_set_string (d, "block.storage_device",
+ hal_device_property_get_string (parent, "info.udi"));
+
+ if (stat (devpath, &st) == 0) {
+ hal_device_property_set_int (d, "block.major", major (st.st_rdev));
+ hal_device_property_set_int (d, "block.minor", minor (st.st_rdev));
+ }
+
+ hal_device_property_set_bool (d, "block.is_volume", TRUE);
+ hal_device_property_set_bool (d, "block.no_partitions", FALSE);
+ hal_device_property_set_bool (d, "block.have_scanned", TRUE);
+
+ hal_device_add_capability (d, "volume");
+ hal_device_property_set_bool (d, "volume.ignore", FALSE);
+ hal_device_property_set_bool (d, "volume.is_mounted", FALSE);
+ hal_device_property_set_bool (d, "volume.is_mounted_read_only", FALSE);
+ hal_device_property_set_string (d, "volume.mount_point", "");
+ hal_device_property_set_string (d, "volume.fsusage", "filesystem");
+ hal_device_property_set_string (d, "volume.fstype", devinfo_mass_get_fstype (part->p_fstype));
+ hal_device_property_set_bool (d, "volume.is_disc", FALSE);
+
+ hal_device_property_set_string (d, "volume.label", "");
+ hal_device_property_set_string (d, "volume.partition.label", "");
+ hal_device_property_set_string (d, "volume.uuid", "");
+ hal_device_property_set_string (d, "volume.partition.uuid", "");
+
+ psize = (uint64_t)part->p_size * (uint64_t)label.d_secsize;
+ msize = (uint64_t)label.d_secsize * (uint64_t)label.d_secperunit;
+
+ hal_device_property_set_uint64 (d, "volume.size", psize);
+ hal_device_property_set_int (d, "volume.block_size", label.d_secsize);
+ hal_device_property_set_uint64 (d, "volume.num_blocks", part->p_size);
+ hal_device_property_set_uint64 (d, "volume.partition.media_size", msize);
+
+ hal_device_property_set_bool (d, "volume.is_partition", TRUE);
+ hal_device_property_set_int (d, "volume.partition.number", unit);
+ hal_device_property_set_string (d, "volume.partition.scheme", "mbr");
+
+ vid = volume_id_open_fd (fd);
+ if (vid) {
+ if (volume_id_probe_all (vid, 0, psize) == 0) {
+ const char *type,*fstype;
+
+ hal_device_property_set_string (d, "volume.label", vid->label);
+ hal_device_property_set_string (d, "volume.partition.label", vid->label);
+ hal_device_property_set_string (d, "volume.uuid", vid->uuid);
+ hal_device_property_set_string (d, "volume.partition.uuid", vid->uuid);
+
+ if ( type && volume_id_get_type (vid, &type)) {
+ fstype=devinfo_mass_get_fstype (part->p_fstype);
+ if (strcmp (type, fstype)) {
+ HAL_INFO (("%s disklabel reports [%s] but libvolume_id says it is "
+ "[%s], assuming disklabel is incorrect",
+ devpath, fstype, type));
+ hal_device_property_set_string (d, "volume.fstype", type);
+ }
+ }
+ }
+ volume_id_close (vid);
+ }
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_mass_disklabel_handler);
+
+ close (fd);
+
+ g_free (rdevpath);
+ g_free (devpath);
+
+ return d;
+}
diff --git a/hal/files/hald-netbsd/devinfo_mass.h b/hal/files/hald-netbsd/devinfo_mass.h
new file mode 100644
index 0000000000..1b7bdc91f4
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_mass.h
@@ -0,0 +1,37 @@
+/* $NetBSD: devinfo_mass.h,v 1.1 2008/12/01 02:02:33 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2008 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DEVINFO_MASS_H
+#define DEVINFO_MASS_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_mass_handler;
+extern DevinfoDevHandler devinfo_mass_disklabel_handler;
+
+#endif /* DEVINFO_MASS_H */
diff --git a/hal/files/hald-netbsd/devinfo_misc.c b/hal/files/hald-netbsd/devinfo_misc.c
new file mode 100644
index 0000000000..ffb8d2a079
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_misc.c
@@ -0,0 +1,168 @@
+/***************************************************************************
+ *
+ * devinfo_misc : misc devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/utsname.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "devinfo_misc.h"
+#include "drvctl.h"
+
+static HalDevice *devinfo_computer_add(HalDevice *, const char *, char *, char *);
+static HalDevice *devinfo_cpu_add(HalDevice *, const char *, char *,char *);
+static HalDevice *devinfo_default_add(HalDevice *, const char *, char *, char *);
+
+DevinfoDevHandler devinfo_computer_handler = {
+ devinfo_computer_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_cpu_handler = {
+ devinfo_cpu_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_default_handler = {
+ devinfo_default_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static HalDevice *
+devinfo_computer_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type)
+{
+ HalDevice *d;
+ struct utsname un;
+ char acpi_supported_states[20];
+ size_t len = sizeof(acpi_supported_states);
+
+ if (strcmp (devnode, "mainbus0") != 0) {
+ return (NULL);
+ }
+
+ HAL_INFO (("devinfo_computer_add parent=%p devnode=%s devfs_path=%s device_type=%s",
+ parent, devnode, devfs_path, device_type));
+
+ d = hal_device_new ();
+
+ hal_device_property_set_string (d, "info.subsystem", "unknown");
+ hal_device_property_set_string (d, "info.product", "Computer");
+ hal_device_set_udi (d, "/org/freedesktop/Hal/devices/computer");
+ hal_device_property_set_string (d, "netbsd.device", devnode);
+
+ if (uname (&un) >= 0) {
+ hal_device_property_set_string (d, "system.kernel.name", un.sysname);
+ hal_device_property_set_string (d, "system.kernel.version", un.release);
+ hal_device_property_set_string (d, "system.kernel.machine", un.machine);
+ }
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_computer_handler);
+
+ if (sysctlbyname ("hw.acpi.supported_states", acpi_supported_states, &len, NULL, 0) == 0 ||
+ sysctlbyname ("hw.acpi.sleep.states", acpi_supported_states, &len, NULL, 0) == 0) {
+ hal_device_property_set_string (d, "power_management.type", "acpi");
+ if (strstr (acpi_supported_states, "S3") != NULL)
+ hal_device_property_set_bool (d, "power_management.can_suspend", TRUE);
+ else
+ hal_device_property_set_bool (d, "power_management.can_suspend", FALSE);
+
+ hal_device_property_set_bool (d, "power_management.can_hibernate", FALSE);
+ }
+
+ if (drvctl_find_device ("acpibat0", NULL) == TRUE)
+ hal_device_property_set_string (d, "system.formfactor", "laptop");
+ else
+ hal_device_property_set_string (d, "system.formfactor", "desktop"); /* XXX */
+
+ devinfo_add_enqueue (d, devnode, &devinfo_default_handler);
+
+ return d;
+}
+
+static HalDevice *
+devinfo_cpu_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type)
+{
+ HalDevice *d;
+
+ if (strncmp(devnode, "cpu", 3) != 0) {
+ return (NULL);
+ }
+
+ HAL_INFO (("devinfo_cpu_add: parent=%p devnode=%s devfs_path=%s device_type=%s",
+ parent, devnode, devfs_path, device_type));
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, devnode, devnode);
+ hal_device_add_capability (d, "processor");
+
+ devinfo_add_enqueue (d, devnode, &devinfo_cpu_handler);
+
+ return (d);
+}
+
+static void
+devinfo_default_apply_quirks(HalDevice *d, const char *devnode)
+{
+
+/* acpiacad(4) */
+ if (strncmp (devnode, "acpiacad", 8) == 0) {
+ HAL_INFO (("%s: applying acpiacad quirks",devnode));
+ hal_device_add_capability (d, "ac_adapter");
+
+/* acpibat(4) */
+ } else if (strncmp (devnode, "acpibat", 7) == 0) {
+ HAL_INFO (("%s: applying acpibat quirks",devnode));
+ hal_device_add_capability (d, "battery");
+ hal_device_property_set_string (d, "battery.type", "primary");
+ }
+
+}
+
+static HalDevice *
+devinfo_default_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type)
+{
+ char *driver_name;
+ const char *parent_path;
+ HalDevice *d;
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, devnode, devnode);
+
+ devinfo_default_apply_quirks (d, devnode);
+
+ devinfo_add_enqueue (d, devnode, &devinfo_default_handler);
+
+ return (d);
+}
diff --git a/hal/files/hald-netbsd/devinfo_misc.h b/hal/files/hald-netbsd/devinfo_misc.h
new file mode 100644
index 0000000000..ef666ff38c
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_misc.h
@@ -0,0 +1,21 @@
+/***************************************************************************
+ *
+ * devinfo_misc.h : definitions for misc devices
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifndef DEVINFO_MISC_H
+#define DEVINFO_MISC_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_computer_handler;
+extern DevinfoDevHandler devinfo_keyboard_handler;
+extern DevinfoDevHandler devinfo_default_handler;
+
+#endif /* DEVINFO_MISC_H */
diff --git a/hal/files/hald-netbsd/devinfo_optical.c b/hal/files/hald-netbsd/devinfo_optical.c
new file mode 100644
index 0000000000..e435f32231
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_optical.c
@@ -0,0 +1,485 @@
+/*
+ * Copyright (c) 2008 Reinoud Zandijk
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/scsiio.h>
+#include <sys/disklabel.h>
+#include <dev/scsipi/scsi_spc.h>
+#include <dev/scsipi/scsipi_all.h>
+#include <dev/scsipi/scsipi_cd.h>
+#include <string.h>
+#include <machine/disklabel.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <fcntl.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "devinfo_optical.h"
+
+#include "devinfo.h"
+
+
+#define DEVINFO_PROBE_STORAGE_TIMEOUT 60000
+static HalDevice *devinfo_optical_add(HalDevice *, const char *, char *,char *);
+static HalDevice *devinfo_optical_volume_add(HalDevice *, const char *, char *, char *);
+
+
+static const gchar *
+devinfo_storage_get_prober (HalDevice *d, int *timeout)
+{
+ *timeout = DEVINFO_PROBE_STORAGE_TIMEOUT;
+ return "hald-probe-storage";
+}
+
+#if notyet
+const gchar *
+devinfo_volume_get_prober (HalDevice *d, int *timeout)
+{
+ *timeout = DEVINFO_PROBE_VOLUME_TIMEOUT;
+ return "hald-probe-volume";
+}
+#endif
+
+DevinfoDevHandler devinfo_optical_handler = {
+ devinfo_optical_add,
+ NULL, /* remove */
+ NULL, /* hotplug_begin_add */
+ NULL, /* hotplug_begin_remove */
+ NULL, /* probing_done */
+ NULL /* devinfo_storage_get_prober */ /* get_prober */
+};
+
+
+DevinfoDevHandler devinfo_optical_volume_handler = {
+ devinfo_optical_volume_add,
+ NULL, /* remove */
+ NULL, /* hotplug_begin_add */
+ NULL, /* hotplug_begin_remove */
+ NULL, /* probing_done */
+ NULL /* devinfo_storage_get_prober */ /* get_prober */
+};
+
+
+/* XXX i dont know how to link cdutils here XXX ! */
+bool
+scsi_command (int fd, void *cmd, size_t cmdlen, void *data, size_t datalen,
+ int timeout, int flags)
+{
+ scsireq_t req;
+
+ memset(&req, 0, sizeof(req));
+ memcpy(req.cmd, cmd, cmdlen);
+ req.cmdlen = cmdlen;
+ req.databuf = data;
+ req.datalen = datalen;
+ req.timeout = timeout;
+ req.flags = flags;
+ req.senselen = SENSEBUFLEN;
+
+ if (ioctl(fd, SCIOCCOMMAND, &req) == -1)
+ return false;
+ if (req.retsts == SCCMD_OK)
+ return true;
+ return false;
+}
+
+
+static void
+optical_get_str(char *str, unsigned char *buf, int len)
+{
+ char *pos;
+ int i;
+
+ pos = str;
+ for (i = 0; i < len; i++) {
+ if (isprint(buf[i]))
+ *pos++ = buf[i];
+ }
+ *pos = (char) 0;
+ pos--;
+ while (*pos == ' ')
+ *pos-- = (char) 0;
+}
+
+
+static void
+devinfo_optical_identify_drive(HalDevice *d, char *devstr)
+{
+ uint8_t cmd[12], buf[100];
+ char str[100];
+ int fd, ok;
+
+ fd = open(devstr, O_RDONLY, 0);
+ if(!fd)
+ return;
+
+ HAL_INFO(("devinfo_optical_identify_drive: SCSI call"));
+ cmd[0] = 0x12; /* INQUIRY */
+ cmd[1] = 0; /* basic inquiry */
+ cmd[2] = 0; /* no page or operation code */
+ cmd[3] = 0; /* reserved/MSB result */
+ cmd[4] = 96; /* all but vendor specific */
+ cmd[5] = 0; /* control */
+ ok = scsi_command(fd, cmd, 6, buf, 96, 30000, SCCMD_READ);
+ close(fd);
+
+ if (!ok)
+ return;
+
+ optical_get_str(str, buf+8, 8);
+ hal_device_property_set_string (d, "storage.vendor", str);
+ optical_get_str(str, buf+16, 16);
+ hal_device_property_set_string (d, "storage.model", str);
+ optical_get_str(str, buf+32, 4);
+ hal_device_property_set_string (d, "storage.firmware_version", str);
+}
+
+
+static char const *
+get_profile_name(HalDevice *d, int profile)
+{
+ switch (profile) {
+ case 0x00 : return NULL; // "Unknown[0] profile";
+ case 0x01 : return NULL; // "Non removeable disc";
+ case 0x02 : return NULL; // "Removable disc";
+ case 0x03 : return "mo"; // Magneto Optical with sector erase";
+ case 0x04 : return "mo"; // "Magneto Optical write once";
+ case 0x05 : return "mo"; // "Advance Storage Magneto Optical";
+ case 0x08 : return "cd"; // "CD-ROM"; no writing
+ case 0x09 : return "cdr"; // "CD-R recordable";
+ case 0x0a : return "cdrw"; // "CD-RW rewritable";
+ case 0x10 : return "dvd"; // "DVD-ROM"; no writing
+ case 0x11 : return "dvdr"; // "DVD-R sequential";
+ case 0x12 : return "dvdram"; // "DVD-RAM rewritable";
+ case 0x13 : return "dvdrw"; // "DVD-RW restricted overwrite";
+ case 0x14 : return "dvdrw"; // "DVD-RW sequential";
+ case 0x15 : return "dvdr"; // "DVD-R dual layer sequential";
+ case 0x16 : return "dvdr"; // "DVD-R dual layer jump";
+ case 0x17 : return "dvdrw"; // "DVD-RW dual layer";
+ case 0x18 : return NULL; // "DVD-Download disc"; UNKNOWN
+ case 0x1a : return "dvdplusrw"; // "DVD+RW rewritable";
+ case 0x1b : return "dvdplusr"; // "DVD+R recordable";
+ case 0x20 : return "ddcd"; // "DDCD readonly (retracted)"; no writing
+ case 0x21 : return "ddcdr"; // "DDCD-R recordable (retracted)"; OK?
+ case 0x22 : return "ddcdrw"; // "DDCD-RW rewritable (retracted)"; OK?
+ case 0x2a : return "dvdplusrwdl";//"DVD+RW double layer";
+ case 0x2b : return "dvdplusrdl";// "DVD+R double layer";
+ case 0x40 : return "bd"; // "BD-ROM";
+ case 0x41 : return "bdr"; // "BD-R Sequential Recording (SRM)";
+ case 0x42 : return "bdr"; // "BD-R Random Recording (RRM)";
+ case 0x43 : return "bdre"; // "BD-RE rewritable";
+ case 0x50 : return "hddvd"; // "HD DVD-ROM (retracted)";
+ case 0x51 : return "hddvdr"; // "HD DVD-R (retracted)";
+ case 0x52 : return "hddvdram"; // "HD DVD-RAM (retracted)";
+ case 0x53 : return "hddvdrw"; // "HD DVD-RW (retracted)";
+ case 0x58 : return "hddvdrdl"; // "HD DVD-R dual layer (retracted)";
+ case 0x5a : return "hddvdrwdl"; // "HD DVD-RW dual layer (retracted)";
+ }
+ /* reserved */
+ return NULL;
+}
+
+
+#define feat_tbl_len 300
+#define max_profile 255
+static void
+devinfo_optical_disc_caps(int fd, HalDevice *d)
+{
+ uint8_t cmd[12], buf[feat_tbl_len], *fpos, *pos;
+ char str[100];
+ uint8_t present[max_profile+1];
+ char const *name;
+ int feature, feature_cur, feature_len, req_feature;
+ int cnt, profile;
+ int mrw, mrw_w, ok;
+
+ /* set defaults */
+ for (profile = 0; profile <= max_profile; profile++) {
+ present[profile] = FALSE;
+ }
+
+ HAL_INFO(("devinfo_optical_disc_caps: get feature 0 SCSI call"));
+ req_feature = 0;
+ cmd[0] = 0x46; /* Get configuration */
+ cmd[1] = 0; /* RT=0 -> all independent of current setting */
+ cmd[2] = (req_feature) >> 8; /* MSB feature number */
+ cmd[3] = (req_feature) & 0xff; /* LSB feature number */
+ cmd[7] = (feat_tbl_len) >> 8; /* MSB buffersize */
+ cmd[8] = (feat_tbl_len) & 0xff; /* LSB buffersize */
+ cmd[9] = 0; /* control */
+ ok = scsi_command(fd, cmd, 10, buf, feat_tbl_len, 30000, SCCMD_READ);
+
+ if (!ok)
+ return;
+
+ HAL_INFO(("devinfo_optical_disc_caps: processing profiles\n"));
+ fpos = buf + 8;
+
+ feature = fpos[1] | (fpos[0] << 8);
+ feature_cur = (fpos[2] & 1);
+ feature_len = fpos[3];
+ if (feature != 0) {
+ HAL_INFO(("cdrom drive on crack, its not returning feature 0\n"));
+ return;
+ }
+
+ if ((feature_len & 3) != 0)
+ HAL_INFO(("*** drive returned bad feature length ***"));
+
+ /* process feature */
+ pos = &fpos[4];
+ for (cnt=0; cnt < feature_len; cnt += 4) {
+ profile = pos[1] | (pos[0] << 8);
+ if (profile <= max_profile) {
+ present[profile] = TRUE;
+ } else {
+ if (profile != 0xffff)
+ HAL_INFO(("devinfo_optical_disc_caps: bump max_profile!, "
+ "found profile %d", profile));
+ }
+ pos += 4;
+ }
+
+ /* set hal properties */
+ for (profile = 0; profile <= max_profile; profile++) {
+ /* process profile */
+ name = get_profile_name(d, profile);
+ if (name) {
+ strcpy(str, "storage.cdrom.");
+ strcat(str, name);
+ HAL_INFO(("Profile %d : %s : %s", profile, str,
+ present[profile] ? "true":"false"));
+ hal_device_property_set_bool(d, str, present[profile]);
+ }
+ }
+
+ /* set MRW support; feature 0x28, version 0/1 */
+ HAL_INFO(("devinfo_optical_disc_caps: get feature 0x28 SCSI call"));
+ req_feature = 0x28;
+ cmd[0] = 0x46; /* Get configuration */
+ cmd[1] = 0; /* RT=0 -> all independent of current setting */
+ cmd[2] = (req_feature) >> 8; /* MSB feature number */
+ cmd[3] = (req_feature) & 0xff; /* LSB feature number */
+ cmd[7] = (feat_tbl_len) >> 8; /* MSB buffersize */
+ cmd[8] = (feat_tbl_len) & 0xff; /* LSB buffersize */
+ cmd[9] = 0; /* control */
+ ok = scsi_command(fd, cmd, 10, buf, feat_tbl_len, 30000, SCCMD_READ);
+
+ if (!ok)
+ return;
+
+ feature = fpos[1] | (fpos[0] << 8);
+ feature_cur = (fpos[2] & 1);
+ feature_len = fpos[3];
+
+ if ((feature_len & 3) != 0)
+ HAL_INFO(("*** drive returned bad feature length ***"));
+
+ HAL_INFO(("devinfo_optical_disc_caps: processing MRW\n"));
+ /* process feature */
+ pos = &fpos[4];
+ mrw = FALSE;
+ mrw_w = FALSE;
+ if (feature == 0x28) {
+ mrw = TRUE;
+ if (pos[0] & 1)
+ mrw_w = TRUE;
+ }
+ hal_device_property_set_bool(d, "storage.cdrom.mrw", mrw);
+ hal_device_property_set_bool(d, "storage.cdrom.mrw_w", mrw_w);
+
+ /*
+ * XXX very rare to now have multi-session support; could be detected
+ * in the change bits of page 5, but set to true for now
+ */
+ hal_device_property_set_bool(d, "storage.cdrom.support_multisession", TRUE);
+
+ /* XXX realy? */
+ hal_device_property_set_bool(d, "storage.cdrom.support_media_changed", TRUE);
+
+ /* media dependent; addon-storage will handle these */
+ //hal_device_property_set_int(d,"storage.cdrom.read_speed", 0);
+ //hal_device_property_set_int(d,"storage.cdrom.write_speed", 0);
+ //hal_device_property_set_string(d, "storage.cdrom.write_speeds", FALSE);
+
+}
+#undef max_profile
+#undef feat_tbl_len
+
+
+static HalDevice *
+devinfo_optical_volume_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type)
+{
+ HalDevice *d;
+ struct stat devstat;
+ char *devstr;
+ int error;
+
+ HAL_INFO (("devinfo_optical_volume_add: parent=%p devnode=%s devfs_path=%s device_type=%s",
+ parent, devnode, devfs_path, device_type));
+
+ d = hal_device_new ();
+
+ devstr = malloc(strlen(devnode) + 10);
+
+ /* info */
+ devinfo_set_default_properties (d, parent, devnode, devnode);
+ hal_device_add_capability (d, "block");
+ hal_device_add_capability (d, "volume");
+ hal_device_add_capability (d, "volume.disc");
+ hal_device_property_set_string (d, "info.category", "volume");
+
+ /* block */
+ sprintf(devstr, "/dev/%s", devnode);
+ hal_device_property_set_string (d, "block.device", devstr);
+ error = stat(devstr, &devstat);
+ if (!error) {
+ hal_device_property_set_int (d, "block.major", major(devstat.st_rdev));
+ hal_device_property_set_int (d, "block.minor", minor(devstat.st_rdev));
+ }
+ sprintf(devstr, "/dev/r%s", devnode);
+ hal_device_property_set_string (d, "block.netbsd.raw_device", devstr);
+
+ hal_device_property_set_bool (d, "block.is_volume", TRUE);
+ hal_device_property_set_bool (d, "block.no_partitions", TRUE);
+ hal_device_property_set_bool (d, "block.have_scanned", TRUE);
+ hal_device_property_set_string (d, "block.storage_device",
+ hal_device_property_get_string (parent, "info.udi"));
+
+ /* volume */
+ hal_device_property_set_bool (d, "volume.ignore", FALSE);
+ hal_device_property_set_string(d, "volume.fsusage", "filesytem");
+ hal_device_property_set_string(d, "volume.fstype", "");
+ hal_device_property_set_string(d, "volume.label", "");
+ hal_device_property_set_bool (d, "volume.is_disc", TRUE);
+ hal_device_property_set_bool (d, "volume.is_partition", FALSE);
+ /* rest by addon */
+
+ /* volume.disc */
+ /* by addon */
+
+ devinfo_add_enqueue (d, devnode, &devinfo_optical_volume_handler);
+
+ return d;
+}
+
+
+static HalDevice *
+devinfo_optical_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type)
+{
+ HalDevice *d;
+ struct stat devstat;
+ char *devstr;
+ char *parent_devnode;
+ int fd, error;
+
+ if (strncmp(devnode, "cd", 2) != 0) {
+ return (NULL);
+ }
+
+ HAL_INFO (("devinfo_optical_add: parent=%p devnode=%s devfs_path=%s device_type=%s",
+ parent, devnode, devfs_path, device_type));
+
+ d = hal_device_new ();
+
+ devstr = malloc(strlen(devnode) + 10);
+
+ /* info */
+ devinfo_set_default_properties (d, parent, devnode, devnode);
+// hal_device_property_set_string (d, "netbsd.device", devfs_path);
+
+ hal_device_property_set_string (d, "info.subsystem", "block");
+ hal_device_add_capability (d, "block");
+ hal_device_add_capability (d, "storage");
+ hal_device_add_capability (d, "storage.cdrom");
+
+ /* block */
+ sprintf(devstr, "/dev/%s%c", devnode, 'a' + RAW_PART);
+ hal_device_property_set_string (d, "block.device", devstr);
+ error = stat(devstr, &devstat);
+ if (!error) {
+ hal_device_property_set_int (d, "block.major", major(devstat.st_rdev));
+ hal_device_property_set_int (d, "block.minor", minor(devstat.st_rdev));
+ }
+ sprintf(devstr, "/dev/r%s%c", devnode, 'a' + RAW_PART);
+ hal_device_property_set_string (d, "block.netbsd.raw_device", devstr);
+
+ hal_device_property_set_bool (d, "block.is_volume", FALSE);
+ hal_device_property_set_bool (d, "block.no_partitions", TRUE);
+ hal_device_property_set_bool (d, "block.have_scanned", TRUE);
+
+ /* storage */
+ parent_devnode = hal_device_property_get_string (parent, "netbsd.device");
+ if (strstr (parent_devnode, "umass") == parent_devnode)
+ hal_device_property_set_string (d, "storage.bus", "usb");
+ else if (strstr (parent_devnode, "atapi") == parent_devnode)
+ hal_device_property_set_string (d, "storage.bus", "ide");
+ else
+ hal_device_property_set_string (d, "storage.bus", "scsi");
+
+ hal_device_property_set_string (d, "storage.drive_type", "cdrom");
+ hal_device_property_set_bool (d, "storage.removable", TRUE);
+ /* "storage.removable.media_available" set by addon-storage */
+ /* "storage.removable.media_size" set by addon-storage */
+ hal_device_property_set_bool (d, "storage.removable.support_async_notification", FALSE);
+ hal_device_property_set_bool (d, "storage.requires_eject", TRUE);
+ hal_device_property_set_bool (d, "storage.hotpluggable", TRUE);
+ hal_device_property_set_bool (d, "storage.media_check_enabled", TRUE); /* XXX */
+ hal_device_property_set_bool (d, "storage.automount_enabled_hint", FALSE); /* multiple choice */
+ hal_device_property_set_bool (d, "storage.no_partitions_hint", TRUE);
+ hal_device_property_set_string (d, "storage.originating_device", ""); /* XXX */
+
+ fd = open(devstr, O_RDONLY, 0);
+ if (fd) {
+ /* get drive's vendor and model name */
+ devinfo_optical_identify_drive(d, devstr);
+
+ /* get CD specific `storage.cdrom' values */
+ devinfo_optical_disc_caps(fd, d);
+
+ }
+ devinfo_add_enqueue (d, devnode, &devinfo_optical_handler);
+ if (fd) {
+ /* create CD volume node */
+ sprintf(devstr, "%s%c", devnode, 'a' + RAW_PART);
+ devinfo_optical_volume_add(d, devstr, devfs_path, "volume");
+ }
+ close(fd);
+
+ return (d);
+}
+
diff --git a/hal/files/hald-netbsd/devinfo_optical.h b/hal/files/hald-netbsd/devinfo_optical.h
new file mode 100644
index 0000000000..2dc7775a7a
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_optical.h
@@ -0,0 +1,20 @@
+/***************************************************************************
+ *
+ * devinfo_optical.h : definition for optical (MMC compliant) media
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifndef DEVINFO_OPTICAL_H
+#define DEVINFO_OPTICAL_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_optical_handler;
+
+#endif /* DEVINFO_OPTICAL_H */
+
diff --git a/hal/files/hald-netbsd/devinfo_pci.c b/hal/files/hald-netbsd/devinfo_pci.c
new file mode 100644
index 0000000000..415d2f6dc9
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_pci.c
@@ -0,0 +1,122 @@
+/***************************************************************************
+ *
+ * devinfo_pci.c : PCI devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "@(#)devinfo_pci.c 1.2 06/10/13 SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <libdevinfo.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../ids.h"
+#include "devinfo_pci.h"
+
+HalDevice *devinfo_pci_add (HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+
+DevinfoDevHandler devinfo_pci_handler = {
+ devinfo_pci_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+HalDevice *devinfo_pci_add (HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ HalDevice *d;
+ char *s;
+ int *i;
+ int vid, pid, svid, spid;
+
+ if ((device_type == NULL) ||
+ ((strcmp (device_type, "pci") != 0) &&
+ (strcmp (device_type, "pci-ide") != 0))) {
+ if (parent == NULL) {
+ return (NULL);
+ } else {
+ s = (char *)hal_device_property_get_string (parent, "info.subsystem");
+ if ((s == NULL) || (strcmp (s, "pci") != 0)) {
+ return (NULL);
+ }
+ }
+ }
+
+ d = hal_device_new ();
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+
+ hal_device_property_set_string (d, "info.subsystem", "pci");
+
+ vid = pid = svid = spid = 0;
+ if (di_prop_lookup_ints (DDI_DEV_T_ANY, node, "vendor-id", &i) > 0) {
+ vid = i[0];
+ }
+ if (di_prop_lookup_ints (DDI_DEV_T_ANY, node, "device-id", &i) > 0) {
+ pid = i[0];
+ }
+ if (di_prop_lookup_ints (DDI_DEV_T_ANY, node, "subsystem-vendor-id", &i) > 0) {
+ svid = i[0];
+ }
+ if (di_prop_lookup_ints (DDI_DEV_T_ANY, node, "subsystem-id", &i) > 0) {
+ spid = i[0];
+ }
+ hal_device_property_set_int (d, "pci.vendor_id", vid);
+ hal_device_property_set_int (d, "pci.product_id", pid);
+ hal_device_property_set_int (d, "pci.subsys_vendor_id", svid);
+ hal_device_property_set_int (d, "pci.subsys_product_id", spid);
+
+ {
+ char *vendor_name;
+ char *product_name;
+ char *subsys_vendor_name;
+ char *subsys_product_name;
+
+ ids_find_pci (hal_device_property_get_int (d, "pci.vendor_id"),
+ hal_device_property_get_int (d, "pci.product_id"),
+ hal_device_property_get_int (d, "pci.subsys_vendor_id"),
+ hal_device_property_get_int (d, "pci.subsys_product_id"),
+ &vendor_name, &product_name, &subsys_vendor_name,
+&subsys_product_name);
+
+ if (vendor_name != NULL) {
+ hal_device_property_set_string (d, "pci.vendor", vendor_name);
+ hal_device_property_set_string (d, "info.vendor", vendor_name);
+ }
+
+ if (product_name != NULL) {
+ hal_device_property_set_string (d, "pci.product", product_name);
+ hal_device_property_set_string (d, "info.product", product_name);
+ }
+
+ if (subsys_vendor_name != NULL) {
+ hal_device_property_set_string (d, "pci.subsys_vendor",
+subsys_vendor_name);
+ }
+
+ if (subsys_product_name != NULL) {
+ hal_device_property_set_string (d, "pci.subsys_product", subsys_product_name);
+ }
+ }
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_pci_handler);
+
+ return (d);
+}
+
diff --git a/hal/files/hald-netbsd/devinfo_pci.h b/hal/files/hald-netbsd/devinfo_pci.h
new file mode 100644
index 0000000000..dbeb4f6e47
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_pci.h
@@ -0,0 +1,21 @@
+/***************************************************************************
+ *
+ * devinfo_pci.h : definitions for PCI devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef DEVINFO_PCI_H
+#define DEVINFO_PCI_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_pci_handler;
+
+#endif /* DEVINFO_PCI_H */
diff --git a/hal/files/hald-netbsd/devinfo_storage.c b/hal/files/hald-netbsd/devinfo_storage.c
new file mode 100644
index 0000000000..ca711bb9db
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_storage.c
@@ -0,0 +1,1671 @@
+/***************************************************************************
+ *
+ * devinfo_storage.c : storage devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "@(#)devinfo_storage.c 1.2 06/10/13 SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#include <libdevinfo.h>
+#include <sys/types.h>
+#include <sys/mkdev.h>
+#include <sys/stat.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../hald_runner.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "devinfo_misc.h"
+#include "devinfo_storage.h"
+#include "osspec_netbsd.h"
+
+#ifdef sparc
+#define WHOLE_DISK "s2"
+#else
+#define WHOLE_DISK "p0"
+#endif
+
+/* some devices,especially CDROMs, may take a while to be probed (values in ms) */
+#define DEVINFO_PROBE_STORAGE_TIMEOUT 60000
+#define DEVINFO_PROBE_VOLUME_TIMEOUT 60000
+
+typedef struct devinfo_storage_minor {
+ char *devpath;
+ char *devlink;
+ char *slice;
+ dev_t dev;
+ int dosnum; /* dos disk number or -1 */
+} devinfo_storage_minor_t;
+
+HalDevice *devinfo_ide_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+static HalDevice *devinfo_ide_host_add(HalDevice *parent, di_node_t node, char *devfs_path);
+static HalDevice *devinfo_ide_device_add(HalDevice *parent, di_node_t node, char *devfs_path);
+static HalDevice *devinfo_ide_storage_add(HalDevice *grampa, HalDevice *parent, di_node_t node, char *devfs_path);
+HalDevice *devinfo_scsi_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+static HalDevice *devinfo_scsi_storage_add(HalDevice *grampa, HalDevice *parent, di_node_t node, char *devfs_path);
+HalDevice *devinfo_floppy_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+static void devinfo_floppy_add_volume(HalDevice *parent, di_node_t node);
+static HalDevice *devinfo_lofi_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+static void devinfo_lofi_add_minor(HalDevice *parent, di_node_t node, char *minor_path, char *devlink, dev_t dev);
+static int walk_devlinks(di_devlink_t devlink, void *arg);
+static char *get_devlink(di_devlink_handle_t devlink_hdl, char *path);
+static void devinfo_storage_minors(HalDevice *parent, di_node_t node, gchar *devfs_path, gboolean);
+static struct devinfo_storage_minor *devinfo_storage_new_minor(char *maindev_path, char *slice,
+ char *devlink, dev_t dev, int dosnum);
+static void devinfo_storage_free_minor(struct devinfo_storage_minor *m);
+HalDevice *devinfo_volume_add(HalDevice *parent, di_node_t node, devinfo_storage_minor_t *m);
+static void devinfo_volume_preprobing_done(HalDevice *d, gpointer userdata1, gpointer userdata2);
+static void devinfo_volume_hotplug_begin_add (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token);
+static void devinfo_storage_hotplug_begin_add (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token);
+static void devinfo_storage_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2);
+const gchar *devinfo_volume_get_prober (HalDevice *d, int *timeout);
+const gchar *devinfo_storage_get_prober (HalDevice *d, int *timeout);
+
+static char *devinfo_scsi_dtype2str(int dtype);
+static char *devinfo_volume_get_slice_name (char *devlink);
+static gboolean dos_to_dev(char *path, char **devpath, int *partnum);
+static gboolean is_dos_path(char *path, int *partnum);
+
+static void devinfo_storage_set_nicknames (HalDevice *d);
+
+DevinfoDevHandler devinfo_ide_handler = {
+ devinfo_ide_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_scsi_handler = {
+ devinfo_scsi_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_floppy_handler = {
+ devinfo_floppy_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_lofi_handler = {
+ devinfo_lofi_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_storage_handler = {
+ NULL,
+ NULL,
+ devinfo_storage_hotplug_begin_add,
+ NULL,
+ devinfo_storage_probing_done,
+ devinfo_storage_get_prober
+};
+DevinfoDevHandler devinfo_volume_handler = {
+ NULL,
+ NULL,
+ devinfo_volume_hotplug_begin_add,
+ NULL,
+ NULL,
+ devinfo_volume_get_prober
+};
+
+/* IDE */
+
+HalDevice *
+devinfo_ide_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ char *s;
+
+ if ((device_type != NULL) && (strcmp(device_type, "ide") == 0)) {
+ return (devinfo_ide_host_add(parent, node, devfs_path));
+ }
+
+ if ((di_prop_lookup_strings (DDI_DEV_T_ANY, node, "class", &s) > 0) &&
+ (strcmp (s, "dada") == 0)) {
+ return (devinfo_ide_device_add(parent, node, devfs_path));
+ }
+
+ return (NULL);
+}
+
+static HalDevice *
+devinfo_ide_host_add(HalDevice *parent, di_node_t node, char *devfs_path)
+{
+ HalDevice *d;
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.product", "IDE host controller");
+ hal_device_property_set_string (d, "info.subsystem", "ide_host");
+ hal_device_property_set_int (d, "ide_host.number", 0); /* XXX */
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_ide_handler);
+
+ return (d);
+}
+
+static HalDevice *
+devinfo_ide_device_add(HalDevice *parent, di_node_t node, char *devfs_path)
+{
+ HalDevice *d;
+
+ d = hal_device_new();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (parent, "info.product", "IDE device");
+ hal_device_property_set_string (parent, "info.subsystem", "ide");
+ hal_device_property_set_int (parent, "ide.host", 0); /* XXX */
+ hal_device_property_set_int (parent, "ide.channel", 0);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_ide_handler);
+
+ return (devinfo_ide_storage_add (parent, d, node, devfs_path));
+}
+
+static HalDevice *
+devinfo_ide_storage_add(HalDevice *grampa, HalDevice *parent, di_node_t node, char *devfs_path)
+{
+ HalDevice *d;
+ char *s;
+ int *i;
+ char *driver_name;
+ char udi[HAL_PATH_MAX];
+
+ if ((driver_name = di_driver_name (node)) == NULL) {
+ return (NULL);
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.category", "storage");
+
+ hald_compute_udi (udi, sizeof (udi),
+ "%s/%s%d", hal_device_get_udi (parent),
+ driver_name, di_instance (node));
+ hal_device_set_udi (d, udi);
+ PROP_STR(d, node, s, "devid", "info.product");
+
+ hal_device_add_capability (d, "storage");
+ hal_device_property_set_string (d, "storage.bus", "ide");
+ hal_device_property_set_int (d, "storage.lun", 0);
+ hal_device_property_set_string (d, "storage.drive_type", "disk");
+
+ PROP_BOOL(d, node, i, "hotpluggable", "storage.hotpluggable");
+ PROP_BOOL(d, node, i, "removable-media", "storage.removable");
+
+ hal_device_property_set_bool (d, "storage.media_check_enabled", FALSE);
+
+ /* XXX */
+ hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
+
+ hal_device_add_capability (d, "block");
+
+ devinfo_storage_minors (d, node, (char *)devfs_path, FALSE);
+
+ return (d);
+}
+
+/* SCSI */
+
+HalDevice *
+devinfo_scsi_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ int *i;
+ char *driver_name;
+ HalDevice *d;
+ char udi[HAL_PATH_MAX];
+
+ driver_name = di_driver_name (node);
+ if ((driver_name == NULL) || (strcmp (driver_name, "sd") != 0)) {
+ return (NULL);
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.subsystem", "scsi");
+
+ hald_compute_udi (udi, sizeof (udi),
+ "%s/%s%d", hal_device_get_udi (parent),
+ di_node_name(node), di_instance (node));
+ hal_device_set_udi (d, udi);
+
+ hal_device_property_set_int (d, "scsi.host",
+ hal_device_property_get_int (parent, "scsi_host.host"));
+ hal_device_property_set_int (d, "scsi.bus", 0);
+ PROP_INT(d, node, i, "target", "scsi.target");
+ PROP_INT(d, node, i, "lun", "scsi.lun");
+ hal_device_property_set_string (d, "info.product", "SCSI Device");
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_scsi_handler);
+
+ return (devinfo_scsi_storage_add (parent, d, node, devfs_path));
+}
+
+static HalDevice *
+devinfo_scsi_storage_add(HalDevice *grampa, HalDevice *parent, di_node_t node, char *devfs_path)
+{
+ HalDevice *d;
+ int *i;
+ char *s;
+ char udi[HAL_PATH_MAX];
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.category", "storage");
+
+ hald_compute_udi (udi, sizeof (udi),
+ "%s/sd%d", hal_device_get_udi (parent),
+ di_instance (node));
+ hal_device_set_udi (d, udi);
+ PROP_STR(d, node, s, "inquiry-product-id", "info.product");
+
+ hal_device_add_capability (d, "storage");
+
+ hal_device_property_set_int (d, "storage.lun",
+ hal_device_property_get_int (parent, "scsi.lun"));
+ PROP_BOOL(d, node, i, "hotpluggable", "storage.hotpluggable");
+ PROP_BOOL(d, node, i, "removable-media", "storage.removable");
+ hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
+
+ /*
+ * We have to enable polling not only for drives with removable media,
+ * but also for hotpluggable devices, because when a disk is
+ * unplugged while busy/mounted, there is not sysevent generated.
+ * Instead, the HBA driver (scsa2usb, scsa1394) will notify sd driver
+ * and the latter will report DKIO_DEV_GONE via DKIOCSTATE ioctl.
+ * So we have to enable media check so that hald-addon-storage notices
+ * the "device gone" condition and unmounts all associated volumes.
+ */
+ hal_device_property_set_bool (d, "storage.media_check_enabled",
+ ((di_prop_lookup_ints(DDI_DEV_T_ANY, node, "removable-media", &i) >= 0) ||
+ (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "hotpluggable", &i) >= 0)));
+
+ if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "inquiry-device-type",
+ &i) > 0) {
+ s = devinfo_scsi_dtype2str (*i);
+ hal_device_property_set_string (d, "storage.drive_type", s);
+
+ if (strcmp (s, "cdrom") == 0) {
+ hal_device_add_capability (d, "storage.cdrom");
+ hal_device_property_set_bool (d, "storage.no_partitions_hint", TRUE);
+ hal_device_property_set_bool (d, "storage.requires_eject", TRUE);
+ }
+ }
+
+ hal_device_add_capability (d, "block");
+
+ devinfo_storage_minors (d, node, devfs_path, FALSE);
+
+ return (d);
+}
+
+static char *devinfo_scsi_dtype2str(int dtype)
+{
+ char *dtype2str[] = {
+ "disk" , /* DTYPE_DIRECT 0x00 */
+ "tape" , /* DTYPE_SEQUENTIAL 0x01 */
+ "printer", /* DTYPE_PRINTER 0x02 */
+ "processor", /* DTYPE_PROCESSOR 0x03 */
+ "worm" , /* DTYPE_WORM 0x04 */
+ "cdrom" , /* DTYPE_RODIRECT 0x05 */
+ "scanner", /* DTYPE_SCANNER 0x06 */
+ "cdrom" , /* DTYPE_OPTICAL 0x07 */
+ "changer", /* DTYPE_CHANGER 0x08 */
+ "comm" , /* DTYPE_COMM 0x09 */
+ "scsi" , /* DTYPE_??? 0x0A */
+ "scsi" , /* DTYPE_??? 0x0B */
+ "array_ctrl", /* DTYPE_ARRAY_CTRL 0x0C */
+ "esi" , /* DTYPE_ESI 0x0D */
+ "disk" /* DTYPE_RBC 0x0E */
+ };
+
+ if (dtype < NELEM(dtype2str)) {
+ return (dtype2str[dtype]);
+ } else {
+ return ("scsi");
+ }
+
+}
+
+/* floppy */
+
+HalDevice *
+devinfo_floppy_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ char *driver_name;
+ char *raw;
+ char udi[HAL_PATH_MAX];
+ di_devlink_handle_t devlink_hdl;
+ int major;
+ di_minor_t minor;
+ dev_t dev;
+ HalDevice *d = NULL;
+ char *minor_path = NULL;
+ char *devlink = NULL;
+
+ driver_name = di_driver_name (node);
+ if ((driver_name == NULL) || (strcmp (driver_name, "fd") != 0)) {
+ return (NULL);
+ }
+
+ /*
+ * The only minor node we're interested in is /dev/diskette*
+ */
+ major = di_driver_major(node);
+ if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
+ return (NULL);
+ }
+ minor = DI_MINOR_NIL;
+ while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
+ dev = di_minor_devt(minor);
+ if ((major != major(dev)) ||
+ (di_minor_type(minor) != DDM_MINOR) ||
+ (di_minor_spectype(minor) != S_IFBLK) ||
+ ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
+ continue;
+ }
+ if (((devlink = get_devlink(devlink_hdl, minor_path)) != NULL) &&
+ (strncmp (devlink, "/dev/diskette", sizeof ("/dev/diskette") - 1) == 0)) {
+ break;
+ }
+ di_devfs_path_free (minor_path);
+ minor_path = NULL;
+ free(devlink);
+ devlink = NULL;
+ }
+ di_devlink_fini (&devlink_hdl);
+
+ if ((devlink == NULL) || (minor_path == NULL)) {
+ HAL_INFO (("floppy devlink not found %s", devfs_path));
+ goto out;
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.category", "storage");
+ hal_device_add_capability (d, "storage");
+ hal_device_property_set_string (d, "storage.bus", "platform");
+ hal_device_property_set_bool (d, "storage.hotpluggable", FALSE);
+ hal_device_property_set_bool (d, "storage.removable", TRUE);
+ hal_device_property_set_bool (d, "storage.requires_eject", TRUE);
+ hal_device_property_set_bool (d, "storage.media_check_enabled", FALSE);
+ hal_device_property_set_string (d, "storage.drive_type", "floppy");
+
+ hal_device_add_capability (d, "block");
+ hal_device_property_set_bool (d, "block.is_volume", FALSE);
+ hal_device_property_set_int (d, "block.major", major(dev));
+ hal_device_property_set_int (d, "block.minor", minor(dev));
+ hal_device_property_set_string (d, "block.device", devlink);
+ raw = dsk_to_rdsk (devlink);
+ hal_device_property_set_string (d, "block.solaris.raw_device", raw);
+ free (raw);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_storage_handler);
+
+ /* trigger initial probe-volume */
+ devinfo_floppy_add_volume(d, node);
+
+out:
+ di_devfs_path_free (minor_path);
+ free(devlink);
+
+ return (d);
+}
+
+static void
+devinfo_floppy_add_volume(HalDevice *parent, di_node_t node)
+{
+ char *devlink;
+ char *devfs_path;
+ int minor, major;
+ dev_t dev;
+ struct devinfo_storage_minor *m;
+
+ devfs_path = (char *)hal_device_property_get_string (parent, "solaris.devfs_path");
+ devlink = (char *)hal_device_property_get_string (parent, "block.device");
+ major = hal_device_property_get_int (parent, "block.major");
+ minor = hal_device_property_get_int (parent, "block.minor");
+ dev = makedev (major, minor);
+
+ m = devinfo_storage_new_minor (devfs_path, WHOLE_DISK, devlink, dev, -1);
+ devinfo_volume_add (parent, node, m);
+ devinfo_storage_free_minor (m);
+}
+
+/*
+ * After reprobing storage, reprobe its volumes.
+ */
+static void
+devinfo_floppy_rescan_probing_done (HalDevice *d, guint32 exit_type, gint return_code,
+ char **error, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+ const char *devfs_path;
+ di_node_t node;
+ HalDevice *v;
+
+ if (!hal_device_property_get_bool (d, "storage.removable.media_available")) {
+ HAL_INFO (("no floppy media", hal_device_get_udi (d)));
+
+ /* remove child (can only be single volume) */
+ if (((v = hal_device_store_match_key_value_string (hald_get_gdl(),
+ "info.parent", hal_device_get_udi (d))) != NULL) &&
+ ((devfs_path = hal_device_property_get_string (v,
+ "solaris.devfs_path")) != NULL)) {
+ devinfo_remove_enqueue ((char *)devfs_path, NULL);
+ }
+ } else {
+ HAL_INFO (("floppy media found", hal_device_get_udi (d)));
+
+ if ((devfs_path = hal_device_property_get_string(d, "solaris.devfs_path")) == NULL) {
+ HAL_INFO (("no devfs_path", hal_device_get_udi (d)));
+ hotplug_event_process_queue ();
+ return;
+ }
+ if ((node = di_init (devfs_path, DINFOCPYALL)) == DI_NODE_NIL) {
+ HAL_INFO (("di_init %s failed %d", devfs_path, errno));
+ hotplug_event_process_queue ();
+ return;
+ }
+
+ devinfo_floppy_add_volume (d, node);
+
+ di_fini (node);
+ }
+
+ hotplug_event_process_queue ();
+}
+
+/* lofi */
+
+HalDevice *
+devinfo_lofi_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ return (devinfo_lofi_add_major(parent,node, devfs_path, device_type, FALSE, NULL));
+}
+
+HalDevice *
+devinfo_lofi_add_major(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type,
+ gboolean rescan, HalDevice *lofi_d)
+{
+ char *driver_name;
+ HalDevice *d = NULL;
+ char udi[HAL_PATH_MAX];
+ di_devlink_handle_t devlink_hdl;
+ int major;
+ di_minor_t minor;
+ dev_t dev;
+ char *minor_path = NULL;
+ char *devpath, *devlink;
+
+ driver_name = di_driver_name (node);
+ if ((driver_name == NULL) || (strcmp (driver_name, "lofi") != 0)) {
+ return (NULL);
+ }
+
+ if (!rescan) {
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.subsystem", "pseudo");
+
+ hald_compute_udi (udi, sizeof (udi),
+ "%s/%s%d", hal_device_get_udi (parent),
+ di_node_name(node), di_instance (node));
+ hal_device_set_udi (d, udi);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_lofi_handler);
+ } else {
+ d = lofi_d;
+ }
+
+ /*
+ * Unlike normal storage, as in devinfo_storage_minors(), where
+ * sd instance -> HAL storage, sd minor node -> HAL volume,
+ * lofi always has one instance, lofi minor -> HAL storage.
+ * lofi storage never has slices, but it can have
+ * embedded pcfs partitions that fstyp would recognize
+ */
+ major = di_driver_major(node);
+ if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
+ return (d);
+ }
+ minor = DI_MINOR_NIL;
+ while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
+ dev = di_minor_devt(minor);
+ if ((major != major(dev)) ||
+ (di_minor_type(minor) != DDM_MINOR) ||
+ (di_minor_spectype(minor) != S_IFBLK) ||
+ ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
+ continue;
+ }
+ if ((devlink = get_devlink(devlink_hdl, minor_path)) == NULL) {
+ di_devfs_path_free (minor_path);
+ continue;
+ }
+
+ if (!rescan ||
+ (hal_device_store_match_key_value_string (hald_get_gdl (),
+ "solaris.devfs_path", minor_path) == NULL)) {
+ devinfo_lofi_add_minor(d, node, minor_path, devlink, dev);
+ }
+
+ di_devfs_path_free (minor_path);
+ free(devlink);
+ }
+ di_devlink_fini (&devlink_hdl);
+
+ return (d);
+}
+
+static void
+devinfo_lofi_add_minor(HalDevice *parent, di_node_t node, char *minor_path, char *devlink, dev_t dev)
+{
+ HalDevice *d;
+ char *raw;
+ char *doslink;
+ char dospath[64];
+ struct devinfo_storage_minor *m;
+ int i;
+
+ /* add storage */
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, minor_path);
+ hal_device_property_set_string (d, "info.category", "storage");
+ hal_device_add_capability (d, "storage");
+ hal_device_property_set_string (d, "storage.bus", "lofi");
+ hal_device_property_set_bool (d, "storage.hotpluggable", TRUE);
+ hal_device_property_set_bool (d, "storage.removable", FALSE);
+ hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
+ hal_device_property_set_string (d, "storage.drive_type", "disk");
+ hal_device_add_capability (d, "block");
+ hal_device_property_set_int (d, "block.major", major(dev));
+ hal_device_property_set_int (d, "block.minor", minor(dev));
+ hal_device_property_set_string (d, "block.device", devlink);
+ raw = dsk_to_rdsk (devlink);
+ hal_device_property_set_string (d, "block.solaris.raw_device", raw);
+ free (raw);
+ hal_device_property_set_bool (d, "block.is_volume", FALSE);
+
+ devinfo_add_enqueue (d, minor_path, &devinfo_storage_handler);
+
+ /* add volumes: one on main device and a few pcfs candidates */
+ m = devinfo_storage_new_minor(minor_path, WHOLE_DISK, devlink, dev, -1);
+ devinfo_volume_add (d, node, m);
+ devinfo_storage_free_minor (m);
+
+ doslink = (char *)calloc (1, strlen (devlink) + sizeof (":NNN") + 1);
+ if (doslink != NULL) {
+ for (i = 1; i < 16; i++) {
+ snprintf(dospath, sizeof (dospath), WHOLE_DISK":%d", i);
+ sprintf(doslink, "%s:%d", devlink, i);
+ m = devinfo_storage_new_minor(minor_path, dospath, doslink, dev, i);
+ devinfo_volume_add (d, node, m);
+ devinfo_storage_free_minor (m);
+ }
+ free (doslink);
+ }
+}
+
+void
+devinfo_lofi_remove_minor(char *parent_devfs_path, char *name)
+{
+ GSList *i;
+ GSList *devices;
+ HalDevice *d = NULL;
+ const char *devfs_path;
+
+ devices = hal_device_store_match_multiple_key_value_string (hald_get_gdl(),
+ "block.solaris.raw_device", name);
+ for (i = devices; i != NULL; i = g_slist_next (i)) {
+ if (hal_device_has_capability (HAL_DEVICE (i->data), "storage")) {
+ d = HAL_DEVICE (i->data);
+ break;
+ }
+ }
+ g_slist_free (devices);
+
+ if (d == NULL) {
+ HAL_INFO (("device not found %s", name));
+ return;
+ }
+
+ if ((devfs_path = hal_device_property_get_string (d,
+ "solaris.devfs_path")) == NULL) {
+ HAL_INFO (("devfs_path not found %s", hal_device_get_udi (d)));
+ return;
+ }
+
+ if (d != NULL) {
+ devinfo_remove_branch ((char *)devfs_path, d);
+ }
+}
+
+/* common storage */
+
+static int
+walk_devlinks(di_devlink_t devlink, void *arg)
+{
+ char **path= (char **)arg;
+
+ *path = strdup(di_devlink_path(devlink));
+
+ return (DI_WALK_TERMINATE);
+}
+
+static char *
+get_devlink(di_devlink_handle_t devlink_hdl, char *path)
+{
+ char *devlink_path = NULL;
+
+ (void) di_devlink_walk(devlink_hdl, NULL, path,
+ DI_PRIMARY_LINK, &devlink_path, walk_devlinks);
+
+ return (devlink_path);
+}
+
+static void
+devinfo_storage_free_minor(struct devinfo_storage_minor *m)
+{
+ if (m != NULL) {
+ free (m->slice);
+ free (m->devlink);
+ free (m->devpath);
+ free (m);
+ }
+}
+
+static struct devinfo_storage_minor *
+devinfo_storage_new_minor(char *maindev_path, char *slice, char *devlink, dev_t dev, int dosnum)
+{
+ struct devinfo_storage_minor *m;
+ int pathlen;
+ char *devpath;
+
+ m = (struct devinfo_storage_minor *)calloc (sizeof (struct devinfo_storage_minor), 1);
+ if (m != NULL) {
+ /*
+ * For volume's devfs_path we'll use minor_path/slice instead of
+ * minor_path which we use for parent storage device.
+ */
+ pathlen = strlen (maindev_path) + strlen (slice) + 2;
+ devpath = (char *)calloc (1, pathlen);
+ snprintf(devpath, pathlen, "%s/%s", maindev_path, slice);
+
+ m->devpath = devpath;
+ m->devlink = strdup (devlink);
+ m->slice = strdup (slice);
+ m->dev = dev;
+ m->dosnum = dosnum;
+ if ((m->devpath == NULL) || (m->devlink == NULL)) {
+ devinfo_storage_free_minor (m);
+ m = NULL;
+ }
+ }
+ return (m);
+}
+
+/*
+ * Storage minor nodes are potential "volume" objects.
+ * This function also completes building the parent object (main storage device).
+ */
+static void
+devinfo_storage_minors(HalDevice *parent, di_node_t node, gchar *devfs_path, gboolean rescan)
+{
+ di_devlink_handle_t devlink_hdl;
+ gboolean is_cdrom;
+ const char *whole_disk;
+ int major;
+ di_minor_t minor;
+ dev_t dev;
+ char *minor_path = NULL;
+ char *maindev_path = NULL;
+ char *devpath, *devlink;
+ int doslink_len;
+ char *doslink;
+ char dospath[64];
+ char *slice;
+ int pathlen;
+ int i;
+ char *raw;
+ boolean_t maindev_is_d0;
+ GQueue *mq;
+ HalDevice *volume;
+ struct devinfo_storage_minor *m;
+ struct devinfo_storage_minor *maindev = NULL;
+
+ /* for cdroms whole disk is always s2 */
+ is_cdrom = hal_device_has_capability (parent, "storage.cdrom");
+ whole_disk = is_cdrom ? "s2" : WHOLE_DISK;
+
+ major = di_driver_major(node);
+
+ /* the "whole disk" p0/s2/d0 node must come first in the hotplug queue
+ * so we put other minor nodes on the local queue and move to the
+ * hotplug queue up in the end
+ */
+ if ((mq = g_queue_new()) == NULL) {
+ goto err;
+ }
+ if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
+ g_queue_free (mq);
+ goto err;
+ }
+ minor = DI_MINOR_NIL;
+ while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
+ dev = di_minor_devt(minor);
+ if ((major != major(dev)) ||
+ (di_minor_type(minor) != DDM_MINOR) ||
+ (di_minor_spectype(minor) != S_IFBLK) ||
+ ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
+ continue;
+ }
+ if ((devlink = get_devlink(devlink_hdl, minor_path)) == NULL) {
+ di_devfs_path_free (minor_path);
+ continue;
+ }
+
+ slice = devinfo_volume_get_slice_name (devlink);
+ if (strlen (slice) < 2) {
+ free (devlink);
+ di_devfs_path_free (minor_path);
+ continue;
+ }
+
+ /* ignore p1..N - we'll use p0:N instead */
+ if ((strlen (slice) > 1) && (slice[0] == 'p') && isdigit(slice[1]) &&
+ ((atol(&slice[1])) > 0)) {
+ free (devlink);
+ di_devfs_path_free (minor_path);
+ continue;
+ }
+
+ m = devinfo_storage_new_minor(minor_path, slice, devlink, dev, -1);
+ if (m == NULL) {
+ free (devlink);
+ di_devfs_path_free (minor_path);
+ continue;
+ }
+
+ /* main device is either s2/p0 or d0, the latter taking precedence */
+ if ((strcmp (slice, "d0") == 0) ||
+ (((strcmp (slice, whole_disk) == 0) && (maindev == NULL)))) {
+ if (maindev_path != NULL) {
+ di_devfs_path_free (maindev_path);
+ }
+ maindev_path = minor_path;
+ maindev = m;
+ g_queue_push_head (mq, maindev);
+ } else {
+ di_devfs_path_free (minor_path);
+ g_queue_push_tail (mq, m);
+ }
+
+ free (devlink);
+ }
+ di_devlink_fini (&devlink_hdl);
+
+ if (maindev == NULL) {
+ /* shouldn't typically happen */
+ while (!g_queue_is_empty (mq)) {
+ devinfo_storage_free_minor (g_queue_pop_head (mq));
+ }
+ goto err;
+ }
+
+ /* first enqueue main storage device */
+ if (!rescan) {
+ hal_device_property_set_int (parent, "block.major", major);
+ hal_device_property_set_int (parent, "block.minor", minor(maindev->dev));
+ hal_device_property_set_string (parent, "block.device", maindev->devlink);
+ raw = dsk_to_rdsk (maindev->devlink);
+ hal_device_property_set_string (parent, "block.solaris.raw_device", raw);
+ free (raw);
+ hal_device_property_set_bool (parent, "block.is_volume", FALSE);
+ hal_device_property_set_string (parent, "solaris.devfs_path", maindev_path);
+ devinfo_add_enqueue (parent, maindev_path, &devinfo_storage_handler);
+ }
+
+ /* add virtual dos volumes to enable pcfs probing */
+ if (!is_cdrom) {
+ doslink_len = strlen (maindev->devlink) + sizeof (":NNN") + 1;
+ if ((doslink = (char *)calloc (1, doslink_len)) != NULL) {
+ for (i = 1; i < 16; i++) {
+ snprintf(dospath, sizeof (dospath), "%s:%d", maindev->slice, i);
+ snprintf(doslink, doslink_len, "%s:%d", maindev->devlink, i);
+ m = devinfo_storage_new_minor(maindev_path, dospath, doslink, maindev->dev, i);
+ g_queue_push_tail (mq, m);
+ }
+ free (doslink);
+ }
+ }
+
+ maindev_is_d0 = (strcmp (maindev->slice, "d0") == 0);
+
+ /* enqueue all volumes */
+ while (!g_queue_is_empty (mq)) {
+ m = g_queue_pop_head (mq);
+
+ /* if main device is d0, we'll throw away s2/p0 */
+ if (maindev_is_d0 && (strcmp (m->slice, whole_disk) == 0)) {
+ devinfo_storage_free_minor (m);
+ continue;
+ }
+ /* don't do p0 on cdrom */
+ if (is_cdrom && (strcmp (m->slice, "p0") == 0)) {
+ devinfo_storage_free_minor (m);
+ continue;
+ }
+ if (rescan) {
+ /* in rescan mode, don't reprobe existing volumes */
+ /* XXX detect volume removal? */
+ volume = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "solaris.devfs_path", m->devpath);
+ if ((volume == NULL) || !hal_device_has_capability(volume, "volume")) {
+ devinfo_volume_add (parent, node, m);
+ } else {
+ HAL_INFO(("rescan volume exists %s", m->devpath));
+ }
+ } else {
+ devinfo_volume_add (parent, node, m);
+ }
+ devinfo_storage_free_minor (m);
+ }
+
+ if (maindev_path != NULL) {
+ di_devfs_path_free (maindev_path);
+ }
+
+ return;
+
+err:
+ if (maindev_path != NULL) {
+ di_devfs_path_free (maindev_path);
+ }
+ if (!rescan) {
+ devinfo_add_enqueue (parent, devfs_path, &devinfo_storage_handler);
+ }
+}
+
+HalDevice *
+devinfo_volume_add(HalDevice *parent, di_node_t node, devinfo_storage_minor_t *m)
+{
+ HalDevice *d;
+ char *raw;
+ char udi[HAL_PATH_MAX];
+ char *devfs_path = m->devpath;
+ char *devlink = m->devlink;
+ dev_t dev = m->dev;
+ int dosnum = m->dosnum;
+ char *slice = m->slice;
+
+ HAL_INFO (("volume_add: devfs_path=%s devlink=%s", devfs_path, devlink));
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.category", "volume");
+
+ hald_compute_udi (udi, sizeof (udi),
+ "%s/%s", hal_device_get_udi (parent), slice);
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.product", slice);
+
+ hal_device_add_capability (d, "volume");
+ hal_device_add_capability (d, "block");
+ hal_device_property_set_int (d, "block.major", major (dev));
+ hal_device_property_set_int (d, "block.minor", minor (dev));
+ hal_device_property_set_string (d, "block.device", devlink);
+ raw = dsk_to_rdsk (devlink);
+ hal_device_property_set_string (d, "block.solaris.raw_device", raw);
+ free (raw);
+ hal_device_property_set_string (d, "block.solaris.slice", slice);
+ hal_device_property_set_bool (d, "block.is_volume", TRUE); /* XXX */
+
+ hal_device_property_set_string (d, "block.storage_device", hal_device_get_udi (parent));
+
+ /* set volume defaults */
+ hal_device_property_set_string (d, "volume.fstype", "");
+ hal_device_property_set_string (d, "volume.fsusage", "");
+ hal_device_property_set_string (d, "volume.fsversion", "");
+ hal_device_property_set_string (d, "volume.uuid", "");
+ hal_device_property_set_string (d, "volume.label", "");
+ hal_device_property_set_string (d, "volume.mount_point", "");
+ hal_device_property_set_bool (d, "volume.is_mounted", FALSE);
+ if (strcmp (hal_device_property_get_string (parent, "storage.drive_type"), "cdrom") == 0) {
+ hal_device_property_set_bool (d, "volume.is_disc", TRUE);
+ hal_device_add_capability (d, "volume.disc");
+ } else {
+ hal_device_property_set_bool (d, "volume.is_disc", FALSE);
+ }
+
+ if (dosnum > 0) {
+ hal_device_property_set_bool (d, "volume.is_partition", TRUE);
+ hal_device_property_set_int (d, "volume.partition.number", dosnum);
+ } else {
+ hal_device_property_set_bool (d, "volume.is_partition", FALSE);
+ }
+
+ /* prober may override these */
+ hal_device_property_set_int (d, "volume.block_size", 512);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_volume_handler);
+
+ return (d);
+}
+
+static void
+devinfo_volume_preprobing_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+ char *whole_disk;
+ char *block_device;
+ const char *storage_udi;
+ HalDevice *storage_d;
+ const char *slice;
+ int dos_num;
+
+ if (hal_device_property_get_bool (d, "info.ignore")) {
+ HAL_INFO (("Preprobing merged info.ignore==TRUE %s", hal_device_get_udi (d)));
+ goto skip;
+ }
+
+ /*
+ * Optimizations: only probe if there's a chance to find something
+ */
+ block_device = (char *)hal_device_property_get_string (d, "block.device");
+ storage_udi = hal_device_property_get_string (d, "block.storage_device");
+ slice = hal_device_property_get_string(d, "block.solaris.slice");
+ if ((block_device == NULL) || (storage_udi == NULL) ||
+ (slice == NULL) || (strlen (slice) < 2)) {
+ HAL_INFO (("Malformed volume properties %s", hal_device_get_udi (d)));
+ goto skip;
+ }
+ storage_d = hal_device_store_match_key_value_string (hald_get_gdl (), "info.udi", storage_udi);
+ if (storage_d == NULL) {
+ HAL_INFO (("Storage device not found %s", hal_device_get_udi (d)));
+ goto skip;
+ }
+
+ whole_disk = hal_device_has_capability (storage_d,
+ "storage.cdrom") ? "s2" : WHOLE_DISK;
+
+ if (is_dos_path(block_device, &dos_num)) {
+ /* don't probe more dos volumes than probe-storage found */
+ if ((hal_device_property_get_bool (storage_d, "storage.no_partitions_hint") ||
+ (dos_num > hal_device_property_get_int (storage_d, "storage.solaris.num_dos_partitions")))) {
+ HAL_INFO (("%d > %d %s", dos_num, hal_device_property_get_int (storage_d,
+ "storage.solaris.num_dos_partitions"), hal_device_get_udi (storage_d)));
+ goto skip;
+ }
+ } else {
+ /* if no VTOC slices found, don't probe slices except s2 */
+ if ((slice[0] == 's') && (isdigit(slice[1])) && ((strcmp (slice, whole_disk)) != 0) &&
+ !hal_device_property_get_bool (storage_d, "storage.solaris.vtoc_slices")) {
+ HAL_INFO (("Not probing slice %s", hal_device_get_udi (d)));
+ goto skip;
+ }
+ }
+
+ HAL_INFO(("Probing udi=%s", hal_device_get_udi (d)));
+ hald_runner_run (d,
+ "hald-probe-volume", NULL,
+ DEVINFO_PROBE_VOLUME_TIMEOUT,
+ devinfo_callouts_probing_done,
+ (gpointer) end_token, userdata2);
+
+ return;
+
+skip:
+ hal_device_store_remove (hald_get_tdl (), d);
+ g_object_unref (d);
+ hotplug_event_end (end_token);
+}
+
+static void
+devinfo_volume_hotplug_begin_add (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token)
+{
+ HAL_INFO(("Preprobing volume udi=%s", hal_device_get_udi (d)));
+
+ if (hal_device_property_get_bool (parent, "info.ignore")) {
+ HAL_INFO (("Ignoring volume: parent's info.ignore is TRUE"));
+ goto skip;
+ }
+
+ /* add to TDL so preprobing callouts and prober can access it */
+ hal_device_store_add (hald_get_tdl (), d);
+
+ /* Process preprobe fdi files */
+ di_search_and_merge (d, DEVICE_INFO_TYPE_PREPROBE);
+
+ /* Run preprobe callouts */
+ hal_util_callout_device_preprobe (d, devinfo_volume_preprobing_done, end_token, handler);
+
+ return;
+
+skip:
+ g_object_unref (d);
+ hotplug_event_end (end_token);
+}
+
+void
+devinfo_storage_hotplug_begin_add (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token)
+{
+ const char *drive_type;
+ const char *p_udi;
+ HalDevice *p_d;
+ HalDevice *phys_d = NULL;
+ const char *phys_bus;
+ const char *bus;
+ static const char *busses[] = { "usb", "ide", "scsi", "pseudo" };
+ int i;
+
+ HAL_INFO (("Preprobing udi=%s", hal_device_get_udi (d)));
+
+ if (parent == NULL) {
+ HAL_INFO (("no parent %s", hal_device_get_udi (d)));
+ goto error;
+ }
+
+ /*
+ * figure out physical device and bus, except for floppy
+ */
+ drive_type = hal_device_property_get_string (d, "storage.drive_type");
+ if ((drive_type != NULL) && (strcmp (drive_type, "floppy") == 0)) {
+ goto skip_bus;
+ }
+
+ p_d = parent;
+ for (;;) {
+ bus = hal_device_property_get_string (p_d, "info.subsystem");
+ if (bus != NULL) {
+ for (i = 0; i < NELEM(busses); i++) {
+ if (strcmp(bus, busses[i]) == 0) {
+ phys_d = p_d;
+ phys_bus = busses[i];
+ break;
+ }
+ }
+ }
+ /* up the tree */
+ p_udi = hal_device_property_get_string (p_d, "info.parent");
+ if (p_udi == NULL) {
+ break;
+ }
+ p_d = hal_device_store_find (hald_get_gdl (), p_udi);
+ }
+ if (phys_d == NULL) {
+ HAL_INFO (("no physical device %s", hal_device_get_udi (d)));
+ goto error;
+ }
+ hal_device_property_set_string (d, "storage.originating_device", hal_device_get_udi (phys_d));
+ hal_device_property_set_string (d, "storage.bus", phys_bus);
+
+skip_bus:
+
+ /* add to TDL so preprobing callouts and prober can access it */
+ hal_device_store_add (hald_get_tdl (), d);
+
+ /* Process preprobe fdi files */
+ di_search_and_merge (d, DEVICE_INFO_TYPE_PREPROBE);
+
+ /* Run preprobe callouts */
+ hal_util_callout_device_preprobe (d, devinfo_callouts_preprobing_done, end_token, handler);
+
+ return;
+
+error:
+ g_object_unref (d);
+ hotplug_event_end (end_token);
+}
+
+static void
+devinfo_storage_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+
+ HAL_INFO (("devinfo_storage_probing_done %s", hal_device_get_udi (d)));
+
+ /* Discard device if probing reports failure */
+ if (exit_type != HALD_RUN_SUCCESS || return_code != 0) {
+ HAL_INFO (("devinfo_storage_probing_done returning exit_type=%d return_code=%d", exit_type, return_code));
+ hal_device_store_remove (hald_get_tdl (), d);
+ g_object_unref (d);
+ hotplug_event_end (end_token);
+ return;
+ }
+
+ devinfo_storage_set_nicknames (d);
+
+ /* Merge properties from .fdi files */
+ di_search_and_merge (d, DEVICE_INFO_TYPE_INFORMATION);
+ di_search_and_merge (d, DEVICE_INFO_TYPE_POLICY);
+
+ hal_util_callout_device_add (d, devinfo_callouts_add_done, end_token, NULL);
+}
+
+const gchar *
+devinfo_storage_get_prober (HalDevice *d, int *timeout)
+{
+ *timeout = DEVINFO_PROBE_STORAGE_TIMEOUT;
+ return "hald-probe-storage";
+}
+
+const gchar *
+devinfo_volume_get_prober (HalDevice *d, int *timeout)
+{
+ *timeout = DEVINFO_PROBE_VOLUME_TIMEOUT;
+ return "hald-probe-volume";
+}
+
+/*
+ * After reprobing storage, reprobe its volumes.
+ */
+static void
+devinfo_storage_rescan_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+ const char *devfs_path_orig = NULL;
+ char *devfs_path = NULL;
+ char *p;
+ di_node_t node;
+
+ HAL_INFO (("devinfo_storage_rescan_probing_done %s", hal_device_get_udi (d)));
+
+ devfs_path_orig = hal_device_property_get_string (d, "solaris.devfs_path");
+ if (devfs_path_orig == NULL) {
+ HAL_INFO (("device has no solaris.devfs_path"));
+ hotplug_event_process_queue ();
+ return;
+ }
+
+ /* strip trailing minor part if any */
+ if (strrchr(devfs_path_orig, ':') != NULL) {
+ if ((devfs_path = strdup (devfs_path_orig)) != NULL) {
+ p = strrchr(devfs_path, ':');
+ *p = '\0';
+ }
+ } else {
+ devfs_path = (char *)devfs_path_orig;
+ }
+
+ if ((node = di_init (devfs_path, DINFOCPYALL)) == DI_NODE_NIL) {
+ HAL_INFO (("di_init %s failed %d %s", devfs_path, errno, hal_device_get_udi (d)));
+ hotplug_event_process_queue ();
+ return;
+ } else {
+ devinfo_storage_minors (d, node, (char *)devfs_path, TRUE);
+ di_fini (node);
+ }
+
+ if (devfs_path != devfs_path_orig) {
+ free (devfs_path);
+ }
+
+ hotplug_event_process_queue ();
+}
+
+/*
+ * For removable media devices, check for "storage.removable.media_available".
+ * For non-removable media devices, assume media is always there.
+ *
+ * If media is gone, enqueue remove events for all children volumes.
+ * If media is there, first reprobe storage, then probe for new volumes (but leave existing volumes alone).
+ */
+gboolean
+devinfo_storage_device_rescan (HalDevice *d)
+{
+ GSList *i;
+ GSList *volumes;
+ HalDevice *v;
+ gchar *v_devfs_path;
+ const char *drive_type;
+ gboolean is_floppy;
+ gboolean media_available;
+
+ HAL_INFO (("devinfo_storage_device_rescan udi=%s", hal_device_get_udi (d)));
+
+ if (hal_device_property_get_bool (d, "block.is_volume")) {
+ HAL_INFO (("nothing to do for volume"));
+ return (FALSE);
+ }
+
+ drive_type = hal_device_property_get_string (d, "storage.drive_type");
+ is_floppy = (drive_type != NULL) && (strcmp (drive_type, "floppy") == 0);
+
+ media_available = !hal_device_property_get_bool (d, "storage.removable") ||
+ hal_device_property_get_bool (d, "storage.removable.media_available");
+
+ if (!media_available && !is_floppy) {
+ HAL_INFO (("media gone %s", hal_device_get_udi (d)));
+
+ volumes = hal_device_store_match_multiple_key_value_string (hald_get_gdl(),
+ "block.storage_device", hal_device_get_udi (d));
+ for (i = volumes; i != NULL; i = g_slist_next (i)) {
+ v = HAL_DEVICE (i->data);
+ v_devfs_path = (gchar *)hal_device_property_get_string (v, "solaris.devfs_path");
+ HAL_INFO (("child volume %s", hal_device_get_udi (v)));
+ if ((v_devfs_path != NULL) && hal_device_has_capability (v, "volume")) {
+ HAL_INFO (("removing volume %s", hal_device_get_udi (v)));
+ devinfo_remove_enqueue (v_devfs_path, NULL);
+ } else {
+ HAL_INFO (("not a volume %s", hal_device_get_udi (v)));
+ }
+ }
+ g_slist_free (volumes);
+
+ hotplug_event_process_queue ();
+ } else if (is_floppy) {
+ HAL_INFO (("rescanning floppy %s", hal_device_get_udi (d)));
+
+ hald_runner_run (d,
+ "hald-probe-storage --only-check-for-media", NULL,
+ DEVINFO_PROBE_STORAGE_TIMEOUT,
+ devinfo_floppy_rescan_probing_done,
+ NULL, NULL);
+ } else {
+ HAL_INFO (("media available %s", hal_device_get_udi (d)));
+
+ hald_runner_run (d,
+ "hald-probe-storage --only-check-for-media", NULL,
+ DEVINFO_PROBE_STORAGE_TIMEOUT,
+ devinfo_storage_rescan_probing_done,
+ NULL, NULL);
+ }
+
+ return TRUE;
+}
+
+static char *
+devinfo_volume_get_slice_name (char *devlink)
+{
+ char *part, *slice, *disk;
+ char *s = NULL;
+ char *p;
+
+ if ((p = strstr(devlink, "/lofi/")) != 0) {
+ return (p + sizeof ("/lofi/") - 1);
+ }
+
+ part = strrchr(devlink, 'p');
+ slice = strrchr(devlink, 's');
+ disk = strrchr(devlink, 'd');
+
+ if ((part != NULL) && (part > slice) && (part > disk)) {
+ s = part;
+ } else if ((slice != NULL) && (slice > disk)) {
+ s = slice;
+ } else {
+ s = disk;
+ }
+ if ((s != NULL) && isdigit(s[1])) {
+ return (s);
+ } else {
+ return ("");
+ }
+}
+
+static gboolean
+is_dos_path(char *path, int *partnum)
+{
+ char *p;
+
+ if ((p = strrchr (path, ':')) == NULL) {
+ return (FALSE);
+ }
+ return ((*partnum = atoi(p + 1)) != 0);
+}
+
+static gboolean
+dos_to_dev(char *path, char **devpath, int *partnum)
+{
+ char *p;
+
+ if ((p = strrchr (path, ':')) == NULL) {
+ return (FALSE);
+ }
+ if ((*partnum = atoi(p + 1)) == 0) {
+ return (FALSE);
+ }
+ p[0] = '\0';
+ *devpath = strdup(path);
+ p[0] = ':';
+ return (*devpath != NULL);
+}
+
+static void
+devinfo_storage_cleanup_mountpoint_cb (HalDevice *d, guint32 exit_type,
+ gint return_code, gchar **error,
+ gpointer data1, gpointer data2)
+{
+ char *mount_point = (char *) data1;
+
+ HAL_INFO (("Cleaned up mount point '%s'", mount_point));
+ g_free (mount_point);
+}
+
+
+void
+devinfo_storage_mnttab_event (HalDevice *hal_volume)
+{
+ FILE *fp = NULL;
+ struct extmnttab m;
+ HalDevice *d;
+ unsigned int major;
+ unsigned int minor;
+ GSList *volumes = NULL;
+ GSList *v;
+ char *mount_point;
+ dbus_bool_t is_partition;
+ const char *fstype;
+ int partition_number;
+
+ if (hal_volume != NULL) {
+ volumes = g_slist_append (NULL, hal_volume);
+ } else {
+ volumes = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.category", "volume");
+ }
+ if (volumes == NULL) {
+ return;
+ }
+
+ if ((fp = fopen(MNTTAB, "r")) == NULL) {
+ HAL_ERROR (("Open failed %s errno %d", MNTTAB, errno));
+ return;
+ }
+
+ while (getextmntent(fp, &m, 1) == 0) {
+ for (v = volumes; v != NULL; v = g_slist_next (v)) {
+ d = HAL_DEVICE (v->data);
+ major = hal_device_property_get_int (d, "block.major");
+ minor = hal_device_property_get_int (d, "block.minor");
+
+ /*
+ * special handling for pcfs, which encodes logical
+ * drive number into the 6 upper bits of the minor
+ */
+ is_partition = hal_device_property_get_bool (d, "volume.is_partition");
+ partition_number = hal_device_property_get_int (d, "volume.partition.number");
+ fstype = hal_device_property_get_string (d, "volume.fstype");
+
+ if (is_partition && (partition_number > 0) && (strcmp (fstype, "pcfs") == 0)) {
+ minor |= partition_number << 12;
+ }
+
+ if (m.mnt_major != major || m.mnt_minor != minor) {
+ continue;
+ }
+
+ /* this volume matches the mnttab entry */
+ device_property_atomic_update_begin ();
+ hal_device_property_set_bool (d, "volume.is_mounted", TRUE);
+ hal_device_property_set_bool (d, "volume.is_mounted_read_only",
+ hasmntopt ((struct mnttab *)&m, "ro") ? TRUE : FALSE);
+ hal_device_property_set_string (d, "volume.mount_point", m.mnt_mountp);
+ device_property_atomic_update_end ();
+
+ HAL_INFO (("set %s to be mounted at %s",
+ hal_device_get_udi (d), m.mnt_mountp));
+ volumes = g_slist_delete_link (volumes, v);
+ }
+ }
+
+ /* all remaining volumes are not mounted */
+ for (v = volumes; v != NULL; v = g_slist_next (v)) {
+ d = HAL_DEVICE (v->data);
+ mount_point = g_strdup (hal_device_property_get_string (d, "volume.mount_point"));
+ if (mount_point == NULL || strlen (mount_point) == 0) {
+ g_free (mount_point);
+ continue;
+ }
+
+ device_property_atomic_update_begin ();
+ hal_device_property_set_bool (d, "volume.is_mounted", FALSE);
+ hal_device_property_set_bool (d, "volume.is_mounted_read_only", FALSE);
+ hal_device_property_set_string (d, "volume.mount_point", "");
+ device_property_atomic_update_end ();
+
+ HAL_INFO (("set %s to unmounted", hal_device_get_udi (d)));
+
+ /* cleanup if was mounted by us */
+ if (hal_util_is_mounted_by_hald (mount_point)) {
+ char *cleanup_stdin;
+ char *extra_env[2];
+
+ HAL_INFO (("Cleaning up '%s'", mount_point));
+
+ extra_env[0] = g_strdup_printf ("HALD_CLEANUP=%s", mount_point);
+ extra_env[1] = NULL;
+ cleanup_stdin = "\n";
+
+ hald_runner_run_method (d,
+ "hal-storage-cleanup-mountpoint",
+ extra_env,
+ cleanup_stdin, TRUE,
+ 0,
+ devinfo_storage_cleanup_mountpoint_cb,
+ g_strdup (mount_point), NULL);
+
+ g_free (extra_env[0]);
+ }
+
+ g_free (mount_point);
+ }
+ g_slist_free (volumes);
+
+ (void) fclose (fp);
+}
+
+static void
+devinfo_volume_force_unmount_cb (HalDevice *d, guint32 exit_type,
+ gint return_code, gchar **error,
+ gpointer data1, gpointer data2)
+{
+ void *end_token = (void *) data1;
+
+ HAL_INFO (("devinfo_volume_force_unmount_cb for udi='%s', exit_type=%d, return_code=%d", hal_device_get_udi (d), exit_type, return_code));
+
+ if (exit_type == HALD_RUN_SUCCESS && error != NULL &&
+ error[0] != NULL && error[1] != NULL) {
+ char *exp_name = NULL;
+ char *exp_detail = NULL;
+
+ exp_name = error[0];
+ if (error[0] != NULL) {
+ exp_detail = error[1];
+ }
+ HAL_INFO (("failed with '%s' '%s'", exp_name, exp_detail));
+ }
+
+ hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
+}
+
+static void
+devinfo_volume_force_unmount (HalDevice *d, void *end_token)
+{
+ const char *device_file;
+ const char *mount_point;
+ char *unmount_stdin;
+ char *extra_env[2];
+ extra_env[0] = "HAL_METHOD_INVOKED_BY_UID=0";
+ extra_env[1] = NULL;
+
+ device_file = hal_device_property_get_string (d, "block.device");
+ mount_point = hal_device_property_get_string (d, "volume.mount_point");
+
+ if (mount_point == NULL || strlen (mount_point) == 0 || !hal_util_is_mounted_by_hald (mount_point)) {
+ hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
+ return;
+ }
+
+ HAL_INFO (("devinfo_volume_force_unmount for udi='%s'", hal_device_get_udi (d)));
+
+ unmount_stdin = "\n";
+
+ hald_runner_run_method (d,
+ "hal-storage-unmount",
+ extra_env,
+ unmount_stdin, TRUE,
+ 0,
+ devinfo_volume_force_unmount_cb,
+ end_token, NULL);
+}
+
+void
+devinfo_volume_hotplug_begin_remove (HalDevice *d, char *devfs_path, void *end_token)
+{
+ if (hal_device_property_get_bool (d, "volume.is_mounted")) {
+ devinfo_volume_force_unmount (d, end_token);
+ } else {
+ hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
+ }
+}
+
+
+enum {
+ LEGACY_CDROM,
+ LEGACY_FLOPPY,
+ LEGACY_RMDISK
+};
+
+static const char *legacy_media_str[] = {
+ "cdrom",
+ "floppy",
+ "rmdisk"
+};
+
+struct enum_nick {
+ const char *type;
+ GSList *nums;
+};
+
+static int
+devinfo_storage_get_legacy_media(HalDevice *d)
+{
+ const char *drive_type;
+
+ if (hal_device_has_capability (d, "storage.cdrom")) {
+ return (LEGACY_CDROM);
+ } else if (((drive_type = hal_device_property_get_string (d,
+ "storage.drive_type")) != NULL) && (strcmp (drive_type, "floppy") == 0)) {
+ return (LEGACY_FLOPPY);
+ } else if (hal_device_property_get_bool (d, "storage.removable") ||
+ hal_device_property_get_bool (d, "storage.hotpluggable")) {
+ return (LEGACY_RMDISK);
+ } else {
+ return (-1);
+ }
+}
+
+static gboolean
+devinfo_storage_foreach_nick (HalDeviceStore *store, HalDevice *d, gpointer user_data)
+{
+ struct enum_nick *en = (struct enum_nick *) user_data;
+ const char *media_type;
+ int media_num;
+
+ media_type = hal_device_property_get_string (d, "storage.solaris.legacy.media_type");
+ media_num = hal_device_property_get_int (d, "storage.solaris.legacy.media_num");
+ if ((media_type != NULL) && (strcmp (media_type, en->type) == 0) &&
+ (media_num >= 0)) {
+ en->nums = g_slist_prepend (en->nums, GINT_TO_POINTER(media_num));
+ }
+ return TRUE;
+}
+
+static void
+devinfo_storage_append_nickname (HalDevice *d, const char *media_type, int media_num)
+{
+ char buf[64];
+
+ if (media_num == 0) {
+ hal_device_property_strlist_append (d, "storage.solaris.nicknames", media_type, FALSE);
+ }
+ snprintf(buf, sizeof (buf), "%s%d", media_type, media_num);
+ hal_device_property_strlist_append (d, "storage.solaris.nicknames", buf, FALSE);
+}
+
+static void
+devinfo_storage_set_nicknames (HalDevice *d)
+{
+ int media;
+ const char *media_type;
+ int media_num;
+ GSList *i;
+ struct enum_nick en;
+ char buf[64];
+
+ if ((media = devinfo_storage_get_legacy_media (d)) < 0) {
+ return;
+ }
+ media_type = legacy_media_str[media];
+
+ /* enumerate all storage devices of this media type */
+ en.type = media_type;
+ en.nums = NULL;
+ hal_device_store_foreach (hald_get_gdl (), devinfo_storage_foreach_nick, &en);
+
+ /* find a free number */
+ for (media_num = 0; ; media_num++) {
+ for (i = en.nums; i != NULL; i = g_slist_next (i)) {
+ if (GPOINTER_TO_INT (i->data) == media_num) {
+ break;
+ }
+ }
+ if (i == NULL) {
+ break;
+ }
+ }
+ g_slist_free (en.nums);
+
+ hal_device_property_set_string (d, "storage.solaris.legacy.media_type", media_type);
+ hal_device_property_set_int (d, "storage.solaris.legacy.media_num", media_num);
+
+ /* primary nickname, and also vold-style symdev */
+ snprintf(buf, sizeof (buf), "%s%d", media_type, media_num);
+ hal_device_property_set_string (d, "storage.solaris.legacy.symdev", buf);
+ devinfo_storage_append_nickname(d, media_type, media_num);
+
+ /* additional nicknames */
+ if (media == LEGACY_CDROM) {
+ devinfo_storage_append_nickname(d, "cd", media_num);
+ devinfo_storage_append_nickname(d, "sr", media_num);
+ } else if (media == LEGACY_FLOPPY) {
+ devinfo_storage_append_nickname(d, "fd", media_num);
+ devinfo_storage_append_nickname(d, "diskette", media_num);
+ devinfo_storage_append_nickname(d, "rdiskette", media_num);
+ }
+}
diff --git a/hal/files/hald-netbsd/devinfo_storage.h b/hal/files/hald-netbsd/devinfo_storage.h
new file mode 100644
index 0000000000..9238fe539c
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_storage.h
@@ -0,0 +1,30 @@
+/***************************************************************************
+ *
+ * devinfo_storage.h : definitions for storage devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifndef DEVINFO_STORAGE_H
+#define DEVINFO_STORAGE_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_ide_handler;
+extern DevinfoDevHandler devinfo_scsi_handler;
+extern DevinfoDevHandler devinfo_pcata_handler;
+extern DevinfoDevHandler devinfo_floppy_handler;
+extern DevinfoDevHandler devinfo_lofi_handler;
+
+gboolean devinfo_storage_device_rescan (HalDevice *d);
+HalDevice *devinfo_lofi_add_major(HalDevice *parent, const char *devinfo, char *devfs_path,
+ char *device_type, gboolean rescan, HalDevice *lofi_d);
+void devinfo_lofi_remove_minor(char *parent_devfs_path, char *name);
+void devinfo_storage_mnttab_event (HalDevice *hal_volume);
+void devinfo_volume_hotplug_begin_remove (HalDevice *d, char *devfs_path, void *end_token);
+
+#endif /* DEVINFO_STORAGE_H */
diff --git a/hal/files/hald-netbsd/devinfo_usb.c b/hal/files/hald-netbsd/devinfo_usb.c
new file mode 100644
index 0000000000..a93327296c
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_usb.c
@@ -0,0 +1,229 @@
+/***************************************************************************
+ *
+ * devinfo_usb.h : USB devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "@(#)devinfo_usb.c 1.2 06/10/13 SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <libdevinfo.h>
+#include <sys/types.h>
+#include <sys/mkdev.h>
+#include <sys/stat.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../ids.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "devinfo_usb.h"
+
+HalDevice *devinfo_usb_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+static HalDevice *devinfo_usb_if_add(HalDevice *d, di_node_t node, gchar *devfs_path, int ifnum);
+static HalDevice *devinfo_usb_scsa2usb_add(HalDevice *d, di_node_t node, gchar *devfs_path);
+
+DevinfoDevHandler devinfo_usb_handler = {
+ devinfo_usb_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+HalDevice *
+devinfo_usb_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ HalDevice *d, *nd = NULL;
+ char *s;
+ int *i, *vid;
+ char *driver_name, *binding_name;
+ char if_devfs_path[HAL_PATH_MAX];
+
+ /*
+ * we distinguish USB devices by presence of "usb-vendor-id"
+ * property. should USB devices have "device_type"?
+ */
+ if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "usb-vendor-id", &vid) <= 0) {
+ return (NULL);
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.subsystem", "usb_device");
+ PROP_STR(d, node, s, "usb-product-name", "info.product");
+ PROP_STR(d, node, s, "usb-product-name", "usb_device.product");
+ PROP_STR(d, node, s, "usb-vendor-name", "usb_device.vendor");
+ PROP_INT(d, node, i, "usb-vendor-id", "usb_device.vendor_id");
+ PROP_INT(d, node, i, "usb-product-id", "usb_device.product_id");
+ PROP_INT(d, node, i, "usb-revision-id", "usb_device.device_revision_bcd");
+ PROP_INT(d, node, i, "usb-release-id", "usb_device.version_bcd");
+ PROP_STR(d, node, s, "usb-serialno", "usb_device.serial");
+
+ /* class, subclass */
+ /* hal_device_property_set_int (d, "usb_device.device_class", 8); */
+
+ /* binding name tells us if driver is bound to interface or device */
+ if (((binding_name = di_binding_name(node)) != NULL) &&
+ (strncmp(binding_name, "usbif,", sizeof ("usbif,") - 1) == 0)) {
+ snprintf(if_devfs_path, sizeof (if_devfs_path), "%s:if%d", devfs_path, 0);
+ if ((nd = devinfo_usb_if_add(d, node, if_devfs_path, 0)) != NULL) {
+ d = nd;
+ nd = NULL;
+ devfs_path = if_devfs_path;
+ }
+ }
+
+ /* driver specific */
+ driver_name = di_driver_name (node);
+ if ((driver_name != NULL) && (strcmp (driver_name, "scsa2usb") == 0)) {
+ nd = devinfo_usb_scsa2usb_add (d, node, devfs_path);
+ } else {
+ devinfo_add_enqueue (d, devfs_path, &devinfo_usb_handler);
+ }
+
+out:
+ if (nd != NULL) {
+ return (nd);
+ } else {
+ return (d);
+ }
+}
+
+static HalDevice *
+devinfo_usb_if_add(HalDevice *parent, di_node_t node, gchar *devfs_path, int ifnum)
+{
+ HalDevice *d = NULL;
+ char udi[HAL_PATH_MAX];
+
+ devinfo_add_enqueue (parent, devfs_path, &devinfo_usb_handler);
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.subsystem", "usb");
+
+ hald_compute_udi (udi, sizeof (udi),
+ "%s_if%d", hal_device_get_udi (parent), ifnum);
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.product", "USB Device Interface");
+
+ /* copy parent's usb_device.* properties */
+ hal_device_merge_with_rewrite (d, parent, "usb.", "usb_device.");
+
+ return (d);
+}
+
+static int
+walk_devlinks(di_devlink_t devlink, void *arg)
+{
+ char **path = (char **)arg;
+
+ *path = strdup(di_devlink_path(devlink));
+
+ return (DI_WALK_TERMINATE);
+}
+
+static char *
+get_devlink(di_devlink_handle_t devlink_hdl, char *path)
+{
+ char *devlink = NULL;
+
+ (void) di_devlink_walk(devlink_hdl, NULL, path,
+ DI_PRIMARY_LINK, &devlink, walk_devlinks);
+
+ return (devlink);
+}
+
+static HalDevice *
+devinfo_usb_scsa2usb_add(HalDevice *usbd, di_node_t node, gchar *devfs_path)
+{
+ HalDevice *d = NULL;
+ di_devlink_handle_t devlink_hdl;
+ int major;
+ di_minor_t minor;
+ dev_t devt;
+ char *minor_path = NULL;
+ char *devlink = NULL;
+ char udi[HAL_PATH_MAX];
+
+ devinfo_add_enqueue (usbd, devfs_path, &devinfo_usb_handler);
+
+ if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
+ printf("di_devlink_init() failed\n");
+ return (NULL);
+ }
+
+ major = di_driver_major(node);
+ minor = DI_MINOR_NIL;
+ while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
+ devt = di_minor_devt(minor);
+ if (major != major(devt)) {
+ continue;
+ }
+ if ((minor_path = di_devfs_minor_path(minor)) == NULL) {
+ continue;
+ }
+ if (di_minor_type(minor) != DDM_MINOR) {
+ continue;
+ }
+ if (strcmp (di_minor_nodetype(minor),
+ "ddi_ctl:devctl:scsi") == 0) {
+ devlink = get_devlink(devlink_hdl, minor_path);
+ if (devlink == NULL) {
+ devlink = strdup("");
+ }
+ break;
+ }
+ di_devfs_path_free (minor_path);
+ minor_path = NULL;
+ }
+
+ di_devlink_fini (&devlink_hdl);
+
+ if (devlink == NULL) {
+ goto out;
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, usbd, node, minor_path);
+ hal_device_property_set_string (d, "scsi_host.solaris.device", devlink);
+ hal_device_property_set_string (d, "info.category", "scsi_host");
+ hal_device_property_set_int (d, "scsi_host.host", 0);
+
+ hald_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+ "%s/scsi_host%d", hal_device_get_udi (usbd),
+ hal_device_property_get_int (d, "scsi_host.host"));
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.product", "SCSI Host Adapter");
+
+ devinfo_add_enqueue (d, minor_path, &devinfo_usb_handler);
+
+out:
+ if (devlink) {
+ free(devlink);
+ }
+ if (minor_path) {
+ di_devfs_path_free (minor_path);
+ }
+
+ return (d);
+}
+
diff --git a/hal/files/hald-netbsd/devinfo_usb.h b/hal/files/hald-netbsd/devinfo_usb.h
new file mode 100644
index 0000000000..01864c2011
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_usb.h
@@ -0,0 +1,23 @@
+/***************************************************************************
+ *
+ * devinfo_usb.h : definitions for USB devices
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifndef DEVINFO_USB_H
+#define DEVINFO_USB_H
+
+#include "devinfo.h"
+
+#define bcd(a) ((((a) & 0xf000) >> 12) * 1000 + (((a) & 0xf00) >> 8) * 100 + (((a) & 0xf0) >> 4) * 10 + ((a) & 0xf))
+
+extern DevinfoDevHandler devinfo_usb_handler;
+
+HalDevice *devinfo_usb_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type);
+
+#endif /* DEVINFO_USB_H */
diff --git a/hal/files/hald-netbsd/devinfo_video.c b/hal/files/hald-netbsd/devinfo_video.c
new file mode 100644
index 0000000000..8325065895
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_video.c
@@ -0,0 +1,125 @@
+/* $NetBSD: devinfo_video.c,v 1.1 2008/11/27 22:19:10 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2008 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/videoio.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <paths.h>
+#include <unistd.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../ids.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "devinfo_video.h"
+#include "drvctl.h"
+
+HalDevice *devinfo_video_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type);
+
+DevinfoDevHandler devinfo_video_handler = {
+ devinfo_video_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+HalDevice *
+devinfo_video_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type)
+{
+ HalDevice *d = NULL;
+ prop_dictionary_t dict;
+ const char *driver, *parent_udi;
+ char *videodev;
+ int16_t unit;
+ struct v4l2_capability caps;
+ int fd;
+
+ if (drvctl_find_device (devnode, &dict) == FALSE || dict == NULL)
+ return NULL;
+
+ if (prop_dictionary_get_int16 (dict, "device-unit", &unit) == false ||
+ prop_dictionary_get_cstring_nocopy (dict, "device-driver", &driver) == false) {
+ prop_object_release (dict);
+ return NULL;
+ }
+
+ prop_object_release (dict);
+
+ if (strcmp (driver, "video") != 0)
+ return NULL;
+
+ videodev = g_strdup_printf ("/dev/video%d", unit);
+ fd = open (videodev, O_RDONLY);
+ if (fd < 0) {
+ HAL_WARNING (("couldn't open %s: %s", videodev, strerror(errno)));
+ goto done;
+ }
+
+ if (ioctl (fd, VIDIOC_QUERYCAP, &caps) == -1) {
+ HAL_WARNING (("couldn't query %s: %s", videodev, strerror(errno)));
+ close (fd);
+ goto done;
+ }
+
+ close (fd);
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, devnode, devfs_path);
+ hal_device_add_capability (d, "video4linux");
+ if (caps.capabilities & V4L2_CAP_VIDEO_CAPTURE)
+ hal_device_add_capability (d, "video4linux.video_capture");
+ hal_device_property_set_string (d, "info.category", "video4linux");
+ hal_device_property_set_string (d, "info.subsystem", "video4linux");
+
+ hal_device_property_set_string (d, "video4linux.device", videodev);
+ hal_device_property_set_int (d, "video4linux.version", 2);
+ hal_device_property_set_string (d, "info.product", caps.card);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_video_handler);
+
+done:
+ if (videodev)
+ g_free (videodev);
+
+ return d;
+}
diff --git a/hal/files/hald-netbsd/devinfo_video.h b/hal/files/hald-netbsd/devinfo_video.h
new file mode 100644
index 0000000000..d9828ce2b8
--- /dev/null
+++ b/hal/files/hald-netbsd/devinfo_video.h
@@ -0,0 +1,36 @@
+/* $NetBSD: devinfo_video.h,v 1.1 2008/11/27 22:19:10 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2008 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DEVINFO_VIDEO_H
+#define DEVINFO_VIDEO_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_video_handler;
+
+#endif /* DEVINFO_VIDEO_H */
diff --git a/hal/files/hald-netbsd/drvctl.c b/hal/files/hald-netbsd/drvctl.c
new file mode 100644
index 0000000000..5384a1f792
--- /dev/null
+++ b/hal/files/hald-netbsd/drvctl.c
@@ -0,0 +1,303 @@
+/***************************************************************************
+ *
+ * drvctl.c : NetBSD drvctl events
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/drvctlio.h>
+#include <sys/dkio.h>
+#include <sys/stat.h>
+#include <sys/drvctlio.h>
+#include <glib.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "osspec_netbsd.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "devinfo_storage.h"
+#include "drvctl.h"
+
+static gboolean drvctl_iochannel_data(GIOChannel *, GIOCondition, gpointer);
+static void drvctl_dev_add(gchar *);
+static void drvctl_dev_remove(gchar *);
+static void drvctl_dev_branch(gchar *);
+
+static int drvctl_fd;
+static GIOChannel *drvctl_iochannel;
+
+gboolean
+drvctl_init(void)
+{
+ drvctl_fd = open (DRVCTLDEV, O_RDWR);
+ if (drvctl_fd == -1) {
+ HAL_INFO (("open(%s, O_RDWR) failed: %s", DRVCTLDEV, strerror(errno)));
+ return FALSE;
+ }
+
+ drvctl_iochannel = g_io_channel_unix_new (drvctl_fd);
+ if (drvctl_iochannel == NULL) {
+ HAL_INFO (("g_io_channel_unix_new failed"));
+ return FALSE;
+ }
+ g_io_add_watch (drvctl_iochannel, G_IO_IN, drvctl_iochannel_data, NULL);
+
+ return TRUE;
+}
+
+void
+drvctl_fini(void)
+{
+ HAL_INFO (("drvctl_fini"));
+}
+
+static gboolean
+drvctl_iochannel_data (GIOChannel *source,
+ GIOCondition condition,
+ gpointer user_data)
+{
+ prop_dictionary_t ev;
+ const char *event, *device;
+ int res;
+
+ HAL_INFO (("drvctl_iochannel_data"));
+
+ res = prop_dictionary_recv_ioctl (drvctl_fd, DRVGETEVENT, &ev);
+ if (res) {
+ HAL_WARNING (("DRVGETEVENT failed: %s", strerror(errno)));
+ return FALSE;
+ }
+
+ if (!prop_dictionary_get_cstring_nocopy (ev, "event", &event)) {
+ HAL_WARNING (("DRVGETEVENT missing \"event\" parameter"));
+ goto done;
+ }
+ if (!prop_dictionary_get_cstring_nocopy (ev, "device", &device)) {
+ HAL_WARNING (("DRVGETEVENT missing \"device\" parameter"));
+ goto done;
+ }
+
+ HAL_INFO (("DRVGETEVENT event=%s device=%s", event, device));
+
+ if (strcmp (event, "device-attach") == 0) {
+ drvctl_dev_add (device);
+ } else {
+ drvctl_dev_remove (device);
+ }
+
+done:
+ prop_object_release(ev);
+ return TRUE;
+}
+
+static void
+drvctl_dev_add(gchar *name)
+{
+ HalDevice *parent, *d;
+ gchar pdevnode[512];
+
+ if (drvctl_find_parent (name, pdevnode) == FALSE) {
+ HAL_INFO (("dev_add: name=%s orphan", name));
+ parent = NULL;
+ } else {
+ parent = hal_device_store_match_key_value_string (
+ hald_get_gdl(), "netbsd.device", pdevnode);
+ if (parent == NULL)
+ HAL_INFO (("dev_add: name=%s but netbsd.device=%s not found",name, pdevnode));
+ }
+
+ d = devinfo_add_node (parent, name);
+ if (d == NULL)
+ HAL_WARNING (("dev_add: couldn't add %s node (parent=%p)", name, parent));
+
+ hotplug_event_process_queue ();
+}
+
+static void
+drvctl_dev_remove(gchar *name)
+{
+ HAL_INFO (("dev_remove: %s", name));
+
+ devinfo_remove_branch (name, NULL);
+ hotplug_event_process_queue ();
+}
+
+static void
+drvctl_dev_branch(gchar *name)
+{
+ HAL_INFO (("branch_remove: %s", name));
+
+ devinfo_remove_branch (name, NULL);
+ hotplug_event_process_queue ();
+}
+
+int
+drvctl_list(const gchar *name, struct devlistargs *laa)
+{
+ size_t children;
+
+ /* HAL_INFO (("drvctl_list: %s", name)); */
+
+ memset (laa, 0, sizeof (*laa));
+ strlcpy (laa->l_devname, name, sizeof (laa->l_devname));
+ if (ioctl (drvctl_fd, DRVLISTDEV, laa) == -1) {
+ HAL_INFO (("DRVLISTDEV/1 failed: %s", strerror(errno)));
+ return -1;
+ }
+ children = laa->l_children;
+ /* HAL_INFO (("%s: found %d children", name, children)); */
+ if (children == 0)
+ return -1;
+ laa->l_childname = malloc (children * sizeof (laa->l_childname[0]));
+ if (laa->l_childname == NULL) {
+ HAL_INFO (("drvctl_list couldn't allocate %d children: %s\n", children, strerror(errno)));
+ return -1;
+ }
+ if (ioctl (drvctl_fd, DRVLISTDEV, laa) == -1) {
+ HAL_INFO (("DRVLISTDEV/2 failed: %s", strerror(errno)));
+ return -1;
+ }
+ if (children != laa->l_children)
+ HAL_WARNING (("DRVLISTDEV/3 expected %d children, got %d", children, laa->l_childname));
+}
+
+gboolean
+drvctl_find_device(const gchar *devnode, prop_dictionary_t *properties)
+{
+ prop_dictionary_t command_dict;
+ prop_dictionary_t args_dict;
+ prop_dictionary_t results_dict;
+ int err;
+
+ command_dict = prop_dictionary_create ();
+ args_dict = prop_dictionary_create ();
+
+ prop_dictionary_set_cstring_nocopy (command_dict, "drvctl-command", "get-properties");
+ prop_dictionary_set_cstring_nocopy (args_dict, "device-name", devnode);
+ prop_dictionary_set (command_dict, "drvctl-arguments", args_dict);
+ prop_object_release (args_dict);
+
+ err = prop_dictionary_sendrecv_ioctl (command_dict, drvctl_fd,
+ DRVCTLCOMMAND, &results_dict);
+ prop_object_release (command_dict);
+ if (err)
+ return FALSE;
+
+ if (prop_dictionary_get_int8 (results_dict, "drvctl-error", &err) == false || err != 0) {
+ prop_object_release (results_dict);
+ return FALSE;
+ }
+
+ if (properties) {
+ prop_dictionary_t result_data;
+ result_data = prop_dictionary_get (results_dict, "drvctl-result-data");
+ if (result_data)
+ *properties = prop_dictionary_copy (result_data);
+ }
+
+ prop_object_release (results_dict);
+
+ return TRUE;
+}
+
+static gboolean
+drvctl_find_device_with_child(const gchar *curnode, const gchar *devnode,
+ char *parent)
+{
+ struct devlistargs laa;
+ u_int i;
+
+ if (drvctl_list (curnode, &laa) == -1)
+ return FALSE;
+
+ for (i = 0; i < laa.l_children; i++) {
+ if (strcmp (laa.l_childname[i], devnode) == 0) {
+ strlcpy(parent, curnode, 16);
+ free(laa.l_childname);
+ return TRUE;
+ }
+ if (drvctl_find_device_with_child (laa.l_childname[i], devnode, parent) == TRUE) {
+ free(laa.l_childname);
+ return TRUE;
+ }
+ }
+
+ if (laa.l_childname)
+ free(laa.l_childname);
+
+ HAL_INFO (("%s: couldn't find device with child %s", curnode, devnode));
+ return FALSE;
+}
+
+gboolean
+drvctl_find_parent(const gchar *devnode, char *parent)
+{
+ return drvctl_find_device_with_child("mainbus0", devnode, parent);
+}
+
+#if 0
+static void
+drvctl_lofi_add(gchar *devfs_path, gchar *name)
+{
+ di_node_t node;
+ const char *parent_udi;
+ HalDevice *d, *parent;
+
+ HAL_INFO (("lofi_add: %s %s", name, devfs_path));
+
+ if ((d = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "solaris.devfs_path", devfs_path)) == NULL) {
+ HAL_INFO (("device not found in GDL %s", devfs_path));
+ return;
+ }
+ parent_udi = hal_device_property_get_string (d, "info.parent");
+ if ((parent_udi == NULL) || (strlen(parent_udi) == 0)) {
+ HAL_INFO (("parent not found in GDL %s", parent_udi));
+ return;
+ }
+ if ((parent = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "info.udi", parent_udi)) == NULL) {
+ HAL_INFO (("parent not found in GDL %s", parent_udi));
+ return;
+ }
+
+ if ((node = di_init (devfs_path, DINFOCPYALL)) == DI_NODE_NIL) {
+ HAL_INFO (("device not found in devinfo %s", devfs_path));
+ return;
+ }
+
+ HAL_INFO (("device %s parent %s", hal_device_get_udi (d), parent_udi));
+ devinfo_lofi_add_major (parent, node, devfs_path, NULL, TRUE, d);
+
+ di_fini (node);
+
+ hotplug_event_process_queue ();
+}
+
+static void
+drvctl_lofi_remove(gchar *parent_devfs_path, gchar *name)
+{
+ devinfo_lofi_remove_minor(parent_devfs_path, name);
+ hotplug_event_process_queue ();
+}
+#endif
diff --git a/hal/files/hald-netbsd/drvctl.h b/hal/files/hald-netbsd/drvctl.h
new file mode 100644
index 0000000000..9e94fae49b
--- /dev/null
+++ b/hal/files/hald-netbsd/drvctl.h
@@ -0,0 +1,24 @@
+/***************************************************************************
+ *
+ * drvctl.h : definitions for NetBSD drvctl events
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifndef DRVCTL_H
+#define DRVCTL_H
+
+#include <glib.h>
+#include <sys/drvctlio.h>
+
+gboolean drvctl_init(void);
+void drvctl_fini(void);
+int drvctl_list(const gchar *devnode, struct devlistargs *laa);
+gboolean drvctl_find_parent(const gchar *devnode, char *parent);
+gboolean drvctl_find_device(const gchar *devnode, prop_dictionary_t *properties);
+
+#endif /* DRVCTL_H */
diff --git a/hal/files/hald-netbsd/envsys.c b/hal/files/hald-netbsd/envsys.c
new file mode 100644
index 0000000000..7ecf8f7caa
--- /dev/null
+++ b/hal/files/hald-netbsd/envsys.c
@@ -0,0 +1,249 @@
+/* $NetBSD: envsys.c,v 1.6 2010/12/16 11:34:51 ahoka Exp $ */
+
+/*-
+ * Copyright (c) 2008 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/envsys.h>
+
+#include <prop/proplib.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "devinfo.h"
+#include "envsys.h"
+
+#define _DEV_SYSMON "/dev/sysmon"
+
+static int envsys_fd = -1;
+
+static gboolean envsys_timeout(gpointer user_data);
+static void envsys_handle_devnode(const char *devnode, prop_array_t properties);
+
+static void envsys_acadapter_handler(HalDevice *d, prop_array_t properties);
+static void envsys_battery_handler(HalDevice *d, prop_array_t properties);
+
+enum battery_state {
+ CHARGING,
+ DISCHARGING,
+ NORMAL
+};
+
+static struct envsys_devmap {
+ const char *capability;
+ void (*handler)(HalDevice *d, prop_array_t properties);
+} devmap[] = {
+ { "ac_adapter", envsys_acadapter_handler },
+ { "battery", envsys_battery_handler },
+};
+
+void
+envsys_init(void)
+{
+ envsys_fd = open (_DEV_SYSMON, O_RDONLY);
+ if (envsys_fd == -1) {
+ HAL_WARNING (("Couldn't open " _DEV_SYSMON ": %s", strerror(errno)));
+ return;
+ }
+
+ g_timeout_add (1000, envsys_timeout, NULL);
+}
+
+static gboolean
+envsys_timeout(gpointer user_data)
+{
+ prop_dictionary_t global_dict;
+ prop_array_t global_array;
+ prop_object_iterator_t iter;
+ prop_dictionary_keysym_t keysym;
+ int status;
+
+ status = prop_dictionary_recv_ioctl (envsys_fd, ENVSYS_GETDICTIONARY, &global_dict);
+ if (status) {
+ HAL_WARNING (("envsys_timeout: ENVSYS_GETDICTIONARY failed: %s", strerror(status)));
+ return FALSE;
+ }
+
+ global_array = prop_dictionary_all_keys (global_dict);
+ if (global_array == NULL) {
+ HAL_WARNING (("envsys_timeout: prop_dictionary_all_keys returned NULL"));
+ return FALSE;
+ }
+ iter = prop_array_iterator (global_array);
+ while ((keysym = (prop_dictionary_keysym_t)prop_object_iterator_next (iter)) != NULL) {
+ const char *devnode;
+ prop_object_t obj;
+
+ devnode = prop_dictionary_keysym_cstring_nocopy (keysym);
+ obj = prop_dictionary_get_keysym (global_dict, keysym);
+ if (obj == NULL || prop_object_type (obj) != PROP_TYPE_ARRAY)
+ continue;
+
+ envsys_handle_devnode (devnode, (prop_array_t)obj);
+ }
+ prop_object_iterator_release (iter);
+
+ prop_object_release (global_array);
+ prop_object_release (global_dict);
+ return TRUE;
+}
+
+static void
+envsys_handle_devnode(const char *devnode, prop_array_t properties)
+{
+ HalDevice *d;
+ unsigned int i;
+
+ d = hal_device_store_match_key_value_string (hald_get_gdl (), "netbsd.device", devnode);
+ if (d == NULL)
+ return;
+
+ for (i = 0; i < __arraycount (devmap); i++) {
+ if (!hal_device_has_capability (d, devmap[i].capability))
+ continue;
+ devmap[i].handler (d, properties);
+ }
+
+ return;
+}
+
+static void
+envsys_acadapter_handler(HalDevice *d, prop_array_t properties)
+{
+ prop_object_iterator_t iter;
+ prop_dictionary_t prop;
+
+ iter = prop_array_iterator (properties);
+ while ((prop = (prop_dictionary_t)prop_object_iterator_next (iter)) != NULL) {
+ const char *descr;
+ uint8_t connected;
+
+ if (prop_dictionary_get_cstring_nocopy (prop, "description", &descr) == false)
+ continue;
+
+ if (strcmp (descr, "connected") != 0)
+ continue;
+
+ if (prop_dictionary_get_uint8 (prop, "cur-value", &connected) == false)
+ continue;
+
+ hal_device_property_set_bool (d, "ac_adapter.present", connected);
+ }
+
+ prop_object_iterator_release (iter);
+}
+
+static void
+envsys_battery_handler(HalDevice *d, prop_array_t properties)
+{
+ prop_object_iterator_t iter;
+ prop_dictionary_t prop;
+ enum battery_state battstate = NORMAL;
+
+ device_property_atomic_update_begin ();
+
+ hal_device_property_set_bool (d, "battery.is_rechargeable", TRUE);
+
+ iter = prop_array_iterator (properties);
+ while ((prop = (prop_dictionary_t)prop_object_iterator_next (iter)) != NULL) {
+ const char *descr;
+ const char *valid;
+ int64_t intval;
+
+ if (prop_dictionary_get_cstring_nocopy (prop, "description", &descr) == false ||
+ prop_dictionary_get_int64 (prop, "cur-value", &intval) == false ||
+ prop_dictionary_get_cstring_nocopy (prop, "state", &valid) == false ||
+ strcmp (valid, "valid") != 0)
+ continue;
+
+ if (strcmp (descr, "present") == 0)
+ hal_device_property_set_bool (d, "battery.present", intval);
+ else if (strcmp (descr, "design cap") == 0)
+ hal_device_property_set_int (d, "battery.charge_level.design", intval);
+ else if (strcmp (descr, "last full cap") == 0)
+ hal_device_property_set_int (d, "battery.charge_level.last_full", intval);
+ else if (strcmp (descr, "charge") == 0) {
+ int64_t maxval;
+ const char *type;
+
+ if (prop_dictionary_get_cstring_nocopy (prop, "type", &type))
+ if (strcmp (type, "Ampere hour") == 0) {
+ /* HAL 0.5.12 spec discourages this, but what can we do about it? */
+ hal_device_property_set_string (d, "battery.charge_level.unit", "mAh");
+ }
+
+ hal_device_property_set_int (d, "battery.charge_level.current", intval);
+
+ if (prop_dictionary_get_int64 (prop, "max-value", &maxval) && maxval > 0)
+ hal_device_property_set_int (d, "battery.charge_level.percentage", intval * 100 / maxval);
+ else
+ hal_device_property_set_int (d, "battery.charge_level.percentage", 0);
+ }
+ else if (strcmp (descr, "charge rate") == 0) {
+ battstate = CHARGING;
+ hal_device_property_set_int (d, "battery.charge_level.rate", intval);
+ } else if (strcmp (descr, "discharge rate") == 0) {
+ battstate = DISCHARGING;
+ hal_device_property_set_int (d, "battery.charge_level.rate", intval);
+ }
+ }
+
+ switch (battstate) {
+ case NORMAL:
+ hal_device_property_set_bool (d, "battery.rechargeable.is_charging", FALSE);
+ hal_device_property_set_bool (d, "battery.rechargeable.is_discharging", FALSE);
+ hal_device_property_set_int (d, "battery.charge_level.rate", 0);
+ break;
+ case CHARGING:
+ hal_device_property_set_bool (d, "battery.rechargeable.is_charging", TRUE);
+ hal_device_property_set_bool (d, "battery.rechargeable.is_discharging", FALSE);
+ break;
+ case DISCHARGING:
+ hal_device_property_set_bool (d, "battery.rechargeable.is_charging", FALSE);
+ hal_device_property_set_bool (d, "battery.rechargeable.is_discharging", TRUE);
+ break;
+ }
+
+ device_property_atomic_update_end ();
+
+ prop_object_iterator_release (iter);
+}
diff --git a/hal/files/hald-netbsd/envsys.h b/hal/files/hald-netbsd/envsys.h
new file mode 100644
index 0000000000..fa228f3caf
--- /dev/null
+++ b/hal/files/hald-netbsd/envsys.h
@@ -0,0 +1,36 @@
+/* $NetBSD: envsys.h,v 1.1 2008/11/27 01:45:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2008 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DEVINFO_ENVSYS_H
+#define DEVINFO_ENVSYS_H
+
+#include "devinfo.h"
+
+void envsys_init(void);
+
+#endif /* DEVINFO_ENVSYS_H */
diff --git a/hal/files/hald-netbsd/hal-file-monitor.c b/hal/files/hald-netbsd/hal-file-monitor.c
new file mode 100644
index 0000000000..1dddfa319d
--- /dev/null
+++ b/hal/files/hald-netbsd/hal-file-monitor.c
@@ -0,0 +1,821 @@
+/***************************************************************************
+ * CVSID: hal-file-monitor.c,v 1.1.1.1 2017/04/16 15:28:00 cvs Exp
+ *
+ * hal-file-monitor.c: Kqueue-based file monitor
+ *
+ * Copyright (C) 2007 Joe Marcus Clarke <marcus%FreeBSD.org@localhost>
+ *
+ * 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
+ *
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <glib-object.h>
+
+#include "../hal-file-monitor.h"
+
+#define HAL_FILE_MONITOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), HAL_TYPE_FILE_MONITOR, HalFileMonitorPrivate))
+
+#define VN_NOTE_CHANGED (NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_LINK)
+#define VN_NOTE_DELETED (NOTE_DELETE | NOTE_REVOKE)
+#define VN_NOTE_ALL (VN_NOTE_CHANGED | VN_NOTE_DELETED | NOTE_RENAME)
+
+typedef struct
+{
+ char *path;
+ int omask;
+ gboolean isdir;
+ HalFileMonitorNotifyFunc func;
+ gpointer udata;
+ GHashTable *dir_contents;
+} FileKqueueData;
+
+typedef struct
+{
+ char *path;
+ time_t atime;
+ gboolean owner;
+ HalFileMonitorNotifyFunc func;
+ gpointer udata;
+} FileAccessData;
+
+struct HalFileMonitorPrivate
+{
+ int kqueue_fd;
+ guint io_watch;
+ guint access_source;
+
+ gboolean initialized_kqueue;
+
+ GHashTable *fd_to_kdata;
+ GHashTable *fd_to_adata;
+};
+
+G_DEFINE_TYPE (HalFileMonitor, hal_file_monitor, G_TYPE_OBJECT)
+
+static gpointer monitor_object = NULL;
+
+static void hal_file_monitor_finalize (GObject *object);
+static GHashTable *get_dir_contents (const char *path);
+static GHashTable *diff_dir_contents (FileKqueueData *data, GSList **added, GSList **removed);
+static int hal_mask_to_kmask (int mask);
+static void monitor_release_kdata (HalFileMonitor *monitor, int fd, FileKqueueData *data);
+static void monitor_release_adata (HalFileMonitor *monitor, int fd, FileAccessData *data);
+static gboolean remove_kdata_foreach (gpointer fd, FileKqueueData *data, HalFileMonitor *monitor);
+static gboolean remove_adata_foreach (gpointer fd, FileAccessData *data, HalFileMonitor *monitor);
+static void hal_file_monitor_remove_kdata (HalFileMonitor *monitor, guint id);
+static void hal_file_monitor_remove_adata (HalFileMonitor *monitor, guint id);
+static void setup_monitor (HalFileMonitor *monitor);
+static void close_monitor (HalFileMonitor *monitor);
+static gboolean hal_file_access_monitor (gpointer data);
+/*static char *fflags_to_str (int fflags);*/
+static void emit_monitor_event (HalFileMonitor *monitor, HalFileMonitorEvent event, const char *path, HalFileMonitorNotifyFunc func, gpointer udata);
+static gboolean handle_kqueue_event (GIOChannel *source, GIOCondition condition, gpointer udata);
+
+GQuark
+hal_file_monitor_error_quark (void)
+{
+ static GQuark ret = 0;
+ if (ret == 0)
+ {
+ ret = g_quark_from_static_string ("hal_file_monitor_error");
+ }
+
+ return ret;
+}
+
+static int
+hal_mask_to_kmask (int mask)
+{
+ int kmask = 0;
+
+ if (mask & HAL_FILE_MONITOR_EVENT_CREATE)
+ {
+ kmask |= NOTE_WRITE | NOTE_LINK;
+ }
+
+ if (mask & HAL_FILE_MONITOR_EVENT_DELETE)
+ {
+ kmask |= NOTE_WRITE | NOTE_LINK | VN_NOTE_DELETED;
+ }
+
+ if (mask & HAL_FILE_MONITOR_EVENT_CHANGE)
+ {
+ kmask |= VN_NOTE_CHANGED;
+ }
+
+ return kmask;
+}
+
+guint
+hal_file_monitor_add_notify (HalFileMonitor *monitor,
+ const char *path,
+ int mask,
+ HalFileMonitorNotifyFunc notify_func,
+ gpointer data)
+{
+ struct kevent ev;
+ struct stat sb;
+ int fd;
+ int id = 0;
+
+ if (! monitor->priv->initialized_kqueue)
+ {
+ return id;
+ }
+
+ fd = open (path, O_RDONLY);
+ if (fd < 0)
+ {
+ return id;
+ }
+
+ if (fstat (fd, &sb) == -1)
+ {
+ close (fd);
+ return id;
+ }
+
+ if (mask & HAL_FILE_MONITOR_EVENT_ACCESS)
+ {
+ FileAccessData *adata;
+
+ adata = g_new0 (FileAccessData, 1);
+ adata->path = g_strdup (path);
+ adata->atime = sb.st_atime;
+ adata->func = notify_func;
+ adata->udata = data;
+ if (mask == HAL_FILE_MONITOR_EVENT_ACCESS)
+ {
+ /* We will close the file descriptor when we release the adata. */
+ adata->owner = TRUE;
+ }
+ g_hash_table_insert (monitor->priv->fd_to_adata,
+ GINT_TO_POINTER (fd),
+ adata);
+ id = fd;
+ }
+
+ if ((mask & HAL_FILE_MONITOR_EVENT_CREATE) ||
+ (mask & HAL_FILE_MONITOR_EVENT_DELETE) ||
+ (mask & HAL_FILE_MONITOR_EVENT_CHANGE))
+ {
+ FileKqueueData *kdata;
+ int kmask;
+ gboolean isdir;
+
+ kmask = hal_mask_to_kmask (mask);
+
+ isdir = (sb.st_mode & S_IFDIR) != 0;
+ if (! isdir && mask == HAL_FILE_MONITOR_EVENT_CREATE)
+ {
+ /* We can't monitor creation on a file. */
+ goto done;
+ }
+
+ kdata = g_new0 (FileKqueueData, 1);
+ kdata->path = g_strdup (path);
+ kdata->omask = mask;
+ kdata->isdir = isdir;
+ kdata->func = notify_func;
+ kdata->udata = data;
+ if (isdir)
+ {
+ kdata->dir_contents = get_dir_contents (path);
+ }
+
+ /*g_warning ("XXX: Adding event with mask %s", fflags_to_str (kmask));*/
+ EV_SET (&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
+ kmask, 0, monitor);
+ if (kevent (monitor->priv->kqueue_fd, &ev, 1, NULL, 0, NULL) < 0)
+ {
+ monitor_release_kdata (monitor, fd, kdata);
+ goto done;
+ }
+ g_hash_table_insert (monitor->priv->fd_to_kdata,
+ GINT_TO_POINTER (fd),
+ kdata);
+ id = fd;
+ }
+
+done:
+ return id;
+}
+
+static void
+hal_file_monitor_remove_kdata (HalFileMonitor *monitor,
+ guint id)
+{
+ FileKqueueData *kdata;
+
+ kdata = (FileKqueueData *) g_hash_table_lookup (monitor->priv->fd_to_kdata, GINT_TO_POINTER (id));
+
+ if (kdata)
+ {
+ g_hash_table_remove (monitor->priv->fd_to_kdata, GINT_TO_POINTER (id));
+ monitor_release_kdata (monitor, id, kdata);
+ }
+}
+
+static void
+hal_file_monitor_remove_adata (HalFileMonitor *monitor,
+ guint id)
+{
+ FileAccessData *adata;
+
+ adata = (FileAccessData *) g_hash_table_lookup (monitor->priv->fd_to_adata, GINT_TO_POINTER (id));
+
+ if (adata)
+ {
+ g_hash_table_remove (monitor->priv->fd_to_adata, GINT_TO_POINTER (id));
+ monitor_release_adata (monitor, id, adata);
+ }
+}
+
+void
+hal_file_monitor_remove_notify (HalFileMonitor *monitor,
+ guint id)
+{
+ if (! monitor->priv->initialized_kqueue)
+ return;
+
+ hal_file_monitor_remove_kdata (monitor, id);
+ hal_file_monitor_remove_adata (monitor, id);
+
+}
+
+static void
+monitor_release_kdata (HalFileMonitor *monitor,
+ int fd,
+ FileKqueueData *data)
+{
+ g_free (data->path);
+ data->path = NULL;
+
+ if (data->dir_contents)
+ {
+ g_hash_table_remove_all (data->dir_contents);
+ g_hash_table_destroy (data->dir_contents);
+ }
+ data->dir_contents = NULL;
+
+ close (fd);
+
+ g_free (data);
+}
+
+static void
+monitor_release_adata (HalFileMonitor *monitor,
+ int fd,
+ FileAccessData *data)
+{
+ g_free (data->path);
+ data->path = NULL;
+
+ if (data->owner)
+ {
+ close (fd);
+ }
+
+ g_free (data);
+}
+
+static gboolean
+remove_kdata_foreach (gpointer fd,
+ FileKqueueData *data,
+ HalFileMonitor *monitor)
+{
+ monitor_release_kdata (monitor, GPOINTER_TO_INT (fd), data);
+ return TRUE;
+}
+
+static gboolean
+remove_adata_foreach (gpointer fd,
+ FileAccessData *data,
+ HalFileMonitor *monitor)
+{
+ monitor_release_adata (monitor, GPOINTER_TO_INT (fd), data);
+ return TRUE;
+}
+
+static void
+close_monitor (HalFileMonitor *monitor)
+{
+ if (! monitor->priv->initialized_kqueue)
+ {
+ return;
+ }
+
+ monitor->priv->initialized_kqueue = FALSE;
+
+ g_hash_table_foreach_remove (monitor->priv->fd_to_kdata,
+ (GHRFunc) remove_kdata_foreach,
+ monitor);
+
+ g_hash_table_foreach_remove (monitor->priv->fd_to_adata,
+ (GHRFunc) remove_adata_foreach,
+ monitor);
+
+ if (monitor->priv->io_watch)
+ {
+ g_source_remove (monitor->priv->io_watch);
+ }
+ monitor->priv->io_watch = 0;
+
+ if (monitor->priv->access_source)
+ {
+ g_source_remove (monitor->priv->access_source);
+ }
+ monitor->priv->access_source = 0;
+
+ if (monitor->priv->kqueue_fd > -1)
+ {
+ close (monitor->priv->kqueue_fd);
+ }
+ monitor->priv->kqueue_fd = -1;
+}
+
+static gboolean
+hal_file_access_monitor (gpointer data)
+{
+ HalFileMonitor *monitor;
+ GList *keys, *l;
+
+ g_return_val_if_fail (HAL_IS_FILE_MONITOR (data), FALSE);
+
+ monitor = HAL_FILE_MONITOR (data);
+
+ g_return_val_if_fail (monitor->priv != NULL, FALSE);
+
+ keys = g_hash_table_get_keys (monitor->priv->fd_to_adata);
+
+ for (l = keys; l != NULL; l = l->next)
+ {
+ FileAccessData *adata;
+ struct stat sb;
+ int fd;
+
+ fd = GPOINTER_TO_INT (l->data);
+ adata = g_hash_table_lookup (monitor->priv->fd_to_adata,
+ l->data);
+
+ if (! adata)
+ {
+ continue;
+ }
+
+ if (fstat (fd, &sb) == -1)
+ {
+ g_warning ("Failed to stat %s: %s", adata->path, g_strerror (errno));
+ hal_file_monitor_remove_adata (monitor, fd);
+ continue;
+ }
+
+ if (sb.st_atime != adata->atime)
+ {
+ adata->atime = sb.st_atime;
+ emit_monitor_event (monitor, HAL_FILE_MONITOR_EVENT_ACCESS, adata->path, adata->func, adata->udata);
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+setup_monitor (HalFileMonitor *monitor)
+{
+ GIOChannel *io_channel;
+ int fd;
+
+ if (monitor->priv->initialized_kqueue)
+ {
+ return;
+ }
+
+ if ((fd = kqueue ()) < 0)
+ {
+ g_warning ("Failed to initialize kqueue: %s",
+ g_strerror (errno));
+ return;
+ }
+
+ monitor->priv->kqueue_fd = fd;
+
+ monitor->priv->fd_to_kdata = g_hash_table_new (g_direct_hash,
+ g_direct_equal);
+ monitor->priv->fd_to_adata = g_hash_table_new (g_direct_hash,
+ g_direct_equal);
+
+ io_channel = g_io_channel_unix_new (fd);
+ monitor->priv->io_watch = g_io_add_watch (io_channel,
+ G_IO_IN|G_IO_PRI,
+ (GIOFunc) handle_kqueue_event,
+ monitor);
+ g_io_channel_unref (io_channel);
+
+ monitor->priv->access_source = g_timeout_add (1000, (GSourceFunc) hal_file_access_monitor, monitor);
+
+ monitor->priv->initialized_kqueue = TRUE;
+}
+
+static void
+hal_file_monitor_init (HalFileMonitor *monitor)
+{
+ monitor->priv = HAL_FILE_MONITOR_GET_PRIVATE (monitor);
+
+ setup_monitor (monitor);
+}
+
+static void
+hal_file_monitor_class_init (HalFileMonitorClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = hal_file_monitor_finalize;
+
+ g_type_class_add_private (klass, sizeof (HalFileMonitorPrivate));
+}
+
+static void
+hal_file_monitor_finalize (GObject *object)
+{
+ HalFileMonitor *monitor;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (HAL_IS_FILE_MONITOR (object));
+
+ monitor = HAL_FILE_MONITOR (object);
+
+ g_return_if_fail (monitor->priv != NULL);
+
+ close_monitor (monitor);
+
+ g_hash_table_destroy (monitor->priv->fd_to_kdata);
+ g_hash_table_destroy (monitor->priv->fd_to_adata);
+
+ G_OBJECT_CLASS (hal_file_monitor_parent_class)->finalize (object);
+}
+
+HalFileMonitor *
+hal_file_monitor_new (void)
+{
+ if (monitor_object != NULL)
+ {
+ g_object_ref (monitor_object);
+ }
+ else
+ {
+ monitor_object = g_object_new (HAL_TYPE_FILE_MONITOR, NULL);
+
+ g_object_add_weak_pointer (monitor_object,
+ (gpointer *) &monitor_object);
+ }
+
+ return HAL_FILE_MONITOR (monitor_object);
+}
+
+/*
+static char *
+fflags_to_str (int fflags)
+{
+
+ GString *out;
+
+ out = g_string_new (NULL);
+
+ if (fflags & NOTE_WRITE)
+ {
+ g_string_append (out, " WRITE ");
+ }
+ if (fflags & NOTE_EXTEND)
+ {
+ g_string_append (out, " EXTEND ");
+ }
+ if (fflags & NOTE_ATTRIB)
+ {
+ g_string_append (out, " ATTRIB ");
+ }
+ if (fflags & NOTE_LINK)
+ {
+ g_string_append (out, " LINK ");
+ }
+ if (fflags & NOTE_DELETE)
+ {
+ g_string_append (out, " DELETE ");
+ }
+ if (fflags & NOTE_REVOKE)
+ {
+ g_string_append (out, " REVOKE ");
+ }
+ if (fflags & NOTE_RENAME)
+ {
+ g_string_append (out, " RENAME ");
+ }
+
+ return g_string_free (out, FALSE);
+}
+*/
+
+static void
+emit_monitor_event (HalFileMonitor *monitor,
+ HalFileMonitorEvent event,
+ const char *path,
+ HalFileMonitorNotifyFunc func,
+ gpointer udata)
+{
+ if (func)
+ {
+ func (monitor, event, path, udata);
+ }
+}
+
+static gboolean
+handle_kqueue_event (GIOChannel *source,
+ GIOCondition condition,
+ gpointer udata)
+{
+ struct kevent ev;
+ struct timespec timeout = { 0, 0 };
+ int nevents;
+ HalFileMonitor *monitor;
+
+ g_return_val_if_fail (HAL_IS_FILE_MONITOR (udata), FALSE);
+
+ monitor = HAL_FILE_MONITOR (udata);
+
+ g_return_val_if_fail (monitor->priv != NULL, FALSE);
+
+ g_return_val_if_fail (monitor->priv->kqueue_fd > -1, FALSE);
+
+ nevents = kevent (monitor->priv->kqueue_fd, NULL, 0, &ev, 1, &timeout);
+ if (nevents == 1)
+ {
+ int fd;
+ FileKqueueData *data;
+
+ fd = ev.ident;
+ data = g_hash_table_lookup (monitor->priv->fd_to_kdata,
+ GINT_TO_POINTER (fd));
+ if (! data)
+ {
+ /* The monitor may have been deleted. */
+ return TRUE;
+ }
+
+ if ((data->omask & HAL_FILE_MONITOR_EVENT_DELETE) &&
+ (ev.fflags & VN_NOTE_DELETED))
+ {
+ emit_monitor_event (monitor, HAL_FILE_MONITOR_EVENT_DELETE, data->path, data->func, data->udata);
+ hal_file_monitor_remove_kdata (monitor, fd);
+ return TRUE;
+ }
+
+ if ((data->omask & HAL_FILE_MONITOR_EVENT_CREATE) ||
+ (data->omask & HAL_FILE_MONITOR_EVENT_DELETE))
+ {
+ if (data->isdir)
+ {
+ GSList *added = NULL;
+ GSList *removed = NULL;
+ GSList *l;
+ GHashTable *table;
+ gboolean found_change = FALSE;
+
+ table = diff_dir_contents (data, &added, &removed);
+ if (data->omask & HAL_FILE_MONITOR_EVENT_CREATE)
+ {
+ for (l = added; l != NULL; l = l->next)
+ {
+ char *path;
+
+ path = g_build_filename (data->path, l->data, NULL);
+ emit_monitor_event (monitor, HAL_FILE_MONITOR_EVENT_CREATE, path, data->func, data->udata);
+ g_free (path);
+ }
+ }
+
+ if (data->omask & HAL_FILE_MONITOR_EVENT_DELETE)
+ {
+ for (l = removed; l != NULL; l = l->next)
+ {
+ char *path;
+
+ path = g_build_filename (data->path, l->data, NULL);
+ emit_monitor_event (monitor, HAL_FILE_MONITOR_EVENT_DELETE, path, data->func, data->udata);
+ g_free (path);
+ }
+ }
+
+ if (added || removed)
+ {
+ g_hash_table_remove_all (data->dir_contents);
+ g_hash_table_destroy (data->dir_contents);
+ data->dir_contents = table;
+ found_change = TRUE;
+ }
+ else if (table)
+ {
+ g_hash_table_remove_all (table);
+ g_hash_table_destroy (table);
+ }
+ else
+ {
+ hal_file_monitor_remove_kdata (monitor, fd);
+ }
+
+ if (added)
+ {
+ g_slist_foreach (added, (GFunc) g_free, NULL);
+ g_slist_free (added);
+ }
+ if (removed)
+ {
+ g_slist_foreach (removed, (GFunc) g_free, NULL);
+ g_slist_free (removed);
+ }
+
+ if (found_change)
+ {
+ return TRUE;
+ }
+ }
+ }
+
+ if (data->omask & HAL_FILE_MONITOR_EVENT_CHANGE)
+ {
+ emit_monitor_event (monitor, HAL_FILE_MONITOR_EVENT_CHANGE, data->path, data->func, data->udata);
+ }
+ }
+ else
+ {
+ g_warning ("Failed to read from kqueue: %s", g_strerror (errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static GHashTable *
+diff_dir_contents (FileKqueueData *data,
+ GSList **added,
+ GSList **removed)
+{
+ GDir *dir;
+ GError *err = NULL;
+ GHashTable *table = NULL;
+
+ dir = g_dir_open (data->path, 0, &err);
+ if (dir)
+ {
+ const char *fname;
+
+ table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ while ((fname = g_dir_read_name (dir)))
+ {
+ if (added)
+ {
+ if (! g_hash_table_lookup (data->dir_contents, fname))
+ {
+ *added = g_slist_prepend (*added, g_strdup (fname));
+ }
+ }
+
+ g_hash_table_insert (table, g_strdup (fname), GINT_TO_POINTER (TRUE));
+ }
+
+ g_dir_close (dir);
+
+ if (removed)
+ {
+ GList *keys;
+ GList *l;
+
+ keys = g_hash_table_get_keys (data->dir_contents);
+
+ for (l = keys; l != NULL; l = l->next)
+ {
+ if (! g_hash_table_lookup (table, l->data))
+ {
+ *removed = g_slist_prepend (*removed, g_strdup (l->data));
+ }
+ }
+ }
+
+ }
+ else
+ {
+ g_warning ("Failed to open directory: %s", err->message);
+ g_error_free (err);
+ }
+
+ return table;
+}
+
+static GHashTable *
+get_dir_contents (const char *path)
+{
+ GDir *dir;
+ GError *err = NULL;
+ GHashTable *table = NULL;
+
+ dir = g_dir_open (path, 0, &err);
+ if (dir)
+ {
+ const char *fname;
+
+ table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ while ((fname = g_dir_read_name (dir)))
+ {
+ g_hash_table_insert (table, g_strdup (fname), GINT_TO_POINTER (TRUE));
+ }
+ g_dir_close (dir);
+ }
+ else
+ {
+ g_warning ("Failed to open directory %s: %s\n", path, err->message);
+ g_error_free (err);
+ }
+
+ return table;
+}
+
+/*
+static void
+print_event (HalFileMonitor *monitor,
+ HalFileMonitorEvent event,
+ const char *path,
+ gpointer udata)
+{
+ GString *ename;
+
+ ename = g_string_new (NULL);
+
+ if (event & HAL_FILE_MONITOR_EVENT_ACCESS)
+ {
+ g_string_append (ename, "ACCESS ");
+ }
+ if (event & HAL_FILE_MONITOR_EVENT_CREATE)
+ {
+ g_string_append (ename, "CREATE ");
+ }
+ if (event & HAL_FILE_MONITOR_EVENT_DELETE)
+ {
+ g_string_append (ename, "DELETE ");
+ }
+ if (event & HAL_FILE_MONITOR_EVENT_CHANGE)
+ {
+ g_string_append (ename, "CHANGE ");
+ }
+
+ printf("Received event for %s: %s\n", path, g_string_free (ename, FALSE));
+}
+
+int
+main(void)
+{
+ const char *path = "/tmp/kqueue.d";
+ guint watch;
+ GMainLoop *loop;
+ HalFileMonitor *monitor;
+
+ g_type_init ();
+
+ monitor = hal_file_monitor_new ();
+ hal_file_monitor_add_notify (monitor, path, HAL_FILE_MONITOR_EVENT_CREATE|HAL_FILE_MONITOR_EVENT_DELETE|HAL_FILE_MONITOR_EVENT_CHANGE,print_event, NULL);
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ g_main_loop_run (loop);
+
+ return 0;
+}
+*/
diff --git a/hal/files/hald-netbsd/hotplug.c b/hal/files/hald-netbsd/hotplug.c
new file mode 100644
index 0000000000..ce96f84f5e
--- /dev/null
+++ b/hal/files/hald-netbsd/hotplug.c
@@ -0,0 +1,204 @@
+/***************************************************************************
+ *
+ * hotplug.c : HAL-internal hotplug events
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "@(#)hotplug.c 1.2 06/10/13 SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../device_info.h"
+
+#include "osspec_netbsd.h"
+#include "hotplug.h"
+#include "devinfo.h"
+
+/** Queue of ordered hotplug events */
+GQueue *hotplug_event_queue;
+
+/** List of HotplugEvent objects we are currently processing */
+GSList *hotplug_events_in_progress = NULL;
+
+static void hotplug_event_begin (HotplugEvent *hotplug_event);
+
+void
+hotplug_event_end (void *end_token)
+{
+ HotplugEvent *hotplug_event = (HotplugEvent *) end_token;
+
+ hotplug_events_in_progress = g_slist_remove (hotplug_events_in_progress, hotplug_event);
+ g_free (hotplug_event);
+ hotplug_event_process_queue ();
+}
+
+static void
+hotplug_event_begin_devfs_add (HotplugEvent *hotplug_event, HalDevice *d)
+{
+ HalDevice *parent;
+ const gchar *parent_udi;
+ void (*begin_add_func) (HalDevice *, HalDevice *, DevinfoDevHandler *, void *);
+
+ if (d != NULL) {
+ /* XXX */
+ HAL_ERROR (("devpath %s already present in store, ignore event", hotplug_event->un.devfs.devfs_path));
+ hotplug_event_end ((void *) hotplug_event);
+ return;
+ }
+
+ /* find parent */
+ parent_udi = hal_device_property_get_string (hotplug_event->d, "info.parent");
+ if (parent_udi == NULL || strlen(parent_udi) == 0) {
+ parent = NULL;
+ HAL_INFO (("no info.parent parameter found"));
+ } else {
+ parent = hal_device_store_match_key_value_string (hald_get_gdl (), "info.udi", parent_udi);
+ if (parent == NULL)
+ HAL_INFO (("no info.udi=%s parameter found", parent_udi));
+ }
+
+ if (parent == NULL) {
+ gchar pdevnode[512];
+ HAL_INFO (("couldn't look up %s parent by udi, trying netbsd.device", hotplug_event->un.devfs.devfs_path));
+ if (drvctl_find_parent (hotplug_event->un.devfs.devfs_path, pdevnode) == TRUE)
+ parent = hal_device_store_match_key_value_string (hald_get_gdl (), "netbsd.device", pdevnode);
+ }
+
+ /* only root node is allowed to be orphan */
+ if (parent == NULL) {
+ if (strcmp(hotplug_event->un.devfs.devfs_path, "mainbus0") != 0) {
+ HAL_ERROR (("Parent is NULL devfs_path=%s parent_udi=%s", hotplug_event->un.devfs.devfs_path, parent_udi ? parent_udi : "<null>"));
+ hotplug_event_end ((void *) hotplug_event);
+ return;
+ }
+ }
+
+ /* children of ignored parent should be ignored */
+ if (hal_device_property_get_bool (parent, "info.ignore")) {
+ HAL_INFO (("parent ignored %s", parent_udi));
+ hotplug_event_end ((void *) hotplug_event);
+ return;
+ }
+
+ /* custom or generic add function */
+ begin_add_func = hotplug_event->un.devfs.handler->hotplug_begin_add;
+ if (begin_add_func == NULL) {
+ begin_add_func = hotplug_event_begin_add_devinfo;
+ }
+ begin_add_func (hotplug_event->d,
+ parent,
+ hotplug_event->un.devfs.handler,
+ (void *) hotplug_event);
+}
+
+static void
+hotplug_event_begin_devfs_remove (HotplugEvent *hotplug_event, HalDevice *d)
+{
+ if (d == NULL) {
+ HAL_ERROR (("devpath %s not present in store, ignore event", hotplug_event->un.devfs.devfs_path));
+ hotplug_event_end ((void *) hotplug_event);
+ return;
+ }
+ HAL_INFO (("hotplug_event_begin_devfs_remove %s", hal_device_get_udi (d)));
+
+ hotplug_event_begin_remove_devinfo(d,
+ hotplug_event->un.devfs.devfs_path,
+ (void *) hotplug_event);
+}
+
+static void
+hotplug_event_begin_devfs (HotplugEvent *hotplug_event)
+{
+ HalDevice *d;
+
+ HAL_INFO (("hotplug_event_begin_devfs: %s", hotplug_event->un.devfs.devfs_path));
+ d = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "netbsd.device",
+ hotplug_event->un.devfs.devfs_path);
+
+ if (hotplug_event->action == HOTPLUG_ACTION_ADD) {
+ hotplug_event_begin_devfs_add (hotplug_event, d);
+ } else if (hotplug_event->action == HOTPLUG_ACTION_REMOVE) {
+ hotplug_event_begin_devfs_remove (hotplug_event, d);
+ } else {
+ hotplug_event_end ((void *) hotplug_event);
+ }
+}
+
+static void
+hotplug_event_begin (HotplugEvent *hotplug_event)
+{
+ switch (hotplug_event->type) {
+
+ case HOTPLUG_EVENT_DEVFS:
+ hotplug_event_begin_devfs (hotplug_event);
+ break;
+
+ default:
+ HAL_ERROR (("Unknown hotplug event type %d", hotplug_event->type));
+ hotplug_event_end ((void *) hotplug_event);
+ break;
+ }
+}
+
+void
+hotplug_event_enqueue (HotplugEvent *hotplug_event, int front)
+{
+ if (hotplug_event_queue == NULL)
+ hotplug_event_queue = g_queue_new ();
+
+ if (front) {
+ g_queue_push_head (hotplug_event_queue, hotplug_event);
+ } else {
+ g_queue_push_tail (hotplug_event_queue, hotplug_event);
+ }
+}
+
+void
+hotplug_event_process_queue (void)
+{
+ HotplugEvent *hotplug_event;
+
+ if (hotplug_events_in_progress == NULL &&
+ (hotplug_event_queue == NULL || g_queue_is_empty (hotplug_event_queue))) {
+ hotplug_queue_now_empty ();
+ goto out;
+ }
+
+ /* do not process events if some other event is in progress */
+ if (hotplug_events_in_progress != NULL && g_slist_length (hotplug_events_in_progress) > 0)
+ goto out;
+
+ hotplug_event = g_queue_pop_head (hotplug_event_queue);
+ if (hotplug_event == NULL)
+ goto out;
+
+ hotplug_events_in_progress = g_slist_append (hotplug_events_in_progress, hotplug_event);
+ hotplug_event_begin (hotplug_event);
+
+out:
+ ;
+}
diff --git a/hal/files/hald-netbsd/hotplug.h b/hal/files/hald-netbsd/hotplug.h
new file mode 100644
index 0000000000..fc9f92ec1c
--- /dev/null
+++ b/hal/files/hald-netbsd/hotplug.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *
+ * hotplug.h : definitions for HAL-internal hotplug events
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifndef HOTPLUG_H
+#define HOTPLUG_H
+
+#include <glib.h>
+
+#include "../device.h"
+#include "../util.h"
+
+#include "devinfo.h"
+
+typedef enum {
+ HOTPLUG_ACTION_ADD,
+ HOTPLUG_ACTION_REMOVE,
+} HotplugActionType;
+
+typedef enum {
+ HOTPLUG_EVENT_DEVFS = 0,
+} HotplugEventType;
+
+/** Data structure representing a hotplug event; also used for
+ * coldplugging.
+ */
+typedef struct
+{
+ HotplugActionType action; /**< Whether the event is add or remove */
+ HotplugEventType type; /**< Type of hotplug event */
+
+ HalDevice *d;
+
+ union {
+ struct {
+ char devfs_path[HAL_PATH_MAX];
+ DevinfoDevHandler *handler;
+ } devfs;
+ } un;
+
+} HotplugEvent;
+
+void hotplug_event_enqueue (HotplugEvent *event, int front);
+
+void hotplug_event_process_queue (void);
+
+void hotplug_event_end (void *end_token);
+
+void hotplug_queue_now_empty (void);
+
+#endif /* HOTPLUG_H */
diff --git a/hal/files/hald-netbsd/osspec.c b/hal/files/hald-netbsd/osspec.c
new file mode 100644
index 0000000000..44a035dd81
--- /dev/null
+++ b/hal/files/hald-netbsd/osspec.c
@@ -0,0 +1,183 @@
+/***************************************************************************
+ *
+ * osspec.c : NetBSD HAL backend entry points
+ *
+ * Copyright 2008 Jared D. McNeill <jmcneill%NetBSD.org@localhost>
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/statvfs.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../ids.h"
+#include "osspec_netbsd.h"
+#include "hotplug.h"
+#include "drvctl.h"
+#include "envsys.h"
+#include "devinfo.h"
+#include "devinfo_storage.h"
+
+static void mntinfo_event_init ();
+static gboolean mntinfo_timeout (gpointer user_data);
+
+HalFileMonitor *
+osspec_get_file_monitor (void)
+{
+#warning Please implement
+ return NULL;
+}
+
+void
+osspec_init (void)
+{
+ ids_init ();
+ mntinfo_event_init ();
+ envsys_init ();
+}
+
+void
+osspec_privileged_init (void)
+{
+ drvctl_init ();
+}
+
+void
+hotplug_queue_now_empty (void)
+{
+ if (hald_is_initialising) {
+ osspec_probe_done ();
+ }
+}
+
+void
+osspec_probe (void)
+{
+ /* add entire device tree */
+ devinfo_add (NULL, "mainbus0");
+
+ /* start processing events */
+ hotplug_event_process_queue ();
+}
+
+gboolean
+osspec_device_rescan (HalDevice *d)
+{
+ return (devinfo_device_rescan (d));
+}
+
+gboolean
+osspec_device_reprobe (HalDevice *d)
+{
+ return FALSE;
+}
+
+DBusHandlerResult
+osspec_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+/**
+ * hal_util_find_closest_ancestor:
+ * @devfs_path: Path into devfs, e.g. /pci@0,0/pci1025,57@10,2/storage@1
+ *
+ * Returns: Parent Hal Device Object or #NULL if there is none
+ *
+ * Find the closest ancestor by looking at devfs paths
+ */
+HalDevice *
+hal_util_find_closest_ancestor (const gchar *devfs_path, gchar **ancestor_devfs_path, gchar **hotplug_devfs_path)
+{
+ gchar buf[512];
+ gchar c;
+ HalDevice *parent;
+
+ parent = NULL;
+
+ if (drvctl_find_parent (devfs_path, buf) == FALSE)
+ return NULL;
+
+ HAL_INFO (("hal_util_find_closest_ancestor: devnode=%s parent=%s\n", devfs_path, buf));
+
+ parent = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "netbsd.device",
+ buf);
+ if (parent != NULL) {
+ if (ancestor_devfs_path != NULL) {
+ *ancestor_devfs_path = g_strdup (buf);
+ }
+ if (hotplug_devfs_path != NULL) {
+ *hotplug_devfs_path = g_strdup (buf);
+ }
+ }
+
+ return parent;
+}
+
+char *
+dsk_to_rdsk(char *dsk)
+{
+ int len, pos;
+ char *p;
+ char *rdsk;
+
+ if ((len = strlen (dsk)) < sizeof ("/dev/AANA") - 1) {
+ return (strdup(""));
+ }
+ p = strstr (dsk, "/dev/");
+ if (p == NULL) {
+ return (strdup(""));
+ }
+
+ pos = (uintptr_t)p - (uintptr_t)dsk;
+ if ((rdsk = (char *)calloc (len + 2, 1)) != NULL) {
+ strncpy (rdsk, dsk, pos + 1);
+ rdsk[pos + 1] = 'r';
+ strcpy (rdsk + pos + 2, dsk + pos + 1);
+ }
+
+ return (rdsk);
+}
+
+/*
+ * Setup to watch mntinfo changes
+ */
+static void
+mntinfo_event_init ()
+{
+ g_timeout_add (1000, mntinfo_timeout, NULL);
+}
+
+static gboolean
+mntinfo_timeout (gpointer user_data)
+{
+ if (!hald_is_initialising)
+ vfsstat_event (NULL);
+
+ return TRUE;
+}
+
+void
+osspec_refresh_mount_state_for_block_device (HalDevice *d)
+{
+ vfsstat_event (d);
+}
diff --git a/hal/files/hald-netbsd/osspec_netbsd.h b/hal/files/hald-netbsd/osspec_netbsd.h
new file mode 100644
index 0000000000..13ba327711
--- /dev/null
+++ b/hal/files/hald-netbsd/osspec_netbsd.h
@@ -0,0 +1,21 @@
+/***************************************************************************
+ *
+ * osspec_netbsd.h : definitions for NetBSD HAL backend
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifndef OSSPEC_NETBSD_H
+#define OSSPEC_NETBSD_H
+
+#include <glib.h>
+
+void hotplug_queue_now_empty (void);
+HalDevice *hal_util_find_closest_ancestor (const gchar *devfs_path, gchar **ancestor_devfs_path, gchar **hotplug_devfs_path);
+char *dsk_to_rdsk(char *);
+
+#endif /* OSSPEC_NETBSD_H */
diff --git a/hal/files/hald-netbsd/probing/Makefile.am b/hal/files/hald-netbsd/probing/Makefile.am
new file mode 100644
index 0000000000..c9a58549ee
--- /dev/null
+++ b/hal/files/hald-netbsd/probing/Makefile.am
@@ -0,0 +1,20 @@
+
+AM_CPPFLAGS = \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
+ -I$(top_srcdir) -I$(top_srcdir)/hald -I$(top_srcdir)/libhal -I$(top_srcdir)/libhal-storage \
+ @GLIB_CFLAGS@ @DBUS_CFLAGS@
+
+if HALD_COMPILE_NETBSD
+libexec_PROGRAMS = hald-probe-storage hald-probe-volume
+endif
+
+hald_probe_storage_SOURCES = probe-storage.c cdutils.c fsutils.c ../../logger.c
+hald_probe_storage_LDADD = $(top_builddir)/libhal/libhal.la @GLIB_LIBS@ -lprop
+
+hald_probe_volume_SOURCES = probe-volume.c cdutils.c fsutils.c ../../logger.c
+hald_probe_volume_LDADD = $(top_builddir)/libhal/libhal.la @GLIB_LIBS@ -lprop
+
diff --git a/hal/files/hald-netbsd/probing/cdutils.c b/hal/files/hald-netbsd/probing/cdutils.c
new file mode 100644
index 0000000000..0d524eb92e
--- /dev/null
+++ b/hal/files/hald-netbsd/probing/cdutils.c
@@ -0,0 +1,379 @@
+/***************************************************************************
+ *
+ * cdutils.h : CD/DVD utilities
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/scsiio.h>
+#include <sys/disklabel.h>
+#include <dev/scsipi/scsi_spc.h>
+#include <dev/scsipi/scsipi_all.h>
+#include <dev/scsipi/scsipi_cd.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/dkio.h>
+#include <libintl.h>
+
+#include <logger.h>
+
+#include "cdutils.h"
+
+#define RQLEN 32
+#define SENSE_KEY(rqbuf) (rqbuf[2]) /* scsi error category */
+#define ASC(rqbuf) (rqbuf[12]) /* additional sense code */
+#define ASCQ(rqbuf) (rqbuf[13]) /* ASC qualifier */
+
+#define GET16(a) (((a)[0] << 8) | (a)[1])
+#define GET32(a) (((a)[0] << 24) | ((a)[1] << 16) | ((a)[2] << 8) | (a)[3])
+
+bool
+scsi_command (int fd, void *cmd, size_t cmdlen, void *data, size_t datalen,
+ int timeout, int flags)
+{
+ scsireq_t req;
+
+ memset(&req, 0, sizeof(req));
+ memcpy(req.cmd, cmd, cmdlen);
+ req.cmdlen = cmdlen;
+ req.databuf = data;
+ req.datalen = datalen;
+ req.timeout = timeout;
+ req.flags = flags;
+ req.senselen = SENSEBUFLEN;
+
+ if (ioctl(fd, SCIOCCOMMAND, &req) == -1)
+ return false;
+ if (req.retsts == SCCMD_OK)
+ return true;
+ return false;
+}
+
+int
+mode_sense(int fd, u_char pc, int dbd, int page_len, u_char *buffer)
+{
+ struct scsi_mode_sense_10 sms10;
+
+ memset(&sms10, 0, sizeof(sms10));
+ sms10.opcode = SCSI_MODE_SENSE_10;
+ if (dbd)
+ sms10.byte2 = SMS_DBD; /* no block descriptors */
+ sms10.page = pc;
+ sms10.length[0] = (page_len >> 8) & 0xff;
+ sms10.length[1] = page_len & 0xff;
+
+ return (scsi_command(fd, &sms10, sizeof(sms10), buffer, page_len, 10000, SCCMD_READ) == true);
+}
+
+/*
+ * will get the mode page only i.e. will strip off the header.
+ */
+int
+get_mode_page(int fd, int page_no, int pc, int buf_len, u_char *buffer, int *plen)
+{
+ int ret;
+ u_char byte2;
+ u_char buf[256];
+ u_int header_len, page_len, copy_cnt;
+
+ byte2 = (u_char)(((pc << 6) & 0xC0) | (page_no & 0x3f));
+
+ /* Ask 254 bytes only to make our IDE driver happy */
+ if ((ret = mode_sense(fd, byte2, 1, 254, buf)) == 0) {
+ return (0);
+ }
+
+ header_len = 8 + GET16(&buf[6]);
+ page_len = buf[header_len + 1] + 2;
+
+ copy_cnt = ((int)page_len > buf_len) ? (u_int)buf_len : page_len;
+ (void) memcpy(buffer, &buf[header_len], copy_cnt);
+
+ if (plen) {
+ *plen = page_len;
+ }
+
+ return (1);
+}
+
+/* Get information about the Logical Unit's capabilities */
+int
+get_configuration(int fd, uint16_t feature, int bufsize, u_char *buf)
+{
+ struct scsipi_get_configuration conf;
+
+ memset(&conf, 0, sizeof(conf));
+ conf.opcode = GET_CONFIGURATION;
+ conf.request_type = 0x2;
+ conf.start_at_feature[0] = (feature >> 8) & 0xff;
+ conf.start_at_feature[1] = feature & 0xff;
+ conf.data_len[0] = (bufsize >> 8) & 0xff;
+ conf.data_len[1] = bufsize & 0xff;
+
+ return (scsi_command(fd, &conf, sizeof(conf), buf, bufsize, 10000, SCCMD_READ) == true);
+}
+
+bool
+get_current_profile(int fd, int *profile)
+{
+ u_char smallbuf[4];
+ size_t buflen;
+ u_char *bufp;
+ int ret = false;
+
+ /* first determine amount of memory needed to hold all profiles */
+ if (get_configuration(fd, 0, 4, &smallbuf[0])) {
+ buflen = GET32(smallbuf) + 4;
+ bufp = (u_char *)malloc(buflen);
+
+ /* now get all profiles */
+ if (get_configuration(fd, 0, buflen, bufp)) {
+ *profile = GET16(&bufp[6]);
+ ret = true;
+ }
+ free(bufp);
+ }
+
+ return (ret);
+}
+
+void
+walk_profiles(int fd, int (*f)(void *, int, bool), void *arg)
+{
+ size_t i;
+ uint16_t profile, current_profile;
+ u_char smallbuf[4];
+ size_t buflen;
+ u_char *bufp;
+ int ret;
+
+ /* first determine amount of memory needed to hold all profiles */
+ if (get_configuration(fd, 0, 4, &smallbuf[0])) {
+ buflen = GET32(smallbuf) + 4;
+ bufp = (u_char *)malloc(buflen);
+
+ /* now get all profiles */
+ if (get_configuration(fd, 0, buflen, bufp)) {
+ current_profile = GET16(&bufp[6]);
+ for (i = 8 + 4; i < buflen; i += 4) {
+ profile = GET16(&bufp[i]);
+ ret = f(arg, profile, (profile == current_profile));
+ if (ret == CDUTIL_WALK_STOP) {
+ break;
+ }
+ }
+ }
+
+ free(bufp);
+ }
+}
+
+/* retrieve speed list from the Write Speed Performance Descriptor Blocks
+ */
+static void
+get_write_speeds(u_char *page, int n, intlist_t **speeds, int *n_speeds, intlist_t **speeds_mem)
+{
+ u_char *p = page + 2;
+ int i;
+ intlist_t **nextp;
+ intlist_t *current;
+ bool skip;
+
+ *n_speeds = 0;
+ *speeds = NULL;
+ *speeds_mem = (intlist_t *)calloc(n, sizeof (intlist_t));
+ if (*speeds_mem == NULL) {
+ return;
+ }
+
+ for (i = 0; i < n; i++, p += 4) {
+ current = &(*speeds_mem)[i];
+ current->val = GET16(p);
+
+ /* keep the list sorted */
+ skip = false;
+ for (nextp = speeds; *nextp != NULL; nextp = &((*nextp)->next)) {
+ if (current->val == (*nextp)->val) {
+ skip = true; /* skip duplicates */
+ break;
+ } else if (current->val > (*nextp)->val) {
+ break;
+ }
+ }
+ if (!skip) {
+ current->next = *nextp;
+ *nextp = current;
+ *n_speeds++;
+ }
+ }
+}
+
+void
+get_read_write_speeds(int fd, int *read_speed, int *write_speed,
+ intlist_t **speeds, int *n_speeds, intlist_t **speeds_mem)
+{
+ int page_len;
+ u_char p[254];
+ int n; /* number of write speed performance descriptor blocks */
+
+ *read_speed = *write_speed = 0;
+ *speeds = *speeds_mem = NULL;
+
+ if (!get_mode_page(fd, 0x2A, 0, sizeof (p), p, &page_len)) {
+ return;
+ }
+
+ if (page_len > 8) {
+ *read_speed = GET16(&p[8]);
+ }
+ if (page_len > 18) {
+ *write_speed = GET16(&p[18]);
+ }
+ if (page_len < 28) {
+ printf("MMC-2\n");
+ return;
+ } else {
+ printf("MMC-3\n");
+ }
+
+ *write_speed = GET16(&p[28]);
+
+ if (page_len < 30) {
+ return;
+ }
+
+ /* retrieve speed list */
+ n = GET16(&p[30]);
+ n = min(n, (sizeof (p) - 32) / 4);
+
+ get_write_speeds(&p[32], n, speeds, n_speeds, speeds_mem);
+
+ if (*speeds != NULL) {
+ *write_speed = max(*write_speed, (*speeds)[0].val);
+ }
+}
+
+bool
+get_disc_info(int fd, disc_info_t *di)
+{
+ struct scsipi_read_discinfo discinfo;
+ uint8_t buf[32];
+ int bufsize = sizeof (buf);
+
+ bzero(buf, bufsize);
+ memset(&discinfo, 0, sizeof(discinfo));
+ discinfo.opcode = READ_DISCINFO;
+ discinfo.data_len[0] = (bufsize >> 8) & 0xff;
+ discinfo.data_len[1] = bufsize & 0xff;
+
+ if (scsi_command(fd, &discinfo, sizeof(discinfo), buf, bufsize, 10000, SCCMD_READ) == false)
+ return false;
+
+ di->disc_status = buf[2] & 0x03;
+ di->erasable = buf[2] & 0x10;
+ if ((buf[21] != 0) && (buf[21] != 0xff)) {
+ di->capacity = ((buf[21] * 60) + buf[22]) * 75;
+ } else {
+ di->capacity = 0;
+ }
+
+ return true;
+}
+
+/*
+ * returns current/maximum format capacity in bytes
+ */
+bool
+read_format_capacity(int fd, uint64_t *capacity)
+{
+ char cdb[12];
+ uint8_t buf[32];
+ int bufsize = sizeof (buf);
+ uint32_t num_blocks;
+ uint32_t block_len;
+
+ memset(buf, 0, bufsize);
+ memset(cdb, 0, sizeof(cdb));
+ cdb[0] = 0x23; /* READ FORMAT CAPACITIES */
+ cdb[7] = (bufsize >> 8) & 0xff; /* allocation length */
+ cdb[8] = bufsize & 0xff;
+
+ if (scsi_command(fd, &cdb, sizeof(cdb), buf, bufsize, 10000, SCCMD_READ) == false)
+ return false;
+
+ num_blocks = (uint32_t)(buf[4] << 24) + (buf[5] << 16) + (buf[6] << 8) + buf[7];
+ block_len = (uint32_t)(buf[9] << 16) + (buf[10] << 8) + buf[11];
+ *capacity = (uint64_t)num_blocks * block_len;
+
+ return (true);
+}
+
+bool
+get_media_info(int fd, uint64_t *capacity)
+{
+ struct disklabel d;
+ int ret;
+
+ ret = ioctl(fd, DIOCGDINFO, &d);
+ if (ret == -1)
+ return false;
+ *capacity = d.d_secsize * d.d_secperunit;
+ return true;
+}
+
+/*
+ * given current profile, use the best method for determining
+ * disc capacity (in bytes)
+ */
+bool
+get_disc_capacity_for_profile(int fd, int profile, uint64_t *capacity)
+{
+ disc_info_t di;
+ bool ret = false;
+
+ switch (profile) {
+ case 0x08: /* CD-ROM */
+ case 0x10: /* DVD-ROM */
+ if (get_media_info(fd, capacity))
+ ret = true;
+ break;
+ default:
+ if (read_format_capacity(fd, capacity) && (*capacity > 0)) {
+ ret = true;
+ } else if (get_disc_info(fd, &di) && (di.capacity > 0)) {
+ if (get_media_info(fd, capacity))
+ ret = true;
+ }
+ }
+
+ return (ret);
+}
+
+bool
+read_toc(int fd, int format, int trackno, int buflen, u_char *buf)
+{
+ struct scsipi_read_toc toc;
+
+ memset(buf, 0, buflen);
+ toc.opcode = READ_TOC;
+ toc.resp_format = format & 0xf;
+ toc.from_track = trackno;
+ toc.data_len[0] = (buflen >> 8) & 0xff;
+ toc.data_len[1] = buflen & 0xff;
+
+ return scsi_command(fd, &toc, sizeof(toc), buf, buflen, 10000, SCCMD_READ);
+}
diff --git a/hal/files/hald-netbsd/probing/cdutils.h b/hal/files/hald-netbsd/probing/cdutils.h
new file mode 100644
index 0000000000..f79a4a2bdd
--- /dev/null
+++ b/hal/files/hald-netbsd/probing/cdutils.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ *
+ * cdutils.h : definitions for CD/DVD utilities
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifndef CDUTILS_H
+#define CDUTILS_H
+
+#include <sys/types.h>
+#include <sys/dkio.h>
+#include <sys/cdio.h>
+#include <sys/scsiio.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+enum {
+ CDUTIL_WALK_CONTINUE,
+ CDUTIL_WALK_STOP
+};
+
+typedef struct intlist {
+ int val;
+ struct intlist *next;
+} intlist_t;
+
+typedef struct disc_info {
+ int disc_status;
+ int erasable;
+ uint64_t capacity;
+} disc_info_t;
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#define max(a, b) ((a) > (b) ? (a) : (b))
+
+bool scsi_command(int fd, void *cmd, size_t cmdlen, void *data,
+ size_t datalen, int timeout, int flags);
+int mode_sense(int fd, u_char pc, int dbd, int page_len,
+ u_char *buffer);
+int get_mode_page(int fd, int page_no, int pc, int buf_len,
+ u_char *buffer, int *plen);
+int get_configuration(int fd, uint16_t feature, int bufsize,
+ u_char *buf);
+bool get_current_profile(int fd, int *profile);
+void walk_profiles(int fd, int (*f)(void *, int, bool), void *);
+void get_read_write_speeds(int fd, int *read_speed, int *write_speed,
+ intlist_t **wspeeds, int *n_wspeeds, intlist_t **wspeeds_mem);
+bool get_disc_info(int fd, disc_info_t *);
+bool read_format_capacity(int fd, uint64_t *capacity);
+bool get_media_info(int fd, uint64_t *capacity);
+bool get_disc_capacity_for_profile(int fd, int profile,
+ uint64_t *capacity);
+bool read_toc(int fd, int format, int trackno, int buflen,
+ u_char *buf);
+
+#endif /* CDUTILS_H */
diff --git a/hal/files/hald-netbsd/probing/fsutils.c b/hal/files/hald-netbsd/probing/fsutils.c
new file mode 100644
index 0000000000..fa0a16c2a3
--- /dev/null
+++ b/hal/files/hald-netbsd/probing/fsutils.c
@@ -0,0 +1,217 @@
+/***************************************************************************
+ *
+ * fsutils.c : filesystem utilities
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/scsiio.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/dkio.h>
+#include <libintl.h>
+#include <sys/disklabel.h>
+#include <sys/bootblock.h>
+
+#include <libhal.h>
+#include "fsutils.h"
+
+/*
+ * Separates dos notation device spec into device and drive number
+ */
+bool
+dos_to_dev(char *path, char **devpath, int *num)
+{
+ char *p;
+
+ if ((p = strrchr(path, ':')) == NULL) {
+ return (false);
+ }
+ if ((*num = atoi(p + 1)) == 0) {
+ return (false);
+ }
+ p[0] = '\0';
+ *devpath = strdup(path);
+ p[0] = ':';
+ return (*devpath != NULL);
+}
+
+char *
+get_slice_name (char *devlink)
+{
+ char *part, *slice, *disk;
+ char *s = NULL;
+ char *p;
+
+ if ((p = strstr(devlink, "/lofi/")) != 0) {
+ return (p + sizeof ("/lofi/") - 1);
+ }
+
+ part = strrchr(devlink, 'p');
+ slice = strrchr(devlink, 's');
+ disk = strrchr(devlink, 'd');
+
+ if ((part != NULL) && (part > slice) && (part > disk)) {
+ s = part;
+ } else if ((slice != NULL) && (slice > disk)) {
+ s = slice;
+ } else {
+ s = disk;
+ }
+ if ((s != NULL) && isdigit(s[1])) {
+ return (s);
+ } else {
+ return ("");
+ }
+}
+
+bool
+is_dos_drive(u_char type)
+{
+ return ((type == 1) || (type == 4) || (type == 5) || (type == 6) ||
+ ((type >= 8) && (type <= 0xf)));
+}
+
+bool
+is_dos_extended(u_char id)
+{
+ return MBR_IS_EXTENDED(id);
+}
+
+struct part_find_s {
+ int num;
+ int count;
+ int systid;
+ int r_systid;
+ int r_relsect;
+ int r_numsect;
+};
+
+enum { WALK_CONTINUE, WALK_TERMINATE };
+
+/*
+ * Walk partition tables and invoke a callback for each.
+ */
+static void
+walk_partitions(int fd, int startsec, int (*f)(void *, int, int, int),
+ void *arg)
+{
+ uint32_t buf[1024/4];
+ int bufsize = 1024;
+ struct mbr_sector *msect = (struct mbr_sector *)&buf[0];
+ struct mbr_partition mpart[MBR_PART_COUNT];
+ int sec = startsec;
+ int lastsec = sec + 1;
+ int relsect;
+ int ext = 0;
+ int systid;
+ bool valid;
+ int i;
+
+ while (sec != lastsec) {
+ if (pread(fd, buf, bufsize, (off_t)sec * 512) != bufsize) {
+ break;
+ }
+ lastsec = sec;
+ if (le16toh(msect->mbr_magic) != MBR_MAGIC) {
+ break;
+ }
+ memcpy(mpart, msect->mbr_parts, MBR_PART_COUNT * sizeof (struct mbr_partition));
+
+ for (i = 0; i < MBR_PART_COUNT; i++) {
+ systid = mpart[i].mbrp_type;
+ relsect = sec + le32toh(mpart[i].mbrp_start);
+ if (systid == 0) {
+ continue;
+ }
+ valid = true;
+ if (is_dos_extended(systid) && (sec == lastsec)) {
+ sec = startsec + le32toh(mpart[i].mbrp_start);
+ if (ext++ == 0) {
+ relsect = startsec = sec;
+ } else {
+ valid = false;
+ }
+ }
+ if (valid && f(arg, mpart[i].mbrp_type, relsect,
+ le32toh(mpart[i].mbrp_size)) == WALK_TERMINATE) {
+ return;
+ }
+ }
+ }
+}
+
+static int
+find_dos_drive_cb(void *arg, int systid, int relsect, int numsect)
+{
+ struct part_find_s *p = arg;
+
+ if (is_dos_drive(systid)) {
+ if (++p->count == p->num) {
+ p->r_relsect = relsect;
+ p->r_numsect = numsect;
+ p->r_systid = systid;
+ return (WALK_TERMINATE);
+ }
+ }
+
+ return (WALK_CONTINUE);
+}
+
+/*
+ * Given a dos drive number, return its relative sector number,
+ * number of sectors in partition and the system id.
+ */
+bool
+find_dos_drive(int fd, int num, int *relsect, int *numsect, int *systid)
+{
+ struct part_find_s p = { 0, 0, 0, 0, 0, 0 };
+
+ p.num = num;
+
+ if (num > 0) {
+ walk_partitions(fd, 0, find_dos_drive_cb, &p);
+ if (p.count == num) {
+ *relsect = p.r_relsect;
+ *numsect = p.r_numsect;
+ *systid = p.r_systid;
+ return (true);
+ }
+ }
+
+ return (false);
+}
+
+static int
+get_num_dos_drives_cb(void *arg, int systid, int relsect, int numsect)
+{
+ if (is_dos_drive(systid)) {
+ (*(int *)arg)++;
+ }
+ return (WALK_CONTINUE);
+}
+
+int
+get_num_dos_drives(int fd)
+{
+ int count = 0;
+
+ walk_partitions(fd, 0, get_num_dos_drives_cb, &count);
+
+ return (count);
+}
diff --git a/hal/files/hald-netbsd/probing/fsutils.h b/hal/files/hald-netbsd/probing/fsutils.h
new file mode 100644
index 0000000000..8f4558d7d6
--- /dev/null
+++ b/hal/files/hald-netbsd/probing/fsutils.h
@@ -0,0 +1,25 @@
+/***************************************************************************
+ *
+ * fsutils.h : definitions for filesystem utilities
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifndef FSUTILS_H
+#define FSUTILS_H
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+bool dos_to_dev(char *path, char **devpath, int *num);
+char *get_slice_name (char *devlink);
+bool is_dos_drive(u_char id);
+bool is_dos_extended(u_char id);
+bool find_dos_drive(int fd, int num, int *relsect, int *numsect, int *systid);
+
+#endif /* FSUTILS_H */
diff --git a/hal/files/hald-netbsd/probing/probe-storage.c b/hal/files/hald-netbsd/probing/probe-storage.c
new file mode 100644
index 0000000000..ac03ec25f7
--- /dev/null
+++ b/hal/files/hald-netbsd/probing/probe-storage.c
@@ -0,0 +1,414 @@
+/***************************************************************************
+ *
+ * probe-storage.c : Probe for storage devices
+ *
+ * Copyright 2008 Jared D. McNeill <jmcneill%NetBSD.org@localhost>
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/fdio.h>
+#include <sys/statvfs.h>
+#include <sys/syslog.h>
+
+#include <sys/scsiio.h>
+#include <dev/scsipi/scsi_spc.h>
+#include <dev/scsipi/scsipi_all.h>
+
+#include <libhal.h>
+#include <cdutils.h>
+#include <fsutils.h>
+#include <logger.h>
+
+#if notyet
+/** Check if a filesystem on a special device file is mounted
+ *
+ * @param device_file Special device file, e.g. /dev/cd0a
+ * @return TRUE iff there is a filesystem system mounted
+ * on the special device file
+ */
+static dbus_bool_t
+is_mounted (const char *device_file)
+{
+ int count;
+ struct statvfs *statvfs;
+
+ count = getmntinfo(&statvfs, ST_WAIT);
+ while (count-- > 0) {
+ if (strcmp(statvfs->f_mntfromname, device_file) == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+#endif
+
+static int
+get_cdrom_properties_walker (void *arg, int profile, bool is_current)
+{
+ LibHalChangeSet *cs = (LibHalChangeSet *)arg;
+
+ switch (profile) {
+ case 0x09:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.cdr", TRUE);
+ break;
+ case 0x0a:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.cdrw", TRUE);
+ break;
+ case 0x10:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvd", TRUE);
+ break;
+ case 0x11:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdr", TRUE);
+ break;
+ case 0x12:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdram", TRUE);
+ break;
+ case 0x13:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", TRUE);
+ break;
+ case 0x14:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", TRUE);
+ break;
+ case 0x1a:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrw", TRUE);
+ break;
+ case 0x1b:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusr", TRUE);
+ break;
+ case 0x2b:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrdl", TRUE);
+ break;
+ case 0x40:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bd", TRUE);
+ break;
+ case 0x41:
+ case 0x42:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bdr", TRUE);
+ break;
+ case 0x43:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bdre", TRUE);
+ break;
+ case 0x50:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvd", TRUE);
+ break;
+ case 0x51:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdr", TRUE);
+ break;
+ case 0x52:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdrw", TRUE);
+ break;
+ }
+
+ return CDUTIL_WALK_CONTINUE;
+}
+
+#define WSPLEN 64
+
+static void
+get_cdrom_properties (int fd, LibHalChangeSet *cs)
+{
+ int read_speed, write_speed;
+ intlist_t *write_speeds, *write_speeds_mem, *sp;
+ int n_wspeeds;
+ char **wspeeds;
+ char *wspeeds_mem;
+ int i;
+
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.cdr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.cdrw", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvd", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdram", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrw", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrdl", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bd", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bdr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bdre", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvd", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdrw", FALSE);
+
+ walk_profiles(fd, get_cdrom_properties_walker, cs);
+
+ /* XXX */
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.support_media_changed", TRUE);
+
+ get_read_write_speeds(fd, &read_speed, &write_speed, &write_speeds, &n_wspeeds, &write_speeds_mem);
+
+ libhal_changeset_set_property_int (cs, "storage.cdrom.read_speed", read_speed);
+ libhal_changeset_set_property_int (cs, "storage.cdrom.write_speed", write_speed);
+
+ if (n_wspeeds <= 0) {
+ wspeeds_mem = NULL;
+ libhal_changeset_set_property_strlist (cs, "storage.cdrom.write_speeds", (const char **)&wspeeds_mem);
+ return;
+ }
+ if ((wspeeds = (char **)calloc(n_wspeeds + 1, sizeof (char *))) == NULL) {
+ free (write_speeds_mem);
+ return;
+ }
+ if ((wspeeds_mem = (char *)calloc(n_wspeeds, WSPLEN)) == NULL) {
+ free (wspeeds);
+ free (write_speeds_mem);
+ return;
+ }
+ for (i = 0; i < n_wspeeds; i++) {
+ wspeeds[i] = &wspeeds_mem[i * WSPLEN];
+ }
+
+ for (sp = write_speeds, i = 0; sp != NULL; sp = sp->next, i++) {
+ snprintf (wspeeds[i], WSPLEN, "%d", sp->val);
+ }
+ libhal_changeset_set_property_strlist (cs, "storage.cdrom.write_speeds", (const char **)wspeeds);
+
+ free (wspeeds);
+ free (wspeeds_mem);
+ free (write_speeds_mem);
+}
+
+/*
+ * Return a copy of a string without trailing spaces. If 'len' is non-zero,
+ * it specifies max length, otherwise the string must be null-terminated.
+ */
+static char *
+rtrim_copy(char *src, int len)
+{
+ char *dst, *p;
+
+ if (len == 0) {
+ len = strlen(src);
+ }
+ if ((dst = calloc(1, len + 1)) != NULL) {
+ strncpy(dst, src, len);
+ p = dst + len - 1;
+ while ((p >= dst) && (isspace((int)*p))) {
+ *p-- = '\0';
+ }
+ }
+ return (dst);
+}
+
+static void
+get_disk_properties (int fd, LibHalChangeSet *cs)
+{
+ struct scsipi_inquiry_data inqbuf;
+ struct scsipi_inquiry cmd;
+ dbus_bool_t status;
+ char *s;
+
+ /* INQUIRY */
+ memset(&cmd, 0, sizeof(cmd));
+ memset(&inqbuf, 0, sizeof(inqbuf));
+ cmd.opcode = INQUIRY;
+ cmd.length = sizeof(inqbuf);
+ status = scsi_command(fd, &cmd, sizeof(cmd), &inqbuf, sizeof(inqbuf), 10000, SCCMD_READ);
+ if (status == false)
+ return;
+
+ if ((s = rtrim_copy(inqbuf.vendor, sizeof (inqbuf.vendor))) != NULL) {
+ libhal_changeset_set_property_string (cs, "storage.vendor", s);
+ free(s);
+ }
+ if ((s = rtrim_copy(inqbuf.product, sizeof (inqbuf.product))) != NULL) {
+ libhal_changeset_set_property_string (cs, "storage.model", s);
+ free(s);
+ }
+ if ((s = rtrim_copy(inqbuf.revision, sizeof (inqbuf.revision))) != NULL) {
+ libhal_changeset_set_property_string (cs, "storage.firmware_revision", s);
+ free(s);
+ }
+ if ((s = rtrim_copy((char *)inqbuf.vendor_specific, sizeof (inqbuf.vendor_specific))) != NULL) {
+ libhal_changeset_set_property_string (cs, "storage.serial", s);
+ free(s);
+ }
+}
+
+#if notyet
+/*
+ * returns TRUE if diskette is inserted.
+ * also returns write protection status.
+ */
+static dbus_bool_t
+check_floppy(int fd, dbus_bool_t *wprot)
+{
+ int chg;
+
+ if ((ioctl(fd, FDGETCHANGE, &chg) == 0) && !(chg & FDGC_CURRENT)) {
+ *wprot = ((chg & FDGC_CURWPROT) != NULL);
+ return (TRUE);
+ } else {
+ return (FALSE);
+ }
+}
+#endif
+
+int
+main (int argc, char *argv[])
+{
+ int ret = 1;
+ int fd = -1;
+ int rfd = -1;
+ char *udi;
+ char *device_file;
+ char *raw_device_file;
+ LibHalContext *ctx = NULL;
+ DBusError error;
+ char *bus;
+ char *drive_type;
+ dbus_bool_t is_cdrom;
+ dbus_bool_t is_floppy;
+ dbus_bool_t only_check_for_media;
+ int got_media = FALSE;
+ dbus_bool_t is_write_protected = FALSE;
+ dbus_bool_t is_mbr = FALSE;
+ dbus_bool_t is_smi = FALSE;
+ dbus_bool_t is_gpt = FALSE;
+ dbus_bool_t is_partitioned = FALSE;
+ int dos_cnt = 0;
+ const char *scheme = "";
+ LibHalChangeSet *cs = NULL;
+
+ HAL_INFO(("f0"));
+ if ((udi = getenv ("UDI")) == NULL)
+ goto out;
+ HAL_INFO(("f0-1"));
+ if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL)
+ goto out;
+ HAL_INFO(("f0-2"));
+ if ((raw_device_file = getenv ("HAL_PROP_BLOCK_NETBSD_RAW_DEVICE")) == NULL)
+ goto out;
+ HAL_INFO(("f0-3"));
+ if ((bus = getenv ("HAL_PROP_STORAGE_BUS")) == NULL)
+ goto out;
+ HAL_INFO(("f0-4"));
+ if ((drive_type = getenv ("HAL_PROP_STORAGE_DRIVE_TYPE")) == NULL)
+ goto out;
+
+ HAL_INFO(("f1"));
+ setup_logger ();
+
+ if (argc == 2 && strcmp (argv[1], "--only-check-for-media") == 0)
+ only_check_for_media = TRUE;
+ else
+ only_check_for_media = FALSE;
+
+ is_cdrom = (strcmp (drive_type, "cdrom") == 0);
+ is_floppy = (strcmp (drive_type, "floppy") == 0);
+
+ HAL_INFO(("f2"));
+ dbus_error_init (&error);
+ HAL_INFO(("f3"));
+ if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
+ goto out;
+
+ HAL_INFO(("f4"));
+ if ((cs = libhal_device_new_changeset (udi)) == NULL) {
+ HAL_DEBUG (("Cannot allocate changeset"));
+ goto out;
+ }
+ HAL_INFO(("f5"));
+
+ HAL_DEBUG (("Doing probe-storage for %s (bus %s) (drive_type %s) (udi=%s) (--only-check-for-media==%d)",
+ device_file, bus, drive_type, udi, only_check_for_media));
+
+ if ((rfd = open (raw_device_file, O_RDONLY | O_NONBLOCK)) < 0) {
+ HAL_DEBUG (("Cannot open %s: %s", raw_device_file, strerror (errno)));
+ goto out;
+ }
+
+ if (!only_check_for_media) {
+ if (strcmp (drive_type, "cdrom") == 0) {
+ get_cdrom_properties (rfd, cs);
+ } else if (strcmp (drive_type, "disk") == 0) {
+ get_disk_properties (rfd, cs);
+ }
+ }
+
+ ret = 0;
+
+ if (is_cdrom) {
+ uint64_t capacity;
+
+ HAL_DEBUG (("Checking for optical disc on %s", raw_device_file));
+ got_media = get_media_info(rfd, &capacity);
+ if (!got_media) {
+ goto out_cs;
+ }
+ /* XXX */
+ is_write_protected = TRUE;
+ } else if (is_floppy) {
+#if 0
+ HAL_DEBUG (("Checking for floppy on %s", raw_device_file));
+ if (check_floppy(rfd, &is_write_protected)) {
+ got_media = TRUE;
+ }
+#endif
+ /* don't look for partitions on floppy */
+ goto out_cs;
+ } else {
+ got_media = TRUE;
+ }
+
+ HAL_DEBUG (("Checking for partitions on %s", device_file));
+
+ if ((fd = open (device_file, O_RDONLY | O_NONBLOCK)) < 0) {
+ HAL_DEBUG (("Cannot open %s: %s", device_file, strerror (errno)));
+ goto out_cs;
+ }
+
+ scheme = "mbr";
+ dos_cnt = 1;
+
+out_cs:
+ is_partitioned = is_mbr || is_smi || is_gpt;
+ libhal_changeset_set_property_bool (cs, "storage.no_partitions_hint", !is_partitioned);
+ libhal_changeset_set_property_bool (cs, "block.no_partitions", !is_partitioned);
+ libhal_changeset_set_property_string (cs, "storage.partitioning_scheme", scheme);
+ libhal_changeset_set_property_int (cs, "storage.netbsd.num_dos_partitions", dos_cnt);
+ /* XXX should only set for removable drives */
+ libhal_changeset_set_property_bool (cs, "storage.removable.media_available", got_media);
+ libhal_changeset_set_property_bool (cs, "storage.removable.netbsd.read_only", is_write_protected);
+
+ libhal_device_commit_changeset (ctx, cs, &error);
+
+out:
+ if (cs != NULL) {
+ libhal_device_free_changeset (cs);
+ }
+ if (fd >= 0) {
+ close (fd);
+ }
+ if (rfd >= 0) {
+ close (rfd);
+ }
+ if (ctx != NULL) {
+ if (dbus_error_is_set(&error)) {
+ dbus_error_free (&error);
+ }
+ libhal_ctx_shutdown (ctx, &error);
+ libhal_ctx_free (ctx);
+ }
+
+ return ret;
+}
diff --git a/hal/files/hald-netbsd/probing/probe-volume.c b/hal/files/hald-netbsd/probing/probe-volume.c
new file mode 100644
index 0000000000..9b9c66a19d
--- /dev/null
+++ b/hal/files/hald-netbsd/probing/probe-volume.c
@@ -0,0 +1,629 @@
+/***************************************************************************
+ *
+ * probe-volume.c : probe volumes
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/dkio.h>
+#include <sys/cdio.h>
+#include <sys/fdio.h>
+#include <sys/disklabel.h>
+#include <isofs/cd9660/iso.h>
+
+#include <libhal.h>
+#include <cdutils.h>
+#include <fsutils.h>
+#include <logger.h>
+
+static void
+my_dbus_error_free(DBusError *error)
+{
+ if (dbus_error_is_set(error)) {
+ dbus_error_free(error);
+ }
+}
+
+/*
+ * Return a copy of a string without trailing spaces. If 'len' is non-zero,
+ * it specifies max length, otherwise the string must be null-terminated.
+ */
+static char *
+rtrim_copy(char *src, int len)
+{
+ char *dst, *p;
+
+ if (len == 0) {
+ len = strlen(src);
+ }
+ if ((dst = calloc(1, len + 1)) != NULL) {
+ strncpy(dst, src, len);
+ p = dst + len - 1;
+ while ((p >= dst) && (isspace(*p))) {
+ *p-- = '\0';
+ }
+ }
+ return (dst);
+}
+
+static void
+set_fstyp_properties (LibHalContext *ctx, const char *udi, const char *fstype)
+{
+ char buf[256];
+ DBusError error;
+ char *uuid = NULL;
+ char *label_orig = NULL;
+ char *label = NULL;
+ LibHalChangeSet *cs;
+
+ dbus_error_init (&error);
+
+ if ((cs = libhal_device_new_changeset (udi)) == NULL) {
+ return;
+ }
+
+ libhal_changeset_set_property_string (cs, "volume.fsusage", "filesystem");
+ libhal_changeset_set_property_string (cs, "volume.fstype", fstype);
+
+#if notyet
+ /* label */
+ (void) nvlist_lookup_string(fsattr, "gen_volume_label", &label_orig);
+#endif
+ if (label_orig != NULL) {
+ label = rtrim_copy(label_orig, 0);
+ }
+ if ((label != NULL) && (label[0] != '\0')) {
+ libhal_changeset_set_property_string (cs, "volume.label", label);
+ libhal_changeset_set_property_string (cs, "info.product", label);
+ } else {
+ libhal_changeset_set_property_string (cs, "volume.label", "");
+ snprintf (buf, sizeof (buf), "Volume (%s)", fstype);
+ libhal_changeset_set_property_string (cs, "info.product", buf);
+ }
+ if (label)
+ free(label);
+
+#if notyet
+ /* uuid */
+ if (nvlist_lookup_string(fsattr, "gen_uuid", &uuid) == 0) {
+ libhal_changeset_set_property_string (cs, "volume.uuid", uuid);
+ } else {
+ libhal_changeset_set_property_string (cs, "volume.uuid", "");
+ }
+#else
+ libhal_changeset_set_property_string (cs, "volume.uuid", "");
+#endif
+
+ libhal_device_commit_changeset (ctx, cs, &error);
+ libhal_device_free_changeset (cs);
+
+ my_dbus_error_free (&error);
+}
+
+#define ISO_VOLDESC_SEC 16
+#define IPE_FPESIZE 8
+#define IDE_MAX_NAME_LEN (255 - ISO_DIRECTORY_RECORD_SIZE)
+
+/*
+ * isofs/cd9660 contents detection: Video DVD, Video CD, etc.
+ */
+static void
+isofs_contents(int fd, off_t probe_offset, LibHalContext *ctx, const char *udi)
+{
+ size_t secsz = sizeof(struct iso_primary_descriptor);
+ struct iso_primary_descriptor ipdesc;
+ uint8_t buf[sizeof(struct iso_volume_descriptor)];
+ int ptbl_lbn, ptbl_size;
+ int off, reloff, readoff;
+ char *name;
+ int name_len;
+ int ipe_len;
+ DBusError error;
+
+ /*
+ * find 1st Primary Volume Descriptor
+ */
+ readoff = probe_offset + ISO_VOLDESC_SEC * secsz;
+ if (pread (fd, &ipdesc, secsz, readoff) != secsz) {
+ return;
+ }
+ while (isonum_711 (ipdesc.type) != ISO_VD_PRIMARY) {
+ if (isonum_711 (ipdesc.type) == ISO_VD_END) {
+ return;
+ }
+ readoff += secsz;
+ if (pread (fd, buf, secsz, readoff) != secsz) {
+ return;
+ }
+ }
+
+ /*
+ * PVD contains size and offset of the LSB/MSB path table
+ */
+ ptbl_size = isonum_733 (ipdesc.path_table_size);
+ ptbl_lbn = isonum_732 (ipdesc.type_m_path_table);
+
+ /*
+ * Look through path table entries
+ */
+ readoff = probe_offset + ptbl_lbn * secsz;
+ if (pread (fd, buf, secsz, readoff) != secsz) {
+ return;
+ }
+ dbus_error_init (&error);
+
+ for (off = reloff = 0;
+ off < ptbl_size;
+ off += ipe_len, reloff += ipe_len) {
+ uint8_t *p;
+
+ /* load sectors on demand */
+ if (reloff >= secsz) {
+ readoff += secsz;
+ if (pread (fd, buf, secsz, readoff) != secsz) {
+ break;
+ }
+ reloff -= secsz;
+ }
+
+ p = buf + reloff;
+ name_len = isonum_711 (p[0]);
+ ipe_len = IPE_FPESIZE + name_len + (name_len % 2);
+
+ /* only interested in root directories */
+ if (isonum_711 (p[6]) != 1) {
+ continue;
+ }
+ if ((name_len < 2) || (name_len > IDE_MAX_NAME_LEN)) {
+ continue;
+ }
+
+ name = (char *)&p[8];
+ if (strncasecmp (name, "VIDEO_TS", min (8, name_len)) == 0) {
+ libhal_device_set_property_bool (ctx, udi,
+ "volume.disc.is_videodvd", TRUE, &error);
+ } else if (strncasecmp (name, "VCD", min (3, name_len)) == 0) {
+ libhal_device_set_property_bool (ctx, udi,
+ "volume.disc.is_vcd", TRUE, &error);
+ } else if (strncasecmp (name, "SVCD", min (4, name_len)) == 0) {
+ libhal_device_set_property_bool (ctx, udi,
+ "volume.disc.is_svcd", TRUE, &error);
+ }
+ }
+
+ my_dbus_error_free (&error);
+}
+
+static dbus_bool_t
+probe_disc (int fd, LibHalContext *ctx, const char *udi, dbus_bool_t *should_probe_for_fs)
+{
+ DBusError error;
+ disc_info_t di;
+ int profile;
+ dbus_bool_t has_audio, has_data, is_blank, is_appendable, is_rewritable;
+ char *disc_type = "cd_rom";
+ uint64_t capacity = 0;
+ int i;
+ LibHalChangeSet *cs;
+
+ dbus_error_init (&error);
+
+ if (get_disc_info (fd, &di)) {
+ is_blank = (di.disc_status == 0);
+ is_appendable = (di.disc_status == 1);
+ is_rewritable = (di.erasable != 0);
+ } else {
+ is_blank = is_appendable = is_rewritable = FALSE;
+ }
+
+ if (get_current_profile (fd, &profile)) {
+ switch (profile) {
+ case 0x08: /* CD-ROM */
+ disc_type = "cd_rom";
+ break;
+ case 0x09: /* CD-R */
+ disc_type = "cd_r";
+ break;
+ case 0x0A: /* CD-RW */
+ disc_type = "cd_rw";
+ is_rewritable = TRUE;
+ break;
+ case 0x10: /* DVD-ROM */
+ disc_type = "dvd_rom";
+ break;
+ case 0x11: /* DVD-R Sequential */
+ disc_type = "dvd_r";
+ break;
+ case 0x12: /* DVD-RAM */
+ disc_type = "dvd_ram";
+ is_rewritable = TRUE;
+ break;
+ case 0x13: /* DVD-RW Restricted Overwrite */
+ disc_type = "dvd_rw";
+ is_rewritable = TRUE;
+ break;
+ case 0x14: /* DVD-RW Sequential */
+ disc_type = "dvd_rw";
+ is_rewritable = TRUE;
+ break;
+ case 0x1A: /* DVD+RW */
+ disc_type = "dvd_plus_rw";
+ is_rewritable = TRUE;
+ break;
+ case 0x1B: /* DVD+R */
+ disc_type = "dvd_plus_r";
+ break;
+ case 0x2B: /* DVD+R Double Layer */
+ disc_type = "dvd_plus_r_dl";
+ break;
+ case 0x40: /* BD-ROM */
+ disc_type = "bd_rom";
+ break;
+ case 0x41: /* BD-R Sequential */
+ case 0x42: /* BD-R Random */
+ disc_type = "bd_r";
+ break;
+ case 0x43: /* BD-RE */
+ disc_type = "bd_re";
+ is_rewritable = TRUE;
+ break;
+ case 0x50: /* HD DVD-ROM */
+ disc_type = "hddvd_rom";
+ break;
+ case 0x51: /* HD DVD-R */
+ disc_type = "hddvd_r";
+ break;
+ case 0x52: /* HD DVD-Rewritable */
+ disc_type = "hddvd_rw";
+ is_rewritable = TRUE;
+ break;
+ }
+
+ (void) get_disc_capacity_for_profile(fd, profile, &capacity);
+ }
+
+ has_audio = has_data = FALSE;
+ if (!is_blank) {
+ u_char smalltoc[12];
+ size_t toc_size;
+ u_char *toc, *p;
+
+ /*
+ * XXX for some reason CDROMREADTOCENTRY fails on video DVDs,
+ * but extracting the toc directly works okay.
+ */
+ if (!read_toc(fd, 0, 1, 4, smalltoc)) {
+ HAL_DEBUG(("read_toc failed"));
+ has_data = TRUE; /* probe for fs anyway */
+ } else {
+ toc_size = smalltoc[0] * 256 + smalltoc[1] + 2;
+ toc = (u_char *)calloc(1, toc_size);
+ if (toc == NULL || !read_toc(fd, 0, 1, toc_size, toc)) {
+ HAL_DEBUG (("read_toc again failed"));
+ } else {
+ for (p = &toc[4]; p < (toc + toc_size); p += 8) {
+ /* skip leadout */
+ if (p[2] == 0xAA) {
+ continue;
+ }
+ if (p[1] & 4) {
+ has_data = TRUE;
+ } else {
+ has_audio = TRUE;
+ }
+ }
+ }
+ free(toc);
+ }
+ }
+
+ if ((cs = libhal_device_new_changeset (udi)) == NULL) {
+ return (FALSE);
+ }
+ libhal_changeset_set_property_string (cs, "volume.disc.type", disc_type);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_blank", is_blank);
+ libhal_changeset_set_property_bool (cs, "volume.disc.has_audio", has_audio);
+ libhal_changeset_set_property_bool (cs, "volume.disc.has_data", has_data);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_appendable", is_appendable);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", is_rewritable);
+ libhal_changeset_set_property_uint64 (cs, "volume.disc.capacity", capacity);
+
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_videodvd", FALSE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_vcd", FALSE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_svcd", FALSE);
+
+ libhal_device_commit_changeset (ctx, cs, &error);
+ libhal_device_free_changeset (cs);
+
+out:
+
+ *should_probe_for_fs = has_data;
+
+ my_dbus_error_free (&error);
+
+ return (TRUE);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int fd, rfd;
+ int ret;
+ char *udi;
+ char *device_file, *raw_device_file;
+ char *devpath, *rdevpath;
+ bool is_dos;
+ int dos_num;
+ LibHalContext *ctx = NULL;
+ DBusError error;
+ DBusConnection *conn;
+ char *parent_udi;
+ char *storage_device;
+ char *is_disc_str;
+ int fdc;
+ dbus_bool_t is_disc = FALSE;
+ dbus_bool_t is_floppy = FALSE;
+ unsigned int block_size;
+ dbus_uint64_t vol_size;
+ dbus_bool_t should_probe_for_fs;
+ char *partition_scheme = NULL;
+ struct disklabel d;
+ dbus_uint64_t partition_start = 0;
+ int partition_number = 0;
+ int i, dos_cnt;
+ int systid, relsect, numsect;
+ off_t probe_offset = 0;
+ int num_volumes;
+ char **volumes;
+ dbus_uint64_t v_start;
+ const char *fstype;
+
+ fd = rfd = -1;
+
+ ret = 1;
+
+ if ((udi = getenv ("UDI")) == NULL) {
+ goto out;
+ }
+ if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL) {
+ goto out;
+ }
+ if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL) {
+ goto out;
+ }
+ if (!dos_to_dev(device_file, &rdevpath, &dos_num)) {
+ rdevpath = raw_device_file;
+ }
+ if (!(is_dos = dos_to_dev(device_file, &devpath, &dos_num))) {
+ devpath = device_file;
+ }
+ if ((parent_udi = getenv ("HAL_PROP_INFO_PARENT")) == NULL) {
+ goto out;
+ }
+ if ((storage_device = getenv ("HAL_PROP_BLOCK_STORAGE_DEVICE")) == NULL) {
+ goto out;
+ }
+
+ is_disc_str = getenv ("HAL_PROP_VOLUME_IS_DISC");
+ if (is_disc_str != NULL && strcmp (is_disc_str, "true") == 0) {
+ is_disc = TRUE;
+ } else {
+ is_disc = FALSE;
+ }
+
+ setup_logger ();
+
+ dbus_error_init (&error);
+ if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
+ goto out;
+
+ HAL_DEBUG (("Doing probe-volume for %s\n", device_file));
+
+ fd = open (devpath, O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ goto out;
+ }
+ rfd = open (rdevpath, O_RDONLY | O_NONBLOCK);
+ if (rfd < 0) {
+ goto out;
+ }
+
+#if notyet
+ /* if it's a floppy with no media, bail out */
+ if (ioctl(rfd, FDGETCHANGE, &fdc) == 0) {
+ is_floppy = TRUE;
+ if (fdc & FDGC_CURRENT) {
+ goto out;
+ }
+ }
+#endif
+
+ /* block size and total size */
+ if (ioctl(rfd, DIOCGDINFO, &d) != -1) {
+ block_size = d.d_secsize;
+ vol_size = d.d_secsize * d.d_secperunit;
+ } else {
+ block_size = 512;
+ vol_size = 0;
+ }
+ libhal_device_set_property_int (ctx, udi, "volume.block_size", block_size, &error);
+ my_dbus_error_free (&error);
+ libhal_device_set_property_uint64 (ctx, udi, "volume.size", vol_size, &error);
+ my_dbus_error_free (&error);
+
+ should_probe_for_fs = TRUE;
+
+ if (is_disc) {
+ if (!probe_disc (rfd, ctx, udi, &should_probe_for_fs)) {
+ HAL_DEBUG (("probe_disc failed, skipping fstyp"));
+ goto out;
+ }
+ /* XXX vol_probe_offset for multisession discs? */
+ }
+
+ if (!should_probe_for_fs) {
+ goto skip_fs;
+ }
+
+ /* don't support partitioned floppy */
+ if (is_floppy) {
+ goto skip_part;
+ }
+
+ /*
+ * first get partitioning info
+ */
+ if (is_dos) {
+ /* for a dos drive find partition offset */
+ if (!find_dos_drive(fd, dos_num, &relsect, &numsect, &systid)) {
+ goto out;
+ }
+ partition_scheme = "mbr";
+ partition_start = (dbus_uint64_t)relsect * 512;
+ partition_number = dos_num;
+ probe_offset = (off_t)relsect * 512;
+ } else {
+#if notyet
+ if ((partition_number = read_vtoc(rfd, &vtoc)) >= 0) {
+ if (!vtoc_one_slice_entire_disk(&vtoc)) {
+ partition_scheme = "smi";
+ if (partition_number < vtoc.v_nparts) {
+ if (vtoc.v_part[partition_number].p_size == 0) {
+ HAL_DEBUG (("zero size partition"));
+ }
+ partition_start = vtoc.v_part[partition_number].p_start * block_size;
+ }
+ }
+ } else if ((partition_number = efi_alloc_and_read(rfd, &gpt)) >= 0) {
+ partition_scheme = "gpt";
+ if (partition_number < gpt->efi_nparts) {
+ if (gpt->efi_parts[partition_number].p_size == 0) {
+ HAL_DEBUG (("zero size partition"));
+ }
+ partition_start = gpt->efi_parts[partition_number].p_start * block_size;
+ }
+ efi_free(gpt);
+ }
+#endif
+ probe_offset = 0;
+ }
+
+ if (partition_scheme != NULL) {
+ libhal_device_set_property_string (ctx, udi, "volume.partition.scheme", partition_scheme, &error);
+ my_dbus_error_free (&error);
+ libhal_device_set_property_int (ctx, udi, "volume.partition.number", partition_number, &error);
+ my_dbus_error_free (&error);
+ libhal_device_set_property_uint64 (ctx, udi, "volume.partition.start", partition_start, &error);
+ my_dbus_error_free (&error);
+ libhal_device_set_property_bool (ctx, udi, "volume.is_partition", TRUE, &error);
+ my_dbus_error_free (&error);
+ } else {
+ libhal_device_set_property_bool (ctx, udi, "volume.is_partition", FALSE, &error);
+ my_dbus_error_free (&error);
+ }
+
+ /*
+ * ignore duplicate partitions
+ */
+ if ((volumes = libhal_manager_find_device_string_match (
+ ctx, "block.storage_device", storage_device, &num_volumes, &error)) != NULL) {
+ my_dbus_error_free (&error);
+ for (i = 0; i < num_volumes; i++) {
+ if (strcmp (udi, volumes[i]) == 0) {
+ continue; /* skip self */
+ }
+ v_start = libhal_device_get_property_uint64 (ctx, volumes[i], "volume.partition.start", &error);
+ if (dbus_error_is_set(&error)) {
+ dbus_error_free(&error);
+ continue;
+ }
+ if (v_start == partition_start) {
+ HAL_DEBUG (("duplicate partition"));
+ goto out;
+ }
+ }
+ libhal_free_string_array (volumes);
+ }
+
+skip_part:
+
+#if notyet
+ /*
+ * now determine fs type
+ */
+ if (fstyp_init(fd, probe_offset, NULL, &fstyp_handle) != 0) {
+ HAL_DEBUG (("fstyp_init failed"));
+ goto out;
+ }
+ if ((fstyp_ident(fstyp_handle, NULL, &fstype) != 0) ||
+ (fstyp_get_attr(fstyp_handle, &fsattr) != 0)) {
+ HAL_DEBUG (("fstyp ident or get_attr failed"));
+
+ /*
+ * XXX fstyp_udfs has a bug that it only works on raw,
+ * but we don't want to slow down the fast path above.
+ * Try raw for just udfs here until the bug is fixed.
+ */
+ HAL_DEBUG (("trying udfs workaround"));
+ fstyp_fini(fstyp_handle);
+ if (fstyp_init(rfd, probe_offset, NULL, &fstyp_handle) != 0) {
+ goto out;
+ }
+ if ((fstyp_ident(fstyp_handle, "udfs", &fstype) != 0) ||
+ (fstyp_get_attr(fstyp_handle, &fsattr) != 0)) {
+ fstyp_fini(fstyp_handle);
+ goto out;
+ }
+ }
+#else
+ fstype = "cd9660";
+#endif
+ set_fstyp_properties (ctx, udi, fstype);
+
+ if (strcmp (fstype, "cd9660") == 0) {
+ isofs_contents (fd, probe_offset, ctx, udi);
+ }
+
+#if notyet
+ fstyp_fini(fstyp_handle);
+#endif
+
+skip_fs:
+
+ ret = 0;
+
+out:
+ if (fd >= 0)
+ close (fd);
+ if (rfd >= 0)
+ close (rfd);
+
+ if (ctx != NULL) {
+ my_dbus_error_free (&error);
+ libhal_ctx_shutdown (ctx, &error);
+ libhal_ctx_free (ctx);
+ }
+
+ return ret;
+
+}
diff --git a/hal/files/hald-netbsd/vfsstat.c b/hal/files/hald-netbsd/vfsstat.c
new file mode 100644
index 0000000000..9a09c0ef53
--- /dev/null
+++ b/hal/files/hald-netbsd/vfsstat.c
@@ -0,0 +1,157 @@
+/* $NetBSD: vfsstat.c,v 1.1 2008/12/01 02:02:33 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2008 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/statvfs.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <paths.h>
+#include <unistd.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../hald_runner.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../ids.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "vfsstat.h"
+#include "drvctl.h"
+
+static void
+vfsstat_cleanup_mountpoint_cb(HalDevice *d, guint32 exit_type,
+ gint return_code, gchar **error, gpointer data1, gpointer data2)
+{
+ char *mount_point = data1;
+
+ HAL_INFO (("cleaned up mount point %s", mount_point));
+
+ g_free (mount_point);
+}
+
+void
+vfsstat_event(HalDevice *volume)
+{
+ GSList *volumes, *v;
+ HalDevice *d;
+ struct statvfs *statvfs;
+ int nmounts, i;
+
+ if (volume == NULL)
+ volumes = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.category", "volume");
+ else
+ volumes = g_slist_append (NULL, volume);
+
+ if (volumes == NULL)
+ return;
+
+ nmounts = getvfsstat (NULL, 0, ST_WAIT);
+ if (nmounts <= 0)
+ return;
+ statvfs = calloc (nmounts, sizeof (*statvfs));
+ if (statvfs == NULL)
+ return;
+ nmounts = getvfsstat (statvfs, nmounts * sizeof (*statvfs), ST_WAIT);
+ if (nmounts <= 0)
+ goto done;
+
+ for (i = 0; i < nmounts; i++)
+ for (v = volumes; v; v = g_slist_next (v)) {
+ const char *devpath;
+
+ d = HAL_DEVICE (v->data);
+ devpath = hal_device_property_get_string (d, "block.device");
+ if (devpath == NULL || strlen (devpath) == 0)
+ continue;
+ if (strcmp (devpath, statvfs[i].f_mntfromname) != 0)
+ continue;
+
+ device_property_atomic_update_begin ();
+ hal_device_property_set_bool (d, "volume.is_mounted", TRUE);
+ hal_device_property_set_bool (d, "volume.is_mounted_read_only",
+ statvfs[i].f_flag & ST_RDONLY ? TRUE : FALSE);
+ hal_device_property_set_string (d, "volume.mount_point", statvfs[i].f_mntonname);
+ device_property_atomic_update_end ();
+
+ volumes = g_slist_delete_link (volumes, v);
+ }
+
+ for (v = volumes; v; v = g_slist_next (v)) {
+ const char *mount_path;
+
+ d = HAL_DEVICE (v->data);
+ mount_path = g_strdup (hal_device_property_get_string (d, "volume.mount_point"));
+ if (mount_path == NULL || strlen (mount_path) == 0) {
+ if (mount_path)
+ g_free (mount_path);
+ continue;
+ }
+
+ device_property_atomic_update_begin ();
+ hal_device_property_set_bool (d, "volume.is_mounted", FALSE);
+ hal_device_property_set_bool (d, "volume.is_mounted_read_only", FALSE);
+ hal_device_property_set_string (d, "volume.mount_point", "");
+ device_property_atomic_update_end ();
+
+ if (hal_util_is_mounted_by_hald (mount_path)) {
+ char *cleanup_stdin;
+ char *extra_env[2];
+
+ extra_env[0] = g_strdup_printf ("HALD_CLEANUP=%s", mount_path);
+ extra_env[1] = NULL;
+ cleanup_stdin = "\n";
+
+ hald_runner_run_method (d,
+ "hal-storage-cleanup-mountpoint",
+ extra_env,
+ cleanup_stdin, TRUE,
+ 0,
+ vfsstat_cleanup_mountpoint_cb,
+ g_strdup (mount_path), NULL);
+
+ g_free (extra_env[0]);
+ }
+
+ g_free (mount_path);
+ }
+
+ g_slist_free (volumes);
+
+done:
+ free (statvfs);
+}
diff --git a/hal/files/hald-netbsd/vfsstat.h b/hal/files/hald-netbsd/vfsstat.h
new file mode 100644
index 0000000000..a78bc7aa52
--- /dev/null
+++ b/hal/files/hald-netbsd/vfsstat.h
@@ -0,0 +1,36 @@
+/* $NetBSD: vfsstat.h,v 1.1 2008/12/01 02:02:33 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2008 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VFSSTAT_H
+#define VFSSTAT_H
+
+#include "devinfo.h"
+
+void vfsstat_event(HalDevice *volume);
+
+#endif /* VFSSTAT_H */
diff --git a/hal/files/smf/hal.sh b/hal/files/smf/hal.sh
new file mode 100755
index 0000000000..c9d6cc0460
--- /dev/null
+++ b/hal/files/smf/hal.sh
@@ -0,0 +1,35 @@
+#!/sbin/sh
+
+. /lib/svc/share/smf_include.sh
+
+if [ ! -x @PREFIX@/sbin/hald ] ; then
+ echo "@PREFIX@/sbin/hald not found or not executable"
+ exit $SMF_EXIT_ERR_FATAL
+fi
+
+case "$1" in
+'start')
+ dir="@PKG_HOME.haldaemon@"
+ if ! [ -d $dir ]; then
+ @MKDIR@ -m 0755 $dir
+ @CHOWN@ @HAL_USER@:@HAL_GROUP@ $dir
+ fi
+
+ if ! [ -d /media ]; then
+ @MKDIR@ -m 755 /media
+ fi
+
+ @PREFIX@/sbin/hald --daemon=yes --use-syslog
+ err=$?
+ if [ $err -ne 0 ]; then
+ echo "hal failed to start: error $err"
+ exit $SMF_EXIT_ERR_FATAL
+ fi
+ ;;
+*)
+ echo "Usage: $0 { start }"
+ exit $SMF_EXIT_ERR_FATAL
+ ;;
+esac
+
+exit $SMF_EXIT_OK
diff --git a/hal/files/smf/manifest.xml b/hal/files/smf/manifest.xml
new file mode 100644
index 0000000000..1d7a93f173
--- /dev/null
+++ b/hal/files/smf/manifest.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<service_bundle type='manifest' name='export'>
+<service
+ name='@SMF_PREFIX@/@SMF_NAME@'
+ type='service'
+ version='1'>
+ <create_default_instance enabled='false' />
+ <single_instance />
+ <dependency name='usr'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/filesystem/minimal' />
+ </dependency>
+ <dependency
+ name='devices'
+ grouping='require_all'
+ restart_on='none'
+ type='service'>
+ <service_fmri value='svc:/system/device/local' />
+ </dependency>
+ <dependency name='dbus'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/@SMF_PREFIX@/dbus' />
+ </dependency>
+ <dependency name='sysevent'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/sysevent' />
+ </dependency>
+
+ <dependency name='keymap'
+ type='service'
+ grouping='optional_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/keymap' />
+ </dependency>
+
+ <exec_method
+ type='method'
+ name='start'
+ exec='@PREFIX@/@SMF_METHOD_FILE.hal@ start'
+ timeout_seconds='600'>
+ <method_context>
+ <method_credential user='root' group='root' />
+ </method_context>
+ </exec_method>
+
+ <exec_method
+ type='method'
+ name='stop'
+ exec=':kill'
+ timeout_seconds='30' />
+
+ <property_group name='startd' type='framework'>
+ <!-- sub-process core dumps shouldn't restart session -->
+ <propval name='ignore_error' type='astring'
+ value='core,signal' />
+ </property_group>
+
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'>
+ Hardware Abstraction Layer daemon
+ </loctext>
+ </common_name>
+ <documentation>
+ <manpage title='hald' section='8' manpath='@PREFIX@/@PKGMANDIR@'/>
+ </documentation>
+ </template>
+
+</service>
+
+</service_bundle>
diff --git a/hal/files/tools-netbsd/Makefile.am b/hal/files/tools-netbsd/Makefile.am
new file mode 100644
index 0000000000..6876866e70
--- /dev/null
+++ b/hal/files/tools-netbsd/Makefile.am
@@ -0,0 +1,40 @@
+## Process this file with automake to produce Makefile.in
+# $NetBSD: Makefile.am,v 1.2 2011/01/08 13:39:08 obache Exp $
+
+AM_CPPFLAGS = \
+ -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
+ -DPACKAGE_SCRIPT_DIR=\""$(libexecdir)/scripts"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -I$(top_srcdir) -I$(top_srcdir)/libhal -I$(top_srcdir)/libhal-storage \
+ @DBUS_CFLAGS@ @GLIB_CFLAGS@ @POLKIT_CFLAGS@
+
+scriptdir = $(libexecdir)/scripts/netbsd
+
+script_SCRIPTS = \
+ hal-system-power-suspend-netbsd \
+ hal-system-power-shutdown-netbsd \
+ hal-system-power-reboot-netbsd
+
+EXTRA_DIST = $(script_SCRIPTS)
+
+check:
+ for f in $(script_SCRIPTS); do \
+ echo -n "Validate bash syntax in $$f : "; \
+ bash -n $(srcdir)/$$f 2> bash.error;\
+ if test -s bash.error; then \
+ echo failed; \
+ cat bash.error; \
+ rm -f bash.error; \
+ exit 1; \
+ else \
+ echo ok; \
+ rm -f bash.error; \
+ fi; \
+ done;
+
+clean-local :
+ rm -f *~
diff --git a/hal/files/tools-netbsd/hal-system-power-reboot-netbsd b/hal/files/tools-netbsd/hal-system-power-reboot-netbsd
new file mode 100755
index 0000000000..7d1a62d1da
--- /dev/null
+++ b/hal/files/tools-netbsd/hal-system-power-reboot-netbsd
@@ -0,0 +1,19 @@
+#!/bin/sh
+# $NetBSD: hal-system-power-reboot-netbsd,v 1.1 2008/11/27 03:32:19 jmcneill Exp $
+
+unsupported() {
+ echo "org.freedesktop.Hal.Device.SystemPowerManagement.NotSupported" >&2
+ echo "No reboot command found" >&2
+ exit 1
+}
+
+#Try for common tools
+if [ -x "/sbin/shutdown" ] ; then
+ /sbin/shutdown -r now
+ exit $?
+elif [ -x "/usr/sbin/shutdown" ] ; then
+ /usr/sbin/shutdown -r now
+ exit $?
+else
+ unsupported
+fi
diff --git a/hal/files/tools-netbsd/hal-system-power-shutdown-netbsd b/hal/files/tools-netbsd/hal-system-power-shutdown-netbsd
new file mode 100755
index 0000000000..d05d8bca9b
--- /dev/null
+++ b/hal/files/tools-netbsd/hal-system-power-shutdown-netbsd
@@ -0,0 +1,19 @@
+#!/bin/sh
+# $NetBSD: hal-system-power-shutdown-netbsd,v 1.1 2008/11/27 03:32:19 jmcneill Exp $
+
+unsupported() {
+ echo "org.freedesktop.Hal.Device.SystemPowerManagement.NotSupported" >&2
+ echo "No shutdown command found" >&2
+ exit 1
+}
+
+#Try for common tools
+if [ -x "/sbin/shutdown" ] ; then
+ /sbin/shutdown -p now
+ exit $?
+elif [ -x "/usr/sbin/shutdown" ] ; then
+ /usr/sbin/shutdown -p now
+ exit $?
+else
+ unsupported
+fi
diff --git a/hal/files/tools-netbsd/hal-system-power-suspend-netbsd b/hal/files/tools-netbsd/hal-system-power-suspend-netbsd
new file mode 100755
index 0000000000..21b2ed38af
--- /dev/null
+++ b/hal/files/tools-netbsd/hal-system-power-suspend-netbsd
@@ -0,0 +1,29 @@
+#!/bin/sh
+# $NetBSD: hal-system-power-suspend-netbsd,v 1.1 2008/11/27 03:32:19 jmcneill Exp $
+
+alarm_not_supported() {
+ echo org.freedesktop.Hal.Device.SystemPowerManagement.AlarmNotSupported >&2
+ echo Waking the system up is not supported >&2
+ exit 1
+}
+
+unsupported() {
+ echo org.freedesktop.Hal.Device.SystemPowerManagement.NotSupported >&2
+ echo No suspend method found >&2
+ exit 1
+}
+
+read seconds_to_sleep
+
+if [ -x /usr/sbin/apm ] ; then
+ if [ -e /var/run/apmdev ]; then
+ /usr/sbin/apm -z 2>/dev/null
+ else
+ /usr/sbin/apm -z -d 2>/dev/null
+ fi
+ RET=$?
+else
+ unsupported
+fi
+
+exit $RET
diff --git a/hal/patches/patch-Makefile.am b/hal/patches/patch-Makefile.am
new file mode 100644
index 0000000000..cc4a462ee7
--- /dev/null
+++ b/hal/patches/patch-Makefile.am
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- Makefile.am.orig 2008-08-10 13:50:10.000000000 +0000
++++ Makefile.am
+@@ -6,7 +6,7 @@ SUBDIRS = libhal libhal-storage partutil
+ pkgconfigdir = $(libdir)/pkgconfig
+ pkgconfig_DATA = hal.pc hal-storage.pc
+
+-dbusdir = $(DBUS_SYS_DIR)
++dbusdir = $(PREFIX)/share/examples/hal
+ dist_dbus_DATA = hal.conf
+
+ # Creating ChangeLog from git log (taken from cairo/Makefile.am):
diff --git a/hal/patches/patch-configure.in b/hal/patches/patch-configure.in
new file mode 100644
index 0000000000..6b94bed13a
--- /dev/null
+++ b/hal/patches/patch-configure.in
@@ -0,0 +1,100 @@
+$NetBSD$
+
+--- configure.in.orig 2009-08-24 12:42:29.000000000 +0000
++++ configure.in
+@@ -479,12 +479,16 @@ if test "x$with_libpci" != xno ; then
+ fi
+ AM_CONDITIONAL([HAVE_LIBPCI], [test "x$USE_LIBPCI" = "xyes"])
+
++AC_CHECK_HEADERS([linux/videodev.h], [have_videodev_h=yes], [])
++AM_CONDITIONAL(HAVE_V4L1, [test "x$have_videodev_h" = "xyes"])
++
+ USE_LIBUSB20=no
+ USE_LIBUSB=no
+ LIBUSB20_LIBS=""
++LIBUFS_LIBS=""
+ AC_ARG_WITH([backend],
+ AS_HELP_STRING([--with-backend=<name>],
+- [backend to use (linux/solaris/freebsd/dummy)]),
++ [backend to use (linux/solaris/netbsd/freebsd/dummy)]),
+ [backend=$withval])
+ if ! test -z "$with_backend" ; then
+ HALD_BACKEND="$with_backend"
+@@ -493,6 +497,9 @@ else
+ *-*-solaris*)
+ HALD_BACKEND="solaris"
+ ;;
++ *-*-netbsd*)
++ HALD_BACKEND="netbsd"
++ ;;
+ *-*-freebsd* | *-*-kfreebsd*-gnu)
+ HALD_BACKEND="freebsd"
+ ;;
+@@ -508,8 +515,10 @@ AM_CONDITIONAL(HALD_COMPILE_DUMMY, [test
+ AM_CONDITIONAL(HALD_COMPILE_LINUX, [test x$HALD_BACKEND = xlinux], [Compiling for Linux])
+ 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])
++AM_CONDITIONAL(HALD_COMPILE_NETBSD, [test x$HALD_BACKEND = xnetbsd], [Compiling for NetBSD])
+ AC_SUBST(HALD_BACKEND)
+ if test "x$HALD_BACKEND" = "xfreebsd"; then
++ AC_SEARCH_LIBS([ufs_disk_fillout], [ufs], [LIBUFS_LIBS="-lufs"], [])
+ AC_CHECK_LIB([usb20], [libusb20_dev_get_info], [USE_LIBUSB20=yes], [USE_LIBUSB20=no])
+ fi
+ if test "x$USE_LIBUSB20" = "xno"; then
+@@ -526,6 +535,8 @@ elif test "x$USE_LIBUSB" = "xyes"; then
+ fi
+ AC_SUBST(LIBUSB20_LIBS)
+
++AC_SUBST(LIBUFS_LIBS)
++
+ dnl DBUS API is subject to changes
+ AC_DEFINE_UNQUOTED(DBUS_API_SUBJECT_TO_CHANGE, [], [DBUS API is subject to change])
+
+@@ -706,8 +717,8 @@ else
+ fi
+ AC_MSG_RESULT($have_glib_2_14)
+
+-case "$host" in
+- *-*-freebsd*)
++case "$HALD_BACKEND" in
++ freebsd | netbsd)
+ PKG_CHECK_MODULES(VOLUME_ID, [$volume_id_module])
+ AC_SUBST(VOLUME_ID_CFLAGS)
+ AC_SUBST(VOLUME_ID_LIBS)
+@@ -718,14 +729,13 @@ esac
+
+ # blkid (util-linux-ng)
+ case "$host" in
+-*-*-freebsd*)
+- ;;
+-*-*-solaris*)
+- ;;
+-*)
++*linux*)
+ PKG_CHECK_MODULES(BLKID, [$blkid_module])
+ AC_SUBST(BLKID_CFLAGS)
+ AC_SUBST(BLKID_LIBS)
++ ;;
++*)
++ ;;
+ esac
+
+ # OS specific libs
+@@ -1086,6 +1096,9 @@ hald/linux/addons/Makefile
+ hald/solaris/Makefile
+ hald/solaris/probing/Makefile
+ hald/solaris/addons/Makefile
++hald/netbsd/Makefile
++hald/netbsd/probing/Makefile
++hald/netbsd/addons/Makefile
+ hald/freebsd/Makefile
+ hald/freebsd/probing/Makefile
+ hald/freebsd/libprobe/Makefile
+@@ -1096,6 +1109,7 @@ libhal-storage/Makefile
+ tools/Makefile
+ tools/freebsd/Makefile
+ tools/linux/Makefile
++tools/netbsd/Makefile
+ partutil/Makefile
+ policy/Makefile
+ fdi/Makefile
diff --git a/hal/patches/patch-fdi_policy_10osvendor_20-storage-methods.fdi b/hal/patches/patch-fdi_policy_10osvendor_20-storage-methods.fdi
new file mode 100644
index 0000000000..2b37934f84
--- /dev/null
+++ b/hal/patches/patch-fdi_policy_10osvendor_20-storage-methods.fdi
@@ -0,0 +1,98 @@
+$NetBSD$
+
+--- fdi/policy/10osvendor/20-storage-methods.fdi.orig 2009-11-05 14:09:01.000000000 +0000
++++ fdi/policy/10osvendor/20-storage-methods.fdi
+@@ -74,6 +74,11 @@
+ <append key="volume.mount.valid_options" type="strlist">noexec</append>
+ <append key="volume.mount.valid_options" type="strlist">noatime</append>
+ </match>
++ <match key="/org/freedesktop/Hal/devices/computer:system.kernel.name" string="NetBSD">
++ <append key="volume.mount.valid_options" type="strlist">ro</append>
++ <append key="volume.mount.valid_options" type="strlist">noexec</append>
++ <append key="volume.mount.valid_options" type="strlist">noatime</append>
++ </match>
+ </match>
+ </match>
+
+@@ -182,6 +187,13 @@
+ <append key="org.freedesktop.Hal.Device.Volume.method_execpaths" type="strlist">hal-storage-eject</append>
+ </match>
+
++ <match key="/org/freedesktop/Hal/devices/computer:system.kernel.name" string="NetBSD">
++ <append key="org.freedesktop.Hal.Device.Volume.method_names" type="strlist">Eject</append>
++ <append key="org.freedesktop.Hal.Device.Volume.method_signatures" type="strlist">as</append>
++ <append key="org.freedesktop.Hal.Device.Volume.method_argnames" type="strlist">extra_options</append>
++ <append key="org.freedesktop.Hal.Device.Volume.method_execpaths" type="strlist">hal-storage-eject</append>
++ </match>
++
+ <!-- allow these mount options for all file systems -->
+ <match key="/org/freedesktop/Hal/devices/computer:system.kernel.name" string="Linux">
+ <append key="volume.mount.valid_options" type="strlist">ro</append>
+@@ -200,6 +212,11 @@
+ <append key="volume.mount.valid_options" type="strlist">noexec</append>
+ <append key="volume.mount.valid_options" type="strlist">noatime</append>
+ </match>
++ <match key="/org/freedesktop/Hal/devices/computer:system.kernel.name" string="NetBSD">
++ <append key="volume.mount.valid_options" type="strlist">ro</append>
++ <append key="volume.mount.valid_options" type="strlist">noexec</append>
++ <append key="volume.mount.valid_options" type="strlist">noatime</append>
++ </match>
+
+ <!-- allow these mount options for vfat -->
+ <match key="volume.fstype" string="vfat">
+@@ -226,6 +243,15 @@
+ <append key="volume.mount.valid_options" type="strlist">-D=</append>
+ <append key="volume.mount.valid_options" type="strlist">large</append>
+ </match>
++ <match key="/org/freedesktop/Hal/devices/computer:system.kernel.name" string="NetBSD">
++ <append key="volume.mount.valid_options" type="strlist">-u=</append>
++ <append key="volume.mount.valid_options" type="strlist">-g=</append>
++ <append key="volume.mount.valid_options" type="strlist">-m=</append>
++ <append key="volume.mount.valid_options" type="strlist">-M=</append>
++ <append key="volume.mount.valid_options" type="strlist">-9</append>
++ <append key="volume.mount.valid_options" type="strlist">-l</append>
++ <append key="volume.mount.valid_options" type="strlist">-s</append>
++ </match>
+ </match>
+
+
+@@ -258,6 +284,13 @@
+ <append key="volume.mount.valid_options" type="strlist">-C=</append>
+ <append key="volume.mount.valid_options" type="strlist">-W=</append>
+ </match>
++ <match key="/org/freedesktop/Hal/devices/computer:system.kernel.name" string="NetBSD">
++ <append key="volume.mount.valid_options" type="strlist">-u=</append>
++ <append key="volume.mount.valid_options" type="strlist">-g=</append>
++ <append key="volume.mount.valid_options" type="strlist">-m=</append>
++ <append key="volume.mount.valid_options" type="strlist">-a</append>
++ <append key="volume.mount.valid_options" type="strlist">-i</append>
++ </match>
+ </match>
+
+ <!-- allow these mount options for ext3 -->
+@@ -296,6 +329,10 @@
+ <append key="volume.mount.valid_options" type="strlist">-C=</append>
+ <append key="volume.mount.valid_options" type="strlist">-v</append>
+ </match>
++ <match key="/org/freedesktop/Hal/devices/computer:system.kernel.name" string="NetBSD">
++ <append key="volume.mount.valid_options" type="strlist">-u=</append>
++ <append key="volume.mount.valid_options" type="strlist">-g=</append>
++ </match>
+ </match>
+
+ <!-- iso9660 -->
+@@ -316,6 +353,14 @@
+ <append key="volume.mount.valid_options" type="strlist">-C=</append>
+ <append key="volume.mount.valid_options" type="strlist">-v</append>
+ </match>
++ <match key="/org/freedesktop/Hal/devices/computer:system.kernel.name" string="NetBSD">
++ <append key="volume.mount.valid_options" type="strlist">extatt</append>
++ <append key="volume.mount.valid_options" type="strlist">gens</append>
++ <append key="volume.mount.valid_options" type="strlist">nojoliet</append>
++ <append key="volume.mount.valid_options" type="strlist">norrip</append>
++ <append key="volume.mount.valid_options" type="strlist">nomaplcase</append>
++ <append key="volume.mount.valid_options" type="strlist">rcaseins</append>
++ </match>
+ </match>
+
+ <!-- allow these unmount options -->
diff --git a/hal/patches/patch-hald_Makefile.am b/hal/patches/patch-hald_Makefile.am
new file mode 100644
index 0000000000..35643abd05
--- /dev/null
+++ b/hal/patches/patch-hald_Makefile.am
@@ -0,0 +1,12 @@
+$NetBSD$
+
+--- hald/Makefile.am.orig 2009-07-15 06:52:51.000000000 +0000
++++ hald/Makefile.am
+@@ -1,6 +1,6 @@
+ ## Process this file with automake to produce Makefile.in
+
+-SUBDIRS = dummy freebsd linux solaris .
++SUBDIRS = dummy freebsd linux solaris netbsd .
+
+ AM_CPPFLAGS = \
+ -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
diff --git a/hal/patches/patch-hald_device__info.c b/hal/patches/patch-hald_device__info.c
new file mode 100644
index 0000000000..748f57d746
--- /dev/null
+++ b/hal/patches/patch-hald_device__info.c
@@ -0,0 +1,20 @@
+$NetBSD$
+
+--- hald/device_info.c.orig 2009-08-24 12:42:29.000000000 +0000
++++ hald/device_info.c
+@@ -1110,8 +1110,15 @@ rules_match_and_merge_device (void *fdi_
+ /*HAL_INFO(("no match, skip to rule (%llx)", rule->jump_position));*/
+ rule = di_jump(rule);
+
++#if 0
++ /*
++ * XXX
++ * this fires when a node has a single child
++ * which happens on some non-x86 machines
++ */
+ if(rule == NULL)
+ DIE(("Rule is NULL on jump"));
++#endif
+
+ continue;
+ }
diff --git a/hal/patches/patch-hald_freebsd_addons_addon-mouse.c b/hal/patches/patch-hald_freebsd_addons_addon-mouse.c
new file mode 100644
index 0000000000..994ae2f684
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_addons_addon-mouse.c
@@ -0,0 +1,14 @@
+$NetBSD$
+
+--- hald/freebsd/addons/addon-mouse.c.orig 2009-08-24 12:42:29.000000000 +0000
++++ hald/freebsd/addons/addon-mouse.c
+@@ -29,7 +29,9 @@
+ #include <sys/types.h>
+ #include <sys/event.h>
+ #include <sys/time.h>
++#ifdef __FreeBSD__
+ #include <sys/proc.h>
++#endif
+ #if __FreeBSD_version >= 800058
+ #include <sys/types.h>
+ #include <sys/user.h>
diff --git a/hal/patches/patch-hald_freebsd_addons_addon-storage.c b/hal/patches/patch-hald_freebsd_addons_addon-storage.c
new file mode 100644
index 0000000000..6e3f654cdf
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_addons_addon-storage.c
@@ -0,0 +1,140 @@
+$NetBSD$
+
+--- hald/freebsd/addons/addon-storage.c.orig 2009-08-24 12:42:29.000000000 +0000
++++ hald/freebsd/addons/addon-storage.c
+@@ -107,8 +107,12 @@ hf_addon_storage_update (void)
+
+ if (hf_addon_storage_cdrom_eject_pressed(cdrom))
+ {
++#if defined(__FreeBSD__)
++ libhal_device_emit_condition(hfp_ctx, hfp_udi, "EjectPressed", "", NULL);
++#else
+ libhal_device_emit_condition(hfp_ctx, hfp_udi, "EjectPressed", "", &hfp_error);
+ dbus_error_free(&hfp_error);
++#endif
+ }
+
+ hfp_cdrom_free(cdrom);
+@@ -164,11 +168,17 @@ unmount_volumes (void)
+ "block.storage_device",
+ hfp_udi,
+ &num_volumes,
++#if defined(__FreeBSD__)
++ NULL)) != NULL)
++#else
+ &hfp_error)) != NULL)
++#endif
+ {
+ int i;
+
++#if !defined(__FreeBSD__)
+ dbus_error_free(&hfp_error);
++#endif
+
+ for (i = 0; i < num_volumes; i++)
+ {
+@@ -176,7 +186,11 @@ unmount_volumes (void)
+
+ vol_udi = volumes[i];
+
++#if defined(__FreeBSD__)
++ if (libhal_device_get_property_bool(hfp_ctx, vol_udi, "volume.is_mounted", NULL))
++#else
+ if (libhal_device_get_property_bool(hfp_ctx, vol_udi, "volume.is_mounted", &hfp_error))
++#endif
+ {
+ DBusMessage *msg = NULL;
+ DBusMessage *reply = NULL;
+@@ -185,7 +199,9 @@ unmount_volumes (void)
+ char **options = NULL;
+ char *devfile;
+
++#if !defined(__FreeBSD__)
+ dbus_error_free(&hfp_error);
++#endif
+ hfp_info("Forcing unmount of volume '%s'", vol_udi);
+
+ dbus_connection = libhal_ctx_get_dbus_connection(hfp_ctx);
+@@ -265,10 +281,16 @@ poll_for_media (boolean check_only, bool
+ check_lock_state = FALSE;
+
+ hfp_info("Checking whether device %s is locked by HAL", addon.device_file);
++#if defined(__FreeBSD__)
++ if (libhal_device_is_locked_by_others(hfp_ctx, hfp_udi, "org.freedesktop.Hal.Device.Storage", NULL))
++#else
+ if (libhal_device_is_locked_by_others(hfp_ctx, hfp_udi, "org.freedesktop.Hal.Device.Storage", &hfp_error))
++#endif
+ {
+ hfp_info("... device %s is locked by HAL", addon.device_file);
++#if !defined(__FreeBSD__)
+ dbus_error_free(&hfp_error);
++#endif
+ is_locked_by_hal = TRUE;
+ update_proc_title(addon.device_file);
+ goto skip_check;
+@@ -278,9 +300,13 @@ poll_for_media (boolean check_only, bool
+ hfp_info("... device %s is not locked by HAL", addon.device_file);
+ is_locked_by_hal = FALSE;
+ }
++#if defined(__FreeBSD__)
++ should_poll = libhal_device_get_property_bool(hfp_ctx, hfp_udi, "storage.media_check_enabled", NULL);
++#else
+ dbus_error_free(&hfp_error);
+
+ should_poll = libhal_device_get_property_bool(hfp_ctx, hfp_udi, "storage.media_check_enabled", &hfp_error);
++#endif
+ dbus_error_free(&hfp_error);
+ polling_disabled = ! should_poll;
+ update_proc_title(addon.device_file);
+@@ -314,8 +340,12 @@ poll_for_media (boolean check_only, bool
+ unmount_volumes();
+ #endif
+
++#if defined(__FreeBSD__)
++ libhal_device_rescan(hfp_ctx, hfp_udi, NULL);
++#else
+ libhal_device_rescan(hfp_ctx, hfp_udi, &hfp_error);
+ dbus_error_free(&hfp_error);
++#endif
+ addon.had_media = has_media;
+
+ return TRUE;
+@@ -412,12 +442,19 @@ main (int argc, char **argv)
+ ! strcmp(driver, "cd")))) && ! strcmp(removable, "true");
+ addon.had_media = poll_for_media(TRUE, FALSE);
+
++#if defined(__FreeBSD__)
++ if (! libhal_device_addon_is_ready(hfp_ctx, hfp_udi, NULL))
++ goto end;
++
++ syscon = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
++#else
+ 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);
++#endif
+ assert(syscon != NULL);
+ dbus_connection_set_exit_on_disconnect(syscon, 0);
+
+@@ -452,12 +489,18 @@ main (int argc, char **argv)
+ " <method name=\"CheckForMedia\">\n"
+ " <arg name=\"call_had_sideeffect\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n",
++#if defined(__FreeBSD__)
++ NULL))
++#else
+ &hfp_error))
++#endif
+ {
+ hfp_critical("Cannot claim interface 'org.freedesktop.Hal.Device.Storage.Removable'");
+ goto end;
+ }
++#if !defined(__FreeBSD__)
+ dbus_error_free(&hfp_error);
++#endif
+
+ while (TRUE)
+ {
diff --git a/hal/patches/patch-hald_freebsd_hf-ata.c b/hal/patches/patch-hald_freebsd_hf-ata.c
new file mode 100644
index 0000000000..720dcac4df
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_hf-ata.c
@@ -0,0 +1,16 @@
+$NetBSD$
+
+--- hald/freebsd/hf-ata.c.orig 2008-08-10 13:50:10.000000000 +0000
++++ hald/freebsd/hf-ata.c
+@@ -30,7 +30,11 @@
+ #include <unistd.h>
+ #include <errno.h>
+ #include <sys/ioctl.h>
++#ifdef __DragonFly__
++#include <sys/nata.h>
++#else
+ #include <sys/ata.h>
++#endif
+
+ #include "../logger.h"
+
diff --git a/hal/patches/patch-hald_freebsd_hf-devd.c b/hal/patches/patch-hald_freebsd_hf-devd.c
new file mode 100644
index 0000000000..48e81c6127
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_hf-devd.c
@@ -0,0 +1,40 @@
+$NetBSD$
+
+--- hald/freebsd/hf-devd.c.orig 2009-08-24 12:42:29.000000000 +0000
++++ hald/freebsd/hf-devd.c
+@@ -122,7 +122,11 @@ hf_devd_parse_add_remove (const char *ev
+ g_return_val_if_fail(parent != NULL, FALSE);
+
+ if ((params_ptr = strchr(event, ' '))
++#if defined(__FreeBSD__)
++ && (at_ptr = strstr(params_ptr, "at "))
++#else
+ && (at_ptr = strstr(params_ptr + 1, " at "))
++#endif
+ && (parent_ptr = strstr(at_ptr + 4, " on ")))
+ {
+ char *params_str;
+@@ -130,7 +134,11 @@ hf_devd_parse_add_remove (const char *ev
+
+ *name = g_strndup(event, params_ptr - event);
+ params_str = g_strndup(params_ptr + 1, at_ptr - params_ptr - 1);
++#if defined(__FreeBSD__)
++ at_str = g_strndup(at_ptr + 3, parent_ptr - at_ptr - 3);
++#else
+ at_str = g_strndup(at_ptr + 4, parent_ptr - at_ptr - 4);
++#endif
+ *parent = g_strdup(parent_ptr + 4);
+
+ if (! strcmp(*parent, ".")) /* sys/kern/subr_bus.c */
+@@ -398,7 +406,11 @@ hf_devd_event_cb (GIOChannel *source, GI
+ hf_devd_process_event(event);
+ g_free(event);
+ }
++#if defined(__FreeBSD__)
++ else if (status == G_IO_STATUS_AGAIN || status == G_IO_STATUS_EOF)
++#else
+ else if (status == G_IO_STATUS_AGAIN)
++#endif
+ {
+ hf_devd_init();
+ if (hf_devd_inited)
diff --git a/hal/patches/patch-hald_freebsd_hf-pci.c b/hal/patches/patch-hald_freebsd_hf-pci.c
new file mode 100644
index 0000000000..985e21c0ab
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_hf-pci.c
@@ -0,0 +1,16 @@
+$NetBSD$
+
+--- hald/freebsd/hf-pci.c.orig 2009-05-12 12:27:00.000000000 +0000
++++ hald/freebsd/hf-pci.c
+@@ -27,7 +27,11 @@
+
+ #include <stdio.h>
+ #include <string.h>
++#ifdef __DragonFly__
++#include <bitstring.h>
++#else
+ #include <sys/bitstring.h>
++#endif
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <unistd.h>
diff --git a/hal/patches/patch-hald_freebsd_hf-storage.c b/hal/patches/patch-hald_freebsd_hf-storage.c
new file mode 100644
index 0000000000..f5695ba439
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_hf-storage.c
@@ -0,0 +1,14 @@
+$NetBSD$
+
+--- hald/freebsd/hf-storage.c.orig 2009-08-24 12:42:29.000000000 +0000
++++ hald/freebsd/hf-storage.c
+@@ -33,6 +33,9 @@
+ #include <sys/param.h>
+ #include <sys/types.h>
+ #include <sys/disklabel.h>
++#ifdef __DragonFly__
++#include <sys/dtype.h>
++#endif
+
+ #include "../logger.h"
+ #include "../osspec.h"
diff --git a/hal/patches/patch-hald_freebsd_hf-usb.c b/hal/patches/patch-hald_freebsd_hf-usb.c
new file mode 100644
index 0000000000..abcccc8e9e
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_hf-usb.c
@@ -0,0 +1,47 @@
+$NetBSD$
+
+--- hald/freebsd/hf-usb.c.orig 2009-09-17 13:49:46.000000000 +0000
++++ hald/freebsd/hf-usb.c
+@@ -36,9 +36,13 @@
+ #if __FreeBSD_version >= 800064
+ #include <legacy/dev/usb/usb.h>
+ #else
++#ifdef __DragonFly__
++#include <bus/usb/usb.h>
++#else
+ #include <dev/usb/usb.h>
+ #endif
+ #endif
++#endif
+
+ #include "../logger.h"
+ #include "../osspec.h"
+@@ -392,7 +396,11 @@ 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 */
++#if defined(__FreeBSD__)
++ hf_device_set_input(device, "keyboard", "keys", NULL);
++#else
+ hf_device_set_input(device, "keyboard", "keys", devname);
++#endif
+ else if ((devname = hf_usb_get_devname(di, "ums"))) /* USB mouse */
+ hf_device_set_input(device, "mouse", NULL, devname);
+ else if ((devname = hf_usb_get_devname(di, "uhid"))) /* UHID device */
+@@ -613,7 +621,6 @@ hf_usb_privileged_init (void)
+ if (hf_usb_fd < 0)
+ {
+ HAL_INFO(("unable to open %s: %s", HF_USB_DEVICE, g_strerror(errno)));
+- return;
+ }
+
+ for (i = 0; i < 16; i++)
+@@ -908,6 +915,8 @@ hf_usb_add_webcam_properties (HalDevice
+
+ hal_device_property_set_string(device, "info.category", "video4linux");
+ hal_device_add_capability(device, "video4linux");
++ hal_device_add_capability(device, "video4linux.video_capture");
+ hf_device_property_set_string_printf(device, "video4linux.device", "/dev/video%i", unit);
+ hal_device_property_set_string(device, "info.product", "Video Device");
++ hal_device_property_set_string(device, "video4linux.version", "1");
+ }
diff --git a/hal/patches/patch-hald_freebsd_hf-usb2.c b/hal/patches/patch-hald_freebsd_hf-usb2.c
new file mode 100644
index 0000000000..cebec39bb7
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_hf-usb2.c
@@ -0,0 +1,415 @@
+$NetBSD$
+
+--- hald/freebsd/hf-usb2.c.orig 2009-08-24 12:42:29.000000000 +0000
++++ hald/freebsd/hf-usb2.c
+@@ -22,7 +22,7 @@
+ **************************************************************************/
+
+ #ifdef HAVE_CONFIG_H
+-# include <config.h>
++#include <config.h>
+ #endif
+
+ #include <string.h>
+@@ -42,246 +42,200 @@
+ static struct libusb20_backend *hf_usb2_be = NULL;
+
+ static void
+-hf_usb2_copy_parent (HalDevice *parent,
+- const char *key,
+- gpointer user_data)
++hf_usb2_probe_interfaces(HalDevice * parent)
+ {
+- HalDevice *device;
++ int num_interfaces;
++ int i;
+
+- g_return_if_fail(HAL_IS_DEVICE(parent));
+- g_return_if_fail(HAL_IS_DEVICE(user_data));
++ g_return_if_fail(HAL_IS_DEVICE(parent));
+
+- device = HAL_DEVICE(user_data);
+-
+- if (! strncmp(key, "usb_device.", strlen("usb_device.")))
+- hal_device_copy_property(parent, key, device, key);
++ 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_copy_property(parent, "info.product", device, "info.product");
++ hal_device_copy_property(parent, "info.vendor", device, "info.vendor");
++ hal_device_merge_with_rewrite(device, parent, "usb.", "usb_device.");
++
++ 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", "keys", NULL);
++ else if (!strcmp(driver, "ums") || !strcmp(driver, "atp")) {
++ hf_device_set_input(device, "mouse", NULL, 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);
++ }
++ } else {
++ /* Try and detect webcamd devices. */
++ hf_runner_run_sync(device, 0, "hald-probe-video4linux", NULL);
++ }
++
++ hf_usb_device_compute_udi(device);
++ hf_device_add(device);
++ }
++ }
+ }
+
+ static void
+-hf_usb2_probe_interfaces(HalDevice *parent)
++hf_usb2_probe_device(HalDevice * parent, int bus, int addr)
+ {
+- int num_interfaces;
+- int i;
++ HalDevice *device;
+
+- g_return_if_fail(HAL_IS_DEVICE(parent));
++ g_return_if_fail(HAL_IS_DEVICE(parent));
+
+- if (hal_device_property_get_bool(parent, "info.ignore"))
+- return;
++ device = hf_device_new(parent);
+
+- 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);
+- }
+- }
++ 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", 1);
++ hal_device_property_set_int(device, "usb_device.port_number", addr);
+
+- hf_usb_device_compute_udi(device);
+- hf_device_add(device);
++ 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);
++ hf_usb2_probe_interfaces(device);
+ }
+- }
+ }
+
+ static void
+-hf_usb2_probe_device (HalDevice *parent, int bus, int addr)
++hf_usb2_privileged_init(void)
+ {
+- HalDevice *device;
+-
+- g_return_if_fail(HAL_IS_DEVICE(parent));
+-
+- device = hf_device_new(parent);
++ hf_usb2_be = libusb20_be_alloc_default();
++ if (hf_usb2_be == NULL)
++ HAL_INFO(("unable to open USB backend: %s", g_strerror(errno)));
++}
+
+- 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);
++static void
++hf_usb2_new_device(int bus, int addr)
++{
++ HalDevice *parent;
+
+- if (hf_device_preprobe(device))
+- {
+- hf_runner_run_sync(device, 0, "hald-probe-usb2-device", NULL);
+- hf_usb_device_compute_udi(device);
++ parent = hf_devtree_find_from_info(hald_get_gdl(), "usbus", bus);
+
+- hf_device_add(device);
+- }
+- else
+- return;
++ if (!parent || hal_device_property_get_bool(parent, "info.ignore"))
++ return;
+
+- hf_usb2_probe_interfaces(device);
++ hf_usb2_probe_device(parent, bus, addr);
+ }
+
+ static void
+-hf_usb2_privileged_init (void)
++hf_usb2_probe(void)
+ {
+- hf_usb2_be = libusb20_be_alloc_default();
+- if (hf_usb2_be == NULL)
+- HAL_INFO(("unable to open USB backend: %s", g_strerror(errno)));
+-}
++ struct libusb20_device *pdev = NULL;
+
+-static void
+-hf_usb2_probe (void)
+-{
+- struct libusb20_device *pdev = NULL;
++ if (hf_usb2_be == NULL)
++ return;
+
+- if (hf_usb2_be == NULL)
+- return;
++ while ((pdev = libusb20_be_device_foreach(hf_usb2_be, pdev))) {
++ hf_usb2_new_device(libusb20_dev_get_bus_number(pdev),
++ libusb20_dev_get_address(pdev));
++ }
+
+- 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;
++ libusb20_be_free(hf_usb2_be);
++ hf_usb2_be = NULL;
++}
+
+- hf_usb2_probe_device(parent, bus, addr);
+- }
++static gboolean
++hf_usb2_devd_notify(const char *system,
++ const char *subsystem,
++ const char *type,
++ const char *data)
++{
++ const char *ugen;
++ int bus;
++ int addr;
++
++ if (!data || strcmp(system, "USB") || strcmp(subsystem, "DEVICE") ||
++ (strcmp(type, "ATTACH") && strcmp(type, "DETACH")))
++ return FALSE;
++
++ ugen = strstr(data, "ugen=");
++ if (ugen == NULL) {
++ /*
++ * The following case is not required in
++ * FreeBSD 8-stable and newer:
++ */
++ ugen = strstr(data, "cdev=");
++ if (ugen == NULL)
++ return FALSE;
++
++ if (sscanf(ugen, "cdev=ugen%i.%i", &bus, &addr) != 2)
++ return FALSE;
++ } else {
++ if (sscanf(ugen, "ugen=ugen%i.%i", &bus, &addr) != 2)
++ return FALSE;
++ }
+
+- libusb20_be_free(hf_usb2_be);
+- hf_usb2_be = NULL;
+-}
++ if (strcmp(type, "ATTACH") == 0) {
+
+-static gboolean
+-hf_usb2_devd_add (const char *name,
+- GHashTable *params,
+- GHashTable *at,
+- const char *parent)
+-{
+- HalDevice *parent_device;
+- int bus, addr, pbus, paddr;
++ HAL_INFO(("received devd attach event, device %s", data));
+
+- 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;
+- }
++ hf_usb2_new_device(bus, addr);
++ }
++ if (strcmp(type, "DETACH") == 0) {
+
+- return FALSE;
+-}
++ HalDevice *device;
+
+-static gboolean
+-hf_usb2_devd_remove (const char *name,
+- GHashTable *params,
+- GHashTable *at,
+- const char *parent)
+-{
+- HalDevice *device;
+- int bus, addr;
++ HAL_INFO(("received devd detach event, device %s", data));
+
+- 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;
+- }
++ 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,
++ "info.bus", HAL_PROPERTY_TYPE_STRING, "usb_device", NULL);
+
+- return FALSE;
++ if (device)
++ hf_device_remove_tree(device);
++ }
++ return TRUE;
+ }
+
+ HFHandler hf_usb2_handler = {
+- .privileged_init = hf_usb2_privileged_init,
+- .probe = hf_usb2_probe
++ .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
++ .notify = hf_usb2_devd_notify
+ };
diff --git a/hal/patches/patch-hald_freebsd_hf-volume.c b/hal/patches/patch-hald_freebsd_hf-volume.c
new file mode 100644
index 0000000000..f8f501c6ab
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_hf-volume.c
@@ -0,0 +1,18 @@
+$NetBSD$
+
+--- hald/freebsd/hf-volume.c.orig 2009-08-24 12:42:29.000000000 +0000
++++ hald/freebsd/hf-volume.c
+@@ -86,9 +86,12 @@ hf_volume_resolve_fuse (const char *spec
+ {
+ if (strcmp(fields[0], special) == 0)
+ {
++ char *ret;
++
++ ret = g_strdup(fields[1]);
+ g_strfreev(fields);
+ g_strfreev(lines);
+- return g_strdup(fields[1]);
++ return ret;
+ }
+ }
+ g_strfreev(fields);
diff --git a/hal/patches/patch-hald_freebsd_libprobe_hfp-cdrom.c b/hal/patches/patch-hald_freebsd_libprobe_hfp-cdrom.c
new file mode 100644
index 0000000000..1078b086af
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_libprobe_hfp-cdrom.c
@@ -0,0 +1,16 @@
+$NetBSD$
+
+--- hald/freebsd/libprobe/hfp-cdrom.c.orig 2008-08-10 13:50:10.000000000 +0000
++++ hald/freebsd/libprobe/hfp-cdrom.c
+@@ -32,7 +32,11 @@
+ #include <unistd.h>
+ #include <sys/ioctl.h>
+ #include <sys/types.h>
++#ifdef __DragonFly__
++#include <sys/nata.h>
++#else
+ #include <sys/ata.h>
++#endif
+ #include <stdio.h>
+ #include <camlib.h>
+ #include <cam/scsi/scsi_message.h>
diff --git a/hal/patches/patch-hald_freebsd_probing_Makefile.am b/hal/patches/patch-hald_freebsd_probing_Makefile.am
new file mode 100644
index 0000000000..a8ea37df76
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_probing_Makefile.am
@@ -0,0 +1,11 @@
+$NetBSD$
+
+--- hald/freebsd/probing/Makefile.am.orig 2009-08-24 12:42:29.000000000 +0000
++++ hald/freebsd/probing/Makefile.am
+@@ -67,5 +67,5 @@ hald_probe_volume_CPPFLAGS = $(AM_CPPFLA
+ hald_probe_volume_LDADD = \
+ @GLIB_LIBS@ \
+ @VOLUME_ID_LIBS@ \
+- -lufs \
++ @LIBUFS_LIBS@ \
+ $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la
diff --git a/hal/patches/patch-hald_freebsd_probing_probe-hiddev.c b/hal/patches/patch-hald_freebsd_probing_probe-hiddev.c
new file mode 100644
index 0000000000..b9b0e5abcb
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_probing_probe-hiddev.c
@@ -0,0 +1,18 @@
+$NetBSD$
+
+--- hald/freebsd/probing/probe-hiddev.c.orig 2009-09-17 13:47:14.000000000 +0000
++++ hald/freebsd/probing/probe-hiddev.c
+@@ -31,8 +31,13 @@
+ #include <fcntl.h>
+ #ifndef HAVE_LIBUSB20
+ #include <sys/ioctl.h>
++#ifdef __DragonFly__
++#include <bus/usb/usb.h>
++#include <bus/usb/usbhid.h>
++#else
+ #include <dev/usb/usb.h>
+ #include <dev/usb/usbhid.h>
++#endif
+ #else
+ #if __FreeBSD_version >= 800064
+ #include <dev/usb/usbhid.h>
diff --git a/hal/patches/patch-hald_freebsd_probing_probe-storage.c b/hal/patches/patch-hald_freebsd_probing_probe-storage.c
new file mode 100644
index 0000000000..7759bd12cf
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_probing_probe-storage.c
@@ -0,0 +1,44 @@
+$NetBSD$
+
+--- hald/freebsd/probing/probe-storage.c.orig 2009-08-24 12:42:29.000000000 +0000
++++ hald/freebsd/probing/probe-storage.c
+@@ -32,7 +32,11 @@
+ #include <errno.h>
+ #include <sys/types.h>
+ #include <sys/ioctl.h>
++#ifdef __DragonFly__
++#include <sys/diskslice.h>
++#else
+ #include <sys/disk.h>
++#endif
+ #include <netinet/in.h>
+ #include <glib.h>
+ #include <libvolume_id.h>
+@@ -171,6 +175,9 @@ int
+ main (int argc, char **argv)
+ {
+ char *device_file;
++#ifdef __DragonFly__
++ struct partinfo device_info;
++#endif
+ char *drive_type;
+ char *parent;
+ int ret = 0; /* no media/filesystem */
+@@ -221,10 +228,17 @@ main (int argc, char **argv)
+ fd = open(device_file, O_RDONLY | O_NONBLOCK);
+ if (fd > -1)
+ {
++#ifdef __DragonFly__
++ if (ioctl (fd, DIOCGPART, &device_info) == 0)
++ {
++ libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "storage.removable.media_size", device_info.media_size, &hfp_error);
++ }
++#else
+ if (ioctl (fd, DIOCGMEDIASIZE, &size) == 0)
+ {
+ libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "storage.removable.media_size", size, &hfp_error);
+ }
++#endif
+ close(fd);
+ }
+ ret = 2; /* has media */
diff --git a/hal/patches/patch-hald_freebsd_probing_probe-usb2-device.c b/hal/patches/patch-hald_freebsd_probing_probe-usb2-device.c
new file mode 100644
index 0000000000..2f45baf299
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_probing_probe-usb2-device.c
@@ -0,0 +1,44 @@
+$NetBSD$
+
+--- hald/freebsd/probing/probe-usb2-device.c.orig 2009-08-24 12:42:29.000000000 +0000
++++ hald/freebsd/probing/probe-usb2-device.c
+@@ -147,16 +147,16 @@ main(int argc, char **argv)
+ speed = 12.0;
+ bcdspeed = 0x01200;
+ break;
+- case LIBUSB20_SPEED_HIGH:
++ case LIBUSB20_SPEED_VARIABLE:
+ speed = 480.0;
+ bcdspeed = 0x48000;
+ break;
+ case LIBUSB20_SPEED_SUPER:
+- speed = 4800.0;
+- bcdspeed = 0x480000;
++ speed = 5000.0;
++ bcdspeed = 0x500000;
+ break;
+ default:
+- ;
++ break;
+ }
+
+ libhal_device_set_property_double(hfp_ctx, hfp_udi, "usb_device.speed",
+@@ -169,6 +169,9 @@ main(int argc, char **argv)
+ case UD_USB_2_0:
+ version = 2.0;
+ break;
++ case 0x0250:
++ version = 2.5;
++ break;
+ case UD_USB_3_0:
+ version = 3.0;
+ break;
+@@ -184,7 +187,7 @@ main(int argc, char **argv)
+ 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);
++ "usb_device.device_revision_bcd", ddesc->bcdDevice, &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,
diff --git a/hal/patches/patch-hald_freebsd_probing_probe-usb2-interface.c b/hal/patches/patch-hald_freebsd_probing_probe-usb2-interface.c
new file mode 100644
index 0000000000..a6b8acf70a
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_probing_probe-usb2-interface.c
@@ -0,0 +1,18 @@
+$NetBSD$
+
+--- hald/freebsd/probing/probe-usb2-interface.c.orig 2009-08-24 12:42:29.000000000 +0000
++++ hald/freebsd/probing/probe-usb2-interface.c
+@@ -58,11 +58,11 @@ main(int argc, char **argv)
+ if (pbe == NULL)
+ goto end;
+
+- busstr = getenv("HAL_PROP_USB_DEVICE_BUS_NUMBER");
++ busstr = getenv("HAL_PROP_USB_BUS_NUMBER");
+ if (! busstr)
+ goto end;
+
+- addrstr = getenv("HAL_PROP_USB_DEVICE_PORT_NUMBER");
++ addrstr = getenv("HAL_PROP_USB_PORT_NUMBER");
+ if (! addrstr)
+ goto end;
+
diff --git a/hal/patches/patch-hald_freebsd_probing_probe-volume.c b/hal/patches/patch-hald_freebsd_probing_probe-volume.c
new file mode 100644
index 0000000000..32636fa56b
--- /dev/null
+++ b/hal/patches/patch-hald_freebsd_probing_probe-volume.c
@@ -0,0 +1,127 @@
+$NetBSD$
+
+--- hald/freebsd/probing/probe-volume.c.orig 2009-09-17 13:45:09.000000000 +0000
++++ hald/freebsd/probing/probe-volume.c
+@@ -33,7 +33,11 @@
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <sys/ioctl.h>
++#ifdef __DragonFly__
++#include <sys/diskslice.h>
++#else
+ #include <sys/disk.h>
++#endif
+ #include <sys/cdio.h>
+ #include <sys/param.h>
+ #include <sys/mount.h>
+@@ -41,7 +45,11 @@
+ #include <ufs/ufs/ufsmount.h>
+ #include <ufs/ufs/dinode.h>
+ #include <ufs/ffs/fs.h>
++#ifdef __DragonFly__
++#include <ufs/ufs/ufs_types.h>
++#else
+ #include <libufs.h>
++#endif
+ #include <isofs/cd9660/iso.h>
+ #include <glib.h>
+ #include <libvolume_id.h>
+@@ -332,6 +340,9 @@ main (int argc, char **argv)
+ gboolean is_blank = FALSE;
+ const char *usage;
+ char *label;
++#ifdef __DragonFly__
++ struct partinfo device_info;
++#endif
+ unsigned int sector_size = 0;
+ off_t media_size = 0;
+
+@@ -371,7 +382,12 @@ main (int argc, char **argv)
+ is_blank = (! has_audio && ! has_data);
+ }
+
++#ifdef __DragonFly__
++ ioctl(fd, DIOCGPART, &device_info);
++ media_size = device_info.media_size;
++#else
+ ioctl(fd, DIOCGMEDIASIZE, &media_size);
++#endif
+
+ /*
+ * We only check for filesystems if the volume has no children,
+@@ -563,16 +579,35 @@ main (int argc, char **argv)
+
+ if (vid && ! strcmp (vid->type, "ufs"))
+ {
++#ifdef __DragonFly__
++ struct fs fs;
++ int rfd;
++ ssize_t nr;
++
++ if ((rfd = open(device_file, O_RDONLY)) >= 0) {
++ lseek(rfd, (off_t) SBOFF, SEEK_SET);
++
++ nr = read(rfd, &fs, (size_t) SBSIZE);
++ close(rfd);
++ }
++
++ if (nr == (ssize_t) SBSIZE)
++#else
+ struct uufsd ufsdisk;
+
+ if (ufs_disk_fillout(&ufsdisk, device_file) == 0)
++#endif
+ {
+ char ufsid[64];
+ char **ufs_devs = NULL;
+ int num_udis;
+ int i;
+
++#ifdef __DragonFly__
++ snprintf(ufsid, sizeof(ufsid), "%08x%08x", fs.fs_id[0], fs.fs_id[1]);
++#else
+ snprintf(ufsid, sizeof(ufsid), "%08x%08x", ufsdisk.d_fs.fs_id[0], ufsdisk.d_fs.fs_id[1]);
++#endif
+ 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",
+@@ -582,7 +617,11 @@ main (int argc, char **argv)
+ dbus_error_free(&hfp_error);
+ for (i = 0; i < num_udis; i++)
+ {
++#if defined(__FreeBSD__)
++ if (ufs_devs[i] != NULL && strcmp(ufs_devs[i], hfp_udi))
++#else
+ if (ufs_devs[i] != NULL)
++#endif
+ {
+ gboolean mounted;
+
+@@ -592,12 +631,15 @@ main (int argc, char **argv)
+ {
+ libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", TRUE, &hfp_error);
+ dbus_error_free(&hfp_error);
++ break;
+ }
+ }
+ }
+ if (ufs_devs)
+ libhal_free_string_array(ufs_devs);
++#ifndef __DragonFly__
+ ufs_disk_close(&ufsdisk);
++#endif
+ }
+ }
+
+@@ -628,7 +670,11 @@ main (int argc, char **argv)
+
+ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.uuid", vid ? vid->uuid : "", &hfp_error);
+
++#ifdef __DragonFly__
++ sector_size = device_info.media_blksize;
++#else
+ ioctl(fd, DIOCGSECTORSIZE, §or_size);
++#endif
+
+ if (sector_size != 0)
+ libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.block_size", sector_size, &hfp_error);
diff --git a/hal/patches/patch-hald_linux_addons_addon-acpi-buttons-toshiba.c b/hal/patches/patch-hald_linux_addons_addon-acpi-buttons-toshiba.c
new file mode 100644
index 0000000000..23bba951a5
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-acpi-buttons-toshiba.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-acpi-buttons-toshiba.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-acpi-buttons-toshiba.c
+@@ -40,7 +40,7 @@ else
+ #include <string.h>
+ #include <unistd.h>
+
+-#include <glib/gmain.h>
++#include <glib.h>
+
+ #include "libhal/libhal.h"
+ #include "../../logger.h"
diff --git a/hal/patches/patch-hald_linux_addons_addon-cpufreq.c b/hal/patches/patch-hald_linux_addons_addon-cpufreq.c
new file mode 100644
index 0000000000..62ad064e70
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-cpufreq.c
@@ -0,0 +1,12 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-cpufreq.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-cpufreq.c
+@@ -32,7 +32,6 @@
+ #include <unistd.h>
+ #include <signal.h>
+ #include <getopt.h>
+-#include <glib/gprintf.h>
+
+ #include "addon-cpufreq.h"
+ #include "addon-cpufreq-userspace.h"
diff --git a/hal/patches/patch-hald_linux_addons_addon-dell-backlight.cpp b/hal/patches/patch-hald_linux_addons_addon-dell-backlight.cpp
new file mode 100644
index 0000000000..103269870c
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-dell-backlight.cpp
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-dell-backlight.cpp.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-dell-backlight.cpp
+@@ -29,7 +29,7 @@
+
+ #include <string.h>
+
+-#include <glib/gmain.h>
++#include <glib.h>
+ #include <dbus/dbus-glib.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+
diff --git a/hal/patches/patch-hald_linux_addons_addon-generic-backlight.c b/hal/patches/patch-hald_linux_addons_addon-generic-backlight.c
new file mode 100644
index 0000000000..eed39c0b76
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-generic-backlight.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-generic-backlight.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-generic-backlight.c
+@@ -35,7 +35,7 @@
+ #include <sys/stat.h>
+ #include <unistd.h>
+
+-#include <glib/gmain.h>
++#include <glib.h>
+ #include <dbus/dbus-glib.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+
diff --git a/hal/patches/patch-hald_linux_addons_addon-imac-backlight.c b/hal/patches/patch-hald_linux_addons_addon-imac-backlight.c
new file mode 100644
index 0000000000..107750b83c
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-imac-backlight.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-imac-backlight.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-imac-backlight.c
+@@ -29,7 +29,7 @@
+ #include <stdlib.h>
+ #include <sys/io.h>
+
+-#include <glib/gmain.h>
++#include <glib.h>
+ #include <dbus/dbus-glib.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+
diff --git a/hal/patches/patch-hald_linux_addons_addon-input.c b/hal/patches/patch-hald_linux_addons_addon-input.c
new file mode 100644
index 0000000000..1e2429b460
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-input.c
@@ -0,0 +1,14 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-input.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-input.c
+@@ -41,8 +41,7 @@
+ #else
+ #include <linux/input.h>
+ #endif
+-#include <glib/gmain.h>
+-#include <glib/gprintf.h>
++#include <glib.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+
+ #include "libhal/libhal.h"
diff --git a/hal/patches/patch-hald_linux_addons_addon-ipw-killswitch.c b/hal/patches/patch-hald_linux_addons_addon-ipw-killswitch.c
new file mode 100644
index 0000000000..cb2ce9564a
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-ipw-killswitch.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-ipw-killswitch.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-ipw-killswitch.c
+@@ -36,8 +36,6 @@
+ #include <unistd.h>
+
+ #include <glib.h>
+-#include <glib/gmain.h>
+-#include <glib/gstdio.h>
+ #include <dbus/dbus-glib.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+
diff --git a/hal/patches/patch-hald_linux_addons_addon-leds.c b/hal/patches/patch-hald_linux_addons_addon-leds.c
new file mode 100644
index 0000000000..f7d76cd4b2
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-leds.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-leds.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-leds.c
+@@ -36,8 +36,6 @@
+ #include <unistd.h>
+
+ #include <glib.h>
+-#include <glib/gmain.h>
+-#include <glib/gstdio.h>
+ #include <dbus/dbus-glib.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+
diff --git a/hal/patches/patch-hald_linux_addons_addon-macbookpro-backlight.c b/hal/patches/patch-hald_linux_addons_addon-macbookpro-backlight.c
new file mode 100644
index 0000000000..5388499748
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-macbookpro-backlight.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-macbookpro-backlight.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-macbookpro-backlight.c
+@@ -39,7 +39,7 @@
+ #include <pci/pci.h>
+ #include <unistd.h>
+
+-#include <glib/gmain.h>
++#include <glib.h>
+ #include <dbus/dbus-glib.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+
diff --git a/hal/patches/patch-hald_linux_addons_addon-omap-backlight.c b/hal/patches/patch-hald_linux_addons_addon-omap-backlight.c
new file mode 100644
index 0000000000..4ef43b78da
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-omap-backlight.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-omap-backlight.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-omap-backlight.c
+@@ -41,7 +41,7 @@
+ #include <fcntl.h>
+ #include <unistd.h>
+
+-#include <glib/gmain.h>
++#include <glib.h>
+ #include <dbus/dbus-glib.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+
diff --git a/hal/patches/patch-hald_linux_addons_addon-rfkill-killswitch.c b/hal/patches/patch-hald_linux_addons_addon-rfkill-killswitch.c
new file mode 100644
index 0000000000..970faa913c
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-rfkill-killswitch.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-rfkill-killswitch.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-rfkill-killswitch.c
+@@ -36,8 +36,6 @@
+ #include <unistd.h>
+
+ #include <glib.h>
+-#include <glib/gmain.h>
+-#include <glib/gstdio.h>
+ #include <dbus/dbus-glib.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+
diff --git a/hal/patches/patch-hald_linux_addons_addon-storage.c b/hal/patches/patch-hald_linux_addons_addon-storage.c
new file mode 100644
index 0000000000..404fc0e41e
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-storage.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-storage.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-storage.c
+@@ -39,7 +39,7 @@
+ #include <string.h>
+ #include <sys/ioctl.h>
+ #include <unistd.h>
+-#include <glib/gmain.h>
++#include <glib.h>
+ #include <dbus/dbus-glib.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+
diff --git a/hal/patches/patch-hald_linux_addons_addon-usb-csr.c b/hal/patches/patch-hald_linux_addons_addon-usb-csr.c
new file mode 100644
index 0000000000..85835205fa
--- /dev/null
+++ b/hal/patches/patch-hald_linux_addons_addon-usb-csr.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- hald/linux/addons/addon-usb-csr.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/addons/addon-usb-csr.c
+@@ -29,7 +29,7 @@
+ #include <string.h>
+ #include <usb.h>
+
+-#include <glib/gmain.h>
++#include <glib.h>
+ #include <dbus/dbus-glib.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+
diff --git a/hal/patches/patch-hald_linux_probing_probe-video4linux.c b/hal/patches/patch-hald_linux_probing_probe-video4linux.c
new file mode 100644
index 0000000000..0883614e77
--- /dev/null
+++ b/hal/patches/patch-hald_linux_probing_probe-video4linux.c
@@ -0,0 +1,43 @@
+$NetBSD$
+
+--- hald/linux/probing/probe-video4linux.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ hald/linux/probing/probe-video4linux.c
+@@ -30,7 +30,9 @@
+ #include <sys/types.h>
+ #include <sys/time.h>
+ #include <sys/ioctl.h>
++#ifdef HAVE_LINUX_VIDEODEV_H
+ #include <linux/videodev.h>
++#endif
+ #include <linux/videodev2.h>
+ #include <errno.h>
+ #include <fcntl.h>
+@@ -50,7 +52,9 @@ main (int argc, char *argv[])
+ int ret = -1;
+ char *udi;
+ char *device_file;
++#ifdef HAVE_LINUX_VIDEODEV_H
+ struct video_capability v1cap;
++#endif
+ struct v4l2_capability v2cap;
+ LibHalContext *ctx = NULL;
+ LibHalChangeSet *cset;
+@@ -106,7 +110,9 @@ main (int argc, char *argv[])
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ libhal_device_add_capability (ctx, udi, "video4linux.radio", &error);
+ }
+- } else {
++ }
++#ifdef HAVE_LINUX_VIDEODEV_H
++ else {
+ HAL_DEBUG (("ioctl VIDIOC_QUERYCAP failed"));
+
+ if (ioctl (fd, VIDIOCGCAP, &v1cap) == 0) {
+@@ -133,6 +139,7 @@ main (int argc, char *argv[])
+ HAL_DEBUG (("ioctl VIDIOCGCAP failed"));
+ }
+ }
++#endif
+
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ libhal_device_commit_changeset (ctx, cset, &error);
diff --git a/hal/patches/patch-hald_netbsd_devinfo__mass.c b/hal/patches/patch-hald_netbsd_devinfo__mass.c
new file mode 100644
index 0000000000..0fa1e87ea8
--- /dev/null
+++ b/hal/patches/patch-hald_netbsd_devinfo__mass.c
@@ -0,0 +1,12 @@
+$NetBSD$
+
+--- hald/netbsd/devinfo_mass.c.orig 2018-09-22 22:22:46.346651150 +0000
++++ hald/netbsd/devinfo_mass.c
+@@ -41,6 +41,7 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <paths.h>
++#include <sys/stat.h>
+ #include <unistd.h>
+
+ #include "../osspec.h"
diff --git a/hal/patches/patch-hald_netbsd_drvctl.c b/hal/patches/patch-hald_netbsd_drvctl.c
new file mode 100644
index 0000000000..a4dd73a0d6
--- /dev/null
+++ b/hal/patches/patch-hald_netbsd_drvctl.c
@@ -0,0 +1,111 @@
+$NetBSD$
+
+--- hald/netbsd/drvctl.c.orig 2020-09-28 21:35:53.183246491 +0000
++++ hald/netbsd/drvctl.c
+@@ -25,6 +25,7 @@
+ #include <sys/stat.h>
+ #include <sys/drvctlio.h>
+ #include <glib.h>
++#include <glib/gprintf.h>
+
+ #include "../osspec.h"
+ #include "../logger.h"
+@@ -46,22 +47,19 @@ static void drvctl_dev_branch(gchar *);
+ static int drvctl_fd;
+ static GIOChannel *drvctl_iochannel;
+
++#define FIFODEV "/tmp/halfifo"
+ gboolean
+ drvctl_init(void)
+ {
+- drvctl_fd = open (DRVCTLDEV, O_RDWR);
+- if (drvctl_fd == -1) {
+- HAL_INFO (("open(%s, O_RDWR) failed: %s", DRVCTLDEV, strerror(errno)));
+- return FALSE;
+- }
++ GError *rc=NULL;
+
+- drvctl_iochannel = g_io_channel_unix_new (drvctl_fd);
++ drvctl_fd = open (DRVCTLDEV, O_RDWR);
++ drvctl_iochannel = g_io_channel_new_file(FIFODEV,"r",&rc);
+ if (drvctl_iochannel == NULL) {
+- HAL_INFO (("g_io_channel_unix_new failed"));
++ HAL_INFO (("g_io_channel_new_file failed"));
+ return FALSE;
+ }
+ g_io_add_watch (drvctl_iochannel, G_IO_IN, drvctl_iochannel_data, NULL);
+-
+ return TRUE;
+ }
+
+@@ -76,37 +74,22 @@ drvctl_iochannel_data (GIOChannel *sourc
+ GIOCondition condition,
+ gpointer user_data)
+ {
+- prop_dictionary_t ev;
+- const char *event, *device;
+- int res;
+-
+- HAL_INFO (("drvctl_iochannel_data"));
+-
+- res = prop_dictionary_recv_ioctl (drvctl_fd, DRVGETEVENT, &ev);
+- if (res) {
+- HAL_WARNING (("DRVGETEVENT failed: %s", strerror(errno)));
+- return FALSE;
+- }
+-
+- if (!prop_dictionary_get_cstring_nocopy (ev, "event", &event)) {
+- HAL_WARNING (("DRVGETEVENT missing \"event\" parameter"));
+- goto done;
+- }
+- if (!prop_dictionary_get_cstring_nocopy (ev, "device", &device)) {
+- HAL_WARNING (("DRVGETEVENT missing \"device\" parameter"));
+- goto done;
+- }
+-
+- HAL_INFO (("DRVGETEVENT event=%s device=%s", event, device));
+-
+- if (strcmp (event, "device-attach") == 0) {
+- drvctl_dev_add (device);
+- } else {
+- drvctl_dev_remove (device);
+- }
+-
+-done:
+- prop_object_release(ev);
++ GError *rc=NULL;
++ gint i;
++ struct timeval timeout={1,0};
++ gchar **vect,*line;
++
++ g_io_channel_read_line(source,&line,NULL,NULL,&rc);
++ if (!line)
++ return TRUE;
++ g_strstrip(line);
++ vect=g_strsplit(line," ",3);
++ if (! strcmp (vect[0], "device-attach"))
++ drvctl_dev_add (vect[1]);
++ else if (! strcmp (vect[0], "device-detach"))
++ drvctl_dev_remove (vect[1]);
++ g_strfreev(vect);
++ g_free(line);
+ return TRUE;
+ }
+
+@@ -179,6 +162,7 @@ drvctl_list(const gchar *name, struct de
+ }
+ if (children != laa->l_children)
+ HAL_WARNING (("DRVLISTDEV/3 expected %d children, got %d", children, laa->l_childname));
++ return 0;
+ }
+
+ gboolean
+@@ -187,7 +171,7 @@ drvctl_find_device(const gchar *devnode,
+ prop_dictionary_t command_dict;
+ prop_dictionary_t args_dict;
+ prop_dictionary_t results_dict;
+- int err;
++ signed char err;
+
+ command_dict = prop_dictionary_create ();
+ args_dict = prop_dictionary_create ();
diff --git a/hal/patches/patch-libhal_libhal.c b/hal/patches/patch-libhal_libhal.c
new file mode 100644
index 0000000000..d5bc719699
--- /dev/null
+++ b/hal/patches/patch-libhal_libhal.c
@@ -0,0 +1,15 @@
+$NetBSD$
+
+--- libhal/libhal.c.orig 2009-08-24 12:42:30.000000000 +0000
++++ libhal/libhal.c
+@@ -4121,8 +4121,10 @@ out:
+ static void
+ libhal_changeset_append (LibHalChangeSet *changeset, LibHalChangeSetElement *elem)
+ {
++#if !defined(__SUNPRO_C)
+ LIBHAL_CHECK_PARAM_VALID(changeset, "*changeset", (void) NULL );
+ LIBHAL_CHECK_PARAM_VALID(elem, "*elem", (void) NULL);
++#endif
+
+ if (changeset->head == NULL) {
+ changeset->head = elem;
diff --git a/hal/patches/patch-policy_Makefile.am b/hal/patches/patch-policy_Makefile.am
new file mode 100644
index 0000000000..18c9b592a3
--- /dev/null
+++ b/hal/patches/patch-policy_Makefile.am
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- policy/Makefile.am.orig 2009-01-21 00:14:28.000000000 +0000
++++ policy/Makefile.am
+@@ -20,7 +20,7 @@ check:
+ echo -n "Validate PolicyKit policy in $$f : "; \
+ $(POLKIT_POLICY_FILE_VALIDATE) $(srcdir)/$$f ; \
+ ret=$$?; \
+- if [ "$$ret" == "0" ]; \
++ if [ "$$ret" = "0" ]; \
+ then \
+ echo ok; \
+ else \
diff --git a/hal/patches/patch-tools_Makefile.am b/hal/patches/patch-tools_Makefile.am
new file mode 100644
index 0000000000..3e0a5a28c5
--- /dev/null
+++ b/hal/patches/patch-tools_Makefile.am
@@ -0,0 +1,30 @@
+$NetBSD$
+
+--- tools/Makefile.am.orig 2009-11-09 15:33:53.000000000 +0000
++++ tools/Makefile.am
+@@ -8,8 +8,11 @@ endif
+ if HALD_COMPILE_FREEBSD
+ SUBDIRS += freebsd
+ endif
++if HALD_COMPILE_NETBSD
++SUBDIRS += netbsd
++endif
+
+-DIST_SUBDIRS = freebsd linux
++DIST_SUBDIRS = freebsd linux netbsd
+
+ AM_CPPFLAGS = \
+ -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
+@@ -80,7 +83,11 @@ if BUILD_KEYMAPS
+
+ if HAVE_GPERF
+ hal-setup-keymap-keys.txt: @LINUX_INPUT_H@
+- awk '/^#define.*KEY_/ { if ($$2 != "KEY_MAX") { print substr($$2, 5) } }' < $< > $@
++ if test -f /usr/include/linux/input-event-codes.h; then \
++ awk '/^#define.*KEY_/ { if ($$2 != "KEY_MAX") { print substr($$2, 5) } }' < /usr/include/linux/input-event-codes.h > $@; \
++ else \
++ awk '/^#define.*KEY_/ { if ($$2 != "KEY_MAX") { print substr($$2, 5) } }' < $< > $@; \
++ fi
+
+ hal-setup-keymap-hash-name.gperf: hal-setup-keymap-keys.txt
+ awk 'BEGIN{ print "struct key { const char* name; unsigned short id; };"; print "%null-strings"; print "%%";} { print $$1 ", KEY_" $$1 }' < $< > $@
diff --git a/hal/patches/patch-tools_hal-luks-setup b/hal/patches/patch-tools_hal-luks-setup
new file mode 100644
index 0000000000..7c3c463312
--- /dev/null
+++ b/hal/patches/patch-tools_hal-luks-setup
@@ -0,0 +1,22 @@
+$NetBSD$
+
+--- tools/hal-luks-setup.orig 2008-08-10 13:50:10.000000000 +0000
++++ tools/hal-luks-setup
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/bin/sh
+
+ # Copyright (C) 2005 W. Michael Petullo <mike%flyn.org@localhost>
+ # Copyright (C) 2006 David Zeuthen <davidz%redhat.com@localhost>
+@@ -44,9 +44,9 @@ if [ -n "$HAL_METHOD_INVOKED_BY_SYSTEMBU
+ fi
+
+ IS_HOTPLUGGABLE=`hal-get-property --udi $HAL_PROP_BLOCK_STORAGE_DEVICE --key storage.hotpluggable`
+-if [ "$IS_HOTPLUGGABLE" == "true" ] ; then
++if [ "$IS_HOTPLUGGABLE" = "true" ] ; then
+ ACTION="org.freedesktop.hal.storage.crypto-setup-removable"
+-elif [ "$IS_HOTPLUGGABLE" == "false" ] ; then
++elif [ "$IS_HOTPLUGGABLE" = "false" ] ; then
+ ACTION="org.freedesktop.hal.storage.crypto-setup-fixed"
+ else
+ unknown_error
diff --git a/hal/patches/patch-tools_hal-luks-teardown b/hal/patches/patch-tools_hal-luks-teardown
new file mode 100644
index 0000000000..1b7e274a34
--- /dev/null
+++ b/hal/patches/patch-tools_hal-luks-teardown
@@ -0,0 +1,22 @@
+$NetBSD$
+
+--- tools/hal-luks-teardown.orig 2008-08-10 13:50:10.000000000 +0000
++++ tools/hal-luks-teardown
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/bin/sh
+
+ # Copyright (C) 2005 W. Michael Petullo <mike%flyn.org@localhost>
+ # Copyright (C) 2006 David Zeuthen <davidz%redhat.com@localhost>
+@@ -47,9 +47,9 @@ fi
+ # TODO: this is a little sketchy; we should check for hal-storage-crypto-teardown-others?
+ #
+ IS_HOTPLUGGABLE=`hal-get-property --udi $HAL_PROP_BLOCK_STORAGE_DEVICE --key storage.hotpluggable`
+-if [ "$IS_HOTPLUGGABLE" == "true" ] ; then
++if [ "$IS_HOTPLUGGABLE" = "true" ] ; then
+ ACTION="org.freedesktop.hal.storage.crypto-setup-removable"
+-elif [ "$IS_HOTPLUGGABLE" == "false" ] ; then
++elif [ "$IS_HOTPLUGGABLE" = "false" ] ; then
+ ACTION="org.freedesktop.hal.storage.crypto-setup-fixed"
+ else
+ unknown_error
diff --git a/hal/patches/patch-tools_hal-storage-mount.c b/hal/patches/patch-tools_hal-storage-mount.c
new file mode 100644
index 0000000000..9111f77992
--- /dev/null
+++ b/hal/patches/patch-tools_hal-storage-mount.c
@@ -0,0 +1,134 @@
+$NetBSD$
+
+--- tools/hal-storage-mount.c.orig 2009-05-27 20:26:03.000000000 +0000
++++ tools/hal-storage-mount.c
+@@ -31,7 +31,7 @@
+ #include <string.h>
+ #include <glib.h>
+ #include <glib/gstdio.h>
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+ #include <fstab.h>
+ #include <sys/param.h>
+ #include <sys/ucred.h>
+@@ -41,6 +41,14 @@
+ #elif sun
+ #include <sys/mnttab.h>
+ #include <sys/vfstab.h>
++#elif __NetBSD__
++#include <fstab.h>
++#include <sys/param.h>
++#include <sys/mount.h>
++#include <fcntl.h>
++#include <sys/stat.h>
++#include <unistd.h>
++#include <pwd.h>
+ #else
+ #include <mntent.h>
+ #endif
+@@ -54,10 +62,14 @@
+
+ #include "hal-storage-shared.h"
+
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__DragonFly__)
+ #define MOUNT "/sbin/mount"
+ #define MOUNT_OPTIONS "noexec,nosuid"
+ #define MOUNT_TYPE_OPT "-t"
++#elif __NetBSD__
++#define MOUNT "/sbin/mount"
++#define MOUNT_OPTIONS "noexec,nosuid,nodev"
++#define MOUNT_TYPE_OPT "-t"
+ #elif sun
+ #define MOUNT "/sbin/mount"
+ #define MOUNT_OPTIONS "noexec,nosuid"
+@@ -421,7 +433,7 @@ device_is_mounted (const char *device, c
+ static const char *
+ map_fstype (const char *fstype)
+ {
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__DragonFly__)
+ if (! strcmp (fstype, "iso9660"))
+ return "cd9660";
+ else if (! strcmp (fstype, "ext2"))
+@@ -430,6 +442,13 @@ map_fstype (const char *fstype)
+ return "ext2fs";
+ else if (! strcmp (fstype, "vfat"))
+ return "msdosfs";
++#elif __NetBSD__
++ if (! strcmp (fstype, "iso9660"))
++ return "cd9660";
++ else if (! strcmp (fstype, "ext2"))
++ return "ext2fs";
++ else if (! strcmp (fstype, "vfat"))
++ return "msdos";
+ #elif sun
+ if (! strcmp (fstype, "iso9660"))
+ return "hsfs";
+@@ -471,11 +490,16 @@ handle_mount (LibHalContext *hal_ctx,
+ gboolean explicit_mount_point_given;
+ gboolean found_alternative_fstype = FALSE;
+ const char *end;
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__NetBSD__)
+ struct passwd *pw;
+ uid_t calling_uid;
+ gid_t calling_gid;
+ #endif
++ gboolean have_rump = FALSE;
++#ifdef __NetBSD__
++ char *rump_cmd;
++ struct stat st;
++#endif
+ const char *label;
+ const char *uuid;
+
+@@ -646,8 +670,6 @@ handle_mount (LibHalContext *hal_ctx,
+ /* construct arguments to mount */
+ na = 0;
+
+- args[na++] = MOUNT;
+-
+ if (strlen (mount_fstype) > 0) {
+ mount_do_fstype = (char *) map_fstype (mount_fstype);
+ if (volume && strcmp(mount_do_fstype, mount_fstype) == 0) {
+@@ -797,8 +819,28 @@ handle_mount (LibHalContext *hal_ctx,
+ }
+ }
+
+- args[na++] = MOUNT_TYPE_OPT;
+- args[na++] = mount_do_fstype;
++#ifdef __NetBSD__
++ rump_cmd = g_strdup_printf ("/usr/sbin/rump_%s", mount_do_fstype);
++ if (stat (rump_cmd, &st) == 0) {
++ int rump_fd = open ("/dev/puffs", O_RDONLY);
++ if (rump_fd >= 0) {
++ have_rump = TRUE;
++ close (rump_fd);
++ }
++ }
++
++ /* XXX rump_* option handling is different, disable for now */
++ have_rump = FALSE;
++
++ if (have_rump == TRUE)
++ args[na++] = rump_cmd;
++ else
++#endif
++ {
++ args[na++] = MOUNT;
++ args[na++] = MOUNT_TYPE_OPT;
++ args[na++] = mount_do_fstype;
++ }
+
+ args[na++] = "-o";
+ #ifdef HAVE_UMOUNT_HAL
+@@ -869,7 +911,7 @@ handle_mount (LibHalContext *hal_ctx,
+ unknown_error ("Cannot create mount directory");
+ }
+
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__NetBSD__)
+ calling_uid = (uid_t) strtol (invoked_by_uid, (char **) NULL, 10);
+ pw = getpwuid (calling_uid);
+ if (pw != NULL) {
diff --git a/hal/patches/patch-tools_hal-storage-shared.c b/hal/patches/patch-tools_hal-storage-shared.c
new file mode 100644
index 0000000000..dc906460e5
--- /dev/null
+++ b/hal/patches/patch-tools_hal-storage-shared.c
@@ -0,0 +1,138 @@
+$NetBSD$
+
+--- tools/hal-storage-shared.c.orig 2008-08-10 13:50:10.000000000 +0000
++++ tools/hal-storage-shared.c
+@@ -31,7 +31,7 @@
+ #include <string.h>
+ #include <glib.h>
+ #include <glib/gstdio.h>
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+ #include <fstab.h>
+ #include <sys/param.h>
+ #include <sys/ucred.h>
+@@ -42,6 +42,10 @@
+ #include <fcntl.h>
+ #include <sys/mnttab.h>
+ #include <sys/vfstab.h>
++#elif __NetBSD__
++#include <fstab.h>
++#include <sys/param.h>
++#include <sys/mount.h>
+ #else
+ #include <mntent.h>
+ #endif
+@@ -53,20 +57,27 @@
+
+ #include "hal-storage-shared.h"
+
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+ struct mtab_handle
+ {
+ struct statfs *mounts;
+ int n_mounts;
+ int iter;
+ };
++#elif __NetBSD__
++struct mtab_handle
++{
++ struct statvfs *mounts;
++ int n_mounts;
++ int iter;
++};
+ #endif
+
+
+ gboolean
+ mtab_open (gpointer *handle)
+ {
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+ struct mtab_handle *mtab;
+
+ mtab = g_new0 (struct mtab_handle, 1);
+@@ -90,7 +101,7 @@ mtab_open (gpointer *handle)
+ char *
+ mtab_next (gpointer handle, char **mount_point)
+ {
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+ struct mtab_handle *mtab = handle;
+
+ if (mtab->iter < mtab->n_mounts) {
+@@ -131,7 +142,7 @@ mtab_next (gpointer handle, char **mount
+ void
+ mtab_close (gpointer handle)
+ {
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+ g_free (handle);
+ #else
+ fclose (handle);
+@@ -143,7 +154,7 @@ mtab_close (gpointer handle)
+ gboolean
+ fstab_open (gpointer *handle)
+ {
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+ return setfsent () == 1;
+ #elif sun
+ *handle = fopen (VFSTAB, "r");
+@@ -157,7 +168,7 @@ fstab_open (gpointer *handle)
+ char *
+ fstab_next (gpointer handle, char **mount_point)
+ {
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+ struct fstab *fstab;
+
+ fstab = getfsent ();
+@@ -188,14 +199,16 @@ fstab_next (gpointer handle, char **moun
+ void
+ fstab_close (gpointer handle)
+ {
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+ endfsent ();
+ #else
+ fclose (handle);
+ #endif
+ }
+
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__DragonFly__)
++#define UMOUNT "/sbin/umount"
++#elif __NetBSD__
+ #define UMOUNT "/sbin/umount"
+ #elif sun
+ #define UMOUNT "/sbin/umount"
+@@ -467,7 +480,7 @@ line_found:
+ /* construct arguments to /bin/umount */
+ na = 0;
+ args[na++] = UMOUNT;
+-#ifndef __FreeBSD__
++#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__)
+ if (option_lazy)
+ args[na++] = "-l";
+ #endif
+@@ -625,13 +638,18 @@ try_open_excl_again:
+ /* construct arguments to EJECT_PROGRAM (e.g. /usr/bin/eject) */
+ na = 0;
+ args[na++] = EJECT_PROGRAM;
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__DragonFly__)
+ args[na++] = "-f";
+ args[na++] = (char *) device;
+ if (closetray)
+ args[na++] = "close";
+ else
+ args[na++] = "eject";
++#elif __NetBSD__
++ args[na++] = "-f";
++ if (closetray)
++ args[na++] = "-l";
++ args[na++] = (char *) device;
+ #else
+ if (closetray) {
+ args[na++] = "-t";
diff --git a/hal/patches/patch-tools_hal-storage-unmount.c b/hal/patches/patch-tools_hal-storage-unmount.c
new file mode 100644
index 0000000000..ed4ed013b8
--- /dev/null
+++ b/hal/patches/patch-tools_hal-storage-unmount.c
@@ -0,0 +1,23 @@
+$NetBSD$
+
+--- tools/hal-storage-unmount.c.orig 2008-08-10 13:50:10.000000000 +0000
++++ tools/hal-storage-unmount.c
+@@ -31,13 +31,17 @@
+ #include <string.h>
+ #include <glib.h>
+ #include <glib/gstdio.h>
+-#ifdef __FreeBSD__
++#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+ #include <fstab.h>
+ #include <sys/param.h>
+ #include <sys/ucred.h>
+ #include <sys/mount.h>
+ #include <limits.h>
+ #include <pwd.h>
++#elif __NetBSD__
++#include <fstab.h>
++#include <sys/param.h>
++#include <sys/mount.h>
+ #elif sun
+ #include <fcntl.h>
+ #include <sys/mnttab.h>
diff --git a/hal/patches/patch-tools_hal-system-power-pmu.c b/hal/patches/patch-tools_hal-system-power-pmu.c
new file mode 100644
index 0000000000..e7d0dde040
--- /dev/null
+++ b/hal/patches/patch-tools_hal-system-power-pmu.c
@@ -0,0 +1,37 @@
+$NetBSD$
+
+--- tools/hal-system-power-pmu.c.orig 2009-05-12 12:25:58.000000000 +0000
++++ tools/hal-system-power-pmu.c
+@@ -55,6 +55,10 @@ pmac_sleep (void)
+ {
+ #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
+ return FALSE; /* FIXME implement */
++#elif __NetBSD__
++ return FALSE; /* FIXME implement */
++#elif __DragonFly__
++ return FALSE; /* FIXME implement */
+ #elif sun
+ return FALSE; /* FIXME implement */
+ #elif __GNU__
+@@ -92,6 +96,10 @@ pmac_get_lcd_brightness (int *val)
+ {
+ #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
+ return FALSE; /* FIXME implement */
++#elif __NetBSD__
++ return FALSE; /* FIXME implement */
++#elif __DragonFly__
++ return FALSE; /* FIXME implement */
+ #elif sun
+ return FALSE; /* FIXME implement */
+ #elif __GNU__
+@@ -129,6 +137,10 @@ pmac_set_lcd_brightness (int val)
+ {
+ #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
+ return FALSE; /* FIXME implement */
++#elif __NetBSD__
++ return FALSE; /* FIXME implement */
++#elif __DragonFly__
++ return FALSE; /* FIXME implement */
+ #elif sun
+ return FALSE; /* FIXME implement */
+ #elif __GNU__
diff --git a/hal/patches/patch-tools_linux_Makefile.am b/hal/patches/patch-tools_linux_Makefile.am
new file mode 100644
index 0000000000..2807099f5b
--- /dev/null
+++ b/hal/patches/patch-tools_linux_Makefile.am
@@ -0,0 +1,12 @@
+$NetBSD$
+
+--- tools/linux/Makefile.am.orig 2009-07-15 06:52:51.000000000 +0000
++++ tools/linux/Makefile.am
+@@ -1,6 +1,6 @@
+ ## Process this file with automake to produce Makefile.in
+
+-udevrulesdir = $(udev_prefix)/udev/rules.d
++udevrulesdir = $(PREFIX)/share/examples/hal
+ udevrules_DATA = 90-hal.rules
+
+
Home |
Main Index |
Thread Index |
Old Index