]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.c
MdeModulePkg/UsbBus: Fix various typos
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusDxe / UsbUtility.c
... / ...
CommitLineData
1/** @file\r
2\r
3 Wrapper function for usb host controller interface.\r
4\r
5Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
6SPDX-License-Identifier: BSD-2-Clause-Patent\r
7\r
8**/\r
9\r
10\r
11#include "UsbBus.h"\r
12\r
13//\r
14// if RemainingDevicePath== NULL, then all Usb child devices in this bus are wanted.\r
15// Use a shor form Usb class Device Path, which could match any usb device, in WantedUsbIoDPList to indicate all Usb devices\r
16// are wanted Usb devices\r
17//\r
18USB_CLASS_FORMAT_DEVICE_PATH mAllUsbClassDevicePath = {\r
19 {\r
20 {\r
21 MESSAGING_DEVICE_PATH,\r
22 MSG_USB_CLASS_DP,\r
23 {\r
24 (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)),\r
25 (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)\r
26 }\r
27 },\r
28 0xffff, // VendorId\r
29 0xffff, // ProductId\r
30 0xff, // DeviceClass\r
31 0xff, // DeviceSubClass\r
32 0xff // DeviceProtocol\r
33 },\r
34\r
35 {\r
36 END_DEVICE_PATH_TYPE,\r
37 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
38 {\r
39 END_DEVICE_PATH_LENGTH,\r
40 0\r
41 }\r
42 }\r
43};\r
44\r
45\r
46/**\r
47 Get the capability of the host controller.\r
48\r
49 @param UsbBus The usb driver.\r
50 @param MaxSpeed The maximum speed this host controller supports.\r
51 @param NumOfPort The number of the root hub port.\r
52 @param Is64BitCapable Whether this controller support 64 bit addressing.\r
53\r
54 @retval EFI_SUCCESS The host controller capability is returned.\r
55 @retval Others Failed to retrieve the host controller capability.\r
56\r
57**/\r
58EFI_STATUS\r
59UsbHcGetCapability (\r
60 IN USB_BUS *UsbBus,\r
61 OUT UINT8 *MaxSpeed,\r
62 OUT UINT8 *NumOfPort,\r
63 OUT UINT8 *Is64BitCapable\r
64 )\r
65{\r
66 EFI_STATUS Status;\r
67\r
68 if (UsbBus->Usb2Hc != NULL) {\r
69 Status = UsbBus->Usb2Hc->GetCapability (\r
70 UsbBus->Usb2Hc,\r
71 MaxSpeed,\r
72 NumOfPort,\r
73 Is64BitCapable\r
74 );\r
75\r
76 } else {\r
77 Status = UsbBus->UsbHc->GetRootHubPortNumber (UsbBus->UsbHc, NumOfPort);\r
78\r
79 *MaxSpeed = EFI_USB_SPEED_FULL;\r
80 *Is64BitCapable = (UINT8) FALSE;\r
81 }\r
82\r
83 return Status;\r
84}\r
85\r
86\r
87\r
88\r
89\r
90\r
91\r
92\r
93\r
94\r
95/**\r
96 Get the root hub port state.\r
97\r
98 @param UsbBus The USB bus driver.\r
99 @param PortIndex The index of port.\r
100 @param PortStatus The variable to save port state.\r
101\r
102 @retval EFI_SUCCESS The root port state is returned in.\r
103 @retval Others Failed to get the root hub port state.\r
104\r
105**/\r
106EFI_STATUS\r
107UsbHcGetRootHubPortStatus (\r
108 IN USB_BUS *UsbBus,\r
109 IN UINT8 PortIndex,\r
110 OUT EFI_USB_PORT_STATUS *PortStatus\r
111 )\r
112{\r
113 EFI_STATUS Status;\r
114\r
115 if (UsbBus->Usb2Hc != NULL) {\r
116 Status = UsbBus->Usb2Hc->GetRootHubPortStatus (UsbBus->Usb2Hc, PortIndex, PortStatus);\r
117 } else {\r
118 Status = UsbBus->UsbHc->GetRootHubPortStatus (UsbBus->UsbHc, PortIndex, PortStatus);\r
119 }\r
120\r
121 return Status;\r
122}\r
123\r
124\r
125/**\r
126 Set the root hub port feature.\r
127\r
128 @param UsbBus The USB bus driver.\r
129 @param PortIndex The port index.\r
130 @param Feature The port feature to set.\r
131\r
132 @retval EFI_SUCCESS The port feature is set.\r
133 @retval Others Failed to set port feature.\r
134\r
135**/\r
136EFI_STATUS\r
137UsbHcSetRootHubPortFeature (\r
138 IN USB_BUS *UsbBus,\r
139 IN UINT8 PortIndex,\r
140 IN EFI_USB_PORT_FEATURE Feature\r
141 )\r
142{\r
143 EFI_STATUS Status;\r
144\r
145\r
146 if (UsbBus->Usb2Hc != NULL) {\r
147 Status = UsbBus->Usb2Hc->SetRootHubPortFeature (UsbBus->Usb2Hc, PortIndex, Feature);\r
148 } else {\r
149 Status = UsbBus->UsbHc->SetRootHubPortFeature (UsbBus->UsbHc, PortIndex, Feature);\r
150 }\r
151\r
152 return Status;\r
153}\r
154\r
155\r
156/**\r
157 Clear the root hub port feature.\r
158\r
159 @param UsbBus The USB bus driver.\r
160 @param PortIndex The port index.\r
161 @param Feature The port feature to clear.\r
162\r
163 @retval EFI_SUCCESS The port feature is clear.\r
164 @retval Others Failed to clear port feature.\r
165\r
166**/\r
167EFI_STATUS\r
168UsbHcClearRootHubPortFeature (\r
169 IN USB_BUS *UsbBus,\r
170 IN UINT8 PortIndex,\r
171 IN EFI_USB_PORT_FEATURE Feature\r
172 )\r
173{\r
174 EFI_STATUS Status;\r
175\r
176 if (UsbBus->Usb2Hc != NULL) {\r
177 Status = UsbBus->Usb2Hc->ClearRootHubPortFeature (UsbBus->Usb2Hc, PortIndex, Feature);\r
178 } else {\r
179 Status = UsbBus->UsbHc->ClearRootHubPortFeature (UsbBus->UsbHc, PortIndex, Feature);\r
180 }\r
181\r
182 return Status;\r
183}\r
184\r
185\r
186/**\r
187 Execute a control transfer to the device.\r
188\r
189 @param UsbBus The USB bus driver.\r
190 @param DevAddr The device address.\r
191 @param DevSpeed The device speed.\r
192 @param MaxPacket Maximum packet size of endpoint 0.\r
193 @param Request The control transfer request.\r
194 @param Direction The direction of data stage.\r
195 @param Data The buffer holding data.\r
196 @param DataLength The length of the data.\r
197 @param TimeOut Timeout (in ms) to wait until timeout.\r
198 @param Translator The transaction translator for low/full speed device.\r
199 @param UsbResult The result of transfer.\r
200\r
201 @retval EFI_SUCCESS The control transfer finished without error.\r
202 @retval Others The control transfer failed, reason returned in UsbReslt.\r
203\r
204**/\r
205EFI_STATUS\r
206UsbHcControlTransfer (\r
207 IN USB_BUS *UsbBus,\r
208 IN UINT8 DevAddr,\r
209 IN UINT8 DevSpeed,\r
210 IN UINTN MaxPacket,\r
211 IN EFI_USB_DEVICE_REQUEST *Request,\r
212 IN EFI_USB_DATA_DIRECTION Direction,\r
213 IN OUT VOID *Data,\r
214 IN OUT UINTN *DataLength,\r
215 IN UINTN TimeOut,\r
216 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
217 OUT UINT32 *UsbResult\r
218 )\r
219{\r
220 EFI_STATUS Status;\r
221 BOOLEAN IsSlowDevice;\r
222\r
223 if (UsbBus->Usb2Hc != NULL) {\r
224 Status = UsbBus->Usb2Hc->ControlTransfer (\r
225 UsbBus->Usb2Hc,\r
226 DevAddr,\r
227 DevSpeed,\r
228 MaxPacket,\r
229 Request,\r
230 Direction,\r
231 Data,\r
232 DataLength,\r
233 TimeOut,\r
234 Translator,\r
235 UsbResult\r
236 );\r
237\r
238 } else {\r
239 IsSlowDevice = (BOOLEAN)(EFI_USB_SPEED_LOW == DevSpeed);\r
240 Status = UsbBus->UsbHc->ControlTransfer (\r
241 UsbBus->UsbHc,\r
242 DevAddr,\r
243 IsSlowDevice,\r
244 (UINT8) MaxPacket,\r
245 Request,\r
246 Direction,\r
247 Data,\r
248 DataLength,\r
249 TimeOut,\r
250 UsbResult\r
251 );\r
252 }\r
253\r
254 return Status;\r
255}\r
256\r
257\r
258/**\r
259 Execute a bulk transfer to the device's endpoint.\r
260\r
261 @param UsbBus The USB bus driver.\r
262 @param DevAddr The target device address.\r
263 @param EpAddr The target endpoint address, with direction encoded in\r
264 bit 7.\r
265 @param DevSpeed The device's speed.\r
266 @param MaxPacket The endpoint's max packet size.\r
267 @param BufferNum The number of data buffer.\r
268 @param Data Array of pointers to data buffer.\r
269 @param DataLength The length of data buffer.\r
270 @param DataToggle On input, the initial data toggle to use, also return\r
271 the next toggle on output.\r
272 @param TimeOut The time to wait until timeout.\r
273 @param Translator The transaction translator for low/full speed device.\r
274 @param UsbResult The result of USB execution.\r
275\r
276 @retval EFI_SUCCESS The bulk transfer is finished without error.\r
277 @retval Others Failed to execute bulk transfer, result in UsbResult.\r
278\r
279**/\r
280EFI_STATUS\r
281UsbHcBulkTransfer (\r
282 IN USB_BUS *UsbBus,\r
283 IN UINT8 DevAddr,\r
284 IN UINT8 EpAddr,\r
285 IN UINT8 DevSpeed,\r
286 IN UINTN MaxPacket,\r
287 IN UINT8 BufferNum,\r
288 IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
289 IN OUT UINTN *DataLength,\r
290 IN OUT UINT8 *DataToggle,\r
291 IN UINTN TimeOut,\r
292 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
293 OUT UINT32 *UsbResult\r
294 )\r
295{\r
296 EFI_STATUS Status;\r
297\r
298 if (UsbBus->Usb2Hc != NULL) {\r
299 Status = UsbBus->Usb2Hc->BulkTransfer (\r
300 UsbBus->Usb2Hc,\r
301 DevAddr,\r
302 EpAddr,\r
303 DevSpeed,\r
304 MaxPacket,\r
305 BufferNum,\r
306 Data,\r
307 DataLength,\r
308 DataToggle,\r
309 TimeOut,\r
310 Translator,\r
311 UsbResult\r
312 );\r
313 } else {\r
314 Status = UsbBus->UsbHc->BulkTransfer (\r
315 UsbBus->UsbHc,\r
316 DevAddr,\r
317 EpAddr,\r
318 (UINT8) MaxPacket,\r
319 *Data,\r
320 DataLength,\r
321 DataToggle,\r
322 TimeOut,\r
323 UsbResult\r
324 );\r
325 }\r
326\r
327 return Status;\r
328}\r
329\r
330\r
331/**\r
332 Queue or cancel an asynchronous interrupt transfer.\r
333\r
334 @param UsbBus The USB bus driver.\r
335 @param DevAddr The target device address.\r
336 @param EpAddr The target endpoint address, with direction encoded in\r
337 bit 7.\r
338 @param DevSpeed The device's speed.\r
339 @param MaxPacket The endpoint's max packet size.\r
340 @param IsNewTransfer Whether this is a new request. If not, cancel the old\r
341 request.\r
342 @param DataToggle Data toggle to use on input, next toggle on output.\r
343 @param PollingInterval The interval to poll the interrupt transfer (in ms).\r
344 @param DataLength The length of periodical data receive.\r
345 @param Translator The transaction translator for low/full speed device.\r
346 @param Callback Function to call when data is received.\r
347 @param Context The context to the callback.\r
348\r
349 @retval EFI_SUCCESS The asynchronous transfer is queued.\r
350 @retval Others Failed to queue the transfer.\r
351\r
352**/\r
353EFI_STATUS\r
354UsbHcAsyncInterruptTransfer (\r
355 IN USB_BUS *UsbBus,\r
356 IN UINT8 DevAddr,\r
357 IN UINT8 EpAddr,\r
358 IN UINT8 DevSpeed,\r
359 IN UINTN MaxPacket,\r
360 IN BOOLEAN IsNewTransfer,\r
361 IN OUT UINT8 *DataToggle,\r
362 IN UINTN PollingInterval,\r
363 IN UINTN DataLength,\r
364 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
365 IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,\r
366 IN VOID *Context OPTIONAL\r
367 )\r
368{\r
369 EFI_STATUS Status;\r
370 BOOLEAN IsSlowDevice;\r
371\r
372 if (UsbBus->Usb2Hc != NULL) {\r
373 Status = UsbBus->Usb2Hc->AsyncInterruptTransfer (\r
374 UsbBus->Usb2Hc,\r
375 DevAddr,\r
376 EpAddr,\r
377 DevSpeed,\r
378 MaxPacket,\r
379 IsNewTransfer,\r
380 DataToggle,\r
381 PollingInterval,\r
382 DataLength,\r
383 Translator,\r
384 Callback,\r
385 Context\r
386 );\r
387 } else {\r
388 IsSlowDevice = (BOOLEAN)(EFI_USB_SPEED_LOW == DevSpeed);\r
389\r
390 Status = UsbBus->UsbHc->AsyncInterruptTransfer (\r
391 UsbBus->UsbHc,\r
392 DevAddr,\r
393 EpAddr,\r
394 IsSlowDevice,\r
395 (UINT8) MaxPacket,\r
396 IsNewTransfer,\r
397 DataToggle,\r
398 PollingInterval,\r
399 DataLength,\r
400 Callback,\r
401 Context\r
402 );\r
403 }\r
404\r
405 return Status;\r
406}\r
407\r
408\r
409/**\r
410 Execute a synchronous interrupt transfer to the target endpoint.\r
411\r
412 @param UsbBus The USB bus driver.\r
413 @param DevAddr The target device address.\r
414 @param EpAddr The target endpoint address, with direction encoded in\r
415 bit 7.\r
416 @param DevSpeed The device's speed.\r
417 @param MaxPacket The endpoint's max packet size.\r
418 @param Data Pointer to data buffer.\r
419 @param DataLength The length of data buffer.\r
420 @param DataToggle On input, the initial data toggle to use, also return\r
421 the next toggle on output.\r
422 @param TimeOut The time to wait until timeout.\r
423 @param Translator The transaction translator for low/full speed device.\r
424 @param UsbResult The result of USB execution.\r
425\r
426 @retval EFI_SUCCESS The synchronous interrupt transfer is OK.\r
427 @retval Others Failed to execute the synchronous interrupt transfer.\r
428\r
429**/\r
430EFI_STATUS\r
431UsbHcSyncInterruptTransfer (\r
432 IN USB_BUS *UsbBus,\r
433 IN UINT8 DevAddr,\r
434 IN UINT8 EpAddr,\r
435 IN UINT8 DevSpeed,\r
436 IN UINTN MaxPacket,\r
437 IN OUT VOID *Data,\r
438 IN OUT UINTN *DataLength,\r
439 IN OUT UINT8 *DataToggle,\r
440 IN UINTN TimeOut,\r
441 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
442 OUT UINT32 *UsbResult\r
443 )\r
444{\r
445 EFI_STATUS Status;\r
446 BOOLEAN IsSlowDevice;\r
447\r
448 if (UsbBus->Usb2Hc != NULL) {\r
449 Status = UsbBus->Usb2Hc->SyncInterruptTransfer (\r
450 UsbBus->Usb2Hc,\r
451 DevAddr,\r
452 EpAddr,\r
453 DevSpeed,\r
454 MaxPacket,\r
455 Data,\r
456 DataLength,\r
457 DataToggle,\r
458 TimeOut,\r
459 Translator,\r
460 UsbResult\r
461 );\r
462 } else {\r
463 IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DevSpeed) ? TRUE : FALSE);\r
464 Status = UsbBus->UsbHc->SyncInterruptTransfer (\r
465 UsbBus->UsbHc,\r
466 DevAddr,\r
467 EpAddr,\r
468 IsSlowDevice,\r
469 (UINT8) MaxPacket,\r
470 Data,\r
471 DataLength,\r
472 DataToggle,\r
473 TimeOut,\r
474 UsbResult\r
475 );\r
476 }\r
477\r
478 return Status;\r
479}\r
480\r
481\r
482\r
483\r
484\r
485\r
486\r
487\r
488/**\r
489 Open the USB host controller protocol BY_CHILD.\r
490\r
491 @param Bus The USB bus driver.\r
492 @param Child The child handle.\r
493\r
494 @return The open protocol return.\r
495\r
496**/\r
497EFI_STATUS\r
498UsbOpenHostProtoByChild (\r
499 IN USB_BUS *Bus,\r
500 IN EFI_HANDLE Child\r
501 )\r
502{\r
503 EFI_USB_HC_PROTOCOL *UsbHc;\r
504 EFI_USB2_HC_PROTOCOL *Usb2Hc;\r
505 EFI_STATUS Status;\r
506\r
507 if (Bus->Usb2Hc != NULL) {\r
508 Status = gBS->OpenProtocol (\r
509 Bus->HostHandle,\r
510 &gEfiUsb2HcProtocolGuid,\r
511 (VOID **) &Usb2Hc,\r
512 mUsbBusDriverBinding.DriverBindingHandle,\r
513 Child,\r
514 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
515 );\r
516\r
517 } else {\r
518 Status = gBS->OpenProtocol (\r
519 Bus->HostHandle,\r
520 &gEfiUsbHcProtocolGuid,\r
521 (VOID **) &UsbHc,\r
522 mUsbBusDriverBinding.DriverBindingHandle,\r
523 Child,\r
524 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
525 );\r
526 }\r
527\r
528 return Status;\r
529}\r
530\r
531\r
532/**\r
533 Close the USB host controller protocol BY_CHILD.\r
534\r
535 @param Bus The USB bus driver.\r
536 @param Child The child handle.\r
537\r
538**/\r
539VOID\r
540UsbCloseHostProtoByChild (\r
541 IN USB_BUS *Bus,\r
542 IN EFI_HANDLE Child\r
543 )\r
544{\r
545 if (Bus->Usb2Hc != NULL) {\r
546 gBS->CloseProtocol (\r
547 Bus->HostHandle,\r
548 &gEfiUsb2HcProtocolGuid,\r
549 mUsbBusDriverBinding.DriverBindingHandle,\r
550 Child\r
551 );\r
552\r
553 } else {\r
554 gBS->CloseProtocol (\r
555 Bus->HostHandle,\r
556 &gEfiUsbHcProtocolGuid,\r
557 mUsbBusDriverBinding.DriverBindingHandle,\r
558 Child\r
559 );\r
560 }\r
561}\r
562\r
563\r
564/**\r
565 return the current TPL, copied from the EDKII glue lib.\r
566\r
567 @param VOID.\r
568\r
569 @return Current TPL.\r
570\r
571**/\r
572EFI_TPL\r
573UsbGetCurrentTpl (\r
574 VOID\r
575 )\r
576{\r
577 EFI_TPL Tpl;\r
578\r
579 Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
580 gBS->RestoreTPL (Tpl);\r
581\r
582 return Tpl;\r
583}\r
584\r
585/**\r
586 Create a new device path which only contain the first Usb part of the DevicePath.\r
587\r
588 @param DevicePath A full device path which contain the usb nodes.\r
589\r
590 @return A new device path which only contain the Usb part of the DevicePath.\r
591\r
592**/\r
593EFI_DEVICE_PATH_PROTOCOL *\r
594EFIAPI\r
595GetUsbDPFromFullDP (\r
596 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
597 )\r
598{\r
599 EFI_DEVICE_PATH_PROTOCOL *UsbDevicePathPtr;\r
600 EFI_DEVICE_PATH_PROTOCOL *UsbDevicePathBeginPtr;\r
601 EFI_DEVICE_PATH_PROTOCOL *UsbDevicePathEndPtr;\r
602 UINTN Size;\r
603\r
604 //\r
605 // Get the Usb part first Begin node in full device path\r
606 //\r
607 UsbDevicePathBeginPtr = DevicePath;\r
608 while ( (!IsDevicePathEnd (UsbDevicePathBeginPtr))&&\r
609 ((UsbDevicePathBeginPtr->Type != MESSAGING_DEVICE_PATH) ||\r
610 (UsbDevicePathBeginPtr->SubType != MSG_USB_DP &&\r
611 UsbDevicePathBeginPtr->SubType != MSG_USB_CLASS_DP\r
612 && UsbDevicePathBeginPtr->SubType != MSG_USB_WWID_DP\r
613 ))) {\r
614\r
615 UsbDevicePathBeginPtr = NextDevicePathNode(UsbDevicePathBeginPtr);\r
616 }\r
617\r
618 //\r
619 // Get the Usb part first End node in full device path\r
620 //\r
621 UsbDevicePathEndPtr = UsbDevicePathBeginPtr;\r
622 while ((!IsDevicePathEnd (UsbDevicePathEndPtr))&&\r
623 (UsbDevicePathEndPtr->Type == MESSAGING_DEVICE_PATH) &&\r
624 (UsbDevicePathEndPtr->SubType == MSG_USB_DP ||\r
625 UsbDevicePathEndPtr->SubType == MSG_USB_CLASS_DP\r
626 || UsbDevicePathEndPtr->SubType == MSG_USB_WWID_DP\r
627 )) {\r
628\r
629 UsbDevicePathEndPtr = NextDevicePathNode(UsbDevicePathEndPtr);\r
630 }\r
631\r
632 Size = GetDevicePathSize (UsbDevicePathBeginPtr);\r
633 Size -= GetDevicePathSize (UsbDevicePathEndPtr);\r
634 if (Size ==0){\r
635 //\r
636 // The passed in DevicePath does not contain the usb nodes\r
637 //\r
638 return NULL;\r
639 }\r
640\r
641 //\r
642 // Create a new device path which only contain the above Usb part\r
643 //\r
644 UsbDevicePathPtr = AllocateZeroPool (Size + sizeof (EFI_DEVICE_PATH_PROTOCOL));\r
645 ASSERT (UsbDevicePathPtr != NULL);\r
646 CopyMem (UsbDevicePathPtr, UsbDevicePathBeginPtr, Size);\r
647 //\r
648 // Append end device path node\r
649 //\r
650 UsbDevicePathEndPtr = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) UsbDevicePathPtr + Size);\r
651 SetDevicePathEndNode (UsbDevicePathEndPtr);\r
652 return UsbDevicePathPtr;\r
653}\r
654\r
655/**\r
656 Check whether a usb device path is in a DEVICE_PATH_LIST_ITEM list.\r
657\r
658 @param UsbDP a usb device path of DEVICE_PATH_LIST_ITEM.\r
659 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list.\r
660\r
661 @retval TRUE there is a DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP.\r
662 @retval FALSE there is no DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP.\r
663\r
664**/\r
665BOOLEAN\r
666EFIAPI\r
667SearchUsbDPInList (\r
668 IN EFI_DEVICE_PATH_PROTOCOL *UsbDP,\r
669 IN LIST_ENTRY *UsbIoDPList\r
670 )\r
671{\r
672 LIST_ENTRY *ListIndex;\r
673 DEVICE_PATH_LIST_ITEM *ListItem;\r
674 BOOLEAN Found;\r
675 UINTN UsbDpDevicePathSize;\r
676\r
677 //\r
678 // Check that UsbDP and UsbIoDPList are valid\r
679 //\r
680 if ((UsbIoDPList == NULL) || (UsbDP == NULL)) {\r
681 return FALSE;\r
682 }\r
683\r
684 Found = FALSE;\r
685 ListIndex = UsbIoDPList->ForwardLink;\r
686 while (ListIndex != UsbIoDPList){\r
687 ListItem = CR(ListIndex, DEVICE_PATH_LIST_ITEM, Link, DEVICE_PATH_LIST_ITEM_SIGNATURE);\r
688 //\r
689 // Compare DEVICE_PATH_LIST_ITEM.DevicePath[]\r
690 //\r
691 ASSERT (ListItem->DevicePath != NULL);\r
692\r
693 UsbDpDevicePathSize = GetDevicePathSize (UsbDP);\r
694 if (UsbDpDevicePathSize == GetDevicePathSize (ListItem->DevicePath)) {\r
695 if ((CompareMem (UsbDP, ListItem->DevicePath, UsbDpDevicePathSize)) == 0) {\r
696 Found = TRUE;\r
697 break;\r
698 }\r
699 }\r
700 ListIndex = ListIndex->ForwardLink;\r
701 }\r
702\r
703 return Found;\r
704}\r
705\r
706/**\r
707 Add a usb device path into the DEVICE_PATH_LIST_ITEM list.\r
708\r
709 @param UsbDP a usb device path of DEVICE_PATH_LIST_ITEM.\r
710 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list.\r
711\r
712 @retval EFI_INVALID_PARAMETER If parameters are invalid, return this value.\r
713 @retval EFI_SUCCESS If Add operation is successful, return this value.\r
714\r
715**/\r
716EFI_STATUS\r
717EFIAPI\r
718AddUsbDPToList (\r
719 IN EFI_DEVICE_PATH_PROTOCOL *UsbDP,\r
720 IN LIST_ENTRY *UsbIoDPList\r
721 )\r
722{\r
723 DEVICE_PATH_LIST_ITEM *ListItem;\r
724\r
725 //\r
726 // Check that UsbDP and UsbIoDPList are valid\r
727 //\r
728 if ((UsbIoDPList == NULL) || (UsbDP == NULL)) {\r
729 return EFI_INVALID_PARAMETER;\r
730 }\r
731\r
732 if (SearchUsbDPInList (UsbDP, UsbIoDPList)){\r
733 return EFI_SUCCESS;\r
734 }\r
735\r
736 //\r
737 // Prepare the usbio device path DEVICE_PATH_LIST_ITEM structure.\r
738 //\r
739 ListItem = AllocateZeroPool (sizeof (DEVICE_PATH_LIST_ITEM));\r
740 ASSERT (ListItem != NULL);\r
741 ListItem->Signature = DEVICE_PATH_LIST_ITEM_SIGNATURE;\r
742 ListItem->DevicePath = DuplicateDevicePath (UsbDP);\r
743\r
744 InsertTailList (UsbIoDPList, &ListItem->Link);\r
745\r
746 return EFI_SUCCESS;\r
747}\r
748\r
749/**\r
750 Check whether usb device, whose interface is UsbIf, matches the usb class which indicated by\r
751 UsbClassDevicePathPtr whose is a short form usb class device path.\r
752\r
753 @param UsbClassDevicePathPtr a short form usb class device path.\r
754 @param UsbIf a usb device interface.\r
755\r
756 @retval TRUE the usb device match the usb class.\r
757 @retval FALSE the usb device does not match the usb class.\r
758\r
759**/\r
760BOOLEAN\r
761EFIAPI\r
762MatchUsbClass (\r
763 IN USB_CLASS_DEVICE_PATH *UsbClassDevicePathPtr,\r
764 IN USB_INTERFACE *UsbIf\r
765 )\r
766{\r
767 USB_INTERFACE_DESC *IfDesc;\r
768 EFI_USB_INTERFACE_DESCRIPTOR *ActIfDesc;\r
769 EFI_USB_DEVICE_DESCRIPTOR *DevDesc;\r
770\r
771\r
772 if ((UsbClassDevicePathPtr->Header.Type != MESSAGING_DEVICE_PATH) ||\r
773 (UsbClassDevicePathPtr->Header.SubType != MSG_USB_CLASS_DP)){\r
774 ASSERT (0);\r
775 return FALSE;\r
776 }\r
777\r
778 IfDesc = UsbIf->IfDesc;\r
779 ASSERT (IfDesc->ActiveIndex < USB_MAX_INTERFACE_SETTING);\r
780 ActIfDesc = &(IfDesc->Settings[IfDesc->ActiveIndex]->Desc);\r
781 DevDesc = &(UsbIf->Device->DevDesc->Desc);\r
782\r
783 //\r
784 // If connect class policy, determine whether to create device handle by the five fields\r
785 // in class device path node.\r
786 //\r
787 // In addition, hub interface is always matched for this policy.\r
788 //\r
789 if ((ActIfDesc->InterfaceClass == USB_HUB_CLASS_CODE) &&\r
790 (ActIfDesc->InterfaceSubClass == USB_HUB_SUBCLASS_CODE)) {\r
791 return TRUE;\r
792 }\r
793\r
794 //\r
795 // If vendor id or product id is 0xffff, they will be ignored.\r
796 //\r
797 if ((UsbClassDevicePathPtr->VendorId == 0xffff || UsbClassDevicePathPtr->VendorId == DevDesc->IdVendor) &&\r
798 (UsbClassDevicePathPtr->ProductId == 0xffff || UsbClassDevicePathPtr->ProductId == DevDesc->IdProduct)) {\r
799\r
800 //\r
801 // If Class in Device Descriptor is set to 0, the counterparts in interface should be checked.\r
802 //\r
803 if (DevDesc->DeviceClass == 0) {\r
804 if ((UsbClassDevicePathPtr->DeviceClass == ActIfDesc->InterfaceClass ||\r
805 UsbClassDevicePathPtr->DeviceClass == 0xff) &&\r
806 (UsbClassDevicePathPtr->DeviceSubClass == ActIfDesc->InterfaceSubClass ||\r
807 UsbClassDevicePathPtr->DeviceSubClass == 0xff) &&\r
808 (UsbClassDevicePathPtr->DeviceProtocol == ActIfDesc->InterfaceProtocol ||\r
809 UsbClassDevicePathPtr->DeviceProtocol == 0xff)) {\r
810 return TRUE;\r
811 }\r
812\r
813 } else if ((UsbClassDevicePathPtr->DeviceClass == DevDesc->DeviceClass ||\r
814 UsbClassDevicePathPtr->DeviceClass == 0xff) &&\r
815 (UsbClassDevicePathPtr->DeviceSubClass == DevDesc->DeviceSubClass ||\r
816 UsbClassDevicePathPtr->DeviceSubClass == 0xff) &&\r
817 (UsbClassDevicePathPtr->DeviceProtocol == DevDesc->DeviceProtocol ||\r
818 UsbClassDevicePathPtr->DeviceProtocol == 0xff)) {\r
819\r
820 return TRUE;\r
821 }\r
822 }\r
823\r
824 return FALSE;\r
825}\r
826\r
827/**\r
828 Check whether usb device, whose interface is UsbIf, matches the usb WWID requirement which indicated by\r
829 UsbWWIDDevicePathPtr whose is a short form usb WWID device path.\r
830\r
831 @param UsbWWIDDevicePathPtr a short form usb WWID device path.\r
832 @param UsbIf a usb device interface.\r
833\r
834 @retval TRUE the usb device match the usb WWID requirement.\r
835 @retval FALSE the usb device does not match the usb WWID requirement.\r
836\r
837**/\r
838BOOLEAN\r
839MatchUsbWwid (\r
840 IN USB_WWID_DEVICE_PATH *UsbWWIDDevicePathPtr,\r
841 IN USB_INTERFACE *UsbIf\r
842 )\r
843{\r
844 USB_INTERFACE_DESC *IfDesc;\r
845 EFI_USB_INTERFACE_DESCRIPTOR *ActIfDesc;\r
846 EFI_USB_DEVICE_DESCRIPTOR *DevDesc;\r
847 EFI_USB_STRING_DESCRIPTOR *StrDesc;\r
848 UINT16 Index;\r
849 CHAR16 *CompareStr;\r
850 UINTN CompareLen;\r
851 UINTN Length;\r
852\r
853 if ((UsbWWIDDevicePathPtr->Header.Type != MESSAGING_DEVICE_PATH) ||\r
854 (UsbWWIDDevicePathPtr->Header.SubType != MSG_USB_WWID_DP )){\r
855 ASSERT (0);\r
856 return FALSE;\r
857 }\r
858\r
859 IfDesc = UsbIf->IfDesc;\r
860 ASSERT (IfDesc->ActiveIndex < USB_MAX_INTERFACE_SETTING);\r
861 ActIfDesc = &(IfDesc->Settings[IfDesc->ActiveIndex]->Desc);\r
862 DevDesc = &(UsbIf->Device->DevDesc->Desc);\r
863\r
864 //\r
865 // In addition, Hub interface is always matched for this policy.\r
866 //\r
867 if ((ActIfDesc->InterfaceClass == USB_HUB_CLASS_CODE) &&\r
868 (ActIfDesc->InterfaceSubClass == USB_HUB_SUBCLASS_CODE)) {\r
869 return TRUE;\r
870 }\r
871\r
872 //\r
873 // Check Vendor Id, Product Id and Interface Number.\r
874 //\r
875 if ((DevDesc->IdVendor != UsbWWIDDevicePathPtr->VendorId) ||\r
876 (DevDesc->IdProduct != UsbWWIDDevicePathPtr->ProductId) ||\r
877 (ActIfDesc->InterfaceNumber != UsbWWIDDevicePathPtr->InterfaceNumber)) {\r
878 return FALSE;\r
879 }\r
880\r
881 //\r
882 // Check SerialNumber.\r
883 //\r
884 if (DevDesc->StrSerialNumber == 0) {\r
885 return FALSE;\r
886 }\r
887\r
888 //\r
889 // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters.\r
890 //\r
891 CompareStr = (CHAR16 *) (UINTN) (UsbWWIDDevicePathPtr + 1);\r
892 CompareLen = (DevicePathNodeLength (UsbWWIDDevicePathPtr) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16);\r
893 if (CompareStr[CompareLen - 1] == L'\0') {\r
894 CompareLen--;\r
895 }\r
896\r
897 //\r
898 // Compare serial number in each supported language.\r
899 //\r
900 for (Index = 0; Index < UsbIf->Device->TotalLangId; Index++) {\r
901 StrDesc = UsbGetOneString (UsbIf->Device, DevDesc->StrSerialNumber, UsbIf->Device->LangId[Index]);\r
902 if (StrDesc == NULL) {\r
903 continue;\r
904 }\r
905\r
906 Length = (StrDesc->Length - 2) / sizeof (CHAR16);\r
907 if ((Length >= CompareLen) &&\r
908 (CompareMem (StrDesc->String + Length - CompareLen, CompareStr, CompareLen * sizeof (CHAR16)) == 0)) {\r
909 return TRUE;\r
910 }\r
911 }\r
912\r
913 return FALSE;\r
914}\r
915\r
916/**\r
917 Free a DEVICE_PATH_LIST_ITEM list.\r
918\r
919 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list pointer.\r
920\r
921 @retval EFI_INVALID_PARAMETER If parameters are invalid, return this value.\r
922 @retval EFI_SUCCESS If free operation is successful, return this value.\r
923\r
924**/\r
925EFI_STATUS\r
926EFIAPI\r
927UsbBusFreeUsbDPList (\r
928 IN LIST_ENTRY *UsbIoDPList\r
929 )\r
930{\r
931 LIST_ENTRY *ListIndex;\r
932 DEVICE_PATH_LIST_ITEM *ListItem;\r
933\r
934 //\r
935 // Check that ControllerHandle is a valid handle\r
936 //\r
937 if (UsbIoDPList == NULL) {\r
938 return EFI_INVALID_PARAMETER;\r
939 }\r
940\r
941 ListIndex = UsbIoDPList->ForwardLink;\r
942 while (ListIndex != UsbIoDPList){\r
943 ListItem = CR(ListIndex, DEVICE_PATH_LIST_ITEM, Link, DEVICE_PATH_LIST_ITEM_SIGNATURE);\r
944 //\r
945 // Free DEVICE_PATH_LIST_ITEM.DevicePath[]\r
946 //\r
947 if (ListItem->DevicePath != NULL){\r
948 FreePool(ListItem->DevicePath);\r
949 }\r
950 //\r
951 // Free DEVICE_PATH_LIST_ITEM itself\r
952 //\r
953 ListIndex = ListIndex->ForwardLink;\r
954 RemoveEntryList (&ListItem->Link);\r
955 FreePool (ListItem);\r
956 }\r
957\r
958 InitializeListHead (UsbIoDPList);\r
959 return EFI_SUCCESS;\r
960}\r
961\r
962/**\r
963 Store a wanted usb child device info (its Usb part of device path) which is indicated by\r
964 RemainingDevicePath in a Usb bus which is indicated by UsbBusId.\r
965\r
966 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface.\r
967 @param RemainingDevicePath The remaining device patch.\r
968\r
969 @retval EFI_SUCCESS Add operation is successful.\r
970 @retval EFI_INVALID_PARAMETER The parameters are invalid.\r
971\r
972**/\r
973EFI_STATUS\r
974EFIAPI\r
975UsbBusAddWantedUsbIoDP (\r
976 IN EFI_USB_BUS_PROTOCOL *UsbBusId,\r
977 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
978 )\r
979{\r
980 USB_BUS *Bus;\r
981 EFI_STATUS Status;\r
982 EFI_DEVICE_PATH_PROTOCOL *DevicePathPtr;\r
983\r
984 //\r
985 // Check whether remaining device path is valid\r
986 //\r
987 if (RemainingDevicePath != NULL && !IsDevicePathEnd (RemainingDevicePath)) {\r
988 if ((RemainingDevicePath->Type != MESSAGING_DEVICE_PATH) ||\r
989 (RemainingDevicePath->SubType != MSG_USB_DP &&\r
990 RemainingDevicePath->SubType != MSG_USB_CLASS_DP\r
991 && RemainingDevicePath->SubType != MSG_USB_WWID_DP\r
992 )) {\r
993 return EFI_INVALID_PARAMETER;\r
994 }\r
995 }\r
996\r
997 if (UsbBusId == NULL){\r
998 return EFI_INVALID_PARAMETER;\r
999 }\r
1000\r
1001 Bus = USB_BUS_FROM_THIS (UsbBusId);\r
1002\r
1003 if (RemainingDevicePath == NULL) {\r
1004 //\r
1005 // RemainingDevicePath == NULL means all Usb devices in this bus are wanted.\r
1006 // Here use a Usb class Device Path in WantedUsbIoDPList to indicate all Usb devices\r
1007 // are wanted Usb devices\r
1008 //\r
1009 Status = UsbBusFreeUsbDPList (&Bus->WantedUsbIoDPList);\r
1010 ASSERT (!EFI_ERROR (Status));\r
1011 DevicePathPtr = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) &mAllUsbClassDevicePath);\r
1012 } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
1013 //\r
1014 // If RemainingDevicePath isn't the End of Device Path Node,\r
1015 // Create new Usb device path according to the usb part in remaining device path\r
1016 //\r
1017 DevicePathPtr = GetUsbDPFromFullDP (RemainingDevicePath);\r
1018 } else {\r
1019 //\r
1020 // If RemainingDevicePath is the End of Device Path Node,\r
1021 // skip enumerate any device and return EFI_SUCCESS\r
1022 //\r
1023 return EFI_SUCCESS;\r
1024 }\r
1025\r
1026 ASSERT (DevicePathPtr != NULL);\r
1027 Status = AddUsbDPToList (DevicePathPtr, &Bus->WantedUsbIoDPList);\r
1028 ASSERT (!EFI_ERROR (Status));\r
1029 FreePool (DevicePathPtr);\r
1030 return EFI_SUCCESS;\r
1031}\r
1032\r
1033/**\r
1034 Check whether a usb child device is the wanted device in a bus.\r
1035\r
1036 @param Bus The Usb bus's private data pointer.\r
1037 @param UsbIf The usb child device interface.\r
1038\r
1039 @retval True If a usb child device is the wanted device in a bus.\r
1040 @retval False If a usb child device is *NOT* the wanted device in a bus.\r
1041\r
1042**/\r
1043BOOLEAN\r
1044EFIAPI\r
1045UsbBusIsWantedUsbIO (\r
1046 IN USB_BUS *Bus,\r
1047 IN USB_INTERFACE *UsbIf\r
1048 )\r
1049{\r
1050 EFI_DEVICE_PATH_PROTOCOL *DevicePathPtr;\r
1051 LIST_ENTRY *WantedUsbIoDPListPtr;\r
1052 LIST_ENTRY *WantedListIndex;\r
1053 DEVICE_PATH_LIST_ITEM *WantedListItem;\r
1054 BOOLEAN DoConvert;\r
1055 UINTN FirstDevicePathSize;\r
1056\r
1057 //\r
1058 // Check whether passed in parameters are valid\r
1059 //\r
1060 if ((UsbIf == NULL) || (Bus == NULL)) {\r
1061 return FALSE;\r
1062 }\r
1063 //\r
1064 // Check whether UsbIf is Hub\r
1065 //\r
1066 if (UsbIf->IsHub) {\r
1067 return TRUE;\r
1068 }\r
1069\r
1070 //\r
1071 // Check whether all Usb devices in this bus are wanted\r
1072 //\r
1073 if (SearchUsbDPInList ((EFI_DEVICE_PATH_PROTOCOL *)&mAllUsbClassDevicePath, &Bus->WantedUsbIoDPList)){\r
1074 return TRUE;\r
1075 }\r
1076\r
1077 //\r
1078 // Check whether the Usb device match any item in WantedUsbIoDPList\r
1079 //\r
1080 WantedUsbIoDPListPtr = &Bus->WantedUsbIoDPList;\r
1081 //\r
1082 // Create new Usb device path according to the usb part in UsbIo full device path\r
1083 //\r
1084 DevicePathPtr = GetUsbDPFromFullDP (UsbIf->DevicePath);\r
1085 ASSERT (DevicePathPtr != NULL);\r
1086\r
1087 DoConvert = FALSE;\r
1088 WantedListIndex = WantedUsbIoDPListPtr->ForwardLink;\r
1089 while (WantedListIndex != WantedUsbIoDPListPtr){\r
1090 WantedListItem = CR(WantedListIndex, DEVICE_PATH_LIST_ITEM, Link, DEVICE_PATH_LIST_ITEM_SIGNATURE);\r
1091 ASSERT (WantedListItem->DevicePath->Type == MESSAGING_DEVICE_PATH);\r
1092 switch (WantedListItem->DevicePath->SubType) {\r
1093 case MSG_USB_DP:\r
1094 FirstDevicePathSize = GetDevicePathSize (WantedListItem->DevicePath);\r
1095 if (FirstDevicePathSize == GetDevicePathSize (DevicePathPtr)) {\r
1096 if (CompareMem (\r
1097 WantedListItem->DevicePath,\r
1098 DevicePathPtr,\r
1099 GetDevicePathSize (DevicePathPtr)) == 0\r
1100 ) {\r
1101 DoConvert = TRUE;\r
1102 }\r
1103 }\r
1104 break;\r
1105 case MSG_USB_CLASS_DP:\r
1106 if (MatchUsbClass((USB_CLASS_DEVICE_PATH *)WantedListItem->DevicePath, UsbIf)) {\r
1107 DoConvert = TRUE;\r
1108 }\r
1109 break;\r
1110 case MSG_USB_WWID_DP:\r
1111 if (MatchUsbWwid((USB_WWID_DEVICE_PATH *)WantedListItem->DevicePath, UsbIf)) {\r
1112 DoConvert = TRUE;\r
1113 }\r
1114 break;\r
1115 default:\r
1116 ASSERT (0);\r
1117 break;\r
1118 }\r
1119\r
1120 if (DoConvert) {\r
1121 break;\r
1122 }\r
1123\r
1124 WantedListIndex = WantedListIndex->ForwardLink;\r
1125 }\r
1126 gBS->FreePool (DevicePathPtr);\r
1127\r
1128 //\r
1129 // Check whether the new Usb device path is wanted\r
1130 //\r
1131 if (DoConvert){\r
1132 return TRUE;\r
1133 } else {\r
1134 return FALSE;\r
1135 }\r
1136}\r
1137\r
1138/**\r
1139 Recursively connect every wanted usb child device to ensure they all fully connected.\r
1140 Check all the child Usb IO handles in this bus, recursively connecte if it is wanted usb child device.\r
1141\r
1142 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface.\r
1143\r
1144 @retval EFI_SUCCESS Connect is done successfully.\r
1145 @retval EFI_INVALID_PARAMETER The parameter is invalid.\r
1146\r
1147**/\r
1148EFI_STATUS\r
1149EFIAPI\r
1150UsbBusRecursivelyConnectWantedUsbIo (\r
1151 IN EFI_USB_BUS_PROTOCOL *UsbBusId\r
1152 )\r
1153{\r
1154 USB_BUS *Bus;\r
1155 EFI_STATUS Status;\r
1156 UINTN Index;\r
1157 EFI_USB_IO_PROTOCOL *UsbIo;\r
1158 USB_INTERFACE *UsbIf;\r
1159 UINTN UsbIoHandleCount;\r
1160 EFI_HANDLE *UsbIoBuffer;\r
1161 EFI_DEVICE_PATH_PROTOCOL *UsbIoDevicePath;\r
1162\r
1163 if (UsbBusId == NULL){\r
1164 return EFI_INVALID_PARAMETER;\r
1165 }\r
1166\r
1167 Bus = USB_BUS_FROM_THIS (UsbBusId);\r
1168\r
1169 //\r
1170 // Get all Usb IO handles in system\r
1171 //\r
1172 UsbIoHandleCount = 0;\r
1173 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiUsbIoProtocolGuid, NULL, &UsbIoHandleCount, &UsbIoBuffer);\r
1174 if (Status == EFI_NOT_FOUND || UsbIoHandleCount == 0) {\r
1175 return EFI_SUCCESS;\r
1176 }\r
1177 ASSERT (!EFI_ERROR (Status));\r
1178\r
1179 for (Index = 0; Index < UsbIoHandleCount; Index++) {\r
1180 //\r
1181 // Check whether the USB IO handle is a child of this bus\r
1182 // Note: The usb child handle maybe invalid because of hot plugged out during the loop\r
1183 //\r
1184 UsbIoDevicePath = NULL;\r
1185 Status = gBS->HandleProtocol (UsbIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *) &UsbIoDevicePath);\r
1186 if (EFI_ERROR (Status) || UsbIoDevicePath == NULL) {\r
1187 continue;\r
1188 }\r
1189 if (CompareMem (\r
1190 UsbIoDevicePath,\r
1191 Bus->DevicePath,\r
1192 (GetDevicePathSize (Bus->DevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL))\r
1193 ) != 0) {\r
1194 continue;\r
1195 }\r
1196\r
1197 //\r
1198 // Get the child Usb IO interface\r
1199 //\r
1200 Status = gBS->HandleProtocol(\r
1201 UsbIoBuffer[Index],\r
1202 &gEfiUsbIoProtocolGuid,\r
1203 (VOID **) &UsbIo\r
1204 );\r
1205 if (EFI_ERROR (Status)) {\r
1206 continue;\r
1207 }\r
1208 UsbIf = USB_INTERFACE_FROM_USBIO (UsbIo);\r
1209\r
1210 if (UsbBusIsWantedUsbIO (Bus, UsbIf)) {\r
1211 if (!UsbIf->IsManaged) {\r
1212 //\r
1213 // Recursively connect the wanted Usb Io handle\r
1214 //\r
1215 DEBUG ((EFI_D_INFO, "UsbBusRecursivelyConnectWantedUsbIo: TPL before connect is %d\n", (UINT32)UsbGetCurrentTpl ()));\r
1216 Status = gBS->ConnectController (UsbIf->Handle, NULL, NULL, TRUE);\r
1217 UsbIf->IsManaged = (BOOLEAN)!EFI_ERROR (Status);\r
1218 DEBUG ((EFI_D_INFO, "UsbBusRecursivelyConnectWantedUsbIo: TPL after connect is %d\n", (UINT32)UsbGetCurrentTpl()));\r
1219 }\r
1220 }\r
1221 }\r
1222\r
1223 FreePool (UsbIoBuffer);\r
1224\r
1225 return EFI_SUCCESS;\r
1226}\r
1227\r