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