]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Isa/IsaFloppyDxe/IsaFloppyBlock.c
Update the copyright notice format
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / IsaFloppyDxe / IsaFloppyBlock.c
CommitLineData
d6321d6e 1/** @file \r
2 Implementation of the EFI Block IO Protocol for ISA Floppy driver\r
11f43dfd 3 \r
180a5a35
HT
4Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
f8cd287b 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11f43dfd 12\r
f8cd287b 13**/\r
11f43dfd 14\r
11f43dfd 15#include "IsaFloppy.h"\r
16\r
bcd70414 17/**\r
d6321d6e 18 Reset the Block Device.\r
19\r
20 @param This Indicates a pointer to the calling context.\r
21 @param ExtendedVerification Driver may perform diagnostics on reset.\r
bcd70414 22\r
d6321d6e 23 @retval EFI_SUCCESS The device was reset.\r
24 @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
25 not be reset.\r
bcd70414 26**/\r
11f43dfd 27EFI_STATUS\r
28EFIAPI\r
29FdcReset (\r
30 IN EFI_BLOCK_IO_PROTOCOL *This,\r
31 IN BOOLEAN ExtendedVerification\r
32 )\r
11f43dfd 33{\r
34 FDC_BLK_IO_DEV *FdcDev;\r
35\r
36 //\r
37 // Reset the Floppy Disk Controller\r
38 //\r
39 FdcDev = FDD_BLK_IO_FROM_THIS (This);\r
40\r
41 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
42 EFI_PROGRESS_CODE,\r
43 EFI_P_PC_RESET | EFI_PERIPHERAL_REMOVABLE_MEDIA,\r
44 FdcDev->DevicePath\r
45 );\r
46\r
47 return FddReset (FdcDev);\r
48}\r
49\r
bcd70414 50/**\r
d6321d6e 51 Flush the Block Device.\r
52\r
53 @param This Indicates a pointer to the calling context.\r
54\r
55 @retval EFI_SUCCESS All outstanding data was written to the device\r
56 @retval EFI_DEVICE_ERROR The device reported an error while writting back the data\r
57 @retval EFI_NO_MEDIA There is no media in the device.\r
bcd70414 58\r
59**/\r
11f43dfd 60EFI_STATUS\r
61EFIAPI\r
62FddFlushBlocks (\r
63 IN EFI_BLOCK_IO_PROTOCOL *This\r
64 )\r
11f43dfd 65{\r
66 //\r
67 // Not supported yet\r
68 //\r
69 return EFI_SUCCESS;\r
70}\r
71\r
bcd70414 72/**\r
d6321d6e 73 Common report status code interface.\r
bcd70414 74 \r
75 @param This Pointer of FDC_BLK_IO_DEV instance\r
d6321d6e 76 @param Read Read or write operation when error occurrs\r
bcd70414 77**/\r
11f43dfd 78VOID\r
79FddReportStatus (\r
80 IN EFI_BLOCK_IO_PROTOCOL *This,\r
81 IN BOOLEAN Read\r
82 )\r
11f43dfd 83{\r
84 FDC_BLK_IO_DEV *FdcDev;\r
85\r
86 FdcDev = FDD_BLK_IO_FROM_THIS (This);\r
87\r
88 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
89 EFI_ERROR_CODE,\r
90 ((Read) ? EFI_P_EC_INPUT_ERROR : EFI_P_EC_OUTPUT_ERROR) | EFI_PERIPHERAL_REMOVABLE_MEDIA,\r
91 FdcDev->DevicePath\r
92 );\r
93}\r
94\r
bcd70414 95/**\r
d6321d6e 96 Read BufferSize bytes from Lba into Buffer.\r
97\r
98 @param This Indicates a pointer to the calling context.\r
99 @param MediaId Id of the media, changes every time the media is replaced.\r
100 @param Lba The starting Logical Block Address to read from\r
101 @param BufferSize Size of Buffer, must be a multiple of device block size.\r
102 @param Buffer A pointer to the destination buffer for the data. The caller is\r
103 responsible for either having implicit or explicit ownership of the buffer.\r
104\r
105 @retval EFI_SUCCESS The data was read correctly from the device.\r
106 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.\r
107 @retval EFI_NO_MEDIA There is no media in the device.\r
108 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.\r
109 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
110 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, \r
111 or the buffer is not on proper alignment.\r
bcd70414 112\r
113**/\r
11f43dfd 114EFI_STATUS\r
115EFIAPI\r
116FddReadBlocks (\r
117 IN EFI_BLOCK_IO_PROTOCOL *This,\r
118 IN UINT32 MediaId,\r
d6321d6e 119 IN EFI_LBA Lba,\r
11f43dfd 120 IN UINTN BufferSize,\r
121 OUT VOID *Buffer\r
122 )\r
11f43dfd 123{\r
124 EFI_STATUS Status;\r
125\r
d6321d6e 126 Status = FddReadWriteBlocks (This, MediaId, Lba, BufferSize, READ, Buffer);\r
11f43dfd 127\r
128 if (EFI_ERROR (Status)) {\r
129 FddReportStatus (This, TRUE);\r
130 }\r
131\r
132 return Status;\r
133}\r
134\r
bcd70414 135/**\r
d6321d6e 136 Write BufferSize bytes from Lba into Buffer.\r
137\r
138 @param This Indicates a pointer to the calling context.\r
139 @param MediaId The media ID that the write request is for.\r
140 @param Lba The starting logical block address to be written. The caller is\r
141 responsible for writing to only legitimate locations.\r
142 @param BufferSize Size of Buffer, must be a multiple of device block size.\r
143 @param Buffer A pointer to the source buffer for the data.\r
144\r
145 @retval EFI_SUCCESS The data was written correctly to the device.\r
146 @retval EFI_WRITE_PROTECTED The device can not be written to.\r
147 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.\r
148 @retval EFI_NO_MEDIA There is no media in the device.\r
149 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.\r
150 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
151 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, \r
152 or the buffer is not on proper alignment.\r
153\r
bcd70414 154**/\r
11f43dfd 155EFI_STATUS\r
156EFIAPI\r
157FddWriteBlocks (\r
158 IN EFI_BLOCK_IO_PROTOCOL *This,\r
159 IN UINT32 MediaId,\r
d6321d6e 160 IN EFI_LBA Lba,\r
11f43dfd 161 IN UINTN BufferSize,\r
162 IN VOID *Buffer\r
163 )\r
11f43dfd 164{\r
165 EFI_STATUS Status;\r
166\r
d6321d6e 167 Status = FddReadWriteBlocks (This, MediaId, Lba, BufferSize, WRITE, Buffer);\r
11f43dfd 168\r
169 if (EFI_ERROR (Status)) {\r
170 FddReportStatus (This, FALSE);\r
171 }\r
172\r
173 return Status;\r
174}\r
175\r
bcd70414 176/**\r
d6321d6e 177 Read or Write a number of blocks to floppy disk\r
178\r
179 @param This Indicates a pointer to the calling context.\r
180 @param MediaId Id of the media, changes every time the media is replaced.\r
181 @param Lba The starting Logical Block Address to read from\r
182 @param BufferSize Size of Buffer, must be a multiple of device block size.\r
183 @param Operation Specifies the read or write operation.\r
184 @param Buffer A pointer to the destination buffer for the data. The caller is\r
185 responsible for either having implicit or explicit ownership of the buffer.\r
186\r
187 @retval EFI_SUCCESS The data was read correctly from the device.\r
188 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.\r
189 @retval EFI_NO_MEDIA There is no media in the device.\r
190 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.\r
191 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
192 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, \r
193 or the buffer is not on proper alignment.\r
194 @retval EFI_WRITE_PROTECTED The device can not be written to.\r
bcd70414 195\r
196**/\r
11f43dfd 197EFI_STATUS\r
198FddReadWriteBlocks (\r
199 IN EFI_BLOCK_IO_PROTOCOL *This,\r
200 IN UINT32 MediaId,\r
d6321d6e 201 IN EFI_LBA Lba,\r
11f43dfd 202 IN UINTN BufferSize,\r
203 IN BOOLEAN Operation,\r
204 OUT VOID *Buffer\r
205 )\r
11f43dfd 206{\r
207 EFI_BLOCK_IO_MEDIA *Media;\r
208 FDC_BLK_IO_DEV *FdcDev;\r
209 UINTN BlockSize;\r
210 UINTN NumberOfBlocks;\r
211 UINTN BlockCount;\r
212 EFI_STATUS Status;\r
d6321d6e 213 EFI_LBA Lba0;\r
11f43dfd 214 UINT8 *Pointer;\r
215\r
216 //\r
217 // Get the intrinsic block size\r
218 //\r
219 Media = This->Media;\r
220 BlockSize = Media->BlockSize;\r
221 FdcDev = FDD_BLK_IO_FROM_THIS (This);\r
222\r
223 if (Operation == WRITE) {\r
d6321d6e 224 if (Lba == 0) {\r
11f43dfd 225 FdcFreeCache (FdcDev);\r
226 }\r
227 }\r
228 //\r
229 // Check the Parameter is valid\r
230 //\r
231 if (Buffer == NULL) {\r
232 return EFI_INVALID_PARAMETER;\r
233 }\r
234\r
235 if (BufferSize == 0) {\r
236 return EFI_SUCCESS;\r
237 }\r
238 //\r
239 // Set the drive motor on\r
240 //\r
241 Status = MotorOn (FdcDev);\r
242 if (EFI_ERROR (Status)) {\r
243 return EFI_DEVICE_ERROR;\r
244 }\r
245 //\r
246 // Check to see if media can be detected\r
247 //\r
248 Status = DetectMedia (FdcDev);\r
249 if (EFI_ERROR (Status)) {\r
250 MotorOff (FdcDev);\r
251 FdcFreeCache (FdcDev);\r
252 return EFI_DEVICE_ERROR;\r
253 }\r
254 //\r
255 // Check to see if media is present\r
256 //\r
257 if (!(Media->MediaPresent)) {\r
258 MotorOff (FdcDev);\r
259 FdcFreeCache (FdcDev);\r
11f43dfd 260 return EFI_NO_MEDIA;\r
261 }\r
262 //\r
263 // Check to see if media has been changed\r
264 //\r
265 if (MediaId != Media->MediaId) {\r
266 MotorOff (FdcDev);\r
267 FdcFreeCache (FdcDev);\r
268 return EFI_MEDIA_CHANGED;\r
269 }\r
270\r
271 if (Operation == WRITE) {\r
272 if (Media->ReadOnly) {\r
273 MotorOff (FdcDev);\r
274 return EFI_WRITE_PROTECTED;\r
275 }\r
276 }\r
277 //\r
278 // Check the parameters for this read/write operation\r
279 //\r
280 if (BufferSize % BlockSize != 0) {\r
281 MotorOff (FdcDev);\r
282 return EFI_BAD_BUFFER_SIZE;\r
283 }\r
284\r
d6321d6e 285 if (Lba > Media->LastBlock) {\r
11f43dfd 286 MotorOff (FdcDev);\r
287 return EFI_INVALID_PARAMETER;\r
288 }\r
289\r
d6321d6e 290 if (((BufferSize / BlockSize) + Lba - 1) > Media->LastBlock) {\r
11f43dfd 291 MotorOff (FdcDev);\r
292 return EFI_INVALID_PARAMETER;\r
293 }\r
294\r
295 if (Operation == READ) {\r
296 //\r
297 // See if the data that is being read is already in the cache\r
298 //\r
d6321d6e 299 if (FdcDev->Cache != NULL) {\r
300 if (Lba == 0 && BufferSize == BlockSize) {\r
11f43dfd 301 MotorOff (FdcDev);\r
302 CopyMem ((UINT8 *) Buffer, (UINT8 *) FdcDev->Cache, BlockSize);\r
303 return EFI_SUCCESS;\r
304 }\r
305 }\r
306 }\r
307 //\r
308 // Set up Floppy Disk Controller\r
309 //\r
310 Status = Setup (FdcDev);\r
311 if (EFI_ERROR (Status)) {\r
312 MotorOff (FdcDev);\r
313 return EFI_DEVICE_ERROR;\r
314 }\r
315\r
316 NumberOfBlocks = BufferSize / BlockSize;\r
d6321d6e 317 Lba0 = Lba;\r
11f43dfd 318 Pointer = Buffer;\r
319\r
320 //\r
321 // read blocks in the same cylinder.\r
322 // in a cylinder , there are 18 * 2 = 36 blocks\r
323 //\r
d6321d6e 324 BlockCount = GetTransferBlockCount (FdcDev, Lba, NumberOfBlocks);\r
11f43dfd 325 while ((BlockCount != 0) && !EFI_ERROR (Status)) {\r
d6321d6e 326 Status = ReadWriteDataSector (FdcDev, Buffer, Lba, BlockCount, Operation);\r
11f43dfd 327 if (EFI_ERROR (Status)) {\r
328 MotorOff (FdcDev);\r
329 FddReset (FdcDev);\r
330 return EFI_DEVICE_ERROR;\r
331 }\r
332\r
d6321d6e 333 Lba += BlockCount;\r
11f43dfd 334 NumberOfBlocks -= BlockCount;\r
335 Buffer = (VOID *) ((UINTN) Buffer + BlockCount * BlockSize);\r
d6321d6e 336 BlockCount = GetTransferBlockCount (FdcDev, Lba, NumberOfBlocks);\r
11f43dfd 337 }\r
338\r
339 Buffer = Pointer;\r
340\r
341 //\r
342 // Turn the motor off\r
343 //\r
344 MotorOff (FdcDev);\r
345\r
346 if (Operation == READ) {\r
347 //\r
348 // Cache the data read\r
349 //\r
d6321d6e 350 if (Lba0 == 0 && FdcDev->Cache == NULL) {\r
11f43dfd 351 FdcDev->Cache = AllocateCopyPool (BlockSize, Buffer);\r
352 }\r
353 }\r
354\r
355 return EFI_SUCCESS;\r
356\r
357}\r
358\r
bcd70414 359/**\r
d6321d6e 360 Free cache for a floppy disk.\r
bcd70414 361 \r
d6321d6e 362 @param FdcDev A Pointer to FDC_BLK_IO_DEV instance\r
bcd70414 363 \r
364**/\r
11f43dfd 365VOID\r
366FdcFreeCache (\r
d6321d6e 367 IN FDC_BLK_IO_DEV *FdcDev\r
11f43dfd 368 )\r
11f43dfd 369{\r
d6321d6e 370 if (FdcDev->Cache != NULL) {\r
371 FreePool (FdcDev->Cache);\r
11f43dfd 372 FdcDev->Cache = NULL;\r
373 }\r
374}\r