TianoCore EDK2 master
Loading...
Searching...
No Matches
XenBus.c
Go to the documentation of this file.
1
20#include <Library/PrintLib.h>
21
22#include "XenBus.h"
23#include "GrantTable.h"
24#include "XenStore.h"
25#include "EventChannel.h"
26
27#include <IndustryStandard/Xen/io/xenbus.h>
28
29STATIC XENBUS_PRIVATE_DATA gXenBusPrivateData;
30
31STATIC XENBUS_DEVICE_PATH gXenBusDevicePathTemplate = {
32 { // Vendor
33 { // Vendor.Header
34 HARDWARE_DEVICE_PATH, // Vendor.Header.Type
35 HW_VENDOR_DP, // Vendor.Header.SubType
36 {
37 (UINT8)(sizeof (XENBUS_DEVICE_PATH)), // Vendor.Header.Length[0]
38 (UINT8)(sizeof (XENBUS_DEVICE_PATH) >> 8), // Vendor.Header.Length[1]
39 }
40 },
41 XENBUS_PROTOCOL_GUID, // Vendor.Guid
42 },
43 0, // Type
44 0 // DeviceId
45};
46
59 IN XENBUS_DEVICE *Dev,
60 IN CONST CHAR8 *Node
61 )
62{
63 LIST_ENTRY *Entry;
65 XENBUS_PRIVATE_DATA *Result;
66
67 if (IsListEmpty (&Dev->ChildList)) {
68 return NULL;
69 }
70
71 Result = NULL;
72 for (Entry = GetFirstNode (&Dev->ChildList);
73 !IsNodeAtEnd (&Dev->ChildList, Entry);
74 Entry = GetNextNode (&Dev->ChildList, Entry))
75 {
76 Child = XENBUS_PRIVATE_DATA_FROM_LINK (Entry);
77 if (!AsciiStrCmp (Child->XenBusIo.Node, Node)) {
78 Result = Child;
79 break;
80 }
81 }
82
83 return (Result);
84}
85
87XenbusState
88XenBusReadDriverState (
89 IN CONST CHAR8 *Path
90 )
91{
92 XenbusState State;
93 CHAR8 *Ptr = NULL;
94 XENSTORE_STATUS Status;
95
96 Status = XenStoreRead (XST_NIL, Path, "state", NULL, (VOID **)&Ptr);
97 if (Status != XENSTORE_STATUS_SUCCESS) {
98 State = XenbusStateClosed;
99 } else {
100 State = AsciiStrDecimalToUintn (Ptr);
101 }
102
103 if (Ptr != NULL) {
104 FreePool (Ptr);
105 }
106
107 return State;
108}
109
110//
111// Callers should ensure that they are only one calling XenBusAddDevice.
112//
113STATIC
115XenBusAddDevice (
116 XENBUS_DEVICE *Dev,
117 CONST CHAR8 *Type,
118 CONST CHAR8 *Id
119 )
120{
121 CHAR8 DevicePath[XENSTORE_ABS_PATH_MAX];
122 XENSTORE_STATUS StatusXenStore;
123 XENBUS_PRIVATE_DATA *Private;
124 EFI_STATUS Status;
125 XENBUS_DEVICE_PATH *TempXenBusPath;
126 VOID *ChildXenIo;
127
129 DevicePath,
130 sizeof (DevicePath),
131 "device/%a/%a",
132 Type,
133 Id
134 );
135
136 if (XenStorePathExists (XST_NIL, DevicePath, "")) {
138 enum xenbus_state State;
139 CHAR8 *BackendPath;
140
141 Child = XenBusDeviceInitialized (Dev, DevicePath);
142 if (Child != NULL) {
143 /*
144 * We are already tracking this node
145 */
146 Status = EFI_SUCCESS;
147 goto out;
148 }
149
150 State = XenBusReadDriverState (DevicePath);
151 if (State != XenbusStateInitialising) {
152 /*
153 * Device is not new, so ignore it. This can
154 * happen if a device is going away after
155 * switching to Closed.
156 */
157 DEBUG ((
158 DEBUG_INFO,
159 "XenBus: Device %a ignored. "
160 "State %d\n",
161 DevicePath,
162 State
163 ));
164 Status = EFI_SUCCESS;
165 goto out;
166 }
167
168 StatusXenStore = XenStoreRead (
169 XST_NIL,
170 DevicePath,
171 "backend",
172 NULL,
173 (VOID **)&BackendPath
174 );
175 if (StatusXenStore != XENSTORE_STATUS_SUCCESS) {
176 DEBUG ((DEBUG_ERROR, "xenbus: %a no backend path.\n", DevicePath));
177 Status = EFI_NOT_FOUND;
178 goto out;
179 }
180
181 Private = AllocateCopyPool (sizeof (*Private), &gXenBusPrivateData);
182 Private->XenBusIo.Type = AsciiStrDup (Type);
183 Private->XenBusIo.Node = AsciiStrDup (DevicePath);
184 Private->XenBusIo.Backend = BackendPath;
185 Private->XenBusIo.DeviceId = (UINT16)AsciiStrDecimalToUintn (Id);
186 Private->Dev = Dev;
187
188 TempXenBusPath = AllocateCopyPool (
189 sizeof (XENBUS_DEVICE_PATH),
190 &gXenBusDevicePathTemplate
191 );
192 if (!AsciiStrCmp (Private->XenBusIo.Type, "vbd")) {
193 TempXenBusPath->Type = XENBUS_DEVICE_PATH_TYPE_VBD;
194 }
195
196 TempXenBusPath->DeviceId = Private->XenBusIo.DeviceId;
197 Private->DevicePath = (XENBUS_DEVICE_PATH *)AppendDevicePathNode (
198 Dev->DevicePath,
199 &TempXenBusPath->Vendor.Header
200 );
201 FreePool (TempXenBusPath);
202
203 InsertTailList (&Dev->ChildList, &Private->Link);
204
205 Status = gBS->InstallMultipleProtocolInterfaces (
206 &Private->Handle,
207 &gEfiDevicePathProtocolGuid,
208 Private->DevicePath,
209 &gXenBusProtocolGuid,
210 &Private->XenBusIo,
211 NULL
212 );
213 if (EFI_ERROR (Status)) {
214 goto ErrorInstallProtocol;
215 }
216
217 Status = gBS->OpenProtocol (
218 Dev->ControllerHandle,
219 &gXenIoProtocolGuid,
220 &ChildXenIo,
221 Dev->This->DriverBindingHandle,
222 Private->Handle,
223 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
224 );
225 if (EFI_ERROR (Status)) {
226 DEBUG ((
227 DEBUG_ERROR,
228 "open by child controller fail (%r)\n",
229 Status
230 ));
231 goto ErrorOpenProtocolByChild;
232 }
233 } else {
234 DEBUG ((DEBUG_ERROR, "XenBus: does not exist: %a\n", DevicePath));
235 Status = EFI_NOT_FOUND;
236 }
237
238 return Status;
239
240ErrorOpenProtocolByChild:
241 gBS->UninstallMultipleProtocolInterfaces (
242 Private->Handle,
243 &gEfiDevicePathProtocolGuid,
244 Private->DevicePath,
245 &gXenBusProtocolGuid,
246 &Private->XenBusIo,
247 NULL
248 );
249ErrorInstallProtocol:
250 RemoveEntryList (&Private->Link);
251 FreePool (Private->DevicePath);
252 FreePool ((VOID *)Private->XenBusIo.Backend);
253 FreePool ((VOID *)Private->XenBusIo.Node);
254 FreePool ((VOID *)Private->XenBusIo.Type);
255 FreePool (Private);
256out:
257 return Status;
258}
259
271STATIC
272VOID
274 XENBUS_DEVICE *Dev,
275 CONST CHAR8 *Type
276 )
277{
278 CONST CHAR8 **Directory;
279 UINTN Index;
280 UINT32 Count;
281 XENSTORE_STATUS Status;
282
283 Status = XenStoreListDirectory (
284 XST_NIL,
285 "device",
286 Type,
287 &Count,
288 &Directory
289 );
290 if (Status != XENSTORE_STATUS_SUCCESS) {
291 return;
292 }
293
294 for (Index = 0; Index < Count; Index++) {
295 XenBusAddDevice (Dev, Type, Directory[Index]);
296 }
297
298 FreePool ((VOID *)Directory);
299}
300
312XENSTORE_STATUS
314 XENBUS_DEVICE *Dev
315 )
316{
317 CONST CHAR8 **Types;
318 UINTN Index;
319 UINT32 Count;
320 XENSTORE_STATUS Status;
321
322 Status = XenStoreListDirectory (
323 XST_NIL,
324 "device",
325 "",
326 &Count,
327 &Types
328 );
329 if (Status != XENSTORE_STATUS_SUCCESS) {
330 return Status;
331 }
332
333 for (Index = 0; Index < Count; Index++) {
334 XenBusEnumerateDeviceType (Dev, Types[Index]);
335 }
336
337 FreePool ((VOID *)Types);
338
339 return XENSTORE_STATUS_SUCCESS;
340}
341
342STATIC
343XENSTORE_STATUS
344EFIAPI
345XenBusSetState (
346 IN XENBUS_PROTOCOL *This,
348 IN enum xenbus_state NewState
349 )
350{
351 enum xenbus_state CurrentState;
352 XENSTORE_STATUS Status;
353 CHAR8 *Temp;
354
355 DEBUG ((DEBUG_INFO, "XenBus: Set state to %d\n", NewState));
356
357 Status = XenStoreRead (Transaction, This->Node, "state", NULL, (VOID **)&Temp);
358 if (Status != XENSTORE_STATUS_SUCCESS) {
359 goto Out;
360 }
361
362 CurrentState = AsciiStrDecimalToUintn (Temp);
363 FreePool (Temp);
364 if (CurrentState == NewState) {
365 goto Out;
366 }
367
368 do {
369 Status = XenStoreSPrint (Transaction, This->Node, "state", "%d", NewState);
370 } while (Status == XENSTORE_STATUS_EAGAIN);
371
372 if (Status != XENSTORE_STATUS_SUCCESS) {
373 DEBUG ((DEBUG_ERROR, "XenBus: failed to write new state\n"));
374 goto Out;
375 }
376
377 DEBUG ((DEBUG_INFO, "XenBus: Set state to %d, done\n", NewState));
378
379Out:
380 return Status;
381}
382
383STATIC XENBUS_PRIVATE_DATA gXenBusPrivateData = {
384 XENBUS_PRIVATE_DATA_SIGNATURE, // Signature
385 { NULL, NULL }, // Link
386 NULL, // Handle
387 { // XenBusIo
388 XenBusXenStoreRead, // XenBusIo.XsRead
389 XenBusXenStoreBackendRead, // XenBusIo.XsBackendRead
390 XenBusXenStoreSPrint, // XenBusIo.XsPrintf
391 XenBusXenStoreRemove, // XenBusIo.XsRemove
392 XenBusXenStoreTransactionStart, // XenBusIo.XsTransactionStart
393 XenBusXenStoreTransactionEnd, // XenBusIo.XsTransactionEnd
394 XenBusSetState, // XenBusIo.SetState
395 XenBusGrantAccess, // XenBusIo.GrantAccess
396 XenBusGrantEndAccess, // XenBusIo.GrantEndAccess
397 XenBusEventChannelAllocate, // XenBusIo.EventChannelAllocate
398 XenBusEventChannelNotify, // XenBusIo.EventChannelNotify
399 XenBusEventChannelClose, // XenBusIo.EventChannelClose
400 XenBusRegisterWatch, // XenBusIo.RegisterWatch
401 XenBusRegisterWatchBackend, // XenBusIo.RegisterWatchBackend
402 XenBusUnregisterWatch, // XenBusIo.UnregisterWatch
403 XenBusWaitForWatch, // XenBusIo.WaitForWatch
404
405 NULL, // XenBusIo.Type
406 0, // XenBusIo.DeviceId
407 NULL, // XenBusIo.Node
408 NULL, // XenBusIo.Backend
409 },
410
411 NULL, // Dev
412 NULL // DevicePath
413};
UINT64 UINTN
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
BOOLEAN EFIAPI IsNodeAtEnd(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:481
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:716
UINTN EFIAPI AsciiStrDecimalToUintn(IN CONST CHAR8 *String)
Definition: String.c:1006
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
NODE Child(IN NODE LoopVar6, IN UINT8 LoopVar5)
Definition: Compress.c:265
#define HARDWARE_DEVICE_PATH
Definition: DevicePath.h:68
#define HW_VENDOR_DP
Definition: DevicePath.h:133
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
UINT32 EFIAPI XenBusEventChannelNotify(IN XENBUS_PROTOCOL *This, IN evtchn_port_t Port)
Definition: EventChannel.c:58
UINT32 EFIAPI XenBusEventChannelClose(IN XENBUS_PROTOCOL *This, IN evtchn_port_t Port)
Definition: EventChannel.c:71
UINT32 EFIAPI XenBusEventChannelAllocate(IN XENBUS_PROTOCOL *This, IN domid_t DomainId, OUT evtchn_port_t *Port)
Definition: EventChannel.c:32
EFI_STATUS EFIAPI XenBusGrantEndAccess(IN XENBUS_PROTOCOL *This, IN grant_ref_t Ref)
Definition: GrantTable.c:205
EFI_STATUS EFIAPI XenBusGrantAccess(IN XENBUS_PROTOCOL *This, IN domid_t DomainId, IN UINTN Frame, IN BOOLEAN ReadOnly, OUT grant_ref_t *RefPtr)
Definition: GrantTable.c:191
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
Definition: PrintLib.c:813
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define IN
Definition: Base.h:279
#define DEBUG(Expression)
Definition: DebugLib.h:434
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
EFI_BOOT_SERVICES * gBS
STATIC VOID XenBusEnumerateDeviceType(XENBUS_DEVICE *Dev, CONST CHAR8 *Type)
Definition: XenBus.c:273
XENSTORE_STATUS XenBusEnumerateBus(XENBUS_DEVICE *Dev)
Definition: XenBus.c:313
STATIC XENBUS_PRIVATE_DATA * XenBusDeviceInitialized(IN XENBUS_DEVICE *Dev, IN CONST CHAR8 *Node)
Definition: XenBus.c:58
XENSTORE_STATUS EFIAPI XenStoreSPrint(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, IN CONST CHAR8 *FormatString,...)
Definition: XenStore.c:1392
XENSTORE_STATUS XenStoreListDirectory(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, OUT UINT32 *DirectoryCountPtr, OUT CONST CHAR8 ***DirectoryListPtr)
Definition: XenStore.c:1204
BOOLEAN XenStorePathExists(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *Directory, IN CONST CHAR8 *Node)
Definition: XenStore.c:1236
XENSTORE_STATUS XenStoreRead(IN CONST XENSTORE_TRANSACTION *Transaction, IN CONST CHAR8 *DirectoryPath, IN CONST CHAR8 *Node, OUT UINT32 *LenPtr OPTIONAL, OUT VOID **Result)
Definition: XenStore.c:1262