]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBus.c
IntelFrameworkModulePkg/IdeBusDxe: Add error check on the return status of invoking...
[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 - 2010, 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 &= 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 if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {
723 continue;
724 }
725
726 if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {
727 continue;
728 }
729
730 Status = IdeInit->CalculateMode (
731 IdeInit,
732 IdeChannel,
733 IdeDevice,
734 &SupportedModes
735 );
736 if (EFI_ERROR (Status)) {
737 DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));
738 continue;
739 }
740
741 IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];
742
743 //
744 // Set best supported PIO mode on this IDE device
745 //
746 if (SupportedModes->PioMode.Mode <= AtaPioMode2) {
747 TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;
748 } else {
749 TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;
750 }
751
752 TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);
753
754 if (SupportedModes->ExtModeCount == 0){
755 Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);
756
757 if (EFI_ERROR (Status)) {
758 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
759 ReleaseIdeResources (IdeBlkIoDevicePtr);
760 IdeBlkIoDevicePtr = NULL;
761 continue;
762 }
763 }
764
765 //
766 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
767 // be set together. Only one DMA mode can be set to a device. If setting
768 // DMA mode operation fails, we can continue moving on because we only use
769 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
770 //
771 if (SupportedModes->UdmaMode.Valid) {
772
773 TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;
774 TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);
775 Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);
776
777 if (EFI_ERROR (Status)) {
778 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
779 ReleaseIdeResources (IdeBlkIoDevicePtr);
780 IdeBlkIoDevicePtr = NULL;
781 continue;
782 }
783 //
784 // Record Udma Mode
785 //
786 IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;
787 IdeBlkIoDevicePtr->UdmaMode.Mode = SupportedModes->UdmaMode.Mode;
788 EnableInterrupt (IdeBlkIoDevicePtr);
789 } else if (SupportedModes->MultiWordDmaMode.Valid) {
790
791 TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;
792 TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;
793 Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);
794
795 if (EFI_ERROR (Status)) {
796 IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
797 ReleaseIdeResources (IdeBlkIoDevicePtr);
798 IdeBlkIoDevicePtr = NULL;
799 continue;
800 }
801
802 EnableInterrupt (IdeBlkIoDevicePtr);
803 }
804 //
805 // Init driver parameters
806 //
807 DriveParameters.Sector = (UINT8) ((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->sectors_per_track;
808 DriveParameters.Heads = (UINT8) (((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->heads - 1);
809 DriveParameters.MultipleSector = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.multi_sector_cmd_max_sct_cnt;
810 //
811 // Set Parameters for the device:
812 // 1) Init
813 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
814 //
815 if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {
816 Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);
817 }
818
819 //
820 // Record PIO mode used in private data
821 //
822 IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;
823
824 //
825 // Set IDE controller Timing Blocks in the PCI Configuration Space
826 //
827 IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);
828
829 //
830 // Add Component Name for the IDE/ATAPI device that was discovered.
831 //
832 IdeBlkIoDevicePtr->ControllerNameTable = NULL;
833 ADD_IDE_ATAPI_NAME (IdeBlkIoDevicePtr);
834
835 Status = gBS->InstallMultipleProtocolInterfaces (
836 &IdeBlkIoDevicePtr->Handle,
837 &gEfiDevicePathProtocolGuid,
838 IdeBlkIoDevicePtr->DevicePath,
839 &gEfiBlockIoProtocolGuid,
840 &IdeBlkIoDevicePtr->BlkIo,
841 &gEfiDiskInfoProtocolGuid,
842 &IdeBlkIoDevicePtr->DiskInfo,
843 NULL
844 );
845
846 if (EFI_ERROR (Status)) {
847 ReleaseIdeResources (IdeBlkIoDevicePtr);
848 }
849
850 gBS->OpenProtocol (
851 Controller,
852 &gEfiPciIoProtocolGuid,
853 (VOID **) &PciIo,
854 This->DriverBindingHandle,
855 IdeBlkIoDevicePtr->Handle,
856 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
857 );
858
859 IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;
860
861 //
862 // Report status code: device eanbled!
863 //
864 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
865 EFI_PROGRESS_CODE,
866 (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),
867 IdeBlkIoDevicePtr->DevicePath
868 );
869
870 //
871 // Create event to clear pending IDE interrupt
872 //
873 Status = gBS->CreateEventEx (
874 EVT_NOTIFY_SIGNAL,
875 TPL_NOTIFY,
876 ClearInterrupt,
877 IdeBlkIoDevicePtr,
878 &gEfiEventExitBootServicesGuid,
879 &IdeBlkIoDevicePtr->ExitBootServiceEvent
880 );
881
882 //
883 // end of 2nd inner loop ----
884 //
885 }
886 //
887 // end of 2nd outer loop ==========
888 //
889 }
890
891 //
892 // All configurations done! Notify IdeController to do post initialization
893 // work such as saving IDE controller PCI settings for S3 resume
894 //
895 IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);
896
897 if (SupportedModes != NULL) {
898 FreePool (SupportedModes);
899 }
900
901 PERF_START (NULL, "Finish IDE detection", "IDE", 1);
902 PERF_END (NULL, "Finish IDE detection", "IDE", 0);
903
904 return EFI_SUCCESS;
905
906 ErrorExit:
907
908 //
909 // Report error code: controller error
910 //
911 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
912 EFI_ERROR_CODE | EFI_ERROR_MINOR,
913 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),
914 ParentDevicePath
915 );
916
917 gBS->CloseProtocol (
918 Controller,
919 &gEfiIdeControllerInitProtocolGuid,
920 This->DriverBindingHandle,
921 Controller
922 );
923
924 gBS->UninstallMultipleProtocolInterfaces (
925 Controller,
926 &gEfiCallerIdGuid,
927 IdeBusDriverPrivateData,
928 NULL
929 );
930
931 if (IdeBusDriverPrivateData != NULL) {
932 gBS->FreePool (IdeBusDriverPrivateData);
933 }
934
935 if (SupportedModes != NULL) {
936 gBS->FreePool (SupportedModes);
937 }
938
939 gBS->CloseProtocol (
940 Controller,
941 &gEfiPciIoProtocolGuid,
942 This->DriverBindingHandle,
943 Controller
944 );
945
946 gBS->CloseProtocol (
947 Controller,
948 &gEfiDevicePathProtocolGuid,
949 This->DriverBindingHandle,
950 Controller
951 );
952
953 return Status;
954
955 }
956 /**
957 Stop function of Driver Binding Protocol which is to stop the driver on Controller Handle and all
958 child handle attached to the controller handle if there are.
959
960 @param This Protocol instance pointer.
961 @param Controller Handle of device to stop driver on
962 @param NumberOfChildren Not used
963 @param ChildHandleBuffer Not used
964
965 @retval EFI_SUCCESS This driver is removed DeviceHandle
966 @retval other This driver was not removed from this device
967
968 **/
969 EFI_STATUS
970 EFIAPI
971 IDEBusDriverBindingStop (
972 IN EFI_DRIVER_BINDING_PROTOCOL *This,
973 IN EFI_HANDLE Controller,
974 IN UINTN NumberOfChildren,
975 IN EFI_HANDLE *ChildHandleBuffer
976 )
977 {
978 EFI_STATUS Status;
979 EFI_PCI_IO_PROTOCOL *PciIo;
980 BOOLEAN AllChildrenStopped;
981 UINTN Index;
982 IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;
983 UINT64 Supports;
984
985 IdeBusDriverPrivateData = NULL;
986
987 if (NumberOfChildren == 0) {
988
989 Status = gBS->OpenProtocol (
990 Controller,
991 &gEfiPciIoProtocolGuid,
992 (VOID **) &PciIo,
993 This->DriverBindingHandle,
994 Controller,
995 EFI_OPEN_PROTOCOL_GET_PROTOCOL
996 );
997 if (!EFI_ERROR (Status)) {
998 Status = PciIo->Attributes (
999 PciIo,
1000 EfiPciIoAttributeOperationSupported,
1001 0,
1002 &Supports
1003 );
1004 if (!EFI_ERROR (Status)) {
1005 Supports &= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;
1006 PciIo->Attributes (
1007 PciIo,
1008 EfiPciIoAttributeOperationDisable,
1009 Supports,
1010 NULL
1011 );
1012 }
1013 }
1014
1015 gBS->OpenProtocol (
1016 Controller,
1017 &gEfiCallerIdGuid,
1018 (VOID **) &IdeBusDriverPrivateData,
1019 This->DriverBindingHandle,
1020 Controller,
1021 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1022 );
1023
1024 gBS->UninstallMultipleProtocolInterfaces (
1025 Controller,
1026 &gEfiCallerIdGuid,
1027 IdeBusDriverPrivateData,
1028 NULL
1029 );
1030
1031 if (IdeBusDriverPrivateData != NULL) {
1032 gBS->FreePool (IdeBusDriverPrivateData);
1033 }
1034 //
1035 // Close the bus driver
1036 //
1037 gBS->CloseProtocol (
1038 Controller,
1039 &gEfiIdeControllerInitProtocolGuid,
1040 This->DriverBindingHandle,
1041 Controller
1042 );
1043 gBS->CloseProtocol (
1044 Controller,
1045 &gEfiPciIoProtocolGuid,
1046 This->DriverBindingHandle,
1047 Controller
1048 );
1049 gBS->CloseProtocol (
1050 Controller,
1051 &gEfiDevicePathProtocolGuid,
1052 This->DriverBindingHandle,
1053 Controller
1054 );
1055
1056 return EFI_SUCCESS;
1057 }
1058
1059 AllChildrenStopped = TRUE;
1060
1061 for (Index = 0; Index < NumberOfChildren; Index++) {
1062
1063 Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);
1064
1065 if (EFI_ERROR (Status)) {
1066 AllChildrenStopped = FALSE;
1067 }
1068 }
1069
1070 if (!AllChildrenStopped) {
1071 return EFI_DEVICE_ERROR;
1072 }
1073
1074 return EFI_SUCCESS;
1075 }
1076
1077 /**
1078 issue ATA or ATAPI command to reset a block IO device.
1079 @param This Block IO protocol instance pointer.
1080 @param ExtendedVerification If FALSE,for ATAPI device, driver will only invoke ATAPI reset method
1081 If TRUE, for ATAPI device, driver need invoke ATA reset method after
1082 invoke ATAPI reset method
1083
1084 @retval EFI_DEVICE_ERROR When the device is neighther ATA device or ATAPI device.
1085 @retval EFI_SUCCESS The device reset successfully
1086
1087 **/
1088 EFI_STATUS
1089 EFIAPI
1090 IDEBlkIoReset (
1091 IN EFI_BLOCK_IO_PROTOCOL *This,
1092 IN BOOLEAN ExtendedVerification
1093 )
1094 {
1095 IDE_BLK_IO_DEV *IdeBlkIoDevice;
1096 EFI_STATUS Status;
1097 EFI_TPL OldTpl;
1098
1099 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1100
1101 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);
1102 //
1103 // Requery IDE IO resources in case of the switch of native and legacy modes
1104 //
1105 ReassignIdeResources (IdeBlkIoDevice);
1106
1107 //
1108 // for ATA device, using ATA reset method
1109 //
1110 if (IdeBlkIoDevice->Type == IdeHardDisk ||
1111 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
1112 Status = AtaSoftReset (IdeBlkIoDevice);
1113 goto Done;
1114 }
1115
1116 if (IdeBlkIoDevice->Type == IdeUnknown) {
1117 Status = EFI_DEVICE_ERROR;
1118 goto Done;
1119 }
1120
1121 //
1122 // for ATAPI device, using ATAPI reset method
1123 //
1124 Status = AtapiSoftReset (IdeBlkIoDevice);
1125 if (ExtendedVerification) {
1126 Status = AtaSoftReset (IdeBlkIoDevice);
1127 }
1128
1129 Done:
1130 gBS->RestoreTPL (OldTpl);
1131 return Status;
1132 }
1133
1134 /**
1135 Read data from a block IO device
1136
1137 @param This Block IO protocol instance pointer.
1138 @param MediaId The media ID of the device
1139 @param Lba Starting LBA address to read data
1140 @param BufferSize The size of data to be read
1141 @param Buffer Caller supplied buffer to save data
1142
1143 @retval EFI_DEVICE_ERROR unknown device type
1144 @retval other read data status.
1145
1146 **/
1147 EFI_STATUS
1148 EFIAPI
1149 IDEBlkIoReadBlocks (
1150 IN EFI_BLOCK_IO_PROTOCOL *This,
1151 IN UINT32 MediaId,
1152 IN EFI_LBA Lba,
1153 IN UINTN BufferSize,
1154 OUT VOID *Buffer
1155 )
1156 {
1157 IDE_BLK_IO_DEV *IdeBlkIoDevice;
1158 EFI_STATUS Status;
1159 EFI_TPL OldTpl;
1160
1161 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1162
1163 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);
1164
1165 //
1166 // Requery IDE IO resources in case of the switch of native and legacy modes
1167 //
1168 ReassignIdeResources (IdeBlkIoDevice);
1169
1170 //
1171 // For ATA compatible device, use ATA read block's mechanism
1172 //
1173 if (IdeBlkIoDevice->Type == IdeHardDisk ||
1174 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
1175 Status = AtaBlkIoReadBlocks (
1176 IdeBlkIoDevice,
1177 MediaId,
1178 Lba,
1179 BufferSize,
1180 Buffer
1181 );
1182 goto Done;
1183 }
1184
1185 if (IdeBlkIoDevice->Type == IdeUnknown) {
1186 Status = EFI_DEVICE_ERROR;
1187 goto Done;
1188 }
1189
1190 //
1191 // for ATAPI device, using ATAPI read block's mechanism
1192 //
1193 Status = AtapiBlkIoReadBlocks (
1194 IdeBlkIoDevice,
1195 MediaId,
1196 Lba,
1197 BufferSize,
1198 Buffer
1199 );
1200
1201 Done:
1202 gBS->RestoreTPL (OldTpl);
1203
1204 return Status;
1205 }
1206
1207 /**
1208 Write data to block io device.
1209
1210 @param This Protocol instance pointer.
1211 @param MediaId The media ID of the device
1212 @param Lba Starting LBA address to write data
1213 @param BufferSize The size of data to be written
1214 @param Buffer Caller supplied buffer to save data
1215
1216 @retval EFI_DEVICE_ERROR unknown device type
1217 @retval other write data status
1218
1219 **/
1220 EFI_STATUS
1221 EFIAPI
1222 IDEBlkIoWriteBlocks (
1223 IN EFI_BLOCK_IO_PROTOCOL *This,
1224 IN UINT32 MediaId,
1225 IN EFI_LBA Lba,
1226 IN UINTN BufferSize,
1227 IN VOID *Buffer
1228 )
1229 {
1230 IDE_BLK_IO_DEV *IdeBlkIoDevice;
1231 EFI_STATUS Status;
1232 EFI_TPL OldTpl;
1233
1234 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1235
1236 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);
1237 //
1238 // Requery IDE IO resources in case of the switch of native and legacy modes
1239 //
1240 ReassignIdeResources (IdeBlkIoDevice);
1241
1242 //
1243 // for ATA device, using ATA write block's mechanism
1244 //
1245 if (IdeBlkIoDevice->Type == IdeHardDisk ||
1246 IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
1247
1248 Status = AtaBlkIoWriteBlocks (
1249 IdeBlkIoDevice,
1250 MediaId,
1251 Lba,
1252 BufferSize,
1253 Buffer
1254 );
1255 goto Done;
1256 }
1257
1258 if (IdeBlkIoDevice->Type == IdeUnknown) {
1259 Status = EFI_DEVICE_ERROR;
1260 goto Done;
1261 }
1262
1263 //
1264 // for ATAPI device, using ATAPI write block's mechanism
1265 //
1266 Status = AtapiBlkIoWriteBlocks (
1267 IdeBlkIoDevice,
1268 MediaId,
1269 Lba,
1270 BufferSize,
1271 Buffer
1272 );
1273
1274 Done:
1275 gBS->RestoreTPL (OldTpl);
1276 return Status;
1277 }
1278 /**
1279 Flushes all modified data to a physical block devices
1280
1281 @param This Indicates a pointer to the calling context which to sepcify a
1282 sepcific block device
1283
1284 @retval EFI_SUCCESS Always return success.
1285 **/
1286 EFI_STATUS
1287 EFIAPI
1288 IDEBlkIoFlushBlocks (
1289 IN EFI_BLOCK_IO_PROTOCOL *This
1290 )
1291 {
1292 //
1293 // return directly
1294 //
1295 return EFI_SUCCESS;
1296 }
1297
1298 /**
1299 This function is used by the IDE bus driver to get inquiry data.
1300 Data format of Identify data is defined by the Interface GUID.
1301
1302 @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1303 @param InquiryData Pointer to a buffer for the inquiry data.
1304 @param InquiryDataSize Pointer to the value for the inquiry data size.
1305
1306 @retval EFI_SUCCESS The command was accepted without any errors.
1307 @retval EFI_NOT_FOUND Device does not support this data class
1308 @retval EFI_DEVICE_ERROR Error reading InquiryData from device
1309 @retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough
1310
1311 **/
1312 EFI_STATUS
1313 EFIAPI
1314 IDEDiskInfoInquiry (
1315 IN EFI_DISK_INFO_PROTOCOL *This,
1316 IN OUT VOID *InquiryData,
1317 IN OUT UINT32 *InquiryDataSize
1318 )
1319 {
1320 IDE_BLK_IO_DEV *IdeBlkIoDevice;
1321
1322 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);
1323
1324 if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) {
1325 *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);
1326 return EFI_BUFFER_TOO_SMALL;
1327 }
1328
1329 if (IdeBlkIoDevice->InquiryData == NULL) {
1330 return EFI_NOT_FOUND;
1331 }
1332
1333 gBS->CopyMem (InquiryData, IdeBlkIoDevice->InquiryData, sizeof (ATAPI_INQUIRY_DATA));
1334 *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);
1335
1336 return EFI_SUCCESS;
1337 }
1338
1339 /**
1340 This function is used by the IDE bus driver to get identify data.
1341 Data format of Identify data is defined by the Interface GUID.
1342
1343 @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1344 @param IdentifyData Pointer to a buffer for the identify data.
1345 @param IdentifyDataSize Pointer to the value for the identify data size.
1346
1347 @retval EFI_SUCCESS The command was accepted without any errors.
1348 @retval EFI_NOT_FOUND Device does not support this data class
1349 @retval EFI_DEVICE_ERROR Error reading IdentifyData from device
1350 @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough
1351
1352 **/
1353 EFI_STATUS
1354 EFIAPI
1355 IDEDiskInfoIdentify (
1356 IN EFI_DISK_INFO_PROTOCOL *This,
1357 IN OUT VOID *IdentifyData,
1358 IN OUT UINT32 *IdentifyDataSize
1359 )
1360 {
1361 IDE_BLK_IO_DEV *IdeBlkIoDevice;
1362
1363 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);
1364
1365 if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {
1366 *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);
1367 return EFI_BUFFER_TOO_SMALL;
1368 }
1369
1370 if (IdeBlkIoDevice->IdData == NULL) {
1371 return EFI_NOT_FOUND;
1372 }
1373
1374 gBS->CopyMem (IdentifyData, IdeBlkIoDevice->IdData, sizeof (EFI_IDENTIFY_DATA));
1375 *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);
1376
1377 return EFI_SUCCESS;
1378 }
1379
1380 /**
1381 This function is used by the IDE bus driver to get sense data.
1382 Data format of Sense data is defined by the Interface GUID.
1383
1384 @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1385 @param SenseData Pointer to the SenseData.
1386 @param SenseDataSize Size of SenseData in bytes.
1387 @param SenseDataNumber Pointer to the value for the identify data size.
1388
1389 @retval EFI_SUCCESS The command was accepted without any errors.
1390 @retval EFI_NOT_FOUND Device does not support this data class
1391 @retval EFI_DEVICE_ERROR Error reading InquiryData from device
1392 @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough
1393
1394 **/
1395 EFI_STATUS
1396 EFIAPI
1397 IDEDiskInfoSenseData (
1398 IN EFI_DISK_INFO_PROTOCOL *This,
1399 IN OUT VOID *SenseData,
1400 IN OUT UINT32 *SenseDataSize,
1401 OUT UINT8 *SenseDataNumber
1402 )
1403 {
1404 return EFI_NOT_FOUND;
1405 }
1406
1407 /**
1408 This function is used by the IDE bus driver to get controller information.
1409
1410 @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
1411 @param IdeChannel Pointer to the Ide Channel number. Primary or secondary.
1412 @param IdeDevice Pointer to the Ide Device number. Master or slave.
1413
1414 @retval EFI_SUCCESS IdeChannel and IdeDevice are valid
1415 @retval EFI_UNSUPPORTED This is not an IDE device
1416
1417 **/
1418 EFI_STATUS
1419 EFIAPI
1420 IDEDiskInfoWhichIde (
1421 IN EFI_DISK_INFO_PROTOCOL *This,
1422 OUT UINT32 *IdeChannel,
1423 OUT UINT32 *IdeDevice
1424 )
1425 {
1426 IDE_BLK_IO_DEV *IdeBlkIoDevice;
1427
1428 IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);
1429 *IdeChannel = IdeBlkIoDevice->Channel;
1430 *IdeDevice = IdeBlkIoDevice->Device;
1431
1432 return EFI_SUCCESS;
1433 }
1434
1435 /**
1436 The is an event(generally the event is exitBootService event) call back function.
1437 Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.
1438
1439 @param Event Pointer to this event
1440 @param Context Event hanlder private data
1441
1442 **/
1443 VOID
1444 EFIAPI
1445 ClearInterrupt (
1446 IN EFI_EVENT Event,
1447 IN VOID *Context
1448 )
1449 {
1450 EFI_STATUS Status;
1451 UINT64 IoPortForBmis;
1452 UINT8 RegisterValue;
1453 IDE_BLK_IO_DEV *IdeDev;
1454
1455 //
1456 // Get our context
1457 //
1458 IdeDev = (IDE_BLK_IO_DEV *) Context;
1459
1460 //
1461 // Obtain IDE IO port registers' base addresses
1462 //
1463 Status = ReassignIdeResources (IdeDev);
1464 if (EFI_ERROR (Status)) {
1465 return;
1466 }
1467
1468 //
1469 // Check whether interrupt is pending
1470 //
1471
1472 //
1473 // Reset IDE device to force it de-assert interrupt pin
1474 // Note: this will reset all devices on this IDE channel
1475 //
1476 Status = AtaSoftReset (IdeDev);
1477 if (EFI_ERROR (Status)) {
1478 return;
1479 }
1480
1481 //
1482 // Get base address of IDE Bus Master Status Regsiter
1483 //
1484 if (IdePrimary == IdeDev->Channel) {
1485 IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
1486 } else {
1487 if (IdeSecondary == IdeDev->Channel) {
1488 IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;
1489 } else {
1490 return;
1491 }
1492 }
1493 //
1494 // Read BMIS register and clear ERROR and INTR bit
1495 //
1496 IdeDev->PciIo->Io.Read (
1497 IdeDev->PciIo,
1498 EfiPciIoWidthUint8,
1499 EFI_PCI_IO_PASS_THROUGH_BAR,
1500 IoPortForBmis,
1501 1,
1502 &RegisterValue
1503 );
1504
1505 RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
1506
1507 IdeDev->PciIo->Io.Write (
1508 IdeDev->PciIo,
1509 EfiPciIoWidthUint8,
1510 EFI_PCI_IO_PASS_THROUGH_BAR,
1511 IoPortForBmis,
1512 1,
1513 &RegisterValue
1514 );
1515
1516 //
1517 // Select the other device on this channel to ensure this device to release the interrupt pin
1518 //
1519 if (IdeDev->Device == 0) {
1520 RegisterValue = (1 << 4) | 0xe0;
1521 } else {
1522 RegisterValue = (0 << 4) | 0xe0;
1523 }
1524 IDEWritePortB (
1525 IdeDev->PciIo,
1526 IdeDev->IoPort->Head,
1527 RegisterValue
1528 );
1529
1530 }
1531
1532 /**
1533 The user Entry Point for module IdeBus. The user code starts with this function.
1534
1535 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1536 @param[in] SystemTable A pointer to the EFI System Table.
1537
1538 @retval EFI_SUCCESS The entry point is executed successfully.
1539 @retval other Some error occurs when executing this entry point.
1540
1541 **/
1542 EFI_STATUS
1543 EFIAPI
1544 InitializeIdeBus(
1545 IN EFI_HANDLE ImageHandle,
1546 IN EFI_SYSTEM_TABLE *SystemTable
1547 )
1548 {
1549 EFI_STATUS Status;
1550
1551 //
1552 // Install driver model protocol(s).
1553 //
1554 Status = EfiLibInstallAllDriverProtocols2 (
1555 ImageHandle,
1556 SystemTable,
1557 &gIDEBusDriverBinding,
1558 ImageHandle,
1559 &gIDEBusComponentName,
1560 &gIDEBusComponentName2,
1561 NULL,
1562 NULL,
1563 &gIDEBusDriverDiagnostics,
1564 &gIDEBusDriverDiagnostics2
1565 );
1566 ASSERT_EFI_ERROR (Status);
1567
1568 return Status;
1569 }