[haiku-commits] haiku: hrev56192 - src/add-ons/kernel/busses/usb

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 14 Jun 2022 19:26:59 +0000 (UTC)

hrev56192 adds 1 changeset to branch 'master'
old head: d621ee6564d749847029b0f0e1b8a7e46f6d7831
new head: 07b1a217753100f8c8b0ff74faa8d459fc84555e
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=07b1a2177531+%5Ed621ee6564d7

----------------------------------------------------------------------------

07b1a2177531: EHCI: Do not ignore status of PrepareKernelAccess.
  
  May help with #17799.

                              [ Augustin Cavalier <waddlesplash@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev56192
Commit:      07b1a217753100f8c8b0ff74faa8d459fc84555e
URL:         https://git.haiku-os.org/haiku/commit/?id=07b1a2177531
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Tue Jun 14 19:26:27 2022 UTC

Ticket:      https://dev.haiku-os.org/ticket/17799

----------------------------------------------------------------------------

1 file changed, 54 insertions(+), 39 deletions(-)
src/add-ons/kernel/busses/usb/ehci.cpp | 93 +++++++++++++++++-------------

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp 
b/src/add-ons/kernel/busses/usb/ehci.cpp
index d62dfe3614..e0531b4492 100644
--- a/src/add-ons/kernel/busses/usb/ehci.cpp
+++ b/src/add-ons/kernel/busses/usb/ehci.cpp
@@ -1887,11 +1887,13 @@ EHCI::FinishTransfers()
                                                // data to read out
                                                iovec *vector = 
transfer->transfer->Vector();
                                                size_t vectorCount = 
transfer->transfer->VectorCount();
-                                               
transfer->transfer->PrepareKernelAccess();
-                                               actualLength = 
ReadDescriptorChain(
-                                                       
transfer->data_descriptor,
-                                                       vector, vectorCount,
-                                                       &nextDataToggle);
+                                               callbackStatus = 
transfer->transfer->PrepareKernelAccess();
+                                               if (callbackStatus == B_OK) {
+                                                       actualLength = 
ReadDescriptorChain(
+                                                               
transfer->data_descriptor,
+                                                               vector, 
vectorCount,
+                                                               
&nextDataToggle);
+                                               }
                                        } else if (transfer->data_descriptor) {
                                                // calculate transfered length
                                                actualLength = ReadActualLength(
@@ -1900,36 +1902,36 @@ EHCI::FinishTransfers()
 
                                        
transfer->transfer->TransferPipe()->SetDataToggle(
                                                nextDataToggle);
+                               }
 
-                                       if (transfer->transfer->IsFragmented()) 
{
-                                               // this transfer may still have 
data left
-                                               
transfer->transfer->AdvanceByFragment(actualLength);
-                                               if 
(transfer->transfer->FragmentLength() > 0) {
-                                                       
FreeDescriptorChain(transfer->data_descriptor);
-                                                       status_t result = 
FillQueueWithData(
-                                                               
transfer->transfer,
-                                                               
transfer->queue_head,
-                                                               
&transfer->data_descriptor, NULL, true);
-
-                                                       if (result == B_OK && 
Lock()) {
-                                                               // reappend the 
transfer
-                                                               if 
(fLastTransfer)
-                                                                       
fLastTransfer->link = transfer;
-                                                               if 
(!fFirstTransfer)
-                                                                       
fFirstTransfer = transfer;
-
-                                                               fLastTransfer = 
transfer;
-                                                               Unlock();
-
-                                                               transfer = next;
-                                                               continue;
-                                                       }
+                               if (callbackStatus == B_OK && 
transfer->transfer->IsFragmented()) {
+                                       // this transfer may still have data 
left
+                                       
transfer->transfer->AdvanceByFragment(actualLength);
+                                       if 
(transfer->transfer->FragmentLength() > 0) {
+                                               
FreeDescriptorChain(transfer->data_descriptor);
+                                               status_t result = 
FillQueueWithData(
+                                                       transfer->transfer,
+                                                       transfer->queue_head,
+                                                       
&transfer->data_descriptor, NULL, true);
+
+                                               if (result == B_OK && Lock()) {
+                                                       // reappend the transfer
+                                                       if (fLastTransfer)
+                                                               
fLastTransfer->link = transfer;
+                                                       if (!fFirstTransfer)
+                                                               fFirstTransfer 
= transfer;
+
+                                                       fLastTransfer = 
transfer;
+                                                       Unlock();
+
+                                                       transfer = next;
+                                                       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);
@@ -2057,9 +2059,11 @@ EHCI::FinishIsochronousTransfers()
                                if (transfer && transfer->is_active) {
                                        TRACE("FinishIsochronousTransfers 
active transfer\n");
                                        size_t actualLength = 0;
+                                       status_t status = B_OK;
                                        if (((itd->buffer_phy[1] >> 
EHCI_ITD_DIR_SHIFT) & 1) != 0) {
-                                               
transfer->transfer->PrepareKernelAccess();
-                                               actualLength = 
ReadIsochronousDescriptorChain(transfer);
+                                               status = 
transfer->transfer->PrepareKernelAccess();
+                                               if (status == B_OK)
+                                                       actualLength = 
ReadIsochronousDescriptorChain(transfer);
                                        }
 
                                        // Remove the transfer
@@ -2080,7 +2084,7 @@ EHCI::FinishIsochronousTransfers()
                                        }
                                        transfer->link = NULL;
 
-                                       transfer->transfer->Finished(B_OK, 
actualLength);
+                                       transfer->transfer->Finished(status, 
actualLength);
 
                                        itd = itd->prev;
 
@@ -2344,8 +2348,14 @@ EHCI::FillQueueWithRequest(Transfer *transfer, ehci_qh 
*queueHead,
                }
 
                if (!directionIn) {
-                       if (prepareKernelAccess)
-                               transfer->PrepareKernelAccess();
+                       if (prepareKernelAccess) {
+                               result = transfer->PrepareKernelAccess();
+                               if (result != B_OK) {
+                                       FreeDescriptor(setupDescriptor);
+                                       FreeDescriptor(statusDescriptor);
+                                       return result;
+                               }
+                       }
                        WriteDescriptorChain(dataDescriptor, transfer->Vector(),
                                transfer->VectorCount());
                }
@@ -2386,8 +2396,13 @@ EHCI::FillQueueWithData(Transfer *transfer, ehci_qh 
*queueHead,
 
        lastDescriptor->token |= EHCI_QTD_IOC;
        if (!directionIn) {
-               if (prepareKernelAccess)
-                       transfer->PrepareKernelAccess();
+               if (prepareKernelAccess) {
+                       result = transfer->PrepareKernelAccess();
+                       if (result != B_OK) {
+                               FreeDescriptorChain(firstDescriptor);
+                               return result;
+                       }
+               }
                WriteDescriptorChain(firstDescriptor, transfer->Vector(),
                        transfer->VectorCount());
        }


Other related posts:

  • » [haiku-commits] haiku: hrev56192 - src/add-ons/kernel/busses/usb - waddlesplash