Christoffer Hall-Frederiksen writes:
- I have a Exabyte EXB-480 gismo with 4 Exabyte Mammoth EXB-8900
- tapedrives in it. Now if I use Eric Lee Green's mtx (1.2.12) the
- whole thing works just great. I can load and unload tapes and get
- a nice status of the robot just fine. But in my test-setup of amanda
- (version 2.4.2) I get a rather strange error when I use chg-scsi.
- Amcheck tells me this:

        Amanda 2.4.x doesn't have the complete support for the
Exabyte EXB-4x0 robots.. I posted a group of patches to amanda-hackers
a number of weeks/months ago (didn't I?) to allow it to work.

        I'll attach those patches here as well.  I've been using
Amanda with an EXB-480 since last September, quite successfully
(abit on a NetBSD/Alpha host) Also enclosed is a patch to keep
the server from leaking filedescriptors on large robots (like
the EXB-480.)

--
Eric Schnoebelen                [EMAIL PROTECTED]           http://www.cirr.com
  There are two ways of constructing a software design: one way is to make 
  it so simple that there are obviously no deficiencies, and the other is 
  to make it so complicated there are no obvious deficiencies - CAR Hoare

$NetBSD$
# Commentary:
#   The vast majority of the changes in this patch are to add support/fix
#    for the Exabyte EXB8505 8MM tape drive, when attached to NetBSD, and
#    within an EXB-4[48]0 robot.
#   A smaller number of the changes are add support for the EXB-4[48]0 
#    SCSI robots.
#   The remainder of the changes aer to improve the debugg-ability of
#    the program, and the quality of the debug log
#   A number of segmentation violations were also removed.
#   SCSI_LoadUnload was recoded to use a private structure, to make
#    sure the correct bitfields were set.
#   Finally, a new function was added to set/clear (currently only used
#    to clear) the Prevent/Allow Medium Removal flag.
#   
--- changer-src/scsi-changer-driver.c.orig      Tue Oct 24 19:21:15 2000
+++ changer-src/scsi-changer-driver.c   Sat Feb 17 21:23:08 2001
@@ -92,6 +92,7 @@
 int GenericFree();
 int TapeStatus();                   /* Is the tape loaded ? */
 int DLT4000Eject(char *Device, int type);
+int EXB8505Eject(char *Device, int type);
 int GenericEject(char *Device, int type);
 int GenericClean(char *Device);                 /* Does the tape need a clean */
 int GenericBarCode(int DeviceFD);               /* Do we have Barcode reader support 
*/
@@ -225,6 +226,30 @@
     EXB120BarCode,
     GenericSearch,
     EXB120SenseHandler}},
+  {"EXB-440",   
+    "Exabyte Robot [EXB-440]",
+   {GenericMove,
+    GenericElementStatus,
+    GenericResetStatus,
+    GenericFree,
+    GenericEject,
+    GenericClean,
+    GenericRewind,
+    EXB120BarCode,
+    GenericSearch,
+    EXB10eSenseHandler}},
+  {"EXB-480",   
+    "Exabyte Robot [EXB-480]",
+   {GenericMove,
+    GenericElementStatus,
+    GenericResetStatus,
+    GenericFree,
+    GenericEject,
+    GenericClean,
+    GenericRewind,
+    EXB120BarCode,
+    GenericSearch,
+    EXB10eSenseHandler}},
   {"EXB-85058HE-0000",        
    "Exabyte Tape [EXB-85058HE-0000]",
    {DoNothing,
@@ -237,6 +262,19 @@
     GenericBarCode,
     GenericSearch,
     EXB85058SenseHandler}},
+  {"EXB-85058SQANXR1",        
+   "Exabyte Tape [EXB-85058SQANXR1]",
+   {DoNothing,
+    DoNothing,
+    DoNothing,
+    DoNothing,
+    /* DLT4000Eject, */
+    EXB8505Eject,
+    GenericClean,
+    GenericRewind,
+    GenericBarCode,
+    GenericSearch,
+    EXB85058SenseHandler}},
     /* Tandberg Devices */
   {"TDS 1420",              
    "Tandberg Robot (TDS 1420)",
@@ -364,9 +402,15 @@
   {0x39,
    "EXB-85058HE-0000",
    EXB85058HEPage39},
+  {0x39,
+   "EXB-85058SQANXR1",        
+   EXB85058HEPage39},
   {0x3c,
    "EXB-85058HE-0000",
    EXB85058HEPage3c},
+  {0x3c,
+   "EXB-85058SQANXR1",        
+   EXB85058HEPage3c},
   {0, NULL, NULL}
 };
 
@@ -512,13 +556,13 @@
 
 int drive_loaded(int fd, int drivenum)
 {
-
   dbprintf(("###### START drive_loaded\n"));
   dbprintf(("%-20s : fd %d drivenum %d \n", "drive_loaded", fd, drivenum));
 
   if (pChangerDev == NULL)
     {
       dbprintf(("%-20s : pChangerCtl == NULL\n", "drive_loaded"));
+      dbprintf(("###### STOP  drive_loaded: -1\n"));
       return(-1);
     }
 
@@ -526,12 +570,18 @@
       {
           if (pChangerDev->functions->function[CHG_STATUS](fd, 1) != 0)
               {
+                 dbprintf(("###### STOP  drive_loaded: -1\n"));
                   return(-1);
               }
       }
 
   if (pDTE[drivenum].status == 'E')
+    {
+      dbprintf(("###### STOP  drive_loaded: 0\n"));
       return(0);
+    }
+
+  dbprintf(("###### STOP  drive_loaded: 1\n"));
   return(1);
 }
 
@@ -822,8 +872,10 @@
       }
 
 
-  GenericRewind(pwork->fd);
- 
+  /*
+   * call the drive specific rewind function
+   */
+  pwork->functions->function[CHG_REWIND](pwork->fd);
 
   while (true && cnt < wait)
     {
@@ -1340,7 +1392,7 @@
       dbprintf(("Ident = [%s], function = [%s]\n", pChangerDev->ident,
                 pChangerDev->functions->ident));
       ret = pChangerDev->functions->function[CHG_ERROR](DeviceFD, flag, buffer);
-      dbprintf(("#### STOP SenseHandler\n"));
+      dbprintf(("#### STOP SenseHandler (pChangerDev): %d\n", ret));
       return(ret);
     }
 
@@ -1349,20 +1401,20 @@
       dbprintf(("Ident = [%s], function = [%s]\n", pTapeDev->ident,
                pTapeDev->functions->ident));
       ret = pTapeDev->functions->function[CHG_ERROR](DeviceFD, flag, buffer);
-      dbprintf(("#### STOP SenseHandler\n"));
+      dbprintf(("#### STOP SenseHandler (pTapeDev): %d\n", ret));
     
        return(ret);
     }
   
   if (pTapeDevCtl != NULL && pTapeDevCtl->fd == DeviceFD)
     {
-      dbprintf(("Ident = [%s], function = [%s]\n", pTapeDev->ident,
+      dbprintf(("Ident = [%s], function = [%s]\n", pTapeDevCtl->ident,
                pTapeDevCtl->functions->ident));
       ret = pTapeDevCtl->functions->function[CHG_ERROR](DeviceFD, flag, buffer);
-      dbprintf(("#### STOP SenseHandler\n"));
+      dbprintf(("#### STOP SenseHandler (pTapeDevCtl): %d\n", ret));
       return(ret);
     }
-  dbprintf(("#### STOP SenseHandler\n"));
+  dbprintf(("#### STOP SenseHandler: (SENSE_ABORT)\n"));
   return(SENSE_ABORT);
 }
 
@@ -1392,6 +1444,122 @@
   return(0);
 }
 
+int EXB8505Eject(char *Device, int type)
+{
+  RequestSense_T *pRequestSense;
+  ExtendedRequestSense_T *pExtendedRequestSense;
+  int ret;
+  int cnt = 0;
+  int true = 1;
+
+  dbprintf(("##### START EXB8505Eject (type=%d)\n", type));
+
+  if ((pRequestSense = malloc(sizeof(RequestSense_T))) == NULL)
+    {
+      dbprintf(("%-20s : malloc failed\n","EXB8505Eject"));
+      return(-1);
+    }
+
+  if ((pExtendedRequestSense = malloc(sizeof(ExtendedRequestSense_T))) == NULL)
+    {
+      dbprintf(("%-20s : malloc failed\n","EXB8505Eject"));
+      return(-1);
+    }
+  
+  if (pTapeDevCtl != NULL && pTapeDevCtl->SCSI == 1)
+    LogSense(pTapeDevCtl->fd);
+  
+  if ( type > 1)
+    {
+      dbprintf(("EXB8505Eject : use mtio ioctl for eject on %s (%s)\n", 
+                 ((pTapeDev != NULL) ? pTapeDev->dev : pTapeDevCtl->dev),
+                 ((pTapeDev != NULL) ? pTapeDev->ident : pTapeDevCtl->ident)));
+      return(Tape_Eject(((pTapeDev != NULL) ? pTapeDev->fd : pTapeDevCtl->fd)));
+    }
+  
+  if (pTapeDev != NULL && 
+                 pTapeDevCtl != NULL &&
+                 pTapeDev->fd != pTapeDevCtl->fd && 
+                 pTapeDevCtl->SCSI == 1) {
+    dbprintf(("EXB8505Eject : Close %s \n", pTapeDev->dev));
+    close(pTapeDev->fd);
+  }
+  
+  
+  if (pTapeDevCtl->SCSI == 0)
+    {
+      dbprintf(("EXB8505Eject : Device %s not able to receive SCSI commands\n", 
+pTapeDev->dev));
+      return(Tape_Eject((pTapeDev != NULL) ? pTapeDev->fd : pTapeDevCtl->fd));
+    }
+  
+  
+  dbprintf(("EXB8505Eject : SCSI eject on %s = %s\n", 
+                             pTapeDevCtl->dev, pTapeDevCtl->ident));
+  
+  RequestSense(pTapeDevCtl->fd, pExtendedRequestSense, 0); 
+  DecodeExtSense(pExtendedRequestSense, "EXB8505Eject : ", debug_file);
+  /*
+   * Tell the tape drive it _can_ actually eject the tape
+   */
+  ret = SCSI_MediumRemoval(pTapeDevCtl->fd, pRequestSense, 0);
+
+  RequestSense(pTapeDevCtl->fd, pExtendedRequestSense, 0); 
+  DecodeExtSense(pExtendedRequestSense, "EXB8505Eject : ", debug_file);
+
+  /*
+   * Unload the tape, 0 ==  wait for success; 0 == unload 
+   */
+  ret = SCSI_LoadUnload(pTapeDevCtl->fd, pRequestSense, 0, 0);
+
+  RequestSense(pTapeDevCtl->fd, pExtendedRequestSense, 0); 
+  DecodeExtSense(pExtendedRequestSense, "EXB8505Eject : ", debug_file);
+  
+  /* < 0 == fatal */
+  if (ret < 0)
+    return(-1);
+  
+  if ( ret > 0)
+    {
+    }
+  
+  true = 1;
+  
+  
+  /*
+   * the EXB8505 is never going to test UNIT_READY when there is no
+   * tape present.  We need to loop, testing until we get
+   * pExtendedRequestSense.TNP == 1, at which point (we hope) the tape has
+   * been dismounted
+   */
+  while (true && cnt < 300)
+    {
+      /*
+      if (SCSI_TestUnitReady(pTapeDevCtl->fd, pRequestSense))
+        {
+          true = 0;
+          break;
+        }
+      */
+      RequestSense(pTapeDevCtl->fd, pExtendedRequestSense, 0); 
+      DecodeExtSense(pExtendedRequestSense, "EXB8505Eject : ", debug_file);
+
+      if (pExtendedRequestSense->TNP == 1)
+        {
+          true=0;
+          break;
+        } else {
+          cnt++;
+          sleep(2);
+        }
+    }
+  
+  free(pRequestSense);
+  
+  dbprintf(("EXB8505Eject : Ready after %d sec, true = %d\n", cnt * 2, true));
+  return(0);
+  
+}
+
 int DLT4000Eject(char *Device, int type)
 {
   RequestSense_T *pRequestSense;
@@ -1404,30 +1572,32 @@
 
   if ((pRequestSense = malloc(sizeof(RequestSense_T))) == NULL)
     {
-      dbprintf(("%-20s : malloc failed\n","GenericEject"));
+      dbprintf(("%-20s : malloc failed\n","DLT4000Eject"));
       return(-1);
     }
 
   if ((pExtendedRequestSense = malloc(sizeof(ExtendedRequestSense_T))) == NULL)
     {
-      dbprintf(("%-20s : malloc failed\n","GenericEject"));
+      dbprintf(("%-20s : malloc failed\n","DLT4000Eject"));
       return(-1);
     }
   
-  if (pTapeDevCtl != NULL && pTapeDevCtl->SCSI == 1 && pTapeDev != NULL)
-    LogSense(pTapeDev->fd);
+  if (pTapeDevCtl != NULL && pTapeDevCtl->SCSI == 1)
+    LogSense(pTapeDevCtl->fd);
   
   if ( type > 1)
     {
-      dbprintf(("GenericEject : use mtio ioctl for eject on %s\n", pTapeDev->dev));
-      return(Tape_Eject(pTapeDev->fd));
+      dbprintf(("DLT4000Eject : use mtio ioctl for eject on %s (%s)\n", 
+                 ((pTapeDev != NULL) ? pTapeDev->dev : pTapeDevCtl->dev),
+                 ((pTapeDev != NULL) ? pTapeDev->ident : pTapeDevCtl->ident)));
+      return(Tape_Eject(((pTapeDev != NULL) ? pTapeDev->fd : pTapeDevCtl->fd)));
     }
   
   if (pTapeDev != NULL && 
                  pTapeDevCtl != NULL &&
                  pTapeDev->fd != pTapeDevCtl->fd && 
                  pTapeDevCtl->SCSI == 1) {
-    dbprintf(("GenericEject : Close %s \n", pTapeDev->dev));
+    dbprintf(("DLT4000Eject : Close %s \n", pTapeDev->dev));
     close(pTapeDev->fd);
   }
   
@@ -1493,7 +1663,7 @@
   int cnt = 0;
   int true = 1;
 
-  dbprintf(("##### START GenericEject\n"));
+  dbprintf(("##### START GenericEject(%s,%d)\n", Device, type));
 
   if ((pRequestSense = malloc(sizeof(RequestSense_T))) == NULL)
     {
@@ -1501,13 +1671,15 @@
       return(-1);
     }
   
-  if (pTapeDevCtl != NULL && pTapeDevCtl->SCSI == 1 && pTapeDev != NULL)
-    LogSense(pTapeDev->fd);
+  if (pTapeDevCtl != NULL && pTapeDevCtl->SCSI == 1)
+    LogSense(pTapeDevCtl->fd);
   
   if ( type > 1)
     {
-      dbprintf(("GenericEject : use mtio ioctl for eject on %s\n", pTapeDev->dev));
-      return(Tape_Eject(pTapeDev->fd));
+      dbprintf(("GenericEject : use mtio ioctl for eject on %s (%s)\n", 
+                 ((pTapeDev != NULL) ? pTapeDev->dev : pTapeDevCtl->dev),
+                 ((pTapeDev != NULL) ? pTapeDev->ident : pTapeDevCtl->ident)));
+      return(Tape_Eject(((pTapeDev != NULL) ? pTapeDev->fd : pTapeDevCtl->fd)));
     }
   
   if (pTapeDev != NULL && 
@@ -2096,8 +2268,11 @@
               break;
             }
           break;
+       case SENSE_NULL:
+         ret = SENSE_NO;
+         break;
         default:
-          dbprintf(("EXB85058SenseHandler : Unknow %x ASC = %x ASCQ = %x\n",
+          dbprintf(("EXB85058SenseHandler : Unknown SenseKey = %x ASC = %x ASCQ = 
+%x\n",
                     pRequestSense->SenseKey,
                     pRequestSense->AdditionalSenseCode,
                     pRequestSense->AdditionalSenseCodeQualifier));
@@ -4046,18 +4221,14 @@
                             sizeof(ExtendedRequestSense_T),  
                             (char *) &RequestSense, sizeof(RequestSense_T));
   
-  
-  if (ret < 0)
-    {
-      return(ret);
-    }
-  
   if ( ret > 0)
     {
       DecodeExtSense(ExtendedRequestSense, "RequestSense : ",debug_file);
-      return(RequestSense.SenseKey);
+      ret = RequestSense.SenseKey;
     }
-  return(0);
+
+  dbprintf(("##### STOP RequestSense; ret=%d\n", ret));
+  return(ret);
 }
 
 
@@ -4973,6 +5144,72 @@
   return(ret);
 }
 
+/*
+ * the following may be an Exabyte specific command
+ * No, At least the DLT2000/DLT2700 system supports it, as does the
+ * ARCHIVE 4586NP Autoloader
+ *
+ *  Set/Clear the Prevent Medium Removal bit on the drive.
+ *   On an Exabyte drive, Setting the bit will cause the drive to 
+ *   logically unload the drive without physically unloading it.
+ *   Clearing the bit allows logical unload to also physically unload
+ */
+int SCSI_MediumRemoval(int DeviceFD, RequestSense_T *pRequestSense, unsigned prevent)
+{
+  CDB_T CDB;
+  int ret;
+
+  /* Inline a structure to see if it cures the problem.. */
+  struct SCSIMedRemovalCmd {
+    char cmd;
+#ifdef LITTLE_ENDIAN_BITFIELDS 
+    PackedBit   Rsvd1:5;                       /* Byte 01 Bits 0-4 */
+    PackedBit  LUN:3;                          /* byte 01 Bits 5-7 */
+#else 
+    PackedBit  LUN:3;                          /* byte 01 Bits 5-7 */
+    PackedBit   Rsvd1:5;                       /* Byte 01 Bits 0-4 */
+#endif
+    char Rsvd2[2];
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit   Prevent:1;                     /* Byte 04 Bit 0    */
+    PackedBit  Rsvd3:6;                        /* byte 04 Bits 1-7 */
+#else 
+    PackedBit  Rsvd3:6;                        /* byte 04 Bits 1-7 */
+    PackedBit   Prevent:1;                     /* Byte 04 Bit 0    */
+#endif
+#ifdef LITTLE_ENDIAN_BITFIELDS 
+    PackedBit   Zero1:1;                       /* Byte 05 Bit 0    */
+    PackedBit   Zero2:1;                       /* Byte 05 Bit 1    */
+    PackedBit   Rsvd4:4;                       /* Byte 05 Bits 2-5 */
+    PackedBit  VdrUnq:2;                       /* byte 05 Bits 6-7 */
+#else 
+    PackedBit  VdrUnq:2;                       /* byte 05 Bits 6-7 */
+    PackedBit   Rsvd4:4;                       /* Byte 05 Bits 2-5 */
+    PackedBit   Zero2:1;                       /* Byte 05 Bit 1    */
+    PackedBit   Zero1:1;                       /* Byte 05 Bit 0    */
+#endif
+  } SCSIMedRemoval;
+
+
+  dbprintf(("##### START SCSI_MediumRemoval (prevent=%d)\n", prevent));
+  
+  memset(&SCSIMedRemoval, 0, sizeof(struct SCSIMedRemovalCmd));
+
+  SCSIMedRemoval.cmd = 0x1E;
+  SCSIMedRemoval.Prevent = prevent;
+
+  memcpy(CDB, &SCSIMedRemoval, sizeof(SCSIMedRemoval)); 
+ 
+  ret = SCSI_ExecuteCommand(DeviceFD, Input, CDB, 
+                           sizeof(SCSIMedRemoval), 0, 0, 
+                            (char *) pRequestSense,
+                            sizeof(RequestSense_T));
+    
+  ret = (ret < 0);
+
+  dbprintf(("#### STOP SCSI_MediumRemoval : ret=%d\n", ret));
+  return(ret);
+}
 
 int SCSI_Move(int DeviceFD, unsigned char chm, int from, int to)
 {
@@ -5052,23 +5289,60 @@
   return(ret);
 }
 
-int SCSI_LoadUnload(int DeviceFD, RequestSense_T *pRequestSense, unsigned char byte1, 
unsigned char load)
+int SCSI_LoadUnload(int DeviceFD, RequestSense_T *pRequestSense, unsigned char immed, 
+unsigned char load)
 {
   CDB_T CDB;
   int ret;
+  /* Inline a structure to see if it cures the problem.. */
+  struct SCSILoadCmd {
+    char cmd;
+#ifdef LITTLE_ENDIAN_BITFIELDS 
+    PackedBit   Immed:1;                       /* Byte 01 Bit 0    */
+    PackedBit   Rsvd1:4;                       /* Byte 01 Bits 1-4 */
+    PackedBit  LUN:3;                          /* byte 01 Bits 5-7 */
+#else 
+    PackedBit  LUN:3;                          /* byte 01 Bits 5-7 */
+    PackedBit   Rsvd1:4;                       /* Byte 01 Bits 1-4 */
+    PackedBit   Immed:1;                       /* Byte 01 Bit 0    */
+#endif
+    char Rsvd2[2];
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit   Load:1;                                /* Byte 04 Bit 0    */
+    PackedBit   Rtn:1;                         /* Byte 04 Bit 1    */
+    PackedBit   EOT:1;                         /* Byte 04 Bit 2    */
+    PackedBit  Rsvd3:3;                        /* byte 04 Bits 3-7 */
+#else 
+    PackedBit  Rsvd3:3;                        /* byte 04 Bits 3-7 */
+    PackedBit   EOT:1;                         /* Byte 04 Bit 2    */
+    PackedBit   Rtn:1;                         /* Byte 04 Bit 1    */
+    PackedBit   Load:1;                                /* Byte 04 Bit 0    */
+#endif
+#ifdef LITTLE_ENDIAN_BITFIELDS 
+    PackedBit   Zero1:1;                       /* Byte 05 Bit 0    */
+    PackedBit   Zero2:1;                       /* Byte 05 Bit 1    */
+    PackedBit   Rsvd4:4;                       /* Byte 05 Bits 2-5 */
+    PackedBit  VdrUnq:2;                       /* byte 05 Bits 6-7 */
+#else 
+    PackedBit  VdrUnq:2;                       /* byte 05 Bits 6-7 */
+    PackedBit   Rsvd4:4;                       /* Byte 05 Bits 2-5 */
+    PackedBit   Zero2:1;                       /* Byte 05 Bit 1    */
+    PackedBit   Zero1:1;                       /* Byte 05 Bit 0    */
+#endif
+  } SCSILoad;
+
+
+  dbprintf(("##### START SCSI_LoadUnload (immed=%d, load=%d)\n", immed, load));
+  
+  memset(&SCSILoad, 0, sizeof(struct SCSILoadCmd));
+
+  SCSILoad.cmd = SC_COM_UNLOAD;
+  SCSILoad.Immed = immed;
+  SCSILoad.Load = load;
 
-  dbprintf(("##### START SCSI_LoadUnload\n"));
-  
-  CDB[0] = SC_COM_UNLOAD;
-  CDB[1] = byte1;             
-  CDB[2] = 0;
-  CDB[3] = 0;
-  CDB[4] = load;
-  CDB[5] = 0;
-  
+  memcpy(CDB, &SCSILoad, sizeof(SCSILoad)); 
  
-  ret = SCSI_ExecuteCommand(DeviceFD, Input, CDB, 6,
-                            0, 0, 
+  ret = SCSI_ExecuteCommand(DeviceFD, Input, CDB, 
+                           sizeof(SCSILoad), 0, 0, 
                             (char *) pRequestSense,
                             sizeof(RequestSense_T));
     
@@ -5084,6 +5358,7 @@
 int SCSI_TestUnitReady(int DeviceFD, RequestSense_T *pRequestSense)
 {
   CDB_T CDB;
+  int ret=0;
 
   dbprintf(("##### START SCSI_TestUnitReady\n"));
 
@@ -5099,12 +5374,10 @@
                       (char *) pRequestSense,
                       sizeof(RequestSense_T));
 
-  if (pRequestSense->ErrorCode == 0 && pRequestSense->SenseKey == 0)
-    {
-      return(1);
-    }
+  ret = (pRequestSense->ErrorCode == 0 && pRequestSense->SenseKey == 0);
   
-  return(0);
+  dbprintf(("##### STOP SCSI_TestUnitReady=%d\n", ret));
+  return(ret);
 }
 
 
$NetBSD$
# Commentary:
#   Re-ordered the opening of the `scsitapedev' control device.  It is
#    opened before the `dev' device. The failure to open `dev' was made
#    non-fatal, as chg-scsi doesn't realy use `dev' for anything.
#   The reasoning for the reordering is that on NetBSD, /dev/nrstX
#    returns ENODEV on a tape device when the device does not have 
#    the medium ready.  /dev/enrstX has no such restrictions, and makes
#    an excellent `scsitapedev'
#
--- changer-src/chg-scsi.c.orig Tue Oct 24 18:49:39 2000
+++ changer-src/chg-scsi.c      Sat Feb 17 22:32:27 2001
@@ -947,32 +947,32 @@
 
     fd = pChangerDev->fd;
 
-    if (tape_device != NULL)
+    if (scsitapedevice != NULL)
       {
-        if ((pTapeDev = OpenDevice(tape_device, "tape_device", 
chg.conf[confnum].tapeident)) == NULL)
+        if ((pTapeDevCtl = OpenDevice(scsitapedevice, "scsitapedevice", 
+chg.conf[confnum].tapeident)) == NULL)
           {
-            dbprintf(("warning open of %s: failed\n",  tape_device));
+            dbprintf(("open: %s: failed: %s\n", scsitapedevice, strerror(errno)));
           }
       }
-    /*
-      if (pTapeDev != NULL)
-      close(pTapeDev->fd);
-    */
 
-    if (scsitapedevice != NULL)
+    if (tape_device != NULL)
       {
-        if ((pTapeDevCtl = OpenDevice(scsitapedevice, "scsitapedevice", 
chg.conf[confnum].tapeident)) == NULL)
+        if ((pTapeDev = OpenDevice(tape_device, "tape_device", 
+chg.conf[confnum].tapeident)) == NULL)
           {
-            printf("open: %s: failed\n", scsitapedevice);
+         dbprintf(("warning: open of %s: failed: %s\n",  
+                                       tape_device, strerror(errno)));
+         if ( scsitapedevice == NULL )
+           {
+             printf("open: %s: failed: %s\n", tape_device, strerror(errno));
             return(2);
           }
-      } else {
-       if (pTapeDev != NULL && pTapeDev->SCSI == 1)
-       {
-               pTapeDevCtl = pTapeDev;
        }
      }
     
+    /*
+      if (pTapeDev != NULL)
+      close(pTapeDev->fd);
+    */
 
     if (pTapeDevCtl != NULL)
       {
--- server-src/changer.c.orig   Sun Feb 18 17:52:21 2001
+++ server-src/changer.c        Sun Feb 18 17:54:02 2001
@@ -342,7 +342,7 @@
                                       strerror(errno),
                                       NULL);
        exitcode = 2;
-       goto done;
+       goto failed;
     }
     if(fd[0] < 0 || fd[0] >= FD_SETSIZE) {
        ap_snprintf(num1, sizeof(num1), "%d", fd[0]);
@@ -479,7 +479,10 @@
     }
 
 done:
+    aclose(fd[0]);
+    aclose(fd[1]);
 
+failed:
     dbprintf(("changer: got exit: %d str: %s\n", exitcode, changer_resultstr)); 
 
     amfree(cmdstr);

Reply via email to