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