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