summaryrefslogtreecommitdiffstats
path: root/sys/cam/cam_xpt.c
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2007-05-16 16:54:23 +0000
committerscottl <scottl@FreeBSD.org>2007-05-16 16:54:23 +0000
commit74448961ec9a8ecb496066cacac4aee33258b2b0 (patch)
treeeb4208c40ec28ee618733168a87c1e69768e1c1a /sys/cam/cam_xpt.c
parent04e8b672c852d872cc214c6745d7cddca1d5080c (diff)
downloadFreeBSD-src-74448961ec9a8ecb496066cacac4aee33258b2b0.zip
FreeBSD-src-74448961ec9a8ecb496066cacac4aee33258b2b0.tar.gz
Add a helper function for registering async callbacks. Besides
eliminating a lot of duplicated code, this also fixes a locking edge case.
Diffstat (limited to 'sys/cam/cam_xpt.c')
-rw-r--r--sys/cam/cam_xpt.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 882ce61..9c64a5c 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -7029,6 +7029,39 @@ xpt_finishconfig(struct cam_periph *periph, union ccb *done_ccb)
xpt_free_ccb(done_ccb);
}
+cam_status
+xpt_register_async(int event, ac_callback_t *cbfunc, void *cbarg,
+ struct cam_path *path)
+{
+ struct ccb_setasync csa;
+ cam_status status;
+ int xptpath = 0;
+
+ if (path == NULL) {
+ mtx_lock(&xsoftc.xpt_lock);
+ status = xpt_create_path(&path, /*periph*/NULL, CAM_XPT_PATH_ID,
+ CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
+ if (status != CAM_REQ_CMP) {
+ mtx_unlock(&xsoftc.xpt_lock);
+ return (status);
+ }
+ xptpath = 1;
+ }
+
+ xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5);
+ csa.ccb_h.func_code = XPT_SASYNC_CB;
+ csa.event_enable = event;
+ csa.callback = cbfunc;
+ csa.callback_arg = cbarg;
+ xpt_action((union ccb *)&csa);
+ status = csa.ccb_h.status;
+ if (xptpath) {
+ xpt_free_path(path);
+ mtx_unlock(&xsoftc.xpt_lock);
+ }
+ return (status);
+}
+
static void
xptaction(struct cam_sim *sim, union ccb *work_ccb)
{
OpenPOWER on IntegriCloud