diff options
author | scottl <scottl@FreeBSD.org> | 2007-05-16 16:54:23 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2007-05-16 16:54:23 +0000 |
commit | 74448961ec9a8ecb496066cacac4aee33258b2b0 (patch) | |
tree | eb4208c40ec28ee618733168a87c1e69768e1c1a /sys/cam/cam_xpt.c | |
parent | 04e8b672c852d872cc214c6745d7cddca1d5080c (diff) | |
download | FreeBSD-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.c | 33 |
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) { |