#include <Library/UefiRuntimeServicesTableLib.h>\r
#include <Library/DevicePathLib.h>\r
\r
-#include <IndustryStandard/Pci22.h>\r
+#include <Guid/EventGroup.h>\r
+\r
+#include <IndustryStandard/Pci.h>\r
#include "IdeData.h"\r
\r
+//\r
+// Global Variables\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding;\r
+extern EFI_DRIVER_DIAGNOSTICS_PROTOCOL gIDEBusDriverDiagnostics;\r
+extern EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gIDEBusDriverDiagnostics2;\r
+\r
//\r
// Extra Definition to porting\r
//\r
#define ATA_DEVICE_TYPE 0x00\r
#define ATAPI_DEVICE_TYPE 0x01\r
\r
-#define EFI_IOB_ATA_BUS_SMART_ENABLE (EFI_SUBCLASS_SPECIFIC | 0x00000000)\r
-#define EFI_IOB_ATA_BUS_SMART_DISABLE (EFI_SUBCLASS_SPECIFIC | 0x00000001)\r
-#define EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD (EFI_SUBCLASS_SPECIFIC | 0x00000002)\r
-#define EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD (EFI_SUBCLASS_SPECIFIC | 0x00000003)\r
-\r
typedef struct {\r
BOOLEAN HaveScannedDevice[MAX_IDE_DEVICE];\r
BOOLEAN DeviceFound[MAX_IDE_DEVICE];\r
IDE_BASE_REGISTERS *IoPort;\r
UINT16 AtapiError;\r
\r
- ATAPI_INQUIRY_DATA *pInquiryData;\r
- EFI_IDENTIFY_DATA *pIdData;\r
+ ATAPI_INQUIRY_DATA *InquiryData;\r
+ EFI_IDENTIFY_DATA *IdData;\r
ATA_PIO_MODE PioMode;\r
EFI_ATA_MODE UdmaMode;\r
CHAR8 ModelName[41];\r
#define IDE_BLOCK_IO_DEV_FROM_THIS(a) CR (a, IDE_BLK_IO_DEV, BlkIo, IDE_BLK_IO_DEV_SIGNATURE)\r
#define IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS(a) CR (a, IDE_BLK_IO_DEV, DiskInfo, IDE_BLK_IO_DEV_SIGNATURE)\r
\r
-//\r
-// Global Variables\r
-//\r
-extern EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding;\r
-extern EFI_DRIVER_DIAGNOSTICS_PROTOCOL gIDEBusDriverDiagnostics;\r
-extern EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gIDEBusDriverDiagnostics2;\r
-\r
#include "Ide.h"\r
\r
-//\r
-// Prototypes\r
-// Driver model protocol interface\r
-//\r
-/**\r
- TODO: Add function description\r
-\r
- @param ImageHandle TODO: add argument description\r
- @param SystemTable TODO: add argument description\r
-\r
- TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusControllerDriverEntryPoint (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- );\r
\r
/**\r
- TODO: Add function description\r
+ Supported function of Driver Binding protocol for this driver.\r
\r
- @param This TODO: add argument description\r
- @param Controller TODO: add argument description\r
- @param RemainingDevicePath TODO: add argument description\r
+ @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param ControllerHandle The handle of the controller to test.\r
+ @param RemainingDevicePath A pointer to the remaining portion of a device path.\r
\r
- TODO: add return values.\r
+ @retval EFI_SUCCESS Driver loaded.\r
+ @retval other Driver not loaded.\r
\r
**/\r
EFI_STATUS\r
);\r
\r
/**\r
- TODO: Add function description\r
+ Start function of Driver binding protocol which start this driver on Controller\r
+ by detecting all disks and installing BlockIo protocol on them.\r
\r
- @param This TODO: add argument description\r
- @param Controller TODO: add argument description\r
- @param RemainingDevicePath TODO: add argument description\r
+ @param This Protocol instance pointer.\r
+ @param Controller Handle of device to bind driver to.\r
+ @param RemainingDevicePath produce all possible children.\r
\r
- TODO: add return values.\r
+ @retval EFI_SUCCESS This driver is added to ControllerHandle.\r
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
+ @retval other This driver does not support this device.\r
\r
**/\r
EFI_STATUS\r
);\r
\r
/**\r
- TODO: Add function description\r
+ Stop function of Driver Binding Protocol which is to stop the driver on Controller Handle and all\r
+ child handle attached to the controller handle if there are.\r
\r
- @param This TODO: add argument description\r
- @param Controller TODO: add argument description\r
- @param NumberOfChildren TODO: add argument description\r
- @param ChildHandleBuffer TODO: add argument description\r
+ @param This Protocol instance pointer.\r
+ @param Controller Handle of device to stop driver on\r
+ @param NumberOfChildren Not used\r
+ @param ChildHandleBuffer Not used\r
\r
- TODO: add return values.\r
+ @retval EFI_SUCCESS This driver is removed DeviceHandle\r
+ @retval other This driver was not removed from this device\r
\r
**/\r
EFI_STATUS\r
// EFI Driver Configuration Functions\r
//\r
/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param ControllerHandle TODO: add argument description\r
- @param ChildHandle TODO: add argument description\r
- @param Language TODO: add argument description\r
- @param ActionRequired TODO: add argument description\r
-\r
- TODO: add return values.\r
-\r
+ Allows the user to set controller specific options for a controller that a \r
+ driver is currently managing.\r
+\r
+ @param This A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.\r
+ @param ControllerHandle The handle of the controller to set options on.\r
+ @param ChildHandle The handle of the child controller to set options on.\r
+ This is an optional parameter that may be NULL.\r
+ It will be NULL for device drivers, and for a bus drivers\r
+ that wish to set options for the bus controller.\r
+ It will not be NULL for a bus driver that wishes to set\r
+ options for one of its child controllers.\r
+ @param Language A pointer to a three character ISO 639-2 language identifier. \r
+ This is the language of the user interface that should be presented \r
+ to the user, and it must match one of the languages specified in \r
+ SupportedLanguages. The number of languages supported by a driver is up to\r
+ the driver writer.\r
+ @param ActionRequired A pointer to the action that the calling agent is required \r
+ to perform when this function returns.\r
+ \r
+\r
+ @retval EFI_SUCCESS The driver specified by This successfully set the configuration \r
+ options for the controller specified by ControllerHandle..\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ActionRequired is NULL.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support setting configuration options for \r
+ the controller specified by ControllerHandle and ChildHandle.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the language specified by Language.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempt to set the configuration options for the \r
+ controller specified by ControllerHandle and ChildHandle.\r
+ @retval EFI_OUT_RESOURCES There are not enough resources available to set the configuration options for the \r
+ controller specified by ControllerHandle and ChildHandle\r
**/\r
EFI_STATUS\r
+EFIAPI\r
IDEBusDriverConfigurationSetOptions (\r
IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
);\r
\r
/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param ControllerHandle TODO: add argument description\r
- @param ChildHandle TODO: add argument description\r
-\r
- TODO: add return values.\r
-\r
+ Tests to see if a controller's current configuration options are valid.\r
+\r
+ @param This A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL instance.\r
+ @param ControllerHandle The handle of the controller to test if it's current configuration options \r
+ are valid.\r
+ @param ChildHandle The handle of the child controller to test if it's current configuration \r
+ options are valid. This is an optional parameter that may be NULL. It will \r
+ be NULL for device drivers. It will also be NULL for a bus drivers that\r
+ wish to test the configuration options for the bus controller. It will \r
+ not be NULL for a bus driver that wishes to test configuration options for \r
+ one of its child controllers.\r
+ @retval EFI_SUCCESS The controller specified by ControllerHandle and ChildHandle that is being\r
+ managed by the driver specified by This has a valid set of configuration\r
+ options.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently managing the controller \r
+ specified by ControllerHandle and ChildHandle.\r
+ @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and ChildHandle that is being\r
+ managed by the driver specified by This has an invalid set of configuration\r
+ options.\r
**/\r
EFI_STATUS\r
+EFIAPI\r
IDEBusDriverConfigurationOptionsValid (\r
IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
);\r
\r
/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param ControllerHandle TODO: add argument description\r
- @param ChildHandle TODO: add argument description\r
- @param DefaultType TODO: add argument description\r
- @param ActionRequired TODO: add argument description\r
-\r
- TODO: add return values.\r
-\r
+ Forces a driver to set the default configuration options for a controller.\r
+\r
+ @param This A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.\r
+ @param ControllerHandle The handle of the controller to force default configuration options on.\r
+ @param ChildHandle The handle of the child controller to force default configuration \r
+ options on This is an optional parameter that may be NULL. It \r
+ will be NULL for device drivers. It will also be NULL for a bus \r
+ drivers that wish to force default configuration options for the bus\r
+ controller. It will not be NULL for a bus driver that wishes to force\r
+ default configuration options for one of its child controllers.\r
+ @param DefaultType The type of default configuration options to force on the controller \r
+ specified by ControllerHandle and ChildHandle. \r
+ @param ActionRequired A pointer to the action that the calling agent is required to perform \r
+ when this function returns.\r
+\r
+ @retval EFI_SUCCESS The driver specified by This successfully forced the \r
+ default configuration options on the controller specified by \r
+ ControllerHandle and ChildHandle.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ActionRequired is NULL.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support forcing the default \r
+ configuration options on the controller specified by ControllerHandle\r
+ and ChildHandle.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the configuration type \r
+ specified by DefaultType.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempt to force the default configuration \r
+ options on the controller specified by ControllerHandle and ChildHandle.\r
+ @retval EFI_OUT_RESOURCES There are not enough resources available to force the default configuration \r
+ options on the controller specified by ControllerHandle and ChildHandle.\r
**/\r
EFI_STATUS\r
+EFIAPI\r
IDEBusDriverConfigurationForceDefaults (\r
IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
// EFI Driver Diagnostics Functions\r
//\r
/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param ControllerHandle TODO: add argument description\r
- @param ChildHandle TODO: add argument description\r
- @param DiagnosticType TODO: add argument description\r
- @param Language TODO: add argument description\r
- @param ErrorType TODO: add argument description\r
- @param BufferSize TODO: add argument description\r
- @param Buffer TODO: add argument description\r
-\r
- TODO: add return values.\r
-\r
+ Runs diagnostics on a controller.\r
+\r
+ @param This A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOLinstance.\r
+ @param ControllerHandle The handle of the controller to run diagnostics on.\r
+ @param ChildHandle The handle of the child controller to run diagnostics on\r
+ This is an optional parameter that may be NULL. It will\r
+ be NULL for device drivers. It will also be NULL for a\r
+ bus drivers that wish to run diagnostics on the bus controller. \r
+ It will not be NULL for a bus driver that wishes to run \r
+ diagnostics on one of its child controllers.\r
+ @param DiagnosticType Indicates type of diagnostics to perform on the controller\r
+ specified by ControllerHandle and ChildHandle.\r
+ @param Language A pointer to a three character ISO 639-2 language identifier. \r
+ This is the language in which the optional error message should \r
+ be returned in Buffer, and it must match one of the languages \r
+ specified in SupportedLanguages. The number of languages supported by\r
+ a driver is up to the driver writer.\r
+ @param ErrorType A GUID that defines the format of the data returned in Buffer.\r
+ @param BufferSize The size, in bytes, of the data returned in Buffer.\r
+ @param Buffer A buffer that contains a Null-terminated Unicode string\r
+ plus some additional data whose format is defined by ErrorType. \r
+ Buffer is allocated by this function with AllocatePool(), and \r
+ it is the caller's responsibility to free it with a call to FreePool().\r
+\r
+ @retval EFI_SUCCESS The controller specified by ControllerHandle and ChildHandle passed \r
+ the diagnostic.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+ @retval EFI_INVALID_PARAMETER ErrorType is NULL.\r
+ @retval EFI_INVALID_PARAMETER BufferType is NULL.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support running \r
+ diagnostics for the controller specified by ControllerHandle \r
+ and ChildHandle.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
+ type of diagnostic specified by DiagnosticType.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the language \r
+ specified by Language.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to complete the \r
+ diagnostics.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to return the \r
+ status information in ErrorType, BufferSize,and Buffer.\r
+ @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and ChildHandle \r
+ did not pass the diagnostic.\r
**/\r
EFI_STATUS\r
+EFIAPI\r
IDEBusDriverDiagnosticsRunDiagnostics (\r
IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
OUT CHAR16 **Buffer\r
);\r
\r
-//\r
-// Block I/O Protocol Interface\r
-//\r
/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param ExtendedVerification TODO: add argument description\r
+ issue ATA or ATAPI command to reset a block IO device.\r
+ @param This Block IO protocol instance pointer.\r
+ @param ExtendedVerification If FALSE,for ATAPI device, driver will only invoke ATAPI reset method\r
+ If TRUE, for ATAPI device, driver need invoke ATA reset method after\r
+ invoke ATAPI reset method\r
\r
- TODO: add return values.\r
+ @retval EFI_DEVICE_ERROR When the device is neighther ATA device or ATAPI device.\r
+ @retval EFI_SUCCESS The device reset successfully\r
\r
**/\r
EFI_STATUS\r
);\r
\r
/**\r
- TODO: Add function description\r
+ Read data from a block IO device.\r
\r
- @param This TODO: add argument description\r
- @param MediaId TODO: add argument description\r
- @param LBA TODO: add argument description\r
- @param BufferSize TODO: add argument description\r
- @param Buffer TODO: add argument description\r
+ @param This Block IO protocol instance pointer.\r
+ @param MediaId The media ID of the device\r
+ @param Lba Starting LBA address to read data\r
+ @param BufferSize The size of data to be read\r
+ @param Buffer Caller supplied buffer to save data\r
\r
- TODO: add return values.\r
+ @retval EFI_DEVICE_ERROR unknown device type\r
+ @retval EFI_SUCCESS read the data successfully.\r
\r
**/\r
EFI_STATUS\r
IDEBlkIoReadBlocks (\r
IN EFI_BLOCK_IO_PROTOCOL *This,\r
IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
+ IN EFI_LBA Lba,\r
IN UINTN BufferSize,\r
OUT VOID *Buffer\r
);\r
\r
/**\r
- TODO: Add function description\r
+ Write data to block io device\r
\r
- @param This TODO: add argument description\r
- @param MediaId TODO: add argument description\r
- @param LBA TODO: add argument description\r
- @param BufferSize TODO: add argument description\r
- @param Buffer TODO: add argument description\r
+ @param This Protocol instance pointer.\r
+ @param MediaId The media ID of the device\r
+ @param Lba Starting LBA address to write data\r
+ @param BufferSize The size of data to be written\r
+ @param Buffer Caller supplied buffer to save data\r
\r
- TODO: add return values.\r
+ @retval EFI_DEVICE_ERROR unknown device type\r
+ @retval other write data status\r
\r
**/\r
EFI_STATUS\r
IDEBlkIoWriteBlocks (\r
IN EFI_BLOCK_IO_PROTOCOL *This,\r
IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
+ IN EFI_LBA Lba,\r
IN UINTN BufferSize,\r
IN VOID *Buffer\r
);\r
\r
/**\r
- TODO: Add function description\r
+ Flushes all modified data to a physical block devices\r
\r
- @param This TODO: add argument description\r
-\r
- TODO: add return values.\r
+ @param This Indicates a pointer to the calling context which to sepcify a \r
+ sepcific block device\r
\r
+ @retval EFI_SUCCESS Always return success.\r
**/\r
EFI_STATUS\r
EFIAPI\r
IDEBlkIoFlushBlocks (\r
IN EFI_BLOCK_IO_PROTOCOL *This\r
);\r
-\r
/**\r
- TODO: Add function description\r
+ This function is used by the IDE bus driver to get inquiry data. \r
+ Data format of Identify data is defined by the Interface GUID.\r
\r
- @param PciIo TODO: add argument description\r
- @param Enable TODO: add argument description\r
+ @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
+ @param InquiryData Pointer to a buffer for the inquiry data.\r
+ @param InquiryDataSize Pointer to the value for the inquiry data size.\r
\r
- TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-IDERegisterDecodeEnableorDisable (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN BOOLEAN Enable\r
- );\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param InquiryData TODO: add argument description\r
- @param IntquiryDataSize TODO: add argument description\r
-\r
- TODO: add return values.\r
+ @retval EFI_SUCCESS The command was accepted without any errors.\r
+ @retval EFI_NOT_FOUND Device does not support this data class \r
+ @retval EFI_DEVICE_ERROR Error reading InquiryData from device \r
+ @retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough \r
\r
**/\r
EFI_STATUS\r
IDEDiskInfoInquiry (\r
IN EFI_DISK_INFO_PROTOCOL *This,\r
IN OUT VOID *InquiryData,\r
- IN OUT UINT32 *IntquiryDataSize\r
+ IN OUT UINT32 *InquiryDataSize\r
);\r
\r
/**\r
- TODO: Add function description\r
+ This function is used by the IDE bus driver to get identify data. \r
+ Data format of Identify data is defined by the Interface GUID.\r
\r
- @param This TODO: add argument description\r
- @param IdentifyData TODO: add argument description\r
- @param IdentifyDataSize TODO: add argument description\r
+ @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
+ @param IdentifyData Pointer to a buffer for the identify data.\r
+ @param IdentifyDataSize Pointer to the value for the identify data size.\r
\r
- TODO: add return values.\r
+ @retval EFI_SUCCESS The command was accepted without any errors.\r
+ @retval EFI_NOT_FOUND Device does not support this data class \r
+ @retval EFI_DEVICE_ERROR Error reading IdentifyData from device \r
+ @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough \r
\r
**/\r
EFI_STATUS\r
);\r
\r
/**\r
- TODO: Add function description\r
+ This function is used by the IDE bus driver to get sense data. \r
+ Data format of Sense data is defined by the Interface GUID.\r
\r
- @param This TODO: add argument description\r
- @param SenseData TODO: add argument description\r
- @param SenseDataSize TODO: add argument description\r
- @param SenseDataNumber TODO: add argument description\r
+ @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance. \r
+ @param SenseData Pointer to the SenseData. \r
+ @param SenseDataSize Size of SenseData in bytes. \r
+ @param SenseDataNumber Pointer to the value for the identify data size.\r
\r
- TODO: add return values.\r
+ @retval EFI_SUCCESS The command was accepted without any errors.\r
+ @retval EFI_NOT_FOUND Device does not support this data class \r
+ @retval EFI_DEVICE_ERROR Error reading InquiryData from device \r
+ @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough \r
\r
**/\r
EFI_STATUS\r
);\r
\r
/**\r
- TODO: Add function description\r
+ This function is used by the IDE bus driver to get controller information.\r
\r
- @param This TODO: add argument description\r
- @param IdeChannel TODO: add argument description\r
- @param IdeDevice TODO: add argument description\r
+ @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance. \r
+ @param IdeChannel Pointer to the Ide Channel number. Primary or secondary.\r
+ @param IdeDevice Pointer to the Ide Device number. Master or slave.\r
\r
- TODO: add return values.\r
+ @retval EFI_SUCCESS IdeChannel and IdeDevice are valid \r
+ @retval EFI_UNSUPPORTED This is not an IDE device \r
\r
**/\r
EFI_STATUS\r
OUT UINT32 *IdeChannel,\r
OUT UINT32 *IdeDevice\r
);\r
+/**\r
+ The is an event(generally the event is exitBootService event) call back function. \r
+ Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.\r
+\r
+ @param Event Pointer to this event\r
+ @param Context Event hanlder private data\r
\r
+**/\r
+VOID\r
+EFIAPI\r
+ClearInterrupt (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
#endif\r