1.\" 2.\" Copyright (c) 2003 Bruce M Simpson <bms@spc.org> 3.\" All rights reserved. 4.\" 5.\" Redistribution and use in source and binary forms, with or without 6.\" modification, are permitted provided that the following conditions 7.\" are met: 8.\" 1. Redistributions of source code must retain the above copyright 9.\" notice, this list of conditions and the following disclaimer. 10.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" notice, this list of conditions and the following disclaimer in the 12.\" documentation and/or other materials provided with the distribution. 13.\" 14.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24.\" SUCH DAMAGE. 25.\" 26.Dd March 13, 2024 27.Dt RMAN 9 28.Os 29.Sh NAME 30.Nm rman , 31.Nm rman_activate_resource , 32.Nm rman_adjust_resource , 33.Nm rman_deactivate_resource , 34.Nm rman_fini , 35.Nm rman_init , 36.Nm rman_init_from_resource , 37.Nm rman_is_region_manager , 38.Nm rman_manage_region , 39.Nm rman_first_free_region , 40.Nm rman_last_free_region , 41.Nm rman_release_resource , 42.Nm rman_reserve_resource , 43.Nm rman_reserve_resource_bound , 44.Nm rman_make_alignment_flags , 45.Nm rman_get_start , 46.Nm rman_get_end , 47.Nm rman_get_device , 48.Nm rman_get_size , 49.Nm rman_get_flags , 50.Nm rman_set_mapping , 51.Nm rman_get_mapping , 52.Nm rman_set_virtual , 53.Nm rman_get_virtual , 54.Nm rman_set_bustag , 55.Nm rman_get_bustag , 56.Nm rman_set_bushandle , 57.Nm rman_get_bushandle , 58.Nm rman_set_rid , 59.Nm rman_get_rid , 60.Nm rman_set_type , 61.Nm rman_get_type 62.Nd resource management functions 63.Sh SYNOPSIS 64.In sys/types.h 65.In sys/rman.h 66.Ft int 67.Fn rman_activate_resource "struct resource *r" 68.Ft int 69.Fn rman_adjust_resource "struct resource *r" "rman_res_t start" "rman_res_t end" 70.Ft int 71.Fn rman_deactivate_resource "struct resource *r" 72.Ft int 73.Fn rman_fini "struct rman *rm" 74.Ft int 75.Fn rman_init "struct rman *rm" 76.Ft int 77.Fn rman_init_from_resource "struct rman *rm" "struct resource *r" 78.Ft int 79.Fn rman_is_region_manager "struct resource *r" "struct rman *rm" 80.Ft int 81.Fn rman_manage_region "struct rman *rm" "rman_res_t start" "rman_res_t end" 82.Ft int 83.Fn rman_first_free_region "struct rman *rm" "rman_res_t *start" "rman_res_t *end" 84.Ft int 85.Fn rman_last_free_region "struct rman *rm" "rman_res_t *start" "rman_res_t *end" 86.Ft int 87.Fn rman_release_resource "struct resource *r" 88.Ft "struct resource *" 89.Fo rman_reserve_resource 90.Fa "struct rman *rm" "rman_res_t start" "rman_res_t end" "rman_res_t count" 91.Fa "u_int flags" "device_t dev" 92.Fc 93.Ft "struct resource *" 94.Fo rman_reserve_resource_bound 95.Fa "struct rman *rm" "rman_res_t start" "rman_res_t end" "rman_res_t count" 96.Fa "rman_res_t bound" "u_int flags" "device_t dev" 97.Fc 98.Ft uint32_t 99.Fn rman_make_alignment_flags "uint32_t size" 100.Ft rman_res_t 101.Fn rman_get_start "struct resource *r" 102.Ft rman_res_t 103.Fn rman_get_end "struct resource *r" 104.Ft "device_t" 105.Fn rman_get_device "struct resource *r" 106.Ft rman_res_t 107.Fn rman_get_size "struct resource *r" 108.Ft u_int 109.Fn rman_get_flags "struct resource *r" 110.Ft void 111.Fn rman_set_mapping "struct resource *r" "struct resource_map *map" 112.Ft void 113.Fn rman_get_mapping "struct resource *r" "struct resource_map *map" 114.Ft void 115.Fn rman_set_virtual "struct resource *r" "void *v" 116.Ft "void *" 117.Fn rman_get_virtual "struct resource *r" 118.Ft void 119.Fn rman_set_bustag "struct resource *r" "bus_space_tag_t t" 120.Ft bus_space_tag_t 121.Fn rman_get_bustag "struct resource *r" 122.Ft void 123.Fn rman_set_bushandle "struct resource *r" "bus_space_handle_t h" 124.Ft bus_space_handle_t 125.Fn rman_get_bushandle "struct resource *r" 126.Ft void 127.Fn rman_set_rid "struct resource *r" "int rid" 128.Ft int 129.Fn rman_get_rid "struct resource *r" 130.Ft void 131.Fn rman_set_type "struct resource *r" "int type" 132.Ft int 133.Fn rman_get_type "struct resource *r" 134.Sh DESCRIPTION 135The 136.Nm 137set of functions provides a flexible resource management abstraction. 138It is used extensively by the bus management code. 139It implements the abstractions of region and resource. 140A region descriptor is used to manage a region; this could be memory or 141some other form of bus space. 142.Pp 143Each region has a set of bounds. 144Within these bounds, allocated segments may reside. 145Each segment, termed a resource, has several properties which are 146represented by a 16-bit flag register, as follows. 147.Bd -literal 148#define RF_ALLOCATED 0x0001 /* resource has been reserved */ 149#define RF_ACTIVE 0x0002 /* resource allocation has been activated */ 150#define RF_SHAREABLE 0x0004 /* resource permits contemporaneous sharing */ 151#define RF_FIRSTSHARE 0x0020 /* first in sharing list */ 152#define RF_PREFETCHABLE 0x0040 /* resource is prefetchable */ 153#define RF_UNMAPPED 0x0100 /* don't map resource when activating */ 154.Ed 155.Pp 156Bits 15:10 of the flag register are used to represent the desired alignment 157of the resource within the region. 158.Pp 159The 160.Fn rman_init 161function initializes the region descriptor, pointed to by the 162.Fa rm 163argument, for use with the resource management functions. 164It is required that the fields 165.Va rm_type 166and 167.Va rm_descr 168of 169.Vt "struct rman" 170be set before calling 171.Fn rman_init . 172The field 173.Va rm_type 174shall be set to 175.Dv RMAN_ARRAY . 176The field 177.Va rm_descr 178shall be set to a string that describes the resource to be managed. 179The 180.Va rm_start 181and 182.Va rm_end 183fields may be set to limit the range of acceptable resource addresses. 184If these fields are not set, 185.Fn rman_init 186will initialize them to allow the entire range of resource addresses. 187It also initializes any mutexes associated with the structure. 188If 189.Fn rman_init 190fails to initialize the mutex, it will return 191.Er ENOMEM ; otherwise it will return 0 and 192.Fa rm 193will be initialized. 194.Pp 195The 196.Fn rman_fini 197function frees any structures associated with the structure 198pointed to by the 199.Fa rm 200argument. 201If any of the resources within the managed region have the 202.Dv RF_ALLOCATED 203flag set, it will return 204.Er EBUSY ; 205otherwise, any mutexes associated with the structure will be released 206and destroyed, and the function will return 0. 207.Pp 208The 209.Fn rman_manage_region 210function establishes the concept of a region which is under 211.Nm 212control. 213The 214.Fa rman 215argument points to the region descriptor. 216The 217.Fa start 218and 219.Fa end 220arguments specify the bounds of the region. 221If successful, 222.Fn rman_manage_region 223will return 0. 224If the region overlaps with an existing region, it will return 225.Er EBUSY . 226If any part of the region falls outside of the valid address range for 227.Fa rm , 228it will return 229.Er EINVAL . 230.Er ENOMEM 231will be returned when 232.Fn rman_manage_region 233failed to allocate memory for the region. 234.Pp 235The 236.Fn rman_init_from_resource 237function is a wrapper routine to create a resource manager backed by an 238existing resource. 239It initializes 240.Fa rm 241using 242.Fn rman_init 243and then adds a region to 244.Fa rm 245corresponding to the address range allocated to 246.Fa r 247via 248.Fn rman_manage_region . 249.Pp 250The 251.Fn rman_first_free_region 252and 253.Fn rman_last_free_region 254functions can be used to query a resource manager for its first 255.Pq or last 256unallocated region. 257If 258.Fa rm 259contains no free region, 260these functions will return 261.Er ENOENT . 262Otherwise, 263.Fa *start 264and 265.Fa *end 266are set to the bounds of the free region and zero is returned. 267.Pp 268The 269.Fn rman_reserve_resource_bound 270function is where the bulk of the 271.Nm 272logic is located. 273It attempts to reserve a contiguous range in the specified region 274.Fa rm 275for the use of the device 276.Fa dev . 277The caller can specify the 278.Fa start 279and 280.Fa end 281of an acceptable range, 282as well as a boundary restriction and required alignment, 283and the code will attempt to find a free segment which fits. 284The 285.Fa start 286argument is the lowest acceptable starting value of the resource. 287The 288.Fa end 289argument is the highest acceptable ending value of the resource. 290Therefore, 291.Fa start No + Fa count No \- 1 292must be \[<=] 293.Fa end 294for any allocation to happen. 295The alignment requirement 296.Pq if any 297is specified in 298.Fa flags . 299The 300.Fa bound 301argument may be set to specify a boundary restriction such that an 302allocated region may cross an address that is a multiple of the 303boundary. 304The 305.Fa bound 306argument must be a power of two. 307It may be set to zero to specify no boundary restriction. 308A shared segment will be allocated if the 309.Dv RF_SHAREABLE 310flag is set, otherwise an exclusive segment will be allocated. 311If this shared segment already exists, the caller has its device 312added to the list of consumers. 313.Pp 314The 315.Fn rman_reserve_resource 316function is used to reserve resources within a previously established region. 317It is a simplified interface to 318.Fn rman_reserve_resource_bound 319which passes 0 for the 320.Fa bound 321argument. 322.Pp 323The 324.Fn rman_make_alignment_flags 325function returns the flag mask corresponding to the desired alignment 326.Fa size . 327This should be used when calling 328.Fn rman_reserve_resource_bound . 329.Pp 330The 331.Fn rman_is_region_manager 332function returns true if the allocated resource 333.Fa r 334was allocated from 335.Fa rm . 336Otherwise, 337it returns false. 338.Pp 339The 340.Fn rman_adjust_resource 341function is used to adjust the reserved address range of an allocated resource 342to reserve 343.Fa start 344through 345.Fa end . 346It can be used to grow or shrink one or both ends of the resource range. 347The current implementation does not support entirely relocating the resource 348and will fail with 349.Er EINVAL 350if the new resource range does not overlap the old resource range. 351If either end of the resource range grows and the new resource range would 352conflict with another allocated resource, 353the function will fail with 354.Er EBUSY . 355The 356.Fn rman_adjust_resource 357function does not support adjusting the resource range for shared resources 358and will fail such attempts with 359.Er EINVAL . 360Upon success, 361the resource 362.Fa r 363will have a start address of 364.Fa start 365and an end address of 366.Fa end 367and the function will return zero. 368Note that none of the constraints of the original allocation request such 369as alignment or boundary restrictions are checked by 370.Fn rman_adjust_resource . 371It is the caller's responsibility to enforce any such requirements. 372.Pp 373The 374.Fn rman_release_resource 375function releases the reserved resource 376.Fa r . 377It may attempt to merge adjacent free resources. 378.Pp 379The 380.Fn rman_activate_resource 381function marks a resource as active, by setting the 382.Dv RF_ACTIVE 383flag. 384If this is a time shared resource, and the caller has not yet acquired 385the resource, the function returns 386.Er EBUSY . 387.Pp 388The 389.Fn rman_deactivate_resource 390function marks a resource 391.Fa r 392as inactive, by clearing the 393.Dv RF_ACTIVE 394flag. 395If other consumers are waiting for this range, it will wakeup their threads. 396.Pp 397The 398.Fn rman_get_start , 399.Fn rman_get_end , 400.Fn rman_get_size , 401and 402.Fn rman_get_flags 403functions return the bounds, size and flags of the previously reserved 404resource 405.Fa r . 406.Pp 407The 408.Fn rman_set_bustag 409function associates a 410.Vt bus_space_tag_t 411.Fa t 412with the resource 413.Fa r . 414The 415.Fn rman_get_bustag 416function is used to retrieve this tag once set. 417.Pp 418The 419.Fn rman_set_bushandle 420function associates a 421.Vt bus_space_handle_t 422.Fa h 423with the resource 424.Fa r . 425The 426.Fn rman_get_bushandle 427function is used to retrieve this handle once set. 428.Pp 429The 430.Fn rman_set_virtual 431function is used to associate a kernel virtual address with a resource 432.Fa r . 433The 434.Fn rman_get_virtual 435function can be used to retrieve the KVA once set. 436.Pp 437The 438.Fn rman_set_mapping 439function is used to associate a resource mapping with a resource 440.Fa r . 441The mapping must cover the entire resource. 442Setting a mapping sets the associated 443.Xr bus_space 9 444handle and tag for 445.Fa r 446as well as the kernel virtual address if the mapping contains one. 447These individual values can be retrieved via 448.Fn rman_get_bushandle , 449.Fn rman_get_bustag , 450and 451.Fn rman_get_virtual . 452.Pp 453The 454.Fn rman_get_mapping 455function can be used to retrieve the associated resource mapping once set. 456.Pp 457The 458.Fn rman_set_rid 459function associates a resource identifier with a resource 460.Fa r . 461The 462.Fn rman_get_rid 463function retrieves this RID. 464.Pp 465The 466.Fn rman_set_type 467function associates a resource type with a resource 468.Fa r . 469The 470.Fn rman_get_type 471function retrieves this type. 472.Pp 473The 474.Fn rman_get_device 475function returns a pointer to the device which reserved the resource 476.Fa r . 477.Sh SEE ALSO 478.Xr bus_activate_resource 9 , 479.Xr bus_adjust_resource 9 , 480.Xr bus_alloc_resource 9 , 481.Xr bus_map_resource 9 , 482.Xr bus_release_resource 9 , 483.Xr bus_set_resource 9 , 484.Xr bus_space 9 , 485.Xr mutex 9 486.Sh AUTHORS 487This manual page was written by 488.An Bruce M Simpson Aq Mt bms@spc.org . 489