<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-reply;
font-family:"Calibri","sans-serif";
color:#1F497D;}
.MsoChpDefault
{mso-style-type:export-only;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Hi Sean,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">You’re send Get Features Command for Arbitration, which doesn’t involve data transfer via separate buffer and ByteSizeTx should be zero. In other words, the
sizes of input and output buffer should be the same as size of NVME_PASS_THROUGH_IOCTL.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Thanks,<br>
Alex<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> nvmewin-bounces@lists.openfabrics.org [mailto:nvmewin-bounces@lists.openfabrics.org]
<b>On Behalf Of </b>Sean Chen<br>
<b>Sent:</b> Monday, June 09, 2014 5:57 AM<br>
<b>To:</b> nvmewin@lists.openfabrics.org<br>
<b>Subject:</b> [nvmewin] DeviceIOControl Error<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">Hi All<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I study PT_IOCTL.doc to implement NVMe command for windows. But DeviceIControl return "The request could not be performed because of an I/O device error." The following is my code:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">// ================ Get Device ================<br>
char driveName[256];<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Select_choice = ComboBox->GetCurSel();<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">sprintf(driveName, "<a href="file:///\\\scsi%25d:">\\\\.\\scsi%d:</a>", Select_choice);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><br>
DeviceHandle = CreateFile(driveName,<br>
GENERIC_READ | GENERIC_WRITE,<br>
FILE_SHARE_READ | FILE_SHARE_WRITE,<br>
NULL,<br>
OPEN_EXISTING,<br>
FILE_ATTRIBUTE_NORMAL,<br>
NULL);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">if (DeviceHandle == INVALID_HANDLE_VALUE) {<br>
MessageBox("Cannot open device.", "Device Error", MB_OK|MB_ICONERROR);<br>
return FALSE;<br>
}<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><br>
// ================ NVME Test ================<br>
int ByteSizeTX = 256;<br>
BOOL status = 0;<br>
DWORD count = 0;<br>
DWORD InputBufLen = 0;<br>
DWORD OutputBufLen = 0;<br>
PNVME_PASS_THROUGH_IOCTL pInBuffer = NULL;<br>
PNVME_PASS_THROUGH_IOCTL pOutBuffer = NULL;<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">// From Device to Host<br>
// Allocate input buffer to accommodate size of NVME_PASS_THRUGH_IOCTL only<br>
InputBufLen = sizeof(NVME_PASS_THROUGH_IOCTL);<br>
pInBuffer = (PNVME_PASS_THROUGH_IOCTL) malloc(InputBufLen);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">// Allocate output buffer to accommodate size of NVME_PASS_THRUGH_IOCTL and data<br>
OutputBufLen = sizeof(NVME_PASS_THROUGH_IOCTL) + ByteSizeTX;<br>
pOutBuffer = (PNVME_PASS_THROUGH_IOCTL) malloc(OutputBufLen);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">// Confirm we have buffers allocated successfully<br>
if (pInBuffer == NULL || pOutBuffer == NULL)<br>
return;<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">// Zero out the buffers <br>
memset(pInBuffer, 0, InputBufLen);<br>
memset(pOutBuffer, 0, OutputBufLen);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">// Populate SRB_IO_CONTROL fields in input buffer <br>
pInBuffer->SrbIoCtrl.ControlCode = NVME_PASS_THROUGH_SRB_IO_CODE;<br>
pInBuffer->SrbIoCtrl.HeaderLength = sizeof(SRB_IO_CONTROL);<br>
memcpy((UCHAR*)(&pInBuffer->SrbIoCtrl.Signature[0]), NVME_SIG_STR, NVME_SIG_STR_LEN);<br>
pInBuffer->SrbIoCtrl.Timeout = 40;<br>
pInBuffer->SrbIoCtrl.Length = InputBufLen - sizeof(SRB_IO_CONTROL);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">pInBuffer->DataBufferLen = ByteSizeTX;<br>
pInBuffer->ReturnBufferLen = OutputBufLen;<br>
//pInBuffer->Direction = NVME_FROM_DEV_TO_HOST;<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">// Fill in pInBuffer->NVMeCmd here <br>
pInBuffer->NVMeCmd[0] = 0x0A; // OpCode<br>
pInBuffer->NVMeCmd[1] = 0x01; // Namespace ID<br>
pInBuffer->NVMeCmd[10] = 0x01;<br>
// Fill pInBuffer->DataBuffer here when transferring data to device <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">status = DeviceIoControl(<br>
DeviceHandle, // Handle to <a href="file:///\\.\scsi">
\\.\scsi</a> device via CreateFile <br>
IOCTL_SCSI_MINIPORT, // IO control function to a miniport driver
<br>
pInBuffer, // Input buffer with data sent to driver
<br>
InputBufLen, // Length of data sent to driver (in bytes)
<br>
pOutBuffer, // Output buffer with data received from driver
<br>
OutputBufLen, // Length of data received from driver <br>
&count, // Bytes placed in DataBuffer <br>
NULL); // NULL = no overlap <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">free(pInBuffer);<br>
free(pOutBuffer);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">// ====================================================<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">May I have anything wrong?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Thanks for your help.<o:p></o:p></p>
</div>
</div>
</div>
</body>
</html>