]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.c
MdeModulePkg SmmLockBoxSmmLib: Add debug message for the address of lockbox(smm)...
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusPei / HubPeim.c
CommitLineData
4b1bf81c 1/** @file\r
2Usb Hub Request Support In PEI Phase\r
3\r
4Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
5 \r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions\r
8of the BSD License which accompanies this distribution. The\r
9full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include "UsbPeim.h"\r
18#include "HubPeim.h"\r
19#include "PeiUsbLib.h"\r
20\r
21/**\r
22 Get a given hub port status.\r
23\r
24 @param PeiServices General-purpose services that are available to every PEIM.\r
25 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
26 @param Port Usb hub port number (starting from 1).\r
27 @param PortStatus Current Hub port status and change status.\r
28\r
29 @retval EFI_SUCCESS Port status is obtained successfully.\r
30 @retval EFI_DEVICE_ERROR Cannot get the port status due to a hardware error.\r
31 @retval Others Other failure occurs.\r
32\r
33**/\r
34EFI_STATUS\r
35PeiHubGetPortStatus (\r
36 IN EFI_PEI_SERVICES **PeiServices,\r
37 IN PEI_USB_IO_PPI *UsbIoPpi,\r
38 IN UINT8 Port,\r
39 OUT UINT32 *PortStatus\r
40 )\r
41{\r
42 EFI_USB_DEVICE_REQUEST DeviceRequest;\r
43\r
44 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));\r
45\r
46 //\r
47 // Fill Device request packet\r
48 //\r
49 DeviceRequest.RequestType = USB_HUB_GET_PORT_STATUS_REQ_TYPE;\r
50 DeviceRequest.Request = USB_HUB_GET_PORT_STATUS;\r
51 DeviceRequest.Index = Port;\r
52 DeviceRequest.Length = (UINT16) sizeof (UINT32);\r
53\r
54\r
55 return UsbIoPpi->UsbControlTransfer (\r
56 PeiServices,\r
57 UsbIoPpi,\r
58 &DeviceRequest,\r
59 EfiUsbDataIn,\r
60 PcdGet32 (PcdUsbTransferTimeoutValue),\r
61 PortStatus,\r
62 sizeof (UINT32)\r
63 );\r
64\r
65}\r
66\r
67/**\r
68 Set specified feature to a given hub port.\r
69\r
70 @param PeiServices General-purpose services that are available to every PEIM.\r
71 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
72 @param Port Usb hub port number (starting from 1).\r
73 @param Value New feature value.\r
74\r
75 @retval EFI_SUCCESS Port feature is set successfully.\r
76 @retval EFI_DEVICE_ERROR Cannot set the port feature due to a hardware error.\r
77 @retval Others Other failure occurs.\r
78\r
79**/\r
80EFI_STATUS\r
81PeiHubSetPortFeature (\r
82 IN EFI_PEI_SERVICES **PeiServices,\r
83 IN PEI_USB_IO_PPI *UsbIoPpi,\r
84 IN UINT8 Port,\r
85 IN UINT8 Value\r
86 )\r
87{\r
88 EFI_USB_DEVICE_REQUEST DeviceRequest;\r
89\r
90 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));\r
91\r
92 //\r
93 // Fill Device request packet\r
94 //\r
95 DeviceRequest.RequestType = USB_HUB_SET_PORT_FEATURE_REQ_TYPE;\r
96 DeviceRequest.Request = USB_HUB_SET_PORT_FEATURE;\r
97 DeviceRequest.Value = Value;\r
98 DeviceRequest.Index = Port;\r
99\r
100 return UsbIoPpi->UsbControlTransfer (\r
101 PeiServices,\r
102 UsbIoPpi,\r
103 &DeviceRequest,\r
104 EfiUsbNoData,\r
105 PcdGet32 (PcdUsbTransferTimeoutValue),\r
106 NULL,\r
107 0\r
108 );\r
109}\r
110\r
111/**\r
112 Clear specified feature on a given hub port.\r
113\r
114 @param PeiServices General-purpose services that are available to every PEIM.\r
115 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
116 @param Port Usb hub port number (starting from 1).\r
117 @param Value Feature value that will be cleared from the hub port.\r
118\r
119 @retval EFI_SUCCESS Port feature is cleared successfully.\r
120 @retval EFI_DEVICE_ERROR Cannot clear the port feature due to a hardware error.\r
121 @retval Others Other failure occurs.\r
122\r
123**/\r
124EFI_STATUS\r
125PeiHubClearPortFeature (\r
126 IN EFI_PEI_SERVICES **PeiServices,\r
127 IN PEI_USB_IO_PPI *UsbIoPpi,\r
128 IN UINT8 Port,\r
129 IN UINT8 Value\r
130 )\r
131{\r
132 EFI_USB_DEVICE_REQUEST DeviceRequest;\r
133\r
134 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));\r
135\r
136 //\r
137 // Fill Device request packet\r
138 //\r
139 DeviceRequest.RequestType = USB_HUB_CLEAR_FEATURE_PORT_REQ_TYPE;\r
140 DeviceRequest.Request = USB_HUB_CLEAR_FEATURE_PORT;\r
141 DeviceRequest.Value = Value;\r
142 DeviceRequest.Index = Port;\r
143\r
144 return UsbIoPpi->UsbControlTransfer (\r
145 PeiServices,\r
146 UsbIoPpi,\r
147 &DeviceRequest,\r
148 EfiUsbNoData,\r
149 PcdGet32 (PcdUsbTransferTimeoutValue),\r
150 NULL,\r
151 0\r
152 );\r
153}\r
154\r
155/**\r
156 Get a given hub status.\r
157\r
158 @param PeiServices General-purpose services that are available to every PEIM.\r
159 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
160 @param HubStatus Current Hub status and change status.\r
161\r
162 @retval EFI_SUCCESS Hub status is obtained successfully.\r
163 @retval EFI_DEVICE_ERROR Cannot get the hub status due to a hardware error.\r
164 @retval Others Other failure occurs.\r
165\r
166**/\r
167EFI_STATUS\r
168PeiHubGetHubStatus (\r
169 IN EFI_PEI_SERVICES **PeiServices,\r
170 IN PEI_USB_IO_PPI *UsbIoPpi,\r
171 OUT UINT32 *HubStatus\r
172 )\r
173{\r
174 EFI_USB_DEVICE_REQUEST DeviceRequest;\r
175\r
176 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));\r
177\r
178 //\r
179 // Fill Device request packet\r
180 //\r
181 DeviceRequest.RequestType = USB_HUB_GET_HUB_STATUS_REQ_TYPE;\r
182 DeviceRequest.Request = USB_HUB_GET_HUB_STATUS;\r
183 DeviceRequest.Length = (UINT16) sizeof (UINT32);\r
184\r
185 return UsbIoPpi->UsbControlTransfer (\r
186 PeiServices,\r
187 UsbIoPpi,\r
188 &DeviceRequest,\r
189 EfiUsbDataIn,\r
190 PcdGet32 (PcdUsbTransferTimeoutValue),\r
191 HubStatus,\r
192 sizeof (UINT32)\r
193 );\r
194}\r
195\r
196/**\r
197 Set specified feature to a given hub.\r
198\r
199 @param PeiServices General-purpose services that are available to every PEIM.\r
200 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
201 @param Value New feature value.\r
202\r
203 @retval EFI_SUCCESS Port feature is set successfully.\r
204 @retval EFI_DEVICE_ERROR Cannot set the port feature due to a hardware error.\r
205 @retval Others Other failure occurs.\r
206\r
207**/\r
208EFI_STATUS\r
209PeiHubSetHubFeature (\r
210 IN EFI_PEI_SERVICES **PeiServices,\r
211 IN PEI_USB_IO_PPI *UsbIoPpi,\r
212 IN UINT8 Value\r
213 )\r
214{\r
215 EFI_USB_DEVICE_REQUEST DeviceRequest;\r
216\r
217 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));\r
218\r
219 //\r
220 // Fill Device request packet\r
221 //\r
222 DeviceRequest.RequestType = USB_HUB_SET_HUB_FEATURE_REQ_TYPE;\r
223 DeviceRequest.Request = USB_HUB_SET_HUB_FEATURE;\r
224 DeviceRequest.Value = Value;\r
225\r
226 return UsbIoPpi->UsbControlTransfer (\r
227 PeiServices,\r
228 UsbIoPpi,\r
229 &DeviceRequest,\r
230 EfiUsbNoData,\r
231 PcdGet32 (PcdUsbTransferTimeoutValue),\r
232 NULL,\r
233 0\r
234 );\r
235}\r
236\r
237/**\r
238 Clear specified feature on a given hub.\r
239\r
240 @param PeiServices General-purpose services that are available to every PEIM.\r
241 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
242 @param Value Feature value that will be cleared from the hub port.\r
243\r
244 @retval EFI_SUCCESS Hub feature is cleared successfully.\r
245 @retval EFI_DEVICE_ERROR Cannot clear the hub feature due to a hardware error.\r
246 @retval Others Other failure occurs.\r
247\r
248**/\r
249EFI_STATUS\r
250PeiHubClearHubFeature (\r
251 IN EFI_PEI_SERVICES **PeiServices,\r
252 IN PEI_USB_IO_PPI *UsbIoPpi,\r
253 IN UINT8 Value\r
254 )\r
255{\r
256 EFI_USB_DEVICE_REQUEST DeviceRequest;\r
257\r
258 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));\r
259\r
260 //\r
261 // Fill Device request packet\r
262 //\r
263 DeviceRequest.RequestType = USB_HUB_CLEAR_FEATURE_REQ_TYPE;\r
264 DeviceRequest.Request = USB_HUB_CLEAR_FEATURE;\r
265 DeviceRequest.Value = Value;\r
266\r
267 return UsbIoPpi->UsbControlTransfer (\r
268 PeiServices,\r
269 UsbIoPpi,\r
270 &DeviceRequest,\r
271 EfiUsbNoData,\r
272 PcdGet32 (PcdUsbTransferTimeoutValue),\r
273 NULL,\r
274 0\r
275 );\r
276}\r
277\r
278/**\r
279 Get a given hub descriptor.\r
280\r
281 @param PeiServices General-purpose services that are available to every PEIM.\r
282 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
283 @param DescriptorSize The length of Hub Descriptor buffer.\r
284 @param HubDescriptor Caller allocated buffer to store the hub descriptor if\r
285 successfully returned.\r
286\r
287 @retval EFI_SUCCESS Hub descriptor is obtained successfully.\r
288 @retval EFI_DEVICE_ERROR Cannot get the hub descriptor due to a hardware error.\r
289 @retval Others Other failure occurs.\r
290\r
291**/\r
292EFI_STATUS\r
293PeiGetHubDescriptor (\r
294 IN EFI_PEI_SERVICES **PeiServices,\r
295 IN PEI_USB_IO_PPI *UsbIoPpi,\r
296 IN UINTN DescriptorSize,\r
297 OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor\r
298 )\r
299{\r
300 EFI_USB_DEVICE_REQUEST DevReq;\r
301 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
302\r
303 //\r
304 // Fill Device request packet\r
305 //\r
306 DevReq.RequestType = USB_RT_HUB | 0x80;\r
307 DevReq.Request = USB_HUB_GET_DESCRIPTOR;\r
308 DevReq.Value = USB_DT_HUB << 8;\r
309 DevReq.Length = (UINT16)DescriptorSize;\r
310\r
311 return UsbIoPpi->UsbControlTransfer (\r
312 PeiServices,\r
313 UsbIoPpi,\r
314 &DevReq,\r
315 EfiUsbDataIn,\r
316 PcdGet32 (PcdUsbTransferTimeoutValue),\r
317 HubDescriptor,\r
318 (UINT16)DescriptorSize\r
319 );\r
320}\r
321\r
322/**\r
323 Configure a given hub.\r
324\r
325 @param PeiServices General-purpose services that are available to every PEIM.\r
326 @param PeiUsbDevice Indicating the hub controller device that will be configured\r
327\r
328 @retval EFI_SUCCESS Hub configuration is done successfully.\r
329 @retval EFI_DEVICE_ERROR Cannot configure the hub due to a hardware error.\r
330\r
331**/\r
332EFI_STATUS\r
333PeiDoHubConfig (\r
334 IN EFI_PEI_SERVICES **PeiServices,\r
335 IN PEI_USB_DEVICE *PeiUsbDevice\r
336 )\r
337{\r
338 EFI_USB_HUB_DESCRIPTOR HubDescriptor;\r
339 EFI_STATUS Status;\r
340 EFI_USB_HUB_STATUS HubStatus;\r
341 UINTN Index;\r
342 UINT32 PortStatus;\r
343 PEI_USB_IO_PPI *UsbIoPpi;\r
344\r
345 ZeroMem (&HubDescriptor, sizeof (HubDescriptor));\r
346 UsbIoPpi = &PeiUsbDevice->UsbIoPpi;\r
347\r
348 //\r
349 // First get the hub descriptor length\r
350 //\r
351 Status = PeiGetHubDescriptor (\r
352 PeiServices,\r
353 UsbIoPpi,\r
354 2,\r
355 &HubDescriptor\r
356 );\r
357 if (EFI_ERROR (Status)) {\r
358 return EFI_DEVICE_ERROR;\r
359 }\r
360 //\r
361 // First get the whole descriptor, then\r
362 // get the number of hub ports\r
363 //\r
364 Status = PeiGetHubDescriptor (\r
365 PeiServices,\r
366 UsbIoPpi,\r
367 HubDescriptor.Length,\r
368 &HubDescriptor\r
369 );\r
370 if (EFI_ERROR (Status)) {\r
371 return EFI_DEVICE_ERROR;\r
372 }\r
373\r
374 PeiUsbDevice->DownStreamPortNo = HubDescriptor.NbrPorts;\r
375\r
376 Status = PeiHubGetHubStatus (\r
377 PeiServices,\r
378 UsbIoPpi,\r
379 (UINT32 *) &HubStatus\r
380 );\r
381\r
382 if (EFI_ERROR (Status)) {\r
383 return EFI_DEVICE_ERROR;\r
384 }\r
385 //\r
386 // Get all hub ports status\r
387 //\r
388 for (Index = 0; Index < PeiUsbDevice->DownStreamPortNo; Index++) {\r
389\r
390 Status = PeiHubGetPortStatus (\r
391 PeiServices,\r
392 UsbIoPpi,\r
393 (UINT8) (Index + 1),\r
394 &PortStatus\r
395 );\r
396 if (EFI_ERROR (Status)) {\r
397 continue;\r
398 }\r
399 }\r
400 //\r
401 // Power all the hub ports\r
402 //\r
403 for (Index = 0; Index < PeiUsbDevice->DownStreamPortNo; Index++) {\r
404 Status = PeiHubSetPortFeature (\r
405 PeiServices,\r
406 UsbIoPpi,\r
407 (UINT8) (Index + 1),\r
408 EfiUsbPortPower\r
409 );\r
410 if (EFI_ERROR (Status)) {\r
411 continue;\r
412 }\r
413 }\r
414 //\r
415 // Clear Hub Status Change\r
416 //\r
417 Status = PeiHubGetHubStatus (\r
418 PeiServices,\r
419 UsbIoPpi,\r
420 (UINT32 *) &HubStatus\r
421 );\r
422 if (EFI_ERROR (Status)) {\r
423 return EFI_DEVICE_ERROR;\r
424 } else {\r
425 //\r
426 // Hub power supply change happens\r
427 //\r
428 if ((HubStatus.HubChangeStatus & HUB_CHANGE_LOCAL_POWER) != 0) {\r
429 PeiHubClearHubFeature (\r
430 PeiServices,\r
431 UsbIoPpi,\r
432 C_HUB_LOCAL_POWER\r
433 );\r
434 }\r
435 //\r
436 // Hub change overcurrent happens\r
437 //\r
438 if ((HubStatus.HubChangeStatus & HUB_CHANGE_OVERCURRENT) != 0) {\r
439 PeiHubClearHubFeature (\r
440 PeiServices,\r
441 UsbIoPpi,\r
442 C_HUB_OVER_CURRENT\r
443 );\r
444 }\r
445 }\r
446\r
447 return EFI_SUCCESS;\r
448}\r
449\r
450/**\r
451 Send reset signal over the given root hub port.\r
452\r
453 @param PeiServices General-purpose services that are available to every PEIM.\r
454 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
455 @param PortNum Usb hub port number (starting from 1).\r
456\r
457**/\r
458VOID\r
459PeiResetHubPort (\r
460 IN EFI_PEI_SERVICES **PeiServices,\r
461 IN PEI_USB_IO_PPI *UsbIoPpi,\r
462 IN UINT8 PortNum\r
463 )\r
464{\r
465 UINT8 Try;\r
466 EFI_USB_PORT_STATUS HubPortStatus;\r
467\r
468\r
469 MicroSecondDelay (100 * 1000);\r
470\r
471 //\r
472 // reset root port\r
473 //\r
474 PeiHubSetPortFeature (\r
475 PeiServices,\r
476 UsbIoPpi,\r
477 PortNum,\r
478 EfiUsbPortReset\r
479 );\r
480\r
481 Try = 10;\r
482 do {\r
483 PeiHubGetPortStatus (\r
484 PeiServices,\r
485 UsbIoPpi,\r
486 PortNum,\r
487 (UINT32 *) &HubPortStatus\r
488 );\r
489\r
490 MicroSecondDelay (2 * 1000);\r
491 Try -= 1;\r
492 } while ((HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) == 0 && Try > 0);\r
493\r
494 //\r
495 // clear reset root port\r
496 //\r
497 PeiHubClearPortFeature (\r
498 PeiServices,\r
499 UsbIoPpi,\r
500 PortNum,\r
501 EfiUsbPortReset\r
502 );\r
503\r
504 MicroSecondDelay (1 * 1000);\r
505\r
506 PeiHubClearPortFeature (\r
507 PeiServices,\r
508 UsbIoPpi,\r
509 PortNum,\r
510 EfiUsbPortConnectChange\r
511 );\r
512\r
513 //\r
514 // Set port enable\r
515 //\r
516 PeiHubSetPortFeature (\r
517 PeiServices,\r
518 UsbIoPpi,\r
519 PortNum,\r
520 EfiUsbPortEnable\r
521 );\r
522\r
523 //\r
524 // Clear any change status\r
525 //\r
526\r
527 PeiHubClearPortFeature (\r
528 PeiServices,\r
529 UsbIoPpi,\r
530 PortNum,\r
531 EfiUsbPortEnableChange\r
532 );\r
533\r
534 MicroSecondDelay (10 * 1000);\r
535\r
536 return;\r
537}\r