We need to guarantee that when cancel returns that the callback won't be called

anymore. It could happen that the transfer was already in the process of being
finished, so wasn't in the list of pending transfers anymore. Cancel would then
return even though the callback wasn't called yet. This could lead to a callback
being called after a driver was already unloaded (even after it cleaned up the
pipes it used).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33239 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2009-09-23 01:59:05 +00:00
parent be71ca4f57
commit 1393394ba6
6 changed files with 36 additions and 0 deletions
+11
View File
@@ -119,6 +119,7 @@ EHCI::EHCI(pci_info *info, Stack *stack)
fCleanupThread(-1),
fStopThreads(false),
fFreeListHead(NULL),
fProcessingPipe(NULL),
fRootHub(NULL),
fRootHubAddress(0),
fPortCount(0),
@@ -941,6 +942,10 @@ EHCI::CancelQueuedTransfers(Pipe *pipe, bool force)
list = next;
}
// wait for any transfers that might have made it before canceling
while (fProcessingPipe == pipe)
snooze(1000);
// notify the finisher so it can clean up the canceled transfers
release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
return B_OK;
@@ -1075,6 +1080,11 @@ EHCI::FinishTransfers()
if (transfer == fLastTransfer)
fLastTransfer = lastTransfer;
// store the currently processing pipe here so we can wait
// in cancel if we are processing something on the target pipe
if (!transfer->canceled)
fProcessingPipe = transfer->transfer->TransferPipe();
transfer->link = NULL;
Unlock();
}
@@ -1135,6 +1145,7 @@ EHCI::FinishTransfers()
}
transfer->transfer->Finished(callbackStatus, actualLength);
fProcessingPipe = NULL;
}
// unlink hardware queue and delete the transfer
+1
View File
@@ -157,6 +157,7 @@ static pci_module_info * sPCIModule;
thread_id fCleanupThread;
bool fStopThreads;
ehci_qh * fFreeListHead;
Pipe * fProcessingPipe;
// Root Hub
EHCIRootHub * fRootHub;
+11
View File
@@ -71,6 +71,7 @@ OHCI::OHCI(pci_info *info, Stack *stack)
fFinishTransfersSem(-1),
fFinishThread(-1),
fStopFinishThread(false),
fProcessingPipe(NULL),
fRootHub(NULL),
fRootHubAddress(0),
fPortCount(0)
@@ -472,6 +473,10 @@ OHCI::CancelQueuedTransfers(Pipe *pipe, bool force)
list = next;
}
// wait for any transfers that might have made it before canceling
while (fProcessingPipe == pipe)
snooze(1000);
// notify the finisher so it can clean up the canceled transfers
release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
return B_OK;
@@ -1021,6 +1026,11 @@ OHCI::_FinishTransfers()
if (transfer == fLastTransfer)
fLastTransfer = lastTransfer;
// store the currently processing pipe here so we can wait
// in cancel if we are processing something on the target pipe
if (!transfer->canceled)
fProcessingPipe = transfer->transfer->TransferPipe();
transfer->link = NULL;
Unlock();
}
@@ -1071,6 +1081,7 @@ OHCI::_FinishTransfers()
}
transfer->transfer->Finished(callbackStatus, actualLength);
fProcessingPipe = NULL;
}
if (callbackStatus != B_OK) {
+1
View File
@@ -163,6 +163,7 @@ static pci_module_info * sPCIModule;
sem_id fFinishTransfersSem;
thread_id fFinishThread;
bool fStopFinishThread;
Pipe * fProcessingPipe;
// Root Hub
OHCIRootHub * fRootHub;
+11
View File
@@ -335,6 +335,7 @@ UHCI::UHCI(pci_info *info, Stack *stack)
fFinishTransfersSem(-1),
fFinishThread(-1),
fStopThreads(false),
fProcessingPipe(NULL),
fFreeList(NULL),
fCleanupThread(-1),
fCleanupSem(-1),
@@ -795,6 +796,10 @@ UHCI::CancelQueuedTransfers(Pipe *pipe, bool force)
list = next;
}
// wait for any transfers that might have made it before canceling
while (fProcessingPipe == pipe)
snooze(1000);
// notify the finisher so it can clean up the canceled transfers
release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE);
return B_OK;
@@ -1340,6 +1345,11 @@ UHCI::FinishTransfers()
if (transfer == fLastTransfer)
fLastTransfer = lastTransfer;
// store the currently processing pipe here so we can wait
// in cancel if we are processing something on the target pipe
if (!transfer->canceled)
fProcessingPipe = transfer->transfer->TransferPipe();
transfer->link = NULL;
Unlock();
}
@@ -1399,6 +1409,7 @@ UHCI::FinishTransfers()
}
transfer->transfer->Finished(callbackStatus, actualLength);
fProcessingPipe = NULL;
}
// remove and free the hardware queue and its descriptors
+1
View File
@@ -233,6 +233,7 @@ static pci_module_info * sPCIModule;
sem_id fFinishTransfersSem;
thread_id fFinishThread;
bool fStopThreads;
Pipe * fProcessingPipe;
transfer_data * fFreeList;
thread_id fCleanupThread;