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