Changeset 682c9354 in mainline


Ignore:
Timestamp:
2018-01-20T15:32:12Z (6 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
abb5d08
Parents:
129b821f
Message:

xhci: move all real functionality from bus to device/endpoint/transfers

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

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/Makefile

    r129b821f r682c9354  
    3737        commands.c \
    3838        debug.c \
     39        device.c \
    3940        endpoint.c \
    4041        hc.c \
  • uspace/drv/bus/usb/xhci/bus.c

    r129b821f r682c9354  
    3030 */
    3131/** @file
    32  * HC Endpoint management.
     32 * xHCI bus interface.
    3333 */
    3434
    35 #include <usb/host/ddf_helpers.h>
    36 #include <usb/host/endpoint.h>
    37 #include <usb/host/hcd.h>
    38 #include <usb/host/utility.h>
    39 #include <usb/classes/classes.h>
    40 #include <usb/classes/hub.h>
    4135#include <usb/descriptor.h>
    42 #include <usb/debug.h>
    43 
    44 #include <assert.h>
    45 #include <errno.h>
    46 #include <str_error.h>
    47 #include <macros.h>
    48 #include <stdbool.h>
    4936
    5037#include "hc.h"
    51 #include "bus.h"
     38#include "device.h"
    5239#include "endpoint.h"
    5340#include "transfers.h"
    5441
     42#include "bus.h"
    5543
    56 /** Initial descriptor used for control endpoint 0 before more configuration is retrieved. */
    57 static const usb_endpoint_descriptors_t ep0_initial_desc = {
    58         .endpoint.max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE,
    59 };
    60 
    61 static endpoint_t *endpoint_create(device_t *, const usb_endpoint_descriptors_t *);
    62 
    63 /**
    64  * Assign address and control endpoint to a new XHCI device. Once this function
    65  * successfully returns, the device is online.
    66  *
    67  * @param[in] bus XHCI bus, in which the address is assigned.
    68  * @param[in] dev New device to address and configure./e
    69  * @return Error code.
    70  */
    71 static int address_device(xhci_device_t *dev)
    72 {
    73         int err;
    74 
    75         /* Enable new slot. */
    76         if ((err = hc_enable_slot(dev)) != EOK)
    77                 return err;
    78         usb_log_debug2("Obtained slot ID: %u.", dev->slot_id);
    79 
    80         /* Create and configure control endpoint. */
    81         endpoint_t *ep0_base = endpoint_create(&dev->base, &ep0_initial_desc);
    82         if (!ep0_base)
    83                 goto err_slot;
    84 
    85         /* Bus reference */
    86         endpoint_add_ref(ep0_base);
    87         dev->base.endpoints[0] = ep0_base;
    88 
    89         xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base);
    90 
    91         /* Address device */
    92         if ((err = hc_address_device(dev, ep0)))
    93                 goto err_added;
    94 
    95         return EOK;
    96 
    97 err_added:
    98         /* Bus reference */
    99         endpoint_del_ref(ep0_base);
    100         dev->base.endpoints[0] = NULL;
    101 err_slot:
    102         hc_disable_slot(dev);
    103         return err;
    104 }
    105 
    106 /**
    107  * Retrieve and set maximum packet size for endpoint zero of a XHCI device.
    108  *
    109  * @param[in] hc Host controller, which manages the device.
    110  * @param[in] dev Device with operational endpoint zero.
    111  * @return Error code.
    112  */
    113 static int setup_ep0_packet_size(xhci_hc_t *hc, xhci_device_t *dev)
    114 {
    115         int err;
    116 
    117         uint16_t max_packet_size;
    118         if ((err = hc_get_ep0_max_packet_size(&max_packet_size, (bus_t *) &hc->bus, &dev->base)))
    119                 return err;
    120 
    121         xhci_endpoint_t *ep0 = xhci_endpoint_get(dev->base.endpoints[0]);
    122         assert(ep0);
    123 
    124         if (ep0->base.max_packet_size == max_packet_size)
    125                 return EOK;
    126 
    127         ep0->base.max_packet_size = max_packet_size;
    128         ep0->base.max_transfer_size = max_packet_size * ep0->base.packets_per_uframe;
    129 
    130         xhci_ep_ctx_t ep_ctx;
    131         xhci_setup_endpoint_context(ep0, &ep_ctx);
    132 
    133         if ((err = hc_update_endpoint(dev, 0, &ep_ctx)))
    134                 return err;
    135 
    136         return EOK;
    137 }
    138 
    139 /**
    140  * Check whether the device is a hub and if so, fill its characterstics.
    141  *
    142  * If this fails, it does not necessarily mean the device is unusable.
    143  * Just the TT will not work correctly.
    144  */
    145 static int setup_hub(xhci_device_t *dev, usb_standard_device_descriptor_t *desc)
    146 {
    147         if (desc->device_class != USB_CLASS_HUB)
    148                 return EOK;
    149 
    150         usb_hub_descriptor_header_t hub_desc = { 0 };
    151         const int err = hc_get_hub_desc(&dev->base, &hub_desc);
    152         if (err)
    153                 return err;
    154 
    155         dev->is_hub = 1;
    156         dev->num_ports = hub_desc.port_count;
    157         dev->tt_think_time = 8 +
    158                 8  * !!(hub_desc.characteristics & HUB_CHAR_TT_THINK_8) +
    159                 16 * !!(hub_desc.characteristics & HUB_CHAR_TT_THINK_16);
    160 
    161         usb_log_debug2("Device(%u): recognised USB hub with %u ports", dev->base.address, dev->num_ports);
    162         return EOK;
    163 }
    164 
    165 /**
    166  * Respond to a new device on the XHCI bus. Address it, negotiate packet size
    167  * and retrieve USB descriptors.
    168  *
    169  * @param[in] bus XHCI bus, where the new device emerged.
    170  * @param[in] dev XHCI device, which has appeared on the bus.
    171  *
    172  * @return Error code.
    173  */
    174 static int device_enumerate(device_t *dev)
    175 {
    176         int err;
    177         xhci_bus_t *bus = bus_to_xhci_bus(dev->bus);
    178         xhci_device_t *xhci_dev = xhci_device_get(dev);
    179 
    180         /* Calculate route string */
    181         xhci_device_t *xhci_hub = xhci_device_get(dev->hub);
    182         xhci_dev->tier = xhci_hub->tier + 1;
    183         xhci_dev->route_str = xhci_hub->route_str;
    184 
    185         /* Roothub port is not part of the route string */
    186         if (xhci_dev->tier >= 2) {
    187                 const unsigned offset = 4 * (xhci_dev->tier - 2);
    188                 xhci_dev->route_str |= (dev->port & 0xf) << offset;
    189                 xhci_dev->rh_port = xhci_hub->rh_port;
    190         }
    191 
    192         int retries = 3;
    193         do {
    194                 /* Assign an address to the device */
    195                 err = address_device(xhci_dev);
    196         } while (err == ESTALL && --retries > 0);
    197 
    198         if (err) {
    199                 usb_log_error("Failed to setup address of the new device: %s", str_error(err));
    200                 return err;
    201         }
    202 
    203         /* Setup EP0 might already need to issue a transfer. */
    204         fibril_mutex_lock(&bus->base.guard);
    205         assert(bus->devices_by_slot[xhci_dev->slot_id] == NULL);
    206         bus->devices_by_slot[xhci_dev->slot_id] = xhci_dev;
    207         fibril_mutex_unlock(&bus->base.guard);
    208 
    209         if ((err = setup_ep0_packet_size(bus->hc, xhci_dev))) {
    210                 usb_log_error("Failed to setup control endpoint of the new device: %s", str_error(err));
    211                 goto err_address;
    212         }
    213 
    214         usb_standard_device_descriptor_t desc = { 0 };
    215 
    216         if ((err = hc_get_device_desc(dev, &desc))) {
    217                 usb_log_error("Device(%d): failed to get devices descriptor: %s", dev->address, str_error(err));
    218                 goto err_address;
    219         }
    220 
    221         if ((err = setup_hub(xhci_dev, &desc)))
    222                 usb_log_warning("Device(%d): failed to setup hub characteristics: %s. "
    223                     " Continuing anyway.", dev->address, str_error(err));
    224 
    225         if ((err = hcd_ddf_setup_match_ids(dev, &desc))) {
    226                 usb_log_error("Device(%d): failed to setup match IDs: %s", dev->address, str_error(err));
    227                 goto err_address;
    228         }
    229 
    230         return EOK;
    231 
    232 err_address:
    233         // TODO: deaddress device
    234         return err;
    235 }
    236 
    237 /**
    238  * Remove device from XHCI bus. Transition it to the offline state, abort all
    239  * ongoing transfers and unregister all of its endpoints.
    240  *
    241  * Bus callback.
    242  *
    243  * @param[in] bus XHCI bus, from which the device is removed.
    244  * @param[in] dev XHCI device, which is removed from the bus.
    245  * @return Error code.
    246  */
    247 static void device_gone(device_t *dev)
    248 {
    249         int err;
    250         xhci_bus_t *bus = bus_to_xhci_bus(dev->bus);
    251         xhci_device_t *xhci_dev = xhci_device_get(dev);
    252 
    253         /* Disable the slot, dropping all endpoints. */
    254         const uint32_t slot_id = xhci_dev->slot_id;
    255         if ((err = hc_disable_slot(xhci_dev))) {
    256                 usb_log_warning("Failed to disable slot of device " XHCI_DEV_FMT ": %s",
    257                     XHCI_DEV_ARGS(*xhci_dev), str_error(err));
    258         }
    259 
    260         bus->devices_by_slot[slot_id] = NULL;
    261 }
    262 
    263 /**
    264  * Reverts things device_offline did, getting the device back up.
    265  *
    266  * Bus callback.
    267  */
    268 static int device_online(device_t *dev_base)
    269 {
    270         int err;
    271 
    272         xhci_bus_t *bus = bus_to_xhci_bus(dev_base->bus);
    273         assert(bus);
    274 
    275         xhci_device_t *dev = xhci_device_get(dev_base);
    276         assert(dev);
    277 
    278         /* Transition the device from the Addressed to the Configured state. */
    279         if ((err = hc_configure_device(dev))) {
    280                 usb_log_warning("Failed to configure device " XHCI_DEV_FMT ".", XHCI_DEV_ARGS(*dev));
    281                 return err;
    282         }
    283 
    284         return EOK;
    285 }
    286 
    287 /**
    288  * Make given device offline. Offline the DDF function, tear down all
    289  * endpoints, issue Deconfigure Device command to xHC.
    290  *
    291  * Bus callback.
    292  */
    293 static void device_offline(device_t *dev_base)
    294 {
    295         int err;
    296 
    297         xhci_bus_t *bus = bus_to_xhci_bus(dev_base->bus);
    298         assert(bus);
    299 
    300         xhci_device_t *dev = xhci_device_get(dev_base);
    301         assert(dev);
    302 
    303         /* Issue one HC command to simultaneously drop all endpoints except zero. */
    304         if ((err = hc_deconfigure_device(dev))) {
    305                 usb_log_warning("Failed to deconfigure device " XHCI_DEV_FMT ".",
    306                     XHCI_DEV_ARGS(*dev));
    307         }
    308 }
    309 
    310 /**
    311  * Create a new xHCI endpoint structure.
    312  *
    313  * Bus callback.
    314  */
    315 static endpoint_t *endpoint_create(device_t *dev, const usb_endpoint_descriptors_t *desc)
    316 {
    317         const usb_transfer_type_t type = USB_ED_GET_TRANSFER_TYPE(desc->endpoint);
    318 
    319         xhci_endpoint_t *ep = calloc(1, sizeof(xhci_endpoint_t)
    320                 + (type == USB_TRANSFER_ISOCHRONOUS) * sizeof(*ep->isoch));
    321         if (!ep)
    322                 return NULL;
    323 
    324         if (xhci_endpoint_init(ep, dev, desc)) {
    325                 free(ep);
    326                 return NULL;
    327         }
    328 
    329         return &ep->base;
    330 }
    331 
    332 /**
    333  * Destroy given xHCI endpoint structure.
    334  *
    335  * Bus callback.
    336  */
    337 static void endpoint_destroy(endpoint_t *ep)
    338 {
    339         xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep);
    340 
    341         xhci_endpoint_fini(xhci_ep);
    342         free(xhci_ep);
    343 }
    344 
    345 /**
    346  * Register an andpoint to the xHC.
    347  *
    348  * Bus callback.
    349  */
    350 static int endpoint_register(endpoint_t *ep_base)
    351 {
    352         int err;
    353         xhci_endpoint_t *ep = xhci_endpoint_get(ep_base);
    354         xhci_device_t *dev = xhci_device_get(ep_base->device);
    355 
    356         xhci_ep_ctx_t ep_ctx;
    357         xhci_setup_endpoint_context(ep, &ep_ctx);
    358 
    359         if ((err = hc_add_endpoint(dev, xhci_endpoint_index(ep), &ep_ctx)))
    360                 return err;
    361 
    362         return EOK;
    363 }
    364 
    365 /**
    366  * Abort a transfer on an endpoint.
    367  */
    368 static int endpoint_abort(endpoint_t *ep)
    369 {
    370         xhci_device_t *dev = xhci_device_get(ep->device);
    371 
    372         usb_transfer_batch_t *batch = NULL;
    373         fibril_mutex_lock(&ep->guard);
    374         if (ep->active_batch) {
    375                 if (dev->slot_id) {
    376                         const int err = hc_stop_endpoint(dev, xhci_endpoint_dci(xhci_endpoint_get(ep)));
    377                         if (err) {
    378                                 usb_log_warning("Failed to stop endpoint %u of device " XHCI_DEV_FMT ": %s",
    379                                     ep->endpoint, XHCI_DEV_ARGS(*dev), str_error(err));
    380                         }
    381 
    382                         endpoint_wait_timeout_locked(ep, 2000);
    383                 }
    384 
    385                 batch = ep->active_batch;
    386                 if (batch) {
    387                         endpoint_deactivate_locked(ep);
    388                 }
    389         }
    390         fibril_mutex_unlock(&ep->guard);
    391 
    392         if (batch) {
    393                 batch->error = EINTR;
    394                 batch->transfered_size = 0;
    395                 usb_transfer_batch_finish(batch);
    396         }
    397         return EOK;
    398 }
    399 
    400 /**
    401  * Unregister an endpoint. If the device is still available, inform the xHC
    402  * about it.
    403  *
    404  * Bus callback.
    405  */
    406 static void endpoint_unregister(endpoint_t *ep_base)
    407 {
    408         int err;
    409         xhci_endpoint_t *ep = xhci_endpoint_get(ep_base);
    410         xhci_device_t *dev = xhci_device_get(ep_base->device);
    411 
    412         endpoint_abort(ep_base);
    413 
    414         /* If device slot is still available, drop the endpoint. */
    415         if (dev->slot_id) {
    416 
    417                 if ((err = hc_drop_endpoint(dev, xhci_endpoint_index(ep)))) {
    418                         usb_log_error("Failed to drop endpoint " XHCI_EP_FMT ": %s", XHCI_EP_ARGS(*ep), str_error(err));
    419                 }
    420         } else {
    421                 usb_log_debug("Not going to drop endpoint " XHCI_EP_FMT " because"
    422                     " the slot has already been disabled.", XHCI_EP_ARGS(*ep));
    423         }
    424 }
    425 
    426 /**
    427  * Schedule a batch for xHC.
    428  *
    429  * Bus callback.
    430  */
    431 static int batch_schedule(usb_transfer_batch_t *batch)
    432 {
    433         assert(batch);
    434         xhci_hc_t *hc = bus_to_hc(endpoint_get_bus(batch->ep));
    435 
    436         if (!batch->target.address) {
    437                 usb_log_error("Attempted to schedule transfer to address 0.");
    438                 return EINVAL;
    439         }
    440 
    441         return xhci_transfer_schedule(hc, batch);
    442 }
    44344
    44445static const bus_ops_t xhci_bus_ops = {
     
    44647        .status = hc_status,
    44748
    448         .device_enumerate = device_enumerate,
    449         .device_gone = device_gone,
    450         .device_online = device_online,
    451         .device_offline = device_offline,
     49        .device_enumerate = xhci_device_enumerate,
     50        .device_gone = xhci_device_gone,
     51        .device_online = xhci_device_online,
     52        .device_offline = xhci_device_offline,
    45253
    453         .endpoint_create = endpoint_create,
    454         .endpoint_destroy = endpoint_destroy,
    455         .endpoint_register = endpoint_register,
    456         .endpoint_unregister = endpoint_unregister,
     54        .endpoint_create = xhci_endpoint_create,
     55        .endpoint_destroy = xhci_endpoint_destroy,
     56        .endpoint_register = xhci_endpoint_register,
     57        .endpoint_unregister = xhci_endpoint_unregister,
    45758
    458         .batch_schedule = batch_schedule,
     59        .batch_schedule = xhci_transfer_schedule,
    45960        .batch_create = xhci_transfer_create,
    46061        .batch_destroy = xhci_transfer_destroy,
  • uspace/drv/bus/usb/xhci/bus.h

    r129b821f r682c9354  
    3838#define XHCI_BUS_H
    3939
    40 #include <usb/usb.h>
    4140#include <usb/host/bus.h>
    4241
     
    5655void xhci_bus_fini(xhci_bus_t *);
    5756
    58 int xhci_bus_enumerate_device(xhci_bus_t *, device_t *);
    59 int xhci_bus_remove_device(xhci_bus_t *, device_t *);
    60 
    6157static inline xhci_bus_t *bus_to_xhci_bus(bus_t *bus_base)
    6258{
  • uspace/drv/bus/usb/xhci/endpoint.c

    r129b821f r682c9354  
    3939#include <errno.h>
    4040#include <macros.h>
     41#include <str_error.h>
    4142
    4243#include "hc.h"
    4344#include "bus.h"
    4445#include "commands.h"
     46#include "device.h"
    4547#include "endpoint.h"
    4648#include "streams.h"
     
    5658 * @return Error code.
    5759 */
    58 int xhci_endpoint_init(xhci_endpoint_t *xhci_ep, device_t *dev, const usb_endpoint_descriptors_t *desc)
     60static int xhci_endpoint_init(xhci_endpoint_t *xhci_ep, device_t *dev, const usb_endpoint_descriptors_t *desc)
    5961{
    6062        int rc;
     
    113115
    114116/**
     117 * Create a new xHCI endpoint structure.
     118 *
     119 * Bus callback.
     120 */
     121endpoint_t *xhci_endpoint_create(device_t *dev, const usb_endpoint_descriptors_t *desc)
     122{
     123        const usb_transfer_type_t type = USB_ED_GET_TRANSFER_TYPE(desc->endpoint);
     124
     125        xhci_endpoint_t *ep = calloc(1, sizeof(xhci_endpoint_t)
     126                + (type == USB_TRANSFER_ISOCHRONOUS) * sizeof(*ep->isoch));
     127        if (!ep)
     128                return NULL;
     129
     130        if (xhci_endpoint_init(ep, dev, desc)) {
     131                free(ep);
     132                return NULL;
     133        }
     134
     135        return &ep->base;
     136}
     137
     138/**
    115139 * Finalize XHCI endpoint.
    116140 * @param[in] xhci_ep XHCI endpoint to finalize.
    117141 */
    118 void xhci_endpoint_fini(xhci_endpoint_t *xhci_ep)
     142static void xhci_endpoint_fini(xhci_endpoint_t *xhci_ep)
    119143{
    120144        assert(xhci_ep);
     
    123147
    124148        // TODO: Something missed?
     149}
     150
     151/**
     152 * Destroy given xHCI endpoint structure.
     153 *
     154 * Bus callback.
     155 */
     156void xhci_endpoint_destroy(endpoint_t *ep)
     157{
     158        xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep);
     159
     160        xhci_endpoint_fini(xhci_ep);
     161        free(xhci_ep);
     162}
     163
     164
     165/**
     166 * Register an andpoint to the xHC.
     167 *
     168 * Bus callback.
     169 */
     170int xhci_endpoint_register(endpoint_t *ep_base)
     171{
     172        int err;
     173        xhci_endpoint_t *ep = xhci_endpoint_get(ep_base);
     174        xhci_device_t *dev = xhci_device_get(ep_base->device);
     175
     176        xhci_ep_ctx_t ep_ctx;
     177        xhci_setup_endpoint_context(ep, &ep_ctx);
     178
     179        if ((err = hc_add_endpoint(dev, xhci_endpoint_index(ep), &ep_ctx)))
     180                return err;
     181
     182        return EOK;
     183}
     184
     185/**
     186 * Abort a transfer on an endpoint.
     187 */
     188static int endpoint_abort(endpoint_t *ep)
     189{
     190        xhci_device_t *dev = xhci_device_get(ep->device);
     191
     192        usb_transfer_batch_t *batch = NULL;
     193        fibril_mutex_lock(&ep->guard);
     194        if (ep->active_batch) {
     195                if (dev->slot_id) {
     196                        const int err = hc_stop_endpoint(dev, xhci_endpoint_dci(xhci_endpoint_get(ep)));
     197                        if (err) {
     198                                usb_log_warning("Failed to stop endpoint %u of device " XHCI_DEV_FMT ": %s",
     199                                    ep->endpoint, XHCI_DEV_ARGS(*dev), str_error(err));
     200                        }
     201
     202                        endpoint_wait_timeout_locked(ep, 2000);
     203                }
     204
     205                batch = ep->active_batch;
     206                if (batch) {
     207                        endpoint_deactivate_locked(ep);
     208                }
     209        }
     210        fibril_mutex_unlock(&ep->guard);
     211
     212        if (batch) {
     213                batch->error = EINTR;
     214                batch->transfered_size = 0;
     215                usb_transfer_batch_finish(batch);
     216        }
     217        return EOK;
     218}
     219
     220/**
     221 * Unregister an endpoint. If the device is still available, inform the xHC
     222 * about it.
     223 *
     224 * Bus callback.
     225 */
     226void xhci_endpoint_unregister(endpoint_t *ep_base)
     227{
     228        int err;
     229        xhci_endpoint_t *ep = xhci_endpoint_get(ep_base);
     230        xhci_device_t *dev = xhci_device_get(ep_base->device);
     231
     232        endpoint_abort(ep_base);
     233
     234        /* If device slot is still available, drop the endpoint. */
     235        if (dev->slot_id) {
     236
     237                if ((err = hc_drop_endpoint(dev, xhci_endpoint_index(ep)))) {
     238                        usb_log_error("Failed to drop endpoint " XHCI_EP_FMT ": %s", XHCI_EP_ARGS(*ep), str_error(err));
     239                }
     240        } else {
     241                usb_log_debug("Not going to drop endpoint " XHCI_EP_FMT " because"
     242                    " the slot has already been disabled.", XHCI_EP_ARGS(*ep));
     243        }
    125244}
    126245
  • uspace/drv/bus/usb/xhci/endpoint.h

    r129b821f r682c9354  
    4545#include <ddf/driver.h>
    4646
     47#include "device.h"
    4748#include "isoch.h"
    4849#include "transfers.h"
     
    105106        (usb_str_transfer_type((ep).base.transfer_type))
    106107
    107 typedef struct xhci_device {
    108         device_t base;          /**< Inheritance. Keep this first. */
    109 
    110         /** Slot ID assigned to the device by xHC. */
    111         uint32_t slot_id;
    112 
    113         /** Corresponding port on RH */
    114         uint8_t rh_port;
    115 
    116         /** USB Tier of the device */
    117         uint8_t tier;
    118 
    119         /** Route string */
    120         uint32_t route_str;
    121 
    122         /** Place to store the allocated context */
    123         dma_buffer_t dev_ctx;
    124 
    125         /** Hub specific information. Valid only if the device is_hub. */
    126         bool is_hub;
    127         uint8_t num_ports;
    128         uint8_t tt_think_time;
    129 } xhci_device_t;
    130 
    131 #define XHCI_DEV_FMT  "(%s, slot %d)"
    132 #define XHCI_DEV_ARGS(dev)               ddf_fun_get_name((dev).base.fun), (dev).slot_id
    133 
    134108int xhci_endpoint_type(xhci_endpoint_t *ep);
    135109
    136 int xhci_endpoint_init(xhci_endpoint_t *, device_t *, const usb_endpoint_descriptors_t *);
    137 void xhci_endpoint_fini(xhci_endpoint_t *);
     110endpoint_t *xhci_endpoint_create(device_t *, const usb_endpoint_descriptors_t *);
     111int xhci_endpoint_register(endpoint_t *);
     112void xhci_endpoint_unregister(endpoint_t *);
     113void xhci_endpoint_destroy(endpoint_t *);
    138114
    139115void xhci_endpoint_free_transfer_ds(xhci_endpoint_t *xhci_ep);
     
    144120void xhci_setup_endpoint_context(xhci_endpoint_t *, xhci_ep_ctx_t *);
    145121int xhci_endpoint_clear_halt(xhci_endpoint_t *, unsigned);
    146 
    147 static inline xhci_device_t * xhci_device_get(device_t *dev)
    148 {
    149         assert(dev);
    150         return (xhci_device_t *) dev;
    151 }
    152122
    153123static inline xhci_endpoint_t * xhci_endpoint_get(endpoint_t *ep)
  • uspace/drv/bus/usb/xhci/transfers.c

    r129b821f r682c9354  
    416416};
    417417
    418 int xhci_transfer_schedule(xhci_hc_t *hc, usb_transfer_batch_t *batch)
    419 {
    420         assert(hc);
     418/**
     419 * Schedule a batch for xHC.
     420 *
     421 * Bus callback.
     422 */
     423int xhci_transfer_schedule(usb_transfer_batch_t *batch)
     424{
    421425        endpoint_t *ep = batch->ep;
    422426
     427        xhci_hc_t *hc = bus_to_hc(endpoint_get_bus(batch->ep));
    423428        xhci_transfer_t *transfer = xhci_transfer_from_batch(batch);
    424429        xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep);
    425430        xhci_device_t *xhci_dev = xhci_ep_to_dev(xhci_ep);
     431
     432        if (!batch->target.address) {
     433                usb_log_error("Attempted to schedule transfer to address 0.");
     434                return EINVAL;
     435        }
    426436
    427437        // FIXME: find a better way to check if the ring is not initialized
  • uspace/drv/bus/usb/xhci/transfers.h

    r129b821f r682c9354  
    5656
    5757usb_transfer_batch_t* xhci_transfer_create(endpoint_t *);
    58 int xhci_transfer_schedule(xhci_hc_t *, usb_transfer_batch_t *);
     58int xhci_transfer_schedule(usb_transfer_batch_t *);
     59
    5960int xhci_handle_transfer_event(xhci_hc_t *, xhci_trb_t *);
    6061void xhci_transfer_destroy(usb_transfer_batch_t *);
Note: See TracChangeset for help on using the changeset viewer.