FU Logo
  • Startseite
  • Kontakt
  • Impressum
  • Home
  • Listenauswahl
  • Anleitungen

Re: [linux-minidisc] another way to send SCSI commands

<-- thread -->
<-- date -->
  • From: Michael Karcher <Michael.Karcher@fu-berlin.de>
  • To: Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
  • Date: Sun, 05 Dec 2010 01:55:33 +0100
  • Cc: appro@fy.chalmers.se, linux-minidisc@lists.fu-berlin.de
  • Subject: Re: [linux-minidisc] another way to send SCSI commands

Am Samstag, den 04.12.2010, 00:10 +0100 schrieb Michael Karcher:
> > Thanks a lot for investigating into that. I would very glad if we can
> > drop libscg in favor of dvd+rw-tools.
> I did not yet implement the suggested change, but I am quite confident
> that it will work.

The attached patch makes sending an INQUIRY command to the attached
Hi-MD walkman work. I did not test it with a CD drive yet (I might have
broken that, although I doubt it), as the current design has the problem
that it only works on drive with inserted media (as you specify the
device using /dev/rdiskN, and this device does not exist if no medium is
installed...) and the CD drive of the only Mac I have (remote) access to
is currently empty. I will add later a function that allows
specification of the IOKit device ID for attachment.

Regards,
  Michael Karcher
--- transport.hxx.orig	2010-12-03 02:43:34.000000000 +0100
+++ transport.hxx	2010-12-05 01:50:29.000000000 +0100
@@ -1478,7 +1478,7 @@
       io_object_t		scsiob=IO_OBJECT_NULL,parent;
       CFMutableDictionaryRef	match,bsddev;
       CFNumberRef		num;
-      int			i;
+      int			i,res;
 
 	if (ref)			sb = *ref;
 	else if (stat(file,&sb))	return 0;
@@ -1511,32 +1511,51 @@
 	if ((scsiob = IOServiceGetMatchingService(kIOMasterPortDefault,match))
 	    == IO_OBJECT_NULL)	return !(errno=ENXIO);
 
-	// traverse up to "SCSITaskAuthoringDevice"
+	// Find a plugin of type MMCDeviceUserClientType or
+	// SCSITaskDeviceUserClientType by traversing the tree upwards.
 	kern_return_t	kret;
+	int found = 0;
+	CFStringRef mmctype = CFUUIDCreateString(kCFAllocatorDefault,
+						 kIOMMCDeviceUserClientTypeID);
+	CFStringRef tasktype = CFUUIDCreateString(kCFAllocatorDefault,
+						  kIOSCSITaskDeviceUserClientTypeID);
 	while ((kret=IORegistryEntryGetParentEntry(scsiob,kIOServicePlane,
-				&parent)) == kIOReturnSuccess)
-	{ CFStringRef	uclient;
-	  const char	*s;
-	  int		cmp;
+				&parent)) == kIOReturnSuccess && !found)
+	{ CFDictionaryRef plugins;
 
 	    IOObjectRelease(scsiob);
 	    scsiob = parent;
-	    uclient = (CFStringRef)IORegistryEntryCreateCFProperty(scsiob,
-				CFSTR(kIOPropertySCSITaskDeviceCategory),
+	    plugins = (CFDictionaryRef)IORegistryEntryCreateCFProperty(scsiob,
+				CFSTR(kIOCFPlugInTypesKey),
 				kCFAllocatorDefault,0);
-	    if (uclient)
-	    {	s = CFStringGetCStringPtr(uclient,kCFStringEncodingMacRoman);
-		cmp = strcmp(s,kIOPropertySCSITaskAuthoringDevice);
-		CFRelease(uclient);
-		if (cmp==0)	break;
+	    if (plugins)
+	    {	if (CFDictionaryContainsKey(plugins,mmctype)) 
+		{   res = attachViaMMC(scsiob);
+		    found = 1;
+		}
+		if (CFDictionaryContainsKey(plugins,tasktype))
+		{   res = attachViaSCSITask(scsiob);
+		    found = 1;
+		}
+		CFRelease(plugins);
 	    }
 	}
-	if (kret!=kIOReturnSuccess)
+	CFRelease(tasktype);
+	CFRelease(mmctype);
+	if (!found)
 	{   if (scsiob!=IO_OBJECT_NULL)	IOObjectRelease(scsiob);
 	    return !(errno=ENXIO);
 	}
+	if (res)
+	{   filename=strdup(file);
+	    this->scsiob = scsiob;
+	}
+	return res;
+    }
 
-	SInt32	score=0;
+private:
+    int attachViaMMC(io_object_t scsiob)
+    {   SInt32	score=0;
 	if (IOCreatePlugInInterfaceForService(scsiob,
 				kIOMMCDeviceUserClientTypeID,
 				kIOCFPlugInInterfaceID,
@@ -1573,10 +1592,43 @@
 	    return !(errno=EBUSY);
 	}
 
-	filename=strdup(file);
+	return 1;
+    }
+
+    int attachViaSCSITask(io_object_t scsiob)
+    {   SInt32	score=0;
+	if (IOCreatePlugInInterfaceForService(scsiob,
+				kIOSCSITaskDeviceUserClientTypeID,
+				kIOCFPlugInInterfaceID,
+				&plugin,&score) != kIOReturnSuccess)
+	{   IOObjectRelease(scsiob);
+	    return !(errno=ENXIO);
+	}
+	if ((*plugin)->QueryInterface(plugin,
+				CFUUIDGetUUIDBytes(kIOSCSITaskDeviceInterfaceID),
+				(void**)&taskif) != S_OK)
+	{   IODestroyPlugInInterface(plugin),	plugin=NULL;
+	    IOObjectRelease(scsiob);
+	    return !(errno=ENXIO);
+	}
+
+	//
+	// Note that in order to ObtainExclusiveAccess no corresponding
+	// /dev/[r]diskN may remain open by that time. For reference,
+	// acquiring exclusive access temporarily removes BSD block
+	// storage device from I/O registry as well as corresponding
+	// /dev entries.
+	//
+	if ((*taskif)->ObtainExclusiveAccess(taskif) != kIOReturnSuccess)
+	{   (*taskif)->Release(taskif),		taskif=NULL;
+	    IODestroyPlugInInterface(plugin),	plugin=NULL;
+	    IOObjectRelease(scsiob),		scsiob=IO_OBJECT_NULL;
+	    return !(errno=EBUSY);
+	}
 
 	return 1;
     }
+public:
     unsigned char &operator[] (size_t i)
     {	if (i==0)
 	{   memset (cdb,0,sizeof(cdb));
<-- thread -->
<-- date -->
  • References:
    • [linux-minidisc] another way to send SCSI commands
      • From: Michael Karcher <Michael.Karcher@fu-berlin.de>
    • Re: [linux-minidisc] another way to send SCSI commands
      • From: Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
    • Re: [linux-minidisc] another way to send SCSI commands
      • From: Michael Karcher <Michael.Karcher@fu-berlin.de>
  • linux-minidisc - December 2010 - Archives indexes sorted by:
    [ thread ] [ subject ] [ author ] [ date ]
  • Complete archive of the linux-minidisc mailing list
  • More info on this list...

Hilfe

  • FAQ
  • Dienstbeschreibung
  • ZEDAT Beratung
  • postmaster@lists.fu-berlin.de

Service-Navigation

  • Startseite
  • Listenauswahl

Einrichtung Mailingliste

  • ZEDAT-Portal
  • Mailinglisten Portal