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