Changeset 20eaa82 in mainline for uspace/drv/bus/usb/xhci


Ignore:
Timestamp:
2017-10-15T13:44:39Z (8 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2770b66
Parents:
867b375
Message:

usbhost refactoring: introduced bus→enumerate_device

Location:
uspace/drv/bus/usb/xhci
Files:
7 edited

Legend:

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

    r867b375 r20eaa82  
    3535#include <adt/hash_table.h>
    3636#include <adt/hash.h>
     37#include <usb/host/ddf_helpers.h>
    3738#include <usb/host/endpoint.h>
     39#include <usb/host/hcd.h>
    3840#include <usb/debug.h>
    3941
    4042#include <assert.h>
    4143#include <errno.h>
     44#include <str_error.h>
    4245#include <macros.h>
    4346#include <stdbool.h>
     
    5356        xhci_device_t *device;
    5457} hashed_device_t;
     58
     59/** TODO: Still some copy-pasta left...
     60 */
     61int xhci_bus_enumerate_device(xhci_bus_t *bus, xhci_hc_t *hc, device_t *dev)
     62{
     63        int err;
     64
     65        /* TODO: get speed from the default address reservation */
     66        dev->speed = USB_SPEED_FULL;
     67
     68        /* Manage TT */
     69        if (dev->hub->speed == USB_SPEED_HIGH && usb_speed_is_11(dev->speed)) {
     70                /* For LS devices under HS hub */
     71                /* TODO: How about SS hubs? */
     72                dev->tt.address = dev->hub->address;
     73                dev->tt.port = dev->port;
     74        }
     75        else {
     76                /* Inherit hub's TT */
     77                dev->tt = dev->hub->tt;
     78        }
     79
     80        /* Assign an address to the device */
     81        if ((err = xhci_rh_address_device(&hc->rh, dev))) {
     82                usb_log_error("Failed to setup address of the new device: %s", str_error(err));
     83                return err;
     84        }
     85
     86        /* Read the device descriptor, derive the match ids */
     87        if ((err = hcd_ddf_device_explore(hc->hcd, dev))) {
     88                usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err));
     89                bus_release_address(&bus->base, dev->address);
     90                return err;
     91        }
     92
     93        return EOK;
     94}
     95
     96static int enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev)
     97{
     98        xhci_hc_t *hc = hcd_get_driver_data(hcd);
     99        assert(hc);
     100
     101        return xhci_bus_enumerate_device((xhci_bus_t *) bus, hc, dev);
     102}
     103
     104static int remove_device(bus_t *bus, hcd_t *hcd, device_t *dev)
     105{
     106        // TODO: Implement me!
     107
     108        return ENOTSUP;
     109}
    55110
    56111/** Ops receive generic bus_t pointer. */
     
    214269}
    215270
    216 static int get_speed(bus_t *bus_base, usb_address_t address, usb_speed_t *speed)
    217 {
    218         xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
    219         assert(bus);
    220 
    221         // TODO: Use `xhci_get_port_speed` once we find the port corresponding to `address`.
    222         *speed = USB_SPEED_SUPER;
    223         return EOK;
    224 }
    225 
    226271static int release_address(bus_t *bus_base, usb_address_t address)
    227272{
     
    255300
    256301static const bus_ops_t xhci_bus_ops = {
     302        .enumerate_device = enumerate_device,
     303        .remove_device = remove_device,
     304
    257305        .create_endpoint = create_endpoint,
    258306        .destroy_endpoint = destroy_endpoint,
     
    263311
    264312        .request_address = request_address,
    265         .get_speed = get_speed,
    266313        .release_address = release_address,
    267314        .reset_toggle = reset_toggle,
     
    303350        assert(bus);
    304351
    305         bus_init(&bus->base);
     352        bus_init(&bus->base, sizeof(device_t));
    306353
    307354        if (!hash_table_create(&bus->devices, 0, 0, &device_ht_ops)) {
     
    320367        hash_table_destroy(&bus->devices);
    321368}
     369
    322370/**
    323371 * @}
  • uspace/drv/bus/usb/xhci/bus.h

    r867b375 r20eaa82  
    4242#include <usb/host/bus.h>
    4343
     44typedef struct xhci_hc xhci_hc_t;
     45
    4446/** Endpoint management structure */
    4547typedef struct xhci_bus {
     
    5860void xhci_bus_fini(xhci_bus_t *);
    5961
     62int xhci_bus_enumerate_device(xhci_bus_t *, xhci_hc_t *, device_t *);
     63
    6064#endif
    6165/**
  • uspace/drv/bus/usb/xhci/hc.c

    r867b375 r20eaa82  
    158158                return err;
    159159
    160         hc->base = base;
     160        hc->reg_base = base;
    161161        hc->cap_regs = (xhci_cap_regs_t *)  base;
    162162        hc->op_regs  = (xhci_op_regs_t *)  (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_LENGTH));
     
    180180
    181181        if ((err = hc_parse_ec(hc))) {
    182                 pio_disable(hc->base, RNGSZ(hc->mmio_range));
     182                pio_disable(hc->reg_base, RNGSZ(hc->mmio_range));
    183183                return err;
    184184        }
     
    619619        xhci_fini_commands(hc);
    620620        xhci_rh_fini(&hc->rh);
    621         pio_disable(hc->base, RNGSZ(hc->mmio_range));
     621        pio_disable(hc->reg_base, RNGSZ(hc->mmio_range));
    622622        usb_log_info("HC(%p): Finalized.", hc);
    623623}
  • uspace/drv/bus/usb/xhci/hc.h

    r867b375 r20eaa82  
    5353        /* MMIO range */
    5454        addr_range_t mmio_range;
    55         void *base;
    5655
    5756        /* Mapped register sets */
     57        void *reg_base;
    5858        xhci_cap_regs_t *cap_regs;
    5959        xhci_op_regs_t *op_regs;
     
    8383        list_t commands;
    8484        list_t transfers;
     85
     86        /* TODO: Hack. Figure out a better way. */
     87        hcd_t *hcd;
    8588} xhci_hc_t;
    8689
  • uspace/drv/bus/usb/xhci/main.c

    r867b375 r20eaa82  
    5555static void hcd_interrupt(hcd_t *, uint32_t);
    5656static int hcd_schedule(hcd_t *, usb_transfer_batch_t *);
    57 static int hcd_address_device(hcd_t *, usb_speed_t, usb_tt_address_t, usb_address_t *);
    5857static void hc_driver_fini(hcd_t *);
    5958
    6059static const ddf_hc_driver_t xhci_ddf_hc_driver = {
    61         .hc_speed = USB_SPEED_SUPER,
    6260        .name = "XHCI-PCI",
    6361        .init = hc_driver_init,
     
    7169                .irq_hook       = hcd_interrupt,
    7270                .status_hook    = hcd_status,
    73                 .address_device = hcd_address_device,
    7471        }
    7572};
     
    9087
    9188        hcd_set_implementation(hcd, hc, &xhci_ddf_hc_driver.ops, &hc->bus.base);
     89        hc->hcd = hcd;
    9290
    9391        return EOK;
     
    126124        assert(hc);
    127125
    128         hc->rh.hcd_rh = hcd_roothub_create(hcd, dev, USB_SPEED_SUPER);
    129         return hc->rh.hcd_rh ? EOK : ENOMEM;
     126        hc->rh.hc_device = dev;
     127        return device_init(&hc->rh.device);
    130128}
    131129
     
    153151
    154152        hc_interrupt(hc, status);
    155 }
    156 
    157 static int hcd_address_device(hcd_t *hcd, usb_speed_t speed, usb_tt_address_t tt, usb_address_t *address)
    158 {
    159         xhci_hc_t *hc = hcd_get_driver_data(hcd);
    160         assert(hc);
    161 
    162         return xhci_rh_address_device(&hc->rh, speed, tt, address);
    163153}
    164154
  • uspace/drv/bus/usb/xhci/rh.c

    r867b375 r20eaa82  
    3838#include <usb/debug.h>
    3939#include <usb/host/utils/malloc32.h>
     40#include <usb/host/bus.h>
    4041#include <usb/host/ddf_helpers.h>
    4142
     
    7374// TODO: This currently assumes the device is attached to rh directly.
    7475//       Also, we should consider moving a lot of functionailty to xhci bus
    75 int xhci_rh_address_device(xhci_rh_t *rh, usb_speed_t unused_speed, usb_tt_address_t tt, usb_address_t *address)
     76int xhci_rh_address_device(xhci_rh_t *rh, device_t *dev)
    7677{
    7778        int err;
     
    8182        xhci_cmd_init(&cmd);
    8283
    83         uint8_t port = tt.port;
    84 
    8584        /* XXX Certainly not generic solution. */
    8685        uint32_t route_str = 0;
    8786
    88         const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, port);
     87        const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, dev->port);
    8988
    9089        xhci_send_enable_slot_command(hc, &cmd);
     
    109108        /* Initialize slot_ctx according to section 4.3.3 point 3. */
    110109        /* Attaching to root hub port, root string equals to 0. */
    111         XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, port);
     110        XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, dev->port);
    112111        XHCI_SLOT_CTX_ENTRIES_SET(ictx->slot_ctx, 1);
    113112        XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, route_str);
     
    158157        xhci_cmd_fini(&cmd);
    159158
    160         *address = XHCI_SLOT_DEVICE_ADDRESS(dctx->slot_ctx);
    161         usb_log_debug2("Obtained USB address: %d.\n", *address);
     159        dev->address = XHCI_SLOT_DEVICE_ADDRESS(dctx->slot_ctx);
     160        usb_log_debug2("Obtained USB address: %d.\n", dev->address);
    162161
    163162        // TODO: Ask libusbhost to create a control endpoint for EP0.
     
    183182}
    184183
     184/** Create a device node for device directly connected to RH.
     185 */
    185186static int rh_setup_device(xhci_rh_t *rh, uint8_t port_id)
    186187{
    187         /** This should ideally use the libusbhost in a clean and elegant way,
    188          * to create child function. The refactoring of libusbhost is not over
    189          * yet, so for now it is still quirky.
    190          */
    191 
    192         return hcd_roothub_new_device(rh->hcd_rh, port_id);
     188        int err;
     189        assert(rh);
     190
     191        xhci_bus_t *bus = &rh->hc->bus;
     192
     193        device_t *dev = hcd_ddf_device_create(rh->hc_device, bus->base.device_size);
     194        if (!dev) {
     195                usb_log_error("Failed to create USB device function.");
     196                return ENOMEM;
     197        }
     198
     199        dev->hub = &rh->device;
     200        dev->port = port_id;
     201
     202        if ((err = xhci_bus_enumerate_device(bus, rh->hc, dev))) {
     203                usb_log_error("Failed to enumerate USB device: %s", str_error(err));
     204                return err;
     205        }
     206
     207        if (!ddf_fun_get_name(dev->fun)) {
     208                device_set_default_name(dev);
     209        }
     210
     211        if ((err = ddf_fun_bind(dev->fun))) {
     212                usb_log_error("Device(%d): Failed to register: %s.", dev->address, str_error(err));
     213                goto err_usb_dev;
     214        }
     215
     216        fibril_mutex_lock(&rh->device.guard);
     217        list_append(&dev->link, &rh->device.devices);
     218        fibril_mutex_unlock(&rh->device.guard);
     219
     220        return EOK;
     221
     222err_usb_dev:
     223        hcd_ddf_device_destroy(dev);
     224        return err;
    193225}
    194226
  • uspace/drv/bus/usb/xhci/rh.h

    r867b375 r20eaa82  
    3838
    3939#include <usb/host/usb_transfer_batch.h>
     40#include <usb/host/bus.h>
    4041#include "hw_struct/regs.h"
    4142
    4243typedef struct xhci_hc xhci_hc_t;
     44typedef struct ddf_dev ddf_dev_t;
    4345
    4446/**
     
    5860        xhci_hc_t *hc;
    5961
     62        /* Root for the device tree */
     63        device_t device;
     64
     65        /* We need this to attach children to */
     66        ddf_dev_t *hc_device;
     67
    6068        /** Port speeds reported from HC */
    6169        xhci_port_speed_t speeds [16];
     
    6674        /* Number of hub ports. */
    6775        uint8_t max_ports;
    68 
    69         /* We need this to create child devices */
    70         hcd_roothub_t *hcd_rh;
    7176} xhci_rh_t;
    7277
     
    7984void xhci_rh_handle_port_change(xhci_rh_t *);
    8085
    81 int xhci_rh_address_device(xhci_rh_t *, usb_speed_t, usb_tt_address_t, usb_address_t *);
     86int xhci_rh_address_device(xhci_rh_t *rh, device_t *dev);
    8287
    8388#endif
Note: See TracChangeset for help on using the changeset viewer.