Re: [PATCH 20/31] swim: Check drive ready bit
Laurent Vivier <[email protected]> Sun, 26 Jul 2026 16:48:29 +0200
| Newsgroups | org.kernel.vger.linux-m68k,org.kernel.vger.linux-block,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Le 16/07/2026 =C3=A0 12:02, Finn Thain a =C3=A9crit=C2=A0:
> 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.
>=20
> 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.
>=20
> Fixes: 8852ecd97488 ("m68k: mac - Add SWIM floppy support")
> Signed-off-by: Finn Thain <[email protected]>
> ---
> drivers/block/swim.c | 29 ++++++++++++++++++++++-------
> 1 file changed, 22 insertions(+), 7 deletions(-)
Reviewed-by: Laurent Vivier <[email protected]>
>=20
> 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
> =20
> /* 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) =3D=3D val, 1, timeo=
ut_us, false)
> =20
> +#define swim_READY_timeout(base) \
> +({ \
> + int ret =3D 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 *b=
ase)
> =20
> static inline void swim_head(struct swim __iomem *base, enum head head=
)
> {
> - /* wait drive is ready */
> -
> if (head =3D=3D UPPER_HEAD)
> swim_select(base, READ_DATA_1);
> else if (head =3D=3D LOWER_HEAD)
> @@ -390,20 +396,25 @@ static inline int swim_track00(struct swim __iomem=
*base)
> =20
> static inline int swim_seek(struct swim __iomem *base, int step)
> {
> - if (step =3D=3D 0)
> - return 0;
> -
> if (step < 0) {
> swim_action(base, SEEK_NEGATIVE);
> step =3D -step;
> - } else
> + } else if (step > 0)
> swim_action(base, SEEK_POSITIVE);
> =20
> + swim_READY_timeout(base);
> +
> + if (step =3D=3D 0)
> + return 0;
> +
> for ( ; step > 0; step--) {
> if (swim_step(base))
> return -1;
> }
> =20
> + msleep(30);
> + swim_READY_timeout(base);
> +
> return 0;
> }
> =20
> @@ -485,6 +496,8 @@ static blk_status_t floppy_read_sectors(struct flopp=
y_state *fs,
> =20
> =20
> swim_drive(base, fs->location);
> + swim_READY_timeout(base);
> +
> for (i =3D req_sector; i < req_sector + sectors_nb; i++) {
> int x;
> track =3D i / fs->secpercyl;
> @@ -605,6 +618,8 @@ static int floppy_open(struct gendisk *disk, blk_mod=
e_t mode)
> =20
> swim_motor(base, ON);
> swim_action(base, SETMFM);
> + msleep(30);
> + swim_READY_timeout(base);
> =20
> set_capacity(fs->disk, fs->total_secs);
> =20