From 840cdc9efcf81ce93b1ee48884416e11b8ae748b Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Thu, 20 Aug 2009 07:24:49 +0000 Subject: [PATCH] When adding a transfer, the current tail descriptor of the endpoint will be reused and overwritten by the first descriptor of the new transfer and the first descriptor will become the new tail. We anticipate this situation in _AddPendingTransfer() and set the first_descriptor of the transfer data to the tail already. Since the tail was pretty much cleared to zero, this introduced a race condition. After adding the pending transfer it can already be found in the finisher thread. If this happened before actually switching the tail and first descriptor it would find a descriptor with a condition of 0, meaning "No Error" and would process the transfer incorrectly. Depending on the count of descriptors and the timing of the switch taking place this could have resulted in aborted transfers with actual length 0 or with the correct actual length but invalid data. In the very worst case it could have freed things still in use by the controller, resulting in all sorts of device errors. Sadly it doesn't fix #4067. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32534 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/busses/usb/ohci.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index ad6130e9b0..e12beec132 100644 --- a/src/add-ons/kernel/busses/usb/ohci.cpp +++ b/src/add-ons/kernel/busses/usb/ohci.cpp @@ -813,7 +813,7 @@ OHCI::_AddPendingTransfer(Transfer *transfer, data->canceled = false; data->link = NULL; - // the current tail will become the fist descriptor + // the current tail will become the first descriptor data->first_descriptor = (ohci_general_td *)endpoint->tail_logical_descriptor; // the data and first descriptors might be the same @@ -1231,7 +1231,7 @@ OHCI::_SwitchEndpointTail(ohci_endpoint_descriptor *endpoint, tail->next_logical_descriptor = first->next_logical_descriptor; // the first descriptor becomes the new tail - first->flags = 0; + first->flags = OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED); first->buffer_physical = 0; first->next_physical_descriptor = 0; first->last_physical_byte_address = 0; @@ -1410,6 +1410,7 @@ OHCI::_InsertEndpointForPipe(Pipe *pipe) return B_ERROR; } else { ohci_general_td *tail = _CreateGeneralDescriptor(0); + tail->flags = OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED); endpoint->tail_logical_descriptor = tail; endpoint->head_physical_descriptor = tail->physical_address; endpoint->tail_physical_descriptor = tail->physical_address;