[PATCH 20/31] swim: Check drive ready bit
From: Finn Thain
Date: Thu Jul 16 2026 - 06:27:37 EST
The drive provides a readiness signal that has to be tested before
certain commands are issued to the drive. Rename the SEEK_COMPLETE flag
as READY because that's how it's known in the documentation as well as
the mkLinux source code.
Poll for that signal after stepping the heads and also after switching
to MFM mode, as that's what mkLinux does. Check for readiness when
stepping because testing shows that some drives require this.
Fixes: 8852ecd97488 ("m68k: mac - Add SWIM floppy support")
Signed-off-by: Finn Thain <fthain@xxxxxxxxxxxxxx>
---
drivers/block/swim.c | 29 ++++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
index c10ad1266c3b..77d7ac3765ae 100644
--- a/drivers/block/swim.c
+++ b/drivers/block/swim.c
@@ -117,7 +117,7 @@ struct iwm {
#define TACHO 0x1F3
#define READ_DATA_1 0x1F4
#define GCR_MODE 0x1F5
-#define SEEK_COMPLETE 0x1F6
+#define READY 0x1F6
#define TWOMEG_MEDIA 0x1F7
/* Bits in handshake register */
@@ -316,6 +316,14 @@ static inline bool swim_readbit(struct swim __iomem *base, int bit)
#define swim_readbit_timeout_atomic(base, bit, val, timeout_us) \
poll_timeout_us_atomic(, swim_readbit(base, bit) == val, 1, timeout_us, false)
+#define swim_READY_timeout(base) \
+({ \
+ int ret = swim_readbit_timeout(base, READY, true, 1000 * 1000); \
+ if (ret) \
+ printk(KERN_DEBUG "%s: drive not ready\n", __func__); \
+ ret; \
+})
+
static inline void swim_drive(struct swim __iomem *base,
enum drive_location location)
{
@@ -354,8 +362,6 @@ static inline void swim_eject(struct swim __iomem *base)
static inline void swim_head(struct swim __iomem *base, enum head head)
{
- /* wait drive is ready */
-
if (head == UPPER_HEAD)
swim_select(base, READ_DATA_1);
else if (head == LOWER_HEAD)
@@ -390,20 +396,25 @@ static inline int swim_track00(struct swim __iomem *base)
static inline int swim_seek(struct swim __iomem *base, int step)
{
- if (step == 0)
- return 0;
-
if (step < 0) {
swim_action(base, SEEK_NEGATIVE);
step = -step;
- } else
+ } else if (step > 0)
swim_action(base, SEEK_POSITIVE);
+ swim_READY_timeout(base);
+
+ if (step == 0)
+ return 0;
+
for ( ; step > 0; step--) {
if (swim_step(base))
return -1;
}
+ msleep(30);
+ swim_READY_timeout(base);
+
return 0;
}
@@ -485,6 +496,8 @@ static blk_status_t floppy_read_sectors(struct floppy_state *fs,
swim_drive(base, fs->location);
+ swim_READY_timeout(base);
+
for (i = req_sector; i < req_sector + sectors_nb; i++) {
int x;
track = i / fs->secpercyl;
@@ -605,6 +618,8 @@ static int floppy_open(struct gendisk *disk, blk_mode_t mode)
swim_motor(base, ON);
swim_action(base, SETMFM);
+ msleep(30);
+ swim_READY_timeout(base);
set_capacity(fs->disk, fs->total_secs);
--
2.52.0