:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / drivers / dd / floppy / dpc.c
1 /****************************************************************************
2  * Defered procedure calls for floppy disk driver, reactos project, created *
3  * by Phillip Susi on 2/25/2001.  This software is published under the GNU  *
4  * 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 VOID STDCALL
14 FloppyDpc(PKDPC Dpc,
15           PDEVICE_OBJECT DeviceObject,
16           PIRP Irp,
17           PVOID Context)
18 {
19    PCONTROLLER_OBJECT Controller = (PCONTROLLER_OBJECT)Context;
20    PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension;
21    ControllerExtension->DpcState( Dpc,
22                                   DeviceObject,
23                                   Irp,
24                                   Context );
25 }
26
27
28 VOID STDCALL
29 FloppyDpcDetect(PKDPC Dpc,
30                 PDEVICE_OBJECT DeviceObject,
31                 PIRP Irp,
32                 PVOID Context)
33 {
34    PCONTROLLER_OBJECT Controller = (PCONTROLLER_OBJECT)Context;
35    PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension;
36    KeSetEvent( &ControllerExtension->Event, 0, FALSE );
37 }
38
39 VOID STDCALL
40 FloppyDpcFailIrp(PKDPC Dpc,
41                  PDEVICE_OBJECT DeviceObject,
42                  PIRP Irp,
43                  PVOID Context)
44 {
45    Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
46    CHECKPOINT;
47    IoCompleteRequest( Irp, 0 );
48 }
49
50 VOID STDCALL
51 FloppyMotorSpindownDpc(PKDPC Dpc,
52                        PVOID Context,
53                        PVOID Arg1,
54                        PVOID Arg2 )
55 {
56    PCONTROLLER_OBJECT Controller = (PCONTROLLER_OBJECT)Context;
57    PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension;
58    PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)ControllerExtension->Device->DeviceExtension;
59
60    // queue call to turn off motor
61    IoAllocateController( Controller,
62                          ControllerExtension->Device,
63                          FloppyExecuteSpindown,
64                          ControllerExtension );
65 }
66
67 VOID STDCALL
68 FloppyMotorSpinupDpc(PKDPC Dpc,
69                      PVOID Context,
70                      PVOID Arg1,
71                      PVOID Arg2)
72 {
73    PCONTROLLER_OBJECT Controller = (PCONTROLLER_OBJECT)Context;
74    PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension;
75    PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)ControllerExtension->Device->DeviceExtension;
76    LARGE_INTEGER Timeout;
77
78    Timeout.QuadPart = FLOPPY_MOTOR_SPINDOWN_TIME;
79    // Motor has had time to spin up, mark motor as spun up and restart IRP
80    // don't forget to set the spindown timer
81    KeSetTimer( &ControllerExtension->SpinupTimer,
82                Timeout,
83                &ControllerExtension->MotorSpindownDpc );
84    DPRINT( "Motor spun up, retrying operation\n" );
85    ControllerExtension->MotorOn = DeviceExtension->DriveSelect;
86    IoFreeController( Controller );
87    IoAllocateController( Controller,
88                          ControllerExtension->Device,
89                          FloppyExecuteReadWrite,
90                          ControllerExtension->Irp );
91 }
92
93 VOID STDCALL
94 FloppySeekDpc(PKDPC Dpc,
95               PDEVICE_OBJECT DeviceObject,
96               PIRP Irp,
97               PVOID Context)
98 {
99   PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
100   PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)DeviceExtension->Controller->ControllerExtension;
101
102   // if the seek failed, fail the IRP
103   if( ControllerExtension->St0 & FLOPPY_ST0_GDMASK )
104     {
105       ControllerExtension->Irp->IoStatus.Status = STATUS_DISK_CORRUPT_ERROR;
106       ControllerExtension->Irp->IoStatus.Information = 0;
107       DPRINT( "Failing IRP: St0 = %2x, St1 = %2x, St2 = %2x\n",
108               ControllerExtension->St0,
109               ControllerExtension->St1,
110               ControllerExtension->St2 );
111       for(;;);
112       IoCompleteRequest( ControllerExtension->Irp, 0 );
113       IoFreeController( DeviceExtension->Controller );
114       return;
115     }
116   KeStallExecutionProcessor( 10000 );
117   DPRINT( "Seek completed, now on cyl %2x\n", DeviceExtension->Cyl );
118   // now that we are on the right cyl, restart the read
119   if( FloppyExecuteReadWrite( DeviceObject,
120                               ControllerExtension->Irp,
121                               ControllerExtension->MapRegisterBase,
122                               ControllerExtension->Irp ) == DeallocateObject )
123     IoFreeController( DeviceExtension->Controller );
124 }
125
126 VOID STDCALL
127 FloppyDpcReadWrite(PKDPC Dpc,
128                    PDEVICE_OBJECT DeviceObject,
129                    PIRP Irp,
130                    PVOID Context)
131 {
132   PCONTROLLER_OBJECT Controller = (PCONTROLLER_OBJECT)Context;
133   PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension;
134   PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)ControllerExtension->Device->DeviceExtension;
135   DWORD SectorSize = 128 << ControllerExtension->SectorSizeCode;
136   PIO_STACK_LOCATION Stk = IoGetCurrentIrpStackLocation( ControllerExtension->Irp );
137   BOOLEAN WriteToDevice = Stk->MajorFunction == IRP_MJ_WRITE ? TRUE : FALSE;
138
139   Irp = ControllerExtension->Irp;
140   // if the IO failed, fail the IRP
141   if( ControllerExtension->St0 & FLOPPY_ST0_GDMASK )
142     {
143       Irp->IoStatus.Status = STATUS_DISK_CORRUPT_ERROR;
144       Irp->IoStatus.Information = 0;
145       DPRINT( "Failing IRP: St0 = %2x, St1 = %2x, St2 = %2x\n",
146               ControllerExtension->St0,
147               ControllerExtension->St1,
148               ControllerExtension->St2 );
149       for(;;);
150       IoCompleteRequest( Irp, 0 );
151       IoFreeController( Controller );
152       return;
153     }
154   // don't forget to flush the buffers
155   IoFlushAdapterBuffers( ControllerExtension->AdapterObject,
156                          ControllerExtension->Irp->MdlAddress,
157                          ControllerExtension->MapRegisterBase,
158                          ControllerExtension->Irp->Tail.Overlay.DriverContext[0],
159                          ControllerExtension->TransferLength,
160                          WriteToDevice );
161   DPRINT( "St0 = %2x, St1  %2x, St2 = %2x\n",
162           ControllerExtension->St0,
163           ControllerExtension->St1,
164           ControllerExtension->St2 );
165   // update buffer info
166   Stk->Parameters.Read.ByteOffset.u.LowPart += ControllerExtension->TransferLength;
167   Stk->Parameters.Read.Length -= ControllerExtension->TransferLength;
168   // drivercontext used for current va
169   (DWORD)ControllerExtension->Irp->Tail.Overlay.DriverContext[0] += ControllerExtension->TransferLength;
170                          
171   DPRINT( "First dword: %x\n", *((DWORD *)ControllerExtension->MapRegisterBase) )
172
173   // if there is more IO to be done, restart execute routine to issue next read
174   if( Stk->Parameters.Read.Length )
175     {
176       if( FloppyExecuteReadWrite( DeviceObject,
177                                   Irp,
178                                   ControllerExtension->MapRegisterBase,
179                                   Irp ) == DeallocateObject )
180         IoFreeController( Controller );
181     }
182   else {
183     IoFreeController( Controller );
184     // otherwise, complete the Irp
185     IoCompleteRequest( Irp, 0 );
186   }
187 }
188
189 VOID STDCALL
190 FloppyDpcDetectMedia(PKDPC Dpc,
191                      PDEVICE_OBJECT DeviceObject,
192                      PIRP Irp,
193                      PVOID Context)
194 {
195   PCONTROLLER_OBJECT Controller = (PCONTROLLER_OBJECT)Context;
196   PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension;
197   // If the read ID failed, fail the irp
198   if( ControllerExtension->St1 != 0 )
199     {
200       DPRINT1( "Read ID failed: ST1 = %2x\n", ControllerExtension->St1 );
201       Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
202       IoCompleteRequest( Irp, 0 );
203       return;
204     }
205   // set media type, and restart the IRP from the beginning
206   ((PFLOPPY_DEVICE_EXTENSION)ControllerExtension->Device->DeviceExtension)->MediaType = 0;
207   DPRINT( "Media detected, restarting IRP\n" );
208   // don't forget to free the controller so that the now queued routine may execute
209   IoFreeController( Controller );
210
211   IoAllocateController( Controller,
212                         DeviceObject,
213                         FloppyExecuteReadWrite,
214                         Irp );
215 }