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