Re: [PATCH 20/31] swim: Check drive ready bit

Laurent Vivier <[email protected]>
Newsgroups org.kernel.vger.linux-block,org.kernel.vger.linux-kernel,org.kernel.vger.linux-m68k
Message-ID <[email protected]>
Le 16/07/2026 à 12:02, Finn Thain a écrit :
> 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 <[email protected]>
> ---
>   drivers/block/swim.c | 29 ++++++++++++++++++++++-------
>   1 file changed, 22 insertions(+), 7 deletions(-)

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

> 
> 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);
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.