]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBus.c
use the GUIDed versions of events: EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE and EVT_SIGNAL_E...
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / IdeBusDxe / IdeBus.c
CommitLineData
ead42efc 1/** @file\r
03417d8d 2 Copyright (c) 2006 - 2008, Intel Corporation\r
ead42efc 3 All rights reserved. This program and the accompanying materials\r
4 are licensed and made available under the terms and conditions of the BSD License\r
5 which accompanies this distribution. The full text of the license may be found at\r
6 http://opensource.org/licenses/bsd-license.php\r
7\r
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
10\r
11 @par Revision Reference:\r
12 This module is modified from DXE\IDE module for Ide Contriller Init support\r
13\r
14**/\r
15\r
03417d8d 16#include "IdeBus.h"\r
ead42efc 17\r
18#define PCI_CLASS_MASS_STORAGE 0x01\r
19#define PCI_SUB_CLASS_IDE 0x01\r
20\r
21\r
22//\r
23// IDE Bus Driver Binding Protocol Instance\r
24//\r
25EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = {\r
26 IDEBusDriverBindingSupported,\r
27 IDEBusDriverBindingStart,\r
28 IDEBusDriverBindingStop,\r
29 0xa,\r
30 NULL,\r
31 NULL\r
32};\r
33\r
34//\r
35// ***********************************************************************************\r
36// IDEBusDriverBindingSupported\r
37// ***********************************************************************************\r
38//\r
39/**\r
40 Register Driver Binding protocol for this driver.\r
41\r
42 @param[in] This -- A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
43 @param[in] ControllerHandle -- The handle of the controller to test.\r
44 @param[in] RemainingDevicePath -- A pointer to the remaining portion of a device path.\r
45\r
46 @retval EFI_SUCCESS Driver loaded.\r
47 @retval other Driver not loaded.\r
48\r
49**/\r
50EFI_STATUS\r
51EFIAPI\r
52IDEBusDriverBindingSupported (\r
53 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
54 IN EFI_HANDLE Controller,\r
55 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
56 )\r
57// TODO: Controller - add argument and description to function comment\r
58// TODO: EFI_UNSUPPORTED - add return value to function comment\r
59{\r
60 EFI_STATUS Status;\r
61 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
62 EFI_DEV_PATH *Node;\r
63 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;\r
64\r
65 if (RemainingDevicePath != NULL) {\r
66 Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
67 if (Node->DevPath.Type != MESSAGING_DEVICE_PATH ||\r
68 Node->DevPath.SubType != MSG_ATAPI_DP ||\r
69 DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {\r
70 return EFI_UNSUPPORTED;\r
71 }\r
72 }\r
73\r
74 //\r
75 // Open the IO Abstraction(s) needed to perform the supported test\r
76 //\r
77 Status = gBS->OpenProtocol (\r
78 Controller,\r
79 &gEfiDevicePathProtocolGuid,\r
80 (VOID **) &ParentDevicePath,\r
81 This->DriverBindingHandle,\r
82 Controller,\r
83 EFI_OPEN_PROTOCOL_BY_DRIVER\r
84 );\r
85 if (Status == EFI_ALREADY_STARTED) {\r
86 return EFI_SUCCESS;\r
87 }\r
88\r
89 if (EFI_ERROR (Status)) {\r
90 return Status;\r
91 }\r
92\r
93 //\r
94 // Close protocol, don't use device path protocol in the .Support() function\r
95 //\r
96 gBS->CloseProtocol (\r
97 Controller,\r
98 &gEfiDevicePathProtocolGuid,\r
99 This->DriverBindingHandle,\r
100 Controller\r
101 );\r
102\r
103 //\r
104 // Verify the Ide Controller Init Protocol, which installed by the\r
105 // IdeController module.\r
106 // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't\r
107 // open BY_DRIVER here) That's why we don't check pciio protocol\r
108 // Note 2: ide_init driver check ide controller's pci config space, so we dont\r
109 // check here any more to save code size\r
110 //\r
111 Status = gBS->OpenProtocol (\r
112 Controller,\r
113 &gEfiIdeControllerInitProtocolGuid,\r
114 (VOID **) &IdeInit,\r
115 This->DriverBindingHandle,\r
116 Controller,\r
117 EFI_OPEN_PROTOCOL_BY_DRIVER\r
118 );\r
119\r
120 if (Status == EFI_ALREADY_STARTED) {\r
121 return EFI_SUCCESS;\r
122 }\r
123\r
124 //\r
125 // If protocols were opened normally, closed it\r
126 //\r
127 gBS->CloseProtocol (\r
128 Controller,\r
129 &gEfiIdeControllerInitProtocolGuid,\r
130 This->DriverBindingHandle,\r
131 Controller\r
132 );\r
133\r
134 return Status;\r
135}\r
136\r
137//\r
138// ***********************************************************************************\r
139// IDEBusDriverBindingStart\r
140// ***********************************************************************************\r
141//\r
142/**\r
143 Start this driver on Controller by detecting all disks and installing\r
144 BlockIo protocol on them.\r
145\r
146 @param This Protocol instance pointer.\r
147 @param Controller Handle of device to bind driver to.\r
148 @param RemainingDevicePath Not used, always produce all possible children.\r
149\r
150 @retval EFI_SUCCESS This driver is added to ControllerHandle.\r
151 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
152 @retval other This driver does not support this device.\r
153\r
154**/\r
155EFI_STATUS\r
156EFIAPI\r
157IDEBusDriverBindingStart (\r
158 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
159 IN EFI_HANDLE Controller,\r
160 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
161 )\r
162{\r
163 EFI_STATUS Status;\r
164 EFI_STATUS SavedStatus;\r
165 EFI_PCI_IO_PROTOCOL *PciIo;\r
166 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
167 EFI_DEV_PATH *Node;\r
168 UINT8 IdeChannel;\r
169 UINT8 BeginningIdeChannel;\r
170 UINT8 EndIdeChannel;\r
171 UINT8 IdeDevice;\r
172 UINT8 BeginningIdeDevice;\r
173 UINT8 EndIdeDevice;\r
174 IDE_BLK_IO_DEV *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice];\r
175 IDE_BLK_IO_DEV *IdeBlkIoDevicePtr;\r
176 IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel];\r
177 ATA_TRANSFER_MODE TransferMode;\r
178 ATA_DRIVE_PARMS DriveParameters;\r
179 EFI_DEV_PATH NewNode;\r
180 UINT8 ConfigurationOptions;\r
181 UINT16 CommandBlockBaseAddr;\r
182 UINT16 ControlBlockBaseAddr;\r
183 UINTN DataSize;\r
184 IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
96f6af14 185 UINT64 Supports;\r
ead42efc 186\r
187 //\r
188 // Local variables declaration for IdeControllerInit support\r
189 //\r
190 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;\r
191 BOOLEAN EnumAll;\r
192 BOOLEAN ChannelEnabled;\r
193 UINT8 MaxDevices;\r
194 EFI_IDENTIFY_DATA IdentifyData;\r
195 EFI_ATA_COLLECTIVE_MODE *SupportedModes;\r
196\r
197 IdeBusDriverPrivateData = NULL;\r
198 SupportedModes = NULL;\r
199\r
200 //\r
201 // Perform IdeBus initialization\r
202 //\r
203 Status = gBS->OpenProtocol (\r
204 Controller,\r
205 &gEfiDevicePathProtocolGuid,\r
206 (VOID **) &ParentDevicePath,\r
207 This->DriverBindingHandle,\r
208 Controller,\r
209 EFI_OPEN_PROTOCOL_BY_DRIVER\r
210 );\r
211 if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
212 return Status;\r
213 }\r
214\r
215 //\r
216 // Now open the IDE_CONTROLLER_INIT protocol. Step7.1\r
217 //\r
218 Status = gBS->OpenProtocol (\r
219 Controller,\r
220 &gEfiIdeControllerInitProtocolGuid,\r
221 (VOID **) &IdeInit,\r
222 This->DriverBindingHandle,\r
223 Controller,\r
224 EFI_OPEN_PROTOCOL_BY_DRIVER\r
225 );\r
226\r
227 //\r
228 // The following OpenProtocol function with _GET_PROTOCOL attribute and\r
229 // will not return EFI_ALREADY_STARTED, so save it for now\r
230 //\r
231 SavedStatus = Status;\r
232\r
233 if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
234 DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status));\r
235 //\r
236 // open protocol is not SUCCESS or not ALREADY_STARTED, error exit\r
237 //\r
238 goto ErrorExit;\r
239 }\r
240\r
241 //\r
242 // Save Enumall. Step7.2\r
243 //\r
244 EnumAll = IdeInit->EnumAll;\r
245\r
246 //\r
247 // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL\r
248 // attribute will not return EFI_ALREADY_STARTED\r
249 //\r
250 Status = gBS->OpenProtocol (\r
251 Controller,\r
252 &gEfiPciIoProtocolGuid,\r
253 (VOID **) &PciIo,\r
254 This->DriverBindingHandle,\r
255 Controller,\r
256 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
257 );\r
258 if (EFI_ERROR (Status)) {\r
259 DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));\r
260 goto ErrorExit;\r
261 }\r
262\r
263 //\r
264 // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable\r
265 //\r
266 if (SavedStatus != EFI_ALREADY_STARTED) {\r
267 IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
268 if (IdeBusDriverPrivateData == NULL) {\r
269 Status = EFI_OUT_OF_RESOURCES;\r
270 goto ErrorExit;\r
271 }\r
272\r
273 ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
274 Status = gBS->InstallMultipleProtocolInterfaces (\r
275 &Controller,\r
276 &gEfiCallerIdGuid,\r
277 IdeBusDriverPrivateData,\r
278 NULL\r
279 );\r
280 if (EFI_ERROR (Status)) {\r
281 goto ErrorExit;\r
282 }\r
283\r
284 } else {\r
285 Status = gBS->OpenProtocol (\r
286 Controller,\r
287 &gEfiCallerIdGuid,\r
288 (VOID **) &IdeBusDriverPrivateData,\r
289 This->DriverBindingHandle,\r
290 Controller,\r
291 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
292 );\r
293 if (EFI_ERROR (Status)) {\r
294 IdeBusDriverPrivateData = NULL;\r
295 goto ErrorExit;\r
296 }\r
297 }\r
298\r
299 Status = PciIo->Attributes (\r
300 PciIo,\r
96f6af14
LG
301 EfiPciIoAttributeOperationSupported,\r
302 0,\r
303 &Supports\r
ead42efc 304 );\r
96f6af14
LG
305 if (!EFI_ERROR (Status)) {\r
306 Supports &= EFI_PCI_DEVICE_ENABLE;\r
307 Status = PciIo->Attributes (\r
308 PciIo,\r
309 EfiPciIoAttributeOperationEnable,\r
310 Supports,\r
311 NULL\r
312 );\r
313 }\r
314\r
ead42efc 315 if (EFI_ERROR (Status)) {\r
316 goto ErrorExit;\r
317 }\r
318\r
319 //\r
320 // Read the environment variable that contains the IDEBus Driver's\r
321 // Config options that were set by the Driver Configuration Protocol\r
322 //\r
323 DataSize = sizeof (ConfigurationOptions);\r
324 Status = gRT->GetVariable (\r
325 (CHAR16 *) L"Configuration",\r
326 &gEfiCallerIdGuid,\r
327 NULL,\r
328 &DataSize,\r
329 &ConfigurationOptions\r
330 );\r
331 if (EFI_ERROR (Status)) {\r
332 ConfigurationOptions = 0x0f;\r
333 }\r
334\r
335 if (EnumAll) {\r
336 //\r
337 // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway\r
338 //\r
339 BeginningIdeChannel = IdePrimary;\r
340 EndIdeChannel = IdeSecondary;\r
341 BeginningIdeDevice = IdeMaster;\r
342 EndIdeDevice = IdeSlave;\r
343 } else if (RemainingDevicePath == NULL) {\r
344 //\r
345 // RemainingDevicePath is NULL, scan IDE bus for each device;\r
346 //\r
347 BeginningIdeChannel = IdePrimary;\r
348 EndIdeChannel = IdeSecondary;\r
349 BeginningIdeDevice = IdeMaster;\r
350 //\r
351 // default, may be redefined by IdeInit\r
352 //\r
353 EndIdeDevice = IdeSlave;\r
354 } else {\r
355 //\r
356 // RemainingDevicePath is not NULL, only scan the specified device.\r
357 //\r
358 Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
359 BeginningIdeChannel = Node->Atapi.PrimarySecondary;\r
360 EndIdeChannel = BeginningIdeChannel;\r
361 BeginningIdeDevice = Node->Atapi.SlaveMaster;\r
362 EndIdeDevice = BeginningIdeDevice;\r
363 }\r
364\r
365 //\r
366 // Obtain IDE IO port registers' base addresses\r
367 //\r
368 Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);\r
369 if (EFI_ERROR (Status)) {\r
370 goto ErrorExit;\r
371 }\r
372\r
373 //\r
374 // Report status code: begin IdeBus initialization\r
375 //\r
376 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
377 EFI_PROGRESS_CODE,\r
378 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
379 ParentDevicePath\r
380 );\r
381\r
382 //\r
383 // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol\r
384 //\r
385 for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
386\r
387 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);\r
388\r
389 //\r
390 // now obtain channel information fron IdeControllerInit protocol. Step9\r
391 //\r
392 Status = IdeInit->GetChannelInfo (\r
393 IdeInit,\r
394 IdeChannel,\r
395 &ChannelEnabled,\r
396 &MaxDevices\r
397 );\r
398 if (EFI_ERROR (Status)) {\r
399 DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));\r
400 continue;\r
401 }\r
402\r
403 if (!ChannelEnabled) {\r
404 continue;\r
405 }\r
406\r
a1e3528b 407 EndIdeDevice = (UINT8) MIN ((MaxDevices - 1), EndIdeDevice);\r
ead42efc 408\r
409 //\r
410 // Now inform the IDE Controller Init Module. Sept10\r
411 //\r
412 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);\r
413\r
414 //\r
415 // No reset channel function implemented. Sept11\r
416 //\r
417 IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);\r
418\r
419 //\r
420 // Step13\r
421 //\r
422 IdeInit->NotifyPhase (\r
423 IdeInit,\r
424 EfiIdeBusBeforeDevicePresenceDetection,\r
425 IdeChannel\r
426 );\r
427\r
428 //\r
429 // Prepare to detect IDE device of this channel\r
430 //\r
431 InitializeIDEChannelData ();\r
432\r
433 //\r
434 // -- 1st inner loop --- Master/Slave ------------ Step14\r
435 //\r
436 for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
437 //\r
438 // Check whether the configuration options allow this device\r
439 //\r
97404058 440 if ((ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice))) == 0) {\r
ead42efc 441 continue;\r
442 }\r
443\r
444 //\r
445 // The device has been scanned in another Start(), No need to scan it again\r
446 // for perf optimization.\r
447 //\r
448 if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {\r
449 continue;\r
450 }\r
451\r
452 //\r
453 // create child handle for the detected device.\r
454 //\r
455 IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));\r
456 if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {\r
457 continue;\r
458 }\r
459\r
460 IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
461\r
462 ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));\r
463\r
464 IdeBlkIoDevicePtr->Signature = IDE_BLK_IO_DEV_SIGNATURE;\r
465 IdeBlkIoDevicePtr->Channel = (EFI_IDE_CHANNEL) IdeChannel;\r
466 IdeBlkIoDevicePtr->Device = (EFI_IDE_DEVICE) IdeDevice;\r
467\r
468 //\r
469 // initialize Block IO interface's Media pointer\r
470 //\r
471 IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;\r
472\r
473 //\r
474 // Initialize IDE IO port addresses, including Command Block registers\r
475 // and Control Block registers\r
476 //\r
477 IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));\r
478 if (IdeBlkIoDevicePtr->IoPort == NULL) {\r
479 continue;\r
480 }\r
481\r
482 ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));\r
483 CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;\r
484 ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;\r
485\r
486 IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;\r
487 (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);\r
488 IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
489 IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
490 IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
491 IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
492 IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
493 (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);\r
494\r
495 (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;\r
496 IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);\r
497\r
498 IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);\r
499\r
500 IdeBlkIoDevicePtr->PciIo = PciIo;\r
501 IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;\r
502 IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;\r
503\r
504 //\r
505 // Report Status code: is about to detect IDE drive\r
506 //\r
507 REPORT_STATUS_CODE_EX (\r
508 EFI_PROGRESS_CODE,\r
509 (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT),\r
510 0,\r
511 &gEfiCallerIdGuid,\r
512 NULL,\r
513 NULL,\r
514 0\r
515 );\r
516\r
517 //\r
518 // Discover device, now!\r
519 //\r
520 PERF_START (0, "DiscoverIdeDevice", "IDE", 0);\r
521 Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);\r
522 PERF_END (0, "DiscoverIdeDevice", "IDE", 0);\r
523\r
524 IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice] = TRUE;\r
525 IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = FALSE;\r
526\r
527 if (!EFI_ERROR (Status)) {\r
528 //\r
529 // Set Device Path\r
530 //\r
531 ZeroMem (&NewNode, sizeof (NewNode));\r
532 NewNode.DevPath.Type = MESSAGING_DEVICE_PATH;\r
533 NewNode.DevPath.SubType = MSG_ATAPI_DP;\r
534 SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));\r
535\r
536 NewNode.Atapi.PrimarySecondary = (UINT8) IdeBlkIoDevicePtr->Channel;\r
537 NewNode.Atapi.SlaveMaster = (UINT8) IdeBlkIoDevicePtr->Device;\r
538 NewNode.Atapi.Lun = IdeBlkIoDevicePtr->Lun;\r
539 IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (\r
540 ParentDevicePath,\r
541 &NewNode.DevPath\r
542 );\r
543 if (IdeBlkIoDevicePtr->DevicePath == NULL) {\r
544 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
545 continue;\r
546 }\r
547\r
548 //\r
549 // Submit identify data to IDE controller init driver\r
550 //\r
551 CopyMem (&IdentifyData, IdeBlkIoDevicePtr->pIdData, sizeof (IdentifyData));\r
552 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;\r
553 IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);\r
554 } else {\r
555 //\r
556 // Device detection failed\r
557 //\r
558 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
559 IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);\r
560 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
561 IdeBlkIoDevicePtr = NULL;\r
562 }\r
563 //\r
564 // end of 1st inner loop ---\r
565 //\r
566 }\r
567 //\r
568 // end of 1st outer loop =========\r
569 //\r
570 }\r
571\r
572 //\r
573 // = 2nd outer loop == Primary/Secondary =================\r
574 //\r
575 for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
576\r
577 //\r
578 // -- 2nd inner loop --- Master/Slave --------\r
579 //\r
580 for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
581\r
582 if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {\r
583 continue;\r
584 }\r
585\r
586 if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {\r
587 continue;\r
588 }\r
589\r
590 Status = IdeInit->CalculateMode (\r
591 IdeInit,\r
592 IdeChannel,\r
593 IdeDevice,\r
594 &SupportedModes\r
595 );\r
596 if (EFI_ERROR (Status)) {\r
597 DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));\r
598 continue;\r
599 }\r
600\r
601 IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
602\r
603 //\r
604 // Set best supported PIO mode on this IDE device\r
605 //\r
606 if (SupportedModes->PioMode.Mode <= ATA_PIO_MODE_2) {\r
607 TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;\r
608 } else {\r
609 TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;\r
610 }\r
611\r
612 TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);\r
613\r
614 if (SupportedModes->ExtModeCount == 0){\r
615 Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
616\r
617 if (EFI_ERROR (Status)) {\r
618 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
619 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
620 IdeBlkIoDevicePtr = NULL;\r
621 continue;\r
622 }\r
623 }\r
624\r
625 //\r
626 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't\r
627 // be set together. Only one DMA mode can be set to a device. If setting\r
628 // DMA mode operation fails, we can continue moving on because we only use\r
629 // PIO mode at boot time. DMA modes are used by certain kind of OS booting\r
630 //\r
631 if (SupportedModes->UdmaMode.Valid) {\r
632\r
633 TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;\r
634 TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);\r
635 Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
636\r
637 if (EFI_ERROR (Status)) {\r
638 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
639 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
640 IdeBlkIoDevicePtr = NULL;\r
641 continue;\r
642 }\r
643 //\r
644 // Record Udma Mode\r
645 //\r
646 IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;\r
647 IdeBlkIoDevicePtr->UdmaMode.Mode = SupportedModes->UdmaMode.Mode;\r
648 EnableInterrupt (IdeBlkIoDevicePtr);\r
649 } else if (SupportedModes->MultiWordDmaMode.Valid) {\r
650\r
651 TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;\r
652 TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;\r
653 Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
654\r
655 if (EFI_ERROR (Status)) {\r
656 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
657 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
658 IdeBlkIoDevicePtr = NULL;\r
659 continue;\r
660 }\r
661\r
662 EnableInterrupt (IdeBlkIoDevicePtr);\r
663 }\r
664 //\r
665 // Init driver parameters\r
666 //\r
667 DriveParameters.Sector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.sectors_per_track;\r
668 DriveParameters.Heads = (UINT8) (IdeBlkIoDevicePtr->pIdData->AtaData.heads - 1);\r
669 DriveParameters.MultipleSector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.multi_sector_cmd_max_sct_cnt;\r
670 //\r
671 // Set Parameters for the device:\r
672 // 1) Init\r
673 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command\r
674 //\r
675 if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {\r
676 Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);\r
677 }\r
678\r
679 //\r
680 // Record PIO mode used in private data\r
681 //\r
682 IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;\r
683\r
684 //\r
685 // Set IDE controller Timing Blocks in the PCI Configuration Space\r
686 //\r
687 IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);\r
688\r
689 //\r
690 // Add Component Name for the IDE/ATAPI device that was discovered.\r
691 //\r
692 IdeBlkIoDevicePtr->ControllerNameTable = NULL;\r
693 ADD_NAME (IdeBlkIoDevicePtr);\r
694\r
695 Status = gBS->InstallMultipleProtocolInterfaces (\r
696 &IdeBlkIoDevicePtr->Handle,\r
697 &gEfiDevicePathProtocolGuid,\r
698 IdeBlkIoDevicePtr->DevicePath,\r
699 &gEfiBlockIoProtocolGuid,\r
700 &IdeBlkIoDevicePtr->BlkIo,\r
701 &gEfiDiskInfoProtocolGuid,\r
702 &IdeBlkIoDevicePtr->DiskInfo,\r
703 NULL\r
704 );\r
705\r
706 if (EFI_ERROR (Status)) {\r
707 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
708 }\r
709\r
710 gBS->OpenProtocol (\r
711 Controller,\r
712 &gEfiPciIoProtocolGuid,\r
713 (VOID **) &PciIo,\r
714 This->DriverBindingHandle,\r
715 IdeBlkIoDevicePtr->Handle,\r
716 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
717 );\r
718\r
719 IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;\r
720\r
721 //\r
722 // Report status code: device eanbled!\r
723 //\r
724 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
725 EFI_PROGRESS_CODE,\r
726 (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),\r
727 IdeBlkIoDevicePtr->DevicePath\r
728 );\r
729\r
730 //\r
731 // Create event to clear pending IDE interrupt\r
732 //\r
6a27a4eb 733 Status = gBS->CreateEventEx (\r
734 EVT_NOTIFY_SIGNAL,\r
ead42efc 735 TPL_NOTIFY,\r
736 ClearInterrupt,\r
737 IdeBlkIoDevicePtr,\r
6a27a4eb 738 &gEfiEventExitBootServicesGuid,\r
ead42efc 739 &IdeBlkIoDevicePtr->ExitBootServiceEvent\r
740 );\r
741\r
742 //\r
743 // end of 2nd inner loop ----\r
744 //\r
745 }\r
746 //\r
747 // end of 2nd outer loop ==========\r
748 //\r
749 }\r
750\r
751 //\r
752 // All configurations done! Notify IdeController to do post initialization\r
753 // work such as saving IDE controller PCI settings for S3 resume\r
754 //\r
755 IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);\r
756\r
757 if (SupportedModes != NULL) {\r
758 gBS->FreePool (SupportedModes);\r
759 }\r
760\r
761 PERF_START (0, "Finish IDE detection", "IDE", 1);\r
762 PERF_END (0, "Finish IDE detection", "IDE", 0);\r
763\r
764 return EFI_SUCCESS;\r
765\r
766ErrorExit:\r
767\r
768 //\r
769 // Report error code: controller error\r
770 //\r
771 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
772 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
773 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),\r
774 ParentDevicePath\r
775 );\r
776\r
777 gBS->CloseProtocol (\r
778 Controller,\r
779 &gEfiIdeControllerInitProtocolGuid,\r
780 This->DriverBindingHandle,\r
781 Controller\r
782 );\r
783\r
784 gBS->UninstallMultipleProtocolInterfaces (\r
785 Controller,\r
786 &gEfiCallerIdGuid,\r
787 IdeBusDriverPrivateData,\r
788 NULL\r
789 );\r
790\r
791 if (IdeBusDriverPrivateData != NULL) {\r
792 gBS->FreePool (IdeBusDriverPrivateData);\r
793 }\r
794\r
795 if (SupportedModes != NULL) {\r
796 gBS->FreePool (SupportedModes);\r
797 }\r
798\r
799 gBS->CloseProtocol (\r
800 Controller,\r
801 &gEfiPciIoProtocolGuid,\r
802 This->DriverBindingHandle,\r
803 Controller\r
804 );\r
805\r
806 gBS->CloseProtocol (\r
807 Controller,\r
808 &gEfiDevicePathProtocolGuid,\r
809 This->DriverBindingHandle,\r
810 Controller\r
811 );\r
812\r
813 return Status;\r
814\r
815}\r
816\r
817//\r
818// ***********************************************************************************\r
819// IDEBusDriverBindingStop\r
820// ***********************************************************************************\r
821//\r
822/**\r
823 Stop this driver on Controller Handle.\r
824\r
825 @param This Protocol instance pointer.\r
97404058 826 @param Controller Handle of device to stop driver on\r
ead42efc 827 @param NumberOfChildren Not used\r
828 @param ChildHandleBuffer Not used\r
829\r
830 @retval EFI_SUCCESS This driver is removed DeviceHandle\r
831 @retval other This driver was not removed from this device\r
832\r
833**/\r
834EFI_STATUS\r
835EFIAPI\r
836IDEBusDriverBindingStop (\r
837 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
838 IN EFI_HANDLE Controller,\r
839 IN UINTN NumberOfChildren,\r
840 IN EFI_HANDLE *ChildHandleBuffer\r
841 )\r
842// TODO: Controller - add argument and description to function comment\r
843// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
844{\r
845 EFI_STATUS Status;\r
846 EFI_PCI_IO_PROTOCOL *PciIo;\r
847 BOOLEAN AllChildrenStopped;\r
848 UINTN Index;\r
849 IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
96f6af14 850 UINT64 Supports;\r
ead42efc 851\r
852 IdeBusDriverPrivateData = NULL;\r
853\r
854 if (NumberOfChildren == 0) {\r
855\r
856 Status = gBS->OpenProtocol (\r
857 Controller,\r
858 &gEfiPciIoProtocolGuid,\r
859 (VOID **) &PciIo,\r
860 This->DriverBindingHandle,\r
861 Controller,\r
862 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
863 );\r
864 if (!EFI_ERROR (Status)) {\r
96f6af14
LG
865 Status = PciIo->Attributes (\r
866 PciIo,\r
867 EfiPciIoAttributeOperationSupported,\r
868 0,\r
869 &Supports\r
870 );\r
871 if (!EFI_ERROR (Status)) {\r
872 Supports &= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;\r
873 PciIo->Attributes (\r
874 PciIo,\r
875 EfiPciIoAttributeOperationDisable,\r
876 Supports,\r
877 NULL\r
878 );\r
879 }\r
ead42efc 880 }\r
881\r
882 gBS->OpenProtocol (\r
883 Controller,\r
884 &gEfiCallerIdGuid,\r
885 (VOID **) &IdeBusDriverPrivateData,\r
886 This->DriverBindingHandle,\r
887 Controller,\r
888 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
889 );\r
890\r
891 gBS->UninstallMultipleProtocolInterfaces (\r
892 Controller,\r
893 &gEfiCallerIdGuid,\r
894 IdeBusDriverPrivateData,\r
895 NULL\r
896 );\r
897\r
898 if (IdeBusDriverPrivateData != NULL) {\r
899 gBS->FreePool (IdeBusDriverPrivateData);\r
900 }\r
901 //\r
902 // Close the bus driver\r
903 //\r
904 gBS->CloseProtocol (\r
905 Controller,\r
906 &gEfiIdeControllerInitProtocolGuid,\r
907 This->DriverBindingHandle,\r
908 Controller\r
909 );\r
910 gBS->CloseProtocol (\r
911 Controller,\r
912 &gEfiPciIoProtocolGuid,\r
913 This->DriverBindingHandle,\r
914 Controller\r
915 );\r
916 gBS->CloseProtocol (\r
917 Controller,\r
918 &gEfiDevicePathProtocolGuid,\r
919 This->DriverBindingHandle,\r
920 Controller\r
921 );\r
922\r
923 return EFI_SUCCESS;\r
924 }\r
925\r
926 AllChildrenStopped = TRUE;\r
927\r
928 for (Index = 0; Index < NumberOfChildren; Index++) {\r
929\r
930 Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);\r
931\r
932 if (EFI_ERROR (Status)) {\r
933 AllChildrenStopped = FALSE;\r
934 }\r
935 }\r
936\r
937 if (!AllChildrenStopped) {\r
938 return EFI_DEVICE_ERROR;\r
939 }\r
940\r
941 return EFI_SUCCESS;\r
942}\r
943\r
944//\r
945// ***********************************************************************************\r
946// DeRegisterIdeDevice\r
947// ***********************************************************************************\r
948//\r
949/**\r
950 Deregister an IDE device and free resources\r
951\r
952 @param This Protocol instance pointer.\r
953 @param Controller Ide device handle\r
954 @param Handle Handle of device to deregister driver on\r
955\r
956 @return EFI_STATUS\r
957\r
958**/\r
959EFI_STATUS\r
960DeRegisterIdeDevice (\r
961 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
962 IN EFI_HANDLE Controller,\r
963 IN EFI_HANDLE Handle\r
964 )\r
965// TODO: EFI_SUCCESS - add return value to function comment\r
966{\r
967 EFI_STATUS Status;\r
968 EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
969 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
970 EFI_PCI_IO_PROTOCOL *PciIo;\r
971 UINTN Index;\r
972\r
973 Status = gBS->OpenProtocol (\r
974 Handle,\r
975 &gEfiBlockIoProtocolGuid,\r
976 (VOID **) &BlkIo,\r
977 This->DriverBindingHandle,\r
978 Controller,\r
979 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
980 );\r
981 if (EFI_ERROR (Status)) {\r
982 return Status;\r
983 }\r
984\r
985 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);\r
986\r
987 //\r
988 // Report Status code: Device disabled\r
989 //\r
990 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
991 EFI_PROGRESS_CODE,\r
992 (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),\r
993 IdeBlkIoDevice->DevicePath\r
994 );\r
995\r
996 //\r
997 // Close the child handle\r
998 //\r
999 Status = gBS->CloseProtocol (\r
1000 Controller,\r
1001 &gEfiPciIoProtocolGuid,\r
1002 This->DriverBindingHandle,\r
1003 Handle\r
1004 );\r
1005\r
1006 Status = gBS->UninstallMultipleProtocolInterfaces (\r
1007 Handle,\r
1008 &gEfiDevicePathProtocolGuid,\r
1009 IdeBlkIoDevice->DevicePath,\r
1010 &gEfiBlockIoProtocolGuid,\r
1011 &IdeBlkIoDevice->BlkIo,\r
1012 &gEfiDiskInfoProtocolGuid,\r
1013 &IdeBlkIoDevice->DiskInfo,\r
1014 NULL\r
1015 );\r
1016\r
1017 if (EFI_ERROR (Status)) {\r
1018 gBS->OpenProtocol (\r
1019 Controller,\r
1020 &gEfiPciIoProtocolGuid,\r
1021 (VOID **) &PciIo,\r
1022 This->DriverBindingHandle,\r
1023 Handle,\r
1024 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1025 );\r
1026 return Status;\r
1027 }\r
1028\r
1029 //\r
1030 // Release allocated resources\r
1031 //\r
1032 Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;\r
1033 IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;\r
1034\r
1035 ReleaseIdeResources (IdeBlkIoDevice);\r
1036\r
1037 return EFI_SUCCESS;\r
1038}\r
1039\r
1040//\r
1041// ***********************************************************************************\r
1042// IDEBlkIoReset\r
1043// ***********************************************************************************\r
1044//\r
1045/**\r
eeefcb9d 1046 GC_TODO: Add function description\r
1047\r
1048 @param This GC_TODO: add argument description.\r
1049 @param ExtendedVerification GC_TODO: add argument description.\r
1050\r
1051 @retval EFI_DEVICE_ERROR GC_TODO: Add description for return value.\r
ead42efc 1052\r
1053**/\r
1054EFI_STATUS\r
1055EFIAPI\r
1056IDEBlkIoReset (\r
1057 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1058 IN BOOLEAN ExtendedVerification\r
1059 )\r
1060{\r
1061 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1062 EFI_STATUS Status;\r
1063 EFI_TPL OldTpl;\r
1064\r
1065 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1066\r
1067 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
1068 //\r
1069 // Requery IDE IO resources in case of the switch of native and legacy modes\r
1070 //\r
1071 ReassignIdeResources (IdeBlkIoDevice);\r
1072\r
1073 //\r
1074 // for ATA device, using ATA reset method\r
1075 //\r
1076 if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
1077 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
1078 Status = AtaSoftReset (IdeBlkIoDevice);\r
1079 goto Done;\r
1080 }\r
1081\r
1082 if (IdeBlkIoDevice->Type == IdeUnknown) {\r
1083 Status = EFI_DEVICE_ERROR;\r
1084 goto Done;\r
1085 }\r
1086\r
1087 //\r
1088 // for ATAPI device, using ATAPI reset method\r
1089 //\r
1090 Status = AtapiSoftReset (IdeBlkIoDevice);\r
1091 if (ExtendedVerification) {\r
1092 Status = AtaSoftReset (IdeBlkIoDevice);\r
1093 }\r
1094\r
1095Done:\r
1096 gBS->RestoreTPL (OldTpl);\r
1097 return Status;\r
1098}\r
1099\r
1100/**\r
1101 Read data from block io device\r
1102\r
1103 @param This Protocol instance pointer.\r
1104 @param MediaId The media ID of the device\r
1105 @param LBA Starting LBA address to read data\r
1106 @param BufferSize The size of data to be read\r
1107 @param Buffer Caller supplied buffer to save data\r
1108\r
1109 @return read data status\r
1110\r
1111**/\r
1112EFI_STATUS\r
1113EFIAPI\r
1114IDEBlkIoReadBlocks (\r
1115 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1116 IN UINT32 MediaId,\r
1117 IN EFI_LBA LBA,\r
1118 IN UINTN BufferSize,\r
1119 OUT VOID *Buffer\r
1120 )\r
1121// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
1122{\r
1123 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1124 EFI_STATUS Status;\r
1125 EFI_TPL OldTpl;\r
1126\r
1127 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1128\r
1129 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
1130\r
1131 //\r
1132 // Requery IDE IO resources in case of the switch of native and legacy modes\r
1133 //\r
1134 ReassignIdeResources (IdeBlkIoDevice);\r
1135\r
1136 //\r
1137 // For ATA compatible device, use ATA read block's mechanism\r
1138 //\r
1139 if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
1140 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
1141 Status = AtaBlkIoReadBlocks (\r
1142 IdeBlkIoDevice,\r
1143 MediaId,\r
1144 LBA,\r
1145 BufferSize,\r
1146 Buffer\r
1147 );\r
1148 goto Done;\r
1149 }\r
1150\r
1151 if (IdeBlkIoDevice->Type == IdeUnknown) {\r
1152 Status = EFI_DEVICE_ERROR;\r
1153 goto Done;\r
1154 }\r
1155\r
1156 //\r
1157 // for ATAPI device, using ATAPI read block's mechanism\r
1158 //\r
1159 Status = AtapiBlkIoReadBlocks (\r
1160 IdeBlkIoDevice,\r
1161 MediaId,\r
1162 LBA,\r
1163 BufferSize,\r
1164 Buffer\r
1165 );\r
1166\r
1167Done:\r
1168 gBS->RestoreTPL (OldTpl);\r
1169\r
1170 return Status;\r
1171}\r
1172\r
1173/**\r
1174 Write data to block io device\r
1175\r
1176 @param This Protocol instance pointer.\r
1177 @param MediaId The media ID of the device\r
1178 @param LBA Starting LBA address to write data\r
1179 @param BufferSize The size of data to be written\r
1180 @param Buffer Caller supplied buffer to save data\r
1181\r
1182 @return write data status\r
1183\r
1184**/\r
1185EFI_STATUS\r
1186EFIAPI\r
1187IDEBlkIoWriteBlocks (\r
1188 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1189 IN UINT32 MediaId,\r
1190 IN EFI_LBA LBA,\r
1191 IN UINTN BufferSize,\r
1192 IN VOID *Buffer\r
1193 )\r
1194// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
1195{\r
1196 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1197 EFI_STATUS Status;\r
1198 EFI_TPL OldTpl;\r
1199\r
1200 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1201\r
1202 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
1203 //\r
1204 // Requery IDE IO resources in case of the switch of native and legacy modes\r
1205 //\r
1206 ReassignIdeResources (IdeBlkIoDevice);\r
1207\r
1208 //\r
1209 // for ATA device, using ATA write block's mechanism\r
1210 //\r
1211 if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
1212 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
1213\r
1214 Status = AtaBlkIoWriteBlocks (\r
1215 IdeBlkIoDevice,\r
1216 MediaId,\r
1217 LBA,\r
1218 BufferSize,\r
1219 Buffer\r
1220 );\r
1221 goto Done;\r
1222 }\r
1223\r
1224 if (IdeBlkIoDevice->Type == IdeUnknown) {\r
1225 Status = EFI_DEVICE_ERROR;\r
1226 goto Done;\r
1227 }\r
1228\r
1229 //\r
1230 // for ATAPI device, using ATAPI write block's mechanism\r
1231 //\r
1232 Status = AtapiBlkIoWriteBlocks (\r
1233 IdeBlkIoDevice,\r
1234 MediaId,\r
1235 LBA,\r
1236 BufferSize,\r
1237 Buffer\r
1238 );\r
1239\r
1240Done:\r
1241 gBS->RestoreTPL (OldTpl);\r
1242 return Status;\r
1243}\r
1244\r
1245//\r
1246// ***********************************************************************************\r
1247// IDEBlkIoFlushBlocks\r
1248// ***********************************************************************************\r
1249//\r
1250/**\r
eeefcb9d 1251 TODO: Add function description\r
1252\r
1253 @param This TODO: add argument description\r
1254\r
1255 @retval EFI_SUCCESS GC_TODO: Add description for return value.\r
1256\r
ead42efc 1257**/\r
1258EFI_STATUS\r
1259EFIAPI\r
1260IDEBlkIoFlushBlocks (\r
1261 IN EFI_BLOCK_IO_PROTOCOL *This\r
1262 )\r
1263{\r
1264 //\r
1265 // return directly\r
1266 //\r
1267 return EFI_SUCCESS;\r
1268}\r
1269\r
1270/**\r
1271 Return the results of the Inquiry command to a drive in InquiryData.\r
1272 Data format of Inquiry data is defined by the Interface GUID.\r
1273\r
1274 @param This Protocol instance pointer.\r
1275 @param InquiryData Results of Inquiry command to device\r
1276 @param InquiryDataSize Size of InquiryData in bytes.\r
1277\r
1278 @retval EFI_SUCCESS InquiryData valid\r
1279 @retval EFI_NOT_FOUND Device does not support this data class\r
1280 @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
1281 @retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough\r
1282\r
1283**/\r
1284EFI_STATUS\r
1285EFIAPI\r
1286IDEDiskInfoInquiry (\r
1287 IN EFI_DISK_INFO_PROTOCOL *This,\r
1288 IN OUT VOID *InquiryData,\r
1289 IN OUT UINT32 *InquiryDataSize\r
1290 )\r
1291{\r
1292 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1293\r
1294 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
1295\r
1e23bd8d 1296 if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) {\r
1297 *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
ead42efc 1298 return EFI_BUFFER_TOO_SMALL;\r
1299 }\r
1300\r
1301 if (IdeBlkIoDevice->pInquiryData == NULL) {\r
1302 return EFI_NOT_FOUND;\r
1303 }\r
1304\r
1e23bd8d 1305 gBS->CopyMem (InquiryData, IdeBlkIoDevice->pInquiryData, sizeof (ATAPI_INQUIRY_DATA));\r
1306 *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
ead42efc 1307\r
1308 return EFI_SUCCESS;\r
1309}\r
1310\r
1311/**\r
1312 Return the results of the Identify command to a drive in IdentifyData.\r
1313 Data format of Identify data is defined by the Interface GUID.\r
1314\r
1315 @param This Protocol instance pointer.\r
1316 @param IdentifyData Results of Identify command to device\r
1317 @param IdentifyDataSize Size of IdentifyData in bytes.\r
1318\r
1319 @retval EFI_SUCCESS IdentifyData valid\r
1320 @retval EFI_NOT_FOUND Device does not support this data class\r
1321 @retval EFI_DEVICE_ERROR Error reading IdentifyData from device\r
1322 @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough\r
1323\r
1324**/\r
1325EFI_STATUS\r
1326EFIAPI\r
1327IDEDiskInfoIdentify (\r
1328 IN EFI_DISK_INFO_PROTOCOL *This,\r
1329 IN OUT VOID *IdentifyData,\r
1330 IN OUT UINT32 *IdentifyDataSize\r
1331 )\r
1332{\r
1333 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1334\r
1335 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
1336\r
1337 if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {\r
1338 *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
1339 return EFI_BUFFER_TOO_SMALL;\r
1340 }\r
1341\r
1342 if (IdeBlkIoDevice->pIdData == NULL) {\r
1343 return EFI_NOT_FOUND;\r
1344 }\r
1345\r
1346 gBS->CopyMem (IdentifyData, IdeBlkIoDevice->pIdData, sizeof (EFI_IDENTIFY_DATA));\r
1347 *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
1348\r
1349 return EFI_SUCCESS;\r
1350}\r
1351\r
1352/**\r
1353 Return the results of the Request Sense command to a drive in SenseData.\r
1354 Data format of Sense data is defined by the Interface GUID.\r
1355\r
1356 @param This Protocol instance pointer.\r
1357 @param SenseData Results of Request Sense command to device\r
1358 @param SenseDataSize Size of SenseData in bytes.\r
1359 @param SenseDataNumber Type of SenseData\r
1360\r
1361 @retval EFI_SUCCESS InquiryData valid\r
1362 @retval EFI_NOT_FOUND Device does not support this data class\r
1363 @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
1364 @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough\r
1365\r
1366**/\r
1367EFI_STATUS\r
1368EFIAPI\r
1369IDEDiskInfoSenseData (\r
1370 IN EFI_DISK_INFO_PROTOCOL *This,\r
1371 IN OUT VOID *SenseData,\r
1372 IN OUT UINT32 *SenseDataSize,\r
1373 OUT UINT8 *SenseDataNumber\r
1374 )\r
1375{\r
1376 return EFI_NOT_FOUND;\r
1377}\r
1378\r
1379/**\r
1380 Return the results of the Request Sense command to a drive in SenseData.\r
1381 Data format of Sense data is defined by the Interface GUID.\r
1382\r
1383 @param This Protocol instance pointer.\r
1384 @param IdeChannel Primary or Secondary\r
1385 @param IdeDevice Master or Slave\r
1386\r
1387 @retval EFI_SUCCESS IdeChannel and IdeDevice are valid\r
1388 @retval EFI_UNSUPPORTED This is not an IDE device\r
1389\r
1390**/\r
1391EFI_STATUS\r
1392EFIAPI\r
1393IDEDiskInfoWhichIde (\r
1394 IN EFI_DISK_INFO_PROTOCOL *This,\r
1395 OUT UINT32 *IdeChannel,\r
1396 OUT UINT32 *IdeDevice\r
1397 )\r
1398{\r
1399 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1400\r
1401 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
1402 *IdeChannel = IdeBlkIoDevice->Channel;\r
1403 *IdeDevice = IdeBlkIoDevice->Device;\r
1404\r
1405 return EFI_SUCCESS;\r
1406}\r
1407\r
1408/**\r
1409 The user Entry Point for module IdeBus. The user code starts with this function.\r
1410\r
1411 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
1412 @param[in] SystemTable A pointer to the EFI System Table.\r
1413 \r
1414 @retval EFI_SUCCESS The entry point is executed successfully.\r
1415 @retval other Some error occurs when executing this entry point.\r
1416\r
1417**/\r
1418EFI_STATUS\r
1419EFIAPI\r
1420InitializeIdeBus(\r
1421 IN EFI_HANDLE ImageHandle,\r
1422 IN EFI_SYSTEM_TABLE *SystemTable\r
1423 )\r
1424{\r
1425 EFI_STATUS Status;\r
1426\r
1427 //\r
1428 // Install driver model protocol(s).\r
1429 //\r
dfc48464 1430 Status = EfiLibInstallAllDriverProtocols2 (\r
ead42efc 1431 ImageHandle,\r
1432 SystemTable,\r
1433 &gIDEBusDriverBinding,\r
1434 ImageHandle,\r
1435 &gIDEBusComponentName,\r
dfc48464 1436 &gIDEBusComponentName2,\r
1437 NULL,\r
52f1302e 1438 NULL,\r
dfc48464 1439 &gIDEBusDriverDiagnostics,\r
1440 &gIDEBusDriverDiagnostics2\r
ead42efc 1441 );\r
1442 ASSERT_EFI_ERROR (Status);\r
1443\r
1444 return Status;\r
1445}\r