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