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

[linux-minidisc] another way to send SCSI commands

thread -->
date -->
  • From: Michael Karcher <Michael.Karcher@fu-berlin.de>
  • To: linux-minidisc@lists.fu-berlin.de
  • Date: Fri, 03 Dec 2010 03:23:27 +0100
  • Cc: appro@fy.chalmers.se
  • Subject: [linux-minidisc] another way to send SCSI commands

[Cc: to the dvd+rw-tools maintainer to let him know of the patches]

Hello developers,

I know we already got libscg up and running on all three operating
systems that are our main target. But the original libscg by Joerg
Schilling has the disadvantage that it is centered around the Solaris
way of addressing SCSI devices by bus/dev/lun, which does not fit the
model on windows, and also in uncomfortable to deal with on Linux.

On Linux, libscg thankfully supports "open by devname" which avoids the
abstraction into bus/dev/lun we don't need if we are just interested in
the Hi-MD stuff, while on Windows, "open by devname" is not supported.
libusal (the fork by Debain people around Eduard Bloch) adds support for
opening by device name, but hacks it into the present infrastructure in
a not exactly clean way - and for example still scans all drives to
assign bus numbers.

I found that dvd+rwtools contains a refreshingly simple GPLed (without
any restrictions like "you need to modify author name" and so on) SCSI
abstraction layer that covers the following operating systems:
  Linux, OpenBSD/NetBSD, Solaris (license for distribution maybe
questionable), FreeBSD, HP-UX, IRIX, Win32, Mac OS X.
(see: http://fy.chalmers.se/~appro/linux/DVD+RW/ search for "run Linux")

The nice thing is that this library does not even think about adding
some abstraction on device naming, so "/dev/sdb" works out-of-the-box on
Linux while "E:" works out-of-the-box on Windows. I don't have a MacOS
to test here.

Sources for dvd+rw-tools can be obtained from here:
 http://fy.chalmers.se/~appro/linux/DVD+RW/tools/

Patches (one for a bug in the Linux header, one to suppress lots of
warnings to compile with MinGW, one to lift the restriction of only
being able to work on CD/DVD drives) are attached to this mail, as well
as a simple test program that sends an "INQUIRY" SCSI command (reads
vendor/model/revision). I would like to have it tested on MacOS X, too,
if someone cares. It looks like a device node name is expected in the
MacOS case too, just as in Linux.

To use the SCSI layer, you just need transport.hxx, win32err.h and
asctable.h from the dvd+rw-tools package. The only small drawback of
this code compared to libscg is that this code is in C++, but as it in
fact does not really make use of C++ except for making Scsi_Command a
class, it integrates quite well even into C projects. I wouldn't have
problems to add this small amount of C++ to libhimd.

Regards,
  Michael Karcher

--- ../dvd+rw-tools-7.1/win32err.h.orig	2010-12-03 02:57:54.000000000 +0100
+++ win32err.h	2010-12-03 02:59:05.000000000 +0100
@@ -1,16 +1,5 @@
-# define EINVAL		ERROR_BAD_ARGUMENTS
-# define ENOMEM		ERROR_OUTOFMEMORY
 # define EMEDIUMTYPE	ERROR_MEDIA_INCOMPATIBLE
 # define ENOMEDIUM	ERROR_MEDIA_OFFLINE
-# define ENODEV		ERROR_BAD_COMMAND
-# define EAGAIN		ERROR_NOT_READY
-# define ENOSPC		ERROR_DISK_FULL
-# define EIO		ERROR_NOT_SUPPORTED
-# define ENXIO		ERROR_GEN_FAILURE
-# define EBUSY		ERROR_SHARING_VIOLATION
-# define ENOENT		ERROR_FILE_NOT_FOUND
-# define ENOTDIR	ERROR_NO_VOLUME_LABEL
-# define EINTR		ERROR_OPERATION_ABORTED
 # define FATAL_START(e)	(0x10000|(e))
 # define FATAL_MASK	 0x0FFFF
 
--- ../dvd+rw-tools-7.1/transport.hxx.orig	2010-12-03 02:43:34.000000000 +0100
+++ transport.hxx	2010-12-03 02:58:57.000000000 +0100
@@ -1297,14 +1297,21 @@
     int associate (const char *file,const struct stat *ref=NULL)
     { char dev[32];
 	sprintf(dev,"%.*s\\",sizeof(dev)-2,file);
-	if (GetDriveType(dev)!=DRIVE_CDROM)
-	    return errno=EINVAL,0;
 	sprintf(dev,"\\\\.\\%.*s",sizeof(dev)-5,file);
 	fd=CreateFile (dev,GENERIC_WRITE|GENERIC_READ,
 			   FILE_SHARE_READ|FILE_SHARE_WRITE,
 			   NULL,OPEN_EXISTING,0,NULL);
 	if (fd!=INVALID_HANDLE_VALUE)
-	    filename=strdup(dev);
+	{   /* test that SCSI Passthrough is supported by sending test unit ready */
+ 	    for(int i = 0;i < 8;++i)
+		this->operator[](0) = 0;
+	    if(transport() == -1)
+            {   CloseHandle(fd);
+		fd = INVALID_HANDLE_VALUE;
+		errno = EINVAL;
+	    } else
+		filename=strdup(dev);
+	}
 	return fd!=INVALID_HANDLE_VALUE;
     }
     unsigned char &operator[] (size_t i)
--- ../dvd+rw-tools-7.1/transport.hxx.orig	2010-12-03 02:43:34.000000000 +0100
+++ transport.hxx	2010-12-03 02:58:57.000000000 +0100
@@ -139,6 +139,7 @@
 	
 #if defined(__linux)
 
+#include <limits.h>
 #include <sys/ioctl.h>
 #include <linux/cdrom.h>
 #include <mntent.h>
#include <string>
#include <climits>
#include <iostream>
#include <ostream>
#include "transport.hxx"

int main(int argc, char ** argv)
{
	using std::cerr;
	using std::cout;
	using std::endl;
	Scsi_Command cmd;
	char response[96];
	if(!cmd.associate(argv[1]))
	{
		cerr << "Can't associate";
		return 1;
	}
	cmd[0] = 0x12;
	cmd[1] = 0;
	cmd[2] = 0;	/* page code */
	cmd[3] = 0;
	cmd[4] = 96;
	cmd[5] = 0;
	if(cmd.transport(READ,response,96))
	{
		cerr << "Can't execute";
		return 1;
	}
	cout << "Vendor: " << std::string(response+8,8) << 
	        "; Model: " << std::string(response+16,16) <<
	        "; Revision " << std::string(response+32,4) << endl;
	return 0;
}
thread -->
date -->
  • Follow-Ups:
    • Re: [linux-minidisc] another way to send SCSI commands
      • From: Adrian Glaubitz <glaubitz@physik.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