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