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