ReactOS  0.4.15-dev-1207-g698a8e6
readwrite.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

NTSTATUS NTAPI ReadWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
VOID NTAPI ReadWritePassive (PDRIVE_INFO DriveInfo, PIRP Irp)
 
NTSTATUS NTAPI RWDetermineMediaType (PDRIVE_INFO DriveInfo, BOOLEAN OneShot)
 

Variables

DRIVER_DISPATCH ReadWrite
 

Function Documentation

◆ ReadWrite()

NTSTATUS NTAPI ReadWrite ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 90 of file readwrite.c.

105 {
106  TRACE_(FLOPPY, "ReadWrite called\n");
107 
109  ASSERT(Irp);
110 
111  if(!Irp->MdlAddress)
112  {
113  WARN_(FLOPPY, "ReadWrite(): MDL not found in IRP - Completing with STATUS_INVALID_PARAMETER\n");
114  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
115  Irp->IoStatus.Information = 0;
118  }
119 
120  /*
121  * Queue the irp to the thread.
122  * The de-queue thread will look in DriverContext[0] for the Device Object.
123  */
124  Irp->Tail.Overlay.DriverContext[0] = DeviceObject;
126 
127  return STATUS_PENDING;
128 }
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTKERNELAPI VOID NTAPI IoCsqInsertIrp(_Inout_ PIO_CSQ Csq, _Inout_ PIRP Irp, _Out_opt_ PIO_CSQ_IRP_CONTEXT Context)
Insert an IRP into the CSQ.
Definition: csq.c:177
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_(x)
Definition: compat.h:76
#define STATUS_PENDING
Definition: ntstatus.h:82
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
IO_CSQ Csq
Definition: csqrtns.c:46
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define WARN_(ch,...)
Definition: debug.h:157

◆ ReadWritePassive()

VOID NTAPI ReadWritePassive ( PDRIVE_INFO  DriveInfo,
PIRP  Irp 
)

Definition at line 403 of file readwrite.c.

431 {
435  ULONG Length;
436  ULONG DiskByteOffset;
437  KIRQL OldIrql;
439  BOOLEAN DiskChanged;
440  ULONG_PTR TransferByteOffset;
441  UCHAR Gap;
442 
443  PAGED_CODE();
444 
445  TRACE_(FLOPPY, "ReadWritePassive called to %s 0x%x bytes from offset 0x%x\n",
446  (Stack->MajorFunction == IRP_MJ_READ ? "read" : "write"),
447  (Stack->MajorFunction == IRP_MJ_READ ? Stack->Parameters.Read.Length : Stack->Parameters.Write.Length),
448  (Stack->MajorFunction == IRP_MJ_READ ? Stack->Parameters.Read.ByteOffset.u.LowPart :
449  Stack->Parameters.Write.ByteOffset.u.LowPart));
450 
451  /* Default return codes */
452  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
453  Irp->IoStatus.Information = 0;
454 
455  /*
456  * Check to see if the volume needs to be verified. If so,
457  * we can get out of here quickly.
458  */
460  {
461  INFO_(FLOPPY, "ReadWritePassive(): DO_VERIFY_VOLUME set; Completing with STATUS_VERIFY_REQUIRED\n");
462  Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
464  return;
465  }
466 
467  /*
468  * Check the change line, and if it's set, return
469  */
470  StartMotor(DriveInfo);
471  if(HwDiskChanged(DeviceObject->DeviceExtension, &DiskChanged) != STATUS_SUCCESS)
472  {
473  WARN_(FLOPPY, "ReadWritePassive(): unable to detect disk change; Completing with STATUS_UNSUCCESSFUL\n");
475  StopMotor(DriveInfo->ControllerInfo);
476  return;
477  }
478 
479  if(DiskChanged)
480  {
481  INFO_(FLOPPY, "ReadWritePhase1(): signalling media changed; Completing with STATUS_MEDIA_CHANGED\n");
482 
483  /* The following call sets IoStatus.Status and IoStatus.Information */
485 
486  /*
487  * Guessing at something... see ioctl.c for more info
488  */
490  Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
491 
493  StopMotor(DriveInfo->ControllerInfo);
494  return;
495  }
496 
497  /*
498  * Figure out the media type, if we don't know it already
499  */
500  if(DriveInfo->DiskGeometry.MediaType == Unknown)
501  {
502  if(RWDetermineMediaType(DriveInfo, FALSE) != STATUS_SUCCESS)
503  {
504  WARN_(FLOPPY, "ReadWritePassive(): unable to determine media type; completing with STATUS_UNSUCCESSFUL\n");
506  StopMotor(DriveInfo->ControllerInfo);
507  return;
508  }
509 
510  if(DriveInfo->DiskGeometry.MediaType == Unknown)
511  {
512  WARN_(FLOPPY, "ReadWritePassive(): Unknown media in drive; completing with STATUS_UNRECOGNIZED_MEDIA\n");
513  Irp->IoStatus.Status = STATUS_UNRECOGNIZED_MEDIA;
515  StopMotor(DriveInfo->ControllerInfo);
516  return;
517  }
518  }
519 
520  /* Set up parameters for read or write */
521  if(Stack->MajorFunction == IRP_MJ_READ)
522  {
523  Length = Stack->Parameters.Read.Length;
524  DiskByteOffset = Stack->Parameters.Read.ByteOffset.u.LowPart;
526  }
527  else
528  {
529  Length = Stack->Parameters.Write.Length;
530  DiskByteOffset = Stack->Parameters.Write.ByteOffset.u.LowPart;
532  }
533 
534  /*
535  * FIXME:
536  * FloppyDeviceData.ReadWriteGapLength specify the value for the physical drive.
537  * We should set this value depend on the format of the inserted disk and possible
538  * depend on the request (read or write). A value of 0 results in one rotation
539  * between the sectors (7.2sec for reading a track).
540  */
541  Gap = DriveInfo->FloppyDeviceData.ReadWriteGapLength;
542 
543  /*
544  * Set up DMA transfer
545  *
546  * This is as good of a place as any to document something that used to confuse me
547  * greatly (and I even wrote some of the kernel's DMA code, so if it confuses me, it
548  * probably confuses at least a couple of other people too).
549  *
550  * MmGetMdlVirtualAddress() returns the virtual address, as mapped in the buffer's original
551  * process context, of the MDL. In other words: say you start with a buffer at address X, then
552  * you build an MDL out of that buffer called Mdl. If you call MmGetMdlVirtualAddress(Mdl), it
553  * will return X.
554  *
555  * There are two parameters that the function looks at to produce X again, given the MDL: the
556  * first is the StartVa, which is the base virtual address of the page that the buffer starts
557  * in. If your buffer's virtual address is 0x12345678, StartVa will be 0x12345000, assuming 4K pages
558  * (which is (almost) always the case on x86). Note well: this address is only valid in the
559  * process context that you initially built the MDL from. The physical pages that make up
560  * the MDL might perhaps be mapped in other process contexts too (or even in the system space,
561  * above 0x80000000 (default; 0xc0000000 on current ReactOS or /3GB Windows)), but it will
562  * (possibly) be mapped at a different address.
563  *
564  * The second parameter is the ByteOffset. Given an original buffer address of 0x12345678,
565  * the ByteOffset would be 0x678. Because MDLs can only describe full pages (and therefore
566  * StartVa always points to the start address of a page), the ByteOffset must be used to
567  * find the real start of the buffer.
568  *
569  * In general, if you add the StartVa and ByteOffset together, you get back your original
570  * buffer pointer, which you are free to use if you're sure you're in the right process
571  * context. You could tell by accessing the (hidden and not-to-be-used) Process member of
572  * the MDL, but in general, if you have to ask whether or not you are in the right context,
573  * then you shouldn't be using this address for anything anyway. There are also security implications
574  * (big ones, really, I wouldn't kid about this) to directly accessing a user's buffer by VA, so
575  * Don't Do That.
576  *
577  * There is a somewhat weird but very common use of the virtual address associated with a MDL
578  * that pops up often in the context of DMA. DMA APIs (particularly MapTransfer()) need to
579  * know where the memory is that they should DMA into and out of. This memory is described
580  * by a MDL. The controller eventually needs to know a physical address on the host side,
581  * which is generally a 32-bit linear address (on x86), and not just a page address. Therefore,
582  * the DMA APIs look at the ByteOffset field of the MDL to reconstruct the real address that
583  * should be programmed into the DMA controller.
584  *
585  * It is often the case that a transfer needs to be broken down over more than one DMA operation,
586  * particularly when it is a big transfer and the HAL doesn't give you enough map registers
587  * to map the whole thing at once. Therefore, the APIs need a way to tell how far into the MDL
588  * they should look to transfer the next chunk of bytes. Now, Microsoft could have designed
589  * MapTransfer to take a "MDL offset" argument, starting with 0, for how far into the buffer to
590  * start, but it didn't. Instead, MapTransfer asks for the virtual address of the MDL as an "index" into
591  * the MDL. The way it computes how far into the page to start the transfer is by masking off all but
592  * the bottom 12 bits (on x86) of the number you supply as the CurrentVa and using *that* as the
593  * ByteOffset instead of the one in the MDL. (OK, this varies a bit by OS and version, but this
594  * is the effect).
595  *
596  * In other words, you get a number back from MmGetMdlVirtualAddress that represents the start of your
597  * buffer, and you pass it to the first MapTransfer call. Then, for each successive operation
598  * on the same buffer, you increment that address to point to the next spot in the MDL that
599  * you want to DMA to/from. The fact that the virtual address you're manipulating is probably not
600  * mapped into the process context that you're running in is irrelevant, since it's only being
601  * used to index into the MDL.
602  */
603 
604  /* Get map registers for DMA */
606  Status = IoAllocateAdapterChannel(DriveInfo->ControllerInfo->AdapterObject, DeviceObject,
607  DriveInfo->ControllerInfo->MapRegisters, MapRegisterCallback, DriveInfo->ControllerInfo);
609 
610  if(Status != STATUS_SUCCESS)
611  {
612  WARN_(FLOPPY, "ReadWritePassive(): unable allocate an adapter channel; completing with STATUS_UNSUCCESSFUL\n");
614  StopMotor(DriveInfo->ControllerInfo);
615  return ;
616  }
617 
618 
619  /*
620  * Read from (or write to) the device
621  *
622  * This has to be called in a loop, as you can only transfer data to/from a single track at
623  * a time.
624  */
625  TransferByteOffset = 0;
626  while(TransferByteOffset < Length)
627  {
628  UCHAR Cylinder;
629  UCHAR Head;
630  UCHAR StartSector;
631  ULONG CurrentTransferBytes;
632  UCHAR CurrentTransferSectors;
633 
634  INFO_(FLOPPY, "ReadWritePassive(): iterating in while (TransferByteOffset = 0x%x of 0x%x total) - allocating %d registers\n",
635  TransferByteOffset, Length, DriveInfo->ControllerInfo->MapRegisters);
636 
637  KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
638 
639  /*
640  * Compute starting CHS
641  */
642  if(RWComputeCHS(DriveInfo, DiskByteOffset+TransferByteOffset, &Cylinder, &Head, &StartSector) != STATUS_SUCCESS)
643  {
644  WARN_(FLOPPY, "ReadWritePassive(): unable to compute CHS; completing with STATUS_UNSUCCESSFUL\n");
645  RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
647  StopMotor(DriveInfo->ControllerInfo);
648  return;
649  }
650 
651  /*
652  * Seek to the right track
653  */
654  if(!DriveInfo->ControllerInfo->ImpliedSeeks)
655  {
656  if(RWSeekToCylinder(DriveInfo, Cylinder) != STATUS_SUCCESS)
657  {
658  WARN_(FLOPPY, "ReadWritePassive(): unable to seek; completing with STATUS_UNSUCCESSFUL\n");
659  RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
661  StopMotor(DriveInfo->ControllerInfo);
662  return ;
663  }
664  }
665 
666  /*
667  * Compute last sector
668  *
669  * We can only ask for a transfer up to the end of the track. Then we have to re-seek and do more.
670  * TODO: Support the MT bit
671  */
672  INFO_(FLOPPY, "ReadWritePassive(): computing number of sectors to transfer (StartSector 0x%x): ", StartSector);
673 
674  /* 1-based sector number */
675  if( (((DriveInfo->DiskGeometry.TracksPerCylinder - Head) * DriveInfo->DiskGeometry.SectorsPerTrack - StartSector) + 1 ) <
676  (Length - TransferByteOffset) / DriveInfo->DiskGeometry.BytesPerSector)
677  {
678  CurrentTransferSectors = (UCHAR)((DriveInfo->DiskGeometry.TracksPerCylinder - Head) * DriveInfo->DiskGeometry.SectorsPerTrack - StartSector) + 1;
679  }
680  else
681  {
682  CurrentTransferSectors = (UCHAR)((Length - TransferByteOffset) / DriveInfo->DiskGeometry.BytesPerSector);
683  }
684 
685  INFO_(FLOPPY, "0x%x\n", CurrentTransferSectors);
686 
687  CurrentTransferBytes = CurrentTransferSectors * DriveInfo->DiskGeometry.BytesPerSector;
688 
689  /*
690  * Adjust to map registers
691  * BUG: Does this take into account page crossings?
692  */
693  INFO_(FLOPPY, "ReadWritePassive(): Trying to transfer 0x%x bytes\n", CurrentTransferBytes);
694 
695  ASSERT(CurrentTransferBytes);
696 
697  if(BYTES_TO_PAGES(CurrentTransferBytes) > DriveInfo->ControllerInfo->MapRegisters)
698  {
699  CurrentTransferSectors = (UCHAR)((DriveInfo->ControllerInfo->MapRegisters * PAGE_SIZE) /
700  DriveInfo->DiskGeometry.BytesPerSector);
701 
702  CurrentTransferBytes = CurrentTransferSectors * DriveInfo->DiskGeometry.BytesPerSector;
703 
704  INFO_(FLOPPY, "ReadWritePassive: limiting transfer to 0x%x bytes (0x%x sectors) due to map registers\n",
705  CurrentTransferBytes, CurrentTransferSectors);
706  }
707 
708  /* set up this round's dma operation */
709  /* param 2 is ReadOperation --> opposite of WriteToDevice that IoMapTransfer takes. BAD MS. */
710  KeFlushIoBuffers(Irp->MdlAddress, !WriteToDevice, TRUE);
711 
712  IoMapTransfer(DriveInfo->ControllerInfo->AdapterObject, Irp->MdlAddress,
713  DriveInfo->ControllerInfo->MapRegisterBase,
714  (PVOID)((ULONG_PTR)MmGetMdlVirtualAddress(Irp->MdlAddress) + TransferByteOffset),
715  &CurrentTransferBytes, WriteToDevice);
716 
717  /*
718  * Read or Write
719  */
720  KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
721 
722  /* Issue the read/write command to the controller. Note that it expects the opposite of WriteToDevice. */
723  if(HwReadWriteData(DriveInfo->ControllerInfo, !WriteToDevice, DriveInfo->UnitNumber, Cylinder, Head, StartSector,
724  DriveInfo->BytesPerSectorCode, DriveInfo->DiskGeometry.SectorsPerTrack, Gap, 0xff) != STATUS_SUCCESS)
725  {
726  WARN_(FLOPPY, "ReadWritePassive(): HwReadWriteData returned failure; unable to read; completing with STATUS_UNSUCCESSFUL\n");
727  RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
729  StopMotor(DriveInfo->ControllerInfo);
730  return ;
731  }
732 
733  INFO_(FLOPPY, "ReadWritePassive(): HwReadWriteData returned -- waiting on event\n");
734 
735  /*
736  * At this point, we block and wait for an interrupt
737  * FIXME: this seems to take too long
738  */
740 
741  /* Read is complete; flush & free adapter channel */
742  IoFlushAdapterBuffers(DriveInfo->ControllerInfo->AdapterObject, Irp->MdlAddress,
743  DriveInfo->ControllerInfo->MapRegisterBase,
744  (PVOID)((ULONG_PTR)MmGetMdlVirtualAddress(Irp->MdlAddress) + TransferByteOffset),
745  CurrentTransferBytes, WriteToDevice);
746 
747  /* Read the results from the drive */
749  {
750  WARN_(FLOPPY, "ReadWritePassive(): HwReadWriteResult returned failure; unable to read; completing with STATUS_UNSUCCESSFUL\n");
751  HwDumpRegisters(DriveInfo->ControllerInfo);
752  RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
754  StopMotor(DriveInfo->ControllerInfo);
755  return ;
756  }
757 
758  TransferByteOffset += CurrentTransferBytes;
759  }
760 
761  RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
762 
763  /* That's all folks! */
764  INFO_(FLOPPY, "ReadWritePassive(): success; Completing with STATUS_SUCCESS\n");
765  Irp->IoStatus.Status = STATUS_SUCCESS;
766  Irp->IoStatus.Information = Length;
768  StopMotor(DriveInfo->ControllerInfo);
769 }
return
Definition: dirsup.c:529
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define INFO_(ch,...)
Definition: debug.h:159
#define MmGetMdlVirtualAddress(_Mdl)
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
PHYSICAL_ADDRESS NTAPI IoMapTransfer(IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN OUT PULONG Length, IN BOOLEAN WriteToDevice)
Definition: dma.c:144
LONG NTSTATUS
Definition: precomp.h:26
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
VOID NTAPI StartMotor(PDRIVE_INFO DriveInfo)
Definition: floppy.c:96
ULONG BytesPerSector
Definition: ntdddisk.h:442
ULONG TracksPerCylinder
Definition: ntdddisk.h:440
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
VOID NTAPI StopMotor(PCONTROLLER_INFO ControllerInfo)
Definition: floppy.c:135
struct _CONTROLLER_INFO * ControllerInfo
Definition: fdc.h:23
#define STATUS_UNRECOGNIZED_MEDIA
Definition: udferr_usr.h:142
NTSTATUS NTAPI HwReadWriteResult(PCONTROLLER_INFO ControllerInfo)
Definition: hardware.c:462
uint32_t ULONG_PTR
Definition: typedefs.h:65
UCHAR KIRQL
Definition: env_spec_w32.h:591
static VOID NTAPI RWFreeAdapterChannel(PADAPTER_OBJECT AdapterObject)
Definition: readwrite.c:132
PDEVICE_OBJECT DeviceObject
Definition: fdc.h:26
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
static NTSTATUS NTAPI RWSeekToCylinder(PDRIVE_INFO DriveInfo, UCHAR Cylinder)
Definition: readwrite.c:281
VOID NTAPI SignalMediaChanged(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: floppy.c:1090
static IO_ALLOCATION_ACTION NTAPI MapRegisterCallback(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID MapRegisterBase, PVOID Context)
Definition: readwrite.c:60
#define TRACE_(x)
Definition: compat.h:76
NTSTATUS NTAPI IoAllocateAdapterChannel(IN PADAPTER_OBJECT AdapterObject, IN PDEVICE_OBJECT DeviceObject, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context)
Definition: adapter.c:30
ULONG SectorsPerTrack
Definition: ntdddisk.h:441
BOOLEAN NTAPI IoFlushAdapterBuffers(IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN ULONG Length, IN BOOLEAN WriteToDevice)
Definition: dma.c:127
MEDIA_TYPE MediaType
Definition: ntdddisk.h:439
VOID NTAPI HwDumpRegisters(PCONTROLLER_INFO ControllerInfo)
Definition: hardware.c:1029
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define BYTES_TO_PAGES(Size)
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
CM_FLOPPY_DEVICE_DATA FloppyDeviceData
Definition: fdc.h:27
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define PAGE_SIZE
Definition: env_spec_w32.h:49
NTSTATUS NTAPI HwReadWriteData(PCONTROLLER_INFO ControllerInfo, BOOLEAN Read, UCHAR Unit, UCHAR Cylinder, UCHAR Head, UCHAR Sector, UCHAR BytesPerSector, UCHAR EndOfTrack, UCHAR Gap3Length, UCHAR DataLength)
Definition: hardware.c:322
DISK_GEOMETRY DiskGeometry
Definition: floppy.h:49
UCHAR UnitNumber
Definition: fdc.h:24
NTSTATUS NTAPI HwDiskChanged(PDRIVE_INFO DriveInfo, PBOOLEAN DiskChanged)
Definition: hardware.c:785
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN WriteToDevice
Definition: cdrom.h:989
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define KeFlushIoBuffers(_Mdl, _ReadOperation, _DmaOperation)
Definition: ke.h:170
static NTSTATUS NTAPI RWComputeCHS(PDRIVE_INFO IN DriveInfo, ULONG IN DiskByteOffset, PUCHAR OUT Cylinder, PUCHAR OUT Head, PUCHAR OUT Sector)
Definition: readwrite.c:346
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define IRP_MJ_READ
Definition: rdpdr.c:46
NTSTATUS NTAPI RWDetermineMediaType(PDRIVE_INFO DriveInfo, BOOLEAN OneShot)
Definition: readwrite.c:153
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
NTSTATUS NTAPI ResetChangeFlag(PDRIVE_INFO DriveInfo)
Definition: floppy.c:291
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define WARN_(ch,...)
Definition: debug.h:157
UCHAR BytesPerSectorCode
Definition: floppy.h:50
NTSTATUS NTAPI WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo, PLARGE_INTEGER Timeout)
Definition: floppy.c:163
#define PAGED_CODE()

Referenced by QueueThread().

◆ RWDetermineMediaType()

NTSTATUS NTAPI RWDetermineMediaType ( PDRIVE_INFO  DriveInfo,
BOOLEAN  OneShot 
)

Definition at line 153 of file readwrite.c.

169 {
170  UCHAR HeadLoadTime;
171  UCHAR HeadUnloadTime;
172  UCHAR StepRateTime;
174 
175  PAGED_CODE();
176 
177  TRACE_(FLOPPY, "RWDetermineMediaType called\n");
178 
179  /*
180  * This algorithm assumes that a 1.44MB floppy is in the drive. If it's not,
181  * it works backwards until the read works unless OneShot try is asked.
182  * Note that only 1.44 has been tested at all.
183  */
184 
185  Timeout.QuadPart = -10000000; /* 1 second. Is that enough? */
186 
187  do
188  {
189  int i;
191 
192  /* Program data rate */
194  {
195  WARN_(FLOPPY, "RWDetermineMediaType(): unable to set data rate\n");
196  return STATUS_UNSUCCESSFUL;
197  }
198 
199  /* Specify */
200  HeadLoadTime = SPECIFY_HLT_500K;
201  HeadUnloadTime = SPECIFY_HUT_500K;
202  StepRateTime = SPECIFY_SRT_500K;
203 
204  /* Don't disable DMA --> enable dma (dumb & confusing) */
205  if(HwSpecify(DriveInfo->ControllerInfo, HeadLoadTime, HeadUnloadTime, StepRateTime, FALSE) != STATUS_SUCCESS)
206  {
207  WARN_(FLOPPY, "RWDetermineMediaType(): specify failed\n");
208  return STATUS_UNSUCCESSFUL;
209  }
210 
211  /* clear any spurious interrupts in preparation for recalibrate */
212  KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
213 
214  /* Recalibrate --> head over first track */
215  for(i=0; i < 2; i++)
216  {
217  NTSTATUS RecalStatus;
218 
219  if(HwRecalibrate(DriveInfo) != STATUS_SUCCESS)
220  {
221  WARN_(FLOPPY, "RWDetermineMediaType(): Recalibrate failed\n");
222  return STATUS_UNSUCCESSFUL;
223  }
224 
225  /* Wait for the recalibrate to finish */
227 
228  RecalStatus = HwRecalibrateResult(DriveInfo->ControllerInfo);
229 
230  if(RecalStatus == STATUS_SUCCESS)
231  break;
232 
233  if(i == 1) /* failed for 2nd time */
234  {
235  WARN_(FLOPPY, "RWDetermineMediaType(): RecalibrateResult failed\n");
236  return STATUS_UNSUCCESSFUL;
237  }
238  }
239 
240  /* clear any spurious interrupts */
241  KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
242 
243  /* Try to read an ID */
244  if(HwReadId(DriveInfo, 0) != STATUS_SUCCESS) /* read the first ID we find, from head 0 */
245  {
246  WARN_(FLOPPY, "RWDetermineMediaType(): ReadId failed\n");
247  return STATUS_UNSUCCESSFUL; /* if we can't even write to the controller, it's hopeless */
248  }
249 
250  /* Wait for the ReadID to finish */
252 
254  {
255  WARN_(FLOPPY, "RWDetermineMediaType(): ReadIdResult failed; continuing\n");
256  if (OneShot)
257  break;
258  else
259  continue;
260  }
261 
262  /* Found the media; populate the geometry now */
263  WARN_(FLOPPY, "Hardcoded media type!\n");
264  INFO_(FLOPPY, "RWDetermineMediaType(): Found 1.44 media; returning success\n");
271  return STATUS_SUCCESS;
272  }
273  while(TRUE);
274 
275  TRACE_(FLOPPY, "RWDetermineMediaType(): failed to find media\n");
277 }
NTSTATUS NTAPI HwSetDataRate(PCONTROLLER_INFO ControllerInfo, UCHAR DataRate)
Definition: hardware.c:204
#define INFO_(ch,...)
Definition: debug.h:159
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI HwRecalibrateResult(PCONTROLLER_INFO ControllerInfo)
Definition: hardware.c:394
ULONG BytesPerSector
Definition: ntdddisk.h:442
ULONG TracksPerCylinder
Definition: ntdddisk.h:440
#define SPECIFY_HLT_500K
Definition: hardware.h:219
#define GEOMETRY_144_MEDIATYPE
Definition: floppy.h:123
struct _CONTROLLER_INFO * ControllerInfo
Definition: fdc.h:23
#define STATUS_UNRECOGNIZED_MEDIA
Definition: udferr_usr.h:142
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define FALSE
Definition: types.h:117
#define GEOMETRY_144_BYTESPERSECTOR
Definition: floppy.h:127
smooth NULL
Definition: ftsmooth.c:416
#define GEOMETRY_144_TRACKSPERCYLINDER
Definition: floppy.h:125
NTSTATUS NTAPI HwReadIdResult(PCONTROLLER_INFO ControllerInfo, PUCHAR CurCylinder, PUCHAR CurHead)
Definition: hardware.c:864
#define TRACE_(x)
Definition: compat.h:76
#define SPECIFY_SRT_500K
Definition: hardware.h:227
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:438
ULONG SectorsPerTrack
Definition: ntdddisk.h:441
MEDIA_TYPE MediaType
Definition: ntdddisk.h:439
NTSTATUS NTAPI HwReadId(PDRIVE_INFO DriveInfo, UCHAR Head)
Definition: hardware.c:576
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
#define GEOMETRY_144_SECTORSPERTRACK
Definition: floppy.h:126
DISK_GEOMETRY DiskGeometry
Definition: floppy.h:49
NTSTATUS NTAPI HwRecalibrate(PDRIVE_INFO DriveInfo)
Definition: hardware.c:503
static ULONG Timeout
Definition: ping.c:61
#define SPECIFY_HUT_500K
Definition: hardware.h:223
#define GEOMETRY_144_CYLINDERS
Definition: floppy.h:124
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define DRSR_DSEL_500KBPS
Definition: hardware.h:106
#define WARN_(ch,...)
Definition: debug.h:157
UCHAR BytesPerSectorCode
Definition: floppy.h:50
NTSTATUS NTAPI HwSpecify(PCONTROLLER_INFO ControllerInfo, UCHAR HeadLoadTime, UCHAR HeadUnloadTime, UCHAR StepRateTime, BOOLEAN NonDma)
Definition: hardware.c:925
NTSTATUS NTAPI WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo, PLARGE_INTEGER Timeout)
Definition: floppy.c:163
LONGLONG QuadPart
Definition: typedefs.h:114
#define HW_512_BYTES_PER_SECTOR
Definition: hardware.h:259
#define PAGED_CODE()

Referenced by AddControllers(), and ReadWritePassive().

Variable Documentation

◆ ReadWrite

DRIVER_DISPATCH ReadWrite

Definition at line 29 of file readwrite.h.

Referenced by AcpiExFieldDatumIo(), and DriverEntry().