Ticket #8954: 0001-XHCI.patch

File 0001-XHCI.patch, 13.0 KB (added by akshay1994, 10 years ago)
  • src/add-ons/kernel/busses/usb/xhci.cpp

    From 51c413efb64f3bd7cf01a972a1a6c143daa9302a Mon Sep 17 00:00:00 2001
    From: Akshay Jaggi <akshay1994.leo@gmail.com>
    Date: Sat, 2 Aug 2014 19:15:25 +0530
    Subject: [PATCH] XHCI
    
    * Fix Endpoint Context Initialisation (Refer xHCI v1.1 - 6.2.3)
    * Fix Interval Calculation (Refer xHCI v1.1 - 6.2.3.6 , USB 2.0 - 9.6.6 page 271)
    * Fix MaxBurst, MaxPacketSize Calculation (Refer xHCI v1.1 - 6.2.3.5, USB 2.0 - 9.6.6 page 271)
    * Fix MaxESITPayload Calculation (Refer xHCI v1.1 - 4.14.2)
    * Remove Link TRBs as they were never being used
    * Increase Number of TRBs per endpoint (to utilise the whole area allocated for Device TRBs)
    * Fix usage of XHCI_MAX_ENDPOINTS (most of the checks were failing at corner cases)
    * Few Coding Guideline fixes (reported by style checker script)
    ---
     src/add-ons/kernel/busses/usb/xhci.cpp        | 163 +++++++++++++++-----------
     src/add-ons/kernel/busses/usb/xhci.h          |   6 +-
     src/add-ons/kernel/busses/usb/xhci_hardware.h |   2 +-
     3 files changed, 99 insertions(+), 72 deletions(-)
    
    diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp b/src/add-ons/kernel/busses/usb/xhci.cpp
    index dbfd2b4..1e3e349 100644
    a b XHCI::Start()  
    497497    TRACE("setting CRCR addr = 0x%" B_PRIxPHYSADDR "\n", dmaAddress);
    498498    WriteOpReg(XHCI_CRCR_LO, (uint32)dmaAddress | CRCR_RCS);
    499499    WriteOpReg(XHCI_CRCR_HI, /*(uint32)(dmaAddress >> 32)*/0);
    500     //link trb
     500    // link trb
    501501    fCmdRing[XHCI_MAX_COMMANDS - 1].qwtrb0 = dmaAddress;
    502502
    503503    TRACE("setting interrupt rate\n");
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    11491149        return NULL;
    11501150    }
    11511151
    1152     for (uint32 i = 0; i < XHCI_MAX_ENDPOINTS; i++) {
    1153         struct xhci_trb *linkTrb = device->trbs + (i + 1) * XHCI_MAX_TRANSFERS - 1;
    1154         linkTrb->qwtrb0 = device->trb_addr
    1155             + i * XHCI_MAX_TRANSFERS * sizeof(xhci_trb);
    1156         linkTrb->dwtrb2 = TRB_2_IRQ(0);
    1157         linkTrb->dwtrb3 = TRB_3_CYCLE_BIT | TRB_3_TYPE(TRB_TYPE_LINK);
    1158     }
    1159 
    11601152    // set up slot pointer to device context
    11611153    fDcba->baseAddress[slot] = device->device_ctx_addr;
    11621154
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    11751167    }
    11761168
    11771169    // configure the Control endpoint 0 (type 4)
    1178     if (ConfigureEndpoint(slot, 0, 4, device->trb_addr, 0, 1, 1, 0,
    1179         maxPacketSize, maxPacketSize, speed) != B_OK) {
     1170    if (ConfigureEndpoint(slot, 0, 4, device->trb_addr, 0,
     1171        maxPacketSize, maxPacketSize & 0x7ff, speed) != B_OK) {
    11801172        TRACE_ERROR("unable to configure default control endpoint\n");
    11811173        device->state = XHCI_STATE_DISABLED;
    11821174        delete_area(device->input_ctx_area);
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    12151207    // Create a temporary pipe with the new address
    12161208    ControlPipe pipe(parent);
    12171209    pipe.SetControllerCookie(&device->endpoints[0]);
    1218     pipe.InitCommon(device->address + 1, 0, speed, Pipe::Default, 8, 0,
     1210    pipe.InitCommon(device->address + 1, 0, speed, Pipe::Default, maxPacketSize, 0,
    12191211        hubAddress, hubPort);
    12201212
    12211213    // Get the device descriptor
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    12451237        return NULL;
    12461238    }
    12471239
    1248     TRACE("device_class: %d device_subclass %d device_protocol %d\n",
    1249         deviceDescriptor.device_class, deviceDescriptor.device_subclass,
    1250         deviceDescriptor.device_protocol);
     1240    TRACE("\tlength:..............%d\n", deviceDescriptor.length);
     1241    TRACE("\tdescriptor_type:.....0x%04x\n", deviceDescriptor.descriptor_type);
     1242    TRACE("\tusb_version:.........0x%04x\n", deviceDescriptor.usb_version);
     1243    TRACE("\tdevice_class:........0x%02x\n", deviceDescriptor.device_class);
     1244    TRACE("\tdevice_subclass:.....0x%02x\n", deviceDescriptor.device_subclass);
     1245    TRACE("\tdevice_protocol:.....0x%02x\n", deviceDescriptor.device_protocol);
     1246    TRACE("\tmax_packet_size_0:...%d\n", deviceDescriptor.max_packet_size_0);
    12511247       
    12521248    if (speed == USB_SPEED_FULLSPEED && deviceDescriptor.max_packet_size_0 != 8) {
    12531249        TRACE("Full speed device with different max packet size for Endpoint 0\n");
    XHCI::_InsertEndpointForPipe(Pipe *pipe)  
    13511347    }
    13521348
    13531349    uint8 id = XHCI_ENDPOINT_ID(pipe) - 1;
    1354     if (id >= XHCI_MAX_ENDPOINTS)
     1350    if (id >= XHCI_MAX_ENDPOINTS - 1)
    13551351        return B_BAD_VALUE;
    13561352
    13571353    if (id > 0) {
    XHCI::_InsertEndpointForPipe(Pipe *pipe)  
    14031399
    14041400        if (ConfigureEndpoint(device->slot, id, type,
    14051401            device->endpoints[id].trb_addr, pipe->Interval(),
    1406             1, 1, 0, pipe->MaxPacketSize(), pipe->MaxPacketSize(),
     1402            pipe->MaxPacketSize(), pipe->MaxPacketSize() & 0x7ff,
    14071403            usbDevice->Speed()) != B_OK) {
    14081404            TRACE_ERROR("unable to configure endpoint\n");
    14091405            return B_ERROR;
    XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint)  
    14441440{
    14451441    TRACE("_LinkDescriptorForPipe\n");
    14461442    MutexLocker endpointLocker(endpoint->lock);
    1447     if (endpoint->used >= XHCI_MAX_TRANSFERS) {
     1443    if (endpoint->used > XHCI_MAX_TRANSFERS) {
    14481444        TRACE_ERROR("_LinkDescriptorForPipe max transfers count exceeded\n");
    14491445        return B_BAD_VALUE;
    14501446    }
    XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint)  
    14571453    endpoint->td_head = descriptor;
    14581454
    14591455    uint8 current = endpoint->current;
    1460     uint8 next = (current + 1) % (XHCI_MAX_TRANSFERS - 1);
     1456    uint8 next = (current + 1) % (XHCI_MAX_TRANSFERS);
    14611457
    14621458    TRACE("_LinkDescriptorForPipe current %d, next %d\n", current, next);
    14631459
    XHCI::_UnlinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint)  
    15131509
    15141510
    15151511status_t
    1516 XHCI::ConfigureEndpoint(uint8 slot, uint8 number, uint8 type, uint64 ringAddr, uint16 interval,
    1517     uint8 maxPacketCount, uint8 mult, uint8 fpsShift, uint16 maxPacketSize,
    1518     uint16 maxFrameSize, usb_speed speed)
     1512XHCI::ConfigureEndpoint(uint8 slot, uint8 number, uint8 type, uint64 ringAddr,
     1513    uint16 interval, uint16 maxPacketSize, uint16 maxFrameSize, usb_speed speed)
    15191514{
    1520     struct xhci_device *device = &fDevices[slot];
    1521     struct xhci_endpoint_ctx *endpoint = &device->input_ctx->endpoints[number];
     1515    struct xhci_device* device = &fDevices[slot];
     1516    struct xhci_endpoint_ctx* endpoint = &device->input_ctx->endpoints[number];
    15221517
    1523     if (mult == 0 || maxPacketCount == 0)
    1524         return B_BAD_VALUE;
     1518    uint8 maxBurst = (maxPacketSize & 0x1800) >> 11;
     1519    maxPacketSize = (maxPacketSize & 0x7ff);
    15251520
    1526     maxPacketCount--;
     1521    endpoint->dwendpoint0 = 0;
     1522    endpoint->dwendpoint1 = 0;
     1523    endpoint->qwendpoint2 = 0;
     1524    endpoint->dwendpoint4 = 0;
    15271525
    1528     endpoint->dwendpoint0 = ENDPOINT_0_STATE(0) | ENDPOINT_0_MAXPSTREAMS(0);
    1529     // add mult for isochronous and interrupt types
    1530     switch (speed) {
    1531         case USB_SPEED_LOWSPEED:
    1532         case USB_SPEED_FULLSPEED:
    1533             fpsShift += 3;
    1534         break;
    1535         default:
    1536             break;
     1526    // Assigning Interval
     1527
     1528    uint16 calcInterval = 0;
     1529
     1530    if (speed == USB_SPEED_HIGHSPEED
     1531            && (type == 4 || type == 2))
     1532    {
     1533        if (interval != 0)
     1534        {
     1535            while ((1<<calcInterval) <= interval)
     1536            {
     1537                calcInterval++;
     1538            }
     1539            calcInterval--;
     1540        }
    15371541    }
    1538     switch (type) {
    1539         case 1:
    1540         case 5:
    1541             if (fpsShift > 3)
    1542                 fpsShift--;
    1543         case 3:
    1544         case 7:
    1545             endpoint->dwendpoint0 |= ENDPOINT_0_INTERVAL(fpsShift);
    1546             break;
    1547         default:
    1548             break;
     1542    if ((type & 0x3) == 3
     1543            && (speed == USB_SPEED_FULLSPEED || speed == USB_SPEED_LOWSPEED))
     1544    {
     1545        while ((1<<calcInterval) <= interval * 8)
     1546        {
     1547            calcInterval++;
     1548        }
     1549        calcInterval--;
     1550    }
     1551    if ((type & 0x3) == 1 && speed == USB_SPEED_FULLSPEED)
     1552    {
     1553        calcInterval = interval + 2;
     1554    }
     1555    if ( ((type & 0x3) == 1 || (type & 0x3) == 3)
     1556            && (speed == USB_SPEED_HIGHSPEED || speed == USB_SPEED_SUPER) )
     1557    {
     1558        calcInterval = interval - 1;
     1559    }
     1560
     1561    endpoint->dwendpoint0 |= ENDPOINT_0_INTERVAL(calcInterval);
     1562
     1563    // Assigning CERR for non-isoch endpoints
     1564    if ((type & 0x3) != 1)
     1565    {
     1566        endpoint->dwendpoint1 |= ENDPOINT_1_CERR(3);
     1567    }
     1568
     1569    endpoint->dwendpoint1 |= ENDPOINT_1_EPTYPE(type);
     1570
     1571    // Assigning MaxBurst for HighSpeed
     1572    if (speed == USB_SPEED_HIGHSPEED
     1573            && ((type & 0x3) == 1 || (type & 0x3) == 3))
     1574    {
     1575        endpoint->dwendpoint1 |= ENDPOINT_1_MAXBURST(maxBurst);
    15491576    }
    1550     // add interval
    1551     endpoint->dwendpoint1 = ENDPOINT_1_EPTYPE(type)
    1552         | ENDPOINT_1_MAXBURST(maxPacketCount)
    1553         | ENDPOINT_1_MAXPACKETSIZE(maxPacketSize)
    1554         | ENDPOINT_1_CERR(3);
    1555     endpoint->qwendpoint2 = ENDPOINT_2_DCS_BIT | ringAddr;
    1556     // 8 for Control endpoint
     1577
     1578    // TODO Assign MaxBurst for SuperSpeed
     1579
     1580    endpoint->dwendpoint1 |= ENDPOINT_1_MAXPACKETSIZE(maxPacketSize);
     1581    endpoint->qwendpoint2 |= ENDPOINT_2_DCS_BIT | ringAddr;
     1582
     1583    // Assign MaxESITPayload
     1584    // Assign AvgTRBLength
    15571585    switch (type) {
    15581586        case 4:
    15591587            endpoint->dwendpoint4 = ENDPOINT_4_AVGTRBLENGTH(8);
    XHCI::ConfigureEndpoint(uint8 slot, uint8 number, uint8 type, uint64 ringAddr, u  
    15631591        case 5:
    15641592        case 7:
    15651593            endpoint->dwendpoint4 = ENDPOINT_4_AVGTRBLENGTH(min_c(maxFrameSize,
    1566                 B_PAGE_SIZE)) | ENDPOINT_4_MAXESITPAYLOAD(maxFrameSize);
     1594                B_PAGE_SIZE)) | ENDPOINT_4_MAXESITPAYLOAD(( (maxBurst+1) * maxPacketSize ));
    15671595            break;
    15681596        default:
    15691597            endpoint->dwendpoint4 = ENDPOINT_4_AVGTRBLENGTH(B_PAGE_SIZE);
    XHCI::ConfigureEndpoint(uint8 slot, uint8 number, uint8 type, uint64 ringAddr, u  
    15781606
    15791607
    15801608status_t
    1581 XHCI::GetPortSpeed(uint8 index, usb_speed *speed)
     1609XHCI::GetPortSpeed(uint8 index, usb_speed* speed)
    15821610{
    15831611    uint32 portStatus = ReadOpReg(XHCI_PORTSC(index));
    15841612
    XHCI::GetPortSpeed(uint8 index, usb_speed *speed)  
    16071635
    16081636
    16091637status_t
    1610 XHCI::GetPortStatus(uint8 index, usb_port_status *status)
     1638XHCI::GetPortStatus(uint8 index, usb_port_status* status)
    16111639{
    16121640    if (index >= fPortCount)
    16131641        return B_BAD_INDEX;
    XHCI::ControllerReset()  
    17951823
    17961824
    17971825int32
    1798 XHCI::InterruptHandler(void *data)
     1826XHCI::InterruptHandler(void* data)
    17991827{
    1800     return ((XHCI *)data)->Interrupt();
     1828    return ((XHCI*)data)->Interrupt();
    18011829}
    18021830
    18031831
    XHCI::Ring(uint8 slot, uint8 endpoint)  
    18431871    TRACE("Ding Dong! slot:%d endpoint %d\n", slot, endpoint)
    18441872    if ((slot == 0 && endpoint > 0) || (slot > 0 && endpoint == 0))
    18451873        panic("Ring() invalid slot/endpoint combination\n");
    1846     if (slot > fSlotCount || endpoint > XHCI_MAX_ENDPOINTS)
     1874    if (slot > fSlotCount || endpoint >= XHCI_MAX_ENDPOINTS)
    18471875        panic("Ring() invalid slot or endpoint\n");
    18481876    WriteDoorReg32(XHCI_DOORBELL(slot), XHCI_DOORBELL_TARGET(endpoint)
    18491877        | XHCI_DOORBELL_STREAMID(0));
    XHCI::Ring(uint8 slot, uint8 endpoint)  
    18531881
    18541882
    18551883void
    1856 XHCI::QueueCommand(xhci_trb *trb)
     1884XHCI::QueueCommand(xhci_trb* trb)
    18571885{
    18581886    uint8 i, j;
    18591887    uint32 temp;
    XHCI::QueueCommand(xhci_trb *trb)  
    18961924
    18971925
    18981926void
    1899 XHCI::HandleCmdComplete(xhci_trb *trb)
     1927XHCI::HandleCmdComplete(xhci_trb* trb)
    19001928{
    19011929    if (fCmdAddr == trb->qwtrb0) {
    19021930        TRACE("Received command event\n");
    XHCI::HandleCmdComplete(xhci_trb *trb)  
    19091937
    19101938
    19111939void
    1912 XHCI::HandleTransferComplete(xhci_trb *trb)
     1940XHCI::HandleTransferComplete(xhci_trb* trb)
    19131941{
    19141942    TRACE("HandleTransferComplete trb %p\n", trb);
    19151943    addr_t source = trb->qwtrb0;
    XHCI::HandleTransferComplete(xhci_trb *trb)  
    19201948
    19211949    if (slot > fSlotCount)
    19221950        TRACE_ERROR("invalid slot\n");
    1923     if (endpointNumber == 0 || endpointNumber > XHCI_MAX_ENDPOINTS)
     1951    if (endpointNumber == 0 || endpointNumber >= XHCI_MAX_ENDPOINTS)
    19241952        TRACE_ERROR("invalid endpoint\n");
    19251953
    19261954    xhci_device *device = &fDevices[slot];
    XHCI::HandleTransferComplete(xhci_trb *trb)  
    19451973
    19461974
    19471975status_t
    1948 XHCI::DoCommand(xhci_trb *trb)
     1976XHCI::DoCommand(xhci_trb* trb)
    19491977{
    19501978    if (!Lock())
    19511979        return B_ERROR;
    XHCI::Noop()  
    19962024
    19972025
    19982026status_t
    1999 XHCI::EnableSlot(uint8 *slot)
     2027XHCI::EnableSlot(uint8* slot)
    20002028{
    20012029    TRACE("Enable Slot\n");
    20022030    xhci_trb trb;
    XHCI::CompleteEvents()  
    21572185
    21582186        while (1) {
    21592187            uint32 temp = fEventRing[i].dwtrb3;
    2160             TRACE_ALWAYS("event[%u] = %u (0x%016" B_PRIx64 " 0x%08" B_PRIx32 " 0x%08"
     2188            TRACE("event[%u] = %u (0x%016" B_PRIx64 " 0x%08" B_PRIx32 " 0x%08"
    21612189                B_PRIx32 ")\n", i, (uint8)TRB_3_TYPE_GET(temp), fEventRing[i].qwtrb0,
    21622190                fEventRing[i].dwtrb2, fEventRing[i].dwtrb3);
    21632191            uint8 k = (temp & TRB_3_CYCLE_BIT) ? 1 : 0;
    XHCI::FinishTransfers()  
    22962324    }
    22972325}
    22982326
     2327
    22992328inline void
    23002329XHCI::WriteOpReg(uint32 reg, uint32 value)
    23012330{
  • 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 0b130f0..ade72ff 100644
    a b public:  
    102102                                    usb_speed speed);
    103103            status_t            ConfigureEndpoint(uint8 slot, uint8 number,
    104104                                    uint8 type, uint64 ringAddr,
    105                                     uint16 interval, uint8 maxPacketCount,
    106                                     uint8 mult, uint8 fpsShift,
    107                                     uint16 maxPacketSize, uint16 maxFrameSize,
    108                                     usb_speed speed);
     105                                    uint16 interval, uint16 maxPacketSize,
     106                                    uint16 maxFrameSize, usb_speed speed);
    109107    virtual void                FreeDevice(Device *device);
    110108
    111109            status_t            _InsertEndpointForPipe(Pipe *pipe);
  • 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 669c569..a62adf2 100644
    a b  
    278278#define XHCI_MAX_ENDPOINTS  32
    279279#define XHCI_MAX_SCRATCHPADS    32
    280280#define XHCI_MAX_DEVICES    128
    281 #define XHCI_MAX_TRANSFERS  4
     281#define XHCI_MAX_TRANSFERS  8
    282282#define XHCI_MAX_TRBS_PER_TD    18
    283283
    284284