aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/floppy.c36
-rw-r--r--include/uapi/linux/fd.h3
2 files changed, 29 insertions, 10 deletions
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 6b29c4422828..2023043ce7c0 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3691,9 +3691,12 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
3691 if (!(mode & FMODE_NDELAY)) { 3691 if (!(mode & FMODE_NDELAY)) {
3692 if (mode & (FMODE_READ|FMODE_WRITE)) { 3692 if (mode & (FMODE_READ|FMODE_WRITE)) {
3693 UDRS->last_checked = 0; 3693 UDRS->last_checked = 0;
3694 clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags);
3694 check_disk_change(bdev); 3695 check_disk_change(bdev);
3695 if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags)) 3696 if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags))
3696 goto out; 3697 goto out;
3698 if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags))
3699 goto out;
3697 } 3700 }
3698 res = -EROFS; 3701 res = -EROFS;
3699 if ((mode & FMODE_WRITE) && 3702 if ((mode & FMODE_WRITE) &&
@@ -3746,17 +3749,29 @@ static unsigned int floppy_check_events(struct gendisk *disk,
3746 * a disk in the drive, and whether that disk is writable. 3749 * a disk in the drive, and whether that disk is writable.
3747 */ 3750 */
3748 3751
3749static void floppy_rb0_complete(struct bio *bio, int err) 3752struct rb0_cbdata {
3753 int drive;
3754 struct completion complete;
3755};
3756
3757static void floppy_rb0_cb(struct bio *bio, int err)
3750{ 3758{
3751 complete((struct completion *)bio->bi_private); 3759 struct rb0_cbdata *cbdata = (struct rb0_cbdata *)bio->bi_private;
3760 int drive = cbdata->drive;
3761
3762 if (err) {
3763 pr_info("floppy: error %d while reading block 0", err);
3764 set_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags);
3765 }
3766 complete(&cbdata->complete);
3752} 3767}
3753 3768
3754static int __floppy_read_block_0(struct block_device *bdev) 3769static int __floppy_read_block_0(struct block_device *bdev, int drive)
3755{ 3770{
3756 struct bio bio; 3771 struct bio bio;
3757 struct bio_vec bio_vec; 3772 struct bio_vec bio_vec;
3758 struct completion complete;
3759 struct page *page; 3773 struct page *page;
3774 struct rb0_cbdata cbdata;
3760 size_t size; 3775 size_t size;
3761 3776
3762 page = alloc_page(GFP_NOIO); 3777 page = alloc_page(GFP_NOIO);
@@ -3769,6 +3784,8 @@ static int __floppy_read_block_0(struct block_device *bdev)
3769 if (!size) 3784 if (!size)
3770 size = 1024; 3785 size = 1024;
3771 3786
3787 cbdata.drive = drive;
3788
3772 bio_init(&bio); 3789 bio_init(&bio);
3773 bio.bi_io_vec = &bio_vec; 3790 bio.bi_io_vec = &bio_vec;
3774 bio_vec.bv_page = page; 3791 bio_vec.bv_page = page;
@@ -3779,13 +3796,14 @@ static int __floppy_read_block_0(struct block_device *bdev)
3779 bio.bi_bdev = bdev; 3796 bio.bi_bdev = bdev;
3780 bio.bi_iter.bi_sector = 0; 3797 bio.bi_iter.bi_sector = 0;
3781 bio.bi_flags = (1 << BIO_QUIET); 3798 bio.bi_flags = (1 << BIO_QUIET);
3782 init_completion(&complete); 3799 bio.bi_private = &cbdata;
3783 bio.bi_private = &complete; 3800 bio.bi_end_io = floppy_rb0_cb;
3784 bio.bi_end_io = floppy_rb0_complete;
3785 3801
3786 submit_bio(READ, &bio); 3802 submit_bio(READ, &bio);
3787 process_fd_request(); 3803 process_fd_request();
3788 wait_for_completion(&complete); 3804
3805 init_completion(&cbdata.complete);
3806 wait_for_completion(&cbdata.complete);
3789 3807
3790 __free_page(page); 3808 __free_page(page);
3791 3809
@@ -3827,7 +3845,7 @@ static int floppy_revalidate(struct gendisk *disk)
3827 UDRS->generation++; 3845 UDRS->generation++;
3828 if (drive_no_geom(drive)) { 3846 if (drive_no_geom(drive)) {
3829 /* auto-sensing */ 3847 /* auto-sensing */
3830 res = __floppy_read_block_0(opened_bdev[drive]); 3848 res = __floppy_read_block_0(opened_bdev[drive], drive);
3831 } else { 3849 } else {
3832 if (cf) 3850 if (cf)
3833 poll_drive(false, FD_RAW_NEED_DISK); 3851 poll_drive(false, FD_RAW_NEED_DISK);
diff --git a/include/uapi/linux/fd.h b/include/uapi/linux/fd.h
index f1f3dd5981b2..84c517cbce90 100644
--- a/include/uapi/linux/fd.h
+++ b/include/uapi/linux/fd.h
@@ -185,7 +185,8 @@ enum {
185 * to clear media change status */ 185 * to clear media change status */
186 FD_UNUSED_BIT, 186 FD_UNUSED_BIT,
187 FD_DISK_CHANGED_BIT, /* disk has been changed since last i/o */ 187 FD_DISK_CHANGED_BIT, /* disk has been changed since last i/o */
188 FD_DISK_WRITABLE_BIT /* disk is writable */ 188 FD_DISK_WRITABLE_BIT, /* disk is writable */
189 FD_OPEN_SHOULD_FAIL_BIT
189}; 190};
190 191
191#define FDSETDRVPRM _IOW(2, 0x90, struct floppy_drive_params) 192#define FDSETDRVPRM _IOW(2, 0x90, struct floppy_drive_params)