0 Replies Latest reply: Jun 15, 2012 11:06 PM by Pradeep Pathak RSS

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

Pradeep Pathak Community Member
Currently Being Moderated

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

More Like This

  • Retrieving data ...

Legend

  • Correct Answers - 4 points
  • Helpful Answers - 2 points