Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Dec 2007 19:11:50 +0200
From:      Andriy Gapon <avg@icyb.net.ua>
To:        Joe Marcus Clarke <marcus@freebsd.org>
Cc:        kde@freebsd.org, freebsd-gnome@freebsd.org
Subject:   Re: multislot cardreader and hald
Message-ID:  <476FE856.1080702@icyb.net.ua>
In-Reply-To: <476FC2EC.2060804@icyb.net.ua>
References:  <476A8A01.3040202@icyb.net.ua> <op.t3m7k1qp9aq2h7@mezz.mezzweb.com>	<476A9D99.2050804@icyb.net.ua> <op.t3m8cgek9aq2h7@mezz.mezzweb.com>	<476BAAB0.9030303@icyb.net.ua> <op.t3o3zlvn9aq2h7@mezz.mezzweb.com> <476BC09A.8070300@freebsd.org> <476FC2EC.2060804@icyb.net.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------020900060605010802010902
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

on 24/12/2007 16:32 Andriy Gapon said the following:
> on 21/12/2007 15:33 Joe Marcus Clarke said the following:
>> Disc media is treated differently than USB media.  USB umass devices are
>> assumed to have media.  This is part of the issue with the card reader
>> (floppy drives behave the same way).
> 
> Isn't this a bad assumption?

Attached is a patch that attempts to address removable storage devices
(that are not CD-ROMs) attached either via SCSI or via USB. The purpose
is to do "gentler" probing of media presence than that done by OS in
response to open(2).
I employed one hack in the code to avoid device being open()-ed if
cam_open_device() fails, but this was "just in case", not sure if it was
really needed.

The patch works very well for me, especially in tandem with the patch
for SCSI verboseness that I posted to -stable and -scsi.

-- 
Andriy Gapon

--------------020900060605010802010902
Content-Type: text/x-patch;
 name="patch-scsi-addon.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="patch-scsi-addon.patch"

--- addons/addon-storage.c.orig	Mon Dec 24 16:45:04 2007
+++ addons/addon-storage.c	Mon Dec 24 18:22:19 2007
@@ -42,6 +42,7 @@ static struct
   char			*device_file;
   char			*parent;
   boolean		is_cdrom;
+  boolean		is_scsi_removable;
   boolean		had_media;
   struct timeval	next_update;
 } addon = { { 2, 0 } };
@@ -71,6 +72,18 @@ hf_addon_storage_cdrom_eject_pressed (HF
 }
 
 static boolean
+hf_addon_storage_scsi_read_capacity (HFPCDROM *cdrom)
+{
+  unsigned char buf[8];
+  static char ccb[16] = { /*HFP_CDROM_READ_CAPACITY*/ 0x25 };
+
+  assert(cdrom != NULL);
+
+  /* we check only success/error and discard the data */
+  return hfp_cdrom_send_ccb(cdrom, ccb, 10, HFP_CDROM_DIRECTION_IN, buf, sizeof(buf), NULL);
+}
+
+static boolean
 hf_addon_storage_update (void)
 {
   boolean has_media = FALSE;
@@ -94,6 +107,31 @@ hf_addon_storage_update (void)
 	  hfp_cdrom_free(cdrom);
 	}
     }
+  else if (addon.is_scsi_removable)
+    {
+      /* (ab)use cdrom-specific routines:
+       * for what we are doing here there is no difference between
+       * a SCSI CD-ROM and any other disk-like SCSI device 
+       * with removable media.
+       * This is a gentler check than trying to open the device.
+       */
+      HFPCDROM *cdrom;
+
+      /* XXX hfp_cdrom_new_from_fd(-1) below is an ugly hack to prevent
+       * regular open() in the case cam_open_device() fails.
+       */
+      cdrom = hfp_cdrom_new_from_fd(-1, addon.device_file, addon.parent);
+      if (cdrom)
+	{
+	  /* some umass devices may lie in TEST UNIT READY,
+	   * so doing READ CAPACITY to be sure.
+	   */
+	  if (hfp_cdrom_test_unit_ready(cdrom) && hf_addon_storage_scsi_read_capacity(cdrom))
+	    has_media = TRUE;
+
+	  hfp_cdrom_free(cdrom);
+	}
+    }
   else
     {
       int fd;
@@ -115,7 +153,9 @@ hf_addon_storage_update (void)
 int
 main (int argc, char **argv)
 {
-  char *drive_type;
+  const char *drive_type;
+  const char *removable;
+  const char *bus;
   DBusConnection *connection;
 
   if (! hfp_init(argc, argv))
@@ -129,6 +169,14 @@ main (int argc, char **argv)
   if (! drive_type)
     goto end;
 
+  removable = getenv("HAL_PROP_STORAGE_REMOVABLE");
+  if (! removable)
+    goto end;
+
+  bus = getenv("HAL_PROP_STORAGE_BUS");
+  if (! bus)
+    goto end;
+
   addon.parent = getenv("HAL_PROP_INFO_PARENT");
   if (! addon.parent)
     goto end;
@@ -137,6 +185,7 @@ main (int argc, char **argv)
   setproctitle("%s", addon.device_file);
 
   addon.is_cdrom = ! strcmp(drive_type, "cdrom");
+  addon.is_scsi_removable = (! strcmp(bus, "scsi") || ! strcmp(bus, "usb")) && ! strcmp(removable, "true");
   addon.had_media = hf_addon_storage_update();
 
   connection = libhal_ctx_get_dbus_connection(hfp_ctx);

--------------020900060605010802010902--



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