Annotation of ntddk/src/scsi/floppy/flo_data.h, revision 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.