Source-Changes-HG archive

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

[src/netbsd-9]: src/sys/dev Pull up following revision(s) (requested by mrg i...



details:   https://anonhg.NetBSD.org/src/rev/d8e633ce8ad3
branches:  netbsd-9
changeset: 936964:d8e633ce8ad3
user:      martin <martin%NetBSD.org@localhost>
date:      Sun Aug 09 14:03:07 2020 +0000

description:
Pull up following revision(s) (requested by mrg in ticket #1042):

        sys/dev/sdmmc/if_bwfm_sdio.c: revision 1.19
        sys/dev/sdmmc/ld_sdmmc.c: revision 1.38
        sys/dev/sdmmc/sdmmcvar.h: revision 1.35
        sys/dev/sdmmc/if_bwfm_sdio.c: revision 1.5
        sys/dev/ic/bwfm.c: revision 1.26
        sys/dev/ic/bwfm.c: revision 1.27
        sys/dev/sdmmc/if_bwfm_sdio.c: revision 1.20
        sys/dev/sdmmc/if_bwfm_sdio.c: revision 1.21
        sys/dev/sdmmc/sdmmc_io.c: revision 1.20
        sys/dev/sdmmc/sdmmc_mem.c: revision 1.72
        sys/dev/sdmmc/sdmmc.c: revision 1.40
        sys/dev/sdmmc/sdmmc_ioreg.h: revision 1.6
        sys/dev/sdmmc/if_bwfm_sdio.c: revision 1.16

Don't pass empty mbufs to the network stack.

Avoid changing signedness bit with << in sdmmc_ioreg.h
Reported by <prlw1>

If the controller doesn't support switch func (opcode 6) then skip
setting this but continue with other settings.  This allows us to use
a card, albeit at a lower speed.

Fix races in sdmmc tasks and teach ld@sdmmc to abort xfers on detach.
- Teach sdmmc_add_task to queue it only if not already queued.
- Remove now-redundant logic to avoid repeated queueing elsewhere.
- Teach sdmmc_del_task to wait until task has completed.
- Call sdmmc_del_task in various needful places.
- Replace abuse of pcq by a lock and a tailq.
  (pcq is multi-producer, _single_-consumer, but there are potentially
  multiple consumers here and really only one producer.)
- Teach ld_sdmmc to abort xfers on detach.
  (Mechanism is kinda kludgey but it'll do for now; any effort one is
  tempted to spend overhauling this should be spent overhauling sdmmc
  to support proper asynchronous commands.)
- Make sure ld_sdmmc_discard either returns failure or eventually calls
  ldenddiscard.

XXX Currently ld_sdmmc_detach aborts xfers _before_ ldbegindetach has
has committed to detaching or not.  This is currently necessary to
avoid a deadlock because ldbegindetach waits for xfers to drain --
which strikes me as wrong; ldbegindetach shouldn't wait for anything,
and should only make the decision to commit to detaching or not so
the caller can decide whether to abort xfers before we actually wait
for them in ldenddetach.

XXX pullup -- although this changes some kernel symbols (sdmmc_add_task
and sdmmc_del_task), it shouldn't affect any existing modules; the only
module that uses sdmmc is ld_sdmmc.kmod, which is `.if 0' in the build
so there shouldn't be any of them floating around.

Make this work on big endian machines

move some of the patching of callbacks and other data after
ieee80211_ifattach() but before if_deferred_start_init().
may fix panic i saw in after restarting wpa_supplicant.
from mlelstv.

only ask for SDPCMD_INTSTATUS_HMB_SW_MASK and SDPCMD_INTSTATUS_CHIPACTIVE
interrupts, not all of them.  we only ack these ones.
mostly fixes pinebookpro wifi hard hangs.  still is problematic and can
trigger interrupt storm that appears as a hard hang without NET_MPSAFE,
and a follow up, less clearly right, change will reduce that to a soft
hang of the interface that can be cleared with 'ifconfig bwfm0 down up',
and even often recovers itself now.

clear all interrupts, not just those we expect from the hostintmask.
this removes the final hard hang i have seen in pinebookpro wifi,
though one may still need to 'ifconfig bwfm0 down up' occasionally,
so we still have bugs to fix here (the hang is usually associated
with 'checksum error' from bwfm/sdio.)

Sort #includes.  Nix trailing whitespace.
No functional change intended.

diffstat:

 sys/dev/ic/bwfm.c            |   28 ++-
 sys/dev/sdmmc/if_bwfm_sdio.c |   64 +++-----
 sys/dev/sdmmc/ld_sdmmc.c     |  295 +++++++++++++++++++++++++++++++++++-------
 sys/dev/sdmmc/sdmmc.c        |   63 ++++++--
 sys/dev/sdmmc/sdmmc_io.c     |    9 +-
 sys/dev/sdmmc/sdmmc_ioreg.h  |    6 +-
 sys/dev/sdmmc/sdmmc_mem.c    |   16 +-
 sys/dev/sdmmc/sdmmcvar.h     |    8 +-
 8 files changed, 347 insertions(+), 142 deletions(-)

diffs (truncated from 978 to 300 lines):

diff -r 0d1852b249a8 -r d8e633ce8ad3 sys/dev/ic/bwfm.c
--- a/sys/dev/ic/bwfm.c Wed Aug 05 15:20:21 2020 +0000
+++ b/sys/dev/ic/bwfm.c Sun Aug 09 14:03:07 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bwfm.c,v 1.14.6.1 2020/02/25 18:40:43 martin Exp $ */
+/* $NetBSD: bwfm.c,v 1.14.6.2 2020/08/09 14:03:08 martin Exp $ */
 /* $OpenBSD: bwfm.c,v 1.5 2017/10/16 22:27:16 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
@@ -18,21 +18,23 @@
  */
 
 #include <sys/param.h>
-#include <sys/systm.h>
+#include <sys/types.h>
+
 #include <sys/buf.h>
+#include <sys/device.h>
 #include <sys/kernel.h>
-#include <sys/device.h>
+#include <sys/kmem.h>
+#include <sys/pcq.h>
 #include <sys/queue.h>
 #include <sys/socket.h>
-#include <sys/kmem.h>
+#include <sys/systm.h>
 #include <sys/workqueue.h>
-#include <sys/pcq.h>
 
 #include <net/bpf.h>
 #include <net/if.h>
 #include <net/if_dl.h>
+#include <net/if_ether.h>
 #include <net/if_media.h>
-#include <net/if_ether.h>
 
 #include <netinet/in.h>
 
@@ -203,7 +205,7 @@
            sizeof(bandlist))) {
                printf("%s: couldn't get supported band list\n", DEVNAME(sc));
                return;
-       } 
+       }
        const u_int nbands = le32toh(bandlist[0]);
        for (i = 1; i <= MIN(nbands, __arraycount(bandlist) - 1); i++) {
                switch (le32toh(bandlist[i])) {
@@ -252,12 +254,8 @@
 
                return; /* Error */
        }
-               
+
        ieee80211_ifattach(ic);
-       ifp->if_percpuq = if_percpuq_create(ifp);
-       if_deferred_start_init(ifp, NULL);
-       if_register(ifp);
-
        sc->sc_newstate = ic->ic_newstate;
        ic->ic_newstate = bwfm_newstate;
        ic->ic_newassoc = bwfm_newassoc;
@@ -265,6 +263,10 @@
        ic->ic_recv_mgmt = bwfm_recv_mgmt;
        ic->ic_crypto.cs_key_set = bwfm_key_set;
        ic->ic_crypto.cs_key_delete = bwfm_key_delete;
+
+       ifp->if_percpuq = if_percpuq_create(ifp);
+       if_deferred_start_init(ifp, NULL);
+       if_register(ifp);
        ieee80211_media_init(ic, bwfm_media_change, ieee80211_media_status);
 
        ieee80211_announce(ic);
@@ -401,7 +403,7 @@
 #ifdef BWFM_DEBUG
        memset(evmask, 0xff, sizeof(evmask));
 #endif
-       
+
        if (bwfm_fwvar_var_set_data(sc, "event_msgs", evmask, sizeof(evmask))) {
                printf("%s: could not set event mask\n", DEVNAME(sc));
                return EIO;
diff -r 0d1852b249a8 -r d8e633ce8ad3 sys/dev/sdmmc/if_bwfm_sdio.c
--- a/sys/dev/sdmmc/if_bwfm_sdio.c      Wed Aug 05 15:20:21 2020 +0000
+++ b/sys/dev/sdmmc/if_bwfm_sdio.c      Sun Aug 09 14:03:07 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bwfm_sdio.c,v 1.3.8.2 2020/05/07 17:06:44 martin Exp $ */
+/* $NetBSD: if_bwfm_sdio.c,v 1.3.8.3 2020/08/09 14:03:07 martin Exp $ */
 /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
@@ -71,7 +71,6 @@
 struct bwfm_sdio_softc {
        struct bwfm_softc       sc_sc;
        kmutex_t                sc_lock;
-       kmutex_t                sc_intr_lock;
 
        bool                    sc_bwfm_attached;
 
@@ -303,10 +302,8 @@
 
        mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
        cv_init(&sc->sc_rxctl_cv, "bwfmctl");
-       mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_NONE);
 
        sdmmc_init_task(&sc->sc_task, bwfm_sdio_task, sc);
-       sc->sc_task_queued = false;
 
        sc->sc_bounce_size = 64 * 1024;
        sc->sc_bounce_buf = kmem_alloc(sc->sc_bounce_size, KM_SLEEP);
@@ -548,9 +545,8 @@
                goto err;
        }
 
-//     bwfm_sdio_dev_write(sc, SDPCMD_HOSTINTMASK,
-//         SDPCMD_INTSTATUS_HMB_SW_MASK | SDPCMD_INTSTATUS_CHIPACTIVE);
-       bwfm_sdio_dev_write(sc, SDPCMD_HOSTINTMASK, 0xffffffff);
+       bwfm_sdio_dev_write(sc, SDPCMD_HOSTINTMASK,
+           SDPCMD_INTSTATUS_HMB_SW_MASK | SDPCMD_INTSTATUS_CHIPACTIVE);
        bwfm_sdio_write_1(sc, BWFM_SDIO_WATERMARK, 8);
 
        if (bwfm_chip_sr_capable(bwfm)) {
@@ -668,10 +664,11 @@
        if (sc->sc_bwfm_attached)
                bwfm_detach(&sc->sc_sc, flags);
 
+       sdmmc_del_task(sc->sc_sf[1]->sc, &sc->sc_task, NULL);
+
        kmem_free(sc->sc_sf, sc->sc_sf_size);
        kmem_free(sc->sc_bounce_buf, sc->sc_bounce_size);
 
-       mutex_destroy(&sc->sc_intr_lock);
        cv_destroy(&sc->sc_rxctl_cv);
        mutex_destroy(&sc->sc_lock);
 
@@ -739,7 +736,7 @@
                sf = sc->sc_sf[1];
 
        rv = sdmmc_io_read_4(sf, addr);
-       return rv;
+       return htole32(rv);
 }
 
 static void
@@ -782,7 +779,7 @@
        else
                sf = sc->sc_sf[1];
 
-       sdmmc_io_write_4(sf, addr, data);
+       sdmmc_io_write_4(sf, addr, htole32(data));
 }
 
 static int
@@ -1474,11 +1471,7 @@
 
        DPRINTF(("%s: %s\n", DEVNAME(sc), name));
 
-       mutex_enter(&sc->sc_intr_lock);
-       if (!sdmmc_task_pending(&sc->sc_task))
-               sdmmc_add_task(sc->sc_sf[1]->sc, &sc->sc_task);
-       sc->sc_task_queued = true;
-       mutex_exit(&sc->sc_intr_lock);
+       sdmmc_add_task(sc->sc_sf[1]->sc, &sc->sc_task);
        return 1;
 }
 
@@ -1492,33 +1485,13 @@
 bwfm_sdio_task(void *v)
 {
        struct bwfm_sdio_softc *sc = (void *)v;
+
+       mutex_enter(&sc->sc_lock);
+       bwfm_sdio_task1(sc);
 #ifdef BWFM_DEBUG
-       unsigned count = 0;
-#endif
-
-       mutex_enter(&sc->sc_intr_lock);
-       while (sc->sc_task_queued) {
-#ifdef BWFM_DEBUG
-               ++count;
+       bwfm_sdio_debug_console(sc);
 #endif
-               sc->sc_task_queued = false;
-               mutex_exit(&sc->sc_intr_lock);
-
-               mutex_enter(&sc->sc_lock);
-               bwfm_sdio_task1(sc);
-#ifdef BWFM_DEBUG
-               bwfm_sdio_debug_console(sc);
-#endif
-               mutex_exit(&sc->sc_lock);
-
-               mutex_enter(&sc->sc_intr_lock);
-       }
-       mutex_exit(&sc->sc_intr_lock);
-
-#ifdef BWFM_DEBUG
-       if (count > 1)
-               DPRINTF(("%s: finished %u tasks\n", DEVNAME(sc), count));
-#endif
+       mutex_exit(&sc->sc_lock);
 }
 
 static void
@@ -1541,7 +1514,6 @@
 
        intstat = bwfm_sdio_dev_read(sc, BWFM_SDPCMD_INTSTATUS);
        DPRINTF(("%s: intstat 0x%" PRIx32 "\n", DEVNAME(sc), intstat));
-       intstat &= (SDPCMD_INTSTATUS_HMB_SW_MASK|SDPCMD_INTSTATUS_CHIPACTIVE);
        if (intstat)
                bwfm_sdio_dev_write(sc, BWFM_SDPCMD_INTSTATUS, intstat);
 
@@ -1868,6 +1840,11 @@
                                break;
                        }
                        m_adj(m, hoff);
+                       /* don't pass empty packet to stack */
+                       if (m->m_len == 0) {
+                               m_freem(m);
+                               break;
+                       }
                        bwfm_rx(&sc->sc_sc, m);
                        nextlen = swhdr->nextlen << 4;
                        break;
@@ -2014,6 +1991,11 @@
                                break;
                        }
                        m_adj(m, hoff);
+                       /* don't pass empty packet to stack */
+                       if (m->m_len == 0) {
+                               m_freem(m);
+                               break;
+                       }
                        bwfm_rx(&sc->sc_sc, m);
                        break;
                case BWFM_SDIO_SWHDR_CHANNEL_GLOM:
diff -r 0d1852b249a8 -r d8e633ce8ad3 sys/dev/sdmmc/ld_sdmmc.c
--- a/sys/dev/sdmmc/ld_sdmmc.c  Wed Aug 05 15:20:21 2020 +0000
+++ b/sys/dev/sdmmc/ld_sdmmc.c  Sun Aug 09 14:03:07 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ld_sdmmc.c,v 1.36 2019/03/19 07:08:43 mlelstv Exp $    */
+/*     $NetBSD: ld_sdmmc.c,v 1.36.4.1 2020/08/09 14:03:07 martin Exp $ */
 
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.36 2019/03/19 07:08:43 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.36.4.1 2020/08/09 14:03:07 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sdmmc.h"
@@ -59,7 +59,7 @@
 #ifdef LD_SDMMC_DEBUG
 #define DPRINTF(s)     printf s
 #else
-#define DPRINTF(s)     /**/
+#define DPRINTF(s)     __nothing
 #endif
 
 #define        LD_SDMMC_IORETRIES      5       /* number of retries before giving up */
@@ -72,32 +72,37 @@
 
 struct ld_sdmmc_task {
        struct sdmmc_task task;
-
        struct ld_sdmmc_softc *task_sc;
 
        struct buf *task_bp;
        int task_retries; /* number of xfer retry */
        struct callout task_restart_ch;
 
-       kmutex_t task_lock;
-       kcondvar_t task_cv;
+       bool task_poll;
+       int *task_errorp;
 
-       uintptr_t task_data;
+       TAILQ_ENTRY(ld_sdmmc_task) task_entry;
 };
 
 struct ld_sdmmc_softc {
        struct ld_softc sc_ld;
        int sc_hwunit;
-
+       char *sc_typename;
        struct sdmmc_function *sc_sf;
-       struct ld_sdmmc_task sc_task[LD_SDMMC_MAXTASKCNT];
-       pcq_t *sc_freeq;
-       char *sc_typename;
+
+       kmutex_t sc_lock;
+       kcondvar_t sc_cv;
+       TAILQ_HEAD(, ld_sdmmc_task) sc_freeq;
+       TAILQ_HEAD(, ld_sdmmc_task) sc_xferq;
+       unsigned sc_busy;
+       bool sc_dying;
 



Home | Main Index | Thread Index | Old Index