drivers/parport/parport_mfc3.c | 152 ++++++++++++++++----------------- 1 file changed, 72 insertions(+), 80 deletions(-)
Currently this driver causes my Amiga 4000 to crash if it
is not a module because it tries to iterate over the zorro
devices before that has been setup.
Convert the driver over to the modern zorro driver API so
it probes like the other zorro drivers and doesn't crash
my machine.
Claude was able to do the manual work of moving the original
code but I had to fix up some mistakes, clean up the
allocations to use devm versions and so on.
Only build, boot, and "checked the driver is registered correctly"
tested as I don't have the card and it seems to be one of the
few things winuae doesn't emulate. Using claude to fix it up
seemed better than just deleting it considering all of the effort
Joerg put in to documenting the hardware etc.
Assisted-by: Claude:claude-4.6-sonnet
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
v2: Clean up how the interrupt works a bit and return IRQ_NONE when the
interrupt wasn't for the card as suggested by Geert.
I guess this should work but without a way to test it this is best
effort.
drivers/parport/parport_mfc3.c | 152 ++++++++++++++++-----------------
1 file changed, 72 insertions(+), 80 deletions(-)
diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c
index bb1817218d7b..21210cb2d8d2 100644
--- a/drivers/parport/parport_mfc3.c
+++ b/drivers/parport/parport_mfc3.c
@@ -66,12 +66,8 @@
#include <asm/irq.h>
#include <asm/amigaints.h>
-/* Maximum Number of Cards supported */
-#define MAX_MFC 5
-
#undef DEBUG
-static struct parport *this_port[MAX_MFC] = {NULL, };
static volatile int dummy; /* for trigger readds */
#define pia(dev) ((struct pia *)(dev->base))
@@ -169,19 +165,17 @@ static unsigned char mfc3_read_status(struct parport *p)
return status;
}
-static int use_cnt;
-
static irqreturn_t mfc3_interrupt(int irq, void *dev_id)
{
- int i;
-
- for( i = 0; i < MAX_MFC; i++)
- if (this_port[i] != NULL)
- if (pia(this_port[i])->crb & 128) { /* Board caused interrupt */
- dummy = pia(this_port[i])->pprb; /* clear irq bit */
- parport_generic_irq(this_port[i]);
- }
- return IRQ_HANDLED;
+ struct parport *p = dev_id;
+
+ if (pia(p)->crb & 128) { /* Board caused interrupt */
+ dummy = pia(p)->pprb; /* clear irq bit */
+ parport_generic_irq(p);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
}
static void mfc3_enable_irq(struct parport *p)
@@ -280,85 +274,83 @@ static struct parport_operations pp_mfc3_ops = {
/* ----------- Initialisation code --------------------------------- */
-static int __init parport_mfc3_init(void)
+static int mfc3_probe(struct zorro_dev *z, const struct zorro_device_id *ent)
{
+ unsigned long piabase = z->resource.start + PIABASE;
+ struct device *dev = &z->dev;
struct parport *p;
- int pias = 0;
struct pia *pp;
- struct zorro_dev *z = NULL;
- if (!MACH_IS_AMIGA)
+ if (!devm_request_mem_region(dev, piabase, sizeof(struct pia), "PIA"))
+ return -EBUSY;
+
+ pp = ZTWO_VADDR(piabase);
+ pp->crb = 0;
+ pp->pddrb = 255; /* all data pins output */
+ pp->crb = PIA_DDR | 32 | 8;
+ dummy = pp->pddrb; /* reading clears interrupt */
+ pp->cra = 0;
+ pp->pddra = 0xe0; /* /RESET, /DIR, /AUTO-FEED output */
+ pp->cra = PIA_DDR;
+ pp->ppra = 0; /* reset printer */
+ udelay(10);
+ pp->ppra = 128;
+
+ p = parport_register_port((unsigned long)pp, IRQ_AMIGA_PORTS,
+ PARPORT_DMA_NONE, &pp_mfc3_ops);
+ if (!p)
return -ENODEV;
- while ((z = zorro_find_device(ZORRO_PROD_BSC_MULTIFACE_III, z))) {
- unsigned long piabase = z->resource.start+PIABASE;
- if (!request_mem_region(piabase, sizeof(struct pia), "PIA"))
- continue;
-
- pp = ZTWO_VADDR(piabase);
- pp->crb = 0;
- pp->pddrb = 255; /* all data pins output */
- pp->crb = PIA_DDR|32|8;
- dummy = pp->pddrb; /* reading clears interrupt */
- pp->cra = 0;
- pp->pddra = 0xe0; /* /RESET, /DIR ,/AUTO-FEED output */
- pp->cra = PIA_DDR;
- pp->ppra = 0; /* reset printer */
- udelay(10);
- pp->ppra = 128;
- p = parport_register_port((unsigned long)pp, IRQ_AMIGA_PORTS,
- PARPORT_DMA_NONE, &pp_mfc3_ops);
- if (!p)
- goto out_port;
-
- if (p->irq != PARPORT_IRQ_NONE) {
- if (use_cnt++ == 0)
- if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, IRQF_SHARED, p->name, &pp_mfc3_ops))
- goto out_irq;
- }
- p->dev = &z->dev;
-
- this_port[pias++] = p;
- pr_info("%s: Multiface III port using irq\n", p->name);
- /* XXX: set operating mode */
-
- p->private_data = (void *)piabase;
- parport_announce_port (p);
-
- if (pias >= MAX_MFC)
- break;
- continue;
-
- out_irq:
- parport_put_port(p);
- out_port:
- release_mem_region(piabase, sizeof(struct pia));
+ if (p->irq != PARPORT_IRQ_NONE) {
+ if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt,
+ IRQF_SHARED, p->name, p))
+ goto err_put_port;
}
- return pias ? 0 : -ENODEV;
+ p->dev = dev;
+ p->private_data = (void *)piabase;
+
+ zorro_set_drvdata(z, p);
+
+ pr_info("%s: Multiface III port using irq\n", p->name);
+ /* XXX: set operating mode */
+ parport_announce_port(p);
+
+ return 0;
+
+err_put_port:
+ parport_put_port(p);
+
+ return -ENODEV;
}
-static void __exit parport_mfc3_exit(void)
+static void mfc3_remove(struct zorro_dev *z)
{
- int i;
-
- for (i = 0; i < MAX_MFC; i++) {
- if (!this_port[i])
- continue;
- parport_remove_port(this_port[i]);
- if (this_port[i]->irq != PARPORT_IRQ_NONE) {
- if (--use_cnt == 0)
- free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops);
- }
- release_mem_region(ZTWO_PADDR(this_port[i]->private_data), sizeof(struct pia));
- parport_put_port(this_port[i]);
- }
+ struct parport *p = zorro_get_drvdata(z);
+
+ parport_remove_port(p);
+
+ if (p->irq != PARPORT_IRQ_NONE)
+ free_irq(IRQ_AMIGA_PORTS, p);
+
+ parport_put_port(p);
}
+static const struct zorro_device_id mfc3_zorro_tbl[] = {
+ { ZORRO_PROD_BSC_MULTIFACE_III },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(zorro, mfc3_zorro_tbl);
+
+static struct zorro_driver mfc3_driver = {
+ .name = "parport_mfc3",
+ .id_table = mfc3_zorro_tbl,
+ .probe = mfc3_probe,
+ .remove = mfc3_remove,
+};
+
+module_driver(mfc3_driver, zorro_register_driver, zorro_unregister_driver);
MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Parallel Port");
MODULE_LICENSE("GPL");
-
-module_init(parport_mfc3_init)
-module_exit(parport_mfc3_exit)
--
2.51.0
On Fri, 27 Feb 2026 at 11:16, Daniel Palmer <daniel@thingy.jp> wrote:
> Currently this driver causes my Amiga 4000 to crash if it
> is not a module because it tries to iterate over the zorro
> devices before that has been setup.
>
> Convert the driver over to the modern zorro driver API so
> it probes like the other zorro drivers and doesn't crash
> my machine.
>
> Claude was able to do the manual work of moving the original
> code but I had to fix up some mistakes, clean up the
> allocations to use devm versions and so on.
>
> Only build, boot, and "checked the driver is registered correctly"
> tested as I don't have the card and it seems to be one of the
> few things winuae doesn't emulate. Using claude to fix it up
> seemed better than just deleting it considering all of the effort
> Joerg put in to documenting the hardware etc.
>
> Assisted-by: Claude:claude-4.6-sonnet
> Signed-off-by: Daniel Palmer <daniel@thingy.jp>
> ---
>
> v2: Clean up how the interrupt works a bit and return IRQ_NONE when the
> interrupt wasn't for the card as suggested by Geert.
> I guess this should work but without a way to test it this is best
> effort.
Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Hi Geert, On Mon, 30 Mar 2026 at 19:02, Geert Uytterhoeven <geert@linux-m68k.org> wrote: > Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org> Thank you for the review. It seems like the parport maintainer isn't responding (Andy has some patches that haven't been reviewed or picked up[0] too). Is there a way to take this via the m68k tree because it only matters for m68k or something? I have CC'd Linus, Greg K-H and Andy. After googling "LKML how to escalate unresponsive maintainer" and not finding much. If this is wrong, sorry for the spam. :) Thanks, Daniel 0 - https://lore.kernel.org/lkml/20260122090601.2380747-1-andriy.shevchenko@linux.intel.com/
On Tue, Mar 31, 2026 at 06:09:12PM +0900, Daniel Palmer wrote: > On Mon, 30 Mar 2026 at 19:02, Geert Uytterhoeven <geert@linux-m68k.org> wrote: > > Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org> > > Thank you for the review. It seems like the parport maintainer isn't > responding (Andy has some patches that haven't been reviewed or picked > up[0] too). > Is there a way to take this via the m68k tree because it only matters > for m68k or something? > > I have CC'd Linus, Greg K-H and Andy. After googling "LKML how to > escalate unresponsive maintainer" and not finding much. If this is > wrong, sorry for the spam. :) Become a new maintainer! But you can also send a patch changing MAINTAINERS database. > 0 - https://lore.kernel.org/lkml/20260122090601.2380747-1-andriy.shevchenko@linux.intel.com/ -- With Best Regards, Andy Shevchenko
© 2016 - 2026 Red Hat, Inc.