1068 lines
28 KiB
C
1068 lines
28 KiB
C
/*++
|
||
|
||
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
|
||
FdcBusConfigCallBack(
|
||
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
|