]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBus.c
Code scrub for VgaMiniPortDxe.
[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
aa950314 363 if (BeginningIdeChannel >= IdeMaxChannel || EndIdeChannel >= IdeMaxChannel) {\r
364 Status = EFI_INVALID_PARAMETER;\r
365 goto ErrorExit;\r
366 }\r
367 if (BeginningIdeDevice >= IdeMaxDevice|| EndIdeDevice >= IdeMaxDevice) {\r
368 Status = EFI_INVALID_PARAMETER;\r
369 goto ErrorExit;\r
370 }\r
ead42efc 371 }\r
372\r
373 //\r
374 // Obtain IDE IO port registers' base addresses\r
375 //\r
376 Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);\r
377 if (EFI_ERROR (Status)) {\r
378 goto ErrorExit;\r
379 }\r
380\r
381 //\r
382 // Report status code: begin IdeBus initialization\r
383 //\r
384 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
385 EFI_PROGRESS_CODE,\r
386 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
387 ParentDevicePath\r
388 );\r
389\r
390 //\r
391 // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol\r
392 //\r
393 for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
394\r
395 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);\r
396\r
397 //\r
398 // now obtain channel information fron IdeControllerInit protocol. Step9\r
399 //\r
400 Status = IdeInit->GetChannelInfo (\r
401 IdeInit,\r
402 IdeChannel,\r
403 &ChannelEnabled,\r
404 &MaxDevices\r
405 );\r
406 if (EFI_ERROR (Status)) {\r
407 DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));\r
408 continue;\r
409 }\r
410\r
411 if (!ChannelEnabled) {\r
412 continue;\r
413 }\r
414\r
a1e3528b 415 EndIdeDevice = (UINT8) MIN ((MaxDevices - 1), EndIdeDevice);\r
ead42efc 416\r
417 //\r
418 // Now inform the IDE Controller Init Module. Sept10\r
419 //\r
420 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);\r
421\r
422 //\r
423 // No reset channel function implemented. Sept11\r
424 //\r
425 IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);\r
426\r
427 //\r
428 // Step13\r
429 //\r
430 IdeInit->NotifyPhase (\r
431 IdeInit,\r
432 EfiIdeBusBeforeDevicePresenceDetection,\r
433 IdeChannel\r
434 );\r
435\r
436 //\r
437 // Prepare to detect IDE device of this channel\r
438 //\r
439 InitializeIDEChannelData ();\r
440\r
441 //\r
442 // -- 1st inner loop --- Master/Slave ------------ Step14\r
443 //\r
444 for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
445 //\r
446 // Check whether the configuration options allow this device\r
447 //\r
97404058 448 if ((ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice))) == 0) {\r
ead42efc 449 continue;\r
450 }\r
451\r
452 //\r
453 // The device has been scanned in another Start(), No need to scan it again\r
454 // for perf optimization.\r
455 //\r
456 if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {\r
457 continue;\r
458 }\r
459\r
460 //\r
461 // create child handle for the detected device.\r
462 //\r
463 IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));\r
464 if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {\r
465 continue;\r
466 }\r
467\r
468 IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
469\r
470 ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));\r
471\r
472 IdeBlkIoDevicePtr->Signature = IDE_BLK_IO_DEV_SIGNATURE;\r
473 IdeBlkIoDevicePtr->Channel = (EFI_IDE_CHANNEL) IdeChannel;\r
474 IdeBlkIoDevicePtr->Device = (EFI_IDE_DEVICE) IdeDevice;\r
475\r
476 //\r
477 // initialize Block IO interface's Media pointer\r
478 //\r
479 IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;\r
480\r
481 //\r
482 // Initialize IDE IO port addresses, including Command Block registers\r
483 // and Control Block registers\r
484 //\r
485 IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));\r
486 if (IdeBlkIoDevicePtr->IoPort == NULL) {\r
487 continue;\r
488 }\r
489\r
490 ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));\r
491 CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;\r
492 ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;\r
493\r
494 IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;\r
495 (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);\r
496 IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
497 IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
498 IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
499 IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
500 IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
501 (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);\r
502\r
503 (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;\r
504 IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);\r
505\r
506 IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);\r
507\r
508 IdeBlkIoDevicePtr->PciIo = PciIo;\r
509 IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;\r
510 IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;\r
511\r
512 //\r
513 // Report Status code: is about to detect IDE drive\r
514 //\r
515 REPORT_STATUS_CODE_EX (\r
516 EFI_PROGRESS_CODE,\r
517 (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT),\r
518 0,\r
519 &gEfiCallerIdGuid,\r
520 NULL,\r
521 NULL,\r
522 0\r
523 );\r
524\r
525 //\r
526 // Discover device, now!\r
527 //\r
528 PERF_START (0, "DiscoverIdeDevice", "IDE", 0);\r
529 Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);\r
530 PERF_END (0, "DiscoverIdeDevice", "IDE", 0);\r
531\r
532 IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice] = TRUE;\r
533 IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = FALSE;\r
534\r
535 if (!EFI_ERROR (Status)) {\r
536 //\r
537 // Set Device Path\r
538 //\r
539 ZeroMem (&NewNode, sizeof (NewNode));\r
540 NewNode.DevPath.Type = MESSAGING_DEVICE_PATH;\r
541 NewNode.DevPath.SubType = MSG_ATAPI_DP;\r
542 SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));\r
543\r
544 NewNode.Atapi.PrimarySecondary = (UINT8) IdeBlkIoDevicePtr->Channel;\r
545 NewNode.Atapi.SlaveMaster = (UINT8) IdeBlkIoDevicePtr->Device;\r
546 NewNode.Atapi.Lun = IdeBlkIoDevicePtr->Lun;\r
547 IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (\r
548 ParentDevicePath,\r
549 &NewNode.DevPath\r
550 );\r
551 if (IdeBlkIoDevicePtr->DevicePath == NULL) {\r
552 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
553 continue;\r
554 }\r
555\r
556 //\r
557 // Submit identify data to IDE controller init driver\r
558 //\r
559 CopyMem (&IdentifyData, IdeBlkIoDevicePtr->pIdData, sizeof (IdentifyData));\r
560 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;\r
561 IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);\r
562 } else {\r
563 //\r
564 // Device detection failed\r
565 //\r
566 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
567 IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);\r
568 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
569 IdeBlkIoDevicePtr = NULL;\r
570 }\r
571 //\r
572 // end of 1st inner loop ---\r
573 //\r
574 }\r
575 //\r
576 // end of 1st outer loop =========\r
577 //\r
578 }\r
579\r
580 //\r
581 // = 2nd outer loop == Primary/Secondary =================\r
582 //\r
583 for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
584\r
585 //\r
586 // -- 2nd inner loop --- Master/Slave --------\r
587 //\r
588 for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
589\r
590 if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {\r
591 continue;\r
592 }\r
593\r
594 if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {\r
595 continue;\r
596 }\r
597\r
598 Status = IdeInit->CalculateMode (\r
599 IdeInit,\r
600 IdeChannel,\r
601 IdeDevice,\r
602 &SupportedModes\r
603 );\r
604 if (EFI_ERROR (Status)) {\r
605 DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));\r
606 continue;\r
607 }\r
608\r
609 IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
610\r
611 //\r
612 // Set best supported PIO mode on this IDE device\r
613 //\r
614 if (SupportedModes->PioMode.Mode <= ATA_PIO_MODE_2) {\r
615 TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;\r
616 } else {\r
617 TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;\r
618 }\r
619\r
620 TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);\r
621\r
622 if (SupportedModes->ExtModeCount == 0){\r
623 Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
624\r
625 if (EFI_ERROR (Status)) {\r
626 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
627 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
628 IdeBlkIoDevicePtr = NULL;\r
629 continue;\r
630 }\r
631 }\r
632\r
633 //\r
634 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't\r
635 // be set together. Only one DMA mode can be set to a device. If setting\r
636 // DMA mode operation fails, we can continue moving on because we only use\r
637 // PIO mode at boot time. DMA modes are used by certain kind of OS booting\r
638 //\r
639 if (SupportedModes->UdmaMode.Valid) {\r
640\r
641 TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;\r
642 TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);\r
643 Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
644\r
645 if (EFI_ERROR (Status)) {\r
646 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
647 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
648 IdeBlkIoDevicePtr = NULL;\r
649 continue;\r
650 }\r
651 //\r
652 // Record Udma Mode\r
653 //\r
654 IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;\r
655 IdeBlkIoDevicePtr->UdmaMode.Mode = SupportedModes->UdmaMode.Mode;\r
656 EnableInterrupt (IdeBlkIoDevicePtr);\r
657 } else if (SupportedModes->MultiWordDmaMode.Valid) {\r
658\r
659 TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;\r
660 TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;\r
661 Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
662\r
663 if (EFI_ERROR (Status)) {\r
664 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
665 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
666 IdeBlkIoDevicePtr = NULL;\r
667 continue;\r
668 }\r
669\r
670 EnableInterrupt (IdeBlkIoDevicePtr);\r
671 }\r
672 //\r
673 // Init driver parameters\r
674 //\r
675 DriveParameters.Sector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.sectors_per_track;\r
676 DriveParameters.Heads = (UINT8) (IdeBlkIoDevicePtr->pIdData->AtaData.heads - 1);\r
677 DriveParameters.MultipleSector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.multi_sector_cmd_max_sct_cnt;\r
678 //\r
679 // Set Parameters for the device:\r
680 // 1) Init\r
681 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command\r
682 //\r
683 if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {\r
684 Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);\r
685 }\r
686\r
687 //\r
688 // Record PIO mode used in private data\r
689 //\r
690 IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;\r
691\r
692 //\r
693 // Set IDE controller Timing Blocks in the PCI Configuration Space\r
694 //\r
695 IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);\r
696\r
697 //\r
698 // Add Component Name for the IDE/ATAPI device that was discovered.\r
699 //\r
700 IdeBlkIoDevicePtr->ControllerNameTable = NULL;\r
701 ADD_NAME (IdeBlkIoDevicePtr);\r
702\r
703 Status = gBS->InstallMultipleProtocolInterfaces (\r
704 &IdeBlkIoDevicePtr->Handle,\r
705 &gEfiDevicePathProtocolGuid,\r
706 IdeBlkIoDevicePtr->DevicePath,\r
707 &gEfiBlockIoProtocolGuid,\r
708 &IdeBlkIoDevicePtr->BlkIo,\r
709 &gEfiDiskInfoProtocolGuid,\r
710 &IdeBlkIoDevicePtr->DiskInfo,\r
711 NULL\r
712 );\r
713\r
714 if (EFI_ERROR (Status)) {\r
715 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
716 }\r
717\r
718 gBS->OpenProtocol (\r
719 Controller,\r
720 &gEfiPciIoProtocolGuid,\r
721 (VOID **) &PciIo,\r
722 This->DriverBindingHandle,\r
723 IdeBlkIoDevicePtr->Handle,\r
724 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
725 );\r
726\r
727 IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;\r
728\r
729 //\r
730 // Report status code: device eanbled!\r
731 //\r
732 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
733 EFI_PROGRESS_CODE,\r
734 (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),\r
735 IdeBlkIoDevicePtr->DevicePath\r
736 );\r
737\r
738 //\r
739 // Create event to clear pending IDE interrupt\r
740 //\r
6a27a4eb 741 Status = gBS->CreateEventEx (\r
742 EVT_NOTIFY_SIGNAL,\r
ead42efc 743 TPL_NOTIFY,\r
744 ClearInterrupt,\r
745 IdeBlkIoDevicePtr,\r
6a27a4eb 746 &gEfiEventExitBootServicesGuid,\r
ead42efc 747 &IdeBlkIoDevicePtr->ExitBootServiceEvent\r
748 );\r
749\r
750 //\r
751 // end of 2nd inner loop ----\r
752 //\r
753 }\r
754 //\r
755 // end of 2nd outer loop ==========\r
756 //\r
757 }\r
758\r
759 //\r
760 // All configurations done! Notify IdeController to do post initialization\r
761 // work such as saving IDE controller PCI settings for S3 resume\r
762 //\r
763 IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);\r
764\r
765 if (SupportedModes != NULL) {\r
766 gBS->FreePool (SupportedModes);\r
767 }\r
768\r
769 PERF_START (0, "Finish IDE detection", "IDE", 1);\r
770 PERF_END (0, "Finish IDE detection", "IDE", 0);\r
771\r
772 return EFI_SUCCESS;\r
773\r
774ErrorExit:\r
775\r
776 //\r
777 // Report error code: controller error\r
778 //\r
779 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
780 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
781 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),\r
782 ParentDevicePath\r
783 );\r
784\r
785 gBS->CloseProtocol (\r
786 Controller,\r
787 &gEfiIdeControllerInitProtocolGuid,\r
788 This->DriverBindingHandle,\r
789 Controller\r
790 );\r
791\r
792 gBS->UninstallMultipleProtocolInterfaces (\r
793 Controller,\r
794 &gEfiCallerIdGuid,\r
795 IdeBusDriverPrivateData,\r
796 NULL\r
797 );\r
798\r
799 if (IdeBusDriverPrivateData != NULL) {\r
800 gBS->FreePool (IdeBusDriverPrivateData);\r
801 }\r
802\r
803 if (SupportedModes != NULL) {\r
804 gBS->FreePool (SupportedModes);\r
805 }\r
806\r
807 gBS->CloseProtocol (\r
808 Controller,\r
809 &gEfiPciIoProtocolGuid,\r
810 This->DriverBindingHandle,\r
811 Controller\r
812 );\r
813\r
814 gBS->CloseProtocol (\r
815 Controller,\r
816 &gEfiDevicePathProtocolGuid,\r
817 This->DriverBindingHandle,\r
818 Controller\r
819 );\r
820\r
821 return Status;\r
822\r
823}\r
824\r
825//\r
826// ***********************************************************************************\r
827// IDEBusDriverBindingStop\r
828// ***********************************************************************************\r
829//\r
830/**\r
831 Stop this driver on Controller Handle.\r
832\r
833 @param This Protocol instance pointer.\r
97404058 834 @param Controller Handle of device to stop driver on\r
ead42efc 835 @param NumberOfChildren Not used\r
836 @param ChildHandleBuffer Not used\r
837\r
838 @retval EFI_SUCCESS This driver is removed DeviceHandle\r
839 @retval other This driver was not removed from this device\r
840\r
841**/\r
842EFI_STATUS\r
843EFIAPI\r
844IDEBusDriverBindingStop (\r
845 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
846 IN EFI_HANDLE Controller,\r
847 IN UINTN NumberOfChildren,\r
848 IN EFI_HANDLE *ChildHandleBuffer\r
849 )\r
850// TODO: Controller - add argument and description to function comment\r
851// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
852{\r
853 EFI_STATUS Status;\r
854 EFI_PCI_IO_PROTOCOL *PciIo;\r
855 BOOLEAN AllChildrenStopped;\r
856 UINTN Index;\r
857 IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
96f6af14 858 UINT64 Supports;\r
ead42efc 859\r
860 IdeBusDriverPrivateData = NULL;\r
861\r
862 if (NumberOfChildren == 0) {\r
863\r
864 Status = gBS->OpenProtocol (\r
865 Controller,\r
866 &gEfiPciIoProtocolGuid,\r
867 (VOID **) &PciIo,\r
868 This->DriverBindingHandle,\r
869 Controller,\r
870 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
871 );\r
872 if (!EFI_ERROR (Status)) {\r
96f6af14
LG
873 Status = PciIo->Attributes (\r
874 PciIo,\r
875 EfiPciIoAttributeOperationSupported,\r
876 0,\r
877 &Supports\r
878 );\r
879 if (!EFI_ERROR (Status)) {\r
880 Supports &= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;\r
881 PciIo->Attributes (\r
882 PciIo,\r
883 EfiPciIoAttributeOperationDisable,\r
884 Supports,\r
885 NULL\r
886 );\r
887 }\r
ead42efc 888 }\r
889\r
890 gBS->OpenProtocol (\r
891 Controller,\r
892 &gEfiCallerIdGuid,\r
893 (VOID **) &IdeBusDriverPrivateData,\r
894 This->DriverBindingHandle,\r
895 Controller,\r
896 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
897 );\r
898\r
899 gBS->UninstallMultipleProtocolInterfaces (\r
900 Controller,\r
901 &gEfiCallerIdGuid,\r
902 IdeBusDriverPrivateData,\r
903 NULL\r
904 );\r
905\r
906 if (IdeBusDriverPrivateData != NULL) {\r
907 gBS->FreePool (IdeBusDriverPrivateData);\r
908 }\r
909 //\r
910 // Close the bus driver\r
911 //\r
912 gBS->CloseProtocol (\r
913 Controller,\r
914 &gEfiIdeControllerInitProtocolGuid,\r
915 This->DriverBindingHandle,\r
916 Controller\r
917 );\r
918 gBS->CloseProtocol (\r
919 Controller,\r
920 &gEfiPciIoProtocolGuid,\r
921 This->DriverBindingHandle,\r
922 Controller\r
923 );\r
924 gBS->CloseProtocol (\r
925 Controller,\r
926 &gEfiDevicePathProtocolGuid,\r
927 This->DriverBindingHandle,\r
928 Controller\r
929 );\r
930\r
931 return EFI_SUCCESS;\r
932 }\r
933\r
934 AllChildrenStopped = TRUE;\r
935\r
936 for (Index = 0; Index < NumberOfChildren; Index++) {\r
937\r
938 Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);\r
939\r
940 if (EFI_ERROR (Status)) {\r
941 AllChildrenStopped = FALSE;\r
942 }\r
943 }\r
944\r
945 if (!AllChildrenStopped) {\r
946 return EFI_DEVICE_ERROR;\r
947 }\r
948\r
949 return EFI_SUCCESS;\r
950}\r
951\r
952//\r
953// ***********************************************************************************\r
954// DeRegisterIdeDevice\r
955// ***********************************************************************************\r
956//\r
957/**\r
958 Deregister an IDE device and free resources\r
959\r
960 @param This Protocol instance pointer.\r
961 @param Controller Ide device handle\r
962 @param Handle Handle of device to deregister driver on\r
963\r
964 @return EFI_STATUS\r
965\r
966**/\r
967EFI_STATUS\r
968DeRegisterIdeDevice (\r
969 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
970 IN EFI_HANDLE Controller,\r
971 IN EFI_HANDLE Handle\r
972 )\r
973// TODO: EFI_SUCCESS - add return value to function comment\r
974{\r
975 EFI_STATUS Status;\r
976 EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
977 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
978 EFI_PCI_IO_PROTOCOL *PciIo;\r
979 UINTN Index;\r
980\r
981 Status = gBS->OpenProtocol (\r
982 Handle,\r
983 &gEfiBlockIoProtocolGuid,\r
984 (VOID **) &BlkIo,\r
985 This->DriverBindingHandle,\r
986 Controller,\r
987 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
988 );\r
989 if (EFI_ERROR (Status)) {\r
990 return Status;\r
991 }\r
992\r
993 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);\r
994\r
995 //\r
996 // Report Status code: Device disabled\r
997 //\r
998 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
999 EFI_PROGRESS_CODE,\r
1000 (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),\r
1001 IdeBlkIoDevice->DevicePath\r
1002 );\r
1003\r
1004 //\r
1005 // Close the child handle\r
1006 //\r
1007 Status = gBS->CloseProtocol (\r
1008 Controller,\r
1009 &gEfiPciIoProtocolGuid,\r
1010 This->DriverBindingHandle,\r
1011 Handle\r
1012 );\r
1013\r
1014 Status = gBS->UninstallMultipleProtocolInterfaces (\r
1015 Handle,\r
1016 &gEfiDevicePathProtocolGuid,\r
1017 IdeBlkIoDevice->DevicePath,\r
1018 &gEfiBlockIoProtocolGuid,\r
1019 &IdeBlkIoDevice->BlkIo,\r
1020 &gEfiDiskInfoProtocolGuid,\r
1021 &IdeBlkIoDevice->DiskInfo,\r
1022 NULL\r
1023 );\r
1024\r
1025 if (EFI_ERROR (Status)) {\r
1026 gBS->OpenProtocol (\r
1027 Controller,\r
1028 &gEfiPciIoProtocolGuid,\r
1029 (VOID **) &PciIo,\r
1030 This->DriverBindingHandle,\r
1031 Handle,\r
1032 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1033 );\r
1034 return Status;\r
1035 }\r
1036\r
1037 //\r
1038 // Release allocated resources\r
1039 //\r
1040 Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;\r
aa950314 1041 if (Index < MAX_IDE_DEVICE) {\r
1042 IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;\r
1043 }\r
ead42efc 1044 ReleaseIdeResources (IdeBlkIoDevice);\r
1045\r
1046 return EFI_SUCCESS;\r
1047}\r
1048\r
1049//\r
1050// ***********************************************************************************\r
1051// IDEBlkIoReset\r
1052// ***********************************************************************************\r
1053//\r
1054/**\r
eeefcb9d 1055 GC_TODO: Add function description\r
1056\r
1057 @param This GC_TODO: add argument description.\r
1058 @param ExtendedVerification GC_TODO: add argument description.\r
1059\r
1060 @retval EFI_DEVICE_ERROR GC_TODO: Add description for return value.\r
ead42efc 1061\r
1062**/\r
1063EFI_STATUS\r
1064EFIAPI\r
1065IDEBlkIoReset (\r
1066 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1067 IN BOOLEAN ExtendedVerification\r
1068 )\r
1069{\r
1070 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1071 EFI_STATUS Status;\r
1072 EFI_TPL OldTpl;\r
1073\r
1074 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1075\r
1076 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
1077 //\r
1078 // Requery IDE IO resources in case of the switch of native and legacy modes\r
1079 //\r
1080 ReassignIdeResources (IdeBlkIoDevice);\r
1081\r
1082 //\r
1083 // for ATA device, using ATA reset method\r
1084 //\r
1085 if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
1086 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
1087 Status = AtaSoftReset (IdeBlkIoDevice);\r
1088 goto Done;\r
1089 }\r
1090\r
1091 if (IdeBlkIoDevice->Type == IdeUnknown) {\r
1092 Status = EFI_DEVICE_ERROR;\r
1093 goto Done;\r
1094 }\r
1095\r
1096 //\r
1097 // for ATAPI device, using ATAPI reset method\r
1098 //\r
1099 Status = AtapiSoftReset (IdeBlkIoDevice);\r
1100 if (ExtendedVerification) {\r
1101 Status = AtaSoftReset (IdeBlkIoDevice);\r
1102 }\r
1103\r
1104Done:\r
1105 gBS->RestoreTPL (OldTpl);\r
1106 return Status;\r
1107}\r
1108\r
1109/**\r
1110 Read data from block io device\r
1111\r
1112 @param This Protocol instance pointer.\r
1113 @param MediaId The media ID of the device\r
1114 @param LBA Starting LBA address to read data\r
1115 @param BufferSize The size of data to be read\r
1116 @param Buffer Caller supplied buffer to save data\r
1117\r
1118 @return read data status\r
1119\r
1120**/\r
1121EFI_STATUS\r
1122EFIAPI\r
1123IDEBlkIoReadBlocks (\r
1124 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1125 IN UINT32 MediaId,\r
1126 IN EFI_LBA LBA,\r
1127 IN UINTN BufferSize,\r
1128 OUT VOID *Buffer\r
1129 )\r
1130// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
1131{\r
1132 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1133 EFI_STATUS Status;\r
1134 EFI_TPL OldTpl;\r
1135\r
1136 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1137\r
1138 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
1139\r
1140 //\r
1141 // Requery IDE IO resources in case of the switch of native and legacy modes\r
1142 //\r
1143 ReassignIdeResources (IdeBlkIoDevice);\r
1144\r
1145 //\r
1146 // For ATA compatible device, use ATA read block's mechanism\r
1147 //\r
1148 if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
1149 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
1150 Status = AtaBlkIoReadBlocks (\r
1151 IdeBlkIoDevice,\r
1152 MediaId,\r
1153 LBA,\r
1154 BufferSize,\r
1155 Buffer\r
1156 );\r
1157 goto Done;\r
1158 }\r
1159\r
1160 if (IdeBlkIoDevice->Type == IdeUnknown) {\r
1161 Status = EFI_DEVICE_ERROR;\r
1162 goto Done;\r
1163 }\r
1164\r
1165 //\r
1166 // for ATAPI device, using ATAPI read block's mechanism\r
1167 //\r
1168 Status = AtapiBlkIoReadBlocks (\r
1169 IdeBlkIoDevice,\r
1170 MediaId,\r
1171 LBA,\r
1172 BufferSize,\r
1173 Buffer\r
1174 );\r
1175\r
1176Done:\r
1177 gBS->RestoreTPL (OldTpl);\r
1178\r
1179 return Status;\r
1180}\r
1181\r
1182/**\r
1183 Write data to block io device\r
1184\r
1185 @param This Protocol instance pointer.\r
1186 @param MediaId The media ID of the device\r
1187 @param LBA Starting LBA address to write data\r
1188 @param BufferSize The size of data to be written\r
1189 @param Buffer Caller supplied buffer to save data\r
1190\r
1191 @return write data status\r
1192\r
1193**/\r
1194EFI_STATUS\r
1195EFIAPI\r
1196IDEBlkIoWriteBlocks (\r
1197 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1198 IN UINT32 MediaId,\r
1199 IN EFI_LBA LBA,\r
1200 IN UINTN BufferSize,\r
1201 IN VOID *Buffer\r
1202 )\r
1203// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
1204{\r
1205 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1206 EFI_STATUS Status;\r
1207 EFI_TPL OldTpl;\r
1208\r
1209 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1210\r
1211 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
1212 //\r
1213 // Requery IDE IO resources in case of the switch of native and legacy modes\r
1214 //\r
1215 ReassignIdeResources (IdeBlkIoDevice);\r
1216\r
1217 //\r
1218 // for ATA device, using ATA write block's mechanism\r
1219 //\r
1220 if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
1221 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
1222\r
1223 Status = AtaBlkIoWriteBlocks (\r
1224 IdeBlkIoDevice,\r
1225 MediaId,\r
1226 LBA,\r
1227 BufferSize,\r
1228 Buffer\r
1229 );\r
1230 goto Done;\r
1231 }\r
1232\r
1233 if (IdeBlkIoDevice->Type == IdeUnknown) {\r
1234 Status = EFI_DEVICE_ERROR;\r
1235 goto Done;\r
1236 }\r
1237\r
1238 //\r
1239 // for ATAPI device, using ATAPI write block's mechanism\r
1240 //\r
1241 Status = AtapiBlkIoWriteBlocks (\r
1242 IdeBlkIoDevice,\r
1243 MediaId,\r
1244 LBA,\r
1245 BufferSize,\r
1246 Buffer\r
1247 );\r
1248\r
1249Done:\r
1250 gBS->RestoreTPL (OldTpl);\r
1251 return Status;\r
1252}\r
1253\r
1254//\r
1255// ***********************************************************************************\r
1256// IDEBlkIoFlushBlocks\r
1257// ***********************************************************************************\r
1258//\r
1259/**\r
eeefcb9d 1260 TODO: Add function description\r
1261\r
1262 @param This TODO: add argument description\r
1263\r
1264 @retval EFI_SUCCESS GC_TODO: Add description for return value.\r
1265\r
ead42efc 1266**/\r
1267EFI_STATUS\r
1268EFIAPI\r
1269IDEBlkIoFlushBlocks (\r
1270 IN EFI_BLOCK_IO_PROTOCOL *This\r
1271 )\r
1272{\r
1273 //\r
1274 // return directly\r
1275 //\r
1276 return EFI_SUCCESS;\r
1277}\r
1278\r
1279/**\r
1280 Return the results of the Inquiry command to a drive in InquiryData.\r
1281 Data format of Inquiry data is defined by the Interface GUID.\r
1282\r
1283 @param This Protocol instance pointer.\r
1284 @param InquiryData Results of Inquiry command to device\r
1285 @param InquiryDataSize Size of InquiryData in bytes.\r
1286\r
1287 @retval EFI_SUCCESS InquiryData valid\r
1288 @retval EFI_NOT_FOUND Device does not support this data class\r
1289 @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
1290 @retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough\r
1291\r
1292**/\r
1293EFI_STATUS\r
1294EFIAPI\r
1295IDEDiskInfoInquiry (\r
1296 IN EFI_DISK_INFO_PROTOCOL *This,\r
1297 IN OUT VOID *InquiryData,\r
1298 IN OUT UINT32 *InquiryDataSize\r
1299 )\r
1300{\r
1301 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1302\r
1303 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
1304\r
1e23bd8d 1305 if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) {\r
1306 *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
ead42efc 1307 return EFI_BUFFER_TOO_SMALL;\r
1308 }\r
1309\r
1310 if (IdeBlkIoDevice->pInquiryData == NULL) {\r
1311 return EFI_NOT_FOUND;\r
1312 }\r
1313\r
1e23bd8d 1314 gBS->CopyMem (InquiryData, IdeBlkIoDevice->pInquiryData, sizeof (ATAPI_INQUIRY_DATA));\r
1315 *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
ead42efc 1316\r
1317 return EFI_SUCCESS;\r
1318}\r
1319\r
1320/**\r
1321 Return the results of the Identify command to a drive in IdentifyData.\r
1322 Data format of Identify data is defined by the Interface GUID.\r
1323\r
1324 @param This Protocol instance pointer.\r
1325 @param IdentifyData Results of Identify command to device\r
1326 @param IdentifyDataSize Size of IdentifyData in bytes.\r
1327\r
1328 @retval EFI_SUCCESS IdentifyData valid\r
1329 @retval EFI_NOT_FOUND Device does not support this data class\r
1330 @retval EFI_DEVICE_ERROR Error reading IdentifyData from device\r
1331 @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough\r
1332\r
1333**/\r
1334EFI_STATUS\r
1335EFIAPI\r
1336IDEDiskInfoIdentify (\r
1337 IN EFI_DISK_INFO_PROTOCOL *This,\r
1338 IN OUT VOID *IdentifyData,\r
1339 IN OUT UINT32 *IdentifyDataSize\r
1340 )\r
1341{\r
1342 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1343\r
1344 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
1345\r
1346 if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {\r
1347 *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
1348 return EFI_BUFFER_TOO_SMALL;\r
1349 }\r
1350\r
1351 if (IdeBlkIoDevice->pIdData == NULL) {\r
1352 return EFI_NOT_FOUND;\r
1353 }\r
1354\r
1355 gBS->CopyMem (IdentifyData, IdeBlkIoDevice->pIdData, sizeof (EFI_IDENTIFY_DATA));\r
1356 *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
1357\r
1358 return EFI_SUCCESS;\r
1359}\r
1360\r
1361/**\r
1362 Return the results of the Request Sense command to a drive in SenseData.\r
1363 Data format of Sense data is defined by the Interface GUID.\r
1364\r
1365 @param This Protocol instance pointer.\r
1366 @param SenseData Results of Request Sense command to device\r
1367 @param SenseDataSize Size of SenseData in bytes.\r
1368 @param SenseDataNumber Type of SenseData\r
1369\r
1370 @retval EFI_SUCCESS InquiryData valid\r
1371 @retval EFI_NOT_FOUND Device does not support this data class\r
1372 @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
1373 @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough\r
1374\r
1375**/\r
1376EFI_STATUS\r
1377EFIAPI\r
1378IDEDiskInfoSenseData (\r
1379 IN EFI_DISK_INFO_PROTOCOL *This,\r
1380 IN OUT VOID *SenseData,\r
1381 IN OUT UINT32 *SenseDataSize,\r
1382 OUT UINT8 *SenseDataNumber\r
1383 )\r
1384{\r
1385 return EFI_NOT_FOUND;\r
1386}\r
1387\r
1388/**\r
1389 Return the results of the Request Sense command to a drive in SenseData.\r
1390 Data format of Sense data is defined by the Interface GUID.\r
1391\r
1392 @param This Protocol instance pointer.\r
1393 @param IdeChannel Primary or Secondary\r
1394 @param IdeDevice Master or Slave\r
1395\r
1396 @retval EFI_SUCCESS IdeChannel and IdeDevice are valid\r
1397 @retval EFI_UNSUPPORTED This is not an IDE device\r
1398\r
1399**/\r
1400EFI_STATUS\r
1401EFIAPI\r
1402IDEDiskInfoWhichIde (\r
1403 IN EFI_DISK_INFO_PROTOCOL *This,\r
1404 OUT UINT32 *IdeChannel,\r
1405 OUT UINT32 *IdeDevice\r
1406 )\r
1407{\r
1408 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1409\r
1410 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
1411 *IdeChannel = IdeBlkIoDevice->Channel;\r
1412 *IdeDevice = IdeBlkIoDevice->Device;\r
1413\r
1414 return EFI_SUCCESS;\r
1415}\r
1416\r
1417/**\r
1418 The user Entry Point for module IdeBus. The user code starts with this function.\r
1419\r
1420 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
1421 @param[in] SystemTable A pointer to the EFI System Table.\r
1422 \r
1423 @retval EFI_SUCCESS The entry point is executed successfully.\r
1424 @retval other Some error occurs when executing this entry point.\r
1425\r
1426**/\r
1427EFI_STATUS\r
1428EFIAPI\r
1429InitializeIdeBus(\r
1430 IN EFI_HANDLE ImageHandle,\r
1431 IN EFI_SYSTEM_TABLE *SystemTable\r
1432 )\r
1433{\r
1434 EFI_STATUS Status;\r
1435\r
1436 //\r
1437 // Install driver model protocol(s).\r
1438 //\r
dfc48464 1439 Status = EfiLibInstallAllDriverProtocols2 (\r
ead42efc 1440 ImageHandle,\r
1441 SystemTable,\r
1442 &gIDEBusDriverBinding,\r
1443 ImageHandle,\r
1444 &gIDEBusComponentName,\r
dfc48464 1445 &gIDEBusComponentName2,\r
1446 NULL,\r
52f1302e 1447 NULL,\r
dfc48464 1448 &gIDEBusDriverDiagnostics,\r
1449 &gIDEBusDriverDiagnostics2\r
ead42efc 1450 );\r
1451 ASSERT_EFI_ERROR (Status);\r
1452\r
1453 return Status;\r
1454}\r