OBJ += heap.o logging.o debug.o lib.o libc.o adt.o time.o
OBJ += drvutil_video.o drvutil_disk.o
OBJ += messages.o modules.o syscalls.o system.o
-OBJ += threads.o mutex.o semaphore.o workqueue.o events.o
+OBJ += threads.o mutex.o semaphore.o workqueue.o events.o rwlock.o
OBJ += drv/proc.o drv/fifo.o drv/iocache.o drv/pci.o
OBJ += drv/vterm.o drv/vterm_font.o drv/vterm_vt100.o drv/vterm_output.o drv/vterm_input.o drv/vterm_termbuf.o
OBJ += binary.o bin/elf.o bin/pe.o
struct sModule *Next; //!< Next module in list (not to be touched by the driver)
const char *Name; //!< Module Name/Identifier
int (*Init)(char **Arguments); //!< Module initialiser / entrypoint
- void (*Deinit)(void); //!< Cleanup Function
+ int (*Deinit)(void); //!< Cleanup Function
const char **Dependencies; //!< NULL terminated list of dependencies
} PACKED tModule;
THREAD_STAT_ACTIVE, // Running and schedulable process
THREAD_STAT_SLEEPING, // Message Sleep
THREAD_STAT_MUTEXSLEEP, // Mutex Sleep
+ THREAD_STAT_RWLOCKSLEEP, // Read-Writer lock Sleep
THREAD_STAT_SEMAPHORESLEEP, // Semaphore Sleep
THREAD_STAT_QUEUESLEEP, // Queue
THREAD_STAT_EVENTSLEEP, // Event sleep
\r
// === PROTOTYPES ===\r
int Ext2_Install(char **Arguments);\r
-void Ext2_Cleanup(void);\r
+ int Ext2_Cleanup(void);\r
// - Interface Functions\r
tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options);\r
void Ext2_Unmount(tVFS_Node *Node);\r
/**\r
* \brief Clean up driver state before unload\r
*/\r
-void Ext2_Cleanup(void)\r
+int Ext2_Cleanup(void)\r
{\r
- \r
+ return 0;\r
}\r
\r
/**\r
\r
if(bs->bps == 0 || bs->spc == 0) {\r
Log_Notice("FAT", "Error in FAT Boot Sector (zero BPS/SPC)");\r
+ VFS_Close(diskInfo->fileHandle);\r
return NULL;\r
}\r
\r
diskInfo->FATCache = (Uint32*)malloc(sizeof(Uint32)*diskInfo->ClusterCount);\r
if(diskInfo->FATCache == NULL) {\r
Log_Warning("FAT", "Heap Exhausted");\r
+ VFS_Cose(diskInfo->fileHandle);\r
return NULL;\r
}\r
Ofs = bs->resvSectCount*512;\r
// === PROTOTYPES ===
int Keyboard_Install(char **Arguments);
-void Keyboard_Cleanup(void);
+ int Keyboard_Cleanup(void);
// - Internal
tKeymap *Keyboard_LoadMap(const char *Name);
void Keyboard_FreeMap(tKeymap *Keymap);
/**
* \brief Pre-unload cleanup function
*/
-void Keyboard_Cleanup(void)
+int Keyboard_Cleanup(void)
{
// TODO: Do I need this?
+ return 0;
}
// --- Map Management ---
// === PROTOTYPES ===
int Mouse_Install(char **Arguments);
-void Mouse_Cleanup(void);
+ int Mouse_Cleanup(void);
// - "User" side
char *Mouse_Root_ReadDir(tVFS_Node *Node, int Pos);
tVFS_Node *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name);
/**
* \brief Pre-unload cleanup function
*/
-void Mouse_Cleanup(void)
+int Mouse_Cleanup(void)
{
+ return 0;
}
// --- VFS Interface ---
{
const char *Name;
- int (*Read)(void *, Uint64, size_t, void *);
- int (*Write)(void *, Uint64, size_t, const void *);
+ int (*Read)(void *, Uint64, size_t, void *);
+ int (*Write)(void *, Uint64, size_t, const void *);
+ void (*Cleanup)(void *);
};
* lvm.h
* - LVM Core definitions
*/
-#define DEBUG 0
+#define DEBUG 1
#define VERSION VER2(0,1)
#include "lvm_int.h"
#include <fs_devfs.h>
// === PROTOTYPES ===
// ---
int LVM_Initialise(char **Arguments);
-void LVM_Cleanup(void);
+ int LVM_Cleanup(void);
// ---
char *LVM_Root_ReadDir(tVFS_Node *Node, int ID);
tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name);
return 0;
}
-void LVM_Cleanup(void)
+int LVM_Cleanup(void)
{
+ // Attempt to destroy all volumes
+ tLVM_Vol *vol, *prev = NULL, *next;
+ // TODO: Locks?
+ for( vol = gpLVM_FirstVolume; vol; prev = vol, vol = next )
+ {
+ next = vol->Next;
+ int nFree = 0;
+
+ for( int i = 0; i < vol->nSubVolumes; i ++ )
+ {
+ tLVM_SubVolume *sv;
+ sv = vol->SubVolumes[i];
+ if( sv == NULL ) {
+ nFree ++;
+ continue;
+ }
+
+ Mutex_Acquire(&sv->Node.Lock);
+ if(sv->Node.ReferenceCount == 0) {
+ nFree ++;
+ vol->SubVolumes[i] = NULL;
+ }
+ Mutex_Release(&sv->Node.Lock);
+
+ Mutex_Acquire(&sv->Node.Lock);
+ LOG("Removed subvolume %s:%s", vol->Name, sv->Name);
+ free(sv);
+ }
+
+ if( nFree != vol->nSubVolumes )
+ continue ;
+
+ if(prev)
+ prev->Next = next;
+ else
+ gpLVM_FirstVolume = next;
+
+ Mutex_Acquire(&vol->DirNode.Lock);
+ Mutex_Acquire(&vol->VolNode.Lock);
+ if( vol->Type->Cleanup )
+ vol->Type->Cleanup( vol->Ptr );
+ LOG("Removed volume %s", vol->Name);
+ free(vol);
+ }
+
+ if( gpLVM_FirstVolume )
+ return EBUSY;
+
+ return EOK;
}
// --------------------------------------------------------------------
real_vol->Next = NULL;
real_vol->Type = Type;
real_vol->Ptr = Ptr;
+ real_vol->BlockSize = BlockSize;
real_vol->BlockCount = BlockCount;
real_vol->nSubVolumes = dummy_vol.nSubVolumes;
real_vol->SubVolumes = (void*)( real_vol->Name + strlen(Name) + 1 );
// === PROTOTYPES ===
int MSC_Initialise(char **Arguments);
-void MSC_Cleanup(void);
+ int MSC_Cleanup(void);
void MSC_DeviceConnected(tUSBInterface *Dev, void *Descriptors, size_t DescriptorsLen);
void MSC_DataIn(tUSBInterface *Dev, int EndPt, int Length, void *Data);
// --- Internal Helpers
return 0;
}
-void MSC_Cleanup(void)
+int MSC_Cleanup(void)
{
+ return 0;
}
void MSC_DeviceConnected(tUSBInterface *Dev, void *Descriptors, size_t DescriptorsLen)