From owner-svn-src-projects@FreeBSD.ORG Sat Aug 10 19:08:39 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 8CC16AF9; Sat, 10 Aug 2013 19:08:39 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 688932B33; Sat, 10 Aug 2013 19:08:39 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r7AJ8d6p035674; Sat, 10 Aug 2013 19:08:39 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r7AJ8dSj035669; Sat, 10 Aug 2013 19:08:39 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201308101908.r7AJ8dSj035669@svn.freebsd.org> From: Alexander Motin Date: Sat, 10 Aug 2013 19:08:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r254189 - projects/camlock/sys/cam X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 10 Aug 2013 19:08:39 -0000 Author: mav Date: Sat Aug 10 19:08:38 2013 New Revision: 254189 URL: http://svnweb.freebsd.org/changeset/base/254189 Log: Queue async events via sim_doneq. That will allow to decouple event sender and receiver locks later. Modified: projects/camlock/sys/cam/cam_ccb.h projects/camlock/sys/cam/cam_xpt.c Modified: projects/camlock/sys/cam/cam_ccb.h ============================================================================== --- projects/camlock/sys/cam/cam_ccb.h Sat Aug 10 19:08:36 2013 (r254188) +++ projects/camlock/sys/cam/cam_ccb.h Sat Aug 10 19:08:38 2013 (r254189) @@ -147,6 +147,9 @@ typedef enum { /* Device statistics (error counts, etc.) */ XPT_DEV_ADVINFO = 0x0e, /* Get/Set Device advanced information */ + XPT_ASYNC = 0x0f | XPT_FC_QUEUED | XPT_FC_USER_CCB + | XPT_FC_XPT_ONLY, + /* Asynchronous event */ /* SCSI Control Functions: 0x10->0x1F */ XPT_ABORT = 0x10, /* Abort the specified CCB */ @@ -1144,6 +1147,16 @@ struct ccb_dev_advinfo { }; /* + * CCB for sending async events + */ +struct ccb_async { + struct ccb_hdr ccb_h; + uint32_t async_code; + off_t async_arg_size; + void *async_arg_ptr; +}; + +/* * Union of all CCB types for kernel space allocation. This union should * never be used for manipulating CCBs - its only use is for the allocation * and deallocation of raw CCB space and is the return type of xpt_ccb_alloc @@ -1182,6 +1195,7 @@ union ccb { struct ccb_debug cdbg; struct ccb_ataio ataio; struct ccb_dev_advinfo cdai; + struct ccb_async casync; }; __BEGIN_DECLS Modified: projects/camlock/sys/cam/cam_xpt.c ============================================================================== --- projects/camlock/sys/cam/cam_xpt.c Sat Aug 10 19:08:36 2013 (r254188) +++ projects/camlock/sys/cam/cam_xpt.c Sat Aug 10 19:08:38 2013 (r254189) @@ -3966,13 +3966,42 @@ xpt_async_string(u_int32_t async_code) return ("AC_UNKNOWN"); } -void -xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg) +static int +xpt_async_size(u_int32_t async_code) +{ + + switch (async_code) { + case AC_BUS_RESET: return (0); + case AC_UNSOL_RESEL: return (0); + case AC_SCSI_AEN: return (0); + case AC_SENT_BDR: return (0); + case AC_PATH_REGISTERED: return (sizeof(struct ccb_pathinq)); + case AC_PATH_DEREGISTERED: return (0); + case AC_FOUND_DEVICE: return (sizeof(struct ccb_getdev)); + case AC_LOST_DEVICE: return (0); + case AC_TRANSFER_NEG: return (sizeof(struct ccb_trans_settings)); + case AC_INQ_CHANGED: return (0); + case AC_GETDEV_CHANGED: return (0); + case AC_CONTRACT: return (sizeof(struct ac_contract)); + case AC_ADVINFO_CHANGED: return (-1); + case AC_UNIT_ATTENTION: return (sizeof(struct ccb_scsiio)); + } + return (0); +} + +static void +xpt_async_process(struct cam_periph *periph, union ccb *ccb) { struct cam_eb *bus; struct cam_et *target, *next_target; struct cam_ed *device, *next_device; - + struct cam_path *path; + void *async_arg; + u_int32_t async_code; + + path = ccb->ccb_h.path; + async_code = ccb->casync.async_code; + async_arg = ccb->casync.async_arg_ptr; mtx_assert(path->bus->sim->mtx, MA_OWNED); CAM_DEBUG(path, CAM_DEBUG_TRACE | CAM_DEBUG_INFO, ("xpt_async(%s)\n", xpt_async_string(async_code))); @@ -4040,6 +4069,14 @@ xpt_async(u_int32_t async_code, struct c if (bus != xpt_periph->path->bus) xpt_async_bcast(&xpt_periph->path->device->asyncs, async_code, path, async_arg); + if (path->device != NULL) + xpt_release_devq(path, 1, TRUE); + else + xpt_release_simq(path->bus->sim, TRUE); + if (ccb->casync.async_arg_size > 0) + free(async_arg, M_CAMXPT); + xpt_free_path(path); + xpt_free_ccb(ccb); } static void @@ -4066,6 +4103,51 @@ xpt_async_bcast(struct async_list *async } } +void +xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg) +{ + union ccb *ccb; + int size; + + ccb = xpt_alloc_ccb_nowait(); + if (ccb == NULL) { + xpt_print(path, "Can't allocate CCB to send %s\n", + xpt_async_string(async_code)); + return; + } + + if (xpt_clone_path(&ccb->ccb_h.path, path) != CAM_REQ_CMP) { + xpt_print(path, "Can't allocate path to send %s\n", + xpt_async_string(async_code)); + xpt_free_ccb(ccb); + return; + } + ccb->ccb_h.path->periph = NULL; + ccb->ccb_h.func_code = XPT_ASYNC; + ccb->ccb_h.cbfcnp = xpt_async_process; + ccb->casync.async_code = async_code; + ccb->casync.async_arg_size = 0; + size = xpt_async_size(async_code); + if (size > 0 && async_arg != NULL) { + ccb->casync.async_arg_ptr = malloc(size, M_CAMXPT, M_NOWAIT); + if (ccb->casync.async_arg_ptr == NULL) { + xpt_print(path, "Can't allocate argument to send %s\n", + xpt_async_string(async_code)); + xpt_free_path(ccb->ccb_h.path); + xpt_free_ccb(ccb); + return; + } + memcpy(ccb->casync.async_arg_ptr, async_arg, size); + ccb->casync.async_arg_size = size; + } else if (size < 0) + ccb->casync.async_arg_size = size; + if (path->device != NULL) + xpt_freeze_devq(path, 1); + else + xpt_freeze_simq(path->bus->sim, 1); + xpt_done(ccb); +} + static void xpt_dev_async_default(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, struct cam_ed *device,