3 Copyright (c) 2006 - 2007 Intel Corporation. All rights reserved
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 This driver module produces IDE_CONTROLLER_INIT protocol and will be used by
20 IDE Bus driver to support platform dependent timing information. This driver
21 is responsible for early initialization of IDE controller.
26 #include "IdeController.h"
30 // IDE Controller Init Guid
33 gIdeControllerDriverGuid
= { 0x91e365e9, 0xe0c0, 0x4647, 0xb0, 0xeb, 0xf6, 0x78, 0xf6, 0x21, 0xf8, 0x8d };
36 // EFI_DRIVER_BINDING_PROTOCOL instance
38 EFI_DRIVER_BINDING_PROTOCOL gIdeControllerDriverBinding
= {
39 IdeControllerSupported
,
48 // Internal function definitions
51 EnableNativeIdeDecode (
52 IN EFI_PCI_IO_PROTOCOL
*PciIo
56 EnableLegacyIdeDecode (
65 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
66 IN EFI_IDENTIFY_DATA
*IdentifyData
70 AdjustUdmaModeByCableType (
73 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
74 IN OUT EFI_ATA_COLLECTIVE_MODE
*Modes
78 CalculateBestPioMode (
79 IN EFI_IDENTIFY_DATA
* IdentifyData
,
80 IN UINT16
*DisPioMode OPTIONAL
,
81 OUT UINT16
*SelectedMode
85 CalculateBestUdmaMode (
86 IN EFI_IDENTIFY_DATA
* IdentifyData
,
87 IN UINT16
*DisUDmaMode OPTIONAL
,
88 OUT UINT16
*SelectedMode
92 IdeInitSetUdmaTiming (
95 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
96 IN EFI_ATA_COLLECTIVE_MODE
*Modes
100 IdeInitSetPioTiming (
103 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
104 IN EFI_IDENTIFY_DATA
*IdentifyData
,
105 IN EFI_ATA_COLLECTIVE_MODE
*Modes
109 // *************************************
110 // IdeController Driver Entry Point
111 // *************************************
115 InitializeIdeControllerDriver (
116 IN EFI_HANDLE ImageHandle
,
117 IN EFI_SYSTEM_TABLE
*SystemTable
122 Chipset Ide Driver EntryPoint function. It follows the standard EFI driver
123 model. It's called by StartImage() of DXE Core
127 ImageHnadle -- While the driver image loaded be the ImageLoader(),
128 an image handle is assigned to this driver binary,
129 all activities of the driver is tied to this ImageHandle
130 *SystemTable -- A pointer to the system table, for all BS(Boo Services) and
135 Always call EfiLibInstallDriverBindingProtocol( ) and retrun the result
140 return EfiLibInstallDriverBindingComponentName2 (
143 &gIdeControllerDriverBinding
,
152 IdeControllerSupported (
153 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
154 IN EFI_HANDLE Controller
,
155 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
161 Register Driver Binding protocol for this driver.
165 This -- a pointer points to the Binding Protocol instance
166 Controller -- The handle of controller to be tested.
167 *RemainingDevicePath -- A pointer to the device path. Ignored by device
168 driver but used by bus driver
172 EFI_SUCCESS -- Driver loaded.
173 other -- Driver not loaded.
177 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
178 EFI_PCI_IO_PROTOCOL
*PciIo
;
182 // Ide Controller is a device driver, and should ingore the
183 // "RemainingDevicePath" according to EFI spec
185 Status
= gBS
->OpenProtocol (
187 &gEfiDevicePathProtocolGuid
,
188 (VOID
*) &ParentDevicePath
,
189 This
->DriverBindingHandle
,
191 EFI_OPEN_PROTOCOL_BY_DRIVER
193 if (EFI_ERROR (Status
)) {
195 // EFI_ALREADY_STARTED is also an error
200 // Close the protocol because we don't use it here
204 &gEfiDevicePathProtocolGuid
,
205 This
->DriverBindingHandle
,
210 // Now test the EfiPciIoProtocol
212 Status
= gBS
->OpenProtocol (
214 &gEfiPciIoProtocolGuid
,
216 This
->DriverBindingHandle
,
218 EFI_OPEN_PROTOCOL_BY_DRIVER
220 if (EFI_ERROR (Status
)) {
224 // Now further check the PCI header: Base class (offset 0x0B) and
225 // Sub Class (offset 0x0A). This controller should be an Ide controller
227 Status
= PciIo
->Pci
.Read (
235 if (EFI_ERROR (Status
)) {
238 &gEfiPciIoProtocolGuid
,
239 This
->DriverBindingHandle
,
242 return EFI_UNSUPPORTED
;
245 // Examine Ide PCI Configuration table fields
247 if ((PciData
.Hdr
.ClassCode
[2] != PCI_CLASS_MASS_STORAGE
) ||
248 (PciData
.Hdr
.ClassCode
[1] != PCI_SUB_CLASS_IDE
)
251 Status
= EFI_UNSUPPORTED
;
256 &gEfiPciIoProtocolGuid
,
257 This
->DriverBindingHandle
,
267 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
268 IN EFI_HANDLE Controller
,
269 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
275 This routine is called right after the .Supported() called and return
276 EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols
281 This -- a pointer points to the Binding Protocol instance
282 Controller -- The handle of controller to be tested. Parameter
284 *RemainingDevicePath -- A pointer to the device path. Should be ignored by
289 EFI_PCI_IO_PROTOCOL
*PciIo
;
290 EFI_IDE_CONTROLLER_PRIVATE_DATA
*IdePrivateData
;
293 // Now test and open the EfiPciIoProtocol
295 Status
= gBS
->OpenProtocol (
297 &gEfiPciIoProtocolGuid
,
299 This
->DriverBindingHandle
,
301 EFI_OPEN_PROTOCOL_BY_DRIVER
305 // Status == 0 - A normal execution flow, SUCCESS and the program proceeds.
306 // Status == ALREADY_STARTED - A non-zero Status code returned. It indicates
307 // that the protocol has been opened and should be treated as a
308 // normal condition and the program proceeds. The Protocol will not
309 // opened 'again' by this call.
310 // Status != ALREADY_STARTED - Error status, terminate program execution
312 if (EFI_ERROR (Status
)) {
314 // EFI_ALREADY_STARTED is also an error
319 // Allocate Ide private data structure
321 Status
= gBS
->AllocatePool (
323 sizeof (EFI_IDE_CONTROLLER_PRIVATE_DATA
),
324 (VOID
**) &IdePrivateData
326 if (EFI_ERROR (Status
)) {
327 return EFI_OUT_OF_RESOURCES
;
330 // Initialize Ide controller private data
332 ZeroMem (IdePrivateData
, sizeof (EFI_IDE_CONTROLLER_PRIVATE_DATA
));
333 IdePrivateData
->Signature
= IDE_CONTROLLER_SIGNATURE
;
334 IdePrivateData
->PciIo
= PciIo
;
335 IdePrivateData
->IdeInit
.GetChannelInfo
= IdeInitGetChannelInfo
;
336 IdePrivateData
->IdeInit
.NotifyPhase
= IdeInitNotifyPhase
;
337 IdePrivateData
->IdeInit
.SubmitData
= IdeInitSubmitData
;
338 IdePrivateData
->IdeInit
.DisqualifyMode
= IdeInitDisqualifyMode
;
339 IdePrivateData
->IdeInit
.CalculateMode
= IdeInitCalculateMode
;
340 IdePrivateData
->IdeInit
.SetTiming
= IdeInitSetTiming
;
341 IdePrivateData
->IdeInit
.EnumAll
= ICH_IDE_ENUMER_ALL
;
342 IdePrivateData
->IdeInit
.ChannelCount
= ICH_IDE_MAX_CHANNEL
;
345 // Install IDE_CONTROLLER_INIT protocol & private data to this instance
347 Status
= gBS
->InstallMultipleProtocolInterfaces (
349 &gIdeControllerDriverGuid
,
351 &gEfiIdeControllerInitProtocolGuid
,
352 &(IdePrivateData
->IdeInit
),
362 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
363 IN EFI_HANDLE Controller
,
364 IN UINTN NumberOfChildren
,
365 IN EFI_HANDLE
*ChildHandleBuffer
370 Stop this driver on Controller Handle.
373 This - Protocol instance pointer.
374 Controller - Handle of device to stop driver on
375 NumberOfChildren - Not used
376 ChildHandleBuffer - Not used
379 EFI_SUCCESS - This driver is removed DeviceHandle
380 other - This driver was not removed from this device
385 EFI_IDE_CONTROLLER_PRIVATE_DATA
*IdePrivateData
;
390 Status
= gBS
->OpenProtocol (
392 &gIdeControllerDriverGuid
,
393 (VOID
**) &IdePrivateData
,
394 This
->DriverBindingHandle
,
396 EFI_OPEN_PROTOCOL_GET_PROTOCOL
398 ASSERT_EFI_ERROR (Status
);
401 // Close protocols opened by Ide controller driver
403 Status
= gBS
->CloseProtocol (
405 &gEfiPciIoProtocolGuid
,
406 This
->DriverBindingHandle
,
410 gBS
->UninstallMultipleProtocolInterfaces (
412 &gIdeControllerDriverGuid
,
414 &gEfiIdeControllerInitProtocolGuid
,
415 &(IdePrivateData
->IdeInit
),
419 gBS
->FreePool (IdePrivateData
);
425 // Interface functions of IDE_CONTROLLER_INIT protocol
429 IdeInitGetChannelInfo (
430 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL
*This
,
432 OUT BOOLEAN
*Enabled
,
433 OUT UINT8
*MaxDevices
438 This function can be used to obtain information about a specified channel.
439 It's usually used by IDE Bus driver during enumeration process.
443 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
444 Channel -- Channel number (0 based, either 0 or 1)
445 Enabled -- TRUE if the channel is enabled. If the channel is disabled,
446 then it will no be enumerated.
447 MaxDevices -- The Max number of IDE devices that the bus driver can expect
448 on this channel. For ATA/ATAPI, this number is either 1 or 2.
456 // Channel number (0 based, either 0 or 1)
458 if (Channel
< ICH_IDE_MAX_CHANNEL
) {
460 *MaxDevices
= ICH_IDE_MAX_DEVICES
;
465 return EFI_INVALID_PARAMETER
;
472 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL
*This
,
473 IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase
,
480 This function is called by IdeBus driver before executing certain actions.
481 This allows IDE Controller Init to prepare for each action.
485 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
486 Phase -- phase indicator defined by IDE_CONTROLLER_INIT protocol
487 Channel -- Channel number (0 based, either 0 or 1)
499 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL
*This
,
502 IN EFI_IDENTIFY_DATA
*IdentifyData
508 This function is called by IdeBus driver to submit EFI_IDENTIFY_DATA data structure
509 obtained from IDE deivce. This structure is used to set IDE timing
513 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
514 Channel -- IDE channel number (0 based, either 0 or 1)
515 Device -- IDE device number
516 IdentifyData -- A pointer to EFI_IDENTIFY_DATA data structure
527 IdeInitDisqualifyMode (
528 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL
*This
,
531 IN EFI_ATA_COLLECTIVE_MODE
*BadModes
537 This function is called by IdeBus driver to disqualify unsupported operation
538 mode on specfic IDE device
542 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
543 Channel -- IDE channel number (0 based, either 0 or 1)
544 Device -- IDE device number
545 BadModes -- Operation mode indicator
556 IdeInitCalculateMode (
557 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL
*This
,
560 OUT EFI_ATA_COLLECTIVE_MODE
**SupportedModes
566 This function is called by IdeBus driver to calculate the best operation mode
567 supported by specific IDE device
571 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
572 Channel -- IDE channel number (0 based, either 0 or 1)
573 Device -- IDE device number
574 SupportedModes -- Modes collection supported by IDE device
580 if (Channel
>= ICH_IDE_MAX_CHANNEL
|| Device
>= ICH_IDE_MAX_DEVICES
) {
581 return EFI_INVALID_PARAMETER
;
584 *SupportedModes
= AllocateZeroPool (sizeof (EFI_ATA_COLLECTIVE_MODE
));
585 if (*SupportedModes
== NULL
) {
586 return EFI_OUT_OF_RESOURCES
;
590 // In EoE enviroment, when nothing is known about the platform hardware,
591 // just set the mode to lowest PIO mode for compatibility.
593 (*SupportedModes
)->PioMode
.Valid
= TRUE
;
594 (*SupportedModes
)->PioMode
.Mode
= AtaPioModeBelow2
;
595 (*SupportedModes
)->UdmaMode
.Valid
= FALSE
;
596 (*SupportedModes
)->SingleWordDmaMode
.Valid
= FALSE
;
597 (*SupportedModes
)->MultiWordDmaMode
.Valid
= FALSE
;
606 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL
*This
,
609 IN EFI_ATA_COLLECTIVE_MODE
*Modes
615 This function is called by IdeBus driver to set appropriate timing on IDE
616 controller according supported operation mode
620 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
621 Channel -- IDE channel number (0 based, either 0 or 1)
622 Device -- IDE device number