Ticket #8954: 0001-XHCI-Fixes.patch

File 0001-XHCI-Fixes.patch, 25.2 KB (added by akshay1994, 10 years ago)

Updates Updates!!

  • src/add-ons/kernel/bus_managers/usb/Hub.cpp

    From fa65d07bccd74aa39413a44ec3aa611e96af642c Mon Sep 17 00:00:00 2001
    From: Akshay Jaggi <akshay1994.leo@gmail.com>
    Date: Sat, 28 Jun 2014 17:03:12 +0000
    Subject: [PATCH] XHCI Fixes -Add Hub Support -Prevent Page Fault in
     FinishThread -Setting fCapabilityLength -Correction in BIOS ownership code
     -Fix Context Errors in _InsertEndpointForPipe -Updated constants according to
     latest Specification (v1.1) -Fix SMI code -Fix Memory/Device-Slot leaks -Fix
     Allocate Area for TRBs -Fix for Intel Lynx Point and Panther Point Chipsets
    
    ---
     src/add-ons/kernel/bus_managers/usb/Hub.cpp       |   4 +-
     src/add-ons/kernel/bus_managers/usb/Stack.cpp     |   2 +-
     src/add-ons/kernel/bus_managers/usb/usb_private.h |   3 +-
     src/add-ons/kernel/busses/usb/xhci.cpp            | 297 ++++++++++++++++++----
     src/add-ons/kernel/busses/usb/xhci.h              |   2 +
     src/add-ons/kernel/busses/usb/xhci_hardware.h     |  22 +-
     6 files changed, 265 insertions(+), 65 deletions(-)
    
    diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp
    index a1f2d6b..3190018 100644
    a b  
    1717
    1818Hub::Hub(Object *parent, int8 hubAddress, uint8 hubPort,
    1919    usb_device_descriptor &desc, int8 deviceAddress, usb_speed speed,
    20     bool isRootHub)
     20    bool isRootHub, void *controllerCookie)
    2121    :   Device(parent, hubAddress, hubPort, desc, deviceAddress, speed,
    22             isRootHub),
     22            isRootHub, controllerCookie),
    2323        fInterruptPipe(NULL)
    2424{
    2525    TRACE("creating hub\n");
  • src/add-ons/kernel/bus_managers/usb/Stack.cpp

    diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp b/src/add-ons/kernel/bus_managers/usb/Stack.cpp
    index 04ad075..7a562bc 100644
    a b Stack::Stack()  
    6161    // be enumerated as the last item. As this does not apply to us we have to
    6262    // ensure ordering using another method.
    6363    const char *moduleNames[] = {
     64        "busses/usb/xhci",
    6465        "busses/usb/uhci",
    6566        "busses/usb/ohci",
    6667        "busses/usb/ehci",
    67         "busses/usb/xhci",
    6868        NULL
    6969    };
    7070
  • src/add-ons/kernel/bus_managers/usb/usb_private.h

    diff --git a/src/add-ons/kernel/bus_managers/usb/usb_private.h b/src/add-ons/kernel/bus_managers/usb/usb_private.h
    index 13c189b..8ca6b84 100644
    a b public:  
    579579                                            uint8 hubPort,
    580580                                            usb_device_descriptor &desc,
    581581                                            int8 deviceAddress,
    582                                             usb_speed speed, bool isRootHub);
     582                                            usb_speed speed, bool isRootHub,
     583                                            void *controllerCookie = NULL);
    583584virtual                                 ~Hub();
    584585
    585586virtual status_t                        Changed(change_item **changeList,
  • src/add-ons/kernel/busses/usb/xhci.cpp

    diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp b/src/add-ons/kernel/busses/usb/xhci.cpp
    index f53f721..2d1ca46 100644
    a b  
    88 *      Michael Lotz <mmlr@mlotz.ch>
    99 *      Jian Chiang <j.jian.chiang@gmail.com>
    1010 *      Jérôme Duval <jerome.duval@gmail.com>
     11 *      Akshay Jaggi <akshay1994.leo@gmail.com>
    1112 */
    1213
    1314
    XHCI::XHCI(pci_info *info, Stack *stack)  
    174175
    175176    uint32 hciCapLength = ReadCapReg32(XHCI_HCI_CAPLENGTH);
    176177    fCapabilityRegisters += offset;
     178    fCapabilityLength = HCI_CAPLENGTH(hciCapLength);
    177179    TRACE("mapped capability length: 0x%" B_PRIx32 "\n", fCapabilityLength);
    178     fOperationalRegisters = fCapabilityRegisters + HCI_CAPLENGTH(hciCapLength);
     180    fOperationalRegisters = fCapabilityRegisters + fCapabilityLength;
    179181    fRuntimeRegisters = fCapabilityRegisters + ReadCapReg32(XHCI_RTSOFF);
    180182    fDoorbellRegisters = fCapabilityRegisters + ReadCapReg32(XHCI_DBOFF);
    181183    TRACE("mapped capability registers: 0x%p\n", fCapabilityRegisters);
    XHCI::XHCI(pci_info *info, Stack *stack)  
    199201        eec = ReadCapReg32(eecp);
    200202        if (XECP_ID(eec) != XHCI_LEGSUP_CAPID)
    201203            continue;
    202     }
    203     TRACE("eecp register: 0x%04" B_PRIx32 "\n", eecp);
    204     if (eec & XHCI_LEGSUP_BIOSOWNED) {
    205         TRACE_ALWAYS("the host controller is bios owned, claiming"
    206             " ownership\n");
    207         WriteCapReg32(eecp, eec | XHCI_LEGSUP_OSOWNED);
    208 
    209         for (int32 i = 0; i < 20; i++) {
    210             eec = ReadCapReg32(eecp);
    211 
    212             if ((eec & XHCI_LEGSUP_BIOSOWNED) == 0)
    213                 break;
    214 
    215             TRACE_ALWAYS("controller is still bios owned, waiting\n");
    216             snooze(50000);
    217         }
    218 
     204               
     205        TRACE("eecp register: 0x%08" B_PRIx32 "\n", eecp);
    219206        if (eec & XHCI_LEGSUP_BIOSOWNED) {
    220             TRACE_ERROR("bios won't give up control over the host "
    221                 "controller (ignoring)\n");
    222         } else if (eec & XHCI_LEGSUP_OSOWNED) {
    223             TRACE_ALWAYS("successfully took ownership of the host "
    224                 "controller\n");
     207            TRACE_ALWAYS("the host controller is bios owned, claiming"
     208                " ownership\n");
     209            WriteCapReg32(eecp, eec | XHCI_LEGSUP_OSOWNED);
     210   
     211            for (int32 i = 0; i < 20; i++) {
     212                eec = ReadCapReg32(eecp);
     213   
     214                if ((eec & XHCI_LEGSUP_BIOSOWNED) == 0)
     215                    break;
     216   
     217                TRACE_ALWAYS("controller is still bios owned, waiting\n");
     218                snooze(50000);
     219            }
     220   
     221            if (eec & XHCI_LEGSUP_BIOSOWNED) {
     222                TRACE_ERROR("bios won't give up control over the host "
     223                    "controller (ignoring)\n");
     224            } else if (eec & XHCI_LEGSUP_OSOWNED) {
     225                TRACE_ALWAYS("successfully took ownership of the host "
     226                    "controller\n");
     227            }
     228   
     229            // Force off the BIOS owned flag, and clear all SMIs. Some BIOSes
     230            // do indicate a successful handover but do not remove their SMIs
     231            // and then freeze the system when interrupts are generated.
     232            WriteCapReg32(eecp, eec & ~XHCI_LEGSUP_BIOSOWNED);
    225233        }
    226 
    227         // Force off the BIOS owned flag, and clear all SMIs. Some BIOSes
    228         // do indicate a successful handover but do not remove their SMIs
    229         // and then freeze the system when interrupts are generated.
    230         WriteCapReg32(eecp, eec & ~XHCI_LEGSUP_BIOSOWNED);
     234        break;
     235    }
     236    uint32 legctlsts = ReadCapReg32(eecp + XHCI_LEGCTLSTS);
     237    legctlsts &= XHCI_LEGCTLSTS_DISABLE_SMI;
     238    legctlsts |= XHCI_LEGCTLSTS_EVENTS_SMI;
     239    WriteCapReg32(eecp + XHCI_LEGCTLSTS, legctlsts);
     240
     241    // On Intel's Panther Point and Lynx Point Chipset taking ownership
     242    // of EHCI owned ports, is what we do here.
     243    if(fPCIInfo->vendor_id == PCI_VENDOR_ID_INTEL
     244        && (fPCIInfo->device_id == PCI_DEVICE_ID_INTEL_PANTHER_POINT_XHCI
     245            || fPCIInfo->device_id == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI
     246            || fPCIInfo->device_id == PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI)) {
     247       
     248        TRACE("Intel xHC Controller\n");
     249        TRACE("Looking for EHCI owned ports\n");
     250       
     251        uint32 ports = sPCIModule->read_pci_config(fPCIInfo->bus,
     252            fPCIInfo->device, fPCIInfo->function, XHCI_INTEL_USB3PRM, 4);
     253       
     254        TRACE("Superspeed Ports: 0x%"B_PRIx32"\n", ports);
     255       
     256        sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device,
     257            fPCIInfo->function, XHCI_INTEL_USB3_PSSEN, 4, ports);
     258       
     259        ports = sPCIModule->read_pci_config(fPCIInfo->bus,
     260            fPCIInfo->device, fPCIInfo->function, XHCI_INTEL_USB3_PSSEN, 4);
     261       
     262        TRACE("Superspeed ports now under XHCI : 0x%"B_PRIx32"\n", ports);
     263           
     264        ports = sPCIModule->read_pci_config(fPCIInfo->bus,
     265            fPCIInfo->device, fPCIInfo->function, XHCI_INTEL_USB2PRM, 4);
     266           
     267        TRACE("USB 2.0 Ports : 0x%"B_PRIx32"\n", ports);
     268           
     269        sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device,
     270            fPCIInfo->function, XHCI_INTEL_XUSB2PR, 4, ports);
     271           
     272        ports = sPCIModule->read_pci_config(fPCIInfo->bus,
     273            fPCIInfo->device, fPCIInfo->function, XHCI_INTEL_XUSB2PR, 4);
     274           
     275        TRACE("USB 2.0 ports now under XHCI: 0x%"B_PRIx32"\n", ports);
    231276    }
    232     WriteCapReg32(eecp + XHCI_LEGCTLSTS, XHCI_LEGCTLSTS_DISABLE_SMI);
    233277
    234278    // halt the host controller
    235279    if (ControllerHalt() < B_OK) {
    XHCI::Start()  
    337381    }
    338382
    339383    // read port count from capability register
    340     uint32 capabilities = ReadCapReg32(XHCI_HCSPARAMS1);
    341 
     384    uint32 capabilities = ReadCapReg32(XHCI_HCSPARAMS1);   
    342385    fPortCount = HCS_MAX_PORTS(capabilities);
    343386    if (fPortCount == 0) {
    344387        TRACE_ERROR("Invalid number of ports: %u\n", fPortCount);
    XHCI::SubmitControlRequest(Transfer *transfer)  
    574617    xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie();
    575618    uint8 id = XHCI_ENDPOINT_ID(pipe);
    576619    if (id >= XHCI_MAX_ENDPOINTS)
     620    {
     621        TRACE_ERROR("Invalid Endpoint");
    577622        return B_BAD_VALUE;
     623    }
    578624    setupDescriptor->transfer = transfer;
     625    transfer->InitKernelAccess();
    579626    _LinkDescriptorForPipe(setupDescriptor, endpoint);
    580627
    581628    TRACE("SubmitControlRequest() request linked\n");
    582629
     630    TRACE("Endpoint Status 0x%"B_PRIx32" 0x%"B_PRIx32" 0x%"B_PRIx64"\n",
     631        endpoint->device->device_ctx->endpoints[id-1].dwendpoint0,
     632        endpoint->device->device_ctx->endpoints[id-1].dwendpoint1,
     633        endpoint->device->device_ctx->endpoints[id-1].qwendpoint2
     634        );
    583635    Ring(endpoint->device->slot, id);
    584 
     636    TRACE("Endpoint Status 0x%"B_PRIx32" 0x%"B_PRIx32" 0x%"B_PRIx64"\n",
     637        endpoint->device->device_ctx->endpoints[id-1].dwendpoint0,
     638        endpoint->device->device_ctx->endpoints[id-1].dwendpoint1,
     639        endpoint->device->device_ctx->endpoints[id-1].qwendpoint2
     640        );
    585641    return B_OK;
    586642}
    587643
    XHCI::SubmitNormalRequest(Transfer *transfer)  
    625681
    626682    xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie();
    627683    descriptor->transfer = transfer;
     684    transfer->InitKernelAccess();
    628685    _LinkDescriptorForPipe(descriptor, endpoint);
    629686
    630687    TRACE("SubmitNormalRequest() request linked\n");
    631688
     689    TRACE("Endpoint Status 0x%"B_PRIx32" 0x%"B_PRIx32" 0x%"B_PRIx64"\n",
     690        (endpoint->device->device_ctx->endpoints[id-1]).dwendpoint0,
     691        endpoint->device->device_ctx->endpoints[id-1].dwendpoint1,
     692        endpoint->device->device_ctx->endpoints[id-1].qwendpoint2
     693        );
    632694    Ring(endpoint->device->slot, id);
     695    TRACE("Endpoint Status 0x%"B_PRIx32" 0x%"B_PRIx32" 0x%"B_PRIx64"\n",
     696        endpoint->device->device_ctx->endpoints[id-1].dwendpoint0,
     697        endpoint->device->device_ctx->endpoints[id-1].dwendpoint1,
     698        endpoint->device->device_ctx->endpoints[id-1].qwendpoint2
     699        );
    633700
    634701    return B_OK;
    635702}
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    9941061        "XHCI input context");
    9951062    if (device->input_ctx_area < B_OK) {
    9961063        TRACE_ERROR("unable to create a input context area\n");
     1064        device->state = XHCI_STATE_DISABLED;
    9971065        return NULL;
    9981066    }
    9991067
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    10031071
    10041072    uint32 route = 0;
    10051073    uint8 routePort = hubPort;
    1006     uint8 rhPort = 0;
     1074    uint8 rhPort = hubPort;
    10071075    for (Device *hubDevice = parent; hubDevice != RootObject();
    10081076        hubDevice = (Device *)hubDevice->Parent()) {
    10091077
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    10201088    }
    10211089
    10221090    device->input_ctx->slot.dwslot0 = SLOT_0_NUM_ENTRIES(1) | SLOT_0_ROUTE(route);
    1023     //device->input_ctx->slot.dwslot0 =
    1024     //  SLOT_0_NUM_ENTRIES(XHCI_MAX_ENDPOINTS - 1) | SLOT_0_ROUTE(route);
    10251091
    10261092    // add the speed
    10271093    switch (speed) {
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    10591125        "XHCI device context");
    10601126    if (device->device_ctx_area < B_OK) {
    10611127        TRACE_ERROR("unable to create a device context area\n");
     1128        device->state = XHCI_STATE_DISABLED;       
    10621129        delete_area(device->input_ctx_area);
    10631130        return NULL;
    10641131    }
    10651132    memset(device->device_ctx, 0, sizeof(*device->device_ctx));
    10661133
    10671134    device->trb_area = fStack->AllocateArea((void **)&device->trbs,
    1068         &device->trb_addr, sizeof(*device->trbs), "XHCI endpoint trbs");
     1135        &device->trb_addr, sizeof(*device->trbs)*(XHCI_MAX_ENDPOINTS-1)*(XHCI_MAX_TRANSFERS), "XHCI endpoint trbs");
    10691136    if (device->trb_area < B_OK) {
    10701137        TRACE_ERROR("unable to create a device trbs area\n");
     1138        device->state = XHCI_STATE_DISABLED;
    10711139        delete_area(device->input_ctx_area);
    10721140        delete_area(device->device_ctx_area);
    10731141        return NULL;
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    11021170    if (ConfigureEndpoint(slot, 0, 4, device->trb_addr, 0, 1, 1, 0,
    11031171        maxPacketSize, maxPacketSize, speed) != B_OK) {
    11041172        TRACE_ERROR("unable to configure default control endpoint\n");
     1173        device->state = XHCI_STATE_DISABLED;
     1174        delete_area(device->input_ctx_area);
     1175        delete_area(device->device_ctx_area);
     1176        delete_area(device->trb_area);
    11051177        return NULL;
    11061178    }
    11071179
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    11161188    // device should get to addressed state (bsr = 0)
    11171189    if (SetAddress(device->input_ctx_addr, false, slot) != B_OK) {
    11181190        TRACE_ERROR("unable to set address\n");
     1191        device->state = XHCI_STATE_DISABLED;
     1192        delete_area(device->input_ctx_area);
     1193        delete_area(device->device_ctx_area);
     1194        delete_area(device->trb_area);
    11191195        return NULL;
    11201196    }
    11211197
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    11541230
    11551231    if (actualLength != 8) {
    11561232        TRACE_ERROR("error while getting the device descriptor\n");
     1233        device->state = XHCI_STATE_DISABLED;
     1234        delete_area(device->input_ctx_area);
     1235        delete_area(device->device_ctx_area);
     1236        delete_area(device->trb_area);
    11571237        return NULL;
    11581238    }
    11591239
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    11611241        deviceDescriptor.device_class, deviceDescriptor.device_subclass,
    11621242        deviceDescriptor.device_protocol);
    11631243
     1244    if(deviceDescriptor.device_class==0x09)
     1245    {
     1246        TRACE("creating new HUB\n");
     1247        TRACE("getting the hub descriptor\n");
     1248        size_t actualLength = 0;
     1249        usb_hub_descriptor hubDescriptor;
     1250        pipe.SendRequest(
     1251            USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD,       // type
     1252            USB_REQUEST_GET_DESCRIPTOR,                         // request
     1253            USB_DESCRIPTOR_HUB << 8,                            // value
     1254            0,                                                  // index
     1255            sizeof(usb_hub_descriptor),                         // length
     1256            (void *)&hubDescriptor,                             // buffer
     1257            sizeof(usb_hub_descriptor),                         // buffer length
     1258            &actualLength);
     1259       
     1260        if(actualLength!=sizeof(usb_hub_descriptor))
     1261        {
     1262            TRACE_ERROR("error while getting the hub descriptor\n");
     1263            device->state = XHCI_STATE_DISABLED;
     1264            delete_area(device->input_ctx_area);
     1265            delete_area(device->device_ctx_area);
     1266            delete_area(device->trb_area);
     1267            return NULL;
     1268        }
     1269       
     1270        device->input_ctx->slot.dwslot0 |= SLOT_0_HUB_BIT;
     1271        device->input_ctx->slot.dwslot1 |= SLOT_1_NUM_PORTS(hubDescriptor.num_ports);
     1272        if(speed == USB_SPEED_HIGHSPEED)
     1273        {
     1274            device->input_ctx->slot.dwslot2 |= SLOT_2_TT_TIME(HUB_TTT_GET(hubDescriptor.characteristics));
     1275        }
     1276       
     1277        Hub *hub = new(std::nothrow) Hub(parent, hubAddress, hubPort,
     1278            deviceDescriptor, device->address + 1, speed, false, device);
     1279        if(!hub)
     1280        {
     1281            TRACE_ERROR("no memory to allocate hub\n");
     1282            device->state = XHCI_STATE_DISABLED;
     1283            delete_area(device->input_ctx_area);
     1284            delete_area(device->device_ctx_area);
     1285            delete_area(device->trb_area);
     1286            return NULL;
     1287        }
     1288        fPortSlots[hubPort] = slot;
     1289        TRACE("AllocateDevice() port %d slot %d\n", hubPort, slot);
     1290        return (Device *)hub;
     1291    }
    11641292    TRACE("creating new device\n");
    11651293    Device *deviceObject = new(std::nothrow) Device(parent, hubAddress, hubPort,
    11661294        deviceDescriptor, device->address + 1, speed, false, device);
    11671295    if (!deviceObject) {
    11681296        TRACE_ERROR("no memory to allocate device\n");
     1297        device->state = XHCI_STATE_DISABLED;
     1298        delete_area(device->input_ctx_area);
     1299        delete_area(device->device_ctx_area);
     1300        delete_area(device->trb_area);
    11691301        return NULL;
    11701302    }
    11711303    fPortSlots[hubPort] = slot;
    XHCI::FreeDevice(Device *device)  
    11931325status_t
    11941326XHCI::_InsertEndpointForPipe(Pipe *pipe)
    11951327{
     1328    TRACE("_InsertEndpointForPipe endpoint address %"B_PRId8"\n", pipe->EndpointAddress());
    11961329    if (pipe->ControllerCookie() != NULL
    11971330        || pipe->Parent()->Type() != USB_OBJECT_DEVICE) {
    11981331        // default pipe is already referenced
    XHCI::_InsertEndpointForPipe(Pipe *pipe)  
    12781411        TRACE("endpoint[%d] state 0x%" B_PRIx32 "\n", id,
    12791412            ENDPOINT_0_STATE_GET(device->device_ctx->endpoints[id].dwendpoint0));
    12801413        device->state = XHCI_STATE_CONFIGURED;
     1414       
    12811415    }
    12821416    pipe->SetControllerCookie(&device->endpoints[id]);
    12831417
    XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint)  
    13041438    TRACE("_LinkDescriptorForPipe\n");
    13051439    MutexLocker endpointLocker(endpoint->lock);
    13061440    if (endpoint->used >= XHCI_MAX_TRANSFERS)
     1441    {
     1442        TRACE_ERROR("MISS-FIRE MISS-FIRE\n");
    13071443        return B_BAD_VALUE;
     1444    }
    13081445
    13091446    endpoint->used++;
    13101447    if (endpoint->td_head == NULL)
    XHCI::GetPortStatus(uint8 index, usb_port_status *status)  
    14681605
    14691606    status->status = status->change = 0;
    14701607    uint32 portStatus = ReadOpReg(XHCI_PORTSC(index));
    1471     //TRACE("port status=0x%08lx\n", portStatus);
     1608    TRACE("port %" B_PRId8 " status=0x%08" B_PRIx32 "\n", index, portStatus);
    14721609
    14731610    // build the status
    14741611    switch (PS_SPEED_GET(portStatus)) {
    XHCI::HandleTransferComplete(xhci_trb *trb)  
    17671904{
    17681905    TRACE("HandleTransferComplete trb %p\n", trb);
    17691906    addr_t source = trb->qwtrb0;
    1770     //uint8 completionCode = TRB_2_COMP_CODE_GET(trb->dwtrb2);
    1771     //uint32 remainder = TRB_2_REM_GET(trb->dwtrb2);
     1907    uint8 completionCode = TRB_2_COMP_CODE_GET(trb->dwtrb2);
     1908    uint32 remainder = TRB_2_REM_GET(trb->dwtrb2);
    17721909    uint8 endpointNumber = TRB_3_ENDPOINT_GET(trb->dwtrb3);
    17731910    uint8 slot = TRB_3_SLOT_GET(trb->dwtrb3);
    17741911
    XHCI::HandleTransferComplete(xhci_trb *trb)  
    17851922            offset);
    17861923        (void)offset;
    17871924        _UnlinkDescriptorForPipe(td, endpoint);
    1788 
     1925        td->trb_completion_code = completionCode;
     1926        td->trb_left = remainder;
    17891927        // add descriptor to finished list (to be processed and freed)
    17901928        Lock();
    17911929        td->next = fFinishedHead;
    XHCI::DoCommand(xhci_trb *trb)  
    18381976status_t
    18391977XHCI::Noop()
    18401978{
     1979    TRACE("Noop\n");
    18411980    xhci_trb trb;
    18421981    trb.qwtrb0 = 0;
    18431982    trb.dwtrb2 = 0;
    XHCI::Noop()  
    18501989status_t
    18511990XHCI::EnableSlot(uint8 *slot)
    18521991{
     1992    TRACE("Enable Slot\n");
    18531993    xhci_trb trb;
    18541994    trb.qwtrb0 = 0;
    18551995    trb.dwtrb2 = 0;
    XHCI::EnableSlot(uint8 *slot)  
    18672007status_t
    18682008XHCI::DisableSlot(uint8 slot)
    18692009{
     2010    TRACE("Disable Slot\n");
    18702011    xhci_trb trb;
    18712012    trb.qwtrb0 = 0;
    18722013    trb.dwtrb2 = 0;
    XHCI::DisableSlot(uint8 slot)  
    18792020status_t
    18802021XHCI::SetAddress(uint64 inputContext, bool bsr, uint8 slot)
    18812022{
     2023    TRACE("Set Address\n");
    18822024    xhci_trb trb;
    18832025    trb.qwtrb0 = inputContext;
    18842026    trb.dwtrb2 = 0;
    XHCI::SetAddress(uint64 inputContext, bool bsr, uint8 slot)  
    18942036status_t
    18952037XHCI::ConfigureEndpoint(uint64 inputContext, bool deconfigure, uint8 slot)
    18962038{
     2039    TRACE("Configure Endpoint\n");
    18972040    xhci_trb trb;
    18982041    trb.qwtrb0 = inputContext;
    18992042    trb.dwtrb2 = 0;
    XHCI::ConfigureEndpoint(uint64 inputContext, bool deconfigure, uint8 slot)  
    19092052status_t
    19102053XHCI::EvaluateContext(uint64 inputContext, uint8 slot)
    19112054{
     2055    TRACE("Evaluate Context\n");
    19122056    xhci_trb trb;
    19132057    trb.qwtrb0 = inputContext;
    19142058    trb.dwtrb2 = 0;
    XHCI::EvaluateContext(uint64 inputContext, uint8 slot)  
    19212065status_t
    19222066XHCI::ResetEndpoint(bool preserve, uint8 endpoint, uint8 slot)
    19232067{
     2068    TRACE("Reset Endpoint\n");
    19242069    xhci_trb trb;
    19252070    trb.qwtrb0 = 0;
    19262071    trb.dwtrb2 = 0;
    XHCI::ResetEndpoint(bool preserve, uint8 endpoint, uint8 slot)  
    19362081status_t
    19372082XHCI::StopEndpoint(bool suspend, uint8 endpoint, uint8 slot)
    19382083{
     2084    TRACE("Stop Endpoint\n");
    19392085    xhci_trb trb;
    19402086    trb.qwtrb0 = 0;
    19412087    trb.dwtrb2 = 0;
    XHCI::StopEndpoint(bool suspend, uint8 endpoint, uint8 slot)  
    19512097status_t
    19522098XHCI::SetTRDequeue(uint64 dequeue, uint16 stream, uint8 endpoint, uint8 slot)
    19532099{
     2100    TRACE("Set TR Dequeue\n");
    19542101    xhci_trb trb;
    19552102    trb.qwtrb0 = dequeue;
    19562103    trb.dwtrb2 = TRB_2_STREAM(stream);
    XHCI::SetTRDequeue(uint64 dequeue, uint16 stream, uint8 endpoint, uint8 slot)  
    19642111status_t
    19652112XHCI::ResetDevice(uint8 slot)
    19662113{
     2114    TRACE("Reset Device\n");
    19672115    xhci_trb trb;
    19682116    trb.qwtrb0 = 0;
    19692117    trb.dwtrb2 = 0;
    XHCI::CompleteEvents()  
    20002148
    20012149        while (1) {
    20022150            uint32 temp = fEventRing[i].dwtrb3;
     2151            TRACE_ALWAYS("event[%u] = %u (0x%016" B_PRIx64 " 0x%08" B_PRIx32 " 0x%08"
     2152                B_PRIx32 ")\n", i, (uint8)TRB_3_TYPE_GET(temp), fEventRing[i].qwtrb0,
     2153                fEventRing[i].dwtrb2, fEventRing[i].dwtrb3);
    20032154            uint8 k = (temp & TRB_3_CYCLE_BIT) ? 1 : 0;
    20042155            if (j != k)
    20052156                break;
    XHCI::FinishTransfers()  
    20732224            td->next = NULL;
    20742225            Unlock();
    20752226
     2227            TRACE("finishing transfer td %p\n", td);
     2228           
    20762229            Transfer* transfer = td->transfer;
    20772230            bool directionIn = (transfer->TransferPipe()->Direction() != Pipe::Out);
    20782231            usb_request_data *requestData = transfer->RequestData();
    2079 
    2080             // TODO check event
     2232           
    20812233            status_t callbackStatus = B_OK;
    2082             size_t actualLength = requestData ? requestData->Length
    2083                 : transfer->DataLength();
    2084             TRACE("finishing transfer td %p\n", td);
    2085             if (directionIn && actualLength > 0) {
    2086                 if (requestData) {
    2087                     TRACE("copying in data %d bytes\n", requestData->Length);
    2088                     memcpy((uint8 *)transfer->Vector()[0].iov_base,
    2089                         td->buffer_log[0], requestData->Length);
    2090                 } else {
    2091                     TRACE("copying in iov count %ld\n", transfer->VectorCount());
    2092                     ReadDescriptorChain(td, transfer->Vector(),
    2093                         transfer->VectorCount());
     2234            switch(td->trb_completion_code)
     2235            {
     2236                case COMP_SHORT_PACKET:
     2237                case COMP_SUCCESS:
     2238                    callbackStatus = B_OK;
     2239                    break;
     2240                case COMP_DATA_BUFFER:
     2241                    callbackStatus = directionIn ? B_DEV_DATA_OVERRUN : B_DEV_DATA_UNDERRUN;
     2242                    break;
     2243                case COMP_BABBLE:
     2244                    callbackStatus = directionIn ? B_DEV_FIFO_OVERRUN : B_DEV_FIFO_UNDERRUN;
     2245                    break;
     2246                case COMP_USB_TRANSACTION:
     2247                    callbackStatus = B_DEV_CRC_ERROR;
     2248                    break;
     2249                case COMP_STALL:
     2250                    callbackStatus = B_DEV_STALLED;
     2251                    break;
     2252                default:
     2253                    callbackStatus = B_DEV_STALLED;
     2254                    break;
     2255            }
     2256           
     2257            size_t actualLength = 0;
     2258           
     2259            if(callbackStatus == B_OK)
     2260            {
     2261                actualLength = requestData ? requestData->Length
     2262                    : transfer->DataLength();
     2263                   
     2264                if(td->trb_completion_code == COMP_SHORT_PACKET)
     2265                    actualLength -= td->trb_left;
     2266   
     2267                if (directionIn && actualLength > 0) {
     2268                    if (requestData) {
     2269                        TRACE("copying in data %d bytes\n", requestData->Length);
     2270                        transfer->PrepareKernelAccess();
     2271                        memcpy((uint8 *)transfer->Vector()[0].iov_base,
     2272                            td->buffer_log[0], requestData->Length);
     2273                    } else {
     2274                        TRACE("copying in iov count %ld\n", transfer->VectorCount());
     2275                        transfer->PrepareKernelAccess();
     2276                        ReadDescriptorChain(td, transfer->Vector(),
     2277                            transfer->VectorCount());
     2278                    }
    20942279                }
    20952280            }
    2096             transfer->Finished(callbackStatus, actualLength);
    2097 
     2281            transfer->Finished(callbackStatus, actualLength);                       
     2282            delete transfer;
    20982283            FreeDescriptor(td);
    20992284            Lock();
    21002285        }
  • src/add-ons/kernel/busses/usb/xhci.h

    diff --git a/src/add-ons/kernel/busses/usb/xhci.h b/src/add-ons/kernel/busses/usb/xhci.h
    index df4a597..0b130f0 100644
    a b typedef struct xhci_td {  
    4545    struct xhci_td  *next;
    4646    Transfer *transfer;
    4747    uint8   trb_count;
     48    uint8   trb_completion_code;
     49    uint32  trb_left;
    4850} xhci_td __attribute__((__aligned__(16)));
    4951
    5052
  • 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 ebd3d43..64c282a 100644
    a b  
    55 * Authors:
    66 *      Jian Chiang <j.jian.chiang@gmail.com>
    77 *      Jérôme Duval <jerome.duval@gmail.com>
     8 *      Akshay Jaggi <akshay1994.leo@gmail.com>
    89 */
    910#ifndef XHCI_HARDWARE_H
    1011#define XHCI_HARDWARE_H
    1112
     13// Intel quirks
     14#define XHCI_INTEL_USB3PRM                      0xDC    // USB 3.0 Port Routing Mask
     15#define XHCI_INTEL_USB3_PSSEN                   0xD8    // USB 3.0 Port SuperSpeed Enable
     16#define XHCI_INTEL_USB2PRM                      0xD4    // USB 2.0 Port Routing Mask
     17#define XHCI_INTEL_XUSB2PR                      0xD0    // USB 2.0 Port Routing
     18#define PCI_DEVICE_ID_INTEL_PANTHER_POINT_XHCI  0x1E31
     19#define PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI     0x8C31
     20#define PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI  0x9C31
     21#define PCI_VENDOR_ID_INTEL                     0x8086
    1222
    1323// Host Controller Capability Registers
    1424#define XHCI_HCI_CAPLENGTH  0x00        // HCI Capability Register Length
     
    1727#define XHCI_HCSPARAMS1     0x04        // Structural Parameters 1
    1828// HCSPARAMS1
    1929#define HCS_MAX_SLOTS(p)        (((p) >> 0) & 0xff)
    20 #define HCS_MAX_PORTS(p)        (((p) >> 24) & 0x7f)
     30#define HCS_MAX_PORTS(p)        (((p) >> 24) & 0xff)
    2131#define XHCI_HCSPARAMS2     0x08        // Structural Parameters 2
    2232#define HCS_IST(p)              (((p) >> 0) & 0xf)
    2333#define HCS_ERST_MAX(p)         (((p) >> 4) & 0xf)
    2434#define HCS_SPR(p)              (((p) >> 26) & 0x1)
    25 #define HCS_MAX_SC_BUFFERS(p)   (((p) >> 27) & 0x1f)
     35#define HCS_MAX_SC_BUFFERS(p)   (((((p) >> 21) & 0x1f)<<5)|(((p) >> 27) & 0x1f))
    2636#define XHCI_HCSPARAMS3     0x0C        // Structural Parameters 3
    2737#define HCS_U1_DEVICE_LATENCY(p)    (((p) >> 0) & 0xff)
    2838#define HCS_U2_DEVICE_LATENCY(p)    (((p) >> 16) & 0xffff)
     
    98108#define XHCI_LEGSUP_BIOSOWNED   (1 << 16)   // BIOS Owned Semaphore
    99109
    100110#define XHCI_LEGCTLSTS          0x04
    101 #define XHCI_LEGCTLSTS_DISABLE_SMI  ((0x3 << 1) + (0xff << 5) + (0x7 << 17))
     111#define XHCI_LEGCTLSTS_DISABLE_SMI  ((0x7 << 1) + (0xff << 5) + (0x7 << 17))
     112#define XHCI_LEGCTLSTS_EVENTS_SMI (0x7 << 29)
    102113
    103114#define XHCI_SUPPORTED_PROTOCOLS_CAPID  0x02
    104115#define XHCI_SUPPORTED_PROTOCOLS_0_MINOR(x) (((x) >> 16) & 0xff)
    struct xhci_slot_ctx {  
    336347#define SLOT_2_PORT_NUM_GET(x)          (((x) >> 8) & 0xFF)
    337348#define SLOT_2_TT_TIME(x)               (((x) & 0x3) << 16)
    338349#define SLOT_2_TT_TIME_GET(x)           (((x) >> 16) & 0x3)
    339 #define SLOT_2_IRQ_TARGET(x)                (((x) & 0x1F) << 27)
    340 #define SLOT_2_IRQ_TARGET_GET(x)            (((x) >> 27) & 0x1f)
     350#define SLOT_2_IRQ_TARGET(x)                (((x) & 0x7F) << 22)
     351#define SLOT_2_IRQ_TARGET_GET(x)            (((x) >> 22) & 0x7F)
    341352
    342353#define SLOT_3_DEVICE_ADDRESS(x)        ((x) & 0xFF)
    343354#define SLOT_3_DEVICE_ADDRESS_GET(x)    ((x) & 0xFF)
    344355#define SLOT_3_SLOT_STATE(x)            (((x) & 0x1F) << 27)
    345356#define SLOT_3_SLOT_STATE_GET(x)        (((x) >> 27) & 0x1F)
    346357
     358#define HUB_TTT_GET(x)                  (((x) >> 5) & 0x3)
    347359
    348360struct xhci_endpoint_ctx {
    349361    uint32  dwendpoint0;