* @internal * @brief Find or create a device class * * If a device class with the name @p classname exists, return it, * otherwise if @p create is non-zero create and return a new device * class. * * If @p parentname is non-NULL, the parent of the devclass is set to * the devclass of that name. * * @param classname the devclass name to find or create * @param parentname the parent devcl
| 971 | * @param create non-zero to create a devclass |
| 972 | */ |
| 973 | static devclass_t |
| 974 | devclass_find_internal(const char *classname, const char *parentname, |
| 975 | int create) |
| 976 | { |
| 977 | devclass_t dc; |
| 978 | |
| 979 | PDEBUG(("looking for %s", classname)); |
| 980 | if (!classname) |
| 981 | return (NULL); |
| 982 | |
| 983 | TAILQ_FOREACH(dc, &devclasses, link) { |
| 984 | if (!strcmp(dc->name, classname)) |
| 985 | break; |
| 986 | } |
| 987 | |
| 988 | if (create && !dc) { |
| 989 | PDEBUG(("creating %s", classname)); |
| 990 | dc = malloc(sizeof(struct devclass) + strlen(classname) + 1, |
| 991 | M_BUS, M_NOWAIT | M_ZERO); |
| 992 | if (!dc) |
| 993 | return (NULL); |
| 994 | dc->parent = NULL; |
| 995 | dc->name = (char*) (dc + 1); |
| 996 | strcpy(dc->name, classname); |
| 997 | TAILQ_INIT(&dc->drivers); |
| 998 | TAILQ_INSERT_TAIL(&devclasses, dc, link); |
| 999 | |
| 1000 | bus_data_generation_update(); |
| 1001 | } |
| 1002 | |
| 1003 | /* |
| 1004 | * If a parent class is specified, then set that as our parent so |
| 1005 | * that this devclass will support drivers for the parent class as |
| 1006 | * well. If the parent class has the same name don't do this though |
| 1007 | * as it creates a cycle that can trigger an infinite loop in |
| 1008 | * device_probe_child() if a device exists for which there is no |
| 1009 | * suitable driver. |
| 1010 | */ |
| 1011 | if (parentname && dc && !dc->parent && |
| 1012 | strcmp(classname, parentname) != 0) { |
| 1013 | dc->parent = devclass_find_internal(parentname, NULL, TRUE); |
| 1014 | dc->parent->flags |= DC_HAS_CHILDREN; |
| 1015 | } |
| 1016 | |
| 1017 | return (dc); |
| 1018 | } |
| 1019 | |
| 1020 | /** |
| 1021 | * @brief Create a device class |
no test coverage detected