Coverage Report

Created: 2026-03-28 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/edk2/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
Line
Count
Source
1
/** @file
2
3
  This driver produces Virtio Device Protocol instances for Virtio PCI devices.
4
5
  Copyright (C) 2012, Red Hat, Inc.
6
  Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
7
  Copyright (C) 2013, ARM Ltd.
8
  Copyright (C) 2017, AMD Inc, All rights reserved.<BR>
9
10
  SPDX-License-Identifier: BSD-2-Clause-Patent
11
12
**/
13
14
#include <IndustryStandard/Pci.h>
15
#include <Library/BaseMemoryLib.h>
16
#include <Library/DebugLib.h>
17
#include <Library/MemoryAllocationLib.h>
18
#include <Library/UefiBootServicesTableLib.h>
19
#include <Library/UefiLib.h>
20
21
#include "VirtioPciDevice.h"
22
23
STATIC VIRTIO_DEVICE_PROTOCOL  mDeviceProtocolTemplate = {
24
  0,                                    // Revision
25
  0,                                    // SubSystemDeviceId
26
  VirtioPciGetDeviceFeatures,           // GetDeviceFeatures
27
  VirtioPciSetGuestFeatures,            // SetGuestFeatures
28
  VirtioPciSetQueueAddress,             // SetQueueAddress
29
  VirtioPciSetQueueSel,                 // SetQueueSel
30
  VirtioPciSetQueueNotify,              // SetQueueNotify
31
  VirtioPciSetQueueAlignment,           // SetQueueAlignment
32
  VirtioPciSetPageSize,                 // SetPageSize
33
  VirtioPciGetQueueSize,                // GetQueueNumMax
34
  VirtioPciSetQueueSize,                // SetQueueNum
35
  VirtioPciGetDeviceStatus,             // GetDeviceStatus
36
  VirtioPciSetDeviceStatus,             // SetDeviceStatus
37
  VirtioPciDeviceWrite,                 // WriteDevice
38
  VirtioPciDeviceRead,                  // ReadDevice
39
  VirtioPciAllocateSharedPages,         // AllocateSharedPages
40
  VirtioPciFreeSharedPages,             // FreeSharedPages
41
  VirtioPciMapSharedBuffer,             // MapSharedBuffer
42
  VirtioPciUnmapSharedBuffer,           // UnmapSharedBuffer
43
};
44
45
/**
46
47
  Read a word from Region 0 of the device specified by PciIo.
48
49
  Region 0 must be an iomem region. This is an internal function for the PCI
50
  implementation of the protocol.
51
52
  @param[in] Dev          Virtio PCI device.
53
54
  @param[in] FieldOffset  Source offset.
55
56
  @param[in] FieldSize    Source field size, must be in { 1, 2, 4, 8 }.
57
58
  @param[in] BufferSize   Number of bytes available in the target buffer. Must
59
                          equal FieldSize.
60
61
  @param[out] Buffer      Target buffer.
62
63
64
  @return  Status code returned by PciIo->Io.Read().
65
66
**/
67
EFI_STATUS
68
EFIAPI
69
VirtioPciIoRead (
70
  IN  VIRTIO_PCI_DEVICE  *Dev,
71
  IN  UINTN              FieldOffset,
72
  IN  UINTN              FieldSize,
73
  IN  UINTN              BufferSize,
74
  OUT VOID               *Buffer
75
  )
76
563
{
77
563
  UINTN                      Count;
78
563
  EFI_PCI_IO_PROTOCOL_WIDTH  Width;
79
563
  EFI_PCI_IO_PROTOCOL        *PciIo;
80
81
563
  ASSERT (FieldSize == BufferSize);
82
83
563
  PciIo = Dev->PciIo;
84
563
  Count = 1;
85
86
563
  switch (FieldSize) {
87
54
    case 1:
88
54
      Width = EfiPciIoWidthUint8;
89
54
      break;
90
91
69
    case 2:
92
69
      Width = EfiPciIoWidthUint16;
93
69
      break;
94
95
158
    case 8:
96
      //
97
      // The 64bit PCI I/O is broken down into two 32bit reads to prevent
98
      // any alignment or width issues.
99
      // The UEFI spec says under EFI_PCI_IO_PROTOCOL.Io.Write():
100
      //
101
      // The I/O operations are carried out exactly as requested. The caller
102
      // is responsible for any alignment and I/O width issues which the
103
      // bus, device, platform, or type of I/O might require. For example on
104
      // some platforms, width requests of EfiPciIoWidthUint64 do not work.
105
      //
106
158
      Count = 2;
107
108
    //
109
    // fall through
110
    //
111
440
    case 4:
112
440
      Width = EfiPciIoWidthUint32;
113
440
      break;
114
115
0
    default:
116
0
      ASSERT (FALSE);
117
0
      return EFI_INVALID_PARAMETER;
118
563
  }
119
120
563
  return PciIo->Io.Read (
121
563
                     PciIo,
122
563
                     Width,
123
563
                     PCI_BAR_IDX0,
124
563
                     FieldOffset,
125
563
                     Count,
126
563
                     Buffer
127
563
                     );
128
563
}
129
130
/**
131
132
  Write a word into Region 0 of the device specified by PciIo.
133
134
  Region 0 must be an iomem region. This is an internal function for the PCI
135
  implementation of the protocol.
136
137
  @param[in] Dev          Virtio PCI device.
138
139
  @param[in] FieldOffset  Destination offset.
140
141
  @param[in] FieldSize    Destination field size, must be in { 1, 2, 4, 8 }.
142
143
  @param[in] Value        Little endian value to write, converted to UINT64.
144
                          The least significant FieldSize bytes will be used.
145
146
147
  @return  Status code returned by PciIo->Io.Write().
148
149
**/
150
EFI_STATUS
151
EFIAPI
152
VirtioPciIoWrite (
153
  IN  VIRTIO_PCI_DEVICE  *Dev,
154
  IN UINTN               FieldOffset,
155
  IN UINTN               FieldSize,
156
  IN UINT64              Value
157
  )
158
831
{
159
831
  UINTN                      Count;
160
831
  EFI_PCI_IO_PROTOCOL_WIDTH  Width;
161
831
  EFI_PCI_IO_PROTOCOL        *PciIo;
162
163
831
  PciIo = Dev->PciIo;
164
831
  Count = 1;
165
166
831
  switch (FieldSize) {
167
632
    case 1:
168
632
      Width = EfiPciIoWidthUint8;
169
632
      break;
170
171
69
    case 2:
172
69
      Width = EfiPciIoWidthUint16;
173
69
      break;
174
175
0
    case 8:
176
      //
177
      // The 64bit PCI I/O is broken down into two 32bit writes to prevent
178
      // any alignment or width issues.
179
      // The UEFI spec says under EFI_PCI_IO_PROTOCOL.Io.Write():
180
      //
181
      // The I/O operations are carried out exactly as requested. The caller
182
      // is responsible for any alignment and I/O width issues which the
183
      // bus, device, platform, or type of I/O might require. For example on
184
      // some platforms, width requests of EfiPciIoWidthUint64 do not work
185
      //
186
0
      Count = Count * 2;
187
188
    //
189
    // fall through
190
    //
191
130
    case 4:
192
130
      Width = EfiPciIoWidthUint32;
193
130
      break;
194
195
0
    default:
196
0
      ASSERT (FALSE);
197
0
      return EFI_INVALID_PARAMETER;
198
831
  }
199
200
831
  return PciIo->Io.Write (
201
831
                     PciIo,
202
831
                     Width,
203
831
                     PCI_BAR_IDX0,
204
831
                     FieldOffset,
205
831
                     Count,
206
831
                     &Value
207
831
                     );
208
831
}
209
210
/**
211
212
  Device probe function for this driver.
213
214
  The DXE core calls this function for any given device in order to see if the
215
  driver can drive the device.
216
217
  @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
218
                                  incorporating this driver (independently of
219
                                  any device).
220
221
  @param[in] DeviceHandle         The device to probe.
222
223
  @param[in] RemainingDevicePath  Relevant only for bus drivers, ignored.
224
225
226
  @retval EFI_SUCCESS      The driver supports the device being probed.
227
228
  @retval EFI_UNSUPPORTED  Based on virtio-pci discovery, we do not support
229
                           the device.
230
231
  @return                  Error codes from the OpenProtocol() boot service or
232
                           the PciIo protocol.
233
234
**/
235
STATIC
236
EFI_STATUS
237
EFIAPI
238
VirtioPciDeviceBindingSupported (
239
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
240
  IN EFI_HANDLE                   DeviceHandle,
241
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
242
  )
243
0
{
244
0
  EFI_STATUS           Status;
245
0
  EFI_PCI_IO_PROTOCOL  *PciIo;
246
0
  PCI_TYPE00           Pci;
247
248
  //
249
  // Attempt to open the device with the PciIo set of interfaces. On success,
250
  // the protocol is "instantiated" for the PCI device. Covers duplicate open
251
  // attempts (EFI_ALREADY_STARTED).
252
  //
253
0
  Status = gBS->OpenProtocol (
254
0
                  DeviceHandle,               // candidate device
255
0
                  &gEfiPciIoProtocolGuid,     // for generic PCI access
256
0
                  (VOID **)&PciIo,            // handle to instantiate
257
0
                  This->DriverBindingHandle,  // requestor driver identity
258
0
                  DeviceHandle,               // ControllerHandle, according to
259
                                              // the UEFI Driver Model
260
0
                  EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive PciIo access to
261
                                              // the device; to be released
262
0
                  );
263
0
  if (EFI_ERROR (Status)) {
264
0
    return Status;
265
0
  }
266
267
  //
268
  // Read entire PCI configuration header for more extensive check ahead.
269
  //
270
0
  Status = PciIo->Pci.Read (
271
0
                        PciIo,                        // (protocol, device)
272
                                                      // handle
273
0
                        EfiPciIoWidthUint32,          // access width & copy
274
                                                      // mode
275
0
                        0,                            // Offset
276
0
                        sizeof Pci / sizeof (UINT32), // Count
277
0
                        &Pci                          // target buffer
278
0
                        );
279
280
0
  if (Status == EFI_SUCCESS) {
281
    //
282
    // virtio-0.9.5, 2.1 PCI Discovery
283
    //
284
0
    if ((Pci.Hdr.VendorId == VIRTIO_VENDOR_ID) &&
285
0
        (Pci.Hdr.DeviceId >= 0x1000) &&
286
0
        (Pci.Hdr.DeviceId <= 0x103F) &&
287
0
        (Pci.Hdr.RevisionID == 0x00))
288
0
    {
289
0
      Status = EFI_SUCCESS;
290
0
    } else {
291
0
      Status = EFI_UNSUPPORTED;
292
0
    }
293
0
  }
294
295
  //
296
  // We needed PCI IO access only transitorily, to see whether we support the
297
  // device or not.
298
  //
299
0
  gBS->CloseProtocol (
300
0
         DeviceHandle,
301
0
         &gEfiPciIoProtocolGuid,
302
0
         This->DriverBindingHandle,
303
0
         DeviceHandle
304
0
         );
305
306
0
  return Status;
307
0
}
308
309
/**
310
311
  Initialize the VirtIo PCI Device
312
313
  @param[in, out] Dev      The driver instance to configure. The caller is
314
                           responsible for Device->PciIo's validity (ie. working IO
315
                           access to the underlying virtio-pci device).
316
317
  @retval EFI_SUCCESS      Setup complete.
318
319
  @retval EFI_UNSUPPORTED  The underlying IO device doesn't support the
320
                           provided address offset and read size.
321
322
  @return                  Error codes from PciIo->Pci.Read().
323
324
**/
325
STATIC
326
EFI_STATUS
327
EFIAPI
328
VirtioPciInit (
329
  IN OUT VIRTIO_PCI_DEVICE  *Device
330
  )
331
0
{
332
0
  EFI_STATUS           Status;
333
0
  EFI_PCI_IO_PROTOCOL  *PciIo;
334
0
  PCI_TYPE00           Pci;
335
336
0
  ASSERT (Device != NULL);
337
0
  PciIo = Device->PciIo;
338
0
  ASSERT (PciIo != NULL);
339
0
  ASSERT (PciIo->Pci.Read != NULL);
340
341
0
  Status = PciIo->Pci.Read (
342
0
                        PciIo,                          // (protocol, device)
343
                                                        // handle
344
0
                        EfiPciIoWidthUint32,            // access width & copy
345
                                                        // mode
346
0
                        0,                              // Offset
347
0
                        sizeof (Pci) / sizeof (UINT32), // Count
348
0
                        &Pci                            // target buffer
349
0
                        );
350
0
  if (EFI_ERROR (Status)) {
351
0
    return Status;
352
0
  }
353
354
  //
355
  // Copy protocol template
356
  //
357
0
  CopyMem (
358
0
    &Device->VirtioDevice,
359
0
    &mDeviceProtocolTemplate,
360
0
    sizeof (VIRTIO_DEVICE_PROTOCOL)
361
0
    );
362
363
  //
364
  // Initialize the protocol interface attributes
365
  //
366
0
  Device->VirtioDevice.Revision          = VIRTIO_SPEC_REVISION (0, 9, 5);
367
0
  Device->VirtioDevice.SubSystemDeviceId = Pci.Device.SubsystemID;
368
369
  //
370
  // Note: We don't support the MSI-X capability.  If we did,
371
  //       the offset would become 24 after enabling MSI-X.
372
  //
373
0
  Device->DeviceSpecificConfigurationOffset =
374
0
    VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI;
375
376
0
  return EFI_SUCCESS;
377
0
}
378
379
/**
380
381
  Uninitialize the internals of a virtio-pci device that has been successfully
382
  set up with VirtioPciInit().
383
384
  @param[in, out]  Dev  The device to clean up.
385
386
**/
387
STATIC
388
VOID
389
EFIAPI
390
VirtioPciUninit (
391
  IN OUT VIRTIO_PCI_DEVICE  *Device
392
  )
393
0
{
394
  // Note: This function mirrors VirtioPciInit() that does not allocate any
395
  //       resources - there's nothing to free here.
396
0
}
397
398
/**
399
400
  After we've pronounced support for a specific device in
401
  DriverBindingSupported(), we start managing said device (passed in by the
402
  Driver Execution Environment) with the following service.
403
404
  See DriverBindingSupported() for specification references.
405
406
  @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
407
                                  incorporating this driver (independently of
408
                                  any device).
409
410
  @param[in] DeviceHandle         The supported device to drive.
411
412
  @param[in] RemainingDevicePath  Relevant only for bus drivers, ignored.
413
414
415
  @retval EFI_SUCCESS           Driver instance has been created and
416
                                initialized  for the virtio-pci device, it
417
                                is now accessible via VIRTIO_DEVICE_PROTOCOL.
418
419
  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
420
421
  @return                       Error codes from the OpenProtocol() boot
422
                                service, the PciIo protocol, VirtioPciInit(),
423
                                or the InstallProtocolInterface() boot service.
424
425
**/
426
STATIC
427
EFI_STATUS
428
EFIAPI
429
VirtioPciDeviceBindingStart (
430
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
431
  IN EFI_HANDLE                   DeviceHandle,
432
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
433
  )
434
0
{
435
0
  VIRTIO_PCI_DEVICE  *Device;
436
0
  EFI_STATUS         Status;
437
438
0
  Device = (VIRTIO_PCI_DEVICE *)AllocateZeroPool (sizeof *Device);
439
0
  if (Device == NULL) {
440
0
    return EFI_OUT_OF_RESOURCES;
441
0
  }
442
443
0
  Status = gBS->OpenProtocol (
444
0
                  DeviceHandle,
445
0
                  &gEfiPciIoProtocolGuid,
446
0
                  (VOID **)&Device->PciIo,
447
0
                  This->DriverBindingHandle,
448
0
                  DeviceHandle,
449
0
                  EFI_OPEN_PROTOCOL_BY_DRIVER
450
0
                  );
451
0
  if (EFI_ERROR (Status)) {
452
0
    goto FreeVirtioPci;
453
0
  }
454
455
  //
456
  // We must retain and ultimately restore the original PCI attributes of the
457
  // device. See Driver Writer's Guide for UEFI 2.3.1 v1.01, 18.3 PCI drivers /
458
  // 18.3.2 Start() and Stop().
459
  //
460
  // The third parameter ("Attributes", input) is ignored by the Get operation.
461
  // The fourth parameter ("Result", output) is ignored by the Enable and Set
462
  // operations.
463
  //
464
  // For virtio-pci we only need IO space access.
465
  //
466
0
  Status = Device->PciIo->Attributes (
467
0
                            Device->PciIo,
468
0
                            EfiPciIoAttributeOperationGet,
469
0
                            0,
470
0
                            &Device->OriginalPciAttributes
471
0
                            );
472
0
  if (EFI_ERROR (Status)) {
473
0
    goto ClosePciIo;
474
0
  }
475
476
0
  Status = Device->PciIo->Attributes (
477
0
                            Device->PciIo,
478
0
                            EfiPciIoAttributeOperationEnable,
479
0
                            (EFI_PCI_IO_ATTRIBUTE_IO |
480
0
                             EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
481
0
                            NULL
482
0
                            );
483
0
  if (EFI_ERROR (Status)) {
484
0
    goto ClosePciIo;
485
0
  }
486
487
  //
488
  // PCI IO access granted, configure protocol instance
489
  //
490
491
0
  Status = VirtioPciInit (Device);
492
0
  if (EFI_ERROR (Status)) {
493
0
    goto RestorePciAttributes;
494
0
  }
495
496
  //
497
  // Setup complete, attempt to export the driver instance's VirtioDevice
498
  // interface.
499
  //
500
0
  Device->Signature = VIRTIO_PCI_DEVICE_SIGNATURE;
501
0
  Status            = gBS->InstallProtocolInterface (
502
0
                             &DeviceHandle,
503
0
                             &gVirtioDeviceProtocolGuid,
504
0
                             EFI_NATIVE_INTERFACE,
505
0
                             &Device->VirtioDevice
506
0
                             );
507
0
  if (EFI_ERROR (Status)) {
508
0
    goto UninitDev;
509
0
  }
510
511
0
  return EFI_SUCCESS;
512
513
0
UninitDev:
514
0
  VirtioPciUninit (Device);
515
516
0
RestorePciAttributes:
517
0
  Device->PciIo->Attributes (
518
0
                   Device->PciIo,
519
0
                   EfiPciIoAttributeOperationSet,
520
0
                   Device->OriginalPciAttributes,
521
0
                   NULL
522
0
                   );
523
524
0
ClosePciIo:
525
0
  gBS->CloseProtocol (
526
0
         DeviceHandle,
527
0
         &gEfiPciIoProtocolGuid,
528
0
         This->DriverBindingHandle,
529
0
         DeviceHandle
530
0
         );
531
532
0
FreeVirtioPci:
533
0
  FreePool (Device);
534
535
0
  return Status;
536
0
}
537
538
/**
539
540
  Stop driving the Virtio PCI device
541
542
  @param[in] This               The EFI_DRIVER_BINDING_PROTOCOL object
543
                                incorporating this driver (independently of any
544
                                device).
545
546
  @param[in] DeviceHandle       Stop driving this device.
547
548
  @param[in] NumberOfChildren   Since this function belongs to a device driver
549
                                only (as opposed to a bus driver), the caller
550
                                environment sets NumberOfChildren to zero, and
551
                                we ignore it.
552
553
  @param[in] ChildHandleBuffer  Ignored (corresponding to NumberOfChildren).
554
555
  @retval EFI_SUCCESS           Driver instance has been stopped and the PCI
556
                                configuration attributes have been restored.
557
558
  @return                       Error codes from the OpenProtocol() or
559
                                CloseProtocol(), UninstallProtocolInterface()
560
                                boot services.
561
562
**/
563
STATIC
564
EFI_STATUS
565
EFIAPI
566
VirtioPciDeviceBindingStop (
567
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
568
  IN EFI_HANDLE                   DeviceHandle,
569
  IN UINTN                        NumberOfChildren,
570
  IN EFI_HANDLE                   *ChildHandleBuffer
571
  )
572
0
{
573
0
  EFI_STATUS              Status;
574
0
  VIRTIO_DEVICE_PROTOCOL  *VirtioDevice;
575
0
  VIRTIO_PCI_DEVICE       *Device;
576
577
0
  Status = gBS->OpenProtocol (
578
0
                  DeviceHandle,                  // candidate device
579
0
                  &gVirtioDeviceProtocolGuid,    // retrieve the VirtIo iface
580
0
                  (VOID **)&VirtioDevice,        // target pointer
581
0
                  This->DriverBindingHandle,     // requestor driver identity
582
0
                  DeviceHandle,                  // requesting lookup for dev.
583
0
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added
584
0
                  );
585
0
  if (EFI_ERROR (Status)) {
586
0
    return Status;
587
0
  }
588
589
0
  Device = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice);
590
591
  //
592
  // Handle Stop() requests for in-use driver instances gracefully.
593
  //
594
0
  Status = gBS->UninstallProtocolInterface (
595
0
                  DeviceHandle,
596
0
                  &gVirtioDeviceProtocolGuid,
597
0
                  &Device->VirtioDevice
598
0
                  );
599
0
  if (EFI_ERROR (Status)) {
600
0
    return Status;
601
0
  }
602
603
0
  VirtioPciUninit (Device);
604
605
0
  Device->PciIo->Attributes (
606
0
                   Device->PciIo,
607
0
                   EfiPciIoAttributeOperationSet,
608
0
                   Device->OriginalPciAttributes,
609
0
                   NULL
610
0
                   );
611
612
0
  Status = gBS->CloseProtocol (
613
0
                  DeviceHandle,
614
0
                  &gEfiPciIoProtocolGuid,
615
0
                  This->DriverBindingHandle,
616
0
                  DeviceHandle
617
0
                  );
618
619
0
  FreePool (Device);
620
621
0
  return Status;
622
0
}
623
624
//
625
// The static object that groups the Supported() (ie. probe), Start() and
626
// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
627
// C, 10.1 EFI Driver Binding Protocol.
628
//
629
STATIC EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
630
  &VirtioPciDeviceBindingSupported,
631
  &VirtioPciDeviceBindingStart,
632
  &VirtioPciDeviceBindingStop,
633
  0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
634
  NULL, // ImageHandle, to be overwritten by
635
        // EfiLibInstallDriverBindingComponentName2() in VirtioPciEntryPoint()
636
  NULL  // DriverBindingHandle, ditto
637
};
638
639
//
640
// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
641
// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
642
// in English, for display on standard console devices. This is recommended for
643
// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
644
// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
645
//
646
STATIC
647
EFI_UNICODE_STRING_TABLE  mDriverNameTable[] = {
648
  { "eng;en", L"Virtio PCI Driver" },
649
  { NULL,     NULL                 }
650
};
651
652
STATIC
653
EFI_COMPONENT_NAME_PROTOCOL  gComponentName;
654
655
EFI_STATUS
656
EFIAPI
657
VirtioPciGetDriverName (
658
  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
659
  IN  CHAR8                        *Language,
660
  OUT CHAR16                       **DriverName
661
  )
662
0
{
663
0
  return LookupUnicodeString2 (
664
0
           Language,
665
0
           This->SupportedLanguages,
666
0
           mDriverNameTable,
667
0
           DriverName,
668
0
           (BOOLEAN)(This == &gComponentName) // Iso639Language
669
0
           );
670
0
}
671
672
EFI_STATUS
673
EFIAPI
674
VirtioPciGetDeviceName (
675
  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
676
  IN  EFI_HANDLE                   DeviceHandle,
677
  IN  EFI_HANDLE                   ChildHandle,
678
  IN  CHAR8                        *Language,
679
  OUT CHAR16                       **ControllerName
680
  )
681
0
{
682
0
  return EFI_UNSUPPORTED;
683
0
}
684
685
STATIC
686
EFI_COMPONENT_NAME_PROTOCOL  gComponentName = {
687
  &VirtioPciGetDriverName,
688
  &VirtioPciGetDeviceName,
689
  "eng" // SupportedLanguages, ISO 639-2 language codes
690
};
691
692
STATIC
693
EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2 = {
694
  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)&VirtioPciGetDriverName,
695
  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)&VirtioPciGetDeviceName,
696
  "en" // SupportedLanguages, RFC 4646 language codes
697
};
698
699
//
700
// Entry point of this driver.
701
//
702
EFI_STATUS
703
EFIAPI
704
VirtioPciDeviceEntryPoint (
705
  IN EFI_HANDLE        ImageHandle,
706
  IN EFI_SYSTEM_TABLE  *SystemTable
707
  )
708
0
{
709
0
  return EfiLibInstallDriverBindingComponentName2 (
710
0
           ImageHandle,
711
0
           SystemTable,
712
0
           &gDriverBinding,
713
0
           ImageHandle,
714
0
           &gComponentName,
715
0
           &gComponentName2
716
0
           );
717
0
}