Changeset 25453

Show
Ignore:
Timestamp:
05/11/08 12:00:07 (5 days ago)
Author:
axeld
Message:
More work-in-progress:
* Added a generic (for all devices) and specific (for a specific device) video
  driver to be able to play with the replace mechanism (which is not yet done,
  but works well for the one usage case tested).
* Added reference counting and initialize counting: now, each node owns a
  reference of its parent, and each initialized node owns an initialization
  reference of its parent.
* Added locking.
* Moved dump functionality into a member function.
* The same node can now only added once - ie. if a bus tries to register the
  same device twice, it will fail.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • haiku/trunk/src/tests/system/kernel/device_manager/playground/bus.cpp

    r25394 r25453  
    7272                {0x1000, 0x0001, PCI_mass_storage, PCI_sata, PCI_sata_ahci}, 
    7373                {0x1001, 0x0001, PCI_network, PCI_ethernet, 0}, 
     74                {0x1001, 0x0002, PCI_display, 0, 0}, 
    7475                {0x1002, 0x0001, PCI_multimedia, PCI_audio, 0}, 
    7576                {0x1002, 0x0002, PCI_serial_bus, PCI_usb, PCI_usb_ehci}, 
  • haiku/trunk/src/tests/system/kernel/device_manager/playground/device_manager.cpp

    r25406 r25453  
    3030extern struct device_module_info gDeviceModuleInfo; 
    3131extern struct driver_module_info gDriverModuleInfo; 
     32extern struct device_module_info gGenericVideoDeviceModuleInfo; 
     33extern struct driver_module_info gGenericVideoDriverModuleInfo; 
     34extern struct device_module_info gSpecificVideoDeviceModuleInfo; 
     35extern struct driver_module_info gSpecificVideoDriverModuleInfo; 
    3236extern struct driver_module_info gBusModuleInfo; 
    3337extern struct driver_module_info gBusDriverModuleInfo; 
     
    113117                        bool                    IsRegistered() const { return fRegistered; } 
    114118                        bool                    IsInitialized() const { return fInitialized > 0; } 
     119 
     120                        void                    Acquire(); 
     121                        bool                    Release(); 
     122 
     123                        int                             CompareTo(const device_attr* attributes) const; 
     124                        device_node*    FindChild(const device_attr* attributes) const; 
     125 
     126                        void                    Dump(int32 level = 0); 
    115127 
    116128private: 
     
    362374 
    363375 
    364 void 
    365 dm_dump_node(device_node* node, int32 level) 
    366 { 
    367         if (node == NULL) 
    368                 return; 
    369  
    370         put_level(level); 
    371         dprintf("(%ld) @%p \"%s\"\n", level, node, node->ModuleName()); 
    372          
    373         AttributeList::Iterator attribute = node->Attributes().GetIterator(); 
    374         while (attribute.HasNext()) { 
    375                 dump_attribute(attribute.Next(), level); 
    376         } 
    377  
    378         NodeList::ConstIterator iterator = node->Children().GetIterator(); 
    379         while (iterator.HasNext()) { 
    380                 dm_dump_node(iterator.Next(), level + 1); 
    381         } 
    382 } 
    383  
    384  
    385376static void 
    386377uninit_unused() 
     
    435426device_node::~device_node() 
    436427{ 
     428        TRACE(("delete node %p\n", this)); 
     429 
    437430        // Delete children 
    438431        NodeList::Iterator nodeIterator = fChildren.GetIterator(); 
     
    465458device_node::InitDriver() 
    466459{ 
    467         if (fInitialized++ > 0) 
     460        if (fInitialized++ > 0) { 
     461                if (Parent() != NULL) { 
     462                        Parent()->InitDriver(); 
     463                                // acquire another reference to our parent as well 
     464                } 
     465                Acquire(); 
    468466                return B_OK; 
     467        } 
    469468 
    470469        status_t status = get_module(ModuleName(), (module_info**)&fDriver); 
     470        if (status == B_OK && Parent() != NULL) { 
     471                // our parent always have to be initialized 
     472                status = Parent()->InitDriver(); 
     473        } 
    471474        if (status < B_OK) { 
    472475                fInitialized--; 
     
    476479        if (fDriver->init_driver != NULL) 
    477480                status = fDriver->init_driver(this, &fDriverData); 
     481 
    478482        if (status < B_OK) { 
    479483                fInitialized--; 
     484 
    480485                put_module(ModuleName()); 
     486                fDriver = NULL; 
     487                fDriverData = NULL; 
    481488                return status; 
    482489        } 
    483490 
     491        Acquire(); 
    484492        return B_OK; 
    485493} 
     
    489497device_node::UninitDriver() 
    490498{ 
    491         if (fInitialized-- > 1) 
     499        if (fInitialized-- > 1) { 
     500                Release(); 
    492501                return false; 
     502        } 
     503        TRACE(("uninit driver for node %p\n", this)); 
    493504 
    494505        if (fDriver->uninit_driver != NULL) 
     
    500511        put_module(ModuleName()); 
    501512 
     513        Release(); 
     514        if (Parent() != NULL) 
     515                Parent()->UninitDriver(); 
     516 
    502517        if ((fFlags & NODE_FLAG_REMOVE_ON_UNINIT) != 0) 
    503                 delete this
     518                Release()
    504519 
    505520        return true; 
     
    511526{ 
    512527        // we must not be destroyed     as long as we have children 
    513         fRefCount++
     528        Acquire()
    514529        node->fParent = this; 
    515530        fChildren.Add(node); 
     
    520535device_node::RemoveChild(device_node* node) 
    521536{ 
    522         fRefCount--; 
    523                 // TODO: we may need to destruct ourselves here! 
    524537        node->fParent = NULL; 
    525538        fChildren.Remove(node); 
     539        Release(); 
    526540} 
    527541 
     
    785799                float support = driver->supports_device(this); 
    786800                if (support > 0.0) { 
    787 printf("  register module \"%s\", support %f\n", driver->info.name, support); 
     801                        TRACE(("  register module \"%s\", support %f\n", driver->info.name, 
     802                                support)); 
    788803                        if (driver->register_device(this) == B_OK) 
    789804                                count++; 
     
    836851 
    837852                if (bestDriver != NULL) { 
    838 printf("  register best module \"%s\", support %f\n", bestDriver->info.name, bestSupport); 
     853                        TRACE(("  register best module \"%s\", support %f\n", 
     854                                bestDriver->info.name, bestSupport)); 
    839855                        bestDriver->register_device(this); 
    840856                        put_module(bestDriver->info.name); 
     
    862878                        // this child is not used currently, and can be removed safely 
    863879                        iterator.Remove(); 
    864                         fRefCount--; 
    865880                        child->fParent = NULL; 
    866881                        delete child; 
     882                        if (Release()) 
     883                                panic("died early"); 
    867884                } else 
    868885                        child->fFlags |= NODE_FLAG_REMOVE_ON_UNINIT; 
     
    876893device_node::Probe(const char* devicePath) 
    877894{ 
     895        status_t status = InitDriver(); 
     896        if (status < B_OK) 
     897                return status; 
     898 
     899        MethodDeleter<device_node, bool> uninit(this, &device_node::UninitDriver); 
     900 
    878901        uint16 type = 0; 
    879902        uint16 subType = 0; 
     
    918941                device_node* child = iterator.Next(); 
    919942                 
    920                 status_t status = child->Probe(devicePath); 
     943                status = child->Probe(devicePath); 
    921944                if (status != B_OK) 
    922945                        return status; 
     
    963986{ 
    964987        _UninitUnusedChildren(); 
     988} 
     989 
     990 
     991void 
     992device_node::Acquire() 
     993{ 
     994        atomic_add(&fRefCount, 1); 
     995} 
     996 
     997 
     998bool 
     999device_node::Release() 
     1000{ 
     1001        if (atomic_add(&fRefCount, -1) > 1) 
     1002                return false; 
     1003 
     1004        if (Parent() != NULL) 
     1005                Parent()->RemoveChild(this); 
     1006        delete this; 
     1007        return true; 
     1008} 
     1009 
     1010 
     1011int 
     1012device_node::CompareTo(const device_attr* attributes) const 
     1013{ 
     1014        if (attributes == NULL) 
     1015                return -1; 
     1016 
     1017        for (; attributes->name != NULL; attributes++) { 
     1018                // find corresponding attribute 
     1019                AttributeList::ConstIterator iterator = Attributes().GetIterator(); 
     1020                device_attr_private* attr = NULL; 
     1021                while (iterator.HasNext()) { 
     1022                        attr = iterator.Next(); 
     1023 
     1024                        if (!strcmp(attr->name, attributes->name)) 
     1025                                break; 
     1026                } 
     1027                if (!iterator.HasNext()) 
     1028                        return -1; 
     1029 
     1030                int compare = device_attr_private::Compare(attr, attributes); 
     1031                if (compare != 0) 
     1032                        return compare; 
     1033        } 
     1034 
     1035        return 0; 
     1036} 
     1037 
     1038 
     1039device_node* 
     1040device_node::FindChild(const device_attr* attributes) const 
     1041{ 
     1042        if (attributes == NULL) 
     1043                return NULL; 
     1044 
     1045        NodeList::ConstIterator iterator = Children().GetIterator(); 
     1046        while (iterator.HasNext()) { 
     1047                device_node* child = iterator.Next(); 
     1048 
     1049                if (!child->CompareTo(attributes)) 
     1050                        return child; 
     1051        } 
     1052 
     1053        return NULL; 
     1054} 
     1055 
     1056 
     1057void 
     1058device_node::Dump(int32 level = 0) 
     1059{ 
     1060        put_level(level); 
     1061        dprintf("(%ld) @%p \"%s\" (ref %ld, init %ld)\n", level, this, ModuleName(), 
     1062                fRefCount, fInitialized); 
     1063 
     1064        AttributeList::Iterator attribute = Attributes().GetIterator(); 
     1065        while (attribute.HasNext()) { 
     1066                dump_attribute(attribute.Next(), level); 
     1067        } 
     1068 
     1069        NodeList::ConstIterator iterator = Children().GetIterator(); 
     1070        while (iterator.HasNext()) { 
     1071                iterator.Next()->Dump(level + 1); 
     1072        } 
    9651073} 
    9661074 
     
    9841092                return B_BAD_VALUE; 
    9851093 
     1094        if (parent != NULL && parent->FindChild(attrs) != NULL) { 
     1095                // A node like this one already exists for this parent 
     1096                return B_NAME_IN_USE; 
     1097        } 
     1098 
    9861099        // TODO: handle I/O resources! 
    9871100 
     
    9971110 
    9981111        status_t status = newNode->InitCheck(); 
    999         if (status != B_OK) 
    1000                 goto err1; 
    1001  
    1002         status = newNode->InitDriver(); 
    10031112        if (status != B_OK) 
    10041113                goto err1; 
     
    10091118        else 
    10101119                sRootNode = newNode; 
     1120 
     1121        status = newNode->InitDriver(); 
     1122        if (status != B_OK) 
     1123                goto err1; 
    10111124 
    10121125#if 0 
     
    10641177 
    10651178static device_node* 
    1066 device_root(void) 
    1067 
     1179get_device_root(void) 
     1180
     1181        if (sRootNode != NULL) 
     1182                sRootNode->Acquire(); 
     1183 
    10681184        return sRootNode; 
    10691185} 
     
    10811197get_parent(device_node* node) 
    10821198{ 
    1083         return NULL; 
     1199        if (node == NULL) 
     1200                return NULL; 
     1201 
     1202        RecursiveLocker _(sLock); 
     1203 
     1204        device_node* parent = node->Parent(); 
     1205        parent->Acquire(); 
     1206 
     1207        return parent; 
    10841208} 
    10851209 
     
    10881212put_device_node(device_node* node) 
    10891213{ 
     1214        RecursiveLocker _(sLock); 
     1215        node->Release(); 
    10901216} 
    10911217 
     
    12301356        unregister_device, 
    12311357        get_driver, 
    1232         device_root, 
     1358        get_device_root, 
    12331359        get_next_child_device, 
    12341360        get_parent, 
     
    12851411        _add_builtin_module((module_info*)&sDeviceManagerModule); 
    12861412        _add_builtin_module((module_info*)&sDeviceRootModule); 
    1287         _add_builtin_module((module_info*)&gDeviceModuleInfo); 
    1288         _add_builtin_module((module_info*)&gDriverModuleInfo); 
     1413 
     1414        // bus 
    12891415        _add_builtin_module((module_info*)&gBusModuleInfo); 
    12901416        _add_builtin_module((module_info*)&gBusDriverModuleInfo); 
     1417 
     1418        // sample driver 
     1419        _add_builtin_module((module_info*)&gDriverModuleInfo); 
     1420        _add_builtin_module((module_info*)&gDeviceModuleInfo); 
     1421 
     1422        // generic video driver 
     1423        _add_builtin_module((module_info*)&gGenericVideoDriverModuleInfo); 
     1424        _add_builtin_module((module_info*)&gGenericVideoDeviceModuleInfo); 
    12911425 
    12921426        gDeviceManager = &sDeviceManagerModule; 
     
    13021436 
    13031437        dm_init_root_node(); 
    1304         dm_dump_node(sRootNode, 0); 
     1438        sRootNode->Dump(); 
    13051439 
    13061440        probe_path("net"); 
     1441        probe_path("graphics"); 
     1442        // TODO: opened devices need to keep a "initialized" reference of the 
     1443        // device_node 
     1444 
     1445        sRootNode->Dump(); 
     1446        uninit_unused(); 
     1447 
     1448        // add specific video driver - ie. simulate installing it 
     1449        _add_builtin_module((module_info*)&gSpecificVideoDriverModuleInfo); 
     1450        _add_builtin_module((module_info*)&gSpecificVideoDeviceModuleInfo); 
     1451        probe_path("graphics"); 
     1452 
    13071453        uninit_unused(); 
    13081454 
  • haiku/trunk/src/tests/system/kernel/device_manager/playground/device_manager.h

    r25406 r25453  
    7373                                        void **_cookie); 
    7474 
    75         device_node *(*root_device)(); 
     75        device_node *(*get_root_device)(); 
    7676        status_t (*get_next_child_device)(device_node *parent, device_node *node, 
    7777                                        const device_attr *attrs); 
  • haiku/trunk/src/tests/system/kernel/device_manager/playground/driver.cpp

    r25394 r25453  
    160160                NULL, 
    161161        }, 
    162          
     162 
    163163        supports_device, 
    164164        register_device, 
  • haiku/trunk/src/tests/system/kernel/device_manager/playground/Jamfile

    r25383 r25453  
    1313        bus.cpp 
    1414        driver.cpp 
     15        generic_video_driver.cpp 
     16        specific_video_driver.cpp 
    1517 
    1618        : be libkernelland_emu.so