3 * Device Filesystem (DevFS)
13 int DevFS_AddDevice(tDevFS_Driver *Device);
14 void DevFS_DelDevice(tDevFS_Driver *Device);
16 tVFS_Node *DevFS_InitDevice(const char *Device, const char **Options);
17 void DevFS_Unmount(tVFS_Node *RootNode);
18 int DevFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
19 tVFS_Node *DevFS_FindDir(tVFS_Node *Node, const char *Name, Uint Flags);
22 tVFS_Driver gDevFS_Info = {
24 .InitDevice = DevFS_InitDevice,
25 .Unmount = DevFS_Unmount
27 tVFS_NodeType gDevFS_DirType = {
28 .TypeName = "DevFS-Dir",
29 .ReadDir = DevFS_ReadDir,
30 .FindDir = DevFS_FindDir
32 tVFS_Node gDevFS_RootNode = {
34 .Flags = VFS_FFLAG_DIRECTORY,
36 .ACLs = &gVFS_ACL_EveryoneRX,
37 .Type = &gDevFS_DirType
39 tDevFS_Driver *gDevFS_Drivers = NULL;
40 int giDevFS_NextID = 1;
41 tShortSpinlock glDevFS_ListLock;
45 * \fn int DevFS_AddDevice(tDevFS_Driver *Device)
47 int DevFS_AddDevice(tDevFS_Driver *Device)
52 ENTER("pDevice", Device);
53 LOG("Device->Name = '%s'", Device->Name);
55 SHORTLOCK( &glDevFS_ListLock );
57 // Check if the device is already registered or the name is taken
58 for( dev = gDevFS_Drivers; dev; dev = dev->Next )
60 if(dev == Device) break;
61 if(strcmp(dev->Name, Device->Name) == 0) break;
66 Log_Warning("DevFS", "Device %p '%s' attempted to register itself twice",
69 Log_Warning("DevFS", "Device %p attempted to register '%s' which was owned by %p",
70 Device, dev->Name, dev);
74 Device->Next = gDevFS_Drivers;
75 gDevFS_Drivers = Device;
76 gDevFS_RootNode.Size ++;
77 ret = giDevFS_NextID ++;
79 SHORTREL( &glDevFS_ListLock );
86 * \brief Delete a device from the DevFS folder
88 void DevFS_DelDevice(tDevFS_Driver *Device)
90 tDevFS_Driver *prev = NULL, *dev;
92 SHORTLOCK( &glDevFS_ListLock );
93 // Search list for device
94 for(dev = gDevFS_Drivers;
96 prev = dev, dev = dev->Next
99 // Check if it was found
103 prev->Next = Device->Next;
105 gDevFS_Drivers = Device->Next;
108 Log_Warning("DevFS", "Attempted to unregister device %p '%s' which was not registered",
109 Device, Device->Name);
111 SHORTREL( &glDevFS_ListLock );
115 * \brief Initialise the DevFS and detect double-mounting, or just do nothing
118 tVFS_Node *DevFS_InitDevice(const char *Device, const char **Options)
120 return &gDevFS_RootNode;
123 void DevFS_Unmount(tVFS_Node *RootNode)
129 * \fn char *DevFS_ReadDir(tVFS_Node *Node, int Pos)
131 int DevFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
135 if(Pos < 0) return -EINVAL;
137 for(dev = gDevFS_Drivers;
143 strncpy(Dest, dev->Name, FILENAME_MAX);
152 * \fn tVFS_Node *DevFS_FindDir(tVFS_Node *Node, const char *Name)
153 * \brief Get an entry from the devices directory
155 tVFS_Node *DevFS_FindDir(tVFS_Node *Node, const char *Name, Uint Flags)
159 ENTER("pNode sName", Node, Name);
161 for(dev = gDevFS_Drivers;
166 //LOG("dev = %p", dev);
167 LOG("dev->Name = '%s'", dev->Name);
168 if(strcmp(dev->Name, Name) == 0) {
169 LEAVE('p', &dev->RootNode);
170 return &dev->RootNode;
179 EXPORT(DevFS_AddDevice);
180 EXPORT(DevFS_DelDevice);