Add doxygen doc comments for most of newbus and the BUS interface.

This commit is contained in:
Doug Rabson 2004-07-18 16:30:31 +00:00
parent 701f140800
commit 4c4392e791
3 changed files with 1323 additions and 228 deletions

View File

@ -1,5 +1,6 @@
#
# Copyright (c) 1998 Doug Rabson
# Copyright (c) 1998,2004 Doug Rabson
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -28,6 +29,12 @@
#include <sys/bus.h>
/**
* @defgroup BUS bus - KObj methods for drivers of devices with children
* @brief A set of methods required device drivers that support
* child devices.
* @{
*/
INTERFACE bus;
#
@ -43,53 +50,90 @@ CODE {
}
};
#
# This is called from system code which prints out a description of a
# device. It should describe the attachment that the child has with
# the parent. For instance the TurboLaser bus prints which node the
# device is attached to. See bus_generic_print_child.9 for more
# information.
# This method returns the number of characters output.
#
/**
* @brief Print a description of a child device
*
* This is called from system code which prints out a description of a
* device. It should describe the attachment that the child has with
* the parent. For instance the TurboLaser bus prints which node the
* device is attached to. See bus_generic_print_child() for more
* information.
*
* @param _dev the device whose child is being printed
* @param _child the child device to describe
*
* @returns the number of characters output.
*/
METHOD int print_child {
device_t dev;
device_t child;
device_t _dev;
device_t _child;
} DEFAULT bus_generic_print_child;
#
# Called for each child device that
# did not succeed in probing for a
# driver.
#
/**
* @brief Print a notification about an unprobed child device.
*
* Called for each child device that did not succeed in probing for a
* driver.
*
* @param _dev the device whose child was being probed
* @param _child the child device which failed to probe
*/
METHOD void probe_nomatch {
device_t dev;
device_t child;
device_t _dev;
device_t _child;
};
#
# These two methods manage a bus specific set of instance variables of
# a child device. The intention is that each different type of bus
# defines a set of appropriate instance variables (such as ports and
# irqs for ISA bus etc.)
#
# This information could be given to the child device as a struct but
# that makes it hard for a bus to add or remove variables without
# forcing an edit and recompile for all drivers which may not be
# possible for vendor supplied binary drivers.
#
# Read an instance variable. Return 0 on success.
#
/**
* @brief Read the value of a bus-specific attribute of a device
*
* This method, along with BUS_WRITE_IVAR() manages a bus-specific set
* of instance variables of a child device. The intention is that
* each different type of bus defines a set of appropriate instance
* variables (such as ports and irqs for ISA bus etc.)
*
* This information could be given to the child device as a struct but
* that makes it hard for a bus to add or remove variables without
* forcing an edit and recompile for all drivers which may not be
* possible for vendor supplied binary drivers.
*
* This method copies the value of an instance variable to the
* location specified by @p *_result.
*
* @param _dev the device whose child was being examined
* @param _child the child device whose instance variable is
* being read
* @param _index the instance variable to read
* @param _result a loction to recieve the instance variable
* value
*
* @retval 0 success
* @retval ENOENT no such instance variable is supported by @p
* _dev
*/
METHOD int read_ivar {
device_t _dev;
device_t _child;
int _indx;
int _index;
uintptr_t *_result;
};
#
# Write an instance variable. Return 0 on success.
#
/**
* @brief Write the value of a bus-specific attribute of a device
*
* This method sets the value of an instance variable to @p _value.
*
* @param _dev the device whose child was being updated
* @param _child the child device whose instance variable is
* being written
* @param _index the instance variable to write
* @param _value the value to write to that instance variable
*
* @retval 0 success
* @retval ENOENT no such instance variable is supported by @p
* _dev
* @retval EINVAL the instance variable was recognised but
* contains a read-only value
*/
METHOD int write_ivar {
device_t _dev;
device_t _child;
@ -97,31 +141,55 @@ METHOD int write_ivar {
uintptr_t _value;
};
#
# Called after the child's DEVICE_DETACH method to allow the parent
# to reclaim any resources allocated on behalf of the child.
#
/**
* @brief Notify a bus that a child was detached
*
* Called after the child's DEVICE_DETACH() method to allow the parent
* to reclaim any resources allocated on behalf of the child.
*
* @param _dev the device whose child changed state
* @param _child the child device which changed state
*/
METHOD void child_detached {
device_t _dev;
device_t _child;
};
#
# Called when a new driver is added to the devclass which owns this
# bus. The generic implementation of this method attempts to probe and
# attach any un-matched children of the bus.
#
/**
* @brief Notify a bus that a new driver was added
*
* Called when a new driver is added to the devclass which owns this
* bus. The generic implementation of this method attempts to probe and
* attach any un-matched children of the bus.
*
* @param _dev the device whose devclass had a new driver
* added to it
* @param _driver the new driver which was added
*/
METHOD void driver_added {
device_t _dev;
driver_t *_driver;
} DEFAULT bus_generic_driver_added;
#
# For busses which use use drivers supporting DEVICE_IDENTIFY to
# enumerate their devices, these methods are used to create new
# device instances. If place is non-NULL, the new device will be
# added after the last existing child with the same order.
#
/**
* @brief Create a new child device
*
* For busses which use use drivers supporting DEVICE_IDENTIFY() to
* enumerate their devices, this method is used to create new
* device instances. The new device will be added after the last
* existing child with the same order.
*
* @param _dev the bus device which will be the parent of the
* new child device
* @param _order a value which is used to partially sort the
* children of @p _dev - devices created using
* lower values of @p _order appear first in @p
* _dev's list of children
* @param _name devclass name for new device or @c NULL if not
* specified
* @param _unit unit number for new device or @c -1 if not
* specified
*/
METHOD device_t add_child {
device_t _dev;
int _order;
@ -129,20 +197,34 @@ METHOD device_t add_child {
int _unit;
};
#
# Allocate a system resource attached to `dev' on behalf of `child'.
# The types are defined in <machine/resource.h>; the meaning of the
# resource-ID field varies from bus to bus (but *rid == 0 is always
# valid if the resource type is). start and end reflect the allowable
# range, and should be passed as `0UL' and `~0UL', respectively, if
# the client has no range restriction. count is the number of consecutive
# indices in the resource required. flags is a set of sharing flags
# as defined in <sys/rman.h>.
#
# Returns a resource or a null pointer on failure. The caller is
# responsible for calling rman_activate_resource() when it actually
# uses the resource.
#
/**
* @brief Allocate a system resource
*
* This method is called by child devices of a bus to allocate resources.
* The types are defined in <machine/resource.h>; the meaning of the
* resource-ID field varies from bus to bus (but @p *rid == 0 is always
* valid if the resource type is). If a resource was allocated and the
* caller did not use the RF_ACTIVE to specify that it should be
* activated immediately, the caller is responsible for calling
* BUS_ACTIVATE_RESOURCE() when it actually uses the resource.
*
* @param _dev the parent device of @p _child
* @param _child the device which is requesting an allocation
* @param _type the type of resource to allocate
* @param _rid a pointer to the resource identifier
* @param _start hint at the start of the resource range - pass
* @c 0UL for any start address
* @param _end hint at the end of the resource range - pass
* @c ~0UL for any end address
* @param _count hint at the size of range required - pass @c 1
* for any size
* @param _flags any extra flags to control the resource
* allocation - see @c RF_XXX flags in
* <sys/rman.h> for details
*
* @returns the resource which was allocated or @c NULL if no
* resource could be allocated
*/
METHOD struct resource * alloc_resource {
device_t _dev;
device_t _child;
@ -154,6 +236,19 @@ METHOD struct resource * alloc_resource {
u_int _flags;
} DEFAULT null_alloc_resource;
/**
* @brief Activate a resource
*
* Activate a resource previously allocated with
* BUS_ALLOC_RESOURCE(). This may for instance map a memory region
* into the kernel's virtual address space.
*
* @param _dev the parent device of @p _child
* @param _child the device which allocated the resource
* @param _type the type of resource
* @param _rid the resource identifier
* @param _r the resource to activate
*/
METHOD int activate_resource {
device_t _dev;
device_t _child;
@ -162,6 +257,19 @@ METHOD int activate_resource {
struct resource *_r;
};
/**
* @brief Deactivate a resource
*
* Deactivate a resource previously allocated with
* BUS_ALLOC_RESOURCE(). This may for instance unmap a memory region
* from the kernel's virtual address space.
*
* @param _dev the parent device of @p _child
* @param _child the device which allocated the resource
* @param _type the type of resource
* @param _rid the resource identifier
* @param _r the resource to deactivate
*/
METHOD int deactivate_resource {
device_t _dev;
device_t _child;
@ -170,11 +278,19 @@ METHOD int deactivate_resource {
struct resource *_r;
};
#
# Free a resource allocated by the preceding method. The `rid' value
# must be the same as the one returned by BUS_ALLOC_RESOURCE (which
# is not necessarily the same as the one the client passed).
#
/**
* @brief Release a resource
*
* Free a resource allocated by the BUS_ALLOC_RESOURCE. The @p _rid
* value must be the same as the one returned by BUS_ALLOC_RESOURCE()
* (which is not necessarily the same as the one the client passed).
*
* @param _dev the parent device of @p _child
* @param _child the device which allocated the resource
* @param _type the type of resource
* @param _rid the resource identifier
* @param _r the resource to release
*/
METHOD int release_resource {
device_t _dev;
device_t _child;
@ -183,6 +299,29 @@ METHOD int release_resource {
struct resource *_res;
};
/**
* @brief Install an interrupt handler
*
* This method is used to associate an interrupt handler function with
* an irq resource. When the interrupt triggers, the function @p _intr
* will be called with the value of @p _arg as its single
* argument. The value returned in @p *_cookiep is used to cancel the
* interrupt handler - the caller should save this value to use in a
* future call to BUS_TEARDOWN_INTR().
*
* @param _dev the parent device of @p _child
* @param _child the device which allocated the resource
* @param _irq the resource representing the interrupt
* @param _flags a set of bits from enum intr_type specifying
* the class of interrupt
* @param _intr the function to call when the interrupt
* triggers
* @param _arg a value to use as the single argument in calls
* to @p _intr
* @param _cookiep a pointer to a location to recieve a cookie
* value that may be used to remove the interrupt
* handler
*/
METHOD int setup_intr {
device_t _dev;
device_t _child;
@ -193,6 +332,19 @@ METHOD int setup_intr {
void **_cookiep;
};
/**
* @brief Uninstall an interrupt handler
*
* This method is used to disassociate an interrupt handler function
* with an irq resource. The value of @p _cookie must be the value
* returned from a previous call to BUS_SETUP_INTR().
*
* @param _dev the parent device of @p _child
* @param _child the device which allocated the resource
* @param _irq the resource representing the interrupt
* @param _cookie the cookie value returned when the interrupt
* was originally registered
*/
METHOD int teardown_intr {
device_t _dev;
device_t _child;
@ -200,10 +352,23 @@ METHOD int teardown_intr {
void *_cookie;
};
#
# Set the range used for a particular resource. Return EINVAL if
# the type or rid are out of range.
#
/**
* @brief Define a resource which can be allocated with
* BUS_ALLOC_RESOURCE().
*
* This method is used by some busses (typically ISA) to allow a
* driver to describe a resource range that it would like to
* allocate. The resource defined by @p _type and @p _rid is defined
* to start at @p _start and to include @p _count indices in its
* range.
*
* @param _dev the parent device of @p _child
* @param _child the device which owns the resource
* @param _type the type of resource
* @param _rid the resource identifier
* @param _start the start of the resource range
* @param _count the size of the resource range
*/
METHOD int set_resource {
device_t _dev;
device_t _child;
@ -213,10 +378,21 @@ METHOD int set_resource {
u_long _count;
};
#
# Get the range for a resource. Return ENOENT if the type or rid are
# out of range or have not been set.
#
/**
* @brief Describe a resource
*
* This method allows a driver to examine the range used for a given
* resource without actually allocating it.
*
* @param _dev the parent device of @p _child
* @param _child the device which owns the resource
* @param _type the type of resource
* @param _rid the resource identifier
* @param _start the address of a location to recieve the start
* index of the resource range
* @param _count the address of a location to recieve the size
* of the resource range
*/
METHOD int get_resource {
device_t _dev;
device_t _child;
@ -226,9 +402,17 @@ METHOD int get_resource {
u_long *_countp;
};
#
# Delete a resource.
#
/**
* @brief Delete a resource.
*
* Use this to delete a resource (possibly one previously added with
* BUS_SET_RESOURCE()).
*
* @param _dev the parent device of @p _child
* @param _child the device which owns the resource
* @param _type the type of resource
* @param _rid the resource identifier
*/
METHOD void delete_resource {
device_t _dev;
device_t _child;
@ -236,33 +420,52 @@ METHOD void delete_resource {
int _rid;
};
#
# Return a struct resource_list.
#
/**
* @brief Return a struct resource_list.
*
* Used by drivers which use bus_generic_rl_alloc_resource() etc. to
* implement their resource handling. It should return the resource
* list of the given child device.
*
* @param _dev the parent device of @p _child
* @param _child the device which owns the resource list
*/
METHOD struct resource_list * get_resource_list {
device_t _dev;
device_t _child;
} DEFAULT bus_generic_get_resource_list;
#
# Is the hardware described by _child still attached to the system?
#
# This method should return 0 if the device is not present. It should
# return -1 if it is present. Any errors in determining should be
# returned as a normal errno value. Client drivers are to assume that
# the device is present, even if there is an error determining if it is
# there. Busses are to try to avoid returning errors, but newcard will return
# an error if the device fails to implement this method.
#
/**
* @brief Is the hardware described by @p _child still attached to the
* system?
*
* This method should return 0 if the device is not present. It should
* return -1 if it is present. Any errors in determining should be
* returned as a normal errno value. Client drivers are to assume that
* the device is present, even if there is an error determining if it is
* there. Busses are to try to avoid returning errors, but newcard will return
* an error if the device fails to implement this method.
*
* @param _dev the parent device of @p _child
* @param _child the device which is being examined
*/
METHOD int child_present {
device_t _dev;
device_t _child;
} DEFAULT bus_generic_child_present;
#
# Returns the pnp info for this device. Return it as a string. If the
# string is insufficient for the storage, then return EOVERFLOW.
#
/**
* @brief Returns the pnp info for this device.
*
* Return it as a string. If the string is insufficient for the
* storage, then return EOVERFLOW.
*
* @param _dev the parent device of @p _child
* @param _child the device which is being examined
* @param _buf the address of a buffer to receive the pnp
* string
* @param _buflen the size of the buffer pointed to by @p _buf
*/
METHOD int child_pnpinfo_str {
device_t _dev;
device_t _child;
@ -270,10 +473,18 @@ METHOD int child_pnpinfo_str {
size_t _buflen;
};
#
# Returns the location for this device. Return it as a string. If the
# string is insufficient for the storage, then return EOVERFLOW.
#
/**
* @brief Returns the location for this device.
*
* Return it as a string. If the string is insufficient for the
* storage, then return EOVERFLOW.
*
* @param _dev the parent device of @p _child
* @param _child the device which is being examined
* @param _buf the address of a buffer to receive the location
* string
* @param _buflen the size of the buffer pointed to by @p _buf
*/
METHOD int child_location_str {
device_t _dev;
device_t _child;
@ -281,10 +492,15 @@ METHOD int child_location_str {
size_t _buflen;
};
#
# Allow (bus) drivers to specify the trigger mode and polarity of the
# specified interrupt.
#
/**
* @brief Allow (bus) drivers to specify the trigger mode and polarity
* of the specified interrupt.
*
* @param _dev the bus device
* @param _irq the interrupt number to modify
* @param _trig the trigger mode required
* @param _pol the interrupt polarity required
*/
METHOD int config_intr {
device_t _dev;
int _irq;

File diff suppressed because it is too large Load Diff

View File

@ -29,40 +29,45 @@
#ifndef _SYS_BUS_H_
#define _SYS_BUS_H_
/*
* Interface information structure.
/**
* @defgroup NEWBUS newbus - a generic framework for managing devices
* @{
*/
/**
* @brief Interface information structure.
*/
struct u_businfo {
int ub_version; /* interface version */
int ub_version; /**< @brief interface version */
#define BUS_USER_VERSION 1
int ub_generation; /* generation count */
int ub_generation; /**< @brief generation count */
};
/*
* State of the device.
/**
* @brief State of the device.
*/
typedef enum device_state {
DS_NOTPRESENT, /* not probed or probe failed */
DS_ALIVE, /* probe succeeded */
DS_ATTACHED, /* attach method called */
DS_BUSY /* device is open */
DS_NOTPRESENT, /**< @brief not probed or probe failed */
DS_ALIVE, /**< @brief probe succeeded */
DS_ATTACHED, /**< @brief attach method called */
DS_BUSY /**< @brief device is open */
} device_state_t;
/*
* Device information exported to userspace.
/**
* @brief Device information exported to userspace.
*/
struct u_device {
uintptr_t dv_handle;
uintptr_t dv_parent;
char dv_name[32]; /* Name of device in tree. */
char dv_desc[32]; /* Driver description */
char dv_drivername[32]; /* Driver name */
char dv_pnpinfo[128]; /* Plug and play info */
char dv_location[128]; /* Where is the device? */
uint32_t dv_devflags; /* API Flags for device */
uint16_t dv_flags; /* flags for dev date */
device_state_t dv_state; /* State of attachment */
char dv_name[32]; /**< @brief Name of device in tree. */
char dv_desc[32]; /**< @brief Driver description */
char dv_drivername[32]; /**< @brief Driver name */
char dv_pnpinfo[128]; /**< @brief Plug and play info */
char dv_location[128]; /**< @brief Where is the device? */
uint32_t dv_devflags; /**< @brief API Flags for device */
uint16_t dv_flags; /**< @brief flags for dev date */
device_state_t dv_state; /**< @brief State of attachment */
/* XXX more driver info? */
};
@ -71,7 +76,7 @@ struct u_device {
#include <sys/queue.h>
#include <sys/kobj.h>
/*
/**
* devctl hooks. Typically one should use the devctl_notify
* hook to send the message. However, devctl_queue_data is also
* included in case devctl_notify isn't sufficiently general.
@ -84,25 +89,61 @@ void devctl_queue_data(char *__data);
* Forward declarations
*/
typedef struct device *device_t;
/**
* @brief A device driver (included mainly for compatibility with
* FreeBSD 4.x).
*/
typedef struct kobj_class driver_t;
/**
* @brief A device class
*
* The devclass object has two main functions in the system. The first
* is to manage the allocation of unit numbers for device instances
* and the second is to hold the list of device drivers for a
* particular bus type. Each devclass has a name and there cannot be
* two devclasses with the same name. This ensures that unique unit
* numbers are allocated to device instances.
*
* Drivers that support several different bus attachments (e.g. isa,
* pci, pccard) should all use the same devclass to ensure that unit
* numbers do not conflict.
*
* Each devclass may also have a parent devclass. This is used when
* searching for device drivers to allow a form of inheritance. When
* matching drivers with devices, first the driver list of the parent
* device's devclass is searched. If no driver is found in that list,
* the search continues in the parent devclass (if any).
*/
typedef struct devclass *devclass_t;
/**
* @brief A device method (included mainly for compatibility with
* FreeBSD 4.x).
*/
#define device_method_t kobj_method_t
/**
* @brief A driver interrupt service routine
*/
typedef void driver_intr_t(void*);
/*
* Interrupt type bits. These flags are used both by newbus interrupt
/**
* @brief Interrupt type bits.
*
* These flags are used both by newbus interrupt
* registration (nexus.c) and also in struct intrec, which defines
* interrupt properties.
*
* XXX We should probably revisit this and remove the vestiges of the
* spls implicit in names like INTR_TYPE_TTY. In the meantime, don't
* spls implicit in names like INTR_TYPE_TTY. In the meantime, don't
* confuse things by renaming them (Grog, 18 July 2000).
*
* We define this in terms of bits because some devices may belong
* to multiple classes (and therefore need to be included in
* multiple interrupt masks, which is what this really serves to
* indicate. Buses which do interrupt remapping will want to
* indicate. Buses which do interrupt remapping will want to
* change their type to reflect what sort of devices are underneath.
*/
enum intr_type {
@ -133,8 +174,10 @@ enum intr_polarity {
typedef int (*devop_t)(void);
/*
* This structure is deprecated. Use the kobj(9) macro DEFINE_CLASS to
/**
* @brief This structure is deprecated.
*
* Use the kobj(9) macro DEFINE_CLASS to
* declare classes which implement device drivers.
*/
struct driver {
@ -147,79 +190,42 @@ struct driver {
*/
struct resource;
/**
* @brief An entry for a single resource in a resource list.
*/
struct resource_list_entry {
SLIST_ENTRY(resource_list_entry) link;
int type; /* type argument to alloc_resource */
int rid; /* resource identifier */
struct resource *res; /* the real resource when allocated */
u_long start; /* start of resource range */
u_long end; /* end of resource range */
u_long count; /* count within range */
int type; /**< @brief type argument to alloc_resource */
int rid; /**< @brief resource identifier */
struct resource *res; /**< @brief the real resource when allocated */
u_long start; /**< @brief start of resource range */
u_long end; /**< @brief end of resource range */
u_long count; /**< @brief count within range */
};
SLIST_HEAD(resource_list, resource_list_entry);
/*
* Initialise a resource list.
*/
void resource_list_init(struct resource_list *rl);
/*
* Reclaim memory used by a resource list.
*/
void resource_list_free(struct resource_list *rl);
/*
* Add a resource entry or modify an existing entry if one exists with
* the same type and rid.
*/
void resource_list_add(struct resource_list *rl,
int type, int rid,
u_long start, u_long end, u_long count);
int resource_list_add_next(struct resource_list *rl,
int type,
u_long start, u_long end, u_long count);
/*
* Find a resource entry by type and rid.
*/
struct resource_list_entry*
resource_list_find(struct resource_list *rl,
int type, int rid);
/*
* Delete a resource entry.
*/
void resource_list_delete(struct resource_list *rl,
int type, int rid);
/*
* Implement BUS_ALLOC_RESOURCE by looking up a resource from the list
* and passing the allocation up to the parent of bus. This assumes
* that the first entry of device_get_ivars(child) is a struct
* resource_list. This also handles 'passthrough' allocations where a
* child is a remote descendant of bus by passing the allocation up to
* the parent of bus.
*/
struct resource *
resource_list_alloc(struct resource_list *rl,
device_t bus, device_t child,
int type, int *rid,
u_long start, u_long end,
u_long count, u_int flags);
/*
* Implement BUS_RELEASE_RESOURCE.
*/
int resource_list_release(struct resource_list *rl,
device_t bus, device_t child,
int type, int rid, struct resource *res);
/*
* Print all resources of a specified type, for use in bus_print_child.
* The name is printed if at least one resource of the given type is available.
* The format ist used to print resource start and end.
*/
int resource_list_print_type(struct resource_list *rl,
const char *name, int type,
const char *format);
@ -410,7 +416,7 @@ int resource_set_string(const char *name, int unit, const char *resname,
int bus_data_generation_check(int generation);
void bus_data_generation_update(void);
/*
/**
* Shorthand for constructing method tables.
*/
#define DEVMETHOD KOBJMETHOD
@ -425,7 +431,7 @@ struct module;
int driver_module_handler(struct module *, int, void *);
/*
/**
* Module support for automatically adding drivers to busses.
*/
struct driver_module_data {
@ -453,7 +459,7 @@ static moduledata_t name##_##busname##_mod = { \
DECLARE_MODULE(name##_##busname, name##_##busname##_mod, \
SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
/*
/**
* Generic ivar accessor generation macros for bus drivers
*/
#define __BUS_ACCESSOR(varp, var, ivarp, ivar, type) \