Cleaning up FDD driver, removed local cache in favour of iocache.h
authorJohn Hodge <[email protected]>
Mon, 15 Mar 2010 10:50:49 +0000 (18:50 +0800)
committerJohn Hodge <[email protected]>
Mon, 15 Mar 2010 10:50:49 +0000 (18:50 +0800)
Modules/Storage/FDD/fdd.c

index 412f71d..229c66a 100644 (file)
@@ -17,8 +17,6 @@
 #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
@@ -27,7 +25,8 @@
 /**\r
  * \brief Representation of a floppy drive\r
  */\r
-typedef struct {\r
+typedef struct sFloppyDrive\r
+{\r
         int    type;\r
        volatile int    motorState;     //2 - On, 1 - Spinup, 0 - Off\r
         int    track[2];\r
@@ -114,8 +113,8 @@ void        FDD_int_StartMotor(int disk);
 // === 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
+tSpinlock      glFDD;\r
+volatile int   gbFDD_IrqFired = 0;\r
 tDevFS_Driver  gFDD_DriverInfo = {\r
        NULL, "fdd",\r
        {\r
@@ -128,11 +127,6 @@ tDevFS_Driver      gFDD_DriverInfo = {
        .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
@@ -169,7 +163,7 @@ int FDD_Install(char **Arguments)
        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
+       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
@@ -179,23 +173,20 @@ int FDD_Install(char **Arguments)
        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
+       if( cFDD_SIZES[data >> 4] )\r
+       {\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
+       if( cFDD_SIZES[data & 15] )\r
+       {\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
@@ -207,22 +198,16 @@ int FDD_Install(char **Arguments)
  * \fn char *FDD_ReadDir(tVFS_Node *Node, int pos)\r
  * \brief Read Directory\r
  */\r
-char *FDD_ReadDir(tVFS_Node *Node, int pos)\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(Pos >= 2 || Pos < 0) return NULL;\r
        \r
-       if(gFDD_Devices[pos].type == 0)\r
-               return VFS_SKIP;\r
+       if(gFDD_Devices[Pos].type == 0) return VFS_SKIP;\r
        \r
-       name[0] += pos;\r
+       name[0] += Pos;\r
        \r
-       //Return\r
        return strdup(name);\r
 }\r
 \r
@@ -295,9 +280,7 @@ int FDD_IOCtl(tVFS_Node *Node, int ID, void *Data)
 */\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
+        int    ret;\r
        \r
        ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);\r
        \r
@@ -311,78 +294,12 @@ Uint64 FDD_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                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
+       ret = DrvUtil_ReadBlock(Offset, Length, Buffer, FDD_ReadSectors, 512, Node->Inode);\r
+       LEAVE('i', ret);\r
+       return ret;\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
@@ -418,15 +335,16 @@ int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer)
         int    i;\r
         int    lba = SectorAddr;\r
        \r
-       ENTER("idisk Xlba pbuf", disk, lba, buf);\r
+       ENTER("iDisk XSectorAddr pBuffer", disk, SectorAddr, Buffer);\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
+               if( sFDD_SectorCache[i].disk == Disk\r
+                && sFDD_SectorCache[i].sector == lba)\r
+               {\r
                        LOG("Found %i in cache %i", lba, i);\r
                        memcpy(Buffer, sFDD_SectorCache[i].data, 512);\r
                        sFDD_SectorCache[i].timestamp = now();\r
@@ -444,11 +362,12 @@ int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer)
        }\r
        #endif\r
        \r
-       base = cPORTBASE[Disk>>1];\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
+       if(FDD_int_GetDims(gFDD_Devices[Disk].type, lba, &cyl, &head, &sec, &spt) != 1)\r
+       {\r
                LEAVE('i', -1);\r
                return -1;\r
        }\r
@@ -456,30 +375,32 @@ int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer)
        // 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
+       if(gFDD_Devices[Disk].motorState == 0)  FDD_int_StartMotor(Disk);\r
        \r
-       LOG("Wait for Motor Spinup");\r
+       LOG("Wait for the motor to spin up");\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("Cyl=%i, Head=%i, Sector=%i", cyl, head, sec);\r
        LOG("Acquire Spinlock");\r
        \r
        FDD_AquireSpinlock();\r
        \r
        // Seek to track\r
-       outb(base+CALIBRATE_DRIVE, 0);\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
+       while(FDD_int_SeekTrack(Disk, head, (Uint8)cyl) == 0 && i++ < FDD_SEEK_TIMEOUT )\r
+               Threads_Yield();\r
+       if( i > FDD_SEEK_TIMEOUT ) {\r
+               LEAVE('i', 0);\r
+               return 0;\r
+       }\r
        //FDD_SensInt(base, NULL, NULL);        // Wait for IRQ\r
-       \r
+               \r
+       // Read Data from DMA\r
        LOG("Setting DMA for read");\r
-       \r
-       //Read Data from DMA\r
-       DMA_SetChannel(2, 512, 1);      // Read 512 Bytes\r
+       DMA_SetChannel(2, 512, 1);      // Read 512 Bytes from channel 2\r
        \r
        LOG("Sending read command");\r
        \r
@@ -508,35 +429,14 @@ int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer)
        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
+       LOG("Realeasing Spinlock and setting motor to stop");\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
+       // Don't turn the motor off now, wait for a while\r
+       gFDD_Devices[Disk].timer = Time_CreateTimer(MOTOR_OFF_DELAY, FDD_int_StopMotor, (void*)Disk);
 \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
@@ -648,7 +548,7 @@ int FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt)
  */\r
 void FDD_IRQHandler(int Num)\r
 {\r
-    fdd_irq6 = 1;\r
+    gbFDD_IrqFired = 1;\r
 }\r
 \r
 /**\r
@@ -658,8 +558,8 @@ void FDD_IRQHandler(int Num)
 void FDD_WaitIRQ()\r
 {\r
        // Wait for IRQ\r
-       while(!fdd_irq6)        Threads_Yield();\r
-       fdd_irq6 = 0;\r
+       while(!gbFDD_IrqFired)  Threads_Yield();\r
+       gbFDD_IrqFired = 0;\r
 }\r
 \r
 void FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl)\r
@@ -671,30 +571,16 @@ void FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl)
        else    FDD_int_GetByte(base);\r
 }\r
 \r
-void FDD_AquireSpinlock()\r
+inline void FDD_AquireSpinlock()\r
 {\r
-       while(fdd_inUse)\r
-               Threads_Yield();\r
-       fdd_inUse = 1;\r
+       LOCK(&glFDD);\r
 }\r
 \r
 inline void FDD_FreeSpinlock()\r
 {\r
-       fdd_inUse = 0;\r
+       RELEASE(&glFDD)\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

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