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