xref: /freebsd/share/man/man9/rman.9 (revision e0c4386e7e71d93b0edc0c8fa156263fc4a8b0b6)
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