mirror of
https://github.com/reactos/reactos.git
synced 2025-01-06 06:20:13 +00:00
[OHCI]
- Add check that controller is functional state - enable interrupts after the controller has been started - partly implement isr routine svn path=/branches/usb-bringup/; revision=51852
This commit is contained in:
parent
d4c4a2e080
commit
89d52d98bb
2 changed files with 161 additions and 9 deletions
|
@ -22,7 +22,7 @@ InterruptServiceRoutine(
|
|||
|
||||
VOID
|
||||
NTAPI
|
||||
EhciDefferedRoutine(
|
||||
OhciDefferedRoutine(
|
||||
IN PKDPC Dpc,
|
||||
IN PVOID DeferredContext,
|
||||
IN PVOID SystemArgument1,
|
||||
|
@ -82,7 +82,7 @@ public:
|
|||
|
||||
// friend function
|
||||
friend BOOLEAN NTAPI InterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext);
|
||||
friend VOID NTAPI EhciDefferedRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);
|
||||
friend VOID NTAPI OhciDefferedRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);
|
||||
friend VOID NTAPI StatusChangeWorkItemRoutine(PVOID Context);
|
||||
// constructor / destructor
|
||||
CUSBHardwareDevice(IUnknown *OuterUnknown){}
|
||||
|
@ -249,7 +249,7 @@ CUSBHardwareDevice::PnpStart(
|
|||
case CmResourceTypeInterrupt:
|
||||
{
|
||||
KeInitializeDpc(&m_IntDpcObject,
|
||||
EhciDefferedRoutine,
|
||||
OhciDefferedRoutine,
|
||||
this);
|
||||
|
||||
Status = IoConnectInterrupt(&m_Interrupt,
|
||||
|
@ -521,6 +521,21 @@ CUSBHardwareDevice::StartController(void)
|
|||
//
|
||||
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_CONTROL_OFFSET), Control);
|
||||
|
||||
//
|
||||
// wait a bit
|
||||
//
|
||||
KeStallExecutionProcessor(100);
|
||||
|
||||
//
|
||||
// is the controller started
|
||||
//
|
||||
Control = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_CONTROL_OFFSET));
|
||||
|
||||
//
|
||||
// assert that the controller has been started
|
||||
//
|
||||
ASSERT((Control & OHCI_HC_FUNCTIONAL_STATE_MASK) == OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL);
|
||||
|
||||
//
|
||||
// retrieve number of ports
|
||||
//
|
||||
|
@ -563,6 +578,12 @@ CUSBHardwareDevice::StartController(void)
|
|||
//
|
||||
DPRINT1("NumberOfPorts %lu\n", m_NumberOfPorts);
|
||||
|
||||
|
||||
//
|
||||
// now enable the interrupts
|
||||
//
|
||||
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_INTERRUPT_ENABLE_OFFSET), OHCI_NORMAL_INTERRUPTS | OHCI_MASTER_INTERRUPT_ENABLE);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
|
@ -938,19 +959,150 @@ InterruptServiceRoutine(
|
|||
IN PKINTERRUPT Interrupt,
|
||||
IN PVOID ServiceContext)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
CUSBHardwareDevice *This;
|
||||
ULONG DoneHead, Status, Acknowledge = 0;
|
||||
|
||||
//
|
||||
// get context
|
||||
//
|
||||
This = (CUSBHardwareDevice*) ServiceContext;
|
||||
|
||||
DPRINT1("InterruptServiceRoutine\n");
|
||||
|
||||
//
|
||||
// get done head
|
||||
//
|
||||
DoneHead = This->m_HCCA->DoneHead;
|
||||
|
||||
//
|
||||
// check if zero
|
||||
//
|
||||
if (DoneHead == 0)
|
||||
{
|
||||
//
|
||||
// the interrupt was not caused by DoneHead update
|
||||
// check if something important happened
|
||||
//
|
||||
Status = READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + OHCI_INTERRUPT_STATUS_OFFSET)) & READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + OHCI_INTERRUPT_ENABLE_OFFSET)) & (~OHCI_WRITEBACK_DONE_HEAD);
|
||||
if (Status == 0)
|
||||
{
|
||||
//
|
||||
// nothing happened, appears to be shared interrupt
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// DoneHead update happened, check if there are other events too
|
||||
//
|
||||
Status = OHCI_WRITEBACK_DONE_HEAD;
|
||||
|
||||
//
|
||||
// since ed descriptors are 16 byte aligned, the controller sets the lower bits if there were other interrupt requests
|
||||
//
|
||||
if (DoneHead & OHCI_DONE_INTERRUPTS)
|
||||
{
|
||||
//
|
||||
// get other events
|
||||
//
|
||||
Status |= READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + OHCI_INTERRUPT_STATUS_OFFSET)) & READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + OHCI_INTERRUPT_ENABLE_OFFSET));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
ASSERT(Status != 0);
|
||||
|
||||
if (Status & OHCI_WRITEBACK_DONE_HEAD)
|
||||
{
|
||||
//
|
||||
// head completed
|
||||
//
|
||||
DPRINT1("InterruptServiceRoutine> Done Head completion\n");
|
||||
|
||||
//
|
||||
// FIXME: handle event
|
||||
//
|
||||
Acknowledge |= OHCI_WRITEBACK_DONE_HEAD;
|
||||
}
|
||||
|
||||
if (Status & OHCI_RESUME_DETECTED)
|
||||
{
|
||||
//
|
||||
// resume
|
||||
//
|
||||
DPRINT1("InterruptServiceRoutine> Resume\n");
|
||||
Acknowledge |= OHCI_RESUME_DETECTED;
|
||||
}
|
||||
|
||||
|
||||
if (Status & OHCI_UNRECOVERABLE_ERROR)
|
||||
{
|
||||
DPRINT1("InterruptServiceRoutine> Controller error\n");
|
||||
//
|
||||
// halt controller
|
||||
//
|
||||
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)(This->m_Base + OHCI_CONTROL_OFFSET)), OHCI_HC_FUNCTIONAL_STATE_RESET);
|
||||
}
|
||||
|
||||
if (Status & OHCI_ROOT_HUB_STATUS_CHANGE)
|
||||
{
|
||||
//
|
||||
// new device has arrived
|
||||
//
|
||||
DPRINT1("InterruptServiceRoutine> New Device arrival\n");
|
||||
|
||||
//
|
||||
// disable interrupt as it will fire untill the port has been reset
|
||||
//
|
||||
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)(This->m_Base + OHCI_INTERRUPT_DISABLE_OFFSET)), OHCI_ROOT_HUB_STATUS_CHANGE);
|
||||
Acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE;
|
||||
}
|
||||
|
||||
//
|
||||
// is there something to acknowledge
|
||||
//
|
||||
if (Acknowledge)
|
||||
{
|
||||
//
|
||||
// ack change
|
||||
//
|
||||
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)(This->m_Base + OHCI_INTERRUPT_STATUS_OFFSET)), Acknowledge);
|
||||
}
|
||||
|
||||
//
|
||||
// defer processing
|
||||
//
|
||||
DPRINT1("Status %x\n", Status);
|
||||
KeInsertQueueDpc(&This->m_IntDpcObject, This, (PVOID)Status);
|
||||
|
||||
//
|
||||
// interrupt handled
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID NTAPI
|
||||
EhciDefferedRoutine(
|
||||
VOID
|
||||
NTAPI
|
||||
OhciDefferedRoutine(
|
||||
IN PKDPC Dpc,
|
||||
IN PVOID DeferredContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return;
|
||||
CUSBHardwareDevice *This;
|
||||
ULONG CStatus;
|
||||
|
||||
//
|
||||
// get parameters
|
||||
//
|
||||
This = (CUSBHardwareDevice*) SystemArgument1;
|
||||
CStatus = (ULONG) SystemArgument2;
|
||||
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
|
|
|
@ -49,7 +49,7 @@ typedef struct
|
|||
//
|
||||
// tag for allocations
|
||||
//
|
||||
#define TAG_USBOHCI 'ICHE'
|
||||
#define TAG_USBOHCI 'ICHO'
|
||||
|
||||
//
|
||||
// assert for c++ - taken from portcls
|
||||
|
|
Loading…
Reference in a new issue