NetBSD-Bugs archive

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

Re: kern/54070: urtwn(4) does not work on OHCI



How about this untested patch?

I think it might help 50278 as well.

Nick
Index: sys/dev/usb/ohci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ohci.c,v
retrieving revision 1.290
diff -u -p -r1.290 ohci.c
--- sys/dev/usb/ohci.c	11 Aug 2019 22:55:03 -0000	1.290
+++ sys/dev/usb/ohci.c	28 Nov 2019 07:35:13 -0000
@@ -1515,8 +1515,9 @@ ohci_softintr(void *v)
 
 			ohci_soft_ed_t *sed = opipe->sed;
 
-			/* clear halt and TD chain */
-			sed->ed.ed_headp = HTOO32(p->physaddr);
+			/* clear halt and TD chain, preserving toggle carry */
+			sed->ed.ed_headp = HTOO32(p->physaddr) |
+			   (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY));
 			usb_syncmem(&sed->dma,
 			    sed->offs + offsetof(ohci_ed_t, ed_headp),
 			    sizeof(sed->ed.ed_headp),
@@ -1524,6 +1525,7 @@ ohci_softintr(void *v)
 
 			OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
 
+			/* XXX USBD_SHORT_XFER_OK ?? */
 			if (cc == OHCI_CC_DATA_UNDERRUN)
 				xfer->ux_status = USBD_NORMAL_COMPLETION;
 			else if (cc == OHCI_CC_STALL)
@@ -3051,8 +3053,11 @@ ohci_device_bulk_start(struct usbd_xfer 
 	    (uintptr_t)ox->ox_stds[0], (uintptr_t)tail, 0);
 	KASSERT(opipe->tail.td == tail);
 
-	/* We want interrupt at the end of the transfer. */
-	last->td.td_flags &= HTOO32(~OHCI_TD_INTR_MASK);
+	/*
+	 * We want interrupt at the end of the transfer and for round to be clear.
+	 * All short transfers are handled via OHCI_CC_DATA_UNDERRUN
+	 */
+	last->td.td_flags &= ~HTOO32(OHCI_TD_INTR_MASK | OHCI_TD_R);
 	last->td.td_flags |= HTOO32(OHCI_TD_SET_DI(1));
 	last->td.td_nexttd = HTOO32(tail->physaddr);
 	last->nexttd = tail;
@@ -3254,8 +3259,11 @@ ohci_device_intr_start(struct usbd_xfer 
 	    (uintptr_t)tail, 0, 0);
 	KASSERT(opipe->tail.td == tail);
 
-	/* We want interrupt at the end of the transfer. */
-	last->td.td_flags &= HTOO32(~OHCI_TD_INTR_MASK);
+	/*
+	 * We want interrupt at the end of the transfer and for round to be clear.
+	 * All short transfers are handled via OHCI_CC_DATA_UNDERRUN
+	 */
+	last->td.td_flags &= ~HTOO32(OHCI_TD_INTR_MASK | OHCI_TD_R);
 	last->td.td_flags |= HTOO32(OHCI_TD_SET_DI(1));
 
 	last->td.td_nexttd = HTOO32(tail->physaddr);


Home | Main Index | Thread Index | Old Index