Source-Changes-HG archive

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

[src/jmcneill-usbmp]: src/sys/dev/usb my compiles-but-un-runtime-tested port ...



details:   https://anonhg.NetBSD.org/src/rev/92c20e9b9f23
branches:  jmcneill-usbmp
changeset: 771780:92c20e9b9f23
user:      mrg <mrg%NetBSD.org@localhost>
date:      Tue Dec 06 05:06:50 2011 +0000

description:
my compiles-but-un-runtime-tested port of uhci to usbmp branch.
based upon the ohci and ehci changes.

diffstat:

 sys/dev/usb/uhci.c    |  292 +++++++++++++++++++++++++++++++------------------
 sys/dev/usb/uhcivar.h |    6 +-
 2 files changed, 189 insertions(+), 109 deletions(-)

diffs (truncated from 1038 to 300 lines):

diff -r ebc84d7bd231 -r 92c20e9b9f23 sys/dev/usb/uhci.c
--- a/sys/dev/usb/uhci.c        Tue Dec 06 05:05:30 2011 +0000
+++ b/sys/dev/usb/uhci.c        Tue Dec 06 05:06:50 2011 +0000
@@ -1,13 +1,14 @@
-/*     $NetBSD: uhci.c,v 1.240.6.1 2011/12/04 13:23:17 jmcneill Exp $  */
+/*     $NetBSD: uhci.c,v 1.240.6.2 2011/12/06 05:06:50 mrg Exp $       */
 /*     $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $       */
 
 /*
- * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998, 2004, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
  * by Lennart Augustsson (lennart%augustsson.net@localhost) at
- * Carlstedt Research & Technology.
+ * Carlstedt Research & Technology, Jared D. McNeill (jmcneill%invisible.ca@localhost)
+ * and Matthew R. Green.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,14 +43,14 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.240.6.1 2011/12/04 13:23:17 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.240.6.2 2011/12/06 05:06:50 mrg Exp $");
 
 #include "opt_usb.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
-#include <sys/malloc.h>
+#include <sys/kmem.h>
 #include <sys/device.h>
 #include <sys/select.h>
 #include <sys/extent.h>
@@ -171,6 +172,8 @@
 
 Static usbd_xfer_handle        uhci_allocx(struct usbd_bus *);
 Static void            uhci_freex(struct usbd_bus *, usbd_xfer_handle);
+Static void            uhci_get_locks(struct usbd_bus *, kmutex_t **,
+                                      kmutex_t **);
 
 Static usbd_status     uhci_device_ctrl_transfer(usbd_xfer_handle);
 Static usbd_status     uhci_device_ctrl_start(usbd_xfer_handle);
@@ -288,7 +291,7 @@
        uhci_freem,
        uhci_allocx,
        uhci_freex,
-       NULL, /* uhci_get_locks */
+       uhci_get_locks,
 };
 
 const struct usbd_pipe_methods uhci_root_ctrl_methods = {
@@ -523,7 +526,11 @@
 
        SIMPLEQ_INIT(&sc->sc_free_xfers);
 
-       callout_init(&sc->sc_poll_handle, 0);
+       callout_init(&sc->sc_poll_handle, CALLOUT_MPSAFE);
+
+       mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
+       mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
+       cv_init(&sc->sc_softwake_cv, "uhciab");
 
        /* Set up the bus struct. */
        sc->sc_bus.methods = &uhci_bus_methods;
@@ -580,12 +587,17 @@
                if (xfer == NULL)
                        break;
                SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-               free(xfer, M_USB);
+               kmem_free(xfer, sizeof(struct uhci_xfer));
        }
 
        callout_halt(&sc->sc_poll_handle, NULL);
        callout_destroy(&sc->sc_poll_handle);
 
+       cv_destroy(&sc->sc_softwake_cv);
+
+       mutex_destroy(&sc->sc_lock);
+       mutex_destroy(&sc->sc_intr_lock);
+
        /* XXX free other data structures XXX */
 
        return (rv);
@@ -609,18 +621,19 @@
        if (n > 16) {
                u_int32_t i;
                uhci_soft_td_t **stds;
+
                DPRINTF(("uhci_allocm: get %d TDs\n", n));
-               stds = malloc(sizeof(uhci_soft_td_t *) * n, M_TEMP,
-                   M_WAITOK|M_ZERO);
-               for(i=0; i < n; i++)
+               stds = kmem_alloc(sizeof(uhci_soft_td_t *) * n, KM_SLEEP);
+               if (!stds)
+                       return USBD_NOMEM;
+               for(i = 0; i < n; i++)
                        stds[i] = uhci_alloc_std(sc);
-               for(i=0; i < n; i++)
+               for(i = 0; i < n; i++)
                        if (stds[i] != NULL)
                                uhci_free_std(sc, stds[i]);
-               free(stds, M_TEMP);
+               kmem_free(stds, sizeof(uhci_soft_td_t *) * n);
        }
 
-
        status = usb_allocmem(&sc->sc_bus, size, 0, dma);
        if (status == USBD_NOMEM)
                status = usb_reserve_allocm(&sc->sc_dma_reserve, dma, size);
@@ -654,7 +667,7 @@
                }
 #endif
        } else {
-               xfer = malloc(sizeof(struct uhci_xfer), M_USB, M_NOWAIT);
+               xfer = kmem_alloc(sizeof(struct uhci_xfer), KM_SLEEP);
        }
        if (xfer != NULL) {
                memset(xfer, 0, sizeof (struct uhci_xfer));
@@ -685,6 +698,16 @@
        SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
 }
 
+Static void
+uhci_get_locks(struct usbd_bus *bus, kmutex_t **intr, kmutex_t **thread)
+{
+       struct uhci_softc *sc = bus->hci_private;
+
+       *intr = &sc->sc_intr_lock;
+       *thread = &sc->sc_lock;
+}
+
+
 /*
  * Handle suspend/resume.
  *
@@ -697,9 +720,8 @@
 {
        uhci_softc_t *sc = device_private(dv);
        int cmd;
-       int s;
-
-       s = splhardusb();
+
+       mutex_spin_enter(&sc->sc_intr_lock);
 
        cmd = UREAD2(sc, UHCI_CMD);
        sc->sc_bus.use_polling++;
@@ -732,7 +754,7 @@
 #endif
 
        sc->sc_suspend = PWR_RESUME;
-       splx(s);
+       mutex_spin_exit(&sc->sc_intr_lock);
 
        return true;
 }
@@ -742,9 +764,8 @@
 {
        uhci_softc_t *sc = device_private(dv);
        int cmd;
-       int s;
-
-       s = splhardusb();
+
+       mutex_spin_enter(&sc->sc_intr_lock);
 
        cmd = UREAD2(sc, UHCI_CMD);
 
@@ -770,7 +791,7 @@
        usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
        sc->sc_bus.use_polling--;
 
-       splx(s);
+       mutex_spin_exit(&sc->sc_intr_lock);
 
        return true;
 }
@@ -992,7 +1013,6 @@
        usbd_xfer_handle xfer = addr;
        usbd_pipe_handle pipe = xfer->pipe;
        uhci_softc_t *sc;
-       int s;
        u_char *p;
 
        DPRINTFN(20, ("uhci_poll_hub\n"));
@@ -1014,11 +1034,11 @@
 
        xfer->actlen = 1;
        xfer->status = USBD_NORMAL_COMPLETION;
-       s = splusb();
+       mutex_enter(&sc->sc_lock);
        xfer->device->bus->intr_context++;
        usb_transfer_complete(xfer);
        xfer->device->bus->intr_context--;
-       splx(s);
+       mutex_exit(&sc->sc_lock);
 }
 
 void
@@ -1269,18 +1289,25 @@
 uhci_intr(void *arg)
 {
        uhci_softc_t *sc = arg;
+       int ret = 0;
+
+       mutex_spin_enter(&sc->sc_intr_lock);
 
        if (sc->sc_dying || !device_has_power(sc->sc_dev))
-               return (0);
+               goto done;
 
        if (sc->sc_bus.use_polling || UREAD2(sc, UHCI_INTR) == 0) {
 #ifdef DIAGNOSTIC
                DPRINTFN(16, ("uhci_intr: ignored interrupt while polling\n"));
 #endif
-               return (0);
+               goto done;
        }
 
-       return (uhci_intr1(sc));
+       ret = uhci_intr1(sc);
+
+ done:
+       mutex_spin_exit(&sc->sc_intr_lock);
+       return ret;
 }
 
 int
@@ -1296,6 +1323,8 @@
        }
 #endif
 
+       KASSERT(mutex_owned(&sc->sc_lock));
+
        status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS;
        if (status == 0)        /* The interrupt was not for us. */
                return (0);
@@ -1365,6 +1394,8 @@
        DPRINTFN(10,("%s: uhci_softintr (%d)\n", device_xname(sc->sc_dev),
                     sc->sc_bus.intr_context));
 
+       mutex_enter(&sc->sc_lock);
+
        sc->sc_bus.intr_context++;
 
        /*
@@ -1383,14 +1414,14 @@
                uhci_check_intr(sc, ii);
        }
 
-#ifdef USB_USE_SOFTINTR
        if (sc->sc_softwake) {
                sc->sc_softwake = 0;
-               wakeup(&sc->sc_softwake);
+               cv_broadcast(&sc->sc_softwake_cv);
        }
-#endif /* USB_USE_SOFTINTR */
 
        sc->sc_bus.intr_context--;
+
+       mutex_exit(&sc->sc_lock);
 }
 
 /* Check for an interrupt. */
@@ -1485,6 +1516,7 @@
        DPRINTFN(12, ("uhci_idone: ii=%p\n", ii));
 #ifdef DIAGNOSTIC
        {
+               /* XXX SMP? */
                int s = splhigh();
                if (ii->isdone) {
                        splx(s);
@@ -1631,13 +1663,10 @@
 uhci_timeout_task(void *addr)
 {
        usbd_xfer_handle xfer = addr;
-       int s;
 
        DPRINTF(("uhci_timeout_task: xfer=%p\n", xfer));
 
-       s = splusb();
        uhci_abort_xfer(xfer, USBD_TIMEOUT);
-       splx(s);
 }
 
 /*
@@ -1652,6 +1681,8 @@
        int timo = xfer->timeout;
        uhci_intr_info_t *ii;
 
+       mutex_enter(&sc->sc_lock);
+
        DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo));
 
        xfer->status = USBD_IN_PROGRESS;



Home | Main Index | Thread Index | Old Index