]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/VirtioBlkDxe/VirtioBlk.c
OvmfPkg: rename OFFSET_OF_VHDR() / SIZE_OF_VHDR() to *_OF_VBLK()
[mirror_edk2.git] / OvmfPkg / VirtioBlkDxe / VirtioBlk.c
1 /** @file
2
3 This driver produces Block I/O Protocol instances for virtio-blk devices.
4
5 The implementation is basic:
6
7 - No attach/detach (ie. removable media).
8
9 - Although the non-blocking interfaces of EFI_BLOCK_IO2_PROTOCOL could be a
10 good match for multiple in-flight virtio-blk requests, we stick to
11 synchronous requests and EFI_BLOCK_IO_PROTOCOL for now.
12
13 Copyright (C) 2012, Red Hat, Inc.
14
15 This program and the accompanying materials are licensed and made available
16 under the terms and conditions of the BSD License which accompanies this
17 distribution. The full text of the license may be found at
18 http://opensource.org/licenses/bsd-license.php
19
20 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
21 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22
23 **/
24
25 #include <IndustryStandard/Pci.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/DebugLib.h>
28 #include <Library/MemoryAllocationLib.h>
29 #include <Library/UefiBootServicesTableLib.h>
30 #include <Library/UefiLib.h>
31
32 #include "VirtioBlk.h"
33
34 /**
35
36 Write a word into Region 0 of the device specified by PciIo.
37
38 Region 0 must be an iomem region. This is an internal function for the
39 VIRTIO_CFG_WRITE() macro below.
40
41 @param[in] PciIo Target PCI device.
42
43 @param[in] FieldOffset Destination offset.
44
45 @param[in] FieldSize Destination field size, must be in { 1, 2, 4, 8 }.
46
47 @param[in] Value Little endian value to write, converted to UINT64.
48 The least significant FieldSize bytes will be used.
49
50
51 @return Status code returned by PciIo->Io.Write().
52
53 **/
54 STATIC
55 EFIAPI
56 EFI_STATUS
57 VirtioWrite (
58 IN EFI_PCI_IO_PROTOCOL *PciIo,
59 IN UINTN FieldOffset,
60 IN UINTN FieldSize,
61 IN UINT64 Value
62 )
63 {
64 UINTN Count;
65 EFI_PCI_IO_PROTOCOL_WIDTH Width;
66
67 Count = 1;
68 switch (FieldSize) {
69 case 1:
70 Width = EfiPciIoWidthUint8;
71 break;
72
73 case 2:
74 Width = EfiPciIoWidthUint16;
75 break;
76
77 case 8:
78 Count = 2;
79 // fall through
80
81 case 4:
82 Width = EfiPciIoWidthUint32;
83 break;
84
85 default:
86 ASSERT (FALSE);
87 }
88
89 return PciIo->Io.Write (
90 PciIo,
91 Width,
92 PCI_BAR_IDX0,
93 FieldOffset,
94 Count,
95 &Value
96 );
97 }
98
99
100 /**
101
102 Read a word from Region 0 of the device specified by PciIo.
103
104 Region 0 must be an iomem region. This is an internal function for the
105 VIRTIO_CFG_READ() macro below.
106
107 @param[in] PciIo Source PCI device.
108
109 @param[in] FieldOffset Source offset.
110
111 @param[in] FieldSize Source field size, must be in { 1, 2, 4, 8 }.
112
113 @param[in] BufferSize Number of bytes available in the target buffer. Must
114 equal FieldSize.
115
116 @param[out] Buffer Target buffer.
117
118
119 @return Status code returned by PciIo->Io.Read().
120
121 **/
122 STATIC
123 EFIAPI
124 EFI_STATUS
125 VirtioRead (
126 IN EFI_PCI_IO_PROTOCOL *PciIo,
127 IN UINTN FieldOffset,
128 IN UINTN FieldSize,
129 IN UINTN BufferSize,
130 OUT VOID *Buffer
131 )
132 {
133 UINTN Count;
134 EFI_PCI_IO_PROTOCOL_WIDTH Width;
135
136 ASSERT (FieldSize == BufferSize);
137
138 Count = 1;
139 switch (FieldSize) {
140 case 1:
141 Width = EfiPciIoWidthUint8;
142 break;
143
144 case 2:
145 Width = EfiPciIoWidthUint16;
146 break;
147
148 case 8:
149 Count = 2;
150 // fall through
151
152 case 4:
153 Width = EfiPciIoWidthUint32;
154 break;
155
156 default:
157 ASSERT (FALSE);
158 }
159
160 return PciIo->Io.Read (
161 PciIo,
162 Width,
163 PCI_BAR_IDX0,
164 FieldOffset,
165 Count,
166 Buffer
167 );
168 }
169
170
171 /**
172
173 Convenience macros to read and write region 0 IO space elements of the
174 virtio-blk PCI device, for configuration purposes.
175
176 The following macros make it possible to specify only the "core parameters"
177 for such accesses and to derive the rest. By the time VIRTIO_CFG_WRITE()
178 returns, the transaction will have been completed.
179
180 @param[in] Dev Pointer to the VBLK_DEV structure whose PCI IO space
181 we're accessing. Dev->PciIo must be valid.
182
183 @param[in] Field A field name from VBLK_HDR, identifying the virtio-blk
184 configuration item to access.
185
186 @param[in] Value (VIRTIO_CFG_WRITE() only.) The value to write to the
187 selected configuration item.
188
189 @param[out] Pointer (VIRTIO_CFG_READ() only.) The object to receive the
190 value read from the configuration item. Its type must be
191 one of UINT8, UINT16, UINT32, UINT64.
192
193
194 @return Status code returned by VirtioWrite() / VirtioRead().
195
196 **/
197
198 #define VIRTIO_CFG_WRITE(Dev, Field, Value) (VirtioWrite ( \
199 (Dev)->PciIo, \
200 OFFSET_OF_VBLK (Field), \
201 SIZE_OF_VBLK (Field), \
202 (Value) \
203 ))
204
205 #define VIRTIO_CFG_READ(Dev, Field, Pointer) (VirtioRead ( \
206 (Dev)->PciIo, \
207 OFFSET_OF_VBLK (Field), \
208 SIZE_OF_VBLK (Field), \
209 sizeof *(Pointer), \
210 (Pointer) \
211 ))
212
213
214 //
215 // UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol
216 // Driver Writer's Guide for UEFI 2.3.1 v1.01,
217 // 24.2 Block I/O Protocol Implementations
218 //
219 EFI_STATUS
220 EFIAPI
221 VirtioBlkReset (
222 IN EFI_BLOCK_IO_PROTOCOL *This,
223 IN BOOLEAN ExtendedVerification
224 )
225 {
226 //
227 // If we managed to initialize and install the driver, then the device is
228 // working correctly.
229 //
230 return EFI_SUCCESS;
231 }
232
233 /**
234
235 Verify correctness of the read/write (not flush) request submitted to the
236 EFI_BLOCK_IO_PROTOCOL instance.
237
238 This function provides most verification steps described in:
239
240 UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O
241 Protocol,
242 - EFI_BLOCK_IO_PROTOCOL.ReadBlocks()
243 - EFI_BLOCK_IO_PROTOCOL.WriteBlocks()
244
245 Driver Writer's Guide for UEFI 2.3.1 v1.01,
246 - 24.2.2. ReadBlocks() and ReadBlocksEx() Implementation
247 - 24.2.3 WriteBlocks() and WriteBlockEx() Implementation
248
249 Request sizes are limited to 1 GB (checked). This is not a practical
250 limitation, just conformance to virtio-0.9.5, 2.3.2 Descriptor Table: "no
251 descriptor chain may be more than 2^32 bytes long in total".
252
253 Some Media characteristics are hardcoded in VirtioBlkInit() below (like
254 non-removable media, no restriction on buffer alignment etc); we rely on
255 those here without explicit mention.
256
257 @param[in] Media The EFI_BLOCK_IO_MEDIA characteristics for
258 this driver instance, extracted from the
259 underlying virtio-blk device at initialization
260 time. We validate the request against this set
261 of attributes.
262
263
264 @param[in] Lba Logical Block Address: number of logical
265 blocks to skip from the beginning of the
266 device.
267
268 @param[in] PositiveBufferSize Size of buffer to transfer, in bytes. The
269 caller is responsible to ensure this parameter
270 is positive.
271
272 @param[in] RequestIsWrite TRUE iff data transfer goes from guest to
273 device.
274
275
276 @@return Validation result to be forwarded outwards by
277 ReadBlocks() and WriteBlocks, as required by
278 the specs above.
279
280 **/
281 STATIC
282 EFI_STATUS
283 EFIAPI
284 VerifyReadWriteRequest (
285 IN EFI_BLOCK_IO_MEDIA *Media,
286 IN EFI_LBA Lba,
287 IN UINTN PositiveBufferSize,
288 IN BOOLEAN RequestIsWrite
289 )
290 {
291 UINTN BlockCount;
292
293 ASSERT (PositiveBufferSize > 0);
294
295 if (PositiveBufferSize > SIZE_1GB ||
296 PositiveBufferSize % Media->BlockSize > 0) {
297 return EFI_BAD_BUFFER_SIZE;
298 }
299 BlockCount = PositiveBufferSize / Media->BlockSize;
300
301 //
302 // Avoid unsigned wraparound on either side in the second comparison.
303 //
304 if (Lba > Media->LastBlock || BlockCount - 1 > Media->LastBlock - Lba) {
305 return EFI_INVALID_PARAMETER;
306 }
307
308 if (RequestIsWrite && Media->ReadOnly) {
309 return EFI_WRITE_PROTECTED;
310 }
311
312 return EFI_SUCCESS;
313 }
314
315
316 /**
317
318 Append a contiguous buffer for transmission / reception via the virtio ring.
319
320 This function implements the following sections from virtio-0.9.5:
321 - 2.4.1.1 Placing Buffers into the Descriptor Table
322 - 2.4.1.2 Updating the Available Ring
323
324 Free space is taken as granted, since this driver supports only synchronous
325 requests and host side status is processed in lock-step with request
326 submission. VirtioBlkInit() verifies the ring size in advance.
327
328 @param[in out] Ring The virtio ring to append the buffer to, as a
329 descriptor.
330
331 @param [in] BufferPhysAddr (Guest pseudo-physical) start address of the
332 transmit / receive buffer
333
334 @param [in] BufferSize Number of bytes to transmit or receive.
335
336 @param [in] Flags A bitmask of VRING_DESC_F_* flags. The caller
337 computes this mask dependent on further buffers
338 to append and transfer direction.
339 VRING_DESC_F_INDIRECT is unsupported. The
340 VRING_DESC.Next field is always set, but the
341 host only interprets it dependent on
342 VRING_DESC_F_NEXT.
343
344 @param [in] HeadIdx The index identifying the head buffer (first
345 buffer appended) belonging to this same
346 request.
347
348 @param [in out] NextAvailIdx On input, the index identifying the next
349 descriptor available to carry the buffer. On
350 output, incremented by one, modulo 2^16.
351
352 **/
353
354 STATIC
355 VOID
356 EFIAPI
357 AppendDesc (
358 IN OUT VRING *Ring,
359 IN UINTN BufferPhysAddr,
360 IN UINT32 BufferSize,
361 IN UINT16 Flags,
362 IN UINT16 HeadIdx,
363 IN OUT UINT16 *NextAvailIdx
364 )
365 {
366 volatile VRING_DESC *Desc;
367
368 Desc = &Ring->Desc[*NextAvailIdx % Ring->QueueSize];
369 Desc->Addr = BufferPhysAddr;
370 Desc->Len = BufferSize;
371 Desc->Flags = Flags;
372 Ring->Avail.Ring[(*NextAvailIdx)++ % Ring->QueueSize] =
373 HeadIdx % Ring->QueueSize;
374 Desc->Next = *NextAvailIdx % Ring->QueueSize;
375 }
376
377
378 /**
379
380 Format a read / write / flush request as three consecutive virtio
381 descriptors, push them to the host, and poll for the response.
382
383 This is the main workhorse function. Two use cases are supported, read/write
384 and flush. The function may only be called after the request parameters have
385 been verified by
386 - specific checks in ReadBlocks() / WriteBlocks() / FlushBlocks(), and
387 - VerifyReadWriteRequest() (for read/write only).
388
389 Parameters handled commonly:
390
391 @param[in] Dev The virtio-blk device the request is targeted
392 at.
393
394 Flush request:
395
396 @param[in] Lba Must be zero.
397
398 @param[in] BufferSize Must be zero.
399
400 @param[in out] Buffer Ignored by the function.
401
402 @param[in] RequestIsWrite Must be TRUE.
403
404 Read/Write request:
405
406 @param[in] Lba Logical Block Address: number of logical blocks
407 to skip from the beginning of the device.
408
409 @param[in] BufferSize Size of buffer to transfer, in bytes. The caller
410 is responsible to ensure this parameter is
411 positive.
412
413 @param[in out] Buffer The guest side area to read data from the device
414 into, or write data to the device from.
415
416 @param[in] RequestIsWrite TRUE iff data transfer goes from guest to
417 device.
418
419 Return values are common to both use cases, and are appropriate to be
420 forwarded by the EFI_BLOCK_IO_PROTOCOL functions (ReadBlocks(),
421 WriteBlocks(), FlushBlocks()).
422
423
424 @retval EFI_SUCCESS Transfer complete.
425
426 @retval EFI_DEVICE_ERROR Failed to notify host side via PCI write, or
427 unable to parse host response, or host response
428 is not VIRTIO_BLK_S_OK.
429
430 **/
431
432 STATIC
433 EFI_STATUS
434 EFIAPI
435 SynchronousRequest (
436 IN VBLK_DEV *Dev,
437 IN EFI_LBA Lba,
438 IN UINTN BufferSize,
439 IN OUT volatile VOID *Buffer,
440 IN BOOLEAN RequestIsWrite
441 )
442 {
443 UINT32 BlockSize;
444 volatile VIRTIO_BLK_REQ Request;
445 volatile UINT8 HostStatus;
446 UINT16 FirstAvailIdx;
447 UINT16 NextAvailIdx;
448 UINTN PollPeriodUsecs;
449
450 BlockSize = Dev->BlockIoMedia.BlockSize;
451
452 //
453 // ensured by VirtioBlkInit()
454 //
455 ASSERT (BlockSize > 0);
456 ASSERT (BlockSize % 512 == 0);
457
458 //
459 // ensured by contract above, plus VerifyReadWriteRequest()
460 //
461 ASSERT (BufferSize % BlockSize == 0);
462
463 //
464 // Prepare virtio-blk request header, setting zero size for flush.
465 // IO Priority is homogeneously 0.
466 //
467 Request.Type = RequestIsWrite ?
468 (BufferSize == 0 ? VIRTIO_BLK_T_FLUSH : VIRTIO_BLK_T_OUT) :
469 VIRTIO_BLK_T_IN;
470 Request.IoPrio = 0;
471 Request.Sector = Lba * (BlockSize / 512);
472
473 //
474 // Prepare for virtio-0.9.5, 2.4.2 Receiving Used Buffers From the Device.
475 // We're going to poll the answer, the host should not send an interrupt.
476 //
477 *Dev->Ring.Avail.Flags = (UINT16) VRING_AVAIL_F_NO_INTERRUPT;
478
479 //
480 // preset a host status for ourselves that we do not accept as success
481 //
482 HostStatus = VIRTIO_BLK_S_IOERR;
483
484 //
485 // ensured by VirtioBlkInit() -- this predicate, in combination with the
486 // lock-step progress, ensures we don't have to track free descriptors.
487 //
488 ASSERT (Dev->Ring.QueueSize >= 3);
489
490 //
491 // Implement virtio-0.9.5, 2.4.1 Supplying Buffers to the Device.
492 //
493 FirstAvailIdx = *Dev->Ring.Avail.Idx;
494 NextAvailIdx = FirstAvailIdx;
495
496 //
497 // virtio-blk header in first desc
498 //
499 AppendDesc (&Dev->Ring, (UINTN) &Request, sizeof Request, VRING_DESC_F_NEXT,
500 FirstAvailIdx, &NextAvailIdx);
501
502 //
503 // data buffer for read/write in second desc
504 //
505 if (BufferSize > 0) {
506 //
507 // From virtio-0.9.5, 2.3.2 Descriptor Table:
508 // "no descriptor chain may be more than 2^32 bytes long in total".
509 //
510 // The predicate is ensured by the call contract above (for flush), or
511 // VerifyReadWriteRequest() (for read/write). It also implies that
512 // converting BufferSize to UINT32 will not truncate it.
513 //
514 ASSERT (BufferSize <= SIZE_1GB);
515
516 //
517 // VRING_DESC_F_WRITE is interpreted from the host's point of view.
518 //
519 AppendDesc (&Dev->Ring, (UINTN) Buffer, (UINT32) BufferSize,
520 VRING_DESC_F_NEXT | (RequestIsWrite ? 0 : VRING_DESC_F_WRITE),
521 FirstAvailIdx, &NextAvailIdx);
522 }
523
524 //
525 // host status in last (second or third) desc
526 //
527 AppendDesc (&Dev->Ring, (UINTN) &HostStatus, sizeof HostStatus,
528 VRING_DESC_F_WRITE, FirstAvailIdx, &NextAvailIdx);
529
530 //
531 // virtio-0.9.5, 2.4.1.3 Updating the Index Field
532 //
533 MemoryFence();
534 *Dev->Ring.Avail.Idx = NextAvailIdx;
535
536 //
537 // virtio-0.9.5, 2.4.1.4 Notifying the Device -- gratuitous notifications are
538 // OK. virtio-blk's only virtqueue is #0, called "requestq" (see Appendix D).
539 //
540 MemoryFence();
541 if (EFI_ERROR (VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueNotify, 0))) {
542 return EFI_DEVICE_ERROR;
543 }
544
545 //
546 // virtio-0.9.5, 2.4.2 Receiving Used Buffers From the Device
547 // Wait until the host processes and acknowledges our 3-part descriptor
548 // chain. The condition we use for polling is greatly simplified and relies
549 // on synchronous, the lock-step progress.
550 //
551 // Keep slowing down until we reach a poll period of slightly above 1 ms.
552 //
553 PollPeriodUsecs = 1;
554 MemoryFence();
555 while (*Dev->Ring.Used.Idx != NextAvailIdx) {
556 gBS->Stall (PollPeriodUsecs); // calls AcpiTimerLib::MicroSecondDelay
557
558 if (PollPeriodUsecs < 1024) {
559 PollPeriodUsecs *= 2;
560 }
561 MemoryFence();
562 }
563
564 if (HostStatus == VIRTIO_BLK_S_OK) {
565 return EFI_SUCCESS;
566 }
567
568 return EFI_DEVICE_ERROR;
569 }
570
571
572 /**
573
574 ReadBlocks() operation for virtio-blk.
575
576 See
577 - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O
578 Protocol, EFI_BLOCK_IO_PROTOCOL.ReadBlocks().
579 - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.2. ReadBlocks() and
580 ReadBlocksEx() Implementation.
581
582 Parameter checks and conformant return values are implemented in
583 VerifyReadWriteRequest() and SynchronousRequest().
584
585 A zero BufferSize doesn't seem to be prohibited, so do nothing in that case,
586 successfully.
587
588 **/
589
590 EFI_STATUS
591 EFIAPI
592 VirtioBlkReadBlocks (
593 IN EFI_BLOCK_IO_PROTOCOL *This,
594 IN UINT32 MediaId,
595 IN EFI_LBA Lba,
596 IN UINTN BufferSize,
597 OUT VOID *Buffer
598 )
599 {
600 VBLK_DEV *Dev;
601 EFI_STATUS Status;
602
603 if (BufferSize == 0) {
604 return EFI_SUCCESS;
605 }
606
607 Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
608 Status = VerifyReadWriteRequest (
609 &Dev->BlockIoMedia,
610 Lba,
611 BufferSize,
612 FALSE // RequestIsWrite
613 );
614 if (EFI_ERROR (Status)) {
615 return Status;
616 }
617
618 return SynchronousRequest (
619 Dev,
620 Lba,
621 BufferSize,
622 Buffer,
623 FALSE // RequestIsWrite
624 );
625 }
626
627 /**
628
629 WriteBlocks() operation for virtio-blk.
630
631 See
632 - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O
633 Protocol, EFI_BLOCK_IO_PROTOCOL.WriteBlocks().
634 - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.3 WriteBlocks() and
635 WriteBlockEx() Implementation.
636
637 Parameter checks and conformant return values are implemented in
638 VerifyReadWriteRequest() and SynchronousRequest().
639
640 A zero BufferSize doesn't seem to be prohibited, so do nothing in that case,
641 successfully.
642
643 **/
644
645 EFI_STATUS
646 EFIAPI
647 VirtioBlkWriteBlocks (
648 IN EFI_BLOCK_IO_PROTOCOL *This,
649 IN UINT32 MediaId,
650 IN EFI_LBA Lba,
651 IN UINTN BufferSize,
652 IN VOID *Buffer
653 )
654 {
655 VBLK_DEV *Dev;
656 EFI_STATUS Status;
657
658 if (BufferSize == 0) {
659 return EFI_SUCCESS;
660 }
661
662 Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
663 Status = VerifyReadWriteRequest (
664 &Dev->BlockIoMedia,
665 Lba,
666 BufferSize,
667 TRUE // RequestIsWrite
668 );
669 if (EFI_ERROR (Status)) {
670 return Status;
671 }
672
673 return SynchronousRequest (
674 Dev,
675 Lba,
676 BufferSize,
677 Buffer,
678 TRUE // RequestIsWrite
679 );
680 }
681
682
683 /**
684
685 FlushBlocks() operation for virtio-blk.
686
687 See
688 - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O
689 Protocol, EFI_BLOCK_IO_PROTOCOL.FlushBlocks().
690 - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.4 FlushBlocks() and
691 FlushBlocksEx() Implementation.
692
693 If the underlying virtio-blk device doesn't support flushing (ie.
694 write-caching), then this function should not be called by higher layers,
695 according to EFI_BLOCK_IO_MEDIA characteristics set in VirtioBlkInit().
696 Should they do nonetheless, we do nothing, successfully.
697
698 **/
699
700 EFI_STATUS
701 EFIAPI
702 VirtioBlkFlushBlocks (
703 IN EFI_BLOCK_IO_PROTOCOL *This
704 )
705 {
706 VBLK_DEV *Dev;
707
708 Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
709 return Dev->BlockIoMedia.WriteCaching ?
710 SynchronousRequest (
711 Dev,
712 0, // Lba
713 0, // BufferSize
714 NULL, // Buffer
715 TRUE // RequestIsWrite
716 ) :
717 EFI_SUCCESS;
718 }
719
720
721 /**
722
723 Device probe function for this driver.
724
725 The DXE core calls this function for any given device in order to see if the
726 driver can drive the device.
727
728 Specs relevant in the general sense:
729
730 - UEFI Spec 2.3.1 + Errata C:
731 - 6.3 Protocol Handler Services -- for accessing the underlying device
732 - 10.1 EFI Driver Binding Protocol -- for exporting ourselves
733
734 - Driver Writer's Guide for UEFI 2.3.1 v1.01:
735 - 5.1.3.4 OpenProtocol() and CloseProtocol() -- for accessing the
736 underlying device
737 - 9 Driver Binding Protocol -- for exporting ourselves
738
739 Specs relevant in the specific sense:
740 - UEFI Spec 2.3.1 + Errata C, 13.4 EFI PCI I/O Protocol
741 - Driver Writer's Guide for UEFI 2.3.1 v1.01, 18 PCI Driver Design
742 Guidelines, 18.3 PCI drivers.
743
744 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object
745 incorporating this driver (independently of
746 any device).
747
748 @param[in] DeviceHandle The device to probe.
749
750 @param[in] RemainingDevicePath Relevant only for bus drivers, ignored.
751
752
753 @retval EFI_SUCCESS The driver supports the device being probed.
754
755 @retval EFI_UNSUPPORTED Based on virtio-blk PCI discovery, we do not support
756 the device.
757
758 @return Error codes from the OpenProtocol() boot service or
759 the PciIo protocol.
760
761 **/
762
763 EFI_STATUS
764 EFIAPI
765 VirtioBlkDriverBindingSupported (
766 IN EFI_DRIVER_BINDING_PROTOCOL *This,
767 IN EFI_HANDLE DeviceHandle,
768 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
769 )
770 {
771 EFI_STATUS Status;
772 EFI_PCI_IO_PROTOCOL *PciIo;
773 PCI_TYPE00 Pci;
774
775 //
776 // Attempt to open the device with the PciIo set of interfaces. On success,
777 // the protocol is "instantiated" for the PCI device. Covers duplicate open
778 // attempts (EFI_ALREADY_STARTED).
779 //
780 Status = gBS->OpenProtocol (
781 DeviceHandle, // candidate device
782 &gEfiPciIoProtocolGuid, // for generic PCI access
783 (VOID **)&PciIo, // handle to instantiate
784 This->DriverBindingHandle, // requestor driver identity
785 DeviceHandle, // ControllerHandle, according to
786 // the UEFI Driver Model
787 EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive PciIo access to
788 // the device; to be released
789 );
790 if (EFI_ERROR (Status)) {
791 return Status;
792 }
793
794 //
795 // Read entire PCI configuration header for more extensive check ahead.
796 //
797 Status = PciIo->Pci.Read (
798 PciIo, // (protocol, device)
799 // handle
800 EfiPciIoWidthUint32, // access width & copy
801 // mode
802 0, // Offset
803 sizeof Pci / sizeof (UINT32), // Count
804 &Pci // target buffer
805 );
806
807 if (Status == EFI_SUCCESS) {
808 //
809 // virtio-0.9.5, 2.1 PCI Discovery
810 //
811 Status = (Pci.Hdr.VendorId == 0x1AF4 &&
812 Pci.Hdr.DeviceId >= 0x1000 && Pci.Hdr.DeviceId <= 0x103F &&
813 Pci.Hdr.RevisionID == 0x00 &&
814 Pci.Device.SubsystemID == 0x02) ? EFI_SUCCESS : EFI_UNSUPPORTED;
815 }
816
817 //
818 // We needed PCI IO access only transitorily, to see whether we support the
819 // device or not.
820 //
821 gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
822 This->DriverBindingHandle, DeviceHandle);
823 return Status;
824 }
825
826
827 /**
828
829 Configure a virtio ring.
830
831 This function sets up internal storage (the guest-host communication area)
832 and lays out several "navigation" (ie. no-ownership) pointers to parts of
833 that storage.
834
835 Relevant sections from the virtio-0.9.5 spec:
836 - 1.1 Virtqueues,
837 - 2.3 Virtqueue Configuration.
838
839 @param[in] The number of descriptors to allocate for the
840 virtio ring, as requested by the host.
841
842 @param[out] Ring The virtio ring to set up.
843
844 @retval EFI_OUT_OF_RESOURCES AllocatePages() failed to allocate contiguous
845 pages for the requested QueueSize. Fields of
846 Ring have indeterminate value.
847
848 @retval EFI_SUCCESS Allocation and setup successful. Ring->Base
849 (and nothing else) is responsible for
850 deallocation.
851
852 **/
853
854 STATIC
855 EFI_STATUS
856 EFIAPI
857 VirtioRingInit (
858 IN UINT16 QueueSize,
859 OUT VRING *Ring
860 )
861 {
862 UINTN RingSize;
863 volatile UINT8 *RingPagesPtr;
864
865 RingSize = ALIGN_VALUE (
866 sizeof *Ring->Desc * QueueSize +
867 sizeof *Ring->Avail.Flags +
868 sizeof *Ring->Avail.Idx +
869 sizeof *Ring->Avail.Ring * QueueSize +
870 sizeof *Ring->Avail.UsedEvent,
871 EFI_PAGE_SIZE);
872
873 RingSize += ALIGN_VALUE (
874 sizeof *Ring->Used.Flags +
875 sizeof *Ring->Used.Idx +
876 sizeof *Ring->Used.UsedElem * QueueSize +
877 sizeof *Ring->Used.AvailEvent,
878 EFI_PAGE_SIZE);
879
880 Ring->NumPages = EFI_SIZE_TO_PAGES (RingSize);
881 Ring->Base = AllocatePages (Ring->NumPages);
882 if (Ring->Base == NULL) {
883 return EFI_OUT_OF_RESOURCES;
884 }
885 SetMem (Ring->Base, RingSize, 0x00);
886 RingPagesPtr = Ring->Base;
887
888 Ring->Desc = (volatile VOID *) RingPagesPtr;
889 RingPagesPtr += sizeof *Ring->Desc * QueueSize;
890
891 Ring->Avail.Flags = (volatile VOID *) RingPagesPtr;
892 RingPagesPtr += sizeof *Ring->Avail.Flags;
893
894 Ring->Avail.Idx = (volatile VOID *) RingPagesPtr;
895 RingPagesPtr += sizeof *Ring->Avail.Idx;
896
897 Ring->Avail.Ring = (volatile VOID *) RingPagesPtr;
898 RingPagesPtr += sizeof *Ring->Avail.Ring * QueueSize;
899
900 Ring->Avail.UsedEvent = (volatile VOID *) RingPagesPtr;
901 RingPagesPtr += sizeof *Ring->Avail.UsedEvent;
902
903 RingPagesPtr = (volatile UINT8 *) Ring->Base +
904 ALIGN_VALUE (RingPagesPtr - (volatile UINT8 *) Ring->Base,
905 EFI_PAGE_SIZE);
906
907 Ring->Used.Flags = (volatile VOID *) RingPagesPtr;
908 RingPagesPtr += sizeof *Ring->Used.Flags;
909
910 Ring->Used.Idx = (volatile VOID *) RingPagesPtr;
911 RingPagesPtr += sizeof *Ring->Used.Idx;
912
913 Ring->Used.UsedElem = (volatile VOID *) RingPagesPtr;
914 RingPagesPtr += sizeof *Ring->Used.UsedElem * QueueSize;
915
916 Ring->Used.AvailEvent = (volatile VOID *) RingPagesPtr;
917 RingPagesPtr += sizeof *Ring->Used.AvailEvent;
918
919 Ring->QueueSize = QueueSize;
920 return EFI_SUCCESS;
921 }
922
923
924 /**
925
926 Tear down the internal resources of a configured virtio ring.
927
928 The caller is responsible to stop the host from using this ring before
929 invoking this function: the VSTAT_DRIVER_OK bit must be clear in
930 VhdrDeviceStatus.
931
932 @param[out] Ring The virtio ring to clean up.
933
934 **/
935
936
937 STATIC
938 VOID
939 EFIAPI
940 VirtioRingUninit (
941 IN OUT VRING *Ring
942 )
943 {
944 FreePages (Ring->Base, Ring->NumPages);
945 SetMem (Ring, sizeof *Ring, 0x00);
946 }
947
948
949 /**
950
951 Set up all BlockIo and virtio-blk aspects of this driver for the specified
952 device.
953
954 @param[in out] Dev The driver instance to configure. The caller is
955 responsible for Dev->PciIo's validity (ie. working IO
956 access to the underlying virtio-blk PCI device).
957
958 @retval EFI_SUCCESS Setup complete.
959
960 @retval EFI_UNSUPPORTED The driver is unable to work with the virtio ring or
961 virtio-blk attributes the host provides.
962
963 @return Error codes from VirtioRingInit() or
964 VIRTIO_CFG_READ() / VIRTIO_CFG_WRITE().
965
966 **/
967
968 STATIC
969 EFI_STATUS
970 EFIAPI
971 VirtioBlkInit (
972 IN OUT VBLK_DEV *Dev
973 )
974 {
975 UINT8 NextDevStat;
976 EFI_STATUS Status;
977
978 UINT32 Features;
979 UINT64 NumSectors;
980 UINT32 BlockSize;
981 UINT16 QueueSize;
982
983 //
984 // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
985 //
986 NextDevStat = 0; // step 1 -- reset device
987 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
988 if (EFI_ERROR (Status)) {
989 goto Failed;
990 }
991
992 NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence
993 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
994 if (EFI_ERROR (Status)) {
995 goto Failed;
996 }
997
998 NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
999 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
1000 if (EFI_ERROR (Status)) {
1001 goto Failed;
1002 }
1003
1004 //
1005 // step 4a -- retrieve and validate features
1006 //
1007 Status = VIRTIO_CFG_READ (Dev, Generic.VhdrDeviceFeatureBits, &Features);
1008 if (EFI_ERROR (Status)) {
1009 goto Failed;
1010 }
1011 Status = VIRTIO_CFG_READ (Dev, VhdrCapacity, &NumSectors);
1012 if (EFI_ERROR (Status)) {
1013 goto Failed;
1014 }
1015 if (NumSectors == 0) {
1016 Status = EFI_UNSUPPORTED;
1017 goto Failed;
1018 }
1019
1020 if (Features & VIRTIO_BLK_F_BLK_SIZE) {
1021 Status = VIRTIO_CFG_READ (Dev, VhdrBlkSize, &BlockSize);
1022 if (EFI_ERROR (Status)) {
1023 goto Failed;
1024 }
1025 if (BlockSize == 0 || BlockSize % 512 != 0 ||
1026 NumSectors % (BlockSize / 512) != 0) {
1027 //
1028 // We can only handle a logical block consisting of whole sectors,
1029 // and only a disk composed of whole logical blocks.
1030 //
1031 Status = EFI_UNSUPPORTED;
1032 goto Failed;
1033 }
1034 }
1035 else {
1036 BlockSize = 512;
1037 }
1038
1039 //
1040 // step 4b -- allocate virtqueue
1041 //
1042 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueSelect, 0);
1043 if (EFI_ERROR (Status)) {
1044 goto Failed;
1045 }
1046 Status = VIRTIO_CFG_READ (Dev, Generic.VhdrQueueSize, &QueueSize);
1047 if (EFI_ERROR (Status)) {
1048 goto Failed;
1049 }
1050 if (QueueSize < 3) { // SynchronousRequest() uses at most three descriptors
1051 Status = EFI_UNSUPPORTED;
1052 goto Failed;
1053 }
1054
1055 Status = VirtioRingInit (QueueSize, &Dev->Ring);
1056 if (EFI_ERROR (Status)) {
1057 goto Failed;
1058 }
1059
1060 //
1061 // step 4c -- Report GPFN (guest-physical frame number) of queue. If anything
1062 // fails from here on, we must release the ring resources.
1063 //
1064 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueAddress,
1065 (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT);
1066 if (EFI_ERROR (Status)) {
1067 goto ReleaseQueue;
1068 }
1069
1070 //
1071 // step 5 -- Report understood features. There are no virtio-blk specific
1072 // features to negotiate in virtio-0.9.5, plus we do not want any of the
1073 // device-independent (known or unknown) VIRTIO_F_* capabilities (see
1074 // Appendix B).
1075 //
1076 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrGuestFeatureBits, 0);
1077 if (EFI_ERROR (Status)) {
1078 goto ReleaseQueue;
1079 }
1080
1081 //
1082 // step 6 -- initialization complete
1083 //
1084 NextDevStat |= VSTAT_DRIVER_OK;
1085 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
1086 if (EFI_ERROR (Status)) {
1087 goto ReleaseQueue;
1088 }
1089
1090 //
1091 // Populate the exported interface's attributes; see UEFI spec v2.3.1 +
1092 // Errata C, 12.8 EFI Block I/O Protocol. We stick to the lowest possible
1093 // EFI_BLOCK_IO_PROTOCOL revision for now.
1094 //
1095 Dev->BlockIo.Revision = 0;
1096 Dev->BlockIo.Media = &Dev->BlockIoMedia;
1097 Dev->BlockIo.Reset = &VirtioBlkReset;
1098 Dev->BlockIo.ReadBlocks = &VirtioBlkReadBlocks;
1099 Dev->BlockIo.WriteBlocks = &VirtioBlkWriteBlocks;
1100 Dev->BlockIo.FlushBlocks = &VirtioBlkFlushBlocks;
1101 Dev->BlockIoMedia.MediaId = 0;
1102 Dev->BlockIoMedia.RemovableMedia = FALSE;
1103 Dev->BlockIoMedia.MediaPresent = TRUE;
1104 Dev->BlockIoMedia.LogicalPartition = FALSE;
1105 Dev->BlockIoMedia.ReadOnly = !!(Features & VIRTIO_BLK_F_RO);
1106 Dev->BlockIoMedia.WriteCaching = !!(Features & VIRTIO_BLK_F_FLUSH);
1107 Dev->BlockIoMedia.BlockSize = BlockSize;
1108 Dev->BlockIoMedia.IoAlign = 0;
1109 Dev->BlockIoMedia.LastBlock = NumSectors / (BlockSize / 512) - 1;
1110 return EFI_SUCCESS;
1111
1112 ReleaseQueue:
1113 VirtioRingUninit (&Dev->Ring);
1114
1115 Failed:
1116 //
1117 // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device
1118 // Status. PCI IO access failure here should not mask the original error.
1119 //
1120 NextDevStat |= VSTAT_FAILED;
1121 VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
1122
1123 return Status; // reached only via Failed above
1124 }
1125
1126
1127 /**
1128
1129 Uninitialize the internals of a virtio-blk device that has been successfully
1130 set up with VirtioBlkInit().
1131
1132 @param[in out] Dev The device to clean up.
1133
1134 **/
1135
1136 STATIC
1137 VOID
1138 EFIAPI
1139 VirtioBlkUninit (
1140 IN OUT VBLK_DEV *Dev
1141 )
1142 {
1143 //
1144 // Reset the virtual device -- see virtio-0.9.5, 2.2.2.1 Device Status. When
1145 // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from
1146 // the old comms area.
1147 //
1148 VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0);
1149
1150 VirtioRingUninit (&Dev->Ring);
1151
1152 SetMem (&Dev->BlockIo, sizeof Dev->BlockIo, 0x00);
1153 SetMem (&Dev->BlockIoMedia, sizeof Dev->BlockIoMedia, 0x00);
1154 }
1155
1156
1157 /**
1158
1159 After we've pronounced support for a specific device in
1160 DriverBindingSupported(), we start managing said device (passed in by the
1161 Driver Exeuction Environment) with the following service.
1162
1163 See DriverBindingSupported() for specification references.
1164
1165 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object
1166 incorporating this driver (independently of
1167 any device).
1168
1169 @param[in] DeviceHandle The supported device to drive.
1170
1171 @param[in] RemainingDevicePath Relevant only for bus drivers, ignored.
1172
1173
1174 @retval EFI_SUCCESS Driver instance has been created and
1175 initialized for the virtio-blk PCI device, it
1176 is now accessibla via EFI_BLOCK_IO_PROTOCOL.
1177
1178 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
1179
1180 @return Error codes from the OpenProtocol() boot
1181 service, the PciIo protocol, VirtioBlkInit(),
1182 or the InstallProtocolInterface() boot service.
1183
1184 **/
1185
1186 EFI_STATUS
1187 EFIAPI
1188 VirtioBlkDriverBindingStart (
1189 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1190 IN EFI_HANDLE DeviceHandle,
1191 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
1192 )
1193 {
1194 VBLK_DEV *Dev;
1195 EFI_STATUS Status;
1196
1197 Dev = (VBLK_DEV *) AllocateZeroPool (sizeof *Dev);
1198 if (Dev == NULL) {
1199 return EFI_OUT_OF_RESOURCES;
1200 }
1201
1202 Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
1203 (VOID **)&Dev->PciIo, This->DriverBindingHandle,
1204 DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
1205 if (EFI_ERROR (Status)) {
1206 goto FreeVirtioBlk;
1207 }
1208
1209 //
1210 // We must retain and ultimately restore the original PCI attributes of the
1211 // device. See Driver Writer's Guide for UEFI 2.3.1 v1.01, 18.3 PCI drivers /
1212 // 18.3.2 Start() and Stop().
1213 //
1214 // The third parameter ("Attributes", input) is ignored by the Get operation.
1215 // The fourth parameter ("Result", output) is ignored by the Enable and Set
1216 // operations.
1217 //
1218 // For virtio-blk we only need IO space access.
1219 //
1220 Status = Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationGet,
1221 0, &Dev->OriginalPciAttributes);
1222 if (EFI_ERROR (Status)) {
1223 goto ClosePciIo;
1224 }
1225
1226 Status = Dev->PciIo->Attributes (Dev->PciIo,
1227 EfiPciIoAttributeOperationEnable,
1228 EFI_PCI_IO_ATTRIBUTE_IO, NULL);
1229 if (EFI_ERROR (Status)) {
1230 goto ClosePciIo;
1231 }
1232
1233 //
1234 // PCI IO access granted, configure virtio-blk device.
1235 //
1236 Status = VirtioBlkInit (Dev);
1237 if (EFI_ERROR (Status)) {
1238 goto RestorePciAttributes;
1239 }
1240
1241 //
1242 // Setup complete, attempt to export the driver instance's BlockIo interface.
1243 //
1244 Dev->Signature = VBLK_SIG;
1245 Status = gBS->InstallProtocolInterface (&DeviceHandle,
1246 &gEfiBlockIoProtocolGuid, EFI_NATIVE_INTERFACE,
1247 &Dev->BlockIo);
1248 if (EFI_ERROR (Status)) {
1249 goto UninitDev;
1250 }
1251
1252 return EFI_SUCCESS;
1253
1254 UninitDev:
1255 VirtioBlkUninit (Dev);
1256
1257 RestorePciAttributes:
1258 Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet,
1259 Dev->OriginalPciAttributes, NULL);
1260
1261 ClosePciIo:
1262 gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
1263 This->DriverBindingHandle, DeviceHandle);
1264
1265 FreeVirtioBlk:
1266 FreePool (Dev);
1267
1268 return Status;
1269 }
1270
1271
1272 /**
1273
1274 Stop driving a virtio-blk device and remove its BlockIo interface.
1275
1276 This function replays the success path of DriverBindingStart() in reverse.
1277 The host side virtio-blk device is reset, so that the OS boot loader or the
1278 OS may reinitialize it.
1279
1280 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object
1281 incorporating this driver (independently of any
1282 device).
1283
1284 @param[in] DeviceHandle Stop driving this device.
1285
1286 @param[in] NumberOfChildren Since this function belongs to a device driver
1287 only (as opposed to a bus driver), the caller
1288 environment sets NumberOfChildren to zero, and
1289 we ignore it.
1290
1291 @param[in] ChildHandleBuffer Ignored (corresponding to NumberOfChildren).
1292
1293 **/
1294
1295 EFI_STATUS
1296 EFIAPI
1297 VirtioBlkDriverBindingStop (
1298 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1299 IN EFI_HANDLE DeviceHandle,
1300 IN UINTN NumberOfChildren,
1301 IN EFI_HANDLE *ChildHandleBuffer
1302 )
1303 {
1304 VBLK_DEV *Dev;
1305 EFI_STATUS Status;
1306
1307 Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
1308
1309 //
1310 // If DriverBindingStop() is called with the driver instance still in use,
1311 // or any of the parameters are invalid, we've caught a bug.
1312 //
1313 Status = gBS->UninstallProtocolInterface (DeviceHandle,
1314 &gEfiBlockIoProtocolGuid, &Dev->BlockIo);
1315 ASSERT (Status == EFI_SUCCESS);
1316
1317 VirtioBlkUninit (Dev);
1318
1319 Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet,
1320 Dev->OriginalPciAttributes, NULL);
1321
1322 gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
1323 This->DriverBindingHandle, DeviceHandle);
1324
1325 FreePool (Dev);
1326
1327 return EFI_SUCCESS;
1328 }
1329
1330
1331 //
1332 // The static object that groups the Supported() (ie. probe), Start() and
1333 // Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
1334 // C, 10.1 EFI Driver Binding Protocol.
1335 //
1336 STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
1337 &VirtioBlkDriverBindingSupported,
1338 &VirtioBlkDriverBindingStart,
1339 &VirtioBlkDriverBindingStop,
1340 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
1341 NULL, // ImageHandle, to be overwritten by
1342 // EfiLibInstallDriverBindingComponentName2() in VirtioBlkEntryPoint()
1343 NULL // DriverBindingHandle, ditto
1344 };
1345
1346
1347 //
1348 // The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
1349 // EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
1350 // in English, for display on standard console devices. This is recommended for
1351 // UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
1352 // Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
1353 //
1354 // Device type names ("Virtio Block Device") are not formatted because the
1355 // driver supports only that device type. Therefore the driver name suffices
1356 // for unambiguous identification.
1357 //
1358
1359 STATIC GLOBAL_REMOVE_IF_UNREFERENCED
1360 EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
1361 { "eng;en", L"Virtio Block Driver" },
1362 { NULL, NULL }
1363 };
1364
1365 STATIC GLOBAL_REMOVE_IF_UNREFERENCED
1366 EFI_COMPONENT_NAME_PROTOCOL gComponentName;
1367
1368 EFI_STATUS
1369 EFIAPI
1370 VirtioBlkGetDriverName (
1371 IN EFI_COMPONENT_NAME_PROTOCOL *This,
1372 IN CHAR8 *Language,
1373 OUT CHAR16 **DriverName
1374 )
1375 {
1376 return LookupUnicodeString2 (
1377 Language,
1378 This->SupportedLanguages,
1379 mDriverNameTable,
1380 DriverName,
1381 (BOOLEAN)(This == &gComponentName) // Iso639Language
1382 );
1383 }
1384
1385 EFI_STATUS
1386 EFIAPI
1387 VirtioBlkGetDeviceName (
1388 IN EFI_COMPONENT_NAME_PROTOCOL *This,
1389 IN EFI_HANDLE DeviceHandle,
1390 IN EFI_HANDLE ChildHandle,
1391 IN CHAR8 *Language,
1392 OUT CHAR16 **ControllerName
1393 )
1394 {
1395 return EFI_UNSUPPORTED;
1396 }
1397
1398 STATIC GLOBAL_REMOVE_IF_UNREFERENCED
1399 EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
1400 &VirtioBlkGetDriverName,
1401 &VirtioBlkGetDeviceName,
1402 "eng" // SupportedLanguages, ISO 639-2 language codes
1403 };
1404
1405 STATIC GLOBAL_REMOVE_IF_UNREFERENCED
1406 EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
1407 (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) &VirtioBlkGetDriverName,
1408 (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &VirtioBlkGetDeviceName,
1409 "en" // SupportedLanguages, RFC 4646 language codes
1410 };
1411
1412
1413 //
1414 // Entry point of this driver.
1415 //
1416 EFI_STATUS
1417 EFIAPI
1418 VirtioBlkEntryPoint (
1419 IN EFI_HANDLE ImageHandle,
1420 IN EFI_SYSTEM_TABLE *SystemTable
1421 )
1422 {
1423 return EfiLibInstallDriverBindingComponentName2 (
1424 ImageHandle,
1425 SystemTable,
1426 &gDriverBinding,
1427 ImageHandle,
1428 &gComponentName,
1429 &gComponentName2
1430 );
1431 }
1432