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