From 5f92e39f7b50cd57fffbdde384133052c749f7bd Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Thu, 20 Aug 2009 04:45:13 +0000 Subject: [PATCH] That's actually not how it works. OHCI does the dirty work of splitting up the transfer descriptors into individual packets. The descriptors are more a logical thing. As such we do not generate one descriptor per packet but one for each block of two pages at max. Therefore we only set the initial toggle bit to the one we stored on the first descriptor and let OHCI use the carry bit for subsequet descriptors. That error would only be visible on transfers above two pages in size though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32532 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/busses/usb/ohci.cpp | 23 ++++++++++++----------- src/add-ons/kernel/busses/usb/ohci.h | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index bcb74ff48d..ad6130e9b0 100644 --- a/src/add-ons/kernel/busses/usb/ohci.cpp +++ b/src/add-ons/kernel/busses/usb/ohci.cpp @@ -962,7 +962,7 @@ OHCI::_FinishTransfers() } } - // the td has complete without an error + // the td has completed without an error TRACE("td %p done\n", descriptor); if (descriptor == transfer->last_descriptor @@ -1114,9 +1114,8 @@ OHCI::_SubmitRequest(Transfer *transfer) ohci_general_td *dataDescriptor = NULL; if (transfer->VectorCount() > 0) { ohci_general_td *lastDescriptor = NULL; - result = _CreateDescriptorChain(transfer->TransferPipe(), - &dataDescriptor, &lastDescriptor, directionIn - ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, + result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor, + directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, transfer->VectorLength()); if (result < B_OK) { _FreeGeneralDescriptor(setupDescriptor); @@ -1164,14 +1163,18 @@ OHCI::_SubmitTransfer(Transfer *transfer) ohci_general_td *firstDescriptor = NULL; ohci_general_td *lastDescriptor = NULL; - status_t result = _CreateDescriptorChain(pipe, &firstDescriptor, - &lastDescriptor, directionIn - ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, + status_t result = _CreateDescriptorChain(&firstDescriptor, &lastDescriptor, + directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, transfer->VectorLength()); if (result < B_OK) return result; + // Apply data toggle to the first descriptor (the others will use the carry) + firstDescriptor->flags &= ~OHCI_TD_TOGGLE_CARRY; + firstDescriptor->flags |= pipe->DataToggle() ? OHCI_TD_TOGGLE_1 + : OHCI_TD_TOGGLE_0; + // Set the last descriptor to generate an interrupt lastDescriptor->flags &= ~OHCI_TD_INTERRUPT_MASK; lastDescriptor->flags |= @@ -1521,7 +1524,7 @@ OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor) status_t -OHCI::_CreateDescriptorChain(Pipe *pipe, ohci_general_td **_firstDescriptor, +OHCI::_CreateDescriptorChain(ohci_general_td **_firstDescriptor, ohci_general_td **_lastDescriptor, uint32 direction, size_t bufferSize) { size_t blockSize = 8192; @@ -1529,7 +1532,6 @@ OHCI::_CreateDescriptorChain(Pipe *pipe, ohci_general_td **_firstDescriptor, if (descriptorCount == 0) descriptorCount = 1; - bool dataToggle = pipe->DataToggle(); ohci_general_td *firstDescriptor = NULL; ohci_general_td *lastDescriptor = *_firstDescriptor; for (int32 i = 0; i < descriptorCount; i++) { @@ -1545,13 +1547,12 @@ OHCI::_CreateDescriptorChain(Pipe *pipe, ohci_general_td **_firstDescriptor, | OHCI_TD_BUFFER_ROUNDING | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE) - | (dataToggle ? OHCI_TD_TOGGLE_1 : OHCI_TD_TOGGLE_0); + | OHCI_TD_TOGGLE_CARRY; // link to previous if (lastDescriptor) _LinkDescriptors(lastDescriptor, descriptor); - dataToggle = !dataToggle; bufferSize -= blockSize; lastDescriptor = descriptor; if (!firstDescriptor) diff --git a/src/add-ons/kernel/busses/usb/ohci.h b/src/add-ons/kernel/busses/usb/ohci.h index 97a31ff973..b23ce6f46e 100644 --- a/src/add-ons/kernel/busses/usb/ohci.h +++ b/src/add-ons/kernel/busses/usb/ohci.h @@ -101,7 +101,7 @@ static int32 _FinishThread(void *data); void _FreeGeneralDescriptor( ohci_general_td *descriptor); - status_t _CreateDescriptorChain(Pipe *pipe, + status_t _CreateDescriptorChain( ohci_general_td **firstDescriptor, ohci_general_td **lastDescriptor, uint32 direction,