Removed broken dma code
[reactos.git] / reactos / drivers / dd / floppy / floppy.c
index ce6016b..c6eb39e 100644 (file)
@@ -1,31 +1,52 @@
-//
-//  FLOPPY.C - NEC-765/8272A floppy device driver
-//    written by Rex Jolliff
-//    with help from various other sources, including but not limited to:
-//    Art Baker's NT Device Driver Book, Linux Source, and the internet.
-//
-//  Modification History:
-//    08/19/98  RJJ  Created.
-//
-//  To do:
-// FIXME: get it working
-// FIXME: add support for DMA hardware
-// FIXME: should add support for floppy tape/zip devices
+/*
+ *  FLOPPY.C - NEC-765/8272A floppy device driver
+ *   written by Rex Jolliff
+ *    with help from various other sources, including but not limited to:
+ *    Art Baker's NT Device Driver Book, Linux Source, and the internet.
+ *
+ *  Modification History:
+ *    08/19/98  RJJ  Created.
+ *
+ *  To do:
+ * FIXME: get it working
+ * FIXME: add support for DMA hardware
+ * FIXME: should add support for floppy tape/zip devices
+ */
 
 #include <ddk/ntddk.h>
+#include "../../../ntoskrnl/include/internal/i386/io.h"
 
 #include "floppy.h"
 
+#include <debug.h>
+
 #define  VERSION  "V0.0.1"
 
-//  ---------------------------------------------------  File Statics
+/* ---------------------------------------------------  File Statics */
+
+/* from linux drivers/block/floppy.c */
+#define FLOPPY_MAX_REPLIES  (16)
+
+typedef struct _FLOPPY_DEVICE_EXTENSION
+{
+} FLOPPY_DEVICE_EXTENSION, *PFLOPPY_DEVICE_EXTENSION;
 
-typedef struct _FLOPPY_CONTROLLER_PARAMETERS 
+typedef struct _FLOPPY_CONTROLLER_EXTENSION
 {
-  int              PortBase;
-  int              Vector;
-  int              IrqL;
-  int              SynchronizeIrqL;
+   PKINTERRUPT Interrupt;
+   KSPIN_LOCK SpinLock;
+   FLOPPY_CONTROLLER_TYPE FDCType;
+   ULONG Number;
+   ULONG PortBase;
+   ULONG Vector;
+} FLOPPY_CONTROLLER_EXTENSION, *PFLOPPY_CONTROLLER_EXTENSION;
+
+typedef struct _FLOPPY_CONTROLLER_PARAMETERS
+{
+  ULONG              PortBase;
+  ULONG              Vector;
+  ULONG              IrqL;
+  ULONG             SynchronizeIrqL;
   KINTERRUPT_MODE  InterruptMode;
   KAFFINITY        Affinity;
 } FLOPPY_CONTROLLER_PARAMETERS, *PFLOPPY_CONTROLLER_PARAMETERS;
@@ -57,154 +78,198 @@ FLOPPY_DEVICE_PARAMETERS DeviceTypes[] =
 
 static BOOLEAN FloppyInitialized = FALSE;
 
-//  ------------------------------------------------------  Functions
-
-//    ModuleEntry
-//
-//  DESCRIPTION:
-//    This function initializes the driver, locates and claims 
-//    hardware resources, and creates various NT objects needed
-//    to process I/O requests.
-//
-//  RUN LEVEL:
-//    PASSIVE_LEVEL
-//
-//  ARGUMENTS:
-//    IN  PDRIVER_OBJECT   DriverObject  System allocated Driver Object
-//                                       for this driver
-//    IN  PUNICODE_STRING  RegistryPath  Name of registry driver service 
-//                                       key
-//
-//  RETURNS:
-//    NTSTATUS  
-
-NTSTATUS 
-DriverEntry(IN PDRIVER_OBJECT DriverObject, 
-            IN PUNICODE_STRING RegistryPath) 
+/* Bits of main status register */
+#define STATUS_BUSYMASK  (0x0f)
+#define STATUS_BUSY      (0x10)
+#define STATUS_DMA       (0x20)
+#define STATUS_DIR       (0x40)
+#define STATUS_READY     (0x80)
+
+#define FLOPPY_STATUS (4)
+#define FLOPPY_DATA   (5)
+
+#define FLOPPY_CMD_UNLK_FIFO 0x14
+#define FLOPPY_CMD_LOCK_FIFO 0x94
+
+/*  ------------------------------------------------------  Functions */
+
+static int
+FloppyReadSTAT(ULONG PortBase)
+{
+   return(inb_p(PortBase + FLOPPY_STATUS));
+}
+
+/* waits until the fdc becomes ready */
+static int 
+FloppyWaitUntilReady(WORD PortBase)
 {
-  NTSTATUS  RC;
-  PFLOPPY_DEVICE_EXTENSION  DeviceExtension;
-
-  //  Export other driver entry points...
-  DriverObject->DriverStartIo = FloppyStartIo;
-  DriverObject->MajorFunction[IRP_MJ_CREATE] = FloppyDispatchOpenClose;
-  DriverObject->MajorFunction[IRP_MJ_CLOSE] = FloppyDispatchOpenClose;
-  DriverObject->MajorFunction[IRP_MJ_READ] = FloppyDispatchReadWrite;
-  DriverObject->MajorFunction[IRP_MJ_WRITE] = FloppyDispatchReadWrite;
-  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FloppyDispatchDeviceControl;
-
-  //   Try to detect controller and abort if it fails
-  if (!FloppyCreateController(DriverObject, 
-                              &ControllerParameters[0],
-                              0))
+  int Retries;
+  int Status;
+
+  for (Retries = 0; Retries < FLOPPY_MAX_STAT_RETRIES; Retries++) 
+    {
+      Status = FloppyReadSTAT(PortBase);
+      if (Status & STATUS_READY)
+        {
+          return Status;
+        }
+    }
+
+  if (FloppyInitialized) 
     {
-      DPRINT("Could not find floppy controller");
-      return STATUS_NO_SUCH_DEVICE;
+      DPRINT("Getstatus times out (%x) on fdc %d\n",
+             Status, 
+             PortBase);
     }
 
-  return STATUS_SUCCESS;
+  return -1;
 }
 
-static BOOLEAN
-FloppyCreateController(PDRIVER_OBJECT DriverObject,
-                       PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
-                       int Index)
+static VOID
+FloppyWriteData(WORD PortBase, BYTE Byte)
+{
+   outb_p(PortBase + FLOPPY_DATA, Byte);
+}
+
+/* sends a command byte to the fdc */
+static BOOLEAN 
+FloppyWriteCommandByte(WORD PortBase, BYTE Byte)
 {
-  PFLOPPY_CONTROLLER_TYPE ControllerType;
-  PCONTROLLER_OBJECT ControllerObject;
-  PFLOPPY_CONTROLLER_EXTENSION ControllerExtension;
+  int Status;
 
-  /*  Detect controller and determine type  */
-  if (!FloppyGetControllerVersion(ControllerParameters, &ControllerType))
+  if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
     {
       return FALSE;
     }
 
-  // FIXME: Register port ranges and interrupts with HAL
+  if ((Status & (STATUS_READY|STATUS_DIR|STATUS_DMA)) == STATUS_READY)
+    {
+      FloppyWriteData(PortBase, Byte);
+      return 0;
+    }
 
-  /*  Create controller object for FDC  */
-  ControllerObject = IoCreateController(sizeof(FLOPPY_CONTROLLER_EXTENSION));
-  if (ControllerObject == NULL) 
+  if (FloppyInitialized) 
     {
-      DPRINT("Could not create controller object for controller %d\n",
-             Index);
-      return FALSE;
+      DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n",
+             Byte, 
+             PortBase, 
+             Status);
+    }
+
+  return FALSE;
+}
+
+/* gets the response from the fdc */
+static int 
+FloppyReadResultCode(WORD PortBase, PUCHAR Result)
+{
+  int Replies;
+  int Status;
+
+  for (Replies = 0; Replies < FLOPPY_MAX_REPLIES; Replies++) 
+    {
+      if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
+        {
+          break;
+        }
+      Status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA;
+      if ((Status & ~STATUS_BUSY) == STATUS_READY)
+        {
+          return Replies;
+        }
+      if (Status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
+        {
+          Result[Replies] = inb_p(FLOPPY_DATA);
+        }
+      else
+        {
+          break;
+        }
     }
 
-  // FIXME: fill out controller data
-  ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)
-      ControllerObject->ControllerExtension;
-  ControllerExtension->Number = Index;
-  ControllerExtension->PortBase = ControllerParameters->PortBase;
-  ControllerExtension->Vector = ControllerParameters->Vector;
-  ControllerExtension->FDCType = ControllerType;
-
-  /*  Initialize the spin lock in the controller extension  */
-  KeInitializeSpinLock(&ControllerExtension->SpinLock);
-
-  /*  Register an interrupt handler for this controller  */
-  RC = IoConnectInterrupt(&ControllerExtension->Interrupt,
-                          FloppyIsr, 
-                          ControllerExtension, 
-                          &ControllerExtension->SpinLock, 
-                          ControllerExtension->Vector, 
-                          ControllerParameters->IrqL, 
-                          ControllerParameters->SynchronizeIrqL, 
-                          ControllerParameters->InterruptMode, 
-                          FALSE, 
-                          ControllerParameters->Affinity, 
-                          FALSE);
-  if (!NT_SUCCESS(RC)) 
+  if (FloppyInitialized) 
     {
-      DPRINT("Could not Connect Interrupt %d\n", ControllerExtension->Vector);
-      IoDeleteController(ControllerObject);
-      return FALSE;
+      DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
+             PortBase, 
+             Status, 
+             Replies);
     }
 
-  // FIXME: setup DMA stuff for controller
+  return -1;
+}
 
-  //  Check for each possible drive and create devices for them
-  for (DriveIdx = 0; DriveIdx < FLOPPY_MAX_DRIVES; DriveIdx++)
+#define MORE_OUTPUT -2
+/* does the fdc need more output? */
+static int 
+FloppyNeedsMoreOutput(WORD PortBase, PUCHAR Result)
+{
+  int Status;
+
+  if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
+    return -1;
+  if ((Status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY)
     {
-      // FIXME: try to identify the drive
-      // FIXME: create a device if it's there
+      return FLOPPY_NEEDS_OUTPUT;
     }
-    
-  return  STATUS_SUCCESS;
+
+  return FloppyReadResultCode(PortBase, Result);
 }
 
-//    FloppyGetControllerVersion
-//
-//  DESCRIPTION
-//    Get the type/version of the floppy controller
-//
-//  RUN LEVEL:
-//    PASSIVE_LEVEL
-//
-//  ARGUMENTS:
-//    IN OUT  PFLOPPY_DEVICE_EXTENSION  DeviceExtension
-//
-//  RETURNS:
-//    BOOL  success or failure
-//
-//  COMMENTS:
-//    This routine (get_fdc_version) was originally written by David C. Niemi
-//
+static BOOLEAN
+FloppyConfigure(WORD PortBase, BOOLEAN DisableFIFO, BYTE FIFODepth)
+{
+  BYTE Result[FLOPPY_MAX_REPLIES];
+
+  /* Turn on FIFO */
+  FloppyWriteCommandByte(PortBase, FLOPPY_CMD_CFG_FIFO);
+  if (FloppyNeedsMoreOutput(PortBase, Result) != FLOPPY_NEEDS_OUTPUT)
+    {
+      return FALSE;
+    }
+  FloppyWriteCommandByte(PortBase, 0);
+  FloppyWriteCommandByte(PortBase, 
+                         0x10 | 
+                           (DisableFIFO ? 0x20 : 0x00) | 
+                           (FIFODepth & 0x0f));
+  /* pre-compensation from track 0 upwards */
+  FloppyWriteCommandByte(PortBase, 0); 
+
+  return TRUE;
+}       
+
+/*    FloppyGetControllerVersion
+ *
+ *  DESCRIPTION
+ *    Get the type/version of the floppy controller
+ *
+ *  RUN LEVEL:
+ *    PASSIVE_LEVEL
+ *
+ *  ARGUMENTS:
+ *    IN OUT  PFLOPPY_DEVICE_EXTENSION  DeviceExtension
+ *
+ *  RETURNS:
+ *    BOOL  success or failure
+ *
+ *  COMMENTS:
+ *    This routine (get_fdc_version) was originally written by David C. Niemi
+ */
 static BOOLEAN  
 FloppyGetControllerVersion(IN PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
                            OUT PFLOPPY_CONTROLLER_TYPE ControllerType)
 {
-  BYTE ResultReturned
-  BYTE Result[FLOPPY_MAX_REPLIES];
-  int  ResultLength;
+   ULONG ResultLength;
+  UCHAR Result[FLOPPY_MAX_REPLIES];
 
   /* 82072 and better know DUMPREGS */
   if (!FloppyWriteCommandByte(ControllerParameters->PortBase, 
                               FLOPPY_CMD_DUMP_FDC))
     {
-      return FALSE;
+       DPRINT("Failed to write command byte\n");
+       return FALSE;
     }
-  ResultLength = FloppyReadResultCode(PortBase, &Result));
+  ResultLength = FloppyReadResultCode(ControllerParameters->PortBase, 
+                                     Result);
   if (ResultLength < 0)
     {
       return FALSE;
@@ -213,66 +278,69 @@ FloppyGetControllerVersion(IN PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters
   /* 8272a/765 don't know DUMPREGS */
   if ((ResultLength == 1) && (Result[0] == 0x80))
     {
-      DPRINT("FDC %d is an 8272A\n", PortBase);
+      DPRINT("FDC %d is an 8272A\n", ControllerParameters->PortBase);
       *ControllerType = FDC_8272A;       
       return TRUE;
     }
-  if (r != 10) 
+  if (ResultLength != 10) 
     {
       DPRINT("FDC %d init: DUMP_FDC: unexpected return of %d bytes.\n",
-             PortBase, 
+             ControllerParameters->PortBase,
              ResultLength);
       return FALSE;
     }
 
-  if (!FloppyConfigure(PortBase, FALSE, 0x0a)) 
+  if (!FloppyConfigure(ControllerParameters->PortBase, FALSE, 0x0a)) 
     {
-      DPRINT("FDC %d is an 82072\n", PortBase);
+      DPRINT("FDC %d is an 82072\n", ControllerParameters->PortBase);
       *ControllerType = FDC_82072;
       return TRUE;
     }
-  FloppyWriteCommandByte(PortBase, FLOPPY_CMD_PPND_RW);
-  if (FloppyNeedsMoreOutput(PortBase, Result) == FLOPPY_NEEDS_OUTPUT) 
+  FloppyWriteCommandByte(ControllerParameters->PortBase, FLOPPY_CMD_PPND_RW);
+  if (FloppyNeedsMoreOutput(ControllerParameters->PortBase, Result) == 
+      FLOPPY_NEEDS_OUTPUT) 
     {
-      FloppyWriteCommandByte(PortBase, 0);
+      FloppyWriteCommandByte(ControllerParameters->PortBase, 0);
     } 
   else 
     {
-      DPRINT("FDC %d is an 82072A\n", PortBase);
+      DPRINT("FDC %d is an 82072A\n", ControllerParameters->PortBase);
       *ControllerType = FDC_82072A;
       return TRUE;
     }
 
   /* Pre-1991 82077, doesn't know LOCK/UNLOCK */
-  FloppyWriteCommandByte(PortBase, FLOPPY_CMD_UNLK_FIFO);
-  ResultLength = FloppyReadResultCode(PortBase, &Result));
+  FloppyWriteCommandByte(ControllerParameters->PortBase, FLOPPY_CMD_UNLK_FIFO);
+  ResultLength = FloppyReadResultCode(ControllerParameters->PortBase, 
+                                     Result);
   if ((ResultLength == 1) && (Result[0] == 0x80))
     {
-      DPRINT("FDC %d is a pre-1991 82077\n", PortBase);
+      DPRINT("FDC %d is a pre-1991 82077\n", ControllerParameters->PortBase);
       *ControllerType = FDC_82077_ORIG;  
       return TRUE;
     }
   if ((ResultLength != 1) || (Result[0] != 0x00)) 
     {
       DPRINT("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
-             PortBase, 
+             ControllerParameters->PortBase, 
              ResultLength);
       return FALSE;
     }
 
   /* Revised 82077AA passes all the tests */
-  FloppyWriteCommandByte(PortBase, FLOPPY_CMD_PARTID);
-  ResultLength = FloppyReadResultCode(PortBase, &Result));
+  FloppyWriteCommandByte(ControllerParameters->PortBase, FLOPPY_CMD_PARTID);
+  ResultLength = FloppyReadResultCode(ControllerParameters->PortBase, 
+                                     Result);
   if (ResultLength != 1) 
     {
       DPRINT("FDC %d init: PARTID: unexpected return of %d bytes.\n",
-             PortBase, 
+             ControllerParameters->PortBase, 
              ResultLength);
       return FALSE;
     }
   if (Result[0] == 0x80) 
     {
-      DPRINT("FDC %d is a post-1991 82077\n", PortBase);
+      DPRINT("FDC %d is a post-1991 82077\n", ControllerParameters->PortBase);
       *ControllerType = FDC_82077;
       return TRUE;
     }
@@ -280,165 +348,204 @@ FloppyGetControllerVersion(IN PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters
     {
     case 0x0:
       /* Either a 82078-1 or a 82078SL running at 5Volt */
-      DPRINT("FDC %d is an 82078.\n", PortBase);
+      DPRINT("FDC %d is an 82078.\n", ControllerParameters->PortBase);
       *ControllerType = FDC_82078;
       return TRUE;
 
     case 0x1:
-      DPRINT("FDC %d is a 44pin 82078\n", PortBase);
+      DPRINT("FDC %d is a 44pin 82078\n", ControllerParameters->PortBase);
       *ControllerType = FDC_82078;
       return TRUE;
 
     case 0x2:
-      DPRINT("FDC %d is a S82078B\n", PortBase);
+      DPRINT("FDC %d is a S82078B\n", ControllerParameters->PortBase);
       *ControllerType = FDC_S82078B;
       return TRUE;
 
     case 0x3:
-      DPRINT("FDC %d is a National Semiconductor PC87306\n", PortBase);
+      DPRINT("FDC %d is a National Semiconductor PC87306\n", 
+            ControllerParameters->PortBase);
       *ControllerType = FDC_87306;
       return TRUE;
 
     default:
       DPRINT("FDC %d init: 82078 variant with unknown PARTID=%d.\n",
-             PortBase, 
+             ControllerParameters->PortBase, 
              Result[0] >> 5);
       *ControllerType = FDC_82078_UNKN;
       return TRUE;
     }
 }
 
-/* sends a command byte to the fdc */
 static BOOLEAN 
-FloppyWriteCommandByte(WORD PortBase, BYTE Byte)
+FloppyIsr(PKINTERRUPT Interrupt, PVOID ServiceContext)
 {
-  int Status;
-
-  if ((Status = FloppyWaitUntilReady()) < 0)
-    {
-      return FALSE;
-    }
-
-  if ((Status & (STATUS_READY|STATUS_DIR|STATUS_DMA)) == STATUS_READY)
-    {
-      FloppyWriteData(PortBase, Byte);
-      return 0;
-    }
-
-  if (FloppyInitialized) 
-    {
-      DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n",
-             Byte, 
-             PortBase, 
-             Status);
-    }
-
-  return FALSE;
+   return(TRUE);
 }
 
-/* gets the response from the fdc */
-static int 
-FloppyReadResultCode(WORD PortBase, PBYTE Result)
+static BOOLEAN
+FloppyCreateController(PDRIVER_OBJECT DriverObject,
+                       PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
+                       int Index)
 {
-  int Replies;
-  int Status;
-
-  for (Replies = 0; Replies < FLOPPY_MAX_REPLIES; Replies++) 
-    {
-      if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
-        {
-          break;
-        }
-      Status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA;
-      if ((Status & ~STATUS_BUSY) == STATUS_READY)
-        {
-          return Replies;
-        }
-      if (Status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
-        {
-          Result[Replies] = fd_inb(FD_DATA);
-        }
-      else
-        {
-          break;
-        }
-    }
-
-  if (FloppyInitialized) 
-    {
-      DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
-             PortBase, 
-             Status, 
-             Replies);
-    }
-
-  return -1;
+   FLOPPY_CONTROLLER_TYPE ControllerType;
+   PCONTROLLER_OBJECT ControllerObject;
+   PFLOPPY_CONTROLLER_EXTENSION ControllerExtension;
+   UNICODE_STRING DeviceName;   
+   UNICODE_STRING SymlinkName;
+   NTSTATUS Status;
+   PDEVICE_OBJECT DeviceObject;
+   
+   /*  Detect controller and determine type  */
+   if (!FloppyGetControllerVersion(ControllerParameters, &ControllerType))
+     {
+       DPRINT("Failed to get controller version\n");
+       return FALSE;
+     }
+   
+   /* FIXME: Register port ranges and interrupts with HAL */
+
+   /*  Create controller object for FDC  */
+   ControllerObject = IoCreateController(sizeof(FLOPPY_CONTROLLER_EXTENSION));
+   if (ControllerObject == NULL) 
+     {
+       DPRINT("Could not create controller object for controller %d\n",
+              Index);
+       return FALSE;
+     }
+   
+   /* FIXME: fill out controller data */
+   ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)
+     ControllerObject->ControllerExtension;
+   ControllerExtension->Number = Index;
+   ControllerExtension->PortBase = ControllerParameters->PortBase;
+   ControllerExtension->Vector = ControllerParameters->Vector;
+   ControllerExtension->FDCType = ControllerType;
+
+   /*  Initialize the spin lock in the controller extension  */
+   KeInitializeSpinLock(&ControllerExtension->SpinLock);
+   
+   /*  Register an interrupt handler for this controller  */
+   Status = IoConnectInterrupt(&ControllerExtension->Interrupt,
+                              FloppyIsr, 
+                              ControllerExtension, 
+                              &ControllerExtension->SpinLock, 
+                              ControllerExtension->Vector, 
+                              ControllerParameters->IrqL, 
+                              ControllerParameters->SynchronizeIrqL, 
+                              ControllerParameters->InterruptMode, 
+                              FALSE, 
+                              ControllerParameters->Affinity, 
+                              FALSE);
+   if (!NT_SUCCESS(Status)) 
+     {
+       DPRINT("Could not Connect Interrupt %d\n", 
+              ControllerExtension->Vector);
+       IoDeleteController(ControllerObject);
+       return FALSE;
+     }
+   
+   /* FIXME: setup DMA stuff for controller */
+   
+#if 0
+   /*  Check for each possible drive and create devices for them */
+   for (DriveIdx = 0; DriveIdx < FLOPPY_MAX_DRIVES; DriveIdx++)
+     {
+       /* FIXME: try to identify the drive */
+       /* FIXME: create a device if it's there */
+     }
+#endif
+    
+   /* FIXME: Let's assume one drive and one controller for the moment */
+   RtlInitUnicodeString(&DeviceName, L"\\Device\\Floppy0");
+   Status = IoCreateDevice(DriverObject,
+                          sizeof(FLOPPY_DEVICE_EXTENSION),
+                          &DeviceName,
+                          FILE_DEVICE_DISK,
+                          FILE_REMOVABLE_MEDIA | FILE_FLOPPY_DISKETTE,
+                          FALSE,
+                          &DeviceObject);
+   if (!NT_SUCCESS(Status))
+     {
+       IoDisconnectInterrupt(ControllerExtension->Interrupt);
+       IoDeleteController(ControllerObject);
+     }
+   
+   /* Initialize the device */
+   DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
+   DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
+   
+   /* Create a symlink */
+   RtlInitUnicodeString(&SymlinkName, L"\\??\\A:");
+   IoCreateSymbolicLink(&SymlinkName, &DeviceName);
+   
+   return  STATUS_SUCCESS;
 }
-
-/* waits until the fdc becomes ready */
-static int 
-FloppyWaitUntilReady(WORD PortBase)
+   
+VOID FloppyStartIo(PDEVICE_OBJECT DeviceObject,
+                  PIRP Irp)
 {
-  int Retries;
-  int Status;
-
-  for (Retries = 0; Retries < FLOPPY_MAX_STAT_RETRIES; Retries++) 
-    {
-      status = FloppyReadSTAT(PortBase);
-      if (Status & STATUS_READY)
-        {
-          return Status;
-        }
-    }
-
-  if (FloppyInitialized) 
-    {
-      DPRINT("Getstatus times out (%x) on fdc %d\n",
-             Status, 
-             PortBase);
-    }
-
-  return -1;
 }
 
-
-#define MORE_OUTPUT -2
-/* does the fdc need more output? */
-static int 
-FloppyNeedsMoreOutput(WORD PortBase, PBYTE Result)
+NTSTATUS FloppyDispatchOpenClose(PDEVICE_OBJECT DeviceObject,
+                                PIRP Irp)
 {
-  int Status;
-
-  if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
-    return -1;
-  if ((Status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY)
-    {
-      return FLOPPY_NEEDS_OUTPUT;
-    }
-
-  return FloppyReadResultCode(PortBase, Result);
+   return(STATUS_UNSUCCESSFUL);
 }
 
-static BOOLEAN
-FloppyConfigure(WORD PortBase, BOOLEAN DisableFIFO, BYTE FIFODepth)
+NTSTATUS FloppyDispatchReadWrite(PDEVICE_OBJECT DeviceObject,
+                                PIRP Irp)
 {
-  BYTE Result[FLOPPY_MAX_REPLIES];
-
-  /* Turn on FIFO */
-  FloppyWriteCommandByte(FLOPPY_CMD_CFG_FIFO);
-  if (FloppyNeedsOutput(PortBase, Result) != FLOPPY_NEEDS_OUTPUT)
-    {
-      return FALSE;
-    }
-  FloppyWriteCommandByte(PortBase, 0);
-  FloppyWriteCommandByte(PortBase, 
-                         0x10 | 
-                           (DisableFIFO ? 0x20 : 0x00) | 
-                           (FIFODepth & 0x0f));
-  /* pre-compensation from track 0 upwards */
-  FloppyWriteCommandByte(PortBase, 0); 
-
-  return TRUE;
-}       
+   return(STATUS_UNSUCCESSFUL);
+}
 
+NTSTATUS FloppyDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
+                                    PIRP Irp)
+{
+   return(STATUS_UNSUCCESSFUL);
+}
 
+/*    ModuleEntry
+ *
+ *  DESCRIPTION:
+ *    This function initializes the driver, locates and claims 
+ *    hardware resources, and creates various NT objects needed
+ *    to process I/O requests.
+ *
+ *  RUN LEVEL:
+ *    PASSIVE_LEVEL
+ *
+ *  ARGUMENTS:
+ *    IN  PDRIVER_OBJECT   DriverObject  System allocated Driver Object
+ *                                       for this driver
+ *    IN  PUNICODE_STRING  RegistryPath  Name of registry driver service 
+ *                                       key
+ *
+ *  RETURNS:
+ *    NTSTATUS  
+ */
+NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject, 
+                            IN PUNICODE_STRING RegistryPath) 
+{
+   DbgPrint("Floppy driver\n");
+   
+   /* Export other driver entry points... */
+   DriverObject->DriverStartIo = FloppyStartIo;
+   DriverObject->MajorFunction[IRP_MJ_CREATE] = FloppyDispatchOpenClose;
+   DriverObject->MajorFunction[IRP_MJ_CLOSE] = FloppyDispatchOpenClose;
+   DriverObject->MajorFunction[IRP_MJ_READ] = FloppyDispatchReadWrite;
+   DriverObject->MajorFunction[IRP_MJ_WRITE] = FloppyDispatchReadWrite;
+   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = 
+     FloppyDispatchDeviceControl;
+   
+   /*  Try to detect controller and abort if it fails */
+   if (!FloppyCreateController(DriverObject, 
+                              &ControllerParameters[0],
+                              0))
+     {
+       DPRINT("Could not find floppy controller\n");
+       return STATUS_NO_SUCH_DEVICE;
+     }     
+   
+   return STATUS_SUCCESS;
+}