Copyright 1997-1998 by Leonard N. Zubkoff.
Copyright 1999-2006 by Eric Lee Green.
- Copyright 2007 by Robert Nelson <robertn@the-nelsons.org>
+ Copyright 2007-2008 by Robert Nelson <robertn@the-nelsons.org>
- $Date: 2007-03-24 18:14:01 -0700 (Sat, 24 Mar 2007) $
- $Revision: 166 $
+ $Date: 2008-08-19 03:03:38 -0700 (Tue, 19 Aug 2008) $
+ $Revision: 193 $
This file created Feb 2000 by Eric Lee Green <eric@badtux.org> from pieces
extracted from mtx.c, plus a near total re-write of most of the beast.
/* set us a very short timeout, sigh... */
SCSI_Set_Timeout(30); /* 30 seconds, sigh! */
- if (SCSI_ExecuteCommand(fd, Input, &CDB, 6,
- Inquiry, sizeof(Inquiry_T), RequestSense) != 0)
+ if (SCSI_ExecuteCommand(fd, Input, &CDB, 6, Inquiry, sizeof(Inquiry_T), RequestSense) != 0)
{
#ifdef DEBUG
fprintf(stderr, "SCSI Inquiry Command failed\n");
if (SCSI_ExecuteCommand(MediumChangerFD,Input,&CDB,6,NULL,0,&scsi_error_sense) != 0)
{
-#ifdef DEBUG
- PrintRequestSense(&scsi_error_sense);
- fprintf(stderr, "Initialize Element Status (0x07) failed\n");
-#endif
- return -1; /* could not do! */
+ /* If error is UNIT ATTENTION then retry the request */
+ if (scsi_error_sense.ErrorCode != 0x70 || scsi_error_sense.SenseKey != 6 ||
+ ClearUnitAttention(MediumChangerFD, &scsi_error_sense) != 0 ||
+ SCSI_ExecuteCommand(MediumChangerFD,Input,&CDB,6,NULL,0,&scsi_error_sense) != 0)
+ {
+ PrintRequestSense(&scsi_error_sense);
+ fprintf(stderr, "Initialize Element Status (0x07) failed\n");
+ return -1; /* could not do! */
+ }
}
return 0; /* did do! */
}
if (SCSI_ExecuteCommand(MediumChangerFD, Input, &CDB, 6,
&input_buffer, sizeof(input_buffer), &scsi_error_sense) != 0)
{
- PrintRequestSense(&scsi_error_sense);
- fprintf(stderr,"Mode sense (0x1A) for Page 0x1D failed\n");
- fflush(stderr);
- return NULL; /* sorry, couldn't do it. */
+ /* If error is UNIT ATTENTION then retry the request */
+ if (scsi_error_sense.ErrorCode != 0x70 || scsi_error_sense.SenseKey != 6 ||
+ ClearUnitAttention(MediumChangerFD, &scsi_error_sense) != 0 ||
+ SCSI_ExecuteCommand(MediumChangerFD, Input, &CDB, 6,
+ &input_buffer, sizeof(input_buffer), &scsi_error_sense) != 0)
+ {
+ PrintRequestSense(&scsi_error_sense);
+ fprintf(stderr,"Mode sense (0x1A) for Page 0x1D failed\n");
+ fflush(stderr);
+ return NULL; /* sorry, couldn't do it. */
+ }
}
/* Could do it, now build return value: */
CDB[1] = 0; /* Short! */
CDB[2] = CDB[3] = CDB[4] = CDB[5] = 0;
- if (SCSI_ExecuteCommand(MediumChangerFD, Output, &CDB, 6,
- NULL, 0, RequestSense) != 0)
+ if (SCSI_ExecuteCommand(MediumChangerFD, Output, &CDB, 6, NULL, 0, RequestSense) != 0)
{
+ /* If error is UNIT ATTENTION then retry the request */
+ if (RequestSense->ErrorCode != 0x70 || RequestSense->SenseKey != 6 ||
+ ClearUnitAttention(MediumChangerFD, RequestSense) != 0 ||
+ SCSI_ExecuteCommand(MediumChangerFD, Output, &CDB, 6, NULL, 0, RequestSense) != 0)
+ {
#ifdef DEBUG
- fprintf(stderr, "Erase (0x19) failed\n");
+ fprintf(stderr, "Erase (0x19) failed\n");
#endif
- return RequestSense;
+ return RequestSense;
+ }
}
free(RequestSense);
if (SCSI_ExecuteCommand(fd, Input, &CDB, 6, NULL, 0, &scsi_error_sense) != 0)
{
-#ifdef DEBUG_MODE_SENSE
- PrintRequestSense(&scsi_error_sense);
- fprintf(stderr, "Eject (0x1B) failed\n");
-#endif
- return -1; /* could not do! */
+ /* If error is UNIT ATTENTION then retry the request */
+ if (scsi_error_sense.ErrorCode != 0x70 || scsi_error_sense.SenseKey != 6 ||
+ ClearUnitAttention(fd, &scsi_error_sense) != 0 ||
+ SCSI_ExecuteCommand(fd, Input, &CDB, 6, NULL, 0, &scsi_error_sense) != 0)
+ {
+ PrintRequestSense(&scsi_error_sense);
+ fprintf(stderr, "Eject (0x1B) failed\n");
+ return -1; /* could not do! */
+ }
}
return 0; /* did do! */
}
if (SCSI_ExecuteCommand(fd, Input, &CDB, 6,NULL, 0, &scsi_error_sense) != 0)
{
-#ifdef DEBUG_MODE_SENSE
PrintRequestSense(&scsi_error_sense);
fprintf(stderr, "Eject (0x1B) failed\n");
-#endif
return -1; /* could not do! */
}
return 0; /* did do! */
if (SCSI_ExecuteCommand(fd, Input, &CDB, 6, NULL, 0, &scsi_error_sense) != 0)
{
-#ifdef DEBUG_MODE_SENSE
PrintRequestSense(&scsi_error_sense);
- fprintf(stderr, "Eject (0x1B) failed\n");
-#endif
+ fprintf(stderr, "Lock/Unlock (0x1E) failed\n");
return -1; /* could not do! */
}
return 0; /* did do! */
}
+int ClearUnitAttention(DEVICE_TYPE fd, RequestSense_T *RequestSense)
+{
+ CDB_T CDB;
+ int RetryCount = 10; /* Unit Attentions may be stacked */
+ RequestSense_T unit_attention_sense;
+
+ CDB[0] = 0x03; /* Request Sense */
+ CDB[4] = (char)sizeof(*RequestSense);
+ CDB[1] = CDB[2] = CDB[3] = CDB[5] = 0;
+
+ while (RetryCount-- > 0)
+ {
+ if (SCSI_ExecuteCommand(fd, Input, &CDB, 6,
+ &unit_attention_sense, sizeof(unit_attention_sense),
+ RequestSense) != 0)
+ {
+ fprintf(stderr, "RequestSense (0x03) failed\n");
+ return -1; /* could not do! */
+ }
+
+ if (unit_attention_sense.SenseKey == 0)
+ {
+ /* If SenseKey is NO SENSE then we are done. */
+ return 0;
+ }
+ }
+ return -1; /* did do! */
+
+}
+
static char Spaces[] = " ";
void PrintHex(int Indent, unsigned char *Buffer, int Length)