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