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