Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Jan 2010 09:33:29 +1300 (NZDT)
From:      Andrew Thompson <thompsa@FreeBSD.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        marcus@FreeBSD.org
Subject:   ports/142988: [patch] incorrect hal properties for usb (2) interfaces
Message-ID:  <20100119203329.5B74211432@citylink.fud.org.nz>
Resent-Message-ID: <201001192040.o0JKe7oJ024292@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         142988
>Category:       ports
>Synopsis:       [patch] incorrect hal properties for usb (2) interfaces
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jan 19 20:40:07 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Andrew Thompson
>Release:        FreeBSD 9.0-CURRENT amd64
>Organization:
>Environment:
System: FreeBSD pea.fud.org.nz 9.0-CURRENT FreeBSD 9.0-CURRENT #3 r201070:201071M: Mon Dec 28 14:38:56 NZDT 2009     thompsa@pea.fud.org.nz:/usr/obj/usr/home/thompsa/scratch/fbsvn/head/sys/PEA  amd64


	
>Description:
	USB interfaces in hal should have usb.X for properties, compared to
	usb_device for the parent. hf-usb.c is correct but hf-usb2.c is not.

>How-To-Repeat:
	
>Fix:

--- files/patch-hald_freebsd_hf-usb2.c	2009-11-29 09:06:02.000000000 +1300
+++ files/patch-hald_freebsd_hf-usb2.c	2010-01-21 11:22:28.000000000 +1300
@@ -1,6 +1,6 @@
---- hald/freebsd/hf-usb2.c.orig	2009-11-21 19:57:40.000000000 -0500
-+++ hald/freebsd/hf-usb2.c	2009-11-21 19:58:07.000000000 -0500
-@@ -0,0 +1,312 @@
+--- hald/freebsd/hf-usb2.c.orig	2010-01-21 11:13:33.000000000 +1300
++++ hald/freebsd/hf-usb2.c	2010-01-21 11:22:12.000000000 +1300
+@@ -0,0 +1,296 @@
 +/***************************************************************************
 + * CVSID: $Id$
 + *
@@ -45,22 +45,6 @@
 +static struct libusb20_backend *hf_usb2_be = NULL;
 +
 +static void
-+hf_usb2_copy_parent (HalDevice *parent,
-+		     const char *key,
-+		     gpointer user_data)
-+{
-+  HalDevice *device;
-+
-+  g_return_if_fail(HAL_IS_DEVICE(parent));
-+  g_return_if_fail(HAL_IS_DEVICE(user_data));
-+
-+  device = HAL_DEVICE(user_data);
-+
-+  if (! strncmp(key, "usb_device.", strlen("usb_device.")))
-+    hal_device_copy_property(parent, key, device, key);
-+}
-+
-+static void
 +hf_usb2_probe_interfaces(HalDevice *parent)
 +{
 +  int num_interfaces;
@@ -82,9 +66,9 @@
 +
 +      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");
++      hal_device_merge_with_rewrite(device, parent, "usb.", "usb_device.");
 +
 +      if (hf_device_preprobe(device))
 +        {



And the complete patch-hald_freebsd_hf-usb2.c file.


--- hald/freebsd/hf-usb2.c.orig	2010-01-21 11:13:33.000000000 +1300
+++ hald/freebsd/hf-usb2.c	2010-01-21 11:22:12.000000000 +1300
@@ -0,0 +1,296 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hf-usb.c : USB support
+ *
+ * Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libusb20.h>
+
+#include "../logger.h"
+#include "../osspec.h"
+
+#include "hf-usb.h"
+#include "hf-usb2.h"
+#include "hf-devtree.h"
+#include "hf-util.h"
+
+static struct libusb20_backend *hf_usb2_be = NULL;
+
+static void
+hf_usb2_probe_interfaces(HalDevice *parent)
+{
+  int num_interfaces;
+  int i;
+
+  g_return_if_fail(HAL_IS_DEVICE(parent));
+
+  if (hal_device_property_get_bool(parent, "info.ignore"))
+    return;
+
+  num_interfaces = hal_device_property_get_int(parent,
+    "usb_device.num_interfaces");
+
+  for (i = 0; i < num_interfaces; i++)
+    {
+      HalDevice *device;
+
+      device = hf_device_new(parent);
+
+      hal_device_property_set_string(device, "info.subsystem", "usb");
+      hal_device_property_set_int(device, "usb.interface.number", i);
+      hal_device_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", NULL);
+	      else if (! strcmp(driver, "ums") || ! strcmp(driver, "atp"))
+                {
+                  hf_device_set_input(device, "mouse", devname);
+	          hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL);
+	        }
+	      else if (! strcmp(driver, "uhid"))
+                {
+                  hal_device_property_set_string(device, "info.category",
+                    "hiddev");
+	          hal_device_add_capability(device, "hiddev");
+	          hf_device_property_set_string_printf(device, "hiddev.device",
+                    "/dev/%s", devname);
+	          hal_device_copy_property(device, "info.product", device,
+                    "hiddev.product");
+	          hf_runner_run_sync(device, 0, "hald-probe-hiddev", NULL);
+	        }
+	      else if (! strcmp(driver, "ldev"))
+                {
+                  /* Linux driver (webcam) */
+
+	          /*
+                   * XXX This is a hack.  Currently, all ldev devices are
+		   * webcams.  That may not always be the case.  Hopefully,
+		   * when other Linux driver support is added, there will be
+		   * a sysctl or some other way to determine device class.
+	           */
+                  hf_usb_add_webcam_properties(device);
+	        }
+	      else if (! strcmp(driver, "pwc"))
+                {
+                  /* Phillips Web Cam */
+                  hf_usb_add_webcam_properties(device);
+	        }
+	    }
+
+	  hf_usb_device_compute_udi(device);
+	  hf_device_add(device);
+	}
+    }
+}
+
+static void
+hf_usb2_probe_device (HalDevice *parent, int bus, int addr)
+{
+  HalDevice *device;
+
+  g_return_if_fail(HAL_IS_DEVICE(parent));
+
+  device = hf_device_new(parent);
+
+  hal_device_property_set_string(device, "info.subsystem", "usb_device");
+  hal_device_property_set_int(device, "usb_device.bus_number", bus);
+  hal_device_property_set_int(device, "usb_device.level_number", addr - 1);
+  hal_device_property_set_int(device, "usb_device.port_number", addr);
+
+  if (hf_device_preprobe(device))
+    {
+      hf_runner_run_sync(device, 0, "hald-probe-usb2-device", NULL);
+      hf_usb_device_compute_udi(device);
+
+      hf_device_add(device);
+    }
+  else
+    return;
+
+  hf_usb2_probe_interfaces(device);
+}
+
+static void
+hf_usb2_privileged_init (void)
+{
+  hf_usb2_be = libusb20_be_alloc_default();
+  if (hf_usb2_be == NULL)
+    HAL_INFO(("unable to open USB backend: %s", g_strerror(errno)));
+}
+
+static void
+hf_usb2_probe (void)
+{
+  struct libusb20_device *pdev = NULL;
+
+  if (hf_usb2_be == NULL)
+    return;
+
+  while ((pdev = libusb20_be_device_foreach(hf_usb2_be, pdev)))
+    {
+      HalDevice *parent;
+      int bus, addr;
+
+      bus = libusb20_dev_get_bus_number(pdev);
+      addr = libusb20_dev_get_address(pdev);
+
+      if (addr == 1)
+        parent = hf_devtree_find_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, "info.bus",
+	  HAL_PROPERTY_TYPE_STRING, "usb_device", NULL);
+      if (! parent || hal_device_property_get_bool(parent, "info.ignore"))
+        continue;
+
+      hf_usb2_probe_device(parent, bus, addr);
+    }
+
+  libusb20_be_free(hf_usb2_be);
+  hf_usb2_be = NULL;
+}
+
+static gboolean
+hf_usb2_devd_add (const char *name,
+		  GHashTable *params,
+		  GHashTable *at,
+		  const char *parent)
+{
+  HalDevice *parent_device;
+  int bus, addr, pbus, paddr;
+
+  if (! parent)
+    return FALSE;
+
+  if (strncmp(name, "ugen", strlen("ugen")) &&
+      ! strncmp(parent, "uhub", strlen("uhub")))
+    return TRUE;
+  else 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, "info.bus",
+    HAL_PROPERTY_TYPE_STRING, "usb_device", NULL);
+
+  if (parent_device && ! hal_device_property_get_bool(parent_device,
+      "info.ignore"))
+    {
+      hf_usb2_probe_device(parent_device, bus, addr);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+hf_usb2_devd_remove (const char *name,
+		     GHashTable *params,
+		     GHashTable *at,
+		     const char *parent)
+{
+  HalDevice *device;
+  int bus, addr;
+
+  if (strncmp(name, "ugen", strlen("ugen")))
+    return FALSE;
+
+  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, "info.bus",
+    HAL_PROPERTY_TYPE_STRING, "usb_device", NULL);
+
+  if (device)
+    {
+      hf_device_remove_tree(device);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+hf_usb2_devd_notify (const char *system,
+		     const char *subsystem,
+		     const char *type,
+		     const char *data)
+{
+  if (! data || strcmp(system, "DEVFS") || strcmp(subsystem, "CDEV") ||
+      (strcmp(type, "CREATE") && strcmp(type, "DESTROY")))
+    return FALSE;
+
+  if (! strncmp(data, "cdev=ugen", strlen("cdev=ugen")) ||
+      ! strncmp(data, "cdev=usb", strlen("cdev=usb")))
+    return TRUE;
+
+  return FALSE;
+}
+
+HFHandler hf_usb2_handler = {
+  .privileged_init	= hf_usb2_privileged_init,
+  .probe		= hf_usb2_probe
+};
+
+HFDevdHandler hf_usb2_devd_handler = {
+  .add =	hf_usb2_devd_add,
+  .remove =	hf_usb2_devd_remove,
+  .notify =     hf_usb2_devd_notify
+};
>Release-Note:
>Audit-Trail:
>Unformatted:



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