[PATCH v2 20/32] swim: Check drive ready bit

From: Finn Thain

Date: Sun Aug 16 2026 - 21:59:54 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")
Reviewed-by: Laurent Vivier <laurent@xxxxxxxxx>
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 36e28a766a5a..987e43e5b4ef 100644
--- a/drivers/block/swim.c
+++ b/drivers/block/swim.c
@@ -117,7 +117,7 @@ struct iwm {
#define TACHO 0x103
#define READ_DATA_1 0x104
#define GCR_MODE 0x105
-#define SEEK_COMPLETE 0x106
+#define READY 0x106
#define TWOMEG_MEDIA 0x107

/* Bits in handshake register */
@@ -313,6 +313,14 @@ static inline bool swim_readbit(struct swim __iomem *base, int bit)
#define swim_readbit_timeout(base, bit, val, timeout_us) \
poll_timeout_us(, swim_readbit(base, bit) == val, 1000, 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)
{
@@ -351,8 +359,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)
@@ -387,20 +393,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;
}

@@ -482,6 +493,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;
@@ -602,6 +615,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