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;
 }

Reply via email to