A try at actual data toggle handling. Since we do not properly ensure that the

toggle carry stays valid, we better make sure we set it correctly. Additionally
even if the toggle carry wasn't clobbered, there are conditions the toggle is
reset without the controller being able to notice (as in clearing a halt state).
Since I don't have any OHCI hardware this is untested, but should fix bug #4067
if correct.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32510 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2009-08-19 04:45:02 +00:00
parent 75c92c56f6
commit abe8e8a2c2
2 changed files with 17 additions and 8 deletions

View File

@ -1033,6 +1033,11 @@ OHCI::_FinishTransfers()
transfer->data_descriptor);
}
// get the last data toggle and store it for next time
transfer->transfer->TransferPipe()->SetDataToggle(
(transfer->endpoint->head_physical_descriptor
& OHCI_ENDPOINT_TOGGLE_CARRY) == 0);
if (transfer->transfer->IsFragmented()) {
// this transfer may still have data left
TRACE("advancing fragmented transfer\n");
@ -1109,8 +1114,9 @@ OHCI::_SubmitRequest(Transfer *transfer)
ohci_general_td *dataDescriptor = NULL;
if (transfer->VectorCount() > 0) {
ohci_general_td *lastDescriptor = NULL;
result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor,
directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT,
result = _CreateDescriptorChain(transfer->TransferPipe(),
&dataDescriptor, &lastDescriptor, directionIn
? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT,
transfer->VectorLength());
if (result < B_OK) {
_FreeGeneralDescriptor(setupDescriptor);
@ -1158,8 +1164,9 @@ OHCI::_SubmitTransfer(Transfer *transfer)
ohci_general_td *firstDescriptor = NULL;
ohci_general_td *lastDescriptor = NULL;
status_t result = _CreateDescriptorChain(&firstDescriptor, &lastDescriptor,
directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT,
status_t result = _CreateDescriptorChain(pipe, &firstDescriptor,
&lastDescriptor, directionIn
? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT,
transfer->VectorLength());
if (result < B_OK)
@ -1514,7 +1521,7 @@ OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor)
status_t
OHCI::_CreateDescriptorChain(ohci_general_td **_firstDescriptor,
OHCI::_CreateDescriptorChain(Pipe *pipe, ohci_general_td **_firstDescriptor,
ohci_general_td **_lastDescriptor, uint32 direction, size_t bufferSize)
{
size_t blockSize = 8192;
@ -1522,6 +1529,7 @@ OHCI::_CreateDescriptorChain(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++) {
@ -1536,13 +1544,14 @@ OHCI::_CreateDescriptorChain(ohci_general_td **_firstDescriptor,
descriptor->flags = direction
| OHCI_TD_BUFFER_ROUNDING
| OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED)
| OHCI_TD_TOGGLE_CARRY
| OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE);
| OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE)
| (dataToggle ? OHCI_TD_TOGGLE_1 : OHCI_TD_TOGGLE_0);
// link to previous
if (lastDescriptor)
_LinkDescriptors(lastDescriptor, descriptor);
dataToggle = !dataToggle;
bufferSize -= blockSize;
lastDescriptor = descriptor;
if (!firstDescriptor)

View File

@ -101,7 +101,7 @@ static int32 _FinishThread(void *data);
void _FreeGeneralDescriptor(
ohci_general_td *descriptor);
status_t _CreateDescriptorChain(
status_t _CreateDescriptorChain(Pipe *pipe,
ohci_general_td **firstDescriptor,
ohci_general_td **lastDescriptor,
uint32 direction,