1 /* 2 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "device_manager.h" 8 9 #include <new> 10 #include <set> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 15 #include <KernelExport.h> 16 #include <Locker.h> 17 #include <module.h> 18 #include <PCI.h> 19 20 #include <fs/KPath.h> 21 #include <util/AutoLock.h> 22 #include <util/DoublyLinkedList.h> 23 #include <util/Stack.h> 24 25 #include "bus.h" 26 27 #define TRACE(a) dprintf a 28 29 #define DEVICE_MANAGER_ROOT_NAME "system/devices_root/driver_v1" 30 31 extern struct device_module_info gDeviceModuleInfo; 32 extern struct driver_module_info gDriverModuleInfo; 33 extern struct device_module_info gGenericVideoDeviceModuleInfo; 34 extern struct driver_module_info gGenericVideoDriverModuleInfo; 35 extern struct device_module_info gSpecificVideoDeviceModuleInfo; 36 extern struct driver_module_info gSpecificVideoDriverModuleInfo; 37 extern struct driver_module_info gBusModuleInfo; 38 extern struct driver_module_info gBusDriverModuleInfo; 39 40 extern "C" status_t _add_builtin_module(module_info *info); 41 extern "C" status_t _get_builtin_dependencies(void); 42 extern bool gDebugOutputEnabled; 43 // from libkernelland_emu.so 44 45 struct device_attr_private : device_attr, 46 DoublyLinkedListLinkImpl<device_attr_private> { 47 device_attr_private(); 48 device_attr_private(const device_attr& attr); 49 ~device_attr_private(); 50 51 status_t InitCheck(); 52 status_t CopyFrom(const device_attr& attr); 53 54 static int Compare(const device_attr* attrA, 55 const device_attr *attrB); 56 57 private: 58 void _Unset(); 59 }; 60 61 typedef DoublyLinkedList<device_attr_private> AttributeList; 62 63 // I/O resource 64 typedef struct io_resource_info { 65 struct io_resource_info *prev, *next; 66 device_node* owner; // associated node; NULL for temporary allocation 67 io_resource resource; // info about actual resource 68 } io_resource_info; 69 70 class Device : public DoublyLinkedListLinkImpl<Device> { 71 public: 72 Device(device_node* node, const char* path, 73 const char* moduleName); 74 ~Device(); 75 76 status_t InitCheck() const; 77 78 device_node* Node() const { return fNode; } 79 const char* Path() const { return fPath; } 80 const char* ModuleName() const { return fModuleName; } 81 82 status_t InitDevice(); 83 void UninitDevice(); 84 85 device_module_info* DeviceModule() const { return fDeviceModule; } 86 void* DeviceData() const { return fDeviceData; } 87 88 private: 89 device_node* fNode; 90 const char* fPath; 91 const char* fModuleName; 92 93 int32 fInitialized; 94 device_module_info* fDeviceModule; 95 void* fDeviceData; 96 }; 97 98 typedef DoublyLinkedList<Device> DeviceList; 99 typedef DoublyLinkedList<device_node> NodeList; 100 101 struct device_node : DoublyLinkedListLinkImpl<device_node> { 102 device_node(const char* moduleName, 103 const device_attr* attrs, 104 const io_resource* resources); 105 ~device_node(); 106 107 status_t InitCheck() const; 108 109 const char* ModuleName() const { return fModuleName; } 110 device_node* Parent() const { return fParent; } 111 AttributeList& Attributes() { return fAttributes; } 112 const AttributeList& Attributes() const { return fAttributes; } 113 114 status_t InitDriver(); 115 bool UninitDriver(); 116 void UninitUnusedDriver(); 117 118 // The following two are only valid, if the node's driver is 119 // initialized 120 driver_module_info* DriverModule() const { return fDriver; } 121 void* DriverData() const { return fDriverData; } 122 123 void AddChild(device_node *node); 124 void RemoveChild(device_node *node); 125 const NodeList& Children() const { return fChildren; } 126 void DeviceRemoved(); 127 128 status_t Register(device_node* parent); 129 status_t Probe(const char* devicePath, uint32 updateCycle); 130 bool IsRegistered() const { return fRegistered; } 131 bool IsInitialized() const { return fInitialized > 0; } 132 uint32 Flags() const { return fFlags; } 133 134 void Acquire(); 135 bool Release(); 136 137 const DeviceList& Devices() const { return fDevices; } 138 void AddDevice(Device* device); 139 void RemoveDevice(Device* device); 140 141 int CompareTo(const device_attr* attributes) const; 142 device_node* FindChild(const device_attr* attributes) const; 143 device_node* FindChild(const char* moduleName) const; 144 145 void Dump(int32 level = 0); 146 147 private: 148 status_t _RegisterFixed(uint32& registered); 149 bool _AlwaysRegisterDynamic(); 150 status_t _AddPath(Stack<KPath*>& stack, const char* path, 151 const char* subPath = NULL); 152 status_t _GetNextDriverPath(void*& cookie, KPath& _path); 153 status_t _GetNextDriver(void* list, 154 driver_module_info*& driver); 155 status_t _FindBestDriver(const char* path, 156 driver_module_info*& bestDriver, 157 float& bestSupport, 158 device_node* previous = NULL); 159 status_t _RegisterPath(const char* path); 160 status_t _RegisterDynamic(device_node* previous = NULL); 161 status_t _RemoveChildren(); 162 device_node* _FindCurrentChild(); 163 void _ReleaseWaiting(); 164 165 device_node* fParent; 166 NodeList fChildren; 167 int32 fRefCount; 168 int32 fInitialized; 169 bool fRegistered; 170 uint32 fFlags; 171 float fSupportsParent; 172 uint32 fLastUpdateCycle; 173 174 const char* fModuleName; 175 176 driver_module_info* fDriver; 177 void* fDriverData; 178 179 DeviceList fDevices; 180 AttributeList fAttributes; 181 }; 182 183 // flags in addition to those specified by B_DEVICE_FLAGS 184 enum node_flags { 185 NODE_FLAG_REGISTER_INITIALIZED = 0x00010000, 186 NODE_FLAG_DEVICE_REMOVED = 0x00020000, 187 NODE_FLAG_OBSOLETE_DRIVER = 0x00040000, 188 NODE_FLAG_WAITING_FOR_DRIVER = 0x00080000, 189 190 NODE_FLAG_PUBLIC_MASK = 0x0000ffff 191 }; 192 193 device_manager_info *gDeviceManager; 194 195 static device_node *sRootNode; 196 static recursive_lock sLock; 197 198 static uint32 sDriverUpdateCycle = 1; 199 // this is a *very* basic devfs emulation 200 201 202 // #pragma mark - 203 204 205 static device_attr_private* 206 find_attr(const device_node* node, const char* name, bool recursive, 207 type_code type) 208 { 209 do { 210 AttributeList::ConstIterator iterator 211 = node->Attributes().GetIterator(); 212 213 while (iterator.HasNext()) { 214 device_attr_private* attr = iterator.Next(); 215 216 if (type != B_ANY_TYPE && attr->type != type) 217 continue; 218 219 if (!strcmp(attr->name, name)) 220 return attr; 221 } 222 223 node = node->Parent(); 224 } while (node != NULL && recursive); 225 226 return NULL; 227 } 228 229 230 static void 231 put_level(int32 level) 232 { 233 while (level-- > 0) 234 dprintf(" "); 235 } 236 237 238 static void 239 dump_attribute(device_attr* attr, int32 level) 240 { 241 if (attr == NULL) 242 return; 243 244 put_level(level + 2); 245 dprintf("\"%s\" : ", attr->name); 246 switch (attr->type) { 247 case B_STRING_TYPE: 248 dprintf("string : \"%s\"", attr->value.string); 249 break; 250 case B_INT8_TYPE: 251 case B_UINT8_TYPE: 252 dprintf("uint8 : %u (%#x)", attr->value.ui8, attr->value.ui8); 253 break; 254 case B_INT16_TYPE: 255 case B_UINT16_TYPE: 256 dprintf("uint16 : %u (%#x)", attr->value.ui16, attr->value.ui16); 257 break; 258 case B_INT32_TYPE: 259 case B_UINT32_TYPE: 260 dprintf("uint32 : %lu (%#lx)", attr->value.ui32, attr->value.ui32); 261 break; 262 case B_INT64_TYPE: 263 case B_UINT64_TYPE: 264 dprintf("uint64 : %Lu (%#Lx)", attr->value.ui64, attr->value.ui64); 265 break; 266 default: 267 dprintf("raw data"); 268 } 269 dprintf("\n"); 270 } 271 272 273 static void 274 uninit_unused() 275 { 276 puts("uninit unused"); 277 RecursiveLocker _(sLock); 278 sRootNode->UninitUnusedDriver(); 279 } 280 281 282 static status_t 283 probe_path(const char* path) 284 { 285 printf("probe path \"%s\"\n", path); 286 RecursiveLocker _(sLock); 287 return sRootNode->Probe(path, sDriverUpdateCycle); 288 } 289 290 291 static void 292 close_path(void* cookie) 293 { 294 Device* device = (Device*)cookie; 295 if (device == NULL) 296 return; 297 298 printf("close path \"%s\" (node %p)\n", device->Path(), device->Node()); 299 device->UninitDevice(); 300 } 301 302 303 static Device* 304 get_device(device_node* node, const char* path) 305 { 306 DeviceList::ConstIterator iterator = node->Devices().GetIterator(); 307 while (iterator.HasNext()) { 308 Device* device = iterator.Next(); 309 if (!strcmp(device->Path(), path)) { 310 status_t status = device->InitDevice(); 311 if (status != B_OK) { 312 printf("opening path \"%s\" failed: %s\n", path, 313 strerror(status)); 314 return NULL; 315 } 316 317 printf("open path \"%s\" (node %p)\n", device->Path(), 318 device->Node()); 319 return device; 320 } 321 } 322 323 // search in children 324 325 NodeList::ConstIterator nodeIterator = node->Children().GetIterator(); 326 while (nodeIterator.HasNext()) { 327 device_node* child = nodeIterator.Next(); 328 329 Device* device = get_device(child, path); 330 if (device != NULL) 331 return device; 332 } 333 334 return NULL; 335 } 336 337 338 static void* 339 open_path(const char* path) 340 { 341 return get_device(sRootNode, path); 342 } 343 344 345 // #pragma mark - Device Manager module API 346 347 348 static status_t 349 rescan_node(device_node* node) 350 { 351 return B_ERROR; 352 } 353 354 355 static status_t 356 register_node(device_node* parent, const char* moduleName, 357 const device_attr* attrs, const io_resource* ioResources, 358 device_node** _node) 359 { 360 if ((parent == NULL && sRootNode != NULL) || moduleName == NULL) 361 return B_BAD_VALUE; 362 363 if (parent != NULL && parent->FindChild(attrs) != NULL) { 364 // A node like this one already exists for this parent 365 return B_NAME_IN_USE; 366 } 367 368 // TODO: handle I/O resources! 369 370 device_node *newNode = new(std::nothrow) device_node(moduleName, attrs, 371 ioResources); 372 if (newNode == NULL) 373 return B_NO_MEMORY; 374 375 TRACE(("%p: register node \"%s\", parent %p\n", newNode, moduleName, 376 parent)); 377 378 RecursiveLocker _(sLock); 379 380 status_t status = newNode->InitCheck(); 381 if (status != B_OK) 382 goto err1; 383 384 #if 0 385 // The following is done to reduce the stack usage of deeply nested 386 // child device nodes. 387 // There is no other need to delay the complete registration process 388 // the way done here. This approach is also slightly different as 389 // the registration might fail later than it used in case of errors. 390 391 if (!parent->IsRegistered()) { 392 // The parent has not been registered completely yet - child 393 // registration is deferred to the parent registration 394 return B_OK; 395 } 396 #endif 397 398 status = newNode->Register(parent); 399 if (status < B_OK) { 400 parent->RemoveChild(newNode); 401 goto err1; 402 } 403 404 if (_node) 405 *_node = newNode; 406 407 return B_OK; 408 409 err1: 410 newNode->Release(); 411 return status; 412 } 413 414 415 /*! Unregisters the device \a node. 416 417 If the node is currently in use, this function will return B_BUSY to 418 indicate that the node hasn't been removed yet - it will still remove 419 the node as soon as possible. 420 */ 421 static status_t 422 unregister_node(device_node* node) 423 { 424 TRACE(("unregister_node(node %p)\n", node)); 425 RecursiveLocker _(sLock); 426 427 bool initialized = node->IsInitialized(); 428 429 node->DeviceRemoved(); 430 431 return initialized ? B_BUSY : B_OK; 432 } 433 434 435 static status_t 436 get_driver(device_node* node, driver_module_info** _module, void** _data) 437 { 438 if (node->DriverModule() == NULL) 439 return B_NO_INIT; 440 441 if (_module != NULL) 442 *_module = node->DriverModule(); 443 if (_data != NULL) 444 *_data = node->DriverData(); 445 446 return B_OK; 447 } 448 449 450 static device_node* 451 get_root_node(void) 452 { 453 if (sRootNode != NULL) 454 sRootNode->Acquire(); 455 456 return sRootNode; 457 } 458 459 460 static status_t 461 get_next_child_node(device_node* parent, const device_attr* attributes, 462 device_node** _node) 463 { 464 RecursiveLocker _(sLock); 465 466 NodeList::ConstIterator iterator = parent->Children().GetIterator(); 467 device_node* last = *_node; 468 469 // skip those we already traversed 470 while (iterator.HasNext() && last != NULL) { 471 device_node* node = iterator.Next(); 472 473 if (node != last) 474 continue; 475 } 476 477 // find the next one that fits 478 while (iterator.HasNext()) { 479 device_node* node = iterator.Next(); 480 481 if (!node->IsRegistered()) 482 continue; 483 484 if (!node->CompareTo(attributes)) { 485 if (last != NULL) 486 last->Release(); 487 488 node->Acquire(); 489 *_node = node; 490 return B_OK; 491 } 492 } 493 494 if (last != NULL) 495 last->Release(); 496 497 return B_ENTRY_NOT_FOUND; 498 } 499 500 501 static device_node* 502 get_parent_node(device_node* node) 503 { 504 if (node == NULL) 505 return NULL; 506 507 RecursiveLocker _(sLock); 508 509 device_node* parent = node->Parent(); 510 parent->Acquire(); 511 512 return parent; 513 } 514 515 516 static void 517 put_node(device_node* node) 518 { 519 RecursiveLocker _(sLock); 520 node->Release(); 521 } 522 523 524 static status_t 525 publish_device(device_node *node, const char *path, const char *moduleName) 526 { 527 if (path == NULL || !path[0] || moduleName == NULL || !moduleName[0]) 528 return B_BAD_VALUE; 529 530 RecursiveLocker _(sLock); 531 dprintf("publish device: node %p, path %s, module %s\n", node, path, 532 moduleName); 533 534 Device* device = new(std::nothrow) Device(node, path, moduleName); 535 if (device == NULL) 536 return B_NO_MEMORY; 537 538 if (device->InitCheck() != B_OK) { 539 delete device; 540 return B_NO_MEMORY; 541 } 542 543 node->AddDevice(device); 544 return B_OK; 545 } 546 547 548 static status_t 549 unpublish_device(device_node *node, const char *path) 550 { 551 if (path == NULL) 552 return B_BAD_VALUE; 553 554 RecursiveLocker _(sLock); 555 556 DeviceList::ConstIterator iterator = node->Devices().GetIterator(); 557 while (iterator.HasNext()) { 558 Device* device = iterator.Next(); 559 if (!strcmp(device->Path(), path)) { 560 node->RemoveDevice(device); 561 delete device; 562 return B_OK; 563 } 564 } 565 566 return B_ENTRY_NOT_FOUND; 567 } 568 569 570 static status_t 571 get_attr_uint8(const device_node* node, const char* name, uint8* _value, 572 bool recursive) 573 { 574 if (node == NULL || name == NULL || _value == NULL) 575 return B_BAD_VALUE; 576 577 device_attr_private* attr = find_attr(node, name, recursive, B_UINT8_TYPE); 578 if (attr == NULL) 579 return B_NAME_NOT_FOUND; 580 581 *_value = attr->value.ui8; 582 return B_OK; 583 } 584 585 586 static status_t 587 get_attr_uint16(const device_node* node, const char* name, uint16* _value, 588 bool recursive) 589 { 590 if (node == NULL || name == NULL || _value == NULL) 591 return B_BAD_VALUE; 592 593 device_attr_private* attr = find_attr(node, name, recursive, B_UINT16_TYPE); 594 if (attr == NULL) 595 return B_NAME_NOT_FOUND; 596 597 *_value = attr->value.ui16; 598 return B_OK; 599 } 600 601 602 static status_t 603 get_attr_uint32(const device_node* node, const char* name, uint32* _value, 604 bool recursive) 605 { 606 if (node == NULL || name == NULL || _value == NULL) 607 return B_BAD_VALUE; 608 609 device_attr_private* attr = find_attr(node, name, recursive, B_UINT32_TYPE); 610 if (attr == NULL) 611 return B_NAME_NOT_FOUND; 612 613 *_value = attr->value.ui32; 614 return B_OK; 615 } 616 617 618 static status_t 619 get_attr_uint64(const device_node* node, const char* name, 620 uint64* _value, bool recursive) 621 { 622 if (node == NULL || name == NULL || _value == NULL) 623 return B_BAD_VALUE; 624 625 device_attr_private* attr = find_attr(node, name, recursive, B_UINT64_TYPE); 626 if (attr == NULL) 627 return B_NAME_NOT_FOUND; 628 629 *_value = attr->value.ui64; 630 return B_OK; 631 } 632 633 634 static status_t 635 get_attr_string(const device_node* node, const char* name, 636 const char** _value, bool recursive) 637 { 638 if (node == NULL || name == NULL || _value == NULL) 639 return B_BAD_VALUE; 640 641 device_attr_private* attr = find_attr(node, name, recursive, B_STRING_TYPE); 642 if (attr == NULL) 643 return B_NAME_NOT_FOUND; 644 645 *_value = attr->value.string; 646 return B_OK; 647 } 648 649 650 static status_t 651 get_attr_raw(const device_node* node, const char* name, const void** _data, 652 size_t* _length, bool recursive) 653 { 654 if (node == NULL || name == NULL || (_data == NULL && _length == NULL)) 655 return B_BAD_VALUE; 656 657 device_attr_private* attr = find_attr(node, name, recursive, B_RAW_TYPE); 658 if (attr == NULL) 659 return B_NAME_NOT_FOUND; 660 661 if (_data != NULL) 662 *_data = attr->value.raw.data; 663 if (_length != NULL) 664 *_length = attr->value.raw.length; 665 return B_OK; 666 } 667 668 669 static status_t 670 get_next_attr(device_node* node, device_attr** _attr) 671 { 672 if (node == NULL) 673 return B_BAD_VALUE; 674 675 device_attr_private* next; 676 device_attr_private* attr = *(device_attr_private**)_attr; 677 678 if (attr != NULL) { 679 // next attribute 680 next = attr->GetDoublyLinkedListLink()->next; 681 } else { 682 // first attribute 683 next = node->Attributes().First(); 684 } 685 686 *_attr = next; 687 688 return next ? B_OK : B_ENTRY_NOT_FOUND; 689 } 690 691 692 static struct device_manager_info sDeviceManagerModule = { 693 { 694 B_DEVICE_MANAGER_MODULE_NAME, 695 0, 696 NULL 697 }, 698 699 // device nodes 700 rescan_node, 701 register_node, 702 unregister_node, 703 get_driver, 704 get_root_node, 705 get_next_child_node, 706 get_parent_node, 707 put_node, 708 709 // devices 710 publish_device, 711 unpublish_device, 712 713 // attributes 714 get_attr_uint8, 715 get_attr_uint16, 716 get_attr_uint32, 717 get_attr_uint64, 718 get_attr_string, 719 get_attr_raw, 720 get_next_attr, 721 }; 722 723 724 // #pragma mark - device_attr 725 726 727 device_attr_private::device_attr_private() 728 { 729 name = NULL; 730 type = 0; 731 value.raw.data = NULL; 732 value.raw.length = 0; 733 } 734 735 736 device_attr_private::device_attr_private(const device_attr& attr) 737 { 738 CopyFrom(attr); 739 } 740 741 742 device_attr_private::~device_attr_private() 743 { 744 _Unset(); 745 } 746 747 748 status_t 749 device_attr_private::InitCheck() 750 { 751 return name != NULL ? B_OK : B_NO_INIT; 752 } 753 754 755 status_t 756 device_attr_private::CopyFrom(const device_attr& attr) 757 { 758 name = strdup(attr.name); 759 if (name == NULL) 760 return B_NO_MEMORY; 761 762 type = attr.type; 763 764 switch (type) { 765 case B_UINT8_TYPE: 766 case B_UINT16_TYPE: 767 case B_UINT32_TYPE: 768 case B_UINT64_TYPE: 769 value.ui64 = attr.value.ui64; 770 break; 771 772 case B_STRING_TYPE: 773 if (attr.value.string != NULL) { 774 value.string = strdup(attr.value.string); 775 if (value.string == NULL) { 776 _Unset(); 777 return B_NO_MEMORY; 778 } 779 } else 780 value.string = NULL; 781 break; 782 783 case B_RAW_TYPE: 784 value.raw.data = malloc(attr.value.raw.length); 785 if (value.raw.data == NULL) { 786 _Unset(); 787 return B_NO_MEMORY; 788 } 789 790 value.raw.length = attr.value.raw.length; 791 memcpy((void*)value.raw.data, attr.value.raw.data, 792 attr.value.raw.length); 793 break; 794 795 default: 796 return B_BAD_VALUE; 797 } 798 799 return B_OK; 800 } 801 802 803 void 804 device_attr_private::_Unset() 805 { 806 if (type == B_STRING_TYPE) 807 free((char*)value.string); 808 else if (type == B_RAW_TYPE) 809 free((void*)value.raw.data); 810 811 free((char*)name); 812 813 name = NULL; 814 value.raw.data = NULL; 815 value.raw.length = 0; 816 } 817 818 819 /*static*/ int 820 device_attr_private::Compare(const device_attr* attrA, const device_attr *attrB) 821 { 822 if (attrA->type != attrB->type) 823 return -1; 824 825 switch (attrA->type) { 826 case B_UINT8_TYPE: 827 return (int)attrA->value.ui8 - (int)attrB->value.ui8; 828 829 case B_UINT16_TYPE: 830 return (int)attrA->value.ui16 - (int)attrB->value.ui16; 831 832 case B_UINT32_TYPE: 833 if (attrA->value.ui32 > attrB->value.ui32) 834 return 1; 835 if (attrA->value.ui32 < attrB->value.ui32) 836 return -1; 837 return 0; 838 839 case B_UINT64_TYPE: 840 if (attrA->value.ui64 > attrB->value.ui64) 841 return 1; 842 if (attrA->value.ui64 < attrB->value.ui64) 843 return -1; 844 return 0; 845 846 case B_STRING_TYPE: 847 return strcmp(attrA->value.string, attrB->value.string); 848 849 case B_RAW_TYPE: 850 if (attrA->value.raw.length != attrB->value.raw.length) 851 return -1; 852 853 return memcmp(attrA->value.raw.data, attrB->value.raw.data, 854 attrA->value.raw.length); 855 } 856 857 return -1; 858 } 859 860 861 // #pragma mark - Device 862 863 864 Device::Device(device_node* node, const char* path, const char* moduleName) 865 : 866 fNode(node), 867 fInitialized(0), 868 fDeviceModule(NULL), 869 fDeviceData(NULL) 870 { 871 fPath = strdup(path); 872 fModuleName = strdup(moduleName); 873 } 874 875 876 Device::~Device() 877 { 878 free((char*)fPath); 879 free((char*)fModuleName); 880 } 881 882 883 status_t 884 Device::InitCheck() const 885 { 886 return fPath != NULL && fModuleName != NULL ? B_OK : B_NO_MEMORY; 887 } 888 889 890 status_t 891 Device::InitDevice() 892 { 893 if ((fNode->Flags() & NODE_FLAG_DEVICE_REMOVED) != 0) { 894 // TODO: maybe the device should be unlinked in devfs, too 895 return ENODEV; 896 } 897 if ((fNode->Flags() & NODE_FLAG_WAITING_FOR_DRIVER) != 0) 898 return B_BUSY; 899 900 if (fInitialized++ > 0) { 901 fNode->InitDriver(); 902 // acquire another reference to our parent as well 903 return B_OK; 904 } 905 906 status_t status = get_module(ModuleName(), (module_info**)&fDeviceModule); 907 if (status == B_OK) { 908 // our parent always has to be initialized 909 status = fNode->InitDriver(); 910 } 911 if (status < B_OK) { 912 fInitialized--; 913 return status; 914 } 915 916 if (fDeviceModule->init_device != NULL) 917 status = fDeviceModule->init_device(fNode->DriverData(), &fDeviceData); 918 919 if (status < B_OK) { 920 fNode->UninitDriver(); 921 fInitialized--; 922 923 put_module(ModuleName()); 924 fDeviceModule = NULL; 925 fDeviceData = NULL; 926 } 927 928 return status; 929 } 930 931 932 void 933 Device::UninitDevice() 934 { 935 if (fInitialized-- > 1) { 936 fNode->UninitDriver(); 937 return; 938 } 939 940 TRACE(("uninit driver for node %p\n", this)); 941 942 if (fDeviceModule->uninit_device != NULL) 943 fDeviceModule->uninit_device(fDeviceData); 944 945 fDeviceModule = NULL; 946 fDeviceData = NULL; 947 948 put_module(ModuleName()); 949 950 fNode->UninitDriver(); 951 } 952 953 954 // #pragma mark - device_node 955 956 957 /*! Allocate device node info structure; 958 initially, ref_count is one to make sure node won't get destroyed by mistake 959 */ 960 device_node::device_node(const char* moduleName, const device_attr* attrs, 961 const io_resource* resources) 962 { 963 fModuleName = strdup(moduleName); 964 if (fModuleName == NULL) 965 return; 966 967 fParent = NULL; 968 fRefCount = 1; 969 fInitialized = 0; 970 fRegistered = false; 971 fFlags = 0; 972 fSupportsParent = 0.0; 973 fLastUpdateCycle = 0; 974 fDriver = NULL; 975 fDriverData = NULL; 976 977 // copy attributes 978 979 while (attrs != NULL && attrs->name != NULL) { 980 device_attr_private* attr 981 = new(std::nothrow) device_attr_private(*attrs); 982 if (attr == NULL) 983 break; 984 985 fAttributes.Add(attr); 986 attrs++; 987 } 988 989 get_attr_uint32(this, B_DEVICE_FLAGS, &fFlags, false); 990 fFlags &= NODE_FLAG_PUBLIC_MASK; 991 } 992 993 994 device_node::~device_node() 995 { 996 TRACE(("delete node %p\n", this)); 997 ASSERT(DriverModule() == NULL); 998 999 if (Parent() != NULL) { 1000 if ((fFlags & NODE_FLAG_OBSOLETE_DRIVER) != 0) { 1001 // This driver has been obsoleted; another driver has been waiting 1002 // for us - make it available 1003 Parent()->_ReleaseWaiting(); 1004 } 1005 Parent()->RemoveChild(this); 1006 } 1007 1008 // Delete children 1009 NodeList::Iterator nodeIterator = fChildren.GetIterator(); 1010 while (nodeIterator.HasNext()) { 1011 device_node* child = nodeIterator.Next(); 1012 nodeIterator.Remove(); 1013 delete child; 1014 } 1015 1016 // Delete devices 1017 DeviceList::Iterator deviceIterator = fDevices.GetIterator(); 1018 while (deviceIterator.HasNext()) { 1019 Device* device = deviceIterator.Next(); 1020 deviceIterator.Remove(); 1021 // TODO: unpublish! 1022 delete device; 1023 } 1024 1025 // Delete attributes 1026 AttributeList::Iterator attrIterator = fAttributes.GetIterator(); 1027 while (attrIterator.HasNext()) { 1028 device_attr_private* attr = attrIterator.Next(); 1029 attrIterator.Remove(); 1030 delete attr; 1031 } 1032 1033 free((char*)fModuleName); 1034 } 1035 1036 1037 status_t 1038 device_node::InitCheck() const 1039 { 1040 return fModuleName != NULL ? B_OK : B_NO_MEMORY; 1041 } 1042 1043 1044 status_t 1045 device_node::InitDriver() 1046 { 1047 if (fInitialized++ > 0) { 1048 if (Parent() != NULL) { 1049 Parent()->InitDriver(); 1050 // acquire another reference to our parent as well 1051 } 1052 Acquire(); 1053 return B_OK; 1054 } 1055 1056 status_t status = get_module(ModuleName(), (module_info**)&fDriver); 1057 if (status == B_OK && Parent() != NULL) { 1058 // our parent always has to be initialized 1059 status = Parent()->InitDriver(); 1060 } 1061 if (status < B_OK) { 1062 fInitialized--; 1063 return status; 1064 } 1065 1066 if (fDriver->init_driver != NULL) 1067 status = fDriver->init_driver(this, &fDriverData); 1068 1069 if (status < B_OK) { 1070 if (Parent() != NULL) 1071 Parent()->UninitDriver(); 1072 fInitialized--; 1073 1074 put_module(ModuleName()); 1075 fDriver = NULL; 1076 fDriverData = NULL; 1077 return status; 1078 } 1079 1080 Acquire(); 1081 return B_OK; 1082 } 1083 1084 1085 bool 1086 device_node::UninitDriver() 1087 { 1088 if (fInitialized-- > 1) { 1089 if (Parent() != NULL) 1090 Parent()->UninitDriver(); 1091 Release(); 1092 return false; 1093 } 1094 1095 TRACE(("uninit driver for node %p\n", this)); 1096 1097 if (fDriver->uninit_driver != NULL) 1098 fDriver->uninit_driver(fDriverData); 1099 1100 fDriver = NULL; 1101 fDriverData = NULL; 1102 1103 put_module(ModuleName()); 1104 1105 if (Parent() != NULL) 1106 Parent()->UninitDriver(); 1107 Release(); 1108 1109 return true; 1110 } 1111 1112 1113 void 1114 device_node::AddChild(device_node* node) 1115 { 1116 // we must not be destroyed as long as we have children 1117 Acquire(); 1118 node->fParent = this; 1119 fChildren.Add(node); 1120 } 1121 1122 1123 void 1124 device_node::RemoveChild(device_node* node) 1125 { 1126 node->fParent = NULL; 1127 fChildren.Remove(node); 1128 Release(); 1129 } 1130 1131 1132 /*! Registers this node, and all of its children that have to be registered. 1133 Also initializes the driver and keeps it that way on return in case 1134 it returns successfully. 1135 */ 1136 status_t 1137 device_node::Register(device_node* parent) 1138 { 1139 // make it public 1140 if (parent != NULL) 1141 parent->AddChild(this); 1142 else 1143 sRootNode = this; 1144 1145 status_t status = InitDriver(); 1146 if (status != B_OK) 1147 return status; 1148 1149 if ((fFlags & B_KEEP_DRIVER_LOADED) != 0) { 1150 // We keep this driver loaded by having it always initialized 1151 InitDriver(); 1152 } 1153 1154 fFlags |= NODE_FLAG_REGISTER_INITIALIZED; 1155 // We don't uninitialize the driver - this is done by the caller 1156 // in order to save reinitializing during driver loading. 1157 1158 uint32 registered; 1159 status = _RegisterFixed(registered); 1160 if (status != B_OK) { 1161 UninitUnusedDriver(); 1162 return status; 1163 } 1164 if (registered > 0) { 1165 fRegistered = true; 1166 return B_OK; 1167 } 1168 1169 // Register the children the driver wants 1170 1171 if (DriverModule()->register_child_devices != NULL) { 1172 status = DriverModule()->register_child_devices(this); 1173 if (status != B_OK) { 1174 UninitUnusedDriver(); 1175 return status; 1176 } 1177 1178 if (!fChildren.IsEmpty()) { 1179 fRegistered = true; 1180 return B_OK; 1181 } 1182 } 1183 1184 // Register all possible child device nodes 1185 1186 status = _RegisterDynamic(); 1187 if (status == B_OK) 1188 fRegistered = true; 1189 else 1190 UninitUnusedDriver(); 1191 1192 return status; 1193 } 1194 1195 1196 /*! Registers any children that are identified via the B_DRIVER_FIXED_CHILD 1197 attribute. 1198 If any of these children cannot be registered, this call will fail (we 1199 don't remove children we already registered up to this point in this case). 1200 */ 1201 status_t 1202 device_node::_RegisterFixed(uint32& registered) 1203 { 1204 AttributeList::Iterator iterator = fAttributes.GetIterator(); 1205 registered = 0; 1206 1207 while (iterator.HasNext()) { 1208 device_attr_private* attr = iterator.Next(); 1209 if (strcmp(attr->name, B_DEVICE_FIXED_CHILD)) 1210 continue; 1211 1212 driver_module_info* driver; 1213 status_t status = get_module(attr->value.string, 1214 (module_info**)&driver); 1215 if (status != B_OK) 1216 return status; 1217 1218 if (driver->register_device != NULL) { 1219 status = driver->register_device(this); 1220 if (status == B_OK) 1221 registered++; 1222 } 1223 1224 put_module(attr->value.string); 1225 1226 if (status != B_OK) 1227 return status; 1228 } 1229 1230 return B_OK; 1231 } 1232 1233 1234 status_t 1235 device_node::_AddPath(Stack<KPath*>& stack, const char* basePath, 1236 const char* subPath) 1237 { 1238 KPath* path = new(std::nothrow) KPath; 1239 if (path == NULL) 1240 return B_NO_MEMORY; 1241 1242 status_t status = path->SetTo(basePath); 1243 if (status == B_OK && subPath != NULL && subPath[0]) 1244 status = path->Append(subPath); 1245 if (status == B_OK) 1246 status = stack.Push(path); 1247 1248 if (status != B_OK) 1249 delete path; 1250 1251 return status; 1252 } 1253 1254 1255 status_t 1256 device_node::_GetNextDriverPath(void*& cookie, KPath& _path) 1257 { 1258 Stack<KPath*>* stack = NULL; 1259 1260 if (cookie == NULL) { 1261 // find all paths and add them 1262 stack = new(std::nothrow) Stack<KPath*>(); 1263 if (stack == NULL) 1264 return B_NO_MEMORY; 1265 1266 StackDeleter<KPath*> stackDeleter(stack); 1267 uint16 type = 0; 1268 uint16 subType = 0; 1269 uint16 interface = 0; 1270 get_attr_uint16(this, B_DEVICE_TYPE, &type, false); 1271 get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false); 1272 get_attr_uint16(this, B_DEVICE_INTERFACE, &interface, false); 1273 1274 // TODO: maybe make this extendible via settings file? 1275 switch (type) { 1276 case PCI_mass_storage: 1277 switch (subType) { 1278 case PCI_scsi: 1279 _AddPath(*stack, "busses", "scsi"); 1280 break; 1281 case PCI_ide: 1282 _AddPath(*stack, "busses", "ide"); 1283 break; 1284 case PCI_sata: 1285 _AddPath(*stack, "busses", "sata"); 1286 break; 1287 default: 1288 _AddPath(*stack, "busses", "disk"); 1289 break; 1290 } 1291 break; 1292 case PCI_serial_bus: 1293 switch (subType) { 1294 case PCI_firewire: 1295 _AddPath(*stack, "busses", "firewire"); 1296 break; 1297 case PCI_usb: 1298 _AddPath(*stack, "busses", "usb"); 1299 break; 1300 default: 1301 _AddPath(*stack, "busses"); 1302 break; 1303 } 1304 break; 1305 case PCI_network: 1306 _AddPath(*stack, "drivers", "net"); 1307 break; 1308 case PCI_display: 1309 _AddPath(*stack, "drivers", "graphics"); 1310 break; 1311 case PCI_multimedia: 1312 switch (subType) { 1313 case PCI_audio: 1314 case PCI_hd_audio: 1315 _AddPath(*stack, "drivers", "audio"); 1316 break; 1317 case PCI_video: 1318 _AddPath(*stack, "drivers", "video"); 1319 break; 1320 default: 1321 _AddPath(*stack, "drivers"); 1322 break; 1323 } 1324 break; 1325 default: 1326 if (sRootNode == this) { 1327 _AddPath(*stack, "busses/pci"); 1328 _AddPath(*stack, "bus_managers"); 1329 } else 1330 _AddPath(*stack, "drivers"); 1331 break; 1332 } 1333 1334 stackDeleter.Detach(); 1335 1336 cookie = (void*)stack; 1337 } else 1338 stack = static_cast<Stack<KPath*>*>(cookie); 1339 1340 KPath* path; 1341 if (stack->Pop(&path)) { 1342 _path.Adopt(*path); 1343 delete path; 1344 return B_OK; 1345 } 1346 1347 delete stack; 1348 return B_ENTRY_NOT_FOUND; 1349 } 1350 1351 1352 status_t 1353 device_node::_GetNextDriver(void* list, driver_module_info*& driver) 1354 { 1355 while (true) { 1356 char name[B_FILE_NAME_LENGTH]; 1357 size_t nameLength = sizeof(name); 1358 1359 status_t status = read_next_module_name(list, name, &nameLength); 1360 if (status != B_OK) 1361 return status; 1362 1363 if (!strcmp(fModuleName, name)) 1364 continue; 1365 1366 if (get_module(name, (module_info**)&driver) != B_OK) 1367 continue; 1368 1369 if (driver->supports_device == NULL 1370 || driver->register_device == NULL) { 1371 put_module(name); 1372 continue; 1373 } 1374 1375 return B_OK; 1376 } 1377 } 1378 1379 1380 status_t 1381 device_node::_FindBestDriver(const char* path, driver_module_info*& bestDriver, 1382 float& bestSupport, device_node* previous) 1383 { 1384 if (bestDriver == NULL) 1385 bestSupport = previous != NULL ? previous->fSupportsParent : 0.0f; 1386 1387 void* list = open_module_list_etc(path, "driver_v1"); 1388 driver_module_info* driver; 1389 while (_GetNextDriver(list, driver) == B_OK) { 1390 if (previous != NULL && driver == previous->DriverModule()) { 1391 put_module(driver->info.name); 1392 continue; 1393 } 1394 1395 float support = driver->supports_device(this); 1396 if (support > bestSupport) { 1397 if (bestDriver != NULL) 1398 put_module(bestDriver->info.name); 1399 1400 bestDriver = driver; 1401 bestSupport = support; 1402 continue; 1403 // keep reference to best module around 1404 } 1405 1406 put_module(driver->info.name); 1407 } 1408 close_module_list(list); 1409 1410 return bestDriver != NULL ? B_OK : B_ENTRY_NOT_FOUND; 1411 } 1412 1413 1414 status_t 1415 device_node::_RegisterPath(const char* path) 1416 { 1417 void* list = open_module_list_etc(path, "driver_v1"); 1418 driver_module_info* driver; 1419 uint32 count = 0; 1420 1421 while (_GetNextDriver(list, driver) == B_OK) { 1422 float support = driver->supports_device(this); 1423 if (support > 0.0) { 1424 TRACE((" register module \"%s\", support %f\n", driver->info.name, 1425 support)); 1426 if (driver->register_device(this) == B_OK) 1427 count++; 1428 } 1429 1430 put_module(driver->info.name); 1431 } 1432 close_module_list(list); 1433 1434 return count > 0 ? B_OK : B_ENTRY_NOT_FOUND; 1435 } 1436 1437 1438 bool 1439 device_node::_AlwaysRegisterDynamic() 1440 { 1441 uint16 type = 0; 1442 uint16 subType = 0; 1443 get_attr_uint16(this, B_DEVICE_TYPE, &type, false); 1444 get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false); 1445 1446 return type == PCI_serial_bus || type == PCI_bridge; 1447 // TODO: we may want to be a bit more specific in the future 1448 } 1449 1450 1451 status_t 1452 device_node::_RegisterDynamic(device_node* previous) 1453 { 1454 // If this is our initial registration, we honour the B_FIND_CHILD_ON_DEMAND 1455 // requirements 1456 if (!fRegistered && (fFlags & B_FIND_CHILD_ON_DEMAND) != 0 1457 && !_AlwaysRegisterDynamic()) 1458 return B_OK; 1459 1460 KPath path; 1461 1462 if ((fFlags & B_FIND_MULTIPLE_CHILDREN) == 0) { 1463 // find the one driver 1464 driver_module_info* bestDriver = NULL; 1465 float bestSupport = 0.0; 1466 void* cookie = NULL; 1467 1468 while (_GetNextDriverPath(cookie, path) == B_OK) { 1469 _FindBestDriver(path.Path(), bestDriver, bestSupport, previous); 1470 } 1471 1472 if (bestDriver != NULL) { 1473 TRACE((" register best module \"%s\", support %f\n", 1474 bestDriver->info.name, bestSupport)); 1475 if (bestDriver->register_device(this) == B_OK) { 1476 // There can only be one node of this driver 1477 // (usually only one at all, but there might be a new driver 1478 // "waiting" for its turn) 1479 device_node* child = FindChild(bestDriver->info.name); 1480 if (child != NULL) { 1481 child->fSupportsParent = bestSupport; 1482 if (previous != NULL) { 1483 previous->fFlags |= NODE_FLAG_OBSOLETE_DRIVER; 1484 previous->Release(); 1485 child->fFlags |= NODE_FLAG_WAITING_FOR_DRIVER; 1486 } 1487 } 1488 // TODO: if this fails, we could try the second best driver, 1489 // and so on... 1490 } 1491 put_module(bestDriver->info.name); 1492 } 1493 } else { 1494 // register all drivers that match 1495 void* cookie = NULL; 1496 while (_GetNextDriverPath(cookie, path) == B_OK) { 1497 _RegisterPath(path.Path()); 1498 } 1499 } 1500 1501 return B_OK; 1502 } 1503 1504 1505 void 1506 device_node::_ReleaseWaiting() 1507 { 1508 NodeList::Iterator iterator = fChildren.GetIterator(); 1509 while (iterator.HasNext()) { 1510 device_node* child = iterator.Next(); 1511 1512 child->fFlags &= ~NODE_FLAG_WAITING_FOR_DRIVER; 1513 } 1514 } 1515 1516 1517 status_t 1518 device_node::_RemoveChildren() 1519 { 1520 NodeList::Iterator iterator = fChildren.GetIterator(); 1521 while (iterator.HasNext()) { 1522 device_node* child = iterator.Next(); 1523 child->Release(); 1524 } 1525 1526 return fChildren.IsEmpty() ? B_OK : B_BUSY; 1527 } 1528 1529 1530 device_node* 1531 device_node::_FindCurrentChild() 1532 { 1533 NodeList::Iterator iterator = fChildren.GetIterator(); 1534 while (iterator.HasNext()) { 1535 device_node* child = iterator.Next(); 1536 1537 if ((child->Flags() & NODE_FLAG_WAITING_FOR_DRIVER) == 0) 1538 return child; 1539 } 1540 1541 return NULL; 1542 } 1543 1544 1545 status_t 1546 device_node::Probe(const char* devicePath, uint32 updateCycle) 1547 { 1548 if ((fFlags & NODE_FLAG_DEVICE_REMOVED) != 0 1549 || updateCycle == fLastUpdateCycle) 1550 return B_OK; 1551 1552 status_t status = InitDriver(); 1553 if (status < B_OK) 1554 return status; 1555 1556 MethodDeleter<device_node, bool> uninit(this, 1557 &device_node::UninitDriver); 1558 1559 uint16 type = 0; 1560 uint16 subType = 0; 1561 if (get_attr_uint16(this, B_DEVICE_TYPE, &type, false) == B_OK 1562 && get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false) 1563 == B_OK) { 1564 // Check if this node matches the device path 1565 // TODO: maybe make this extendible via settings file? 1566 bool matches = false; 1567 if (!strcmp(devicePath, "disk")) { 1568 matches = type == PCI_mass_storage; 1569 } else if (!strcmp(devicePath, "audio")) { 1570 matches = type == PCI_multimedia 1571 && (subType == PCI_audio || subType == PCI_hd_audio); 1572 } else if (!strcmp(devicePath, "net")) { 1573 matches = type == PCI_network; 1574 } else if (!strcmp(devicePath, "graphics")) { 1575 matches = type == PCI_display; 1576 } else if (!strcmp(devicePath, "video")) { 1577 matches = type == PCI_multimedia && subType == PCI_video; 1578 } 1579 1580 if (matches) { 1581 device_node* previous = NULL; 1582 1583 fLastUpdateCycle = updateCycle; 1584 // This node will be probed in this update cycle 1585 1586 if (!fChildren.IsEmpty() 1587 && (fFlags & B_FIND_MULTIPLE_CHILDREN) == 0) { 1588 // We already have a driver that claims this node; remove all 1589 // (unused) nodes, and evaluate it again 1590 _RemoveChildren(); 1591 1592 previous = _FindCurrentChild(); 1593 if (previous != NULL) { 1594 // This driver is still active - give it back the reference 1595 // that was stolen by _RemoveChildren() - _RegisterDynamic() 1596 // will release it, if it really isn't needed anymore 1597 previous->Acquire(); 1598 } 1599 } 1600 return _RegisterDynamic(previous); 1601 } 1602 1603 return B_OK; 1604 } 1605 1606 NodeList::Iterator iterator = fChildren.GetIterator(); 1607 while (iterator.HasNext()) { 1608 device_node* child = iterator.Next(); 1609 1610 status = child->Probe(devicePath, updateCycle); 1611 if (status != B_OK) 1612 return status; 1613 } 1614 1615 return B_OK; 1616 } 1617 1618 1619 /*! Uninitializes all temporary references to the driver. The registration 1620 process keeps the driver initialized to optimize the startup procedure; 1621 this function gives this reference away again. 1622 */ 1623 void 1624 device_node::UninitUnusedDriver() 1625 { 1626 // First, we need to go to the leaf, and go back from there 1627 1628 NodeList::Iterator iterator = fChildren.GetIterator(); 1629 while (iterator.HasNext()) { 1630 device_node* child = iterator.Next(); 1631 1632 child->UninitUnusedDriver(); 1633 } 1634 1635 if (!IsInitialized() 1636 || (fFlags & NODE_FLAG_REGISTER_INITIALIZED) == 0) 1637 return; 1638 1639 fFlags &= ~NODE_FLAG_REGISTER_INITIALIZED; 1640 1641 UninitDriver(); 1642 } 1643 1644 1645 /*! Calls device_removed() on this node and all of its children - starting 1646 with the deepest and last child. 1647 It will also remove the one reference that every node gets on its creation. 1648 */ 1649 void 1650 device_node::DeviceRemoved() 1651 { 1652 // notify children 1653 NodeList::ConstIterator iterator = Children().GetIterator(); 1654 while (iterator.HasNext()) { 1655 device_node* child = iterator.Next(); 1656 1657 child->DeviceRemoved(); 1658 } 1659 1660 // notify devices 1661 DeviceList::ConstIterator deviceIterator = Devices().GetIterator(); 1662 while (deviceIterator.HasNext()) { 1663 Device* device = deviceIterator.Next(); 1664 1665 if (device->DeviceModule() != NULL 1666 && device->DeviceModule()->device_removed != NULL) 1667 device->DeviceModule()->device_removed(device->DeviceData()); 1668 } 1669 1670 fFlags |= NODE_FLAG_DEVICE_REMOVED; 1671 1672 if (IsInitialized() && DriverModule()->device_removed != NULL) 1673 DriverModule()->device_removed(this); 1674 1675 if ((fFlags & B_KEEP_DRIVER_LOADED) != 0) { 1676 // There is no point in keeping this driver loaded when its device 1677 // is gone 1678 UninitDriver(); 1679 } 1680 1681 UninitUnusedDriver(); 1682 Release(); 1683 } 1684 1685 1686 void 1687 device_node::Acquire() 1688 { 1689 atomic_add(&fRefCount, 1); 1690 } 1691 1692 1693 bool 1694 device_node::Release() 1695 { 1696 if (atomic_add(&fRefCount, -1) > 1) 1697 return false; 1698 1699 delete this; 1700 return true; 1701 } 1702 1703 1704 void 1705 device_node::AddDevice(Device* device) 1706 { 1707 fDevices.Add(device); 1708 } 1709 1710 1711 void 1712 device_node::RemoveDevice(Device* device) 1713 { 1714 fDevices.Remove(device); 1715 } 1716 1717 1718 int 1719 device_node::CompareTo(const device_attr* attributes) const 1720 { 1721 if (attributes == NULL) 1722 return -1; 1723 1724 for (; attributes->name != NULL; attributes++) { 1725 // find corresponding attribute 1726 AttributeList::ConstIterator iterator = Attributes().GetIterator(); 1727 device_attr_private* attr = NULL; 1728 while (iterator.HasNext()) { 1729 attr = iterator.Next(); 1730 1731 if (!strcmp(attr->name, attributes->name)) 1732 break; 1733 } 1734 if (!iterator.HasNext()) 1735 return -1; 1736 1737 int compare = device_attr_private::Compare(attr, attributes); 1738 if (compare != 0) 1739 return compare; 1740 } 1741 1742 return 0; 1743 } 1744 1745 1746 device_node* 1747 device_node::FindChild(const device_attr* attributes) const 1748 { 1749 if (attributes == NULL) 1750 return NULL; 1751 1752 NodeList::ConstIterator iterator = Children().GetIterator(); 1753 while (iterator.HasNext()) { 1754 device_node* child = iterator.Next(); 1755 1756 // ignore nodes that are pending to be removed 1757 if ((child->Flags() & NODE_FLAG_DEVICE_REMOVED) == 0 1758 && !child->CompareTo(attributes)) 1759 return child; 1760 } 1761 1762 return NULL; 1763 } 1764 1765 1766 device_node* 1767 device_node::FindChild(const char* moduleName) const 1768 { 1769 if (moduleName == NULL) 1770 return NULL; 1771 1772 NodeList::ConstIterator iterator = Children().GetIterator(); 1773 while (iterator.HasNext()) { 1774 device_node* child = iterator.Next(); 1775 1776 if (!strcmp(child->ModuleName(), moduleName)) 1777 return child; 1778 } 1779 1780 return NULL; 1781 } 1782 1783 1784 void 1785 device_node::Dump(int32 level = 0) 1786 { 1787 put_level(level); 1788 dprintf("(%ld) @%p \"%s\" (ref %ld, init %ld)\n", level, this, ModuleName(), 1789 fRefCount, fInitialized); 1790 1791 AttributeList::Iterator attribute = Attributes().GetIterator(); 1792 while (attribute.HasNext()) { 1793 dump_attribute(attribute.Next(), level); 1794 } 1795 1796 NodeList::ConstIterator iterator = Children().GetIterator(); 1797 while (iterator.HasNext()) { 1798 iterator.Next()->Dump(level + 1); 1799 } 1800 } 1801 1802 1803 // #pragma mark - root node 1804 1805 1806 static void 1807 init_root_node(void) 1808 { 1809 device_attr attrs[] = { 1810 {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "Devices Root"}}, 1811 {B_DEVICE_BUS, B_STRING_TYPE, {string: "root"}}, 1812 {B_DEVICE_FLAGS, B_UINT32_TYPE, 1813 {ui32: B_FIND_MULTIPLE_CHILDREN | B_KEEP_DRIVER_LOADED }}, 1814 {NULL} 1815 }; 1816 1817 if (register_node(NULL, DEVICE_MANAGER_ROOT_NAME, attrs, NULL, NULL) 1818 != B_OK) { 1819 dprintf("Cannot register Devices Root Node\n"); 1820 } 1821 } 1822 1823 1824 static driver_module_info sDeviceRootModule = { 1825 { 1826 DEVICE_MANAGER_ROOT_NAME, 1827 0, 1828 NULL, 1829 }, 1830 NULL 1831 }; 1832 1833 1834 // #pragma mark - 1835 1836 1837 int 1838 main(int argc, char** argv) 1839 { 1840 _add_builtin_module((module_info*)&sDeviceManagerModule); 1841 _add_builtin_module((module_info*)&sDeviceRootModule); 1842 1843 // bus 1844 _add_builtin_module((module_info*)&gBusModuleInfo); 1845 _add_builtin_module((module_info*)&gBusDriverModuleInfo); 1846 1847 // sample driver 1848 _add_builtin_module((module_info*)&gDriverModuleInfo); 1849 _add_builtin_module((module_info*)&gDeviceModuleInfo); 1850 1851 // generic video driver 1852 _add_builtin_module((module_info*)&gGenericVideoDriverModuleInfo); 1853 _add_builtin_module((module_info*)&gGenericVideoDeviceModuleInfo); 1854 1855 gDeviceManager = &sDeviceManagerModule; 1856 1857 status_t status = _get_builtin_dependencies(); 1858 if (status < B_OK) { 1859 fprintf(stderr, "device_manager: Could not initialize modules: %s\n", 1860 strerror(status)); 1861 return 1; 1862 } 1863 1864 recursive_lock_init(&sLock, "device manager"); 1865 1866 init_root_node(); 1867 sRootNode->Dump(); 1868 1869 probe_path("net"); 1870 probe_path("graphics"); 1871 1872 void* netHandle = open_path("net/sample/0"); 1873 1874 uninit_unused(); 1875 1876 puts("remove net driver"); 1877 device_node* busNode = sRootNode->FindChild(BUS_MODULE_NAME); 1878 bus_trigger_device_removed(busNode); 1879 1880 close_path(netHandle); 1881 // the net nodes must be removed with this call 1882 1883 void* graphicsHandle = open_path("graphics/generic/0"); 1884 1885 // add specific video driver - ie. simulate installing it 1886 _add_builtin_module((module_info*)&gSpecificVideoDriverModuleInfo); 1887 _add_builtin_module((module_info*)&gSpecificVideoDeviceModuleInfo); 1888 sDriverUpdateCycle++; 1889 probe_path("graphics"); 1890 1891 open_path("graphics/specific/0"); 1892 // this will fail 1893 1894 close_path(graphicsHandle); 1895 // the graphics drivers must be switched with this call 1896 1897 graphicsHandle = open_path("graphics/specific/0"); 1898 close_path(graphicsHandle); 1899 1900 uninit_unused(); 1901 1902 recursive_lock_destroy(&sLock); 1903 return 0; 1904 } 1905