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