Module Name: src
Committed By: cegger
Date: Sat Aug 14 10:39:36 UTC 2010
Modified Files:
src/sys/dev/ieee1394: sbp.c
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/sys/dev/ieee1394/sbp.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/ieee1394/sbp.c
diff -u src/sys/dev/ieee1394/sbp.c:1.32 src/sys/dev/ieee1394/sbp.c:1.33
--- src/sys/dev/ieee1394/sbp.c:1.32 Sun May 23 18:56:59 2010
+++ src/sys/dev/ieee1394/sbp.c Sat Aug 14 10:39:33 2010
@@ -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,6 +846,18 @@
target->sbp = sc;
target->fwdev = fwdev;
target->target_id = 0;
+ target->mgm_ocb_cur = NULL;
+SBP_DEBUG(1)
+ printf("target: mgm_port: %x\n", target->mgm_lo);
+END_DEBUG
+ STAILQ_INIT(&target->xferlist);
+ target->n_xfer = 0;
+ STAILQ_INIT(&target->mgm_ocb_queue);
+ callout_init(&target->mgm_ocb_timeout, CALLOUT_MPSAFE);
+
+ 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);
@@ -850,19 +867,10 @@
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);
-END_DEBUG
- STAILQ_INIT(&target->xferlist);
- target->n_xfer = 0;
- STAILQ_INIT(&target->mgm_ocb_queue);
- callout_init(&target->mgm_ocb_timeout, CALLOUT_MPSAFE);
- target->luns = NULL;
- target->num_lun = 0;
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;
}