Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/usb Simplify synchronization between umcs(4) intr an...



details:   https://anonhg.NetBSD.org/src/rev/8b21785258cf
branches:  trunk
changeset: 328020:8b21785258cf
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Mar 23 20:20:38 2014 +0000

description:
Simplify synchronization between umcs(4) intr and task.

ok martin@, nick@

diffstat:

 sys/dev/usb/umcs.c |  27 +++++++++++++--------------
 1 files changed, 13 insertions(+), 14 deletions(-)

diffs (87 lines):

diff -r d8e458d5746b -r 8b21785258cf sys/dev/usb/umcs.c
--- a/sys/dev/usb/umcs.c        Sun Mar 23 19:49:52 2014 +0000
+++ b/sys/dev/usb/umcs.c        Sun Mar 23 20:20:38 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: umcs.c,v 1.5 2014/03/22 20:56:04 martin Exp $ */
+/* $NetBSD: umcs.c,v 1.6 2014/03/23 20:20:38 riastradh Exp $ */
 /* $FreeBSD: head/sys/dev/usb/serial/umcs.c 260559 2014-01-12 11:44:28Z hselasky $ */
 
 /*-
@@ -41,7 +41,7 @@
  *
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umcs.c,v 1.5 2014/03/22 20:56:04 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umcs.c,v 1.6 2014/03/23 20:20:38 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -78,9 +78,6 @@
  */
 struct umcs7840_softc_oneport {
        device_t sc_port_ucom;          /* ucom subdevice */
-       volatile uint32_t               /* changes for this port have */
-               sc_port_changed;        /* been signaled,
-                                          call ucom_status_change() */
        unsigned int sc_port_phys;      /* physical port number */
        uint8_t sc_port_lcr;            /* local line control register */
        uint8_t sc_port_mcr;            /* local modem control register */
@@ -94,6 +91,7 @@
        uint8_t *sc_intr_buf;           /* buffer for interrupt xfer */
        unsigned int sc_intr_buflen;    /* size of buffer */
        struct usb_task sc_change_task; /* async status changes */
+       volatile uint32_t sc_change_mask;       /* mask of port changes */
        struct umcs7840_softc_oneport sc_ports[UMCS7840_MAX_PORTS];
                                        /* data for each port */
        uint8_t sc_numports;            /* number of ports (subunits) */
@@ -889,7 +887,7 @@
 
        usbd_get_xfer_status(xfer, NULL, NULL, &actlen, NULL);
        if (actlen == 5 || actlen == 13) {
-               usb_rem_task(sc->sc_udev, &sc->sc_change_task);
+               uint32_t change_mask = 0;
                /* Check status of all ports */
                for (subunit = 0; subunit < sc->sc_numports; subunit++) {
                        uint8_t pn = sc->sc_ports[subunit].sc_port_phys;
@@ -904,7 +902,7 @@
                        case MCS7840_UART_ISR_RXHASDATA:
                        case MCS7840_UART_ISR_RXTIMEOUT:
                        case MCS7840_UART_ISR_MSCHANGE:
-                               sc->sc_ports[subunit].sc_port_changed = 1;
+                               change_mask |= (1U << subunit);
                                break;
                        default:
                                /* Do nothing */
@@ -912,9 +910,11 @@
                        }
                }
 
-               membar_exit();
-               usb_add_task(sc->sc_udev, &sc->sc_change_task,
-                   USB_TASKQ_DRIVER);
+               if (change_mask != 0) {
+                       atomic_or_32(&sc->sc_change_mask, change_mask);
+                       usb_add_task(sc->sc_udev, &sc->sc_change_task,
+                           USB_TASKQ_DRIVER);
+               }
        } else {
                aprint_error_dev(sc->sc_dev,
                   "Invalid interrupt data length %d", actlen);
@@ -925,14 +925,13 @@
 umcs7840_change_task(void *arg)
 {
        struct umcs7840_softc *sc = arg;
+       uint32_t change_mask;
        int i;
 
+       change_mask = atomic_swap_32(&sc->sc_change_mask, 0);
        for (i = 0; i < sc->sc_numports; i++) {
-               if (sc->sc_ports[i].sc_port_changed) {
-                       sc->sc_ports[i].sc_port_changed = 0;
-                       membar_exit();
+               if (ISSET(change_mask, (1U << i)))
                        ucom_status_change(device_private(
                            sc->sc_ports[i].sc_port_ucom));
-               }
        }
 }



Home | Main Index | Thread Index | Old Index