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