Imported Upstream version 1.3.11
[debian/mtx] / scsi_linux.c
index e5378d3a15242412e0d8107504a994318c8c1f0b..6dcae86519d83f76443ef990ef9c7020deebaac2 100644 (file)
@@ -1,8 +1,8 @@
 /* Copyright 1997, 1998 Leonard Zubkoff <lnz@dandelion.com>
-   Changes in Feb 2000 Eric Green <eric@estinc.com>
+   Changes in Feb 2000 Eric Green <eric@badtux.org>
 
-$Date: 2001/06/19 21:51:32 $
-$Revision: 1.2 $
+$Date: 2007-03-24 21:17:10 -0700 (Sat, 24 Mar 2007) $
+$Revision: 171 $
 
   This program is free software; you may redistribute and/or modify it under
   the terms of the GNU General Public License Version 2 as published by the
@@ -15,12 +15,13 @@ $Revision: 1.2 $
 
 */
 
-/* this is the SCSI commands for Linux. Note that <eric@estinc.com> changed 
+/* this is the SCSI commands for Linux. Note that <eric@badtux.org> changed 
  * it from using SCSI_IOCTL_SEND_COMMAND to using the SCSI generic interface.
  */
 
 #ifndef HZ
-#define HZ 100
+#warning "HZ is not defined, mtx might not work correctly!"
+#define HZ 100   /* Jiffys for SG_SET_TIMEOUT */
 #endif
 
 /* These are copied out of BRU 16.1, with all the boolean masks changed
@@ -51,38 +52,53 @@ $Revision: 1.2 $
 
 #define STILL_A_VALID_READ(s) (HIT_FILEMARK(s) || SHORT_READ(s) || HIT_EOD(s) || HIT_EOP(s) || HIT_EOM(s))
 
+#define SG_SCSI_DEFAULT_TIMEOUT (HZ*60*5)  /* 5 minutes? */
 
-#define SG_SCSI_DEFAULT_TIMEOUT HZ*60*5  /* 5 minutes? */
+static int pack_id;
+static int sg_timeout;
 
 DEVICE_TYPE SCSI_OpenDevice(char *DeviceName)
 {
-  int timeout=SG_SCSI_DEFAULT_TIMEOUT;      /* 5 minutes */
-  int DeviceFD = open(DeviceName, O_RDWR);
-  if (DeviceFD < 0)
-    FatalError("cannot open SCSI device '%s' - %m\n", DeviceName);
+       int timeout = SG_SCSI_DEFAULT_TIMEOUT;
+#ifdef SG_IO
+       int k; /* version */
+#endif
+       int DeviceFD = open(DeviceName, O_RDWR);
 
-  if(ioctl(DeviceFD, SG_SET_TIMEOUT, &timeout)) {
-    FatalError("failed to set sg timeout - %m\n");
-  }
+       if (DeviceFD < 0)
+               FatalError("cannot open SCSI device '%s' - %m\n", DeviceName);
 
-  return (DEVICE_TYPE) DeviceFD;
-}
 
-static int sg_timeout = SG_SCSI_DEFAULT_TIMEOUT ;
+#ifdef SG_IO
+       /* It is prudent to check we have a sg device by trying an ioctl */
+       if ((ioctl(DeviceFD, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000))
+       {
+               FatalError("%s is not an sg device, or old sg driver\n", DeviceName);
+       }
+#endif
 
-void SCSI_Set_Timeout(int secs) {
-  sg_timeout=secs*HZ;
+       if (ioctl(DeviceFD, SG_SET_TIMEOUT, &timeout))
+       {
+               FatalError("failed to set sg timeout - %m\n");
+       }
+       pack_id = 1;    /* used for SG v3 interface if possible. */
+       return (DEVICE_TYPE) DeviceFD;
+}
+
+void SCSI_Set_Timeout(int secs)
+{
+       sg_timeout = secs * HZ;
 }
  
-void SCSI_Default_Timeout(void) {
-  sg_timeout=SG_SCSI_DEFAULT_TIMEOUT;
+void SCSI_Default_Timeout(void)
+{
+       sg_timeout = SG_SCSI_DEFAULT_TIMEOUT;
 }
 
-void SCSI_CloseDevice(char *DeviceName,
-                            DEVICE_TYPE DeviceFD)
+void SCSI_CloseDevice(char *DeviceName, DEVICE_TYPE DeviceFD)
 {
-  if (close(DeviceFD) < 0)
-    FatalError("cannot close SCSI device '%s' - %m\n", DeviceName);
+       if (close(DeviceFD) < 0)
+               FatalError("cannot close SCSI device '%s' - %m\n", DeviceName);
 }
 
 
@@ -90,29 +106,113 @@ void SCSI_CloseDevice(char *DeviceName,
  * Seagate autoloader (hopefully!). 
  */
 /* Get the SCSI ID and LUN... */
-scsi_id_t *SCSI_GetIDLun(DEVICE_TYPE fd) {
-  int status;
-  scsi_id_t *retval;
-  
-  struct my_scsi_idlun {
-    int word1;
-    int word2;
-  } idlun;
-
-  status=ioctl(fd,SCSI_IOCTL_GET_IDLUN,&idlun);
-  if (status) {
-    return NULL; /* sorry! */
-  }
-  
-  retval=(scsi_id_t *)xmalloc(sizeof(scsi_id_t));
-  retval->id=idlun.word1 & 0xff;
-  retval->lun=idlun.word1 >> 8 & 0xff;
+scsi_id_t *SCSI_GetIDLun(DEVICE_TYPE fd)
+{
+       int status;
+       scsi_id_t *retval;
+
+       struct my_scsi_idlun
+       {
+               int word1;
+               int word2;
+       } idlun;
+
+       status = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun);
+       if (status)
+       {
+               return NULL; /* sorry! */
+       }
+
+       retval = (scsi_id_t *)xmalloc(sizeof(scsi_id_t));
+       retval->id = idlun.word1 & 0xff;
+       retval->lun = idlun.word1 >> 8 & 0xff;
+
 #ifdef DEBUG
-  fprintf(stderr,"SCSI:ID=%d LUN=%d\n",retval->id,retval->lun);
+       fprintf(stderr, "SCSI:ID=%d LUN=%d\n", retval->id, retval->lun);
 #endif
-  return retval;
+
+       return retval;
 }
-  
+
+
+/* Changed January 2001 by Eric Green <eric@badtux.org> to 
+ * use the Linux version 2.4 SCSI Generic facility if available.
+ * Liberally cribbed code from Doug Gilbert's sg3 utils. 
+ */
+
+#ifdef SG_IO
+#include "sg_err.h"  /* error stuff. */
+#include "sg_err.c"  /* some of Doug Gilbert's routines */
+
+/* Use the new SG_IO structure */
+int SCSI_ExecuteCommand(DEVICE_TYPE DeviceFD,
+                                               Direction_T Direction,
+                                               CDB_T *CDB,
+                                               int CDB_Length,
+                                               void *DataBuffer,
+                                               int DataBufferLength,
+                                               RequestSense_T *RequestSense)
+{
+       unsigned int status;
+       sg_io_hdr_t io_hdr;
+
+       memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
+       memset(RequestSense, 0, sizeof(RequestSense_T));
+
+       /* Fill in the common stuff... */
+       io_hdr.interface_id = 'S';
+       io_hdr.cmd_len = CDB_Length;
+       io_hdr.mx_sb_len = sizeof(RequestSense_T);
+       io_hdr.dxfer_len = DataBufferLength;
+       io_hdr.cmdp = (unsigned char *) CDB;
+       io_hdr.sbp = (unsigned char *) RequestSense;
+       io_hdr.dxferp = DataBuffer;
+       io_hdr.timeout = sg_timeout * 10; /* Convert from Jiffys to milliseconds */
+
+       if (Direction==Input)
+       {
+               /* fprintf(stderr,"direction=input\n"); */
+               io_hdr.dxfer_direction=SG_DXFER_FROM_DEV;
+       }
+       else
+       {
+               /* fprintf(stderr,"direction=output\n"); */
+               io_hdr.dxfer_direction=SG_DXFER_TO_DEV;
+       }
+
+       /* Now do it:  */
+       if ((status = ioctl(DeviceFD, SG_IO , &io_hdr)) || io_hdr.masked_status)
+       {
+               /* fprintf(stderr, "smt_scsi_cmd: Rval=%d Status=%d, errno=%d [%s]\n",status, io_hdr.masked_status,
+               errno, 
+               strerror(errno)); */
+
+               switch (sg_err_category3(&io_hdr))
+               {
+               case SG_ERR_CAT_CLEAN:
+               case SG_ERR_CAT_RECOVERED:
+                       break;
+
+               case SG_ERR_CAT_MEDIA_CHANGED:
+                       return 2;
+
+               default:
+                       return -1;
+               }
+
+               /*  fprintf(stderr,"host_status=%d driver_status=%d residual=%d writelen=%d\n",io_hdr.host_status,io_hdr.driver_status,io_hdr.resid,io_hdr.sb_len_wr ); */
+
+               return -errno;
+       }
+
+       /* Now check the returned statuses: */
+       /* fprintf(stderr,"host_status=%d driver_status=%d residual=%d writelen=%d\n",io_hdr.host_status,io_hdr.driver_status,io_hdr.resid,io_hdr.sb_len_wr ); */
+
+       SCSI_Default_Timeout();  /* reset back to default timeout, sigh. */
+       return 0;
+}
+
+#else
 
 /* Changed February 2000 by Eric Green <eric@estinc.com> to 
  * use the SCSI generic interface rather than SCSI_IOCTL_SEND_COMMAND
@@ -127,271 +227,264 @@ scsi_id_t *SCSI_GetIDLun(DEVICE_TYPE fd) {
  * manner. This sucks. But sucks less than SCSI_IOCTL_SEND_COMMAND, sigh.
  */
 
+
 #ifndef OLD_EXECUTE_COMMAND_STUFF
 
 static void slow_memcopy(unsigned char *src, unsigned char *dest, int numbytes)
 {
-  while (numbytes--) {
-    *dest++ = *src++;
-  }
+       while (numbytes--)
+       {
+               *dest++ = *src++;
+       }
 }
 
 
 int SCSI_ExecuteCommand(DEVICE_TYPE DeviceFD,
-                              Direction_T Direction,
-                              CDB_T *CDB,
-                              int CDB_Length,
-                              void *DataBuffer,
-                              int DataBufferLength,
-                              RequestSense_T *RequestSense)
+                                               Direction_T Direction,
+                                               CDB_T *CDB,
+                                               int CDB_Length,
+                                               void *DataBuffer,
+                                               int DataBufferLength,
+                                               RequestSense_T *RequestSense)
 {
+       unsigned char *Command=NULL;   /* the command data struct sent to them... */
+       unsigned char *ResultBuf=NULL; /* the data we read in return...         */
 
-  unsigned char *Command=NULL;   /* the command data struct sent to them... */
-  unsigned char *ResultBuf=NULL; /* the data we read in return...         */
+       unsigned char *src;       /* for copying stuff, sigh. */
+       unsigned char *dest;      /* for copy stuff, again, sigh. */
 
-  unsigned char *src;       /* for copying stuff, sigh. */
-  unsigned char *dest;      /* for copy stuff, again, sigh. */
+       int write_length = sizeof(struct sg_header)+CDB_Length;
+       int i;                  /* a random index...          */
+       int result;             /* the result of the write... */ 
 
-  int write_length = sizeof(struct sg_header)+CDB_Length;
-  int i;                  /* a random index...          */
-  int result;             /* the result of the write... */ 
-  
-  
-  struct sg_header *Header; /* we actually point this into Command... */
-  struct sg_header *ResultHeader; /* we point this into ResultBuf... */
+       struct sg_header *Header; /* we actually point this into Command... */
+       struct sg_header *ResultHeader; /* we point this into ResultBuf... */
 
-
-  /* First, see if we need to set our SCSI timeout to something different */
-  if (sg_timeout != SG_SCSI_DEFAULT_TIMEOUT) {
-    /* if not default, set it: */
+       /* First, see if we need to set our SCSI timeout to something different */
+       if (sg_timeout != SG_SCSI_DEFAULT_TIMEOUT)
+       {
+               /* if not default, set it: */
 #ifdef DEBUG_TIMEOUT
-    fprintf(stderr,"Setting timeout to %d\n", sg_timeout);
-    fflush(stderr);
+               fprintf(stderr,"Setting timeout to %d\n", sg_timeout);
+               fflush(stderr);
 #endif
-    if(ioctl(DeviceFD, SG_SET_TIMEOUT, &sg_timeout)) {
-      FatalError("failed to set sg timeout - %m\n");
-    }
-  }
-
-  if (Direction == Output) {  /* if we're writing, our length is longer... */
-    write_length += DataBufferLength; 
-  }
-  
-  /* allocate some memory... enough for the command plus the header +
-   *  any other data that we may need here...
-   */
-  
-  Command=(unsigned char *)xmalloc(write_length);
-  Header = (struct sg_header *) Command;  /* make it point to start of buf */
-
-  dest=Command; /* now to copy the CDB... from start of buffer,*/
-  dest+= sizeof(struct sg_header); /* increment it past the header. */
-
-  slow_memcopy((char *)CDB,dest,CDB_Length);
-
-  /* if we are writing additional data, tack it on here! */
-  if (Direction == Output) {
-    dest += CDB_Length;
-    slow_memcopy(DataBuffer,dest,DataBufferLength); /* copy to end of command */
-  }
-  /* Now to fill in the Header struct: */
-  Header->reply_len=DataBufferLength+sizeof(struct sg_header);
+               if(ioctl(DeviceFD, SG_SET_TIMEOUT, &sg_timeout))
+               {
+                       FatalError("failed to set sg timeout - %m\n");
+               }
+       }
+
+       if (Direction == Output)
+       {
+               /* if we're writing, our length is longer... */
+               write_length += DataBufferLength; 
+       }
+
+       /* allocate some memory... enough for the command plus the header +
+        *  any other data that we may need here...
+        */
+
+       Command = (unsigned char *)xmalloc(write_length);
+       Header = (struct sg_header *) Command;  /* make it point to start of buf */
+
+       dest = Command; /* now to copy the CDB... from start of buffer,*/
+       dest += sizeof(struct sg_header); /* increment it past the header. */
+
+       slow_memcopy((char *)CDB, dest, CDB_Length);
+
+       /* if we are writing additional data, tack it on here! */
+       if (Direction == Output)
+       {
+               dest += CDB_Length;
+               slow_memcopy(DataBuffer, dest, DataBufferLength); /* copy to end of command */
+       }
+
+       /* Now to fill in the Header struct: */
+       Header->reply_len=DataBufferLength+sizeof(struct sg_header);
 #ifdef DEBUG
-  fprintf(stderr,"sg:reply_len(sent)=%d\n",Header->reply_len);
+       fprintf(stderr,"sg:reply_len(sent)=%d\n",Header->reply_len);
 #endif
-  Header->twelve_byte = CDB_Length == 12; 
-  Header->result = 0;
-  Header->pack_len = write_length; /* # of bytes written... */
-  Header->pack_id = 0;             /* not used              */
-  Header->other_flags = 0;         /* not used.             */
-  Header->sense_buffer[0]=0;      /* used? */
-
-  /* Now to do the write... */
-  result=write(DeviceFD,Command,write_length);
-  
-  /* Now to check the result :-(. */
-  /* Note that we don't have any request sense here. So we have no
-   * idea what's going on. 
-   */ 
-  if ( (result < 0) || (result != write_length) || Header->result ||
-       Header->sense_buffer[0] ) {
+       Header->twelve_byte = CDB_Length == 12; 
+       Header->result = 0;
+       Header->pack_len = write_length; /* # of bytes written... */
+       Header->pack_id = 0;             /* not used              */
+       Header->other_flags = 0;         /* not used.             */
+       Header->sense_buffer[0]=0;      /* used? */
+
+       /* Now to do the write... */
+       result = write(DeviceFD,Command,write_length);
+
+       /* Now to check the result :-(. */
+       /* Note that we don't have any request sense here. So we have no
+       * idea what's going on. 
+       */ 
+       if (result < 0 || result != write_length || Header->result || Header->sense_buffer[0])
+       {
 #ifdef DEBUG_SCSI
-    fprintf(stderr,"scsi:result=%d Header->result=%d Header->sense_buffer[0]=%d\n",
-           result,Header->result,Header->sense_buffer[0]);
+               fprintf(stderr,"scsi:result=%d Header->result=%d Header->sense_buffer[0]=%d\n",
+               result,Header->result,Header->sense_buffer[0]);
 #endif  
-    /* we don't have any real sense data, sigh :-(. */
-    if (Header->sense_buffer[0]) {
-      /* well, I guess we DID have some! eep! copy the sense data! */
-      slow_memcopy((char *)Header->sense_buffer,(char *)RequestSense,
-                  sizeof(Header->sense_buffer));
-    } else {
-      dest=(unsigned char *)RequestSense;
-      *dest=(unsigned char)Header->result; /* may chop, sigh... */
-    }
-
-    /* okay, now, we may or may not need to find a non-zero value to return.
-     * For tape drives, we may get a BLANK_CHECK or MEDIUM_ERROR and find
-     * that it's *STILL* a good read! Use the STILL_A_VALID_READ macro
-     * that calls all those macros I cribbed from Richard. 
-     */
-    
-    if (!STILL_A_VALID_READ(RequestSense)) {
-      free(Command); /* zap memory leak, sigh */
-      /* okay, find us a non-zero value to return :-(. */
-      if (result) {
-       return result;
-      } else if (Header->result) {
-       return Header->result;
-      } else {
-       return -1;  /* sigh */
-      }
-    } else {
-      result=-1;
-    }
-  } else {
-    result=0; /* we're okay! */
-  }
-    
-  
-  /* now to allocate the new block.... */
-  ResultBuf=(unsigned char *)xmalloc(Header->reply_len);
-  /* now to clear ResultBuf... */
-  slow_bzero(ResultBuf,Header->reply_len); 
-
-  ResultHeader=(struct sg_header *)ResultBuf;
-  
-  /* copy the original Header... */
-  ResultHeader->result=0;
-  ResultHeader->pack_id=0;
-  ResultHeader->other_flags=0;
-  ResultHeader->reply_len=Header->reply_len;
-  ResultHeader->twelve_byte = CDB_Length == 12; 
-  ResultHeader->pack_len = write_length; /* # of bytes written... */
-  ResultHeader->sense_buffer[0]=0; /* whoops! Zero that! */
+               /* we don't have any real sense data, sigh :-(. */
+               if (Header->sense_buffer[0])
+               {
+                       /* well, I guess we DID have some! eep! copy the sense data! */
+                       slow_memcopy((char *)Header->sense_buffer,(char *)RequestSense,
+                                                sizeof(Header->sense_buffer));
+               }
+               else
+               {
+                       dest=(unsigned char *)RequestSense;
+                       *dest=(unsigned char)Header->result; /* may chop, sigh... */
+               }
+
+               /* okay, now, we may or may not need to find a non-zero value to return.
+               * For tape drives, we may get a BLANK_CHECK or MEDIUM_ERROR and find
+               * that it's *STILL* a good read! Use the STILL_A_VALID_READ macro
+               * that calls all those macros I cribbed from Richard. 
+               */
+
+               if (!STILL_A_VALID_READ(RequestSense))
+               {
+                       free(Command); /* zap memory leak, sigh */
+                       /* okay, find us a non-zero value to return :-(. */
+                       if (result)
+                       {
+                               return result;
+                       }
+                       else if (Header->result)
+                       {
+                               return Header->result;
+                       }
+                       else
+                       {
+                               return -1;  /* sigh */
+                       }
+               }
+               else
+               {
+                       result=-1;
+               }
+       }
+       else
+       {
+               result=0; /* we're okay! */
+       }
+
+       /* now to allocate the new block.... */
+       ResultBuf=(unsigned char *)xmalloc(Header->reply_len);
+       /* now to clear ResultBuf... */
+       slow_bzero(ResultBuf,Header->reply_len); 
+
+       ResultHeader=(struct sg_header *)ResultBuf;
+
+       /* copy the original Header... */
+       ResultHeader->result=0;
+       ResultHeader->pack_id=0;
+       ResultHeader->other_flags=0;
+       ResultHeader->reply_len=Header->reply_len;
+       ResultHeader->twelve_byte = CDB_Length == 12; 
+       ResultHeader->pack_len = write_length; /* # of bytes written... */
+       ResultHeader->sense_buffer[0]=0; /* whoops! Zero that! */
 #ifdef DEBUG
-  fprintf(stderr,"sg:Reading %d bytes from DeviceFD\n",Header->reply_len);
-  fflush(stderr);
+       fprintf(stderr,"sg:Reading %d bytes from DeviceFD\n",Header->reply_len);
+       fflush(stderr);
 #endif
-  result=read(DeviceFD,ResultBuf,Header->reply_len);
+       result=read(DeviceFD,ResultBuf,Header->reply_len);
 #ifdef DEBUG
-  fprintf(stderr,"sg:result=%d ResultHeader->result=%d\n",
-         result,ResultHeader->result);
-  fflush(stderr);
+       fprintf(stderr,"sg:result=%d ResultHeader->result=%d\n",
+       result,ResultHeader->result);
+       fflush(stderr);
 #endif
-  /* New: added check to see if the result block is still all zeros! */
-  if ( (result < 0) || (result != Header->reply_len) || ResultHeader->result ||
-       ResultHeader->sense_buffer[0] ) {
+       /* New: added check to see if the result block is still all zeros! */
+       if (result < 0 ||
+               result != Header->reply_len ||
+               ResultHeader->result ||
+               ResultHeader->sense_buffer[0])
+       {
 #ifdef DEBUG
-    fprintf(stderr,
-           "scsi: result=%d Header->reply_len=%d ResultHeader->result=%d ResultHeader->sense_buffer[0]=%d\n",
-           result,
-           Header->reply_len,
-           ResultHeader->result,
-           ResultHeader->sense_buffer[0]);
+               fprintf(stderr,
+               "scsi: result=%d Header->reply_len=%d ResultHeader->result=%d ResultHeader->sense_buffer[0]=%d\n",
+               result,
+               Header->reply_len,
+               ResultHeader->result,
+               ResultHeader->sense_buffer[0]);
 #endif
-    /* eep! copy the sense data! */
-    slow_memcopy((char *)ResultHeader->sense_buffer,(char *)RequestSense,
-                sizeof(ResultHeader->sense_buffer));
-    /* sense data copied, now find us a non-zero value to return :-(. */
-    /* NOTE: Some commands return sense data even though they validly
-     * executed! We catch a few of those with the macro STILL_A_VALID_READ.
-     */
-
-    if (!STILL_A_VALID_READ(RequestSense)) {
-      free(Command);
-      if (result) {
-       free(ResultBuf);
-       return result;
-      } else if (ResultHeader->result) {
-       free(ResultBuf);
-       return ResultHeader->result;
-      } else {
-       free(ResultBuf);
-       return -1; /* sigh! */
-      } 
-    } else {
-      result=-1; /* if it was a valid read, still have -1 result. */
-    }
-  } else {
-    result=0;
-  }
-  
-  /* See if we need to reset our SCSI timeout */
-  if (sg_timeout != SG_SCSI_DEFAULT_TIMEOUT) {
-    sg_timeout = SG_SCSI_DEFAULT_TIMEOUT; /* reset it back to default */
+               /* eep! copy the sense data! */
+               slow_memcopy((char *)ResultHeader->sense_buffer,(char *)RequestSense,
+               sizeof(ResultHeader->sense_buffer));
+               /* sense data copied, now find us a non-zero value to return :-(. */
+               /* NOTE: Some commands return sense data even though they validly
+               * executed! We catch a few of those with the macro STILL_A_VALID_READ.
+               */
+
+               if (!STILL_A_VALID_READ(RequestSense))
+               {
+                       free(Command);
+                       if (result)
+                       {
+                               free(ResultBuf);
+                               return result;
+                       }
+                       else if (ResultHeader->result)
+                       {
+                               free(ResultBuf);
+                               return ResultHeader->result;
+                       }
+                       else
+                       {
+                               free(ResultBuf);
+                               return -1; /* sigh! */
+                       } 
+               }
+               else
+               {
+                       result=-1; /* if it was a valid read, still have -1 result. */
+               }
+       }
+       else
+       {
+               result=0;
+       }
+
+       /* See if we need to reset our SCSI timeout */
+       if (sg_timeout != SG_SCSI_DEFAULT_TIMEOUT)
+       {
+               sg_timeout = SG_SCSI_DEFAULT_TIMEOUT; /* reset it back to default */
+
 #ifdef DEBUG_TIMEOUT
-    fprintf(stderr,"Setting timeout to %d\n", sg_timeout);
-    fflush(stderr);
+               fprintf(stderr,"Setting timeout to %d\n", sg_timeout);
+               fflush(stderr);
 #endif
-    /* if not default, set it: */
-    if(ioctl(DeviceFD, SG_SET_TIMEOUT, &sg_timeout)) {
-      FatalError("failed to set sg timeout - %m\n");
-    }
-  }
-  
-  
-  /* now for the crowning moment: copying any result into the DataBuffer! */
-  /* (but only if it were an input command and not an output command :-}  */
-  if (Direction == Input) {
+               /* if not default, set it: */
+               if (ioctl(DeviceFD, SG_SET_TIMEOUT, &sg_timeout))
+               {
+                       FatalError("failed to set sg timeout - %m\n");
+               }
+       }
+
+       /* now for the crowning moment: copying any result into the DataBuffer! */
+       /* (but only if it were an input command and not an output command :-}  */
+       if (Direction == Input)
+       {
 #ifdef DEBUG
-    fprintf(stderr,"Header->reply_len=%d,ResultHeader->reply_len=%d\n",
-           Header->reply_len,ResultHeader->reply_len);
+               fprintf(stderr,"Header->reply_len=%d,ResultHeader->reply_len=%d\n",
+               Header->reply_len,ResultHeader->reply_len);
 #endif
-    src=ResultBuf+sizeof(struct sg_header);
-    dest=DataBuffer;
-    for (i=0;i< (ResultHeader->reply_len);i++) {
-      if (i>=DataBufferLength) break;  /* eep! */
-      *dest++=*src++;
-    }
-  }
-  
-  /* and return! */
-  free(Command);    /* clean up memory leak... */
-  free(ResultBuf);
-  return result; /* good stuff ! */
+               src=ResultBuf+sizeof(struct sg_header);
+               dest=DataBuffer;
+               for (i = 0; i < ResultHeader->reply_len; i++)
+               {
+                       if (i >= DataBufferLength)
+                               break;  /* eep! */
+                       *dest++ = *src++;
+               }
+       }
+
+       /* and return! */
+       free(Command);    /* clean up memory leak... */
+       free(ResultBuf);
+       return result; /* good stuff ! */
 }
 
 #endif  
-  
-
-#ifdef OLD_EXECUTE_COMMAND_STUFF
-
-int SCSI_ExecuteCommand(int DeviceFD,
-                              Direction_T Direction,
-                              CDB_T CDB,
-                              int CDB_Length,
-                              void *DataBuffer,
-                              int DataBufferLength,
-                              RequestSense_T *RequestSense)
-{
-  unsigned char *Command;
-  int Zero = 0, Result;
-  memset(RequestSense, 0, sizeof(RequestSense_T));
-  switch (Direction)
-    {
-    case Input:
-      Command = (unsigned char *)
-       xmalloc(8 + max(DataBufferLength, sizeof(RequestSense_T)));
-      memcpy(&Command[0], &Zero, 4);
-      memcpy(&Command[4], &DataBufferLength, 4);
-      memcpy(&Command[8], CDB, CDB_Length);
-      break;
-    case Output:
-      Command = (unsigned char *)
-       xmalloc(8 + max(CDB_Length + DataBufferLength, sizeof(RequestSense_T)));
-      memcpy(&Command[0], &DataBufferLength, 4);
-      memcpy(&Command[4], &Zero, 4);
-      memcpy(&Command[8], CDB, CDB_Length);
-      memcpy(&Command[8 + CDB_Length], DataBuffer, DataBufferLength);
-      break;
-    }
-  Result = ioctl(DeviceFD, SCSI_IOCTL_SEND_COMMAND, Command);
-  if (Result != 0)
-    memcpy(RequestSense, &Command[8], sizeof(RequestSense_T));
-  else if (Direction == Input)
-    memcpy(DataBuffer, &Command[8], DataBufferLength);
-  free(Command);
-  return Result;
-}
-
-#endif
+#endif   /* #ifdef  SG_IO    */