NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/51202: XHCI driver sends stale TRBs from a pipe previously opened



The following reply was made to PR kern/51202; it has been noted by GNATS.

From: Sprow <webpages%sprow.co.uk@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: 
Subject: Re: kern/51202: XHCI driver sends stale TRBs from a pipe previously opened
Date: Tue, 31 May 2016 13:55:49 +0100

 For completeness, xhci_ring_init sharing code for the host side dequeue too.
 
 
 --- xhci_1-46.c	2016-05-30 22:44:14 +0100
 +++ xhci.c	2016-05-31 12:52:30 +0100
 @@ -142,6 +142,7 @@
  static usbd_status xhci_reset_endpoint(struct usbd_pipe *);
  static usbd_status xhci_stop_endpoint(struct usbd_pipe *);
  
 +static void xhci_host_dequeue(struct xhci_ring * const);
  static usbd_status xhci_set_dequeue(struct usbd_pipe *);
  
  static usbd_status xhci_do_command(struct xhci_softc * const,
 @@ -1508,6 +1509,9 @@
  	cp = xhci_slot_get_icv(sc, xs, xhci_dci_to_ici(dci));
  	xhci_setup_endp_ctx(pipe, cp);
  
 +	/* configure ep context performs an implicit dequeue */
 +	xhci_host_dequeue(&xs->xs_ep[dci].xe_tr);
 +
  	/* sync input contexts before they are read from memory */
  	usb_syncmem(&xs->xs_ic_dma, 0, sc->sc_pgsz, BUS_DMASYNC_PREWRITE);
  	hexdump("input control context", xhci_slot_get_icv(sc, xs, 0),
 @@ -1600,6 +1604,19 @@
  	return err;
  }
  
 +static void
 +xhci_host_dequeue(struct xhci_ring * const xr)
 +{
 +	/* When dequeueing the controller, update our struct copy too */
 +	memset(xr->xr_trb, 0, xr->xr_ntrb * XHCI_TRB_SIZE);
 +	usb_syncmem(&xr->xr_dma, 0, xr->xr_ntrb * XHCI_TRB_SIZE,
 +	    BUS_DMASYNC_PREWRITE);
 +	memset(xr->xr_cookies, 0, xr->xr_ntrb * sizeof(*xr->xr_cookies));
 +
 +	xr->xr_ep = 0;
 +	xr->xr_cs = 1;
 +}
 +
  /*
   * Set TR Dequeue Pointer.
   * xCHI 1.1  4.6.10  6.4.3.9
 @@ -1619,13 +1636,7 @@
  	XHCIHIST_FUNC(); XHCIHIST_CALLED();
  	DPRINTFN(4, "slot %u dci %u", xs->xs_idx, dci, 0, 0);
  
 -	memset(xr->xr_trb, 0, xr->xr_ntrb * XHCI_TRB_SIZE);
 -	usb_syncmem(&xr->xr_dma, 0, xr->xr_ntrb * XHCI_TRB_SIZE,
 -	    BUS_DMASYNC_PREWRITE);
 -	memset(xr->xr_cookies, 0, xr->xr_ntrb * sizeof(*xr->xr_cookies));
 -
 -	xr->xr_ep = 0;
 -	xr->xr_cs = 1;
 +	xhci_host_dequeue(xr);
  
  	/* set DCS */
  	trb.trb_0 = xhci_ring_trbp(xr, 0) | 1; /* XXX */
 @@ -2449,13 +2460,10 @@
  	if (err)
  		return err;
  	mutex_init(&xr->xr_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
 -	xr->xr_cookies = kmem_zalloc(sizeof(*xr->xr_cookies) * ntrb, KM_SLEEP);
 +	xr->xr_cookies = kmem_alloc(sizeof(*xr->xr_cookies) * ntrb, KM_SLEEP);
  	xr->xr_trb = xhci_ring_trbv(xr, 0);
  	xr->xr_ntrb = ntrb;
 -	xr->xr_ep = 0;
 -	xr->xr_cs = 1;
 -	memset(xr->xr_trb, 0, size);
 -	usb_syncmem(&xr->xr_dma, 0, size, BUS_DMASYNC_PREWRITE);
 +	xhci_host_dequeue(xr);
  	xr->is_halted = false;
  
  	return USBD_NORMAL_COMPLETION;
 @@ -2898,6 +2906,10 @@
  	*(uint64_t *)(&cp[2]) = htole64(
  	    xhci_ring_trbp(&xs->xs_ep[XHCI_DCI_EP_CONTROL].xe_tr, 0) |
  	    XHCI_EPCTX_2_DCS_SET(1));
 +	/* this performs an implicit dequeue of the ep transfer ring,
 +	 * but the call to xhci_ring_init above has dequeued the host
 +	 * view of the structures already. 
 +	 */
  	cp[4] = htole32(
  		XHCI_EPCTX_4_AVG_TRB_LEN_SET(8)
  		);
 


Home | Main Index | Thread Index | Old Index