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