/** @file\r
- This file implement UEFI driver for IDE Bus which includes device identification, \r
- Child device(Disk, CDROM, etc) enumeration and child handler installation, and \r
+ This file implement UEFI driver for IDE Bus which includes device identification,\r
+ Child device(Disk, CDROM, etc) enumeration and child handler installation, and\r
driver stop.\r
- \r
- Copyright (c) 2006 - 2009, Intel Corporation\r
- All rights reserved. This program and the accompanying materials\r
+\r
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ 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
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
EFI_DEV_PATH *Node;\r
EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ PCI_TYPE00 PciData;\r
\r
if (RemainingDevicePath != NULL) {\r
Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
//\r
- // Check if RemainingDevicePath is the End of Device Path Node, \r
+ // Check if RemainingDevicePath is the End of Device Path Node,\r
// if yes, go on checking other conditions\r
//\r
if (!IsDevicePathEnd (Node)) {\r
//\r
// Verify the Ide Controller Init Protocol, which installed by the\r
// IdeController module.\r
- // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't\r
- // open BY_DRIVER here) That's why we don't check pciio protocol\r
- // Note 2: ide_init driver check ide controller's pci config space, so we dont\r
- // check here any more to save code size\r
//\r
Status = gBS->OpenProtocol (\r
Controller,\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
//\r
- // If protocols were opened normally, closed it\r
+ // Close the I/O Abstraction(s) used to perform the supported test\r
//\r
gBS->CloseProtocol (\r
Controller,\r
Controller\r
);\r
\r
+ //\r
+ // Get the EfiPciIoProtocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Now further check the PCI header: Base class (offset 0x0B) and\r
+ // Sub Class (offset 0x0A). This controller should be an IDE controller\r
+ //\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ 0,\r
+ sizeof (PciData),\r
+ &PciData\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Examine if it is IDE mode by class code\r
+ //\r
+ if ((PciData.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE) || (PciData.Hdr.ClassCode[1] != PCI_SUB_CLASS_IDE)) {\r
+ Status = EFI_UNSUPPORTED;\r
+ } else {\r
+ Status = EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
return Status;\r
}\r
\r
&Supports\r
);\r
if (!EFI_ERROR (Status)) {\r
- Supports &= EFI_PCI_DEVICE_ENABLE;\r
+ Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;\r
Status = PciIo->Attributes (\r
PciIo,\r
EfiPciIoAttributeOperationEnable,\r
\r
if (EnumAll || RemainingDevicePath == NULL) {\r
//\r
- // If IdeInit->EnumAll is TRUE or RemainingDevicePath is NULL, \r
- // must enumerate all IDE device anyway\r
+ // If IdeInit->EnumAll is TRUE or RemainingDevicePath is NULL,\r
+ // must enumerate all IDE devices anyway\r
//\r
BeginningIdeChannel = IdePrimary;\r
EndIdeChannel = IdeSecondary;\r
\r
} else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
//\r
- // RemainingDevicePath is the End of Device Path Node, \r
- // only scan the specified device by RemainingDevicePath.\r
+ // If RemainingDevicePath isn't the End of Device Path Node,\r
+ // only scan the specified device by RemainingDevicePath\r
//\r
Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
BeginningIdeChannel = Node->Atapi.PrimarySecondary;\r
\r
} else {\r
//\r
- // If RemainingDevicePath is not the End of Device Path Node,\r
+ // If RemainingDevicePath is the End of Device Path Node,\r
// skip enumerate any device and return EFI_SUCESSS\r
- // \r
+ //\r
BeginningIdeChannel = IdeMaxChannel;\r
EndIdeChannel = IdeMaxChannel - 1;\r
BeginningIdeDevice = IdeMaxDevice;\r
//\r
for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
\r
+ ASSERT (IdeChannel * 2 + IdeDevice < MAX_IDE_DEVICE);\r
if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {\r
continue;\r
}\r
continue;\r
}\r
\r
+ ASSERT (IdeChannel < IdeMaxChannel && IdeDevice < IdeMaxDevice);\r
IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
\r
//\r
//\r
// Init driver parameters\r
//\r
- DriveParameters.Sector = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.sectors_per_track;\r
- DriveParameters.Heads = (UINT8) (IdeBlkIoDevicePtr->IdData->AtaData.heads - 1);\r
+ DriveParameters.Sector = (UINT8) ((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->sectors_per_track;\r
+ DriveParameters.Heads = (UINT8) (((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->heads - 1);\r
DriveParameters.MultipleSector = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.multi_sector_cmd_max_sct_cnt;\r
//\r
// Set Parameters for the device:\r
&Supports\r
);\r
if (!EFI_ERROR (Status)) {\r
- Supports &= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;\r
+ Supports &= (UINT64)(EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE);\r
PciIo->Attributes (\r
PciIo,\r
EfiPciIoAttributeOperationDisable,\r
}\r
\r
/**\r
- This function is used by the IDE bus driver to get inquiry data. \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 This Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
@param InquiryDataSize Pointer to the value for the inquiry data size.\r
\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
+ @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
}\r
\r
/**\r
- This function is used by the IDE bus driver to get identify data. \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 Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
@param IdentifyDataSize Pointer to the value for the identify data size.\r
\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
+ @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
- This function is used by the IDE bus driver to get sense data. \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 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 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
@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
+ @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
This function is used by the IDE bus driver to get controller information.\r
\r
- @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance. \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
- @retval EFI_SUCCESS IdeChannel and IdeDevice are valid \r
- @retval EFI_UNSUPPORTED This is not an IDE device \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
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
+ @param Context Event handler private data\r
\r
**/\r
VOID\r
// Reset IDE device to force it de-assert interrupt pin\r
// Note: this will reset all devices on this IDE channel\r
//\r
- AtaSoftReset (IdeDev);\r
+ Status = AtaSoftReset (IdeDev);\r
if (EFI_ERROR (Status)) {\r
return;\r
}\r