My changes to the new device interface:
- Interface wth the new resource manager. - Allow for multiple drivers implementing a single devclass. - Remove ordering dependencies between header files. - Style cleanup. - Add DEVICE_SUSPEND and DEVICE_RESUME methods. - Move to a single-phase interrupt setup scheme. Kernel builds on the Alpha are brken until Doug gets a chance to incorporate these changes on that side. Agreed to in principle by: dfr
This commit is contained in:
parent
a55946faaf
commit
14177d72cd
@ -23,7 +23,7 @@
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $Id: bus_if.m,v 1.3 1998/09/16 08:25:56 dfr Exp $
|
||||
# $Id: bus_if.m,v 1.4 1998/11/08 18:51:38 nsouch Exp $
|
||||
#
|
||||
|
||||
INTERFACE bus;
|
||||
@ -57,7 +57,7 @@ METHOD int read_ivar {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
int index;
|
||||
u_long *result;
|
||||
uintptr_t *result;
|
||||
};
|
||||
|
||||
#
|
||||
@ -67,27 +67,75 @@ METHOD int write_ivar {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
int index;
|
||||
u_long value;
|
||||
uintptr_t value;
|
||||
};
|
||||
|
||||
#
|
||||
# Create an interrupt handler for the child device. The handler will
|
||||
# be called with the value 'arg' as its only argument. This method
|
||||
# does not activate the handler.
|
||||
# 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>.
|
||||
#
|
||||
METHOD void* create_intr {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
int irq;
|
||||
driver_intr_t *intr;
|
||||
void *arg;
|
||||
# Returns a resource or a null pointer on failure. The caller is
|
||||
# responsible for calling rman_activate_resource() when it actually
|
||||
# uses the resource.
|
||||
#
|
||||
METHOD struct resource * alloc_resource {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
int type;
|
||||
int *rid;
|
||||
u_long start;
|
||||
u_long end;
|
||||
u_long count;
|
||||
u_int flags;
|
||||
};
|
||||
|
||||
METHOD int activate_resource {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
int type;
|
||||
int rid;
|
||||
struct resource *r;
|
||||
};
|
||||
|
||||
METHOD int deactivate_resource {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
int type;
|
||||
int rid;
|
||||
struct resource *r;
|
||||
};
|
||||
|
||||
#
|
||||
# Activate an interrupt handler previously created with
|
||||
# BUS_CREATE_INTR.
|
||||
# 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).
|
||||
#
|
||||
METHOD int connect_intr {
|
||||
device_t dev;
|
||||
void *ih;
|
||||
METHOD int release_resource {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
int type;
|
||||
int rid;
|
||||
struct resource *res;
|
||||
};
|
||||
|
||||
METHOD int setup_intr {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
struct resource *irq;
|
||||
driver_intr_t *intr;
|
||||
void *arg;
|
||||
void **cookiep;
|
||||
};
|
||||
|
||||
METHOD int teardown_intr {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
struct resource *irq;
|
||||
void *cookie;
|
||||
};
|
||||
|
@ -23,7 +23,7 @@
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $Id: device_if.m,v 1.1 1998/06/14 13:53:10 dfr Exp $
|
||||
# $Id: device_if.m,v 1.2 1998/11/08 18:35:53 nsouch Exp $
|
||||
#
|
||||
|
||||
INTERFACE device;
|
||||
@ -67,3 +67,17 @@ METHOD int detach {
|
||||
METHOD int shutdown {
|
||||
device_t dev;
|
||||
};
|
||||
|
||||
#
|
||||
# This is called by the power-management subsystem when a suspend has been
|
||||
# requested by the user or by some automatic mechanism. This gives
|
||||
# drivers a chance to veto the suspend or save their configuration before
|
||||
# power is removed.
|
||||
#
|
||||
METHOD int suspend {
|
||||
device_t dev;
|
||||
};
|
||||
|
||||
METHOD int resume {
|
||||
device_t dev;
|
||||
};
|
||||
|
@ -30,7 +30,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: kern_conf.c,v 1.27 1998/07/04 22:30:21 julian Exp $
|
||||
* $Id: kern_conf.c,v 1.28 1998/10/25 17:44:50 phk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -166,7 +166,7 @@ cdevsw_add_generic(int bdev, int cdev, struct cdevsw *cdevsw)
|
||||
}
|
||||
|
||||
int
|
||||
cdevsw_module_handler(module_t mod, modeventtype_t what, void* arg)
|
||||
cdevsw_module_handler(module_t mod, int what, void *arg)
|
||||
{
|
||||
struct cdevsw_module_data* data = (struct cdevsw_module_data*) arg;
|
||||
int error;
|
||||
@ -190,7 +190,7 @@ cdevsw_module_handler(module_t mod, modeventtype_t what, void* arg)
|
||||
}
|
||||
|
||||
int
|
||||
bdevsw_module_handler(module_t mod, modeventtype_t what, void* arg)
|
||||
bdevsw_module_handler(module_t mod, int what, void* arg)
|
||||
{
|
||||
struct bdevsw_module_data* data = (struct bdevsw_module_data*) arg;
|
||||
int error;
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: subr_bus.c,v 1.8 1998/10/27 09:21:43 dfr Exp $
|
||||
* $Id: subr_bus.c,v 1.9 1998/11/13 09:39:37 dfr Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -667,6 +667,16 @@ device_get_desc(device_t dev)
|
||||
return dev->desc;
|
||||
}
|
||||
|
||||
void
|
||||
device_print_prettyname(device_t dev)
|
||||
{
|
||||
const char *name = device_get_name(dev);
|
||||
|
||||
if (name == 0)
|
||||
name = "(no driver assigned)";
|
||||
printf("%s%d: ", name, device_get_unit(dev));
|
||||
}
|
||||
|
||||
void
|
||||
device_set_desc(device_t dev, const char* desc)
|
||||
{
|
||||
@ -807,9 +817,10 @@ device_probe_and_attach(device_t dev)
|
||||
dev->state = DS_NOTPRESENT;
|
||||
}
|
||||
}
|
||||
} else
|
||||
printf("%s%d: disabled, not probed.\n",
|
||||
dev->devclass->name, dev->unit);
|
||||
} else {
|
||||
device_print_prettyname(dev);
|
||||
printf("not probed (disabled)\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -855,7 +866,7 @@ static int
|
||||
resource_match_string(int i, char *resname, char *value)
|
||||
{
|
||||
int j;
|
||||
struct resource *res;
|
||||
struct config_resource *res;
|
||||
|
||||
for (j = 0, res = devtab[i].resources;
|
||||
j < devtab[i].resource_count; j++, res++)
|
||||
@ -867,10 +878,11 @@ resource_match_string(int i, char *resname, char *value)
|
||||
}
|
||||
|
||||
static int
|
||||
resource_find(const char *name, int unit, char *resname, struct resource **result)
|
||||
resource_find(const char *name, int unit, char *resname,
|
||||
struct config_resource **result)
|
||||
{
|
||||
int i, j;
|
||||
struct resource *res;
|
||||
struct config_resource *res;
|
||||
|
||||
/*
|
||||
* First check specific instances, then generic.
|
||||
@ -906,7 +918,7 @@ int
|
||||
resource_int_value(const char *name, int unit, char *resname, int *result)
|
||||
{
|
||||
int error;
|
||||
struct resource *res;
|
||||
struct config_resource *res;
|
||||
if ((error = resource_find(name, unit, resname, &res)) != 0)
|
||||
return error;
|
||||
if (res->type != RES_INT)
|
||||
@ -919,7 +931,7 @@ int
|
||||
resource_long_value(const char *name, int unit, char *resname, long *result)
|
||||
{
|
||||
int error;
|
||||
struct resource *res;
|
||||
struct config_resource *res;
|
||||
if ((error = resource_find(name, unit, resname, &res)) != 0)
|
||||
return error;
|
||||
if (res->type != RES_LONG)
|
||||
@ -932,7 +944,7 @@ int
|
||||
resource_string_value(const char *name, int unit, char *resname, char **result)
|
||||
{
|
||||
int error;
|
||||
struct resource *res;
|
||||
struct config_resource *res;
|
||||
if ((error = resource_find(name, unit, resname, &res)) != 0)
|
||||
return error;
|
||||
if (res->type != RES_STRING)
|
||||
@ -1011,59 +1023,167 @@ bus_generic_shutdown(device_t dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bus_generic_suspend(device_t dev)
|
||||
{
|
||||
int error;
|
||||
device_t child, child2;
|
||||
|
||||
for (child = TAILQ_FIRST(&dev->children);
|
||||
child; child = TAILQ_NEXT(child, link)) {
|
||||
error = DEVICE_SUSPEND(child);
|
||||
if (error) {
|
||||
for (child2 = TAILQ_FIRST(&dev->children);
|
||||
child2 && child2 != child;
|
||||
child2 = TAILQ_NEXT(child2, link))
|
||||
DEVICE_RESUME(child2);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bus_generic_resume(device_t dev)
|
||||
{
|
||||
device_t child;
|
||||
|
||||
for (child = TAILQ_FIRST(&dev->children);
|
||||
child; child = TAILQ_NEXT(child, link)) {
|
||||
DEVICE_RESUME(child);
|
||||
/* if resume fails, there's nothing we can usefully do... */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bus_generic_print_child(device_t dev, device_t child)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
bus_generic_read_ivar(device_t dev, device_t child, int index, u_long* result)
|
||||
bus_generic_read_ivar(device_t dev, device_t child, int index,
|
||||
uintptr_t * result)
|
||||
{
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
int
|
||||
bus_generic_write_ivar(device_t dev, device_t child, int index, u_long value)
|
||||
bus_generic_write_ivar(device_t dev, device_t child, int index,
|
||||
uintptr_t value)
|
||||
{
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
void *
|
||||
bus_generic_create_intr(device_t dev, device_t child, int irq, driver_intr_t *intr, void *arg)
|
||||
int
|
||||
bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
|
||||
driver_intr_t *intr, void *arg, void **cookiep)
|
||||
{
|
||||
/* Propagate up the bus hierarchy until someone handles it. */
|
||||
if (dev->parent)
|
||||
return BUS_CREATE_INTR(dev->parent, dev, irq, intr, arg);
|
||||
else
|
||||
return NULL;
|
||||
/* Propagate up the bus hierarchy until someone handles it. */
|
||||
if (dev->parent)
|
||||
return (BUS_SETUP_INTR(dev->parent, dev, irq, intr, arg,
|
||||
cookiep));
|
||||
else
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
int
|
||||
bus_generic_connect_intr(device_t dev, void *ih)
|
||||
bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq,
|
||||
void *cookie)
|
||||
{
|
||||
/* Propagate up the bus hierarchy until someone handles it. */
|
||||
if (dev->parent)
|
||||
return BUS_CONNECT_INTR(dev->parent, ih);
|
||||
else
|
||||
return EINVAL;
|
||||
/* Propagate up the bus hierarchy until someone handles it. */
|
||||
if (dev->parent)
|
||||
return (BUS_TEARDOWN_INTR(dev->parent, dev, irq, cookie));
|
||||
else
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
static int root_create_intr(device_t dev, device_t child,
|
||||
driver_intr_t *intr, void *arg)
|
||||
int
|
||||
bus_generic_activate_resource(device_t dev, device_t child, int type, int rid,
|
||||
struct resource *r)
|
||||
{
|
||||
/*
|
||||
* If an interrupt mapping gets to here something bad has happened.
|
||||
* Should probably panic.
|
||||
*/
|
||||
return EINVAL;
|
||||
/* Propagate up the bus hierarchy until someone handles it. */
|
||||
if (dev->parent)
|
||||
return (BUS_ACTIVATE_RESOURCE(dev->parent, child, type, rid,
|
||||
r));
|
||||
else
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
int
|
||||
bus_generic_deactivate_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct resource *r)
|
||||
{
|
||||
/* Propagate up the bus hierarchy until someone handles it. */
|
||||
if (dev->parent)
|
||||
return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, type, rid,
|
||||
r));
|
||||
else
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some convenience functions to make it easier for drivers to use the
|
||||
* resource-management functions. All these really do is hide the
|
||||
* indirection through the parent's method table, making for slightly
|
||||
* less-wordy code. In the future, it might make sense for this code
|
||||
* to maintain some sort of a list of resources allocated by each device.
|
||||
*/
|
||||
struct resource *
|
||||
bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end,
|
||||
u_long count, u_int flags)
|
||||
{
|
||||
if (dev->parent == 0)
|
||||
return (0);
|
||||
return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
|
||||
count, flags));
|
||||
}
|
||||
|
||||
int
|
||||
bus_activate_resource(device_t dev, int type, int rid, struct resource *r)
|
||||
{
|
||||
if (dev->parent == 0)
|
||||
return (EINVAL);
|
||||
return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
|
||||
}
|
||||
|
||||
int
|
||||
bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r)
|
||||
{
|
||||
if (dev->parent == 0)
|
||||
return (EINVAL);
|
||||
return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
|
||||
}
|
||||
|
||||
int
|
||||
bus_release_resource(device_t dev, int type, int rid, struct resource *r)
|
||||
{
|
||||
if (dev->parent == 0)
|
||||
return (EINVAL);
|
||||
return (BUS_RELEASE_RESOURCE(dev->parent, dev,
|
||||
type, rid, r));
|
||||
}
|
||||
|
||||
static int
|
||||
root_setup_intr(device_t dev, device_t child, driver_intr_t *intr, void *arg,
|
||||
void **cookiep)
|
||||
{
|
||||
/*
|
||||
* If an interrupt mapping gets to here something bad has happened.
|
||||
*/
|
||||
panic("root_setup_intr");
|
||||
}
|
||||
|
||||
static device_method_t root_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_suspend, bus_generic_suspend),
|
||||
DEVMETHOD(device_resume, bus_generic_resume),
|
||||
|
||||
/* Bus interface */
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
|
||||
DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
|
||||
DEVMETHOD(bus_create_intr, root_create_intr),
|
||||
DEVMETHOD(bus_setup_intr, root_setup_intr),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
@ -1075,11 +1195,11 @@ static driver_t root_driver = {
|
||||
1, /* no softc */
|
||||
};
|
||||
|
||||
device_t root_bus;
|
||||
devclass_t root_devclass;
|
||||
device_t root_bus;
|
||||
devclass_t root_devclass;
|
||||
|
||||
static int
|
||||
root_bus_module_handler(module_t mod, modeventtype_t what, void* arg)
|
||||
root_bus_module_handler(module_t mod, int what, void* arg)
|
||||
{
|
||||
switch (what) {
|
||||
case MOD_LOAD:
|
||||
@ -1104,7 +1224,7 @@ static moduledata_t root_bus_mod = {
|
||||
DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
|
||||
|
||||
void
|
||||
root_bus_configure()
|
||||
root_bus_configure(void)
|
||||
{
|
||||
device_t dev;
|
||||
|
||||
@ -1117,40 +1237,53 @@ root_bus_configure()
|
||||
}
|
||||
|
||||
int
|
||||
driver_module_handler(module_t mod, modeventtype_t what, void* arg)
|
||||
driver_module_handler(module_t mod, int what, void *arg)
|
||||
{
|
||||
struct driver_module_data* data = (struct driver_module_data*) arg;
|
||||
devclass_t bus_devclass = devclass_find_internal(data->busname, TRUE);
|
||||
int error;
|
||||
int error, i;
|
||||
struct driver_module_data *dmd;
|
||||
devclass_t bus_devclass;
|
||||
|
||||
switch (what) {
|
||||
case MOD_LOAD:
|
||||
PDEBUG(("Loading module: driver %s on bus %s",
|
||||
DRIVERNAME(data->driver), data->busname));
|
||||
if (error = devclass_add_driver(bus_devclass,
|
||||
data->driver))
|
||||
return error;
|
||||
*data->devclass =
|
||||
devclass_find_internal(data->driver->name, TRUE);
|
||||
break;
|
||||
dmd = (struct driver_module_data *)arg;
|
||||
bus_devclass = devclass_find_internal(dmd->dmd_busname, TRUE);
|
||||
error = 0;
|
||||
|
||||
case MOD_UNLOAD:
|
||||
PDEBUG(("Unloading module: driver %s from bus %s",
|
||||
DRIVERNAME(data->driver), data->busname));
|
||||
if (error = devclass_delete_driver(bus_devclass,
|
||||
data->driver))
|
||||
return error;
|
||||
break;
|
||||
}
|
||||
switch (what) {
|
||||
case MOD_LOAD:
|
||||
for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
|
||||
PDEBUG(("Loading module: driver %s on bus %s",
|
||||
DRIVERNAME(dmd->dmd_driver[i]),
|
||||
dmd->dmd_busname));
|
||||
error = devclass_add_driver(bus_devclass,
|
||||
dmd->dmd_drivers[i]);
|
||||
}
|
||||
if (error)
|
||||
break;
|
||||
|
||||
if (data->chainevh)
|
||||
return data->chainevh(mod, what, data->chainarg);
|
||||
else
|
||||
return 0;
|
||||
/*
|
||||
* The drivers loaded in this way are assumed to all
|
||||
* implement the same devclass.
|
||||
*/
|
||||
*dmd->dmd_devclass =
|
||||
devclass_find_internal(dmd->dmd_drivers[0]->name,
|
||||
TRUE);
|
||||
break;
|
||||
|
||||
case MOD_UNLOAD:
|
||||
for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
|
||||
PDEBUG(("Unloading module: driver %s from bus %s",
|
||||
DRIVERNAME(dmd->dmd_drivers[i]),
|
||||
dmd->dmd_busname));
|
||||
error = devclass_delete_driver(bus_devclass,
|
||||
dmd->dmd_drivers[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!error && dmd->dmd_chainevh)
|
||||
error = dmd->dmd_chainevh(mod, what, dmd->dmd_chainarg);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef BUS_DEBUG
|
||||
|
||||
/* the _short versions avoid iteration by not calling anything that prints
|
||||
|
@ -25,7 +25,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: subr_devstat.c,v 1.3 1998/10/06 04:16:07 ken Exp $
|
||||
* $Id: subr_devstat.c,v 1.4 1998/10/14 20:44:05 ken Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -49,7 +49,7 @@ STAILQ_HEAD(devstatlist, devstat) device_statq;
|
||||
* and add it to the queue of devices.
|
||||
*/
|
||||
void
|
||||
devstat_add_entry(struct devstat *ds, char *dev_name,
|
||||
devstat_add_entry(struct devstat *ds, const char *dev_name,
|
||||
int unit_number, u_int32_t block_size,
|
||||
devstat_support_flags flags,
|
||||
devstat_type_flags device_type)
|
||||
|
211
sys/sys/bus.h
211
sys/sys/bus.h
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: bus.h,v 1.5 1998/07/22 08:35:48 dfr Exp $
|
||||
* $Id: bus.h,v 1.6 1998/07/31 09:18:52 dfr Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_BUS_H_
|
||||
@ -43,12 +43,20 @@ typedef struct device_op_desc *device_op_desc_t;
|
||||
|
||||
typedef void driver_intr_t(void*);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* change their type to reflect what sort of devices are underneath.
|
||||
*/
|
||||
typedef enum driver_type {
|
||||
DRIVER_TYPE_TTY,
|
||||
DRIVER_TYPE_BIO,
|
||||
DRIVER_TYPE_NET,
|
||||
DRIVER_TYPE_MISC,
|
||||
MAX_DRIVER_TYPE
|
||||
DRIVER_TYPE_TTY = 1,
|
||||
DRIVER_TYPE_BIO = 2,
|
||||
DRIVER_TYPE_NET = 4,
|
||||
DRIVER_TYPE_CAM = 8,
|
||||
DRIVER_TYPE_MISC = 16,
|
||||
DRIVER_TYPE_FAST = 128
|
||||
} driver_type_t;
|
||||
|
||||
typedef int (*devop_t)(void);
|
||||
@ -80,76 +88,105 @@ enum device_state {
|
||||
*/
|
||||
extern device_t root_bus;
|
||||
extern devclass_t root_devclass;
|
||||
void root_bus_configure(void);
|
||||
void root_bus_configure(void);
|
||||
|
||||
/*
|
||||
* Useful functions for implementing busses.
|
||||
*/
|
||||
int bus_generic_attach(device_t dev);
|
||||
int bus_generic_detach(device_t dev);
|
||||
int bus_generic_shutdown(device_t dev);
|
||||
void bus_generic_print_child(device_t dev, device_t child);
|
||||
int bus_generic_read_ivar(device_t dev, device_t child, int which, u_long *result);
|
||||
int bus_generic_write_ivar(device_t dev, device_t child, int which, u_long value);
|
||||
void *bus_generic_create_intr(device_t dev, device_t child, int irq, driver_intr_t *intr, void *arg);
|
||||
int bus_generic_connect_intr(device_t dev, void *ih);
|
||||
struct resource;
|
||||
|
||||
int bus_generic_activate_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct resource *r);
|
||||
int bus_generic_attach(device_t dev);
|
||||
int bus_generic_deactivate_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct resource *r);
|
||||
int bus_generic_detach(device_t dev);
|
||||
void bus_generic_print_child(device_t dev, device_t child);
|
||||
int bus_generic_read_ivar(device_t dev, device_t child, int which,
|
||||
uintptr_t *result);
|
||||
int bus_generic_resume(device_t dev);
|
||||
int bus_generic_setup_intr(device_t dev, device_t child,
|
||||
struct resource *irq,
|
||||
driver_intr_t *intr, void *arg, void **cookiep);
|
||||
int bus_generic_shutdown(device_t dev);
|
||||
int bus_generic_suspend(device_t dev);
|
||||
int bus_generic_teardown_intr(device_t dev, device_t child,
|
||||
struct resource *irq, void *cookie);
|
||||
int bus_generic_write_ivar(device_t dev, device_t child, int which,
|
||||
uintptr_t value);
|
||||
|
||||
/*
|
||||
* Wrapper functions for the BUS_*_RESOURCE methods to make client code
|
||||
* a little simpler.
|
||||
*/
|
||||
struct resource *bus_alloc_resource(device_t dev, int type, int *rid,
|
||||
u_long start, u_long end, u_long count,
|
||||
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);
|
||||
|
||||
/*
|
||||
* Access functions for device.
|
||||
*/
|
||||
device_t device_get_parent(device_t dev);
|
||||
device_t device_add_child(device_t dev, const char *name,
|
||||
int unit, void *ivars);
|
||||
device_t device_add_child_after(device_t dev, device_t place, const char *name,
|
||||
int unit, void *ivars);
|
||||
device_t device_find_child(device_t dev, const char *classname, int unit);
|
||||
int device_delete_child(device_t dev, device_t child);
|
||||
driver_t *device_get_driver(device_t dev);
|
||||
devclass_t device_get_devclass(device_t dev);
|
||||
int device_set_devclass(device_t dev, const char *classname);
|
||||
int device_set_driver(device_t dev, driver_t *driver);
|
||||
void device_set_desc(device_t dev, const char* desc);
|
||||
const char* device_get_desc(device_t dev);
|
||||
const char* device_get_name(device_t dev);
|
||||
int device_get_unit(device_t dev);
|
||||
void *device_get_softc(device_t dev);
|
||||
void *device_get_ivars(device_t dev);
|
||||
device_state_t device_get_state(device_t dev);
|
||||
void device_enable(device_t dev);
|
||||
void device_disable(device_t dev);
|
||||
void device_busy(device_t dev);
|
||||
void device_unbusy(device_t dev);
|
||||
int device_is_enabled(device_t dev);
|
||||
int device_is_alive(device_t dev); /* did probe succeed? */
|
||||
int device_probe_and_attach(device_t dev);
|
||||
int device_detach(device_t dev);
|
||||
int device_shutdown(device_t dev);
|
||||
device_t device_add_child(device_t dev, const char *name, int unit,
|
||||
void *ivp);
|
||||
device_t device_add_child_after(device_t dev, device_t place,
|
||||
const char *name, int unit, void *ivp);
|
||||
void device_busy(device_t dev);
|
||||
int device_delete_child(device_t dev, device_t child);
|
||||
int device_detach(device_t dev);
|
||||
void device_disable(device_t dev);
|
||||
void device_enable(device_t dev);
|
||||
device_t device_find_child(device_t dev, const char *classname,
|
||||
int unit);
|
||||
const char *device_get_desc(device_t dev);
|
||||
devclass_t device_get_devclass(device_t dev);
|
||||
driver_t *device_get_driver(device_t dev);
|
||||
device_t device_get_parent(device_t dev);
|
||||
void *device_get_ivars(device_t dev);
|
||||
const char *device_get_name(device_t dev);
|
||||
void *device_get_softc(device_t dev);
|
||||
device_state_t device_get_state(device_t dev);
|
||||
int device_get_unit(device_t dev);
|
||||
int device_is_enabled(device_t dev);
|
||||
int device_is_alive(device_t dev); /* did probe succeed? */
|
||||
void device_print_prettyname(device_t dev);
|
||||
int device_probe_and_attach(device_t dev);
|
||||
void device_set_desc(device_t dev, const char* desc);
|
||||
int device_set_devclass(device_t dev, const char *classname);
|
||||
int device_set_driver(device_t dev, driver_t *driver);
|
||||
int device_shutdown(device_t dev);
|
||||
void device_unbusy(device_t dev);
|
||||
|
||||
/*
|
||||
* Access functions for devclass.
|
||||
*/
|
||||
devclass_t devclass_find(const char *classname);
|
||||
int devclass_add_driver(devclass_t dc, driver_t *driver);
|
||||
int devclass_delete_driver(devclass_t dc, driver_t *driver);
|
||||
driver_t *devclass_find_driver(devclass_t dc, const char *classname);
|
||||
const char *devclass_get_name(devclass_t dc);
|
||||
device_t devclass_get_device(devclass_t dc, int unit);
|
||||
void *devclass_get_softc(devclass_t dc, int unit);
|
||||
int devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp);
|
||||
int devclass_get_maxunit(devclass_t dc);
|
||||
int devclass_add_driver(devclass_t dc, driver_t *driver);
|
||||
int devclass_delete_driver(devclass_t dc, driver_t *driver);
|
||||
devclass_t devclass_find(const char *classname);
|
||||
driver_t *devclass_find_driver(devclass_t dc, const char *classname);
|
||||
const char *devclass_get_name(devclass_t dc);
|
||||
device_t devclass_get_device(devclass_t dc, int unit);
|
||||
void *devclass_get_softc(devclass_t dc, int unit);
|
||||
int devclass_get_devices(devclass_t dc, device_t **listp, int *countp);
|
||||
int devclass_get_maxunit(devclass_t dc);
|
||||
|
||||
/*
|
||||
* Access functions for device resources.
|
||||
*/
|
||||
int resource_int_value(const char *name, int unit,
|
||||
char *resname, int *result);
|
||||
int resource_long_value(const char *name, int unit,
|
||||
char *resname, long *result);
|
||||
int resource_string_value(const char *name, int unit,
|
||||
char *resname, char **result);
|
||||
int resource_query_string(int i, char *resname, char *value);
|
||||
char *resource_query_name(int i);
|
||||
int resource_query_unit(int i);
|
||||
int resource_int_value(const char *name, int unit, char *resname,
|
||||
int *result);
|
||||
int resource_long_value(const char *name, int unit, char *resname,
|
||||
long *result);
|
||||
int resource_string_value(const char *name, int unit, char *resname,
|
||||
char **result);
|
||||
int resource_query_string(int i, char *resname, char *value);
|
||||
char *resource_query_name(int i);
|
||||
int resource_query_unit(int i);
|
||||
|
||||
/*
|
||||
* Shorthand for constructing method tables.
|
||||
@ -162,28 +199,52 @@ int resource_query_unit(int i);
|
||||
#include "device_if.h"
|
||||
#include "bus_if.h"
|
||||
|
||||
#ifdef _SYS_MODULE_H_
|
||||
struct module;
|
||||
|
||||
int driver_module_handler(struct module *, int, void *);
|
||||
|
||||
/*
|
||||
* Module support for automatically adding drivers to busses.
|
||||
*/
|
||||
struct driver_module_data {
|
||||
modeventhand_t chainevh;
|
||||
void* chainarg;
|
||||
const char* busname;
|
||||
driver_t* driver;
|
||||
devclass_t* devclass;
|
||||
int (*dmd_chainevh)(struct module *, int, void *);
|
||||
void *dmd_chainarg;
|
||||
const char *dmd_busname;
|
||||
driver_t **dmd_drivers;
|
||||
int dmd_ndrivers;
|
||||
devclass_t *dmd_devclass;
|
||||
};
|
||||
|
||||
int driver_module_handler(module_t, modeventtype_t, void*);
|
||||
|
||||
#define DRIVER_MODULE(name, busname, driver, devclass, evh, arg) \
|
||||
\
|
||||
static driver_t *name##_##busname##_driver_list[] = { &driver }; \
|
||||
static struct driver_module_data name##_##busname##_driver_mod = { \
|
||||
evh, arg, \
|
||||
#busname, \
|
||||
&driver, \
|
||||
&devclass, \
|
||||
name##_##busname##_driver_list, \
|
||||
(sizeof name##_##busname##_driver_list) / \
|
||||
(sizeof name##_##busname##_driver_list[0]), \
|
||||
&devclass \
|
||||
}; \
|
||||
\
|
||||
static moduledata_t name##_##busname##_mod = { \
|
||||
#busname "/" #name, \
|
||||
driver_module_handler, \
|
||||
&name##_##busname##_driver_mod \
|
||||
}; \
|
||||
DECLARE_MODULE(name##_##busname, name##_##busname##_mod, \
|
||||
SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
|
||||
|
||||
#define MULTI_DRIVER_MODULE(name, busname, drivers, devclass, evh, arg) \
|
||||
\
|
||||
static driver_t name##_##busname##_driver_list[] = drivers; \
|
||||
static struct driver_module_data name##_##busname##_driver_mod = { \
|
||||
evh, arg, \
|
||||
#busname, \
|
||||
name##_##busname##_driver_list, \
|
||||
(sizeof name##_##busname##_driver_list) / \
|
||||
(sizeof name##_##busname##_driver_list[0]), \
|
||||
&devclass \
|
||||
}; \
|
||||
\
|
||||
static moduledata_t name##_##busname##_mod = { \
|
||||
@ -204,7 +265,15 @@ static struct cdevsw_module_data name##_##busname##_cdevsw_mod = { \
|
||||
DRIVER_MODULE(name, busname, driver, devclass, \
|
||||
cdevsw_module_handler, &name##_##busname##_cdevsw_mod)
|
||||
|
||||
#endif
|
||||
#define BDEV_DRIVER_MODULE(name, busname, driver, devclass, \
|
||||
bmajor, cmajor, devsw, evh, arg) \
|
||||
\
|
||||
static struct bdevsw_module_data name##_##busname##_bdevsw_mod = { \
|
||||
evh, arg, makedev(bmajor, 0), makedev(cmajor, 0), &devsw \
|
||||
}; \
|
||||
\
|
||||
DRIVER_MODULE(name, busname, driver, devclass, \
|
||||
bdevsw_module_handler, &name##_##busname##_bdevsw_mod)
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: bus_private.h,v 1.2 1998/06/14 13:46:10 dfr Exp $
|
||||
* $Id: bus_private.h,v 1.3 1998/07/22 08:35:50 dfr Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_BUS_PRIVATE_H_
|
||||
@ -54,7 +54,7 @@ typedef enum {
|
||||
RES_INT, RES_STRING, RES_LONG
|
||||
} resource_type;
|
||||
|
||||
struct resource {
|
||||
struct config_resource {
|
||||
char *name;
|
||||
resource_type type;
|
||||
union {
|
||||
@ -68,7 +68,7 @@ struct config_device {
|
||||
char *name; /* e.g. "lpt", "wdc" etc */
|
||||
int unit;
|
||||
int resource_count;
|
||||
struct resource *resources;
|
||||
struct config_resource *resources;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)conf.h 8.5 (Berkeley) 1/9/95
|
||||
* $Id: conf.h,v 1.46 1998/11/08 12:39:07 dfr Exp $
|
||||
* $Id: conf.h,v 1.47 1998/11/10 21:45:18 dfr Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CONF_H_
|
||||
@ -199,24 +199,21 @@ d_close_t nullclose;
|
||||
l_read_t l_noread;
|
||||
l_write_t l_nowrite;
|
||||
|
||||
/*
|
||||
* XXX This is ugly.
|
||||
*/
|
||||
#ifdef _SYS_MODULE_H_
|
||||
struct module;
|
||||
|
||||
struct cdevsw_module_data {
|
||||
modeventhand_t chainevh; /* next event handler in chain */
|
||||
void* chainarg; /* arg for next event handler */
|
||||
dev_t dev; /* device major to use */
|
||||
struct cdevsw* cdevsw; /* device functions */
|
||||
int (*chainevh)(struct module *, int, void *); /* next handler */
|
||||
void *chainarg; /* arg for next event handler */
|
||||
dev_t dev; /* device major to use */
|
||||
struct cdevsw *cdevsw; /* device functions */
|
||||
};
|
||||
|
||||
struct bdevsw_module_data {
|
||||
modeventhand_t chainevh; /* next event handler in chain */
|
||||
void* chainarg; /* arg for next event handler */
|
||||
int bdev; /* device major to use */
|
||||
int cdev; /* device major to use */
|
||||
struct cdevsw* cdevsw; /* device functions */
|
||||
int (*chainevh)(struct module *, int, void *); /* next handler */
|
||||
void *chainarg; /* arg for next event handler */
|
||||
int bdev; /* device major to use */
|
||||
int cdev; /* device major to use */
|
||||
struct cdevsw *cdevsw; /* device functions */
|
||||
};
|
||||
|
||||
#define CDEV_MODULE(name, major, devsw, evh, arg) \
|
||||
@ -244,10 +241,8 @@ static moduledata_t name##_mod = { \
|
||||
}; \
|
||||
DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+cdev)
|
||||
|
||||
int cdevsw_module_handler __P((module_t mod, modeventtype_t what, void* arg));
|
||||
int bdevsw_module_handler __P((module_t mod, modeventtype_t what, void* arg));
|
||||
|
||||
#endif /* _SYS_MODULE_H_ */
|
||||
int cdevsw_module_handler __P((struct module *mod, int what, void *arg));
|
||||
int bdevsw_module_handler __P((struct module *mod, int what, void *arg));
|
||||
|
||||
int cdevsw_add __P((dev_t *descrip,struct cdevsw *new,struct cdevsw **old));
|
||||
void cdevsw_add_generic __P((int bdev, int cdev, struct cdevsw *cdevsw));
|
||||
|
@ -25,7 +25,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: devicestat.h,v 1.1 1998/09/15 08:16:17 gibbs Exp $
|
||||
* $Id: devicestat.h,v 1.2 1998/09/20 00:10:58 ken Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DEVICESTAT_H
|
||||
@ -182,7 +182,7 @@ struct devstat {
|
||||
};
|
||||
|
||||
#ifdef KERNEL
|
||||
void devstat_add_entry(struct devstat *ds, char *dev_name,
|
||||
void devstat_add_entry(struct devstat *ds, const char *dev_name,
|
||||
int unit_number, u_int32_t block_size,
|
||||
devstat_support_flags flags,
|
||||
devstat_type_flags device_type);
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)conf.h 8.5 (Berkeley) 1/9/95
|
||||
* $Id: conf.h,v 1.46 1998/11/08 12:39:07 dfr Exp $
|
||||
* $Id: conf.h,v 1.47 1998/11/10 21:45:18 dfr Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CONF_H_
|
||||
@ -199,24 +199,21 @@ d_close_t nullclose;
|
||||
l_read_t l_noread;
|
||||
l_write_t l_nowrite;
|
||||
|
||||
/*
|
||||
* XXX This is ugly.
|
||||
*/
|
||||
#ifdef _SYS_MODULE_H_
|
||||
struct module;
|
||||
|
||||
struct cdevsw_module_data {
|
||||
modeventhand_t chainevh; /* next event handler in chain */
|
||||
void* chainarg; /* arg for next event handler */
|
||||
dev_t dev; /* device major to use */
|
||||
struct cdevsw* cdevsw; /* device functions */
|
||||
int (*chainevh)(struct module *, int, void *); /* next handler */
|
||||
void *chainarg; /* arg for next event handler */
|
||||
dev_t dev; /* device major to use */
|
||||
struct cdevsw *cdevsw; /* device functions */
|
||||
};
|
||||
|
||||
struct bdevsw_module_data {
|
||||
modeventhand_t chainevh; /* next event handler in chain */
|
||||
void* chainarg; /* arg for next event handler */
|
||||
int bdev; /* device major to use */
|
||||
int cdev; /* device major to use */
|
||||
struct cdevsw* cdevsw; /* device functions */
|
||||
int (*chainevh)(struct module *, int, void *); /* next handler */
|
||||
void *chainarg; /* arg for next event handler */
|
||||
int bdev; /* device major to use */
|
||||
int cdev; /* device major to use */
|
||||
struct cdevsw *cdevsw; /* device functions */
|
||||
};
|
||||
|
||||
#define CDEV_MODULE(name, major, devsw, evh, arg) \
|
||||
@ -244,10 +241,8 @@ static moduledata_t name##_mod = { \
|
||||
}; \
|
||||
DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+cdev)
|
||||
|
||||
int cdevsw_module_handler __P((module_t mod, modeventtype_t what, void* arg));
|
||||
int bdevsw_module_handler __P((module_t mod, modeventtype_t what, void* arg));
|
||||
|
||||
#endif /* _SYS_MODULE_H_ */
|
||||
int cdevsw_module_handler __P((struct module *mod, int what, void *arg));
|
||||
int bdevsw_module_handler __P((struct module *mod, int what, void *arg));
|
||||
|
||||
int cdevsw_add __P((dev_t *descrip,struct cdevsw *new,struct cdevsw **old));
|
||||
void cdevsw_add_generic __P((int bdev, int cdev, struct cdevsw *cdevsw));
|
||||
|
@ -23,31 +23,31 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: module.h,v 1.3 1998/06/10 10:57:29 dfr Exp $
|
||||
* $Id: module.h,v 1.4 1998/10/09 23:05:45 peter Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_MODULE_H_
|
||||
#define _SYS_MODULE_H_
|
||||
|
||||
typedef enum {
|
||||
typedef enum modeventtype {
|
||||
MOD_LOAD,
|
||||
MOD_UNLOAD,
|
||||
MOD_SHUTDOWN
|
||||
} modeventtype_t;
|
||||
|
||||
struct module;
|
||||
typedef struct module *module_t;
|
||||
typedef struct module *module_t;
|
||||
|
||||
typedef int (*modeventhand_t)(module_t mod, modeventtype_t what, void *arg);
|
||||
typedef int (*modeventhand_t)(module_t mod, int /*modeventtype_t*/ what,
|
||||
void *arg);
|
||||
|
||||
/*
|
||||
* Struct for registering modules statically via SYSINIT.
|
||||
*/
|
||||
typedef struct moduledata {
|
||||
char* name; /* module name */
|
||||
modeventhand_t evhand; /* event handler */
|
||||
void* priv; /* extra data */
|
||||
void* _file; /* private; used by linker */
|
||||
char *name; /* module name */
|
||||
modeventhand_t evhand; /* event handler */
|
||||
void *priv; /* extra data */
|
||||
void *_file; /* private; used by linker */
|
||||
} moduledata_t;
|
||||
|
||||
#ifdef KERNEL
|
||||
|
Loading…
Reference in New Issue
Block a user