1#- 2# Copyright (c) 1998-2004 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# 26# $FreeBSD$ 27# 28 29#include <sys/bus.h> 30 31/** 32 * @defgroup BUS bus - KObj methods for drivers of devices with children 33 * @brief A set of methods required device drivers that support 34 * child devices. 35 * @{ 36 */ 37INTERFACE bus; 38 39# 40# Default implementations of some methods. 41# 42CODE { 43 static struct resource * 44 null_alloc_resource(device_t dev, device_t child, 45 int type, int *rid, u_long start, u_long end, 46 u_long count, u_int flags) 47 { 48 return (0); 49 } 50 51 static int 52 null_remap_intr(device_t bus, device_t dev, u_int irq) 53 { 54 55 if (dev != NULL) 56 return (BUS_REMAP_INTR(dev, NULL, irq)); 57 return (ENXIO); 58 } 59}; 60 61/** 62 * @brief Print a description of a child device 63 * 64 * This is called from system code which prints out a description of a 65 * device. It should describe the attachment that the child has with 66 * the parent. For instance the TurboLaser bus prints which node the 67 * device is attached to. See bus_generic_print_child() for more 68 * information. 69 * 70 * @param _dev the device whose child is being printed 71 * @param _child the child device to describe 72 * 73 * @returns the number of characters output. 74 */ 75METHOD int print_child { 76 device_t _dev; 77 device_t _child; 78} DEFAULT bus_generic_print_child; 79 80/** 81 * @brief Print a notification about an unprobed child device. 82 * 83 * Called for each child device that did not succeed in probing for a 84 * driver. 85 * 86 * @param _dev the device whose child was being probed 87 * @param _child the child device which failed to probe 88 */ 89METHOD void probe_nomatch { 90 device_t _dev; 91 device_t _child; 92}; 93 94/** 95 * @brief Read the value of a bus-specific attribute of a device 96 * 97 * This method, along with BUS_WRITE_IVAR() manages a bus-specific set 98 * of instance variables of a child device. The intention is that 99 * each different type of bus defines a set of appropriate instance 100 * variables (such as ports and irqs for ISA bus etc.) 101 * 102 * This information could be given to the child device as a struct but 103 * that makes it hard for a bus to add or remove variables without 104 * forcing an edit and recompile for all drivers which may not be 105 * possible for vendor supplied binary drivers. 106 * 107 * This method copies the value of an instance variable to the 108 * location specified by @p *_result. 109 * 110 * @param _dev the device whose child was being examined 111 * @param _child the child device whose instance variable is 112 * being read 113 * @param _index the instance variable to read 114 * @param _result a loction to recieve the instance variable 115 * value 116 * 117 * @retval 0 success 118 * @retval ENOENT no such instance variable is supported by @p 119 * _dev 120 */ 121METHOD int read_ivar { 122 device_t _dev; 123 device_t _child; 124 int _index; 125 uintptr_t *_result; 126}; 127 128/** 129 * @brief Write the value of a bus-specific attribute of a device 130 * 131 * This method sets the value of an instance variable to @p _value. 132 * 133 * @param _dev the device whose child was being updated 134 * @param _child the child device whose instance variable is 135 * being written 136 * @param _index the instance variable to write 137 * @param _value the value to write to that instance variable 138 * 139 * @retval 0 success 140 * @retval ENOENT no such instance variable is supported by @p 141 * _dev 142 * @retval EINVAL the instance variable was recognised but 143 * contains a read-only value 144 */ 145METHOD int write_ivar { 146 device_t _dev; 147 device_t _child; 148 int _indx; 149 uintptr_t _value; 150}; 151 152/** 153 * @brief Notify a bus that a child was detached 154 * 155 * Called after the child's DEVICE_DETACH() method to allow the parent 156 * to reclaim any resources allocated on behalf of the child. 157 * 158 * @param _dev the device whose child changed state 159 * @param _child the child device which changed state 160 */ 161METHOD void child_detached { 162 device_t _dev; 163 device_t _child; 164}; 165 166/** 167 * @brief Notify a bus that a new driver was added 168 * 169 * Called when a new driver is added to the devclass which owns this 170 * bus. The generic implementation of this method attempts to probe and 171 * attach any un-matched children of the bus. 172 * 173 * @param _dev the device whose devclass had a new driver 174 * added to it 175 * @param _driver the new driver which was added 176 */ 177METHOD void driver_added { 178 device_t _dev; 179 driver_t *_driver; 180} DEFAULT bus_generic_driver_added; 181 182/** 183 * @brief Create a new child device 184 * 185 * For busses which use use drivers supporting DEVICE_IDENTIFY() to 186 * enumerate their devices, this method is used to create new 187 * device instances. The new device will be added after the last 188 * existing child with the same order. 189 * 190 * @param _dev the bus device which will be the parent of the 191 * new child device 192 * @param _order a value which is used to partially sort the 193 * children of @p _dev - devices created using 194 * lower values of @p _order appear first in @p 195 * _dev's list of children 196 * @param _name devclass name for new device or @c NULL if not 197 * specified 198 * @param _unit unit number for new device or @c -1 if not 199 * specified 200 */ 201METHOD device_t add_child { 202 device_t _dev; 203 int _order; 204 const char *_name; 205 int _unit; 206}; 207 208/** 209 * @brief Allocate a system resource 210 * 211 * This method is called by child devices of a bus to allocate resources. 212 * The types are defined in <machine/resource.h>; the meaning of the 213 * resource-ID field varies from bus to bus (but @p *rid == 0 is always 214 * valid if the resource type is). If a resource was allocated and the 215 * caller did not use the RF_ACTIVE to specify that it should be 216 * activated immediately, the caller is responsible for calling 217 * BUS_ACTIVATE_RESOURCE() when it actually uses the resource. 218 * 219 * @param _dev the parent device of @p _child 220 * @param _child the device which is requesting an allocation 221 * @param _type the type of resource to allocate 222 * @param _rid a pointer to the resource identifier 223 * @param _start hint at the start of the resource range - pass 224 * @c 0UL for any start address 225 * @param _end hint at the end of the resource range - pass 226 * @c ~0UL for any end address 227 * @param _count hint at the size of range required - pass @c 1 228 * for any size 229 * @param _flags any extra flags to control the resource 230 * allocation - see @c RF_XXX flags in 231 * <sys/rman.h> for details 232 * 233 * @returns the resource which was allocated or @c NULL if no 234 * resource could be allocated 235 */ 236METHOD struct resource * alloc_resource { 237 device_t _dev; 238 device_t _child; 239 int _type; 240 int *_rid; 241 u_long _start; 242 u_long _end; 243 u_long _count; 244 u_int _flags; 245} DEFAULT null_alloc_resource; 246 247/** 248 * @brief Activate a resource 249 * 250 * Activate a resource previously allocated with 251 * BUS_ALLOC_RESOURCE(). This may for instance map a memory region 252 * into the kernel's virtual address space. 253 * 254 * @param _dev the parent device of @p _child 255 * @param _child the device which allocated the resource 256 * @param _type the type of resource 257 * @param _rid the resource identifier 258 * @param _r the resource to activate 259 */ 260METHOD int activate_resource { 261 device_t _dev; 262 device_t _child; 263 int _type; 264 int _rid; 265 struct resource *_r; 266}; 267 268/** 269 * @brief Deactivate a resource 270 * 271 * Deactivate a resource previously allocated with 272 * BUS_ALLOC_RESOURCE(). This may for instance unmap a memory region 273 * from the kernel's virtual address space. 274 * 275 * @param _dev the parent device of @p _child 276 * @param _child the device which allocated the resource 277 * @param _type the type of resource 278 * @param _rid the resource identifier 279 * @param _r the resource to deactivate 280 */ 281METHOD int deactivate_resource { 282 device_t _dev; 283 device_t _child; 284 int _type; 285 int _rid; 286 struct resource *_r; 287}; 288 289/** 290 * @brief Release a resource 291 * 292 * Free a resource allocated by the BUS_ALLOC_RESOURCE. The @p _rid 293 * value must be the same as the one returned by BUS_ALLOC_RESOURCE() 294 * (which is not necessarily the same as the one the client passed). 295 * 296 * @param _dev the parent device of @p _child 297 * @param _child the device which allocated the resource 298 * @param _type the type of resource 299 * @param _rid the resource identifier 300 * @param _r the resource to release 301 */ 302METHOD int release_resource { 303 device_t _dev; 304 device_t _child; 305 int _type; 306 int _rid; 307 struct resource *_res; 308}; 309 310/** 311 * @brief Install an interrupt handler 312 * 313 * This method is used to associate an interrupt handler function with 314 * an irq resource. When the interrupt triggers, the function @p _intr 315 * will be called with the value of @p _arg as its single 316 * argument. The value returned in @p *_cookiep is used to cancel the 317 * interrupt handler - the caller should save this value to use in a 318 * future call to BUS_TEARDOWN_INTR(). 319 * 320 * @param _dev the parent device of @p _child 321 * @param _child the device which allocated the resource 322 * @param _irq the resource representing the interrupt 323 * @param _flags a set of bits from enum intr_type specifying 324 * the class of interrupt 325 * @param _intr the function to call when the interrupt 326 * triggers 327 * @param _arg a value to use as the single argument in calls 328 * to @p _intr 329 * @param _cookiep a pointer to a location to recieve a cookie 330 * value that may be used to remove the interrupt 331 * handler 332 */ 333METHOD int setup_intr { 334 device_t _dev; 335 device_t _child; 336 struct resource *_irq; 337 int _flags; 338 driver_filter_t *_filter; 339 driver_intr_t *_intr; 340 void *_arg; 341 void **_cookiep; 342}; 343 344/** 345 * @brief Uninstall an interrupt handler 346 * 347 * This method is used to disassociate an interrupt handler function 348 * with an irq resource. The value of @p _cookie must be the value 349 * returned from a previous call to BUS_SETUP_INTR(). 350 * 351 * @param _dev the parent device of @p _child 352 * @param _child the device which allocated the resource 353 * @param _irq the resource representing the interrupt 354 * @param _cookie the cookie value returned when the interrupt 355 * was originally registered 356 */ 357METHOD int teardown_intr { 358 device_t _dev; 359 device_t _child; 360 struct resource *_irq; 361 void *_cookie; 362}; 363 364/** 365 * @brief Define a resource which can be allocated with 366 * BUS_ALLOC_RESOURCE(). 367 * 368 * This method is used by some busses (typically ISA) to allow a 369 * driver to describe a resource range that it would like to 370 * allocate. The resource defined by @p _type and @p _rid is defined 371 * to start at @p _start and to include @p _count indices in its 372 * range. 373 * 374 * @param _dev the parent device of @p _child 375 * @param _child the device which owns the resource 376 * @param _type the type of resource 377 * @param _rid the resource identifier 378 * @param _start the start of the resource range 379 * @param _count the size of the resource range 380 */ 381METHOD int set_resource { 382 device_t _dev; 383 device_t _child; 384 int _type; 385 int _rid; 386 u_long _start; 387 u_long _count; 388}; 389 390/** 391 * @brief Describe a resource 392 * 393 * This method allows a driver to examine the range used for a given 394 * resource without actually allocating it. 395 * 396 * @param _dev the parent device of @p _child 397 * @param _child the device which owns the resource 398 * @param _type the type of resource 399 * @param _rid the resource identifier 400 * @param _start the address of a location to recieve the start 401 * index of the resource range 402 * @param _count the address of a location to recieve the size 403 * of the resource range 404 */ 405METHOD int get_resource { 406 device_t _dev; 407 device_t _child; 408 int _type; 409 int _rid; 410 u_long *_startp; 411 u_long *_countp; 412}; 413 414/** 415 * @brief Delete a resource. 416 * 417 * Use this to delete a resource (possibly one previously added with 418 * BUS_SET_RESOURCE()). 419 * 420 * @param _dev the parent device of @p _child 421 * @param _child the device which owns the resource 422 * @param _type the type of resource 423 * @param _rid the resource identifier 424 */ 425METHOD void delete_resource { 426 device_t _dev; 427 device_t _child; 428 int _type; 429 int _rid; 430}; 431 432/** 433 * @brief Return a struct resource_list. 434 * 435 * Used by drivers which use bus_generic_rl_alloc_resource() etc. to 436 * implement their resource handling. It should return the resource 437 * list of the given child device. 438 * 439 * @param _dev the parent device of @p _child 440 * @param _child the device which owns the resource list 441 */ 442METHOD struct resource_list * get_resource_list { 443 device_t _dev; 444 device_t _child; 445} DEFAULT bus_generic_get_resource_list; 446 447/** 448 * @brief Is the hardware described by @p _child still attached to the 449 * system? 450 * 451 * This method should return 0 if the device is not present. It 452 * should return -1 if it is present. Any errors in determining 453 * should be returned as a normal errno value. Client drivers are to 454 * assume that the device is present, even if there is an error 455 * determining if it is there. Busses are to try to avoid returning 456 * errors, but newcard will return an error if the device fails to 457 * implement this method. 458 * 459 * @param _dev the parent device of @p _child 460 * @param _child the device which is being examined 461 */ 462METHOD int child_present { 463 device_t _dev; 464 device_t _child; 465} DEFAULT bus_generic_child_present; 466 467/** 468 * @brief Returns the pnp info for this device. 469 * 470 * Return it as a string. If the string is insufficient for the 471 * storage, then return EOVERFLOW. 472 * 473 * @param _dev the parent device of @p _child 474 * @param _child the device which is being examined 475 * @param _buf the address of a buffer to receive the pnp 476 * string 477 * @param _buflen the size of the buffer pointed to by @p _buf 478 */ 479METHOD int child_pnpinfo_str { 480 device_t _dev; 481 device_t _child; 482 char *_buf; 483 size_t _buflen; 484}; 485 486/** 487 * @brief Returns the location for this device. 488 * 489 * Return it as a string. If the string is insufficient for the 490 * storage, then return EOVERFLOW. 491 * 492 * @param _dev the parent device of @p _child 493 * @param _child the device which is being examined 494 * @param _buf the address of a buffer to receive the location 495 * string 496 * @param _buflen the size of the buffer pointed to by @p _buf 497 */ 498METHOD int child_location_str { 499 device_t _dev; 500 device_t _child; 501 char *_buf; 502 size_t _buflen; 503}; 504 505/** 506 * @brief Allow drivers to request that an interrupt be bound to a specific 507 * CPU. 508 * 509 * @param _dev the parent device of @p _child 510 * @param _child the device which allocated the resource 511 * @param _irq the resource representing the interrupt 512 * @param _cpu the CPU to bind the interrupt to 513 */ 514METHOD int bind_intr { 515 device_t _dev; 516 device_t _child; 517 struct resource *_irq; 518 int _cpu; 519} DEFAULT bus_generic_bind_intr; 520 521/** 522 * @brief Allow (bus) drivers to specify the trigger mode and polarity 523 * of the specified interrupt. 524 * 525 * @param _dev the bus device 526 * @param _irq the interrupt number to modify 527 * @param _trig the trigger mode required 528 * @param _pol the interrupt polarity required 529 */ 530METHOD int config_intr { 531 device_t _dev; 532 int _irq; 533 enum intr_trigger _trig; 534 enum intr_polarity _pol; 535} DEFAULT bus_generic_config_intr; 536 537/** 538 * @brief Allow drivers to associate a description with an active 539 * interrupt handler. 540 * 541 * @param _dev the parent device of @p _child 542 * @param _child the device which allocated the resource 543 * @param _irq the resource representing the interrupt 544 * @param _cookie the cookie value returned when the interrupt 545 * was originally registered 546 * @param _descr the description to associate with the interrupt 547 */ 548METHOD int describe_intr { 549 device_t _dev; 550 device_t _child; 551 struct resource *_irq; 552 void *_cookie; 553 const char *_descr; 554} DEFAULT bus_generic_describe_intr; 555 556/** 557 * @brief Notify a (bus) driver about a child that the hints mechanism 558 * believes it has discovered. 559 * 560 * The bus is responsible for then adding the child in the right order 561 * and discovering other things about the child. The bus driver is 562 * free to ignore this hint, to do special things, etc. It is all up 563 * to the bus driver to interpret. 564 * 565 * This method is only called in response to the parent bus asking for 566 * hinted devices to be enumerated. 567 * 568 * @param _dev the bus device 569 * @param _dname the name of the device w/o unit numbers 570 * @param _dunit the unit number of the device 571 */ 572METHOD void hinted_child { 573 device_t _dev; 574 const char *_dname; 575 int _dunit; 576}; 577 578/** 579 * @brief Returns bus_dma_tag_t for use w/ devices on the bus. 580 * 581 * @param _dev the parent device of @p _child 582 * @param _child the device to which the tag will belong 583 */ 584METHOD bus_dma_tag_t get_dma_tag { 585 device_t _dev; 586 device_t _child; 587} DEFAULT bus_generic_get_dma_tag; 588 589/** 590 * @brief Allow the bus to determine the unit number of a device. 591 * 592 * @param _dev the parent device of @p _child 593 * @param _child the device whose unit is to be wired 594 * @param _name the name of the device's new devclass 595 * @param _unitp a pointer to the device's new unit value 596 */ 597METHOD void hint_device_unit { 598 device_t _dev; 599 device_t _child; 600 const char *_name; 601 int *_unitp; 602}; 603 604/** 605 * @brief Notify a bus that the bus pass level has been changed 606 * 607 * @param _dev the bus device 608 */ 609METHOD void new_pass { 610 device_t _dev; 611} DEFAULT bus_generic_new_pass; 612 613/** 614 * @brief Notify a bus that specified child's IRQ should be remapped. 615 * 616 * @param _dev the bus device 617 * @param _child the child device 618 * @param _irq the irq number 619 */ 620METHOD int remap_intr { 621 device_t _dev; 622 device_t _child; 623 u_int _irq; 624} DEFAULT null_remap_intr; 625