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