[USBOHCI_NEW] Bring-in the USB OHCI miniport driver created by Vadim Galyant. (#244)

[USBOHCI_NEW] Add the new usbport-based OHCI driver.
This commit is contained in:
Amine Khaldi 2018-01-12 21:09:58 +01:00 committed by Thomas Faber
parent 2a8864967f
commit f2f2dd0552
9 changed files with 3876 additions and 0 deletions

View file

@ -4,6 +4,7 @@ add_subdirectory(usbehci)
add_subdirectory(usbhub)
#add_subdirectory(usbhub_new)
add_subdirectory(usbohci)
#add_subdirectory(usbohci_new)
add_subdirectory(usbport)
add_subdirectory(usbstor)
add_subdirectory(usbuhci)

View file

@ -0,0 +1,15 @@
list(APPEND SOURCE
roothub.c
usbohci.c
usbohci.h)
add_library(usbohci SHARED
${SOURCE}
guid.c
usbohci.rc)
set_module_type(usbohci kernelmodedriver)
add_importlibs(usbohci usbport usbd hal ntoskrnl)
add_pch(usbohci usbohci.h SOURCE)
add_cd_file(TARGET usbohci DESTINATION reactos/system32/drivers NO_CAB FOR all)

View file

@ -0,0 +1,29 @@
#ifndef DBG_OHCI_H__
#define DBG_OHCI_H__
#if DBG
#ifndef NDEBUG_OHCI_TRACE
#define DPRINT_OHCI(fmt, ...) do { \
if (DbgPrint("(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__)) \
DbgPrint("(%s:%d) DbgPrint() failed!\n", __RELFILE__, __LINE__); \
} while (0)
#else
#if defined(_MSC_VER)
#define DPRINT_OHCI __noop
#else
#define DPRINT_OHCI(...) do {if(0) {DbgPrint(__VA_ARGS__);}} while(0)
#endif
#endif
#else /* not DBG */
#if defined(_MSC_VER)
#define DPRINT_OHCI __noop
#else
#define DPRINT_OHCI(...) do {if(0) {DbgPrint(__VA_ARGS__);}} while(0)
#endif /* _MSC_VER */
#endif /* not DBG */
#endif /* DBG_OHCI_H__ */

View file

@ -0,0 +1,9 @@
/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */
#include <wdm.h>
#include <initguid.h>
#include <wdmguid.h>
#include <hubbusif.h>
#include <usbbusif.h>
/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */

View file

@ -0,0 +1,328 @@
#define OHCI_NUMBER_OF_INTERRUPTS 32
#define OHCI_MAX_PORT_COUNT 15
#define ED_EOF -1
#define OHCI_MAXIMUM_OVERHEAD 210 // 5.4 FrameInterval Counter, in bit-times
#define OHCI_DEFAULT_FRAME_INTERVAL 11999 // 6.3.1 Frame Timing
#define OHCI_MINIMAL_POTPGT 25 // == 50 ms., PowerOnToPowerGoodTime (HcRhDescriptorA Register)
/* Controller states */
#define OHCI_HC_STATE_RESET 0
#define OHCI_HC_STATE_RESUME 1
#define OHCI_HC_STATE_OPERATIONAL 2
#define OHCI_HC_STATE_SUSPEND 3
/* Endpoint Descriptor Control */
#define OHCI_ED_DATA_FLOW_DIRECTION_FROM_TD 0
#define OHCI_ED_DATA_FLOW_DIRECTION_OUT 1
#define OHCI_ED_DATA_FLOW_DIRECTION_IN 2
#define OHCI_ENDPOINT_FULL_SPEED 0
#define OHCI_ENDPOINT_LOW_SPEED 1
#define OHCI_ENDPOINT_GENERAL_FORMAT 0
#define OHCI_ENDPOINT_ISOCHRONOUS_FORMAT 1
/* Transfer Descriptor Control */
#define OHCI_TD_INTERRUPT_IMMEDIATE 0
#define OHCI_TD_INTERRUPT_NONE 7
#define OHCI_TD_DIRECTION_PID_SETUP 0
#define OHCI_TD_DIRECTION_PID_OUT 1
#define OHCI_TD_DIRECTION_PID_IN 2
#define OHCI_TD_DIRECTION_PID_RESERVED 3
#define OHCI_TD_DATA_TOGGLE_FROM_ED 0
#define OHCI_TD_DATA_TOGGLE_DATA0 2
#define OHCI_TD_DATA_TOGGLE_DATA1 3
#define OHCI_TD_CONDITION_NO_ERROR 0x00
#define OHCI_TD_CONDITION_CRC_ERROR 0x01
#define OHCI_TD_CONDITION_BIT_STUFFING 0x02
#define OHCI_TD_CONDITION_TOGGLE_MISMATCH 0x03
#define OHCI_TD_CONDITION_STALL 0x04
#define OHCI_TD_CONDITION_NO_RESPONSE 0x05
#define OHCI_TD_CONDITION_PID_CHECK_FAILURE 0x06
#define OHCI_TD_CONDITION_UNEXPECTED_PID 0x07
#define OHCI_TD_CONDITION_DATA_OVERRUN 0x08
#define OHCI_TD_CONDITION_DATA_UNDERRUN 0x09
#define OHCI_TD_CONDITION_BUFFER_OVERRUN 0x0C
#define OHCI_TD_CONDITION_BUFFER_UNDERRUN 0x0D
#define OHCI_TD_CONDITION_NOT_ACCESSED 0x0E
#define OHCI_RH_STATUS_GOOD 1
typedef union _OHCI_TRANSFER_CONTROL {
struct {
ULONG Reserved : 18;
ULONG BufferRounding : 1;
ULONG DirectionPID : 2;
ULONG DelayInterrupt : 3;
ULONG DataToggle : 2;
ULONG ErrorCount : 2;
ULONG ConditionCode : 4;
};
ULONG AsULONG;
} OHCI_TRANSFER_CONTROL, *POHCI_TRANSFER_CONTROL;
C_ASSERT(sizeof(OHCI_TRANSFER_CONTROL) == sizeof(ULONG));
typedef struct _OHCI_TRANSFER_DESCRIPTOR { // must be aligned to a 16-byte boundary
OHCI_TRANSFER_CONTROL Control;
ULONG CurrentBuffer; // physical address of the next memory location
ULONG NextTD; // pointer to the next TD on the list of TDs
ULONG BufferEnd; // physical address of the last byte
} OHCI_TRANSFER_DESCRIPTOR, *POHCI_TRANSFER_DESCRIPTOR;
C_ASSERT(sizeof(OHCI_TRANSFER_DESCRIPTOR) == 16);
typedef union _OHCI_ISO_TRANSFER_CONTROL {
struct {
ULONG StartingFrame : 16;
ULONG Reserved1 : 5;
ULONG DelayInterrupt : 3;
ULONG FrameCount : 3;
ULONG Reserved2 : 1;
ULONG ConditionCode : 4;
};
ULONG AsULONG;
} OHCI_ISO_TRANSFER_CONTROL, *POHCI_ISO_TRANSFER_CONTROL;
C_ASSERT(sizeof(OHCI_ISO_TRANSFER_CONTROL) == sizeof(ULONG));
typedef struct _OHCI_ISO_TRANSFER_DESCRIPTOR { // must be aligned to a 32-byte boundary
OHCI_ISO_TRANSFER_CONTROL Control;
ULONG BufferPage0; // physical page number of the 1 byte of the data buffer
ULONG NextTD; // pointer to the next Isochronous TD on the queue of Isochronous TDs
ULONG BufferEnd; // physical address of the last byte in the buffer
USHORT Offset[8]; // for determine size and start addr. iso packet | PacketStatusWord - completion code
} OHCI_ISO_TRANSFER_DESCRIPTOR, *POHCI_ISO_TRANSFER_DESCRIPTOR;
C_ASSERT(sizeof(OHCI_ISO_TRANSFER_DESCRIPTOR) == 32);
typedef union _OHCI_ENDPOINT_CONTROL {
struct {
ULONG FunctionAddress : 7;
ULONG EndpointNumber : 4;
ULONG Direction : 2;
ULONG Speed : 1;
ULONG sKip : 1;
ULONG Format : 1;
ULONG MaximumPacketSize : 11;
ULONG Reserved : 5;
};
ULONG AsULONG;
} OHCI_ENDPOINT_CONTROL, *POHCI_ENDPOINT_CONTROL;
C_ASSERT(sizeof(OHCI_ENDPOINT_CONTROL) == sizeof(ULONG));
/* Bit flags for HeadPointer member of the EP descriptor */
#define OHCI_ED_HEAD_POINTER_HALT 0x00000001 // hardware stopped bit
#define OHCI_ED_HEAD_POINTER_CARRY 0x00000002 // hardware toggle carry bit
#define OHCI_ED_HEAD_POINTER_MASK 0XFFFFFFF0 // mask physical pointer
#define OHCI_ED_HEAD_POINTER_FLAGS_MASK 0X0000000F // mask bit flags
typedef struct _OHCI_ENDPOINT_DESCRIPTOR { // must be aligned to a 16-byte boundary
OHCI_ENDPOINT_CONTROL EndpointControl;
ULONG TailPointer; // if TailP and HeadP are different, then the list contains a TD to be processed
ULONG HeadPointer; // physical pointer to the next TD to be processed for this endpoint
ULONG NextED; // entry points to the next ED on the list
} OHCI_ENDPOINT_DESCRIPTOR, *POHCI_ENDPOINT_DESCRIPTOR;
C_ASSERT(sizeof(OHCI_ENDPOINT_DESCRIPTOR) == 16);
typedef struct _OHCI_HCCA { // must be located on a 256-byte boundary
ULONG InterrruptTable[OHCI_NUMBER_OF_INTERRUPTS];
USHORT FrameNumber;
USHORT Pad1;
ULONG DoneHead;
UCHAR reserved_hc[116];
UCHAR Pad[4];
} OHCI_HCCA, *POHCI_HCCA;
C_ASSERT(sizeof(OHCI_HCCA) == 256);
typedef union _OHCI_REG_CONTROL {
struct {
ULONG ControlBulkServiceRatio : 2;
ULONG PeriodicListEnable : 1;
ULONG IsochronousEnable : 1;
ULONG ControlListEnable : 1;
ULONG BulkListEnable : 1;
ULONG HostControllerFunctionalState : 2;
ULONG InterruptRouting : 1;
ULONG RemoteWakeupConnected : 1;
ULONG RemoteWakeupEnable : 1;
ULONG Reserved : 21;
};
ULONG AsULONG;
} OHCI_REG_CONTROL, *POHCI_REG_CONTROL;
C_ASSERT(sizeof(OHCI_REG_CONTROL) == sizeof(ULONG));
typedef union _OHCI_REG_COMMAND_STATUS {
struct {
ULONG HostControllerReset : 1;
ULONG ControlListFilled : 1;
ULONG BulkListFilled : 1;
ULONG OwnershipChangeRequest : 1;
ULONG Reserved1 : 12;
ULONG SchedulingOverrunCount : 1;
ULONG Reserved2 : 15;
};
ULONG AsULONG;
} OHCI_REG_COMMAND_STATUS, *POHCI_REG_COMMAND_STATUS;
C_ASSERT(sizeof(OHCI_REG_COMMAND_STATUS) == sizeof(ULONG));
typedef union _OHCI_REG_INTERRUPT_STATUS {
struct {
ULONG SchedulingOverrun : 1;
ULONG WritebackDoneHead : 1;
ULONG StartofFrame : 1;
ULONG ResumeDetected : 1;
ULONG UnrecoverableError : 1;
ULONG FrameNumberOverflow : 1;
ULONG RootHubStatusChange : 1;
ULONG Reserved1 : 23;
ULONG OwnershipChange : 1;
ULONG Reserved2 : 1;
};
ULONG AsULONG;
} OHCI_REG_INTERRUPT_STATUS, *POHCI_REG_INTERRUPT_STATUS;
C_ASSERT(sizeof(OHCI_REG_INTERRUPT_STATUS) == sizeof(ULONG));
typedef union _OHCI_REG_INTERRUPT_ENABLE_DISABLE {
struct {
ULONG SchedulingOverrun : 1;
ULONG WritebackDoneHead : 1;
ULONG StartofFrame : 1;
ULONG ResumeDetected : 1;
ULONG UnrecoverableError : 1;
ULONG FrameNumberOverflow : 1;
ULONG RootHubStatusChange : 1;
ULONG Reserved1 : 23;
ULONG OwnershipChange : 1;
ULONG MasterInterruptEnable : 1;
};
ULONG AsULONG;
} OHCI_REG_INTERRUPT_ENABLE_DISABLE, *POHCI_REG_INTERRUPT_ENABLE_DISABLE;
C_ASSERT(sizeof(OHCI_REG_INTERRUPT_ENABLE_DISABLE) == sizeof(ULONG));
typedef union _OHCI_REG_FRAME_INTERVAL {
struct {
ULONG FrameInterval : 14;
ULONG Reserved : 2;
ULONG FSLargestDataPacket : 15;
ULONG FrameIntervalToggle : 1;
};
ULONG AsULONG;
} OHCI_REG_FRAME_INTERVAL, *POHCI_REG_FRAME_INTERVAL;
C_ASSERT(sizeof(OHCI_REG_FRAME_INTERVAL) == sizeof(ULONG));
typedef union _OHCI_REG_RH_DESCRIPTORA {
struct {
ULONG NumberDownstreamPorts : 8;
ULONG PowerSwitchingMode : 1;
ULONG NoPowerSwitching : 1;
ULONG DeviceType : 1;
ULONG OverCurrentProtectionMode : 1;
ULONG NoOverCurrentProtection : 1;
ULONG Reserved : 11;
ULONG PowerOnToPowerGoodTime : 8;
};
ULONG AsULONG;
} OHCI_REG_RH_DESCRIPTORA, *POHCI_REG_RH_DESCRIPTORA;
C_ASSERT(sizeof(OHCI_REG_RH_DESCRIPTORA) == sizeof(ULONG));
typedef union _OHCI_REG_RH_STATUS {
union {
struct { // read
ULONG LocalPowerStatus : 1;
ULONG OverCurrentIndicator : 1;
ULONG Reserved10 : 13;
ULONG DeviceRemoteWakeupEnable : 1;
ULONG LocalPowerStatusChange : 1;
ULONG OverCurrentIndicatorChangeR : 1;
ULONG Reserved20 : 14;
};
struct { // write
ULONG ClearGlobalPower : 1;
ULONG Reserved11 : 14;
ULONG SetRemoteWakeupEnable : 1;
ULONG SetGlobalPower : 1;
ULONG OverCurrentIndicatorChangeW : 1;
ULONG Reserved22 : 13;
ULONG ClearRemoteWakeupEnable : 1;
};
};
ULONG AsULONG;
} OHCI_REG_RH_STATUS, *POHCI_REG_RH_STATUS;
C_ASSERT(sizeof(OHCI_REG_RH_STATUS) == sizeof(ULONG));
typedef union _OHCI_REG_RH_PORT_STATUS {
struct {
union {
struct { // read
USHORT CurrentConnectStatus : 1;
USHORT PortEnableStatus : 1;
USHORT PortSuspendStatus : 1;
USHORT PortOverCurrentIndicator : 1;
USHORT PortResetStatus : 1;
USHORT Reserved1r : 3;
USHORT PortPowerStatus : 1;
USHORT LowSpeedDeviceAttached : 1;
USHORT Reserved2r : 6;
};
struct { // write
USHORT ClearPortEnable : 1;
USHORT SetPortEnable : 1;
USHORT SetPortSuspend : 1;
USHORT ClearSuspendStatus : 1;
USHORT SetPortReset : 1;
USHORT Reserved1w : 3;
USHORT SetPortPower : 1;
USHORT ClearPortPower : 1;
USHORT Reserved2w : 6;
};
};
USHORT ConnectStatusChange : 1;
USHORT PortEnableStatusChange : 1;
USHORT PortSuspendStatusChange : 1;
USHORT PortOverCurrentIndicatorChange : 1;
USHORT PortResetStatusChange : 1;
USHORT Reserved3 : 11;
};
ULONG AsULONG;
} OHCI_REG_RH_PORT_STATUS, *POHCI_REG_RH_PORT_STATUS;
C_ASSERT(sizeof(OHCI_REG_RH_PORT_STATUS) == sizeof(ULONG));
typedef struct _OHCI_OPERATIONAL_REGISTERS {
ULONG HcRevision;
OHCI_REG_CONTROL HcControl;
OHCI_REG_COMMAND_STATUS HcCommandStatus;
OHCI_REG_INTERRUPT_STATUS HcInterruptStatus;
OHCI_REG_INTERRUPT_ENABLE_DISABLE HcInterruptEnable;
OHCI_REG_INTERRUPT_ENABLE_DISABLE HcInterruptDisable;
ULONG HcHCCA;
ULONG HcPeriodCurrentED;
ULONG HcControlHeadED;
ULONG HcControlCurrentED;
ULONG HcBulkHeadED;
ULONG HcBulkCurrentED;
ULONG HcDoneHead;
OHCI_REG_FRAME_INTERVAL HcFmInterval;
ULONG HcFmRemaining;
ULONG HcFmNumber;
ULONG HcPeriodicStart;
ULONG HcLSThreshold;
OHCI_REG_RH_DESCRIPTORA HcRhDescriptorA;
ULONG HcRhDescriptorB;
OHCI_REG_RH_STATUS HcRhStatus;
OHCI_REG_RH_PORT_STATUS HcRhPortStatus[OHCI_MAX_PORT_COUNT];
} OHCI_OPERATIONAL_REGISTERS, *POHCI_OPERATIONAL_REGISTERS;

View file

@ -0,0 +1,579 @@
#include "usbohci.h"
#define NDEBUG
#include <debug.h>
OHCI_REG_RH_DESCRIPTORA
NTAPI
OHCI_ReadRhDescriptorA(IN POHCI_EXTENSION OhciExtension)
{
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
OHCI_REG_RH_DESCRIPTORA DescriptorA;
PULONG DescriptorAReg;
ULONG ix;
OperationalRegs = OhciExtension->OperationalRegs;
DescriptorAReg = (PULONG)&OperationalRegs->HcRhDescriptorA;
DPRINT("OHCI_ReadRhDescriptorA: OhciExtension - %p\n", OhciExtension);
for (ix = 0; ix < 10; ix++)
{
DescriptorA.AsULONG = READ_REGISTER_ULONG(DescriptorAReg);
if (DescriptorA.AsULONG != 0 &&
DescriptorA.Reserved == 0 &&
DescriptorA.NumberDownstreamPorts <= OHCI_MAX_PORT_COUNT)
{
break;
}
DPRINT1("OHCI_ReadRhDescriptorA: DescriptorA - %lX, ix - %d\n",
DescriptorA.AsULONG, ix);
KeStallExecutionProcessor(5);
}
return DescriptorA;
}
VOID
NTAPI
OHCI_RH_GetRootHubData(IN PVOID ohciExtension,
IN PVOID rootHubData)
{
POHCI_EXTENSION OhciExtension;
PUSBPORT_ROOT_HUB_DATA RootHubData;
OHCI_REG_RH_DESCRIPTORA DescriptorA;
UCHAR PowerOnToPowerGoodTime;
USBPORT_HUB_11_CHARACTERISTICS HubCharacteristics;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_GetRootHubData: OhciExtension - %p, rootHubData - %p\n",
OhciExtension,
rootHubData);
RootHubData = rootHubData;
DescriptorA = OHCI_ReadRhDescriptorA(OhciExtension);
RootHubData->NumberOfPorts = DescriptorA.NumberDownstreamPorts;
/* Waiting time (in 2 ms intervals) */
PowerOnToPowerGoodTime = DescriptorA.PowerOnToPowerGoodTime;
if (PowerOnToPowerGoodTime <= OHCI_MINIMAL_POTPGT)
PowerOnToPowerGoodTime = OHCI_MINIMAL_POTPGT;
RootHubData->PowerOnToPowerGood = PowerOnToPowerGoodTime;
HubCharacteristics.AsUSHORT = 0;
if (DescriptorA.PowerSwitchingMode)
{
/* Individual port power switching */
HubCharacteristics.PowerControlMode = 1;
}
else
{
/* Ganged power switching */
HubCharacteristics.PowerControlMode = 0;
}
HubCharacteristics.NoPowerSwitching = 0;
/* always 0 (OHCI RH is not a compound device) */
ASSERT(DescriptorA.DeviceType == 0);
HubCharacteristics.PartOfCompoundDevice = DescriptorA.DeviceType;
HubCharacteristics.OverCurrentProtectionMode = DescriptorA.OverCurrentProtectionMode;
HubCharacteristics.NoOverCurrentProtection = DescriptorA.NoOverCurrentProtection;
RootHubData->HubCharacteristics.Usb11HubCharacteristics = HubCharacteristics;
RootHubData->HubControlCurrent = 0;
}
MPSTATUS
NTAPI
OHCI_RH_GetStatus(IN PVOID ohciExtension,
IN PUSHORT Status)
{
DPRINT("OHCI_RH_GetStatus: \n");
*Status = OHCI_RH_STATUS_GOOD;
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_GetPortStatus(IN PVOID ohciExtension,
IN USHORT Port,
IN PUSB_PORT_STATUS_AND_CHANGE PortStatus)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
OHCI_REG_RH_PORT_STATUS OhciPortStatus;
ULONG ix;
ULONG Reserved;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_GetPortStatus: OhciExtension - %p, Port - %x, PortStatus - %lX\n",
OhciExtension,
Port,
PortStatus->AsUlong32);
ASSERT(Port > 0);
OperationalRegs = OhciExtension->OperationalRegs;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
for (ix = 0; ix < 10; ix++)
{
OhciPortStatus.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
Reserved = OhciPortStatus.Reserved1r |
OhciPortStatus.Reserved2r |
OhciPortStatus.Reserved3;
if (OhciPortStatus.AsULONG && !Reserved)
break;
DPRINT("OHCI_RH_GetPortStatus: OhciPortStatus - %X\n", OhciPortStatus.AsULONG);
KeStallExecutionProcessor(5);
}
PortStatus->AsUlong32 = OhciPortStatus.AsULONG;
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_GetHubStatus(IN PVOID ohciExtension,
IN PUSB_HUB_STATUS_AND_CHANGE HubStatus)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG RhStatusReg;
OHCI_REG_RH_STATUS HcRhStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_GetHubStatus: ohciExtension - %p, HubStatus - %lX\n",
ohciExtension,
HubStatus->AsUlong32);
OperationalRegs = OhciExtension->OperationalRegs;
RhStatusReg = (PULONG)&OperationalRegs->HcRhStatus;
HcRhStatus.AsULONG = READ_REGISTER_ULONG(RhStatusReg);
HubStatus->HubStatus.LocalPowerLost = HcRhStatus.LocalPowerStatus;
HubStatus->HubChange.LocalPowerChange = HcRhStatus.LocalPowerStatusChange;
HubStatus->HubStatus.OverCurrent = HcRhStatus.OverCurrentIndicator;
HubStatus->HubChange.OverCurrentChange = HcRhStatus.OverCurrentIndicatorChangeR;
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_SetFeaturePortReset(IN PVOID ohciExtension,
IN USHORT Port)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
OHCI_REG_RH_PORT_STATUS PortStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_SetFeaturePortReset: OhciExtension - %p, Port - %x\n",
OhciExtension,
Port);
ASSERT(Port > 0);
OperationalRegs = OhciExtension->OperationalRegs;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
PortStatus.AsULONG = 0;
PortStatus.SetPortReset = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortStatus.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_SetFeaturePortPower(IN PVOID ohciExtension,
IN USHORT Port)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
OHCI_REG_RH_PORT_STATUS PortStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_SetFeaturePortPower: OhciExtension - %p, Port - %x\n",
OhciExtension,
Port);
ASSERT(Port > 0);
OperationalRegs = OhciExtension->OperationalRegs;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
PortStatus.AsULONG = 0;
PortStatus.SetPortPower = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortStatus.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_SetFeaturePortEnable(IN PVOID ohciExtension,
IN USHORT Port)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
OHCI_REG_RH_PORT_STATUS PortStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_SetFeaturePortEnable: OhciExtension - %p, Port - %x\n",
OhciExtension,
Port);
ASSERT(Port > 0);
OperationalRegs = OhciExtension->OperationalRegs;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
PortStatus.AsULONG = 0;
PortStatus.SetPortEnable = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortStatus.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_SetFeaturePortSuspend(IN PVOID ohciExtension,
IN USHORT Port)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
OHCI_REG_RH_PORT_STATUS PortStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_SetFeaturePortSuspend: OhciExtension - %p, Port - %x\n",
OhciExtension,
Port);
ASSERT(Port > 0);
OperationalRegs = OhciExtension->OperationalRegs;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
PortStatus.AsULONG = 0;
PortStatus.SetPortSuspend = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortStatus.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortEnable(IN PVOID ohciExtension,
IN USHORT Port)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
OHCI_REG_RH_PORT_STATUS PortStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_ClearFeaturePortEnable: OhciExtension - %p, Port - %x\n",
OhciExtension,
Port);
ASSERT(Port > 0);
OperationalRegs = OhciExtension->OperationalRegs;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
PortStatus.AsULONG = 0;
PortStatus.ClearPortEnable = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortStatus.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortPower(IN PVOID ohciExtension,
IN USHORT Port)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
OHCI_REG_RH_PORT_STATUS PortStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_ClearFeaturePortPower: OhciExtension - %p, Port - %x\n",
OhciExtension,
Port);
ASSERT(Port > 0);
OperationalRegs = OhciExtension->OperationalRegs;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
PortStatus.AsULONG = 0;
PortStatus.ClearPortPower = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortStatus.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortSuspend(IN PVOID ohciExtension,
IN USHORT Port)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
OHCI_REG_RH_PORT_STATUS PortStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_ClearFeaturePortSuspend: OhciExtension - %p, Port - %x\n",
OhciExtension,
Port);
ASSERT(Port > 0);
OperationalRegs = OhciExtension->OperationalRegs;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
PortStatus.AsULONG = 0;
PortStatus.ClearSuspendStatus = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortStatus.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortEnableChange(IN PVOID ohciExtension,
IN USHORT Port)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
OHCI_REG_RH_PORT_STATUS PortStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_ClearFeaturePortEnableChange: ohciExtension - %p, Port - %x\n",
ohciExtension,
Port);
ASSERT(Port > 0);
OperationalRegs = OhciExtension->OperationalRegs;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
PortStatus.AsULONG = 0;
PortStatus.PortEnableStatusChange = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortStatus.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortConnectChange(IN PVOID ohciExtension,
IN USHORT Port)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
OHCI_REG_RH_PORT_STATUS PortStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_ClearFeaturePortConnectChange: OhciExtension - %p, Port - %x\n",
OhciExtension,
Port);
ASSERT(Port > 0);
OperationalRegs = OhciExtension->OperationalRegs;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
PortStatus.AsULONG = 0;
PortStatus.ConnectStatusChange = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortStatus.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortResetChange(IN PVOID ohciExtension,
IN USHORT Port)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
OHCI_REG_RH_PORT_STATUS PortStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_ClearFeaturePortResetChange: OhciExtension - %p, Port - %x\n",
OhciExtension,
Port);
ASSERT(Port > 0);
OperationalRegs = OhciExtension->OperationalRegs;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
PortStatus.AsULONG = 0;
PortStatus.PortResetStatusChange = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortStatus.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortSuspendChange(IN PVOID ohciExtension,
IN USHORT Port)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
OHCI_REG_RH_PORT_STATUS PortStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_ClearFeaturePortSuspendChange: OhciExtension - %p, Port - %x\n",
OhciExtension,
Port);
ASSERT(Port > 0);
OperationalRegs = OhciExtension->OperationalRegs;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
PortStatus.AsULONG = 0;
PortStatus.PortSuspendStatusChange = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortStatus.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortOvercurrentChange(IN PVOID ohciExtension,
IN USHORT Port)
{
POHCI_EXTENSION OhciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG PortStatusReg;
PULONG RhStatusReg;
OHCI_REG_RH_PORT_STATUS PortStatus;
OHCI_REG_RH_STATUS RhStatus;
OhciExtension = ohciExtension;
DPRINT("OHCI_RH_ClearFeaturePortOvercurrentChange: OhciExtension - %p, Port - %x\n",
OhciExtension,
Port);
OperationalRegs = OhciExtension->OperationalRegs;
if (Port)
{
/* USBPORT_RECIPIENT_PORT */
PortStatus.AsULONG = 0;
PortStatus.PortOverCurrentIndicatorChange = 1;
PortStatusReg = (PULONG)&OperationalRegs->HcRhPortStatus[Port-1];
WRITE_REGISTER_ULONG(PortStatusReg, PortStatus.AsULONG);
}
else
{
/* USBPORT_RECIPIENT_HUB */
RhStatus.AsULONG = 0;
RhStatus.OverCurrentIndicatorChangeW = 1;
RhStatusReg = (PULONG)&OperationalRegs->HcRhStatus;
WRITE_REGISTER_ULONG(RhStatusReg, RhStatus.AsULONG);
}
return MP_STATUS_SUCCESS;
}
VOID
NTAPI
OHCI_RH_DisableIrq(IN PVOID ohciExtension)
{
POHCI_EXTENSION OhciExtension = ohciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG InterruptDisableReg;
OHCI_REG_INTERRUPT_ENABLE_DISABLE InterruptDisable;
DPRINT("OHCI_RH_DisableIrq: OhciExtension - %p\n", OhciExtension);
OperationalRegs = OhciExtension->OperationalRegs;
InterruptDisableReg = (PULONG)&OperationalRegs->HcInterruptDisable;
InterruptDisable.AsULONG = 0;
InterruptDisable.RootHubStatusChange = 1;
WRITE_REGISTER_ULONG(InterruptDisableReg, InterruptDisable.AsULONG);
}
VOID
NTAPI
OHCI_RH_EnableIrq(IN PVOID ohciExtension)
{
POHCI_EXTENSION OhciExtension = ohciExtension;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
PULONG InterruptEnableReg;
OHCI_REG_INTERRUPT_ENABLE_DISABLE InterruptEnable;
DPRINT("OHCI_RH_EnableIrq: OhciExtension - %p\n", OhciExtension);
OperationalRegs = OhciExtension->OperationalRegs;
InterruptEnableReg = (PULONG)&OperationalRegs->HcInterruptEnable;
InterruptEnable.AsULONG = 0;
InterruptEnable.RootHubStatusChange = 1;
WRITE_REGISTER_ULONG(InterruptEnableReg, InterruptEnable.AsULONG);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,257 @@
#ifndef USBOHCI_H__
#define USBOHCI_H__
#include <ntddk.h>
#include <windef.h>
#include <stdio.h>
#include <hubbusif.h>
#include <usbbusif.h>
#include <usbdlib.h>
#include <drivers/usbport/usbmport.h>
#include "hardware.h"
extern USBPORT_REGISTRATION_PACKET RegPacket;
#define OHCI_HCD_ED_FLAG_CONTROL 0x00000001
#define OHCI_HCD_ED_FLAG_RESET_ON_HALT 0x00000008
#define OHCI_HCD_ED_FLAG_NOT_ACCESSED 0x00000010
#define OHCI_HCD_TD_FLAG_ALLOCATED 0x00000001
#define OHCI_HCD_TD_FLAG_PROCESSED 0x00000002
#define OHCI_HCD_TD_FLAG_CONTROL_STATUS 0x00000004
#define OHCI_HCD_TD_FLAG_DONE 0x00000008
#define OHCI_HCD_TD_FLAG_NOT_ACCESSED 0x00000010
#define OHCI_MAX_ISO_TRANSFER_SIZE 0x10000
#define OHCI_MAX_CONTROL_TRANSFER_SIZE 0x10000
#define OHCI_MAX_BULK_TRANSFER_SIZE 0x40000
#define OHCI_MAX_INTERRUPT_TRANSFER_SIZE 0x1000
#define OHCI_MAX_ISO_TD_COUNT 64
#define OHCI_MAX_CONTROL_TD_COUNT 38
#define OHCI_MAX_BULK_TD_COUNT 68
#define OHCI_MAX_INTERRUPT_TD_COUNT 4
#define OHCI_NON_DATA_CONTROL_TDS 2
#define OHCI_TRANSFER_FLAGS_SHORT_TRANSFER_OK 1
typedef struct _OHCI_TRANSFER *POHCI_TRANSFER;
typedef union _OHCI_HW_TRANSFER_DESCRIPTOR {
struct {
OHCI_TRANSFER_DESCRIPTOR gTD; // must be aligned to a 16-byte boundary
USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
ULONG Padded[2];
};
struct {
OHCI_ISO_TRANSFER_DESCRIPTOR iTD; // must be aligned to a 32-byte boundary
};
} OHCI_HW_TRANSFER_DESCRIPTOR, *POHCI_HW_TRANSFER_DESCRIPTOR;
C_ASSERT(sizeof(OHCI_HW_TRANSFER_DESCRIPTOR) == 32);
typedef struct _OHCI_HCD_TD {
/* Hardware part */
OHCI_HW_TRANSFER_DESCRIPTOR HwTD; // must be aligned to a 32-byte boundary
/* Software part */
ULONG PhysicalAddress;
ULONG Flags;
ULONG OhciTransfer;
ULONG NextHcdTD;
ULONG TransferLen;
LIST_ENTRY DoneLink;
ULONG Pad[1];
} OHCI_HCD_TD, *POHCI_HCD_TD;
C_ASSERT(sizeof(OHCI_HCD_TD) == 64);
typedef struct _OHCI_HCD_ED {
/* Hardware part */
OHCI_ENDPOINT_DESCRIPTOR HwED; // must be aligned to a 16-byte boundary
/* Software part */
ULONG PhysicalAddress;
ULONG Flags;
LIST_ENTRY HcdEDLink;
ULONG Pad[8];
} OHCI_HCD_ED, *POHCI_HCD_ED;
C_ASSERT(sizeof(OHCI_HCD_ED) == 64);
#define OHCI_STATIC_ED_TYPE_INTERRUPT 0
#define OHCI_STATIC_ED_TYPE_CONTROL 1
#define OHCI_STATIC_ED_TYPE_BULK 2
typedef struct _OHCI_STATIC_ED {
/* Software only */
POHCI_ENDPOINT_DESCRIPTOR HwED;
ULONG PhysicalAddress;
UCHAR HeadIndex;
UCHAR Reserved[3];
LIST_ENTRY Link;
ULONG Type;
PULONG pNextED;
ULONG HccaIndex;
} OHCI_STATIC_ED, *POHCI_STATIC_ED;
typedef struct _OHCI_HC_RESOURCES {
OHCI_HCCA HcHCCA; // (256 byte align)
OHCI_ENDPOINT_DESCRIPTOR InterrruptHeadED[63]; // (16 byte align)
OHCI_ENDPOINT_DESCRIPTOR ControlHeadED; // (16 byte align)
OHCI_ENDPOINT_DESCRIPTOR BulkHeadED; // (16 byte align)
} OHCI_HC_RESOURCES, *POHCI_HC_RESOURCES;
/* OHCI Endpoint follows USBPORT Endpoint */
typedef struct _OHCI_ENDPOINT {
ULONG Reserved;
USBPORT_ENDPOINT_PROPERTIES EndpointProperties;
POHCI_STATIC_ED HeadED;
POHCI_HCD_TD FirstTD;
POHCI_HCD_ED HcdED;
ULONG MaxTransferDescriptors;
POHCI_HCD_TD HcdHeadP;
POHCI_HCD_TD HcdTailP;
LIST_ENTRY TDList;
} OHCI_ENDPOINT, *POHCI_ENDPOINT;
/* OHCI Transfer follows USBPORT Transfer */
typedef struct _OHCI_TRANSFER {
ULONG Reserved;
ULONG TransferLen;
PUSBPORT_TRANSFER_PARAMETERS TransferParameters;
ULONG PendingTDs;
ULONG Flags;
USBD_STATUS USBDStatus;
POHCI_ENDPOINT OhciEndpoint;
POHCI_HCD_TD NextTD;
POHCI_HCD_TD ControlStatusTD;
} OHCI_TRANSFER, *POHCI_TRANSFER;
/* OHCI Extension follows USBPORT Extension */
typedef struct _OHCI_EXTENSION {
ULONG Reserved;
POHCI_OPERATIONAL_REGISTERS OperationalRegs;
OHCI_REG_FRAME_INTERVAL FrameInterval;
ULONG FrameHighPart;
ULONG HcdFmNumber;
POHCI_HC_RESOURCES HcResourcesVA;
POHCI_HC_RESOURCES HcResourcesPA;
OHCI_STATIC_ED IntStaticED[63];
OHCI_STATIC_ED ControlStaticED;
OHCI_STATIC_ED BulkStaticED;
} OHCI_EXTENSION, *POHCI_EXTENSION;
/* roothub.c */
VOID
NTAPI
OHCI_RH_GetRootHubData(
IN PVOID ohciExtension,
IN PVOID rootHubData);
MPSTATUS
NTAPI
OHCI_RH_GetStatus(
IN PVOID ohciExtension,
IN PUSHORT Status);
MPSTATUS
NTAPI
OHCI_RH_GetPortStatus(
IN PVOID ohciExtension,
IN USHORT Port,
IN PUSB_PORT_STATUS_AND_CHANGE PortStatus);
MPSTATUS
NTAPI
OHCI_RH_GetHubStatus(
IN PVOID ohciExtension,
IN PUSB_HUB_STATUS_AND_CHANGE HubStatus);
MPSTATUS
NTAPI
OHCI_RH_SetFeaturePortReset(
IN PVOID ohciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
OHCI_RH_SetFeaturePortPower(
IN PVOID ohciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
OHCI_RH_SetFeaturePortEnable(
IN PVOID ohciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
OHCI_RH_SetFeaturePortSuspend(
IN PVOID ohciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortEnable(
IN PVOID ohciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortPower(
IN PVOID ohciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortSuspend(
IN PVOID ohciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortEnableChange(
IN PVOID ohciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortConnectChange(
IN PVOID ohciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortResetChange(
IN PVOID ohciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortSuspendChange(
IN PVOID ohciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
OHCI_RH_ClearFeaturePortOvercurrentChange(
IN PVOID ohciExtension,
IN USHORT Port);
VOID
NTAPI
OHCI_RH_DisableIrq(
IN PVOID ohciExtension);
VOID
NTAPI
OHCI_RH_EnableIrq(
IN PVOID ohciExtension);
OHCI_REG_RH_DESCRIPTORA
NTAPI
OHCI_ReadRhDescriptorA(
IN POHCI_EXTENSION OhciExtension);
#endif /* USBOHCI_H__ */

View file

@ -0,0 +1,5 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "USB OHCI miniport driver"
#define REACTOS_STR_INTERNAL_NAME "usbohci"
#define REACTOS_STR_ORIGINAL_FILENAME "usbohci.sys"
#include <reactos/version.rc>