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