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