2 Implementation of the EFI Block IO Protocol for ISA Floppy driver
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "IsaFloppy.h"
18 Reset the Block Device.
20 @param This Indicates a pointer to the calling context.
21 @param ExtendedVerification Driver may perform diagnostics on reset.
23 @retval EFI_SUCCESS The device was reset.
24 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
30 IN EFI_BLOCK_IO_PROTOCOL
*This
,
31 IN BOOLEAN ExtendedVerification
34 FDC_BLK_IO_DEV
*FdcDev
;
37 // Reset the Floppy Disk Controller
39 FdcDev
= FDD_BLK_IO_FROM_THIS (This
);
41 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
43 EFI_P_PC_RESET
| EFI_PERIPHERAL_REMOVABLE_MEDIA
,
47 return FddReset (FdcDev
);
51 Flush the Block Device.
53 @param This Indicates a pointer to the calling context.
55 @retval EFI_SUCCESS All outstanding data was written to the device
56 @retval EFI_DEVICE_ERROR The device reported an error while writting back the data
57 @retval EFI_NO_MEDIA There is no media in the device.
63 IN EFI_BLOCK_IO_PROTOCOL
*This
73 Common report status code interface.
75 @param This Pointer of FDC_BLK_IO_DEV instance
76 @param Read Read or write operation when error occurrs
80 IN EFI_BLOCK_IO_PROTOCOL
*This
,
84 FDC_BLK_IO_DEV
*FdcDev
;
86 FdcDev
= FDD_BLK_IO_FROM_THIS (This
);
88 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
90 ((Read
) ? EFI_P_EC_INPUT_ERROR
: EFI_P_EC_OUTPUT_ERROR
) | EFI_PERIPHERAL_REMOVABLE_MEDIA
,
96 Read BufferSize bytes from Lba into Buffer.
98 @param This Indicates a pointer to the calling context.
99 @param MediaId Id of the media, changes every time the media is replaced.
100 @param Lba The starting Logical Block Address to read from
101 @param BufferSize Size of Buffer, must be a multiple of device block size.
102 @param Buffer A pointer to the destination buffer for the data. The caller is
103 responsible for either having implicit or explicit ownership of the buffer.
105 @retval EFI_SUCCESS The data was read correctly from the device.
106 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
107 @retval EFI_NO_MEDIA There is no media in the device.
108 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
109 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
110 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
111 or the buffer is not on proper alignment.
117 IN EFI_BLOCK_IO_PROTOCOL
*This
,
126 Status
= FddReadWriteBlocks (This
, MediaId
, Lba
, BufferSize
, READ
, Buffer
);
128 if (EFI_ERROR (Status
)) {
129 FddReportStatus (This
, TRUE
);
136 Write BufferSize bytes from Lba into Buffer.
138 @param This Indicates a pointer to the calling context.
139 @param MediaId The media ID that the write request is for.
140 @param Lba The starting logical block address to be written. The caller is
141 responsible for writing to only legitimate locations.
142 @param BufferSize Size of Buffer, must be a multiple of device block size.
143 @param Buffer A pointer to the source buffer for the data.
145 @retval EFI_SUCCESS The data was written correctly to the device.
146 @retval EFI_WRITE_PROTECTED The device can not be written to.
147 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
148 @retval EFI_NO_MEDIA There is no media in the device.
149 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
150 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
151 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
152 or the buffer is not on proper alignment.
158 IN EFI_BLOCK_IO_PROTOCOL
*This
,
167 Status
= FddReadWriteBlocks (This
, MediaId
, Lba
, BufferSize
, WRITE
, Buffer
);
169 if (EFI_ERROR (Status
)) {
170 FddReportStatus (This
, FALSE
);
177 Read or Write a number of blocks to floppy disk
179 @param This Indicates a pointer to the calling context.
180 @param MediaId Id of the media, changes every time the media is replaced.
181 @param Lba The starting Logical Block Address to read from
182 @param BufferSize Size of Buffer, must be a multiple of device block size.
183 @param Operation Specifies the read or write operation.
184 @param Buffer A pointer to the destination buffer for the data. The caller is
185 responsible for either having implicit or explicit ownership of the buffer.
187 @retval EFI_SUCCESS The data was read correctly from the device.
188 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
189 @retval EFI_NO_MEDIA There is no media in the device.
190 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
191 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
192 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
193 or the buffer is not on proper alignment.
194 @retval EFI_WRITE_PROTECTED The device can not be written to.
199 IN EFI_BLOCK_IO_PROTOCOL
*This
,
203 IN BOOLEAN Operation
,
207 EFI_BLOCK_IO_MEDIA
*Media
;
208 FDC_BLK_IO_DEV
*FdcDev
;
210 UINTN NumberOfBlocks
;
217 // Get the intrinsic block size
220 BlockSize
= Media
->BlockSize
;
221 FdcDev
= FDD_BLK_IO_FROM_THIS (This
);
223 if (Operation
== WRITE
) {
225 FdcFreeCache (FdcDev
);
230 // Set the drive motor on
232 Status
= MotorOn (FdcDev
);
233 if (EFI_ERROR (Status
)) {
234 return EFI_DEVICE_ERROR
;
237 // Check to see if media can be detected
239 Status
= DetectMedia (FdcDev
);
240 if (EFI_ERROR (Status
)) {
242 FdcFreeCache (FdcDev
);
243 return EFI_DEVICE_ERROR
;
246 // Check to see if media is present
248 if (!(Media
->MediaPresent
)) {
250 FdcFreeCache (FdcDev
);
254 // Check to see if media has been changed
256 if (MediaId
!= Media
->MediaId
) {
258 FdcFreeCache (FdcDev
);
259 return EFI_MEDIA_CHANGED
;
262 if (BufferSize
== 0) {
267 if (Operation
== WRITE
) {
268 if (Media
->ReadOnly
) {
270 return EFI_WRITE_PROTECTED
;
274 // Check the parameters for this read/write operation
276 if (Buffer
== NULL
) {
278 return EFI_INVALID_PARAMETER
;
281 if (BufferSize
% BlockSize
!= 0) {
283 return EFI_BAD_BUFFER_SIZE
;
286 if (Lba
> Media
->LastBlock
) {
288 return EFI_INVALID_PARAMETER
;
291 if (((BufferSize
/ BlockSize
) + Lba
- 1) > Media
->LastBlock
) {
293 return EFI_INVALID_PARAMETER
;
296 if (Operation
== READ
) {
298 // See if the data that is being read is already in the cache
300 if (FdcDev
->Cache
!= NULL
) {
301 if (Lba
== 0 && BufferSize
== BlockSize
) {
303 CopyMem ((UINT8
*) Buffer
, (UINT8
*) FdcDev
->Cache
, BlockSize
);
309 // Set up Floppy Disk Controller
311 Status
= Setup (FdcDev
);
312 if (EFI_ERROR (Status
)) {
314 return EFI_DEVICE_ERROR
;
317 NumberOfBlocks
= BufferSize
/ BlockSize
;
322 // read blocks in the same cylinder.
323 // in a cylinder , there are 18 * 2 = 36 blocks
325 BlockCount
= GetTransferBlockCount (FdcDev
, Lba
, NumberOfBlocks
);
326 while ((BlockCount
!= 0) && !EFI_ERROR (Status
)) {
327 Status
= ReadWriteDataSector (FdcDev
, Buffer
, Lba
, BlockCount
, Operation
);
328 if (EFI_ERROR (Status
)) {
331 return EFI_DEVICE_ERROR
;
335 NumberOfBlocks
-= BlockCount
;
336 Buffer
= (VOID
*) ((UINTN
) Buffer
+ BlockCount
* BlockSize
);
337 BlockCount
= GetTransferBlockCount (FdcDev
, Lba
, NumberOfBlocks
);
343 // Turn the motor off
347 if (Operation
== READ
) {
349 // Cache the data read
351 if (Lba0
== 0 && FdcDev
->Cache
== NULL
) {
352 FdcDev
->Cache
= AllocateCopyPool (BlockSize
, Buffer
);
361 Free cache for a floppy disk.
363 @param FdcDev A Pointer to FDC_BLK_IO_DEV instance
368 IN FDC_BLK_IO_DEV
*FdcDev
371 if (FdcDev
->Cache
!= NULL
) {
372 FreePool (FdcDev
->Cache
);
373 FdcDev
->Cache
= NULL
;