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