Initial revision

svn path=/trunk/; revision=56
This commit is contained in:
Rex Jolliff 1998-10-05 04:55:44 +00:00
parent 3f988bd286
commit c38258c97a
2 changed files with 293 additions and 0 deletions

View File

@ -0,0 +1,218 @@
//
// FLOPPY.C - NEC-765/8272A floppy device driver
// written by Rex Jolliff
// with help from various other sources, including but not limited to:
// Art Baker's NT Device Driver Book, Linux Source, and the internet.
//
// Modification History:
// 08/19/98 RJJ Created.
//
#include <ddk/ntddk.h>
#include "floppy.h"
#define VERSION "V0.0.1"
// --------------------------------------------------- File Statics
// ------------------------------------------------------ Functions
// ModuleEntry
//
// DESCRIPTION:
// This function initializes the driver, locates and claims
// hardware resources, and creates various NT objects needed
// to process I/O requests.
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// IN PDRIVER_OBJECT DriverObject System allocated Driver Object
// for this driver
// IN PUNICODE_STRING RegistryPath Name of registry driver service
// key
//
// RETURNS:
// NTSTATUS
NTSTATUS ModuleEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
) {
NTSTATUS RC;
PFLOPPY_DEVICE_EXTENSION DeviceExtension;
// Export other driver entry points...
DriverObject->DriverStartIo = FloppyStartIo;
DriverObject->MajorFunction[IRP_MJ_CREATE] = FloppyDispatchOpenClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FloppyDispatchOpenClose;
DriverObject->MajorFunction[IRP_MJ_READ] = FloppyDispatchReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = FloppyDispatchReadWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FloppyDispatchDeviceControl;
// FIXME: Try to detect floppy and abort if it fails
// Create a device object for the floppy
RC = IoCreateDevice(DriverObject,
sizeof(FLOPPY_DEVICE_EXTENSION),
DeviceName,
FILE_DEVICE_DISK,
0,
TRUE,
&DeviceObject);
if (!NT_SUCCESS(RC)) {
DPRINT("Could not create device for floppy");
return STATUS_NO_SUCH_DEVICE;
}
// Fill out Device Extension
DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)
DeviceObject->DeviceExtension;
DeviceExtension->Number = 0;
DeviceExtension->PortBase = FLOPPY_PORT_BASE;
DeviceExtension->Vector = FLOPPY_IRQ_VECTOR;
DeviceExtension->IrqL = FLOPPY_DIRQL;
DeviceExtension->DMASupported = FALSE;
DeviceExtension->FloppyState = FloppyStateIdle;
// Register an interrupt handler for this device
RC = IoConnectInterrupt(&DeviceExtension->Interrupt,
FloppyIsr, DeviceExtension, NULL,
DeviceExtension->Vector, DeviceExtension->IrqL,
DeviceExtension->IrqL, FLOPPY_IRQ_MODE,
FALSE, FLOPPY_AFFINITY, FALSE);
if (!NT_SUCCESS(RC)) {
DPRINT("Could not Connect Interrupt %d\n", DeviceExtension->Vector);
return STATUS_NO_SUCH_DEVICE;
}
// FIXME: register a DMA handler if needed for this controller
return STATUS_SUCCESS;
}
// FloppyGetControllerVersion
//
// DESCRIPTION
// Get the type/version of the floppy controller
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// IN OUT PFLOPPY_DEVICE_EXTENSION DeviceExtension
//
// RETURNS:
// BOOL success or failure
//
// COMMENTS:
// This routine (get_fdc_version) was originally written by David C. Niemi
//
static BOOLEAN FloppyGetControllerVersion(
IN OUT PFLOPPY_DEVICE_EXTENSION DeviceExtension
) {
int Result;
FLOPPY_CMD CommandToSend;
FLOPPY_RESULT ResultReturned
CommandToSend.CMd[0] = FLOPPY_CMD_FD_DUMPREGS;
FloppyWriteCommand(DeviceExtension->PortBase, &CommandToSend, &ResultReturned);
/* 82072 and better know DUMPREGS */
if (FDCS->reset)
return FDC_NONE;
if ((r = result()) <= 0x00)
return FDC_NONE; /* No FDC present ??? */
if ((r==1) && (reply_buffer[0] == 0x80)){
printk(KERN_INFO "FDC %d is an 8272A\n",fdc);
return FDC_8272A; /* 8272a/765 don't know DUMPREGS */
}
if (r != 10) {
printk("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n",
fdc, r);
return FDC_UNKNOWN;
}
if(!fdc_configure()) {
printk(KERN_INFO "FDC %d is an 82072\n",fdc);
return FDC_82072; /* 82072 doesn't know CONFIGURE */
}
output_byte(FD_PERPENDICULAR);
if(need_more_output() == MORE_OUTPUT) {
output_byte(0);
} else {
printk(KERN_INFO "FDC %d is an 82072A\n", fdc);
return FDC_82072A; /* 82072A as found on Sparcs. */
}
output_byte(FD_UNLOCK);
r = result();
if ((r == 1) && (reply_buffer[0] == 0x80)){
printk(KERN_INFO "FDC %d is a pre-1991 82077\n", fdc);
return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know
* LOCK/UNLOCK */
}
if ((r != 1) || (reply_buffer[0] != 0x00)) {
printk("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
fdc, r);
return FDC_UNKNOWN;
}
output_byte(FD_PARTID);
r = result();
if (r != 1) {
printk("FDC %d init: PARTID: unexpected return of %d bytes.\n",
fdc, r);
return FDC_UNKNOWN;
}
if (reply_buffer[0] == 0x80) {
printk(KERN_INFO "FDC %d is a post-1991 82077\n",fdc);
return FDC_82077; /* Revised 82077AA passes all the tests */
}
switch (reply_buffer[0] >> 5) {
case 0x0:
/* Either a 82078-1 or a 82078SL running at 5Volt */
printk(KERN_INFO "FDC %d is an 82078.\n",fdc);
return FDC_82078;
case 0x1:
printk(KERN_INFO "FDC %d is a 44pin 82078\n",fdc);
return FDC_82078;
case 0x2:
printk(KERN_INFO "FDC %d is a S82078B\n", fdc);
return FDC_S82078B;
case 0x3:
printk(KERN_INFO "FDC %d is a National Semiconductor PC87306\n", fdc);
return FDC_87306;
default:
printk(KERN_INFO "FDC %d init: 82078 variant with unknown PARTID=%d.\n",
fdc, reply_buffer[0] >> 5);
return FDC_82078_UNKN;
}
} /* get_fdc_version */
static NTSTATUS FloppyStartIo(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
) {
PIO_STACK_LOCATION IrpStack;
PFLOPPY_DEVICE_EXTENSION DeviceExtension;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
DeviceExtension = (PFLOPPY_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
}
FloppyDispatchOpenClose
FloppyDispatchReadWrite
FloppyDispatchDeviceControl
FloppyIsr

View File

@ -0,0 +1,75 @@
#define FLOPPY_REG_DOR 0x0002
#define FLOPPY_REG_MSTAT 0x0004
#define FLOPPY_MS_DRV0BUSY 0x01
#define FLOPPY_MS_DRV1BUSY 0x02
#define FLOPPY_MS_DRV2BUSY 0x04
#define FLOPPY_MS_DRV3BUSY 0x08
#define FLOPPY_MS_FDCBUSY 0x10
#define FLOPPY_MS_DMAMODE 0x20
#define FLOPPY_MS_DATADIR 0x40
#define FLOPPY_MS_DATARDY 0x80
#define FLOPPY_REG_DATA 0x0005
#define FLOPPY_REG_DIR 0x0007 /* READ ONLY */
#define FLOPPY_DI_DSKCHNG 0x80
#define FLOPPY_REG_CCNTL 0x0007 /* WRITE ONLY */
#define FLOPPY_CMD_RD_TRK 0x02
#define FLOPPY_CMD_SPEC_CHARS 0x03
#define FLOPPY_CSC_SRT_SHIFT 4
#define FLOPPY_CSC_HUT_MASK 0x0f
#define FLOPPY_CSC_HLT_SHIFT 1
#define FLOPPY_CSC_NON_DMA 0x01
#define FLOPPY_CMD_SNS_DRV 0x04
#define FLOPPY_CMD_WRT_DATA 0x05
#define FLOPPY_CMD_RD_DATA 0x06
#define FLOPPY_CMD_RECAL 0x07
#define FLOPPY_CMD_SNS_INTR 0x08
#define FLOPPY_CSI_IC_MASK 0xe0
#define FLOPPY_CSI_IC_RDYCH 0x60
#define FLOPPY_CSI_IC_SEEKGD 0x80
#define FLOPPY_CSI_IC_SEEKBD 0xc0
#define FLOPPY_CMD_WRT_DEL 0x09
#define FLOPPY_CMD_RD_ID 0x0a
#define FLOPPY_CMD_RD_DEL 0x0c
#define FLOPPY_CMD_FMT_TRK 0x0d
#define FLOPPY_CMD_DUMP_FDC 0x0e
#define FLOPPY_CMD_SEEK 0x0f
#define FLOPPY_CMD_VERSION 0x10
#define FLOPPY_CMD_SCN_EQ 0x11
#define FLOPPY_CMD_PPND_RW 0x12
#define FLOPPY_CMD_CFG_FIFO 0x13
#define FLOPPY_CMD_LCK_FIFO 0x14
#define FLOPPY_CMD_PARTID 0x18
#define FLOPPY_CMD_SCN_LE 0x19
#define FLOPPY_CMD_SCN_GE 0x1d
#define FLOPPY_CMD_CFG_PWR 0x27
#define FLOPPY_CMD_SAVE_FDC 0x2e
#define FLOPPY_CMD_FMT_ISO 0x33
#define FLOPPY_CMD_DMA_READ 0x46
#define FLOPPY_CMD_DMA_WRT 0x4a
#define FLOPPY_CMD_REST_FDC 0x4e
#define FLOPPY_CMD_DRV_SPEC 0x8e
#define FLOPPY_CMD_RSEEK_OUT 0x8f
#define FLOPPY_CMD_ULK_FIFO 0x94
#define FLOPPY_CMD_RSEEK_IN 0xcf
#define FLOPPY_CMD_FMT_WRT 0xef
// Command Code modifiers
#define FLOPPY_C0M_SK 0x20
#define FLOPPY_C0M_MFM 0x40
#define FLOPPY_C0M_MT 0x80
#define FLOPPY_C1M_DRVMASK 0x03
#define FLOPPY_C1M_HEAD1 0x04
// Status code values and masks
#define FLOPPY_ST0_INVALID 0x80
// useful command defines
#define FLOPPY_CMD_READ (FLOPPY_CMD_RD_DATA | FLOPPY_C0M_SK | FLOPPY_C0M_MFM | FLOPPY_C0M_MT)
#define FLOPPY_CMD_WRITE (FLOPPY_CMD_WRT_DATA | FLOPPY_C0M_MFM | FLOPPY_C0M_MT)
#define FLOPPY_CMD_FORMAT (FLOPPY_CMD_FMT_TRK | FLOPPY_C0M_MFM)