As part of configuring and operating devices, a driver might need to manage hardware resources, such as interrupt-request lines (IRQs), I/O ports, or I/O memory (McKusick and Neville-Neil, 2005). Naturally, Newbus includes several functions for doing just that.
#include <sys/param.h> #include <sys/bus.h> #include <machine/bus.h> #include <sys/rman.h> #include <machine/resource.h> struct resource * bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end, u_long count, u_int flags); struct resource * bus_alloc_resource_any(device_t dev, int type, int *rid, u_int flags); int bus_activate_resource(device_t dev, int type, int rid, struct resource *r); int bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r); int bus_release_resource(device_t dev, int type, int rid, struct resource *r);
The bus_alloc_resource
function allocates hardware resources for a specific device to use. If successful, a struct resource
pointer is returned; otherwise, NULL
is returned. This function is normally called during device_attach
. If it is called during device_probe
, all allocated resources must be released (via bus_release_resource
) before returning. Most of the arguments for bus_alloc_resource
are common to the other hardware resource management functions. These arguments are described in the next few paragraphs.
The dev
argument is the device that requires ownership of the hardware resource(s). Before allocation, resources are owned by the parent bus.
The type
argument represents the type of resource dev
wants allocated. Valid values for this argument are listed in Table 7-2.
Table 7-2. Symbolic Constants for Hardware Resources
Constant | Description |
---|---|
| Interrupt-request line |
| I/O port |
| I/O memory |
The rid
argument expects a resource ID (RID). If bus_alloc_resource
is successful, a RID is returned in rid
that may differ from what you passed. You’ll learn more about RIDs later.
The start
and end
arguments are the start and end addresses of the hardware resource(s). To employ the default bus values, simply pass 0ul
as start
and ˜0ul
as end
.
The count
argument denotes the size of the hardware resource(s). If you used the default bus values for start
and end
, count
is used only if it is larger than the default bus value.
The flags
argument details the characteristics of the hardware resource. Valid values for this argument are listed in Table 7-3.
Table 7-3. bus_alloc_resource Symbolic Constants
Constant | Description |
---|---|
| Allocate hardware resource, but don’t activate it |
| Allocate hardware resource and activate resource automatically |
| Hardware resource permits contemporaneous sharing; you should always set this flag, unless the resource cannot be shared |
| Hardware resource permits time-division sharing |
The bus_alloc_resource_any
function is a convenience wrapper for bus_alloc_resource
that sets start
, end
, and count
to their default bus values.
The bus_activate_resource
function activates a previously allocated hardware resource. Naturally, resources must be activated before they can be used. Most drivers simply pass RF_ACTIVE
to bus_alloc_resource
or bus_alloc_resource_any
to avoid calling bus_activate_resource
.
The bus_deactivate_resource
function deactivates a hardware resource. This function is primarily used in bus drivers (so we’ll never call it).
The bus_release_resource
function releases a previously allocated hardware resource. Of course, the resource cannot be in use on release. If successful, 0
is returned; otherwise, the kernel panics.
We’ll cover an example that employs IRQs in Chapter 8 and Chapter 9, and I’ll go over an example that requires I/O ports and I/O memory in Chapter 10 and Chapter 11.
3.144.227.72