Date: Thu, 5 Jul 2007 21:15:09 GMT From: Maxim Zhuravlev <thioretic@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 122974 for review Message-ID: <200707052115.l65LF9SH049400@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=122974 Change 122974 by thioretic@thioretic on 2007/07/05 21:14:17 Devclasses for filter drivers stuff. Affected files ... .. //depot/projects/soc2007/thioretic_gidl/TODO#7 edit .. //depot/projects/soc2007/thioretic_gidl/kern/subr_bus.c#6 edit .. //depot/projects/soc2007/thioretic_gidl/sys/bus.h#4 edit Differences ... ==== //depot/projects/soc2007/thioretic_gidl/TODO#7 (text+ko) ==== @@ -68,4 +68,22 @@ # attached, but to drv_compat_ctrl_driver, which will demux # to stacked drivers. # dev->drivers are pointers to drv_compat structures that - # represent drivers of interest.+ # represent drivers of interest. + a.1.2 Devclasses + SOLUTION: add filters field to devclass + # the filter drivers (with DR_LOWEST<level<DR_TOPMOST) use + # devclasses quite differently. Actually, they just extend + # the functionality of DR_LOWEST driver. So only DR_LOWEST + # driver should have an in-tree built devclass, with + # pointers to devclasses of filter drivers. I.e.: + # + # Devclasses tree: + # + # BUS<-+-+.... + # | + # DR_LOWEST driver_n<-+----+... + # | | + # filter0 filter1 + # + # NB: here BUS is also a DR_LOWEST driver in turn with all + # those consequences. ==== //depot/projects/soc2007/thioretic_gidl/kern/subr_bus.c#6 (text+ko) ==== @@ -84,20 +84,29 @@ struct pdrv_compat { drv_compat *pdriver; TAILQ_ENTRY(pdrv_compat) link; -} +}; + /* * Forward declarations */ typedef TAILQ_HEAD(devclass_list, devclass) devclass_list_t; +typedef TAILQ_HEAD(pdevclass_list, pdevclass) pdevclass_list_t; typedef TAILQ_HEAD(driver_list, driverlink) driver_list_t; typedef TAILQ_HEAD(device_list, device) device_list_t; typedef TAILQ_HEAD(drv_compat_list, drv_compat) drv_compat_list_t; typedef TAILQ_HEAD(pdrv_compat_list, pdrv_compat) pdrv_compat_list_t; +struct pdevclass{ + devclass_t devclass_ptr; + TAILQ_ENTRY(pdevclass) link; +}; + struct devclass { TAILQ_ENTRY(devclass) link; devclass_t parent; /* parent in devclass hierarchy */ + pdevclass_list_t filters; /* these are used to hold information, + used for non-DRV_LOWEST drivers' classes */ driver_list_t drivers; /* bus devclasses store drivers for bus */ char *name; device_t *devices; /* array of devices indexed by unit */ @@ -1124,7 +1133,7 @@ */ static devclass_t devclass_find_internal(const char *classname, const char *parentname, - int create) + int create, int filter) { devclass_t dc; @@ -1147,6 +1156,7 @@ dc->name = (char*) (dc + 1); strcpy(dc->name, classname); TAILQ_INIT(&dc->drivers); + TAILQ_INIT(&dc->filters); TAILQ_INSERT_TAIL(&devclasses, dc, link); bus_data_generation_update(); @@ -1162,7 +1172,11 @@ */ if (parentname && dc && !dc->parent && strcmp(classname, parentname) != 0) { - dc->parent = devclass_find_internal(parentname, 0, FALSE); + dc->parent = devclass_find_internal(parentname, 0, FALSE, FALSE); + } + + if (filter) { + TAILQ_INSERT_TAIL(&(dc->parent->filters), dc, link); } return (dc); @@ -1179,7 +1193,7 @@ devclass_t devclass_create(const char *classname) { - return (devclass_find_internal(classname, 0, TRUE)); + return (devclass_find_internal(classname, 0, TRUE, FALSE)); } /** @@ -1193,7 +1207,7 @@ devclass_t devclass_find(const char *classname) { - return (devclass_find_internal(classname, 0, FALSE)); + return (devclass_find_internal(classname, 0, FALSE, FALSE)); } /** @@ -1212,6 +1226,7 @@ { driverlink_t dl; int i; + uint32_t flags; PDEBUG(("%s", DRIVERNAME(driver))); @@ -1230,7 +1245,11 @@ /* * Make sure the devclass which the driver is implementing exists. */ - devclass_find_internal(driver->name, 0, TRUE); + if (!drv_compat_get_flags (driver, &flags)){ + /*todo what???*/ + } + + devclass_find_internal(driver->name, 0, TRUE, FALSE); dl->driver = driver; TAILQ_INSERT_TAIL(&dc->drivers, dl, link); @@ -1810,7 +1829,7 @@ PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit)); if (name) { - dc = devclass_find_internal(name, 0, TRUE); + dc = devclass_find_internal(name, 0, TRUE, FALSE); if (!dc) { printf("make_device: can't find device class %s\n", name); @@ -2627,7 +2646,7 @@ return (EINVAL); } - dc = devclass_find_internal(classname, 0, TRUE); + dc = devclass_find_internal(classname, 0, TRUE, FALSE); if (!dc) return (ENOMEM); @@ -4043,7 +4062,7 @@ kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver); root_bus->driver = &root_driver; root_bus->state = DS_ATTACHED; - root_devclass = devclass_find_internal("root", 0, FALSE); + root_devclass = devclass_find_internal("root", 0, FALSE, FALSE); devinit(); return (0); @@ -4083,6 +4102,53 @@ } /** + * @internal + * @brief Parses the dmd_busname for filter drivers + * + * The dmd_busname for filter drivers if represented + * by a string of busnames (actually they are names + * of DR_LOWEST drivers) delimited by '|' symbol. + * + * @param in a pointer to dmd_busname string + * @param out a pointer to store the address + * of an array of strings, representing + * the devclass names of DR_LOWEST + * drivers. + */ + +static int +parse_parent_name (char* in, char ***out){ /*TODO*/ + char* cptr = in, *ptr = in, *newpar; + int count = 1, num = 0; + + if (!in || *in == '\0') + return (0); + + if (!strcmp(in, "*")){ + /* do we need this? + * if we do, then there must be a way + * to add filter driver to devclasses + * of drivers, not yet added + */ + } + else{ + while (strchr(ptr, '|')) count++; + *out = malloc (sizeof(char*)*(count+1), M_BUS, M_NOWAIT|M_ZERO); + count=0; + do { + while (*ptr!='|' && *ptr!='\0') num++, ptr++; + newpar = malloc ((num+1)*sizeof(char), M_BUS, M_NOWAIT|M_ZERO); + if (!newpar) return(0); + strlcpy(newpar, cptr, num+1); + (*out)[count++] = newpar; + num = 0; cptr = ++ptr; + } while (cptr<(in+strlen(in))); + (*out)[count]=NULL; + return (1); + } +} + +/** * @brief Module handler for registering device drivers * * This module handler is used to automatically register device @@ -4095,12 +4161,16 @@ { int error; struct driver_module_data *dmd; - devclass_t bus_devclass; + devclass_t bus_devclass, parent_devclass, filter_devclass; drv_internal_t drv_intnl; kobj_class_t driver; + char* parents[]; + int count=0; dmd = (struct driver_module_data *)arg; - bus_devclass = devclass_find_internal(dmd->dmd_busname, 0, TRUE); + drv_intnl = dmd->dmd_driver; + if (!(drv_intnl->flags & ~(DR_LOWEST | DR_STACKAWARE | DR_TOPMOST))) + bus_devclass = devclass_find_internal(dmd->dmd_busname, 0, TRUE, FALSE); error = 0; switch (what) { @@ -4109,12 +4179,27 @@ error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg); //driver = dmd->dmd_driver; - drv_intnl = dmd->dmd_driver; drv_compat_add_driver(drv_intnl); driver = drv_intnl->devops; PDEBUG(("Loading module: driver %s on bus %s", DRIVERNAME(driver), dmd->dmd_busname)); - error = devclass_add_driver(bus_devclass, driver); + if (drv_intnl->flags & ~(DR_LOWEST | DR_STACKAWARE | DR_TOPMOST)){ + /* if is a filter driver */ + if (!parse_parent_name(dmd->dmd_busname, &parents)) + break; + while (parents[count]){ + parent_devclass = devclass_find_internal (parents[count], + 0, TRUE, FALSE); + filter_devclass = devclass_find_internal (driver->name, + parent[count], TRUE, TRUE); + error = devclass_add_driver (filter_devclass, driver); + count++; + } + free(parents); + } + else{ + error = devclass_add_driver(bus_devclass, driver); + } if (error) break; ==== //depot/projects/soc2007/thioretic_gidl/sys/bus.h#4 (text+ko) ==== @@ -498,6 +498,8 @@ uint32_t flags; }; +#define DR_ALLLEVELS (DR_LOWEST|DR_LOWER|DR_MIDDLE|DR_UPPER|DR_TOPMOST) + typedef struct drv_internal *drv_internal_t; struct driver_module_data { @@ -513,7 +515,7 @@ \ static struct drv_internal name##_##busname##_intnl { \ (kobj_class_t) &driver, \ - LOWEST \ + DR_LOWEST \ }; \ \ static struct driver_module_data name##_##busname##_driver_mod = { \
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200707052115.l65LF9SH049400>