From nobody Wed Jan 03 22:02:43 2024 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4T53cM3gMRz56nZV; Wed, 3 Jan 2024 22:02:43 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4T53cM3DNyz4YBb; Wed, 3 Jan 2024 22:02:43 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704319363; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=S6HvQ6ipebvCZKeRoSD9SOUytRYHnGjqe2EJ7mb7FWk=; b=J9tj1Oq4WjOuZi4/tL/YBBd2/Ppd4kGxEndTbCXb226RS9+HtD8J21GZOzMBMcyXeSCBnR 3p+f3N4ptvIHJz1hxppMBCO0o+SZVpJEyS1IYbPbfRrmPWPMhezmFFKvcDhtU/oWmKNGfV qDX3XxnH4BbswIhaHYCsKFv7cxWMlLi1q0jUqFUUrrMp2iY+1YgOySrheKVzc/Vh+hjhH6 J3+KEz+BPgSUgBGuJRT2wcdUukaq6vu53szX3yorvMoXvGu/CJZRvGG4Pd0xjPy3+VZQ5J xhKkl9q8bfGu8mrJ7h3oQoJqfUUinVvqs+Uk6WRLmPQX+WSlo7mGdK9ykW/oHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704319363; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=S6HvQ6ipebvCZKeRoSD9SOUytRYHnGjqe2EJ7mb7FWk=; b=uE+2Vi3jPSKggha6/s+KFZeXVCqScxBYPYy/TSExs+LMyHVsWHbyN1YUHNlzz/BIVjzyjN fzP/QFdvUwp2MxfQ4XywAByXxpROn2h5nehlcXd68yGzJx8VLVh4idJF/293hv6JS/bto+ h0V8HwFy9NzxcL9zA1cuGfTE0aJX29qGPnBHfE8GandqUY+dCj1pYyenlqb39tGzi3DlTj G+UxxJ11vCCDP99Bk6x4y9ViNzmdFr/NCGs9bkx9bBou1SWaOs2h2eO1yDuNC5rrTp8TzI 5Kq6Y6eQnQdQ9Er5dud5+7C2aDcS8B40rWrtNWPRhTryNaqfmyDa07GbZZ3MUw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1704319363; a=rsa-sha256; cv=none; b=QItlX9z9NhWrROxart/ZIDXYEFRE1e5DWDGZakcKuEmS11z6txywR8UWiwMFoaqmh0O4MM XF3PRyhBAU85KOehGLk+WEbEAx2xpfQ8+v9V59vV364Gjfc0UE24ZAnixbgMLDaOavMBTW Zc0+yZ4LymSFIDi3hdRSMGvn6TWgmN5Rn77en3NIqqoN3yex+yX+6u5uyOpanYz6SKCv91 7Ww77Od+9Vitkl1/62iludWaYwzeXiVOXGlqyNRUOmdh1Tv5+5DCkZMN/P/4kcu7uT2zVe U45p4E0hh+bDUNf/4Oc+uQRcQbOwMhBwobO+ivYKVnozCO44NNdIRlkNbX/ymw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4T53cM2Hbgz1370; Wed, 3 Jan 2024 22:02:43 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 403M2h05072539; Wed, 3 Jan 2024 22:02:43 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 403M2h8j072536; Wed, 3 Jan 2024 22:02:43 GMT (envelope-from git) Date: Wed, 3 Jan 2024 22:02:43 GMT Message-Id: <202401032202.403M2h8j072536@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: John Baldwin Subject: git: 0962b9d08676 - stable/14 - newbus: Add a set of bus resource helpers for nexus-like devices List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhb X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 0962b9d0867602eed41361f1982ce8f6b967064b Auto-Submitted: auto-generated The branch stable/14 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=0962b9d0867602eed41361f1982ce8f6b967064b commit 0962b9d0867602eed41361f1982ce8f6b967064b Author: John Baldwin AuthorDate: 2023-11-24 17:28:00 +0000 Commit: John Baldwin CommitDate: 2024-01-03 20:47:08 +0000 newbus: Add a set of bus resource helpers for nexus-like devices These routines can be used to implement bus_alloc/adjust/activate/deactive/release_resource on bus drivers which suballocate resources from rman(9) resource managers. These methods require a new bus_get_rman method in the bus driver to return the suitable rman for a given resource type. The activate/deactivate helpers also require the bus to implement the bus_map/ummap_resource methods. Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D42739 (cherry picked from commit 751615c538446ea0384f8faa9cb2508670c3799a) --- sys/kern/bus_if.m | 24 ++++++++ sys/kern/subr_bus.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++ sys/sys/bus.h | 17 ++++++ 3 files changed, 198 insertions(+) diff --git a/sys/kern/bus_if.m b/sys/kern/bus_if.m index 7bd08fb713f8..7078683911b8 100644 --- a/sys/kern/bus_if.m +++ b/sys/kern/bus_if.m @@ -77,6 +77,12 @@ CODE { { return (0); } + + static struct rman * + null_get_rman(device_t bus, int type, u_int flags) + { + return (NULL); + } }; /** @@ -622,6 +628,24 @@ METHOD struct resource_list * get_resource_list { device_t _child; } DEFAULT bus_generic_get_resource_list; +/** + * @brief Return a struct rman. + * + * Used by drivers which use bus_generic_rman_alloc_resource() etc. to + * implement their resource handling. It should return the resource + * manager used for the given resource type. + * + * @param _dev the bus device + * @param _type the resource type + * @param _flags resource flags (@c RF_XXX flags in + * ) + */ +METHOD struct rman * get_rman { + device_t _dev; + int _type; + u_int _flags; +} DEFAULT null_get_rman; + /** * @brief Is the hardware described by @p _child still attached to the * system? diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 571e90b52dfc..4c44c264a5c0 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -4189,6 +4189,163 @@ bus_generic_rl_alloc_resource(device_t dev, device_t child, int type, start, end, count, flags)); } +/** + * @brief Helper function for implementing BUS_ALLOC_RESOURCE(). + * + * This implementation of BUS_ALLOC_RESOURCE() allocates a + * resource from a resource manager. It uses BUS_GET_RMAN() + * to obtain the resource manager. + */ +struct resource * +bus_generic_rman_alloc_resource(device_t dev, device_t child, int type, + int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) +{ + struct resource *r; + struct rman *rm; + + rm = BUS_GET_RMAN(dev, type, flags); + if (rm == NULL) + return (NULL); + + r = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, + child); + if (r == NULL) + return (NULL); + rman_set_rid(r, *rid); + + if (flags & RF_ACTIVE) { + if (bus_activate_resource(child, type, *rid, r) != 0) { + rman_release_resource(r); + return (NULL); + } + } + + return (r); +} + +/** + * @brief Helper function for implementing BUS_ADJUST_RESOURCE(). + * + * This implementation of BUS_ADJUST_RESOURCE() adjusts resources only + * if they were allocated from the resource manager returned by + * BUS_GET_RMAN(). + */ +int +bus_generic_rman_adjust_resource(device_t dev, device_t child, int type, + struct resource *r, rman_res_t start, rman_res_t end) +{ + struct rman *rm; + + rm = BUS_GET_RMAN(dev, type, rman_get_flags(r)); + if (rm == NULL) + return (ENXIO); + if (!rman_is_region_manager(r, rm)) + return (EINVAL); + return (rman_adjust_resource(r, start, end)); +} + +/** + * @brief Helper function for implementing BUS_RELEASE_RESOURCE(). + * + * This implementation of BUS_RELEASE_RESOURCE() releases resources + * allocated by bus_generic_rman_alloc_resource. + */ +int +bus_generic_rman_release_resource(device_t dev, device_t child, int type, + int rid, struct resource *r) +{ +#ifdef INVARIANTS + struct rman *rm; +#endif + int error; + +#ifdef INVARIANTS + rm = BUS_GET_RMAN(dev, type, rman_get_flags(r)); + KASSERT(rman_is_region_manager(r, rm), + ("%s: rman %p doesn't match for resource %p", __func__, rm, r)); +#endif + + if (rman_get_flags(r) & RF_ACTIVE) { + error = bus_deactivate_resource(child, type, rid, r); + if (error != 0) + return (error); + } + return (rman_release_resource(r)); +} + +/** + * @brief Helper function for implementing BUS_ACTIVATE_RESOURCE(). + * + * This implementation of BUS_ACTIVATE_RESOURCE() activates resources + * allocated by bus_generic_rman_alloc_resource. + */ +int +bus_generic_rman_activate_resource(device_t dev, device_t child, int type, + int rid, struct resource *r) +{ + struct resource_map map; +#ifdef INVARIANTS + struct rman *rm; +#endif + int error; + +#ifdef INVARIANTS + rm = BUS_GET_RMAN(dev, type, rman_get_flags(r)); + KASSERT(rman_is_region_manager(r, rm), + ("%s: rman %p doesn't match for resource %p", __func__, rm, r)); +#endif + + error = rman_activate_resource(r); + if (error != 0) + return (error); + + if ((rman_get_flags(r) & RF_UNMAPPED) == 0 && + (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT)) { + error = BUS_MAP_RESOURCE(dev, child, type, r, NULL, &map); + if (error != 0) { + rman_deactivate_resource(r); + return (error); + } + + rman_set_mapping(r, &map); + } + return (0); +} + +/** + * @brief Helper function for implementing BUS_DEACTIVATE_RESOURCE(). + * + * This implementation of BUS_DEACTIVATE_RESOURCE() deactivates + * resources allocated by bus_generic_rman_alloc_resource. + */ +int +bus_generic_rman_deactivate_resource(device_t dev, device_t child, int type, + int rid, struct resource *r) +{ + struct resource_map map; +#ifdef INVARIANTS + struct rman *rm; +#endif + int error; + +#ifdef INVARIANTS + rm = BUS_GET_RMAN(dev, type, rman_get_flags(r)); + KASSERT(rman_is_region_manager(r, rm), + ("%s: rman %p doesn't match for resource %p", __func__, rm, r)); +#endif + + error = rman_deactivate_resource(r); + if (error != 0) + return (error); + + if ((rman_get_flags(r) & RF_UNMAPPED) == 0 && + (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT)) { + rman_get_mapping(r, &map); + BUS_UNMAP_RESOURCE(dev, child, type, r, &map); + } + return (0); +} + /** * @brief Helper function for implementing BUS_CHILD_PRESENT(). * diff --git a/sys/sys/bus.h b/sys/sys/bus.h index 88ae4000004b..2ec735659452 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -499,6 +499,23 @@ int bus_generic_rl_set_resource (device_t, device_t, int, int, rman_res_t, rman_res_t); int bus_generic_rl_release_resource (device_t, device_t, int, int, struct resource *); +struct resource * + bus_generic_rman_alloc_resource(device_t dev, device_t child, int type, + int *rid, rman_res_t start, + rman_res_t end, rman_res_t count, + u_int flags); +int bus_generic_rman_adjust_resource(device_t dev, device_t child, int type, + struct resource *r, rman_res_t start, + rman_res_t end); +int bus_generic_rman_release_resource(device_t dev, device_t child, + int type, int rid, + struct resource *r); +int bus_generic_rman_activate_resource(device_t dev, device_t child, + int type, int rid, + struct resource *r); +int bus_generic_rman_deactivate_resource(device_t dev, device_t child, + int type, int rid, + struct resource *r); int bus_generic_shutdown(device_t dev); int bus_generic_suspend(device_t dev);