|
|
|
Back to Index
|
The information that a user enters into the kernel configuration file is processed and
passed to the kernel as configuration resources. This information is parsed by the bus
configuration code and transformed into a value of structure device_t and the bus
resources associated with it. The drivers may access the configuration resources directly
using functions resource_* for more complex cases of configuration. However, generally
this is neither needed nor recommended, so this issue is not discussed further here.
The bus resources are associated with each device. They are identified by type and
number within the type. For the ISA bus the following types are defined:
-
SYS_RES_IRQ - interrupt
number
-
SYS_RES_DRQ - ISA DMA channel
number
-
SYS_RES_MEMORY - range of device
memory mapped into the system memory space
-
SYS_RES_IOPORT - range of device
I/O registers
The enumeration within types starts from 0, so if a device has two memory regions it
would have resources of type SYS_RES_MEMORY numbered 0 and 1. The resource type has
nothing to do with the C language type, all the resource values have the C language type
unsigned long and must be cast as necessary. The resource
numbers do not have to be contiguous, although for ISA they normally would be. The
permitted resource numbers for ISA devices are:
IRQ: 0-1
DRQ: 0-1
MEMORY: 0-3
IOPORT: 0-7
All the resources are represented as ranges, with a start value and count. For IRQ and
DRQ resources the count would normally be equal to 1. The values for memory refer to the
physical addresses.
Three types of activities can be performed on resources:
-
set/get
-
allocate/release
-
activate/deactivate
Setting sets the range used by the resource. Allocation reserves the requested range
that no other driver would be able to reserve it (and checking that no other driver
reserved this range already). Activation makes the resource accessible to the driver by
doing whatever is necessary for that (for example, for memory it would be mapping into
the kernel virtual address space).
The functions to manipulate resources are:
-
int bus_set_resource(device_t dev, int type, int rid, u_long
start, u_long count)
Set a range for a resource. Returns 0 if successful, error code otherwise. Normally,
this function will return an error only if one of type, rid, start or count has a value that falls out of the permitted range.
-
dev - driver's device
-
type - type of resource, SYS_RES_*
-
rid - resource number (ID) within type
-
start, count - resource range
-
int bus_get_resource(device_t dev, int type, int rid, u_long
*startp, u_long *countp)
Get the range of resource. Returns 0 if successful, error code if the resource is not
defined yet.
-
u_long bus_get_resource_start(device_t dev, int type, int rid)
u_long bus_get_resource_count (device_t dev, int type, int rid)
Convenience functions to get only the start or count. Return 0 in case of error, so if
the resource start has 0 among the legitimate values it would be impossible to tell if
the value is 0 or an error occurred. Luckily, no ISA resources for add-on drivers may
have a start value equal to 0.
-
void bus_delete_resource(device_t dev, int type, int
rid)
Delete a resource, make it undefined.
-
struct resource * bus_alloc_resource(device_t dev, int type,
int *rid, u_long start, u_long end, u_long count, u_int flags)
Allocate a resource as a range of count values not allocated by anyone else, somewhere
between start and end. Alas, alignment is not supported. If the resource was not set yet
it is automatically created. The special values of start 0 and end ~0 (all ones) means
that the fixed values previously set by bus_set_resource()
must be used instead: start and count as themselves and end=(start+count), in this case
if the resource was not defined before then an error is returned. Although rid is passed
by reference it is not set anywhere by the resource allocation code of the ISA bus. (The
other buses may use a different approach and modify it).
Flags are a bitmap, the flags interesting for the caller are:
-
RF_ACTIVE - causes the resource
to be automatically activated after allocation.
-
RF_SHAREABLE - resource may be
shared at the same time by multiple drivers.
-
RF_TIMESHARE - resource may be
time-shared by multiple drivers, i.e. allocated at the same time by many but activated
only by one at any given moment of time.
-
Returns 0 on error. The allocated values may be obtained from the returned handle
using methods rhand_*().
-
int bus_release_resource(device_t dev, int type, int rid,
struct resource *r)
-
Release the resource, r is the handle returned by bus_alloc_resource(). Returns 0 on success, error code
otherwise.
-
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)
-
Activate or deactivate resource. Return 0 on success, error code otherwise. If the
resource is time-shared and currently activated by another driver then EBUSY is
returned.
-
int bus_setup_intr(device_t dev, struct resource *r, int flags,
driver_intr_t *handler, void *arg, void **cookiep) int
bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
-
Associate or de-associate the interrupt handler with a device. Return 0 on success,
error code otherwise.
-
r - the activated resource handler describing the IRQ
flags - the interrupt priority level, one of:
-
INTR_TYPE_TTY - terminals and other likewise
character-type devices. To mask them use spltty().
-
(INTR_TYPE_TTY | INTR_TYPE_FAST) - terminal type devices
with small input buffer, critical to the data loss on input (such as the old-fashioned
serial ports). To mask them use spltty().
-
INTR_TYPE_BIO - block-type devices, except those on the
CAM controllers. To mask them use splbio().
-
INTR_TYPE_CAM - CAM (Common Access Method) bus
controllers. To mask them use splcam().
-
INTR_TYPE_NET - network interface controllers. To mask
them use splimp().
-
INTR_TYPE_MISC - miscellaneous devices. There is no
other way to mask them than by splhigh() which masks all
interrupts.
When an interrupt handler executes all the other interrupts matching its priority
level will be masked. The only exception is the MISC level for which no other interrupts
are masked and which is not masked by any other interrupt.
-
handler - pointer to the handler
function, the type driver_intr_t is defined as void
driver_intr_t(void *)
-
arg - the argument passed to the
handler to identify this particular device. It is cast from void* to any real type by the
handler. The old convention for the ISA interrupt handlers was to use the unit number as
argument, the new (recommended) convention is using a pointer to the device softc
structure.
-
cookie[p] - the value received
from setup() is used to identify the handler when passed to
teardown()
A number of methods are defined to operate on the resource handlers (struct resource
*). Those of interest to the device driver writers are:
|
|
|
|
© 2002-2004
Active-Venture.com
Website Hosting
Service
|
| |
|
Disclaimer: This
documentation is provided only for the benefits of our website hosting customers.
For authoritative source of the documentation, please refer to http://www.freebsd.org
|
|
|