-/*++\r
-\r
- Copyright (c) 2006 - 2007, Intel Corporation<BR>\r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- IsaFloppyCtrl.c\r
-\r
-Abstract:\r
-\r
- ISA Floppy Driver\r
- 1. Support two types diskette drive \r
- 1.44M drive and 2.88M drive (and now only support 1.44M)\r
- 2. Support two diskette drives\r
- 3. Use DMA channel 2 to transfer data\r
- 4. Do not use interrupt\r
- 5. Support diskette change line signal and write protect\r
- \r
- The internal function for the floppy driver\r
-\r
-Revision History:\r
-\r
---*/\r
-\r
-#include "IsaFloppy.h"\r
-\r
-EFI_STATUS\r
-DiscoverFddDevice (\r
- IN FDC_BLK_IO_DEV *FdcDev\r
- )\r
-/*++\r
-\r
- Routine Description: Detect the floppy drive is presented or not \r
- Parameters:\r
- FdcDev FDC_BLK_IO_DEV * : A pointer to the Data Structure FDC_BLK_IO_DEV \r
- Returns:\r
- EFI_SUCCESS Drive is presented \r
- EFI_NOT_FOUND Drive is not presented\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
-\r
- FdcDev->BlkIo.Media = &FdcDev->BlkMedia;\r
-\r
- //\r
- // Call FddIndentify subroutine\r
- //\r
- Status = FddIdentify (FdcDev);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- FdcDev->BlkIo.Reset = FdcReset;\r
- FdcDev->BlkIo.FlushBlocks = FddFlushBlocks;\r
- FdcDev->BlkIo.ReadBlocks = FddReadBlocks;\r
- FdcDev->BlkIo.WriteBlocks = FddWriteBlocks;\r
- FdcDev->BlkMedia.LogicalPartition = FALSE;\r
- FdcDev->BlkMedia.WriteCaching = FALSE;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FddIdentify (\r
- IN FDC_BLK_IO_DEV *FdcDev\r
- )\r
-/*++\r
-\r
- Routine Description: Do recalibrate and see the drive is presented or not\r
- Set the media parameters\r
- Parameters:\r
- FdcDev FDC_BLK_IO_DEV * : A pointer to the Data Structure FDC_BLK_IO_DEV \r
- Returns:\r
- EFI_SUCCESS: \r
- EFI_DEVICE_ERROR: \r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Set Floppy Disk Controller's motor on\r
- //\r
- Status = MotorOn (FdcDev);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Status = Recalibrate (FdcDev);\r
-\r
- if (EFI_ERROR (Status)) {\r
- MotorOff (FdcDev);\r
- FdcDev->ControllerState->NeedRecalibrate = TRUE;\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Set Media Parameter\r
- //\r
- FdcDev->BlkIo.Media->RemovableMedia = TRUE;\r
- FdcDev->BlkIo.Media->MediaPresent = TRUE;\r
- //\r
- // investigate\r
- //\r
- FdcDev->BlkIo.Media->MediaId = 0;\r
-\r
- //\r
- // Check Media\r
- //\r
- Status = DisketChanged (FdcDev);\r
- switch (Status) {\r
- case EFI_NO_MEDIA:\r
- FdcDev->BlkIo.Media->MediaPresent = FALSE;\r
- break;\r
-\r
- case EFI_MEDIA_CHANGED:\r
- case EFI_SUCCESS:\r
- break;\r
-\r
- default:\r
- MotorOff (FdcDev);\r
- return Status;\r
- }\r
- //\r
- // Check Disk Write Protected\r
- //\r
- Status = SenseDrvStatus (FdcDev, 0);\r
- switch (Status) {\r
- case EFI_WRITE_PROTECTED:\r
- FdcDev->BlkIo.Media->ReadOnly = TRUE;\r
- break;\r
-\r
- case EFI_SUCCESS:\r
- FdcDev->BlkIo.Media->ReadOnly = FALSE;\r
- break;\r
-\r
- default:\r
- return EFI_DEVICE_ERROR;\r
- break;\r
- }\r
-\r
- MotorOff (FdcDev);\r
-\r
- //\r
- // Set Media Default Type\r
- //\r
- FdcDev->BlkIo.Media->BlockSize = DISK_1440K_BYTEPERSECTOR;\r
- FdcDev->BlkIo.Media->LastBlock = DISK_1440K_EOT * 2 * (DISK_1440K_MAXTRACKNUM + 1) - 1;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FddReset (\r
- IN FDC_BLK_IO_DEV *FdcDev\r
- )\r
-/*++\r
-\r
- Routine Description: Reset the Floppy Logic Drive \r
- Parameters:\r
- FdcDev FDC_BLK_IO_DEV * : A pointer to the Data Structure FDC_BLK_IO_DEV \r
- Returns:\r
- EFI_SUCCESS: The Floppy Logic Drive is reset\r
- EFI_DEVICE_ERROR: The Floppy Logic Drive is not functioning correctly and \r
- can not be reset\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-{\r
- UINT8 data;\r
- UINT8 StatusRegister0;\r
- UINT8 PresentCylinderNumber;\r
- UINTN Index;\r
-\r
- //\r
- // Report reset progress code\r
- //\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_PROGRESS_CODE,\r
- EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_RESET,\r
- FdcDev->DevicePath\r
- );\r
-\r
- //\r
- // Reset specified Floppy Logic Drive according to FdcDev -> Disk\r
- // Set Digital Output Register(DOR) to do reset work\r
- // bit0 & bit1 of DOR : Drive Select\r
- // bit2 : Reset bit\r
- // bit3 : DMA and Int bit\r
- // Reset : a "0" written to bit2 resets the FDC, this reset will remain\r
- // active until\r
- // a "1" is written to this bit.\r
- // Reset step 1:\r
- // use bit0 & bit1 to select the logic drive\r
- // write "0" to bit2\r
- //\r
- data = 0x0;\r
- data = (UINT8) (data | (SELECT_DRV & FdcDev->Disk));\r
- FdcWritePort (FdcDev, FDC_REGISTER_DOR, data);\r
-\r
- //\r
- // wait some time,at least 120us\r
- //\r
- MicroSecondDelay (500);\r
-\r
- //\r
- // Reset step 2:\r
- // write "1" to bit2\r
- // write "1" to bit3 : enable DMA\r
- //\r
- data |= 0x0C;\r
- FdcWritePort (FdcDev, FDC_REGISTER_DOR, data);\r
-\r
- //\r
- // Experience value\r
- //\r
- MicroSecondDelay (2000);\r
-\r
- //\r
- // wait specified floppy logic drive is not busy\r
- //\r
- if (EFI_ERROR (FddWaitForBSYClear (FdcDev, 1))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Set the Transfer Data Rate\r
- //\r
- FdcWritePort (FdcDev, FDC_REGISTER_CCR, 0x0);\r
-\r
- //\r
- // Experience value\r
- //\r
- MicroSecondDelay (100);\r
-\r
- //\r
- // Issue Sense interrupt command for each drive (total 4 drives)\r
- //\r
- for (Index = 0; Index < 4; Index++) {\r
- if (EFI_ERROR (SenseIntStatus (FdcDev, &StatusRegister0, &PresentCylinderNumber))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
- //\r
- // issue Specify command\r
- //\r
- if (EFI_ERROR (Specify (FdcDev))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-MotorOn (\r
- IN FDC_BLK_IO_DEV *FdcDev\r
- )\r
-/*++\r
-\r
- Routine Description: Turn the drive's motor on\r
- The drive's motor must be on before any command can be executed \r
- Parameters:\r
- FdcDev FDC_BLK_IO_DEV * : A pointer to the Data Structure FDC_BLK_IO_DEV \r
- Returns:\r
- EFI_SUCCESS: Turn the drive's motor on successfully\r
- EFI_DEVICE_ERROR: The drive is busy, so can not turn motor on \r
- EFI_INVALID_PARAMETER: Fail to Set timer(Cancel timer) \r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
- UINT8 data;\r
-\r
- //\r
- // Control of the floppy drive motors is a big pain. If motor is off, you have\r
- // to turn it on first. But you can not leave the motor on all the time, since\r
- // that would wear out the disk. On the other hand, if you turn the motor off\r
- // after each operation, the system performance will be awful. The compromise\r
- // used in this driver is to leave the motor on for 2 seconds after\r
- // each operation. If a new operation is started in that interval(2s),\r
- // the motor need not be turned on again. If no new operation is started,\r
- // a timer goes off and the motor is turned off\r
- //\r
- //\r
- // Cancel the timer\r
- //\r
- Status = gBS->SetTimer (FdcDev->Event, TimerCancel, 0);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Get the motor status\r
- //\r
- data = FdcReadPort (FdcDev, FDC_REGISTER_DOR);\r
-\r
- if (((FdcDev->Disk == FDC_DISK0) && ((data & 0x10) == 0x10)) ||\r
- ((FdcDev->Disk == FDC_DISK1) && ((data & 0x21) == 0x21))\r
- ) {\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // The drive's motor is off, so need turn it on\r
- // first look at command and drive are busy or not\r
- //\r
- if (EFI_ERROR (FddWaitForBSYClear (FdcDev, 1))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // for drive A: 1CH, drive B: 2DH\r
- //\r
- data = 0x0C;\r
- data = (UINT8) (data | (SELECT_DRV & FdcDev->Disk));\r
- if (FdcDev->Disk == FDC_DISK0) {\r
- //\r
- // drive A\r
- //\r
- data |= DRVA_MOTOR_ON;\r
- } else {\r
- //\r
- // drive B\r
- //\r
- data |= DRVB_MOTOR_ON;\r
- }\r
-\r
- FdcWritePort (FdcDev, FDC_REGISTER_DOR, data);\r
-\r
- //\r
- // Experience value\r
- //\r
- MicroSecondDelay (4000);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-MotorOff (\r
- IN FDC_BLK_IO_DEV *FdcDev\r
- )\r
-/*++\r
-\r
- Routine Description: Set a Timer and when Timer goes off, turn the motor off\r
- Parameters:\r
- FdcDev FDC_BLK_IO_DEV * : A pointer to the Data Structure FDC_BLK_IO_DEV \r
- Returns:\r
- EFI_SUCCESS: Set the Timer successfully\r
- EFI_INVALID_PARAMETER: Fail to Set the timer \r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-{\r
- //\r
- // Set the timer : 2s\r
- //\r
- return gBS->SetTimer (FdcDev->Event, TimerRelative, 20000000);\r
-}\r
-\r
-EFI_STATUS\r
-DisketChanged (\r
- IN FDC_BLK_IO_DEV *FdcDev\r
- )\r
-/*++\r
-\r
- Routine Description: Detect the disk in the drive is changed or not\r
- Parameters:\r
- FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV \r
- Returns:\r
- EFI_SUCCESS: No disk media change\r
- EFI_DEVICE_ERROR: Fail to do the recalibrate or seek operation\r
- EFI_NO_MEDIA: No disk in the drive\r
- EFI_MEDIA_CHANGED: There is a new disk in the drive\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
- UINT8 data;\r
-\r
- //\r
- // Check change line\r
- //\r
- data = FdcReadPort (FdcDev, FDC_REGISTER_DIR);\r
-\r
- //\r
- // Io delay\r
- //\r
- MicroSecondDelay (50);\r
-\r
- if ((data & DIR_DCL) == 0x80) {\r
- //\r
- // disk change line is active\r
- //\r
- if (FdcDev->PresentCylinderNumber != 0) {\r
- Status = Recalibrate (FdcDev);\r
- } else {\r
- Status = Seek (FdcDev, 0x30);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- FdcDev->ControllerState->NeedRecalibrate = TRUE;\r
- return EFI_DEVICE_ERROR;\r
- //\r
- // Fail to do the seek or recalibrate operation\r
- //\r
- }\r
-\r
- data = FdcReadPort (FdcDev, FDC_REGISTER_DIR);\r
-\r
- //\r
- // Io delay\r
- //\r
- MicroSecondDelay (50);\r
-\r
- if ((data & DIR_DCL) == 0x80) {\r
- return EFI_NO_MEDIA;\r
- }\r
-\r
- return EFI_MEDIA_CHANGED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-Specify (\r
- IN FDC_BLK_IO_DEV *FdcDev\r
- )\r
-/*++\r
-\r
- Routine Description: Do the Specify command, this command sets DMA operation\r
- and the initial values for each of the three internal \r
- times: HUT, SRT and HLT\r
- Parameters:\r
- None\r
- Returns:\r
- EFI_SUCCESS: Execute the Specify command successfully\r
- EFI_DEVICE_ERROR: Fail to execute the command\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-{\r
- FDD_SPECIFY_CMD Command;\r
- UINTN Index;\r
- UINT8 *CommandPointer;\r
-\r
- ZeroMem (&Command, sizeof (FDD_SPECIFY_CMD));\r
- Command.CommandCode = SPECIFY_CMD;\r
- //\r
- // set SRT, HUT\r
- //\r
- Command.SrtHut = 0xdf;\r
- //\r
- // 0xdf;\r
- //\r
- // set HLT and DMA\r
- //\r
- Command.HltNd = 0x02;\r
-\r
- CommandPointer = (UINT8 *) (&Command);\r
- for (Index = 0; Index < sizeof (FDD_SPECIFY_CMD); Index++) {\r
- if (EFI_ERROR (DataOutByte (FdcDev, CommandPointer++))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-Recalibrate (\r
- IN FDC_BLK_IO_DEV *FdcDev\r
- )\r
-/*++\r
-\r
- Routine Description: Set the head of floppy drive to track 0\r
- Parameters:\r
- FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV\r
- Returns:\r
- EFI_SUCCESS: Execute the Recalibrate operation successfully\r
- EFI_DEVICE_ERROR: Fail to execute the Recalibrate operation\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-{\r
- FDD_COMMAND_PACKET2 Command;\r
- UINTN Index;\r
- UINT8 StatusRegister0;\r
- UINT8 PresentCylinderNumber;\r
- UINT8 *CommandPointer;\r
- UINT8 Count;\r
-\r
- Count = 2;\r
-\r
- while (Count > 0) {\r
- ZeroMem (&Command, sizeof (FDD_COMMAND_PACKET2));\r
- Command.CommandCode = RECALIBRATE_CMD;\r
- //\r
- // drive select\r
- //\r
- if (FdcDev->Disk == FDC_DISK0) {\r
- Command.DiskHeadSel = 0;\r
- //\r
- // 0\r
- //\r
- } else {\r
- Command.DiskHeadSel = 1;\r
- //\r
- // 1\r
- //\r
- }\r
-\r
- CommandPointer = (UINT8 *) (&Command);\r
- for (Index = 0; Index < sizeof (FDD_COMMAND_PACKET2); Index++) {\r
- if (EFI_ERROR (DataOutByte (FdcDev, CommandPointer++))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
- //\r
- // Experience value\r
- //\r
- MicroSecondDelay (250000);\r
- //\r
- // need modify according to 1.44M or 2.88M\r
- //\r
- if (EFI_ERROR (SenseIntStatus (FdcDev, &StatusRegister0, &PresentCylinderNumber))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- if ((StatusRegister0 & 0xf0) == 0x20 && PresentCylinderNumber == 0) {\r
- FdcDev->PresentCylinderNumber = 0;\r
- FdcDev->ControllerState->NeedRecalibrate = FALSE;\r
- return EFI_SUCCESS;\r
- } else {\r
- Count--;\r
- if (Count == 0) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
- }\r
- //\r
- // end while\r
- //\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-Seek (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN EFI_LBA Lba\r
- )\r
-/*++\r
-\r
- Routine Description: Set the head of floppy drive to the new cylinder\r
- Parameters:\r
- FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV\r
- Lba EFI_LBA : The logic block address want to seek\r
- Returns:\r
- EFI_SUCCESS: Execute the Seek operation successfully\r
- EFI_DEVICE_ERROR: Fail to execute the Seek operation\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: Lba - add argument and description to function comment\r
-{\r
- FDD_SEEK_CMD Command;\r
- UINT8 EndOfTrack;\r
- UINT8 Head;\r
- UINT8 Cylinder;\r
- UINT8 StatusRegister0;\r
- UINT8 *CommandPointer;\r
- UINT8 PresentCylinderNumber;\r
- UINTN Index;\r
- UINT8 DelayTime;\r
-\r
- if (FdcDev->ControllerState->NeedRecalibrate) {\r
- if (EFI_ERROR (Recalibrate (FdcDev))) {\r
- FdcDev->ControllerState->NeedRecalibrate = TRUE;\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
- EndOfTrack = DISK_1440K_EOT;\r
- //\r
- // Calculate cylinder based on Lba and EOT\r
- //\r
- Cylinder = (UINT8) ((UINTN) Lba / EndOfTrack / 2);\r
-\r
- //\r
- // if the destination cylinder is the present cylinder, unnecessary to do the\r
- // seek operation\r
- //\r
- if (FdcDev->PresentCylinderNumber == Cylinder) {\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // Calculate the head : 0 or 1\r
- //\r
- Head = (UINT8) ((UINTN) Lba / EndOfTrack % 2);\r
-\r
- ZeroMem (&Command, sizeof (FDD_SEEK_CMD));\r
- Command.CommandCode = SEEK_CMD;\r
- if (FdcDev->Disk == FDC_DISK0) {\r
- Command.DiskHeadSel = 0;\r
- //\r
- // 0\r
- //\r
- } else {\r
- Command.DiskHeadSel = 1;\r
- //\r
- // 1\r
- //\r
- }\r
-\r
- Command.DiskHeadSel = (UINT8) (Command.DiskHeadSel | (Head << 2));\r
- Command.NewCylinder = Cylinder;\r
-\r
- CommandPointer = (UINT8 *) (&Command);\r
- for (Index = 0; Index < sizeof (FDD_SEEK_CMD); Index++) {\r
- if (EFI_ERROR (DataOutByte (FdcDev, CommandPointer++))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
- //\r
- // Io delay\r
- //\r
- MicroSecondDelay (100);\r
-\r
- //\r
- // Calculate waiting time\r
- //\r
- if (FdcDev->PresentCylinderNumber > Cylinder) {\r
- DelayTime = (UINT8) (FdcDev->PresentCylinderNumber - Cylinder);\r
- } else {\r
- DelayTime = (UINT8) (Cylinder - FdcDev->PresentCylinderNumber);\r
- }\r
-\r
- MicroSecondDelay ((DelayTime + 1) * 4000);\r
-\r
- if (EFI_ERROR (SenseIntStatus (FdcDev, &StatusRegister0, &PresentCylinderNumber))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- if ((StatusRegister0 & 0xf0) == 0x20) {\r
- FdcDev->PresentCylinderNumber = Command.NewCylinder;\r
- return EFI_SUCCESS;\r
- } else {\r
- FdcDev->ControllerState->NeedRecalibrate = TRUE;\r
- return EFI_DEVICE_ERROR;\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-SenseIntStatus (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN OUT UINT8 *StatusRegister0,\r
- IN OUT UINT8 *PresentCylinderNumber\r
- )\r
-/*++\r
-\r
- Routine Description: Do the Sense Interrupt Status command, this command \r
- resets the interrupt signal\r
- Parameters:\r
- StatusRegister0 UINT8 *: Be used to save Status Register 0 read from FDC \r
- PresentCylinderNumber UINT8 *: Be used to save present cylinder number \r
- read from FDC\r
- Returns:\r
- EFI_SUCCESS: Execute the Sense Interrupt Status command successfully\r
- EFI_DEVICE_ERROR: Fail to execute the command\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: StatusRegister0 - add argument and description to function comment\r
-// GC_TODO: PresentCylinderNumber - add argument and description to function comment\r
-{\r
- UINT8 command;\r
-\r
- command = SENSE_INT_STATUS_CMD;\r
- if (EFI_ERROR (DataOutByte (FdcDev, &command))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (EFI_ERROR (DataInByte (FdcDev, StatusRegister0))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (EFI_ERROR (DataInByte (FdcDev, PresentCylinderNumber))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-SenseDrvStatus (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN EFI_LBA Lba\r
- )\r
-/*++\r
-\r
- Routine Description: Do the Sense Drive Status command\r
- Parameters:\r
- FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV \r
- Lba EFI_LBA : Logic block address\r
- Returns:\r
- EFI_SUCCESS: Execute the Sense Drive Status command successfully\r
- EFI_DEVICE_ERROR: Fail to execute the command\r
- EFI_WRITE_PROTECTED:The disk is write protected \r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: Lba - add argument and description to function comment\r
-{\r
- FDD_COMMAND_PACKET2 Command;\r
- UINT8 Head;\r
- UINT8 EndOfTrack;\r
- UINTN Index;\r
- UINT8 StatusRegister3;\r
- UINT8 *CommandPointer;\r
-\r
- //\r
- // Sense Drive Status command obtains drive status information,\r
- // it has not execution phase and goes directly to the result phase from the\r
- // command phase, Status Register 3 contains the drive status information\r
- //\r
- ZeroMem (&Command, sizeof (FDD_COMMAND_PACKET2));\r
- Command.CommandCode = SENSE_DRV_STATUS_CMD;\r
-\r
- if (FdcDev->Disk == FDC_DISK0) {\r
- Command.DiskHeadSel = 0;\r
- } else {\r
- Command.DiskHeadSel = 1;\r
- }\r
-\r
- EndOfTrack = DISK_1440K_EOT;\r
- Head = (UINT8) ((UINTN) Lba / EndOfTrack % 2);\r
- Command.DiskHeadSel = (UINT8) (Command.DiskHeadSel | (Head << 2));\r
-\r
- CommandPointer = (UINT8 *) (&Command);\r
- for (Index = 0; Index < sizeof (FDD_COMMAND_PACKET2); Index++) {\r
- if (EFI_ERROR (DataOutByte (FdcDev, CommandPointer++))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
- if (EFI_ERROR (DataInByte (FdcDev, &StatusRegister3))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Io delay\r
- //\r
- MicroSecondDelay (50);\r
-\r
- //\r
- // Check Status Register 3 to get drive status information\r
- //\r
- return CheckStatus3 (StatusRegister3);\r
-}\r
-\r
-EFI_STATUS\r
-DetectMedia (\r
- IN FDC_BLK_IO_DEV *FdcDev\r
- )\r
-/*++\r
-\r
- Routine Description: Update the disk media properties and if necessary \r
- reinstall Block I/O interface\r
- Parameters:\r
- FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV \r
- Returns:\r
- EFI_SUCCESS: Do the operation successfully\r
- EFI_DEVICE_ERROR: Fail to the operation\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
- BOOLEAN bReset;\r
- BOOLEAN bReadOnlyLastTime;\r
- BOOLEAN bMediaPresentLastTime;\r
-\r
- bReset = FALSE;\r
- bReadOnlyLastTime = FdcDev->BlkIo.Media->ReadOnly;\r
- bMediaPresentLastTime = FdcDev->BlkIo.Media->MediaPresent;\r
-\r
- //\r
- // Check disk change\r
- //\r
- Status = DisketChanged (FdcDev);\r
- switch (Status) {\r
- case EFI_MEDIA_CHANGED:\r
- FdcDev->BlkIo.Media->MediaId++;\r
- FdcDev->BlkIo.Media->MediaPresent = TRUE;\r
- bReset = TRUE;\r
- break;\r
-\r
- case EFI_NO_MEDIA:\r
- FdcDev->BlkIo.Media->MediaPresent = FALSE;\r
- break;\r
-\r
- case EFI_SUCCESS:\r
- break;\r
-\r
- default:\r
- MotorOff (FdcDev);\r
- return Status;\r
- //\r
- // EFI_DEVICE_ERROR\r
- //\r
- }\r
-\r
- if (FdcDev->BlkIo.Media->MediaPresent) {\r
- //\r
- // Check disk write protected\r
- //\r
- Status = SenseDrvStatus (FdcDev, 0);\r
- if (Status == EFI_WRITE_PROTECTED) {\r
- FdcDev->BlkIo.Media->ReadOnly = TRUE;\r
- } else {\r
- FdcDev->BlkIo.Media->ReadOnly = FALSE;\r
- }\r
- }\r
-\r
- if (FdcDev->BlkIo.Media->MediaPresent && (bReadOnlyLastTime != FdcDev->BlkIo.Media->ReadOnly)) {\r
- bReset = TRUE;\r
- }\r
-\r
- if (bMediaPresentLastTime != FdcDev->BlkIo.Media->MediaPresent) {\r
- bReset = TRUE;\r
- }\r
-\r
- if (bReset) {\r
- Status = gBS->ReinstallProtocolInterface (\r
- FdcDev->Handle,\r
- &gEfiBlockIoProtocolGuid,\r
- &FdcDev->BlkIo,\r
- &FdcDev->BlkIo\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-Setup (\r
- IN FDC_BLK_IO_DEV *FdcDev\r
- )\r
-/*++\r
-\r
- Routine Description: Set the data rate and so on\r
- Parameters:\r
- None \r
- Returns:\r
- EFI_SUCCESS: \r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Set data rate 500kbs\r
- //\r
- FdcWritePort (FdcDev, FDC_REGISTER_CCR, 0x0);\r
-\r
- //\r
- // Io delay\r
- //\r
- MicroSecondDelay (50);\r
-\r
- Status = Specify (FdcDev);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ReadWriteDataSector (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN VOID *HostAddress,\r
- IN EFI_LBA Lba,\r
- IN UINTN NumberOfBlocks,\r
- IN BOOLEAN Read\r
- )\r
-/*++\r
-\r
- Routine Description: Read or Write a number of blocks in the same cylinder\r
- Parameters:\r
- FdcDev FDC_BLK_IO_DEV * : A pointer to Data Structure FDC_BLK_IO_DEV\r
- Buffer VOID *:\r
- Lba EFI_LBA:\r
- NumberOfBlocks UINTN:\r
- Read BOOLEAN: \r
- Returns:\r
- EFI_SUCCESS: \r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: HostAddress - add argument and description to function comment\r
-// GC_TODO: Lba - add argument and description to function comment\r
-// GC_TODO: NumberOfBlocks - add argument and description to function comment\r
-// GC_TODO: Read - add argument and description to function comment\r
-// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// GC_TODO: EFI_TIMEOUT - add return value to function comment\r
-// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- FDD_COMMAND_PACKET1 Command;\r
- FDD_RESULT_PACKET Result;\r
- UINTN Index;\r
- UINTN Times;\r
- UINT8 *CommandPointer;\r
-\r
- EFI_PHYSICAL_ADDRESS DeviceAddress;\r
- EFI_ISA_IO_PROTOCOL *IsaIo;\r
- UINTN NumberofBytes;\r
- VOID *Mapping;\r
- EFI_ISA_IO_PROTOCOL_OPERATION Operation;\r
- EFI_STATUS Status1;\r
- UINT8 Channel;\r
- EFI_ISA_ACPI_RESOURCE *ResourceItem;\r
- UINT32 Attribute;\r
-\r
- Status = Seek (FdcDev, Lba);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Map Dma\r
- //\r
- IsaIo = FdcDev->IsaIo;\r
- NumberofBytes = NumberOfBlocks * 512;\r
- if (Read == READ) {\r
- Operation = EfiIsaIoOperationSlaveWrite;\r
- } else {\r
- Operation = EfiIsaIoOperationSlaveRead;\r
- }\r
-\r
- ResourceItem = IsaIo->ResourceList->ResourceItem;\r
- Index = 0;\r
- while (ResourceItem[Index].Type != EfiIsaAcpiResourceEndOfList) {\r
- if (ResourceItem[Index].Type == EfiIsaAcpiResourceDma) {\r
- break;\r
- }\r
-\r
- Index++;\r
- }\r
-\r
- if (ResourceItem[Index].Type == EfiIsaAcpiResourceEndOfList) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Channel = (UINT8) IsaIo->ResourceList->ResourceItem[Index].StartRange;\r
- Attribute = IsaIo->ResourceList->ResourceItem[Index].Attribute;\r
-\r
- Status1 = IsaIo->Map (\r
- IsaIo,\r
- Operation,\r
- Channel,\r
- Attribute,\r
- HostAddress,\r
- &NumberofBytes,\r
- &DeviceAddress,\r
- &Mapping\r
- );\r
- if (EFI_ERROR (Status1)) {\r
- return Status1;\r
- }\r
-\r
- //\r
- // Allocate Read or Write command packet\r
- //\r
- ZeroMem (&Command, sizeof (FDD_COMMAND_PACKET1));\r
- if (Read == READ) {\r
- Command.CommandCode = READ_DATA_CMD | CMD_MT | CMD_MFM | CMD_SK;\r
- } else {\r
- Command.CommandCode = WRITE_DATA_CMD | CMD_MT | CMD_MFM;\r
- }\r
-\r
- FillPara (FdcDev, Lba, &Command);\r
-\r
- //\r
- // Write command bytes to FDC\r
- //\r
- CommandPointer = (UINT8 *) (&Command);\r
- for (Index = 0; Index < sizeof (FDD_COMMAND_PACKET1); Index++) {\r
- if (EFI_ERROR (DataOutByte (FdcDev, CommandPointer++))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
- //\r
- // wait for some time\r
- //\r
- Times = (STALL_1_SECOND / 50) + 1;\r
- do {\r
- if ((FdcReadPort (FdcDev, FDC_REGISTER_MSR) & 0xc0) == 0xc0) {\r
- break;\r
- }\r
-\r
- MicroSecondDelay (50);\r
- Times = Times - 1;\r
- } while (Times);\r
-\r
- if (Times == 0) {\r
- return EFI_TIMEOUT;\r
- }\r
- //\r
- // Read result bytes from FDC\r
- //\r
- CommandPointer = (UINT8 *) (&Result);\r
- for (Index = 0; Index < sizeof (FDD_RESULT_PACKET); Index++) {\r
- if (EFI_ERROR (DataInByte (FdcDev, CommandPointer++))) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
- //\r
- // Flush before Unmap\r
- //\r
- if (Read == READ) {\r
- Status1 = IsaIo->Flush (IsaIo);\r
- if (EFI_ERROR (Status1)) {\r
- return Status1;\r
- }\r
- }\r
- //\r
- // Unmap Dma\r
- //\r
- Status1 = IsaIo->Unmap (IsaIo, Mapping);\r
- if (EFI_ERROR (Status1)) {\r
- return Status1;\r
- }\r
-\r
- return CheckResult (&Result, FdcDev);\r
-}\r
-\r
-VOID\r
-FillPara (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN EFI_LBA Lba,\r
- IN FDD_COMMAND_PACKET1 *Command\r
- )\r
-/*++\r
-\r
- Routine Description: Fill in Parameter\r
- Parameters:\r
- Returns:\r
- \r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: Lba - add argument and description to function comment\r
-// GC_TODO: Command - add argument and description to function comment\r
-{\r
- UINT8 EndOfTrack;\r
-\r
- //\r
- // Get EndOfTrack from the Para table\r
- //\r
- EndOfTrack = DISK_1440K_EOT;\r
-\r
- //\r
- // Fill the command parameter\r
- //\r
- if (FdcDev->Disk == FDC_DISK0) {\r
- Command->DiskHeadSel = 0;\r
- } else {\r
- Command->DiskHeadSel = 1;\r
- }\r
-\r
- Command->Cylinder = (UINT8) ((UINTN) Lba / EndOfTrack / 2);\r
- Command->Head = (UINT8) ((UINTN) Lba / EndOfTrack % 2);\r
- Command->Sector = (UINT8) ((UINT8) ((UINTN) Lba % EndOfTrack) + 1);\r
- Command->DiskHeadSel = (UINT8) (Command->DiskHeadSel | (Command->Head << 2));\r
- Command->Number = DISK_1440K_NUMBER;\r
- Command->EndOfTrack = DISK_1440K_EOT;\r
- Command->GapLength = DISK_1440K_GPL;\r
- Command->DataLength = DISK_1440K_DTL;\r
-}\r
-\r
-EFI_STATUS\r
-DataInByte (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN OUT UINT8 *Pointer\r
- )\r
-/*++\r
-\r
- Routine Description: Read result byte from Data Register of FDC\r
- Parameters:\r
- Pointer UINT8 *: Be used to save result byte read from FDC \r
- Returns:\r
- EFI_SUCCESS: Read result byte from FDC successfully\r
- EFI_DEVICE_ERROR: The FDC is not ready to be read\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: Pointer - add argument and description to function comment\r
-{\r
- UINT8 data;\r
-\r
- //\r
- // wait for 1ms and detect the FDC is ready to be read\r
- //\r
- if (EFI_ERROR (FddDRQReady (FdcDev, DATA_IN, 1))) {\r
- return EFI_DEVICE_ERROR;\r
- //\r
- // is not ready\r
- //\r
- }\r
-\r
- data = FdcReadPort (FdcDev, FDC_REGISTER_DTR);\r
-\r
- //\r
- // Io delay\r
- //\r
- MicroSecondDelay (50);\r
-\r
- *Pointer = data;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-DataOutByte (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN UINT8 *Pointer\r
- )\r
-/*++\r
-\r
- Routine Description: Write command byte to Data Register of FDC\r
- Parameters:\r
- Pointer UINT8 *: Be used to save command byte written to FDC \r
- Returns:\r
- EFI_SUCCESS: Write command byte to FDC successfully\r
- EFI_DEVICE_ERROR: The FDC is not ready to be written\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: Pointer - add argument and description to function comment\r
-{\r
- UINT8 data;\r
-\r
- //\r
- // wait for 1ms and detect the FDC is ready to be written\r
- //\r
- if (EFI_ERROR (FddDRQReady (FdcDev, DATA_OUT, 1))) {\r
- return EFI_DEVICE_ERROR;\r
- //\r
- // is not ready\r
- //\r
- }\r
-\r
- data = *Pointer;\r
-\r
- FdcWritePort (FdcDev, FDC_REGISTER_DTR, data);\r
-\r
- //\r
- // Io delay\r
- //\r
- MicroSecondDelay (50);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FddWaitForBSYClear (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN UINTN TimeoutInSeconds\r
- )\r
-/*++\r
-\r
- Routine Description: Detect the specified floppy logic drive is busy or \r
- not within a period of time\r
- Parameters:\r
- Disk EFI_FDC_DISK: Indicate it is drive A or drive B\r
- TimeoutInSeconds UINTN: the time period for waiting \r
- Returns:\r
- EFI_SUCCESS: The drive and command are not busy\r
- EFI_TIMEOUT: The drive or command is still busy after a period time that \r
- set by TimeoutInSeconds\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: TimeoutInSeconds - add argument and description to function comment\r
-{\r
- UINTN Delay;\r
- UINT8 StatusRegister;\r
- UINT8 Mask;\r
-\r
- //\r
- // How to determine drive and command are busy or not: by the bits of\r
- // Main Status Register\r
- // bit0: Drive 0 busy (drive A)\r
- // bit1: Drive 1 busy (drive B)\r
- // bit4: Command busy\r
- //\r
- //\r
- // set mask: for drive A set bit0 & bit4; for drive B set bit1 & bit4\r
- //\r
- Mask = (UINT8) ((FdcDev->Disk == FDC_DISK0 ? MSR_DAB : MSR_DBB) | MSR_CB);\r
-\r
- Delay = ((TimeoutInSeconds * STALL_1_MSECOND) / 50) + 1;\r
- do {\r
- StatusRegister = FdcReadPort (FdcDev, FDC_REGISTER_MSR);\r
- if ((StatusRegister & Mask) == 0x00) {\r
- break;\r
- //\r
- // not busy\r
- //\r
- }\r
-\r
- MicroSecondDelay (50);\r
- Delay = Delay - 1;\r
- } while (Delay);\r
-\r
- if (Delay == 0) {\r
- return EFI_TIMEOUT;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FddDRQReady (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN BOOLEAN Dio,\r
- IN UINTN TimeoutInSeconds\r
- )\r
-/*++\r
-\r
- Routine Description: Determine whether FDC is ready to write or read\r
- Parameters:\r
- Dio BOOLEAN: Indicate the FDC is waiting to write or read\r
- TimeoutInSeconds UINTN: The time period for waiting \r
- Returns:\r
- EFI_SUCCESS: FDC is ready to write or read\r
- EFI_NOT_READY: FDC is not ready within the specified time period\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: Dio - add argument and description to function comment\r
-// GC_TODO: TimeoutInSeconds - add argument and description to function comment\r
-{\r
- UINTN Delay;\r
- UINT8 StatusRegister;\r
- UINT8 DataInOut;\r
-\r
- //\r
- // Before writing to FDC or reading from FDC, the Host must examine\r
- // the bit7(RQM) and bit6(DIO) of the Main Status Register.\r
- // That is to say:\r
- // command bytes can not be written to Data Register\r
- // unless RQM is 1 and DIO is 0\r
- // result bytes can not be read from Data Register\r
- // unless RQM is 1 and DIO is 1\r
- //\r
- DataInOut = (UINT8) (Dio << 6);\r
- //\r
- // in order to compare bit6\r
- //\r
- Delay = ((TimeoutInSeconds * STALL_1_MSECOND) / 50) + 1;\r
- do {\r
- StatusRegister = FdcReadPort (FdcDev, FDC_REGISTER_MSR);\r
- if ((StatusRegister & MSR_RQM) == MSR_RQM && (StatusRegister & MSR_DIO) == DataInOut) {\r
- break;\r
- //\r
- // FDC is ready\r
- //\r
- }\r
-\r
- MicroSecondDelay (50);\r
- //\r
- // Stall for 50 us\r
- //\r
- Delay = Delay - 1;\r
- } while (Delay);\r
-\r
- if (Delay == 0) {\r
- return EFI_NOT_READY;\r
- //\r
- // FDC is not ready within the specified time period\r
- //\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-CheckResult (\r
- IN FDD_RESULT_PACKET *Result,\r
- IN OUT FDC_BLK_IO_DEV *FdcDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- GC_TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Result - GC_TODO: add argument description\r
- FdcDev - GC_TODO: add argument description\r
-\r
-Returns:\r
-\r
- EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
- EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
- EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
- EFI_SUCCESS - GC_TODO: Add description for return value\r
-\r
---*/\r
-{\r
- //\r
- // Check Status Register0\r
- //\r
- if ((Result->Status0 & STS0_IC) != IC_NT) {\r
- if ((Result->Status0 & STS0_SE) == 0x20) {\r
- //\r
- // seek error\r
- //\r
- FdcDev->ControllerState->NeedRecalibrate = TRUE;\r
- }\r
-\r
- FdcDev->ControllerState->NeedRecalibrate = TRUE;\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Check Status Register1\r
- //\r
- if (Result->Status1 & (STS1_EN | STS1_DE | STS1_OR | STS1_ND | STS1_NW | STS1_MA)) {\r
- FdcDev->ControllerState->NeedRecalibrate = TRUE;\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Check Status Register2\r
- //\r
- if (Result->Status2 & (STS2_CM | STS2_DD | STS2_WC | STS2_BC | STS2_MD)) {\r
- FdcDev->ControllerState->NeedRecalibrate = TRUE;\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-CheckStatus3 (\r
- IN UINT8 StatusRegister3\r
- )\r
-/*++\r
-\r
- Routine Description: Check the drive status information\r
- Parameters:\r
- StatusRegister3 UINT8: the value of Status Register 3 \r
- Returns:\r
- EFI_SUCCESS: \r
- EFI_WRITE_PROTECTED: The disk is write protected\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: StatusRegister3 - add argument and description to function comment\r
-{\r
- if (StatusRegister3 & STS3_WP) {\r
- return EFI_WRITE_PROTECTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-UINTN\r
-GetTransferBlockCount (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN EFI_LBA LBA,\r
- IN UINTN NumberOfBlocks\r
- )\r
-/*++\r
-\r
- Routine Description: Calculate the number of block in the same cylinder \r
- according to LBA\r
- Parameters:\r
- FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV\r
- LBA EFI_LBA: The starting logic block address \r
- NumberOfBlocks UINTN: The number of blocks\r
- Returns:\r
- UINTN : The number of blocks in the same cylinder which the starting \r
- logic block address is LBA\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: LBA - add argument and description to function comment\r
-// GC_TODO: NumberOfBlocks - add argument and description to function comment\r
-{\r
- UINT8 EndOfTrack;\r
- UINT8 Head;\r
- UINT8 SectorsInTrack;\r
-\r
- //\r
- // Calculate the number of block in the same cylinder\r
- //\r
- EndOfTrack = DISK_1440K_EOT;\r
- Head = (UINT8) ((UINTN) LBA / EndOfTrack % 2);\r
-\r
- SectorsInTrack = (UINT8) (EndOfTrack * (2 - Head) - (UINT8) ((UINTN) LBA % EndOfTrack));\r
- if (SectorsInTrack < NumberOfBlocks) {\r
- return SectorsInTrack;\r
- } else {\r
- return NumberOfBlocks;\r
- }\r
-}\r
-\r
-VOID\r
-EFIAPI\r
-FddTimerProc (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-/*++\r
-\r
- Routine Description: When the Timer(2s) off, turn the drive's motor off\r
- Parameters:\r
- Event EFI_EVENT: Event(the timer) whose notification function is being \r
- invoked\r
- Context VOID *: Pointer to the notification function's context \r
- Returns:\r
- VOID\r
-\r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: Event - add argument and description to function comment\r
-// GC_TODO: Context - add argument and description to function comment\r
-{\r
- FDC_BLK_IO_DEV *FdcDev;\r
- UINT8 data;\r
-\r
- FdcDev = (FDC_BLK_IO_DEV *) Context;\r
-\r
- //\r
- // Get the motor status\r
- //\r
- data = FdcReadPort (FdcDev, FDC_REGISTER_DOR);\r
-\r
- if (((FdcDev->Disk == FDC_DISK0) && ((data & 0x10) != 0x10)) ||\r
- ((FdcDev->Disk == FDC_DISK1) && ((data & 0x21) != 0x21))\r
- ) {\r
- return ;\r
- }\r
- //\r
- // the motor is on, so need motor off\r
- //\r
- data = 0x0C;\r
- data = (UINT8) (data | (SELECT_DRV & FdcDev->Disk));\r
- FdcWritePort (FdcDev, FDC_REGISTER_DOR, data);\r
- MicroSecondDelay (500);\r
-}\r
-\r
-UINT8\r
-FdcReadPort (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN UINT32 Offset\r
- )\r
-/*++\r
-\r
- Routine Description: Read I/O port for FDC \r
- Parameters:\r
- Returns:\r
- \r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: Offset - add argument and description to function comment\r
-{\r
- UINT8 Data;\r
-\r
- //\r
- // Call IsaIo\r
- //\r
- FdcDev->IsaIo->Io.Read (\r
- FdcDev->IsaIo,\r
- EfiIsaIoWidthUint8,\r
- FdcDev->BaseAddress + Offset,\r
- 1,\r
- &Data\r
- );\r
-\r
- return Data;\r
-}\r
-\r
-VOID\r
-FdcWritePort (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN UINT32 Offset,\r
- IN UINT8 Data\r
- )\r
-/*++\r
-\r
- Routine Description: Write I/O port for FDC \r
- Parameters:\r
- Returns:\r
- \r
---*/\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: FdcDev - add argument and description to function comment\r
-// GC_TODO: Offset - add argument and description to function comment\r
-// GC_TODO: Data - add argument and description to function comment\r
-{\r
-\r
- //\r
- // Call IsaIo\r
- //\r
- FdcDev->IsaIo->Io.Write (\r
- FdcDev->IsaIo,\r
- EfiIsaIoWidthUint8,\r
- FdcDev->BaseAddress + Offset,\r
- 1,\r
- &Data\r
- );\r
-}\r