svn commit: r197686 - in projects/sbruno_firewire/sys: cam dev/firewire sys

Sean Bruno sbruno at FreeBSD.org
Thu Oct 1 20:11:43 UTC 2009


Author: sbruno
Date: Thu Oct  1 20:11:42 2009
New Revision: 197686
URL: http://svn.freebsd.org/changeset/base/197686

Log:
  Capture CAM enhancements from perforce via scottl
  
  instrument the callout function to indicate completion
  
  Avoid a racy condition in sbp where multiple targets could conflict with each other by giving each target it's own malloc and stop executing secondary targets via the callback handler.

Modified:
  projects/sbruno_firewire/sys/cam/cam_xpt.c
  projects/sbruno_firewire/sys/dev/firewire/sbp.c
  projects/sbruno_firewire/sys/sys/kernel.h

Modified: projects/sbruno_firewire/sys/cam/cam_xpt.c
==============================================================================
--- projects/sbruno_firewire/sys/cam/cam_xpt.c	Thu Oct  1 20:05:36 2009	(r197685)
+++ projects/sbruno_firewire/sys/cam/cam_xpt.c	Thu Oct  1 20:11:42 2009	(r197686)
@@ -107,8 +107,6 @@ struct xpt_softc {
 	TAILQ_HEAD(,cam_eb)	xpt_busses;
 	u_int			bus_generation;
 
-	struct intr_config_hook	*xpt_config_hook;
-
 	struct mtx		xpt_topo_lock;
 	struct mtx		xpt_lock;
 };
@@ -910,35 +908,19 @@ xpt_init(void *dummy)
 	xpt_free_path(path);
 	mtx_unlock(&xsoftc.xpt_lock);
 
-	/*
-	 * Register a callback for when interrupts are enabled.
-	 */
-	xsoftc.xpt_config_hook =
-	    (struct intr_config_hook *)malloc(sizeof(struct intr_config_hook),
-					      M_CAMXPT, M_NOWAIT | M_ZERO);
-	if (xsoftc.xpt_config_hook == NULL) {
-		printf("xpt_init: Cannot malloc config hook "
-		       "- failing attach\n");
-		return (ENOMEM);
-	}
-
-	xsoftc.xpt_config_hook->ich_func = xpt_config;
-	if (config_intrhook_establish(xsoftc.xpt_config_hook) != 0) {
-		free (xsoftc.xpt_config_hook, M_CAMXPT);
-		printf("xpt_init: config_intrhook_establish failed "
-		       "- failing attach\n");
-	}
-
 	/* fire up rescan thread */
 	if (kproc_create(xpt_scanner_thread, NULL, NULL, 0, 0, "xpt_thrd")) {
 		printf("xpt_init: failed to create rescan thread\n");
 	}
 	/* Install our software interrupt handlers */
-	swi_add(NULL, "cambio", camisr, NULL, SWI_CAMBIO, INTR_MPSAFE, &cambio_ih);
+	swi_add(NULL, "cambio", camisr, NULL, SWI_CAMBIO, INTR_MPSAFE,
+		&cambio_ih);
 
 	return (0);
 }
 
+SYSINIT(cam_config, SI_SUB_CONFIG_CAM, SI_ORDER_FIRST, xpt_config, NULL);
+
 static cam_status
 xptregister(struct cam_periph *periph, void *arg)
 {
@@ -4697,6 +4679,13 @@ xpt_config(void *arg)
 		}
 		xpt_for_all_busses(xptconfigfunc, NULL);
 	}
+
+	mtx_lock(&xsoftc.xpt_lock);
+	while (msleep(xpt_config, &xsoftc.xpt_lock, PCONFIG, "camhk",
+		      30 * hz) == EWOULDBLOCK) {
+		printf("Warning\n");
+	}
+	mtx_unlock(&xsoftc.xpt_lock);
 }
 
 /*
@@ -4743,9 +4732,9 @@ xpt_finishconfig_task(void *context, int
 		xpt_for_all_devices(xptpassannouncefunc, NULL);
 
 		/* Release our hook so that the boot can continue. */
-		config_intrhook_disestablish(xsoftc.xpt_config_hook);
-		free(xsoftc.xpt_config_hook, M_CAMXPT);
-		xsoftc.xpt_config_hook = NULL;
+		mtx_lock(&xsoftc.xpt_lock);
+		wakeup(xpt_config);
+		mtx_unlock(&xsoftc.xpt_lock);
 	}
 
 	free(context, M_CAMXPT);

Modified: projects/sbruno_firewire/sys/dev/firewire/sbp.c
==============================================================================
--- projects/sbruno_firewire/sys/dev/firewire/sbp.c	Thu Oct  1 20:05:36 2009	(r197685)
+++ projects/sbruno_firewire/sys/dev/firewire/sbp.c	Thu Oct  1 20:11:42 2009	(r197686)
@@ -811,7 +811,7 @@ sbp_post_busreset(void *arg)
 
 	sbp = (struct sbp_softc *)arg;
 SBP_DEBUG(0)
-	printf("sbp_post_busreset\n");
+	printf("%s\n", __func__);
 END_DEBUG
 	SBP_LOCK(sbp);
 	if ((sbp->sim->flags & SIMQ_FREEZED) == 0) {
@@ -838,6 +838,7 @@ sbp_busreset_timeout(void *arg)
 	xpt_release_simq(sbp->sim, /*run queue*/TRUE);
 	sbp->sim->flags &= ~SIMQ_FREEZED;
 	SBP_UNLOCK(sbp);
+	printf("%s: Done\n", __func__);
 }
 
 
@@ -860,14 +861,6 @@ END_DEBUG
 	if (sbp_cold > 0)
 		sbp_cold --;
 
-#if 0
-	/*
-	 * XXX don't let CAM the bus rest.
-	 * CAM tries to do something with freezed (DEV_RETRY) devices.
-	 */
-	xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
-#endif
-
 	/* Garbage Collection */
 	for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){
 		target = &sbp->targets[i];
@@ -1036,6 +1029,8 @@ END_DEBUG
 		device_printf(sdev->target->sbp->fd.dev,
 			"%s:%s failed\n", __func__, sdev->bustgtlun);
 	}
+	free(ccb, M_SBP);
+#if 0
 	sdev = sbp_next_dev(target, sdev->lun_id + 1);
 	if (sdev == NULL) {
 		free(ccb, M_SBP);
@@ -1047,6 +1042,7 @@ END_DEBUG
 	xpt_action(ccb);
 	xpt_release_devq(sdev->path, sdev->freeze, TRUE);
 	sdev->freeze = 1;
+#endif
 }
 
 static void
@@ -1055,35 +1051,41 @@ sbp_cam_scan_target(void *arg)
 	struct sbp_target *target = (struct sbp_target *)arg;
 	struct sbp_dev *sdev;
 	union ccb *ccb;
+	int targ_ctr = 0;
 
+	while ((sdev = sbp_next_dev(target, targ_ctr)) != NULL) {
+#if 0
 	sdev = sbp_next_dev(target, 0);
 	if (sdev == NULL) {
 		printf("sbp_cam_scan_target: nothing to do for target%d\n",
 							target->target_id);
 		return;
 	}
+#endif
 SBP_DEBUG(0)
-	device_printf(sdev->target->sbp->fd.dev,
-		"%s:%s\n", __func__, sdev->bustgtlun);
+		device_printf(sdev->target->sbp->fd.dev,
+				"%s:%s\n", __func__, sdev->bustgtlun);
 END_DEBUG
-	ccb = malloc(sizeof(union ccb), M_SBP, M_NOWAIT | M_ZERO);
-	if (ccb == NULL) {
-		printf("sbp_cam_scan_target: malloc failed\n");
-		return;
-	}
-	xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI);
-	ccb->ccb_h.func_code = XPT_SCAN_LUN;
-	ccb->ccb_h.cbfcnp = sbp_cam_scan_lun;
-	ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
-	ccb->crcn.flags = CAM_FLAG_NONE;
-	ccb->ccb_h.ccb_sdev_ptr = sdev;
+		ccb = malloc(sizeof(union ccb), M_SBP, M_NOWAIT | M_ZERO);
+		if (ccb == NULL) {
+			printf("sbp_cam_scan_target: malloc failed\n");
+			break;
+		}
+		xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI);
+		ccb->ccb_h.func_code = XPT_SCAN_LUN;
+		ccb->ccb_h.cbfcnp = sbp_cam_scan_lun;
+		ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
+		ccb->crcn.flags = CAM_FLAG_NONE;
+		ccb->ccb_h.ccb_sdev_ptr = sdev;
 
-	/* The scan is in progress now. */
-	SBP_LOCK(target->sbp);
-	xpt_action(ccb);
-	xpt_release_devq(sdev->path, sdev->freeze, TRUE);
-	sdev->freeze = 1;
-	SBP_UNLOCK(target->sbp);
+		/* The scan is in progress now. */
+		SBP_LOCK(target->sbp);
+		xpt_action(ccb);
+		xpt_release_devq(sdev->path, sdev->freeze, TRUE);
+		sdev->freeze = 1;
+		SBP_UNLOCK(target->sbp);
+		targ_ctr++;
+	}
 }
 
 static __inline void

Modified: projects/sbruno_firewire/sys/sys/kernel.h
==============================================================================
--- projects/sbruno_firewire/sys/sys/kernel.h	Thu Oct  1 20:05:36 2009	(r197685)
+++ projects/sbruno_firewire/sys/sys/kernel.h	Thu Oct  1 20:11:42 2009	(r197686)
@@ -154,6 +154,7 @@ enum sysinit_sub_id {
 	SI_SUB_KPROF		= 0x9000000,	/* kernel profiling*/
 	SI_SUB_KICK_SCHEDULER	= 0xa000000,	/* start the timeout events*/
 	SI_SUB_INT_CONFIG_HOOKS	= 0xa800000,	/* Interrupts enabled config */
+	SI_SUB_CONFIG_CAM	= 0xa900000,	/* Interrupts enabled config */
 	SI_SUB_ROOT_CONF	= 0xb000000,	/* Find root devices */
 	SI_SUB_DUMP_CONF	= 0xb200000,	/* Find dump devices */
 	SI_SUB_RAID		= 0xb380000,	/* Configure GEOM classes */


More information about the svn-src-projects mailing list