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