Reorganised the modules directory, started serious work on GUI support
authorJohn Hodge <tpg@prelude.(none)>
Tue, 2 Feb 2010 00:16:30 +0000 (08:16 +0800)
committerJohn Hodge <tpg@prelude.(none)>
Tue, 2 Feb 2010 00:16:30 +0000 (08:16 +0800)
- Cleaning up and bugfixing VTerm graphics support

106 files changed:
Kernel/Makefile.BuildNum
Kernel/drv/vterm.c
Kernel/include/modules.h
Kernel/include/tpl_drv_terminal.h
Makefile.cfg
Modules/ATA/Makefile [deleted file]
Modules/ATA/common.h [deleted file]
Modules/ATA/main.c [deleted file]
Modules/ATA/mbr.c [deleted file]
Modules/BochsGA/Makefile [deleted file]
Modules/BochsGA/bochsvbe.c [deleted file]
Modules/Display/BochsGA/Makefile [new file with mode: 0644]
Modules/Display/BochsGA/bochsvbe.c [new file with mode: 0644]
Modules/Display/Makefile.tpl [new file with mode: 0644]
Modules/FDD/Makefile [deleted file]
Modules/FDD/fdd.c [deleted file]
Modules/FS_Ext2/Makefile [deleted file]
Modules/FS_Ext2/dir.c [deleted file]
Modules/FS_Ext2/ext2.c [deleted file]
Modules/FS_Ext2/ext2_common.h [deleted file]
Modules/FS_Ext2/ext2fs.h [deleted file]
Modules/FS_Ext2/read.c [deleted file]
Modules/FS_Ext2/write.c [deleted file]
Modules/Filesystems/FS_Ext2/Makefile [new file with mode: 0644]
Modules/Filesystems/FS_Ext2/dir.c [new file with mode: 0644]
Modules/Filesystems/FS_Ext2/ext2.c [new file with mode: 0644]
Modules/Filesystems/FS_Ext2/ext2_common.h [new file with mode: 0644]
Modules/Filesystems/FS_Ext2/ext2fs.h [new file with mode: 0644]
Modules/Filesystems/FS_Ext2/read.c [new file with mode: 0644]
Modules/Filesystems/FS_Ext2/write.c [new file with mode: 0644]
Modules/Filesystems/Makefile.tpl [new file with mode: 0644]
Modules/Interfaces/Makefile.tpl [new file with mode: 0644]
Modules/Interfaces/UDI/Makefile [new file with mode: 0644]
Modules/Interfaces/UDI/buf.c [new file with mode: 0644]
Modules/Interfaces/UDI/cb.c [new file with mode: 0644]
Modules/Interfaces/UDI/imc.c [new file with mode: 0644]
Modules/Interfaces/UDI/include/physio/meta_bus.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/physio/meta_intr.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/physio/pio.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/udi.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/udi/attr.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/udi/buf.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/udi/cb.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/udi/imc.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/udi/init.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/udi/log.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/udi/mem.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/udi/meta_gio.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/udi/meta_mgmt.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/udi/strmem.h [new file with mode: 0644]
Modules/Interfaces/UDI/include/udi_physio.h [new file with mode: 0644]
Modules/Interfaces/UDI/logging.c [new file with mode: 0644]
Modules/Interfaces/UDI/main.c [new file with mode: 0644]
Modules/Interfaces/UDI/mem.c [new file with mode: 0644]
Modules/Interfaces/UDI/meta_gio.c [new file with mode: 0644]
Modules/Interfaces/UDI/meta_mgmt.c [new file with mode: 0644]
Modules/Interfaces/UDI/physio.c [new file with mode: 0644]
Modules/Interfaces/UDI/physio/meta_bus.c [new file with mode: 0644]
Modules/Interfaces/UDI/physio/meta_intr.c [new file with mode: 0644]
Modules/Interfaces/UDI/physio_main.c [new file with mode: 0644]
Modules/Interfaces/UDI/strmem.c [new file with mode: 0644]
Modules/Makefile.tpl
Modules/NE2000/Makefile [deleted file]
Modules/NE2000/ne2000.c [deleted file]
Modules/Network/Makefile.tpl [new file with mode: 0644]
Modules/Network/NE2000/Makefile [new file with mode: 0644]
Modules/Network/NE2000/ne2000.c [new file with mode: 0644]
Modules/Storage/ATA/Makefile [new file with mode: 0644]
Modules/Storage/ATA/common.h [new file with mode: 0644]
Modules/Storage/ATA/main.c [new file with mode: 0644]
Modules/Storage/ATA/mbr.c [new file with mode: 0644]
Modules/Storage/FDD/Makefile [new file with mode: 0644]
Modules/Storage/FDD/fdd.c [new file with mode: 0644]
Modules/Storage/Makefile.tpl [new file with mode: 0644]
Modules/UDI/Makefile [deleted file]
Modules/UDI/buf.c [deleted file]
Modules/UDI/cb.c [deleted file]
Modules/UDI/imc.c [deleted file]
Modules/UDI/include/physio/meta_bus.h [deleted file]
Modules/UDI/include/physio/meta_intr.h [deleted file]
Modules/UDI/include/physio/pio.h [deleted file]
Modules/UDI/include/udi.h [deleted file]
Modules/UDI/include/udi/attr.h [deleted file]
Modules/UDI/include/udi/buf.h [deleted file]
Modules/UDI/include/udi/cb.h [deleted file]
Modules/UDI/include/udi/imc.h [deleted file]
Modules/UDI/include/udi/init.h [deleted file]
Modules/UDI/include/udi/log.h [deleted file]
Modules/UDI/include/udi/mem.h [deleted file]
Modules/UDI/include/udi/meta_gio.h [deleted file]
Modules/UDI/include/udi/meta_mgmt.h [deleted file]
Modules/UDI/include/udi/strmem.h [deleted file]
Modules/UDI/include/udi_physio.h [deleted file]
Modules/UDI/logging.c [deleted file]
Modules/UDI/main.c [deleted file]
Modules/UDI/mem.c [deleted file]
Modules/UDI/meta_gio.c [deleted file]
Modules/UDI/meta_mgmt.c [deleted file]
Modules/UDI/physio.c [deleted file]
Modules/UDI/physio/meta_bus.c [deleted file]
Modules/UDI/physio/meta_intr.c [deleted file]
Modules/UDI/physio_main.c [deleted file]
Modules/UDI/strmem.c [deleted file]
Usermode/Applications/login_src/database_tpl.c
Usermode/Applications/login_src/main.c
Usermode/include/acess/devices/terminal.h

index 3ef05ea..3cd471c 100644 (file)
@@ -1 +1 @@
-BUILD_NUM = 1398
+BUILD_NUM = 1407
index 76b7f1e..716a553 100644 (file)
@@ -19,8 +19,8 @@
 #define MAX_INPUT_CHARS32      64
 #define MAX_INPUT_CHARS8       (MAX_INPUT_CHARS32*4)
 #define VT_SCROLLBACK  1       // 2 Screens of text
-#define DEFAULT_OUTPUT "VGA"
-//#define DEFAULT_OUTPUT       "BochsGA"
+//#define DEFAULT_OUTPUT       "VGA"
+#define DEFAULT_OUTPUT "BochsGA"
 #define DEFAULT_INPUT  "PS2Keyboard"
 #define        DEFAULT_WIDTH   80
 #define        DEFAULT_HEIGHT  25
@@ -348,6 +348,28 @@ Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        case TERM_MODE_TEXT:
                VT_int_PutString(term, Buffer, Length);
                break;
+       case TERM_MODE_FB:
+               if( term->RealWidth > term->Width || term->RealHeight > term->Height )
+               {
+                       #if 0
+                        int    x, y, h;
+                       x = Offset/4;   y = x / term->Width;    x %= term->Width;
+                       w = Length/4+x; h = w / term->Width;    w %= term->Width;
+                       while(h--)
+                       {
+                               VFS_WriteAt( giVT_OutputDevHandle,
+                                       (x+y*term->RealWidth)*4,
+                                       term->Width * 4,
+                                       Buffer
+                                       );
+                               Buffer = (void*)( (Uint)Buffer + term->Width*term->Height*4 );
+                       }
+                       #endif
+                       return 0;
+               }
+               else {
+                       return VFS_WriteAt( giVT_OutputDevHandle, Offset, Length, Buffer );
+               }
        }
        
        //LEAVE('i', 0);
@@ -364,6 +386,10 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
        tVTerm  *term = Node->ImplPtr;
        ENTER("pNode iId pData", Node, Id, Data);
        
+       if(Id >= DRV_IOCTL_LOOKUP) {
+               if( Threads_GetUID() != 0 )     return -1;
+       }
+       
        switch(Id)
        {
        case DRV_IOCTL_TYPE:
@@ -407,6 +433,11 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
                Log("VT_Terminal_IOCtl - RETURN term->Height = %i", term->Height);
                LEAVE('i', term->Height);
                return term->Height;
+       
+       case TERM_IOCTL_FORCESHOW:
+               VT_SetTerminal( Node->Inode );
+               LEAVE('i', 1);
+               return 1;
        }
        LEAVE('i', -1);
        return -1;
index 591dbf9..d53f774 100644 (file)
 # error "Unknown architecture when determining MODULE_ARCH_ID ('" #ARCHDIR "')"
 #endif
 
-#define MODULE_DEFINE(_flags,_ver,_ident,_entry,_deinit,_deps...)      char *_DriverDeps_##_ident[]={_deps};\
-       tModule __attribute__ ((section ("KMODULES"),unused)) _DriverInfo_##_ident=\
-       {MODULE_MAGIC,MODULE_ARCH_ID,_flags,_ver,NULL,#_ident,_entry,_deinit,_DriverDeps_##_ident}
+#define MODULE_DEFINE(_flags,_ver,_ident,_entry,_deinit,_deps...) \
+       char *EXPAND_CONCAT(_DriverDeps_,_ident)[]={_deps};\
+       tModule __attribute__ ((section ("KMODULES"),unused))\
+       EXPAND_CONCAT(_DriverInfo_,_ident)=\
+       {MODULE_MAGIC,MODULE_ARCH_ID,_flags,_ver,NULL,EXPAND_STR(_ident),\
+       _entry,_deinit,EXPAND_CONCAT(_DriverDeps_,_ident)}
 
 typedef struct sModule {
        Uint32  Magic;
index 907cc14..21ba290 100644 (file)
@@ -59,7 +59,13 @@ enum eTplTerminal_IOCtl {
         * \note The id field of \a info is not for use with ::TERM_IOCTL_MODETYPE\r
         *       This field is just for indexing the mode to get its information.\r
         */\r
-       TERM_IOCTL_QUERYMODE\r
+       TERM_IOCTL_QUERYMODE,\r
+       \r
+       /**\r
+        * ioctl(...)\r
+        * \brief Forces the current terminal to be shown\r
+        */\r
+       TERM_IOCTL_FORCESHOW\r
 };\r
 \r
 /**\r
index be0194f..348206f 100644 (file)
@@ -25,8 +25,12 @@ endif
 
 FILESYSTEMS = fat
 DRIVERS = 
-MODULES = ATA FS_Ext2 FDD NE2000 BochsGA IPStack
-DYNMODS = USB UDI
+MODULES  = Storage/ATA Storage/FDD
+MODULES += Network/NE2000
+MODULES += Display/BochsGA
+MODULES += Filesystems/FS_Ext2
+MODULES += IPStack
+DYNMODS = USB Interfaces/UDI
 
 #DISTROOT = /mnt/AcessHDD/Acess2
 #DISTROOT = ~/Projects/Acess2/Filesystem
diff --git a/Modules/ATA/Makefile b/Modules/ATA/Makefile
deleted file mode 100644 (file)
index 05e66af..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-#
-
-OBJ = main.o mbr.o
-NAME = ATA
-
--include ../Makefile.tpl
diff --git a/Modules/ATA/common.h b/Modules/ATA/common.h
deleted file mode 100644 (file)
index 18e62a8..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Acess2 IDE Harddisk Driver
- * - main.c
- */
-#ifndef _COMMON_H_
-#define _COMMON_H_
-
-#include <acess.h>
-#include <vfs.h>
-
-// === CONSTANTS ===
-#define        MAX_ATA_DISKS   4
-#define        SECTOR_SIZE             512
-#define        MAX_DMA_SECTORS (0x1000 / SECTOR_SIZE)
-
-#define        IDE_PRI_BASE    0x1F0
-#define        IDE_SEC_BASE    0x170
-
-#define        IDE_PRDT_LAST   0x8000
-/**
- \enum HddControls
- \brief Commands to be sent to HDD_CMD
-*/
-enum HddControls {
-       HDD_PIO_R28 = 0x20,
-       HDD_PIO_R48 = 0x24,
-       HDD_DMA_R48 = 0x25,
-       HDD_PIO_W28 = 0x30,
-       HDD_PIO_W48 = 0x34,
-       HDD_DMA_W48 = 0x35,
-       HDD_DMA_R28 = 0xC8,
-       HDD_DMA_W28 = 0xCA,
-};
-
-// === STRUCTURES ===
-typedef struct
-{
-       Uint8   BootCode[0x1BE];
-       struct {
-               Uint8   Boot;
-               Uint8   Unused1;        // Also CHS Start
-               Uint16  StartHi;        // Also CHS Start
-               Uint8   SystemID;
-               Uint8   Unused2;        // Also CHS Length
-               Uint16  LengthHi;       // Also CHS Length
-               Uint32  LBAStart;
-               Uint32  LBALength;
-       } __attribute__ ((packed)) Parts[4];
-       Uint16  BootFlag;       // = 0xAA 55
-} __attribute__ ((packed))     tMBR;
-
-typedef struct
-{
-       Uint64  Start;
-       Uint64  Length;
-       char    Name[4];
-       tVFS_Node       Node;
-}      tATA_Partition;
-
-typedef struct
-{
-       Uint64  Sectors;
-       char    Name[2];
-       tVFS_Node       Node;
-        int    NumPartitions;
-       tATA_Partition  *Partitions;
-}      tATA_Disk;
-
-// === GLOBALS ===
-extern tATA_Disk       gATA_Disks[];
-
-// === FUNCTIONS ===
-extern void    ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length);
-extern int     ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
-extern int     ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
-
-#endif
diff --git a/Modules/ATA/main.c b/Modules/ATA/main.c
deleted file mode 100644 (file)
index 41f0873..0000000
+++ /dev/null
@@ -1,793 +0,0 @@
-/*
- * Acess2 IDE Harddisk Driver
- * - main.c
- */
-#define DEBUG  0
-#include <acess.h>
-#include <modules.h>
-#include <vfs.h>
-#include <fs_devfs.h>
-#include <drv_pci.h>
-#include <tpl_drv_common.h>
-#include <tpl_drv_disk.h>
-#include "common.h"
-
-// --- Flags ---
-#define START_BEFORE_CMD       0
-
-// === STRUCTURES ===
-typedef struct
-{
-       Uint32  PBufAddr;
-       Uint16  Bytes;
-       Uint16  Flags;
-} __attribute__ ((packed))     tPRDT_Ent;
-typedef struct
-{
-       Uint16  Flags;          // 1
-       Uint16  Usused1[9];     // 10
-       char    SerialNum[20];  // 20
-       Uint16  Usused2[3];     // 23
-       char    FirmwareVer[8]; // 27
-       char    ModelNumber[40];        // 47
-       Uint16  SectPerInt;     // 48 - AND with 0xFF to get true value;
-       Uint16  Unused3;        // 49
-       Uint16  Capabilities[2];        // 51
-       Uint16  Unused4[2];     // 53
-       Uint16  ValidExtData;   // 54
-       Uint16  Unused5[5];      // 59
-       Uint16  SizeOfRWMultiple;       // 60
-       Uint32  Sectors28;      // 62
-       Uint16  Unused6[100-62];
-       Uint64  Sectors48;
-       Uint16  Unused7[256-104];
-} __attribute__ ((packed))     tIdentify;
-
-// === IMPORTS ===
-extern void    ATA_ParseMBR(int Disk);
-
-// === PROTOTYPES ===
- int   ATA_Install();
- int   ATA_SetupIO();
-void   ATA_SetupPartitions();
-void   ATA_SetupVFS();
- int   ATA_ScanDisk(int Disk);
-void   ATA_ParseGPT(int Disk);
-void   ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length);
-Uint16 ATA_GetBasePort(int Disk);
-// Filesystem Interface
-char   *ATA_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node      *ATA_FindDir(tVFS_Node *Node, char *Name);
-Uint64 ATA_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
-Uint64 ATA_WriteFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
- int   ATA_IOCtl(tVFS_Node *Node, int Id, void *Data);
-// Read/Write Interface/Quantiser
-Uint   ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk);
-Uint   ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk);
-// Read/Write DMA
- int   ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
- int   ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
-// IRQs
-void   ATA_IRQHandlerPri(int unused);
-void   ATA_IRQHandlerSec(int unused);
-// Controller IO
-Uint8  ATA_int_BusMasterReadByte(int Ofs);
-void   ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value);
-void   ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value);
-
-// === GLOBALS ===
-MODULE_DEFINE(0, 0x0032, i386ATA, ATA_Install, NULL, NULL);
-tDevFS_Driver  gATA_DriverInfo = {
-       NULL, "ata",
-       {
-               .NumACLs = 1,
-               .Size = -1,
-               .Flags = VFS_FFLAG_DIRECTORY,
-               .ACLs = &gVFS_ACL_EveryoneRX,
-               .ReadDir = ATA_ReadDir,
-               .FindDir = ATA_FindDir
-       }
-};
-tATA_Disk      gATA_Disks[MAX_ATA_DISKS];
- int   giATA_NumNodes;
-tVFS_Node      **gATA_Nodes;
-Uint16 gATA_BusMasterBase = 0;
-Uint8  *gATA_BusMasterBasePtr = 0;
- int   gATA_IRQPri = 14;
- int   gATA_IRQSec = 15;
- int   giaATA_ControllerLock[2] = {0}; //!< Spinlocks for each controller
-Uint8  gATA_Buffers[2][4096] __attribute__ ((section(".padata")));
- int   gaATA_IRQs[2] = {0};
-tPRDT_Ent      gATA_PRDTs[2] = {
-       {0, 512, IDE_PRDT_LAST},
-       {0, 512, IDE_PRDT_LAST}
-};
-
-// === CODE ===
-/**
- * \fn int ATA_Install()
- */
-int ATA_Install()
-{
-       int     ret;
-       
-       ret = ATA_SetupIO();
-       if(ret != 1)    return ret;
-       
-       ATA_SetupPartitions();
-       
-       ATA_SetupVFS();
-       
-       if( DevFS_AddDevice( &gATA_DriverInfo ) == 0 )
-               return MODULE_INIT_FAILURE;
-       
-       return MODULE_INIT_SUCCESS;
-}
-
-/**
- * \fn int ATA_SetupIO()
- * \brief Sets up the ATA controller's DMA mode
- */
-int ATA_SetupIO()
-{
-        int    ent;
-       tPAddr  addr;
-       
-       ENTER("");
-       
-       // Get IDE Controller's PCI Entry
-       ent = PCI_GetDeviceByClass(0x0101, 0xFFFF, -1);
-       LOG("ent = %i", ent);
-       gATA_BusMasterBase = PCI_GetBAR4( ent );
-       if( gATA_BusMasterBase == 0 ) {
-               Warning("It seems that there is no Bus Master Controller on this machine. Get one");
-               LEAVE('i', MODULE_INIT_FAILURE);
-               return MODULE_INIT_FAILURE;
-       }
-       if( !(gATA_BusMasterBase & 1) )
-       {
-               if( gATA_BusMasterBase < 0x100000 )
-                       gATA_BusMasterBasePtr = (void*)(0xC0000000|gATA_BusMasterBase);
-               else
-                       gATA_BusMasterBasePtr = (void*)( MM_MapHWPage( gATA_BusMasterBase, 1 ) + (gATA_BusMasterBase&0xFFF) );
-               LOG("gATA_BusMasterBasePtr = %p", gATA_BusMasterBasePtr);
-       }
-       else {
-               // Bit 0 is left set as a flag to other functions
-               LOG("gATA_BusMasterBase = 0x%x", gATA_BusMasterBase & ~1);
-       }
-       
-       IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri );
-       IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec );
-       
-       gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (Uint)&gATA_Buffers[0] );
-       gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (Uint)&gATA_Buffers[1] );
-       
-       LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr);
-       
-       addr = MM_GetPhysAddr( (Uint)&gATA_PRDTs[0] );
-       LOG("addr = 0x%x", addr);
-       ATA_int_BusMasterWriteDWord(4, addr);
-       addr = MM_GetPhysAddr( (Uint)&gATA_PRDTs[1] );
-       LOG("addr = 0x%x", addr);
-       ATA_int_BusMasterWriteDWord(12, addr);
-       
-       outb(IDE_PRI_BASE+1, 1);
-       outb(IDE_SEC_BASE+1, 1);
-       
-       LEAVE('i', MODULE_INIT_SUCCESS);
-       return MODULE_INIT_SUCCESS;
-}
-
-/**
- * \fn void ATA_SetupPartitions()
- */
-void ATA_SetupPartitions()
-{
-        int    i;
-       for( i = 0; i < MAX_ATA_DISKS; i ++ )
-       {
-               if( !ATA_ScanDisk(i) ) {
-                       gATA_Disks[i].Name[0] = '\0';   // Mark as unused
-                       continue;
-               }
-       }
-}
-
-/**
- * \fn void ATA_SetupVFS()
- * \brief Sets up the ATA drivers VFS information and registers with DevFS
- */
-void ATA_SetupVFS()
-{
-        int    i, j, k;
-       
-       // Count number of nodes needed
-       giATA_NumNodes = 0;
-       for( i = 0; i < MAX_ATA_DISKS; i++ )
-       {
-               if(gATA_Disks[i].Name[0] == '\0')       continue;       // Ignore
-               giATA_NumNodes ++;
-               giATA_NumNodes += gATA_Disks[i].NumPartitions;
-       }
-       
-       // Allocate Node space
-       gATA_Nodes = malloc( giATA_NumNodes * sizeof(void*) );
-       
-       // Set nodes
-       k = 0;
-       for( i = 0; i < MAX_ATA_DISKS; i++ )
-       {
-               if(gATA_Disks[i].Name[0] == '\0')       continue;       // Ignore
-               gATA_Nodes[ k++ ] = &gATA_Disks[i].Node;
-               for( j = 0; j < gATA_Disks[i].NumPartitions; j ++ )
-                       gATA_Nodes[ k++ ] = &gATA_Disks[i].Partitions[j].Node;
-       }
-       
-       gATA_DriverInfo.RootNode.Size = giATA_NumNodes;
-}
-
-/**
- * \fn int ATA_ScanDisk(int Disk)
- */
-int ATA_ScanDisk(int Disk)
-{
-       Uint16  buf[256];
-       tIdentify       *identify = (void*)buf;
-       tMBR    *mbr = (void*)buf;
-       Uint16  base;
-       Uint8   val;
-        int    i;
-       tVFS_Node       *node;
-       
-       ENTER("iDisk", Disk);
-       
-       base = ATA_GetBasePort( Disk );
-       
-       LOG("base = 0x%x", base);
-       
-       // Send Disk Selector
-       if(Disk == 1 || Disk == 3)
-               outb(base+6, 0xB0);
-       else
-               outb(base+6, 0xA0);
-       
-       // Send IDENTIFY
-       outb(base+7, 0xEC);
-       val = inb(base+7);      // Read status
-       if(val == 0) {
-               LEAVE('i', 0);
-               return 0;       // Disk does not exist
-       }
-       
-       // Poll until BSY clears and DRQ sets or ERR is set
-       while( ((val & 0x80) || !(val & 0x08)) && !(val & 1))   val = inb(base+7);
-       
-       if(val & 1) {
-               LEAVE('i', 0);
-               return 0;       // Error occured, so return false
-       }
-       
-       // Read Data
-       for(i=0;i<256;i++)      buf[i] = inw(base);
-       
-       // Populate Disk Structure
-       if(identify->Sectors48 != 0)
-               gATA_Disks[ Disk ].Sectors = identify->Sectors48;
-       else
-               gATA_Disks[ Disk ].Sectors = identify->Sectors28;
-       
-       
-       LOG("gATA_Disks[ Disk ].Sectors = 0x%x", gATA_Disks[ Disk ].Sectors);
-       
-       if( gATA_Disks[ Disk ].Sectors / (2048*1024) )
-               Log("Disk %i: 0x%llx Sectors (%i GiB)", Disk,
-                       gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / (2048*1024));
-       else if( gATA_Disks[ Disk ].Sectors / 2048 )
-               Log("Disk %i: 0x%llx Sectors (%i MiB)", Disk,
-                       gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / 2048);
-       else
-               Log("Disk %i: 0x%llx Sectors (%i KiB)", Disk,
-                       gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / 2);
-       
-       // Create Name
-       gATA_Disks[ Disk ].Name[0] = 'A'+Disk;
-       gATA_Disks[ Disk ].Name[1] = '\0';
-       
-       // Get pointer to vfs node and populate it
-       node = &gATA_Disks[ Disk ].Node;
-       node->Size = gATA_Disks[Disk].Sectors * SECTOR_SIZE;
-       node->NumACLs = 0;      // Means Superuser only can access it
-       node->Inode = (Disk << 8) | 0xFF;
-       node->ImplPtr = gATA_Disks[ Disk ].Name;
-       
-       node->ATime = node->MTime
-               = node->CTime = now();
-       
-       node->Read = ATA_ReadFS;
-       node->Write = ATA_WriteFS;
-       node->IOCtl = ATA_IOCtl;
-
-
-       // --- Scan Partitions ---
-       LOG("Reading MBR");
-       // Read Boot Sector
-       ATA_ReadDMA( Disk, 0, 1, mbr );
-       
-       // Check for a GPT table
-       if(mbr->Parts[0].SystemID == 0xEE)
-               ATA_ParseGPT(Disk);
-       else    // No? Just parse the MBR
-               ATA_ParseMBR(Disk);
-       
-       LEAVE('i', 0);
-       return 1;
-}
-
-/**
- * \fn void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length)
- * \brief Fills a parition's information structure
- */
-void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length)
-{
-       ENTER("pPart iDisk iNum XStart XLength", Part, Disk, Num, Start, Length);
-       Part->Start = Start;
-       Part->Length = Length;
-       Part->Name[0] = 'A'+Disk;
-       if(Num >= 10) {
-               Part->Name[1] = '1'+Num/10;
-               Part->Name[2] = '1'+Num%10;
-               Part->Name[3] = '\0';
-       } else {
-               Part->Name[1] = '1'+Num;
-               Part->Name[2] = '\0';
-       }
-       Part->Node.NumACLs = 0; // Only root can read/write raw block devices
-       Part->Node.Inode = (Disk << 8) | Num;
-       Part->Node.ImplPtr = Part->Name;
-       
-       Part->Node.Read = ATA_ReadFS;
-       Part->Node.Write = ATA_WriteFS;
-       Part->Node.IOCtl = ATA_IOCtl;
-       LOG("Made '%s' (&Node=%p)", Part->Name, &Part->Node);
-       LEAVE('-');
-}
-
-/**
- * \fn void ATA_ParseGPT(int Disk)
- * \brief Parses the GUID Partition Table
- */
-void ATA_ParseGPT(int Disk)
-{
-       ///\todo Support GPT Disks
-       Warning("GPT Disks are currently unsupported");
-}
-
-/**
- * \fn Uint16 ATA_GetPortBase(int Disk)
- * \brief Returns the base port for a given disk
- */
-Uint16 ATA_GetBasePort(int Disk)
-{
-       switch(Disk)
-       {
-       case 0: case 1:         return IDE_PRI_BASE;
-       case 2: case 3:         return IDE_SEC_BASE;
-       }
-       return 0;
-}
-
-/**
- * \fn char *ATA_ReadDir(tVFS_Node *Node, int Pos)
- */
-char *ATA_ReadDir(tVFS_Node *Node, int Pos)
-{
-       if(Pos >= giATA_NumNodes || Pos < 0)    return NULL;
-       return strdup( gATA_Nodes[Pos]->ImplPtr );
-}
-
-/**
- * \fn tVFS_Node *ATA_FindDir(tVFS_Node *Node, char *Name)
- */
-tVFS_Node *ATA_FindDir(tVFS_Node *Node, char *Name)
-{
-        int    part;
-       // Check first character
-       if(Name[0] < 'A' || Name[0] > 'A'+MAX_ATA_DISKS)
-               return NULL;
-       // Raw Disk
-       if(Name[1] == '\0') {
-               if( gATA_Disks[Name[0]-'A'].Sectors == 0 )
-                       return NULL;
-               return &gATA_Disks[Name[0]-'A'].Node;
-       }
-       
-       // Partitions
-       if(Name[1] < '0' || '9' < Name[1])      return NULL;
-       if(Name[2] == '\0') {   // <= 9
-               part = Name[1] - '0';
-               part --;
-               return &gATA_Disks[Name[0]-'A'].Partitions[part].Node;
-       }
-       // > 9
-       if('0' > Name[2] || '9' < Name[2])      return NULL;
-       if(Name[3] != '\0')     return NULL;
-       
-       part = (Name[1] - '0') * 10;
-       part += Name[2] - '0';
-       part --;
-       return &gATA_Disks[Name[0]-'A'].Partitions[part].Node;
-       
-}
-
-/**
- * \fn Uint64 ATA_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
- */
-Uint64 ATA_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
-{
-        int    disk = Node->Inode >> 8;
-        int    part = Node->Inode & 0xFF;
-       
-       // Raw Disk Access
-       if(part == 0xFF)
-       {
-               if( Offset >= gATA_Disks[disk].Sectors * SECTOR_SIZE )
-                       return 0;
-               if( Offset + Length > gATA_Disks[disk].Sectors*SECTOR_SIZE )
-                       Length = gATA_Disks[disk].Sectors*SECTOR_SIZE - Offset;
-       }
-       // Partition
-       else
-       {
-               if( Offset >= gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE )
-                       return 0;
-               if( Offset + Length > gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE )
-                       Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset;
-               Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE;
-       }
-       
-       //Log("ATA_ReadFS: (Node=%p, Offset=0x%llx, Length=0x%llx, Buffer=%p)", Node, Offset, Length, Buffer);
-       return DrvUtil_ReadBlock(Offset, Length, Buffer, ATA_ReadRaw, SECTOR_SIZE, disk);
-}
-
-/**
- * \fn Uint64 ATA_WriteFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
- */
-Uint64 ATA_WriteFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
-{
-        int    disk = Node->Inode >> 8;
-        int    part = Node->Inode & 0xFF;
-       
-       // Raw Disk Access
-       if(part == 0xFF)
-       {
-               if( Offset >= gATA_Disks[disk].Sectors * SECTOR_SIZE )
-                       return 0;
-               if( Offset + Length > gATA_Disks[disk].Sectors*SECTOR_SIZE )
-                       Length = gATA_Disks[disk].Sectors*SECTOR_SIZE - Offset;
-       }
-       // Partition
-       else
-       {
-               if( Offset >= gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE )
-                       return 0;
-               if( Offset + Length > gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE )
-                       Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset;
-               Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE;
-       }
-       
-       Log("ATA_WriteFS: (Node=%p, Offset=0x%llx, Length=0x%llx, Buffer=%p)", Node, Offset, Length, Buffer);
-       Debug_HexDump("ATA_WriteFS", Buffer, Length);
-       return DrvUtil_WriteBlock(Offset, Length, Buffer, ATA_ReadRaw, ATA_WriteRaw, SECTOR_SIZE, disk);
-}
-
-/**
- * \fn int ATA_IOCtl(tVFS_Node *Node, int Id, void *Data)
- * \brief IO Control Funtion
- */
-int ATA_IOCtl(tVFS_Node *Node, int Id, void *Data)
-{
-       switch(Id)
-       {
-       case DRV_IOCTL_TYPE:    return DRV_TYPE_DISK;
-       }
-       return 0;
-}
-
-// --- Disk Access ---
-/**
- * \fn Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
- */
-Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
-{
-        int    ret;
-       Uint    offset;
-       Uint    done = 0;
-        
-       // Pass straight on to ATA_ReadDMAPage if we can
-       if(Count <= MAX_DMA_SECTORS)
-       {
-               ret = ATA_ReadDMA(Disk, Address, Count, Buffer);
-               if(ret == 0)    return 0;
-               return Count;
-       }
-       
-       // Else we will have to break up the transfer
-       offset = 0;
-       while(Count > MAX_DMA_SECTORS)
-       {
-               ret = ATA_ReadDMA(Disk, Address+offset, MAX_DMA_SECTORS, Buffer+offset);
-               // Check for errors
-               if(ret != 1)    return done;
-               // Change Position
-               done += MAX_DMA_SECTORS;
-               Count -= MAX_DMA_SECTORS;
-               offset += MAX_DMA_SECTORS*SECTOR_SIZE;
-       }
-       
-       ret = ATA_ReadDMA(Disk, Address+offset, Count, Buffer+offset);
-       if(ret != 1)    return 0;
-       return done+Count;
-}
-
-/**
- * \fn Uint ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
- */
-Uint ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
-{
-        int    ret;
-       Uint    offset;
-       Uint    done = 0;
-        
-       // Pass straight on to ATA_WriteDMA if we can
-       if(Count <= MAX_DMA_SECTORS)
-       {
-               ret = ATA_WriteDMA(Disk, Address, Count, Buffer);
-               if(ret == 0)    return 0;
-               return Count;
-       }
-       
-       // Else we will have to break up the transfer
-       offset = 0;
-       while(Count > MAX_DMA_SECTORS)
-       {
-               ret = ATA_WriteDMA(Disk, Address+offset, MAX_DMA_SECTORS, Buffer+offset);
-               // Check for errors
-               if(ret != 1)    return done;
-               // Change Position
-               done += MAX_DMA_SECTORS;
-               Count -= MAX_DMA_SECTORS;
-               offset += MAX_DMA_SECTORS*SECTOR_SIZE;
-       }
-       
-       ret = ATA_WriteDMA(Disk, Address+offset, Count, Buffer+offset);
-       if(ret != 1)    return 0;
-       return done+Count;
-}
-
-/**
- * \fn int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
- */
-int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
-{
-        int    cont = (Disk>>1)&1;     // Controller ID
-        int    disk = Disk & 1;
-       Uint16  base;
-       
-       ENTER("iDisk XAddress iCount pBuffer", Disk, Address, Count, Buffer);
-       
-       // Check if the count is small enough
-       if(Count > MAX_DMA_SECTORS) {
-               Warning("Passed too many sectors for a bulk DMA read (%i > %i)",
-                       Count, MAX_DMA_SECTORS);
-               LEAVE('i');
-               return 0;
-       }
-       
-       // Get exclusive access to the disk controller
-       LOCK( &giaATA_ControllerLock[ cont ] );
-       
-       // Set Size
-       gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
-       
-       // Get Port Base
-       base = ATA_GetBasePort(Disk);
-       
-       // Reset IRQ Flag
-       gaATA_IRQs[cont] = 0;
-       
-       // Set up transfer
-       outb(base+0x01, 0x00);
-       if( Address > 0x0FFFFFFF )      // Use LBA48
-       {
-               outb(base+0x6, 0x40 | (disk << 4));
-               outb(base+0x2, 0 >> 8); // Upper Sector Count
-               outb(base+0x3, Address >> 24);  // Low 2 Addr
-               outb(base+0x3, Address >> 28);  // Mid 2 Addr
-               outb(base+0x3, Address >> 32);  // High 2 Addr
-       }
-       else
-       {
-               outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); //Disk,Magic,High addr
-       }
-       
-       outb(base+0x02, (Uint8) Count);         // Sector Count
-       outb(base+0x03, (Uint8) Address);               // Low Addr
-       outb(base+0x04, (Uint8) (Address >> 8));        // Middle Addr
-       outb(base+0x05, (Uint8) (Address >> 16));       // High Addr
-       
-       LOG("Starting Transfer");
-       #if START_BEFORE_CMD
-       // Start transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 9 );     // Read and start
-       if( Address > 0x0FFFFFFF )
-               outb(base+0x07, HDD_DMA_R48);   // Read Command (LBA48)
-       else
-               outb(base+0x07, HDD_DMA_R28);   // Read Command (LBA28)
-       #else
-       if( Address > 0x0FFFFFFF )
-               outb(base+0x07, HDD_DMA_R48);   // Read Command (LBA48)
-       else
-               outb(base+0x07, HDD_DMA_R28);   // Read Command (LBA28)
-       // Start transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 9 );     // Read and start
-       #endif
-       
-       // Wait for transfer to complete
-       //ATA_int_BusMasterWriteByte( (cont << 3) + 2, 0x4 );
-       while( gaATA_IRQs[cont] == 0 ) {
-               //Uint8 val = ATA_int_BusMasterReadByte( (cont << 3) + 2, 0x4 );
-               //LOG("val = 0x%02x", val);
-               Threads_Yield();
-       }
-       
-       // Complete Transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 0 );     // Write and stop
-       
-       LOG("Transfer Completed & Acknowledged");
-       
-       // Copy to destination buffer
-       memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE );
-       
-       // Release controller lock
-       RELEASE( &giaATA_ControllerLock[ cont ] );
-       
-       LEAVE('i', 1);
-       return 1;
-}
-
-/**
- * \fn int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
- */
-int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
-{
-        int    cont = (Disk>>1)&1;     // Controller ID
-        int    disk = Disk & 1;
-       Uint16  base;
-       
-       // Check if the count is small enough
-       if(Count > MAX_DMA_SECTORS)     return 0;
-       
-       // Get exclusive access to the disk controller
-       LOCK( &giaATA_ControllerLock[ cont ] );
-       
-       // Set Size
-       gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
-       
-       // Get Port Base
-       base = ATA_GetBasePort(Disk);
-       
-       // Set up transfer
-       outb(base+0x01, 0x00);
-       if( Address > 0x0FFFFFFF )      // Use LBA48
-       {
-               outb(base+0x6, 0x40 | (disk << 4));
-               outb(base+0x2, 0 >> 8); // Upper Sector Count
-               outb(base+0x3, Address >> 24);  // Low 2 Addr
-               outb(base+0x3, Address >> 28);  // Mid 2 Addr
-               outb(base+0x3, Address >> 32);  // High 2 Addr
-       }
-       else
-       {
-               outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); //Disk,Magic,High addr
-       }
-       
-       outb(base+0x02, (Uint8) Count);         // Sector Count
-       outb(base+0x03, (Uint8) Address);               // Low Addr
-       outb(base+0x04, (Uint8) (Address >> 8));        // Middle Addr
-       outb(base+0x05, (Uint8) (Address >> 16));       // High Addr
-       if( Address > 0x0FFFFFFF )
-               outb(base+0x07, HDD_DMA_W48);   // Write Command (LBA48)
-       else
-               outb(base+0x07, HDD_DMA_W28);   // Write Command (LBA28)
-       
-       // Reset IRQ Flag
-       gaATA_IRQs[cont] = 0;
-       
-       // Copy to output buffer
-       memcpy( gATA_Buffers[cont], Buffer, Count*SECTOR_SIZE );
-       
-       // Start transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 1 );     // Write and start
-       
-       // Wait for transfer to complete
-       while( gaATA_IRQs[cont] == 0 )  Threads_Yield();
-       
-       // Complete Transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 0 );     // Write and stop
-       
-       // Release controller lock
-       RELEASE( &giaATA_ControllerLock[ cont ] );
-       
-       return 1;
-}
-
-/**
- * \fn void ATA_IRQHandlerPri(int unused)
- */
-void ATA_IRQHandlerPri(int unused)
-{
-       Uint8   val;
-       
-       // IRQ bit set for Primary Controller
-       val = ATA_int_BusMasterReadByte( 0x2 );
-       LOG("IRQ val = 0x%x", val);
-       if(val & 4) {
-               LOG("IRQ hit (val = 0x%x)", val);
-               ATA_int_BusMasterWriteByte( 0x2, 4 );
-               gaATA_IRQs[0] = 1;
-               return ;
-       }
-}
-
-/**
- * \fn void ATA_IRQHandlerSec(int unused)
- */
-void ATA_IRQHandlerSec(int unused)
-{
-       Uint8   val;
-       // IRQ bit set for Secondary Controller
-       val = ATA_int_BusMasterReadByte( 0xA );
-       if(val & 4) {
-               LOG("IRQ hit (val = 0x%x)", val);
-               ATA_int_BusMasterWriteByte( 0xA, 4 );
-               gaATA_IRQs[1] = 1;
-               return ;
-       }
-}
-
-/**
- * \fn Uint8 ATA_int_BusMasterReadByte(int Ofs)
- */
-Uint8 ATA_int_BusMasterReadByte(int Ofs)
-{
-       if( gATA_BusMasterBase & 1 )
-               return inb( (gATA_BusMasterBase & ~1) + Ofs );
-       else
-               return *(Uint8*)(gATA_BusMasterBasePtr + Ofs);
-}
-
-/**
- * \fn void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value)
- * \brief Writes a byte to a Bus Master Register
- */
-void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value)
-{
-       if( gATA_BusMasterBase & 1 )
-               outb( (gATA_BusMasterBase & ~1) + Ofs, Value );
-       else
-               *(Uint8*)(gATA_BusMasterBasePtr + Ofs) = Value;
-}
-
-/**
- * \fn void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value)
- * \brief Writes a dword to a Bus Master Register
- */
-void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value)
-{
-       
-       if( gATA_BusMasterBase & 1 )
-               outd( (gATA_BusMasterBase & ~1) + Ofs, Value );
-       else
-               *(Uint32*)(gATA_BusMasterBasePtr + Ofs) = Value;
-}
diff --git a/Modules/ATA/mbr.c b/Modules/ATA/mbr.c
deleted file mode 100644 (file)
index 45ade88..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Acess2 IDE Harddisk Driver
- * - MBR Parsing Code
- * mbr.c
- */
-#define DEBUG  0
-#include <acess.h>
-#include "common.h"
-
-// === PROTOTYPES ===
-Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length);
-
-// === GLOBALS ===
-
-// === CODE ===
-/**
- * \fn void ATA_ParseMBR(int Disk)
- */
-void ATA_ParseMBR(int Disk)
-{
-        int    i, j = 0, k = 4;
-       tMBR    mbr;
-       Uint64  extendedLBA;
-       Uint64  base, len;
-       
-       ENTER("iDisk", Disk);
-       
-       // Read Boot Sector
-       ATA_ReadDMA( Disk, 0, 1, &mbr );
-       
-       // Count Partitions
-       gATA_Disks[Disk].NumPartitions = 0;
-       extendedLBA = 0;
-       for( i = 0; i < 4; i ++ )
-       {
-               if( mbr.Parts[i].SystemID == 0 )        continue;
-               if(     mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80   // LBA 28
-               ||      mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81   // LBA 48
-                       )
-               {
-                       if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) {
-                               LOG("Extended Partition");
-                               if(extendedLBA != 0) {
-                                       Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
-                                       continue;
-                               }
-                               extendedLBA = mbr.Parts[i].LBAStart;
-                               continue;
-                       }
-                       LOG("Primary Partition");
-                       
-                       gATA_Disks[Disk].NumPartitions ++;
-                       continue;
-               }
-               // Invalid Partition, so don't count it
-       }
-       while(extendedLBA != 0)
-       {
-               extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len);
-               if( extendedLBA == -1 ) return ;
-               gATA_Disks[Disk].NumPartitions ++;
-       }
-       LOG("gATA_Disks[Disk].NumPartitions = %i", gATA_Disks[Disk].NumPartitions);
-       
-       // Create patition array
-       gATA_Disks[Disk].Partitions = malloc( gATA_Disks[Disk].NumPartitions * sizeof(tATA_Partition) );
-       
-       // --- Fill Partition Info ---
-       extendedLBA = 0;
-       for( j = 0, i = 0; i < 4; i ++ )
-       {
-               Log("mbr.Parts[%i].SystemID = 0x%02x", i, mbr.Parts[i].SystemID);
-               if( mbr.Parts[i].SystemID == 0 )        continue;
-               if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 )     // LBA 28
-               {
-                       base = mbr.Parts[i].LBAStart;
-                       len = mbr.Parts[i].LBALength;
-               }
-               else if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 )        // LBA 58
-               {
-                       base = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
-                       len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength;
-               }
-               else
-                       continue;
-               
-               if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) {
-                       if(extendedLBA != 0) {
-                               Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
-                               continue;
-                       }
-                       extendedLBA = base;
-                       continue;
-               }
-               // Create Partition
-               ATA_int_MakePartition(
-                       &gATA_Disks[Disk].Partitions[j], Disk, j,
-                       base, len
-                       );
-               j ++;
-               
-       }
-       // Scan extended partitions
-       while(extendedLBA != 0)
-       {
-               extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len);
-               ATA_int_MakePartition(
-                       &gATA_Disks[Disk].Partitions[j], Disk, k, base, len
-                       );
-       }
-       
-       LEAVE('-');
-}
-
-/**
- * \brief Reads an extended partition
- * \return LBA of next Extended, -1 on error, 0 for last
- */
-Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length)
-{
-       Uint64  link = 0;
-        int    bFoundPart = 0;;
-        int    i;
-       tMBR    mbr;
-       Uint64  base, len;
-       
-       if( ATA_ReadDMA( Disk, Addr, 1, &mbr ) != 0 )
-               return -1;      // Stop on Errors
-       
-       
-       for( i = 0; i < 4; i ++ )
-       {
-               if( mbr.Parts[i].SystemID == 0 )        continue;
-               
-               // LBA 24
-               if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 ) {
-                       base = mbr.Parts[i].LBAStart;
-                       len = mbr.Parts[i].LBALength;
-               }
-               // LBA 48
-               else if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 ) {
-                       base = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
-                       len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength;
-               }
-               else {
-                       Warning("Unknown partition type, Disk %i 0x%llx Part %i",
-                               Disk, Addr, i);
-                       return -1;
-               }
-               
-               switch(mbr.Parts[i].SystemID)
-               {
-               case 0xF:
-               case 0x5:
-                       if(link != 0) {
-                               Warning("Disk %i has two forward links in the extended partition",
-                                       Disk);
-                               return -1;
-                       }
-                       link = base;
-                       break;
-               default:
-                       if(bFoundPart) {
-                               Warning("Disk %i has more than one partition in the extended partition at 0x%llx",
-                                       Disk, Addr);
-                               return -1;
-                       }
-                       bFoundPart = 1;
-                       *Base = base;
-                       *Length = len;
-                       break;
-               }
-       }
-       
-       if(!bFoundPart) {
-               Warning("No partition in extended partiton, Disk %i 0x%llx",
-                       Disk, Addr);
-               return -1;
-       }
-       
-       return link;
-}
diff --git a/Modules/BochsGA/Makefile b/Modules/BochsGA/Makefile
deleted file mode 100644 (file)
index 2df219a..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-#
-
-OBJ = bochsvbe.o
-NAME = BochsGA
-
--include ../Makefile.tpl
diff --git a/Modules/BochsGA/bochsvbe.c b/Modules/BochsGA/bochsvbe.c
deleted file mode 100644 (file)
index 5fe82f5..0000000
+++ /dev/null
@@ -1,467 +0,0 @@
-/**\r
- * \file drv_bochsvbe.c\r
- * \brief BGA (Bochs Graphic Adapter) Driver\r
- * \note for Acess2\r
- * \warning This driver does NOT support the Bochs PCI VGA driver\r
-*/\r
-#define DEBUG  0\r
-#include <acess.h>\r
-#include <errno.h>\r
-#include <modules.h>\r
-#include <vfs.h>\r
-#include <fs_devfs.h>\r
-#include <drv_pci.h>\r
-#include <tpl_drv_video.h>\r
-\r
-#define INT\r
-\r
-// === TYPEDEFS ===\r
-typedef struct {\r
-       Uint16  width;\r
-       Uint16  height;\r
-       Uint16  bpp;\r
-       Uint16  flags;\r
-       Uint32  fbSize;\r
-} t_bga_mode;\r
-\r
-// === CONSTANTS ===\r
-enum eMode_Flags {\r
-       MODEFLAG_TEXT = 1\r
-};\r
-#define        BGA_LFB_MAXSIZE (1024*768*4)\r
-#define        VBE_DISPI_BANK_ADDRESS  0xA0000\r
-#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000\r
-#define VBE_DISPI_IOPORT_INDEX 0x01CE\r
-#define        VBE_DISPI_IOPORT_DATA   0x01CF\r
-#define        VBE_DISPI_DISABLED      0x00\r
-#define VBE_DISPI_ENABLED      0x01\r
-#define        VBE_DISPI_LFB_ENABLED   0x40\r
-#define        VBE_DISPI_NOCLEARMEM    0x80\r
-enum {\r
-       VBE_DISPI_INDEX_ID,\r
-       VBE_DISPI_INDEX_XRES,\r
-       VBE_DISPI_INDEX_YRES,\r
-       VBE_DISPI_INDEX_BPP,\r
-       VBE_DISPI_INDEX_ENABLE,\r
-       VBE_DISPI_INDEX_BANK,\r
-       VBE_DISPI_INDEX_VIRT_WIDTH,\r
-       VBE_DISPI_INDEX_VIRT_HEIGHT,\r
-       VBE_DISPI_INDEX_X_OFFSET,\r
-       VBE_DISPI_INDEX_Y_OFFSET\r
-};\r
-\r
-\r
-// === PROTOTYPES ===\r
-// Driver\r
- int   BGA_Install(char **Arguments);\r
-void   BGA_Uninstall();\r
-// Internal\r
-void   BGA_int_WriteRegister(Uint16 reg, Uint16 value);\r
-Uint16 BGA_int_ReadRegister(Uint16 reg);\r
-void   BGA_int_SetBank(Uint16 bank);\r
-void   BGA_int_SetMode(Uint16 width, Uint16 height);\r
- int   BGA_int_UpdateMode(int id);\r
- int   BGA_int_FindMode(tVideo_IOCtl_Mode *info);\r
- int   BGA_int_ModeInfo(tVideo_IOCtl_Mode *info);\r
- int   BGA_int_MapFB(void *Dest);\r
-// Filesystem\r
-Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
-Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
- int   BGA_Ioctl(tVFS_Node *node, int id, void *data);\r
-\r
-// === GLOBALS ===\r
-MODULE_DEFINE(0, 0x0032, BochsGA, BGA_Install, NULL, NULL);\r
-tDevFS_Driver  gBGA_DriverStruct = {\r
-       NULL, "BochsGA",\r
-       {\r
-       .Read = BGA_Read,\r
-       .Write = BGA_Write,\r
-       .IOCtl = BGA_Ioctl\r
-       }\r
-};\r
- int   giBGA_CurrentMode = -1;\r
-tVideo_IOCtl_Pos       gBGA_CursorPos = {-1,-1};\r
- int   giBGA_DriverId = -1;\r
-Uint   *gBGA_Framebuffer;\r
-t_bga_mode     gBGA_Modes[] = {\r
-       {},\r
-       { 80,25, 12, MODEFLAG_TEXT, 80*25*8},   // 640 x 480\r
-       {100,37, 12, MODEFLAG_TEXT, 100*37*8},  // 800 x 600\r
-       {640,480,8, 0, 640*480},\r
-       {640,480,32, 0, 640*480*4},\r
-       {800,600,8, 0, 800*600},\r
-       {800,600,32, 0, 800*600*4},\r
-};\r
-#define        BGA_MODE_COUNT  (sizeof(gBGA_Modes)/sizeof(gBGA_Modes[0]))\r
-\r
-// === CODE ===\r
-/**\r
- * \fn int BGA_Install(char **Arguments)\r
- */\r
-int BGA_Install(char **Arguments)\r
-{\r
-        int    bga_version = 0;\r
-       \r
-       // Check BGA Version\r
-       bga_version = BGA_int_ReadRegister(VBE_DISPI_INDEX_ID);\r
-       // NOTE: This driver was written for 0xB0C4, but they seem to be backwards compatable\r
-       if(bga_version < 0xB0C4 || bga_version > 0xB0C5) {\r
-               Warning("[BGA ] Bochs Adapter Version is not 0xB0C4 or 0xB0C5, instead 0x%x", bga_version);\r
-               return 0;\r
-       }\r
-       \r
-       // Install Device\r
-       giBGA_DriverId = DevFS_AddDevice( &gBGA_DriverStruct );\r
-       if(giBGA_DriverId == -1) {\r
-               Warning("[BGA ] Unable to register with DevFS, maybe already loaded?");\r
-               return 0;\r
-       }\r
-       \r
-       // Map Framebuffer to hardware address\r
-       gBGA_Framebuffer = (void *) MM_MapHWPage(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768);  // 768 pages (3Mb)\r
-       \r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn void BGA_Uninstall()\r
- */\r
-void BGA_Uninstall()\r
-{\r
-       //DevFS_DelDevice( giBGA_DriverId );\r
-       MM_UnmapHWPage( VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768 );\r
-}\r
-\r
-/**\r
- * \fn Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
- * \brief Read from the framebuffer\r
- */\r
-Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
-{\r
-       // Check Mode\r
-       if(giBGA_CurrentMode == -1)     return -1;\r
-       \r
-       // Check Offset and Length against Framebuffer Size\r
-       if(off+len > gBGA_Modes[giBGA_CurrentMode].fbSize)\r
-               return -1;\r
-       \r
-       // Copy from Framebuffer\r
-       memcpy(buffer, (void*)((Uint)gBGA_Framebuffer + (Uint)off), len);\r
-       return len;\r
-}\r
-\r
-/**\r
- * \fn Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
- * \brief Write to the framebuffer\r
- */\r
-Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
-{      \r
-       ENTER("xoff xlen", off, len);\r
-       \r
-       // Check Mode\r
-       if(giBGA_CurrentMode == -1) {\r
-               LEAVE('i', -1);\r
-               return -1;\r
-       }\r
-       \r
-       // Check Input against Frambuffer Size\r
-       if(off+len > gBGA_Modes[giBGA_CurrentMode].fbSize) {\r
-               LEAVE('i', -1);\r
-               return -1;\r
-       }\r
-       \r
-       // Text Mode\r
-       if( gBGA_Modes[giBGA_CurrentMode].flags & MODEFLAG_TEXT )\r
-       {\r
-               tVT_Char        *chars = buffer;\r
-                int    pitch = gBGA_Modes[giBGA_CurrentMode].width * giVT_CharWidth;\r
-                int    x, y;\r
-               Uint32  *dest;\r
-               \r
-               off /= sizeof(tVT_Char);\r
-               dest = (void*)gBGA_Framebuffer;\r
-               x = (off % gBGA_Modes[giBGA_CurrentMode].width) * giVT_CharWidth;\r
-               y = (off / gBGA_Modes[giBGA_CurrentMode].width) * giVT_CharHeight;\r
-               dest += y * pitch;\r
-               dest += x * giVT_CharWidth;\r
-               len /= sizeof(tVT_Char);\r
-               while(len--)\r
-               {\r
-                       VT_Font_Render(\r
-                               chars->Ch,\r
-                               dest, pitch,\r
-                               VT_Colour12to24(chars->BGCol),\r
-                               VT_Colour12to24(chars->FGCol)\r
-                               );\r
-                       \r
-                       dest += giVT_CharWidth;\r
-                       \r
-                       chars ++;\r
-                       x += giVT_CharWidth;\r
-                       if( x >= pitch ) {\r
-                               x = 0;\r
-                               y += giVT_CharHeight;\r
-                               dest += pitch*(giVT_CharHeight-1);\r
-                       }\r
-               }\r
-       }\r
-       else\r
-       {\r
-               Uint8   *destBuf = (Uint8*) ((Uint)gBGA_Framebuffer + (Uint)off);\r
-               \r
-               LOG("buffer = %p\n", buffer);\r
-               LOG("Updating Framebuffer (%p to %p)\n", \r
-                       destBuf, destBuf + (Uint)len);\r
-               \r
-               \r
-               // Copy to Frambuffer\r
-               memcpy(destBuf, buffer, len);\r
-               \r
-               LOG("BGA Framebuffer updated\n");\r
-       }\r
-       \r
-       LEAVE('i', len);\r
-       return len;\r
-}\r
-\r
-/**\r
- * \fn INT int BGA_Ioctl(tVFS_Node *node, int ID, void *Data)\r
- * \brief Handle messages to the device\r
- */\r
-INT int BGA_Ioctl(tVFS_Node *node, int ID, void *Data)\r
-{\r
-        int    ret = -2;\r
-       ENTER("pNode iId pData", node, ID, Data);\r
-       \r
-       switch(ID)\r
-       {\r
-       case DRV_IOCTL_TYPE:\r
-               ret = DRV_TYPE_VIDEO;\r
-               break;\r
-       case DRV_IOCTL_IDENT:\r
-               memcpy(Data, "BGA1", 4);\r
-               ret = 1;\r
-               break;\r
-       case DRV_IOCTL_VERSION:\r
-               ret = 0x100;\r
-               break;\r
-       case DRV_IOCTL_LOOKUP:  // TODO: Implement\r
-               ret = 0;\r
-               break;\r
-               \r
-       case VIDEO_IOCTL_GETSETMODE:\r
-               if( Data )\r
-                       ret = BGA_int_UpdateMode(*(int*)(Data));\r
-               else\r
-                       ret = giBGA_CurrentMode;\r
-               break;\r
-       \r
-       case VIDEO_IOCTL_FINDMODE:\r
-               ret = BGA_int_FindMode((tVideo_IOCtl_Mode*)Data);\r
-               break;\r
-       \r
-       case VIDEO_IOCTL_MODEINFO:\r
-               ret = BGA_int_ModeInfo((tVideo_IOCtl_Mode*)Data);\r
-               break;\r
-       \r
-       // Request Access to LFB\r
-       case VIDEO_IOCTL_REQLFB:\r
-               ret = BGA_int_MapFB( *(void**)Data );\r
-               break;\r
-       \r
-       case VIDEO_IOCTL_SETCURSOR:\r
-               gBGA_CursorPos.x = ((tVideo_IOCtl_Pos*)Data)->x;\r
-               gBGA_CursorPos.y = ((tVideo_IOCtl_Pos*)Data)->y;\r
-               break;\r
-       \r
-       default:\r
-               LEAVE('i', -2);\r
-               return -2;\r
-       }\r
-       \r
-       LEAVE('i', ret);\r
-       return ret;\r
-}\r
-\r
-//== Internal Functions ==\r
-/**\r
- * \fn void BGA_int_WriteRegister(Uint16 reg, Uint16 value)\r
- * \brief Writes to a BGA register\r
- */\r
-void BGA_int_WriteRegister(Uint16 reg, Uint16 value)\r
-{\r
-       outw(VBE_DISPI_IOPORT_INDEX, reg);\r
-       outw(VBE_DISPI_IOPORT_DATA, value);\r
-}\r
-\r
-INT Uint16 BGA_int_ReadRegister(Uint16 reg)\r
-{\r
-       outw(VBE_DISPI_IOPORT_INDEX, reg);\r
-       return inw(VBE_DISPI_IOPORT_DATA);\r
-}\r
-\r
-#if 0\r
-INT void BGA_int_SetBank(Uint16 bank)\r
-{\r
-       BGA_int_WriteRegister(VBE_DISPI_INDEX_BANK, bank);\r
-}\r
-#endif\r
-\r
-/**\r
- * \fn void BGA_int_SetMode(Uint16 width, Uint16 height, Uint16 bpp)\r
- * \brief Sets the video mode from the dimensions and bpp given\r
- */\r
-void BGA_int_SetMode(Uint16 width, Uint16 height)\r
-{\r
-       ENTER("iwidth iheight ibpp", width, height, bpp);\r
-       BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);\r
-    BGA_int_WriteRegister(VBE_DISPI_INDEX_XRES,        width);\r
-    BGA_int_WriteRegister(VBE_DISPI_INDEX_YRES,        height);\r
-    BGA_int_WriteRegister(VBE_DISPI_INDEX_BPP, 32);\r
-    BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM | VBE_DISPI_LFB_ENABLED);\r
-    //BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM);\r
-       LEAVE('-');\r
-}\r
-\r
-/**\r
- * \fn int BGA_int_UpdateMode(int id)\r
- * \brief Set current vide mode given a mode id\r
- */\r
-int BGA_int_UpdateMode(int id)\r
-{\r
-       // Sanity Check\r
-       if(id < 0 || id >= BGA_MODE_COUNT)      return -1;\r
-       \r
-       // Check if it is a text mode\r
-       if( gBGA_Modes[id].flags & MODEFLAG_TEXT )\r
-               BGA_int_SetMode(\r
-                       gBGA_Modes[id].width*giVT_CharWidth,\r
-                       gBGA_Modes[id].height*giVT_CharHeight);\r
-       else    // Graphics?\r
-               BGA_int_SetMode(\r
-                       gBGA_Modes[id].width,\r
-                       gBGA_Modes[id].height);\r
-       \r
-       giBGA_CurrentMode = id;\r
-       return id;\r
-}\r
-\r
-/**\r
- * \fn int BGA_int_FindMode(tVideo_IOCtl_Mode *info)\r
- * \brief Find a mode matching the given options\r
- */\r
-int BGA_int_FindMode(tVideo_IOCtl_Mode *info)\r
-{\r
-        int    i;\r
-        int    best = 0, bestFactor = 1000;\r
-        int    factor, tmp;\r
-        int    rqdProduct = info->width * info->height * info->bpp;\r
-       \r
-       ENTER("pinfo", info);\r
-       LOG("info = {width:%i,height:%i,bpp:%i})\n", info->width, info->height, info->bpp);\r
-       \r
-       for(i = 0; i < BGA_MODE_COUNT; i++)\r
-       {\r
-               #if DEBUG >= 2\r
-               LogF("Mode %i (%ix%ix%i), ", i, gBGA_Modes[i].width, gBGA_Modes[i].height, gBGA_Modes[i].bpp);\r
-               #endif\r
-               \r
-               // Check if this mode is the same type as what we want\r
-               if( !(gBGA_Modes[i].flags & MODEFLAG_TEXT) != !(info->flags & VIDEO_FLAG_TEXT) )\r
-                       continue;\r
-               \r
-               // Ooh! A perfect match\r
-               if(gBGA_Modes[i].width == info->width\r
-               && gBGA_Modes[i].height == info->height\r
-               && gBGA_Modes[i].bpp == info->bpp)\r
-               {\r
-                       #if DEBUG >= 2\r
-                       LogF("Perfect!\n");\r
-                       #endif\r
-                       best = i;\r
-                       break;\r
-               }\r
-               \r
-               // If not, how close are we?\r
-               tmp = gBGA_Modes[i].width * gBGA_Modes[i].height * gBGA_Modes[i].bpp;\r
-               tmp -= rqdProduct;\r
-               tmp = tmp < 0 ? -tmp : tmp;     // tmp = ABS(tmp)\r
-               factor = tmp * 100 / rqdProduct;\r
-               \r
-               #if DEBUG >= 2\r
-               LogF("factor = %i\n", factor);\r
-               #endif\r
-               \r
-               if(factor < bestFactor)\r
-               {\r
-                       bestFactor = factor;\r
-                       best = i;\r
-               }\r
-       }\r
-       \r
-       info->id = best;\r
-       info->width = gBGA_Modes[best].width;\r
-       info->height = gBGA_Modes[best].height;\r
-       info->bpp = gBGA_Modes[best].bpp;\r
-       \r
-       info->flags = 0;\r
-       if(gBGA_Modes[best].flags & MODEFLAG_TEXT)\r
-               info->flags |= VIDEO_FLAG_TEXT;\r
-       \r
-       return best;\r
-}\r
-\r
-/**\r
- * \fn int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info)\r
- * \brief Get mode information\r
- */\r
-int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info)\r
-{\r
-       // Sanity Check\r
-       //if( !MM_IsUser( (Uint)info, sizeof(tVideo_IOCtl_Mode) ) ) {\r
-       //      return -EINVAL;\r
-       //}\r
-       \r
-       if(info->id < 0 || info->id >= BGA_MODE_COUNT)  return -1;\r
-       \r
-       info->width = gBGA_Modes[info->id].width;\r
-       info->height = gBGA_Modes[info->id].height;\r
-       info->bpp = gBGA_Modes[info->id].bpp;\r
-       \r
-       info->flags = 0;\r
-       if(gBGA_Modes[info->id].flags & MODEFLAG_TEXT)\r
-               info->flags |= VIDEO_FLAG_TEXT;\r
-       \r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn int BGA_int_MapFB(void *Dest)\r
- * \brief Map the framebuffer into a process's space\r
- * \param Dest User address to load to\r
- */\r
-int BGA_int_MapFB(void *Dest)\r
-{\r
-       Uint    i;\r
-       Uint    pages;\r
-       \r
-       // Sanity Check\r
-       if((Uint)Dest > 0xC0000000)     return 0;\r
-       if(gBGA_Modes[giBGA_CurrentMode].bpp < 15)      return 0;       // Only non-pallete modes are supported\r
-       \r
-       // Count required pages\r
-       pages = (gBGA_Modes[giBGA_CurrentMode].fbSize + 0xFFF) >> 12;\r
-       \r
-       // Check if there is space\r
-       for( i = 0; i < pages; i++ )\r
-       {\r
-               if(MM_GetPhysAddr( (Uint)Dest + (i << 12) ))\r
-                       return 0;\r
-       }\r
-       \r
-       // Map\r
-       for( i = 0; i < pages; i++ )\r
-               MM_Map( (Uint)Dest + (i<<12), VBE_DISPI_LFB_PHYSICAL_ADDRESS + (i<<12) );\r
-       \r
-       return 1;\r
-}\r
diff --git a/Modules/Display/BochsGA/Makefile b/Modules/Display/BochsGA/Makefile
new file mode 100644 (file)
index 0000000..2df219a
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = bochsvbe.o
+NAME = BochsGA
+
+-include ../Makefile.tpl
diff --git a/Modules/Display/BochsGA/bochsvbe.c b/Modules/Display/BochsGA/bochsvbe.c
new file mode 100644 (file)
index 0000000..06d362c
--- /dev/null
@@ -0,0 +1,467 @@
+/**\r
+ * \file drv_bochsvbe.c\r
+ * \brief BGA (Bochs Graphic Adapter) Driver\r
+ * \note for Acess2\r
+ * \warning This driver does NOT support the Bochs PCI VGA driver\r
+*/\r
+#define DEBUG  0\r
+#include <acess.h>\r
+#include <errno.h>\r
+#include <modules.h>\r
+#include <vfs.h>\r
+#include <fs_devfs.h>\r
+#include <drv_pci.h>\r
+#include <tpl_drv_video.h>\r
+\r
+#define INT\r
+\r
+// === TYPEDEFS ===\r
+typedef struct {\r
+       Uint16  width;\r
+       Uint16  height;\r
+       Uint16  bpp;\r
+       Uint16  flags;\r
+       Uint32  fbSize;\r
+} t_bga_mode;\r
+\r
+// === CONSTANTS ===\r
+enum eMode_Flags {\r
+       MODEFLAG_TEXT = 1\r
+};\r
+#define        BGA_LFB_MAXSIZE (1024*768*4)\r
+#define        VBE_DISPI_BANK_ADDRESS  0xA0000\r
+#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000\r
+#define VBE_DISPI_IOPORT_INDEX 0x01CE\r
+#define        VBE_DISPI_IOPORT_DATA   0x01CF\r
+#define        VBE_DISPI_DISABLED      0x00\r
+#define VBE_DISPI_ENABLED      0x01\r
+#define        VBE_DISPI_LFB_ENABLED   0x40\r
+#define        VBE_DISPI_NOCLEARMEM    0x80\r
+enum {\r
+       VBE_DISPI_INDEX_ID,\r
+       VBE_DISPI_INDEX_XRES,\r
+       VBE_DISPI_INDEX_YRES,\r
+       VBE_DISPI_INDEX_BPP,\r
+       VBE_DISPI_INDEX_ENABLE,\r
+       VBE_DISPI_INDEX_BANK,\r
+       VBE_DISPI_INDEX_VIRT_WIDTH,\r
+       VBE_DISPI_INDEX_VIRT_HEIGHT,\r
+       VBE_DISPI_INDEX_X_OFFSET,\r
+       VBE_DISPI_INDEX_Y_OFFSET\r
+};\r
+\r
+\r
+// === PROTOTYPES ===\r
+// Driver\r
+ int   BGA_Install(char **Arguments);\r
+void   BGA_Uninstall();\r
+// Internal\r
+void   BGA_int_WriteRegister(Uint16 reg, Uint16 value);\r
+Uint16 BGA_int_ReadRegister(Uint16 reg);\r
+void   BGA_int_SetBank(Uint16 bank);\r
+void   BGA_int_SetMode(Uint16 width, Uint16 height);\r
+ int   BGA_int_UpdateMode(int id);\r
+ int   BGA_int_FindMode(tVideo_IOCtl_Mode *info);\r
+ int   BGA_int_ModeInfo(tVideo_IOCtl_Mode *info);\r
+ int   BGA_int_MapFB(void *Dest);\r
+// Filesystem\r
+Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
+Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
+ int   BGA_Ioctl(tVFS_Node *node, int id, void *data);\r
+\r
+// === GLOBALS ===\r
+MODULE_DEFINE(0, 0x0032, BochsGA, BGA_Install, NULL, NULL);\r
+tDevFS_Driver  gBGA_DriverStruct = {\r
+       NULL, "BochsGA",\r
+       {\r
+       .Read = BGA_Read,\r
+       .Write = BGA_Write,\r
+       .IOCtl = BGA_Ioctl\r
+       }\r
+};\r
+ int   giBGA_CurrentMode = -1;\r
+tVideo_IOCtl_Pos       gBGA_CursorPos = {-1,-1};\r
+ int   giBGA_DriverId = -1;\r
+Uint   *gBGA_Framebuffer;\r
+t_bga_mode     gBGA_Modes[] = {\r
+       {},\r
+       { 80,25, 12, MODEFLAG_TEXT, 80*25*8},   // 640 x 480\r
+       {100,37, 12, MODEFLAG_TEXT, 100*37*8},  // 800 x 600\r
+       {640,480,8, 0, 640*480},\r
+       {640,480,32, 0, 640*480*4},\r
+       {800,600,8, 0, 800*600},\r
+       {800,600,32, 0, 800*600*4},\r
+};\r
+#define        BGA_MODE_COUNT  (sizeof(gBGA_Modes)/sizeof(gBGA_Modes[0]))\r
+\r
+// === CODE ===\r
+/**\r
+ * \fn int BGA_Install(char **Arguments)\r
+ */\r
+int BGA_Install(char **Arguments)\r
+{\r
+        int    bga_version = 0;\r
+       \r
+       // Check BGA Version\r
+       bga_version = BGA_int_ReadRegister(VBE_DISPI_INDEX_ID);\r
+       // NOTE: This driver was written for 0xB0C4, but they seem to be backwards compatable\r
+       if(bga_version < 0xB0C4 || bga_version > 0xB0C5) {\r
+               Warning("[BGA ] Bochs Adapter Version is not 0xB0C4 or 0xB0C5, instead 0x%x", bga_version);\r
+               return 0;\r
+       }\r
+       \r
+       // Install Device\r
+       giBGA_DriverId = DevFS_AddDevice( &gBGA_DriverStruct );\r
+       if(giBGA_DriverId == -1) {\r
+               Warning("[BGA ] Unable to register with DevFS, maybe already loaded?");\r
+               return 0;\r
+       }\r
+       \r
+       // Map Framebuffer to hardware address\r
+       gBGA_Framebuffer = (void *) MM_MapHWPage(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768);  // 768 pages (3Mb)\r
+       \r
+       return 1;\r
+}\r
+\r
+/**\r
+ * \fn void BGA_Uninstall()\r
+ */\r
+void BGA_Uninstall()\r
+{\r
+       //DevFS_DelDevice( giBGA_DriverId );\r
+       MM_UnmapHWPage( VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768 );\r
+}\r
+\r
+/**\r
+ * \fn Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
+ * \brief Read from the framebuffer\r
+ */\r
+Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
+{\r
+       // Check Mode\r
+       if(giBGA_CurrentMode == -1)     return -1;\r
+       \r
+       // Check Offset and Length against Framebuffer Size\r
+       if(off+len > gBGA_Modes[giBGA_CurrentMode].fbSize)\r
+               return -1;\r
+       \r
+       // Copy from Framebuffer\r
+       memcpy(buffer, (void*)((Uint)gBGA_Framebuffer + (Uint)off), len);\r
+       return len;\r
+}\r
+\r
+/**\r
+ * \fn Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
+ * \brief Write to the framebuffer\r
+ */\r
+Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *Buffer)\r
+{      \r
+       ENTER("xoff xlen", off, len);\r
+       \r
+       // Check Mode\r
+       if(giBGA_CurrentMode == -1) {\r
+               LEAVE('i', -1);\r
+               return -1;\r
+       }\r
+       \r
+       // Check Input against Frambuffer Size\r
+       if(off + len > gBGA_Modes[giBGA_CurrentMode].fbSize) {\r
+               LEAVE('i', -1);\r
+               return -1;\r
+       }\r
+       \r
+       // Text Mode\r
+       if( gBGA_Modes[giBGA_CurrentMode].flags & MODEFLAG_TEXT )\r
+       {\r
+               tVT_Char        *chars = Buffer;\r
+                int    pitch = gBGA_Modes[giBGA_CurrentMode].width * giVT_CharWidth;\r
+                int    x, y;\r
+               Uint32  *dest;\r
+               \r
+               off /= sizeof(tVT_Char);\r
+               dest = (void*)gBGA_Framebuffer;\r
+               x = (off % gBGA_Modes[giBGA_CurrentMode].width) * giVT_CharWidth;\r
+               y = (off / gBGA_Modes[giBGA_CurrentMode].width) * giVT_CharHeight;\r
+               dest += y * pitch;\r
+               dest += x * giVT_CharWidth;\r
+               len /= sizeof(tVT_Char);\r
+               while(len--)\r
+               {\r
+                       VT_Font_Render(\r
+                               chars->Ch,\r
+                               dest, pitch,\r
+                               VT_Colour12to24(chars->BGCol),\r
+                               VT_Colour12to24(chars->FGCol)\r
+                               );\r
+                       \r
+                       dest += giVT_CharWidth;\r
+                       \r
+                       chars ++;\r
+                       x += giVT_CharWidth;\r
+                       if( x >= pitch ) {\r
+                               x = 0;\r
+                               y += giVT_CharHeight;\r
+                               dest += pitch*(giVT_CharHeight-1);\r
+                       }\r
+               }\r
+       }\r
+       else\r
+       {\r
+               Uint8   *destBuf = (Uint8*) ((Uint)gBGA_Framebuffer + (Uint)off);\r
+               \r
+               Log("buffer = %p", Buffer);\r
+               Log("Updating Framebuffer (%p to %p)",\r
+                       destBuf, destBuf + (Uint)len);\r
+               \r
+               \r
+               // Copy to Frambuffer\r
+               memcpy(destBuf, Buffer, len);\r
+               \r
+               Log("BGA Framebuffer updated");\r
+       }\r
+       \r
+       LEAVE('i', len);\r
+       return len;\r
+}\r
+\r
+/**\r
+ * \fn INT int BGA_Ioctl(tVFS_Node *node, int ID, void *Data)\r
+ * \brief Handle messages to the device\r
+ */\r
+INT int BGA_Ioctl(tVFS_Node *node, int ID, void *Data)\r
+{\r
+        int    ret = -2;\r
+       ENTER("pNode iId pData", node, ID, Data);\r
+       \r
+       switch(ID)\r
+       {\r
+       case DRV_IOCTL_TYPE:\r
+               ret = DRV_TYPE_VIDEO;\r
+               break;\r
+       case DRV_IOCTL_IDENT:\r
+               memcpy(Data, "BGA1", 4);\r
+               ret = 1;\r
+               break;\r
+       case DRV_IOCTL_VERSION:\r
+               ret = 0x100;\r
+               break;\r
+       case DRV_IOCTL_LOOKUP:  // TODO: Implement\r
+               ret = 0;\r
+               break;\r
+               \r
+       case VIDEO_IOCTL_GETSETMODE:\r
+               if( Data )\r
+                       ret = BGA_int_UpdateMode(*(int*)(Data));\r
+               else\r
+                       ret = giBGA_CurrentMode;\r
+               break;\r
+       \r
+       case VIDEO_IOCTL_FINDMODE:\r
+               ret = BGA_int_FindMode((tVideo_IOCtl_Mode*)Data);\r
+               break;\r
+       \r
+       case VIDEO_IOCTL_MODEINFO:\r
+               ret = BGA_int_ModeInfo((tVideo_IOCtl_Mode*)Data);\r
+               break;\r
+       \r
+       // Request Access to LFB\r
+       case VIDEO_IOCTL_REQLFB:\r
+               ret = BGA_int_MapFB( *(void**)Data );\r
+               break;\r
+       \r
+       case VIDEO_IOCTL_SETCURSOR:\r
+               gBGA_CursorPos.x = ((tVideo_IOCtl_Pos*)Data)->x;\r
+               gBGA_CursorPos.y = ((tVideo_IOCtl_Pos*)Data)->y;\r
+               break;\r
+       \r
+       default:\r
+               LEAVE('i', -2);\r
+               return -2;\r
+       }\r
+       \r
+       LEAVE('i', ret);\r
+       return ret;\r
+}\r
+\r
+//== Internal Functions ==\r
+/**\r
+ * \fn void BGA_int_WriteRegister(Uint16 reg, Uint16 value)\r
+ * \brief Writes to a BGA register\r
+ */\r
+void BGA_int_WriteRegister(Uint16 reg, Uint16 value)\r
+{\r
+       outw(VBE_DISPI_IOPORT_INDEX, reg);\r
+       outw(VBE_DISPI_IOPORT_DATA, value);\r
+}\r
+\r
+INT Uint16 BGA_int_ReadRegister(Uint16 reg)\r
+{\r
+       outw(VBE_DISPI_IOPORT_INDEX, reg);\r
+       return inw(VBE_DISPI_IOPORT_DATA);\r
+}\r
+\r
+#if 0\r
+INT void BGA_int_SetBank(Uint16 bank)\r
+{\r
+       BGA_int_WriteRegister(VBE_DISPI_INDEX_BANK, bank);\r
+}\r
+#endif\r
+\r
+/**\r
+ * \fn void BGA_int_SetMode(Uint16 width, Uint16 height, Uint16 bpp)\r
+ * \brief Sets the video mode from the dimensions and bpp given\r
+ */\r
+void BGA_int_SetMode(Uint16 width, Uint16 height)\r
+{\r
+       ENTER("iwidth iheight ibpp", width, height, bpp);\r
+       BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);\r
+    BGA_int_WriteRegister(VBE_DISPI_INDEX_XRES,        width);\r
+    BGA_int_WriteRegister(VBE_DISPI_INDEX_YRES,        height);\r
+    BGA_int_WriteRegister(VBE_DISPI_INDEX_BPP, 32);\r
+    BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM | VBE_DISPI_LFB_ENABLED);\r
+    //BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM);\r
+       LEAVE('-');\r
+}\r
+\r
+/**\r
+ * \fn int BGA_int_UpdateMode(int id)\r
+ * \brief Set current vide mode given a mode id\r
+ */\r
+int BGA_int_UpdateMode(int id)\r
+{\r
+       // Sanity Check\r
+       if(id < 0 || id >= BGA_MODE_COUNT)      return -1;\r
+       \r
+       // Check if it is a text mode\r
+       if( gBGA_Modes[id].flags & MODEFLAG_TEXT )\r
+               BGA_int_SetMode(\r
+                       gBGA_Modes[id].width*giVT_CharWidth,\r
+                       gBGA_Modes[id].height*giVT_CharHeight);\r
+       else    // Graphics?\r
+               BGA_int_SetMode(\r
+                       gBGA_Modes[id].width,\r
+                       gBGA_Modes[id].height);\r
+       \r
+       giBGA_CurrentMode = id;\r
+       return id;\r
+}\r
+\r
+/**\r
+ * \fn int BGA_int_FindMode(tVideo_IOCtl_Mode *info)\r
+ * \brief Find a mode matching the given options\r
+ */\r
+int BGA_int_FindMode(tVideo_IOCtl_Mode *info)\r
+{\r
+        int    i;\r
+        int    best = 0, bestFactor = 1000;\r
+        int    factor, tmp;\r
+        int    rqdProduct = info->width * info->height * info->bpp;\r
+       \r
+       ENTER("pinfo", info);\r
+       LOG("info = {width:%i,height:%i,bpp:%i})\n", info->width, info->height, info->bpp);\r
+       \r
+       for(i = 0; i < BGA_MODE_COUNT; i++)\r
+       {\r
+               #if DEBUG >= 2\r
+               LogF("Mode %i (%ix%ix%i), ", i, gBGA_Modes[i].width, gBGA_Modes[i].height, gBGA_Modes[i].bpp);\r
+               #endif\r
+               \r
+               // Check if this mode is the same type as what we want\r
+               if( !(gBGA_Modes[i].flags & MODEFLAG_TEXT) != !(info->flags & VIDEO_FLAG_TEXT) )\r
+                       continue;\r
+               \r
+               // Ooh! A perfect match\r
+               if(gBGA_Modes[i].width == info->width\r
+               && gBGA_Modes[i].height == info->height\r
+               && gBGA_Modes[i].bpp == info->bpp)\r
+               {\r
+                       #if DEBUG >= 2\r
+                       LogF("Perfect!\n");\r
+                       #endif\r
+                       best = i;\r
+                       break;\r
+               }\r
+               \r
+               // If not, how close are we?\r
+               tmp = gBGA_Modes[i].width * gBGA_Modes[i].height * gBGA_Modes[i].bpp;\r
+               tmp -= rqdProduct;\r
+               tmp = tmp < 0 ? -tmp : tmp;     // tmp = ABS(tmp)\r
+               factor = tmp * 100 / rqdProduct;\r
+               \r
+               #if DEBUG >= 2\r
+               LogF("factor = %i\n", factor);\r
+               #endif\r
+               \r
+               if(factor < bestFactor)\r
+               {\r
+                       bestFactor = factor;\r
+                       best = i;\r
+               }\r
+       }\r
+       \r
+       info->id = best;\r
+       info->width = gBGA_Modes[best].width;\r
+       info->height = gBGA_Modes[best].height;\r
+       info->bpp = gBGA_Modes[best].bpp;\r
+       \r
+       info->flags = 0;\r
+       if(gBGA_Modes[best].flags & MODEFLAG_TEXT)\r
+               info->flags |= VIDEO_FLAG_TEXT;\r
+       \r
+       return best;\r
+}\r
+\r
+/**\r
+ * \fn int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info)\r
+ * \brief Get mode information\r
+ */\r
+int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info)\r
+{\r
+       // Sanity Check\r
+       //if( !MM_IsUser( (Uint)info, sizeof(tVideo_IOCtl_Mode) ) ) {\r
+       //      return -EINVAL;\r
+       //}\r
+       \r
+       if(info->id < 0 || info->id >= BGA_MODE_COUNT)  return -1;\r
+       \r
+       info->width = gBGA_Modes[info->id].width;\r
+       info->height = gBGA_Modes[info->id].height;\r
+       info->bpp = gBGA_Modes[info->id].bpp;\r
+       \r
+       info->flags = 0;\r
+       if(gBGA_Modes[info->id].flags & MODEFLAG_TEXT)\r
+               info->flags |= VIDEO_FLAG_TEXT;\r
+       \r
+       return 1;\r
+}\r
+\r
+/**\r
+ * \fn int BGA_int_MapFB(void *Dest)\r
+ * \brief Map the framebuffer into a process's space\r
+ * \param Dest User address to load to\r
+ */\r
+int BGA_int_MapFB(void *Dest)\r
+{\r
+       Uint    i;\r
+       Uint    pages;\r
+       \r
+       // Sanity Check\r
+       if((Uint)Dest > 0xC0000000)     return 0;\r
+       if(gBGA_Modes[giBGA_CurrentMode].bpp < 15)      return 0;       // Only non-pallete modes are supported\r
+       \r
+       // Count required pages\r
+       pages = (gBGA_Modes[giBGA_CurrentMode].fbSize + 0xFFF) >> 12;\r
+       \r
+       // Check if there is space\r
+       for( i = 0; i < pages; i++ )\r
+       {\r
+               if(MM_GetPhysAddr( (Uint)Dest + (i << 12) ))\r
+                       return 0;\r
+       }\r
+       \r
+       // Map\r
+       for( i = 0; i < pages; i++ )\r
+               MM_Map( (Uint)Dest + (i<<12), VBE_DISPI_LFB_PHYSICAL_ADDRESS + (i<<12) );\r
+       \r
+       return 1;\r
+}\r
diff --git a/Modules/Display/Makefile.tpl b/Modules/Display/Makefile.tpl
new file mode 100644 (file)
index 0000000..80c6d4d
--- /dev/null
@@ -0,0 +1 @@
+-include ../../Makefile.tpl
diff --git a/Modules/FDD/Makefile b/Modules/FDD/Makefile
deleted file mode 100644 (file)
index 1596553..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-#
-
-OBJ = fdd.o
-NAME = FDD
-
--include ../Makefile.tpl
diff --git a/Modules/FDD/fdd.c b/Modules/FDD/fdd.c
deleted file mode 100644 (file)
index 6b55f17..0000000
+++ /dev/null
@@ -1,849 +0,0 @@
-/*\r
- * AcessOS 0.1\r
- * Floppy Disk Access Code\r
- */\r
-#define DEBUG  0\r
-#include <acess.h>\r
-#include <modules.h>\r
-#include <fs_devfs.h>\r
-#include <tpl_drv_disk.h>\r
-#include <dma.h>\r
-#include <iocache.h>\r
-\r
-#define WARN   0\r
-\r
-// === CONSTANTS ===\r
-// --- Current Version\r
-#define FDD_VERSION     ((0<<8)|(75))\r
-\r
-// --- Options\r
-#define USE_CACHE      0       // Use Sector Cache\r
-#define        CACHE_SIZE      32      // Number of cachable sectors\r
-#define FDD_SEEK_TIMEOUT       10      // Timeout for a seek operation\r
-#define MOTOR_ON_DELAY 500             // Miliseconds\r
-#define MOTOR_OFF_DELAY        2000    // Miliseconds\r
-\r
-// === TYPEDEFS ===\r
-/**\r
- * \brief Representation of a floppy drive\r
- */\r
-typedef struct {\r
-        int    type;\r
-       volatile int    motorState;     //2 - On, 1 - Spinup, 0 - Off\r
-        int    track[2];\r
-        int    timer;\r
-       tVFS_Node       Node;\r
-       #if !USE_CACHE\r
-       tIOCache        *CacheHandle;\r
-       #endif\r
-} t_floppyDevice;\r
-\r
-/**\r
- * \brief Cached Sector\r
- */\r
-typedef struct {\r
-       Uint64  timestamp;\r
-       Uint16  disk;\r
-       Uint16  sector; // Allows 32Mb of addressable space (Plenty for FDD)\r
-       Uint8   data[512];\r
-} t_floppySector;\r
-\r
-// === CONSTANTS ===\r
-static const char      *cFDD_TYPES[] = {"None", "360kB 5.25\"", "1.2MB 5.25\"", "720kB 3.5\"", "1.44MB 3.5\"", "2.88MB 3.5\"" };\r
-static const int       cFDD_SIZES[] = { 0, 360*1024, 1200*1024, 720*1024, 1440*1024, 2880*1024 };\r
-static const short     cPORTBASE[] = { 0x3F0, 0x370 };\r
-\r
-enum FloppyPorts {\r
-       PORT_STATUSA    = 0x0,\r
-       PORT_STATUSB    = 0x1,\r
-       PORT_DIGOUTPUT  = 0x2,\r
-       PORT_MAINSTATUS = 0x4,\r
-       PORT_DATARATE   = 0x4,\r
-       PORT_DATA               = 0x5,\r
-       PORT_DIGINPUT   = 0x7,\r
-       PORT_CONFIGCTRL = 0x7\r
-};\r
-\r
-enum FloppyCommands {\r
-       FIX_DRIVE_DATA  = 0x03,\r
-       HECK_DRIVE_STATUS       = 0x04,\r
-       CALIBRATE_DRIVE = 0x07,\r
-       CHECK_INTERRUPT_STATUS = 0x08,\r
-       SEEK_TRACK              = 0x0F,\r
-       READ_SECTOR_ID  = 0x4A,\r
-       FORMAT_TRACK    = 0x4D,\r
-       READ_TRACK              = 0x42,\r
-       READ_SECTOR             = 0x66,\r
-       WRITE_SECTOR    = 0xC5,\r
-       WRITE_DELETE_SECTOR     = 0xC9,\r
-       READ_DELETE_SECTOR      = 0xCC,\r
-};\r
-\r
-// === PROTOTYPES ===\r
-// --- Filesystem\r
- int   FDD_Install(char **Arguments);\r
-char   *FDD_ReadDir(tVFS_Node *Node, int pos);\r
-tVFS_Node      *FDD_FindDir(tVFS_Node *dirNode, char *Name);\r
- int   FDD_IOCtl(tVFS_Node *Node, int ID, void *Data);\r
-Uint64 FDD_ReadFS(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
-// --- 1st Level Disk Access\r
-Uint   FDD_ReadSectors(Uint64 SectorAddr, Uint Count, void *Buffer, Uint Disk);\r
-// --- Raw Disk Access\r
- int   FDD_ReadSector(Uint32 disk, Uint64 lba, void *Buffer);\r
- int   FDD_WriteSector(Uint32 Disk, Uint64 LBA, void *Buffer);\r
-// --- Helpers\r
-void   FDD_IRQHandler(int Num);\r
-void   FDD_WaitIRQ();\r
-void   FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl);\r
-inline void    FDD_AquireSpinlock();\r
-inline void    FDD_FreeSpinlock();\r
-#if USE_CACHE\r
-inline void FDD_AquireCacheSpinlock();\r
-inline void FDD_FreeCacheSpinlock();\r
-#endif\r
-void   FDD_int_SendByte(int base, char byte);\r
- int   FDD_int_GetByte(int base);\r
-void   FDD_Reset(int id);\r
-void   FDD_Recalibrate(int disk);\r
- int   FDD_int_SeekTrack(int disk, int head, int track);\r
-void   FDD_int_TimerCallback(int arg);\r
-void   FDD_int_StopMotor(int disk);\r
-void   FDD_int_StartMotor(int disk);\r
- int   FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt);\r
-\r
-// === GLOBALS ===\r
-MODULE_DEFINE(0, FDD_VERSION, FDD, FDD_Install, NULL, NULL);\r
-t_floppyDevice gFDD_Devices[2];\r
-volatile int   fdd_inUse = 0;\r
-volatile int   fdd_irq6 = 0;\r
-tDevFS_Driver  gFDD_DriverInfo = {\r
-       NULL, "fdd",\r
-       {\r
-       .Size = -1,\r
-       .NumACLs = 1,\r
-       .ACLs = &gVFS_ACL_EveryoneRX,\r
-       .Flags = VFS_FFLAG_DIRECTORY,\r
-       .ReadDir = FDD_ReadDir,\r
-       .FindDir = FDD_FindDir,\r
-       .IOCtl = FDD_IOCtl\r
-       }\r
-};\r
-#if USE_CACHE\r
-int    siFDD_CacheInUse = 0;\r
-int    siFDD_SectorCacheSize = CACHE_SIZE;\r
-t_floppySector sFDD_SectorCache[CACHE_SIZE];\r
-#endif\r
-\r
-// === CODE ===\r
-/**\r
- * \fn int FDD_Install(char **Arguments)\r
- * \brief Installs floppy driver\r
- */\r
-int FDD_Install(char **Arguments)\r
-{\r
-       Uint8 data;\r
-       \r
-       // Determine Floppy Types (From CMOS)\r
-       outb(0x70, 0x10);\r
-       data = inb(0x71);\r
-       gFDD_Devices[0].type = data >> 4;\r
-       gFDD_Devices[1].type = data & 0xF;\r
-       gFDD_Devices[0].track[0] = -1;\r
-       gFDD_Devices[1].track[1] = -1;\r
-       \r
-       Log("[FDD ] Detected Disk 0: %s and Disk 1: %s", cFDD_TYPES[data>>4], cFDD_TYPES[data&0xF]);\r
-       \r
-       // Clear FDD IRQ Flag\r
-       FDD_SensInt(0x3F0, NULL, NULL);\r
-       // Install IRQ6 Handler\r
-       IRQ_AddHandler(6, FDD_IRQHandler);\r
-       // Reset Primary FDD Controller\r
-       FDD_Reset(0);\r
-       \r
-       // Initialise Root Node\r
-       gFDD_DriverInfo.RootNode.CTime = gFDD_DriverInfo.RootNode.MTime\r
-               = gFDD_DriverInfo.RootNode.ATime = now();\r
-       \r
-       // Initialise Child Nodes\r
-       gFDD_Devices[0].Node.Inode = 0;\r
-       gFDD_Devices[0].Node.Flags = 0;\r
-       gFDD_Devices[0].Node.NumACLs = 0;\r
-       gFDD_Devices[0].Node.Read = FDD_ReadFS;\r
-       gFDD_Devices[0].Node.Write = NULL;//fdd_writeFS;\r
-       memcpy(&gFDD_Devices[1].Node, &gFDD_Devices[0].Node, sizeof(tVFS_Node));\r
-       \r
-       gFDD_Devices[1].Node.Inode = 1;\r
-       \r
-       // Set Lengths\r
-       gFDD_Devices[0].Node.Size = cFDD_SIZES[data >> 4];\r
-       gFDD_Devices[1].Node.Size = cFDD_SIZES[data & 0xF];\r
-       \r
-       // Create Sector Cache\r
-       #if USE_CACHE\r
-       //sFDD_SectorCache = malloc(sizeof(*sFDD_SectorCache)*CACHE_SIZE);\r
-       //siFDD_SectorCacheSize = CACHE_SIZE;\r
-       #else\r
-       if( cFDD_SIZES[data >> 4] ) {\r
-               gFDD_Devices[0].CacheHandle = IOCache_Create(\r
-                       FDD_WriteSector, 0, 512,\r
-                       gFDD_Devices[0].Node.Size / (512*4)\r
-                       );      // Cache is 1/4 the size of the disk\r
-       }\r
-       if( cFDD_SIZES[data & 15] ) {\r
-               gFDD_Devices[1].CacheHandle = IOCache_Create(\r
-                       FDD_WriteSector, 0, 512,\r
-                       gFDD_Devices[1].Node.Size / (512*4)\r
-                       );      // Cache is 1/4 the size of the disk\r
-       }\r
-       #endif\r
-       \r
-       // Register with devfs\r
-       DevFS_AddDevice(&gFDD_DriverInfo);\r
-       \r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn char *FDD_ReadDir(tVFS_Node *Node, int pos)\r
- * \brief Read Directory\r
- */\r
-char *FDD_ReadDir(tVFS_Node *Node, int pos)\r
-{\r
-       char    name[2] = "0\0";\r
-       //Update Accessed Time\r
-       //gFDD_DrvInfo.rootNode.atime = now();\r
-       \r
-       //Check for bounds\r
-       if(pos >= 2 || pos < 0)\r
-               return NULL;\r
-       \r
-       if(gFDD_Devices[pos].type == 0)\r
-               return VFS_SKIP;\r
-       \r
-       name[0] += pos;\r
-       \r
-       //Return\r
-       return strdup(name);\r
-}\r
-\r
-/**\r
- * \fn tVFS_Node *FDD_FindDir(tVFS_Node *Node, char *filename);\r
- * \brief Find File Routine (for vfs_node)\r
- */\r
-tVFS_Node *FDD_FindDir(tVFS_Node *Node, char *Filename)\r
-{\r
-        int    i;\r
-       \r
-       ENTER("sFilename", Filename);\r
-       \r
-       // Sanity check string\r
-       if(Filename == NULL) {\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       \r
-       // Check string length (should be 1)\r
-       if(Filename[0] == '\0' || Filename[1] != '\0') {\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       \r
-       // Get First character\r
-       i = Filename[0] - '0';\r
-       \r
-       // Check for 1st disk and if it is present return\r
-       if(i == 0 && gFDD_Devices[0].type != 0) {\r
-               LEAVE('p', &gFDD_Devices[0].Node);\r
-               return &gFDD_Devices[0].Node;\r
-       }\r
-       \r
-       // Check for 2nd disk and if it is present return\r
-       if(i == 1 && gFDD_Devices[1].type != 0) {\r
-               LEAVE('p', &gFDD_Devices[1].Node);\r
-               return &gFDD_Devices[1].Node;\r
-       }\r
-       \r
-       // Else return null\r
-       LEAVE('n');\r
-       return NULL;\r
-}\r
-\r
-static const char      *casIOCTLS[] = {DRV_IOCTLNAMES,DRV_DISK_IOCTLNAMES,NULL};\r
-/**\r
- * \fn int FDD_IOCtl(tVFS_Node *Node, int id, void *data)\r
- * \brief Stub ioctl function\r
- */\r
-int FDD_IOCtl(tVFS_Node *Node, int ID, void *Data)\r
-{\r
-       switch(ID)\r
-       {\r
-       case DRV_IOCTL_TYPE:    return DRV_TYPE_DISK;\r
-       case DRV_IOCTL_IDENT:   return ModUtil_SetIdent(Data, "FDD");\r
-       case DRV_IOCTL_VERSION: return FDD_VERSION;\r
-       case DRV_IOCTL_LOOKUP:  return ModUtil_LookupString((char**)casIOCTLS, Data);\r
-       \r
-       case DISK_IOCTL_GETBLOCKSIZE:   return 512;     \r
-       \r
-       default:\r
-               return 0;\r
-       }\r
-}\r
-\r
-/**\r
- * \fn Uint64 FDD_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
- * \brief Read Data from a disk\r
-*/\r
-Uint64 FDD_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
-{\r
-        int    i = 0;\r
-        int    disk;\r
-       //Uint32        buf[128];\r
-       \r
-       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);\r
-       \r
-       if(Node == NULL) {\r
-               LEAVE('i', -1);\r
-               return -1;\r
-       }\r
-       \r
-       if(Node->Inode != 0 && Node->Inode != 1) {\r
-               LEAVE('i', -1);\r
-               return -1;\r
-       }\r
-       \r
-       disk = Node->Inode;\r
-       \r
-       // Update Accessed Time\r
-       Node->ATime = now();\r
-       \r
-       #if 0\r
-       if((Offset & 0x1FF) || (Length & 0x1FF))\r
-       {\r
-               // Un-Aligned Offset/Length\r
-                int    startOff = Offset >> 9;\r
-                int    sectOff = Offset & 0x1FF;\r
-                int    sectors = (Length + 0x1FF) >> 9;\r
-       \r
-               LOG("Non-aligned Read");\r
-               \r
-               //Read Starting Sector\r
-               if(!FDD_ReadSector(disk, startOff, buf))\r
-                       return 0;\r
-               memcpy(Buffer, (char*)(buf+sectOff), Length > 512-sectOff ? 512-sectOff : Length);\r
-               \r
-               // If the data size is one sector or less\r
-               if(Length <= 512-sectOff)\r
-               {\r
-                       LEAVE('X', Length);\r
-                       return Length;  //Return\r
-               }\r
-               Buffer += 512-sectOff;\r
-       \r
-               //Read Middle Sectors\r
-               for( i = 1; i < sectors - 1; i++ )\r
-               {\r
-                       if(!FDD_ReadSector(disk, startOff+i, buf)) {\r
-                               LEAVE('i', -1);\r
-                               return -1;\r
-                       }\r
-                       memcpy(Buffer, buf, 512);\r
-                       Buffer += 512;\r
-               }\r
-       \r
-               //Read End Sectors\r
-               if(!FDD_ReadSector(disk, startOff+i, buf))\r
-                       return 0;\r
-               memcpy(Buffer, buf, (len&0x1FF)-sectOff);\r
-               
-               LEAVE('X', Length);\r
-               return Length;\r
-       }\r
-       else\r
-       {\r
-                int    count = Length >> 9;\r
-                int    sector = Offset >> 9;\r
-               LOG("Aligned Read");\r
-               //Aligned Offset and Length - Simple Code\r
-               for( i = 0; i < count; i ++ )\r
-               {\r
-                       FDD_ReadSector(disk, sector, buf);\r
-                       memcpy(buffer, buf, 512);\r
-                       buffer += 512;\r
-                       sector++;\r
-               }
-               LEAVE('i', Length);\r
-               return Length;\r
-       }\r
-       #endif\r
-       \r
-       i = DrvUtil_ReadBlock(Offset, Length, Buffer, FDD_ReadSectors, 512, disk);\r
-       LEAVE('i', i);\r
-       return i;\r
-}\r
-\r
-/**\r
- * \fn Uint FDD_ReadSectors(Uint64 SectorAddr, Uint Count, void *Buffer, Uint32 Disk)\r
- * \brief Reads \a Count contiguous sectors from a disk\r
- * \param SectorAddr   Address of the first sector\r
- * \param Count        Number of sectors to read\r
- * \param Buffer       Destination Buffer\r
- * \param Disk Disk Number\r
- * \return Number of sectors read\r
- * \note Used as a ::DrvUtil_ReadBlock helper\r
- */\r
-Uint FDD_ReadSectors(Uint64 SectorAddr, Uint Count, void *Buffer, Uint Disk)\r
-{\r
-       Uint    ret = 0;\r
-       while(Count --)\r
-       {\r
-               if( FDD_ReadSector(Disk, SectorAddr, Buffer) != 1 )\r
-                       return ret;\r
-               \r
-               Buffer = (void*)( (tVAddr)Buffer + 512 );\r
-               SectorAddr ++;\r
-               ret ++;\r
-       }\r
-       return ret;\r
-}\r
-\r
-/**\r
- * \fn int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer)\r
- * \fn Read a sector from disk\r
-*/\r
-int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer)\r
-{\r
-        int    cyl, head, sec;\r
-        int    spt, base;\r
-        int    i;\r
-        int    lba = SectorAddr;\r
-       \r
-       ENTER("idisk Xlba pbuf", disk, lba, buf);\r
-       \r
-       #if USE_CACHE\r
-       FDD_AquireCacheSpinlock();\r
-       for( i = 0; i < siFDD_SectorCacheSize; i++ )\r
-       {\r
-               if(sFDD_SectorCache[i].timestamp == 0)  continue;\r
-               if(sFDD_SectorCache[i].disk == Disk\r
-               && sFDD_SectorCache[i].sector == lba) {\r
-                       LOG("Found %i in cache %i", lba, i);\r
-                       memcpy(Buffer, sFDD_SectorCache[i].data, 512);\r
-                       sFDD_SectorCache[i].timestamp = now();\r
-                       FDD_FreeCacheSpinlock();\r
-                       LEAVE('i', 1);\r
-                       return 1;\r
-               }\r
-       }\r
-       LOG("Read %i from Disk", lba);\r
-       FDD_FreeCacheSpinlock();\r
-       #else\r
-       if( IOCache_Read( gFDD_Devices[Disk].CacheHandle, SectorAddr, Buffer ) == 1 ) {\r
-               LEAVE('i', 1);\r
-               return 1;\r
-       }\r
-       #endif\r
-       \r
-       base = cPORTBASE[Disk>>1];\r
-       \r
-       LOG("Calculating Disk Dimensions");\r
-       // Get CHS position\r
-       if(FDD_int_GetDims(gFDD_Devices[Disk].type, lba, &cyl, &head, &sec, &spt) != 1) {\r
-               LEAVE('i', -1);\r
-               return -1;\r
-       }\r
-       \r
-       // Remove Old Timer\r
-       Time_RemoveTimer(gFDD_Devices[Disk].timer);\r
-       // Check if Motor is on\r
-       if(gFDD_Devices[Disk].motorState == 0) {\r
-               FDD_int_StartMotor(Disk);\r
-       }\r
-       \r
-       LOG("Wait for Motor Spinup");\r
-       \r
-       // Wait for spinup\r
-       while(gFDD_Devices[Disk].motorState == 1)       Threads_Yield();\r
-       \r
-       LOG("C:%i,H:%i,S:%i", cyl, head, sec);\r
-       LOG("Acquire Spinlock");\r
-       \r
-       FDD_AquireSpinlock();\r
-       \r
-       // Seek to track\r
-       outb(base+CALIBRATE_DRIVE, 0);\r
-       i = 0;\r
-       while(FDD_int_SeekTrack(Disk, head, (Uint8)cyl) == 0 && i++ < FDD_SEEK_TIMEOUT )        Threads_Yield();\r
-       //FDD_SensInt(base, NULL, NULL);        // Wait for IRQ\r
-       \r
-       LOG("Setting DMA for read");\r
-       \r
-       //Read Data from DMA\r
-       DMA_SetChannel(2, 512, 1);      // Read 512 Bytes\r
-       \r
-       LOG("Sending read command");\r
-       \r
-       //Threads_Wait(100);    // Wait for Head to settle\r
-       Time_Delay(100);\r
-       FDD_int_SendByte(base, READ_SECTOR);    // Was 0xE6\r
-       FDD_int_SendByte(base, (head << 2) | (Disk&1));\r
-       FDD_int_SendByte(base, (Uint8)cyl);\r
-       FDD_int_SendByte(base, (Uint8)head);\r
-       FDD_int_SendByte(base, (Uint8)sec);\r
-       FDD_int_SendByte(base, 0x02);   // Bytes Per Sector (Real BPS=128*2^{val})\r
-       FDD_int_SendByte(base, spt);    // SPT\r
-       FDD_int_SendByte(base, 0x1B);   // Gap Length (27 is default)\r
-       FDD_int_SendByte(base, 0xFF);   // Data Length\r
-       \r
-       // Wait for IRQ\r
-       LOG("Waiting for Data to be read");\r
-       FDD_WaitIRQ();\r
-       \r
-       // Read Data from DMA\r
-       LOG(" FDD_ReadSector: Reading Data");\r
-       DMA_ReadData(2, 512, Buffer);\r
-       \r
-       // Clear Input Buffer\r
-       LOG("Clearing Input Buffer");\r
-       FDD_int_GetByte(base); FDD_int_GetByte(base); FDD_int_GetByte(base);\r
-       FDD_int_GetByte(base); FDD_int_GetByte(base); FDD_int_GetByte(base); FDD_int_GetByte(base);\r
-       \r
-       LOG("Realeasing Spinlock and Setting motor to stop");\r
-       // Release Spinlock\r
-       FDD_FreeSpinlock();\r
-       \r
-       //Set timer to turn off motor affter a gap\r
-       gFDD_Devices[Disk].timer = Time_CreateTimer(MOTOR_OFF_DELAY, FDD_int_StopMotor, (void*)Disk);   //One Shot Timer
-\r
-       #if USE_CACHE\r
-       {\r
-               FDD_AquireCacheSpinlock();\r
-               int oldest = 0;\r
-               for(i=0;i<siFDD_SectorCacheSize;i++)\r
-               {\r
-                       if(sFDD_SectorCache[i].timestamp == 0) {\r
-                               oldest = i;\r
-                               break;\r
-                       }\r
-                       if(sFDD_SectorCache[i].timestamp < sFDD_SectorCache[oldest].timestamp)\r
-                               oldest = i;\r
-               }\r
-               sFDD_SectorCache[oldest].timestamp = now();\r
-               sFDD_SectorCache[oldest].disk = Disk;\r
-               sFDD_SectorCache[oldest].sector = lba;\r
-               memcpy(sFDD_SectorCache[oldest].data, Buffer, 512);\r
-               FDD_FreeCacheSpinlock();\r
-       }\r
-       #else\r
-       IOCache_Add( gFDD_Devices[Disk].CacheHandle, SectorAddr, Buffer );\r
-       #endif\r
-
-       LEAVE('i', 1);\r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn int FDD_WriteSector(Uint32 Disk, Uint64 LBA, void *Buffer)\r
- * \brief Write a sector to the floppy disk\r
- * \note Not Implemented\r
- */\r
-int FDD_WriteSector(Uint32 Disk, Uint64 LBA, void *Buffer)\r
-{\r
-       Warning("[FDD  ] Read Only at the moment");\r
-       return -1;\r
-}\r
-\r
-/**\r
- * \fn int FDD_int_SeekTrack(int disk, int track)\r
- * \brief Seek disk to selected track\r
- */\r
-int FDD_int_SeekTrack(int disk, int head, int track)\r
-{\r
-       Uint8   sr0, cyl;\r
-        int    base;\r
-       \r
-       base = cPORTBASE[disk>>1];\r
-       \r
-       // Check if seeking is needed\r
-       if(gFDD_Devices[disk].track[head] == track)\r
-               return 1;\r
-       \r
-       // - Seek Head 0\r
-       FDD_int_SendByte(base, SEEK_TRACK);\r
-       FDD_int_SendByte(base, (head<<2)|(disk&1));\r
-       FDD_int_SendByte(base, track);  // Send Seek command\r
-       FDD_WaitIRQ();\r
-       FDD_SensInt(base, &sr0, &cyl);  // Wait for IRQ\r
-       if((sr0 & 0xF0) != 0x20) {
-               LOG("sr0 = 0x%x", sr0);
-               return 0;       //Check Status
-       }\r
-       if(cyl != track)        return 0;\r
-       \r
-       // Set Track in structure\r
-       gFDD_Devices[disk].track[head] = track;\r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn int FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt)\r
- * \brief Get Dimensions of a disk\r
- */\r
-int FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt)\r
-{\r
-       switch(type) {\r
-       case 0:\r
-               return 0;\r
-       \r
-       // 360Kb 5.25"\r
-       case 1:\r
-               *spt = 9;\r
-               *s = (lba % 9) + 1;\r
-               *c = lba / 18;\r
-               *h = (lba / 9) & 1;\r
-               break;\r
-       \r
-       // 1220Kb 5.25"\r
-       case 2:\r
-               *spt = 15;\r
-               *s = (lba % 15) + 1;\r
-               *c = lba / 30;\r
-               *h = (lba / 15) & 1;\r
-               break;\r
-       \r
-       // 720Kb 3.5"\r
-       case 3:\r
-               *spt = 9;\r
-               *s = (lba % 9) + 1;\r
-               *c = lba / 18;\r
-               *h = (lba / 9) & 1;\r
-               break;\r
-       \r
-       // 1440Kb 3.5"\r
-       case 4:\r
-               *spt = 18;\r
-               *s = (lba % 18) + 1;\r
-               *c = lba / 36;\r
-               *h = (lba / 18) & 1;\r
-               //Log("1440k - lba=%i(0x%x), *s=%i,*c=%i,*h=%i", lba, lba, *s, *c, *h);\r
-               break;\r
-               \r
-       // 2880Kb 3.5"\r
-       case 5:\r
-               *spt = 36;\r
-               *s = (lba % 36) + 1;\r
-               *c = lba / 72;\r
-               *h = (lba / 32) & 1;\r
-               break;\r
-               \r
-       default:\r
-               return -2;\r
-       }\r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn void FDD_IRQHandler(int Num)\r
- * \brief Handles IRQ6\r
- */\r
-void FDD_IRQHandler(int Num)\r
-{\r
-    fdd_irq6 = 1;\r
-}\r
-\r
-/**\r
- * \fn FDD_WaitIRQ()\r
- * \brief Wait for an IRQ6\r
- */\r
-void FDD_WaitIRQ()\r
-{\r
-       // Wait for IRQ\r
-       while(!fdd_irq6)        Threads_Yield();\r
-       fdd_irq6 = 0;\r
-}\r
-\r
-void FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl)\r
-{\r
-       FDD_int_SendByte(base, CHECK_INTERRUPT_STATUS);\r
-       if(sr0) *sr0 = FDD_int_GetByte(base);\r
-       else    FDD_int_GetByte(base);\r
-       if(cyl) *cyl = FDD_int_GetByte(base);\r
-       else    FDD_int_GetByte(base);\r
-}\r
-\r
-void FDD_AquireSpinlock()\r
-{\r
-       while(fdd_inUse)\r
-               Threads_Yield();\r
-       fdd_inUse = 1;\r
-}\r
-\r
-inline void FDD_FreeSpinlock()\r
-{\r
-       fdd_inUse = 0;\r
-}\r
-\r
-#if USE_CACHE\r
-inline void FDD_AquireCacheSpinlock()\r
-{\r
-       while(siFDD_CacheInUse) Threads_Yield();\r
-       siFDD_CacheInUse = 1;\r
-}\r
-inline void FDD_FreeCacheSpinlock()\r
-{\r
-       siFDD_CacheInUse = 0;\r
-}\r
-#endif\r
-\r
-/**\r
- * void FDD_int_SendByte(int base, char byte)\r
- * \brief Sends a command to the controller\r
- */\r
-void FDD_int_SendByte(int base, char byte)\r
-{\r
-    volatile int state;\r
-    int timeout = 128;\r
-    for( ; timeout--; )\r
-    {\r
-        state = inb(base + PORT_MAINSTATUS);\r
-        if ((state & 0xC0) == 0x80)\r
-        {\r
-            outb(base + PORT_DATA, byte);\r
-            return;\r
-        }\r
-        inb(0x80);     //Delay\r
-    }\r
-       #if WARN\r
-               Warning("FDD_int_SendByte - Timeout sending byte 0x%x to base 0x%x\n", byte, base);\r
-       #endif\r
-}\r
-\r
-/**\r
- * int FDD_int_GetByte(int base, char byte)\r
- * \brief Receive data from fdd controller\r
- */\r
-int FDD_int_GetByte(int base)\r
-{\r
-    volatile int state;\r
-    int timeout;\r
-    for( timeout = 128; timeout--; )\r
-    {\r
-        state = inb((base + PORT_MAINSTATUS));\r
-        if ((state & 0xd0) == 0xd0)\r
-               return inb(base + PORT_DATA);\r
-        inb(0x80);\r
-    }\r
-    return -1;\r
-}\r
-\r
-/**\r
- * \brief Recalibrate the specified disk\r
- */\r
-void FDD_Recalibrate(int disk)\r
-{\r
-       ENTER("idisk", disk);\r
-       \r
-       LOG("Starting Motor");\r
-       FDD_int_StartMotor(disk);\r
-       // Wait for Spinup\r
-       while(gFDD_Devices[disk].motorState == 1)       Threads_Yield();\r
-       \r
-       LOG("Sending Calibrate Command");\r
-       FDD_int_SendByte(cPORTBASE[disk>>1], CALIBRATE_DRIVE);\r
-       FDD_int_SendByte(cPORTBASE[disk>>1], disk&1);\r
-       \r
-       LOG("Waiting for IRQ");\r
-       FDD_WaitIRQ();\r
-       FDD_SensInt(cPORTBASE[disk>>1], NULL, NULL);\r
-       \r
-       LOG("Stopping Motor");\r
-       FDD_int_StopMotor(disk);\r
-       LEAVE('-');\r
-}\r
-\r
-/**\r
- * \brief Reset the specified FDD controller\r
- */\r
-void FDD_Reset(int id)\r
-{\r
-       int base = cPORTBASE[id];\r
-       \r
-       ENTER("iID", id);\r
-       \r
-       outb(base + PORT_DIGOUTPUT, 0); // Stop Motors & Disable FDC\r
-       outb(base + PORT_DIGOUTPUT, 0x0C);      // Re-enable FDC (DMA and Enable)\r
-       \r
-       LOG("Awaiting IRQ");\r
-       \r
-       FDD_WaitIRQ();\r
-       FDD_SensInt(base, NULL, NULL);\r
-       \r
-       LOG("Setting Driver Info");\r
-       outb(base + PORT_DATARATE, 0);  // Set data rate to 500K/s\r
-       FDD_int_SendByte(base, FIX_DRIVE_DATA); // Step and Head Load Times\r
-       FDD_int_SendByte(base, 0xDF);   // Step Rate Time, Head Unload Time (Nibble each)\r
-       FDD_int_SendByte(base, 0x02);   // Head Load Time >> 1\r
-       while(FDD_int_SeekTrack(0, 0, 1) == 0); // set track\r
-       while(FDD_int_SeekTrack(0, 1, 1) == 0); // set track\r
-       \r
-       LOG("Recalibrating Disk");\r
-       FDD_Recalibrate((id<<1)|0);\r
-       FDD_Recalibrate((id<<1)|1);
-\r
-       LEAVE('-');\r
-}\r
-\r
-/**\r
- * \fn void FDD_int_TimerCallback()\r
- * \brief Called by timer\r
- */\r
-void FDD_int_TimerCallback(int arg)\r
-{\r
-       ENTER("iarg", arg);\r
-       if(gFDD_Devices[arg].motorState == 1)\r
-               gFDD_Devices[arg].motorState = 2;\r
-       Time_RemoveTimer(gFDD_Devices[arg].timer);\r
-       gFDD_Devices[arg].timer = -1;\r
-       LEAVE('-');\r
-}\r
-\r
-/**\r
- * \fn void FDD_int_StartMotor(char disk)\r
- * \brief Starts FDD Motor\r
- */\r
-void FDD_int_StartMotor(int disk)\r
-{\r
-       Uint8   state;\r
-       state = inb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT );\r
-       state |= 1 << (4+disk);\r
-       outb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT, state );\r
-       gFDD_Devices[disk].motorState = 1;\r
-       gFDD_Devices[disk].timer = Time_CreateTimer(MOTOR_ON_DELAY, FDD_int_TimerCallback, (void*)disk);\r
-}\r
-\r
-/**\r
- * \fn void FDD_int_StopMotor(int disk)\r
- * \brief Stops FDD Motor\r
- */\r
-void FDD_int_StopMotor(int disk)\r
-{\r
-       Uint8   state;\r
-       state = inb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT );\r
-       state &= ~( 1 << (4+disk) );\r
-       outb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT, state );\r
-    gFDD_Devices[disk].motorState = 0;\r
-}\r
-\r
-/**\r
- * \fn void ModuleUnload()\r
- * \brief Prepare the module for removal\r
- */\r
-void ModuleUnload()\r
-{\r
-       int i;\r
-       FDD_AquireSpinlock();\r
-       for(i=0;i<4;i++) {\r
-               Time_RemoveTimer(gFDD_Devices[i].timer);\r
-               FDD_int_StopMotor(i);\r
-       }\r
-       //IRQ_Clear(6);\r
-}\r
diff --git a/Modules/FS_Ext2/Makefile b/Modules/FS_Ext2/Makefile
deleted file mode 100644 (file)
index 806e638..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-#
-
-OBJ = ext2.o read.o dir.o write.o
-NAME = FS_Ext2
-
--include ../Makefile.tpl
diff --git a/Modules/FS_Ext2/dir.c b/Modules/FS_Ext2/dir.c
deleted file mode 100644 (file)
index 5fe8933..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Acess OS
- * Ext2 Driver Version 1
- */
-/**
- * \file dir.c
- * \brief Second Extended Filesystem Driver
- * \todo Implement file full write support
- */
-#define DEBUG  1
-#define VERBOSE        0
-#include "ext2_common.h"
-
-
-// === PROTOTYPES ===
-char           *Ext2_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node      *Ext2_FindDir(tVFS_Node *Node, char *FileName);
- int           Ext2_MkNod(tVFS_Node *Node, char *Name, Uint Flags);
-tVFS_Node      *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeId, char *Name);
-
-// === CODE ===
-/**
- \fn char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
- \brief Reads a directory entry
-*/
-char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
-{
-       tExt2_Inode     inode;
-       char    namebuf[EXT2_NAME_LEN+1];
-       tExt2_DirEnt    dirent;
-       Uint64  Base;   // Block's Base Address
-        int    block = 0, ofs = 0;
-        int    entNum = 0;
-       tExt2_Disk      *disk = Node->ImplPtr;
-       Uint    size;
-       
-       ENTER("pNode iPos", Node, Pos);
-       
-       // Read directory's inode
-       Ext2_int_GetInode(Node, &inode);
-       size = inode.i_size;
-       
-       LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);
-       
-       // Find Entry
-       // Get First Block
-       // - Do this ourselves as it is a simple operation
-       Base = inode.i_block[0] * disk->BlockSize;
-       while(Pos -- && size > 0)
-       {
-               VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);
-               ofs += dirent.rec_len;
-               size -= dirent.rec_len;
-               entNum ++;
-               
-               if(ofs >= disk->BlockSize) {
-                       block ++;
-                       if( ofs > disk->BlockSize ) {
-                               Warning("[EXT2] Directory Entry %i of inode %i extends over a block boundary, ignoring",
-                                       entNum-1, Node->Inode);
-                       }
-                       ofs = 0;
-                       Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );
-               }
-       }
-       
-       // Check for the end of the list
-       if(size <= 0) {
-               LEAVE('n');
-               return NULL;
-       }
-       
-       // Read Entry
-       VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent );
-       //LOG("dirent.inode = %i", dirent.inode);
-       //LOG("dirent.rec_len = %i", dirent.rec_len);
-       //LOG("dirent.name_len = %i", dirent.name_len);
-       VFS_ReadAt( disk->FD, Base+ofs+sizeof(tExt2_DirEnt), dirent.name_len, namebuf );
-       namebuf[ dirent.name_len ] = '\0';      // Cap off string
-       
-       
-       // Ignore . and .. (these are done in the VFS)
-       if( (namebuf[0] == '.' && namebuf[1] == '\0')
-       ||  (namebuf[0] == '.' && namebuf[1] == '.' && namebuf[2]=='\0')) {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;        // Skip
-       }
-       
-       LEAVE('s', namebuf);
-       // Create new node
-       return strdup(namebuf);
-}
-
-/**
- \fn tVFS_Node *Ext2_FindDir(tVFS_Node *node, char *filename)
- \brief Gets information about a file
- \param node   vfs node - Parent Node
- \param filename       String - Name of file
- \return VFS Node of file
-*/
-tVFS_Node *Ext2_FindDir(tVFS_Node *Node, char *Filename)
-{
-       tExt2_Disk      *disk = Node->ImplPtr;
-       tExt2_Inode     inode;
-       char    namebuf[EXT2_NAME_LEN+1];
-       tExt2_DirEnt    dirent;
-       Uint64  Base;   // Block's Base Address
-        int    block = 0, ofs = 0;
-        int    entNum = 0;
-       Uint    size;
-       
-       // Read directory's inode
-       Ext2_int_GetInode(Node, &inode);
-       size = inode.i_size;
-       
-       // Get First Block
-       // - Do this ourselves as it is a simple operation
-       Base = inode.i_block[0] * disk->BlockSize;
-       // Find File
-       while(size > 0)
-       {
-               VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);
-               VFS_ReadAt( disk->FD, Base+ofs+sizeof(tExt2_DirEnt), dirent.name_len, namebuf );
-               namebuf[ dirent.name_len ] = '\0';      // Cap off string
-               // If it matches, create a node and return it
-               if(strcmp(namebuf, Filename) == 0)
-                       return Ext2_int_CreateNode( disk, dirent.inode, namebuf );
-               // Increment pointers
-               ofs += dirent.rec_len;
-               size -= dirent.rec_len;
-               entNum ++;
-               
-               // Check for end of block
-               if(ofs >= disk->BlockSize) {
-                       block ++;
-                       if( ofs > disk->BlockSize ) {
-                               Warning("[EXT2 ] Directory Entry %i of inode %i extends over a block boundary, ignoring",
-                                       entNum-1, Node->Inode);
-                       }
-                       ofs = 0;
-                       Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );
-               }
-       }
-       
-       return NULL;
-}
-
-/**
- * \fn int Ext2_MkNod(tVFS_Node *Parent, char *Name, Uint Flags)
- * \brief Create a new node
- */
-int Ext2_MkNod(tVFS_Node *Parent, char *Name, Uint Flags)
-{
-       return 0;
-}
-
-// ---- INTERNAL FUNCTIONS ----
-/**
- * \fn vfs_node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID, char *Name)
- * \brief Create a new VFS Node
- */
-tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID, char *Name)
-{
-       tExt2_Inode     inode;
-       tVFS_Node       retNode;
-       tVFS_Node       *tmpNode;
-       
-       if( !Ext2_int_ReadInode(Disk, InodeID, &inode) )
-               return NULL;
-       
-       if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )
-               return tmpNode;
-       
-       
-       // Set identifiers
-       retNode.Inode = InodeID;
-       retNode.ImplPtr = Disk;
-       
-       // Set file length
-       retNode.Size = inode.i_size;
-       
-       // Set Access Permissions
-       retNode.UID = inode.i_uid;
-       retNode.GID = inode.i_gid;
-       retNode.NumACLs = 3;
-       retNode.ACLs = VFS_UnixToAcessACL(inode.i_mode & 0777, inode.i_uid, inode.i_gid);
-       
-       //  Set Function Pointers
-       retNode.Read = Ext2_Read;
-       retNode.Write = Ext2_Write;
-       retNode.Close = Ext2_CloseFile;
-       
-       switch(inode.i_mode & EXT2_S_IFMT)
-       {
-       // Symbolic Link
-       case EXT2_S_IFLNK:
-               retNode.Flags = VFS_FFLAG_SYMLINK;
-               break;
-       // Regular File
-       case EXT2_S_IFREG:
-               retNode.Flags = 0;
-               retNode.Size |= (Uint64)inode.i_dir_acl << 32;
-               break;
-       // Directory
-       case EXT2_S_IFDIR:
-               retNode.ReadDir = Ext2_ReadDir;
-               retNode.FindDir = Ext2_FindDir;
-               retNode.MkNod = Ext2_MkNod;
-               //retNode.Relink = Ext2_Relink;
-               retNode.Flags = VFS_FFLAG_DIRECTORY;
-               break;
-       // Unknown, Write protect and hide it to be safe 
-       default:
-               retNode.Flags = VFS_FFLAG_READONLY;//|VFS_FFLAG_HIDDEN;
-               break;
-       }
-       
-       // Check if the file should be hidden
-       //if(Name[0] == '.')    retNode.Flags |= VFS_FFLAG_HIDDEN;
-       
-       // Set Timestamps
-       retNode.ATime = now();
-       retNode.MTime = inode.i_mtime * 1000;
-       retNode.CTime = inode.i_ctime * 1000;
-       
-       // Save in node cache and return saved node
-       return Inode_CacheNode(Disk->CacheID, &retNode);
-}
diff --git a/Modules/FS_Ext2/ext2.c b/Modules/FS_Ext2/ext2.c
deleted file mode 100644 (file)
index 81dcef0..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-/*\r
- * Acess OS\r
- * Ext2 Driver Version 1\r
- */\r
-/**\r
- * \file fs/ext2.c\r
- * \brief Second Extended Filesystem Driver\r
- * \todo Implement file full write support\r
- */\r
-#define DEBUG  1\r
-#define VERBOSE        0\r
-#include "ext2_common.h"\r
-#include <modules.h>\r
-\r
-// === PROTOTYPES ===\r
- int   Ext2_Install(char **Arguments);\r
-// Interface Functions\r
-tVFS_Node      *Ext2_InitDevice(char *Device, char **Options);\r
-void           Ext2_Unmount(tVFS_Node *Node);\r
-void           Ext2_CloseFile(tVFS_Node *Node);\r
-// Internal Helpers\r
- int           Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode);\r
-Uint64         Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);\r
-Uint32         Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent);\r
-void           Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);\r
-\r
-// === SEMI-GLOBALS ===\r
-MODULE_DEFINE(0, 0x5B /*v0.90*/, FS_Ext2, Ext2_Install, NULL);\r
-tExt2_Disk     gExt2_disks[6];\r
- int   giExt2_count = 0;\r
-tVFS_Driver    gExt2_FSInfo = {\r
-       "ext2", 0, Ext2_InitDevice, Ext2_Unmount, NULL\r
-       };\r
-\r
-// === CODE ===\r
-\r
-/**\r
- * \fn int Ext2_Install(char **Arguments)\r
- * \brief Install the Ext2 Filesystem Driver\r
- */\r
-int Ext2_Install(char **Arguments)\r
-{\r
-       VFS_AddDriver( &gExt2_FSInfo );\r
-       return 1;\r
-}\r
-\r
-/**\r
- \fn tVFS_Node *Ext2_InitDevice(char *Device, char **Options)\r
- \brief Initializes a device to be read by by the driver\r
- \param Device String - Device to read from\r
- \param Options        NULL Terminated array of option strings\r
- \return Root Node\r
-*/\r
-tVFS_Node *Ext2_InitDevice(char *Device, char **Options)\r
-{\r
-       tExt2_Disk      *disk;\r
-        int    fd;\r
-        int    groupCount;\r
-       tExt2_SuperBlock        sb;\r
-       tExt2_Inode     inode;\r
-       \r
-       ENTER("sDevice pOptions", Device, Options);\r
-       \r
-       // Open Disk\r
-       fd = VFS_Open(Device, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);            //Open Device\r
-       if(fd == -1) {\r
-               Warning("[EXT2 ] Unable to open '%s'", Device);\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       \r
-       // Read Superblock at offset 1024\r
-       VFS_ReadAt(fd, 1024, 1024, &sb);        // Read Superblock\r
-       \r
-       // Sanity Check Magic value\r
-       if(sb.s_magic != 0xEF53) {\r
-               Warning("[EXT2 ] Volume '%s' is not an EXT2 volume", Device);\r
-               VFS_Close(fd);\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       \r
-       // Get Group count\r
-       groupCount = DivUp(sb.s_blocks_count, sb.s_blocks_per_group);\r
-       LOG("groupCount = %i", groupCount);\r
-       \r
-       // Allocate Disk Information\r
-       disk = malloc(sizeof(tExt2_Disk) + sizeof(tExt2_Group)*groupCount);\r
-       if(!disk) {\r
-               Warning("[EXT2 ] Unable to allocate disk structure");\r
-               VFS_Close(fd);\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       disk->FD = fd;\r
-       memcpy(&disk->SuperBlock, &sb, 1024);\r
-       disk->GroupCount = groupCount;\r
-       \r
-       // Get an inode cache handle\r
-       disk->CacheID = Inode_GetHandle();\r
-       \r
-       // Get Block Size\r
-       LOG("s_log_block_size = 0x%x", sb.s_log_block_size);\r
-       disk->BlockSize = 1024 << sb.s_log_block_size;\r
-       \r
-       // Read Group Information\r
-       VFS_ReadAt(\r
-               disk->FD,\r
-               sb.s_first_data_block * disk->BlockSize + 1024,\r
-               sizeof(tExt2_Group)*groupCount,\r
-               disk->Groups\r
-               );\r
-       \r
-       #if VERBOSE\r
-       LOG("Block Group 0");\r
-       LOG(".bg_block_bitmap = 0x%x", disk->Groups[0].bg_block_bitmap);\r
-       LOG(".bg_inode_bitmap = 0x%x", disk->Groups[0].bg_inode_bitmap);\r
-       LOG(".bg_inode_table = 0x%x", disk->Groups[0].bg_inode_table);\r
-       LOG("Block Group 1");\r
-       LOG(".bg_block_bitmap = 0x%x", disk->Groups[1].bg_block_bitmap);\r
-       LOG(".bg_inode_bitmap = 0x%x", disk->Groups[1].bg_inode_bitmap);\r
-       LOG(".bg_inode_table = 0x%x", disk->Groups[1].bg_inode_table);\r
-       #endif\r
-       \r
-       // Get root Inode\r
-       Ext2_int_ReadInode(disk, 2, &inode);\r
-       \r
-       // Create Root Node\r
-       memset(&disk->RootNode, 0, sizeof(tVFS_Node));\r
-       disk->RootNode.Inode = 2;       // Root inode ID\r
-       disk->RootNode.ImplPtr = disk;  // Save disk pointer\r
-       disk->RootNode.Size = -1;       // Fill in later (on readdir)\r
-       disk->RootNode.Flags = VFS_FFLAG_DIRECTORY;\r
-       \r
-       disk->RootNode.ReadDir = Ext2_ReadDir;\r
-       disk->RootNode.FindDir = Ext2_FindDir;\r
-       //disk->RootNode.Relink = Ext2_Relink;\r
-       \r
-       // Complete root node\r
-       disk->RootNode.UID = inode.i_uid;\r
-       disk->RootNode.GID = inode.i_gid;\r
-       disk->RootNode.NumACLs = 1;\r
-       disk->RootNode.ACLs = &gVFS_ACL_EveryoneRW;\r
-       \r
-       #if DEBUG\r
-       LOG("inode.i_size = 0x%x", inode.i_size);\r
-       LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);\r
-       #endif\r
-       \r
-       LEAVE('p', &disk->RootNode);\r
-       return &disk->RootNode;\r
-}\r
-\r
-/**\r
- * \fn void Ext2_Unmount(tVFS_Node *Node)\r
- * \brief Close a mounted device\r
- */\r
-void Ext2_Unmount(tVFS_Node *Node)\r
-{\r
-       tExt2_Disk      *disk = Node->ImplPtr;\r
-       \r
-       VFS_Close( disk->FD );\r
-       Inode_ClearCache( disk->CacheID );\r
-       memset(disk, 0, sizeof(tExt2_Disk)+disk->GroupCount*sizeof(tExt2_Group));\r
-       free(disk);\r
-}\r
-\r
-/**\r
- * \fn void Ext2_CloseFile(tVFS_Node *Node)\r
- * \brief Close a file (Remove it from the cache)\r
- */\r
-void Ext2_CloseFile(tVFS_Node *Node)\r
-{\r
-       tExt2_Disk      *disk = Node->ImplPtr;\r
-       Inode_UncacheNode(disk->CacheID, Node->Inode);\r
-       return ;\r
-}\r
-\r
-//==================================\r
-//=       INTERNAL FUNCTIONS       =\r
-//==================================\r
-\r
-\r
-/**\r
- * \fn int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode)\r
- * \brief Gets the inode descriptor for a node\r
- * \param Node node to get the Inode of\r
- * \param Inode        Destination\r
- */\r
-int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode)\r
-{\r
-       return Ext2_int_ReadInode(Node->ImplPtr, Node->Inode, Inode);\r
-}\r
-\r
-/**\r
- * \fn int Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode)\r
- * \brief Read an inode into memory\r
- */\r
-int Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode)\r
-{\r
-        int    group, subId;\r
-       \r
-       //LogF("Ext2_int_ReadInode: (Disk=%p, InodeId=%i, Inode=%p)", Disk, InodeId, Inode);\r
-       //ENTER("pDisk iInodeId pInode", Disk, InodeId, Inode);\r
-       \r
-       if(InodeId == 0)        return 0;\r
-       \r
-       InodeId --;     // Inodes are numbered starting at 1\r
-       \r
-       group = InodeId / Disk->SuperBlock.s_inodes_per_group;\r
-       subId = InodeId % Disk->SuperBlock.s_inodes_per_group;\r
-       \r
-       //LOG("group=%i, subId = %i", group, subId);\r
-       \r
-       // Read Inode\r
-       VFS_ReadAt(Disk->FD,\r
-               Disk->Groups[group].bg_inode_table * Disk->BlockSize + sizeof(tExt2_Inode)*subId,\r
-               sizeof(tExt2_Inode),\r
-               Inode);\r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)\r
- * \brief Get the address of a block from an inode's list\r
- * \param Disk Disk information structure\r
- * \param Blocks       Pointer to an inode's block list\r
- * \param BlockNum     Block index in list\r
- */\r
-Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)\r
-{\r
-       Uint32  *iBlocks;\r
-       // Direct Blocks\r
-       if(BlockNum < 12)\r
-               return (Uint64)Blocks[BlockNum] * Disk->BlockSize;\r
-       \r
-       // Single Indirect Blocks\r
-       iBlocks = malloc( Disk->BlockSize );\r
-       VFS_ReadAt(Disk->FD, (Uint64)Blocks[12]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
-       \r
-       BlockNum -= 12;\r
-       if(BlockNum < 256) {\r
-               BlockNum = iBlocks[BlockNum];\r
-               free(iBlocks);\r
-               return (Uint64)BlockNum * Disk->BlockSize;\r
-       }\r
-       \r
-       // Double Indirect Blocks\r
-       if(BlockNum < 256*256)\r
-       {\r
-               VFS_ReadAt(Disk->FD, (Uint64)Blocks[13]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
-               VFS_ReadAt(Disk->FD, (Uint64)iBlocks[BlockNum/256]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
-               BlockNum = iBlocks[BlockNum%256];\r
-               free(iBlocks);\r
-               return (Uint64)BlockNum * Disk->BlockSize;\r
-       }\r
-       // Triple Indirect Blocks\r
-       VFS_ReadAt(Disk->FD, (Uint64)Blocks[14]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
-       VFS_ReadAt(Disk->FD, (Uint64)iBlocks[BlockNum/(256*256)]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
-       VFS_ReadAt(Disk->FD, (Uint64)iBlocks[(BlockNum/256)%256]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
-       BlockNum = iBlocks[BlockNum%256];\r
-       free(iBlocks);\r
-       return (Uint64)BlockNum * Disk->BlockSize;\r
-}\r
-\r
-/**\r
- * \fn Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)\r
- * \brief Allocate an inode (from the current group preferably)\r
- * \param Disk EXT2 Disk Information Structure\r
- * \param Parent       Inode ID of the parent (used to locate the child nearby)\r
- */\r
-Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)\r
-{\r
-//     Uint    block = (Parent - 1) / Disk->SuperBlock.s_inodes_per_group;\r
-       return 0;\r
-}\r
-\r
-/**\r
- * \fn void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
- * \brief Updates the superblock\r
- */\r
-void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
-{\r
-        int    bpg = Disk->SuperBlock.s_blocks_per_group;\r
-        int    ngrp = Disk->SuperBlock.s_blocks_count / bpg;\r
-        int    i;\r
-        \r
-       // Update Primary\r
-       VFS_WriteAt(Disk->FD, 1024, 1024, &Disk->SuperBlock);\r
-       \r
-       // Secondaries\r
-       // at Block Group 1, 3^n, 5^n, 7^n\r
-       \r
-       // 1\r
-       if(ngrp <= 1)   return;\r
-       VFS_WriteAt(Disk->FD, 1*bpg*Disk->BlockSize, 1024, &Disk->SuperBlock);\r
-       \r
-       // Powers of 3\r
-       for( i = 3; i < ngrp; i *= 3 )\r
-               VFS_WriteAt(Disk->FD, i*bpg*Disk->BlockSize, 1024, &Disk->SuperBlock);\r
-       \r
-       // Powers of 5\r
-       for( i = 5; i < ngrp; i *= 5 )\r
-               VFS_WriteAt(Disk->FD, i*bpg*Disk->BlockSize, 1024, &Disk->SuperBlock);\r
-       \r
-       // Powers of 7\r
-       for( i = 7; i < ngrp; i *= 7 )\r
-               VFS_WriteAt(Disk->FD, i*bpg*Disk->BlockSize, 1024, &Disk->SuperBlock);\r
-}\r
diff --git a/Modules/FS_Ext2/ext2_common.h b/Modules/FS_Ext2/ext2_common.h
deleted file mode 100644 (file)
index 2e2baba..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Acess OS
- * Ext2 Driver Version 1
- */
-/**
- * \file ext2_common.h
- * \brief Second Extended Filesystem Driver
- */
-#ifndef _EXT2_COMMON_H
-#define _EXT2_COMMON_H
-#include <acess.h>
-#include <vfs.h>
-#include "ext2fs.h"
-
-#define EXT2_UPDATE_WRITEBACK  1
-
-// === STRUCTURES ===
-typedef struct {
-        int    FD;
-        int    CacheID;
-       tVFS_Node       RootNode;
-       
-       tExt2_SuperBlock        SuperBlock;
-        int    BlockSize;
-        
-        int    GroupCount;
-       tExt2_Group             Groups[];
-} tExt2_Disk;
-
-// === FUNCTIONS ===
-// --- Common ---
-extern void    Ext2_CloseFile(tVFS_Node *Node);
-extern int     Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode);
-extern Uint64  Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);
-extern void    Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);
-// --- Dir ---
-extern char    *Ext2_ReadDir(tVFS_Node *Node, int Pos);
-extern tVFS_Node       *Ext2_FindDir(tVFS_Node *Node, char *FileName);
-extern int     Ext2_MkNod(tVFS_Node *Node, char *Name, Uint Flags);
-// --- Read ---
-extern Uint64  Ext2_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
-extern int     Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode);
-// --- Write ---
-extern Uint64  Ext2_Write(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
-
-#endif
diff --git a/Modules/FS_Ext2/ext2fs.h b/Modules/FS_Ext2/ext2fs.h
deleted file mode 100644 (file)
index 8fd87ce..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/**\r
- * Acess2\r
- * \file ext2fs.h\r
- * \brief EXT2 Filesystem Driver\r
- */\r
-#ifndef _EXT2FS_H_\r
-#define _EXT2FS_H_\r
-\r
-/**\r
- \name Inode Flag Values\r
- \{\r
-*/\r
-#define EXT2_S_IFMT            0xF000  //!< Format Mask\r
-#define EXT2_S_IFSOCK  0xC000  //!< Socket\r
-#define EXT2_S_IFLNK   0xA000  //!< Symbolic Link\r
-#define EXT2_S_IFREG   0x8000  //!< Regular File\r
-#define EXT2_S_IFBLK   0x6000  //!< Block Device\r
-#define EXT2_S_IFDIR   0x4000  //!< Directory\r
-#define EXT2_S_IFCHR   0x2000  //!< Character Device\r
-#define EXT2_S_IFIFO   0x1000  //!< FIFO\r
-#define EXT2_S_ISUID   0x0800  //!< SUID\r
-#define EXT2_S_ISGID   0x0400  //!< SGID\r
-#define EXT2_S_ISVTX   0x0200  //!< sticky bit\r
-#define EXT2_S_IRWXU   0700    //!< user access rights mask\r
-#define EXT2_S_IRUSR   0400    //!< Owner Read\r
-#define EXT2_S_IWUSR   0200    //!< Owner Write\r
-#define EXT2_S_IXUSR   0100    //!< Owner Execute\r
-#define EXT2_S_IRWXG   0070    //!< Group Access rights mask\r
-#define EXT2_S_IRGRP   0040    //!< Group Read\r
-#define EXT2_S_IWGRP   0020    //!< Group Write\r
-#define EXT2_S_IXGRP   0010    //!< Group Execute\r
-#define EXT2_S_IRWXO   0007    //!< Global Access rights mask\r
-#define EXT2_S_IROTH   0004    //!< Global Read\r
-#define EXT2_S_IWOTH   0002    //!< Global Write\r
-#define EXT2_S_IXOTH   0001    //!< Global Execute\r
-//! \}\r
-\r
-#define EXT2_NAME_LEN 255      //!< Maximum Name Length\r
-\r
-// === TYPEDEFS ===\r
-typedef struct ext2_inode_s                    tExt2_Inode;    //!< Inode Type\r
-typedef struct ext2_super_block_s      tExt2_SuperBlock;       //!< Superblock Type\r
-typedef struct ext2_group_desc_s       tExt2_Group;    //!< Group Descriptor Type\r
-typedef struct ext2_dir_entry_s                tExt2_DirEnt;   //!< Directory Entry Type\r
-\r
-// === STRUCTURES ===\r
-/**\r
- * \brief EXT2 Superblock Structure\r
- */\r
-struct ext2_super_block_s {\r
-       Uint32  s_inodes_count;         //!< Inodes count\r
-       Uint32  s_blocks_count;         //!< Blocks count\r
-       Uint32  s_r_blocks_count;       //!< Reserved blocks count\r
-       Uint32  s_free_blocks_count;    //!< Free blocks count\r
-       Uint32  s_free_inodes_count;    //!< Free inodes count\r
-       Uint32  s_first_data_block;     //!< First Data Block\r
-       Uint32  s_log_block_size;       //!< Block size\r
-       Sint32  s_log_frag_size;        //!< Fragment size\r
-       Uint32  s_blocks_per_group;     //!< Number Blocks per group\r
-       Uint32  s_frags_per_group;      //!< Number Fragments per group\r
-       Uint32  s_inodes_per_group;     //!< Number Inodes per group\r
-       Uint32  s_mtime;                        //!< Mount time\r
-       Uint32  s_wtime;                        //!< Write time\r
-       Uint16  s_mnt_count;            //!< Mount count\r
-       Sint16  s_max_mnt_count;        //!< Maximal mount count\r
-       Uint16  s_magic;                        //!< Magic signature\r
-       Uint16  s_state;                        //!< File system state\r
-       Uint16  s_errors;                       //!< Behaviour when detecting errors\r
-       Uint16  s_pad;                          //!< Padding\r
-       Uint32  s_lastcheck;            //!< time of last check\r
-       Uint32  s_checkinterval;        //!< max. time between checks\r
-       Uint32  s_creator_os;           //!< Formatting OS\r
-       Uint32  s_rev_level;            //!< Revision level\r
-       Uint16  s_def_resuid;           //!< Default uid for reserved blocks\r
-       Uint16  s_def_resgid;           //!< Default gid for reserved blocks\r
-       Uint32  s_reserved[235];        //!< Padding to the end of the block\r
-};\r
-\r
-/**\r
- * \struct ext2_inode_s\r
- * \brief EXT2 Inode Definition\r
- */\r
-struct ext2_inode_s {\r
-       Uint16 i_mode;  //!< File mode\r
-       Uint16 i_uid;   //!< Owner Uid\r
-       Uint32 i_size;  //!< Size in bytes\r
-       Uint32 i_atime; //!< Access time\r
-       Uint32 i_ctime; //!< Creation time\r
-       Uint32 i_mtime; //!< Modification time\r
-       Uint32 i_dtime; //!< Deletion Time\r
-       Uint16 i_gid;   //!< Group Id\r
-       Uint16 i_links_count;   //!< Links count\r
-       Uint32 i_blocks;        //!< Number of blocks allocated for the file\r
-       Uint32 i_flags; //!< File flags\r
-       union {\r
-               Uint32 linux_reserved1; //!< Linux: Reserved\r
-               Uint32 hurd_translator; //!< HURD: Translator\r
-               Uint32 masix_reserved1; //!< Masix: Reserved\r
-       } osd1; //!< OS dependent 1\r
-       Uint32 i_block[15];     //!< Pointers to blocks\r
-       Uint32 i_version;       //!< File version (for NFS)\r
-       Uint32 i_file_acl;      //!< File ACL\r
-       Uint32 i_dir_acl;       //!< Directory ACL / Extended File Size\r
-       Uint32 i_faddr;         //!< Fragment address\r
-       union {\r
-               struct {\r
-                       Uint8 l_i_frag; //!< Fragment number\r
-                       Uint8 l_i_fsize;        //!< Fragment size\r
-                       Uint16 i_pad1;  //!< Padding\r
-                       Uint32 l_i_reserved2[2];        //!< Reserved\r
-               } linux2;\r
-               struct {\r
-                       Uint8 h_i_frag; //!< Fragment number\r
-                       Uint8 h_i_fsize; //!< Fragment size\r
-                       Uint16 h_i_mode_high;   //!< Mode High Bits\r
-                       Uint16 h_i_uid_high;    //!< UID High Bits\r
-                       Uint16 h_i_gid_high;    //!< GID High Bits\r
-                       Uint32 h_i_author;      //!< Creator ID\r
-               } hurd2;\r
-               struct {\r
-                       Uint8 m_i_frag; //!< Fragment number\r
-                       Uint8 m_i_fsize;        //!< Fragment size\r
-                       Uint16 m_pad1;  //!< Padding\r
-                       Uint32 m_i_reserved2[2];        //!< reserved\r
-               } masix2;\r
-       } osd2; //!< OS dependent 2\r
-};\r
-\r
-/**\r
- * \struct ext2_group_desc_s\r
- * \brief EXT2 Group Descriptor\r
- */\r
-struct ext2_group_desc_s {\r
-       Uint32  bg_block_bitmap;        //!< Blocks bitmap block\r
-       Uint32  bg_inode_bitmap;        //!< Inodes bitmap block\r
-       Uint32  bg_inode_table; //!< Inodes table block\r
-       Uint16  bg_free_blocks_count;   //!< Free blocks count\r
-       Uint16  bg_free_inodes_count;   //!< Free inodes count\r
-       Uint16  bg_used_dirs_count;     //!< Directories count\r
-       Uint16  bg_pad; //!< Padding\r
-       Uint32  bg_reserved[3]; //!< Reserved\r
-};\r
-\r
-/**\r
- * \brief EXT2 Directory Entry\r
- * \note The name may take up less than 255 characters\r
- */\r
-struct ext2_dir_entry_s {\r
-       Uint32  inode;          //!< Inode number\r
-       Uint16  rec_len;        //!< Directory entry length\r
-       Uint8   name_len;       //!< Short Name Length\r
-       Uint8   type;           //!< File Type\r
-       char    name[];         //!< File name\r
-};\r
-\r
-#endif\r
diff --git a/Modules/FS_Ext2/read.c b/Modules/FS_Ext2/read.c
deleted file mode 100644 (file)
index cb6649a..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Acess OS
- * Ext2 Driver Version 1
- */
-/**
- * \file read.c
- * \brief Second Extended Filesystem Driver
- * \todo Implement file full write support
- */
-#define DEBUG  1
-#define VERBOSE        0
-#include "ext2_common.h"
-
-// === PROTOTYPES ===
-Uint64         Ext2_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
- int           Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode);
-
-// === CODE ===
-/**
- * \fn Uint64 Ext2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
- * \brief Read from a file
- */
-Uint64 Ext2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
-{
-       tExt2_Disk      *disk = Node->ImplPtr;
-       tExt2_Inode     inode;
-       Uint64  base;
-       Uint    block;
-       Uint64  remLen;
-       
-       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
-       
-       // Get Inode
-       Ext2_int_GetInode(Node, &inode);
-       
-       // Sanity Checks
-       if(Offset >= inode.i_size) {
-               LEAVE('i', 0);
-               return 0;
-       }
-       if(Offset + Length > inode.i_size)
-               Length = inode.i_size - Offset;
-       
-       block = Offset / disk->BlockSize;
-       Offset = Offset / disk->BlockSize;
-       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
-       if(base == 0) {
-               Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode);
-               LEAVE('i', 0);
-               return 0;
-       }
-       
-       // Read only block
-       if(Length <= disk->BlockSize - Offset)
-       {
-               VFS_ReadAt( disk->FD, base+Offset, Length, Buffer);
-               LEAVE('X', Length);
-               return Length;
-       }
-       
-       // Read first block
-       remLen = Length;
-       VFS_ReadAt( disk->FD, base + Offset, disk->BlockSize - Offset, Buffer);
-       remLen -= disk->BlockSize - Offset;
-       Buffer += disk->BlockSize - Offset;
-       block ++;
-       
-       // Read middle blocks
-       while(remLen > disk->BlockSize)
-       {
-               base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
-               if(base == 0) {
-                       Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode);
-                       LEAVE('i', 0);
-                       return 0;
-               }
-               VFS_ReadAt( disk->FD, base, disk->BlockSize, Buffer);
-               Buffer += disk->BlockSize;
-               remLen -= disk->BlockSize;
-               block ++;
-       }
-       
-       // Read last block
-       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
-       VFS_ReadAt( disk->FD, base, remLen, Buffer);
-       
-       LEAVE('X', Length);
-       return Length;
-}
diff --git a/Modules/FS_Ext2/write.c b/Modules/FS_Ext2/write.c
deleted file mode 100644 (file)
index f3fdc6b..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Acess OS
- * Ext2 Driver Version 1
- */
-/**
- * \file write.c
- * \brief Second Extended Filesystem Driver
- * \todo Implement file full write support
- */
-#define DEBUG  1
-#define VERBOSE        0
-#include "ext2_common.h"
-
-// === PROTOYPES ===
-Uint64         Ext2_Write(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
-Uint32         Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock);
-
-// === CODE ===
-/**
- * \fn Uint64 Ext2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
- * \brief Write to a file
- */
-Uint64 Ext2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
-{
-       tExt2_Disk      *disk = Node->ImplPtr;
-       tExt2_Inode     inode;
-       Uint64  base;
-       Uint64  retLen;
-       Uint    block;
-       Uint64  allocSize;
-        int    bNewBlocks = 0;
-       
-       Debug_HexDump("Ext2_Write", Buffer, Length);
-       
-       Ext2_int_GetInode(Node, &inode);
-       
-       // Get the ammount of space already allocated
-       // - Round size up to block size
-       // - block size is a power of two, so this will work
-       allocSize = (inode.i_size + disk->BlockSize) & ~(disk->BlockSize-1);
-       
-       // Are we writing to inside the allocated space?
-       if( Offset < allocSize )
-       {
-               // Will we go out of it?
-               if(Offset + Length > allocSize) {
-                       bNewBlocks = 1;
-                       retLen = allocSize - Offset;
-               } else
-                       retLen = Length;
-               
-               // Within the allocated space
-               block = Offset / disk->BlockSize;
-               Offset %= disk->BlockSize;
-               base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
-               
-               // Write only block (if only one)
-               if(Offset + retLen <= disk->BlockSize) {
-                       VFS_WriteAt(disk->FD, base+Offset, retLen, Buffer);
-                       if(!bNewBlocks) return Length;
-                       goto addBlocks; // Ugh! A goto, but it seems unavoidable
-               }
-               
-               // Write First Block
-               VFS_WriteAt(disk->FD, base+Offset, disk->BlockSize-Offset, Buffer);
-               Buffer += disk->BlockSize-Offset;
-               retLen -= disk->BlockSize-Offset;
-               block ++;
-               
-               // Write middle blocks
-               while(retLen > disk->BlockSize)
-               {
-                       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
-                       VFS_WriteAt(disk->FD, base, disk->BlockSize, Buffer);
-                       Buffer += disk->BlockSize;
-                       retLen -= disk->BlockSize;
-                       block ++;
-               }
-               
-               // Write last block
-               base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
-               VFS_WriteAt(disk->FD, base, retLen, Buffer);
-               if(!bNewBlocks) return Length;  // Writing in only allocated space
-       }
-       
-addBlocks:
-       ///\todo Implement block allocation
-       Warning("[EXT2] File extending is not yet supported");
-       
-       return 0;
-}
-
-/**
- * \fn Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock)
- * \brief Allocate a block from the best possible location
- * \param Disk EXT2 Disk Information Structure
- * \param PrevBlock    Previous block ID in the file
- */
-Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock)
-{
-        int    bpg = Disk->SuperBlock.s_blocks_per_group;
-       Uint    blockgroup = PrevBlock / bpg;
-       Uint    bitmap[Disk->BlockSize/sizeof(Uint)];
-       Uint    bitsperblock = 8*Disk->BlockSize;
-        int    i, j = 0;
-       Uint    block;
-       
-       // Are there any free blocks?
-       if(Disk->SuperBlock.s_free_blocks_count == 0)   return 0;
-       
-       if(Disk->Groups[blockgroup].bg_free_blocks_count > 0)
-       {
-               // Search block group's bitmap
-               for(i = 0; i < bpg; i++)
-               {
-                       // Get the block in the bitmap block
-                       j = i & (bitsperblock-1);
-                       
-                       // Read in if needed
-                       if(j == 0) {
-                               VFS_ReadAt(
-                                       Disk->FD,
-                                       (Uint64)Disk->Groups[blockgroup].bg_block_bitmap + i / bitsperblock,
-                                       Disk->BlockSize,
-                                       bitmap
-                                       );
-                       }
-                       
-                       // Fast Check
-                       if( bitmap[j/32] == -1 ) {
-                               j = (j + 31) & ~31;
-                               continue;
-                       }
-                       
-                       // Is the bit set?
-                       if( bitmap[j/32] & (1 << (j%32)) )
-                               continue;
-                       
-                       // Ooh! We found one
-                       break;
-               }
-               if( i < bpg ) {
-                       Warning("[EXT2 ] Inconsistency detected, Group Free Block count is non-zero when no free blocks exist");
-                       goto    checkAll;       // Search the entire filesystem for a free block
-                       // Goto needed for neatness
-               }
-               
-               // Mark as used
-               bitmap[j/32] |= (1 << (j%32));
-               VFS_WriteAt(
-                       Disk->FD,
-                       (Uint64)Disk->Groups[blockgroup].bg_block_bitmap + i / bitsperblock,
-                       Disk->BlockSize,
-                       bitmap
-                       );
-               block = i;
-               Disk->Groups[blockgroup].bg_free_blocks_count --;
-               #if EXT2_UPDATE_WRITEBACK
-               //Ext2_int_UpdateBlockGroup(blockgroup);
-               #endif
-       }
-       else
-       {
-       checkAll:
-               Warning("[EXT2 ] TODO - Implement using blocks outside the current block group");
-               return 0;
-       }
-       
-       // Reduce global count
-       Disk->SuperBlock.s_free_blocks_count --;
-       #if EXT2_UPDATE_WRITEBACK
-       Ext2_int_UpdateSuperblock(Disk);
-       #endif
-       
-       return block;
-}
diff --git a/Modules/Filesystems/FS_Ext2/Makefile b/Modules/Filesystems/FS_Ext2/Makefile
new file mode 100644 (file)
index 0000000..806e638
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = ext2.o read.o dir.o write.o
+NAME = FS_Ext2
+
+-include ../Makefile.tpl
diff --git a/Modules/Filesystems/FS_Ext2/dir.c b/Modules/Filesystems/FS_Ext2/dir.c
new file mode 100644 (file)
index 0000000..5fe8933
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Acess OS
+ * Ext2 Driver Version 1
+ */
+/**
+ * \file dir.c
+ * \brief Second Extended Filesystem Driver
+ * \todo Implement file full write support
+ */
+#define DEBUG  1
+#define VERBOSE        0
+#include "ext2_common.h"
+
+
+// === PROTOTYPES ===
+char           *Ext2_ReadDir(tVFS_Node *Node, int Pos);
+tVFS_Node      *Ext2_FindDir(tVFS_Node *Node, char *FileName);
+ int           Ext2_MkNod(tVFS_Node *Node, char *Name, Uint Flags);
+tVFS_Node      *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeId, char *Name);
+
+// === CODE ===
+/**
+ \fn char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
+ \brief Reads a directory entry
+*/
+char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
+{
+       tExt2_Inode     inode;
+       char    namebuf[EXT2_NAME_LEN+1];
+       tExt2_DirEnt    dirent;
+       Uint64  Base;   // Block's Base Address
+        int    block = 0, ofs = 0;
+        int    entNum = 0;
+       tExt2_Disk      *disk = Node->ImplPtr;
+       Uint    size;
+       
+       ENTER("pNode iPos", Node, Pos);
+       
+       // Read directory's inode
+       Ext2_int_GetInode(Node, &inode);
+       size = inode.i_size;
+       
+       LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);
+       
+       // Find Entry
+       // Get First Block
+       // - Do this ourselves as it is a simple operation
+       Base = inode.i_block[0] * disk->BlockSize;
+       while(Pos -- && size > 0)
+       {
+               VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);
+               ofs += dirent.rec_len;
+               size -= dirent.rec_len;
+               entNum ++;
+               
+               if(ofs >= disk->BlockSize) {
+                       block ++;
+                       if( ofs > disk->BlockSize ) {
+                               Warning("[EXT2] Directory Entry %i of inode %i extends over a block boundary, ignoring",
+                                       entNum-1, Node->Inode);
+                       }
+                       ofs = 0;
+                       Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );
+               }
+       }
+       
+       // Check for the end of the list
+       if(size <= 0) {
+               LEAVE('n');
+               return NULL;
+       }
+       
+       // Read Entry
+       VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent );
+       //LOG("dirent.inode = %i", dirent.inode);
+       //LOG("dirent.rec_len = %i", dirent.rec_len);
+       //LOG("dirent.name_len = %i", dirent.name_len);
+       VFS_ReadAt( disk->FD, Base+ofs+sizeof(tExt2_DirEnt), dirent.name_len, namebuf );
+       namebuf[ dirent.name_len ] = '\0';      // Cap off string
+       
+       
+       // Ignore . and .. (these are done in the VFS)
+       if( (namebuf[0] == '.' && namebuf[1] == '\0')
+       ||  (namebuf[0] == '.' && namebuf[1] == '.' && namebuf[2]=='\0')) {
+               LEAVE('p', VFS_SKIP);
+               return VFS_SKIP;        // Skip
+       }
+       
+       LEAVE('s', namebuf);
+       // Create new node
+       return strdup(namebuf);
+}
+
+/**
+ \fn tVFS_Node *Ext2_FindDir(tVFS_Node *node, char *filename)
+ \brief Gets information about a file
+ \param node   vfs node - Parent Node
+ \param filename       String - Name of file
+ \return VFS Node of file
+*/
+tVFS_Node *Ext2_FindDir(tVFS_Node *Node, char *Filename)
+{
+       tExt2_Disk      *disk = Node->ImplPtr;
+       tExt2_Inode     inode;
+       char    namebuf[EXT2_NAME_LEN+1];
+       tExt2_DirEnt    dirent;
+       Uint64  Base;   // Block's Base Address
+        int    block = 0, ofs = 0;
+        int    entNum = 0;
+       Uint    size;
+       
+       // Read directory's inode
+       Ext2_int_GetInode(Node, &inode);
+       size = inode.i_size;
+       
+       // Get First Block
+       // - Do this ourselves as it is a simple operation
+       Base = inode.i_block[0] * disk->BlockSize;
+       // Find File
+       while(size > 0)
+       {
+               VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);
+               VFS_ReadAt( disk->FD, Base+ofs+sizeof(tExt2_DirEnt), dirent.name_len, namebuf );
+               namebuf[ dirent.name_len ] = '\0';      // Cap off string
+               // If it matches, create a node and return it
+               if(strcmp(namebuf, Filename) == 0)
+                       return Ext2_int_CreateNode( disk, dirent.inode, namebuf );
+               // Increment pointers
+               ofs += dirent.rec_len;
+               size -= dirent.rec_len;
+               entNum ++;
+               
+               // Check for end of block
+               if(ofs >= disk->BlockSize) {
+                       block ++;
+                       if( ofs > disk->BlockSize ) {
+                               Warning("[EXT2 ] Directory Entry %i of inode %i extends over a block boundary, ignoring",
+                                       entNum-1, Node->Inode);
+                       }
+                       ofs = 0;
+                       Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );
+               }
+       }
+       
+       return NULL;
+}
+
+/**
+ * \fn int Ext2_MkNod(tVFS_Node *Parent, char *Name, Uint Flags)
+ * \brief Create a new node
+ */
+int Ext2_MkNod(tVFS_Node *Parent, char *Name, Uint Flags)
+{
+       return 0;
+}
+
+// ---- INTERNAL FUNCTIONS ----
+/**
+ * \fn vfs_node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID, char *Name)
+ * \brief Create a new VFS Node
+ */
+tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID, char *Name)
+{
+       tExt2_Inode     inode;
+       tVFS_Node       retNode;
+       tVFS_Node       *tmpNode;
+       
+       if( !Ext2_int_ReadInode(Disk, InodeID, &inode) )
+               return NULL;
+       
+       if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )
+               return tmpNode;
+       
+       
+       // Set identifiers
+       retNode.Inode = InodeID;
+       retNode.ImplPtr = Disk;
+       
+       // Set file length
+       retNode.Size = inode.i_size;
+       
+       // Set Access Permissions
+       retNode.UID = inode.i_uid;
+       retNode.GID = inode.i_gid;
+       retNode.NumACLs = 3;
+       retNode.ACLs = VFS_UnixToAcessACL(inode.i_mode & 0777, inode.i_uid, inode.i_gid);
+       
+       //  Set Function Pointers
+       retNode.Read = Ext2_Read;
+       retNode.Write = Ext2_Write;
+       retNode.Close = Ext2_CloseFile;
+       
+       switch(inode.i_mode & EXT2_S_IFMT)
+       {
+       // Symbolic Link
+       case EXT2_S_IFLNK:
+               retNode.Flags = VFS_FFLAG_SYMLINK;
+               break;
+       // Regular File
+       case EXT2_S_IFREG:
+               retNode.Flags = 0;
+               retNode.Size |= (Uint64)inode.i_dir_acl << 32;
+               break;
+       // Directory
+       case EXT2_S_IFDIR:
+               retNode.ReadDir = Ext2_ReadDir;
+               retNode.FindDir = Ext2_FindDir;
+               retNode.MkNod = Ext2_MkNod;
+               //retNode.Relink = Ext2_Relink;
+               retNode.Flags = VFS_FFLAG_DIRECTORY;
+               break;
+       // Unknown, Write protect and hide it to be safe 
+       default:
+               retNode.Flags = VFS_FFLAG_READONLY;//|VFS_FFLAG_HIDDEN;
+               break;
+       }
+       
+       // Check if the file should be hidden
+       //if(Name[0] == '.')    retNode.Flags |= VFS_FFLAG_HIDDEN;
+       
+       // Set Timestamps
+       retNode.ATime = now();
+       retNode.MTime = inode.i_mtime * 1000;
+       retNode.CTime = inode.i_ctime * 1000;
+       
+       // Save in node cache and return saved node
+       return Inode_CacheNode(Disk->CacheID, &retNode);
+}
diff --git a/Modules/Filesystems/FS_Ext2/ext2.c b/Modules/Filesystems/FS_Ext2/ext2.c
new file mode 100644 (file)
index 0000000..81dcef0
--- /dev/null
@@ -0,0 +1,309 @@
+/*\r
+ * Acess OS\r
+ * Ext2 Driver Version 1\r
+ */\r
+/**\r
+ * \file fs/ext2.c\r
+ * \brief Second Extended Filesystem Driver\r
+ * \todo Implement file full write support\r
+ */\r
+#define DEBUG  1\r
+#define VERBOSE        0\r
+#include "ext2_common.h"\r
+#include <modules.h>\r
+\r
+// === PROTOTYPES ===\r
+ int   Ext2_Install(char **Arguments);\r
+// Interface Functions\r
+tVFS_Node      *Ext2_InitDevice(char *Device, char **Options);\r
+void           Ext2_Unmount(tVFS_Node *Node);\r
+void           Ext2_CloseFile(tVFS_Node *Node);\r
+// Internal Helpers\r
+ int           Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode);\r
+Uint64         Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);\r
+Uint32         Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent);\r
+void           Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);\r
+\r
+// === SEMI-GLOBALS ===\r
+MODULE_DEFINE(0, 0x5B /*v0.90*/, FS_Ext2, Ext2_Install, NULL);\r
+tExt2_Disk     gExt2_disks[6];\r
+ int   giExt2_count = 0;\r
+tVFS_Driver    gExt2_FSInfo = {\r
+       "ext2", 0, Ext2_InitDevice, Ext2_Unmount, NULL\r
+       };\r
+\r
+// === CODE ===\r
+\r
+/**\r
+ * \fn int Ext2_Install(char **Arguments)\r
+ * \brief Install the Ext2 Filesystem Driver\r
+ */\r
+int Ext2_Install(char **Arguments)\r
+{\r
+       VFS_AddDriver( &gExt2_FSInfo );\r
+       return 1;\r
+}\r
+\r
+/**\r
+ \fn tVFS_Node *Ext2_InitDevice(char *Device, char **Options)\r
+ \brief Initializes a device to be read by by the driver\r
+ \param Device String - Device to read from\r
+ \param Options        NULL Terminated array of option strings\r
+ \return Root Node\r
+*/\r
+tVFS_Node *Ext2_InitDevice(char *Device, char **Options)\r
+{\r
+       tExt2_Disk      *disk;\r
+        int    fd;\r
+        int    groupCount;\r
+       tExt2_SuperBlock        sb;\r
+       tExt2_Inode     inode;\r
+       \r
+       ENTER("sDevice pOptions", Device, Options);\r
+       \r
+       // Open Disk\r
+       fd = VFS_Open(Device, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);            //Open Device\r
+       if(fd == -1) {\r
+               Warning("[EXT2 ] Unable to open '%s'", Device);\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       \r
+       // Read Superblock at offset 1024\r
+       VFS_ReadAt(fd, 1024, 1024, &sb);        // Read Superblock\r
+       \r
+       // Sanity Check Magic value\r
+       if(sb.s_magic != 0xEF53) {\r
+               Warning("[EXT2 ] Volume '%s' is not an EXT2 volume", Device);\r
+               VFS_Close(fd);\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       \r
+       // Get Group count\r
+       groupCount = DivUp(sb.s_blocks_count, sb.s_blocks_per_group);\r
+       LOG("groupCount = %i", groupCount);\r
+       \r
+       // Allocate Disk Information\r
+       disk = malloc(sizeof(tExt2_Disk) + sizeof(tExt2_Group)*groupCount);\r
+       if(!disk) {\r
+               Warning("[EXT2 ] Unable to allocate disk structure");\r
+               VFS_Close(fd);\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       disk->FD = fd;\r
+       memcpy(&disk->SuperBlock, &sb, 1024);\r
+       disk->GroupCount = groupCount;\r
+       \r
+       // Get an inode cache handle\r
+       disk->CacheID = Inode_GetHandle();\r
+       \r
+       // Get Block Size\r
+       LOG("s_log_block_size = 0x%x", sb.s_log_block_size);\r
+       disk->BlockSize = 1024 << sb.s_log_block_size;\r
+       \r
+       // Read Group Information\r
+       VFS_ReadAt(\r
+               disk->FD,\r
+               sb.s_first_data_block * disk->BlockSize + 1024,\r
+               sizeof(tExt2_Group)*groupCount,\r
+               disk->Groups\r
+               );\r
+       \r
+       #if VERBOSE\r
+       LOG("Block Group 0");\r
+       LOG(".bg_block_bitmap = 0x%x", disk->Groups[0].bg_block_bitmap);\r
+       LOG(".bg_inode_bitmap = 0x%x", disk->Groups[0].bg_inode_bitmap);\r
+       LOG(".bg_inode_table = 0x%x", disk->Groups[0].bg_inode_table);\r
+       LOG("Block Group 1");\r
+       LOG(".bg_block_bitmap = 0x%x", disk->Groups[1].bg_block_bitmap);\r
+       LOG(".bg_inode_bitmap = 0x%x", disk->Groups[1].bg_inode_bitmap);\r
+       LOG(".bg_inode_table = 0x%x", disk->Groups[1].bg_inode_table);\r
+       #endif\r
+       \r
+       // Get root Inode\r
+       Ext2_int_ReadInode(disk, 2, &inode);\r
+       \r
+       // Create Root Node\r
+       memset(&disk->RootNode, 0, sizeof(tVFS_Node));\r
+       disk->RootNode.Inode = 2;       // Root inode ID\r
+       disk->RootNode.ImplPtr = disk;  // Save disk pointer\r
+       disk->RootNode.Size = -1;       // Fill in later (on readdir)\r
+       disk->RootNode.Flags = VFS_FFLAG_DIRECTORY;\r
+       \r
+       disk->RootNode.ReadDir = Ext2_ReadDir;\r
+       disk->RootNode.FindDir = Ext2_FindDir;\r
+       //disk->RootNode.Relink = Ext2_Relink;\r
+       \r
+       // Complete root node\r
+       disk->RootNode.UID = inode.i_uid;\r
+       disk->RootNode.GID = inode.i_gid;\r
+       disk->RootNode.NumACLs = 1;\r
+       disk->RootNode.ACLs = &gVFS_ACL_EveryoneRW;\r
+       \r
+       #if DEBUG\r
+       LOG("inode.i_size = 0x%x", inode.i_size);\r
+       LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);\r
+       #endif\r
+       \r
+       LEAVE('p', &disk->RootNode);\r
+       return &disk->RootNode;\r
+}\r
+\r
+/**\r
+ * \fn void Ext2_Unmount(tVFS_Node *Node)\r
+ * \brief Close a mounted device\r
+ */\r
+void Ext2_Unmount(tVFS_Node *Node)\r
+{\r
+       tExt2_Disk      *disk = Node->ImplPtr;\r
+       \r
+       VFS_Close( disk->FD );\r
+       Inode_ClearCache( disk->CacheID );\r
+       memset(disk, 0, sizeof(tExt2_Disk)+disk->GroupCount*sizeof(tExt2_Group));\r
+       free(disk);\r
+}\r
+\r
+/**\r
+ * \fn void Ext2_CloseFile(tVFS_Node *Node)\r
+ * \brief Close a file (Remove it from the cache)\r
+ */\r
+void Ext2_CloseFile(tVFS_Node *Node)\r
+{\r
+       tExt2_Disk      *disk = Node->ImplPtr;\r
+       Inode_UncacheNode(disk->CacheID, Node->Inode);\r
+       return ;\r
+}\r
+\r
+//==================================\r
+//=       INTERNAL FUNCTIONS       =\r
+//==================================\r
+\r
+\r
+/**\r
+ * \fn int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode)\r
+ * \brief Gets the inode descriptor for a node\r
+ * \param Node node to get the Inode of\r
+ * \param Inode        Destination\r
+ */\r
+int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode)\r
+{\r
+       return Ext2_int_ReadInode(Node->ImplPtr, Node->Inode, Inode);\r
+}\r
+\r
+/**\r
+ * \fn int Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode)\r
+ * \brief Read an inode into memory\r
+ */\r
+int Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode)\r
+{\r
+        int    group, subId;\r
+       \r
+       //LogF("Ext2_int_ReadInode: (Disk=%p, InodeId=%i, Inode=%p)", Disk, InodeId, Inode);\r
+       //ENTER("pDisk iInodeId pInode", Disk, InodeId, Inode);\r
+       \r
+       if(InodeId == 0)        return 0;\r
+       \r
+       InodeId --;     // Inodes are numbered starting at 1\r
+       \r
+       group = InodeId / Disk->SuperBlock.s_inodes_per_group;\r
+       subId = InodeId % Disk->SuperBlock.s_inodes_per_group;\r
+       \r
+       //LOG("group=%i, subId = %i", group, subId);\r
+       \r
+       // Read Inode\r
+       VFS_ReadAt(Disk->FD,\r
+               Disk->Groups[group].bg_inode_table * Disk->BlockSize + sizeof(tExt2_Inode)*subId,\r
+               sizeof(tExt2_Inode),\r
+               Inode);\r
+       return 1;\r
+}\r
+\r
+/**\r
+ * \fn Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)\r
+ * \brief Get the address of a block from an inode's list\r
+ * \param Disk Disk information structure\r
+ * \param Blocks       Pointer to an inode's block list\r
+ * \param BlockNum     Block index in list\r
+ */\r
+Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)\r
+{\r
+       Uint32  *iBlocks;\r
+       // Direct Blocks\r
+       if(BlockNum < 12)\r
+               return (Uint64)Blocks[BlockNum] * Disk->BlockSize;\r
+       \r
+       // Single Indirect Blocks\r
+       iBlocks = malloc( Disk->BlockSize );\r
+       VFS_ReadAt(Disk->FD, (Uint64)Blocks[12]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
+       \r
+       BlockNum -= 12;\r
+       if(BlockNum < 256) {\r
+               BlockNum = iBlocks[BlockNum];\r
+               free(iBlocks);\r
+               return (Uint64)BlockNum * Disk->BlockSize;\r
+       }\r
+       \r
+       // Double Indirect Blocks\r
+       if(BlockNum < 256*256)\r
+       {\r
+               VFS_ReadAt(Disk->FD, (Uint64)Blocks[13]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
+               VFS_ReadAt(Disk->FD, (Uint64)iBlocks[BlockNum/256]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
+               BlockNum = iBlocks[BlockNum%256];\r
+               free(iBlocks);\r
+               return (Uint64)BlockNum * Disk->BlockSize;\r
+       }\r
+       // Triple Indirect Blocks\r
+       VFS_ReadAt(Disk->FD, (Uint64)Blocks[14]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
+       VFS_ReadAt(Disk->FD, (Uint64)iBlocks[BlockNum/(256*256)]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
+       VFS_ReadAt(Disk->FD, (Uint64)iBlocks[(BlockNum/256)%256]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
+       BlockNum = iBlocks[BlockNum%256];\r
+       free(iBlocks);\r
+       return (Uint64)BlockNum * Disk->BlockSize;\r
+}\r
+\r
+/**\r
+ * \fn Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)\r
+ * \brief Allocate an inode (from the current group preferably)\r
+ * \param Disk EXT2 Disk Information Structure\r
+ * \param Parent       Inode ID of the parent (used to locate the child nearby)\r
+ */\r
+Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)\r
+{\r
+//     Uint    block = (Parent - 1) / Disk->SuperBlock.s_inodes_per_group;\r
+       return 0;\r
+}\r
+\r
+/**\r
+ * \fn void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
+ * \brief Updates the superblock\r
+ */\r
+void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
+{\r
+        int    bpg = Disk->SuperBlock.s_blocks_per_group;\r
+        int    ngrp = Disk->SuperBlock.s_blocks_count / bpg;\r
+        int    i;\r
+        \r
+       // Update Primary\r
+       VFS_WriteAt(Disk->FD, 1024, 1024, &Disk->SuperBlock);\r
+       \r
+       // Secondaries\r
+       // at Block Group 1, 3^n, 5^n, 7^n\r
+       \r
+       // 1\r
+       if(ngrp <= 1)   return;\r
+       VFS_WriteAt(Disk->FD, 1*bpg*Disk->BlockSize, 1024, &Disk->SuperBlock);\r
+       \r
+       // Powers of 3\r
+       for( i = 3; i < ngrp; i *= 3 )\r
+               VFS_WriteAt(Disk->FD, i*bpg*Disk->BlockSize, 1024, &Disk->SuperBlock);\r
+       \r
+       // Powers of 5\r
+       for( i = 5; i < ngrp; i *= 5 )\r
+               VFS_WriteAt(Disk->FD, i*bpg*Disk->BlockSize, 1024, &Disk->SuperBlock);\r
+       \r
+       // Powers of 7\r
+       for( i = 7; i < ngrp; i *= 7 )\r
+               VFS_WriteAt(Disk->FD, i*bpg*Disk->BlockSize, 1024, &Disk->SuperBlock);\r
+}\r
diff --git a/Modules/Filesystems/FS_Ext2/ext2_common.h b/Modules/Filesystems/FS_Ext2/ext2_common.h
new file mode 100644 (file)
index 0000000..2e2baba
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Acess OS
+ * Ext2 Driver Version 1
+ */
+/**
+ * \file ext2_common.h
+ * \brief Second Extended Filesystem Driver
+ */
+#ifndef _EXT2_COMMON_H
+#define _EXT2_COMMON_H
+#include <acess.h>
+#include <vfs.h>
+#include "ext2fs.h"
+
+#define EXT2_UPDATE_WRITEBACK  1
+
+// === STRUCTURES ===
+typedef struct {
+        int    FD;
+        int    CacheID;
+       tVFS_Node       RootNode;
+       
+       tExt2_SuperBlock        SuperBlock;
+        int    BlockSize;
+        
+        int    GroupCount;
+       tExt2_Group             Groups[];
+} tExt2_Disk;
+
+// === FUNCTIONS ===
+// --- Common ---
+extern void    Ext2_CloseFile(tVFS_Node *Node);
+extern int     Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode);
+extern Uint64  Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);
+extern void    Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);
+// --- Dir ---
+extern char    *Ext2_ReadDir(tVFS_Node *Node, int Pos);
+extern tVFS_Node       *Ext2_FindDir(tVFS_Node *Node, char *FileName);
+extern int     Ext2_MkNod(tVFS_Node *Node, char *Name, Uint Flags);
+// --- Read ---
+extern Uint64  Ext2_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
+extern int     Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode);
+// --- Write ---
+extern Uint64  Ext2_Write(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
+
+#endif
diff --git a/Modules/Filesystems/FS_Ext2/ext2fs.h b/Modules/Filesystems/FS_Ext2/ext2fs.h
new file mode 100644 (file)
index 0000000..8fd87ce
--- /dev/null
@@ -0,0 +1,156 @@
+/**\r
+ * Acess2\r
+ * \file ext2fs.h\r
+ * \brief EXT2 Filesystem Driver\r
+ */\r
+#ifndef _EXT2FS_H_\r
+#define _EXT2FS_H_\r
+\r
+/**\r
+ \name Inode Flag Values\r
+ \{\r
+*/\r
+#define EXT2_S_IFMT            0xF000  //!< Format Mask\r
+#define EXT2_S_IFSOCK  0xC000  //!< Socket\r
+#define EXT2_S_IFLNK   0xA000  //!< Symbolic Link\r
+#define EXT2_S_IFREG   0x8000  //!< Regular File\r
+#define EXT2_S_IFBLK   0x6000  //!< Block Device\r
+#define EXT2_S_IFDIR   0x4000  //!< Directory\r
+#define EXT2_S_IFCHR   0x2000  //!< Character Device\r
+#define EXT2_S_IFIFO   0x1000  //!< FIFO\r
+#define EXT2_S_ISUID   0x0800  //!< SUID\r
+#define EXT2_S_ISGID   0x0400  //!< SGID\r
+#define EXT2_S_ISVTX   0x0200  //!< sticky bit\r
+#define EXT2_S_IRWXU   0700    //!< user access rights mask\r
+#define EXT2_S_IRUSR   0400    //!< Owner Read\r
+#define EXT2_S_IWUSR   0200    //!< Owner Write\r
+#define EXT2_S_IXUSR   0100    //!< Owner Execute\r
+#define EXT2_S_IRWXG   0070    //!< Group Access rights mask\r
+#define EXT2_S_IRGRP   0040    //!< Group Read\r
+#define EXT2_S_IWGRP   0020    //!< Group Write\r
+#define EXT2_S_IXGRP   0010    //!< Group Execute\r
+#define EXT2_S_IRWXO   0007    //!< Global Access rights mask\r
+#define EXT2_S_IROTH   0004    //!< Global Read\r
+#define EXT2_S_IWOTH   0002    //!< Global Write\r
+#define EXT2_S_IXOTH   0001    //!< Global Execute\r
+//! \}\r
+\r
+#define EXT2_NAME_LEN 255      //!< Maximum Name Length\r
+\r
+// === TYPEDEFS ===\r
+typedef struct ext2_inode_s                    tExt2_Inode;    //!< Inode Type\r
+typedef struct ext2_super_block_s      tExt2_SuperBlock;       //!< Superblock Type\r
+typedef struct ext2_group_desc_s       tExt2_Group;    //!< Group Descriptor Type\r
+typedef struct ext2_dir_entry_s                tExt2_DirEnt;   //!< Directory Entry Type\r
+\r
+// === STRUCTURES ===\r
+/**\r
+ * \brief EXT2 Superblock Structure\r
+ */\r
+struct ext2_super_block_s {\r
+       Uint32  s_inodes_count;         //!< Inodes count\r
+       Uint32  s_blocks_count;         //!< Blocks count\r
+       Uint32  s_r_blocks_count;       //!< Reserved blocks count\r
+       Uint32  s_free_blocks_count;    //!< Free blocks count\r
+       Uint32  s_free_inodes_count;    //!< Free inodes count\r
+       Uint32  s_first_data_block;     //!< First Data Block\r
+       Uint32  s_log_block_size;       //!< Block size\r
+       Sint32  s_log_frag_size;        //!< Fragment size\r
+       Uint32  s_blocks_per_group;     //!< Number Blocks per group\r
+       Uint32  s_frags_per_group;      //!< Number Fragments per group\r
+       Uint32  s_inodes_per_group;     //!< Number Inodes per group\r
+       Uint32  s_mtime;                        //!< Mount time\r
+       Uint32  s_wtime;                        //!< Write time\r
+       Uint16  s_mnt_count;            //!< Mount count\r
+       Sint16  s_max_mnt_count;        //!< Maximal mount count\r
+       Uint16  s_magic;                        //!< Magic signature\r
+       Uint16  s_state;                        //!< File system state\r
+       Uint16  s_errors;                       //!< Behaviour when detecting errors\r
+       Uint16  s_pad;                          //!< Padding\r
+       Uint32  s_lastcheck;            //!< time of last check\r
+       Uint32  s_checkinterval;        //!< max. time between checks\r
+       Uint32  s_creator_os;           //!< Formatting OS\r
+       Uint32  s_rev_level;            //!< Revision level\r
+       Uint16  s_def_resuid;           //!< Default uid for reserved blocks\r
+       Uint16  s_def_resgid;           //!< Default gid for reserved blocks\r
+       Uint32  s_reserved[235];        //!< Padding to the end of the block\r
+};\r
+\r
+/**\r
+ * \struct ext2_inode_s\r
+ * \brief EXT2 Inode Definition\r
+ */\r
+struct ext2_inode_s {\r
+       Uint16 i_mode;  //!< File mode\r
+       Uint16 i_uid;   //!< Owner Uid\r
+       Uint32 i_size;  //!< Size in bytes\r
+       Uint32 i_atime; //!< Access time\r
+       Uint32 i_ctime; //!< Creation time\r
+       Uint32 i_mtime; //!< Modification time\r
+       Uint32 i_dtime; //!< Deletion Time\r
+       Uint16 i_gid;   //!< Group Id\r
+       Uint16 i_links_count;   //!< Links count\r
+       Uint32 i_blocks;        //!< Number of blocks allocated for the file\r
+       Uint32 i_flags; //!< File flags\r
+       union {\r
+               Uint32 linux_reserved1; //!< Linux: Reserved\r
+               Uint32 hurd_translator; //!< HURD: Translator\r
+               Uint32 masix_reserved1; //!< Masix: Reserved\r
+       } osd1; //!< OS dependent 1\r
+       Uint32 i_block[15];     //!< Pointers to blocks\r
+       Uint32 i_version;       //!< File version (for NFS)\r
+       Uint32 i_file_acl;      //!< File ACL\r
+       Uint32 i_dir_acl;       //!< Directory ACL / Extended File Size\r
+       Uint32 i_faddr;         //!< Fragment address\r
+       union {\r
+               struct {\r
+                       Uint8 l_i_frag; //!< Fragment number\r
+                       Uint8 l_i_fsize;        //!< Fragment size\r
+                       Uint16 i_pad1;  //!< Padding\r
+                       Uint32 l_i_reserved2[2];        //!< Reserved\r
+               } linux2;\r
+               struct {\r
+                       Uint8 h_i_frag; //!< Fragment number\r
+                       Uint8 h_i_fsize; //!< Fragment size\r
+                       Uint16 h_i_mode_high;   //!< Mode High Bits\r
+                       Uint16 h_i_uid_high;    //!< UID High Bits\r
+                       Uint16 h_i_gid_high;    //!< GID High Bits\r
+                       Uint32 h_i_author;      //!< Creator ID\r
+               } hurd2;\r
+               struct {\r
+                       Uint8 m_i_frag; //!< Fragment number\r
+                       Uint8 m_i_fsize;        //!< Fragment size\r
+                       Uint16 m_pad1;  //!< Padding\r
+                       Uint32 m_i_reserved2[2];        //!< reserved\r
+               } masix2;\r
+       } osd2; //!< OS dependent 2\r
+};\r
+\r
+/**\r
+ * \struct ext2_group_desc_s\r
+ * \brief EXT2 Group Descriptor\r
+ */\r
+struct ext2_group_desc_s {\r
+       Uint32  bg_block_bitmap;        //!< Blocks bitmap block\r
+       Uint32  bg_inode_bitmap;        //!< Inodes bitmap block\r
+       Uint32  bg_inode_table; //!< Inodes table block\r
+       Uint16  bg_free_blocks_count;   //!< Free blocks count\r
+       Uint16  bg_free_inodes_count;   //!< Free inodes count\r
+       Uint16  bg_used_dirs_count;     //!< Directories count\r
+       Uint16  bg_pad; //!< Padding\r
+       Uint32  bg_reserved[3]; //!< Reserved\r
+};\r
+\r
+/**\r
+ * \brief EXT2 Directory Entry\r
+ * \note The name may take up less than 255 characters\r
+ */\r
+struct ext2_dir_entry_s {\r
+       Uint32  inode;          //!< Inode number\r
+       Uint16  rec_len;        //!< Directory entry length\r
+       Uint8   name_len;       //!< Short Name Length\r
+       Uint8   type;           //!< File Type\r
+       char    name[];         //!< File name\r
+};\r
+\r
+#endif\r
diff --git a/Modules/Filesystems/FS_Ext2/read.c b/Modules/Filesystems/FS_Ext2/read.c
new file mode 100644 (file)
index 0000000..cb6649a
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Acess OS
+ * Ext2 Driver Version 1
+ */
+/**
+ * \file read.c
+ * \brief Second Extended Filesystem Driver
+ * \todo Implement file full write support
+ */
+#define DEBUG  1
+#define VERBOSE        0
+#include "ext2_common.h"
+
+// === PROTOTYPES ===
+Uint64         Ext2_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
+ int           Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode);
+
+// === CODE ===
+/**
+ * \fn Uint64 Ext2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+ * \brief Read from a file
+ */
+Uint64 Ext2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       tExt2_Disk      *disk = Node->ImplPtr;
+       tExt2_Inode     inode;
+       Uint64  base;
+       Uint    block;
+       Uint64  remLen;
+       
+       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
+       
+       // Get Inode
+       Ext2_int_GetInode(Node, &inode);
+       
+       // Sanity Checks
+       if(Offset >= inode.i_size) {
+               LEAVE('i', 0);
+               return 0;
+       }
+       if(Offset + Length > inode.i_size)
+               Length = inode.i_size - Offset;
+       
+       block = Offset / disk->BlockSize;
+       Offset = Offset / disk->BlockSize;
+       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
+       if(base == 0) {
+               Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode);
+               LEAVE('i', 0);
+               return 0;
+       }
+       
+       // Read only block
+       if(Length <= disk->BlockSize - Offset)
+       {
+               VFS_ReadAt( disk->FD, base+Offset, Length, Buffer);
+               LEAVE('X', Length);
+               return Length;
+       }
+       
+       // Read first block
+       remLen = Length;
+       VFS_ReadAt( disk->FD, base + Offset, disk->BlockSize - Offset, Buffer);
+       remLen -= disk->BlockSize - Offset;
+       Buffer += disk->BlockSize - Offset;
+       block ++;
+       
+       // Read middle blocks
+       while(remLen > disk->BlockSize)
+       {
+               base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
+               if(base == 0) {
+                       Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode);
+                       LEAVE('i', 0);
+                       return 0;
+               }
+               VFS_ReadAt( disk->FD, base, disk->BlockSize, Buffer);
+               Buffer += disk->BlockSize;
+               remLen -= disk->BlockSize;
+               block ++;
+       }
+       
+       // Read last block
+       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
+       VFS_ReadAt( disk->FD, base, remLen, Buffer);
+       
+       LEAVE('X', Length);
+       return Length;
+}
diff --git a/Modules/Filesystems/FS_Ext2/write.c b/Modules/Filesystems/FS_Ext2/write.c
new file mode 100644 (file)
index 0000000..f3fdc6b
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Acess OS
+ * Ext2 Driver Version 1
+ */
+/**
+ * \file write.c
+ * \brief Second Extended Filesystem Driver
+ * \todo Implement file full write support
+ */
+#define DEBUG  1
+#define VERBOSE        0
+#include "ext2_common.h"
+
+// === PROTOYPES ===
+Uint64         Ext2_Write(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
+Uint32         Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock);
+
+// === CODE ===
+/**
+ * \fn Uint64 Ext2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+ * \brief Write to a file
+ */
+Uint64 Ext2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       tExt2_Disk      *disk = Node->ImplPtr;
+       tExt2_Inode     inode;
+       Uint64  base;
+       Uint64  retLen;
+       Uint    block;
+       Uint64  allocSize;
+        int    bNewBlocks = 0;
+       
+       Debug_HexDump("Ext2_Write", Buffer, Length);
+       
+       Ext2_int_GetInode(Node, &inode);
+       
+       // Get the ammount of space already allocated
+       // - Round size up to block size
+       // - block size is a power of two, so this will work
+       allocSize = (inode.i_size + disk->BlockSize) & ~(disk->BlockSize-1);
+       
+       // Are we writing to inside the allocated space?
+       if( Offset < allocSize )
+       {
+               // Will we go out of it?
+               if(Offset + Length > allocSize) {
+                       bNewBlocks = 1;
+                       retLen = allocSize - Offset;
+               } else
+                       retLen = Length;
+               
+               // Within the allocated space
+               block = Offset / disk->BlockSize;
+               Offset %= disk->BlockSize;
+               base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
+               
+               // Write only block (if only one)
+               if(Offset + retLen <= disk->BlockSize) {
+                       VFS_WriteAt(disk->FD, base+Offset, retLen, Buffer);
+                       if(!bNewBlocks) return Length;
+                       goto addBlocks; // Ugh! A goto, but it seems unavoidable
+               }
+               
+               // Write First Block
+               VFS_WriteAt(disk->FD, base+Offset, disk->BlockSize-Offset, Buffer);
+               Buffer += disk->BlockSize-Offset;
+               retLen -= disk->BlockSize-Offset;
+               block ++;
+               
+               // Write middle blocks
+               while(retLen > disk->BlockSize)
+               {
+                       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
+                       VFS_WriteAt(disk->FD, base, disk->BlockSize, Buffer);
+                       Buffer += disk->BlockSize;
+                       retLen -= disk->BlockSize;
+                       block ++;
+               }
+               
+               // Write last block
+               base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
+               VFS_WriteAt(disk->FD, base, retLen, Buffer);
+               if(!bNewBlocks) return Length;  // Writing in only allocated space
+       }
+       
+addBlocks:
+       ///\todo Implement block allocation
+       Warning("[EXT2] File extending is not yet supported");
+       
+       return 0;
+}
+
+/**
+ * \fn Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock)
+ * \brief Allocate a block from the best possible location
+ * \param Disk EXT2 Disk Information Structure
+ * \param PrevBlock    Previous block ID in the file
+ */
+Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock)
+{
+        int    bpg = Disk->SuperBlock.s_blocks_per_group;
+       Uint    blockgroup = PrevBlock / bpg;
+       Uint    bitmap[Disk->BlockSize/sizeof(Uint)];
+       Uint    bitsperblock = 8*Disk->BlockSize;
+        int    i, j = 0;
+       Uint    block;
+       
+       // Are there any free blocks?
+       if(Disk->SuperBlock.s_free_blocks_count == 0)   return 0;
+       
+       if(Disk->Groups[blockgroup].bg_free_blocks_count > 0)
+       {
+               // Search block group's bitmap
+               for(i = 0; i < bpg; i++)
+               {
+                       // Get the block in the bitmap block
+                       j = i & (bitsperblock-1);
+                       
+                       // Read in if needed
+                       if(j == 0) {
+                               VFS_ReadAt(
+                                       Disk->FD,
+                                       (Uint64)Disk->Groups[blockgroup].bg_block_bitmap + i / bitsperblock,
+                                       Disk->BlockSize,
+                                       bitmap
+                                       );
+                       }
+                       
+                       // Fast Check
+                       if( bitmap[j/32] == -1 ) {
+                               j = (j + 31) & ~31;
+                               continue;
+                       }
+                       
+                       // Is the bit set?
+                       if( bitmap[j/32] & (1 << (j%32)) )
+                               continue;
+                       
+                       // Ooh! We found one
+                       break;
+               }
+               if( i < bpg ) {
+                       Warning("[EXT2 ] Inconsistency detected, Group Free Block count is non-zero when no free blocks exist");
+                       goto    checkAll;       // Search the entire filesystem for a free block
+                       // Goto needed for neatness
+               }
+               
+               // Mark as used
+               bitmap[j/32] |= (1 << (j%32));
+               VFS_WriteAt(
+                       Disk->FD,
+                       (Uint64)Disk->Groups[blockgroup].bg_block_bitmap + i / bitsperblock,
+                       Disk->BlockSize,
+                       bitmap
+                       );
+               block = i;
+               Disk->Groups[blockgroup].bg_free_blocks_count --;
+               #if EXT2_UPDATE_WRITEBACK
+               //Ext2_int_UpdateBlockGroup(blockgroup);
+               #endif
+       }
+       else
+       {
+       checkAll:
+               Warning("[EXT2 ] TODO - Implement using blocks outside the current block group");
+               return 0;
+       }
+       
+       // Reduce global count
+       Disk->SuperBlock.s_free_blocks_count --;
+       #if EXT2_UPDATE_WRITEBACK
+       Ext2_int_UpdateSuperblock(Disk);
+       #endif
+       
+       return block;
+}
diff --git a/Modules/Filesystems/Makefile.tpl b/Modules/Filesystems/Makefile.tpl
new file mode 100644 (file)
index 0000000..80c6d4d
--- /dev/null
@@ -0,0 +1 @@
+-include ../../Makefile.tpl
diff --git a/Modules/Interfaces/Makefile.tpl b/Modules/Interfaces/Makefile.tpl
new file mode 100644 (file)
index 0000000..80c6d4d
--- /dev/null
@@ -0,0 +1 @@
+-include ../../Makefile.tpl
diff --git a/Modules/Interfaces/UDI/Makefile b/Modules/Interfaces/UDI/Makefile
new file mode 100644 (file)
index 0000000..4c199f1
--- /dev/null
@@ -0,0 +1,10 @@
+#
+#
+
+CPPFLAGS = -I./include
+OBJ  = main.o logging.o strmem.o imc.o mem.o buf.o cb.o
+OBJ += meta_mgmt.o meta_gio.o
+OBJ += physio.o physio/meta_bus.o physio/meta_intr.o
+NAME = UDI
+
+-include ../Makefile.tpl
diff --git a/Modules/Interfaces/UDI/buf.c b/Modules/Interfaces/UDI/buf.c
new file mode 100644 (file)
index 0000000..3255911
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * \file buf.c
+ * \author John Hodge (thePowersGang)
+ */
+#include <acess.h>
+#include <udi.h>
+
+// === EXPORTS ===
+EXPORT(udi_buf_copy);
+EXPORT(udi_buf_write);
+EXPORT(udi_buf_read);
+EXPORT(udi_buf_free);
+
+// === CODE ===
+void udi_buf_copy(
+       udi_buf_copy_call_t *callback,
+       udi_cb_t        *gcb,
+       udi_buf_t       *src_buf,
+       udi_size_t      src_off,
+       udi_size_t      src_len,
+       udi_buf_t       *dst_buf,
+       udi_size_t      dst_off,
+       udi_size_t      dst_len,
+       udi_buf_path_t path_handle
+       )
+{
+       UNIMPLEMENTED();
+}
+
+void udi_buf_write(
+       udi_buf_write_call_t *callback,
+       udi_cb_t        *gcb,
+       const void      *src_mem,
+       udi_size_t      src_len,
+       udi_buf_t       *dst_buf,
+       udi_size_t      dst_off,
+       udi_size_t      dst_len,
+       udi_buf_path_t path_handle
+       )
+{
+       UNIMPLEMENTED();
+}
+
+void udi_buf_read(
+       udi_buf_t       *src_buf,
+       udi_size_t      src_off,
+       udi_size_t      src_len,
+       void    *dst_mem )
+{
+       UNIMPLEMENTED();
+}
+
+void udi_buf_free(udi_buf_t *buf)
+{
+       UNIMPLEMENTED();
+}
diff --git a/Modules/Interfaces/UDI/cb.c b/Modules/Interfaces/UDI/cb.c
new file mode 100644 (file)
index 0000000..78be97b
--- /dev/null
@@ -0,0 +1,59 @@
+/**
+ * \file cb.c
+ * \author John Hodge (thePowersGang)
+ */
+#include <acess.h>
+#include <udi.h>
+
+// === EXPORTS ===
+EXPORT(udi_cb_alloc);
+EXPORT(udi_cb_alloc_dynamic);
+EXPORT(udi_cb_alloc_batch);
+EXPORT(udi_cb_free);
+EXPORT(udi_cancel);
+
+// === CODE ===
+void udi_cb_alloc (
+       udi_cb_alloc_call_t *callback,
+       udi_cb_t *gcb,
+       udi_index_t cb_idx,
+       udi_channel_t default_channel
+       )
+{
+       UNIMPLEMENTED();
+}
+
+void udi_cb_alloc_dynamic(
+       udi_cb_alloc_call_t     *callback,
+       udi_cb_t        *gcb,
+       udi_index_t     cb_idx,
+       udi_channel_t   default_channel,
+       udi_size_t      inline_size,
+       udi_layout_t    *inline_layout
+       )
+{
+       UNIMPLEMENTED();
+}
+
+void udi_cb_alloc_batch(
+       udi_cb_alloc_batch_call_t       *callback,
+       udi_cb_t        *gcb,
+       udi_index_t     cb_idx,
+       udi_index_t     count,
+       udi_boolean_t   with_buf,
+       udi_size_t      buf_size,
+       udi_buf_path_t  path_handle
+       )
+{
+       UNIMPLEMENTED();
+}
+
+void udi_cb_free(udi_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+
+void udi_cancel(udi_cancel_call_t *callback, udi_cb_t *gcb)
+{
+       UNIMPLEMENTED();
+}
diff --git a/Modules/Interfaces/UDI/imc.c b/Modules/Interfaces/UDI/imc.c
new file mode 100644 (file)
index 0000000..cd15e07
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * \file imc.c
+ * \author John Hodge (thePowersGang)
+ */
+#include <acess.h>
+#include <udi.h>
+
+// === EXPORTS ===
+EXPORT(udi_channel_anchor);
+EXPORT(udi_channel_spawn);
+EXPORT(udi_channel_set_context);
+EXPORT(udi_channel_op_abort);
+EXPORT(udi_channel_close);
+EXPORT(udi_channel_event_ind);
+EXPORT(udi_channel_event_complete);
+
+// === CODE ===
+/**
+ */
+void udi_channel_anchor(
+       udi_channel_anchor_call_t *callback, udi_cb_t *gcb,
+       udi_channel_t channel, udi_index_t ops_idx, void *channel_context
+       )
+{
+       Warning("%s Unimplemented", __func__);
+}
+
+/**
+ */
+extern void udi_channel_spawn(
+       udi_channel_spawn_call_t *callback, udi_cb_t *gcb,
+       udi_channel_t channel, udi_index_t spawn_idx,
+       udi_index_t ops_idx, void *channel_context
+       )
+{
+       Warning("%s Unimplemented", __func__);
+}
+
+/**
+ * 
+ */
+void udi_channel_set_context(
+       udi_channel_t target_channel, void *channel_context
+       )
+{
+       Warning("%s Unimplemented", __func__);
+}
+
+void udi_channel_op_abort(
+       udi_channel_t target_channel, udi_cb_t *orig_cb
+       )
+{
+       Warning("%s Unimplemented", __func__);
+}
+
+void udi_channel_close(udi_channel_t channel)
+{
+       Warning("%s Unimplemented", __func__);
+}
+
+void udi_channel_event_ind(udi_channel_event_cb_t *cb)
+{
+       udi_channel_event_complete(cb, UDI_OK);
+}
+
+void udi_channel_event_complete(udi_channel_event_cb_t *cb, udi_status_t status)
+{
+       Warning("%s Unimplemented", __func__);
+}
diff --git a/Modules/Interfaces/UDI/include/physio/meta_bus.h b/Modules/Interfaces/UDI/include/physio/meta_bus.h
new file mode 100644 (file)
index 0000000..7b88ece
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * \file physio/meta_bus.h
+ */
+#ifndef _PHYSIO_META_BUS_H_
+#define _PHYSIO_META_BUS_H_
+
+#include <udi.h>
+#include <udi_physio.h>
+
+typedef const struct udi_bus_device_ops_s      udi_bus_device_ops_t;
+typedef const struct udi_bus_bridge_ops_s      udi_bus_bridge_ops_t;
+typedef struct udi_bus_bind_cb_s       udi_bus_bind_cb_t;
+typedef void   udi_bus_unbind_req_op_t(udi_bus_bind_cb_t *cb);
+typedef void   udi_bus_unbind_ack_op_t(udi_bus_bind_cb_t *cb);
+typedef void   udi_bus_bind_req_op_t(udi_bus_bind_cb_t *cb);
+typedef void   udi_bus_bind_ack_op_t(
+       udi_bus_bind_cb_t       *cb,
+       udi_dma_constraints_t   dma_constraints,
+       udi_ubit8_t     preferred_endianness,
+       udi_status_t    status
+       );
+
+
+struct udi_bus_device_ops_s
+{
+       udi_channel_event_ind_op_t      *channel_event_ind_op;
+       udi_bus_bind_ack_op_t   *bus_bind_ack_op;
+       udi_bus_unbind_ack_op_t *bus_unbind_ack_op;
+       udi_intr_attach_ack_op_t        *intr_attach_ack_op;
+       udi_intr_detach_ack_op_t        *intr_detach_ack_op;
+};
+/* Bus Device Ops Vector Number */
+#define UDI_BUS_DEVICE_OPS_NUM            1
+
+struct udi_bus_bridge_ops_s
+{
+     udi_channel_event_ind_op_t        *channel_event_ind_op;
+     udi_bus_bind_req_op_t     *bus_bind_req_op;
+     udi_bus_unbind_req_op_t   *bus_unbind_req_op;
+     udi_intr_attach_req_op_t  *intr_attach_req_op;
+     udi_intr_detach_req_op_t  *intr_detach_req_op;
+};
+/* Bus Bridge Ops Vector Number */
+#define UDI_BUS_BRIDGE_OPS_NUM
+
+struct udi_bus_bind_cb_s
+{
+     udi_cb_t gcb;
+};
+/* Bus Bind Control Block Group Number */
+#define UDI_BUS_BIND_CB_NUM              1
+
+
+extern void udi_bus_bind_req(udi_bus_bind_cb_t *cb);
+
+extern void udi_bus_bind_ack(
+       udi_bus_bind_cb_t       *cb,
+       udi_dma_constraints_t   dma_constraints,
+       udi_ubit8_t     preferred_endianness,
+       udi_status_t    status
+       );
+/* Values for preferred_endianness */
+#define UDI_DMA_BIG_ENDIAN                (1U<<5)
+#define UDI_DMA_LITTLE_ENDIAN             (1U<<6)
+#define UDI_DMA_ANY_ENDIAN                (1U<<0)
+
+extern void udi_bus_unbind_req(udi_bus_bind_cb_t *cb);
+extern void udi_bus_unbind_ack(udi_bus_bind_cb_t *cb);
+
+
+
+
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/physio/meta_intr.h b/Modules/Interfaces/UDI/include/physio/meta_intr.h
new file mode 100644 (file)
index 0000000..d5dd394
--- /dev/null
@@ -0,0 +1,100 @@
+/**
+ * \file physio/meta_intr.h
+ */
+#ifndef _PHYSIO_META_INTR_H_
+#define _PHYSIO_META_INTR_H_
+
+#include <udi.h>
+#include <udi_physio.h>
+#include "pio.h"
+
+typedef struct udi_intr_attach_cb_s    udi_intr_attach_cb_t;
+typedef void   udi_intr_attach_req_op_t(udi_intr_attach_cb_t *intr_attach_cb);
+typedef void   udi_intr_attach_ack_op_t(
+       udi_intr_attach_cb_t *intr_attach_cb,
+       udi_status_t status
+       );
+typedef struct udi_intr_detach_cb_s    udi_intr_detach_cb_t;
+typedef void   udi_intr_detach_req_op_t(udi_intr_detach_cb_t *intr_detach_cb);
+typedef void   udi_intr_detach_ack_op_t(udi_intr_detach_cb_t *intr_detach_cb);
+typedef const struct udi_intr_handler_ops_s    udi_intr_handler_ops_t;
+typedef const struct udi_intr_dispatcher_ops_s udi_intr_dispatcher_ops_t;
+typedef struct udi_intr_event_cb_s     udi_intr_event_cb_t;
+typedef void   udi_intr_event_ind_op_t(udi_intr_event_cb_t *intr_event_cb, udi_ubit8_t flags);
+typedef void   udi_intr_event_rdy_op_t(udi_intr_event_cb_t *intr_event_cb);
+
+
+struct udi_intr_attach_cb_s
+{
+       udi_cb_t        gcb;
+       udi_index_t     interrupt_idx;
+       udi_ubit8_t     min_event_pend;
+       udi_pio_handle_t        preprocessing_handle;
+};
+/* Bridge Attach Control Block Group Number */
+#define UDI_BUS_INTR_ATTACH_CB_NUM        2
+
+struct udi_intr_detach_cb_s
+{
+       udi_cb_t        gcb;
+       udi_index_t     interrupt_idx;
+};
+/* Bridge Detach Control Block Group Number */
+#define UDI_BUS_INTR_DETACH_CB_NUM       3
+
+struct udi_intr_handler_ops_s
+{
+       udi_channel_event_ind_op_t      *channel_event_ind_op;
+       udi_intr_event_ind_op_t *intr_event_ind_op;
+};
+/* Interrupt Handler Ops Vector Number */
+#define UDI_BUS_INTR_HANDLER_OPS_NUM      3
+
+struct udi_intr_dispatcher_ops_s
+{
+       udi_channel_event_ind_op_t      *channel_event_ind_op;
+       udi_intr_event_rdy_op_t *intr_event_rdy_op;
+};
+/* Interrupt Dispatcher Ops Vector Number */
+#define UDI_BUS_INTR_DISPATCH_OPS_NUM     4
+
+struct udi_intr_event_cb_s
+{
+       udi_cb_t        gcb;
+       udi_buf_t       *event_buf;
+       udi_ubit16_t    intr_result;
+};
+/* Flag values for interrupt handling */
+#define UDI_INTR_UNCLAIMED               (1U<<0)
+#define UDI_INTR_NO_EVENT                (1U<<1)
+/* Bus Interrupt Event Control Block Group Number */
+#define UDI_BUS_INTR_EVENT_CB_NUM        4
+
+
+
+extern void udi_intr_attach_req(udi_intr_attach_cb_t *intr_attach_cb);
+extern void udi_intr_attach_ack(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status);
+extern void udi_intr_attach_ack_unused(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status);
+
+extern void udi_intr_detach_req(udi_intr_detach_cb_t *intr_detach_cb);
+extern void udi_intr_detach_ack(udi_intr_detach_cb_t *intr_detach_cb);
+extern void udi_intr_detach_ack_unused(udi_intr_detach_cb_t *intr_detach_cb);
+
+
+extern void udi_intr_event_ind(udi_intr_event_cb_t *intr_event_cb, udi_ubit8_t flags);
+/**
+ * \brief Values for ::udi_intr_event_ind \a flags
+ * \{
+ */
+#define UDI_INTR_MASKING_NOT_REQUIRED    (1U<<0)
+#define UDI_INTR_OVERRUN_OCCURRED        (1U<<1)
+#define UDI_INTR_PREPROCESSED            (1U<<2)
+/**
+ * \}
+ */
+
+extern void udi_intr_event_rdy(udi_intr_event_cb_t *intr_event_cb);
+
+
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/physio/pio.h b/Modules/Interfaces/UDI/include/physio/pio.h
new file mode 100644 (file)
index 0000000..1ce305f
--- /dev/null
@@ -0,0 +1,15 @@
+/**
+ * \file physio/pio.h
+ */
+#ifndef _PHYSIO_PIO_H_
+#define _PHYSIO_PIO_H_
+
+#include <udi.h>
+#include <udi_physio.h>
+
+
+typedef _udi_handle_t  udi_pio_handle_t;
+/* Null handle value for udi_pio_handle_t */
+#define UDI_NULL_PIO_HANDLE    _NULL_HANDLE
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/udi.h b/Modules/Interfaces/UDI/include/udi.h
new file mode 100644 (file)
index 0000000..fa5cac3
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * \file udi.h
+ */
+#ifndef _UDI_ARCH_H_
+#define _UDI_ARCH_H_
+
+// Use the core acess file to use the specific size types (plus va_arg)
+#include <acess.h>
+
+typedef Sint8  udi_sbit8_t;    /* signed 8-bit: -2^7..2^7-1 */
+typedef Sint16 udi_sbit16_t;   /* signed 16-bit: -2^15..2^15-1 */
+typedef Sint32 udi_sbit32_t;   /* signed 32-bit: -2^31..2^31-1 */
+typedef Uint8  udi_ubit8_t;    /* unsigned 8-bit: 0..28-1 */
+typedef Uint16 udi_ubit16_t;   /* unsigned 16-bit: 0..216-1 */
+typedef Uint32 udi_ubit32_t;   /* unsigned 32-bit: 0..232-1 */
+
+typedef udi_ubit8_t    udi_boolean_t;  /* 0=False; 1..28-1=True */
+#define FALSE  0
+#define TRUE   1
+
+typedef size_t udi_size_t;     /* buffer size */
+typedef size_t udi_index_t;    /* zero-based index type */
+
+typedef void   *_udi_handle_t;
+#define        _NULL_HANDLE    NULL
+
+/* Channel Handle */
+typedef _udi_handle_t  *udi_channel_t;
+#define UDI_NULL_CHANNEL       _NULL_HANDLE
+
+/**
+ * \brief Buffer Path
+ */
+typedef _udi_handle_t  udi_buf_path_t;
+#define UDI_NULL_BUF_PATH      _NULL_HANDLE
+
+typedef _udi_handle_t  udi_origin_t;
+#define UDI_NULL_ORIGIN        _NULL_HANDLE
+
+typedef Sint64 udi_timestamp_t;
+
+#define UDI_HANDLE_IS_NULL(handle, handle_type)        (handle == NULL)
+#define UDI_HANDLE_ID(handle, handle_type)     ((Uint32)handle)
+
+/**
+ * \name va_arg wrapper
+ * \{
+ */
+#define UDI_VA_ARG(pvar, type, va_code)        va_arg(pvar,type)
+#define UDI_VA_UBIT8_T
+#define UDI_VA_SBIT8_T
+#define UDI_VA_UBIT16_T
+#define UDI_VA_SBIT16_T
+#define UDI_VA_UBIT32_T
+#define UDI_VA_SBIT32_T
+#define UDI_VA_BOOLEAN_T
+#define UDI_VA_INDEX_T
+#define UDI_VA_SIZE_T
+#define UDI_VA_STATUS_T
+#define UDI_VA_CHANNEL_T
+#define UDI_VA_ORIGIN_T
+#define UDI_VA_POINTER
+/**
+ * \}
+ */
+
+/**
+ * \brief Status Type
+ */
+typedef udi_ubit32_t   udi_status_t;
+
+/**
+ * \name Values and Flags for udi_status_t
+ * \{
+ */
+#define UDI_STATUS_CODE_MASK           0x0000FFFF
+#define UDI_STAT_META_SPECIFIC         0x00008000
+#define UDI_SPECIFIC_STATUS_MASK       0x00007FFF
+#define UDI_CORRELATE_OFFSET           16
+#define UDI_CORRELATE_MASK                     0xFFFF0000
+/* Common Status Values */
+#define UDI_OK                                         0
+#define UDI_STAT_NOT_SUPPORTED         1
+#define UDI_STAT_NOT_UNDERSTOOD                2
+#define UDI_STAT_INVALID_STATE         3
+#define UDI_STAT_MISTAKEN_IDENTITY     4
+#define UDI_STAT_ABORTED                       5
+#define UDI_STAT_TIMEOUT                       6
+#define UDI_STAT_BUSY                          7
+#define UDI_STAT_RESOURCE_UNAVAIL      8
+#define UDI_STAT_HW_PROBLEM                    9
+#define UDI_STAT_NOT_RESPONDING                10
+#define UDI_STAT_DATA_UNDERRUN         11
+#define UDI_STAT_DATA_OVERRUN          12
+#define UDI_STAT_DATA_ERROR                    13
+#define UDI_STAT_PARENT_DRV_ERROR      14
+#define UDI_STAT_CANNOT_BIND           15
+#define UDI_STAT_CANNOT_BIND_EXCL      16
+#define UDI_STAT_TOO_MANY_PARENTS      17
+#define UDI_STAT_BAD_PARENT_TYPE       18
+#define UDI_STAT_TERMINATED                    19
+#define UDI_STAT_ATTR_MISMATCH         20
+/**
+ * \}
+ */
+
+/**
+ * \name Data Layout Specifiers
+ * \{
+ */
+typedef const udi_ubit8_t      udi_layout_t;
+/* Specific-Length Layout Type Codes */
+#define UDI_DL_UBIT8_T                   1
+#define UDI_DL_SBIT8_T                   2
+#define UDI_DL_UBIT16_T                  3
+#define UDI_DL_SBIT16_T                  4
+#define UDI_DL_UBIT32_T                  5
+#define UDI_DL_SBIT32_T                  6
+#define UDI_DL_BOOLEAN_T                 7
+#define UDI_DL_STATUS_T                  8
+/* Abstract Element Layout Type Codes */
+#define UDI_DL_INDEX_T                   20
+/* Opaque Handle Element Layout Type Codes */
+#define UDI_DL_CHANNEL_T                 30
+#define UDI_DL_ORIGIN_T                  32
+/* Indirect Element Layout Type Codes */
+#define UDI_DL_BUF                       40
+#define UDI_DL_CB                        41
+#define UDI_DL_INLINE_UNTYPED            42
+#define UDI_DL_INLINE_DRIVER_TYPED       43
+#define UDI_DL_MOVABLE_UNTYPED           44
+/* Nested Element Layout Type Codes */
+#define UDI_DL_INLINE_TYPED              50
+#define UDI_DL_MOVABLE_TYPED             51
+#define UDI_DL_ARRAY                     52
+#define UDI_DL_END                       0
+/**
+ * \}
+ */
+
+
+// === INCLUDE SUB-SECTIONS ===
+#include "udi/cb.h"    // Control Blocks
+#include "udi/log.h"   // Logging
+#include "udi/attr.h"  // Attributes
+#include "udi/strmem.h"        // String/Memory
+#include "udi/buf.h"   // Buffers
+#include "udi/mem.h"   // Memory Management
+#include "udi/imc.h"   // Inter-module Communication
+#include "udi/meta_mgmt.h"     // Management Metalanguage
+#include "udi/meta_gio.h"      // General IO Metalanguage
+#include "udi/init.h"  // Init
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/udi/attr.h b/Modules/Interfaces/UDI/include/udi/attr.h
new file mode 100644 (file)
index 0000000..a63ce8a
--- /dev/null
@@ -0,0 +1,41 @@
+/**
+ * \file udi_attr.h
+ */
+#ifndef _UDI_ATTR_H_
+#define _UDI_ATTR_H_
+
+typedef struct udi_instance_attr_list_s        udi_instance_attr_list_t;
+typedef udi_ubit8_t    udi_instance_attr_type_t;
+
+/* Instance attribute limits */
+#define UDI_MAX_ATTR_NAMELEN   32
+#define UDI_MAX_ATTR_SIZE              64
+
+/**
+ * \brief Instance Attribute
+ */
+struct udi_instance_attr_list_s
+{
+     char      attr_name[UDI_MAX_ATTR_NAMELEN];
+     udi_ubit8_t       attr_value[UDI_MAX_ATTR_SIZE];
+     udi_ubit8_t       attr_length;
+     udi_instance_attr_type_t  attr_type;
+};
+
+
+/**
+ * \brief Instance Attribute Types
+ * \see ::udi_instance_attr_type_t
+ */
+enum
+{
+       UDI_ATTR_NONE,
+       UDI_ATTR_STRING,
+       UDI_ATTR_ARRAY8,
+       UDI_ATTR_UBIT32,
+       UDI_ATTR_BOOLEAN,
+       UDI_ATTR_FILE
+};
+
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/udi/buf.h b/Modules/Interfaces/UDI/include/udi/buf.h
new file mode 100644 (file)
index 0000000..fa2428b
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ * \file udi_buf.h
+ */
+#ifndef _UDI_BUF_H_
+#define _UDI_BUF_H_
+
+
+typedef struct udi_buf_s       udi_buf_t;
+typedef struct udi_xfer_constraints_s  udi_xfer_constraints_t;
+typedef void udi_buf_copy_call_t(udi_cb_t *gcb, udi_buf_t *new_dst_buf);
+typedef void udi_buf_write_call_t(udi_cb_t *gcb, udi_buf_t *new_dst_buf);
+
+/**
+ * \brief Describes a buffer
+ * \note Semi-Opaque
+ */
+struct udi_buf_s
+{
+       udi_size_t      buf_size;
+       Uint8   Data[]; //!< ENVIRONMENT ONLY
+};
+
+/**
+ * \brief 
+ */
+struct udi_xfer_constraints_s
+{
+       udi_ubit32_t    udi_xfer_max;
+       udi_ubit32_t    udi_xfer_typical;
+       udi_ubit32_t    udi_xfer_granularity;
+       udi_boolean_t   udi_xfer_one_piece;
+       udi_boolean_t   udi_xfer_exact_size;
+       udi_boolean_t   udi_xfer_no_reorder;
+};
+
+// --- MACROS ---
+/**
+ * \brief Allocates a buffer
+ */
+#define UDI_BUF_ALLOC(callback, gcb, init_data, size, path_handle) \
+       udi_buf_write(callback, gcb, init_data, size, NULL, 0, 0, path_handle)
+
+/**
+ * \brief Inserts data into a buffer
+ */
+#define UDI_BUF_INSERT(callback, gcb, new_data, size, dst_buf, dst_off) \
+       udi_buf_write(callback, gcb, new_data, size, dst_buf, dst_off, 0, UDI_NULL_BUF_PATH)
+
+/**
+ * \brief Removes data from a buffer (data afterwards will be moved forewards)
+ */
+#define UDI_BUF_DELETE(callback, gcb, size, dst_buf, dst_off) \
+       udi_buf_write(callback, gcb, NULL, 0, dst_buf, dst_off, size, UDI_NULL_BUF_PATH)
+
+/**
+ * \brief Duplicates \a src_buf
+ */
+#define UDI_BUF_DUP(callback, gcb, src_buf, path_handle) \
+       udi_buf_copy(callback, gcb, src_buf, 0, (src_buf)->buf_size, NULL, 0, 0, path_handle)
+
+
+/**
+ * \brief Copies data from one buffer to another
+ */
+extern void udi_buf_copy(
+       udi_buf_copy_call_t *callback,
+       udi_cb_t        *gcb,
+       udi_buf_t       *src_buf,
+       udi_size_t      src_off,
+       udi_size_t      src_len,
+       udi_buf_t       *dst_buf,
+       udi_size_t      dst_off,
+       udi_size_t      dst_len,
+       udi_buf_path_t path_handle );
+
+/**
+ * \brief Copies data from driver space to a buffer
+ */
+extern void udi_buf_write(
+       udi_buf_write_call_t *callback,
+       udi_cb_t        *gcb,
+       const void      *src_mem,
+       udi_size_t      src_len,
+       udi_buf_t       *dst_buf,
+       udi_size_t      dst_off,
+       udi_size_t      dst_len,
+       udi_buf_path_t path_handle
+       );
+
+/**
+ * \brief Reads data from a buffer into driver space
+ */
+extern void udi_buf_read(
+       udi_buf_t       *src_buf,
+       udi_size_t      src_off,
+       udi_size_t      src_len,
+       void    *dst_mem );
+
+/**
+ * \brief Frees a buffer
+ */
+extern void udi_buf_free(udi_buf_t *buf);
+
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/udi/cb.h b/Modules/Interfaces/UDI/include/udi/cb.h
new file mode 100644 (file)
index 0000000..76db5c6
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+ * \file udi_cb.h
+ */
+#ifndef _UDI_CB_H_
+#define _UDI_CB_H_
+
+typedef struct udi_cb_s        udi_cb_t;
+typedef void udi_cb_alloc_call_t(udi_cb_t *gcb, udi_cb_t *new_cb);
+typedef void udi_cb_alloc_batch_call_t(udi_cb_t *gcb, udi_cb_t *first_new_cb);
+typedef void udi_cancel_call_t(udi_cb_t *gcb);
+
+#define UDI_GCB(mcb)   (&(mcb)->gcb)
+#define UDI_MCB(gcb, cb_type)  ((cb_type *)(gcb))
+
+/**
+ * \brief Describes a generic control block
+ * \note Semi-opaque
+ */
+struct udi_cb_s
+{
+       /**
+        * \brief Channel associated with the control block
+        */
+       udi_channel_t   channel;
+       /**
+        * \brief Current state
+        * \note Driver changable
+        */
+       void    *context;
+       /**
+        * \brief CB's scratch area
+        */
+       void    *scratch;
+       /**
+        * \brief ???
+        */
+       void    *initiator_context;
+       /**
+        * \brief Request Handle?
+        */
+       udi_origin_t    origin;
+};
+
+extern void udi_cb_alloc (
+       udi_cb_alloc_call_t     *callback,
+       udi_cb_t        *gcb,
+       udi_index_t     cb_idx,
+       udi_channel_t   default_channel
+       );
+
+extern void udi_cb_alloc_dynamic(
+       udi_cb_alloc_call_t     *callback,
+       udi_cb_t        *gcb,
+       udi_index_t     cb_idx,
+       udi_channel_t   default_channel,
+       udi_size_t      inline_size,
+       udi_layout_t    *inline_layout
+       );
+
+extern void udi_cb_alloc_batch(
+       udi_cb_alloc_batch_call_t       *callback,
+       udi_cb_t        *gcb,
+       udi_index_t     cb_idx,
+       udi_index_t     count,
+       udi_boolean_t   with_buf,
+       udi_size_t      buf_size,
+       udi_buf_path_t  path_handle
+       );
+
+extern void udi_cb_free(udi_cb_t *cb);
+
+extern void udi_cancel(udi_cancel_call_t *callback, udi_cb_t *gcb);
+
+
+
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/udi/imc.h b/Modules/Interfaces/UDI/include/udi/imc.h
new file mode 100644 (file)
index 0000000..e5b3f3b
--- /dev/null
@@ -0,0 +1,92 @@
+/**
+ * \file udi_imc.h
+ * \brief Inter-Module Communication
+ */
+#ifndef _UDI_IMC_H_
+#define _UDI_IMC_H_
+
+typedef void udi_channel_anchor_call_t(udi_cb_t *gcb, udi_channel_t anchored_channel);
+typedef void udi_channel_spawn_call_t(udi_cb_t *gcb, udi_channel_t new_channel);
+
+typedef struct udi_channel_event_cb_s  udi_channel_event_cb_t;
+
+typedef void udi_channel_event_ind_op_t(udi_channel_event_cb_t *cb);
+
+/**
+ * \brief Anchors a channel end to the current region
+ */
+extern void udi_channel_anchor(
+       udi_channel_anchor_call_t *callback, udi_cb_t *gcb,
+       udi_channel_t channel, udi_index_t ops_idx, void *channel_context
+       );
+
+/**
+ * \brief Created a new channel between two regions
+ */
+extern void udi_channel_spawn(
+       udi_channel_spawn_call_t *callback,
+       udi_cb_t *gcb,
+       udi_channel_t channel,
+       udi_index_t spawn_idx,
+       udi_index_t ops_idx,
+       void *channel_context
+       );
+
+/**
+ * \brief Attaches a new context pointer to the current channel
+ */
+extern void udi_channel_set_context(
+       udi_channel_t target_channel,
+       void *channel_context
+       );
+/**
+ * \brief 
+ */
+extern void udi_channel_op_abort(
+       udi_channel_t target_channel,
+       udi_cb_t *orig_cb
+       );
+
+/**
+ * \brief Closes an open channel
+ */
+extern void udi_channel_close(udi_channel_t channel);
+
+/**
+ * \brief Describes a channel event
+ */
+struct udi_channel_event_cb_s
+{
+       udi_cb_t gcb;
+       udi_ubit8_t event;
+       union {
+               struct {
+                       udi_cb_t *bind_cb;
+               } internal_bound;
+               struct {
+                       udi_cb_t *bind_cb;
+                       udi_ubit8_t parent_ID;
+                       udi_buf_path_t *path_handles;
+               } parent_bound;
+               udi_cb_t *orig_cb;
+       }       params;
+};
+/* Channel event types */
+#define UDI_CHANNEL_CLOSED                0
+#define UDI_CHANNEL_BOUND                 1
+#define UDI_CHANNEL_OP_ABORTED            2
+
+/**
+ * \brief Proxy function 
+ */
+extern void udi_channel_event_ind(udi_channel_event_cb_t *cb);
+
+/**
+ * \brief Called when channel event is completed
+ */
+extern void udi_channel_event_complete(
+       udi_channel_event_cb_t *cb, udi_status_t status
+       );
+
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/udi/init.h b/Modules/Interfaces/UDI/include/udi/init.h
new file mode 100644 (file)
index 0000000..f405d03
--- /dev/null
@@ -0,0 +1,315 @@
+/**
+ * \file udi_init.h
+ */
+#ifndef _UDI_INIT_H_
+#define _UDI_INIT_H_
+
+typedef struct udi_init_s              udi_init_t;
+typedef struct udi_primary_init_s      udi_primary_init_t;
+typedef struct udi_secondary_init_s    udi_secondary_init_t;
+typedef struct udi_ops_init_s  udi_ops_init_t;
+typedef struct udi_cb_init_s   udi_cb_init_t;
+typedef struct udi_cb_select_s udi_cb_select_t;
+typedef struct udi_gcb_init_s  udi_gcb_init_t;
+
+typedef struct udi_init_context_s      udi_init_context_t;
+typedef struct udi_limits_s            udi_limits_t;
+typedef struct udi_chan_context_s      udi_chan_context_t;
+typedef struct udi_child_chan_context_s        udi_child_chan_context_t;
+
+typedef void   udi_op_t(void);
+typedef udi_op_t * const       udi_ops_vector_t;
+
+/**
+ * \brief UDI Initialisation Structure
+ * 
+ * Defines how to initialise and use a UDI driver
+ */
+struct udi_init_s
+{
+       /**
+        * \brief Defines the primary region
+        * \note For secondary modules this must be NULL
+        */
+       udi_primary_init_t      *primary_init_info;
+       
+       /**
+        * \brief Defines all secondary regions
+        * Pointer to a list (so, essentially an array) of ::udi_secondary_init_t
+        * It is terminated by an entry with ::udi_secondary_init_t.region_idx
+        * set to zero.
+        * \note If NULL, it is to be treated as an empty list
+        */
+       udi_secondary_init_t    *secondary_init_list;
+       
+       /**
+        * \brief Channel operations
+        * Pointer to a ::udi_ops_init_t.ops_idx == 0  terminated list that
+        * defines the channel opterations usage for each ops vector implemented
+        * in this module.
+        * \note Must contain at least one entry for each metalanguage used
+        */
+       udi_ops_init_t  *ops_init_list;
+       
+       /**
+        * \brief Control Blocks
+        */
+       udi_cb_init_t   *cb_init_list;
+       
+       /**
+        * \brief Generic Control Blocks
+        */
+       udi_gcb_init_t  *gcb_init_list;
+       
+       /**
+        * \brief Overrides for control blocks
+        * Allows a control block to override the ammount of scratch space it
+        * gets for a specific ops vector.
+        */
+       udi_cb_select_t *cb_select_list;
+};
+
+
+/**
+ * \name Flags for ::udi_primary_init_t.mgmt_op_flags
+ * \{
+ */
+
+/**
+ * \brief Tells the environment that this operation may take some time
+ * Used as a hint in scheduling tasks
+ */
+#define UDI_OP_LONG_EXEC       0x01
+
+/**
+ * \}
+ */
+
+/**
+ * \brief Describes the Primary Region
+ * Tells the environment how to set up the driver's primary region.
+ */
+struct udi_primary_init_s
+{
+       /**
+        * \brief Management Ops Vector
+        * Pointer to a list of functions for the Management Metalanguage
+        */
+       udi_mgmt_ops_t  *mgmt_ops;
+       
+       /**
+        * \brief Flags for \a mgmt_ops
+        * Each entry in \a mgmt_ops is acommanied by an entry in this array.
+        * Each entry contains the flags that apply to the specified ops vector.
+        * \see UDI_OP_LONG_EXEC
+        */
+       const udi_ubit8_t       *mgmt_op_flags;
+       
+       /**
+        * \brief Scratch space size
+        * Specifies the number of bytes to allocate for each control block
+        * passed by the environment.
+        * \note must not exceed ::UDI_MAX_SCRATCH
+        */
+       udi_size_t      mgmt_scratch_requirement;
+       
+       /**
+        * \todo What is this?
+        */
+       udi_ubit8_t     enumeration_attr_list_length;
+       
+       /**
+        * \brief Size in bytes to allocate to each instance of the primary
+        *        region
+        * Essentially the size of the driver's instance state
+        * \note Must be at least sizeof(udi_init_context_t) and not more
+        *       than UDI_MIN_ALLOC_LIMIT
+        */
+       udi_size_t      rdata_size;
+       
+       /**
+        * \brief Size in bytes to allocate for each call to ::udi_enumerate_req
+        * \note Must not exceed UDI_MIN_ALLOC_LIMIT
+        */
+       udi_size_t      child_data_size;
+       
+       /**
+        * \brief Number of path handles for each parent bound to this driver
+        * \todo What the hell are path handles?
+        */
+       udi_ubit8_t     per_parent_paths;
+};
+
+/**
+ * \brief Tells the environment how to create a secondary region
+ */
+struct udi_secondary_init_s
+{
+       /**
+        * \brief Region Index
+        * Non-zero driver-dependent index value that identifies the region
+        * \note This corresponds to a "region" declaration in the udiprops.txt
+        *       file.
+        */
+       udi_index_t     region_idx;
+       /**
+        * \brief Number of bytes to allocate
+        * 
+        * \note Again, must be between sizeof(udi_init_context_t) and
+        *       UDI_MIN_ALLOC_LIMIT
+        */
+       udi_size_t      rdata_size;
+};
+
+/**
+ * \brief Defines channel endpoints (ways of communicating with the driver)
+ * 
+ */
+struct udi_ops_init_s
+{
+       /**
+        * \brief ops index number
+        * Used to uniquely this entry
+        * \note If this is zero, it marks the end of the list
+        */
+       udi_index_t     ops_idx;
+       /**
+        * \brief Metalanguage Index
+        * Defines what metalanguage is used
+        */
+       udi_index_t     meta_idx;
+       /**
+        * \brief Metalanguage Operation
+        * Defines what metalanguage operation is used
+        */
+       udi_index_t     meta_ops_num;
+       /**
+        * \brief Size of the context area
+        * \note If non-zero, must be at least 
+        */
+       udi_size_t      chan_context_size;
+       /**
+        * \brief Pointer to the operations
+        * Pointer to a <<meta>>_<<role>>_ops_t structure
+        */
+       udi_ops_vector_t        *ops_vector;
+       /**
+        * \brief Flags for each entry in \a ops_vector
+        */
+       const udi_ubit8_t       *op_flags;
+};
+
+/**
+ * \brief Defines control blocks
+ * Much the same as ::udi_ops_init_t
+ */
+struct udi_cb_init_s
+{
+       udi_index_t     cb_idx;
+       udi_index_t     meta_idx;
+       udi_index_t     meta_cb_num;
+       udi_size_t      scratch_requirement;
+       /**
+        * \brief Size of inline memory
+        */
+       udi_size_t      inline_size;
+       /**
+        * \brief Layout of inline memory
+        */
+       udi_layout_t    *inline_layout;
+};
+
+/**
+ * \brief Overrides the scratch size for an operation
+ */
+struct udi_cb_select_s
+{
+       udi_index_t     ops_idx;
+       udi_index_t     cb_idx;
+};
+
+/**
+ * \brief General Control Blocks
+ * These control blocks can only be used as general data storage, not
+ * for any channel operations.
+ */
+struct udi_gcb_init_s
+{
+       udi_index_t     cb_idx;
+       udi_size_t      scratch_requirement;
+};
+
+
+// ===
+// ===
+/**
+ * \brief Environement Imposed Limits
+ */
+struct udi_limits_s
+{
+       /**
+        * \brief Maximum legal ammount of memory that can be allocated
+        */
+       udi_size_t      max_legal_alloc;
+       
+       /**
+        * \brief Maximum ammount of guaranteed memory
+        */
+       udi_size_t      max_safe_alloc;
+       /**
+        * \brief Maximum size of the final string from ::udi_trace_write
+        *        or ::udi_log_write
+        */
+       udi_size_t      max_trace_log_formatted_len;
+       /**
+        * \brief Maximum legal size of an instanct attribute value
+        */
+       udi_size_t      max_instance_attr_len;
+       /**
+        * \brief Minumum time difference (in nanoseconds between unique values
+        *        returned by ::udi_time_current
+        */
+       udi_ubit32_t    min_curtime_res;
+       /**
+        * \brief Minimum resolution of timers
+        * \see ::udi_timer_start_repeating, ::udi_timer_start
+        */
+       udi_ubit32_t    min_timer_res;
+} PACKED;
+
+/**
+ * \brief Primary Region Context data
+ */
+struct udi_init_context_s
+{
+       udi_index_t     region_idx;
+       udi_limits_t    limits;
+};
+
+/**
+ * \brief Channel context data
+ */
+struct udi_chan_context_s
+{
+       /**
+        * \brief Pointer to the driver instance's initial region data
+        */
+       void    *rdata;
+} PACKED;
+
+/**
+ * \brief Child Channel context
+ */
+struct udi_child_chan_context_s
+{
+       /**
+        * \brief Pointer to the driver instance's initial region data
+        */
+       void    *rdata;
+       /**
+        * \brief Some sort of unique ID number
+        */
+       udi_ubit32_t    child_ID;
+};
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/udi/log.h b/Modules/Interfaces/UDI/include/udi/log.h
new file mode 100644 (file)
index 0000000..dccb124
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * \file udi_log.h
+ */
+#ifndef _UDI_LOG_H_
+#define _UDI_LOG_H_
+
+/**
+ * \brief Trace Event
+ */
+typedef udi_ubit32_t   udi_trevent_t;
+
+/**
+ * \brief Log Callback
+ */
+typedef void udi_log_write_call_t(udi_cb_t *gcb, udi_status_t correlated_status);
+
+/**
+ * \name Log Severities
+ * \brief Values for severity
+ * \{
+ */
+#define UDI_LOG_DISASTER       1
+#define UDI_LOG_ERROR          2
+#define UDI_LOG_WARNING                3
+#define UDI_LOG_INFORMATION    4
+/**
+ * \}
+ */
+
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/udi/mem.h b/Modules/Interfaces/UDI/include/udi/mem.h
new file mode 100644 (file)
index 0000000..d29f25e
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * \file udi_mem.h
+ */
+#ifndef _UDI_MEM_H_
+#define _UDI_MEM_H_
+
+/**
+ * \brief Callback type for ::udi_mem_alloc
+ */
+typedef void udi_mem_alloc_call_t(udi_cb_t *gcb, void *new_mem);
+
+/**
+ * \brief Allocate memory
+ */
+extern void udi_mem_alloc(
+       udi_mem_alloc_call_t *callback,
+       udi_cb_t        *gcb,
+       udi_size_t      size,
+       udi_ubit8_t     flags
+       );
+
+/**
+ * \brief Values for ::udi_mem_alloc \a flags
+ * \{
+ */
+#define UDI_MEM_NOZERO               (1U<<0)   //!< No need to zero the memory
+#define UDI_MEM_MOVABLE              (1U<<1)   //!< Globally accessable memory?
+/**
+ * \}
+ */
+
+/**
+ * \brief Free allocated memory
+ */
+extern void udi_mem_free(void *target_mem);
+
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/udi/meta_gio.h b/Modules/Interfaces/UDI/include/udi/meta_gio.h
new file mode 100644 (file)
index 0000000..d1cf86f
--- /dev/null
@@ -0,0 +1,120 @@
+/**
+ * \file udi_meta_gio.h
+ */
+#ifndef _UDI_META_GIO_H_
+#define _UDI_META_GIO_H_
+
+typedef const struct udi_gio_provider_ops_s    udi_gio_provider_ops_t;
+typedef const struct udi_gio_client_ops_s      udi_gio_client_ops_t;
+typedef struct udi_gio_bind_cb_s       udi_gio_bind_cb_t;
+typedef struct udi_gio_xfer_cb_s       udi_gio_xfer_cb_t;
+typedef struct udi_gio_rw_params_s     udi_gio_rw_params_t;
+typedef struct udi_gio_event_cb_s      udi_gio_event_cb_t;
+
+typedef void   udi_gio_bind_req_op_t(udi_gio_bind_cb_t *cb);
+typedef void   udi_gio_unbind_req_op_t(udi_gio_bind_cb_t *cb);
+typedef void   udi_gio_xfer_req_op_t(udi_gio_bind_cb_t *cb);
+typedef void   udi_gio_event_res_op_t(udi_gio_bind_cb_t *cb);
+
+typedef void   udi_gio_bind_ack_op_t(
+       udi_gio_bind_cb_t *cb,
+       udi_ubit32_t    device_size_lo,
+       udi_ubit32_t    device_size_hi,
+       udi_status_t    status
+       );
+typedef void   udi_gio_unbind_ack_op_t(udi_gio_bind_cb_t *cb);
+typedef void   udi_gio_xfer_ack_op_t(udi_gio_bind_cb_t *cb);
+typedef void   udi_gio_xfer_nak_op_t(udi_gio_bind_cb_t *cb, udi_status_t status);
+typedef void   udi_gio_event_ind_op_t(udi_gio_bind_cb_t *cb);
+
+typedef udi_ubit8_t    udi_gio_op_t;
+/* Limit values for udi_gio_op_t */
+#define UDI_GIO_OP_CUSTOM                 16
+#define UDI_GIO_OP_MAX                    64
+/* Direction flag values for op */
+#define UDI_GIO_DIR_READ                  (1U<<6)
+#define UDI_GIO_DIR_WRITE                 (1U<<7)
+/* Standard Operation Codes */
+#define UDI_GIO_OP_READ       UDI_GIO_DIR_READ
+#define UDI_GIO_OP_WRITE      UDI_GIO_DIR_WRITE
+
+
+
+struct udi_gio_provider_ops_s
+{
+       udi_channel_event_ind_op_t      *channel_event_ind_op;
+       udi_gio_bind_req_op_t   *gio_bind_req_op;
+       udi_gio_unbind_req_op_t *gio_unbind_req_op;
+       udi_gio_xfer_req_op_t   *gio_xfer_req_op;
+       udi_gio_event_res_op_t  *gio_event_res_op;
+};
+/* Ops Vector Number */
+#define UDI_GIO_PROVIDER_OPS_NUM          1
+
+struct udi_gio_client_ops_s
+{
+       udi_channel_event_ind_op_t      *channel_event_ind_op;
+       udi_gio_bind_ack_op_t   *gio_bind_ack_op;
+       udi_gio_unbind_ack_op_t *gio_unbind_ack_op;
+       udi_gio_xfer_ack_op_t   *gio_xfer_ack_op;
+       udi_gio_xfer_nak_op_t   *gio_xfer_nak_op;
+       udi_gio_event_ind_op_t  *gio_event_ind_op;
+};
+/* Ops Vector Number */
+#define UDI_GIO_CLIENT_OPS_NUM            2
+
+struct udi_gio_bind_cb_s
+{
+       udi_cb_t        gcb;
+       udi_xfer_constraints_t  xfer_constraints;
+};
+/* Control Block Group Number */
+#define UDI_GIO_BIND_CB_NUM      1
+
+
+struct udi_gio_xfer_cb_s
+{
+       udi_cb_t        gcb;
+       udi_gio_op_t    op;
+       void    *tr_params;
+       udi_buf_t       *data_buf;
+};
+/* Control Block Group Number */
+#define UDI_GIO_XFER_CB_NUM      2
+
+struct udi_gio_rw_params_s
+{
+       udi_ubit32_t offset_lo;
+       udi_ubit32_t offset_hi;
+};
+
+struct udi_gio_event_cb_s
+{
+       udi_cb_t        gcb;
+       udi_ubit8_t     event_code;
+       void    *event_params;
+};
+/* Control Block Group Number */
+#define UDI_GIO_EVENT_CB_NUM     3
+
+
+extern void udi_gio_bind_req(udi_gio_bind_cb_t *cb);
+extern void udi_gio_bind_ack(
+       udi_gio_bind_cb_t       *cb,
+       udi_ubit32_t    device_size_lo,
+       udi_ubit32_t    device_size_hi,
+       udi_status_t    status
+       );
+
+extern void udi_gio_unbind_req(udi_gio_bind_cb_t *cb);
+extern void udi_gio_unbind_ack(udi_gio_bind_cb_t *cb);
+
+extern void udi_gio_xfer_req(udi_gio_xfer_cb_t *cb);
+extern void udi_gio_xfer_ack(udi_gio_xfer_cb_t *cb);
+extern void udi_gio_xfer_nak(udi_gio_xfer_cb_t *cb, udi_status_t status);
+
+extern void udi_gio_event_res(udi_gio_event_cb_t *cb);
+extern void udi_gio_event_ind(udi_gio_event_cb_t *cb);
+extern void udi_gio_event_res_unused(udi_gio_event_cb_t *cb);
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/udi/meta_mgmt.h b/Modules/Interfaces/UDI/include/udi/meta_mgmt.h
new file mode 100644 (file)
index 0000000..97eccf2
--- /dev/null
@@ -0,0 +1,156 @@
+/**
+ * \file udi_meta_mgmt.h
+ */
+#ifndef _UDI_META_MGMT_H_
+#define _UDI_META_MGMT_H_
+
+typedef struct udi_mgmt_ops_s  udi_mgmt_ops_t;
+typedef struct udi_mgmt_cb_s   udi_mgmt_cb_t;
+typedef struct udi_usage_cb_s  udi_usage_cb_t;
+typedef struct udi_filter_element_s    udi_filter_element_t;
+typedef struct udi_enumerate_cb_s      udi_enumerate_cb_t;
+
+/**
+ * \name Specify Usage
+ * \{
+ */
+typedef void udi_usage_ind_op_t(udi_usage_cb_t *cb, udi_ubit8_t resource_level);
+/* Values for resource_level */
+#define UDI_RESOURCES_CRITICAL     1
+#define UDI_RESOURCES_LOW          2
+#define UDI_RESOURCES_NORMAL       3
+#define UDI_RESOURCES_PLENTIFUL    4
+/* Proxy */
+extern void    udi_static_usage(udi_usage_cb_t *cb, udi_ubit8_t resource_level);
+/**
+ * \}
+ */
+
+typedef void udi_usage_res_op_t(udi_usage_cb_t *cb);
+
+/**
+ * \name Enumerate this driver
+ * \{
+ */
+typedef void udi_enumerate_req_op_t(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level);
+/* Values for enumeration_level */
+#define UDI_ENUMERATE_START           1
+#define UDI_ENUMERATE_START_RESCAN    2
+#define UDI_ENUMERATE_NEXT            3
+#define UDI_ENUMERATE_NEW             4
+#define UDI_ENUMERATE_DIRECTED        5
+#define UDI_ENUMERATE_RELEASE         6
+/* Proxy */
+extern void udi_enumerate_no_children(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level);
+/**
+ * \}
+ */
+
+/**
+ * \name Enumeration Acknowlagement
+ * \{
+ */
+typedef void udi_enumerate_ack_op_t(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_result, udi_index_t ops_idx);
+/* Values for enumeration_result */
+#define UDI_ENUMERATE_OK             0
+#define UDI_ENUMERATE_LEAF           1
+#define UDI_ENUMERATE_DONE           2
+#define UDI_ENUMERATE_RESCAN         3
+#define UDI_ENUMERATE_REMOVED        4
+#define UDI_ENUMERATE_REMOVED_SELF   5
+#define UDI_ENUMERATE_RELEASED       6
+#define UDI_ENUMERATE_FAILED         255
+/**
+ * \}
+ */
+
+/**
+ * \name 
+ * \{
+ */
+typedef void udi_devmgmt_req_op_t(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID);
+
+typedef void udi_devmgmt_ack_op_t(udi_mgmt_cb_t *cb, udi_ubit8_t flags, udi_status_t status);
+/**
+ * \}
+ */
+typedef void udi_final_cleanup_req_op_t(udi_mgmt_cb_t *cb);
+typedef void udi_final_cleanup_ack_op_t(udi_mgmt_cb_t *cb);
+
+
+
+
+
+struct udi_mgmt_ops_s
+{
+       udi_usage_ind_op_t      *usage_ind_op;
+       udi_enumerate_req_op_t  *enumerate_req_op;
+       udi_devmgmt_req_op_t    *devmgmt_req_op;
+       udi_final_cleanup_req_op_t      *final_cleanup_req_op;
+};
+
+struct udi_mgmt_cb_s
+{
+       udi_cb_t        gcb;
+};
+
+struct udi_usage_cb_s
+{
+       udi_cb_t        gcb;
+       udi_trevent_t   trace_mask;
+       udi_index_t     meta_idx;
+};
+
+
+struct udi_filter_element_s
+{
+     char      attr_name[UDI_MAX_ATTR_NAMELEN];
+     udi_ubit8_t       attr_min[UDI_MAX_ATTR_SIZE];
+     udi_ubit8_t       attr_min_len;
+     udi_ubit8_t       attr_max[UDI_MAX_ATTR_SIZE];
+     udi_ubit8_t       attr_max_len;
+     udi_instance_attr_type_t  attr_type;
+     udi_ubit32_t      attr_stride;
+};
+struct udi_enumerate_cb_s
+{
+     udi_cb_t  gcb;
+     udi_ubit32_t      child_ID;
+     void      *child_data;
+     udi_instance_attr_list_t  *attr_list;
+     udi_ubit8_t       attr_valid_length;
+     const udi_filter_element_t        *filter_list;
+     udi_ubit8_t       filter_list_length;
+     udi_ubit8_t       parent_ID;
+};
+/* Special parent_ID filter values */
+#define UDI_ANY_PARENT_ID      0
+
+/**
+ * \brief 
+ */
+extern void    udi_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID );
+/**
+ * \brief Values for ::udi_devmgmt_req \a mgmt_op
+ */
+enum eDMGMT
+{
+       UDI_DMGMT_PREPARE_TO_SUSPEND = 1,
+       UDI_DMGMT_SUSPEND,
+       UDI_DMGMT_SHUTDOWN,
+       UDI_DMGMT_PARENT_SUSPENDED,
+       UDI_DMGMT_RESUME,
+       UDI_DMGMT_UNBIND
+};
+
+extern void    udi_devmgmt_ack(udi_mgmt_cb_t *cb, udi_ubit8_t flags, udi_status_t status);
+//!\brief Values for flags
+#define UDI_DMGMT_NONTRANSPARENT       (1U<<0)
+//!\brief Meta-Specific Status Codes
+#define UDI_DMGMT_STAT_ROUTING_CHANGE  (UDI_STAT_META_SPECIFIC|1)
+
+extern void udi_final_cleanup_req(udi_mgmt_cb_t *cb);
+extern void udi_final_cleanup_ack(udi_mgmt_cb_t *cb);
+
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/udi/strmem.h b/Modules/Interfaces/UDI/include/udi/strmem.h
new file mode 100644 (file)
index 0000000..f540a3e
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * \file udi_strmem.h
+ */
+#ifndef _UDI_STRMEM_H_
+#define _UDI_STRMEM_H_
+
+/**
+ * \brief Gets the length of a C style string
+ */
+extern udi_size_t      udi_strlen(const char *s);
+
+/**
+ * \brief Appends to a string
+ */
+extern char *udi_strcat(char *s1, const char *s2);
+extern char *udi_strncat(char *s1, const char *s2, udi_size_t n);
+
+/**
+ * \brief Compares Strings/Memory
+ */
+extern udi_sbit8_t udi_strcmp(const char *s1, const char *s2);
+extern udi_sbit8_t udi_strncmp(const char *s1, const char *s2, udi_size_t n);
+extern udi_sbit8_t udi_memcmp(const void *s1, const void *s2, udi_size_t n);
+
+extern char *udi_strcpy(char *s1, const char *s2);
+extern char *udi_strncpy(char *s1, const char *s2, udi_size_t n);
+extern void *udi_memcpy(void *s1, const void *s2, udi_size_t n);
+extern void *udi_memmove(void *s1, const void *s2, udi_size_t n);
+
+extern char *udi_strncpy_rtrim(char *s1, const char *s2, udi_size_t n);
+
+extern char *udi_strchr(const char *s, char c);
+extern char *udi_strrchr(const char *s, char c);
+extern void *udi_memchr (const void *s, udi_ubit8_t c, udi_size_t n);
+
+extern void *udi_memset(void *s, udi_ubit8_t c, udi_size_t n);
+extern udi_ubit32_t udi_strtou32(const char *s, char **endptr, int base);
+
+
+extern udi_size_t udi_snprintf(char *s, udi_size_t max_bytes, const char *format, ...);
+
+
+
+#endif
diff --git a/Modules/Interfaces/UDI/include/udi_physio.h b/Modules/Interfaces/UDI/include/udi_physio.h
new file mode 100644 (file)
index 0000000..1397b1c
--- /dev/null
@@ -0,0 +1,144 @@
+/**
+ * \file udi_physio.h
+ */
+#ifndef _UDI_PHYSIO_H_
+#define _UDI_PHYSIO_H_
+
+#include <udi.h>
+
+// === TYPEDEFS ===
+// DMA Core
+typedef _udi_handle_t  udi_dma_handle_t;
+#define        UDI_NULL_DMA_HANDLE     _NULL_HANDLE
+typedef Uint64 udi_busaddr64_t;        //!< \note Opaque
+typedef struct udi_scgth_element_32_s  udi_scgth_element_32_t;
+typedef struct udi_scgth_element_64_s  udi_scgth_element_64_t;
+typedef struct udi_scgth_s     udi_scgth_t;
+typedef _udi_handle_t  udi_dma_constraints_t;
+#define UDI_NULL_DMA_CONSTRAINTS       _NULL_HANDLE
+/**
+ * \name DMA constraints attributes
+ * \{
+ */
+typedef udi_ubit8_t udi_dma_constraints_attr_t;
+/* DMA Convenience Attribute Codes */
+#define UDI_DMA_ADDRESSABLE_BITS          100
+#define UDI_DMA_ALIGNMENT_BITS            101
+/* DMA Constraints on the Entire Transfer */
+#define UDI_DMA_DATA_ADDRESSABLE_BITS     110
+#define UDI_DMA_NO_PARTIAL                111
+/* DMA Constraints on the Scatter/Gather  List */
+#define UDI_DMA_SCGTH_MAX_ELEMENTS        120
+#define UDI_DMA_SCGTH_FORMAT              121
+#define UDI_DMA_SCGTH_ENDIANNESS          122
+#define UDI_DMA_SCGTH_ADDRESSABLE_BITS    123
+#define UDI_DMA_SCGTH_MAX_SEGMENTS        124
+/* DMA Constraints on Scatter/Gather Segments */
+#define UDI_DMA_SCGTH_ALIGNMENT_BITS      130
+#define UDI_DMA_SCGTH_MAX_EL_PER_SEG      131
+#define UDI_DMA_SCGTH_PREFIX_BYTES        132
+/* DMA Constraints on Scatter/Gather Elements */
+#define UDI_DMA_ELEMENT_ALIGNMENT_BITS    140
+#define UDI_DMA_ELEMENT_LENGTH_BITS       141
+#define UDI_DMA_ELEMENT_GRANULARITY_BITS 142
+/* DMA Constraints for Special Addressing */
+#define UDI_DMA_ADDR_FIXED_BITS           150
+#define UDI_DMA_ADDR_FIXED_TYPE           151
+#define UDI_DMA_ADDR_FIXED_VALUE_LO       152
+#define UDI_DMA_ADDR_FIXED_VALUE_HI       153
+/* DMA Constraints on DMA Access Behavior */
+#define UDI_DMA_SEQUENTIAL                160
+#define UDI_DMA_SLOP_IN_BITS              161
+#define UDI_DMA_SLOP_OUT_BITS             162
+#define UDI_DMA_SLOP_OUT_EXTRA            163
+#define UDI_DMA_SLOP_BARRIER_BITS         164
+/* Values for UDI_DMA_SCGTH_ENDIANNESS */
+#define UDI_DMA_LITTLE_ENDIAN             (1U<<6)
+#define UDI_DMA_BIG_ENDIAN                (1U<<5)
+/* Values for UDI_DMA_ADDR_FIXED_TYPE */
+#define UDI_DMA_FIXED_ELEMENT             1
+/**
+ * \}
+ */
+// DMA Constraints Management
+typedef struct udi_dma_constraints_attr_spec_s udi_dma_constraints_attr_spec_t;
+typedef void udi_dma_constraints_attr_set_call_t(
+       udi_cb_t *gcb, udi_dma_constraints_t new_constraints, udi_status_t status
+       );
+typedef        struct udi_dma_limits_s udi_dma_limits_t;
+
+
+// === STRUCTURES ===
+// --- DMA Constraints Management ---
+struct udi_dma_constraints_attr_spec_s
+{
+     udi_dma_constraints_attr_t        attr_type;
+     udi_ubit32_t      attr_value;
+};
+// --- DMA Core ---
+struct udi_dma_limits_s
+{
+     udi_size_t max_legal_contig_alloc;
+     udi_size_t max_safe_contig_alloc;
+     udi_size_t cache_line_size;
+};
+struct udi_scgth_element_32_s
+{
+     udi_ubit32_t      block_busaddr;
+     udi_ubit32_t      block_length;
+};
+struct udi_scgth_element_64_s
+{
+     udi_busaddr64_t   block_busaddr;
+     udi_ubit32_t      block_length;
+     udi_ubit32_t      el_reserved;
+};
+/* Extension Flag */
+#define UDI_SCGTH_EXT                    0x80000000
+struct udi_scgth_s
+{
+     udi_ubit16_t      scgth_num_elements;
+     udi_ubit8_t       scgth_format;
+     udi_boolean_t     scgth_must_swap;
+     union {
+          udi_scgth_element_32_t       *el32p;
+          udi_scgth_element_64_t       *el64p;
+     } scgth_elements;
+     union {
+          udi_scgth_element_32_t       el32;
+          udi_scgth_element_64_t       el64;
+     } scgth_first_segment;
+};
+/* Values for scgth_format */
+#define UDI_SCGTH_32                     (1U<<0)
+#define UDI_SCGTH_64                     (1U<<1)
+#define UDI_SCGTH_DMA_MAPPED             (1U<<6)
+#define UDI_SCGTH_DRIVER_MAPPED          (1U<<7)
+
+
+
+// === FUNCTIONS ===
+// --- DMA Constraints Management ---
+extern void udi_dma_constraints_attr_set(
+       udi_dma_constraints_attr_set_call_t     *callback,
+       udi_cb_t        *gcb,
+       udi_dma_constraints_t   src_constraints,
+       const udi_dma_constraints_attr_spec_t   *attr_list,
+       udi_ubit16_t    list_length,
+       udi_ubit8_t     flags
+       );
+/* Constraints Flags */
+#define UDI_DMA_CONSTRAINTS_COPY (1U<<0)
+
+extern void udi_dma_constraints_attr_reset(
+       udi_dma_constraints_t   constraints,
+       udi_dma_constraints_attr_t      attr_type
+       );
+
+extern void udi_dma_constraints_free(udi_dma_constraints_t constraints);
+
+#include <physio/meta_intr.h>
+#include <physio/meta_bus.h>
+
+
+#endif
diff --git a/Modules/Interfaces/UDI/logging.c b/Modules/Interfaces/UDI/logging.c
new file mode 100644 (file)
index 0000000..2e58e37
--- /dev/null
@@ -0,0 +1,18 @@
+/**
+ * \file logging.c
+ * \author John Hodge (thePowersGang)
+ */
+#include <acess.h>
+#include <udi.h>
+
+// === PROTOTYPES ===
+
+// === CODE ===
+void udi_log_write( udi_log_write_call_t *callback, udi_cb_t *gcb,
+       udi_trevent_t trace_event, udi_ubit8_t severity, udi_index_t meta_idx,
+       udi_status_t original_status, udi_ubit32_t msgnum, ... )
+{
+       Log("UDI Log");
+}
+
+EXPORT(udi_log_write);
diff --git a/Modules/Interfaces/UDI/main.c b/Modules/Interfaces/UDI/main.c
new file mode 100644 (file)
index 0000000..d114bdc
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Acess2 UDI Layer
+ */
+#define DEBUG  0
+#define VERSION        ((0<<8)|1)
+#include <acess.h>
+#include <modules.h>
+#include <udi.h>
+
+// === PROTOTYPES ===
+ int   UDI_Install(char **Arguments);
+ int   UDI_DetectDriver(void *Base);
+ int   UDI_LoadDriver(void *Base);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, UDI, UDI_Install, NULL, NULL);
+tModuleLoader  gUDI_Loader = {
+       NULL, "UDI", UDI_DetectDriver, UDI_LoadDriver, NULL
+};
+
+// === CODE ===
+/**
+ * \fn int UDI_Install(char **Arguments)
+ * \brief Stub intialisation routine
+ */
+int UDI_Install(char **Arguments)
+{
+       Module_RegisterLoader( &gUDI_Loader );
+       return 1;
+}
+
+/**
+ * \brief Detects if a driver should be loaded by the UDI subsystem
+ */
+int UDI_DetectDriver(void *Base)
+{
+       if( Binary_FindSymbol(Base, "udi_init_info", NULL) == 0) {
+               return 0;
+       }
+       
+       return 1;
+}
+
+/**
+ * \fn int UDI_LoadDriver(void *Base)
+ */
+int UDI_LoadDriver(void *Base)
+{
+       udi_init_t      *info;
+       char    *udiprops = NULL;
+        int    udiprops_size = 0;
+        int    i;
+       // int  j;
+       
+       Log("UDI_LoadDriver: (Base=%p)", Base);
+       
+       if( Binary_FindSymbol(Base, "udi_init_info", (Uint*)&info) == 0) {
+               Binary_Unload(Base);
+               return 0;
+       }
+       
+       if( Binary_FindSymbol(Base, "_udiprops", (Uint*)&udiprops) == 0 ) {
+               Warning("[UDI  ] _udiprops is not defined, this is usually bad");
+       }
+       else {
+               Binary_FindSymbol(Base, "_udiprops_size", (Uint*)&udiprops_size);
+               Log("udiprops = %p, udiprops_size = 0x%x", udiprops, udiprops_size);
+       }
+       
+       
+       Log("primary_init_info = %p = {", info->primary_init_info);
+       {
+               Log(" .mgmt_ops = %p = {", info->primary_init_info->mgmt_ops);
+               Log("  .usage_ind_op: %p() - 0x%02x",
+                       info->primary_init_info->mgmt_ops->usage_ind_op,
+                       info->primary_init_info->mgmt_op_flags[0]
+                       );
+               Log("  .enumerate_req_op: %p() - 0x%02x",
+                       info->primary_init_info->mgmt_ops->enumerate_req_op,
+                       info->primary_init_info->mgmt_op_flags[1]
+                       );
+               Log("  .devmgmt_req_op: %p() - 0x%02x",
+                       info->primary_init_info->mgmt_ops->devmgmt_req_op,
+                       info->primary_init_info->mgmt_op_flags[2]
+                       );
+               Log("  .final_cleanup_req_op: %p() - 0x%02x",
+                       info->primary_init_info->mgmt_ops->final_cleanup_req_op,
+                       info->primary_init_info->mgmt_op_flags[3]
+                       );
+               Log(" }");
+               Log(" .mgmt_scratch_requirement = 0x%x", info->primary_init_info->mgmt_scratch_requirement);
+               Log(" .enumeration_attr_list_length = 0x%x", info->primary_init_info->enumeration_attr_list_length);
+               Log(" .rdata_size = 0x%x", info->primary_init_info->rdata_size);
+               Log(" .child_data_size = 0x%x", info->primary_init_info->child_data_size);
+               Log(" .per_parent_paths = 0x%x", info->primary_init_info->per_parent_paths);
+       }
+       Log("}");
+       Log("secondary_init_list = %p", info->secondary_init_list);
+       Log("ops_init_list = %p", info->ops_init_list);
+       
+       for( i = 0; info->ops_init_list[i].ops_idx; i++ )
+       {
+               Log("info->ops_init_list[%i] = {", i);
+               Log(" .ops_idx = 0x%x", info->ops_init_list[i].ops_idx);
+               Log(" .meta_idx = 0x%x", info->ops_init_list[i].meta_idx);
+               Log(" .meta_ops_num = 0x%x", info->ops_init_list[i].meta_ops_num);
+               Log(" .chan_context_size = 0x%x", info->ops_init_list[i].chan_context_size);
+               Log(" .ops_vector = %p", info->ops_init_list[i].ops_vector);
+               Log(" .op_flags = %p", info->ops_init_list[i].op_flags);
+               Log("}");
+       }
+       
+       return 0;
+}
diff --git a/Modules/Interfaces/UDI/mem.c b/Modules/Interfaces/UDI/mem.c
new file mode 100644 (file)
index 0000000..a09d54c
--- /dev/null
@@ -0,0 +1,32 @@
+/**
+ * \file mem.c
+ * \author John Hodge (thePowersGang)
+ */
+#include <acess.h>
+#include <udi.h>
+
+// === EXPORTS ===
+EXPORT(udi_mem_alloc);
+EXPORT(udi_mem_free);
+
+// === CODE ===
+void udi_mem_alloc(
+       udi_mem_alloc_call_t *callback,
+       udi_cb_t        *gcb,
+       udi_size_t      size,
+       udi_ubit8_t     flags
+       )
+{
+       void    *buf = malloc(size);
+       if(buf)
+       {
+               if( !(flags & UDI_MEM_NOZERO) )
+                       memset(buf, 0, size);
+       }
+       callback(gcb, buf);
+}
+
+void udi_mem_free(void *target_mem)
+{
+       free(target_mem);
+}
diff --git a/Modules/Interfaces/UDI/meta_gio.c b/Modules/Interfaces/UDI/meta_gio.c
new file mode 100644 (file)
index 0000000..1618c27
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * \file meta_gio.c
+ * \author John Hodge (thePowersGang)
+ */
+#include <acess.h>
+#include <udi.h>
+
+// === EXPORTS ===
+EXPORT(udi_gio_bind_req);
+EXPORT(udi_gio_bind_ack);
+EXPORT(udi_gio_unbind_req);
+EXPORT(udi_gio_unbind_ack);
+EXPORT(udi_gio_xfer_req);
+EXPORT(udi_gio_xfer_ack);
+EXPORT(udi_gio_xfer_nak);
+EXPORT(udi_gio_event_res);
+EXPORT(udi_gio_event_ind);
+EXPORT(udi_gio_event_res_unused);
+
+// === CODE ===
+void udi_gio_bind_req(udi_gio_bind_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+void udi_gio_bind_ack(
+       udi_gio_bind_cb_t       *cb,
+       udi_ubit32_t    device_size_lo,
+       udi_ubit32_t    device_size_hi,
+       udi_status_t    status
+       )
+{
+       UNIMPLEMENTED();
+}
+
+void udi_gio_unbind_req(udi_gio_bind_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+void udi_gio_unbind_ack(udi_gio_bind_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+
+void udi_gio_xfer_req(udi_gio_xfer_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+void udi_gio_xfer_ack(udi_gio_xfer_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+void udi_gio_xfer_nak(udi_gio_xfer_cb_t *cb, udi_status_t status)
+{
+       UNIMPLEMENTED();
+}
+
+void udi_gio_event_res(udi_gio_event_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+void udi_gio_event_ind(udi_gio_event_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+void udi_gio_event_res_unused(udi_gio_event_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
diff --git a/Modules/Interfaces/UDI/meta_mgmt.c b/Modules/Interfaces/UDI/meta_mgmt.c
new file mode 100644 (file)
index 0000000..45a02c4
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * \file meta_mgmt.c
+ * \author John Hodge (thePowersGang)
+ */
+#include <acess.h>
+#include <udi.h>
+
+// === EXPORTS ===
+EXPORT(udi_devmgmt_req);
+EXPORT(udi_devmgmt_ack);
+EXPORT(udi_final_cleanup_req);
+EXPORT(udi_final_cleanup_ack);
+EXPORT(udi_static_usage);
+EXPORT(udi_enumerate_no_children);
+
+// === CODE ===
+void udi_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID )
+{      
+       ENTER("pcb imgmt_op iparent_ID", cb, mgmt_op, parent_ID);
+       LEAVE('-');
+}
+
+void udi_devmgmt_ack(udi_mgmt_cb_t *cb, udi_ubit8_t flags, udi_status_t status)
+{
+       ENTER("pcb xflags istatus", cb, flags, status);
+       LEAVE('-');
+}
+
+void udi_final_cleanup_req(udi_mgmt_cb_t *cb)
+{
+       ENTER("pcb", cb);
+       LEAVE('-');
+}
+
+void udi_final_cleanup_ack(udi_mgmt_cb_t *cb)
+{
+       ENTER("pcb", cb);
+       LEAVE('-');
+}
+
+void udi_static_usage(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
+{
+       UNIMPLEMENTED();
+}
+
+void udi_enumerate_no_children(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level)
+{
+       UNIMPLEMENTED();
+}
diff --git a/Modules/Interfaces/UDI/physio.c b/Modules/Interfaces/UDI/physio.c
new file mode 100644 (file)
index 0000000..881c9f4
--- /dev/null
@@ -0,0 +1,25 @@
+/**
+ * \file physio.c
+ * \author John Hodge (thePowersGang)
+ */
+#include <acess.h>
+#include <udi.h>
+#include <udi_physio.h>
+
+// === EXPORTS ===
+EXPORT(udi_dma_constraints_attr_reset);
+EXPORT(udi_dma_constraints_free);
+
+// === CODE ===
+void udi_dma_constraints_attr_reset(
+       udi_dma_constraints_t   constraints,
+       udi_dma_constraints_attr_t      attr_type
+       )
+{
+       UNIMPLEMENTED();
+}
+
+void udi_dma_constraints_free(udi_dma_constraints_t constraints)
+{
+       UNIMPLEMENTED();
+}
diff --git a/Modules/Interfaces/UDI/physio/meta_bus.c b/Modules/Interfaces/UDI/physio/meta_bus.c
new file mode 100644 (file)
index 0000000..e1e6a47
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * \file physio/meta_bus.c
+ * \author John Hodge (thePowersGang)
+ */
+#include <acess.h>
+#include <udi.h>
+#include <udi_physio.h>
+
+// === EXPORTS ===
+EXPORT(udi_bus_unbind_req);
+EXPORT(udi_bus_unbind_ack);
+EXPORT(udi_bus_bind_req);
+EXPORT(udi_bus_bind_ack);
+
+// === CODE ===
+void udi_bus_unbind_req(udi_bus_bind_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+void udi_bus_unbind_ack(udi_bus_bind_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+
+void udi_bus_bind_req(udi_bus_bind_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+
+void udi_bus_bind_ack(
+       udi_bus_bind_cb_t       *cb,
+       udi_dma_constraints_t   dma_constraints,
+       udi_ubit8_t     preferred_endianness,
+       udi_status_t    status
+       )
+{
+       UNIMPLEMENTED();
+}
diff --git a/Modules/Interfaces/UDI/physio/meta_intr.c b/Modules/Interfaces/UDI/physio/meta_intr.c
new file mode 100644 (file)
index 0000000..f4f5096
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * \file physio/meta_intr.c
+ * \author John Hodge (thePowersGang)
+ */
+#include <acess.h>
+#include <udi.h>
+#include <udi_physio.h>
+
+// === EXPORTS ===
+EXPORT(udi_intr_attach_req);
+EXPORT(udi_intr_attach_ack);
+EXPORT(udi_intr_attach_ack_unused);
+EXPORT(udi_intr_detach_req);
+EXPORT(udi_intr_detach_ack);
+EXPORT(udi_intr_detach_ack_unused);
+EXPORT(udi_intr_event_ind);
+
+// === CODE ===
+void udi_intr_attach_req(udi_intr_attach_cb_t *intr_attach_cb)
+{
+       UNIMPLEMENTED();
+}
+void udi_intr_attach_ack(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status)
+{
+       UNIMPLEMENTED();
+}
+void udi_intr_attach_ack_unused(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status)
+{
+       UNIMPLEMENTED();
+}
+
+void udi_intr_detach_req(udi_intr_detach_cb_t *intr_detach_cb)
+{
+       UNIMPLEMENTED();
+}
+void udi_intr_detach_ack(udi_intr_detach_cb_t *intr_detach_cb)
+{
+       UNIMPLEMENTED();
+}
+void udi_intr_detach_ack_unused(udi_intr_detach_cb_t *intr_detach_cb)
+{
+       UNIMPLEMENTED();
+}
+
+void udi_intr_event_ind(udi_intr_event_cb_t *intr_event_cb, udi_ubit8_t flags)
+{
+       UNIMPLEMENTED();
+}
diff --git a/Modules/Interfaces/UDI/physio_main.c b/Modules/Interfaces/UDI/physio_main.c
new file mode 100644 (file)
index 0000000..f5e7aa0
--- /dev/null
@@ -0,0 +1,16 @@
+/**
+ * \file logging.c
+ * \author John Hodge (thePowersGang)
+ */
+#include <common.h>
+#include <udi.h>
+#include <udi_physio.h>
+
+// === CODE ===
+void udi_bus_bind_req(udi_bus_bind_cb_t *cb)
+{
+}
+
+void udi_bus_unbind_req(udi_bus_bind_cb_t *cb)
+{
+}
diff --git a/Modules/Interfaces/UDI/strmem.c b/Modules/Interfaces/UDI/strmem.c
new file mode 100644 (file)
index 0000000..4ab1e20
--- /dev/null
@@ -0,0 +1,16 @@
+/**
+ * \file strmem.c
+ * \author John Hodge (thePowersGang)
+ */
+#include <acess.h>
+#include <udi.h>
+
+// === EXPORTS ===
+EXPORT(udi_snprintf);
+
+// === CODE ===
+udi_size_t udi_snprintf(char *s, udi_size_t max_bytes, const char *format, ...)
+{
+       s[0] = '\0';
+       return 0;
+}
index ae6d574..964f5ce 100644 (file)
@@ -5,6 +5,7 @@
 _CPPFLAGS := $(CPPFLAGS)
 
 CFGFILES = 
+CFGFILES += $(shell test -f ../../../Makefile.cfg && echo ../../../Makefile.cfg)
 CFGFILES += $(shell test -f ../../Makefile.cfg && echo ../../Makefile.cfg)
 CFGFILES += $(shell test -f ../Makefile.cfg && echo ../Makefile.cfg)
 CFGFILES += $(shell test -f Makefile.cfg && echo Makefile.cfg)
diff --git a/Modules/NE2000/Makefile b/Modules/NE2000/Makefile
deleted file mode 100644 (file)
index 7e74022..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-#
-
-OBJ = ne2000.o
-NAME = NE2000
-
--include ../Makefile.tpl
diff --git a/Modules/NE2000/ne2000.c b/Modules/NE2000/ne2000.c
deleted file mode 100644 (file)
index 76e4379..0000000
+++ /dev/null
@@ -1,502 +0,0 @@
-/* Acess2
- * NE2000 Driver
- * 
- * See: ~/Sources/bochs/bochs.../iodev/ne2k.cc
- */
-#define        DEBUG   0
-#define VERSION        ((0<<8)|50)
-#include <acess.h>
-#include <modules.h>
-#include <fs_devfs.h>
-#include <drv_pci.h>
-#include <tpl_drv_network.h>
-
-// === CONSTANTS ===
-#define        MEM_START       0x40
-#define        MEM_END         0xC0
-#define RX_FIRST       (MEM_START)
-#define RX_LAST                (MEM_START+RX_BUF_SIZE-1)
-#define        RX_BUF_SIZE     0x40
-#define TX_FIRST       (MEM_START+RX_BUF_SIZE)
-#define TX_LAST                (MEM_END)
-#define        TX_BUF_SIZE     0x40
-#define        MAX_PACKET_QUEUE        10
-
-static const struct {
-       Uint16  Vendor;
-       Uint16  Device;
-} csaCOMPAT_DEVICES[] = {
-       {0x10EC, 0x8029},       // Realtek 8029
-       {0x10EC, 0x8129}        // Realtek 8129
-};
-#define NUM_COMPAT_DEVICES     (sizeof(csaCOMPAT_DEVICES)/sizeof(csaCOMPAT_DEVICES[0]))
-
-enum eNe2k_Page0Read {
-       CMD = 0,        //!< the master command register
-       CLDA0,          //!< Current Local DMA Address 0
-       CLDA1,          //!< Current Local DMA Address 1
-       BNRY,           //!< Boundary Pointer (for ringbuffer)
-       TSR,            //!< Transmit Status Register
-       NCR,            //!< collisions counter
-       FIFO,           //!< (for what purpose ??)
-       ISR,            //!< Interrupt Status Register
-       CRDA0,          //!< Current Remote DMA Address 0
-       CRDA1,          //!< Current Remote DMA Address 1
-       RSR = 0xC       //!< Receive Status Register
-};
-
-enum eNe2k_Page0Write {
-       PSTART = 1,     //!< page start (init only)
-       PSTOP,          //!< page stop  (init only)
-       TPSR = 4,       //!< transmit page start address
-       TBCR0,          //!< transmit byte count (low)
-       TBCR1,          //!< transmit byte count (high)
-       RSAR0 = 8,      //!< remote start address (lo)
-       RSAR1,  //!< remote start address (hi)
-       RBCR0,  //!< remote byte count (lo)
-       RBCR1,  //!< remote byte count (hi)
-       RCR,    //!< receive config register
-       TCR,    //!< transmit config register
-       DCR,    //!< data config register    (init)
-       IMR             //!< interrupt mask register (init)
-};
-
-enum eNe2k_Page1Read {
-       CURR = 7        //!< current page
-};
-
-// === TYPES ===
-typedef struct sNe2k_Card {
-       Uint16  IOBase; //!< IO Port Address from PCI
-       Uint8   IRQ;    //!< IRQ Assigned from PCI
-       
-        int    NumWaitingPackets;
-        int    NextRXPage;
-       
-        int    NextMemPage;    //!< Next Card Memory page to use
-       
-       Uint8   Buffer[RX_BUF_SIZE];
-       
-       char    Name[2];        // "0"
-       tVFS_Node       Node;
-       Uint8   MacAddr[6];
-} tCard;
-
-// === PROTOTYPES ===
- int   Ne2k_Install(char **Arguments);
-char   *Ne2k_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node      *Ne2k_FindDir(tVFS_Node *Node, char *Name);
- int   Ne2k_IOCtl(tVFS_Node *Node, int ID, void *Data);
-Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
-Uint64 Ne2k_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
-Uint8  Ne2k_int_GetWritePage(tCard *Card, Uint16 Length);
-void   Ne2k_IRQHandler(int IntNum);
-
-// === GLOBALS ===
-MODULE_DEFINE(0, VERSION, Ne2k, Ne2k_Install, NULL, NULL);
-tDevFS_Driver  gNe2k_DriverInfo = {
-       NULL, "ne2k",
-       {
-       .NumACLs = 1,
-       .ACLs = &gVFS_ACL_EveryoneRX,
-       .Flags = VFS_FFLAG_DIRECTORY,
-       .ReadDir = Ne2k_ReadDir,
-       .FindDir = Ne2k_FindDir,
-       .IOCtl = Ne2k_IOCtl
-       }
-};
-Uint16 gNe2k_BaseAddress;
- int   giNe2k_CardCount = 0;
-tCard  *gpNe2k_Cards = NULL;
-
-// === CODE ===
-/**
- * \fn int Ne2k_Install(char **Options)
- * \brief Installs the NE2000 Driver
- */
-int Ne2k_Install(char **Options)
-{
-        int    i, j, k;
-        int    count, id, base;
-       
-       // --- Scan PCI Bus ---
-       // Count Cards
-       giNe2k_CardCount = 0;
-       for( i = 0; i < NUM_COMPAT_DEVICES; i ++ )
-       {
-               giNe2k_CardCount += PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0 );
-       }
-       
-       // Enumerate Cards
-       k = 0;
-       gpNe2k_Cards = calloc( giNe2k_CardCount, sizeof(tCard) );
-       
-       for( i = 0; i < NUM_COMPAT_DEVICES; i ++ )
-       {
-               count = PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0 );
-               for( j = 0; j < count; j ++,k ++ )
-               {
-                       id = PCI_GetDevice( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0, j );
-                       // Create Structure
-                       base = PCI_AssignPort( id, 0, 0x20 );
-                       gpNe2k_Cards[ k ].IOBase = base;
-                       gpNe2k_Cards[ k ].IRQ = PCI_GetIRQ( id );
-                       gpNe2k_Cards[ k ].NextMemPage = 64;
-                       gpNe2k_Cards[ k ].NextRXPage = RX_FIRST;
-                       
-                       // Install IRQ Handler
-                       IRQ_AddHandler(gpNe2k_Cards[ k ].IRQ, Ne2k_IRQHandler);
-                       
-                       // Reset Card
-                       outb( base + 0x1F, inb(base + 0x1F) );
-                       while( (inb( base+ISR ) & 0x80) == 0 );
-                       outb( base + ISR, 0x80 );
-                       
-                       // Initialise Card
-                       outb( base + CMD, 0x40|0x21 );  // Page 1, No DMA, Stop
-                       outb( base + CURR, RX_FIRST );  // Current RX page
-                       outb( base + CMD, 0x21 );       // No DMA and Stop
-                       outb( base + DCR, 0x49 );       // Set WORD mode
-                       outb( base + IMR, 0x00 );
-                       outb( base + ISR, 0xFF );
-                       outb( base + RCR, 0x20 );       // Reciever to Monitor
-                       outb( base + TCR, 0x02 );       // Transmitter OFF (TCR.LB = 1, Internal Loopback)
-                       outb( base + RBCR0, 6*4 );      // Remote Byte Count
-                       outb( base + RBCR1, 0 );
-                       outb( base + RSAR0, 0 );        // Clear Source Address
-                       outb( base + RSAR1, 0 );
-                       outb( base + CMD, 0x0A );       // Remote Read, Start
-                       
-                       // Read MAC Address
-                       gpNe2k_Cards[ k ].MacAddr[0] = inb(base+0x10);//        inb(base+0x10);
-                       gpNe2k_Cards[ k ].MacAddr[1] = inb(base+0x10);//        inb(base+0x10);
-                       gpNe2k_Cards[ k ].MacAddr[2] = inb(base+0x10);//        inb(base+0x10);
-                       gpNe2k_Cards[ k ].MacAddr[3] = inb(base+0x10);//        inb(base+0x10);
-                       gpNe2k_Cards[ k ].MacAddr[4] = inb(base+0x10);//        inb(base+0x10);
-                       gpNe2k_Cards[ k ].MacAddr[5] = inb(base+0x10);//        inb(base+0x10);
-                       
-                       outb( base+PSTART, RX_FIRST);   // Set Receive Start
-                       outb( base+BNRY, RX_LAST-1);    // Set Boundary Page
-                       outb( base+PSTOP, RX_LAST);     // Set Stop Page
-                       outb( base+ISR, 0xFF ); // Clear all ints
-                       outb( base+CMD, 0x22 ); // No DMA, Start
-                       outb( base+IMR, 0x3F ); // Set Interupt Mask
-                       outb( base+RCR, 0x0F ); // Set WRAP and allow all packet matches
-                       outb( base+TCR, 0x00 ); // Set Normal Transmitter mode
-                       outb( base+TPSR, 0x40); // Set Transmit Start
-                       // Set MAC Address
-                       /*
-                       Ne2k_WriteReg(base, MAC0, gpNe2k_Cards[ k ].MacAddr[0]);
-                       Ne2k_WriteReg(base, MAC1, gpNe2k_Cards[ k ].MacAddr[1]);
-                       Ne2k_WriteReg(base, MAC2, gpNe2k_Cards[ k ].MacAddr[2]);
-                       Ne2k_WriteReg(base, MAC3, gpNe2k_Cards[ k ].MacAddr[3]);
-                       Ne2k_WriteReg(base, MAC4, gpNe2k_Cards[ k ].MacAddr[4]);
-                       Ne2k_WriteReg(base, MAC5, gpNe2k_Cards[ k ].MacAddr[5]);
-                       */
-                       
-                       Log("[NE2K]: Card #%i: IRQ=%i, IOBase=0x%x",
-                               k, gpNe2k_Cards[ k ].IRQ, gpNe2k_Cards[ k ].IOBase);
-                       Log("MAC Address %x:%x:%x:%x:%x:%x",
-                               gpNe2k_Cards[ k ].MacAddr[0], gpNe2k_Cards[ k ].MacAddr[1],
-                               gpNe2k_Cards[ k ].MacAddr[2], gpNe2k_Cards[ k ].MacAddr[3],
-                               gpNe2k_Cards[ k ].MacAddr[4], gpNe2k_Cards[ k ].MacAddr[5]
-                               );
-                       
-                       // Set VFS Node
-                       gpNe2k_Cards[ k ].Name[0] = '0'+k;
-                       gpNe2k_Cards[ k ].Name[1] = '\0';
-                       gpNe2k_Cards[ k ].Node.ImplPtr = &gpNe2k_Cards[ k ];
-                       gpNe2k_Cards[ k ].Node.NumACLs = 0;     // Root Only
-                       gpNe2k_Cards[ k ].Node.CTime = now();
-                       gpNe2k_Cards[ k ].Node.Write = Ne2k_Write;
-                       gpNe2k_Cards[ k ].Node.Read = Ne2k_Read;
-                       gpNe2k_Cards[ k ].Node.IOCtl = Ne2k_IOCtl;
-               }
-       }
-       
-       gNe2k_DriverInfo.RootNode.Size = giNe2k_CardCount;
-       DevFS_AddDevice( &gNe2k_DriverInfo );
-       return 1;
-}
-
-/**
- * \fn char *Ne2k_ReadDir(tVFS_Node *Node, int Pos)
- */
-char *Ne2k_ReadDir(tVFS_Node *Node, int Pos)
-{
-       char    ret[2];
-       if(Pos < 0 || Pos >= giNe2k_CardCount)  return NULL;
-       ret[0] = '0'+Pos;
-       ret[1] = '\0';
-       return strdup(ret);
-}
-
-/**
- * \fn tVFS_Node *Ne2k_FindDir(tVFS_Node *Node, char *Name)
- */
-tVFS_Node *Ne2k_FindDir(tVFS_Node *Node, char *Name)
-{
-       if(Name[0] == '\0' || Name[1] != '\0')  return NULL;
-       
-       return &gpNe2k_Cards[ Name[0]-'0' ].Node;
-}
-
-static const char *casIOCtls[] = { DRV_IOCTLNAMES, DRV_NETWORK_IOCTLNAMES, NULL };
-/**
- * \fn int Ne2k_IOCtl(tVFS_Node *Node, int ID, void *Data)
- * \brief IOCtl calls for a network device
- */
-int Ne2k_IOCtl(tVFS_Node *Node, int ID, void *Data)
-{
-        int    tmp;
-       ENTER("pNode iID pData", Node, ID, Data);
-       switch( ID )
-       {
-       case DRV_IOCTL_TYPE:
-               LEAVE('i', DRV_TYPE_NETWORK);
-               return DRV_TYPE_NETWORK;
-       
-       case DRV_IOCTL_IDENT:
-               tmp = ModUtil_SetIdent(Data, "Ne2k");
-               LEAVE('i', tmp);
-               return tmp;
-       
-       case DRV_IOCTL_VERSION:
-               LEAVE('x', VERSION);
-               return VERSION;
-       
-       case DRV_IOCTL_LOOKUP:
-               tmp = ModUtil_LookupString( (char**)casIOCtls, Data );
-               LEAVE('i', tmp);
-               return tmp;
-       }
-       
-       // If this is the root, return
-       if( Node == &gNe2k_DriverInfo.RootNode ) {
-               LEAVE('i', 0);
-               return 0;
-       }
-       
-       // Device specific settings
-       switch( ID )
-       {
-       case NET_IOCTL_GETMAC:
-               if( !CheckMem(Data, 6) ) {
-                       LEAVE('i', -1);
-                       return -1;
-               }
-               memcpy( Data, ((tCard*)Node->ImplPtr)->MacAddr, 6 );
-               LEAVE('i', 1);
-               return 1;
-       }
-       LEAVE('i', 0);
-       return 0;
-}
-
-/**
- * \fn Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
- * \brief Send a packet from the network card
- */
-Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
-{
-       tCard   *Card = (tCard*)Node->ImplPtr;
-       Uint16  *buf = Buffer;
-        int    rem = Length;
-       
-       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
-       
-       // Sanity Check Length
-       if(Length > TX_BUF_SIZE) {
-               LEAVE('i', 0);
-               return 0;
-       }
-       
-       // Make sure that the card is in page 0
-       outb(Card->IOBase + CMD, 0|0x22);       // Page 0, Start, NoDMA
-       
-       // Clear Remote DMA Flag
-       outb(Card->IOBase + ISR, 0x40); // Bit 6
-       
-       // Send Size - Remote Byte Count Register
-       outb(Card->IOBase + TBCR0, Length & 0xFF);
-       outb(Card->IOBase + TBCR1, Length >> 8);
-       
-       // Send Size - Remote Byte Count Register
-       outb(Card->IOBase + RBCR0, Length & 0xFF);
-       outb(Card->IOBase + RBCR1, Length >> 8);
-       
-       // Set up transfer
-       outb(Card->IOBase + RSAR0, 0x00);       // Page Offset
-       outb(Card->IOBase + RSAR1, Ne2k_int_GetWritePage(Card, Length));        // Page Offset
-       // Start
-       //outb(Card->IOBase + CMD, 0|0x18|0x4|0x2);     // Page 0, Transmit Packet, TXP, Start
-       outb(Card->IOBase + CMD, 0|0x10|0x2);   // Page 0, Remote Write, Start
-       
-       // Send Data
-       for(rem = Length; rem; rem -= 2)
-               outw(Card->IOBase + 0x10, *buf++);
-       
-       while( inb(Card->IOBase + ISR) == 0 )   // Wait for Remote DMA Complete
-               ;       //Proc_Yield();
-       
-       outb( Card->IOBase + ISR, 0x40 );       // ACK Interrupt
-       
-       // Send Packet
-       outb(Card->IOBase + CMD, 0|0x10|0x4|0x2);
-       
-       // Complete DMA
-       //outb(Card->IOBase + CMD, 0|0x20);
-       
-       LEAVE('i', Length);
-       return Length;
-}
-
-/**
- * \fn Uint64 Ne2k_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
- * \brief Wait for and read a packet from the network card
- */
-Uint64 Ne2k_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
-{
-       tCard   *Card = (tCard*)Node->ImplPtr;
-       Uint8   page;
-       Uint8   data[256];
-        int    i;
-       struct {
-               Uint8   Status;
-               Uint8   NextPacketPage;
-               Uint16  Length; // Little Endian
-       }       *pktHdr;
-       
-       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
-       
-       while(Card->NumWaitingPackets == 0)     Threads_Yield();
-       
-       // Make sure that the card is in page 0
-       outb(Card->IOBase + CMD, 0|0x22);       // Page 0, Start, NoDMA
-       
-       // Get BOUNDARY
-       page = Card->NextRXPage;
-       
-       // Set up transfer
-       outb(Card->IOBase + RBCR0, 0);
-       outb(Card->IOBase + RBCR1, 1);  // 256-bytes
-       outb(Card->IOBase + RSAR0, 0x00);       // Page Offset
-       outb(Card->IOBase + RSAR1, page);       // Page Number
-       
-       outb(Card->IOBase + CMD, 0|0x08|0x2);   // Page 0, Remote Read, Start
-       
-       // Clear Remote DMA Flag
-       outb(Card->IOBase + ISR, 0x40); // Bit 6
-       
-       // Read data
-       for(i = 0; i < 128; i ++)
-               ((Uint16*)data)[i] = inw(Card->IOBase + 0x10);
-       
-       pktHdr = (void*)data;
-       //Log("Ne2k_Read: Recieved packet (%i bytes)", pktHdr->Length);
-       
-       // Have we read all the required bytes yet?
-       if(pktHdr->Length < 256 - 4)
-       {
-               if(Length > pktHdr->Length)
-                       Length = pktHdr->Length;
-               memcpy(Buffer, &data[4], Length);
-               page ++;
-               if(page == RX_LAST+1)   page = RX_FIRST;
-       }
-       // No? oh damn, now we need to allocate a buffer
-       else {
-                int    j = 256/2;
-               char    *buf = malloc( (pktHdr->Length + 4 + 255) & ~255 );
-               
-               if(!buf) {
-                       LEAVE('i', -1);
-                       return -1;
-               }
-               
-               memcpy(buf, data, 256);
-               
-               page ++;
-               while(page != pktHdr->NextPacketPage)
-               {
-                       if(page == RX_LAST+1)   page = RX_FIRST;
-                       
-                       outb(Card->IOBase + RBCR0, 0);
-                       outb(Card->IOBase + RBCR1, 1);  // 256-bytes
-                       outb(Card->IOBase + RSAR0, 0x00);       // Page Offset
-                       outb(Card->IOBase + RSAR1, page);       // Page Number
-                       outb(Card->IOBase + CMD, 0|0x08|0x2);   // Page 0, Remote Read, Start
-                       
-                       for(i = 0; i < 128; i ++)
-                               ((Uint16*)buf)[j+i] = inw(Card->IOBase + 0x10);
-                       j += 128;
-                       page ++;
-               }
-               
-               if(Length > pktHdr->Length)
-                       Length = pktHdr->Length;
-               memcpy(Buffer, &buf[4], Length);
-       }
-       
-       // Write BNRY
-       if(page == RX_FIRST)
-               outb( Card->IOBase + BNRY, RX_LAST );
-       else
-               outb( Card->IOBase + BNRY, page-1 );
-       // Set next RX Page and decrement the waiting list
-       Card->NextRXPage = page;
-       Card->NumWaitingPackets --;
-       
-       LEAVE('i', Length);
-       return Length;
-}
-
-/**
- * \fn Uint8 Ne2k_int_GetWritePage(tCard *Card, Uint16 Length)
- */
-Uint8 Ne2k_int_GetWritePage(tCard *Card, Uint16 Length)
-{
-       Uint8   ret = Card->NextMemPage;
-       
-       Card->NextMemPage += (Length + 0xFF) >> 8;
-       if(Card->NextMemPage >= TX_LAST) {
-               Card->NextMemPage -= TX_BUF_SIZE;
-       }
-       
-       return ret;
-}
-
-/**
- * \fn void Ne2k_IRQHandler(int IntNum)
- */
-void Ne2k_IRQHandler(int IntNum)
-{
-        int    i;
-       Uint8   byte;
-       for( i = 0; i < giNe2k_CardCount; i++ )
-       {
-               if(gpNe2k_Cards[i].IRQ == IntNum)
-               {
-                       byte = inb( gpNe2k_Cards[i].IOBase + ISR );
-                       
-                       // 0: Packet recieved (no error)
-                       if( byte & 1 )
-                       {
-                               gpNe2k_Cards[i].NumWaitingPackets ++;
-                               if( gpNe2k_Cards[i].NumWaitingPackets > MAX_PACKET_QUEUE )
-                                       gpNe2k_Cards[i].NumWaitingPackets = MAX_PACKET_QUEUE;
-                       }
-                       // 1: Packet sent (no error)
-                       // 2: Recieved with error
-                       // 3: Transmission Halted (Excessive Collisions)
-                       // 4: Recieve Buffer Exhausted
-                       // 5: 
-                       // 6: Remote DMA Complete
-                       // 7: Reset
-                       //LOG("Clearing interrupts on card %i (was 0x%x)\n", i, byte);
-                       outb( gpNe2k_Cards[i].IOBase + ISR, 0xFF );     // Reset All
-                       return ;
-               }
-       }
-       Warning("[NE2K ] Recieved Unknown IRQ %i", IntNum);
-}
diff --git a/Modules/Network/Makefile.tpl b/Modules/Network/Makefile.tpl
new file mode 100644 (file)
index 0000000..80c6d4d
--- /dev/null
@@ -0,0 +1 @@
+-include ../../Makefile.tpl
diff --git a/Modules/Network/NE2000/Makefile b/Modules/Network/NE2000/Makefile
new file mode 100644 (file)
index 0000000..7e74022
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = ne2000.o
+NAME = NE2000
+
+-include ../Makefile.tpl
diff --git a/Modules/Network/NE2000/ne2000.c b/Modules/Network/NE2000/ne2000.c
new file mode 100644 (file)
index 0000000..76e4379
--- /dev/null
@@ -0,0 +1,502 @@
+/* Acess2
+ * NE2000 Driver
+ * 
+ * See: ~/Sources/bochs/bochs.../iodev/ne2k.cc
+ */
+#define        DEBUG   0
+#define VERSION        ((0<<8)|50)
+#include <acess.h>
+#include <modules.h>
+#include <fs_devfs.h>
+#include <drv_pci.h>
+#include <tpl_drv_network.h>
+
+// === CONSTANTS ===
+#define        MEM_START       0x40
+#define        MEM_END         0xC0
+#define RX_FIRST       (MEM_START)
+#define RX_LAST                (MEM_START+RX_BUF_SIZE-1)
+#define        RX_BUF_SIZE     0x40
+#define TX_FIRST       (MEM_START+RX_BUF_SIZE)
+#define TX_LAST                (MEM_END)
+#define        TX_BUF_SIZE     0x40
+#define        MAX_PACKET_QUEUE        10
+
+static const struct {
+       Uint16  Vendor;
+       Uint16  Device;
+} csaCOMPAT_DEVICES[] = {
+       {0x10EC, 0x8029},       // Realtek 8029
+       {0x10EC, 0x8129}        // Realtek 8129
+};
+#define NUM_COMPAT_DEVICES     (sizeof(csaCOMPAT_DEVICES)/sizeof(csaCOMPAT_DEVICES[0]))
+
+enum eNe2k_Page0Read {
+       CMD = 0,        //!< the master command register
+       CLDA0,          //!< Current Local DMA Address 0
+       CLDA1,          //!< Current Local DMA Address 1
+       BNRY,           //!< Boundary Pointer (for ringbuffer)
+       TSR,            //!< Transmit Status Register
+       NCR,            //!< collisions counter
+       FIFO,           //!< (for what purpose ??)
+       ISR,            //!< Interrupt Status Register
+       CRDA0,          //!< Current Remote DMA Address 0
+       CRDA1,          //!< Current Remote DMA Address 1
+       RSR = 0xC       //!< Receive Status Register
+};
+
+enum eNe2k_Page0Write {
+       PSTART = 1,     //!< page start (init only)
+       PSTOP,          //!< page stop  (init only)
+       TPSR = 4,       //!< transmit page start address
+       TBCR0,          //!< transmit byte count (low)
+       TBCR1,          //!< transmit byte count (high)
+       RSAR0 = 8,      //!< remote start address (lo)
+       RSAR1,  //!< remote start address (hi)
+       RBCR0,  //!< remote byte count (lo)
+       RBCR1,  //!< remote byte count (hi)
+       RCR,    //!< receive config register
+       TCR,    //!< transmit config register
+       DCR,    //!< data config register    (init)
+       IMR             //!< interrupt mask register (init)
+};
+
+enum eNe2k_Page1Read {
+       CURR = 7        //!< current page
+};
+
+// === TYPES ===
+typedef struct sNe2k_Card {
+       Uint16  IOBase; //!< IO Port Address from PCI
+       Uint8   IRQ;    //!< IRQ Assigned from PCI
+       
+        int    NumWaitingPackets;
+        int    NextRXPage;
+       
+        int    NextMemPage;    //!< Next Card Memory page to use
+       
+       Uint8   Buffer[RX_BUF_SIZE];
+       
+       char    Name[2];        // "0"
+       tVFS_Node       Node;
+       Uint8   MacAddr[6];
+} tCard;
+
+// === PROTOTYPES ===
+ int   Ne2k_Install(char **Arguments);
+char   *Ne2k_ReadDir(tVFS_Node *Node, int Pos);
+tVFS_Node      *Ne2k_FindDir(tVFS_Node *Node, char *Name);
+ int   Ne2k_IOCtl(tVFS_Node *Node, int ID, void *Data);
+Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+Uint64 Ne2k_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+Uint8  Ne2k_int_GetWritePage(tCard *Card, Uint16 Length);
+void   Ne2k_IRQHandler(int IntNum);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, Ne2k, Ne2k_Install, NULL, NULL);
+tDevFS_Driver  gNe2k_DriverInfo = {
+       NULL, "ne2k",
+       {
+       .NumACLs = 1,
+       .ACLs = &gVFS_ACL_EveryoneRX,
+       .Flags = VFS_FFLAG_DIRECTORY,
+       .ReadDir = Ne2k_ReadDir,
+       .FindDir = Ne2k_FindDir,
+       .IOCtl = Ne2k_IOCtl
+       }
+};
+Uint16 gNe2k_BaseAddress;
+ int   giNe2k_CardCount = 0;
+tCard  *gpNe2k_Cards = NULL;
+
+// === CODE ===
+/**
+ * \fn int Ne2k_Install(char **Options)
+ * \brief Installs the NE2000 Driver
+ */
+int Ne2k_Install(char **Options)
+{
+        int    i, j, k;
+        int    count, id, base;
+       
+       // --- Scan PCI Bus ---
+       // Count Cards
+       giNe2k_CardCount = 0;
+       for( i = 0; i < NUM_COMPAT_DEVICES; i ++ )
+       {
+               giNe2k_CardCount += PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0 );
+       }
+       
+       // Enumerate Cards
+       k = 0;
+       gpNe2k_Cards = calloc( giNe2k_CardCount, sizeof(tCard) );
+       
+       for( i = 0; i < NUM_COMPAT_DEVICES; i ++ )
+       {
+               count = PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0 );
+               for( j = 0; j < count; j ++,k ++ )
+               {
+                       id = PCI_GetDevice( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0, j );
+                       // Create Structure
+                       base = PCI_AssignPort( id, 0, 0x20 );
+                       gpNe2k_Cards[ k ].IOBase = base;
+                       gpNe2k_Cards[ k ].IRQ = PCI_GetIRQ( id );
+                       gpNe2k_Cards[ k ].NextMemPage = 64;
+                       gpNe2k_Cards[ k ].NextRXPage = RX_FIRST;
+                       
+                       // Install IRQ Handler
+                       IRQ_AddHandler(gpNe2k_Cards[ k ].IRQ, Ne2k_IRQHandler);
+                       
+                       // Reset Card
+                       outb( base + 0x1F, inb(base + 0x1F) );
+                       while( (inb( base+ISR ) & 0x80) == 0 );
+                       outb( base + ISR, 0x80 );
+                       
+                       // Initialise Card
+                       outb( base + CMD, 0x40|0x21 );  // Page 1, No DMA, Stop
+                       outb( base + CURR, RX_FIRST );  // Current RX page
+                       outb( base + CMD, 0x21 );       // No DMA and Stop
+                       outb( base + DCR, 0x49 );       // Set WORD mode
+                       outb( base + IMR, 0x00 );
+                       outb( base + ISR, 0xFF );
+                       outb( base + RCR, 0x20 );       // Reciever to Monitor
+                       outb( base + TCR, 0x02 );       // Transmitter OFF (TCR.LB = 1, Internal Loopback)
+                       outb( base + RBCR0, 6*4 );      // Remote Byte Count
+                       outb( base + RBCR1, 0 );
+                       outb( base + RSAR0, 0 );        // Clear Source Address
+                       outb( base + RSAR1, 0 );
+                       outb( base + CMD, 0x0A );       // Remote Read, Start
+                       
+                       // Read MAC Address
+                       gpNe2k_Cards[ k ].MacAddr[0] = inb(base+0x10);//        inb(base+0x10);
+                       gpNe2k_Cards[ k ].MacAddr[1] = inb(base+0x10);//        inb(base+0x10);
+                       gpNe2k_Cards[ k ].MacAddr[2] = inb(base+0x10);//        inb(base+0x10);
+                       gpNe2k_Cards[ k ].MacAddr[3] = inb(base+0x10);//        inb(base+0x10);
+                       gpNe2k_Cards[ k ].MacAddr[4] = inb(base+0x10);//        inb(base+0x10);
+                       gpNe2k_Cards[ k ].MacAddr[5] = inb(base+0x10);//        inb(base+0x10);
+                       
+                       outb( base+PSTART, RX_FIRST);   // Set Receive Start
+                       outb( base+BNRY, RX_LAST-1);    // Set Boundary Page
+                       outb( base+PSTOP, RX_LAST);     // Set Stop Page
+                       outb( base+ISR, 0xFF ); // Clear all ints
+                       outb( base+CMD, 0x22 ); // No DMA, Start
+                       outb( base+IMR, 0x3F ); // Set Interupt Mask
+                       outb( base+RCR, 0x0F ); // Set WRAP and allow all packet matches
+                       outb( base+TCR, 0x00 ); // Set Normal Transmitter mode
+                       outb( base+TPSR, 0x40); // Set Transmit Start
+                       // Set MAC Address
+                       /*
+                       Ne2k_WriteReg(base, MAC0, gpNe2k_Cards[ k ].MacAddr[0]);
+                       Ne2k_WriteReg(base, MAC1, gpNe2k_Cards[ k ].MacAddr[1]);
+                       Ne2k_WriteReg(base, MAC2, gpNe2k_Cards[ k ].MacAddr[2]);
+                       Ne2k_WriteReg(base, MAC3, gpNe2k_Cards[ k ].MacAddr[3]);
+                       Ne2k_WriteReg(base, MAC4, gpNe2k_Cards[ k ].MacAddr[4]);
+                       Ne2k_WriteReg(base, MAC5, gpNe2k_Cards[ k ].MacAddr[5]);
+                       */
+                       
+                       Log("[NE2K]: Card #%i: IRQ=%i, IOBase=0x%x",
+                               k, gpNe2k_Cards[ k ].IRQ, gpNe2k_Cards[ k ].IOBase);
+                       Log("MAC Address %x:%x:%x:%x:%x:%x",
+                               gpNe2k_Cards[ k ].MacAddr[0], gpNe2k_Cards[ k ].MacAddr[1],
+                               gpNe2k_Cards[ k ].MacAddr[2], gpNe2k_Cards[ k ].MacAddr[3],
+                               gpNe2k_Cards[ k ].MacAddr[4], gpNe2k_Cards[ k ].MacAddr[5]
+                               );
+                       
+                       // Set VFS Node
+                       gpNe2k_Cards[ k ].Name[0] = '0'+k;
+                       gpNe2k_Cards[ k ].Name[1] = '\0';
+                       gpNe2k_Cards[ k ].Node.ImplPtr = &gpNe2k_Cards[ k ];
+                       gpNe2k_Cards[ k ].Node.NumACLs = 0;     // Root Only
+                       gpNe2k_Cards[ k ].Node.CTime = now();
+                       gpNe2k_Cards[ k ].Node.Write = Ne2k_Write;
+                       gpNe2k_Cards[ k ].Node.Read = Ne2k_Read;
+                       gpNe2k_Cards[ k ].Node.IOCtl = Ne2k_IOCtl;
+               }
+       }
+       
+       gNe2k_DriverInfo.RootNode.Size = giNe2k_CardCount;
+       DevFS_AddDevice( &gNe2k_DriverInfo );
+       return 1;
+}
+
+/**
+ * \fn char *Ne2k_ReadDir(tVFS_Node *Node, int Pos)
+ */
+char *Ne2k_ReadDir(tVFS_Node *Node, int Pos)
+{
+       char    ret[2];
+       if(Pos < 0 || Pos >= giNe2k_CardCount)  return NULL;
+       ret[0] = '0'+Pos;
+       ret[1] = '\0';
+       return strdup(ret);
+}
+
+/**
+ * \fn tVFS_Node *Ne2k_FindDir(tVFS_Node *Node, char *Name)
+ */
+tVFS_Node *Ne2k_FindDir(tVFS_Node *Node, char *Name)
+{
+       if(Name[0] == '\0' || Name[1] != '\0')  return NULL;
+       
+       return &gpNe2k_Cards[ Name[0]-'0' ].Node;
+}
+
+static const char *casIOCtls[] = { DRV_IOCTLNAMES, DRV_NETWORK_IOCTLNAMES, NULL };
+/**
+ * \fn int Ne2k_IOCtl(tVFS_Node *Node, int ID, void *Data)
+ * \brief IOCtl calls for a network device
+ */
+int Ne2k_IOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+        int    tmp;
+       ENTER("pNode iID pData", Node, ID, Data);
+       switch( ID )
+       {
+       case DRV_IOCTL_TYPE:
+               LEAVE('i', DRV_TYPE_NETWORK);
+               return DRV_TYPE_NETWORK;
+       
+       case DRV_IOCTL_IDENT:
+               tmp = ModUtil_SetIdent(Data, "Ne2k");
+               LEAVE('i', tmp);
+               return tmp;
+       
+       case DRV_IOCTL_VERSION:
+               LEAVE('x', VERSION);
+               return VERSION;
+       
+       case DRV_IOCTL_LOOKUP:
+               tmp = ModUtil_LookupString( (char**)casIOCtls, Data );
+               LEAVE('i', tmp);
+               return tmp;
+       }
+       
+       // If this is the root, return
+       if( Node == &gNe2k_DriverInfo.RootNode ) {
+               LEAVE('i', 0);
+               return 0;
+       }
+       
+       // Device specific settings
+       switch( ID )
+       {
+       case NET_IOCTL_GETMAC:
+               if( !CheckMem(Data, 6) ) {
+                       LEAVE('i', -1);
+                       return -1;
+               }
+               memcpy( Data, ((tCard*)Node->ImplPtr)->MacAddr, 6 );
+               LEAVE('i', 1);
+               return 1;
+       }
+       LEAVE('i', 0);
+       return 0;
+}
+
+/**
+ * \fn Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+ * \brief Send a packet from the network card
+ */
+Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       tCard   *Card = (tCard*)Node->ImplPtr;
+       Uint16  *buf = Buffer;
+        int    rem = Length;
+       
+       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
+       
+       // Sanity Check Length
+       if(Length > TX_BUF_SIZE) {
+               LEAVE('i', 0);
+               return 0;
+       }
+       
+       // Make sure that the card is in page 0
+       outb(Card->IOBase + CMD, 0|0x22);       // Page 0, Start, NoDMA
+       
+       // Clear Remote DMA Flag
+       outb(Card->IOBase + ISR, 0x40); // Bit 6
+       
+       // Send Size - Remote Byte Count Register
+       outb(Card->IOBase + TBCR0, Length & 0xFF);
+       outb(Card->IOBase + TBCR1, Length >> 8);
+       
+       // Send Size - Remote Byte Count Register
+       outb(Card->IOBase + RBCR0, Length & 0xFF);
+       outb(Card->IOBase + RBCR1, Length >> 8);
+       
+       // Set up transfer
+       outb(Card->IOBase + RSAR0, 0x00);       // Page Offset
+       outb(Card->IOBase + RSAR1, Ne2k_int_GetWritePage(Card, Length));        // Page Offset
+       // Start
+       //outb(Card->IOBase + CMD, 0|0x18|0x4|0x2);     // Page 0, Transmit Packet, TXP, Start
+       outb(Card->IOBase + CMD, 0|0x10|0x2);   // Page 0, Remote Write, Start
+       
+       // Send Data
+       for(rem = Length; rem; rem -= 2)
+               outw(Card->IOBase + 0x10, *buf++);
+       
+       while( inb(Card->IOBase + ISR) == 0 )   // Wait for Remote DMA Complete
+               ;       //Proc_Yield();
+       
+       outb( Card->IOBase + ISR, 0x40 );       // ACK Interrupt
+       
+       // Send Packet
+       outb(Card->IOBase + CMD, 0|0x10|0x4|0x2);
+       
+       // Complete DMA
+       //outb(Card->IOBase + CMD, 0|0x20);
+       
+       LEAVE('i', Length);
+       return Length;
+}
+
+/**
+ * \fn Uint64 Ne2k_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+ * \brief Wait for and read a packet from the network card
+ */
+Uint64 Ne2k_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       tCard   *Card = (tCard*)Node->ImplPtr;
+       Uint8   page;
+       Uint8   data[256];
+        int    i;
+       struct {
+               Uint8   Status;
+               Uint8   NextPacketPage;
+               Uint16  Length; // Little Endian
+       }       *pktHdr;
+       
+       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
+       
+       while(Card->NumWaitingPackets == 0)     Threads_Yield();
+       
+       // Make sure that the card is in page 0
+       outb(Card->IOBase + CMD, 0|0x22);       // Page 0, Start, NoDMA
+       
+       // Get BOUNDARY
+       page = Card->NextRXPage;
+       
+       // Set up transfer
+       outb(Card->IOBase + RBCR0, 0);
+       outb(Card->IOBase + RBCR1, 1);  // 256-bytes
+       outb(Card->IOBase + RSAR0, 0x00);       // Page Offset
+       outb(Card->IOBase + RSAR1, page);       // Page Number
+       
+       outb(Card->IOBase + CMD, 0|0x08|0x2);   // Page 0, Remote Read, Start
+       
+       // Clear Remote DMA Flag
+       outb(Card->IOBase + ISR, 0x40); // Bit 6
+       
+       // Read data
+       for(i = 0; i < 128; i ++)
+               ((Uint16*)data)[i] = inw(Card->IOBase + 0x10);
+       
+       pktHdr = (void*)data;
+       //Log("Ne2k_Read: Recieved packet (%i bytes)", pktHdr->Length);
+       
+       // Have we read all the required bytes yet?
+       if(pktHdr->Length < 256 - 4)
+       {
+               if(Length > pktHdr->Length)
+                       Length = pktHdr->Length;
+               memcpy(Buffer, &data[4], Length);
+               page ++;
+               if(page == RX_LAST+1)   page = RX_FIRST;
+       }
+       // No? oh damn, now we need to allocate a buffer
+       else {
+                int    j = 256/2;
+               char    *buf = malloc( (pktHdr->Length + 4 + 255) & ~255 );
+               
+               if(!buf) {
+                       LEAVE('i', -1);
+                       return -1;
+               }
+               
+               memcpy(buf, data, 256);
+               
+               page ++;
+               while(page != pktHdr->NextPacketPage)
+               {
+                       if(page == RX_LAST+1)   page = RX_FIRST;
+                       
+                       outb(Card->IOBase + RBCR0, 0);
+                       outb(Card->IOBase + RBCR1, 1);  // 256-bytes
+                       outb(Card->IOBase + RSAR0, 0x00);       // Page Offset
+                       outb(Card->IOBase + RSAR1, page);       // Page Number
+                       outb(Card->IOBase + CMD, 0|0x08|0x2);   // Page 0, Remote Read, Start
+                       
+                       for(i = 0; i < 128; i ++)
+                               ((Uint16*)buf)[j+i] = inw(Card->IOBase + 0x10);
+                       j += 128;
+                       page ++;
+               }
+               
+               if(Length > pktHdr->Length)
+                       Length = pktHdr->Length;
+               memcpy(Buffer, &buf[4], Length);
+       }
+       
+       // Write BNRY
+       if(page == RX_FIRST)
+               outb( Card->IOBase + BNRY, RX_LAST );
+       else
+               outb( Card->IOBase + BNRY, page-1 );
+       // Set next RX Page and decrement the waiting list
+       Card->NextRXPage = page;
+       Card->NumWaitingPackets --;
+       
+       LEAVE('i', Length);
+       return Length;
+}
+
+/**
+ * \fn Uint8 Ne2k_int_GetWritePage(tCard *Card, Uint16 Length)
+ */
+Uint8 Ne2k_int_GetWritePage(tCard *Card, Uint16 Length)
+{
+       Uint8   ret = Card->NextMemPage;
+       
+       Card->NextMemPage += (Length + 0xFF) >> 8;
+       if(Card->NextMemPage >= TX_LAST) {
+               Card->NextMemPage -= TX_BUF_SIZE;
+       }
+       
+       return ret;
+}
+
+/**
+ * \fn void Ne2k_IRQHandler(int IntNum)
+ */
+void Ne2k_IRQHandler(int IntNum)
+{
+        int    i;
+       Uint8   byte;
+       for( i = 0; i < giNe2k_CardCount; i++ )
+       {
+               if(gpNe2k_Cards[i].IRQ == IntNum)
+               {
+                       byte = inb( gpNe2k_Cards[i].IOBase + ISR );
+                       
+                       // 0: Packet recieved (no error)
+                       if( byte & 1 )
+                       {
+                               gpNe2k_Cards[i].NumWaitingPackets ++;
+                               if( gpNe2k_Cards[i].NumWaitingPackets > MAX_PACKET_QUEUE )
+                                       gpNe2k_Cards[i].NumWaitingPackets = MAX_PACKET_QUEUE;
+                       }
+                       // 1: Packet sent (no error)
+                       // 2: Recieved with error
+                       // 3: Transmission Halted (Excessive Collisions)
+                       // 4: Recieve Buffer Exhausted
+                       // 5: 
+                       // 6: Remote DMA Complete
+                       // 7: Reset
+                       //LOG("Clearing interrupts on card %i (was 0x%x)\n", i, byte);
+                       outb( gpNe2k_Cards[i].IOBase + ISR, 0xFF );     // Reset All
+                       return ;
+               }
+       }
+       Warning("[NE2K ] Recieved Unknown IRQ %i", IntNum);
+}
diff --git a/Modules/Storage/ATA/Makefile b/Modules/Storage/ATA/Makefile
new file mode 100644 (file)
index 0000000..05e66af
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = main.o mbr.o
+NAME = ATA
+
+-include ../Makefile.tpl
diff --git a/Modules/Storage/ATA/common.h b/Modules/Storage/ATA/common.h
new file mode 100644 (file)
index 0000000..18e62a8
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Acess2 IDE Harddisk Driver
+ * - main.c
+ */
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <acess.h>
+#include <vfs.h>
+
+// === CONSTANTS ===
+#define        MAX_ATA_DISKS   4
+#define        SECTOR_SIZE             512
+#define        MAX_DMA_SECTORS (0x1000 / SECTOR_SIZE)
+
+#define        IDE_PRI_BASE    0x1F0
+#define        IDE_SEC_BASE    0x170
+
+#define        IDE_PRDT_LAST   0x8000
+/**
+ \enum HddControls
+ \brief Commands to be sent to HDD_CMD
+*/
+enum HddControls {
+       HDD_PIO_R28 = 0x20,
+       HDD_PIO_R48 = 0x24,
+       HDD_DMA_R48 = 0x25,
+       HDD_PIO_W28 = 0x30,
+       HDD_PIO_W48 = 0x34,
+       HDD_DMA_W48 = 0x35,
+       HDD_DMA_R28 = 0xC8,
+       HDD_DMA_W28 = 0xCA,
+};
+
+// === STRUCTURES ===
+typedef struct
+{
+       Uint8   BootCode[0x1BE];
+       struct {
+               Uint8   Boot;
+               Uint8   Unused1;        // Also CHS Start
+               Uint16  StartHi;        // Also CHS Start
+               Uint8   SystemID;
+               Uint8   Unused2;        // Also CHS Length
+               Uint16  LengthHi;       // Also CHS Length
+               Uint32  LBAStart;
+               Uint32  LBALength;
+       } __attribute__ ((packed)) Parts[4];
+       Uint16  BootFlag;       // = 0xAA 55
+} __attribute__ ((packed))     tMBR;
+
+typedef struct
+{
+       Uint64  Start;
+       Uint64  Length;
+       char    Name[4];
+       tVFS_Node       Node;
+}      tATA_Partition;
+
+typedef struct
+{
+       Uint64  Sectors;
+       char    Name[2];
+       tVFS_Node       Node;
+        int    NumPartitions;
+       tATA_Partition  *Partitions;
+}      tATA_Disk;
+
+// === GLOBALS ===
+extern tATA_Disk       gATA_Disks[];
+
+// === FUNCTIONS ===
+extern void    ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length);
+extern int     ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
+extern int     ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
+
+#endif
diff --git a/Modules/Storage/ATA/main.c b/Modules/Storage/ATA/main.c
new file mode 100644 (file)
index 0000000..41f0873
--- /dev/null
@@ -0,0 +1,793 @@
+/*
+ * Acess2 IDE Harddisk Driver
+ * - main.c
+ */
+#define DEBUG  0
+#include <acess.h>
+#include <modules.h>
+#include <vfs.h>
+#include <fs_devfs.h>
+#include <drv_pci.h>
+#include <tpl_drv_common.h>
+#include <tpl_drv_disk.h>
+#include "common.h"
+
+// --- Flags ---
+#define START_BEFORE_CMD       0
+
+// === STRUCTURES ===
+typedef struct
+{
+       Uint32  PBufAddr;
+       Uint16  Bytes;
+       Uint16  Flags;
+} __attribute__ ((packed))     tPRDT_Ent;
+typedef struct
+{
+       Uint16  Flags;          // 1
+       Uint16  Usused1[9];     // 10
+       char    SerialNum[20];  // 20
+       Uint16  Usused2[3];     // 23
+       char    FirmwareVer[8]; // 27
+       char    ModelNumber[40];        // 47
+       Uint16  SectPerInt;     // 48 - AND with 0xFF to get true value;
+       Uint16  Unused3;        // 49
+       Uint16  Capabilities[2];        // 51
+       Uint16  Unused4[2];     // 53
+       Uint16  ValidExtData;   // 54
+       Uint16  Unused5[5];      // 59
+       Uint16  SizeOfRWMultiple;       // 60
+       Uint32  Sectors28;      // 62
+       Uint16  Unused6[100-62];
+       Uint64  Sectors48;
+       Uint16  Unused7[256-104];
+} __attribute__ ((packed))     tIdentify;
+
+// === IMPORTS ===
+extern void    ATA_ParseMBR(int Disk);
+
+// === PROTOTYPES ===
+ int   ATA_Install();
+ int   ATA_SetupIO();
+void   ATA_SetupPartitions();
+void   ATA_SetupVFS();
+ int   ATA_ScanDisk(int Disk);
+void   ATA_ParseGPT(int Disk);
+void   ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length);
+Uint16 ATA_GetBasePort(int Disk);
+// Filesystem Interface
+char   *ATA_ReadDir(tVFS_Node *Node, int Pos);
+tVFS_Node      *ATA_FindDir(tVFS_Node *Node, char *Name);
+Uint64 ATA_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+Uint64 ATA_WriteFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+ int   ATA_IOCtl(tVFS_Node *Node, int Id, void *Data);
+// Read/Write Interface/Quantiser
+Uint   ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk);
+Uint   ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk);
+// Read/Write DMA
+ int   ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
+ int   ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
+// IRQs
+void   ATA_IRQHandlerPri(int unused);
+void   ATA_IRQHandlerSec(int unused);
+// Controller IO
+Uint8  ATA_int_BusMasterReadByte(int Ofs);
+void   ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value);
+void   ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, 0x0032, i386ATA, ATA_Install, NULL, NULL);
+tDevFS_Driver  gATA_DriverInfo = {
+       NULL, "ata",
+       {
+               .NumACLs = 1,
+               .Size = -1,
+               .Flags = VFS_FFLAG_DIRECTORY,
+               .ACLs = &gVFS_ACL_EveryoneRX,
+               .ReadDir = ATA_ReadDir,
+               .FindDir = ATA_FindDir
+       }
+};
+tATA_Disk      gATA_Disks[MAX_ATA_DISKS];
+ int   giATA_NumNodes;
+tVFS_Node      **gATA_Nodes;
+Uint16 gATA_BusMasterBase = 0;
+Uint8  *gATA_BusMasterBasePtr = 0;
+ int   gATA_IRQPri = 14;
+ int   gATA_IRQSec = 15;
+ int   giaATA_ControllerLock[2] = {0}; //!< Spinlocks for each controller
+Uint8  gATA_Buffers[2][4096] __attribute__ ((section(".padata")));
+ int   gaATA_IRQs[2] = {0};
+tPRDT_Ent      gATA_PRDTs[2] = {
+       {0, 512, IDE_PRDT_LAST},
+       {0, 512, IDE_PRDT_LAST}
+};
+
+// === CODE ===
+/**
+ * \fn int ATA_Install()
+ */
+int ATA_Install()
+{
+       int     ret;
+       
+       ret = ATA_SetupIO();
+       if(ret != 1)    return ret;
+       
+       ATA_SetupPartitions();
+       
+       ATA_SetupVFS();
+       
+       if( DevFS_AddDevice( &gATA_DriverInfo ) == 0 )
+               return MODULE_INIT_FAILURE;
+       
+       return MODULE_INIT_SUCCESS;
+}
+
+/**
+ * \fn int ATA_SetupIO()
+ * \brief Sets up the ATA controller's DMA mode
+ */
+int ATA_SetupIO()
+{
+        int    ent;
+       tPAddr  addr;
+       
+       ENTER("");
+       
+       // Get IDE Controller's PCI Entry
+       ent = PCI_GetDeviceByClass(0x0101, 0xFFFF, -1);
+       LOG("ent = %i", ent);
+       gATA_BusMasterBase = PCI_GetBAR4( ent );
+       if( gATA_BusMasterBase == 0 ) {
+               Warning("It seems that there is no Bus Master Controller on this machine. Get one");
+               LEAVE('i', MODULE_INIT_FAILURE);
+               return MODULE_INIT_FAILURE;
+       }
+       if( !(gATA_BusMasterBase & 1) )
+       {
+               if( gATA_BusMasterBase < 0x100000 )
+                       gATA_BusMasterBasePtr = (void*)(0xC0000000|gATA_BusMasterBase);
+               else
+                       gATA_BusMasterBasePtr = (void*)( MM_MapHWPage( gATA_BusMasterBase, 1 ) + (gATA_BusMasterBase&0xFFF) );
+               LOG("gATA_BusMasterBasePtr = %p", gATA_BusMasterBasePtr);
+       }
+       else {
+               // Bit 0 is left set as a flag to other functions
+               LOG("gATA_BusMasterBase = 0x%x", gATA_BusMasterBase & ~1);
+       }
+       
+       IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri );
+       IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec );
+       
+       gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (Uint)&gATA_Buffers[0] );
+       gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (Uint)&gATA_Buffers[1] );
+       
+       LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr);
+       
+       addr = MM_GetPhysAddr( (Uint)&gATA_PRDTs[0] );
+       LOG("addr = 0x%x", addr);
+       ATA_int_BusMasterWriteDWord(4, addr);
+       addr = MM_GetPhysAddr( (Uint)&gATA_PRDTs[1] );
+       LOG("addr = 0x%x", addr);
+       ATA_int_BusMasterWriteDWord(12, addr);
+       
+       outb(IDE_PRI_BASE+1, 1);
+       outb(IDE_SEC_BASE+1, 1);
+       
+       LEAVE('i', MODULE_INIT_SUCCESS);
+       return MODULE_INIT_SUCCESS;
+}
+
+/**
+ * \fn void ATA_SetupPartitions()
+ */
+void ATA_SetupPartitions()
+{
+        int    i;
+       for( i = 0; i < MAX_ATA_DISKS; i ++ )
+       {
+               if( !ATA_ScanDisk(i) ) {
+                       gATA_Disks[i].Name[0] = '\0';   // Mark as unused
+                       continue;
+               }
+       }
+}
+
+/**
+ * \fn void ATA_SetupVFS()
+ * \brief Sets up the ATA drivers VFS information and registers with DevFS
+ */
+void ATA_SetupVFS()
+{
+        int    i, j, k;
+       
+       // Count number of nodes needed
+       giATA_NumNodes = 0;
+       for( i = 0; i < MAX_ATA_DISKS; i++ )
+       {
+               if(gATA_Disks[i].Name[0] == '\0')       continue;       // Ignore
+               giATA_NumNodes ++;
+               giATA_NumNodes += gATA_Disks[i].NumPartitions;
+       }
+       
+       // Allocate Node space
+       gATA_Nodes = malloc( giATA_NumNodes * sizeof(void*) );
+       
+       // Set nodes
+       k = 0;
+       for( i = 0; i < MAX_ATA_DISKS; i++ )
+       {
+               if(gATA_Disks[i].Name[0] == '\0')       continue;       // Ignore
+               gATA_Nodes[ k++ ] = &gATA_Disks[i].Node;
+               for( j = 0; j < gATA_Disks[i].NumPartitions; j ++ )
+                       gATA_Nodes[ k++ ] = &gATA_Disks[i].Partitions[j].Node;
+       }
+       
+       gATA_DriverInfo.RootNode.Size = giATA_NumNodes;
+}
+
+/**
+ * \fn int ATA_ScanDisk(int Disk)
+ */
+int ATA_ScanDisk(int Disk)
+{
+       Uint16  buf[256];
+       tIdentify       *identify = (void*)buf;
+       tMBR    *mbr = (void*)buf;
+       Uint16  base;
+       Uint8   val;
+        int    i;
+       tVFS_Node       *node;
+       
+       ENTER("iDisk", Disk);
+       
+       base = ATA_GetBasePort( Disk );
+       
+       LOG("base = 0x%x", base);
+       
+       // Send Disk Selector
+       if(Disk == 1 || Disk == 3)
+               outb(base+6, 0xB0);
+       else
+               outb(base+6, 0xA0);
+       
+       // Send IDENTIFY
+       outb(base+7, 0xEC);
+       val = inb(base+7);      // Read status
+       if(val == 0) {
+               LEAVE('i', 0);
+               return 0;       // Disk does not exist
+       }
+       
+       // Poll until BSY clears and DRQ sets or ERR is set
+       while( ((val & 0x80) || !(val & 0x08)) && !(val & 1))   val = inb(base+7);
+       
+       if(val & 1) {
+               LEAVE('i', 0);
+               return 0;       // Error occured, so return false
+       }
+       
+       // Read Data
+       for(i=0;i<256;i++)      buf[i] = inw(base);
+       
+       // Populate Disk Structure
+       if(identify->Sectors48 != 0)
+               gATA_Disks[ Disk ].Sectors = identify->Sectors48;
+       else
+               gATA_Disks[ Disk ].Sectors = identify->Sectors28;
+       
+       
+       LOG("gATA_Disks[ Disk ].Sectors = 0x%x", gATA_Disks[ Disk ].Sectors);
+       
+       if( gATA_Disks[ Disk ].Sectors / (2048*1024) )
+               Log("Disk %i: 0x%llx Sectors (%i GiB)", Disk,
+                       gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / (2048*1024));
+       else if( gATA_Disks[ Disk ].Sectors / 2048 )
+               Log("Disk %i: 0x%llx Sectors (%i MiB)", Disk,
+                       gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / 2048);
+       else
+               Log("Disk %i: 0x%llx Sectors (%i KiB)", Disk,
+                       gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / 2);
+       
+       // Create Name
+       gATA_Disks[ Disk ].Name[0] = 'A'+Disk;
+       gATA_Disks[ Disk ].Name[1] = '\0';
+       
+       // Get pointer to vfs node and populate it
+       node = &gATA_Disks[ Disk ].Node;
+       node->Size = gATA_Disks[Disk].Sectors * SECTOR_SIZE;
+       node->NumACLs = 0;      // Means Superuser only can access it
+       node->Inode = (Disk << 8) | 0xFF;
+       node->ImplPtr = gATA_Disks[ Disk ].Name;
+       
+       node->ATime = node->MTime
+               = node->CTime = now();
+       
+       node->Read = ATA_ReadFS;
+       node->Write = ATA_WriteFS;
+       node->IOCtl = ATA_IOCtl;
+
+
+       // --- Scan Partitions ---
+       LOG("Reading MBR");
+       // Read Boot Sector
+       ATA_ReadDMA( Disk, 0, 1, mbr );
+       
+       // Check for a GPT table
+       if(mbr->Parts[0].SystemID == 0xEE)
+               ATA_ParseGPT(Disk);
+       else    // No? Just parse the MBR
+               ATA_ParseMBR(Disk);
+       
+       LEAVE('i', 0);
+       return 1;
+}
+
+/**
+ * \fn void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length)
+ * \brief Fills a parition's information structure
+ */
+void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length)
+{
+       ENTER("pPart iDisk iNum XStart XLength", Part, Disk, Num, Start, Length);
+       Part->Start = Start;
+       Part->Length = Length;
+       Part->Name[0] = 'A'+Disk;
+       if(Num >= 10) {
+               Part->Name[1] = '1'+Num/10;
+               Part->Name[2] = '1'+Num%10;
+               Part->Name[3] = '\0';
+       } else {
+               Part->Name[1] = '1'+Num;
+               Part->Name[2] = '\0';
+       }
+       Part->Node.NumACLs = 0; // Only root can read/write raw block devices
+       Part->Node.Inode = (Disk << 8) | Num;
+       Part->Node.ImplPtr = Part->Name;
+       
+       Part->Node.Read = ATA_ReadFS;
+       Part->Node.Write = ATA_WriteFS;
+       Part->Node.IOCtl = ATA_IOCtl;
+       LOG("Made '%s' (&Node=%p)", Part->Name, &Part->Node);
+       LEAVE('-');
+}
+
+/**
+ * \fn void ATA_ParseGPT(int Disk)
+ * \brief Parses the GUID Partition Table
+ */
+void ATA_ParseGPT(int Disk)
+{
+       ///\todo Support GPT Disks
+       Warning("GPT Disks are currently unsupported");
+}
+
+/**
+ * \fn Uint16 ATA_GetPortBase(int Disk)
+ * \brief Returns the base port for a given disk
+ */
+Uint16 ATA_GetBasePort(int Disk)
+{
+       switch(Disk)
+       {
+       case 0: case 1:         return IDE_PRI_BASE;
+       case 2: case 3:         return IDE_SEC_BASE;
+       }
+       return 0;
+}
+
+/**
+ * \fn char *ATA_ReadDir(tVFS_Node *Node, int Pos)
+ */
+char *ATA_ReadDir(tVFS_Node *Node, int Pos)
+{
+       if(Pos >= giATA_NumNodes || Pos < 0)    return NULL;
+       return strdup( gATA_Nodes[Pos]->ImplPtr );
+}
+
+/**
+ * \fn tVFS_Node *ATA_FindDir(tVFS_Node *Node, char *Name)
+ */
+tVFS_Node *ATA_FindDir(tVFS_Node *Node, char *Name)
+{
+        int    part;
+       // Check first character
+       if(Name[0] < 'A' || Name[0] > 'A'+MAX_ATA_DISKS)
+               return NULL;
+       // Raw Disk
+       if(Name[1] == '\0') {
+               if( gATA_Disks[Name[0]-'A'].Sectors == 0 )
+                       return NULL;
+               return &gATA_Disks[Name[0]-'A'].Node;
+       }
+       
+       // Partitions
+       if(Name[1] < '0' || '9' < Name[1])      return NULL;
+       if(Name[2] == '\0') {   // <= 9
+               part = Name[1] - '0';
+               part --;
+               return &gATA_Disks[Name[0]-'A'].Partitions[part].Node;
+       }
+       // > 9
+       if('0' > Name[2] || '9' < Name[2])      return NULL;
+       if(Name[3] != '\0')     return NULL;
+       
+       part = (Name[1] - '0') * 10;
+       part += Name[2] - '0';
+       part --;
+       return &gATA_Disks[Name[0]-'A'].Partitions[part].Node;
+       
+}
+
+/**
+ * \fn Uint64 ATA_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+ */
+Uint64 ATA_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+        int    disk = Node->Inode >> 8;
+        int    part = Node->Inode & 0xFF;
+       
+       // Raw Disk Access
+       if(part == 0xFF)
+       {
+               if( Offset >= gATA_Disks[disk].Sectors * SECTOR_SIZE )
+                       return 0;
+               if( Offset + Length > gATA_Disks[disk].Sectors*SECTOR_SIZE )
+                       Length = gATA_Disks[disk].Sectors*SECTOR_SIZE - Offset;
+       }
+       // Partition
+       else
+       {
+               if( Offset >= gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE )
+                       return 0;
+               if( Offset + Length > gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE )
+                       Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset;
+               Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE;
+       }
+       
+       //Log("ATA_ReadFS: (Node=%p, Offset=0x%llx, Length=0x%llx, Buffer=%p)", Node, Offset, Length, Buffer);
+       return DrvUtil_ReadBlock(Offset, Length, Buffer, ATA_ReadRaw, SECTOR_SIZE, disk);
+}
+
+/**
+ * \fn Uint64 ATA_WriteFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+ */
+Uint64 ATA_WriteFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+        int    disk = Node->Inode >> 8;
+        int    part = Node->Inode & 0xFF;
+       
+       // Raw Disk Access
+       if(part == 0xFF)
+       {
+               if( Offset >= gATA_Disks[disk].Sectors * SECTOR_SIZE )
+                       return 0;
+               if( Offset + Length > gATA_Disks[disk].Sectors*SECTOR_SIZE )
+                       Length = gATA_Disks[disk].Sectors*SECTOR_SIZE - Offset;
+       }
+       // Partition
+       else
+       {
+               if( Offset >= gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE )
+                       return 0;
+               if( Offset + Length > gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE )
+                       Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset;
+               Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE;
+       }
+       
+       Log("ATA_WriteFS: (Node=%p, Offset=0x%llx, Length=0x%llx, Buffer=%p)", Node, Offset, Length, Buffer);
+       Debug_HexDump("ATA_WriteFS", Buffer, Length);
+       return DrvUtil_WriteBlock(Offset, Length, Buffer, ATA_ReadRaw, ATA_WriteRaw, SECTOR_SIZE, disk);
+}
+
+/**
+ * \fn int ATA_IOCtl(tVFS_Node *Node, int Id, void *Data)
+ * \brief IO Control Funtion
+ */
+int ATA_IOCtl(tVFS_Node *Node, int Id, void *Data)
+{
+       switch(Id)
+       {
+       case DRV_IOCTL_TYPE:    return DRV_TYPE_DISK;
+       }
+       return 0;
+}
+
+// --- Disk Access ---
+/**
+ * \fn Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
+ */
+Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
+{
+        int    ret;
+       Uint    offset;
+       Uint    done = 0;
+        
+       // Pass straight on to ATA_ReadDMAPage if we can
+       if(Count <= MAX_DMA_SECTORS)
+       {
+               ret = ATA_ReadDMA(Disk, Address, Count, Buffer);
+               if(ret == 0)    return 0;
+               return Count;
+       }
+       
+       // Else we will have to break up the transfer
+       offset = 0;
+       while(Count > MAX_DMA_SECTORS)
+       {
+               ret = ATA_ReadDMA(Disk, Address+offset, MAX_DMA_SECTORS, Buffer+offset);
+               // Check for errors
+               if(ret != 1)    return done;
+               // Change Position
+               done += MAX_DMA_SECTORS;
+               Count -= MAX_DMA_SECTORS;
+               offset += MAX_DMA_SECTORS*SECTOR_SIZE;
+       }
+       
+       ret = ATA_ReadDMA(Disk, Address+offset, Count, Buffer+offset);
+       if(ret != 1)    return 0;
+       return done+Count;
+}
+
+/**
+ * \fn Uint ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
+ */
+Uint ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
+{
+        int    ret;
+       Uint    offset;
+       Uint    done = 0;
+        
+       // Pass straight on to ATA_WriteDMA if we can
+       if(Count <= MAX_DMA_SECTORS)
+       {
+               ret = ATA_WriteDMA(Disk, Address, Count, Buffer);
+               if(ret == 0)    return 0;
+               return Count;
+       }
+       
+       // Else we will have to break up the transfer
+       offset = 0;
+       while(Count > MAX_DMA_SECTORS)
+       {
+               ret = ATA_WriteDMA(Disk, Address+offset, MAX_DMA_SECTORS, Buffer+offset);
+               // Check for errors
+               if(ret != 1)    return done;
+               // Change Position
+               done += MAX_DMA_SECTORS;
+               Count -= MAX_DMA_SECTORS;
+               offset += MAX_DMA_SECTORS*SECTOR_SIZE;
+       }
+       
+       ret = ATA_WriteDMA(Disk, Address+offset, Count, Buffer+offset);
+       if(ret != 1)    return 0;
+       return done+Count;
+}
+
+/**
+ * \fn int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
+ */
+int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
+{
+        int    cont = (Disk>>1)&1;     // Controller ID
+        int    disk = Disk & 1;
+       Uint16  base;
+       
+       ENTER("iDisk XAddress iCount pBuffer", Disk, Address, Count, Buffer);
+       
+       // Check if the count is small enough
+       if(Count > MAX_DMA_SECTORS) {
+               Warning("Passed too many sectors for a bulk DMA read (%i > %i)",
+                       Count, MAX_DMA_SECTORS);
+               LEAVE('i');
+               return 0;
+       }
+       
+       // Get exclusive access to the disk controller
+       LOCK( &giaATA_ControllerLock[ cont ] );
+       
+       // Set Size
+       gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
+       
+       // Get Port Base
+       base = ATA_GetBasePort(Disk);
+       
+       // Reset IRQ Flag
+       gaATA_IRQs[cont] = 0;
+       
+       // Set up transfer
+       outb(base+0x01, 0x00);
+       if( Address > 0x0FFFFFFF )      // Use LBA48
+       {
+               outb(base+0x6, 0x40 | (disk << 4));
+               outb(base+0x2, 0 >> 8); // Upper Sector Count
+               outb(base+0x3, Address >> 24);  // Low 2 Addr
+               outb(base+0x3, Address >> 28);  // Mid 2 Addr
+               outb(base+0x3, Address >> 32);  // High 2 Addr
+       }
+       else
+       {
+               outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); //Disk,Magic,High addr
+       }
+       
+       outb(base+0x02, (Uint8) Count);         // Sector Count
+       outb(base+0x03, (Uint8) Address);               // Low Addr
+       outb(base+0x04, (Uint8) (Address >> 8));        // Middle Addr
+       outb(base+0x05, (Uint8) (Address >> 16));       // High Addr
+       
+       LOG("Starting Transfer");
+       #if START_BEFORE_CMD
+       // Start transfer
+       ATA_int_BusMasterWriteByte( cont << 3, 9 );     // Read and start
+       if( Address > 0x0FFFFFFF )
+               outb(base+0x07, HDD_DMA_R48);   // Read Command (LBA48)
+       else
+               outb(base+0x07, HDD_DMA_R28);   // Read Command (LBA28)
+       #else
+       if( Address > 0x0FFFFFFF )
+               outb(base+0x07, HDD_DMA_R48);   // Read Command (LBA48)
+       else
+               outb(base+0x07, HDD_DMA_R28);   // Read Command (LBA28)
+       // Start transfer
+       ATA_int_BusMasterWriteByte( cont << 3, 9 );     // Read and start
+       #endif
+       
+       // Wait for transfer to complete
+       //ATA_int_BusMasterWriteByte( (cont << 3) + 2, 0x4 );
+       while( gaATA_IRQs[cont] == 0 ) {
+               //Uint8 val = ATA_int_BusMasterReadByte( (cont << 3) + 2, 0x4 );
+               //LOG("val = 0x%02x", val);
+               Threads_Yield();
+       }
+       
+       // Complete Transfer
+       ATA_int_BusMasterWriteByte( cont << 3, 0 );     // Write and stop
+       
+       LOG("Transfer Completed & Acknowledged");
+       
+       // Copy to destination buffer
+       memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE );
+       
+       // Release controller lock
+       RELEASE( &giaATA_ControllerLock[ cont ] );
+       
+       LEAVE('i', 1);
+       return 1;
+}
+
+/**
+ * \fn int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
+ */
+int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
+{
+        int    cont = (Disk>>1)&1;     // Controller ID
+        int    disk = Disk & 1;
+       Uint16  base;
+       
+       // Check if the count is small enough
+       if(Count > MAX_DMA_SECTORS)     return 0;
+       
+       // Get exclusive access to the disk controller
+       LOCK( &giaATA_ControllerLock[ cont ] );
+       
+       // Set Size
+       gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
+       
+       // Get Port Base
+       base = ATA_GetBasePort(Disk);
+       
+       // Set up transfer
+       outb(base+0x01, 0x00);
+       if( Address > 0x0FFFFFFF )      // Use LBA48
+       {
+               outb(base+0x6, 0x40 | (disk << 4));
+               outb(base+0x2, 0 >> 8); // Upper Sector Count
+               outb(base+0x3, Address >> 24);  // Low 2 Addr
+               outb(base+0x3, Address >> 28);  // Mid 2 Addr
+               outb(base+0x3, Address >> 32);  // High 2 Addr
+       }
+       else
+       {
+               outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); //Disk,Magic,High addr
+       }
+       
+       outb(base+0x02, (Uint8) Count);         // Sector Count
+       outb(base+0x03, (Uint8) Address);               // Low Addr
+       outb(base+0x04, (Uint8) (Address >> 8));        // Middle Addr
+       outb(base+0x05, (Uint8) (Address >> 16));       // High Addr
+       if( Address > 0x0FFFFFFF )
+               outb(base+0x07, HDD_DMA_W48);   // Write Command (LBA48)
+       else
+               outb(base+0x07, HDD_DMA_W28);   // Write Command (LBA28)
+       
+       // Reset IRQ Flag
+       gaATA_IRQs[cont] = 0;
+       
+       // Copy to output buffer
+       memcpy( gATA_Buffers[cont], Buffer, Count*SECTOR_SIZE );
+       
+       // Start transfer
+       ATA_int_BusMasterWriteByte( cont << 3, 1 );     // Write and start
+       
+       // Wait for transfer to complete
+       while( gaATA_IRQs[cont] == 0 )  Threads_Yield();
+       
+       // Complete Transfer
+       ATA_int_BusMasterWriteByte( cont << 3, 0 );     // Write and stop
+       
+       // Release controller lock
+       RELEASE( &giaATA_ControllerLock[ cont ] );
+       
+       return 1;
+}
+
+/**
+ * \fn void ATA_IRQHandlerPri(int unused)
+ */
+void ATA_IRQHandlerPri(int unused)
+{
+       Uint8   val;
+       
+       // IRQ bit set for Primary Controller
+       val = ATA_int_BusMasterReadByte( 0x2 );
+       LOG("IRQ val = 0x%x", val);
+       if(val & 4) {
+               LOG("IRQ hit (val = 0x%x)", val);
+               ATA_int_BusMasterWriteByte( 0x2, 4 );
+               gaATA_IRQs[0] = 1;
+               return ;
+       }
+}
+
+/**
+ * \fn void ATA_IRQHandlerSec(int unused)
+ */
+void ATA_IRQHandlerSec(int unused)
+{
+       Uint8   val;
+       // IRQ bit set for Secondary Controller
+       val = ATA_int_BusMasterReadByte( 0xA );
+       if(val & 4) {
+               LOG("IRQ hit (val = 0x%x)", val);
+               ATA_int_BusMasterWriteByte( 0xA, 4 );
+               gaATA_IRQs[1] = 1;
+               return ;
+       }
+}
+
+/**
+ * \fn Uint8 ATA_int_BusMasterReadByte(int Ofs)
+ */
+Uint8 ATA_int_BusMasterReadByte(int Ofs)
+{
+       if( gATA_BusMasterBase & 1 )
+               return inb( (gATA_BusMasterBase & ~1) + Ofs );
+       else
+               return *(Uint8*)(gATA_BusMasterBasePtr + Ofs);
+}
+
+/**
+ * \fn void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value)
+ * \brief Writes a byte to a Bus Master Register
+ */
+void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value)
+{
+       if( gATA_BusMasterBase & 1 )
+               outb( (gATA_BusMasterBase & ~1) + Ofs, Value );
+       else
+               *(Uint8*)(gATA_BusMasterBasePtr + Ofs) = Value;
+}
+
+/**
+ * \fn void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value)
+ * \brief Writes a dword to a Bus Master Register
+ */
+void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value)
+{
+       
+       if( gATA_BusMasterBase & 1 )
+               outd( (gATA_BusMasterBase & ~1) + Ofs, Value );
+       else
+               *(Uint32*)(gATA_BusMasterBasePtr + Ofs) = Value;
+}
diff --git a/Modules/Storage/ATA/mbr.c b/Modules/Storage/ATA/mbr.c
new file mode 100644 (file)
index 0000000..45ade88
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Acess2 IDE Harddisk Driver
+ * - MBR Parsing Code
+ * mbr.c
+ */
+#define DEBUG  0
+#include <acess.h>
+#include "common.h"
+
+// === PROTOTYPES ===
+Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length);
+
+// === GLOBALS ===
+
+// === CODE ===
+/**
+ * \fn void ATA_ParseMBR(int Disk)
+ */
+void ATA_ParseMBR(int Disk)
+{
+        int    i, j = 0, k = 4;
+       tMBR    mbr;
+       Uint64  extendedLBA;
+       Uint64  base, len;
+       
+       ENTER("iDisk", Disk);
+       
+       // Read Boot Sector
+       ATA_ReadDMA( Disk, 0, 1, &mbr );
+       
+       // Count Partitions
+       gATA_Disks[Disk].NumPartitions = 0;
+       extendedLBA = 0;
+       for( i = 0; i < 4; i ++ )
+       {
+               if( mbr.Parts[i].SystemID == 0 )        continue;
+               if(     mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80   // LBA 28
+               ||      mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81   // LBA 48
+                       )
+               {
+                       if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) {
+                               LOG("Extended Partition");
+                               if(extendedLBA != 0) {
+                                       Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
+                                       continue;
+                               }
+                               extendedLBA = mbr.Parts[i].LBAStart;
+                               continue;
+                       }
+                       LOG("Primary Partition");
+                       
+                       gATA_Disks[Disk].NumPartitions ++;
+                       continue;
+               }
+               // Invalid Partition, so don't count it
+       }
+       while(extendedLBA != 0)
+       {
+               extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len);
+               if( extendedLBA == -1 ) return ;
+               gATA_Disks[Disk].NumPartitions ++;
+       }
+       LOG("gATA_Disks[Disk].NumPartitions = %i", gATA_Disks[Disk].NumPartitions);
+       
+       // Create patition array
+       gATA_Disks[Disk].Partitions = malloc( gATA_Disks[Disk].NumPartitions * sizeof(tATA_Partition) );
+       
+       // --- Fill Partition Info ---
+       extendedLBA = 0;
+       for( j = 0, i = 0; i < 4; i ++ )
+       {
+               Log("mbr.Parts[%i].SystemID = 0x%02x", i, mbr.Parts[i].SystemID);
+               if( mbr.Parts[i].SystemID == 0 )        continue;
+               if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 )     // LBA 28
+               {
+                       base = mbr.Parts[i].LBAStart;
+                       len = mbr.Parts[i].LBALength;
+               }
+               else if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 )        // LBA 58
+               {
+                       base = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
+                       len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength;
+               }
+               else
+                       continue;
+               
+               if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) {
+                       if(extendedLBA != 0) {
+                               Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
+                               continue;
+                       }
+                       extendedLBA = base;
+                       continue;
+               }
+               // Create Partition
+               ATA_int_MakePartition(
+                       &gATA_Disks[Disk].Partitions[j], Disk, j,
+                       base, len
+                       );
+               j ++;
+               
+       }
+       // Scan extended partitions
+       while(extendedLBA != 0)
+       {
+               extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len);
+               ATA_int_MakePartition(
+                       &gATA_Disks[Disk].Partitions[j], Disk, k, base, len
+                       );
+       }
+       
+       LEAVE('-');
+}
+
+/**
+ * \brief Reads an extended partition
+ * \return LBA of next Extended, -1 on error, 0 for last
+ */
+Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length)
+{
+       Uint64  link = 0;
+        int    bFoundPart = 0;;
+        int    i;
+       tMBR    mbr;
+       Uint64  base, len;
+       
+       if( ATA_ReadDMA( Disk, Addr, 1, &mbr ) != 0 )
+               return -1;      // Stop on Errors
+       
+       
+       for( i = 0; i < 4; i ++ )
+       {
+               if( mbr.Parts[i].SystemID == 0 )        continue;
+               
+               // LBA 24
+               if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 ) {
+                       base = mbr.Parts[i].LBAStart;
+                       len = mbr.Parts[i].LBALength;
+               }
+               // LBA 48
+               else if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 ) {
+                       base = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
+                       len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength;
+               }
+               else {
+                       Warning("Unknown partition type, Disk %i 0x%llx Part %i",
+                               Disk, Addr, i);
+                       return -1;
+               }
+               
+               switch(mbr.Parts[i].SystemID)
+               {
+               case 0xF:
+               case 0x5:
+                       if(link != 0) {
+                               Warning("Disk %i has two forward links in the extended partition",
+                                       Disk);
+                               return -1;
+                       }
+                       link = base;
+                       break;
+               default:
+                       if(bFoundPart) {
+                               Warning("Disk %i has more than one partition in the extended partition at 0x%llx",
+                                       Disk, Addr);
+                               return -1;
+                       }
+                       bFoundPart = 1;
+                       *Base = base;
+                       *Length = len;
+                       break;
+               }
+       }
+       
+       if(!bFoundPart) {
+               Warning("No partition in extended partiton, Disk %i 0x%llx",
+                       Disk, Addr);
+               return -1;
+       }
+       
+       return link;
+}
diff --git a/Modules/Storage/FDD/Makefile b/Modules/Storage/FDD/Makefile
new file mode 100644 (file)
index 0000000..1596553
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = fdd.o
+NAME = FDD
+
+-include ../Makefile.tpl
diff --git a/Modules/Storage/FDD/fdd.c b/Modules/Storage/FDD/fdd.c
new file mode 100644 (file)
index 0000000..6b55f17
--- /dev/null
@@ -0,0 +1,849 @@
+/*\r
+ * AcessOS 0.1\r
+ * Floppy Disk Access Code\r
+ */\r
+#define DEBUG  0\r
+#include <acess.h>\r
+#include <modules.h>\r
+#include <fs_devfs.h>\r
+#include <tpl_drv_disk.h>\r
+#include <dma.h>\r
+#include <iocache.h>\r
+\r
+#define WARN   0\r
+\r
+// === CONSTANTS ===\r
+// --- Current Version\r
+#define FDD_VERSION     ((0<<8)|(75))\r
+\r
+// --- Options\r
+#define USE_CACHE      0       // Use Sector Cache\r
+#define        CACHE_SIZE      32      // Number of cachable sectors\r
+#define FDD_SEEK_TIMEOUT       10      // Timeout for a seek operation\r
+#define MOTOR_ON_DELAY 500             // Miliseconds\r
+#define MOTOR_OFF_DELAY        2000    // Miliseconds\r
+\r
+// === TYPEDEFS ===\r
+/**\r
+ * \brief Representation of a floppy drive\r
+ */\r
+typedef struct {\r
+        int    type;\r
+       volatile int    motorState;     //2 - On, 1 - Spinup, 0 - Off\r
+        int    track[2];\r
+        int    timer;\r
+       tVFS_Node       Node;\r
+       #if !USE_CACHE\r
+       tIOCache        *CacheHandle;\r
+       #endif\r
+} t_floppyDevice;\r
+\r
+/**\r
+ * \brief Cached Sector\r
+ */\r
+typedef struct {\r
+       Uint64  timestamp;\r
+       Uint16  disk;\r
+       Uint16  sector; // Allows 32Mb of addressable space (Plenty for FDD)\r
+       Uint8   data[512];\r
+} t_floppySector;\r
+\r
+// === CONSTANTS ===\r
+static const char      *cFDD_TYPES[] = {"None", "360kB 5.25\"", "1.2MB 5.25\"", "720kB 3.5\"", "1.44MB 3.5\"", "2.88MB 3.5\"" };\r
+static const int       cFDD_SIZES[] = { 0, 360*1024, 1200*1024, 720*1024, 1440*1024, 2880*1024 };\r
+static const short     cPORTBASE[] = { 0x3F0, 0x370 };\r
+\r
+enum FloppyPorts {\r
+       PORT_STATUSA    = 0x0,\r
+       PORT_STATUSB    = 0x1,\r
+       PORT_DIGOUTPUT  = 0x2,\r
+       PORT_MAINSTATUS = 0x4,\r
+       PORT_DATARATE   = 0x4,\r
+       PORT_DATA               = 0x5,\r
+       PORT_DIGINPUT   = 0x7,\r
+       PORT_CONFIGCTRL = 0x7\r
+};\r
+\r
+enum FloppyCommands {\r
+       FIX_DRIVE_DATA  = 0x03,\r
+       HECK_DRIVE_STATUS       = 0x04,\r
+       CALIBRATE_DRIVE = 0x07,\r
+       CHECK_INTERRUPT_STATUS = 0x08,\r
+       SEEK_TRACK              = 0x0F,\r
+       READ_SECTOR_ID  = 0x4A,\r
+       FORMAT_TRACK    = 0x4D,\r
+       READ_TRACK              = 0x42,\r
+       READ_SECTOR             = 0x66,\r
+       WRITE_SECTOR    = 0xC5,\r
+       WRITE_DELETE_SECTOR     = 0xC9,\r
+       READ_DELETE_SECTOR      = 0xCC,\r
+};\r
+\r
+// === PROTOTYPES ===\r
+// --- Filesystem\r
+ int   FDD_Install(char **Arguments);\r
+char   *FDD_ReadDir(tVFS_Node *Node, int pos);\r
+tVFS_Node      *FDD_FindDir(tVFS_Node *dirNode, char *Name);\r
+ int   FDD_IOCtl(tVFS_Node *Node, int ID, void *Data);\r
+Uint64 FDD_ReadFS(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
+// --- 1st Level Disk Access\r
+Uint   FDD_ReadSectors(Uint64 SectorAddr, Uint Count, void *Buffer, Uint Disk);\r
+// --- Raw Disk Access\r
+ int   FDD_ReadSector(Uint32 disk, Uint64 lba, void *Buffer);\r
+ int   FDD_WriteSector(Uint32 Disk, Uint64 LBA, void *Buffer);\r
+// --- Helpers\r
+void   FDD_IRQHandler(int Num);\r
+void   FDD_WaitIRQ();\r
+void   FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl);\r
+inline void    FDD_AquireSpinlock();\r
+inline void    FDD_FreeSpinlock();\r
+#if USE_CACHE\r
+inline void FDD_AquireCacheSpinlock();\r
+inline void FDD_FreeCacheSpinlock();\r
+#endif\r
+void   FDD_int_SendByte(int base, char byte);\r
+ int   FDD_int_GetByte(int base);\r
+void   FDD_Reset(int id);\r
+void   FDD_Recalibrate(int disk);\r
+ int   FDD_int_SeekTrack(int disk, int head, int track);\r
+void   FDD_int_TimerCallback(int arg);\r
+void   FDD_int_StopMotor(int disk);\r
+void   FDD_int_StartMotor(int disk);\r
+ int   FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt);\r
+\r
+// === GLOBALS ===\r
+MODULE_DEFINE(0, FDD_VERSION, FDD, FDD_Install, NULL, NULL);\r
+t_floppyDevice gFDD_Devices[2];\r
+volatile int   fdd_inUse = 0;\r
+volatile int   fdd_irq6 = 0;\r
+tDevFS_Driver  gFDD_DriverInfo = {\r
+       NULL, "fdd",\r
+       {\r
+       .Size = -1,\r
+       .NumACLs = 1,\r
+       .ACLs = &gVFS_ACL_EveryoneRX,\r
+       .Flags = VFS_FFLAG_DIRECTORY,\r
+       .ReadDir = FDD_ReadDir,\r
+       .FindDir = FDD_FindDir,\r
+       .IOCtl = FDD_IOCtl\r
+       }\r
+};\r
+#if USE_CACHE\r
+int    siFDD_CacheInUse = 0;\r
+int    siFDD_SectorCacheSize = CACHE_SIZE;\r
+t_floppySector sFDD_SectorCache[CACHE_SIZE];\r
+#endif\r
+\r
+// === CODE ===\r
+/**\r
+ * \fn int FDD_Install(char **Arguments)\r
+ * \brief Installs floppy driver\r
+ */\r
+int FDD_Install(char **Arguments)\r
+{\r
+       Uint8 data;\r
+       \r
+       // Determine Floppy Types (From CMOS)\r
+       outb(0x70, 0x10);\r
+       data = inb(0x71);\r
+       gFDD_Devices[0].type = data >> 4;\r
+       gFDD_Devices[1].type = data & 0xF;\r
+       gFDD_Devices[0].track[0] = -1;\r
+       gFDD_Devices[1].track[1] = -1;\r
+       \r
+       Log("[FDD ] Detected Disk 0: %s and Disk 1: %s", cFDD_TYPES[data>>4], cFDD_TYPES[data&0xF]);\r
+       \r
+       // Clear FDD IRQ Flag\r
+       FDD_SensInt(0x3F0, NULL, NULL);\r
+       // Install IRQ6 Handler\r
+       IRQ_AddHandler(6, FDD_IRQHandler);\r
+       // Reset Primary FDD Controller\r
+       FDD_Reset(0);\r
+       \r
+       // Initialise Root Node\r
+       gFDD_DriverInfo.RootNode.CTime = gFDD_DriverInfo.RootNode.MTime\r
+               = gFDD_DriverInfo.RootNode.ATime = now();\r
+       \r
+       // Initialise Child Nodes\r
+       gFDD_Devices[0].Node.Inode = 0;\r
+       gFDD_Devices[0].Node.Flags = 0;\r
+       gFDD_Devices[0].Node.NumACLs = 0;\r
+       gFDD_Devices[0].Node.Read = FDD_ReadFS;\r
+       gFDD_Devices[0].Node.Write = NULL;//fdd_writeFS;\r
+       memcpy(&gFDD_Devices[1].Node, &gFDD_Devices[0].Node, sizeof(tVFS_Node));\r
+       \r
+       gFDD_Devices[1].Node.Inode = 1;\r
+       \r
+       // Set Lengths\r
+       gFDD_Devices[0].Node.Size = cFDD_SIZES[data >> 4];\r
+       gFDD_Devices[1].Node.Size = cFDD_SIZES[data & 0xF];\r
+       \r
+       // Create Sector Cache\r
+       #if USE_CACHE\r
+       //sFDD_SectorCache = malloc(sizeof(*sFDD_SectorCache)*CACHE_SIZE);\r
+       //siFDD_SectorCacheSize = CACHE_SIZE;\r
+       #else\r
+       if( cFDD_SIZES[data >> 4] ) {\r
+               gFDD_Devices[0].CacheHandle = IOCache_Create(\r
+                       FDD_WriteSector, 0, 512,\r
+                       gFDD_Devices[0].Node.Size / (512*4)\r
+                       );      // Cache is 1/4 the size of the disk\r
+       }\r
+       if( cFDD_SIZES[data & 15] ) {\r
+               gFDD_Devices[1].CacheHandle = IOCache_Create(\r
+                       FDD_WriteSector, 0, 512,\r
+                       gFDD_Devices[1].Node.Size / (512*4)\r
+                       );      // Cache is 1/4 the size of the disk\r
+       }\r
+       #endif\r
+       \r
+       // Register with devfs\r
+       DevFS_AddDevice(&gFDD_DriverInfo);\r
+       \r
+       return 1;\r
+}\r
+\r
+/**\r
+ * \fn char *FDD_ReadDir(tVFS_Node *Node, int pos)\r
+ * \brief Read Directory\r
+ */\r
+char *FDD_ReadDir(tVFS_Node *Node, int pos)\r
+{\r
+       char    name[2] = "0\0";\r
+       //Update Accessed Time\r
+       //gFDD_DrvInfo.rootNode.atime = now();\r
+       \r
+       //Check for bounds\r
+       if(pos >= 2 || pos < 0)\r
+               return NULL;\r
+       \r
+       if(gFDD_Devices[pos].type == 0)\r
+               return VFS_SKIP;\r
+       \r
+       name[0] += pos;\r
+       \r
+       //Return\r
+       return strdup(name);\r
+}\r
+\r
+/**\r
+ * \fn tVFS_Node *FDD_FindDir(tVFS_Node *Node, char *filename);\r
+ * \brief Find File Routine (for vfs_node)\r
+ */\r
+tVFS_Node *FDD_FindDir(tVFS_Node *Node, char *Filename)\r
+{\r
+        int    i;\r
+       \r
+       ENTER("sFilename", Filename);\r
+       \r
+       // Sanity check string\r
+       if(Filename == NULL) {\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       \r
+       // Check string length (should be 1)\r
+       if(Filename[0] == '\0' || Filename[1] != '\0') {\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       \r
+       // Get First character\r
+       i = Filename[0] - '0';\r
+       \r
+       // Check for 1st disk and if it is present return\r
+       if(i == 0 && gFDD_Devices[0].type != 0) {\r
+               LEAVE('p', &gFDD_Devices[0].Node);\r
+               return &gFDD_Devices[0].Node;\r
+       }\r
+       \r
+       // Check for 2nd disk and if it is present return\r
+       if(i == 1 && gFDD_Devices[1].type != 0) {\r
+               LEAVE('p', &gFDD_Devices[1].Node);\r
+               return &gFDD_Devices[1].Node;\r
+       }\r
+       \r
+       // Else return null\r
+       LEAVE('n');\r
+       return NULL;\r
+}\r
+\r
+static const char      *casIOCTLS[] = {DRV_IOCTLNAMES,DRV_DISK_IOCTLNAMES,NULL};\r
+/**\r
+ * \fn int FDD_IOCtl(tVFS_Node *Node, int id, void *data)\r
+ * \brief Stub ioctl function\r
+ */\r
+int FDD_IOCtl(tVFS_Node *Node, int ID, void *Data)\r
+{\r
+       switch(ID)\r
+       {\r
+       case DRV_IOCTL_TYPE:    return DRV_TYPE_DISK;\r
+       case DRV_IOCTL_IDENT:   return ModUtil_SetIdent(Data, "FDD");\r
+       case DRV_IOCTL_VERSION: return FDD_VERSION;\r
+       case DRV_IOCTL_LOOKUP:  return ModUtil_LookupString((char**)casIOCTLS, Data);\r
+       \r
+       case DISK_IOCTL_GETBLOCKSIZE:   return 512;     \r
+       \r
+       default:\r
+               return 0;\r
+       }\r
+}\r
+\r
+/**\r
+ * \fn Uint64 FDD_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
+ * \brief Read Data from a disk\r
+*/\r
+Uint64 FDD_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
+{\r
+        int    i = 0;\r
+        int    disk;\r
+       //Uint32        buf[128];\r
+       \r
+       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);\r
+       \r
+       if(Node == NULL) {\r
+               LEAVE('i', -1);\r
+               return -1;\r
+       }\r
+       \r
+       if(Node->Inode != 0 && Node->Inode != 1) {\r
+               LEAVE('i', -1);\r
+               return -1;\r
+       }\r
+       \r
+       disk = Node->Inode;\r
+       \r
+       // Update Accessed Time\r
+       Node->ATime = now();\r
+       \r
+       #if 0\r
+       if((Offset & 0x1FF) || (Length & 0x1FF))\r
+       {\r
+               // Un-Aligned Offset/Length\r
+                int    startOff = Offset >> 9;\r
+                int    sectOff = Offset & 0x1FF;\r
+                int    sectors = (Length + 0x1FF) >> 9;\r
+       \r
+               LOG("Non-aligned Read");\r
+               \r
+               //Read Starting Sector\r
+               if(!FDD_ReadSector(disk, startOff, buf))\r
+                       return 0;\r
+               memcpy(Buffer, (char*)(buf+sectOff), Length > 512-sectOff ? 512-sectOff : Length);\r
+               \r
+               // If the data size is one sector or less\r
+               if(Length <= 512-sectOff)\r
+               {\r
+                       LEAVE('X', Length);\r
+                       return Length;  //Return\r
+               }\r
+               Buffer += 512-sectOff;\r
+       \r
+               //Read Middle Sectors\r
+               for( i = 1; i < sectors - 1; i++ )\r
+               {\r
+                       if(!FDD_ReadSector(disk, startOff+i, buf)) {\r
+                               LEAVE('i', -1);\r
+                               return -1;\r
+                       }\r
+                       memcpy(Buffer, buf, 512);\r
+                       Buffer += 512;\r
+               }\r
+       \r
+               //Read End Sectors\r
+               if(!FDD_ReadSector(disk, startOff+i, buf))\r
+                       return 0;\r
+               memcpy(Buffer, buf, (len&0x1FF)-sectOff);\r
+               
+               LEAVE('X', Length);\r
+               return Length;\r
+       }\r
+       else\r
+       {\r
+                int    count = Length >> 9;\r
+                int    sector = Offset >> 9;\r
+               LOG("Aligned Read");\r
+               //Aligned Offset and Length - Simple Code\r
+               for( i = 0; i < count; i ++ )\r
+               {\r
+                       FDD_ReadSector(disk, sector, buf);\r
+                       memcpy(buffer, buf, 512);\r
+                       buffer += 512;\r
+                       sector++;\r
+               }
+               LEAVE('i', Length);\r
+               return Length;\r
+       }\r
+       #endif\r
+       \r
+       i = DrvUtil_ReadBlock(Offset, Length, Buffer, FDD_ReadSectors, 512, disk);\r
+       LEAVE('i', i);\r
+       return i;\r
+}\r
+\r
+/**\r
+ * \fn Uint FDD_ReadSectors(Uint64 SectorAddr, Uint Count, void *Buffer, Uint32 Disk)\r
+ * \brief Reads \a Count contiguous sectors from a disk\r
+ * \param SectorAddr   Address of the first sector\r
+ * \param Count        Number of sectors to read\r
+ * \param Buffer       Destination Buffer\r
+ * \param Disk Disk Number\r
+ * \return Number of sectors read\r
+ * \note Used as a ::DrvUtil_ReadBlock helper\r
+ */\r
+Uint FDD_ReadSectors(Uint64 SectorAddr, Uint Count, void *Buffer, Uint Disk)\r
+{\r
+       Uint    ret = 0;\r
+       while(Count --)\r
+       {\r
+               if( FDD_ReadSector(Disk, SectorAddr, Buffer) != 1 )\r
+                       return ret;\r
+               \r
+               Buffer = (void*)( (tVAddr)Buffer + 512 );\r
+               SectorAddr ++;\r
+               ret ++;\r
+       }\r
+       return ret;\r
+}\r
+\r
+/**\r
+ * \fn int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer)\r
+ * \fn Read a sector from disk\r
+*/\r
+int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer)\r
+{\r
+        int    cyl, head, sec;\r
+        int    spt, base;\r
+        int    i;\r
+        int    lba = SectorAddr;\r
+       \r
+       ENTER("idisk Xlba pbuf", disk, lba, buf);\r
+       \r
+       #if USE_CACHE\r
+       FDD_AquireCacheSpinlock();\r
+       for( i = 0; i < siFDD_SectorCacheSize; i++ )\r
+       {\r
+               if(sFDD_SectorCache[i].timestamp == 0)  continue;\r
+               if(sFDD_SectorCache[i].disk == Disk\r
+               && sFDD_SectorCache[i].sector == lba) {\r
+                       LOG("Found %i in cache %i", lba, i);\r
+                       memcpy(Buffer, sFDD_SectorCache[i].data, 512);\r
+                       sFDD_SectorCache[i].timestamp = now();\r
+                       FDD_FreeCacheSpinlock();\r
+                       LEAVE('i', 1);\r
+                       return 1;\r
+               }\r
+       }\r
+       LOG("Read %i from Disk", lba);\r
+       FDD_FreeCacheSpinlock();\r
+       #else\r
+       if( IOCache_Read( gFDD_Devices[Disk].CacheHandle, SectorAddr, Buffer ) == 1 ) {\r
+               LEAVE('i', 1);\r
+               return 1;\r
+       }\r
+       #endif\r
+       \r
+       base = cPORTBASE[Disk>>1];\r
+       \r
+       LOG("Calculating Disk Dimensions");\r
+       // Get CHS position\r
+       if(FDD_int_GetDims(gFDD_Devices[Disk].type, lba, &cyl, &head, &sec, &spt) != 1) {\r
+               LEAVE('i', -1);\r
+               return -1;\r
+       }\r
+       \r
+       // Remove Old Timer\r
+       Time_RemoveTimer(gFDD_Devices[Disk].timer);\r
+       // Check if Motor is on\r
+       if(gFDD_Devices[Disk].motorState == 0) {\r
+               FDD_int_StartMotor(Disk);\r
+       }\r
+       \r
+       LOG("Wait for Motor Spinup");\r
+       \r
+       // Wait for spinup\r
+       while(gFDD_Devices[Disk].motorState == 1)       Threads_Yield();\r
+       \r
+       LOG("C:%i,H:%i,S:%i", cyl, head, sec);\r
+       LOG("Acquire Spinlock");\r
+       \r
+       FDD_AquireSpinlock();\r
+       \r
+       // Seek to track\r
+       outb(base+CALIBRATE_DRIVE, 0);\r
+       i = 0;\r
+       while(FDD_int_SeekTrack(Disk, head, (Uint8)cyl) == 0 && i++ < FDD_SEEK_TIMEOUT )        Threads_Yield();\r
+       //FDD_SensInt(base, NULL, NULL);        // Wait for IRQ\r
+       \r
+       LOG("Setting DMA for read");\r
+       \r
+       //Read Data from DMA\r
+       DMA_SetChannel(2, 512, 1);      // Read 512 Bytes\r
+       \r
+       LOG("Sending read command");\r
+       \r
+       //Threads_Wait(100);    // Wait for Head to settle\r
+       Time_Delay(100);\r
+       FDD_int_SendByte(base, READ_SECTOR);    // Was 0xE6\r
+       FDD_int_SendByte(base, (head << 2) | (Disk&1));\r
+       FDD_int_SendByte(base, (Uint8)cyl);\r
+       FDD_int_SendByte(base, (Uint8)head);\r
+       FDD_int_SendByte(base, (Uint8)sec);\r
+       FDD_int_SendByte(base, 0x02);   // Bytes Per Sector (Real BPS=128*2^{val})\r
+       FDD_int_SendByte(base, spt);    // SPT\r
+       FDD_int_SendByte(base, 0x1B);   // Gap Length (27 is default)\r
+       FDD_int_SendByte(base, 0xFF);   // Data Length\r
+       \r
+       // Wait for IRQ\r
+       LOG("Waiting for Data to be read");\r
+       FDD_WaitIRQ();\r
+       \r
+       // Read Data from DMA\r
+       LOG(" FDD_ReadSector: Reading Data");\r
+       DMA_ReadData(2, 512, Buffer);\r
+       \r
+       // Clear Input Buffer\r
+       LOG("Clearing Input Buffer");\r
+       FDD_int_GetByte(base); FDD_int_GetByte(base); FDD_int_GetByte(base);\r
+       FDD_int_GetByte(base); FDD_int_GetByte(base); FDD_int_GetByte(base); FDD_int_GetByte(base);\r
+       \r
+       LOG("Realeasing Spinlock and Setting motor to stop");\r
+       // Release Spinlock\r
+       FDD_FreeSpinlock();\r
+       \r
+       //Set timer to turn off motor affter a gap\r
+       gFDD_Devices[Disk].timer = Time_CreateTimer(MOTOR_OFF_DELAY, FDD_int_StopMotor, (void*)Disk);   //One Shot Timer
+\r
+       #if USE_CACHE\r
+       {\r
+               FDD_AquireCacheSpinlock();\r
+               int oldest = 0;\r
+               for(i=0;i<siFDD_SectorCacheSize;i++)\r
+               {\r
+                       if(sFDD_SectorCache[i].timestamp == 0) {\r
+                               oldest = i;\r
+                               break;\r
+                       }\r
+                       if(sFDD_SectorCache[i].timestamp < sFDD_SectorCache[oldest].timestamp)\r
+                               oldest = i;\r
+               }\r
+               sFDD_SectorCache[oldest].timestamp = now();\r
+               sFDD_SectorCache[oldest].disk = Disk;\r
+               sFDD_SectorCache[oldest].sector = lba;\r
+               memcpy(sFDD_SectorCache[oldest].data, Buffer, 512);\r
+               FDD_FreeCacheSpinlock();\r
+       }\r
+       #else\r
+       IOCache_Add( gFDD_Devices[Disk].CacheHandle, SectorAddr, Buffer );\r
+       #endif\r
+
+       LEAVE('i', 1);\r
+       return 1;\r
+}\r
+\r
+/**\r
+ * \fn int FDD_WriteSector(Uint32 Disk, Uint64 LBA, void *Buffer)\r
+ * \brief Write a sector to the floppy disk\r
+ * \note Not Implemented\r
+ */\r
+int FDD_WriteSector(Uint32 Disk, Uint64 LBA, void *Buffer)\r
+{\r
+       Warning("[FDD  ] Read Only at the moment");\r
+       return -1;\r
+}\r
+\r
+/**\r
+ * \fn int FDD_int_SeekTrack(int disk, int track)\r
+ * \brief Seek disk to selected track\r
+ */\r
+int FDD_int_SeekTrack(int disk, int head, int track)\r
+{\r
+       Uint8   sr0, cyl;\r
+        int    base;\r
+       \r
+       base = cPORTBASE[disk>>1];\r
+       \r
+       // Check if seeking is needed\r
+       if(gFDD_Devices[disk].track[head] == track)\r
+               return 1;\r
+       \r
+       // - Seek Head 0\r
+       FDD_int_SendByte(base, SEEK_TRACK);\r
+       FDD_int_SendByte(base, (head<<2)|(disk&1));\r
+       FDD_int_SendByte(base, track);  // Send Seek command\r
+       FDD_WaitIRQ();\r
+       FDD_SensInt(base, &sr0, &cyl);  // Wait for IRQ\r
+       if((sr0 & 0xF0) != 0x20) {
+               LOG("sr0 = 0x%x", sr0);
+               return 0;       //Check Status
+       }\r
+       if(cyl != track)        return 0;\r
+       \r
+       // Set Track in structure\r
+       gFDD_Devices[disk].track[head] = track;\r
+       return 1;\r
+}\r
+\r
+/**\r
+ * \fn int FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt)\r
+ * \brief Get Dimensions of a disk\r
+ */\r
+int FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt)\r
+{\r
+       switch(type) {\r
+       case 0:\r
+               return 0;\r
+       \r
+       // 360Kb 5.25"\r
+       case 1:\r
+               *spt = 9;\r
+               *s = (lba % 9) + 1;\r
+               *c = lba / 18;\r
+               *h = (lba / 9) & 1;\r
+               break;\r
+       \r
+       // 1220Kb 5.25"\r
+       case 2:\r
+               *spt = 15;\r
+               *s = (lba % 15) + 1;\r
+               *c = lba / 30;\r
+               *h = (lba / 15) & 1;\r
+               break;\r
+       \r
+       // 720Kb 3.5"\r
+       case 3:\r
+               *spt = 9;\r
+               *s = (lba % 9) + 1;\r
+               *c = lba / 18;\r
+               *h = (lba / 9) & 1;\r
+               break;\r
+       \r
+       // 1440Kb 3.5"\r
+       case 4:\r
+               *spt = 18;\r
+               *s = (lba % 18) + 1;\r
+               *c = lba / 36;\r
+               *h = (lba / 18) & 1;\r
+               //Log("1440k - lba=%i(0x%x), *s=%i,*c=%i,*h=%i", lba, lba, *s, *c, *h);\r
+               break;\r
+               \r
+       // 2880Kb 3.5"\r
+       case 5:\r
+               *spt = 36;\r
+               *s = (lba % 36) + 1;\r
+               *c = lba / 72;\r
+               *h = (lba / 32) & 1;\r
+               break;\r
+               \r
+       default:\r
+               return -2;\r
+       }\r
+       return 1;\r
+}\r
+\r
+/**\r
+ * \fn void FDD_IRQHandler(int Num)\r
+ * \brief Handles IRQ6\r
+ */\r
+void FDD_IRQHandler(int Num)\r
+{\r
+    fdd_irq6 = 1;\r
+}\r
+\r
+/**\r
+ * \fn FDD_WaitIRQ()\r
+ * \brief Wait for an IRQ6\r
+ */\r
+void FDD_WaitIRQ()\r
+{\r
+       // Wait for IRQ\r
+       while(!fdd_irq6)        Threads_Yield();\r
+       fdd_irq6 = 0;\r
+}\r
+\r
+void FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl)\r
+{\r
+       FDD_int_SendByte(base, CHECK_INTERRUPT_STATUS);\r
+       if(sr0) *sr0 = FDD_int_GetByte(base);\r
+       else    FDD_int_GetByte(base);\r
+       if(cyl) *cyl = FDD_int_GetByte(base);\r
+       else    FDD_int_GetByte(base);\r
+}\r
+\r
+void FDD_AquireSpinlock()\r
+{\r
+       while(fdd_inUse)\r
+               Threads_Yield();\r
+       fdd_inUse = 1;\r
+}\r
+\r
+inline void FDD_FreeSpinlock()\r
+{\r
+       fdd_inUse = 0;\r
+}\r
+\r
+#if USE_CACHE\r
+inline void FDD_AquireCacheSpinlock()\r
+{\r
+       while(siFDD_CacheInUse) Threads_Yield();\r
+       siFDD_CacheInUse = 1;\r
+}\r
+inline void FDD_FreeCacheSpinlock()\r
+{\r
+       siFDD_CacheInUse = 0;\r
+}\r
+#endif\r
+\r
+/**\r
+ * void FDD_int_SendByte(int base, char byte)\r
+ * \brief Sends a command to the controller\r
+ */\r
+void FDD_int_SendByte(int base, char byte)\r
+{\r
+    volatile int state;\r
+    int timeout = 128;\r
+    for( ; timeout--; )\r
+    {\r
+        state = inb(base + PORT_MAINSTATUS);\r
+        if ((state & 0xC0) == 0x80)\r
+        {\r
+            outb(base + PORT_DATA, byte);\r
+            return;\r
+        }\r
+        inb(0x80);     //Delay\r
+    }\r
+       #if WARN\r
+               Warning("FDD_int_SendByte - Timeout sending byte 0x%x to base 0x%x\n", byte, base);\r
+       #endif\r
+}\r
+\r
+/**\r
+ * int FDD_int_GetByte(int base, char byte)\r
+ * \brief Receive data from fdd controller\r
+ */\r
+int FDD_int_GetByte(int base)\r
+{\r
+    volatile int state;\r
+    int timeout;\r
+    for( timeout = 128; timeout--; )\r
+    {\r
+        state = inb((base + PORT_MAINSTATUS));\r
+        if ((state & 0xd0) == 0xd0)\r
+               return inb(base + PORT_DATA);\r
+        inb(0x80);\r
+    }\r
+    return -1;\r
+}\r
+\r
+/**\r
+ * \brief Recalibrate the specified disk\r
+ */\r
+void FDD_Recalibrate(int disk)\r
+{\r
+       ENTER("idisk", disk);\r
+       \r
+       LOG("Starting Motor");\r
+       FDD_int_StartMotor(disk);\r
+       // Wait for Spinup\r
+       while(gFDD_Devices[disk].motorState == 1)       Threads_Yield();\r
+       \r
+       LOG("Sending Calibrate Command");\r
+       FDD_int_SendByte(cPORTBASE[disk>>1], CALIBRATE_DRIVE);\r
+       FDD_int_SendByte(cPORTBASE[disk>>1], disk&1);\r
+       \r
+       LOG("Waiting for IRQ");\r
+       FDD_WaitIRQ();\r
+       FDD_SensInt(cPORTBASE[disk>>1], NULL, NULL);\r
+       \r
+       LOG("Stopping Motor");\r
+       FDD_int_StopMotor(disk);\r
+       LEAVE('-');\r
+}\r
+\r
+/**\r
+ * \brief Reset the specified FDD controller\r
+ */\r
+void FDD_Reset(int id)\r
+{\r
+       int base = cPORTBASE[id];\r
+       \r
+       ENTER("iID", id);\r
+       \r
+       outb(base + PORT_DIGOUTPUT, 0); // Stop Motors & Disable FDC\r
+       outb(base + PORT_DIGOUTPUT, 0x0C);      // Re-enable FDC (DMA and Enable)\r
+       \r
+       LOG("Awaiting IRQ");\r
+       \r
+       FDD_WaitIRQ();\r
+       FDD_SensInt(base, NULL, NULL);\r
+       \r
+       LOG("Setting Driver Info");\r
+       outb(base + PORT_DATARATE, 0);  // Set data rate to 500K/s\r
+       FDD_int_SendByte(base, FIX_DRIVE_DATA); // Step and Head Load Times\r
+       FDD_int_SendByte(base, 0xDF);   // Step Rate Time, Head Unload Time (Nibble each)\r
+       FDD_int_SendByte(base, 0x02);   // Head Load Time >> 1\r
+       while(FDD_int_SeekTrack(0, 0, 1) == 0); // set track\r
+       while(FDD_int_SeekTrack(0, 1, 1) == 0); // set track\r
+       \r
+       LOG("Recalibrating Disk");\r
+       FDD_Recalibrate((id<<1)|0);\r
+       FDD_Recalibrate((id<<1)|1);
+\r
+       LEAVE('-');\r
+}\r
+\r
+/**\r
+ * \fn void FDD_int_TimerCallback()\r
+ * \brief Called by timer\r
+ */\r
+void FDD_int_TimerCallback(int arg)\r
+{\r
+       ENTER("iarg", arg);\r
+       if(gFDD_Devices[arg].motorState == 1)\r
+               gFDD_Devices[arg].motorState = 2;\r
+       Time_RemoveTimer(gFDD_Devices[arg].timer);\r
+       gFDD_Devices[arg].timer = -1;\r
+       LEAVE('-');\r
+}\r
+\r
+/**\r
+ * \fn void FDD_int_StartMotor(char disk)\r
+ * \brief Starts FDD Motor\r
+ */\r
+void FDD_int_StartMotor(int disk)\r
+{\r
+       Uint8   state;\r
+       state = inb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT );\r
+       state |= 1 << (4+disk);\r
+       outb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT, state );\r
+       gFDD_Devices[disk].motorState = 1;\r
+       gFDD_Devices[disk].timer = Time_CreateTimer(MOTOR_ON_DELAY, FDD_int_TimerCallback, (void*)disk);\r
+}\r
+\r
+/**\r
+ * \fn void FDD_int_StopMotor(int disk)\r
+ * \brief Stops FDD Motor\r
+ */\r
+void FDD_int_StopMotor(int disk)\r
+{\r
+       Uint8   state;\r
+       state = inb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT );\r
+       state &= ~( 1 << (4+disk) );\r
+       outb( cPORTBASE[ disk>>1 ] + PORT_DIGOUTPUT, state );\r
+    gFDD_Devices[disk].motorState = 0;\r
+}\r
+\r
+/**\r
+ * \fn void ModuleUnload()\r
+ * \brief Prepare the module for removal\r
+ */\r
+void ModuleUnload()\r
+{\r
+       int i;\r
+       FDD_AquireSpinlock();\r
+       for(i=0;i<4;i++) {\r
+               Time_RemoveTimer(gFDD_Devices[i].timer);\r
+               FDD_int_StopMotor(i);\r
+       }\r
+       //IRQ_Clear(6);\r
+}\r
diff --git a/Modules/Storage/Makefile.tpl b/Modules/Storage/Makefile.tpl
new file mode 100644 (file)
index 0000000..80c6d4d
--- /dev/null
@@ -0,0 +1 @@
+-include ../../Makefile.tpl
diff --git a/Modules/UDI/Makefile b/Modules/UDI/Makefile
deleted file mode 100644 (file)
index 4c199f1..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-#
-
-CPPFLAGS = -I./include
-OBJ  = main.o logging.o strmem.o imc.o mem.o buf.o cb.o
-OBJ += meta_mgmt.o meta_gio.o
-OBJ += physio.o physio/meta_bus.o physio/meta_intr.o
-NAME = UDI
-
--include ../Makefile.tpl
diff --git a/Modules/UDI/buf.c b/Modules/UDI/buf.c
deleted file mode 100644 (file)
index 3255911..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * \file buf.c
- * \author John Hodge (thePowersGang)
- */
-#include <acess.h>
-#include <udi.h>
-
-// === EXPORTS ===
-EXPORT(udi_buf_copy);
-EXPORT(udi_buf_write);
-EXPORT(udi_buf_read);
-EXPORT(udi_buf_free);
-
-// === CODE ===
-void udi_buf_copy(
-       udi_buf_copy_call_t *callback,
-       udi_cb_t        *gcb,
-       udi_buf_t       *src_buf,
-       udi_size_t      src_off,
-       udi_size_t      src_len,
-       udi_buf_t       *dst_buf,
-       udi_size_t      dst_off,
-       udi_size_t      dst_len,
-       udi_buf_path_t path_handle
-       )
-{
-       UNIMPLEMENTED();
-}
-
-void udi_buf_write(
-       udi_buf_write_call_t *callback,
-       udi_cb_t        *gcb,
-       const void      *src_mem,
-       udi_size_t      src_len,
-       udi_buf_t       *dst_buf,
-       udi_size_t      dst_off,
-       udi_size_t      dst_len,
-       udi_buf_path_t path_handle
-       )
-{
-       UNIMPLEMENTED();
-}
-
-void udi_buf_read(
-       udi_buf_t       *src_buf,
-       udi_size_t      src_off,
-       udi_size_t      src_len,
-       void    *dst_mem )
-{
-       UNIMPLEMENTED();
-}
-
-void udi_buf_free(udi_buf_t *buf)
-{
-       UNIMPLEMENTED();
-}
diff --git a/Modules/UDI/cb.c b/Modules/UDI/cb.c
deleted file mode 100644 (file)
index 78be97b..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * \file cb.c
- * \author John Hodge (thePowersGang)
- */
-#include <acess.h>
-#include <udi.h>
-
-// === EXPORTS ===
-EXPORT(udi_cb_alloc);
-EXPORT(udi_cb_alloc_dynamic);
-EXPORT(udi_cb_alloc_batch);
-EXPORT(udi_cb_free);
-EXPORT(udi_cancel);
-
-// === CODE ===
-void udi_cb_alloc (
-       udi_cb_alloc_call_t *callback,
-       udi_cb_t *gcb,
-       udi_index_t cb_idx,
-       udi_channel_t default_channel
-       )
-{
-       UNIMPLEMENTED();
-}
-
-void udi_cb_alloc_dynamic(
-       udi_cb_alloc_call_t     *callback,
-       udi_cb_t        *gcb,
-       udi_index_t     cb_idx,
-       udi_channel_t   default_channel,
-       udi_size_t      inline_size,
-       udi_layout_t    *inline_layout
-       )
-{
-       UNIMPLEMENTED();
-}
-
-void udi_cb_alloc_batch(
-       udi_cb_alloc_batch_call_t       *callback,
-       udi_cb_t        *gcb,
-       udi_index_t     cb_idx,
-       udi_index_t     count,
-       udi_boolean_t   with_buf,
-       udi_size_t      buf_size,
-       udi_buf_path_t  path_handle
-       )
-{
-       UNIMPLEMENTED();
-}
-
-void udi_cb_free(udi_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_cancel(udi_cancel_call_t *callback, udi_cb_t *gcb)
-{
-       UNIMPLEMENTED();
-}
diff --git a/Modules/UDI/imc.c b/Modules/UDI/imc.c
deleted file mode 100644 (file)
index cd15e07..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * \file imc.c
- * \author John Hodge (thePowersGang)
- */
-#include <acess.h>
-#include <udi.h>
-
-// === EXPORTS ===
-EXPORT(udi_channel_anchor);
-EXPORT(udi_channel_spawn);
-EXPORT(udi_channel_set_context);
-EXPORT(udi_channel_op_abort);
-EXPORT(udi_channel_close);
-EXPORT(udi_channel_event_ind);
-EXPORT(udi_channel_event_complete);
-
-// === CODE ===
-/**
- */
-void udi_channel_anchor(
-       udi_channel_anchor_call_t *callback, udi_cb_t *gcb,
-       udi_channel_t channel, udi_index_t ops_idx, void *channel_context
-       )
-{
-       Warning("%s Unimplemented", __func__);
-}
-
-/**
- */
-extern void udi_channel_spawn(
-       udi_channel_spawn_call_t *callback, udi_cb_t *gcb,
-       udi_channel_t channel, udi_index_t spawn_idx,
-       udi_index_t ops_idx, void *channel_context
-       )
-{
-       Warning("%s Unimplemented", __func__);
-}
-
-/**
- * 
- */
-void udi_channel_set_context(
-       udi_channel_t target_channel, void *channel_context
-       )
-{
-       Warning("%s Unimplemented", __func__);
-}
-
-void udi_channel_op_abort(
-       udi_channel_t target_channel, udi_cb_t *orig_cb
-       )
-{
-       Warning("%s Unimplemented", __func__);
-}
-
-void udi_channel_close(udi_channel_t channel)
-{
-       Warning("%s Unimplemented", __func__);
-}
-
-void udi_channel_event_ind(udi_channel_event_cb_t *cb)
-{
-       udi_channel_event_complete(cb, UDI_OK);
-}
-
-void udi_channel_event_complete(udi_channel_event_cb_t *cb, udi_status_t status)
-{
-       Warning("%s Unimplemented", __func__);
-}
diff --git a/Modules/UDI/include/physio/meta_bus.h b/Modules/UDI/include/physio/meta_bus.h
deleted file mode 100644 (file)
index 7b88ece..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * \file physio/meta_bus.h
- */
-#ifndef _PHYSIO_META_BUS_H_
-#define _PHYSIO_META_BUS_H_
-
-#include <udi.h>
-#include <udi_physio.h>
-
-typedef const struct udi_bus_device_ops_s      udi_bus_device_ops_t;
-typedef const struct udi_bus_bridge_ops_s      udi_bus_bridge_ops_t;
-typedef struct udi_bus_bind_cb_s       udi_bus_bind_cb_t;
-typedef void   udi_bus_unbind_req_op_t(udi_bus_bind_cb_t *cb);
-typedef void   udi_bus_unbind_ack_op_t(udi_bus_bind_cb_t *cb);
-typedef void   udi_bus_bind_req_op_t(udi_bus_bind_cb_t *cb);
-typedef void   udi_bus_bind_ack_op_t(
-       udi_bus_bind_cb_t       *cb,
-       udi_dma_constraints_t   dma_constraints,
-       udi_ubit8_t     preferred_endianness,
-       udi_status_t    status
-       );
-
-
-struct udi_bus_device_ops_s
-{
-       udi_channel_event_ind_op_t      *channel_event_ind_op;
-       udi_bus_bind_ack_op_t   *bus_bind_ack_op;
-       udi_bus_unbind_ack_op_t *bus_unbind_ack_op;
-       udi_intr_attach_ack_op_t        *intr_attach_ack_op;
-       udi_intr_detach_ack_op_t        *intr_detach_ack_op;
-};
-/* Bus Device Ops Vector Number */
-#define UDI_BUS_DEVICE_OPS_NUM            1
-
-struct udi_bus_bridge_ops_s
-{
-     udi_channel_event_ind_op_t        *channel_event_ind_op;
-     udi_bus_bind_req_op_t     *bus_bind_req_op;
-     udi_bus_unbind_req_op_t   *bus_unbind_req_op;
-     udi_intr_attach_req_op_t  *intr_attach_req_op;
-     udi_intr_detach_req_op_t  *intr_detach_req_op;
-};
-/* Bus Bridge Ops Vector Number */
-#define UDI_BUS_BRIDGE_OPS_NUM
-
-struct udi_bus_bind_cb_s
-{
-     udi_cb_t gcb;
-};
-/* Bus Bind Control Block Group Number */
-#define UDI_BUS_BIND_CB_NUM              1
-
-
-extern void udi_bus_bind_req(udi_bus_bind_cb_t *cb);
-
-extern void udi_bus_bind_ack(
-       udi_bus_bind_cb_t       *cb,
-       udi_dma_constraints_t   dma_constraints,
-       udi_ubit8_t     preferred_endianness,
-       udi_status_t    status
-       );
-/* Values for preferred_endianness */
-#define UDI_DMA_BIG_ENDIAN                (1U<<5)
-#define UDI_DMA_LITTLE_ENDIAN             (1U<<6)
-#define UDI_DMA_ANY_ENDIAN                (1U<<0)
-
-extern void udi_bus_unbind_req(udi_bus_bind_cb_t *cb);
-extern void udi_bus_unbind_ack(udi_bus_bind_cb_t *cb);
-
-
-
-
-
-#endif
diff --git a/Modules/UDI/include/physio/meta_intr.h b/Modules/UDI/include/physio/meta_intr.h
deleted file mode 100644 (file)
index d5dd394..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * \file physio/meta_intr.h
- */
-#ifndef _PHYSIO_META_INTR_H_
-#define _PHYSIO_META_INTR_H_
-
-#include <udi.h>
-#include <udi_physio.h>
-#include "pio.h"
-
-typedef struct udi_intr_attach_cb_s    udi_intr_attach_cb_t;
-typedef void   udi_intr_attach_req_op_t(udi_intr_attach_cb_t *intr_attach_cb);
-typedef void   udi_intr_attach_ack_op_t(
-       udi_intr_attach_cb_t *intr_attach_cb,
-       udi_status_t status
-       );
-typedef struct udi_intr_detach_cb_s    udi_intr_detach_cb_t;
-typedef void   udi_intr_detach_req_op_t(udi_intr_detach_cb_t *intr_detach_cb);
-typedef void   udi_intr_detach_ack_op_t(udi_intr_detach_cb_t *intr_detach_cb);
-typedef const struct udi_intr_handler_ops_s    udi_intr_handler_ops_t;
-typedef const struct udi_intr_dispatcher_ops_s udi_intr_dispatcher_ops_t;
-typedef struct udi_intr_event_cb_s     udi_intr_event_cb_t;
-typedef void   udi_intr_event_ind_op_t(udi_intr_event_cb_t *intr_event_cb, udi_ubit8_t flags);
-typedef void   udi_intr_event_rdy_op_t(udi_intr_event_cb_t *intr_event_cb);
-
-
-struct udi_intr_attach_cb_s
-{
-       udi_cb_t        gcb;
-       udi_index_t     interrupt_idx;
-       udi_ubit8_t     min_event_pend;
-       udi_pio_handle_t        preprocessing_handle;
-};
-/* Bridge Attach Control Block Group Number */
-#define UDI_BUS_INTR_ATTACH_CB_NUM        2
-
-struct udi_intr_detach_cb_s
-{
-       udi_cb_t        gcb;
-       udi_index_t     interrupt_idx;
-};
-/* Bridge Detach Control Block Group Number */
-#define UDI_BUS_INTR_DETACH_CB_NUM       3
-
-struct udi_intr_handler_ops_s
-{
-       udi_channel_event_ind_op_t      *channel_event_ind_op;
-       udi_intr_event_ind_op_t *intr_event_ind_op;
-};
-/* Interrupt Handler Ops Vector Number */
-#define UDI_BUS_INTR_HANDLER_OPS_NUM      3
-
-struct udi_intr_dispatcher_ops_s
-{
-       udi_channel_event_ind_op_t      *channel_event_ind_op;
-       udi_intr_event_rdy_op_t *intr_event_rdy_op;
-};
-/* Interrupt Dispatcher Ops Vector Number */
-#define UDI_BUS_INTR_DISPATCH_OPS_NUM     4
-
-struct udi_intr_event_cb_s
-{
-       udi_cb_t        gcb;
-       udi_buf_t       *event_buf;
-       udi_ubit16_t    intr_result;
-};
-/* Flag values for interrupt handling */
-#define UDI_INTR_UNCLAIMED               (1U<<0)
-#define UDI_INTR_NO_EVENT                (1U<<1)
-/* Bus Interrupt Event Control Block Group Number */
-#define UDI_BUS_INTR_EVENT_CB_NUM        4
-
-
-
-extern void udi_intr_attach_req(udi_intr_attach_cb_t *intr_attach_cb);
-extern void udi_intr_attach_ack(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status);
-extern void udi_intr_attach_ack_unused(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status);
-
-extern void udi_intr_detach_req(udi_intr_detach_cb_t *intr_detach_cb);
-extern void udi_intr_detach_ack(udi_intr_detach_cb_t *intr_detach_cb);
-extern void udi_intr_detach_ack_unused(udi_intr_detach_cb_t *intr_detach_cb);
-
-
-extern void udi_intr_event_ind(udi_intr_event_cb_t *intr_event_cb, udi_ubit8_t flags);
-/**
- * \brief Values for ::udi_intr_event_ind \a flags
- * \{
- */
-#define UDI_INTR_MASKING_NOT_REQUIRED    (1U<<0)
-#define UDI_INTR_OVERRUN_OCCURRED        (1U<<1)
-#define UDI_INTR_PREPROCESSED            (1U<<2)
-/**
- * \}
- */
-
-extern void udi_intr_event_rdy(udi_intr_event_cb_t *intr_event_cb);
-
-
-
-#endif
diff --git a/Modules/UDI/include/physio/pio.h b/Modules/UDI/include/physio/pio.h
deleted file mode 100644 (file)
index 1ce305f..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * \file physio/pio.h
- */
-#ifndef _PHYSIO_PIO_H_
-#define _PHYSIO_PIO_H_
-
-#include <udi.h>
-#include <udi_physio.h>
-
-
-typedef _udi_handle_t  udi_pio_handle_t;
-/* Null handle value for udi_pio_handle_t */
-#define UDI_NULL_PIO_HANDLE    _NULL_HANDLE
-
-#endif
diff --git a/Modules/UDI/include/udi.h b/Modules/UDI/include/udi.h
deleted file mode 100644 (file)
index fa5cac3..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * \file udi.h
- */
-#ifndef _UDI_ARCH_H_
-#define _UDI_ARCH_H_
-
-// Use the core acess file to use the specific size types (plus va_arg)
-#include <acess.h>
-
-typedef Sint8  udi_sbit8_t;    /* signed 8-bit: -2^7..2^7-1 */
-typedef Sint16 udi_sbit16_t;   /* signed 16-bit: -2^15..2^15-1 */
-typedef Sint32 udi_sbit32_t;   /* signed 32-bit: -2^31..2^31-1 */
-typedef Uint8  udi_ubit8_t;    /* unsigned 8-bit: 0..28-1 */
-typedef Uint16 udi_ubit16_t;   /* unsigned 16-bit: 0..216-1 */
-typedef Uint32 udi_ubit32_t;   /* unsigned 32-bit: 0..232-1 */
-
-typedef udi_ubit8_t    udi_boolean_t;  /* 0=False; 1..28-1=True */
-#define FALSE  0
-#define TRUE   1
-
-typedef size_t udi_size_t;     /* buffer size */
-typedef size_t udi_index_t;    /* zero-based index type */
-
-typedef void   *_udi_handle_t;
-#define        _NULL_HANDLE    NULL
-
-/* Channel Handle */
-typedef _udi_handle_t  *udi_channel_t;
-#define UDI_NULL_CHANNEL       _NULL_HANDLE
-
-/**
- * \brief Buffer Path
- */
-typedef _udi_handle_t  udi_buf_path_t;
-#define UDI_NULL_BUF_PATH      _NULL_HANDLE
-
-typedef _udi_handle_t  udi_origin_t;
-#define UDI_NULL_ORIGIN        _NULL_HANDLE
-
-typedef Sint64 udi_timestamp_t;
-
-#define UDI_HANDLE_IS_NULL(handle, handle_type)        (handle == NULL)
-#define UDI_HANDLE_ID(handle, handle_type)     ((Uint32)handle)
-
-/**
- * \name va_arg wrapper
- * \{
- */
-#define UDI_VA_ARG(pvar, type, va_code)        va_arg(pvar,type)
-#define UDI_VA_UBIT8_T
-#define UDI_VA_SBIT8_T
-#define UDI_VA_UBIT16_T
-#define UDI_VA_SBIT16_T
-#define UDI_VA_UBIT32_T
-#define UDI_VA_SBIT32_T
-#define UDI_VA_BOOLEAN_T
-#define UDI_VA_INDEX_T
-#define UDI_VA_SIZE_T
-#define UDI_VA_STATUS_T
-#define UDI_VA_CHANNEL_T
-#define UDI_VA_ORIGIN_T
-#define UDI_VA_POINTER
-/**
- * \}
- */
-
-/**
- * \brief Status Type
- */
-typedef udi_ubit32_t   udi_status_t;
-
-/**
- * \name Values and Flags for udi_status_t
- * \{
- */
-#define UDI_STATUS_CODE_MASK           0x0000FFFF
-#define UDI_STAT_META_SPECIFIC         0x00008000
-#define UDI_SPECIFIC_STATUS_MASK       0x00007FFF
-#define UDI_CORRELATE_OFFSET           16
-#define UDI_CORRELATE_MASK                     0xFFFF0000
-/* Common Status Values */
-#define UDI_OK                                         0
-#define UDI_STAT_NOT_SUPPORTED         1
-#define UDI_STAT_NOT_UNDERSTOOD                2
-#define UDI_STAT_INVALID_STATE         3
-#define UDI_STAT_MISTAKEN_IDENTITY     4
-#define UDI_STAT_ABORTED                       5
-#define UDI_STAT_TIMEOUT                       6
-#define UDI_STAT_BUSY                          7
-#define UDI_STAT_RESOURCE_UNAVAIL      8
-#define UDI_STAT_HW_PROBLEM                    9
-#define UDI_STAT_NOT_RESPONDING                10
-#define UDI_STAT_DATA_UNDERRUN         11
-#define UDI_STAT_DATA_OVERRUN          12
-#define UDI_STAT_DATA_ERROR                    13
-#define UDI_STAT_PARENT_DRV_ERROR      14
-#define UDI_STAT_CANNOT_BIND           15
-#define UDI_STAT_CANNOT_BIND_EXCL      16
-#define UDI_STAT_TOO_MANY_PARENTS      17
-#define UDI_STAT_BAD_PARENT_TYPE       18
-#define UDI_STAT_TERMINATED                    19
-#define UDI_STAT_ATTR_MISMATCH         20
-/**
- * \}
- */
-
-/**
- * \name Data Layout Specifiers
- * \{
- */
-typedef const udi_ubit8_t      udi_layout_t;
-/* Specific-Length Layout Type Codes */
-#define UDI_DL_UBIT8_T                   1
-#define UDI_DL_SBIT8_T                   2
-#define UDI_DL_UBIT16_T                  3
-#define UDI_DL_SBIT16_T                  4
-#define UDI_DL_UBIT32_T                  5
-#define UDI_DL_SBIT32_T                  6
-#define UDI_DL_BOOLEAN_T                 7
-#define UDI_DL_STATUS_T                  8
-/* Abstract Element Layout Type Codes */
-#define UDI_DL_INDEX_T                   20
-/* Opaque Handle Element Layout Type Codes */
-#define UDI_DL_CHANNEL_T                 30
-#define UDI_DL_ORIGIN_T                  32
-/* Indirect Element Layout Type Codes */
-#define UDI_DL_BUF                       40
-#define UDI_DL_CB                        41
-#define UDI_DL_INLINE_UNTYPED            42
-#define UDI_DL_INLINE_DRIVER_TYPED       43
-#define UDI_DL_MOVABLE_UNTYPED           44
-/* Nested Element Layout Type Codes */
-#define UDI_DL_INLINE_TYPED              50
-#define UDI_DL_MOVABLE_TYPED             51
-#define UDI_DL_ARRAY                     52
-#define UDI_DL_END                       0
-/**
- * \}
- */
-
-
-// === INCLUDE SUB-SECTIONS ===
-#include "udi/cb.h"    // Control Blocks
-#include "udi/log.h"   // Logging
-#include "udi/attr.h"  // Attributes
-#include "udi/strmem.h"        // String/Memory
-#include "udi/buf.h"   // Buffers
-#include "udi/mem.h"   // Memory Management
-#include "udi/imc.h"   // Inter-module Communication
-#include "udi/meta_mgmt.h"     // Management Metalanguage
-#include "udi/meta_gio.h"      // General IO Metalanguage
-#include "udi/init.h"  // Init
-
-#endif
diff --git a/Modules/UDI/include/udi/attr.h b/Modules/UDI/include/udi/attr.h
deleted file mode 100644 (file)
index a63ce8a..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * \file udi_attr.h
- */
-#ifndef _UDI_ATTR_H_
-#define _UDI_ATTR_H_
-
-typedef struct udi_instance_attr_list_s        udi_instance_attr_list_t;
-typedef udi_ubit8_t    udi_instance_attr_type_t;
-
-/* Instance attribute limits */
-#define UDI_MAX_ATTR_NAMELEN   32
-#define UDI_MAX_ATTR_SIZE              64
-
-/**
- * \brief Instance Attribute
- */
-struct udi_instance_attr_list_s
-{
-     char      attr_name[UDI_MAX_ATTR_NAMELEN];
-     udi_ubit8_t       attr_value[UDI_MAX_ATTR_SIZE];
-     udi_ubit8_t       attr_length;
-     udi_instance_attr_type_t  attr_type;
-};
-
-
-/**
- * \brief Instance Attribute Types
- * \see ::udi_instance_attr_type_t
- */
-enum
-{
-       UDI_ATTR_NONE,
-       UDI_ATTR_STRING,
-       UDI_ATTR_ARRAY8,
-       UDI_ATTR_UBIT32,
-       UDI_ATTR_BOOLEAN,
-       UDI_ATTR_FILE
-};
-
-
-#endif
diff --git a/Modules/UDI/include/udi/buf.h b/Modules/UDI/include/udi/buf.h
deleted file mode 100644 (file)
index fa2428b..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * \file udi_buf.h
- */
-#ifndef _UDI_BUF_H_
-#define _UDI_BUF_H_
-
-
-typedef struct udi_buf_s       udi_buf_t;
-typedef struct udi_xfer_constraints_s  udi_xfer_constraints_t;
-typedef void udi_buf_copy_call_t(udi_cb_t *gcb, udi_buf_t *new_dst_buf);
-typedef void udi_buf_write_call_t(udi_cb_t *gcb, udi_buf_t *new_dst_buf);
-
-/**
- * \brief Describes a buffer
- * \note Semi-Opaque
- */
-struct udi_buf_s
-{
-       udi_size_t      buf_size;
-       Uint8   Data[]; //!< ENVIRONMENT ONLY
-};
-
-/**
- * \brief 
- */
-struct udi_xfer_constraints_s
-{
-       udi_ubit32_t    udi_xfer_max;
-       udi_ubit32_t    udi_xfer_typical;
-       udi_ubit32_t    udi_xfer_granularity;
-       udi_boolean_t   udi_xfer_one_piece;
-       udi_boolean_t   udi_xfer_exact_size;
-       udi_boolean_t   udi_xfer_no_reorder;
-};
-
-// --- MACROS ---
-/**
- * \brief Allocates a buffer
- */
-#define UDI_BUF_ALLOC(callback, gcb, init_data, size, path_handle) \
-       udi_buf_write(callback, gcb, init_data, size, NULL, 0, 0, path_handle)
-
-/**
- * \brief Inserts data into a buffer
- */
-#define UDI_BUF_INSERT(callback, gcb, new_data, size, dst_buf, dst_off) \
-       udi_buf_write(callback, gcb, new_data, size, dst_buf, dst_off, 0, UDI_NULL_BUF_PATH)
-
-/**
- * \brief Removes data from a buffer (data afterwards will be moved forewards)
- */
-#define UDI_BUF_DELETE(callback, gcb, size, dst_buf, dst_off) \
-       udi_buf_write(callback, gcb, NULL, 0, dst_buf, dst_off, size, UDI_NULL_BUF_PATH)
-
-/**
- * \brief Duplicates \a src_buf
- */
-#define UDI_BUF_DUP(callback, gcb, src_buf, path_handle) \
-       udi_buf_copy(callback, gcb, src_buf, 0, (src_buf)->buf_size, NULL, 0, 0, path_handle)
-
-
-/**
- * \brief Copies data from one buffer to another
- */
-extern void udi_buf_copy(
-       udi_buf_copy_call_t *callback,
-       udi_cb_t        *gcb,
-       udi_buf_t       *src_buf,
-       udi_size_t      src_off,
-       udi_size_t      src_len,
-       udi_buf_t       *dst_buf,
-       udi_size_t      dst_off,
-       udi_size_t      dst_len,
-       udi_buf_path_t path_handle );
-
-/**
- * \brief Copies data from driver space to a buffer
- */
-extern void udi_buf_write(
-       udi_buf_write_call_t *callback,
-       udi_cb_t        *gcb,
-       const void      *src_mem,
-       udi_size_t      src_len,
-       udi_buf_t       *dst_buf,
-       udi_size_t      dst_off,
-       udi_size_t      dst_len,
-       udi_buf_path_t path_handle
-       );
-
-/**
- * \brief Reads data from a buffer into driver space
- */
-extern void udi_buf_read(
-       udi_buf_t       *src_buf,
-       udi_size_t      src_off,
-       udi_size_t      src_len,
-       void    *dst_mem );
-
-/**
- * \brief Frees a buffer
- */
-extern void udi_buf_free(udi_buf_t *buf);
-
-
-#endif
diff --git a/Modules/UDI/include/udi/cb.h b/Modules/UDI/include/udi/cb.h
deleted file mode 100644 (file)
index 76db5c6..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * \file udi_cb.h
- */
-#ifndef _UDI_CB_H_
-#define _UDI_CB_H_
-
-typedef struct udi_cb_s        udi_cb_t;
-typedef void udi_cb_alloc_call_t(udi_cb_t *gcb, udi_cb_t *new_cb);
-typedef void udi_cb_alloc_batch_call_t(udi_cb_t *gcb, udi_cb_t *first_new_cb);
-typedef void udi_cancel_call_t(udi_cb_t *gcb);
-
-#define UDI_GCB(mcb)   (&(mcb)->gcb)
-#define UDI_MCB(gcb, cb_type)  ((cb_type *)(gcb))
-
-/**
- * \brief Describes a generic control block
- * \note Semi-opaque
- */
-struct udi_cb_s
-{
-       /**
-        * \brief Channel associated with the control block
-        */
-       udi_channel_t   channel;
-       /**
-        * \brief Current state
-        * \note Driver changable
-        */
-       void    *context;
-       /**
-        * \brief CB's scratch area
-        */
-       void    *scratch;
-       /**
-        * \brief ???
-        */
-       void    *initiator_context;
-       /**
-        * \brief Request Handle?
-        */
-       udi_origin_t    origin;
-};
-
-extern void udi_cb_alloc (
-       udi_cb_alloc_call_t     *callback,
-       udi_cb_t        *gcb,
-       udi_index_t     cb_idx,
-       udi_channel_t   default_channel
-       );
-
-extern void udi_cb_alloc_dynamic(
-       udi_cb_alloc_call_t     *callback,
-       udi_cb_t        *gcb,
-       udi_index_t     cb_idx,
-       udi_channel_t   default_channel,
-       udi_size_t      inline_size,
-       udi_layout_t    *inline_layout
-       );
-
-extern void udi_cb_alloc_batch(
-       udi_cb_alloc_batch_call_t       *callback,
-       udi_cb_t        *gcb,
-       udi_index_t     cb_idx,
-       udi_index_t     count,
-       udi_boolean_t   with_buf,
-       udi_size_t      buf_size,
-       udi_buf_path_t  path_handle
-       );
-
-extern void udi_cb_free(udi_cb_t *cb);
-
-extern void udi_cancel(udi_cancel_call_t *callback, udi_cb_t *gcb);
-
-
-
-
-#endif
diff --git a/Modules/UDI/include/udi/imc.h b/Modules/UDI/include/udi/imc.h
deleted file mode 100644 (file)
index e5b3f3b..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * \file udi_imc.h
- * \brief Inter-Module Communication
- */
-#ifndef _UDI_IMC_H_
-#define _UDI_IMC_H_
-
-typedef void udi_channel_anchor_call_t(udi_cb_t *gcb, udi_channel_t anchored_channel);
-typedef void udi_channel_spawn_call_t(udi_cb_t *gcb, udi_channel_t new_channel);
-
-typedef struct udi_channel_event_cb_s  udi_channel_event_cb_t;
-
-typedef void udi_channel_event_ind_op_t(udi_channel_event_cb_t *cb);
-
-/**
- * \brief Anchors a channel end to the current region
- */
-extern void udi_channel_anchor(
-       udi_channel_anchor_call_t *callback, udi_cb_t *gcb,
-       udi_channel_t channel, udi_index_t ops_idx, void *channel_context
-       );
-
-/**
- * \brief Created a new channel between two regions
- */
-extern void udi_channel_spawn(
-       udi_channel_spawn_call_t *callback,
-       udi_cb_t *gcb,
-       udi_channel_t channel,
-       udi_index_t spawn_idx,
-       udi_index_t ops_idx,
-       void *channel_context
-       );
-
-/**
- * \brief Attaches a new context pointer to the current channel
- */
-extern void udi_channel_set_context(
-       udi_channel_t target_channel,
-       void *channel_context
-       );
-/**
- * \brief 
- */
-extern void udi_channel_op_abort(
-       udi_channel_t target_channel,
-       udi_cb_t *orig_cb
-       );
-
-/**
- * \brief Closes an open channel
- */
-extern void udi_channel_close(udi_channel_t channel);
-
-/**
- * \brief Describes a channel event
- */
-struct udi_channel_event_cb_s
-{
-       udi_cb_t gcb;
-       udi_ubit8_t event;
-       union {
-               struct {
-                       udi_cb_t *bind_cb;
-               } internal_bound;
-               struct {
-                       udi_cb_t *bind_cb;
-                       udi_ubit8_t parent_ID;
-                       udi_buf_path_t *path_handles;
-               } parent_bound;
-               udi_cb_t *orig_cb;
-       }       params;
-};
-/* Channel event types */
-#define UDI_CHANNEL_CLOSED                0
-#define UDI_CHANNEL_BOUND                 1
-#define UDI_CHANNEL_OP_ABORTED            2
-
-/**
- * \brief Proxy function 
- */
-extern void udi_channel_event_ind(udi_channel_event_cb_t *cb);
-
-/**
- * \brief Called when channel event is completed
- */
-extern void udi_channel_event_complete(
-       udi_channel_event_cb_t *cb, udi_status_t status
-       );
-
-
-#endif
diff --git a/Modules/UDI/include/udi/init.h b/Modules/UDI/include/udi/init.h
deleted file mode 100644 (file)
index f405d03..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-/**
- * \file udi_init.h
- */
-#ifndef _UDI_INIT_H_
-#define _UDI_INIT_H_
-
-typedef struct udi_init_s              udi_init_t;
-typedef struct udi_primary_init_s      udi_primary_init_t;
-typedef struct udi_secondary_init_s    udi_secondary_init_t;
-typedef struct udi_ops_init_s  udi_ops_init_t;
-typedef struct udi_cb_init_s   udi_cb_init_t;
-typedef struct udi_cb_select_s udi_cb_select_t;
-typedef struct udi_gcb_init_s  udi_gcb_init_t;
-
-typedef struct udi_init_context_s      udi_init_context_t;
-typedef struct udi_limits_s            udi_limits_t;
-typedef struct udi_chan_context_s      udi_chan_context_t;
-typedef struct udi_child_chan_context_s        udi_child_chan_context_t;
-
-typedef void   udi_op_t(void);
-typedef udi_op_t * const       udi_ops_vector_t;
-
-/**
- * \brief UDI Initialisation Structure
- * 
- * Defines how to initialise and use a UDI driver
- */
-struct udi_init_s
-{
-       /**
-        * \brief Defines the primary region
-        * \note For secondary modules this must be NULL
-        */
-       udi_primary_init_t      *primary_init_info;
-       
-       /**
-        * \brief Defines all secondary regions
-        * Pointer to a list (so, essentially an array) of ::udi_secondary_init_t
-        * It is terminated by an entry with ::udi_secondary_init_t.region_idx
-        * set to zero.
-        * \note If NULL, it is to be treated as an empty list
-        */
-       udi_secondary_init_t    *secondary_init_list;
-       
-       /**
-        * \brief Channel operations
-        * Pointer to a ::udi_ops_init_t.ops_idx == 0  terminated list that
-        * defines the channel opterations usage for each ops vector implemented
-        * in this module.
-        * \note Must contain at least one entry for each metalanguage used
-        */
-       udi_ops_init_t  *ops_init_list;
-       
-       /**
-        * \brief Control Blocks
-        */
-       udi_cb_init_t   *cb_init_list;
-       
-       /**
-        * \brief Generic Control Blocks
-        */
-       udi_gcb_init_t  *gcb_init_list;
-       
-       /**
-        * \brief Overrides for control blocks
-        * Allows a control block to override the ammount of scratch space it
-        * gets for a specific ops vector.
-        */
-       udi_cb_select_t *cb_select_list;
-};
-
-
-/**
- * \name Flags for ::udi_primary_init_t.mgmt_op_flags
- * \{
- */
-
-/**
- * \brief Tells the environment that this operation may take some time
- * Used as a hint in scheduling tasks
- */
-#define UDI_OP_LONG_EXEC       0x01
-
-/**
- * \}
- */
-
-/**
- * \brief Describes the Primary Region
- * Tells the environment how to set up the driver's primary region.
- */
-struct udi_primary_init_s
-{
-       /**
-        * \brief Management Ops Vector
-        * Pointer to a list of functions for the Management Metalanguage
-        */
-       udi_mgmt_ops_t  *mgmt_ops;
-       
-       /**
-        * \brief Flags for \a mgmt_ops
-        * Each entry in \a mgmt_ops is acommanied by an entry in this array.
-        * Each entry contains the flags that apply to the specified ops vector.
-        * \see UDI_OP_LONG_EXEC
-        */
-       const udi_ubit8_t       *mgmt_op_flags;
-       
-       /**
-        * \brief Scratch space size
-        * Specifies the number of bytes to allocate for each control block
-        * passed by the environment.
-        * \note must not exceed ::UDI_MAX_SCRATCH
-        */
-       udi_size_t      mgmt_scratch_requirement;
-       
-       /**
-        * \todo What is this?
-        */
-       udi_ubit8_t     enumeration_attr_list_length;
-       
-       /**
-        * \brief Size in bytes to allocate to each instance of the primary
-        *        region
-        * Essentially the size of the driver's instance state
-        * \note Must be at least sizeof(udi_init_context_t) and not more
-        *       than UDI_MIN_ALLOC_LIMIT
-        */
-       udi_size_t      rdata_size;
-       
-       /**
-        * \brief Size in bytes to allocate for each call to ::udi_enumerate_req
-        * \note Must not exceed UDI_MIN_ALLOC_LIMIT
-        */
-       udi_size_t      child_data_size;
-       
-       /**
-        * \brief Number of path handles for each parent bound to this driver
-        * \todo What the hell are path handles?
-        */
-       udi_ubit8_t     per_parent_paths;
-};
-
-/**
- * \brief Tells the environment how to create a secondary region
- */
-struct udi_secondary_init_s
-{
-       /**
-        * \brief Region Index
-        * Non-zero driver-dependent index value that identifies the region
-        * \note This corresponds to a "region" declaration in the udiprops.txt
-        *       file.
-        */
-       udi_index_t     region_idx;
-       /**
-        * \brief Number of bytes to allocate
-        * 
-        * \note Again, must be between sizeof(udi_init_context_t) and
-        *       UDI_MIN_ALLOC_LIMIT
-        */
-       udi_size_t      rdata_size;
-};
-
-/**
- * \brief Defines channel endpoints (ways of communicating with the driver)
- * 
- */
-struct udi_ops_init_s
-{
-       /**
-        * \brief ops index number
-        * Used to uniquely this entry
-        * \note If this is zero, it marks the end of the list
-        */
-       udi_index_t     ops_idx;
-       /**
-        * \brief Metalanguage Index
-        * Defines what metalanguage is used
-        */
-       udi_index_t     meta_idx;
-       /**
-        * \brief Metalanguage Operation
-        * Defines what metalanguage operation is used
-        */
-       udi_index_t     meta_ops_num;
-       /**
-        * \brief Size of the context area
-        * \note If non-zero, must be at least 
-        */
-       udi_size_t      chan_context_size;
-       /**
-        * \brief Pointer to the operations
-        * Pointer to a <<meta>>_<<role>>_ops_t structure
-        */
-       udi_ops_vector_t        *ops_vector;
-       /**
-        * \brief Flags for each entry in \a ops_vector
-        */
-       const udi_ubit8_t       *op_flags;
-};
-
-/**
- * \brief Defines control blocks
- * Much the same as ::udi_ops_init_t
- */
-struct udi_cb_init_s
-{
-       udi_index_t     cb_idx;
-       udi_index_t     meta_idx;
-       udi_index_t     meta_cb_num;
-       udi_size_t      scratch_requirement;
-       /**
-        * \brief Size of inline memory
-        */
-       udi_size_t      inline_size;
-       /**
-        * \brief Layout of inline memory
-        */
-       udi_layout_t    *inline_layout;
-};
-
-/**
- * \brief Overrides the scratch size for an operation
- */
-struct udi_cb_select_s
-{
-       udi_index_t     ops_idx;
-       udi_index_t     cb_idx;
-};
-
-/**
- * \brief General Control Blocks
- * These control blocks can only be used as general data storage, not
- * for any channel operations.
- */
-struct udi_gcb_init_s
-{
-       udi_index_t     cb_idx;
-       udi_size_t      scratch_requirement;
-};
-
-
-// ===
-// ===
-/**
- * \brief Environement Imposed Limits
- */
-struct udi_limits_s
-{
-       /**
-        * \brief Maximum legal ammount of memory that can be allocated
-        */
-       udi_size_t      max_legal_alloc;
-       
-       /**
-        * \brief Maximum ammount of guaranteed memory
-        */
-       udi_size_t      max_safe_alloc;
-       /**
-        * \brief Maximum size of the final string from ::udi_trace_write
-        *        or ::udi_log_write
-        */
-       udi_size_t      max_trace_log_formatted_len;
-       /**
-        * \brief Maximum legal size of an instanct attribute value
-        */
-       udi_size_t      max_instance_attr_len;
-       /**
-        * \brief Minumum time difference (in nanoseconds between unique values
-        *        returned by ::udi_time_current
-        */
-       udi_ubit32_t    min_curtime_res;
-       /**
-        * \brief Minimum resolution of timers
-        * \see ::udi_timer_start_repeating, ::udi_timer_start
-        */
-       udi_ubit32_t    min_timer_res;
-} PACKED;
-
-/**
- * \brief Primary Region Context data
- */
-struct udi_init_context_s
-{
-       udi_index_t     region_idx;
-       udi_limits_t    limits;
-};
-
-/**
- * \brief Channel context data
- */
-struct udi_chan_context_s
-{
-       /**
-        * \brief Pointer to the driver instance's initial region data
-        */
-       void    *rdata;
-} PACKED;
-
-/**
- * \brief Child Channel context
- */
-struct udi_child_chan_context_s
-{
-       /**
-        * \brief Pointer to the driver instance's initial region data
-        */
-       void    *rdata;
-       /**
-        * \brief Some sort of unique ID number
-        */
-       udi_ubit32_t    child_ID;
-};
-
-#endif
diff --git a/Modules/UDI/include/udi/log.h b/Modules/UDI/include/udi/log.h
deleted file mode 100644 (file)
index dccb124..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * \file udi_log.h
- */
-#ifndef _UDI_LOG_H_
-#define _UDI_LOG_H_
-
-/**
- * \brief Trace Event
- */
-typedef udi_ubit32_t   udi_trevent_t;
-
-/**
- * \brief Log Callback
- */
-typedef void udi_log_write_call_t(udi_cb_t *gcb, udi_status_t correlated_status);
-
-/**
- * \name Log Severities
- * \brief Values for severity
- * \{
- */
-#define UDI_LOG_DISASTER       1
-#define UDI_LOG_ERROR          2
-#define UDI_LOG_WARNING                3
-#define UDI_LOG_INFORMATION    4
-/**
- * \}
- */
-
-
-#endif
diff --git a/Modules/UDI/include/udi/mem.h b/Modules/UDI/include/udi/mem.h
deleted file mode 100644 (file)
index d29f25e..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * \file udi_mem.h
- */
-#ifndef _UDI_MEM_H_
-#define _UDI_MEM_H_
-
-/**
- * \brief Callback type for ::udi_mem_alloc
- */
-typedef void udi_mem_alloc_call_t(udi_cb_t *gcb, void *new_mem);
-
-/**
- * \brief Allocate memory
- */
-extern void udi_mem_alloc(
-       udi_mem_alloc_call_t *callback,
-       udi_cb_t        *gcb,
-       udi_size_t      size,
-       udi_ubit8_t     flags
-       );
-
-/**
- * \brief Values for ::udi_mem_alloc \a flags
- * \{
- */
-#define UDI_MEM_NOZERO               (1U<<0)   //!< No need to zero the memory
-#define UDI_MEM_MOVABLE              (1U<<1)   //!< Globally accessable memory?
-/**
- * \}
- */
-
-/**
- * \brief Free allocated memory
- */
-extern void udi_mem_free(void *target_mem);
-
-
-#endif
diff --git a/Modules/UDI/include/udi/meta_gio.h b/Modules/UDI/include/udi/meta_gio.h
deleted file mode 100644 (file)
index d1cf86f..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * \file udi_meta_gio.h
- */
-#ifndef _UDI_META_GIO_H_
-#define _UDI_META_GIO_H_
-
-typedef const struct udi_gio_provider_ops_s    udi_gio_provider_ops_t;
-typedef const struct udi_gio_client_ops_s      udi_gio_client_ops_t;
-typedef struct udi_gio_bind_cb_s       udi_gio_bind_cb_t;
-typedef struct udi_gio_xfer_cb_s       udi_gio_xfer_cb_t;
-typedef struct udi_gio_rw_params_s     udi_gio_rw_params_t;
-typedef struct udi_gio_event_cb_s      udi_gio_event_cb_t;
-
-typedef void   udi_gio_bind_req_op_t(udi_gio_bind_cb_t *cb);
-typedef void   udi_gio_unbind_req_op_t(udi_gio_bind_cb_t *cb);
-typedef void   udi_gio_xfer_req_op_t(udi_gio_bind_cb_t *cb);
-typedef void   udi_gio_event_res_op_t(udi_gio_bind_cb_t *cb);
-
-typedef void   udi_gio_bind_ack_op_t(
-       udi_gio_bind_cb_t *cb,
-       udi_ubit32_t    device_size_lo,
-       udi_ubit32_t    device_size_hi,
-       udi_status_t    status
-       );
-typedef void   udi_gio_unbind_ack_op_t(udi_gio_bind_cb_t *cb);
-typedef void   udi_gio_xfer_ack_op_t(udi_gio_bind_cb_t *cb);
-typedef void   udi_gio_xfer_nak_op_t(udi_gio_bind_cb_t *cb, udi_status_t status);
-typedef void   udi_gio_event_ind_op_t(udi_gio_bind_cb_t *cb);
-
-typedef udi_ubit8_t    udi_gio_op_t;
-/* Limit values for udi_gio_op_t */
-#define UDI_GIO_OP_CUSTOM                 16
-#define UDI_GIO_OP_MAX                    64
-/* Direction flag values for op */
-#define UDI_GIO_DIR_READ                  (1U<<6)
-#define UDI_GIO_DIR_WRITE                 (1U<<7)
-/* Standard Operation Codes */
-#define UDI_GIO_OP_READ       UDI_GIO_DIR_READ
-#define UDI_GIO_OP_WRITE      UDI_GIO_DIR_WRITE
-
-
-
-struct udi_gio_provider_ops_s
-{
-       udi_channel_event_ind_op_t      *channel_event_ind_op;
-       udi_gio_bind_req_op_t   *gio_bind_req_op;
-       udi_gio_unbind_req_op_t *gio_unbind_req_op;
-       udi_gio_xfer_req_op_t   *gio_xfer_req_op;
-       udi_gio_event_res_op_t  *gio_event_res_op;
-};
-/* Ops Vector Number */
-#define UDI_GIO_PROVIDER_OPS_NUM          1
-
-struct udi_gio_client_ops_s
-{
-       udi_channel_event_ind_op_t      *channel_event_ind_op;
-       udi_gio_bind_ack_op_t   *gio_bind_ack_op;
-       udi_gio_unbind_ack_op_t *gio_unbind_ack_op;
-       udi_gio_xfer_ack_op_t   *gio_xfer_ack_op;
-       udi_gio_xfer_nak_op_t   *gio_xfer_nak_op;
-       udi_gio_event_ind_op_t  *gio_event_ind_op;
-};
-/* Ops Vector Number */
-#define UDI_GIO_CLIENT_OPS_NUM            2
-
-struct udi_gio_bind_cb_s
-{
-       udi_cb_t        gcb;
-       udi_xfer_constraints_t  xfer_constraints;
-};
-/* Control Block Group Number */
-#define UDI_GIO_BIND_CB_NUM      1
-
-
-struct udi_gio_xfer_cb_s
-{
-       udi_cb_t        gcb;
-       udi_gio_op_t    op;
-       void    *tr_params;
-       udi_buf_t       *data_buf;
-};
-/* Control Block Group Number */
-#define UDI_GIO_XFER_CB_NUM      2
-
-struct udi_gio_rw_params_s
-{
-       udi_ubit32_t offset_lo;
-       udi_ubit32_t offset_hi;
-};
-
-struct udi_gio_event_cb_s
-{
-       udi_cb_t        gcb;
-       udi_ubit8_t     event_code;
-       void    *event_params;
-};
-/* Control Block Group Number */
-#define UDI_GIO_EVENT_CB_NUM     3
-
-
-extern void udi_gio_bind_req(udi_gio_bind_cb_t *cb);
-extern void udi_gio_bind_ack(
-       udi_gio_bind_cb_t       *cb,
-       udi_ubit32_t    device_size_lo,
-       udi_ubit32_t    device_size_hi,
-       udi_status_t    status
-       );
-
-extern void udi_gio_unbind_req(udi_gio_bind_cb_t *cb);
-extern void udi_gio_unbind_ack(udi_gio_bind_cb_t *cb);
-
-extern void udi_gio_xfer_req(udi_gio_xfer_cb_t *cb);
-extern void udi_gio_xfer_ack(udi_gio_xfer_cb_t *cb);
-extern void udi_gio_xfer_nak(udi_gio_xfer_cb_t *cb, udi_status_t status);
-
-extern void udi_gio_event_res(udi_gio_event_cb_t *cb);
-extern void udi_gio_event_ind(udi_gio_event_cb_t *cb);
-extern void udi_gio_event_res_unused(udi_gio_event_cb_t *cb);
-
-#endif
diff --git a/Modules/UDI/include/udi/meta_mgmt.h b/Modules/UDI/include/udi/meta_mgmt.h
deleted file mode 100644 (file)
index 97eccf2..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/**
- * \file udi_meta_mgmt.h
- */
-#ifndef _UDI_META_MGMT_H_
-#define _UDI_META_MGMT_H_
-
-typedef struct udi_mgmt_ops_s  udi_mgmt_ops_t;
-typedef struct udi_mgmt_cb_s   udi_mgmt_cb_t;
-typedef struct udi_usage_cb_s  udi_usage_cb_t;
-typedef struct udi_filter_element_s    udi_filter_element_t;
-typedef struct udi_enumerate_cb_s      udi_enumerate_cb_t;
-
-/**
- * \name Specify Usage
- * \{
- */
-typedef void udi_usage_ind_op_t(udi_usage_cb_t *cb, udi_ubit8_t resource_level);
-/* Values for resource_level */
-#define UDI_RESOURCES_CRITICAL     1
-#define UDI_RESOURCES_LOW          2
-#define UDI_RESOURCES_NORMAL       3
-#define UDI_RESOURCES_PLENTIFUL    4
-/* Proxy */
-extern void    udi_static_usage(udi_usage_cb_t *cb, udi_ubit8_t resource_level);
-/**
- * \}
- */
-
-typedef void udi_usage_res_op_t(udi_usage_cb_t *cb);
-
-/**
- * \name Enumerate this driver
- * \{
- */
-typedef void udi_enumerate_req_op_t(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level);
-/* Values for enumeration_level */
-#define UDI_ENUMERATE_START           1
-#define UDI_ENUMERATE_START_RESCAN    2
-#define UDI_ENUMERATE_NEXT            3
-#define UDI_ENUMERATE_NEW             4
-#define UDI_ENUMERATE_DIRECTED        5
-#define UDI_ENUMERATE_RELEASE         6
-/* Proxy */
-extern void udi_enumerate_no_children(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level);
-/**
- * \}
- */
-
-/**
- * \name Enumeration Acknowlagement
- * \{
- */
-typedef void udi_enumerate_ack_op_t(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_result, udi_index_t ops_idx);
-/* Values for enumeration_result */
-#define UDI_ENUMERATE_OK             0
-#define UDI_ENUMERATE_LEAF           1
-#define UDI_ENUMERATE_DONE           2
-#define UDI_ENUMERATE_RESCAN         3
-#define UDI_ENUMERATE_REMOVED        4
-#define UDI_ENUMERATE_REMOVED_SELF   5
-#define UDI_ENUMERATE_RELEASED       6
-#define UDI_ENUMERATE_FAILED         255
-/**
- * \}
- */
-
-/**
- * \name 
- * \{
- */
-typedef void udi_devmgmt_req_op_t(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID);
-
-typedef void udi_devmgmt_ack_op_t(udi_mgmt_cb_t *cb, udi_ubit8_t flags, udi_status_t status);
-/**
- * \}
- */
-typedef void udi_final_cleanup_req_op_t(udi_mgmt_cb_t *cb);
-typedef void udi_final_cleanup_ack_op_t(udi_mgmt_cb_t *cb);
-
-
-
-
-
-struct udi_mgmt_ops_s
-{
-       udi_usage_ind_op_t      *usage_ind_op;
-       udi_enumerate_req_op_t  *enumerate_req_op;
-       udi_devmgmt_req_op_t    *devmgmt_req_op;
-       udi_final_cleanup_req_op_t      *final_cleanup_req_op;
-};
-
-struct udi_mgmt_cb_s
-{
-       udi_cb_t        gcb;
-};
-
-struct udi_usage_cb_s
-{
-       udi_cb_t        gcb;
-       udi_trevent_t   trace_mask;
-       udi_index_t     meta_idx;
-};
-
-
-struct udi_filter_element_s
-{
-     char      attr_name[UDI_MAX_ATTR_NAMELEN];
-     udi_ubit8_t       attr_min[UDI_MAX_ATTR_SIZE];
-     udi_ubit8_t       attr_min_len;
-     udi_ubit8_t       attr_max[UDI_MAX_ATTR_SIZE];
-     udi_ubit8_t       attr_max_len;
-     udi_instance_attr_type_t  attr_type;
-     udi_ubit32_t      attr_stride;
-};
-struct udi_enumerate_cb_s
-{
-     udi_cb_t  gcb;
-     udi_ubit32_t      child_ID;
-     void      *child_data;
-     udi_instance_attr_list_t  *attr_list;
-     udi_ubit8_t       attr_valid_length;
-     const udi_filter_element_t        *filter_list;
-     udi_ubit8_t       filter_list_length;
-     udi_ubit8_t       parent_ID;
-};
-/* Special parent_ID filter values */
-#define UDI_ANY_PARENT_ID      0
-
-/**
- * \brief 
- */
-extern void    udi_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID );
-/**
- * \brief Values for ::udi_devmgmt_req \a mgmt_op
- */
-enum eDMGMT
-{
-       UDI_DMGMT_PREPARE_TO_SUSPEND = 1,
-       UDI_DMGMT_SUSPEND,
-       UDI_DMGMT_SHUTDOWN,
-       UDI_DMGMT_PARENT_SUSPENDED,
-       UDI_DMGMT_RESUME,
-       UDI_DMGMT_UNBIND
-};
-
-extern void    udi_devmgmt_ack(udi_mgmt_cb_t *cb, udi_ubit8_t flags, udi_status_t status);
-//!\brief Values for flags
-#define UDI_DMGMT_NONTRANSPARENT       (1U<<0)
-//!\brief Meta-Specific Status Codes
-#define UDI_DMGMT_STAT_ROUTING_CHANGE  (UDI_STAT_META_SPECIFIC|1)
-
-extern void udi_final_cleanup_req(udi_mgmt_cb_t *cb);
-extern void udi_final_cleanup_ack(udi_mgmt_cb_t *cb);
-
-
-#endif
diff --git a/Modules/UDI/include/udi/strmem.h b/Modules/UDI/include/udi/strmem.h
deleted file mode 100644 (file)
index f540a3e..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * \file udi_strmem.h
- */
-#ifndef _UDI_STRMEM_H_
-#define _UDI_STRMEM_H_
-
-/**
- * \brief Gets the length of a C style string
- */
-extern udi_size_t      udi_strlen(const char *s);
-
-/**
- * \brief Appends to a string
- */
-extern char *udi_strcat(char *s1, const char *s2);
-extern char *udi_strncat(char *s1, const char *s2, udi_size_t n);
-
-/**
- * \brief Compares Strings/Memory
- */
-extern udi_sbit8_t udi_strcmp(const char *s1, const char *s2);
-extern udi_sbit8_t udi_strncmp(const char *s1, const char *s2, udi_size_t n);
-extern udi_sbit8_t udi_memcmp(const void *s1, const void *s2, udi_size_t n);
-
-extern char *udi_strcpy(char *s1, const char *s2);
-extern char *udi_strncpy(char *s1, const char *s2, udi_size_t n);
-extern void *udi_memcpy(void *s1, const void *s2, udi_size_t n);
-extern void *udi_memmove(void *s1, const void *s2, udi_size_t n);
-
-extern char *udi_strncpy_rtrim(char *s1, const char *s2, udi_size_t n);
-
-extern char *udi_strchr(const char *s, char c);
-extern char *udi_strrchr(const char *s, char c);
-extern void *udi_memchr (const void *s, udi_ubit8_t c, udi_size_t n);
-
-extern void *udi_memset(void *s, udi_ubit8_t c, udi_size_t n);
-extern udi_ubit32_t udi_strtou32(const char *s, char **endptr, int base);
-
-
-extern udi_size_t udi_snprintf(char *s, udi_size_t max_bytes, const char *format, ...);
-
-
-
-#endif
diff --git a/Modules/UDI/include/udi_physio.h b/Modules/UDI/include/udi_physio.h
deleted file mode 100644 (file)
index 1397b1c..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * \file udi_physio.h
- */
-#ifndef _UDI_PHYSIO_H_
-#define _UDI_PHYSIO_H_
-
-#include <udi.h>
-
-// === TYPEDEFS ===
-// DMA Core
-typedef _udi_handle_t  udi_dma_handle_t;
-#define        UDI_NULL_DMA_HANDLE     _NULL_HANDLE
-typedef Uint64 udi_busaddr64_t;        //!< \note Opaque
-typedef struct udi_scgth_element_32_s  udi_scgth_element_32_t;
-typedef struct udi_scgth_element_64_s  udi_scgth_element_64_t;
-typedef struct udi_scgth_s     udi_scgth_t;
-typedef _udi_handle_t  udi_dma_constraints_t;
-#define UDI_NULL_DMA_CONSTRAINTS       _NULL_HANDLE
-/**
- * \name DMA constraints attributes
- * \{
- */
-typedef udi_ubit8_t udi_dma_constraints_attr_t;
-/* DMA Convenience Attribute Codes */
-#define UDI_DMA_ADDRESSABLE_BITS          100
-#define UDI_DMA_ALIGNMENT_BITS            101
-/* DMA Constraints on the Entire Transfer */
-#define UDI_DMA_DATA_ADDRESSABLE_BITS     110
-#define UDI_DMA_NO_PARTIAL                111
-/* DMA Constraints on the Scatter/Gather  List */
-#define UDI_DMA_SCGTH_MAX_ELEMENTS        120
-#define UDI_DMA_SCGTH_FORMAT              121
-#define UDI_DMA_SCGTH_ENDIANNESS          122
-#define UDI_DMA_SCGTH_ADDRESSABLE_BITS    123
-#define UDI_DMA_SCGTH_MAX_SEGMENTS        124
-/* DMA Constraints on Scatter/Gather Segments */
-#define UDI_DMA_SCGTH_ALIGNMENT_BITS      130
-#define UDI_DMA_SCGTH_MAX_EL_PER_SEG      131
-#define UDI_DMA_SCGTH_PREFIX_BYTES        132
-/* DMA Constraints on Scatter/Gather Elements */
-#define UDI_DMA_ELEMENT_ALIGNMENT_BITS    140
-#define UDI_DMA_ELEMENT_LENGTH_BITS       141
-#define UDI_DMA_ELEMENT_GRANULARITY_BITS 142
-/* DMA Constraints for Special Addressing */
-#define UDI_DMA_ADDR_FIXED_BITS           150
-#define UDI_DMA_ADDR_FIXED_TYPE           151
-#define UDI_DMA_ADDR_FIXED_VALUE_LO       152
-#define UDI_DMA_ADDR_FIXED_VALUE_HI       153
-/* DMA Constraints on DMA Access Behavior */
-#define UDI_DMA_SEQUENTIAL                160
-#define UDI_DMA_SLOP_IN_BITS              161
-#define UDI_DMA_SLOP_OUT_BITS             162
-#define UDI_DMA_SLOP_OUT_EXTRA            163
-#define UDI_DMA_SLOP_BARRIER_BITS         164
-/* Values for UDI_DMA_SCGTH_ENDIANNESS */
-#define UDI_DMA_LITTLE_ENDIAN             (1U<<6)
-#define UDI_DMA_BIG_ENDIAN                (1U<<5)
-/* Values for UDI_DMA_ADDR_FIXED_TYPE */
-#define UDI_DMA_FIXED_ELEMENT             1
-/**
- * \}
- */
-// DMA Constraints Management
-typedef struct udi_dma_constraints_attr_spec_s udi_dma_constraints_attr_spec_t;
-typedef void udi_dma_constraints_attr_set_call_t(
-       udi_cb_t *gcb, udi_dma_constraints_t new_constraints, udi_status_t status
-       );
-typedef        struct udi_dma_limits_s udi_dma_limits_t;
-
-
-// === STRUCTURES ===
-// --- DMA Constraints Management ---
-struct udi_dma_constraints_attr_spec_s
-{
-     udi_dma_constraints_attr_t        attr_type;
-     udi_ubit32_t      attr_value;
-};
-// --- DMA Core ---
-struct udi_dma_limits_s
-{
-     udi_size_t max_legal_contig_alloc;
-     udi_size_t max_safe_contig_alloc;
-     udi_size_t cache_line_size;
-};
-struct udi_scgth_element_32_s
-{
-     udi_ubit32_t      block_busaddr;
-     udi_ubit32_t      block_length;
-};
-struct udi_scgth_element_64_s
-{
-     udi_busaddr64_t   block_busaddr;
-     udi_ubit32_t      block_length;
-     udi_ubit32_t      el_reserved;
-};
-/* Extension Flag */
-#define UDI_SCGTH_EXT                    0x80000000
-struct udi_scgth_s
-{
-     udi_ubit16_t      scgth_num_elements;
-     udi_ubit8_t       scgth_format;
-     udi_boolean_t     scgth_must_swap;
-     union {
-          udi_scgth_element_32_t       *el32p;
-          udi_scgth_element_64_t       *el64p;
-     } scgth_elements;
-     union {
-          udi_scgth_element_32_t       el32;
-          udi_scgth_element_64_t       el64;
-     } scgth_first_segment;
-};
-/* Values for scgth_format */
-#define UDI_SCGTH_32                     (1U<<0)
-#define UDI_SCGTH_64                     (1U<<1)
-#define UDI_SCGTH_DMA_MAPPED             (1U<<6)
-#define UDI_SCGTH_DRIVER_MAPPED          (1U<<7)
-
-
-
-// === FUNCTIONS ===
-// --- DMA Constraints Management ---
-extern void udi_dma_constraints_attr_set(
-       udi_dma_constraints_attr_set_call_t     *callback,
-       udi_cb_t        *gcb,
-       udi_dma_constraints_t   src_constraints,
-       const udi_dma_constraints_attr_spec_t   *attr_list,
-       udi_ubit16_t    list_length,
-       udi_ubit8_t     flags
-       );
-/* Constraints Flags */
-#define UDI_DMA_CONSTRAINTS_COPY (1U<<0)
-
-extern void udi_dma_constraints_attr_reset(
-       udi_dma_constraints_t   constraints,
-       udi_dma_constraints_attr_t      attr_type
-       );
-
-extern void udi_dma_constraints_free(udi_dma_constraints_t constraints);
-
-#include <physio/meta_intr.h>
-#include <physio/meta_bus.h>
-
-
-#endif
diff --git a/Modules/UDI/logging.c b/Modules/UDI/logging.c
deleted file mode 100644 (file)
index 2e58e37..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * \file logging.c
- * \author John Hodge (thePowersGang)
- */
-#include <acess.h>
-#include <udi.h>
-
-// === PROTOTYPES ===
-
-// === CODE ===
-void udi_log_write( udi_log_write_call_t *callback, udi_cb_t *gcb,
-       udi_trevent_t trace_event, udi_ubit8_t severity, udi_index_t meta_idx,
-       udi_status_t original_status, udi_ubit32_t msgnum, ... )
-{
-       Log("UDI Log");
-}
-
-EXPORT(udi_log_write);
diff --git a/Modules/UDI/main.c b/Modules/UDI/main.c
deleted file mode 100644 (file)
index d114bdc..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Acess2 UDI Layer
- */
-#define DEBUG  0
-#define VERSION        ((0<<8)|1)
-#include <acess.h>
-#include <modules.h>
-#include <udi.h>
-
-// === PROTOTYPES ===
- int   UDI_Install(char **Arguments);
- int   UDI_DetectDriver(void *Base);
- int   UDI_LoadDriver(void *Base);
-
-// === GLOBALS ===
-MODULE_DEFINE(0, VERSION, UDI, UDI_Install, NULL, NULL);
-tModuleLoader  gUDI_Loader = {
-       NULL, "UDI", UDI_DetectDriver, UDI_LoadDriver, NULL
-};
-
-// === CODE ===
-/**
- * \fn int UDI_Install(char **Arguments)
- * \brief Stub intialisation routine
- */
-int UDI_Install(char **Arguments)
-{
-       Module_RegisterLoader( &gUDI_Loader );
-       return 1;
-}
-
-/**
- * \brief Detects if a driver should be loaded by the UDI subsystem
- */
-int UDI_DetectDriver(void *Base)
-{
-       if( Binary_FindSymbol(Base, "udi_init_info", NULL) == 0) {
-               return 0;
-       }
-       
-       return 1;
-}
-
-/**
- * \fn int UDI_LoadDriver(void *Base)
- */
-int UDI_LoadDriver(void *Base)
-{
-       udi_init_t      *info;
-       char    *udiprops = NULL;
-        int    udiprops_size = 0;
-        int    i;
-       // int  j;
-       
-       Log("UDI_LoadDriver: (Base=%p)", Base);
-       
-       if( Binary_FindSymbol(Base, "udi_init_info", (Uint*)&info) == 0) {
-               Binary_Unload(Base);
-               return 0;
-       }
-       
-       if( Binary_FindSymbol(Base, "_udiprops", (Uint*)&udiprops) == 0 ) {
-               Warning("[UDI  ] _udiprops is not defined, this is usually bad");
-       }
-       else {
-               Binary_FindSymbol(Base, "_udiprops_size", (Uint*)&udiprops_size);
-               Log("udiprops = %p, udiprops_size = 0x%x", udiprops, udiprops_size);
-       }
-       
-       
-       Log("primary_init_info = %p = {", info->primary_init_info);
-       {
-               Log(" .mgmt_ops = %p = {", info->primary_init_info->mgmt_ops);
-               Log("  .usage_ind_op: %p() - 0x%02x",
-                       info->primary_init_info->mgmt_ops->usage_ind_op,
-                       info->primary_init_info->mgmt_op_flags[0]
-                       );
-               Log("  .enumerate_req_op: %p() - 0x%02x",
-                       info->primary_init_info->mgmt_ops->enumerate_req_op,
-                       info->primary_init_info->mgmt_op_flags[1]
-                       );
-               Log("  .devmgmt_req_op: %p() - 0x%02x",
-                       info->primary_init_info->mgmt_ops->devmgmt_req_op,
-                       info->primary_init_info->mgmt_op_flags[2]
-                       );
-               Log("  .final_cleanup_req_op: %p() - 0x%02x",
-                       info->primary_init_info->mgmt_ops->final_cleanup_req_op,
-                       info->primary_init_info->mgmt_op_flags[3]
-                       );
-               Log(" }");
-               Log(" .mgmt_scratch_requirement = 0x%x", info->primary_init_info->mgmt_scratch_requirement);
-               Log(" .enumeration_attr_list_length = 0x%x", info->primary_init_info->enumeration_attr_list_length);
-               Log(" .rdata_size = 0x%x", info->primary_init_info->rdata_size);
-               Log(" .child_data_size = 0x%x", info->primary_init_info->child_data_size);
-               Log(" .per_parent_paths = 0x%x", info->primary_init_info->per_parent_paths);
-       }
-       Log("}");
-       Log("secondary_init_list = %p", info->secondary_init_list);
-       Log("ops_init_list = %p", info->ops_init_list);
-       
-       for( i = 0; info->ops_init_list[i].ops_idx; i++ )
-       {
-               Log("info->ops_init_list[%i] = {", i);
-               Log(" .ops_idx = 0x%x", info->ops_init_list[i].ops_idx);
-               Log(" .meta_idx = 0x%x", info->ops_init_list[i].meta_idx);
-               Log(" .meta_ops_num = 0x%x", info->ops_init_list[i].meta_ops_num);
-               Log(" .chan_context_size = 0x%x", info->ops_init_list[i].chan_context_size);
-               Log(" .ops_vector = %p", info->ops_init_list[i].ops_vector);
-               Log(" .op_flags = %p", info->ops_init_list[i].op_flags);
-               Log("}");
-       }
-       
-       return 0;
-}
diff --git a/Modules/UDI/mem.c b/Modules/UDI/mem.c
deleted file mode 100644 (file)
index a09d54c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * \file mem.c
- * \author John Hodge (thePowersGang)
- */
-#include <acess.h>
-#include <udi.h>
-
-// === EXPORTS ===
-EXPORT(udi_mem_alloc);
-EXPORT(udi_mem_free);
-
-// === CODE ===
-void udi_mem_alloc(
-       udi_mem_alloc_call_t *callback,
-       udi_cb_t        *gcb,
-       udi_size_t      size,
-       udi_ubit8_t     flags
-       )
-{
-       void    *buf = malloc(size);
-       if(buf)
-       {
-               if( !(flags & UDI_MEM_NOZERO) )
-                       memset(buf, 0, size);
-       }
-       callback(gcb, buf);
-}
-
-void udi_mem_free(void *target_mem)
-{
-       free(target_mem);
-}
diff --git a/Modules/UDI/meta_gio.c b/Modules/UDI/meta_gio.c
deleted file mode 100644 (file)
index 1618c27..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * \file meta_gio.c
- * \author John Hodge (thePowersGang)
- */
-#include <acess.h>
-#include <udi.h>
-
-// === EXPORTS ===
-EXPORT(udi_gio_bind_req);
-EXPORT(udi_gio_bind_ack);
-EXPORT(udi_gio_unbind_req);
-EXPORT(udi_gio_unbind_ack);
-EXPORT(udi_gio_xfer_req);
-EXPORT(udi_gio_xfer_ack);
-EXPORT(udi_gio_xfer_nak);
-EXPORT(udi_gio_event_res);
-EXPORT(udi_gio_event_ind);
-EXPORT(udi_gio_event_res_unused);
-
-// === CODE ===
-void udi_gio_bind_req(udi_gio_bind_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_gio_bind_ack(
-       udi_gio_bind_cb_t       *cb,
-       udi_ubit32_t    device_size_lo,
-       udi_ubit32_t    device_size_hi,
-       udi_status_t    status
-       )
-{
-       UNIMPLEMENTED();
-}
-
-void udi_gio_unbind_req(udi_gio_bind_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_gio_unbind_ack(udi_gio_bind_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_gio_xfer_req(udi_gio_xfer_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_gio_xfer_ack(udi_gio_xfer_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_gio_xfer_nak(udi_gio_xfer_cb_t *cb, udi_status_t status)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_gio_event_res(udi_gio_event_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_gio_event_ind(udi_gio_event_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_gio_event_res_unused(udi_gio_event_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
diff --git a/Modules/UDI/meta_mgmt.c b/Modules/UDI/meta_mgmt.c
deleted file mode 100644 (file)
index 45a02c4..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * \file meta_mgmt.c
- * \author John Hodge (thePowersGang)
- */
-#include <acess.h>
-#include <udi.h>
-
-// === EXPORTS ===
-EXPORT(udi_devmgmt_req);
-EXPORT(udi_devmgmt_ack);
-EXPORT(udi_final_cleanup_req);
-EXPORT(udi_final_cleanup_ack);
-EXPORT(udi_static_usage);
-EXPORT(udi_enumerate_no_children);
-
-// === CODE ===
-void udi_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID )
-{      
-       ENTER("pcb imgmt_op iparent_ID", cb, mgmt_op, parent_ID);
-       LEAVE('-');
-}
-
-void udi_devmgmt_ack(udi_mgmt_cb_t *cb, udi_ubit8_t flags, udi_status_t status)
-{
-       ENTER("pcb xflags istatus", cb, flags, status);
-       LEAVE('-');
-}
-
-void udi_final_cleanup_req(udi_mgmt_cb_t *cb)
-{
-       ENTER("pcb", cb);
-       LEAVE('-');
-}
-
-void udi_final_cleanup_ack(udi_mgmt_cb_t *cb)
-{
-       ENTER("pcb", cb);
-       LEAVE('-');
-}
-
-void udi_static_usage(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_enumerate_no_children(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level)
-{
-       UNIMPLEMENTED();
-}
diff --git a/Modules/UDI/physio.c b/Modules/UDI/physio.c
deleted file mode 100644 (file)
index 881c9f4..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * \file physio.c
- * \author John Hodge (thePowersGang)
- */
-#include <acess.h>
-#include <udi.h>
-#include <udi_physio.h>
-
-// === EXPORTS ===
-EXPORT(udi_dma_constraints_attr_reset);
-EXPORT(udi_dma_constraints_free);
-
-// === CODE ===
-void udi_dma_constraints_attr_reset(
-       udi_dma_constraints_t   constraints,
-       udi_dma_constraints_attr_t      attr_type
-       )
-{
-       UNIMPLEMENTED();
-}
-
-void udi_dma_constraints_free(udi_dma_constraints_t constraints)
-{
-       UNIMPLEMENTED();
-}
diff --git a/Modules/UDI/physio/meta_bus.c b/Modules/UDI/physio/meta_bus.c
deleted file mode 100644 (file)
index e1e6a47..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * \file physio/meta_bus.c
- * \author John Hodge (thePowersGang)
- */
-#include <acess.h>
-#include <udi.h>
-#include <udi_physio.h>
-
-// === EXPORTS ===
-EXPORT(udi_bus_unbind_req);
-EXPORT(udi_bus_unbind_ack);
-EXPORT(udi_bus_bind_req);
-EXPORT(udi_bus_bind_ack);
-
-// === CODE ===
-void udi_bus_unbind_req(udi_bus_bind_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_bus_unbind_ack(udi_bus_bind_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_bus_bind_req(udi_bus_bind_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_bus_bind_ack(
-       udi_bus_bind_cb_t       *cb,
-       udi_dma_constraints_t   dma_constraints,
-       udi_ubit8_t     preferred_endianness,
-       udi_status_t    status
-       )
-{
-       UNIMPLEMENTED();
-}
diff --git a/Modules/UDI/physio/meta_intr.c b/Modules/UDI/physio/meta_intr.c
deleted file mode 100644 (file)
index f4f5096..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * \file physio/meta_intr.c
- * \author John Hodge (thePowersGang)
- */
-#include <acess.h>
-#include <udi.h>
-#include <udi_physio.h>
-
-// === EXPORTS ===
-EXPORT(udi_intr_attach_req);
-EXPORT(udi_intr_attach_ack);
-EXPORT(udi_intr_attach_ack_unused);
-EXPORT(udi_intr_detach_req);
-EXPORT(udi_intr_detach_ack);
-EXPORT(udi_intr_detach_ack_unused);
-EXPORT(udi_intr_event_ind);
-
-// === CODE ===
-void udi_intr_attach_req(udi_intr_attach_cb_t *intr_attach_cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_intr_attach_ack(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status)
-{
-       UNIMPLEMENTED();
-}
-void udi_intr_attach_ack_unused(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_intr_detach_req(udi_intr_detach_cb_t *intr_detach_cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_intr_detach_ack(udi_intr_detach_cb_t *intr_detach_cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_intr_detach_ack_unused(udi_intr_detach_cb_t *intr_detach_cb)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_intr_event_ind(udi_intr_event_cb_t *intr_event_cb, udi_ubit8_t flags)
-{
-       UNIMPLEMENTED();
-}
diff --git a/Modules/UDI/physio_main.c b/Modules/UDI/physio_main.c
deleted file mode 100644 (file)
index f5e7aa0..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * \file logging.c
- * \author John Hodge (thePowersGang)
- */
-#include <common.h>
-#include <udi.h>
-#include <udi_physio.h>
-
-// === CODE ===
-void udi_bus_bind_req(udi_bus_bind_cb_t *cb)
-{
-}
-
-void udi_bus_unbind_req(udi_bus_bind_cb_t *cb)
-{
-}
diff --git a/Modules/UDI/strmem.c b/Modules/UDI/strmem.c
deleted file mode 100644 (file)
index 4ab1e20..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * \file strmem.c
- * \author John Hodge (thePowersGang)
- */
-#include <acess.h>
-#include <udi.h>
-
-// === EXPORTS ===
-EXPORT(udi_snprintf);
-
-// === CODE ===
-udi_size_t udi_snprintf(char *s, udi_size_t max_bytes, const char *format, ...)
-{
-       s[0] = '\0';
-       return 0;
-}
index 0f79469..ddead96 100644 (file)
@@ -22,11 +22,11 @@ tUserInfo   gUserInfo;
  */
 int ValidateUser(char *Username, char *Password)
 {
-       printf("Username: %s\n", Username);
        if(Username == NULL)    return -1;
        if(Password == NULL)    return -1;
        if(strcmp(Username, "root") == 0)       return 0;
        if(strcmp(Username, "tpg") == 0)        return 1;
+       if(strcmp(Username, "gui") == 0)        return 2;
        return -1;
 }
 
@@ -47,6 +47,11 @@ tUserInfo *GetUserInfo(int UID)
        case 1:
                gUserInfo.Home = "/Acess/Users/tpg";
                break;
+       case 2:
+               gUserInfo.UID = 0;      //HACK!
+               gUserInfo.Home = "/Acess/Users/gui";
+               gUserInfo.Shell = "/Acess/Apps/AxWin/1.0/AxWinWM";
+               break;
        default:
                gUserInfo.Home = "/Acess/Users/Guest";
                break;
index 391d5bc..2866dbd 100644 (file)
@@ -57,7 +57,8 @@ int main(int argc, char *argv[])
                        child_argv[0] = uinfo->Shell;
                        // Set Environment
                        setgid(uinfo->GID);
-                       setuid(uid);
+                       //setuid(uid);
+                       setuid(uinfo->UID);
                        
                        execve(uinfo->Shell, child_argv, child_envp);
                        exit(-1);
index 2fc460b..8397d18 100644 (file)
@@ -10,7 +10,8 @@ enum eDrv_Terminal {
        TERM_IOCTL_MODETYPE = 4,
        TERM_IOCTL_WIDTH,
        TERM_IOCTL_HEIGHT,
-       TERM_IOCTL_QUERYMODE
+       TERM_IOCTL_QUERYMODE,
+       TERM_IOCTL_FORCESHOW
 };
 
 

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