1 /** @file
2
3 The definition for SD media device driver model and blkio protocol routines.
4
5 Copyright (c) 2013-2016 Intel Corporation.
6
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17
18 #include "SDMediaDevice.h"
19
20
21 EFI_DRIVER_BINDING_PROTOCOL gSDMediaDeviceDriverBinding = {
22 SDMediaDeviceSupported,
23 SDMediaDeviceStart,
24 SDMediaDeviceStop,
25 0x20,
26 NULL,
27 NULL
28 };
29
30 /**
31 Entry point for EFI drivers.
32
33 @param ImageHandle EFI_HANDLE.
34 @param SystemTable EFI_SYSTEM_TABLE.
35
36 @retval EFI_SUCCESS Driver is successfully loaded.
37 @return Others Failed.
38
39 **/
40 EFI_STATUS
41 EFIAPI
InitializeSDMediaDevice(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)42 InitializeSDMediaDevice (
43 IN EFI_HANDLE ImageHandle,
44 IN EFI_SYSTEM_TABLE *SystemTable
45 )
46 {
47 return EfiLibInstallDriverBindingComponentName2 (
48 ImageHandle,
49 SystemTable,
50 &gSDMediaDeviceDriverBinding,
51 ImageHandle,
52 &gSDMediaDeviceName,
53 &gSDMediaDeviceName2
54 );
55 }
56
57
58 /**
59 Test to see if this driver supports ControllerHandle. Any
60 ControllerHandle that has BlockIoProtocol installed will be supported.
61
62 @param This Protocol instance pointer.
63 @param Controller Handle of device to test.
64 @param RemainingDevicePath Not used.
65
66 @return EFI_SUCCESS This driver supports this device.
67 @return EFI_UNSUPPORTED This driver does not support this device.
68
69 **/
70 EFI_STATUS
71 EFIAPI
SDMediaDeviceSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)72 SDMediaDeviceSupported (
73 IN EFI_DRIVER_BINDING_PROTOCOL *This,
74 IN EFI_HANDLE Controller,
75 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
76 )
77 {
78 EFI_STATUS Status;
79 EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
80
81 //
82 // Test whether there is PCI IO Protocol attached on the controller handle.
83 //
84 Status = gBS->OpenProtocol (
85 Controller,
86 &gEfiSDHostIoProtocolGuid,
87 (VOID **)&SDHostIo,
88 This->DriverBindingHandle,
89 Controller,
90 EFI_OPEN_PROTOCOL_BY_DRIVER
91 );
92 if (EFI_ERROR (Status)) {
93 goto Exit;
94 }
95
96 gBS->CloseProtocol (
97 Controller,
98 &gEfiSDHostIoProtocolGuid,
99 This->DriverBindingHandle,
100 Controller
101 );
102
103 Exit:
104 return Status;
105 }
106
107 /**
108 Starting the SD Media Device Driver.
109
110 @param This Protocol instance pointer.
111 @param Controller Handle of device to test.
112 @param RemainingDevicePath Not used.
113
114 @retval EFI_SUCCESS This driver supports this device.
115 @retval EFI_UNSUPPORTED This driver does not support this device.
116 @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
117 EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
118
119 **/
120 EFI_STATUS
121 EFIAPI
SDMediaDeviceStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)122 SDMediaDeviceStart (
123 IN EFI_DRIVER_BINDING_PROTOCOL *This,
124 IN EFI_HANDLE Controller,
125 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
126 )
127 {
128 EFI_STATUS Status;
129 EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
130 CARD_DATA *CardData;
131
132 CardData = NULL;
133
134 //
135 // Open PCI I/O Protocol and save pointer to open protocol
136 // in private data area.
137 //
138 Status = gBS->OpenProtocol (
139 Controller,
140 &gEfiSDHostIoProtocolGuid,
141 (VOID **) &SDHostIo,
142 This->DriverBindingHandle,
143 Controller,
144 EFI_OPEN_PROTOCOL_BY_DRIVER
145 );
146 if (EFI_ERROR (Status)) {
147 DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to open gEfiSDHostIoProtocolGuid \r\n"));
148 goto Exit;
149 }
150
151 Status = SDHostIo->DetectCardAndInitHost (SDHostIo);
152 if (EFI_ERROR (Status)) {
153 DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: Fail to DetectCardAndInitHost \r\n"));
154 goto Exit;
155 }
156
157 CardData = (CARD_DATA*)AllocateZeroPool(sizeof (CARD_DATA));
158 if (CardData == NULL) {
159 Status = EFI_OUT_OF_RESOURCES;
160 DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to AllocateZeroPool(CARD_DATA) \r\n"));
161 goto Exit;
162 }
163
164 ASSERT (SDHostIo->HostCapability.BoundarySize >= 4 * 1024);
165 CardData->RawBufferPointer = (UINT8*)((UINTN)DMA_MEMORY_TOP);
166 Status = gBS->AllocatePages (
167 AllocateMaxAddress,
168 EfiBootServicesData,
169 EFI_SIZE_TO_PAGES (2 * SDHostIo->HostCapability.BoundarySize),
170 (EFI_PHYSICAL_ADDRESS *)(&CardData->RawBufferPointer)
171 );
172
173 if (CardData->RawBufferPointer == NULL) {
174 DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to AllocateZeroPool(2*x) \r\n"));
175 Status = EFI_OUT_OF_RESOURCES;
176 goto Exit;
177 }
178 CardData->AlignedBuffer = CardData->RawBufferPointer - ((UINTN)(CardData->RawBufferPointer) & (SDHostIo->HostCapability.BoundarySize - 1)) + SDHostIo->HostCapability.BoundarySize;
179
180 CardData->Signature = CARD_DATA_SIGNATURE;
181 CardData->SDHostIo = SDHostIo;
182
183 Status = MMCSDCardInit (CardData);
184 if (EFI_ERROR (Status)) {
185 DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to MMCSDCardInit \r\n"));
186 goto Exit;
187 }
188 DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: MMCSDCardInit SuccessFul\n"));
189
190 if (CardData->CardType == CEATACard) {
191 Status = CEATABlockIoInit (CardData);
192 } else {
193 Status = MMCSDBlockIoInit (CardData);
194 }
195
196 if (EFI_ERROR (Status)) {
197 DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to BlockIoInit \r\n"));
198 goto Exit;
199 }
200 DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: BlockIo is successfully installed\n"));
201
202
203 Status = gBS->InstallProtocolInterface (
204 &Controller,
205 &gEfiBlockIoProtocolGuid,
206 EFI_NATIVE_INTERFACE,
207 &CardData->BlockIo
208 );
209 if (EFI_ERROR (Status)) {
210 DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to install gEfiBlockIoProtocolGuid \r\n"));
211 goto Exit;
212 }
213
214 //
215 // Install the component name protocol
216 //
217 CardData->ControllerNameTable = NULL;
218
219 AddUnicodeString2 (
220 "eng",
221 gSDMediaDeviceName.SupportedLanguages,
222 &CardData->ControllerNameTable,
223 L"MMC/SD Media Device",
224 TRUE
225 );
226 AddUnicodeString2 (
227 "en",
228 gSDMediaDeviceName2.SupportedLanguages,
229 &CardData->ControllerNameTable,
230 L"MMC/SD Media Device",
231 FALSE
232 );
233
234 Exit:
235 if (EFI_ERROR (Status)) {
236 DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: End with failure\r\n"));
237 if (CardData != NULL) {
238 if (CardData->RawBufferPointer != NULL) {
239 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) CardData->RawBufferPointer, EFI_SIZE_TO_PAGES (2 * SDHostIo->HostCapability.BoundarySize));
240 }
241 FreePool (CardData);
242 }
243 }
244
245 return Status;
246 }
247
248
249 /**
250 Stop this driver on ControllerHandle. Support stopping any child handles
251 created by this driver.
252
253 @param This Protocol instance pointer.
254 @param Controller Handle of device to stop driver on.
255 @param NumberOfChildren Number of Children in the ChildHandleBuffer.
256 @param ChildHandleBuffer List of handles for the children we need to stop.
257
258 @return EFI_SUCCESS
259 @return others
260
261 **/
262 EFI_STATUS
263 EFIAPI
SDMediaDeviceStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)264 SDMediaDeviceStop (
265 IN EFI_DRIVER_BINDING_PROTOCOL *This,
266 IN EFI_HANDLE Controller,
267 IN UINTN NumberOfChildren,
268 IN EFI_HANDLE *ChildHandleBuffer
269 )
270 {
271 EFI_STATUS Status;
272 CARD_DATA *CardData;
273 EFI_BLOCK_IO_PROTOCOL *BlockIo;
274
275 //
276 // First find BlockIo Protocol
277 //
278 Status = gBS->OpenProtocol (
279 Controller,
280 &gEfiBlockIoProtocolGuid,
281 (VOID **)&BlockIo,
282 This->DriverBindingHandle,
283 Controller,
284 EFI_OPEN_PROTOCOL_GET_PROTOCOL
285 );
286 if (EFI_ERROR (Status)) {
287 return Status;
288 }
289
290 CardData = CARD_DATA_FROM_THIS(BlockIo);
291
292 //
293 // Uninstall Block I/O protocol from the device handle
294 //
295 Status = gBS->UninstallProtocolInterface (
296 Controller,
297 &gEfiBlockIoProtocolGuid,
298 BlockIo
299 );
300 if (EFI_ERROR (Status)) {
301 return Status;
302 }
303
304 if (CardData != NULL) {
305 if (CardData->RawBufferPointer != NULL) {
306 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) CardData->RawBufferPointer, EFI_SIZE_TO_PAGES (2 * CardData->SDHostIo->HostCapability.BoundarySize));
307 }
308 FreeUnicodeStringTable (CardData->ControllerNameTable);
309 FreePool (CardData);
310 }
311
312 gBS->CloseProtocol (
313 Controller,
314 &gEfiSDHostIoProtocolGuid,
315 This->DriverBindingHandle,
316 Controller
317 );
318
319 return EFI_SUCCESS;
320 }
321
322
323
324