Changeset 20eaa82 in mainline


Ignore:
Timestamp:
2017-10-15T13:44:39Z (7 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
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ehci/hw_struct/queue_head.c

    r867b375 r20eaa82  
    3737#include <mem.h>
    3838#include <macros.h>
     39#include <usb/host/bus.h>
    3940
    4041#include "mem_access.h"
     
    8182        if (ep->speed != USB_SPEED_HIGH) {
    8283                ep_cap |=
    83                     QH_EP_CAP_TT_PORT_SET(ep->tt.port) |
    84                     QH_EP_CAP_TT_ADDR_SET(ep->tt.address);
     84                    QH_EP_CAP_TT_PORT_SET(ep->device->tt.port) |
     85                    QH_EP_CAP_TT_ADDR_SET(ep->device->tt.address);
    8586        }
    8687        if (ep->transfer_type == USB_TRANSFER_INTERRUPT) {
  • uspace/drv/bus/usb/ehci/main.c

    r867b375 r20eaa82  
    5757
    5858static const ddf_hc_driver_t ehci_hc_driver = {
    59         .hc_speed = USB_SPEED_HIGH,
    6059        .name = "EHCI-PCI",
    6160        .init = ehci_driver_init,
  • 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
  • uspace/lib/usb/include/usb/request.h

    r867b375 r20eaa82  
    112112    const usb_device_request_setup_packet_t *request);
    113113
     114#define GET_DEVICE_DESC(size) \
     115{ \
     116        .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \
     117            | (USB_REQUEST_TYPE_STANDARD << 5) \
     118            | USB_REQUEST_RECIPIENT_DEVICE, \
     119        .request = USB_DEVREQ_GET_DESCRIPTOR, \
     120        .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \
     121        .index = uint16_host2usb(0), \
     122        .length = uint16_host2usb(size), \
     123};
     124
     125#define SET_ADDRESS(address) \
     126{ \
     127        .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \
     128            | (USB_REQUEST_TYPE_STANDARD << 5) \
     129            | USB_REQUEST_RECIPIENT_DEVICE, \
     130        .request = USB_DEVREQ_SET_ADDRESS, \
     131        .value = uint16_host2usb(address), \
     132        .index = uint16_host2usb(0), \
     133        .length = uint16_host2usb(0), \
     134};
     135
     136#define CTRL_PIPE_MIN_PACKET_SIZE 8
     137
    114138#endif
    115139/**
  • uspace/lib/usbhost/include/usb/host/bus.h

    r867b375 r20eaa82  
    4545#include <usb/usb.h>
    4646
     47#include <assert.h>
    4748#include <fibril_synch.h>
    4849#include <stdbool.h>
     
    5152typedef struct endpoint endpoint_t;
    5253typedef struct bus bus_t;
     54typedef struct ddf_fun ddf_fun_t;
     55
     56typedef struct device {
     57        /* Device tree keeping */
     58        link_t link;
     59        list_t devices;
     60        fibril_mutex_t guard;
     61
     62        /* Associated DDF function, if any */
     63        ddf_fun_t *fun;
     64
     65        /* Invalid for the roothub device */
     66        unsigned port;
     67        struct device *hub;
     68
     69        /* Transaction translator */
     70        usb_tt_address_t tt;
     71
     72        /* The following are not set by the library */
     73        usb_speed_t speed;
     74        usb_address_t address;
     75
     76        /* This structure is meant to be extended by overriding. */
     77} device_t;
    5378
    5479typedef struct {
     80        int (*enumerate_device)(bus_t *, hcd_t *, device_t *);
     81        int (*remove_device)(bus_t *, hcd_t *, device_t *);
     82
    5583        endpoint_t *(*create_endpoint)(bus_t *);
    5684        int (*register_endpoint)(bus_t *, endpoint_t *);
     
    5987
    6088        int (*request_address)(bus_t *, usb_address_t*, bool, usb_speed_t);
    61         int (*get_speed)(bus_t *, usb_address_t, usb_speed_t *);
    6289        int (*release_address)(bus_t *, usb_address_t);
    6390
     
    77104        fibril_mutex_t guard;
    78105
     106        size_t device_size;
     107
    79108        /* Do not call directly, ops are synchronized. */
    80109        bus_ops_t ops;
     
    83112} bus_t;
    84113
    85 void bus_init(bus_t *);
     114void bus_init(bus_t *, size_t);
     115int device_init(device_t *);
     116
     117extern int bus_add_ep(bus_t *bus, device_t *device, usb_endpoint_t endpoint,
     118    usb_direction_t dir, usb_transfer_type_t type, size_t max_packet_size,
     119    unsigned packets, size_t size);
     120extern int bus_remove_ep(bus_t *bus, usb_target_t target, usb_direction_t dir);
     121
     122int device_set_default_name(device_t *);
     123
     124int bus_enumerate_device(bus_t *, hcd_t *, device_t *);
     125int bus_remove_device(bus_t *, hcd_t *, device_t *);
    86126
    87127endpoint_t *bus_create_endpoint(bus_t *);
     
    93133
    94134int bus_request_address(bus_t *, usb_address_t *, bool, usb_speed_t);
    95 int bus_get_speed(bus_t *, usb_address_t, usb_speed_t *);
    96135int bus_release_address(bus_t *, usb_address_t);
     136
     137static inline int bus_reserve_default_address(bus_t *bus, usb_speed_t speed) {
     138        usb_address_t addr = USB_ADDRESS_DEFAULT;
     139
     140        const int r = bus_request_address(bus, &addr, true, speed);
     141        assert(addr == USB_ADDRESS_DEFAULT);
     142        return r;
     143}
     144
     145static inline int bus_release_default_address(bus_t *bus) {
     146        return bus_release_address(bus, USB_ADDRESS_DEFAULT);
     147}
    97148
    98149int bus_reset_toggle(bus_t *, usb_target_t, bool);
  • uspace/lib/usbhost/include/usb/host/ddf_helpers.h

    r867b375 r20eaa82  
    5959typedef struct {
    6060        hcd_ops_t ops;
    61         usb_speed_t hc_speed;
    6261        const char *name;
    6362
     
    8382int hcd_setup_virtual_root_hub(hcd_t *, ddf_dev_t *);
    8483
     84device_t *hcd_ddf_device_create(ddf_dev_t *, size_t);
     85void hcd_ddf_device_destroy(device_t *);
     86int hcd_ddf_device_explore(hcd_t *, device_t *);
     87
    8588hcd_t *dev_to_hcd(ddf_dev_t *dev);
    8689
     
    9396void ddf_hcd_gen_irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev);
    9497
    95 /* For xHCI, we need to drive the roothub without roothub having assigned an
    96  * address. Thus we cannot create function for it, and we have to carry the
    97  * usb_dev_t somewhere.
    98  *
    99  * This is sort of hacky, but at least does not expose the internals of ddf_helpers.
    100  */
    101 typedef struct hcd_roothub hcd_roothub_t;
    102 
    103 hcd_roothub_t *hcd_roothub_create(hcd_t *, ddf_dev_t *, usb_speed_t);
    104 int hcd_roothub_new_device(hcd_roothub_t *, unsigned port);
    105 
    10698#endif
    10799
  • uspace/lib/usbhost/include/usb/host/endpoint.h

    r867b375 r20eaa82  
    4747
    4848typedef struct bus bus_t;
     49typedef struct device device_t;
    4950
    5051/** Host controller side endpoint structure. */
     
    5657        /** Part of linked list. */
    5758        link_t link;
     59        /** USB device */
     60        device_t *device;
    5861        /** USB address. */
    5962        usb_target_t target;
     
    7881        /** Signals change of active status. */
    7982        fibril_condvar_t avail;
    80         /** High speed TT data */
    81         usb_tt_address_t tt;
    8283
    8384        /* This structure is meant to be extended by overriding. */
  • uspace/lib/usbhost/include/usb/host/hcd.h

    r867b375 r20eaa82  
    103103extern usb_address_t hcd_request_address(hcd_t *, usb_speed_t);
    104104
    105 extern int hcd_release_address(hcd_t *, usb_address_t);
    106 
    107 extern int hcd_reserve_default_address(hcd_t *, usb_speed_t);
    108 
    109 static inline int hcd_release_default_address(hcd_t *hcd)
    110 {
    111         return hcd_release_address(hcd, USB_ADDRESS_DEFAULT);
    112 }
    113 
    114105extern int hcd_add_ep(hcd_t *, usb_target_t, usb_direction_t,
    115106    usb_transfer_type_t, size_t, unsigned int, size_t, usb_tt_address_t);
  • uspace/lib/usbhost/src/bus.c

    r867b375 r20eaa82  
    3636#include <usb/host/bus.h>
    3737#include <usb/host/endpoint.h>
     38#include <ddf/driver.h>
    3839
    3940#include <mem.h>
    4041#include <errno.h>
     42#include <stdio.h>
    4143
    4244/**
    4345 * Initializes the bus structure.
    4446 */
    45 void bus_init(bus_t *bus)
    46 {
     47void bus_init(bus_t *bus, size_t device_size)
     48{
     49        assert(bus);
     50        assert(device_size >= sizeof(device_t));
    4751        memset(bus, 0, sizeof(bus_t));
    4852
    4953        fibril_mutex_initialize(&bus->guard);
     54        bus->device_size = device_size;
     55}
     56
     57int device_init(device_t *dev)
     58{
     59        memset(dev, 0, sizeof(*dev));
     60
     61        link_initialize(&dev->link);
     62        list_initialize(&dev->devices);
     63        fibril_mutex_initialize(&dev->guard);
     64
     65        return EOK;
     66}
     67
     68int bus_add_ep(bus_t *bus, device_t *device, usb_endpoint_t endpoint,
     69    usb_direction_t dir, usb_transfer_type_t type, size_t max_packet_size,
     70    unsigned packets, size_t size)
     71{
     72        assert(bus);
     73        assert(device);
     74
     75        /* Temporary reference */
     76        endpoint_t *ep = bus_create_endpoint(bus);
     77        if (!ep)
     78                return ENOMEM;
     79
     80        ep->target = (usb_target_t) {
     81                .address = device->address,
     82                .endpoint = endpoint,
     83        };
     84
     85        ep->device = device;
     86        ep->direction = dir;
     87        ep->transfer_type = type;
     88        ep->max_packet_size = max_packet_size;
     89        ep->packets = packets;
     90
     91        ep->bandwidth = bus_count_bw(ep, size);
     92
     93        const int err = bus_register_endpoint(bus, ep);
     94
     95        /* drop Temporary reference */
     96        endpoint_del_ref(ep);
     97
     98        return err;
     99}
     100
     101int bus_remove_ep(bus_t *bus, usb_target_t target, usb_direction_t dir)
     102{
     103        assert(bus);
     104        endpoint_t *ep = bus_find_endpoint(bus, target, dir);
     105        if (!ep)
     106                return ENOENT;
     107
     108        return bus_release_endpoint(bus, ep);
     109}
     110
     111int device_set_default_name(device_t *dev)
     112{
     113        assert(dev);
     114        assert(dev->fun);
     115
     116        char buf[10] = { 0 }; /* usbxyz-ss */
     117        snprintf(buf, sizeof(buf) - 1, "usb%u-%cs",
     118            dev->address, usb_str_speed(dev->speed)[0]);
     119
     120        return ddf_fun_set_name(dev->fun, buf);
     121}
     122
     123int bus_enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev)
     124{
     125        assert(bus);
     126        assert(hcd);
     127        assert(dev);
     128
     129        if (!bus->ops.enumerate_device)
     130                return ENOTSUP;
     131
     132        fibril_mutex_lock(&bus->guard);
     133        const int r = bus->ops.enumerate_device(bus, hcd, dev);
     134        fibril_mutex_unlock(&bus->guard);
     135        return r;
     136}
     137
     138int bus_remove_device(bus_t *bus, hcd_t *hcd, device_t *dev)
     139{
     140        assert(bus);
     141        assert(dev);
     142
     143        if (!bus->ops.remove_device)
     144                return ENOTSUP;
     145
     146        fibril_mutex_lock(&bus->guard);
     147        const int r = bus->ops.remove_device(bus, hcd, dev);
     148        fibril_mutex_unlock(&bus->guard);
     149        return r;
    50150}
    51151
     
    141241}
    142242
    143 int bus_get_speed(bus_t *bus, usb_address_t address, usb_speed_t *speed)
    144 {
    145         assert(bus);
    146         assert(speed);
    147 
    148         if (!bus->ops.get_speed)
    149                 return ENOTSUP;
    150 
    151         fibril_mutex_lock(&bus->guard);
    152         const int r = bus->ops.get_speed(bus, address, speed);
    153         fibril_mutex_unlock(&bus->guard);
    154         return r;
    155 }
    156 
    157243int bus_reset_toggle(bus_t *bus, usb_target_t target, bool all)
    158244{
  • uspace/lib/usbhost/src/ddf_helpers.c

    r867b375 r20eaa82  
    3535
    3636#include <usb/classes/classes.h>
     37#include <usb/host/bus.h>
    3738#include <usb/debug.h>
    3839#include <usb/descriptor.h>
     
    5051#include <fibril_synch.h>
    5152#include <macros.h>
    52 #include <stdio.h>
    5353#include <stdlib.h>
    5454#include <str_error.h>
     
    5656
    5757#include "ddf_helpers.h"
    58 
    59 #define CTRL_PIPE_MIN_PACKET_SIZE 8
    60 
    61 typedef struct usb_dev {
    62         link_t link;
    63         list_t devices;
    64         fibril_mutex_t guard;
    65         usb_address_t address;
    66         usb_speed_t speed;
    67         usb_tt_address_t tt;
    68 
    69         /* This must be set iff the usb_dev is managed by ddf_fun. */
    70         ddf_fun_t *fun;
    71 } usb_dev_t;
    7258
    7359typedef struct hc_dev {
     
    9278
    9379
    94 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, usb_dev_t *hub_dev, unsigned port);
    95 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port);
     80static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub_dev, unsigned port);
     81static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub, unsigned port);
    9682
    9783
     
    115101        assert(fun);
    116102        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    117         usb_dev_t *dev = ddf_fun_data_get(fun);
     103        device_t *dev = ddf_fun_data_get(fun);
    118104        assert(hcd);
     105        assert(hcd->bus);
    119106        assert(dev);
    120107        const size_t size = max_packet_size;
    121         const usb_target_t target =
    122             {{.address = dev->address, .endpoint = endpoint}};
    123108
    124109        usb_log_debug("Register endpoint %d:%d %s-%s %zuB %ums.\n",
     
    126111            usb_str_direction(direction), max_packet_size, interval);
    127112
    128         return hcd_add_ep(hcd, target, direction, transfer_type,
    129             max_packet_size, packets, size, dev->tt);
     113        return bus_add_ep(hcd->bus, dev, endpoint, direction, transfer_type,
     114            max_packet_size, packets, size);
    130115}
    131116
     
    142127        assert(fun);
    143128        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    144         usb_dev_t *dev = ddf_fun_data_get(fun);
     129        device_t *dev = ddf_fun_data_get(fun);
    145130        assert(hcd);
     131        assert(hcd->bus);
    146132        assert(dev);
    147         const usb_target_t target =
    148             {{.address = dev->address, .endpoint = endpoint}};
     133        const usb_target_t target = {{
     134                .address = dev->address,
     135                .endpoint = endpoint
     136        }};
    149137        usb_log_debug("Unregister endpoint %d:%d %s.\n",
    150138            dev->address, endpoint, usb_str_direction(direction));
    151         return hcd_remove_ep(hcd, target, direction);
     139        return bus_remove_ep(hcd->bus, target, direction);
    152140}
    153141
     
    156144        assert(fun);
    157145        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    158         usb_dev_t *dev = ddf_fun_data_get(fun);
     146        device_t *dev = ddf_fun_data_get(fun);
    159147        assert(hcd);
     148        assert(hcd->bus);
    160149        assert(dev);
    161150
    162151        usb_log_debug("Device %d requested default address at %s speed\n",
    163152            dev->address, usb_str_speed(speed));
    164         return hcd_reserve_default_address(hcd, speed);
     153        return bus_reserve_default_address(hcd->bus, speed);
    165154}
    166155
     
    169158        assert(fun);
    170159        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    171         usb_dev_t *dev = ddf_fun_data_get(fun);
     160        device_t *dev = ddf_fun_data_get(fun);
    172161        assert(hcd);
     162        assert(hcd->bus);
    173163        assert(dev);
    174164
    175165        usb_log_debug("Device %d released default address\n", dev->address);
    176         return hcd_release_default_address(hcd);
     166        return bus_release_default_address(hcd->bus);
    177167}
    178168
     
    184174        hcd_t *hcd = dev_to_hcd(hc);
    185175        assert(hcd);
    186         usb_dev_t *hub = ddf_fun_data_get(fun);
     176        device_t *hub = ddf_fun_data_get(fun);
    187177        assert(hub);
    188178
     
    196186        assert(fun);
    197187        ddf_dev_t *ddf_dev = ddf_fun_get_dev(fun);
    198         usb_dev_t *dev = ddf_fun_data_get(fun);
     188        device_t *dev = ddf_fun_data_get(fun);
    199189        assert(ddf_dev);
    200190        assert(dev);
     
    233223{
    234224        assert(fun);
    235         usb_dev_t *usb_dev = ddf_fun_data_get(fun);
    236         assert(usb_dev);
     225        device_t *dev = ddf_fun_data_get(fun);
     226        assert(dev);
    237227        const usb_target_t target = {{
    238             .address =  usb_dev->address,
     228            .address  = dev->address,
    239229            .endpoint = endpoint,
    240230        }};
     
    259249{
    260250        assert(fun);
    261         usb_dev_t *usb_dev = ddf_fun_data_get(fun);
    262         assert(usb_dev);
     251        device_t *dev = ddf_fun_data_get(fun);
     252        assert(dev);
    263253        const usb_target_t target = {{
    264             .address =  usb_dev->address,
     254            .address  = dev->address,
    265255            .endpoint = endpoint,
    266256        }};
     
    343333}
    344334
    345 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub,
     335static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub,
    346336    unsigned port)
    347337{
     
    350340        hcd_t *hcd = dev_to_hcd(device);
    351341        assert(hcd);
     342        assert(hcd->bus);
    352343
    353344        hc_dev_t *hc_dev = dev_to_hc_dev(device);
     
    356347        fibril_mutex_lock(&hub->guard);
    357348
    358         usb_dev_t *victim = NULL;
    359 
    360         list_foreach(hub->devices, link, usb_dev_t, it) {
    361                 if (it->tt.port == port) {
     349        device_t *victim = NULL;
     350
     351        list_foreach(hub->devices, link, device_t, it) {
     352                if (it->port == port) {
    362353                        victim = it;
    363354                        break;
     
    366357        if (victim) {
    367358                assert(victim->fun);
    368                 assert(victim->tt.port == port);
     359                assert(victim->port == port);
     360                assert(victim->hub == hub);
    369361                list_remove(&victim->link);
    370362                fibril_mutex_unlock(&hub->guard);
     
    372364                if (ret == EOK) {
    373365                        usb_address_t address = victim->address;
     366                        bus_remove_device(hcd->bus, hcd, victim);
    374367                        ddf_fun_destroy(victim->fun);
    375                         hcd_release_address(hcd, address);
     368                        bus_release_address(hcd->bus, address);
    376369                } else {
    377370                        usb_log_warning("Failed to unbind device `%s': %s\n",
     
    384377}
    385378
    386 #define GET_DEVICE_DESC(size) \
    387 { \
    388         .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \
    389             | (USB_REQUEST_TYPE_STANDARD << 5) \
    390             | USB_REQUEST_RECIPIENT_DEVICE, \
    391         .request = USB_DEVREQ_GET_DESCRIPTOR, \
    392         .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \
    393         .index = uint16_host2usb(0), \
    394         .length = uint16_host2usb(size), \
    395 };
    396 
    397 #define SET_ADDRESS(address) \
    398 { \
    399         .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \
    400             | (USB_REQUEST_TYPE_STANDARD << 5) \
    401             | USB_REQUEST_RECIPIENT_DEVICE, \
    402         .request = USB_DEVREQ_SET_ADDRESS, \
    403         .value = uint16_host2usb(address), \
    404         .index = uint16_host2usb(0), \
    405         .length = uint16_host2usb(0), \
    406 };
    407 
    408 static int hcd_usb2_address_device(hcd_t *hcd, usb_speed_t speed,
    409     usb_tt_address_t tt, usb_address_t *out_address)
    410 {
    411         int err;
    412 
    413         static const usb_target_t default_target = {{
    414                 .address = USB_ADDRESS_DEFAULT,
    415                 .endpoint = 0,
    416         }};
    417 
    418         /** Reserve address early, we want pretty log messages */
    419         const usb_address_t address = hcd_request_address(hcd, speed);
    420         if (address < 0) {
    421                 usb_log_error("Failed to reserve new address: %s.",
    422                     str_error(address));
    423                 return address;
    424         }
    425         usb_log_debug("Device(%d): Reserved new address.", address);
    426 
    427         /* Add default pipe on default address */
    428         usb_log_debug("Device(%d): Adding default target (0:0)", address);
    429         err = hcd_add_ep(hcd,
    430             default_target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
    431             CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1, tt);
    432         if (err != EOK) {
    433                 usb_log_error("Device(%d): Failed to add default target: %s.",
    434                     address, str_error(err));
    435                 goto err_address;
    436         }
    437 
    438         /* Get max packet size for default pipe */
    439         usb_standard_device_descriptor_t desc = { 0 };
    440         const usb_device_request_setup_packet_t get_device_desc_8 =
    441             GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE);
    442 
    443         usb_log_debug("Device(%d): Requesting first 8B of device descriptor.",
    444             address);
    445         ssize_t got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_IN,
    446             &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8,
    447             "read first 8 bytes of dev descriptor");
    448 
    449         if (got != CTRL_PIPE_MIN_PACKET_SIZE) {
    450                 err = got < 0 ? got : EOVERFLOW;
    451                 usb_log_error("Device(%d): Failed to get 8B of dev descr: %s.",
    452                     address, str_error(err));
    453                 goto err_default_target;
    454         }
    455 
    456         /* Set new address */
    457         const usb_device_request_setup_packet_t set_address = SET_ADDRESS(address);
    458 
    459         usb_log_debug("Device(%d): Setting USB address.", address);
    460         err = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT,
    461             NULL, 0, *(uint64_t *)&set_address, "set address");
    462         if (err != 0) {
    463                 usb_log_error("Device(%d): Failed to set new address: %s.",
    464                     address, str_error(got));
    465                 goto err_default_target;
    466         }
    467 
    468         *out_address = address;
    469 
    470         usb_target_t control_ep = {
    471                 .address = address,
    472                 .endpoint = 0
    473         };
    474 
    475         /* Register EP on the new address */
    476         usb_log_debug("Device(%d): Registering control EP.", address);
    477         err = hcd_add_ep(hcd, control_ep, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
    478             ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)),
    479             ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(desc.max_packet_size)),
    480             ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), tt);
    481         if (err != EOK) {
    482                 usb_log_error("Device(%d): Failed to register EP0: %s",
    483                     address, str_error(err));
    484                 goto err_default_target;
    485         }
    486 
    487         hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
    488         return EOK;
    489 
    490 
    491 err_default_target:
    492         hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
    493 err_address:
    494         hcd_release_address(hcd, address);
    495         return err;
    496 }
    497 
    498 static int usb_dev_init(usb_dev_t *usb_dev, usb_speed_t speed)
    499 {
    500         memset(usb_dev, 0, sizeof(*usb_dev));
    501 
    502         link_initialize(&usb_dev->link);
    503         list_initialize(&usb_dev->devices);
    504         fibril_mutex_initialize(&usb_dev->guard);
    505 
    506         usb_dev->speed = speed;
    507 
    508         return EOK;
    509 }
    510 
    511 static usb_dev_t *usb_dev_create(ddf_dev_t *hc, usb_speed_t speed)
     379device_t *hcd_ddf_device_create(ddf_dev_t *hc, size_t device_size)
    512380{
    513381        /* Create DDF function for the new device */
     
    519387
    520388        /* Create USB device node for the new device */
    521         usb_dev_t *usb_dev = ddf_fun_data_alloc(fun, sizeof(usb_dev_t));
    522         if (!usb_dev) {
     389        device_t *dev = ddf_fun_data_alloc(fun, device_size);
     390        if (!dev) {
    523391                ddf_fun_destroy(fun);
    524392                return NULL;
    525393        }
    526394
    527         usb_dev_init(usb_dev, speed);
    528         usb_dev->fun = fun;
    529         return usb_dev;
    530 }
    531 
    532 static void usb_dev_destroy(usb_dev_t *dev)
     395        device_init(dev);
     396        dev->fun = fun;
     397        return dev;
     398}
     399
     400void hcd_ddf_device_destroy(device_t *dev)
    533401{
    534402        assert(dev);
     
    537405}
    538406
    539 static int usb_dev_set_default_name(usb_dev_t *usb_dev)
    540 {
    541         assert(usb_dev);
    542 
    543         char buf[10] = { 0 }; /* usbxyz-ss */
    544         snprintf(buf, sizeof(buf) - 1, "usb%u-%cs",
    545             usb_dev->address, usb_str_speed(usb_dev->speed)[0]);
    546 
    547         return ddf_fun_set_name(usb_dev->fun, buf);
    548 }
    549 
    550 static int usb_dev_explore(hcd_t *hcd, usb_dev_t *usb_dev)
     407int hcd_ddf_device_explore(hcd_t *hcd, device_t *device)
    551408{
    552409        int err;
     
    556413        init_match_ids(&mids);
    557414
    558         usb_target_t control_ep = {
    559                 .address = usb_dev->address,
     415        usb_target_t control_ep = {{
     416                .address = device->address,
    560417                .endpoint = 0
    561         };
     418        }};
    562419
    563420        /* Get std device descriptor */
     
    566423
    567424        usb_log_debug("Device(%d): Requesting full device descriptor.",
    568             usb_dev->address);
     425            device->address);
    569426        ssize_t got = hcd_send_batch_sync(hcd, control_ep, USB_DIRECTION_IN,
    570427            &desc, sizeof(desc), *(uint64_t *)&get_device_desc,
     
    573430                err = got < 0 ? got : EOVERFLOW;
    574431                usb_log_error("Device(%d): Failed to set get dev descriptor: %s",
    575                     usb_dev->address, str_error(err));
     432                    device->address, str_error(err));
    576433                goto out;
    577434        }
    578435
    579436        /* Create match ids from the device descriptor */
    580         usb_log_debug("Device(%d): Creating match IDs.", usb_dev->address);
     437        usb_log_debug("Device(%d): Creating match IDs.", device->address);
    581438        if ((err = create_match_ids(&mids, &desc))) {
    582                 usb_log_error("Device(%d): Failed to create match ids: %s", usb_dev->address, str_error(err));
     439                usb_log_error("Device(%d): Failed to create match ids: %s", device->address, str_error(err));
    583440                goto out;
    584441        }
    585442
    586443        list_foreach(mids.ids, link, const match_id_t, mid) {
    587                 ddf_fun_add_match_id(usb_dev->fun, mid->id, mid->score);
     444                ddf_fun_add_match_id(device->fun, mid->id, mid->score);
    588445        }
    589446
     
    593450}
    594451
    595 static int hcd_address_device(hcd_t *hcd, usb_dev_t *usb_dev)
    596 {
    597         if (hcd->ops.address_device)
    598                 return hcd->ops.address_device(hcd, usb_dev->speed, usb_dev->tt, &usb_dev->address);
    599         else
    600                 return hcd_usb2_address_device(hcd, usb_dev->speed, usb_dev->tt, &usb_dev->address);
    601 }
    602 
    603 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, usb_dev_t *hub_dev, unsigned port)
     452static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub, unsigned port)
    604453{
    605454        int err;
    606455        assert(hcd);
    607         assert(hub_dev);
     456        assert(hcd->bus);
     457        assert(hub);
    608458        assert(hc);
    609459
    610         usb_speed_t speed = USB_SPEED_MAX;
    611         /* The speed of the new device was reported by the hub when reserving
    612          * default address.
     460        device_t *dev = hcd_ddf_device_create(hc, hcd->bus->device_size);
     461        if (!dev) {
     462                usb_log_error("Failed to create USB device function.");
     463                return ENOMEM;
     464        }
     465
     466        dev->hub = hub;
     467        dev->port = port;
     468
     469        if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) {
     470                usb_log_error("Failed to initialize USB dev memory structures.");
     471                return err;
     472        }
     473
     474        /* If the driver didn't name the dev when enumerating,
     475         * do it in some generic way.
    613476         */
    614         if ((err = bus_get_speed(hcd->bus, USB_ADDRESS_DEFAULT, &speed))) {
    615                 usb_log_error("Failed to verify speed: %s.", str_error(err));
    616                 return err;
    617         }
    618         usb_log_debug("Found new %s speed USB device.", usb_str_speed(speed));
    619 
    620         usb_dev_t *usb_dev = usb_dev_create(hc, speed);
    621         if (!usb_dev) {
    622                 usb_log_error("Failed to create USB device function.");
    623                 return err;
    624         }
    625 
    626         /* For devices under HS hub */
    627         /* TODO: How about SS hubs? */
    628         if (hub_dev->speed == USB_SPEED_HIGH && usb_speed_is_11(speed)) {
    629                 usb_dev->tt.address = hub_dev->address;
    630         }
    631         else {
    632                 /* Inherit hub's TT */
    633                 usb_dev->tt.address = hub_dev->tt.address;
    634         }
    635         usb_dev->tt.port = port;
    636 
    637         /* Assign an address to the device */
    638         if ((err = hcd_address_device(hcd, usb_dev))) {
    639                 usb_log_error("Failed to setup address of the new device: %s", str_error(err));
     477        if (!ddf_fun_get_name(dev->fun)) {
     478                device_set_default_name(dev);
     479        }
     480
     481        if ((err = ddf_fun_bind(dev->fun))) {
     482                usb_log_error("Device(%d): Failed to register: %s.", dev->address, str_error(err));
    640483                goto err_usb_dev;
    641484        }
    642485
    643         /* Read the device descriptor, derive the match ids */
    644         if ((err = usb_dev_explore(hcd, usb_dev))) {
    645                 usb_log_error("Device(%d): Failed to explore device: %s", usb_dev->address, str_error(err));
    646                 goto err_usb_dev;
    647         }
    648 
    649         /* If the driver didn't name the device when addressing/exploring,
    650          * do it insome generic way.
    651          */
    652         if (!ddf_fun_get_name(usb_dev->fun)) {
    653                 usb_dev_set_default_name(usb_dev);
    654         }
    655 
    656         if ((err = ddf_fun_bind(usb_dev->fun))) {
    657                 usb_log_error("Device(%d): Failed to register: %s.", usb_dev->address, str_error(err));
    658                 goto err_usb_dev;
    659         }
    660 
    661         fibril_mutex_lock(&hub_dev->guard);
    662         list_append(&usb_dev->link, &hub_dev->devices);
    663         fibril_mutex_unlock(&hub_dev->guard);
     486        fibril_mutex_lock(&hub->guard);
     487        list_append(&dev->link, &hub->devices);
     488        fibril_mutex_unlock(&hub->guard);
    664489
    665490        return EOK;
    666491
    667492err_usb_dev:
    668         usb_dev_destroy(usb_dev);
     493        hcd_ddf_device_destroy(dev);
    669494        return err;
    670495}
     
    681506        assert(hc);
    682507        assert(hcd);
    683 
    684         if ((err = hcd_reserve_default_address(hcd, USB_SPEED_MAX))) {
     508        assert(hcd->bus);
     509
     510        if ((err = bus_reserve_default_address(hcd->bus, USB_SPEED_MAX))) {
    685511                usb_log_error("Failed to reserve default address for roothub setup: %s", str_error(err));
    686512                return err;
    687513        }
    688514
    689         usb_dev_t *usb_dev = usb_dev_create(hc, USB_SPEED_MAX);
    690         if (!usb_dev) {
     515        device_t *dev = hcd_ddf_device_create(hc, USB_SPEED_MAX);
     516        if (!dev) {
    691517                usb_log_error("Failed to create function for the root hub.");
    692518                goto err_default_address;
    693519        }
    694520
    695         usb_dev->tt.address = -1;
    696         usb_dev->tt.port = 0;
     521        ddf_fun_set_name(dev->fun, "roothub");
     522
     523        dev->tt = (usb_tt_address_t) {
     524                .address = -1,
     525                .port = 0,
     526        };
    697527
    698528        /* Assign an address to the device */
    699         if ((err = hcd_address_device(hcd, usb_dev))) {
    700                 usb_log_error("Failed to setup roothub address: %s", str_error(err));
     529        if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) {
     530                usb_log_error("Failed to enumerate roothub device: %s", str_error(err));
    701531                goto err_usb_dev;
    702532        }
    703533
    704         /* Read the device descriptor, derive the match ids */
    705         if ((err = usb_dev_explore(hcd, usb_dev))) {
    706                 usb_log_error("Failed to explore roothub: %s", str_error(err));
    707                 goto err_usb_dev;
    708         }
    709 
    710         ddf_fun_set_name(usb_dev->fun, "roothub");
    711 
    712         if ((err = ddf_fun_bind(usb_dev->fun))) {
     534        if ((err = ddf_fun_bind(dev->fun))) {
    713535                usb_log_error("Failed to register roothub: %s.", str_error(err));
    714536                goto err_usb_dev;
    715537        }
    716538
    717         hcd_release_default_address(hcd);
     539        bus_release_default_address(hcd->bus);
    718540        return EOK;
    719541
    720542err_usb_dev:
    721         usb_dev_destroy(usb_dev);
     543        hcd_ddf_device_destroy(dev);
    722544err_default_address:
    723         hcd_release_default_address(hcd);
     545        bus_release_default_address(hcd->bus);
    724546        return err;
    725547}
     
    1043865}
    1044866
    1045 struct hcd_roothub {
    1046         hcd_t *hcd;
    1047         ddf_dev_t *hc_dev;
    1048         usb_dev_t rh_usb;
    1049 };
    1050 
    1051 hcd_roothub_t *hcd_roothub_create(hcd_t *hcd, ddf_dev_t *dev, usb_speed_t speed)
    1052 {
    1053         hcd_roothub_t *rh = malloc(sizeof(*rh));
    1054 
    1055         rh->hcd = hcd;
    1056         rh->hc_dev = dev;
    1057         usb_dev_init(&rh->rh_usb, speed);
    1058 
    1059         rh->rh_usb.tt.address = -1;
    1060         return rh;
    1061 }
    1062 
    1063 int hcd_roothub_new_device(hcd_roothub_t *rh, unsigned port) {
    1064         return hcd_ddf_new_device(rh->hcd, rh->hc_dev, &rh->rh_usb, port);
    1065 }
    1066867/**
    1067868 * @}
  • uspace/lib/usbhost/src/hcd.c

    r867b375 r20eaa82  
    4545
    4646
    47 /*[>* Calls ep_add_hook upon endpoint registration.
    48  * @param ep Endpoint to be registered.
    49  * @param arg hcd_t in disguise.
    50  * @return Error code.
    51  * OH TODO: remove
    52  <]
    53 static int register_helper(endpoint_t *ep, void *arg)
    54 {
    55         hcd_t *hcd = arg;
    56         assert(ep);
    57         assert(hcd);
    58         if (hcd->ops.ep_add_hook)
    59                 return hcd->ops.ep_add_hook(hcd, ep);
    60         return EOK;
    61 }
    62 
    63 [>* Calls ep_remove_hook upon endpoint removal.
    64  * @param ep Endpoint to be unregistered.
    65  * @param arg hcd_t in disguise.
    66  * OH TODO: remove
    67  <]
    68 static void unregister_helper(endpoint_t *ep, void *arg)
    69 {
    70         hcd_t *hcd = arg;
    71         assert(ep);
    72         assert(hcd);
    73         if (hcd->ops.ep_remove_hook)
    74                 hcd->ops.ep_remove_hook(hcd, ep);
    75 }
    76 
    77 [>* Calls ep_remove_hook upon endpoint removal. Prints warning.
    78  *  * @param ep Endpoint to be unregistered.
    79  *   * @param arg hcd_t in disguise.
    80  * OH TODO: remove
    81  *    <]
    82 static void unregister_helper_warn(endpoint_t *ep, void *arg)
    83 {
    84         assert(ep);
    85         usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n",
    86             ep->target.address, ep->target.endpoint, usb_str_direction(ep->direction));
    87         unregister_helper(ep, arg);
    88 }
    89 */
    90 
    9147/** Initialize hcd_t structure.
    9248 * Initializes device and endpoint managers. Sets data and hook pointer to NULL.
     
    11268        return address;
    11369}
    114 
    115 int hcd_release_address(hcd_t *hcd, usb_address_t address)
    116 {
    117         assert(hcd);
    118         return bus_release_address(hcd->bus, address);
    119         // OH TODO removed helper
    120 }
    121 
    122 int hcd_reserve_default_address(hcd_t *hcd, usb_speed_t speed)
    123 {
    124         assert(hcd);
    125         usb_address_t address = 0;
    126         return bus_request_address(hcd->bus, &address, true, speed);
    127 }
    128 
    129 int hcd_add_ep(hcd_t *hcd, usb_target_t target, usb_direction_t dir,
    130     usb_transfer_type_t type, size_t max_packet_size, unsigned packets,
    131     size_t size, usb_tt_address_t tt)
    132 {
    133         assert(hcd);
    134 
    135         /* Temporary reference */
    136         endpoint_t *ep = bus_create_endpoint(hcd->bus);
    137         if (!ep)
    138                 return ENOMEM;
    139 
    140         ep->target = target;
    141         ep->direction = dir;
    142         ep->transfer_type = type;
    143         ep->max_packet_size = max_packet_size;
    144         ep->packets = packets;
    145         ep->tt = tt;
    146 
    147         ep->bandwidth = bus_count_bw(ep, size);
    148 
    149         const int err = bus_register_endpoint(hcd->bus, ep);
    150 
    151         /* drop Temporary reference */
    152         endpoint_del_ref(ep);
    153 
    154         return err;
    155 }
    156 
    157 int hcd_remove_ep(hcd_t *hcd, usb_target_t target, usb_direction_t dir)
    158 {
    159         assert(hcd);
    160         endpoint_t *ep = bus_find_endpoint(hcd->bus, target, dir);
    161         if (!ep)
    162                 return ENOENT;
    163 
    164         return bus_release_endpoint(hcd->bus, ep);
    165         // OH TODO removed helper
    166 }
    167 
    16870
    16971typedef struct {
  • uspace/lib/usbhost/src/usb2_bus.c

    r867b375 r20eaa82  
    3636#include <usb/host/usb2_bus.h>
    3737#include <usb/host/endpoint.h>
     38#include <usb/host/ddf_helpers.h>
    3839#include <usb/debug.h>
     40#include <usb/request.h>
     41#include <usb/descriptor.h>
     42#include <usb/usb.h>
    3943
    4044#include <assert.h>
    4145#include <errno.h>
    4246#include <macros.h>
     47#include <str_error.h>
    4348#include <stdlib.h>
    4449#include <stdbool.h>
     
    6166        assert(addr >= 0);
    6267        return &bus->devices[addr % ARRAY_SIZE(bus->devices)].endpoint_list;
     68}
     69
     70/** Get speed assigned to USB address.
     71 *
     72 * @param[in] bus Device manager structure to use.
     73 * @param[in] address Address the caller wants to find.
     74 * @param[out] speed Assigned speed.
     75 * @return Error code.
     76 */
     77static int usb2_bus_get_speed(bus_t *bus_base, usb_address_t address, usb_speed_t *speed)
     78{
     79        usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
     80
     81        if (!usb_address_is_valid(address)) {
     82                return EINVAL;
     83        }
     84
     85        const int ret = bus->devices[address].occupied ? EOK : ENOENT;
     86        if (speed && bus->devices[address].occupied) {
     87                *speed = bus->devices[address].speed;
     88        }
     89
     90        return ret;
     91}
     92
     93static int usb2_bus_address_device(bus_t *bus, hcd_t *hcd, device_t *dev)
     94{
     95        int err;
     96
     97        static const usb_target_t default_target = {{
     98                .address = USB_ADDRESS_DEFAULT,
     99                .endpoint = 0,
     100        }};
     101
     102        /** Reserve address early, we want pretty log messages */
     103        const usb_address_t address = bus_reserve_default_address(bus, dev->speed);
     104        if (address < 0) {
     105                usb_log_error("Failed to reserve new address: %s.",
     106                    str_error(address));
     107                return address;
     108        }
     109        usb_log_debug("Device(%d): Reserved new address.", address);
     110
     111        /* Add default pipe on default address */
     112        usb_log_debug("Device(%d): Adding default target (0:0)", address);
     113        err = bus_add_ep(bus, dev, 0, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
     114            CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1);
     115        if (err != EOK) {
     116                usb_log_error("Device(%d): Failed to add default target: %s.",
     117                    address, str_error(err));
     118                goto err_address;
     119        }
     120
     121        /* Get max packet size for default pipe */
     122        usb_standard_device_descriptor_t desc = { 0 };
     123        const usb_device_request_setup_packet_t get_device_desc_8 =
     124            GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE);
     125
     126        usb_log_debug("Device(%d): Requesting first 8B of device descriptor.",
     127            address);
     128        ssize_t got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_IN,
     129            &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8,
     130            "read first 8 bytes of dev descriptor");
     131
     132        if (got != CTRL_PIPE_MIN_PACKET_SIZE) {
     133                err = got < 0 ? got : EOVERFLOW;
     134                usb_log_error("Device(%d): Failed to get 8B of dev descr: %s.",
     135                    address, str_error(err));
     136                goto err_default_target;
     137        }
     138
     139        /* Set new address */
     140        const usb_device_request_setup_packet_t set_address = SET_ADDRESS(address);
     141
     142        usb_log_debug("Device(%d): Setting USB address.", address);
     143        err = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT,
     144            NULL, 0, *(uint64_t *)&set_address, "set address");
     145        if (err != 0) {
     146                usb_log_error("Device(%d): Failed to set new address: %s.",
     147                    address, str_error(got));
     148                goto err_default_target;
     149        }
     150
     151        dev->address = address;
     152
     153        /* Register EP on the new address */
     154        usb_log_debug("Device(%d): Registering control EP.", address);
     155        err = bus_add_ep(bus, dev, 0, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
     156            ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)),
     157            ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(desc.max_packet_size)),
     158            ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)));
     159        if (err != EOK) {
     160                usb_log_error("Device(%d): Failed to register EP0: %s",
     161                    address, str_error(err));
     162                goto err_default_target;
     163        }
     164
     165        bus_remove_ep(bus, default_target, USB_DIRECTION_BOTH);
     166        return EOK;
     167
     168err_default_target:
     169        bus_remove_ep(bus, default_target, USB_DIRECTION_BOTH);
     170err_address:
     171        bus_release_address(bus, address);
     172        return err;
     173}
     174
     175/** Enumerate a new USB device
     176 */
     177static int usb2_bus_enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev)
     178{
     179        int err;
     180
     181        /* The speed of the new device was reported by the hub when reserving
     182         * default address.
     183         */
     184        if ((err = usb2_bus_get_speed(bus, USB_ADDRESS_DEFAULT, &dev->speed))) {
     185                usb_log_error("Failed to verify speed: %s.", str_error(err));
     186                return err;
     187        }
     188        usb_log_debug("Found new %s speed USB device.", usb_str_speed(dev->speed));
     189
     190        /* Manage TT */
     191        if (dev->hub->speed == USB_SPEED_HIGH && usb_speed_is_11(dev->speed)) {
     192                /* For LS devices under HS hub */
     193                /* TODO: How about SS hubs? */
     194                dev->tt.address = dev->hub->address;
     195                dev->tt.port = dev->port;
     196        }
     197        else {
     198                /* Inherit hub's TT */
     199                dev->tt = dev->hub->tt;
     200        }
     201
     202        /* Assign an address to the device */
     203        if ((err = usb2_bus_address_device(bus, hcd, dev))) {
     204                usb_log_error("Failed to setup address of the new device: %s", str_error(err));
     205                return err;
     206        }
     207
     208        /* Read the device descriptor, derive the match ids */
     209        if ((err = hcd_ddf_device_explore(hcd, dev))) {
     210                usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err));
     211                bus_release_address(bus, dev->address);
     212                return err;
     213        }
     214
     215        return EOK;
    63216}
    64217
     
    190343 * @param endpoint USB endpoint number.
    191344 * @param direction Communication direction.
    192  * @param callback Function to call after unregister, before destruction.
    193  * @arg Argument to pass to the callback function.
    194345 * @return Error code.
    195346 */
     
    211362                list_remove(&ep->link);
    212363
     364                usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n",
     365                    ep->target.address, ep->target.endpoint, usb_str_direction(ep->direction));
     366
    213367                /* Drop bus reference */
    214368                endpoint_del_ref(ep);
     
    258412}
    259413
    260 /** Get speed assigned to USB address.
    261  *
    262  * @param[in] bus Device manager structure to use.
    263  * @param[in] address Address the caller wants to find.
    264  * @param[out] speed Assigned speed.
    265  * @return Error code.
    266  */
    267 static int usb2_bus_get_speed(bus_t *bus_base, usb_address_t address, usb_speed_t *speed)
    268 {
    269         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
    270 
    271         if (!usb_address_is_valid(address)) {
    272                 return EINVAL;
    273         }
    274 
    275         const int ret = bus->devices[address].occupied ? EOK : ENOENT;
    276         if (speed && bus->devices[address].occupied) {
    277                 *speed = bus->devices[address].speed;
    278         }
    279 
    280         return ret;
    281 }
    282 
    283414static const bus_ops_t usb2_bus_ops = {
     415        .enumerate_device = usb2_bus_enumerate_device,
    284416        .create_endpoint = usb2_bus_create_ep,
    285417        .find_endpoint = usb2_bus_find_ep,
     
    289421        .release_address = usb2_bus_release_address,
    290422        .reset_toggle = usb2_bus_reset_toggle,
    291         .get_speed = usb2_bus_get_speed,
    292423};
    293424
     
    303434        assert(bus);
    304435
    305         bus_init(&bus->base);
     436        bus_init(&bus->base, sizeof(device_t));
    306437
    307438        bus->base.ops = usb2_bus_ops;
Note: See TracChangeset for help on using the changeset viewer.