| Commit | Line | Data |
|---|---|---|
| 984263bc MD |
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 | * notice, this list of conditions and the following disclaimer. | |
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 11 | * notice, this list of conditions and the following disclaimer in the | |
| 12 | * documentation and/or other materials provided with the distribution. | |
| 13 | * | |
| 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
| 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
| 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 | * | |
| 07d2fd35 | 26 | * $FreeBSD: src/sys/sys/bus.h,v 1.30.2.5 2004/03/17 17:54:25 njl Exp $ |
| 71fc104f | 27 | * $DragonFly: src/sys/sys/bus.h,v 1.31 2008/10/03 00:26:21 hasso Exp $ |
| 984263bc MD |
28 | */ |
| 29 | ||
| 30 | #ifndef _SYS_BUS_H_ | |
| 31 | #define _SYS_BUS_H_ | |
| 32 | ||
| 7490f18b | 33 | #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) |
| 984263bc | 34 | |
| 1bd40720 MD |
35 | #ifndef _SYS_TYPES_H_ |
| 36 | #include <sys/types.h> | |
| 37 | #endif | |
| 38 | #ifndef _SYS_QUEUE_H_ | |
| 984263bc | 39 | #include <sys/queue.h> |
| 1bd40720 MD |
40 | #endif |
| 41 | #ifndef _SYS_KOBJ_H_ | |
| 80eff43d | 42 | #include <sys/kobj.h> |
| 1bd40720 | 43 | #endif |
| 7490f18b | 44 | #ifdef _KERNEL |
| e9cb6d99 | 45 | #include <sys/serialize.h> |
| 7490f18b | 46 | #endif |
| 1f7ab7c9 MD |
47 | #ifndef _SYS_BUS_DMA_H_ |
| 48 | #include <sys/bus_dma.h> | |
| 49 | #endif | |
| 50 | #ifndef _SYS_BUS_RESOURCE_H_ | |
| 51 | #include <sys/bus_resource.h> | |
| 52 | #endif | |
| 984263bc MD |
53 | |
| 54 | /* | |
| 55 | * Forward declarations | |
| 56 | */ | |
| 57 | typedef struct device *device_t; | |
| e1bc6fbb | 58 | typedef struct kobj_class driver_t; |
| 984263bc | 59 | typedef struct devclass *devclass_t; |
| 80eff43d | 60 | #define device_method_t kobj_method_t |
| 984263bc MD |
61 | |
| 62 | typedef void driver_intr_t(void*); | |
| 63 | ||
| 64 | /* | |
| 0010e23a HT |
65 | * Interface information structure. |
| 66 | */ | |
| 67 | struct u_businfo { | |
| 68 | int ub_version; /* interface version */ | |
| 69 | #define BUS_USER_VERSION 1 | |
| 70 | int ub_generation; /* generation count */ | |
| 71 | }; | |
| 72 | ||
| 73 | /* | |
| 74 | * State of the device. | |
| 75 | */ | |
| 76 | typedef enum device_state { | |
| 77 | DS_NOTPRESENT, /* not probed or probe failed */ | |
| 78 | DS_ALIVE, /* probe succeeded */ | |
| 79 | DS_INPROGRESS, /* attach in progress */ | |
| 80 | DS_ATTACHED, /* attach method called */ | |
| 81 | DS_BUSY /* device is open */ | |
| 82 | } device_state_t; | |
| 83 | ||
| 84 | /* | |
| 85 | * Device information exported to userspace. | |
| 86 | */ | |
| 87 | struct u_device { | |
| 88 | uintptr_t dv_handle; | |
| 89 | uintptr_t dv_parent; | |
| 90 | ||
| 91 | char dv_name[32]; /* Name of device in tree. */ | |
| 92 | char dv_desc[32]; /* Driver description */ | |
| 93 | char dv_drivername[32]; /* Driver name */ | |
| 94 | char dv_pnpinfo[128]; /* Plug and play info */ | |
| 95 | char dv_location[128]; /* Where is the device? */ | |
| 96 | uint32_t dv_devflags; /* API Flags for device */ | |
| 97 | uint16_t dv_flags; /* flags for dev date */ | |
| 98 | device_state_t dv_state; /* State of attachment */ | |
| 99 | /* XXX more driver info? */ | |
| 100 | }; | |
| 101 | ||
| 102 | /* | |
| ee61f228 MD |
103 | * Interrupt features mask. Note that DragonFly no longer implements |
| 104 | * INTR_TYPE_* flags. | |
| 984263bc | 105 | */ |
| ee61f228 MD |
106 | #define INTR_FAST 0x0080 |
| 107 | #define INTR_EXCL 0x0100 | |
| 108 | #define INTR_MPSAFE 0x0200 | |
| 8b3ec75a | 109 | #define INTR_NOENTROPY 0x0400 |
| 477d3c1c | 110 | #define INTR_NOPOLL 0x0800 /* interrupt cannot be polled (e.g. ata) */ |
| bbe77fc3 | 111 | |
| e126caf1 MD |
112 | enum intr_trigger { |
| 113 | INTR_TRIGGER_CONFORM = 0, | |
| 114 | INTR_TRIGGER_EDGE = 1, | |
| 115 | INTR_TRIGGER_LEVEL = 2 | |
| 116 | }; | |
| 117 | ||
| 118 | enum intr_polarity { | |
| 119 | INTR_POLARITY_CONFORM = 0, | |
| 120 | INTR_POLARITY_HIGH = 1, | |
| 121 | INTR_POLARITY_LOW = 2 | |
| 984263bc | 122 | }; |
| 984263bc MD |
123 | |
| 124 | typedef int (*devop_t)(void); | |
| 125 | ||
| 984263bc MD |
126 | /* |
| 127 | * Definitions for drivers which need to keep simple lists of resources | |
| 128 | * for their child devices. | |
| 129 | */ | |
| 130 | struct resource; | |
| 131 | ||
| 132 | struct resource_list_entry { | |
| 133 | SLIST_ENTRY(resource_list_entry) link; | |
| 134 | int type; /* type argument to alloc_resource */ | |
| 135 | int rid; /* resource identifier */ | |
| 136 | struct resource *res; /* the real resource when allocated */ | |
| 137 | u_long start; /* start of resource range */ | |
| 138 | u_long end; /* end of resource range */ | |
| 139 | u_long count; /* count within range */ | |
| 140 | }; | |
| 141 | SLIST_HEAD(resource_list, resource_list_entry); | |
| 142 | ||
| 7490f18b SS |
143 | #endif /* _KERNEL || _KERNEL_STRUCTURES */ |
| 144 | #ifdef _KERNEL | |
| 145 | ||
| 71fc104f HT |
146 | /** |
| 147 | * devctl hooks. Typically one should use the devctl_notify | |
| 148 | * hook to send the message. However, devctl_queue_data is also | |
| 149 | * included in case devctl_notify isn't sufficiently general. | |
| 150 | */ | |
| 151 | boolean_t devctl_process_running(void); | |
| 152 | void devctl_notify(const char *__system, const char *__subsystem, | |
| 153 | const char *__type, const char *__data); | |
| 154 | void devctl_queue_data(char *__data); | |
| 155 | ||
| 984263bc MD |
156 | /* |
| 157 | * Initialise a resource list. | |
| 158 | */ | |
| 159 | void resource_list_init(struct resource_list *rl); | |
| 160 | ||
| 161 | /* | |
| 162 | * Reclaim memory used by a resource list. | |
| 163 | */ | |
| 164 | void resource_list_free(struct resource_list *rl); | |
| 165 | ||
| 166 | /* | |
| 167 | * Add a resource entry or modify an existing entry if one exists with | |
| 168 | * the same type and rid. | |
| 169 | */ | |
| 170 | void resource_list_add(struct resource_list *rl, | |
| 171 | int type, int rid, | |
| 172 | u_long start, u_long end, u_long count); | |
| 173 | ||
| 174 | /* | |
| 175 | * Find a resource entry by type and rid. | |
| 176 | */ | |
| 177 | struct resource_list_entry* | |
| 178 | resource_list_find(struct resource_list *rl, | |
| 179 | int type, int rid); | |
| 180 | ||
| 181 | /* | |
| 182 | * Delete a resource entry. | |
| 183 | */ | |
| 184 | void resource_list_delete(struct resource_list *rl, | |
| 185 | int type, int rid); | |
| 186 | ||
| 187 | /* | |
| 188 | * Implement BUS_ALLOC_RESOURCE by looking up a resource from the list | |
| 189 | * and passing the allocation up to the parent of bus. This assumes | |
| 190 | * that the first entry of device_get_ivars(child) is a struct | |
| 191 | * resource_list. This also handles 'passthrough' allocations where a | |
| 192 | * child is a remote descendant of bus by passing the allocation up to | |
| 193 | * the parent of bus. | |
| 194 | */ | |
| 195 | struct resource * | |
| 196 | resource_list_alloc(struct resource_list *rl, | |
| 197 | device_t bus, device_t child, | |
| 198 | int type, int *rid, | |
| 199 | u_long start, u_long end, | |
| 200 | u_long count, u_int flags); | |
| 201 | ||
| 202 | /* | |
| 203 | * Implement BUS_RELEASE_RESOURCE. | |
| 204 | */ | |
| 205 | int resource_list_release(struct resource_list *rl, | |
| 206 | device_t bus, device_t child, | |
| 207 | int type, int rid, struct resource *res); | |
| 208 | ||
| 209 | /* | |
| 210 | * Print all resources of a specified type, for use in bus_print_child. | |
| 211 | * The name is printed if at least one resource of the given type is available. | |
| 212 | * The format ist used to print resource start and end. | |
| 213 | */ | |
| 214 | int resource_list_print_type(struct resource_list *rl, | |
| 215 | const char *name, int type, | |
| 216 | const char *format); | |
| 217 | ||
| 218 | /* | |
| 219 | * The root bus, to which all top-level busses are attached. | |
| 220 | */ | |
| 221 | extern device_t root_bus; | |
| 984263bc MD |
222 | void root_bus_configure(void); |
| 223 | ||
| 224 | /* | |
| 225 | * Useful functions for implementing busses. | |
| 226 | */ | |
| 227 | ||
| 228 | int bus_generic_activate_resource(device_t dev, device_t child, int type, | |
| 229 | int rid, struct resource *r); | |
| e126caf1 MD |
230 | struct resource * |
| 231 | bus_generic_alloc_resource(device_t bus, device_t child, | |
| 232 | int type, int *rid, | |
| 233 | u_long start, u_long end, | |
| 234 | u_long count, u_int flags); | |
| 235 | struct resource_list * | |
| 236 | bus_generic_get_resource_list (device_t, device_t); | |
| 237 | ||
| 238 | int bus_generic_config_intr(device_t, int, enum intr_trigger, | |
| 239 | enum intr_polarity); | |
| 984263bc | 240 | int bus_generic_attach(device_t dev); |
| 22457186 | 241 | int bus_generic_child_present(device_t dev, device_t child); |
| 984263bc MD |
242 | int bus_generic_deactivate_resource(device_t dev, device_t child, int type, |
| 243 | int rid, struct resource *r); | |
| 244 | int bus_generic_detach(device_t dev); | |
| e9cb6d99 | 245 | int bus_generic_disable_intr(device_t dev, device_t child, void *cookie); |
| 984263bc | 246 | void bus_generic_driver_added(device_t dev, driver_t *driver); |
| 67a2436e | 247 | void bus_generic_enable_intr(device_t dev, device_t child, void *cookie); |
| 984263bc MD |
248 | int bus_print_child_header(device_t dev, device_t child); |
| 249 | int bus_print_child_footer(device_t dev, device_t child); | |
| 250 | int bus_generic_print_child(device_t dev, device_t child); | |
| 39b5d600 MD |
251 | int bus_generic_identify(driver_t *driver, device_t parent); |
| 252 | int bus_generic_identify_sameunit(driver_t *driver, device_t parent); | |
| 984263bc | 253 | int bus_generic_probe(device_t dev); |
| 39b5d600 | 254 | int bus_generic_probe_hack(device_t dev); |
| 2581072f | 255 | device_t bus_generic_add_child(device_t, device_t, int, const char *, int); |
| 984263bc MD |
256 | int bus_generic_read_ivar(device_t dev, device_t child, int which, |
| 257 | uintptr_t *result); | |
| 258 | int bus_generic_release_resource(device_t bus, device_t child, | |
| 259 | int type, int rid, struct resource *r); | |
| 2581072f MD |
260 | int bus_generic_get_resource(device_t dev, device_t child, int type, |
| 261 | int rid, u_long *startp, u_long *countp); | |
| 262 | int bus_generic_set_resource(device_t dev, device_t child, int type, | |
| 263 | int rid, u_long start, u_long count); | |
| 264 | void bus_generic_delete_resource(device_t dev, device_t child, | |
| 265 | int type, int rid); | |
| 984263bc MD |
266 | int bus_generic_resume(device_t dev); |
| 267 | int bus_generic_setup_intr(device_t dev, device_t child, | |
| 268 | struct resource *irq, int flags, | |
| e9cb6d99 MD |
269 | driver_intr_t *intr, void *arg, |
| 270 | void **cookiep, lwkt_serialize_t serializer); | |
| 984263bc MD |
271 | int bus_generic_shutdown(device_t dev); |
| 272 | int bus_generic_suspend(device_t dev); | |
| 273 | int bus_generic_teardown_intr(device_t dev, device_t child, | |
| 274 | struct resource *irq, void *cookie); | |
| 275 | int bus_generic_write_ivar(device_t dev, device_t child, int which, | |
| 276 | uintptr_t value); | |
| 277 | ||
| e126caf1 MD |
278 | struct resource * |
| 279 | bus_generic_rl_alloc_resource (device_t, device_t, int, int *, | |
| 280 | u_long, u_long, u_long, u_int); | |
| 281 | void bus_generic_rl_delete_resource (device_t, device_t, int, int); | |
| 282 | int bus_generic_rl_get_resource (device_t, device_t, int, int, u_long *, | |
| 283 | u_long *); | |
| 284 | int bus_generic_rl_set_resource (device_t, device_t, int, int, u_long, | |
| 285 | u_long); | |
| 286 | int bus_generic_rl_release_resource (device_t, device_t, int, int, | |
| 287 | struct resource *); | |
| 288 | ||
| 984263bc MD |
289 | /* |
| 290 | * Wrapper functions for the BUS_*_RESOURCE methods to make client code | |
| 291 | * a little simpler. | |
| 292 | */ | |
| 43167546 HT |
293 | struct resource_spec { |
| 294 | int type; | |
| 295 | int rid; | |
| 296 | int flags; | |
| 297 | }; | |
| 298 | ||
| 299 | int bus_alloc_resources(device_t dev, struct resource_spec *rs, | |
| 300 | struct resource **res); | |
| 301 | void bus_release_resources(device_t dev, const struct resource_spec *rs, | |
| 302 | struct resource **res); | |
| 303 | ||
| 984263bc MD |
304 | struct resource *bus_alloc_resource(device_t dev, int type, int *rid, |
| 305 | u_long start, u_long end, u_long count, | |
| 306 | u_int flags); | |
| 307 | int bus_activate_resource(device_t dev, int type, int rid, | |
| 308 | struct resource *r); | |
| 309 | int bus_deactivate_resource(device_t dev, int type, int rid, | |
| 310 | struct resource *r); | |
| e9cb6d99 | 311 | int bus_disable_intr(device_t dev, void *cookie); |
| 67a2436e | 312 | void bus_enable_intr(device_t dev, void *cookie); |
| 984263bc MD |
313 | int bus_release_resource(device_t dev, int type, int rid, |
| 314 | struct resource *r); | |
| 315 | int bus_setup_intr(device_t dev, struct resource *r, int flags, | |
| e9cb6d99 MD |
316 | driver_intr_t handler, void *arg, |
| 317 | void **cookiep, lwkt_serialize_t serializer); | |
| 984263bc MD |
318 | int bus_teardown_intr(device_t dev, struct resource *r, void *cookie); |
| 319 | int bus_set_resource(device_t dev, int type, int rid, | |
| 320 | u_long start, u_long count); | |
| 321 | int bus_get_resource(device_t dev, int type, int rid, | |
| 322 | u_long *startp, u_long *countp); | |
| 323 | u_long bus_get_resource_start(device_t dev, int type, int rid); | |
| 324 | u_long bus_get_resource_count(device_t dev, int type, int rid); | |
| 325 | void bus_delete_resource(device_t dev, int type, int rid); | |
| cac6f3da JS |
326 | int bus_child_present(device_t child); |
| 327 | int bus_child_pnpinfo_str(device_t child, char *buf, size_t buflen); | |
| 328 | int bus_child_location_str(device_t child, char *buf, size_t buflen); | |
| 984263bc | 329 | |
| 07d2fd35 HP |
330 | static __inline struct resource * |
| 331 | bus_alloc_resource_any(device_t dev, int type, int *rid, u_int flags) | |
| 332 | { | |
| 333 | return (bus_alloc_resource(dev, type, rid, 0ul, ~0ul, 1, flags)); | |
| 334 | } | |
| 335 | ||
| 984263bc MD |
336 | /* |
| 337 | * Access functions for device. | |
| 338 | */ | |
| 339 | device_t device_add_child(device_t dev, const char *name, int unit); | |
| 340 | device_t device_add_child_ordered(device_t dev, int order, | |
| 341 | const char *name, int unit); | |
| 342 | void device_busy(device_t dev); | |
| 343 | int device_delete_child(device_t dev, device_t child); | |
| 344 | int device_detach(device_t dev); | |
| 345 | void device_disable(device_t dev); | |
| 346 | void device_enable(device_t dev); | |
| 347 | device_t device_find_child(device_t dev, const char *classname, | |
| 348 | int unit); | |
| 349 | const char *device_get_desc(device_t dev); | |
| 350 | devclass_t device_get_devclass(device_t dev); | |
| 351 | driver_t *device_get_driver(device_t dev); | |
| 352 | u_int32_t device_get_flags(device_t dev); | |
| 353 | device_t device_get_parent(device_t dev); | |
| 354 | int device_get_children(device_t dev, device_t **listp, int *countp); | |
| 355 | void *device_get_ivars(device_t dev); | |
| 356 | void device_set_ivars(device_t dev, void *ivars); | |
| 357 | const char *device_get_name(device_t dev); | |
| 358 | const char *device_get_nameunit(device_t dev); | |
| 359 | void *device_get_softc(device_t dev); | |
| 360 | device_state_t device_get_state(device_t dev); | |
| 361 | int device_get_unit(device_t dev); | |
| 362 | int device_is_alive(device_t dev); /* did probe succeed? */ | |
| 2140e77f | 363 | int device_is_attached(device_t dev); /* did attach succeed? */ |
| 984263bc MD |
364 | int device_is_enabled(device_t dev); |
| 365 | int device_is_quiet(device_t dev); | |
| 366 | int device_print_prettyname(device_t dev); | |
| 367 | int device_printf(device_t dev, const char *, ...) __printflike(2, 3); | |
| 368 | int device_probe_and_attach(device_t dev); | |
| 369 | void device_quiet(device_t dev); | |
| 370 | void device_set_desc(device_t dev, const char* desc); | |
| 371 | void device_set_desc_copy(device_t dev, const char* desc); | |
| 372 | int device_set_devclass(device_t dev, const char *classname); | |
| 373 | int device_set_driver(device_t dev, driver_t *driver); | |
| 374 | void device_set_flags(device_t dev, u_int32_t flags); | |
| 375 | void device_set_softc(device_t dev, void *softc); | |
| dbcd0c9b | 376 | void device_set_async_attach(device_t dev, int enable); |
| 984263bc MD |
377 | int device_set_unit(device_t dev, int unit); /* XXX DONT USE XXX */ |
| 378 | int device_shutdown(device_t dev); | |
| 379 | void device_unbusy(device_t dev); | |
| 380 | void device_verbose(device_t dev); | |
| 381 | ||
| 382 | /* | |
| 383 | * Access functions for devclass. | |
| 384 | */ | |
| 91a0c258 JS |
385 | int devclass_add_driver(devclass_t dc, kobj_class_t driver); |
| 386 | int devclass_delete_driver(devclass_t dc, kobj_class_t driver); | |
| 984263bc MD |
387 | devclass_t devclass_create(const char *classname); |
| 388 | devclass_t devclass_find(const char *classname); | |
| 2581072f | 389 | device_t devclass_find_unit(const char *classname, int unit); |
| 91a0c258 | 390 | kobj_class_t devclass_find_driver(devclass_t dc, const char *classname); |
| 984263bc MD |
391 | const char *devclass_get_name(devclass_t dc); |
| 392 | device_t devclass_get_device(devclass_t dc, int unit); | |
| 393 | void *devclass_get_softc(devclass_t dc, int unit); | |
| 394 | int devclass_get_devices(devclass_t dc, device_t **listp, int *countp); | |
| 5ebadb2c | 395 | int devclass_get_drivers(devclass_t dc, driver_t ***listp, int *countp); |
| 7d58d14b | 396 | int devclass_get_count(devclass_t dc); |
| 984263bc | 397 | int devclass_get_maxunit(devclass_t dc); |
| 91a0c258 JS |
398 | void devclass_set_parent(devclass_t dc, devclass_t pdc); |
| 399 | devclass_t devclass_get_parent(devclass_t dc); | |
| 984263bc MD |
400 | |
| 401 | /* | |
| 402 | * Access functions for device resources. | |
| 403 | */ | |
| 404 | ||
| 405 | int resource_int_value(const char *name, int unit, const char *resname, | |
| 406 | int *result); | |
| 407 | int resource_long_value(const char *name, int unit, const char *resname, | |
| 408 | long *result); | |
| 409 | int resource_string_value(const char *name, int unit, const char *resname, | |
| 410 | char **result); | |
| e126caf1 | 411 | int resource_disabled(const char *name, int unit); |
| 984263bc MD |
412 | int resource_query_string(int i, const char *resname, const char *value); |
| 413 | char *resource_query_name(int i); | |
| 414 | int resource_query_unit(int i); | |
| 415 | int resource_locate(int i, const char *resname); | |
| 416 | int resource_set_int(const char *name, int unit, const char *resname, | |
| 417 | int value); | |
| 418 | int resource_set_long(const char *name, int unit, const char *resname, | |
| 419 | long value); | |
| 420 | int resource_set_string(const char *name, int unit, const char *resname, | |
| 421 | const char *value); | |
| 422 | int resource_count(void); | |
| 423 | ||
| 0010e23a HT |
424 | /* |
| 425 | * Functions for maintaining and checking consistency of | |
| 426 | * bus information exported to userspace. | |
| 427 | */ | |
| 428 | int bus_data_generation_check(int generation); | |
| 429 | void bus_data_generation_update(void); | |
| 430 | ||
| 558a398b SS |
431 | /** |
| 432 | * Some convenience defines for probe routines to return. These are just | |
| 433 | * suggested values, and there's nothing magical about them. | |
| 434 | * BUS_PROBE_SPECIFIC is for devices that cannot be reprobed, and that no | |
| 435 | * possible other driver may exist (typically legacy drivers who don't fallow | |
| 436 | * all the rules, or special needs drivers). BUS_PROBE_VENDOR is the | |
| 437 | * suggested value that vendor supplied drivers use. This is for source or | |
| 438 | * binary drivers that are not yet integrated into the FreeBSD tree. Its use | |
| 439 | * in the base OS is prohibited. BUS_PROBE_DEFAULT is the normal return value | |
| 440 | * for drivers to use. It is intended that nearly all of the drivers in the | |
| 441 | * tree should return this value. BUS_PROBE_LOW_PRIORITY are for drivers that | |
| 442 | * have special requirements like when there are two drivers that support | |
| 443 | * overlapping series of hardware devices. In this case the one that supports | |
| 444 | * the older part of the line would return this value, while the one that | |
| 445 | * supports the newer ones would return BUS_PROBE_DEFAULT. BUS_PROBE_GENERIC | |
| 446 | * is for drivers that wish to have a generic form and a specialized form, | |
| 447 | * like is done with the pci bus and the acpi pci bus. BUS_PROBE_HOOVER is | |
| 448 | * for those busses that implement a generic device place-holder for devices on | |
| 449 | * the bus that have no more specific driver for them (aka ugen). | |
| 450 | */ | |
| 451 | #define BUS_PROBE_SPECIFIC 0 /* Only I can use this device */ | |
| 452 | #if notyet | |
| 453 | #define BUS_PROBE_VENDOR (-10) /* Vendor supplied driver */ | |
| 454 | #define BUS_PROBE_DEFAULT (-20) /* Base OS default driver */ | |
| 455 | #define BUS_PROBE_LOW_PRIORITY (-40) /* Older, less desirable drivers */ | |
| 456 | #define BUS_PROBE_GENERIC (-100) /* generic driver for dev */ | |
| 457 | #define BUS_PROBE_HOOVER (-500) /* Generic dev for all devs on bus */ | |
| 458 | #else | |
| 459 | #define BUS_PROBE_VENDOR 0 | |
| 460 | #define BUS_PROBE_DEFAULT 0 | |
| 461 | #define BUS_PROBE_LOW_PRIORITY 0 | |
| 462 | #define BUS_PROBE_GENERIC 0 | |
| 463 | #define BUS_PROBE_HOOVER 0 | |
| 464 | #endif | |
| 465 | ||
| 984263bc MD |
466 | /* |
| 467 | * Shorthand for constructing method tables. | |
| 468 | */ | |
| 80eff43d | 469 | #define DEVMETHOD KOBJMETHOD |
| 984263bc MD |
470 | |
| 471 | /* | |
| 472 | * Some common device interfaces. | |
| 473 | */ | |
| 474 | #include "device_if.h" | |
| 475 | #include "bus_if.h" | |
| 476 | ||
| 477 | struct module; | |
| 478 | ||
| 479 | int driver_module_handler(struct module *, int, void *); | |
| 480 | ||
| 481 | /* | |
| 482 | * Module support for automatically adding drivers to busses. | |
| 483 | */ | |
| 484 | struct driver_module_data { | |
| 485 | int (*dmd_chainevh)(struct module *, int, void *); | |
| 486 | void *dmd_chainarg; | |
| 487 | const char *dmd_busname; | |
| 91a0c258 | 488 | kobj_class_t dmd_driver; |
| 984263bc MD |
489 | devclass_t *dmd_devclass; |
| 490 | }; | |
| 491 | ||
| 492 | #define DRIVER_MODULE(name, busname, driver, devclass, evh, arg) \ | |
| 493 | \ | |
| 984263bc MD |
494 | static struct driver_module_data name##_##busname##_driver_mod = { \ |
| 495 | evh, arg, \ | |
| 496 | #busname, \ | |
| 91a0c258 | 497 | (kobj_class_t) &driver, \ |
| 984263bc MD |
498 | &devclass \ |
| 499 | }; \ | |
| 500 | \ | |
| 501 | static moduledata_t name##_##busname##_mod = { \ | |
| 502 | #busname "/" #name, \ | |
| 503 | driver_module_handler, \ | |
| 504 | &name##_##busname##_driver_mod \ | |
| 505 | }; \ | |
| 506 | DECLARE_MODULE(name##_##busname, name##_##busname##_mod, \ | |
| 507 | SI_SUB_DRIVERS, SI_ORDER_MIDDLE) | |
| 508 | ||
| 89ffa1cf SS |
509 | /** |
| 510 | * Shorthand macros, taking resource argument | |
| 511 | */ | |
| 512 | ||
| 513 | #define bus_barrier(r, o, l, f) \ | |
| 514 | bus_space_barrier((r)->r_bustag, (r)->r_bushandle, (o), (l), (f)) | |
| 515 | #define bus_read_1(r, o) \ | |
| 516 | bus_space_read_1((r)->r_bustag, (r)->r_bushandle, (o)) | |
| 517 | #define bus_read_multi_1(r, o, d, c) \ | |
| 518 | bus_space_read_multi_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 519 | #define bus_read_region_1(r, o, d, c) \ | |
| 520 | bus_space_read_region_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 521 | #define bus_set_multi_1(r, o, v, c) \ | |
| 522 | bus_space_set_multi_1((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 523 | #define bus_set_region_1(r, o, v, c) \ | |
| 524 | bus_space_set_region_1((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 525 | #define bus_write_1(r, o, v) \ | |
| 526 | bus_space_write_1((r)->r_bustag, (r)->r_bushandle, (o), (v)) | |
| 527 | #define bus_write_multi_1(r, o, d, c) \ | |
| 528 | bus_space_write_multi_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 529 | #define bus_write_region_1(r, o, d, c) \ | |
| 530 | bus_space_write_region_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 531 | #define bus_read_stream_1(r, o) \ | |
| 532 | bus_space_read_stream_1((r)->r_bustag, (r)->r_bushandle, (o)) | |
| 533 | #define bus_read_multi_stream_1(r, o, d, c) \ | |
| 534 | bus_space_read_multi_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 535 | #define bus_read_region_stream_1(r, o, d, c) \ | |
| 536 | bus_space_read_region_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 537 | #define bus_set_multi_stream_1(r, o, v, c) \ | |
| 538 | bus_space_set_multi_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 539 | #define bus_set_region_stream_1(r, o, v, c) \ | |
| 540 | bus_space_set_region_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 541 | #define bus_write_stream_1(r, o, v) \ | |
| 542 | bus_space_write_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (v)) | |
| 543 | #define bus_write_multi_stream_1(r, o, d, c) \ | |
| 544 | bus_space_write_multi_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 545 | #define bus_write_region_stream_1(r, o, d, c) \ | |
| 546 | bus_space_write_region_stream_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 547 | #define bus_read_2(r, o) \ | |
| 548 | bus_space_read_2((r)->r_bustag, (r)->r_bushandle, (o)) | |
| 549 | #define bus_read_multi_2(r, o, d, c) \ | |
| 550 | bus_space_read_multi_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 551 | #define bus_read_region_2(r, o, d, c) \ | |
| 552 | bus_space_read_region_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 553 | #define bus_set_multi_2(r, o, v, c) \ | |
| 554 | bus_space_set_multi_2((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 555 | #define bus_set_region_2(r, o, v, c) \ | |
| 556 | bus_space_set_region_2((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 557 | #define bus_write_2(r, o, v) \ | |
| 558 | bus_space_write_2((r)->r_bustag, (r)->r_bushandle, (o), (v)) | |
| 559 | #define bus_write_multi_2(r, o, d, c) \ | |
| 560 | bus_space_write_multi_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 561 | #define bus_write_region_2(r, o, d, c) \ | |
| 562 | bus_space_write_region_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 563 | #define bus_read_stream_2(r, o) \ | |
| 564 | bus_space_read_stream_2((r)->r_bustag, (r)->r_bushandle, (o)) | |
| 565 | #define bus_read_multi_stream_2(r, o, d, c) \ | |
| 566 | bus_space_read_multi_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 567 | #define bus_read_region_stream_2(r, o, d, c) \ | |
| 568 | bus_space_read_region_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 569 | #define bus_set_multi_stream_2(r, o, v, c) \ | |
| 570 | bus_space_set_multi_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 571 | #define bus_set_region_stream_2(r, o, v, c) \ | |
| 572 | bus_space_set_region_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 573 | #define bus_write_stream_2(r, o, v) \ | |
| 574 | bus_space_write_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (v)) | |
| 575 | #define bus_write_multi_stream_2(r, o, d, c) \ | |
| 576 | bus_space_write_multi_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 577 | #define bus_write_region_stream_2(r, o, d, c) \ | |
| 578 | bus_space_write_region_stream_2((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 579 | #define bus_read_4(r, o) \ | |
| 580 | bus_space_read_4((r)->r_bustag, (r)->r_bushandle, (o)) | |
| 581 | #define bus_read_multi_4(r, o, d, c) \ | |
| 582 | bus_space_read_multi_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 583 | #define bus_read_region_4(r, o, d, c) \ | |
| 584 | bus_space_read_region_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 585 | #define bus_set_multi_4(r, o, v, c) \ | |
| 586 | bus_space_set_multi_4((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 587 | #define bus_set_region_4(r, o, v, c) \ | |
| 588 | bus_space_set_region_4((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 589 | #define bus_write_4(r, o, v) \ | |
| 590 | bus_space_write_4((r)->r_bustag, (r)->r_bushandle, (o), (v)) | |
| 591 | #define bus_write_multi_4(r, o, d, c) \ | |
| 592 | bus_space_write_multi_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 593 | #define bus_write_region_4(r, o, d, c) \ | |
| 594 | bus_space_write_region_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 595 | #define bus_read_stream_4(r, o) \ | |
| 596 | bus_space_read_stream_4((r)->r_bustag, (r)->r_bushandle, (o)) | |
| 597 | #define bus_read_multi_stream_4(r, o, d, c) \ | |
| 598 | bus_space_read_multi_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 599 | #define bus_read_region_stream_4(r, o, d, c) \ | |
| 600 | bus_space_read_region_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 601 | #define bus_set_multi_stream_4(r, o, v, c) \ | |
| 602 | bus_space_set_multi_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 603 | #define bus_set_region_stream_4(r, o, v, c) \ | |
| 604 | bus_space_set_region_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 605 | #define bus_write_stream_4(r, o, v) \ | |
| 606 | bus_space_write_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (v)) | |
| 607 | #define bus_write_multi_stream_4(r, o, d, c) \ | |
| 608 | bus_space_write_multi_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 609 | #define bus_write_region_stream_4(r, o, d, c) \ | |
| 610 | bus_space_write_region_stream_4((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 611 | #define bus_read_8(r, o) \ | |
| 612 | bus_space_read_8((r)->r_bustag, (r)->r_bushandle, (o)) | |
| 613 | #define bus_read_multi_8(r, o, d, c) \ | |
| 614 | bus_space_read_multi_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 615 | #define bus_read_region_8(r, o, d, c) \ | |
| 616 | bus_space_read_region_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 617 | #define bus_set_multi_8(r, o, v, c) \ | |
| 618 | bus_space_set_multi_8((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 619 | #define bus_set_region_8(r, o, v, c) \ | |
| 620 | bus_space_set_region_8((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 621 | #define bus_write_8(r, o, v) \ | |
| 622 | bus_space_write_8((r)->r_bustag, (r)->r_bushandle, (o), (v)) | |
| 623 | #define bus_write_multi_8(r, o, d, c) \ | |
| 624 | bus_space_write_multi_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 625 | #define bus_write_region_8(r, o, d, c) \ | |
| 626 | bus_space_write_region_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 627 | #define bus_read_stream_8(r, o) \ | |
| 628 | bus_space_read_stream_8((r)->r_bustag, (r)->r_bushandle, (o)) | |
| 629 | #define bus_read_multi_stream_8(r, o, d, c) \ | |
| 630 | bus_space_read_multi_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 631 | #define bus_read_region_stream_8(r, o, d, c) \ | |
| 632 | bus_space_read_region_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 633 | #define bus_set_multi_stream_8(r, o, v, c) \ | |
| 634 | bus_space_set_multi_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 635 | #define bus_set_region_stream_8(r, o, v, c) \ | |
| 636 | bus_space_set_region_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (v), (c)) | |
| 637 | #define bus_write_stream_8(r, o, v) \ | |
| 638 | bus_space_write_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (v)) | |
| 639 | #define bus_write_multi_stream_8(r, o, d, c) \ | |
| 640 | bus_space_write_multi_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 641 | #define bus_write_region_stream_8(r, o, d, c) \ | |
| 642 | bus_space_write_region_stream_8((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) | |
| 984263bc MD |
643 | #endif /* _KERNEL */ |
| 644 | ||
| 645 | #endif /* !_SYS_BUS_H_ */ |