Annotation of ntddk/src/scsi/floppy/flo_data.h, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1991 - 1993 Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     flo_data.h
                      8: 
                      9: Abstract:
                     10: 
                     11:     This file includes data and hardware declarations for the NEC PD765
                     12:     (aka AT, ISA, and ix86) and Intel 82077 (aka MIPS) floppy driver for
                     13:     NT.
                     14: 
                     15: Author:
                     16: 
                     17: 
                     18: Environment:
                     19: 
                     20:     Kernel mode only.
                     21: 
                     22: Notes:
                     23: 
                     24: 
                     25: --*/
                     26: 
                     27: 
                     28: #if DBG
                     29: //
                     30: // For checked kernels, define a macro to print out informational
                     31: // messages.
                     32: //
                     33: // FloppyDebug is normally 0.  At compile-time or at run-time, it can be
                     34: // set to some bit patter for increasingly detailed messages.
                     35: //
                     36: // Big, nasty errors are noted with DBGP.  Errors that might be
                     37: // recoverable are handled by the WARN bit.  More information on
                     38: // unusual but possibly normal happenings are handled by the INFO bit.
                     39: // And finally, boring details such as routines entered and register
                     40: // dumps are handled by the SHOW bit.
                     41: //
                     42: #define FLOPDBGP              ((ULONG)0x00000001)
                     43: #define FLOPWARN              ((ULONG)0x00000002)
                     44: #define FLOPINFO              ((ULONG)0x00000004)
                     45: #define FLOPSHOW              ((ULONG)0x00000008)
                     46: #define FLOPIRPPATH           ((ULONG)0x00000010)
                     47: #define FLOPFORMAT            ((ULONG)0x00000020)
                     48: extern ULONG FloppyDebugLevel;
                     49: #define FloppyDump(LEVEL,STRING) \
                     50:         do { \
                     51:             if (FloppyDebugLevel & LEVEL) { \
                     52:                 DbgPrint STRING; \
                     53:             } \
                     54:         } while (0)
                     55: #else
                     56: #define FloppyDump(LEVEL,STRING) do {NOTHING;} while (0)
                     57: #endif
                     58: 
                     59: 
                     60: //
                     61: // For device name manipulation, we allocate a buffer since there is no
                     62: // preset limit on name size.  The system hands us a prefix, and we
                     63: // allocate the buffer to be the size of that prefix plus the delta defined
                     64: // below.  This size gives us room for
                     65: //     PREFIX + <disk number>
                     66: // with up to five digits for the disk number.
                     67: //
                     68: 
                     69: #define DEVICE_NAME_DELTA            5
                     70: 
                     71: //
                     72: // Partitions need to be linked to ARC names, in case we're booting off
                     73: // the partition.  The system hands us a prefix, and we allocate the
                     74: // buffer to be the size of that prefix plus the delta defined below.
                     75: // This size gives us room for
                     76: //      PREFIX + disk(<#>)fdisk(<#>)
                     77: // with up to five digits per number.
                     78: //
                     79: 
                     80: #define ARC_NAME_DELTA               23
                     81: 
                     82: //
                     83: // Macros to access the controller.  Note that the *_PORT_UCHAR macros
                     84: // work on all machines, whether the I/O ports are separate or in
                     85: // memory space.
                     86: //
                     87: 
                     88: #define READ_CONTROLLER( Address )                         \
                     89:     READ_PORT_UCHAR( ( PUCHAR )Address )
                     90: 
                     91: #define WRITE_CONTROLLER( Address, Value )                 \
                     92:     WRITE_PORT_UCHAR( ( PUCHAR )Address, ( UCHAR )Value )
                     93: 
                     94: 
                     95: //
                     96: // If we don't get enough map registers to handle the maximum track size,
                     97: // we will allocate a contiguous buffer and do I/O to/from that.
                     98: //
                     99: // On MIPS, we should always have enough map registers.  On the ix86 we
                    100: // might not, and when we allocate the contiguous buffer we have to make
                    101: // sure that it's in the first 16Mb of RAM to make sure the DMA chip can
                    102: // address it.
                    103: //
                    104: 
                    105: #define MAXIMUM_DMA_ADDRESS                0xFFFFFF
                    106: 
                    107: //
                    108: // The byte in the boot sector that specifies the type of media, and
                    109: // the values that it can assume.  We can often tell what type of media
                    110: // is in the drive by seeing which controller parameters allow us to read
                    111: // the diskette, but some different densities are readable with the same
                    112: // parameters so we use this byte to decide the media type.
                    113: //
                    114: 
                    115: #define MEDIA_DESCRIPTOR_OFFSET            0x15
                    116: #define MEDIA_DESCRIPTOR_SECTORS_PER_TRACK 0x18
                    117: #define MEDIA_DESCRIPTOR_NUM_OF_HEADS     0x1A
                    118: 
                    119: #define MEDIA_DESCRIPTOR_160K              0xFE
                    120: #define MEDIA_DESCRIPTOR_180K              0xFC
                    121: #define MEDIA_DESCRIPTOR_320K              0xFF
                    122: #define MEDIA_DESCRIPTOR_360K              0xFD
                    123: #define MEDIA_DESCRIPTOR_720K_OR_1220K     0xF9
                    124: #define MEDIA_DESCRIPTOR_1440K_OR_2880K    0xF0
                    125: 
                    126: //
                    127: // Retry counts -
                    128: //
                    129: // When moving a byte to/from the FIFO, we sit in a tight loop for a while
                    130: // waiting for the controller to become ready.  The number of times through
                    131: // the loop is controlled by FIFO_TIGHTLOOP_RETRY_COUNT.  When that count
                    132: // expires, we'll wait in 10ms increments.  FIFO_DELAY_RETRY_COUNT controls
                    133: // how many times we wait.
                    134: //
                    135: // The ISR_SENSE_RETRY_COUNT is the maximum number of 1 microsecond
                    136: // stalls that the ISR will do waiting for the controller to accept
                    137: // a SENSE INTERRUPT command.  We do this because there is a hardware
                    138: // quirk in at least the NCR 8 processor machine where it can take
                    139: // up to 50 microseconds to accept the command.
                    140: //
                    141: // When attempting I/O, we may run into many different errors.  The
                    142: // hardware retries things 8 times invisibly.  If the hardware reports
                    143: // any type of error, we will recalibrate and retry the operation
                    144: // up to RECALIBRATE_RETRY_COUNT times.  When this expires, we check to
                    145: // see if there's an overrun - if so, the DMA is probably being hogged
                    146: // by a higher priority device, so we repeat the earlier loop up to
                    147: // OVERRUN_RETRY_COUNT times.
                    148: //
                    149: // Any packet that is about to be returned with an error caused by an
                    150: // unexpected hardware error or state will be restarted from the very
                    151: // beginning after resetting the hardware HARDWARE_RESET_RETRY_COUNT
                    152: // times.
                    153: //
                    154: 
                    155: #define FIFO_TIGHTLOOP_RETRY_COUNT         500
                    156: #define FIFO_ISR_TIGHTLOOP_RETRY_COUNT     25
                    157: #define ISR_SENSE_RETRY_COUNT              50
                    158: #define FIFO_DELAY_RETRY_COUNT             5
                    159: #define RECALIBRATE_RETRY_COUNT            3
                    160: #define OVERRUN_RETRY_COUNT                3
                    161: #define HARDWARE_RESET_RETRY_COUNT         2
                    162: #define FLOPPY_RESET_ISR_THRESHOLD         20
                    163: 
                    164: //
                    165: // The I/O system calls our timer routine once every second.  If the timer
                    166: // counter is -1, the timer is "off" and the timer routine will just return.
                    167: // By setting the counter to 3, the timer routine will decrement the
                    168: // counter every second, so the timer will expire in 2 to 3 seconds.  At
                    169: // that time the drive motor will be turned off.
                    170: //
                    171: 
                    172: #define TIMER_CANCEL                       -1
                    173: #define TIMER_EXPIRED                      0
                    174: #define TIMER_START                        3
                    175: 
                    176: 
                    177: //
                    178: // Define drive types.  Numbers are read from CMOS, translated to these
                    179: // numbers, and then used as an index into the DRIVE_MEDIA_LIMITS table.
                    180: //
                    181: 
                    182: #define DRIVE_TYPE_0360                    0
                    183: #define DRIVE_TYPE_1200                    1
                    184: #define DRIVE_TYPE_0720                    2
                    185: #define DRIVE_TYPE_1440                    3
                    186: #define DRIVE_TYPE_2880                    4
                    187: 
                    188: #define NUMBER_OF_DRIVE_TYPES              5
                    189: #define DRIVE_TYPE_NONE                    NUMBER_OF_DRIVE_TYPES
                    190: #define DRIVE_TYPE_INVALID                 DRIVE_TYPE_NONE + 1
                    191: 
                    192: //
                    193: // Media types are defined in ntdddisk.h, but we'll add one type here.
                    194: // This keeps us from wasting time trying to determine the media type
                    195: // over and over when, for example, a fresh floppy is about to be
                    196: // formatted.
                    197: //
                    198: 
                    199: #define Undetermined                       -1
                    200: 
                    201: //
                    202: // Define all possible drive/media combinations, given drives listed above
                    203: // and media types in ntdddisk.h.
                    204: //
                    205: // These values are used to index the DriveMediaConstants table.
                    206: //
                    207: 
                    208: #define NUMBER_OF_DRIVE_MEDIA_COMBINATIONS 17
                    209: 
                    210: typedef enum _DRIVE_MEDIA_TYPE {
                    211:     Drive360Media160,                      // 5.25"  360k  drive;  160k   media
                    212:     Drive360Media180,                      // 5.25"  360k  drive;  180k   media
                    213:     Drive360Media320,                      // 5.25"  360k  drive;  320k   media
                    214:     Drive360Media32X,                      // 5.25"  360k  drive;  320k 1k secs
                    215:     Drive360Media360,                      // 5.25"  360k  drive;  360k   media
                    216:     Drive720Media720,                      // 3.5"   720k  drive;  720k   media
                    217:     Drive120Media160,                      // 5.25" 1.2Mb  drive;  160k   media
                    218:     Drive120Media180,                      // 5.25" 1.2Mb  drive;  180k   media
                    219:     Drive120Media320,                      // 5.25" 1.2Mb  drive;  320k   media
                    220:     Drive120Media32X,                      // 5.25" 1.2Mb  drive;  320k 1k secs
                    221:     Drive120Media360,                      // 5.25" 1.2Mb  drive;  360k   media
                    222:     Drive120Media120,                      // 5.25" 1.2Mb  drive; 1.2Mb   media
                    223:     Drive144Media720,                      // 3.5"  1.44Mb drive;  720k   media
                    224:     Drive144Media144,                      // 3.5"  1.44Mb drive; 1.44Mb  media
                    225:     Drive288Media720,                      // 3.5"  2.88Mb drive;  720k   media
                    226:     Drive288Media144,                      // 3.5"  2.88Mb drive; 1.44Mb  media
                    227:     Drive288Media288                       // 3.5"  2.88Mb drive; 2.88Mb  media
                    228: } DRIVE_MEDIA_TYPE;
                    229: 
                    230: //
                    231: // When we want to determine the media type in a drive, we will first
                    232: // guess that the media with highest possible density is in the drive,
                    233: // and keep trying lower densities until we can successfully read from
                    234: // the drive.
                    235: //
                    236: // These values are used to select a DRIVE_MEDIA_TYPE value.
                    237: //
                    238: // The following table defines ranges that apply to the DRIVE_MEDIA_TYPE
                    239: // enumerated values when trying media types for a particular drive type.
                    240: // Note that for this to work, the DRIVE_MEDIA_TYPE values must be sorted
                    241: // by ascending densities within drive types.  Also, for maximum track
                    242: // size to be determined properly, the drive types must be in ascending
                    243: // order.
                    244: //
                    245: 
                    246: typedef struct _DRIVE_MEDIA_LIMITS {
                    247:     DRIVE_MEDIA_TYPE HighestDriveMediaType;
                    248:     DRIVE_MEDIA_TYPE LowestDriveMediaType;
                    249: } DRIVE_MEDIA_LIMITS, *PDRIVE_MEDIA_LIMITS;
                    250: 
                    251: DRIVE_MEDIA_LIMITS DriveMediaLimits[NUMBER_OF_DRIVE_TYPES] = {
                    252: 
                    253:     { Drive360Media360, Drive360Media160 }, // DRIVE_TYPE_0360
                    254:     { Drive120Media120, Drive120Media160 }, // DRIVE_TYPE_1200
                    255:     { Drive720Media720, Drive720Media720 }, // DRIVE_TYPE_0720
                    256:     { Drive144Media144, Drive144Media720 }, // DRIVE_TYPE_1440
                    257:     { Drive288Media288, Drive288Media720 }  // DRIVE_TYPE_2880
                    258: };
                    259: 
                    260: //
                    261: // For each drive/media combination, define important constants.
                    262: //
                    263: 
                    264: typedef struct _DRIVE_MEDIA_CONSTANTS {
                    265:     MEDIA_TYPE MediaType;
                    266:     UCHAR      StepRateHeadUnloadTime;
                    267:     UCHAR      HeadLoadTime;
                    268:     UCHAR      MotorOffTime;
                    269:     UCHAR      SectorLengthCode;
                    270:     USHORT     BytesPerSector;
                    271:     UCHAR      SectorsPerTrack;
                    272:     UCHAR      ReadWriteGapLength;
                    273:     UCHAR      FormatGapLength;
                    274:     UCHAR      FormatFillCharacter;
                    275:     UCHAR      HeadSettleTime;
                    276:     USHORT     MotorSettleTimeRead;
                    277:     USHORT     MotorSettleTimeWrite;
                    278:     UCHAR      MaximumTrack;
                    279:     UCHAR      CylinderShift;
                    280:     UCHAR      DataTransferRate;
                    281:     UCHAR      NumberOfHeads;
                    282:     UCHAR      DataLength;
                    283: } DRIVE_MEDIA_CONSTANTS, *PDRIVE_MEDIA_CONSTANTS;
                    284: 
                    285: //
                    286: // Magic value to add to the SectorLengthCode to use it as a shift value
                    287: // to determine the sector size.
                    288: //
                    289: 
                    290: #define SECTORLENGTHCODE_TO_BYTESHIFT      7
                    291: 
                    292: //
                    293: // The following values were gleaned from many different sources, which
                    294: // often disagreed with each other.  Where numbers were in conflict, I
                    295: // chose the more conservative or most-often-selected value.
                    296: //
                    297: 
                    298: DRIVE_MEDIA_CONSTANTS DriveMediaConstants[NUMBER_OF_DRIVE_MEDIA_COMBINATIONS] =
                    299:     {
                    300: 
                    301:     { F5_160_512,   0xdf, 0x2, 0x25, 0x2, 0x200, 0x08, 0x2a, 0x50, 0xf6, 0xf,
                    302:         1000, 1000, 0x27, 0, 0x2, 0x1, 0xff },
                    303:     { F5_180_512,   0xdf, 0x2, 0x25, 0x2, 0x200, 0x09, 0x2a, 0x50, 0xf6, 0xf,
                    304:         1000, 1000, 0x27, 0, 0x2, 0x1, 0xff },
                    305:     { F5_320_512,   0xdf, 0x2, 0x25, 0x2, 0x200, 0x08, 0x2a, 0x50, 0xf6, 0xf,
                    306:         1000, 1000, 0x27, 0, 0x2, 0x2, 0xff },
                    307:     { F5_320_1024,  0xdf, 0x2, 0x25, 0x3, 0x400, 0x04, 0x80, 0xf0, 0xf6, 0xf,
                    308:         1000, 1000, 0x27, 0, 0x2, 0x2, 0xff },
                    309:     { F5_360_512,   0xdf, 0x2, 0x25, 0x2, 0x200, 0x09, 0x2a, 0x50, 0xf6, 0xf,
                    310:          250, 1000, 0x27, 0, 0x2, 0x2, 0xff },
                    311: 
                    312:     { F3_720_512,   0xdf, 0x2, 0x25, 0x2, 0x200, 0x09, 0x2a, 0x50, 0xf6, 0xf,
                    313:          500, 1000, 0x4f, 0, 0x2, 0x2, 0xff },
                    314: 
                    315:     { F5_160_512,   0xdf, 0x2, 0x25, 0x2, 0x200, 0x08, 0x2a, 0x50, 0xf6, 0xf,
                    316:         1000, 1000, 0x27, 1, 0x1, 0x1, 0xff },
                    317:     { F5_180_512,   0xdf, 0x2, 0x25, 0x2, 0x200, 0x09, 0x2a, 0x50, 0xf6, 0xf,
                    318:         1000, 1000, 0x27, 1, 0x1, 0x1, 0xff },
                    319:     { F5_320_512,   0xdf, 0x2, 0x25, 0x2, 0x200, 0x08, 0x2a, 0x50, 0xf6, 0xf,
                    320:         1000, 1000, 0x27, 1, 0x1, 0x2, 0xff },
                    321:     { F5_320_1024,  0xdf, 0x2, 0x25, 0x3, 0x400, 0x04, 0x80, 0xf0, 0xf6, 0xf,
                    322:         1000, 1000, 0x27, 1, 0x1, 0x2, 0xff },
                    323:     { F5_360_512,   0xdf, 0x2, 0x25, 0x2, 0x200, 0x09, 0x2a, 0x50, 0xf6, 0xf,
                    324:          625, 1000, 0x27, 1, 0x1, 0x2, 0xff },
                    325:     { F5_1Pt2_512,  0xdf, 0x2, 0x25, 0x2, 0x200, 0x0f, 0x1b, 0x54, 0xf6, 0xf,
                    326:          625, 1000, 0x4f, 0, 0x0, 0x2, 0xff },
                    327: 
                    328:     { F3_720_512,   0xdf, 0x2, 0x25, 0x2, 0x200, 0x09, 0x2a, 0x50, 0xf6, 0xf,
                    329:          500, 1000, 0x4f, 0, 0x2, 0x2, 0xff },
                    330:     { F3_1Pt44_512, 0xaf, 0x2, 0x25, 0x2, 0x200, 0x12, 0x1b, 0x6c, 0xf6, 0xf,
                    331:          500, 1000, 0x4f, 0, 0x0, 0x2, 0xff },
                    332: 
                    333:     { F3_720_512,   0xe1, 0x2, 0x25, 0x2, 0x200, 0x09, 0x2a, 0x50, 0xf6, 0xf,
                    334:          500, 1000, 0x4f, 0, 0x2, 0x2, 0xff },
                    335:     { F3_1Pt44_512, 0xd1, 0x2, 0x25, 0x2, 0x200, 0x12, 0x1b, 0x65, 0xf6, 0xf,
                    336:          500, 1000, 0x4f, 0, 0x0, 0x2, 0xff },
                    337:     { F3_2Pt88_512, 0xa1, 0x2, 0x25, 0x2, 0x200, 0x24, 0x38, 0x53, 0xf6, 0xf,
                    338:          500, 1000, 0x4f, 0, 0x3, 0x2, 0xff }
                    339: };
                    340: 
                    341: 
                    342: //
                    343: // Boot Configuration Information
                    344: //
                    345: 
                    346: //
                    347: // Define the maximum number of controllers and floppies per controller
                    348: // that this driver will support.
                    349: //
                    350: // The number of floppies per controller is fixed at 4, since the
                    351: // controllers don't have enough bits to select more than that (and
                    352: // actually, many controllers will only support 2).  The number of
                    353: // controllers per machine is arbitrary; 3 should be more than enough.
                    354: //
                    355: 
                    356: #define MAXIMUM_CONTROLLERS_PER_MACHINE    3
                    357: #define MAXIMUM_DISKETTES_PER_CONTROLLER   4
                    358: 
                    359: //
                    360: // Floppy register structure.  The base address of the controller is
                    361: // passed in by configuration management.  Note that this is the 82077
                    362: // structure, which is a superset of the PD765 structure.  Not all of
                    363: // the registers are used.
                    364: //
                    365: 
                    366: typedef struct _CONTROLLER {
                    367:     UCHAR StatusA;
                    368:     UCHAR StatusB;
                    369:     UCHAR DriveControl;
                    370:     UCHAR Reserved1;
                    371:     UCHAR Status;
                    372:     UCHAR Fifo;
                    373:     UCHAR Reserved2;
                    374:     union {
                    375:         UCHAR DataRate;
                    376:         UCHAR DiskChange;
                    377:     } DRDC;
                    378: } CONTROLLER, *PCONTROLLER;
                    379: 
                    380: //
                    381: // This structure holds all of the configuration data.  It is filled in
                    382: // by FlGetConfigurationInformation(), which gets the information from
                    383: // the configuration manager or the hardware architecture layer (HAL).
                    384: //
                    385: 
                    386: typedef struct _CONFIG_CONTROLLER_DATA {
                    387:     PHYSICAL_ADDRESS OriginalBaseAddress;
                    388:     ULONG           ResourcePortType;
                    389:     PCONTROLLER     ControllerBaseAddress;
                    390:     PADAPTER_OBJECT AdapterObject;
                    391:     ULONG           SpanOfControllerAddress;
                    392:     ULONG           NumberOfMapRegisters;
                    393:     ULONG           BusNumber;
                    394:     ULONG           OriginalIrql;
                    395:     ULONG           OriginalVector;
                    396:     ULONG           OriginalDmaChannel;
                    397:     LONG            ActualControllerNumber;
                    398:     INTERFACE_TYPE  InterfaceType;
                    399:     KINTERRUPT_MODE InterruptMode;
                    400:     KAFFINITY       ProcessorMask;
                    401:     KIRQL           ControllerIrql;
                    402:     BOOLEAN         SaveFloatState;
                    403:     BOOLEAN         SharableVector;
                    404:     BOOLEAN         MappedAddress;
                    405:     BOOLEAN         OkToUseThisController;
                    406:     ULONG           ControllerVector;
                    407:     UCHAR           NumberOfDrives;
                    408:     UCHAR           DriveType[MAXIMUM_DISKETTES_PER_CONTROLLER];
                    409:     DRIVE_MEDIA_CONSTANTS BiosDriveMediaConstants[MAXIMUM_DISKETTES_PER_CONTROLLER];
                    410: } CONFIG_CONTROLLER_DATA,*PCONFIG_CONTROLLER_DATA;
                    411: 
                    412: typedef struct _CONFIG_DATA {
                    413:     PULONG          FloppyCount;
                    414:     PUCHAR          NtNamePrefix;
                    415:     UCHAR           NumberOfControllers;
                    416:     CONFIG_CONTROLLER_DATA Controller[MAXIMUM_CONTROLLERS_PER_MACHINE];
                    417: } CONFIG_DATA;
                    418: 
                    419: typedef CONFIG_DATA *PCONFIG_DATA;
                    420: 
                    421: 
                    422: //
                    423: // Floppy commands.                                Optional bits allowed.
                    424: //
                    425: 
                    426: #define COMMND_READ_DATA                   0x06    // Multi-Track, MFM, Skip
                    427: #define COMMND_READ_DELETED_DATA           0x0C    // Multi-Track, MFM, Skip
                    428: #define COMMND_READ_TRACK                  0x02    // MFM
                    429: #define COMMND_WRITE_DATA                  0x05    // Multi-Track, MFM
                    430: #define COMMND_WRITE_DELETED_DATA          0x09    // Multi-Track, MFM
                    431: #define COMMND_READ_ID                     0x0A    // MFM
                    432: #define COMMND_FORMAT_TRACK                0x0D    // MFM
                    433: #define COMMND_RECALIBRATE                 0x07
                    434: #define COMMND_SENSE_INTERRUPT             0x08
                    435: #define COMMND_SPECIFY                     0x03
                    436: #define COMMND_SENSE_DRIVE                 0x04
                    437: #define COMMND_SEEK                        0x0F
                    438: #define COMMND_PERPENDICULAR_MODE          0x12
                    439: #define COMMND_CONFIGURE                   0x13
                    440: 
                    441: //
                    442: // Optional bits used with the commands.
                    443: //
                    444: 
                    445: #define COMMND_MULTI_TRACK                 0x80
                    446: #define COMMND_MFM                         0x40
                    447: #define COMMND_SKIP                        0x20
                    448: 
                    449: //
                    450: // Parameter fields passed to the CONFIGURE command.
                    451: //
                    452: 
                    453: #define COMMND_CONFIGURE_IMPLIED_SEEKS     0x40
                    454: #define COMMND_CONFIGURE_FIFO_THRESHOLD    0x0F
                    455: #define COMMND_CONFIGURE_DISABLE_FIFO      0x20
                    456: #define COMMND_CONFIGURE_DISABLE_POLLING   0x10
                    457: 
                    458: //
                    459: // Write Enable bit for PERPENDICULAR MODE command.
                    460: //
                    461: 
                    462: #define COMMND_PERPENDICULAR_MODE_OW       0x80
                    463: 
                    464: //
                    465: // The command table is used by FlIssueCommand() to determine how many
                    466: // bytes to get and receive, and whether or not to wait for an interrupt.
                    467: // Some commands have extra bits; COMMAND_MASK takes these off.
                    468: // FirstResultByte indicates whether the command has a result stage
                    469: // or not; if so, it's 1 because the ISR read the 1st byte, and
                    470: // NumberOfResultBytes is 1 less than expected.  If not, it's 0 and
                    471: // NumberOfResultBytes is 2, since the ISR will have issued a SENSE
                    472: // INTERRUPT STATUS command.
                    473: //
                    474: 
                    475: #define COMMAND_MASK                       0x1f
                    476: 
                    477: typedef struct _COMMAND_TABLE {
                    478:     UCHAR   NumberOfParameters;
                    479:     UCHAR   FirstResultByte;
                    480:     UCHAR   NumberOfResultBytes;
                    481:     BOOLEAN InterruptExpected;
                    482:     BOOLEAN AlwaysImplemented;
                    483: } COMMAND_TABLE;
                    484: 
                    485: COMMAND_TABLE CommandTable[] = {
                    486: 
                    487:     { 0, 0, 0,  FALSE, FALSE },            // 00 not implemented
                    488:     { 0, 0, 0,  FALSE, FALSE },            // 01 not implemented
                    489:     { 8, 1, 7,  TRUE,  TRUE  },            // 02 read track
                    490:     { 2, 0, 0,  FALSE, TRUE  },            // 03 specify
                    491:     { 1, 0, 1,  FALSE, TRUE  },            // 04 sense drive status
                    492:     { 8, 1, 7,  TRUE,  TRUE  },            // 05 write
                    493:     { 8, 1, 7,  TRUE,  TRUE  },            // 06 read
                    494:     { 1, 0, 2,  TRUE,  TRUE  },            // 07 recalibrate
                    495:     { 0, 0, 2,  FALSE, TRUE  },            // 08 sense interrupt status
                    496:     { 0, 0, 0,  FALSE, FALSE },            // 09 not implemented
                    497:     { 1, 1, 7,  TRUE,  TRUE  },            // 0a read id
                    498:     { 0, 0, 0,  FALSE, FALSE },            // 0b not implemented
                    499:     { 0, 0, 0,  FALSE, FALSE },            // 0c not implemented
                    500:     { 5, 1, 7,  TRUE,  TRUE  },            // 0d format track
                    501:     { 0, 0, 10, FALSE, FALSE },            // 0e dump registers
                    502:     { 2, 0, 2,  TRUE,  TRUE  },            // 0f seek
                    503:     { 0, 0, 1,  FALSE, FALSE },            // 10 version
                    504:     { 0, 0, 0,  FALSE, FALSE },            // 11 not implemented
                    505:     { 1, 0, 0,  FALSE, FALSE },            // 12 perpendicular mode
                    506:     { 3, 0, 0,  FALSE, FALSE },            // 13 configure
                    507:     { 0, 0, 0,  FALSE, FALSE },            // 14 not implemented
                    508:     { 0, 0, 0,  FALSE, FALSE },            // 15 not implemented
                    509:     { 8, 1, 7,  TRUE,  FALSE }             // 16 verify
                    510: };
                    511: 
                    512: //
                    513: // Bits in the DRIVE_CONTROL register.
                    514: //
                    515: 
                    516: #define DRVCTL_RESET                       0x00
                    517: #define DRVCTL_ENABLE_CONTROLLER           0x04
                    518: #define DRVCTL_ENABLE_DMA_AND_INTERRUPTS   0x08
                    519: #define DRVCTL_DRIVE_0                     0x10
                    520: #define DRVCTL_DRIVE_1                     0x21
                    521: #define DRVCTL_DRIVE_2                     0x42
                    522: #define DRVCTL_DRIVE_3                     0x83
                    523: #define DRVCTL_DRIVE_MASK                  0x03
                    524: #define DRVCTL_MOTOR_MASK                  0xf0
                    525: 
                    526: //
                    527: // Bits in the STATUS register.
                    528: //
                    529: 
                    530: #define STATUS_DRIVE_0_BUSY                0x01
                    531: #define STATUS_DRIVE_1_BUSY                0x02
                    532: #define STATUS_DRIVE_2_BUSY                0x04
                    533: #define STATUS_DRIVE_3_BUSY                0x08
                    534: #define STATUS_CONTROLLER_BUSY             0x10
                    535: #define STATUS_DMA_UNUSED                  0x20
                    536: #define STATUS_DIRECTION_READ              0x40
                    537: #define STATUS_DATA_REQUEST                0x80
                    538: 
                    539: #define STATUS_IO_READY_MASK               0xc0
                    540: #define STATUS_READ_READY                  0xc0
                    541: #define STATUS_WRITE_READY                 0x80
                    542: 
                    543: //
                    544: // Bits in the DATA_RATE register.
                    545: //
                    546: 
                    547: #define DATART_0125                        0x03
                    548: #define DATART_0250                        0x02
                    549: #define DATART_0300                        0x01
                    550: #define DATART_0500                        0x00
                    551: #define DATART_1000                        0x03
                    552: #define DATART_RESERVED                    0xfc
                    553: 
                    554: //
                    555: // Bits in the DISK_CHANGE register.
                    556: //
                    557: 
                    558: #define DSKCHG_RESERVED                    0x7f
                    559: #define DSKCHG_DISKETTE_REMOVED            0x80
                    560: 
                    561: //
                    562: // Bits in status register 0.
                    563: //
                    564: 
                    565: #define STREG0_DRIVE_0                     0x00
                    566: #define STREG0_DRIVE_1                     0x01
                    567: #define STREG0_DRIVE_2                     0x02
                    568: #define STREG0_DRIVE_3                     0x03
                    569: #define STREG0_HEAD                        0x04
                    570: #define STREG0_DRIVE_NOT_READY             0x08
                    571: #define STREG0_DRIVE_FAULT                 0x10
                    572: #define STREG0_SEEK_COMPLETE               0x20
                    573: #define STREG0_END_NORMAL                  0x00
                    574: #define STREG0_END_ERROR                   0x40
                    575: #define STREG0_END_INVALID_COMMAND         0x80
                    576: #define STREG0_END_DRIVE_NOT_READY         0xC0
                    577: #define STREG0_END_MASK                    0xC0
                    578: 
                    579: //
                    580: // Bits in status register 1.
                    581: //
                    582: 
                    583: #define STREG1_ID_NOT_FOUND                0x01
                    584: #define STREG1_WRITE_PROTECTED             0x02
                    585: #define STREG1_SECTOR_NOT_FOUND            0x04
                    586: #define STREG1_RESERVED1                   0x08
                    587: #define STREG1_DATA_OVERRUN                0x10
                    588: #define STREG1_CRC_ERROR                   0x20
                    589: #define STREG1_RESERVED2                   0x40
                    590: #define STREG1_END_OF_DISKETTE             0x80
                    591: 
                    592: //
                    593: // Bits in status register 2.
                    594: //
                    595: 
                    596: #define STREG2_SUCCESS                     0x00
                    597: #define STREG2_DATA_NOT_FOUND              0x01
                    598: #define STREG2_BAD_CYLINDER                0x02
                    599: #define STREG2_SCAN_FAIL                   0x04
                    600: #define STREG2_SCAN_EQUAL                  0x08
                    601: #define STREG2_WRONG_CYLINDER              0x10
                    602: #define STREG2_CRC_ERROR                   0x20
                    603: #define STREG2_DELETED_DATA                0x40
                    604: #define STREG2_RESERVED                    0x80
                    605: 
                    606: //
                    607: // Bits in status register 3.
                    608: //
                    609: 
                    610: #define STREG3_DRIVE_0                     0x00
                    611: #define STREG3_DRIVE_1                     0x01
                    612: #define STREG3_DRIVE_2                     0x02
                    613: #define STREG3_DRIVE_3                     0x03
                    614: #define STREG3_HEAD                        0x04
                    615: #define STREG3_TWO_SIDED                   0x08
                    616: #define STREG3_TRACK_0                     0x10
                    617: #define STREG3_DRIVE_READY                 0x20
                    618: #define STREG3_WRITE_PROTECTED             0x40
                    619: #define STREG3_DRIVE_FAULT                 0x80
                    620: 
                    621: 
                    622: //
                    623: // Runtime device structures
                    624: //
                    625: 
                    626: //
                    627: // There is one CONTROLLER_DATA allocated per controller (generally one
                    628: // per machine).  It holds all information common to all the drives
                    629: // attached to the controller.
                    630: //
                    631: 
                    632: typedef struct _CONTROLLER_DATA {
                    633:     UCHAR            FifoBuffer[10];
                    634:     LARGE_INTEGER    InterruptDelay;
                    635:     LARGE_INTEGER    Minimum10msDelay;
                    636:     LIST_ENTRY       ListEntry;
                    637:     KEVENT           InterruptEvent;
                    638:     KEVENT           AllocateAdapterChannelEvent;
                    639:     KDPC             LogErrorDpc;
                    640:     KSEMAPHORE       RequestSemaphore;
                    641:     KSPIN_LOCK       TimerSpinLock;
                    642:     KSPIN_LOCK       ListSpinLock;
                    643:     PKINTERRUPT      InterruptObject;
                    644:     PVOID            MapRegisterBase;
                    645:     PUCHAR           IoBuffer;
                    646:     PMDL             IoBufferMdl;
                    647:     PADAPTER_OBJECT  AdapterObject;
                    648:     PDEVICE_OBJECT   CurrentDeviceObject;
                    649:     PDRIVER_OBJECT   DriverObject;
                    650:     PCONTROLLER      ControllerAddress;
                    651:     PVOID            LastDisketteExtension;
                    652:     HANDLE           ControllerEventHandle;
                    653:     PKEVENT          ControllerEvent;
                    654:     ULONG            IoBufferSize;
                    655:     ULONG            SpanOfControllerAddress;
                    656:     ULONG            NumberOfMapRegisters;
                    657:     ULONG            IsrReentered;
                    658:     LONG             MotorTimer;
                    659:     DRIVE_MEDIA_TYPE LastDriveMediaType;
                    660:     UCHAR            NumberOfDrives;
                    661:     UCHAR            DriveControlImage;
                    662:     UCHAR            HardwareFailCount;
                    663:     BOOLEAN          HardwareFailed;
                    664:     BOOLEAN          CommandHasResultPhase;
                    665:     BOOLEAN          ControllerConfigurable;
                    666:     BOOLEAN          CreatedArtificialDrive;
                    667:     BOOLEAN          UnloadingDriver;
                    668:     BOOLEAN          MappedControllerAddress;
                    669:     BOOLEAN          CurrentInterrupt;
                    670:     UCHAR            PerpendicularDrives;
                    671: } CONTROLLER_DATA;
                    672: 
                    673: typedef CONTROLLER_DATA *PCONTROLLER_DATA;
                    674: 
                    675: //
                    676: // There is one DISKETTE_EXTENSION attached to the device object of each
                    677: // floppy drive.  Only data directly related to that drive (and the media
                    678: // in it) is stored here; common data is in CONTROLLER_DATA.  So the
                    679: // DISKETTE_EXTENSION has a pointer to the CONTROLLER_DATA.
                    680: //
                    681: 
                    682: typedef struct _DISKETTE_EXTENSION {
                    683:     PDEVICE_OBJECT        DeviceObject;
                    684:     PCONTROLLER_DATA      ControllerData;
                    685:     UCHAR                 DriveType;
                    686:     ULONG                 BytesPerSector;
                    687:     ULONG                 ByteCapacity;
                    688:     MEDIA_TYPE            MediaType;
                    689:     DRIVE_MEDIA_TYPE      DriveMediaType;
                    690:     UCHAR                 DeviceUnit;
                    691:     UCHAR                 DriveOnValue;
                    692:     BOOLEAN               ArtificialVerifyRequired;
                    693:     DRIVE_MEDIA_CONSTANTS BiosDriveMediaConstants;
                    694:     DRIVE_MEDIA_CONSTANTS DriveMediaConstants;
                    695: } DISKETTE_EXTENSION;
                    696: 
                    697: typedef DISKETTE_EXTENSION *PDISKETTE_EXTENSION;
                    698: 
                    699: 
                    700: //
                    701: // Prototypes of external routines.
                    702: //
                    703: 
                    704: LONG
                    705: sprintf(
                    706:     CHAR *,
                    707:     const CHAR *,
                    708:     ...
                    709:     );
                    710: 
                    711: //
                    712: // Prototypes of driver routines.
                    713: //
                    714: 
                    715: NTSTATUS
                    716: DriverEntry(
                    717:     IN PDRIVER_OBJECT DriverObject,
                    718:     IN PUNICODE_STRING RegistryPath
                    719:     );
                    720: 
                    721: NTSTATUS
                    722: FlConfigCallBack(
                    723:     IN PVOID Context,
                    724:     IN PUNICODE_STRING PathName,
                    725:     IN INTERFACE_TYPE BusType,
                    726:     IN ULONG BusNumber,
                    727:     IN PKEY_VALUE_FULL_INFORMATION *BusInformation,
                    728:     IN CONFIGURATION_TYPE ControllerType,
                    729:     IN ULONG ControllerNumber,
                    730:     IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
                    731:     IN CONFIGURATION_TYPE PeripheralType,
                    732:     IN ULONG PeripheralNumber,
                    733:     IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation
                    734:     );
                    735: 
                    736: BOOLEAN
                    737: FlReportResources(
                    738:     IN PDRIVER_OBJECT DriverObject,
                    739:     IN PCONFIG_DATA ConfigData,
                    740:     IN UCHAR ControllerNumber
                    741:     );
                    742: 
                    743: NTSTATUS
                    744: FlGetConfigurationInformation(
                    745:     OUT PCONFIG_DATA *ConfigData
                    746:     );
                    747: 
                    748: NTSTATUS
                    749: FlInitializeController(
                    750:     IN PCONFIG_DATA ConfigData,
                    751:     IN UCHAR ControllerNumber,
                    752:     IN PDRIVER_OBJECT DriverObject
                    753:     );
                    754: 
                    755: NTSTATUS
                    756: FlInitializeControllerHardware(
                    757:     IN PCONTROLLER_DATA ControllerData,
                    758:     IN PDEVICE_OBJECT DeviceObject
                    759:     );
                    760: 
                    761: NTSTATUS
                    762: FlInitializeDrive(
                    763:     IN PCONFIG_DATA ConfigData,
                    764:     IN PCONTROLLER_DATA ControllerData,
                    765:     IN UCHAR ControllerNum,
                    766:     IN UCHAR DisketteNum,
                    767:     IN UCHAR DisketteUnit,
                    768:     IN PDRIVER_OBJECT DriverObject
                    769:     );
                    770: 
                    771: NTSTATUS
                    772: FloppyDispatchCreateClose(
                    773:     IN PDEVICE_OBJECT DeviceObject,
                    774:     IN PIRP Irp
                    775:     );
                    776: 
                    777: NTSTATUS
                    778: FloppyDispatchDeviceControl(
                    779:     IN PDEVICE_OBJECT DeviceObject,
                    780:     IN PIRP Irp
                    781:     );
                    782: 
                    783: NTSTATUS
                    784: FloppyDispatchReadWrite(
                    785:     IN PDEVICE_OBJECT DeviceObject,
                    786:     IN PIRP Irp
                    787:     );
                    788: 
                    789: BOOLEAN
                    790: FloppyInterruptService(
                    791:     IN PKINTERRUPT Interrupt,
                    792:     IN PVOID Context
                    793:     );
                    794: 
                    795: VOID
                    796: FloppyDeferredProcedure(
                    797:     IN PKDPC Dpc,
                    798:     IN PVOID DeferredContext,
                    799:     IN PVOID SystemArgument1,
                    800:     IN PVOID SystemArgument2
                    801:     );
                    802: 
                    803: VOID
                    804: FloppyUnloadDriver(
                    805:     IN PDRIVER_OBJECT DriverObject
                    806:     );
                    807: 
                    808: VOID
                    809: FloppyMotorOffDpc(
                    810:     IN PDEVICE_OBJECT DeviceObject,
                    811:     IN PVOID Context
                    812:     );
                    813: 
                    814: NTSTATUS
                    815: FlRecalibrateDrive(
                    816:     IN PDISKETTE_EXTENSION DisketteExtension
                    817:     );
                    818: 
                    819: NTSTATUS
                    820: FlDatarateSpecifyConfigure(
                    821:     IN PDISKETTE_EXTENSION DisketteExtension
                    822:     );
                    823: 
                    824: NTSTATUS
                    825: FlStartDrive(
                    826:     IN OUT PDISKETTE_EXTENSION DisketteExtension,
                    827:     IN BOOLEAN WriteOperation,
                    828:     IN BOOLEAN SetUpMedia,
                    829:     IN BOOLEAN IgnoreChange
                    830:     );
                    831: 
                    832: VOID
                    833: FlFinishOperation(
                    834:     IN OUT PIRP Irp,
                    835:     IN PDISKETTE_EXTENSION DisketteExtension
                    836:     );
                    837: 
                    838: NTSTATUS
                    839: FlDetermineMediaType(
                    840:     IN OUT PDISKETTE_EXTENSION DisketteExtension
                    841:     );
                    842: 
                    843: VOID
                    844: FloppyThread(
                    845:     IN PVOID Context
                    846:     );
                    847: 
                    848: IO_ALLOCATION_ACTION
                    849: FloppyAllocateAdapterChannel(
                    850:     IN PDEVICE_OBJECT DeviceObject,
                    851:     IN PIRP Irp,
                    852:     IN PVOID MapRegisterBase,
                    853:     IN PVOID Context
                    854:     );
                    855: 
                    856: NTSTATUS
                    857: FlReadWrite(
                    858:     IN OUT PDISKETTE_EXTENSION DisketteExtension,
                    859:     IN OUT PIRP Irp
                    860:     );
                    861: 
                    862: NTSTATUS
                    863: FlFormat(
                    864:     IN PDISKETTE_EXTENSION DisketteExtension,
                    865:     IN PIRP Irp
                    866:     );
                    867: 
                    868: NTSTATUS
                    869: FlSendByte(
                    870:     IN UCHAR ByteToSend,
                    871:     IN PCONTROLLER_DATA ControllerData
                    872:     );
                    873: 
                    874: NTSTATUS
                    875: FlGetByte(
                    876:     OUT PUCHAR ByteToGet,
                    877:     IN PCONTROLLER_DATA ControllerData
                    878:     );
                    879: 
                    880: NTSTATUS
                    881: FlIssueCommand(
                    882:     IN UCHAR Command,
                    883:     IN OUT PDISKETTE_EXTENSION DisketteExtension
                    884:     );
                    885: 
                    886: BOOLEAN
                    887: FlCheckFormatParameters(
                    888:     IN PDISKETTE_EXTENSION DisketteExtension,
                    889:     IN PFORMAT_PARAMETERS Fp
                    890:     );
                    891: 
                    892: PCONTROLLER
                    893: FlGetControllerBase(
                    894:     IN INTERFACE_TYPE BusType,
                    895:     IN ULONG BusNumber,
                    896:     PHYSICAL_ADDRESS IoAddress,
                    897:     ULONG NumberOfBytes,
                    898:     BOOLEAN InIoSpace,
                    899:     PBOOLEAN MappedAddress
                    900:     );
                    901: 
                    902: VOID
                    903: FlLogErrorDpc(
                    904:     IN PKDPC Dpc,
                    905:     IN PVOID DeferredContext,
                    906:     IN PVOID SystemContext1,
                    907:     IN PVOID SystemContext2
                    908:     );

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.