]> git.proxmox.com Git - mirror_edk2.git/blob - PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeController.c
5dfb98dc7630728725e2e478b25d5e6f1ab9b709
[mirror_edk2.git] / PcAtChipsetPkg / Bus / Pci / IdeControllerDxe / IdeController.c
1 /** @file
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.
5
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
11
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.
14
15 **/
16
17 #include "IdeController.h"
18
19 ///
20 /// EFI_DRIVER_BINDING_PROTOCOL instance
21 ///
22 EFI_DRIVER_BINDING_PROTOCOL gIdeControllerDriverBinding = {
23 IdeControllerSupported,
24 IdeControllerStart,
25 IdeControllerStop,
26 0xa,
27 NULL,
28 NULL
29 };
30
31 ///
32 /// EFI_IDE_CONTROLLER_PROVATE_DATA Template
33 ///
34 EFI_IDE_CONTROLLER_INIT_PROTOCOL gEfiIdeControllerInit = {
35 IdeInitGetChannelInfo,
36 IdeInitNotifyPhase,
37 IdeInitSubmitData,
38 IdeInitDisqualifyMode,
39 IdeInitCalculateMode,
40 IdeInitSetTiming,
41 ICH_IDE_ENUMER_ALL,
42 ICH_IDE_MAX_CHANNEL
43 };
44
45 ///
46 /// EFI_ATA_COLLECTIVE_MODE Template
47 ///
48 EFI_ATA_COLLECTIVE_MODE gEfiAtaCollectiveModeTemplate = {
49 {
50 TRUE, ///< PioMode.Valid
51 0 ///< PioMode.Mode
52 },
53 {
54 TRUE, ///< SingleWordDmaMode.Valid
55 0
56 },
57 {
58 FALSE, ///< MultiWordDmaMode.Valid
59 0
60 },
61 {
62 TRUE, ///< UdmaMode.Valid
63 0 ///< UdmaMode.Mode
64 }
65 };
66
67 /**
68 Chipset Ide Driver EntryPoint function. It follows the standard EFI driver model.
69 It's called by StartImage() of DXE Core.
70
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
75 RT(Runtime Services)
76
77 @return EFI_STATUS Status of EfiLibInstallDriverBindingComponentName2().
78 **/
79 EFI_STATUS
80 EFIAPI
81 InitializeIdeControllerDriver (
82 IN EFI_HANDLE ImageHandle,
83 IN EFI_SYSTEM_TABLE *SystemTable
84 )
85 {
86 EFI_STATUS Status;
87
88 //
89 // Install driver model protocol(s).
90 //
91 Status = EfiLibInstallDriverBindingComponentName2 (
92 ImageHandle,
93 SystemTable,
94 &gIdeControllerDriverBinding,
95 ImageHandle,
96 &gIdeControllerComponentName,
97 &gIdeControllerComponentName2
98 );
99 ASSERT_EFI_ERROR (Status);
100
101 return Status;
102 }
103
104 /**
105 Register Driver Binding protocol for this driver.
106
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
111
112 @retval EFI_SUCCESS Driver loaded.
113 @retval !EFI_SUCESS Driver not loaded.
114 **/
115 EFI_STATUS
116 EFIAPI
117 IdeControllerSupported (
118 IN EFI_DRIVER_BINDING_PROTOCOL *This,
119 IN EFI_HANDLE Controller,
120 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
121 )
122 {
123 EFI_STATUS Status;
124 EFI_PCI_IO_PROTOCOL *PciIo;
125 UINT8 PciClass;
126 UINT8 PciSubClass;
127
128 //
129 // Attempt to Open PCI I/O Protocol
130 //
131 Status = gBS->OpenProtocol (
132 Controller,
133 &gEfiPciIoProtocolGuid,
134 (VOID **) &PciIo,
135 This->DriverBindingHandle,
136 Controller,
137 EFI_OPEN_PROTOCOL_BY_DRIVER
138 );
139 if (EFI_ERROR (Status)) {
140 return Status;
141 }
142
143 //
144 // Now further check the PCI header: Base class (offset 0x0B) and
145 // Sub Class (offset 0x0A). This controller should be an Ide controller
146 //
147 Status = PciIo->Pci.Read (
148 PciIo,
149 EfiPciIoWidthUint8,
150 PCI_CLASSCODE_OFFSET + 2,
151 1,
152 &PciClass
153 );
154 if (EFI_ERROR (Status)) {
155 goto Done;
156 }
157
158 Status = PciIo->Pci.Read (
159 PciIo,
160 EfiPciIoWidthUint8,
161 PCI_CLASSCODE_OFFSET + 1,
162 1,
163 &PciSubClass
164 );
165 if (EFI_ERROR (Status)) {
166 goto Done;
167 }
168
169 //
170 // Examine Ide PCI Configuration table fields
171 //
172 if ((PciClass != PCI_CLASS_MASS_STORAGE) || (PciSubClass != PCI_CLASS_MASS_STORAGE_IDE)) {
173 Status = EFI_UNSUPPORTED;
174 }
175
176 Done:
177 gBS->CloseProtocol (
178 Controller,
179 &gEfiPciIoProtocolGuid,
180 This->DriverBindingHandle,
181 Controller
182 );
183
184 return Status;
185 }
186
187 /**
188 This routine is called right after the .Supported() called and return
189 EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols
190 are closed.
191
192 @param This A pointer points to the Binding Protocol instance
193 @param Controller The handle of controller to be tested. Parameter
194 passed by the caller
195 @param RemainingDevicePath A pointer to the device path. Should be ignored by
196 device driver
197
198 @return EFI_STATUS Status of InstallMultipleProtocolInterfaces()
199 **/
200 EFI_STATUS
201 EFIAPI
202 IdeControllerStart (
203 IN EFI_DRIVER_BINDING_PROTOCOL *This,
204 IN EFI_HANDLE Controller,
205 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
206 )
207 {
208 EFI_STATUS Status;
209 EFI_PCI_IO_PROTOCOL *PciIo;
210
211 //
212 // Now test and open the EfiPciIoProtocol
213 //
214 Status = gBS->OpenProtocol (
215 Controller,
216 &gEfiPciIoProtocolGuid,
217 (VOID **) &PciIo,
218 This->DriverBindingHandle,
219 Controller,
220 EFI_OPEN_PROTOCOL_BY_DRIVER
221 );
222 //
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
229 //
230 if (EFI_ERROR (Status)) {
231 return Status;
232 }
233
234 //
235 // Install IDE_CONTROLLER_INIT protocol
236 //
237 return gBS->InstallMultipleProtocolInterfaces (
238 &Controller,
239 &gEfiIdeControllerInitProtocolGuid, &gEfiIdeControllerInit,
240 NULL
241 );
242 }
243
244 /**
245 Stop this driver on Controller Handle.
246
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
251
252 @retval EFI_SUCESS This driver is removed DeviceHandle
253 @retval !EFI_SUCCESS This driver was not removed from this device
254 **/
255 EFI_STATUS
256 EFIAPI
257 IdeControllerStop (
258 IN EFI_DRIVER_BINDING_PROTOCOL *This,
259 IN EFI_HANDLE Controller,
260 IN UINTN NumberOfChildren,
261 IN EFI_HANDLE *ChildHandleBuffer
262 )
263 {
264 EFI_STATUS Status;
265 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInit;
266
267 //
268 // Open the produced protocol
269 //
270 Status = gBS->OpenProtocol (
271 Controller,
272 &gEfiIdeControllerInitProtocolGuid,
273 (VOID **) &IdeControllerInit,
274 This->DriverBindingHandle,
275 Controller,
276 EFI_OPEN_PROTOCOL_GET_PROTOCOL
277 );
278 if (EFI_ERROR (Status)) {
279 return EFI_UNSUPPORTED;
280 }
281
282 //
283 // Make sure the protocol was produced by this driver
284 //
285 if (IdeControllerInit != &gEfiIdeControllerInit) {
286 return EFI_UNSUPPORTED;
287 }
288
289 //
290 // Uninstall the IDE Controller Init Protocol
291 //
292 Status = gBS->UninstallMultipleProtocolInterfaces (
293 Controller,
294 &gEfiIdeControllerInitProtocolGuid, &gEfiIdeControllerInit,
295 NULL
296 );
297 if (EFI_ERROR (Status)) {
298 return Status;
299 }
300
301 //
302 // Close protocols opened by Ide controller driver
303 //
304 return gBS->CloseProtocol (
305 Controller,
306 &gEfiPciIoProtocolGuid,
307 This->DriverBindingHandle,
308 Controller
309 );
310 }
311
312 //
313 // Interface functions of IDE_CONTROLLER_INIT protocol
314 //
315 /**
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.
318
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.
325
326 @retval EFI_SUCCESS Success to get channel information
327 @retval EFI_INVALID_PARAMETER Invalid channel id.
328 **/
329 EFI_STATUS
330 EFIAPI
331 IdeInitGetChannelInfo (
332 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
333 IN UINT8 Channel,
334 OUT BOOLEAN *Enabled,
335 OUT UINT8 *MaxDevices
336 )
337 {
338 //
339 // Channel number (0 based, either 0 or 1)
340 //
341 if (Channel < ICH_IDE_MAX_CHANNEL) {
342 *Enabled = TRUE;
343 *MaxDevices = ICH_IDE_MAX_DEVICES;
344 return EFI_SUCCESS;
345 }
346
347 *Enabled = FALSE;
348 return EFI_INVALID_PARAMETER;
349 }
350
351 /**
352 This function is called by IdeBus driver before executing certain actions.
353 This allows IDE Controller Init to prepare for each action.
354
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)
358
359 @return EFI_SUCCESS Success operation.
360 **/
361 EFI_STATUS
362 EFIAPI
363 IdeInitNotifyPhase (
364 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
365 IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase,
366 IN UINT8 Channel
367 )
368 {
369 return EFI_SUCCESS;
370 }
371
372 /**
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
375
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
380
381 @return EFI_SUCCESS Success operation.
382 **/
383 EFI_STATUS
384 EFIAPI
385 IdeInitSubmitData (
386 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
387 IN UINT8 Channel,
388 IN UINT8 Device,
389 IN EFI_IDENTIFY_DATA *IdentifyData
390 )
391 {
392 return EFI_SUCCESS;
393 }
394
395 /**
396 This function is called by IdeBus driver to disqualify unsupported operation
397 mode on specfic IDE device
398
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
403
404 @return EFI_SUCCESS Success operation.
405 **/
406 EFI_STATUS
407 EFIAPI
408 IdeInitDisqualifyMode (
409 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
410 IN UINT8 Channel,
411 IN UINT8 Device,
412 IN EFI_ATA_COLLECTIVE_MODE *BadModes
413 )
414 {
415 return EFI_SUCCESS;
416 }
417
418 /**
419 This function is called by IdeBus driver to calculate the best operation mode
420 supported by specific IDE device
421
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
426
427 @retval EFI_OUT_OF_RESOURCES Fail to allocate pool.
428 @retval EFI_INVALID_PARAMETER Invalid channel id and device id.
429 **/
430 EFI_STATUS
431 EFIAPI
432 IdeInitCalculateMode (
433 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
434 IN UINT8 Channel,
435 IN UINT8 Device,
436 OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes
437 )
438 {
439 if (Channel >= ICH_IDE_MAX_CHANNEL || Device >= ICH_IDE_MAX_DEVICES) {
440 return EFI_INVALID_PARAMETER;
441 }
442
443 *SupportedModes = AllocateCopyPool (sizeof (EFI_ATA_COLLECTIVE_MODE), &gEfiAtaCollectiveModeTemplate);
444 if (*SupportedModes == NULL) {
445 return EFI_OUT_OF_RESOURCES;
446 }
447
448 return EFI_SUCCESS;
449 }
450
451 /**
452 This function is called by IdeBus driver to set appropriate timing on IDE
453 controller according supported operation mode.
454
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
459
460 @retval EFI_SUCCESS Sucess operation.
461 **/
462 EFI_STATUS
463 EFIAPI
464 IdeInitSetTiming (
465 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
466 IN UINT8 Channel,
467 IN UINT8 Device,
468 IN EFI_ATA_COLLECTIVE_MODE *Modes
469 )
470 {
471 return EFI_SUCCESS;
472 }