154 lines
4.6 KiB
C
154 lines
4.6 KiB
C
/* $OpenBSD: xhcivar.h,v 1.14 2022/12/12 19:18:25 kettenis Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 2014 Martin Pieuchot
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#ifndef _XHCIVAR_H_
|
|
#define _XHCIVAR_H_
|
|
|
|
/* Default command execution time (implementation defined). */
|
|
#define XHCI_CMD_TIMEOUT MSEC_TO_NSEC(500)
|
|
|
|
#define XHCI_MAX_CMDS (16 * 1)
|
|
#define XHCI_MAX_EVTS (16 * 13)
|
|
#define XHCI_MAX_XFER (16 * 16)
|
|
|
|
struct usbd_dma_info {
|
|
bus_dma_tag_t tag;
|
|
bus_dmamap_t map;
|
|
bus_dma_segment_t seg;
|
|
int nsegs;
|
|
bus_addr_t paddr;
|
|
caddr_t vaddr;
|
|
bus_size_t size;
|
|
};
|
|
|
|
struct xhci_xfer {
|
|
struct usbd_xfer xfer;
|
|
int index; /* Index of the last TRB */
|
|
size_t ntrb; /* Number of associated TRBs */
|
|
size_t zerotd; /* Is zero len TD required? */
|
|
};
|
|
|
|
struct xhci_ring {
|
|
struct xhci_trb *trbs;
|
|
size_t ntrb;
|
|
struct usbd_dma_info dma;
|
|
|
|
uint32_t index;
|
|
uint32_t toggle; /* Producer/Consumer bit */
|
|
};
|
|
|
|
struct xhci_soft_dev {
|
|
struct xhci_inctx *input_ctx; /* Input context */
|
|
struct xhci_sctx *slot_ctx;
|
|
struct xhci_epctx *ep_ctx[31];
|
|
struct usbd_dma_info ictx_dma;
|
|
|
|
struct usbd_dma_info octx_dma; /* Output context */
|
|
|
|
struct xhci_pipe *pipes[31];
|
|
};
|
|
|
|
/* Device context segment table. */
|
|
struct xhci_devctx {
|
|
uint64_t *segs; /* at most USB_MAX_DEVICES+1 */
|
|
struct usbd_dma_info dma;
|
|
};
|
|
|
|
/* Event ring segment table. */
|
|
struct xhci_erst {
|
|
struct xhci_erseg *segs; /* One segment per event ring */
|
|
struct usbd_dma_info dma;
|
|
};
|
|
|
|
struct xhci_scratchpad {
|
|
struct usbd_dma_info table_dma;
|
|
struct usbd_dma_info pages_dma;
|
|
int npage;
|
|
};
|
|
|
|
struct xhci_softc {
|
|
struct usbd_bus sc_bus;
|
|
|
|
bus_space_tag_t iot;
|
|
bus_space_handle_t ioh;
|
|
bus_size_t sc_size;
|
|
|
|
int sc_dead;
|
|
|
|
bus_size_t sc_oper_off; /* Operational Register space */
|
|
bus_size_t sc_runt_off; /* Runtime */
|
|
bus_size_t sc_door_off; /* Doorbell */
|
|
|
|
uint16_t sc_version; /* xHCI version */
|
|
uint32_t sc_pagesize; /* xHCI page size, minimum 4k */
|
|
uint32_t sc_ctxsize; /* 32/64 byte context structs */
|
|
|
|
int sc_noport; /* Maximum number of ports */
|
|
|
|
u_int8_t sc_conf; /* Device configuration */
|
|
struct usbd_xfer *sc_intrxfer; /* Root HUB interrupt xfer */
|
|
|
|
struct xhci_devctx sc_dcbaa; /* Device context base addr. */
|
|
struct xhci_ring sc_cmd_ring; /* Command ring */
|
|
struct rwlock sc_cmd_lock; /* Serialize commands */
|
|
|
|
struct xhci_erst sc_erst; /* Event ring segment table */
|
|
struct xhci_ring sc_evt_ring; /* Event ring */
|
|
|
|
struct xhci_scratchpad sc_spad; /* Optional scratchpad */
|
|
|
|
int sc_noslot; /* Maximum number of slots */
|
|
struct xhci_soft_dev sc_sdevs[USB_MAX_DEVICES];
|
|
|
|
struct xhci_trb *sc_cmd_trb;
|
|
struct xhci_trb sc_result_trb;
|
|
|
|
char sc_vendor[16]; /* Vendor string for root hub */
|
|
int sc_id_vendor; /* Vendor ID for root hub */
|
|
};
|
|
|
|
int xhci_init(struct xhci_softc *);
|
|
void xhci_config(struct xhci_softc *);
|
|
void xhci_reinit(struct xhci_softc *);
|
|
int xhci_intr(void *);
|
|
int xhci_detach(struct device *, int);
|
|
int xhci_activate(struct device *, int);
|
|
|
|
#define XREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a))
|
|
#define XREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a))
|
|
#define XREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (a))
|
|
#define XWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (a), (x))
|
|
#define XWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (a), (x))
|
|
#define XWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (a), (x))
|
|
|
|
#define XOREAD4(sc, a) \
|
|
bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_oper_off + (a))
|
|
#define XOWRITE4(sc, a, x) \
|
|
bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_oper_off + (a), (x))
|
|
|
|
#define XRREAD4(sc, a) \
|
|
bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_runt_off + (a))
|
|
#define XRWRITE4(sc, a, x) \
|
|
bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_runt_off + (a), (x))
|
|
|
|
#define XDREAD4(sc, a) \
|
|
bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_door_off + (a))
|
|
#define XDWRITE4(sc, a, x) \
|
|
bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_door_off + (a), (x))
|
|
|
|
#endif /* _XHCIVAR_H_ */
|