Solid State Drives
Support for Issues Related to Intel® Solid State Drives
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
4365 Discussions

Sending IDENTIFY DEVICE COMMAND - ATA PASS THROUGH on raid - SSD

idata
Community Manager
1,181 Views

Hi All, (Kindly guide me if I am at wrong place)

My aim is to detect Solid State Drives in systems with raid configuration. Using smartmontools' following command I observe bit 434 (217) shows value 1 for SSD: smartctl -i -r ataioctl,2 /dev/csmi0,0

Attempting to read the same 512 bytes of data I have attempted to send IDENTIFY DEVICE commands in following 2 ways:

Method 1 has info->IoctlHeader.ReturnCode = 3 which means CSMI_SAS_STATUS_INVALID_PARAMETER.(CSMI buffer provided is too small)

Method 2 fails with DeviceIoControl() set GetLastError() as 87 (ERROR_INVALID_PARAMETER), Can you help me in understanding what could be wrong and am I on the right track?

BYTE portNumber = 0;

_stprintf_s(DeviceName, (sizeof(char)*128),_T("\\\\.\\Scsi%u:"),portNumber);

handle = CreateFile(DeviceName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,

OPEN_EXISTING, NULL, NULL);

if (handle == INVALID_HANDLE_VALUE)

{

printf("Unable to open handle to device , Error %u\n", GetLastError());

return;

}

CSMI_SAS_STP_PASSTHRU_BUFFER* info = (CSMI_SAS_STP_PASSTHRU_BUFFER *)

calloc(1, sizeof(CSMI_SAS_STP_PASSTHRU_BUFFER));

info->IoctlHeader.HeaderLength = sizeof(IOCTL_HEADER);

info->IoctlHeader.Timeout = CSMI_SAS_TIMEOUT;

info->IoctlHeader.ControlCode = CC_CSMI_SAS_STP_PASSTHRU;

info->IoctlHeader.Length = sizeof(CSMI_SAS_STP_PASSTHRU_BUFFER) - sizeof(IOCTL_HEADER);

info->IoctlHeader.ReturnCode = 0;

memcpy(&info->IoctlHeader.Signature, CSMI_SAS_SIGNATURE, sizeof(CSMI_SAS_SIGNATURE));

bSuccess = DeviceIoControl(handle, IOCTL_SCSI_MINIPORT, info,

sizeof(CSMI_SAS_STP_PASSTHRU_BUFFER),

info, sizeof(CSMI_SAS_STP_PASSTHRU_BUFFER),

&bytesReturned, NULL);

////////////////////////////////////////////////////////

METHOD 2

/////////////////////////////////////////////////////////

handle = CreateFile(L"\\\\.\\PhysicalDrive0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,

NULL,

OPEN_EXISTING,

NULL,

NULL);

if (handle == INVALID_HANDLE_VALUE)

{

printf("Unable to open handle to device , Error %u\n", GetLastError());

return 1;

}

//Allocate memory for ATA_PASS_THROUGH_EX and clear the contents

pATAData = (PATA_PASS_THROUGH_EX) VirtualAlloc(NULL, dataSize, MEM_COMMIT, PAGE_READWRITE);

ZeroMemory(pATAData,dataSize);

//Fill in the IDENTIFY DEVICE query data

pATAData->Length = sizeof(ATA_PASS_THROUGH_EX);

pATAData->DataBufferOffset = sizeof(ATA_PASS_THROUGH_EX);

pATAData->DataTransferLength = 512;

pATAData->AtaFlags = ATA_FLAGS_DATA_IN;

pATAData->TimeOutValue = 10; //Seconds

pATAData->CurrentTaskFile[6] = 0xEC; /* send the command*/

status = DeviceIoControl( handle,

IOCTL_ATA_PASS_THROUGH,

pATAData,

dataSize, /* input buffer and size */

pATAData,

dataSize, /* output buffer and size */

&bytescopied, /* bytes copied to output buffer*/

NULL ); /* no overlapping */

Thank you,

Pradeep

0 Kudos
0 Replies
Reply