Formatting only, no code changes.
svn path=/trunk/; revision=51410
* CSQ Callbacks
*/
-\f
-VOID NTAPI CsqRemoveIrp(PIO_CSQ UnusedCsq,
- PIRP Irp)
+
+VOID NTAPI
+CsqRemoveIrp(PIO_CSQ UnusedCsq, PIRP Irp)
/*
* FUNCTION: Remove an IRP from the queue
* ARGUMENTS:
* - Called under the protection of the queue lock
*/
{
- UNREFERENCED_PARAMETER(UnusedCsq);
- TRACE_(FLOPPY, "CSQ: Removing IRP 0x%p\n", Irp);
- RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+ UNREFERENCED_PARAMETER(UnusedCsq);
+ TRACE_(FLOPPY, "CSQ: Removing IRP 0x%p\n", Irp);
+ RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
}
-\f
-PIRP NTAPI CsqPeekNextIrp(PIO_CSQ UnusedCsq,
- PIRP Irp,
- PVOID PeekContext)
+
+PIRP NTAPI
+CsqPeekNextIrp(PIO_CSQ UnusedCsq, PIRP Irp, PVOID PeekContext)
/*
* FUNCTION: Find the next matching IRP in the queue
* ARGUMENTS:
* - Called under the protection of the queue lock
*/
{
- UNREFERENCED_PARAMETER(UnusedCsq);
- UNREFERENCED_PARAMETER(PeekContext);
- TRACE_(FLOPPY, "CSQ: Peeking for next IRP\n");
+ UNREFERENCED_PARAMETER(UnusedCsq);
+ UNREFERENCED_PARAMETER(PeekContext);
+ TRACE_(FLOPPY, "CSQ: Peeking for next IRP\n");
- if(Irp)
- return CONTAINING_RECORD(&Irp->Tail.Overlay.ListEntry.Flink, IRP, Tail.Overlay.ListEntry);
+ if(Irp)
+ return CONTAINING_RECORD(&Irp->Tail.Overlay.ListEntry.Flink, IRP, Tail.Overlay.ListEntry);
- if(IsListEmpty(&IrpQueue))
- return NULL;
+ if(IsListEmpty(&IrpQueue))
+ return NULL;
- return CONTAINING_RECORD(IrpQueue.Flink, IRP, Tail.Overlay.ListEntry);
+ return CONTAINING_RECORD(IrpQueue.Flink, IRP, Tail.Overlay.ListEntry);
}
-\f
-VOID NTAPI CsqAcquireLock(PIO_CSQ UnusedCsq,
- PKIRQL Irql)
+
+VOID NTAPI
+CsqAcquireLock(PIO_CSQ UnusedCsq, PKIRQL Irql)
/*
* FUNCTION: Acquire the queue lock
* ARGUMENTS:
* Irql: Pointer to a variable to store the old irql into
*/
{
- UNREFERENCED_PARAMETER(UnusedCsq);
- INFO_(FLOPPY, "CSQ: Acquiring spin lock\n");
- KeAcquireSpinLock(&IrpQueueLock, Irql);
+ UNREFERENCED_PARAMETER(UnusedCsq);
+ INFO_(FLOPPY, "CSQ: Acquiring spin lock\n");
+ KeAcquireSpinLock(&IrpQueueLock, Irql);
}
-\f
-VOID NTAPI CsqReleaseLock(PIO_CSQ UnusedCsq,
- KIRQL Irql)
+
+VOID NTAPI
+CsqReleaseLock(PIO_CSQ UnusedCsq, KIRQL Irql)
/*
* FUNCTION: Release the queue lock
* ARGUMENTS:
* Irql: IRQL to lower to on release
*/
{
- UNREFERENCED_PARAMETER(UnusedCsq);
- INFO_(FLOPPY, "CSQ: Releasing spin lock\n");
- KeReleaseSpinLock(&IrpQueueLock, Irql);
+ UNREFERENCED_PARAMETER(UnusedCsq);
+ INFO_(FLOPPY, "CSQ: Releasing spin lock\n");
+ KeReleaseSpinLock(&IrpQueueLock, Irql);
}
-\f
-VOID NTAPI CsqCompleteCanceledIrp(PIO_CSQ UnusedCsq,
- PIRP Irp)
+
+VOID NTAPI
+CsqCompleteCanceledIrp(PIO_CSQ UnusedCsq, PIRP Irp)
/*
* FUNCTION: Complete a canceled IRP
* ARGUMENTS:
* - MS misspelled CANCELLED... sigh...
*/
{
- UNREFERENCED_PARAMETER(UnusedCsq);
- TRACE_(FLOPPY, "CSQ: Canceling irp 0x%p\n", Irp);
- Irp->IoStatus.Status = STATUS_CANCELLED;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ UNREFERENCED_PARAMETER(UnusedCsq);
+ TRACE_(FLOPPY, "CSQ: Canceling irp 0x%p\n", Irp);
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
-\f
-VOID NTAPI CsqInsertIrp(PIO_CSQ UnusedCsq,
- PIRP Irp)
+
+VOID NTAPI
+CsqInsertIrp(PIO_CSQ UnusedCsq, PIRP Irp)
/*
* FUNCTION: Queue an IRP
* ARGUMENTS:
* that at least one IRP is canceled at some point
*/
{
- UNREFERENCED_PARAMETER(UnusedCsq);
- TRACE_(FLOPPY, "CSQ: Inserting IRP 0x%p\n", Irp);
- InsertTailList(&IrpQueue, &Irp->Tail.Overlay.ListEntry);
- KeReleaseSemaphore(&QueueSemaphore, 0, 1, FALSE);
+ UNREFERENCED_PARAMETER(UnusedCsq);
+ TRACE_(FLOPPY, "CSQ: Inserting IRP 0x%p\n", Irp);
+ InsertTailList(&IrpQueue, &Irp->Tail.Overlay.ListEntry);
+ KeReleaseSemaphore(&QueueSemaphore, 0, 1, FALSE);
}
extern KSPIN_LOCK IrpQueueLock;
extern KSEMAPHORE QueueSemaphore;
-VOID NTAPI CsqInsertIrp(PIO_CSQ Csq,
- PIRP Irp);
+VOID NTAPI
+CsqInsertIrp(PIO_CSQ Csq, PIRP Irp);
-VOID NTAPI CsqRemoveIrp(PIO_CSQ Csq,
- PIRP Irp);
+VOID NTAPI
+CsqRemoveIrp(PIO_CSQ Csq, PIRP Irp);
-PIRP NTAPI CsqPeekNextIrp(PIO_CSQ Csq,
- PIRP Irp,
- PVOID PeekContext);
+PIRP NTAPI
+CsqPeekNextIrp(PIO_CSQ Csq, PIRP Irp, PVOID PeekContext);
-VOID NTAPI CsqAcquireLock(PIO_CSQ Csq,
- PKIRQL Irql);
+VOID NTAPI
+CsqAcquireLock(PIO_CSQ Csq, PKIRQL Irql);
-VOID NTAPI CsqReleaseLock(PIO_CSQ Csq,
- KIRQL Irql);
+VOID NTAPI
+CsqReleaseLock(PIO_CSQ Csq, KIRQL Irql);
-VOID NTAPI CsqCompleteCanceledIrp(PIO_CSQ Csq,
- PIRP Irp);
+VOID NTAPI
+CsqCompleteCanceledIrp(PIO_CSQ Csq, PIRP Irp);
static KEVENT QueueThreadTerminate;
static PVOID QueueThreadObject;
-\f
-static VOID NTAPI MotorStopDpcFunc(PKDPC UnusedDpc,
- PVOID DeferredContext,
- PVOID SystemArgument1,
- PVOID SystemArgument2)
+
+static VOID NTAPI
+MotorStopDpcFunc(PKDPC UnusedDpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
/*
* FUNCTION: Stop the floppy motor
* ARGUMENTS:
* - Called back at DISPATCH_LEVEL
*/
{
- PCONTROLLER_INFO ControllerInfo = (PCONTROLLER_INFO)DeferredContext;
+ PCONTROLLER_INFO ControllerInfo = (PCONTROLLER_INFO)DeferredContext;
- UNREFERENCED_PARAMETER(SystemArgument1);
- UNREFERENCED_PARAMETER(SystemArgument2);
- UNREFERENCED_PARAMETER(UnusedDpc);
+ UNREFERENCED_PARAMETER(SystemArgument1);
+ UNREFERENCED_PARAMETER(SystemArgument2);
+ UNREFERENCED_PARAMETER(UnusedDpc);
- ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
- ASSERT(ControllerInfo);
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+ ASSERT(ControllerInfo);
- TRACE_(FLOPPY, "MotorStopDpcFunc called\n");
+ TRACE_(FLOPPY, "MotorStopDpcFunc called\n");
- HwTurnOffMotor(ControllerInfo);
- ControllerInfo->StopDpcQueued = FALSE;
- KeSetEvent(&ControllerInfo->MotorStoppedEvent, EVENT_INCREMENT, FALSE);
+ HwTurnOffMotor(ControllerInfo);
+ ControllerInfo->StopDpcQueued = FALSE;
+ KeSetEvent(&ControllerInfo->MotorStoppedEvent, EVENT_INCREMENT, FALSE);
}
-\f
-VOID NTAPI StartMotor(PDRIVE_INFO DriveInfo)
+
+VOID NTAPI
+StartMotor(PDRIVE_INFO DriveInfo)
/*
* FUNCTION: Start the motor, taking into account proper handling of the timer race
* ARGUMENTS:
* - PAGED_CODE because we wait
*/
{
- PAGED_CODE();
- ASSERT(DriveInfo);
+ PAGED_CODE();
+ ASSERT(DriveInfo);
- TRACE_(FLOPPY, "StartMotor called\n");
+ TRACE_(FLOPPY, "StartMotor called\n");
- if(DriveInfo->ControllerInfo->StopDpcQueued && !KeCancelTimer(&DriveInfo->ControllerInfo->MotorTimer))
+ if(DriveInfo->ControllerInfo->StopDpcQueued && !KeCancelTimer(&DriveInfo->ControllerInfo->MotorTimer))
{
- /* Motor turner-offer is already running; wait for it to finish */
- INFO_(FLOPPY, "StartMotor: motor turner-offer is already running; waiting for it\n");
- KeWaitForSingleObject(&DriveInfo->ControllerInfo->MotorStoppedEvent, Executive, KernelMode, FALSE, NULL);
- INFO_(FLOPPY, "StartMotor: wait satisfied\n");
+ /* Motor turner-offer is already running; wait for it to finish */
+ INFO_(FLOPPY, "StartMotor: motor turner-offer is already running; waiting for it\n");
+ KeWaitForSingleObject(&DriveInfo->ControllerInfo->MotorStoppedEvent, Executive, KernelMode, FALSE, NULL);
+ INFO_(FLOPPY, "StartMotor: wait satisfied\n");
}
- DriveInfo->ControllerInfo->StopDpcQueued = FALSE;
+ DriveInfo->ControllerInfo->StopDpcQueued = FALSE;
- if(HwTurnOnMotor(DriveInfo) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "StartMotor(): warning: HwTurnOnMotor failed\n");
- }
+ if(HwTurnOnMotor(DriveInfo) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "StartMotor(): warning: HwTurnOnMotor failed\n");
+ }
}
-\f
-VOID NTAPI StopMotor(PCONTROLLER_INFO ControllerInfo)
+
+VOID NTAPI
+StopMotor(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Stop all motors on the controller
* ARGUMENTS:
* All we have to do is set up a timer.
*/
{
- LARGE_INTEGER StopTime;
+ LARGE_INTEGER StopTime;
- ASSERT(ControllerInfo);
+ ASSERT(ControllerInfo);
- TRACE_(FLOPPY, "StopMotor called\n");
+ TRACE_(FLOPPY, "StopMotor called\n");
- /* one relative second, in 100-ns units */
- StopTime.QuadPart = 10000000;
- StopTime.QuadPart *= -1;
+ /* one relative second, in 100-ns units */
+ StopTime.QuadPart = 10000000;
+ StopTime.QuadPart *= -1;
- KeClearEvent(&ControllerInfo->MotorStoppedEvent);
- KeSetTimer(&ControllerInfo->MotorTimer, StopTime, &ControllerInfo->MotorStopDpc);
- ControllerInfo->StopDpcQueued = TRUE;
+ KeClearEvent(&ControllerInfo->MotorStoppedEvent);
+ KeSetTimer(&ControllerInfo->MotorTimer, StopTime, &ControllerInfo->MotorStopDpc);
+ ControllerInfo->StopDpcQueued = TRUE;
}
-\f
-VOID NTAPI WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo)
+
+VOID NTAPI
+WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Wait for the controller to interrupt, and then clear the event
* ARGUMENTS:
* - PAGED_CODE because it waits
*/
{
- PAGED_CODE();
- ASSERT(ControllerInfo);
+ PAGED_CODE();
+ ASSERT(ControllerInfo);
- KeWaitForSingleObject(&ControllerInfo->SynchEvent, Executive, KernelMode, FALSE, NULL);
- KeClearEvent(&ControllerInfo->SynchEvent);
+ KeWaitForSingleObject(&ControllerInfo->SynchEvent, Executive, KernelMode, FALSE, NULL);
+ KeClearEvent(&ControllerInfo->SynchEvent);
}
static DRIVER_DISPATCH CreateClose;
* TODO: Figure out why this isn't getting called
*/
{
- UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(DeviceObject);
- TRACE_(FLOPPY, "CreateClose called\n");
+ TRACE_(FLOPPY, "CreateClose called\n");
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = FILE_OPENED;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = FILE_OPENED;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
+ IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-static NTSTATUS NTAPI Recalibrate(PDRIVE_INFO DriveInfo)
+
+static NTSTATUS NTAPI
+Recalibrate(PDRIVE_INFO DriveInfo)
/*
* FUNCTION: Start the recalibration process
* ARGUMENTS:
* - PAGED_CODE because we wait
*/
{
- NTSTATUS Status;
- ULONG i;
+ NTSTATUS Status;
+ ULONG i;
- PAGED_CODE();
- ASSERT(DriveInfo);
+ PAGED_CODE();
+ ASSERT(DriveInfo);
- /* first turn on the motor */
- /* Must stop after every start, prior to return */
- StartMotor(DriveInfo);
+ /* first turn on the motor */
+ /* Must stop after every start, prior to return */
+ StartMotor(DriveInfo);
- /* set the data rate */
- WARN_(FLOPPY, "FIXME: UN-HARDCODE DATA RATE\n");
- if(HwSetDataRate(DriveInfo->ControllerInfo, 0) != STATUS_SUCCESS)
+ /* set the data rate */
+ WARN_(FLOPPY, "FIXME: UN-HARDCODE DATA RATE\n");
+ if(HwSetDataRate(DriveInfo->ControllerInfo, 0) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "Recalibrate: HwSetDataRate failed\n");
- StopMotor(DriveInfo->ControllerInfo);
- return STATUS_IO_DEVICE_ERROR;
+ WARN_(FLOPPY, "Recalibrate: HwSetDataRate failed\n");
+ StopMotor(DriveInfo->ControllerInfo);
+ return STATUS_IO_DEVICE_ERROR;
}
- /* clear the event just in case the last call forgot */
- KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
+ /* clear the event just in case the last call forgot */
+ KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
- /* 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++)
+ /* 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 */
- Status = HwRecalibrate(DriveInfo);
- if(Status != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "Recalibrate: HwRecalibrate returned error\n");
- continue;
- }
-
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
-
- /* Get the results */
- Status = HwRecalibrateResult(DriveInfo->ControllerInfo);
- if(Status != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "Recalibrate: HwRecalibrateResult returned error\n");
- break;
+ /* Send the command */
+ Status = HwRecalibrate(DriveInfo);
+ if(Status != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "Recalibrate: HwRecalibrate returned error\n");
+ continue;
+ }
+
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+
+ /* Get the results */
+ Status = HwRecalibrateResult(DriveInfo->ControllerInfo);
+ if(Status != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "Recalibrate: HwRecalibrateResult returned error\n");
+ break;
}
}
- KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
+ KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
- /* Must stop after every start, prior to return */
- StopMotor(DriveInfo->ControllerInfo);
+ /* Must stop after every start, prior to return */
+ StopMotor(DriveInfo->ControllerInfo);
- return Status;
+ return Status;
}
-\f
-NTSTATUS NTAPI ResetChangeFlag(PDRIVE_INFO DriveInfo)
+
+NTSTATUS NTAPI
+ResetChangeFlag(PDRIVE_INFO DriveInfo)
/*
* FUNCTION: Reset the drive's change flag (as reflected in the DIR)
* ARGUMENTS:
* - PAGED_CODE because we wait
*/
{
- BOOLEAN DiskChanged;
+ BOOLEAN DiskChanged;
- PAGED_CODE();
- ASSERT(DriveInfo);
+ PAGED_CODE();
+ ASSERT(DriveInfo);
- TRACE_(FLOPPY, "ResetChangeFlag called\n");
+ TRACE_(FLOPPY, "ResetChangeFlag called\n");
- /* Try to recalibrate. We don't care if it works. */
- Recalibrate(DriveInfo);
+ /* Try to recalibrate. We don't care if it works. */
+ Recalibrate(DriveInfo);
- /* clear spurious interrupts in prep for seeks */
- KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
+ /* clear spurious interrupts in prep for seeks */
+ KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
- /* must re-start the drive because Recalibrate() stops it */
- StartMotor(DriveInfo);
+ /* must re-start the drive because Recalibrate() stops it */
+ StartMotor(DriveInfo);
- /* Seek to 1 */
- if(HwSeek(DriveInfo, 1) != STATUS_SUCCESS)
+ /* Seek to 1 */
+ if(HwSeek(DriveInfo, 1) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "ResetChangeFlag(): HwSeek failed; returning STATUS_IO_DEVICE_ERROR\n");
- StopMotor(DriveInfo->ControllerInfo);
- return STATUS_IO_DEVICE_ERROR;
+ WARN_(FLOPPY, "ResetChangeFlag(): HwSeek failed; returning STATUS_IO_DEVICE_ERROR\n");
+ StopMotor(DriveInfo->ControllerInfo);
+ return STATUS_IO_DEVICE_ERROR;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo);
- if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
+ if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "ResetChangeFlag(): HwSenseInterruptStatus failed; bailing out\n");
- StopMotor(DriveInfo->ControllerInfo);
- return STATUS_IO_DEVICE_ERROR;
+ WARN_(FLOPPY, "ResetChangeFlag(): HwSenseInterruptStatus failed; bailing out\n");
+ StopMotor(DriveInfo->ControllerInfo);
+ return STATUS_IO_DEVICE_ERROR;
}
- /* Seek back to 0 */
- if(HwSeek(DriveInfo, 0) != STATUS_SUCCESS)
+ /* Seek back to 0 */
+ if(HwSeek(DriveInfo, 0) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "ResetChangeFlag(): HwSeek failed; returning STATUS_IO_DEVICE_ERROR\n");
- StopMotor(DriveInfo->ControllerInfo);
- return STATUS_IO_DEVICE_ERROR;
+ WARN_(FLOPPY, "ResetChangeFlag(): HwSeek failed; returning STATUS_IO_DEVICE_ERROR\n");
+ StopMotor(DriveInfo->ControllerInfo);
+ return STATUS_IO_DEVICE_ERROR;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo);
- if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
+ if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "ResetChangeFlag(): HwSenseInterruptStatus #2 failed; bailing\n");
- StopMotor(DriveInfo->ControllerInfo);
- return STATUS_IO_DEVICE_ERROR;
+ WARN_(FLOPPY, "ResetChangeFlag(): HwSenseInterruptStatus #2 failed; bailing\n");
+ StopMotor(DriveInfo->ControllerInfo);
+ return STATUS_IO_DEVICE_ERROR;
}
- /* Check the change bit */
- if(HwDiskChanged(DriveInfo, &DiskChanged) != STATUS_SUCCESS)
+ /* Check the change bit */
+ if(HwDiskChanged(DriveInfo, &DiskChanged) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "ResetChangeFlag(): HwDiskChanged failed; returning STATUS_IO_DEVICE_ERROR\n");
- StopMotor(DriveInfo->ControllerInfo);
- return STATUS_IO_DEVICE_ERROR;
+ WARN_(FLOPPY, "ResetChangeFlag(): HwDiskChanged failed; returning STATUS_IO_DEVICE_ERROR\n");
+ StopMotor(DriveInfo->ControllerInfo);
+ return STATUS_IO_DEVICE_ERROR;
}
- StopMotor(DriveInfo->ControllerInfo);
+ 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;
+ /* if the change flag is still set, there's probably no media in the drive. */
+ if(DiskChanged)
+ return STATUS_NO_MEDIA_IN_DEVICE;
- /* else we're done! */
- return STATUS_SUCCESS;
+ /* else we're done! */
+ return STATUS_SUCCESS;
}
-\f
-static VOID NTAPI Unload(PDRIVER_OBJECT DriverObject)
+
+static VOID NTAPI
+Unload(PDRIVER_OBJECT DriverObject)
/*
* FUNCTION: Unload the driver from memory
* ARGUMENTS:
* DriverObject - The driver that is being unloaded
*/
{
- ULONG i,j;
+ ULONG i,j;
- PAGED_CODE();
- UNREFERENCED_PARAMETER(DriverObject);
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(DriverObject);
- TRACE_(FLOPPY, "unloading\n");
+ TRACE_(FLOPPY, "unloading\n");
- KeSetEvent(&QueueThreadTerminate, 0, FALSE);
- KeWaitForSingleObject(QueueThreadObject, Executive, KernelMode, FALSE, 0);
- ObDereferenceObject(QueueThreadObject);
+ KeSetEvent(&QueueThreadTerminate, 0, FALSE);
+ KeWaitForSingleObject(QueueThreadObject, Executive, KernelMode, FALSE, 0);
+ ObDereferenceObject(QueueThreadObject);
- for(i = 0; i < gNumberOfControllers; i++)
+ for(i = 0; i < gNumberOfControllers; i++)
{
- if(!gControllerInfo[i].Initialized)
- continue;
+ if(!gControllerInfo[i].Initialized)
+ continue;
- for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++)
- {
- if(!gControllerInfo[i].DriveInfo[j].Initialized)
- continue;
+ 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);
- IoDeleteSymbolicLink(&Link);
+ RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].SymLinkBuffer);
+ IoDeleteSymbolicLink(&Link);
- RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].ArcPathBuffer);
- IoDeassignArcName(&Link);
+ RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].ArcPathBuffer);
+ IoDeassignArcName(&Link);
- IoDeleteDevice(gControllerInfo[i].DriveInfo[j].DeviceObject);
+ IoDeleteDevice(gControllerInfo[i].DriveInfo[j].DeviceObject);
}
- }
+ }
- IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
+ IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
- /* Power down the controller */
- if(HwPowerOff(&gControllerInfo[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "unload: warning: HwPowerOff failed\n");
- }
+ /* Power down the controller */
+ if(HwPowerOff(&gControllerInfo[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "unload: warning: HwPowerOff failed\n");
+ }
}
}
-\f
-static NTSTATUS NTAPI ConfigCallback(PVOID Context,
- PUNICODE_STRING PathName,
- INTERFACE_TYPE BusType,
- ULONG BusNumber,
- PKEY_VALUE_FULL_INFORMATION *BusInformation,
- CONFIGURATION_TYPE ControllerType,
- ULONG ControllerNumber,
- PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
- CONFIGURATION_TYPE PeripheralType,
- ULONG PeripheralNumber,
- PKEY_VALUE_FULL_INFORMATION *PeripheralInformation)
+
+static NTSTATUS NTAPI
+ConfigCallback(PVOID Context,
+ PUNICODE_STRING PathName,
+ INTERFACE_TYPE BusType,
+ ULONG BusNumber,
+ PKEY_VALUE_FULL_INFORMATION *BusInformation,
+ CONFIGURATION_TYPE ControllerType,
+ ULONG ControllerNumber,
+ PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
+ CONFIGURATION_TYPE PeripheralType,
+ ULONG PeripheralNumber,
+ PKEY_VALUE_FULL_INFORMATION *PeripheralInformation)
/*
* FUNCTION: Callback to IoQueryDeviceDescription, which tells us about our controllers
* ARGUMENTS:
* drives.
*/
{
- PKEY_VALUE_FULL_INFORMATION ControllerFullDescriptor = ControllerInformation[IoQueryDeviceConfigurationData];
- PCM_FULL_RESOURCE_DESCRIPTOR ControllerResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PCHAR)ControllerFullDescriptor +
- ControllerFullDescriptor->DataOffset);
+ PKEY_VALUE_FULL_INFORMATION ControllerFullDescriptor = ControllerInformation[IoQueryDeviceConfigurationData];
+ PCM_FULL_RESOURCE_DESCRIPTOR ControllerResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PCHAR)ControllerFullDescriptor +
+ ControllerFullDescriptor->DataOffset);
- PKEY_VALUE_FULL_INFORMATION PeripheralFullDescriptor = PeripheralInformation[IoQueryDeviceConfigurationData];
- PCM_FULL_RESOURCE_DESCRIPTOR PeripheralResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PCHAR)PeripheralFullDescriptor +
- PeripheralFullDescriptor->DataOffset);
+ PKEY_VALUE_FULL_INFORMATION PeripheralFullDescriptor = PeripheralInformation[IoQueryDeviceConfigurationData];
+ PCM_FULL_RESOURCE_DESCRIPTOR PeripheralResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PCHAR)PeripheralFullDescriptor +
+ PeripheralFullDescriptor->DataOffset);
- PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
- PCM_FLOPPY_DEVICE_DATA FloppyDeviceData;
- UCHAR i;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+ PCM_FLOPPY_DEVICE_DATA FloppyDeviceData;
+ UCHAR i;
- PAGED_CODE();
- UNREFERENCED_PARAMETER(PeripheralType);
- UNREFERENCED_PARAMETER(PeripheralNumber);
- UNREFERENCED_PARAMETER(BusInformation);
- UNREFERENCED_PARAMETER(Context);
- UNREFERENCED_PARAMETER(ControllerType);
- UNREFERENCED_PARAMETER(PathName);
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(PeripheralType);
+ UNREFERENCED_PARAMETER(PeripheralNumber);
+ UNREFERENCED_PARAMETER(BusInformation);
+ UNREFERENCED_PARAMETER(Context);
+ UNREFERENCED_PARAMETER(ControllerType);
+ UNREFERENCED_PARAMETER(PathName);
- TRACE_(FLOPPY, "ConfigCallback called with ControllerNumber %d\n", ControllerNumber);
+ TRACE_(FLOPPY, "ConfigCallback called with ControllerNumber %d\n", ControllerNumber);
- gControllerInfo[gNumberOfControllers].ControllerNumber = ControllerNumber;
- gControllerInfo[gNumberOfControllers].InterfaceType = BusType;
- gControllerInfo[gNumberOfControllers].BusNumber = BusNumber;
+ gControllerInfo[gNumberOfControllers].ControllerNumber = ControllerNumber;
+ gControllerInfo[gNumberOfControllers].InterfaceType = BusType;
+ gControllerInfo[gNumberOfControllers].BusNumber = BusNumber;
- /* Get controller interrupt level/vector, dma channel, and port base */
- for(i = 0; i < ControllerResourceDescriptor->PartialResourceList.Count; i++)
+ /* Get controller interrupt level/vector, dma channel, and port base */
+ for(i = 0; i < ControllerResourceDescriptor->PartialResourceList.Count; i++)
{
- KeInitializeEvent(&gControllerInfo[gNumberOfControllers].SynchEvent, NotificationEvent, FALSE);
+ KeInitializeEvent(&gControllerInfo[gNumberOfControllers].SynchEvent, NotificationEvent, FALSE);
- PartialDescriptor = &ControllerResourceDescriptor->PartialResourceList.PartialDescriptors[i];
+ PartialDescriptor = &ControllerResourceDescriptor->PartialResourceList.PartialDescriptors[i];
- if(PartialDescriptor->Type == CmResourceTypeInterrupt)
+ if(PartialDescriptor->Type == CmResourceTypeInterrupt)
{
- gControllerInfo[gNumberOfControllers].Level = PartialDescriptor->u.Interrupt.Level;
- gControllerInfo[gNumberOfControllers].Vector = PartialDescriptor->u.Interrupt.Vector;
+ gControllerInfo[gNumberOfControllers].Level = PartialDescriptor->u.Interrupt.Level;
+ gControllerInfo[gNumberOfControllers].Vector = PartialDescriptor->u.Interrupt.Vector;
- if(PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
- gControllerInfo[gNumberOfControllers].InterruptMode = Latched;
- else
- gControllerInfo[gNumberOfControllers].InterruptMode = LevelSensitive;
+ if(PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
+ gControllerInfo[gNumberOfControllers].InterruptMode = Latched;
+ else
+ gControllerInfo[gNumberOfControllers].InterruptMode = LevelSensitive;
}
- else if(PartialDescriptor->Type == CmResourceTypePort)
+ else if(PartialDescriptor->Type == CmResourceTypePort)
{
- PHYSICAL_ADDRESS TranslatedAddress;
- ULONG AddressSpace = 0x1; /* I/O Port Range */
-
- if(!HalTranslateBusAddress(BusType, BusNumber, PartialDescriptor->u.Port.Start, &AddressSpace, &TranslatedAddress))
- {
- WARN_(FLOPPY, "HalTranslateBusAddress failed; returning\n");
- return STATUS_IO_DEVICE_ERROR;
- }
-
- if(AddressSpace == 0)
- gControllerInfo[gNumberOfControllers].BaseAddress = MmMapIoSpace(TranslatedAddress, FDC_PORT_BYTES, MmNonCached);
- else
- gControllerInfo[gNumberOfControllers].BaseAddress = (PUCHAR)(ULONG_PTR)TranslatedAddress.QuadPart;
+ PHYSICAL_ADDRESS TranslatedAddress;
+ ULONG AddressSpace = 0x1; /* I/O Port Range */
+
+ if(!HalTranslateBusAddress(BusType, BusNumber, PartialDescriptor->u.Port.Start, &AddressSpace, &TranslatedAddress))
+ {
+ WARN_(FLOPPY, "HalTranslateBusAddress failed; returning\n");
+ return STATUS_IO_DEVICE_ERROR;
+ }
+
+ if(AddressSpace == 0)
+ gControllerInfo[gNumberOfControllers].BaseAddress = MmMapIoSpace(TranslatedAddress, FDC_PORT_BYTES, MmNonCached);
+ else
+ gControllerInfo[gNumberOfControllers].BaseAddress = (PUCHAR)(ULONG_PTR)TranslatedAddress.QuadPart;
}
- else if(PartialDescriptor->Type == CmResourceTypeDma)
- gControllerInfo[gNumberOfControllers].Dma = PartialDescriptor->u.Dma.Channel;
+ else if(PartialDescriptor->Type == CmResourceTypeDma)
+ gControllerInfo[gNumberOfControllers].Dma = PartialDescriptor->u.Dma.Channel;
}
- /* Start with 0 drives, then go looking */
- gControllerInfo[gNumberOfControllers].NumberOfDrives = 0;
+ /* Start with 0 drives, then go looking */
+ gControllerInfo[gNumberOfControllers].NumberOfDrives = 0;
- /* learn about drives attached to controller */
- for(i = 0; i < PeripheralResourceDescriptor->PartialResourceList.Count; i++)
+ /* learn about drives attached to controller */
+ for(i = 0; i < PeripheralResourceDescriptor->PartialResourceList.Count; i++)
{
- PDRIVE_INFO DriveInfo = &gControllerInfo[gNumberOfControllers].DriveInfo[i];
-
- PartialDescriptor = &PeripheralResourceDescriptor->PartialResourceList.PartialDescriptors[i];
-
- if(PartialDescriptor->Type != CmResourceTypeDeviceSpecific)
- continue;
-
- FloppyDeviceData = (PCM_FLOPPY_DEVICE_DATA)(PartialDescriptor + 1);
-
- DriveInfo->ControllerInfo = &gControllerInfo[gNumberOfControllers];
- DriveInfo->UnitNumber = i;
-
- DriveInfo->FloppyDeviceData.MaxDensity = FloppyDeviceData->MaxDensity;
- DriveInfo->FloppyDeviceData.MountDensity = FloppyDeviceData->MountDensity;
- DriveInfo->FloppyDeviceData.StepRateHeadUnloadTime = FloppyDeviceData->StepRateHeadUnloadTime;
- DriveInfo->FloppyDeviceData.HeadLoadTime = FloppyDeviceData->HeadLoadTime;
- DriveInfo->FloppyDeviceData.MotorOffTime = FloppyDeviceData->MotorOffTime;
- DriveInfo->FloppyDeviceData.SectorLengthCode = FloppyDeviceData->SectorLengthCode;
- DriveInfo->FloppyDeviceData.SectorPerTrack = FloppyDeviceData->SectorPerTrack;
- DriveInfo->FloppyDeviceData.ReadWriteGapLength = FloppyDeviceData->ReadWriteGapLength;
- DriveInfo->FloppyDeviceData.FormatGapLength = FloppyDeviceData->FormatGapLength;
- DriveInfo->FloppyDeviceData.FormatFillCharacter = FloppyDeviceData->FormatFillCharacter;
- DriveInfo->FloppyDeviceData.HeadSettleTime = FloppyDeviceData->HeadSettleTime;
- DriveInfo->FloppyDeviceData.MotorSettleTime = FloppyDeviceData->MotorSettleTime;
- DriveInfo->FloppyDeviceData.MaximumTrackValue = FloppyDeviceData->MaximumTrackValue;
- DriveInfo->FloppyDeviceData.DataTransferLength = FloppyDeviceData->DataTransferLength;
-
- /* Once it's all set up, acknowledge its existance in the controller info object */
- gControllerInfo[gNumberOfControllers].NumberOfDrives++;
+ PDRIVE_INFO DriveInfo = &gControllerInfo[gNumberOfControllers].DriveInfo[i];
+
+ PartialDescriptor = &PeripheralResourceDescriptor->PartialResourceList.PartialDescriptors[i];
+
+ if(PartialDescriptor->Type != CmResourceTypeDeviceSpecific)
+ continue;
+
+ FloppyDeviceData = (PCM_FLOPPY_DEVICE_DATA)(PartialDescriptor + 1);
+
+ DriveInfo->ControllerInfo = &gControllerInfo[gNumberOfControllers];
+ DriveInfo->UnitNumber = i;
+
+ DriveInfo->FloppyDeviceData.MaxDensity = FloppyDeviceData->MaxDensity;
+ DriveInfo->FloppyDeviceData.MountDensity = FloppyDeviceData->MountDensity;
+ DriveInfo->FloppyDeviceData.StepRateHeadUnloadTime = FloppyDeviceData->StepRateHeadUnloadTime;
+ DriveInfo->FloppyDeviceData.HeadLoadTime = FloppyDeviceData->HeadLoadTime;
+ DriveInfo->FloppyDeviceData.MotorOffTime = FloppyDeviceData->MotorOffTime;
+ DriveInfo->FloppyDeviceData.SectorLengthCode = FloppyDeviceData->SectorLengthCode;
+ DriveInfo->FloppyDeviceData.SectorPerTrack = FloppyDeviceData->SectorPerTrack;
+ DriveInfo->FloppyDeviceData.ReadWriteGapLength = FloppyDeviceData->ReadWriteGapLength;
+ DriveInfo->FloppyDeviceData.FormatGapLength = FloppyDeviceData->FormatGapLength;
+ DriveInfo->FloppyDeviceData.FormatFillCharacter = FloppyDeviceData->FormatFillCharacter;
+ DriveInfo->FloppyDeviceData.HeadSettleTime = FloppyDeviceData->HeadSettleTime;
+ DriveInfo->FloppyDeviceData.MotorSettleTime = FloppyDeviceData->MotorSettleTime;
+ DriveInfo->FloppyDeviceData.MaximumTrackValue = FloppyDeviceData->MaximumTrackValue;
+ DriveInfo->FloppyDeviceData.DataTransferLength = FloppyDeviceData->DataTransferLength;
+
+ /* Once it's all set up, acknowledge its existance in the controller info object */
+ gControllerInfo[gNumberOfControllers].NumberOfDrives++;
}
- gControllerInfo[gNumberOfControllers].Populated = TRUE;
- gNumberOfControllers++;
+ gControllerInfo[gNumberOfControllers].Populated = TRUE;
+ gNumberOfControllers++;
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-static BOOLEAN NTAPI Isr(PKINTERRUPT Interrupt,
- PVOID ServiceContext)
+
+static BOOLEAN NTAPI
+Isr(PKINTERRUPT Interrupt, PVOID ServiceContext)
/*
* FUNCTION: Interrupt service routine for the controllers
* ARGUMENTS:
* - Called at DIRQL
*/
{
- PCONTROLLER_INFO ControllerInfo = (PCONTROLLER_INFO)ServiceContext;
+ PCONTROLLER_INFO ControllerInfo = (PCONTROLLER_INFO)ServiceContext;
- UNREFERENCED_PARAMETER(Interrupt);
+ UNREFERENCED_PARAMETER(Interrupt);
- ASSERT(ControllerInfo);
+ ASSERT(ControllerInfo);
- TRACE_(FLOPPY, "ISR called\n");
+ TRACE_(FLOPPY, "ISR called\n");
- /*
- * Due to the stupidity of the drive/controller relationship on the floppy drive, only one device object
- * can have an active interrupt pending. Due to the nature of these IRPs, though, there will only ever
- * be one thread expecting an interrupt at a time, and furthermore, Interrupts (outside of spurious ones)
- * won't ever happen unless a thread is expecting them. Therefore, all we have to do is signal an event
- * and we're done. Queue a DPC and leave.
- */
- KeInsertQueueDpc(&ControllerInfo->Dpc, NULL, NULL);
+ /*
+ * Due to the stupidity of the drive/controller relationship on the floppy drive, only one device object
+ * can have an active interrupt pending. Due to the nature of these IRPs, though, there will only ever
+ * be one thread expecting an interrupt at a time, and furthermore, Interrupts (outside of spurious ones)
+ * won't ever happen unless a thread is expecting them. Therefore, all we have to do is signal an event
+ * and we're done. Queue a DPC and leave.
+ */
+ KeInsertQueueDpc(&ControllerInfo->Dpc, NULL, NULL);
- return TRUE;
+ return TRUE;
}
-\f
-VOID NTAPI DpcForIsr(PKDPC UnusedDpc,
- PVOID Context,
- PVOID SystemArgument1,
- PVOID SystemArgument2)
+
+VOID NTAPI
+DpcForIsr(PKDPC UnusedDpc, PVOID Context, PVOID SystemArgument1, PVOID SystemArgument2)
/*
* FUNCTION: This DPC gets queued by every ISR. Does the real per-interrupt work.
* ARGUMENTS:
* - Called at DISPATCH_LEVEL
*/
{
- PCONTROLLER_INFO ControllerInfo = (PCONTROLLER_INFO)Context;
+ PCONTROLLER_INFO ControllerInfo = (PCONTROLLER_INFO)Context;
- UNREFERENCED_PARAMETER(UnusedDpc);
- UNREFERENCED_PARAMETER(SystemArgument1);
- UNREFERENCED_PARAMETER(SystemArgument2);
+ UNREFERENCED_PARAMETER(UnusedDpc);
+ UNREFERENCED_PARAMETER(SystemArgument1);
+ UNREFERENCED_PARAMETER(SystemArgument2);
- ASSERT(ControllerInfo);
+ ASSERT(ControllerInfo);
- TRACE_(FLOPPY, "DpcForIsr called\n");
+ TRACE_(FLOPPY, "DpcForIsr called\n");
- KeSetEvent(&ControllerInfo->SynchEvent, EVENT_INCREMENT, FALSE);
+ KeSetEvent(&ControllerInfo->SynchEvent, EVENT_INCREMENT, FALSE);
}
-\f
-static NTSTATUS NTAPI InitController(PCONTROLLER_INFO ControllerInfo)
+
+static NTSTATUS NTAPI
+InitController(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Initialize a newly-found controller
* ARGUMENTS:
* STATUS_IO_DEVICE_ERROR otherwise
*/
{
- int i;
- UCHAR HeadLoadTime;
- UCHAR HeadUnloadTime;
- UCHAR StepRateTime;
+ int i;
+ UCHAR HeadLoadTime;
+ UCHAR HeadUnloadTime;
+ UCHAR StepRateTime;
- PAGED_CODE();
- ASSERT(ControllerInfo);
+ PAGED_CODE();
+ ASSERT(ControllerInfo);
- TRACE_(FLOPPY, "InitController called with Controller 0x%p\n", ControllerInfo);
+ TRACE_(FLOPPY, "InitController called with Controller 0x%p\n", ControllerInfo);
- KeClearEvent(&ControllerInfo->SynchEvent);
+ KeClearEvent(&ControllerInfo->SynchEvent);
- INFO_(FLOPPY, "InitController: resetting the controller\n");
+ INFO_(FLOPPY, "InitController: resetting the controller\n");
- /* Reset the controller */
- if(HwReset(ControllerInfo) != STATUS_SUCCESS)
+ /* Reset the controller */
+ if(HwReset(ControllerInfo) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "InitController: unable to reset controller\n");
- return STATUS_IO_DEVICE_ERROR;
+ WARN_(FLOPPY, "InitController: unable to reset controller\n");
+ return STATUS_IO_DEVICE_ERROR;
}
- /* All controllers should support this so
- * if we get something strange back then we
- * know that this isn't a floppy controller
- */
- if (HwGetVersion(ControllerInfo) <= 0)
+ /* All controllers should support this so
+ * if we get something strange back then we
+ * know that this isn't a floppy controller
+ */
+ if (HwGetVersion(ControllerInfo) <= 0)
{
- WARN_(FLOPPY, "InitController: unable to contact controller\n");
- return STATUS_NO_SUCH_DEVICE;
+ WARN_(FLOPPY, "InitController: unable to contact controller\n");
+ return STATUS_NO_SUCH_DEVICE;
}
- /* Reset the controller to avoid interrupt garbage on certain controllers */
- if(HwReset(ControllerInfo) != STATUS_SUCCESS)
+ /* Reset the controller to avoid interrupt garbage on certain controllers */
+ if(HwReset(ControllerInfo) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "InitController: unable to reset controller #2\n");
- return STATUS_IO_DEVICE_ERROR;
+ WARN_(FLOPPY, "InitController: unable to reset controller #2\n");
+ return STATUS_IO_DEVICE_ERROR;
}
- INFO_(FLOPPY, "InitController: setting data rate\n");
+ INFO_(FLOPPY, "InitController: setting data rate\n");
- /* Set data rate */
- if(HwSetDataRate(ControllerInfo, DRSR_DSEL_500KBPS) != STATUS_SUCCESS)
+ /* Set data rate */
+ if(HwSetDataRate(ControllerInfo, DRSR_DSEL_500KBPS) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "InitController: unable to set data rate\n");
- return STATUS_IO_DEVICE_ERROR;
+ WARN_(FLOPPY, "InitController: unable to set data rate\n");
+ return STATUS_IO_DEVICE_ERROR;
}
- INFO_(FLOPPY, "InitController: waiting for initial interrupt\n");
+ INFO_(FLOPPY, "InitController: waiting for initial interrupt\n");
- /* Wait for an interrupt */
- WaitForControllerInterrupt(ControllerInfo);
+ /* Wait for an interrupt */
+ WaitForControllerInterrupt(ControllerInfo);
- /* Reset means you have to clear each of the four interrupts (one per drive) */
- for(i = 0; i < MAX_DRIVES_PER_CONTROLLER; i++)
+ /* Reset means you have to clear each of the four interrupts (one per drive) */
+ for(i = 0; i < MAX_DRIVES_PER_CONTROLLER; i++)
{
- INFO_(FLOPPY, "InitController: Sensing interrupt %d\n", i);
+ INFO_(FLOPPY, "InitController: Sensing interrupt %d\n", i);
- if(HwSenseInterruptStatus(ControllerInfo) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "InitController: Unable to clear interrupt 0x%x\n", i);
- return STATUS_IO_DEVICE_ERROR;
- }
+ if(HwSenseInterruptStatus(ControllerInfo) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "InitController: Unable to clear interrupt 0x%x\n", i);
+ return STATUS_IO_DEVICE_ERROR;
+ }
}
- INFO_(FLOPPY, "InitController: done sensing interrupts\n");
+ INFO_(FLOPPY, "InitController: done sensing interrupts\n");
- /* Next, see if we have the right version to do implied seek */
- if(HwGetVersion(ControllerInfo) == VERSION_ENHANCED)
+ /* Next, see if we have the right version to do implied seek */
+ 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)
- {
- WARN_(FLOPPY, "InitController: unable to set up implied seek\n");
- ControllerInfo->ImpliedSeeks = FALSE;
- }
- else
- {
- INFO_(FLOPPY, "InitController: implied seeks set!\n");
- ControllerInfo->ImpliedSeeks = 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;
+ /* If so, set that up -- all defaults below except first TRUE for EIS */
+ if(HwConfigure(ControllerInfo, TRUE, TRUE, FALSE, 0, 0) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "InitController: unable to set up implied seek\n");
+ ControllerInfo->ImpliedSeeks = FALSE;
+ }
+ else
+ {
+ INFO_(FLOPPY, "InitController: implied seeks set!\n");
+ ControllerInfo->ImpliedSeeks = 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
+ else
{
- INFO_(FLOPPY, "InitController: enhanced version not supported; disabling implied seeks\n");
- ControllerInfo->ImpliedSeeks = FALSE;
- ControllerInfo->Model30 = FALSE;
+ INFO_(FLOPPY, "InitController: enhanced version not supported; disabling implied seeks\n");
+ ControllerInfo->ImpliedSeeks = FALSE;
+ ControllerInfo->Model30 = FALSE;
}
- /* Specify */
- WARN_(FLOPPY, "FIXME: Figure out speed\n");
- HeadLoadTime = SPECIFY_HLT_500K;
- HeadUnloadTime = SPECIFY_HUT_500K;
- StepRateTime = SPECIFY_SRT_500K;
+ /* Specify */
+ WARN_(FLOPPY, "FIXME: Figure out speed\n");
+ HeadLoadTime = SPECIFY_HLT_500K;
+ HeadUnloadTime = SPECIFY_HUT_500K;
+ StepRateTime = SPECIFY_SRT_500K;
- INFO_(FLOPPY, "InitController: issuing specify command to controller\n");
+ INFO_(FLOPPY, "InitController: issuing specify command to controller\n");
- /* Don't disable DMA --> enable dma (dumb & confusing) */
- if(HwSpecify(ControllerInfo, HeadLoadTime, HeadUnloadTime, StepRateTime, FALSE) != STATUS_SUCCESS)
+ /* Don't disable DMA --> enable dma (dumb & confusing) */
+ if(HwSpecify(ControllerInfo, HeadLoadTime, HeadUnloadTime, StepRateTime, FALSE) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "InitController: unable to specify options\n");
- return STATUS_IO_DEVICE_ERROR;
+ WARN_(FLOPPY, "InitController: unable to specify options\n");
+ return STATUS_IO_DEVICE_ERROR;
}
- /* Init the stop stuff */
- KeInitializeDpc(&ControllerInfo->MotorStopDpc, MotorStopDpcFunc, ControllerInfo);
- KeInitializeTimer(&ControllerInfo->MotorTimer);
- KeInitializeEvent(&ControllerInfo->MotorStoppedEvent, NotificationEvent, FALSE);
- ControllerInfo->StopDpcQueued = FALSE;
-
- /*
- * 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++)
+ /* Init the stop stuff */
+ KeInitializeDpc(&ControllerInfo->MotorStopDpc, MotorStopDpcFunc, ControllerInfo);
+ KeInitializeTimer(&ControllerInfo->MotorTimer);
+ KeInitializeEvent(&ControllerInfo->MotorStoppedEvent, NotificationEvent, FALSE);
+ ControllerInfo->StopDpcQueued = FALSE;
+
+ /*
+ * 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++)
{
- INFO_(FLOPPY, "InitController: recalibrating drive 0x%x on controller 0x%p\n", i, ControllerInfo);
- Recalibrate(&ControllerInfo->DriveInfo[i]);
+ INFO_(FLOPPY, "InitController: recalibrating drive 0x%x on controller 0x%p\n", i, ControllerInfo);
+ Recalibrate(&ControllerInfo->DriveInfo[i]);
}
- INFO_(FLOPPY, "InitController: done initializing; returning STATUS_SUCCESS\n");
+ INFO_(FLOPPY, "InitController: done initializing; returning STATUS_SUCCESS\n");
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-static BOOLEAN NTAPI AddControllers(PDRIVER_OBJECT DriverObject)
+
+static BOOLEAN NTAPI
+AddControllers(PDRIVER_OBJECT DriverObject)
/*
* FUNCTION: Called on initialization to find our controllers and build device and controller objects for them
* ARGUMENTS:
* - Report resource usage to the HAL
*/
{
- INTERFACE_TYPE InterfaceType = Isa;
- CONFIGURATION_TYPE ControllerType = DiskController;
- CONFIGURATION_TYPE PeripheralType = FloppyDiskPeripheral;
- KAFFINITY Affinity;
- DEVICE_DESCRIPTION DeviceDescription;
- UCHAR i;
- UCHAR j;
-
- PAGED_CODE();
-
- /* Find our controllers on all ISA buses */
- IoQueryDeviceDescription(&InterfaceType, 0, &ControllerType, 0, &PeripheralType, 0, ConfigCallback, 0);
-
- /*
- * w2k breaks the return val from ConfigCallback, so we have to hack around it, rather than just
- * looking for a return value from ConfigCallback. We expect at least one controller.
- */
- if(!gControllerInfo[0].Populated)
+ INTERFACE_TYPE InterfaceType = Isa;
+ CONFIGURATION_TYPE ControllerType = DiskController;
+ CONFIGURATION_TYPE PeripheralType = FloppyDiskPeripheral;
+ KAFFINITY Affinity;
+ DEVICE_DESCRIPTION DeviceDescription;
+ UCHAR i;
+ UCHAR j;
+
+ PAGED_CODE();
+
+ /* Find our controllers on all ISA buses */
+ IoQueryDeviceDescription(&InterfaceType, 0, &ControllerType, 0, &PeripheralType, 0, ConfigCallback, 0);
+
+ /*
+ * w2k breaks the return val from ConfigCallback, so we have to hack around it, rather than just
+ * looking for a return value from ConfigCallback. We expect at least one controller.
+ */
+ if(!gControllerInfo[0].Populated)
{
- WARN_(FLOPPY, "AddControllers: failed to get controller info from registry\n");
- return FALSE;
+ WARN_(FLOPPY, "AddControllers: failed to get controller info from registry\n");
+ return FALSE;
}
- /* Now that we have a controller, set it up with the system */
- for(i = 0; i < gNumberOfControllers; i++)
+ /* Now that we have a controller, set it up with the system */
+ for(i = 0; i < gNumberOfControllers; i++)
{
- /* 0: Report resource usage to the kernel, to make sure they aren't assigned to anyone else */
- /* FIXME: Implement me. */
+ /* 0: Report resource usage to the kernel, to make sure they aren't assigned to anyone else */
+ /* FIXME: Implement me. */
- /* 1: Set up interrupt */
- gControllerInfo[i].MappedVector = HalGetInterruptVector(gControllerInfo[i].InterfaceType, gControllerInfo[i].BusNumber,
- gControllerInfo[i].Level, gControllerInfo[i].Vector,
- &gControllerInfo[i].MappedLevel, &Affinity);
+ /* 1: Set up interrupt */
+ gControllerInfo[i].MappedVector = HalGetInterruptVector(gControllerInfo[i].InterfaceType, gControllerInfo[i].BusNumber,
+ gControllerInfo[i].Level, gControllerInfo[i].Vector,
+ &gControllerInfo[i].MappedLevel, &Affinity);
- /* Must set up the DPC before we connect the interrupt */
- KeInitializeDpc(&gControllerInfo[i].Dpc, DpcForIsr, &gControllerInfo[i]);
+ /* Must set up the DPC before we connect the interrupt */
+ KeInitializeDpc(&gControllerInfo[i].Dpc, DpcForIsr, &gControllerInfo[i]);
- INFO_(FLOPPY, "Connecting interrupt %d to controller%d (object 0x%p)\n", gControllerInfo[i].MappedVector,
- i, &gControllerInfo[i]);
+ INFO_(FLOPPY, "Connecting interrupt %d to controller%d (object 0x%p)\n", gControllerInfo[i].MappedVector,
+ i, &gControllerInfo[i]);
- /* NOTE: We cannot share our interrupt, even on level-triggered buses. See Isr() for details. */
- if(IoConnectInterrupt(&gControllerInfo[i].InterruptObject, Isr, &gControllerInfo[i], 0, gControllerInfo[i].MappedVector,
- gControllerInfo[i].MappedLevel, gControllerInfo[i].MappedLevel, gControllerInfo[i].InterruptMode,
- FALSE, Affinity, 0) != STATUS_SUCCESS)
+ /* NOTE: We cannot share our interrupt, even on level-triggered buses. See Isr() for details. */
+ if(IoConnectInterrupt(&gControllerInfo[i].InterruptObject, Isr, &gControllerInfo[i], 0, gControllerInfo[i].MappedVector,
+ gControllerInfo[i].MappedLevel, gControllerInfo[i].MappedLevel, gControllerInfo[i].InterruptMode,
+ FALSE, Affinity, 0) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "AddControllers: unable to connect interrupt\n");
- continue;
+ WARN_(FLOPPY, "AddControllers: unable to connect interrupt\n");
+ continue;
}
- /* 2: Set up DMA */
- memset(&DeviceDescription, 0, sizeof(DeviceDescription));
- DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
- DeviceDescription.DmaChannel = gControllerInfo[i].Dma;
- DeviceDescription.InterfaceType = gControllerInfo[i].InterfaceType;
- DeviceDescription.BusNumber = gControllerInfo[i].BusNumber;
- DeviceDescription.MaximumLength = 2*18*512; /* based on a 1.44MB floppy */
+ /* 2: Set up DMA */
+ memset(&DeviceDescription, 0, sizeof(DeviceDescription));
+ DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
+ DeviceDescription.DmaChannel = gControllerInfo[i].Dma;
+ DeviceDescription.InterfaceType = gControllerInfo[i].InterfaceType;
+ DeviceDescription.BusNumber = gControllerInfo[i].BusNumber;
+ DeviceDescription.MaximumLength = 2*18*512; /* based on a 1.44MB floppy */
- /* 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);
+ gControllerInfo[i].AdapterObject = HalGetAdapter(&DeviceDescription, &gControllerInfo[i].MapRegisters);
- if(!gControllerInfo[i].AdapterObject)
+ if(!gControllerInfo[i].AdapterObject)
{
- WARN_(FLOPPY, "AddControllers: unable to allocate an adapter object\n");
- IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
- continue;
+ WARN_(FLOPPY, "AddControllers: unable to allocate an adapter object\n");
+ IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
+ continue;
}
- /* 2b: Initialize the new controller */
- if(InitController(&gControllerInfo[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "AddControllers(): Unable to set up controller %d - initialization failed\n", i);
- IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
- continue;
- }
+ /* 2b: Initialize the new controller */
+ if(InitController(&gControllerInfo[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "AddControllers(): Unable to set up controller %d - initialization failed\n", i);
+ IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
+ continue;
+ }
- /* 2c: Set the controller's initlized flag so we know to release stuff in Unload */
- gControllerInfo[i].Initialized = TRUE;
+ /* 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++)
+ /* 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;
-
- INFO_(FLOPPY, "AddControllers(): Configuring drive %d on controller %d\n", i, j);
-
- /*
- * 3a: create a device object for the drive
- * Controllers and drives are 0-based, so the combos are:
- * 0: 0,0
- * 1: 0,1
- * 2: 0,2
- * 3: 0,3
- * 4: 1,0
- * 5: 1,1
- * ...
- * 14: 3,2
- * 15: 3,3
- */
-
- DriveNumber = (UCHAR)(i*4 + j); /* loss of precision is OK; there are only 16 of 'em */
-
- RtlZeroMemory(&DeviceNameBuf, MAX_DEVICE_NAME * sizeof(WCHAR));
- swprintf(DeviceNameBuf, L"\\Device\\Floppy%d", DriveNumber);
- RtlInitUnicodeString(&DeviceName, DeviceNameBuf);
-
- if(IoCreateDevice(DriverObject, sizeof(PVOID), &DeviceName,
- FILE_DEVICE_DISK, FILE_REMOVABLE_MEDIA | FILE_FLOPPY_DISKETTE, FALSE,
- &gControllerInfo[i].DriveInfo[j].DeviceObject) != STATUS_SUCCESS)
+ WCHAR DeviceNameBuf[MAX_DEVICE_NAME];
+ UNICODE_STRING DeviceName;
+ UNICODE_STRING LinkName;
+ UNICODE_STRING ArcPath;
+ UCHAR DriveNumber;
+
+ INFO_(FLOPPY, "AddControllers(): Configuring drive %d on controller %d\n", i, j);
+
+ /*
+ * 3a: create a device object for the drive
+ * Controllers and drives are 0-based, so the combos are:
+ * 0: 0,0
+ * 1: 0,1
+ * 2: 0,2
+ * 3: 0,3
+ * 4: 1,0
+ * 5: 1,1
+ * ...
+ * 14: 3,2
+ * 15: 3,3
+ */
+
+ DriveNumber = (UCHAR)(i*4 + j); /* loss of precision is OK; there are only 16 of 'em */
+
+ RtlZeroMemory(&DeviceNameBuf, MAX_DEVICE_NAME * sizeof(WCHAR));
+ swprintf(DeviceNameBuf, L"\\Device\\Floppy%d", DriveNumber);
+ RtlInitUnicodeString(&DeviceName, DeviceNameBuf);
+
+ if(IoCreateDevice(DriverObject, sizeof(PVOID), &DeviceName,
+ FILE_DEVICE_DISK, FILE_REMOVABLE_MEDIA | FILE_FLOPPY_DISKETTE, FALSE,
+ &gControllerInfo[i].DriveInfo[j].DeviceObject) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "AddControllers: unable to register a Device object\n");
- IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
- continue; /* continue on to next drive */
+ WARN_(FLOPPY, "AddControllers: unable to register a Device object\n");
+ IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
+ continue; /* continue on to next drive */
}
- INFO_(FLOPPY, "AddControllers: New device: %S (0x%p)\n", DeviceNameBuf, gControllerInfo[i].DriveInfo[j].DeviceObject);
+ INFO_(FLOPPY, "AddControllers: New device: %S (0x%p)\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);
+ /* 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);
+ RtlInitUnicodeString(&ArcPath, gControllerInfo[i].DriveInfo[j].ArcPathBuffer);
+ IoAssignArcName(&ArcPath, &DeviceName);
- /* 3c: Set flags up */
- gControllerInfo[i].DriveInfo[j].DeviceObject->Flags |= DO_DIRECT_IO;
+ /* 3c: Set flags up */
+ gControllerInfo[i].DriveInfo[j].DeviceObject->Flags |= DO_DIRECT_IO;
- /* 3d: Create a symlink */
- swprintf(gControllerInfo[i].DriveInfo[j].SymLinkBuffer, L"\\DosDevices\\%c:", DriveNumber + 'A');
- RtlInitUnicodeString(&LinkName, gControllerInfo[i].DriveInfo[j].SymLinkBuffer);
- if(IoCreateSymbolicLink(&LinkName, &DeviceName) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "AddControllers: Unable to create a symlink for drive %d\n", DriveNumber);
- IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
- IoDeassignArcName(&ArcPath);
- continue; /* continue to next drive */
- }
+ /* 3d: Create a symlink */
+ swprintf(gControllerInfo[i].DriveInfo[j].SymLinkBuffer, L"\\DosDevices\\%c:", DriveNumber + 'A');
+ RtlInitUnicodeString(&LinkName, gControllerInfo[i].DriveInfo[j].SymLinkBuffer);
+ if(IoCreateSymbolicLink(&LinkName, &DeviceName) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "AddControllers: Unable to create a symlink for drive %d\n", DriveNumber);
+ IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
+ IoDeassignArcName(&ArcPath);
+ continue; /* continue to next drive */
+ }
- /* 3e: Increase global floppy drives count */
- IoGetConfigurationInformation()->FloppyCount++;
+ /* 3e: Increase global floppy drives count */
+ IoGetConfigurationInformation()->FloppyCount++;
- /* 3f: Set up the DPC */
- IoInitializeDpcRequest(gControllerInfo[i].DriveInfo[j].DeviceObject, (PIO_DPC_ROUTINE)DpcForIsr);
+ /* 3f: Set up the DPC */
+ IoInitializeDpcRequest(gControllerInfo[i].DriveInfo[j].DeviceObject, (PIO_DPC_ROUTINE)DpcForIsr);
- /* 3g: Point the device extension at our DriveInfo struct */
- gControllerInfo[i].DriveInfo[j].DeviceObject->DeviceExtension = &gControllerInfo[i].DriveInfo[j];
+ /* 3g: Point the device extension at our DriveInfo struct */
+ gControllerInfo[i].DriveInfo[j].DeviceObject->DeviceExtension = &gControllerInfo[i].DriveInfo[j];
- /* 3h: neat comic strip */
+ /* 3h: neat comic strip */
- /* 3i: 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: set the initial media type to unknown */
+ memset(&gControllerInfo[i].DriveInfo[j].DiskGeometry, 0, sizeof(DISK_GEOMETRY));
+ gControllerInfo[i].DriveInfo[j].DiskGeometry.MediaType = Unknown;
- /* 3j: Now that we're done, set the Initialized flag so we know to free this in Unload */
- gControllerInfo[i].DriveInfo[j].Initialized = TRUE;
+ /* 3j: Now that we're done, set the Initialized flag so we know to free this in Unload */
+ gControllerInfo[i].DriveInfo[j].Initialized = TRUE;
- /* 3k: Clear the DO_DEVICE_INITIALIZING flag */
- gControllerInfo[i].DriveInfo[j].DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+ /* 3k: Clear the DO_DEVICE_INITIALIZING flag */
+ gControllerInfo[i].DriveInfo[j].DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
}
}
- INFO_(FLOPPY, "AddControllers: --------------------------------------------> finished adding controllers\n");
+ INFO_(FLOPPY, "AddControllers: --------------------------------------------> finished adding controllers\n");
- return TRUE;
+ return TRUE;
}
-\f
-VOID NTAPI SignalMediaChanged(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+
+VOID NTAPI
+SignalMediaChanged(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Process an IRP when the media has changed, and possibly notify the user
* ARGUMENTS:
* - Callable at <= DISPATCH_LEVEL
*/
{
- PDRIVE_INFO DriveInfo = DeviceObject->DeviceExtension;
+ PDRIVE_INFO DriveInfo = DeviceObject->DeviceExtension;
- TRACE_(FLOPPY, "SignalMediaChanged called\n");
+ TRACE_(FLOPPY, "SignalMediaChanged called\n");
- DriveInfo->DiskChangeCount++;
+ DriveInfo->DiskChangeCount++;
- /* If volume is not mounted, do NOT set verify and return STATUS_IO_DEVICE_ERROR */
- if(!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
+ /* If volume is not mounted, do NOT set verify and return STATUS_IO_DEVICE_ERROR */
+ if(!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
{
- Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
- Irp->IoStatus.Information = 0;
- return;
+ Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
+ Irp->IoStatus.Information = 0;
+ return;
}
- /* Notify the filesystem that it will need to verify the volume */
- DeviceObject->Flags |= DO_VERIFY_VOLUME;
- Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
- Irp->IoStatus.Information = 0;
-
- /*
- * If this is a user-based, threaded request, let the IO manager know to pop up a box asking
- * the user to supply the correct media, but only if the error (which we just picked out above)
- * is deemed by the IO manager to be "user induced". The reason we don't just unconditionally
- * call IoSetHardError... is because MS might change the definition of "user induced" some day,
- * and we don't want to have to remember to re-code this.
- */
- if(Irp->Tail.Overlay.Thread && IoIsErrorUserInduced(Irp->IoStatus.Status))
- IoSetHardErrorOrVerifyDevice(Irp, DeviceObject);
+ /* Notify the filesystem that it will need to verify the volume */
+ DeviceObject->Flags |= DO_VERIFY_VOLUME;
+ Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
+ Irp->IoStatus.Information = 0;
+
+ /*
+ * If this is a user-based, threaded request, let the IO manager know to pop up a box asking
+ * the user to supply the correct media, but only if the error (which we just picked out above)
+ * is deemed by the IO manager to be "user induced". The reason we don't just unconditionally
+ * call IoSetHardError... is because MS might change the definition of "user induced" some day,
+ * and we don't want to have to remember to re-code this.
+ */
+ if(Irp->Tail.Overlay.Thread && IoIsErrorUserInduced(Irp->IoStatus.Status))
+ IoSetHardErrorOrVerifyDevice(Irp, DeviceObject);
}
-\f
-static VOID NTAPI QueueThread(PVOID Context)
+
+static VOID NTAPI
+QueueThread(PVOID Context)
/*
* FUNCTION: Thread that manages the queue and dispatches any queued requests
* ARGUMENTS:
* Context: unused
*/
{
- PIRP Irp;
- PIO_STACK_LOCATION Stack;
- PDEVICE_OBJECT DeviceObject;
- PVOID Objects[2];
+ PIRP Irp;
+ PIO_STACK_LOCATION Stack;
+ PDEVICE_OBJECT DeviceObject;
+ PVOID Objects[2];
- PAGED_CODE();
- UNREFERENCED_PARAMETER(Context);
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(Context);
- Objects[0] = &QueueSemaphore;
- Objects[1] = &QueueThreadTerminate;
+ Objects[0] = &QueueSemaphore;
+ Objects[1] = &QueueThreadTerminate;
- for(;;)
+ for(;;)
{
- KeWaitForMultipleObjects(2, Objects, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);
+ KeWaitForMultipleObjects(2, Objects, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);
- if(KeReadStateEvent(&QueueThreadTerminate))
- {
- INFO_(FLOPPY, "QueueThread terminating\n");
- return;
- }
-
- INFO_(FLOPPY, "QueueThread: servicing an IRP\n");
-
- Irp = IoCsqRemoveNextIrp(&Csq, 0);
+ if(KeReadStateEvent(&QueueThreadTerminate))
+ {
+ INFO_(FLOPPY, "QueueThread terminating\n");
+ return;
+ }
- /* we won't get an irp if it was canceled */
- if(!Irp)
- {
- INFO_(FLOPPY, "QueueThread: IRP queue empty\n");
- continue;
- }
+ INFO_(FLOPPY, "QueueThread: servicing an IRP\n");
- DeviceObject = (PDEVICE_OBJECT)Irp->Tail.Overlay.DriverContext[0];
+ Irp = IoCsqRemoveNextIrp(&Csq, 0);
- ASSERT(DeviceObject);
+ /* we won't get an irp if it was canceled */
+ if(!Irp)
+ {
+ INFO_(FLOPPY, "QueueThread: IRP queue empty\n");
+ continue;
+ }
- Stack = IoGetCurrentIrpStackLocation(Irp);
+ DeviceObject = (PDEVICE_OBJECT)Irp->Tail.Overlay.DriverContext[0];
- /* Decide what to do with the IRP */
- switch(Stack->MajorFunction)
- {
- case IRP_MJ_READ:
- case IRP_MJ_WRITE:
- ReadWritePassive(DeviceObject->DeviceExtension, Irp);
- break;
+ ASSERT(DeviceObject);
- case IRP_MJ_DEVICE_CONTROL:
- DeviceIoctlPassive(DeviceObject->DeviceExtension, Irp);
- break;
+ Stack = IoGetCurrentIrpStackLocation(Irp);
- default:
- WARN_(FLOPPY, "QueueThread(): Unrecognized irp: mj: 0x%x\n", Stack->MajorFunction);
- Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- }
+ /* Decide what to do with the IRP */
+ switch(Stack->MajorFunction)
+ {
+ case IRP_MJ_READ:
+ case IRP_MJ_WRITE:
+ ReadWritePassive(DeviceObject->DeviceExtension, Irp);
+ break;
+
+ case IRP_MJ_DEVICE_CONTROL:
+ DeviceIoctlPassive(DeviceObject->DeviceExtension, Irp);
+ break;
+
+ default:
+ WARN_(FLOPPY, "QueueThread(): Unrecognized irp: mj: 0x%x\n", Stack->MajorFunction);
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ }
}
}
-\f
-NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject,
- PUNICODE_STRING RegistryPath)
+
+NTSTATUS NTAPI
+DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Entry-point for the driver
* ARGUMENTS:
* STATUS_UNSUCCESSFUL otherwise
*/
{
- HANDLE ThreadHandle;
-
- UNREFERENCED_PARAMETER(RegistryPath);
-
- /*
- * Set up dispatch routines
- */
- DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)CreateClose;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)CreateClose;
- DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)ReadWrite;
- DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH)ReadWrite;
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)DeviceIoctl;
-
- DriverObject->DriverUnload = Unload;
-
- /*
- * We depend on some zeroes in these structures. I know this is supposed to be
- * initialized to 0 by the complier but this makes me feel beter.
- */
- memset(&gControllerInfo, 0, sizeof(gControllerInfo));
-
- /*
- * Set up queue. This routine cannot fail (trust me, I wrote it).
- */
- IoCsqInitialize(&Csq, CsqInsertIrp, CsqRemoveIrp, CsqPeekNextIrp,
- CsqAcquireLock, CsqReleaseLock, CsqCompleteCanceledIrp);
-
- /*
- * ...and its lock
- */
- KeInitializeSpinLock(&IrpQueueLock);
-
- /*
- * ...and the queue list itself
- */
- InitializeListHead(&IrpQueue);
-
- /*
- * The queue is counted by a semaphore. The queue management thread
- * blocks on this semaphore, so if requests come in faster than the queue
- * thread can handle them, the semaphore count goes up.
- */
- KeInitializeSemaphore(&QueueSemaphore, 0, 0x7fffffff);
-
- /*
- * Event to terminate that thread
- */
- KeInitializeEvent(&QueueThreadTerminate, NotificationEvent, FALSE);
-
- /*
- * Create the queue processing thread. Save its handle in the global variable
- * ThreadHandle so we can wait on its termination during Unload.
- */
- if(PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, 0, 0, 0, QueueThread, 0) != STATUS_SUCCESS)
+ HANDLE ThreadHandle;
+
+ UNREFERENCED_PARAMETER(RegistryPath);
+
+ /*
+ * Set up dispatch routines
+ */
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)CreateClose;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)CreateClose;
+ DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)ReadWrite;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH)ReadWrite;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)DeviceIoctl;
+
+ DriverObject->DriverUnload = Unload;
+
+ /*
+ * We depend on some zeroes in these structures. I know this is supposed to be
+ * initialized to 0 by the complier but this makes me feel beter.
+ */
+ memset(&gControllerInfo, 0, sizeof(gControllerInfo));
+
+ /*
+ * Set up queue. This routine cannot fail (trust me, I wrote it).
+ */
+ IoCsqInitialize(&Csq, CsqInsertIrp, CsqRemoveIrp, CsqPeekNextIrp,
+ CsqAcquireLock, CsqReleaseLock, CsqCompleteCanceledIrp);
+
+ /*
+ * ...and its lock
+ */
+ KeInitializeSpinLock(&IrpQueueLock);
+
+ /*
+ * ...and the queue list itself
+ */
+ InitializeListHead(&IrpQueue);
+
+ /*
+ * The queue is counted by a semaphore. The queue management thread
+ * blocks on this semaphore, so if requests come in faster than the queue
+ * thread can handle them, the semaphore count goes up.
+ */
+ KeInitializeSemaphore(&QueueSemaphore, 0, 0x7fffffff);
+
+ /*
+ * Event to terminate that thread
+ */
+ KeInitializeEvent(&QueueThreadTerminate, NotificationEvent, FALSE);
+
+ /*
+ * Create the queue processing thread. Save its handle in the global variable
+ * ThreadHandle so we can wait on its termination during Unload.
+ */
+ if(PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, 0, 0, 0, QueueThread, 0) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "Unable to create system thread; failing init\n");
- return STATUS_INSUFFICIENT_RESOURCES;
+ WARN_(FLOPPY, "Unable to create system thread; failing init\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
}
- if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, NULL, KernelMode, &QueueThreadObject, NULL) != STATUS_SUCCESS)
+ if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, NULL, KernelMode, &QueueThreadObject, NULL) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "Unable to reference returned thread handle; failing init\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "Unable to reference returned thread handle; failing init\n");
+ 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);
-
- /*
- * 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;
-
- return STATUS_SUCCESS;
+ /*
+ * 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);
+
+ /*
+ * 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;
+
+ return STATUS_SUCCESS;
}
typedef struct _DRIVE_INFO
{
- struct _CONTROLLER_INFO *ControllerInfo;
- UCHAR UnitNumber; /* 0,1,2,3 */
- LARGE_INTEGER MotorStartTime;
- PDEVICE_OBJECT DeviceObject;
- CM_FLOPPY_DEVICE_DATA FloppyDeviceData;
- DISK_GEOMETRY DiskGeometry;
- UCHAR BytesPerSectorCode;
- WCHAR SymLinkBuffer[MAX_DEVICE_NAME];
- WCHAR ArcPathBuffer[MAX_ARC_PATH_LEN];
- ULONG DiskChangeCount;
- BOOLEAN Initialized;
+ struct _CONTROLLER_INFO *ControllerInfo;
+ UCHAR UnitNumber; /* 0,1,2,3 */
+ LARGE_INTEGER MotorStartTime;
+ PDEVICE_OBJECT DeviceObject;
+ CM_FLOPPY_DEVICE_DATA FloppyDeviceData;
+ 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;
- ULONG Level;
- KIRQL MappedLevel;
- ULONG Vector;
- ULONG MappedVector;
- KINTERRUPT_MODE InterruptMode;
- PUCHAR BaseAddress;
- ULONG Dma;
- ULONG MapRegisters;
- PVOID MapRegisterBase;
- BOOLEAN Master;
- KEVENT SynchEvent;
- KDPC Dpc;
- PKINTERRUPT InterruptObject;
- PADAPTER_OBJECT AdapterObject;
- UCHAR NumberOfDrives;
- BOOLEAN ImpliedSeeks;
- DRIVE_INFO DriveInfo[MAX_DRIVES_PER_CONTROLLER];
- PDRIVE_INFO CurrentDrive;
- BOOLEAN Model30;
- KEVENT MotorStoppedEvent;
- KTIMER MotorTimer;
- KDPC MotorStopDpc;
- BOOLEAN StopDpcQueued;
+ BOOLEAN Populated;
+ BOOLEAN Initialized;
+ ULONG ControllerNumber;
+ INTERFACE_TYPE InterfaceType;
+ ULONG BusNumber;
+ ULONG Level;
+ KIRQL MappedLevel;
+ ULONG Vector;
+ ULONG MappedVector;
+ KINTERRUPT_MODE InterruptMode;
+ PUCHAR BaseAddress;
+ ULONG Dma;
+ ULONG MapRegisters;
+ PVOID MapRegisterBase;
+ BOOLEAN Master;
+ KEVENT SynchEvent;
+ KDPC Dpc;
+ PKINTERRUPT InterruptObject;
+ PADAPTER_OBJECT AdapterObject;
+ UCHAR NumberOfDrives;
+ BOOLEAN ImpliedSeeks;
+ DRIVE_INFO DriveInfo[MAX_DRIVES_PER_CONTROLLER];
+ PDRIVE_INFO CurrentDrive;
+ BOOLEAN Model30;
+ KEVENT MotorStoppedEvent;
+ KTIMER MotorTimer;
+ KDPC MotorStopDpc;
+ BOOLEAN StopDpcQueued;
} CONTROLLER_INFO, *PCONTROLLER_INFO;
-NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject,
- PUNICODE_STRING RegistryPath);
+NTSTATUS NTAPI
+DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
-VOID NTAPI SignalMediaChanged(PDEVICE_OBJECT DeviceObject,
- PIRP Irp);
+VOID NTAPI
+SignalMediaChanged(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-VOID NTAPI WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo);
+VOID NTAPI
+WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo);
-NTSTATUS NTAPI ResetChangeFlag(PDRIVE_INFO DriveInfo);
+NTSTATUS NTAPI
+ResetChangeFlag(PDRIVE_INFO DriveInfo);
-VOID NTAPI StartMotor(PDRIVE_INFO DriveInfo);
+VOID NTAPI
+StartMotor(PDRIVE_INFO DriveInfo);
-VOID NTAPI StopMotor(PCONTROLLER_INFO ControllerInfo);
+VOID NTAPI
+StopMotor(PCONTROLLER_INFO ControllerInfo);
/*
* MEDIA TYPES
* Hardware Support Routines
*/
-\f
-static BOOLEAN NTAPI ReadyForWrite(PCONTROLLER_INFO ControllerInfo)
+
+static BOOLEAN NTAPI
+ReadyForWrite(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Determine of the controller is ready to accept a byte on the FIFO
* ARGUMENTS:
* and that the "ready for i/o" bit is set.
*/
{
- UCHAR Status = READ_PORT_UCHAR(ControllerInfo->BaseAddress + MAIN_STATUS_REGISTER);
+ UCHAR Status = READ_PORT_UCHAR(ControllerInfo->BaseAddress + MAIN_STATUS_REGISTER);
- if(Status & MSR_IO_DIRECTION) /* 0 for out */
- return FALSE;
+ if(Status & MSR_IO_DIRECTION) /* 0 for out */
+ return FALSE;
- if(!(Status & MSR_DATA_REG_READY_FOR_IO))
- return FALSE;
+ if(!(Status & MSR_DATA_REG_READY_FOR_IO))
+ return FALSE;
- return TRUE;
+ return TRUE;
}
-\f
-static BOOLEAN NTAPI ReadyForRead(PCONTROLLER_INFO ControllerInfo)
+
+static BOOLEAN NTAPI
+ReadyForRead(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Determine of the controller is ready to read a byte on the FIFO
* ARGUMENTS:
* and that the "ready for i/o" bit is set.
*/
{
- UCHAR Status = READ_PORT_UCHAR(ControllerInfo->BaseAddress + MAIN_STATUS_REGISTER);
+ UCHAR Status = READ_PORT_UCHAR(ControllerInfo->BaseAddress + MAIN_STATUS_REGISTER);
- if(!(Status & MSR_IO_DIRECTION)) /* Read = 1 */
- return FALSE;
+ if(!(Status & MSR_IO_DIRECTION)) /* Read = 1 */
+ return FALSE;
- if(!(Status & MSR_DATA_REG_READY_FOR_IO))
- return FALSE;
+ if(!(Status & MSR_DATA_REG_READY_FOR_IO))
+ return FALSE;
- return TRUE;
+ return TRUE;
}
-\f
-static NTSTATUS NTAPI Send_Byte(PCONTROLLER_INFO ControllerInfo,
- UCHAR Byte)
+
+static NTSTATUS NTAPI
+Send_Byte(PCONTROLLER_INFO ControllerInfo, UCHAR Byte)
/*
* FUNCTION: Send a byte from the host to the controller's FIFO
* ARGUMENTS:
* and isn't yet ready to read or write the next byte
*/
{
- int i;
+ int i;
- PAGED_CODE();
+ PAGED_CODE();
- for(i = 0; i < 5; i++)
+ for(i = 0; i < 5; i++)
{
- if(ReadyForWrite(ControllerInfo))
- break;
+ if(ReadyForWrite(ControllerInfo))
+ break;
- KeStallExecutionProcessor(50);
+ KeStallExecutionProcessor(50);
}
- if (i < 5)
- {
- WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + FIFO, Byte);
- return STATUS_SUCCESS;
- }
- else
- {
- INFO_(FLOPPY, "Send_Byte: timed out trying to write\n");
- HwDumpRegisters(ControllerInfo);
- return STATUS_UNSUCCESSFUL;
- }
+ if (i < 5)
+ {
+ WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + FIFO, Byte);
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ INFO_(FLOPPY, "Send_Byte: timed out trying to write\n");
+ HwDumpRegisters(ControllerInfo);
+ return STATUS_UNSUCCESSFUL;
+ }
}
-\f
-static NTSTATUS NTAPI Get_Byte(PCONTROLLER_INFO ControllerInfo,
- PUCHAR Byte)
+
+static NTSTATUS NTAPI
+Get_Byte(PCONTROLLER_INFO ControllerInfo, PUCHAR Byte)
/*
* FUNCTION: Read a byte from the controller to the host
* ARGUMENTS:
* - PAGED_CODE because we spin for longer than Microsoft recommends
*/
{
- int i;
+ int i;
- PAGED_CODE();
+ PAGED_CODE();
- for(i = 0; i < 5; i++)
+ for(i = 0; i < 5; i++)
{
- if(ReadyForRead(ControllerInfo))
- break;
+ if(ReadyForRead(ControllerInfo))
+ break;
- KeStallExecutionProcessor(50);
+ KeStallExecutionProcessor(50);
}
- if (i < 5)
- {
- *Byte = READ_PORT_UCHAR(ControllerInfo->BaseAddress + FIFO);
- return STATUS_SUCCESS;
- }
- else
- {
- INFO_(FLOPPY, "Get_Byte: timed out trying to write\n");
- HwDumpRegisters(ControllerInfo);
- return STATUS_UNSUCCESSFUL;
- }
+ if (i < 5)
+ {
+ *Byte = READ_PORT_UCHAR(ControllerInfo->BaseAddress + FIFO);
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ INFO_(FLOPPY, "Get_Byte: timed out trying to write\n");
+ HwDumpRegisters(ControllerInfo);
+ return STATUS_UNSUCCESSFUL;
+ }
}
-\f
-NTSTATUS NTAPI HwSetDataRate(PCONTROLLER_INFO ControllerInfo,
- UCHAR DataRate)
+
+NTSTATUS NTAPI
+HwSetDataRate(PCONTROLLER_INFO ControllerInfo, UCHAR DataRate)
/*
* FUNCTION: Set the data rte on a controller
* ARGUMENTS:
* STATUS_SUCCESS
*/
{
- TRACE_(FLOPPY, "HwSetDataRate called; writing rate code 0x%x to offset 0x%x\n", DataRate, DATA_RATE_SELECT_REGISTER);
+ TRACE_(FLOPPY, "HwSetDataRate called; writing rate code 0x%x to offset 0x%x\n", DataRate, DATA_RATE_SELECT_REGISTER);
- WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DATA_RATE_SELECT_REGISTER, DataRate);
+ WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DATA_RATE_SELECT_REGISTER, DataRate);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwTurnOffMotor(PCONTROLLER_INFO ControllerInfo)
+
+NTSTATUS NTAPI
+HwTurnOffMotor(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Turn off all motors
* ARGUMENTS:
* - Called at DISPATCH_LEVEL
*/
{
- TRACE_(FLOPPY, "HwTurnOffMotor: writing byte 0x%x to offset 0x%x\n", DOR_FDC_ENABLE|DOR_DMA_IO_INTERFACE_ENABLE, DIGITAL_OUTPUT_REGISTER);
+ TRACE_(FLOPPY, "HwTurnOffMotor: writing byte 0x%x to offset 0x%x\n", DOR_FDC_ENABLE|DOR_DMA_IO_INTERFACE_ENABLE, DIGITAL_OUTPUT_REGISTER);
- WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER, DOR_FDC_ENABLE|DOR_DMA_IO_INTERFACE_ENABLE);
+ WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER, DOR_FDC_ENABLE|DOR_DMA_IO_INTERFACE_ENABLE);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwTurnOnMotor(PDRIVE_INFO DriveInfo)
+
+NTSTATUS NTAPI
+HwTurnOnMotor(PDRIVE_INFO DriveInfo)
/*
* FUNCTION: Turn on the motor on the selected drive
* ARGUMENTS:
* - Currently cannot fail
*/
{
- PCONTROLLER_INFO ControllerInfo = DriveInfo->ControllerInfo;
- UCHAR Unit = DriveInfo->UnitNumber;
- UCHAR Buffer;
+ PCONTROLLER_INFO ControllerInfo = DriveInfo->ControllerInfo;
+ UCHAR Unit = DriveInfo->UnitNumber;
+ UCHAR Buffer;
- PAGED_CODE();
+ PAGED_CODE();
- /* turn on motor */
- Buffer = Unit;
+ /* turn on motor */
+ Buffer = Unit;
- Buffer |= DOR_FDC_ENABLE;
- Buffer |= DOR_DMA_IO_INTERFACE_ENABLE;
+ Buffer |= DOR_FDC_ENABLE;
+ Buffer |= DOR_DMA_IO_INTERFACE_ENABLE;
- if(Unit == 0)
- Buffer |= DOR_FLOPPY_MOTOR_ON_A;
- else if (Unit == 1)
- Buffer |= DOR_FLOPPY_MOTOR_ON_B;
- else if (Unit == 2)
- Buffer |= DOR_FLOPPY_MOTOR_ON_C;
- else if (Unit == 3)
- Buffer |= DOR_FLOPPY_MOTOR_ON_D;
+ if(Unit == 0)
+ Buffer |= DOR_FLOPPY_MOTOR_ON_A;
+ else if (Unit == 1)
+ Buffer |= DOR_FLOPPY_MOTOR_ON_B;
+ else if (Unit == 2)
+ Buffer |= DOR_FLOPPY_MOTOR_ON_C;
+ else if (Unit == 3)
+ Buffer |= DOR_FLOPPY_MOTOR_ON_D;
- TRACE_(FLOPPY, "HwTurnOnMotor: writing byte 0x%x to offset 0x%x\n", Buffer, DIGITAL_OUTPUT_REGISTER);
- WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER, Buffer);
+ TRACE_(FLOPPY, "HwTurnOnMotor: writing byte 0x%x to offset 0x%x\n", Buffer, DIGITAL_OUTPUT_REGISTER);
+ WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER, Buffer);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwSenseDriveStatus(PDRIVE_INFO DriveInfo)
+
+NTSTATUS NTAPI
+HwSenseDriveStatus(PDRIVE_INFO DriveInfo)
/*
* FUNCTION: Start a sense status command
* ARGUMENTS:
* - hard-wired to head 0
*/
{
- UCHAR Buffer[2];
- int i;
+ UCHAR Buffer[2];
+ int i;
- PAGED_CODE();
+ PAGED_CODE();
- TRACE_(FLOPPY, "HwSenseDriveStatus called\n");
+ TRACE_(FLOPPY, "HwSenseDriveStatus called\n");
- Buffer[0] = COMMAND_SENSE_DRIVE_STATUS;
- Buffer[1] = DriveInfo->UnitNumber; /* hard-wired to head 0 for now */
+ Buffer[0] = COMMAND_SENSE_DRIVE_STATUS;
+ Buffer[1] = DriveInfo->UnitNumber; /* hard-wired to head 0 for now */
- for(i = 0; i < 2; i++)
- if(Send_Byte(DriveInfo->ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "HwSenseDriveStatus: failed to write FIFO\n");
- return STATUS_UNSUCCESSFUL;
- }
+ for(i = 0; i < 2; i++)
+ if(Send_Byte(DriveInfo->ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "HwSenseDriveStatus: failed to write FIFO\n");
+ return STATUS_UNSUCCESSFUL;
+ }
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwReadWriteData(PCONTROLLER_INFO ControllerInfo,
- BOOLEAN Read,
- UCHAR Unit,
- UCHAR Cylinder,
- UCHAR Head,
- UCHAR Sector,
- UCHAR BytesPerSector,
- UCHAR EndOfTrack,
- UCHAR Gap3Length,
- UCHAR DataLength)
+
+NTSTATUS NTAPI
+HwReadWriteData(PCONTROLLER_INFO ControllerInfo,
+ BOOLEAN Read,
+ UCHAR Unit,
+ UCHAR Cylinder,
+ UCHAR Head,
+ UCHAR Sector,
+ UCHAR BytesPerSector,
+ UCHAR EndOfTrack,
+ UCHAR Gap3Length,
+ UCHAR DataLength)
/*
* FUNCTION: Read or write data to the drive
* ARGUMENTS:
* - Generates an interrupt
*/
{
- UCHAR Buffer[9];
- int i;
+ UCHAR Buffer[9];
+ int i;
- PAGED_CODE();
+ PAGED_CODE();
- /* Shouldn't be using DataLength in this driver */
- ASSERT(DataLength == 0xff);
+ /* Shouldn't be using DataLength in this driver */
+ ASSERT(DataLength == 0xff);
- /* Build the command to send */
- if(Read)
- Buffer[0] = COMMAND_READ_DATA;
- else
- Buffer[0] = COMMAND_WRITE_DATA;
+ /* Build the command to send */
+ if(Read)
+ Buffer[0] = COMMAND_READ_DATA;
+ else
+ Buffer[0] = COMMAND_WRITE_DATA;
- Buffer[0] |= READ_DATA_MFM | READ_DATA_MT;
+ Buffer[0] |= READ_DATA_MFM | READ_DATA_MT;
- Buffer[1] = (Head << COMMAND_HEAD_NUMBER_SHIFT) | Unit;
- Buffer[2] = Cylinder;
- Buffer[3] = Head;
- Buffer[4] = Sector;
- Buffer[5] = BytesPerSector;
- Buffer[6] = EndOfTrack;
- Buffer[7] = Gap3Length;
- Buffer[8] = DataLength;
+ Buffer[1] = (Head << COMMAND_HEAD_NUMBER_SHIFT) | Unit;
+ Buffer[2] = Cylinder;
+ Buffer[3] = Head;
+ Buffer[4] = Sector;
+ Buffer[5] = BytesPerSector;
+ Buffer[6] = EndOfTrack;
+ Buffer[7] = Gap3Length;
+ Buffer[8] = DataLength;
- /* Send the command */
- for(i = 0; i < 9; i++)
+ /* Send the command */
+ for(i = 0; i < 9; i++)
{
INFO_(FLOPPY, "HwReadWriteData: Sending a command byte to the FIFO: 0x%x\n", Buffer[i]);
- if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "HwReadWriteData: Unable to write to the FIFO\n");
- return STATUS_UNSUCCESSFUL;
- }
+ if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "HwReadWriteData: Unable to write to the FIFO\n");
+ return STATUS_UNSUCCESSFUL;
+ }
}
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwRecalibrateResult(PCONTROLLER_INFO ControllerInfo)
+
+NTSTATUS NTAPI
+HwRecalibrateResult(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Get the result of a recalibrate command
* ARGUMENTS:
* - perhaps handle more status
*/
{
- UCHAR Buffer[2];
- int i;
+ UCHAR Buffer[2];
+ int i;
- PAGED_CODE();
+ PAGED_CODE();
- if(Send_Byte(ControllerInfo, COMMAND_SENSE_INTERRUPT_STATUS) != STATUS_SUCCESS)
+ if(Send_Byte(ControllerInfo, COMMAND_SENSE_INTERRUPT_STATUS) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "HwRecalibrateResult: Unable to write the controller\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "HwRecalibrateResult: Unable to write the controller\n");
+ return STATUS_UNSUCCESSFUL;
}
- for(i = 0; i < 2; i++)
- if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "HwRecalibrateResult: unable to read FIFO\n");
- return STATUS_UNSUCCESSFUL;
- }
+ for(i = 0; i < 2; i++)
+ if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "HwRecalibrateResult: unable to read FIFO\n");
+ return STATUS_UNSUCCESSFUL;
+ }
- /* Validate that it did what we told it to */
- INFO_(FLOPPY, "HwRecalibrateResult results: ST0: 0x%x PCN: 0x%x\n", Buffer[0], Buffer[1]);
+ /* Validate that it did what we told it to */
+ INFO_(FLOPPY, "HwRecalibrateResult results: ST0: 0x%x PCN: 0x%x\n", Buffer[0], Buffer[1]);
- /*
- * Buffer[0] = ST0
- * Buffer[1] = PCN
- */
+ /*
+ * Buffer[0] = ST0
+ * Buffer[1] = PCN
+ */
- /* Is the PCN 0? */
- if(Buffer[1] != 0)
+ /* Is the PCN 0? */
+ if(Buffer[1] != 0)
{
- WARN_(FLOPPY, "HwRecalibrateResult: PCN not 0\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "HwRecalibrateResult: PCN not 0\n");
+ return STATUS_UNSUCCESSFUL;
}
- /* test seek complete */
- if((Buffer[0] & SR0_SEEK_COMPLETE) != SR0_SEEK_COMPLETE)
+ /* test seek complete */
+ if((Buffer[0] & SR0_SEEK_COMPLETE) != SR0_SEEK_COMPLETE)
{
- WARN_(FLOPPY, "HwRecalibrateResult: Failed to complete the seek\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "HwRecalibrateResult: Failed to complete the seek\n");
+ return STATUS_UNSUCCESSFUL;
}
- /* Is the equipment check flag set? Could be no disk in drive... */
- if((Buffer[0] & SR0_EQUIPMENT_CHECK) == SR0_EQUIPMENT_CHECK)
- INFO_(FLOPPY, "HwRecalibrateResult: Seeked to track 0 successfully, but EC is set; returning STATUS_SUCCESS anyway\n");
+ /* Is the equipment check flag set? Could be no disk in drive... */
+ if((Buffer[0] & SR0_EQUIPMENT_CHECK) == SR0_EQUIPMENT_CHECK)
+ INFO_(FLOPPY, "HwRecalibrateResult: Seeked to track 0 successfully, but EC is set; returning STATUS_SUCCESS anyway\n");
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwReadWriteResult(PCONTROLLER_INFO ControllerInfo)
+
+NTSTATUS NTAPI
+HwReadWriteResult(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Get the result of a read or write from the controller
* ARGUMENTS:
* - perhaps handle more status
*/
{
- UCHAR Buffer[7];
- int i;
+ UCHAR Buffer[7];
+ int i;
- PAGED_CODE();
+ PAGED_CODE();
- for(i = 0; i < 7; i++)
- if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "HwReadWriteResult: unable to read fifo\n");
- return STATUS_UNSUCCESSFUL;
- }
+ for(i = 0; i < 7; i++)
+ if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "HwReadWriteResult: unable to read fifo\n");
+ return STATUS_UNSUCCESSFUL;
+ }
- /* Validate that it did what we told it to */
- INFO_(FLOPPY, "HwReadWriteResult results: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", Buffer[0], Buffer[1], Buffer[2], Buffer[3],
- Buffer[4], Buffer[5], Buffer[6]);
+ /* Validate that it did what we told it to */
+ INFO_(FLOPPY, "HwReadWriteResult results: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", Buffer[0], Buffer[1], Buffer[2], Buffer[3],
+ Buffer[4], Buffer[5], Buffer[6]);
- /* Last command successful? */
- if((Buffer[0] & SR0_LAST_COMMAND_STATUS) != SR0_LCS_SUCCESS)
- return STATUS_UNSUCCESSFUL;
+ /* Last command successful? */
+ if((Buffer[0] & SR0_LAST_COMMAND_STATUS) != SR0_LCS_SUCCESS)
+ return STATUS_UNSUCCESSFUL;
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwRecalibrate(PDRIVE_INFO DriveInfo)
+
+NTSTATUS NTAPI
+HwRecalibrate(PDRIVE_INFO DriveInfo)
/*
* FUNCTION: Start a recalibration of a drive
* ARGUMENTS:
* - Generates an interrupt
*/
{
- PCONTROLLER_INFO ControllerInfo = DriveInfo->ControllerInfo;
- UCHAR Unit = DriveInfo->UnitNumber;
- UCHAR Buffer[2];
- int i;
+ PCONTROLLER_INFO ControllerInfo = DriveInfo->ControllerInfo;
+ UCHAR Unit = DriveInfo->UnitNumber;
+ UCHAR Buffer[2];
+ int i;
- TRACE_(FLOPPY, "HwRecalibrate called\n");
+ TRACE_(FLOPPY, "HwRecalibrate called\n");
- PAGED_CODE();
+ PAGED_CODE();
- Buffer[0] = COMMAND_RECALIBRATE;
- Buffer[1] = Unit;
+ Buffer[0] = COMMAND_RECALIBRATE;
+ Buffer[1] = Unit;
- for(i = 0; i < 2; i++)
- if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "HwRecalibrate: unable to write FIFO\n");
- return STATUS_UNSUCCESSFUL;
- }
+ for(i = 0; i < 2; i++)
+ if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "HwRecalibrate: unable to write FIFO\n");
+ return STATUS_UNSUCCESSFUL;
+ }
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwSenseInterruptStatus(PCONTROLLER_INFO ControllerInfo)
+
+NTSTATUS NTAPI
+HwSenseInterruptStatus(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Send a sense interrupt status command to a controller
* ARGUMENTS:
* STATUS_UNSUCCESSFUL if not
*/
{
- UCHAR Buffer[2];
- int i;
+ UCHAR Buffer[2];
+ int i;
- PAGED_CODE();
+ PAGED_CODE();
- if(Send_Byte(ControllerInfo, COMMAND_SENSE_INTERRUPT_STATUS) != STATUS_SUCCESS)
+ if(Send_Byte(ControllerInfo, COMMAND_SENSE_INTERRUPT_STATUS) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "HwSenseInterruptStatus: failed to write controller\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "HwSenseInterruptStatus: failed to write controller\n");
+ return STATUS_UNSUCCESSFUL;
}
- for(i = 0; i < 2; i++)
+ for(i = 0; i < 2; i++)
{
- if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "HwSenseInterruptStatus: failed to read controller\n");
- return STATUS_UNSUCCESSFUL;
- }
+ if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "HwSenseInterruptStatus: failed to read controller\n");
+ return STATUS_UNSUCCESSFUL;
+ }
}
- INFO_(FLOPPY, "HwSenseInterruptStatus returned 0x%x 0x%x\n", Buffer[0], Buffer[1]);
+ INFO_(FLOPPY, "HwSenseInterruptStatus returned 0x%x 0x%x\n", Buffer[0], Buffer[1]);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwReadId(PDRIVE_INFO DriveInfo, UCHAR Head)
+
+NTSTATUS NTAPI
+HwReadId(PDRIVE_INFO DriveInfo, UCHAR Head)
/*
* FUNCTION: Issue a read id command to the drive
* ARGUMENTS:
* - Generates an interrupt
*/
{
- UCHAR Buffer[2];
- int i;
+ UCHAR Buffer[2];
+ int i;
- TRACE_(FLOPPY, "HwReadId called\n");
+ TRACE_(FLOPPY, "HwReadId called\n");
- PAGED_CODE();
+ PAGED_CODE();
- Buffer[0] = COMMAND_READ_ID | READ_ID_MFM;
- Buffer[1] = (Head << COMMAND_HEAD_NUMBER_SHIFT) | DriveInfo->UnitNumber;
+ Buffer[0] = COMMAND_READ_ID | READ_ID_MFM;
+ Buffer[1] = (Head << COMMAND_HEAD_NUMBER_SHIFT) | DriveInfo->UnitNumber;
- for(i = 0; i < 2; i++)
- if(Send_Byte(DriveInfo->ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "HwReadId: unable to send bytes to fifo\n");
- return STATUS_UNSUCCESSFUL;
- }
+ for(i = 0; i < 2; i++)
+ if(Send_Byte(DriveInfo->ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "HwReadId: unable to send bytes to fifo\n");
+ return STATUS_UNSUCCESSFUL;
+ }
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwFormatTrack(PCONTROLLER_INFO ControllerInfo,
- UCHAR Unit,
- UCHAR Head,
- UCHAR BytesPerSector,
- UCHAR SectorsPerTrack,
- UCHAR Gap3Length,
- UCHAR FillerPattern)
+
+NTSTATUS NTAPI
+HwFormatTrack(PCONTROLLER_INFO ControllerInfo,
+ UCHAR Unit,
+ UCHAR Head,
+ UCHAR BytesPerSector,
+ UCHAR SectorsPerTrack,
+ UCHAR Gap3Length,
+ UCHAR FillerPattern)
/*
* FUNCTION: Format a track
* ARGUMENTS:
* STATUS_UNSUCCESSFUL otherwise
*/
{
- UCHAR Buffer[6];
- int i;
+ UCHAR Buffer[6];
+ int i;
- TRACE_(FLOPPY, "HwFormatTrack called\n");
+ TRACE_(FLOPPY, "HwFormatTrack called\n");
- PAGED_CODE();
+ PAGED_CODE();
- Buffer[0] = COMMAND_FORMAT_TRACK;
- Buffer[1] = (Head << COMMAND_HEAD_NUMBER_SHIFT) | Unit;
- Buffer[2] = BytesPerSector;
- Buffer[3] = SectorsPerTrack;
- Buffer[4] = Gap3Length;
- Buffer[5] = FillerPattern;
+ Buffer[0] = COMMAND_FORMAT_TRACK;
+ Buffer[1] = (Head << COMMAND_HEAD_NUMBER_SHIFT) | Unit;
+ Buffer[2] = BytesPerSector;
+ Buffer[3] = SectorsPerTrack;
+ Buffer[4] = Gap3Length;
+ Buffer[5] = FillerPattern;
- for(i = 0; i < 6; i++)
- if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "HwFormatTrack: unable to send bytes to floppy\n");
- return STATUS_UNSUCCESSFUL;
- }
+ for(i = 0; i < 6; i++)
+ if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "HwFormatTrack: unable to send bytes to floppy\n");
+ return STATUS_UNSUCCESSFUL;
+ }
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwSeek(PDRIVE_INFO DriveInfo,
- UCHAR Cylinder)
+
+NTSTATUS NTAPI
+HwSeek(PDRIVE_INFO DriveInfo, UCHAR Cylinder)
/*
* FUNCTION: Seek the heads to a particular cylinder
* ARGUMENTS:
* - Generates an interrupt
*/
{
- LARGE_INTEGER Delay;
- UCHAR Buffer[3];
- int i;
+ LARGE_INTEGER Delay;
+ UCHAR Buffer[3];
+ int i;
- TRACE_(FLOPPY, "HwSeek called for cyl 0x%x\n", Cylinder);
+ TRACE_(FLOPPY, "HwSeek called for cyl 0x%x\n", Cylinder);
- PAGED_CODE();
+ PAGED_CODE();
- Buffer[0] = COMMAND_SEEK;
- Buffer[1] = DriveInfo->UnitNumber;
- Buffer[2] = Cylinder;
+ Buffer[0] = COMMAND_SEEK;
+ Buffer[1] = DriveInfo->UnitNumber;
+ Buffer[2] = Cylinder;
- for(i = 0; i < 3; i++)
- if(Send_Byte(DriveInfo->ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "HwSeek: failed to write fifo\n");
- return STATUS_UNSUCCESSFUL;
- }
+ for(i = 0; i < 3; i++)
+ if(Send_Byte(DriveInfo->ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "HwSeek: failed to write fifo\n");
+ return STATUS_UNSUCCESSFUL;
+ }
- /* Wait for the head to settle */
- Delay.QuadPart = 10 * 1000;
- Delay.QuadPart *= -1;
- Delay.QuadPart *= DriveInfo->FloppyDeviceData.HeadSettleTime;
+ /* Wait for the head to settle */
+ Delay.QuadPart = 10 * 1000;
+ Delay.QuadPart *= -1;
+ Delay.QuadPart *= DriveInfo->FloppyDeviceData.HeadSettleTime;
- KeDelayExecutionThread(KernelMode, FALSE, &Delay);
+ KeDelayExecutionThread(KernelMode, FALSE, &Delay);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwConfigure(PCONTROLLER_INFO ControllerInfo,
- BOOLEAN EIS,
- BOOLEAN EFIFO,
- BOOLEAN POLL,
- UCHAR FIFOTHR,
- UCHAR PRETRK)
+
+NTSTATUS NTAPI
+HwConfigure(PCONTROLLER_INFO ControllerInfo,
+ BOOLEAN EIS,
+ BOOLEAN EFIFO,
+ BOOLEAN POLL,
+ UCHAR FIFOTHR,
+ UCHAR PRETRK)
/*
* FUNCTION: Sends configuration to the drive
* ARGUMENTS:
* - No interrupt
*/
{
- UCHAR Buffer[4];
- int i;
+ UCHAR Buffer[4];
+ int i;
- TRACE_(FLOPPY, "HwConfigure called\n");
+ TRACE_(FLOPPY, "HwConfigure called\n");
- PAGED_CODE();
+ PAGED_CODE();
- Buffer[0] = COMMAND_CONFIGURE;
- Buffer[1] = 0;
- Buffer[2] = (EIS * CONFIGURE_EIS) + (EFIFO * CONFIGURE_EFIFO) + (POLL * CONFIGURE_POLL) + (FIFOTHR);
- Buffer[3] = PRETRK;
+ Buffer[0] = COMMAND_CONFIGURE;
+ Buffer[1] = 0;
+ Buffer[2] = (EIS * CONFIGURE_EIS) + (EFIFO * CONFIGURE_EFIFO) + (POLL * CONFIGURE_POLL) + (FIFOTHR);
+ Buffer[3] = PRETRK;
- for(i = 0; i < 4; i++)
- if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "HwConfigure: failed to write the fifo\n");
- return STATUS_UNSUCCESSFUL;
- }
+ for(i = 0; i < 4; i++)
+ if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "HwConfigure: failed to write the fifo\n");
+ return STATUS_UNSUCCESSFUL;
+ }
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwGetVersion(PCONTROLLER_INFO ControllerInfo)
+
+NTSTATUS NTAPI
+HwGetVersion(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Gets the version of the controller
* ARGUMENTS:
* we issue the command
*/
{
- UCHAR Buffer;
+ UCHAR Buffer;
- PAGED_CODE();
+ PAGED_CODE();
- if(Send_Byte(ControllerInfo, COMMAND_VERSION) != STATUS_SUCCESS)
+ if(Send_Byte(ControllerInfo, COMMAND_VERSION) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "HwGetVersion: unable to write fifo\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "HwGetVersion: unable to write fifo\n");
+ return STATUS_UNSUCCESSFUL;
}
- if(Get_Byte(ControllerInfo, &Buffer) != STATUS_SUCCESS)
+ if(Get_Byte(ControllerInfo, &Buffer) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "HwGetVersion: unable to write fifo\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "HwGetVersion: unable to write fifo\n");
+ return STATUS_UNSUCCESSFUL;
}
- INFO_(FLOPPY, "HwGetVersion returning version 0x%x\n", Buffer);
+ INFO_(FLOPPY, "HwGetVersion returning version 0x%x\n", Buffer);
- return Buffer;
+ return Buffer;
}
-NTSTATUS NTAPI HwDiskChanged(PDRIVE_INFO DriveInfo,
- PBOOLEAN DiskChanged)
+NTSTATUS NTAPI
+HwDiskChanged(PDRIVE_INFO DriveInfo, PBOOLEAN DiskChanged)
/*
* FUNCTION: Detect whether the hardware has sensed a disk change
* ARGUMENTS:
* - Guessing a bit at the Model30 stuff
*/
{
- UCHAR Buffer;
- PCONTROLLER_INFO ControllerInfo = (PCONTROLLER_INFO) DriveInfo->ControllerInfo;
+ UCHAR Buffer;
+ PCONTROLLER_INFO ControllerInfo = (PCONTROLLER_INFO) DriveInfo->ControllerInfo;
- Buffer = READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_INPUT_REGISTER);
+ Buffer = READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_INPUT_REGISTER);
- TRACE_(FLOPPY, "HwDiskChanged: read 0x%x from DIR\n", Buffer);
+ TRACE_(FLOPPY, "HwDiskChanged: read 0x%x from DIR\n", Buffer);
- if(ControllerInfo->Model30)
+ if(ControllerInfo->Model30)
{
- if(!(Buffer & DIR_DISKETTE_CHANGE))
- {
- INFO_(FLOPPY, "HdDiskChanged - Model30 - returning TRUE\n");
- *DiskChanged = TRUE;
- }
- else
- {
- INFO_(FLOPPY, "HdDiskChanged - Model30 - returning FALSE\n");
- *DiskChanged = FALSE;
- }
+ if(!(Buffer & DIR_DISKETTE_CHANGE))
+ {
+ INFO_(FLOPPY, "HdDiskChanged - Model30 - returning TRUE\n");
+ *DiskChanged = TRUE;
+ }
+ else
+ {
+ INFO_(FLOPPY, "HdDiskChanged - Model30 - returning FALSE\n");
+ *DiskChanged = FALSE;
+ }
}
- else
+ else
{
- if(Buffer & DIR_DISKETTE_CHANGE)
- {
- INFO_(FLOPPY, "HdDiskChanged - PS2 - returning TRUE\n");
- *DiskChanged = TRUE;
- }
- else
- {
- INFO_(FLOPPY, "HdDiskChanged - PS2 - returning FALSE\n");
- *DiskChanged = FALSE;
- }
+ if(Buffer & DIR_DISKETTE_CHANGE)
+ {
+ INFO_(FLOPPY, "HdDiskChanged - PS2 - returning TRUE\n");
+ *DiskChanged = TRUE;
+ }
+ else
+ {
+ INFO_(FLOPPY, "HdDiskChanged - PS2 - returning FALSE\n");
+ *DiskChanged = FALSE;
+ }
}
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-NTSTATUS NTAPI HwSenseDriveStatusResult(PCONTROLLER_INFO ControllerInfo,
- PUCHAR Status)
+NTSTATUS NTAPI
+HwSenseDriveStatusResult(PCONTROLLER_INFO ControllerInfo, PUCHAR Status)
/*
* FUNCTION: Get the result of a sense drive status command
* ARGUMENTS:
* - Called post-interrupt; does not interrupt
*/
{
- PAGED_CODE();
+ PAGED_CODE();
- if(Get_Byte(ControllerInfo, Status) != STATUS_SUCCESS)
+ if(Get_Byte(ControllerInfo, Status) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "HwSenseDriveStatus: unable to read fifo\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "HwSenseDriveStatus: unable to read fifo\n");
+ return STATUS_UNSUCCESSFUL;
}
- TRACE_(FLOPPY, "HwSenseDriveStatusResult: ST3: 0x%x\n", *Status);
+ TRACE_(FLOPPY, "HwSenseDriveStatusResult: ST3: 0x%x\n", *Status);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwReadIdResult(PCONTROLLER_INFO ControllerInfo,
- PUCHAR CurCylinder,
- PUCHAR CurHead)
+
+NTSTATUS NTAPI
+HwReadIdResult(PCONTROLLER_INFO ControllerInfo,
+ PUCHAR CurCylinder,
+ PUCHAR CurHead)
/*
* FUNCTION: Get the result of a read id command
* ARGUMENTS:
* - perhaps handle more status
*/
{
- UCHAR Buffer[7] = {0,0,0,0,0,0,0};
- int i;
+ UCHAR Buffer[7] = {0,0,0,0,0,0,0};
+ int i;
- PAGED_CODE();
+ PAGED_CODE();
- for(i = 0; i < 7; i++)
- if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "ReadIdResult(): can't read from the controller\n");
- return STATUS_UNSUCCESSFUL;
- }
+ for(i = 0; i < 7; i++)
+ if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "ReadIdResult(): can't read from the controller\n");
+ return STATUS_UNSUCCESSFUL;
+ }
- /* Validate that it did what we told it to */
- INFO_(FLOPPY, "ReadId results: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", Buffer[0], Buffer[1], Buffer[2], Buffer[3],
- Buffer[4], Buffer[5], Buffer[6]);
+ /* Validate that it did what we told it to */
+ INFO_(FLOPPY, "ReadId results: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", Buffer[0], Buffer[1], Buffer[2], Buffer[3],
+ Buffer[4], Buffer[5], Buffer[6]);
- /* Last command successful? */
- if((Buffer[0] & SR0_LAST_COMMAND_STATUS) != SR0_LCS_SUCCESS)
+ /* Last command successful? */
+ if((Buffer[0] & SR0_LAST_COMMAND_STATUS) != SR0_LCS_SUCCESS)
{
- WARN_(FLOPPY, "ReadId didn't return last command success\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "ReadId didn't return last command success\n");
+ return STATUS_UNSUCCESSFUL;
}
- /* ID mark found? */
- if(Buffer[1] & SR1_CANNOT_FIND_ID_ADDRESS)
+ /* ID mark found? */
+ if(Buffer[1] & SR1_CANNOT_FIND_ID_ADDRESS)
{
- WARN_(FLOPPY, "ReadId didn't find an address mark\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "ReadId didn't find an address mark\n");
+ return STATUS_UNSUCCESSFUL;
}
- if(CurCylinder)
- *CurCylinder = Buffer[3];
+ if(CurCylinder)
+ *CurCylinder = Buffer[3];
- if(CurHead)
- *CurHead = Buffer[4];
+ if(CurHead)
+ *CurHead = Buffer[4];
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwSpecify(PCONTROLLER_INFO ControllerInfo,
- UCHAR HeadLoadTime,
- UCHAR HeadUnloadTime,
- UCHAR StepRateTime,
- BOOLEAN NonDma)
+
+NTSTATUS NTAPI
+HwSpecify(PCONTROLLER_INFO ControllerInfo,
+ UCHAR HeadLoadTime,
+ UCHAR HeadUnloadTime,
+ UCHAR StepRateTime,
+ BOOLEAN NonDma)
/*
* FUNCTION: Set up timing and DMA mode for the controller
* ARGUMENTS:
* TODO: Figure out timings
*/
{
- UCHAR Buffer[3];
- int i;
-
- Buffer[0] = COMMAND_SPECIFY;
- /*
- Buffer[1] = (StepRateTime << 4) + HeadUnloadTime;
- Buffer[2] = (HeadLoadTime << 1) + (NonDma ? 1 : 0);
- */
- Buffer[1] = 0xdf;
- Buffer[2] = 0x2;
-
- //INFO_(FLOPPY, "HwSpecify: sending 0x%x 0x%x 0x%x to FIFO\n", Buffer[0], Buffer[1], Buffer[2]);
- WARN_(FLOPPY, "HWSPECIFY: FIXME - sending 0x3 0xd1 0x2 to FIFO\n");
-
- for(i = 0; i < 3; i++)
- if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "HwSpecify: unable to write to controller\n");
- return STATUS_UNSUCCESSFUL;
- }
+ UCHAR Buffer[3];
+ int i;
+
+ Buffer[0] = COMMAND_SPECIFY;
+ /*
+ Buffer[1] = (StepRateTime << 4) + HeadUnloadTime;
+ Buffer[2] = (HeadLoadTime << 1) + (NonDma ? 1 : 0);
+ */
+ Buffer[1] = 0xdf;
+ Buffer[2] = 0x2;
+
+ //INFO_(FLOPPY, "HwSpecify: sending 0x%x 0x%x 0x%x to FIFO\n", Buffer[0], Buffer[1], Buffer[2]);
+ WARN_(FLOPPY, "HWSPECIFY: FIXME - sending 0x3 0xd1 0x2 to FIFO\n");
+
+ for(i = 0; i < 3; i++)
+ if(Send_Byte(ControllerInfo, Buffer[i]) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "HwSpecify: unable to write to controller\n");
+ return STATUS_UNSUCCESSFUL;
+ }
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwReset(PCONTROLLER_INFO ControllerInfo)
+
+NTSTATUS NTAPI
+HwReset(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Reset the controller
* ARGUMENTS:
* - Generates an interrupt that must be serviced four times (one per drive)
*/
{
- TRACE_(FLOPPY, "HwReset called\n");
+ TRACE_(FLOPPY, "HwReset called\n");
- /* Write the reset bit in the DRSR */
- WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DATA_RATE_SELECT_REGISTER, DRSR_SW_RESET);
+ /* Write the reset bit in the DRSR */
+ WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DATA_RATE_SELECT_REGISTER, DRSR_SW_RESET);
- /* Check for the reset bit in the DOR and set it if necessary (see Intel doc) */
- if(!(READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER) & DOR_RESET))
+ /* Check for the reset bit in the DOR and set it if necessary (see Intel doc) */
+ if(!(READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER) & DOR_RESET))
{
- HwDumpRegisters(ControllerInfo);
- INFO_(FLOPPY, "HwReset: Setting Enable bit\n");
- WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER, DOR_DMA_IO_INTERFACE_ENABLE|DOR_RESET);
- HwDumpRegisters(ControllerInfo);
-
- if(!(READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER) & DOR_RESET))
- {
- WARN_(FLOPPY, "HwReset: failed to set the DOR enable bit!\n");
- HwDumpRegisters(ControllerInfo);
- return STATUS_UNSUCCESSFUL;
- }
+ HwDumpRegisters(ControllerInfo);
+ INFO_(FLOPPY, "HwReset: Setting Enable bit\n");
+ WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER, DOR_DMA_IO_INTERFACE_ENABLE|DOR_RESET);
+ HwDumpRegisters(ControllerInfo);
+
+ if(!(READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER) & DOR_RESET))
+ {
+ WARN_(FLOPPY, "HwReset: failed to set the DOR enable bit!\n");
+ HwDumpRegisters(ControllerInfo);
+ return STATUS_UNSUCCESSFUL;
+ }
}
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-NTSTATUS NTAPI HwPowerOff(PCONTROLLER_INFO ControllerInfo)
+
+NTSTATUS NTAPI
+HwPowerOff(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Power down a controller
* ARGUMENTS:
* - Wake up with a hardware reset
*/
{
- TRACE_(FLOPPY, "HwPowerOff called on controller 0x%p\n", ControllerInfo);
+ TRACE_(FLOPPY, "HwPowerOff called on controller 0x%p\n", ControllerInfo);
- WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DATA_RATE_SELECT_REGISTER, DRSR_POWER_DOWN);
+ WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + DATA_RATE_SELECT_REGISTER, DRSR_POWER_DOWN);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-VOID NTAPI HwDumpRegisters(PCONTROLLER_INFO ControllerInfo)
+VOID NTAPI
+HwDumpRegisters(PCONTROLLER_INFO ControllerInfo)
/*
* FUNCTION: Dump all readable registers from the floppy controller
* ARGUMENTS:
* ControllerInfo: Controller to dump registers from
*/
{
- UNREFERENCED_PARAMETER(ControllerInfo);
-
- INFO_(FLOPPY, "STATUS:\n");
- INFO_(FLOPPY, "STATUS_REGISTER_A = 0x%x\n", READ_PORT_UCHAR(ControllerInfo->BaseAddress + STATUS_REGISTER_A));
- INFO_(FLOPPY, "STATUS_REGISTER_B = 0x%x\n", READ_PORT_UCHAR(ControllerInfo->BaseAddress + STATUS_REGISTER_B));
- INFO_(FLOPPY, "DIGITAL_OUTPUT_REGISTER = 0x%x\n", READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER));
- INFO_(FLOPPY, "MAIN_STATUS_REGISTER =0x%x\n", READ_PORT_UCHAR(ControllerInfo->BaseAddress + MAIN_STATUS_REGISTER));
- INFO_(FLOPPY, "DIGITAL_INPUT_REGISTER = 0x%x\n", READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_INPUT_REGISTER));
+ UNREFERENCED_PARAMETER(ControllerInfo);
+
+ INFO_(FLOPPY, "STATUS:\n");
+ INFO_(FLOPPY, "STATUS_REGISTER_A = 0x%x\n", READ_PORT_UCHAR(ControllerInfo->BaseAddress + STATUS_REGISTER_A));
+ INFO_(FLOPPY, "STATUS_REGISTER_B = 0x%x\n", READ_PORT_UCHAR(ControllerInfo->BaseAddress + STATUS_REGISTER_B));
+ INFO_(FLOPPY, "DIGITAL_OUTPUT_REGISTER = 0x%x\n", READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_OUTPUT_REGISTER));
+ INFO_(FLOPPY, "MAIN_STATUS_REGISTER =0x%x\n", READ_PORT_UCHAR(ControllerInfo->BaseAddress + MAIN_STATUS_REGISTER));
+ INFO_(FLOPPY, "DIGITAL_INPUT_REGISTER = 0x%x\n", READ_PORT_UCHAR(ControllerInfo->BaseAddress + DIGITAL_INPUT_REGISTER));
}
/*
* FUNCTIONS
*/
-NTSTATUS NTAPI HwTurnOnMotor(PDRIVE_INFO DriveInfo);
-
-NTSTATUS NTAPI HwSenseDriveStatus(PDRIVE_INFO DriveInfo);
-
-NTSTATUS NTAPI HwReadWriteData(PCONTROLLER_INFO ControllerInfo,
- BOOLEAN Read,
- UCHAR Unit,
- UCHAR Cylinder,
- UCHAR Head,
- UCHAR Sector,
- UCHAR BytesPerSector,
- UCHAR EndOfTrack,
- UCHAR Gap3Length,
- UCHAR DataLength);
-
-NTSTATUS NTAPI HwRecalibrate(PDRIVE_INFO DriveInfo);
-
-NTSTATUS NTAPI HwSenseInterruptStatus(PCONTROLLER_INFO ControllerInfo);
-
-NTSTATUS NTAPI HwReadId(PDRIVE_INFO DriveInfo,
- UCHAR Head);
-
-NTSTATUS NTAPI HwFormatTrack(PCONTROLLER_INFO ControllerInfo,
- UCHAR Unit,
- UCHAR Head,
- UCHAR BytesPerSector,
- UCHAR SectorsPerTrack,
- UCHAR Gap3Length,
- UCHAR FillerPattern);
-
-NTSTATUS NTAPI HwSeek(PDRIVE_INFO DriveInfo,
- UCHAR Cylinder);
-
-NTSTATUS NTAPI HwReadWriteResult(PCONTROLLER_INFO ControllerInfo);
-
-NTSTATUS NTAPI HwGetVersion(PCONTROLLER_INFO ControllerInfo);
-
-NTSTATUS NTAPI HwConfigure(PCONTROLLER_INFO ControllerInfo,
- BOOLEAN EIS,
- BOOLEAN EFIFO,
- BOOLEAN POLL,
- UCHAR FIFOTHR,
- UCHAR PRETRK) ;
-
-NTSTATUS NTAPI HwRecalibrateResult(PCONTROLLER_INFO ControllerInfo);
-
-NTSTATUS NTAPI HwDiskChanged(PDRIVE_INFO DriveInfo,
- PBOOLEAN DiskChanged);
-
-NTSTATUS NTAPI HwSenseDriveStatusResult(PCONTROLLER_INFO ControllerInfo,
- PUCHAR Status);
-
-NTSTATUS NTAPI HwSpecify(PCONTROLLER_INFO ControllerInfo,
- UCHAR HeadLoadTime,
- UCHAR HeadUnloadTime,
- UCHAR StepRateTime,
- BOOLEAN NonDma);
-
-NTSTATUS NTAPI HwReadIdResult(PCONTROLLER_INFO ControllerInfo,
- PUCHAR CurCylinder,
- PUCHAR CurHead);
-
-NTSTATUS NTAPI HwSetDataRate(PCONTROLLER_INFO ControllerInfo,
- UCHAR DataRate);
-
-NTSTATUS NTAPI HwReset(PCONTROLLER_INFO Controller);
-
-NTSTATUS NTAPI HwPowerOff(PCONTROLLER_INFO ControllerInfo);
-
-VOID NTAPI HwDumpRegisters(PCONTROLLER_INFO ControllerInfo);
-
-NTSTATUS NTAPI HwTurnOffMotor(PCONTROLLER_INFO ControllerInfo);
+NTSTATUS NTAPI
+HwTurnOnMotor(PDRIVE_INFO DriveInfo);
+
+NTSTATUS NTAPI
+HwSenseDriveStatus(PDRIVE_INFO DriveInfo);
+
+NTSTATUS NTAPI
+HwReadWriteData(PCONTROLLER_INFO ControllerInfo,
+ BOOLEAN Read,
+ UCHAR Unit,
+ UCHAR Cylinder,
+ UCHAR Head,
+ UCHAR Sector,
+ UCHAR BytesPerSector,
+ UCHAR EndOfTrack,
+ UCHAR Gap3Length,
+ UCHAR DataLength);
+
+NTSTATUS NTAPI
+HwRecalibrate(PDRIVE_INFO DriveInfo);
+
+NTSTATUS NTAPI
+HwSenseInterruptStatus(PCONTROLLER_INFO ControllerInfo);
+
+NTSTATUS NTAPI
+HwReadId(PDRIVE_INFO DriveInfo, UCHAR Head);
+
+NTSTATUS NTAPI
+HwFormatTrack(PCONTROLLER_INFO ControllerInfo,
+ UCHAR Unit,
+ UCHAR Head,
+ UCHAR BytesPerSector,
+ UCHAR SectorsPerTrack,
+ UCHAR Gap3Length,
+ UCHAR FillerPattern);
+
+NTSTATUS NTAPI
+HwSeek(PDRIVE_INFO DriveInfo, UCHAR Cylinder);
+
+NTSTATUS NTAPI
+HwReadWriteResult(PCONTROLLER_INFO ControllerInfo);
+
+NTSTATUS NTAPI
+HwGetVersion(PCONTROLLER_INFO ControllerInfo);
+
+NTSTATUS NTAPI
+HwConfigure(PCONTROLLER_INFO ControllerInfo,
+ BOOLEAN EIS,
+ BOOLEAN EFIFO,
+ BOOLEAN POLL,
+ UCHAR FIFOTHR,
+ UCHAR PRETRK) ;
+
+NTSTATUS NTAPI
+HwRecalibrateResult(PCONTROLLER_INFO ControllerInfo);
+
+NTSTATUS NTAPI
+HwDiskChanged(PDRIVE_INFO DriveInfo,
+ PBOOLEAN DiskChanged);
+
+NTSTATUS NTAPI
+HwSenseDriveStatusResult(PCONTROLLER_INFO ControllerInfo,
+ PUCHAR Status);
+
+NTSTATUS NTAPI
+HwSpecify(PCONTROLLER_INFO ControllerInfo,
+ UCHAR HeadLoadTime,
+ UCHAR HeadUnloadTime,
+ UCHAR StepRateTime,
+ BOOLEAN NonDma);
+
+NTSTATUS NTAPI
+HwReadIdResult(PCONTROLLER_INFO ControllerInfo,
+ PUCHAR CurCylinder,
+ PUCHAR CurHead);
+
+NTSTATUS NTAPI
+HwSetDataRate(PCONTROLLER_INFO ControllerInfo, UCHAR DataRate);
+
+NTSTATUS NTAPI
+HwReset(PCONTROLLER_INFO Controller);
+
+NTSTATUS NTAPI
+HwPowerOff(PCONTROLLER_INFO ControllerInfo);
+
+VOID NTAPI
+HwDumpRegisters(PCONTROLLER_INFO ControllerInfo);
+
+NTSTATUS NTAPI
+HwTurnOffMotor(PCONTROLLER_INFO ControllerInfo);
#include "csqrtns.h"
#include "ioctl.h"
-\f
-NTSTATUS NTAPI DeviceIoctl(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+
+NTSTATUS NTAPI
+DeviceIoctl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Queue IOCTL IRPs
* ARGUMENTS:
* read/write or ioctl irps.
*/
{
- ASSERT(DeviceObject);
- ASSERT(Irp);
+ ASSERT(DeviceObject);
+ ASSERT(Irp);
- Irp->Tail.Overlay.DriverContext[0] = DeviceObject;
- IoCsqInsertIrp(&Csq, Irp, NULL);
+ Irp->Tail.Overlay.DriverContext[0] = DeviceObject;
+ IoCsqInsertIrp(&Csq, Irp, NULL);
- return STATUS_PENDING;
+ return STATUS_PENDING;
}
-\f
-VOID NTAPI DeviceIoctlPassive(PDRIVE_INFO DriveInfo,
- PIRP Irp)
+
+VOID NTAPI
+DeviceIoctlPassive(PDRIVE_INFO DriveInfo, PIRP Irp)
/*
* FUNCTION: Handlees IOCTL requests at PASSIVE_LEVEL
* ARGUMENTS:
* Irp: IRP with the request in it
*/
{
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
- ULONG OutputLength = Stack->Parameters.DeviceIoControl.OutputBufferLength;
- PVOID OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
- ULONG Code = Stack->Parameters.DeviceIoControl.IoControlCode;
- BOOLEAN DiskChanged;
-
- TRACE_(FLOPPY, "DeviceIoctl called\n");
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
-
- /*
- * First the non-change-sensitive ioctls
- */
- if(Code == IOCTL_DISK_GET_MEDIA_TYPES)
+ PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+ ULONG OutputLength = Stack->Parameters.DeviceIoControl.OutputBufferLength;
+ PVOID OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
+ ULONG Code = Stack->Parameters.DeviceIoControl.IoControlCode;
+ BOOLEAN DiskChanged;
+
+ TRACE_(FLOPPY, "DeviceIoctl called\n");
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+
+ /*
+ * First the non-change-sensitive ioctls
+ */
+ if(Code == IOCTL_DISK_GET_MEDIA_TYPES)
{
- PDISK_GEOMETRY Geometry = OutputBuffer;
- INFO_(FLOPPY, "IOCTL_DISK_GET_MEDIA_TYPES Called\n");
+ PDISK_GEOMETRY Geometry = OutputBuffer;
+ INFO_(FLOPPY, "IOCTL_DISK_GET_MEDIA_TYPES Called\n");
- if(OutputLength < sizeof(DISK_GEOMETRY))
+ if(OutputLength < sizeof(DISK_GEOMETRY))
{
- INFO_(FLOPPY, "IOCTL_DISK_GET_MEDIA_TYPES: insufficient buffer; returning STATUS_INVALID_PARAMETER\n");
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return;
+ INFO_(FLOPPY, "IOCTL_DISK_GET_MEDIA_TYPES: insufficient buffer; returning STATUS_INVALID_PARAMETER\n");
+ Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return;
}
- /*
- * for now, this driver only supports 3.5" HD media
- */
- Geometry->MediaType = F3_1Pt44_512;
- Geometry->Cylinders.QuadPart = 80;
- Geometry->TracksPerCylinder = 2 * 18;
- Geometry->SectorsPerTrack = 18;
- Geometry->BytesPerSector = 512;
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
- INFO_(FLOPPY, "Ioctl: completing with STATUS_SUCCESS\n");
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return;
+ /*
+ * for now, this driver only supports 3.5" HD media
+ */
+ Geometry->MediaType = F3_1Pt44_512;
+ Geometry->Cylinders.QuadPart = 80;
+ Geometry->TracksPerCylinder = 2 * 18;
+ Geometry->SectorsPerTrack = 18;
+ Geometry->BytesPerSector = 512;
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
+ INFO_(FLOPPY, "Ioctl: completing with STATUS_SUCCESS\n");
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return;
}
- /*
- * Now, check to see if the volume needs to be verified. If so,
- * return STATUS_VERIFY_REQUIRED.
- *
- * NOTE: This code, which is outside of the switch and if/else blocks,
- * will implicity catch and correctly service IOCTL_DISK_CHECK_VERIFY.
- * Therefore if we see one below in the switch, we can return STATUS_SUCCESS
- * immediately.
- */
- if(DriveInfo->DeviceObject->Flags & DO_VERIFY_VOLUME && !(DriveInfo->DeviceObject->Flags & SL_OVERRIDE_VERIFY_VOLUME))
+ /*
+ * Now, check to see if the volume needs to be verified. If so,
+ * return STATUS_VERIFY_REQUIRED.
+ *
+ * NOTE: This code, which is outside of the switch and if/else blocks,
+ * will implicity catch and correctly service IOCTL_DISK_CHECK_VERIFY.
+ * Therefore if we see one below in the switch, we can return STATUS_SUCCESS
+ * immediately.
+ */
+ if(DriveInfo->DeviceObject->Flags & DO_VERIFY_VOLUME && !(DriveInfo->DeviceObject->Flags & SL_OVERRIDE_VERIFY_VOLUME))
{
- INFO_(FLOPPY, "DeviceIoctl(): completing with STATUS_VERIFY_REQUIRED\n");
- Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return;
+ INFO_(FLOPPY, "DeviceIoctl(): completing with STATUS_VERIFY_REQUIRED\n");
+ Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return;
}
- /*
- * Start the drive to see if the disk has changed
- */
- StartMotor(DriveInfo);
+ /*
+ * 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)
+ /*
+ * Check the change line, and if it's set, return
+ */
+ if(HwDiskChanged(DriveInfo, &DiskChanged) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "DeviceIoctl(): unable to sense disk change; completing with STATUS_UNSUCCESSFUL\n");
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
- return;
+ WARN_(FLOPPY, "DeviceIoctl(): unable to sense disk change; completing with STATUS_UNSUCCESSFUL\n");
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ StopMotor(DriveInfo->ControllerInfo);
+ return;
}
- if(DiskChanged)
+ if(DiskChanged)
{
- INFO_(FLOPPY, "DeviceIoctl(): detected disk changed; signalling media change and completing\n");
- SignalMediaChanged(DriveInfo->DeviceObject, Irp);
-
- /*
- * Just guessing here - I have a choice of returning NO_MEDIA or VERIFY_REQUIRED. If there's
- * really no disk in the drive, I'm thinking I can save time by just reporting that fact, rather
- * than forcing windows to ask me twice. If this doesn't work, we'll need to split this up and
- * handle the CHECK_VERIFY IOCTL separately.
- */
- if(ResetChangeFlag(DriveInfo) == STATUS_NO_MEDIA_IN_DEVICE)
- Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
- return;
+ INFO_(FLOPPY, "DeviceIoctl(): detected disk changed; signalling media change and completing\n");
+ SignalMediaChanged(DriveInfo->DeviceObject, Irp);
+
+ /*
+ * Just guessing here - I have a choice of returning NO_MEDIA or VERIFY_REQUIRED. If there's
+ * really no disk in the drive, I'm thinking I can save time by just reporting that fact, rather
+ * than forcing windows to ask me twice. If this doesn't work, we'll need to split this up and
+ * handle the CHECK_VERIFY IOCTL separately.
+ */
+ if(ResetChangeFlag(DriveInfo) == STATUS_NO_MEDIA_IN_DEVICE)
+ Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ StopMotor(DriveInfo->ControllerInfo);
+ return;
}
- switch(Code)
+ switch(Code)
{
case IOCTL_DISK_IS_WRITABLE:
- {
+ {
UCHAR Status;
INFO_(FLOPPY, "IOCTL_DISK_IS_WRITABLE Called\n");
Irp->IoStatus.Information = 0;
if(HwSenseDriveStatus(DriveInfo) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "IoctlDiskIsWritable(): unable to sense drive status\n");
- Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
- break;
- }
-
- /* Now, read the drive's status back */
- if(HwSenseDriveStatusResult(DriveInfo->ControllerInfo, &Status) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "IoctlDiskIsWritable(): unable to read drive status result\n");
- Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
- break;
- }
+ {
+ WARN_(FLOPPY, "IoctlDiskIsWritable(): unable to sense drive status\n");
+ Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
+ break;
+ }
+
+ /* Now, read the drive's status back */
+ if(HwSenseDriveStatusResult(DriveInfo->ControllerInfo, &Status) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "IoctlDiskIsWritable(): unable to read drive status result\n");
+ Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
+ break;
+ }
/* Check to see if the write flag is set. */
if(Status & SR3_WRITE_PROTECT_STATUS_SIGNAL)
- {
+ {
INFO_(FLOPPY, "IOCTL_DISK_IS_WRITABLE: disk is write protected\n");
Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
- }
+ }
else
- Irp->IoStatus.Status = STATUS_SUCCESS;
- }
- break;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ }
+ break;
case IOCTL_DISK_CHECK_VERIFY:
- INFO_(FLOPPY, "IOCTL_DISK_CHECK_VERIFY called\n");
- if (OutputLength != 0)
+ INFO_(FLOPPY, "IOCTL_DISK_CHECK_VERIFY called\n");
+ if (OutputLength != 0)
{
- if (OutputLength < sizeof(ULONG))
- {
- Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
- Irp->IoStatus.Information = 0;
- }
- else
- {
- *((PULONG)OutputBuffer) = DriveInfo->DiskChangeCount;
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = sizeof(ULONG);
- }
- }
- else
+ if (OutputLength < sizeof(ULONG))
+ {
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ Irp->IoStatus.Information = 0;
+ }
+ else
+ {
+ *((PULONG)OutputBuffer) = DriveInfo->DiskChangeCount;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = sizeof(ULONG);
+ }
+ }
+ else
{
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- }
- break;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ }
+ break;
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
- {
+ {
INFO_(FLOPPY, "IOCTL_DISK_GET_DRIVE_GEOMETRY Called\n");
if(OutputLength < sizeof(DISK_GEOMETRY))
- {
+ {
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
break;
- }
+ }
- /* This still works right even if DriveInfo->DiskGeometry->MediaType = Unknown */
- memcpy(OutputBuffer, &DriveInfo->DiskGeometry, sizeof(DISK_GEOMETRY));
+ /* This still works right even if DriveInfo->DiskGeometry->MediaType = Unknown */
+ memcpy(OutputBuffer, &DriveInfo->DiskGeometry, sizeof(DISK_GEOMETRY));
Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
break;
- }
+ }
case IOCTL_DISK_FORMAT_TRACKS:
case IOCTL_DISK_FORMAT_TRACKS_EX:
- ERR_(FLOPPY, "Format called; not supported yet\n");
- Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
- Irp->IoStatus.Information = 0;
- break;
+ ERR_(FLOPPY, "Format called; not supported yet\n");
+ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ Irp->IoStatus.Information = 0;
+ break;
case IOCTL_DISK_GET_PARTITION_INFO:
- INFO_(FLOPPY, "IOCTL_DISK_GET_PARTITION_INFO Called; not supported by a floppy driver\n");
- Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
- Irp->IoStatus.Information = 0;
- break;
+ INFO_(FLOPPY, "IOCTL_DISK_GET_PARTITION_INFO Called; not supported by a floppy driver\n");
+ Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
+ Irp->IoStatus.Information = 0;
+ break;
default:
- ERR_(FLOPPY, "UNKNOWN IOCTL CODE: 0x%x\n", Code);
- Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- Irp->IoStatus.Information = 0;
- break;
+ ERR_(FLOPPY, "UNKNOWN IOCTL CODE: 0x%x\n", Code);
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+ Irp->IoStatus.Information = 0;
+ break;
}
- INFO_(FLOPPY, "ioctl: completing with status 0x%x\n", Irp->IoStatus.Status);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ INFO_(FLOPPY, "ioctl: completing with status 0x%x\n", Irp->IoStatus.Status);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
- return;
+ StopMotor(DriveInfo->ControllerInfo);
+ return;
}
*/
DRIVER_DISPATCH DeviceIoctl;
-NTSTATUS NTAPI DeviceIoctl(PDEVICE_OBJECT DeviceObject,
- PIRP Irp);
-VOID NTAPI DeviceIoctlPassive(PDRIVE_INFO DriveInfo,
- PIRP Irp);
+NTSTATUS NTAPI
+DeviceIoctl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+VOID NTAPI
+DeviceIoctlPassive(PDRIVE_INFO DriveInfo, PIRP Irp);
#include "hardware.h"
#include "readwrite.h"
-\f
-static IO_ALLOCATION_ACTION NTAPI MapRegisterCallback(PDEVICE_OBJECT DeviceObject,
- PIRP Irp,
- PVOID MapRegisterBase,
- PVOID Context)
+
+static IO_ALLOCATION_ACTION NTAPI
+MapRegisterCallback(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PVOID MapRegisterBase,
+ PVOID Context)
/*
* FUNCTION: Acquire map registers in prep for DMA
* ARGUMENTS:
* KeepObject, because that's what the DDK says to do
*/
{
- PCONTROLLER_INFO ControllerInfo = (PCONTROLLER_INFO)Context;
- UNREFERENCED_PARAMETER(DeviceObject);
- UNREFERENCED_PARAMETER(Irp);
+ PCONTROLLER_INFO ControllerInfo = (PCONTROLLER_INFO)Context;
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Irp);
- TRACE_(FLOPPY, "MapRegisterCallback Called\n");
+ TRACE_(FLOPPY, "MapRegisterCallback Called\n");
- ControllerInfo->MapRegisterBase = MapRegisterBase;
- KeSetEvent(&ControllerInfo->SynchEvent, 0, FALSE);
+ ControllerInfo->MapRegisterBase = MapRegisterBase;
+ KeSetEvent(&ControllerInfo->SynchEvent, 0, FALSE);
- return KeepObject;
+ return KeepObject;
}
-\f
-NTSTATUS NTAPI ReadWrite(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+
+NTSTATUS NTAPI
+ReadWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Dispatch routine called for read or write IRPs
* ARGUMENTS:
* it onto the irp queue
*/
{
- TRACE_(FLOPPY, "ReadWrite called\n");
+ TRACE_(FLOPPY, "ReadWrite called\n");
- ASSERT(DeviceObject);
- ASSERT(Irp);
+ ASSERT(DeviceObject);
+ ASSERT(Irp);
- if(!Irp->MdlAddress)
+ if(!Irp->MdlAddress)
{
- WARN_(FLOPPY, "ReadWrite(): MDL not found in IRP - Completing with STATUS_INVALID_PARAMETER\n");
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_INVALID_PARAMETER;
+ WARN_(FLOPPY, "ReadWrite(): MDL not found in IRP - Completing with STATUS_INVALID_PARAMETER\n");
+ Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_INVALID_PARAMETER;
}
- /*
- * Queue the irp to the thread.
- * The de-queue thread will look in DriverContext[0] for the Device Object.
- */
- Irp->Tail.Overlay.DriverContext[0] = DeviceObject;
- IoCsqInsertIrp(&Csq, Irp, NULL);
+ /*
+ * Queue the irp to the thread.
+ * The de-queue thread will look in DriverContext[0] for the Device Object.
+ */
+ Irp->Tail.Overlay.DriverContext[0] = DeviceObject;
+ IoCsqInsertIrp(&Csq, Irp, NULL);
- return STATUS_PENDING;
+ return STATUS_PENDING;
}
-\f
-static VOID NTAPI RWFreeAdapterChannel(PADAPTER_OBJECT AdapterObject)
+
+static VOID NTAPI
+RWFreeAdapterChannel(PADAPTER_OBJECT AdapterObject)
/*
* FUNCTION: Free the adapter DMA channel that we allocated
* ARGUMENTS:
* be called at DISPATCH_LEVEL
*/
{
- KIRQL Irql;
+ KIRQL Irql;
- ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+ ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
- KeRaiseIrql(DISPATCH_LEVEL, &Irql);
- IoFreeAdapterChannel(AdapterObject);
- KeLowerIrql(Irql);
+ KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+ IoFreeAdapterChannel(AdapterObject);
+ KeLowerIrql(Irql);
}
-\f
-static NTSTATUS NTAPI RWDetermineMediaType(PDRIVE_INFO DriveInfo)
+
+static NTSTATUS NTAPI
+RWDetermineMediaType(PDRIVE_INFO DriveInfo)
/*
* FUNCTION: Determine the media type of the disk in the drive and fill in the geometry
* ARGUMENTS:
* - Support more disk types
*/
{
- UCHAR HeadLoadTime;
- UCHAR HeadUnloadTime;
- UCHAR StepRateTime;
+ UCHAR HeadLoadTime;
+ UCHAR HeadUnloadTime;
+ UCHAR StepRateTime;
- PAGED_CODE();
+ PAGED_CODE();
- TRACE_(FLOPPY, "RWDetermineMediaType called\n");
+ TRACE_(FLOPPY, "RWDetermineMediaType called\n");
- /*
- * This algorithm assumes that a 1.44MB floppy is in the drive. If it's not,
- * it works backwards until the read works. Note that only 1.44 has been tested
- * at all.
- */
+ /*
+ * This algorithm assumes that a 1.44MB floppy is in the drive. If it's not,
+ * it works backwards until the read works. Note that only 1.44 has been tested
+ * at all.
+ */
- do
+ do
{
- int i;
-
- /* Program data rate */
- if(HwSetDataRate(DriveInfo->ControllerInfo, DRSR_DSEL_500KBPS) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "RWDetermineMediaType(): unable to set data rate\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- /* Specify */
- HeadLoadTime = SPECIFY_HLT_500K;
- HeadUnloadTime = SPECIFY_HUT_500K;
- StepRateTime = SPECIFY_SRT_500K;
-
- /* Don't disable DMA --> enable dma (dumb & confusing) */
- if(HwSpecify(DriveInfo->ControllerInfo, HeadLoadTime, HeadUnloadTime, StepRateTime, FALSE) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "RWDetermineMediaType(): specify failed\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- /* clear any spurious interrupts in preparation for recalibrate */
- KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
-
- /* Recalibrate --> head over first track */
- for(i=0; i < 2; i++)
- {
- NTSTATUS RecalStatus;
-
- if(HwRecalibrate(DriveInfo) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "RWDetermineMediaType(): Recalibrate 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 */
- {
- WARN_(FLOPPY, "RWDetermineMediaType(): RecalibrateResult failed\n");
- return STATUS_UNSUCCESSFUL;
- }
- }
-
- /* clear any spurious interrupts */
- KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
-
- /* Try to read an ID */
- if(HwReadId(DriveInfo, 0) != STATUS_SUCCESS) /* read the first ID we find, from head 0 */
- {
- WARN_(FLOPPY, "RWDetermineMediaType(): ReadId failed\n");
- return STATUS_UNSUCCESSFUL; /* if we can't even write to the controller, it's hopeless */
- }
-
- /* Wait for the ReadID to finish */
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
-
- if(HwReadIdResult(DriveInfo->ControllerInfo, NULL, NULL) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "RWDetermineMediaType(): ReadIdResult failed; continuing\n");
- continue;
- }
-
- /* Found the media; populate the geometry now */
- WARN_(FLOPPY, "Hardcoded media type!\n");
- INFO_(FLOPPY, "RWDetermineMediaType(): Found 1.44 media; returning success\n");
- DriveInfo->DiskGeometry.MediaType = GEOMETRY_144_MEDIATYPE;
- DriveInfo->DiskGeometry.Cylinders.QuadPart = GEOMETRY_144_CYLINDERS;
- DriveInfo->DiskGeometry.TracksPerCylinder = GEOMETRY_144_TRACKSPERCYLINDER;
- DriveInfo->DiskGeometry.SectorsPerTrack = GEOMETRY_144_SECTORSPERTRACK;
- DriveInfo->DiskGeometry.BytesPerSector = GEOMETRY_144_BYTESPERSECTOR;
- DriveInfo->BytesPerSectorCode = HW_512_BYTES_PER_SECTOR;
- return STATUS_SUCCESS;
+ int i;
+
+ /* Program data rate */
+ if(HwSetDataRate(DriveInfo->ControllerInfo, DRSR_DSEL_500KBPS) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "RWDetermineMediaType(): unable to set data rate\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Specify */
+ HeadLoadTime = SPECIFY_HLT_500K;
+ HeadUnloadTime = SPECIFY_HUT_500K;
+ StepRateTime = SPECIFY_SRT_500K;
+
+ /* Don't disable DMA --> enable dma (dumb & confusing) */
+ if(HwSpecify(DriveInfo->ControllerInfo, HeadLoadTime, HeadUnloadTime, StepRateTime, FALSE) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "RWDetermineMediaType(): specify failed\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* clear any spurious interrupts in preparation for recalibrate */
+ KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
+
+ /* Recalibrate --> head over first track */
+ for(i=0; i < 2; i++)
+ {
+ NTSTATUS RecalStatus;
+
+ if(HwRecalibrate(DriveInfo) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "RWDetermineMediaType(): Recalibrate 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 */
+ {
+ WARN_(FLOPPY, "RWDetermineMediaType(): RecalibrateResult failed\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ /* clear any spurious interrupts */
+ KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
+
+ /* Try to read an ID */
+ if(HwReadId(DriveInfo, 0) != STATUS_SUCCESS) /* read the first ID we find, from head 0 */
+ {
+ WARN_(FLOPPY, "RWDetermineMediaType(): ReadId failed\n");
+ return STATUS_UNSUCCESSFUL; /* if we can't even write to the controller, it's hopeless */
+ }
+
+ /* Wait for the ReadID to finish */
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+
+ if(HwReadIdResult(DriveInfo->ControllerInfo, NULL, NULL) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "RWDetermineMediaType(): ReadIdResult failed; continuing\n");
+ continue;
+ }
+
+ /* Found the media; populate the geometry now */
+ WARN_(FLOPPY, "Hardcoded media type!\n");
+ INFO_(FLOPPY, "RWDetermineMediaType(): Found 1.44 media; returning success\n");
+ DriveInfo->DiskGeometry.MediaType = GEOMETRY_144_MEDIATYPE;
+ DriveInfo->DiskGeometry.Cylinders.QuadPart = GEOMETRY_144_CYLINDERS;
+ DriveInfo->DiskGeometry.TracksPerCylinder = GEOMETRY_144_TRACKSPERCYLINDER;
+ DriveInfo->DiskGeometry.SectorsPerTrack = GEOMETRY_144_SECTORSPERTRACK;
+ DriveInfo->DiskGeometry.BytesPerSector = GEOMETRY_144_BYTESPERSECTOR;
+ DriveInfo->BytesPerSectorCode = HW_512_BYTES_PER_SECTOR;
+ return STATUS_SUCCESS;
}
- while(FALSE);
+ while(FALSE);
- TRACE_(FLOPPY, "RWDetermineMediaType(): failed to find media\n");
- return STATUS_UNRECOGNIZED_MEDIA;
+ TRACE_(FLOPPY, "RWDetermineMediaType(): failed to find media\n");
+ return STATUS_UNRECOGNIZED_MEDIA;
}
-\f
-static NTSTATUS NTAPI RWSeekToCylinder(PDRIVE_INFO DriveInfo,
- UCHAR Cylinder)
+
+static NTSTATUS NTAPI
+RWSeekToCylinder(PDRIVE_INFO DriveInfo, UCHAR Cylinder)
/*
* FUNCTION: Seek a particular drive to a particular track
* ARGUMENTS:
* - PAGED_CODE because it blocks
*/
{
- UCHAR CurCylinder;
+ UCHAR CurCylinder;
- PAGED_CODE();
+ PAGED_CODE();
- TRACE_(FLOPPY, "RWSeekToCylinder called drive 0x%p cylinder %d\n", DriveInfo, Cylinder);
+ TRACE_(FLOPPY, "RWSeekToCylinder called drive 0x%p cylinder %d\n", DriveInfo, Cylinder);
- /* Clear any spurious interrupts */
- KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
+ /* Clear any spurious interrupts */
+ KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
- /* queue seek command */
- if(HwSeek(DriveInfo, Cylinder) != STATUS_SUCCESS)
+ /* queue seek command */
+ if(HwSeek(DriveInfo, Cylinder) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "RWSeekToTrack(): unable to seek\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "RWSeekToTrack(): unable to seek\n");
+ return STATUS_UNSUCCESSFUL;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo);
- if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
+ if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "RWSeekToTrack(): unable to get seek results\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "RWSeekToTrack(): unable to get seek results\n");
+ return STATUS_UNSUCCESSFUL;
}
- /* read ID mark from head 0 to verify */
- if(HwReadId(DriveInfo, 0) != STATUS_SUCCESS)
+ /* read ID mark from head 0 to verify */
+ if(HwReadId(DriveInfo, 0) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "RWSeekToTrack(): unable to queue ReadId\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "RWSeekToTrack(): unable to queue ReadId\n");
+ return STATUS_UNSUCCESSFUL;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo);
- if(HwReadIdResult(DriveInfo->ControllerInfo, &CurCylinder, NULL) != STATUS_SUCCESS)
+ if(HwReadIdResult(DriveInfo->ControllerInfo, &CurCylinder, NULL) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "RWSeekToTrack(): unable to get ReadId result\n");
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "RWSeekToTrack(): unable to get ReadId result\n");
+ return STATUS_UNSUCCESSFUL;
}
- if(CurCylinder != Cylinder)
+ if(CurCylinder != Cylinder)
{
- WARN_(FLOPPY, "RWSeekToTrack(): Seeek to track failed; current cylinder is 0x%x\n", CurCylinder);
- return STATUS_UNSUCCESSFUL;
+ WARN_(FLOPPY, "RWSeekToTrack(): Seeek to track failed; current cylinder is 0x%x\n", CurCylinder);
+ return STATUS_UNSUCCESSFUL;
}
- INFO_(FLOPPY, "RWSeekToCylinder: returning successfully, now on cyl %d\n", Cylinder);
+ INFO_(FLOPPY, "RWSeekToCylinder: returning successfully, now on cyl %d\n", Cylinder);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-static NTSTATUS NTAPI RWComputeCHS(PDRIVE_INFO IN DriveInfo,
- ULONG IN DiskByteOffset,
- PUCHAR OUT Cylinder,
- PUCHAR OUT Head,
- PUCHAR OUT Sector)
+
+static NTSTATUS NTAPI
+RWComputeCHS(PDRIVE_INFO IN DriveInfo,
+ ULONG IN DiskByteOffset,
+ PUCHAR OUT Cylinder,
+ PUCHAR OUT Head,
+ PUCHAR OUT Sector)
/*
* FUNCTION: Compute the CHS from the absolute byte offset on disk
* ARGUMENTS:
* - This is really crummy code. Please FIXME.
*/
{
- ULONG AbsoluteSector;
- UCHAR SectorsPerCylinder = (UCHAR)DriveInfo->DiskGeometry.SectorsPerTrack * (UCHAR)DriveInfo->DiskGeometry.TracksPerCylinder;
+ ULONG AbsoluteSector;
+ UCHAR SectorsPerCylinder = (UCHAR)DriveInfo->DiskGeometry.SectorsPerTrack * (UCHAR)DriveInfo->DiskGeometry.TracksPerCylinder;
- TRACE_(FLOPPY, "RWComputeCHS: Called with offset 0x%x\n", DiskByteOffset);
+ TRACE_(FLOPPY, "RWComputeCHS: Called with offset 0x%x\n", DiskByteOffset);
- /* First calculate the 1-based "absolute sector" based on the byte offset */
- ASSERT(!(DiskByteOffset % DriveInfo->DiskGeometry.BytesPerSector)); /* FIXME: Only handle full sector transfers atm */
+ /* First calculate the 1-based "absolute sector" based on the byte offset */
+ ASSERT(!(DiskByteOffset % DriveInfo->DiskGeometry.BytesPerSector)); /* FIXME: Only handle full sector transfers atm */
- /* AbsoluteSector is zero-based to make the math a little easier */
- AbsoluteSector = DiskByteOffset / DriveInfo->DiskGeometry.BytesPerSector; /* Num full sectors */
+ /* AbsoluteSector is zero-based to make the math a little easier */
+ AbsoluteSector = DiskByteOffset / DriveInfo->DiskGeometry.BytesPerSector; /* Num full sectors */
- /* Cylinder number is floor(AbsoluteSector / SectorsPerCylinder) */
- *Cylinder = (CHAR)(AbsoluteSector / SectorsPerCylinder);
+ /* Cylinder number is floor(AbsoluteSector / SectorsPerCylinder) */
+ *Cylinder = (CHAR)(AbsoluteSector / SectorsPerCylinder);
- /* Head number is 0 if the sector within the cylinder < SectorsPerTrack; 1 otherwise */
- *Head = AbsoluteSector % SectorsPerCylinder < DriveInfo->DiskGeometry.SectorsPerTrack ? 0 : 1;
+ /* Head number is 0 if the sector within the cylinder < SectorsPerTrack; 1 otherwise */
+ *Head = AbsoluteSector % SectorsPerCylinder < DriveInfo->DiskGeometry.SectorsPerTrack ? 0 : 1;
- /*
- * Sector number is the sector within the cylinder if on head 0; that minus SectorsPerTrack if it's on head 1
- * (lots of casts to placate msvc). 1-based!
- */
- *Sector = ((UCHAR)(AbsoluteSector % SectorsPerCylinder) + 1) - ((*Head) * (UCHAR)DriveInfo->DiskGeometry.SectorsPerTrack);
+ /*
+ * Sector number is the sector within the cylinder if on head 0; that minus SectorsPerTrack if it's on head 1
+ * (lots of casts to placate msvc). 1-based!
+ */
+ *Sector = ((UCHAR)(AbsoluteSector % SectorsPerCylinder) + 1) - ((*Head) * (UCHAR)DriveInfo->DiskGeometry.SectorsPerTrack);
- INFO_(FLOPPY, "RWComputeCHS: offset 0x%x is c:0x%x h:0x%x s:0x%x\n", DiskByteOffset, *Cylinder, *Head, *Sector);
+ INFO_(FLOPPY, "RWComputeCHS: offset 0x%x is c:0x%x h:0x%x s:0x%x\n", DiskByteOffset, *Cylinder, *Head, *Sector);
- /* Sanity checking */
- ASSERT(*Cylinder <= DriveInfo->DiskGeometry.Cylinders.QuadPart);
- ASSERT(*Head <= DriveInfo->DiskGeometry.TracksPerCylinder);
- ASSERT(*Sector <= DriveInfo->DiskGeometry.SectorsPerTrack);
+ /* Sanity checking */
+ ASSERT(*Cylinder <= DriveInfo->DiskGeometry.Cylinders.QuadPart);
+ ASSERT(*Head <= DriveInfo->DiskGeometry.TracksPerCylinder);
+ ASSERT(*Sector <= DriveInfo->DiskGeometry.SectorsPerTrack);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-\f
-VOID NTAPI ReadWritePassive(PDRIVE_INFO DriveInfo,
- PIRP Irp)
+
+VOID NTAPI
+ReadWritePassive(PDRIVE_INFO DriveInfo, PIRP Irp)
/*
* FUNCTION: Handle the first phase of a read or write IRP
* ARGUMENTS:
* f) Read the results of the command
*/
{
- PDEVICE_OBJECT DeviceObject = DriveInfo->DeviceObject;
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
- BOOLEAN WriteToDevice;
- ULONG Length;
- ULONG DiskByteOffset;
- KIRQL OldIrql;
- NTSTATUS Status;
- BOOLEAN DiskChanged;
- ULONG_PTR TransferByteOffset;
- UCHAR Gap;
-
- PAGED_CODE();
-
- TRACE_(FLOPPY, "ReadWritePassive called to %s 0x%x bytes from offset 0x%x\n",
- (Stack->MajorFunction == IRP_MJ_READ ? "read" : "write"),
- (Stack->MajorFunction == IRP_MJ_READ ? Stack->Parameters.Read.Length : Stack->Parameters.Write.Length),
- (Stack->MajorFunction == IRP_MJ_READ ? Stack->Parameters.Read.ByteOffset.u.LowPart :
- Stack->Parameters.Write.ByteOffset.u.LowPart));
-
- /* Default return codes */
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
-
- /*
- * Check to see if the volume needs to be verified. If so,
- * we can get out of here quickly.
- */
- if(DeviceObject->Flags & DO_VERIFY_VOLUME && !(DeviceObject->Flags & SL_OVERRIDE_VERIFY_VOLUME))
+ PDEVICE_OBJECT DeviceObject = DriveInfo->DeviceObject;
+ PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+ BOOLEAN WriteToDevice;
+ ULONG Length;
+ ULONG DiskByteOffset;
+ KIRQL OldIrql;
+ NTSTATUS Status;
+ BOOLEAN DiskChanged;
+ ULONG_PTR TransferByteOffset;
+ UCHAR Gap;
+
+ PAGED_CODE();
+
+ TRACE_(FLOPPY, "ReadWritePassive called to %s 0x%x bytes from offset 0x%x\n",
+ (Stack->MajorFunction == IRP_MJ_READ ? "read" : "write"),
+ (Stack->MajorFunction == IRP_MJ_READ ? Stack->Parameters.Read.Length : Stack->Parameters.Write.Length),
+ (Stack->MajorFunction == IRP_MJ_READ ? Stack->Parameters.Read.ByteOffset.u.LowPart :
+ Stack->Parameters.Write.ByteOffset.u.LowPart));
+
+ /* Default return codes */
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ Irp->IoStatus.Information = 0;
+
+ /*
+ * Check to see if the volume needs to be verified. If so,
+ * we can get out of here quickly.
+ */
+ if(DeviceObject->Flags & DO_VERIFY_VOLUME && !(DeviceObject->Flags & SL_OVERRIDE_VERIFY_VOLUME))
{
- INFO_(FLOPPY, "ReadWritePassive(): DO_VERIFY_VOLUME set; Completing with STATUS_VERIFY_REQUIRED\n");
- Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return;
+ INFO_(FLOPPY, "ReadWritePassive(): DO_VERIFY_VOLUME set; Completing with STATUS_VERIFY_REQUIRED\n");
+ Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return;
}
- /*
- * Check the change line, and if it's set, return
- */
- StartMotor(DriveInfo);
- if(HwDiskChanged(DeviceObject->DeviceExtension, &DiskChanged) != STATUS_SUCCESS)
+ /*
+ * Check the change line, and if it's set, return
+ */
+ StartMotor(DriveInfo);
+ if(HwDiskChanged(DeviceObject->DeviceExtension, &DiskChanged) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "ReadWritePassive(): unable to detect disk change; Completing with STATUS_UNSUCCESSFUL\n");
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
- return;
+ WARN_(FLOPPY, "ReadWritePassive(): unable to detect disk change; Completing with STATUS_UNSUCCESSFUL\n");
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ StopMotor(DriveInfo->ControllerInfo);
+ return;
}
- if(DiskChanged)
+ if(DiskChanged)
{
- INFO_(FLOPPY, "ReadWritePhase1(): signalling media changed; Completing with STATUS_MEDIA_CHANGED\n");
+ INFO_(FLOPPY, "ReadWritePhase1(): signalling media changed; Completing with STATUS_MEDIA_CHANGED\n");
- /* The following call sets IoStatus.Status and IoStatus.Information */
- SignalMediaChanged(DeviceObject, Irp);
+ /* The following call sets IoStatus.Status and IoStatus.Information */
+ SignalMediaChanged(DeviceObject, Irp);
- /*
- * Guessing at something... see ioctl.c for more info
- */
- if(ResetChangeFlag(DriveInfo) == STATUS_NO_MEDIA_IN_DEVICE)
- Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
+ /*
+ * Guessing at something... see ioctl.c for more info
+ */
+ if(ResetChangeFlag(DriveInfo) == STATUS_NO_MEDIA_IN_DEVICE)
+ Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
- return;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ StopMotor(DriveInfo->ControllerInfo);
+ return;
}
- /*
- * Figure out the media type, if we don't know it already
- */
- if(DriveInfo->DiskGeometry.MediaType == Unknown)
+ /*
+ * Figure out the media type, if we don't know it already
+ */
+ if(DriveInfo->DiskGeometry.MediaType == Unknown)
{
- if(RWDetermineMediaType(DriveInfo) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "ReadWritePassive(): unable to determine media type; completing with STATUS_UNSUCCESSFUL\n");
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
- return;
- }
-
- if(DriveInfo->DiskGeometry.MediaType == Unknown)
- {
- WARN_(FLOPPY, "ReadWritePassive(): Unknown media in drive; completing with STATUS_UNRECOGNIZED_MEDIA\n");
- Irp->IoStatus.Status = STATUS_UNRECOGNIZED_MEDIA;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
- return;
- }
+ if(RWDetermineMediaType(DriveInfo) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "ReadWritePassive(): unable to determine media type; completing with STATUS_UNSUCCESSFUL\n");
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ StopMotor(DriveInfo->ControllerInfo);
+ return;
+ }
+
+ if(DriveInfo->DiskGeometry.MediaType == Unknown)
+ {
+ WARN_(FLOPPY, "ReadWritePassive(): Unknown media in drive; completing with STATUS_UNRECOGNIZED_MEDIA\n");
+ Irp->IoStatus.Status = STATUS_UNRECOGNIZED_MEDIA;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ StopMotor(DriveInfo->ControllerInfo);
+ return;
+ }
}
- /* Set up parameters for read or write */
- if(Stack->MajorFunction == IRP_MJ_READ)
+ /* Set up parameters for read or write */
+ if(Stack->MajorFunction == IRP_MJ_READ)
{
- Length = Stack->Parameters.Read.Length;
- DiskByteOffset = Stack->Parameters.Read.ByteOffset.u.LowPart;
- WriteToDevice = FALSE;
+ Length = Stack->Parameters.Read.Length;
+ DiskByteOffset = Stack->Parameters.Read.ByteOffset.u.LowPart;
+ WriteToDevice = FALSE;
}
- else
+ else
{
- Length = Stack->Parameters.Write.Length;
- DiskByteOffset = Stack->Parameters.Write.ByteOffset.u.LowPart;
- WriteToDevice = TRUE;
+ Length = Stack->Parameters.Write.Length;
+ DiskByteOffset = Stack->Parameters.Write.ByteOffset.u.LowPart;
+ WriteToDevice = TRUE;
}
- /*
- * FIXME:
- * FloppyDeviceData.ReadWriteGapLength specify the value for the physical drive.
- * We should set this value depend on the format of the inserted disk and possible
- * depend on the request (read or write). A value of 0 results in one rotation
- * between the sectors (7.2sec for reading a track).
- */
- Gap = DriveInfo->FloppyDeviceData.ReadWriteGapLength;
-
- /*
- * Set up DMA transfer
- *
- * This is as good of a place as any to document something that used to confuse me
- * greatly (and I even wrote some of the kernel's DMA code, so if it confuses me, it
- * probably confuses at least a couple of other people too).
- *
- * MmGetMdlVirtualAddress() returns the virtal address, as mapped in the buffer's original
- * process context, of the MDL. In other words: say you start with a buffer at address X, then
- * you build an MDL out of that buffer called Mdl. If you call MmGetMdlVirtualAddress(Mdl), it
- * will return X.
- *
- * There are two parameters that the function looks at to produce X again, given the MDL: the
- * first is the StartVa, which is the base virtual address of the page that the buffer starts
- * in. If your buffer's virtual address is 0x12345678, StartVa will be 0x12345000, assuming 4K pages
- * (which is (almost) always the case on x86). Note well: this address is only valid in the
- * process context that you initially built the MDL from. The physical pages that make up
- * the MDL might perhaps be mapped in other process contexts too (or even in the system space,
- * above 0x80000000 (default; 0xc0000000 on current ReactOS or /3GB Windows)), but it will
- * (possibly) be mapped at a different address.
- *
- * The second parameter is the ByteOffset. Given an original buffer address of 0x12345678,
- * the ByteOffset would be 0x678. Because MDLs can only describe full pages (and therefore
- * StartVa always points to the start address of a page), the ByteOffset must be used to
- * find the real start of the buffer.
- *
- * In general, if you add the StartVa and ByteOffset together, you get back your original
- * buffer pointer, which you are free to use if you're sure you're in the right process
- * context. You could tell by accessing the (hidden and not-to-be-used) Process member of
- * the MDL, but in general, if you have to ask whether or not you are in the right context,
- * then you shouldn't be using this address for anything anyway. There are also security implications
- * (big ones, really, I wouldn't kid about this) to directly accessing a user's buffer by VA, so
- * Don't Do That.
- *
- * There is a somewhat weird but very common use of the virtual address associated with a MDL
- * that pops up often in the context of DMA. DMA APIs (particularly MapTransfer()) need to
- * know where the memory is that they should DMA into and out of. This memory is described
- * by a MDL. The controller eventually needs to know a physical address on the host side,
- * which is generally a 32-bit linear address (on x86), and not just a page address. Therefore,
- * the DMA APIs look at the ByteOffset field of the MDL to reconstruct the real address that
- * should be programmed into the DMA controller.
- *
- * It is often the case that a transfer needs to be broken down over more than one DMA operation,
- * particularly when it is a big transfer and the HAL doesn't give you enough map registers
- * to map the whole thing at once. Therefore, the APIs need a way to tell how far into the MDL
- * they should look to transfer the next chunk of bytes. Now, Microsoft could have designed
- * MapTransfer to take a "MDL offset" argument, starting with 0, for how far into the buffer to
- * start, but it didn't. Instead, MapTransfer asks for the virtual address of the MDL as an "index" into
- * the MDL. The way it computes how far into the page to start the transfer is by masking off all but
- * the bottom 12 bits (on x86) of the number you supply as the CurrentVa and using *that* as the
- * ByteOffset instead of the one in the MDL. (OK, this varies a bit by OS and version, but this
- * is the effect).
- *
- * In other words, you get a number back from MmGetMdlVirtualAddress that represents the start of your
- * buffer, and you pass it to the first MapTransfer call. Then, for each successive operation
- * on the same buffer, you increment that address to point to the next spot in the MDL that
- * you want to DMA to/from. The fact that the virtual address you're manipulating is probably not
- * mapped into the process context that you're running in is irrelevant, since it's only being
- * used to index into the MDL.
- */
-
- /* Get map registers for DMA */
- KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
- Status = IoAllocateAdapterChannel(DriveInfo->ControllerInfo->AdapterObject, DeviceObject,
- DriveInfo->ControllerInfo->MapRegisters, MapRegisterCallback, DriveInfo->ControllerInfo);
- KeLowerIrql(OldIrql);
-
- if(Status != STATUS_SUCCESS)
+ /*
+ * FIXME:
+ * FloppyDeviceData.ReadWriteGapLength specify the value for the physical drive.
+ * We should set this value depend on the format of the inserted disk and possible
+ * depend on the request (read or write). A value of 0 results in one rotation
+ * between the sectors (7.2sec for reading a track).
+ */
+ Gap = DriveInfo->FloppyDeviceData.ReadWriteGapLength;
+
+ /*
+ * Set up DMA transfer
+ *
+ * This is as good of a place as any to document something that used to confuse me
+ * greatly (and I even wrote some of the kernel's DMA code, so if it confuses me, it
+ * probably confuses at least a couple of other people too).
+ *
+ * MmGetMdlVirtualAddress() returns the virtal address, as mapped in the buffer's original
+ * process context, of the MDL. In other words: say you start with a buffer at address X, then
+ * you build an MDL out of that buffer called Mdl. If you call MmGetMdlVirtualAddress(Mdl), it
+ * will return X.
+ *
+ * There are two parameters that the function looks at to produce X again, given the MDL: the
+ * first is the StartVa, which is the base virtual address of the page that the buffer starts
+ * in. If your buffer's virtual address is 0x12345678, StartVa will be 0x12345000, assuming 4K pages
+ * (which is (almost) always the case on x86). Note well: this address is only valid in the
+ * process context that you initially built the MDL from. The physical pages that make up
+ * the MDL might perhaps be mapped in other process contexts too (or even in the system space,
+ * above 0x80000000 (default; 0xc0000000 on current ReactOS or /3GB Windows)), but it will
+ * (possibly) be mapped at a different address.
+ *
+ * The second parameter is the ByteOffset. Given an original buffer address of 0x12345678,
+ * the ByteOffset would be 0x678. Because MDLs can only describe full pages (and therefore
+ * StartVa always points to the start address of a page), the ByteOffset must be used to
+ * find the real start of the buffer.
+ *
+ * In general, if you add the StartVa and ByteOffset together, you get back your original
+ * buffer pointer, which you are free to use if you're sure you're in the right process
+ * context. You could tell by accessing the (hidden and not-to-be-used) Process member of
+ * the MDL, but in general, if you have to ask whether or not you are in the right context,
+ * then you shouldn't be using this address for anything anyway. There are also security implications
+ * (big ones, really, I wouldn't kid about this) to directly accessing a user's buffer by VA, so
+ * Don't Do That.
+ *
+ * There is a somewhat weird but very common use of the virtual address associated with a MDL
+ * that pops up often in the context of DMA. DMA APIs (particularly MapTransfer()) need to
+ * know where the memory is that they should DMA into and out of. This memory is described
+ * by a MDL. The controller eventually needs to know a physical address on the host side,
+ * which is generally a 32-bit linear address (on x86), and not just a page address. Therefore,
+ * the DMA APIs look at the ByteOffset field of the MDL to reconstruct the real address that
+ * should be programmed into the DMA controller.
+ *
+ * It is often the case that a transfer needs to be broken down over more than one DMA operation,
+ * particularly when it is a big transfer and the HAL doesn't give you enough map registers
+ * to map the whole thing at once. Therefore, the APIs need a way to tell how far into the MDL
+ * they should look to transfer the next chunk of bytes. Now, Microsoft could have designed
+ * MapTransfer to take a "MDL offset" argument, starting with 0, for how far into the buffer to
+ * start, but it didn't. Instead, MapTransfer asks for the virtual address of the MDL as an "index" into
+ * the MDL. The way it computes how far into the page to start the transfer is by masking off all but
+ * the bottom 12 bits (on x86) of the number you supply as the CurrentVa and using *that* as the
+ * ByteOffset instead of the one in the MDL. (OK, this varies a bit by OS and version, but this
+ * is the effect).
+ *
+ * In other words, you get a number back from MmGetMdlVirtualAddress that represents the start of your
+ * buffer, and you pass it to the first MapTransfer call. Then, for each successive operation
+ * on the same buffer, you increment that address to point to the next spot in the MDL that
+ * you want to DMA to/from. The fact that the virtual address you're manipulating is probably not
+ * mapped into the process context that you're running in is irrelevant, since it's only being
+ * used to index into the MDL.
+ */
+
+ /* Get map registers for DMA */
+ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+ Status = IoAllocateAdapterChannel(DriveInfo->ControllerInfo->AdapterObject, DeviceObject,
+ DriveInfo->ControllerInfo->MapRegisters, MapRegisterCallback, DriveInfo->ControllerInfo);
+ KeLowerIrql(OldIrql);
+
+ if(Status != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "ReadWritePassive(): unable allocate an adapter channel; completing with STATUS_UNSUCCESSFUL\n");
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
- return ;
+ WARN_(FLOPPY, "ReadWritePassive(): unable allocate an adapter channel; completing with STATUS_UNSUCCESSFUL\n");
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ StopMotor(DriveInfo->ControllerInfo);
+ return ;
}
- /*
- * Read from (or write to) the device
- *
- * This has to be called in a loop, as you can only transfer data to/from a single track at
- * a time.
- */
- TransferByteOffset = 0;
- while(TransferByteOffset < Length)
+ /*
+ * Read from (or write to) the device
+ *
+ * This has to be called in a loop, as you can only transfer data to/from a single track at
+ * a time.
+ */
+ TransferByteOffset = 0;
+ while(TransferByteOffset < Length)
{
- UCHAR Cylinder;
- UCHAR Head;
- UCHAR StartSector;
- ULONG CurrentTransferBytes;
- UCHAR CurrentTransferSectors;
-
- INFO_(FLOPPY, "ReadWritePassive(): iterating in while (TransferByteOffset = 0x%x of 0x%x total) - allocating %d registers\n",
- TransferByteOffset, Length, DriveInfo->ControllerInfo->MapRegisters);
-
- KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
-
- /*
- * Compute starting CHS
- */
- if(RWComputeCHS(DriveInfo, DiskByteOffset+TransferByteOffset, &Cylinder, &Head, &StartSector) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "ReadWritePassive(): unable to compute CHS; completing with STATUS_UNSUCCESSFUL\n");
- RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
- return;
- }
-
- /*
- * Seek to the right track
- */
- if(!DriveInfo->ControllerInfo->ImpliedSeeks)
+ UCHAR Cylinder;
+ UCHAR Head;
+ UCHAR StartSector;
+ ULONG CurrentTransferBytes;
+ UCHAR CurrentTransferSectors;
+
+ INFO_(FLOPPY, "ReadWritePassive(): iterating in while (TransferByteOffset = 0x%x of 0x%x total) - allocating %d registers\n",
+ TransferByteOffset, Length, DriveInfo->ControllerInfo->MapRegisters);
+
+ KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
+
+ /*
+ * Compute starting CHS
+ */
+ if(RWComputeCHS(DriveInfo, DiskByteOffset+TransferByteOffset, &Cylinder, &Head, &StartSector) != STATUS_SUCCESS)
{
- if(RWSeekToCylinder(DriveInfo, Cylinder) != STATUS_SUCCESS)
+ WARN_(FLOPPY, "ReadWritePassive(): unable to compute CHS; completing with STATUS_UNSUCCESSFUL\n");
+ RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ StopMotor(DriveInfo->ControllerInfo);
+ return;
+ }
+
+ /*
+ * Seek to the right track
+ */
+ if(!DriveInfo->ControllerInfo->ImpliedSeeks)
+ {
+ if(RWSeekToCylinder(DriveInfo, Cylinder) != STATUS_SUCCESS)
{
- WARN_(FLOPPY, "ReadWritePassive(): unable to seek; completing with STATUS_UNSUCCESSFUL\n");
- RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
- return ;
- }
+ WARN_(FLOPPY, "ReadWritePassive(): unable to seek; completing with STATUS_UNSUCCESSFUL\n");
+ RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ StopMotor(DriveInfo->ControllerInfo);
+ return ;
+ }
}
- /*
- * Compute last sector
- *
- * We can only ask for a transfer up to the end of the track. Then we have to re-seek and do more.
- * TODO: Support the MT bit
- */
- INFO_(FLOPPY, "ReadWritePassive(): computing number of sectors to transfer (StartSector 0x%x): ", StartSector);
-
- /* 1-based sector number */
- if( (((DriveInfo->DiskGeometry.TracksPerCylinder - Head) * DriveInfo->DiskGeometry.SectorsPerTrack - StartSector) + 1 ) <
- (Length - TransferByteOffset) / DriveInfo->DiskGeometry.BytesPerSector)
- {
- CurrentTransferSectors = (UCHAR)((DriveInfo->DiskGeometry.TracksPerCylinder - Head) * DriveInfo->DiskGeometry.SectorsPerTrack - StartSector) + 1;
- }
- else
- {
- CurrentTransferSectors = (UCHAR)((Length - TransferByteOffset) / DriveInfo->DiskGeometry.BytesPerSector);
- }
-
- INFO_(FLOPPY, "0x%x\n", CurrentTransferSectors);
-
- CurrentTransferBytes = CurrentTransferSectors * DriveInfo->DiskGeometry.BytesPerSector;
-
- /*
- * Adjust to map registers
- * BUG: Does this take into account page crossings?
- */
- INFO_(FLOPPY, "ReadWritePassive(): Trying to transfer 0x%x bytes\n", CurrentTransferBytes);
-
- ASSERT(CurrentTransferBytes);
-
- if(BYTES_TO_PAGES(CurrentTransferBytes) > DriveInfo->ControllerInfo->MapRegisters)
+ /*
+ * Compute last sector
+ *
+ * We can only ask for a transfer up to the end of the track. Then we have to re-seek and do more.
+ * TODO: Support the MT bit
+ */
+ INFO_(FLOPPY, "ReadWritePassive(): computing number of sectors to transfer (StartSector 0x%x): ", StartSector);
+
+ /* 1-based sector number */
+ if( (((DriveInfo->DiskGeometry.TracksPerCylinder - Head) * DriveInfo->DiskGeometry.SectorsPerTrack - StartSector) + 1 ) <
+ (Length - TransferByteOffset) / DriveInfo->DiskGeometry.BytesPerSector)
+ {
+ CurrentTransferSectors = (UCHAR)((DriveInfo->DiskGeometry.TracksPerCylinder - Head) * DriveInfo->DiskGeometry.SectorsPerTrack - StartSector) + 1;
+ }
+ else
{
- CurrentTransferSectors = (UCHAR)((DriveInfo->ControllerInfo->MapRegisters * PAGE_SIZE) /
- DriveInfo->DiskGeometry.BytesPerSector);
+ CurrentTransferSectors = (UCHAR)((Length - TransferByteOffset) / DriveInfo->DiskGeometry.BytesPerSector);
+ }
+
+ INFO_(FLOPPY, "0x%x\n", CurrentTransferSectors);
+
+ CurrentTransferBytes = CurrentTransferSectors * DriveInfo->DiskGeometry.BytesPerSector;
- CurrentTransferBytes = CurrentTransferSectors * DriveInfo->DiskGeometry.BytesPerSector;
+ /*
+ * Adjust to map registers
+ * BUG: Does this take into account page crossings?
+ */
+ INFO_(FLOPPY, "ReadWritePassive(): Trying to transfer 0x%x bytes\n", CurrentTransferBytes);
- INFO_(FLOPPY, "ReadWritePassive: limiting transfer to 0x%x bytes (0x%x sectors) due to map registers\n",
- CurrentTransferBytes, CurrentTransferSectors);
+ ASSERT(CurrentTransferBytes);
+
+ if(BYTES_TO_PAGES(CurrentTransferBytes) > DriveInfo->ControllerInfo->MapRegisters)
+ {
+ CurrentTransferSectors = (UCHAR)((DriveInfo->ControllerInfo->MapRegisters * PAGE_SIZE) /
+ DriveInfo->DiskGeometry.BytesPerSector);
+
+ CurrentTransferBytes = CurrentTransferSectors * DriveInfo->DiskGeometry.BytesPerSector;
+
+ INFO_(FLOPPY, "ReadWritePassive: limiting transfer to 0x%x bytes (0x%x sectors) due to map registers\n",
+ CurrentTransferBytes, CurrentTransferSectors);
+ }
+
+ /* set up this round's dma operation */
+ /* param 2 is ReadOperation --> opposite of WriteToDevice that IoMapTransfer takes. BAD MS. */
+ KeFlushIoBuffers(Irp->MdlAddress, !WriteToDevice, TRUE);
+
+ IoMapTransfer(DriveInfo->ControllerInfo->AdapterObject, Irp->MdlAddress,
+ DriveInfo->ControllerInfo->MapRegisterBase,
+ (PVOID)((ULONG_PTR)MmGetMdlVirtualAddress(Irp->MdlAddress) + TransferByteOffset),
+ &CurrentTransferBytes, WriteToDevice);
+
+ /*
+ * Read or Write
+ */
+ KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
+
+ /* Issue the read/write command to the controller. Note that it expects the opposite of WriteToDevice. */
+ if(HwReadWriteData(DriveInfo->ControllerInfo, !WriteToDevice, DriveInfo->UnitNumber, Cylinder, Head, StartSector,
+ DriveInfo->BytesPerSectorCode, DriveInfo->DiskGeometry.SectorsPerTrack, Gap, 0xff) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "ReadWritePassive(): HwReadWriteData returned failure; unable to read; completing with STATUS_UNSUCCESSFUL\n");
+ RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ StopMotor(DriveInfo->ControllerInfo);
+ return ;
+ }
+
+ INFO_(FLOPPY, "ReadWritePassive(): HwReadWriteData returned -- waiting on event\n");
+
+ /*
+ * At this point, we block and wait for an interrupt
+ * FIXME: this seems to take too long
+ */
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+
+ /* Read is complete; flush & free adapter channel */
+ IoFlushAdapterBuffers(DriveInfo->ControllerInfo->AdapterObject, Irp->MdlAddress,
+ DriveInfo->ControllerInfo->MapRegisterBase,
+ (PVOID)((ULONG_PTR)MmGetMdlVirtualAddress(Irp->MdlAddress) + TransferByteOffset),
+ CurrentTransferBytes, WriteToDevice);
+
+ /* Read the results from the drive */
+ if(HwReadWriteResult(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
+ {
+ WARN_(FLOPPY, "ReadWritePassive(): HwReadWriteResult returned failure; unable to read; completing with STATUS_UNSUCCESSFUL\n");
+ HwDumpRegisters(DriveInfo->ControllerInfo);
+ RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ StopMotor(DriveInfo->ControllerInfo);
+ return ;
}
- /* set up this round's dma operation */
- /* param 2 is ReadOperation --> opposite of WriteToDevice that IoMapTransfer takes. BAD MS. */
- KeFlushIoBuffers(Irp->MdlAddress, !WriteToDevice, TRUE);
-
- IoMapTransfer(DriveInfo->ControllerInfo->AdapterObject, Irp->MdlAddress,
- DriveInfo->ControllerInfo->MapRegisterBase,
- (PVOID)((ULONG_PTR)MmGetMdlVirtualAddress(Irp->MdlAddress) + TransferByteOffset),
- &CurrentTransferBytes, WriteToDevice);
-
- /*
- * Read or Write
- */
- KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
-
- /* Issue the read/write command to the controller. Note that it expects the opposite of WriteToDevice. */
- if(HwReadWriteData(DriveInfo->ControllerInfo, !WriteToDevice, DriveInfo->UnitNumber, Cylinder, Head, StartSector,
- DriveInfo->BytesPerSectorCode, DriveInfo->DiskGeometry.SectorsPerTrack, Gap, 0xff) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "ReadWritePassive(): HwReadWriteData returned failure; unable to read; completing with STATUS_UNSUCCESSFUL\n");
- RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
- return ;
- }
-
- INFO_(FLOPPY, "ReadWritePassive(): HwReadWriteData returned -- waiting on event\n");
-
- /*
- * At this point, we block and wait for an interrupt
- * FIXME: this seems to take too long
- */
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
-
- /* Read is complete; flush & free adapter channel */
- IoFlushAdapterBuffers(DriveInfo->ControllerInfo->AdapterObject, Irp->MdlAddress,
- DriveInfo->ControllerInfo->MapRegisterBase,
- (PVOID)((ULONG_PTR)MmGetMdlVirtualAddress(Irp->MdlAddress) + TransferByteOffset),
- CurrentTransferBytes, WriteToDevice);
-
- /* Read the results from the drive */
- if(HwReadWriteResult(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "ReadWritePassive(): HwReadWriteResult returned failure; unable to read; completing with STATUS_UNSUCCESSFUL\n");
- HwDumpRegisters(DriveInfo->ControllerInfo);
- RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
- return ;
- }
-
- TransferByteOffset += CurrentTransferBytes;
+ TransferByteOffset += CurrentTransferBytes;
}
- RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
+ RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
- /* That's all folks! */
- INFO_(FLOPPY, "ReadWritePassive(): success; Completing with STATUS_SUCCESS\n");
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = Length;
- IoCompleteRequest(Irp, IO_DISK_INCREMENT);
- StopMotor(DriveInfo->ControllerInfo);
+ /* That's all folks! */
+ INFO_(FLOPPY, "ReadWritePassive(): success; Completing with STATUS_SUCCESS\n");
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = Length;
+ IoCompleteRequest(Irp, IO_DISK_INCREMENT);
+ StopMotor(DriveInfo->ControllerInfo);
}
*/
DRIVER_DISPATCH ReadWrite;
-NTSTATUS NTAPI ReadWrite(PDEVICE_OBJECT DeviceObject,
- PIRP Irp);
-VOID NTAPI ReadWritePassive(PDRIVE_INFO DriveInfo, PIRP Irp);
+NTSTATUS NTAPI
+ReadWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+VOID NTAPI
+ReadWritePassive(PDRIVE_INFO DriveInfo, PIRP Irp);