[haiku-commits] haiku: hrev52918 - in src/add-ons/kernel: busses/usb bus_managers/usb

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 22 Feb 2019 13:33:14 -0500 (EST)

hrev52918 adds 3 changesets to branch 'master'
old head: 14263044aac31fb9b570850708a3c29a4f44f95d
new head: da8c1a9a403aed0fa06beeeb100c3c0c50b8362c
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=da8c1a9a403a+%5E14263044aac3

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

c409803d6f4a: XHCI: Refactoring and fixes to SubmitControlRequest.
  
   * Rearrange some basic setup to be more towards the top of the function,
     so we have less things to tear down upon failures.
   * Don't double-initialize qwtrb0 of the Setup Stage (no functional change.)
   * Rework Data Stage initialization considerably:
     - TD_SIZE refers to the number of remaining TRBs in this TD. As we only
       use 1 TRB for the Data Stage TD at present, this should be 0, not 1.
     - Actually copy data for outbound transfers. (This code does get hit,
       so I'm not sure how it wasn't a problem previously.)
   * Initialize the first quadbit of the Status Stage. (Potentially a
     functional change.)
   * Set the TRB_3_DIR bit on the Status Stage correctly as per the spec.
     (See inline comment.)
  
  Device initialization seems to behave much more smoothly now; at least on
  my hardware, the "error Parameter" doesn't happen anymore, and of course
  anything depending on outbound Control transfers will now work correctly.
  I now get much better speeds from usb_disk, but I still see usb_hid stalls
  after this patch.

7b53b3c2e490: XHCI: Don't compute the error code twice.
  
  No functional change.

da8c1a9a403a: USB: Don't loop endlessly waiting for a physical buffer.
  
  This is used quite a lot in critical transfer paths, so we don't
  want to lock things up if no buffers are available for whatever reason.
  Wait 2 seconds, and if we didn't get anything by then, return B_NO_MEMORY.
  
  Possibly fixes or helps with certain USB-related lockups.

                              [ Augustin Cavalier <waddlesplash@xxxxxxxxx> ]

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

2 files changed, 45 insertions(+), 35 deletions(-)
.../bus_managers/usb/PhysicalMemoryAllocator.cpp |  5 +-
src/add-ons/kernel/busses/usb/xhci.cpp           | 75 +++++++++++---------

############################################################################

Commit:      c409803d6f4a0577547c05938c6fecd1a43aec4a
URL:         https://git.haiku-os.org/haiku/commit/?id=c409803d6f4a
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Fri Feb 22 18:07:15 2019 UTC

XHCI: Refactoring and fixes to SubmitControlRequest.

 * Rearrange some basic setup to be more towards the top of the function,
   so we have less things to tear down upon failures.
 * Don't double-initialize qwtrb0 of the Setup Stage (no functional change.)
 * Rework Data Stage initialization considerably:
   - TD_SIZE refers to the number of remaining TRBs in this TD. As we only
     use 1 TRB for the Data Stage TD at present, this should be 0, not 1.
   - Actually copy data for outbound transfers. (This code does get hit,
     so I'm not sure how it wasn't a problem previously.)
 * Initialize the first quadbit of the Status Stage. (Potentially a
   functional change.)
 * Set the TRB_3_DIR bit on the Status Stage correctly as per the spec.
   (See inline comment.)

Device initialization seems to behave much more smoothly now; at least on
my hardware, the "error Parameter" doesn't happen anymore, and of course
anything depending on outbound Control transfers will now work correctly.
I now get much better speeds from usb_disk, but I still see usb_hid stalls
after this patch.

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

diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp 
b/src/add-ons/kernel/busses/usb/xhci.cpp
index 3831098c57..ad8f0014f5 100644
--- a/src/add-ons/kernel/busses/usb/xhci.cpp
+++ b/src/add-ons/kernel/busses/usb/xhci.cpp
@@ -618,62 +618,69 @@ XHCI::SubmitControlRequest(Transfer *transfer)
        usb_request_data *requestData = transfer->RequestData();
        bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) 
!= 0;
 
+       xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie();
+       uint8 id = XHCI_ENDPOINT_ID(pipe);
+       if (id >= XHCI_MAX_ENDPOINTS) {
+               TRACE_ERROR("Invalid Endpoint");
+               return B_BAD_VALUE;
+       }
+       status_t status = transfer->InitKernelAccess();
+       if (status != B_OK)
+               return status;
+
        TRACE("SubmitControlRequest() length %d\n", requestData->Length);
 
-       xhci_td *setupDescriptor = CreateDescriptor(requestData->Length);
+       xhci_td *descriptor = CreateDescriptor(requestData->Length);
+       descriptor->transfer = transfer;
 
-       // set SetupStage
+       // Setup Stage
        uint8 index = 0;
-       setupDescriptor->trbs[index].qwtrb0 = 0;
-       setupDescriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0) | TRB_2_BYTES(8);
-       setupDescriptor->trbs[index].dwtrb3
+       memcpy(&descriptor->trbs[index].qwtrb0, requestData,
+               sizeof(usb_request_data));
+       descriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0) | TRB_2_BYTES(8);
+       descriptor->trbs[index].dwtrb3
                = B_HOST_TO_LENDIAN_INT32(TRB_3_TYPE(TRB_TYPE_SETUP_STAGE)
                        | TRB_3_IDT_BIT | TRB_3_CYCLE_BIT);
        if (requestData->Length > 0) {
-               setupDescriptor->trbs[index].dwtrb3 |= B_HOST_TO_LENDIAN_INT32(
+               descriptor->trbs[index].dwtrb3 |= B_HOST_TO_LENDIAN_INT32(
                        directionIn ? TRB_3_TRT_IN : TRB_3_TRT_OUT);
        }
-       memcpy(&setupDescriptor->trbs[index].qwtrb0, requestData,
-               sizeof(usb_request_data));
 
        index++;
 
+       // Data Stage (if any)
        if (requestData->Length > 0) {
-               // set DataStage if any
-               setupDescriptor->trbs[index].qwtrb0 = 
setupDescriptor->buffer_phy[0];
-               setupDescriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0)
+               descriptor->trbs[index].qwtrb0 = descriptor->buffer_phy[0];
+               descriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0)
                        | TRB_2_BYTES(requestData->Length)
-                       | TRB_2_TD_SIZE(transfer->VectorCount());
-               setupDescriptor->trbs[index].dwtrb3 = B_HOST_TO_LENDIAN_INT32(
+                       | TRB_2_TD_SIZE(0);
+               descriptor->trbs[index].dwtrb3 = B_HOST_TO_LENDIAN_INT32(
                        TRB_3_TYPE(TRB_TYPE_DATA_STAGE)
                                | (directionIn ? (TRB_3_DIR_IN | TRB_3_ISP_BIT) 
: 0)
                                | TRB_3_CYCLE_BIT);
 
-               // TODO copy data for out transfers
+               if (!directionIn) {
+                       transfer->PrepareKernelAccess();
+                       memcpy(descriptor->buffer_log[0],
+                               (uint8 *)transfer->Vector()[0].iov_base, 
requestData->Length);
+               }
+
                index++;
        }
 
-       // set StatusStage
-       setupDescriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0);
-       setupDescriptor->trbs[index].dwtrb3 = B_HOST_TO_LENDIAN_INT32(
+       // Status Stage
+       descriptor->trbs[index].qwtrb0 = 0;
+       descriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0);
+       descriptor->trbs[index].dwtrb3 = B_HOST_TO_LENDIAN_INT32(
                TRB_3_TYPE(TRB_TYPE_STATUS_STAGE)
-                       | ((directionIn && requestData->Length > 0) ? 0 : 
TRB_3_DIR_IN)
-                       | TRB_3_IOC_BIT | TRB_3_CYCLE_BIT);
+                       | TRB_3_DIR_IN | TRB_3_IOC_BIT | TRB_3_CYCLE_BIT);
+               // Note that TRB_3_DIR on a TRB_TYPE_STATUS_STAGE does not 
refer to the
+               // Data Stage, but rather to which way the status notification 
should
+               // go, i.e. device to host, or host to device. (XHCI 1.1 § 
4.11.2.2 p205.)
 
-       setupDescriptor->trb_count = index + 1;
+       descriptor->trb_count = index + 1;
 
-       xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie();
-       uint8 id = XHCI_ENDPOINT_ID(pipe);
-       if (id >= XHCI_MAX_ENDPOINTS) {
-               TRACE_ERROR("Invalid Endpoint");
-               return B_BAD_VALUE;
-       }
-       status_t status = transfer->InitKernelAccess();
-       if (status != B_OK)
-               return status;
-
-       setupDescriptor->transfer = transfer;
-       status = _LinkDescriptorForPipe(setupDescriptor, endpoint);
+       status = _LinkDescriptorForPipe(descriptor, endpoint);
        if (status != B_OK)
                return status;
        TRACE("SubmitControlRequest() request linked\n");

############################################################################

Commit:      7b53b3c2e49005cd02ca61c1f39d340267d52760
URL:         https://git.haiku-os.org/haiku/commit/?id=7b53b3c2e490
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Fri Feb 22 18:26:10 2019 UTC

XHCI: Don't compute the error code twice.

No functional change.

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

diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp 
b/src/add-ons/kernel/busses/usb/xhci.cpp
index ad8f0014f5..efbd063dcb 100644
--- a/src/add-ons/kernel/busses/usb/xhci.cpp
+++ b/src/add-ons/kernel/busses/usb/xhci.cpp
@@ -2153,9 +2153,9 @@ XHCI::DoCommand(xhci_trb* trb)
        uint32 completionCode = TRB_2_COMP_CODE_GET(fCmdResult[0]);
        TRACE("Command Complete. Result: %" B_PRId32 "\n", completionCode);
        if (completionCode != COMP_SUCCESS) {
-               uint32 errorCode = TRB_2_COMP_CODE_GET(fCmdResult[0]);
                TRACE_ERROR("unsuccessful command %" B_PRId32 ", error %s (%" 
B_PRId32 ")\n",
-                       TRB_3_TYPE_GET(trb->dwtrb3), 
xhci_error_string(errorCode), errorCode);
+                       TRB_3_TYPE_GET(trb->dwtrb3), 
xhci_error_string(completionCode),
+                       completionCode);
                status = B_IO_ERROR;
        }
 

############################################################################

Revision:    hrev52918
Commit:      da8c1a9a403aed0fa06beeeb100c3c0c50b8362c
URL:         https://git.haiku-os.org/haiku/commit/?id=da8c1a9a403a
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Fri Feb 22 18:29:40 2019 UTC

USB: Don't loop endlessly waiting for a physical buffer.

This is used quite a lot in critical transfer paths, so we don't
want to lock things up if no buffers are available for whatever reason.
Wait 2 seconds, and if we didn't get anything by then, return B_NO_MEMORY.

Possibly fixes or helps with certain USB-related lockups.

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

diff --git a/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.cpp 
b/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.cpp
index 2bc3db2402..a1f09e0167 100644
--- a/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.cpp
+++ b/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.cpp
@@ -222,7 +222,10 @@ PhysicalMemoryAllocator::Allocate(size_t size, void 
**logicalAddress,
                TRACE_ERROR(("PMA: found no free slot to store %ld bytes, 
waiting\n",
                        size));
 
-               entry.Wait();
+               if (entry.Wait(B_RELATIVE_TIMEOUT, 2 * 1000 * 1000) == 
B_TIMED_OUT) {
+                       TRACE_ERROR(("PMA: timed out waiting for a free slot, 
giving up\n"));
+                       break;
+               }
 
                if (!_Lock())
                        return B_ERROR;


Other related posts:

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