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