[USBUHCI_NEW] Bring-in the USB UHCI miniport driver created by Vadim Galyant. (#245)

This commit is contained in:
Amine Khaldi 2018-09-01 16:45:45 +01:00 committed by Thomas Faber
parent 69a040d275
commit a1a65e940a
9 changed files with 3824 additions and 0 deletions

View file

@ -9,3 +9,4 @@ add_subdirectory(usbport)
add_subdirectory(usbstor)
#add_subdirectory(usbstor_new)
add_subdirectory(usbuhci)
#add_subdirectory(usbuhci_new)

View file

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

View file

@ -0,0 +1,49 @@
#ifndef DBG_UHCI_H__
#define DBG_UHCI_H__
#if DBG
#ifndef NDEBUG_UHCI_TRACE
#define DPRINT_UHCI(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_UHCI __noop
#else
#define DPRINT_UHCI(...) do {if(0) {DbgPrint(__VA_ARGS__);}} while(0)
#endif
#endif
#ifndef NDEBUG_UHCI_IMPLEMENT
#define DPRINT_IMPL(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_IMPL __noop
#else
#define DPRINT_IMPL(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#endif
#endif
#else /* not DBG */
#if defined(_MSC_VER)
#define DPRINT_UHCI __noop
#define DPRINT_IMPL __noop
#else
#define DPRINT_UHCI(...) do {if(0) {DbgPrint(__VA_ARGS__);}} while(0)
#define DPRINT_IMPL(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#endif /* _MSC_VER */
#endif /* not DBG */
#endif /* DBG_UHCI_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,218 @@
#define UHCI_FRAME_LIST_MAX_ENTRIES 1024 // Number of frames in Frame List
#define UHCI_NUM_ROOT_HUB_PORTS 2
/* UHCI HC I/O Registers offset (PUSHORT) */
#define UHCI_USBCMD 0 // USB Command R/W
#define UHCI_USBSTS 1 // USB Status R/WC
#define UHCI_USBINTR 2 // USB Interrupt Enable R/W
#define UHCI_FRNUM 3 // Frame Number R/W WORD writeable only
#define UHCI_FRBASEADD 4 // Frame List Base Address R/W // 32 bit
#define UHCI_SOFMOD 6 // Start Of Frame Modify R/W // 8 bit
#define UHCI_PORTSC1 8 // Port 1 Status/Control R/WC WORD writeable only
#define UHCI_PORTSC2 9 // Port 2 Status/Control R/WC WORD writeable only
/* PCI Legacy Support */
#define PCI_LEGSUP 0xC0 // Legacy Support register offset. R/WC
#define PCI_LEGSUP_USBPIRQDEN 0x2000
#define PCI_LEGSUP_CLEAR_SMI 0x8F00
/* LEGSUP Legacy support register (PCI Configuration - Function 2) */
typedef union _UHCI_PCI_LEGSUP {
struct {
USHORT Smi60Read : 1; // (60REN) Trap/SMI On 60h Read Enable. R/W.
USHORT Smi60Write : 1; // (60WEN) Trap/SMI On 60h Write Enable. R/W.
USHORT Smi64Read : 1; // (64REN) Trap/SMI On 64h Read Enable. R/W.
USHORT Smi64Write : 1; // (64WEN) Trap/SMI On 64h Write Enable. R/W.
USHORT SmiIrq : 1; // (USBSMIEN) Trap/SMI ON IRQ Enable. R/W.
USHORT A20Gate : 1; // (A20PTEN) A20Gate Pass Through Enable. R/W.
USHORT PassThroughStatus : 1; // (PSS) Pass Through Status. RO.
USHORT SmiEndPassThrough : 1; // (SMIEPTE) SMI At End Of Pass Through Enable. R/W.
USHORT TrapBy60ReadStatus : 1; // (TBY60R) Trap By 60h Read Status. R/WC.
USHORT TrapBy60WriteStatus : 1; // (TBY60W) Trap By 60h Write Status. R/WC.
USHORT TrapBy64ReadStatus : 1; // (TBY64R) Trap By 64h Read Status. R/WC.
USHORT TrapBy64WriteStatus : 1; // (TBY64W) Trap By 64h Write Status. R/WC.
USHORT UsbIrqStatus : 1; // (USBIRQS) USB IRQ Status. RO.
USHORT UsbPIRQ : 1; // (USBPIRQDEN) USB PIRQ Enable. R/W.
USHORT Reserved : 1;
USHORT EndA20GateStatus : 1; // (A20PTS) End OF A20GATE Pass Through Status. R/WC.
};
USHORT AsUSHORT;
} UHCI_PCI_LEGSUP;
C_ASSERT(sizeof(UHCI_PCI_LEGSUP) == sizeof(USHORT));
/* USBCMD Command register */
typedef union _UHCI_USB_COMMAND {
struct {
USHORT Run : 1;
USHORT HcReset : 1;
USHORT GlobalReset : 1;
USHORT GlobalSuspend : 1;
USHORT GlobalResume : 1; // Force Global Resume
USHORT SoftwareDebug : 1; // 0 - Normal Mode, 1 - Debug mode
USHORT ConfigureFlag : 1; // no effect on the hardware
USHORT MaxPacket : 1; // 0 = 32, 1 = 64
USHORT Reserved : 8;
};
USHORT AsUSHORT;
} UHCI_USB_COMMAND;
C_ASSERT(sizeof(UHCI_USB_COMMAND) == sizeof(USHORT));
/* USBSTS Status register */
#define UHCI_USB_STATUS_MASK 0x3F
typedef union _UHCI_USB_STATUS {
struct {
USHORT Interrupt : 1; // due to IOC (Interrupt On Complete)
USHORT ErrorInterrupt : 1; // due to error
USHORT ResumeDetect : 1;
USHORT HostSystemError : 1; // PCI problems
USHORT HcProcessError : 1; // Schedule is buggy
USHORT HcHalted : 1;
USHORT Reserved : 10;
};
USHORT AsUSHORT;
} UHCI_USB_STATUS;
C_ASSERT(sizeof(UHCI_USB_STATUS) == sizeof(USHORT));
/* USBINTR Interrupt enable register */
typedef union _UHCI_INTERRUPT_ENABLE {
struct {
USHORT TimeoutCRC : 1; // Timeout/CRC error enable
USHORT ResumeInterrupt : 1;
USHORT InterruptOnComplete : 1;
USHORT ShortPacket : 1;
USHORT Reserved : 12;
};
USHORT AsUSHORT;
} UHCI_INTERRUPT_ENABLE;
C_ASSERT(sizeof(UHCI_INTERRUPT_ENABLE) == sizeof(USHORT));
/* FRNUM Frame Number register */
#define UHCI_FRNUM_FRAME_MASK 0x7FF
#define UHCI_FRNUM_INDEX_MASK 0x3FF
#define UHCI_FRNUM_OVERFLOW_LIST 0x400
/* PORTSC(1|2) USB port status and control registers */
typedef union _UHCI_PORT_STATUS_CONTROL {
struct {
USHORT CurrentConnectStatus : 1;
USHORT ConnectStatusChange : 1;
USHORT PortEnabledDisabled : 1;
USHORT PortEnableDisableChange : 1;
USHORT LineStatus : 2; // D+ and D-
USHORT ResumeDetect : 1;
USHORT Reserved1 : 1; // always 1
USHORT LowSpeedDevice : 1; // LS device Attached
USHORT PortReset : 1;
USHORT Reserved2 : 2; // Intel use it (not UHCI 1.1d spec)
USHORT Suspend : 1;
USHORT Reserved3 : 3; // write zeroes
};
USHORT AsUSHORT;
} UHCI_PORT_STATUS_CONTROL;
C_ASSERT(sizeof(UHCI_PORT_STATUS_CONTROL) == sizeof(USHORT));
typedef struct _UHCI_HW_REGISTERS {
UHCI_USB_COMMAND HcCommand; // R/W
UHCI_USB_STATUS HcStatus; // R/WC
UHCI_INTERRUPT_ENABLE HcInterruptEnable; // R/W
USHORT FrameNumber; // R/W WORD writeable only
ULONG FrameAddress; // R/W
UCHAR SOF_Modify; // R/W
UCHAR Reserved[3];
UHCI_PORT_STATUS_CONTROL PortControl[UHCI_NUM_ROOT_HUB_PORTS]; // R/WC WORD writeable only
} UHCI_HW_REGISTERS, *PUHCI_HW_REGISTERS;
/* Transfer Descriptor (TD) */
#define UHCI_TD_STS_ACTIVE (1 << 7)
#define UHCI_TD_STS_STALLED (1 << 6)
#define UHCI_TD_STS_DATA_BUFFER_ERROR (1 << 5)
#define UHCI_TD_STS_BABBLE_DETECTED (1 << 4)
#define UHCI_TD_STS_NAK_RECEIVED (1 << 3)
#define UHCI_TD_STS_TIMEOUT_CRC_ERROR (1 << 2)
#define UHCI_TD_STS_BITSTUFF_ERROR (1 << 1)
//#define UHCI_TD_STS_Reserved (1 << 0)
#define UHCI_TD_VALID_LENGTH 0x4FF
#define UHCI_TD_LENGTH_INVALID 0x7FE
#define UHCI_TD_LENGTH_NULL 0x7FF
typedef union _UHCI_CONTROL_STATUS {
struct {
ULONG ActualLength : 11; // encoded as n - 1
ULONG Reserved1 : 5;
ULONG Status : 8; // UHCI_TD_STS_ xxx
ULONG InterruptOnComplete : 1;
ULONG IsochronousType : 1;
ULONG LowSpeedDevice : 1;
ULONG ErrorCounter : 2;
ULONG ShortPacketDetect : 1;
ULONG Reserved2 : 2;
};
ULONG AsULONG;
} UHCI_CONTROL_STATUS;
C_ASSERT(sizeof(UHCI_CONTROL_STATUS) == sizeof(ULONG));
#define UHCI_TD_PID_IN 0x69
#define UHCI_TD_PID_OUT 0xE1
#define UHCI_TD_PID_SETUP 0x2D
#define UHCI_TD_PID_DATA0 0
#define UHCI_TD_PID_DATA1 1
typedef union _UHCI_TD_TOKEN {
struct {
ULONG PIDCode : 8;
ULONG DeviceAddress : 7;
ULONG Endpoint : 4;
ULONG DataToggle : 1;
ULONG Reserved : 1;
ULONG MaximumLength : 11;
};
ULONG AsULONG;
} UHCI_TD_TOKEN;
C_ASSERT(sizeof(UHCI_TD_TOKEN) == sizeof(ULONG));
#define UHCI_TD_LINK_PTR_VALID (0 << 0)
#define UHCI_TD_LINK_PTR_TERMINATE (1 << 0)
#define UHCI_TD_LINK_PTR_TD (0 << 1)
#define UHCI_TD_LINK_PTR_QH (1 << 1)
#define UHCI_TD_LINK_PTR_BREADTH_FIRST (0 << 2)
#define UHCI_TD_LINK_PTR_DEPTH_FIRST (1 << 2)
#define UHCI_TD_LINK_POINTER_MASK 0xFFFFFFF0
typedef struct _UHCI_TD { // Transfer Descriptors always aligned on 16-byte boundaries
ULONG NextElement;
UHCI_CONTROL_STATUS ControlStatus;
UHCI_TD_TOKEN Token;
ULONG Buffer;
} UHCI_TD, *PUHCI_TD;
C_ASSERT(sizeof(UHCI_TD) == 16);
/* Queue Header (QH) */
#define UHCI_QH_HEAD_LINK_PTR_VALID (0 << 0)
#define UHCI_QH_HEAD_LINK_PTR_TERMINATE (1 << 0)
#define UHCI_QH_HEAD_LINK_PTR_TD (0 << 1)
#define UHCI_QH_HEAD_LINK_PTR_QH (1 << 1)
#define UHCI_QH_HEAD_LINK_POINTER_MASK 0xFFFFFFF0
#define UHCI_QH_ELEMENT_LINK_PTR_VALID (0 << 0)
#define UHCI_QH_ELEMENT_LINK_PTR_TERMINATE (1 << 0)
#define UHCI_QH_ELEMENT_LINK_PTR_TD (0 << 1)
#define UHCI_QH_ELEMENT_LINK_PTR_QH (1 << 1)
#define UHCI_QH_ELEMENT_LINK_POINTER_MASK 0xFFFFFFF0
typedef struct _UHCI_QH { // Queue Heads must be aligned on a 16-byte boundary
ULONG NextQH;
ULONG NextElement;
} UHCI_QH, *PUHCI_QH;
C_ASSERT(sizeof(UHCI_QH) == 8);

View file

@ -0,0 +1,473 @@
#include "usbuhci.h"
#define NDEBUG
#include <debug.h>
VOID
NTAPI
UhciRHGetRootHubData(IN PVOID uhciExtension,
IN PVOID rootHubData)
{
PUHCI_EXTENSION UhciExtension = uhciExtension;
PUSBPORT_ROOT_HUB_DATA RootHubData = rootHubData;
USBPORT_HUB_11_CHARACTERISTICS HubCharacteristics;
DPRINT("UhciRHGetRootHubData: ...\n");
HubCharacteristics.AsUSHORT = 0;
HubCharacteristics.PowerControlMode = 1;
HubCharacteristics.NoPowerSwitching = 1;
HubCharacteristics.OverCurrentProtectionMode = 1;
if (UhciExtension->HcFlavor != UHCI_Piix4)
HubCharacteristics.NoOverCurrentProtection = 1;
RootHubData->NumberOfPorts = UHCI_NUM_ROOT_HUB_PORTS;
RootHubData->HubCharacteristics.Usb11HubCharacteristics = HubCharacteristics;
RootHubData->PowerOnToPowerGood = 1;
RootHubData->HubControlCurrent = 0;
}
MPSTATUS
NTAPI
UhciRHGetStatus(IN PVOID uhciExtension,
IN PUSHORT Status)
{
DPRINT("UhciRHGetStatus: ...\n");
*Status = UHCI_RH_STATUS_SUCCESS;
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
UhciRHGetPortStatus(IN PVOID uhciExtension,
IN USHORT Port,
IN PUSB_PORT_STATUS_AND_CHANGE PortStatus)
{
PUHCI_EXTENSION UhciExtension = uhciExtension;
PUHCI_HW_REGISTERS BaseRegister;
PUSHORT PortControlRegister;
UHCI_PORT_STATUS_CONTROL PortControl;
ULONG PortBit;
USB_20_PORT_STATUS portStatus;
USB_20_PORT_CHANGE portChange;
//DPRINT("UhciRHGetPortStatus: ...\n");
ASSERT(Port);
BaseRegister = UhciExtension->BaseRegister;
PortControlRegister = &BaseRegister->PortControl[Port-1].AsUSHORT;
PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
portStatus.AsUshort16 = 0;
portChange.AsUshort16 = 0;
portStatus.CurrentConnectStatus = PortControl.CurrentConnectStatus;
portStatus.PortEnabledDisabled = PortControl.PortEnabledDisabled;
if (PortControl.Suspend == 1 &&
PortControl.PortEnabledDisabled == 1)
{
portStatus.Suspend = 1;
}
else
{
portStatus.Suspend = 0;
}
//if (UhciExtension->HcFlavor == UHCI_Piix4) // check will work after supporting HcFlavor in usbport.
if (TRUE)
{
portStatus.OverCurrent = PortControl.Reserved2 & 1;
portStatus.PortPower = (~PortControl.Reserved2 & 1);
portChange.OverCurrentIndicatorChange = (PortControl.Reserved2 & 2) != 0;
}
else
{
portStatus.OverCurrent = 0;
portStatus.PortPower = 1;
portChange.OverCurrentIndicatorChange = 0;
}
portStatus.HighSpeedDeviceAttached = 0;
portStatus.Reset = PortControl.PortReset;
portStatus.LowSpeedDeviceAttached = PortControl.LowSpeedDevice;
portChange.ConnectStatusChange = PortControl.ConnectStatusChange;
PortBit = 1 << (Port - 1);
if (UhciExtension->ResetPortMask & PortBit)
{
portChange.ConnectStatusChange = 0;
portChange.PortEnableDisableChange = 0;
}
else
{
portChange.PortEnableDisableChange = PortControl.PortEnableDisableChange;
}
if (UhciExtension->SuspendChangePortMask & PortBit)
portChange.SuspendChange = 1;
if (UhciExtension->ResetChangePortMask & PortBit)
portChange.ResetChange = 1;
PortStatus->PortStatus.Usb20PortStatus = portStatus;
PortStatus->PortChange.Usb20PortChange = portChange;
//DPRINT("UhciRHGetPortStatus: PortControl.AsUSHORT[%x] - %X, PortStatus - %X\n",
// Port,
// PortControl.AsUSHORT,
// PortStatus->AsUlong32);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
UhciRHGetHubStatus(IN PVOID uhciExtension,
IN PUSB_HUB_STATUS_AND_CHANGE HubStatus)
{
//DPRINT("UhciRHGetHubStatus: ...\n");
HubStatus->AsUlong32 = 0;
return MP_STATUS_SUCCESS;
}
VOID
NTAPI
UhciRHPortResetComplete(IN PVOID uhciExtension,
IN PVOID pPort)
{
PUHCI_EXTENSION UhciExtension = uhciExtension;
ULONG ix;
PUHCI_HW_REGISTERS BaseRegister;
PUSHORT PortControlRegister;
UHCI_PORT_STATUS_CONTROL PortControl;
USHORT Port;
DPRINT("UhciRHPortResetComplete: ...\n");
BaseRegister = UhciExtension->BaseRegister;
Port = *(PUSHORT)pPort;
ASSERT(Port);
PortControlRegister = &BaseRegister->PortControl[Port - 1].AsUSHORT;
PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
PortControl.ConnectStatusChange = 0;
PortControl.PortEnableDisableChange = 0;
PortControl.PortReset = 0;
WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
while (UhciHardwarePresent(UhciExtension))
{
PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
if (PortControl.PortReset == 0)
break;
}
for (ix = 0; ix < 10; ++ix)
{
KeStallExecutionProcessor(50);
PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
if (PortControl.PortEnabledDisabled == 1)
break;
PortControl.PortEnabledDisabled = 1;
WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
}
PortControl.ConnectStatusChange = 1;
PortControl.PortEnableDisableChange = 1;
WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
if (UhciExtension->HcFlavor == UHCI_VIA &&
UhciExtension->HcFlavor == UHCI_VIA_x01 &&
UhciExtension->HcFlavor == UHCI_VIA_x02 &&
UhciExtension->HcFlavor == UHCI_VIA_x03 &&
UhciExtension->HcFlavor == UHCI_VIA_x04)
{
DPRINT("UhciRHPortResetComplete: Via chip. FIXME\n");
DbgBreakPoint();
return;
}
UhciExtension->ResetChangePortMask |= (1 << (Port - 1));
UhciExtension->ResetPortMask &= ~(1 << (Port - 1));
RegPacket.UsbPortInvalidateRootHub(UhciExtension);
}
VOID
NTAPI
UhciRHSetFeaturePortResetWorker(IN PUHCI_EXTENSION UhciExtension,
IN PUSHORT pPort)
{
PUHCI_HW_REGISTERS BaseRegister;
PUSHORT PortControlRegister;
UHCI_PORT_STATUS_CONTROL PortControl;
USHORT Port;
DPRINT("UhciRHSetFeaturePortResetWorker: ...\n");
BaseRegister = UhciExtension->BaseRegister;
Port = *(PUSHORT)pPort;
ASSERT(Port);
PortControlRegister = &BaseRegister->PortControl[Port - 1].AsUSHORT;
PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
PortControl.ConnectStatusChange = 0;
PortControl.PortEnableDisableChange = 0;
PortControl.PortReset = 1;
WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
RegPacket.UsbPortRequestAsyncCallback(UhciExtension,
10, // TimerValue
pPort,
sizeof(pPort),
UhciRHPortResetComplete);
}
MPSTATUS
NTAPI
UhciRHSetFeaturePortReset(IN PVOID uhciExtension,
IN USHORT Port)
{
PUHCI_EXTENSION UhciExtension = uhciExtension;
ULONG ResetPortMask;
ULONG PortBit;
DPRINT("UhciRHSetFeaturePortReset: ...\n");
ASSERT(Port);
ResetPortMask = UhciExtension->ResetPortMask;
PortBit = 1 << (Port - 1);
if (ResetPortMask & PortBit)
return MP_STATUS_FAILURE;
UhciExtension->ResetPortMask = ResetPortMask | PortBit;
if (UhciExtension->HcFlavor == UHCI_VIA &&
UhciExtension->HcFlavor == UHCI_VIA_x01 &&
UhciExtension->HcFlavor == UHCI_VIA_x02 &&
UhciExtension->HcFlavor == UHCI_VIA_x03 &&
UhciExtension->HcFlavor == UHCI_VIA_x04)
{
DPRINT1("UhciRHSetFeaturePortReset: Via chip. FIXME\n");
return MP_STATUS_SUCCESS;
}
UhciRHSetFeaturePortResetWorker(UhciExtension, &Port);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
UhciRHSetFeaturePortPower(IN PVOID uhciExtension,
IN USHORT Port)
{
DPRINT("UhciRHSetFeaturePortPower: ...\n");
ASSERT(Port);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
UhciRHPortEnable(IN PVOID uhciExtension,
IN USHORT Port,
IN BOOLEAN IsSet)
{
PUHCI_EXTENSION UhciExtension = uhciExtension;
PUHCI_HW_REGISTERS BaseRegister;
PUSHORT PortControlRegister;
UHCI_PORT_STATUS_CONTROL PortControl;
DPRINT("UhciRHPortEnable: ...\n");
ASSERT(Port);
BaseRegister = UhciExtension->BaseRegister;
PortControlRegister = &BaseRegister->PortControl[Port-1].AsUSHORT;
PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
PortControl.ConnectStatusChange = 0;
PortControl.PortEnableDisableChange = 0;
if (IsSet)
PortControl.PortEnabledDisabled = 1;
else
PortControl.PortEnabledDisabled = 0;
WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
UhciRHSetFeaturePortEnable(IN PVOID uhciExtension,
IN USHORT Port)
{
PUHCI_EXTENSION UhciExtension = uhciExtension;
DPRINT("UhciRHSetFeaturePortEnable: ...\n");
ASSERT(Port);
return UhciRHPortEnable(UhciExtension, Port, TRUE);
}
MPSTATUS
NTAPI
UhciRHSetFeaturePortSuspend(IN PVOID uhciExtension,
IN USHORT Port)
{
DPRINT("UhciRHSetFeaturePortSuspend: UNIMPLEMENTED. FIXME\n");
ASSERT(Port);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
UhciRHClearFeaturePortEnable(IN PVOID uhciExtension,
IN USHORT Port)
{
PUHCI_EXTENSION UhciExtension = uhciExtension;
DPRINT("UhciRHClearFeaturePortEnable: ...\n");
ASSERT(Port);
return UhciRHPortEnable(UhciExtension, Port, FALSE);
}
MPSTATUS
NTAPI
UhciRHClearFeaturePortPower(IN PVOID uhciExtension,
IN USHORT Port)
{
DPRINT("UhciRHClearFeaturePortPower: UNIMPLEMENTED. FIXME\n");
ASSERT(Port);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
UhciRHClearFeaturePortSuspend(IN PVOID uhciExtension,
IN USHORT Port)
{
DPRINT("UhciRHClearFeaturePortSuspend: UNIMPLEMENTED. FIXME\n");
ASSERT(Port);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
UhciRHClearFeaturePortEnableChange(IN PVOID uhciExtension,
IN USHORT Port)
{
PUHCI_EXTENSION UhciExtension = uhciExtension;
PUHCI_HW_REGISTERS BaseRegister;
PUSHORT PortControlRegister;
UHCI_PORT_STATUS_CONTROL PortControl;
DPRINT("UhciRHClearFeaturePortEnableChange: ...\n");
ASSERT(Port);
BaseRegister = UhciExtension->BaseRegister;
PortControlRegister = (PUSHORT)&BaseRegister->PortControl[Port - 1];
PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
PortControl.ConnectStatusChange = 0;
PortControl.PortEnableDisableChange = 1;
WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
UhciRHClearFeaturePortConnectChange(IN PVOID uhciExtension,
IN USHORT Port)
{
PUHCI_EXTENSION UhciExtension = uhciExtension;
PUHCI_HW_REGISTERS BaseRegister;
PUSHORT PortControlRegister;
UHCI_PORT_STATUS_CONTROL PortControl;
DPRINT("UhciRHClearFeaturePortConnectChange: Port - %04X\n", Port);
ASSERT(Port);
BaseRegister = UhciExtension->BaseRegister;
PortControlRegister = (PUSHORT)&BaseRegister->PortControl[Port - 1];
PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
if (PortControl.ConnectStatusChange == 1)
{
/* WC (Write Clear) bits */
PortControl.PortEnableDisableChange = 0;
PortControl.ConnectStatusChange = 1;
WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
}
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
UhciRHClearFeaturePortResetChange(IN PVOID uhciExtension,
IN USHORT Port)
{
PUHCI_EXTENSION UhciExtension = uhciExtension;
DPRINT("UhciRHClearFeaturePortResetChange: ...\n");
ASSERT(Port);
UhciExtension->ResetChangePortMask &= ~(1 << (Port - 1));
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
UhciRHClearFeaturePortSuspendChange(IN PVOID uhciExtension,
IN USHORT Port)
{
DPRINT("UhciRHClearFeaturePortSuspendChange: UNIMPLEMENTED. FIXME\n");
ASSERT(Port);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
UhciRHClearFeaturePortOvercurrentChange(IN PVOID uhciExtension,
IN USHORT Port)
{
DPRINT("UhciRHClearFeaturePortOvercurrentChange: UNIMPLEMENTED. FIXME\n");
ASSERT(Port);
return MP_STATUS_SUCCESS;
}
VOID
NTAPI
UhciRHDisableIrq(IN PVOID uhciExtension)
{
/* Do nothing */
return;
}
VOID
NTAPI
UhciRHEnableIrq(IN PVOID uhciExtension)
{
/* Do nothing */
return;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,297 @@
#ifndef USBUHCI_H__
#define USBUHCI_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 UHCI_MAX_HC_SCHEDULE_ERRORS 16
#define UHCI_RH_STATUS_SUCCESS 1
#define UHCI_MAX_ISO_TRANSFER_SIZE 0x10000
#define UHCI_MAX_BULK_TRANSFER_SIZE 0x1000
//#define UHCI_MAX_BULK_TRANSFER_SIZE 0x10000 // Hack for testing w/o Split Transfers
#define UHCI_MAX_ISO_TD_COUNT 256
#define UHCI_MAX_INTERRUPT_TD_COUNT 8
/* Host Controller Driver Transfer Descriptor (HCD TD) */
#define UHCI_HCD_TD_FLAG_ALLOCATED 0x00000001
#define UHCI_HCD_TD_FLAG_PROCESSED 0x00000002
#define UHCI_HCD_TD_FLAG_DONE 0x00000008
#define UHCI_HCD_TD_FLAG_NOT_ACCESSED 0x00000010
#define UHCI_HCD_TD_FLAG_DATA_BUFFER 0x00000020
#define UHCI_HCD_TD_FLAG_GOOD_FRAME 0x00000040
#define UHCI_HCD_TD_FLAG_CONTROLL 0x00000400
#define UHCI_HCD_TD_FLAG_STALLED_SETUP 0x00000800
typedef struct _UHCI_ENDPOINT *PUHCI_ENDPOINT;
typedef struct _UHCI_TRANSFER *PUHCI_TRANSFER;
typedef struct _UHCI_HCD_TD {
/* Hardware */
UHCI_TD HwTD;
/* Software */
USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
ULONG PhysicalAddress;
ULONG Flags;
struct _UHCI_HCD_TD * NextHcdTD;
_ANONYMOUS_UNION union {
PUHCI_TRANSFER UhciTransfer;
#if !defined(_M_X64)
ULONG Frame; // for SOF_HcdTDs only
#else
struct {
ULONG Frame;
ULONG Pad2;
};
#endif
} DUMMYUNIONNAME;
LIST_ENTRY TdLink;
#if !defined(_M_X64)
ULONG Padded[4];
#else
ULONG Padded[15];
#endif
} UHCI_HCD_TD, *PUHCI_HCD_TD;
#if !defined(_M_X64)
C_ASSERT(sizeof(UHCI_HCD_TD) == 0x40);
#else
C_ASSERT(sizeof(UHCI_HCD_TD) == 0x80);
#endif
/* Host Controller Driver Queue Header (HCD QH) */
#define UHCI_HCD_QH_FLAG_ACTIVE 0x00000001
#define UHCI_HCD_QH_FLAG_REMOVE 0x00000002
typedef struct _UHCI_HCD_QH {
/* Hardware */
UHCI_QH HwQH;
/* Software */
ULONG PhysicalAddress;
ULONG QhFlags;
struct _UHCI_HCD_QH * NextHcdQH;
#if !defined(_M_X64)
ULONG Pad1;
#endif
struct _UHCI_HCD_QH * PrevHcdQH;
#if !defined(_M_X64)
ULONG Pad2;
#endif
PUHCI_ENDPOINT UhciEndpoint;
#if !defined(_M_X64)
ULONG Pad3;
#endif
ULONG Padded[6];
} UHCI_HCD_QH, *PUHCI_HCD_QH;
C_ASSERT(sizeof(UHCI_HCD_QH) == 0x40);
#define UHCI_ENDPOINT_FLAG_HALTED 1
#define UHCI_ENDPOINT_FLAG_RESERVED 2
#define UHCI_ENDPOINT_FLAG_CONTROL_OR_ISO 4
/* UHCI Endpoint follows USBPORT Endpoint */
typedef struct _UHCI_ENDPOINT {
ULONG Flags;
LONG EndpointLock;
USBPORT_ENDPOINT_PROPERTIES EndpointProperties;
PUHCI_HCD_QH QH;
PUHCI_HCD_TD TailTD;
PUHCI_HCD_TD HeadTD;
PUHCI_HCD_TD FirstTD;
ULONG MaxTDs;
ULONG AllocatedTDs;
ULONG AllocTdCounter;
LIST_ENTRY ListTDs;
BOOL DataToggle;
} UHCI_ENDPOINT, *PUHCI_ENDPOINT;
/* UHCI Transfer follows USBPORT Transfer */
typedef struct _UHCI_TRANSFER {
PUSBPORT_TRANSFER_PARAMETERS TransferParameters;
PUHCI_ENDPOINT UhciEndpoint;
USBD_STATUS USBDStatus;
ULONG PendingTds;
SIZE_T TransferLen;
} UHCI_TRANSFER, *PUHCI_TRANSFER;
#define UHCI_FRAME_LIST_POINTER_VALID (0 << 0)
#define UHCI_FRAME_LIST_POINTER_TERMINATE (1 << 0)
#define UHCI_FRAME_LIST_POINTER_TD (0 << 1)
#define UHCI_FRAME_LIST_POINTER_QH (1 << 1)
#define UHCI_FRAME_LIST_INDEX_MASK 0x3FF
#define UHCI_MAX_STATIC_SOF_TDS 8
typedef struct _UHCI_HC_RESOURCES {
ULONG FrameList[UHCI_FRAME_LIST_MAX_ENTRIES]; // The 4-Kbyte Frame List Table is aligned on a 4-Kbyte boundary
UHCI_HCD_QH StaticIntHead[INTERRUPT_ENDPOINTs];
UHCI_HCD_QH StaticControlHead;
UHCI_HCD_QH StaticBulkHead;
UHCI_HCD_TD StaticBulkTD;
UHCI_HCD_TD StaticTD;
UHCI_HCD_TD StaticSofTD[UHCI_MAX_STATIC_SOF_TDS];
} UHCI_HC_RESOURCES, *PUHCI_HC_RESOURCES;
#define UHCI_EXTENSION_FLAG_SUSPENDED 0x00000002
/* UHCI Extension follows USBPORT Extension */
typedef struct _UHCI_EXTENSION {
PUHCI_HW_REGISTERS BaseRegister;
USB_CONTROLLER_FLAVOR HcFlavor;
PUHCI_HC_RESOURCES HcResourcesVA;
ULONG HcResourcesPA;
PUHCI_HCD_QH IntQH[INTERRUPT_ENDPOINTs];
PUHCI_HCD_QH ControlQH;
PUHCI_HCD_QH BulkQH;
PUHCI_HCD_QH BulkTailQH;
PUHCI_HCD_TD StaticTD;
PUHCI_HCD_TD SOF_HcdTDs; // pointer to array StaticSofTD[UHCI_MAX_STATIC_SOF_TDS]
ULONG FrameNumber;
ULONG FrameHighPart;
ULONG Flags;
LONG LockFrameList;
ULONG ResetPortMask;
ULONG ResetChangePortMask;
ULONG SuspendChangePortMask;
ULONG HcScheduleError;
LONG ExtensionLock;
UHCI_USB_STATUS StatusMask;
UHCI_USB_STATUS HcStatus;
UCHAR SOF_Modify;
UCHAR Padded2[3];
} UHCI_EXTENSION, *PUHCI_EXTENSION;
/* roothub.c */
VOID
NTAPI
UhciRHGetRootHubData(
IN PVOID uhciExtension,
IN PVOID rootHubData);
MPSTATUS
NTAPI
UhciRHGetStatus(
IN PVOID uhciExtension,
IN PUSHORT Status);
MPSTATUS
NTAPI
UhciRHGetPortStatus(
IN PVOID uhciExtension,
IN USHORT Port,
IN PUSB_PORT_STATUS_AND_CHANGE PortStatus);
MPSTATUS
NTAPI
UhciRHGetHubStatus(
IN PVOID uhciExtension,
IN PUSB_HUB_STATUS_AND_CHANGE HubStatus);
MPSTATUS
NTAPI
UhciRHSetFeaturePortReset(
IN PVOID uhciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
UhciRHSetFeaturePortPower(
IN PVOID uhciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
UhciRHSetFeaturePortEnable(
IN PVOID uhciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
UhciRHSetFeaturePortSuspend(
IN PVOID uhciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
UhciRHClearFeaturePortEnable(
IN PVOID uhciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
UhciRHClearFeaturePortPower(
IN PVOID uhciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
UhciRHClearFeaturePortSuspend(
IN PVOID uhciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
UhciRHClearFeaturePortEnableChange(
IN PVOID uhciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
UhciRHClearFeaturePortConnectChange(
IN PVOID uhciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
UhciRHClearFeaturePortResetChange(
IN PVOID uhciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
UhciRHClearFeaturePortSuspendChange(
IN PVOID uhciExtension,
IN USHORT Port);
MPSTATUS
NTAPI
UhciRHClearFeaturePortOvercurrentChange(
IN PVOID uhciExtension,
IN USHORT Port);
VOID
NTAPI
UhciRHDisableIrq(
IN PVOID uhciExtension);
VOID
NTAPI
UhciRHEnableIrq(
IN PVOID uhciExtension);
/* usbuhci.c */
VOID
NTAPI
UhciDisableInterrupts(
IN PVOID uhciExtension);
ULONG
NTAPI
UhciGet32BitFrameNumber(
IN PVOID uhciExtension);
BOOLEAN
NTAPI
UhciHardwarePresent(
IN PUHCI_EXTENSION UhciExtension);
#endif /* USBUHCI_H__ */

View file

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