1 /** @file
2   This file implement UEFI driver for IDE Bus which includes device identification,
3   Child device(Disk, CDROM, etc) enumeration and child handler installation, and
4   driver stop.
5 
6   Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
7   This program and the accompanying materials
8   are licensed and made available under the terms and conditions of the BSD License
9   which accompanies this distribution.  The full text of the license may be found at
10   http://opensource.org/licenses/bsd-license.php
11 
12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15   @par Revision Reference:
16   This module is modified from DXE\IDE module for Ide Contriller Init support
17 
18 **/
19 
20 #include "IdeBus.h"
21 
22 #define PCI_CLASS_MASS_STORAGE  0x01
23 #define PCI_SUB_CLASS_IDE       0x01
24 
25 
26 //
27 // IDE Bus Driver Binding Protocol Instance
28 //
29 EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = {
30   IDEBusDriverBindingSupported,
31   IDEBusDriverBindingStart,
32   IDEBusDriverBindingStop,
33   0xa,
34   NULL,
35   NULL
36 };
37 /**
38   Deregister an IDE device and free resources
39 
40   @param  This Protocol instance pointer.
41   @param  Controller Ide device handle
42   @param  Handle Handle of device to deregister driver on
43 
44   @retval EFI_SUCCESS  Deregiter a specific IDE device successfully
45 
46 
47 **/
48 EFI_STATUS
DeRegisterIdeDevice(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_HANDLE Handle)49 DeRegisterIdeDevice (
50   IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
51   IN  EFI_HANDLE                     Controller,
52   IN  EFI_HANDLE                     Handle
53   )
54 {
55   EFI_STATUS            Status;
56   EFI_BLOCK_IO_PROTOCOL *BlkIo;
57   IDE_BLK_IO_DEV        *IdeBlkIoDevice;
58   EFI_PCI_IO_PROTOCOL   *PciIo;
59   UINTN                 Index;
60 
61   Status = gBS->OpenProtocol (
62                   Handle,
63                   &gEfiBlockIoProtocolGuid,
64                   (VOID **) &BlkIo,
65                   This->DriverBindingHandle,
66                   Controller,
67                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
68                   );
69   if (EFI_ERROR (Status)) {
70     return Status;
71   }
72 
73   IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);
74 
75   //
76   // Report Status code: Device disabled
77   //
78   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
79     EFI_PROGRESS_CODE,
80     (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),
81     IdeBlkIoDevice->DevicePath
82     );
83 
84   //
85   // Close the child handle
86   //
87   Status = gBS->CloseProtocol (
88                   Controller,
89                   &gEfiPciIoProtocolGuid,
90                   This->DriverBindingHandle,
91                   Handle
92                   );
93 
94   Status = gBS->UninstallMultipleProtocolInterfaces (
95                   Handle,
96                   &gEfiDevicePathProtocolGuid,
97                   IdeBlkIoDevice->DevicePath,
98                   &gEfiBlockIoProtocolGuid,
99                   &IdeBlkIoDevice->BlkIo,
100                   &gEfiDiskInfoProtocolGuid,
101                   &IdeBlkIoDevice->DiskInfo,
102                   NULL
103                   );
104 
105   if (EFI_ERROR (Status)) {
106     gBS->OpenProtocol (
107           Controller,
108           &gEfiPciIoProtocolGuid,
109           (VOID **) &PciIo,
110           This->DriverBindingHandle,
111           Handle,
112           EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
113           );
114     return Status;
115   }
116 
117   //
118   // Release allocated resources
119   //
120   Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;
121   if (Index < MAX_IDE_DEVICE) {
122     IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;
123   }
124   ReleaseIdeResources (IdeBlkIoDevice);
125 
126   return EFI_SUCCESS;
127 }
128 /**
129   Supported function of Driver Binding protocol for this driver.
130 
131   @param This                A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
132   @param ControllerHandle    The handle of the controller to test.
133   @param RemainingDevicePath A pointer to the remaining portion of a device path.
134 
135   @retval  EFI_SUCCESS Driver loaded.
136   @retval  other       Driver not loaded.
137 
138 **/
139 EFI_STATUS
140 EFIAPI
IDEBusDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)141 IDEBusDriverBindingSupported (
142   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
143   IN EFI_HANDLE                   Controller,
144   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
145   )
146 {
147   EFI_STATUS                        Status;
148   EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;
149   EFI_DEV_PATH                      *Node;
150   EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;
151   EFI_PCI_IO_PROTOCOL               *PciIo;
152   PCI_TYPE00                        PciData;
153 
154   if (RemainingDevicePath != NULL) {
155     Node = (EFI_DEV_PATH *) RemainingDevicePath;
156     //
157     // Check if RemainingDevicePath is the End of Device Path Node,
158     // if yes, go on checking other conditions
159     //
160     if (!IsDevicePathEnd (Node)) {
161       //
162       // If RemainingDevicePath isn't the End of Device Path Node,
163       // check its validation
164       //
165       if (Node->DevPath.Type != MESSAGING_DEVICE_PATH ||
166           Node->DevPath.SubType != MSG_ATAPI_DP ||
167           DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {
168         return EFI_UNSUPPORTED;
169       }
170     }
171   }
172 
173   //
174   // Verify the Ide Controller Init Protocol, which installed by the
175   // IdeController module.
176   //
177   Status = gBS->OpenProtocol (
178                   Controller,
179                   &gEfiIdeControllerInitProtocolGuid,
180                   (VOID **) &IdeInit,
181                   This->DriverBindingHandle,
182                   Controller,
183                   EFI_OPEN_PROTOCOL_BY_DRIVER
184                   );
185 
186   if (Status == EFI_ALREADY_STARTED) {
187     return EFI_SUCCESS;
188   }
189 
190   if (EFI_ERROR (Status)) {
191     return Status;
192   }
193 
194   //
195   // Close the I/O Abstraction(s) used to perform the supported test
196   //
197   gBS->CloseProtocol (
198         Controller,
199         &gEfiIdeControllerInitProtocolGuid,
200         This->DriverBindingHandle,
201         Controller
202         );
203 
204   //
205   // Open the EFI Device Path protocol needed to perform the supported test
206   //
207   Status = gBS->OpenProtocol (
208                   Controller,
209                   &gEfiDevicePathProtocolGuid,
210                   (VOID **) &ParentDevicePath,
211                   This->DriverBindingHandle,
212                   Controller,
213                   EFI_OPEN_PROTOCOL_BY_DRIVER
214                   );
215   if (Status == EFI_ALREADY_STARTED) {
216     return EFI_SUCCESS;
217   }
218 
219   //
220   // Close protocol, don't use device path protocol in the Support() function
221   //
222   gBS->CloseProtocol (
223         Controller,
224         &gEfiDevicePathProtocolGuid,
225         This->DriverBindingHandle,
226         Controller
227         );
228 
229   //
230   // Get the EfiPciIoProtocol
231   //
232   Status = gBS->OpenProtocol (
233                   Controller,
234                   &gEfiPciIoProtocolGuid,
235                   (VOID **) &PciIo,
236                   This->DriverBindingHandle,
237                   Controller,
238                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
239                   );
240 
241   if (EFI_ERROR (Status)) {
242     return Status;
243   }
244 
245   //
246   // Now further check the PCI header: Base class (offset 0x0B) and
247   // Sub Class (offset 0x0A). This controller should be an IDE controller
248   //
249   Status = PciIo->Pci.Read (
250                         PciIo,
251                         EfiPciIoWidthUint8,
252                         0,
253                         sizeof (PciData),
254                         &PciData
255                         );
256 
257   if (!EFI_ERROR (Status)) {
258     //
259     // Examine if it is IDE mode by class code
260     //
261     if ((PciData.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE) || (PciData.Hdr.ClassCode[1] != PCI_SUB_CLASS_IDE)) {
262       Status = EFI_UNSUPPORTED;
263     } else {
264       Status = EFI_SUCCESS;
265     }
266   }
267 
268   return Status;
269 }
270 
271 
272 /**
273   Start function of Driver binding protocol which start this driver on Controller
274   by detecting all disks and installing BlockIo protocol on them.
275 
276   @param  This                Protocol instance pointer.
277   @param  Controller          Handle of device to bind driver to.
278   @param  RemainingDevicePath produce all possible children.
279 
280   @retval  EFI_SUCCESS         This driver is added to ControllerHandle.
281   @retval  EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
282   @retval  other               This driver does not support this device.
283 
284 **/
285 EFI_STATUS
286 EFIAPI
IDEBusDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)287 IDEBusDriverBindingStart (
288   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
289   IN EFI_HANDLE                   Controller,
290   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
291   )
292 {
293   EFI_STATUS                        Status;
294   EFI_STATUS                        SavedStatus;
295   EFI_PCI_IO_PROTOCOL               *PciIo;
296   EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;
297   EFI_DEV_PATH                      *Node;
298   UINT8                             IdeChannel;
299   UINT8                             BeginningIdeChannel;
300   UINT8                             EndIdeChannel;
301   UINT8                             IdeDevice;
302   UINT8                             BeginningIdeDevice;
303   UINT8                             EndIdeDevice;
304   IDE_BLK_IO_DEV                    *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice];
305   IDE_BLK_IO_DEV                    *IdeBlkIoDevicePtr;
306   IDE_REGISTERS_BASE_ADDR           IdeRegsBaseAddr[IdeMaxChannel];
307   ATA_TRANSFER_MODE                 TransferMode;
308   ATA_DRIVE_PARMS                   DriveParameters;
309   EFI_DEV_PATH                      NewNode;
310   UINT8                             ConfigurationOptions;
311   UINT16                            CommandBlockBaseAddr;
312   UINT16                            ControlBlockBaseAddr;
313   UINTN                             DataSize;
314   IDE_BUS_DRIVER_PRIVATE_DATA       *IdeBusDriverPrivateData;
315   UINT64                            Supports;
316 
317   //
318   // Local variables declaration for IdeControllerInit support
319   //
320   EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;
321   BOOLEAN                           EnumAll;
322   BOOLEAN                           ChannelEnabled;
323   UINT8                             MaxDevices;
324   EFI_IDENTIFY_DATA                 IdentifyData;
325   EFI_ATA_COLLECTIVE_MODE           *SupportedModes;
326 
327   IdeBusDriverPrivateData = NULL;
328   SupportedModes          = NULL;
329 
330   //
331   // Perform IdeBus initialization
332   //
333   Status = gBS->OpenProtocol (
334                   Controller,
335                   &gEfiDevicePathProtocolGuid,
336                   (VOID **) &ParentDevicePath,
337                   This->DriverBindingHandle,
338                   Controller,
339                   EFI_OPEN_PROTOCOL_BY_DRIVER
340                   );
341   if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
342     return Status;
343   }
344 
345   //
346   // Now open the IDE_CONTROLLER_INIT protocol. Step7.1
347   //
348   Status = gBS->OpenProtocol (
349                   Controller,
350                   &gEfiIdeControllerInitProtocolGuid,
351                   (VOID **) &IdeInit,
352                   This->DriverBindingHandle,
353                   Controller,
354                   EFI_OPEN_PROTOCOL_BY_DRIVER
355                   );
356 
357   //
358   // The following OpenProtocol function with _GET_PROTOCOL attribute and
359   // will not return EFI_ALREADY_STARTED, so save it for now
360   //
361   SavedStatus = Status;
362 
363   if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
364     DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status));
365     //
366     // open protocol is not SUCCESS or not ALREADY_STARTED, error exit
367     //
368     goto ErrorExit;
369   }
370 
371   //
372   // Save Enumall. Step7.2
373   //
374   EnumAll       = IdeInit->EnumAll;
375 
376   //
377   // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL
378   // attribute will not return EFI_ALREADY_STARTED
379   //
380   Status = gBS->OpenProtocol (
381                   Controller,
382                   &gEfiPciIoProtocolGuid,
383                   (VOID **) &PciIo,
384                   This->DriverBindingHandle,
385                   Controller,
386                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
387                   );
388   if (EFI_ERROR (Status)) {
389     DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));
390     goto ErrorExit;
391   }
392 
393   //
394   // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable
395   //
396   if (SavedStatus != EFI_ALREADY_STARTED) {
397     IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));
398     if (IdeBusDriverPrivateData == NULL) {
399       Status = EFI_OUT_OF_RESOURCES;
400       goto ErrorExit;
401     }
402 
403     ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));
404     Status = gBS->InstallMultipleProtocolInterfaces (
405                     &Controller,
406                     &gEfiCallerIdGuid,
407                     IdeBusDriverPrivateData,
408                     NULL
409                     );
410     if (EFI_ERROR (Status)) {
411       goto ErrorExit;
412     }
413 
414   } else {
415     Status = gBS->OpenProtocol (
416                     Controller,
417                     &gEfiCallerIdGuid,
418                     (VOID **) &IdeBusDriverPrivateData,
419                     This->DriverBindingHandle,
420                     Controller,
421                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
422                     );
423     if (EFI_ERROR (Status)) {
424       IdeBusDriverPrivateData = NULL;
425       goto ErrorExit;
426     }
427   }
428 
429   Status = PciIo->Attributes (
430                     PciIo,
431                     EfiPciIoAttributeOperationSupported,
432                     0,
433                     &Supports
434                     );
435   if (!EFI_ERROR (Status)) {
436     Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
437     Status = PciIo->Attributes (
438                       PciIo,
439                       EfiPciIoAttributeOperationEnable,
440                       Supports,
441                       NULL
442                       );
443   }
444 
445   if (EFI_ERROR (Status)) {
446     goto ErrorExit;
447   }
448 
449   //
450   // Read the environment variable that contains the IDEBus Driver's
451   // Config options that were set by the Driver Configuration Protocol
452   //
453   DataSize = sizeof (ConfigurationOptions);
454   Status = gRT->GetVariable (
455                   (CHAR16 *) L"Configuration",
456                   &gEfiCallerIdGuid,
457                   NULL,
458                   &DataSize,
459                   &ConfigurationOptions
460                   );
461   if (EFI_ERROR (Status)) {
462     ConfigurationOptions = 0x0f;
463   }
464 
465    if (EnumAll || RemainingDevicePath == NULL) {
466     //
467     // If IdeInit->EnumAll is TRUE or RemainingDevicePath is NULL,
468     // must enumerate all IDE devices anyway
469     //
470     BeginningIdeChannel = IdePrimary;
471     EndIdeChannel       = IdeSecondary;
472     BeginningIdeDevice  = IdeMaster;
473     EndIdeDevice        = IdeSlave;
474 
475   } else if (!IsDevicePathEnd (RemainingDevicePath)) {
476     //
477     // If RemainingDevicePath isn't the End of Device Path Node,
478     // only scan the specified device by RemainingDevicePath
479     //
480     Node                = (EFI_DEV_PATH *) RemainingDevicePath;
481     BeginningIdeChannel = Node->Atapi.PrimarySecondary;
482     EndIdeChannel       = BeginningIdeChannel;
483     BeginningIdeDevice  = Node->Atapi.SlaveMaster;
484     EndIdeDevice        = BeginningIdeDevice;
485     if (BeginningIdeChannel >= IdeMaxChannel || EndIdeChannel >= IdeMaxChannel) {
486       Status = EFI_INVALID_PARAMETER;
487       goto ErrorExit;
488     }
489     if (BeginningIdeDevice >= IdeMaxDevice|| EndIdeDevice >= IdeMaxDevice) {
490       Status = EFI_INVALID_PARAMETER;
491       goto ErrorExit;
492     }
493 
494   } else {
495     //
496     // If RemainingDevicePath is the End of Device Path Node,
497     // skip enumerate any device and return EFI_SUCESSS
498     //
499     BeginningIdeChannel = IdeMaxChannel;
500     EndIdeChannel       = IdeMaxChannel - 1;
501     BeginningIdeDevice  = IdeMaxDevice;
502     EndIdeDevice        = IdeMaxDevice - 1;
503   }
504 
505   //
506   // Obtain IDE IO port registers' base addresses
507   //
508   Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);
509   if (EFI_ERROR (Status)) {
510     goto ErrorExit;
511   }
512 
513   //
514   // Report status code: begin IdeBus initialization
515   //
516   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
517     EFI_PROGRESS_CODE,
518     (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),
519     ParentDevicePath
520     );
521 
522   //
523   // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol
524   //
525   for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {
526 
527     IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);
528 
529     //
530     // now obtain channel information fron IdeControllerInit protocol. Step9
531     //
532     Status = IdeInit->GetChannelInfo (
533                         IdeInit,
534                         IdeChannel,
535                         &ChannelEnabled,
536                         &MaxDevices
537                         );
538     if (EFI_ERROR (Status)) {
539       DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));
540       continue;
541     }
542 
543     if (!ChannelEnabled) {
544       continue;
545     }
546 
547     EndIdeDevice = (UINT8) MIN ((MaxDevices - 1), EndIdeDevice);
548     ASSERT (EndIdeDevice < IdeMaxDevice);
549     //
550     // Now inform the IDE Controller Init Module. Sept10
551     //
552     IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);
553 
554     //
555     // No reset channel function implemented. Sept11
556     //
557     IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);
558 
559     //
560     // Step13
561     //
562     IdeInit->NotifyPhase (
563               IdeInit,
564               EfiIdeBusBeforeDevicePresenceDetection,
565               IdeChannel
566               );
567 
568     //
569     // Prepare to detect IDE device of this channel
570     //
571     InitializeIDEChannelData ();
572 
573     //
574     // -- 1st inner loop --- Master/Slave ------------  Step14
575     //
576     for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {
577       //
578       // Check whether the configuration options allow this device
579       //
580       if ((ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice))) == 0) {
581         continue;
582       }
583 
584       //
585       // The device has been scanned in another Start(), No need to scan it again
586       // for perf optimization.
587       //
588       if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {
589         continue;
590       }
591 
592       //
593       // create child handle for the detected device.
594       //
595       IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));
596       if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {
597         continue;
598       }
599 
600       IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];
601 
602       ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));
603 
604       IdeBlkIoDevicePtr->Signature  = IDE_BLK_IO_DEV_SIGNATURE;
605       IdeBlkIoDevicePtr->Channel    = (EFI_IDE_CHANNEL) IdeChannel;
606       IdeBlkIoDevicePtr->Device     = (EFI_IDE_DEVICE) IdeDevice;
607 
608       //
609       // initialize Block IO interface's Media pointer
610       //
611       IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;
612 
613       //
614       // Initialize IDE IO port addresses, including Command Block registers
615       // and Control Block registers
616       //
617       IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));
618       if (IdeBlkIoDevicePtr->IoPort == NULL) {
619         continue;
620       }
621 
622       ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));
623       CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;
624       ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;
625 
626       IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;
627       (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);
628       IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);
629       IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);
630       IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);
631       IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);
632       IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);
633       (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);
634 
635       (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;
636       IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);
637 
638       IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);
639 
640       IdeBlkIoDevicePtr->PciIo = PciIo;
641       IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;
642       IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;
643 
644       //
645       // Report Status code: is about to detect IDE drive
646       //
647       REPORT_STATUS_CODE_EX (
648         EFI_PROGRESS_CODE,
649         (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT),
650         0,
651         &gEfiCallerIdGuid,
652         NULL,
653         NULL,
654         0
655       );
656 
657       //
658       // Discover device, now!
659       //
660       PERF_START (NULL, "DiscoverIdeDevice", "IDE", 0);
661       Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);
662       PERF_END (NULL, "DiscoverIdeDevice", "IDE", 0);
663 
664       IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]  = TRUE;
665       IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]    = FALSE;
666 
667       if (!EFI_ERROR (Status)) {
668         //
669         // Set Device Path
670         //
671         ZeroMem (&NewNode, sizeof (NewNode));
672         NewNode.DevPath.Type    = MESSAGING_DEVICE_PATH;
673         NewNode.DevPath.SubType = MSG_ATAPI_DP;
674         SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));
675 
676         NewNode.Atapi.PrimarySecondary  = (UINT8) IdeBlkIoDevicePtr->Channel;
677         NewNode.Atapi.SlaveMaster       = (UINT8) IdeBlkIoDevicePtr->Device;
678         NewNode.Atapi.Lun               = IdeBlkIoDevicePtr->Lun;
679         IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (
680                                           ParentDevicePath,
681                                           &NewNode.DevPath
682                                           );
683         if (IdeBlkIoDevicePtr->DevicePath == NULL) {
684           ReleaseIdeResources (IdeBlkIoDevicePtr);
685           continue;
686         }
687 
688         //
689         // Submit identify data to IDE controller init driver
690         //
691         CopyMem (&IdentifyData, IdeBlkIoDevicePtr->IdData, sizeof (IdentifyData));
692         IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;
693         IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);
694       } else {
695         //
696         // Device detection failed
697         //
698         IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
699         IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);
700         ReleaseIdeResources (IdeBlkIoDevicePtr);
701         IdeBlkIoDevicePtr = NULL;
702       }
703       //
704       // end of 1st inner loop ---
705       //
706     }
707     //
708     // end of 1st outer loop =========
709     //
710   }
711 
712   //
713   // = 2nd outer loop == Primary/Secondary =================
714   //
715   for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {
716 
717     //
718     // -- 2nd inner loop --- Master/Slave --------
719     //
720     for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {
721 
722       ASSERT (IdeChannel * 2 + IdeDevice < MAX_IDE_DEVICE);
723       if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {
724         continue;
725       }
726 
727       if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {
728         continue;
729       }
730 
731       Status = IdeInit->CalculateMode (
732                           IdeInit,
733                           IdeChannel,
734                           IdeDevice,
735                           &SupportedModes
736                           );
737       if (EFI_ERROR (Status)) {
738         DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));
739         continue;
740       }
741 
742       ASSERT (IdeChannel < IdeMaxChannel && IdeDevice < IdeMaxDevice);
743       IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];
744 
745       //
746       // Set best supported PIO mode on this IDE device
747       //
748       if (SupportedModes->PioMode.Mode <= AtaPioMode2) {
749         TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;
750       } else {
751         TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;
752       }
753 
754       TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);
755 
756       if (SupportedModes->ExtModeCount == 0){
757         Status                  = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);
758 
759         if (EFI_ERROR (Status)) {
760           IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
761           ReleaseIdeResources (IdeBlkIoDevicePtr);
762           IdeBlkIoDevicePtr = NULL;
763           continue;
764         }
765       }
766 
767       //
768       // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
769       // be set together. Only one DMA mode can be set to a device. If setting
770       // DMA mode operation fails, we can continue moving on because we only use
771       // PIO mode at boot time. DMA modes are used by certain kind of OS booting
772       //
773       if (SupportedModes->UdmaMode.Valid) {
774 
775         TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;
776         TransferMode.ModeNumber   = (UINT8) (SupportedModes->UdmaMode.Mode);
777         Status                    = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);
778 
779         if (EFI_ERROR (Status)) {
780           IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
781           ReleaseIdeResources (IdeBlkIoDevicePtr);
782           IdeBlkIoDevicePtr = NULL;
783           continue;
784         }
785         //
786         // Record Udma Mode
787         //
788         IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;
789         IdeBlkIoDevicePtr->UdmaMode.Mode  = SupportedModes->UdmaMode.Mode;
790         EnableInterrupt (IdeBlkIoDevicePtr);
791       } else if (SupportedModes->MultiWordDmaMode.Valid) {
792 
793         TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;
794         TransferMode.ModeNumber   = (UINT8) SupportedModes->MultiWordDmaMode.Mode;
795         Status                    = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);
796 
797         if (EFI_ERROR (Status)) {
798           IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
799           ReleaseIdeResources (IdeBlkIoDevicePtr);
800           IdeBlkIoDevicePtr = NULL;
801           continue;
802         }
803 
804         EnableInterrupt (IdeBlkIoDevicePtr);
805       }
806       //
807       // Init driver parameters
808       //
809       DriveParameters.Sector          = (UINT8) ((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->sectors_per_track;
810       DriveParameters.Heads           = (UINT8) (((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->heads - 1);
811       DriveParameters.MultipleSector  = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.multi_sector_cmd_max_sct_cnt;
812       //
813       // Set Parameters for the device:
814       // 1) Init
815       // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
816       //
817       if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {
818         Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);
819       }
820 
821       //
822       // Record PIO mode used in private data
823       //
824       IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;
825 
826       //
827       // Set IDE controller Timing Blocks in the PCI Configuration Space
828       //
829       IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);
830 
831       //
832       // Add Component Name for the IDE/ATAPI device that was discovered.
833       //
834       IdeBlkIoDevicePtr->ControllerNameTable = NULL;
835       ADD_IDE_ATAPI_NAME (IdeBlkIoDevicePtr);
836 
837       Status = gBS->InstallMultipleProtocolInterfaces (
838                       &IdeBlkIoDevicePtr->Handle,
839                       &gEfiDevicePathProtocolGuid,
840                       IdeBlkIoDevicePtr->DevicePath,
841                       &gEfiBlockIoProtocolGuid,
842                       &IdeBlkIoDevicePtr->BlkIo,
843                       &gEfiDiskInfoProtocolGuid,
844                       &IdeBlkIoDevicePtr->DiskInfo,
845                       NULL
846                       );
847 
848       if (EFI_ERROR (Status)) {
849         ReleaseIdeResources (IdeBlkIoDevicePtr);
850       }
851 
852       gBS->OpenProtocol (
853             Controller,
854             &gEfiPciIoProtocolGuid,
855             (VOID **) &PciIo,
856             This->DriverBindingHandle,
857             IdeBlkIoDevicePtr->Handle,
858             EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
859             );
860 
861       IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;
862 
863       //
864       // Report status code: device eanbled!
865       //
866       REPORT_STATUS_CODE_WITH_DEVICE_PATH (
867         EFI_PROGRESS_CODE,
868         (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),
869         IdeBlkIoDevicePtr->DevicePath
870         );
871 
872       //
873       // Create event to clear pending IDE interrupt
874       //
875       Status = gBS->CreateEventEx (
876                       EVT_NOTIFY_SIGNAL,
877                       TPL_NOTIFY,
878                       ClearInterrupt,
879                       IdeBlkIoDevicePtr,
880                       &gEfiEventExitBootServicesGuid,
881                       &IdeBlkIoDevicePtr->ExitBootServiceEvent
882                       );
883 
884       //
885       // end of 2nd inner loop ----
886       //
887     }
888     //
889     // end of 2nd outer loop ==========
890     //
891   }
892 
893   //
894   // All configurations done! Notify IdeController to do post initialization
895   // work such as saving IDE controller PCI settings for S3 resume
896   //
897   IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);
898 
899   if (SupportedModes != NULL) {
900     FreePool (SupportedModes);
901   }
902 
903   PERF_START (NULL, "Finish IDE detection", "IDE", 1);
904   PERF_END (NULL, "Finish IDE detection", "IDE", 0);
905 
906   return EFI_SUCCESS;
907 
908 ErrorExit:
909 
910   //
911   // Report error code: controller error
912   //
913   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
914     EFI_ERROR_CODE | EFI_ERROR_MINOR,
915     (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),
916     ParentDevicePath
917     );
918 
919   gBS->CloseProtocol (
920         Controller,
921         &gEfiIdeControllerInitProtocolGuid,
922         This->DriverBindingHandle,
923         Controller
924         );
925 
926   gBS->UninstallMultipleProtocolInterfaces (
927         Controller,
928         &gEfiCallerIdGuid,
929         IdeBusDriverPrivateData,
930         NULL
931         );
932 
933   if (IdeBusDriverPrivateData != NULL) {
934     gBS->FreePool (IdeBusDriverPrivateData);
935   }
936 
937   if (SupportedModes != NULL) {
938     gBS->FreePool (SupportedModes);
939   }
940 
941   gBS->CloseProtocol (
942         Controller,
943         &gEfiPciIoProtocolGuid,
944         This->DriverBindingHandle,
945         Controller
946         );
947 
948   gBS->CloseProtocol (
949         Controller,
950         &gEfiDevicePathProtocolGuid,
951         This->DriverBindingHandle,
952         Controller
953         );
954 
955   return Status;
956 
957 }
958 /**
959   Stop function of Driver Binding Protocol which is to stop the driver on Controller Handle and all
960   child handle attached to the controller handle if there are.
961 
962   @param  This Protocol instance pointer.
963   @param  Controller Handle of device to stop driver on
964   @param  NumberOfChildren Not used
965   @param  ChildHandleBuffer Not used
966 
967   @retval  EFI_SUCCESS This driver is removed DeviceHandle
968   @retval  other This driver was not removed from this device
969 
970 **/
971 EFI_STATUS
972 EFIAPI
IDEBusDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)973 IDEBusDriverBindingStop (
974   IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
975   IN  EFI_HANDLE                      Controller,
976   IN  UINTN                           NumberOfChildren,
977   IN  EFI_HANDLE                      *ChildHandleBuffer
978   )
979 {
980   EFI_STATUS                  Status;
981   EFI_PCI_IO_PROTOCOL         *PciIo;
982   BOOLEAN                     AllChildrenStopped;
983   UINTN                       Index;
984   IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;
985   UINT64                      Supports;
986 
987   IdeBusDriverPrivateData = NULL;
988 
989   if (NumberOfChildren == 0) {
990 
991     Status = gBS->OpenProtocol (
992                     Controller,
993                     &gEfiPciIoProtocolGuid,
994                     (VOID **) &PciIo,
995                     This->DriverBindingHandle,
996                     Controller,
997                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
998                     );
999     if (!EFI_ERROR (Status)) {
1000       Status = PciIo->Attributes (
1001                         PciIo,
1002                         EfiPciIoAttributeOperationSupported,
1003                         0,
1004                         &Supports
1005                         );
1006       if (!EFI_ERROR (Status)) {
1007         Supports &= (UINT64)(EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE);
1008         PciIo->Attributes (
1009                 PciIo,
1010                 EfiPciIoAttributeOperationDisable,
1011                 Supports,
1012                 NULL
1013                 );
1014       }
1015     }
1016 
1017     gBS->OpenProtocol (
1018           Controller,
1019           &gEfiCallerIdGuid,
1020           (VOID **) &IdeBusDriverPrivateData,
1021           This->DriverBindingHandle,
1022           Controller,
1023           EFI_OPEN_PROTOCOL_GET_PROTOCOL
1024           );
1025 
1026     gBS->UninstallMultipleProtocolInterfaces (
1027           Controller,
1028           &gEfiCallerIdGuid,
1029           IdeBusDriverPrivateData,
1030           NULL
1031           );
1032 
1033     if (IdeBusDriverPrivateData != NULL) {
1034       gBS->FreePool (IdeBusDriverPrivateData);
1035     }
1036     //
1037     // Close the bus driver
1038     //
1039     gBS->CloseProtocol (
1040           Controller,
1041           &gEfiIdeControllerInitProtocolGuid,
1042           This->DriverBindingHandle,
1043           Controller
1044           );
1045     gBS->CloseProtocol (
1046           Controller,
1047           &gEfiPciIoProtocolGuid,
1048           This->DriverBindingHandle,
1049           Controller
1050           );
1051     gBS->CloseProtocol (
1052           Controller,
1053           &gEfiDevicePathProtocolGuid,
1054           This->DriverBindingHandle,
1055           Controller
1056           );
1057 
1058     return EFI_SUCCESS;
1059   }
1060 
1061   AllChildrenStopped = TRUE;
1062 
1063   for (Index = 0; Index < NumberOfChildren; Index++) {
1064 
1065     Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);
1066 
1067     if (EFI_ERROR (Status)) {
1068       AllChildrenStopped = FALSE;
1069     }
1070   }
1071 
1072   if (!AllChildrenStopped) {
1073     return EFI_DEVICE_ERROR;
1074   }
1075 
1076   return EFI_SUCCESS;
1077 }
1078 
1079 /**
1080   issue ATA or ATAPI command to reset a block IO device.
1081   @param  This                  Block IO protocol instance pointer.
1082   @param  ExtendedVerification  If FALSE,for ATAPI device, driver will only invoke ATAPI reset method
1083                                 If TRUE, for ATAPI device, driver need invoke ATA reset method after
1084                                 invoke ATAPI reset method
1085 
1086   @retval EFI_DEVICE_ERROR      When the device is neighther ATA device or ATAPI device.
1087   @retval EFI_SUCCESS           The device reset successfully
1088 
1089 **/
1090 EFI_STATUS
1091 EFIAPI
IDEBlkIoReset(IN EFI_BLOCK_IO_PROTOCOL * This,IN BOOLEAN ExtendedVerification)1092 IDEBlkIoReset (
1093   IN  EFI_BLOCK_IO_PROTOCOL   *This,
1094   IN  BOOLEAN                 ExtendedVerification
1095   )
1096 {
1097   IDE_BLK_IO_DEV  *IdeBlkIoDevice;
1098   EFI_STATUS      Status;
1099   EFI_TPL         OldTpl;
1100 
1101   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1102 
1103   IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);
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 device, using ATA reset method
1111   //
1112   if (IdeBlkIoDevice->Type == IdeHardDisk ||
1113       IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
1114     Status = AtaSoftReset (IdeBlkIoDevice);
1115     goto Done;
1116   }
1117 
1118   if (IdeBlkIoDevice->Type == IdeUnknown) {
1119     Status = EFI_DEVICE_ERROR;
1120     goto Done;
1121   }
1122 
1123   //
1124   // for ATAPI device, using ATAPI reset method
1125   //
1126   Status = AtapiSoftReset (IdeBlkIoDevice);
1127   if (ExtendedVerification) {
1128     Status = AtaSoftReset (IdeBlkIoDevice);
1129   }
1130 
1131 Done:
1132   gBS->RestoreTPL (OldTpl);
1133   return Status;
1134 }
1135 
1136 /**
1137   Read data from a block IO device
1138 
1139   @param  This       Block IO protocol instance pointer.
1140   @param  MediaId    The media ID of the device
1141   @param  Lba        Starting LBA address to read data
1142   @param  BufferSize The size of data to be read
1143   @param  Buffer     Caller supplied buffer to save data
1144 
1145   @retval EFI_DEVICE_ERROR  unknown device type
1146   @retval other             read data status.
1147 
1148 **/
1149 EFI_STATUS
1150 EFIAPI
IDEBlkIoReadBlocks(IN EFI_BLOCK_IO_PROTOCOL * This,IN UINT32 MediaId,IN EFI_LBA Lba,IN UINTN BufferSize,OUT VOID * Buffer)1151 IDEBlkIoReadBlocks (
1152   IN  EFI_BLOCK_IO_PROTOCOL   *This,
1153   IN  UINT32                  MediaId,
1154   IN  EFI_LBA                 Lba,
1155   IN  UINTN                   BufferSize,
1156   OUT VOID                    *Buffer
1157   )
1158 {
1159   IDE_BLK_IO_DEV  *IdeBlkIoDevice;
1160   EFI_STATUS      Status;
1161   EFI_TPL         OldTpl;
1162 
1163   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1164 
1165   IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);
1166 
1167   //
1168   // Requery IDE IO resources in case of the switch of native and legacy modes
1169   //
1170   ReassignIdeResources (IdeBlkIoDevice);
1171 
1172   //
1173   // For ATA compatible device, use ATA read block's mechanism
1174   //
1175   if (IdeBlkIoDevice->Type == IdeHardDisk ||
1176       IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
1177     Status = AtaBlkIoReadBlocks (
1178             IdeBlkIoDevice,
1179             MediaId,
1180             Lba,
1181             BufferSize,
1182             Buffer
1183             );
1184     goto Done;
1185   }
1186 
1187   if (IdeBlkIoDevice->Type == IdeUnknown) {
1188     Status = EFI_DEVICE_ERROR;
1189     goto Done;
1190   }
1191 
1192   //
1193   // for ATAPI device, using ATAPI read block's mechanism
1194   //
1195   Status = AtapiBlkIoReadBlocks (
1196           IdeBlkIoDevice,
1197           MediaId,
1198           Lba,
1199           BufferSize,
1200           Buffer
1201           );
1202 
1203 Done:
1204   gBS->RestoreTPL (OldTpl);
1205 
1206   return Status;
1207 }
1208 
1209 /**
1210   Write data to block io device.
1211 
1212   @param  This       Protocol instance pointer.
1213   @param  MediaId    The media ID of the device
1214   @param  Lba        Starting LBA address to write data
1215   @param  BufferSize The size of data to be written
1216   @param  Buffer     Caller supplied buffer to save data
1217 
1218   @retval EFI_DEVICE_ERROR  unknown device type
1219   @retval other             write data status
1220 
1221 **/
1222 EFI_STATUS
1223 EFIAPI
IDEBlkIoWriteBlocks(IN EFI_BLOCK_IO_PROTOCOL * This,IN UINT32 MediaId,IN EFI_LBA Lba,IN UINTN BufferSize,IN VOID * Buffer)1224 IDEBlkIoWriteBlocks (
1225   IN  EFI_BLOCK_IO_PROTOCOL   *This,
1226   IN  UINT32                  MediaId,
1227   IN  EFI_LBA                 Lba,
1228   IN  UINTN                   BufferSize,
1229   IN  VOID                    *Buffer
1230   )
1231 {
1232   IDE_BLK_IO_DEV  *IdeBlkIoDevice;
1233   EFI_STATUS      Status;
1234   EFI_TPL         OldTpl;
1235 
1236   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1237 
1238   IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);
1239   //
1240   // Requery IDE IO resources in case of the switch of native and legacy modes
1241   //
1242   ReassignIdeResources (IdeBlkIoDevice);
1243 
1244   //
1245   // for ATA device, using ATA write block's mechanism
1246   //
1247   if (IdeBlkIoDevice->Type == IdeHardDisk ||
1248       IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
1249 
1250     Status = AtaBlkIoWriteBlocks (
1251             IdeBlkIoDevice,
1252             MediaId,
1253             Lba,
1254             BufferSize,
1255             Buffer
1256             );
1257     goto Done;
1258   }
1259 
1260   if (IdeBlkIoDevice->Type == IdeUnknown) {
1261     Status = EFI_DEVICE_ERROR;
1262     goto Done;
1263   }
1264 
1265   //
1266   // for ATAPI device, using ATAPI write block's mechanism
1267   //
1268   Status = AtapiBlkIoWriteBlocks (
1269           IdeBlkIoDevice,
1270           MediaId,
1271           Lba,
1272           BufferSize,
1273           Buffer
1274           );
1275 
1276 Done:
1277   gBS->RestoreTPL (OldTpl);
1278   return Status;
1279 }
1280 /**
1281   Flushes all modified data to a physical block devices
1282 
1283   @param  This  Indicates a pointer to the calling context which to sepcify a
1284                 sepcific block device
1285 
1286   @retval EFI_SUCCESS   Always return success.
1287 **/
1288 EFI_STATUS
1289 EFIAPI
IDEBlkIoFlushBlocks(IN EFI_BLOCK_IO_PROTOCOL * This)1290 IDEBlkIoFlushBlocks (
1291   IN  EFI_BLOCK_IO_PROTOCOL   *This
1292   )
1293 {
1294   //
1295   // return directly
1296   //
1297   return EFI_SUCCESS;
1298 }
1299 
1300 /**
1301   This function is used by the IDE bus driver to get inquiry data.
1302   Data format of Identify data is defined by the Interface GUID.
1303 
1304   @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1305   @param  InquiryData           Pointer to a buffer for the inquiry data.
1306   @param  InquiryDataSize       Pointer to the value for the inquiry data size.
1307 
1308   @retval EFI_SUCCESS           The command was accepted without any errors.
1309   @retval EFI_NOT_FOUND         Device does not support this data class
1310   @retval EFI_DEVICE_ERROR      Error reading InquiryData from device
1311   @retval EFI_BUFFER_TOO_SMALL  IntquiryDataSize not big enough
1312 
1313 **/
1314 EFI_STATUS
1315 EFIAPI
IDEDiskInfoInquiry(IN EFI_DISK_INFO_PROTOCOL * This,IN OUT VOID * InquiryData,IN OUT UINT32 * InquiryDataSize)1316 IDEDiskInfoInquiry (
1317   IN     EFI_DISK_INFO_PROTOCOL   *This,
1318   IN OUT VOID                     *InquiryData,
1319   IN OUT UINT32                   *InquiryDataSize
1320   )
1321 {
1322   IDE_BLK_IO_DEV  *IdeBlkIoDevice;
1323 
1324   IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);
1325 
1326   if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) {
1327     *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);
1328     return EFI_BUFFER_TOO_SMALL;
1329   }
1330 
1331   if (IdeBlkIoDevice->InquiryData == NULL) {
1332     return EFI_NOT_FOUND;
1333   }
1334 
1335   gBS->CopyMem (InquiryData, IdeBlkIoDevice->InquiryData, sizeof (ATAPI_INQUIRY_DATA));
1336   *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);
1337 
1338   return EFI_SUCCESS;
1339 }
1340 
1341 /**
1342   This function is used by the IDE bus driver to get identify data.
1343   Data format of Identify data is defined by the Interface GUID.
1344 
1345   @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1346   @param  IdentifyData          Pointer to a buffer for the identify data.
1347   @param  IdentifyDataSize      Pointer to the value for the identify data size.
1348 
1349   @retval EFI_SUCCESS           The command was accepted without any errors.
1350   @retval EFI_NOT_FOUND         Device does not support this data class
1351   @retval EFI_DEVICE_ERROR      Error reading IdentifyData from device
1352   @retval EFI_BUFFER_TOO_SMALL  IdentifyDataSize not big enough
1353 
1354 **/
1355 EFI_STATUS
1356 EFIAPI
IDEDiskInfoIdentify(IN EFI_DISK_INFO_PROTOCOL * This,IN OUT VOID * IdentifyData,IN OUT UINT32 * IdentifyDataSize)1357 IDEDiskInfoIdentify (
1358   IN     EFI_DISK_INFO_PROTOCOL   *This,
1359   IN OUT VOID                     *IdentifyData,
1360   IN OUT UINT32                   *IdentifyDataSize
1361   )
1362 {
1363   IDE_BLK_IO_DEV  *IdeBlkIoDevice;
1364 
1365   IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);
1366 
1367   if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {
1368     *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);
1369     return EFI_BUFFER_TOO_SMALL;
1370   }
1371 
1372   if (IdeBlkIoDevice->IdData == NULL) {
1373     return EFI_NOT_FOUND;
1374   }
1375 
1376   gBS->CopyMem (IdentifyData, IdeBlkIoDevice->IdData, sizeof (EFI_IDENTIFY_DATA));
1377   *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);
1378 
1379   return EFI_SUCCESS;
1380 }
1381 
1382 /**
1383   This function is used by the IDE bus driver to get sense data.
1384   Data format of Sense data is defined by the Interface GUID.
1385 
1386   @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1387   @param  SenseData             Pointer to the SenseData.
1388   @param  SenseDataSize         Size of SenseData in bytes.
1389   @param  SenseDataNumber       Pointer to the value for the identify data size.
1390 
1391   @retval EFI_SUCCESS           The command was accepted without any errors.
1392   @retval EFI_NOT_FOUND         Device does not support this data class
1393   @retval EFI_DEVICE_ERROR      Error reading InquiryData from device
1394   @retval EFI_BUFFER_TOO_SMALL  SenseDataSize not big enough
1395 
1396 **/
1397 EFI_STATUS
1398 EFIAPI
IDEDiskInfoSenseData(IN EFI_DISK_INFO_PROTOCOL * This,IN OUT VOID * SenseData,IN OUT UINT32 * SenseDataSize,OUT UINT8 * SenseDataNumber)1399 IDEDiskInfoSenseData (
1400   IN     EFI_DISK_INFO_PROTOCOL   *This,
1401   IN OUT VOID                     *SenseData,
1402   IN OUT UINT32                   *SenseDataSize,
1403   OUT    UINT8                    *SenseDataNumber
1404   )
1405 {
1406   return EFI_NOT_FOUND;
1407 }
1408 
1409 /**
1410   This function is used by the IDE bus driver to get controller information.
1411 
1412   @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1413   @param  IdeChannel            Pointer to the Ide Channel number. Primary or secondary.
1414   @param  IdeDevice             Pointer to the Ide Device number. Master or slave.
1415 
1416   @retval EFI_SUCCESS           IdeChannel and IdeDevice are valid
1417   @retval EFI_UNSUPPORTED       This is not an IDE device
1418 
1419 **/
1420 EFI_STATUS
1421 EFIAPI
IDEDiskInfoWhichIde(IN EFI_DISK_INFO_PROTOCOL * This,OUT UINT32 * IdeChannel,OUT UINT32 * IdeDevice)1422 IDEDiskInfoWhichIde (
1423   IN  EFI_DISK_INFO_PROTOCOL   *This,
1424   OUT UINT32                   *IdeChannel,
1425   OUT UINT32                   *IdeDevice
1426   )
1427 {
1428   IDE_BLK_IO_DEV  *IdeBlkIoDevice;
1429 
1430   IdeBlkIoDevice  = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);
1431   *IdeChannel     = IdeBlkIoDevice->Channel;
1432   *IdeDevice      = IdeBlkIoDevice->Device;
1433 
1434   return EFI_SUCCESS;
1435 }
1436 
1437 /**
1438   The is an event(generally the event is exitBootService event) call back function.
1439   Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.
1440 
1441   @param  Event   Pointer to this event
1442   @param  Context Event handler private data
1443 
1444 **/
1445 VOID
1446 EFIAPI
ClearInterrupt(IN EFI_EVENT Event,IN VOID * Context)1447 ClearInterrupt (
1448   IN EFI_EVENT  Event,
1449   IN VOID       *Context
1450   )
1451 {
1452   EFI_STATUS      Status;
1453   UINT64          IoPortForBmis;
1454   UINT8           RegisterValue;
1455   IDE_BLK_IO_DEV  *IdeDev;
1456 
1457   //
1458   // Get our context
1459   //
1460   IdeDev = (IDE_BLK_IO_DEV *) Context;
1461 
1462   //
1463   // Obtain IDE IO port registers' base addresses
1464   //
1465   Status = ReassignIdeResources (IdeDev);
1466   if (EFI_ERROR (Status)) {
1467     return;
1468   }
1469 
1470   //
1471   // Check whether interrupt is pending
1472   //
1473 
1474   //
1475   // Reset IDE device to force it de-assert interrupt pin
1476   // Note: this will reset all devices on this IDE channel
1477   //
1478   Status = AtaSoftReset (IdeDev);
1479   if (EFI_ERROR (Status)) {
1480     return;
1481   }
1482 
1483   //
1484   // Get base address of IDE Bus Master Status Regsiter
1485   //
1486   if (IdePrimary == IdeDev->Channel) {
1487     IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
1488   } else {
1489     if (IdeSecondary == IdeDev->Channel) {
1490       IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;
1491     } else {
1492       return;
1493     }
1494   }
1495   //
1496   // Read BMIS register and clear ERROR and INTR bit
1497   //
1498   IdeDev->PciIo->Io.Read (
1499                       IdeDev->PciIo,
1500                       EfiPciIoWidthUint8,
1501                       EFI_PCI_IO_PASS_THROUGH_BAR,
1502                       IoPortForBmis,
1503                       1,
1504                       &RegisterValue
1505                       );
1506 
1507   RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
1508 
1509   IdeDev->PciIo->Io.Write (
1510                       IdeDev->PciIo,
1511                       EfiPciIoWidthUint8,
1512                       EFI_PCI_IO_PASS_THROUGH_BAR,
1513                       IoPortForBmis,
1514                       1,
1515                       &RegisterValue
1516                       );
1517 
1518   //
1519   // Select the other device on this channel to ensure this device to release the interrupt pin
1520   //
1521   if (IdeDev->Device == 0) {
1522     RegisterValue = (1 << 4) | 0xe0;
1523   } else {
1524     RegisterValue = (0 << 4) | 0xe0;
1525   }
1526   IDEWritePortB (
1527     IdeDev->PciIo,
1528     IdeDev->IoPort->Head,
1529     RegisterValue
1530     );
1531 
1532 }
1533 
1534 /**
1535   The user Entry Point for module IdeBus. The user code starts with this function.
1536 
1537   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
1538   @param[in] SystemTable    A pointer to the EFI System Table.
1539 
1540   @retval EFI_SUCCESS       The entry point is executed successfully.
1541   @retval other             Some error occurs when executing this entry point.
1542 
1543 **/
1544 EFI_STATUS
1545 EFIAPI
InitializeIdeBus(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)1546 InitializeIdeBus(
1547   IN EFI_HANDLE           ImageHandle,
1548   IN EFI_SYSTEM_TABLE     *SystemTable
1549   )
1550 {
1551   EFI_STATUS              Status;
1552 
1553   //
1554   // Install driver model protocol(s).
1555   //
1556   Status = EfiLibInstallAllDriverProtocols2 (
1557              ImageHandle,
1558              SystemTable,
1559              &gIDEBusDriverBinding,
1560              ImageHandle,
1561              &gIDEBusComponentName,
1562              &gIDEBusComponentName2,
1563              NULL,
1564              NULL,
1565              &gIDEBusDriverDiagnostics,
1566              &gIDEBusDriverDiagnostics2
1567              );
1568   ASSERT_EFI_ERROR (Status);
1569 
1570   return Status;
1571 }
1572