shithub: riscv

Download patch

ref: 5bb7240ee93111a7c73adaedc0dabfa0caacbe25
parent: 83e20b4df18d539db59c8e1090f77a6565df250e
author: cinap_lenrek <[email protected]>
date: Sat Oct 20 15:57:37 EDT 2018

nusb/kb: work arround broken split transaction on raspi's dwc otg usb controller

--- a/sys/src/cmd/nusb/kb/hid.h
+++ b/sys/src/cmd/nusb/kb/hid.h
@@ -15,6 +15,7 @@
 	Getreport = 0x01,
 	Setreport = 0x09,
 	Getproto	= 0x03,
+	Setidle		= 0x0a,
 	Setproto	= 0x0b,
 
 	/* protocols for SET_PROTO request */
--- a/sys/src/cmd/nusb/kb/kb.c
+++ b/sys/src/cmd/nusb/kb/kb.c
@@ -299,12 +299,19 @@
 static int
 setproto(Hiddev *f, int eid)
 {
-	int id, proto;
+	int proto;
 	Iface *iface;
 
 	iface = f->dev->usb->ep[eid]->iface;
-	id = iface->id;
-	f->nrep = usbcmd(f->dev, Rd2h|Rstd|Riface, Rgetdesc, Dreport<<8, id, 
+
+	/*
+	 * DWC OTG controller misses some split transaction inputs.
+	 * Set nonzero idle time to return more frequent reports
+	 * of keyboard state, to avoid losing key up/down events.
+	 */
+	usbcmd(f->dev, Rh2d|Rclass|Riface, Setidle, 8<<8, iface->id, nil, 0);
+
+	f->nrep = usbcmd(f->dev, Rd2h|Rstd|Riface, Rgetdesc, Dreport<<8, iface->id,
 		f->rep, sizeof(f->rep));
 	if(f->nrep > 0){
 		if(debug){
@@ -335,7 +342,7 @@
 		}
 		proto = Bootproto;
 	}
-	return usbcmd(f->dev, Rh2d|Rclass|Riface, Setproto, proto, id, nil, 0);
+	return usbcmd(f->dev, Rh2d|Rclass|Riface, Setproto, proto, iface->id, nil, 0);
 }
 
 static int