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