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