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