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

  • From: jerome.duval@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 12 Jul 2014 00:46:35 +0200 (CEST)

hrev47483 adds 1 changeset to branch 'master'
old head: 74e1a530f88029d2933619301c56f23bf31e96a1
new head: 192f01c669102651bdc81273811079e90e0a29e5
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=192f01c+%5E74e1a53

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

192f01c: XHCI USB: Some more fixes.
  
  * Fix device speed identification.
  * Fix Max Packet Size for Full-Speed devices.
  * Fix IRQ rate.
  * Update slot context for LS/FS devices connected to non-root HS hub.
  * Fix typo.
  
  Signed-off-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

                                 [ Akshay Jaggi <akshay1994.leo@xxxxxxxxx> ]

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

Revision:    hrev47483
Commit:      192f01c669102651bdc81273811079e90e0a29e5
URL:         http://cgit.haiku-os.org/haiku/commit/?id=192f01c
Author:      Akshay Jaggi <akshay1994.leo@xxxxxxxxx>
Date:        Fri Jul 11 22:07:14 2014 UTC
Committer:   Jérôme Duval <jerome.duval@xxxxxxxxx>
Commit-Date: Fri Jul 11 22:11:39 2014 UTC

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

3 files changed, 62 insertions(+), 23 deletions(-)
src/add-ons/kernel/bus_managers/usb/Hub.cpp   |  5 +-
src/add-ons/kernel/busses/usb/xhci.cpp        | 78 +++++++++++++++++------
src/add-ons/kernel/busses/usb/xhci_hardware.h |  2 +-

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

diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp 
b/src/add-ons/kernel/bus_managers/usb/Hub.cpp
index 3190018..229786d 100644
--- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp
+++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp
@@ -258,6 +258,9 @@ Hub::Explore(change_item **changeList)
                                        }
 
                                        usb_speed speed = USB_SPEED_FULLSPEED;
+                                       // Hack - We currently do not support 
USB3.0 Hubs
+                                       // This is for XHCI, which anyway 
rechecks the port speed
+                                       // This will in no way work for 
non-root USB3.0 Hubs
                                        if (fDeviceDescriptor.usb_version == 
0x300)
                                                speed = USB_SPEED_SUPER;
                                        else if (fPortStatus[i].status & 
PORT_STATUS_LOW_SPEED)
@@ -327,7 +330,7 @@ Hub::Explore(change_item **changeList)
                }
 
                if (fPortStatus[i].change & PORT_STATUS_RESET) {
-                       TRACE_ALWAYS("port %" B_PRId32 "was reset\n", i);
+                       TRACE_ALWAYS("port %" B_PRId32 " was reset\n", i);
                        DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | 
USB_REQTYPE_OTHER_OUT,
                                USB_REQUEST_CLEAR_FEATURE, C_PORT_RESET, i + 1,
                                0, NULL, 0, NULL);
diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp 
b/src/add-ons/kernel/busses/usb/xhci.cpp
index 50b11ef..dbfd2b4 100644
--- a/src/add-ons/kernel/busses/usb/xhci.cpp
+++ b/src/add-ons/kernel/busses/usb/xhci.cpp
@@ -501,7 +501,16 @@ XHCI::Start()
        fCmdRing[XHCI_MAX_COMMANDS - 1].qwtrb0 = dmaAddress;
 
        TRACE("setting interrupt rate\n");
-       WriteRunReg32(XHCI_IMOD(0), 160); // 25000 irq/s
+       
+       // Setting IMOD below 0x3F8 on Intel Lynx Point can cause IRQ lockups
+       if (fPCIInfo->vendor_id == PCI_VENDOR_INTEL 
+               && (fPCIInfo->device_id == PCI_DEVICE_INTEL_PANTHER_POINT_XHCI
+                       || fPCIInfo->device_id == 
PCI_DEVICE_INTEL_LYNX_POINT_XHCI
+                       || fPCIInfo->device_id == 
PCI_DEVICE_INTEL_LYNX_POINT_LP_XHCI)) {
+               WriteRunReg32(XHCI_IMOD(0), 0x000003f8); // 4000 irq/s
+       } else {
+               WriteRunReg32(XHCI_IMOD(0), 0x000001f4); // 8000 irq/s
+       }
 
        TRACE("enabling interrupt\n");
        WriteRunReg32(XHCI_IMAN(0), ReadRunReg32(XHCI_IMAN(0)) | IMAN_INTR_ENA);
@@ -1017,8 +1026,6 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 
hubPort,
 {
        TRACE("AllocateDevice hubAddress %d hubPort %d speed %d\n", hubAddress,
                hubPort, speed);
-       GetPortSpeed(hubPort - 1, &speed);
-       TRACE("speed %d\n", speed);
 
        uint8 slot = XHCI_MAX_SLOTS;
        if (EnableSlot(&slot) != B_OK) {
@@ -1072,6 +1079,13 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 
hubPort,
                routePort = hubDevice->HubPort();
        }
 
+       // Get speed of port, only if device connected to root hub port
+       // else we have to rely on value reported by the Hub Explore thread
+       if (route == 0) {
+               GetPortSpeed(hubPort - 1, &speed);
+               TRACE("speed updated %d\n", speed);
+       }
+
        device->input_ctx->slot.dwslot0 = SLOT_0_NUM_ENTRIES(1) | 
SLOT_0_ROUTE(route);
 
        // add the speed
@@ -1095,8 +1109,16 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 
hubPort,
 
        device->input_ctx->slot.dwslot1 = SLOT_1_RH_PORT(rhPort); // TODO 
enable power save
        device->input_ctx->slot.dwslot2 = SLOT_2_IRQ_TARGET(0);
-       if (0)
+       
+       // If LS/FS device connected to non-root HS device
+       if (route != 0 && parent->Speed() == USB_SPEED_HIGHSPEED
+               && (speed == USB_SPEED_LOWSPEED || speed == 
USB_SPEED_FULLSPEED)) {
+               struct xhci_device *parenthub = (struct xhci_device *)
+                       parent->ControllerCookie();
                device->input_ctx->slot.dwslot2 |= SLOT_2_PORT_NUM(hubPort);
+               device->input_ctx->slot.dwslot2 |= 
SLOT_2_TT_HUB_SLOT(parenthub->slot);
+       }
+
        device->input_ctx->slot.dwslot3 = SLOT_3_SLOT_STATE(0)
                | SLOT_3_DEVICE_ADDRESS(0);
 
@@ -1226,6 +1248,17 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 
hubPort,
        TRACE("device_class: %d device_subclass %d device_protocol %d\n",
                deviceDescriptor.device_class, deviceDescriptor.device_subclass,
                deviceDescriptor.device_protocol);
+               
+       if (speed == USB_SPEED_FULLSPEED && deviceDescriptor.max_packet_size_0 
!= 8) {
+               TRACE("Full speed device with different max packet size for 
Endpoint 0\n");
+               device->input_ctx->endpoints[0].dwendpoint1 &=
+                       ~ENDPOINT_1_MAXPACKETSIZE(0xffff);
+               device->input_ctx->endpoints[0].dwendpoint1 |=
+                       
ENDPOINT_1_MAXPACKETSIZE(deviceDescriptor.max_packet_size_0);
+               device->input_ctx->input.dropFlags = 0;
+               device->input_ctx->input.addFlags = (1 << 1);
+               EvaluateContext(device->input_ctx_addr, device->slot);
+       }
 
        Device *deviceObject = NULL;
        if (deviceDescriptor.device_class == 0x09) {
@@ -1547,25 +1580,28 @@ XHCI::ConfigureEndpoint(uint8 slot, uint8 number, uint8 
type, uint64 ringAddr, u
 status_t
 XHCI::GetPortSpeed(uint8 index, usb_speed *speed)
 {
-       if (fPortSpeeds[index] == USB_SPEED_SUPER)
-               *speed = USB_SPEED_SUPER;
-       else {
-               uint32 portStatus = ReadOpReg(XHCI_PORTSC(index));
+       uint32 portStatus = ReadOpReg(XHCI_PORTSC(index));
 
-               switch (PS_SPEED_GET(portStatus)) {
-               case 3:
-                       *speed = USB_SPEED_HIGHSPEED;
-                       break;
-               case 2:
-                       *speed = USB_SPEED_LOWSPEED;
-                       break;
-               case 1:
-                       *speed = USB_SPEED_FULLSPEED;
-                       break;
-               default:
-                       *speed = USB_SPEED_SUPER;
-               }
+       switch (PS_SPEED_GET(portStatus)) {
+       case 3:
+               *speed = USB_SPEED_HIGHSPEED;
+               break;
+       case 2:
+               *speed = USB_SPEED_LOWSPEED;
+               break;
+       case 1:
+               *speed = USB_SPEED_FULLSPEED;
+               break;
+       case 4:
+               *speed = USB_SPEED_SUPER;
+               break;
+       default:
+               TRACE("Non Standard Port Speed\n");
+               TRACE("Assuming Superspeed\n");
+               *speed = USB_SPEED_SUPER;
+               break;
        }
+
        return B_OK;
 }
 
diff --git a/src/add-ons/kernel/busses/usb/xhci_hardware.h 
b/src/add-ons/kernel/busses/usb/xhci_hardware.h
index 05904d8..669c569 100644
--- a/src/add-ons/kernel/busses/usb/xhci_hardware.h
+++ b/src/add-ons/kernel/busses/usb/xhci_hardware.h
@@ -344,7 +344,7 @@ struct xhci_slot_ctx {
 #define SLOT_1_NUM_PORTS_GET(x)                        (((x) >> 24) & 0xFF)
 
 #define SLOT_2_TT_HUB_SLOT(x)                  ((x) & 0xFF)
-#define SLOT_2_TT_HUB_SLOT(x)                  ((x) & 0xFF)
+#define SLOT_2_TT_HUB_SLOT_GET(x)              ((x) & 0xFF)
 #define SLOT_2_PORT_NUM(x)                             (((x) & 0xFF) << 8)
 #define SLOT_2_PORT_NUM_GET(x)                 (((x) >> 8) & 0xFF)
 #define SLOT_2_TT_TIME(x)                              (((x) & 0x3) << 16)


Other related posts:

  • » [haiku-commits] haiku: hrev47483 - in src/add-ons/kernel: busses/usb bus_managers/usb - jerome . duval