]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c
QuarkSocPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / QuarkSocPkg / QuarkSouthCluster / Sdio / Dxe / SDMediaDeviceDxe / CEATABlockIo.c
CommitLineData
9b6bbcdb
MK
1/** @file\r
2\r
3Block I/O protocol for CE-ATA device\r
4\r
5Copyright (c) 2013-2015 Intel Corporation.\r
6\r
c9f231d0 7SPDX-License-Identifier: BSD-2-Clause-Patent\r
9b6bbcdb
MK
8\r
9**/\r
10\r
11#include "SDMediaDevice.h"\r
12\r
13/**\r
14 Implements EFI_BLOCK_IO_PROTOCOL.Reset() function.\r
15\r
16 @param This The EFI_BLOCK_IO_PROTOCOL instance.\r
17 @param ExtendedVerification Indicates that the driver may perform a more exhaustive.\r
18 verification operation of the device during reset.\r
19 (This parameter is ingored in this driver.)\r
20\r
21 @retval EFI_SUCCESS Success\r
22**/\r
23EFI_STATUS\r
24EFIAPI\r
25CEATABlockReset (\r
26 IN EFI_BLOCK_IO_PROTOCOL *This,\r
27 IN BOOLEAN ExtendedVerification\r
28 )\r
29{\r
30 EFI_STATUS Status;\r
31 CARD_DATA *CardData;\r
32 EFI_SD_HOST_IO_PROTOCOL *SDHostIo;\r
33\r
34 CardData = CARD_DATA_FROM_THIS(This);\r
35 SDHostIo = CardData->SDHostIo;\r
36\r
37 if (!ExtendedVerification) {\r
38 Status = SoftwareReset (CardData);\r
39 } else {\r
40 Status = SDHostIo->ResetSDHost (SDHostIo, Reset_DAT_CMD);\r
41 if (EFI_ERROR (Status)) {\r
42 DEBUG((EFI_D_ERROR, "CEATABlockReset: Fail to ResetSDHost\n" ));\r
43 return Status;\r
44 }\r
45 Status = MMCSDCardInit (CardData);\r
46 }\r
47\r
48\r
49 return Status;\r
50\r
51 }\r
52\r
53/**\r
54 Implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks() function.\r
55\r
56 @param This The EFI_BLOCK_IO_PROTOCOL instance.\r
57 @param MediaId The media id that the write request is for.\r
58 @param LBA The starting logical block address to read from on the device.\r
59 The caller is responsible for writing to only legitimate locations.\r
60 @param BufferSize The size of the Buffer in bytes. This must be a multiple of the\r
61 intrinsic block size of the device.\r
62 @param Buffer A pointer to the destination buffer for the data. The caller\r
63 is responsible for either having implicit or explicit ownership\r
64 of the buffer.\r
65\r
66 @retval EFI_SUCCESS Success\r
67 @retval EFI_DEVICE_ERROR Hardware Error\r
68 @retval EFI_INVALID_PARAMETER Parameter is error\r
69 @retval EFI_NO_MEDIA No media\r
70 @retval EFI_MEDIA_CHANGED Media Change\r
71 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
72**/\r
73EFI_STATUS\r
74EFIAPI\r
75CEATABlockReadBlocks (\r
76 IN EFI_BLOCK_IO_PROTOCOL *This,\r
77 IN UINT32 MediaId,\r
78 IN EFI_LBA LBA,\r
79 IN UINTN BufferSize,\r
80 OUT VOID *Buffer\r
81 )\r
82{\r
83 EFI_STATUS Status;\r
84 CARD_DATA *CardData;\r
85 UINT32 TransferSize;\r
86 UINT8 *pBuf;\r
87 UINT32 Index;\r
88 UINT64 Address;\r
89 UINT32 Remainder;\r
90 UINT64 CEATALBA;\r
91 UINT32 BoundarySize;\r
92\r
93 Status = EFI_SUCCESS;\r
94 CardData = CARD_DATA_FROM_THIS(This);\r
95 pBuf = Buffer;\r
96 Index = 0;\r
97 Address = MultU64x32(LBA, CardData->BlockIoMedia.BlockSize);\r
98 BoundarySize = CardData->SDHostIo->HostCapability.BoundarySize;\r
99\r
100 if (!Buffer) {\r
101 Status = EFI_INVALID_PARAMETER;\r
102 DEBUG((EFI_D_ERROR, "CEATABlockReadBlocks:Invalid parameter\n" ));\r
103 goto Exit;\r
104 }\r
105\r
106 if (MediaId != CardData->BlockIoMedia.MediaId) {\r
107 Status = EFI_MEDIA_CHANGED;\r
108 DEBUG((EFI_D_ERROR, "CEATABlockReadBlocks:Media changed\n" ));\r
109 goto Exit;\r
110 }\r
111\r
112 if ((BufferSize % CardData->BlockIoMedia.BlockSize) != 0) {\r
113 Status = EFI_BAD_BUFFER_SIZE;\r
114 DEBUG((EFI_D_ERROR, "CEATABlockReadBlocks:Bad buffer size\n" ));\r
115 goto Exit;\r
116 }\r
117\r
118 if (BufferSize == 0) {\r
119 Status = EFI_SUCCESS;\r
120 goto Exit;\r
121 }\r
122\r
123 if ((Address + BufferSize) > MultU64x32 (CardData->BlockIoMedia.LastBlock + 1, CardData->BlockIoMedia.BlockSize)) {\r
124 Status = EFI_INVALID_PARAMETER;\r
125 DEBUG((EFI_D_ERROR, "CEATABlockReadBlocks:Invalid parameter\n" ));\r
126 goto Exit;\r
127 }\r
128\r
129\r
130 do {\r
131 if (BufferSize < BoundarySize) {\r
132 TransferSize = (UINT32)BufferSize;\r
133 } else {\r
134 TransferSize = BoundarySize;\r
135 }\r
136\r
137 Address += Index * TransferSize;\r
138 CEATALBA = DivU64x32Remainder (Address, DATA_UNIT_SIZE, &Remainder);\r
139 ASSERT(Remainder == 0);\r
140\r
141 Status = ReadDMAExt (\r
142 CardData,\r
143 CEATALBA,\r
144 pBuf,\r
145 (UINT16)(TransferSize / DATA_UNIT_SIZE)\r
146 );\r
147 if (EFI_ERROR (Status)) {\r
148 DEBUG((EFI_D_ERROR, "Read Failed at 0x%x, Index %d, Size 0x%x\n", Address, Index, TransferSize));\r
149 This->Reset (This, TRUE);\r
150 goto Exit;\r
151 }\r
152 BufferSize -= TransferSize;\r
153 pBuf += TransferSize;\r
154 Index ++;\r
155 } while (BufferSize != 0);\r
156\r
157\r
158Exit:\r
159 return Status;\r
160}\r
161\r
162/**\r
163 Implements EFI_BLOCK_IO_PROTOCOL.WriteBlocks() function.\r
164\r
165 @param This The EFI_BLOCK_IO_PROTOCOL instance.\r
166 @param MediaId The media id that the write request is for.\r
167 @param LBA The starting logical block address to read from on the device.\r
168 The caller is responsible for writing to only legitimate locations.\r
169 @param BufferSize The size of the Buffer in bytes. This must be a multiple of the\r
170 intrinsic block size of the device.\r
171 @param Buffer A pointer to the destination buffer for the data. The caller\r
172 is responsible for either having implicit or explicit ownership\r
173 of the buffer.\r
174\r
175 @retval EFI_SUCCESS Success\r
176 @retval EFI_DEVICE_ERROR Hardware Error\r
177 @retval EFI_INVALID_PARAMETER Parameter is error\r
178 @retval EFI_NO_MEDIA No media\r
179 @retval EFI_MEDIA_CHANGED Media Change\r
180 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
181**/\r
182EFI_STATUS\r
183EFIAPI\r
184CEATABlockWriteBlocks (\r
185 IN EFI_BLOCK_IO_PROTOCOL *This,\r
186 IN UINT32 MediaId,\r
187 IN EFI_LBA LBA,\r
188 IN UINTN BufferSize,\r
189 IN VOID *Buffer\r
190 )\r
191{\r
192 EFI_STATUS Status;\r
193 CARD_DATA *CardData;\r
194 UINT32 TransferSize;\r
195 UINT8 *pBuf;\r
196 UINT32 Index;\r
197 UINT64 Address;\r
198 UINT32 Remainder;\r
199 UINT64 CEATALBA;\r
200 UINT32 BoundarySize;\r
201\r
202\r
203 Status = EFI_SUCCESS;\r
204 CardData = CARD_DATA_FROM_THIS(This);\r
205 pBuf = Buffer;\r
206 Index = 0;\r
207 Address = MultU64x32(LBA, CardData->BlockIoMedia.BlockSize);\r
208 BoundarySize = CardData->SDHostIo->HostCapability.BoundarySize;\r
209\r
210\r
211 if (!Buffer) {\r
212 Status = EFI_INVALID_PARAMETER;\r
213 goto Exit;\r
214 }\r
215\r
216 if (MediaId != CardData->BlockIoMedia.MediaId) {\r
217 Status = EFI_MEDIA_CHANGED;\r
218 goto Exit;\r
219 }\r
220\r
221 if ((BufferSize % CardData->BlockIoMedia.BlockSize) != 0) {\r
222 Status = EFI_BAD_BUFFER_SIZE;\r
223 goto Exit;\r
224 }\r
225\r
226 if (BufferSize == 0) {\r
227 Status = EFI_SUCCESS;\r
228 goto Exit;\r
229 }\r
230\r
231 if (CardData->BlockIoMedia.ReadOnly) {\r
232 Status = EFI_WRITE_PROTECTED;\r
233 goto Exit;\r
234 }\r
235\r
236 if ((Address + BufferSize) > MultU64x32 (CardData->BlockIoMedia.LastBlock + 1, CardData->BlockIoMedia.BlockSize)) {\r
237 Status = EFI_INVALID_PARAMETER;\r
238 goto Exit;\r
239 }\r
240\r
241 CardData->NeedFlush = TRUE;\r
242\r
243 do {\r
244 if (BufferSize < BoundarySize) {\r
245 TransferSize = (UINT32)BufferSize;\r
246 } else {\r
247 TransferSize = BoundarySize;\r
248 }\r
249\r
250 Address += Index * TransferSize;\r
251 CEATALBA = DivU64x32Remainder (Address, DATA_UNIT_SIZE, &Remainder);\r
252 ASSERT(Remainder == 0);\r
253\r
254 Status = WriteDMAExt (\r
255 CardData,\r
256 CEATALBA,\r
257 pBuf,\r
258 (UINT16)(TransferSize / DATA_UNIT_SIZE)\r
259 );\r
260 if (EFI_ERROR (Status)) {\r
261 DEBUG((EFI_D_ERROR, "Write Failed at 0x%x, Index %d, Size 0x%x\n", Address, Index, TransferSize));\r
262 This->Reset (This, TRUE);\r
263 goto Exit;\r
264 }\r
265 BufferSize -= TransferSize;\r
266 pBuf += TransferSize;\r
267 Index ++;\r
268 } while (BufferSize != 0);\r
269\r
270\r
271Exit:\r
272 return Status;\r
273}\r
274\r
275/**\r
276 Implements EFI_BLOCK_IO_PROTOCOL.FlushBlocks() function.\r
277 (In this driver, this function just returns EFI_SUCCESS.)\r
278\r
279 @param This The EFI_BLOCK_IO_PROTOCOL instance.\r
280\r
281 @retval EFI_SUCCESS\r
282 @retval Others\r
283**/\r
284EFI_STATUS\r
285EFIAPI\r
286CEATABlockFlushBlocks (\r
287 IN EFI_BLOCK_IO_PROTOCOL *This\r
288 )\r
289{\r
290\r
9b6bbcdb
MK
291 CARD_DATA *CardData;\r
292\r
293 CardData = CARD_DATA_FROM_THIS(This);\r
294\r
295 if (CardData->NeedFlush) {\r
296 CardData->NeedFlush = FALSE;\r
f87c0b5e 297 FlushCache (CardData);\r
9b6bbcdb
MK
298 }\r
299\r
300 return EFI_SUCCESS;\r
301}\r
302\r
303\r
304/**\r
305 CEATA card BlockIo init function.\r
306\r
307 @param CardData Pointer to CARD_DATA.\r
308\r
309 @retval EFI_SUCCESS\r
310 @retval Others\r
311**/\r
312EFI_STATUS\r
313CEATABlockIoInit (\r
314 IN CARD_DATA *CardData\r
315 )\r
316/*++\r
317\r
318 Routine Description:\r
319 CEATA card BlockIo init function\r
320\r
321 Arguments:\r
322 CardData - Pointer to CARD_DATA\r
323\r
324 Returns:\r
325 EFI_SUCCESS - Success\r
326--*/\r
327{\r
328 EFI_STATUS Status;\r
329 UINT64 MaxSize;\r
330 UINT32 Remainder;\r
331 //\r
332 //BlockIO protocol\r
333 //\r
334 CardData->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;\r
335 CardData->BlockIo.Media = &(CardData->BlockIoMedia);\r
336 CardData->BlockIo.Reset = CEATABlockReset;\r
337 CardData->BlockIo.ReadBlocks = CEATABlockReadBlocks ;\r
338 CardData->BlockIo.WriteBlocks = CEATABlockWriteBlocks;\r
339 CardData->BlockIo.FlushBlocks = CEATABlockFlushBlocks;\r
340\r
341 CardData->BlockIoMedia.MediaId = 0;\r
342 CardData->BlockIoMedia.RemovableMedia = FALSE;\r
343 CardData->BlockIoMedia.MediaPresent = TRUE;\r
344 CardData->BlockIoMedia.LogicalPartition = FALSE;\r
345\r
346 if (CardData->CSDRegister.PERM_WRITE_PROTECT | CardData->CSDRegister.TMP_WRITE_PROTECT) {\r
347 CardData->BlockIoMedia.ReadOnly = TRUE;\r
348 } else {\r
349 CardData->BlockIoMedia.ReadOnly = FALSE;\r
350 }\r
351\r
352\r
353 CardData->BlockIoMedia.WriteCaching = FALSE;\r
354 CardData->BlockIoMedia.IoAlign = 1;\r
355\r
356 Status = IndentifyDevice (CardData);\r
357 if (EFI_ERROR (Status)) {\r
358 goto Exit;\r
359 }\r
360\r
361 //\r
362 //Some device does not support this feature\r
363 //\r
364\r
365 if (CardData->IndentifyDeviceData.MaxWritesPerAddress == 0) {\r
366 CardData->BlockIoMedia.ReadOnly = TRUE;\r
367 }\r
368\r
369 CardData->BlockIoMedia.BlockSize = (1 << CardData->IndentifyDeviceData.Sectorsize);\r
370 ASSERT(CardData->BlockIoMedia.BlockSize >= 12);\r
371\r
372\r
373 MaxSize = *(UINT64*)(CardData->IndentifyDeviceData.MaximumLBA);\r
374 MaxSize = MultU64x32 (MaxSize, 512);\r
375\r
376 Remainder = 0;\r
377 CardData->BlockNumber = DivU64x32Remainder (MaxSize, CardData->BlockIoMedia.BlockSize, &Remainder);\r
378 ASSERT(Remainder == 0);\r
379\r
380 CardData->BlockIoMedia.LastBlock = (EFI_LBA)(CardData->BlockNumber - 1);\r
381\r
382\r
383Exit:\r
384 return Status;\r
385\r
386}\r
387\r
388\r
389\r