Saturday, July 2, 2016

Finding NVMe Passthru handle - UEFI Edk2.5

One of the challenge when I started working on NVMe devices in UEFI driver was the lack of sample code which can leverage the NvmExpressDxe code in the Edk2.5 code.

At this point, let me add that there is a quite a bit of different in the NvmExpressDxe code in Edk2 and Edk2.5.

1. The major difference is the GUID itself. Then all the data structures for sending command, completion etc are different. This is an important point - If you are using the wrong GUID, you will not be able to communicate with your NVMe driver using pass thru protocol.

2. The location of the NvmExpressPassthru.h is different in Edk2.5. You can find it in Edk_2.5\MdePkg\Include\Protocol. This file was previously included in the NvmExpressDxe folder in MdeModulePkg.

So here is a bit of reference code that can be used. Refer Edk2.5 code for better clarity.

#define EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL_GUID \
  { \
    0x52c78312, 0x8edc, 0x4233, { 0x98, 0xf2, 0x1a, 0x1a, 0xa5, 0xe3, 0x88, 0xa5 } \
  }

 EFI_GUID gNvmExpressPassThruProtocolGuid = EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL_GUID;
EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *ptrNvmePassThru = NULL;
We can use the LocateHandleBuffer function to find the handles which has exposed the Nvm Pass thru protocol.

UINTN       NHandles = 0;
    EFI_HANDLE      *Handles = NULL;
        Status = gBS->LocateHandleBuffer (
                ByProtocol,
                &gNvmExpressPassThruProtocolGuid,
                NULL,
                &NHandles,
                &Handles
                );

    if (Status == EFI_NOT_FOUND || NHandles == 0) {
    //
    // If there are no Protocols handles, then return EFI_NOT_FOUND
    //
                return EFI_NOT_FOUND;
    }

    for(Index = 0; Index < NHandles; Index++) {

        Status = gBS->HandleProtocol(
                        Handles[Index],
                        &gNvmExpressPassThruProtocolGuid,
                        (VOID **) &ptrNvmePassThru                      
                        );
        if (EFI_ERROR (Status)) {              continue;
        }
//Use  ptrNvmePassThru for sending identify nvme controller to get the details of the nvme controller
}

This ptrNvmePassThru is the passthru handle required for sending any command to the NVMe device using NVMe passthru protocol.

Note: The above code is very much similar for getting handle who has exposed SATA Pass through protocol or SCSI pass through protocol.

No comments:

Post a Comment