branch update for HEAD-2003050101
[reactos.git] / drivers / dd / floppy / isr.c
1 /************************************************************************
2  * Interrupt handlers for floppy disk driver, reactos project, created  *
3  * by Phillip Susi on 2/25/2001.  This software is publised under the   *
4  * GNU General public license.  See the README file for more details    *
5  ***********************************************************************/
6
7 #include <ddk/ntddk.h>
8 #define NDEBUG
9 #include <debug.h>
10 #include "floppy.h"
11
12
13 // ISR state machine function called when expecting an interrupt due to reset
14 // During reset, there is nothing ready to read, just issue sense interrupt status
15
16 BOOLEAN FloppyIsrDetect( PCONTROLLER_OBJECT Controller )
17 {
18    PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension;
19    PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)ControllerExtension->Device->DeviceExtension;
20    // Issue read interrupt status, and store the results
21    FloppyWriteDATA( ControllerExtension->PortBase, FLOPPY_CMD_SNS_INTR );
22    KeStallExecutionProcessor( 100 );
23    ControllerExtension->St0 = FloppyReadDATA( ControllerExtension->PortBase );
24    KeStallExecutionProcessor( 100 );
25    DeviceExtension->Cyl = FloppyReadDATA( ControllerExtension->PortBase );
26    KeStallExecutionProcessor( 100 );
27    if (FLOPPY_MS_DATARDYR ==
28        (FloppyReadMSTAT( ControllerExtension->PortBase ) & FLOPPY_MS_RDYMASK))
29       {
30          /* There's something still to be read (what is it???? only happens on some
31             controllers). Ignore it. */
32          (void) FloppyReadDATA( ControllerExtension->PortBase );
33       }
34    // now queue DPC to set the event
35    IoRequestDpc( ControllerExtension->Device,
36                  0,
37                  Controller );
38    return TRUE;
39 }
40
41 // ISR state machine handler for unexpected interrupt
42 BOOLEAN FloppyIsrUnexpected( PCONTROLLER_OBJECT Controller )
43 {
44    DPRINT( "Unexpected interrupt!\n" );
45    return FALSE;
46 }
47
48 BOOLEAN FloppyIsrDetectMedia( PCONTROLLER_OBJECT Controller )
49 {
50   PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension;
51   BYTE SectorSize;
52   // media detect in progress, read ID command already issued
53   // first, read result registers
54   KeStallExecutionProcessor( 1000 );
55   ControllerExtension->St0 = FloppyReadDATA( ControllerExtension->PortBase );
56   KeStallExecutionProcessor( 1000 );
57   ControllerExtension->St1 = FloppyReadDATA( ControllerExtension->PortBase );
58   KeStallExecutionProcessor( 1000 );
59   ControllerExtension->St2 = FloppyReadDATA( ControllerExtension->PortBase );
60   KeStallExecutionProcessor( 1000 );
61   FloppyReadDATA( ControllerExtension->PortBase ); // ignore cyl
62   KeStallExecutionProcessor( 1000 );
63   FloppyReadDATA( ControllerExtension->PortBase ); // ignore head
64   KeStallExecutionProcessor( 1000 );
65   FloppyReadDATA( ControllerExtension->PortBase ); // ignore sector
66   KeStallExecutionProcessor( 1000 );
67   SectorSize = FloppyReadDATA( ControllerExtension->PortBase );
68   DPRINT( "Sector Size Code: %2x\n", SectorSize );
69   DPRINT( "St0 = %2x, St1 = %2x, St2 = %2x\n", ControllerExtension->St0, ControllerExtension->St1, ControllerExtension->St2 );
70   DPRINT( "ControllerExtension->Device = %x, ControllerExtension->Irp = %x\n", ControllerExtension->Device, ControllerExtension->Irp );
71   // queue DPC
72   ControllerExtension->DpcState = FloppyDpcDetectMedia;
73   IoRequestDpc( ControllerExtension->Device,
74                 ControllerExtension->Irp,
75                 Controller );
76   return TRUE;
77
78     
79 BOOLEAN FloppyIsrRecal( PCONTROLLER_OBJECT Controller )
80 {
81    PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension;
82    // issue sense interrupt status, and read St0 and cyl
83
84    FloppyWriteDATA( ControllerExtension->PortBase, FLOPPY_CMD_SNS_INTR );
85    KeStallExecutionProcessor( 1000 );
86    ControllerExtension->St0 = FloppyReadDATA( ControllerExtension->PortBase );
87    KeStallExecutionProcessor( 1000 );
88    FloppyReadDATA( ControllerExtension->PortBase );  // ignore cyl number
89    if (FLOPPY_MS_DATARDYR ==
90        (FloppyReadMSTAT( ControllerExtension->PortBase ) & FLOPPY_MS_RDYMASK))
91       {
92          /* There's something still to be read (what is it???? only happens on some
93             controllers). Ignore it. */
94          (void) FloppyReadDATA( ControllerExtension->PortBase );
95       }
96    DPRINT( "Recal St0: %2x\n", ControllerExtension->St0 );
97
98    // If recalibrate worked, issue read ID for each media type untill one works
99    if( ControllerExtension->St0 != FLOPPY_ST0_SEEKGD )
100       {
101          DPRINT( "Recalibrate failed, ST0 = %2x\n", ControllerExtension->St0 );
102          // queue DPC to fail IRP
103          ControllerExtension->DpcState = FloppyDpcFailIrp;
104          IoRequestDpc( ControllerExtension->Device,
105                        ControllerExtension->Irp,
106                        Controller );
107       }
108    else {
109      // issue first read id, FloppyIsrDetectMedia will handle
110      DPRINT( "Recalibrate worked, issuing read ID mark command\n" );
111      ControllerExtension->IsrState = FloppyIsrDetectMedia;
112      KeStallExecutionProcessor( 1000 );
113      FloppyWriteDATA( ControllerExtension->PortBase, FLOPPY_CMD_RD_ID | FLOPPY_C0M_MFM );
114      KeStallExecutionProcessor( 1000 );
115      FloppyWriteDATA( ControllerExtension->PortBase, ((PFLOPPY_DEVICE_EXTENSION)ControllerExtension->Device->DeviceExtension)->DriveSelect );
116    }
117    
118    return TRUE;
119 }
120
121 BOOLEAN FloppyIsrReadWrite( PCONTROLLER_OBJECT Controller )
122 {
123   // read result registers from read or write command, and queue dpc to start next operation
124   PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension;
125   BYTE Cyl, Head, Sector;
126   PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)ControllerExtension->Device->DeviceExtension;
127   PIO_STACK_LOCATION Stk = IoGetCurrentIrpStackLocation( ControllerExtension->Irp );
128   BOOLEAN WriteToDevice = Stk->MajorFunction == IRP_MJ_WRITE ? TRUE : FALSE;
129
130
131   ControllerExtension->St0 = FloppyReadDATA( ControllerExtension->PortBase );
132   KeStallExecutionProcessor( 100 );
133   ControllerExtension->St1 = FloppyReadDATA( ControllerExtension->PortBase );
134   KeStallExecutionProcessor( 100 );
135   ControllerExtension->St2 = FloppyReadDATA( ControllerExtension->PortBase );
136   KeStallExecutionProcessor( 100 );
137   Cyl = FloppyReadDATA( ControllerExtension->PortBase );    // cyl
138   KeStallExecutionProcessor( 100 );
139   Head = FloppyReadDATA( ControllerExtension->PortBase );    // head
140   KeStallExecutionProcessor( 100 );
141   Sector = FloppyReadDATA( ControllerExtension->PortBase );    // sector
142   KeStallExecutionProcessor( 100 );
143   ControllerExtension->SectorSizeCode = FloppyReadDATA( ControllerExtension->PortBase );
144   // reprogam for next sector if we are not done reading track
145   /*  if( ( ControllerExtension->TransferLength -= ( 128 << ControllerExtension->SectorSizeCode ) ) )
146     {
147       DPRINT1( "ISR reprogramming for next sector: %d\n", Sector );
148       Sector++;
149       FloppyWriteDATA( ControllerExtension->PortBase, WriteToDevice ? FLOPPY_CMD_WRITE : FLOPPY_CMD_READ );
150       KeStallExecutionProcessor( 100 );
151       FloppyWriteDATA( ControllerExtension->PortBase, ( Head << 2 ) | DeviceExtension->DriveSelect );
152       KeStallExecutionProcessor( 100 );
153       FloppyWriteDATA( ControllerExtension->PortBase, Cyl );
154       KeStallExecutionProcessor( 100 );
155       FloppyWriteDATA( ControllerExtension->PortBase, Head );
156       KeStallExecutionProcessor( 100 );
157       FloppyWriteDATA( ControllerExtension->PortBase, Sector );
158       KeStallExecutionProcessor( 100 );
159       FloppyWriteDATA( ControllerExtension->PortBase, ControllerExtension->SectorSizeCode );
160       KeStallExecutionProcessor( 100 );
161       FloppyWriteDATA( ControllerExtension->PortBase, MediaTypes[DeviceExtension->MediaType].SectorsPerTrack );
162       KeStallExecutionProcessor( 100 );
163       FloppyWriteDATA( ControllerExtension->PortBase, 0 );
164       KeStallExecutionProcessor( 100 );
165       FloppyWriteDATA( ControllerExtension->PortBase, 0xFF );
166     }
167     else */IoRequestDpc( ControllerExtension->Device,
168                      ControllerExtension->Irp,
169                      Controller );
170   return TRUE;
171 }
172
173 // actual ISR, passes controll to handler for current state in state machine
174
175 BOOLEAN STDCALL
176 FloppyIsr(PKINTERRUPT Interrupt,
177           PVOID ServiceContext)
178 {
179    PCONTROLLER_OBJECT Controller = (PCONTROLLER_OBJECT)ServiceContext;
180    PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension;
181    BYTE Byte;
182
183    // need to make sure interrupt is for us, and add some delay for the damn FDC
184    // without the delay, even though the thing has interrupted, it's still not ready
185    // for us to read the data register.
186    KeStallExecutionProcessor( 100 );
187    Byte = FloppyReadMSTAT( ControllerExtension->PortBase );
188    KeStallExecutionProcessor( 100 );
189    if( Byte == 0 )
190      {
191        DPRINT( "Ignoring interrupt, MSTAT = 0\n" );
192        return TRUE;
193      }
194    return ControllerExtension->IsrState( Controller );
195 }
196
197