hal: Branch 'master'

Joe Marcus Clarke marcus at kemper.freedesktop.org
Thu Jan 4 20:10:57 PST 2007


 hald/freebsd/README    |   14 +++++-----
 hald/freebsd/hf-ata.c  |   34 +++++++++++++++++++++++--
 hald/freebsd/hf-ata.h  |    6 +++-
 hald/freebsd/hf-scsi.c |   66 +++++++++++++++++++++++++++----------------------
 4 files changed, 81 insertions(+), 39 deletions(-)

New commits:
diff-tree 91e7fd50a7f5b427f09e91e134f12d6edf552770 (from c66993a7064c3fb3d1c1a86198ff7f56b49cc3b8)
Author: Jean-Yves Lefort <jylefort at FreeBSD.org>
Date:   Thu Jan 4 23:10:48 2007 -0500

    favor CAM devices over ATAPI devices
    
    If atapicam is enabled in the kernel, use CAM device nodes instead of ATAPI
    device nodes to access disc devices.  This can avoid lock ups on certain
    machines when disc burning software is used.

diff --git a/hald/freebsd/README b/hald/freebsd/README
index 9daacd5..7b70070 100644
--- a/hald/freebsd/README
+++ b/hald/freebsd/README
@@ -3,25 +3,25 @@
  FreeBSD notes
 
  Jean-Yves Lefort <jylefort at FreeBSD.org>
- September 11, 2006
+ January 1, 2007
 ===============================================================================
 
 1. Handling of atapicam devices
 
 By default, when an ATAPI device is available through both ata(4) and
-atapicam(4), the HAL daemon will use the ata interface and mark the
-virtual SCSI device as ignored (info.ignore=true).
+atapicam(4), the HAL daemon will use the atapicam interface and mark
+the ata device as ignored (info.ignore=true).
 
-If you want the HAL daemon to use the atapicam interface for a
-particular device, add a fdi rule for ignoring the ata device (create
+If you want the HAL daemon to use the ata interface for a particular
+device, add a fdi rule for ignoring the atapicam device (create
 /usr/local/share/hal/fdi/preprobe/20thirdparty/10-atapi-device.fdi
 with the following contents).
 
   <?xml version="1.0" encoding="UTF-8"?>
   <deviceinfo version="0.2">
     <device>
-      <!-- ignore /dev/acd0; we want hald to use the atapicam interface -->
-      <match key="block.device" string="/dev/acd0">
+      <!-- ignore /dev/cd0; we want hald to use the ata interface -->
+      <match key="block.device" string="/dev/cd0">
         <merge key="info.ignore" type="bool">true</merge>
       </match>
     </device>
diff --git a/hald/freebsd/hf-ata.c b/hald/freebsd/hf-ata.c
index 4ac7574..5257683 100644
--- a/hald/freebsd/hf-ata.c
+++ b/hald/freebsd/hf-ata.c
@@ -3,7 +3,7 @@
  *
  * hf-ata.c : ATA support
  *
- * 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
@@ -45,6 +45,8 @@
 
 static int hf_ata_fd;
 
+GList *hf_ata_pending_devices = NULL;
+
 /* adapted from ad_describe() in sys/dev/ata/atadisk.c */
 static char *
 hf_ata_get_vendor (const char *model)
@@ -222,11 +224,32 @@ hf_ata_probe_devices (HalDevice *ide_hos
 	    HalDevice *block_device;
 
 	    block_device = hf_ata_block_device_new(ide_device, i, &devices);
-	    hf_storage_device_add(block_device);
+
+	    /*
+	     * hf-scsi might need to ignore the device, so we cannot
+	     * add it immediately (we cannot ignore a device after it
+	     * was added). We will therefore add the device to a
+	     * pending list, and let hf-scsi call
+	     * hf_ata_add_pending_devices() to add the pending
+	     * devices.
+	     */
+	    hf_ata_pending_devices = g_list_append(hf_ata_pending_devices, block_device);
 	  }
       }
 }
 
+void
+hf_ata_add_pending_devices (void)
+{
+  GList *l;
+
+  HF_LIST_FOREACH(l, hf_ata_pending_devices)
+    hf_storage_device_add(l->data);
+
+  g_list_free(hf_ata_pending_devices);
+  hf_ata_pending_devices = NULL;
+}
+
 static void
 hf_ata_privileged_init (void)
 {
@@ -241,6 +264,13 @@ hf_ata_probe (void)
   GSList *gdl_devices;
   GSList *l;
 
+  /*
+   * There must be no pending device, otherwise hf-scsi did not call
+   * hf_ata_add_pending_devices() during the previous probe and there
+   * is a bug somewhere.
+   */
+  g_assert(hf_ata_pending_devices == NULL);
+
   if (hf_ata_fd < 0)
     return;
 
diff --git a/hald/freebsd/hf-ata.h b/hald/freebsd/hf-ata.h
index 37a5d6c..d200925 100644
--- a/hald/freebsd/hf-ata.h
+++ b/hald/freebsd/hf-ata.h
@@ -3,7 +3,7 @@
  *
  * hf-ata.h : ATA support
  *
- * 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
@@ -32,6 +32,10 @@
 
 extern HFHandler hf_ata_handler;
 
+extern GList *hf_ata_pending_devices;
+
+void hf_ata_add_pending_devices (void);
+
 void hf_ata_channel_set_properties (HalDevice *device);
 
 #endif /* _HF_ATA_H */
diff --git a/hald/freebsd/hf-scsi.c b/hald/freebsd/hf-scsi.c
index e937daf..7c8bd3b 100644
--- a/hald/freebsd/hf-scsi.c
+++ b/hald/freebsd/hf-scsi.c
@@ -3,7 +3,7 @@
  *
  * hf-scsi.c : SCSI support
  *
- * 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
@@ -39,6 +39,7 @@
 #include "../logger.h"
 
 #include "hf-scsi.h"
+#include "hf-ata.h"
 #include "hf-block.h"
 #include "hf-devtree.h"
 #include "hf-storage.h"
@@ -273,14 +274,17 @@ static HalDevice *
 hf_scsi_get_atapi_device (HalDevice *ata_channel, int lun)
 {
   HalDevice *device = NULL;
-  GSList *children;
-  GSList *l;
+  GList *l;
 
   g_return_val_if_fail(HAL_IS_DEVICE(ata_channel), NULL);
   g_return_val_if_fail(lun == 0 || lun == 1, NULL); /* ATA master or slave*/
 
-  children = hf_device_store_get_children(hald_get_gdl(), ata_channel);
-  HF_LIST_FOREACH(l, children)
+  /*
+   * If there's an ATAPI device it will be in hf_ata_pending_devices,
+   * since we haven't called hf_ata_add_pending_devices() yet.
+   */
+
+  HF_LIST_FOREACH(l, hf_ata_pending_devices)
     {
       HalDevice *child = l->data;
       const char *driver;
@@ -294,7 +298,6 @@ hf_scsi_get_atapi_device (HalDevice *ata
 	    break;		/* we wanted the first device, done */
 	}
     }
-  g_slist_free(children);
 
   return device;
 }
@@ -313,16 +316,16 @@ hf_scsi_handle_pending_device (struct de
       parent = hal_device_store_match_key_value_int(hald_get_gdl(), "scsi_host.host", (*match)->path_id);
       if (! parent || ! hal_device_property_get_bool(parent, "info.ignore"))
 	{
+	  HalDevice *atapi_device = NULL;
 	  HalDevice *scsi_device;
-	  gboolean ignore = FALSE;
 	  int type;
 
 	  /*
 	   * If the device's parent (the SCSI bus) is an atapicam(4)
-	   * bus, we shall ignore the device unless its corresponding
-	   * ATAPI device was ignored. This is to ensure that the same
-	   * physical device will only be handled once (through ATA or
-	   * SCSI).
+	   * bus, we shall ignore the corresponding ATAPI device
+	   * unless this device was ignored. This is to ensure that
+	   * the same physical device will only be handled once
+	   * (through ATA or SCSI).
 	   */
 	  if (parent)
 	    {
@@ -331,8 +334,6 @@ hf_scsi_handle_pending_device (struct de
 	      ata_channel = hf_scsi_get_ata_channel(parent);
 	      if (ata_channel)
 		{
-		  HalDevice *atapi_device;
-
 		  atapi_device = hf_scsi_get_atapi_device(ata_channel, (*match)->target_lun);
 		  if (atapi_device)
                     {
@@ -345,9 +346,6 @@ hf_scsi_handle_pending_device (struct de
 		      hal_device_property_set_string(atapi_device, "block.freebsd.cam_path", scsi_path);
 		      g_free(cam_devname);
 		      g_free(scsi_path);
-
-		      if (! hal_device_property_get_bool(atapi_device, "info.ignore"))
-		        ignore = TRUE; /* ATAPI device not ignored, so ignore this one */
 		    }
 		}
 	    }
@@ -359,22 +357,24 @@ hf_scsi_handle_pending_device (struct de
 	      hf_scsi_is_cdrom(type)))
 	    {
 	      HalDevice *block_device;
+	      char *scsi_path;
 
 	      block_device = hf_scsi_block_device_new(scsi_device, *match, *devname);
-	      if (ignore)
-                {
-		  hal_device_property_set_bool(block_device, "info.ignore", TRUE);
-		}
-	      else
-                {
-                  char *scsi_path;
-
-		  scsi_path = g_strdup_printf("%d,%d,%d", (*match)->path_id, (*match)->target_id, (*match)->target_lun);
-                  hal_device_property_set_string(block_device, "block.freebsd.cam_path", scsi_path);
-		  g_free(scsi_path);
-		}
+
+	      scsi_path = g_strdup_printf("%d,%d,%d", (*match)->path_id, (*match)->target_id, (*match)->target_lun);
+	      hal_device_property_set_string(block_device, "block.freebsd.cam_path", scsi_path);
+	      g_free(scsi_path);
+
 	      if (hf_device_preprobe(block_device))
 		{
+		  /*
+		   * The device was not ignored. If there is a
+		   * corresponding ATAPI device, ignore it (see above
+		   * comment).
+		   */
+		  if (atapi_device)
+		    hal_device_property_set_bool(atapi_device, "info.ignore", TRUE);
+
 		  hf_runner_run_sync(block_device, 0, "hald-probe-scsi", NULL);
 
 		  /*
@@ -407,7 +407,7 @@ hf_scsi_probe (void)
   char *pending_devname = NULL;
 
   if (hf_scsi_fd < 0)
-    return;			/* already warned in hf_scsi_init() */
+    goto end;			/* already warned in hf_scsi_init() */
 
   memset(&ccb, 0, sizeof(ccb));
 
@@ -537,6 +537,14 @@ hf_scsi_probe (void)
   hf_scsi_handle_pending_device(&pending_device, &pending_devname);
 
   g_free(ccb.cdm.matches);
+
+ end:
+  /*
+   * Now that we have probed the SCSI devices and ignored the ATAPI
+   * devices as necessary, it is time to add the pending ATA block
+   * devices.
+   */
+  hf_ata_add_pending_devices();
 }
 
 HFHandler hf_scsi_handler = {


More information about the hal-commit mailing list