-/*++\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
+/** @file\r
+ Internal floppy disk controller programming functions for the floppy driver.\r
\r
- The internal function for the floppy driver\r
+Copyright (c) 2006 - 2009, 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
-Revision History:\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
---*/\r
+**/\r
\r
#include "IsaFloppy.h"\r
\r
+/**\r
+ Detect whether a floppy drive is present or not.\r
+ \r
+ @param[in] FdcDev A pointer to the FDC_BLK_IO_DEV\r
+\r
+ @retval EFI_SUCCESS The floppy disk drive is present\r
+ @retval EFI_NOT_FOUND The floppy disk drive is not present\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
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Do recalibrate and check if the drive is present or not\r
+ and set the media parameters if the driver is present.\r
+ \r
+ @param[in] FdcDev A pointer to the FDC_BLK_IO_DEV\r
+\r
+ @retval EFI_SUCCESS The floppy disk drive is present\r
+ @retval EFI_DEVICE_ERROR The floppy disk drive is not present\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
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
+ if (Status == EFI_NO_MEDIA) {\r
+ FdcDev->BlkIo.Media->MediaPresent = FALSE;\r
+ } else if ((Status != EFI_MEDIA_CHANGED) &&\r
+ (Status != EFI_SUCCESS)) {\r
MotorOff (FdcDev);\r
return Status;\r
}\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
+ if (Status == EFI_WRITE_PROTECTED) {\r
+ FdcDev->BlkIo.Media->ReadOnly = TRUE;\r
+ } else if (Status == EFI_SUCCESS) {\r
FdcDev->BlkIo.Media->ReadOnly = FALSE;\r
- break;\r
-\r
- default:\r
+ } else {\r
return EFI_DEVICE_ERROR;\r
- break;\r
}\r
\r
MotorOff (FdcDev);\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Reset the Floppy Logic Drive.\r
+ \r
+ @param FdcDev FDC_BLK_IO_DEV * : A pointer to the FDC_BLK_IO_DEV\r
+ \r
+ @retval EFI_SUCCESS: The Floppy Logic Drive is reset\r
+ @retval EFI_DEVICE_ERROR: The Floppy Logic Drive is not functioning correctly and\r
+ can not be reset\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 Data;\r
UINT8 StatusRegister0;\r
UINT8 PresentCylinderNumber;\r
UINTN Index;\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
+ 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
// write "1" to bit2\r
// write "1" to bit3 : enable DMA\r
//\r
- data |= 0x0C;\r
- FdcWritePort (FdcDev, FDC_REGISTER_DOR, data);\r
+ Data |= 0x0C;\r
+ FdcWritePort (FdcDev, FDC_REGISTER_DOR, Data);\r
\r
//\r
// Experience value\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Turn the floppy disk drive's motor on.\r
+ The drive's motor must be on before any command can be executed.\r
+ \r
+ @param[in] FdcDev A pointer to the FDC_BLK_IO_DEV\r
+ \r
+ @retval EFI_SUCCESS The drive's motor was turned on successfully\r
+ @retval EFI_DEVICE_ERROR The drive is busy, so can not turn motor on\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
+ UINT8 DorData;\r
\r
//\r
// Control of the floppy drive motors is a big pain. If motor is off, you have\r
// Cancel the timer\r
//\r
Status = gBS->SetTimer (FdcDev->Event, TimerCancel, 0);\r
+ ASSERT_EFI_ERROR (Status);\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
+ DorData = FdcReadPort (FdcDev, FDC_REGISTER_DOR);\r
\r
- if (((FdcDev->Disk == FDC_DISK0) && ((data & 0x10) == 0x10)) ||\r
- ((FdcDev->Disk == FDC_DISK1) && ((data & 0x21) == 0x21))\r
+ if (((FdcDev->Disk == FdcDisk0) && ((DorData & 0x10) == 0x10)) ||\r
+ ((FdcDev->Disk == FdcDisk1) && ((DorData & 0x21) == 0x21))\r
) {\r
return EFI_SUCCESS;\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
+ DorData = 0x0C;\r
+ DorData = (UINT8) (DorData | (SELECT_DRV & FdcDev->Disk));\r
+ if (FdcDev->Disk == FdcDisk0) {\r
//\r
// drive A\r
//\r
- data |= DRVA_MOTOR_ON;\r
+ DorData |= DRVA_MOTOR_ON;\r
} else {\r
//\r
// drive B\r
//\r
- data |= DRVB_MOTOR_ON;\r
+ DorData |= DRVB_MOTOR_ON;\r
}\r
\r
- FdcWritePort (FdcDev, FDC_REGISTER_DOR, data);\r
+ FdcWritePort (FdcDev, FDC_REGISTER_DOR, DorData);\r
\r
//\r
// Experience value\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Set a Timer and when Timer goes off, turn the motor off.\r
+ \r
+ @param[in] FdcDev A pointer to the FDC_BLK_IO_DEV\r
+ \r
+ @retval EFI_SUCCESS Set the Timer successfully\r
+ @retval EFI_INVALID_PARAMETER Fail to Set the timer\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
return gBS->SetTimer (FdcDev->Event, TimerRelative, 20000000);\r
}\r
\r
+/**\r
+ Detect whether the disk in the drive is changed or not.\r
+ \r
+ @param[in] FdcDev A pointer to FDC_BLK_IO_DEV\r
+ \r
+ @retval EFI_SUCCESS No disk media change\r
+ @retval EFI_DEVICE_ERROR Fail to do the recalibrate or seek operation\r
+ @retval EFI_NO_MEDIA No disk in the drive\r
+ @retval EFI_MEDIA_CHANGED There is a new disk in the drive\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
+ UINT8 Data;\r
\r
//\r
// Check change line\r
//\r
- data = FdcReadPort (FdcDev, FDC_REGISTER_DIR);\r
+ Data = FdcReadPort (FdcDev, FDC_REGISTER_DIR);\r
\r
//\r
// Io delay\r
//\r
MicroSecondDelay (50);\r
\r
- if ((data & DIR_DCL) == 0x80) {\r
+ if ((Data & DIR_DCL) == 0x80) {\r
//\r
// disk change line is active\r
//\r
//\r
}\r
\r
- data = FdcReadPort (FdcDev, FDC_REGISTER_DIR);\r
+ Data = FdcReadPort (FdcDev, FDC_REGISTER_DIR);\r
\r
//\r
// Io delay\r
//\r
MicroSecondDelay (50);\r
\r
- if ((data & DIR_DCL) == 0x80) {\r
+ if ((Data & DIR_DCL) == 0x80) {\r
return EFI_NO_MEDIA;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ 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
+ \r
+ @param[in] FdcDev Pointer to instance of FDC_BLK_IO_DEV\r
+ \r
+ @retval EFI_SUCCESS Execute the Specify command successfully\r
+ @retval EFI_DEVICE_ERROR Fail to execute the command\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
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Set the head of floppy drive to track 0.\r
+ \r
+ @param FdcDev FDC_BLK_IO_DEV *: A pointer to FDC_BLK_IO_DEV\r
+ @retval EFI_SUCCESS: Execute the Recalibrate operation successfully\r
+ @retval EFI_DEVICE_ERROR: Fail to execute the Recalibrate operation\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
//\r
// drive select\r
//\r
- if (FdcDev->Disk == FDC_DISK0) {\r
+ if (FdcDev->Disk == FdcDisk0) {\r
Command.DiskHeadSel = 0;\r
//\r
// 0\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Set the head of floppy drive to the new cylinder.\r
+ \r
+ @param FdcDev FDC_BLK_IO_DEV *: A pointer to FDC_BLK_IO_DEV\r
+ @param Lba EFI_LBA : The logic block address want to seek\r
+ \r
+ @retval EFI_SUCCESS: Execute the Seek operation successfully\r
+ @retval EFI_DEVICE_ERROR: Fail to execute the Seek operation\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
\r
ZeroMem (&Command, sizeof (FDD_SEEK_CMD));\r
Command.CommandCode = SEEK_CMD;\r
- if (FdcDev->Disk == FDC_DISK0) {\r
+ if (FdcDev->Disk == FdcDisk0) {\r
Command.DiskHeadSel = 0;\r
//\r
// 0\r
}\r
}\r
\r
+/**\r
+ Do the Sense Interrupt Status command, this command\r
+ resets the interrupt signal.\r
+ \r
+ @param FdcDev FDC_BLK_IO_DEV *: A pointer to FDC_BLK_IO_DEV\r
+ @param StatusRegister0 UINT8 *: Be used to save Status Register 0 read from FDC\r
+ @param PresentCylinderNumber UINT8 *: Be used to save present cylinder number\r
+ read from FDC\r
+ \r
+ @retval EFI_SUCCESS: Execute the Sense Interrupt Status command successfully\r
+ @retval EFI_DEVICE_ERROR: Fail to execute the command\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
+ UINT8 Command;\r
\r
- command = SENSE_INT_STATUS_CMD;\r
- if (EFI_ERROR (DataOutByte (FdcDev, &command))) {\r
+ Command = SENSE_INT_STATUS_CMD;\r
+ if (EFI_ERROR (DataOutByte (FdcDev, &Command))) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Do the Sense Drive Status command.\r
+ \r
+ @param FdcDev FDC_BLK_IO_DEV *: A pointer to FDC_BLK_IO_DEV\r
+ @param Lba EFI_LBA : Logic block address\r
+ \r
+ @retval EFI_SUCCESS: Execute the Sense Drive Status command successfully\r
+ @retval EFI_DEVICE_ERROR: Fail to execute the command\r
+ @retval EFI_WRITE_PROTECTED:The disk is write protected\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
ZeroMem (&Command, sizeof (FDD_COMMAND_PACKET2));\r
Command.CommandCode = SENSE_DRV_STATUS_CMD;\r
\r
- if (FdcDev->Disk == FDC_DISK0) {\r
+ if (FdcDev->Disk == FdcDisk0) {\r
Command.DiskHeadSel = 0;\r
} else {\r
Command.DiskHeadSel = 1;\r
return CheckStatus3 (StatusRegister3);\r
}\r
\r
+/**\r
+ Update the disk media properties and if necessary reinstall Block I/O interface.\r
+ \r
+ @param FdcDev FDC_BLK_IO_DEV *: A pointer to FDC_BLK_IO_DEV\r
+ \r
+ @retval EFI_SUCCESS: Do the operation successfully\r
+ @retval EFI_DEVICE_ERROR: Fail to the operation\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
+ BOOLEAN Reset;\r
+ BOOLEAN ReadOnlyLastTime;\r
+ BOOLEAN MediaPresentLastTime;\r
\r
- bReset = FALSE;\r
- bReadOnlyLastTime = FdcDev->BlkIo.Media->ReadOnly;\r
- bMediaPresentLastTime = FdcDev->BlkIo.Media->MediaPresent;\r
+ Reset = FALSE;\r
+ ReadOnlyLastTime = FdcDev->BlkIo.Media->ReadOnly;\r
+ MediaPresentLastTime = FdcDev->BlkIo.Media->MediaPresent;\r
\r
//\r
// Check disk change\r
//\r
Status = DisketChanged (FdcDev);\r
- switch (Status) {\r
- case EFI_MEDIA_CHANGED:\r
+\r
+ if (Status == 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
+ Reset = TRUE;\r
+ } else if (Status == EFI_NO_MEDIA) {\r
FdcDev->BlkIo.Media->MediaPresent = FALSE;\r
- break;\r
-\r
- case EFI_SUCCESS:\r
- break;\r
-\r
- default:\r
+ } else if (Status != EFI_SUCCESS) {\r
MotorOff (FdcDev);\r
return Status;\r
//\r
}\r
}\r
\r
- if (FdcDev->BlkIo.Media->MediaPresent && (bReadOnlyLastTime != FdcDev->BlkIo.Media->ReadOnly)) {\r
- bReset = TRUE;\r
+ if (FdcDev->BlkIo.Media->MediaPresent && (ReadOnlyLastTime != FdcDev->BlkIo.Media->ReadOnly)) {\r
+ Reset = TRUE;\r
}\r
\r
- if (bMediaPresentLastTime != FdcDev->BlkIo.Media->MediaPresent) {\r
- bReset = TRUE;\r
+ if (MediaPresentLastTime != FdcDev->BlkIo.Media->MediaPresent) {\r
+ Reset = TRUE;\r
}\r
\r
- if (bReset) {\r
+ if (Reset) {\r
Status = gBS->ReinstallProtocolInterface (\r
FdcDev->Handle,\r
&gEfiBlockIoProtocolGuid,\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Set the data rate and so on.\r
+ \r
+ @param FdcDev A pointer to FDC_BLK_IO_DEV\r
+\r
+ @retval EFI_SUCCESS success to set the data rate\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
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Read or Write a number of blocks in the same cylinder.\r
+ \r
+ @param FdcDev A pointer to FDC_BLK_IO_DEV\r
+ @param HostAddress device address \r
+ @param Lba The starting logic block address to read from on the device\r
+ @param NumberOfBlocks The number of block wanted to be read or write\r
+ @param Read Operation type: read or write\r
+ \r
+ @retval EFI_SUCCESS Success operate\r
+\r
+**/\r
EFI_STATUS\r
ReadWriteDataSector (\r
IN FDC_BLK_IO_DEV *FdcDev,\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
\r
MicroSecondDelay (50);\r
Times = Times - 1;\r
- } while (Times);\r
+ } while (Times >= 0);\r
\r
if (Times == 0) {\r
return EFI_TIMEOUT;\r
return CheckResult (&Result, FdcDev);\r
}\r
\r
+/**\r
+ Fill in FDD command's parameter.\r
+ \r
+ @param FdcDev Pointer to instance of FDC_BLK_IO_DEV\r
+ @param Lba The starting logic block address to read from on the device\r
+ @param Command FDD command\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
// Fill the command parameter\r
//\r
- if (FdcDev->Disk == FDC_DISK0) {\r
+ if (FdcDev->Disk == FdcDisk0) {\r
Command->DiskHeadSel = 0;\r
} else {\r
Command->DiskHeadSel = 1;\r
Command->DataLength = DISK_1440K_DTL;\r
}\r
\r
+/**\r
+ Read result byte from Data Register of FDC.\r
+ \r
+ @param FdcDev Pointer to instance of FDC_BLK_IO_DEV\r
+ @param Pointer Buffer to store the byte read from FDC\r
+ \r
+ @retval EFI_SUCCESS Read result byte from FDC successfully\r
+ @retval EFI_DEVICE_ERROR The FDC is not ready to be read\r
+\r
+**/\r
EFI_STATUS\r
DataInByte (\r
- IN FDC_BLK_IO_DEV *FdcDev,\r
- IN OUT UINT8 *Pointer\r
+ IN FDC_BLK_IO_DEV *FdcDev,\r
+ 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
+ UINT8 Data;\r
\r
//\r
// wait for 1ms and detect the FDC is ready to be read\r
//\r
}\r
\r
- data = FdcReadPort (FdcDev, FDC_REGISTER_DTR);\r
+ Data = FdcReadPort (FdcDev, FDC_REGISTER_DTR);\r
\r
//\r
// Io delay\r
//\r
MicroSecondDelay (50);\r
\r
- *Pointer = data;\r
+ *Pointer = Data;\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Write command byte to Data Register of FDC.\r
+ \r
+ @param FdcDev Pointer to instance of FDC_BLK_IO_DEV\r
+ @param Pointer Be used to save command byte written to FDC\r
+ \r
+ @retval EFI_SUCCESS: Write command byte to FDC successfully\r
+ @retval EFI_DEVICE_ERROR: The FDC is not ready to be written\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
+ 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
+ // Not ready\r
//\r
+ return EFI_DEVICE_ERROR;\r
}\r
\r
- data = *Pointer;\r
+ Data = *Pointer;\r
\r
- FdcWritePort (FdcDev, FDC_REGISTER_DTR, data);\r
+ FdcWritePort (FdcDev, FDC_REGISTER_DTR, Data);\r
\r
//\r
// Io delay\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Detect the specified floppy logic drive is busy or not within a period of time.\r
+ \r
+ @param FdcDev Indicate it is drive A or drive B\r
+ @param TimeoutInSeconds the time period for waiting\r
+ \r
+ @retval EFI_SUCCESS: The drive and command are not busy\r
+ @retval EFI_TIMEOUT: The drive or command is still busy after a period time that\r
+ set by TimeoutInSeconds\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
//\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
+ Mask = (UINT8) ((FdcDev->Disk == FdcDisk0 ? MSR_DAB : MSR_DBB) | MSR_CB);\r
\r
Delay = ((TimeoutInSeconds * STALL_1_MSECOND) / 50) + 1;\r
do {\r
\r
MicroSecondDelay (50);\r
Delay = Delay - 1;\r
- } while (Delay);\r
+ } while (Delay >= 0);\r
\r
if (Delay == 0) {\r
return EFI_TIMEOUT;\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+\r
+ Routine Description: Determine whether FDC is ready to write or read.\r
+ \r
+ @param FdcDev Pointer to instance of FDC_BLK_IO_DEV\r
+ @param Dio BOOLEAN: Indicate the FDC is waiting to write or read\r
+ @param TimeoutInSeconds UINTN: The time period for waiting\r
+ \r
+ @retval EFI_SUCCESS: FDC is ready to write or read\r
+ @retval EFI_NOT_READY: FDC is not ready within the specified time period\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
// Stall for 50 us\r
//\r
Delay = Delay - 1;\r
- } while (Delay);\r
+ } while (Delay > 0);\r
\r
if (Delay == 0) {\r
return EFI_NOT_READY;\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Set FDC control structure's attribute according to result. \r
+\r
+ @param Result Point to result structure\r
+ @param FdcDev FDC control structure\r
+\r
+ @retval EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
+ @retval EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
+ @retval EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
+ @retval EFI_SUCCESS - GC_TODO: Add description for return value\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
// Check Status Register1\r
//\r
- if (Result->Status1 & (STS1_EN | STS1_DE | STS1_OR | STS1_ND | STS1_NW | STS1_MA)) {\r
+ if ((Result->Status1 & (STS1_EN | STS1_DE | STS1_OR | STS1_ND | STS1_NW | STS1_MA)) != 0) {\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
+ if ((Result->Status2 & (STS2_CM | STS2_DD | STS2_WC | STS2_BC | STS2_MD)) != 0) {\r
FdcDev->ControllerState->NeedRecalibrate = TRUE;\r
return EFI_DEVICE_ERROR;\r
}\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Check the drive status information.\r
+ \r
+ @param StatusRegister3 the value of Status Register 3\r
+ \r
+ @retval EFI_SUCCESS The disk is not write protected\r
+ @retval EFI_WRITE_PROTECTED: The disk is write protected\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
+ if ((StatusRegister3 & STS3_WP) != 0) {\r
return EFI_WRITE_PROTECTED;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Calculate the number of block in the same cylinder according to LBA.\r
+ \r
+ @param FdcDev FDC_BLK_IO_DEV *: A pointer to FDC_BLK_IO_DEV\r
+ @param LBA EFI_LBA: The starting logic block address\r
+ @param NumberOfBlocks UINTN: The number of blocks\r
+ \r
+ @return The number of blocks in the same cylinder which the starting\r
+ logic block address is LBA\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
}\r
}\r
\r
+/**\r
+ When the Timer(2s) off, turn the drive's motor off.\r
+ \r
+ @param Event EFI_EVENT: Event(the timer) whose notification function is being\r
+ invoked\r
+ @param Context VOID *: Pointer to the notification function's context\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
+ 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
+ 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
+ if (((FdcDev->Disk == FdcDisk0) && ((Data & 0x10) != 0x10)) ||\r
+ ((FdcDev->Disk == FdcDisk1) && ((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
+ Data = 0x0C;\r
+ Data = (UINT8) (Data | (SELECT_DRV & FdcDev->Disk));\r
+ FdcWritePort (FdcDev, FDC_REGISTER_DOR, Data);\r
MicroSecondDelay (500);\r
}\r
\r
+/**\r
+ Read an I/O port of FDC.\r
+ \r
+ @param[in] FdcDev A pointer to FDC_BLK_IO_DEV.\r
+ @param[in] Offset The address offset of the I/O port.\r
+\r
+ @retval 8-bit data read from the I/O port.\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
+ EFI_STATUS Status;\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
+ Status = FdcDev->IsaIo->Io.Read (\r
+ FdcDev->IsaIo,\r
+ EfiIsaIoWidthUint8,\r
+ FdcDev->BaseAddress + Offset,\r
+ 1,\r
+ &Data\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
\r
return Data;\r
}\r
\r
+/**\r
+ Write an I/O port of FDC.\r
+ \r
+ @param[in] FdcDev A pointer to FDC_BLK_IO_DEV\r
+ @param[in] Offset The address offset of the I/O port\r
+ @param[in] Data 8-bit Value written to the I/O port\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
+ EFI_STATUS Status;\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
+ Status = FdcDev->IsaIo->Io.Write (\r
+ FdcDev->IsaIo,\r
+ EfiIsaIoWidthUint8,\r
+ FdcDev->BaseAddress + Offset,\r
+ 1,\r
+ &Data\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
}\r
+\r