Scsi Erase Failing - Error Code : 1117

I am working with tape drives. I am facing a problem with Scsi Erase for the tape devices. Its giving an Error Code as 1117 representing “The request could not be performed because of an I/O device error”. But i am able to execute the SCSI commands like read, write, rewind and so on. Have anyone faced the problem if so Please let me know the solution for the same. The Code is as follows:

int GetScsiErase_SPTD(HANDLE hTapehandle, BYTE bEraseType)
{
printf(" ***** ERASE - SCSI_PASS_THROUGH_DIRECT *****\n");
ZeroMemory(&sptdwb,sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
ZeroMemory(&bCDB,sizeof(bCDB));
bCDB[0] = SCSIOP_ERASE; // Erase command 19h
bCDB[1] = bEraseType;
sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
sptdwb.sptd.CdbLength = CDB6GENERIC_LENGTH;
sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
sptdwb.sptd.SenseInfoLength = sizeof(sptdwb.ucSenseBuf);
sptdwb.sptd.DataTransferLength = 0;
sptdwb.sptd.TimeOutValue = 5;
sptdwb.sptd.DataBuffer = NULL;
sptdwb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
memcpy(sptdwb.sptd.Cdb, bCDB, CDB6GENERIC_LENGTH);
status = DeviceIoControl(hTapehandle,
IOCTL_SCSI_PASS_THROUGH_DIRECT,
&sptdwb,
sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
&sptdwb,
sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
&returned,
FALSE);
if (!status)
{
printf( “Error Erase information; error was %d\n”,
errorCode = GetLastError());
return 0;
}
if ((sptdwb.sptd.ScsiStatus == 0) && (status != 0))
printf(“\n Space Success\n”);
else
printf( “Scsi Status : %d\n\n”,sptdwb.sptd.ScsiStatus);
return 1;
}

I am opening the device handle with

hTapehandle = CreateFile( TEXT(“\\.\Tape0”), // tape dev to open
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,// read/write access
NULL,
OPEN_EXISTING, // req for tape devs
0,
NULL
);

Can anyone help me out?

Can’t you check the sense info?

wrote in message news:xxxxx@ntdev…
>I am working with tape drives. I am facing a problem with Scsi Erase for
>the tape devices. Its giving an Error Code as 1117 representing “The
>request could not be performed because of an I/O device error”. But i am
>able to execute the SCSI commands like read, write, rewind and so on. Have
>anyone faced the problem if so Please let me know the solution for the
>same. The Code is as follows:
>
> int GetScsiErase_SPTD(HANDLE hTapehandle, BYTE bEraseType)
> {
> printf(" ERASE - SCSI_PASS_THROUGH_DIRECT \n");
> ZeroMemory(&sptdwb,sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
> ZeroMemory(&bCDB,sizeof(bCDB));
> bCDB[0] = SCSIOP_ERASE; // Erase command 19h
> bCDB[1] = bEraseType;
> sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
> sptdwb.sptd.CdbLength = CDB6GENERIC_LENGTH;
> sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
> sptdwb.sptd.SenseInfoLength = sizeof(sptdwb.ucSenseBuf);
> sptdwb.sptd.DataTransferLength = 0;
> sptdwb.sptd.TimeOutValue = 5;
> sptdwb.sptd.DataBuffer = NULL;
> sptdwb.sptd.SenseInfoOffset =
> offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
> memcpy(sptdwb.sptd.Cdb, bCDB, CDB6GENERIC_LENGTH);
> status = DeviceIoControl(hTapehandle,
> IOCTL_SCSI_PASS_THROUGH_DIRECT,
> &sptdwb,
> sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
> &sptdwb,
> sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
> &returned,
> FALSE);
> if (!status)
> {
> printf( “Error Erase information; error was %d\n”,
> errorCode = GetLastError());
> return 0;
> }
> if ((sptdwb.sptd.ScsiStatus == 0) && (status != 0))
> printf(“\n Space Success\n”);
> else
> printf( “Scsi Status : %d\n\n”,sptdwb.sptd.ScsiStatus);
> return 1;
> }
>
> I am opening the device handle with
>
> hTapehandle = CreateFile( TEXT(“\\.\Tape0”), // tape dev to open
> GENERIC_READ|GENERIC_WRITE,
> FILE_SHARE_READ|FILE_SHARE_WRITE,// read/write access
> NULL,
> OPEN_EXISTING, // req for tape devs
> 0,
> NULL
> );
>
> Can anyone help me out?
>

It would be zeros. Sense info is filled only when IOCTL call retuned with
success.

On the OP place I’d experiment with the data direction flags and also would
try to use DIRECT (w/o BUFFER) call.

Also timeout value is TOO small for such a long operation (erase can take
hours).

Regards,
Anton A. Kolomyeytsev

CEO, Rocket Division Software

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of cristalink
Sent: Wednesday, May 09, 2007 11:49 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Scsi Erase Failing - Error Code : 1117

Can’t you check the sense info?

wrote in message news:xxxxx@ntdev…
>I am working with tape drives. I am facing a problem with Scsi Erase for
>the tape devices. Its giving an Error Code as 1117 representing “The
>request could not be performed because of an I/O device error”. But i am
>able to execute the SCSI commands like read, write, rewind and so on. Have
>anyone faced the problem if so Please let me know the solution for the
>same. The Code is as follows:
>
> int GetScsiErase_SPTD(HANDLE hTapehandle, BYTE bEraseType)
> {
> printf(" ERASE - SCSI_PASS_THROUGH_DIRECT \n");
> ZeroMemory(&sptdwb,sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
> ZeroMemory(&bCDB,sizeof(bCDB));
> bCDB[0] = SCSIOP_ERASE; // Erase command 19h
> bCDB[1] = bEraseType;
> sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
> sptdwb.sptd.CdbLength = CDB6GENERIC_LENGTH;
> sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
> sptdwb.sptd.SenseInfoLength = sizeof(sptdwb.ucSenseBuf);
> sptdwb.sptd.DataTransferLength = 0;
> sptdwb.sptd.TimeOutValue = 5;
> sptdwb.sptd.DataBuffer = NULL;
> sptdwb.sptd.SenseInfoOffset =
> offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
> memcpy(sptdwb.sptd.Cdb, bCDB, CDB6GENERIC_LENGTH);
> status = DeviceIoControl(hTapehandle,
> IOCTL_SCSI_PASS_THROUGH_DIRECT,
> &sptdwb,
> sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
> &sptdwb,
> sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
> &returned,
> FALSE);
> if (!status)
> {
> printf( “Error Erase information; error was %d\n”,
> errorCode = GetLastError());
> return 0;
> }
> if ((sptdwb.sptd.ScsiStatus == 0) && (status != 0))
> printf(“\n Space Success\n”);
> else
> printf( “Scsi Status : %d\n\n”,sptdwb.sptd.ScsiStatus);
> return 1;
> }
>
> I am opening the device handle with
>
> hTapehandle = CreateFile( TEXT(“\\.\Tape0”), // tape dev to open
> GENERIC_READ|GENERIC_WRITE,
> FILE_SHARE_READ|FILE_SHARE_WRITE,// read/write access
> NULL,
> OPEN_EXISTING, // req for tape devs
> 0,
> NULL
> );
>
> Can anyone help me out?
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

I found the solution for the same. I just changed the structure to SCSI_PASS_THROUGH instead of SCSI_PASS_THROUGH_DIRECT.

I even changed the data direction flags to SCSI_IOCTL_DATA_IN and timeout value to 10.

It executed Successfully. Thanks for the help.

The code is here as follows:

int GetScsiErase_SPT(HANDLE hTapehandle, BYTE bEraseType)
{
printf(" ***** ERASE - SCSI_PASS_THROUGH *****\n");

ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
ZeroMemory(&bCDB,sizeof(bCDB));

bCDB[0] = SCSIOP_ERASE; // Erase command 11h
bCDB[1] = bEraseType; // Erase Type Short(0) or Long(1)

sptwb.spt.Length = sizeof(sptwb.spt);
sptwb.spt.CdbLength = CDB6GENERIC_LENGTH;
sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN;
sptwb.spt.SenseInfoLength = sizeof(sptwb.ucSenseBuf);
sptwb.spt.DataTransferLength = 0;
sptwb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf);
sptwb.spt.DataBufferOffset = 0;
sptwb.spt.TimeOutValue = 10;
memcpy(sptwb.spt.Cdb, bCDB, CDB6GENERIC_LENGTH);

status = DeviceIoControl(hTapehandle,
IOCTL_SCSI_PASS_THROUGH,
&sptwb,
sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS),
&sptwb,
sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS),
&returned,
FALSE);

if (!status)
{
printf( “Error Erase information; error was %d\n”,
errorCode = GetLastError());
PrintError(errorCode);
printf(“Scsi Status = %d”,sptwb.spt.ScsiStatus);
return 0;
}

if ((sptwb.spt.ScsiStatus == 0) && (status != 0))
PrintDataBuffer((char *)sptwb.ucDataBuf,sptwb.spt.DataTransferLength);
else
PrintDataBuffer((char *)sptwb.ucSenseBuf,sptwb.spt.SenseInfoLength);

printf( “Scsi Status : %d\n\n”,sptwb.spt.ScsiStatus);

return 1;
}

But i am not understanding what could be the reason for failing when SCSI_PASS_THROUGH_DIRECT structure is used.

Can anyone specify the technical reason for the same.

Well… Tuning device with more then one handle at the same time is always considered to be an
extremely bad engineering practice. In your case you’ve applied all three recommendations so now
we don’t know which one exactly worked :slight_smile:

Regards,
Anton A. Kolomyeytsev

CEO, Rocket Division Software

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Friday, May 11, 2007 8:49 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Scsi Erase Failing - Error Code : 1117

I found the solution for the same. I just changed the structure to SCSI_PASS_THROUGH instead of SCSI_PASS_THROUGH_DIRECT.

I even changed the data direction flags to SCSI_IOCTL_DATA_IN and timeout value to 10.

It executed Successfully. Thanks for the help.

The code is here as follows:

int GetScsiErase_SPT(HANDLE hTapehandle, BYTE bEraseType)
{
printf(" ***** ERASE - SCSI_PASS_THROUGH *****\n");

ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
ZeroMemory(&bCDB,sizeof(bCDB));

bCDB[0] = SCSIOP_ERASE; // Erase command 11h
bCDB[1] = bEraseType; // Erase Type Short(0) or Long(1)

sptwb.spt.Length = sizeof(sptwb.spt);
sptwb.spt.CdbLength = CDB6GENERIC_LENGTH;
sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN;
sptwb.spt.SenseInfoLength = sizeof(sptwb.ucSenseBuf);
sptwb.spt.DataTransferLength = 0;
sptwb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf);
sptwb.spt.DataBufferOffset = 0;
sptwb.spt.TimeOutValue = 10;
memcpy(sptwb.spt.Cdb, bCDB, CDB6GENERIC_LENGTH);

status = DeviceIoControl(hTapehandle,
IOCTL_SCSI_PASS_THROUGH,
&sptwb,
sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS),
&sptwb,
sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS),
&returned,
FALSE);

if (!status)
{
printf( “Error Erase information; error was %d\n”,
errorCode = GetLastError());
PrintError(errorCode);
printf(“Scsi Status = %d”,sptwb.spt.ScsiStatus);
return 0;
}

if ((sptwb.spt.ScsiStatus == 0) && (status != 0))
PrintDataBuffer((char *)sptwb.ucDataBuf,sptwb.spt.DataTransferLength);
else
PrintDataBuffer((char *)sptwb.ucSenseBuf,sptwb.spt.SenseInfoLength);

printf( “Scsi Status : %d\n\n”,sptwb.spt.ScsiStatus);

return 1;
}

But i am not understanding what could be the reason for failing when SCSI_PASS_THROUGH_DIRECT structure is used.

Can anyone specify the technical reason for the same.


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

My bet is data direction flags.

Failure of these IOCTLs usually means that the CDB was not even delivered
to the LUN, so, something was mis-filled a lot.

Such a failure can also occur on some LUNs on some commands where the LUN
expects (violating the spec a bit) at least 16 bytes, or at least 32 bytes of
data transfer space.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

“Anton A. Kolomyeytsev” wrote in message
news:xxxxx@ntdev…
Well… Tuning device with more then one handle at the same time is always
considered to be an
extremely bad engineering practice. In your case you’ve applied all three
recommendations so now
we don’t know which one exactly worked :slight_smile:

Regards,
Anton A. Kolomyeytsev

CEO, Rocket Division Software

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Friday, May 11, 2007 8:49 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Scsi Erase Failing - Error Code : 1117

I found the solution for the same. I just changed the structure to
SCSI_PASS_THROUGH instead of SCSI_PASS_THROUGH_DIRECT.

I even changed the data direction flags to SCSI_IOCTL_DATA_IN and timeout value
to 10.

It executed Successfully. Thanks for the help.

The code is here as follows:

int GetScsiErase_SPT(HANDLE hTapehandle, BYTE bEraseType)
{
printf(" ERASE - SCSI_PASS_THROUGH \n");

ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
ZeroMemory(&bCDB,sizeof(bCDB));

bCDB[0] = SCSIOP_ERASE; // Erase command 11h
bCDB[1] = bEraseType; // Erase Type Short(0) or Long(1)

sptwb.spt.Length = sizeof(sptwb.spt);
sptwb.spt.CdbLength = CDB6GENERIC_LENGTH;
sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN;
sptwb.spt.SenseInfoLength = sizeof(sptwb.ucSenseBuf);
sptwb.spt.DataTransferLength = 0;
sptwb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,
ucSenseBuf);
sptwb.spt.DataBufferOffset = 0;
sptwb.spt.TimeOutValue = 10;
memcpy(sptwb.spt.Cdb, bCDB, CDB6GENERIC_LENGTH);

status = DeviceIoControl(hTapehandle,
IOCTL_SCSI_PASS_THROUGH,
&sptwb,
sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS),
&sptwb,
sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS),
&returned,
FALSE);

if (!status)
{
printf( “Error Erase information; error was %d\n”,
errorCode = GetLastError());
PrintError(errorCode);
printf(“Scsi Status = %d”,sptwb.spt.ScsiStatus);
return 0;
}

if ((sptwb.spt.ScsiStatus == 0) && (status != 0))
PrintDataBuffer((char *)sptwb.ucDataBuf,sptwb.spt.DataTransferLength);
else
PrintDataBuffer((char *)sptwb.ucSenseBuf,sptwb.spt.SenseInfoLength);

printf( “Scsi Status : %d\n\n”,sptwb.spt.ScsiStatus);

return 1;
}

But i am not understanding what could be the reason for failing when
SCSI_PASS_THROUGH_DIRECT structure is used.

Can anyone specify the technical reason for the same.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Definitely! I’ve checked my code: I use OUT for all virtual write (data moved TO target)
operations and IN for everything else (including BLANK, RESERVE TRACK and other “no data”
commands).

Regards,
Anton A. Kolomyeytsev

CEO, Rocket Division Software

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Maxim S. Shatskih
Sent: Saturday, May 12, 2007 12:59 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Scsi Erase Failing - Error Code : 1117

My bet is data direction flags.

Failure of these IOCTLs usually means that the CDB was not even delivered
to the LUN, so, something was mis-filled a lot.

Such a failure can also occur on some LUNs on some commands where the LUN
expects (violating the spec a bit) at least 16 bytes, or at least 32 bytes of
data transfer space.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

“Anton A. Kolomyeytsev” wrote in message
news:xxxxx@ntdev…
Well… Tuning device with more then one handle at the same time is always
considered to be an
extremely bad engineering practice. In your case you’ve applied all three
recommendations so now
we don’t know which one exactly worked :slight_smile:

Regards,
Anton A. Kolomyeytsev

CEO, Rocket Division Software

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Friday, May 11, 2007 8:49 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Scsi Erase Failing - Error Code : 1117

I found the solution for the same. I just changed the structure to
SCSI_PASS_THROUGH instead of SCSI_PASS_THROUGH_DIRECT.

I even changed the data direction flags to SCSI_IOCTL_DATA_IN and timeout value
to 10.

It executed Successfully. Thanks for the help.

The code is here as follows:

int GetScsiErase_SPT(HANDLE hTapehandle, BYTE bEraseType)
{
printf(" ERASE - SCSI_PASS_THROUGH \n");

ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
ZeroMemory(&bCDB,sizeof(bCDB));

bCDB[0] = SCSIOP_ERASE; // Erase command 11h
bCDB[1] = bEraseType; // Erase Type Short(0) or Long(1)

sptwb.spt.Length = sizeof(sptwb.spt);
sptwb.spt.CdbLength = CDB6GENERIC_LENGTH;
sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN;
sptwb.spt.SenseInfoLength = sizeof(sptwb.ucSenseBuf);
sptwb.spt.DataTransferLength = 0;
sptwb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,
ucSenseBuf);
sptwb.spt.DataBufferOffset = 0;
sptwb.spt.TimeOutValue = 10;
memcpy(sptwb.spt.Cdb, bCDB, CDB6GENERIC_LENGTH);

status = DeviceIoControl(hTapehandle,
IOCTL_SCSI_PASS_THROUGH,
&sptwb,
sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS),
&sptwb,
sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS),
&returned,
FALSE);

if (!status)
{
printf( “Error Erase information; error was %d\n”,
errorCode = GetLastError());
PrintError(errorCode);
printf(“Scsi Status = %d”,sptwb.spt.ScsiStatus);
return 0;
}

if ((sptwb.spt.ScsiStatus == 0) && (status != 0))
PrintDataBuffer((char *)sptwb.ucDataBuf,sptwb.spt.DataTransferLength);
else
PrintDataBuffer((char *)sptwb.ucSenseBuf,sptwb.spt.SenseInfoLength);

printf( “Scsi Status : %d\n\n”,sptwb.spt.ScsiStatus);

return 1;
}

But i am not understanding what could be the reason for failing when
SCSI_PASS_THROUGH_DIRECT structure is used.

Can anyone specify the technical reason for the same.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer