]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.c
Remove the special logic on EFI_PCI_DEVICE_ENABLE in PciBus driver. And update driver...
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / IdeBusDxe / idebus.c
CommitLineData
ead42efc 1/** @file\r
2 Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
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
16#include "idebus.h"\r
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
440 if (!(ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice)))) {\r
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
733 Status = gBS->CreateEvent (\r
734 EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
735 TPL_NOTIFY,\r
736 ClearInterrupt,\r
737 IdeBlkIoDevicePtr,\r
738 &IdeBlkIoDevicePtr->ExitBootServiceEvent\r
739 );\r
740\r
741 //\r
742 // end of 2nd inner loop ----\r
743 //\r
744 }\r
745 //\r
746 // end of 2nd outer loop ==========\r
747 //\r
748 }\r
749\r
750 //\r
751 // All configurations done! Notify IdeController to do post initialization\r
752 // work such as saving IDE controller PCI settings for S3 resume\r
753 //\r
754 IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);\r
755\r
756 if (SupportedModes != NULL) {\r
757 gBS->FreePool (SupportedModes);\r
758 }\r
759\r
760 PERF_START (0, "Finish IDE detection", "IDE", 1);\r
761 PERF_END (0, "Finish IDE detection", "IDE", 0);\r
762\r
763 return EFI_SUCCESS;\r
764\r
765ErrorExit:\r
766\r
767 //\r
768 // Report error code: controller error\r
769 //\r
770 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
771 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
772 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),\r
773 ParentDevicePath\r
774 );\r
775\r
776 gBS->CloseProtocol (\r
777 Controller,\r
778 &gEfiIdeControllerInitProtocolGuid,\r
779 This->DriverBindingHandle,\r
780 Controller\r
781 );\r
782\r
783 gBS->UninstallMultipleProtocolInterfaces (\r
784 Controller,\r
785 &gEfiCallerIdGuid,\r
786 IdeBusDriverPrivateData,\r
787 NULL\r
788 );\r
789\r
790 if (IdeBusDriverPrivateData != NULL) {\r
791 gBS->FreePool (IdeBusDriverPrivateData);\r
792 }\r
793\r
794 if (SupportedModes != NULL) {\r
795 gBS->FreePool (SupportedModes);\r
796 }\r
797\r
798 gBS->CloseProtocol (\r
799 Controller,\r
800 &gEfiPciIoProtocolGuid,\r
801 This->DriverBindingHandle,\r
802 Controller\r
803 );\r
804\r
805 gBS->CloseProtocol (\r
806 Controller,\r
807 &gEfiDevicePathProtocolGuid,\r
808 This->DriverBindingHandle,\r
809 Controller\r
810 );\r
811\r
812 return Status;\r
813\r
814}\r
815\r
816//\r
817// ***********************************************************************************\r
818// IDEBusDriverBindingStop\r
819// ***********************************************************************************\r
820//\r
821/**\r
822 Stop this driver on Controller Handle.\r
823\r
824 @param This Protocol instance pointer.\r
825 @param DeviceHandle Handle of device to stop driver on\r
826 @param NumberOfChildren Not used\r
827 @param ChildHandleBuffer Not used\r
828\r
829 @retval EFI_SUCCESS This driver is removed DeviceHandle\r
830 @retval other This driver was not removed from this device\r
831\r
832**/\r
833EFI_STATUS\r
834EFIAPI\r
835IDEBusDriverBindingStop (\r
836 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
837 IN EFI_HANDLE Controller,\r
838 IN UINTN NumberOfChildren,\r
839 IN EFI_HANDLE *ChildHandleBuffer\r
840 )\r
841// TODO: Controller - add argument and description to function comment\r
842// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
843{\r
844 EFI_STATUS Status;\r
845 EFI_PCI_IO_PROTOCOL *PciIo;\r
846 BOOLEAN AllChildrenStopped;\r
847 UINTN Index;\r
848 IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
96f6af14 849 UINT64 Supports;\r
ead42efc 850\r
851 IdeBusDriverPrivateData = NULL;\r
852\r
853 if (NumberOfChildren == 0) {\r
854\r
855 Status = gBS->OpenProtocol (\r
856 Controller,\r
857 &gEfiPciIoProtocolGuid,\r
858 (VOID **) &PciIo,\r
859 This->DriverBindingHandle,\r
860 Controller,\r
861 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
862 );\r
863 if (!EFI_ERROR (Status)) {\r
96f6af14
LG
864 Status = PciIo->Attributes (\r
865 PciIo,\r
866 EfiPciIoAttributeOperationSupported,\r
867 0,\r
868 &Supports\r
869 );\r
870 if (!EFI_ERROR (Status)) {\r
871 Supports &= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;\r
872 PciIo->Attributes (\r
873 PciIo,\r
874 EfiPciIoAttributeOperationDisable,\r
875 Supports,\r
876 NULL\r
877 );\r
878 }\r
ead42efc 879 }\r
880\r
881 gBS->OpenProtocol (\r
882 Controller,\r
883 &gEfiCallerIdGuid,\r
884 (VOID **) &IdeBusDriverPrivateData,\r
885 This->DriverBindingHandle,\r
886 Controller,\r
887 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
888 );\r
889\r
890 gBS->UninstallMultipleProtocolInterfaces (\r
891 Controller,\r
892 &gEfiCallerIdGuid,\r
893 IdeBusDriverPrivateData,\r
894 NULL\r
895 );\r
896\r
897 if (IdeBusDriverPrivateData != NULL) {\r
898 gBS->FreePool (IdeBusDriverPrivateData);\r
899 }\r
900 //\r
901 // Close the bus driver\r
902 //\r
903 gBS->CloseProtocol (\r
904 Controller,\r
905 &gEfiIdeControllerInitProtocolGuid,\r
906 This->DriverBindingHandle,\r
907 Controller\r
908 );\r
909 gBS->CloseProtocol (\r
910 Controller,\r
911 &gEfiPciIoProtocolGuid,\r
912 This->DriverBindingHandle,\r
913 Controller\r
914 );\r
915 gBS->CloseProtocol (\r
916 Controller,\r
917 &gEfiDevicePathProtocolGuid,\r
918 This->DriverBindingHandle,\r
919 Controller\r
920 );\r
921\r
922 return EFI_SUCCESS;\r
923 }\r
924\r
925 AllChildrenStopped = TRUE;\r
926\r
927 for (Index = 0; Index < NumberOfChildren; Index++) {\r
928\r
929 Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);\r
930\r
931 if (EFI_ERROR (Status)) {\r
932 AllChildrenStopped = FALSE;\r
933 }\r
934 }\r
935\r
936 if (!AllChildrenStopped) {\r
937 return EFI_DEVICE_ERROR;\r
938 }\r
939\r
940 return EFI_SUCCESS;\r
941}\r
942\r
943//\r
944// ***********************************************************************************\r
945// DeRegisterIdeDevice\r
946// ***********************************************************************************\r
947//\r
948/**\r
949 Deregister an IDE device and free resources\r
950\r
951 @param This Protocol instance pointer.\r
952 @param Controller Ide device handle\r
953 @param Handle Handle of device to deregister driver on\r
954\r
955 @return EFI_STATUS\r
956\r
957**/\r
958EFI_STATUS\r
959DeRegisterIdeDevice (\r
960 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
961 IN EFI_HANDLE Controller,\r
962 IN EFI_HANDLE Handle\r
963 )\r
964// TODO: EFI_SUCCESS - add return value to function comment\r
965{\r
966 EFI_STATUS Status;\r
967 EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
968 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
969 EFI_PCI_IO_PROTOCOL *PciIo;\r
970 UINTN Index;\r
971\r
972 Status = gBS->OpenProtocol (\r
973 Handle,\r
974 &gEfiBlockIoProtocolGuid,\r
975 (VOID **) &BlkIo,\r
976 This->DriverBindingHandle,\r
977 Controller,\r
978 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
979 );\r
980 if (EFI_ERROR (Status)) {\r
981 return Status;\r
982 }\r
983\r
984 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);\r
985\r
986 //\r
987 // Report Status code: Device disabled\r
988 //\r
989 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
990 EFI_PROGRESS_CODE,\r
991 (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),\r
992 IdeBlkIoDevice->DevicePath\r
993 );\r
994\r
995 //\r
996 // Close the child handle\r
997 //\r
998 Status = gBS->CloseProtocol (\r
999 Controller,\r
1000 &gEfiPciIoProtocolGuid,\r
1001 This->DriverBindingHandle,\r
1002 Handle\r
1003 );\r
1004\r
1005 Status = gBS->UninstallMultipleProtocolInterfaces (\r
1006 Handle,\r
1007 &gEfiDevicePathProtocolGuid,\r
1008 IdeBlkIoDevice->DevicePath,\r
1009 &gEfiBlockIoProtocolGuid,\r
1010 &IdeBlkIoDevice->BlkIo,\r
1011 &gEfiDiskInfoProtocolGuid,\r
1012 &IdeBlkIoDevice->DiskInfo,\r
1013 NULL\r
1014 );\r
1015\r
1016 if (EFI_ERROR (Status)) {\r
1017 gBS->OpenProtocol (\r
1018 Controller,\r
1019 &gEfiPciIoProtocolGuid,\r
1020 (VOID **) &PciIo,\r
1021 This->DriverBindingHandle,\r
1022 Handle,\r
1023 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1024 );\r
1025 return Status;\r
1026 }\r
1027\r
1028 //\r
1029 // Release allocated resources\r
1030 //\r
1031 Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;\r
1032 IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;\r
1033\r
1034 ReleaseIdeResources (IdeBlkIoDevice);\r
1035\r
1036 return EFI_SUCCESS;\r
1037}\r
1038\r
1039//\r
1040// ***********************************************************************************\r
1041// IDEBlkIoReset\r
1042// ***********************************************************************************\r
1043//\r
1044/**\r
1045 TODO: This - add argument and description to function comment\r
1046 TODO: ExtendedVerification - add argument and description to function comment\r
1047 TODO: EFI_DEVICE_ERROR - add return value to function comment\r
1048\r
1049**/\r
1050EFI_STATUS\r
1051EFIAPI\r
1052IDEBlkIoReset (\r
1053 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1054 IN BOOLEAN ExtendedVerification\r
1055 )\r
1056{\r
1057 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1058 EFI_STATUS Status;\r
1059 EFI_TPL OldTpl;\r
1060\r
1061 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1062\r
1063 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
1064 //\r
1065 // Requery IDE IO resources in case of the switch of native and legacy modes\r
1066 //\r
1067 ReassignIdeResources (IdeBlkIoDevice);\r
1068\r
1069 //\r
1070 // for ATA device, using ATA reset method\r
1071 //\r
1072 if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
1073 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
1074 Status = AtaSoftReset (IdeBlkIoDevice);\r
1075 goto Done;\r
1076 }\r
1077\r
1078 if (IdeBlkIoDevice->Type == IdeUnknown) {\r
1079 Status = EFI_DEVICE_ERROR;\r
1080 goto Done;\r
1081 }\r
1082\r
1083 //\r
1084 // for ATAPI device, using ATAPI reset method\r
1085 //\r
1086 Status = AtapiSoftReset (IdeBlkIoDevice);\r
1087 if (ExtendedVerification) {\r
1088 Status = AtaSoftReset (IdeBlkIoDevice);\r
1089 }\r
1090\r
1091Done:\r
1092 gBS->RestoreTPL (OldTpl);\r
1093 return Status;\r
1094}\r
1095\r
1096/**\r
1097 Read data from block io device\r
1098\r
1099 @param This Protocol instance pointer.\r
1100 @param MediaId The media ID of the device\r
1101 @param LBA Starting LBA address to read data\r
1102 @param BufferSize The size of data to be read\r
1103 @param Buffer Caller supplied buffer to save data\r
1104\r
1105 @return read data status\r
1106\r
1107**/\r
1108EFI_STATUS\r
1109EFIAPI\r
1110IDEBlkIoReadBlocks (\r
1111 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1112 IN UINT32 MediaId,\r
1113 IN EFI_LBA LBA,\r
1114 IN UINTN BufferSize,\r
1115 OUT VOID *Buffer\r
1116 )\r
1117// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
1118{\r
1119 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1120 EFI_STATUS Status;\r
1121 EFI_TPL OldTpl;\r
1122\r
1123 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1124\r
1125 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
1126\r
1127 //\r
1128 // Requery IDE IO resources in case of the switch of native and legacy modes\r
1129 //\r
1130 ReassignIdeResources (IdeBlkIoDevice);\r
1131\r
1132 //\r
1133 // For ATA compatible device, use ATA read block's mechanism\r
1134 //\r
1135 if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
1136 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
1137 Status = AtaBlkIoReadBlocks (\r
1138 IdeBlkIoDevice,\r
1139 MediaId,\r
1140 LBA,\r
1141 BufferSize,\r
1142 Buffer\r
1143 );\r
1144 goto Done;\r
1145 }\r
1146\r
1147 if (IdeBlkIoDevice->Type == IdeUnknown) {\r
1148 Status = EFI_DEVICE_ERROR;\r
1149 goto Done;\r
1150 }\r
1151\r
1152 //\r
1153 // for ATAPI device, using ATAPI read block's mechanism\r
1154 //\r
1155 Status = AtapiBlkIoReadBlocks (\r
1156 IdeBlkIoDevice,\r
1157 MediaId,\r
1158 LBA,\r
1159 BufferSize,\r
1160 Buffer\r
1161 );\r
1162\r
1163Done:\r
1164 gBS->RestoreTPL (OldTpl);\r
1165\r
1166 return Status;\r
1167}\r
1168\r
1169/**\r
1170 Write data to block io device\r
1171\r
1172 @param This Protocol instance pointer.\r
1173 @param MediaId The media ID of the device\r
1174 @param LBA Starting LBA address to write data\r
1175 @param BufferSize The size of data to be written\r
1176 @param Buffer Caller supplied buffer to save data\r
1177\r
1178 @return write data status\r
1179\r
1180**/\r
1181EFI_STATUS\r
1182EFIAPI\r
1183IDEBlkIoWriteBlocks (\r
1184 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1185 IN UINT32 MediaId,\r
1186 IN EFI_LBA LBA,\r
1187 IN UINTN BufferSize,\r
1188 IN VOID *Buffer\r
1189 )\r
1190// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
1191{\r
1192 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1193 EFI_STATUS Status;\r
1194 EFI_TPL OldTpl;\r
1195\r
1196 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1197\r
1198 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
1199 //\r
1200 // Requery IDE IO resources in case of the switch of native and legacy modes\r
1201 //\r
1202 ReassignIdeResources (IdeBlkIoDevice);\r
1203\r
1204 //\r
1205 // for ATA device, using ATA write block's mechanism\r
1206 //\r
1207 if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
1208 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
1209\r
1210 Status = AtaBlkIoWriteBlocks (\r
1211 IdeBlkIoDevice,\r
1212 MediaId,\r
1213 LBA,\r
1214 BufferSize,\r
1215 Buffer\r
1216 );\r
1217 goto Done;\r
1218 }\r
1219\r
1220 if (IdeBlkIoDevice->Type == IdeUnknown) {\r
1221 Status = EFI_DEVICE_ERROR;\r
1222 goto Done;\r
1223 }\r
1224\r
1225 //\r
1226 // for ATAPI device, using ATAPI write block's mechanism\r
1227 //\r
1228 Status = AtapiBlkIoWriteBlocks (\r
1229 IdeBlkIoDevice,\r
1230 MediaId,\r
1231 LBA,\r
1232 BufferSize,\r
1233 Buffer\r
1234 );\r
1235\r
1236Done:\r
1237 gBS->RestoreTPL (OldTpl);\r
1238 return Status;\r
1239}\r
1240\r
1241//\r
1242// ***********************************************************************************\r
1243// IDEBlkIoFlushBlocks\r
1244// ***********************************************************************************\r
1245//\r
1246/**\r
1247 TODO: This - add argument and description to function comment\r
1248 TODO: EFI_SUCCESS - add return value to function comment\r
1249**/\r
1250EFI_STATUS\r
1251EFIAPI\r
1252IDEBlkIoFlushBlocks (\r
1253 IN EFI_BLOCK_IO_PROTOCOL *This\r
1254 )\r
1255{\r
1256 //\r
1257 // return directly\r
1258 //\r
1259 return EFI_SUCCESS;\r
1260}\r
1261\r
1262/**\r
1263 Return the results of the Inquiry command to a drive in InquiryData.\r
1264 Data format of Inquiry data is defined by the Interface GUID.\r
1265\r
1266 @param This Protocol instance pointer.\r
1267 @param InquiryData Results of Inquiry command to device\r
1268 @param InquiryDataSize Size of InquiryData in bytes.\r
1269\r
1270 @retval EFI_SUCCESS InquiryData valid\r
1271 @retval EFI_NOT_FOUND Device does not support this data class\r
1272 @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
1273 @retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough\r
1274\r
1275**/\r
1276EFI_STATUS\r
1277EFIAPI\r
1278IDEDiskInfoInquiry (\r
1279 IN EFI_DISK_INFO_PROTOCOL *This,\r
1280 IN OUT VOID *InquiryData,\r
1281 IN OUT UINT32 *InquiryDataSize\r
1282 )\r
1283{\r
1284 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1285\r
1286 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
1287\r
1e23bd8d 1288 if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) {\r
1289 *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
ead42efc 1290 return EFI_BUFFER_TOO_SMALL;\r
1291 }\r
1292\r
1293 if (IdeBlkIoDevice->pInquiryData == NULL) {\r
1294 return EFI_NOT_FOUND;\r
1295 }\r
1296\r
1e23bd8d 1297 gBS->CopyMem (InquiryData, IdeBlkIoDevice->pInquiryData, sizeof (ATAPI_INQUIRY_DATA));\r
1298 *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
ead42efc 1299\r
1300 return EFI_SUCCESS;\r
1301}\r
1302\r
1303/**\r
1304 Return the results of the Identify command to a drive in IdentifyData.\r
1305 Data format of Identify data is defined by the Interface GUID.\r
1306\r
1307 @param This Protocol instance pointer.\r
1308 @param IdentifyData Results of Identify command to device\r
1309 @param IdentifyDataSize Size of IdentifyData in bytes.\r
1310\r
1311 @retval EFI_SUCCESS IdentifyData valid\r
1312 @retval EFI_NOT_FOUND Device does not support this data class\r
1313 @retval EFI_DEVICE_ERROR Error reading IdentifyData from device\r
1314 @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough\r
1315\r
1316**/\r
1317EFI_STATUS\r
1318EFIAPI\r
1319IDEDiskInfoIdentify (\r
1320 IN EFI_DISK_INFO_PROTOCOL *This,\r
1321 IN OUT VOID *IdentifyData,\r
1322 IN OUT UINT32 *IdentifyDataSize\r
1323 )\r
1324{\r
1325 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1326\r
1327 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
1328\r
1329 if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {\r
1330 *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
1331 return EFI_BUFFER_TOO_SMALL;\r
1332 }\r
1333\r
1334 if (IdeBlkIoDevice->pIdData == NULL) {\r
1335 return EFI_NOT_FOUND;\r
1336 }\r
1337\r
1338 gBS->CopyMem (IdentifyData, IdeBlkIoDevice->pIdData, sizeof (EFI_IDENTIFY_DATA));\r
1339 *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
1340\r
1341 return EFI_SUCCESS;\r
1342}\r
1343\r
1344/**\r
1345 Return the results of the Request Sense command to a drive in SenseData.\r
1346 Data format of Sense data is defined by the Interface GUID.\r
1347\r
1348 @param This Protocol instance pointer.\r
1349 @param SenseData Results of Request Sense command to device\r
1350 @param SenseDataSize Size of SenseData in bytes.\r
1351 @param SenseDataNumber Type of SenseData\r
1352\r
1353 @retval EFI_SUCCESS InquiryData valid\r
1354 @retval EFI_NOT_FOUND Device does not support this data class\r
1355 @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
1356 @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough\r
1357\r
1358**/\r
1359EFI_STATUS\r
1360EFIAPI\r
1361IDEDiskInfoSenseData (\r
1362 IN EFI_DISK_INFO_PROTOCOL *This,\r
1363 IN OUT VOID *SenseData,\r
1364 IN OUT UINT32 *SenseDataSize,\r
1365 OUT UINT8 *SenseDataNumber\r
1366 )\r
1367{\r
1368 return EFI_NOT_FOUND;\r
1369}\r
1370\r
1371/**\r
1372 Return the results of the Request Sense command to a drive in SenseData.\r
1373 Data format of Sense data is defined by the Interface GUID.\r
1374\r
1375 @param This Protocol instance pointer.\r
1376 @param IdeChannel Primary or Secondary\r
1377 @param IdeDevice Master or Slave\r
1378\r
1379 @retval EFI_SUCCESS IdeChannel and IdeDevice are valid\r
1380 @retval EFI_UNSUPPORTED This is not an IDE device\r
1381\r
1382**/\r
1383EFI_STATUS\r
1384EFIAPI\r
1385IDEDiskInfoWhichIde (\r
1386 IN EFI_DISK_INFO_PROTOCOL *This,\r
1387 OUT UINT32 *IdeChannel,\r
1388 OUT UINT32 *IdeDevice\r
1389 )\r
1390{\r
1391 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1392\r
1393 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
1394 *IdeChannel = IdeBlkIoDevice->Channel;\r
1395 *IdeDevice = IdeBlkIoDevice->Device;\r
1396\r
1397 return EFI_SUCCESS;\r
1398}\r
1399\r
1400/**\r
1401 The user Entry Point for module IdeBus. The user code starts with this function.\r
1402\r
1403 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
1404 @param[in] SystemTable A pointer to the EFI System Table.\r
1405 \r
1406 @retval EFI_SUCCESS The entry point is executed successfully.\r
1407 @retval other Some error occurs when executing this entry point.\r
1408\r
1409**/\r
1410EFI_STATUS\r
1411EFIAPI\r
1412InitializeIdeBus(\r
1413 IN EFI_HANDLE ImageHandle,\r
1414 IN EFI_SYSTEM_TABLE *SystemTable\r
1415 )\r
1416{\r
1417 EFI_STATUS Status;\r
1418\r
1419 //\r
1420 // Install driver model protocol(s).\r
1421 //\r
733f03aa 1422 Status = EfiLibInstallDriverBindingComponentName2 (\r
ead42efc 1423 ImageHandle,\r
1424 SystemTable,\r
1425 &gIDEBusDriverBinding,\r
1426 ImageHandle,\r
1427 &gIDEBusComponentName,\r
733f03aa 1428 &gIDEBusComponentName2\r
ead42efc 1429 );\r
1430 ASSERT_EFI_ERROR (Status);\r
1431\r
1432 return Status;\r
1433}\r