]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.c
MdeModulePkg/NonDiscoverablePciDev: Fix type mismatch in switch/case
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / NonDiscoverablePciDeviceDxe / NonDiscoverablePciDeviceDxe.c
CommitLineData
a42e6d44
AB
1/** @file\r
2\r
3 Copyright (C) 2016, Linaro Ltd. All rights reserved.<BR>\r
4\r
5 This program and the accompanying materials are licensed and made available\r
6 under the terms and conditions of the BSD License which accompanies this\r
7 distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
11 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "NonDiscoverablePciDeviceIo.h"\r
16\r
17#include <Protocol/DriverBinding.h>\r
18\r
19//\r
20// We only support the following device types\r
21//\r
22STATIC\r
23CONST EFI_GUID * CONST\r
24SupportedNonDiscoverableDevices [] = {\r
25 &gEdkiiNonDiscoverableAhciDeviceGuid,\r
26 &gEdkiiNonDiscoverableEhciDeviceGuid,\r
27 &gEdkiiNonDiscoverableNvmeDeviceGuid,\r
28 &gEdkiiNonDiscoverableOhciDeviceGuid,\r
29 &gEdkiiNonDiscoverableSdhciDeviceGuid,\r
30 &gEdkiiNonDiscoverableUfsDeviceGuid,\r
31 &gEdkiiNonDiscoverableUhciDeviceGuid,\r
32 &gEdkiiNonDiscoverableXhciDeviceGuid,\r
33};\r
34\r
35//\r
36// Probe, start and stop functions of this driver, called by the DXE core for\r
37// specific devices.\r
38//\r
39// The following specifications document these interfaces:\r
40// - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol\r
41// - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol\r
42//\r
43// The implementation follows:\r
44// - Driver Writer's Guide for UEFI 2.3.1 v1.01\r
45// - 5.1.3.4 OpenProtocol() and CloseProtocol()\r
46// - UEFI Spec 2.3.1 + Errata C\r
47// - 6.3 Protocol Handler Services\r
48//\r
49\r
50STATIC\r
51EFI_STATUS\r
52EFIAPI\r
53NonDiscoverablePciDeviceSupported (\r
54 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
55 IN EFI_HANDLE DeviceHandle,\r
56 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
57 )\r
58{\r
59 NON_DISCOVERABLE_DEVICE *Device;\r
60 EFI_STATUS Status;\r
61 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc;\r
62 INTN Idx;\r
63\r
64 Status = gBS->OpenProtocol (DeviceHandle,\r
65 &gEdkiiNonDiscoverableDeviceProtocolGuid, (VOID **)&Device,\r
66 This->DriverBindingHandle, DeviceHandle,\r
67 EFI_OPEN_PROTOCOL_BY_DRIVER);\r
68 if (EFI_ERROR (Status)) {\r
69 return Status;\r
70 }\r
71\r
72 //\r
73 // Restricted to DMA coherent for now\r
74 //\r
75 Status = EFI_UNSUPPORTED;\r
76 if (Device->DmaType != NonDiscoverableDeviceDmaTypeCoherent) {\r
77 goto CloseProtocol;\r
78 }\r
79\r
80 for (Idx = 0; Idx < ARRAY_SIZE (SupportedNonDiscoverableDevices); Idx++) {\r
81 if (CompareGuid (Device->Type, SupportedNonDiscoverableDevices [Idx])) {\r
82 Status = EFI_SUCCESS;\r
83 break;\r
84 }\r
85 }\r
86\r
87 if (EFI_ERROR (Status)) {\r
88 goto CloseProtocol;\r
89 }\r
90\r
91 //\r
92 // We only support MMIO devices, so iterate over the resources to ensure\r
93 // that they only describe things that we can handle\r
94 //\r
95 for (Desc = Device->Resources; Desc->Desc != ACPI_END_TAG_DESCRIPTOR;\r
96 Desc = (VOID *)((UINT8 *)Desc + Desc->Len + 3)) {\r
97 if (Desc->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR ||\r
98 Desc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
99 Status = EFI_UNSUPPORTED;\r
100 break;\r
101 }\r
102 }\r
103\r
104CloseProtocol:\r
105 gBS->CloseProtocol (DeviceHandle, &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
106 This->DriverBindingHandle, DeviceHandle);\r
107\r
108 return Status;\r
109}\r
110\r
111STATIC\r
112EFI_STATUS\r
113EFIAPI\r
114NonDiscoverablePciDeviceStart (\r
115 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
116 IN EFI_HANDLE DeviceHandle,\r
117 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
118 )\r
119{\r
120 NON_DISCOVERABLE_PCI_DEVICE *Dev;\r
121 EFI_STATUS Status;\r
122\r
123 Dev = AllocateZeroPool (sizeof *Dev);\r
124 if (Dev == NULL) {\r
125 return EFI_OUT_OF_RESOURCES;\r
126 }\r
127\r
128 Status = gBS->OpenProtocol (DeviceHandle,\r
129 &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
130 (VOID **)&Dev->Device, This->DriverBindingHandle,\r
131 DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);\r
132 if (EFI_ERROR (Status)) {\r
133 goto FreeDev;\r
134 }\r
135\r
136 InitializePciIoProtocol (Dev);\r
137\r
138 //\r
139 // Setup complete, attempt to export the driver instance's\r
140 // EFI_PCI_IO_PROTOCOL interface.\r
141 //\r
142 Dev->Signature = NON_DISCOVERABLE_PCI_DEVICE_SIG;\r
143 Status = gBS->InstallProtocolInterface (&DeviceHandle, &gEfiPciIoProtocolGuid,\r
144 EFI_NATIVE_INTERFACE, &Dev->PciIo);\r
145 if (EFI_ERROR (Status)) {\r
146 goto CloseProtocol;\r
147 }\r
148\r
149 return EFI_SUCCESS;\r
150\r
151CloseProtocol:\r
152 gBS->CloseProtocol (DeviceHandle, &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
153 This->DriverBindingHandle, DeviceHandle);\r
154\r
155FreeDev:\r
156 FreePool (Dev);\r
157\r
158 return Status;\r
159}\r
160\r
161\r
162STATIC\r
163EFI_STATUS\r
164EFIAPI\r
165NonDiscoverablePciDeviceStop (\r
166 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
167 IN EFI_HANDLE DeviceHandle,\r
168 IN UINTN NumberOfChildren,\r
169 IN EFI_HANDLE *ChildHandleBuffer\r
170 )\r
171{\r
172 EFI_STATUS Status;\r
173 EFI_PCI_IO_PROTOCOL *PciIo;\r
174 NON_DISCOVERABLE_PCI_DEVICE *Dev;\r
175\r
176 Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,\r
177 (VOID **)&PciIo, This->DriverBindingHandle, DeviceHandle,\r
178 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
179 if (EFI_ERROR (Status)) {\r
180 return Status;\r
181 }\r
182\r
183 Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (PciIo);\r
184\r
185 //\r
186 // Handle Stop() requests for in-use driver instances gracefully.\r
187 //\r
188 Status = gBS->UninstallProtocolInterface (DeviceHandle,\r
189 &gEfiPciIoProtocolGuid, &Dev->PciIo);\r
190 if (EFI_ERROR (Status)) {\r
191 return Status;\r
192 }\r
193\r
194 gBS->CloseProtocol (DeviceHandle, &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
195 This->DriverBindingHandle, DeviceHandle);\r
196\r
197 FreePool (Dev);\r
198\r
199 return EFI_SUCCESS;\r
200}\r
201\r
202\r
203//\r
204// The static object that groups the Supported() (ie. probe), Start() and\r
205// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata\r
206// C, 10.1 EFI Driver Binding Protocol.\r
207//\r
208STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {\r
209 &NonDiscoverablePciDeviceSupported,\r
210 &NonDiscoverablePciDeviceStart,\r
211 &NonDiscoverablePciDeviceStop,\r
212 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers\r
213 NULL,\r
214 NULL\r
215};\r
216\r
217//\r
218// Entry point of this driver.\r
219//\r
220EFI_STATUS\r
221EFIAPI\r
222NonDiscoverablePciDeviceDxeEntryPoint (\r
223 IN EFI_HANDLE ImageHandle,\r
224 IN EFI_SYSTEM_TABLE *SystemTable\r
225 )\r
226{\r
227 return EfiLibInstallDriverBindingComponentName2 (\r
228 ImageHandle,\r
229 SystemTable,\r
230 &gDriverBinding,\r
231 ImageHandle,\r
232 &gComponentName,\r
233 &gComponentName2\r
234 );\r
235}\r