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