diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index c67e3f5a62..ceb708fcde 100644 --- a/src/add-ons/kernel/busses/usb/ohci.cpp +++ b/src/add-ons/kernel/busses/usb/ohci.cpp @@ -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) diff --git a/src/add-ons/kernel/busses/usb/ohci.h b/src/add-ons/kernel/busses/usb/ohci.h index b23ce6f46e..97a31ff973 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( + status_t _CreateDescriptorChain(Pipe *pipe, ohci_general_td **firstDescriptor, ohci_general_td **lastDescriptor, uint32 direction,