Re: [PATCH 05/31] swim: Perform ISM/IWM mode switching according to specs
Laurent Vivier <[email protected]> Mon, 20 Jul 2026 20:20:53 +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 SWIM spec says, "MOTOREN must be low to switch modes" and "after
> switching from ISM to IWM, the very first command must be a clear L7".
>=20
> The ISM spec says, MOTOREN "must not be cleared until after the Action
> bit is cleared". Perform those operations in the correct sequence.
>=20
> When switching to ISM mode, the Mode register has to be selected with a
> particular sequence of bit flips. Set q7 low then q6 low then mtrOff.
>=20
> Fixes: 8852ecd97488 ("m68k: mac - Add SWIM floppy support")
> Signed-off-by: Finn Thain <[email protected]>
> ---
> drivers/block/swim.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>=20
> diff --git a/drivers/block/swim.c b/drivers/block/swim.c
> index f9c59282b81f..7499ff250ca7 100644
> --- a/drivers/block/swim.c
> +++ b/drivers/block/swim.c
> @@ -149,6 +149,7 @@ struct iwm {
> #define ACTION 0x08
> #define WRITE_MODE 0x10
> #define HEDSEL 0x20
> +#define ISM_SELECT 0x40
> #define MOTON 0x80
> =20
> /*--------------------------------------------------------------------=
=2D-------*/
> @@ -223,18 +224,21 @@ extern int swim_read_sector_data(struct swim __iom=
em *base,
> static DEFINE_MUTEX(swim_mutex);
> static inline void set_swim_mode(struct swim __iomem *base, int enable=
)
> {
> - struct iwm __iomem *iwm_base;
> + struct iwm __iomem *iwm_base =3D (struct iwm __iomem *)base;
> unsigned long flags;
> =20
> if (!enable) {
> - swim_write(base, mode0, 0xf8);
> + swim_write(base, mode0, ACTION);
> + swim_write(base, mode0, ENBL1 | ENBL2 | MOTON);
> + swim_write(base, mode0, ISM_SELECT);
> + iwm_read(iwm_base, q7L);
> return;
> }
> =20
> - iwm_base =3D (struct iwm __iomem *)base;
> local_irq_save(flags);
> =20
> iwm_read(iwm_base, q7L);
> + iwm_read(iwm_base, q6L);
> iwm_read(iwm_base, mtrOff);
> iwm_read(iwm_base, q6H);
> =20
Reviewed-by: Laurent Vivier <[email protected]>