* Placed underscore to private methods like ReadReg and WriteReg
* Rewrote _AllocateEndpoint * More work in the constructor git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22873 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
db81403db4
commit
a097d8c8ee
@ -67,9 +67,9 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
|||||||
fStack(stack),
|
fStack(stack),
|
||||||
fRegisterArea(-1),
|
fRegisterArea(-1),
|
||||||
fHccaArea(-1),
|
fHccaArea(-1),
|
||||||
fDummyControl(0),
|
fDummyControl(NULL),
|
||||||
fDummyBulk(0),
|
fDummyBulk(NULL),
|
||||||
fDummyIsochronous(0),
|
fDummyIsochronous(NULL),
|
||||||
fRootHub(NULL),
|
fRootHub(NULL),
|
||||||
fRootHubAddress(0),
|
fRootHubAddress(0),
|
||||||
fNumPorts(0)
|
fNumPorts(0)
|
||||||
@ -109,7 +109,7 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
|||||||
*fOperationalRegisters));
|
*fOperationalRegisters));
|
||||||
|
|
||||||
// Check the revision of the controller, which should be 10h
|
// Check the revision of the controller, which should be 10h
|
||||||
uint32 revision = ReadReg(OHCI_REVISION) & 0xff;
|
uint32 revision = _ReadReg(OHCI_REVISION) & 0xff;
|
||||||
TRACE(("usb_ohci: version %ld.%ld%s\n", OHCI_REVISION_HIGH(revision),
|
TRACE(("usb_ohci: version %ld.%ld%s\n", OHCI_REVISION_HIGH(revision),
|
||||||
OHCI_REVISION_LOW(revision), OHCI_REVISION_LEGACY(revision)
|
OHCI_REVISION_LOW(revision), OHCI_REVISION_LEGACY(revision)
|
||||||
? ", legacy support" : ""));
|
? ", legacy support" : ""));
|
||||||
@ -135,42 +135,67 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
|||||||
fDummyControl = _AllocateEndpoint();
|
fDummyControl = _AllocateEndpoint();
|
||||||
if (!fDummyControl)
|
if (!fDummyControl)
|
||||||
return;
|
return;
|
||||||
|
fDummyControl->flags |= OHCI_ENDPOINT_SKIP;
|
||||||
|
|
||||||
fDummyBulk = _AllocateEndpoint();
|
fDummyBulk = _AllocateEndpoint();
|
||||||
if (!fDummyBulk)
|
if (!fDummyBulk) {
|
||||||
|
_FreeEndpoint(fDummyControl);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
fDummyBulk->flags |= OHCI_ENDPOINT_SKIP;
|
||||||
|
|
||||||
fDummyIsochronous = _AllocateEndpoint();
|
fDummyIsochronous = _AllocateEndpoint();
|
||||||
if (!fDummyIsochronous)
|
if (!fDummyIsochronous) {
|
||||||
|
_FreeEndpoint(fDummyControl);
|
||||||
|
_FreeEndpoint(fDummyBulk);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
fDummyIsochronous->flags |= OHCI_ENDPOINT_SKIP;
|
||||||
|
|
||||||
// Create the interrupt tree
|
// Create the interrupt tree
|
||||||
// Algorithm kindly borrowed from NetBSD code
|
// Algorithm kindly borrowed from NetBSD code
|
||||||
for( uint32 i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++) {
|
// TODO: Check it once again
|
||||||
fInterruptEndpoints[i] = _AllocateEndpoint();
|
ohci_endpoint_descriptor *current, *previous;
|
||||||
if (!fInterruptEndpoints[i])
|
for( uint32 i = 0; i < OHCI_NUMBER_OF_ENDPOINTS; i++) {
|
||||||
|
current = _AllocateEndpoint();
|
||||||
|
if (!current) {
|
||||||
|
TRACE_ERROR(("usb_ohci: failed to create interrupts tree\n"));
|
||||||
|
while (--i >= 0)
|
||||||
|
_FreeEndpoint(fInterruptEndpoints[i]);
|
||||||
|
_FreeEndpoint(fDummyBulk);
|
||||||
|
_FreeEndpoint(fDummyControl);
|
||||||
|
_FreeEndpoint(fDummyIsochronous);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
fInterruptEndpoints[i] = current;
|
||||||
|
current->flags |= OHCI_ENDPOINT_SKIP;
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
fInterruptEndpoints[i]->SetNext(fInterruptEndpoints[(i-1) / 2]);
|
previous = fInterruptEndpoints[(i - 1) / 2];
|
||||||
else
|
else
|
||||||
fInterruptEndpoints[i]->SetNext(fDummyIsochronous);
|
previous = fDummyIsochronous;
|
||||||
|
current->next_logical_endpoint = previous;
|
||||||
|
current->next_physical_endpoint = previous->this_physical;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fill HCCA interrupt table. The bit reversal is to get
|
||||||
|
// the tree set up properly to spread the interrupts.
|
||||||
for (uint32 i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++)
|
for (uint32 i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++)
|
||||||
fHcca->hcca_interrupt_table[revbits[i]] =
|
fHcca->hcca_interrupt_table[revbits[i]] =
|
||||||
fInterruptEndpoints[OHCI_NO_EDS-OHCI_NUMBER_OF_INTERRUPTS+i]->physical_address;
|
fInterruptEndpoints[OHCI_NUMBER_OF_ENDPOINTS - OHCI_NUMBER_OF_INTERRUPTS + i]->physical_address;
|
||||||
|
|
||||||
|
|
||||||
// Determine in what context we are running (Kindly copied from FreeBSD)
|
// Determine in what context we are running (Kindly copied from FreeBSD)
|
||||||
uint32 control = ReadReg(OHCI_CONTROL);
|
uint32 control = _ReadReg(OHCI_CONTROL);
|
||||||
if (control & OHCI_INTERRUPT_ROUTING) {
|
if (control & OHCI_INTERRUPT_ROUTING) {
|
||||||
TRACE(("usb_ohci: SMM is in control of the host controller\n"));
|
TRACE(("usb_ohci: SMM is in control of the host controller\n"));
|
||||||
WriteReg(OHCI_COMMAND_STATUS, OHCI_OWNERSHIP_CHANGE_REQUEST);
|
_WriteReg(OHCI_COMMAND_STATUS, OHCI_OWNERSHIP_CHANGE_REQUEST);
|
||||||
for (uint32 i = 0; i < 100 && (control & OHCI_INTERRUPT_ROUTING); i++) {
|
for (uint32 i = 0; i < 100 && (control & OHCI_INTERRUPT_ROUTING); i++) {
|
||||||
snooze(1000);
|
snooze(1000);
|
||||||
control = ReadReg(OHCI_CONTROL);
|
control = _ReadReg(OHCI_CONTROL);
|
||||||
}
|
}
|
||||||
if (!(control & OHCI_INTERRUPT_ROUTING)) {
|
if (!(control & OHCI_INTERRUPT_ROUTING)) {
|
||||||
TRACE(("usb_ohci: SMM does not respond. Resetting...\n"));
|
TRACE(("usb_ohci: SMM does not respond. Resetting...\n"));
|
||||||
WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
|
_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
|
||||||
snooze(USB_DELAY_BUS_RESET);
|
snooze(USB_DELAY_BUS_RESET);
|
||||||
}
|
}
|
||||||
} else if ((control & OHCI_HC_FUNCTIONAL_STATE_MASK)
|
} else if ((control & OHCI_HC_FUNCTIONAL_STATE_MASK)
|
||||||
@ -178,7 +203,7 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
|||||||
TRACE(("usb_ohci: BIOS is in control of the host controller\n"));
|
TRACE(("usb_ohci: BIOS is in control of the host controller\n"));
|
||||||
if ((control & OHCI_HC_FUNCTIONAL_STATE_MASK)
|
if ((control & OHCI_HC_FUNCTIONAL_STATE_MASK)
|
||||||
!= OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) {
|
!= OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) {
|
||||||
WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL);
|
_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL);
|
||||||
// TOFIX: shorter delay
|
// TOFIX: shorter delay
|
||||||
snooze(USB_DELAY_BUS_RESET);
|
snooze(USB_DELAY_BUS_RESET);
|
||||||
}
|
}
|
||||||
@ -186,21 +211,21 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
|||||||
|
|
||||||
// This reset should not be necessary according to the OHCI spec, but
|
// This reset should not be necessary according to the OHCI spec, but
|
||||||
// without it some controllers do not start.
|
// without it some controllers do not start.
|
||||||
WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
|
_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
|
||||||
snooze(USB_DELAY_BUS_RESET);
|
snooze(USB_DELAY_BUS_RESET);
|
||||||
|
|
||||||
// We now own the host controller and the bus has been reset
|
// We now own the host controller and the bus has been reset
|
||||||
uint32 frameInterval = ReadReg(OHCI_FRAME_INTERVAL);
|
uint32 frameInterval = _ReadReg(OHCI_FRAME_INTERVAL);
|
||||||
uint32 intervalValue = OHCI_GET_INTERVAL_VALUE(frameInterval);
|
uint32 intervalValue = OHCI_GET_INTERVAL_VALUE(frameInterval);
|
||||||
WriteReg(OHCI_COMMAND_STATUS, OHCI_HOST_CONTROLLER_RESET);
|
_WriteReg(OHCI_COMMAND_STATUS, OHCI_HOST_CONTROLLER_RESET);
|
||||||
|
|
||||||
for (uint32 i = 0; i < 10; i++) {
|
for (uint32 i = 0; i < 10; i++) {
|
||||||
snooze(10);
|
snooze(10);
|
||||||
if (!(ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET))
|
if (!(_ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET) {
|
if (_ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET) {
|
||||||
TRACE_ERROR(("usb_ohci: Error resetting the host controller (timeout)\n"));
|
TRACE_ERROR(("usb_ohci: Error resetting the host controller (timeout)\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -208,47 +233,51 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
|||||||
// The controller is now in SUSPEND state, we have 2ms to finish
|
// The controller is now in SUSPEND state, we have 2ms to finish
|
||||||
// TODO: maybe add spinlock protection???
|
// TODO: maybe add spinlock protection???
|
||||||
// Set up host controller register
|
// Set up host controller register
|
||||||
WriteReg(OHCI_HCCA, (uint32)hccaPhysicalAddress);
|
_WriteReg(OHCI_HCCA, (uint32)hccaPhysicalAddress);
|
||||||
WriteReg(OHCI_CONTROL_HEAD_ED, (uint32)fDummyControl->physical_address);
|
_WriteReg(OHCI_CONTROL_HEAD_ED, (uint32)fDummyControl->physical_address);
|
||||||
WriteReg(OHCI_BULK_HEAD_ED, (uint32)fDummyBulk->physical_address);
|
_WriteReg(OHCI_BULK_HEAD_ED, (uint32)fDummyBulk->physical_address);
|
||||||
// Disable all interrupts and then switch on all desired interrupts
|
// Disable all interrupts and then switch on all desired interrupts
|
||||||
WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS);
|
_WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS);
|
||||||
WriteReg(OHCI_INTERRUPT_ENABLE, OHCI_NORMAL_INTERRUPTS
|
_WriteReg(OHCI_INTERRUPT_ENABLE, OHCI_NORMAL_INTERRUPTS
|
||||||
| OHCI_MASTER_INTERRUPT_ENABLE);
|
| OHCI_MASTER_INTERRUPT_ENABLE);
|
||||||
// Switch on desired functional features
|
// Switch on desired functional features
|
||||||
control = ReadReg(OHCI_CONTROL);
|
control = _ReadReg(OHCI_CONTROL);
|
||||||
control &= ~(OHCI_CONTROL_BULK_SERVICE_RATIO_MASK | OHCI_ENABLE_LIST
|
control &= ~(OHCI_CONTROL_BULK_SERVICE_RATIO_MASK | OHCI_ENABLE_LIST
|
||||||
| OHCI_HC_FUNCTIONAL_STATE_MASK | OHCI_INTERRUPT_ROUTING);
|
| OHCI_HC_FUNCTIONAL_STATE_MASK | OHCI_INTERRUPT_ROUTING);
|
||||||
control |= OHCI_ENABLE_LIST | OHCI_CONTROL_BULK_RATIO_1_4
|
control |= OHCI_ENABLE_LIST | OHCI_CONTROL_BULK_RATIO_1_4
|
||||||
| OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL;
|
| OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL;
|
||||||
// And finally start the controller
|
// And finally start the controller
|
||||||
WriteReg(OHCI_CONTROL, control);
|
_WriteReg(OHCI_CONTROL, control);
|
||||||
|
|
||||||
// The controller is now OPERATIONAL.
|
// The controller is now OPERATIONAL.
|
||||||
frameInterval = (ReadReg(OHCI_FRAME_INTERVAL) & OHCI_FRAME_INTERVAL_TOGGLE)
|
frameInterval = (_ReadReg(OHCI_FRAME_INTERVAL) & OHCI_FRAME_INTERVAL_TOGGLE)
|
||||||
^ OHCI_FRAME_INTERVAL_TOGGLE;
|
^ OHCI_FRAME_INTERVAL_TOGGLE;
|
||||||
frameInterval |= OHCI_FSMPS(intervalValue) | intervalValue;
|
frameInterval |= OHCI_FSMPS(intervalValue) | intervalValue;
|
||||||
WriteReg(OHCI_FRAME_INTERVAL, frameInterval);
|
_WriteReg(OHCI_FRAME_INTERVAL, frameInterval);
|
||||||
// 90% periodic
|
// 90% periodic
|
||||||
uint32 periodic = OHCI_PERIODIC(intervalValue);
|
uint32 periodic = OHCI_PERIODIC(intervalValue);
|
||||||
WriteReg(OHCI_PERIODIC_START, periodic);
|
_WriteReg(OHCI_PERIODIC_START, periodic);
|
||||||
|
|
||||||
// Fiddle the No Over Current Protection bit to avoid chip bug
|
// Fiddle the No Over Current Protection bit to avoid chip bug
|
||||||
uint32 desca = ReadReg(OHCI_RH_DESCRIPTOR_A);
|
uint32 desca = _ReadReg(OHCI_RH_DESCRIPTOR_A);
|
||||||
WriteReg(OHCI_RH_DESCRIPTOR_A, desca | OHCI_RH_NO_OVER_CURRENT_PROTECTION);
|
_WriteReg(OHCI_RH_DESCRIPTOR_A, desca | OHCI_RH_NO_OVER_CURRENT_PROTECTION);
|
||||||
WriteReg(OHCI_RH_STATUS, OHCI_RH_LOCAL_POWER_STATUS_CHANGE);
|
_WriteReg(OHCI_RH_STATUS, OHCI_RH_LOCAL_POWER_STATUS_CHANGE);
|
||||||
snooze(OHCI_ENABLE_POWER_DELAY);
|
snooze(OHCI_ENABLE_POWER_DELAY);
|
||||||
WriteReg(OHCI_RH_DESCRIPTOR_A, desca);
|
_WriteReg(OHCI_RH_DESCRIPTOR_A, desca);
|
||||||
|
|
||||||
// The AMD756 requires a delay before re-reading the register,
|
// The AMD756 requires a delay before re-reading the register,
|
||||||
// otherwise it will occasionally report 0 ports.
|
// otherwise it will occasionally report 0 ports.
|
||||||
uint32 numberOfPorts = 0;
|
uint32 numberOfPorts = 0;
|
||||||
for (uint32 i = 0; i < 10 && numberOfPorts == 0; i++) {
|
for (uint32 i = 0; i < 10 && numberOfPorts == 0; i++) {
|
||||||
snooze(OHCI_READ_DESC_DELAY);
|
snooze(OHCI_READ_DESC_DELAY);
|
||||||
uint32 descriptor = ReadReg(OHCI_RH_DESCRIPTOR_A);
|
uint32 descriptor = _ReadReg(OHCI_RH_DESCRIPTOR_A);
|
||||||
numberOfPorts = OHCI_RH_GET_PORT_COUNT(descriptor);
|
numberOfPorts = OHCI_RH_GET_PORT_COUNT(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add Finisher Thread.
|
||||||
|
|
||||||
|
TRACE(("usb_ohci: OHCI Host Controller Driver constructed\n"));
|
||||||
|
|
||||||
fInitOK = true;
|
fInitOK = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,13 +309,13 @@ OHCI::Start()
|
|||||||
if (InitCheck())
|
if (InitCheck())
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
if (!(ReadReg(OHCI_CONTROL) & OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL)) {
|
if (!(_ReadReg(OHCI_CONTROL) & OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL)) {
|
||||||
TRACE(("usb_ohci::Start(): Controller not started. TODO: find out what happens.\n"));
|
TRACE(("usb_ohci::Start(): Controller not started. TODO: find out what happens.\n"));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fRootHubAddress = AllocateAddress();
|
fRootHubAddress = AllocateAddress();
|
||||||
fNumPorts = OHCI_RH_GET_PORT_COUNT(ReadReg(OHCI_RH_DESCRIPTOR_A));
|
fNumPorts = OHCI_RH_GET_PORT_COUNT(_ReadReg(OHCI_RH_DESCRIPTOR_A));
|
||||||
|
|
||||||
fRootHub = new(std::nothrow) OHCIRootHub(RootObject(), fRootHubAddress);
|
fRootHub = new(std::nothrow) OHCIRootHub(RootObject(), fRootHubAddress);
|
||||||
if (!fRootHub) {
|
if (!fRootHub) {
|
||||||
@ -420,7 +449,7 @@ OHCI::GetPortStatus(uint8 index, usb_port_status *status)
|
|||||||
return B_BAD_INDEX;
|
return B_BAD_INDEX;
|
||||||
|
|
||||||
status->status = status->change = 0;
|
status->status = status->change = 0;
|
||||||
uint32 portStatus = ReadReg(OHCI_RH_PORT_STATUS(index));
|
uint32 portStatus = _ReadReg(OHCI_RH_PORT_STATUS(index));
|
||||||
|
|
||||||
TRACE(("usb_ohci: RootHub::GetPortStatus: Port %i Value 0x%lx\n", OHCI_RH_PORT_STATUS(index), portStatus));
|
TRACE(("usb_ohci: RootHub::GetPortStatus: Port %i Value 0x%lx\n", OHCI_RH_PORT_STATUS(index), portStatus));
|
||||||
|
|
||||||
@ -466,11 +495,11 @@ OHCI::SetPortFeature(uint8 index, uint16 feature)
|
|||||||
|
|
||||||
switch (feature) {
|
switch (feature) {
|
||||||
case PORT_RESET:
|
case PORT_RESET:
|
||||||
WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS);
|
_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
case PORT_POWER:
|
case PORT_POWER:
|
||||||
WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS);
|
_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,11 +516,11 @@ OHCI::ClearPortFeature(uint8 index, uint16 feature)
|
|||||||
|
|
||||||
switch (feature) {
|
switch (feature) {
|
||||||
case C_PORT_RESET:
|
case C_PORT_RESET:
|
||||||
WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC);
|
_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
case C_PORT_CONNECTION:
|
case C_PORT_CONNECTION:
|
||||||
WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC);
|
_WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,34 +528,35 @@ OHCI::ClearPortFeature(uint8 index, uint16 feature)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Endpoint *
|
ohci_endpoint_descriptor*
|
||||||
OHCI::_AllocateEndpoint()
|
OHCI::_AllocateEndpoint()
|
||||||
{
|
{
|
||||||
TRACE(("OHCI::%s()\n", __FUNCTION__));
|
ohci_endpoint_descriptor *endpoint;
|
||||||
|
void* physicalAddress;
|
||||||
|
|
||||||
//Allocate memory chunk
|
//Allocate memory chunk
|
||||||
Endpoint *endpoint = new(std::nothrow) Endpoint;
|
if (fStack->AllocateChunk((void **)&endpoint, &physicalAddress,
|
||||||
void *phy;
|
sizeof(ohci_endpoint_descriptor)) < B_OK) {
|
||||||
if (fStack->AllocateChunk((void **)&endpoint->ed, &phy, sizeof(ohci_endpoint_descriptor)) != B_OK) {
|
TRACE_ERROR(("usb_uhci: failed to allocate endpoint descriptor\n"));
|
||||||
TRACE(("OHCI::AllocateEndpoint(): Error Allocating Endpoint\n"));
|
return NULL;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
endpoint->physical_address = (addr_t)phy;
|
|
||||||
|
endpoint->this_physical = (addr_t)physicalAddress;
|
||||||
//Initialize the physical part
|
|
||||||
memset((void *)endpoint->ed, 0, sizeof(ohci_endpoint_descriptor));
|
// Add an empty list by creating a general descriptor
|
||||||
endpoint->ed->flags = OHCI_ENDPOINT_SKIP;
|
ohci_general_transfer_descriptor *descriptor = _CreateGeneralDescriptor();
|
||||||
|
endpoint->head_physical_descriptor = descriptor->this_physical;
|
||||||
//Add a NULL list by creating one TransferDescriptor
|
endpoint->tail_physical_descriptor = descriptor->this_physical;
|
||||||
TransferDescriptor *trans = new(std::nothrow) TransferDescriptor;
|
|
||||||
endpoint->head = endpoint->tail = trans;
|
endpoint->head_logical_descriptor = descriptor;
|
||||||
endpoint->ed->head_pointer = endpoint->ed->tail_pointer = trans->physical_address;
|
endpoint->tail_logical_descriptor = descriptor;
|
||||||
|
|
||||||
return endpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
OHCI::_FreeEndpoint(Endpoint *end)
|
OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint)
|
||||||
{
|
{
|
||||||
TRACE(("OHCI::%s(%p)\n", __FUNCTION__, end));
|
TRACE(("OHCI::%s(%p)\n", __FUNCTION__, end));
|
||||||
fStack->FreeChunk((void *)end->ed, (void *) end->physical_address, sizeof(ohci_endpoint_descriptor));
|
fStack->FreeChunk((void *)end->ed, (void *) end->physical_address, sizeof(ohci_endpoint_descriptor));
|
||||||
@ -653,14 +683,14 @@ OHCI::_InsertEndpointForPipe(Pipe *p)
|
|||||||
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
OHCI::WriteReg(uint32 reg, uint32 value)
|
OHCI::_WriteReg(uint32 reg, uint32 value)
|
||||||
{
|
{
|
||||||
*(volatile uint32 *)(fOperationalRegisters + reg) = value;
|
*(volatile uint32 *)(fOperationalRegisters + reg) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline uint32
|
inline uint32
|
||||||
OHCI::ReadReg(uint32 reg)
|
OHCI::_ReadReg(uint32 reg)
|
||||||
{
|
{
|
||||||
return *(volatile uint32 *)(fOperationalRegisters + reg);
|
return *(volatile uint32 *)(fOperationalRegisters + reg);
|
||||||
}
|
}
|
||||||
|
@ -81,15 +81,15 @@ static pci_module_info *sPCIModule;
|
|||||||
// Host Controller Communication Area related stuff
|
// Host Controller Communication Area related stuff
|
||||||
area_id fHccaArea;
|
area_id fHccaArea;
|
||||||
struct ohci_hcca *fHcca;
|
struct ohci_hcca *fHcca;
|
||||||
Endpoint *fInterruptEndpoints[OHCI_NUMBER_OF_ENDPOINTS];
|
ohci_endpoint_descriptor *fInterruptEndpoints[OHCI_NUMBER_OF_ENDPOINTS];
|
||||||
|
|
||||||
// Dummy endpoints
|
// Dummy endpoints
|
||||||
Endpoint *fDummyControl;
|
ohci_endpoint_descriptor *fDummyControl;
|
||||||
Endpoint *fDummyBulk;
|
ohci_endpoint_descriptor *fDummyBulk;
|
||||||
Endpoint *fDummyIsochronous;
|
ohci_endpoint_descriptor *fDummyIsochronous;
|
||||||
|
|
||||||
// Endpoint related methods
|
// Endpoint related methods
|
||||||
Endpoint *_AllocateEndpoint();
|
ohci_endpoint_descriptor *_AllocateEndpoint();
|
||||||
void _FreeEndpoint(Endpoint *end);
|
void _FreeEndpoint(Endpoint *end);
|
||||||
TransferDescriptor *_AllocateTransfer();
|
TransferDescriptor *_AllocateTransfer();
|
||||||
void _FreeTransfer(TransferDescriptor *trans);
|
void _FreeTransfer(TransferDescriptor *trans);
|
||||||
|
Loading…
Reference in New Issue
Block a user