#ifndef _XHCIVAR_H_
#define _XHCIVAR_H_
#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;
size_t ntrb;
size_t zerotd;
};
struct xhci_ring {
struct xhci_trb *trbs;
size_t ntrb;
struct usbd_dma_info dma;
uint32_t index;
uint32_t toggle;
};
struct xhci_soft_dev {
struct xhci_inctx *input_ctx;
struct xhci_sctx *slot_ctx;
struct xhci_epctx *ep_ctx[31];
struct usbd_dma_info ictx_dma;
struct usbd_dma_info octx_dma;
struct xhci_pipe *pipes[31];
};
struct xhci_devctx {
uint64_t *segs;
struct usbd_dma_info dma;
};
struct xhci_erst {
struct xhci_erseg *segs;
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;
int sc_saved_state;
bus_size_t sc_oper_off;
bus_size_t sc_runt_off;
bus_size_t sc_door_off;
uint16_t sc_version;
uint32_t sc_pagesize;
uint32_t sc_ctxsize;
int sc_noport;
u_int8_t sc_conf;
struct usbd_xfer *sc_intrxfer;
struct xhci_devctx sc_dcbaa;
struct xhci_ring sc_cmd_ring;
struct rwlock sc_cmd_lock;
struct xhci_erst sc_erst;
struct xhci_ring sc_evt_ring;
struct xhci_scratchpad sc_spad;
int sc_noslot;
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];
int sc_id_vendor;
int sc_flags;
#define XHCI_NOCSS 0x01
};
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);
static inline uint8_t
xhci_read_1(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t offset)
{
uint32_t reg;
reg = bus_space_read_4(iot, ioh, offset & ~3);
return (reg >> ((offset & 3) * 8)) & 0xff;
}
static inline uint16_t
xhci_read_2(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t offset)
{
uint32_t reg;
reg = bus_space_read_4(iot, ioh, offset & ~2);
return (reg >> ((offset & 2) * 8)) & 0xffff;
}
#define XREAD1(sc, a) xhci_read_1((sc)->iot, (sc)->ioh, (a))
#define XREAD2(sc, a) xhci_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