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