Module Name: src Committed By: jakllsch Date: Mon Jan 7 03:00:39 UTC 2019
Modified Files: src/sys/dev/usb: xhci.c xhcivar.h Log Message: Seperate xHCI and xhci(4) TRB structs so as to avoid some of them (the ones that the hardware doesn't touch) ending up less-aligned than the compiler assumed. Additionally, fix the most obvious problems that xhci(4) had on big endian systems. Briefly tested on a Jetson TK1 in LE and BE w/ evbarm GENERIC kernel. To generate a diff of this commit: cvs rdiff -u -r1.100 -r1.101 src/sys/dev/usb/xhci.c cvs rdiff -u -r1.10 -r1.11 src/sys/dev/usb/xhcivar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/xhci.c diff -u src/sys/dev/usb/xhci.c:1.100 src/sys/dev/usb/xhci.c:1.101 --- src/sys/dev/usb/xhci.c:1.100 Sun Oct 28 21:36:34 2018 +++ src/sys/dev/usb/xhci.c Mon Jan 7 03:00:39 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: xhci.c,v 1.100 2018/10/28 21:36:34 mrg Exp $ */ +/* $NetBSD: xhci.c,v 1.101 2019/01/07 03:00:39 jakllsch Exp $ */ /* * Copyright (c) 2013 Jonathan A. Kollasch @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.100 2018/10/28 21:36:34 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.101 2019/01/07 03:00:39 jakllsch Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -155,9 +155,9 @@ static void xhci_host_dequeue(struct xhc static usbd_status xhci_set_dequeue(struct usbd_pipe *); static usbd_status xhci_do_command(struct xhci_softc * const, - struct xhci_trb * const, int); + struct xhci_soft_trb * const, int); static usbd_status xhci_do_command_locked(struct xhci_softc * const, - struct xhci_trb * const, int); + struct xhci_soft_trb * const, int); static usbd_status xhci_init_slot(struct usbd_device *, uint32_t); static void xhci_free_slot(struct xhci_softc *, struct xhci_slot *, int, int); static usbd_status xhci_set_address(struct usbd_device *, uint32_t, bool); @@ -505,6 +505,15 @@ xhci_ring_trbp(struct xhci_ring * const } static inline void +xhci_soft_trb_put(struct xhci_soft_trb * const trb, + uint64_t parameter, uint32_t status, uint32_t control) +{ + trb->trb_0 = parameter; + trb->trb_2 = status; + trb->trb_3 = control; +} + +static inline void xhci_trb_put(struct xhci_trb * const trb, uint64_t parameter, uint32_t status, uint32_t control) { @@ -1385,7 +1394,7 @@ xhci_configure_endpoint(struct usbd_pipe #ifdef USB_DEBUG const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); #endif - struct xhci_trb trb; + struct xhci_soft_trb trb; usbd_status err; XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -1441,7 +1450,7 @@ xhci_reset_endpoint_locked(struct usbd_p struct xhci_softc * const sc = XHCI_PIPE2SC(pipe); struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); - struct xhci_trb trb; + struct xhci_soft_trb trb; usbd_status err; XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -1482,7 +1491,7 @@ xhci_stop_endpoint(struct usbd_pipe *pip { struct xhci_softc * const sc = XHCI_PIPE2SC(pipe); struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; - struct xhci_trb trb; + struct xhci_soft_trb trb; usbd_status err; const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); @@ -1517,7 +1526,7 @@ xhci_set_dequeue_locked(struct usbd_pipe struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); struct xhci_ring * const xr = &xs->xs_ep[dci].xe_tr; - struct xhci_trb trb; + struct xhci_soft_trb trb; usbd_status err; XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -1631,7 +1640,7 @@ xhci_close_pipe(struct usbd_pipe *pipe) struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; usb_endpoint_descriptor_t * const ed = pipe->up_endpoint->ue_edesc; const u_int dci = xhci_ep_get_dci(ed); - struct xhci_trb trb; + struct xhci_soft_trb trb; uint32_t *cp; XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -2532,7 +2541,7 @@ xhci_ring_free(struct xhci_softc * const static void xhci_ring_put(struct xhci_softc * const sc, struct xhci_ring * const xr, - void *cookie, struct xhci_trb * const trbs, size_t ntrbs) + void *cookie, struct xhci_soft_trb * const trbs, size_t ntrbs) { size_t i; u_int ri; @@ -2687,7 +2696,7 @@ xhci_abort_command(struct xhci_softc *sc */ static usbd_status xhci_do_command_locked(struct xhci_softc * const sc, - struct xhci_trb * const trb, int timeout) + struct xhci_soft_trb * const trb, int timeout) { struct xhci_ring * const cr = &sc->sc_cr; usbd_status err; @@ -2757,7 +2766,7 @@ timedout: } static usbd_status -xhci_do_command(struct xhci_softc * const sc, struct xhci_trb * const trb, +xhci_do_command(struct xhci_softc * const sc, struct xhci_soft_trb * const trb, int timeout) { @@ -2771,7 +2780,7 @@ xhci_do_command(struct xhci_softc * cons static usbd_status xhci_enable_slot(struct xhci_softc * const sc, uint8_t * const slotp) { - struct xhci_trb trb; + struct xhci_soft_trb trb; usbd_status err; XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -2799,7 +2808,7 @@ xhci_enable_slot(struct xhci_softc * con static usbd_status xhci_disable_slot(struct xhci_softc * const sc, uint8_t slot) { - struct xhci_trb trb; + struct xhci_soft_trb trb; struct xhci_slot *xs; usbd_status err; @@ -2810,9 +2819,8 @@ xhci_disable_slot(struct xhci_softc * co trb.trb_0 = 0; trb.trb_2 = 0; - trb.trb_3 = htole32( - XHCI_TRB_3_SLOT_SET(slot) | - XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DISABLE_SLOT)); + trb.trb_3 = XHCI_TRB_3_SLOT_SET(slot) | + XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DISABLE_SLOT); err = xhci_do_command_locked(sc, &trb, USBD_DEFAULT_TIMEOUT); @@ -2839,7 +2847,7 @@ static usbd_status xhci_address_device(struct xhci_softc * const sc, uint64_t icp, uint8_t slot_id, bool bsr) { - struct xhci_trb trb; + struct xhci_soft_trb trb; usbd_status err; XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -2862,7 +2870,7 @@ static usbd_status xhci_update_ep0_mps(struct xhci_softc * const sc, struct xhci_slot * const xs, u_int mps) { - struct xhci_trb trb; + struct xhci_soft_trb trb; usbd_status err; uint32_t * cp; @@ -3816,7 +3824,8 @@ xhci_device_ctrl_start(struct usbd_xfer (isread ? XHCI_TRB_3_TRT_IN : XHCI_TRB_3_TRT_OUT)) | XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_SETUP_STAGE) | XHCI_TRB_3_IDT_BIT; - xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); + /* we need parameter un-swapped on big endian, so pre-swap it here */ + xhci_soft_trb_put(&xx->xx_trb[i++], htole64(parameter), status, control); if (len != 0) { /* data phase */ @@ -3829,7 +3838,7 @@ xhci_device_ctrl_start(struct usbd_xfer XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DATA_STAGE) | (usbd_xfer_isread(xfer) ? XHCI_TRB_3_ISP_BIT : 0) | XHCI_TRB_3_IOC_BIT; - xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); + xhci_soft_trb_put(&xx->xx_trb[i++], parameter, status, control); } parameter = 0; @@ -3838,7 +3847,7 @@ xhci_device_ctrl_start(struct usbd_xfer control = ((isread && (len > 0)) ? 0 : XHCI_TRB_3_DIR_IN) | XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_STATUS_STAGE) | XHCI_TRB_3_IOC_BIT; - xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); + xhci_soft_trb_put(&xx->xx_trb[i++], parameter, status, control); xfer->ux_status = USBD_IN_PROGRESS; if (!polling) @@ -3959,7 +3968,7 @@ xhci_device_bulk_start(struct usbd_xfer control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_NORMAL) | (usbd_xfer_isread(xfer) ? XHCI_TRB_3_ISP_BIT : 0) | XHCI_TRB_3_IOC_BIT; - xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); + xhci_soft_trb_put(&xx->xx_trb[i++], parameter, status, control); xfer->ux_status = USBD_IN_PROGRESS; if (!polling) @@ -4071,7 +4080,7 @@ xhci_device_intr_start(struct usbd_xfer control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_NORMAL) | (usbd_xfer_isread(xfer) ? XHCI_TRB_3_ISP_BIT : 0) | XHCI_TRB_3_IOC_BIT; - xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); + xhci_soft_trb_put(&xx->xx_trb[i++], parameter, status, control); xfer->ux_status = USBD_IN_PROGRESS; if (!polling) Index: src/sys/dev/usb/xhcivar.h diff -u src/sys/dev/usb/xhcivar.h:1.10 src/sys/dev/usb/xhcivar.h:1.11 --- src/sys/dev/usb/xhcivar.h:1.10 Thu Aug 9 06:26:47 2018 +++ src/sys/dev/usb/xhcivar.h Mon Jan 7 03:00:39 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: xhcivar.h,v 1.10 2018/08/09 06:26:47 mrg Exp $ */ +/* $NetBSD: xhcivar.h,v 1.11 2019/01/07 03:00:39 jakllsch Exp $ */ /* * Copyright (c) 2013 Jonathan A. Kollasch @@ -33,9 +33,15 @@ #define XHCI_XFER_NTRB 20 +struct xhci_soft_trb { + uint64_t trb_0; + uint32_t trb_2; + uint32_t trb_3; +}; + struct xhci_xfer { struct usbd_xfer xx_xfer; - struct xhci_trb xx_trb[XHCI_XFER_NTRB]; + struct xhci_soft_trb xx_trb[XHCI_XFER_NTRB]; }; #define XHCI_BUS2SC(bus) ((bus)->ub_hcpriv) @@ -119,7 +125,7 @@ struct xhci_softc { kcondvar_t sc_cmdbusy_cv; kcondvar_t sc_command_cv; bus_addr_t sc_command_addr; - struct xhci_trb sc_result_trb; + struct xhci_soft_trb sc_result_trb; bool sc_resultpending; bool sc_ac64;