mirror of
https://github.com/reactos/reactos.git
synced 2024-07-11 07:05:12 +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
|
@ -22,7 +22,7 @@ InterruptServiceRoutine(
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
EhciDefferedRoutine(
|
OhciDefferedRoutine(
|
||||||
IN PKDPC Dpc,
|
IN PKDPC Dpc,
|
||||||
IN PVOID DeferredContext,
|
IN PVOID DeferredContext,
|
||||||
IN PVOID SystemArgument1,
|
IN PVOID SystemArgument1,
|
||||||
|
@ -82,7 +82,7 @@ public:
|
||||||
|
|
||||||
// friend function
|
// friend function
|
||||||
friend BOOLEAN NTAPI InterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext);
|
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);
|
friend VOID NTAPI StatusChangeWorkItemRoutine(PVOID Context);
|
||||||
// constructor / destructor
|
// constructor / destructor
|
||||||
CUSBHardwareDevice(IUnknown *OuterUnknown){}
|
CUSBHardwareDevice(IUnknown *OuterUnknown){}
|
||||||
|
@ -249,7 +249,7 @@ CUSBHardwareDevice::PnpStart(
|
||||||
case CmResourceTypeInterrupt:
|
case CmResourceTypeInterrupt:
|
||||||
{
|
{
|
||||||
KeInitializeDpc(&m_IntDpcObject,
|
KeInitializeDpc(&m_IntDpcObject,
|
||||||
EhciDefferedRoutine,
|
OhciDefferedRoutine,
|
||||||
this);
|
this);
|
||||||
|
|
||||||
Status = IoConnectInterrupt(&m_Interrupt,
|
Status = IoConnectInterrupt(&m_Interrupt,
|
||||||
|
@ -521,6 +521,21 @@ CUSBHardwareDevice::StartController(void)
|
||||||
//
|
//
|
||||||
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_CONTROL_OFFSET), Control);
|
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
|
// retrieve number of ports
|
||||||
//
|
//
|
||||||
|
@ -563,6 +578,12 @@ CUSBHardwareDevice::StartController(void)
|
||||||
//
|
//
|
||||||
DPRINT1("NumberOfPorts %lu\n", m_NumberOfPorts);
|
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
|
// done
|
||||||
//
|
//
|
||||||
|
@ -938,19 +959,150 @@ InterruptServiceRoutine(
|
||||||
IN PKINTERRUPT Interrupt,
|
IN PKINTERRUPT Interrupt,
|
||||||
IN PVOID ServiceContext)
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID NTAPI
|
VOID
|
||||||
EhciDefferedRoutine(
|
NTAPI
|
||||||
|
OhciDefferedRoutine(
|
||||||
IN PKDPC Dpc,
|
IN PKDPC Dpc,
|
||||||
IN PVOID DeferredContext,
|
IN PVOID DeferredContext,
|
||||||
IN PVOID SystemArgument1,
|
IN PVOID SystemArgument1,
|
||||||
IN PVOID SystemArgument2)
|
IN PVOID SystemArgument2)
|
||||||
{
|
{
|
||||||
ASSERT(FALSE);
|
CUSBHardwareDevice *This;
|
||||||
return;
|
ULONG CStatus;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get parameters
|
||||||
|
//
|
||||||
|
This = (CUSBHardwareDevice*) SystemArgument1;
|
||||||
|
CStatus = (ULONG) SystemArgument2;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -49,7 +49,7 @@ typedef struct
|
||||||
//
|
//
|
||||||
// tag for allocations
|
// tag for allocations
|
||||||
//
|
//
|
||||||
#define TAG_USBOHCI 'ICHE'
|
#define TAG_USBOHCI 'ICHO'
|
||||||
|
|
||||||
//
|
//
|
||||||
// assert for c++ - taken from portcls
|
// assert for c++ - taken from portcls
|
||||||
|
|
Loading…
Reference in a new issue