source: mainline/uspace/drv/bus/usb/xhci/endpoint.h@ f92f6b1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since f92f6b1 was 708d8fcd, checked in by Ondřej Hlavatý <aearsis@…>, 8 years ago

xhci: rewritten isochronous transfers

There was a fundamental problem with relying on hardware to send
RING_OVERRUN/UNDERRUN events, which QEMU (and possibly others) do not
send. That resulted in not knowing if the transfer is still on schedule,
and having to ring the doorbell every time. That is not feasible,
because then the transfer can be more frequent than it should be.
Furthermore, it ignored the fact that isochronous TRBs are to be
scheduled not too late, but also not too soon (see 4.11.2.5 of the xHCI
spec).

Now, scheduling the TRBs to hardware is called feeding, and can be
delayed by setting a timer. Ring overruns/underruns are detected also at
the end of handling an event.

  • Property mode set to 100644
File size: 4.9 KB
RevLine 
[c0ec9e7]1/*
2 * Copyright (c) 2017 Petr Manek
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup drvusbxhci
30 * @{
31 */
32/** @file
33 * @brief The host controller endpoint management.
34 */
35
36#ifndef XHCI_ENDPOINT_H
37#define XHCI_ENDPOINT_H
38
39#include <assert.h>
40
41#include <usb/debug.h>
[b80c1ab]42#include <usb/host/dma_buffer.h>
[c0ec9e7]43#include <usb/host/endpoint.h>
44#include <usb/host/hcd.h>
[479e32d]45#include <ddf/driver.h>
[c0ec9e7]46
[708d8fcd]47#include "isoch.h"
[2b61945]48#include "transfers.h"
[708d8fcd]49#include "trb_ring.h"
[d7869d7e]50
[c10daa8]51typedef struct xhci_device xhci_device_t;
[41924f30]52typedef struct xhci_endpoint xhci_endpoint_t;
53typedef struct xhci_bus xhci_bus_t;
54
[370a1c8]55enum {
56 EP_TYPE_INVALID = 0,
57 EP_TYPE_ISOCH_OUT = 1,
58 EP_TYPE_BULK_OUT = 2,
59 EP_TYPE_INTERRUPT_OUT = 3,
60 EP_TYPE_CONTROL = 4,
61 EP_TYPE_ISOCH_IN = 5,
62 EP_TYPE_BULK_IN = 6,
63 EP_TYPE_INTERRUPT_IN = 7
64};
65
[176a70a]66/** Connector structure linking endpoint context to the endpoint. */
67typedef struct xhci_endpoint {
[41924f30]68 endpoint_t base; /**< Inheritance. Keep this first. */
69
[82fe063]70 /** Main transfer ring (unused if streams are enabled) */
[2b61945]71 xhci_trb_ring_t ring;
72
[ef1a3a8]73 /** Primary stream context array (or NULL if endpoint doesn't use streams). */
[89cefe78]74 xhci_stream_ctx_t *primary_stream_ctx_array;
[b80c1ab]75 dma_buffer_t primary_stream_ctx_dma;
[89cefe78]76
[ef1a3a8]77 /** Primary stream ring array (or NULL if endpoint doesn't use streams). */
78 xhci_trb_ring_t *primary_stream_rings;
79
80 /** Size of the allocated primary stream context array (and ring array). */
[3f6c94ed]81 uint16_t primary_stream_ctx_array_size;
82
[bdd8842c]83 /* Maximum number of primary streams (0 - 2^16). */
84 uint32_t max_streams;
[89cefe78]85
[82fe063]86 /** Maximum number of consecutive USB transactions (0-15) that should be executed per scheduling opportunity */
[89cefe78]87 uint8_t max_burst;
[82fe063]88
89 /** Maximum number of bursts within an interval that this endpoint supports */
[89cefe78]90 uint8_t mult;
[d3086873]91
[bdd8842c]92 /** Scheduling interval for periodic endpoints, as a number of 125us units. (0 - 2^16) */
93 uint32_t interval;
[5c75456]94
[17c5e62]95 /** This field is a valid pointer for (and only for) isochronous transfers. */
[708d8fcd]96 xhci_isoch_t isoch [0];
[176a70a]97} xhci_endpoint_t;
98
[a5b3de6]99#define XHCI_EP_FMT "(%d:%d %s)"
[9620a54]100/* FIXME: "Device -1" messes up log messages, figure out a better way. */
[a5b3de6]101#define XHCI_EP_ARGS(ep) \
[9620a54]102 ((ep).base.device ? (ep).base.device->address : -1), \
[a5b3de6]103 ((ep).base.endpoint), \
104 (usb_str_transfer_type((ep).base.transfer_type))
105
[c10daa8]106typedef struct xhci_device {
[2b61945]107 device_t base; /**< Inheritance. Keep this first. */
[c10daa8]108
[2770b66]109 /** Slot ID assigned to the device by xHC. */
[c10daa8]110 uint32_t slot_id;
111
[2cf28b9]112 /** Corresponding port on RH */
113 uint8_t rh_port;
114
115 /** USB Tier of the device */
116 uint8_t tier;
117
118 /** Route string */
119 uint32_t route_str;
120
[b80c1ab]121 /** Place to store the allocated context */
122 dma_buffer_t dev_ctx;
[2770b66]123
[9b2f69e]124 /** Flag indicating whether the device is USB3 (it's USB2 otherwise). */
125 bool usb3;
[c10daa8]126} xhci_device_t;
127
[9620a54]128#define XHCI_DEV_FMT "(%s, slot %d)"
129#define XHCI_DEV_ARGS(dev) ddf_fun_get_name((dev).base.fun), (dev).slot_id
130
[9efad54]131int xhci_endpoint_init(xhci_endpoint_t *, device_t *, const usb_endpoint_descriptors_t *);
[41924f30]132void xhci_endpoint_fini(xhci_endpoint_t *);
[c0ec9e7]133
[3f6c94ed]134int xhci_endpoint_request_streams(xhci_hc_t *, xhci_device_t *, xhci_endpoint_t *, unsigned);
135
[2b61945]136uint8_t xhci_endpoint_dci(xhci_endpoint_t *);
[dbf32b1]137uint8_t xhci_endpoint_index(xhci_endpoint_t *);
[f971e957]138
[0206d35]139void xhci_setup_endpoint_context(xhci_endpoint_t *, xhci_ep_ctx_t *);
140
[c10daa8]141xhci_endpoint_t * xhci_device_get_endpoint(xhci_device_t *, usb_endpoint_t);
142
[2b61945]143static inline xhci_device_t * xhci_device_get(device_t *dev)
144{
145 assert(dev);
146 return (xhci_device_t *) dev;
147}
148
[41924f30]149static inline xhci_endpoint_t * xhci_endpoint_get(endpoint_t *ep)
[176a70a]150{
[eaf5e86]151 assert(ep);
[41924f30]152 return (xhci_endpoint_t *) ep;
[176a70a]153}
154
[2b61945]155static inline xhci_device_t * xhci_ep_to_dev(xhci_endpoint_t *ep)
156{
157 assert(ep);
158 return xhci_device_get(ep->base.device);
159}
160
[c0ec9e7]161#endif
162
163/**
164 * @}
165 */
Note: See TracBrowser for help on using the repository browser.