From nobody Fri Nov 24 17:28:54 2023 X-Original-To: dev-commits-src-all@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 4ScMQv1FhRz51MQg; Fri, 24 Nov 2023 17:28:55 +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 4ScMQv0QVbz4J3G; Fri, 24 Nov 2023 17:28:55 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1700846935; 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=aLWr30l1l6AnhsSRpBwkKGh0U2M346GsFEv/roMh3fs=; b=czpN/tT/l6DFUmq3yqeIrgGpkcvJYkXWYL7YxN9dflKPpvgSFx1CdsE+FmUeNcuiZazvje 0M/8K3YFGxld2kAGgfdvod2An6ON4f0gzO0ff3L1Zjkj+ZOY6lpJbt95BIST0XpzqECSy/ F//oHK6N6yJ7/BI6zNopFH0X0GN83ir1S7VWYxJzua+DE3SzWBX8Tiq7Ce6nsmVkEpxLGn 38FLRoOqETzqO3RevHE7On51wqZEUTp9Fww+5F8uMsheWUCqLLImAmNBd0SbVj1gfEXTSD eaUVZ3elAoXesLSnS3GfpjTDzZcPsA1ImyAQL0V3aI0+Sw0G3Rs8/WbHn25Uvg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1700846935; 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=aLWr30l1l6AnhsSRpBwkKGh0U2M346GsFEv/roMh3fs=; b=XW6IRkECu7DmBGsTAHb9UxO5aSYOwzvAuZGWUhyoCYa8aXuZ1m1XgqozYs5BSOBC0GzfGC oaEgbAKNI5RVvQUyFUwc5DDSeltJcVKhgQC3/PCY3gB/dkAg26C43ci4yuY7M1hEk7PsLy CjD7LcheRnIcBNXipZbd1IjA5gzDleWL1zW9sFP3XKcRTexNnO/R+Kl7WcBko0+aY595vR Qyfea6JyQuJ00Pimknkip3NK660SkpaJebQaqP+bmgyhS2jOn+11EvluYInv+AnZ5TPuQm UDOMumUxuzs5RO4YbREkjyU7N4AsY7Fi3yqBlepinGLXaGJETggozIWI6Ss6LQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1700846935; a=rsa-sha256; cv=none; b=VjvVrooYkh+DXfim4cf25OGWyDp1CStlIHbt0pZDdduueezQxmNxCovB6BtOP7YcEvm10S Vl9jMavRhnHA2F1dmb9yPlk4GYn47Q/cUPhUguOuPLkEpOXgA8XoFuXCotsUotjouYuy2n YhD5FubOTka3JymVw9c8BRvbqQzInz0vw/tU/ZLxA7IOT2IB14F3dtHUMXvkcpzUdteTiq kUsE4axt5F03TW71OqwcJSRqH/ncxE6qTm9DJVRaee4YPYJZAKwAy0Pwnbz4vj0QEGoKy6 JscLMGT06xhQTCqsEwYYKrTuEIVmtC2LzjnrpKiTjyTwPAJfrxsBWhRDbCshAw== 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 4ScMQt6bQwztZS; Fri, 24 Nov 2023 17:28:54 +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 3AOHSsD3051627; Fri, 24 Nov 2023 17:28:54 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3AOHSsou051624; Fri, 24 Nov 2023 17:28:54 GMT (envelope-from git) Date: Fri, 24 Nov 2023 17:28:54 GMT Message-Id: <202311241728.3AOHSsou051624@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: John Baldwin Subject: git: 751615c53844 - main - newbus: Add a set of bus resource helpers for nexus-like devices List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@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/main X-Git-Reftype: branch X-Git-Commit: 751615c538446ea0384f8faa9cb2508670c3799a Auto-Submitted: auto-generated The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=751615c538446ea0384f8faa9cb2508670c3799a commit 751615c538446ea0384f8faa9cb2508670c3799a Author: John Baldwin AuthorDate: 2023-11-24 17:28:00 +0000 Commit: John Baldwin CommitDate: 2023-11-24 17:28:00 +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 --- 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 80fe182eab56..9e191f4c3a4f 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);