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 May 20, 2016 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_reserve_resource_bound , 44.Nm rman_make_alignment_flags , 45.Nm rman_get_start , 46.Nm rman_get_end , 47.Nm rman_get_device , 48.Nm rman_get_size , 49.Nm rman_get_flags , 50.Nm rman_set_mapping , 51.Nm rman_get_mapping , 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" "device_t 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" "device_t 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 "device_t" 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_mapping "struct resource *r" "struct resource_map *map" 110.Ft void 111.Fn rman_get_mapping "struct resource *r" "struct resource_map *map" 112.Ft void 113.Fn rman_set_virtual "struct resource *r" "void *v" 114.Ft "void *" 115.Fn rman_get_virtual "struct resource *r" 116.Ft void 117.Fn rman_set_bustag "struct resource *r" "bus_space_tag_t t" 118.Ft bus_space_tag_t 119.Fn rman_get_bustag "struct resource *r" 120.Ft void 121.Fn rman_set_bushandle "struct resource *r" "bus_space_handle_t h" 122.Ft bus_space_handle_t 123.Fn rman_get_bushandle "struct resource *r" 124.Ft void 125.Fn rman_set_rid "struct resource *r" "int rid" 126.Ft int 127.Fn rman_get_rid "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_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 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 . 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. 302A shared segment will be allocated if the 303.Dv RF_SHAREABLE 304flag is set, otherwise an exclusive segment will be allocated. 305If this shared segment already exists, the caller has its device 306added to the list of consumers. 307.Pp 308The 309.Fn rman_reserve_resource 310function is used to reserve resources within a previously established region. 311It is a simplified interface to 312.Fn rman_reserve_resource_bound 313which passes 0 for the 314.Fa bound 315argument. 316.Pp 317The 318.Fn rman_make_alignment_flags 319function returns the flag mask corresponding to the desired alignment 320.Fa size . 321This should be used when calling 322.Fn rman_reserve_resource_bound . 323.Pp 324The 325.Fn rman_is_region_manager 326function returns true if the allocated resource 327.Fa r 328was allocated from 329.Fa rm . 330Otherwise, 331it returns false. 332.Pp 333The 334.Fn rman_adjust_resource 335function is used to adjust the reserved address range of an allocated resource 336to reserve 337.Fa start 338through 339.Fa end . 340It can be used to grow or shrink one or both ends of the resource range. 341The current implementation does not support entirely relocating the resource 342and will fail with 343.Er EINVAL 344if the new resource range does not overlap the old resource range. 345If either end of the resource range grows and the new resource range would 346conflict with another allocated resource, 347the function will fail with 348.Er EBUSY . 349The 350.Fn rman_adjust_resource 351function does not support adjusting the resource range for shared resources 352and will fail such attempts with 353.Er EINVAL . 354Upon success, 355the resource 356.Fa r 357will have a start address of 358.Fa start 359and an end address of 360.Fa end 361and the function will return zero. 362Note that none of the constraints of the original allocation request such 363as alignment or boundary restrictions are checked by 364.Fn rman_adjust_resource . 365It is the caller's responsibility to enforce any such requirements. 366.Pp 367The 368.Fn rman_release_resource 369function releases the reserved resource 370.Fa r . 371It may attempt to merge adjacent free resources. 372.Pp 373The 374.Fn rman_activate_resource 375function marks a resource as active, by setting the 376.Dv RF_ACTIVE 377flag. 378If this is a time shared resource, and the caller has not yet acquired 379the resource, the function returns 380.Er EBUSY . 381.Pp 382The 383.Fn rman_deactivate_resource 384function marks a resource 385.Fa r 386as inactive, by clearing the 387.Dv RF_ACTIVE 388flag. 389If other consumers are waiting for this range, it will wakeup their threads. 390.Pp 391The 392.Fn rman_get_start , 393.Fn rman_get_end , 394.Fn rman_get_size , 395and 396.Fn rman_get_flags 397functions return the bounds, size and flags of the previously reserved 398resource 399.Fa r . 400.Pp 401The 402.Fn rman_set_bustag 403function associates a 404.Vt bus_space_tag_t 405.Fa t 406with the resource 407.Fa r . 408The 409.Fn rman_get_bustag 410function is used to retrieve this tag once set. 411.Pp 412The 413.Fn rman_set_bushandle 414function associates a 415.Vt bus_space_handle_t 416.Fa h 417with the resource 418.Fa r . 419The 420.Fn rman_get_bushandle 421function is used to retrieve this handle once set. 422.Pp 423The 424.Fn rman_set_virtual 425function is used to associate a kernel virtual address with a resource 426.Fa r . 427The 428.Fn rman_get_virtual 429function can be used to retrieve the KVA once set. 430.Pp 431The 432.Fn rman_set_mapping 433function is used to associate a resource mapping with a resource 434.Fa r . 435The mapping must cover the entire resource. 436Setting a mapping sets the associated 437.Xr bus_space 9 438handle and tag for 439.Fa r 440as well as the kernel virtual address if the mapping contains one. 441These individual values can be retrieved via 442.Fn rman_get_bushandle , 443.Fn rman_get_bustag , 444and 445.Fn rman_get_virtual . 446.Pp 447The 448.Fn rman_get_mapping 449function can be used to retrieve the associated resource mapping 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_adjust_resource 9 , 466.Xr bus_alloc_resource 9 , 467.Xr bus_map_resource 9 , 468.Xr bus_release_resource 9 , 469.Xr bus_set_resource 9 , 470.Xr bus_space 9 , 471.Xr mutex 9 472.Sh AUTHORS 473This manual page was written by 474.An Bruce M Simpson Aq Mt bms@spc.org . 475