+++ /dev/null
-From b777f4c47781df6b23e3f4df6fdb92d9aceac7bb Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Wed, 21 Apr 2021 13:19:45 +0300
-Subject: ataflop: fix off by one in ataflop_probe()
-
-From: Dan Carpenter <dan.carpenter@oracle.com>
-
-commit b777f4c47781df6b23e3f4df6fdb92d9aceac7bb upstream.
-
-Smatch complains that the "type > NUM_DISK_MINORS" should be >=
-instead of >. We also need to subtract one from "type" at the start.
-
-Fixes: bf9c0538e485 ("ataflop: use a separate gendisk for each media format")
-Reported-by: kernel test robot <lkp@intel.com>
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-Reviewed-by: Christoph Hellwig <hch@lst.de>
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/block/ataflop.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/drivers/block/ataflop.c
-+++ b/drivers/block/ataflop.c
-@@ -2023,7 +2023,10 @@ static void ataflop_probe(dev_t dev)
- int drive = MINOR(dev) & 3;
- int type = MINOR(dev) >> 2;
-
-- if (drive >= FD_MAX_UNITS || type > NUM_DISK_MINORS)
-+ if (type)
-+ type--;
-+
-+ if (drive >= FD_MAX_UNITS || type >= NUM_DISK_MINORS)
- return;
- mutex_lock(&ataflop_probe_lock);
- if (!unit[drive].disk[type]) {
+++ /dev/null
-From 57e77a3cd843f54a00814bf8e1378fe1645fa118 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 21 Apr 2021 13:18:35 +0300
-Subject: ataflop: potential out of bounds in do_format()
-
-From: Dan Carpenter <dan.carpenter@oracle.com>
-
-[ Upstream commit 1ffec389a6431782a8a28805830b6fae9bf00af1 ]
-
-The function uses "type" as an array index:
-
- q = unit[drive].disk[type]->queue;
-
-Unfortunately the bounds check on "type" isn't done until later in the
-function. Fix this by moving the bounds check to the start.
-
-Fixes: bf9c0538e485 ("ataflop: use a separate gendisk for each media format")
-Reported-by: kernel test robot <lkp@intel.com>
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-Reviewed-by: Christoph Hellwig <hch@lst.de>
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/block/ataflop.c | 11 +++++------
- 1 file changed, 5 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
-index e6264db11e415..0a86f9d3a3798 100644
---- a/drivers/block/ataflop.c
-+++ b/drivers/block/ataflop.c
-@@ -726,8 +726,12 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)
- unsigned long flags;
- int ret;
-
-- if (type)
-+ if (type) {
- type--;
-+ if (type >= NUM_DISK_MINORS ||
-+ minor2disktype[type].drive_types > DriveType)
-+ return -EINVAL;
-+ }
-
- q = unit[drive].disk[type]->queue;
- blk_mq_freeze_queue(q);
-@@ -739,11 +743,6 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)
- local_irq_restore(flags);
-
- if (type) {
-- if (type >= NUM_DISK_MINORS ||
-- minor2disktype[type].drive_types > DriveType) {
-- ret = -EINVAL;
-- goto out;
-- }
- type = minor2disktype[type].index;
- UDT = &atari_disk_type[type];
- }
---
-2.33.0
-
+++ /dev/null
-From 733dd2e9a54e23a799a415b865b86ac53477e175 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 29 Oct 2020 15:58:38 +0100
-Subject: ataflop: use a separate gendisk for each media format
-
-From: Christoph Hellwig <hch@lst.de>
-
-[ Upstream commit bf9c0538e485b591a2ee02d9adb8a99db4be5a2a ]
-
-The Atari floppy driver usually autodetects the media when used with the
-ormal /dev/fd? devices, which also are the only nodes created by udev.
-But it also supports various aliases that force a given media format.
-That is currently supported using the blk_register_region framework
-which finds the floppy gendisk even for a 'mismatched' dev_t. The
-problem with this (besides the code complexity) is that it creates
-multiple struct block_device instances for the whole device of a
-single gendisk, which can lead to interesting issues in code not
-aware of that fact.
-
-To fix this just create a separate gendisk for each of the aliases
-if they are accessed.
-
-Signed-off-by: Christoph Hellwig <hch@lst.de>
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/block/ataflop.c | 135 +++++++++++++++++++++++++---------------
- 1 file changed, 86 insertions(+), 49 deletions(-)
-
-diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
-index cd612cd04767a..e6264db11e415 100644
---- a/drivers/block/ataflop.c
-+++ b/drivers/block/ataflop.c
-@@ -297,7 +297,7 @@ static struct atari_floppy_struct {
- unsigned int wpstat; /* current state of WP signal (for
- disk change detection) */
- int flags; /* flags */
-- struct gendisk *disk;
-+ struct gendisk *disk[NUM_DISK_MINORS];
- int ref;
- int type;
- struct blk_mq_tag_set tag_set;
-@@ -720,12 +720,16 @@ static void fd_error( void )
-
- static int do_format(int drive, int type, struct atari_format_descr *desc)
- {
-- struct request_queue *q = unit[drive].disk->queue;
-+ struct request_queue *q;
- unsigned char *p;
- int sect, nsect;
- unsigned long flags;
- int ret;
-
-+ if (type)
-+ type--;
-+
-+ q = unit[drive].disk[type]->queue;
- blk_mq_freeze_queue(q);
- blk_mq_quiesce_queue(q);
-
-@@ -735,7 +739,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)
- local_irq_restore(flags);
-
- if (type) {
-- if (--type >= NUM_DISK_MINORS ||
-+ if (type >= NUM_DISK_MINORS ||
- minor2disktype[type].drive_types > DriveType) {
- ret = -EINVAL;
- goto out;
-@@ -1151,7 +1155,7 @@ static void fd_rwsec_done1(int status)
- if (SUDT[-1].blocks > ReqBlock) {
- /* try another disk type */
- SUDT--;
-- set_capacity(unit[SelectedDrive].disk,
-+ set_capacity(unit[SelectedDrive].disk[0],
- SUDT->blocks);
- } else
- Probing = 0;
-@@ -1166,7 +1170,7 @@ static void fd_rwsec_done1(int status)
- /* record not found, but not probing. Maybe stretch wrong ? Restart probing */
- if (SUD.autoprobe) {
- SUDT = atari_disk_type + StartDiskType[DriveType];
-- set_capacity(unit[SelectedDrive].disk,
-+ set_capacity(unit[SelectedDrive].disk[0],
- SUDT->blocks);
- Probing = 1;
- }
-@@ -1506,7 +1510,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
- if (!UDT) {
- Probing = 1;
- UDT = atari_disk_type + StartDiskType[DriveType];
-- set_capacity(floppy->disk, UDT->blocks);
-+ set_capacity(bd->rq->rq_disk, UDT->blocks);
- UD.autoprobe = 1;
- }
- }
-@@ -1524,7 +1528,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
- }
- type = minor2disktype[type].index;
- UDT = &atari_disk_type[type];
-- set_capacity(floppy->disk, UDT->blocks);
-+ set_capacity(bd->rq->rq_disk, UDT->blocks);
- UD.autoprobe = 0;
- }
-
-@@ -1647,7 +1651,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
- printk (KERN_INFO "floppy%d: setting %s %p!\n",
- drive, dtp->name, dtp);
- UDT = dtp;
-- set_capacity(floppy->disk, UDT->blocks);
-+ set_capacity(disk, UDT->blocks);
-
- if (cmd == FDDEFPRM) {
- /* save settings as permanent default type */
-@@ -1691,7 +1695,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
- return -EINVAL;
-
- UDT = dtp;
-- set_capacity(floppy->disk, UDT->blocks);
-+ set_capacity(disk, UDT->blocks);
-
- return 0;
- case FDMSGON:
-@@ -1714,7 +1718,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
- UDT = NULL;
- /* MSch: invalidate default_params */
- default_params[drive].blocks = 0;
-- set_capacity(floppy->disk, MAX_DISK_SIZE * 2);
-+ set_capacity(disk, MAX_DISK_SIZE * 2);
- fallthrough;
- case FDFMTEND:
- case FDFLUSH:
-@@ -1950,14 +1954,50 @@ static const struct blk_mq_ops ataflop_mq_ops = {
- .queue_rq = ataflop_queue_rq,
- };
-
--static struct kobject *floppy_find(dev_t dev, int *part, void *data)
-+static int ataflop_alloc_disk(unsigned int drive, unsigned int type)
- {
-- int drive = *part & 3;
-- int type = *part >> 2;
-+ struct gendisk *disk;
-+ int ret;
-+
-+ disk = alloc_disk(1);
-+ if (!disk)
-+ return -ENOMEM;
-+
-+ disk->queue = blk_mq_init_queue(&unit[drive].tag_set);
-+ if (IS_ERR(disk->queue)) {
-+ ret = PTR_ERR(disk->queue);
-+ disk->queue = NULL;
-+ put_disk(disk);
-+ return ret;
-+ }
-+
-+ disk->major = FLOPPY_MAJOR;
-+ disk->first_minor = drive + (type << 2);
-+ sprintf(disk->disk_name, "fd%d", drive);
-+ disk->fops = &floppy_fops;
-+ disk->events = DISK_EVENT_MEDIA_CHANGE;
-+ disk->private_data = &unit[drive];
-+ set_capacity(disk, MAX_DISK_SIZE * 2);
-+
-+ unit[drive].disk[type] = disk;
-+ return 0;
-+}
-+
-+static DEFINE_MUTEX(ataflop_probe_lock);
-+
-+static void ataflop_probe(dev_t dev)
-+{
-+ int drive = MINOR(dev) & 3;
-+ int type = MINOR(dev) >> 2;
-+
- if (drive >= FD_MAX_UNITS || type > NUM_DISK_MINORS)
-- return NULL;
-- *part = 0;
-- return get_disk_and_module(unit[drive].disk);
-+ return;
-+ mutex_lock(&ataflop_probe_lock);
-+ if (!unit[drive].disk[type]) {
-+ if (ataflop_alloc_disk(drive, type) == 0)
-+ add_disk(unit[drive].disk[type]);
-+ }
-+ mutex_unlock(&ataflop_probe_lock);
- }
-
- static int __init atari_floppy_init (void)
-@@ -1969,23 +2009,26 @@ static int __init atari_floppy_init (void)
- /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */
- return -ENODEV;
-
-- if (register_blkdev(FLOPPY_MAJOR,"fd"))
-- return -EBUSY;
-+ mutex_lock(&ataflop_probe_lock);
-+ ret = __register_blkdev(FLOPPY_MAJOR, "fd", ataflop_probe);
-+ if (ret)
-+ goto out_unlock;
-
- for (i = 0; i < FD_MAX_UNITS; i++) {
-- unit[i].disk = alloc_disk(1);
-- if (!unit[i].disk) {
-- ret = -ENOMEM;
-+ memset(&unit[i].tag_set, 0, sizeof(unit[i].tag_set));
-+ unit[i].tag_set.ops = &ataflop_mq_ops;
-+ unit[i].tag_set.nr_hw_queues = 1;
-+ unit[i].tag_set.nr_maps = 1;
-+ unit[i].tag_set.queue_depth = 2;
-+ unit[i].tag_set.numa_node = NUMA_NO_NODE;
-+ unit[i].tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
-+ ret = blk_mq_alloc_tag_set(&unit[i].tag_set);
-+ if (ret)
- goto err;
-- }
-
-- unit[i].disk->queue = blk_mq_init_sq_queue(&unit[i].tag_set,
-- &ataflop_mq_ops, 2,
-- BLK_MQ_F_SHOULD_MERGE);
-- if (IS_ERR(unit[i].disk->queue)) {
-- put_disk(unit[i].disk);
-- ret = PTR_ERR(unit[i].disk->queue);
-- unit[i].disk->queue = NULL;
-+ ret = ataflop_alloc_disk(i, 0);
-+ if (ret) {
-+ blk_mq_free_tag_set(&unit[i].tag_set);
- goto err;
- }
- }
-@@ -2015,19 +2058,9 @@ static int __init atari_floppy_init (void)
- for (i = 0; i < FD_MAX_UNITS; i++) {
- unit[i].track = -1;
- unit[i].flags = 0;
-- unit[i].disk->major = FLOPPY_MAJOR;
-- unit[i].disk->first_minor = i;
-- sprintf(unit[i].disk->disk_name, "fd%d", i);
-- unit[i].disk->fops = &floppy_fops;
-- unit[i].disk->events = DISK_EVENT_MEDIA_CHANGE;
-- unit[i].disk->private_data = &unit[i];
-- set_capacity(unit[i].disk, MAX_DISK_SIZE * 2);
-- add_disk(unit[i].disk);
-+ add_disk(unit[i].disk[0]);
- }
-
-- blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
-- floppy_find, NULL, NULL);
--
- printk(KERN_INFO "Atari floppy driver: max. %cD, %strack buffering\n",
- DriveType == 0 ? 'D' : DriveType == 1 ? 'H' : 'E',
- UseTrackbuffer ? "" : "no ");
-@@ -2037,14 +2070,14 @@ static int __init atari_floppy_init (void)
-
- err:
- while (--i >= 0) {
-- struct gendisk *disk = unit[i].disk;
--
-- blk_cleanup_queue(disk->queue);
-+ blk_cleanup_queue(unit[i].disk[0]->queue);
-+ put_disk(unit[i].disk[0]);
- blk_mq_free_tag_set(&unit[i].tag_set);
-- put_disk(unit[i].disk);
- }
-
- unregister_blkdev(FLOPPY_MAJOR, "fd");
-+out_unlock:
-+ mutex_unlock(&ataflop_probe_lock);
- return ret;
- }
-
-@@ -2089,13 +2122,17 @@ __setup("floppy=", atari_floppy_setup);
-
- static void __exit atari_floppy_exit(void)
- {
-- int i;
-- blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
-+ int i, type;
-+
- for (i = 0; i < FD_MAX_UNITS; i++) {
-- del_gendisk(unit[i].disk);
-- blk_cleanup_queue(unit[i].disk->queue);
-+ for (type = 0; type < NUM_DISK_MINORS; type++) {
-+ if (!unit[i].disk[type])
-+ continue;
-+ del_gendisk(unit[i].disk[type]);
-+ blk_cleanup_queue(unit[i].disk[type]->queue);
-+ put_disk(unit[i].disk[type]);
-+ }
- blk_mq_free_tag_set(&unit[i].tag_set);
-- put_disk(unit[i].disk);
- }
- unregister_blkdev(FLOPPY_MAJOR, "fd");
-
---
-2.33.0
-
+++ /dev/null
-From ac390f57524e054e6c17ae9ea70c9c34f24d4b7d Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 27 Sep 2021 15:03:00 -0700
-Subject: block/ataflop: add registration bool before calling del_gendisk()
-
-From: Luis Chamberlain <mcgrof@kernel.org>
-
-[ Upstream commit 573effb298011d3fcabc9b12025cf637f8a07911 ]
-
-The ataflop assumes del_gendisk() is safe to call, this is only
-true because add_disk() does not return a failure, but that will
-change soon. And so, before we get to adding error handling for
-that case, let's make sure we keep track of which disks actually
-get registered. Then we use this to only call del_gendisk for them.
-
-Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
-Link: https://lore.kernel.org/r/20210927220302.1073499-13-mcgrof@kernel.org
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/block/ataflop.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
-index 359417a016e43..c8a999086060f 100644
---- a/drivers/block/ataflop.c
-+++ b/drivers/block/ataflop.c
-@@ -298,6 +298,7 @@ static struct atari_floppy_struct {
- disk change detection) */
- int flags; /* flags */
- struct gendisk *disk[NUM_DISK_MINORS];
-+ bool registered[NUM_DISK_MINORS];
- int ref;
- int type;
- struct blk_mq_tag_set tag_set;
-@@ -2026,8 +2027,10 @@ static void ataflop_probe(dev_t dev)
- return;
- mutex_lock(&ataflop_probe_lock);
- if (!unit[drive].disk[type]) {
-- if (ataflop_alloc_disk(drive, type) == 0)
-+ if (ataflop_alloc_disk(drive, type) == 0) {
- add_disk(unit[drive].disk[type]);
-+ unit[drive].registered[type] = true;
-+ }
- }
- mutex_unlock(&ataflop_probe_lock);
- }
-@@ -2091,6 +2094,7 @@ static int __init atari_floppy_init (void)
- unit[i].track = -1;
- unit[i].flags = 0;
- add_disk(unit[i].disk[0]);
-+ unit[i].registered[0] = true;
- }
-
- printk(KERN_INFO "Atari floppy driver: max. %cD, %strack buffering\n",
-@@ -2159,7 +2163,8 @@ static void __exit atari_floppy_exit(void)
- for (type = 0; type < NUM_DISK_MINORS; type++) {
- if (!unit[i].disk[type])
- continue;
-- del_gendisk(unit[i].disk[type]);
-+ if (unit[i].registered[type])
-+ del_gendisk(unit[i].disk[type]);
- blk_cleanup_disk(unit[i].disk[type]);
- }
- blk_mq_free_tag_set(&unit[i].tag_set);
---
-2.33.0
-
+++ /dev/null
-From 09451954ade6946683001515407fa95a9ef916a5 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 19 Oct 2021 19:13:21 +1300
-Subject: block: ataflop: fix breakage introduced at blk-mq refactoring
-
-From: Michael Schmitz <schmitzmic@gmail.com>
-
-[ Upstream commit 86d46fdaa12ae5befc16b8d73fc85a3ca0399ea6 ]
-
-Refactoring of the Atari floppy driver when converting to blk-mq
-has broken the state machine in not-so-subtle ways:
-
-finish_fdc() must be called when operations on the floppy device
-have completed. This is crucial in order to relase the ST-DMA
-lock, which protects against concurrent access to the ST-DMA
-controller by other drivers (some DMA related, most just related
-to device register access - broken beyond compare, I know).
-
-When rewriting the driver's old do_request() function, the fact
-that finish_fdc() was called only when all queued requests had
-completed appears to have been overlooked. Instead, the new
-request function calls finish_fdc() immediately after the last
-request has been queued. finish_fdc() executes a dummy seek after
-most requests, and this overwrites the state machine's interrupt
-hander that was set up to wait for completion of the read/write
-request just prior. To make matters worse, finish_fdc() is called
-before device interrupts are re-enabled, making certain that the
-read/write interupt is missed.
-
-Shifting the finish_fdc() call into the read/write request
-completion handler ensures the driver waits for the request to
-actually complete. With a queue depth of 2, we won't see long
-request sequences, so calling finish_fdc() unconditionally just
-adds a little overhead for the dummy seeks, and keeps the code
-simple.
-
-While we're at it, kill ataflop_commit_rqs() which does nothing
-but run finish_fdc() unconditionally, again likely wiping out an
-in-flight request.
-
-Signed-off-by: Michael Schmitz <schmitzmic@gmail.com>
-Fixes: 6ec3938cff95 ("ataflop: convert to blk-mq")
-CC: linux-block@vger.kernel.org
-CC: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
-Link: https://lore.kernel.org/r/20211019061321.26425-1-schmitzmic@gmail.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/block/ataflop.c | 18 +++---------------
- 1 file changed, 3 insertions(+), 15 deletions(-)
-
-diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
-index 3e881fdb06e0a..cd612cd04767a 100644
---- a/drivers/block/ataflop.c
-+++ b/drivers/block/ataflop.c
-@@ -653,9 +653,6 @@ static inline void copy_buffer(void *from, void *to)
- *p2++ = *p1++;
- }
-
--
--
--
- /* General Interrupt Handling */
-
- static void (*FloppyIRQHandler)( int status ) = NULL;
-@@ -1225,6 +1222,7 @@ static void fd_rwsec_done1(int status)
- }
- else {
- /* all sectors finished */
-+ finish_fdc();
- fd_end_request_cur(BLK_STS_OK);
- }
- return;
-@@ -1472,15 +1470,6 @@ static void setup_req_params( int drive )
- ReqTrack, ReqSector, (unsigned long)ReqData ));
- }
-
--static void ataflop_commit_rqs(struct blk_mq_hw_ctx *hctx)
--{
-- spin_lock_irq(&ataflop_lock);
-- atari_disable_irq(IRQ_MFP_FDC);
-- finish_fdc();
-- atari_enable_irq(IRQ_MFP_FDC);
-- spin_unlock_irq(&ataflop_lock);
--}
--
- static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
- const struct blk_mq_queue_data *bd)
- {
-@@ -1488,6 +1477,8 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
- int drive = floppy - unit;
- int type = floppy->type;
-
-+ DPRINT(("Queue request: drive %d type %d last %d\n", drive, type, bd->last));
-+
- spin_lock_irq(&ataflop_lock);
- if (fd_request) {
- spin_unlock_irq(&ataflop_lock);
-@@ -1547,8 +1538,6 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
- setup_req_params( drive );
- do_fd_action( drive );
-
-- if (bd->last)
-- finish_fdc();
- atari_enable_irq( IRQ_MFP_FDC );
-
- out:
-@@ -1959,7 +1948,6 @@ static const struct block_device_operations floppy_fops = {
-
- static const struct blk_mq_ops ataflop_mq_ops = {
- .queue_rq = ataflop_queue_rq,
-- .commit_rqs = ataflop_commit_rqs,
- };
-
- static struct kobject *floppy_find(dev_t dev, int *part, void *data)
---
-2.33.0
-
+++ /dev/null
-From 4ae8f8216a7e7cceb54e422b521a78f0c9148afc Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 24 Oct 2021 13:20:13 +1300
-Subject: block: ataflop: more blk-mq refactoring fixes
-
-From: Michael Schmitz <schmitzmic@gmail.com>
-
-[ Upstream commit d28e4dff085c5a87025c9a0a85fb798bd8e9ca17 ]
-
-As it turns out, my earlier patch in commit 86d46fdaa12a (block:
-ataflop: fix breakage introduced at blk-mq refactoring) was
-incomplete. This patch fixes any remaining issues found during
-more testing and code review.
-
-Requests exceeding 4 k are handled in 4k segments but
-__blk_mq_end_request() is never called on these (still
-sectors outstanding on the request). With redo_fd_request()
-removed, there is no provision to kick off processing of the
-next segment, causing requests exceeding 4k to hang. (By
-setting /sys/block/fd0/queue/max_sectors_k <= 4 as workaround,
-this behaviour can be avoided).
-
-Instead of reintroducing redo_fd_request(), requeue the remainder
-of the request by calling blk_mq_requeue_request() on incomplete
-requests (i.e. when blk_update_request() still returns true), and
-rely on the block layer to queue the residual as new request.
-
-Both error handling and formatting needs to release the
-ST-DMA lock, so call finish_fdc() on these (this was previously
-handled by redo_fd_request()). finish_fdc() may be called
-legitimately without the ST-DMA lock held - make sure we only
-release the lock if we actually held it. In a similar way,
-early exit due to errors in ataflop_queue_rq() must release
-the lock.
-
-After minor errors, fd_error sets up to recalibrate the drive
-but never re-runs the current operation (another task handled by
-redo_fd_request() before). Call do_fd_action() to get the next
-steps (seek, retry read/write) underway.
-
-Signed-off-by: Michael Schmitz <schmitzmic@gmail.com>
-Fixes: 6ec3938cff95f (ataflop: convert to blk-mq)
-CC: linux-block@vger.kernel.org
-Link: https://lore.kernel.org/r/20211024002013.9332-1-schmitzmic@gmail.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/block/ataflop.c | 45 +++++++++++++++++++++++++++++++++++------
- 1 file changed, 39 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
-index 0a86f9d3a3798..94b76c254db9b 100644
---- a/drivers/block/ataflop.c
-+++ b/drivers/block/ataflop.c
-@@ -456,10 +456,20 @@ static DEFINE_TIMER(fd_timer, check_change);
-
- static void fd_end_request_cur(blk_status_t err)
- {
-+ DPRINT(("fd_end_request_cur(), bytes %d of %d\n",
-+ blk_rq_cur_bytes(fd_request),
-+ blk_rq_bytes(fd_request)));
-+
- if (!blk_update_request(fd_request, err,
- blk_rq_cur_bytes(fd_request))) {
-+ DPRINT(("calling __blk_mq_end_request()\n"));
- __blk_mq_end_request(fd_request, err);
- fd_request = NULL;
-+ } else {
-+ /* requeue rest of request */
-+ DPRINT(("calling blk_mq_requeue_request()\n"));
-+ blk_mq_requeue_request(fd_request, true);
-+ fd_request = NULL;
- }
- }
-
-@@ -697,12 +707,21 @@ static void fd_error( void )
- if (fd_request->error_count >= MAX_ERRORS) {
- printk(KERN_ERR "fd%d: too many errors.\n", SelectedDrive );
- fd_end_request_cur(BLK_STS_IOERR);
-+ finish_fdc();
-+ return;
- }
- else if (fd_request->error_count == RECALIBRATE_ERRORS) {
- printk(KERN_WARNING "fd%d: recalibrating\n", SelectedDrive );
- if (SelectedDrive != -1)
- SUD.track = -1;
- }
-+ /* need to re-run request to recalibrate */
-+ atari_disable_irq( IRQ_MFP_FDC );
-+
-+ setup_req_params( SelectedDrive );
-+ do_fd_action( SelectedDrive );
-+
-+ atari_enable_irq( IRQ_MFP_FDC );
- }
-
-
-@@ -729,8 +748,10 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)
- if (type) {
- type--;
- if (type >= NUM_DISK_MINORS ||
-- minor2disktype[type].drive_types > DriveType)
-+ minor2disktype[type].drive_types > DriveType) {
-+ finish_fdc();
- return -EINVAL;
-+ }
- }
-
- q = unit[drive].disk[type]->queue;
-@@ -748,6 +769,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)
- }
-
- if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) {
-+ finish_fdc();
- ret = -EINVAL;
- goto out;
- }
-@@ -788,6 +810,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)
-
- wait_for_completion(&format_wait);
-
-+ finish_fdc();
- ret = FormatError ? -EIO : 0;
- out:
- blk_mq_unquiesce_queue(q);
-@@ -822,6 +845,7 @@ static void do_fd_action( int drive )
- else {
- /* all sectors finished */
- fd_end_request_cur(BLK_STS_OK);
-+ finish_fdc();
- return;
- }
- }
-@@ -1225,8 +1249,8 @@ static void fd_rwsec_done1(int status)
- }
- else {
- /* all sectors finished */
-- finish_fdc();
- fd_end_request_cur(BLK_STS_OK);
-+ finish_fdc();
- }
- return;
-
-@@ -1348,7 +1372,7 @@ static void fd_times_out(struct timer_list *unused)
-
- static void finish_fdc( void )
- {
-- if (!NeedSeek) {
-+ if (!NeedSeek || !stdma_is_locked_by(floppy_irq)) {
- finish_fdc_done( 0 );
- }
- else {
-@@ -1383,7 +1407,8 @@ static void finish_fdc_done( int dummy )
- start_motor_off_timer();
-
- local_irq_save(flags);
-- stdma_release();
-+ if (stdma_is_locked_by(floppy_irq))
-+ stdma_release();
- local_irq_restore(flags);
-
- DPRINT(("finish_fdc() finished\n"));
-@@ -1480,7 +1505,9 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
- int drive = floppy - unit;
- int type = floppy->type;
-
-- DPRINT(("Queue request: drive %d type %d last %d\n", drive, type, bd->last));
-+ DPRINT(("Queue request: drive %d type %d sectors %d of %d last %d\n",
-+ drive, type, blk_rq_cur_sectors(bd->rq),
-+ blk_rq_sectors(bd->rq), bd->last));
-
- spin_lock_irq(&ataflop_lock);
- if (fd_request) {
-@@ -1502,6 +1529,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
- /* drive not connected */
- printk(KERN_ERR "Unknown Device: fd%d\n", drive );
- fd_end_request_cur(BLK_STS_IOERR);
-+ stdma_release();
- goto out;
- }
-
-@@ -1518,11 +1546,13 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
- if (--type >= NUM_DISK_MINORS) {
- printk(KERN_WARNING "fd%d: invalid disk format", drive );
- fd_end_request_cur(BLK_STS_IOERR);
-+ stdma_release();
- goto out;
- }
- if (minor2disktype[type].drive_types > DriveType) {
- printk(KERN_WARNING "fd%d: unsupported disk format", drive );
- fd_end_request_cur(BLK_STS_IOERR);
-+ stdma_release();
- goto out;
- }
- type = minor2disktype[type].index;
-@@ -1623,6 +1653,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
- /* what if type > 0 here? Overwrite specified entry ? */
- if (type) {
- /* refuse to re-set a predefined type for now */
-+ finish_fdc();
- return -EINVAL;
- }
-
-@@ -1690,8 +1721,10 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
-
- /* sanity check */
- if (setprm.track != dtp->blocks/dtp->spt/2 ||
-- setprm.head != 2)
-+ setprm.head != 2) {
-+ finish_fdc();
- return -EINVAL;
-+ }
-
- UDT = dtp;
- set_capacity(disk, UDT->blocks);
---
-2.33.0
-
+++ /dev/null
-From d24593de8e05bbbaca47ce45586e189d680d2bdc Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 27 Sep 2021 15:03:01 -0700
-Subject: block/ataflop: provide a helper for cleanup up an atari disk
-
-From: Luis Chamberlain <mcgrof@kernel.org>
-
-[ Upstream commit deae1138d04758c7f8939fcb8aee330bc37e3015 ]
-
-Instead of using two separate code paths for cleaning up an atari disk,
-use one. We take the more careful approach to check for *all* disk
-types, as is done on exit. The init path didn't have that check as
-the alternative disk types are only probed for later, they are not
-initialized by default.
-
-Yes, there is a shared tag for all disks.
-
-Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
-Link: https://lore.kernel.org/r/20210927220302.1073499-14-mcgrof@kernel.org
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/block/ataflop.c | 34 +++++++++++++++++++---------------
- 1 file changed, 19 insertions(+), 15 deletions(-)
-
-diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
-index c8a999086060f..2d3a66362dcf9 100644
---- a/drivers/block/ataflop.c
-+++ b/drivers/block/ataflop.c
-@@ -2035,6 +2035,20 @@ static void ataflop_probe(dev_t dev)
- mutex_unlock(&ataflop_probe_lock);
- }
-
-+static void atari_cleanup_floppy_disk(struct atari_floppy_struct *fs)
-+{
-+ int type;
-+
-+ for (type = 0; type < NUM_DISK_MINORS; type++) {
-+ if (!fs->disk[type])
-+ continue;
-+ if (fs->registered[type])
-+ del_gendisk(fs->disk[type]);
-+ blk_cleanup_disk(fs->disk[type]);
-+ }
-+ blk_mq_free_tag_set(&fs->tag_set);
-+}
-+
- static int __init atari_floppy_init (void)
- {
- int i;
-@@ -2105,10 +2119,8 @@ static int __init atari_floppy_init (void)
- return 0;
-
- err:
-- while (--i >= 0) {
-- blk_cleanup_disk(unit[i].disk[0]);
-- blk_mq_free_tag_set(&unit[i].tag_set);
-- }
-+ while (--i >= 0)
-+ atari_cleanup_floppy_disk(&unit[i]);
-
- unregister_blkdev(FLOPPY_MAJOR, "fd");
- out_unlock:
-@@ -2157,18 +2169,10 @@ __setup("floppy=", atari_floppy_setup);
-
- static void __exit atari_floppy_exit(void)
- {
-- int i, type;
-+ int i;
-
-- for (i = 0; i < FD_MAX_UNITS; i++) {
-- for (type = 0; type < NUM_DISK_MINORS; type++) {
-- if (!unit[i].disk[type])
-- continue;
-- if (unit[i].registered[type])
-- del_gendisk(unit[i].disk[type]);
-- blk_cleanup_disk(unit[i].disk[type]);
-- }
-- blk_mq_free_tag_set(&unit[i].tag_set);
-- }
-+ for (i = 0; i < FD_MAX_UNITS; i++)
-+ atari_cleanup_floppy_disk(&unit[i]);
- unregister_blkdev(FLOPPY_MAJOR, "fd");
-
- del_timer_sync(&fd_timer);
---
-2.33.0
-
+++ /dev/null
-From 70e64a2ff417290a5bf367f474cad610e0557dcf Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 27 Sep 2021 15:02:59 -0700
-Subject: block/ataflop: use the blk_cleanup_disk() helper
-
-From: Luis Chamberlain <mcgrof@kernel.org>
-
-[ Upstream commit 44a469b6acae6ad05c4acca8429467d1d50a8b8d ]
-
-Use the helper to replace two lines with one.
-
-Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
-Link: https://lore.kernel.org/r/20210927220302.1073499-12-mcgrof@kernel.org
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/block/ataflop.c | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
-index 94b76c254db9b..359417a016e43 100644
---- a/drivers/block/ataflop.c
-+++ b/drivers/block/ataflop.c
-@@ -2102,8 +2102,7 @@ static int __init atari_floppy_init (void)
-
- err:
- while (--i >= 0) {
-- blk_cleanup_queue(unit[i].disk[0]->queue);
-- put_disk(unit[i].disk[0]);
-+ blk_cleanup_disk(unit[i].disk[0]);
- blk_mq_free_tag_set(&unit[i].tag_set);
- }
-
-@@ -2161,8 +2160,7 @@ static void __exit atari_floppy_exit(void)
- if (!unit[i].disk[type])
- continue;
- del_gendisk(unit[i].disk[type]);
-- blk_cleanup_queue(unit[i].disk[type]->queue);
-- put_disk(unit[i].disk[type]);
-+ blk_cleanup_disk(unit[i].disk[type]);
- }
- blk_mq_free_tag_set(&unit[i].tag_set);
- }
---
-2.33.0
-
net-stream-don-t-purge-sk_error_queue-in-sk_stream_k.patch
media-ir_toy-assignment-to-be16-should-be-of-correct.patch
mmc-mxs-mmc-disable-regulator-on-error-and-in-the-re.patch
-block-ataflop-fix-breakage-introduced-at-blk-mq-refa.patch
platform-x86-thinkpad_acpi-fix-bitwise-vs.-logical-w.patch
mt76-mt7615-fix-endianness-warning-in-mt7615_mac_wri.patch
mt76-mt76x02-fix-endianness-warnings-in-mt76x02_mac..patch
kvm-s390-pv-avoid-double-free-of-sida-page.patch
kvm-s390-pv-avoid-stalls-for-kvm_s390_pv_init_vm.patch
irq-mips-avoid-nested-irq_enter.patch
-ataflop-use-a-separate-gendisk-for-each-media-format.patch
-ataflop-potential-out-of-bounds-in-do_format.patch
-block-ataflop-more-blk-mq-refactoring-fixes.patch
tpm-fix-atmel-tpm-crash-caused-by-too-frequent-queri.patch
tpm_tis_spi-add-missing-spi-id.patch
libbpf-fix-endianness-detection-in-bpf_core_read_bit.patch
ice-fix-not-stopping-tx-queues-for-vfs.patch
acpi-pmic-fix-intel_pmic_regs_handler-read-accesses.patch
drm-nouveau-svm-fix-refcount-leak-bug-and-missing-ch.patch
-block-ataflop-use-the-blk_cleanup_disk-helper.patch
-block-ataflop-add-registration-bool-before-calling-d.patch
-block-ataflop-provide-a-helper-for-cleanup-up-an-ata.patch
net-phy-fix-duplex-out-of-sync-problem-while-changin.patch
bonding-fix-a-use-after-free-problem-when-bond_sysfs.patch
mfd-core-add-missing-of_node_put-for-loop-iteration.patch
ath10k-fix-invalid-dma_addr_t-token-assignment.patch
mmc-moxart-fix-null-pointer-dereference-on-pointer-host.patch
selftests-bpf-fix-also-no-alu32-strobemeta-selftest.patch
-ataflop-fix-off-by-one-in-ataflop_probe.patch
arch-cc-introduce-a-function-to-check-for-confidential-computing-features.patch
x86-sev-add-an-x86-version-of-cc_platform_has.patch
x86-sev-make-the-vc-exception-stacks-part-of-the-default-stacks-storage.patch