]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Isa/IsaFloppyDxe/IsaFloppyBlock.c
Remove ambiguous auto-increment usage. (gcc warning)
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / IsaFloppyDxe / IsaFloppyBlock.c
CommitLineData
f8cd287b 1/**@file\r
11f43dfd 2 ISA Floppy Driver\r
3 1. Support two types diskette drive \r
4 1.44M drive and 2.88M drive (and now only support 1.44M)\r
5 2. Support two diskette drives\r
6 3. Use DMA channel 2 to transfer data\r
7 4. Do not use interrupt\r
8 5. Support diskette change line signal and write protect\r
9 \r
10 Implement the Block IO interface\r
f8cd287b 11 \r
12Copyright (c) 2006 - 2007, Intel Corporation.<BR>\r
13All rights reserved. This program and the accompanying materials\r
14are licensed and made available under the terms and conditions of the BSD License\r
15which accompanies this distribution. The full text of the license may be found at\r
16http://opensource.org/licenses/bsd-license.php\r
17\r
18THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
19WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11f43dfd 20\r
f8cd287b 21**/\r
11f43dfd 22\r
11f43dfd 23\r
24#include "IsaFloppy.h"\r
25\r
26EFI_STATUS\r
27EFIAPI\r
28FdcReset (\r
29 IN EFI_BLOCK_IO_PROTOCOL *This,\r
30 IN BOOLEAN ExtendedVerification\r
31 )\r
32/*++\r
33 \r
34 Routine Description: Reset the Floppy Logic Drive, call the FddReset function \r
35 Parameters:\r
36 This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface\r
37 ExtendedVerification BOOLEAN: Indicate that the driver may perform a more \r
38 exhaustive verification operation of the device during \r
39 reset, now this par is ignored in this driver \r
40 Returns:\r
41 EFI_SUCCESS: The Floppy Logic Drive is reset\r
42 EFI_DEVICE_ERROR: The Floppy Logic Drive is not functioning correctly \r
43 and can not be reset\r
44\r
45--*/\r
46// GC_TODO: function comment is missing 'Arguments:'\r
47// GC_TODO: This - add argument and description to function comment\r
48// GC_TODO: ExtendedVerification - add argument and description to function comment\r
49{\r
50 FDC_BLK_IO_DEV *FdcDev;\r
51\r
52 //\r
53 // Reset the Floppy Disk Controller\r
54 //\r
55 FdcDev = FDD_BLK_IO_FROM_THIS (This);\r
56\r
57 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
58 EFI_PROGRESS_CODE,\r
59 EFI_P_PC_RESET | EFI_PERIPHERAL_REMOVABLE_MEDIA,\r
60 FdcDev->DevicePath\r
61 );\r
62\r
63 return FddReset (FdcDev);\r
64}\r
65\r
66EFI_STATUS\r
67EFIAPI\r
68FddFlushBlocks (\r
69 IN EFI_BLOCK_IO_PROTOCOL *This\r
70 )\r
71/*++\r
72 \r
73 Routine Description: \r
74 Parameters:\r
75 This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface\r
76 Returns:\r
77 EFI_SUCCESS: \r
78\r
79--*/\r
80// GC_TODO: function comment is missing 'Arguments:'\r
81// GC_TODO: This - add argument and description to function comment\r
82{\r
83 //\r
84 // Not supported yet\r
85 //\r
86 return EFI_SUCCESS;\r
87}\r
88\r
89STATIC\r
90VOID\r
91FddReportStatus (\r
92 IN EFI_BLOCK_IO_PROTOCOL *This,\r
93 IN BOOLEAN Read\r
94 )\r
95/*++\r
96\r
97Routine Description:\r
98\r
99 GC_TODO: Add function description\r
100\r
101Arguments:\r
102\r
103 This - GC_TODO: add argument description\r
104 Read - GC_TODO: add argument description\r
105\r
106Returns:\r
107\r
108 GC_TODO: add return values\r
109\r
110--*/\r
111{\r
112 FDC_BLK_IO_DEV *FdcDev;\r
113\r
114 FdcDev = FDD_BLK_IO_FROM_THIS (This);\r
115\r
116 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
117 EFI_ERROR_CODE,\r
118 ((Read) ? EFI_P_EC_INPUT_ERROR : EFI_P_EC_OUTPUT_ERROR) | EFI_PERIPHERAL_REMOVABLE_MEDIA,\r
119 FdcDev->DevicePath\r
120 );\r
121}\r
122\r
123EFI_STATUS\r
124EFIAPI\r
125FddReadBlocks (\r
126 IN EFI_BLOCK_IO_PROTOCOL *This,\r
127 IN UINT32 MediaId,\r
128 IN EFI_LBA LBA,\r
129 IN UINTN BufferSize,\r
130 OUT VOID *Buffer\r
131 )\r
132/*++\r
133\r
134 Routine Description: Read the requested number of blocks from the device \r
135 Parameters:\r
136 This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface\r
137 MediaId UINT32: The media id that the read request is for \r
138 LBA EFI_LBA: The starting logic block address to read from on the device\r
139 BufferSize UINTN: The size of the Buffer in bytes\r
140 Buffer VOID *: A pointer to the destination buffer for the data\r
141 Returns:\r
142 EFI_SUCCESS: The data was read correctly from the device\r
143 EFI_DEVICE_ERROR:The device reported an error while attempting to perform\r
144 the read operation\r
145 EFI_NO_MEDIA: There is no media in the device\r
146 EFI_MEDIA_CHANGED: The MediaId is not for the current media\r
147 EFI_BAD_BUFFER_SIZE: The BufferSize parameter is not a multiple of the \r
148 intrinsic block size of the device\r
149 EFI_INVALID_PARAMETER:The read request contains LBAs that are not valid, \r
150 or the buffer is not on proper alignment \r
151\r
152--*/\r
153// GC_TODO: function comment is missing 'Arguments:'\r
154// GC_TODO: This - add argument and description to function comment\r
155// GC_TODO: MediaId - add argument and description to function comment\r
156// GC_TODO: LBA - add argument and description to function comment\r
157// GC_TODO: BufferSize - add argument and description to function comment\r
158// GC_TODO: Buffer - add argument and description to function comment\r
159{\r
160 EFI_STATUS Status;\r
161\r
162 Status = FddReadWriteBlocks (This, MediaId, LBA, BufferSize, READ, Buffer);\r
163\r
164 if (EFI_ERROR (Status)) {\r
165 FddReportStatus (This, TRUE);\r
166 }\r
167\r
168 return Status;\r
169}\r
170\r
171EFI_STATUS\r
172EFIAPI\r
173FddWriteBlocks (\r
174 IN EFI_BLOCK_IO_PROTOCOL *This,\r
175 IN UINT32 MediaId,\r
176 IN EFI_LBA LBA,\r
177 IN UINTN BufferSize,\r
178 IN VOID *Buffer\r
179 )\r
180/*++\r
181\r
182 Routine Description: Write a specified number of blocks to the device \r
183 Parameters:\r
184 This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface\r
185 MediaId UINT32: The media id that the write request is for \r
186 LBA EFI_LBA: The starting logic block address to be written\r
187 BufferSize UINTN: The size in bytes in Buffer\r
188 Buffer VOID *: A pointer to the source buffer for the data\r
189 Returns :\r
190 EFI_SUCCESS: The data were written correctly to the device\r
191 EFI_WRITE_PROTECTED: The device can not be written to \r
192 EFI_NO_MEDIA: There is no media in the device\r
193 EFI_MEDIA_CHANGED: The MediaId is not for the current media\r
194 EFI_DEVICE_ERROR: The device reported an error while attempting to perform \r
195 the write operation \r
196 EFI_BAD_BUFFER_SIZE: The BufferSize parameter is not a multiple of the \r
197 intrinsic block size of the device\r
198 EFI_INVALID_PARAMETER:The write request contains LBAs that are not valid, \r
199 or the buffer is not on proper alignment \r
200\r
201--*/\r
202// GC_TODO: function comment is missing 'Arguments:'\r
203// GC_TODO: function comment is missing 'Returns:'\r
204// GC_TODO: This - add argument and description to function comment\r
205// GC_TODO: MediaId - add argument and description to function comment\r
206// GC_TODO: LBA - add argument and description to function comment\r
207// GC_TODO: BufferSize - add argument and description to function comment\r
208// GC_TODO: Buffer - add argument and description to function comment\r
209{\r
210 EFI_STATUS Status;\r
211\r
212 Status = FddReadWriteBlocks (This, MediaId, LBA, BufferSize, WRITE, Buffer);\r
213\r
214 if (EFI_ERROR (Status)) {\r
215 FddReportStatus (This, FALSE);\r
216 }\r
217\r
218 return Status;\r
219}\r
220\r
221EFI_STATUS\r
222FddReadWriteBlocks (\r
223 IN EFI_BLOCK_IO_PROTOCOL *This,\r
224 IN UINT32 MediaId,\r
225 IN EFI_LBA LBA,\r
226 IN UINTN BufferSize,\r
227 IN BOOLEAN Operation,\r
228 OUT VOID *Buffer\r
229 )\r
230/*++\r
231\r
232Routine Description:\r
233\r
234 GC_TODO: Add function description\r
235\r
236Arguments:\r
237\r
238 This - GC_TODO: add argument description\r
239 MediaId - GC_TODO: add argument description\r
240 LBA - GC_TODO: add argument description\r
241 BufferSize - GC_TODO: add argument description\r
242 Operation - GC_TODO: add argument description\r
243 Buffer - GC_TODO: add argument description\r
244\r
245Returns:\r
246\r
247 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
248 EFI_SUCCESS - GC_TODO: Add description for return value\r
249 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
250 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
251 EFI_NO_MEDIA - GC_TODO: Add description for return value\r
252 EFI_MEDIA_CHANGED - GC_TODO: Add description for return value\r
253 EFI_WRITE_PROTECTED - GC_TODO: Add description for return value\r
254 EFI_BAD_BUFFER_SIZE - GC_TODO: Add description for return value\r
255 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
256 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
257 EFI_SUCCESS - GC_TODO: Add description for return value\r
258 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
259 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
260 EFI_SUCCESS - GC_TODO: Add description for return value\r
261\r
262--*/\r
263{\r
264 EFI_BLOCK_IO_MEDIA *Media;\r
265 FDC_BLK_IO_DEV *FdcDev;\r
266 UINTN BlockSize;\r
267 UINTN NumberOfBlocks;\r
268 UINTN BlockCount;\r
269 EFI_STATUS Status;\r
270 //\r
271 // EFI_STATUS CacheStatus;\r
272 //\r
273 EFI_LBA LBA0;\r
274 UINT8 *Pointer;\r
275\r
276 //\r
277 // Get the intrinsic block size\r
278 //\r
279 Media = This->Media;\r
280 BlockSize = Media->BlockSize;\r
281 FdcDev = FDD_BLK_IO_FROM_THIS (This);\r
282\r
283 if (Operation == WRITE) {\r
284 if (LBA == 0) {\r
285 FdcFreeCache (FdcDev);\r
286 }\r
287 }\r
288 //\r
289 // Check the Parameter is valid\r
290 //\r
291 if (Buffer == NULL) {\r
292 return EFI_INVALID_PARAMETER;\r
293 }\r
294\r
295 if (BufferSize == 0) {\r
296 return EFI_SUCCESS;\r
297 }\r
298 //\r
299 // Set the drive motor on\r
300 //\r
301 Status = MotorOn (FdcDev);\r
302 if (EFI_ERROR (Status)) {\r
303 return EFI_DEVICE_ERROR;\r
304 }\r
305 //\r
306 // Check to see if media can be detected\r
307 //\r
308 Status = DetectMedia (FdcDev);\r
309 if (EFI_ERROR (Status)) {\r
310 MotorOff (FdcDev);\r
311 FdcFreeCache (FdcDev);\r
312 return EFI_DEVICE_ERROR;\r
313 }\r
314 //\r
315 // Check to see if media is present\r
316 //\r
317 if (!(Media->MediaPresent)) {\r
318 MotorOff (FdcDev);\r
319 FdcFreeCache (FdcDev);\r
320\r
321 /*\r
322 if (FdcDev->Cache) {\r
323 gBS->FreePool (FdcDev->Cache);\r
324 FdcDev->Cache = NULL;\r
325 }\r
326*/\r
327 return EFI_NO_MEDIA;\r
328 }\r
329 //\r
330 // Check to see if media has been changed\r
331 //\r
332 if (MediaId != Media->MediaId) {\r
333 MotorOff (FdcDev);\r
334 FdcFreeCache (FdcDev);\r
335 return EFI_MEDIA_CHANGED;\r
336 }\r
337\r
338 if (Operation == WRITE) {\r
339 if (Media->ReadOnly) {\r
340 MotorOff (FdcDev);\r
341 return EFI_WRITE_PROTECTED;\r
342 }\r
343 }\r
344 //\r
345 // Check the parameters for this read/write operation\r
346 //\r
347 if (BufferSize % BlockSize != 0) {\r
348 MotorOff (FdcDev);\r
349 return EFI_BAD_BUFFER_SIZE;\r
350 }\r
351\r
352 if (LBA > Media->LastBlock) {\r
353 MotorOff (FdcDev);\r
354 return EFI_INVALID_PARAMETER;\r
355 }\r
356\r
357 if (((BufferSize / BlockSize) + LBA - 1) > Media->LastBlock) {\r
358 MotorOff (FdcDev);\r
359 return EFI_INVALID_PARAMETER;\r
360 }\r
361\r
362 if (Operation == READ) {\r
363 //\r
364 // See if the data that is being read is already in the cache\r
365 //\r
366 if (FdcDev->Cache) {\r
367 if (LBA == 0 && BufferSize == BlockSize) {\r
368 MotorOff (FdcDev);\r
369 CopyMem ((UINT8 *) Buffer, (UINT8 *) FdcDev->Cache, BlockSize);\r
370 return EFI_SUCCESS;\r
371 }\r
372 }\r
373 }\r
374 //\r
375 // Set up Floppy Disk Controller\r
376 //\r
377 Status = Setup (FdcDev);\r
378 if (EFI_ERROR (Status)) {\r
379 MotorOff (FdcDev);\r
380 return EFI_DEVICE_ERROR;\r
381 }\r
382\r
383 NumberOfBlocks = BufferSize / BlockSize;\r
384 LBA0 = LBA;\r
385 Pointer = Buffer;\r
386\r
387 //\r
388 // read blocks in the same cylinder.\r
389 // in a cylinder , there are 18 * 2 = 36 blocks\r
390 //\r
391 BlockCount = GetTransferBlockCount (FdcDev, LBA, NumberOfBlocks);\r
392 while ((BlockCount != 0) && !EFI_ERROR (Status)) {\r
393 Status = ReadWriteDataSector (FdcDev, Buffer, LBA, BlockCount, Operation);\r
394 if (EFI_ERROR (Status)) {\r
395 MotorOff (FdcDev);\r
396 FddReset (FdcDev);\r
397 return EFI_DEVICE_ERROR;\r
398 }\r
399\r
400 LBA += BlockCount;\r
401 NumberOfBlocks -= BlockCount;\r
402 Buffer = (VOID *) ((UINTN) Buffer + BlockCount * BlockSize);\r
403 BlockCount = GetTransferBlockCount (FdcDev, LBA, NumberOfBlocks);\r
404 }\r
405\r
406 Buffer = Pointer;\r
407\r
408 //\r
409 // Turn the motor off\r
410 //\r
411 MotorOff (FdcDev);\r
412\r
413 if (Operation == READ) {\r
414 //\r
415 // Cache the data read\r
416 //\r
417 if (LBA0 == 0 && !FdcDev->Cache) {\r
418 FdcDev->Cache = AllocateCopyPool (BlockSize, Buffer);\r
419 }\r
420 }\r
421\r
422 return EFI_SUCCESS;\r
423\r
424}\r
425\r
426VOID\r
427FdcFreeCache (\r
428 IN FDC_BLK_IO_DEV *FdcDev\r
429 )\r
430/*++\r
431\r
432Routine Description:\r
433\r
434 GC_TODO: Add function description\r
435\r
436Arguments:\r
437\r
438 FdcDev - GC_TODO: add argument description\r
439\r
440Returns:\r
441\r
442 GC_TODO: add return values\r
443\r
444--*/\r
445{\r
446 if (FdcDev->Cache) {\r
447 gBS->FreePool (FdcDev->Cache);\r
448 FdcDev->Cache = NULL;\r
449 }\r
450}\r