Ticket #13343: 0001-xhci-Transfer-complete-semaphore-was-not-being-relea.patch

File 0001-xhci-Transfer-complete-semaphore-was-not-being-relea.patch, 6.0 KB (added by GregCrain, 7 years ago)

A patch for xhci driver, but not directly impacting QEMU.

  • src/add-ons/kernel/busses/usb/xhci.cpp

    From 78bc8425c0c4162848aa056708b79900e332f43a Mon Sep 17 00:00:00 2001
    From: Greg Crain <gcrain70@gmail.com>
    Date: Wed, 8 Nov 2017 08:12:08 -0500
    Subject: [PATCH] xhci: Transfer complete semaphore was not being released.
    
    The 'fFinishTransfersSem' semaphore is timing out and not being
    released after a successful transfer due to an off by 1 offset.
    Quad word in command transfer was not cleared and sometimes
    contained garbage.
    Add some additional debugging output.
    ---
     src/add-ons/kernel/busses/usb/xhci.cpp        | 34 ++++++++++++++++-----------
     src/add-ons/kernel/busses/usb/xhci_hardware.h |  4 ++++
     2 files changed, 24 insertions(+), 14 deletions(-)
    
    diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp b/src/add-ons/kernel/busses/usb/xhci.cpp
    index 6009621..605c207 100644
    a b  
    11/*
    2  * Copyright 2006-2014, Haiku Inc. All rights reserved.
     2 * Copyright 2006-2017, Haiku Inc. All rights reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Some code borrowed from the Haiku EHCI driver
    XHCI::Start()  
    517517    dmaAddress += sizeof(xhci_erst_element) + XHCI_MAX_EVENTS
    518518        * sizeof(xhci_trb);
    519519    TRACE("setting CRCR addr = 0x%" B_PRIxPHYSADDR "\n", dmaAddress);
     520    //Make sure Command Ring is stopped
     521    WriteOpReg(XHCI_CRCR_LO, CRCR_CA );
    520522    WriteOpReg(XHCI_CRCR_LO, (uint32)dmaAddress | CRCR_RCS);
    521523    WriteOpReg(XHCI_CRCR_HI, /*(uint32)(dmaAddress >> 32)*/0);
    522524    // link trb
    XHCI::Start()  
    566568    SetRootHub(fRootHub);
    567569
    568570    TRACE_ALWAYS("successfully started the controller\n");
    569 #ifdef TRACE_USB
     571//#ifdef TRACE_USB
     572#if 1
    570573    TRACE("No-Op test...\n");
    571574    status_t noopResult = Noop();
    572     TRACE("No-Op %ssuccessful\n", noopResult < B_OK ? "un" : "");
     575    TRACE_ALWAYS("No-Op %ssuccessful\n", noopResult < B_OK ? "un" : "");
    573576#endif
    574577
    575578    //DumpRing(fCmdRing, (XHCI_MAX_COMMANDS - 1));
    XHCI::SubmitControlRequest(Transfer *transfer)  
    637640    }
    638641
    639642    // set StatusStage
     643    setupDescriptor->trbs[index].qwtrb0 = 0;
    640644    setupDescriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0);
    641645    setupDescriptor->trbs[index].dwtrb3 = B_HOST_TO_LENDIAN_INT32(
    642646        TRB_3_TYPE(TRB_TYPE_STATUS_STAGE)
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    10951099
    10961100    uint8 slot = XHCI_MAX_SLOTS;
    10971101    if (EnableSlot(&slot) != B_OK) {
    1098         TRACE_ERROR("AllocateDevice() failed enable slot\n");
     1102        TRACE_ERROR("AllocateDevice() failed enable slot %d\n",slot);
    10991103        return NULL;
     1104    } else {
     1105        TRACE_ALWAYS("EnableSlot %d\n",slot);
    11001106    }
    11011107
    11021108    if (slot == 0 || slot > fSlotCount) {
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    13101316        return NULL;
    13111317    }
    13121318
    1313     TRACE("device_class: %d device_subclass %d device_protocol %d\n",
     1319    TRACE_ALWAYS("device_class: %d device_subclass %d device_protocol %d\n",
    13141320        deviceDescriptor.device_class, deviceDescriptor.device_subclass,
    13151321        deviceDescriptor.device_protocol);
    13161322
    XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint)  
    15251531    TRACE("_LinkDescriptorForPipe\n");
    15261532    MutexLocker endpointLocker(endpoint->lock);
    15271533    if (endpoint->used >= XHCI_MAX_TRANSFERS) {
    1528         TRACE_ERROR("_LinkDescriptorForPipe max transfers count exceeded\n");
     1534        TRACE_ERROR("_LinkDescriptorForPipe max transfers count exceeded %d\n",endpoint->used );
     1535        //Seem to have a problem with interupts not occuring when this happens
     1536        //and endpoints are not being freed.
    15291537        return B_BAD_VALUE;
    15301538    }
    15311539
    XHCI::SetPortFeature(uint8 index, uint16 feature)  
    18121820    default:
    18131821        return B_BAD_VALUE;
    18141822    }
    1815     ReadOpReg(portRegister);
    18161823    return B_OK;
    18171824}
    18181825
    XHCI::ClearPortFeature(uint8 index, uint16 feature)  
    18611868        return B_BAD_VALUE;
    18621869    }
    18631870
    1864     ReadOpReg(portRegister);
    18651871    return B_OK;
    18661872}
    18671873
    XHCI::ControllerReset()  
    18931899    while (ReadOpReg(XHCI_CMD) & CMD_HCRST) {
    18941900        snooze(1000);
    18951901        if (tries-- < 0) {
    1896             TRACE("ControllerReset() failed CMD_HCRST\n");
     1902            TRACE_ERROR("ControllerReset() failed CMD_HCRST\n");
    18971903            return B_ERROR;
    18981904        }
    18991905    }
    XHCI::ControllerReset()  
    19021908    while (ReadOpReg(XHCI_STS) & STS_CNR) {
    19031909        snooze(1000);
    19041910        if (tries-- < 0) {
    1905             TRACE("ControllerReset() failed STS_CNR\n");
     1911            TRACE_ERROR("ControllerReset() failed STS_CNR\n");
    19061912            return B_ERROR;
    19071913        }
    19081914    }
    XHCI::HandleTransferComplete(xhci_trb* trb)  
    20512057            int64 offset = source - td_chain->this_phy;
    20522058            TRACE("HandleTransferComplete td %p offset %" B_PRId64 " %"
    20532059                B_PRIxADDR "\n", td_chain, offset, source);
    2054             offset = offset / sizeof(xhci_trb);
     2060            offset = offset / sizeof(xhci_trb) +1;
    20552061            if (offset <= td_chain->trb_count && offset >= 0) {
    20562062                TRACE("HandleTransferComplete td %p trb %" B_PRId64 " found "
    20572063                    "\n", td_chain, offset);
    XHCI::DoCommand(xhci_trb* trb)  
    21292135
    21302136    trb->dwtrb2 = fCmdResult[0];
    21312137    trb->dwtrb3 = fCmdResult[1];
    2132     TRACE("Storing trb 0x%08" B_PRIx32 " 0x%08" B_PRIx32 "\n", trb->dwtrb2,
     2138    TRACE("Storing command trb 0x%08" B_PRIx32 " 0x%08" B_PRIx32 "\n", trb->dwtrb2,
    21332139        trb->dwtrb3);
    21342140
    21352141    Unlock();
    XHCI::EnableSlot(uint8* slot)  
    21712177status_t
    21722178XHCI::DisableSlot(uint8 slot)
    21732179{
    2174     TRACE("Disable Slot\n");
     2180    TRACE("Disable Slot %d\n", slot);
    21752181    xhci_trb trb;
    21762182    trb.qwtrb0 = 0;
    21772183    trb.dwtrb2 = 0;
    XHCI::DisableSlot(uint8 slot)  
    21842190status_t
    21852191XHCI::SetAddress(uint64 inputContext, bool bsr, uint8 slot)
    21862192{
    2187     TRACE("Set Address\n");
     2193    TRACE_ALWAYS("Set Address slot %d 0x%016" B_PRIx64 "\n", slot, inputContext);
    21882194    xhci_trb trb;
    21892195    trb.qwtrb0 = inputContext;
    21902196    trb.dwtrb2 = 0;
  • src/add-ons/kernel/busses/usb/xhci_hardware.h

    diff --git a/src/add-ons/kernel/busses/usb/xhci_hardware.h b/src/add-ons/kernel/busses/usb/xhci_hardware.h
    index a9619d9..bfe9356 100644
    a b  
    9191#define XHCI_CRCR_LO        0x18
    9292#define XHCI_CRCR_HI        0x1C
    9393#define CRCR_RCS            (1<<0)
     94#define CRCR_CS             (1<<1)
     95#define CRCR_CA             (1<<2)
     96#define CRCR_CRR            (1<<3)
     97
    9498// Section 5.4.6
    9599#define XHCI_DCBAAP_LO      0x30
    96100#define XHCI_DCBAAP_HI      0x34