]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c
1) Use FeatureFlag PcdPciBusHotplugDeviceSupport to merge LightPciLib.c with PcdLib.c.
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / IdeBus / Dxe / idebus.c
... / ...
CommitLineData
1/** @file\r
2 Copyright (c) 2006, Intel Corporation \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 0x10,\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 // Clsoe 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
185\r
186 //\r
187 // Local variables declaration for IdeControllerInit support\r
188 //\r
189 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;\r
190 BOOLEAN EnumAll;\r
191 BOOLEAN ChannelEnabled;\r
192 UINT8 ChannelCount;\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 and ChannelCount. Step7.2\r
243 //\r
244 EnumAll = IdeInit->EnumAll;\r
245 ChannelCount = IdeInit->ChannelCount;\r
246\r
247 //\r
248 // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL\r
249 // attribute will not return EFI_ALREADY_STARTED\r
250 //\r
251 Status = gBS->OpenProtocol (\r
252 Controller,\r
253 &gEfiPciIoProtocolGuid,\r
254 (VOID **) &PciIo,\r
255 This->DriverBindingHandle,\r
256 Controller,\r
257 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
258 );\r
259 if (EFI_ERROR (Status)) {\r
260 DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));\r
261 goto ErrorExit;\r
262 }\r
263\r
264 //\r
265 // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable\r
266 //\r
267 if (SavedStatus != EFI_ALREADY_STARTED) {\r
268 IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
269 if (IdeBusDriverPrivateData == NULL) {\r
270 Status = EFI_OUT_OF_RESOURCES;\r
271 goto ErrorExit;\r
272 }\r
273\r
274 ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
275 Status = gBS->InstallMultipleProtocolInterfaces (\r
276 &Controller,\r
277 &gEfiCallerIdGuid,\r
278 IdeBusDriverPrivateData,\r
279 NULL\r
280 );\r
281 if (EFI_ERROR (Status)) {\r
282 goto ErrorExit;\r
283 }\r
284\r
285 } else {\r
286 Status = gBS->OpenProtocol (\r
287 Controller,\r
288 &gEfiCallerIdGuid,\r
289 (VOID **) &IdeBusDriverPrivateData,\r
290 This->DriverBindingHandle,\r
291 Controller,\r
292 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
293 );\r
294 if (EFI_ERROR (Status)) {\r
295 IdeBusDriverPrivateData = NULL;\r
296 goto ErrorExit;\r
297 }\r
298 }\r
299\r
300 Status = PciIo->Attributes (\r
301 PciIo,\r
302 EfiPciIoAttributeOperationEnable,\r
303 EFI_PCI_DEVICE_ENABLE,\r
304 NULL\r
305 );\r
306 if (EFI_ERROR (Status)) {\r
307 goto ErrorExit;\r
308 }\r
309\r
310 //\r
311 // Read the environment variable that contains the IDEBus Driver's\r
312 // Config options that were set by the Driver Configuration Protocol\r
313 //\r
314 DataSize = sizeof (ConfigurationOptions);\r
315 Status = gRT->GetVariable (\r
316 (CHAR16 *) L"Configuration",\r
317 &gEfiCallerIdGuid,\r
318 NULL,\r
319 &DataSize,\r
320 &ConfigurationOptions\r
321 );\r
322 if (EFI_ERROR (Status)) {\r
323 ConfigurationOptions = 0x0f;\r
324 }\r
325\r
326 if (EnumAll) {\r
327 //\r
328 // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway\r
329 //\r
330 BeginningIdeChannel = IdePrimary;\r
331 EndIdeChannel = IdeSecondary;\r
332 BeginningIdeDevice = IdeMaster;\r
333 EndIdeDevice = IdeSlave;\r
334 } else if (RemainingDevicePath == NULL) {\r
335 //\r
336 // RemainingDevicePath is NULL, scan IDE bus for each device;\r
337 //\r
338 BeginningIdeChannel = IdePrimary;\r
339 EndIdeChannel = IdeSecondary;\r
340 BeginningIdeDevice = IdeMaster;\r
341 //\r
342 // default, may be redefined by IdeInit\r
343 //\r
344 EndIdeDevice = IdeSlave;\r
345 } else {\r
346 //\r
347 // RemainingDevicePath is not NULL, only scan the specified device.\r
348 //\r
349 Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
350 BeginningIdeChannel = Node->Atapi.PrimarySecondary;\r
351 EndIdeChannel = BeginningIdeChannel;\r
352 BeginningIdeDevice = Node->Atapi.SlaveMaster;\r
353 EndIdeDevice = BeginningIdeDevice;\r
354 }\r
355\r
356 //\r
357 // Obtain IDE IO port registers' base addresses\r
358 //\r
359 Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);\r
360 if (EFI_ERROR (Status)) {\r
361 goto ErrorExit;\r
362 }\r
363\r
364 //\r
365 // Report status code: begin IdeBus initialization\r
366 //\r
367 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
368 EFI_PROGRESS_CODE,\r
369 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
370 ParentDevicePath\r
371 );\r
372\r
373 //\r
374 // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol\r
375 //\r
376 for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
377\r
378 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);\r
379\r
380 //\r
381 // now obtain channel information fron IdeControllerInit protocol. Step9\r
382 //\r
383 Status = IdeInit->GetChannelInfo (\r
384 IdeInit,\r
385 IdeChannel,\r
386 &ChannelEnabled,\r
387 &MaxDevices\r
388 );\r
389 if (EFI_ERROR (Status)) {\r
390 DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));\r
391 continue;\r
392 }\r
393\r
394 if (!ChannelEnabled) {\r
395 continue;\r
396 }\r
397\r
398 EndIdeDevice = (UINT8) EFI_MIN ((MaxDevices - 1), EndIdeDevice);\r
399\r
400 //\r
401 // Now inform the IDE Controller Init Module. Sept10\r
402 //\r
403 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);\r
404\r
405 //\r
406 // No reset channel function implemented. Sept11\r
407 //\r
408 IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);\r
409\r
410 //\r
411 // Step13\r
412 //\r
413 IdeInit->NotifyPhase (\r
414 IdeInit,\r
415 EfiIdeBusBeforeDevicePresenceDetection,\r
416 IdeChannel\r
417 );\r
418\r
419 //\r
420 // Prepare to detect IDE device of this channel\r
421 //\r
422 InitializeIDEChannelData ();\r
423\r
424 //\r
425 // -- 1st inner loop --- Master/Slave ------------ Step14\r
426 //\r
427 for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
428 //\r
429 // Check whether the configuration options allow this device\r
430 //\r
431 if (!(ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice)))) {\r
432 continue;\r
433 }\r
434 \r
435 //\r
436 // The device has been scanned in another Start(), No need to scan it again\r
437 // for perf optimization.\r
438 //\r
439 if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {\r
440 continue;\r
441 }\r
442 \r
443 //\r
444 // create child handle for the detected device.\r
445 //\r
446 IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));\r
447 if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {\r
448 continue;\r
449 }\r
450\r
451 IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
452\r
453 ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));\r
454\r
455 IdeBlkIoDevicePtr->Signature = IDE_BLK_IO_DEV_SIGNATURE;\r
456 IdeBlkIoDevicePtr->Channel = IdeChannel;\r
457 IdeBlkIoDevicePtr->Device = IdeDevice;\r
458\r
459 //\r
460 // initialize Block IO interface's Media pointer\r
461 //\r
462 IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;\r
463\r
464 //\r
465 // Initialize IDE IO port addresses, including Command Block registers\r
466 // and Control Block registers\r
467 //\r
468 IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));\r
469 if (IdeBlkIoDevicePtr->IoPort == NULL) {\r
470 continue;\r
471 }\r
472\r
473 ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));\r
474 CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;\r
475 ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;\r
476\r
477 IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;\r
478 (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);\r
479 IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
480 IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
481 IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
482 IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
483 IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
484 (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);\r
485\r
486 (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;\r
487 IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);\r
488\r
489 IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);\r
490\r
491 IdeBlkIoDevicePtr->PciIo = PciIo;\r
492 IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;\r
493 IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;\r
494\r
495 //\r
496 // Report Status code: is about to detect IDE drive\r
497 //\r
498 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
499 EFI_PROGRESS_CODE,\r
500 (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT),\r
501 IdeBlkIoDevicePtr->DevicePath\r
502 );\r
503\r
504 //\r
505 // Discover device, now!\r
506 //\r
507 PERF_START (0, "DiscoverIdeDevice", "IDE", 0);\r
508 Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);\r
509 PERF_END (0, "DiscoverIdeDevice", "IDE", 0);\r
510\r
511 IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice] = TRUE;\r
512 IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = FALSE;\r
513\r
514 if (!EFI_ERROR (Status)) {\r
515 //\r
516 // Set Device Path\r
517 //\r
518 ZeroMem (&NewNode, sizeof (NewNode));\r
519 NewNode.DevPath.Type = MESSAGING_DEVICE_PATH;\r
520 NewNode.DevPath.SubType = MSG_ATAPI_DP;\r
521 SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));\r
522\r
523 NewNode.Atapi.PrimarySecondary = (UINT8) IdeBlkIoDevicePtr->Channel;\r
524 NewNode.Atapi.SlaveMaster = (UINT8) IdeBlkIoDevicePtr->Device;\r
525 NewNode.Atapi.Lun = IdeBlkIoDevicePtr->Lun;\r
526 IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (\r
527 ParentDevicePath,\r
528 &NewNode.DevPath\r
529 );\r
530 if (IdeBlkIoDevicePtr->DevicePath == NULL) {\r
531 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
532 continue;\r
533 }\r
534\r
535 //\r
536 // Submit identify data to IDE controller init driver\r
537 //\r
538 CopyMem (&IdentifyData, IdeBlkIoDevicePtr->pIdData, sizeof (IdentifyData));\r
539 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;\r
540 IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);\r
541 } else {\r
542 //\r
543 // Device detection failed\r
544 //\r
545 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
546 IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);\r
547 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
548 IdeBlkIoDevicePtr = NULL;\r
549 }\r
550 //\r
551 // end of 1st inner loop ---\r
552 //\r
553 }\r
554 //\r
555 // end of 1st outer loop =========\r
556 //\r
557 }\r
558\r
559 //\r
560 // = 2nd outer loop == Primary/Secondary =================\r
561 //\r
562 for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
563\r
564 //\r
565 // -- 2nd inner loop --- Master/Slave --------\r
566 //\r
567 for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
568\r
569 if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {\r
570 continue;\r
571 }\r
572\r
573 if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {\r
574 continue;\r
575 }\r
576\r
577 Status = IdeInit->CalculateMode (\r
578 IdeInit,\r
579 IdeChannel,\r
580 IdeDevice,\r
581 &SupportedModes\r
582 );\r
583 if (EFI_ERROR (Status)) {\r
584 DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));\r
585 continue;\r
586 }\r
587\r
588 IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
589\r
590 //\r
591 // Set best supported PIO mode on this IDE device\r
592 //\r
593 if (SupportedModes->PioMode.Mode <= ATA_PIO_MODE_2) {\r
594 TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;\r
595 } else {\r
596 TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;\r
597 }\r
598\r
599 TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);\r
600\r
601 if (SupportedModes->ExtModeCount == 0){\r
602 Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
603\r
604 if (EFI_ERROR (Status)) {\r
605 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
606 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
607 IdeBlkIoDevicePtr = NULL;\r
608 continue;\r
609 }\r
610 }\r
611\r
612 //\r
613 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't\r
614 // be set together. Only one DMA mode can be set to a device. If setting\r
615 // DMA mode operation fails, we can continue moving on because we only use\r
616 // PIO mode at boot time. DMA modes are used by certain kind of OS booting\r
617 //\r
618 if (SupportedModes->UdmaMode.Valid) {\r
619\r
620 TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;\r
621 TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);\r
622 Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
623\r
624 if (EFI_ERROR (Status)) {\r
625 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
626 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
627 IdeBlkIoDevicePtr = NULL;\r
628 continue;\r
629 }\r
630\r
631 EnableInterrupt (IdeBlkIoDevicePtr);\r
632 } else if (SupportedModes->MultiWordDmaMode.Valid) {\r
633\r
634 TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;\r
635 TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;\r
636 Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
637\r
638 if (EFI_ERROR (Status)) {\r
639 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
640 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
641 IdeBlkIoDevicePtr = NULL;\r
642 continue;\r
643 }\r
644\r
645 EnableInterrupt (IdeBlkIoDevicePtr);\r
646 }\r
647 //\r
648 // Init driver parameters\r
649 //\r
650 DriveParameters.Sector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.sectors_per_track;\r
651 DriveParameters.Heads = (UINT8) (IdeBlkIoDevicePtr->pIdData->AtaData.heads - 1);\r
652 DriveParameters.MultipleSector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.multi_sector_cmd_max_sct_cnt;\r
653 //\r
654 // Set Parameters for the device:\r
655 // 1) Init\r
656 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command\r
657 //\r
658 if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {\r
659 Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);\r
660 }\r
661 \r
662 //\r
663 // Record PIO mode used in private data\r
664 //\r
665 IdeBlkIoDevicePtr->PioMode = SupportedModes->PioMode.Mode;\r
666\r
667 //\r
668 // Set IDE controller Timing Blocks in the PCI Configuration Space\r
669 //\r
670 IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);\r
671\r
672 //\r
673 // Add Component Name for the IDE/ATAPI device that was discovered.\r
674 //\r
675 IdeBlkIoDevicePtr->ControllerNameTable = NULL;\r
676 ADD_NAME (IdeBlkIoDevicePtr);\r
677\r
678 Status = gBS->InstallMultipleProtocolInterfaces (\r
679 &IdeBlkIoDevicePtr->Handle,\r
680 &gEfiDevicePathProtocolGuid,\r
681 IdeBlkIoDevicePtr->DevicePath,\r
682 &gEfiBlockIoProtocolGuid,\r
683 &IdeBlkIoDevicePtr->BlkIo,\r
684 &gEfiDiskInfoProtocolGuid,\r
685 &IdeBlkIoDevicePtr->DiskInfo,\r
686 NULL\r
687 );\r
688\r
689 if (EFI_ERROR (Status)) {\r
690 ReleaseIdeResources (IdeBlkIoDevicePtr);\r
691 }\r
692\r
693 gBS->OpenProtocol (\r
694 Controller,\r
695 &gEfiPciIoProtocolGuid,\r
696 (VOID **) &PciIo,\r
697 This->DriverBindingHandle,\r
698 IdeBlkIoDevicePtr->Handle,\r
699 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
700 );\r
701\r
702 IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;\r
703\r
704 //\r
705 // Report status code: device eanbled!\r
706 //\r
707 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
708 EFI_PROGRESS_CODE,\r
709 (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),\r
710 IdeBlkIoDevicePtr->DevicePath\r
711 );\r
712 \r
713 //\r
714 // Create event to clear pending IDE interrupt\r
715 //\r
716 Status = gBS->CreateEvent (\r
717 EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,\r
718 EFI_TPL_NOTIFY,\r
719 ClearInterrupt,\r
720 IdeBlkIoDevicePtr,\r
721 &IdeBlkIoDevicePtr->ExitBootServiceEvent\r
722 );\r
723\r
724 //\r
725 // end of 2nd inner loop ----\r
726 //\r
727 }\r
728 //\r
729 // end of 2nd outer loop ==========\r
730 //\r
731 }\r
732 \r
733 //\r
734 // All configurations done! Notify IdeController to do post initialization\r
735 // work such as saving IDE controller PCI settings for S3 resume\r
736 //\r
737 IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);\r
738\r
739 if (SupportedModes != NULL) {\r
740 gBS->FreePool (SupportedModes);\r
741 }\r
742\r
743 PERF_START (0, "Finish IDE detection", "IDE", 1);\r
744 PERF_END (0, "Finish IDE detection", "IDE", 0);\r
745\r
746 return EFI_SUCCESS;\r
747\r
748ErrorExit:\r
749\r
750 //\r
751 // Report error code: controller error\r
752 //\r
753 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
754 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
755 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),\r
756 ParentDevicePath\r
757 );\r
758\r
759 gBS->CloseProtocol (\r
760 Controller,\r
761 &gEfiIdeControllerInitProtocolGuid,\r
762 This->DriverBindingHandle,\r
763 Controller\r
764 );\r
765\r
766 gBS->UninstallMultipleProtocolInterfaces (\r
767 Controller,\r
768 &gEfiCallerIdGuid,\r
769 IdeBusDriverPrivateData,\r
770 NULL\r
771 );\r
772\r
773 if (IdeBusDriverPrivateData != NULL) {\r
774 gBS->FreePool (IdeBusDriverPrivateData);\r
775 }\r
776\r
777 if (SupportedModes != NULL) {\r
778 gBS->FreePool (SupportedModes);\r
779 }\r
780\r
781 gBS->CloseProtocol (\r
782 Controller,\r
783 &gEfiPciIoProtocolGuid,\r
784 This->DriverBindingHandle,\r
785 Controller\r
786 );\r
787\r
788 gBS->CloseProtocol (\r
789 Controller,\r
790 &gEfiDevicePathProtocolGuid,\r
791 This->DriverBindingHandle,\r
792 Controller\r
793 );\r
794\r
795 return Status;\r
796\r
797}\r
798\r
799//\r
800// ***********************************************************************************\r
801// IDEBusDriverBindingStop\r
802// ***********************************************************************************\r
803//\r
804/**\r
805 Stop this driver on Controller Handle. \r
806\r
807 @param This Protocol instance pointer.\r
808 @param DeviceHandle Handle of device to stop driver on\r
809 @param NumberOfChildren Not used\r
810 @param ChildHandleBuffer Not used\r
811\r
812 @retval EFI_SUCCESS This driver is removed DeviceHandle\r
813 @retval other This driver was not removed from this device\r
814\r
815**/\r
816EFI_STATUS\r
817EFIAPI\r
818IDEBusDriverBindingStop (\r
819 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
820 IN EFI_HANDLE Controller,\r
821 IN UINTN NumberOfChildren,\r
822 IN EFI_HANDLE *ChildHandleBuffer\r
823 )\r
824// TODO: Controller - add argument and description to function comment\r
825// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
826{\r
827 EFI_STATUS Status;\r
828 EFI_PCI_IO_PROTOCOL *PciIo;\r
829 BOOLEAN AllChildrenStopped;\r
830 UINTN Index;\r
831 IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
832\r
833 IdeBusDriverPrivateData = NULL;\r
834\r
835 if (NumberOfChildren == 0) {\r
836\r
837 Status = gBS->OpenProtocol (\r
838 Controller,\r
839 &gEfiPciIoProtocolGuid,\r
840 (VOID **) &PciIo,\r
841 This->DriverBindingHandle,\r
842 Controller,\r
843 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
844 );\r
845 if (!EFI_ERROR (Status)) {\r
846 PciIo->Attributes (\r
847 PciIo,\r
848 EfiPciIoAttributeOperationDisable,\r
849 EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE,\r
850 NULL\r
851 );\r
852 }\r
853\r
854 gBS->OpenProtocol (\r
855 Controller,\r
856 &gEfiCallerIdGuid,\r
857 (VOID **) &IdeBusDriverPrivateData,\r
858 This->DriverBindingHandle,\r
859 Controller,\r
860 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
861 );\r
862\r
863 gBS->UninstallMultipleProtocolInterfaces (\r
864 Controller,\r
865 &gEfiCallerIdGuid,\r
866 IdeBusDriverPrivateData,\r
867 NULL\r
868 );\r
869\r
870 if (IdeBusDriverPrivateData != NULL) {\r
871 gBS->FreePool (IdeBusDriverPrivateData);\r
872 }\r
873 //\r
874 // Close the bus driver\r
875 //\r
876 gBS->CloseProtocol (\r
877 Controller,\r
878 &gEfiIdeControllerInitProtocolGuid,\r
879 This->DriverBindingHandle,\r
880 Controller\r
881 );\r
882 gBS->CloseProtocol (\r
883 Controller,\r
884 &gEfiPciIoProtocolGuid,\r
885 This->DriverBindingHandle,\r
886 Controller\r
887 );\r
888 gBS->CloseProtocol (\r
889 Controller,\r
890 &gEfiDevicePathProtocolGuid,\r
891 This->DriverBindingHandle,\r
892 Controller\r
893 );\r
894\r
895 return EFI_SUCCESS;\r
896 }\r
897\r
898 AllChildrenStopped = TRUE;\r
899\r
900 for (Index = 0; Index < NumberOfChildren; Index++) {\r
901\r
902 Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);\r
903\r
904 if (EFI_ERROR (Status)) {\r
905 AllChildrenStopped = FALSE;\r
906 }\r
907 }\r
908\r
909 if (!AllChildrenStopped) {\r
910 return EFI_DEVICE_ERROR;\r
911 }\r
912\r
913 return EFI_SUCCESS;\r
914}\r
915\r
916//\r
917// ***********************************************************************************\r
918// DeRegisterIdeDevice\r
919// ***********************************************************************************\r
920//\r
921/**\r
922 Deregister an IDE device and free resources\r
923\r
924 @param This Protocol instance pointer.\r
925 @param Controller Ide device handle\r
926 @param Handle Handle of device to deregister driver on\r
927\r
928 @return EFI_STATUS\r
929\r
930**/\r
931EFI_STATUS\r
932DeRegisterIdeDevice (\r
933 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
934 IN EFI_HANDLE Controller,\r
935 IN EFI_HANDLE Handle\r
936 )\r
937// TODO: EFI_SUCCESS - add return value to function comment\r
938{\r
939 EFI_STATUS Status;\r
940 EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
941 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
942 EFI_PCI_IO_PROTOCOL *PciIo;\r
943 UINTN Index;\r
944\r
945 Status = gBS->OpenProtocol (\r
946 Handle,\r
947 &gEfiBlockIoProtocolGuid,\r
948 (VOID **) &BlkIo,\r
949 This->DriverBindingHandle,\r
950 Controller,\r
951 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
952 );\r
953 if (EFI_ERROR (Status)) {\r
954 return Status;\r
955 }\r
956\r
957 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);\r
958\r
959 //\r
960 // Report Status code: Device disabled\r
961 //\r
962 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
963 EFI_PROGRESS_CODE,\r
964 (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),\r
965 IdeBlkIoDevice->DevicePath\r
966 );\r
967\r
968 //\r
969 // Close the child handle\r
970 //\r
971 Status = gBS->CloseProtocol (\r
972 Controller,\r
973 &gEfiPciIoProtocolGuid,\r
974 This->DriverBindingHandle,\r
975 Handle\r
976 );\r
977\r
978 Status = gBS->UninstallMultipleProtocolInterfaces (\r
979 Handle,\r
980 &gEfiDevicePathProtocolGuid,\r
981 IdeBlkIoDevice->DevicePath,\r
982 &gEfiBlockIoProtocolGuid,\r
983 &IdeBlkIoDevice->BlkIo,\r
984 &gEfiDiskInfoProtocolGuid,\r
985 &IdeBlkIoDevice->DiskInfo,\r
986 NULL\r
987 );\r
988\r
989 if (EFI_ERROR (Status)) {\r
990 gBS->OpenProtocol (\r
991 Controller,\r
992 &gEfiPciIoProtocolGuid,\r
993 (VOID **) &PciIo,\r
994 This->DriverBindingHandle,\r
995 Handle,\r
996 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
997 );\r
998 return Status;\r
999 }\r
1000 \r
1001 //\r
1002 // Release allocated resources\r
1003 //\r
1004 Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;\r
1005 IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;\r
1006\r
1007 ReleaseIdeResources (IdeBlkIoDevice);\r
1008\r
1009 return EFI_SUCCESS;\r
1010}\r
1011\r
1012//\r
1013// ***********************************************************************************\r
1014// IDEBlkIoReset\r
1015// ***********************************************************************************\r
1016//\r
1017/**\r
1018 TODO: This - add argument and description to function comment\r
1019 TODO: ExtendedVerification - add argument and description to function comment\r
1020 TODO: EFI_DEVICE_ERROR - add return value to function comment\r
1021\r
1022**/\r
1023EFI_STATUS\r
1024EFIAPI\r
1025IDEBlkIoReset (\r
1026 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1027 IN BOOLEAN ExtendedVerification\r
1028 )\r
1029{\r
1030 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1031 EFI_STATUS Status;\r
1032\r
1033 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
1034 //\r
1035 // Requery IDE IO resources in case of the switch of native and legacy modes\r
1036 //\r
1037 ReassignIdeResources (IdeBlkIoDevice);\r
1038\r
1039 //\r
1040 // for ATA device, using ATA reset method\r
1041 //\r
1042 if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
1043 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
1044 return AtaSoftReset (IdeBlkIoDevice);\r
1045 }\r
1046\r
1047 if (IdeBlkIoDevice->Type == IdeUnknown) {\r
1048 return EFI_DEVICE_ERROR;\r
1049 }\r
1050 \r
1051 //\r
1052 // for ATAPI device, using ATAPI reset method\r
1053 //\r
1054 Status = AtapiSoftReset (IdeBlkIoDevice);\r
1055 if (ExtendedVerification) {\r
1056 Status = AtaSoftReset (IdeBlkIoDevice);\r
1057 }\r
1058\r
1059 return Status;\r
1060}\r
1061\r
1062/**\r
1063 Read data from block io device\r
1064\r
1065 @param This Protocol instance pointer.\r
1066 @param MediaId The media ID of the device\r
1067 @param LBA Starting LBA address to read data\r
1068 @param BufferSize The size of data to be read\r
1069 @param Buffer Caller supplied buffer to save data\r
1070\r
1071 @return read data status\r
1072\r
1073**/\r
1074EFI_STATUS\r
1075EFIAPI\r
1076IDEBlkIoReadBlocks (\r
1077 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1078 IN UINT32 MediaId,\r
1079 IN EFI_LBA LBA,\r
1080 IN UINTN BufferSize,\r
1081 OUT VOID *Buffer\r
1082 )\r
1083// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
1084{\r
1085 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1086\r
1087 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
1088\r
1089 //\r
1090 // Requery IDE IO resources in case of the switch of native and legacy modes\r
1091 //\r
1092 ReassignIdeResources (IdeBlkIoDevice);\r
1093\r
1094 //\r
1095 // For ATA compatible device, use ATA read block's mechanism\r
1096 //\r
1097 if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
1098 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
1099 return AtaBlkIoReadBlocks (\r
1100 IdeBlkIoDevice,\r
1101 MediaId,\r
1102 LBA,\r
1103 BufferSize,\r
1104 Buffer\r
1105 );\r
1106 }\r
1107\r
1108 if (IdeBlkIoDevice->Type == IdeUnknown) {\r
1109 return EFI_DEVICE_ERROR;\r
1110 }\r
1111 \r
1112 //\r
1113 // for ATAPI device, using ATAPI read block's mechanism\r
1114 //\r
1115 return AtapiBlkIoReadBlocks (\r
1116 IdeBlkIoDevice,\r
1117 MediaId,\r
1118 LBA,\r
1119 BufferSize,\r
1120 Buffer\r
1121 );\r
1122\r
1123}\r
1124\r
1125/**\r
1126 Write data to block io device\r
1127\r
1128 @param This Protocol instance pointer.\r
1129 @param MediaId The media ID of the device\r
1130 @param LBA Starting LBA address to write data\r
1131 @param BufferSize The size of data to be written\r
1132 @param Buffer Caller supplied buffer to save data\r
1133\r
1134 @return write data status\r
1135\r
1136**/\r
1137EFI_STATUS\r
1138EFIAPI\r
1139IDEBlkIoWriteBlocks (\r
1140 IN EFI_BLOCK_IO_PROTOCOL *This,\r
1141 IN UINT32 MediaId,\r
1142 IN EFI_LBA LBA,\r
1143 IN UINTN BufferSize,\r
1144 IN VOID *Buffer\r
1145 )\r
1146// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
1147{\r
1148 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1149\r
1150 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
1151 //\r
1152 // Requery IDE IO resources in case of the switch of native and legacy modes\r
1153 //\r
1154 ReassignIdeResources (IdeBlkIoDevice);\r
1155\r
1156 //\r
1157 // for ATA device, using ATA write block's mechanism\r
1158 //\r
1159 if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
1160 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) { \r
1161\r
1162 return AtaBlkIoWriteBlocks (\r
1163 IdeBlkIoDevice,\r
1164 MediaId,\r
1165 LBA,\r
1166 BufferSize,\r
1167 Buffer\r
1168 );\r
1169 }\r
1170\r
1171 if (IdeBlkIoDevice->Type == IdeUnknown) {\r
1172 return EFI_DEVICE_ERROR;\r
1173 }\r
1174 \r
1175 //\r
1176 // for ATAPI device, using ATAPI write block's mechanism\r
1177 //\r
1178 return AtapiBlkIoWriteBlocks (\r
1179 IdeBlkIoDevice,\r
1180 MediaId,\r
1181 LBA,\r
1182 BufferSize,\r
1183 Buffer\r
1184 );\r
1185}\r
1186\r
1187//\r
1188// ***********************************************************************************\r
1189// IDEBlkIoFlushBlocks\r
1190// ***********************************************************************************\r
1191//\r
1192/**\r
1193 TODO: This - add argument and description to function comment\r
1194 TODO: EFI_SUCCESS - add return value to function comment\r
1195**/\r
1196EFI_STATUS\r
1197EFIAPI\r
1198IDEBlkIoFlushBlocks (\r
1199 IN EFI_BLOCK_IO_PROTOCOL *This\r
1200 )\r
1201{\r
1202 //\r
1203 // return directly\r
1204 //\r
1205 return EFI_SUCCESS;\r
1206}\r
1207\r
1208/**\r
1209 Return the results of the Inquiry command to a drive in InquiryData.\r
1210 Data format of Inquiry data is defined by the Interface GUID.\r
1211\r
1212 @param This Protocol instance pointer.\r
1213 @param InquiryData Results of Inquiry command to device\r
1214 @param InquiryDataSize Size of InquiryData in bytes.\r
1215\r
1216 @retval EFI_SUCCESS InquiryData valid\r
1217 @retval EFI_NOT_FOUND Device does not support this data class\r
1218 @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
1219 @retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough\r
1220\r
1221**/\r
1222EFI_STATUS\r
1223EFIAPI\r
1224IDEDiskInfoInquiry (\r
1225 IN EFI_DISK_INFO_PROTOCOL *This,\r
1226 IN OUT VOID *InquiryData,\r
1227 IN OUT UINT32 *InquiryDataSize\r
1228 )\r
1229{\r
1230 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1231\r
1232 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
1233\r
1234 if (*InquiryDataSize < sizeof (INQUIRY_DATA)) {\r
1235 *InquiryDataSize = sizeof (INQUIRY_DATA);\r
1236 return EFI_BUFFER_TOO_SMALL;\r
1237 }\r
1238\r
1239 if (IdeBlkIoDevice->pInquiryData == NULL) {\r
1240 return EFI_NOT_FOUND;\r
1241 }\r
1242\r
1243 gBS->CopyMem (InquiryData, IdeBlkIoDevice->pInquiryData, sizeof (INQUIRY_DATA));\r
1244 *InquiryDataSize = sizeof (INQUIRY_DATA);\r
1245\r
1246 return EFI_SUCCESS;\r
1247}\r
1248\r
1249/**\r
1250 Return the results of the Identify command to a drive in IdentifyData.\r
1251 Data format of Identify data is defined by the Interface GUID.\r
1252\r
1253 @param This Protocol instance pointer.\r
1254 @param IdentifyData Results of Identify command to device\r
1255 @param IdentifyDataSize Size of IdentifyData in bytes.\r
1256\r
1257 @retval EFI_SUCCESS IdentifyData valid\r
1258 @retval EFI_NOT_FOUND Device does not support this data class\r
1259 @retval EFI_DEVICE_ERROR Error reading IdentifyData from device\r
1260 @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough\r
1261\r
1262**/\r
1263EFI_STATUS\r
1264EFIAPI\r
1265IDEDiskInfoIdentify (\r
1266 IN EFI_DISK_INFO_PROTOCOL *This,\r
1267 IN OUT VOID *IdentifyData,\r
1268 IN OUT UINT32 *IdentifyDataSize\r
1269 )\r
1270{\r
1271 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1272\r
1273 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
1274\r
1275 if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {\r
1276 *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
1277 return EFI_BUFFER_TOO_SMALL;\r
1278 }\r
1279\r
1280 if (IdeBlkIoDevice->pIdData == NULL) {\r
1281 return EFI_NOT_FOUND;\r
1282 }\r
1283\r
1284 gBS->CopyMem (IdentifyData, IdeBlkIoDevice->pIdData, sizeof (EFI_IDENTIFY_DATA));\r
1285 *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
1286\r
1287 return EFI_SUCCESS;\r
1288}\r
1289\r
1290/**\r
1291 Return the results of the Request Sense command to a drive in SenseData.\r
1292 Data format of Sense data is defined by the Interface GUID.\r
1293\r
1294 @param This Protocol instance pointer.\r
1295 @param SenseData Results of Request Sense command to device\r
1296 @param SenseDataSize Size of SenseData in bytes.\r
1297 @param SenseDataNumber Type of SenseData\r
1298\r
1299 @retval EFI_SUCCESS InquiryData valid\r
1300 @retval EFI_NOT_FOUND Device does not support this data class\r
1301 @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
1302 @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough\r
1303\r
1304**/\r
1305EFI_STATUS\r
1306EFIAPI\r
1307IDEDiskInfoSenseData (\r
1308 IN EFI_DISK_INFO_PROTOCOL *This,\r
1309 IN OUT VOID *SenseData,\r
1310 IN OUT UINT32 *SenseDataSize,\r
1311 OUT UINT8 *SenseDataNumber\r
1312 )\r
1313{\r
1314 return EFI_NOT_FOUND;\r
1315}\r
1316\r
1317/**\r
1318 Return the results of the Request Sense command to a drive in SenseData.\r
1319 Data format of Sense data is defined by the Interface GUID.\r
1320\r
1321 @param This Protocol instance pointer.\r
1322 @param IdeChannel Primary or Secondary\r
1323 @param IdeDevice Master or Slave\r
1324\r
1325 @retval EFI_SUCCESS IdeChannel and IdeDevice are valid\r
1326 @retval EFI_UNSUPPORTED This is not an IDE device\r
1327\r
1328**/\r
1329EFI_STATUS\r
1330EFIAPI\r
1331IDEDiskInfoWhichIde (\r
1332 IN EFI_DISK_INFO_PROTOCOL *This,\r
1333 OUT UINT32 *IdeChannel,\r
1334 OUT UINT32 *IdeDevice\r
1335 )\r
1336{\r
1337 IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
1338\r
1339 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
1340 *IdeChannel = IdeBlkIoDevice->Channel;\r
1341 *IdeDevice = IdeBlkIoDevice->Device;\r
1342\r
1343 return EFI_SUCCESS;\r
1344}\r