- 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

svn path=/trunk/; revision=8660
This commit is contained in:
Vizzini 2004-03-12 03:36:32 +00:00
parent f12f44e036
commit 29d063166b
7 changed files with 157 additions and 159 deletions

View file

@ -23,32 +23,21 @@
* REVISIONS: * REVISIONS:
* 15-Feb-2004 vizzini - Created * 15-Feb-2004 vizzini - Created
* NOTES: * 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 ---- * ---- General to-do items ----
* TODO: Clean up properly on failed init * TODO: Figure out why CreateClose isn't called any more. Seems to correspond
* TODO: Add arc-path support so we can boot from the floppy * with the driver not being unloadable.
* 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: Think about StopDpcQueued -- could be a race; too tired atm to tell * 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 ---- * ---- Support for proper media detection ----
* TODO: Handle MFM flag * TODO: Handle MFM flag
* TODO: Un-hardcode the data rate from various places * TODO: Un-hardcode the data rate from various places
* TODO: Proper media detection (right now we're hardcoded to 1.44) * TODO: Proper media detection (right now we're hardcoded to 1.44)
* TODO: Media detection based on sector 1 * 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> #include <ntddk.h>
@ -101,7 +90,7 @@ static VOID NTAPI MotorStopDpcFunc(PKDPC UnusedDpc,
HwTurnOffMotor(ControllerInfo); HwTurnOffMotor(ControllerInfo);
ControllerInfo->StopDpcQueued = FALSE; ControllerInfo->StopDpcQueued = FALSE;
KeSetEvent(&ControllerInfo->MotorStoppedEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&ControllerInfo->MotorStoppedEvent, EVENT_INCREMENT, FALSE);
} }
@ -202,7 +191,7 @@ static NTSTATUS NTAPI CreateClose(PDEVICE_OBJECT DeviceObject,
* - No state to track, so this routine is easy * - No state to track, so this routine is easy
* - Can be called <= DISPATCH_LEVEL * - 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); UNREFERENCED_PARAMETER(DeviceObject);
@ -212,7 +201,7 @@ static NTSTATUS NTAPI CreateClose(PDEVICE_OBJECT DeviceObject,
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED; Irp->IoStatus.Information = FILE_OPENED;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -225,7 +214,7 @@ static NTSTATUS NTAPI Recalibrate(PDRIVE_INFO DriveInfo)
* DriveInfo: Pointer to the driveinfo struct associated with the targeted drive * DriveInfo: Pointer to the driveinfo struct associated with the targeted drive
* RETURNS: * RETURNS:
* STATUS_SUCCESS on successful starting of the process * STATUS_SUCCESS on successful starting of the process
* STATUS_UNSUCCESSFUL if it fails * STATUS_IO_DEVICE_ERROR if it fails
* NOTES: * NOTES:
* - Sometimes you have to do two recalibrations, particularly if the disk has <80 tracks. * - Sometimes you have to do two recalibrations, particularly if the disk has <80 tracks.
* - PAGED_CODE because we wait * - PAGED_CODE because we wait
@ -246,13 +235,17 @@ static NTSTATUS NTAPI Recalibrate(PDRIVE_INFO DriveInfo)
if(HwSetDataRate(DriveInfo->ControllerInfo, 0) != STATUS_SUCCESS) if(HwSetDataRate(DriveInfo->ControllerInfo, 0) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: Recalibrate: HwSetDataRate failed\n")); 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 */ /* clear the event just in case the last call forgot */
KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent); 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++) for(i = 0; i < 2; i++)
{ {
/* Send the command */ /* Send the command */
@ -312,10 +305,14 @@ NTSTATUS NTAPI ResetChangeFlag(PDRIVE_INFO DriveInfo)
/* clear spurious interrupts in prep for seeks */ /* clear spurious interrupts in prep for seeks */
KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent); KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
/* must re-start the drive because Recalibrate() stops it */
StartMotor(DriveInfo);
/* Seek to 1 */ /* Seek to 1 */
if(HwSeek(DriveInfo, 1) != STATUS_SUCCESS) if(HwSeek(DriveInfo, 1) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: ResetChangeFlag(): HwSeek failed; returning STATUS_IO_DEVICE_ERROR\n")); KdPrint(("floppy: ResetChangeFlag(): HwSeek failed; returning STATUS_IO_DEVICE_ERROR\n"));
StopMotor(DriveInfo->ControllerInfo);
return STATUS_IO_DEVICE_ERROR; return STATUS_IO_DEVICE_ERROR;
} }
@ -324,6 +321,7 @@ NTSTATUS NTAPI ResetChangeFlag(PDRIVE_INFO DriveInfo)
if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS) if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: ResetChangeFlag(): HwSenseInterruptStatus failed; bailing out\n")); KdPrint(("floppy: ResetChangeFlag(): HwSenseInterruptStatus failed; bailing out\n"));
StopMotor(DriveInfo->ControllerInfo);
return STATUS_IO_DEVICE_ERROR; return STATUS_IO_DEVICE_ERROR;
} }
@ -331,6 +329,7 @@ NTSTATUS NTAPI ResetChangeFlag(PDRIVE_INFO DriveInfo)
if(HwSeek(DriveInfo, 1) != STATUS_SUCCESS) if(HwSeek(DriveInfo, 1) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: ResetChangeFlag(): HwSeek failed; returning STATUS_IO_DEVICE_ERROR\n")); KdPrint(("floppy: ResetChangeFlag(): HwSeek failed; returning STATUS_IO_DEVICE_ERROR\n"));
StopMotor(DriveInfo->ControllerInfo);
return STATUS_IO_DEVICE_ERROR; return STATUS_IO_DEVICE_ERROR;
} }
@ -339,6 +338,7 @@ NTSTATUS NTAPI ResetChangeFlag(PDRIVE_INFO DriveInfo)
if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS) if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: ResetChangeFlag(): HwSenseInterruptStatus #2 failed; bailing\n")); KdPrint(("floppy: ResetChangeFlag(): HwSenseInterruptStatus #2 failed; bailing\n"));
StopMotor(DriveInfo->ControllerInfo);
return STATUS_IO_DEVICE_ERROR; return STATUS_IO_DEVICE_ERROR;
} }
@ -346,9 +346,12 @@ NTSTATUS NTAPI ResetChangeFlag(PDRIVE_INFO DriveInfo)
if(HwDiskChanged(DriveInfo, &DiskChanged) != STATUS_SUCCESS) if(HwDiskChanged(DriveInfo, &DiskChanged) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: ResetChangeFlag(): HwDiskChagned failed; returning STATUS_IO_DEVICE_ERROR\n")); KdPrint(("floppy: ResetChangeFlag(): HwDiskChagned failed; returning STATUS_IO_DEVICE_ERROR\n"));
StopMotor(DriveInfo->ControllerInfo);
return STATUS_IO_DEVICE_ERROR; return STATUS_IO_DEVICE_ERROR;
} }
StopMotor(DriveInfo->ControllerInfo);
/* if the change flag is still set, there's probably no media in the drive. */ /* if the change flag is still set, there's probably no media in the drive. */
if(DiskChanged) if(DiskChanged)
return STATUS_NO_MEDIA_IN_DEVICE; return STATUS_NO_MEDIA_IN_DEVICE;
@ -363,8 +366,6 @@ static VOID NTAPI Unload(PDRIVER_OBJECT DriverObject)
* FUNCTION: Unload the driver from memory * FUNCTION: Unload the driver from memory
* ARGUMENTS: * ARGUMENTS:
* DriverObject - The driver that is being unloaded * DriverObject - The driver that is being unloaded
*
* TODO: Delete ARC links
*/ */
{ {
ULONG i,j; ULONG i,j;
@ -380,16 +381,24 @@ static VOID NTAPI Unload(PDRIVER_OBJECT DriverObject)
for(i = 0; i < gNumberOfControllers; i++) for(i = 0; i < gNumberOfControllers; i++)
{ {
if(!gControllerInfo[i].Populated) if(!gControllerInfo[i].Initialized)
continue; continue;
for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++) for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++)
{ {
if(!gControllerInfo[i].DriveInfo[j].Initialized)
continue;
if(gControllerInfo[i].DriveInfo[j].DeviceObject) if(gControllerInfo[i].DriveInfo[j].DeviceObject)
{ {
UNICODE_STRING Link; UNICODE_STRING Link;
RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].SymLinkBuffer); RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].SymLinkBuffer);
IoDeleteSymbolicLink(&Link); IoDeleteSymbolicLink(&Link);
RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].ArcPathBuffer);
IoDeassignArcName(&Link);
IoDeleteDevice(gControllerInfo[i].DriveInfo[j].DeviceObject); IoDeleteDevice(gControllerInfo[i].DriveInfo[j].DeviceObject);
} }
} }
@ -502,13 +511,9 @@ static NTSTATUS NTAPI ConfigCallback(PVOID Context,
} }
if(AddressSpace == 0) if(AddressSpace == 0)
{ gControllerInfo[gNumberOfControllers].BaseAddress = MmMapIoSpace(TranslatedAddress, FDC_PORT_BYTES, MmNonCached);
gControllerInfo[gNumberOfControllers].BaseAddress = MmMapIoSpace(TranslatedAddress, 8, MmNonCached); // symbolic constant?
}
else else
{
gControllerInfo[gNumberOfControllers].BaseAddress = (PUCHAR)TranslatedAddress.u.LowPart; gControllerInfo[gNumberOfControllers].BaseAddress = (PUCHAR)TranslatedAddress.u.LowPart;
}
} }
else if(PartialDescriptor->Type == CmResourceTypeDma) else if(PartialDescriptor->Type == CmResourceTypeDma)
@ -579,7 +584,6 @@ static BOOLEAN NTAPI Isr(PKINTERRUPT Interrupt,
* triggered, this is safe to not do here, as we can just wait for the DPC. * 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 * - 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. * schedule a DPC to take care of it.
* TODO:
* - This driver really cannot shrare interrupts, as I don't know how to conclusively say * - 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 * 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 * my ISR gets called, it was my board that called it. Dumb design, yes, but it goes back to
@ -640,7 +644,7 @@ VOID NTAPI DpcForIsr(PKDPC UnusedDpc,
KdPrint(("floppy: DpcForIsr called\n")); KdPrint(("floppy: DpcForIsr called\n"));
KeSetEvent(&ControllerInfo->SynchEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&ControllerInfo->SynchEvent, EVENT_INCREMENT, FALSE);
} }
@ -651,7 +655,7 @@ static NTSTATUS NTAPI InitController(PCONTROLLER_INFO ControllerInfo)
* ControllerInfo: pointer to the controller to be initialized * ControllerInfo: pointer to the controller to be initialized
* RETURNS: * RETURNS:
* STATUS_SUCCESS if the controller is successfully initialized * STATUS_SUCCESS if the controller is successfully initialized
* STATUS_UNSUCCESSFUL otherwise * STATUS_IO_DEVICE_ERROR otherwise
*/ */
{ {
int i; int i;
@ -666,26 +670,22 @@ static NTSTATUS NTAPI InitController(PCONTROLLER_INFO ControllerInfo)
KeClearEvent(&ControllerInfo->SynchEvent); KeClearEvent(&ControllerInfo->SynchEvent);
//HwDumpRegisters(ControllerInfo);
KdPrint(("floppy: InitController: resetting the controller\n")); KdPrint(("floppy: InitController: resetting the controller\n"));
/* Reset the controller */ /* Reset the controller */
if(HwReset(ControllerInfo) != STATUS_SUCCESS) if(HwReset(ControllerInfo) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: InitController: unable to reset controller\n")); 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")); KdPrint(("floppy: InitController: setting data rate\n"));
/* Set data rate */ /* Set data rate */
if(HwSetDataRate(ControllerInfo, DRSR_DSEL_500KBPS) != STATUS_SUCCESS) if(HwSetDataRate(ControllerInfo, DRSR_DSEL_500KBPS) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: InitController: unable to set data rate\n")); 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")); KdPrint(("floppy: InitController: waiting for initial interrupt\n"));
@ -697,27 +697,18 @@ static NTSTATUS NTAPI InitController(PCONTROLLER_INFO ControllerInfo)
for(i = 0; i < MAX_DRIVES_PER_CONTROLLER; i++) for(i = 0; i < MAX_DRIVES_PER_CONTROLLER; i++)
{ {
KdPrint(("floppy: InitController: Sensing interrupt %d\n", i)); KdPrint(("floppy: InitController: Sensing interrupt %d\n", i));
//HwDumpRegisters(ControllerInfo);
if(HwSenseInterruptStatus(ControllerInfo) != STATUS_SUCCESS) if(HwSenseInterruptStatus(ControllerInfo) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: InitController: Unable to clear interrupt 0x%x\n", i)); 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")); KdPrint(("floppy: InitController: done sensing interrupts\n"));
//HwDumpRegisters(ControllerInfo);
/* Next, see if we have the right version to do implied seek */ /* Next, see if we have the right version to do implied seek */
if(HwGetVersion(ControllerInfo) != VERSION_ENHANCED) if(HwGetVersion(ControllerInfo) == VERSION_ENHANCED)
{
KdPrint(("floppy: InitController: enhanced version not supported; disabling implied seeks\n"));
ControllerInfo->ImpliedSeeks = FALSE;
ControllerInfo->Model30 = FALSE;
}
else
{ {
/* If so, set that up -- all defaults below except first TRUE for EIS */ /* If so, set that up -- all defaults below except first TRUE for EIS */
if(HwConfigure(ControllerInfo, TRUE, TRUE, FALSE, 0, 0) != STATUS_SUCCESS) if(HwConfigure(ControllerInfo, TRUE, TRUE, FALSE, 0, 0) != STATUS_SUCCESS)
@ -731,7 +722,32 @@ static NTSTATUS NTAPI InitController(PCONTROLLER_INFO ControllerInfo)
ControllerInfo->ImpliedSeeks = TRUE; 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 */ /* Specify */
@ -746,32 +762,25 @@ static NTSTATUS NTAPI InitController(PCONTROLLER_INFO ControllerInfo)
if(HwSpecify(ControllerInfo, HeadLoadTime, HeadUnloadTime, StepRateTime, FALSE) != STATUS_SUCCESS) if(HwSpecify(ControllerInfo, HeadLoadTime, HeadUnloadTime, StepRateTime, FALSE) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: InitController: unable to specify options\n")); KdPrint(("floppy: InitController: unable to specify options\n"));
return STATUS_UNSUCCESSFUL; return STATUS_IO_DEVICE_ERROR;
} }
//HwDumpRegisters(ControllerInfo);
/* Init the stop stuff */ /* Init the stop stuff */
KeInitializeDpc(&ControllerInfo->MotorStopDpc, MotorStopDpcFunc, ControllerInfo); KeInitializeDpc(&ControllerInfo->MotorStopDpc, MotorStopDpcFunc, ControllerInfo);
KeInitializeTimer(&ControllerInfo->MotorTimer); KeInitializeTimer(&ControllerInfo->MotorTimer);
KeInitializeEvent(&ControllerInfo->MotorStoppedEvent, SynchronizationEvent, FALSE); KeInitializeEvent(&ControllerInfo->MotorStoppedEvent, SynchronizationEvent, FALSE);
ControllerInfo->StopDpcQueued = 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++) for(i = 0; i < ControllerInfo->NumberOfDrives; i++)
{ {
KdPrint(("floppy: InitController: recalibrating drive 0x%x on controller 0x%x\n", i, ControllerInfo)); KdPrint(("floppy: InitController: recalibrating drive 0x%x on controller 0x%x\n", i, ControllerInfo));
Recalibrate(&ControllerInfo->DriveInfo[i]);
if(Recalibrate(&ControllerInfo->DriveInfo[i]) != STATUS_SUCCESS)
{
KdPrint(("floppy: InitController: unable to recalibrate drive\n"));
return STATUS_UNSUCCESSFUL;
}
} }
//HwDumpRegisters(ControllerInfo);
KdPrint(("floppy: InitController: done initializing; returning STATUS_SUCCESS\n")); KdPrint(("floppy: InitController: done initializing; returning STATUS_SUCCESS\n"));
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -792,11 +801,7 @@ static BOOLEAN NTAPI AddControllers(PDRIVER_OBJECT DriverObject)
* just test a boolean value in the first object to see if it was completely populated. The same value * 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. * is tested for each controller before we build device objects for it.
* TODO: * 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 * - 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; INTERFACE_TYPE InterfaceType = Isa;
@ -814,7 +819,7 @@ static BOOLEAN NTAPI AddControllers(PDRIVER_OBJECT DriverObject)
/* /*
* w2k breaks the return val from ConfigCallback, so we have to hack around it, rather than just * 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) if(!gControllerInfo[0].Populated)
{ {
@ -826,7 +831,7 @@ static BOOLEAN NTAPI AddControllers(PDRIVER_OBJECT DriverObject)
for(i = 0; i < gNumberOfControllers; i++) for(i = 0; i < gNumberOfControllers; i++)
{ {
/* 0: Report resource usage to the kernel, to make sure they aren't assigned to anyone else */ /* 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 */ /* 1: Set up interrupt */
gControllerInfo[i].MappedVector = HalGetInterruptVector(gControllerInfo[i].InterfaceType, gControllerInfo[i].BusNumber, gControllerInfo[i].MappedVector = HalGetInterruptVector(gControllerInfo[i].InterfaceType, gControllerInfo[i].BusNumber,
@ -845,26 +850,18 @@ static BOOLEAN NTAPI AddControllers(PDRIVER_OBJECT DriverObject)
FALSE, Affinity, 0) != STATUS_SUCCESS) FALSE, Affinity, 0) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: AddControllers: unable to connect interrupt\n")); KdPrint(("floppy: AddControllers: unable to connect interrupt\n"));
return FALSE; continue;
} }
/* 2: Set up DMA */ /* 2: Set up DMA */
memset(&DeviceDescription, 0, sizeof(DeviceDescription)); memset(&DeviceDescription, 0, sizeof(DeviceDescription));
DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION; 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.DmaChannel = gControllerInfo[i].Dma;
DeviceDescription.InterfaceType = gControllerInfo[i].InterfaceType; DeviceDescription.InterfaceType = gControllerInfo[i].InterfaceType;
DeviceDescription.BusNumber = gControllerInfo[i].BusNumber; DeviceDescription.BusNumber = gControllerInfo[i].BusNumber;
if(gControllerInfo[i].InterfaceType == PCIBus) /* 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;
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;
gControllerInfo[i].AdapterObject = HalGetAdapter(&DeviceDescription, &gControllerInfo[i].MapRegisters); gControllerInfo[i].AdapterObject = HalGetAdapter(&DeviceDescription, &gControllerInfo[i].MapRegisters);
@ -872,23 +869,27 @@ static BOOLEAN NTAPI AddControllers(PDRIVER_OBJECT DriverObject)
{ {
KdPrint(("floppy: AddControllers: unable to allocate an adapter object\n")); KdPrint(("floppy: AddControllers: unable to allocate an adapter object\n"));
IoDisconnectInterrupt(gControllerInfo[i].InterruptObject); IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
return FALSE; continue;
} }
/* 2b: Initialize the new controller */ /* 2b: Initialize the new controller */
if(InitController(&gControllerInfo[i]) != STATUS_SUCCESS) if(InitController(&gControllerInfo[i]) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: AddControllers():Unable to set up controller %d - initialization failed\n", i)); KdPrint(("floppy: AddControllers():Unable to set up controller %d - initialization failed\n", i));
ASSERT(0); /* FIXME: clean up properly */ IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
continue; continue;
} }
/* 2c: Set the controller's initlized flag so we know to release stuff in Unload */
gControllerInfo[i].Initialized = TRUE;
/* 3: per-drive setup */ /* 3: per-drive setup */
for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++) for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++)
{ {
WCHAR DeviceNameBuf[MAX_DEVICE_NAME]; WCHAR DeviceNameBuf[MAX_DEVICE_NAME];
UNICODE_STRING DeviceName; UNICODE_STRING DeviceName;
UNICODE_STRING LinkName; UNICODE_STRING LinkName;
UNICODE_STRING ArcPath;
UCHAR DriveNumber; UCHAR DriveNumber;
KdPrint(("floppy: AddControllers(): Configuring drive %d on controller %d\n", i, j)); KdPrint(("floppy: AddControllers(): Configuring drive %d on controller %d\n", i, j));
@ -917,11 +918,18 @@ static BOOLEAN NTAPI AddControllers(PDRIVER_OBJECT DriverObject)
{ {
KdPrint(("floppy: AddControllers: unable to register a Device object\n")); KdPrint(("floppy: AddControllers: unable to register a Device object\n"));
IoDisconnectInterrupt(gControllerInfo[i].InterruptObject); 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)); 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 */ /* 3c: Set flags up */
gControllerInfo[i].DriveInfo[j].DeviceObject->Flags |= DO_DIRECT_IO; gControllerInfo[i].DriveInfo[j].DeviceObject->Flags |= DO_DIRECT_IO;
@ -932,8 +940,8 @@ static BOOLEAN NTAPI AddControllers(PDRIVER_OBJECT DriverObject)
{ {
KdPrint(("floppy: AddControllers: Unable to create a symlink for drive %d\n", DriveNumber)); KdPrint(("floppy: AddControllers: Unable to create a symlink for drive %d\n", DriveNumber));
IoDisconnectInterrupt(gControllerInfo[i].InterruptObject); IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
// delete devices too? IoDeassignArcName(&ArcPath);
return FALSE; continue; /* continue to next drive */
} }
/* 3e: Set up the DPC */ /* 3e: Set up the DPC */
@ -947,6 +955,9 @@ static BOOLEAN NTAPI AddControllers(PDRIVER_OBJECT DriverObject)
/* 3h: set the initial media type to unknown */ /* 3h: set the initial media type to unknown */
memset(&gControllerInfo[i].DriveInfo[j].DiskGeometry, 0, sizeof(DISK_GEOMETRY)); memset(&gControllerInfo[i].DriveInfo[j].DiskGeometry, 0, sizeof(DISK_GEOMETRY));
gControllerInfo[i].DriveInfo[j].DiskGeometry.MediaType = Unknown; 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 @@ NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject,
if(PsCreateSystemThread(&ThreadHandle, 0, 0, 0, 0, QueueThread, 0) != STATUS_SUCCESS) if(PsCreateSystemThread(&ThreadHandle, 0, 0, 0, 0, QueueThread, 0) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: Unable to create system thread; failing init\n")); 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) if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, NULL, KernelMode, &ThreadObject, NULL) != STATUS_SUCCESS)
@ -1140,6 +1151,11 @@ NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject,
return STATUS_UNSUCCESSFUL; 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); ZwClose(ThreadHandle);
/* /*
@ -1148,9 +1164,8 @@ NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject,
KeInitializeEvent(&QueueThreadTerminate, NotificationEvent, FALSE); KeInitializeEvent(&QueueThreadTerminate, NotificationEvent, FALSE);
/* /*
* Start the device discovery proces. In theory, this should return STATUS_SUCCESS if * Start the device discovery proces. Returns STATUS_SUCCESS if
* it finds even one drive attached to one controller. In practice, the AddControllers * it finds even one drive attached to one controller.
* routine doesn't handle all of the errors right just yet. FIXME.
*/ */
if(!AddControllers(DriverObject)) if(!AddControllers(DriverObject))
return STATUS_NO_SUCH_DEVICE; return STATUS_NO_SUCH_DEVICE;

View file

@ -71,12 +71,15 @@ typedef struct _DRIVE_INFO
DISK_GEOMETRY DiskGeometry; DISK_GEOMETRY DiskGeometry;
UCHAR BytesPerSectorCode; UCHAR BytesPerSectorCode;
WCHAR SymLinkBuffer[MAX_DEVICE_NAME]; WCHAR SymLinkBuffer[MAX_DEVICE_NAME];
WCHAR ArcPathBuffer[MAX_ARC_PATH_LEN];
ULONG DiskChangeCount; ULONG DiskChangeCount;
BOOLEAN Initialized;
} DRIVE_INFO, *PDRIVE_INFO; } DRIVE_INFO, *PDRIVE_INFO;
typedef struct _CONTROLLER_INFO typedef struct _CONTROLLER_INFO
{ {
BOOLEAN Populated; BOOLEAN Populated;
BOOLEAN Initialized;
ULONG ControllerNumber; ULONG ControllerNumber;
INTERFACE_TYPE InterfaceType; INTERFACE_TYPE InterfaceType;
ULONG BusNumber; ULONG BusNumber;
@ -111,6 +114,14 @@ NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject,
VOID NTAPI SignalMediaChanged(PDEVICE_OBJECT DeviceObject, VOID NTAPI SignalMediaChanged(PDEVICE_OBJECT DeviceObject,
PIRP Irp); 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 * MEDIA TYPES
* *
@ -133,10 +144,3 @@ VOID NTAPI SignalMediaChanged(PDEVICE_OBJECT DeviceObject,
#define GEOMETRY_144_SECTORSPERTRACK 18 #define GEOMETRY_144_SECTORSPERTRACK 18
#define GEOMETRY_144_BYTESPERSECTOR 512 #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);

View file

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

View file

@ -35,6 +35,7 @@
*/ */
#define FLOPPY_DEFAULT_IRQ 0x6 #define FLOPPY_DEFAULT_IRQ 0x6
#define FDC_PORT_BYTES 0x8
/* Register offsets from base address (usually 0x3f8) */ /* Register offsets from base address (usually 0x3f8) */
#define STATUS_REGISTER_A 0x0 /* Read; PS/2 Only */ #define STATUS_REGISTER_A 0x0 /* Read; PS/2 Only */

View file

@ -134,6 +134,11 @@ VOID NTAPI DeviceIoctlPassive(PDRIVE_INFO DriveInfo,
return; return;
} }
/*
* Start the drive to see if the disk has changed
*/
StartMotor(DriveInfo);
/* /*
* Check the change line, and if it's set, return * Check the change line, and if it's set, return
*/ */
@ -143,6 +148,7 @@ VOID NTAPI DeviceIoctlPassive(PDRIVE_INFO DriveInfo,
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
StopMotor(DriveInfo->ControllerInfo);
return; return;
} }
@ -161,7 +167,7 @@ VOID NTAPI DeviceIoctlPassive(PDRIVE_INFO DriveInfo,
Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE; Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
StopMotor(DriveInfo->ControllerInfo);
return; return;
} }
@ -245,6 +251,7 @@ VOID NTAPI DeviceIoctlPassive(PDRIVE_INFO DriveInfo,
KdPrint(("floppy: ioctl: completing with status 0x%x\n", Irp->IoStatus.Status)); KdPrint(("floppy: ioctl: completing with status 0x%x\n", Irp->IoStatus.Status));
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
StopMotor(DriveInfo->ControllerInfo);
return; return;
} }

View file

@ -29,3 +29,4 @@ NTSTATUS NTAPI DeviceIoctl(PDEVICE_OBJECT DeviceObject,
VOID NTAPI DeviceIoctlPassive(PDRIVE_INFO DriveInfo, VOID NTAPI DeviceIoctlPassive(PDRIVE_INFO DriveInfo,
PIRP Irp); PIRP Irp);

View file

@ -45,7 +45,6 @@
* of RWComputeCHS. I've never seen Windows send a partial-sector request, though, so * 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. * 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: Break up ReadWritePassive and handle errors better
* TODO: Figure out data rate issues * TODO: Figure out data rate issues
* TODO: Media type detection * TODO: Media type detection
@ -85,7 +84,7 @@ static IO_ALLOCATION_ACTION NTAPI MapRegisterCallback(PDEVICE_OBJECT DeviceObjec
ControllerInfo->MapRegisterBase = MapRegisterBase; ControllerInfo->MapRegisterBase = MapRegisterBase;
KeSetEvent(&ControllerInfo->SynchEvent, 0, FALSE); KeSetEvent(&ControllerInfo->SynchEvent, 0, FALSE);
return KeepObject; /* FIXME: Should be something else if we find a bus master */ return KeepObject;
} }
@ -184,6 +183,8 @@ static NTSTATUS NTAPI RWDetermineMediaType(PDRIVE_INFO DriveInfo)
do do
{ {
int i;
/* Program data rate */ /* Program data rate */
if(HwSetDataRate(DriveInfo->ControllerInfo, DRSR_DSEL_500KBPS) != STATUS_SUCCESS) if(HwSetDataRate(DriveInfo->ControllerInfo, DRSR_DSEL_500KBPS) != STATUS_SUCCESS)
{ {
@ -207,20 +208,29 @@ static NTSTATUS NTAPI RWDetermineMediaType(PDRIVE_INFO DriveInfo)
KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent); KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
/* Recalibrate --> head over first track */ /* Recalibrate --> head over first track */
/* FIXME: should be done in a loop? */ for(i=0; i < 2; i++)
if(HwRecalibrate(DriveInfo) != STATUS_SUCCESS)
{ {
KdPrint(("floppy: RWDetermineMediaType(): Recalibrate failed\n")); NTSTATUS RecalStatus;
return STATUS_UNSUCCESSFUL;
}
/* Wait for the recalibrate to finish */ if(HwRecalibrate(DriveInfo) != STATUS_SUCCESS)
WaitForControllerInterrupt(DriveInfo->ControllerInfo); {
KdPrint(("floppy: RWDetermineMediaType(): Recalibrate failed\n"));
return STATUS_UNSUCCESSFUL;
}
if(HwRecalibrateResult(DriveInfo->ControllerInfo) != STATUS_SUCCESS) /* Wait for the recalibrate to finish */
{ WaitForControllerInterrupt(DriveInfo->ControllerInfo);
KdPrint(("floppy: RWDetermineMediaType(): RecalibrateResult failed\n"));
return STATUS_UNSUCCESSFUL; 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 */ /* clear any spurious interrupts */
@ -574,7 +584,6 @@ VOID NTAPI ReadWritePassive(PDRIVE_INFO DriveInfo,
*/ */
/* Get map registers for DMA */ /* Get map registers for DMA */
/* FIXME: Just request all of our map regiters for now */
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
Status = IoAllocateAdapterChannel(DriveInfo->ControllerInfo->AdapterObject, DeviceObject, Status = IoAllocateAdapterChannel(DriveInfo->ControllerInfo->AdapterObject, DeviceObject,
DriveInfo->ControllerInfo->MapRegisters, MapRegisterCallback, DriveInfo->ControllerInfo); DriveInfo->ControllerInfo->MapRegisters, MapRegisterCallback, DriveInfo->ControllerInfo);