Use free Windows DDK and compile with latest MinGW releases.
[reactos.git] / reactos / drivers / dd / floppy / floppy.c
1 /*
2 * FLOPPY.C - NEC-765/8272A floppy device driver
3 * written by Rex Jolliff
4 * with help from various other sources, including but not limited to:
5 * Art Baker's NT Device Driver Book, Linux Source, and the internet.
6 *
7 * Modification History:
8 * 08/19/98 RJJ Created.
9 * 01/31/01 PJS Heavy rewrite, most of code thrown out
10 *
11 * To do:
12 * FIXME: get it working
13 * FIXME: add support for DMA hardware
14 * FIXME: should add support for floppy tape/zip devices
15 */
16
17 #include <ddk/ntddk.h>
18 #include <ddk/ntdddisk.h>
19
20 #include "floppy.h"
21 #define NDEBUG
22 #include <debug.h>
23
24
25 FLOPPY_CONTROLLER_PARAMETERS ControllerParameters[FLOPPY_MAX_CONTROLLERS] =
26 {
27 {0x03f0, 6, 6, 2, 6, LevelSensitive, 0xffff}
28 // {0x0370, 6, 6, 6, LevelSensitive, 0xffff},
29 };
30
31 const FLOPPY_MEDIA_TYPE MediaTypes[] = {
32 { 0x02, 80, 2, 18, 512 },
33 { 0, 0, 0, 0, 0 } };
34
35
36 static BOOLEAN
37 FloppyCreateController(PDRIVER_OBJECT DriverObject,
38 PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
39 int Index)
40 {
41 PCONTROLLER_OBJECT ControllerObject;
42 PFLOPPY_CONTROLLER_EXTENSION ControllerExtension;
43 PFLOPPY_DEVICE_EXTENSION DeviceExtension;
44 UNICODE_STRING DeviceName;
45 NTSTATUS Status;
46 PDEVICE_OBJECT DeviceObject;
47 PCONFIGURATION_INFORMATION ConfigInfo;
48 LARGE_INTEGER Timeout;
49 BYTE Byte;
50 int c;
51 PCONFIGURATION_INFORMATION Config;
52 DEVICE_DESCRIPTION DeviceDescription;
53 ULONG MaxMapRegs;
54
55 /* FIXME: Register port ranges and interrupts with HAL */
56
57 /* Create controller object for FDC */
58 ControllerObject = IoCreateController(sizeof(FLOPPY_CONTROLLER_EXTENSION));
59 if (ControllerObject == NULL)
60 {
61 DPRINT("Could not create controller object for controller %d\n",
62 Index);
63 return FALSE;
64 }
65
66 /* FIXME: fill out controller data */
67 ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)
68 ControllerObject->ControllerExtension;
69 ControllerExtension->Number = Index;
70 ControllerExtension->PortBase = ControllerParameters->PortBase;
71 ControllerExtension->Vector = ControllerParameters->Vector;
72 KeInitializeEvent( &ControllerExtension->Event, SynchronizationEvent, FALSE );
73 ControllerExtension->Device = 0; // no active device
74 ControllerExtension->Irp = 0; // no active IRP
75 /* Initialize the spin lock in the controller extension */
76 KeInitializeSpinLock(&ControllerExtension->SpinLock);
77 ControllerExtension->IsrState = FloppyIsrDetect;
78 ControllerExtension->DpcState = FloppyDpcDetect;
79
80 /* Register an interrupt handler for this controller */
81 Status = IoConnectInterrupt(&ControllerExtension->Interrupt,
82 FloppyIsr,
83 ControllerObject,
84 &ControllerExtension->SpinLock,
85 ControllerExtension->Vector,
86 ControllerParameters->IrqL,
87 ControllerParameters->SynchronizeIrqL,
88 ControllerParameters->InterruptMode,
89 FALSE,
90 ControllerParameters->Affinity,
91 FALSE);
92 if (!NT_SUCCESS(Status))
93 {
94 DPRINT("Could not Connect Interrupt %d\n",
95 ControllerExtension->Vector);
96 goto controllercleanup;
97 }
98
99
100 /* setup DMA stuff for controller */
101 DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
102 DeviceDescription.Master = FALSE;
103 DeviceDescription.ScatterGather = FALSE;
104 DeviceDescription.AutoInitialize = FALSE;
105 DeviceDescription.Dma32BitAddresses = FALSE;
106 DeviceDescription.DmaChannel = ControllerParameters->DmaChannel;
107 DeviceDescription.InterfaceType = Isa;
108 // DeviceDescription.DmaWidth = Width8Bits;
109 ControllerExtension->AdapterObject = HalGetAdapter( &DeviceDescription, &MaxMapRegs );
110 if( ControllerExtension->AdapterObject == NULL )
111 {
112 DPRINT1( "Could not get adapter object\n" );
113 goto interruptcleanup;
114 }
115
116 #if 0
117 /* Check for each possible drive and create devices for them */
118 for (DriveIdx = 0; DriveIdx < FLOPPY_MAX_DRIVES; DriveIdx++)
119 {
120 /* FIXME: try to identify the drive */
121 /* FIXME: create a device if it's there */
122 }
123 #endif
124
125 /* FIXME: Let's assume one drive and one controller for the moment */
126 RtlInitUnicodeString(&DeviceName, L"\\Device\\Floppy0");
127 Status = IoCreateDevice(DriverObject,
128 sizeof(FLOPPY_DEVICE_EXTENSION),
129 &DeviceName,
130 FILE_DEVICE_DISK,
131 FILE_REMOVABLE_MEDIA | FILE_FLOPPY_DISKETTE,
132 FALSE,
133 &DeviceObject);
134 if (!NT_SUCCESS(Status))
135 {
136 goto interruptcleanup;
137 }
138 DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
139 DeviceExtension->DriveSelect = 0;
140 DeviceExtension->Controller = ControllerObject;
141 DeviceExtension->MediaType = ~0;
142 ControllerExtension->MotorOn = ~0;
143 // set up DPC
144 ControllerExtension->Device = DeviceObject;
145 KeInitializeDpc( &ControllerExtension->MotorSpinupDpc,
146 FloppyMotorSpinupDpc,
147 ControllerObject );
148 KeInitializeDpc( &ControllerExtension->MotorSpindownDpc,
149 FloppyMotorSpindownDpc,
150 ControllerObject );
151 KeInitializeTimer( &ControllerExtension->SpinupTimer );
152 IoInitializeDpcRequest( DeviceObject, FloppyDpc );
153 // reset controller and wait for interrupt
154 DPRINT( "Controller Off\n" );
155 FloppyWriteDOR( ControllerExtension->PortBase, 0 );
156 // let controller reset for at least FLOPPY_RESET_TIME
157 KeStallExecutionProcessor( FLOPPY_RESET_TIME );
158 DPRINT( "Controller On\n" );
159 FloppyWriteDOR( ControllerExtension->PortBase, FLOPPY_DOR_ENABLE | FLOPPY_DOR_DMA );
160 // wait for interrupt now
161 Timeout.QuadPart = -10000000;
162 Status = KeWaitForSingleObject( &ControllerExtension->Event,
163 Executive,
164 KernelMode,
165 FALSE,
166 &Timeout );
167 if( Status != STATUS_WAIT_0 )
168 {
169 DPRINT1( "Error: KeWaitForSingleObject returned: %x\n", Status );
170 goto devicecleanup;
171 }
172 // set for high speed mode
173 // FloppyWriteCCNTL( ControllerExtension->PortBase, FLOPPY_CCNTL_1MBIT );
174
175 // ok, so we have an FDC, now check for drives
176 // aparently the sense drive status command does not work on any FDC I can find
177 // so instead we will just have to assume a 1.44 meg 3.5 inch floppy. At some
178 // point we should get the bios disk parameters passed in to the kernel at boot
179 // and stored in the HARDWARE registry key for us to pick up here.
180
181 // turn on motor, wait for spinup time, and recalibrate the drive
182 FloppyWriteDOR( ControllerExtension->PortBase, FLOPPY_DRIVE0_ON );
183 Timeout.QuadPart = FLOPPY_MOTOR_SPINUP_TIME;
184 KeDelayExecutionThread( KernelMode, FALSE, &Timeout );
185 DPRINT( "MSTAT: %2x\n", FloppyReadMSTAT( ControllerExtension->PortBase ) );
186 FloppyWriteDATA( ControllerExtension->PortBase, FLOPPY_CMD_RECAL );
187 DPRINT( "MSTAT: %2x\n", FloppyReadMSTAT( ControllerExtension->PortBase ) );
188 KeStallExecutionProcessor( 10000 );
189 FloppyWriteDATA( ControllerExtension->PortBase, 0 ); // drive select
190 Timeout.QuadPart = FLOPPY_RECAL_TIMEOUT;
191 Status = KeWaitForSingleObject( &ControllerExtension->Event,
192 Executive,
193 KernelMode,
194 FALSE,
195 &Timeout );
196 if( Status != STATUS_WAIT_0 )
197 {
198 DPRINT1( "Error: KeWaitForSingleObject returned: %x\n", Status );
199 goto devicecleanup;
200 }
201 if( ControllerExtension->St0 != FLOPPY_ST0_SEEKGD )
202 {
203 DbgPrint( "Floppy: error recalibrating drive, ST0: %2x\n", (DWORD)ControllerExtension->St0 );
204 goto interruptcleanup;
205 }
206 DeviceExtension->Cyl = 0;
207 // drive is good, and it is now on track 0, turn off the motor
208 FloppyWriteDOR( ControllerExtension->PortBase, FLOPPY_DOR_ENABLE | FLOPPY_DOR_DMA );
209 /* Initialize the device */
210 DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
211 DeviceObject->AlignmentRequirement = FILE_512_BYTE_ALIGNMENT;
212 // change state machine, no interrupt expected
213 ControllerExtension->IsrState = FloppyIsrUnexpected;
214 Config = IoGetConfigurationInformation();
215 Config->FloppyCount++;
216 // call IoAllocateAdapterChannel, and wait for execution routine to be given the channel
217 CHECKPOINT;
218 Status = IoAllocateAdapterChannel( ControllerExtension->AdapterObject,
219 DeviceObject,
220 0x3000/PAGE_SIZE, // max track size is 12k
221 FloppyAdapterControl,
222 ControllerExtension );
223 if( !NT_SUCCESS( Status ) )
224 {
225 DPRINT1( "Error: IoAllocateAdapterChannel returned %x\n", Status );
226 goto interruptcleanup;
227 }
228 CHECKPOINT;
229 Status = KeWaitForSingleObject( &ControllerExtension->Event,
230 Executive,
231 KernelMode,
232 FALSE,
233 &Timeout );
234 CHECKPOINT;
235 if( Status != STATUS_WAIT_0 )
236 {
237 DPRINT1( "Error: KeWaitForSingleObject returned: %x\n", Status );
238 goto interruptcleanup;
239 }
240 // Ok, we own the adapter object, from now on we can just IoMapTransfer, and not
241 // bother releasing the adapter ever.
242
243 DPRINT( "Floppy drive initialized\n" );
244 return TRUE;
245
246 devicecleanup:
247 IoDeleteDevice( DeviceObject );
248 interruptcleanup:
249 IoDisconnectInterrupt(ControllerExtension->Interrupt);
250 controllercleanup:
251 // turn off controller
252 FloppyWriteDOR( ControllerExtension->PortBase, 0 );
253 IoDeleteController(ControllerObject);
254 for(;;);
255 return FALSE;
256 }
257
258 IO_ALLOCATION_ACTION STDCALL
259 FloppyExecuteSpindown(PDEVICE_OBJECT DeviceObject,
260 PIRP Irp,
261 PVOID MapRegisterbase,
262 PVOID Context)
263 {
264 PFLOPPY_CONTROLLER_EXTENSION ControllerExtension= (PFLOPPY_CONTROLLER_EXTENSION)Context;
265
266 // turn off motor, and return
267 DPRINT( "Spinning down motor\n" );
268 ControllerExtension->MotorOn = ~0;
269 FloppyWriteDOR( ControllerExtension->PortBase,
270 FLOPPY_DOR_ENABLE | FLOPPY_DOR_DMA );
271 return DeallocateObject;
272 }
273
274 IO_ALLOCATION_ACTION STDCALL
275 FloppyExecuteReadWrite(PDEVICE_OBJECT DeviceObject,
276 PIRP Irp,
277 PVOID MapRegisterbase,
278 PVOID Context)
279 {
280 PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
281 PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)DeviceExtension->Controller->ControllerExtension;
282 LARGE_INTEGER Timeout;
283 BOOLEAN WriteToDevice;
284 DWORD Cyl, Sector, Head;
285 PIO_STACK_LOCATION Stk;
286 DWORD Length;
287
288 ControllerExtension->Irp = Irp = (PIRP)Context;
289 Stk = IoGetCurrentIrpStackLocation( Irp );
290 ControllerExtension->Device = DeviceObject;
291 Timeout.QuadPart = FLOPPY_MOTOR_SPINUP_TIME;
292 DPRINT( "FloppyExecuteReadWrite()\n" );
293 CHECKPOINT;
294 WriteToDevice = Stk->MajorFunction == IRP_MJ_WRITE ? TRUE : FALSE;
295 // verify drive is spun up and selected
296 if( ControllerExtension->MotorOn != DeviceExtension->DriveSelect )
297 {
298 // turn on and select drive, and allow it to spin up
299 // FloppyMotorSpinupDpc will restart this operation once motor is spun up
300 DPRINT( "Motor not on, turning it on now\n" );
301 FloppyWriteDOR( ControllerExtension->PortBase,
302 DeviceExtension->DriveSelect ? FLOPPY_DRIVE1_ON : FLOPPY_DRIVE0_ON );
303 // cancel possible spindown timer first
304 KeCancelTimer( &ControllerExtension->SpinupTimer );
305 KeSetTimerEx( &ControllerExtension->SpinupTimer,
306 Timeout,
307 0,
308 &ControllerExtension->MotorSpinupDpc );
309 return KeepObject;
310 }
311 else {
312 Timeout.QuadPart = FLOPPY_MOTOR_SPINDOWN_TIME;
313 // motor is already spinning, so reset the spindown timer
314 KeCancelTimer( &ControllerExtension->SpinupTimer );
315 KeSetTimer( &ControllerExtension->SpinupTimer,
316 Timeout,
317 &ControllerExtension->MotorSpindownDpc );
318 }
319 // verify media content
320 if( FloppyReadDIR( ControllerExtension->PortBase ) & FLOPPY_DI_DSKCHNG )
321 {
322 // No disk is in the drive
323 DPRINT( "No disk is in the drive\n" );
324 Irp->IoStatus.Status = STATUS_NO_MEDIA;
325 Irp->IoStatus.Information = 0;
326 IoCompleteRequest( Irp, 0 );
327 return DeallocateObject;
328 }
329 if( DeviceExtension->MediaType == ~0 )
330 {
331 // media is in disk, but we have not yet detected what kind it is,
332 // so detect it now
333 // First, we need to recalibrate the drive though
334 ControllerExtension->IsrState = FloppyIsrRecal;
335 DPRINT( "Recalibrating drive\n" );
336 KeStallExecutionProcessor( 1000 );
337 FloppyWriteDATA( ControllerExtension->PortBase, FLOPPY_CMD_RECAL );
338 KeStallExecutionProcessor( 1000 );
339 FloppyWriteDATA( ControllerExtension->PortBase, DeviceExtension->DriveSelect );
340 return KeepObject;
341 }
342 // looks like we have media in the drive.... do the read
343 // first, calculate geometry for read
344 Sector = Stk->Parameters.Read.ByteOffset.u.LowPart / MediaTypes[DeviceExtension->MediaType].BytesPerSector;
345 // absolute sector right now
346 Cyl = Sector / MediaTypes[DeviceExtension->MediaType].SectorsPerTrack;
347 DPRINT( "Sector = %x, Offset = %x, Cyl = %x, Heads = %x MediaType = %x\n", Sector, Stk->Parameters.Read.ByteOffset.u.LowPart, (DWORD)Cyl, (DWORD)MediaTypes[DeviceExtension->MediaType].Heads, (DWORD)DeviceExtension->MediaType );
348 Head = Cyl % MediaTypes[DeviceExtension->MediaType].Heads;
349 DPRINT( "Head = %2x\n", Head );
350 // convert absolute cyl to relative
351 Cyl /= MediaTypes[DeviceExtension->MediaType].Heads;
352 // convert absolute sector to relative
353 Sector %= MediaTypes[DeviceExtension->MediaType].SectorsPerTrack;
354 Sector++; // track relative sector numbers are 1 based, not 0 based
355 DPRINT( "Cyl = %2x, Head = %2x, Sector = %2x\n", Cyl, Head, Sector );
356
357 // seek if we need to seek
358 if( DeviceExtension->Cyl != Cyl )
359 {
360 DPRINT( "Seeking...\n" );
361 ControllerExtension->IsrState = FloppyIsrDetect;
362 ControllerExtension->DpcState = FloppySeekDpc;
363 FloppyWriteDATA( ControllerExtension->PortBase, FLOPPY_CMD_SEEK );
364 KeStallExecutionProcessor( 100 );
365 FloppyWriteDATA( ControllerExtension->PortBase, DeviceExtension->DriveSelect );
366 KeStallExecutionProcessor( 100 );
367 FloppyWriteDATA( ControllerExtension->PortBase, Cyl );
368 return KeepObject;
369 }
370 //set up DMA and issue read command
371 Length = MediaTypes[DeviceExtension->MediaType].SectorsPerTrack - Sector + 1;
372 // number of sectors untill end of track
373 Length *= 512; // convert to bytes
374 if( Length > Stk->Parameters.Read.Length )
375 Length = Stk->Parameters.Read.Length;
376 DPRINT( "Sector: %d, Length: %d\n", Sector, Length );
377 ControllerExtension->TransferLength = Length;
378 IoMapTransfer( ControllerExtension->AdapterObject,
379 Irp->MdlAddress,
380 ControllerExtension->MapRegisterBase,
381 Irp->Tail.Overlay.DriverContext[0], // current va
382 &Length,
383 WriteToDevice );
384 ControllerExtension->IsrState = FloppyIsrReadWrite;
385 ControllerExtension->DpcState = FloppyDpcReadWrite;
386 CHECKPOINT;
387 FloppyWriteDATA( ControllerExtension->PortBase, WriteToDevice ? FLOPPY_CMD_WRITE : FLOPPY_CMD_READ );
388 KeStallExecutionProcessor( 100 );
389 FloppyWriteDATA( ControllerExtension->PortBase, ( Head << 2 ) | DeviceExtension->DriveSelect );
390 KeStallExecutionProcessor( 100 );
391 FloppyWriteDATA( ControllerExtension->PortBase, Cyl );
392 KeStallExecutionProcessor( 100 );
393 FloppyWriteDATA( ControllerExtension->PortBase, Head );
394 KeStallExecutionProcessor( 100 );
395 FloppyWriteDATA( ControllerExtension->PortBase, Sector );
396 KeStallExecutionProcessor( 100 );
397 FloppyWriteDATA( ControllerExtension->PortBase, MediaTypes[DeviceExtension->MediaType].SectorSizeCode );
398 KeStallExecutionProcessor( 100 );
399 FloppyWriteDATA( ControllerExtension->PortBase, MediaTypes[DeviceExtension->MediaType].SectorsPerTrack );
400 KeStallExecutionProcessor( 100 );
401 FloppyWriteDATA( ControllerExtension->PortBase, 0 );
402 KeStallExecutionProcessor( 100 );
403 FloppyWriteDATA( ControllerExtension->PortBase, 0xFF );
404 CHECKPOINT;
405 // eventually, the FDC will interrupt and we will read results then
406 return KeepObject;
407 }
408
409 NTSTATUS STDCALL
410 FloppyDispatchOpenClose(PDEVICE_OBJECT DeviceObject,
411 PIRP Irp)
412 {
413 DPRINT("FloppyDispatchOpenClose\n");
414 return STATUS_SUCCESS;
415 }
416
417 NTSTATUS STDCALL
418 FloppyDispatchReadWrite(PDEVICE_OBJECT DeviceObject,
419 PIRP Irp)
420 {
421 PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
422 PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)DeviceExtension->Controller->ControllerExtension;
423 PIO_STACK_LOCATION Stk = IoGetCurrentIrpStackLocation( Irp );
424 KIRQL oldlvl;
425
426 if( Stk->Parameters.Read.ByteOffset.u.HighPart )
427 {
428 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
429 Irp->IoStatus.Information = 0;
430 IoCompleteRequest( Irp, 1 );
431 return STATUS_INVALID_PARAMETER;
432 }
433 // store currentva in drivercontext
434 Irp->Tail.Overlay.DriverContext[0] = MmGetMdlVirtualAddress( Irp->MdlAddress );
435 DPRINT( "FloppyDispatchReadWrite: offset = %x, length = %x, va = %x\n",
436 Stk->Parameters.Read.ByteOffset.u.LowPart,
437 Stk->Parameters.Read.Length,
438 Irp->Tail.Overlay.DriverContext[0] );
439 // Queue IRP
440 Irp->IoStatus.Status = STATUS_SUCCESS;
441 Irp->IoStatus.Information = Stk->Parameters.Read.Length;
442 IoMarkIrpPending( Irp );
443 KeRaiseIrql( DISPATCH_LEVEL, &oldlvl );
444 IoAllocateController( ((PFLOPPY_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Controller,
445 DeviceObject,
446 FloppyExecuteReadWrite,
447 Irp );
448 KeLowerIrql( oldlvl );
449 DPRINT( "oldlvl = %x\n", oldlvl );
450 return STATUS_PENDING;
451 }
452
453 IO_ALLOCATION_ACTION STDCALL
454 FloppyAdapterControl(PDEVICE_OBJECT DeviceObject,
455 PIRP Irp,
456 PVOID MapRegisterBase,
457 PVOID Context)
458 {
459 PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Context;
460
461 // just set the event, and return KeepObject
462 CHECKPOINT;
463 ControllerExtension->MapRegisterBase = MapRegisterBase;
464 KeSetEvent( &ControllerExtension->Event, 0, FALSE );
465 return KeepObject;
466 }
467
468 NTSTATUS STDCALL
469 FloppyDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
470 PIRP Irp)
471 {
472 PIO_STACK_LOCATION IrpStack;
473 ULONG ControlCode, InputLength, OutputLength;
474 NTSTATUS Status;
475
476 DPRINT("FloppyDispatchDeviceControl\n");
477
478 IrpStack = IoGetCurrentIrpStackLocation(Irp);
479 ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
480 InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
481 OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
482
483 switch (ControlCode)
484 {
485 case IOCTL_DISK_GET_DRIVE_GEOMETRY:
486 if (OutputLength < sizeof(DISK_GEOMETRY))
487 {
488 Status = STATUS_INVALID_PARAMETER;
489 }
490 else
491 {
492 PDISK_GEOMETRY Geometry = Irp->AssociatedIrp.SystemBuffer;
493 // FIXME: read the first sector of the diskette
494 Geometry->MediaType = F3_1Pt44_512;
495 Geometry->Cylinders.QuadPart = 80;
496 Geometry->TracksPerCylinder = 2 * 18;
497 Geometry->SectorsPerTrack = 18;
498 Geometry->BytesPerSector = 512;
499 Status = STATUS_SUCCESS;
500 Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
501 }
502 break;
503 default:
504 Status = STATUS_INVALID_DEVICE_REQUEST;
505 }
506 Irp->IoStatus.Status = Status;
507 IoCompleteRequest(Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
508 return Status;
509 }
510
511 /* ModuleEntry
512 *
513 * DESCRIPTION:
514 * This function initializes the driver, locates and claims
515 * hardware resources, and creates various NT objects needed
516 * to process I/O requests.
517 *
518 * RUN LEVEL:
519 * PASSIVE_LEVEL
520 *
521 * ARGUMENTS:
522 * IN PDRIVER_OBJECT DriverObject System allocated Driver Object
523 * for this driver
524 * IN PUNICODE_STRING RegistryPath Name of registry driver service
525 * key
526 *
527 * RETURNS:
528 * NTSTATUS
529 */
530 NTSTATUS STDCALL
531 DriverEntry(IN PDRIVER_OBJECT DriverObject,
532 IN PUNICODE_STRING RegistryPath)
533 {
534 DPRINT("Floppy driver\n");
535
536 /* Export other driver entry points... */
537 DriverObject->MajorFunction[IRP_MJ_CREATE] = FloppyDispatchOpenClose;
538 DriverObject->MajorFunction[IRP_MJ_CLOSE] = FloppyDispatchOpenClose;
539 DriverObject->MajorFunction[IRP_MJ_READ] = FloppyDispatchReadWrite;
540 DriverObject->MajorFunction[IRP_MJ_WRITE] = FloppyDispatchReadWrite;
541 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
542 FloppyDispatchDeviceControl;
543
544 /* Try to detect controller and abort if it fails */
545 if (!FloppyCreateController(DriverObject,
546 &ControllerParameters[0],
547 0))
548 {
549 DPRINT("Could not find floppy controller\n");
550 return STATUS_NO_SUCH_DEVICE;
551 }
552
553 return STATUS_SUCCESS;
554 }
555
556 /* EOF */
557