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