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 April 29, 2011 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_TIMESHARE 0x0008 /* resource permits time-division sharing */ 145#define RF_WANTED 0x0010 /* somebody is waiting for this resource */ 146#define RF_FIRSTSHARE 0x0020 /* first in sharing list */ 147#define RF_PREFETCHABLE 0x0040 /* resource is prefetchable */ 148.Ed 149.Pp 150The remainder of the flag bits 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_bound 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, 276as well as a boundary restriction and required aligment, 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 aligment requirement 290.Pq if any 291is specified in 292.Fa flags . 293The 294.Fa bound 295argument may be set to specify a boundary restriction such that an 296allocated region may cross an address that is a multiple of the 297boundary. 298The 299.Fa bound 300argument must be a power of two. 301It may be set to zero to specify no boundary restriction. 302The default behavior is to allocate an exclusive segment, unless the 303.Dv RF_SHAREABLE 304or 305.Dv RF_TIMESHARE 306flags are set, in which case a shared 307segment will be allocated. 308If this shared segment already exists, the caller has its device 309added to the list of consumers. 310.Pp 311The 312.Fn rman_reserve_resource 313function is used to reserve resources within a previously established region. 314It is a simplified interface to 315.Fn rman_reserve_resource_bound 316which passes 0 for the 317.Fa bound 318argument. 319.Pp 320The 321.Fn rman_make_alignment_flags 322function returns the flag mask corresponding to the desired alignment 323.Fa size . 324This should be used when calling 325.Fn rman_reserve_resource_bound . 326.Pp 327The 328.Fn rman_is_region_manager 329function returns true if the allocated resource 330.Fa r 331was allocated from 332.Fa rm . 333Otherwise, 334it returns false. 335.Pp 336The 337.Fn rman_adjust_resource 338function is used to adjust the reserved address range of an allocated resource 339to reserve 340.Fa start 341through 342.Fa end . 343It can be used to grow or shrink one or both ends of the resource range. 344The current implementation does not support entirely relocating the resource 345and will fail with 346.Er EINVAL 347if the new resource range does not overlap the old resource range. 348If either end of the resource range grows and the new resource range would 349conflict with another allocated resource, 350the function will fail with 351.Er EBUSY . 352The 353.Fn rman_adjust_resource 354function does not support adjusting the resource range for shared resources 355and will fail such attempts with 356.Er EINVAL . 357Upon success, 358the resource 359.Fa r 360will have a start address of 361.Fa start 362and an end address of 363.Fa end 364and the function will return zero. 365Note that none of the constraints of the original allocation request such 366as alignment or boundary restrictions are checked by 367.Fn rman_adjust_resource . 368It is the caller's responsibility to enforce any such requirements. 369.Pp 370The 371.Fn rman_release_resource 372function releases the reserved resource 373.Fa r . 374It may attempt to merge adjacent free resources. 375.Pp 376The 377.Fn rman_activate_resource 378function marks a resource as active, by setting the 379.Dv RF_ACTIVE 380flag. 381If this is a time shared resource, and the caller has not yet acquired 382the resource, the function returns 383.Er EBUSY . 384.Pp 385The 386.Fn rman_deactivate_resource 387function marks a resource 388.Fa r 389as inactive, by clearing the 390.Dv RF_ACTIVE 391flag. 392If other consumers are waiting for this range, it will wakeup their threads. 393.Pp 394The 395.Fn rman_await_resource 396function performs an asynchronous wait for a resource 397.Fa r 398to become inactive, that is, for the 399.Dv RF_ACTIVE 400flag to be cleared. 401It is used to enable cooperative sharing of a resource 402which can only be safely used by one thread at a time. 403The arguments 404.Fa pri 405and 406.Fa timo 407are passed to the 408.Fn rman_await_resource 409function. 410.Pp 411The 412.Fn rman_get_start , 413.Fn rman_get_end , 414.Fn rman_get_size , 415and 416.Fn rman_get_flags 417functions return the bounds, size and flags of the previously reserved 418resource 419.Fa r . 420.Pp 421The 422.Fn rman_set_bustag 423function associates a 424.Vt bus_space_tag_t 425.Fa t 426with the resource 427.Fa r . 428The 429.Fn rman_get_bustag 430function is used to retrieve this tag once set. 431.Pp 432The 433.Fn rman_set_bushandle 434function associates a 435.Vt bus_space_handle_t 436.Fa h 437with the resource 438.Fa r . 439The 440.Fn rman_get_bushandle 441function is used to retrieve this handle once set. 442.Pp 443The 444.Fn rman_set_virtual 445function is used to associate a kernel virtual address with a resource 446.Fa r . 447The 448.Fn rman_get_virtual 449function can be used to retrieve the KVA once set. 450.Pp 451The 452.Fn rman_set_rid 453function associates a resource identifier with a resource 454.Fa r . 455The 456.Fn rman_get_rid 457function retrieves this RID. 458.Pp 459The 460.Fn rman_get_device 461function returns a pointer to the device which reserved the resource 462.Fa r . 463.Sh SEE ALSO 464.Xr bus_activate_resource 9 , 465.Xr bus_alloc_resource 9 , 466.Xr bus_release_resource 9 , 467.Xr bus_set_resource 9 , 468.Xr mutex 9 469.Sh AUTHORS 470This manual page was written by 471.An Bruce M Simpson Aq bms@spc.org . 472