EHCI: Do not ignore status of PrepareKernelAccess.
May help with #17799.
This commit is contained in:
@@ -1887,11 +1887,13 @@ EHCI::FinishTransfers()
|
|||||||
// data to read out
|
// data to read out
|
||||||
iovec *vector = transfer->transfer->Vector();
|
iovec *vector = transfer->transfer->Vector();
|
||||||
size_t vectorCount = transfer->transfer->VectorCount();
|
size_t vectorCount = transfer->transfer->VectorCount();
|
||||||
transfer->transfer->PrepareKernelAccess();
|
callbackStatus = transfer->transfer->PrepareKernelAccess();
|
||||||
actualLength = ReadDescriptorChain(
|
if (callbackStatus == B_OK) {
|
||||||
transfer->data_descriptor,
|
actualLength = ReadDescriptorChain(
|
||||||
vector, vectorCount,
|
transfer->data_descriptor,
|
||||||
&nextDataToggle);
|
vector, vectorCount,
|
||||||
|
&nextDataToggle);
|
||||||
|
}
|
||||||
} else if (transfer->data_descriptor) {
|
} else if (transfer->data_descriptor) {
|
||||||
// calculate transfered length
|
// calculate transfered length
|
||||||
actualLength = ReadActualLength(
|
actualLength = ReadActualLength(
|
||||||
@@ -1900,36 +1902,36 @@ EHCI::FinishTransfers()
|
|||||||
|
|
||||||
transfer->transfer->TransferPipe()->SetDataToggle(
|
transfer->transfer->TransferPipe()->SetDataToggle(
|
||||||
nextDataToggle);
|
nextDataToggle);
|
||||||
|
}
|
||||||
|
|
||||||
if (transfer->transfer->IsFragmented()) {
|
if (callbackStatus == B_OK && transfer->transfer->IsFragmented()) {
|
||||||
// this transfer may still have data left
|
// this transfer may still have data left
|
||||||
transfer->transfer->AdvanceByFragment(actualLength);
|
transfer->transfer->AdvanceByFragment(actualLength);
|
||||||
if (transfer->transfer->FragmentLength() > 0) {
|
if (transfer->transfer->FragmentLength() > 0) {
|
||||||
FreeDescriptorChain(transfer->data_descriptor);
|
FreeDescriptorChain(transfer->data_descriptor);
|
||||||
status_t result = FillQueueWithData(
|
status_t result = FillQueueWithData(
|
||||||
transfer->transfer,
|
transfer->transfer,
|
||||||
transfer->queue_head,
|
transfer->queue_head,
|
||||||
&transfer->data_descriptor, NULL, true);
|
&transfer->data_descriptor, NULL, true);
|
||||||
|
|
||||||
if (result == B_OK && Lock()) {
|
if (result == B_OK && Lock()) {
|
||||||
// reappend the transfer
|
// reappend the transfer
|
||||||
if (fLastTransfer)
|
if (fLastTransfer)
|
||||||
fLastTransfer->link = transfer;
|
fLastTransfer->link = transfer;
|
||||||
if (!fFirstTransfer)
|
if (!fFirstTransfer)
|
||||||
fFirstTransfer = transfer;
|
fFirstTransfer = transfer;
|
||||||
|
|
||||||
fLastTransfer = transfer;
|
fLastTransfer = transfer;
|
||||||
Unlock();
|
Unlock();
|
||||||
|
|
||||||
transfer = next;
|
transfer = next;
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the transfer is done, but we already set the
|
|
||||||
// actualLength with AdvanceByFragment()
|
|
||||||
actualLength = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the transfer is done, but we already set the
|
||||||
|
// actualLength with AdvanceByFragment()
|
||||||
|
actualLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer->transfer->Finished(callbackStatus, actualLength);
|
transfer->transfer->Finished(callbackStatus, actualLength);
|
||||||
@@ -2057,9 +2059,11 @@ EHCI::FinishIsochronousTransfers()
|
|||||||
if (transfer && transfer->is_active) {
|
if (transfer && transfer->is_active) {
|
||||||
TRACE("FinishIsochronousTransfers active transfer\n");
|
TRACE("FinishIsochronousTransfers active transfer\n");
|
||||||
size_t actualLength = 0;
|
size_t actualLength = 0;
|
||||||
|
status_t status = B_OK;
|
||||||
if (((itd->buffer_phy[1] >> EHCI_ITD_DIR_SHIFT) & 1) != 0) {
|
if (((itd->buffer_phy[1] >> EHCI_ITD_DIR_SHIFT) & 1) != 0) {
|
||||||
transfer->transfer->PrepareKernelAccess();
|
status = transfer->transfer->PrepareKernelAccess();
|
||||||
actualLength = ReadIsochronousDescriptorChain(transfer);
|
if (status == B_OK)
|
||||||
|
actualLength = ReadIsochronousDescriptorChain(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the transfer
|
// Remove the transfer
|
||||||
@@ -2080,7 +2084,7 @@ EHCI::FinishIsochronousTransfers()
|
|||||||
}
|
}
|
||||||
transfer->link = NULL;
|
transfer->link = NULL;
|
||||||
|
|
||||||
transfer->transfer->Finished(B_OK, actualLength);
|
transfer->transfer->Finished(status, actualLength);
|
||||||
|
|
||||||
itd = itd->prev;
|
itd = itd->prev;
|
||||||
|
|
||||||
@@ -2344,8 +2348,14 @@ EHCI::FillQueueWithRequest(Transfer *transfer, ehci_qh *queueHead,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!directionIn) {
|
if (!directionIn) {
|
||||||
if (prepareKernelAccess)
|
if (prepareKernelAccess) {
|
||||||
transfer->PrepareKernelAccess();
|
result = transfer->PrepareKernelAccess();
|
||||||
|
if (result != B_OK) {
|
||||||
|
FreeDescriptor(setupDescriptor);
|
||||||
|
FreeDescriptor(statusDescriptor);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
WriteDescriptorChain(dataDescriptor, transfer->Vector(),
|
WriteDescriptorChain(dataDescriptor, transfer->Vector(),
|
||||||
transfer->VectorCount());
|
transfer->VectorCount());
|
||||||
}
|
}
|
||||||
@@ -2386,8 +2396,13 @@ EHCI::FillQueueWithData(Transfer *transfer, ehci_qh *queueHead,
|
|||||||
|
|
||||||
lastDescriptor->token |= EHCI_QTD_IOC;
|
lastDescriptor->token |= EHCI_QTD_IOC;
|
||||||
if (!directionIn) {
|
if (!directionIn) {
|
||||||
if (prepareKernelAccess)
|
if (prepareKernelAccess) {
|
||||||
transfer->PrepareKernelAccess();
|
result = transfer->PrepareKernelAccess();
|
||||||
|
if (result != B_OK) {
|
||||||
|
FreeDescriptorChain(firstDescriptor);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
WriteDescriptorChain(firstDescriptor, transfer->Vector(),
|
WriteDescriptorChain(firstDescriptor, transfer->Vector(),
|
||||||
transfer->VectorCount());
|
transfer->VectorCount());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user