diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2018-04-11 20:50:14 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-04-16 23:49:35 -0400 |
commit | 5a13388d7aa1177b98d7168330ecbeeac52f844d (patch) | |
tree | 904df7828bd422cd725e53379d8ac96dbc01f19d | |
parent | 8a500df63d07d8aee44b7ee2c54e462e47ce93ec (diff) |
block/swim: Fix IO error at end of medium
Reading to the end of a 720K disk results in an IO error instead of EOF
because the block layer thinks the disk has 2880 sectors. (Partly this
is a result of inverted logic of the ONEMEG_MEDIA bit that's now fixed.)
Initialize the density and head count in swim_add_floppy() to agree
with the device size passed to set_capacity() during drive probe.
Call set_capacity() again upon device open, after refreshing the density
and head count values.
Cc: Laurent Vivier <lvivier@redhat.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: stable@vger.kernel.org # v4.14+
Tested-by: Stan Johnson <userm57@yahoo.com>
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Acked-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | drivers/block/swim.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/block/swim.c b/drivers/block/swim.c index c8c8b9da3edd..2c75761b61e8 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c | |||
@@ -612,7 +612,6 @@ static void setup_medium(struct floppy_state *fs) | |||
612 | struct floppy_struct *g; | 612 | struct floppy_struct *g; |
613 | fs->disk_in = 1; | 613 | fs->disk_in = 1; |
614 | fs->write_protected = swim_readbit(base, WRITE_PROT); | 614 | fs->write_protected = swim_readbit(base, WRITE_PROT); |
615 | fs->type = swim_readbit(base, TWOMEG_MEDIA); | ||
616 | 615 | ||
617 | if (swim_track00(base)) | 616 | if (swim_track00(base)) |
618 | printk(KERN_ERR | 617 | printk(KERN_ERR |
@@ -620,6 +619,9 @@ static void setup_medium(struct floppy_state *fs) | |||
620 | 619 | ||
621 | swim_track00(base); | 620 | swim_track00(base); |
622 | 621 | ||
622 | fs->type = swim_readbit(base, TWOMEG_MEDIA) ? | ||
623 | HD_MEDIA : DD_MEDIA; | ||
624 | fs->head_number = swim_readbit(base, SINGLE_SIDED) ? 1 : 2; | ||
623 | get_floppy_geometry(fs, 0, &g); | 625 | get_floppy_geometry(fs, 0, &g); |
624 | fs->total_secs = g->size; | 626 | fs->total_secs = g->size; |
625 | fs->secpercyl = g->head * g->sect; | 627 | fs->secpercyl = g->head * g->sect; |
@@ -656,6 +658,8 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
656 | goto out; | 658 | goto out; |
657 | } | 659 | } |
658 | 660 | ||
661 | set_capacity(fs->disk, fs->total_secs); | ||
662 | |||
659 | if (mode & FMODE_NDELAY) | 663 | if (mode & FMODE_NDELAY) |
660 | return 0; | 664 | return 0; |
661 | 665 | ||
@@ -808,10 +812,9 @@ static int swim_add_floppy(struct swim_priv *swd, enum drive_location location) | |||
808 | 812 | ||
809 | swim_motor(base, OFF); | 813 | swim_motor(base, OFF); |
810 | 814 | ||
811 | if (swim_readbit(base, SINGLE_SIDED)) | 815 | fs->type = HD_MEDIA; |
812 | fs->head_number = 1; | 816 | fs->head_number = 2; |
813 | else | 817 | |
814 | fs->head_number = 2; | ||
815 | fs->ref_count = 0; | 818 | fs->ref_count = 0; |
816 | fs->ejected = 1; | 819 | fs->ejected = 1; |
817 | 820 | ||