You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1052 lines
28 KiB
1052 lines
28 KiB
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 1991 - 1999
|
|
|
|
Module Name:
|
|
|
|
fdc_data.h
|
|
|
|
Abstract:
|
|
|
|
This file includes data and hardware declarations for the NEC PD765
|
|
(aka AT, ISA, and ix86) and Intel 82077 (aka MIPS) floppy driver for
|
|
NT.
|
|
|
|
Author:
|
|
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Notes:
|
|
|
|
|
|
--*/
|
|
|
|
|
|
#if DBG
|
|
//
|
|
// For checked kernels, define a macro to print out informational
|
|
// messages.
|
|
//
|
|
// FdcDebug is normally 0. At compile-time or at run-time, it can be
|
|
// set to some bit pattern for increasingly detailed messages.
|
|
//
|
|
// Big, nasty errors are noted with DBGP. Errors that might be
|
|
// recoverable are handled by the WARN bit. More information on
|
|
// unusual but possibly normal happenings are handled by the INFO bit.
|
|
// And finally, boring details such as routines entered and register
|
|
// dumps are handled by the SHOW bit.
|
|
//
|
|
#define FDCDBGP ((ULONG)0x00000001)
|
|
#define FDCWARN ((ULONG)0x00000002)
|
|
#define FDCINFO ((ULONG)0x00000004)
|
|
#define FDCSHOW ((ULONG)0x00000008)
|
|
#define FDCIRPPATH ((ULONG)0x00000010)
|
|
#define FDCFORMAT ((ULONG)0x00000020)
|
|
#define FDCSTATUS ((ULONG)0x00000040)
|
|
|
|
extern ULONG FdcDebugLevel;
|
|
#define FdcDump(LEVEL,STRING) \
|
|
do { \
|
|
if (FdcDebugLevel & LEVEL) { \
|
|
DbgPrint STRING; \
|
|
} \
|
|
} while (0)
|
|
#else
|
|
#define FdcDump(LEVEL,STRING) do {NOTHING;} while (0)
|
|
#endif
|
|
|
|
|
|
//
|
|
// Macros to access the controller. Note that the *_PORT_UCHAR macros
|
|
// work on all machines, whether the I/O ports are separate or in
|
|
// memory space.
|
|
//
|
|
|
|
#define READ_CONTROLLER( Address ) \
|
|
READ_PORT_UCHAR( ( PUCHAR )Address )
|
|
|
|
#define WRITE_CONTROLLER( Address, Value ) \
|
|
WRITE_PORT_UCHAR( ( PUCHAR )Address, ( UCHAR )Value )
|
|
|
|
|
|
//
|
|
// Retry counts -
|
|
//
|
|
// When moving a byte to/from the FIFO, we sit in a tight loop for a while
|
|
// waiting for the controller to become ready. The number of times through
|
|
// the loop is controlled by FIFO_TIGHTLOOP_RETRY_COUNT. When that count
|
|
// expires, we'll wait in 10ms increments. FIFO_DELAY_RETRY_COUNT controls
|
|
// how many times we wait.
|
|
//
|
|
// The ISR_SENSE_RETRY_COUNT is the maximum number of 1 microsecond
|
|
// stalls that the ISR will do waiting for the controller to accept
|
|
// a SENSE INTERRUPT command. We do this because there is a hardware
|
|
// quirk in at least the NCR 8 processor machine where it can take
|
|
// up to 50 microseconds to accept the command.
|
|
//
|
|
// When attempting I/O, we may run into many different errors. The
|
|
// hardware retries things 8 times invisibly. If the hardware reports
|
|
// any type of error, we will recalibrate and retry the operation
|
|
// up to RECALIBRATE_RETRY_COUNT times. When this expires, we check to
|
|
// see if there's an overrun - if so, the DMA is probably being hogged
|
|
// by a higher priority device, so we repeat the earlier loop up to
|
|
// OVERRUN_RETRY_COUNT times.
|
|
//
|
|
// Any packet that is about to be returned with an error caused by an
|
|
// unexpected hardware error or state will be restarted from the very
|
|
// beginning after resetting the hardware HARDWARE_RESET_RETRY_COUNT
|
|
// times.
|
|
//
|
|
|
|
#define FIFO_TIGHTLOOP_RETRY_COUNT 500
|
|
#define FIFO_ISR_TIGHTLOOP_RETRY_COUNT 25
|
|
#define ISR_SENSE_RETRY_COUNT 50
|
|
#define FIFO_DELAY_RETRY_COUNT 5
|
|
#define RECALIBRATE_RETRY_COUNT 3
|
|
#define OVERRUN_RETRY_COUNT 1
|
|
#define HARDWARE_RESET_RETRY_COUNT 2
|
|
#define FLOPPY_RESET_ISR_THRESHOLD 20
|
|
#define RQM_READY_RETRY_COUNT 100
|
|
|
|
#define ONE_SECOND (10 * 1000 * 1000) // 100ns increments
|
|
#define CANCEL_TIMER -1
|
|
#define START_TIMER (IsNEC_98 ? 15 : 9)
|
|
#define EXPIRED_TIMER 0
|
|
|
|
#define RESET_NOT_RESETTING 0
|
|
#define RESET_DRIVE_RESETTING 1
|
|
|
|
//
|
|
// Need some maximum size values so that we can appropriately set up the DMA
|
|
// channels
|
|
//
|
|
|
|
#define MAX_BYTES_PER_SECTOR (IsNEC_98 ? 1024 : 512)
|
|
#define MAX_SECTORS_PER_TRACK 36
|
|
|
|
|
|
//
|
|
// Boot Configuration Information
|
|
//
|
|
|
|
//
|
|
// Define the maximum number of controllers and floppies per controller
|
|
// that this driver will support.
|
|
//
|
|
// The number of floppies per controller is fixed at 4, since the
|
|
// controllers don't have enough bits to select more than that (and
|
|
// actually, many controllers will only support 2). The number of
|
|
// controllers per machine is arbitrary; 3 should be more than enough.
|
|
//
|
|
|
|
#define MAXIMUM_CONTROLLERS_PER_MACHINE 3
|
|
#define MAXIMUM_DISKETTES_PER_CONTROLLER 4
|
|
|
|
//
|
|
// Floppy register structure. The base address of the controller is
|
|
// passed in by configuration management. Note that this is the 82077
|
|
// structure, which is a superset of the PD765 structure. Not all of
|
|
// the registers are used.
|
|
//
|
|
|
|
typedef union _CONTROLLER {
|
|
|
|
struct {
|
|
PUCHAR StatusA;
|
|
PUCHAR StatusB;
|
|
PUCHAR DriveControl;
|
|
PUCHAR Tape;
|
|
PUCHAR Status;
|
|
PUCHAR Fifo;
|
|
PUCHAR Reserved;
|
|
union {
|
|
PUCHAR DataRate;
|
|
PUCHAR DiskChange;
|
|
} DRDC;
|
|
PUCHAR ModeChange; // for NEC98 : 0xbe
|
|
PUCHAR ModeChangeEx; // for NEC98 : 0x4be
|
|
};
|
|
|
|
PUCHAR Address[8];
|
|
|
|
} CONTROLLER, *PCONTROLLER;
|
|
|
|
//
|
|
// Io Port address information structure. This structure is used to save
|
|
// information about ioport addresses as it is collected from a resource
|
|
// requirements list.
|
|
//
|
|
typedef struct _IO_PORT_INFO {
|
|
LARGE_INTEGER BaseAddress;
|
|
UCHAR Map;
|
|
LIST_ENTRY ListEntry;
|
|
} IO_PORT_INFO, *PIO_PORT_INFO;
|
|
|
|
|
|
//
|
|
// Parameter fields passed to the CONFIGURE command.
|
|
//
|
|
|
|
#define COMMND_CONFIGURE_IMPLIED_SEEKS 0x40
|
|
#define COMMND_CONFIGURE_FIFO_THRESHOLD 0x0F
|
|
#define COMMND_CONFIGURE_DISABLE_FIFO 0x20
|
|
#define COMMND_CONFIGURE_DISABLE_POLLING 0x10
|
|
|
|
//
|
|
// Write Enable bit for PERPENDICULAR MODE command.
|
|
//
|
|
|
|
#define COMMND_PERPENDICULAR_MODE_OW 0x80
|
|
|
|
//
|
|
// The command table is used by FlIssueCommand() to determine how many
|
|
// bytes to get and receive, and whether or not to wait for an interrupt.
|
|
// Some commands have extra bits; COMMAND_MASK takes these off.
|
|
// FirstResultByte indicates whether the command has a result stage
|
|
// or not; if so, it's 1 because the ISR read the 1st byte, and
|
|
// NumberOfResultBytes is 1 less than expected. If not, it's 0 and
|
|
// NumberOfResultBytes is 2, since the ISR will have issued a SENSE
|
|
// INTERRUPT STATUS command.
|
|
//
|
|
|
|
#define COMMAND_MASK 0x1f
|
|
#define FDC_NO_DATA 0x00
|
|
#define FDC_READ_DATA 0x01
|
|
#define FDC_WRITE_DATA 0x02
|
|
|
|
typedef struct _COMMAND_TABLE {
|
|
UCHAR OpCode;
|
|
UCHAR NumberOfParameters;
|
|
UCHAR FirstResultByte;
|
|
UCHAR NumberOfResultBytes;
|
|
BOOLEAN InterruptExpected;
|
|
BOOLEAN AlwaysImplemented;
|
|
UCHAR DataTransfer;
|
|
} COMMAND_TABLE;
|
|
|
|
//
|
|
// Bits in the DRIVE_CONTROL register.
|
|
//
|
|
|
|
#define DRVCTL_RESET 0x00
|
|
#define DRVCTL_ENABLE_CONTROLLER (IsNEC_98 ? 0x80 : 0x04)
|
|
#define DRVCTL_ENABLE_DMA_AND_INTERRUPTS (IsNEC_98 ? 0x10 : 0x08)
|
|
#define DRVCTL_DRIVE_0 0x10
|
|
#define DRVCTL_DRIVE_1 0x21
|
|
#define DRVCTL_DRIVE_2 0x42
|
|
#define DRVCTL_DRIVE_3 0x83
|
|
#define DRVCTL_DRIVE_MASK 0x03
|
|
#define DRVCTL_MOTOR_MASK (IsNEC_98 ? 0x08 : 0xf0)
|
|
#define DRVCTL_HD_BIT 0x20 // for NEC98
|
|
#define DRVCTL_AI_ENABLE 0x20 // for NEC98. Indicate AI enable bit.
|
|
|
|
//
|
|
// Bits in the STATUS register.
|
|
//
|
|
|
|
#define STATUS_DRIVE_0_BUSY 0x01
|
|
#define STATUS_DRIVE_1_BUSY 0x02
|
|
#define STATUS_DRIVE_2_BUSY 0x04
|
|
#define STATUS_DRIVE_3_BUSY 0x08
|
|
#define STATUS_CONTROLLER_BUSY 0x10
|
|
#define STATUS_DMA_UNUSED 0x20
|
|
#define STATUS_DIRECTION_READ 0x40
|
|
#define STATUS_DATA_REQUEST 0x80
|
|
|
|
#define STATUS_IO_READY_MASK 0xc0
|
|
#define STATUS_READ_READY 0xc0
|
|
#define STATUS_WRITE_READY 0x80
|
|
#define STATUS_IO_READY_MASK1 0x80 // for NEC98.
|
|
#define STATUS_RQM_READY 0x80 // for NEC98.
|
|
|
|
//
|
|
// Bits in the DATA_RATE register.
|
|
//
|
|
|
|
#define DATART_0125 0x03
|
|
#define DATART_0250 0x02
|
|
#define DATART_0300 0x01
|
|
#define DATART_0500 0x00
|
|
#define DATART_1000 0x03
|
|
#define DATART_RESERVED 0xfc
|
|
|
|
//
|
|
// Bits in the DISK_CHANGE register.
|
|
//
|
|
|
|
#define DSKCHG_RESERVED 0x7f
|
|
#define DSKCHG_DISKETTE_REMOVED 0x80
|
|
|
|
//
|
|
// Bits in status register 0.
|
|
//
|
|
|
|
#define STREG0_DRIVE_0 0x00
|
|
#define STREG0_DRIVE_1 0x01
|
|
#define STREG0_DRIVE_2 0x02
|
|
#define STREG0_DRIVE_3 0x03
|
|
#define STREG0_HEAD 0x04
|
|
#define STREG0_DRIVE_NOT_READY 0x08
|
|
#define STREG0_DRIVE_FAULT 0x10
|
|
#define STREG0_SEEK_COMPLETE 0x20
|
|
#define STREG0_END_NORMAL 0x00
|
|
#define STREG0_END_ERROR 0x40
|
|
#define STREG0_END_INVALID_COMMAND 0x80
|
|
#define STREG0_END_DRIVE_NOT_READY 0xC0
|
|
#define STREG0_END_MASK 0xC0
|
|
|
|
//
|
|
// Bits in status register 1.
|
|
//
|
|
|
|
#define STREG1_ID_NOT_FOUND 0x01
|
|
#define STREG1_WRITE_PROTECTED 0x02
|
|
#define STREG1_SECTOR_NOT_FOUND 0x04
|
|
#define STREG1_RESERVED1 0x08
|
|
#define STREG1_DATA_OVERRUN 0x10
|
|
#define STREG1_CRC_ERROR 0x20
|
|
#define STREG1_RESERVED2 0x40
|
|
#define STREG1_END_OF_DISKETTE 0x80
|
|
|
|
//
|
|
// Bits in status register 2.
|
|
//
|
|
|
|
#define STREG2_SUCCESS 0x00
|
|
#define STREG2_DATA_NOT_FOUND 0x01
|
|
#define STREG2_BAD_CYLINDER 0x02
|
|
#define STREG2_SCAN_FAIL 0x04
|
|
#define STREG2_SCAN_EQUAL 0x08
|
|
#define STREG2_WRONG_CYLINDER 0x10
|
|
#define STREG2_CRC_ERROR 0x20
|
|
#define STREG2_DELETED_DATA 0x40
|
|
#define STREG2_RESERVED 0x80
|
|
|
|
//
|
|
// Bits in status register 3.
|
|
//
|
|
|
|
#define STREG3_DRIVE_0 0x00
|
|
#define STREG3_DRIVE_1 0x01
|
|
#define STREG3_DRIVE_2 0x02
|
|
#define STREG3_DRIVE_3 0x03
|
|
#define STREG3_HEAD 0x04
|
|
#define STREG3_TWO_SIDED 0x08
|
|
#define STREG3_TRACK_0 0x10
|
|
#define STREG3_DRIVE_READY 0x20
|
|
#define STREG3_WRITE_PROTECTED 0x40
|
|
#define STREG3_DRIVE_FAULT 0x80
|
|
|
|
#define VALID_NEC_FDC 0x90 // version number
|
|
#define NSC_PRIMARY_VERSION 0x70 // National 8477 verion number
|
|
#define NSC_MASK 0xF0 // mask for National version number
|
|
#define INTEL_MASK 0xe0
|
|
#define INTEL_44_PIN_VERSION 0x40
|
|
#define INTEL_64_PIN_VERSION 0x00
|
|
|
|
#define DMA_DIR_UNKNOWN 0xff /* The DMA direction is not currently known */
|
|
#define DMA_WRITE 0 /* Program the DMA to write (FDC->DMA->RAM) */
|
|
#define DMA_READ 1 /* Program the DMA to read (RAM->DMA->FDC) */
|
|
|
|
//
|
|
// Strings for PnP Identification.
|
|
//
|
|
#define FDC_FLOPPY_COMPATIBLE_IDS L"*PNP0700\0GenFloppyDisk\0\0"
|
|
#define FDC_FLOPPY_COMPATIBLE_IDS_LENGTH 24 // NB wide characters.
|
|
|
|
#define FDC_TAPE_COMPATIBLE_IDS L"QICPNP\0\0"
|
|
#define FDC_TAPE_COMPATIBLE_IDS_LENGTH 8 // NB wide characters.
|
|
|
|
#define FDC_CONTROLLER_COMPATIBLE_IDS L"*PNP0700\0\0"
|
|
#define FDC_CONTROLLER_COMPATIBLE_IDS_LENGTH 10 // NB wide characters.
|
|
|
|
|
|
|
|
//
|
|
// Runtime device structures
|
|
//
|
|
|
|
//
|
|
// There is one FDC_EXTENSION attached to the device object of each
|
|
// floppy drive. Only data directly related to that drive (and the media
|
|
// in it) is stored here; common data is in CONTROLLER_DATA. So the
|
|
// FDC_EXTENSION has a pointer to the CONTROLLER_DATA.
|
|
//
|
|
|
|
typedef struct _FDC_EXTENSION_HEADER {
|
|
|
|
//
|
|
// A flag to indicate whether this is a FDO or a PDO
|
|
//
|
|
BOOLEAN IsFDO;
|
|
|
|
//
|
|
// A pointer to our own device object.
|
|
//
|
|
PDEVICE_OBJECT Self;
|
|
|
|
} FDC_EXTENSION_HEADER, *PFDC_EXTENSION_HEADER;
|
|
|
|
typedef enum _FDC_DEVICE_TYPE {
|
|
|
|
FloppyControllerDevice,
|
|
FloppyDiskDevice,
|
|
FloppyTapeDevice
|
|
|
|
} FDC_DEVICE_TYPE;
|
|
|
|
typedef struct _FDC_PDO_EXTENSION {
|
|
|
|
FDC_EXTENSION_HEADER;
|
|
|
|
//
|
|
// A pointer to the FDO that created us.
|
|
//
|
|
PDEVICE_OBJECT ParentFdo;
|
|
|
|
//
|
|
// The instance number for this PDO. Determined by the order of the
|
|
// callbacks from IoQueryDeviceDescription.
|
|
//
|
|
USHORT Instance;
|
|
|
|
//
|
|
// The type of device this PDO supports. Currently disk or tape.
|
|
//
|
|
FDC_DEVICE_TYPE DeviceType;
|
|
|
|
SHORT TapeVendorId;
|
|
|
|
//
|
|
// A flag that indicates whether this PDO is pending removal.
|
|
//
|
|
BOOLEAN Removed;
|
|
|
|
//
|
|
// This PDO's entry in its parent's list of related PDOs.
|
|
//
|
|
LIST_ENTRY PdoLink;
|
|
|
|
//
|
|
// The enumerated number of this specific device, as returned from
|
|
// IoQueryDeviceDescription.
|
|
//
|
|
ULONG PeripheralNumber;
|
|
|
|
PDEVICE_OBJECT TargetObject;
|
|
|
|
} FDC_PDO_EXTENSION, *PFDC_PDO_EXTENSION;
|
|
|
|
typedef struct _FDC_FDO_EXTENSION {
|
|
|
|
FDC_EXTENSION_HEADER;
|
|
|
|
//
|
|
// A kernel resource for controlling access to the FDC.
|
|
//
|
|
ERESOURCE Resource;
|
|
//
|
|
// A pointer to the PDO to which this FDO is attached.
|
|
//
|
|
PDEVICE_OBJECT UnderlyingPDO;
|
|
|
|
//
|
|
// The top of the object stack to which this FDO is attached.
|
|
//
|
|
PDEVICE_OBJECT TargetObject;
|
|
|
|
//
|
|
// A list and count of PDOs that were created by this FDO.
|
|
//
|
|
LIST_ENTRY PDOs;
|
|
ULONG NumPDOs;
|
|
BOOLEAN Removed;
|
|
ULONG OutstandingRequests;
|
|
KEVENT RemoveEvent;
|
|
BOOLEAN TapeEnumerationPending;
|
|
KEVENT TapeEnumerationEvent;
|
|
|
|
//
|
|
// Some stuff for power management
|
|
//
|
|
LIST_ENTRY PowerQueue;
|
|
KSPIN_LOCK PowerQueueSpinLock;
|
|
KEVENT PowerEvent;
|
|
SYSTEM_POWER_STATE CurrentPowerState;
|
|
LARGE_INTEGER LastMotorSettleTime;
|
|
BOOLEAN WakeUp;
|
|
|
|
//
|
|
// The bus number on which this physical device lives.
|
|
//
|
|
INTERFACE_TYPE BusType;
|
|
ULONG BusNumber;
|
|
ULONG ControllerNumber;
|
|
|
|
BOOLEAN DeviceObjectInitialized;
|
|
LARGE_INTEGER InterruptDelay;
|
|
LARGE_INTEGER Minimum10msDelay;
|
|
KEVENT InterruptEvent;
|
|
LONG InterruptTimer;
|
|
CCHAR ResettingController;
|
|
KEVENT AllocateAdapterChannelEvent;
|
|
LONG AdapterChannelRefCount;
|
|
PKEVENT AcquireEvent;
|
|
HANDLE AcquireEventHandle;
|
|
KEVENT SynchEvent;
|
|
KDPC LogErrorDpc;
|
|
KDPC BufferTimerDpc;
|
|
KTIMER BufferTimer;
|
|
PKINTERRUPT InterruptObject;
|
|
PVOID MapRegisterBase;
|
|
PADAPTER_OBJECT AdapterObject;
|
|
PDEVICE_OBJECT CurrentDeviceObject;
|
|
PDRIVER_OBJECT DriverObject;
|
|
CONTROLLER ControllerAddress;
|
|
ULONG SpanOfControllerAddress;
|
|
ULONG NumberOfMapRegisters;
|
|
ULONG BuffersRequested;
|
|
ULONG BufferCount;
|
|
ULONG BufferSize;
|
|
PTRANSFER_BUFFER TransferBuffers;
|
|
ULONG IsrReentered;
|
|
ULONG ControllerVector;
|
|
KIRQL ControllerIrql;
|
|
KINTERRUPT_MODE InterruptMode;
|
|
KAFFINITY ProcessorMask;
|
|
UCHAR FifoBuffer[10];
|
|
BOOLEAN AllowInterruptProcessing;
|
|
BOOLEAN SharableVector;
|
|
BOOLEAN SaveFloatState;
|
|
BOOLEAN HardwareFailed;
|
|
BOOLEAN CommandHasResultPhase;
|
|
BOOLEAN ControllerConfigurable;
|
|
BOOLEAN MappedControllerAddress;
|
|
BOOLEAN CurrentInterrupt;
|
|
BOOLEAN Model30;
|
|
UCHAR PerpendicularDrives;
|
|
UCHAR NumberOfDrives;
|
|
UCHAR DriveControlImage;
|
|
UCHAR HardwareFailCount;
|
|
BOOLEAN ControllerInUse;
|
|
UCHAR FdcType;
|
|
UCHAR FdcSpeeds;
|
|
PIRP CurrentIrp;
|
|
UCHAR DriveOnValue;
|
|
PDEVICE_OBJECT LastDeviceObject;
|
|
BOOLEAN Clock48MHz;
|
|
BOOLEAN FdcEnablerSupported;
|
|
PDEVICE_OBJECT FdcEnablerDeviceObject;
|
|
PFILE_OBJECT FdcEnablerFileObject;
|
|
BOOLEAN ResetFlag; // for NEC98
|
|
BOOLEAN FloppyEquip; // for NEC98
|
|
UCHAR MotorRunning; // for NEC98
|
|
UCHAR ResultStatus0[4]; // for NEC98
|
|
|
|
#ifdef TOSHIBAJ
|
|
// For 3mode support
|
|
BOOLEAN Available3Mode;
|
|
// Feb.9.1998 KIADP010 Assign Toshiba special registers.
|
|
PUCHAR ConfigBase;
|
|
#endif
|
|
|
|
} FDC_FDO_EXTENSION, *PFDC_FDO_EXTENSION;
|
|
|
|
|
|
#ifdef TOSHIBAJ
|
|
// Feb.9.1998 KIADP011 Get base address and identifier
|
|
// Feb.9.1998 KIADP012 Identify controller
|
|
// Feb.9.1998 KIADP013 Change Speed
|
|
|
|
// Definitions for SMC 37C67X/777
|
|
|
|
// Ports
|
|
#define SMC_INDEX_PORT(port) (port)
|
|
#define SMC_DATA_PORT(port) (port)+1
|
|
|
|
// Key
|
|
#define SMC_KEY_ENTER_CONFIG 0x55
|
|
#define SMC_KEY_EXIT_CONFIG 0xaa
|
|
|
|
#define SMC_CONFIG_PORT_LENGTH 2
|
|
|
|
// Index
|
|
#define SMC_INDEX_DEVICE 0x07
|
|
#define SMC_INDEX_IDENTIFY 0x20
|
|
#define SMC_INDEX_CONF_ADDR_0 0x26
|
|
#define SMC_INDEX_CONF_ADDR_1 0x27
|
|
#define SMC_INDEX_FDC_OPT 0xf1
|
|
|
|
// Device
|
|
#define SMC_DEVICE_FDC 0x00
|
|
|
|
// Mask
|
|
#define SMC_MASK_DENSEL 0x0c
|
|
|
|
// Dencity select
|
|
#define SMC_DELSEL_HIGH 0x08 // 300rpm
|
|
#define SMC_DENSEL_LOW 0x0c // 360rpm
|
|
|
|
#endif
|
|
|
|
//
|
|
// NEC98: Registory path of MultifunctionAdapter.
|
|
//
|
|
#define ISA_BUS_NODE \
|
|
"\\Registry\\MACHINE\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter\\%d"
|
|
|
|
//
|
|
// Macro
|
|
//
|
|
|
|
//
|
|
// Enable/Disable Controller
|
|
//
|
|
|
|
#define DISABLE_CONTROLLER_IMAGE(FdoExtension) \
|
|
{ \
|
|
if (IsNEC_98) { \
|
|
FdoExtension->DriveControlImage |= DRVCTL_ENABLE_DMA_AND_INTERRUPTS; \
|
|
FdoExtension->DriveControlImage |= DRVCTL_ENABLE_CONTROLLER; \
|
|
FdoExtension->ResetFlag = FALSE; \
|
|
} else { \
|
|
FdoExtension->DriveControlImage |= DRVCTL_ENABLE_DMA_AND_INTERRUPTS; \
|
|
FdoExtension->DriveControlImage &= ~( DRVCTL_ENABLE_CONTROLLER ); \
|
|
} \
|
|
}
|
|
|
|
#define ENABLE_CONTROLLER_IMAGE(FdoExtension) \
|
|
{ \
|
|
if (IsNEC_98) { \
|
|
FdoExtension->DriveControlImage &= ~( DRVCTL_ENABLE_CONTROLLER ); \
|
|
FdoExtension->DriveControlImage |= DRVCTL_AI_ENABLE; \
|
|
} else { \
|
|
FdoExtension->DriveControlImage |= DRVCTL_ENABLE_CONTROLLER; \
|
|
} \
|
|
}
|
|
|
|
//
|
|
// Dma speed
|
|
//
|
|
#define DEFAULT_DMA_SPEED (IsNEC_98 ? Compatible : TypeA)
|
|
|
|
//
|
|
// Paging Driver with Mutex
|
|
//
|
|
#define FDC_PAGE_INITIALIZE_DRIVER_WITH_MUTEX \
|
|
{ \
|
|
if (!IsNEC_98) { \
|
|
PagingMutex = ExAllocatePool(NonPagedPool, sizeof(FAST_MUTEX)); \
|
|
if (!PagingMutex) { \
|
|
return STATUS_INSUFFICIENT_RESOURCES; \
|
|
} \
|
|
ExInitializeFastMutex(PagingMutex); \
|
|
MmPageEntireDriver(DriverEntry); \
|
|
} \
|
|
}
|
|
|
|
#define FDC_PAGE_RESET_DRIVER_WITH_MUTEX \
|
|
{ \
|
|
if (!IsNEC_98) { \
|
|
ExAcquireFastMutex( PagingMutex ); \
|
|
if ( ++PagingReferenceCount == 1 ) { \
|
|
MmResetDriverPaging( DriverEntry ); \
|
|
} \
|
|
ExReleaseFastMutex( PagingMutex ); \
|
|
} \
|
|
}
|
|
|
|
#define FDC_PAGE_ENTIRE_DRIVER_WITH_MUTEX \
|
|
{ \
|
|
if (!IsNEC_98) { \
|
|
ExAcquireFastMutex(PagingMutex); \
|
|
if (--PagingReferenceCount == 0) { \
|
|
MmPageEntireDriver(DriverEntry); \
|
|
} \
|
|
ExReleaseFastMutex(PagingMutex); \
|
|
} \
|
|
}
|
|
|
|
|
|
//
|
|
// Prototypes of external routines.
|
|
//
|
|
|
|
/*
|
|
LONG
|
|
sprintf(
|
|
CHAR *,
|
|
const CHAR *,
|
|
...
|
|
);
|
|
*/
|
|
|
|
//
|
|
// Prototypes of driver routines.
|
|
//
|
|
|
|
NTSTATUS
|
|
DriverEntry(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPath
|
|
);
|
|
|
|
NTSTATUS
|
|
FcAllocateCommonBuffers(
|
|
IN PFDC_FDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
FcInitializeControllerHardware(
|
|
IN PFDC_FDO_EXTENSION FdoExtension,
|
|
IN PDEVICE_OBJECT DeviceObject
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcCreateClose(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcInternalDeviceControl(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcPnp(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcPower(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcAddDevice(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN OUT PDEVICE_OBJECT PhysicalDeviceObject
|
|
);
|
|
|
|
BOOLEAN
|
|
FdcInterruptService(
|
|
IN PKINTERRUPT Interrupt,
|
|
IN PVOID Context
|
|
);
|
|
|
|
VOID
|
|
FdcDeferredProcedure(
|
|
IN PKDPC Dpc,
|
|
IN PVOID DeferredContext,
|
|
IN PVOID SystemArgument1,
|
|
IN PVOID SystemArgument2
|
|
);
|
|
|
|
NTSTATUS
|
|
FcAcquireFdc(
|
|
IN OUT PFDC_FDO_EXTENSION FdoExtension,
|
|
IN PLARGE_INTEGER TimeOut
|
|
);
|
|
|
|
NTSTATUS
|
|
FcReleaseFdc(
|
|
IN OUT PFDC_FDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
VOID
|
|
FcReportFdcInformation(
|
|
IN PFDC_PDO_EXTENSION PdoExtension,
|
|
IN PFDC_FDO_EXTENSION FdcExtension,
|
|
IN OUT PIO_STACK_LOCATION IrpSp
|
|
);
|
|
|
|
NTSTATUS
|
|
FcTurnOnMotor(
|
|
IN PFDC_FDO_EXTENSION FdcExtension,
|
|
IN OUT PIO_STACK_LOCATION irpSp
|
|
);
|
|
|
|
NTSTATUS
|
|
FcTurnOffMotor(
|
|
IN PFDC_FDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
VOID
|
|
FcAllocateAdapterChannel(
|
|
IN OUT PFDC_FDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
VOID
|
|
FcFreeAdapterChannel(
|
|
IN OUT PFDC_FDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
IO_ALLOCATION_ACTION
|
|
FdcAllocateAdapterChannel(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp,
|
|
IN PVOID MapRegisterBase,
|
|
IN PVOID Context
|
|
);
|
|
|
|
NTSTATUS
|
|
FcSendByte(
|
|
IN UCHAR ByteToSend,
|
|
IN PFDC_FDO_EXTENSION FdoExtension,
|
|
IN BOOLEAN AllowLongDelay
|
|
);
|
|
|
|
NTSTATUS
|
|
FcGetByte(
|
|
OUT PUCHAR ByteToGet,
|
|
IN OUT PFDC_FDO_EXTENSION FdoExtension,
|
|
IN BOOLEAN AllowLongDelay
|
|
);
|
|
|
|
NTSTATUS
|
|
FcIssueCommand(
|
|
IN OUT PFDC_FDO_EXTENSION FdoExtension,
|
|
IN PUCHAR FifoInBuffer,
|
|
OUT PUCHAR FifoOutBuffer,
|
|
IN PVOID IoHandle,
|
|
IN ULONG IoOffset,
|
|
IN ULONG TransferBytes
|
|
);
|
|
|
|
VOID
|
|
FcLogErrorDpc(
|
|
IN PKDPC Dpc,
|
|
IN PVOID DeferredContext,
|
|
IN PVOID SystemContext1,
|
|
IN PVOID SystemContext2
|
|
);
|
|
|
|
BOOLEAN
|
|
FcClearIsrReentered(
|
|
IN PVOID Context
|
|
);
|
|
|
|
NTSTATUS
|
|
FcGetFdcInformation(
|
|
IN OUT PFDC_FDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
VOID
|
|
FdcCheckTimer(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN OUT PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
FdcTimerSync(
|
|
IN OUT PVOID Context
|
|
);
|
|
|
|
VOID
|
|
FdcStartIo(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
FcStartCommand(
|
|
IN OUT PFDC_FDO_EXTENSION FdoExtension,
|
|
IN PUCHAR FifoInBuffer,
|
|
OUT PUCHAR FifoOutBuffer,
|
|
IN PVOID IoHandle,
|
|
IN ULONG IoOffset,
|
|
IN ULONG TransferBytes,
|
|
IN BOOLEAN AllowLongDelay
|
|
);
|
|
|
|
NTSTATUS
|
|
FcFinishCommand(
|
|
IN OUT PFDC_FDO_EXTENSION FdoExtension,
|
|
IN PUCHAR FifoInBuffer,
|
|
OUT PUCHAR FifoOutBuffer,
|
|
IN PVOID IoHandle,
|
|
IN ULONG IoOffset,
|
|
IN ULONG TransferBytes,
|
|
IN BOOLEAN AllowLongDelay
|
|
);
|
|
|
|
NTSTATUS
|
|
FcFinishReset(
|
|
IN OUT PFDC_FDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
VOID
|
|
FdcBufferThread(
|
|
IN PVOID Context
|
|
);
|
|
|
|
NTSTATUS
|
|
FcFdcEnabler(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN ULONG Ioctl,
|
|
IN OUT PVOID Data
|
|
);
|
|
|
|
NTSTATUS
|
|
FcSynchronizeQueue(
|
|
IN OUT PFDC_FDO_EXTENSION FdoExtension,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcPnpComplete(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp,
|
|
PVOID Context
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcStartDevice(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcInitializeDeviceObject(
|
|
IN PDEVICE_OBJECT DeviceObject
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcFdoPnp(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcPdoPnp(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcFilterResourceRequirements(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcQueryDeviceRelations(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcConfigCallBack(
|
|
IN PVOID Context,
|
|
IN PUNICODE_STRING PathName,
|
|
IN INTERFACE_TYPE BusType,
|
|
IN ULONG BusNumber,
|
|
IN PKEY_VALUE_FULL_INFORMATION *BusInformation,
|
|
IN CONFIGURATION_TYPE ControllerType,
|
|
IN ULONG ControllerNumber,
|
|
IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
|
|
IN CONFIGURATION_TYPE PeripheralType,
|
|
IN ULONG PeripheralNumber,
|
|
IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcFdoConfigCallBack(
|
|
IN PVOID Context,
|
|
IN PUNICODE_STRING PathName,
|
|
IN INTERFACE_TYPE BusType,
|
|
IN ULONG BusNumber,
|
|
IN PKEY_VALUE_FULL_INFORMATION *BusInformation,
|
|
IN CONFIGURATION_TYPE ControllerType,
|
|
IN ULONG ControllerNumber,
|
|
IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
|
|
IN CONFIGURATION_TYPE PeripheralType,
|
|
IN ULONG PeripheralNumber,
|
|
IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcEnumerateQ117(
|
|
IN PFDC_FDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
VOID
|
|
FdcGetEnablerDevice(
|
|
IN OUT PFDC_FDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcPdoInternalDeviceControl(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
FdcFdoInternalDeviceControl(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
PVOID
|
|
FdcGetControllerBase(
|
|
IN INTERFACE_TYPE BusType,
|
|
IN ULONG BusNumber,
|
|
PHYSICAL_ADDRESS IoAddress,
|
|
ULONG NumberOfBytes,
|
|
BOOLEAN InIoSpace
|
|
);
|
|
|
|
//
|
|
// For NEC98
|
|
//
|
|
|
|
NTSTATUS
|
|
FdcHdbit(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PFDC_FDO_EXTENSION FdoExtension,
|
|
IN PSET_HD_BIT_PARMS SetHdBitParams
|
|
);
|
|
|
|
ULONG
|
|
FdcGet0Seg(
|
|
IN PUCHAR ConfigrationData1,
|
|
IN ULONG Offset
|
|
);
|
|
|
|
ULONG
|
|
FdcFindIsaBusNode(
|
|
IN OUT VOID
|
|
);
|
|
|
|
UCHAR
|
|
FdcRqmReadyWait(
|
|
IN PFDC_FDO_EXTENSION FdoExtension,
|
|
IN ULONG IssueSenseInterrupt
|
|
);
|
|
|
|
|
|
#ifdef TOSHIBAJ
|
|
|
|
NTSTATUS FcFdcEnable3Mode(
|
|
IN PFDC_FDO_EXTENSION FdoExtension,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS FcFdcAvailable3Mode(
|
|
IN PFDC_FDO_EXTENSION FdoExtension,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
BOOLEAN
|
|
FcCheckConfigPort(
|
|
IN PUCHAR ConfigPort
|
|
);
|
|
|
|
#endif
|