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