Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Feb 2013 20:30:08 +0100
From:      Hans Petter Selasky <hselasky@c2i.net>
To:        edwin@freebsd.org
Cc:        freebsd-ports-bugs@freebsd.org, Juergen Lock <nox@jelal.kn-bremen.de>, Jan Beich <jbeich@tormail.org>
Subject:   Re: ports/175860: multimedia/webcamd: expose Wacom via HAL for hotplugging
Message-ID:  <201302052030.08377.hselasky@c2i.net>
In-Reply-To: <201302051200.r15C0DKw030241@freefall.freebsd.org>
References:  <201302051200.r15C0DKw030241@freefall.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
--Boundary-00=_A3VEREGaeYp2uWZ
Content-Type: Text/Plain;
  charset="iso-8859-15"
Content-Transfer-Encoding: 7bit

On Tuesday 05 February 2013 13:00:13 edwin@freebsd.org wrote:
> Synopsis: multimedia/webcamd: expose Wacom via HAL for hotplugging
> 
> Responsible-Changed-From-To: freebsd-ports-bugs->hselasky
> Responsible-Changed-By: edwin
> Responsible-Changed-When: Tue Feb 5 12:00:13 UTC 2013
> Responsible-Changed-Why:
> Over to maintainer (via the GNATS Auto Assign Tool)
> 
> http://www.freebsd.org/cgi/query-pr.cgi?pr=175860

The attached patch updates webcamd 3.9.0.4.

HOWTO:

1)
This file needs to be installed:
/usr/ports/x11-drivers/input-wacom/work/xf86-input-wacom-0.15.0/conf/wacom.fdi
At:
/usr/local/share/hal/fdi/policy/10osvendor/wacom.fdi

Possibly we could define the "x11_driver" key in webcamd itself ?

2)
xorg-server must be compiled with HAL support.

3)
/etc/X11/xorg.conf must contain this:

Section "ServerFlags"
    Option "AutoAddDevices" "true"
    Option "AutoEnableDevices" "true"
    Option "AllowEmptyInput" "false"
EndSection

4)
Restart Xorg and hald

--HPS

--Boundary-00=_A3VEREGaeYp2uWZ
Content-Type: text/x-patch;
  charset="iso-8859-15";
  name="wacom.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
	filename="wacom.diff"

Index: webcamd.c
===================================================================
--- webcamd.c	(revision 2570)
+++ webcamd.c	(revision 2571)
@@ -94,6 +94,7 @@
 static int do_fork = 0;
 static int do_realtime = 1;
 static struct pidfh *local_pid = NULL;
+static char *d_desc;
 static gid_t gid;
 static uid_t uid;
 static int gid_found;
@@ -707,12 +708,12 @@
 	linux_init();
 
 	if (vtuner_client == 0) {
-		if (usb_linux_probe_p(&u_unit, &u_addr, &u_index) < 0)
+		if (usb_linux_probe_p(&u_unit, &u_addr, &u_index, &d_desc) < 0)
 			v4b_errx(1, "Cannot find USB device");
 	}
 	if (vtuner_server == 0) {
 		if (webcamd_hal_register)
-			hal_init(u_unit, u_addr, u_index);
+			hal_init(u_unit, u_addr, u_index, d_desc);
 
 		v4b_create(u_videodev);
 
Index: webcamd_hal.c
===================================================================
--- webcamd_hal.c	(revision 2570)
+++ webcamd_hal.c	(revision 2571)
@@ -40,7 +40,7 @@
 #ifndef HAVE_HAL
 
 void
-hal_init(int bus, int addr, int iface)
+hal_init(int bus, int addr, int iface, const char *desc)
 {
 	return;
 }
@@ -61,10 +61,12 @@
 static LibHalContext *hal_ctx;
 static DBusConnection *hal_conn;
 static char *hal_dev;
+static char *hal_desc;
+static int hal_iface;
 static int hal_dvb_index;
 
 void
-hal_init(int bus, int addr, int iface)
+hal_init(int bus, int addr, int iface, const char *desc)
 {
 	char **ppdev;
 	int n;
@@ -77,6 +79,13 @@
 		printf("Waiting for DBUS connection.\n");
 	}
 
+	if (desc == NULL)
+		desc = "Unknown";
+
+	hal_desc = strdup(desc);
+	if (hal_desc == NULL)
+		return;
+
 	hal_ctx = libhal_ctx_new();
 	if (hal_ctx == NULL)
 		return;
@@ -109,6 +118,7 @@
 					continue;
 
 				hal_dev = strdup(ppdev[n]);
+				hal_iface = iface;
 				break;
 			}
 		}
@@ -254,6 +264,56 @@
 		free(pdvb);
 
 		hal_dvb_index++;
+	} else if (!strncmp(devname, "input/event",
+	    sizeof("input_event") - 1)) {
+
+		char *pinput = NULL;
+		char *pnew;
+
+		asprintf(&pinput, "%s_if%d_logicaldev_input",
+		    hal_dev, hal_iface);
+
+		if (pinput == NULL)
+			return;
+
+		if (libhal_device_exists(hal_ctx, pinput, NULL) == 0) {
+			pnew = libhal_new_device(hal_ctx, NULL);
+			if (pnew == NULL) {
+				free(pinput);
+				return;
+			}
+		} else {
+			pnew = pinput;
+		}
+
+		cset = libhal_device_new_changeset(pnew);
+		if (cset == NULL) {
+			if (pnew != pinput)
+				free(pnew);
+			free(pinput);
+		}
+
+		libhal_changeset_set_property_string(cset, "info.category", "input");
+		libhal_changeset_set_property_string(cset, "info.parent", hal_dev);
+		libhal_changeset_set_property_string(cset, "info.product", hal_desc);
+		libhal_changeset_set_property_string(cset, "info.subsystem", "input");
+		libhal_changeset_set_property_string(cset, "input.device", devpath);
+		libhal_changeset_set_property_string(cset, "input.originating_device", hal_dev);
+		libhal_changeset_set_property_string(cset, "input.product", hal_desc);
+		libhal_changeset_set_property_string(cset, "linux.device_file", devpath);
+		libhal_changeset_set_property_int(cset, "linux.hotplug_type", 2);
+		libhal_changeset_set_property_string(cset, "info.subsystem", "input");
+		libhal_changeset_set_property_string(cset, "linux.sysfs_path", devpath);
+
+		libhal_device_add_capability(hal_ctx, pnew, "input", NULL);
+		libhal_device_commit_changeset(hal_ctx, cset, NULL);
+		libhal_device_free_changeset(cset);
+
+		if (pnew != pinput) {
+			libhal_device_commit_to_gdl(hal_ctx, pnew, pinput, NULL);
+			free(pnew);
+		}
+		free(pinput);
 	}
 }
 
Index: webcamd_hal.h
===================================================================
--- webcamd_hal.h	(revision 2570)
+++ webcamd_hal.h	(revision 2571)
@@ -26,7 +26,7 @@
 #ifndef _WEBCAMD_HAL_H_
 #define	_WEBCAMD_HAL_H_
 
-void	hal_init(int bus, int addr, int iface);
+void	hal_init(int bus, int addr, int iface, const char *desc);
 void	hal_add_device(const char *devname);
 
 #endif					/* _WEBCAMD_HAL_H_ */
Index: kernel/linux_usb.c
===================================================================
--- kernel/linux_usb.c	(revision 2570)
+++ kernel/linux_usb.c	(revision 2571)
@@ -281,8 +281,19 @@
  *
  * This function is the FreeBSD probe and attach callback.
  *------------------------------------------------------------------------*/
+static char *
+usb_linux_probe_get_desc(struct libusb20_device *pdev)
+{
+	const char *ptr = libusb20_dev_get_desc(pdev);
+
+	if (ptr == NULL)
+		return (strdup("Unknown"));
+
+	return (strdup(ptr));
+}
+
 int
-usb_linux_probe_p(int *p_bus, int *p_addr, int *p_index)
+usb_linux_probe_p(int *p_bus, int *p_addr, int *p_index, char **pp_desc)
 {
 	const struct usb_device_id *id;
 	struct usb_linux_softc *sc;
@@ -387,6 +398,7 @@
 	*p_bus = libusb20_dev_get_bus_number(pdev);
 	*p_addr = libusb20_dev_get_address(pdev);
 	*p_index = index_copy;
+	*pp_desc = usb_linux_probe_get_desc(pdev);
 
 	if (pidfile_create(*p_bus, *p_addr, index_copy)) {
 		fprintf(stderr, "Webcamd is already running for "
@@ -434,6 +446,9 @@
 	libusb20_be_dequeue_device(pbe, pdev);
 	libusb20_be_free(pbe);
 
+	/* detach kernel driver, if any */
+	libusb20_dev_detach_kernel_driver(pdev, i);
+
 	return (device_index);
 }
 
Index: kernel/linux_usb.h
===================================================================
--- kernel/linux_usb.h	(revision 2570)
+++ kernel/linux_usb.h	(revision 2571)
@@ -638,7 +638,7 @@
 int	usb_deregister(struct usb_driver *drv);
 
 struct usb_linux_softc *usb_linux2usb(int fd);
-int	usb_linux_probe_p(int *p_bus, int *p_addr, int *p_index);
+int	usb_linux_probe_p(int *p_bus, int *p_addr, int *p_index, char **ppdesc);
 int	usb_linux_detach(int fd);
 int	usb_linux_suspend(int fd);
 int	usb_linux_resume(int fd);

--Boundary-00=_A3VEREGaeYp2uWZ--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302052030.08377.hselasky>