Re: [PATCH 01/31] swim: Assert strobe with stable outputs

Laurent Vivier <[email protected]> Mon, 20 Jul 2026 15:22: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:
> Inside Macintosh says, "Be sure that you don't change CA0-CA2 or SEL
> while LSTRB is high". Unfortunately, those bits do change. The CA0-CA2
> outputs become inputs when (LSTRB << 4) | LSTRB gets written to the
> phase register. Then when LSTRB is driven low, CA0-CA2 get driven high.
>=20
> This is a problem because the drive interprets a STEP command as an
> EJECT command when these pins float high. This occurs intermittently,
> perhaps because interrupts are disabled and the race condition happens
> to end well. However, when I add code to step the heads with interrupts
> enabled, the disk always ejects.
>=20
> Keep the four phase pin directions set to output and hold their levels
> constant during LSTRB signalling.

Perhaps you can also add a short comment to describe the changes you made =
to the defines.

Reviewed-by: Laurent Vivier <[email protected]>

Thansk,
Laurent

> Fixes: 8852ecd97488 ("m68k: mac - Add SWIM floppy support")
> Signed-off-by: Finn Thain <[email protected]>
> ---
>   drivers/block/swim.c | 52 ++++++++++++++++++++++----------------------
>   1 file changed, 26 insertions(+), 26 deletions(-)
>=20
> diff --git a/drivers/block/swim.c b/drivers/block/swim.c
> index 0ccc12a72388..b61e92d0e3e9 100644
> --- a/drivers/block/swim.c
> +++ b/drivers/block/swim.c
> @@ -89,35 +89,35 @@ struct iwm {
>  =20
>   /* bits in phase register */
>  =20
> -#define SEEK_POSITIVE	0x070
> -#define SEEK_NEGATIVE	0x074
> -#define STEP		0x071
> -#define MOTOR_ON	0x072
> -#define MOTOR_OFF	0x076
> -#define INDEX		0x073
> -#define EJECT		0x077
> -#define SETMFM		0x171
> -#define SETGCR		0x175
> +#define SEEK_POSITIVE	0x0F0
> +#define SEEK_NEGATIVE	0x0F4
> +#define STEP		0x0F1
> +#define MOTOR_ON	0x0F2
> +#define MOTOR_OFF	0x0F6
> +#define INDEX		0x0F3
> +#define EJECT		0x0F7
> +#define SETMFM		0x1F1
> +#define SETGCR		0x1F5
>  =20
> -#define RELAX		0x033
> -#define LSTRB		0x008
> +#define RELAX		0x0F3
> +#define LSTRB		0x0F8
>  =20
> -#define CA_MASK		0x077
> +#define CA_MASK		0x0F7
>  =20
>   /* Select values for swim_select and swim_readbit */
>  =20
> -#define READ_DATA_0	0x074
> -#define ONEMEG_DRIVE	0x075
> -#define SINGLE_SIDED	0x076
> -#define DRIVE_PRESENT	0x077
> -#define DISK_IN		0x170
> -#define WRITE_PROT	0x171
> -#define TRACK_ZERO	0x172
> -#define TACHO		0x173
> -#define READ_DATA_1	0x174
> -#define GCR_MODE	0x175
> -#define SEEK_COMPLETE	0x176
> -#define TWOMEG_MEDIA	0x177
> +#define READ_DATA_0	0x0F4
> +#define ONEMEG_DRIVE	0x0F5
> +#define SINGLE_SIDED	0x0F6
> +#define DRIVE_PRESENT	0x0F7
> +#define DISK_IN		0x1F0
> +#define WRITE_PROT	0x1F1
> +#define TRACK_ZERO	0x1F2
> +#define TACHO		0x1F3
> +#define READ_DATA_1	0x1F4
> +#define GCR_MODE	0x1F5
> +#define SEEK_COMPLETE	0x1F6
> +#define TWOMEG_MEDIA	0x1F7
>  =20
>   /* Bits in handshake register */
>  =20
> @@ -284,9 +284,9 @@ static inline void swim_action(struct swim __iomem *=
base, int action)
>  =20
>   	swim_select(base, action);
>   	udelay(1);
> -	swim_write(base, phase, (LSTRB<<4) | LSTRB);
> +	swim_write(base, phase, action | LSTRB);
>   	udelay(1);
> -	swim_write(base, phase, (LSTRB<<4) | ((~LSTRB) & 0x0F));
> +	swim_write(base, phase, action);
>   	udelay(1);
>  =20
>   	local_irq_restore(flags);