TianoCore EDK2 master
Loading...
Searching...
No Matches
BlockFront.c
Go to the documentation of this file.
1
11#include <Library/PrintLib.h>
12#include <Library/DebugLib.h>
13
14#include "BlockFront.h"
15
16#include <IndustryStandard/Xen/io/protocols.h>
17#include <IndustryStandard/Xen/io/xenbus.h>
18
35XENSTORE_STATUS
37 IN XENBUS_PROTOCOL *This,
38 IN CONST CHAR8 *Node,
39 IN BOOLEAN FromBackend,
40 OUT UINT64 *ValuePtr
41 )
42{
43 XENSTORE_STATUS Status;
44 CHAR8 *Ptr;
45
46 if (!FromBackend) {
47 Status = This->XsRead (This, XST_NIL, Node, (VOID **)&Ptr);
48 } else {
49 Status = This->XsBackendRead (This, XST_NIL, Node, (VOID **)&Ptr);
50 }
51
52 if (Status != XENSTORE_STATUS_SUCCESS) {
53 return Status;
54 }
55
56 // AsciiStrDecimalToUint64 will ASSERT if Ptr overflow UINT64.
57 *ValuePtr = AsciiStrDecimalToUint64 (Ptr);
58 FreePool (Ptr);
59 return Status;
60}
61
68VOID
71 )
72{
73 XENBUS_PROTOCOL *XenBusIo = Dev->XenBusIo;
74
75 if (Dev->RingRef != 0) {
76 XenBusIo->GrantEndAccess (XenBusIo, Dev->RingRef);
77 }
78
79 if (Dev->Ring.sring != NULL) {
80 FreePages (Dev->Ring.sring, 1);
81 }
82
83 if (Dev->EventChannel != 0) {
84 XenBusIo->EventChannelClose (XenBusIo, Dev->EventChannel);
85 }
86
87 FreePool (Dev);
88}
89
100STATIC
101XENSTORE_STATUS
104 IN XenbusState ExpectedState,
105 OUT XenbusState *LastStatePtr OPTIONAL
106 )
107{
108 XENBUS_PROTOCOL *XenBusIo = Dev->XenBusIo;
109 XenbusState State;
110 UINT64 Value;
111 XENSTORE_STATUS Status = XENSTORE_STATUS_SUCCESS;
112
113 while (TRUE) {
114 Status = XenBusReadUint64 (XenBusIo, "state", TRUE, &Value);
115 if (Status != XENSTORE_STATUS_SUCCESS) {
116 return Status;
117 }
118
119 if (Value > XenbusStateReconfigured) {
120 //
121 // Value is not a State value.
122 //
123 return XENSTORE_STATUS_EIO;
124 }
125
126 State = Value;
127 if (State == ExpectedState) {
128 break;
129 } else if (State > ExpectedState) {
130 Status = XENSTORE_STATUS_FAIL;
131 break;
132 }
133
134 DEBUG ((
135 DEBUG_INFO,
136 "XenPvBlk: waiting backend state %d, current: %d\n",
137 ExpectedState,
138 State
139 ));
140 XenBusIo->WaitForWatch (XenBusIo, Dev->StateWatchToken);
141 }
142
143 if (LastStatePtr != NULL) {
144 *LastStatePtr = State;
145 }
146
147 return Status;
148}
149
151XenPvBlockFrontInitialization (
152 IN XENBUS_PROTOCOL *XenBusIo,
153 IN CONST CHAR8 *NodeName,
155 )
156{
158 CHAR8 *DeviceType;
159 blkif_sring_t *SharedRing;
160 XENSTORE_STATUS Status;
162 XenbusState State;
163 UINT64 Value;
164 CHAR8 *Params;
165
166 ASSERT (NodeName != NULL);
167
169 if (Dev == NULL) {
170 return EFI_OUT_OF_RESOURCES;
171 }
172
173 Dev->Signature = XEN_BLOCK_FRONT_SIGNATURE;
174 Dev->NodeName = NodeName;
175 Dev->XenBusIo = XenBusIo;
176 Dev->DeviceId = XenBusIo->DeviceId;
177
178 XenBusIo->XsRead (XenBusIo, XST_NIL, "device-type", (VOID **)&DeviceType);
179 if (AsciiStrCmp (DeviceType, "cdrom") == 0) {
180 Dev->MediaInfo.CdRom = TRUE;
181 } else {
182 Dev->MediaInfo.CdRom = FALSE;
183 }
184
185 FreePool (DeviceType);
186
187 if (Dev->MediaInfo.CdRom) {
188 Status = XenBusIo->XsBackendRead (XenBusIo, XST_NIL, "params", (VOID **)&Params);
189 if (Status != XENSTORE_STATUS_SUCCESS) {
190 DEBUG ((DEBUG_ERROR, "%a: Failed to read params (%d)\n", __func__, Status));
191 goto Error;
192 }
193
194 if ((AsciiStrLen (Params) == 0) || (AsciiStrCmp (Params, "aio:") == 0)) {
195 FreePool (Params);
196 DEBUG ((DEBUG_INFO, "%a: Empty cdrom\n", __func__));
197 goto Error;
198 }
199
200 FreePool (Params);
201 }
202
203 Status = XenBusReadUint64 (XenBusIo, "backend-id", FALSE, &Value);
204 if ((Status != XENSTORE_STATUS_SUCCESS) || (Value > MAX_UINT16)) {
205 DEBUG ((
206 DEBUG_ERROR,
207 "XenPvBlk: Failed to get backend-id (%d)\n",
208 Status
209 ));
210 goto Error;
211 }
212
213 Dev->DomainId = (domid_t)Value;
214 XenBusIo->EventChannelAllocate (XenBusIo, Dev->DomainId, &Dev->EventChannel);
215
216 SharedRing = (blkif_sring_t *)AllocatePages (1);
217 SHARED_RING_INIT (SharedRing);
218 FRONT_RING_INIT (&Dev->Ring, SharedRing, EFI_PAGE_SIZE);
219 XenBusIo->GrantAccess (
220 XenBusIo,
221 Dev->DomainId,
222 (INTN)SharedRing >> EFI_PAGE_SHIFT,
223 FALSE,
224 &Dev->RingRef
225 );
226
227Again:
228 Status = XenBusIo->XsTransactionStart (XenBusIo, &Transaction);
229 if (Status != XENSTORE_STATUS_SUCCESS) {
230 DEBUG ((DEBUG_WARN, "XenPvBlk: Failed to start transaction, %d\n", Status));
231 goto Error;
232 }
233
234 Status = XenBusIo->XsPrintf (
235 XenBusIo,
237 NodeName,
238 "ring-ref",
239 "%d",
240 Dev->RingRef
241 );
242 if (Status != XENSTORE_STATUS_SUCCESS) {
243 DEBUG ((DEBUG_ERROR, "XenPvBlk: Failed to write ring-ref.\n"));
244 goto AbortTransaction;
245 }
246
247 Status = XenBusIo->XsPrintf (
248 XenBusIo,
250 NodeName,
251 "event-channel",
252 "%d",
253 Dev->EventChannel
254 );
255 if (Status != XENSTORE_STATUS_SUCCESS) {
256 DEBUG ((DEBUG_ERROR, "XenPvBlk: Failed to write event-channel.\n"));
257 goto AbortTransaction;
258 }
259
260 Status = XenBusIo->XsPrintf (
261 XenBusIo,
263 NodeName,
264 "protocol",
265 "%a",
266 XEN_IO_PROTO_ABI_NATIVE
267 );
268 if (Status != XENSTORE_STATUS_SUCCESS) {
269 DEBUG ((DEBUG_ERROR, "XenPvBlk: Failed to write protocol.\n"));
270 goto AbortTransaction;
271 }
272
273 Status = XenBusIo->SetState (XenBusIo, &Transaction, XenbusStateConnected);
274 if (Status != XENSTORE_STATUS_SUCCESS) {
275 DEBUG ((DEBUG_ERROR, "XenPvBlk: Failed to switch state.\n"));
276 goto AbortTransaction;
277 }
278
279 Status = XenBusIo->XsTransactionEnd (XenBusIo, &Transaction, FALSE);
280 if (Status == XENSTORE_STATUS_EAGAIN) {
281 goto Again;
282 }
283
284 XenBusIo->RegisterWatchBackend (XenBusIo, "state", &Dev->StateWatchToken);
285
286 //
287 // Waiting for backend
288 //
289 Status = XenPvBlkWaitForBackendState (Dev, XenbusStateConnected, &State);
290 if (Status != XENSTORE_STATUS_SUCCESS) {
291 DEBUG ((
292 DEBUG_ERROR,
293 "XenPvBlk: backend for %a/%d not available, rc=%d state=%d\n",
294 XenBusIo->Type,
295 XenBusIo->DeviceId,
296 Status,
297 State
298 ));
299 goto Error2;
300 }
301
302 Status = XenBusReadUint64 (XenBusIo, "info", TRUE, &Value);
303 if ((Status != XENSTORE_STATUS_SUCCESS) || (Value > MAX_UINT32)) {
304 goto Error2;
305 }
306
307 Dev->MediaInfo.VDiskInfo = (UINT32)Value;
308 if (Dev->MediaInfo.VDiskInfo & VDISK_READONLY) {
309 Dev->MediaInfo.ReadWrite = FALSE;
310 } else {
311 Dev->MediaInfo.ReadWrite = TRUE;
312 }
313
314 Status = XenBusReadUint64 (XenBusIo, "sectors", TRUE, &Dev->MediaInfo.Sectors);
315 if (Status != XENSTORE_STATUS_SUCCESS) {
316 goto Error2;
317 }
318
319 Status = XenBusReadUint64 (XenBusIo, "sector-size", TRUE, &Value);
320 if ((Status != XENSTORE_STATUS_SUCCESS) || (Value > MAX_UINT32)) {
321 goto Error2;
322 }
323
324 if ((UINT32)Value % 512 != 0) {
325 //
326 // This is not supported by the driver.
327 //
328 DEBUG ((
329 DEBUG_ERROR,
330 "XenPvBlk: Unsupported sector-size value %Lu, "
331 "it must be a multiple of 512\n",
332 Value
333 ));
334 goto Error2;
335 }
336
337 Dev->MediaInfo.SectorSize = (UINT32)Value;
338
339 // Default value
340 Value = 0;
341 XenBusReadUint64 (XenBusIo, "feature-barrier", TRUE, &Value);
342 if (Value == 1) {
343 Dev->MediaInfo.FeatureBarrier = TRUE;
344 } else {
345 Dev->MediaInfo.FeatureBarrier = FALSE;
346 }
347
348 // Default value
349 Value = 0;
350 XenBusReadUint64 (XenBusIo, "feature-flush-cache", TRUE, &Value);
351 if (Value == 1) {
352 Dev->MediaInfo.FeatureFlushCache = TRUE;
353 } else {
354 Dev->MediaInfo.FeatureFlushCache = FALSE;
355 }
356
357 DEBUG ((
358 DEBUG_INFO,
359 "XenPvBlk: New disk with %ld sectors of %d bytes\n",
360 Dev->MediaInfo.Sectors,
361 Dev->MediaInfo.SectorSize
362 ));
363
364 *DevPtr = Dev;
365 return EFI_SUCCESS;
366
367Error2:
368 XenBusIo->UnregisterWatch (XenBusIo, Dev->StateWatchToken);
369 XenBusIo->XsRemove (XenBusIo, XST_NIL, "ring-ref");
370 XenBusIo->XsRemove (XenBusIo, XST_NIL, "event-channel");
371 XenBusIo->XsRemove (XenBusIo, XST_NIL, "protocol");
372 goto Error;
373AbortTransaction:
374 XenBusIo->XsTransactionEnd (XenBusIo, &Transaction, TRUE);
375Error:
376 XenPvBlockFree (Dev);
377 return EFI_DEVICE_ERROR;
378}
379
380VOID
381XenPvBlockFrontShutdown (
383 )
384{
385 XENBUS_PROTOCOL *XenBusIo = Dev->XenBusIo;
386 XENSTORE_STATUS Status;
387 UINT64 Value;
388
389 XenPvBlockSync (Dev);
390
391 Status = XenBusIo->SetState (XenBusIo, XST_NIL, XenbusStateClosing);
392 if (Status != XENSTORE_STATUS_SUCCESS) {
393 DEBUG ((
394 DEBUG_ERROR,
395 "XenPvBlk: error while changing state to Closing: %d\n",
396 Status
397 ));
398 goto Close;
399 }
400
401 Status = XenPvBlkWaitForBackendState (Dev, XenbusStateClosing, NULL);
402 if (Status != XENSTORE_STATUS_SUCCESS) {
403 DEBUG ((
404 DEBUG_ERROR,
405 "XenPvBlk: error while waiting for closing backend state: %d\n",
406 Status
407 ));
408 goto Close;
409 }
410
411 Status = XenBusIo->SetState (XenBusIo, XST_NIL, XenbusStateClosed);
412 if (Status != XENSTORE_STATUS_SUCCESS) {
413 DEBUG ((
414 DEBUG_ERROR,
415 "XenPvBlk: error while changing state to Closed: %d\n",
416 Status
417 ));
418 goto Close;
419 }
420
421 Status = XenPvBlkWaitForBackendState (Dev, XenbusStateClosed, NULL);
422 if (Status != XENSTORE_STATUS_SUCCESS) {
423 DEBUG ((
424 DEBUG_ERROR,
425 "XenPvBlk: error while waiting for closed backend state: %d\n",
426 Status
427 ));
428 goto Close;
429 }
430
431 Status = XenBusIo->SetState (XenBusIo, XST_NIL, XenbusStateInitialising);
432 if (Status != XENSTORE_STATUS_SUCCESS) {
433 DEBUG ((
434 DEBUG_ERROR,
435 "XenPvBlk: error while changing state to initialising: %d\n",
436 Status
437 ));
438 goto Close;
439 }
440
441 while (TRUE) {
442 Status = XenBusReadUint64 (XenBusIo, "state", TRUE, &Value);
443 if (Status != XENSTORE_STATUS_SUCCESS) {
444 DEBUG ((
445 DEBUG_ERROR,
446 "XenPvBlk: error while waiting for new backend state: %d\n",
447 Status
448 ));
449 goto Close;
450 }
451
452 if ((Value <= XenbusStateInitWait) || (Value >= XenbusStateClosed)) {
453 break;
454 }
455
456 DEBUG ((
457 DEBUG_INFO,
458 "XenPvBlk: waiting backend state %d, current: %Lu\n",
459 XenbusStateInitWait,
460 Value
461 ));
462 XenBusIo->WaitForWatch (XenBusIo, Dev->StateWatchToken);
463 }
464
465Close:
466 XenBusIo->UnregisterWatch (XenBusIo, Dev->StateWatchToken);
467 XenBusIo->XsRemove (XenBusIo, XST_NIL, "ring-ref");
468 XenBusIo->XsRemove (XenBusIo, XST_NIL, "event-channel");
469 XenBusIo->XsRemove (XenBusIo, XST_NIL, "protocol");
470
471 XenPvBlockFree (Dev);
472}
473
474STATIC
475VOID
476XenPvBlockWaitSlot (
478 )
479{
480 /* Wait for a slot */
481 if (RING_FULL (&Dev->Ring)) {
482 while (TRUE) {
483 XenPvBlockAsyncIoPoll (Dev);
484 if (!RING_FULL (&Dev->Ring)) {
485 break;
486 }
487
488 /* Really no slot, could wait for an event on Dev->EventChannel. */
489 }
490 }
491}
492
493VOID
494XenPvBlockAsyncIo (
495 IN OUT XEN_BLOCK_FRONT_IO *IoData,
496 IN BOOLEAN IsWrite
497 )
498{
499 XEN_BLOCK_FRONT_DEVICE *Dev = IoData->Dev;
500 XENBUS_PROTOCOL *XenBusIo = Dev->XenBusIo;
501 blkif_request_t *Request;
502 RING_IDX RingIndex;
503 BOOLEAN Notify;
504 INT32 NumSegments, Index;
505 UINTN Start, End;
506
507 // Can't io at non-sector-aligned location
508 ASSERT (!(IoData->Sector & ((Dev->MediaInfo.SectorSize / 512) - 1)));
509 // Can't io non-sector-sized amounts
510 ASSERT (!(IoData->Size & (Dev->MediaInfo.SectorSize - 1)));
511 // Can't io non-sector-aligned buffer
512 ASSERT (!((UINTN)IoData->Buffer & (Dev->MediaInfo.SectorSize - 1)));
513
514 Start = (UINTN)IoData->Buffer & ~EFI_PAGE_MASK;
515 End = ((UINTN)IoData->Buffer + IoData->Size + EFI_PAGE_SIZE - 1) & ~EFI_PAGE_MASK;
516 IoData->NumRef = NumSegments = (INT32)((End - Start) / EFI_PAGE_SIZE);
517
518 ASSERT (NumSegments <= BLKIF_MAX_SEGMENTS_PER_REQUEST);
519
520 XenPvBlockWaitSlot (Dev);
521 RingIndex = Dev->Ring.req_prod_pvt;
522 Request = RING_GET_REQUEST (&Dev->Ring, RingIndex);
523
524 Request->operation = IsWrite ? BLKIF_OP_WRITE : BLKIF_OP_READ;
525 Request->nr_segments = (UINT8)NumSegments;
526 Request->handle = Dev->DeviceId;
527 Request->id = (UINTN)IoData;
528 Request->sector_number = IoData->Sector;
529
530 for (Index = 0; Index < NumSegments; Index++) {
531 Request->seg[Index].first_sect = 0;
532 Request->seg[Index].last_sect = EFI_PAGE_SIZE / 512 - 1;
533 }
534
535 Request->seg[0].first_sect = (UINT8)(((UINTN)IoData->Buffer & EFI_PAGE_MASK) / 512);
536 Request->seg[NumSegments - 1].last_sect =
537 (UINT8)((((UINTN)IoData->Buffer + IoData->Size - 1) & EFI_PAGE_MASK) / 512);
538 for (Index = 0; Index < NumSegments; Index++) {
539 UINTN Data = Start + Index * EFI_PAGE_SIZE;
540 XenBusIo->GrantAccess (
541 XenBusIo,
542 Dev->DomainId,
543 Data >> EFI_PAGE_SHIFT,
544 IsWrite,
545 &Request->seg[Index].gref
546 );
547 IoData->GrantRef[Index] = Request->seg[Index].gref;
548 }
549
550 Dev->Ring.req_prod_pvt = RingIndex + 1;
551
552 MemoryFence ();
553 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY (&Dev->Ring, Notify);
554
555 if (Notify) {
556 UINT32 ReturnCode;
557 ReturnCode = XenBusIo->EventChannelNotify (XenBusIo, Dev->EventChannel);
558 if (ReturnCode != 0) {
559 DEBUG ((
560 DEBUG_ERROR,
561 "XenPvBlk: Unexpected return value from EventChannelNotify: %d\n",
562 ReturnCode
563 ));
564 }
565 }
566}
567
569XenPvBlockIo (
570 IN OUT XEN_BLOCK_FRONT_IO *IoData,
571 IN BOOLEAN IsWrite
572 )
573{
574 //
575 // Status value that correspond to an IO in progress.
576 //
577 IoData->Status = EFI_ALREADY_STARTED;
578 XenPvBlockAsyncIo (IoData, IsWrite);
579
580 while (IoData->Status == EFI_ALREADY_STARTED) {
581 XenPvBlockAsyncIoPoll (IoData->Dev);
582 }
583
584 return IoData->Status;
585}
586
587STATIC
588VOID
589XenPvBlockPushOperation (
591 IN UINT8 Operation,
592 IN UINT64 Id
593 )
594{
595 INT32 Index;
596 blkif_request_t *Request;
597 BOOLEAN Notify;
598
599 XenPvBlockWaitSlot (Dev);
600 Index = Dev->Ring.req_prod_pvt;
601 Request = RING_GET_REQUEST (&Dev->Ring, Index);
602 Request->operation = Operation;
603 Request->nr_segments = 0;
604 Request->handle = Dev->DeviceId;
605 Request->id = Id;
606 /* Not needed anyway, but the backend will check it */
607 Request->sector_number = 0;
608 Dev->Ring.req_prod_pvt = Index + 1;
609 MemoryFence ();
610 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY (&Dev->Ring, Notify);
611 if (Notify) {
612 XENBUS_PROTOCOL *XenBusIo = Dev->XenBusIo;
613 UINT32 ReturnCode;
614 ReturnCode = XenBusIo->EventChannelNotify (XenBusIo, Dev->EventChannel);
615 if (ReturnCode != 0) {
616 DEBUG ((
617 DEBUG_ERROR,
618 "XenPvBlk: Unexpected return value from EventChannelNotify: %d\n",
619 ReturnCode
620 ));
621 }
622 }
623}
624
625VOID
626XenPvBlockSync (
628 )
629{
630 if (Dev->MediaInfo.ReadWrite) {
631 if (Dev->MediaInfo.FeatureBarrier) {
632 XenPvBlockPushOperation (Dev, BLKIF_OP_WRITE_BARRIER, 0);
633 }
634
635 if (Dev->MediaInfo.FeatureFlushCache) {
636 XenPvBlockPushOperation (Dev, BLKIF_OP_FLUSH_DISKCACHE, 0);
637 }
638 }
639
640 /* Note: This won't finish if another thread enqueues requests. */
641 while (TRUE) {
642 XenPvBlockAsyncIoPoll (Dev);
643 if (RING_FREE_REQUESTS (&Dev->Ring) == RING_SIZE (&Dev->Ring)) {
644 break;
645 }
646 }
647}
648
649VOID
650XenPvBlockAsyncIoPoll (
652 )
653{
654 RING_IDX ProducerIndex, ConsumerIndex;
655 blkif_response_t *Response;
656 INT32 More;
657
658 do {
659 ProducerIndex = Dev->Ring.sring->rsp_prod;
660 /* Ensure we see queued responses up to 'ProducerIndex'. */
661 MemoryFence ();
662 ConsumerIndex = Dev->Ring.rsp_cons;
663
664 while (ConsumerIndex != ProducerIndex) {
665 XEN_BLOCK_FRONT_IO *IoData = NULL;
666 INT16 Status;
667
668 Response = RING_GET_RESPONSE (&Dev->Ring, ConsumerIndex);
669
670 IoData = (VOID *)(UINTN)Response->id;
671 Status = Response->status;
672
673 switch (Response->operation) {
674 case BLKIF_OP_READ:
675 case BLKIF_OP_WRITE:
676 {
677 INT32 Index;
678
679 if (Status != BLKIF_RSP_OKAY) {
680 DEBUG ((
681 DEBUG_ERROR,
682 "XenPvBlk: "
683 "%a error %d on %a at sector %Lx, num bytes %Lx\n",
684 Response->operation == BLKIF_OP_READ ? "read" : "write",
685 Status,
686 IoData->Dev->NodeName,
687 (UINT64)IoData->Sector,
688 (UINT64)IoData->Size
689 ));
690 }
691
692 for (Index = 0; Index < IoData->NumRef; Index++) {
693 Dev->XenBusIo->GrantEndAccess (Dev->XenBusIo, IoData->GrantRef[Index]);
694 }
695
696 break;
697 }
698
699 case BLKIF_OP_WRITE_BARRIER:
700 if (Status != BLKIF_RSP_OKAY) {
701 DEBUG ((DEBUG_ERROR, "XenPvBlk: write barrier error %d\n", Status));
702 }
703
704 break;
705 case BLKIF_OP_FLUSH_DISKCACHE:
706 if (Status != BLKIF_RSP_OKAY) {
707 DEBUG ((DEBUG_ERROR, "XenPvBlk: flush error %d\n", Status));
708 }
709
710 break;
711
712 default:
713 DEBUG ((
714 DEBUG_ERROR,
715 "XenPvBlk: unrecognized block operation %d response (status %d)\n",
716 Response->operation,
717 Status
718 ));
719 break;
720 }
721
722 Dev->Ring.rsp_cons = ++ConsumerIndex;
723 if (IoData != NULL) {
724 IoData->Status = Status ? EFI_DEVICE_ERROR : EFI_SUCCESS;
725 }
726
727 if (Dev->Ring.rsp_cons != ConsumerIndex) {
728 /* We reentered, we must not continue here */
729 break;
730 }
731 }
732
733 RING_FINAL_CHECK_FOR_RESPONSES (&Dev->Ring, More);
734 } while (More != 0);
735}
UINT64 UINTN
INT64 INTN
EFI_STATUS EFIAPI Close(IN EFI_ACPI_HANDLE Handle)
Definition: AcpiSdt.c:628
UINT64 EFIAPI AsciiStrDecimalToUint64(IN CONST CHAR8 *String)
Definition: String.c:1053
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:716
VOID EFIAPI MemoryFence(VOID)
Definition: CpuBreakpoint.c:42
STATIC VOID XenPvBlockFree(IN XEN_BLOCK_FRONT_DEVICE *Dev)
Definition: BlockFront.c:69
STATIC XENSTORE_STATUS XenBusReadUint64(IN XENBUS_PROTOCOL *This, IN CONST CHAR8 *Node, IN BOOLEAN FromBackend, OUT UINT64 *ValuePtr)
Definition: BlockFront.c:36
STATIC XENSTORE_STATUS XenPvBlkWaitForBackendState(IN XEN_BLOCK_FRONT_DEVICE *Dev, IN XenbusState ExpectedState, OUT XenbusState *LastStatePtr OPTIONAL)
Definition: BlockFront.c:102
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
VOID *EFIAPI AllocatePages(IN UINTN Pages)
EFI_STATUS EFIAPI Transaction(IN CONST EFI_SPI_IO_PROTOCOL *This, IN EFI_SPI_TRANSACTION_TYPE TransactionType, IN BOOLEAN DebugTransaction, IN UINT32 ClockHz OPTIONAL, IN UINT32 BusWidth, IN UINT32 FrameSize, IN UINT32 WriteBytes, IN UINT8 *WriteBuffer, IN UINT32 ReadBytes, OUT UINT8 *ReadBuffer)
Definition: SpiBus.c:231
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
UINTN Sector
512 bytes sector.
Definition: BlockFront.h:21