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
10 Implement the Block IO interface
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
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.
24 #include "IsaFloppy.h"
29 IN EFI_BLOCK_IO_PROTOCOL
*This
,
30 IN BOOLEAN ExtendedVerification
34 Routine Description: Reset the Floppy Logic Drive, call the FddReset function
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
41 EFI_SUCCESS: The Floppy Logic Drive is reset
42 EFI_DEVICE_ERROR: The Floppy Logic Drive is not functioning correctly
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
50 FDC_BLK_IO_DEV
*FdcDev
;
53 // Reset the Floppy Disk Controller
55 FdcDev
= FDD_BLK_IO_FROM_THIS (This
);
57 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
59 EFI_P_PC_RESET
| EFI_PERIPHERAL_REMOVABLE_MEDIA
,
63 return FddReset (FdcDev
);
69 IN EFI_BLOCK_IO_PROTOCOL
*This
75 This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface
80 // GC_TODO: function comment is missing 'Arguments:'
81 // GC_TODO: This - add argument and description to function comment
92 IN EFI_BLOCK_IO_PROTOCOL
*This
,
99 GC_TODO: Add function description
103 This - GC_TODO: add argument description
104 Read - GC_TODO: add argument description
108 GC_TODO: add return values
112 FDC_BLK_IO_DEV
*FdcDev
;
114 FdcDev
= FDD_BLK_IO_FROM_THIS (This
);
116 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
118 ((Read
) ? EFI_P_EC_INPUT_ERROR
: EFI_P_EC_OUTPUT_ERROR
) | EFI_PERIPHERAL_REMOVABLE_MEDIA
,
126 IN EFI_BLOCK_IO_PROTOCOL
*This
,
134 Routine Description: Read the requested number of blocks from the device
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
142 EFI_SUCCESS: The data was read correctly from the device
143 EFI_DEVICE_ERROR:The device reported an error while attempting to perform
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
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
162 Status
= FddReadWriteBlocks (This
, MediaId
, LBA
, BufferSize
, READ
, Buffer
);
164 if (EFI_ERROR (Status
)) {
165 FddReportStatus (This
, TRUE
);
174 IN EFI_BLOCK_IO_PROTOCOL
*This
,
182 Routine Description: Write a specified number of blocks to the device
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
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
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
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
212 Status
= FddReadWriteBlocks (This
, MediaId
, LBA
, BufferSize
, WRITE
, Buffer
);
214 if (EFI_ERROR (Status
)) {
215 FddReportStatus (This
, FALSE
);
223 IN EFI_BLOCK_IO_PROTOCOL
*This
,
227 IN BOOLEAN Operation
,
234 GC_TODO: Add function description
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
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
264 EFI_BLOCK_IO_MEDIA
*Media
;
265 FDC_BLK_IO_DEV
*FdcDev
;
267 UINTN NumberOfBlocks
;
271 // EFI_STATUS CacheStatus;
277 // Get the intrinsic block size
280 BlockSize
= Media
->BlockSize
;
281 FdcDev
= FDD_BLK_IO_FROM_THIS (This
);
283 if (Operation
== WRITE
) {
285 FdcFreeCache (FdcDev
);
289 // Check the Parameter is valid
291 if (Buffer
== NULL
) {
292 return EFI_INVALID_PARAMETER
;
295 if (BufferSize
== 0) {
299 // Set the drive motor on
301 Status
= MotorOn (FdcDev
);
302 if (EFI_ERROR (Status
)) {
303 return EFI_DEVICE_ERROR
;
306 // Check to see if media can be detected
308 Status
= DetectMedia (FdcDev
);
309 if (EFI_ERROR (Status
)) {
311 FdcFreeCache (FdcDev
);
312 return EFI_DEVICE_ERROR
;
315 // Check to see if media is present
317 if (!(Media
->MediaPresent
)) {
319 FdcFreeCache (FdcDev
);
323 gBS->FreePool (FdcDev->Cache);
324 FdcDev->Cache = NULL;
330 // Check to see if media has been changed
332 if (MediaId
!= Media
->MediaId
) {
334 FdcFreeCache (FdcDev
);
335 return EFI_MEDIA_CHANGED
;
338 if (Operation
== WRITE
) {
339 if (Media
->ReadOnly
) {
341 return EFI_WRITE_PROTECTED
;
345 // Check the parameters for this read/write operation
347 if (BufferSize
% BlockSize
!= 0) {
349 return EFI_BAD_BUFFER_SIZE
;
352 if (LBA
> Media
->LastBlock
) {
354 return EFI_INVALID_PARAMETER
;
357 if (((BufferSize
/ BlockSize
) + LBA
- 1) > Media
->LastBlock
) {
359 return EFI_INVALID_PARAMETER
;
362 if (Operation
== READ
) {
364 // See if the data that is being read is already in the cache
367 if (LBA
== 0 && BufferSize
== BlockSize
) {
369 CopyMem ((UINT8
*) Buffer
, (UINT8
*) FdcDev
->Cache
, BlockSize
);
375 // Set up Floppy Disk Controller
377 Status
= Setup (FdcDev
);
378 if (EFI_ERROR (Status
)) {
380 return EFI_DEVICE_ERROR
;
383 NumberOfBlocks
= BufferSize
/ BlockSize
;
388 // read blocks in the same cylinder.
389 // in a cylinder , there are 18 * 2 = 36 blocks
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
)) {
397 return EFI_DEVICE_ERROR
;
401 NumberOfBlocks
-= BlockCount
;
402 Buffer
= (VOID
*) ((UINTN
) Buffer
+ BlockCount
* BlockSize
);
403 BlockCount
= GetTransferBlockCount (FdcDev
, LBA
, NumberOfBlocks
);
409 // Turn the motor off
413 if (Operation
== READ
) {
415 // Cache the data read
417 if (LBA0
== 0 && !FdcDev
->Cache
) {
418 FdcDev
->Cache
= AllocateCopyPool (BlockSize
, Buffer
);
428 IN FDC_BLK_IO_DEV
*FdcDev
434 GC_TODO: Add function description
438 FdcDev - GC_TODO: add argument description
442 GC_TODO: add return values
447 gBS
->FreePool (FdcDev
->Cache
);
448 FdcDev
->Cache
= NULL
;