Track zero recalibration can be slow and is normally done only once i.e. during system POST or boot-up. Recalibrate once after the drive is probed rather than every time the device is opened. Don't register the drive if recalibration fails. Park the heads before ejecting. Reviewed-by: Laurent Vivier Fixes: 8852ecd97488 ("m68k: mac - Add SWIM floppy support") Signed-off-by: Finn Thain --- Changed since v1: - Refactor swim_add_floppy() slightly. Start spindle motor before recalibration if a disk is loaded. - Change return type of swim_add_floppy() to void. - Park heads at track 40 because that's what MacOS does. --- drivers/block/swim.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/block/swim.c b/drivers/block/swim.c index 6a49fc51f5d2..9abf93bc0980 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -412,6 +412,7 @@ static inline int swim_track00(struct swim __iomem *base) if (swim_readbit(base, TRACK_ZERO)) return 0; + pr_err("swim: track zero recalibration failed\n"); return -1; } @@ -456,6 +457,7 @@ static int floppy_eject(struct floppy_state *fs) struct swim __iomem *base = fs->swd->base; swim_drive(base, fs->location); + swim_track(fs, 40); swim_motor(base, OFF); swim_eject(base); swim_drive(base, NO_DRIVE); @@ -596,13 +598,6 @@ static void setup_medium(struct floppy_state *fs) struct floppy_struct *g; fs->disk_in = 1; fs->write_protected = swim_readbit(base, WRITE_PROT); - - if (swim_track00(base)) - printk(KERN_ERR - "SWIM: cannot move floppy head to track 0\n"); - - swim_track00(base); - fs->type = swim_readbit(base, TWOMEG_MEDIA) ? HD_MEDIA : DD_MEDIA; fs->head_number = swim_readbit(base, SINGLE_SIDED) ? 1 : 2; @@ -610,7 +605,6 @@ static void setup_medium(struct floppy_state *fs) fs->total_secs = g->size; fs->secpercyl = g->head * g->sect; fs->secpertrack = g->sect; - fs->track = 0; } else { fs->disk_in = 0; } @@ -759,24 +753,33 @@ static const struct block_device_operations floppy_fops = { .check_events = floppy_check_events, }; -static int swim_add_floppy(struct swim_priv *swd, enum drive_location location) +static void swim_add_floppy(struct swim_priv *swd, enum drive_location location) { struct floppy_state *fs = &swd->unit[swd->floppy_count]; struct swim __iomem *base = swd->base; - fs->location = location; + swim_drive(base, location); + if (!swim_readbit(base, DRIVE_PRESENT) || + swim_readbit(base, ONEMEG_DRIVE)) + goto out; + if (swim_readbit(base, DISK_IN)) + swim_motor(base, ON); + if (swim_track00(base)) + goto out; - swim_motor(base, OFF); + fs->location = location; fs->type = HD_MEDIA; fs->head_number = 2; fs->ref_count = 0; fs->ejected = 1; + fs->track = 0; swd->floppy_count++; - return 0; +out: + swim_motor(base, OFF); } static const struct blk_mq_ops swim_mq_ops = { @@ -825,14 +828,8 @@ static int swim_floppy_init(struct platform_device *pdev) /* scan floppy drives */ - swim_drive(base, INTERNAL_DRIVE); - if (swim_readbit(base, DRIVE_PRESENT) && - !swim_readbit(base, ONEMEG_DRIVE)) - swim_add_floppy(swd, INTERNAL_DRIVE); - swim_drive(base, EXTERNAL_DRIVE); - if (swim_readbit(base, DRIVE_PRESENT) && - !swim_readbit(base, ONEMEG_DRIVE)) - swim_add_floppy(swd, EXTERNAL_DRIVE); + swim_add_floppy(swd, INTERNAL_DRIVE); + swim_add_floppy(swd, EXTERNAL_DRIVE); swim_drive(base, NO_DRIVE); /* register floppy drives */ -- 2.52.0