Changeset 2cf28b9 in mainline


Ignore:
Timestamp:
2017-10-25T15:22:45Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
62558202
Parents:
f668d60
Message:

xhci: connecting devices deeper than to roothub

It still does not work, because the address command fails, but there should not be any fundamental problem.

Location:
uspace
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/bus.c

    rf668d60 r2cf28b9  
    4545#include <stdbool.h>
    4646
     47#include "hc.h"
    4748#include "bus.h"
    4849#include "endpoint.h"
     
    136137        }
    137138
     139        /* Calculate route string */
     140        xhci_device_t *xhci_hub = xhci_device_get(dev->hub);
     141        xhci_dev->tier = xhci_hub->tier + 1;
     142        xhci_dev->route_str = xhci_hub->route_str;
     143
     144        /* Roothub port is not part of the route string */
     145        if (xhci_dev->tier >= 2) {
     146                const unsigned offset = 4 * (xhci_dev->tier - 2);
     147                xhci_dev->route_str |= (dev->port & 0xf) << offset;
     148        }
     149
     150        fibril_mutex_lock(&bus->base.guard);
    138151        /* Assign an address to the device */
    139152        if ((err = address_device(hc, xhci_dev))) {
     
    147160        assert(bus->devices_by_slot[xhci_dev->slot_id] == NULL);
    148161        bus->devices_by_slot[xhci_dev->slot_id] = xhci_dev;
     162        fibril_mutex_unlock(&bus->base.guard);
    149163
    150164        /* Read the device descriptor, derive the match ids */
     
    305319}
    306320
     321static int request_address(bus_t *bus_base, usb_address_t *addr, bool strict, usb_speed_t speed)
     322{
     323        assert(addr);
     324
     325        if (*addr != USB_ADDRESS_DEFAULT)
     326                /* xHCI does not allow software to assign addresses. */
     327                return ENOTSUP;
     328
     329        assert(strict);
     330
     331        xhci_bus_t *xhci_bus = bus_to_xhci_bus(bus_base);
     332
     333        if (xhci_bus->default_address_speed != USB_SPEED_MAX)
     334                /* Already allocated */
     335                return ENOENT;
     336
     337        xhci_bus->default_address_speed = speed;
     338        return EOK;
     339}
     340
     341static int release_address(bus_t *bus_base, usb_address_t addr)
     342{
     343        if (addr != USB_ADDRESS_DEFAULT)
     344                return ENOTSUP;
     345
     346        xhci_bus_t *xhci_bus = bus_to_xhci_bus(bus_base);
     347
     348        xhci_bus->default_address_speed = USB_SPEED_MAX;
     349        return EOK;
     350}
     351
    307352static usb_transfer_batch_t *create_batch(bus_t *bus, endpoint_t *ep)
    308353{
     
    327372        .find_endpoint = find_endpoint,
    328373
    329         .request_address = NULL,
    330         .release_address = NULL,
     374        .request_address = request_address,
     375        .release_address = release_address,
    331376        .reset_toggle = reset_toggle,
    332377
     
    351396
    352397        bus->base.ops = xhci_bus_ops;
     398        bus->default_address_speed = USB_SPEED_MAX;
    353399        return EOK;
    354400}
  • uspace/drv/bus/usb/xhci/bus.h

    rf668d60 r2cf28b9  
    4949
    5050        xhci_device_t **devices_by_slot;        /**< Devices by Slot ID */
     51
     52        usb_speed_t default_address_speed;      /**< Used to get speed from usb hubs */
    5153} xhci_bus_t;
    5254
  • uspace/drv/bus/usb/xhci/endpoint.c

    rf668d60 r2cf28b9  
    3939
    4040#include <errno.h>
    41 
     41#include <macros.h>
     42
     43#include "hc.h"
    4244#include "bus.h"
    4345#include "commands.h"
  • uspace/drv/bus/usb/xhci/endpoint.h

    rf668d60 r2cf28b9  
    4343#include <usb/host/hcd.h>
    4444
    45 #include "hc.h"
     45#include "trb_ring.h"
     46
    4647#include "transfers.h"
    4748
     
    9798        /** Slot ID assigned to the device by xHC. */
    9899        uint32_t slot_id;
     100
     101        /** Corresponding port on RH */
     102        uint8_t rh_port;
     103
     104        /** USB Tier of the device */
     105        uint8_t tier;
     106
     107        /** Route string */
     108        uint32_t route_str;
    99109
    100110        /** Place to store virtual address for allocated context */
  • uspace/drv/bus/usb/xhci/hc.c

    rf668d60 r2cf28b9  
    657657        int err = ENOMEM;
    658658
     659        /* Although we have the precise PSIV value on devices of tier 1,
     660         * we have to rely on reverse mapping on others. */
     661        if (!hc->speed_to_psiv[dev->base.speed]) {
     662                usb_log_error("Device reported an usb speed that cannot be mapped to HC port speed.");
     663                return EINVAL;
     664        }
     665
    659666        /* Setup and register device context */
    660667        dev->dev_ctx = malloc32(sizeof(xhci_device_ctx_t));
     
    672679
    673680        /* Initialize slot_ctx according to section 4.3.3 point 3. */
    674         XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, dev->base.port); // FIXME: This should be port at RH
     681        XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, dev->rh_port);
    675682        XHCI_SLOT_CTX_ENTRIES_SET(ictx->slot_ctx, 1);
    676 
    677         /* Attaching to root hub port, root string equals to 0. */
    678         XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, 0); // FIXME: This is apparently valid in limited cases
     683        XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, dev->route_str);
     684        XHCI_SLOT_SPEED_SET(ictx->slot_ctx, hc->speed_to_psiv[dev->base.speed]);
     685
     686        /* In a very specific case, we have to set also these. But before that,
     687         * we need to refactor how TT is handled in libusbhost. */
     688        XHCI_SLOT_TT_HUB_SLOT_ID_SET(ictx->slot_ctx, 0);
     689        XHCI_SLOT_TT_HUB_PORT_SET(ictx->slot_ctx, 0);
     690        XHCI_SLOT_MTT_SET(ictx->slot_ctx, 0);
    679691
    680692        /* Copy endpoint 0 context and set A1 flag. */
  • uspace/drv/bus/usb/xhci/hc.h

    rf668d60 r2cf28b9  
    4343#include "scratchpad.h"
    4444#include "trb_ring.h"
     45
    4546#include "rh.h"
    4647#include "bus.h"
  • uspace/drv/bus/usb/xhci/hw_struct/context.h

    rf668d60 r2cf28b9  
    111111        xhci_dword_t reserved [4];
    112112
     113#define XHCI_SLOT_ROUTE_STRING_SET(ctx, val) \
     114        xhci_dword_set_bits(&(ctx).data[0], (val & 0xFFFFF), 19, 0)
     115#define XHCI_SLOT_SPEED_SET(ctx, val) \
     116        xhci_dword_set_bits(&(ctx).data[0], (val & 0xF), 23, 20)
     117#define XHCI_SLOT_MTT_SET(ctx, val) \
     118        xhci_dword_set_bits(&(ctx).data[0], !!val, 25, 25)
     119#define XHCI_SLOT_CTX_ENTRIES_SET(ctx, val) \
     120        xhci_dword_set_bits(&(ctx).data[0], val, 31, 27)
     121
    113122#define XHCI_SLOT_ROOT_HUB_PORT_SET(ctx, val) \
    114123        xhci_dword_set_bits(&(ctx).data[1], val, 23, 16)
    115 #define XHCI_SLOT_CTX_ENTRIES_SET(ctx, val) \
    116         xhci_dword_set_bits(&(ctx).data[0], val, 31, 27)
    117 #define XHCI_SLOT_ROUTE_STRING_SET(ctx, val) \
    118         xhci_dword_set_bits(&(ctx).data[0], (val & 0xFFFFF), 19, 0)
     124
     125#define XHCI_SLOT_TT_HUB_SLOT_ID_SET(ctx, val) \
     126        xhci_dword_set_bits(&(ctx).data[2], (val & 0xFF), 7, 0)
     127#define XHCI_SLOT_TT_HUB_PORT_SET(ctx, val) \
     128        xhci_dword_set_bits(&(ctx).data[2], (val & 0xFF), 15, 8)
    119129
    120130#define XHCI_SLOT_ROUTE_STRING(ctx)     XHCI_DWORD_EXTRACT((ctx).data[0], 19,  0)
  • uspace/drv/bus/usb/xhci/rh.c

    rf668d60 r2cf28b9  
    6969        rh->max_ports = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_PORTS);
    7070        rh->devices = (xhci_device_t **) calloc(rh->max_ports, sizeof(xhci_device_t *));
    71         hc->rh.hc_device = device;
    72 
    73         return device_init(&hc->rh.device);
     71        rh->hc_device = device;
     72
     73        const int err = device_init(&rh->device.base);
     74        if (err)
     75                return err;
     76
     77        /* Initialize route string */
     78        rh->device.route_str = 0;
     79        rh->device.tier = 0;
     80
     81        return EOK;
    7482}
    7583
     
    8189        assert(rh);
    8290        assert(rh->hc_device);
     91
     92        assert(rh->devices[port_id - 1] == NULL);
    8393
    8494        xhci_bus_t *bus = &rh->hc->bus;
     
    94104        xhci_dev->hc = rh->hc;
    95105        xhci_dev->usb3 = port_speed->major == 3;
    96 
    97         dev->hub = &rh->device;
     106        xhci_dev->rh_port = port_id;
     107
     108        dev->hub = &rh->device.base;
    98109        dev->port = port_id;
    99110        dev->speed = port_speed->usb_speed;
     
    113124        }
    114125
    115         fibril_mutex_lock(&rh->device.guard);
    116         list_append(&dev->link, &rh->device.devices);
    117         if (!rh->devices[port_id - 1]) {
    118                 /* Only save the device if it's the first one connected to this port. */
    119                 rh->devices[port_id - 1] = xhci_dev;
    120         }
    121         fibril_mutex_unlock(&rh->device.guard);
     126        fibril_mutex_lock(&rh->device.base.guard);
     127        list_append(&dev->link, &rh->device.base.devices);
     128        rh->devices[port_id - 1] = xhci_dev;
     129        fibril_mutex_unlock(&rh->device.base.guard);
    122130
    123131        return EOK;
     
    185193        fibril_mutex_unlock(&dev->base.guard);
    186194
    187         fibril_mutex_lock(&rh->device.guard);
     195        fibril_mutex_lock(&rh->device.base.guard);
    188196        list_remove(&dev->base.link);
    189         fibril_mutex_unlock(&rh->device.guard);
    190 
    191197        rh->devices[port_id - 1] = NULL;
     198        fibril_mutex_unlock(&rh->device.base.guard);
     199
    192200        usb_log_debug2("Aborting all active transfers to '%s'.", ddf_fun_get_name(dev->base.fun));
    193201
  • uspace/drv/bus/usb/xhci/rh.h

    rf668d60 r2cf28b9  
    3939#include <usb/host/usb_transfer_batch.h>
    4040#include <usb/host/bus.h>
     41
    4142#include "hw_struct/regs.h"
     43#include "endpoint.h"
    4244
    4345typedef struct xhci_hc xhci_hc_t;
     
    5658typedef struct hcd_roothub hcd_roothub_t;
    5759typedef struct xhci_bus xhci_bus_t;
    58 typedef struct xhci_device xhci_device_t;
    5960
    6061/* XHCI root hub instance */
     
    6465
    6566        /* Root for the device tree */
    66         device_t device;
     67        xhci_device_t device;
    6768
    6869        /* We need this to attach children to */
  • uspace/drv/bus/usb/xhci/transfers.h

    rf668d60 r2cf28b9  
    3939#include <usb/host/usb_transfer_batch.h>
    4040
    41 #include "hc.h"
     41#include "hw_struct/context.h"
    4242#include "trb_ring.h"
     43
     44typedef struct xhci_hc xhci_hc_t;
    4345
    4446typedef struct {
  • uspace/lib/usbhost/include/usb/host/bus.h

    rf668d60 r2cf28b9  
    8282        int (*remove_device)(bus_t *, hcd_t *, device_t *);
    8383
     84        /* The following operations are protected by a bus guard. */
    8485        endpoint_t *(*create_endpoint)(bus_t *);
    8586        int (*register_endpoint)(bus_t *, endpoint_t *, const usb_endpoint_desc_t *);
  • uspace/lib/usbhost/src/bus.c

    rf668d60 r2cf28b9  
    8787                return ENOTSUP;
    8888
    89         fibril_mutex_lock(&bus->guard);
    90         const int r = bus->ops.enumerate_device(bus, hcd, dev);
    91         fibril_mutex_unlock(&bus->guard);
    92         return r;
     89        return bus->ops.enumerate_device(bus, hcd, dev);
    9390}
    9491
     
    10198                return ENOTSUP;
    10299
    103         fibril_mutex_lock(&bus->guard);
    104         const int r = bus->ops.remove_device(bus, hcd, dev);
    105         fibril_mutex_unlock(&bus->guard);
    106         return r;
     100        return bus->ops.remove_device(bus, hcd, dev);
    107101}
    108102
Note: See TracChangeset for help on using the changeset viewer.