1 /* $OpenBSD: xhcivar.h,v 1.16 2024/08/17 01:55:03 jsg Exp $ */ 2 3 /* 4 * Copyright (c) 2014 Martin Pieuchot 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #ifndef _XHCIVAR_H_ 20 #define _XHCIVAR_H_ 21 22 /* Default command execution time (implementation defined). */ 23 #define XHCI_CMD_TIMEOUT MSEC_TO_NSEC(500) 24 25 #define XHCI_MAX_CMDS (16 * 1) 26 #define XHCI_MAX_EVTS (16 * 13) 27 #define XHCI_MAX_XFER (16 * 16) 28 29 struct usbd_dma_info { 30 bus_dma_tag_t tag; 31 bus_dmamap_t map; 32 bus_dma_segment_t seg; 33 int nsegs; 34 bus_addr_t paddr; 35 caddr_t vaddr; 36 bus_size_t size; 37 }; 38 39 struct xhci_xfer { 40 struct usbd_xfer xfer; 41 int index; /* Index of the last TRB */ 42 size_t ntrb; /* Number of associated TRBs */ 43 size_t zerotd; /* Is zero len TD required? */ 44 }; 45 46 struct xhci_ring { 47 struct xhci_trb *trbs; 48 size_t ntrb; 49 struct usbd_dma_info dma; 50 51 uint32_t index; 52 uint32_t toggle; /* Producer/Consumer bit */ 53 }; 54 55 struct xhci_soft_dev { 56 struct xhci_inctx *input_ctx; /* Input context */ 57 struct xhci_sctx *slot_ctx; 58 struct xhci_epctx *ep_ctx[31]; 59 struct usbd_dma_info ictx_dma; 60 61 struct usbd_dma_info octx_dma; /* Output context */ 62 63 struct xhci_pipe *pipes[31]; 64 }; 65 66 /* Device context segment table. */ 67 struct xhci_devctx { 68 uint64_t *segs; /* at most USB_MAX_DEVICES+1 */ 69 struct usbd_dma_info dma; 70 }; 71 72 /* Event ring segment table. */ 73 struct xhci_erst { 74 struct xhci_erseg *segs; /* One segment per event ring */ 75 struct usbd_dma_info dma; 76 }; 77 78 struct xhci_scratchpad { 79 struct usbd_dma_info table_dma; 80 struct usbd_dma_info pages_dma; 81 int npage; 82 }; 83 84 struct xhci_softc { 85 struct usbd_bus sc_bus; 86 87 bus_space_tag_t iot; 88 bus_space_handle_t ioh; 89 bus_size_t sc_size; 90 91 int sc_dead; 92 int sc_saved_state; 93 94 bus_size_t sc_oper_off; /* Operational Register space */ 95 bus_size_t sc_runt_off; /* Runtime */ 96 bus_size_t sc_door_off; /* Doorbell */ 97 98 uint16_t sc_version; /* xHCI version */ 99 uint32_t sc_pagesize; /* xHCI page size, minimum 4k */ 100 uint32_t sc_ctxsize; /* 32/64 byte context structs */ 101 102 int sc_noport; /* Maximum number of ports */ 103 104 u_int8_t sc_conf; /* Device configuration */ 105 struct usbd_xfer *sc_intrxfer; /* Root HUB interrupt xfer */ 106 107 struct xhci_devctx sc_dcbaa; /* Device context base addr. */ 108 struct xhci_ring sc_cmd_ring; /* Command ring */ 109 struct rwlock sc_cmd_lock; /* Serialize commands */ 110 111 struct xhci_erst sc_erst; /* Event ring segment table */ 112 struct xhci_ring sc_evt_ring; /* Event ring */ 113 114 struct xhci_scratchpad sc_spad; /* Optional scratchpad */ 115 116 int sc_noslot; /* Maximum number of slots */ 117 struct xhci_soft_dev sc_sdevs[USB_MAX_DEVICES]; 118 119 struct xhci_trb *sc_cmd_trb; 120 struct xhci_trb sc_result_trb; 121 122 char sc_vendor[16]; /* Vendor string for root hub */ 123 int sc_id_vendor; /* Vendor ID for root hub */ 124 125 int sc_flags; 126 #define XHCI_NOCSS 0x01 127 }; 128 129 int xhci_init(struct xhci_softc *); 130 void xhci_config(struct xhci_softc *); 131 void xhci_reinit(struct xhci_softc *); 132 int xhci_intr(void *); 133 int xhci_detach(struct device *, int); 134 int xhci_activate(struct device *, int); 135 136 #define XREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a)) 137 #define XREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a)) 138 #define XREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (a)) 139 #define XWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (a), (x)) 140 #define XWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (a), (x)) 141 #define XWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (a), (x)) 142 143 #define XOREAD4(sc, a) \ 144 bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_oper_off + (a)) 145 #define XOWRITE4(sc, a, x) \ 146 bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_oper_off + (a), (x)) 147 148 #define XRREAD4(sc, a) \ 149 bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_runt_off + (a)) 150 #define XRWRITE4(sc, a, x) \ 151 bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_runt_off + (a), (x)) 152 153 #define XDREAD4(sc, a) \ 154 bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_door_off + (a)) 155 #define XDWRITE4(sc, a, x) \ 156 bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_door_off + (a), (x)) 157 158 #endif /* _XHCIVAR_H_ */ 159