From owner-p4-projects@FreeBSD.ORG Mon Jul 2 17:41:42 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 90A6416A41F; Mon, 2 Jul 2007 17:41:42 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 5B4C516A46C for ; Mon, 2 Jul 2007 17:41:42 +0000 (UTC) (envelope-from thioretic@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 47CEB13C4CA for ; Mon, 2 Jul 2007 17:41:42 +0000 (UTC) (envelope-from thioretic@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l62Hfghl073451 for ; Mon, 2 Jul 2007 17:41:42 GMT (envelope-from thioretic@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l62HffXs073448 for perforce@freebsd.org; Mon, 2 Jul 2007 17:41:41 GMT (envelope-from thioretic@FreeBSD.org) Date: Mon, 2 Jul 2007 17:41:41 GMT Message-Id: <200707021741.l62HffXs073448@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to thioretic@FreeBSD.org using -f From: Maxim Zhuravlev To: Perforce Change Reviews Cc: Subject: PERFORCE change 122730 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Jul 2007 17:41:43 -0000 http://perforce.freebsd.org/chv.cgi?CH=122730 Change 122730 by thioretic@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 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 = { \