Coverage Report

Created: 2024-10-17 06:29

/src/hbfa-fl/HBFA/UefiHostTestPkg/Library/UefiBootServicesTableLibHost/DriverSupport.c
Line
Count
Source (jump to first uncovered line)
1
/** @file
2
  Support functions to connect/disconnect UEFI Driver model Protocol
3
4
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5
SPDX-License-Identifier: BSD-2-Clause-Patent
6
7
**/
8
9
#include "DxeMain.h"
10
#include "Handle.h"
11
12
13
//
14
// Driver Support Functions
15
//
16
/**
17
  Connects one or more drivers to a controller.
18
19
  @param  ControllerHandle      The handle of the controller to which driver(s) are to be connected.
20
  @param  DriverImageHandle     A pointer to an ordered list handles that support the
21
                                EFI_DRIVER_BINDING_PROTOCOL.
22
  @param  RemainingDevicePath   A pointer to the device path that specifies a child of the
23
                                controller specified by ControllerHandle.
24
  @param  Recursive             If TRUE, then ConnectController() is called recursively
25
                                until the entire tree of controllers below the controller specified
26
                                by ControllerHandle have been created. If FALSE, then
27
                                the tree of controllers is only expanded one level.
28
29
  @retval EFI_SUCCESS           1) One or more drivers were connected to ControllerHandle.
30
                                2) No drivers were connected to ControllerHandle, but
31
                                RemainingDevicePath is not NULL, and it is an End Device
32
                                Path Node.
33
  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
34
  @retval EFI_NOT_FOUND         1) There are no EFI_DRIVER_BINDING_PROTOCOL instances
35
                                present in the system.
36
                                2) No drivers were connected to ControllerHandle.
37
  @retval EFI_SECURITY_VIOLATION
38
                                The user has no permission to start UEFI device drivers on the device path
39
                                associated with the ControllerHandle or specified by the RemainingDevicePath.
40
41
**/
42
EFI_STATUS
43
EFIAPI
44
CoreConnectController (
45
  IN  EFI_HANDLE                ControllerHandle,
46
  IN  EFI_HANDLE                *DriverImageHandle    OPTIONAL,
47
  IN  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath  OPTIONAL,
48
  IN  BOOLEAN                   Recursive
49
  )
50
0
{
51
0
  EFI_STATUS                           Status;
52
0
  EFI_STATUS                           ReturnStatus;
53
0
  IHANDLE                              *Handle;
54
0
  PROTOCOL_INTERFACE                   *Prot;
55
0
  LIST_ENTRY                           *Link;
56
0
  LIST_ENTRY                           *ProtLink;
57
0
  OPEN_PROTOCOL_DATA                   *OpenData;
58
0
  EFI_DEVICE_PATH_PROTOCOL             *AlignedRemainingDevicePath;
59
0
  EFI_HANDLE                           *ChildHandleBuffer;
60
0
  UINTN                                ChildHandleCount;
61
0
  UINTN                                Index;
62
0
  UINTN                                HandleFilePathSize;
63
0
  UINTN                                RemainingDevicePathSize;
64
0
  EFI_DEVICE_PATH_PROTOCOL             *HandleFilePath;
65
0
  EFI_DEVICE_PATH_PROTOCOL             *FilePath;
66
0
  EFI_DEVICE_PATH_PROTOCOL             *TempFilePath;
67
68
  //
69
  // Make sure ControllerHandle is valid
70
  //
71
0
  Status = CoreValidateHandle (ControllerHandle);
72
0
  if (EFI_ERROR (Status)) {
73
0
    return Status;
74
0
  }
75
76
0
  if (gSecurity2 != NULL) {
77
    //
78
    // Check whether the user has permission to start UEFI device drivers.
79
    //
80
0
    Status = CoreHandleProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath);
81
0
    if (!EFI_ERROR (Status)) {
82
0
      ASSERT (HandleFilePath != NULL);
83
0
      FilePath     = HandleFilePath;
84
0
      TempFilePath = NULL;
85
0
      if (RemainingDevicePath != NULL && !Recursive) {
86
0
        HandleFilePathSize      = GetDevicePathSize (HandleFilePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL);
87
0
        RemainingDevicePathSize = GetDevicePathSize (RemainingDevicePath);
88
0
        TempFilePath = AllocateZeroPool (HandleFilePathSize + RemainingDevicePathSize);
89
0
        ASSERT (TempFilePath != NULL);
90
0
        CopyMem (TempFilePath, HandleFilePath, HandleFilePathSize);
91
0
        CopyMem ((UINT8 *) TempFilePath + HandleFilePathSize, RemainingDevicePath, RemainingDevicePathSize);
92
0
        FilePath = TempFilePath;
93
0
      }
94
0
      Status = gSecurity2->FileAuthentication (
95
0
                            gSecurity2,
96
0
                            FilePath,
97
0
                            NULL,
98
0
                            0,
99
0
                            FALSE
100
0
                            );
101
0
      if (TempFilePath != NULL) {
102
0
        FreePool (TempFilePath);
103
0
      }
104
0
      if (EFI_ERROR (Status)) {
105
0
        return Status;
106
0
      }
107
0
    }
108
0
  }
109
110
0
  Handle = ControllerHandle;
111
112
  //
113
  // Make a copy of RemainingDevicePath to guanatee it is aligned
114
  //
115
0
  AlignedRemainingDevicePath = NULL;
116
0
  if (RemainingDevicePath != NULL) {
117
0
    AlignedRemainingDevicePath = DuplicateDevicePath (RemainingDevicePath);
118
119
0
    if (AlignedRemainingDevicePath == NULL) {
120
0
      return EFI_OUT_OF_RESOURCES;
121
0
    }
122
0
  }
123
124
  //
125
  // Connect all drivers to ControllerHandle
126
  // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
127
  // Driver Binding Protocols in the handle database has increased during the call
128
  // so the connect operation must be restarted
129
  //
130
0
  do {
131
0
    ReturnStatus = CoreConnectSingleController (
132
0
                     ControllerHandle,
133
0
                     DriverImageHandle,
134
0
                     AlignedRemainingDevicePath
135
0
                     );
136
0
  } while (ReturnStatus == EFI_NOT_READY);
137
138
  //
139
  // Free the aligned copy of RemainingDevicePath
140
  //
141
0
  if (AlignedRemainingDevicePath != NULL) {
142
0
    CoreFreePool (AlignedRemainingDevicePath);
143
0
  }
144
145
  //
146
  // If recursive, then connect all drivers to all of ControllerHandle's children
147
  //
148
0
  if (Recursive) {
149
    //
150
    // Acquire the protocol lock on the handle database so the child handles can be collected
151
    //
152
0
    CoreAcquireProtocolLock ();
153
154
    //
155
    // Make sure the DriverBindingHandle is valid
156
    //
157
0
    Status = CoreValidateHandle (ControllerHandle);
158
0
    if (EFI_ERROR (Status)) {
159
      //
160
      // Release the protocol lock on the handle database
161
      //
162
0
      CoreReleaseProtocolLock ();
163
164
0
      return ReturnStatus;
165
0
    }
166
167
168
    //
169
    // Count ControllerHandle's children
170
    //
171
0
    for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) {
172
0
      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
173
0
      for (ProtLink = Prot->OpenList.ForwardLink;
174
0
          ProtLink != &Prot->OpenList;
175
0
          ProtLink = ProtLink->ForwardLink) {
176
0
        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
177
0
        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
178
0
          ChildHandleCount++;
179
0
        }
180
0
      }
181
0
    }
182
183
    //
184
    // Allocate a handle buffer for ControllerHandle's children
185
    //
186
0
    ChildHandleBuffer = AllocatePool (ChildHandleCount * sizeof(EFI_HANDLE));
187
0
    if (ChildHandleBuffer == NULL) {
188
0
      CoreReleaseProtocolLock ();
189
0
      return EFI_OUT_OF_RESOURCES;
190
0
    }
191
192
    //
193
    // Fill in a handle buffer with ControllerHandle's children
194
    //
195
0
    for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) {
196
0
      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
197
0
      for (ProtLink = Prot->OpenList.ForwardLink;
198
0
          ProtLink != &Prot->OpenList;
199
0
          ProtLink = ProtLink->ForwardLink) {
200
0
        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
201
0
        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
202
0
          ChildHandleBuffer[ChildHandleCount] = OpenData->ControllerHandle;
203
0
          ChildHandleCount++;
204
0
        }
205
0
      }
206
0
    }
207
208
    //
209
    // Release the protocol lock on the handle database
210
    //
211
0
    CoreReleaseProtocolLock ();
212
213
    //
214
    // Recursively connect each child handle
215
    //
216
0
    for (Index = 0; Index < ChildHandleCount; Index++) {
217
0
      CoreConnectController (
218
0
        ChildHandleBuffer[Index],
219
0
        NULL,
220
0
        NULL,
221
0
        TRUE
222
0
        );
223
0
    }
224
225
    //
226
    // Free the handle buffer of ControllerHandle's children
227
    //
228
0
    CoreFreePool (ChildHandleBuffer);
229
0
  }
230
231
0
  return ReturnStatus;
232
0
}
233
234
235
/**
236
  Add Driver Binding Protocols from Context Driver Image Handles to sorted
237
  Driver Binding Protocol list.
238
239
  @param  DriverBindingHandle                   Handle of the driver binding
240
                                                protocol.
241
  @param  NumberOfSortedDriverBindingProtocols  Number Of sorted driver binding
242
                                                protocols
243
  @param  SortedDriverBindingProtocols          The sorted protocol list.
244
  @param  DriverBindingHandleCount              Driver Binding Handle Count.
245
  @param  DriverBindingHandleBuffer             The buffer of driver binding
246
                                                protocol to be modified.
247
  @param  IsImageHandle                         Indicate whether
248
                                                DriverBindingHandle is an image
249
                                                handle
250
251
  @return None.
252
253
**/
254
VOID
255
AddSortedDriverBindingProtocol (
256
  IN      EFI_HANDLE                   DriverBindingHandle,
257
  IN OUT  UINTN                        *NumberOfSortedDriverBindingProtocols,
258
  IN OUT  EFI_DRIVER_BINDING_PROTOCOL  **SortedDriverBindingProtocols,
259
  IN      UINTN                        DriverBindingHandleCount,
260
  IN OUT  EFI_HANDLE                   *DriverBindingHandleBuffer,
261
  IN      BOOLEAN                      IsImageHandle
262
  )
263
0
{
264
0
  EFI_STATUS                   Status;
265
0
  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding;
266
0
  UINTN                        Index;
267
268
  //
269
  // Make sure the DriverBindingHandle is valid
270
  //
271
0
  Status = CoreValidateHandle (DriverBindingHandle);
272
0
  if (EFI_ERROR (Status)) {
273
0
    return;
274
0
  }
275
276
  //
277
  // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
278
  // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
279
  //
280
0
  if (IsImageHandle) {
281
    //
282
    // Loop through all the Driver Binding Handles
283
    //
284
0
    for (Index = 0; Index < DriverBindingHandleCount; Index++) {
285
      //
286
      // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
287
      //
288
0
      Status = CoreHandleProtocol (
289
0
                DriverBindingHandleBuffer[Index],
290
0
                &gEfiDriverBindingProtocolGuid,
291
0
                (VOID **) &DriverBinding
292
0
                );
293
0
      if (EFI_ERROR (Status) || DriverBinding == NULL) {
294
0
        continue;
295
0
      }
296
297
      //
298
      // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
299
      // then add the DriverBindingProtocol[Index] to the sorted list
300
      //
301
0
      if (DriverBinding->ImageHandle == DriverBindingHandle) {
302
0
        AddSortedDriverBindingProtocol (
303
0
          DriverBindingHandleBuffer[Index],
304
0
          NumberOfSortedDriverBindingProtocols,
305
0
          SortedDriverBindingProtocols,
306
0
          DriverBindingHandleCount,
307
0
          DriverBindingHandleBuffer,
308
0
          FALSE
309
0
          );
310
0
      }
311
0
    }
312
0
    return;
313
0
  }
314
315
  //
316
  // Retrieve the Driver Binding Protocol from DriverBindingHandle
317
  //
318
0
  Status = CoreHandleProtocol(
319
0
             DriverBindingHandle,
320
0
             &gEfiDriverBindingProtocolGuid,
321
0
             (VOID **) &DriverBinding
322
0
             );
323
  //
324
  // If DriverBindingHandle does not support the Driver Binding Protocol then return
325
  //
326
0
  if (EFI_ERROR (Status) || DriverBinding == NULL) {
327
0
    return;
328
0
  }
329
330
  //
331
  // See if DriverBinding is already in the sorted list
332
  //
333
0
  for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols && Index < DriverBindingHandleCount; Index++) {
334
0
    if (DriverBinding == SortedDriverBindingProtocols[Index]) {
335
0
      return;
336
0
    }
337
0
  }
338
339
  //
340
  // Add DriverBinding to the end of the list
341
  //
342
0
  if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) {
343
0
    SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding;
344
0
  }
345
0
  *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1;
346
347
  //
348
  // Mark the cooresponding handle in DriverBindingHandleBuffer as used
349
  //
350
0
  for (Index = 0; Index < DriverBindingHandleCount; Index++) {
351
0
    if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {
352
0
      DriverBindingHandleBuffer[Index] = NULL;
353
0
    }
354
0
  }
355
0
}
356
357
358
/**
359
  Connects a controller to a driver.
360
361
  @param  ControllerHandle                      Handle of the controller to be
362
                                                connected.
363
  @param  ContextDriverImageHandles             DriverImageHandle A pointer to an
364
                                                ordered list of driver image
365
                                                handles.
366
  @param  RemainingDevicePath                   RemainingDevicePath A pointer to
367
                                                the device path that specifies a
368
                                                child  of the controller
369
                                                specified by ControllerHandle.
370
371
  @retval EFI_SUCCESS                           One or more drivers were
372
                                                connected to ControllerHandle.
373
  @retval EFI_OUT_OF_RESOURCES                  No enough system resources to
374
                                                complete the request.
375
  @retval EFI_NOT_FOUND                         No drivers were connected to
376
                                                ControllerHandle.
377
378
**/
379
EFI_STATUS
380
CoreConnectSingleController (
381
  IN  EFI_HANDLE                ControllerHandle,
382
  IN  EFI_HANDLE                *ContextDriverImageHandles OPTIONAL,
383
  IN  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath       OPTIONAL
384
  )
385
0
{
386
0
  EFI_STATUS                                 Status;
387
0
  UINTN                                      Index;
388
0
  EFI_HANDLE                                 DriverImageHandle;
389
0
  EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL      *PlatformDriverOverride;
390
0
  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL  *BusSpecificDriverOverride;
391
0
  UINTN                                      DriverBindingHandleCount;
392
0
  EFI_HANDLE                                 *DriverBindingHandleBuffer;
393
0
  UINTN                                      NewDriverBindingHandleCount;
394
0
  EFI_HANDLE                                 *NewDriverBindingHandleBuffer;
395
0
  EFI_DRIVER_BINDING_PROTOCOL                *DriverBinding;
396
0
  EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL        *DriverFamilyOverride;
397
0
  UINTN                                      NumberOfSortedDriverBindingProtocols;
398
0
  EFI_DRIVER_BINDING_PROTOCOL                **SortedDriverBindingProtocols;
399
0
  UINT32                                     DriverFamilyOverrideVersion;
400
0
  UINT32                                     HighestVersion;
401
0
  UINTN                                      HighestIndex;
402
0
  UINTN                                      SortIndex;
403
0
  BOOLEAN                                    OneStarted;
404
0
  BOOLEAN                                    DriverFound;
405
406
  //
407
  // Initialize local variables
408
  //
409
0
  DriverBindingHandleCount              = 0;
410
0
  DriverBindingHandleBuffer             = NULL;
411
0
  NumberOfSortedDriverBindingProtocols  = 0;
412
0
  SortedDriverBindingProtocols          = NULL;
413
0
  PlatformDriverOverride                = NULL;
414
0
  NewDriverBindingHandleBuffer          = NULL;
415
416
  //
417
  // Get list of all Driver Binding Protocol Instances
418
  //
419
0
  Status = CoreLocateHandleBuffer (
420
0
             ByProtocol,
421
0
             &gEfiDriverBindingProtocolGuid,
422
0
             NULL,
423
0
             &DriverBindingHandleCount,
424
0
             &DriverBindingHandleBuffer
425
0
             );
426
0
  if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {
427
0
    return EFI_NOT_FOUND;
428
0
  }
429
430
  //
431
  // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
432
  //
433
0
  SortedDriverBindingProtocols = AllocatePool (sizeof (VOID *) * DriverBindingHandleCount);
434
0
  if (SortedDriverBindingProtocols == NULL) {
435
0
    CoreFreePool (DriverBindingHandleBuffer);
436
0
    return EFI_OUT_OF_RESOURCES;
437
0
  }
438
439
  //
440
  // Add Driver Binding Protocols from Context Driver Image Handles first
441
  //
442
0
  if (ContextDriverImageHandles != NULL) {
443
0
    for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) {
444
0
      AddSortedDriverBindingProtocol (
445
0
        ContextDriverImageHandles[Index],
446
0
        &NumberOfSortedDriverBindingProtocols,
447
0
        SortedDriverBindingProtocols,
448
0
        DriverBindingHandleCount,
449
0
        DriverBindingHandleBuffer,
450
0
        FALSE
451
0
        );
452
0
    }
453
0
  }
454
455
  //
456
  // Add the Platform Driver Override Protocol drivers for ControllerHandle next
457
  //
458
0
  Status = CoreLocateProtocol (
459
0
             &gEfiPlatformDriverOverrideProtocolGuid,
460
0
             NULL,
461
0
             (VOID **) &PlatformDriverOverride
462
0
             );
463
0
  if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) {
464
0
    DriverImageHandle = NULL;
465
0
    do {
466
0
      Status = PlatformDriverOverride->GetDriver (
467
0
                                         PlatformDriverOverride,
468
0
                                         ControllerHandle,
469
0
                                         &DriverImageHandle
470
0
                                         );
471
0
      if (!EFI_ERROR (Status)) {
472
0
        AddSortedDriverBindingProtocol (
473
0
          DriverImageHandle,
474
0
          &NumberOfSortedDriverBindingProtocols,
475
0
          SortedDriverBindingProtocols,
476
0
          DriverBindingHandleCount,
477
0
          DriverBindingHandleBuffer,
478
0
          TRUE
479
0
          );
480
0
      }
481
0
    } while (!EFI_ERROR (Status));
482
0
  }
483
484
  //
485
  // Add the Driver Family Override Protocol drivers for ControllerHandle
486
  //
487
0
  while (TRUE) {
488
0
    HighestIndex   = DriverBindingHandleCount;
489
0
    HighestVersion = 0;
490
0
    for (Index = 0; Index < DriverBindingHandleCount; Index++) {
491
0
      Status = CoreHandleProtocol (
492
0
                 DriverBindingHandleBuffer[Index],
493
0
                 &gEfiDriverFamilyOverrideProtocolGuid,
494
0
                 (VOID **) &DriverFamilyOverride
495
0
                 );
496
0
      if (!EFI_ERROR (Status) && (DriverFamilyOverride != NULL)) {
497
0
        DriverFamilyOverrideVersion = DriverFamilyOverride->GetVersion (DriverFamilyOverride);
498
0
        if ((HighestIndex == DriverBindingHandleCount) || (DriverFamilyOverrideVersion > HighestVersion)) {
499
0
          HighestVersion = DriverFamilyOverrideVersion;
500
0
          HighestIndex   = Index;
501
0
        }
502
0
      }
503
0
    }
504
505
0
    if (HighestIndex == DriverBindingHandleCount) {
506
0
      break;
507
0
    }
508
509
0
    AddSortedDriverBindingProtocol (
510
0
      DriverBindingHandleBuffer[HighestIndex],
511
0
      &NumberOfSortedDriverBindingProtocols,
512
0
      SortedDriverBindingProtocols,
513
0
      DriverBindingHandleCount,
514
0
      DriverBindingHandleBuffer,
515
0
      FALSE
516
0
      );
517
0
  }
518
519
  //
520
  // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
521
  //
522
0
  Status = CoreHandleProtocol (
523
0
             ControllerHandle,
524
0
             &gEfiBusSpecificDriverOverrideProtocolGuid,
525
0
             (VOID **) &BusSpecificDriverOverride
526
0
             );
527
0
  if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {
528
0
    DriverImageHandle = NULL;
529
0
    do {
530
0
      Status = BusSpecificDriverOverride->GetDriver (
531
0
                                            BusSpecificDriverOverride,
532
0
                                            &DriverImageHandle
533
0
                                            );
534
0
      if (!EFI_ERROR (Status)) {
535
0
        AddSortedDriverBindingProtocol (
536
0
          DriverImageHandle,
537
0
          &NumberOfSortedDriverBindingProtocols,
538
0
          SortedDriverBindingProtocols,
539
0
          DriverBindingHandleCount,
540
0
          DriverBindingHandleBuffer,
541
0
          TRUE
542
0
          );
543
0
      }
544
0
    } while (!EFI_ERROR (Status));
545
0
  }
546
547
  //
548
  // Then add all the remaining Driver Binding Protocols
549
  //
550
0
  SortIndex = NumberOfSortedDriverBindingProtocols;
551
0
  for (Index = 0; Index < DriverBindingHandleCount; Index++) {
552
0
    AddSortedDriverBindingProtocol (
553
0
      DriverBindingHandleBuffer[Index],
554
0
      &NumberOfSortedDriverBindingProtocols,
555
0
      SortedDriverBindingProtocols,
556
0
      DriverBindingHandleCount,
557
0
      DriverBindingHandleBuffer,
558
0
      FALSE
559
0
      );
560
0
  }
561
562
  //
563
  // Free the Driver Binding Handle Buffer
564
  //
565
0
  CoreFreePool (DriverBindingHandleBuffer);
566
567
  //
568
  // If the number of Driver Binding Protocols has increased since this function started, then return
569
  // EFI_NOT_READY, so it will be restarted
570
  //
571
0
  Status = CoreLocateHandleBuffer (
572
0
             ByProtocol,
573
0
             &gEfiDriverBindingProtocolGuid,
574
0
             NULL,
575
0
             &NewDriverBindingHandleCount,
576
0
             &NewDriverBindingHandleBuffer
577
0
             );
578
0
  CoreFreePool (NewDriverBindingHandleBuffer);
579
0
  if (NewDriverBindingHandleCount > DriverBindingHandleCount) {
580
    //
581
    // Free any buffers that were allocated with AllocatePool()
582
    //
583
0
    CoreFreePool (SortedDriverBindingProtocols);
584
585
0
    return EFI_NOT_READY;
586
0
  }
587
588
  //
589
  // Sort the remaining DriverBinding Protocol based on their Version field from
590
  // highest to lowest.
591
  //
592
0
  for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) {
593
0
    HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;
594
0
    HighestIndex   = SortIndex;
595
0
    for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) {
596
0
      if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {
597
0
        HighestVersion = SortedDriverBindingProtocols[Index]->Version;
598
0
        HighestIndex   = Index;
599
0
      }
600
0
    }
601
0
    if (SortIndex != HighestIndex) {
602
0
      DriverBinding = SortedDriverBindingProtocols[SortIndex];
603
0
      SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];
604
0
      SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
605
0
    }
606
0
  }
607
608
  //
609
  // Loop until no more drivers can be started on ControllerHandle
610
  //
611
0
  OneStarted = FALSE;
612
0
  do {
613
614
    //
615
    // Loop through the sorted Driver Binding Protocol Instances in order, and see if
616
    // any of the Driver Binding Protocols support the controller specified by
617
    // ControllerHandle.
618
    //
619
0
    DriverBinding = NULL;
620
0
    DriverFound = FALSE;
621
0
    for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {
622
0
      if (SortedDriverBindingProtocols[Index] != NULL) {
623
0
        DriverBinding = SortedDriverBindingProtocols[Index];
624
0
        Status = DriverBinding->Supported(
625
0
                                  DriverBinding,
626
0
                                  ControllerHandle,
627
0
                                  RemainingDevicePath
628
0
                                  );
629
0
        if (!EFI_ERROR (Status)) {
630
0
          SortedDriverBindingProtocols[Index] = NULL;
631
0
          DriverFound = TRUE;
632
633
          //
634
          // A driver was found that supports ControllerHandle, so attempt to start the driver
635
          // on ControllerHandle.
636
          //
637
0
          Status = DriverBinding->Start (
638
0
                                    DriverBinding,
639
0
                                    ControllerHandle,
640
0
                                    RemainingDevicePath
641
0
                                    );
642
0
          if (!EFI_ERROR (Status)) {
643
            //
644
            // The driver was successfully started on ControllerHandle, so set a flag
645
            //
646
0
            OneStarted = TRUE;
647
0
          }
648
0
        }
649
0
      }
650
0
    }
651
0
  } while (DriverFound);
652
653
  //
654
  // Free any buffers that were allocated with AllocatePool()
655
  //
656
0
  CoreFreePool (SortedDriverBindingProtocols);
657
658
  //
659
  // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
660
  //
661
0
  if (OneStarted) {
662
0
    return EFI_SUCCESS;
663
0
  }
664
665
  //
666
  // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
667
  //
668
0
  if (RemainingDevicePath != NULL) {
669
0
    if (IsDevicePathEnd (RemainingDevicePath)) {
670
0
      return EFI_SUCCESS;
671
0
    }
672
0
  }
673
674
  //
675
  // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
676
  //
677
0
  return EFI_NOT_FOUND;
678
0
}
679
680
681
682
/**
683
  Disonnects a controller from a driver
684
685
  @param  ControllerHandle                      ControllerHandle The handle of
686
                                                the controller from which
687
                                                driver(s)  are to be
688
                                                disconnected.
689
  @param  DriverImageHandle                     DriverImageHandle The driver to
690
                                                disconnect from ControllerHandle.
691
  @param  ChildHandle                           ChildHandle The handle of the
692
                                                child to destroy.
693
694
  @retval EFI_SUCCESS                           One or more drivers were
695
                                                disconnected from the controller.
696
  @retval EFI_SUCCESS                           On entry, no drivers are managing
697
                                                ControllerHandle.
698
  @retval EFI_SUCCESS                           DriverImageHandle is not NULL,
699
                                                and on entry DriverImageHandle is
700
                                                not managing ControllerHandle.
701
  @retval EFI_INVALID_PARAMETER                 ControllerHandle is NULL.
702
  @retval EFI_INVALID_PARAMETER                 DriverImageHandle is not NULL,
703
                                                and it is not a valid EFI_HANDLE.
704
  @retval EFI_INVALID_PARAMETER                 ChildHandle is not NULL, and it
705
                                                is not a valid EFI_HANDLE.
706
  @retval EFI_OUT_OF_RESOURCES                  There are not enough resources
707
                                                available to disconnect any
708
                                                drivers from ControllerHandle.
709
  @retval EFI_DEVICE_ERROR                      The controller could not be
710
                                                disconnected because of a device
711
                                                error.
712
713
**/
714
EFI_STATUS
715
EFIAPI
716
CoreDisconnectController (
717
  IN  EFI_HANDLE  ControllerHandle,
718
  IN  EFI_HANDLE  DriverImageHandle  OPTIONAL,
719
  IN  EFI_HANDLE  ChildHandle        OPTIONAL
720
  )
721
0
{
722
0
  EFI_STATUS                          Status;
723
0
  IHANDLE                             *Handle;
724
0
  EFI_HANDLE                          *DriverImageHandleBuffer;
725
0
  EFI_HANDLE                          *ChildBuffer;
726
0
  UINTN                               Index;
727
0
  UINTN                               HandleIndex;
728
0
  UINTN                               DriverImageHandleCount;
729
0
  UINTN                               ChildrenToStop;
730
0
  UINTN                               ChildBufferCount;
731
0
  UINTN                               StopCount;
732
0
  BOOLEAN                             Duplicate;
733
0
  BOOLEAN                             ChildHandleValid;
734
0
  BOOLEAN                             DriverImageHandleValid;
735
0
  LIST_ENTRY                          *Link;
736
0
  LIST_ENTRY                          *ProtLink;
737
0
  OPEN_PROTOCOL_DATA                  *OpenData;
738
0
  PROTOCOL_INTERFACE                  *Prot;
739
0
  EFI_DRIVER_BINDING_PROTOCOL         *DriverBinding;
740
741
  //
742
  // Make sure ControllerHandle is valid
743
  //
744
0
  Status = CoreValidateHandle (ControllerHandle);
745
0
  if (EFI_ERROR (Status)) {
746
0
    return Status;
747
0
  }
748
749
  //
750
  // Make sure ChildHandle is valid if it is not NULL
751
  //
752
0
  if (ChildHandle != NULL) {
753
0
    Status = CoreValidateHandle (ChildHandle);
754
0
    if (EFI_ERROR (Status)) {
755
0
      return Status;
756
0
    }
757
0
  }
758
759
0
  Handle = ControllerHandle;
760
761
  //
762
  // Get list of drivers that are currently managing ControllerHandle
763
  //
764
0
  DriverImageHandleBuffer = NULL;
765
0
  DriverImageHandleCount  = 1;
766
767
0
  if (DriverImageHandle == NULL) {
768
    //
769
    // Look at each protocol interface for a match
770
    //
771
0
    DriverImageHandleCount = 0;
772
773
0
    CoreAcquireProtocolLock ();
774
0
    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
775
0
      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
776
0
      for (ProtLink = Prot->OpenList.ForwardLink;
777
0
           ProtLink != &Prot->OpenList;
778
0
           ProtLink = ProtLink->ForwardLink) {
779
0
        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
780
0
        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
781
0
          DriverImageHandleCount++;
782
0
        }
783
0
      }
784
0
    }
785
0
    CoreReleaseProtocolLock ();
786
787
    //
788
    // If there are no drivers managing this controller, then return EFI_SUCCESS
789
    //
790
0
    if (DriverImageHandleCount == 0) {
791
0
      Status = EFI_SUCCESS;
792
0
      goto Done;
793
0
    }
794
795
0
    DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE) * DriverImageHandleCount);
796
0
    if (DriverImageHandleBuffer == NULL) {
797
0
      Status = EFI_OUT_OF_RESOURCES;
798
0
      goto Done;
799
0
    }
800
801
0
    DriverImageHandleCount = 0;
802
803
0
    CoreAcquireProtocolLock ();
804
0
    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
805
0
      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
806
0
      for (ProtLink = Prot->OpenList.ForwardLink;
807
0
           ProtLink != &Prot->OpenList;
808
0
           ProtLink = ProtLink->ForwardLink) {
809
0
        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
810
0
        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
811
0
          Duplicate = FALSE;
812
0
          for (Index = 0; Index< DriverImageHandleCount; Index++) {
813
0
            if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) {
814
0
              Duplicate = TRUE;
815
0
              break;
816
0
            }
817
0
          }
818
0
          if (!Duplicate) {
819
0
            DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle;
820
0
            DriverImageHandleCount++;
821
0
          }
822
0
        }
823
0
      }
824
0
    }
825
0
    CoreReleaseProtocolLock ();
826
0
  }
827
828
0
  StopCount = 0;
829
0
  for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) {
830
831
0
    if (DriverImageHandleBuffer != NULL) {
832
0
      DriverImageHandle = DriverImageHandleBuffer[HandleIndex];
833
0
    }
834
835
    //
836
    // Get the Driver Binding Protocol of the driver that is managing this controller
837
    //
838
0
    Status = CoreHandleProtocol (
839
0
               DriverImageHandle,
840
0
               &gEfiDriverBindingProtocolGuid,
841
0
               (VOID **)&DriverBinding
842
0
               );
843
0
    if (EFI_ERROR (Status) || DriverBinding == NULL) {
844
0
      Status = EFI_INVALID_PARAMETER;
845
0
      goto Done;
846
0
    }
847
848
    //
849
    // Look at each protocol interface for a match
850
    //
851
0
    DriverImageHandleValid = FALSE;
852
0
    ChildBufferCount = 0;
853
854
0
    CoreAcquireProtocolLock ();
855
0
    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
856
0
      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
857
0
      for (ProtLink = Prot->OpenList.ForwardLink;
858
0
           ProtLink != &Prot->OpenList;
859
0
           ProtLink = ProtLink->ForwardLink) {
860
0
        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
861
0
        if (OpenData->AgentHandle == DriverImageHandle) {
862
0
          if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
863
0
            ChildBufferCount++;
864
0
          }
865
0
          if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
866
0
            DriverImageHandleValid = TRUE;
867
0
          }
868
0
        }
869
0
      }
870
0
    }
871
0
    CoreReleaseProtocolLock ();
872
873
0
    if (DriverImageHandleValid) {
874
0
      ChildHandleValid = FALSE;
875
0
      ChildBuffer = NULL;
876
0
      if (ChildBufferCount != 0) {
877
0
        ChildBuffer = AllocatePool (sizeof (EFI_HANDLE) * ChildBufferCount);
878
0
        if (ChildBuffer == NULL) {
879
0
          Status = EFI_OUT_OF_RESOURCES;
880
0
          goto Done;
881
0
        }
882
883
0
        ChildBufferCount = 0;
884
885
0
        CoreAcquireProtocolLock ();
886
0
        for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
887
0
          Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
888
0
          for (ProtLink = Prot->OpenList.ForwardLink;
889
0
               ProtLink != &Prot->OpenList;
890
0
               ProtLink = ProtLink->ForwardLink) {
891
0
            OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
892
0
            if ((OpenData->AgentHandle == DriverImageHandle) &&
893
0
                ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) {
894
0
              Duplicate = FALSE;
895
0
              for (Index = 0; Index < ChildBufferCount; Index++) {
896
0
                if (ChildBuffer[Index] == OpenData->ControllerHandle) {
897
0
                  Duplicate = TRUE;
898
0
                  break;
899
0
                }
900
0
              }
901
0
              if (!Duplicate) {
902
0
                ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle;
903
0
                if (ChildHandle == ChildBuffer[ChildBufferCount]) {
904
0
                  ChildHandleValid = TRUE;
905
0
                }
906
0
                ChildBufferCount++;
907
0
              }
908
0
            }
909
0
          }
910
0
        }
911
0
        CoreReleaseProtocolLock ();
912
0
      }
913
914
0
      if (ChildHandle == NULL || ChildHandleValid) {
915
0
        ChildrenToStop = 0;
916
0
        Status = EFI_SUCCESS;
917
0
        if (ChildBufferCount > 0) {
918
0
          if (ChildHandle != NULL) {
919
0
            ChildrenToStop = 1;
920
0
            Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);
921
0
          } else {
922
0
            ChildrenToStop = ChildBufferCount;
923
0
            Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);
924
0
          }
925
0
        }
926
0
        if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) {
927
0
          Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);
928
0
        }
929
0
        if (!EFI_ERROR (Status)) {
930
0
          StopCount++;
931
0
        }
932
0
      }
933
934
0
      if (ChildBuffer != NULL) {
935
0
        CoreFreePool (ChildBuffer);
936
0
      }
937
0
    }
938
0
  }
939
940
0
  if (StopCount > 0) {
941
0
    Status = EFI_SUCCESS;
942
0
  } else {
943
0
    Status = EFI_NOT_FOUND;
944
0
  }
945
946
0
Done:
947
948
0
  if (DriverImageHandleBuffer != NULL) {
949
0
    CoreFreePool (DriverImageHandleBuffer);
950
0
  }
951
952
0
  return Status;
953
0
}