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