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