1 /* 2 * Copyright 2008-2009, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <kdevice_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 <boot_device.h> 21 #include <device_manager_defs.h> 22 #include <fs/devfs.h> 23 #include <fs/KPath.h> 24 #include <kernel.h> 25 #include <generic_syscall.h> 26 #include <util/AutoLock.h> 27 #include <util/DoublyLinkedList.h> 28 #include <util/Stack.h> 29 30 #include "BaseDevice.h" 31 #include "devfs_private.h" 32 #include "id_generator.h" 33 #include "IORequest.h" 34 #include "io_resources.h" 35 #include "IOScheduler.h" 36 37 38 //#define TRACE_DEVICE_MANAGER 39 #ifdef TRACE_DEVICE_MANAGER 40 # define TRACE(a) dprintf a 41 #else 42 # define TRACE(a) ; 43 #endif 44 45 46 #define DEVICE_MANAGER_ROOT_NAME "system/devices_root/driver_v1" 47 #define DEVICE_MANAGER_GENERIC_NAME "system/devices_generic/driver_v1" 48 49 50 struct device_attr_private : device_attr, 51 DoublyLinkedListLinkImpl<device_attr_private> { 52 device_attr_private(); 53 device_attr_private(const device_attr& attr); 54 ~device_attr_private(); 55 56 status_t InitCheck(); 57 status_t CopyFrom(const device_attr& attr); 58 59 static int Compare(const device_attr* attrA, 60 const device_attr *attrB); 61 62 private: 63 void _Unset(); 64 }; 65 66 typedef DoublyLinkedList<device_attr_private> AttributeList; 67 68 // I/O resource 69 typedef struct io_resource_info { 70 struct io_resource_info *prev, *next; 71 device_node* owner; // associated node; NULL for temporary allocation 72 io_resource resource; // info about actual resource 73 } io_resource_info; 74 75 class Device : public BaseDevice, public DoublyLinkedListLinkImpl<Device> { 76 public: 77 Device(device_node* node, const char* moduleName); 78 virtual ~Device(); 79 80 status_t InitCheck() const; 81 82 const char* ModuleName() const { return fModuleName; } 83 84 virtual status_t InitDevice(); 85 virtual void UninitDevice(); 86 87 virtual void Removed(); 88 89 void SetRemovedFromParent(bool removed) 90 { fRemovedFromParent = removed; } 91 92 private: 93 const char* fModuleName; 94 bool fRemovedFromParent; 95 }; 96 97 typedef DoublyLinkedList<Device> DeviceList; 98 typedef DoublyLinkedList<device_node> NodeList; 99 100 struct device_node : DoublyLinkedListLinkImpl<device_node> { 101 device_node(const char* moduleName, 102 const device_attr* attrs); 103 ~device_node(); 104 105 status_t InitCheck() const; 106 107 status_t AcquireResources(const io_resource* resources); 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 status_t Reprobe(); 131 status_t Rescan(); 132 133 bool IsRegistered() const { return fRegistered; } 134 bool IsInitialized() const { return fInitialized > 0; } 135 bool IsProbed() const { return fLastUpdateCycle != 0; } 136 uint32 Flags() const { return fFlags; } 137 138 void Acquire(); 139 bool Release(); 140 141 const DeviceList& Devices() const { return fDevices; } 142 void AddDevice(Device* device); 143 void RemoveDevice(Device* device); 144 145 int CompareTo(const device_attr* attributes) const; 146 device_node* FindChild(const device_attr* attributes) const; 147 device_node* FindChild(const char* moduleName) const; 148 149 int32 Priority(); 150 151 void Dump(int32 level = 0); 152 153 private: 154 status_t _RegisterFixed(uint32& registered); 155 bool _AlwaysRegisterDynamic(); 156 status_t _AddPath(Stack<KPath*>& stack, const char* path, 157 const char* subPath = NULL); 158 status_t _GetNextDriverPath(void*& cookie, KPath& _path); 159 status_t _GetNextDriver(void* list, 160 driver_module_info*& driver); 161 status_t _FindBestDriver(const char* path, 162 driver_module_info*& bestDriver, 163 float& bestSupport, 164 device_node* previous = NULL); 165 status_t _RegisterPath(const char* path); 166 status_t _RegisterDynamic(device_node* previous = NULL); 167 status_t _RemoveChildren(); 168 device_node* _FindCurrentChild(); 169 status_t _Probe(); 170 void _ReleaseWaiting(); 171 172 device_node* fParent; 173 NodeList fChildren; 174 int32 fRefCount; 175 int32 fInitialized; 176 bool fRegistered; 177 uint32 fFlags; 178 float fSupportsParent; 179 uint32 fLastUpdateCycle; 180 181 const char* fModuleName; 182 183 driver_module_info* fDriver; 184 void* fDriverData; 185 186 DeviceList fDevices; 187 AttributeList fAttributes; 188 ResourceList fResources; 189 }; 190 191 // flags in addition to those specified by B_DEVICE_FLAGS 192 enum node_flags { 193 NODE_FLAG_REGISTER_INITIALIZED = 0x00010000, 194 NODE_FLAG_DEVICE_REMOVED = 0x00020000, 195 NODE_FLAG_OBSOLETE_DRIVER = 0x00040000, 196 NODE_FLAG_WAITING_FOR_DRIVER = 0x00080000, 197 198 NODE_FLAG_PUBLIC_MASK = 0x0000ffff 199 }; 200 201 202 static device_node *sRootNode; 203 static recursive_lock sLock; 204 static const char* sGenericContextPath; 205 206 207 // #pragma mark - 208 209 210 static device_attr_private* 211 find_attr(const device_node* node, const char* name, bool recursive, 212 type_code type) 213 { 214 do { 215 AttributeList::ConstIterator iterator 216 = node->Attributes().GetIterator(); 217 218 while (iterator.HasNext()) { 219 device_attr_private* attr = iterator.Next(); 220 221 if (type != B_ANY_TYPE && attr->type != type) 222 continue; 223 224 if (!strcmp(attr->name, name)) 225 return attr; 226 } 227 228 node = node->Parent(); 229 } while (node != NULL && recursive); 230 231 return NULL; 232 } 233 234 235 static void 236 put_level(int32 level) 237 { 238 while (level-- > 0) 239 kprintf(" "); 240 } 241 242 243 static void 244 dump_attribute(device_attr* attr, int32 level) 245 { 246 if (attr == NULL) 247 return; 248 249 put_level(level + 2); 250 kprintf("\"%s\" : ", attr->name); 251 switch (attr->type) { 252 case B_STRING_TYPE: 253 kprintf("string : \"%s\"", attr->value.string); 254 break; 255 case B_INT8_TYPE: 256 case B_UINT8_TYPE: 257 kprintf("uint8 : %u (%#x)", attr->value.ui8, attr->value.ui8); 258 break; 259 case B_INT16_TYPE: 260 case B_UINT16_TYPE: 261 kprintf("uint16 : %u (%#x)", attr->value.ui16, attr->value.ui16); 262 break; 263 case B_INT32_TYPE: 264 case B_UINT32_TYPE: 265 kprintf("uint32 : %lu (%#lx)", attr->value.ui32, attr->value.ui32); 266 break; 267 case B_INT64_TYPE: 268 case B_UINT64_TYPE: 269 kprintf("uint64 : %Lu (%#Lx)", attr->value.ui64, attr->value.ui64); 270 break; 271 default: 272 kprintf("raw data"); 273 } 274 kprintf("\n"); 275 } 276 277 278 static int 279 dump_io_scheduler(int argc, char** argv) 280 { 281 if (argc != 2) { 282 print_debugger_command_usage(argv[0]); 283 return 0; 284 } 285 286 IOScheduler* scheduler = (IOScheduler*)parse_expression(argv[1]); 287 scheduler->Dump(); 288 return 0; 289 } 290 291 292 static int 293 dump_io_request_owner(int argc, char** argv) 294 { 295 if (argc != 2) { 296 print_debugger_command_usage(argv[0]); 297 return 0; 298 } 299 300 IORequestOwner* owner = (IORequestOwner*)parse_expression(argv[1]); 301 owner->Dump(); 302 return 0; 303 } 304 305 306 static int 307 dump_io_request(int argc, char** argv) 308 { 309 if (argc != 2 || !strcmp(argv[1], "--help")) { 310 kprintf("usage: %s <ptr-to-io-request>\n", argv[0]); 311 return 0; 312 } 313 314 IORequest* request = (IORequest*)parse_expression(argv[1]); 315 request->Dump(); 316 return 0; 317 } 318 319 320 static int 321 dump_io_operation(int argc, char** argv) 322 { 323 if (argc != 2 || !strcmp(argv[1], "--help")) { 324 kprintf("usage: %s <ptr-to-io-operation>\n", argv[0]); 325 return 0; 326 } 327 328 IOOperation* operation = (IOOperation*)parse_expression(argv[1]); 329 operation->Dump(); 330 return 0; 331 } 332 333 334 static int 335 dump_io_buffer(int argc, char** argv) 336 { 337 if (argc != 2 || !strcmp(argv[1], "--help")) { 338 kprintf("usage: %s <ptr-to-io-buffer>\n", argv[0]); 339 return 0; 340 } 341 342 IOBuffer* buffer = (IOBuffer*)parse_expression(argv[1]); 343 buffer->Dump(); 344 return 0; 345 } 346 347 348 static int 349 dump_dma_buffer(int argc, char** argv) 350 { 351 if (argc != 2 || !strcmp(argv[1], "--help")) { 352 kprintf("usage: %s <ptr-to-dma-buffer>\n", argv[0]); 353 return 0; 354 } 355 356 DMABuffer* buffer = (DMABuffer*)parse_expression(argv[1]); 357 buffer->Dump(); 358 return 0; 359 } 360 361 362 static int 363 dump_device_nodes(int argc, char** argv) 364 { 365 sRootNode->Dump(); 366 return 0; 367 } 368 369 370 static void 371 publish_directories(const char* subPath) 372 { 373 if (gBootDevice < 0) { 374 if (subPath[0]) { 375 // we only support the top-level directory for modules 376 return; 377 } 378 379 // we can only iterate over the known modules to find all directories 380 KPath path("drivers"); 381 if (path.Append(subPath) != B_OK) 382 return; 383 384 size_t length = strlen(path.Path()) + 1; 385 // account for the separating '/' 386 387 void* list = open_module_list_etc(path.Path(), "driver_v1"); 388 char name[B_FILE_NAME_LENGTH]; 389 size_t nameLength = sizeof(name); 390 while (read_next_module_name(list, name, &nameLength) == B_OK) { 391 if (nameLength == length) 392 continue; 393 394 char* leaf = name + length; 395 char* end = strchr(leaf, '/'); 396 if (end != NULL) 397 end[0] = '\0'; 398 399 path.SetTo(subPath); 400 path.Append(leaf); 401 402 devfs_publish_directory(path.Path()); 403 } 404 close_module_list(list); 405 } else { 406 // TODO: implement module directory traversal! 407 } 408 } 409 410 411 static status_t 412 control_device_manager(const char* subsystem, uint32 function, void* buffer, 413 size_t bufferSize) 414 { 415 // TODO: this function passes pointers to userland, and uses pointers 416 // to device nodes that came from userland - this is completely unsafe 417 // and should be changed. 418 switch (function) { 419 case DM_GET_ROOT: 420 { 421 device_node_cookie cookie; 422 if (!IS_USER_ADDRESS(buffer)) 423 return B_BAD_ADDRESS; 424 if (bufferSize != sizeof(device_node_cookie)) 425 return B_BAD_VALUE; 426 cookie = (device_node_cookie)sRootNode; 427 428 // copy back to user space 429 return user_memcpy(buffer, &cookie, sizeof(device_node_cookie)); 430 } 431 432 case DM_GET_CHILD: 433 { 434 if (!IS_USER_ADDRESS(buffer)) 435 return B_BAD_ADDRESS; 436 if (bufferSize != sizeof(device_node_cookie)) 437 return B_BAD_VALUE; 438 439 device_node_cookie cookie; 440 if (user_memcpy(&cookie, buffer, sizeof(device_node_cookie)) < B_OK) 441 return B_BAD_ADDRESS; 442 443 device_node* node = (device_node*)cookie; 444 NodeList::ConstIterator iterator = node->Children().GetIterator(); 445 446 if (!iterator.HasNext()) { 447 return B_ENTRY_NOT_FOUND; 448 } 449 node = iterator.Next(); 450 cookie = (device_node_cookie)node; 451 452 // copy back to user space 453 return user_memcpy(buffer, &cookie, sizeof(device_node_cookie)); 454 } 455 456 case DM_GET_NEXT_CHILD: 457 { 458 if (!IS_USER_ADDRESS(buffer)) 459 return B_BAD_ADDRESS; 460 if (bufferSize != sizeof(device_node_cookie)) 461 return B_BAD_VALUE; 462 463 device_node_cookie cookie; 464 if (user_memcpy(&cookie, buffer, sizeof(device_node_cookie)) < B_OK) 465 return B_BAD_ADDRESS; 466 467 device_node* last = (device_node*)cookie; 468 if (!last->Parent()) 469 return B_ENTRY_NOT_FOUND; 470 471 NodeList::ConstIterator iterator 472 = last->Parent()->Children().GetIterator(); 473 474 // skip those we already traversed 475 while (iterator.HasNext()) { 476 device_node* node = iterator.Next(); 477 478 if (node == last) 479 break; 480 } 481 482 if (!iterator.HasNext()) 483 return B_ENTRY_NOT_FOUND; 484 device_node* node = iterator.Next(); 485 cookie = (device_node_cookie)node; 486 487 // copy back to user space 488 return user_memcpy(buffer, &cookie, sizeof(device_node_cookie)); 489 } 490 491 case DM_GET_NEXT_ATTRIBUTE: 492 { 493 struct device_attr_info attrInfo; 494 if (!IS_USER_ADDRESS(buffer)) 495 return B_BAD_ADDRESS; 496 if (bufferSize != sizeof(device_attr_info)) 497 return B_BAD_VALUE; 498 if (user_memcpy(&attrInfo, buffer, sizeof(device_attr_info)) < B_OK) 499 return B_BAD_ADDRESS; 500 501 device_node* node = (device_node*)attrInfo.node_cookie; 502 device_attr* last = (device_attr*)attrInfo.cookie; 503 AttributeList::Iterator iterator = node->Attributes().GetIterator(); 504 // skip those we already traversed 505 while (iterator.HasNext() && last != NULL) { 506 device_attr* attr = iterator.Next(); 507 508 if (attr == last) 509 break; 510 } 511 512 if (!iterator.HasNext()) { 513 attrInfo.cookie = 0; 514 return B_ENTRY_NOT_FOUND; 515 } 516 517 device_attr* attr = iterator.Next(); 518 attrInfo.cookie = (device_node_cookie)attr; 519 strlcpy(attrInfo.name, attr->name, 254); 520 attrInfo.type = attr->type; 521 switch (attrInfo.type) { 522 case B_UINT8_TYPE: 523 attrInfo.value.ui8 = attr->value.ui8; 524 break; 525 case B_UINT16_TYPE: 526 attrInfo.value.ui16 = attr->value.ui16; 527 break; 528 case B_UINT32_TYPE: 529 attrInfo.value.ui32 = attr->value.ui32; 530 break; 531 case B_UINT64_TYPE: 532 attrInfo.value.ui64 = attr->value.ui64; 533 break; 534 case B_STRING_TYPE: 535 strlcpy(attrInfo.value.string, attr->value.string, 254); 536 break; 537 /*case B_RAW_TYPE: 538 if (attr.value.raw.length > attr_info->attr.value.raw.length) 539 attr.value.raw.length = attr_info->attr.value.raw.length; 540 user_memcpy(attr.value.raw.data, attr_info->attr.value.raw.data, 541 attr.value.raw.length); 542 break;*/ 543 } 544 545 // copy back to user space 546 return user_memcpy(buffer, &attrInfo, sizeof(device_attr_info)); 547 } 548 } 549 550 return B_BAD_HANDLER; 551 } 552 553 554 // #pragma mark - Device Manager module API 555 556 557 static status_t 558 rescan_node(device_node* node) 559 { 560 RecursiveLocker _(sLock); 561 return node->Rescan(); 562 } 563 564 565 static status_t 566 register_node(device_node* parent, const char* moduleName, 567 const device_attr* attrs, const io_resource* ioResources, 568 device_node** _node) 569 { 570 if ((parent == NULL && sRootNode != NULL) || moduleName == NULL) 571 return B_BAD_VALUE; 572 573 if (parent != NULL && parent->FindChild(attrs) != NULL) { 574 // A node like this one already exists for this parent 575 return B_NAME_IN_USE; 576 } 577 578 RecursiveLocker _(sLock); 579 580 device_node* newNode = new(std::nothrow) device_node(moduleName, attrs); 581 if (newNode == NULL) 582 return B_NO_MEMORY; 583 584 TRACE(("%p: register node \"%s\", parent %p\n", newNode, moduleName, 585 parent)); 586 587 status_t status = newNode->InitCheck(); 588 if (status == B_OK) 589 status = newNode->AcquireResources(ioResources); 590 if (status == B_OK) 591 status = newNode->Register(parent); 592 593 if (status != B_OK) { 594 newNode->Release(); 595 return status; 596 } 597 598 if (_node) 599 *_node = newNode; 600 601 return B_OK; 602 } 603 604 605 /*! Unregisters the device \a node. 606 607 If the node is currently in use, this function will return B_BUSY to 608 indicate that the node hasn't been removed yet - it will still remove 609 the node as soon as possible. 610 */ 611 static status_t 612 unregister_node(device_node* node) 613 { 614 TRACE(("unregister_node(node %p)\n", node)); 615 RecursiveLocker _(sLock); 616 617 bool initialized = node->IsInitialized(); 618 619 node->DeviceRemoved(); 620 621 return initialized ? B_BUSY : B_OK; 622 } 623 624 625 static status_t 626 get_driver(device_node* node, driver_module_info** _module, void** _data) 627 { 628 if (node->DriverModule() == NULL) 629 return B_NO_INIT; 630 631 if (_module != NULL) 632 *_module = node->DriverModule(); 633 if (_data != NULL) 634 *_data = node->DriverData(); 635 636 return B_OK; 637 } 638 639 640 static device_node* 641 get_root_node(void) 642 { 643 if (sRootNode != NULL) 644 sRootNode->Acquire(); 645 646 return sRootNode; 647 } 648 649 650 static status_t 651 get_next_child_node(device_node* parent, const device_attr* attributes, 652 device_node** _node) 653 { 654 RecursiveLocker _(sLock); 655 656 NodeList::ConstIterator iterator = parent->Children().GetIterator(); 657 device_node* last = *_node; 658 659 // skip those we already traversed 660 while (iterator.HasNext() && last != NULL) { 661 device_node* node = iterator.Next(); 662 663 if (node != last) 664 continue; 665 } 666 667 // find the next one that fits 668 while (iterator.HasNext()) { 669 device_node* node = iterator.Next(); 670 671 if (!node->IsRegistered()) 672 continue; 673 674 if (!node->CompareTo(attributes)) { 675 if (last != NULL) 676 last->Release(); 677 678 node->Acquire(); 679 *_node = node; 680 return B_OK; 681 } 682 } 683 684 if (last != NULL) 685 last->Release(); 686 687 return B_ENTRY_NOT_FOUND; 688 } 689 690 691 static device_node* 692 get_parent_node(device_node* node) 693 { 694 if (node == NULL) 695 return NULL; 696 697 RecursiveLocker _(sLock); 698 699 device_node* parent = node->Parent(); 700 parent->Acquire(); 701 702 return parent; 703 } 704 705 706 static void 707 put_node(device_node* node) 708 { 709 RecursiveLocker _(sLock); 710 node->Release(); 711 } 712 713 714 static status_t 715 publish_device(device_node *node, const char *path, const char *moduleName) 716 { 717 if (path == NULL || !path[0] || moduleName == NULL || !moduleName[0]) 718 return B_BAD_VALUE; 719 720 RecursiveLocker _(sLock); 721 dprintf("publish device: node %p, path %s, module %s\n", node, path, 722 moduleName); 723 724 Device* device = new(std::nothrow) Device(node, moduleName); 725 if (device == NULL) 726 return B_NO_MEMORY; 727 728 status_t status = device->InitCheck(); 729 if (status == B_OK) 730 status = devfs_publish_device(path, device); 731 if (status != B_OK) { 732 delete device; 733 return status; 734 } 735 736 node->AddDevice(device); 737 return B_OK; 738 } 739 740 741 static status_t 742 unpublish_device(device_node *node, const char *path) 743 { 744 if (path == NULL) 745 return B_BAD_VALUE; 746 747 RecursiveLocker _(sLock); 748 749 #if 0 750 DeviceList::ConstIterator iterator = node->Devices().GetIterator(); 751 while (iterator.HasNext()) { 752 Device* device = iterator.Next(); 753 if (!strcmp(device->Path(), path)) { 754 node->RemoveDevice(device); 755 delete device; 756 return B_OK; 757 } 758 } 759 #endif 760 761 return B_ENTRY_NOT_FOUND; 762 } 763 764 765 static status_t 766 get_attr_uint8(const device_node* node, const char* name, uint8* _value, 767 bool recursive) 768 { 769 if (node == NULL || name == NULL || _value == NULL) 770 return B_BAD_VALUE; 771 772 device_attr_private* attr = find_attr(node, name, recursive, B_UINT8_TYPE); 773 if (attr == NULL) 774 return B_NAME_NOT_FOUND; 775 776 *_value = attr->value.ui8; 777 return B_OK; 778 } 779 780 781 static status_t 782 get_attr_uint16(const device_node* node, const char* name, uint16* _value, 783 bool recursive) 784 { 785 if (node == NULL || name == NULL || _value == NULL) 786 return B_BAD_VALUE; 787 788 device_attr_private* attr = find_attr(node, name, recursive, B_UINT16_TYPE); 789 if (attr == NULL) 790 return B_NAME_NOT_FOUND; 791 792 *_value = attr->value.ui16; 793 return B_OK; 794 } 795 796 797 static status_t 798 get_attr_uint32(const device_node* node, const char* name, uint32* _value, 799 bool recursive) 800 { 801 if (node == NULL || name == NULL || _value == NULL) 802 return B_BAD_VALUE; 803 804 device_attr_private* attr = find_attr(node, name, recursive, B_UINT32_TYPE); 805 if (attr == NULL) 806 return B_NAME_NOT_FOUND; 807 808 *_value = attr->value.ui32; 809 return B_OK; 810 } 811 812 813 static status_t 814 get_attr_uint64(const device_node* node, const char* name, 815 uint64* _value, bool recursive) 816 { 817 if (node == NULL || name == NULL || _value == NULL) 818 return B_BAD_VALUE; 819 820 device_attr_private* attr = find_attr(node, name, recursive, B_UINT64_TYPE); 821 if (attr == NULL) 822 return B_NAME_NOT_FOUND; 823 824 *_value = attr->value.ui64; 825 return B_OK; 826 } 827 828 829 static status_t 830 get_attr_string(const device_node* node, const char* name, 831 const char** _value, bool recursive) 832 { 833 if (node == NULL || name == NULL || _value == NULL) 834 return B_BAD_VALUE; 835 836 device_attr_private* attr = find_attr(node, name, recursive, B_STRING_TYPE); 837 if (attr == NULL) 838 return B_NAME_NOT_FOUND; 839 840 *_value = attr->value.string; 841 return B_OK; 842 } 843 844 845 static status_t 846 get_attr_raw(const device_node* node, const char* name, const void** _data, 847 size_t* _length, bool recursive) 848 { 849 if (node == NULL || name == NULL || (_data == NULL && _length == NULL)) 850 return B_BAD_VALUE; 851 852 device_attr_private* attr = find_attr(node, name, recursive, B_RAW_TYPE); 853 if (attr == NULL) 854 return B_NAME_NOT_FOUND; 855 856 if (_data != NULL) 857 *_data = attr->value.raw.data; 858 if (_length != NULL) 859 *_length = attr->value.raw.length; 860 return B_OK; 861 } 862 863 864 static status_t 865 get_next_attr(device_node* node, device_attr** _attr) 866 { 867 if (node == NULL) 868 return B_BAD_VALUE; 869 870 device_attr_private* next; 871 device_attr_private* attr = *(device_attr_private**)_attr; 872 873 if (attr != NULL) { 874 // next attribute 875 next = attr->GetDoublyLinkedListLink()->next; 876 } else { 877 // first attribute 878 next = node->Attributes().First(); 879 } 880 881 *_attr = next; 882 883 return next ? B_OK : B_ENTRY_NOT_FOUND; 884 } 885 886 887 struct device_manager_info gDeviceManagerModule = { 888 { 889 B_DEVICE_MANAGER_MODULE_NAME, 890 0, 891 NULL 892 }, 893 894 // device nodes 895 rescan_node, 896 register_node, 897 unregister_node, 898 get_driver, 899 get_root_node, 900 get_next_child_node, 901 get_parent_node, 902 put_node, 903 904 // devices 905 publish_device, 906 unpublish_device, 907 908 // I/O resources 909 910 // ID generator 911 dm_create_id, 912 dm_free_id, 913 914 // attributes 915 get_attr_uint8, 916 get_attr_uint16, 917 get_attr_uint32, 918 get_attr_uint64, 919 get_attr_string, 920 get_attr_raw, 921 get_next_attr, 922 }; 923 924 925 // #pragma mark - device_attr 926 927 928 device_attr_private::device_attr_private() 929 { 930 name = NULL; 931 type = 0; 932 value.raw.data = NULL; 933 value.raw.length = 0; 934 } 935 936 937 device_attr_private::device_attr_private(const device_attr& attr) 938 { 939 CopyFrom(attr); 940 } 941 942 943 device_attr_private::~device_attr_private() 944 { 945 _Unset(); 946 } 947 948 949 status_t 950 device_attr_private::InitCheck() 951 { 952 return name != NULL ? B_OK : B_NO_INIT; 953 } 954 955 956 status_t 957 device_attr_private::CopyFrom(const device_attr& attr) 958 { 959 name = strdup(attr.name); 960 if (name == NULL) 961 return B_NO_MEMORY; 962 963 type = attr.type; 964 965 switch (type) { 966 case B_UINT8_TYPE: 967 case B_UINT16_TYPE: 968 case B_UINT32_TYPE: 969 case B_UINT64_TYPE: 970 value.ui64 = attr.value.ui64; 971 break; 972 973 case B_STRING_TYPE: 974 if (attr.value.string != NULL) { 975 value.string = strdup(attr.value.string); 976 if (value.string == NULL) { 977 _Unset(); 978 return B_NO_MEMORY; 979 } 980 } else 981 value.string = NULL; 982 break; 983 984 case B_RAW_TYPE: 985 value.raw.data = malloc(attr.value.raw.length); 986 if (value.raw.data == NULL) { 987 _Unset(); 988 return B_NO_MEMORY; 989 } 990 991 value.raw.length = attr.value.raw.length; 992 memcpy((void*)value.raw.data, attr.value.raw.data, 993 attr.value.raw.length); 994 break; 995 996 default: 997 return B_BAD_VALUE; 998 } 999 1000 return B_OK; 1001 } 1002 1003 1004 void 1005 device_attr_private::_Unset() 1006 { 1007 if (type == B_STRING_TYPE) 1008 free((char*)value.string); 1009 else if (type == B_RAW_TYPE) 1010 free((void*)value.raw.data); 1011 1012 free((char*)name); 1013 1014 name = NULL; 1015 value.raw.data = NULL; 1016 value.raw.length = 0; 1017 } 1018 1019 1020 /*static*/ int 1021 device_attr_private::Compare(const device_attr* attrA, const device_attr *attrB) 1022 { 1023 if (attrA->type != attrB->type) 1024 return -1; 1025 1026 switch (attrA->type) { 1027 case B_UINT8_TYPE: 1028 return (int)attrA->value.ui8 - (int)attrB->value.ui8; 1029 1030 case B_UINT16_TYPE: 1031 return (int)attrA->value.ui16 - (int)attrB->value.ui16; 1032 1033 case B_UINT32_TYPE: 1034 if (attrA->value.ui32 > attrB->value.ui32) 1035 return 1; 1036 if (attrA->value.ui32 < attrB->value.ui32) 1037 return -1; 1038 return 0; 1039 1040 case B_UINT64_TYPE: 1041 if (attrA->value.ui64 > attrB->value.ui64) 1042 return 1; 1043 if (attrA->value.ui64 < attrB->value.ui64) 1044 return -1; 1045 return 0; 1046 1047 case B_STRING_TYPE: 1048 return strcmp(attrA->value.string, attrB->value.string); 1049 1050 case B_RAW_TYPE: 1051 if (attrA->value.raw.length != attrB->value.raw.length) 1052 return -1; 1053 1054 return memcmp(attrA->value.raw.data, attrB->value.raw.data, 1055 attrA->value.raw.length); 1056 } 1057 1058 return -1; 1059 } 1060 1061 1062 // #pragma mark - Device 1063 1064 1065 Device::Device(device_node* node, const char* moduleName) 1066 : 1067 fRemovedFromParent(false) 1068 { 1069 fNode = node; 1070 fModuleName = strdup(moduleName); 1071 } 1072 1073 1074 Device::~Device() 1075 { 1076 free((char*)fModuleName); 1077 } 1078 1079 1080 status_t 1081 Device::InitCheck() const 1082 { 1083 return fModuleName != NULL ? B_OK : B_NO_MEMORY; 1084 } 1085 1086 1087 status_t 1088 Device::InitDevice() 1089 { 1090 RecursiveLocker _(sLock); 1091 1092 if ((fNode->Flags() & NODE_FLAG_DEVICE_REMOVED) != 0) { 1093 // TODO: maybe the device should be unlinked in devfs, too 1094 return ENODEV; 1095 } 1096 if ((fNode->Flags() & NODE_FLAG_WAITING_FOR_DRIVER) != 0) 1097 return B_BUSY; 1098 1099 if (fInitialized++ > 0) { 1100 fNode->InitDriver(); 1101 // acquire another reference to our parent as well 1102 return B_OK; 1103 } 1104 1105 status_t status = get_module(ModuleName(), (module_info**)&fDeviceModule); 1106 if (status == B_OK) { 1107 // our parent always has to be initialized 1108 status = fNode->InitDriver(); 1109 } 1110 if (status < B_OK) { 1111 fInitialized--; 1112 return status; 1113 } 1114 1115 if (Module()->init_device != NULL) 1116 status = Module()->init_device(fNode->DriverData(), &fDeviceData); 1117 1118 if (status < B_OK) { 1119 fNode->UninitDriver(); 1120 fInitialized--; 1121 1122 put_module(ModuleName()); 1123 fDeviceModule = NULL; 1124 fDeviceData = NULL; 1125 } 1126 1127 return status; 1128 } 1129 1130 1131 void 1132 Device::UninitDevice() 1133 { 1134 RecursiveLocker _(sLock); 1135 1136 if (fInitialized-- > 1) { 1137 fNode->UninitDriver(); 1138 return; 1139 } 1140 1141 TRACE(("uninit driver for node %p\n", this)); 1142 1143 if (Module()->uninit_device != NULL) 1144 Module()->uninit_device(fDeviceData); 1145 1146 fDeviceModule = NULL; 1147 fDeviceData = NULL; 1148 1149 put_module(ModuleName()); 1150 1151 fNode->UninitDriver(); 1152 } 1153 1154 1155 void 1156 Device::Removed() 1157 { 1158 RecursiveLocker _(sLock); 1159 1160 if (!fRemovedFromParent) 1161 fNode->RemoveDevice(this); 1162 1163 delete this; 1164 } 1165 1166 1167 // #pragma mark - device_node 1168 1169 1170 device_node::device_node(const char* moduleName, const device_attr* attrs) 1171 { 1172 fModuleName = strdup(moduleName); 1173 if (fModuleName == NULL) 1174 return; 1175 1176 fParent = NULL; 1177 fRefCount = 1; 1178 fInitialized = 0; 1179 fRegistered = false; 1180 fFlags = 0; 1181 fSupportsParent = 0.0; 1182 fLastUpdateCycle = 0; 1183 fDriver = NULL; 1184 fDriverData = NULL; 1185 1186 // copy attributes 1187 1188 while (attrs != NULL && attrs->name != NULL) { 1189 device_attr_private* attr 1190 = new(std::nothrow) device_attr_private(*attrs); 1191 if (attr == NULL) 1192 break; 1193 1194 fAttributes.Add(attr); 1195 attrs++; 1196 } 1197 1198 get_attr_uint32(this, B_DEVICE_FLAGS, &fFlags, false); 1199 fFlags &= NODE_FLAG_PUBLIC_MASK; 1200 } 1201 1202 1203 device_node::~device_node() 1204 { 1205 TRACE(("delete node %p\n", this)); 1206 ASSERT(DriverModule() == NULL); 1207 1208 if (Parent() != NULL) { 1209 if ((fFlags & NODE_FLAG_OBSOLETE_DRIVER) != 0) { 1210 // This driver has been obsoleted; another driver has been waiting 1211 // for us - make it available 1212 Parent()->_ReleaseWaiting(); 1213 } 1214 Parent()->RemoveChild(this); 1215 } 1216 1217 // Delete children 1218 while (device_node* child = fChildren.RemoveHead()) { 1219 delete child; 1220 } 1221 1222 // Delete devices 1223 while (Device* device = fDevices.RemoveHead()) { 1224 device->SetRemovedFromParent(true); 1225 devfs_unpublish_device(device, true); 1226 } 1227 1228 // Delete attributes 1229 while (device_attr_private* attr = fAttributes.RemoveHead()) { 1230 delete attr; 1231 } 1232 1233 // Delete resources 1234 while (io_resource_private* resource = fResources.RemoveHead()) { 1235 delete resource; 1236 } 1237 1238 free((char*)fModuleName); 1239 } 1240 1241 1242 status_t 1243 device_node::InitCheck() const 1244 { 1245 return fModuleName != NULL ? B_OK : B_NO_MEMORY; 1246 } 1247 1248 1249 status_t 1250 device_node::AcquireResources(const io_resource* resources) 1251 { 1252 if (resources == NULL) 1253 return B_OK; 1254 1255 for (uint32 i = 0; resources[i].type != 0; i++) { 1256 io_resource_private* resource = new(std::nothrow) io_resource_private; 1257 if (resource == NULL) 1258 return B_NO_MEMORY; 1259 1260 status_t status = resource->Acquire(resources[i]); 1261 if (status != B_OK) { 1262 delete resource; 1263 return status; 1264 } 1265 1266 fResources.Add(resource); 1267 } 1268 1269 return B_OK; 1270 } 1271 1272 1273 status_t 1274 device_node::InitDriver() 1275 { 1276 if (fInitialized++ > 0) { 1277 if (Parent() != NULL) { 1278 Parent()->InitDriver(); 1279 // acquire another reference to our parent as well 1280 } 1281 Acquire(); 1282 return B_OK; 1283 } 1284 1285 status_t status = get_module(ModuleName(), (module_info**)&fDriver); 1286 if (status == B_OK && Parent() != NULL) { 1287 // our parent always has to be initialized 1288 status = Parent()->InitDriver(); 1289 } 1290 if (status < B_OK) { 1291 fInitialized--; 1292 return status; 1293 } 1294 1295 if (fDriver->init_driver != NULL) { 1296 status = fDriver->init_driver(this, &fDriverData); 1297 if (status != B_OK) { 1298 dprintf("driver %s init failed: %s\n", ModuleName(), 1299 strerror(status)); 1300 } 1301 } 1302 1303 if (status < B_OK) { 1304 if (Parent() != NULL) 1305 Parent()->UninitDriver(); 1306 fInitialized--; 1307 1308 put_module(ModuleName()); 1309 fDriver = NULL; 1310 fDriverData = NULL; 1311 return status; 1312 } 1313 1314 Acquire(); 1315 return B_OK; 1316 } 1317 1318 1319 bool 1320 device_node::UninitDriver() 1321 { 1322 if (fInitialized-- > 1) { 1323 if (Parent() != NULL) 1324 Parent()->UninitDriver(); 1325 Release(); 1326 return false; 1327 } 1328 1329 TRACE(("uninit driver for node %p\n", this)); 1330 1331 if (fDriver->uninit_driver != NULL) 1332 fDriver->uninit_driver(fDriverData); 1333 1334 fDriver = NULL; 1335 fDriverData = NULL; 1336 1337 put_module(ModuleName()); 1338 1339 if (Parent() != NULL) 1340 Parent()->UninitDriver(); 1341 Release(); 1342 1343 return true; 1344 } 1345 1346 1347 void 1348 device_node::AddChild(device_node* node) 1349 { 1350 // we must not be destroyed as long as we have children 1351 Acquire(); 1352 node->fParent = this; 1353 1354 int32 priority = node->Priority(); 1355 1356 // Enforce an order in which the children are traversed - from most 1357 // specific to least specific child. 1358 NodeList::Iterator iterator = fChildren.GetIterator(); 1359 device_node* before = NULL; 1360 while (iterator.HasNext()) { 1361 device_node* child = iterator.Next(); 1362 if (child->Priority() <= priority) { 1363 before = child; 1364 break; 1365 } 1366 } 1367 1368 fChildren.Insert(before, node); 1369 } 1370 1371 1372 void 1373 device_node::RemoveChild(device_node* node) 1374 { 1375 node->fParent = NULL; 1376 fChildren.Remove(node); 1377 Release(); 1378 } 1379 1380 1381 /*! Registers this node, and all of its children that have to be registered. 1382 Also initializes the driver and keeps it that way on return in case 1383 it returns successfully. 1384 */ 1385 status_t 1386 device_node::Register(device_node* parent) 1387 { 1388 // make it public 1389 if (parent != NULL) 1390 parent->AddChild(this); 1391 else 1392 sRootNode = this; 1393 1394 status_t status = InitDriver(); 1395 if (status != B_OK) 1396 return status; 1397 1398 if ((fFlags & B_KEEP_DRIVER_LOADED) != 0) { 1399 // We keep this driver loaded by having it always initialized 1400 InitDriver(); 1401 } 1402 1403 fFlags |= NODE_FLAG_REGISTER_INITIALIZED; 1404 // We don't uninitialize the driver - this is done by the caller 1405 // in order to save reinitializing during driver loading. 1406 1407 uint32 registeredFixedCount; 1408 status = _RegisterFixed(registeredFixedCount); 1409 if (status != B_OK) { 1410 UninitUnusedDriver(); 1411 return status; 1412 } 1413 1414 // Register the children the driver wants 1415 1416 if (DriverModule()->register_child_devices != NULL) { 1417 status = DriverModule()->register_child_devices(DriverData()); 1418 if (status != B_OK) { 1419 UninitUnusedDriver(); 1420 return status; 1421 } 1422 1423 if (!fChildren.IsEmpty()) { 1424 fRegistered = true; 1425 return B_OK; 1426 } 1427 } 1428 1429 if (registeredFixedCount > 0) { 1430 // Nodes with fixed children cannot have any dynamic children, so bail 1431 // out here 1432 fRegistered = true; 1433 return B_OK; 1434 } 1435 1436 // Register all possible child device nodes 1437 1438 status = _RegisterDynamic(); 1439 if (status == B_OK) 1440 fRegistered = true; 1441 else 1442 UninitUnusedDriver(); 1443 1444 return status; 1445 } 1446 1447 1448 /*! Registers any children that are identified via the B_DEVICE_FIXED_CHILD 1449 attribute. 1450 If any of these children cannot be registered, this call will fail (we 1451 don't remove children we already registered up to this point in this case). 1452 */ 1453 status_t 1454 device_node::_RegisterFixed(uint32& registered) 1455 { 1456 AttributeList::Iterator iterator = fAttributes.GetIterator(); 1457 registered = 0; 1458 1459 while (iterator.HasNext()) { 1460 device_attr_private* attr = iterator.Next(); 1461 if (strcmp(attr->name, B_DEVICE_FIXED_CHILD)) 1462 continue; 1463 1464 driver_module_info* driver; 1465 status_t status = get_module(attr->value.string, 1466 (module_info**)&driver); 1467 if (status != B_OK) { 1468 TRACE(("register fixed child %s failed: %s\n", attr->value.string, 1469 strerror(status))); 1470 return status; 1471 } 1472 1473 if (driver->register_device != NULL) { 1474 status = driver->register_device(this); 1475 if (status == B_OK) 1476 registered++; 1477 } 1478 1479 put_module(attr->value.string); 1480 1481 if (status != B_OK) 1482 return status; 1483 } 1484 1485 return B_OK; 1486 } 1487 1488 1489 status_t 1490 device_node::_AddPath(Stack<KPath*>& stack, const char* basePath, 1491 const char* subPath) 1492 { 1493 KPath* path = new(std::nothrow) KPath; 1494 if (path == NULL) 1495 return B_NO_MEMORY; 1496 1497 status_t status = path->SetTo(basePath); 1498 if (status == B_OK && subPath != NULL && subPath[0]) 1499 status = path->Append(subPath); 1500 if (status == B_OK) 1501 status = stack.Push(path); 1502 1503 TRACE((" add path: \"%s\", %ld\n", path->Path(), status)); 1504 1505 if (status != B_OK) 1506 delete path; 1507 1508 return status; 1509 } 1510 1511 1512 status_t 1513 device_node::_GetNextDriverPath(void*& cookie, KPath& _path) 1514 { 1515 Stack<KPath*>* stack = NULL; 1516 1517 if (cookie == NULL) { 1518 // find all paths and add them 1519 stack = new(std::nothrow) Stack<KPath*>(); 1520 if (stack == NULL) 1521 return B_NO_MEMORY; 1522 1523 StackDeleter<KPath*> stackDeleter(stack); 1524 1525 bool generic = false; 1526 uint16 type = 0; 1527 uint16 subType = 0; 1528 uint16 interface = 0; 1529 if (get_attr_uint16(this, B_DEVICE_TYPE, &type, false) != B_OK 1530 || get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false) 1531 != B_OK) 1532 generic = true; 1533 1534 get_attr_uint16(this, B_DEVICE_INTERFACE, &interface, false); 1535 1536 // TODO: maybe make this extendible via settings file? 1537 switch (type) { 1538 case PCI_mass_storage: 1539 switch (subType) { 1540 case PCI_scsi: 1541 _AddPath(*stack, "busses", "scsi"); 1542 break; 1543 case PCI_ide: 1544 _AddPath(*stack, "busses", "ata"); 1545 _AddPath(*stack, "busses", "ide"); 1546 break; 1547 case PCI_sata: 1548 // TODO: check for ahci interface 1549 _AddPath(*stack, "busses", "scsi"); 1550 _AddPath(*stack, "busses", "ata"); 1551 _AddPath(*stack, "busses", "ide"); 1552 break; 1553 default: 1554 _AddPath(*stack, "busses"); 1555 break; 1556 } 1557 break; 1558 case PCI_serial_bus: 1559 switch (subType) { 1560 case PCI_firewire: 1561 _AddPath(*stack, "busses", "firewire"); 1562 break; 1563 case PCI_usb: 1564 _AddPath(*stack, "busses", "usb"); 1565 break; 1566 default: 1567 _AddPath(*stack, "busses"); 1568 break; 1569 } 1570 break; 1571 case PCI_network: 1572 _AddPath(*stack, "drivers", "net"); 1573 break; 1574 case PCI_display: 1575 _AddPath(*stack, "drivers", "graphics"); 1576 break; 1577 case PCI_multimedia: 1578 switch (subType) { 1579 case PCI_audio: 1580 case PCI_hd_audio: 1581 _AddPath(*stack, "drivers", "audio"); 1582 break; 1583 case PCI_video: 1584 _AddPath(*stack, "drivers", "video"); 1585 break; 1586 default: 1587 _AddPath(*stack, "drivers"); 1588 break; 1589 } 1590 break; 1591 default: 1592 if (sRootNode == this) { 1593 _AddPath(*stack, "busses/pci"); 1594 _AddPath(*stack, "bus_managers"); 1595 } else if (!generic) { 1596 _AddPath(*stack, "drivers"); 1597 } else { 1598 // For generic drivers, we only allow busses when the 1599 // request is more specified 1600 if (sGenericContextPath != NULL 1601 && (!strcmp(sGenericContextPath, "disk") 1602 || !strcmp(sGenericContextPath, "ports") 1603 || !strcmp(sGenericContextPath, "bus"))) { 1604 _AddPath(*stack, "busses"); 1605 } 1606 _AddPath(*stack, "drivers", sGenericContextPath); 1607 } 1608 break; 1609 } 1610 1611 stackDeleter.Detach(); 1612 1613 cookie = (void*)stack; 1614 } else 1615 stack = static_cast<Stack<KPath*>*>(cookie); 1616 1617 KPath* path; 1618 if (stack->Pop(&path)) { 1619 _path.Adopt(*path); 1620 delete path; 1621 return B_OK; 1622 } 1623 1624 delete stack; 1625 return B_ENTRY_NOT_FOUND; 1626 } 1627 1628 1629 status_t 1630 device_node::_GetNextDriver(void* list, driver_module_info*& driver) 1631 { 1632 while (true) { 1633 char name[B_FILE_NAME_LENGTH]; 1634 size_t nameLength = sizeof(name); 1635 1636 status_t status = read_next_module_name(list, name, &nameLength); 1637 if (status != B_OK) 1638 return status; 1639 1640 if (!strcmp(fModuleName, name)) 1641 continue; 1642 1643 if (get_module(name, (module_info**)&driver) != B_OK) 1644 continue; 1645 1646 if (driver->supports_device == NULL 1647 || driver->register_device == NULL) { 1648 put_module(name); 1649 continue; 1650 } 1651 1652 return B_OK; 1653 } 1654 } 1655 1656 1657 status_t 1658 device_node::_FindBestDriver(const char* path, driver_module_info*& bestDriver, 1659 float& bestSupport, device_node* previous) 1660 { 1661 if (bestDriver == NULL) 1662 bestSupport = previous != NULL ? previous->fSupportsParent : 0.0f; 1663 1664 void* list = open_module_list_etc(path, "driver_v1"); 1665 driver_module_info* driver; 1666 while (_GetNextDriver(list, driver) == B_OK) { 1667 if (previous != NULL && driver == previous->DriverModule()) { 1668 put_module(driver->info.name); 1669 continue; 1670 } 1671 1672 float support = driver->supports_device(this); 1673 if (support > bestSupport) { 1674 if (bestDriver != NULL) 1675 put_module(bestDriver->info.name); 1676 1677 bestDriver = driver; 1678 bestSupport = support; 1679 continue; 1680 // keep reference to best module around 1681 } 1682 1683 put_module(driver->info.name); 1684 } 1685 close_module_list(list); 1686 1687 return bestDriver != NULL ? B_OK : B_ENTRY_NOT_FOUND; 1688 } 1689 1690 1691 status_t 1692 device_node::_RegisterPath(const char* path) 1693 { 1694 void* list = open_module_list_etc(path, "driver_v1"); 1695 driver_module_info* driver; 1696 uint32 count = 0; 1697 1698 while (_GetNextDriver(list, driver) == B_OK) { 1699 float support = driver->supports_device(this); 1700 if (support > 0.0) { 1701 TRACE((" register module \"%s\", support %f\n", driver->info.name, 1702 support)); 1703 if (driver->register_device(this) == B_OK) 1704 count++; 1705 } 1706 1707 put_module(driver->info.name); 1708 } 1709 close_module_list(list); 1710 1711 return count > 0 ? B_OK : B_ENTRY_NOT_FOUND; 1712 } 1713 1714 1715 bool 1716 device_node::_AlwaysRegisterDynamic() 1717 { 1718 uint16 type = 0; 1719 uint16 subType = 0; 1720 get_attr_uint16(this, B_DEVICE_TYPE, &type, false); 1721 get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false); 1722 1723 return type == PCI_serial_bus || type == PCI_bridge; 1724 // TODO: we may want to be a bit more specific in the future 1725 } 1726 1727 1728 status_t 1729 device_node::_RegisterDynamic(device_node* previous) 1730 { 1731 // If this is not a bus, we don't have to scan it 1732 if (find_attr(this, B_DEVICE_BUS, false, B_STRING_TYPE) == NULL) 1733 return B_OK; 1734 1735 // If we're not being probed, we honour the B_FIND_CHILD_ON_DEMAND 1736 // requirements 1737 if (!IsProbed() && (fFlags & B_FIND_CHILD_ON_DEMAND) != 0 1738 && !_AlwaysRegisterDynamic()) 1739 return B_OK; 1740 1741 KPath path; 1742 1743 if ((fFlags & B_FIND_MULTIPLE_CHILDREN) == 0) { 1744 // find the one driver 1745 driver_module_info* bestDriver = NULL; 1746 float bestSupport = 0.0; 1747 void* cookie = NULL; 1748 1749 while (_GetNextDriverPath(cookie, path) == B_OK) { 1750 _FindBestDriver(path.Path(), bestDriver, bestSupport, previous); 1751 } 1752 1753 if (bestDriver != NULL) { 1754 TRACE((" register best module \"%s\", support %f\n", 1755 bestDriver->info.name, bestSupport)); 1756 if (bestDriver->register_device(this) == B_OK) { 1757 // There can only be one node of this driver 1758 // (usually only one at all, but there might be a new driver 1759 // "waiting" for its turn) 1760 device_node* child = FindChild(bestDriver->info.name); 1761 if (child != NULL) { 1762 child->fSupportsParent = bestSupport; 1763 if (previous != NULL) { 1764 previous->fFlags |= NODE_FLAG_OBSOLETE_DRIVER; 1765 previous->Release(); 1766 child->fFlags |= NODE_FLAG_WAITING_FOR_DRIVER; 1767 } 1768 } 1769 // TODO: if this fails, we could try the second best driver, 1770 // and so on... 1771 } 1772 put_module(bestDriver->info.name); 1773 } 1774 } else { 1775 // register all drivers that match 1776 void* cookie = NULL; 1777 while (_GetNextDriverPath(cookie, path) == B_OK) { 1778 _RegisterPath(path.Path()); 1779 } 1780 } 1781 1782 return B_OK; 1783 } 1784 1785 1786 void 1787 device_node::_ReleaseWaiting() 1788 { 1789 NodeList::Iterator iterator = fChildren.GetIterator(); 1790 while (iterator.HasNext()) { 1791 device_node* child = iterator.Next(); 1792 1793 child->fFlags &= ~NODE_FLAG_WAITING_FOR_DRIVER; 1794 } 1795 } 1796 1797 1798 status_t 1799 device_node::_RemoveChildren() 1800 { 1801 NodeList::Iterator iterator = fChildren.GetIterator(); 1802 while (iterator.HasNext()) { 1803 device_node* child = iterator.Next(); 1804 child->Release(); 1805 } 1806 1807 return fChildren.IsEmpty() ? B_OK : B_BUSY; 1808 } 1809 1810 1811 device_node* 1812 device_node::_FindCurrentChild() 1813 { 1814 NodeList::Iterator iterator = fChildren.GetIterator(); 1815 while (iterator.HasNext()) { 1816 device_node* child = iterator.Next(); 1817 1818 if ((child->Flags() & NODE_FLAG_WAITING_FOR_DRIVER) == 0) 1819 return child; 1820 } 1821 1822 return NULL; 1823 } 1824 1825 1826 status_t 1827 device_node::_Probe() 1828 { 1829 device_node* previous = NULL; 1830 1831 if (IsProbed() && !fChildren.IsEmpty() 1832 && (fFlags & (B_FIND_CHILD_ON_DEMAND | B_FIND_MULTIPLE_CHILDREN)) 1833 == B_FIND_CHILD_ON_DEMAND) { 1834 // We already have a driver that claims this node; remove all 1835 // (unused) nodes, and evaluate it again 1836 _RemoveChildren(); 1837 1838 previous = _FindCurrentChild(); 1839 if (previous != NULL) { 1840 // This driver is still active - give it back the reference 1841 // that was stolen by _RemoveChildren() - _RegisterDynamic() 1842 // will release it, if it really isn't needed anymore 1843 previous->Acquire(); 1844 } 1845 } 1846 1847 return _RegisterDynamic(previous); 1848 } 1849 1850 1851 status_t 1852 device_node::Probe(const char* devicePath, uint32 updateCycle) 1853 { 1854 if ((fFlags & NODE_FLAG_DEVICE_REMOVED) != 0 1855 || updateCycle == fLastUpdateCycle) 1856 return B_OK; 1857 1858 status_t status = InitDriver(); 1859 if (status < B_OK) 1860 return status; 1861 1862 MethodDeleter<device_node, bool> uninit(this, 1863 &device_node::UninitDriver); 1864 1865 if ((fFlags & B_FIND_CHILD_ON_DEMAND) != 0) { 1866 bool matches = false; 1867 uint16 type = 0; 1868 uint16 subType = 0; 1869 if (get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false) == B_OK 1870 && get_attr_uint16(this, B_DEVICE_TYPE, &type, false) == B_OK) { 1871 // Check if this node matches the device path 1872 // TODO: maybe make this extendible via settings file? 1873 if (!strcmp(devicePath, "disk")) { 1874 matches = type == PCI_mass_storage; 1875 } else if (!strcmp(devicePath, "audio")) { 1876 matches = type == PCI_multimedia 1877 && (subType == PCI_audio || subType == PCI_hd_audio); 1878 } else if (!strcmp(devicePath, "net")) { 1879 matches = type == PCI_network; 1880 } else if (!strcmp(devicePath, "graphics")) { 1881 matches = type == PCI_display; 1882 } else if (!strcmp(devicePath, "video")) { 1883 matches = type == PCI_multimedia && subType == PCI_video; 1884 } 1885 } else { 1886 // This driver does not support types, but still wants to its 1887 // children explored on demand only. 1888 matches = true; 1889 sGenericContextPath = devicePath; 1890 } 1891 1892 if (matches) { 1893 fLastUpdateCycle = updateCycle; 1894 // This node will be probed in this update cycle 1895 1896 status = _Probe(); 1897 1898 sGenericContextPath = NULL; 1899 return status; 1900 } 1901 1902 return B_OK; 1903 } 1904 1905 NodeList::Iterator iterator = fChildren.GetIterator(); 1906 while (iterator.HasNext()) { 1907 device_node* child = iterator.Next(); 1908 1909 status = child->Probe(devicePath, updateCycle); 1910 if (status != B_OK) 1911 return status; 1912 } 1913 1914 return B_OK; 1915 } 1916 1917 1918 status_t 1919 device_node::Reprobe() 1920 { 1921 status_t status = InitDriver(); 1922 if (status < B_OK) 1923 return status; 1924 1925 MethodDeleter<device_node, bool> uninit(this, 1926 &device_node::UninitDriver); 1927 1928 // If this child has been probed already, probe it again 1929 status = _Probe(); 1930 if (status != B_OK) 1931 return status; 1932 1933 NodeList::Iterator iterator = fChildren.GetIterator(); 1934 while (iterator.HasNext()) { 1935 device_node* child = iterator.Next(); 1936 1937 status = child->Reprobe(); 1938 if (status != B_OK) 1939 return status; 1940 } 1941 1942 return B_OK; 1943 } 1944 1945 1946 status_t 1947 device_node::Rescan() 1948 { 1949 status_t status = InitDriver(); 1950 if (status < B_OK) 1951 return status; 1952 1953 MethodDeleter<device_node, bool> uninit(this, 1954 &device_node::UninitDriver); 1955 1956 if (DriverModule()->rescan_child_devices != NULL) { 1957 status = DriverModule()->rescan_child_devices(DriverData()); 1958 if (status != B_OK) 1959 return status; 1960 } 1961 1962 NodeList::Iterator iterator = fChildren.GetIterator(); 1963 while (iterator.HasNext()) { 1964 device_node* child = iterator.Next(); 1965 1966 status = child->Rescan(); 1967 if (status != B_OK) 1968 return status; 1969 } 1970 1971 return B_OK; 1972 } 1973 1974 1975 /*! Uninitializes all temporary references to the driver. The registration 1976 process keeps the driver initialized to optimize the startup procedure; 1977 this function gives this reference away again. 1978 */ 1979 void 1980 device_node::UninitUnusedDriver() 1981 { 1982 // First, we need to go to the leaf, and go back from there 1983 1984 NodeList::Iterator iterator = fChildren.GetIterator(); 1985 while (iterator.HasNext()) { 1986 device_node* child = iterator.Next(); 1987 1988 child->UninitUnusedDriver(); 1989 } 1990 1991 if (!IsInitialized() 1992 || (fFlags & NODE_FLAG_REGISTER_INITIALIZED) == 0) 1993 return; 1994 1995 fFlags &= ~NODE_FLAG_REGISTER_INITIALIZED; 1996 1997 UninitDriver(); 1998 } 1999 2000 2001 /*! Calls device_removed() on this node and all of its children - starting 2002 with the deepest and last child. 2003 It will also remove the one reference that every node gets on its creation. 2004 */ 2005 void 2006 device_node::DeviceRemoved() 2007 { 2008 // notify children 2009 NodeList::ConstIterator iterator = Children().GetIterator(); 2010 while (iterator.HasNext()) { 2011 device_node* child = iterator.Next(); 2012 2013 child->DeviceRemoved(); 2014 } 2015 2016 // notify devices 2017 DeviceList::ConstIterator deviceIterator = Devices().GetIterator(); 2018 while (deviceIterator.HasNext()) { 2019 Device* device = deviceIterator.Next(); 2020 2021 if (device->Module() != NULL 2022 && device->Module()->device_removed != NULL) 2023 device->Module()->device_removed(device->Data()); 2024 } 2025 2026 fFlags |= NODE_FLAG_DEVICE_REMOVED; 2027 2028 if (IsInitialized() && DriverModule()->device_removed != NULL) 2029 DriverModule()->device_removed(this); 2030 2031 if ((fFlags & B_KEEP_DRIVER_LOADED) != 0) { 2032 // There is no point in keeping this driver loaded when its device 2033 // is gone 2034 UninitDriver(); 2035 } 2036 2037 UninitUnusedDriver(); 2038 Release(); 2039 } 2040 2041 2042 void 2043 device_node::Acquire() 2044 { 2045 atomic_add(&fRefCount, 1); 2046 } 2047 2048 2049 bool 2050 device_node::Release() 2051 { 2052 if (atomic_add(&fRefCount, -1) > 1) 2053 return false; 2054 2055 delete this; 2056 return true; 2057 } 2058 2059 2060 void 2061 device_node::AddDevice(Device* device) 2062 { 2063 fDevices.Add(device); 2064 } 2065 2066 2067 void 2068 device_node::RemoveDevice(Device* device) 2069 { 2070 fDevices.Remove(device); 2071 } 2072 2073 2074 int 2075 device_node::CompareTo(const device_attr* attributes) const 2076 { 2077 if (attributes == NULL) 2078 return -1; 2079 2080 for (; attributes->name != NULL; attributes++) { 2081 // find corresponding attribute 2082 AttributeList::ConstIterator iterator = Attributes().GetIterator(); 2083 device_attr_private* attr = NULL; 2084 bool found = false; 2085 2086 while (iterator.HasNext()) { 2087 attr = iterator.Next(); 2088 2089 if (!strcmp(attr->name, attributes->name)) { 2090 found = true; 2091 break; 2092 } 2093 } 2094 if (!found) 2095 return -1; 2096 2097 int compare = device_attr_private::Compare(attr, attributes); 2098 if (compare != 0) 2099 return compare; 2100 } 2101 2102 return 0; 2103 } 2104 2105 2106 device_node* 2107 device_node::FindChild(const device_attr* attributes) const 2108 { 2109 if (attributes == NULL) 2110 return NULL; 2111 2112 NodeList::ConstIterator iterator = Children().GetIterator(); 2113 while (iterator.HasNext()) { 2114 device_node* child = iterator.Next(); 2115 2116 // ignore nodes that are pending to be removed 2117 if ((child->Flags() & NODE_FLAG_DEVICE_REMOVED) == 0 2118 && !child->CompareTo(attributes)) 2119 return child; 2120 } 2121 2122 return NULL; 2123 } 2124 2125 2126 device_node* 2127 device_node::FindChild(const char* moduleName) const 2128 { 2129 if (moduleName == NULL) 2130 return NULL; 2131 2132 NodeList::ConstIterator iterator = Children().GetIterator(); 2133 while (iterator.HasNext()) { 2134 device_node* child = iterator.Next(); 2135 2136 if (!strcmp(child->ModuleName(), moduleName)) 2137 return child; 2138 } 2139 2140 return NULL; 2141 } 2142 2143 2144 /*! This returns the priority or importance of this node. Nodes with higher 2145 priority are registered/probed first. 2146 Currently, only the B_FIND_MULTIPLE_CHILDREN flag alters the priority; 2147 it might make sense to be able to directly set the priority via an 2148 attribute. 2149 */ 2150 int32 2151 device_node::Priority() 2152 { 2153 return (fFlags & B_FIND_MULTIPLE_CHILDREN) != 0 ? 0 : 100; 2154 } 2155 2156 2157 void 2158 device_node::Dump(int32 level) 2159 { 2160 put_level(level); 2161 kprintf("(%ld) @%p \"%s\" (ref %ld, init %ld, module %p, data %p)\n", level, 2162 this, ModuleName(), fRefCount, fInitialized, DriverModule(), 2163 DriverData()); 2164 2165 AttributeList::Iterator attribute = Attributes().GetIterator(); 2166 while (attribute.HasNext()) { 2167 dump_attribute(attribute.Next(), level); 2168 } 2169 2170 DeviceList::Iterator deviceIterator = fDevices.GetIterator(); 2171 while (deviceIterator.HasNext()) { 2172 Device* device = deviceIterator.Next(); 2173 put_level(level); 2174 kprintf("device: %s, %p\n", device->ModuleName(), device->Data()); 2175 } 2176 2177 NodeList::ConstIterator iterator = Children().GetIterator(); 2178 while (iterator.HasNext()) { 2179 iterator.Next()->Dump(level + 1); 2180 } 2181 } 2182 2183 2184 // #pragma mark - root node 2185 2186 2187 static void 2188 init_node_tree(void) 2189 { 2190 device_attr attrs[] = { 2191 {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "Devices Root"}}, 2192 {B_DEVICE_BUS, B_STRING_TYPE, {string: "root"}}, 2193 {B_DEVICE_FLAGS, B_UINT32_TYPE, 2194 {ui32: B_FIND_MULTIPLE_CHILDREN | B_KEEP_DRIVER_LOADED }}, 2195 {NULL} 2196 }; 2197 2198 device_node* node; 2199 if (register_node(NULL, DEVICE_MANAGER_ROOT_NAME, attrs, NULL, &node) 2200 != B_OK) { 2201 dprintf("Cannot register Devices Root Node\n"); 2202 } 2203 2204 device_attr genericAttrs[] = { 2205 {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "Generic"}}, 2206 {B_DEVICE_BUS, B_STRING_TYPE, {string: "generic"}}, 2207 {B_DEVICE_FLAGS, B_UINT32_TYPE, {ui32: B_FIND_MULTIPLE_CHILDREN 2208 | B_KEEP_DRIVER_LOADED | B_FIND_CHILD_ON_DEMAND}}, 2209 {NULL} 2210 }; 2211 2212 if (register_node(node, DEVICE_MANAGER_GENERIC_NAME, genericAttrs, NULL, 2213 NULL) != B_OK) { 2214 dprintf("Cannot register Generic Devices Node\n"); 2215 } 2216 } 2217 2218 2219 driver_module_info gDeviceRootModule = { 2220 { 2221 DEVICE_MANAGER_ROOT_NAME, 2222 0, 2223 NULL, 2224 }, 2225 }; 2226 2227 2228 driver_module_info gDeviceGenericModule = { 2229 { 2230 DEVICE_MANAGER_GENERIC_NAME, 2231 0, 2232 NULL, 2233 }, 2234 NULL 2235 }; 2236 2237 2238 // #pragma mark - private kernel API 2239 2240 2241 status_t 2242 device_manager_probe(const char* path, uint32 updateCycle) 2243 { 2244 TRACE(("device_manager_probe(\"%s\")\n", path)); 2245 RecursiveLocker _(sLock); 2246 2247 // first, publish directories in the driver directory 2248 publish_directories(path); 2249 2250 return sRootNode->Probe(path, updateCycle); 2251 } 2252 2253 2254 status_t 2255 device_manager_init(struct kernel_args* args) 2256 { 2257 TRACE(("device manager init\n")); 2258 2259 vip_io_request_allocator_init(); 2260 2261 dm_init_id_generator(); 2262 dm_init_io_resources(); 2263 2264 recursive_lock_init(&sLock, "device manager"); 2265 init_node_tree(); 2266 2267 register_generic_syscall(DEVICE_MANAGER_SYSCALLS, control_device_manager, 2268 1, 0); 2269 2270 add_debugger_command("dm_tree", &dump_device_nodes, 2271 "dump device node tree"); 2272 add_debugger_command_etc("io_scheduler", &dump_io_scheduler, 2273 "Dump an I/O scheduler", 2274 "<scheduler>\n" 2275 "Dumps I/O scheduler at address <scheduler>.\n", 0); 2276 add_debugger_command_etc("io_request_owner", &dump_io_request_owner, 2277 "Dump an I/O request owner", 2278 "<owner>\n" 2279 "Dumps I/O request owner at address <owner>.\n", 0); 2280 add_debugger_command("io_request", &dump_io_request, "dump an I/O request"); 2281 add_debugger_command("io_operation", &dump_io_operation, 2282 "dump an I/O operation"); 2283 add_debugger_command("io_buffer", &dump_io_buffer, "dump an I/O buffer"); 2284 add_debugger_command("dma_buffer", &dump_dma_buffer, "dump a DMA buffer"); 2285 return B_OK; 2286 } 2287 2288 2289 status_t 2290 device_manager_init_post_modules(struct kernel_args* args) 2291 { 2292 RecursiveLocker _(sLock); 2293 return sRootNode->Reprobe(); 2294 } 2295 2296