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 --- |