From nobody Thu Apr 16 17:38:32 2026 Received: from mail-pf1-f170.google.com (mail-pf1-f170.google.com [209.85.210.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E6CF5242D98 for ; Thu, 26 Feb 2026 14:56:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772117763; cv=none; b=Ftn2qprpvynXEzi6ge6pzHE0YnNYJbhQgWbV5cGNrQdgCQ/kXUUK2GgN+yigoMRWghLXUVGQou19MxBHTkG8Hfb0DDq9+Jxap6bf/3D9B+6soCKJnR78XA9nq03gLY7Oq7SVQndyPAbqL7U8Di06RuGFSF1azYTnF1odxYDec1c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772117763; c=relaxed/simple; bh=nXVQ53makdg3jwsMBYpdubAWQrSSGP1sXdl2IvF9QoM=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=nR9QIBsBzdZ6BjYI5K60ac8672tmTERWm0xgauqqG1joWd6pclYjM5IgLZCtjo9/z0UAagR/ZHn3Sco0GpBqA5PQ+fsIhhFEY2OtExAL3jqSPOo14gEotxgwcnzAmKTx5lujnmK7LjcojuOHBoNLMJq9djbPkWNfwP9aYaX5008= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=thingy.jp; spf=pass smtp.mailfrom=0x0f.com; dkim=pass (1024-bit key) header.d=thingy.jp header.i=@thingy.jp header.b=GQlVxXXP; arc=none smtp.client-ip=209.85.210.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=thingy.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=0x0f.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=thingy.jp header.i=@thingy.jp header.b="GQlVxXXP" Received: by mail-pf1-f170.google.com with SMTP id d2e1a72fcca58-82746ed8cdcso201523b3a.3 for ; Thu, 26 Feb 2026 06:56:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=thingy.jp; s=google; t=1772117760; x=1772722560; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=W+9DeU24eJjz9tNf9en2Zw19YE84GqsQyUQaagU9Tag=; b=GQlVxXXPmpblBXrBfZecn9doYu4DZxZUehBSJBGLOSp8ecWt3ZKrV3vLqncmuIFWW7 VAZTiLRuI6e5UGLl7FSV9tk33o8Yhmb629XXoDGCQJskEtPJAzuDotS1nfjlDf96YiUQ jATxhxKoj4njeTL+FqjEb/j8yw8wBkQINmYKc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772117760; x=1772722560; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=W+9DeU24eJjz9tNf9en2Zw19YE84GqsQyUQaagU9Tag=; b=BvxJ8cDKckRfhkNTm/QYGmUZTRPU6N7Fs8Sa9d2IuqcvYbuXEcE+a3KYL6ulgxXjfH RxZVPbbrzLXKYzOF1DEzzbDutXL3UpMIbF9gXx9+mROd8+pSHtbDcy+SZaNFxg4116nV 2FalKg05hXWiFGfch8ZTweXuLddYBTvAsxavUuQYFn4aGeAKP3YZq0Y1m823313BIgkC 7cypIEkXAdLWh4e0xhC9gjAuOhXlolIBsIMwGfjDNWQTgNkKn0BrvIXqXrzpacdhkx1t HGo9zeMoKAsa1jEVQR20ujiBETSH+17O3UeTIhgy68ivNrv47/q5hW7QhbwSzNPV+mI8 fhqA== X-Forwarded-Encrypted: i=1; AJvYcCVCJEJBgSCDVVXPskfpF7ZCGWRRfXRzodR9vzNDxdKqiwbHJG0qfnjfYUOtSs9o5ieJnTTwsNbY+Ja1S9Y=@vger.kernel.org X-Gm-Message-State: AOJu0YyvQb7nU8z2wU7h5PGtFPa8v7hRHHXkyqQMWnwmMnNq8EMO1qjK 7jMUYH8fMT5YDzt6V3uAMAHZMCpiejn61OhMMNuhOVnYyLCN0bSa66xAJqJMBrb7ksV78MkTuBy RJu3N X-Gm-Gg: ATEYQzx9lCdJ4k+n6hwyTlDj5p/G81Z7Wcfjl0otHMk7kvDsjqDYDLY5EI6CmVrUeFK vkgpXQ8g+/XNPN0ZEOTqOfa38XJtx4dPOieJRvjKlEtMRspzkd43kKLExM3F/36+hoL7iMWwUPf OrK3BC0hKlmst7fxx1h0z4hOh5ZbvxiKYxyGz9aA/TVkvsLv4w7M2Y7cU6zNn2YHdTf271t47P/ 43JbdsDeud+0Xt5nO+sKI1NxbtTAfwB71dLtP31Qtq4PqJXMl+Lr5RLftdYyOLCUq40PEM3wFYf HprvFM/JcY2Zq0qfrPTCJt6MkrSh5PlVuuFNTiXg1Hnvl2WNMop7P2DYuhYCllKjiRa7CcRq868 oWfHozeFOauDMPxQH/v5HaxQTCGrKRxhe9ZfWQQMt7Q5sTZk08MjNj2tk3u94pdYAKBJuQzzcOb pN5DXP5g21sFKCjihTba7jpF9nCTMeqrSHKFukFTNsiTzxYEgMChNKS6jSKES/OLLMJKsm/qGDi Xut3mMeRXySXnI= X-Received: by 2002:a17:90b:3e82:b0:356:1edc:b71 with SMTP id 98e67ed59e1d1-35928a38e71mr3311421a91.1.1772117760137; Thu, 26 Feb 2026 06:56:00 -0800 (PST) Received: from kinako.work.home.arpa (p1590226-ipxg00c01sizuokaden.shizuoka.ocn.ne.jp. [153.227.10.226]) by smtp.googlemail.com with ESMTPSA id 98e67ed59e1d1-35912f5f29fsm3486404a91.1.2026.02.26.06.55.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Feb 2026 06:55:59 -0800 (PST) From: Daniel Palmer To: sudipm.mukherjee@gmail.com, joerg@dorchain.net Cc: linux-m68k@lists.linux-m68k.org, linux-kernel@vger.kernel.org, Daniel Palmer Subject: [PATCH] parport: mfc3: Convert to a modern zorro driver Date: Thu, 26 Feb 2026 23:54:41 +0900 Message-ID: <20260226145441.3606201-1-daniel@thingy.jp> X-Mailer: git-send-email 2.51.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- drivers/parport/parport_mfc3.c | 157 ++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 70 deletions(-) diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c index bb1817218d7b..c77282ba78d3 100644 --- a/drivers/parport/parport_mfc3.c +++ b/drivers/parport/parport_mfc3.c @@ -66,17 +66,19 @@ #include #include =20 -/* Maximum Number of Cards supported */ -#define MAX_MFC 5 - #undef DEBUG =20 -static struct parport *this_port[MAX_MFC] =3D {NULL, }; static volatile int dummy; /* for trigger readds */ =20 #define pia(dev) ((struct pia *)(dev->base)) static struct parport_operations pp_mfc3_ops; =20 +struct mfc3_card { + struct parport *port; + unsigned long piabase; + bool has_irq; +}; + static void mfc3_write_data(struct parport *p, unsigned char data) { pr_debug("write_data %c\n", data); @@ -173,14 +175,18 @@ static int use_cnt; =20 static irqreturn_t mfc3_interrupt(int irq, void *dev_id) { - int i; + struct zorro_dev *z =3D NULL; =20 - for( i =3D 0; i < MAX_MFC; i++) - if (this_port[i] !=3D NULL) - if (pia(this_port[i])->crb & 128) { /* Board caused interrupt */ - dummy =3D pia(this_port[i])->pprb; /* clear irq bit */ - parport_generic_irq(this_port[i]); - } + while ((z =3D zorro_find_device(ZORRO_PROD_BSC_MULTIFACE_III, z))) { + struct mfc3_card *card =3D zorro_get_drvdata(z); + + if (!card || !card->port) + continue; + if (pia(card->port)->crb & 128) { /* Board caused interrupt */ + dummy =3D pia(card->port)->pprb; /* clear irq bit */ + parport_generic_irq(card->port); + } + } return IRQ_HANDLED; } =20 @@ -280,85 +286,96 @@ static struct parport_operations pp_mfc3_ops =3D { =20 /* ----------- Initialisation code --------------------------------- */ =20 -static int __init parport_mfc3_init(void) +static int mfc3_probe(struct zorro_dev *z, const struct zorro_device_id *e= nt) { + unsigned long piabase =3D z->resource.start + PIABASE; + struct device *dev =3D &z->dev; + struct mfc3_card *card; struct parport *p; - int pias =3D 0; struct pia *pp; - struct zorro_dev *z =3D NULL; =20 - if (!MACH_IS_AMIGA) + card =3D devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + if (!devm_request_mem_region(dev, piabase, sizeof(struct pia), "PIA")) + return -EBUSY; + + pp =3D ZTWO_VADDR(piabase); + pp->crb =3D 0; + pp->pddrb =3D 255; /* all data pins output */ + pp->crb =3D PIA_DDR | 32 | 8; + dummy =3D pp->pddrb; /* reading clears interrupt */ + pp->cra =3D 0; + pp->pddra =3D 0xe0; /* /RESET, /DIR, /AUTO-FEED output */ + pp->cra =3D PIA_DDR; + pp->ppra =3D 0; /* reset printer */ + udelay(10); + pp->ppra =3D 128; + + p =3D parport_register_port((unsigned long)pp, IRQ_AMIGA_PORTS, + PARPORT_DMA_NONE, &pp_mfc3_ops); + if (!p) return -ENODEV; =20 - while ((z =3D zorro_find_device(ZORRO_PROD_BSC_MULTIFACE_III, z))) { - unsigned long piabase =3D z->resource.start+PIABASE; - if (!request_mem_region(piabase, sizeof(struct pia), "PIA")) - continue; + card->port =3D p; + card->piabase =3D piabase; =20 - pp =3D ZTWO_VADDR(piabase); - pp->crb =3D 0; - pp->pddrb =3D 255; /* all data pins output */ - pp->crb =3D PIA_DDR|32|8; - dummy =3D pp->pddrb; /* reading clears interrupt */ - pp->cra =3D 0; - pp->pddra =3D 0xe0; /* /RESET, /DIR ,/AUTO-FEED output */ - pp->cra =3D PIA_DDR; - pp->ppra =3D 0; /* reset printer */ - udelay(10); - pp->ppra =3D 128; - p =3D parport_register_port((unsigned long)pp, IRQ_AMIGA_PORTS, - PARPORT_DMA_NONE, &pp_mfc3_ops); - if (!p) - goto out_port; - - if (p->irq !=3D PARPORT_IRQ_NONE) { - if (use_cnt++ =3D=3D 0) - if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, IRQF_SHARED, p->name,= &pp_mfc3_ops)) - goto out_irq; + if (p->irq !=3D PARPORT_IRQ_NONE) { + if (use_cnt++ =3D=3D 0) { + if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, + IRQF_SHARED, p->name, &pp_mfc3_ops)) { + use_cnt--; + goto err_put_port; + } } - p->dev =3D &z->dev; + card->has_irq =3D true; + } =20 - this_port[pias++] =3D p; - pr_info("%s: Multiface III port using irq\n", p->name); - /* XXX: set operating mode */ + p->dev =3D dev; + p->private_data =3D (void *)piabase; =20 - p->private_data =3D (void *)piabase; - parport_announce_port (p); + zorro_set_drvdata(z, card); =20 - if (pias >=3D MAX_MFC) - break; - continue; + pr_info("%s: Multiface III port using irq\n", p->name); + /* XXX: set operating mode */ + parport_announce_port(p); =20 - out_irq: - parport_put_port(p); - out_port: - release_mem_region(piabase, sizeof(struct pia)); - } + return 0; =20 - return pias ? 0 : -ENODEV; +err_put_port: + parport_put_port(p); + + return -ENODEV; } =20 -static void __exit parport_mfc3_exit(void) +static void mfc3_remove(struct zorro_dev *z) { - int i; + struct mfc3_card *card =3D zorro_get_drvdata(z); =20 - for (i =3D 0; i < MAX_MFC; i++) { - if (!this_port[i]) - continue; - parport_remove_port(this_port[i]); - if (this_port[i]->irq !=3D PARPORT_IRQ_NONE) { - if (--use_cnt =3D=3D 0)=20 - 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]); - } + parport_remove_port(card->port); + + if (card->has_irq && (--use_cnt =3D=3D 0)) + free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops); + + parport_put_port(card->port); } =20 +static const struct zorro_device_id mfc3_zorro_tbl[] =3D { + { ZORRO_PROD_BSC_MULTIFACE_III }, + { 0 } +}; +MODULE_DEVICE_TABLE(zorro, mfc3_zorro_tbl); + +static struct zorro_driver mfc3_driver =3D { + .name =3D "parport_mfc3", + .id_table =3D mfc3_zorro_tbl, + .probe =3D mfc3_probe, + .remove =3D mfc3_remove, +}; + +module_driver(mfc3_driver, zorro_register_driver, zorro_unregister_driver); =20 MODULE_AUTHOR("Joerg Dorchain "); MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Paralle= l Port"); MODULE_LICENSE("GPL"); - -module_init(parport_mfc3_init) -module_exit(parport_mfc3_exit) --=20 2.51.0