]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Bus/Usb/UsbBus/Dxe/hub.c
changed EdkModulePkg GUID from the original B6EC423C-21D2-490D-85C6-DD5864EAA674...
[mirror_edk2.git] / EdkModulePkg / Bus / Usb / UsbBus / Dxe / hub.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12 Module Name:\r
13\r
14 Hub.c\r
15 \r
16 Abstract:\r
17\r
18 Usb Hub Request\r
19\r
20 Revision History\r
21\r
22--*/\r
23\r
24#include "usbbus.h"\r
25\r
26EFI_STATUS\r
27HubGetPortStatus (\r
28 IN EFI_USB_IO_PROTOCOL *UsbIo,\r
29 IN UINT8 Port,\r
30 OUT UINT32 *PortStatus\r
31 )\r
32/*++\r
33 \r
34 Routine Description:\r
35 Get a given hub port status\r
36 \r
37 Arguments:\r
38 UsbIo - EFI_USB_IO_PROTOCOL instance\r
39 Port - Usb hub port number (starting from 1).\r
40 PortStatus - Current Hub port status and change status.\r
41 \r
42 Returns:\r
43 EFI_SUCCESS\r
44 EFI_DEVICE\r
45 EFI_TIME_OUT\r
46 EFI_INVALID_PARAMETER\r
47 \r
48--*/\r
49{\r
50 EFI_USB_DEVICE_REQUEST DevReq;\r
51 EFI_STATUS EfiStatus;\r
52 UINT32 UsbStatus;\r
53 UINT32 Timeout;\r
54\r
55 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
56\r
57 //\r
58 // Fill Device request packet\r
59 //\r
60 DevReq.RequestType = HUB_GET_PORT_STATUS_REQ_TYPE;\r
61 DevReq.Request = HUB_GET_PORT_STATUS;\r
62 DevReq.Value = 0;\r
63 DevReq.Index = Port;\r
64 DevReq.Length = sizeof (UINT32);\r
65\r
66 Timeout = 3000;\r
67\r
68 EfiStatus = UsbIo->UsbControlTransfer (\r
69 UsbIo,\r
70 &DevReq,\r
71 EfiUsbDataIn,\r
72 Timeout,\r
73 PortStatus,\r
74 sizeof (UINT32),\r
75 &UsbStatus\r
76 );\r
77\r
78 return EfiStatus;\r
79}\r
80\r
81EFI_STATUS\r
82HubSetPortFeature (\r
83 IN EFI_USB_IO_PROTOCOL *UsbIo,\r
84 IN UINT8 Port,\r
85 IN UINT8 Value\r
86 )\r
87/*++\r
88 \r
89 Routine Description:\r
90 Set specified feature to a give hub port\r
91 \r
92 Arguments:\r
93 UsbIo - EFI_USB_IO_PROTOCOL instance\r
94 Port - Usb hub port number (starting from 1).\r
95 Value - New feature value.\r
96 \r
97 Returns:\r
98 EFI_SUCCESS\r
99 EFI_DEVICE\r
100 EFI_TIME_OUT\r
101 EFI_INVALID_PARAMETER\r
102 \r
103--*/\r
104{\r
105 EFI_USB_DEVICE_REQUEST DevReq;\r
106 EFI_STATUS EfiStatus;\r
107 UINT32 UsbStatus;\r
108 UINT32 Timeout;\r
109\r
110 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
111\r
112 //\r
113 // Fill Device request packet\r
114 //\r
115 DevReq.RequestType = HUB_SET_PORT_FEATURE_REQ_TYPE;\r
116 DevReq.Request = HUB_SET_PORT_FEATURE;\r
117 DevReq.Value = Value;\r
118 DevReq.Index = Port;\r
119 DevReq.Length = 0;\r
120\r
121 Timeout = 3000;\r
122 EfiStatus = UsbIo->UsbControlTransfer (\r
123 UsbIo,\r
124 &DevReq,\r
125 EfiUsbNoData,\r
126 Timeout,\r
127 NULL,\r
128 0,\r
129 &UsbStatus\r
130 );\r
131\r
132 return EfiStatus;\r
133}\r
134\r
135EFI_STATUS\r
136HubClearPortFeature (\r
137 IN EFI_USB_IO_PROTOCOL *UsbIo,\r
138 IN UINT8 Port,\r
139 IN UINT8 Value\r
140 )\r
141/*++\r
142 \r
143 Routine Description:\r
144 Clear a specified feature of a given hub port\r
145 \r
146 Arguments:\r
147 UsbIo - EFI_USB_IO_PROTOCOL instance\r
148 Port - Usb hub port number (starting from 1).\r
149 Value - Feature value that will be cleared from\r
150 that hub port.\r
151 \r
152 Returns:\r
153 EFI_SUCCESS\r
154 EFI_DEVICE\r
155 EFI_TIME_OUT\r
156 EFI_INVALID_PARAMETER\r
157 \r
158--*/\r
159{\r
160 EFI_USB_DEVICE_REQUEST DevReq;\r
161 EFI_STATUS EfiStatus;\r
162 UINT32 UsbStatus;\r
163 UINT32 Timeout;\r
164\r
165 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
166\r
167 //\r
168 // Fill Device request packet\r
169 //\r
170 DevReq.RequestType = HUB_CLEAR_FEATURE_PORT_REQ_TYPE;\r
171 DevReq.Request = HUB_CLEAR_FEATURE_PORT;\r
172 DevReq.Value = Value;\r
173 DevReq.Index = Port;\r
174 DevReq.Length = 0;\r
175\r
176 Timeout = 3000;\r
177 EfiStatus = UsbIo->UsbControlTransfer (\r
178 UsbIo,\r
179 &DevReq,\r
180 EfiUsbNoData,\r
181 Timeout,\r
182 NULL,\r
183 0,\r
184 &UsbStatus\r
185 );\r
186\r
187 return EfiStatus;\r
188}\r
189\r
190EFI_STATUS\r
191HubGetHubStatus (\r
192 IN EFI_USB_IO_PROTOCOL *UsbIo,\r
193 OUT UINT32 *HubStatus\r
194 )\r
195/*++\r
196 \r
197 Routine Description:\r
198 Get Hub Status\r
199 \r
200 Arguments:\r
201 UsbIo - EFI_USB_IO_PROTOCOL instance\r
202 HubStatus - Current Hub status and change status.\r
203 \r
204 Returns:\r
205 EFI_SUCCESS\r
206 EFI_DEVICE\r
207 EFI_TIME_OUT\r
208 \r
209--*/\r
210{\r
211 EFI_USB_DEVICE_REQUEST DevReq;\r
212 EFI_STATUS EfiStatus;\r
213 UINT32 UsbStatus;\r
214 UINT32 Timeout;\r
215\r
216 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
217\r
218 //\r
219 // Fill Device request packet\r
220 //\r
221 DevReq.RequestType = HUB_GET_HUB_STATUS_REQ_TYPE;\r
222 DevReq.Request = HUB_GET_HUB_STATUS;\r
223 DevReq.Value = 0;\r
224 DevReq.Index = 0;\r
225 DevReq.Length = sizeof (UINT32);\r
226\r
227 Timeout = 3000;\r
228 EfiStatus = UsbIo->UsbControlTransfer (\r
229 UsbIo,\r
230 &DevReq,\r
231 EfiUsbDataIn,\r
232 Timeout,\r
233 HubStatus,\r
234 sizeof (UINT32),\r
235 &UsbStatus\r
236 );\r
237\r
238 return EfiStatus;\r
239}\r
240\r
241EFI_STATUS\r
242HubSetHubFeature (\r
243 IN EFI_USB_IO_PROTOCOL *UsbIo,\r
244 IN UINT8 Value\r
245 )\r
246/*++\r
247 \r
248 Routine Description:\r
249 Set a specified feature to the hub\r
250 \r
251 Arguments:\r
252 UsbIo - EFI_USB_IO_PROTOCOL instance\r
253 Value - Feature value that will be set to the hub.\r
254 \r
255 Returns:\r
256 EFI_SUCCESS\r
257 EFI_DEVICE\r
258 EFI_TIME_OUT\r
259 \r
260--*/\r
261{\r
262 EFI_USB_DEVICE_REQUEST DevReq;\r
263 EFI_STATUS EfiStatus;\r
264 UINT32 UsbStatus;\r
265 UINT32 Timeout;\r
266\r
267 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
268\r
269 //\r
270 // Fill Device request packet\r
271 //\r
272 DevReq.RequestType = HUB_SET_HUB_FEATURE_REQ_TYPE;\r
273 DevReq.Request = HUB_SET_HUB_FEATURE;\r
274 DevReq.Value = Value;\r
275 DevReq.Index = 0;\r
276 DevReq.Length = 0;\r
277\r
278 Timeout = 3000;\r
279 EfiStatus = UsbIo->UsbControlTransfer (\r
280 UsbIo,\r
281 &DevReq,\r
282 EfiUsbNoData,\r
283 Timeout,\r
284 NULL,\r
285 0,\r
286 &UsbStatus\r
287 );\r
288\r
289 return EfiStatus;\r
290}\r
291\r
292EFI_STATUS\r
293HubClearHubFeature (\r
294 IN EFI_USB_IO_PROTOCOL *UsbIo,\r
295 IN UINT8 Value\r
296 )\r
297/*++\r
298 \r
299 Routine Description:\r
300 Set a specified feature to the hub\r
301 \r
302 Arguments:\r
303 UsbIo - EFI_USB_IO_PROTOCOL instance\r
304 Value - Feature value that will be cleared from the hub.\r
305 \r
306 Returns:\r
307 EFI_SUCCESS\r
308 EFI_DEVICE\r
309 EFI_TIME_OUT\r
310 \r
311--*/\r
312{\r
313 EFI_USB_DEVICE_REQUEST DevReq;\r
314 EFI_STATUS EfiStatus;\r
315 UINT32 UsbStatus;\r
316 UINT32 Timeout;\r
317\r
318 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
319\r
320 //\r
321 // Fill Device request packet\r
322 //\r
323 DevReq.RequestType = HUB_CLEAR_FEATURE_REQ_TYPE;\r
324 DevReq.Request = HUB_CLEAR_FEATURE;\r
325 DevReq.Value = Value;\r
326 DevReq.Index = 0;\r
327 DevReq.Length = 0;\r
328\r
329 Timeout = 3000;\r
330 EfiStatus = UsbIo->UsbControlTransfer (\r
331 UsbIo,\r
332 &DevReq,\r
333 EfiUsbNoData,\r
334 Timeout,\r
335 NULL,\r
336 0,\r
337 &UsbStatus\r
338 );\r
339\r
340 return EfiStatus;\r
341\r
342}\r
343\r
344EFI_STATUS\r
345GetHubDescriptor (\r
346 IN EFI_USB_IO_PROTOCOL *UsbIo,\r
347 IN UINTN DescriptorSize,\r
348 OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor\r
349 )\r
350/*++\r
351 \r
352 Routine Description:\r
353 Get the hub descriptor\r
354 \r
355 Arguments:\r
356 UsbIo - EFI_USB_IO_PROTOCOL instance\r
357 DescriptorSize - The length of Hub Descriptor buffer.\r
358 HubDescriptor - Caller allocated buffer to store the hub descriptor\r
359 if successfully returned.\r
360 \r
361 Returns:\r
362 EFI_SUCCESS\r
363 EFI_DEVICE\r
364 EFI_TIME_OUT\r
365 \r
366--*/\r
367{\r
368 EFI_USB_DEVICE_REQUEST DevReq;\r
369 EFI_STATUS EfiStatus;\r
370 UINT32 UsbStatus;\r
371 UINT32 Timeout;\r
372\r
373 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
374\r
375 //\r
376 // Fill Device request packet\r
377 //\r
378 DevReq.RequestType = USB_RT_HUB | 0x80;\r
379 DevReq.Request = HUB_GET_DESCRIPTOR;\r
380 DevReq.Value = USB_DT_HUB << 8;\r
381 DevReq.Index = 0;\r
382 DevReq.Length = (UINT16) DescriptorSize;\r
383\r
384 Timeout = 3000;\r
385 EfiStatus = UsbIo->UsbControlTransfer (\r
386 UsbIo,\r
387 &DevReq,\r
388 EfiUsbDataIn,\r
389 Timeout,\r
390 HubDescriptor,\r
391 (UINT16) DescriptorSize,\r
392 &UsbStatus\r
393 );\r
394\r
395 return EfiStatus;\r
396\r
397}\r
398\r
399EFI_STATUS\r
400DoHubConfig (\r
401 IN USB_IO_CONTROLLER_DEVICE *HubController\r
402 )\r
403/*++\r
404 \r
405 Routine Description:\r
406 Configure the hub\r
407 \r
408 Arguments:\r
409 HubController - Indicating the hub controller device that\r
410 will be configured\r
411 \r
412 Returns:\r
413 EFI_SUCCESS\r
414 EFI_DEVICE_ERROR\r
415 \r
416--*/\r
417{\r
418 EFI_USB_IO_PROTOCOL *UsbIo;\r
419 EFI_USB_HUB_DESCRIPTOR HubDescriptor;\r
420 EFI_STATUS Status;\r
421 EFI_USB_HUB_STATUS HubStatus;\r
422 UINTN Index;\r
423 UINT32 PortStatus;\r
424\r
425 UsbIo = &HubController->UsbIo;\r
426\r
427 ZeroMem (&HubDescriptor, sizeof (HubDescriptor));\r
428\r
429 //\r
430 // First get the hub descriptor length\r
431 //\r
432 Status = GetHubDescriptor (UsbIo, 2, &HubDescriptor);\r
433 if (EFI_ERROR (Status)) {\r
434 return EFI_DEVICE_ERROR;\r
435 }\r
436 \r
437 //\r
438 // First get the whole descriptor, then\r
439 // get the number of hub ports\r
440 //\r
441 Status = GetHubDescriptor (\r
442 UsbIo,\r
443 HubDescriptor.Length,\r
444 &HubDescriptor\r
445 );\r
446 if (EFI_ERROR (Status)) {\r
447 DEBUG ((gUSBErrorLevel, "Get hub descriptor fail\n"));\r
448 return EFI_DEVICE_ERROR;\r
449 }\r
450\r
451 HubController->DownstreamPorts = HubDescriptor.NbrPorts;\r
452\r
453 Status = HubGetHubStatus (UsbIo, (UINT32 *) &HubStatus);\r
454 if (EFI_ERROR (Status)) {\r
455 DEBUG ((gUSBErrorLevel, "Get hub status fail when configure\n"));\r
456 return EFI_DEVICE_ERROR;\r
457 }\r
458 \r
459 //\r
460 // Get all hub ports status\r
461 //\r
462 for (Index = 0; Index < HubController->DownstreamPorts; Index++) {\r
463\r
464 Status = HubGetPortStatus (UsbIo, (UINT8) (Index + 1), &PortStatus);\r
465 if (EFI_ERROR (Status)) {\r
466 continue;\r
467 }\r
468 }\r
469 //\r
470 // Power all the hub ports\r
471 //\r
472 for (Index = 0; Index < HubController->DownstreamPorts; Index++) {\r
473 Status = HubSetPortFeature (\r
474 UsbIo,\r
475 (UINT8) (Index + 1),\r
476 EfiUsbPortPower\r
477 );\r
478 if (EFI_ERROR (Status)) {\r
479 continue;\r
480 }\r
481 }\r
482 \r
483 //\r
484 // Clear Hub Status Change\r
485 //\r
486 Status = HubGetHubStatus (UsbIo, (UINT32 *) &HubStatus);\r
487 if (EFI_ERROR (Status)) {\r
488 DEBUG ((gUSBErrorLevel, "Get hub status fail\n"));\r
489 return EFI_DEVICE_ERROR;\r
490 } else {\r
491 //\r
492 // Hub power supply change happens\r
493 //\r
494 if (HubStatus.HubChange & HUB_CHANGE_LOCAL_POWER) {\r
495 HubClearHubFeature (UsbIo, C_HUB_LOCAL_POWER);\r
496 }\r
497 //\r
498 // Hub change overcurrent happens\r
499 //\r
500 if (HubStatus.HubChange & HUB_CHANGE_OVERCURRENT) {\r
501 HubClearHubFeature (UsbIo, C_HUB_OVER_CURRENT);\r
502 }\r
503 }\r
504\r
505 return EFI_SUCCESS;\r
506\r
507}\r