[if gte mso 9]>

Re: [edk2] Protocol Questions

Subject: Re: [edk2] Protocol Questions

From: "Michael Lorer" <michael.lorer@opus.de>

To: <edk2-devel@lists.sourceforge.net>

Date: 2012-10-11 16:51:40



the BlockIO-Pointer in your example isn’t mapped one-to-many.

Instead it gets overwritten for each loop in the for-loop.


You don’t have to open all handle instances if you want to use a protocol.

If you’ve got a valid device-pointer you can open just the single protocol instance for that device.





Von: duck wilson [mailto:duck.54321@gmail.com]
Gesendet: Donnerstag, 11. Oktober 2012 07:26
An: edk2-devel@lists.sourceforge.net
Betreff: [edk2] Protocol Questions



I have managed to get wrapped around my axle in understanding the implementation
and use of protocols in UEFI. I "think" the working model I have is correct
but am not sure at this point, help would be much appreciated. To illustrate my
confusion, refer to the source code below taken from the "Driver Writer's
Guide for UEFI 2.3.1", Version 1.01, 3/08/2012, Section, Example 36
on pages 116-117. The example shows how to retrieve all Block I/O Protocols
from the handle database using LocateHandleBuffer and OpenProtocol. In the
loop where the OpenProtocol call is made, the interface pointer is written
to the same variable, BlockIo, for each handle which I am interpreting to
mean that all handles use one, and only one, instance in the system that
implements BLOCK_IO_PROTOCOL and so one interface instance, that is, there is
a one-to-many mapping. There are similar examples in the UEFI specification.
I further interpret this to mean that if I am writing a driver for a device
that needs BLOCK_IO_PROTOCOL services that I simply use the existing protocol
and do not have to write an implementation for this service. Is this correct?

Also, when using a protocol, is it necessary to open all handle instances
of a protocol when using a protocol as the examples shows in either a
driver or application? For example, if I am using a device on a device path,
which is a protocol mapped to a handle, do I also need to open all other
instances on all other handles to use the device or just open the handle

To make my confusion more concrete let's move the model outside the realm of
computers. Assume that a protocol is a dishwasher, that a handle is a restaurant,
and that hiring the dishwasher is the equivalent of opening a protocol. The
dishwasher’s name happens to be GUID. Are all restaurants required to have
dishwashers named GUID, in which case there are a lot of persons named GUID
who are dishwashers, or is there just one dishwasher named GUID who provides
dish washing services to all the restaurants? In either case, the pairing of
a restaurant with GUID is unique, however, in the former case there are many
different people with the same name doing the same work and in the later case
just on person doing all the work. So if I go into the restaurant business, do I
need to find another dishwasher named GUID or do I need to contract with the
one dishwasher named GUID? What is the correct model?


#include <Uefi.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Protocol/BlockIo.h>

EFI_STATUS            Status;
UINTN                 HandleCount;
EFI_HANDLE            *HandleBuffer;
UINTN                 Index;

// Retrieve the list of handles that support the Block I/O
// Protocol from the handle database. The number of handles
// that support the Block I/O Protocol is returned in HandleCount,
// and the array of handle values is returned in HandleBuffer
// which is allocated using AlocatePool()

Status = gBS->LocateHandleBuffer (
if (EFI_ERROR (Status)) {
  return Status;

// Loop through all the handles that support the Block I/O
// Protocol, and retrieve the Block I/O Protocol instance
// from each handle.

for (Index = 0; Index < HandleCount; Index++) {
  Status = gBS->OpenProtocol (
                   (VOID **)&BlockIo,
  if (EFI_ERROR (Status)) {
    return Status;

  // BlockIo can be used here to make Block I/O Protocol
  // service requests.

// Free the array of handles allocated by gBS->LocateHandleBuffer()
FreePool (HandleBuffer);