Commit in reactos/drivers/storage/floppy on MAIN
floppy.c+106-911.3 -> 1.4
floppy.h+11-71.2 -> 1.3
hardware.c+7-461.3 -> 1.4
hardware.h+11.2 -> 1.3
ioctl.c+8-11.1 -> 1.2
ioctl.h+11.1 -> 1.2
readwrite.c+23-141.7 -> 1.8
+157-159
7 modified files
 - Added arc path support
 - Fixed disk change support
 - Fixed the priority boosts to be saner
 - Fixed some start/stop motor timing bugs
 - Figured out the Real Deal with Model 30 support (I hope...)
 - Cleaned up DMA init a bit
 - Improved return values, freed things on fail, etc
 - General code cleanup

reactos/drivers/storage/floppy
floppy.c 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- floppy.c	11 Mar 2004 23:12:03 -0000	1.3
+++ floppy.c	12 Mar 2004 03:36:32 -0000	1.4
@@ -23,32 +23,21 @@
  * REVISIONS:
  *                  15-Feb-2004 vizzini - Created
  * NOTES:
+ *  - This driver is only designed to work with ISA-bus floppy controllers.  This
+ *    won't work on PCI-based controllers or on anything else with level-sensitive
+ *    interrupts without modification.  I don't think these controllers exist.
  *
  * ---- General to-do items ----
- * TODO: Clean up properly on failed init
- * TODO: Add arc-path support so we can boot from the floppy
- * TODO: Fix all these stupid STATUS_UNSUCCESSFUL return values
- * TODO: Think about IO_NO_INCREMENT
- * TODO: Figure out why CreateClose isn't called any more on XP.  Seems to correspond 
- *       with the driver not being unloadable.  Does it have to do with cleanup?
- * TODO: Consider using the built-in device object pointer in the stack location 
- *       rather than the context area
+ * TODO: Figure out why CreateClose isn't called any more.  Seems to correspond 
+ *       with the driver not being unloadable.
  * TODO: Think about StopDpcQueued -- could be a race; too tired atm to tell
+ * TODO: Clean up drive start/stop responsibilities (currently a mess...)
  *
  * ---- Support for proper media detection ----
  * TODO: Handle MFM flag
  * TODO: Un-hardcode the data rate from various places
  * TODO: Proper media detection (right now we're hardcoded to 1.44)
  * TODO: Media detection based on sector 1
- *
- * ---- Support for normal floppy hardware ----
- * TODO: Support the three primary types of controller
- * TODO: Figure out thinkpad compatibility (I've heard rumors of weirdness with them)
- *
- * ---- Support for non-ISA and/or non-slave-dma controllers, if they exist ----
- * TODO: Find controllers on non-ISA buses
- * TODO: Think about making the interrupt shareable
- * TODO: Support bus-master controllers.  PCI will break ATM.
  */
 
 #include <ntddk.h>
@@ -101,7 +90,7 @@
 
   HwTurnOffMotor(ControllerInfo);
   ControllerInfo->StopDpcQueued = FALSE;
-  KeSetEvent(&ControllerInfo->MotorStoppedEvent, IO_NO_INCREMENT, FALSE);
+  KeSetEvent(&ControllerInfo->MotorStoppedEvent, EVENT_INCREMENT, FALSE);
 }
 
 
@@ -202,7 +191,7 @@
  *     - No state to track, so this routine is easy
  *     - Can be called <= DISPATCH_LEVEL
  *
- * TODO: Figure out why this isn't getting called any more, and remove the ASSERT once that happens
+ * TODO: Figure out why this isn't getting called 
  */
 {
   UNREFERENCED_PARAMETER(DeviceObject);
@@ -212,7 +201,7 @@
   Irp->IoStatus.Status = STATUS_SUCCESS;
   Irp->IoStatus.Information = FILE_OPENED;
 
-  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+  IoCompleteRequest(Irp, IO_DISK_INCREMENT);
 
   return STATUS_SUCCESS;
 }
@@ -225,7 +214,7 @@
  *     DriveInfo: Pointer to the driveinfo struct associated with the targeted drive
  * RETURNS:
  *     STATUS_SUCCESS on successful starting of the process
- *     STATUS_UNSUCCESSFUL if it fails
+ *     STATUS_IO_DEVICE_ERROR if it fails
  * NOTES:
  *     - Sometimes you have to do two recalibrations, particularly if the disk has <80 tracks.
  *     - PAGED_CODE because we wait
@@ -246,13 +235,17 @@
   if(HwSetDataRate(DriveInfo->ControllerInfo, 0) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: Recalibrate: HwSetDataRate failed\n"));
-      return STATUS_UNSUCCESSFUL;
+      StopMotor(DriveInfo->ControllerInfo);
+      return STATUS_IO_DEVICE_ERROR;
     }
 
   /* clear the event just in case the last call forgot */
   KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
 
-  /* sometimes you have to do this twice */
+  /* sometimes you have to do this twice; we'll just do it twice all the time since
+   * we don't know if the people calling this Recalibrate routine expect a disk to
+   * even be in the drive, and if so, if that disk is formatted.
+   */
   for(i = 0; i < 2; i++)
     {
       /* Send the command */
@@ -312,10 +305,14 @@
   /* clear spurious interrupts in prep for seeks */
   KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
 
+  /* must re-start the drive because Recalibrate() stops it */
+  StartMotor(DriveInfo);
+
   /* Seek to 1 */
   if(HwSeek(DriveInfo, 1) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: ResetChangeFlag(): HwSeek failed; returning STATUS_IO_DEVICE_ERROR\n"));
+      StopMotor(DriveInfo->ControllerInfo);
       return STATUS_IO_DEVICE_ERROR;
     }
 
@@ -324,6 +321,7 @@
   if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: ResetChangeFlag(): HwSenseInterruptStatus failed; bailing out\n"));
+      StopMotor(DriveInfo->ControllerInfo);
       return STATUS_IO_DEVICE_ERROR;
     }
 
@@ -331,6 +329,7 @@
   if(HwSeek(DriveInfo, 1) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: ResetChangeFlag(): HwSeek failed; returning STATUS_IO_DEVICE_ERROR\n"));
+      StopMotor(DriveInfo->ControllerInfo);
       return STATUS_IO_DEVICE_ERROR;
     }
 
@@ -339,6 +338,7 @@
   if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: ResetChangeFlag(): HwSenseInterruptStatus #2 failed; bailing\n"));
+      StopMotor(DriveInfo->ControllerInfo);
       return STATUS_IO_DEVICE_ERROR;
     }
 
@@ -346,9 +346,12 @@
   if(HwDiskChanged(DriveInfo, &DiskChanged) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: ResetChangeFlag(): HwDiskChagned failed; returning STATUS_IO_DEVICE_ERROR\n"));
+      StopMotor(DriveInfo->ControllerInfo);
       return STATUS_IO_DEVICE_ERROR;
     }
 
+  StopMotor(DriveInfo->ControllerInfo);
+
   /* if the change flag is still set, there's probably no media in the drive. */
   if(DiskChanged)
     return STATUS_NO_MEDIA_IN_DEVICE;
@@ -363,8 +366,6 @@
  * FUNCTION: Unload the driver from memory
  * ARGUMENTS:
  *     DriverObject - The driver that is being unloaded
- *
- * TODO: Delete ARC links
  */
 {
   ULONG i,j;
@@ -380,16 +381,24 @@
 
   for(i = 0; i < gNumberOfControllers; i++)
     {
-      if(!gControllerInfo[i].Populated)
+      if(!gControllerInfo[i].Initialized)
 	continue;
 
       for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++)
 	{
+	  if(!gControllerInfo[i].DriveInfo[j].Initialized)
+	    continue;
+
           if(gControllerInfo[i].DriveInfo[j].DeviceObject)
             {
 	      UNICODE_STRING Link;
+
 	      RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].SymLinkBuffer);
 	      IoDeleteSymbolicLink(&Link);
+
+	      RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].ArcPathBuffer);
+	      IoDeassignArcName(&Link);
+
               IoDeleteDevice(gControllerInfo[i].DriveInfo[j].DeviceObject);
             }
 	}
@@ -502,13 +511,9 @@
 	    }
 
           if(AddressSpace == 0)
-	    {
-              gControllerInfo[gNumberOfControllers].BaseAddress = MmMapIoSpace(TranslatedAddress, 8, MmNonCached); // symbolic constant?
-	    }
+              gControllerInfo[gNumberOfControllers].BaseAddress = MmMapIoSpace(TranslatedAddress, FDC_PORT_BYTES, MmNonCached);
           else
-	    {
               gControllerInfo[gNumberOfControllers].BaseAddress = (PUCHAR)TranslatedAddress.u.LowPart;
-	    }
         }
 
       else if(PartialDescriptor->Type == CmResourceTypeDma)
@@ -579,7 +584,6 @@
  *       triggered, this is safe to not do here, as we can just wait for the DPC.
  *     - Either way, we don't want to do this here.  The controller shouldn't interrupt again, so we'll
  *       schedule a DPC to take care of it.
- * TODO:
  *     - This driver really cannot shrare interrupts, as I don't know how to conclusively say 
  *       whether it was our controller that interrupted or not.  I just have to assume that any time
  *       my ISR gets called, it was my board that called it.  Dumb design, yes, but it goes back to 
@@ -640,7 +644,7 @@
 
   KdPrint(("floppy: DpcForIsr called\n"));
 
-  KeSetEvent(&ControllerInfo->SynchEvent, IO_NO_INCREMENT, FALSE);
+  KeSetEvent(&ControllerInfo->SynchEvent, EVENT_INCREMENT, FALSE);
 }
 
 
@@ -651,7 +655,7 @@
  *     ControllerInfo: pointer to the controller to be initialized
  * RETURNS:
  *     STATUS_SUCCESS if the controller is successfully initialized
- *     STATUS_UNSUCCESSFUL otherwise
+ *     STATUS_IO_DEVICE_ERROR otherwise
  */
 {
   int i;
@@ -666,26 +670,22 @@
 
   KeClearEvent(&ControllerInfo->SynchEvent);
 
-  //HwDumpRegisters(ControllerInfo);
-
   KdPrint(("floppy: InitController: resetting the controller\n"));
 
   /* Reset the controller */
   if(HwReset(ControllerInfo) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: InitController: unable to reset controller\n"));
-      return STATUS_UNSUCCESSFUL;
+      return STATUS_IO_DEVICE_ERROR;
     }
 
-  //HwDumpRegisters(ControllerInfo);
-
   KdPrint(("floppy: InitController: setting data rate\n"));
 
   /* Set data rate */
   if(HwSetDataRate(ControllerInfo, DRSR_DSEL_500KBPS) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: InitController: unable to set data rate\n"));
-      return STATUS_UNSUCCESSFUL;
+      return STATUS_IO_DEVICE_ERROR;
     }
 
   KdPrint(("floppy: InitController: waiting for initial interrupt\n"));
@@ -697,27 +697,18 @@
   for(i = 0; i < MAX_DRIVES_PER_CONTROLLER; i++)
     {
       KdPrint(("floppy: InitController: Sensing interrupt %d\n", i));
-      //HwDumpRegisters(ControllerInfo);
 
       if(HwSenseInterruptStatus(ControllerInfo) != STATUS_SUCCESS)
 	{
 	  KdPrint(("floppy: InitController: Unable to clear interrupt 0x%x\n", i));
-	  return STATUS_UNSUCCESSFUL;
+	  return STATUS_IO_DEVICE_ERROR;
 	}
     }
 
   KdPrint(("floppy: InitController: done sensing interrupts\n"));
 
-  //HwDumpRegisters(ControllerInfo);
-
   /* Next, see if we have the right version to do implied seek */
-  if(HwGetVersion(ControllerInfo) != VERSION_ENHANCED)
-    {
-      KdPrint(("floppy: InitController: enhanced version not supported; disabling implied seeks\n"));
-      ControllerInfo->ImpliedSeeks = FALSE;
-      ControllerInfo->Model30 = FALSE;
-    }
-  else
+  if(HwGetVersion(ControllerInfo) == VERSION_ENHANCED)
     {
       /* If so, set that up -- all defaults below except first TRUE for EIS */
       if(HwConfigure(ControllerInfo, TRUE, TRUE, FALSE, 0, 0) != STATUS_SUCCESS)
@@ -731,7 +722,32 @@
           ControllerInfo->ImpliedSeeks = TRUE;
 	}
 
-      ControllerInfo->Model30 = TRUE;
+      /* 
+       * FIXME: Figure out the answer to the below
+       *
+       * I must admit that I'm really confused about the Model 30 issue.  At least one
+       * important bit (the disk change bit in the DIR) is flipped if this is a Model 30
+       * controller.  However, at least one other floppy driver believes that there are only
+       * two computers that are guaranteed to have a Model 30 controller:
+       *  - IBM Thinkpad 750
+       *  - IBM PS2e
+       *
+       * ...and another driver only lists a config option for "thinkpad", that flips
+       * the change line.  A third driver doesn't mention the Model 30 issue at all.
+       *
+       * What I can't tell is whether or not the average, run-of-the-mill computer now has
+       * a Model 30 controller.  For the time being, I'm going to wire this to FALSE,
+       * and just not support the computers mentioned above, while I try to figure out
+       * how ubiquitous these newfangled 30 thingies are.
+       */
+      //ControllerInfo->Model30 = TRUE;
+      ControllerInfo->Model30 = FALSE;
+    }
+  else
+    {
+      KdPrint(("floppy: InitController: enhanced version not supported; disabling implied seeks\n"));
+      ControllerInfo->ImpliedSeeks = FALSE;
+      ControllerInfo->Model30 = FALSE;
     }
   
   /* Specify */
@@ -746,32 +762,25 @@
   if(HwSpecify(ControllerInfo, HeadLoadTime, HeadUnloadTime, StepRateTime, FALSE) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: InitController: unable to specify options\n"));
-      return STATUS_UNSUCCESSFUL;
+      return STATUS_IO_DEVICE_ERROR;
     }
 
-  //HwDumpRegisters(ControllerInfo);
-
   /* Init the stop stuff */
   KeInitializeDpc(&ControllerInfo->MotorStopDpc, MotorStopDpcFunc, ControllerInfo);
   KeInitializeTimer(&ControllerInfo->MotorTimer);
   KeInitializeEvent(&ControllerInfo->MotorStoppedEvent, SynchronizationEvent, FALSE);
   ControllerInfo->StopDpcQueued = FALSE;
 
-  /* Recalibrate each drive on the controller (depends on StartMotor, which depends on the timer stuff above) */
-  /* TODO: Handle failure of one or more drives */
+  /* 
+   * Recalibrate each drive on the controller (depends on StartMotor, which depends on the timer stuff above) 
+   * We don't even know if there is a disk in the drive, so this may not work, but that's OK.
+   */
   for(i = 0; i < ControllerInfo->NumberOfDrives; i++)
     {
       KdPrint(("floppy: InitController: recalibrating drive 0x%x on controller 0x%x\n", i, ControllerInfo));
-
-      if(Recalibrate(&ControllerInfo->DriveInfo[i]) != STATUS_SUCCESS)
-	{
-	  KdPrint(("floppy: InitController: unable to recalibrate drive\n"));
-	  return STATUS_UNSUCCESSFUL;
-	}
+      Recalibrate(&ControllerInfo->DriveInfo[i]);
     }
 
-  //HwDumpRegisters(ControllerInfo);
-
   KdPrint(("floppy: InitController: done initializing; returning STATUS_SUCCESS\n"));
 
   return STATUS_SUCCESS;
@@ -792,11 +801,7 @@
  *       just test a boolean value in the first object to see if it was completely populated.  The same value
  *       is tested for each controller before we build device objects for it.
  * TODO:
- *     - Figure out a workable interrupt-sharing scheme and un-hardcode FALSE in IoConnectInterrupt
- *     - Add support for non-ISA buses, by looping through all of the bus types looking for floppy controllers
  *     - Report resource usage to the HAL
- *     - Add ARC path support
- *     - Think more about error handling; atm most errors abort the start of the driver
  */
 {
   INTERFACE_TYPE InterfaceType = Isa;
@@ -814,7 +819,7 @@
 
   /* 
    * w2k breaks the return val from ConfigCallback, so we have to hack around it, rather than just
-   * looking for a return value from ConfigCallback
+   * looking for a return value from ConfigCallback.  We expect at least one controller.
    */ 
   if(!gControllerInfo[0].Populated)
     {
@@ -826,7 +831,7 @@
   for(i = 0; i < gNumberOfControllers; i++)
     {
       /* 0: Report resource usage to the kernel, to make sure they aren't assigned to anyone else */
-      /* XXX do me baby */
+      /* FIXME: Implement me. */
 
       /* 1: Set up interrupt */
       gControllerInfo[i].MappedVector = HalGetInterruptVector(gControllerInfo[i].InterfaceType, gControllerInfo[i].BusNumber,
@@ -845,26 +850,18 @@
          FALSE, Affinity, 0) != STATUS_SUCCESS)
         {
           KdPrint(("floppy: AddControllers: unable to connect interrupt\n"));
-          return FALSE;
+          continue;
         }
 
       /* 2: Set up DMA */
-
       memset(&DeviceDescription, 0, sizeof(DeviceDescription));
       DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
-      DeviceDescription.Master = (gControllerInfo[i].InterfaceType == PCIBus ? TRUE : FALSE); /* guessing if not pci not master */
       DeviceDescription.DmaChannel = gControllerInfo[i].Dma;
       DeviceDescription.InterfaceType = gControllerInfo[i].InterfaceType;
       DeviceDescription.BusNumber = gControllerInfo[i].BusNumber;
 
-      if(gControllerInfo[i].InterfaceType == PCIBus)
-        {
-          DeviceDescription.Dma32BitAddresses = TRUE;
-          DeviceDescription.DmaWidth = Width32Bits;
-        }
-      else
-	/* DMA 0,1,2,3 are 8-bit; 4,5,6,7 are 16-bit (4 is chain i think) */
-        DeviceDescription.DmaWidth = gControllerInfo[i].Dma > 3 ? Width16Bits: Width8Bits;
+      /* DMA 0,1,2,3 are 8-bit; 4,5,6,7 are 16-bit (4 is chain i think) */
+      DeviceDescription.DmaWidth = gControllerInfo[i].Dma > 3 ? Width16Bits: Width8Bits;
 
       gControllerInfo[i].AdapterObject = HalGetAdapter(&DeviceDescription, &gControllerInfo[i].MapRegisters);
 
@@ -872,23 +869,27 @@
         {
           KdPrint(("floppy: AddControllers: unable to allocate an adapter object\n"));
           IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
-          return FALSE;
+          continue;
         }
 
       /* 2b: Initialize the new controller */
       if(InitController(&gControllerInfo[i]) != STATUS_SUCCESS)
 	{
 	  KdPrint(("floppy: AddControllers():Unable to set up controller %d - initialization failed\n", i));
-	  ASSERT(0); /* FIXME: clean up properly */
+          IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
 	  continue;
 	}
 
+      /* 2c: Set the controller's initlized flag so we know to release stuff in Unload */
+      gControllerInfo[i].Initialized = TRUE;
+
       /* 3: per-drive setup */
       for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++)
         {
           WCHAR DeviceNameBuf[MAX_DEVICE_NAME];
           UNICODE_STRING DeviceName;
           UNICODE_STRING LinkName;
+	  UNICODE_STRING ArcPath;
 	  UCHAR DriveNumber;
 
 	  KdPrint(("floppy: AddControllers(): Configuring drive %d on controller %d\n", i, j));
@@ -917,11 +918,18 @@
             {
               KdPrint(("floppy: AddControllers: unable to register a Device object\n"));
               IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
-              return FALSE;
+              continue; /* continue on to next drive */
             }
 
 	  KdPrint(("floppy: AddControllers: New device: %S (0x%x)\n", DeviceNameBuf, gControllerInfo[i].DriveInfo[j].DeviceObject));
 
+	  /* 3b.5: Create an ARC path in case we're booting from this drive */
+	  swprintf(gControllerInfo[i].DriveInfo[j].ArcPathBuffer,
+		   L"\\ArcName\\multi(%d)disk(%d)fdisk(%d)", gControllerInfo[i].BusNumber, i, DriveNumber);
+
+	  RtlInitUnicodeString(&ArcPath, gControllerInfo[i].DriveInfo[j].ArcPathBuffer);
+	  IoAssignArcName(&ArcPath, &DeviceName);
+
 	  /* 3c: Set flags up */
 	  gControllerInfo[i].DriveInfo[j].DeviceObject->Flags |= DO_DIRECT_IO;
 
@@ -932,8 +940,8 @@
 	    {
 	      KdPrint(("floppy: AddControllers: Unable to create a symlink for drive %d\n", DriveNumber));
 	      IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
-	      // delete devices too?
-	      return FALSE;
+	      IoDeassignArcName(&ArcPath);
+	      continue; /* continue to next drive */
 	    }
 
 	  /* 3e: Set up the DPC */
@@ -947,6 +955,9 @@
 	  /* 3h: set the initial media type to unknown */
 	  memset(&gControllerInfo[i].DriveInfo[j].DiskGeometry, 0, sizeof(DISK_GEOMETRY));
 	  gControllerInfo[i].DriveInfo[j].DiskGeometry.MediaType = Unknown;
+
+	  /* 3i: Now that we're done, set the Initialized flag so we know to free this in Unload */
+	  gControllerInfo[i].DriveInfo[j].Initialized = TRUE;
         }
     }
 
@@ -1131,7 +1142,7 @@
   if(PsCreateSystemThread(&ThreadHandle, 0, 0, 0, 0, QueueThread, 0) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: Unable to create system thread; failing init\n"));
-      return STATUS_UNSUCCESSFUL;
+      return STATUS_INSUFFICIENT_RESOURCES;
     }
 
   if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, NULL, KernelMode, &ThreadObject, NULL) != STATUS_SUCCESS)
@@ -1140,6 +1151,11 @@
       return STATUS_UNSUCCESSFUL;
     }
 
+  /* 
+   * Close the handle, now that we have the object pointer and a reference of our own. 
+   * The handle will certainly not be valid in the context of the caller next time we
+   * need it, as handles are process-specific.
+   */
   ZwClose(ThreadHandle);
 
   /*
@@ -1148,9 +1164,8 @@
   KeInitializeEvent(&QueueThreadTerminate, NotificationEvent, FALSE);
 
   /*
-   * Start the device discovery proces.  In theory, this should return STATUS_SUCCESS if
-   * it finds even one drive attached to one controller.  In practice, the AddControllers
-   * routine doesn't handle all of the errors right just yet.  FIXME.
+   * Start the device discovery proces.  Returns STATUS_SUCCESS if
+   * it finds even one drive attached to one controller. 
    */
   if(!AddControllers(DriverObject))
     return STATUS_NO_SUCH_DEVICE;

reactos/drivers/storage/floppy
floppy.h 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- floppy.h	11 Mar 2004 23:12:03 -0000	1.2
+++ floppy.h	12 Mar 2004 03:36:32 -0000	1.3
@@ -71,12 +71,15 @@
   DISK_GEOMETRY            DiskGeometry;
   UCHAR                    BytesPerSectorCode;
   WCHAR                    SymLinkBuffer[MAX_DEVICE_NAME];
+  WCHAR                    ArcPathBuffer[MAX_ARC_PATH_LEN];
   ULONG                    DiskChangeCount;
+  BOOLEAN                  Initialized;
 } DRIVE_INFO, *PDRIVE_INFO;
 
 typedef struct _CONTROLLER_INFO
 {
   BOOLEAN          Populated;
+  BOOLEAN          Initialized;
   ULONG            ControllerNumber;
   INTERFACE_TYPE   InterfaceType;
   ULONG            BusNumber;
@@ -111,6 +114,14 @@
 VOID NTAPI SignalMediaChanged(PDEVICE_OBJECT DeviceObject,
                               PIRP Irp);
 
+VOID NTAPI WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo);
+
+NTSTATUS NTAPI ResetChangeFlag(PDRIVE_INFO DriveInfo);
+
+VOID NTAPI StartMotor(PDRIVE_INFO DriveInfo);
+
+VOID NTAPI StopMotor(PCONTROLLER_INFO ControllerInfo);
+
 /*
  * MEDIA TYPES
  *
@@ -133,10 +144,3 @@
 #define GEOMETRY_144_SECTORSPERTRACK 18
 #define GEOMETRY_144_BYTESPERSECTOR 512
 
-VOID NTAPI WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo);
-
-NTSTATUS NTAPI ResetChangeFlag(PDRIVE_INFO DriveInfo);
-
-VOID NTAPI StartMotor(PDRIVE_INFO DriveInfo);
-VOID NTAPI StopMotor(PCONTROLLER_INFO ControllerInfo);
-

reactos/drivers/storage/floppy
hardware.c 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- hardware.c	11 Mar 2004 23:12:03 -0000	1.3
+++ hardware.c	12 Mar 2004 03:36:32 -0000	1.4
@@ -41,7 +41,6 @@
  *       thread.  
  *     - Some information taken from Intel 82077AA data sheet (order #290166-007)
  *
- * TODO: Fix all of the stupid STATUS_UNSUCCESSFUL return codes
  * TODO: ATM the constants defined in hardware.h *might* be shifted to line up
  *       with the bit position in the register, or they *might not*.  This should
  *       all be converted to standardize on absolute values or shifts.
@@ -81,21 +80,11 @@
 {
   UCHAR Status = READ_PORT_UCHAR(ControllerInfo->BaseAddress + MAIN_STATUS_REGISTER);
 	
-  PAGED_CODE();
-
   if((Status & MSR_IO_DIRECTION)) /* 0 for out */
-    {
-      //KdPrint(("floppy: ReadyForWrite returning false due to incorrect FIFO direction; Status = 0x%x\n", Status));
-      //HwDumpRegisters(ControllerInfo);
       return FALSE;
-    }
 
   if(!(Status & MSR_DATA_REG_READY_FOR_IO))
-    {
-      //KdPrint(("floppy: ReadyForWrite returning false due to MSR Not ready for I/O; Status = 0x%x\n", Status));
-      //HwDumpRegisters(ControllerInfo);
       return FALSE;
-    }
 
   return TRUE;
 }
@@ -116,21 +105,11 @@
 {
   UCHAR Status = READ_PORT_UCHAR(ControllerInfo->BaseAddress + MAIN_STATUS_REGISTER);
 	
-  PAGED_CODE();
-
   if(!(Status & MSR_IO_DIRECTION)) /* Read = 1 */
-    {
-//      KdPrint(("floppy: ReadyForRead returning FALSE due to incorrect FIFO direction; Status 0x%x\n", Status));
-//      HwDumpRegisters(ControllerInfo);
       return FALSE;
-    }
 
   if(!(Status & MSR_DATA_REG_READY_FOR_IO))
-    {
-//      KdPrint(("floppy: ReadyForRead returning FALSE due to MSR Not ready for I/O\n; Status 0x%x", Status));
-//      HwDumpRegisters(ControllerInfo);
       return FALSE;
-    }
 
   return TRUE;
 }
@@ -157,14 +136,13 @@
  *       maximum.
  *     - This function is necessary because sometimes the FIFO reacts slowly
  *       and isn't yet ready to read or write the next byte
+ * FIXME: time interval here and in Get_Byte
  */
 {
   LARGE_INTEGER StartingTickCount;
   LARGE_INTEGER CurrentTickCount;
   PUCHAR Address;
 
-  //KdPrint(("floppy: Send_Byte called to write 0x%x at offset 0x%x\n", Byte, Offset));
-
   PAGED_CODE();
 
   Address = ControllerInfo->BaseAddress + FIFO;
@@ -193,8 +171,6 @@
 	  ElapsedTicks = CurrentTickCount.QuadPart - StartingTickCount.QuadPart;
 	  TimeUnits = ElapsedTicks * TimeIncrement;
 
-	  //KdPrint(("floppy: Send_Byte: failed to write; elapsed time %d\n", TimeUnits));
-
 	  if(TimeUnits > 25000000)
 	    break;
 
@@ -263,8 +239,6 @@
 	  ElapsedTicks = CurrentTickCount.QuadPart - StartingTickCount.QuadPart;
 	  TimeUnits = ElapsedTicks * TimeIncrement;
 
-	  //KdPrint(("floppy: Get_Byte: failed to read; elapsed time %d\n", TimeUnits));
-
 	  if(TimeUnits > 25000000)
 	    break;
 
@@ -273,8 +247,6 @@
 			
       *Byte = READ_PORT_UCHAR(Address);
 
-      //KdPrint(("floppy: Get_Byte read 0x%x from offset 0x%x\n", *Byte, Offset));
-
       return STATUS_SUCCESS;
     }
 
@@ -334,14 +306,13 @@
  *     STATUS_UNSUCCESSFUL otherwise
  * NOTES:
  *     - Doesn't interrupt
+ *     - Currently cannot fail
  */
 {
   PCONTROLLER_INFO ControllerInfo = DriveInfo->ControllerInfo;
   UCHAR Unit = DriveInfo->UnitNumber;
   UCHAR Buffer;
 
-  //KdPrint(("floppy: HwTurnOnMotor called; setting unit 0x%x to data rate 0x%x\n", Unit, DataRate));
-
   PAGED_CODE();
 
   /* turn on motor */
@@ -435,8 +406,6 @@
 
   PAGED_CODE();
 
-  //KdPrint(("floppy: HwReadWriteData called\n"));
-
   /* Shouldn't be using DataLength in this driver */
   ASSERT(DataLength == 0xff);
 
@@ -469,7 +438,6 @@
 	  }
     }
 
-  //KdPrint(("floppy: HwReadWriteData: returning STATUS_SUCCESS\n"));
   return STATUS_SUCCESS;
 }
 
@@ -487,7 +455,7 @@
  *       whole thing down to a single SUCCESS or FAILURE result
  *     - Called post-interrupt; does not interrupt
  * TODO 
- *     - handle much more status
+ *     - perhaps handle more status
  */
 {
   UCHAR Buffer[2];
@@ -495,8 +463,6 @@
 
   PAGED_CODE();
 
-  //KdPrint(("floppy: HwRecalibrateResult called\n"));
-
   if(Send_Byte(ControllerInfo, COMMAND_SENSE_INTERRUPT_STATUS) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: HwRecalibrateResult: Unable to write the controller\n"));
@@ -552,15 +518,13 @@
  *     - This function tests the error conditions itself, and boils the
  *       whole thing down to a single SUCCESS or FAILURE result
  *     - Called post-interrupt; does not interrupt
- * TODO 
- *     - handle much more status
+ * TODO:
+ *     - perhaps handle more status
  */
 {
   UCHAR Buffer[7];
   int i;
 
-  //KdPrint(("floppy: HwReadWriteResult called\n"));
-
   PAGED_CODE();
 
   for(i = 0; i < 7; i++)
@@ -632,8 +596,6 @@
 
   PAGED_CODE();
 
-  //KdPrint(("floppy: HwSenseInterruptStatus called\n"));
-
   if(Send_Byte(ControllerInfo, COMMAND_SENSE_INTERRUPT_STATUS) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: HwSenseInterruptStatus: failed to write controller\n"));
@@ -885,9 +847,8 @@
     {
       if(!(Buffer & DIR_DISKETTE_CHANGE))
 	{
-	  /* FIXME FIXME FIXME: This is wrong */
 	  KdPrint(("floppy: HdDiskChanged - Model30 - returning TRUE\n"));
-	  *DiskChanged = FALSE;
+	  *DiskChanged = TRUE;
 	}
       else
 	{
@@ -957,7 +918,7 @@
  *       whole thing down to a single SUCCESS or FAILURE result
  *     - Called post-interrupt; does not interrupt
  * TODO 
- *     - handle much more status
+ *     - perhaps handle more status
  */
 {
   UCHAR Buffer[7] = {0,0,0,0,0,0,0};

reactos/drivers/storage/floppy
hardware.h 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- hardware.h	11 Mar 2004 23:12:03 -0000	1.2
+++ hardware.h	12 Mar 2004 03:36:32 -0000	1.3
@@ -35,6 +35,7 @@
  */
 
 #define FLOPPY_DEFAULT_IRQ              0x6
+#define FDC_PORT_BYTES                  0x8
 
 /* Register offsets from base address (usually 0x3f8)  */
 #define STATUS_REGISTER_A               0x0 /* Read; PS/2 Only */

reactos/drivers/storage/floppy
ioctl.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- ioctl.c	1 Mar 2004 06:37:26 -0000	1.1
+++ ioctl.c	12 Mar 2004 03:36:32 -0000	1.2
@@ -135,6 +135,11 @@
     }
 
   /*
+   * Start the drive to see if the disk has changed
+   */
+  StartMotor(DriveInfo);
+
+  /*
    * Check the change line, and if it's set, return
    */
   if(HwDiskChanged(DriveInfo, &DiskChanged) != STATUS_SUCCESS)
@@ -143,6 +148,7 @@
       Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
       Irp->IoStatus.Information = 0;
       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+      StopMotor(DriveInfo->ControllerInfo);
       return;
     }
 
@@ -161,7 +167,7 @@
 	Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
 
       IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+      StopMotor(DriveInfo->ControllerInfo);
       return;
     }
 
@@ -245,6 +251,7 @@
   KdPrint(("floppy: ioctl: completing with status 0x%x\n", Irp->IoStatus.Status));
   IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
+  StopMotor(DriveInfo->ControllerInfo);
   return;
 }
 

reactos/drivers/storage/floppy
ioctl.h 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- ioctl.h	1 Mar 2004 06:37:26 -0000	1.1
+++ ioctl.h	12 Mar 2004 03:36:32 -0000	1.2
@@ -29,3 +29,4 @@
 
 VOID NTAPI DeviceIoctlPassive(PDRIVE_INFO DriveInfo,
                               PIRP Irp);
+

reactos/drivers/storage/floppy
readwrite.c 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- readwrite.c	11 Mar 2004 23:12:03 -0000	1.7
+++ readwrite.c	12 Mar 2004 03:36:32 -0000	1.8
@@ -45,7 +45,6 @@
  *       of RWComputeCHS.  I've never seen Windows send a partial-sector request, though, so
  *       this may not be a bad thing.  Should be looked into, regardless.
  *
- * TODO: Handle split reads and writes across multiple map registers
  * TODO: Break up ReadWritePassive and handle errors better
  * TODO: Figure out data rate issues
  * TODO: Media type detection
@@ -85,7 +84,7 @@
   ControllerInfo->MapRegisterBase = MapRegisterBase;
   KeSetEvent(&ControllerInfo->SynchEvent, 0, FALSE);
 
-  return KeepObject; /* FIXME: Should be something else if we find a bus master */
+  return KeepObject;
 }
 
 
@@ -184,6 +183,8 @@
 
   do
     {
+      int i;
+
       /* Program data rate */
       if(HwSetDataRate(DriveInfo->ControllerInfo, DRSR_DSEL_500KBPS) != STATUS_SUCCESS)
 	{
@@ -207,20 +208,29 @@
       KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
 
       /* Recalibrate --> head over first track */
-      /* FIXME: should be done in a loop? */
-      if(HwRecalibrate(DriveInfo) != STATUS_SUCCESS)
+      for(i=0; i < 2; i++)
 	{
-	  KdPrint(("floppy: RWDetermineMediaType(): Recalibrate failed\n"));
-	  return STATUS_UNSUCCESSFUL;
-	}
+	  NTSTATUS RecalStatus;
 
-      /* Wait for the recalibrate to finish */
-      WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+	  if(HwRecalibrate(DriveInfo) != STATUS_SUCCESS)
+	    {
+	      KdPrint(("floppy: RWDetermineMediaType(): Recalibrate failed\n"));
+	      return STATUS_UNSUCCESSFUL;
+	    }
 
-      if(HwRecalibrateResult(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
-	{
-	  KdPrint(("floppy: RWDetermineMediaType(): RecalibrateResult failed\n"));
-	  return STATUS_UNSUCCESSFUL;
+	  /* Wait for the recalibrate to finish */
+	  WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+
+	  RecalStatus = HwRecalibrateResult(DriveInfo->ControllerInfo);
+	  
+	  if(RecalStatus == STATUS_SUCCESS)
+	    break;
+
+	  if(i == 1) /* failed for 2nd time */
+	    {
+	      KdPrint(("floppy: RWDetermineMediaType(): RecalibrateResult failed\n"));
+	      return STATUS_UNSUCCESSFUL;
+	    }
 	}
 
       /* clear any spurious interrupts */
@@ -574,7 +584,6 @@
    */ 
 
   /* Get map registers for DMA */
-  /* FIXME: Just request all of our map regiters for now */
   KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
   Status = IoAllocateAdapterChannel(DriveInfo->ControllerInfo->AdapterObject, DeviceObject,
 				    DriveInfo->ControllerInfo->MapRegisters, MapRegisterCallback, DriveInfo->ControllerInfo);
CVSspam 0.2.8