]> git.proxmox.com Git - mirror_edk2.git/blob - PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeController.c
6150198ce9aa02b094b34d138621089794f228c1
[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 - 2009 Intel Corporation. <BR>
7 All rights reserved. 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 EFI_STATUS
68 EFIAPI
69 InitializeIdeControllerDriver (
70 IN EFI_HANDLE ImageHandle,
71 IN EFI_SYSTEM_TABLE *SystemTable
72 )
73 /*++
74 Routine Description:
75
76 Chipset Ide Driver EntryPoint function. It follows the standard EFI driver
77 model. It's called by StartImage() of DXE Core
78
79 Argments:
80
81 ImageHnadle -- While the driver image loaded be the ImageLoader(),
82 an image handle is assigned to this driver binary,
83 all activities of the driver is tied to this ImageHandle
84 *SystemTable -- A pointer to the system table, for all BS(Boo Services) and
85 RT(Runtime Services)
86
87 Retruns:
88
89 Always call EfiLibInstallDriverBindingProtocol( ) and retrun the result
90
91 --*/
92 {
93 EFI_STATUS Status;
94
95 //
96 // Install driver model protocol(s).
97 //
98 Status = EfiLibInstallDriverBindingComponentName2 (
99 ImageHandle,
100 SystemTable,
101 &gIdeControllerDriverBinding,
102 ImageHandle,
103 &gIdeControllerComponentName,
104 &gIdeControllerComponentName2
105 );
106 ASSERT_EFI_ERROR (Status);
107
108 return Status;
109 }
110
111 EFI_STATUS
112 EFIAPI
113 IdeControllerSupported (
114 IN EFI_DRIVER_BINDING_PROTOCOL *This,
115 IN EFI_HANDLE Controller,
116 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
117 )
118 /*++
119
120 Routine Description:
121
122 Register Driver Binding protocol for this driver.
123
124 Arguments:
125
126 This -- a pointer points to the Binding Protocol instance
127 Controller -- The handle of controller to be tested.
128 *RemainingDevicePath -- A pointer to the device path. Ignored by device
129 driver but used by bus driver
130
131 Returns:
132
133 EFI_SUCCESS -- Driver loaded.
134 other -- Driver not loaded.
135 --*/
136 {
137 EFI_STATUS Status;
138 EFI_PCI_IO_PROTOCOL *PciIo;
139 UINT8 PciClass;
140 UINT8 PciSubClass;
141
142 //
143 // Attempt to Open PCI I/O Protocol
144 //
145 Status = gBS->OpenProtocol (
146 Controller,
147 &gEfiPciIoProtocolGuid,
148 (VOID **) &PciIo,
149 This->DriverBindingHandle,
150 Controller,
151 EFI_OPEN_PROTOCOL_BY_DRIVER
152 );
153 if (EFI_ERROR (Status)) {
154 return Status;
155 }
156
157 //
158 // Now further check the PCI header: Base class (offset 0x0B) and
159 // Sub Class (offset 0x0A). This controller should be an Ide controller
160 //
161 Status = PciIo->Pci.Read (
162 PciIo,
163 EfiPciIoWidthUint8,
164 PCI_CLASSCODE_OFFSET + 2,
165 1,
166 &PciClass
167 );
168 if (EFI_ERROR (Status)) {
169 goto Done;
170 }
171
172 Status = PciIo->Pci.Read (
173 PciIo,
174 EfiPciIoWidthUint8,
175 PCI_CLASSCODE_OFFSET + 1,
176 1,
177 &PciSubClass
178 );
179 if (EFI_ERROR (Status)) {
180 goto Done;
181 }
182
183 //
184 // Examine Ide PCI Configuration table fields
185 //
186 if ((PciClass != PCI_CLASS_MASS_STORAGE) || (PciSubClass != PCI_CLASS_MASS_STORAGE_IDE)) {
187 Status = EFI_UNSUPPORTED;
188 }
189
190 Done:
191 gBS->CloseProtocol (
192 Controller,
193 &gEfiPciIoProtocolGuid,
194 This->DriverBindingHandle,
195 Controller
196 );
197
198 return Status;
199 }
200
201 EFI_STATUS
202 EFIAPI
203 IdeControllerStart (
204 IN EFI_DRIVER_BINDING_PROTOCOL *This,
205 IN EFI_HANDLE Controller,
206 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
207 )
208 /*++
209
210 Routine Description:
211
212 This routine is called right after the .Supported() called and return
213 EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols
214 are closed.
215
216 Arguments:
217
218 This -- a pointer points to the Binding Protocol instance
219 Controller -- The handle of controller to be tested. Parameter
220 passed by the caller
221 *RemainingDevicePath -- A pointer to the device path. Should be ignored by
222 device driver
223 --*/
224 {
225 EFI_STATUS Status;
226 EFI_PCI_IO_PROTOCOL *PciIo;
227
228 //
229 // Now test and open the EfiPciIoProtocol
230 //
231 Status = gBS->OpenProtocol (
232 Controller,
233 &gEfiPciIoProtocolGuid,
234 (VOID **) &PciIo,
235 This->DriverBindingHandle,
236 Controller,
237 EFI_OPEN_PROTOCOL_BY_DRIVER
238 );
239 //
240 // Status == EFI_SUCCESS - A normal execution flow, SUCCESS and the program proceeds.
241 // Status == ALREADY_STARTED - A non-zero Status code returned. It indicates
242 // that the protocol has been opened and should be treated as a
243 // normal condition and the program proceeds. The Protocol will not
244 // opened 'again' by this call.
245 // Status != ALREADY_STARTED - Error status, terminate program execution
246 //
247 if (EFI_ERROR (Status)) {
248 return Status;
249 }
250
251 //
252 // Install IDE_CONTROLLER_INIT protocol
253 //
254 return gBS->InstallMultipleProtocolInterfaces (
255 &Controller,
256 &gEfiIdeControllerInitProtocolGuid, &gEfiIdeControllerInit,
257 NULL
258 );
259 }
260
261 EFI_STATUS
262 EFIAPI
263 IdeControllerStop (
264 IN EFI_DRIVER_BINDING_PROTOCOL *This,
265 IN EFI_HANDLE Controller,
266 IN UINTN NumberOfChildren,
267 IN EFI_HANDLE *ChildHandleBuffer
268 )
269 /*++
270
271 Routine Description:
272 Stop this driver on Controller Handle.
273
274 Arguments:
275 This - Protocol instance pointer.
276 Controller - Handle of device to stop driver on
277 NumberOfChildren - Not used
278 ChildHandleBuffer - Not used
279
280 Returns:
281 EFI_SUCCESS - This driver is removed DeviceHandle
282 other - This driver was not removed from this device
283
284 --*/
285 {
286 EFI_STATUS Status;
287 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInit;
288
289 //
290 // Open the produced protocol
291 //
292 Status = gBS->OpenProtocol (
293 Controller,
294 &gEfiIdeControllerInitProtocolGuid,
295 (VOID **) &IdeControllerInit,
296 This->DriverBindingHandle,
297 Controller,
298 EFI_OPEN_PROTOCOL_GET_PROTOCOL
299 );
300 if (EFI_ERROR (Status)) {
301 return EFI_UNSUPPORTED;
302 }
303
304 //
305 // Make sure the protocol was produced by this driver
306 //
307 if (IdeControllerInit != &gEfiIdeControllerInit) {
308 return EFI_UNSUPPORTED;
309 }
310
311 //
312 // Uninstall the IDE Controller Init Protocol
313 //
314 Status = gBS->UninstallMultipleProtocolInterfaces (
315 Controller,
316 &gEfiIdeControllerInitProtocolGuid, &gEfiIdeControllerInit,
317 NULL
318 );
319 if (EFI_ERROR (Status)) {
320 return Status;
321 }
322
323 //
324 // Close protocols opened by Ide controller driver
325 //
326 return gBS->CloseProtocol (
327 Controller,
328 &gEfiPciIoProtocolGuid,
329 This->DriverBindingHandle,
330 Controller
331 );
332 }
333
334 //
335 // Interface functions of IDE_CONTROLLER_INIT protocol
336 //
337 EFI_STATUS
338 EFIAPI
339 IdeInitGetChannelInfo (
340 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
341 IN UINT8 Channel,
342 OUT BOOLEAN *Enabled,
343 OUT UINT8 *MaxDevices
344 )
345 /*++
346 Routine Description:
347
348 This function can be used to obtain information about a specified channel.
349 It's usually used by IDE Bus driver during enumeration process.
350
351 Arguments:
352
353 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
354 Channel -- Channel number (0 based, either 0 or 1)
355 Enabled -- TRUE if the channel is enabled. If the channel is disabled,
356 then it will no be enumerated.
357 MaxDevices -- The Max number of IDE devices that the bus driver can expect
358 on this channel. For ATA/ATAPI, this number is either 1 or 2.
359
360 Returns:
361 EFI_STATUS
362
363 --*/
364 {
365 //
366 // Channel number (0 based, either 0 or 1)
367 //
368 if (Channel < ICH_IDE_MAX_CHANNEL) {
369 *Enabled = TRUE;
370 *MaxDevices = ICH_IDE_MAX_DEVICES;
371 return EFI_SUCCESS;
372 }
373
374 *Enabled = FALSE;
375 return EFI_INVALID_PARAMETER;
376 }
377
378
379 EFI_STATUS
380 EFIAPI
381 IdeInitNotifyPhase (
382 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
383 IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase,
384 IN UINT8 Channel
385 )
386 /*++
387
388 Routine Description:
389
390 This function is called by IdeBus driver before executing certain actions.
391 This allows IDE Controller Init to prepare for each action.
392
393 Arguments:
394
395 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
396 Phase -- phase indicator defined by IDE_CONTROLLER_INIT protocol
397 Channel -- Channel number (0 based, either 0 or 1)
398
399 Returns:
400
401 --*/
402 {
403 return EFI_SUCCESS;
404 }
405
406 EFI_STATUS
407 EFIAPI
408 IdeInitSubmitData (
409 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
410 IN UINT8 Channel,
411 IN UINT8 Device,
412 IN EFI_IDENTIFY_DATA *IdentifyData
413 )
414 /*++
415
416 Routine Description:
417
418 This function is called by IdeBus driver to submit EFI_IDENTIFY_DATA data structure
419 obtained from IDE deivce. This structure is used to set IDE timing
420
421 Arguments:
422
423 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
424 Channel -- IDE channel number (0 based, either 0 or 1)
425 Device -- IDE device number
426 IdentifyData -- A pointer to EFI_IDENTIFY_DATA data structure
427
428 Returns:
429
430 --*/
431 {
432 return EFI_SUCCESS;
433 }
434
435 EFI_STATUS
436 EFIAPI
437 IdeInitDisqualifyMode (
438 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
439 IN UINT8 Channel,
440 IN UINT8 Device,
441 IN EFI_ATA_COLLECTIVE_MODE *BadModes
442 )
443 /*++
444
445 Routine Description:
446
447 This function is called by IdeBus driver to disqualify unsupported operation
448 mode on specfic IDE device
449
450 Arguments:
451
452 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
453 Channel -- IDE channel number (0 based, either 0 or 1)
454 Device -- IDE device number
455 BadModes -- Operation mode indicator
456
457 Returns:
458
459 --*/
460 {
461 return EFI_SUCCESS;
462 }
463
464 EFI_STATUS
465 EFIAPI
466 IdeInitCalculateMode (
467 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
468 IN UINT8 Channel,
469 IN UINT8 Device,
470 OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes
471 )
472 /*++
473
474 Routine Description:
475
476 This function is called by IdeBus driver to calculate the best operation mode
477 supported by specific IDE device
478
479 Arguments:
480
481 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
482 Channel -- IDE channel number (0 based, either 0 or 1)
483 Device -- IDE device number
484 SupportedModes -- Modes collection supported by IDE device
485
486 Returns:
487
488 --*/
489 {
490 if (Channel >= ICH_IDE_MAX_CHANNEL || Device >= ICH_IDE_MAX_DEVICES) {
491 return EFI_INVALID_PARAMETER;
492 }
493
494 *SupportedModes = AllocateCopyPool (sizeof (EFI_ATA_COLLECTIVE_MODE), &gEfiAtaCollectiveModeTemplate);
495 if (*SupportedModes == NULL) {
496 return EFI_OUT_OF_RESOURCES;
497 }
498
499 return EFI_SUCCESS;
500 }
501
502
503 EFI_STATUS
504 EFIAPI
505 IdeInitSetTiming (
506 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
507 IN UINT8 Channel,
508 IN UINT8 Device,
509 IN EFI_ATA_COLLECTIVE_MODE *Modes
510 )
511 /*++
512
513 Routine Description:
514
515 This function is called by IdeBus driver to set appropriate timing on IDE
516 controller according supported operation mode
517
518 Arguments:
519
520 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
521 Channel -- IDE channel number (0 based, either 0 or 1)
522 Device -- IDE device number
523
524 Returns:
525
526 --*/
527 {
528 return EFI_SUCCESS;
529 }