From owner-p4-projects@FreeBSD.ORG Thu Jul 12 19:41:46 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 E755D16A46D; Thu, 12 Jul 2007 19:41:45 +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 AF29116A468 for ; Thu, 12 Jul 2007 19:41:45 +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 9F10513C4C1 for ; Thu, 12 Jul 2007 19:41:45 +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 l6CJfjnY097063 for ; Thu, 12 Jul 2007 19:41:45 GMT (envelope-from thioretic@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l6CJfjl6097058 for perforce@freebsd.org; Thu, 12 Jul 2007 19:41:45 GMT (envelope-from thioretic@FreeBSD.org) Date: Thu, 12 Jul 2007 19:41:45 GMT Message-Id: <200707121941.l6CJfjl6097058@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 123400 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: Thu, 12 Jul 2007 19:41:46 -0000 http://perforce.freebsd.org/chv.cgi?CH=123400 Change 123400 by thioretic@thioretic on 2007/07/12 19:41:00 TODO: bus_generic_* and resource_* stuff , cleanups, including proper naming :) (probably they should go first), locking and IO requests processing stuff. DONE: device_set_driver semantics. ALSO: my thoughts about drv_compat_ctrl_driver should now be more obvious. Affected files ... .. //depot/projects/soc2007/thioretic_gidl/TODO#12 edit .. //depot/projects/soc2007/thioretic_gidl/kern/subr_bus.c#13 edit .. //depot/projects/soc2007/thioretic_gidl/sys/bus.h#6 edit Differences ... ==== //depot/projects/soc2007/thioretic_gidl/TODO#12 (text+ko) ==== @@ -107,10 +107,6 @@ # a driver not just process, but also produce and destroy an io request. # Inportant note: from above-said one can see, that since now newbus # won't be a tree, it will be a graph! - # New logic: - # probe/attach: the dev->driver is set to drv_compat(driver) to be - # probed and attached. - # detach: will detach DRV_LOWEST driver and all filters consequently. # As for functional devices (let's call like this all drivers with # DR_REQDEV flag set), the following scenario looks reasonable: # @@ -132,4 +128,11 @@ # device_set_driver_softc(). # All these return softc of a specified driver for a device. Old functions # (those without '_driver_') return softc of DRV_LOWEST driver (as expected). - + a.1.5 device_set_driver semantics + SOLUTION: add DS_RAW state value && add per-pdrv_compat state + FILE(S) AFFECTED: kern/subr_bus.c, sys/bus.h + # As now device hosts many drivers, dev->driver should point to currently + # probed/attached/.. driver. If driver to be set to is DR_LOWEST not equal + # to that already in stack or is NULL, the whole driver configuration is + # destroyed. Device won't process any i/o requests till its state is set + # to DS_ALIVE (i.e. there is no DS_RAW or other drivers in stack). ==== //depot/projects/soc2007/thioretic_gidl/kern/subr_bus.c#13 (text+ko) ==== @@ -87,6 +87,7 @@ void *softc; #define DF_EXTERNALSOFTC 1 /* softc not allocated by us */ int flags; + device_state_t state; TAILQ_ENTRY(pdrv_compat) link; }; @@ -953,133 +954,181 @@ return((level>DR_LOWEST & leveldrivers[level]))) \ + continue; \ + TAILQ_FOREACH (pdc, &(dev->drivers[level]), link){ \ + func(pdc->pdriver->memb, __VA_ARGS__); \ + } \ + } + + +FUNC(int, PREFIX, probe, device_t dev){ + FOR_RAW_DRIVER(DEVICE_PROBE, dev->driver->pdriver->topology_ops); +} + +FUNC(int, PREFIX, identify, driver_t *driver, device_t parent){ + FOR_RAW_DRIVER(DEVICE_IDENTIFY, dev->driver->pdriver->driver, parent); +} + +FUNC(int, PREFIX, attach, device_t dev){ + FOR_RAW_DRIVER(DEVICE_ATTACH, dev->driver->pdriver->topology_ops); +} + +FUNC(int, PREFIX, detach, device_t dev){ + FOR_RAW_DRIVER(DEVICE_DETACH, dev->driver->pdriver->topology_ops); +} + +FUNC(int, PREFIX, shutdown, device_t parent){ + FOR_RAW_DRIVER(DEVICE_SHUTDOWN, dev->driver->pdriver->topology_ops); +} + +FUNC(int, PREFIX, suspend, device_t dev){ + FOR_RAW_DRIVER(DEVICE_SUSPEND, dev->driver->pdriver->topology_ops); +} + +FUNC(int, PREFIX, resume, device_t dev){ + FOR_RAW_DRIVER(DEVICE_RESUME, dev->driver->pdriver->topology_ops); +} + +FUNC(int, PREFIX, quiesce, device_t dev){ + FOR_RAW_DRIVER(DEVICE_QUIESCE, dev->driver->pdriver->topology_ops); +} -static int drv_compat_ctrl_probe (device_t dev); -static int drv_compat_ctrl_identify (driver_t *driver, device_t parent); -static int drv_compat_ctrl_attach (device_t dev); -static int drv_compat_ctrl_detach (device_t dev); -static int drv_compat_ctrl_shutdown (device_t dev); -static int drv_compat_ctrl_suspend (device_t dev); -static int drv_compat_ctrl_resume (device_t dev); -static int drv_compat_ctrl_quiesce (device_t dev); -static void* drv_compat_ctrl_info (device_t dev); +FUNC(void *, PREFIX, info, driver_t *driver, device_t parent){ + FOR_ALL_BUT_RAW_DRIVER(DEVICE_INFO, topology_ops); +} + /** * bus control multiplexing entries */ static int drv_compat_ctrl_print_child (device_t dev, - device_t child); + device_t child); static void drv_compat_ctrl_probe_nomatch (device_t dev, - device_t child); + device_t child); static int drv_compat_ctrl_read_ivar (device_t dev, - device_t child, - int index, - uintptr_t *result); + device_t child, + int index, + uintptr_t *result); static int drv_compat_ctrl_write_ivar (device_t dev, - device_t child, - int index, - uintptr_t value); + device_t child, + int index, + uintptr_t value); static void drv_compat_ctrl_child_detached (device_t dev, - device_t child); + device_t child); static void drv_compat_ctrl_driver_added (device_t dev, - driver_t *driver); + driver_t *driver); static device_t drv_compat_ctrl_add_child (device_t dev, - int order, - const char* name, - int unit); + int order, + const char* name, + int unit); static struct_resource * drv_compat_ctrl_alloc_resource (device_t dev, - device_t child, - int type, - int *rid, - u_long start, - u_long end, - u_long count, - u_int flags); + device_t child, + int type, + int *rid, + u_long start, + u_long end, + u_long count, + u_int flags); static int drv_compat_ctrl_activate_resource (device_t dev, - device_t child, - int type, - int rid, - struct resource *r); + device_t child, + int type, + int rid, + struct resource *r); static int drv_compat_ctrl_deactivate_resource (device_t dev, - device_t child, - int type, - int rid, - struct resource *r); + device_t child, + int type, + int rid, + struct resource *r); static int drv_compat_ctrl_release_resource (device_t dev, - device_t child, - int type, - int rid, - struct resource *res); + device_t child, + int type, + int rid, + struct resource *res); static int drv_compat_ctrl_setup_intr (device_t dev, - device_t child, - struct resource *irq, - int flags, - driver_intr_t *intr, - void *arg, - void **cookiep); + device_t child, + struct resource *irq, + int flags, + driver_intr_t *intr, + void *arg, + void **cookiep); static int drv_compat_ctrl_teardown_intr (device_t dev, - device_t child, - struct resource *irq, - void *cookie); + device_t child, + struct resource *irq, + void *cookie); static int drv_compat_ctrl_set_resource (device_t dev, - device_t child, - int type, - int rid, - u_long start, - u_long count); + device_t child, + int type, + int rid, + u_long start, + u_long count); static int drv_compat_ctrl_get_resource (device_t dev, - device_t child, - int type, - int rid, - u_long *startp, - u_long *countp); + device_t child, + int type, + int rid, + u_long *startp, + u_long *countp); static void drv_compat_ctrl_delete_resource (device_t dev, - device_t child, - int type, - int rid); + device_t child, + int type, + int rid); static struct resource_list * drv_compat_ctrl_get_resource_list (device_t dev, - device_t child); + device_t child); static int drv_compat_ctrl_child_present (device_t dev, - device_t child); + device_t child); static int drv_compat_ctrl_child_pnpinfo_str (device_t dev, - device_t child, - char *buf, - size_t buflen); + device_t child, + char *buf, + size_t buflen); static int -drv_compat_ctrl_child_location_str (device_t dev, - device_t child, - char *buf, - size_t buflen); +drv_compat_ctrl_child_location_str (device_t dev, + device_t child, + char *buf, + size_t buflen); static int -drv_compat_ctrl_config_intr (device_t dev, - int irq, - enum intr_trigger trig, - enum intr_polarity pol); +drv_compat_ctrl_config_intr (device_t dev, + int irq, + enum intr_trigger trig, + enum intr_polarity pol); static void -drv_compat_ctrl_hinted_child (device_t dev, - const char *dname, - int dunit); +drv_compat_ctrl_hinted_child (device_t dev, + const char *dname, + int dunit); static device_method_t drv_compat_ctrl_methods[] = { DEVMETHOD(device_probe, drv_compat_ctrl_probe), @@ -1889,7 +1938,7 @@ drv_compat_t drvc; int level; - device_set_driver (dev, dl->driver); + device_set_driver (dev, drvc->driver); if (DEVICE_PROBE(dev)<=0){ drvc = dev->driver; level = drv_compat_flags2idx(drvc->flags); @@ -2053,7 +2102,7 @@ } static int -device_add_to_dev_list (device_t addwhat, pdevice_list_t *addwhere){ +device_add_to_dev_list (device_t addwhat, pdevice_list_t *addwhere, int incr_refs){ pdevice *pd; TAILQ_FOREACH (pd, addwhere, link){ if (pd->device_ptr == addwhat) @@ -2066,7 +2115,8 @@ pd->device_ptr = addwhat; TAILQ_INSERT_TAIL(addwhere, pd, link); - pd->device_ptr->refs++; + if (incr_refs) + pd->device_ptr->refs++; bus_data_generation_update(); return (1); @@ -2079,7 +2129,8 @@ */ int device_add_existing_child (device_t dev, device_t child){ - device_add_to_dev_list (child, &(dev->children)); + device_add_to_dev_list (child, &(dev->children), TRUE); + device_add_to_dev_list (dev, &(child->parents), FALSE); } /** * @brief Add a new parent, which is a device, that already exists @@ -2088,7 +2139,8 @@ */ int device_add_existing_parent (device_t dev, device_t parent){ - device_add_to_dev_list (parent, &(dev->parents)); + device_add_to_dev_list (parent, &(dev->parents), FALSE); + device_add_to_dev_list (dev, &(parent->children), TRUE); } @@ -2149,6 +2201,8 @@ } child->device_ptr->refs++; + device_add_existing_parent (child->device_ptr, dev); + bus_data_generation_update(); return (child); } @@ -2162,27 +2216,32 @@ pdevice *grand; pdevice *pd; pdevice_list_t *list; + device_t child, parent; PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev))); + if (direction==PARENTS) + return (destroy_recurse (devtodel, dev, CHILDREN)); + /* remove children first */ - list = (direction == CHILDREN) ? &devtodel->children : &devtodel->parents; - if (--devtodel->refs) goto deleteself; - while ( (grand = TAILQ_FIRST(list)) ) { + if (devtodel->refs>1) goto deletefromparents; + while ( (grand = TAILQ_FIRST(&devtodel->children)) ) { error = destroy_recurse(devtodel, grand->device_ptr, direction); if (error) return (error); + TAILQ_REMOVE (&devtodel->children, grand, link) free (grand); } - if ((error = device_detach(devtodel)) != 0) +/*!!!*/ if ((error = device_detach(devtodel)) != 0) return (error); if (devtodel->devclass) devclass_delete_device(devtodel->devclass, devtodel); -deletefromparent: - TAILQ_FOREACH_SAFE(pd, list, link){ - if (pd->device_ptr == devtodel){ - TAILQ_REMOVE(list, devtodel, link); +deletefromparents: + TAILQ_FOREACH_SAFE(pd, &devtodel->parents, link){ + if (pd->device_ptr == dev){ + TAILQ_REMOVE(&devtodel->parents, pd, link); + devtodel->refs--; free (pd); break; } @@ -2205,7 +2264,7 @@ } void -device_add_existing_parent (device_t dev, device_t parent){ +device_delete_existing_parent (device_t dev, device_t parent){ destroy_recurse (dev, parent, PARENTS); } @@ -2983,6 +3042,25 @@ return (error); } +static int +device_destroy_configuration (device_t dev){ + int level, error; + pdrv_compat *pdrvc; + + for (level = DRV_TOPMOST; level>= DRV_LOWEST; level--){ + if (TAILQ_EMPTY(&(dev->drivers[level]))) + continue; + while(pdrvc = TAILQ_FIRST(&(dev->drivers[level]))){ + pdrvc->state = DS_RAW; + if(error = device_detach(dev)) + return(error); + TAILQ_REMOVE(&(dev->drivers[level]), pdrvc, link); + free(pdrvc); + + } + } +} + /** * @brief Set the driver of a device * @@ -2994,30 +3072,42 @@ device_set_driver(device_t dev, driver_t *driver) /*TODO*/ { drv_compat_t drvc; - pdrv_compat *drvctmp; + pdrv_compat *pdrvc; uint32_t flags; int level; if (dev->state >= DS_ATTACHED) return (EBUSY); - drvc = drv_compat_find_driver (driver); + if (driver != NULL){ + drvc = drv_compat_find_driver (driver); + + drv_compat_get_flags(driver, &flags); + level = drv_compat_flags2idx(flags); - TAILQ_FOREACH(drvctmp, &(dev->drivers[level]), link){ - if (drvctmp->pdriver == drvc) - break; + TAILQ_FOREACH(pdrvc, &(dev->drivers[level]), link){ + if (pdrvc->pdriver == drvc) + break; + } + if (pdrvc){ + pdrvc->state = DS_RAW; + return (0); + } } - if (!drvctmp){ - + if(driver == NULL || level == DRV_LOWEST){ + if(!device_destroy_configuration(dev)) + return (EBUSY); } - dev->driver = drvctmp; - dev->driver_level = level; + pdrvc = malloc (sizeof(struct pdrv_compat), M_BUS, M_NOWAIT|M_ZERO); + pdrvc->pdriver = drvc; + pdrvc->state = DS_RAW; + + TAILQ_INSERT_TAIL (&(dev->drivers[level]), pdrvc); - /* - if (dev->driver == driver) - return (0); + dev->driver = pdrvc; +// dev->driver_level = level; if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) { free(dev->softc, M_BUS_SC); @@ -3030,7 +3120,9 @@ if (!dev->softc) { //kobj_delete((kobj_t) dev, 0); //kobj_init((kobj_t) dev, &null_class); - dev->driver = NULL; + //dev->driver = NULL; + TAILQ_REMOVE(&(dev->drivers[level]), pdrvc, link); + free (pdrvc); return (ENOMEM); } } @@ -3141,9 +3233,10 @@ } else { drvc = dev->driver; dev->devclass = devclass_find (DRIVERNAME(drvc->driver)); - level = drv_compat_flags2idx(drvc->flags); - TAILQ_INSERT_TAIL (&((dev->drivers)[level]), &drvc, link); - dev->driver = NULL; + //level = drv_compat_flags2idx(drvc->flags); + + //TAILQ_INSERT_TAIL (&((dev->drivers)[level]), &drvc, link); + //dev->driver = NULL; } dev->state = DS_ATTACHED; devadded(dev); ==== //depot/projects/soc2007/thioretic_gidl/sys/bus.h#6 (text+ko) ==== @@ -47,6 +47,7 @@ * @brief State of the device. */ typedef enum device_state { + DS_RAW, DS_NOTPRESENT, /**< @brief not probed or probe failed */ DS_ALIVE, /**< @brief probe succeeded */ DS_ATTACHED, /**< @brief attach method called */