Initial import.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
507
EdkModulePkg/Bus/Usb/UsbBus/Dxe/hub.c
Normal file
507
EdkModulePkg/Bus/Usb/UsbBus/Dxe/hub.c
Normal file
@@ -0,0 +1,507 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Hub.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Usb Hub Request
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include "usbbus.h"
|
||||
|
||||
EFI_STATUS
|
||||
HubGetPortStatus (
|
||||
IN EFI_USB_IO_PROTOCOL *UsbIo,
|
||||
IN UINT8 Port,
|
||||
OUT UINT32 *PortStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Get a given hub port status
|
||||
|
||||
Arguments:
|
||||
UsbIo - EFI_USB_IO_PROTOCOL instance
|
||||
Port - Usb hub port number (starting from 1).
|
||||
PortStatus - Current Hub port status and change status.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS
|
||||
EFI_DEVICE
|
||||
EFI_TIME_OUT
|
||||
EFI_INVALID_PARAMETER
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_USB_DEVICE_REQUEST DevReq;
|
||||
EFI_STATUS EfiStatus;
|
||||
UINT32 UsbStatus;
|
||||
UINT32 Timeout;
|
||||
|
||||
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
|
||||
|
||||
//
|
||||
// Fill Device request packet
|
||||
//
|
||||
DevReq.RequestType = HUB_GET_PORT_STATUS_REQ_TYPE;
|
||||
DevReq.Request = HUB_GET_PORT_STATUS;
|
||||
DevReq.Value = 0;
|
||||
DevReq.Index = Port;
|
||||
DevReq.Length = sizeof (UINT32);
|
||||
|
||||
Timeout = 3000;
|
||||
|
||||
EfiStatus = UsbIo->UsbControlTransfer (
|
||||
UsbIo,
|
||||
&DevReq,
|
||||
EfiUsbDataIn,
|
||||
Timeout,
|
||||
PortStatus,
|
||||
sizeof (UINT32),
|
||||
&UsbStatus
|
||||
);
|
||||
|
||||
return EfiStatus;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
HubSetPortFeature (
|
||||
IN EFI_USB_IO_PROTOCOL *UsbIo,
|
||||
IN UINT8 Port,
|
||||
IN UINT8 Value
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Set specified feature to a give hub port
|
||||
|
||||
Arguments:
|
||||
UsbIo - EFI_USB_IO_PROTOCOL instance
|
||||
Port - Usb hub port number (starting from 1).
|
||||
Value - New feature value.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS
|
||||
EFI_DEVICE
|
||||
EFI_TIME_OUT
|
||||
EFI_INVALID_PARAMETER
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_USB_DEVICE_REQUEST DevReq;
|
||||
EFI_STATUS EfiStatus;
|
||||
UINT32 UsbStatus;
|
||||
UINT32 Timeout;
|
||||
|
||||
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
|
||||
|
||||
//
|
||||
// Fill Device request packet
|
||||
//
|
||||
DevReq.RequestType = HUB_SET_PORT_FEATURE_REQ_TYPE;
|
||||
DevReq.Request = HUB_SET_PORT_FEATURE;
|
||||
DevReq.Value = Value;
|
||||
DevReq.Index = Port;
|
||||
DevReq.Length = 0;
|
||||
|
||||
Timeout = 3000;
|
||||
EfiStatus = UsbIo->UsbControlTransfer (
|
||||
UsbIo,
|
||||
&DevReq,
|
||||
EfiUsbNoData,
|
||||
Timeout,
|
||||
NULL,
|
||||
0,
|
||||
&UsbStatus
|
||||
);
|
||||
|
||||
return EfiStatus;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
HubClearPortFeature (
|
||||
IN EFI_USB_IO_PROTOCOL *UsbIo,
|
||||
IN UINT8 Port,
|
||||
IN UINT8 Value
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Clear a specified feature of a given hub port
|
||||
|
||||
Arguments:
|
||||
UsbIo - EFI_USB_IO_PROTOCOL instance
|
||||
Port - Usb hub port number (starting from 1).
|
||||
Value - Feature value that will be cleared from
|
||||
that hub port.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS
|
||||
EFI_DEVICE
|
||||
EFI_TIME_OUT
|
||||
EFI_INVALID_PARAMETER
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_USB_DEVICE_REQUEST DevReq;
|
||||
EFI_STATUS EfiStatus;
|
||||
UINT32 UsbStatus;
|
||||
UINT32 Timeout;
|
||||
|
||||
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
|
||||
|
||||
//
|
||||
// Fill Device request packet
|
||||
//
|
||||
DevReq.RequestType = HUB_CLEAR_FEATURE_PORT_REQ_TYPE;
|
||||
DevReq.Request = HUB_CLEAR_FEATURE_PORT;
|
||||
DevReq.Value = Value;
|
||||
DevReq.Index = Port;
|
||||
DevReq.Length = 0;
|
||||
|
||||
Timeout = 3000;
|
||||
EfiStatus = UsbIo->UsbControlTransfer (
|
||||
UsbIo,
|
||||
&DevReq,
|
||||
EfiUsbNoData,
|
||||
Timeout,
|
||||
NULL,
|
||||
0,
|
||||
&UsbStatus
|
||||
);
|
||||
|
||||
return EfiStatus;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
HubGetHubStatus (
|
||||
IN EFI_USB_IO_PROTOCOL *UsbIo,
|
||||
OUT UINT32 *HubStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Get Hub Status
|
||||
|
||||
Arguments:
|
||||
UsbIo - EFI_USB_IO_PROTOCOL instance
|
||||
HubStatus - Current Hub status and change status.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS
|
||||
EFI_DEVICE
|
||||
EFI_TIME_OUT
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_USB_DEVICE_REQUEST DevReq;
|
||||
EFI_STATUS EfiStatus;
|
||||
UINT32 UsbStatus;
|
||||
UINT32 Timeout;
|
||||
|
||||
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
|
||||
|
||||
//
|
||||
// Fill Device request packet
|
||||
//
|
||||
DevReq.RequestType = HUB_GET_HUB_STATUS_REQ_TYPE;
|
||||
DevReq.Request = HUB_GET_HUB_STATUS;
|
||||
DevReq.Value = 0;
|
||||
DevReq.Index = 0;
|
||||
DevReq.Length = sizeof (UINT32);
|
||||
|
||||
Timeout = 3000;
|
||||
EfiStatus = UsbIo->UsbControlTransfer (
|
||||
UsbIo,
|
||||
&DevReq,
|
||||
EfiUsbDataIn,
|
||||
Timeout,
|
||||
HubStatus,
|
||||
sizeof (UINT32),
|
||||
&UsbStatus
|
||||
);
|
||||
|
||||
return EfiStatus;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
HubSetHubFeature (
|
||||
IN EFI_USB_IO_PROTOCOL *UsbIo,
|
||||
IN UINT8 Value
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Set a specified feature to the hub
|
||||
|
||||
Arguments:
|
||||
UsbIo - EFI_USB_IO_PROTOCOL instance
|
||||
Value - Feature value that will be set to the hub.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS
|
||||
EFI_DEVICE
|
||||
EFI_TIME_OUT
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_USB_DEVICE_REQUEST DevReq;
|
||||
EFI_STATUS EfiStatus;
|
||||
UINT32 UsbStatus;
|
||||
UINT32 Timeout;
|
||||
|
||||
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
|
||||
|
||||
//
|
||||
// Fill Device request packet
|
||||
//
|
||||
DevReq.RequestType = HUB_SET_HUB_FEATURE_REQ_TYPE;
|
||||
DevReq.Request = HUB_SET_HUB_FEATURE;
|
||||
DevReq.Value = Value;
|
||||
DevReq.Index = 0;
|
||||
DevReq.Length = 0;
|
||||
|
||||
Timeout = 3000;
|
||||
EfiStatus = UsbIo->UsbControlTransfer (
|
||||
UsbIo,
|
||||
&DevReq,
|
||||
EfiUsbNoData,
|
||||
Timeout,
|
||||
NULL,
|
||||
0,
|
||||
&UsbStatus
|
||||
);
|
||||
|
||||
return EfiStatus;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
HubClearHubFeature (
|
||||
IN EFI_USB_IO_PROTOCOL *UsbIo,
|
||||
IN UINT8 Value
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Set a specified feature to the hub
|
||||
|
||||
Arguments:
|
||||
UsbIo - EFI_USB_IO_PROTOCOL instance
|
||||
Value - Feature value that will be cleared from the hub.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS
|
||||
EFI_DEVICE
|
||||
EFI_TIME_OUT
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_USB_DEVICE_REQUEST DevReq;
|
||||
EFI_STATUS EfiStatus;
|
||||
UINT32 UsbStatus;
|
||||
UINT32 Timeout;
|
||||
|
||||
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
|
||||
|
||||
//
|
||||
// Fill Device request packet
|
||||
//
|
||||
DevReq.RequestType = HUB_CLEAR_FEATURE_REQ_TYPE;
|
||||
DevReq.Request = HUB_CLEAR_FEATURE;
|
||||
DevReq.Value = Value;
|
||||
DevReq.Index = 0;
|
||||
DevReq.Length = 0;
|
||||
|
||||
Timeout = 3000;
|
||||
EfiStatus = UsbIo->UsbControlTransfer (
|
||||
UsbIo,
|
||||
&DevReq,
|
||||
EfiUsbNoData,
|
||||
Timeout,
|
||||
NULL,
|
||||
0,
|
||||
&UsbStatus
|
||||
);
|
||||
|
||||
return EfiStatus;
|
||||
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
GetHubDescriptor (
|
||||
IN EFI_USB_IO_PROTOCOL *UsbIo,
|
||||
IN UINTN DescriptorSize,
|
||||
OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Get the hub descriptor
|
||||
|
||||
Arguments:
|
||||
UsbIo - EFI_USB_IO_PROTOCOL instance
|
||||
DescriptorSize - The length of Hub Descriptor buffer.
|
||||
HubDescriptor - Caller allocated buffer to store the hub descriptor
|
||||
if successfully returned.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS
|
||||
EFI_DEVICE
|
||||
EFI_TIME_OUT
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_USB_DEVICE_REQUEST DevReq;
|
||||
EFI_STATUS EfiStatus;
|
||||
UINT32 UsbStatus;
|
||||
UINT32 Timeout;
|
||||
|
||||
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
|
||||
|
||||
//
|
||||
// Fill Device request packet
|
||||
//
|
||||
DevReq.RequestType = USB_RT_HUB | 0x80;
|
||||
DevReq.Request = HUB_GET_DESCRIPTOR;
|
||||
DevReq.Value = USB_DT_HUB << 8;
|
||||
DevReq.Index = 0;
|
||||
DevReq.Length = (UINT16) DescriptorSize;
|
||||
|
||||
Timeout = 3000;
|
||||
EfiStatus = UsbIo->UsbControlTransfer (
|
||||
UsbIo,
|
||||
&DevReq,
|
||||
EfiUsbDataIn,
|
||||
Timeout,
|
||||
HubDescriptor,
|
||||
(UINT16) DescriptorSize,
|
||||
&UsbStatus
|
||||
);
|
||||
|
||||
return EfiStatus;
|
||||
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
DoHubConfig (
|
||||
IN USB_IO_CONTROLLER_DEVICE *HubController
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Configure the hub
|
||||
|
||||
Arguments:
|
||||
HubController - Indicating the hub controller device that
|
||||
will be configured
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS
|
||||
EFI_DEVICE_ERROR
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||
EFI_USB_HUB_DESCRIPTOR HubDescriptor;
|
||||
EFI_STATUS Status;
|
||||
EFI_USB_HUB_STATUS HubStatus;
|
||||
UINTN Index;
|
||||
UINT32 PortStatus;
|
||||
|
||||
UsbIo = &HubController->UsbIo;
|
||||
|
||||
ZeroMem (&HubDescriptor, sizeof (HubDescriptor));
|
||||
|
||||
//
|
||||
// First get the hub descriptor length
|
||||
//
|
||||
Status = GetHubDescriptor (UsbIo, 2, &HubDescriptor);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// First get the whole descriptor, then
|
||||
// get the number of hub ports
|
||||
//
|
||||
Status = GetHubDescriptor (
|
||||
UsbIo,
|
||||
HubDescriptor.Length,
|
||||
&HubDescriptor
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((gUSBErrorLevel, "Get hub descriptor fail\n"));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
HubController->DownstreamPorts = HubDescriptor.NbrPorts;
|
||||
|
||||
Status = HubGetHubStatus (UsbIo, (UINT32 *) &HubStatus);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((gUSBErrorLevel, "Get hub status fail when configure\n"));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Get all hub ports status
|
||||
//
|
||||
for (Index = 0; Index < HubController->DownstreamPorts; Index++) {
|
||||
|
||||
Status = HubGetPortStatus (UsbIo, (UINT8) (Index + 1), &PortStatus);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Power all the hub ports
|
||||
//
|
||||
for (Index = 0; Index < HubController->DownstreamPorts; Index++) {
|
||||
Status = HubSetPortFeature (
|
||||
UsbIo,
|
||||
(UINT8) (Index + 1),
|
||||
EfiUsbPortPower
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Clear Hub Status Change
|
||||
//
|
||||
Status = HubGetHubStatus (UsbIo, (UINT32 *) &HubStatus);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((gUSBErrorLevel, "Get hub status fail\n"));
|
||||
return EFI_DEVICE_ERROR;
|
||||
} else {
|
||||
//
|
||||
// Hub power supply change happens
|
||||
//
|
||||
if (HubStatus.HubChange & HUB_CHANGE_LOCAL_POWER) {
|
||||
HubClearHubFeature (UsbIo, C_HUB_LOCAL_POWER);
|
||||
}
|
||||
//
|
||||
// Hub change overcurrent happens
|
||||
//
|
||||
if (HubStatus.HubChange & HUB_CHANGE_OVERCURRENT) {
|
||||
HubClearHubFeature (UsbIo, C_HUB_OVER_CURRENT);
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
}
|
Reference in New Issue
Block a user