]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/VirtioBlkDxe/VirtioBlk.c
CryptoPkg: update openssl to ignore RVCT 3079
[mirror_edk2.git] / OvmfPkg / VirtioBlkDxe / VirtioBlk.c
CommitLineData
fd51d759 1/** @file\r
2\r
3 This driver produces Block I/O Protocol instances for virtio-blk devices.\r
4\r
5 The implementation is basic:\r
6\r
7 - No attach/detach (ie. removable media).\r
8\r
9 - Although the non-blocking interfaces of EFI_BLOCK_IO2_PROTOCOL could be a\r
10 good match for multiple in-flight virtio-blk requests, we stick to\r
11 synchronous requests and EFI_BLOCK_IO_PROTOCOL for now.\r
12\r
13 Copyright (C) 2012, Red Hat, Inc.\r
c4046161 14 Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>\r
fd51d759 15\r
16 This program and the accompanying materials are licensed and made available\r
17 under the terms and conditions of the BSD License which accompanies this\r
18 distribution. The full text of the license may be found at\r
19 http://opensource.org/licenses/bsd-license.php\r
20\r
21 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
22 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
23\r
24**/\r
25\r
6b28fe9e 26#include <IndustryStandard/VirtioBlk.h>\r
fd51d759 27#include <Library/BaseMemoryLib.h>\r
28#include <Library/DebugLib.h>\r
29#include <Library/MemoryAllocationLib.h>\r
30#include <Library/UefiBootServicesTableLib.h>\r
31#include <Library/UefiLib.h>\r
263559b8 32#include <Library/VirtioLib.h>\r
fd51d759 33\r
34#include "VirtioBlk.h"\r
35\r
fd51d759 36/**\r
37\r
38 Convenience macros to read and write region 0 IO space elements of the\r
56f65ed8 39 virtio-blk device, for configuration purposes.\r
fd51d759 40\r
41 The following macros make it possible to specify only the "core parameters"\r
42 for such accesses and to derive the rest. By the time VIRTIO_CFG_WRITE()\r
43 returns, the transaction will have been completed.\r
44\r
56f65ed8
OM
45 @param[in] Dev Pointer to the VBLK_DEV structure whose VirtIo space\r
46 we're accessing. Dev->VirtIo must be valid.\r
fd51d759 47\r
48 @param[in] Field A field name from VBLK_HDR, identifying the virtio-blk\r
49 configuration item to access.\r
50\r
51 @param[in] Value (VIRTIO_CFG_WRITE() only.) The value to write to the\r
52 selected configuration item.\r
53\r
54 @param[out] Pointer (VIRTIO_CFG_READ() only.) The object to receive the\r
55 value read from the configuration item. Its type must be\r
56 one of UINT8, UINT16, UINT32, UINT64.\r
57\r
58\r
21479c3c
LE
59 @return Status code returned by Virtio->WriteDevice() /\r
60 Virtio->ReadDevice().\r
fd51d759 61\r
62**/\r
63\r
ece77e40
OM
64#define VIRTIO_CFG_WRITE(Dev, Field, Value) ((Dev)->VirtIo->WriteDevice ( \\r
65 (Dev)->VirtIo, \\r
66 OFFSET_OF_VBLK (Field), \\r
67 SIZE_OF_VBLK (Field), \\r
68 (Value) \\r
fd51d759 69 ))\r
70\r
ece77e40
OM
71#define VIRTIO_CFG_READ(Dev, Field, Pointer) ((Dev)->VirtIo->ReadDevice ( \\r
72 (Dev)->VirtIo, \\r
73 OFFSET_OF_VBLK (Field), \\r
74 SIZE_OF_VBLK (Field), \\r
75 sizeof *(Pointer), \\r
76 (Pointer) \\r
fd51d759 77 ))\r
78\r
79\r
80//\r
81// UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol\r
82// Driver Writer's Guide for UEFI 2.3.1 v1.01,\r
83// 24.2 Block I/O Protocol Implementations\r
84//\r
85EFI_STATUS\r
86EFIAPI\r
87VirtioBlkReset (\r
88 IN EFI_BLOCK_IO_PROTOCOL *This,\r
89 IN BOOLEAN ExtendedVerification\r
90 )\r
91{\r
92 //\r
93 // If we managed to initialize and install the driver, then the device is\r
94 // working correctly.\r
95 //\r
96 return EFI_SUCCESS;\r
97}\r
98\r
99/**\r
100\r
101 Verify correctness of the read/write (not flush) request submitted to the\r
102 EFI_BLOCK_IO_PROTOCOL instance.\r
103\r
104 This function provides most verification steps described in:\r
105\r
106 UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O\r
107 Protocol,\r
108 - EFI_BLOCK_IO_PROTOCOL.ReadBlocks()\r
109 - EFI_BLOCK_IO_PROTOCOL.WriteBlocks()\r
110\r
111 Driver Writer's Guide for UEFI 2.3.1 v1.01,\r
112 - 24.2.2. ReadBlocks() and ReadBlocksEx() Implementation\r
113 - 24.2.3 WriteBlocks() and WriteBlockEx() Implementation\r
114\r
115 Request sizes are limited to 1 GB (checked). This is not a practical\r
116 limitation, just conformance to virtio-0.9.5, 2.3.2 Descriptor Table: "no\r
117 descriptor chain may be more than 2^32 bytes long in total".\r
118\r
119 Some Media characteristics are hardcoded in VirtioBlkInit() below (like\r
120 non-removable media, no restriction on buffer alignment etc); we rely on\r
121 those here without explicit mention.\r
122\r
123 @param[in] Media The EFI_BLOCK_IO_MEDIA characteristics for\r
124 this driver instance, extracted from the\r
125 underlying virtio-blk device at initialization\r
126 time. We validate the request against this set\r
127 of attributes.\r
128\r
129\r
130 @param[in] Lba Logical Block Address: number of logical\r
131 blocks to skip from the beginning of the\r
132 device.\r
133\r
134 @param[in] PositiveBufferSize Size of buffer to transfer, in bytes. The\r
135 caller is responsible to ensure this parameter\r
136 is positive.\r
137\r
138 @param[in] RequestIsWrite TRUE iff data transfer goes from guest to\r
139 device.\r
140\r
141\r
142 @@return Validation result to be forwarded outwards by\r
143 ReadBlocks() and WriteBlocks, as required by\r
144 the specs above.\r
145\r
146**/\r
147STATIC\r
148EFI_STATUS\r
149EFIAPI\r
150VerifyReadWriteRequest (\r
151 IN EFI_BLOCK_IO_MEDIA *Media,\r
152 IN EFI_LBA Lba,\r
153 IN UINTN PositiveBufferSize,\r
154 IN BOOLEAN RequestIsWrite\r
155 )\r
156{\r
157 UINTN BlockCount;\r
158\r
159 ASSERT (PositiveBufferSize > 0);\r
160\r
161 if (PositiveBufferSize > SIZE_1GB ||\r
162 PositiveBufferSize % Media->BlockSize > 0) {\r
163 return EFI_BAD_BUFFER_SIZE;\r
164 }\r
165 BlockCount = PositiveBufferSize / Media->BlockSize;\r
166\r
167 //\r
168 // Avoid unsigned wraparound on either side in the second comparison.\r
169 //\r
170 if (Lba > Media->LastBlock || BlockCount - 1 > Media->LastBlock - Lba) {\r
171 return EFI_INVALID_PARAMETER;\r
172 }\r
173\r
174 if (RequestIsWrite && Media->ReadOnly) {\r
175 return EFI_WRITE_PROTECTED;\r
176 }\r
177\r
178 return EFI_SUCCESS;\r
179}\r
180\r
181\r
fd51d759 182\r
183\r
184/**\r
185\r
186 Format a read / write / flush request as three consecutive virtio\r
187 descriptors, push them to the host, and poll for the response.\r
188\r
189 This is the main workhorse function. Two use cases are supported, read/write\r
190 and flush. The function may only be called after the request parameters have\r
191 been verified by\r
192 - specific checks in ReadBlocks() / WriteBlocks() / FlushBlocks(), and\r
193 - VerifyReadWriteRequest() (for read/write only).\r
194\r
195 Parameters handled commonly:\r
196\r
197 @param[in] Dev The virtio-blk device the request is targeted\r
198 at.\r
199\r
200 Flush request:\r
201\r
202 @param[in] Lba Must be zero.\r
203\r
204 @param[in] BufferSize Must be zero.\r
205\r
206 @param[in out] Buffer Ignored by the function.\r
207\r
208 @param[in] RequestIsWrite Must be TRUE.\r
209\r
210 Read/Write request:\r
211\r
212 @param[in] Lba Logical Block Address: number of logical blocks\r
213 to skip from the beginning of the device.\r
214\r
215 @param[in] BufferSize Size of buffer to transfer, in bytes. The caller\r
216 is responsible to ensure this parameter is\r
217 positive.\r
218\r
219 @param[in out] Buffer The guest side area to read data from the device\r
220 into, or write data to the device from.\r
221\r
222 @param[in] RequestIsWrite TRUE iff data transfer goes from guest to\r
223 device.\r
224\r
225 Return values are common to both use cases, and are appropriate to be\r
226 forwarded by the EFI_BLOCK_IO_PROTOCOL functions (ReadBlocks(),\r
227 WriteBlocks(), FlushBlocks()).\r
228\r
229\r
230 @retval EFI_SUCCESS Transfer complete.\r
231\r
56f65ed8 232 @retval EFI_DEVICE_ERROR Failed to notify host side via VirtIo write, or\r
fd51d759 233 unable to parse host response, or host response\r
234 is not VIRTIO_BLK_S_OK.\r
235\r
236**/\r
237\r
238STATIC\r
239EFI_STATUS\r
240EFIAPI\r
241SynchronousRequest (\r
242 IN VBLK_DEV *Dev,\r
243 IN EFI_LBA Lba,\r
244 IN UINTN BufferSize,\r
245 IN OUT volatile VOID *Buffer,\r
246 IN BOOLEAN RequestIsWrite\r
247 )\r
248{\r
249 UINT32 BlockSize;\r
250 volatile VIRTIO_BLK_REQ Request;\r
251 volatile UINT8 HostStatus;\r
e371e7e5 252 DESC_INDICES Indices;\r
fd51d759 253\r
254 BlockSize = Dev->BlockIoMedia.BlockSize;\r
255\r
256 //\r
257 // ensured by VirtioBlkInit()\r
258 //\r
259 ASSERT (BlockSize > 0);\r
260 ASSERT (BlockSize % 512 == 0);\r
261\r
262 //\r
263 // ensured by contract above, plus VerifyReadWriteRequest()\r
264 //\r
265 ASSERT (BufferSize % BlockSize == 0);\r
266\r
267 //\r
268 // Prepare virtio-blk request header, setting zero size for flush.\r
269 // IO Priority is homogeneously 0.\r
270 //\r
271 Request.Type = RequestIsWrite ?\r
272 (BufferSize == 0 ? VIRTIO_BLK_T_FLUSH : VIRTIO_BLK_T_OUT) :\r
273 VIRTIO_BLK_T_IN;\r
274 Request.IoPrio = 0;\r
389b5518 275 Request.Sector = MultU64x32(Lba, BlockSize / 512);\r
fd51d759 276\r
e371e7e5 277 VirtioPrepare (&Dev->Ring, &Indices);\r
fd51d759 278\r
279 //\r
280 // preset a host status for ourselves that we do not accept as success\r
281 //\r
282 HostStatus = VIRTIO_BLK_S_IOERR;\r
283\r
284 //\r
285 // ensured by VirtioBlkInit() -- this predicate, in combination with the\r
286 // lock-step progress, ensures we don't have to track free descriptors.\r
287 //\r
288 ASSERT (Dev->Ring.QueueSize >= 3);\r
289\r
fd51d759 290 //\r
291 // virtio-blk header in first desc\r
292 //\r
7fcacd6c 293 VirtioAppendDesc (&Dev->Ring, (UINTN) &Request, sizeof Request,\r
e371e7e5 294 VRING_DESC_F_NEXT, &Indices);\r
fd51d759 295\r
296 //\r
297 // data buffer for read/write in second desc\r
298 //\r
299 if (BufferSize > 0) {\r
300 //\r
301 // From virtio-0.9.5, 2.3.2 Descriptor Table:\r
302 // "no descriptor chain may be more than 2^32 bytes long in total".\r
303 //\r
304 // The predicate is ensured by the call contract above (for flush), or\r
305 // VerifyReadWriteRequest() (for read/write). It also implies that\r
306 // converting BufferSize to UINT32 will not truncate it.\r
307 //\r
308 ASSERT (BufferSize <= SIZE_1GB);\r
309\r
310 //\r
311 // VRING_DESC_F_WRITE is interpreted from the host's point of view.\r
312 //\r
7fcacd6c 313 VirtioAppendDesc (&Dev->Ring, (UINTN) Buffer, (UINT32) BufferSize,\r
fd51d759 314 VRING_DESC_F_NEXT | (RequestIsWrite ? 0 : VRING_DESC_F_WRITE),\r
e371e7e5 315 &Indices);\r
fd51d759 316 }\r
317\r
318 //\r
319 // host status in last (second or third) desc\r
320 //\r
7fcacd6c 321 VirtioAppendDesc (&Dev->Ring, (UINTN) &HostStatus, sizeof HostStatus,\r
e371e7e5 322 VRING_DESC_F_WRITE, &Indices);\r
fd51d759 323\r
324 //\r
e371e7e5 325 // virtio-blk's only virtqueue is #0, called "requestq" (see Appendix D).\r
fd51d759 326 //\r
8bc951a2
LE
327 if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices,\r
328 NULL) == EFI_SUCCESS &&\r
e371e7e5 329 HostStatus == VIRTIO_BLK_S_OK) {\r
fd51d759 330 return EFI_SUCCESS;\r
331 }\r
332\r
333 return EFI_DEVICE_ERROR;\r
334}\r
335\r
336\r
337/**\r
338\r
339 ReadBlocks() operation for virtio-blk.\r
340\r
341 See\r
342 - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O\r
343 Protocol, EFI_BLOCK_IO_PROTOCOL.ReadBlocks().\r
344 - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.2. ReadBlocks() and\r
345 ReadBlocksEx() Implementation.\r
346\r
347 Parameter checks and conformant return values are implemented in\r
348 VerifyReadWriteRequest() and SynchronousRequest().\r
349\r
350 A zero BufferSize doesn't seem to be prohibited, so do nothing in that case,\r
351 successfully.\r
352\r
353**/\r
354\r
355EFI_STATUS\r
356EFIAPI\r
357VirtioBlkReadBlocks (\r
358 IN EFI_BLOCK_IO_PROTOCOL *This,\r
359 IN UINT32 MediaId,\r
360 IN EFI_LBA Lba,\r
361 IN UINTN BufferSize,\r
362 OUT VOID *Buffer\r
363 )\r
364{\r
365 VBLK_DEV *Dev;\r
366 EFI_STATUS Status;\r
367\r
368 if (BufferSize == 0) {\r
369 return EFI_SUCCESS;\r
370 }\r
371\r
372 Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);\r
373 Status = VerifyReadWriteRequest (\r
374 &Dev->BlockIoMedia,\r
375 Lba,\r
376 BufferSize,\r
377 FALSE // RequestIsWrite\r
378 );\r
379 if (EFI_ERROR (Status)) {\r
380 return Status;\r
381 }\r
382\r
383 return SynchronousRequest (\r
384 Dev,\r
385 Lba,\r
386 BufferSize,\r
387 Buffer,\r
388 FALSE // RequestIsWrite\r
389 );\r
390}\r
391\r
392/**\r
393\r
394 WriteBlocks() operation for virtio-blk.\r
395\r
396 See\r
397 - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O\r
398 Protocol, EFI_BLOCK_IO_PROTOCOL.WriteBlocks().\r
399 - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.3 WriteBlocks() and\r
400 WriteBlockEx() Implementation.\r
401\r
402 Parameter checks and conformant return values are implemented in\r
403 VerifyReadWriteRequest() and SynchronousRequest().\r
404\r
405 A zero BufferSize doesn't seem to be prohibited, so do nothing in that case,\r
406 successfully.\r
407\r
408**/\r
409\r
410EFI_STATUS\r
411EFIAPI\r
412VirtioBlkWriteBlocks (\r
413 IN EFI_BLOCK_IO_PROTOCOL *This,\r
414 IN UINT32 MediaId,\r
415 IN EFI_LBA Lba,\r
416 IN UINTN BufferSize,\r
417 IN VOID *Buffer\r
418 )\r
419{\r
420 VBLK_DEV *Dev;\r
421 EFI_STATUS Status;\r
422\r
423 if (BufferSize == 0) {\r
424 return EFI_SUCCESS;\r
425 }\r
426\r
427 Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);\r
428 Status = VerifyReadWriteRequest (\r
429 &Dev->BlockIoMedia,\r
430 Lba,\r
431 BufferSize,\r
432 TRUE // RequestIsWrite\r
433 );\r
434 if (EFI_ERROR (Status)) {\r
435 return Status;\r
436 }\r
437\r
438 return SynchronousRequest (\r
439 Dev,\r
440 Lba,\r
441 BufferSize,\r
442 Buffer,\r
443 TRUE // RequestIsWrite\r
444 );\r
445}\r
446\r
447\r
448/**\r
449\r
450 FlushBlocks() operation for virtio-blk.\r
451\r
452 See\r
453 - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O\r
454 Protocol, EFI_BLOCK_IO_PROTOCOL.FlushBlocks().\r
455 - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.4 FlushBlocks() and\r
456 FlushBlocksEx() Implementation.\r
457\r
458 If the underlying virtio-blk device doesn't support flushing (ie.\r
459 write-caching), then this function should not be called by higher layers,\r
460 according to EFI_BLOCK_IO_MEDIA characteristics set in VirtioBlkInit().\r
461 Should they do nonetheless, we do nothing, successfully.\r
462\r
463**/\r
464\r
465EFI_STATUS\r
466EFIAPI\r
467VirtioBlkFlushBlocks (\r
468 IN EFI_BLOCK_IO_PROTOCOL *This\r
469 )\r
470{\r
471 VBLK_DEV *Dev;\r
472\r
473 Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);\r
474 return Dev->BlockIoMedia.WriteCaching ?\r
475 SynchronousRequest (\r
476 Dev,\r
477 0, // Lba\r
478 0, // BufferSize\r
479 NULL, // Buffer\r
480 TRUE // RequestIsWrite\r
481 ) :\r
482 EFI_SUCCESS;\r
483}\r
484\r
485\r
486/**\r
487\r
488 Device probe function for this driver.\r
489\r
490 The DXE core calls this function for any given device in order to see if the\r
491 driver can drive the device.\r
492\r
493 Specs relevant in the general sense:\r
494\r
495 - UEFI Spec 2.3.1 + Errata C:\r
496 - 6.3 Protocol Handler Services -- for accessing the underlying device\r
497 - 10.1 EFI Driver Binding Protocol -- for exporting ourselves\r
498\r
499 - Driver Writer's Guide for UEFI 2.3.1 v1.01:\r
500 - 5.1.3.4 OpenProtocol() and CloseProtocol() -- for accessing the\r
501 underlying device\r
502 - 9 Driver Binding Protocol -- for exporting ourselves\r
503\r
fd51d759 504 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object\r
505 incorporating this driver (independently of\r
506 any device).\r
507\r
508 @param[in] DeviceHandle The device to probe.\r
509\r
510 @param[in] RemainingDevicePath Relevant only for bus drivers, ignored.\r
511\r
512\r
513 @retval EFI_SUCCESS The driver supports the device being probed.\r
514\r
56f65ed8 515 @retval EFI_UNSUPPORTED Based on virtio-blk discovery, we do not support\r
fd51d759 516 the device.\r
517\r
518 @return Error codes from the OpenProtocol() boot service or\r
56f65ed8 519 the VirtIo protocol.\r
fd51d759 520\r
521**/\r
522\r
523EFI_STATUS\r
524EFIAPI\r
525VirtioBlkDriverBindingSupported (\r
526 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
527 IN EFI_HANDLE DeviceHandle,\r
528 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
529 )\r
530{\r
531 EFI_STATUS Status;\r
56f65ed8 532 VIRTIO_DEVICE_PROTOCOL *VirtIo;\r
fd51d759 533\r
534 //\r
56f65ed8 535 // Attempt to open the device with the VirtIo set of interfaces. On success,\r
21479c3c
LE
536 // the protocol is "instantiated" for the VirtIo device. Covers duplicate\r
537 // open attempts (EFI_ALREADY_STARTED).\r
fd51d759 538 //\r
539 Status = gBS->OpenProtocol (\r
540 DeviceHandle, // candidate device\r
56f65ed8
OM
541 &gVirtioDeviceProtocolGuid, // for generic VirtIo access\r
542 (VOID **)&VirtIo, // handle to instantiate\r
fd51d759 543 This->DriverBindingHandle, // requestor driver identity\r
544 DeviceHandle, // ControllerHandle, according to\r
545 // the UEFI Driver Model\r
56f65ed8 546 EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive VirtIo access to\r
fd51d759 547 // the device; to be released\r
548 );\r
549 if (EFI_ERROR (Status)) {\r
550 return Status;\r
551 }\r
552\r
56f65ed8
OM
553 if (VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_BLOCK_DEVICE) {\r
554 Status = EFI_UNSUPPORTED;\r
fd51d759 555 }\r
556\r
557 //\r
56f65ed8 558 // We needed VirtIo access only transitorily, to see whether we support the\r
fd51d759 559 // device or not.\r
560 //\r
56f65ed8 561 gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,\r
fd51d759 562 This->DriverBindingHandle, DeviceHandle);\r
563 return Status;\r
564}\r
565\r
566\r
fd51d759 567/**\r
568\r
569 Set up all BlockIo and virtio-blk aspects of this driver for the specified\r
570 device.\r
571\r
572 @param[in out] Dev The driver instance to configure. The caller is\r
56f65ed8
OM
573 responsible for Dev->VirtIo's validity (ie. working IO\r
574 access to the underlying virtio-blk device).\r
fd51d759 575\r
576 @retval EFI_SUCCESS Setup complete.\r
577\r
578 @retval EFI_UNSUPPORTED The driver is unable to work with the virtio ring or\r
579 virtio-blk attributes the host provides.\r
580\r
581 @return Error codes from VirtioRingInit() or\r
582 VIRTIO_CFG_READ() / VIRTIO_CFG_WRITE().\r
583\r
584**/\r
585\r
586STATIC\r
587EFI_STATUS\r
588EFIAPI\r
589VirtioBlkInit (\r
590 IN OUT VBLK_DEV *Dev\r
591 )\r
592{\r
593 UINT8 NextDevStat;\r
594 EFI_STATUS Status;\r
595\r
bc8fde6f 596 UINT64 Features;\r
fd51d759 597 UINT64 NumSectors;\r
598 UINT32 BlockSize;\r
6476804e
LE
599 UINT8 PhysicalBlockExp;\r
600 UINT8 AlignmentOffset;\r
601 UINT32 OptIoSize;\r
fd51d759 602 UINT16 QueueSize;\r
603\r
6476804e
LE
604 PhysicalBlockExp = 0;\r
605 AlignmentOffset = 0;\r
606 OptIoSize = 0;\r
607\r
fd51d759 608 //\r
609 // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.\r
610 //\r
611 NextDevStat = 0; // step 1 -- reset device\r
56f65ed8 612 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);\r
fd51d759 613 if (EFI_ERROR (Status)) {\r
614 goto Failed;\r
615 }\r
616\r
617 NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence\r
56f65ed8 618 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);\r
fd51d759 619 if (EFI_ERROR (Status)) {\r
620 goto Failed;\r
621 }\r
622\r
623 NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it\r
56f65ed8
OM
624 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);\r
625 if (EFI_ERROR (Status)) {\r
626 goto Failed;\r
627 }\r
628\r
629 //\r
630 // Set Page Size - MMIO VirtIo Specific\r
631 //\r
632 Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);\r
fd51d759 633 if (EFI_ERROR (Status)) {\r
634 goto Failed;\r
635 }\r
636\r
637 //\r
638 // step 4a -- retrieve and validate features\r
639 //\r
56f65ed8 640 Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features);\r
fd51d759 641 if (EFI_ERROR (Status)) {\r
642 goto Failed;\r
643 }\r
56f65ed8
OM
644\r
645 Status = VIRTIO_CFG_READ (Dev, Capacity, &NumSectors);\r
fd51d759 646 if (EFI_ERROR (Status)) {\r
647 goto Failed;\r
648 }\r
649 if (NumSectors == 0) {\r
650 Status = EFI_UNSUPPORTED;\r
651 goto Failed;\r
652 }\r
653\r
654 if (Features & VIRTIO_BLK_F_BLK_SIZE) {\r
56f65ed8 655 Status = VIRTIO_CFG_READ (Dev, BlkSize, &BlockSize);\r
fd51d759 656 if (EFI_ERROR (Status)) {\r
657 goto Failed;\r
658 }\r
659 if (BlockSize == 0 || BlockSize % 512 != 0 ||\r
2f03f796 660 ModU64x32 (NumSectors, BlockSize / 512) != 0) {\r
fd51d759 661 //\r
662 // We can only handle a logical block consisting of whole sectors,\r
663 // and only a disk composed of whole logical blocks.\r
664 //\r
665 Status = EFI_UNSUPPORTED;\r
666 goto Failed;\r
667 }\r
668 }\r
669 else {\r
670 BlockSize = 512;\r
671 }\r
672\r
6476804e
LE
673 if (Features & VIRTIO_BLK_F_TOPOLOGY) {\r
674 Status = VIRTIO_CFG_READ (Dev, Topology.PhysicalBlockExp,\r
675 &PhysicalBlockExp);\r
676 if (EFI_ERROR (Status)) {\r
677 goto Failed;\r
678 }\r
679 if (PhysicalBlockExp >= 32) {\r
680 Status = EFI_UNSUPPORTED;\r
681 goto Failed;\r
682 }\r
683\r
684 Status = VIRTIO_CFG_READ (Dev, Topology.AlignmentOffset, &AlignmentOffset);\r
685 if (EFI_ERROR (Status)) {\r
686 goto Failed;\r
687 }\r
688\r
689 Status = VIRTIO_CFG_READ (Dev, Topology.OptIoSize, &OptIoSize);\r
690 if (EFI_ERROR (Status)) {\r
691 goto Failed;\r
692 }\r
693 }\r
694\r
cbad8e4c
LE
695 Features &= VIRTIO_BLK_F_BLK_SIZE | VIRTIO_BLK_F_TOPOLOGY | VIRTIO_BLK_F_RO |\r
696 VIRTIO_BLK_F_FLUSH | VIRTIO_F_VERSION_1;\r
697\r
698 //\r
699 // In virtio-1.0, feature negotiation is expected to complete before queue\r
700 // discovery, and the device can also reject the selected set of features.\r
701 //\r
702 if (Dev->VirtIo->Revision >= VIRTIO_SPEC_REVISION (1, 0, 0)) {\r
703 Status = Virtio10WriteFeatures (Dev->VirtIo, Features, &NextDevStat);\r
704 if (EFI_ERROR (Status)) {\r
705 goto Failed;\r
706 }\r
707 }\r
708\r
fd51d759 709 //\r
710 // step 4b -- allocate virtqueue\r
711 //\r
56f65ed8 712 Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, 0);\r
fd51d759 713 if (EFI_ERROR (Status)) {\r
714 goto Failed;\r
715 }\r
56f65ed8 716 Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);\r
fd51d759 717 if (EFI_ERROR (Status)) {\r
718 goto Failed;\r
719 }\r
720 if (QueueSize < 3) { // SynchronousRequest() uses at most three descriptors\r
721 Status = EFI_UNSUPPORTED;\r
722 goto Failed;\r
723 }\r
724\r
725 Status = VirtioRingInit (QueueSize, &Dev->Ring);\r
726 if (EFI_ERROR (Status)) {\r
727 goto Failed;\r
728 }\r
729\r
730 //\r
56f65ed8
OM
731 // Additional steps for MMIO: align the queue appropriately, and set the\r
732 // size. If anything fails from here on, we must release the ring resources.\r
fd51d759 733 //\r
56f65ed8 734 Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);\r
fd51d759 735 if (EFI_ERROR (Status)) {\r
736 goto ReleaseQueue;\r
737 }\r
738\r
56f65ed8
OM
739 Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);\r
740 if (EFI_ERROR (Status)) {\r
741 goto ReleaseQueue;\r
742 }\r
743\r
744 //\r
745 // step 4c -- Report GPFN (guest-physical frame number) of queue.\r
746 //\r
07af4eee 747 Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);\r
56f65ed8
OM
748 if (EFI_ERROR (Status)) {\r
749 goto ReleaseQueue;\r
750 }\r
751\r
752\r
fd51d759 753 //\r
0c2a4860 754 // step 5 -- Report understood features.\r
fd51d759 755 //\r
cbad8e4c
LE
756 if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {\r
757 Features &= ~(UINT64)VIRTIO_F_VERSION_1;\r
758 Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);\r
759 if (EFI_ERROR (Status)) {\r
760 goto ReleaseQueue;\r
761 }\r
fd51d759 762 }\r
763\r
764 //\r
765 // step 6 -- initialization complete\r
766 //\r
767 NextDevStat |= VSTAT_DRIVER_OK;\r
56f65ed8 768 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);\r
fd51d759 769 if (EFI_ERROR (Status)) {\r
770 goto ReleaseQueue;\r
771 }\r
772\r
773 //\r
6476804e
LE
774 // Populate the exported interface's attributes; see UEFI spec v2.4, 12.9 EFI\r
775 // Block I/O Protocol.\r
fd51d759 776 //\r
777 Dev->BlockIo.Revision = 0;\r
778 Dev->BlockIo.Media = &Dev->BlockIoMedia;\r
779 Dev->BlockIo.Reset = &VirtioBlkReset;\r
780 Dev->BlockIo.ReadBlocks = &VirtioBlkReadBlocks;\r
781 Dev->BlockIo.WriteBlocks = &VirtioBlkWriteBlocks;\r
782 Dev->BlockIo.FlushBlocks = &VirtioBlkFlushBlocks;\r
783 Dev->BlockIoMedia.MediaId = 0;\r
784 Dev->BlockIoMedia.RemovableMedia = FALSE;\r
785 Dev->BlockIoMedia.MediaPresent = TRUE;\r
786 Dev->BlockIoMedia.LogicalPartition = FALSE;\r
c4046161
JJ
787 Dev->BlockIoMedia.ReadOnly = (BOOLEAN) ((Features & VIRTIO_BLK_F_RO) != 0);\r
788 Dev->BlockIoMedia.WriteCaching = (BOOLEAN) ((Features & VIRTIO_BLK_F_FLUSH) != 0);\r
fd51d759 789 Dev->BlockIoMedia.BlockSize = BlockSize;\r
790 Dev->BlockIoMedia.IoAlign = 0;\r
2f03f796 791 Dev->BlockIoMedia.LastBlock = DivU64x32 (NumSectors,\r
792 BlockSize / 512) - 1;\r
6476804e 793\r
957914ee
LE
794 DEBUG ((DEBUG_INFO, "%a: LbaSize=0x%x[B] NumBlocks=0x%Lx[Lba]\n",\r
795 __FUNCTION__, Dev->BlockIoMedia.BlockSize,\r
796 Dev->BlockIoMedia.LastBlock + 1));\r
797\r
6476804e
LE
798 if (Features & VIRTIO_BLK_F_TOPOLOGY) {\r
799 Dev->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;\r
800\r
801 Dev->BlockIoMedia.LowestAlignedLba = AlignmentOffset;\r
802 Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock = 1u << PhysicalBlockExp;\r
803 Dev->BlockIoMedia.OptimalTransferLengthGranularity = OptIoSize;\r
957914ee
LE
804\r
805 DEBUG ((DEBUG_INFO, "%a: FirstAligned=0x%Lx[Lba] PhysBlkSize=0x%x[Lba]\n",\r
806 __FUNCTION__, Dev->BlockIoMedia.LowestAlignedLba,\r
807 Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock));\r
808 DEBUG ((DEBUG_INFO, "%a: OptimalTransferLengthGranularity=0x%x[Lba]\n",\r
809 __FUNCTION__, Dev->BlockIoMedia.OptimalTransferLengthGranularity));\r
6476804e 810 }\r
fd51d759 811 return EFI_SUCCESS;\r
812\r
813ReleaseQueue:\r
814 VirtioRingUninit (&Dev->Ring);\r
815\r
816Failed:\r
817 //\r
818 // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device\r
56f65ed8 819 // Status. VirtIo access failure here should not mask the original error.\r
fd51d759 820 //\r
821 NextDevStat |= VSTAT_FAILED;\r
56f65ed8 822 Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);\r
fd51d759 823\r
824 return Status; // reached only via Failed above\r
825}\r
826\r
827\r
828/**\r
829\r
830 Uninitialize the internals of a virtio-blk device that has been successfully\r
831 set up with VirtioBlkInit().\r
832\r
833 @param[in out] Dev The device to clean up.\r
834\r
835**/\r
836\r
837STATIC\r
838VOID\r
839EFIAPI\r
840VirtioBlkUninit (\r
841 IN OUT VBLK_DEV *Dev\r
842 )\r
843{\r
844 //\r
845 // Reset the virtual device -- see virtio-0.9.5, 2.2.2.1 Device Status. When\r
846 // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from\r
847 // the old comms area.\r
848 //\r
56f65ed8 849 Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);\r
fd51d759 850\r
851 VirtioRingUninit (&Dev->Ring);\r
852\r
853 SetMem (&Dev->BlockIo, sizeof Dev->BlockIo, 0x00);\r
854 SetMem (&Dev->BlockIoMedia, sizeof Dev->BlockIoMedia, 0x00);\r
855}\r
856\r
857\r
fcb636ea
LE
858/**\r
859\r
860 Event notification function enqueued by ExitBootServices().\r
861\r
862 @param[in] Event Event whose notification function is being invoked.\r
863\r
864 @param[in] Context Pointer to the VBLK_DEV structure.\r
865\r
866**/\r
867\r
868STATIC\r
869VOID\r
870EFIAPI\r
871VirtioBlkExitBoot (\r
872 IN EFI_EVENT Event,\r
873 IN VOID *Context\r
874 )\r
875{\r
876 VBLK_DEV *Dev;\r
877\r
878 //\r
879 // Reset the device. This causes the hypervisor to forget about the virtio\r
880 // ring.\r
881 //\r
882 // We allocated said ring in EfiBootServicesData type memory, and code\r
883 // executing after ExitBootServices() is permitted to overwrite it.\r
884 //\r
885 Dev = Context;\r
886 Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);\r
887}\r
888\r
fd51d759 889/**\r
890\r
891 After we've pronounced support for a specific device in\r
892 DriverBindingSupported(), we start managing said device (passed in by the\r
893 Driver Exeuction Environment) with the following service.\r
894\r
895 See DriverBindingSupported() for specification references.\r
896\r
897 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object\r
898 incorporating this driver (independently of\r
899 any device).\r
900\r
901 @param[in] DeviceHandle The supported device to drive.\r
902\r
903 @param[in] RemainingDevicePath Relevant only for bus drivers, ignored.\r
904\r
905\r
906 @retval EFI_SUCCESS Driver instance has been created and\r
56f65ed8 907 initialized for the virtio-blk device, it\r
fd51d759 908 is now accessibla via EFI_BLOCK_IO_PROTOCOL.\r
909\r
910 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.\r
911\r
912 @return Error codes from the OpenProtocol() boot\r
56f65ed8 913 service, the VirtIo protocol, VirtioBlkInit(),\r
fd51d759 914 or the InstallProtocolInterface() boot service.\r
915\r
916**/\r
917\r
918EFI_STATUS\r
919EFIAPI\r
920VirtioBlkDriverBindingStart (\r
921 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
922 IN EFI_HANDLE DeviceHandle,\r
923 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
924 )\r
925{\r
926 VBLK_DEV *Dev;\r
927 EFI_STATUS Status;\r
928\r
929 Dev = (VBLK_DEV *) AllocateZeroPool (sizeof *Dev);\r
930 if (Dev == NULL) {\r
931 return EFI_OUT_OF_RESOURCES;\r
932 }\r
933\r
56f65ed8
OM
934 Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,\r
935 (VOID **)&Dev->VirtIo, This->DriverBindingHandle,\r
fd51d759 936 DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);\r
937 if (EFI_ERROR (Status)) {\r
938 goto FreeVirtioBlk;\r
939 }\r
940\r
941 //\r
56f65ed8 942 // VirtIo access granted, configure virtio-blk device.\r
fd51d759 943 //\r
944 Status = VirtioBlkInit (Dev);\r
945 if (EFI_ERROR (Status)) {\r
56f65ed8 946 goto CloseVirtIo;\r
fd51d759 947 }\r
948\r
fcb636ea
LE
949 Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,\r
950 &VirtioBlkExitBoot, Dev, &Dev->ExitBoot);\r
951 if (EFI_ERROR (Status)) {\r
952 goto UninitDev;\r
953 }\r
954\r
fd51d759 955 //\r
956 // Setup complete, attempt to export the driver instance's BlockIo interface.\r
957 //\r
958 Dev->Signature = VBLK_SIG;\r
959 Status = gBS->InstallProtocolInterface (&DeviceHandle,\r
960 &gEfiBlockIoProtocolGuid, EFI_NATIVE_INTERFACE,\r
961 &Dev->BlockIo);\r
962 if (EFI_ERROR (Status)) {\r
fcb636ea 963 goto CloseExitBoot;\r
fd51d759 964 }\r
965\r
966 return EFI_SUCCESS;\r
967\r
fcb636ea
LE
968CloseExitBoot:\r
969 gBS->CloseEvent (Dev->ExitBoot);\r
970\r
fd51d759 971UninitDev:\r
972 VirtioBlkUninit (Dev);\r
973\r
56f65ed8
OM
974CloseVirtIo:\r
975 gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,\r
fd51d759 976 This->DriverBindingHandle, DeviceHandle);\r
977\r
978FreeVirtioBlk:\r
979 FreePool (Dev);\r
980\r
981 return Status;\r
982}\r
983\r
984\r
985/**\r
986\r
987 Stop driving a virtio-blk device and remove its BlockIo interface.\r
988\r
989 This function replays the success path of DriverBindingStart() in reverse.\r
990 The host side virtio-blk device is reset, so that the OS boot loader or the\r
991 OS may reinitialize it.\r
992\r
993 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object\r
994 incorporating this driver (independently of any\r
995 device).\r
996\r
997 @param[in] DeviceHandle Stop driving this device.\r
998\r
999 @param[in] NumberOfChildren Since this function belongs to a device driver\r
1000 only (as opposed to a bus driver), the caller\r
1001 environment sets NumberOfChildren to zero, and\r
1002 we ignore it.\r
1003\r
1004 @param[in] ChildHandleBuffer Ignored (corresponding to NumberOfChildren).\r
1005\r
1006**/\r
1007\r
1008EFI_STATUS\r
1009EFIAPI\r
1010VirtioBlkDriverBindingStop (\r
1011 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1012 IN EFI_HANDLE DeviceHandle,\r
1013 IN UINTN NumberOfChildren,\r
1014 IN EFI_HANDLE *ChildHandleBuffer\r
1015 )\r
1016{\r
c8c2e4d6 1017 EFI_STATUS Status;\r
1018 EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
1019 VBLK_DEV *Dev;\r
fd51d759 1020\r
c8c2e4d6 1021 Status = gBS->OpenProtocol (\r
1022 DeviceHandle, // candidate device\r
1023 &gEfiBlockIoProtocolGuid, // retrieve the BlockIo iface\r
1024 (VOID **)&BlockIo, // target pointer\r
1025 This->DriverBindingHandle, // requestor driver identity\r
1026 DeviceHandle, // requesting lookup for dev.\r
1027 EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added\r
1028 );\r
1029 if (EFI_ERROR (Status)) {\r
1030 return Status;\r
1031 }\r
1032\r
1033 Dev = VIRTIO_BLK_FROM_BLOCK_IO (BlockIo);\r
fd51d759 1034\r
1035 //\r
c8c2e4d6 1036 // Handle Stop() requests for in-use driver instances gracefully.\r
fd51d759 1037 //\r
1038 Status = gBS->UninstallProtocolInterface (DeviceHandle,\r
1039 &gEfiBlockIoProtocolGuid, &Dev->BlockIo);\r
c8c2e4d6 1040 if (EFI_ERROR (Status)) {\r
1041 return Status;\r
1042 }\r
fd51d759 1043\r
fcb636ea
LE
1044 gBS->CloseEvent (Dev->ExitBoot);\r
1045\r
fd51d759 1046 VirtioBlkUninit (Dev);\r
1047\r
56f65ed8 1048 gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,\r
fd51d759 1049 This->DriverBindingHandle, DeviceHandle);\r
1050\r
1051 FreePool (Dev);\r
1052\r
1053 return EFI_SUCCESS;\r
1054}\r
1055\r
1056\r
1057//\r
1058// The static object that groups the Supported() (ie. probe), Start() and\r
1059// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata\r
1060// C, 10.1 EFI Driver Binding Protocol.\r
1061//\r
1062STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {\r
1063 &VirtioBlkDriverBindingSupported,\r
1064 &VirtioBlkDriverBindingStart,\r
1065 &VirtioBlkDriverBindingStop,\r
1066 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers\r
1067 NULL, // ImageHandle, to be overwritten by\r
1068 // EfiLibInstallDriverBindingComponentName2() in VirtioBlkEntryPoint()\r
1069 NULL // DriverBindingHandle, ditto\r
1070};\r
1071\r
1072\r
1073//\r
1074// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and\r
1075// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name\r
1076// in English, for display on standard console devices. This is recommended for\r
1077// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's\r
1078// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.\r
1079//\r
1080// Device type names ("Virtio Block Device") are not formatted because the\r
1081// driver supports only that device type. Therefore the driver name suffices\r
1082// for unambiguous identification.\r
1083//\r
1084\r
9de0355b 1085STATIC\r
fd51d759 1086EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {\r
1087 { "eng;en", L"Virtio Block Driver" },\r
1088 { NULL, NULL }\r
1089};\r
1090\r
9de0355b 1091STATIC\r
fd51d759 1092EFI_COMPONENT_NAME_PROTOCOL gComponentName;\r
1093\r
1094EFI_STATUS\r
1095EFIAPI\r
1096VirtioBlkGetDriverName (\r
1097 IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
1098 IN CHAR8 *Language,\r
1099 OUT CHAR16 **DriverName\r
1100 )\r
1101{\r
1102 return LookupUnicodeString2 (\r
1103 Language,\r
1104 This->SupportedLanguages,\r
1105 mDriverNameTable,\r
1106 DriverName,\r
1107 (BOOLEAN)(This == &gComponentName) // Iso639Language\r
1108 );\r
1109}\r
1110\r
1111EFI_STATUS\r
1112EFIAPI\r
1113VirtioBlkGetDeviceName (\r
1114 IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
1115 IN EFI_HANDLE DeviceHandle,\r
1116 IN EFI_HANDLE ChildHandle,\r
1117 IN CHAR8 *Language,\r
1118 OUT CHAR16 **ControllerName\r
1119 )\r
1120{\r
1121 return EFI_UNSUPPORTED;\r
1122}\r
1123\r
9de0355b 1124STATIC\r
fd51d759 1125EFI_COMPONENT_NAME_PROTOCOL gComponentName = {\r
1126 &VirtioBlkGetDriverName,\r
1127 &VirtioBlkGetDeviceName,\r
1128 "eng" // SupportedLanguages, ISO 639-2 language codes\r
1129};\r
1130\r
9de0355b 1131STATIC\r
fd51d759 1132EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {\r
1133 (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) &VirtioBlkGetDriverName,\r
1134 (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &VirtioBlkGetDeviceName,\r
1135 "en" // SupportedLanguages, RFC 4646 language codes\r
1136};\r
1137\r
1138\r
1139//\r
1140// Entry point of this driver.\r
1141//\r
1142EFI_STATUS\r
1143EFIAPI\r
1144VirtioBlkEntryPoint (\r
1145 IN EFI_HANDLE ImageHandle,\r
1146 IN EFI_SYSTEM_TABLE *SystemTable\r
1147 )\r
1148{\r
1149 return EfiLibInstallDriverBindingComponentName2 (\r
1150 ImageHandle,\r
1151 SystemTable,\r
1152 &gDriverBinding,\r
1153 ImageHandle,\r
1154 &gComponentName,\r
1155 &gComponentName2\r
1156 );\r
1157}\r
1158\r