summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorpirofti <pirofti@openbsd.org>2014-07-12 21:07:33 +0000
committerpirofti <pirofti@openbsd.org>2014-07-12 21:07:33 +0000
commitd4c7cd03d53d3129d20ed9da0aa4e88a8b9ea8da (patch)
treeee5cd04b48df4e62c1c7780e8d8b0f6ae887defb /sys
parentResize the pcb hashtable automatically. The table size will be doubled (diff)
downloadwireguard-openbsd-d4c7cd03d53d3129d20ed9da0aa4e88a8b9ea8da.tar.xz
wireguard-openbsd-d4c7cd03d53d3129d20ed9da0aa4e88a8b9ea8da.zip
Fix USB connect freeze by clearing the host port interrupt.
Connects and disconnects have no affect on the machine, just like before this driver came into existence. While at it check for a few more interrupt types.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/octeon/dev/octhci.c67
1 files changed, 46 insertions, 21 deletions
diff --git a/sys/arch/octeon/dev/octhci.c b/sys/arch/octeon/dev/octhci.c
index 74e2affe24a..f51c2732d82 100644
--- a/sys/arch/octeon/dev/octhci.c
+++ b/sys/arch/octeon/dev/octhci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: octhci.c,v 1.13 2014/07/12 19:54:17 pirofti Exp $ */
+/* $OpenBSD: octhci.c,v 1.14 2014/07/12 21:07:33 pirofti Exp $ */
/*
* Copyright (c) 2014 Paul Irofti <pirofti@openbsd.org>
@@ -80,7 +80,8 @@ void octhci_init_core(struct octhci_softc *);
void octhci_init_host(struct octhci_softc *);
int octhci_intr(void *);
-int octhci_intr1(struct octhci_softc *);
+int octhci_intr1(struct octhci_softc *);
+int octhci_intr_host_port(struct octhci_softc *);
const struct cfattach octhci_ca = {
sizeof(struct octhci_softc), octhci_match, octhci_attach,
@@ -379,34 +380,58 @@ octhci_intr1(struct octhci_softc *sc)
sc->sc_bus.no_intrs++;
octhci_regc_write(sc, USBC_GINTSTS_OFFSET, intsts); /* Acknowledge */
- usb_schedsoftintr(&sc->sc_bus);
-#if 0
- if ((intsts & USBC_GINTSTS_DISCONNINT) ||
- (intsts & USBC_GINTSTS_PRTINT)) {
- /* Device disconnected */
-
- /* XXX: user callback */
- octhci_regc_clear(sc, USBC_HPRT_OFFSET, USBC_HPRT_PRTENA);
+ if (intsts & USBC_GINTSTS_WKUPINT) {
+ DPRINTFN(16, ("%s: wake-up interrupt\n", DEVNAME(sc)));
+ octhci_regc_set(sc, USBC_GINTSTS_OFFSET,
+ USBC_GINTSTS_WKUPINT);
+ }
+ if (intsts & USBC_GINTSTS_SESSREQINT) {
+ DPRINTFN(16, ("%s: session request interrupt\n", DEVNAME(sc)));
+ octhci_regc_set(sc, USBC_GINTSTS_OFFSET,
+ USBC_GINTSTS_SESSREQINT);
+ }
+ if (intsts & USBC_GINTSTS_DISCONNINT) {
+ DPRINTFN(16, ("%s: disco interrupt\n", DEVNAME(sc)));
+ octhci_regc_set(sc, USBC_GINTSTS_OFFSET,
+ USBC_GINTSTS_DISCONNINT);
+ }
+ if (intsts & USBC_GINTSTS_CONIDSTSCHNG) {
+ DPRINTFN(16, ("%s: connector ID interrupt\n", DEVNAME(sc)));
+ octhci_regc_set(sc, USBC_GINTSTS_OFFSET,
+ USBC_GINTSTS_CONIDSTSCHNG);
}
if (intsts & USBC_GINTSTS_HCHINT) {
- /* Host Channel Interrupt */
- uint32_t haint;
- int chan;
-
- /* XXX: Assume single USB port */
- for (haint = octhci_regc_read(sc, USBC_HAINT_OFFSET);
- haint != 0; haint ^= (1 << chan)) {
- chan = ffs32(haint) - 1;
- /* XXX: implement octhci_poll_chan(sc, chan); */
- }
+ DPRINTFN(16, ("%s: host channel interrupt\n", DEVNAME(sc)));
+ /* XXX: add host channel irq handler */
}
-#endif
+ if (intsts & USBC_GINTSTS_PRTINT) {
+ DPRINTFN(16, ("%s: host port interrupt\n", DEVNAME(sc)));
+ octhci_intr_host_port(sc);
+ }
+ if (intsts & USBC_GINTSTS_MODEMIS) {
+ DPRINTFN(16, ("%s: mode missmatch\n", DEVNAME(sc)));
+ }
+ if (intsts & USBC_GINTSTS_OTGINT) {
+ DPRINTFN(16, ("%s: OTG interrupt\n", DEVNAME(sc)));
+ }
+
+ usb_schedsoftintr(&sc->sc_bus);
sc->sc_bus.intr_context--;
return (1);
}
+int
+octhci_intr_host_port(struct octhci_softc *sc)
+{
+ uint32_t hprt = octhci_regc_read(sc, USBC_HPRT_OFFSET);
+
+ octhci_regc_write(sc, USBC_HPRT_OFFSET, hprt); /* Acknowledge */
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
inline void
octhci_regn_set(struct octhci_softc *sc, bus_size_t offset, uint64_t bits)
{