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