Ticket #8954: 0001-XHCI-More-Fixes.patch

File 0001-XHCI-More-Fixes.patch, 6.1 KB (added by akshay1994, 10 years ago)
  • src/add-ons/kernel/bus_managers/usb/Hub.cpp

    From 12a80667260a99d59aab0f477cbc3d3150a2267d Mon Sep 17 00:00:00 2001
    From: Akshay Jaggi <akshay1994.leo@gmail.com>
    Date: Fri, 11 Jul 2014 14:25:14 +0000
    Subject: [PATCH] XHCI-More-Fixes
    
    - Fix device speed idtification
    - Fix Max Packet Size for Full-Speed Devices
    - Fix IRQ rate
    - Update slot context for LS/FS devices connected to non-root HS hub
    ---
     src/add-ons/kernel/bus_managers/usb/Hub.cpp   |  3 +
     src/add-ons/kernel/busses/usb/xhci.cpp        | 82 ++++++++++++++++++++-------
     src/add-ons/kernel/busses/usb/xhci_hardware.h |  2 +-
     3 files changed, 65 insertions(+), 22 deletions(-)
    
    diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp
    index 3190018..dea45e9 100644
    a b Hub::Explore(change_item **changeList)  
    258258                    }
    259259
    260260                    usb_speed speed = USB_SPEED_FULLSPEED;
     261                    // Hack - We currently do not support USB3.0 Hubs
     262                    // This is for XHCI, which anyway rechecks the port speed
     263                    // This will in no way work for non-root USB3.0 Hubs
    261264                    if (fDeviceDescriptor.usb_version == 0x300)
    262265                        speed = USB_SPEED_SUPER;
    263266                    else if (fPortStatus[i].status & PORT_STATUS_LOW_SPEED)
  • 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 2d1ca46..bc81362 100644
    a b XHCI::Start()  
    511511    fCmdRing[XHCI_MAX_COMMANDS - 1].qwtrb0 = dmaAddress;
    512512
    513513    TRACE("setting interrupt rate\n");
    514     WriteRunReg32(XHCI_IMOD(0), 160); // 25000 irq/s
     514   
     515    //Setting IMOD below 0x3F8 on Intel Lynx Point can cause IRQ lockups
     516    if(fPCIInfo->vendor_id == PCI_VENDOR_ID_INTEL
     517        && (fPCIInfo->device_id == PCI_DEVICE_ID_INTEL_PANTHER_POINT_XHCI
     518            || fPCIInfo->device_id == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI
     519            || fPCIInfo->device_id == PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI)) {
     520       
     521        WriteRunReg32(XHCI_IMOD(0), 0x000003F8U); // 4000 irq/s
     522    }
     523    else
     524    {
     525        WriteRunReg32(XHCI_IMOD(0), 0x000001F4U); // 8000 irq/s
     526    }
    515527
    516528    TRACE("enabling interrupt\n");
    517529    WriteRunReg32(XHCI_IMAN(0), ReadRunReg32(XHCI_IMAN(0)) | IMAN_INTR_ENA);
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    10321044{
    10331045    TRACE("AllocateDevice hubAddress %d hubPort %d speed %d\n", hubAddress,
    10341046        hubPort, speed);
    1035     GetPortSpeed(hubPort - 1, &speed);
    1036     TRACE("speed %d\n", speed);
    10371047
    10381048    uint8 slot = XHCI_MAX_SLOTS;
    10391049    if (EnableSlot(&slot) != B_OK) {
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    10871097        routePort = hubDevice->HubPort();
    10881098    }
    10891099
     1100    // Get speed of port, only if device connected to root hub port
     1101    // Else we have to rely on value reported by Hub Explore Thread
     1102    if(route == 0)
     1103    {
     1104        GetPortSpeed(hubPort - 1, &speed);
     1105        TRACE("speed updated %d\n", speed);
     1106    }
     1107
    10901108    device->input_ctx->slot.dwslot0 = SLOT_0_NUM_ENTRIES(1) | SLOT_0_ROUTE(route);
    10911109
    10921110    // add the speed
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    11101128
    11111129    device->input_ctx->slot.dwslot1 = SLOT_1_RH_PORT(rhPort); // TODO enable power save
    11121130    device->input_ctx->slot.dwslot2 = SLOT_2_IRQ_TARGET(0);
    1113     if (0)
     1131   
     1132    // If LS/FS device connected to non-root HS device
     1133    if((route != 0) && (parent->Speed() == USB_SPEED_HIGHSPEED)
     1134        && (speed == USB_SPEED_LOWSPEED
     1135            || speed == USB_SPEED_FULLSPEED)) {
     1136   
     1137        struct xhci_device *parenthub = (struct xhci_device *) parent->ControllerCookie();
    11141138        device->input_ctx->slot.dwslot2 |= SLOT_2_PORT_NUM(hubPort);
     1139        device->input_ctx->slot.dwslot2 |= SLOT_2_TT_HUB_SLOT(parenthub->slot);
     1140    }
     1141   
    11151142    device->input_ctx->slot.dwslot3 = SLOT_3_SLOT_STATE(0)
    11161143        | SLOT_3_DEVICE_ADDRESS(0);
    11171144
    XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort,  
    12401267    TRACE("device_class: %d device_subclass %d device_protocol %d\n",
    12411268        deviceDescriptor.device_class, deviceDescriptor.device_subclass,
    12421269        deviceDescriptor.device_protocol);
     1270       
     1271    if(speed == USB_SPEED_FULLSPEED && deviceDescriptor.max_packet_size_0 != 8)
     1272    {
     1273        TRACE("Full speed device with different max packet size for Endpoint 0\n");
     1274        device->input_ctx->endpoints[0].dwendpoint1 &= ~ENDPOINT_1_MAXPACKETSIZE(0xFFFF);
     1275        device->input_ctx->endpoints[0].dwendpoint1 |= ENDPOINT_1_MAXPACKETSIZE(deviceDescriptor.max_packet_size_0);
     1276        device->input_ctx->input.dropFlags = 0;
     1277        device->input_ctx->input.addFlags = (1<<1);
     1278        EvaluateContext(device->input_ctx_addr, device->slot);
     1279    }
    12431280
    12441281    if(deviceDescriptor.device_class==0x09)
    12451282    {
    XHCI::ConfigureEndpoint(uint8 slot, uint8 number, uint8 type, uint64 ringAddr, u  
    15741611status_t
    15751612XHCI::GetPortSpeed(uint8 index, usb_speed *speed)
    15761613{
    1577     if (fPortSpeeds[index] == USB_SPEED_SUPER)
    1578         *speed = USB_SPEED_SUPER;
    1579     else {
    1580         uint32 portStatus = ReadOpReg(XHCI_PORTSC(index));
     1614    uint32 portStatus = ReadOpReg(XHCI_PORTSC(index));
    15811615
    1582         switch (PS_SPEED_GET(portStatus)) {
    1583         case 3:
    1584             *speed = USB_SPEED_HIGHSPEED;
    1585             break;
    1586         case 2:
    1587             *speed = USB_SPEED_LOWSPEED;
    1588             break;
    1589         case 1:
    1590             *speed = USB_SPEED_FULLSPEED;
    1591             break;
    1592         default:
    1593             *speed = USB_SPEED_SUPER;
    1594         }
     1616    switch (PS_SPEED_GET(portStatus)) {
     1617    case 3:
     1618        *speed = USB_SPEED_HIGHSPEED;
     1619        break;
     1620    case 2:
     1621        *speed = USB_SPEED_LOWSPEED;
     1622        break;
     1623    case 1:
     1624        *speed = USB_SPEED_FULLSPEED;
     1625        break;
     1626    case 4:
     1627        *speed = USB_SPEED_SUPER;
     1628        break;
     1629    default:
     1630        TRACE("Non Standard Port Speed\n");
     1631        TRACE("Assuming Superspeed\n");
     1632        *speed = USB_SPEED_SUPER;
     1633        break;
    15951634    }
     1635
    15961636    return B_OK;
    15971637}
    15981638
  • 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 64c282a..8bf4aca 100644
    a b struct xhci_slot_ctx {  
    342342#define SLOT_1_NUM_PORTS_GET(x)         (((x) >> 24) & 0xFF)
    343343
    344344#define SLOT_2_TT_HUB_SLOT(x)           ((x) & 0xFF)
    345 #define SLOT_2_TT_HUB_SLOT(x)           ((x) & 0xFF)
     345#define SLOT_2_TT_HUB_SLOT_GET(x)       ((x) & 0xFF)
    346346#define SLOT_2_PORT_NUM(x)              (((x) & 0xFF) << 8)
    347347#define SLOT_2_PORT_NUM_GET(x)          (((x) >> 8) & 0xFF)
    348348#define SLOT_2_TT_TIME(x)               (((x) & 0x3) << 16)