Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ieee1394 Fix sbp attach/detach.



details:   https://anonhg.NetBSD.org/src/rev/676ddca7ad66
branches:  trunk
changeset: 757090:676ddca7ad66
user:      cegger <cegger%NetBSD.org@localhost>
date:      Sat Aug 14 10:39:33 2010 +0000

description:
Fix sbp attach/detach.
When plugging a firewire webcam, sbp attaches.
sbpattach() calls sbp_alloc_target().
In sbp_alloc_target, crom_search_key() fails and sbp_alloc_target() returns NULL.
Move mutex and list initializations up in sbpattach() and in sbp_alloc_target()
so that destroyal of them through sbpdetach() does not cause
LOCKDEBUG panics when unplugging the firewire webcam.

diffstat:

 sys/dev/ieee1394/sbp.c |  43 ++++++++++++++++++++++++++-----------------
 1 files changed, 26 insertions(+), 17 deletions(-)

diffs (114 lines):

diff -r d894882cda48 -r 676ddca7ad66 sys/dev/ieee1394/sbp.c
--- a/sys/dev/ieee1394/sbp.c    Sat Aug 14 10:30:11 2010 +0000
+++ b/sys/dev/ieee1394/sbp.c    Sat Aug 14 10:39:33 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sbp.c,v 1.32 2010/05/23 18:56:59 christos Exp $        */
+/*     $NetBSD: sbp.c,v 1.33 2010/08/14 10:39:33 cegger Exp $  */
 /*-
  * Copyright (c) 2003 Hidetoshi Shimokawa
  * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sbp.c,v 1.32 2010/05/23 18:56:59 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sbp.c,v 1.33 2010/08/14 10:39:33 cegger Exp $");
 
 
 #include <sys/param.h>
@@ -495,6 +495,12 @@
        sc->sc_target.fwdev = NULL;
        sc->sc_target.luns = NULL;
 
+       /* Initialize mutexes and lists before we can error out
+        * to prevent crashes on detach
+        */
+       mutex_init(&sc->sc_fwb.fwb_mtx, MUTEX_DEFAULT, IPL_VM);
+       STAILQ_INIT(&sc->sc_fwb.xferlist);
+
        if (sbp_alloc_target(sc, fwa->fwdev) == NULL)
                return;
 
@@ -525,9 +531,7 @@
        dv_unit = device_unit(sc->sc_fd.dev);
        sc->sc_fwb.start = SBP_DEV2ADDR(dv_unit, 0);
        sc->sc_fwb.end = SBP_DEV2ADDR(dv_unit, -1);
-       mutex_init(&sc->sc_fwb.fwb_mtx, MUTEX_DEFAULT, IPL_VM);
        /* pre-allocate xfer */
-       STAILQ_INIT(&sc->sc_fwb.xferlist);
        fw_xferlist_add(&sc->sc_fwb.xferlist, M_SBP,
            /*send*/ 0, /*recv*/ SBP_RECV_LEN, SBP_NUM_OCB / 2,
            fc, (void *)sc, sbp_recv);
@@ -550,7 +554,7 @@
 
        sbp_scsipi_detach_target(&sc->sc_target);
 
-       if (SBP_FWDEV_ALIVE(sc->sc_target.fwdev)) {
+       if (sc->sc_target.fwdev && SBP_FWDEV_ALIVE(sc->sc_target.fwdev)) {
                sbp_logout_all(sc);
 
                /* XXX wait for logout completion */
@@ -566,6 +570,7 @@
        mutex_destroy(&sc->sc_fwb.fwb_mtx);
 
        mutex_destroy(&sc->sc_mtx);
+       cv_destroy(&sc->sc_cv);
 
        return 0;
 }
@@ -841,17 +846,6 @@
        target->sbp = sc;
        target->fwdev = fwdev;
        target->target_id = 0;
-       /* XXX we may want to reload mgm port after each bus reset */
-       /* XXX there might be multiple management agents */
-       crom_init_context(&cc, target->fwdev->csrrom);
-       reg = crom_search_key(&cc, CROM_MGM);
-       if (reg == NULL || reg->val == 0) {
-               aprint_error_dev(sc->sc_fd.dev, "NULL management address\n");
-               target->fwdev = NULL;
-               return NULL;
-       }
-       target->mgm_hi = 0xffff;
-       target->mgm_lo = 0xf0000000 | (reg->val << 2);
        target->mgm_ocb_cur = NULL;
 SBP_DEBUG(1)
        printf("target: mgm_port: %x\n", target->mgm_lo);
@@ -863,6 +857,20 @@
 
        target->luns = NULL;
        target->num_lun = 0;
+
+       /* XXX we may want to reload mgm port after each bus reset */
+       /* XXX there might be multiple management agents */
+       crom_init_context(&cc, target->fwdev->csrrom);
+       reg = crom_search_key(&cc, CROM_MGM);
+       if (reg == NULL || reg->val == 0) {
+               aprint_error_dev(sc->sc_fd.dev, "NULL management address\n");
+               target->fwdev = NULL;
+               return NULL;
+       }
+
+       target->mgm_hi = 0xffff;
+       target->mgm_lo = 0xf0000000 | (reg->val << 2);
+
        return target;
 }
 
@@ -2023,7 +2031,7 @@
        printf("sbp_logout_all\n");
 END_DEBUG
        target = &sbp->sc_target;
-       if (target->luns != NULL)
+       if (target->luns != NULL) {
                for (i = 0; i < target->num_lun; i++) {
                        sdev = target->luns[i];
                        if (sdev == NULL)
@@ -2033,6 +2041,7 @@
                            sdev->status <= SBP_DEV_ATTACHED)
                                sbp_mgm_orb(sdev, ORB_FUN_LGO, NULL);
                }
+       }
 
        return 0;
 }



Home | Main Index | Thread Index | Old Index