354f402040599adf19d4929df25907bfc2f6d0b9
[tpg/acess2.git] / KernelLand / Kernel / vfs / fs / devfs.c
1 /*
2  * Acess 2
3  * Device Filesystem (DevFS)
4  * - vfs/fs/devfs.c
5  */
6 #define DEBUG   0
7 #include <acess.h>
8 #include <vfs.h>
9 #include <fs_devfs.h>
10
11 // === PROTOTYPES ===
12 #if 0
13  int    DevFS_AddDevice(tDevFS_Driver *Device);
14 void    DevFS_DelDevice(tDevFS_Driver *Device);
15 #endif
16 tVFS_Node       *DevFS_InitDevice(const char *Device, const char **Options);
17 void    DevFS_Unmount(tVFS_Node *RootNode);
18 char    *DevFS_ReadDir(tVFS_Node *Node, int Pos);
19 tVFS_Node       *DevFS_FindDir(tVFS_Node *Node, const char *Name);
20
21 // === GLOBALS ===
22 tVFS_Driver     gDevFS_Info = {
23         "devfs", 0, DevFS_InitDevice, DevFS_Unmount, NULL
24         };
25 tVFS_NodeType   gDevFS_DirType = {
26         .TypeName = "DevFS-Dir",
27         .ReadDir = DevFS_ReadDir,
28         .FindDir = DevFS_FindDir
29         };
30 tVFS_Node       gDevFS_RootNode = {
31         .Size = 0,
32         .Flags = VFS_FFLAG_DIRECTORY,
33         .NumACLs = 1,
34         .ACLs = &gVFS_ACL_EveryoneRX,
35         .Type = &gDevFS_DirType
36         };
37 tDevFS_Driver   *gDevFS_Drivers = NULL;
38  int    giDevFS_NextID = 1;
39 tShortSpinlock  glDevFS_ListLock;
40
41 // === CODE ===
42 /**
43  * \fn int DevFS_AddDevice(tDevFS_Driver *Device)
44  */
45 int DevFS_AddDevice(tDevFS_Driver *Device)
46 {
47          int    ret = 0;
48         tDevFS_Driver   *dev;
49
50         ENTER("pDevice", Device);
51         LOG("Device->Name = '%s'", Device->Name);
52         
53         SHORTLOCK( &glDevFS_ListLock );
54         
55         // Check if the device is already registered or the name is taken
56         for( dev = gDevFS_Drivers; dev; dev = dev->Next )
57         {
58                 if(dev == Device)       break;
59                 if(strcmp(dev->Name, Device->Name) == 0)        break;
60         }
61         
62         if(dev) {
63                 if(dev == Device)
64                         Log_Warning("DevFS", "Device %p '%s' attempted to register itself twice",
65                                 dev, dev->Name);
66                 else
67                         Log_Warning("DevFS", "Device %p attempted to register '%s' which was owned by %p",
68                                 Device, dev->Name, dev);
69                 ret = -1;       // Error
70         }
71         else {
72                 Device->Next = gDevFS_Drivers;
73                 gDevFS_Drivers = Device;
74                 gDevFS_RootNode.Size ++;
75                 ret = giDevFS_NextID ++;
76         }
77         SHORTREL( &glDevFS_ListLock );
78         
79         LEAVE('i', ret);
80         return ret;
81 }
82
83 /**
84  * \brief Delete a device from the DevFS folder
85  */
86 void DevFS_DelDevice(tDevFS_Driver *Device)
87 {
88         tDevFS_Driver   *prev = NULL, *dev;
89         
90         SHORTLOCK( &glDevFS_ListLock );
91         // Search list for device
92         for(dev = gDevFS_Drivers;
93                 dev && dev != Device;
94                 prev = dev, dev = dev->Next
95                 );
96         
97         // Check if it was found
98         if(dev)
99         {
100                 if(prev)
101                         prev->Next = Device->Next;
102                 else
103                         gDevFS_Drivers = Device->Next;
104         }
105         else
106                 Log_Warning("DevFS", "Attempted to unregister device %p '%s' which was not registered",
107                         Device, Device->Name);
108         
109         SHORTREL( &glDevFS_ListLock );
110 }
111
112 /**
113  * \brief Initialise the DevFS and detect double-mounting, or just do nothing
114  * \note STUB
115  */
116 tVFS_Node *DevFS_InitDevice(const char *Device, const char **Options)
117 {
118         return &gDevFS_RootNode;
119 }
120
121 void DevFS_Unmount(tVFS_Node *RootNode)
122 {
123         
124 }
125
126 /**
127  * \fn char *DevFS_ReadDir(tVFS_Node *Node, int Pos)
128  */
129 char *DevFS_ReadDir(tVFS_Node *Node, int Pos)
130 {
131         tDevFS_Driver   *dev;
132         
133         if(Pos < 0)     return NULL;
134         
135         for(dev = gDevFS_Drivers;
136                 dev && Pos--;
137                 dev = dev->Next
138                 );
139         
140         if(dev)
141                 return strdup(dev->Name);
142         else
143                 return NULL;
144 }
145
146 /**
147  * \fn tVFS_Node *DevFS_FindDir(tVFS_Node *Node, const char *Name)
148  * \brief Get an entry from the devices directory
149  */
150 tVFS_Node *DevFS_FindDir(tVFS_Node *Node, const char *Name)
151 {
152         tDevFS_Driver   *dev;
153         
154         ENTER("pNode sName", Node, Name);
155         
156         for(dev = gDevFS_Drivers;
157                 dev;
158                 dev = dev->Next
159                 )
160         {
161                 //LOG("dev = %p", dev);
162                 LOG("dev->Name = '%s'", dev->Name);
163                 if(strcmp(dev->Name, Name) == 0) {
164                         LEAVE('p', &dev->RootNode);
165                         return &dev->RootNode;
166                 }
167         }
168         
169         LEAVE('n');
170         return NULL;
171 }
172
173 // --- EXPORTS ---
174 EXPORT(DevFS_AddDevice);
175 EXPORT(DevFS_DelDevice);

UCC git Repository :: git.ucc.asn.au