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