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