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