2 Implementation of the EFI Block IO Protocol for ISA Floppy driver
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 Reset the Block Device.
14 @param This Indicates a pointer to the calling context.
15 @param ExtendedVerification Driver may perform diagnostics on reset.
17 @retval EFI_SUCCESS The device was reset.
18 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
24 IN EFI_BLOCK_IO_PROTOCOL
*This
,
25 IN BOOLEAN ExtendedVerification
28 FDC_BLK_IO_DEV
*FdcDev
;
31 // Reset the Floppy Disk Controller
33 FdcDev
= FDD_BLK_IO_FROM_THIS (This
);
35 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
37 EFI_P_PC_RESET
| EFI_PERIPHERAL_REMOVABLE_MEDIA
,
41 return FddReset (FdcDev
);
45 Flush the Block Device.
47 @param This Indicates a pointer to the calling context.
49 @retval EFI_SUCCESS All outstanding data was written to the device
50 @retval EFI_DEVICE_ERROR The device reported an error while writting back the data
51 @retval EFI_NO_MEDIA There is no media in the device.
57 IN EFI_BLOCK_IO_PROTOCOL
*This
67 Common report status code interface.
69 @param This Pointer of FDC_BLK_IO_DEV instance
70 @param Read Read or write operation when error occurrs
74 IN EFI_BLOCK_IO_PROTOCOL
*This
,
78 FDC_BLK_IO_DEV
*FdcDev
;
80 FdcDev
= FDD_BLK_IO_FROM_THIS (This
);
82 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
84 ((Read
) ? EFI_P_EC_INPUT_ERROR
: EFI_P_EC_OUTPUT_ERROR
) | EFI_PERIPHERAL_REMOVABLE_MEDIA
,
90 Read BufferSize bytes from Lba into Buffer.
92 @param This Indicates a pointer to the calling context.
93 @param MediaId Id of the media, changes every time the media is replaced.
94 @param Lba The starting Logical Block Address to read from
95 @param BufferSize Size of Buffer, must be a multiple of device block size.
96 @param Buffer A pointer to the destination buffer for the data. The caller is
97 responsible for either having implicit or explicit ownership of the buffer.
99 @retval EFI_SUCCESS The data was read correctly from the device.
100 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
101 @retval EFI_NO_MEDIA There is no media in the device.
102 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
103 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
104 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
105 or the buffer is not on proper alignment.
111 IN EFI_BLOCK_IO_PROTOCOL
*This
,
120 Status
= FddReadWriteBlocks (This
, MediaId
, Lba
, BufferSize
, READ
, Buffer
);
122 if (EFI_ERROR (Status
)) {
123 FddReportStatus (This
, TRUE
);
130 Write BufferSize bytes from Lba into Buffer.
132 @param This Indicates a pointer to the calling context.
133 @param MediaId The media ID that the write request is for.
134 @param Lba The starting logical block address to be written. The caller is
135 responsible for writing to only legitimate locations.
136 @param BufferSize Size of Buffer, must be a multiple of device block size.
137 @param Buffer A pointer to the source buffer for the data.
139 @retval EFI_SUCCESS The data was written correctly to the device.
140 @retval EFI_WRITE_PROTECTED The device can not be written to.
141 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
142 @retval EFI_NO_MEDIA There is no media in the device.
143 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
144 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
145 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
146 or the buffer is not on proper alignment.
152 IN EFI_BLOCK_IO_PROTOCOL
*This
,
161 Status
= FddReadWriteBlocks (This
, MediaId
, Lba
, BufferSize
, WRITE
, Buffer
);
163 if (EFI_ERROR (Status
)) {
164 FddReportStatus (This
, FALSE
);
171 Read or Write a number of blocks to floppy disk
173 @param This Indicates a pointer to the calling context.
174 @param MediaId Id of the media, changes every time the media is replaced.
175 @param Lba The starting Logical Block Address to read from
176 @param BufferSize Size of Buffer, must be a multiple of device block size.
177 @param Operation Specifies the read or write operation.
178 @param Buffer A pointer to the destination buffer for the data. The caller is
179 responsible for either having implicit or explicit ownership of the buffer.
181 @retval EFI_SUCCESS The data was read correctly from the device.
182 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
183 @retval EFI_NO_MEDIA There is no media in the device.
184 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
185 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
186 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
187 or the buffer is not on proper alignment.
188 @retval EFI_WRITE_PROTECTED The device can not be written to.
193 IN EFI_BLOCK_IO_PROTOCOL
*This
,
197 IN BOOLEAN Operation
,
201 EFI_BLOCK_IO_MEDIA
*Media
;
202 FDC_BLK_IO_DEV
*FdcDev
;
204 UINTN NumberOfBlocks
;
211 // Get the intrinsic block size
214 BlockSize
= Media
->BlockSize
;
215 FdcDev
= FDD_BLK_IO_FROM_THIS (This
);
217 if (Operation
== WRITE
) {
219 FdcFreeCache (FdcDev
);
224 // Set the drive motor on
226 Status
= MotorOn (FdcDev
);
227 if (EFI_ERROR (Status
)) {
228 return EFI_DEVICE_ERROR
;
231 // Check to see if media can be detected
233 Status
= DetectMedia (FdcDev
);
234 if (EFI_ERROR (Status
)) {
236 FdcFreeCache (FdcDev
);
237 return EFI_DEVICE_ERROR
;
240 // Check to see if media is present
242 if (!(Media
->MediaPresent
)) {
244 FdcFreeCache (FdcDev
);
248 // Check to see if media has been changed
250 if (MediaId
!= Media
->MediaId
) {
252 FdcFreeCache (FdcDev
);
253 return EFI_MEDIA_CHANGED
;
256 if (BufferSize
== 0) {
261 if (Operation
== WRITE
) {
262 if (Media
->ReadOnly
) {
264 return EFI_WRITE_PROTECTED
;
268 // Check the parameters for this read/write operation
270 if (Buffer
== NULL
) {
272 return EFI_INVALID_PARAMETER
;
275 if (BufferSize
% BlockSize
!= 0) {
277 return EFI_BAD_BUFFER_SIZE
;
280 if (Lba
> Media
->LastBlock
) {
282 return EFI_INVALID_PARAMETER
;
285 if (((BufferSize
/ BlockSize
) + Lba
- 1) > Media
->LastBlock
) {
287 return EFI_INVALID_PARAMETER
;
290 if (Operation
== READ
) {
292 // See if the data that is being read is already in the cache
294 if (FdcDev
->Cache
!= NULL
) {
295 if (Lba
== 0 && BufferSize
== BlockSize
) {
297 CopyMem ((UINT8
*) Buffer
, (UINT8
*) FdcDev
->Cache
, BlockSize
);
303 // Set up Floppy Disk Controller
305 Status
= Setup (FdcDev
);
306 if (EFI_ERROR (Status
)) {
308 return EFI_DEVICE_ERROR
;
311 NumberOfBlocks
= BufferSize
/ BlockSize
;
316 // read blocks in the same cylinder.
317 // in a cylinder , there are 18 * 2 = 36 blocks
319 BlockCount
= GetTransferBlockCount (FdcDev
, Lba
, NumberOfBlocks
);
320 while ((BlockCount
!= 0) && !EFI_ERROR (Status
)) {
321 Status
= ReadWriteDataSector (FdcDev
, Buffer
, Lba
, BlockCount
, Operation
);
322 if (EFI_ERROR (Status
)) {
325 return EFI_DEVICE_ERROR
;
329 NumberOfBlocks
-= BlockCount
;
330 Buffer
= (VOID
*) ((UINTN
) Buffer
+ BlockCount
* BlockSize
);
331 BlockCount
= GetTransferBlockCount (FdcDev
, Lba
, NumberOfBlocks
);
337 // Turn the motor off
341 if (Operation
== READ
) {
343 // Cache the data read
345 if (Lba0
== 0 && FdcDev
->Cache
== NULL
) {
346 FdcDev
->Cache
= AllocateCopyPool (BlockSize
, Buffer
);
355 Free cache for a floppy disk.
357 @param FdcDev A Pointer to FDC_BLK_IO_DEV instance
362 IN FDC_BLK_IO_DEV
*FdcDev
365 if (FdcDev
->Cache
!= NULL
) {
366 FreePool (FdcDev
->Cache
);
367 FdcDev
->Cache
= NULL
;