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 default: 1564 _AddPath(*stack, "busses"); 1565 break; 1566 } 1567 break; 1568 case PCI_serial_bus: 1569 switch (subType) { 1570 case PCI_firewire: 1571 _AddPath(*stack, "busses", "firewire"); 1572 break; 1573 case PCI_usb: 1574 _AddPath(*stack, "busses", "usb"); 1575 break; 1576 default: 1577 _AddPath(*stack, "busses"); 1578 break; 1579 } 1580 break; 1581 case PCI_network: 1582 _AddPath(*stack, "drivers", "net"); 1583 _AddPath(*stack, "busses", "virtio"); 1584 break; 1585 case PCI_display: 1586 _AddPath(*stack, "drivers", "graphics"); 1587 break; 1588 case PCI_multimedia: 1589 switch (subType) { 1590 case PCI_audio: 1591 case PCI_hd_audio: 1592 _AddPath(*stack, "drivers", "audio"); 1593 break; 1594 case PCI_video: 1595 _AddPath(*stack, "drivers", "video"); 1596 break; 1597 default: 1598 _AddPath(*stack, "drivers"); 1599 break; 1600 } 1601 break; 1602 default: 1603 if (sRootNode == this) { 1604 _AddPath(*stack, "busses/pci"); 1605 _AddPath(*stack, "bus_managers"); 1606 } else if (!generic) { 1607 _AddPath(*stack, "busses", "virtio"); 1608 _AddPath(*stack, "drivers"); 1609 } else { 1610 // For generic drivers, we only allow busses when the 1611 // request is more specified 1612 if (sGenericContextPath != NULL 1613 && (!strcmp(sGenericContextPath, "disk") 1614 || !strcmp(sGenericContextPath, "ports") 1615 || !strcmp(sGenericContextPath, "bus"))) { 1616 _AddPath(*stack, "busses"); 1617 } 1618 _AddPath(*stack, "drivers", sGenericContextPath); 1619 _AddPath(*stack, "busses/scsi"); 1620 _AddPath(*stack, "busses/random"); 1621 } 1622 break; 1623 } 1624 1625 stackDeleter.Detach(); 1626 1627 cookie = (void*)stack; 1628 } else 1629 stack = static_cast<Stack<KPath*>*>(cookie); 1630 1631 KPath* path; 1632 if (stack->Pop(&path)) { 1633 _path.Adopt(*path); 1634 delete path; 1635 return B_OK; 1636 } 1637 1638 delete stack; 1639 return B_ENTRY_NOT_FOUND; 1640 } 1641 1642 1643 status_t 1644 device_node::_GetNextDriver(void* list, driver_module_info*& driver) 1645 { 1646 while (true) { 1647 char name[B_FILE_NAME_LENGTH]; 1648 size_t nameLength = sizeof(name); 1649 1650 status_t status = read_next_module_name(list, name, &nameLength); 1651 if (status != B_OK) 1652 return status; 1653 1654 if (!strcmp(fModuleName, name)) 1655 continue; 1656 1657 if (get_module(name, (module_info**)&driver) != B_OK) 1658 continue; 1659 1660 if (driver->supports_device == NULL 1661 || driver->register_device == NULL) { 1662 put_module(name); 1663 continue; 1664 } 1665 1666 return B_OK; 1667 } 1668 } 1669 1670 1671 status_t 1672 device_node::_FindBestDriver(const char* path, driver_module_info*& bestDriver, 1673 float& bestSupport, device_node* previous) 1674 { 1675 if (bestDriver == NULL) 1676 bestSupport = previous != NULL ? previous->fSupportsParent : 0.0f; 1677 1678 void* list = open_module_list_etc(path, "driver_v1"); 1679 driver_module_info* driver; 1680 while (_GetNextDriver(list, driver) == B_OK) { 1681 if (previous != NULL && driver == previous->DriverModule()) { 1682 put_module(driver->info.name); 1683 continue; 1684 } 1685 1686 float support = driver->supports_device(this); 1687 if (support > bestSupport) { 1688 if (bestDriver != NULL) 1689 put_module(bestDriver->info.name); 1690 1691 bestDriver = driver; 1692 bestSupport = support; 1693 continue; 1694 // keep reference to best module around 1695 } 1696 1697 put_module(driver->info.name); 1698 } 1699 close_module_list(list); 1700 1701 return bestDriver != NULL ? B_OK : B_ENTRY_NOT_FOUND; 1702 } 1703 1704 1705 status_t 1706 device_node::_RegisterPath(const char* path) 1707 { 1708 void* list = open_module_list_etc(path, "driver_v1"); 1709 driver_module_info* driver; 1710 uint32 count = 0; 1711 1712 while (_GetNextDriver(list, driver) == B_OK) { 1713 float support = driver->supports_device(this); 1714 if (support > 0.0) { 1715 TRACE((" register module \"%s\", support %f\n", driver->info.name, 1716 support)); 1717 if (driver->register_device(this) == B_OK) 1718 count++; 1719 } 1720 1721 put_module(driver->info.name); 1722 } 1723 close_module_list(list); 1724 1725 return count > 0 ? B_OK : B_ENTRY_NOT_FOUND; 1726 } 1727 1728 1729 bool 1730 device_node::_AlwaysRegisterDynamic() 1731 { 1732 uint16 type = 0; 1733 uint16 subType = 0; 1734 get_attr_uint16(this, B_DEVICE_TYPE, &type, false); 1735 get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false); 1736 1737 return type == PCI_serial_bus || type == PCI_bridge || type == 0; 1738 // TODO: we may want to be a bit more specific in the future 1739 } 1740 1741 1742 status_t 1743 device_node::_RegisterDynamic(device_node* previous) 1744 { 1745 // If this is not a bus, we don't have to scan it 1746 if (find_attr(this, B_DEVICE_BUS, false, B_STRING_TYPE) == NULL) 1747 return B_OK; 1748 1749 // If we're not being probed, we honour the B_FIND_CHILD_ON_DEMAND 1750 // requirements 1751 if (!IsProbed() && (fFlags & B_FIND_CHILD_ON_DEMAND) != 0 1752 && !_AlwaysRegisterDynamic()) 1753 return B_OK; 1754 1755 KPath path; 1756 1757 if ((fFlags & B_FIND_MULTIPLE_CHILDREN) == 0) { 1758 // find the one driver 1759 driver_module_info* bestDriver = NULL; 1760 float bestSupport = 0.0; 1761 void* cookie = NULL; 1762 1763 while (_GetNextDriverPath(cookie, path) == B_OK) { 1764 _FindBestDriver(path.Path(), bestDriver, bestSupport, previous); 1765 } 1766 1767 if (bestDriver != NULL) { 1768 TRACE((" register best module \"%s\", support %f\n", 1769 bestDriver->info.name, bestSupport)); 1770 if (bestDriver->register_device(this) == B_OK) { 1771 // There can only be one node of this driver 1772 // (usually only one at all, but there might be a new driver 1773 // "waiting" for its turn) 1774 device_node* child = FindChild(bestDriver->info.name); 1775 if (child != NULL) { 1776 child->fSupportsParent = bestSupport; 1777 if (previous != NULL) { 1778 previous->fFlags |= NODE_FLAG_OBSOLETE_DRIVER; 1779 previous->Release(); 1780 child->fFlags |= NODE_FLAG_WAITING_FOR_DRIVER; 1781 } 1782 } 1783 // TODO: if this fails, we could try the second best driver, 1784 // and so on... 1785 } 1786 put_module(bestDriver->info.name); 1787 } 1788 } else { 1789 // register all drivers that match 1790 void* cookie = NULL; 1791 while (_GetNextDriverPath(cookie, path) == B_OK) { 1792 _RegisterPath(path.Path()); 1793 } 1794 } 1795 1796 return B_OK; 1797 } 1798 1799 1800 void 1801 device_node::_ReleaseWaiting() 1802 { 1803 NodeList::Iterator iterator = fChildren.GetIterator(); 1804 while (iterator.HasNext()) { 1805 device_node* child = iterator.Next(); 1806 1807 child->fFlags &= ~NODE_FLAG_WAITING_FOR_DRIVER; 1808 } 1809 } 1810 1811 1812 status_t 1813 device_node::_RemoveChildren() 1814 { 1815 NodeList::Iterator iterator = fChildren.GetIterator(); 1816 while (iterator.HasNext()) { 1817 device_node* child = iterator.Next(); 1818 child->Release(); 1819 } 1820 1821 return fChildren.IsEmpty() ? B_OK : B_BUSY; 1822 } 1823 1824 1825 device_node* 1826 device_node::_FindCurrentChild() 1827 { 1828 NodeList::Iterator iterator = fChildren.GetIterator(); 1829 while (iterator.HasNext()) { 1830 device_node* child = iterator.Next(); 1831 1832 if ((child->Flags() & NODE_FLAG_WAITING_FOR_DRIVER) == 0) 1833 return child; 1834 } 1835 1836 return NULL; 1837 } 1838 1839 1840 status_t 1841 device_node::_Probe() 1842 { 1843 device_node* previous = NULL; 1844 1845 if (IsProbed() && !fChildren.IsEmpty() 1846 && (fFlags & (B_FIND_CHILD_ON_DEMAND | B_FIND_MULTIPLE_CHILDREN)) 1847 == B_FIND_CHILD_ON_DEMAND) { 1848 // We already have a driver that claims this node; remove all 1849 // (unused) nodes, and evaluate it again 1850 _RemoveChildren(); 1851 1852 previous = _FindCurrentChild(); 1853 if (previous != NULL) { 1854 // This driver is still active - give it back the reference 1855 // that was stolen by _RemoveChildren() - _RegisterDynamic() 1856 // will release it, if it really isn't needed anymore 1857 previous->Acquire(); 1858 } 1859 } 1860 1861 return _RegisterDynamic(previous); 1862 } 1863 1864 1865 status_t 1866 device_node::Probe(const char* devicePath, uint32 updateCycle) 1867 { 1868 if ((fFlags & NODE_FLAG_DEVICE_REMOVED) != 0 1869 || updateCycle == fLastUpdateCycle) 1870 return B_OK; 1871 1872 status_t status = InitDriver(); 1873 if (status < B_OK) 1874 return status; 1875 1876 MethodDeleter<device_node, bool> uninit(this, 1877 &device_node::UninitDriver); 1878 1879 if ((fFlags & B_FIND_CHILD_ON_DEMAND) != 0) { 1880 bool matches = false; 1881 uint16 type = 0; 1882 uint16 subType = 0; 1883 if (get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false) == B_OK 1884 && get_attr_uint16(this, B_DEVICE_TYPE, &type, false) == B_OK) { 1885 // Check if this node matches the device path 1886 // TODO: maybe make this extendible via settings file? 1887 if (!strcmp(devicePath, "disk")) { 1888 matches = type == PCI_mass_storage; 1889 } else if (!strcmp(devicePath, "audio")) { 1890 matches = type == PCI_multimedia 1891 && (subType == PCI_audio || subType == PCI_hd_audio); 1892 } else if (!strcmp(devicePath, "net")) { 1893 matches = type == PCI_network; 1894 } else if (!strcmp(devicePath, "graphics")) { 1895 matches = type == PCI_display; 1896 } else if (!strcmp(devicePath, "video")) { 1897 matches = type == PCI_multimedia && subType == PCI_video; 1898 } 1899 } else { 1900 // This driver does not support types, but still wants to its 1901 // children explored on demand only. 1902 matches = true; 1903 sGenericContextPath = devicePath; 1904 } 1905 1906 if (matches) { 1907 fLastUpdateCycle = updateCycle; 1908 // This node will be probed in this update cycle 1909 1910 status = _Probe(); 1911 1912 sGenericContextPath = NULL; 1913 return status; 1914 } 1915 1916 return B_OK; 1917 } 1918 1919 NodeList::Iterator iterator = fChildren.GetIterator(); 1920 while (iterator.HasNext()) { 1921 device_node* child = iterator.Next(); 1922 1923 status = child->Probe(devicePath, updateCycle); 1924 if (status != B_OK) 1925 return status; 1926 } 1927 1928 return B_OK; 1929 } 1930 1931 1932 status_t 1933 device_node::Reprobe() 1934 { 1935 status_t status = InitDriver(); 1936 if (status < B_OK) 1937 return status; 1938 1939 MethodDeleter<device_node, bool> uninit(this, 1940 &device_node::UninitDriver); 1941 1942 // If this child has been probed already, probe it again 1943 status = _Probe(); 1944 if (status != B_OK) 1945 return status; 1946 1947 NodeList::Iterator iterator = fChildren.GetIterator(); 1948 while (iterator.HasNext()) { 1949 device_node* child = iterator.Next(); 1950 1951 status = child->Reprobe(); 1952 if (status != B_OK) 1953 return status; 1954 } 1955 1956 return B_OK; 1957 } 1958 1959 1960 status_t 1961 device_node::Rescan() 1962 { 1963 status_t status = InitDriver(); 1964 if (status < B_OK) 1965 return status; 1966 1967 MethodDeleter<device_node, bool> uninit(this, 1968 &device_node::UninitDriver); 1969 1970 if (DriverModule()->rescan_child_devices != NULL) { 1971 status = DriverModule()->rescan_child_devices(DriverData()); 1972 if (status != B_OK) 1973 return status; 1974 } 1975 1976 NodeList::Iterator iterator = fChildren.GetIterator(); 1977 while (iterator.HasNext()) { 1978 device_node* child = iterator.Next(); 1979 1980 status = child->Rescan(); 1981 if (status != B_OK) 1982 return status; 1983 } 1984 1985 return B_OK; 1986 } 1987 1988 1989 /*! Uninitializes all temporary references to the driver. The registration 1990 process keeps the driver initialized to optimize the startup procedure; 1991 this function gives this reference away again. 1992 */ 1993 void 1994 device_node::UninitUnusedDriver() 1995 { 1996 // First, we need to go to the leaf, and go back from there 1997 1998 NodeList::Iterator iterator = fChildren.GetIterator(); 1999 while (iterator.HasNext()) { 2000 device_node* child = iterator.Next(); 2001 2002 child->UninitUnusedDriver(); 2003 } 2004 2005 if (!IsInitialized() 2006 || (fFlags & NODE_FLAG_REGISTER_INITIALIZED) == 0) 2007 return; 2008 2009 fFlags &= ~NODE_FLAG_REGISTER_INITIALIZED; 2010 2011 UninitDriver(); 2012 } 2013 2014 2015 /*! Calls device_removed() on this node and all of its children - starting 2016 with the deepest and last child. 2017 It will also remove the one reference that every node gets on its creation. 2018 */ 2019 void 2020 device_node::DeviceRemoved() 2021 { 2022 // notify children 2023 NodeList::ConstIterator iterator = Children().GetIterator(); 2024 while (iterator.HasNext()) { 2025 device_node* child = iterator.Next(); 2026 2027 child->DeviceRemoved(); 2028 } 2029 2030 // notify devices 2031 DeviceList::ConstIterator deviceIterator = Devices().GetIterator(); 2032 while (deviceIterator.HasNext()) { 2033 Device* device = deviceIterator.Next(); 2034 2035 if (device->Module() != NULL 2036 && device->Module()->device_removed != NULL) 2037 device->Module()->device_removed(device->Data()); 2038 } 2039 2040 fFlags |= NODE_FLAG_DEVICE_REMOVED; 2041 2042 if (IsInitialized() && DriverModule()->device_removed != NULL) 2043 DriverModule()->device_removed(this); 2044 2045 if ((fFlags & B_KEEP_DRIVER_LOADED) != 0) { 2046 // There is no point in keeping this driver loaded when its device 2047 // is gone 2048 UninitDriver(); 2049 } 2050 2051 UninitUnusedDriver(); 2052 Release(); 2053 } 2054 2055 2056 void 2057 device_node::Acquire() 2058 { 2059 atomic_add(&fRefCount, 1); 2060 } 2061 2062 2063 bool 2064 device_node::Release() 2065 { 2066 if (atomic_add(&fRefCount, -1) > 1) 2067 return false; 2068 2069 delete this; 2070 return true; 2071 } 2072 2073 2074 void 2075 device_node::AddDevice(Device* device) 2076 { 2077 fDevices.Add(device); 2078 } 2079 2080 2081 void 2082 device_node::RemoveDevice(Device* device) 2083 { 2084 fDevices.Remove(device); 2085 } 2086 2087 2088 int 2089 device_node::CompareTo(const device_attr* attributes) const 2090 { 2091 if (attributes == NULL) 2092 return -1; 2093 2094 for (; attributes->name != NULL; attributes++) { 2095 // find corresponding attribute 2096 AttributeList::ConstIterator iterator = Attributes().GetIterator(); 2097 device_attr_private* attr = NULL; 2098 bool found = false; 2099 2100 while (iterator.HasNext()) { 2101 attr = iterator.Next(); 2102 2103 if (!strcmp(attr->name, attributes->name)) { 2104 found = true; 2105 break; 2106 } 2107 } 2108 if (!found) 2109 return -1; 2110 2111 int compare = device_attr_private::Compare(attr, attributes); 2112 if (compare != 0) 2113 return compare; 2114 } 2115 2116 return 0; 2117 } 2118 2119 2120 device_node* 2121 device_node::FindChild(const device_attr* attributes) const 2122 { 2123 if (attributes == NULL) 2124 return NULL; 2125 2126 NodeList::ConstIterator iterator = Children().GetIterator(); 2127 while (iterator.HasNext()) { 2128 device_node* child = iterator.Next(); 2129 2130 // ignore nodes that are pending to be removed 2131 if ((child->Flags() & NODE_FLAG_DEVICE_REMOVED) == 0 2132 && !child->CompareTo(attributes)) 2133 return child; 2134 } 2135 2136 return NULL; 2137 } 2138 2139 2140 device_node* 2141 device_node::FindChild(const char* moduleName) const 2142 { 2143 if (moduleName == NULL) 2144 return NULL; 2145 2146 NodeList::ConstIterator iterator = Children().GetIterator(); 2147 while (iterator.HasNext()) { 2148 device_node* child = iterator.Next(); 2149 2150 if (!strcmp(child->ModuleName(), moduleName)) 2151 return child; 2152 } 2153 2154 return NULL; 2155 } 2156 2157 2158 /*! This returns the priority or importance of this node. Nodes with higher 2159 priority are registered/probed first. 2160 Currently, only the B_FIND_MULTIPLE_CHILDREN flag alters the priority; 2161 it might make sense to be able to directly set the priority via an 2162 attribute. 2163 */ 2164 int32 2165 device_node::Priority() 2166 { 2167 return (fFlags & B_FIND_MULTIPLE_CHILDREN) != 0 ? 0 : 100; 2168 } 2169 2170 2171 void 2172 device_node::Dump(int32 level) 2173 { 2174 put_level(level); 2175 kprintf("(%" B_PRId32 ") @%p \"%s\" (ref %" B_PRId32 ", init %" B_PRId32 2176 ", module %p, data %p)\n", level, this, ModuleName(), fRefCount, 2177 fInitialized, DriverModule(), DriverData()); 2178 2179 AttributeList::Iterator attribute = Attributes().GetIterator(); 2180 while (attribute.HasNext()) { 2181 dump_attribute(attribute.Next(), level); 2182 } 2183 2184 DeviceList::Iterator deviceIterator = fDevices.GetIterator(); 2185 while (deviceIterator.HasNext()) { 2186 Device* device = deviceIterator.Next(); 2187 put_level(level); 2188 kprintf("device: %s, %p\n", device->ModuleName(), device->Data()); 2189 } 2190 2191 NodeList::ConstIterator iterator = Children().GetIterator(); 2192 while (iterator.HasNext()) { 2193 iterator.Next()->Dump(level + 1); 2194 } 2195 } 2196 2197 2198 // #pragma mark - root node 2199 2200 2201 static void 2202 init_node_tree(void) 2203 { 2204 device_attr attrs[] = { 2205 {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "Devices Root"}}, 2206 {B_DEVICE_BUS, B_STRING_TYPE, {string: "root"}}, 2207 {B_DEVICE_FLAGS, B_UINT32_TYPE, 2208 {ui32: B_FIND_MULTIPLE_CHILDREN | B_KEEP_DRIVER_LOADED }}, 2209 {NULL} 2210 }; 2211 2212 device_node* node = NULL; 2213 if (register_node(NULL, DEVICE_MANAGER_ROOT_NAME, attrs, NULL, &node) 2214 != B_OK) { 2215 dprintf("Cannot register Devices Root Node\n"); 2216 } 2217 2218 device_attr genericAttrs[] = { 2219 {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "Generic"}}, 2220 {B_DEVICE_BUS, B_STRING_TYPE, {string: "generic"}}, 2221 {B_DEVICE_FLAGS, B_UINT32_TYPE, {ui32: B_FIND_MULTIPLE_CHILDREN 2222 | B_KEEP_DRIVER_LOADED | B_FIND_CHILD_ON_DEMAND}}, 2223 {NULL} 2224 }; 2225 2226 if (register_node(node, DEVICE_MANAGER_GENERIC_NAME, genericAttrs, NULL, 2227 NULL) != B_OK) { 2228 dprintf("Cannot register Generic Devices Node\n"); 2229 } 2230 } 2231 2232 2233 driver_module_info gDeviceRootModule = { 2234 { 2235 DEVICE_MANAGER_ROOT_NAME, 2236 0, 2237 NULL, 2238 }, 2239 }; 2240 2241 2242 driver_module_info gDeviceGenericModule = { 2243 { 2244 DEVICE_MANAGER_GENERIC_NAME, 2245 0, 2246 NULL, 2247 }, 2248 NULL 2249 }; 2250 2251 2252 // #pragma mark - private kernel API 2253 2254 2255 status_t 2256 device_manager_probe(const char* path, uint32 updateCycle) 2257 { 2258 TRACE(("device_manager_probe(\"%s\")\n", path)); 2259 RecursiveLocker _(sLock); 2260 2261 // first, publish directories in the driver directory 2262 publish_directories(path); 2263 2264 return sRootNode->Probe(path, updateCycle); 2265 } 2266 2267 2268 status_t 2269 device_manager_init(struct kernel_args* args) 2270 { 2271 TRACE(("device manager init\n")); 2272 2273 IOSchedulerRoster::Init(); 2274 2275 dm_init_id_generator(); 2276 dm_init_io_resources(); 2277 2278 recursive_lock_init(&sLock, "device manager"); 2279 2280 register_generic_syscall(DEVICE_MANAGER_SYSCALLS, control_device_manager, 2281 1, 0); 2282 2283 add_debugger_command("dm_tree", &dump_device_nodes, 2284 "dump device node tree"); 2285 add_debugger_command_etc("io_scheduler", &dump_io_scheduler, 2286 "Dump an I/O scheduler", 2287 "<scheduler>\n" 2288 "Dumps I/O scheduler at address <scheduler>.\n", 0); 2289 add_debugger_command_etc("io_request_owner", &dump_io_request_owner, 2290 "Dump an I/O request owner", 2291 "<owner>\n" 2292 "Dumps I/O request owner at address <owner>.\n", 0); 2293 add_debugger_command("io_request", &dump_io_request, "dump an I/O request"); 2294 add_debugger_command("io_operation", &dump_io_operation, 2295 "dump an I/O operation"); 2296 add_debugger_command("io_buffer", &dump_io_buffer, "dump an I/O buffer"); 2297 add_debugger_command("dma_buffer", &dump_dma_buffer, "dump a DMA buffer"); 2298 2299 init_node_tree(); 2300 2301 return B_OK; 2302 } 2303 2304 2305 status_t 2306 device_manager_init_post_modules(struct kernel_args* args) 2307 { 2308 RecursiveLocker _(sLock); 2309 return sRootNode->Reprobe(); 2310 } 2311