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