* Replaced snooze with spin (Thanks Axel)

* Fixing TRACE messages
* minor clean up


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22935 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Salvatore Benedetto
2007-11-17 11:03:16 +00:00
parent e1abd4c8ce
commit eaa35fb2d1
+36 -61
View File
@@ -18,7 +18,7 @@ pci_module_info *OHCI::sPCIModule = NULL;
static int32 static int32
ohci_std_ops( int32 op , ... ) ohci_std_ops(int32 op, ...)
{ {
switch (op) { switch (op) {
case B_MODULE_INIT: case B_MODULE_INIT:
@@ -157,7 +157,7 @@ OHCI::OHCI(pci_info *info, Stack *stack)
} }
fDummyIsochronous->flags |= OHCI_ENDPOINT_SKIP; fDummyIsochronous->flags |= OHCI_ENDPOINT_SKIP;
// Create the interrupt tree // Static endpoints that get linked in the HCCA
fInterruptEndpoints = new(std::nothrow) fInterruptEndpoints = new(std::nothrow)
ohci_endpoint_descriptor *[OHCI_NUMBER_OF_INTERRUPTS]; ohci_endpoint_descriptor *[OHCI_NUMBER_OF_INTERRUPTS];
if (!fInterruptEndpoints) { if (!fInterruptEndpoints) {
@@ -168,11 +168,11 @@ OHCI::OHCI(pci_info *info, Stack *stack)
_FreeEndpoint(fDummyIsochronous); _FreeEndpoint(fDummyIsochronous);
return; return;
} }
// Static endpoints that get linked in the HCCA
for (uint32 i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++) { for (uint32 i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++) {
fInterruptEndpoints[i] = _AllocateEndpoint(); fInterruptEndpoints[i] = _AllocateEndpoint();
if (!fInterruptEndpoints[i]) { if (!fInterruptEndpoints[i]) {
TRACE_ERROR(("ohci_usb: cannot allocate memory for"
" fInterruptEndpoints[%d] endpoint\n", i));
while (--i >= 0) while (--i >= 0)
_FreeEndpoint(fInterruptEndpoints[i]); _FreeEndpoint(fInterruptEndpoints[i]);
_FreeEndpoint(fDummyBulk); _FreeEndpoint(fDummyBulk);
@@ -180,41 +180,15 @@ OHCI::OHCI(pci_info *info, Stack *stack)
_FreeEndpoint(fDummyIsochronous); _FreeEndpoint(fDummyIsochronous);
return; return;
} }
// Make them point all to the dummy isochronous endpoint
fInterruptEndpoints[i]->flags |= OHCI_ENDPOINT_SKIP; fInterruptEndpoints[i]->flags |= OHCI_ENDPOINT_SKIP;
fInterruptEndpoints[i]->next_physical_endpoint fInterruptEndpoints[i]->next_physical_endpoint
= fDummyIsochronous->physical_address; = fDummyIsochronous->physical_address;
} }
#if 0 // Fill HCCA interrupt table.
ohci_endpoint_descriptor *current;
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;
}
fInterruptEndpoints[i] = current;
current->flags |= OHCI_ENDPOINT_SKIP;
if (i != 0)
previous = fInterruptEndpoints[(i - 1) / 2];
else
previous = fDummyIsochronous;
current->next_logical_endpoint = previous;
current->next_physical_endpoint = previous->physical_address;
}
#endif
// 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->interrupt_table[revbits[i]] = fHcca->interrupt_table[i] = fInterruptEndpoints[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);
@@ -254,7 +228,7 @@ OHCI::OHCI(pci_info *info, Stack *stack)
cpu_status former = disable_interrupts(); cpu_status former = disable_interrupts();
_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); spin(10);
if (!(_ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET)) if (!(_ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET))
break; break;
} }
@@ -330,8 +304,6 @@ OHCI::OHCI(pci_info *info, Stack *stack)
install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line, install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line,
_InterruptHandler, (void *)this, 0); _InterruptHandler, (void *)this, 0);
// TODO: Enable interrupts. Maybe disable first somewhere before :)
TRACE(("usb_ohci: OHCI Host Controller Driver constructed\n")); TRACE(("usb_ohci: OHCI Host Controller Driver constructed\n"));
fInitOK = true; fInitOK = true;
} }
@@ -339,6 +311,11 @@ OHCI::OHCI(pci_info *info, Stack *stack)
OHCI::~OHCI() OHCI::~OHCI()
{ {
int32 result = 0;
fStopFinishThread = true;
delete_sem(fFinishTransfersSem);
wait_for_thread(fFinishThread, &result);
if (fHccaArea > 0) if (fHccaArea > 0)
delete_area(fHccaArea); delete_area(fHccaArea);
if (fRegisterArea > 0) if (fRegisterArea > 0)
@@ -355,6 +332,7 @@ OHCI::~OHCI()
if (fInterruptEndpoints[i]) if (fInterruptEndpoints[i])
_FreeEndpoint(fInterruptEndpoints[i]); _FreeEndpoint(fInterruptEndpoints[i]);
delete [] fInterruptEndpoints; delete [] fInterruptEndpoints;
put_module(B_PCI_MODULE_NAME);
} }
@@ -390,9 +368,13 @@ OHCI::_FinishThread(void *data)
void void
OHCI::_FinishTransfer() OHCI::_FinishTransfer()
{ {
// TODO: block on the semaphore while (!fStopFinishThread) {
if (acquire_sem(fFinishTransfersSem) < B_OK)
continue;
}
} }
status_t status_t
OHCI::Start() OHCI::Start()
{ {
@@ -495,14 +477,13 @@ OHCI::AddTo(Stack *stack)
if (!sPCIModule) { if (!sPCIModule) {
status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule); status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule);
if (status < B_OK) { if (status < B_OK) {
TRACE_ERROR(("usb_ohci: AddTo(): getting pci module failed! 0x%08lx\n", TRACE_ERROR(("usb_ohci: getting pci module failed! 0x%08lx\n",
status)); status));
return status; return status;
} }
} }
TRACE(("usb_ohci: AddTo(): setting up hardware\n")); TRACE(("usb_ohci: searching devices\n"));
bool found = false; bool found = false;
pci_info *item = new(std::nothrow) pci_info; pci_info *item = new(std::nothrow) pci_info;
if (!item) { if (!item) {
@@ -517,12 +498,12 @@ OHCI::AddTo(Stack *stack)
&& item->class_api == PCI_usb_ohci) { && item->class_api == PCI_usb_ohci) {
if (item->u.h0.interrupt_line == 0 if (item->u.h0.interrupt_line == 0
|| item->u.h0.interrupt_line == 0xFF) { || item->u.h0.interrupt_line == 0xFF) {
TRACE_ERROR(("usb_ohci: AddTo(): found with invalid IRQ -" TRACE_ERROR(("usb_ohci: found device with invalid IRQ -"
" check IRQ assignement\n")); " check IRQ assignement\n"));
continue; continue;
} }
TRACE(("usb_ohci: AddTo(): found at IRQ %u\n", TRACE(("usb_ohci: found device at IRQ %u\n",
item->u.h0.interrupt_line)); item->u.h0.interrupt_line));
OHCI *bus = new(std::nothrow) OHCI(item, stack); OHCI *bus = new(std::nothrow) OHCI(item, stack);
if (!bus) { if (!bus) {
@@ -533,8 +514,7 @@ OHCI::AddTo(Stack *stack)
} }
if (bus->InitCheck() < B_OK) { if (bus->InitCheck() < B_OK) {
TRACE_ERROR(("usb_ohci: AddTo(): InitCheck() failed 0x%08lx\n", TRACE_ERROR(("usb_ohci: bus failed init check\n"));
bus->InitCheck()));
delete bus; delete bus;
continue; continue;
} }
@@ -551,6 +531,7 @@ OHCI::AddTo(Stack *stack)
if (!found) { if (!found) {
TRACE_ERROR(("usb_ohci: no devices found\n")); TRACE_ERROR(("usb_ohci: no devices found\n"));
delete item; delete item;
sPCIModule = NULL;
put_module(B_PCI_MODULE_NAME); put_module(B_PCI_MODULE_NAME);
return ENODEV; return ENODEV;
} }
@@ -675,6 +656,9 @@ OHCI::_AllocateEndpoint()
void void
OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint) OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint)
{ {
if (!endpoint)
return;
fStack->FreeChunk((void *)endpoint, (void *)endpoint->physical_address, fStack->FreeChunk((void *)endpoint, (void *)endpoint->physical_address,
sizeof(ohci_endpoint_descriptor)); sizeof(ohci_endpoint_descriptor));
} }
@@ -716,28 +700,19 @@ OHCI::_InsertEndpointForPipe(Pipe *pipe)
{ {
#if 0 #if 0
TRACE(("OHCI: Inserting Endpoint for device %u function %u\n", p->DeviceAddress(), p->EndpointAddress())); TRACE(("OHCI: Inserting Endpoint for device %u function %u\n", p->DeviceAddress(), p->EndpointAddress()));
if (InitCheck())
return B_ERROR;
//Endpoint *endpoint = _AllocateEndpoint();
ohci_endpoint_descriptor *endpoint = _AllocateEndpoint(); ohci_endpoint_descriptor *endpoint = _AllocateEndpoint();
if (!endpoint) if (!endpoint) {
TRACE_ERROR(("usb_ohci: cannot allocate memory for endpoint\n"));
return B_NO_MEMORY; return B_NO_MEMORY;
}
endpoint->flags |= OHCI_ENDPOINT_SKIP;
//Set up properties of the endpoint // Set up properties of the endpoint
//TODO: does this need its own utility function? endpoints->flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(pipe->DeviceAddress())
{ | OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(pipe->EndpointAddress());
uint32 properties = 0;
//Set the device address
properties |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(p->DeviceAddress());
//Set the endpoint number
properties |= OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(p->EndpointAddress());
//Set the direction //Set the direction
switch (p->Direction()) { switch (pipe->Direction()) {
case Pipe::In: case Pipe::In:
properties |= OHCI_ENDPOINT_DIRECTION_IN; properties |= OHCI_ENDPOINT_DIRECTION_IN;
break; break;