[haiku-commits] haiku: hrev47481 - in src/add-ons/kernel: busses/usb network/protocols/udp

  • From: jerome.duval@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 11 Jul 2014 22:14:51 +0200 (CEST)

hrev47481 adds 1 changeset to branch 'master'
old head: 8674959175ead46ef143a0a60c59e34ce77294c0
new head: 17aa359b5df69f658b4b33e29546c9fb2f0cfce3
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=17aa359+%5E8674959

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

17aa359: XHCI USB: Fixes.
  
  * Add support for hubs in AllocateDevice().
  * Prevent page fault in FinishTransfers().
  * Set fCapabilityLength
  * Correct in BIOS ownership code
  * Fix context errors in _InsertEndpointForPipe().
  * Update constants according to latest Specification (v1.1)
  * Fix SMI code (reference
  http://lkml.iu.edu/hypermail/linux/kernel/1204.2/02460.html).
  * Fix Memory/Device-Slot leaks.
  * Fix area allocation for TRBs.
  * Fix for Intel Lynx Point and Panther Point chipsets. Also move init
  of xhci before ehci, to switch USB 2.0 ports before the ehci module
  discovers them.
  
  Signed-off-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

                                 [ Akshay Jaggi <akshay1994.leo@xxxxxxxxx> ]

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

Revision:    hrev47481
Commit:      17aa359b5df69f658b4b33e29546c9fb2f0cfce3
URL:         http://cgit.haiku-os.org/haiku/commit/?id=17aa359
Author:      Akshay Jaggi <akshay1994.leo@xxxxxxxxx>
Date:        Sat Jun 28 17:03:12 2014 UTC
Committer:   Jérôme Duval <jerome.duval@xxxxxxxxx>
Commit-Date: Fri Jul 11 20:14:05 2014 UTC

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

9 files changed, 334 insertions(+), 83 deletions(-)
build/jam/packages/Haiku                         |   4 +-
headers/posix/netinet/in.h                       |   1 +
src/add-ons/kernel/bus_managers/usb/Hub.cpp      |   4 +-
src/add-ons/kernel/bus_managers/usb/Stack.cpp    |   5 +-
.../kernel/bus_managers/usb/usb_private.h        |   3 +-
src/add-ons/kernel/busses/usb/xhci.cpp           | 283 ++++++++++++++-----
src/add-ons/kernel/busses/usb/xhci.h             |   2 +
src/add-ons/kernel/busses/usb/xhci_hardware.h    |  24 +-
src/add-ons/kernel/network/protocols/udp/udp.cpp |  91 +++++-

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

diff --git a/build/jam/packages/Haiku b/build/jam/packages/Haiku
index 72f52ab..c975bbb 100644
--- a/build/jam/packages/Haiku
+++ b/build/jam/packages/Haiku
@@ -38,7 +38,7 @@ if $(HAIKU_ATA_STACK) = 1 {
 
 AddFilesToPackage add-ons kernel busses random : virtio_rng ;
 AddFilesToPackage add-ons kernel busses scsi : ahci virtio_scsi ;
-AddFilesToPackage add-ons kernel busses usb : <usb>uhci <usb>ohci <usb>ehci ;
+AddFilesToPackage add-ons kernel busses usb : <usb>uhci <usb>ohci <usb>ehci 
<usb>xhci ;
 AddFilesToPackage add-ons kernel busses virtio : virtio_pci ;
 AddFilesToPackage add-ons kernel console : vga_text ;
 AddFilesToPackage add-ons kernel debugger
@@ -206,7 +206,7 @@ AddBootModuleSymlinksToPackage
        openpic@ppc
        packagefs pci
        scsi scsi_cd scsi_disk scsi_periph silicon_image_3112
-       usb usb_disk <usb>ehci <usb>ohci <usb>uhci
+       usb usb_disk <usb>ehci <usb>ohci <usb>uhci <usb>xhci
        virtio virtio_block virtio_pci virtio_scsi
 ;
 
diff --git a/headers/posix/netinet/in.h b/headers/posix/netinet/in.h
index ab891cb..73a6bfc 100644
--- a/headers/posix/netinet/in.h
+++ b/headers/posix/netinet/in.h
@@ -64,6 +64,7 @@ typedef uint32_t in_addr_t;
 #define IPPROTO_NONE                   59      /* 59, IPv6 no next header */
 #define IPPROTO_DSTOPTS                        60      /* 60, IPv6 destination 
option */
 #define IPPROTO_ETHERIP                        97      /* 97, Ethernet in IPv4 
*/
+#define IPPROTO_UDPLITE         136 /* 136, UDPLite */
 #define IPPROTO_RAW                            255     /* 255 */
 
 #define IPPROTO_MAX                            256
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/src/add-ons/kernel/bus_managers/usb/Hub.cpp
+++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp
@@ -17,9 +17,9 @@
 
 Hub::Hub(Object *parent, int8 hubAddress, uint8 hubPort,
        usb_device_descriptor &desc, int8 deviceAddress, usb_speed speed,
-       bool isRootHub)
+       bool isRootHub, void *controllerCookie)
        :       Device(parent, hubAddress, hubPort, desc, deviceAddress, speed,
-                       isRootHub),
+                       isRootHub, controllerCookie),
                fInterruptPipe(NULL)
 {
        TRACE("creating hub\n");
diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp 
b/src/add-ons/kernel/bus_managers/usb/Stack.cpp
index 04ad075..92cb858 100644
--- a/src/add-ons/kernel/bus_managers/usb/Stack.cpp
+++ b/src/add-ons/kernel/bus_managers/usb/Stack.cpp
@@ -60,11 +60,14 @@ Stack::Stack()
        // companion host controllers (per the EHCI specs) and it would 
therefore
        // be enumerated as the last item. As this does not apply to us we have 
to
        // ensure ordering using another method.
+       // Intel Lynx Point and Panther Point chipsets have ports shared between
+       // EHCI and XHCI, defaulting to EHCI. The XHCI module will switch USB 
2.0
+       // ports before the EHCI module discovers them.
        const char *moduleNames[] = {
+               "busses/usb/xhci",
                "busses/usb/uhci",
                "busses/usb/ohci",
                "busses/usb/ehci",
-               "busses/usb/xhci",
                NULL
        };
 
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/src/add-ons/kernel/bus_managers/usb/usb_private.h
+++ b/src/add-ons/kernel/bus_managers/usb/usb_private.h
@@ -579,7 +579,8 @@ public:
                                                                                
        uint8 hubPort,
                                                                                
        usb_device_descriptor &desc,
                                                                                
        int8 deviceAddress,
-                                                                               
        usb_speed speed, bool isRootHub);
+                                                                               
        usb_speed speed, bool isRootHub,
+                                                                               
        void *controllerCookie = NULL);
 virtual                                                                        
~Hub();
 
 virtual        status_t                                                
Changed(change_item **changeList,
diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp 
b/src/add-ons/kernel/busses/usb/xhci.cpp
index f53f721..50b11ef 100644
--- a/src/add-ons/kernel/busses/usb/xhci.cpp
+++ b/src/add-ons/kernel/busses/usb/xhci.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2012, Haiku Inc. All rights reserved.
+ * Copyright 2006-2014, Haiku Inc. All rights reserved.
  * Distributed under the terms of the MIT License.
  *
  * Some code borrowed from the Haiku EHCI driver
@@ -8,6 +8,7 @@
  *             Michael Lotz <mmlr@xxxxxxxx>
  *             Jian Chiang <j.jian.chiang@xxxxxxxxx>
  *             Jérôme Duval <jerome.duval@xxxxxxxxx>
+ *             Akshay Jaggi <akshay1994.leo@xxxxxxxxx>
  */
 
 
@@ -174,8 +175,9 @@ XHCI::XHCI(pci_info *info, Stack *stack)
 
        uint32 hciCapLength = ReadCapReg32(XHCI_HCI_CAPLENGTH);
        fCapabilityRegisters += offset;
+       fCapabilityLength = HCI_CAPLENGTH(hciCapLength);
        TRACE("mapped capability length: 0x%" B_PRIx32 "\n", fCapabilityLength);
-       fOperationalRegisters = fCapabilityRegisters + 
HCI_CAPLENGTH(hciCapLength);
+       fOperationalRegisters = fCapabilityRegisters + fCapabilityLength;
        fRuntimeRegisters = fCapabilityRegisters + ReadCapReg32(XHCI_RTSOFF);
        fDoorbellRegisters = fCapabilityRegisters + ReadCapReg32(XHCI_DBOFF);
        TRACE("mapped capability registers: 0x%p\n", fCapabilityRegisters);
@@ -199,37 +201,69 @@ XHCI::XHCI(pci_info *info, Stack *stack)
                eec = ReadCapReg32(eecp);
                if (XECP_ID(eec) != XHCI_LEGSUP_CAPID)
                        continue;
-       }
-       TRACE("eecp register: 0x%04" B_PRIx32 "\n", eecp);
-       if (eec & XHCI_LEGSUP_BIOSOWNED) {
-               TRACE_ALWAYS("the host controller is bios owned, claiming"
-                       " ownership\n");
-               WriteCapReg32(eecp, eec | XHCI_LEGSUP_OSOWNED);
-
-               for (int32 i = 0; i < 20; i++) {
-                       eec = ReadCapReg32(eecp);
-
-                       if ((eec & XHCI_LEGSUP_BIOSOWNED) == 0)
-                               break;
-
-                       TRACE_ALWAYS("controller is still bios owned, 
waiting\n");
-                       snooze(50000);
-               }
-
+                               
+               TRACE("eecp register: 0x%08" B_PRIx32 "\n", eecp);
                if (eec & XHCI_LEGSUP_BIOSOWNED) {
-                       TRACE_ERROR("bios won't give up control over the host "
-                               "controller (ignoring)\n");
-               } else if (eec & XHCI_LEGSUP_OSOWNED) {
-                       TRACE_ALWAYS("successfully took ownership of the host "
-                               "controller\n");
+                       TRACE_ALWAYS("the host controller is bios owned, 
claiming"
+                               " ownership\n");
+                       WriteCapReg32(eecp, eec | XHCI_LEGSUP_OSOWNED);
+       
+                       for (int32 i = 0; i < 20; i++) {
+                               eec = ReadCapReg32(eecp);
+       
+                               if ((eec & XHCI_LEGSUP_BIOSOWNED) == 0)
+                                       break;
+       
+                               TRACE_ALWAYS("controller is still bios owned, 
waiting\n");
+                               snooze(50000);
+                       }
+       
+                       if (eec & XHCI_LEGSUP_BIOSOWNED) {
+                               TRACE_ERROR("bios won't give up control over 
the host "
+                                       "controller (ignoring)\n");
+                       } else if (eec & XHCI_LEGSUP_OSOWNED) {
+                               TRACE_ALWAYS("successfully took ownership of 
the host "
+                                       "controller\n");
+                       }
+       
+                       // Force off the BIOS owned flag, and clear all SMIs. 
Some BIOSes
+                       // do indicate a successful handover but do not remove 
their SMIs
+                       // and then freeze the system when interrupts are 
generated.
+                       WriteCapReg32(eecp, eec & ~XHCI_LEGSUP_BIOSOWNED);
                }
-
-               // Force off the BIOS owned flag, and clear all SMIs. Some 
BIOSes
-               // do indicate a successful handover but do not remove their 
SMIs
-               // and then freeze the system when interrupts are generated.
-               WriteCapReg32(eecp, eec & ~XHCI_LEGSUP_BIOSOWNED);
+               break;
+       }
+       uint32 legctlsts = ReadCapReg32(eecp + XHCI_LEGCTLSTS);
+       legctlsts &= XHCI_LEGCTLSTS_DISABLE_SMI;
+       legctlsts |= XHCI_LEGCTLSTS_EVENTS_SMI;
+       WriteCapReg32(eecp + XHCI_LEGCTLSTS, legctlsts);
+
+       // On Intel's Panther Point and Lynx Point Chipset taking ownership 
+       // of EHCI owned ports, is what we do here.
+       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)) {
+               
+               TRACE("Intel xHC Controller\n");
+               TRACE("Looking for EHCI owned ports\n");
+               uint32 ports = sPCIModule->read_pci_config(fPCIInfo->bus,
+                       fPCIInfo->device, fPCIInfo->function, 
XHCI_INTEL_USB3PRM, 4);           
+               TRACE("Superspeed Ports: 0x%" B_PRIx32 "\n", ports);
+               sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device,
+                       fPCIInfo->function, XHCI_INTEL_USB3_PSSEN, 4, ports);
+               ports = sPCIModule->read_pci_config(fPCIInfo->bus,
+                       fPCIInfo->device, fPCIInfo->function, 
XHCI_INTEL_USB3_PSSEN, 4);
+               TRACE("Superspeed ports now under XHCI : 0x%" B_PRIx32 "\n", 
ports);
+               ports = sPCIModule->read_pci_config(fPCIInfo->bus,
+                       fPCIInfo->device, fPCIInfo->function, 
XHCI_INTEL_USB2PRM, 4);
+               TRACE("USB 2.0 Ports : 0x%" B_PRIx32 "\n", ports);
+               sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device,
+                       fPCIInfo->function, XHCI_INTEL_XUSB2PR, 4, ports);
+               ports = sPCIModule->read_pci_config(fPCIInfo->bus,
+                       fPCIInfo->device, fPCIInfo->function, 
XHCI_INTEL_XUSB2PR, 4);
+               TRACE("USB 2.0 ports now under XHCI: 0x%" B_PRIx32 "\n", ports);
        }
-       WriteCapReg32(eecp + XHCI_LEGCTLSTS, XHCI_LEGCTLSTS_DISABLE_SMI);
 
        // halt the host controller
        if (ControllerHalt() < B_OK) {
@@ -337,8 +371,7 @@ XHCI::Start()
        }
 
        // read port count from capability register
-       uint32 capabilities = ReadCapReg32(XHCI_HCSPARAMS1);
-
+       uint32 capabilities = ReadCapReg32(XHCI_HCSPARAMS1);    
        fPortCount = HCS_MAX_PORTS(capabilities);
        if (fPortCount == 0) {
                TRACE_ERROR("Invalid number of ports: %u\n", fPortCount);
@@ -573,15 +606,25 @@ XHCI::SubmitControlRequest(Transfer *transfer)
 
        xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie();
        uint8 id = XHCI_ENDPOINT_ID(pipe);
-       if (id >= XHCI_MAX_ENDPOINTS)
+       if (id >= XHCI_MAX_ENDPOINTS) {
+               TRACE_ERROR("Invalid Endpoint");
                return B_BAD_VALUE;
+       }
        setupDescriptor->transfer = transfer;
+       transfer->InitKernelAccess();
        _LinkDescriptorForPipe(setupDescriptor, endpoint);
 
        TRACE("SubmitControlRequest() request linked\n");
 
+       TRACE("Endpoint status 0x%" B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx64 
"\n", 
+               endpoint->device->device_ctx->endpoints[id-1].dwendpoint0,
+               endpoint->device->device_ctx->endpoints[id-1].dwendpoint1,
+               endpoint->device->device_ctx->endpoints[id-1].qwendpoint2);
        Ring(endpoint->device->slot, id);
-
+       TRACE("Endpoint status 0x%" B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx64 
"\n", 
+               endpoint->device->device_ctx->endpoints[id-1].dwendpoint0,
+               endpoint->device->device_ctx->endpoints[id-1].dwendpoint1,
+               endpoint->device->device_ctx->endpoints[id-1].qwendpoint2);
        return B_OK;
 }
 
@@ -625,11 +668,20 @@ XHCI::SubmitNormalRequest(Transfer *transfer)
 
        xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie();
        descriptor->transfer = transfer;
+       transfer->InitKernelAccess();
        _LinkDescriptorForPipe(descriptor, endpoint);
 
        TRACE("SubmitNormalRequest() request linked\n");
 
+       TRACE("Endpoint status 0x%" B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx64 
"\n", 
+               endpoint->device->device_ctx->endpoints[id - 1].dwendpoint0,
+               endpoint->device->device_ctx->endpoints[id - 1].dwendpoint1,
+               endpoint->device->device_ctx->endpoints[id - 1].qwendpoint2);
        Ring(endpoint->device->slot, id);
+       TRACE("Endpoint status 0x%" B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx64 
"\n",
+               endpoint->device->device_ctx->endpoints[id - 1].dwendpoint0,
+               endpoint->device->device_ctx->endpoints[id - 1].dwendpoint1,
+               endpoint->device->device_ctx->endpoints[id - 1].qwendpoint2);
 
        return B_OK;
 }
@@ -994,6 +1046,7 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 
hubPort,
                "XHCI input context");
        if (device->input_ctx_area < B_OK) {
                TRACE_ERROR("unable to create a input context area\n");
+               device->state = XHCI_STATE_DISABLED;
                return NULL;
        }
 
@@ -1003,7 +1056,7 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 
hubPort,
 
        uint32 route = 0;
        uint8 routePort = hubPort;
-       uint8 rhPort = 0;
+       uint8 rhPort = hubPort;
        for (Device *hubDevice = parent; hubDevice != RootObject();
                hubDevice = (Device *)hubDevice->Parent()) {
 
@@ -1020,8 +1073,6 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 
hubPort,
        }
 
        device->input_ctx->slot.dwslot0 = SLOT_0_NUM_ENTRIES(1) | 
SLOT_0_ROUTE(route);
-       //device->input_ctx->slot.dwslot0 =
-       //      SLOT_0_NUM_ENTRIES(XHCI_MAX_ENDPOINTS - 1) | 
SLOT_0_ROUTE(route);
 
        // add the speed
        switch (speed) {
@@ -1059,15 +1110,18 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, 
uint8 hubPort,
                "XHCI device context");
        if (device->device_ctx_area < B_OK) {
                TRACE_ERROR("unable to create a device context area\n");
+               device->state = XHCI_STATE_DISABLED;            
                delete_area(device->input_ctx_area);
                return NULL;
        }
        memset(device->device_ctx, 0, sizeof(*device->device_ctx));
 
        device->trb_area = fStack->AllocateArea((void **)&device->trbs,
-               &device->trb_addr, sizeof(*device->trbs), "XHCI endpoint trbs");
+               &device->trb_addr, sizeof(*device->trbs) * (XHCI_MAX_ENDPOINTS 
- 1)
+                       * XHCI_MAX_TRANSFERS, "XHCI endpoint trbs");
        if (device->trb_area < B_OK) {
                TRACE_ERROR("unable to create a device trbs area\n");
+               device->state = XHCI_STATE_DISABLED;
                delete_area(device->input_ctx_area);
                delete_area(device->device_ctx_area);
                return NULL;
@@ -1102,6 +1156,10 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 
hubPort,
        if (ConfigureEndpoint(slot, 0, 4, device->trb_addr, 0, 1, 1, 0,
                maxPacketSize, maxPacketSize, speed) != B_OK) {
                TRACE_ERROR("unable to configure default control endpoint\n");
+               device->state = XHCI_STATE_DISABLED;
+               delete_area(device->input_ctx_area);
+               delete_area(device->device_ctx_area);
+               delete_area(device->trb_area);
                return NULL;
        }
 
@@ -1116,6 +1174,10 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 
hubPort,
        // device should get to addressed state (bsr = 0)
        if (SetAddress(device->input_ctx_addr, false, slot) != B_OK) {
                TRACE_ERROR("unable to set address\n");
+               device->state = XHCI_STATE_DISABLED;
+               delete_area(device->input_ctx_area);
+               delete_area(device->device_ctx_area);
+               delete_area(device->trb_area);
                return NULL;
        }
 
@@ -1154,6 +1216,10 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 
hubPort,
 
        if (actualLength != 8) {
                TRACE_ERROR("error while getting the device descriptor\n");
+               device->state = XHCI_STATE_DISABLED;
+               delete_area(device->input_ctx_area);
+               delete_area(device->device_ctx_area);
+               delete_area(device->trb_area);
                return NULL;
        }
 
@@ -1161,11 +1227,51 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, 
uint8 hubPort,
                deviceDescriptor.device_class, deviceDescriptor.device_subclass,
                deviceDescriptor.device_protocol);
 
-       TRACE("creating new device\n");
-       Device *deviceObject = new(std::nothrow) Device(parent, hubAddress, 
hubPort,
-               deviceDescriptor, device->address + 1, speed, false, device);
-       if (!deviceObject) {
+       Device *deviceObject = NULL;
+       if (deviceDescriptor.device_class == 0x09) {
+               TRACE("creating new Hub\n");
+               TRACE("getting the hub descriptor\n");
+               size_t actualLength = 0;
+               usb_hub_descriptor hubDescriptor;
+               pipe.SendRequest(
+                       USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD,           
// type
+                       USB_REQUEST_GET_DESCRIPTOR,                             
                        // request
+                       USB_DESCRIPTOR_HUB << 8,                                
                        // value
+                       0,                                                      
                                                // index
+                       sizeof(usb_hub_descriptor),                             
                        // length
+                       (void *)&hubDescriptor,                                 
                        // buffer
+                       sizeof(usb_hub_descriptor),                             
                        // buffer length
+                       &actualLength);
+               
+               if (actualLength != sizeof(usb_hub_descriptor)) {
+                       TRACE_ERROR("error while getting the hub descriptor\n");
+                       device->state = XHCI_STATE_DISABLED;
+                       delete_area(device->input_ctx_area);
+                       delete_area(device->device_ctx_area);
+                       delete_area(device->trb_area);
+                       return NULL;
+               }
+               
+               device->input_ctx->slot.dwslot0 |= SLOT_0_HUB_BIT;
+               device->input_ctx->slot.dwslot1 |= 
SLOT_1_NUM_PORTS(hubDescriptor.num_ports);
+               if (speed == USB_SPEED_HIGHSPEED) {
+                       device->input_ctx->slot.dwslot2 |=
+                               
SLOT_2_TT_TIME(HUB_TTT_GET(hubDescriptor.characteristics)); 
+               }
+               
+               deviceObject = new(std::nothrow) Hub(parent, hubAddress, 
hubPort,
+                       deviceDescriptor, device->address + 1, speed, false, 
device);
+       } else {
+               TRACE("creating new device\n");
+               deviceObject = new(std::nothrow) Device(parent, hubAddress, 
hubPort,
+                       deviceDescriptor, device->address + 1, speed, false, 
device);
+       }
+       if (deviceObject == NULL) {
                TRACE_ERROR("no memory to allocate device\n");
+               device->state = XHCI_STATE_DISABLED;
+               delete_area(device->input_ctx_area);
+               delete_area(device->device_ctx_area);
+               delete_area(device->trb_area);
                return NULL;
        }
        fPortSlots[hubPort] = slot;
@@ -1193,6 +1299,8 @@ XHCI::FreeDevice(Device *device)
 status_t
 XHCI::_InsertEndpointForPipe(Pipe *pipe)
 {
+       TRACE("_InsertEndpointForPipe endpoint address %" B_PRId8 "\n", 
+               pipe->EndpointAddress());
        if (pipe->ControllerCookie() != NULL
                || pipe->Parent()->Type() != USB_OBJECT_DEVICE) {
                // default pipe is already referenced
@@ -1303,8 +1411,10 @@ XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, 
xhci_endpoint *endpoint)
 {
        TRACE("_LinkDescriptorForPipe\n");
        MutexLocker endpointLocker(endpoint->lock);
-       if (endpoint->used >= XHCI_MAX_TRANSFERS)
+       if (endpoint->used >= XHCI_MAX_TRANSFERS) {
+               TRACE_ERROR("_LinkDescriptorForPipe max transfers count 
exceeded\n");
                return B_BAD_VALUE;
+       }
 
        endpoint->used++;
        if (endpoint->td_head == NULL)
@@ -1468,7 +1578,7 @@ XHCI::GetPortStatus(uint8 index, usb_port_status *status)
 
        status->status = status->change = 0;
        uint32 portStatus = ReadOpReg(XHCI_PORTSC(index));
-       //TRACE("port status=0x%08lx\n", portStatus);
+       TRACE("port %" B_PRId8 " status=0x%08" B_PRIx32 "\n", index, 
portStatus);
 
        // build the status
        switch (PS_SPEED_GET(portStatus)) {
@@ -1767,8 +1877,8 @@ XHCI::HandleTransferComplete(xhci_trb *trb)
 {
        TRACE("HandleTransferComplete trb %p\n", trb);
        addr_t source = trb->qwtrb0;
-       //uint8 completionCode = TRB_2_COMP_CODE_GET(trb->dwtrb2);
-       //uint32 remainder = TRB_2_REM_GET(trb->dwtrb2);
+       uint8 completionCode = TRB_2_COMP_CODE_GET(trb->dwtrb2);
+       uint32 remainder = TRB_2_REM_GET(trb->dwtrb2);
        uint8 endpointNumber = TRB_3_ENDPOINT_GET(trb->dwtrb3);
        uint8 slot = TRB_3_SLOT_GET(trb->dwtrb3);
 
@@ -1785,7 +1895,8 @@ XHCI::HandleTransferComplete(xhci_trb *trb)
                        offset);
                (void)offset;
                _UnlinkDescriptorForPipe(td, endpoint);
-
+               td->trb_completion_code = completionCode;
+               td->trb_left = remainder;
                // add descriptor to finished list (to be processed and freed)
                Lock();
                td->next = fFinishedHead;
@@ -1838,6 +1949,7 @@ XHCI::DoCommand(xhci_trb *trb)
 status_t
 XHCI::Noop()
 {
+       TRACE("Noop\n");
        xhci_trb trb;
        trb.qwtrb0 = 0;
        trb.dwtrb2 = 0;
@@ -1850,6 +1962,7 @@ XHCI::Noop()
 status_t
 XHCI::EnableSlot(uint8 *slot)
 {
+       TRACE("Enable Slot\n");
        xhci_trb trb;
        trb.qwtrb0 = 0;
        trb.dwtrb2 = 0;
@@ -1867,6 +1980,7 @@ XHCI::EnableSlot(uint8 *slot)
 status_t
 XHCI::DisableSlot(uint8 slot)
 {
+       TRACE("Disable Slot\n");
        xhci_trb trb;
        trb.qwtrb0 = 0;
        trb.dwtrb2 = 0;
@@ -1879,6 +1993,7 @@ XHCI::DisableSlot(uint8 slot)
 status_t
 XHCI::SetAddress(uint64 inputContext, bool bsr, uint8 slot)
 {
+       TRACE("Set Address\n");
        xhci_trb trb;
        trb.qwtrb0 = inputContext;
        trb.dwtrb2 = 0;
@@ -1894,6 +2009,7 @@ XHCI::SetAddress(uint64 inputContext, bool bsr, uint8 
slot)
 status_t
 XHCI::ConfigureEndpoint(uint64 inputContext, bool deconfigure, uint8 slot)
 {
+       TRACE("Configure Endpoint\n");
        xhci_trb trb;
        trb.qwtrb0 = inputContext;
        trb.dwtrb2 = 0;
@@ -1909,6 +2025,7 @@ XHCI::ConfigureEndpoint(uint64 inputContext, bool 
deconfigure, uint8 slot)
 status_t
 XHCI::EvaluateContext(uint64 inputContext, uint8 slot)
 {
+       TRACE("Evaluate Context\n");
        xhci_trb trb;
        trb.qwtrb0 = inputContext;
        trb.dwtrb2 = 0;
@@ -1921,6 +2038,7 @@ XHCI::EvaluateContext(uint64 inputContext, uint8 slot)
 status_t
 XHCI::ResetEndpoint(bool preserve, uint8 endpoint, uint8 slot)
 {
+       TRACE("Reset Endpoint\n");
        xhci_trb trb;
        trb.qwtrb0 = 0;
        trb.dwtrb2 = 0;
@@ -1936,6 +2054,7 @@ XHCI::ResetEndpoint(bool preserve, uint8 endpoint, uint8 
slot)
 status_t
 XHCI::StopEndpoint(bool suspend, uint8 endpoint, uint8 slot)
 {
+       TRACE("Stop Endpoint\n");
        xhci_trb trb;
        trb.qwtrb0 = 0;
        trb.dwtrb2 = 0;
@@ -1951,6 +2070,7 @@ XHCI::StopEndpoint(bool suspend, uint8 endpoint, uint8 
slot)
 status_t
 XHCI::SetTRDequeue(uint64 dequeue, uint16 stream, uint8 endpoint, uint8 slot)
 {
+       TRACE("Set TR Dequeue\n");
        xhci_trb trb;
        trb.qwtrb0 = dequeue;
        trb.dwtrb2 = TRB_2_STREAM(stream);
@@ -1964,6 +2084,7 @@ XHCI::SetTRDequeue(uint64 dequeue, uint16 stream, uint8 
endpoint, uint8 slot)
 status_t
 XHCI::ResetDevice(uint8 slot)
 {
+       TRACE("Reset Device\n");
        xhci_trb trb;
        trb.qwtrb0 = 0;
        trb.dwtrb2 = 0;
@@ -2000,6 +2121,9 @@ XHCI::CompleteEvents()
 
                while (1) {
                        uint32 temp = fEventRing[i].dwtrb3;
+                       TRACE_ALWAYS("event[%u] = %u (0x%016" B_PRIx64 " 0x%08" 
B_PRIx32 " 0x%08"
+                               B_PRIx32 ")\n", i, (uint8)TRB_3_TYPE_GET(temp), 
fEventRing[i].qwtrb0,
+                               fEventRing[i].dwtrb2, fEventRing[i].dwtrb3);
                        uint8 k = (temp & TRB_3_CYCLE_BIT) ? 1 : 0;
                        if (j != k)
                                break;
@@ -2073,28 +2197,61 @@ XHCI::FinishTransfers()
                        td->next = NULL;
                        Unlock();
 
+                       TRACE("finishing transfer td %p\n", td);
+                       
                        Transfer* transfer = td->transfer;
                        bool directionIn = 
(transfer->TransferPipe()->Direction() != Pipe::Out);
                        usb_request_data *requestData = transfer->RequestData();
-
-                       // TODO check event
+                       
                        status_t callbackStatus = B_OK;
-                       size_t actualLength = requestData ? requestData->Length
-                               : transfer->DataLength();
-                       TRACE("finishing transfer td %p\n", td);
-                       if (directionIn && actualLength > 0) {
-                               if (requestData) {
-                                       TRACE("copying in data %d bytes\n", 
requestData->Length);
-                                       memcpy((uint8 
*)transfer->Vector()[0].iov_base,
-                                               td->buffer_log[0], 
requestData->Length);
-                               } else {
-                                       TRACE("copying in iov count %ld\n", 
transfer->VectorCount());
-                                       ReadDescriptorChain(td, 
transfer->Vector(),
-                                               transfer->VectorCount());
+                       switch (td->trb_completion_code) {
+                               case COMP_SHORT_PACKET:
+                               case COMP_SUCCESS:
+                                       callbackStatus = B_OK;
+                                       break;
+                               case COMP_DATA_BUFFER:
+                                       callbackStatus = directionIn ? 
B_DEV_DATA_OVERRUN
+                                               : B_DEV_DATA_UNDERRUN;
+                                       break;
+                               case COMP_BABBLE:
+                                       callbackStatus = directionIn ? 
B_DEV_FIFO_OVERRUN
+                                               : B_DEV_FIFO_UNDERRUN;
+                                       break;
+                               case COMP_USB_TRANSACTION:
+                                       callbackStatus = B_DEV_CRC_ERROR;
+                                       break;
+                               case COMP_STALL:
+                                       callbackStatus = B_DEV_STALLED;
+                                       break;
+                               default:
+                                       callbackStatus = B_DEV_STALLED;
+                                       break;
+                       }
+                       
+                       size_t actualLength = 0;
+                       if (callbackStatus == B_OK) {
+                               actualLength = requestData ? requestData->Length
+                                       : transfer->DataLength();
+                                       
+                               if (td->trb_completion_code == 
COMP_SHORT_PACKET)
+                                       actualLength -= td->trb_left;
+       
+                               if (directionIn && actualLength > 0) {
+                                       if (requestData) {
+                                               TRACE("copying in data %d 
bytes\n", requestData->Length);
+                                               transfer->PrepareKernelAccess();
+                                               memcpy((uint8 
*)transfer->Vector()[0].iov_base,
+                                                       td->buffer_log[0], 
requestData->Length);
+                                       } else {
+                                               TRACE("copying in iov count 
%ld\n", transfer->VectorCount());
+                                               transfer->PrepareKernelAccess();
+                                               ReadDescriptorChain(td, 
transfer->Vector(),
+                                                       
transfer->VectorCount());
+                                       }
                                }
                        }
-                       transfer->Finished(callbackStatus, actualLength);
-
+                       transfer->Finished(callbackStatus, actualLength);       
                                        
+                       delete transfer;
                        FreeDescriptor(td);
                        Lock();
                }
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/src/add-ons/kernel/busses/usb/xhci.h
+++ b/src/add-ons/kernel/busses/usb/xhci.h
@@ -45,6 +45,8 @@ typedef struct xhci_td {
        struct xhci_td  *next;
        Transfer *transfer;
        uint8   trb_count;
+       uint8   trb_completion_code;
+       uint32  trb_left;
 } xhci_td __attribute__((__aligned__(16)));
 
 
diff --git a/src/add-ons/kernel/busses/usb/xhci_hardware.h 
b/src/add-ons/kernel/busses/usb/xhci_hardware.h
index ebd3d43..05904d8 100644
--- a/src/add-ons/kernel/busses/usb/xhci_hardware.h
+++ b/src/add-ons/kernel/busses/usb/xhci_hardware.h
@@ -5,10 +5,22 @@
  * Authors:
  *             Jian Chiang <j.jian.chiang@xxxxxxxxx>
  *             Jérôme Duval <jerome.duval@xxxxxxxxx>
+ *             Akshay Jaggi <akshay1994.leo@xxxxxxxxx>
  */
 #ifndef XHCI_HARDWARE_H
 #define XHCI_HARDWARE_H
 
+// PCI IDs
+#define        PCI_VENDOR_INTEL                                                
0x8086
+#define        PCI_DEVICE_INTEL_PANTHER_POINT_XHCI             0x1e31
+#define        PCI_DEVICE_INTEL_LYNX_POINT_XHCI                0x8c31
+#define        PCI_DEVICE_INTEL_LYNX_POINT_LP_XHCI             0x9c31
+
+// Intel quirks registers in PCI config
+#define        XHCI_INTEL_USB3PRM                              0xdc    // USB 
3.0 Port Routing Mask
+#define        XHCI_INTEL_USB3_PSSEN                   0xd8    // USB 3.0 Port 
SuperSpeed Enable
+#define        XHCI_INTEL_USB2PRM                              0xd4    // USB 
2.0 Port Routing Mask
+#define        XHCI_INTEL_XUSB2PR                              0xd0    // USB 
2.0 Port Routing
 
 // Host Controller Capability Registers
 #define XHCI_HCI_CAPLENGTH     0x00            // HCI Capability Register 
Length
@@ -17,12 +29,12 @@
 #define XHCI_HCSPARAMS1                0x04            // Structural 
Parameters 1
 // HCSPARAMS1
 #define HCS_MAX_SLOTS(p)               (((p) >> 0) & 0xff)
-#define HCS_MAX_PORTS(p)               (((p) >> 24) & 0x7f)
+#define HCS_MAX_PORTS(p)               (((p) >> 24) & 0xff)
 #define XHCI_HCSPARAMS2                0x08            // Structural 
Parameters 2
 #define HCS_IST(p)                             (((p) >> 0) & 0xf)
 #define HCS_ERST_MAX(p)                        (((p) >> 4) & 0xf)
 #define HCS_SPR(p)                             (((p) >> 26) & 0x1)
-#define HCS_MAX_SC_BUFFERS(p)  (((p) >> 27) & 0x1f)
+#define HCS_MAX_SC_BUFFERS(p)  (((((p) >> 21) & 0x1f)<<5)|(((p) >> 27) & 0x1f))
 #define XHCI_HCSPARAMS3                0x0C            // Structural 
Parameters 3
 #define HCS_U1_DEVICE_LATENCY(p)       (((p) >> 0) & 0xff)
 #define HCS_U2_DEVICE_LATENCY(p)       (((p) >> 16) & 0xffff)
@@ -98,7 +110,8 @@
 #define XHCI_LEGSUP_BIOSOWNED  (1 << 16)       // BIOS Owned Semaphore
 
 #define XHCI_LEGCTLSTS                 0x04
-#define XHCI_LEGCTLSTS_DISABLE_SMI     ((0x3 << 1) + (0xff << 5) + (0x7 << 17))
+#define XHCI_LEGCTLSTS_DISABLE_SMI     ((0x7 << 1) + (0xff << 5) + (0x7 << 17))
+#define XHCI_LEGCTLSTS_EVENTS_SMI (0x7 << 29)
 
 #define XHCI_SUPPORTED_PROTOCOLS_CAPID 0x02
 #define XHCI_SUPPORTED_PROTOCOLS_0_MINOR(x)    (((x) >> 16) & 0xff)
@@ -336,14 +349,15 @@ struct xhci_slot_ctx {
 #define SLOT_2_PORT_NUM_GET(x)                 (((x) >> 8) & 0xFF)
 #define SLOT_2_TT_TIME(x)                              (((x) & 0x3) << 16)
 #define SLOT_2_TT_TIME_GET(x)                  (((x) >> 16) & 0x3)
-#define SLOT_2_IRQ_TARGET(x)                           (((x) & 0x1F) << 27)
-#define SLOT_2_IRQ_TARGET_GET(x)                       (((x) >> 27) & 0x1f)
+#define SLOT_2_IRQ_TARGET(x)                           (((x) & 0x7F) << 22)
+#define SLOT_2_IRQ_TARGET_GET(x)                       (((x) >> 22) & 0x7F)
 
 #define SLOT_3_DEVICE_ADDRESS(x)               ((x) & 0xFF)
 #define SLOT_3_DEVICE_ADDRESS_GET(x)   ((x) & 0xFF)
 #define SLOT_3_SLOT_STATE(x)                   (((x) & 0x1F) << 27)
 #define SLOT_3_SLOT_STATE_GET(x)               (((x) >> 27) & 0x1F)
 
+#define        HUB_TTT_GET(x)                                  (((x) >> 5) & 
0x3)
 
 struct xhci_endpoint_ctx {
        uint32  dwendpoint0;
diff --git a/src/add-ons/kernel/network/protocols/udp/udp.cpp 
b/src/add-ons/kernel/network/protocols/udp/udp.cpp
index 97926b1..d19474e 100644
--- a/src/add-ons/kernel/network/protocols/udp/udp.cpp
+++ b/src/add-ons/kernel/network/protocols/udp/udp.cpp
@@ -223,10 +223,12 @@ public:
 
                        status_t                        InitCheck() const;
 
-                       status_t                        ReceiveData(net_buffer* 
buffer);
+                       status_t                        ReceiveData(net_buffer* 
buffer,
+                                                                       bool 
isUDPLite = false);
                        status_t                        ReceiveError(status_t 
error,
                                                                        
net_buffer* buffer);
-                       status_t                        Deframe(net_buffer* 
buffer);
+                       status_t                        Deframe(net_buffer* 
buffer,
+                                                                       bool 
isUDPLite = false);
 
                        UdpDomainSupport*       OpenEndpoint(UdpEndpoint* 
endpoint);
                        status_t                        
FreeEndpoint(UdpDomainSupport* domain);
@@ -692,7 +694,7 @@ UdpEndpointManager::DumpEndpoints(int argc, char *argv[])
 
 
 status_t
-UdpEndpointManager::ReceiveData(net_buffer *buffer)
+UdpEndpointManager::ReceiveData(net_buffer *buffer, bool isUDPLite)
 {
        TRACE_EPM("ReceiveData(%p [%" B_PRIu32 " bytes])", buffer, 
buffer->size);
 
@@ -703,7 +705,7 @@ UdpEndpointManager::ReceiveData(net_buffer *buffer)
                return B_ERROR;
        }
 
-       status_t status = Deframe(buffer);
+       status_t status = Deframe(buffer, isUDPLite);
        if (status != B_OK)
                return status;
 
@@ -759,7 +761,7 @@ UdpEndpointManager::ReceiveError(status_t error, 
net_buffer* buffer)
 
 
 status_t
-UdpEndpointManager::Deframe(net_buffer* buffer)
+UdpEndpointManager::Deframe(net_buffer* buffer, bool isUDPLite)
 {
        TRACE_EPM("Deframe(%p [%ld bytes])", buffer, buffer->size);
 
@@ -786,26 +788,33 @@ UdpEndpointManager::Deframe(net_buffer* buffer)
        TRACE_EPM("  Deframe(): data from %s to %s", 
source.AsString(true).Data(),
                destination.AsString(true).Data());
 
+       bool liteCheck = isUDPLite;
        uint16 udpLength = ntohs(header.udp_length);
+       if (isUDPLite && udpLength == 0) {
+               udpLength = buffer->size;
+               liteCheck = false;
+       }
        if (udpLength > buffer->size) {
                TRACE_EPM("  Deframe(): buffer is too short, expected %hu.",
                        udpLength);
                return B_MISMATCHED_VALUES;
        }
 
-       if (buffer->size > udpLength)
+       if (!isUDPLite && buffer->size > udpLength)
                gBufferModule->trim(buffer, udpLength);
 
        if (header.udp_checksum != 0) {
                // check UDP-checksum (simulating a so-called "pseudo-header"):
                uint16 sum = Checksum::PseudoHeader(addressModule, 
gBufferModule,
-                       buffer, IPPROTO_UDP);
+                       buffer, isUDPLite ? IPPROTO_UDPLITE : IPPROTO_UDP);
                if (sum != 0) {
                        TRACE_EPM("  Deframe(): bad checksum 0x%hx.", sum);
                        return B_BAD_VALUE;
                }
        }
 
+       // TODO check for udpLength < configured min length
+       
        bufferHeader.Remove();
                // remove UDP-header from buffer before passing it on
 
@@ -991,7 +1000,7 @@ UdpEndpoint::SendRoutedData(net_buffer *buffer, net_route 
*route)
        if (buffer->size > (0xffff - sizeof(udp_header)))
                return EMSGSIZE;
 
-       buffer->protocol = IPPROTO_UDP;
+       buffer->protocol = Socket()->protocol;
 
        // add and fill UDP-specific header:
        NetBufferPrepend<udp_header> header(buffer);
@@ -1071,7 +1080,7 @@ UdpEndpoint::DeliverData(net_buffer *_buffer)
        if (buffer == NULL)
                return B_NO_MEMORY;
 
-       status_t status = sUdpEndpointManager->Deframe(buffer);
+       status_t status = sUdpEndpointManager->Deframe(buffer, 
Socket()->protocol);
        if (status < B_OK) {
                gBufferModule->free(buffer);
                return status;
@@ -1111,6 +1120,21 @@ udp_init_protocol(net_socket *socket)
 }
 
 
+net_protocol *
+udplite_init_protocol(net_socket *socket)
+{      
+       UdpEndpoint *endpoint = new (std::nothrow) UdpEndpoint(socket);
+       if (endpoint == NULL || endpoint->InitCheck() < B_OK) {
+               delete endpoint;
+               return NULL;
+       }
+       
+       socket->protocol = IPPROTO_UDPLITE;
+
+       return endpoint;
+}
+
+
 status_t
 udp_uninit_protocol(net_protocol *protocol)
 {
@@ -1268,6 +1292,13 @@ udp_receive_data(net_buffer *buffer)
 
 
 status_t
+udplite_receive_data(net_buffer *buffer)
+{
+       return sUdpEndpointManager->ReceiveData(buffer, true);
+}
+
+
+status_t
 udp_deliver_data(net_protocol *protocol, net_buffer *buffer)
 {
        return ((UdpEndpoint *)protocol)->DeliverData(buffer);
@@ -1465,6 +1496,48 @@ net_protocol_module_info sUDPModule = {
        NULL            // read_data_no_buffer()
 };
 
+
+net_protocol_module_info sUDPLiteModule = {
+       {
+               "network/protocols/udplite/v1",
+               0,
+               NULL
+       },
+       NET_PROTOCOL_ATOMIC_MESSAGES,
+
+       udplite_init_protocol,
+       udp_uninit_protocol,
+       udp_open,
+       udp_close,
+       udp_free,
+       udp_connect,
+       udp_accept,
+       udp_control,
+       udp_getsockopt,
+       udp_setsockopt,
+       udp_bind,
+       udp_unbind,
+       udp_listen,
+       udp_shutdown,
+       udp_send_data,
+       udp_send_routed_data,
+       udp_send_avail,
+       udp_read_data,
+       udp_read_avail,
+       udp_get_domain,
+       udp_get_mtu,
+       udplite_receive_data,
+       udp_deliver_data,
+       udp_error_received,
+       udp_error_reply,
+       NULL,           // add_ancillary_data()
+       NULL,           // process_ancillary_data()
+       udp_process_ancillary_data_no_container,
+       NULL,           // send_data_no_buffer()
+       NULL            // read_data_no_buffer()
+};
+
+
 module_dependency module_dependencies[] = {
        {NET_STACK_MODULE_NAME, (module_info **)&gStackModule},
        {NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule},


Other related posts: