Deleted Added
full compact
subr_bus.c (41131) subr_bus.c (41153)
1/*-
2 * Copyright (c) 1997,1998 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 1997,1998 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: subr_bus.c,v 1.8 1998/10/27 09:21:43 dfr Exp $
26 * $Id: subr_bus.c,v 1.9 1998/11/13 09:39:37 dfr Exp $
27 */
28
29#include <sys/param.h>
30#include <sys/queue.h>
31#include <sys/malloc.h>
32#include <sys/kernel.h>
33#include <sys/module.h>
34#include <sys/bus_private.h>

--- 628 unchanged lines hidden (view full) ---

663
664const char *
665device_get_desc(device_t dev)
666{
667 return dev->desc;
668}
669
670void
27 */
28
29#include <sys/param.h>
30#include <sys/queue.h>
31#include <sys/malloc.h>
32#include <sys/kernel.h>
33#include <sys/module.h>
34#include <sys/bus_private.h>

--- 628 unchanged lines hidden (view full) ---

663
664const char *
665device_get_desc(device_t dev)
666{
667 return dev->desc;
668}
669
670void
671device_print_prettyname(device_t dev)
672{
673 const char *name = device_get_name(dev);
674
675 if (name == 0)
676 name = "(no driver assigned)";
677 printf("%s%d: ", name, device_get_unit(dev));
678}
679
680void
671device_set_desc(device_t dev, const char* desc)
672{
673 dev->desc = desc;
674}
675
676void *
677device_get_softc(device_t dev)
678{

--- 123 unchanged lines hidden (view full) ---

802 dev->state = DS_ATTACHED;
803 else {
804 printf("device_probe_and_attach: %s%d attach returned %d\n",
805 dev->driver->name, dev->unit, error);
806 device_set_driver(dev, NULL);
807 dev->state = DS_NOTPRESENT;
808 }
809 }
681device_set_desc(device_t dev, const char* desc)
682{
683 dev->desc = desc;
684}
685
686void *
687device_get_softc(device_t dev)
688{

--- 123 unchanged lines hidden (view full) ---

812 dev->state = DS_ATTACHED;
813 else {
814 printf("device_probe_and_attach: %s%d attach returned %d\n",
815 dev->driver->name, dev->unit, error);
816 device_set_driver(dev, NULL);
817 dev->state = DS_NOTPRESENT;
818 }
819 }
810 } else
811 printf("%s%d: disabled, not probed.\n",
812 dev->devclass->name, dev->unit);
820 } else {
821 device_print_prettyname(dev);
822 printf("not probed (disabled)\n");
823 }
813
814 return 0;
815}
816
817int
818device_detach(device_t dev)
819{
820 int error;

--- 29 unchanged lines hidden (view full) ---

850 */
851extern struct config_device devtab[];
852extern int devtab_count;
853
854static int
855resource_match_string(int i, char *resname, char *value)
856{
857 int j;
824
825 return 0;
826}
827
828int
829device_detach(device_t dev)
830{
831 int error;

--- 29 unchanged lines hidden (view full) ---

861 */
862extern struct config_device devtab[];
863extern int devtab_count;
864
865static int
866resource_match_string(int i, char *resname, char *value)
867{
868 int j;
858 struct resource *res;
869 struct config_resource *res;
859
860 for (j = 0, res = devtab[i].resources;
861 j < devtab[i].resource_count; j++, res++)
862 if (!strcmp(res->name, resname)
863 && res->type == RES_STRING
864 && !strcmp(res->u.stringval, value))
865 return TRUE;
866 return FALSE;
867}
868
869static int
870
871 for (j = 0, res = devtab[i].resources;
872 j < devtab[i].resource_count; j++, res++)
873 if (!strcmp(res->name, resname)
874 && res->type == RES_STRING
875 && !strcmp(res->u.stringval, value))
876 return TRUE;
877 return FALSE;
878}
879
880static int
870resource_find(const char *name, int unit, char *resname, struct resource **result)
881resource_find(const char *name, int unit, char *resname,
882 struct config_resource **result)
871{
872 int i, j;
883{
884 int i, j;
873 struct resource *res;
885 struct config_resource *res;
874
875 /*
876 * First check specific instances, then generic.
877 */
878 for (i = 0; i < devtab_count; i++) {
879 if (devtab[i].unit < 0)
880 continue;
881 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {

--- 19 unchanged lines hidden (view full) ---

901 }
902 return ENOENT;
903}
904
905int
906resource_int_value(const char *name, int unit, char *resname, int *result)
907{
908 int error;
886
887 /*
888 * First check specific instances, then generic.
889 */
890 for (i = 0; i < devtab_count; i++) {
891 if (devtab[i].unit < 0)
892 continue;
893 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {

--- 19 unchanged lines hidden (view full) ---

913 }
914 return ENOENT;
915}
916
917int
918resource_int_value(const char *name, int unit, char *resname, int *result)
919{
920 int error;
909 struct resource *res;
921 struct config_resource *res;
910 if ((error = resource_find(name, unit, resname, &res)) != 0)
911 return error;
912 if (res->type != RES_INT)
913 return EFTYPE;
914 *result = res->u.intval;
915 return 0;
916}
917
918int
919resource_long_value(const char *name, int unit, char *resname, long *result)
920{
921 int error;
922 if ((error = resource_find(name, unit, resname, &res)) != 0)
923 return error;
924 if (res->type != RES_INT)
925 return EFTYPE;
926 *result = res->u.intval;
927 return 0;
928}
929
930int
931resource_long_value(const char *name, int unit, char *resname, long *result)
932{
933 int error;
922 struct resource *res;
934 struct config_resource *res;
923 if ((error = resource_find(name, unit, resname, &res)) != 0)
924 return error;
925 if (res->type != RES_LONG)
926 return EFTYPE;
927 *result = res->u.longval;
928 return 0;
929}
930
931int
932resource_string_value(const char *name, int unit, char *resname, char **result)
933{
934 int error;
935 if ((error = resource_find(name, unit, resname, &res)) != 0)
936 return error;
937 if (res->type != RES_LONG)
938 return EFTYPE;
939 *result = res->u.longval;
940 return 0;
941}
942
943int
944resource_string_value(const char *name, int unit, char *resname, char **result)
945{
946 int error;
935 struct resource *res;
947 struct config_resource *res;
936 if ((error = resource_find(name, unit, resname, &res)) != 0)
937 return error;
938 if (res->type != RES_STRING)
939 return EFTYPE;
940 *result = res->u.stringval;
941 return 0;
942}
943

--- 62 unchanged lines hidden (view full) ---

1006
1007 for (child = TAILQ_FIRST(&dev->children);
1008 child; child = TAILQ_NEXT(child, link))
1009 DEVICE_SHUTDOWN(child);
1010
1011 return 0;
1012}
1013
948 if ((error = resource_find(name, unit, resname, &res)) != 0)
949 return error;
950 if (res->type != RES_STRING)
951 return EFTYPE;
952 *result = res->u.stringval;
953 return 0;
954}
955

--- 62 unchanged lines hidden (view full) ---

1018
1019 for (child = TAILQ_FIRST(&dev->children);
1020 child; child = TAILQ_NEXT(child, link))
1021 DEVICE_SHUTDOWN(child);
1022
1023 return 0;
1024}
1025
1026int
1027bus_generic_suspend(device_t dev)
1028{
1029 int error;
1030 device_t child, child2;
1031
1032 for (child = TAILQ_FIRST(&dev->children);
1033 child; child = TAILQ_NEXT(child, link)) {
1034 error = DEVICE_SUSPEND(child);
1035 if (error) {
1036 for (child2 = TAILQ_FIRST(&dev->children);
1037 child2 && child2 != child;
1038 child2 = TAILQ_NEXT(child2, link))
1039 DEVICE_RESUME(child2);
1040 return (error);
1041 }
1042 }
1043 return 0;
1044}
1045
1046int
1047bus_generic_resume(device_t dev)
1048{
1049 device_t child;
1050
1051 for (child = TAILQ_FIRST(&dev->children);
1052 child; child = TAILQ_NEXT(child, link)) {
1053 DEVICE_RESUME(child);
1054 /* if resume fails, there's nothing we can usefully do... */
1055 }
1056 return 0;
1057}
1058
1014void
1015bus_generic_print_child(device_t dev, device_t child)
1016{
1017}
1018
1019int
1059void
1060bus_generic_print_child(device_t dev, device_t child)
1061{
1062}
1063
1064int
1020bus_generic_read_ivar(device_t dev, device_t child, int index, u_long* result)
1065bus_generic_read_ivar(device_t dev, device_t child, int index,
1066 uintptr_t * result)
1021{
1022 return ENOENT;
1023}
1024
1025int
1067{
1068 return ENOENT;
1069}
1070
1071int
1026bus_generic_write_ivar(device_t dev, device_t child, int index, u_long value)
1072bus_generic_write_ivar(device_t dev, device_t child, int index,
1073 uintptr_t value)
1027{
1028 return ENOENT;
1029}
1030
1074{
1075 return ENOENT;
1076}
1077
1031void *
1032bus_generic_create_intr(device_t dev, device_t child, int irq, driver_intr_t *intr, void *arg)
1078int
1079bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
1080 driver_intr_t *intr, void *arg, void **cookiep)
1033{
1081{
1034 /* Propagate up the bus hierarchy until someone handles it. */
1035 if (dev->parent)
1036 return BUS_CREATE_INTR(dev->parent, dev, irq, intr, arg);
1037 else
1038 return NULL;
1082 /* Propagate up the bus hierarchy until someone handles it. */
1083 if (dev->parent)
1084 return (BUS_SETUP_INTR(dev->parent, dev, irq, intr, arg,
1085 cookiep));
1086 else
1087 return (EINVAL);
1039}
1040
1041int
1088}
1089
1090int
1042bus_generic_connect_intr(device_t dev, void *ih)
1091bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq,
1092 void *cookie)
1043{
1093{
1044 /* Propagate up the bus hierarchy until someone handles it. */
1045 if (dev->parent)
1046 return BUS_CONNECT_INTR(dev->parent, ih);
1047 else
1048 return EINVAL;
1094 /* Propagate up the bus hierarchy until someone handles it. */
1095 if (dev->parent)
1096 return (BUS_TEARDOWN_INTR(dev->parent, dev, irq, cookie));
1097 else
1098 return (EINVAL);
1049}
1050
1099}
1100
1051static int root_create_intr(device_t dev, device_t child,
1052 driver_intr_t *intr, void *arg)
1101int
1102bus_generic_activate_resource(device_t dev, device_t child, int type, int rid,
1103 struct resource *r)
1053{
1104{
1054 /*
1055 * If an interrupt mapping gets to here something bad has happened.
1056 * Should probably panic.
1057 */
1058 return EINVAL;
1105 /* Propagate up the bus hierarchy until someone handles it. */
1106 if (dev->parent)
1107 return (BUS_ACTIVATE_RESOURCE(dev->parent, child, type, rid,
1108 r));
1109 else
1110 return (EINVAL);
1059}
1060
1111}
1112
1113int
1114bus_generic_deactivate_resource(device_t dev, device_t child, int type,
1115 int rid, struct resource *r)
1116{
1117 /* Propagate up the bus hierarchy until someone handles it. */
1118 if (dev->parent)
1119 return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, type, rid,
1120 r));
1121 else
1122 return (EINVAL);
1123}
1124
1125/*
1126 * Some convenience functions to make it easier for drivers to use the
1127 * resource-management functions. All these really do is hide the
1128 * indirection through the parent's method table, making for slightly
1129 * less-wordy code. In the future, it might make sense for this code
1130 * to maintain some sort of a list of resources allocated by each device.
1131 */
1132struct resource *
1133bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end,
1134 u_long count, u_int flags)
1135{
1136 if (dev->parent == 0)
1137 return (0);
1138 return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
1139 count, flags));
1140}
1141
1142int
1143bus_activate_resource(device_t dev, int type, int rid, struct resource *r)
1144{
1145 if (dev->parent == 0)
1146 return (EINVAL);
1147 return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
1148}
1149
1150int
1151bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r)
1152{
1153 if (dev->parent == 0)
1154 return (EINVAL);
1155 return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
1156}
1157
1158int
1159bus_release_resource(device_t dev, int type, int rid, struct resource *r)
1160{
1161 if (dev->parent == 0)
1162 return (EINVAL);
1163 return (BUS_RELEASE_RESOURCE(dev->parent, dev,
1164 type, rid, r));
1165}
1166
1167static int
1168root_setup_intr(device_t dev, device_t child, driver_intr_t *intr, void *arg,
1169 void **cookiep)
1170{
1171 /*
1172 * If an interrupt mapping gets to here something bad has happened.
1173 */
1174 panic("root_setup_intr");
1175}
1176
1061static device_method_t root_methods[] = {
1177static device_method_t root_methods[] = {
1178 /* Device interface */
1179 DEVMETHOD(device_suspend, bus_generic_suspend),
1180 DEVMETHOD(device_resume, bus_generic_resume),
1181
1062 /* Bus interface */
1063 DEVMETHOD(bus_print_child, bus_generic_print_child),
1064 DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
1065 DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
1182 /* Bus interface */
1183 DEVMETHOD(bus_print_child, bus_generic_print_child),
1184 DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
1185 DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
1066 DEVMETHOD(bus_create_intr, root_create_intr),
1186 DEVMETHOD(bus_setup_intr, root_setup_intr),
1067
1068 { 0, 0 }
1069};
1070
1071static driver_t root_driver = {
1072 "root",
1073 root_methods,
1074 DRIVER_TYPE_MISC,
1075 1, /* no softc */
1076};
1077
1187
1188 { 0, 0 }
1189};
1190
1191static driver_t root_driver = {
1192 "root",
1193 root_methods,
1194 DRIVER_TYPE_MISC,
1195 1, /* no softc */
1196};
1197
1078device_t root_bus;
1079devclass_t root_devclass;
1198device_t root_bus;
1199devclass_t root_devclass;
1080
1081static int
1200
1201static int
1082root_bus_module_handler(module_t mod, modeventtype_t what, void* arg)
1202root_bus_module_handler(module_t mod, int what, void* arg)
1083{
1084 switch (what) {
1085 case MOD_LOAD:
1086 compile_methods(&root_driver);
1087 root_bus = make_device(NULL, "root", 0, NULL);
1088 root_bus->desc = "System root bus";
1089 root_bus->ops = root_driver.ops;
1090 root_bus->driver = &root_driver;

--- 8 unchanged lines hidden (view full) ---

1099static moduledata_t root_bus_mod = {
1100 "rootbus",
1101 root_bus_module_handler,
1102 0
1103};
1104DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
1105
1106void
1203{
1204 switch (what) {
1205 case MOD_LOAD:
1206 compile_methods(&root_driver);
1207 root_bus = make_device(NULL, "root", 0, NULL);
1208 root_bus->desc = "System root bus";
1209 root_bus->ops = root_driver.ops;
1210 root_bus->driver = &root_driver;

--- 8 unchanged lines hidden (view full) ---

1219static moduledata_t root_bus_mod = {
1220 "rootbus",
1221 root_bus_module_handler,
1222 0
1223};
1224DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
1225
1226void
1107root_bus_configure()
1227root_bus_configure(void)
1108{
1109 device_t dev;
1110
1111 PDEBUG(("."));
1112
1113 for (dev = TAILQ_FIRST(&root_bus->children); dev;
1114 dev = TAILQ_NEXT(dev, link)) {
1115 device_probe_and_attach(dev);
1116 }
1117}
1118
1119int
1228{
1229 device_t dev;
1230
1231 PDEBUG(("."));
1232
1233 for (dev = TAILQ_FIRST(&root_bus->children); dev;
1234 dev = TAILQ_NEXT(dev, link)) {
1235 device_probe_and_attach(dev);
1236 }
1237}
1238
1239int
1120driver_module_handler(module_t mod, modeventtype_t what, void* arg)
1240driver_module_handler(module_t mod, int what, void *arg)
1121{
1241{
1122 struct driver_module_data* data = (struct driver_module_data*) arg;
1123 devclass_t bus_devclass = devclass_find_internal(data->busname, TRUE);
1124 int error;
1242 int error, i;
1243 struct driver_module_data *dmd;
1244 devclass_t bus_devclass;
1125
1245
1126 switch (what) {
1127 case MOD_LOAD:
1128 PDEBUG(("Loading module: driver %s on bus %s",
1129 DRIVERNAME(data->driver), data->busname));
1130 if (error = devclass_add_driver(bus_devclass,
1131 data->driver))
1132 return error;
1133 *data->devclass =
1134 devclass_find_internal(data->driver->name, TRUE);
1135 break;
1246 dmd = (struct driver_module_data *)arg;
1247 bus_devclass = devclass_find_internal(dmd->dmd_busname, TRUE);
1248 error = 0;
1136
1249
1137 case MOD_UNLOAD:
1138 PDEBUG(("Unloading module: driver %s from bus %s",
1139 DRIVERNAME(data->driver), data->busname));
1140 if (error = devclass_delete_driver(bus_devclass,
1141 data->driver))
1142 return error;
1143 break;
1144 }
1250 switch (what) {
1251 case MOD_LOAD:
1252 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
1253 PDEBUG(("Loading module: driver %s on bus %s",
1254 DRIVERNAME(dmd->dmd_driver[i]),
1255 dmd->dmd_busname));
1256 error = devclass_add_driver(bus_devclass,
1257 dmd->dmd_drivers[i]);
1258 }
1259 if (error)
1260 break;
1145
1261
1146 if (data->chainevh)
1147 return data->chainevh(mod, what, data->chainarg);
1148 else
1149 return 0;
1150}
1262 /*
1263 * The drivers loaded in this way are assumed to all
1264 * implement the same devclass.
1265 */
1266 *dmd->dmd_devclass =
1267 devclass_find_internal(dmd->dmd_drivers[0]->name,
1268 TRUE);
1269 break;
1151
1270
1271 case MOD_UNLOAD:
1272 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
1273 PDEBUG(("Unloading module: driver %s from bus %s",
1274 DRIVERNAME(dmd->dmd_drivers[i]),
1275 dmd->dmd_busname));
1276 error = devclass_delete_driver(bus_devclass,
1277 dmd->dmd_drivers[i]);
1278 }
1279 break;
1280 }
1152
1281
1282 if (!error && dmd->dmd_chainevh)
1283 error = dmd->dmd_chainevh(mod, what, dmd->dmd_chainarg);
1284 return (error);
1285}
1153
1154#ifdef BUS_DEBUG
1155
1156/* the _short versions avoid iteration by not calling anything that prints
1157 * more than oneliners. I love oneliners.
1158 */
1159
1160static void

--- 204 unchanged lines hidden ---
1286
1287#ifdef BUS_DEBUG
1288
1289/* the _short versions avoid iteration by not calling anything that prints
1290 * more than oneliners. I love oneliners.
1291 */
1292
1293static void

--- 204 unchanged lines hidden ---