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

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