PERFORCE change 122730 for review
Maxim Zhuravlev
thioretic at FreeBSD.org
Mon Jul 2 17:41:43 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=122730
Change 122730 by thioretic at thioretic on 2007/07/02 17:41:01
Start to introduce stack to newbus
Affected files ...
.. //depot/projects/soc2007/thioretic_gidl/TODO#4 edit
.. //depot/projects/soc2007/thioretic_gidl/kern/subr_bus.c#2 edit
.. //depot/projects/soc2007/thioretic_gidl/sys/bus.h#3 edit
Differences ...
==== //depot/projects/soc2007/thioretic_gidl/TODO#4 (text+ko) ====
@@ -45,4 +45,12 @@
# ...
3. Implement *drivers* stack namespace.
SOLUTION: define stack namespace methods suitable for drivers
- FILE(S) AFFECTED: kern/sns_drivers.c + FILE(S) AFFECTED: kern/sns_drivers.c
+ a. ADD
+ a.1.drivers
+ SOLUTION: modify newbus so that it's aware about stacked
+ structure of a device.
+ FILE(S) AFFECTED: sys/bus.h, kern/subr_bus.c
+ # since now internally (and externally) for newbus, driver is
+ # not just kernel object class to be compiled into device, but
+ # also has flags, default driversops (TODO)...
==== //depot/projects/soc2007/thioretic_gidl/kern/subr_bus.c#2 (text+ko) ====
@@ -63,7 +63,8 @@
*/
typedef struct driverlink *driverlink_t;
struct driverlink {
- kobj_class_t driver;
+// kobj_class_t driver;
+ drv_internal_t driver;
TAILQ_ENTRY(driverlink) link; /* list of drivers in devclass */
};
@@ -107,8 +108,9 @@
/*
* Details of this device.
*/
- driver_t *driver; /**< current driver */
- devclass_t devclass; /**< current device class */
+// driver_t *driver; /**< current driver */
+ driver_list_t drivers[DRV_LEVELS]; /**< list of all drivers in stack*/
+ devclass_t devclass; /**< current device class */ /*TODO*/
int unit; /**< current unit number */
char* nameunit; /**< name+unit e.g. foodev0 */
char* desc; /**< driver specific description */
@@ -239,8 +241,10 @@
{
device_t dev = (device_t)arg1;
const char *value;
- char *buf;
+ char *buf, *tmpbuf;
int error;
+ int level;
+ driverlink_t dl;
buf = NULL;
switch (arg2) {
@@ -248,7 +252,27 @@
value = dev->desc ? dev->desc : "";
break;
case DEVICE_SYSCTL_DRIVER:
- value = dev->driver ? dev->driver->name : "";
+ value = buf = malloc(1024, M_BUS, M_WAITOK | M_ZERO);
+ buf[0]='\0';
+ for (level=DRV_LOWEST; level<=DRV_TOPMOST; level++){
+ switch(level){
+ case DRV_LOWEST: tmpbuf="LOWEST:"; break;
+ case DRV_LOWER: tmpbuf="LOWER:"; break;
+ case DRV_MIDDLE: tmpbuf="MIDDLE:"; break;
+ case DRV_UPPER: tmpbuf="UPPER:"; break;
+ case DRV_TOPMOST: tmpbuf="TOPMOST:"; break;
+ }
+ if (strlen(tmpbuf)+strlen(buf)>1023) break;
+ TAILQ_FOREACH(dl,&((dev->drivers)[level]),link){
+ if(strlen(dl->driver->devops->name)+strlen(buf)>1022)
+ break;
+ strcat(buf,dl->driver->devops->name);
+ strcat(buf,",");
+ }
+ buf[strlen(buf)]='\0';
+ strcat(buf,"\n");
+ }
+ //value = dev->driver ? dev->driver->name : ""; /**TODO*/
break;
case DEVICE_SYSCTL_LOCATION:
value = buf = malloc(1024, M_BUS, M_WAITOK | M_ZERO);
@@ -287,10 +311,10 @@
OID_AUTO, "%desc", CTLFLAG_RD,
dev, DEVICE_SYSCTL_DESC, device_sysctl_handler, "A",
"device description");
- SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
+ SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree), /**TODO*/
OID_AUTO, "%driver", CTLFLAG_RD,
dev, DEVICE_SYSCTL_DRIVER, device_sysctl_handler, "A",
- "device driver name");
+ "device stacked drivers names");
SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
OID_AUTO, "%location", CTLFLAG_RD,
dev, DEVICE_SYSCTL_LOCATION, device_sysctl_handler, "A",
@@ -838,12 +862,12 @@
* @param driver the driver to register
*/
int
-devclass_add_driver(devclass_t dc, driver_t *driver)
+devclass_add_driver(devclass_t dc, /*driver_t **/ drv_internal_t driver) /**TODO*/
{
driverlink_t dl;
int i;
- PDEBUG(("%s", DRIVERNAME(driver)));
+ PDEBUG(("%s", DRIVERNAME(driver->devops)));
dl = malloc(sizeof *dl, M_BUS, M_NOWAIT|M_ZERO);
if (!dl)
@@ -855,12 +879,12 @@
* goes. This means we can safely use static methods and avoids a
* double-free in devclass_delete_driver.
*/
- kobj_class_compile((kobj_class_t) driver);
+ kobj_class_compile((kobj_class_t) (driver->devops));
/*
* Make sure the devclass which the driver is implementing exists.
*/
- devclass_find_internal(driver->name, 0, TRUE);
+ devclass_find_internal(driver->devops->name, 0, TRUE);
dl->driver = driver;
TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
@@ -877,6 +901,23 @@
return (0);
}
+int
+is_device_driver (device_t dev, drv_internal_t driver){
+ int level;
+ driverlink_t dl;
+
+ switch ((driver->flags)&(DR_LOWEST|DR_LOWER|DR_MIDDLE|DR_UPPER|DR_TOPMOST)) {
+ case DR_LOWEST: level=DRV_LOWEST; break;
+ case DR_LOWER: level=DRV_LOWER; break;
+ case DR_MIDDLE: level=DRV_MIDDLE; break;
+ case DR_UPPER: level=DRV_UPPER; break;
+ case DR_TOPMOST: level=DRV_TOPMOST; break;
+ }
+ TAILQ_FOREACH(dl,&((dev->drivers)[level]),link){
+ if (dl->driver==driver) return(1);
+ }
+ return(0);
+}
/**
* @brief Delete a device driver from a device class
*
@@ -892,15 +933,16 @@
* @param driver the driver to unregister
*/
int
-devclass_delete_driver(devclass_t busclass, driver_t *driver)
+devclass_delete_driver(devclass_t busclass, /*driver_t **/drv_internal_t driver)
+/**TODO*/
{
- devclass_t dc = devclass_find(driver->name);
+ devclass_t dc = devclass_find(driver->devops->name);
driverlink_t dl;
device_t dev;
int i;
int error;
- PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
+ PDEBUG(("%s from devclass %s", driver->devops->name, DEVCLANAME(busclass)));
if (!dc)
return (0);
@@ -914,7 +956,7 @@
}
if (!dl) {
- PDEBUG(("%s not found in %s list", driver->name,
+ PDEBUG(("%s not found in %s list", driver->devops->name,
busclass->name));
return (ENOENT);
}
@@ -932,7 +974,8 @@
for (i = 0; i < dc->maxunit; i++) {
if (dc->devices[i]) {
dev = dc->devices[i];
- if (dev->driver == driver && dev->parent &&
+ if (/*dev->driver == driver*/
+ is_device_driver(dev,driver) && dev->parent &&
dev->parent->devclass == busclass) {
if ((error = device_detach(dev)) != 0)
return (error);
@@ -947,7 +990,7 @@
/* XXX: kobj_mtx */
driver->refs--;
if (driver->refs == 0)
- kobj_class_free((kobj_class_t) driver);
+ kobj_class_free((kobj_class_t) (driver->devops));
bus_data_generation_update();
return (0);
@@ -967,15 +1010,15 @@
* @param driver the driver to unregister
*/
int
-devclass_quiesce_driver(devclass_t busclass, driver_t *driver)
+devclass_quiesce_driver(devclass_t busclass, /*driver_t **/ drv_internal_t driver) /**TODO*/
{
- devclass_t dc = devclass_find(driver->name);
+ devclass_t dc = devclass_find(driver->devops->name);
driverlink_t dl;
device_t dev;
int i;
int error;
- PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
+ PDEBUG(("%s from devclass %s", driver->devops->name, DEVCLANAME(busclass)));
if (!dc)
return (0);
@@ -989,7 +1032,7 @@
}
if (!dl) {
- PDEBUG(("%s not found in %s list", driver->name,
+ PDEBUG(("%s not found in %s list", driver->devops->name,
busclass->name));
return (ENOENT);
}
@@ -1007,7 +1050,8 @@
for (i = 0; i < dc->maxunit; i++) {
if (dc->devices[i]) {
dev = dc->devices[i];
- if (dev->driver == driver && dev->parent &&
+ if (/*dev->driver == driver*/
+ is_device_driver(dev,driver) && dev->parent &&
dev->parent->devclass == busclass) {
if ((error = device_quiesce(dev)) != 0)
return (error);
@@ -1022,14 +1066,14 @@
* @internal
*/
static driverlink_t
-devclass_find_driver_internal(devclass_t dc, const char *classname)
+devclass_find_driver_internal(devclass_t dc, const char *classname) /**TODO*/
{
driverlink_t dl;
PDEBUG(("%s in devclass %s", classname, DEVCLANAME(dc)));
TAILQ_FOREACH(dl, &dc->drivers, link) {
- if (!strcmp(dl->driver->name, classname))
+ if (!strcmp(dl->driver->devops->name, classname))
return (dl);
}
@@ -1047,8 +1091,8 @@
* @param dc the devclass to search
* @param classname the driver name to search for
*/
-kobj_class_t
-devclass_find_driver(devclass_t dc, const char *classname)
+/*kobj_class_t*/ drv_internal_t
+devclass_find_driver(devclass_t dc, const char *classname) /**TODO*/
{
driverlink_t dl;
@@ -1164,16 +1208,17 @@
* @retval ENOMEM the array allocation failed
*/
int
-devclass_get_drivers(devclass_t dc, driver_t ***listp, int *countp)
+devclass_get_drivers(devclass_t dc, /*driver_t **/
+ drv_internal_t **listp, int *countp) /**TODO*/
{
driverlink_t dl;
- driver_t **list;
+ /*driver_t **/ drv_internal_t *list;
int count;
count = 0;
TAILQ_FOREACH(dl, &dc->drivers, link)
count++;
- list = malloc(count * sizeof(driver_t *), M_TEMP, M_NOWAIT);
+ list = malloc(count * sizeof(/*driver_t **/drv_internal_t), M_TEMP, M_NOWAIT);
if (list == NULL)
return (ENOMEM);
@@ -1429,10 +1474,11 @@
* @returns the new device
*/
static device_t
-make_device(device_t parent, const char *name, int unit)
+make_device(device_t parent, const char *name, int unit) /**TODO*/
{
device_t dev;
devclass_t dc;
+ int level;
PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit));
@@ -1454,7 +1500,10 @@
dev->parent = parent;
TAILQ_INIT(&dev->children);
kobj_init((kobj_t) dev, &null_class);
- dev->driver = NULL;
+// dev->driver = NULL;
+ for (level=DRV_LOWEST;level<=DRV_TOPMOST;level++){
+ TAILQ_INIT(&((dev->drivers)[level]));
+ }
dev->devclass = NULL;
dev->unit = unit;
dev->nameunit = NULL;
@@ -1661,7 +1710,7 @@
* @internal
*/
static driverlink_t
-first_matching_driver(devclass_t dc, device_t dev)
+first_matching_driver(devclass_t dc, device_t dev) /**TODO*/
{
if (dev->devclass)
return (devclass_find_driver_internal(dc, dev->devclass->name));
@@ -1672,12 +1721,12 @@
* @internal
*/
static driverlink_t
-next_matching_driver(devclass_t dc, device_t dev, driverlink_t last)
+next_matching_driver(devclass_t dc, device_t dev, driverlink_t last) /**TODO*/
{
if (dev->devclass) {
driverlink_t dl;
for (dl = TAILQ_NEXT(last, link); dl; dl = TAILQ_NEXT(dl, link))
- if (!strcmp(dev->devclass->name, dl->driver->name))
+ if (!strcmp(dev->devclass->name, dl->driver->devops->name))
return (dl);
return (NULL);
}
@@ -1688,7 +1737,7 @@
* @internal
*/
static int
-device_probe_child(device_t dev, device_t child)
+device_probe_child(device_t dev, device_t child) /*TODO*/
{
devclass_t dc;
driverlink_t best = 0;
@@ -1706,20 +1755,22 @@
* If the state is already probed, then return. However, don't
* return if we can rebid this object.
*/
- if (child->state == DS_ALIVE && (child->flags & DF_REBID) == 0)
+ if (/*child->state == DS_ALIVE && */(child->flags & DF_REBID) == 0)
return (0);
for (; dc; dc = dc->parent) {
for (dl = first_matching_driver(dc, child);
dl;
dl = next_matching_driver(dc, child, dl)) {
- PDEBUG(("Trying %s", DRIVERNAME(dl->driver)));
+ if ((child->state == DS_ALIVE && (dl->driver->flags & (DR_LOWEST|DR_STACKAWARE))) || (child->state != DS_ALIVE && (dl->driver->flags & ~(DR_LOWEST|DR_STACKAWARE))))
+ continue;
+ PDEBUG(("Trying %s", DRIVERNAME(dl->driver->devops)));
device_set_driver(child, dl->driver);
if (!hasclass)
- device_set_devclass(child, dl->driver->name);
+ device_set_devclass(child, dl->driver->devops->name);
/* Fetch any flags for the device before probing. */
- resource_int_value(dl->driver->name, child->unit,
+ resource_int_value(dl->driver->devops->name, child->unit,
"flags", &child->devflags);
result = DEVICE_PROBE(child);
@@ -1795,9 +1846,9 @@
/* Set the winning driver, devclass, and flags. */
if (!child->devclass)
- device_set_devclass(child, best->driver->name);
+ device_set_devclass(child, best->driver->devops->name);
device_set_driver(child, best->driver);
- resource_int_value(best->driver->name, child->unit,
+ resource_int_value(best->driver->devops->name, child->unit,
"flags", &child->devflags);
if (pri < 0) {
@@ -1878,7 +1929,7 @@
* is no driver currently attached
*/
driver_t *
-device_get_driver(device_t dev)
+device_get_driver(device_t dev) /*TODO*/
{
return (dev->driver);
}
@@ -2258,7 +2309,7 @@
* @retval ENOMEM a memory allocation failure occurred
*/
int
-device_set_driver(device_t dev, driver_t *driver)
+device_set_driver(device_t dev, driver_t *driver) /*TODO*/
{
if (dev->state >= DS_ATTACHED)
return (EBUSY);
@@ -2319,7 +2370,7 @@
* @retval non-zero some other unix error code
*/
int
-device_probe_and_attach(device_t dev)
+device_probe_and_attach(device_t dev) /*TODO*/
{
int error;
@@ -2368,7 +2419,7 @@
* @retval non-zero some other unix error code
*/
int
-device_attach(device_t dev)
+device_attach(device_t dev) /*TODO*/
{
int error;
@@ -2408,7 +2459,7 @@
* @retval non-zero some other unix error code
*/
int
-device_detach(device_t dev)
+device_detach(device_t dev) /*TODO*/
{
int error;
@@ -2855,7 +2906,7 @@
* devclass.
*/
int
-bus_generic_probe(device_t dev)
+bus_generic_probe(device_t dev) /*TODO*/
{
devclass_t dc = dev->devclass;
driverlink_t dl;
@@ -2875,7 +2926,7 @@
* children.
*/
int
-bus_generic_attach(device_t dev)
+bus_generic_attach(device_t dev) /*TODO*/
{
device_t child;
@@ -3075,7 +3126,7 @@
* and then calls device_probe_and_attach() for each unattached child.
*/
void
-bus_generic_driver_added(device_t dev, driver_t *driver)
+bus_generic_driver_added(device_t dev, driver_t *driver) /*TODO*/
{
device_t child;
@@ -3095,7 +3146,7 @@
*/
int
bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
- int flags, driver_intr_t *intr, void *arg, void **cookiep)
+ int flags, driver_intr_t *intr, void *arg, void **cookiep) /*TODO*/
{
/* Propagate up the bus hierarchy until someone handles it. */
if (dev->parent)
@@ -3408,7 +3459,7 @@
*/
int
bus_setup_intr(device_t dev, struct resource *r, int flags,
- driver_intr_t handler, void *arg, void **cookiep)
+ driver_intr_t handler, void *arg, void **cookiep) /*TODO*/
{
int error;
@@ -3619,7 +3670,7 @@
return (-1);
}
-static kobj_method_t root_methods[] = {
+static kobj_method_t root_methods[] = { /*TODO*/
/* Device interface */
KOBJMETHOD(device_shutdown, bus_generic_shutdown),
KOBJMETHOD(device_suspend, bus_generic_suspend),
@@ -3645,7 +3696,7 @@
devclass_t root_devclass;
static int
-root_bus_module_handler(module_t mod, int what, void* arg)
+root_bus_module_handler(module_t mod, int what, void* arg) /*TODO*/
{
switch (what) {
case MOD_LOAD:
@@ -3704,7 +3755,7 @@
* driver_module_data structure pointed to by @p arg
*/
int
-driver_module_handler(module_t mod, int what, void *arg)
+driver_module_handler(module_t mod, int what, void *arg) /*TODO*/
{
int error;
struct driver_module_data *dmd;
==== //depot/projects/soc2007/thioretic_gidl/sys/bus.h#3 (text+ko) ====
@@ -472,31 +472,56 @@
*/
#include "device_if.h"
#include "bus_if.h"
+#include <sys/types.h>
struct module;
int driver_module_handler(struct module *, int, void *);
+#define DRV_LEVELS 5
+#define DRV_LOWEST 0
+#define DRV_LOWER 1
+#define DRV_MIDDLE 2
+#define DRV_UPPER 3
+#define DRV_TOPMOST 4
/**
* Module support for automatically adding drivers to busses.
*/
+struct drv_internal {
+ kobj_class_t devops;
+#define DR_STACKAWARE 1
+#define DR_LOWEST 2
+#define DR_LOWER 4
+#define DR_MIDDLE 8
+#define DR_UPPER 16
+#define DR_TOPMOST 32
+ uint32_t flags;
+};
+
+typedef struct drv_internal *drv_internal_t;
+
struct driver_module_data {
int (*dmd_chainevh)(struct module *, int, void *);
void *dmd_chainarg;
const char *dmd_busname;
- kobj_class_t dmd_driver;
+// kobj_class_t dmd_driver;
+ drv_internal_t dmd_driver;
devclass_t *dmd_devclass;
- int stackaware;
};
#define DRIVER_MODULE(name, busname, driver, devclass, evh, arg) \
\
+static struct drv_internal name##_##busname##_intnl { \
+ (kobj_class_t) &driver, \
+ LOWEST \
+}; \
+ \
static struct driver_module_data name##_##busname##_driver_mod = { \
evh, arg, \
#busname, \
- (kobj_class_t) &driver, \
- &devclass, \
- 0 \
+/* (kobj_class_t) &driver, \ */
+ &name##_##busname##_intnl, \
+ &devclass \
}; \
\
static moduledata_t name##_##busname##_mod = { \
More information about the p4-projects
mailing list