From 0439bcbbbbec2fe70401e02bb962b3f013b166b6 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 18 May 2008 12:34:40 +0000 Subject: [PATCH] Use a dedicated endpoint lock for endpoint manipulation. Fixes the guaranteed deadlock with the BusManager on setup of the default pipes (for addressing). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25542 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/busses/usb/ohci.cpp | 26 ++++++++++++++++++++++++-- src/add-ons/kernel/busses/usb/ohci.h | 7 ++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index a06f0173c5..0ac23d5dc2 100644 --- a/src/add-ons/kernel/busses/usb/ohci.cpp +++ b/src/add-ons/kernel/busses/usb/ohci.cpp @@ -89,6 +89,11 @@ OHCI::OHCI(pci_info *info, Stack *stack) TRACE(("usb_ohci: constructing new OHCI Host Controller Driver\n")); fInitOK = false; + if (benaphore_init(&fEndpointLock, "ohci endpoint lock") < B_OK) { + TRACE_ERROR(("usb_ohci: failed to create endpoint lock\n")); + return; + } + // enable busmaster and memory mapped access uint16 command = sPCIModule->read_pci_config(fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function, PCI_command, 2); @@ -314,6 +319,9 @@ OHCI::~OHCI() delete_sem(fFinishTransfersSem); wait_for_thread(fFinishThread, &result); + _LockEndpoints(); + benaphore_destroy(&fEndpointLock); + if (fHccaArea >= B_OK) delete_area(fHccaArea); if (fRegisterArea >= B_OK) @@ -1255,7 +1263,7 @@ OHCI::_InsertEndpointForPipe(Pipe *pipe) endpoint->tail_physical_descriptor = tail->physical_address; } - if (!Lock()) { + if (!_LockEndpoints()) { if (endpoint->head_logical_descriptor) { _FreeGeneralDescriptor( (ohci_general_td *)endpoint->head_logical_descriptor); @@ -1271,7 +1279,7 @@ OHCI::_InsertEndpointForPipe(Pipe *pipe) head->next_logical_endpoint = (void *)endpoint; head->next_physical_endpoint = (uint32)endpoint->physical_address; - Unlock(); + _UnlockEndpoints(); return B_OK; } @@ -1443,6 +1451,20 @@ OHCI::_FreeIsochronousDescriptor(ohci_isochronous_td *descriptor) } +bool +OHCI::_LockEndpoints() +{ + return (benaphore_lock(&fEndpointLock) == B_OK); +} + + +void +OHCI::_UnlockEndpoints() +{ + benaphore_unlock(&fEndpointLock); +} + + inline void OHCI::_WriteReg(uint32 reg, uint32 value) { diff --git a/src/add-ons/kernel/busses/usb/ohci.h b/src/add-ons/kernel/busses/usb/ohci.h index c66e820952..c0da969861 100644 --- a/src/add-ons/kernel/busses/usb/ohci.h +++ b/src/add-ons/kernel/busses/usb/ohci.h @@ -118,6 +118,10 @@ static int32 _FinishThread(void *data); void _FreeIsochronousDescriptor( ohci_isochronous_td *descriptor); + // Private locking + bool _LockEndpoints(); + void _UnlockEndpoints(); + // Register functions inline void _WriteReg(uint32 reg, uint32 value); inline uint32 _ReadReg(uint32 reg); @@ -134,7 +138,8 @@ static pci_module_info *sPCIModule; ohci_hcca *fHcca; ohci_endpoint_descriptor **fInterruptEndpoints; - // Dummy endpoints + // Endpoint management + benaphore fEndpointLock; ohci_endpoint_descriptor *fDummyControl; ohci_endpoint_descriptor *fDummyBulk; ohci_endpoint_descriptor *fDummyIsochronous;