* NVMe Smart Data Buffer Size
@ 2018-03-28 13:32 Rafael Machado
2018-03-29 1:30 ` Wu, Hao A
0 siblings, 1 reply; 3+ messages in thread
From: Rafael Machado @ 2018-03-28 13:32 UTC (permalink / raw)
To: edk2-devel@lists.01.org
Hi everyone
I'am working on a development related to retrieving the SMART data
information from a NVMe device.
After some research I got to a code that works correctly, but I would like
to have a 100% understanding of why it works.
To retrieve the SMART data I send the command (EFI_NVM_EXPRESS_COMMAND) as
follows:
//************************************************************
//Fill the EFI_NVM_EXPRESS_COMMAND struct
Command->Cdw0.Opcode = NVME_ADMIN_GET_LOG_PAGE_CMD; //This is the command
0x02
Command->Nsid = NVME_ALL_VALID_NSID; //The NSID used in this case is
the 0xFFFFFFFF to retrieve the global information
Command->Cdw10 = (4096 << 16) | 2; // page 2 is the Smart/Health log page
Command->Cdw11 = 0x0;
Command->Cdw12 = 0x0;
Command->Cdw13 = 0x0;
Command->Flags = CDW10_VALID
| CDW11_VALID
| CDW12_VALID
| CDW13_VALID;
// Fill the EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET struct
This->Nsid = NVME_ALL_VALID_NSID; //This is the NSID used by
the NVME_PROTOCOL, that is also 0xFFFFFFFF
CommandPacket->NvmeCmd = Command;
CommandPacket->NvmeCompletion = Completion;
CommandPacket->TransferBuffer = (VOID*) SmartData;
CommandPacket->TransferLength = 4096;
CommandPacket->CommandTimeout = 0;
CommandPacket->QueueType = NVME_ADMIN_QUEUE;
CommandPacket->MetadataBuffer = NULL;
CommandPacket->MetadataLength = 0;
//************************************************************
The question I have, is about the size of the buffer to be used as the
transfer buffer at the EFI_NVM_EXPRESS_COMMAND and at the
EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET. At the Nvme spec we see that the
SmartData information is 512 bytes long.
So the question is.
Why, even having just 512 bytes to be retrieved by the GetLogCommand page
0x02, do I need to create a 4096 bytes buffer to retrieve the SMART data ?
Command->Cdw10 = (4096 << 16) | 2;
CommandPacket->TransferBuffer = (VOID*) SmartData; (allocated previously)
CommandPacket->TransferLength = 4096;
Just for reference. When I create a 512 bytes buffer I get a DeviceError
status after the PassThru. With the sample code below:
Command->Cdw10 = (512 << 16) | 2;
CommandPacket->TransferBuffer = (VOID*) SmartData; (allocated previously)
CommandPacket->TransferLength = 512;
Another question I have is:
We have two places that we need to set the Nsid.
EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET. Nsid
EFI_NVM_EXPRESS_COMMAND.Nsid
Since I am not a NVme expert, my question is if both represent the same
information.
Should I use 0xFFFFFFFF in both?
Thanks and Regards
Rafael R. Machado
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: NVMe Smart Data Buffer Size
2018-03-28 13:32 NVMe Smart Data Buffer Size Rafael Machado
@ 2018-03-29 1:30 ` Wu, Hao A
2018-03-29 14:13 ` Rafael Machado
0 siblings, 1 reply; 3+ messages in thread
From: Wu, Hao A @ 2018-03-29 1:30 UTC (permalink / raw)
To: Rafael Machado, edk2-devel@lists.01.org
Hi,
Some comments below:
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Rafael Machado
> Sent: Wednesday, March 28, 2018 9:32 PM
> To: edk2-devel@lists.01.org
> Subject: [edk2] NVMe Smart Data Buffer Size
>
> Hi everyone
>
> I'am working on a development related to retrieving the SMART data
> information from a NVMe device.
> After some research I got to a code that works correctly, but I would like
> to have a 100% understanding of why it works.
>
> To retrieve the SMART data I send the command
> (EFI_NVM_EXPRESS_COMMAND) as
> follows:
>
> //************************************************************
> //Fill the EFI_NVM_EXPRESS_COMMAND struct
> Command->Cdw0.Opcode = NVME_ADMIN_GET_LOG_PAGE_CMD; //This is
> the command
> 0x02
> Command->Nsid = NVME_ALL_VALID_NSID; //The NSID used in this case is
> the 0xFFFFFFFF to retrieve the global information
> Command->Cdw10 = (4096 << 16) | 2; // page 2 is the Smart/Health log page
> Command->Cdw11 = 0x0;
> Command->Cdw12 = 0x0;
> Command->Cdw13 = 0x0;
> Command->Flags = CDW10_VALID
> | CDW11_VALID
> | CDW12_VALID
> | CDW13_VALID;
>
> // Fill the EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET struct
> This->Nsid = NVME_ALL_VALID_NSID; //This is the NSID used by
> the NVME_PROTOCOL, that is also 0xFFFFFFFF
> CommandPacket->NvmeCmd = Command;
> CommandPacket->NvmeCompletion = Completion;
> CommandPacket->TransferBuffer = (VOID*) SmartData;
> CommandPacket->TransferLength = 4096;
> CommandPacket->CommandTimeout = 0;
> CommandPacket->QueueType = NVME_ADMIN_QUEUE;
> CommandPacket->MetadataBuffer = NULL;
> CommandPacket->MetadataLength = 0;
> //************************************************************
>
> The question I have, is about the size of the buffer to be used as the
> transfer buffer at the EFI_NVM_EXPRESS_COMMAND and at the
> EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET. At the Nvme spec we
> see that the
> SmartData information is 512 bytes long.
>
> So the question is.
> Why, even having just 512 bytes to be retrieved by the GetLogCommand page
> 0x02, do I need to create a 4096 bytes buffer to retrieve the SMART data ?
I have a check on the NVMe v1.1 spec for the Get Log Page command:
For Command Dword 10:
27:16 Number of Dwords (NUMD):
This field specifies the number of Dwords to return. If host software
specifies a size larger than the log page requested, the results are
undefined. This is a 0's based value.
Per my understanding, since the field requires a 0's based Dword value,
for getting the SMART / Health Information (which is 512 bytes in length),
the Cdw10 should be:
Command->Cdw10 = (127 << 16) | 2; // 128 Dword, 0's based
And for the PassThru command packet:
CommandPacket->TransferLength = 512;
Please help to verify if this works properly for you. Thanks in advance.
>
> Command->Cdw10 = (4096 << 16) | 2;
> CommandPacket->TransferBuffer = (VOID*) SmartData; (allocated previously)
> CommandPacket->TransferLength = 4096;
>
> Just for reference. When I create a 512 bytes buffer I get a DeviceError
> status after the PassThru. With the sample code below:
>
> Command->Cdw10 = (512 << 16) | 2;
> CommandPacket->TransferBuffer = (VOID*) SmartData; (allocated previously)
> CommandPacket->TransferLength = 512;
>
>
> Another question I have is:
> We have two places that we need to set the Nsid.
>
> EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET. Nsid
> EFI_NVM_EXPRESS_COMMAND.Nsid
>
> Since I am not a NVme expert, my question is if both represent the same
> information.
> Should I use 0xFFFFFFFF in both?
Yes, you are right.
These two values:
NamespaceId param for EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.PassThru() and
Nsid field of EFI_NVM_EXPRESS_COMMAND
should be set to the same value.
Best Regards,
Hao Wu
>
> Thanks and Regards
> Rafael R. Machado
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: NVMe Smart Data Buffer Size
2018-03-29 1:30 ` Wu, Hao A
@ 2018-03-29 14:13 ` Rafael Machado
0 siblings, 0 replies; 3+ messages in thread
From: Rafael Machado @ 2018-03-29 14:13 UTC (permalink / raw)
To: Wu, Hao A; +Cc: edk2-devel@lists.01.org
Hi Hao Wu
Thanks for clarifying. The problem was that my code didn't consider the
command packet CDw10 as 0's based.
Best Regards
Rafael R. Machado
Em qua, 28 de mar de 2018 às 22:30, Wu, Hao A <hao.a.wu@intel.com> escreveu:
> Hi,
>
> Some comments below:
>
> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > Rafael Machado
> > Sent: Wednesday, March 28, 2018 9:32 PM
> > To: edk2-devel@lists.01.org
> > Subject: [edk2] NVMe Smart Data Buffer Size
> >
> > Hi everyone
> >
> > I'am working on a development related to retrieving the SMART data
> > information from a NVMe device.
> > After some research I got to a code that works correctly, but I would
> like
> > to have a 100% understanding of why it works.
> >
> > To retrieve the SMART data I send the command
> > (EFI_NVM_EXPRESS_COMMAND) as
> > follows:
> >
> > //************************************************************
> > //Fill the EFI_NVM_EXPRESS_COMMAND struct
> > Command->Cdw0.Opcode = NVME_ADMIN_GET_LOG_PAGE_CMD; //This is
> > the command
> > 0x02
> > Command->Nsid = NVME_ALL_VALID_NSID; //The NSID used in this case is
> > the 0xFFFFFFFF to retrieve the global information
> > Command->Cdw10 = (4096 << 16) | 2; // page 2 is the Smart/Health log
> page
> > Command->Cdw11 = 0x0;
> > Command->Cdw12 = 0x0;
> > Command->Cdw13 = 0x0;
> > Command->Flags = CDW10_VALID
> > | CDW11_VALID
> > | CDW12_VALID
> > | CDW13_VALID;
> >
> > // Fill the EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET struct
> > This->Nsid = NVME_ALL_VALID_NSID; //This is the NSID used by
> > the NVME_PROTOCOL, that is also 0xFFFFFFFF
> > CommandPacket->NvmeCmd = Command;
> > CommandPacket->NvmeCompletion = Completion;
> > CommandPacket->TransferBuffer = (VOID*) SmartData;
> > CommandPacket->TransferLength = 4096;
> > CommandPacket->CommandTimeout = 0;
> > CommandPacket->QueueType = NVME_ADMIN_QUEUE;
> > CommandPacket->MetadataBuffer = NULL;
> > CommandPacket->MetadataLength = 0;
> > //************************************************************
> >
> > The question I have, is about the size of the buffer to be used as the
> > transfer buffer at the EFI_NVM_EXPRESS_COMMAND and at the
> > EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET. At the Nvme spec we
> > see that the
> > SmartData information is 512 bytes long.
> >
> > So the question is.
> > Why, even having just 512 bytes to be retrieved by the GetLogCommand page
> > 0x02, do I need to create a 4096 bytes buffer to retrieve the SMART data
> ?
>
> I have a check on the NVMe v1.1 spec for the Get Log Page command:
>
> For Command Dword 10:
> 27:16 Number of Dwords (NUMD):
> This field specifies the number of Dwords to return. If host software
> specifies a size larger than the log page requested, the results are
> undefined. This is a 0's based value.
>
> Per my understanding, since the field requires a 0's based Dword value,
> for getting the SMART / Health Information (which is 512 bytes in length),
> the Cdw10 should be:
> Command->Cdw10 = (127 << 16) | 2; // 128 Dword, 0's based
>
> And for the PassThru command packet:
> CommandPacket->TransferLength = 512;
>
> Please help to verify if this works properly for you. Thanks in advance.
>
> >
> > Command->Cdw10 = (4096 << 16) | 2;
> > CommandPacket->TransferBuffer = (VOID*) SmartData; (allocated previously)
> > CommandPacket->TransferLength = 4096;
> >
> > Just for reference. When I create a 512 bytes buffer I get a DeviceError
> > status after the PassThru. With the sample code below:
> >
> > Command->Cdw10 = (512 << 16) | 2;
> > CommandPacket->TransferBuffer = (VOID*) SmartData; (allocated previously)
> > CommandPacket->TransferLength = 512;
> >
> >
> > Another question I have is:
> > We have two places that we need to set the Nsid.
> >
> > EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET. Nsid
> > EFI_NVM_EXPRESS_COMMAND.Nsid
> >
> > Since I am not a NVme expert, my question is if both represent the same
> > information.
> > Should I use 0xFFFFFFFF in both?
>
> Yes, you are right.
>
> These two values:
> NamespaceId param for EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.PassThru() and
> Nsid field of EFI_NVM_EXPRESS_COMMAND
>
> should be set to the same value.
>
> Best Regards,
> Hao Wu
>
> >
> > Thanks and Regards
> > Rafael R. Machado
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-03-29 14:06 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-28 13:32 NVMe Smart Data Buffer Size Rafael Machado
2018-03-29 1:30 ` Wu, Hao A
2018-03-29 14:13 ` Rafael Machado
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox