2 This driver module produces IDE_CONTROLLER_INIT protocol and will be used by
3 IDE Bus driver to support platform dependent timing information. This driver
4 is responsible for early initialization of IDE controller.
6 Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "IdeController.h"
20 /// EFI_DRIVER_BINDING_PROTOCOL instance
22 EFI_DRIVER_BINDING_PROTOCOL gIdeControllerDriverBinding
= {
23 IdeControllerSupported
,
32 /// EFI_IDE_CONTROLLER_PROVATE_DATA Template
34 EFI_IDE_CONTROLLER_INIT_PROTOCOL gEfiIdeControllerInit
= {
35 IdeInitGetChannelInfo
,
38 IdeInitDisqualifyMode
,
46 /// EFI_ATA_COLLECTIVE_MODE Template
48 EFI_ATA_COLLECTIVE_MODE gEfiAtaCollectiveModeTemplate
= {
50 TRUE
, ///< PioMode.Valid
54 TRUE
, ///< SingleWordDmaMode.Valid
58 FALSE
, ///< MultiWordDmaMode.Valid
62 TRUE
, ///< UdmaMode.Valid
68 Chipset Ide Driver EntryPoint function. It follows the standard EFI driver model.
69 It's called by StartImage() of DXE Core.
71 @param ImageHandle While the driver image loaded be the ImageLoader(),
72 an image handle is assigned to this driver binary,
73 all activities of the driver is tied to this ImageHandle
74 @param SystemTable A pointer to the system table, for all BS(Boo Services) and
77 @return EFI_STATUS Status of EfiLibInstallDriverBindingComponentName2().
81 InitializeIdeControllerDriver (
82 IN EFI_HANDLE ImageHandle
,
83 IN EFI_SYSTEM_TABLE
*SystemTable
89 // Install driver model protocol(s).
91 Status
= EfiLibInstallDriverBindingComponentName2 (
94 &gIdeControllerDriverBinding
,
96 &gIdeControllerComponentName
,
97 &gIdeControllerComponentName2
99 ASSERT_EFI_ERROR (Status
);
105 Register Driver Binding protocol for this driver.
107 @param This A pointer points to the Binding Protocol instance
108 @param Controller The handle of controller to be tested.
109 @param RemainingDevicePath A pointer to the device path. Ignored by device
110 driver but used by bus driver
112 @retval EFI_SUCCESS Driver loaded.
113 @retval !EFI_SUCESS Driver not loaded.
117 IdeControllerSupported (
118 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
119 IN EFI_HANDLE Controller
,
120 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
124 EFI_PCI_IO_PROTOCOL
*PciIo
;
129 // Attempt to Open PCI I/O Protocol
131 Status
= gBS
->OpenProtocol (
133 &gEfiPciIoProtocolGuid
,
135 This
->DriverBindingHandle
,
137 EFI_OPEN_PROTOCOL_BY_DRIVER
139 if (EFI_ERROR (Status
)) {
144 // Now further check the PCI header: Base class (offset 0x0B) and
145 // Sub Class (offset 0x0A). This controller should be an Ide controller
147 Status
= PciIo
->Pci
.Read (
150 PCI_CLASSCODE_OFFSET
+ 2,
154 if (EFI_ERROR (Status
)) {
158 Status
= PciIo
->Pci
.Read (
161 PCI_CLASSCODE_OFFSET
+ 1,
165 if (EFI_ERROR (Status
)) {
170 // Examine Ide PCI Configuration table fields
172 if ((PciClass
!= PCI_CLASS_MASS_STORAGE
) || (PciSubClass
!= PCI_CLASS_MASS_STORAGE_IDE
)) {
173 Status
= EFI_UNSUPPORTED
;
179 &gEfiPciIoProtocolGuid
,
180 This
->DriverBindingHandle
,
188 This routine is called right after the .Supported() called and return
189 EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols
192 @param This A pointer points to the Binding Protocol instance
193 @param Controller The handle of controller to be tested. Parameter
195 @param RemainingDevicePath A pointer to the device path. Should be ignored by
198 @return EFI_STATUS Status of InstallMultipleProtocolInterfaces()
203 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
204 IN EFI_HANDLE Controller
,
205 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
209 EFI_PCI_IO_PROTOCOL
*PciIo
;
212 // Now test and open the EfiPciIoProtocol
214 Status
= gBS
->OpenProtocol (
216 &gEfiPciIoProtocolGuid
,
218 This
->DriverBindingHandle
,
220 EFI_OPEN_PROTOCOL_BY_DRIVER
223 // Status == EFI_SUCCESS - A normal execution flow, SUCCESS and the program proceeds.
224 // Status == ALREADY_STARTED - A non-zero Status code returned. It indicates
225 // that the protocol has been opened and should be treated as a
226 // normal condition and the program proceeds. The Protocol will not
227 // opened 'again' by this call.
228 // Status != ALREADY_STARTED - Error status, terminate program execution
230 if (EFI_ERROR (Status
)) {
235 // Install IDE_CONTROLLER_INIT protocol
237 return gBS
->InstallMultipleProtocolInterfaces (
239 &gEfiIdeControllerInitProtocolGuid
, &gEfiIdeControllerInit
,
245 Stop this driver on Controller Handle.
247 @param This Protocol instance pointer.
248 @param Controller Handle of device to stop driver on
249 @param NumberOfChildren Not used
250 @param ChildHandleBuffer Not used
252 @retval EFI_SUCESS This driver is removed DeviceHandle
253 @retval !EFI_SUCCESS This driver was not removed from this device
258 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
259 IN EFI_HANDLE Controller
,
260 IN UINTN NumberOfChildren
,
261 IN EFI_HANDLE
*ChildHandleBuffer
265 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeControllerInit
;
268 // Open the produced protocol
270 Status
= gBS
->OpenProtocol (
272 &gEfiIdeControllerInitProtocolGuid
,
273 (VOID
**) &IdeControllerInit
,
274 This
->DriverBindingHandle
,
276 EFI_OPEN_PROTOCOL_GET_PROTOCOL
278 if (EFI_ERROR (Status
)) {
279 return EFI_UNSUPPORTED
;
283 // Make sure the protocol was produced by this driver
285 if (IdeControllerInit
!= &gEfiIdeControllerInit
) {
286 return EFI_UNSUPPORTED
;
290 // Uninstall the IDE Controller Init Protocol
292 Status
= gBS
->UninstallMultipleProtocolInterfaces (
294 &gEfiIdeControllerInitProtocolGuid
, &gEfiIdeControllerInit
,
297 if (EFI_ERROR (Status
)) {
302 // Close protocols opened by Ide controller driver
304 return gBS
->CloseProtocol (
306 &gEfiPciIoProtocolGuid
,
307 This
->DriverBindingHandle
,
313 // Interface functions of IDE_CONTROLLER_INIT protocol
316 This function can be used to obtain information about a specified channel.
317 It's usually used by IDE Bus driver during enumeration process.
319 @param This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
320 @param Channel Channel number (0 based, either 0 or 1)
321 @param Enabled TRUE if the channel is enabled. If the channel is disabled,
322 then it will no be enumerated.
323 @param MaxDevices The Max number of IDE devices that the bus driver can expect
324 on this channel. For ATA/ATAPI, this number is either 1 or 2.
326 @retval EFI_SUCCESS Success to get channel information
327 @retval EFI_INVALID_PARAMETER Invalid channel id.
331 IdeInitGetChannelInfo (
332 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL
*This
,
334 OUT BOOLEAN
*Enabled
,
335 OUT UINT8
*MaxDevices
339 // Channel number (0 based, either 0 or 1)
341 if (Channel
< ICH_IDE_MAX_CHANNEL
) {
343 *MaxDevices
= ICH_IDE_MAX_DEVICES
;
348 return EFI_INVALID_PARAMETER
;
352 This function is called by IdeBus driver before executing certain actions.
353 This allows IDE Controller Init to prepare for each action.
355 @param This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
356 @param Phase phase indicator defined by IDE_CONTROLLER_INIT protocol
357 @param Channel Channel number (0 based, either 0 or 1)
359 @return EFI_SUCCESS Success operation.
364 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL
*This
,
365 IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase
,
373 This function is called by IdeBus driver to submit EFI_IDENTIFY_DATA data structure
374 obtained from IDE deivce. This structure is used to set IDE timing
376 @param This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
377 @param Channel IDE channel number (0 based, either 0 or 1)
378 @param Device IDE device number
379 @param IdentifyData A pointer to EFI_IDENTIFY_DATA data structure
381 @return EFI_SUCCESS Success operation.
386 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL
*This
,
389 IN EFI_IDENTIFY_DATA
*IdentifyData
396 This function is called by IdeBus driver to disqualify unsupported operation
397 mode on specfic IDE device
399 @param This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
400 @param Channel IDE channel number (0 based, either 0 or 1)
401 @param Device IDE device number
402 @param BadModes Operation mode indicator
404 @return EFI_SUCCESS Success operation.
408 IdeInitDisqualifyMode (
409 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL
*This
,
412 IN EFI_ATA_COLLECTIVE_MODE
*BadModes
419 This function is called by IdeBus driver to calculate the best operation mode
420 supported by specific IDE device
422 @param This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
423 @param Channel IDE channel number (0 based, either 0 or 1)
424 @param Device IDE device number
425 @param SupportedModes Modes collection supported by IDE device
427 @retval EFI_OUT_OF_RESOURCES Fail to allocate pool.
428 @retval EFI_INVALID_PARAMETER Invalid channel id and device id.
432 IdeInitCalculateMode (
433 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL
*This
,
436 OUT EFI_ATA_COLLECTIVE_MODE
**SupportedModes
439 if (Channel
>= ICH_IDE_MAX_CHANNEL
|| Device
>= ICH_IDE_MAX_DEVICES
) {
440 return EFI_INVALID_PARAMETER
;
443 *SupportedModes
= AllocateCopyPool (sizeof (EFI_ATA_COLLECTIVE_MODE
), &gEfiAtaCollectiveModeTemplate
);
444 if (*SupportedModes
== NULL
) {
445 return EFI_OUT_OF_RESOURCES
;
452 This function is called by IdeBus driver to set appropriate timing on IDE
453 controller according supported operation mode.
455 @param This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
456 @param Channel IDE channel number (0 based, either 0 or 1)
457 @param Device IDE device number
458 @param Modes IDE device modes
460 @retval EFI_SUCCESS Sucess operation.
465 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL
*This
,
468 IN EFI_ATA_COLLECTIVE_MODE
*Modes