hal: Branch 'master' - 4 commits

Joe Marcus Clarke marcus at kemper.freedesktop.org
Sat Mar 31 09:50:18 PDT 2007


 hald/freebsd/hf-pci.c                           |  162 +++++++++++-------------
 hald/freebsd/hf-util.c                          |   70 +++++++++-
 hald/freebsd/hf-util.h                          |    4 
 tools/freebsd/hal-system-power-shutdown-freebsd |    4 
 4 files changed, 147 insertions(+), 93 deletions(-)

New commits:
diff-tree 41182327af66bbaf81b031c6e2f045bdad519f8d (from 8154d3177af11c06f6699e5fb7ed171c5f42c853)
Author: Joe Marcus Clarke <marcus at FreeBSD.org>
Date:   Sat Mar 31 12:50:09 2007 -0400

    ensure there are no embedded slashes in UDI components
    
    Add a new utility function, hf_str_no_slashes(), that converts '/' into '_'
    for purposes of UDI constructions.  UDI path components cannot contain
    embedded slashes, and a trailing slash will cause hald to crash.

diff --git a/hald/freebsd/hf-util.c b/hald/freebsd/hf-util.c
index b3cb62b..f472570 100644
--- a/hald/freebsd/hf-util.c
+++ b/hald/freebsd/hf-util.c
@@ -254,6 +254,7 @@ hf_device_set_udi (HalDevice *device, co
 {
   va_list args;
   char *udi;
+  char *safe_str;
 
   g_return_if_fail(HAL_IS_DEVICE(device));
   g_return_if_fail(format != NULL);
@@ -262,8 +263,11 @@ hf_device_set_udi (HalDevice *device, co
   udi = g_strdup_vprintf(format, args);
   va_end(args);
 
-  hf_device_set_full_udi(device, "/org/freedesktop/Hal/devices/%s", udi);
+  safe_str = hf_str_no_slashes(udi);
   g_free(udi);
+
+  hf_device_set_full_udi(device, "/org/freedesktop/Hal/devices/%s", safe_str);
+  g_free(safe_str);
 }
 
 void
@@ -666,3 +670,16 @@ hf_device_store_match (HalDeviceStore *s
 
   return device;
 }
+
+char *
+hf_str_no_slashes (const char *str)
+{
+  char *safe_str;
+
+  g_return_val_if_fail(str != NULL, NULL);
+
+  safe_str = g_strdup(str);
+  safe_str = g_strdelimit(safe_str, "/", '_');
+
+  return safe_str;
+}
diff --git a/hald/freebsd/hf-util.h b/hald/freebsd/hf-util.h
index 8648518..f272ae2 100644
--- a/hald/freebsd/hf-util.h
+++ b/hald/freebsd/hf-util.h
@@ -3,7 +3,7 @@
  *
  * hf-util.h : utilities
  *
- * Copyright (C) 2006 Jean-Yves Lefort <jylefort at FreeBSD.org>
+ * Copyright (C) 2006, 2007 Jean-Yves Lefort <jylefort at 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
@@ -110,6 +110,8 @@ int hf_runner_run_sync (HalDevice *devic
 
 int hf_strv_find (char **strv, const char *elem);
 
+char *hf_str_no_slashes (const char *str);
+
 HalDevice *hf_device_store_match (HalDeviceStore *store, ...);
 
 #endif /* _HF_UTIL_H */
diff-tree 8154d3177af11c06f6699e5fb7ed171c5f42c853 (from b707ce8d6c3595c1ca996cb51048288dacd1a337)
Author: Jean-Yves Lefort <jylefort at FreeBSD.org>
Date:   Sat Mar 31 12:47:22 2007 -0400

    ensure that UDIs of ATA and SCSI devices are unique
    
    Ensure that UDIs of ATA and SCSI devices are unique.

diff --git a/hald/freebsd/hf-util.c b/hald/freebsd/hf-util.c
index b1d2916..b3cb62b 100644
--- a/hald/freebsd/hf-util.c
+++ b/hald/freebsd/hf-util.c
@@ -3,7 +3,7 @@
  *
  * hf-util.c : utilities
  *
- * Copyright (C) 2006 Jean-Yves Lefort <jylefort at FreeBSD.org>
+ * Copyright (C) 2006, 2007 Jean-Yves Lefort <jylefort at 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
@@ -37,6 +37,7 @@
 #include "../util.h"
 #include "../device_info.h"
 
+#include "hf-ata.h"
 #include "hf-util.h"
 
 typedef struct
@@ -212,6 +213,42 @@ hf_device_remove_tree (HalDevice *device
   hf_device_remove(device);
 }
 
+/*
+ * Creates a device store containing the concatenation of the GDL and
+ * the ATA pending devices list. This device store differs from the
+ * GDL only between the ATA probe and the SCSI probe. It is used to
+ * compute an unique UDI in hf_device_set_full_udi().
+ */
+static HalDeviceStore *
+hf_pending_gdl_new (void)
+{
+  HalDeviceStore *store;
+  GList *l;
+  GSList *sl;
+
+  store = hal_device_store_new();
+
+  HF_LIST_FOREACH(sl, hald_get_gdl()->devices)
+    hal_device_store_add(store, sl->data);
+
+  HF_LIST_FOREACH(l, hf_ata_pending_devices)
+    hal_device_store_add(store, l->data);
+
+  return store;
+}
+
+static void
+hf_pending_gdl_free (HalDeviceStore *store)
+{
+  g_return_if_fail(HAL_IS_DEVICE_STORE(store));
+
+  /* the device store code fails to do this when a store is finalized */
+  while (store->devices)
+    hal_device_store_remove(store, store->devices->data);
+
+  g_object_unref(store);
+}
+
 void
 hf_device_set_udi (HalDevice *device, const char *format, ...)
 {
@@ -233,17 +270,27 @@ void
 hf_device_set_full_udi (HalDevice *device, const char *format, ...)
 {
   va_list args;
+  HalDeviceStore *pending_gdl;
   char *requested_udi;
   char actual_udi[256];
 
   g_return_if_fail(HAL_IS_DEVICE(device));
   g_return_if_fail(format != NULL);
 
+  /*
+   * To ensure an unique UDI, we must work against the GDL as well as
+   * the ATA pending devices list (since these devices will be added
+   * to the GDL at the end of the probe).
+   */
+  pending_gdl = hf_pending_gdl_new();
+
   va_start(args, format);
   requested_udi = g_strdup_vprintf(format, args);
   va_end(args);
 
-  hal_util_compute_udi(hald_get_gdl(), actual_udi, sizeof(actual_udi), "%s", requested_udi);
+  hal_util_compute_udi(pending_gdl, actual_udi, sizeof(actual_udi), "%s", requested_udi);
+
+  hf_pending_gdl_free(pending_gdl);
   g_free(requested_udi);
 
   hal_device_set_udi(device, actual_udi);
diff-tree b707ce8d6c3595c1ca996cb51048288dacd1a337 (from 694f701426c477c2c845cddd4c423ca1e3554cde)
Author: Jean-Yves Lefort <jylefort at FreeBSD.org>
Date:   Sat Mar 31 12:41:51 2007 -0400

    avoid an infinite loop with buggy PCI firmware
    
    * Avoid an infinite loop with buggy PCI firmware
    * Simplify the PCI probing mechanism

diff --git a/hald/freebsd/hf-pci.c b/hald/freebsd/hf-pci.c
index b3b7bd8..400f183 100644
--- a/hald/freebsd/hf-pci.c
+++ b/hald/freebsd/hf-pci.c
@@ -3,7 +3,7 @@
  *
  * hf-pci.c : enumerate PCI devices
  *
- * Copyright (C) 2006 Jean-Yves Lefort <jylefort at FreeBSD.org>
+ * Copyright (C) 2006, 2007 Jean-Yves Lefort <jylefort at 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
@@ -27,6 +27,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <bitstring.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -48,11 +49,16 @@
 
 /* from sys/dev/pci/pcireg.h */
 #define PCIR_SECBUS_1			0x19
+#define PCIR_HDRTYPE			0x0e
+#define PCIM_HDRTYPE_BRIDGE		0x01
+#define PCIM_HDRTYPE_CARDBUS		0x02
 
 typedef struct
 {
+  HalDevice		*device;
   struct pci_conf	p;
   int			secondary_bus;
+  int			header_type;
 } DeviceInfo;
 
 static int hf_pci_fd;
@@ -141,73 +147,41 @@ hf_pci_privileged_init (void)
     HAL_INFO(("unable to open %s: %s", HF_PCI_DEVICE, g_strerror(errno)));
 }
 
-static GSList *
-hf_pci_lookup (GSList *devices, int bus)
-{
-  if (bus != 0)
-    {
-      GSList *l;
-
-      HF_LIST_FOREACH(l, devices)
-	{
-	  DeviceInfo *info = l->data;
-
-	  if (info->secondary_bus == bus)
-	    return l;
-	}
-    }
-
-  return NULL;
-}
-
-static GSList *
-hf_pci_get_root (GSList *devices)
-{
-  GSList *root;
-  DeviceInfo *info;
-  int bus;
-
-  g_return_val_if_fail(devices != NULL, NULL);
-
-  root = devices;
-  info = root->data;
-
-  bus = info->p.pc_sel.pc_bus;
-  while (bus != -1)
-    {
-      GSList *new_root;
-
-      new_root = hf_pci_lookup(devices, bus);
-      bus = -1;
-
-      if (new_root)
-	{
-	  root = new_root;
-	  info = root->data;
-	  bus = info->p.pc_sel.pc_bus;
-	}
-    }
-
-  return root;
-}
-
 static void
-hf_pci_probe (void)
+hf_pci_probe_bus (HalDevice *parent, int bus, bitstr_t *busmap)
 {
+  struct pci_match_conf match_conf;
   struct pci_conf_io pc;
   struct pci_conf conf[255];
   struct pci_conf *p;
   GSList *devices = NULL;
+  GSList *l;
 
-  if (hf_pci_fd < 0)
-    return;
+  g_return_if_fail(busmap != NULL);
+  g_return_if_fail(bus >= 0 && bus <= 0xff);
+
+  /* test taken from sysutils/pciutils */
+  if (bit_test(busmap, bus))
+    {
+      HAL_WARNING(("PCI bus %.2x appearing twice (firmware bug), ignored", bus));
+      return;
+    }
+
+  bit_set(busmap, bus);
 
  start:
+  memset(&match_conf, 0, sizeof(match_conf));
+  match_conf.pc_sel.pc_bus = bus;
+  match_conf.flags = PCI_GETCONF_MATCH_BUS;
+
   memset(&pc, 0, sizeof(pc));
+  pc.pat_buf_len = sizeof(match_conf);
+  pc.num_patterns = 1;
+  pc.patterns = &match_conf;
   pc.match_buf_len = sizeof(conf);
   pc.matches = conf;
 
-  /* build a list of PCI devices */
+  /* get the devices located on the specified bus */
 
   do
     {
@@ -231,50 +205,64 @@ hf_pci_probe (void)
 	}
 
       for (p = conf; p < &conf[pc.num_matches]; p++)
-	  if (! hf_device_store_match(hald_get_gdl(),
-                                      "pci.freebsd.bus", HAL_PROPERTY_TYPE_INT32, p->pc_sel.pc_bus,
-				      "pci.freebsd.device", HAL_PROPERTY_TYPE_INT32, p->pc_sel.pc_dev,
-				      "pci.freebsd.function", HAL_PROPERTY_TYPE_INT32, p->pc_sel.pc_func,
-				      NULL))
-	    {
-	      DeviceInfo *info;
-
-	      info = g_new(DeviceInfo, 1);
-	      info->p = *p;
-	      info->secondary_bus = hf_pci_get_register(p, PCIR_SECBUS_1);
+        {
+          DeviceInfo *info;
+
+	  info = g_new(DeviceInfo, 1);
+	  info->device = hf_device_store_match(hald_get_gdl(),
+			                       hal_property_new_int("pci.freebsd.bus", p->pc_sel.pc_bus),
+					       hal_property_new_int("pci.freebsd.device", p->pc_sel.pc_dev),
+					       hal_property_new_int("pci.freebsd.function", p->pc_sel.pc_func),
+					       NULL);
+	  info->p = *p;
+	  info->secondary_bus = hf_pci_get_register(p, PCIR_SECBUS_1);
+	  info->header_type = hf_pci_get_register(p, PCIR_HDRTYPE);
 
-	      devices = g_slist_prepend(devices, info);
-	    }
+	  devices = g_slist_prepend(devices, info);
+	}
     }
   while (pc.status == PCI_GETCONF_MORE_DEVS);
 
-  /* add the devices (parents first) */
+  /* add the devices and probe the children of bridges */
 
-  while (devices)
+  HF_LIST_FOREACH(l, devices)
     {
-      GSList *root;
-      DeviceInfo *info;
-      HalDevice *parent = NULL;
+      DeviceInfo *info = l->data;
+
+      /*
+       * If the device already exists, we are reprobing (from
+       * osspec_device_reprobe()). In this case we must not add it
+       * again, but only probe its children if it is a bridge.
+       */
+      if (! info->device)
+        {
+          info->device = hf_pci_device_new(parent, &info->p, info->secondary_bus);
+	  if (hf_device_preprobe(info->device))
+            hf_device_add(info->device);
+	  else
+            continue;	/* device ignored */
+	}
 
-      root = hf_pci_get_root(devices);
-      g_assert(root != NULL);
+      if (info->header_type == PCIM_HDRTYPE_BRIDGE || info->header_type == PCIM_HDRTYPE_CARDBUS)
+        /* a bridge or cardbus, probe its children */
+        hf_pci_probe_bus(info->device, info->secondary_bus, busmap);
+    }
 
-      info = root->data;
+  /* cleanup */
 
-      if (info->p.pc_sel.pc_bus != 0)
-	parent = hal_device_store_match_key_value_int(hald_get_gdl(), "pci.freebsd.secondary_bus", info->p.pc_sel.pc_bus);
+  g_slist_foreach(devices, (GFunc) g_free, NULL);
+  g_slist_free(devices);
+}
 
-      if (! parent || ! hal_device_property_get_bool(parent, "info.ignore"))
-	{
-	  HalDevice *device;
+static void
+hf_pci_probe (void)
+{
+  bitstr_t bit_decl(busmap, 256) = { 0 };
 
-	  device = hf_pci_device_new(parent, &info->p, info->secondary_bus);
-	  hf_device_preprobe_and_add(device);
-	}
+  if (hf_pci_fd < 0)
+    return;
 
-      devices = g_slist_delete_link(devices, root);
-      g_free(info);
-    }
+  hf_pci_probe_bus(NULL, 0, busmap);
 }
 
 HFHandler hf_pci_handler = {
diff-tree 694f701426c477c2c845cddd4c423ca1e3554cde (from 1d1808644eba767828c294232085a2fd34b399a5)
Author: Jean-Yves Lefort <jylefort at FreeBSD.org>
Date:   Sat Mar 31 12:29:19 2007 -0400

    power down instead of halting the system
    
    Power down the system rather than simply shutting it down.

diff --git a/tools/freebsd/hal-system-power-shutdown-freebsd b/tools/freebsd/hal-system-power-shutdown-freebsd
index 6a9811e..c947bea 100755
--- a/tools/freebsd/hal-system-power-shutdown-freebsd
+++ b/tools/freebsd/hal-system-power-shutdown-freebsd
@@ -8,10 +8,10 @@ unsupported() {
 
 #Try for common tools
 if [ -x "/sbin/shutdown" ] ; then
-	/sbin/shutdown -h now
+	/sbin/shutdown -p now
 	exit $?
 elif [ -x "/usr/sbin/shutdown" ] ; then
-	/usr/sbin/shutdown -h now
+	/usr/sbin/shutdown -p now
 	exit $?
 else
 	unsupported


More information about the hal-commit mailing list