]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBus.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / IdeBusDxe / IdeBus.c
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 - 2018, 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }