From linux at zary.sk  Sat Mar  5 12:13:55 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:13:55 +0100
Subject: [Linux-parport] [RFC PATCH] pata_parport: paride replacement
Message-ID: <20220305201411.501-1-linux@zary.sk>

Hello,
this is a RFC patch for the new pata_parport libata driver - a paride
replacement.

Protocol driver registration and device creation was changed since the
second preview - no more protocol numbers or parport I/O addresses.

All parports and all protocol drivers are now probed automatically unless
probe=0 parameter is used. So just "modprobe epat" is enough for a Imation
SuperDisk drive to work.

Manual device creation:
echo auto >/sys/bus/pata_parport/new_device
echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
echo "parport0 auto" >/sys/bus/pata_parport/new_device
echo "auto epat" >/sys/bus/pata_parport/new_device

Deleting devices:
echo pata_parport.0 >/sys/bus/pata_parport/delete_device

Haven't found any sane way to hook pi_connect() and pi_disconnect() to
libata. So pi_connect() is called on every protocol driver access and
pi_disconnect() is called by a timer that's activated after protocol driver
access.

Found that the EPP-32 mode is buggy in EPAT - and also in many (all?) other
protocol drivers - they don't handle non-multiple-of-4 block transfers
correctly. I'll fix that later.

The bpck_connect() in bpck driver seems to need to know if a CD drive is
attached (weird) but it's called before device detection. This probably
cannot be fixed without the HW.

I have only two devices and both have the same EPAT chip, unfortunately:
Imation SupserDisk
HP C4381A (drive was dead, replaced by TOSHIBA CD-ROM XM-6202B)

The both work:
# modprobe epat
[  122.635395] pata_parport: protocol epat registered
[  122.738114] epat pata_parport.0: epat, Shuttle EPAT chip c6 at 0x378, mode 5 (EPP-32), delay 1
[  122.789035] scsi host4: pata_parport-epat
[  122.789226] ata5: PATA max PIO0 port parport0 protocol epat
[  127.831534] ata5: link is slow to respond, please be patient (ready=0)
[  132.811623] ata5: device not ready (errno=-16), forcing hardreset
[  133.015024] ata5.00: ATAPI: TOSHIBA CD-ROM XM-6202B, 1108, max MWDMA2
[  133.023016] scsi 4:0:0:0: CD-ROM            TOSHIBA  CD-ROM XM-6202B  1108 PQ: 0 ANSI: 5
[  133.043817] scsi 4:0:0:0: Attached scsi generic sg1 type 5
[  133.088146] sr 4:0:0:0: [sr0] scsi3-mmc drive: 32x/32x cd/rw xa/form2 cdda tray
[  133.088163] cdrom: Uniform CD-ROM driver Revision: 3.20
[  133.125939] sr 4:0:0:0: Attached scsi CD-ROM sr0
# mount /dev/sr0 /mnt
mount: /mnt: WARNING: source write-protected, mounted read-only.
[  157.922575] ISO 9660 Extensions: Microsoft Joliet Level 3
[  157.991030] ISO 9660 Extensions: RRIP_1991A
# hdparm -t --direct /dev/sr0

/dev/sr0:
 Timing O_DIRECT disk reads:   2 MB in  3.08 seconds = 664.47 kB/sec



# modprobe epat
[  448.160910] pata_parport: protocol epat registered
[  448.267068] epat pata_parport.0: epat, Shuttle EPAT chip c6 at 0x378, mode 5 (EPP-32), delay 1
[  448.301624] scsi host4: pata_parport-epat
[  448.301769] ata6: PATA max PIO0 port parport0 protocol epat
[  448.533850] ata6.00: ATAPI: LS-120 COSM   04              UHD Floppy, 0270M09T, max PIO2
[  448.615500] scsi 4:0:0:0: Direct-Access     MATSHITA LS-120 COSM   04 0270 PQ: 0 ANSI: 5
[  448.651279] sd 4:0:0:0: Attached scsi generic sg1 type 0
[  448.686028] sd 4:0:0:0: [sdb] Media removed, stopped polling
[  448.717879] sd 4:0:0:0: [sdb] Attached SCSI removable disk
[  472.259786] sd 4:0:0:0: [sdb] Read Capacity(16) failed: Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK
[  472.259805] sd 4:0:0:0: [sdb] Sense not available.
[  483.042442] sd 4:0:0:0: [sdb] 246528 512-byte logical blocks: (126 MB/120 MiB)
[  483.158446] sdb: detected capacity change from 0 to 246528
[  483.309771]  sdb:
# hdparm -t --direct /dev/sdb

/dev/sdb:
 Timing O_DIRECT disk reads:   2 MB in 44.19 seconds =  46.35 kB/sec




From linux at zary.sk  Sat Mar  5 12:13:57 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:13:57 +0100
Subject: [Linux-parport] [PATCH 02/16] pata_parport: add aten protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-3-linux@zary.sk>

Add ATEN EH-100 protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  11 +++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/aten.c   | 139 ++++++++++++++++++++++++++++++
 3 files changed, 151 insertions(+)
 create mode 100644 drivers/ata/pata_parport/aten.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index 56dc6b25d5fa..93b0ad65b523 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -8,3 +8,14 @@
 
 comment "Parallel IDE protocol modules"
 	depends on PATA_PARPORT
+
+config PATA_PARPORT_ATEN
+	tristate "ATEN EH-100 protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the ATEN EH-100 parallel port IDE
+	  protocol. This protocol is used in some inexpensive low performance
+	  parallel port kits made in Hong Kong. If you chose to build PATA_PARPORT
+	  support into your kernel, you may answer Y here to build in the
+	  protocol driver, otherwise you should answer M to build it as a
+	  loadable module. The module will be called aten.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index b105e1cb8dc6..7e821b629c58 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -7,3 +7,4 @@
 #
 
 obj-$(CONFIG_PATA_PARPORT)		+= pata_parport.o
+obj-$(CONFIG_PATA_PARPORT_ATEN)		+= aten.o
diff --git a/drivers/ata/pata_parport/aten.c b/drivers/ata/pata_parport/aten.c
new file mode 100644
index 000000000000..a811a471e942
--- /dev/null
+++ b/drivers/ata/pata_parport/aten.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	aten.c  (c) 1997-8  Grant R. Guenther <grant at torque.net>
+ *			    Under the terms of the GNU General Public License.
+ *
+ *	aten.c is a low-level protocol driver for the ATEN EH-100
+ *	parallel port adapter.  The EH-100 supports 4-bit and 8-bit
+ *	modes only.  There is also an EH-132 which supports EPP mode
+ *	transfers.  The EH-132 is not yet supported.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <linux/types.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+#define j44(a, b)		((((a >> 4) & 0x0f) | (b & 0xf0)) ^ 0x88)
+
+/* cont = 0 - access the IDE register file
+ * cont = 1 - access the IDE command set
+ */
+
+static int cont_map[2] = { 0x08, 0x20 };
+
+static void aten_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	int r = regr + cont_map[cont] + 0x80;
+
+	w0(r); w2(0xe); w2(6); w0(val); w2(7); w2(6); w2(0xc);
+}
+
+static int aten_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int a, b, r;
+
+	r = regr + cont_map[cont] + 0x40;
+
+	switch (pi->mode) {
+	case 0:
+		w0(r); w2(0xe); w2(6);
+		w2(7); w2(6); w2(0);
+		a = r1(); w0(0x10); b = r1(); w2(0xc);
+		return j44(a, b);
+	case 1:
+		r |= 0x10;
+		w0(r); w2(0xe); w2(6); w0(0xff);
+		w2(0x27); w2(0x26); w2(0x20);
+		a = r0();
+		w2(0x26); w2(0xc);
+		return a;
+	}
+	return -1;
+}
+
+static void aten_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int  k, a, b, c, d;
+
+	switch (pi->mode) {
+	case 0:
+		w0(0x48); w2(0xe); w2(6);
+		for (k = 0; k < count / 2; k++) {
+			w2(7); w2(6); w2(2);
+			a = r1(); w0(0x58); b = r1();
+			w2(0); d = r1(); w0(0x48); c = r1();
+			buf[2 * k] = j44(c, d);
+			buf[2 * k + 1] = j44(a, b);
+		}
+		w2(0xc);
+		break;
+	case 1:
+		w0(0x58); w2(0xe); w2(6);
+		for (k = 0; k < count / 2; k++) {
+			w2(0x27); w2(0x26); w2(0x22);
+			a = r0(); w2(0x20); b = r0();
+			buf[2 * k] = b; buf[2 * k + 1] = a;
+		}
+		w2(0x26); w2(0xc);
+		break;
+	}
+}
+
+static void aten_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k;
+
+	w0(0x88); w2(0xe); w2(6);
+	for (k = 0; k < count / 2; k++) {
+		w0(buf[2 * k + 1]); w2(0xe); w2(6);
+		w0(buf[2 * k]); w2(7); w2(6);
+	}
+	w2(0xc);
+}
+
+static void aten_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+	w2(0xc);
+}
+
+static void aten_disconnect(struct pi_adapter *pi)
+{
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+static void aten_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	char *mode_string[2] = { "4-bit", "8-bit" };
+
+	dev_info(&pi->dev, "aten, ATEN EH-100 at 0x%x, mode %d (%s), delay %d\n",
+		pi->port, pi->mode, mode_string[pi->mode], pi->delay);
+}
+
+static struct pi_protocol aten = {
+	.owner		= THIS_MODULE,
+	.name		= "aten",
+	.max_mode	= 2,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= aten_write_regr,
+	.read_regr	= aten_read_regr,
+	.write_block	= aten_write_block,
+	.read_block	= aten_read_block,
+	.connect	= aten_connect,
+	.disconnect	= aten_disconnect,
+	.log_adapter	= aten_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-aten") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(aten);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:13:58 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:13:58 +0100
Subject: [Linux-parport] [PATCH 03/16] pata_parport: add bpck protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-4-linux@zary.sk>

Add MicroSolutions backpack (Series 5) protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  17 ++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/bpck.c   | 481 ++++++++++++++++++++++++++++++
 3 files changed, 499 insertions(+)
 create mode 100644 drivers/ata/pata_parport/bpck.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index 93b0ad65b523..ed33a6a5c6fe 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -19,3 +19,20 @@ config PATA_PARPORT_ATEN
 	  support into your kernel, you may answer Y here to build in the
 	  protocol driver, otherwise you should answer M to build it as a
 	  loadable module. The module will be called aten.
+
+config PATA_PARPORT_BPCK
+	tristate "MicroSolutions backpack (Series 5) protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the Micro Solutions BACKPACK
+	  parallel port Series 5 IDE protocol.  (Most BACKPACK drives made
+	  before 1999 were Series 5) Series 5 drives will NOT always have the
+	  Series noted on the bottom of the drive. Series 6 drivers will.
+
+	  In other words, if your BACKPACK drive doesn't say "Series 6" on the
+	  bottom, enable this option.
+
+	  If you chose to build PATA_PARPORT support into your kernel, you may
+	  answer Y here to build in the protocol driver, otherwise you should
+	  answer M to build it as a loadable module.  The module will be
+	  called bpck.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index 7e821b629c58..1d03e49aa29f 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -8,3 +8,4 @@
 
 obj-$(CONFIG_PATA_PARPORT)		+= pata_parport.o
 obj-$(CONFIG_PATA_PARPORT_ATEN)		+= aten.o
+obj-$(CONFIG_PATA_PARPORT_BPCK)		+= bpck.o
diff --git a/drivers/ata/pata_parport/bpck.c b/drivers/ata/pata_parport/bpck.c
new file mode 100644
index 000000000000..07ee353eae84
--- /dev/null
+++ b/drivers/ata/pata_parport/bpck.c
@@ -0,0 +1,481 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	bpck.c	(c) 1996-8  Grant R. Guenther <grant at torque.net>
+ *			    Under the terms of the GNU General Public License.
+ *
+ *	bpck.c is a low-level protocol driver for the MicroSolutions
+ *	"backpack" parallel port IDE adapter.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+#undef r2
+#undef w2
+#undef PC
+
+#define PC		pi->private
+#define r2()		(PC = (in_p(2) & 0xff))
+#define w2(byte)	{ out_p(2, byte); PC = byte; }
+#define t2(pat)		{ PC ^= pat; out_p(2, PC); }
+#define e2()		{ PC &= 0xfe; out_p(2, PC); }
+#define o2()		{ PC |= 1; out_p(2, PC); }
+
+#define j44(l, h)     (((l >> 3) & 0x7) | ((l >> 4) & 0x8) | ((h << 1) & 0x70) | (h & 0x80))
+
+/* cont = 0 - access the IDE register file
+ * cont = 1 - access the IDE command set
+ * cont = 2 - use internal bpck register addressing
+ */
+
+static int cont_map[3] = { 0x40, 0x48, 0 };
+
+static int bpck_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int r, l, h;
+
+	r = regr + cont_map[cont];
+
+	switch (pi->mode) {
+	case 0:
+		w0(r & 0xf); w0(r); t2(2); t2(4);
+		l = r1();
+		t2(4);
+		h = r1();
+		return j44(l, h);
+	case 1:
+		w0(r & 0xf); w0(r); t2(2);
+		e2(); t2(0x20);
+		t2(4); h = r0();
+		t2(1); t2(0x20);
+		return h;
+	case 2:
+	case 3:
+	case 4:
+		w0(r); w2(9); w2(0); w2(0x20);
+		h = r4();
+		w2(0);
+		return h;
+	}
+	return -1;
+}
+
+static void bpck_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	int r = regr + cont_map[cont];
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+		w0(r);
+		t2(2);
+		w0(val);
+		o2(); t2(4); t2(1);
+		break;
+	case 2:
+	case 3:
+	case 4:
+		w0(r); w2(9); w2(0);
+		w0(val); w2(1); w2(3); w2(0);
+		break;
+	}
+}
+
+/* These macros access the bpck registers in native addressing */
+#define WR(r, v)	bpck_write_regr(pi, 2, r, v)
+#define RR(r)		(bpck_read_regr(pi, 2, r))
+
+static void bpck_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int i;
+
+	switch (pi->mode) {
+	case 0:
+		WR(4, 0x40);
+		w0(0x40); t2(2); t2(1);
+		for (i = 0; i < count; i++) {
+			w0(buf[i]); t2(4);
+		}
+		WR(4, 0);
+		break;
+	case 1:
+		WR(4, 0x50);
+		w0(0x40); t2(2); t2(1);
+		for (i = 0; i < count; i++) {
+			w0(buf[i]); t2(4);
+		}
+		WR(4, 0x10);
+		break;
+	case 2:
+		WR(4, 0x48);
+		w0(0x40); w2(9); w2(0); w2(1);
+		for (i = 0; i < count; i++)
+			w4(buf[i]);
+		w2(0);
+		WR(4, 8);
+		break;
+	case 3:
+		WR(4, 0x48);
+		w0(0x40); w2(9); w2(0); w2(1);
+		for (i = 0; i < count / 2; i++)
+			w4w(((u16 *)buf)[i]);
+		w2(0);
+		WR(4, 8);
+		break;
+	case 4:
+		WR(4, 0x48);
+		w0(0x40); w2(9); w2(0); w2(1);
+		for (i = 0; i < count / 4; i++)
+			w4l(((u32 *)buf)[i]);
+		w2(0);
+		WR(4, 8);
+		break;
+	}
+}
+
+static void bpck_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int i, l, h;
+
+	switch (pi->mode) {
+	case 0:
+		WR(4, 0x40);
+		w0(0x40); t2(2);
+		for (i = 0; i < count; i++) {
+			t2(4); l = r1();
+			t2(4); h = r1();
+			buf[i] = j44(l, h);
+		}
+		WR(4, 0);
+		break;
+	case 1:
+		WR(4, 0x50);
+		w0(0x40); t2(2); t2(0x20);
+		for (i = 0; i < count; i++) {
+			t2(4); buf[i] = r0();
+		}
+		t2(1); t2(0x20);
+		WR(4, 0x10);
+		break;
+	case 2:
+		WR(4, 0x48);
+		w0(0x40); w2(9); w2(0); w2(0x20);
+		for (i = 0; i < count; i++)
+			buf[i] = r4();
+		w2(0);
+		WR(4, 8);
+		break;
+	case 3:
+		WR(4, 0x48);
+		w0(0x40); w2(9); w2(0); w2(0x20);
+		for (i = 0; i < count / 2; i++)
+			((u16 *)buf)[i] = r4w();
+		w2(0);
+		WR(4, 8);
+		break;
+	case 4:
+		WR(4, 0x48);
+		w0(0x40); w2(9); w2(0); w2(0x20);
+		for (i = 0; i < count / 4; i++)
+			((u32 *)buf)[i] = r4l();
+		w2(0);
+		WR(4, 8);
+		break;
+	}
+}
+
+static int bpck_probe_unit(struct pi_adapter *pi)
+{
+	int o1, o0, f7, id;
+	int t, s;
+
+	id = pi->unit;
+	s = 0;
+	w2(4); w2(0xe); r2(); t2(2);
+	o1 = r1() & 0xf8;
+	o0 = r0();
+	w0(255-id); w2(4); w0(id);
+	t2(8); t2(8); t2(8);
+	t2(2); t = r1() & 0xf8;
+	f7 = ((id % 8) == 7);
+	if ((f7) || (t != o1)) {
+		t2(2); s = r1() & 0xf8;
+	}
+	if ((t == o1) && ((!f7) || (s == o1)))  {
+		w2(0x4c); w0(o0);
+		return 0;
+	}
+	t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
+	return 1;
+}
+
+static void bpck_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	w0(0xff-pi->unit); w2(4); w0(pi->unit);
+	t2(8); t2(8); t2(8);
+	t2(2); t2(2);
+
+	switch (pi->mode) {
+	case 0:
+		t2(8); WR(4, 0);
+		break;
+	case 1:
+		t2(8); WR(4, 0x10);
+		break;
+	case 2:
+	case 3:
+	case 4:
+		w2(0); WR(4, 8);
+		break;
+	}
+
+	WR(5, 8);
+
+	//// FIXME: devtype was removed and we're called before device detection
+//	if (pi->devtype == PI_PCD) {
+//		WR(0x46, 0x10);		/* fiddle with ESS logic ??? */
+//		WR(0x4c, 0x38);
+//		WR(0x4d, 0x88);
+//		WR(0x46, 0xa0);
+//		WR(0x41, 0);
+//		WR(0x4e, 8);
+//	}
+}
+
+static void bpck_disconnect(struct pi_adapter *pi)
+{
+	w0(0);
+	if (pi->mode >= 2) {
+		w2(9); w2(0);
+	} else
+		t2(2);
+	w2(0x4c); w0(pi->saved_r0);
+}
+
+/* This fakes the EPP protocol to turn off EPP ... */
+static void bpck_force_spp(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	w0(0xff-pi->unit); w2(4); w0(pi->unit);
+	t2(8); t2(8); t2(8);
+	t2(2); t2(2);
+
+	w2(0);
+	w0(4); w2(9); w2(0);
+	w0(0); w2(1); w2(3); w2(0);
+	w0(0); w2(9); w2(0);
+	w2(0x4c); w0(pi->saved_r0);
+}
+
+#define TEST_LEN  16
+
+static int bpck_test_proto(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	int i, e, l, h, om;
+	char buf[TEST_LEN];
+
+	bpck_force_spp(pi);
+
+	switch (pi->mode) {
+	case 0:
+		bpck_connect(pi);
+		WR(0x13, 0x7f);
+		w0(0x13); t2(2);
+		for (i = 0; i < TEST_LEN; i++) {
+			t2(4); l = r1();
+			t2(4); h = r1();
+			buf[i] = j44(l, h);
+		}
+		bpck_disconnect(pi);
+		break;
+	case 1:
+		bpck_connect(pi);
+		WR(0x13, 0x7f);
+		w0(0x13); t2(2); t2(0x20);
+		for (i = 0; i < TEST_LEN; i++) {
+			t2(4); buf[i] = r0();
+		}
+		t2(1); t2(0x20);
+		bpck_disconnect(pi);
+		break;
+	case 2:
+	case 3:
+	case 4:
+		om = pi->mode;
+		pi->mode = 0;
+		bpck_connect(pi);
+		WR(7, 3);
+		WR(4, 8);
+		bpck_disconnect(pi);
+
+		pi->mode = om;
+		bpck_connect(pi);
+		w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
+
+		switch (pi->mode) {
+		case 2:
+			for (i = 0; i < TEST_LEN; i++)
+				buf[i] = r4();
+			break;
+		case 3:
+			for (i = 0; i < TEST_LEN / 2; i++)
+				((u16 *)buf)[i] = r4w();
+			break;
+		case 4:
+			for (i = 0; i < TEST_LEN / 4; i++)
+				((u32 *)buf)[i] = r4l();
+			break;
+		}
+
+		w2(0);
+		WR(7, 0);
+		bpck_disconnect(pi);
+
+		break;
+	}
+
+	if (verbose)
+		dev_info(&pi->dev, "bpck: 0x%x unit %d mode %d",
+		       pi->port, pi->unit, pi->mode);
+
+	e = 0;
+	for (i = 0; i < TEST_LEN; i++)
+		if (buf[i] != (i+1))
+			e++;
+	return e;
+}
+
+static void bpck_read_eeprom(struct pi_adapter *pi, char *buf)
+{
+	int i, j, k, p, v, f, om, od;
+
+	bpck_force_spp(pi);
+
+	om = pi->mode;  od = pi->delay;
+	pi->mode = 0; pi->delay = 6;
+
+	bpck_connect(pi);
+
+	WR(4, 0);
+	for (i = 0; i < 64; i++) {
+		WR(6, 8);
+		WR(6, 0xc);
+		p = 0x100;
+		for (k = 0; k < 9; k++) {
+			f = (((i + 0x180) & p) != 0) * 2;
+			WR(6, f + 0xc);
+			WR(6, f + 0xd);
+			WR(6, f + 0xc);
+			p = (p >> 1);
+		}
+		for (j = 0; j < 2; j++) {
+			v = 0;
+			for (k = 0; k < 8; k++) {
+				WR(6, 0xc);
+				WR(6, 0xd);
+				WR(6, 0xc);
+				f = RR(0);
+				v = 2 * v + (f == 0x84);
+			}
+			buf[2 * i + 1 - j] = v;
+		}
+	}
+	WR(6, 8);
+	WR(6, 0);
+	WR(5, 8);
+
+	bpck_disconnect(pi);
+
+	if (om >= 2) {
+		bpck_connect(pi);
+		WR(7, 3);
+		WR(4, 8);
+		bpck_disconnect(pi);
+	}
+
+	pi->mode = om; pi->delay = od;
+}
+
+static int bpck_test_port(struct pi_adapter *pi)	/* check for 8-bit port */
+{
+	int i, r, m;
+
+	w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
+	m = -1;
+	if (r == i)
+		m = 2;
+	if (r == (255-i))
+		m = 0;
+
+	w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i);
+	if (r != (255-i))
+		m = -1;
+
+	if (m == 0) {
+		w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa);
+	}
+	if (m == 2) {
+		w2(0x26); w2(0xc);
+	}
+
+	if (m == -1)
+		return 0;
+	return 5;
+}
+
+static void bpck_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	static char * const mode_string[] = {
+		"4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
+
+#ifdef DUMP_EEPROM
+	int i;
+#endif
+
+	bpck_read_eeprom(pi, scratch);
+
+#ifdef DUMP_EEPROM
+	if (verbose) {
+		for (i = 0; i < 128; i++)
+			if ((scratch[i] < ' ') || (scratch[i] > '~'))
+				scratch[i] = '.';
+		dev_info(&pi->dev, "bpck EEPROM: %64.64s\n", scratch);
+		dev_info(&pi->dev, "	      %64.64s\n", &scratch[64]);
+	}
+#endif
+
+	dev_info(&pi->dev, "bpck, backpack %8.8s unit %d at 0x%x, mode %d (%s), delay %d\n",
+		&scratch[110], pi->unit, pi->port, pi->mode,
+		mode_string[pi->mode], pi->delay);
+}
+
+static struct pi_protocol bpck = {
+	.owner		= THIS_MODULE,
+	.name		= "bpck",
+	.max_mode	= 5,
+	.epp_first	= 2,
+	.default_delay	= 4,
+	.max_units	= 255,
+	.write_regr	= bpck_write_regr,
+	.read_regr	= bpck_read_regr,
+	.write_block	= bpck_write_block,
+	.read_block	= bpck_read_block,
+	.connect	= bpck_connect,
+	.disconnect	= bpck_disconnect,
+	.test_port	= bpck_test_port,
+	.probe_unit	= bpck_probe_unit,
+	.test_proto	= bpck_test_proto,
+	.log_adapter	= bpck_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-bpck") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(bpck);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:13:59 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:13:59 +0100
Subject: [Linux-parport] [PATCH 04/16] pata_parport: add bpck6 protocol
 driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-5-linux@zary.sk>

Add MicroSolutions backpack (Series 6) protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig   |  18 ++
 drivers/ata/pata_parport/Makefile  |   1 +
 drivers/ata/pata_parport/bpck6.c   | 164 ++++++++++
 drivers/ata/pata_parport/ppc6lnx.c | 486 +++++++++++++++++++++++++++++
 4 files changed, 669 insertions(+)
 create mode 100644 drivers/ata/pata_parport/bpck6.c
 create mode 100644 drivers/ata/pata_parport/ppc6lnx.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index ed33a6a5c6fe..e88d9c0bedc6 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -36,3 +36,21 @@ config PATA_PARPORT_BPCK
 	  answer Y here to build in the protocol driver, otherwise you should
 	  answer M to build it as a loadable module.  The module will be
 	  called bpck.
+
+config PATA_PARPORT_BPCK6
+	tristate "MicroSolutions backpack (Series 6) protocol"
+	depends on PATA_PARPORT && !64BIT
+	help
+	  This option enables support for the Micro Solutions BACKPACK
+	  parallel port Series 6 IDE protocol.  (Most BACKPACK drives made
+	  after 1999 were Series 6) Series 6 drives will have the Series noted
+	  on the bottom of the drive.  Series 5 drivers don't always have it
+	  noted.
+
+	  In other words, if your BACKPACK drive says "Series 6" on the
+	  bottom, enable this option.
+
+	  If you chose to build PATA_PARPORT support into your kernel, you may
+	  answer Y here to build in the protocol driver, otherwise you should
+	  answer M to build it as a loadable module.  The module will be
+	  called bpck6.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index 1d03e49aa29f..60522279aa16 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -9,3 +9,4 @@
 obj-$(CONFIG_PATA_PARPORT)		+= pata_parport.o
 obj-$(CONFIG_PATA_PARPORT_ATEN)		+= aten.o
 obj-$(CONFIG_PATA_PARPORT_BPCK)		+= bpck.o
+obj-$(CONFIG_PATA_PARPORT_BPCK6)	+= bpck6.o
diff --git a/drivers/ata/pata_parport/bpck6.c b/drivers/ata/pata_parport/bpck6.c
new file mode 100644
index 000000000000..cd517c822ee2
--- /dev/null
+++ b/drivers/ata/pata_parport/bpck6.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	backpack.c (c) 2001 Micro Solutions Inc.
+ *		Released under the terms of the GNU General Public license
+ *
+ *	backpack.c is a low-level protocol driver for the Micro Solutions
+ *		"BACKPACK" parallel port IDE adapter
+ *		(Works on Series 6 drives)
+ *
+ *	Written by: Ken Hahn     (linux-dev at micro-solutions.com)
+ *		    Clive Turvey (linux-dev at micro-solutions.com)
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/parport.h>
+
+#include "ppc6lnx.c"
+#include "pata_parport.h"
+
+#define PPCSTRUCT(pi) ((struct ppc_storage *)(pi->private))
+
+#define ATAPI_DATA       0      /* data port */
+
+static int bpck6_read_regr(struct pi_adapter *pi, int cont, int reg)
+{
+	unsigned int out;
+
+	/* check for bad settings */
+	if (reg < 0 || reg > 7 || cont < 0 || cont > 2)
+		return -1;
+	out = ppc6_rd_port(PPCSTRUCT(pi), cont ? reg | 8 : reg);
+	return out;
+}
+
+static void bpck6_write_regr(struct pi_adapter *pi, int cont, int reg, int val)
+{
+	/* check for bad settings */
+	if (reg >= 0 && reg <= 7 && cont >= 0 && cont <= 1)
+		ppc6_wr_port(PPCSTRUCT(pi), cont ? reg | 8 : reg, (u8)val);
+}
+
+static void bpck6_write_block(struct pi_adapter *pi, char *buf, int len)
+{
+	ppc6_wr_port16_blk(PPCSTRUCT(pi), ATAPI_DATA, buf, (u32)len >> 1);
+}
+
+static void bpck6_read_block(struct pi_adapter *pi, char *buf, int len)
+{
+	ppc6_rd_port16_blk(PPCSTRUCT(pi), ATAPI_DATA, buf, (u32) len >> 1);
+}
+
+static void bpck6_connect(struct pi_adapter *pi)
+{
+	if (pi->mode >= 2)
+		PPCSTRUCT(pi)->mode = 4 + pi->mode - 2;
+	else if (pi->mode == 1)
+		PPCSTRUCT(pi)->mode = 3;
+	else
+		PPCSTRUCT(pi)->mode = 1;
+
+	ppc6_open(PPCSTRUCT(pi));
+	ppc6_wr_extout(PPCSTRUCT(pi), 0x3);
+}
+
+static void bpck6_disconnect(struct pi_adapter *pi)
+{
+	ppc6_wr_extout(PPCSTRUCT(pi), 0x0);
+	ppc6_close(PPCSTRUCT(pi));
+}
+
+static int bpck6_test_port(struct pi_adapter *pi)   /* check for 8-bit port */
+{
+	/* copy over duplicate stuff.. initialize state info */
+	PPCSTRUCT(pi)->ppc_id = pi->unit;
+	PPCSTRUCT(pi)->lpt_addr = pi->port;
+
+	/* look at the parport device to see if what modes we can use */
+	if (((struct pardevice *)(pi->pardev))->port->modes &
+	    (PARPORT_MODE_EPP))
+		return 5; /* Can do EPP*/
+	else if (((struct pardevice *)(pi->pardev))->port->modes &
+		 (PARPORT_MODE_TRISTATE))
+		return 2;
+	else /* Just flat SPP */
+		return 1;
+}
+
+static int bpck6_probe_unit(struct pi_adapter *pi)
+{
+	int out;
+
+	/* SET PPC UNIT NUMBER */
+	PPCSTRUCT(pi)->ppc_id = pi->unit;
+
+	/* LOWER DOWN TO UNIDIRECTIONAL */
+	PPCSTRUCT(pi)->mode = 1;
+
+	out = ppc6_open(PPCSTRUCT(pi));
+
+	if (out) {
+		ppc6_close(PPCSTRUCT(pi));
+		return 1;
+	}
+
+	return 0;
+}
+
+static void bpck6_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	static char * const mode_string[] = {
+		"4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
+
+	dev_info(&pi->dev, "bpck6, Micro Solutions BACKPACK Drive at 0x%x\n",
+		pi->port);
+	dev_info(&pi->dev, "Unit: %d Mode:%d (%s) Delay %d\n",
+		pi->unit, pi->mode, mode_string[pi->mode], pi->delay);
+}
+
+static int bpck6_init_proto(struct pi_adapter *pi)
+{
+	struct ppc_storage *p = kzalloc(sizeof(struct ppc_storage), GFP_KERNEL);
+
+	if (p) {
+		pi->private = (unsigned long)p;
+		return 0;
+	}
+
+	return -ENOMEM;
+}
+
+static void bpck6_release_proto(struct pi_adapter *pi)
+{
+	kfree((void *)(pi->private));
+}
+
+static struct pi_protocol bpck6 = {
+	.owner		= THIS_MODULE,
+	.name		= "bpck6",
+	.max_mode	= 5,
+	.epp_first	= 2, /* 2-5 use epp (need 8 ports) */
+	.max_units	= 255,
+	.write_regr	= bpck6_write_regr,
+	.read_regr	= bpck6_read_regr,
+	.write_block	= bpck6_write_block,
+	.read_block	= bpck6_read_block,
+	.connect	= bpck6_connect,
+	.disconnect	= bpck6_disconnect,
+	.test_port	= bpck6_test_port,
+	.probe_unit	= bpck6_probe_unit,
+	.log_adapter	= bpck6_log_adapter,
+	.init_proto	= bpck6_init_proto,
+	.release_proto	= bpck6_release_proto,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-bpck6") },
+};
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Micro Solutions Inc.");
+MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
+module_pata_parport_driver(bpck6);
diff --git a/drivers/ata/pata_parport/ppc6lnx.c b/drivers/ata/pata_parport/ppc6lnx.c
new file mode 100644
index 000000000000..52e0f08548c9
--- /dev/null
+++ b/drivers/ata/pata_parport/ppc6lnx.c
@@ -0,0 +1,486 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	ppc6lnx.c (c) 2001 Micro Solutions Inc.
+ *		Released under the terms of the GNU General Public license
+ *
+ *	ppc6lnx.c  is a part of the protocol driver for the Micro Solutions
+ *		"BACKPACK" parallel port IDE adapter
+ *		(Works on Series 6 drives)
+ */
+
+/* PPC 6 Code in C sanitized for LINUX */
+/* Original x86 ASM by Ron, Converted to C by Clive */
+
+#define port_stb	1
+#define port_afd	2
+#define cmd_stb		port_afd
+#define port_init	4
+#define data_stb	port_init
+#define port_sel	8
+#define port_int	16
+#define port_dir	0x20
+
+#define ECR_EPP		0x80
+#define ECR_BI		0x20
+
+/* 60772 Commands */
+#define ACCESS_REG	0x00
+#define ACCESS_PORT	0x40
+
+#define ACCESS_READ	0x00
+#define ACCESS_WRITE	0x20
+
+/* 60772 Command Prefix */
+
+#define CMD_PREFIX_SET		0xe0	/* Special cmd that modifies the next command's operation */
+#define CMD_PREFIX_RESET	0xc0	/* Resets current cmd modifier reg bits */
+ #define PREFIX_IO16		0x01	/* perform 16-bit wide I/O */
+ #define PREFIX_FASTWR		0x04	/* enable PPC mode fast-write */
+ #define PREFIX_BLK		0x08	/* enable block transfer mode */
+
+/* 60772 Registers */
+
+#define REG_STATUS		0x00	/* status register */
+ #define STATUS_IRQA		0x01	/* Peripheral IRQA line */
+ #define STATUS_EEPROM_DO	0x40	/* Serial EEPROM data bit */
+#define REG_VERSION		0x01	/* PPC version register (read) */
+#define REG_HWCFG		0x02	/* Hardware Config register */
+#define REG_RAMSIZE		0x03	/* Size of RAM Buffer */
+ #define RAMSIZE_128K		0x02
+#define REG_EEPROM		0x06	/* EEPROM control register */
+ #define EEPROM_SK		0x01	/* eeprom SK bit */
+ #define EEPROM_DI		0x02	/* eeprom DI bit */
+ #define EEPROM_CS		0x04	/* eeprom CS bit */
+ #define EEPROM_EN		0x08	/* eeprom output enable */
+#define REG_BLKSIZE		0x08	/* Block transfer len (24 bit) */
+
+struct ppc_storage {
+	u16	lpt_addr;		/* LPT base address */
+	u8	ppc_id;
+	u8	mode;			/* operating mode */
+					/* 0 = PPC Uni SW */
+					/* 1 = PPC Uni FW */
+					/* 2 = PPC Bi SW */
+					/* 3 = PPC Bi FW */
+					/* 4 = EPP Byte */
+					/* 5 = EPP Word */
+					/* 6 = EPP Dword */
+	u8	ppc_flags;
+	u8	org_data;		/* original LPT data port contents */
+	u8	org_ctrl;		/* original LPT control port contents */
+	u8	cur_ctrl;		/* current control port contents */
+};
+
+/* ppc_flags */
+#define fifo_wait		0x10
+
+/* DONT CHANGE THESE LEST YOU BREAK EVERYTHING - BIT FIELD DEPENDENCIES */
+#define PPCMODE_UNI_SW		0
+#define PPCMODE_UNI_FW		1
+#define PPCMODE_BI_SW		2
+#define PPCMODE_BI_FW		3
+#define PPCMODE_EPP_BYTE	4
+#define PPCMODE_EPP_WORD	5
+#define PPCMODE_EPP_DWORD	6
+
+static int ppc6_select(struct ppc_storage *ppc);
+static void ppc6_deselect(struct ppc_storage *ppc);
+static void ppc6_send_cmd(struct ppc_storage *ppc, u8 cmd);
+static void ppc6_wr_data_byte(struct ppc_storage *ppc, u8 data);
+static u8 ppc6_rd_data_byte(struct ppc_storage *ppc);
+static u8 ppc6_rd_port(struct ppc_storage *ppc, u8 port);
+static void ppc6_wr_port(struct ppc_storage *ppc, u8 port, u8 data);
+static void ppc6_rd_data_blk(struct ppc_storage *ppc, u8 *data, long count);
+static void ppc6_wait_for_fifo(struct ppc_storage *ppc);
+static void ppc6_wr_data_blk(struct ppc_storage *ppc, u8 *data, long count);
+static void ppc6_rd_port16_blk(struct ppc_storage *ppc, u8 port, u8 *data, long length);
+static void ppc6_wr_port16_blk(struct ppc_storage *ppc, u8 port, u8 *data, long length);
+static void ppc6_wr_extout(struct ppc_storage *ppc, u8 regdata);
+static int ppc6_open(struct ppc_storage *ppc);
+static void ppc6_close(struct ppc_storage *ppc);
+
+static int ppc6_select(struct ppc_storage *ppc)
+{
+	u8 i, j, k;
+
+	i = inb(ppc->lpt_addr + 1);
+	if (i & 1)
+		outb(i, ppc->lpt_addr + 1);
+
+	ppc->org_data = inb(ppc->lpt_addr);
+	ppc->org_ctrl = inb(ppc->lpt_addr + 2) & 0x5F; /* readback ctrl */
+	ppc->cur_ctrl = ppc->org_ctrl;
+	ppc->cur_ctrl |= port_sel;
+	outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+	if (ppc->org_data == 'b')
+		outb('x', ppc->lpt_addr);
+	outb('b', ppc->lpt_addr);
+	outb('p', ppc->lpt_addr);
+	outb(ppc->ppc_id, ppc->lpt_addr);
+	outb(~ppc->ppc_id, ppc->lpt_addr);
+	ppc->cur_ctrl &= ~port_sel;
+	outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+	ppc->cur_ctrl = (ppc->cur_ctrl & port_int) | port_init;
+	outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+	i = ppc->mode & 0x0C;
+	if (i == 0)
+		i = (ppc->mode & 2) | 1;
+	outb(i, ppc->lpt_addr);
+	ppc->cur_ctrl |= port_sel;
+	outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+	/* DELAY */
+	ppc->cur_ctrl |= port_afd;
+	outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+	j = ((i & 0x08) << 4) | ((i & 0x07) << 3);
+	k = inb(ppc->lpt_addr + 1) & 0xB8;
+	if (j == k) {
+		ppc->cur_ctrl &= ~port_afd;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		k = (inb(ppc->lpt_addr + 1) & 0xB8) ^ 0xB8;
+		if (j == k) {
+			if (i & 4)	/* EPP */
+				ppc->cur_ctrl &= ~(port_sel | port_init);
+			else		/* PPC/ECP */
+				ppc->cur_ctrl &= ~port_sel;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			return 1;
+		}
+	}
+	outb(ppc->org_ctrl, ppc->lpt_addr + 2);
+	outb(ppc->org_data, ppc->lpt_addr);
+
+	return 0; /* FAIL */
+}
+
+static void ppc6_deselect(struct ppc_storage *ppc)
+{
+	if (ppc->mode & 4)	/* EPP */
+		ppc->cur_ctrl |= port_init;
+	else			/* PPC/ECP */
+		ppc->cur_ctrl |= port_sel;
+
+	outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+	outb(ppc->org_data, ppc->lpt_addr);
+	outb((ppc->org_ctrl | port_sel), ppc->lpt_addr + 2);
+	outb(ppc->org_ctrl, ppc->lpt_addr + 2);
+}
+
+static void ppc6_send_cmd(struct ppc_storage *ppc, u8 cmd)
+{
+	switch (ppc->mode) {
+	case PPCMODE_UNI_SW:
+	case PPCMODE_UNI_FW:
+	case PPCMODE_BI_SW:
+	case PPCMODE_BI_FW:
+		outb(cmd, ppc->lpt_addr);
+		ppc->cur_ctrl ^= cmd_stb;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		break;
+	case PPCMODE_EPP_BYTE:
+	case PPCMODE_EPP_WORD:
+	case PPCMODE_EPP_DWORD:
+		outb(cmd, ppc->lpt_addr + 3);
+		break;
+	}
+}
+
+static void ppc6_wr_data_byte(struct ppc_storage *ppc, u8 data)
+{
+	switch (ppc->mode) {
+	case PPCMODE_UNI_SW:
+	case PPCMODE_UNI_FW:
+	case PPCMODE_BI_SW:
+	case PPCMODE_BI_FW:
+		outb(data, ppc->lpt_addr);
+		ppc->cur_ctrl ^= data_stb;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		break;
+	case PPCMODE_EPP_BYTE:
+	case PPCMODE_EPP_WORD:
+	case PPCMODE_EPP_DWORD:
+		outb(data, ppc->lpt_addr + 4);
+		break;
+	}
+}
+
+static u8 ppc6_rd_data_byte(struct ppc_storage *ppc)
+{
+	u8 data = 0;
+
+	switch (ppc->mode) {
+	case PPCMODE_UNI_SW:
+	case PPCMODE_UNI_FW:
+		ppc->cur_ctrl = (ppc->cur_ctrl & ~port_stb) ^ data_stb;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		/* DELAY */
+		data = inb(ppc->lpt_addr + 1);
+		data = ((data & 0x80) >> 1) | ((data & 0x38) >> 3);
+		ppc->cur_ctrl |= port_stb;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		/* DELAY */
+		data |= inb(ppc->lpt_addr + 1) & 0xB8;
+		break;
+	case PPCMODE_BI_SW:
+	case PPCMODE_BI_FW:
+		ppc->cur_ctrl |= port_dir;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		ppc->cur_ctrl = (ppc->cur_ctrl | port_stb) ^ data_stb;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		data = inb(ppc->lpt_addr);
+		ppc->cur_ctrl &= ~port_stb;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		ppc->cur_ctrl &= ~port_dir;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		break;
+	case PPCMODE_EPP_BYTE:
+	case PPCMODE_EPP_WORD:
+	case PPCMODE_EPP_DWORD:
+		outb((ppc->cur_ctrl | port_dir), ppc->lpt_addr + 2);
+		data = inb(ppc->lpt_addr + 4);
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		break;
+	}
+
+	return data;
+}
+
+static u8 ppc6_rd_port(struct ppc_storage *ppc, u8 port)
+{
+	ppc6_send_cmd(ppc, port | ACCESS_PORT | ACCESS_READ);
+
+	return ppc6_rd_data_byte(ppc);
+}
+
+static void ppc6_wr_port(struct ppc_storage *ppc, u8 port, u8 data)
+{
+	ppc6_send_cmd(ppc, port | ACCESS_PORT | ACCESS_WRITE);
+
+	ppc6_wr_data_byte(ppc, data);
+}
+
+static void ppc6_rd_data_blk(struct ppc_storage *ppc, u8 *data, long count)
+{
+	switch (ppc->mode) {
+	case PPCMODE_UNI_SW:
+	case PPCMODE_UNI_FW:
+		while (count) {
+			u8 d;
+
+			ppc->cur_ctrl = (ppc->cur_ctrl & ~port_stb) ^ data_stb;
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+			/* DELAY */
+			d = inb(ppc->lpt_addr + 1);
+			d = ((d & 0x80) >> 1) | ((d & 0x38) >> 3);
+			ppc->cur_ctrl |= port_stb;
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+			/* DELAY */
+			d |= inb(ppc->lpt_addr + 1) & 0xB8;
+			*data++ = d;
+			count--;
+		}
+		break;
+	case PPCMODE_BI_SW:
+	case PPCMODE_BI_FW:
+		ppc->cur_ctrl |= port_dir;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		ppc->cur_ctrl |= port_stb;
+		while (count) {
+			ppc->cur_ctrl ^= data_stb;
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+			*data++ = inb(ppc->lpt_addr);
+			count--;
+		}
+		ppc->cur_ctrl &= ~port_stb;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		ppc->cur_ctrl &= ~port_dir;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		break;
+	case PPCMODE_EPP_BYTE:
+		outb((ppc->cur_ctrl | port_dir), ppc->lpt_addr + 2);
+		/* DELAY */
+		while (count) {
+			*data++ = inb(ppc->lpt_addr + 4);
+			count--;
+		}
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		break;
+	case PPCMODE_EPP_WORD:
+		outb((ppc->cur_ctrl | port_dir), ppc->lpt_addr + 2);
+		/* DELAY */
+		while (count > 1) {
+			*((u16 *)data) = inw(ppc->lpt_addr + 4);
+			data  += 2;
+			count -= 2;
+		}
+		while (count) {
+			*data++ = inb(ppc->lpt_addr + 4);
+			count--;
+		}
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		break;
+	case PPCMODE_EPP_DWORD:
+		outb((ppc->cur_ctrl | port_dir), ppc->lpt_addr + 2);
+		/* DELAY */
+		while (count > 3) {
+			*((u32 *)data) = inl(ppc->lpt_addr + 4);
+			data  += 4;
+			count -= 4;
+		}
+		while (count) {
+			*data++ = inb(ppc->lpt_addr + 4);
+			count--;
+		}
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		break;
+	}
+}
+
+static void ppc6_wait_for_fifo(struct ppc_storage *ppc)
+{
+	int i;
+
+	if (ppc->ppc_flags & fifo_wait)
+		for (i = 0; i < 20; i++)
+			inb(ppc->lpt_addr + 1);
+}
+
+static void ppc6_wr_data_blk(struct ppc_storage *ppc, u8 *data, long count)
+{
+	u8 this, last;
+
+	switch (ppc->mode) {
+	case PPCMODE_UNI_SW:
+	case PPCMODE_BI_SW:
+		while (count--)	{
+			outb(*data++, ppc->lpt_addr);
+			ppc->cur_ctrl ^= data_stb;
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		}
+		break;
+	case PPCMODE_UNI_FW:
+	case PPCMODE_BI_FW:
+		ppc6_send_cmd(ppc, CMD_PREFIX_SET | PREFIX_FASTWR);
+		ppc->cur_ctrl |= port_stb;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		last = *data;
+		outb(last, ppc->lpt_addr);
+		while (count) {
+			this = *data++;
+			count--;
+
+			if (this == last) {
+				ppc->cur_ctrl ^= data_stb;
+				outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+			} else {
+				outb(this, ppc->lpt_addr);
+				last = this;
+			}
+		}
+		ppc->cur_ctrl &= ~port_stb;
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+		ppc6_send_cmd(ppc, CMD_PREFIX_RESET | PREFIX_FASTWR);
+		break;
+	case PPCMODE_EPP_BYTE:
+		while (count) {
+			outb(*data++, ppc->lpt_addr + 4);
+			count--;
+		}
+		ppc6_wait_for_fifo(ppc);
+		break;
+	case PPCMODE_EPP_WORD:
+		while (count > 1) {
+			outw(*((u16 *)data), ppc->lpt_addr + 4);
+			data  += 2;
+			count -= 2;
+		}
+		while (count) {
+			outb(*data++, ppc->lpt_addr + 4);
+			count--;
+		}
+		ppc6_wait_for_fifo(ppc);
+		break;
+	case PPCMODE_EPP_DWORD:
+		while (count > 3) {
+			outl(*((u32 *)data), ppc->lpt_addr + 4);
+			data  += 4;
+			count -= 4;
+		}
+		while (count) {
+			outb(*data++, ppc->lpt_addr + 4);
+			count--;
+		}
+		ppc6_wait_for_fifo(ppc);
+		break;
+	}
+}
+
+static void ppc6_rd_port16_blk(struct ppc_storage *ppc, u8 port, u8 *data, long length)
+{
+	length = length << 1;
+
+	ppc6_send_cmd(ppc, REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE);
+	ppc6_wr_data_byte(ppc, (u8)length);
+	ppc6_wr_data_byte(ppc, (u8)(length >> 8));
+	ppc6_wr_data_byte(ppc, 0);
+
+	ppc6_send_cmd(ppc, CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK);
+
+	ppc6_send_cmd(ppc, port | ACCESS_PORT | ACCESS_READ);
+
+	ppc6_rd_data_blk(ppc, data, length);
+
+	ppc6_send_cmd(ppc, CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK);
+}
+
+static void ppc6_wr_port16_blk(struct ppc_storage *ppc, u8 port, u8 *data, long length)
+{
+	length = length << 1;
+
+	ppc6_send_cmd(ppc, REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE);
+	ppc6_wr_data_byte(ppc, (u8)length);
+	ppc6_wr_data_byte(ppc, (u8)(length >> 8));
+	ppc6_wr_data_byte(ppc, 0);
+
+	ppc6_send_cmd(ppc, CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK);
+
+	ppc6_send_cmd(ppc, port | ACCESS_PORT | ACCESS_WRITE);
+
+	ppc6_wr_data_blk(ppc, data, length);
+
+	ppc6_send_cmd(ppc, CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK);
+}
+
+static void ppc6_wr_extout(struct ppc_storage *ppc, u8 regdata)
+{
+	ppc6_send_cmd(ppc, REG_VERSION | ACCESS_REG | ACCESS_WRITE);
+
+	ppc6_wr_data_byte(ppc, (regdata & 0x03) << 6);
+}
+
+static int ppc6_open(struct ppc_storage *ppc)
+{
+	int ret;
+
+	ret = ppc6_select(ppc);
+	if (ret == 0)
+		return ret;
+
+	ppc->ppc_flags &= ~fifo_wait;
+
+	ppc6_send_cmd(ppc, ACCESS_REG | ACCESS_WRITE | REG_RAMSIZE);
+	ppc6_wr_data_byte(ppc, RAMSIZE_128K);
+
+	ppc6_send_cmd(ppc, ACCESS_REG | ACCESS_READ | REG_VERSION);
+
+	if ((ppc6_rd_data_byte(ppc) & 0x3F) == 0x0C)
+		ppc->ppc_flags |= fifo_wait;
+
+	return ret;
+}
+
+static void ppc6_close(struct ppc_storage *ppc)
+{
+	ppc6_deselect(ppc);
+}
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:14:00 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:14:00 +0100
Subject: [Linux-parport] [PATCH 05/16] pata_parport: add comm protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-6-linux@zary.sk>

Add DataStor Commuter protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  10 ++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/comm.c   | 198 ++++++++++++++++++++++++++++++
 3 files changed, 209 insertions(+)
 create mode 100644 drivers/ata/pata_parport/comm.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index e88d9c0bedc6..3cc3d6ae4d45 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -54,3 +54,13 @@ config PATA_PARPORT_BPCK6
 	  answer Y here to build in the protocol driver, otherwise you should
 	  answer M to build it as a loadable module.  The module will be
 	  called bpck6.
+
+config PATA_PARPORT_COMM
+	tristate "DataStor Commuter protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the Commuter parallel port IDE
+	  protocol from DataStor. If you chose to build PATA_PARPORT support
+	  into your kernel, you may answer Y here to build in the protocol
+	  driver, otherwise you should answer M to build it as a loadable
+	  module. The module will be called comm.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index 60522279aa16..fcb77a855ef6 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_PATA_PARPORT)		+= pata_parport.o
 obj-$(CONFIG_PATA_PARPORT_ATEN)		+= aten.o
 obj-$(CONFIG_PATA_PARPORT_BPCK)		+= bpck.o
 obj-$(CONFIG_PATA_PARPORT_BPCK6)	+= bpck6.o
+obj-$(CONFIG_PATA_PARPORT_COMM)		+= comm.o
diff --git a/drivers/ata/pata_parport/comm.c b/drivers/ata/pata_parport/comm.c
new file mode 100644
index 000000000000..cca67e15b498
--- /dev/null
+++ b/drivers/ata/pata_parport/comm.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	comm.c    (c) 1997-8  Grant R. Guenther <grant at torque.net>
+ *			      Under the terms of the GNU General Public License.
+ *
+ *	comm.c is a low-level protocol driver for some older models
+ *	of the DataStor "Commuter" parallel to IDE adapter.  Some of
+ *	the parallel port devices marketed by Arista currently
+ *	use this adapter.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+/* mode codes:  0  nybble reads, 8-bit writes
+ *		1  8-bit reads and writes
+ *		2  8-bit EPP mode
+ */
+
+#define j44(a, b)	(((a >> 3) & 0x0f) | ((b << 1) & 0xf0))
+
+#define P1	do { w2(5); w2(0xd); w2(0xd); w2(5); w2(4); } while (0)
+#define P2	do { w2(5); w2(7); w2(7); w2(5); w2(4); } while (0)
+
+/* cont = 0 - access the IDE register file
+ * cont = 1 - access the IDE command set
+ */
+
+static int cont_map[2] = { 0x08, 0x10 };
+
+static int comm_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int l, h, r;
+
+	r = regr + cont_map[cont];
+
+	switch (pi->mode)  {
+	case 0:
+		w0(r); P1; w0(0);
+		w2(6); l = r1(); w0(0x80); h = r1(); w2(4);
+		return j44(l, h);
+	case 1:
+		w0(r+0x20); P1;
+		w0(0); w2(0x26); h = r0(); w2(4);
+		return h;
+	case 2:
+	case 3:
+	case 4:
+		w3(r+0x20); (void)r1();
+		w2(0x24); h = r4(); w2(4);
+		return h;
+	}
+	return -1;
+}
+
+static void comm_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	int r = regr + cont_map[cont];
+
+	switch (pi->mode)  {
+	case 0:
+	case 1:
+		w0(r); P1; w0(val); P2;
+		break;
+	case 2:
+	case 3:
+	case 4:
+		w3(r); (void)r1(); w4(val);
+		break;
+	}
+}
+
+static void comm_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+	w2(4); w0(0xff); w2(6);
+	w2(4); w0(0xaa); w2(6);
+	w2(4); w0(0x00); w2(6);
+	w2(4); w0(0x87); w2(6);
+	w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);
+}
+
+static void comm_disconnect(struct pi_adapter *pi)
+{
+	w2(0); w2(0); w2(0); w2(4);
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+static void comm_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int i, l, h;
+
+	switch (pi->mode) {
+	case 0:
+		w0(0x48); P1;
+		for (i = 0; i < count; i++) {
+			w0(0); w2(6); l = r1();
+			w0(0x80); h = r1(); w2(4);
+			buf[i] = j44(l, h);
+		}
+		break;
+	case 1:
+		w0(0x68); P1; w0(0);
+		for (i = 0; i < count; i++) {
+			w2(0x26); buf[i] = r0(); w2(0x24);
+		}
+		w2(4);
+		break;
+	case 2:
+		w3(0x68); (void)r1(); w2(0x24);
+		for (i = 0; i < count; i++)
+			buf[i] = r4();
+		w2(4);
+		break;
+	case 3:
+		w3(0x68); (void)r1(); w2(0x24);
+		for (i = 0; i < count / 2; i++)
+			((u16 *)buf)[i] = r4w();
+		w2(4);
+		break;
+	case 4:
+		w3(0x68); (void)r1(); w2(0x24);
+		for (i = 0; i < count / 4; i++)
+			((u32 *)buf)[i] = r4l();
+		w2(4);
+		break;
+	}
+}
+
+/* NB: Watch out for the byte swapped writes ! */
+static void comm_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k;
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+		w0(0x68); P1;
+		for (k = 0; k < count; k++) {
+			w2(5); w0(buf[k^1]); w2(7);
+		}
+		w2(5); w2(4);
+		break;
+	case 2:
+		w3(0x48); (void)r1();
+		for (k = 0; k < count; k++)
+			w4(buf[k^1]);
+		break;
+	case 3:
+		w3(0x48); (void)r1();
+		for (k = 0; k < count / 2; k++)
+			w4w(pi_swab16(buf, k));
+		break;
+	case 4:
+		w3(0x48); (void)r1();
+		for (k = 0; k < count / 4; k++)
+			w4l(pi_swab32(buf, k));
+		break;
+	}
+}
+
+static void comm_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	static char * const mode_string[] = {
+		"4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
+
+	dev_info(&pi->dev, "comm, DataStor Commuter at 0x%x, mode %d (%s), delay %d\n",
+		pi->port, pi->mode, mode_string[pi->mode], pi->delay);
+}
+
+static struct pi_protocol comm = {
+	.owner		= THIS_MODULE,
+	.name		= "comm",
+	.max_mode	= 5,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= comm_write_regr,
+	.read_regr	= comm_read_regr,
+	.write_block	= comm_write_block,
+	.read_block	= comm_read_block,
+	.connect	= comm_connect,
+	.disconnect	= comm_disconnect,
+	.log_adapter	= comm_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-comm") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(comm);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:14:01 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:14:01 +0100
Subject: [Linux-parport] [PATCH 06/16] pata_parport: add dstr protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-7-linux@zary.sk>

Add DataStor EP-2000 protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  10 ++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/dstr.c   | 226 ++++++++++++++++++++++++++++++
 3 files changed, 237 insertions(+)
 create mode 100644 drivers/ata/pata_parport/dstr.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index 3cc3d6ae4d45..67f203dfbdca 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -64,3 +64,13 @@ config PATA_PARPORT_COMM
 	  into your kernel, you may answer Y here to build in the protocol
 	  driver, otherwise you should answer M to build it as a loadable
 	  module. The module will be called comm.
+
+config PATA_PARPORT_DSTR
+	tristate "DataStor EP-2000 protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the EP-2000 parallel port IDE
+	  protocol from DataStor. If you chose to build PATA_PARPORT support
+	  into your kernel, you may answer Y here to build in the protocol
+	  driver, otherwise you should answer M to build it as a loadable
+	  module. The module will be called dstr.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index fcb77a855ef6..bf81c4ca32ab 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_PATA_PARPORT_ATEN)		+= aten.o
 obj-$(CONFIG_PATA_PARPORT_BPCK)		+= bpck.o
 obj-$(CONFIG_PATA_PARPORT_BPCK6)	+= bpck6.o
 obj-$(CONFIG_PATA_PARPORT_COMM)		+= comm.o
+obj-$(CONFIG_PATA_PARPORT_DSTR)		+= dstr.o
diff --git a/drivers/ata/pata_parport/dstr.c b/drivers/ata/pata_parport/dstr.c
new file mode 100644
index 000000000000..2e1e078fa467
--- /dev/null
+++ b/drivers/ata/pata_parport/dstr.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	dstr.c    (c) 1997-8  Grant R. Guenther <grant at torque.net>
+ *			      Under the terms of the GNU General Public License.
+ *
+ *	dstr.c is a low-level protocol driver for the
+ *	DataStor EP2000 parallel to IDE adapter chip.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+/* mode codes:  0  nybble reads, 8-bit writes
+ *		1  8-bit reads and writes
+ *		2  8-bit EPP mode
+ *		3  EPP-16
+ *		4  EPP-32
+ */
+
+#define j44(a, b)  (((a >> 3) & 0x07) | ((~a >> 4) & 0x08) | ((b << 1) & 0x70) | ((~b) & 0x80))
+
+#define P1	do { w2(5); w2(0xd); w2(5); w2(4); } while (0)
+#define P2	do { w2(5); w2(7); w2(5); w2(4); } while (0)
+#define P3      do { w2(6); w2(4); w2(6); w2(4); } while (0)
+
+/* cont = 0 - access the IDE register file
+ * cont = 1 - access the IDE command set
+ */
+
+static int cont_map[2] = { 0x20, 0x40 };
+
+static int dstr_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int a, b, r;
+
+	r = regr + cont_map[cont];
+
+	w0(0x81); P1;
+	if (pi->mode)
+		w0(0x11);
+	else
+		w0(1);
+	P2; w0(r); P1;
+
+	switch (pi->mode) {
+	case 0:
+		w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4);
+		return j44(a, b);
+	case 1:
+		w0(0); w2(0x26); a = r0(); w2(4);
+		return a;
+	case 2:
+	case 3:
+	case 4:
+		w2(0x24); a = r4(); w2(4);
+		return a;
+	}
+	return -1;
+}
+
+static void dstr_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	int r = regr + cont_map[cont];
+
+	w0(0x81); P1;
+	if (pi->mode >= 2)
+		w0(0x11);
+	else
+		w0(1);
+	P2; w0(r); P1;
+
+	switch (pi->mode)  {
+	case 0:
+	case 1:
+		w0(val); w2(5); w2(7); w2(5); w2(4);
+		break;
+	case 2:
+	case 3:
+	case 4:
+		w4(val);
+		break;
+	}
+}
+
+#define CCP(x)	do { w0(0xff); w2(0xc); w2(4);\
+		     w0(0xaa); w0(0x55); w0(0); w0(0xff); w0(0x87); w0(0x78);\
+		     w0(x); w2(5); w2(4);\
+		} while (0)
+
+static void dstr_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+	w2(4); CCP(0xe0); w0(0xff);
+}
+
+static void dstr_disconnect(struct pi_adapter *pi)
+{
+	CCP(0x30);
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+static void dstr_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k, a, b;
+
+	w0(0x81); P1;
+	if (pi->mode)
+		w0(0x19);
+	else
+		w0(9);
+	P2; w0(0x82); P1; P3; w0(0x20); P1;
+
+	switch (pi->mode) {
+	case 0:
+		for (k = 0; k < count; k++) {
+			w2(6); a = r1(); w2(4);
+			w2(6); b = r1(); w2(4);
+			buf[k] = j44(a, b);
+		}
+		break;
+	case 1:
+		w0(0);
+		for (k = 0; k < count; k++) {
+			w2(0x26); buf[k] = r0(); w2(0x24);
+		}
+		w2(4);
+		break;
+	case 2:
+		w2(0x24);
+		for (k = 0; k < count; k++)
+			buf[k] = r4();
+		w2(4);
+		break;
+	case 3:
+		w2(0x24);
+		for (k = 0; k < count / 2; k++)
+			((u16 *)buf)[k] = r4w();
+		w2(4);
+		break;
+	case 4:
+		w2(0x24);
+		for (k = 0; k < count / 4; k++)
+			((u32 *)buf)[k] = r4l();
+		w2(4);
+		break;
+	}
+}
+
+static void dstr_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k;
+
+	w0(0x81); P1;
+	if (pi->mode)
+		w0(0x19);
+	else
+		w0(9);
+	P2; w0(0x82); P1; P3; w0(0x20); P1;
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+		for (k = 0; k < count; k++) {
+			w2(5); w0(buf[k]); w2(7);
+		}
+		w2(5); w2(4);
+		break;
+	case 2:
+		w2(0xc5);
+		for (k = 0; k < count; k++)
+			w4(buf[k]);
+		w2(0xc4);
+		break;
+	case 3:
+		w2(0xc5);
+		for (k = 0; k < count / 2; k++)
+			w4w(((u16 *)buf)[k]);
+		w2(0xc4);
+		break;
+	case 4:
+		w2(0xc5);
+		for (k = 0; k < count / 4; k++)
+			w4l(((u32 *)buf)[k]);
+		w2(0xc4);
+		break;
+	}
+}
+
+
+static void dstr_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	static char * const mode_string[] = {
+		"4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
+
+	dev_info(&pi->dev, "dstr, DataStor EP2000 at 0x%x, mode %d (%s), delay %d\n",
+		pi->port, pi->mode, mode_string[pi->mode], pi->delay);
+}
+
+static struct pi_protocol dstr = {
+	.owner		= THIS_MODULE,
+	.name		= "dstr",
+	.max_mode	= 5,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= dstr_write_regr,
+	.read_regr	= dstr_read_regr,
+	.write_block	= dstr_write_block,
+	.read_block	= dstr_read_block,
+	.connect	= dstr_connect,
+	.disconnect	= dstr_disconnect,
+	.log_adapter	= dstr_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-dstr") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(dstr);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:13:56 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:13:56 +0100
Subject: [Linux-parport] [PATCH 01/16] pata_parport: add core driver (PARIDE
 replacement)
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-2-linux@zary.sk>

Add pata_parport (PARIDE replacement) core libata driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/Kconfig                     |  25 +
 drivers/ata/Makefile                    |   2 +
 drivers/ata/pata_parport/Kconfig        |  10 +
 drivers/ata/pata_parport/Makefile       |   9 +
 drivers/ata/pata_parport/pata_parport.c | 809 ++++++++++++++++++++++++
 drivers/ata/pata_parport/pata_parport.h | 110 ++++
 6 files changed, 965 insertions(+)
 create mode 100644 drivers/ata/pata_parport/Kconfig
 create mode 100644 drivers/ata/pata_parport/Makefile
 create mode 100644 drivers/ata/pata_parport/pata_parport.c
 create mode 100644 drivers/ata/pata_parport/pata_parport.h

diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index cb54631fd950..de4548471398 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -1161,6 +1161,31 @@ config PATA_WINBOND_VLB
 	  Support for the Winbond W83759A controller on Vesa Local Bus
 	  systems.
 
+config PATA_PARPORT
+	tristate "Parallel port IDE device support (PARIDE replacement)"
+	depends on PARPORT_PC
+	help
+	  There are many external CD-ROM and disk devices that connect through
+	  your computer's parallel port. Most of them are actually IDE devices
+	  using a parallel port IDE adapter. This option enables the PATA_PARPORT
+	  subsystem which contains drivers for many of these external drives.
+	  Read <file:Documentation/admin-guide/blockdev/paride.rst> for more information.
+
+	  If you have said Y to the "Parallel-port support" configuration
+	  option, you may share a single port between your printer and other
+	  parallel port devices. Answer Y to build PATA_PARPORT support into your
+	  kernel, or M if you would like to build it as a loadable module. If
+	  your parallel port support is in a loadable module, you must build
+	  PATA_PARPORT as a module. If you built PATA_PARPORT support into your kernel,
+	  you may still build the individual protocol modules as loadable
+	  modules. If you build this support as a module, it will be called pata_parport.
+
+	  Unlike the old PARIDE, there are no high-level drivers needed.
+	  The IDE devices behind parallel port adapters are handled by the
+	  ATA layer.
+
+source "drivers/ata/pata_parport/Kconfig"
+
 comment "Generic fallback / legacy drivers"
 
 config PATA_ACPI
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index b8aebfb14e82..bd6b5fdc004e 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -114,6 +114,8 @@ obj-$(CONFIG_PATA_SAMSUNG_CF)	+= pata_samsung_cf.o
 
 obj-$(CONFIG_PATA_PXA)		+= pata_pxa.o
 
+obj-$(CONFIG_PATA_PARPORT)	+= pata_parport/
+
 # Should be last but two libata driver
 obj-$(CONFIG_PATA_ACPI)		+= pata_acpi.o
 # Should be last but one libata driver
diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
new file mode 100644
index 000000000000..56dc6b25d5fa
--- /dev/null
+++ b/drivers/ata/pata_parport/Kconfig
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# PATA_PARPORT configuration
+#
+# PATA_PARPORT doesn't need PARPORT, but if PARPORT is configured as a module,
+# PATA_PARPORT must also be a module.
+# PATA_PARPORT only supports PC style parports. Tough for USB or other parports...
+
+comment "Parallel IDE protocol modules"
+	depends on PATA_PARPORT
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
new file mode 100644
index 000000000000..b105e1cb8dc6
--- /dev/null
+++ b/drivers/ata/pata_parport/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for Parallel port IDE device drivers.
+#
+# 7 October 2000, Bartlomiej Zolnierkiewicz <bkz at linux-ide.org>
+# Rewritten to use lists instead of if-statements.
+#
+
+obj-$(CONFIG_PATA_PARPORT)		+= pata_parport.o
diff --git a/drivers/ata/pata_parport/pata_parport.c b/drivers/ata/pata_parport/pata_parport.c
new file mode 100644
index 000000000000..7f814062cedd
--- /dev/null
+++ b/drivers/ata/pata_parport/pata_parport.c
@@ -0,0 +1,809 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/parport.h>
+#include "pata_parport.h"
+
+#define DRV_NAME "pata_parport"
+
+static DEFINE_IDR(parport_list);
+static DEFINE_IDR(protocols);
+static DEFINE_IDA(pata_parport_bus_dev_ids);
+static DEFINE_MUTEX(pi_mutex);
+
+static bool probe = 1;
+module_param(probe, bool, 0644);
+MODULE_PARM_DESC(probe, "Enable automatic device probing (0=off, 1=on [default])");
+
+static bool verbose;
+module_param(verbose, bool, 0644);
+MODULE_PARM_DESC(verbose, "Enable verbose messages (0=off [default], 1=on)");
+
+#define DISCONNECT_TIMEOUT	(HZ / 10)
+
+static void pi_connect(struct pi_adapter *pi)
+{
+	del_timer_sync(&pi->timer);
+	if (pi->claimed)
+		return;
+	pi->claimed = 1;
+	parport_claim_or_block(pi->pardev);
+	pi->proto->connect(pi);
+}
+
+static void pi_disconnect_later(struct pi_adapter *pi)
+{
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+}
+
+static void pi_disconnect_timer(struct timer_list *t)
+{
+	struct pi_adapter *pi = from_timer(pi, t, timer);
+
+	if (!pi->claimed)
+		return;
+	pi->proto->disconnect(pi);
+	parport_release(pi->pardev);
+	pi->claimed = 0;
+}
+
+/* functions taken from libata-sff.c and converted from direct port I/O */
+static unsigned int pata_parport_devchk(struct ata_port *ap, unsigned int device)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+	u8 nsect, lbal;
+
+	ap->ops->sff_dev_select(ap, device);
+
+	pi_connect(pi);
+	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0x55);
+	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
+
+	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0xaa);
+	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0x55);
+
+	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 055);
+	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
+
+	nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
+	lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
+	pi_disconnect_later(pi);
+
+	if ((nsect == 0x55) && (lbal == 0xaa))
+		return 1;	/* we found a device */
+
+	return 0;		/* nothing found */
+}
+
+static int pata_parport_bus_softreset(struct ata_port *ap, unsigned int devmask,
+				      unsigned long deadline)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	/* software reset.  causes dev0 to be selected */
+	pi->proto->write_regr(pi, 1, 6, ap->ctl);
+	udelay(20);	/* FIXME: flush */
+	pi->proto->write_regr(pi, 1, 6, ap->ctl | ATA_SRST);
+	udelay(20);	/* FIXME: flush */
+	pi->proto->write_regr(pi, 1, 6, ap->ctl);
+	ap->last_ctl = ap->ctl;
+	pi_disconnect_later(pi);
+
+	/* wait the port to become ready */
+	return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
+}
+
+static int pata_parport_softreset(struct ata_link *link, unsigned int *classes,
+				  unsigned long deadline)
+{
+	struct ata_port *ap = link->ap;
+	unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
+	unsigned int devmask = 0;
+	int rc;
+	u8 err;
+
+	/* determine if device 0/1 are present */
+	if (pata_parport_devchk(ap, 0))
+		devmask |= (1 << 0);
+	if (slave_possible && pata_parport_devchk(ap, 1))
+		devmask |= (1 << 1);
+
+	/* select device 0 again */
+	ap->ops->sff_dev_select(ap, 0);
+
+	/* issue bus reset */
+	rc = pata_parport_bus_softreset(ap, devmask, deadline);
+	/* if link is occupied, -ENODEV too is an error */
+	if (rc && (rc != -ENODEV || sata_scr_valid(link))) {
+		ata_link_err(link, "SRST failed (errno=%d)\n", rc);
+		return rc;
+	}
+
+	/* determine by signature whether we have ATA or ATAPI devices */
+	classes[0] = ata_sff_dev_classify(&link->device[0],
+					  devmask & (1 << 0), &err);
+	if (slave_possible && err != 0x81)
+		classes[1] = ata_sff_dev_classify(&link->device[1],
+						  devmask & (1 << 1), &err);
+
+	return 0;
+}
+
+static u8 pata_parport_check_status(struct ata_port *ap)
+{
+	u8 status;
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
+	pi_disconnect_later(pi);
+
+	return status;
+}
+
+static u8 pata_parport_check_altstatus(struct ata_port *ap)
+{
+	u8 altstatus;
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	altstatus = pi->proto->read_regr(pi, 1, 6);
+	pi_disconnect_later(pi);
+
+	return altstatus;
+}
+
+static void pata_parport_dev_select(struct ata_port *ap, unsigned int device)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+	u8 tmp;
+
+	pi_connect(pi);
+	if (device == 0)
+		tmp = ATA_DEVICE_OBS;
+	else
+		tmp = ATA_DEVICE_OBS | ATA_DEV1;
+
+	pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tmp);
+	pi_disconnect_later(pi);
+	ata_sff_pause(ap);	/* needed; also flushes, for mmio */
+}
+
+static void pata_parport_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+
+	pi_connect(pi);
+	if (tf->ctl != ap->last_ctl) {
+		pi->proto->write_regr(pi, 1, 6, tf->ctl);
+		ap->last_ctl = tf->ctl;
+		ata_wait_idle(ap);
+	}
+
+	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
+		pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->hob_feature);
+		pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->hob_nsect);
+		pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->hob_lbal);
+		pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->hob_lbam);
+		pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->hob_lbah);
+	}
+
+	if (is_addr) {
+		pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->feature);
+		pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->nsect);
+		pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->lbal);
+		pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->lbam);
+		pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->lbah);
+	}
+
+	if (tf->flags & ATA_TFLAG_DEVICE)
+		pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tf->device);
+
+	ata_wait_idle(ap);
+	pi_disconnect_later(pi);
+}
+
+static void pata_parport_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	tf->command = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
+	tf->feature = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
+	tf->nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
+	tf->lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
+	tf->lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
+	tf->lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
+	tf->device = pi->proto->read_regr(pi, 0, ATA_REG_DEVICE);
+
+	if (tf->flags & ATA_TFLAG_LBA48) {
+		pi->proto->write_regr(pi, 1, 6, tf->ctl | ATA_HOB);
+		tf->hob_feature = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
+		tf->hob_nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
+		tf->hob_lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
+		tf->hob_lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
+		tf->hob_lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
+		pi->proto->write_regr(pi, 1, 6, tf->ctl);
+		ap->last_ctl = tf->ctl;
+	}
+	pi_disconnect_later(pi);
+}
+
+static void pata_parport_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	pi->proto->write_regr(pi, 0, ATA_REG_CMD, tf->command);
+	ata_sff_pause(ap);
+	pi_disconnect_later(pi);
+}
+
+static unsigned int pata_parport_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf,
+					   unsigned int buflen, int rw)
+{
+	struct ata_port *ap = qc->dev->link->ap;
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	if (rw == READ)
+		pi->proto->read_block(pi, buf, buflen);
+	else
+		pi->proto->write_block(pi, buf, buflen);
+	pi_disconnect_later(pi);
+
+	return buflen;
+}
+
+static void pata_parport_drain_fifo(struct ata_queued_cmd *qc)
+{
+	int count;
+	struct ata_port *ap;
+	struct pi_adapter *pi;
+	char junk[2];
+
+	/* We only need to flush incoming data when a command was running */
+	if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
+		return;
+
+	ap = qc->ap;
+	pi = ap->host->private_data;
+	/* Drain up to 64K of data before we give up this recovery method */
+	for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
+						&& count < 65536; count += 2) {
+		pi_connect(pi);
+		pi->proto->read_block(pi, junk, 2);
+		pi_disconnect_later(pi);
+	}
+
+	if (count)
+		ata_port_dbg(ap, "drained %d bytes to clear DRQ\n", count);
+}
+
+static void pata_parport_lost_interrupt(struct ata_port *ap)
+{
+	u8 status;
+	struct ata_queued_cmd *qc;
+
+	/* Only one outstanding command per SFF channel */
+	qc = ata_qc_from_tag(ap, ap->link.active_tag);
+	/* We cannot lose an interrupt on a non-existent or polled command */
+	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
+		return;
+	/* See if the controller thinks it is still busy - if so the command
+	   isn't a lost IRQ but is still in progress */
+	status = pata_parport_check_altstatus(ap);
+	if (status & ATA_BUSY)
+		return;
+
+	/* There was a command running, we are no longer busy and we have
+	   no interrupt. */
+	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
+	/* Run the host interrupt logic as if the interrupt had not been lost */
+	ata_sff_port_intr(ap, qc);
+}
+
+static struct ata_port_operations pata_parport_port_ops = {
+	.qc_prep		= ata_noop_qc_prep,
+	.qc_issue		= ata_sff_qc_issue,
+	.qc_fill_rtf		= ata_sff_qc_fill_rtf,
+
+	.freeze			= ata_sff_freeze,
+	.thaw			= ata_sff_thaw,
+	.prereset		= ata_sff_prereset,
+	.softreset		= pata_parport_softreset,
+	.postreset		= ata_sff_postreset,
+	.error_handler		= ata_sff_error_handler,
+	.sched_eh		= ata_std_sched_eh,
+	.end_eh			= ata_std_end_eh,
+
+	.sff_dev_select		= pata_parport_dev_select,
+	.sff_check_status	= pata_parport_check_status,
+	.sff_check_altstatus	= pata_parport_check_altstatus,
+	.sff_tf_load		= pata_parport_tf_load,
+	.sff_tf_read		= pata_parport_tf_read,
+	.sff_exec_command	= pata_parport_exec_command,
+	.sff_data_xfer		= pata_parport_data_xfer,
+	.sff_drain_fifo		= pata_parport_drain_fifo,
+
+	.lost_interrupt		= pata_parport_lost_interrupt,
+};
+
+static const struct ata_port_info pata_parport_port_info = {
+	.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_POLLING,
+	.pio_mask	= ATA_PIO0,
+	/* No DMA */
+	.port_ops	= &pata_parport_port_ops,
+};
+
+void pi_release(struct pi_adapter *pi)
+{
+	parport_unregister_device(pi->pardev);
+	if (pi->proto->release_proto)
+		pi->proto->release_proto(pi);
+	module_put(pi->proto->owner);
+}
+
+static int default_test_proto(struct pi_adapter *pi, char *scratch)
+{
+	int j, k;
+	int e[2] = { 0, 0 };
+
+	pi->proto->connect(pi);
+
+	for (j = 0; j < 2; j++) {
+		pi->proto->write_regr(pi, 0, 6, 0xa0 + j * 0x10);
+		for (k = 0; k < 256; k++) {
+			pi->proto->write_regr(pi, 0, 2, k ^ 0xaa);
+			pi->proto->write_regr(pi, 0, 3, k ^ 0x55);
+			if (pi->proto->read_regr(pi, 0, 2) != (k ^ 0xaa))
+				e[j]++;
+		}
+	}
+	pi->proto->disconnect(pi);
+
+	if (verbose)
+		dev_info(&pi->dev, "%s: port 0x%x, mode  %d, test=(%d,%d)\n",
+		       pi->proto->name, pi->port,
+		       pi->mode, e[0], e[1]);
+
+	return (e[0] && e[1]);	/* not here if both > 0 */
+}
+
+static int pi_test_proto(struct pi_adapter *pi, char *scratch)
+{
+	int res;
+
+	parport_claim_or_block(pi->pardev);
+	if (pi->proto->test_proto)
+		res = pi->proto->test_proto(pi, scratch, verbose);
+	else
+		res = default_test_proto(pi, scratch);
+	parport_release(pi->pardev);
+
+	return res;
+}
+
+static int pi_probe_mode(struct pi_adapter *pi, int max, char *scratch)
+{
+	int best, range;
+
+	if (pi->mode != -1) {
+		if (pi->mode >= max)
+			return 0;
+		range = 3;
+		if (pi->mode >= pi->proto->epp_first)
+			range = 8;
+		if ((range == 8) && (pi->port % 8))
+			return 0;
+		return (!pi_test_proto(pi, scratch));
+	}
+	best = -1;
+	for (pi->mode = 0; pi->mode < max; pi->mode++) {
+		range = 3;
+		if (pi->mode >= pi->proto->epp_first)
+			range = 8;
+		if ((range == 8) && (pi->port % 8))
+			break;
+		if (!pi_test_proto(pi, scratch))
+			best = pi->mode;
+	}
+	pi->mode = best;
+	return (best > -1);
+}
+
+
+static int pi_probe_unit(struct pi_adapter *pi, int unit, char *scratch)
+{
+	int max, s, e;
+
+	s = unit;
+	e = s + 1;
+
+	if (s == -1) {
+		s = 0;
+		e = pi->proto->max_units;
+	}
+
+	if (pi->proto->test_port) {
+		parport_claim_or_block(pi->pardev);
+		max = pi->proto->test_port(pi);
+		parport_release(pi->pardev);
+	} else
+		max = pi->proto->max_mode;
+
+	if (pi->proto->probe_unit) {
+		parport_claim_or_block(pi->pardev);
+		for (pi->unit = s; pi->unit < e; pi->unit++)
+			if (pi->proto->probe_unit(pi)) {
+				parport_release(pi->pardev);
+				if (pi_probe_mode(pi, max, scratch))
+					return 1;
+				return 0;
+			}
+		parport_release(pi->pardev);
+		return 0;
+	}
+
+	if (!pi_probe_mode(pi, max, scratch))
+		return 0;
+	return 1;
+}
+
+static void pata_parport_dev_release(struct device *dev)
+{
+	struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
+
+	kfree(pi);
+}
+
+void pata_parport_bus_release(struct device *dev)
+{
+	/* nothing to do here but required to avoid warning on device removal */
+}
+
+static struct bus_type pata_parport_bus_type = {
+	.name = DRV_NAME,
+};
+
+static struct device pata_parport_bus = {
+	.init_name = DRV_NAME,
+	.release = pata_parport_bus_release,
+};
+
+struct pi_adapter *pi_init_one(struct parport *parport, struct pi_protocol *pr,
+			       int mode, int unit, int delay)
+{
+	struct pardev_cb par_cb = { };
+	char scratch[512];
+	const struct ata_port_info *ppi[] = { &pata_parport_port_info };
+	struct ata_host *host;
+	struct pi_adapter *pi = kzalloc(sizeof(struct pi_adapter), GFP_KERNEL);
+
+	if (!pi)
+		return NULL;
+
+	/* set up pi->dev before pi_probe_unit() so it can use dev_printk() */
+	pi->dev.parent = &pata_parport_bus;
+	pi->dev.bus = &pata_parport_bus_type;
+	pi->dev.driver = &pr->driver;
+	pi->dev.release = pata_parport_dev_release;
+	pi->dev.id = ida_alloc(&pata_parport_bus_dev_ids, GFP_KERNEL);
+	if (pi->dev.id < 0)
+		return NULL; /* pata_parport_dev_release will do kfree(pi) */
+	dev_set_name(&pi->dev, "pata_parport.%u", pi->dev.id);
+	if (device_register(&pi->dev)) {
+		put_device(&pi->dev);
+		goto out_ida_free;
+	}
+
+	pi->proto = pr;
+
+	/* still racy */
+	if (!try_module_get(pi->proto->owner))
+		goto out_unreg_dev;
+	if (pi->proto->init_proto && pi->proto->init_proto(pi) < 0)
+		goto out_module_put;
+
+	pi->delay = (delay == -1) ? pi->proto->default_delay : delay;
+	pi->mode = mode;
+	pi->port = parport->base;
+
+	par_cb.private = pi;
+	pi->pardev = parport_register_dev_model(parport, dev_name(&pi->dev),
+						&par_cb, pi->dev.id);
+	if (!pi->pardev)
+		goto out_module_put;
+
+	if (!pi_probe_unit(pi, unit, scratch)) {
+		dev_info(&pi->dev, "Adapter not found\n");
+		goto out_unreg_parport;
+	}
+
+	pi->proto->log_adapter(pi, scratch, verbose);
+
+	host = ata_host_alloc_pinfo(&pi->dev, ppi, 1);
+	if (!host)
+		goto out_unreg_parport;
+	dev_set_drvdata(&pi->dev, host);
+	host->private_data = pi;
+
+	ata_port_desc(host->ports[0], "port %s", pi->pardev->port->name);
+	ata_port_desc(host->ports[0], "protocol %s", pi->proto->name);
+
+	timer_setup(&pi->timer, pi_disconnect_timer, 0);
+
+	if (ata_host_activate(host, 0, NULL, 0, &pi->proto->sht))
+		goto out_unreg_parport;
+
+	return pi;
+
+out_unreg_parport:
+	parport_unregister_device(pi->pardev);
+	if (pi->proto->release_proto)
+		pi->proto->release_proto(pi);
+out_module_put:
+	module_put(pi->proto->owner);
+out_unreg_dev:
+	device_unregister(&pi->dev);
+out_ida_free:
+	ida_free(&pata_parport_bus_dev_ids, pi->dev.id);
+	return NULL;
+}
+
+int pata_parport_register_driver(struct pi_protocol *pr)
+{
+	int error;
+	struct parport *parport;
+	int port_num;
+
+	pr->driver.bus = &pata_parport_bus_type;
+	pr->driver.name = pr->name;
+	error = driver_register(&pr->driver);
+	if (error)
+		return error;
+
+	mutex_lock(&pi_mutex);
+	error = idr_alloc(&protocols, pr, 0, 0, GFP_KERNEL);
+	if (error < 0) {
+		driver_unregister(&pr->driver);
+		mutex_unlock(&pi_mutex);
+		return error;
+	}
+
+	pr_info("pata_parport: protocol %s registered\n", pr->name);
+
+	if (probe)	/* probe all parports using this protocol */
+		idr_for_each_entry(&parport_list, parport, port_num)
+			pi_init_one(parport, pr, -1, 0, -1);
+	mutex_unlock(&pi_mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL(pata_parport_register_driver);
+
+void pata_parport_unregister_driver(struct pi_protocol *pr)
+{
+	struct pi_protocol *pr_iter;
+	int id = -1;
+
+	mutex_lock(&pi_mutex);
+	idr_for_each_entry(&protocols, pr_iter, id)
+		if (pr_iter == pr)
+			break;
+	idr_remove(&protocols, id);
+	mutex_unlock(&pi_mutex);
+	pr_info("pata_parport: protocol %s removed\n", pr->name);
+	driver_unregister(&pr->driver);
+}
+EXPORT_SYMBOL(pata_parport_unregister_driver);
+
+static ssize_t new_device_store(struct bus_type *bus, const char *buf, size_t count)
+{
+	char port[12] = "auto";
+	char protocol[8] = "auto";
+	int mode = -1, unit = -1, delay = -1;
+	struct pi_protocol *pr, *pr_wanted;
+	struct device_driver *drv;
+	struct parport *parport;
+	int port_num, port_wanted, pr_num;
+	bool ok = false;
+
+	if (sscanf(buf, "%11s %7s %d %d %d",
+			port, protocol, &mode, &unit, &delay) < 1)
+		return -EINVAL;
+
+	if (sscanf(port, "parport%u", &port_wanted) < 1) {
+		if (!strcmp(port, "auto"))
+			port_wanted = -1;
+		else {
+			pr_err("invalid port name %s\n", port);
+			return -EINVAL;
+		}
+	}
+
+	drv = driver_find(protocol, &pata_parport_bus_type);
+	if (!drv) {
+		if (!strcmp(protocol, "auto"))
+			pr_wanted = NULL;
+		else {
+			pr_err("protocol %s not found\n", protocol);
+			return -EINVAL;
+		}
+	} else
+		pr_wanted = container_of(drv, struct pi_protocol, driver);
+
+	mutex_lock(&pi_mutex);
+	/* walk all parports */
+	idr_for_each_entry(&parport_list, parport, port_num) {
+		if (port_num == port_wanted || port_wanted == -1) {
+			parport = parport_find_number(port_num);
+			if (!parport) {
+				pr_err("no such port %s\n", port);
+				mutex_unlock(&pi_mutex);
+				return -ENODEV;
+			}
+			/* walk all protocols */
+			idr_for_each_entry(&protocols, pr, pr_num)
+				if (pr == pr_wanted || !pr_wanted)
+					if (pi_init_one(parport, pr, mode, unit,
+							delay))
+						ok = true;
+			parport_put_port(parport);
+		}
+	}
+	mutex_unlock(&pi_mutex);
+	if (!ok)
+		return -ENODEV;
+
+	return count;
+}
+static BUS_ATTR_WO(new_device);
+
+static void pi_remove_one(struct device *dev)
+{
+	struct ata_host *host = dev_get_drvdata(dev);
+	struct pi_adapter *pi = host->private_data;
+
+	ata_host_detach(host);
+	del_timer_sync(&pi->timer);
+	pi_release(pi);
+	device_unregister(dev);
+	ida_free(&pata_parport_bus_dev_ids, dev->id);
+	/* pata_parport_dev_release will do kfree(pi) */
+}
+
+static ssize_t delete_device_store(struct bus_type *bus, const char *buf, size_t count)
+{
+	struct device *dev;
+	char device_name[32];
+	int fields;
+
+	fields = sscanf(buf, "%31s", device_name);
+	if (fields < 1)
+		return -EINVAL;
+
+	mutex_lock(&pi_mutex);
+	dev = bus_find_device_by_name(bus, NULL, device_name);
+	if (!dev) {
+		mutex_unlock(&pi_mutex);
+		return -ENODEV;
+	}
+
+	pi_remove_one(dev);
+	mutex_unlock(&pi_mutex);
+
+	return count;
+}
+static BUS_ATTR_WO(delete_device);
+
+static void pata_parport_attach(struct parport *port)
+{
+	struct pi_protocol *pr;
+	int pr_num, id;
+
+	mutex_lock(&pi_mutex);
+	id = idr_alloc(&parport_list, port, port->number, port->number, GFP_KERNEL);
+	if (id < 0) {
+		mutex_unlock(&pi_mutex);
+		return;
+	}
+
+	if (probe) /* probe this port using all protocols */
+		idr_for_each_entry(&protocols, pr, pr_num)
+			pi_init_one(port, pr, -1, 0, -1);
+	mutex_unlock(&pi_mutex);
+}
+
+static int pi_remove_port(struct device *dev, void *p)
+{
+	struct ata_host *host = dev_get_drvdata(dev);
+	struct pi_adapter *pi = host->private_data;
+
+	if (pi->pardev->port == p)
+		pi_remove_one(dev);
+
+	return 0;
+}
+
+static void pata_parport_detach(struct parport *port)
+{
+	mutex_lock(&pi_mutex);
+	bus_for_each_dev(&pata_parport_bus_type, NULL, port, pi_remove_port);
+	idr_remove(&parport_list, port->number);
+	mutex_unlock(&pi_mutex);
+}
+
+static struct parport_driver pata_parport_driver = {
+	.name = DRV_NAME,
+	.match_port = pata_parport_attach,
+	.detach = pata_parport_detach,
+	.devmodel = true,
+};
+
+static __init int pata_parport_init(void)
+{
+	int error;
+
+	error = bus_register(&pata_parport_bus_type);
+	if (error) {
+		pr_err("failed to register pata_parport bus, error: %d\n", error);
+		return error;
+	}
+
+	error = device_register(&pata_parport_bus);
+	if (error) {
+		pr_err("failed to register pata_parport bus, error: %d\n", error);
+		return error;
+		goto out_unregister_bus;
+	}
+
+	error = bus_create_file(&pata_parport_bus_type, &bus_attr_new_device);
+	if (error) {
+		pr_err("unable to create sysfs file, error: %d\n", error);
+		goto out_unregister_dev;
+	}
+
+	error = bus_create_file(&pata_parport_bus_type, &bus_attr_delete_device);
+	if (error) {
+		pr_err("unable to create sysfs file, error: %d\n", error);
+		goto out_remove_new;
+	}
+
+	error = parport_register_driver(&pata_parport_driver);
+	if (error) {
+		pr_err("unable to register parport driver, error: %d\n", error);
+		goto out_remove_del;
+	}
+
+	return 0;
+
+out_remove_del:
+	bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
+out_remove_new:
+	bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
+out_unregister_dev:
+	device_unregister(&pata_parport_bus);
+out_unregister_bus:
+	bus_unregister(&pata_parport_bus_type);
+	return error;
+}
+
+static __exit void pata_parport_exit(void)
+{
+	parport_unregister_driver(&pata_parport_driver);
+	bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
+	bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
+	device_unregister(&pata_parport_bus);
+	bus_unregister(&pata_parport_bus_type);
+}
+
+MODULE_AUTHOR("Ondrej Zary");
+MODULE_DESCRIPTION("driver for parallel port ATA adapters");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("paride");
+
+module_init(pata_parport_init);
+module_exit(pata_parport_exit);
diff --git a/drivers/ata/pata_parport/pata_parport.h b/drivers/ata/pata_parport/pata_parport.h
new file mode 100644
index 000000000000..c4201b809b20
--- /dev/null
+++ b/drivers/ata/pata_parport/pata_parport.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ *	paride.h	(c) 1997-8  Grant R. Guenther <grant at torque.net>
+ *				    Under the terms of the GPL.
+ *
+ * This file defines the interface for adapter chip drivers.
+ */
+
+#include <linux/libata.h>
+
+struct pi_adapter {
+	struct device dev;
+	struct pi_protocol *proto;	/* adapter protocol */
+	int port;			/* base address of parallel port */
+	int mode;			/* transfer mode in use */
+	int delay;			/* adapter delay setting */
+	int unit;			/* unit number for chained adapters */
+	int saved_r0;			/* saved port state */
+	int saved_r2;			/* saved port state */
+	unsigned long private;		/* for protocol module */
+	struct pardevice *pardev;	/* pointer to pardevice */
+	int claimed;			/* parport has already been claimed */
+	struct timer_list timer;	/* disconnect timer */
+};
+
+/* registers are addressed as (cont,regr)
+ *	cont: 0 for command register file, 1 for control register(s)
+ *	regr: 0-7 for register number.
+ */
+
+/* macros and functions exported to the protocol modules */
+#define delay_p			(pi->delay ? udelay(pi->delay) : (void)0)
+#define out_p(offs, byte)	do { outb(byte, pi->port + offs); delay_p; } while (0)
+#define in_p(offs)		(delay_p, inb(pi->port + offs))
+
+#define w0(byte)		out_p(0, byte)
+#define r0()			(in_p(0) & 0xff)
+#define w1(byte)		out_p(1, byte)
+#define r1()			(in_p(1) & 0xff)
+#define w2(byte)		out_p(2, byte)
+#define r2()			(in_p(2) & 0xff)
+#define w3(byte)		out_p(3, byte)
+#define w4(byte)		out_p(4, byte)
+#define r4()			(in_p(4) & 0xff)
+#define w4w(data)		do { outw(data, pi->port + 4); delay_p; } while (0)
+#define w4l(data)		do { outl(data, pi->port + 4); delay_p; } while (0)
+#define r4w()			(delay_p, inw(pi->port + 4) & 0xffff)
+#define r4l()			(delay_p, inl(pi->port + 4) & 0xffffffff)
+
+static inline u16 pi_swab16(char *b, int k)
+{
+	union { u16 u; char t[2]; } r;
+
+	r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k];
+	return r.u;
+}
+
+static inline u32 pi_swab32(char *b, int k)
+{
+	union { u32 u; char f[4]; } r;
+
+	r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k];
+	r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2];
+	return r.u;
+}
+
+struct pi_protocol {
+	char name[8];		/* name for this protocol */
+
+	int max_mode;		/* max mode number */
+	int epp_first;		/* modes >= this use 8 ports */
+
+	int default_delay;	/* delay parameter if not specified */
+	int max_units;		/* max chained units probed for */
+
+	void (*write_regr)(struct pi_adapter *pi, int cont, int regr, int val);
+	int (*read_regr)(struct pi_adapter *pi, int cont, int regr);
+	void (*write_block)(struct pi_adapter *pi, char *buf, int count);
+	void (*read_block)(struct pi_adapter *pi, char *buf, int count);
+
+	void (*connect)(struct pi_adapter *pi);
+	void (*disconnect)(struct pi_adapter *pi);
+
+	int (*test_port)(struct pi_adapter *pi);
+	int (*probe_unit)(struct pi_adapter *pi);
+	int (*test_proto)(struct pi_adapter *pi, char *scratch, int verbose);
+	void (*log_adapter)(struct pi_adapter *pi, char *scratch, int verbose);
+
+	int (*init_proto)(struct pi_adapter *pi);
+	void (*release_proto)(struct pi_adapter *pi);
+	struct module *owner;
+	struct device_driver driver;
+	struct scsi_host_template sht;
+};
+
+#define PATA_PARPORT_SHT ATA_PIO_SHT
+
+extern int pata_parport_register_driver(struct pi_protocol *pr);
+extern void pata_parport_unregister_driver(struct pi_protocol *pr);
+
+/**
+ * module_pata_parport_driver() - Helper macro for registering a pata_parport driver
+ * @__pi_protocol: pi_protocol struct
+ *
+ * Helper macro for pata_parport drivers which do not do anything special in module
+ * init/exit. This eliminates a lot of boilerplate. Each module may only
+ * use this macro once, and calling it replaces module_init() and module_exit()
+ */
+#define module_pata_parport_driver(__pi_protocol) \
+	module_driver(__pi_protocol, pata_parport_register_driver, pata_parport_unregister_driver)
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:14:02 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:14:02 +0100
Subject: [Linux-parport] [PATCH 07/16] pata_parport: add fit2 protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-8-linux@zary.sk>

Add FIT TD-2000 protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  11 +++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/fit2.c   | 135 ++++++++++++++++++++++++++++++
 3 files changed, 147 insertions(+)
 create mode 100644 drivers/ata/pata_parport/fit2.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index 67f203dfbdca..db8edb288db4 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -74,3 +74,14 @@ config PATA_PARPORT_DSTR
 	  into your kernel, you may answer Y here to build in the protocol
 	  driver, otherwise you should answer M to build it as a loadable
 	  module. The module will be called dstr.
+
+config PATA_PARPORT_FIT2
+	tristate "FIT TD-2000 protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the TD-2000 parallel port IDE
+	  protocol from Fidelity International Technology. This is a simple
+	  (low speed) adapter that is used in some portable hard drives. If
+	  you chose to build PATA_PARPORT support into your kernel, you may answer Y
+	  here to build in the protocol driver, otherwise you should answer M
+	  to build it as a loadable module. The module will be called ktti.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index bf81c4ca32ab..27d854f52ad7 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_PATA_PARPORT_BPCK)		+= bpck.o
 obj-$(CONFIG_PATA_PARPORT_BPCK6)	+= bpck6.o
 obj-$(CONFIG_PATA_PARPORT_COMM)		+= comm.o
 obj-$(CONFIG_PATA_PARPORT_DSTR)		+= dstr.o
+obj-$(CONFIG_PATA_PARPORT_FIT2)		+= fit2.o
diff --git a/drivers/ata/pata_parport/fit2.c b/drivers/ata/pata_parport/fit2.c
new file mode 100644
index 000000000000..92cee479108c
--- /dev/null
+++ b/drivers/ata/pata_parport/fit2.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	fit2.c	(c) 1998  Grant R. Guenther <grant at torque.net>
+ *			  Under the terms of the GNU General Public License.
+ *
+ *	fit2.c is a low-level protocol driver for the older version
+ *	of the Fidelity International Technology parallel port adapter.
+ *	This adapter is used in their TransDisk 2000 and older TransDisk
+ *	3000 portable hard-drives.  As far as I can tell, this device
+ *	supports 4-bit mode _only_.
+ *
+ *	Newer models of the FIT products use an enhanced protocol.
+ *	The "fit3" protocol module should support current drives.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+#define j44(a, b)	(((a >> 4) & 0x0f) | (b & 0xf0))
+
+/* cont = 0 - access the IDE register file
+ * cont = 1 - access the IDE command set
+ *
+ * NB:  The FIT adapter does not appear to use the control registers.
+ * So, we map ALT_STATUS to STATUS and NO-OP writes to the device
+ * control register - this means that IDE reset will not work on these
+ * devices.
+ */
+
+static void fit2_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	if (cont == 1)
+		return;
+	w2(0xc); w0(regr); w2(4); w0(val); w2(5); w0(0); w2(4);
+}
+
+static int fit2_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int  a, b, r;
+
+	if (cont) {
+		if (regr != 6)
+			return 0xff;
+		r = 7;
+	} else
+		r = regr + 0x10;
+
+	w2(0xc); w0(r); w2(4); w2(5);
+		 w0(0); a = r1();
+		 w0(1); b = r1();
+	w2(4);
+
+	return j44(a, b);
+}
+
+static void fit2_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k, a, b, c, d;
+
+	w2(0xc); w0(0x10);
+
+	for (k = 0; k < count / 4; k++) {
+		w2(4); w2(5);
+		w0(0); a = r1(); w0(1); b = r1();
+		w0(3); c = r1(); w0(2); d = r1();
+		buf[4 * k + 0] = j44(a, b);
+		buf[4 * k + 1] = j44(d, c);
+
+		w2(4); w2(5);
+		       a = r1(); w0(3); b = r1();
+		w0(1); c = r1(); w0(0); d = r1();
+		buf[4 * k + 2] = j44(d, c);
+		buf[4 * k + 3] = j44(a, b);
+	}
+
+	w2(4);
+}
+
+static void fit2_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k;
+
+	w2(0xc); w0(0);
+	for (k = 0; k < count / 2; k++) {
+		w2(4); w0(buf[2 * k]);
+		w2(5); w0(buf[2 * k + 1]);
+	}
+	w2(4);
+}
+
+static void fit2_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+	w2(0xcc);
+}
+
+static void fit2_disconnect(struct pi_adapter *pi)
+{
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+static void fit2_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	dev_info(&pi->dev, "fit2, FIT 2000 adapter at 0x%x, delay %d\n",
+		pi->port, pi->delay);
+}
+
+static struct pi_protocol fit2 = {
+	.owner		= THIS_MODULE,
+	.name		= "fit2",
+	.max_mode	= 1,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= fit2_write_regr,
+	.read_regr	= fit2_read_regr,
+	.write_block	= fit2_write_block,
+	.read_block	= fit2_read_block,
+	.connect	= fit2_connect,
+	.disconnect	= fit2_disconnect,
+	.log_adapter	= fit2_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-fit2") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(fit2);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:14:03 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:14:03 +0100
Subject: [Linux-parport] [PATCH 08/16] pata_parport: add fit3 protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-9-linux@zary.sk>

Add FIT TD-3000 protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  12 ++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/fit3.c   | 195 ++++++++++++++++++++++++++++++
 3 files changed, 208 insertions(+)
 create mode 100644 drivers/ata/pata_parport/fit3.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index db8edb288db4..a03c626e4e6c 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -85,3 +85,15 @@ config PATA_PARPORT_FIT2
 	  you chose to build PATA_PARPORT support into your kernel, you may answer Y
 	  here to build in the protocol driver, otherwise you should answer M
 	  to build it as a loadable module. The module will be called ktti.
+
+config PATA_PARPORT_FIT3
+	tristate "FIT TD-3000 protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the TD-3000 parallel port IDE
+	  protocol from Fidelity International Technology. This protocol is
+	  used in newer models of their portable disk, CD-ROM and PD/CD
+	  devices. If you chose to build PATA_PARPORT support into your kernel, you
+	  may answer Y here to build in the protocol driver, otherwise you
+	  should answer M to build it as a loadable module. The module will be
+	  called fit3.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index 27d854f52ad7..140f6f142eaa 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_PATA_PARPORT_BPCK6)	+= bpck6.o
 obj-$(CONFIG_PATA_PARPORT_COMM)		+= comm.o
 obj-$(CONFIG_PATA_PARPORT_DSTR)		+= dstr.o
 obj-$(CONFIG_PATA_PARPORT_FIT2)		+= fit2.o
+obj-$(CONFIG_PATA_PARPORT_FIT3)		+= fit3.o
diff --git a/drivers/ata/pata_parport/fit3.c b/drivers/ata/pata_parport/fit3.c
new file mode 100644
index 000000000000..7c874dc8b41b
--- /dev/null
+++ b/drivers/ata/pata_parport/fit3.c
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	fit3.c	(c) 1998  Grant R. Guenther <grant at torque.net>
+ *			  Under the terms of the GNU General Public License.
+ *
+ *	fit3.c is a low-level protocol driver for newer models
+ *	of the Fidelity International Technology parallel port adapter.
+ *	This adapter is used in their TransDisk 3000 portable
+ *	hard-drives, as well as CD-ROM, PD-CD and other devices.
+ *
+ *	The TD-2000 and certain older devices use a different protocol.
+ *	Try the fit2 protocol module with them.
+ *
+ *	NB:  The FIT adapters do not appear to support the control
+ *	registers.  So, we map ALT_STATUS to STATUS and NO-OP writes
+ *	to the device control register - this means that IDE reset
+ *	will not work on these devices.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+#define j44(a, b)	(((a >> 3) & 0x0f) | ((b << 1) & 0xf0))
+
+#define w7(byte)	out_p(7, byte)
+#define r7()		(in_p(7) & 0xff)
+
+/* cont = 0 - access the IDE register file
+ * cont = 1 - access the IDE command set
+ */
+
+static void fit3_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	if (cont == 1)
+		return;
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+		w2(0xc); w0(regr); w2(0x8); w2(0xc);
+		w0(val); w2(0xd);
+		w0(0);   w2(0xc);
+		break;
+	case 2:
+		w2(0xc); w0(regr); w2(0x8); w2(0xc);
+		w4(val); w4(0);
+		w2(0xc);
+		break;
+	}
+}
+
+static int fit3_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int a, b;
+
+	if (cont) {
+		if (regr != 6)
+			return 0xff;
+		regr = 7;
+	}
+
+	switch (pi->mode) {
+	case 0:
+		w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc);
+		w2(0xd); a = r1();
+		w2(0xf); b = r1();
+		w2(0xc);
+		return j44(a, b);
+	case 1:
+		w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
+		w2(0xec); w2(0xee); w2(0xef); a = r0();
+		w2(0xc);
+		return a;
+	case 2:
+		w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
+		w2(0xec);
+		a = r4(); b = r4();
+		w2(0xc);
+		return a;
+	}
+	return -1;
+}
+
+static void fit3_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k, a, b, c, d;
+
+	switch (pi->mode) {
+	case 0:
+		w2(0xc); w0(0x10); w2(0x8); w2(0xc);
+		for (k = 0; k < count / 2; k++) {
+			w2(0xd); a = r1();
+			w2(0xf); b = r1();
+			w2(0xc); c = r1();
+			w2(0xe); d = r1();
+			buf[2 * k] = j44(a, b);
+			buf[2 * k + 1] = j44(c, d);
+		}
+		w2(0xc);
+		break;
+	case 1:
+		w2(0xc); w0(0x90); w2(0x8); w2(0xc);
+		w2(0xec); w2(0xee);
+		for (k = 0; k < count / 2; k++) {
+			w2(0xef); a = r0();
+			w2(0xee); b = r0();
+			buf[2 * k] = a;
+			buf[2 * k + 1] = b;
+		}
+		w2(0xec);
+		w2(0xc);
+		break;
+	case 2:
+		w2(0xc); w0(0x90); w2(0x8); w2(0xc);
+		w2(0xec);
+		for (k = 0; k < count; k++)
+			buf[k] = r4();
+		w2(0xc);
+		break;
+	}
+}
+
+static void fit3_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k;
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+		w2(0xc); w0(0); w2(0x8); w2(0xc);
+		for (k = 0; k < count/2; k++) {
+			w0(buf[2 * k]); w2(0xd);
+			w0(buf[2 * k + 1]); w2(0xc);
+		}
+		break;
+	case 2:
+		w2(0xc); w0(0); w2(0x8); w2(0xc);
+		for (k = 0; k < count; k++)
+			w4(buf[k]);
+		w2(0xc);
+		break;
+	}
+}
+
+static void fit3_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+	w2(0xc); w0(0); w2(0xa);
+	if (pi->mode == 2) {
+		w2(0xc); w0(0x9); w2(0x8); w2(0xc);
+	}
+}
+
+static void fit3_disconnect(struct pi_adapter *pi)
+{
+	w2(0xc); w0(0xa); w2(0x8); w2(0xc);
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+static void fit3_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	static char * const mode_string[] = { "4-bit", "8-bit", "EPP" };
+
+	dev_info(&pi->dev, "fit3, FIT 3000 adapter at 0x%x, mode %d (%s), delay %d\n",
+		pi->port, pi->mode, mode_string[pi->mode], pi->delay);
+}
+
+static struct pi_protocol fit3 = {
+	.owner		= THIS_MODULE,
+	.name		= "fit3",
+	.max_mode	= 3,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= fit3_write_regr,
+	.read_regr	= fit3_read_regr,
+	.write_block	= fit3_write_block,
+	.read_block	= fit3_read_block,
+	.connect	= fit3_connect,
+	.disconnect	= fit3_disconnect,
+	.log_adapter	= fit3_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-fit3") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(fit3);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:14:04 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:14:04 +0100
Subject: [Linux-parport] [PATCH 09/16] pata_parport: add epat protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-10-linux@zary.sk>

Add Shuttle EPAT/EPEZ protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  12 ++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/epat.c   | 320 ++++++++++++++++++++++++++++++
 3 files changed, 333 insertions(+)
 create mode 100644 drivers/ata/pata_parport/epat.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index a03c626e4e6c..6c218486c3b8 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -97,3 +97,15 @@ config PATA_PARPORT_FIT3
 	  may answer Y here to build in the protocol driver, otherwise you
 	  should answer M to build it as a loadable module. The module will be
 	  called fit3.
+
+config PATA_PARPORT_EPAT
+	tristate "Shuttle EPAT/EPEZ protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the EPAT parallel port IDE protocol.
+	  EPAT is a parallel port IDE adapter manufactured by Shuttle
+	  Technology and widely used in devices from major vendors such as
+	  Hewlett-Packard, SyQuest, Imation and Avatar. If you chose to build
+	  PATA_PARPORT support into your kernel, you may answer Y here to build in
+	  the protocol driver, otherwise you should answer M to build it as a
+	  loadable module. The module will be called epat.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index 140f6f142eaa..459307f4a096 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_PATA_PARPORT_COMM)		+= comm.o
 obj-$(CONFIG_PATA_PARPORT_DSTR)		+= dstr.o
 obj-$(CONFIG_PATA_PARPORT_FIT2)		+= fit2.o
 obj-$(CONFIG_PATA_PARPORT_FIT3)		+= fit3.o
+obj-$(CONFIG_PATA_PARPORT_EPAT)		+= epat.o
diff --git a/drivers/ata/pata_parport/epat.c b/drivers/ata/pata_parport/epat.c
new file mode 100644
index 000000000000..2103e272c82a
--- /dev/null
+++ b/drivers/ata/pata_parport/epat.c
@@ -0,0 +1,320 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	epat.c  (c) 1997-8  Grant R. Guenther <grant at torque.net>
+ *			    Under the terms of the GNU General Public License.
+ *
+ *	This is the low level protocol driver for the EPAT parallel
+ *	to IDE adapter from Shuttle Technologies.  This adapter is
+ *	used in many popular parallel port disk products such as the
+ *	SyQuest EZ drives, the Avatar Shark and the Imation SuperDisk.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+#define j44(a, b)	(((a >> 4) & 0x0f) + (b & 0xf0))
+#define j53(a, b)	(((a >> 3) & 0x1f) + ((b << 4) & 0xe0))
+
+static int epatc8 = 1;
+module_param(epatc8, int, 0);
+MODULE_PARM_DESC(epatc8, "Support for the Shuttle EP1284 chip, used in any recent Imation SuperDisk (LS-120) drive (0=off, 1=on [default])");
+
+/* cont =  0   IDE register file
+ * cont =  1   IDE control registers
+ * cont =  2   internal EPAT registers
+ */
+
+static int cont_map[3] = { 0x18, 0x10, 0 };
+
+static void epat_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	int r = regr + cont_map[cont];
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+	case 2:
+		w0(0x60+r); w2(1); w0(val); w2(4);
+		break;
+	case 3:
+	case 4:
+	case 5:
+		w3(0x40+r); w4(val);
+		break;
+	}
+}
+
+static int epat_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int a, b, r;
+
+	r = regr + cont_map[cont];
+
+	switch (pi->mode) {
+	case 0:
+		w0(r); w2(1); w2(3);
+		a = r1(); w2(4); b = r1();
+		return j44(a, b);
+	case 1:
+		w0(0x40+r); w2(1); w2(4);
+		a = r1(); b = r2(); w0(0xff);
+		return j53(a, b);
+	case 2:
+		w0(0x20+r); w2(1); w2(0x25);
+		a = r0(); w2(4);
+		return a;
+	case 3:
+	case 4:
+	case 5:
+		w3(r); w2(0x24); a = r4(); w2(4);
+		return a;
+	}
+	return -1;	/* never gets here */
+}
+
+static void epat_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int  k, ph, a, b;
+
+	switch (pi->mode) {
+	case 0:
+		w0(7); w2(1); w2(3); w0(0xff);
+		ph = 0;
+		for (k = 0; k < count; k++) {
+			if (k == count-1)
+				w0(0xfd);
+			w2(6 + ph); a = r1();
+			if (a & 8)
+				b = a;
+			else {
+				w2(4+ph); b = r1();
+			}
+			buf[k] = j44(a, b);
+			ph =  1 - ph;
+		}
+		w0(0); w2(4);
+		break;
+	case 1:
+		w0(0x47); w2(1); w2(5); w0(0xff);
+		ph = 0;
+		for (k = 0; k < count; k++) {
+			if (k == count - 1)
+				w0(0xfd);
+			w2(4 + ph);
+			a = r1(); b = r2();
+			buf[k] = j53(a, b);
+			ph = 1 - ph;
+		}
+		w0(0); w2(4);
+		break;
+	case 2:
+		w0(0x27); w2(1); w2(0x25); w0(0);
+		ph = 0;
+		for (k = 0; k < count-1; k++) {
+			w2(0x24 + ph);
+			buf[k] = r0();
+			ph = 1 - ph;
+		}
+		w2(0x26); w2(0x27); buf[count - 1] = r0();
+		w2(0x25); w2(4);
+		break;
+	case 3:
+		w3(0x80); w2(0x24);
+		for (k = 0; k < count - 1; k++)
+			buf[k] = r4();
+		w2(4); w3(0xa0); w2(0x24); buf[count - 1] = r4();
+		w2(4);
+		break;
+	case 4:
+		w3(0x80); w2(0x24);
+		for (k = 0; k < (count / 2) - 1; k++)
+			((u16 *)buf)[k] = r4w();
+		buf[count - 2] = r4();
+		w2(4); w3(0xa0); w2(0x24); buf[count - 1] = r4();
+		w2(4);
+		break;
+	case 5:
+		w3(0x80); w2(0x24);
+		for (k = 0; k < (count / 4) - 1; k++)
+			((u32 *)buf)[k] = r4l();
+		for (k = count - 4; k < count - 1; k++)
+			buf[k] = r4();
+		w2(4); w3(0xa0); w2(0x24); buf[count - 1] = r4();
+		w2(4);
+		break;
+	}
+}
+
+static void epat_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int ph, k;
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+	case 2:
+		w0(0x67); w2(1); w2(5);
+		ph = 0;
+		for (k = 0; k < count; k++) {
+			w0(buf[k]);
+			w2(4+ph);
+			ph = 1 - ph;
+		}
+		w2(7); w2(4);
+		break;
+	case 3:
+		w3(0xc0);
+		for (k = 0; k < count; k++)
+			w4(buf[k]);
+		w2(4);
+		break;
+	case 4:
+		w3(0xc0);
+		for (k = 0; k < (count/2); k++)
+			w4w(((u16 *)buf)[k]);
+		w2(4);
+		break;
+	case 5:
+		w3(0xc0);
+		for (k = 0; k < (count/4); k++)
+			w4l(((u32 *)buf)[k]);
+		w2(4);
+		break;
+	}
+}
+
+/* these macros access the EPAT registers in native addressing */
+#define	WR(r, v)	epat_write_regr(pi, 2, r, v)
+#define	RR(r)		(epat_read_regr(pi, 2, r))
+
+/* and these access the IDE task file */
+#define WRi(r, v)	epat_write_regr(pi, 0, r, v)
+#define RRi(r)		(epat_read_regr(pi, 0, r))
+
+/* FIXME:  the CPP stuff should be fixed to handle multiple EPATs on a chain */
+#define CPP(x)	do { w2(4); w0(0x22); w0(0xaa); w0(0x55); w0(0); w0(0xff);\
+		     w0(0x87); w0(0x78); w0(x); w2(4); w2(5); w2(4); w0(0xff);\
+		} while (0)
+
+static void epat_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+
+	/* Initialize the chip */
+	CPP(0);
+
+	if (epatc8) {
+		CPP(0x40); CPP(0xe0);
+		w0(0); w2(1); w2(4);
+		WR(0x8, 0x12); WR(0xc, 0x14); WR(0x12, 0x10);
+		WR(0xe, 0xf); WR(0xf, 4);
+		/* WR(0xe, 0xa); WR(0xf, 4); */
+		WR(0xe, 0xd); WR(0xf, 0);
+		/* CPP(0x30); */
+	}
+
+	/* Connect to the chip */
+	CPP(0xe0);
+	w0(0); w2(1); w2(4); /* Idle into SPP */
+	if (pi->mode >= 3) {
+		w0(0); w2(1); w2(4); w2(0xc);
+		/* Request EPP */
+		w0(0x40); w2(6); w2(7); w2(4); w2(0xc); w2(4);
+	}
+
+	if (!epatc8) {
+		WR(8, 0x10); WR(0xc, 0x14); WR(0xa, 0x38); WR(0x12, 0x10);
+	}
+}
+
+static void epat_disconnect(struct pi_adapter *pi)
+{
+	CPP(0x30);
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+static int epat_test_proto(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	int k, j, f, cc;
+	int e[2] = { 0, 0 };
+
+	epat_connect(pi);
+	cc = RR(0xd);
+	epat_disconnect(pi);
+
+	epat_connect(pi);
+	for (j = 0; j < 2; j++) {
+		WRi(6, 0xa0 + j * 0x10);
+		for (k = 0; k < 256; k++) {
+			WRi(2, k ^ 0xaa);
+			WRi(3, k ^ 0x55);
+			if (RRi(2) != (k ^ 0xaa))
+				e[j]++;
+		}
+	}
+	epat_disconnect(pi);
+
+	f = 0;
+	epat_connect(pi);
+	WR(0x13, 1); WR(0x13, 0); WR(0xa, 0x11);
+	epat_read_block(pi, scratch, 512);
+
+	for (k = 0; k < 256; k++) {
+		if ((scratch[2 * k] & 0xff) != k)
+			f++;
+		if ((scratch[2 * k + 1] & 0xff) != (0xff - k))
+			f++;
+	}
+	epat_disconnect(pi);
+
+	if (verbose)
+		dev_info(&pi->dev, "epat: port 0x%x, mode %d, ccr %x, test=(%d,%d,%d)\n",
+			pi->port, pi->mode, cc, e[0], e[1], f);
+
+	return (e[0] && e[1]) || f;
+}
+
+static void epat_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	int ver;
+	static char * const mode_string[] = {
+		"4-bit", "5/3", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
+
+	epat_connect(pi);
+	WR(0xa, 0x38);		/* read the version code */
+	ver = RR(0xb);
+	epat_disconnect(pi);
+
+	dev_info(&pi->dev, "epat, Shuttle EPAT chip %x at 0x%x, mode %d (%s), delay %d\n",
+		ver, pi->port, pi->mode, mode_string[pi->mode], pi->delay);
+}
+
+static struct pi_protocol epat = {
+	.owner		= THIS_MODULE,
+	.name		= "epat",
+	.max_mode	= 6,
+	.epp_first	= 3,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= epat_write_regr,
+	.read_regr	= epat_read_regr,
+	.write_block	= epat_write_block,
+	.read_block	= epat_read_block,
+	.connect	= epat_connect,
+	.disconnect	= epat_disconnect,
+	.test_proto	= epat_test_proto,
+	.log_adapter	= epat_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-epat") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(epat);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:14:05 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:14:05 +0100
Subject: [Linux-parport] [PATCH 10/16] pata_parport: add epia protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-11-linux@zary.sk>

Add Shuttle EPIA protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  11 ++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/epia.c   | 308 ++++++++++++++++++++++++++++++
 3 files changed, 320 insertions(+)
 create mode 100644 drivers/ata/pata_parport/epia.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index 6c218486c3b8..832ab8b00511 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -109,3 +109,14 @@ config PATA_PARPORT_EPAT
 	  PATA_PARPORT support into your kernel, you may answer Y here to build in
 	  the protocol driver, otherwise you should answer M to build it as a
 	  loadable module. The module will be called epat.
+
+config PATA_PARPORT_EPIA
+	tristate "Shuttle EPIA protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the (obsolete) EPIA parallel port
+	  IDE protocol from Shuttle Technology. This adapter can still be
+	  found in some no-name kits. If you chose to build PATA_PARPORT support
+	  into your kernel, you may answer Y here to build in the protocol
+	  driver, otherwise you should answer M to build it as a loadable
+	  module. The module will be called epia.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index 459307f4a096..6e72778f45cb 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_PATA_PARPORT_DSTR)		+= dstr.o
 obj-$(CONFIG_PATA_PARPORT_FIT2)		+= fit2.o
 obj-$(CONFIG_PATA_PARPORT_FIT3)		+= fit3.o
 obj-$(CONFIG_PATA_PARPORT_EPAT)		+= epat.o
+obj-$(CONFIG_PATA_PARPORT_EPIA)		+= epia.o
diff --git a/drivers/ata/pata_parport/epia.c b/drivers/ata/pata_parport/epia.c
new file mode 100644
index 000000000000..7f3db02fd243
--- /dev/null
+++ b/drivers/ata/pata_parport/epia.c
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	epia.c    (c) 1997-8  Grant R. Guenther <grant at torque.net>
+ *			      Under the terms of the GNU General Public License.
+ *
+ *	epia.c is a low-level protocol driver for Shuttle Technologies
+ *	EPIA parallel to IDE adapter chip.  This device is now obsolete
+ *	and has been replaced with the EPAT chip, which is supported
+ *	by epat.c, however, some devices based on EPIA are still
+ *	available.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+/* mode codes:  0  nybble reads on port 1, 8-bit writes
+ *		1  5/3 reads on ports 1 & 2, 8-bit writes
+ *		2  8-bit reads and writes
+ *		3  8-bit EPP mode
+ *		4  16-bit EPP
+ *		5  32-bit EPP
+ */
+
+#define j44(a, b)	(((a >> 4) & 0x0f) + (b & 0xf0))
+#define j53(a, b)	(((a >> 3) & 0x1f) + ((b << 4) & 0xe0))
+
+/* cont =  0   IDE register file
+ * cont =  1   IDE control registers
+ */
+
+static int cont_map[2] = { 0, 0x80 };
+
+static int epia_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int a, b, r;
+
+	regr += cont_map[cont];
+
+	switch (pi->mode)  {
+	case 0:
+		r = regr ^ 0x39;
+		w0(r); w2(1); w2(3); w0(r);
+		a = r1(); w2(1); b = r1(); w2(4);
+		return j44(a, b);
+	case 1:
+		r = regr ^ 0x31;
+		w0(r); w2(1); w0(r&0x37);
+		w2(3); w2(5); w0(r|0xf0);
+		a = r1(); b = r2(); w2(4);
+		return j53(a, b);
+	case 2:
+		r = regr ^ 0x29;
+		w0(r); w2(1); w2(0X21); w2(0x23);
+		a = r0(); w2(4);
+		return a;
+	case 3:
+	case 4:
+	case 5:
+		w3(regr); w2(0x24); a = r4(); w2(4);
+		return a;
+	}
+	return -1;
+}
+
+static void epia_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	int  r;
+
+	regr += cont_map[cont];
+
+	switch (pi->mode)  {
+	case 0:
+	case 1:
+	case 2:
+		r = regr ^ 0x19;
+		w0(r); w2(1); w0(val); w2(3); w2(4);
+		break;
+	case 3:
+	case 4:
+	case 5:
+		r = regr ^ 0x40;
+		w3(r); w4(val); w2(4);
+		break;
+	}
+}
+
+#define WR(r, v)	epia_write_regr(pi, 0, r, v)
+#define RR(r)		(epia_read_regr(pi, 0, r))
+
+/* The use of register 0x84 is entirely unclear - it seems to control
+ * some EPP counters ...  currently we know about 3 different block
+ * sizes:  the standard 512 byte reads and writes, 12 byte writes and
+ * 2048 byte reads (the last two being used in the CDrom drivers.
+ */
+
+static void epia_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+
+	w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);
+	w2(1); w2(4);
+	if (pi->mode >= 3) {
+		w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);
+		w2(0x24); w2(0x26); w2(4);
+	}
+	WR(0x86, 8);
+}
+
+static void epia_disconnect(struct pi_adapter *pi)
+{
+	/* WR(0x84, 0x10); */
+	w0(pi->saved_r0);
+	w2(1); w2(4);
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+static void epia_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k, ph, a, b;
+
+	switch (pi->mode) {
+	case 0:
+		w0(0x81); w2(1); w2(3); w0(0xc1);
+		ph = 1;
+		for (k = 0; k < count; k++) {
+			w2(2 + ph); a = r1();
+			w2(4 + ph); b = r1();
+			buf[k] = j44(a, b);
+			ph = 1 - ph;
+		}
+		w0(0); w2(4);
+		break;
+	case 1:
+		w0(0x91); w2(1); w0(0x10); w2(3);
+		w0(0x51); w2(5); w0(0xd1);
+		ph = 1;
+		for (k = 0; k < count; k++) {
+			w2(4 + ph);
+			a = r1(); b = r2();
+			buf[k] = j53(a, b);
+			ph = 1 - ph;
+		}
+		w0(0); w2(4);
+		break;
+	case 2:
+		w0(0x89); w2(1); w2(0x23); w2(0x21);
+		ph = 1;
+		for (k = 0; k < count; k++) {
+			w2(0x24 + ph);
+			buf[k] = r0();
+			ph = 1 - ph;
+		}
+		w2(6); w2(4);
+		break;
+	case 3:
+		if (count > 512)
+			WR(0x84, 3);
+		w3(0); w2(0x24);
+		for (k = 0; k < count; k++)
+			buf[k] = r4();
+		w2(4); WR(0x84, 0);
+		break;
+	case 4:
+		if (count > 512)
+			WR(0x84, 3);
+		w3(0); w2(0x24);
+		for (k = 0; k < count / 2; k++)
+			((u16 *)buf)[k] = r4w();
+		w2(4); WR(0x84, 0);
+		break;
+	case 5:
+		if (count > 512)
+			WR(0x84, 3);
+		w3(0); w2(0x24);
+		for (k = 0; k < count / 4; k++)
+			((u32 *)buf)[k] = r4l();
+		w2(4); WR(0x84, 0);
+		break;
+	}
+}
+
+static void epia_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int ph, k, last, d;
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+	case 2:
+		w0(0xa1); w2(1); w2(3); w2(1); w2(5);
+		ph = 0; last = 0x8000;
+		for (k = 0; k < count; k++) {
+			d = buf[k];
+			if (d != last) {
+				last = d; w0(d);
+			}
+			w2(4 + ph);
+			ph = 1 - ph;
+		}
+		w2(7); w2(4);
+		break;
+	case 3:
+		if (count < 512)
+			WR(0x84, 1);
+		w3(0x40);
+		for (k = 0; k < count; k++)
+			w4(buf[k]);
+		if (count < 512)
+			WR(0x84, 0);
+		break;
+	case 4:
+		if (count < 512)
+			WR(0x84, 1);
+		w3(0x40);
+		for (k = 0; k < count / 2; k++)
+			w4w(((u16 *)buf)[k]);
+		if (count < 512)
+			WR(0x84, 0);
+		break;
+	case 5:
+		if (count < 512)
+			WR(0x84, 1);
+		w3(0x40);
+		for (k = 0; k < count / 4; k++)
+			w4l(((u32 *)buf)[k]);
+		if (count < 512)
+			WR(0x84, 0);
+		break;
+	}
+}
+
+static int epia_test_proto(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	int j, k, f;
+	int e[2] = { 0, 0 };
+
+	epia_connect(pi);
+	for (j = 0; j < 2; j++) {
+		WR(6, 0xa0 + j * 0x10);
+		for (k = 0; k < 256; k++) {
+			WR(2, k ^ 0xaa);
+			WR(3, k ^ 0x55);
+			if (RR(2) != (k ^ 0xaa))
+				e[j]++;
+		}
+		WR(2, 1); WR(3, 1);
+	}
+	epia_disconnect(pi);
+
+	f = 0;
+	epia_connect(pi);
+	WR(0x84, 8);
+	epia_read_block(pi, scratch, 512);
+	for (k = 0; k < 256; k++) {
+		if ((scratch[2 * k] & 0xff) != ((k + 1) & 0xff))
+			f++;
+		if ((scratch[2 * k + 1] & 0xff) != ((-2 - k) & 0xff))
+			f++;
+	}
+	WR(0x84, 0);
+	epia_disconnect(pi);
+
+	if (verbose)
+		dev_info(&pi->dev, "epia: port 0x%x, mode %d, test=(%d,%d,%d)\n",
+			pi->port, pi->mode, e[0], e[1], f);
+
+	return (e[0] && e[1]) || f;
+}
+
+
+static void epia_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	static char * const mode_string[] = {
+		"4-bit", "5/3", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
+
+	dev_info(&pi->dev, "epia, Shuttle EPIA at 0x%x, mode %d (%s), delay %d\n",
+		pi->port, pi->mode, mode_string[pi->mode], pi->delay);
+}
+
+static struct pi_protocol epia = {
+	.owner		= THIS_MODULE,
+	.name		= "epia",
+	.max_mode	= 6,
+	.epp_first	= 3,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= epia_write_regr,
+	.read_regr	= epia_read_regr,
+	.write_block	= epia_write_block,
+	.read_block	= epia_read_block,
+	.connect	= epia_connect,
+	.disconnect	= epia_disconnect,
+	.test_proto	= epia_test_proto,
+	.log_adapter	= epia_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-epia") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(epia);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:14:09 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:14:09 +0100
Subject: [Linux-parport] [PATCH 14/16] pata_parport: add ktti protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-15-linux@zary.sk>

Add KT PHd protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  11 +++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/ktti.c   | 112 ++++++++++++++++++++++++++++++
 3 files changed, 124 insertions(+)
 create mode 100644 drivers/ata/pata_parport/ktti.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index 004e5cf708f1..4505a037591a 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -154,3 +154,14 @@ config PATA_PARPORT_KBIC
 	  kernel, you may answer Y here to build in the protocol driver,
 	  otherwise you should answer M to build it as a loadable module. The
 	  module will be called kbic.
+
+config PATA_PARPORT_KTTI
+	tristate "KT PHd protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the "PHd" parallel port IDE protocol
+	  from KT Technology. This is a simple (low speed) adapter that is
+	  used in some 2.5" portable hard drives. If you chose to build PATA_PARPORT
+	  support into your kernel, you may answer Y here to build in the
+	  protocol driver, otherwise you should answer M to build it as a
+	  loadable module. The module will be called ktti.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index e82fded22da3..0c31cf55c96b 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -19,3 +19,4 @@ obj-$(CONFIG_PATA_PARPORT_EPIA)		+= epia.o
 obj-$(CONFIG_PATA_PARPORT_FRIQ)		+= friq.o
 obj-$(CONFIG_PATA_PARPORT_FRPW)		+= frpw.o
 obj-$(CONFIG_PATA_PARPORT_KBIC)		+= kbic.o
+obj-$(CONFIG_PATA_PARPORT_KTTI)		+= ktti.o
diff --git a/drivers/ata/pata_parport/ktti.c b/drivers/ata/pata_parport/ktti.c
new file mode 100644
index 000000000000..4604bbd41b18
--- /dev/null
+++ b/drivers/ata/pata_parport/ktti.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	ktti.c	(c) 1998  Grant R. Guenther <grant at torque.net>
+ *			  Under the terms of the GNU General Public License.
+ *
+ *	ktti.c is a low-level protocol driver for the KT Technology
+ *	parallel port adapter.  This adapter is used in the "PHd"
+ *	portable hard-drives.  As far as I can tell, this device
+ *	supports 4-bit mode _only_.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+#define j44(a, b)	(((a >> 4) & 0x0f) | (b & 0xf0))
+
+/* cont = 0 - access the IDE register file
+ * cont = 1 - access the IDE command set
+ */
+
+static int cont_map[2] = { 0x10, 0x08 };
+
+static void ktti_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	int r = regr + cont_map[cont];
+
+	w0(r); w2(0xb); w2(0xa); w2(3); w2(6);
+	w0(val); w2(3); w0(0); w2(6); w2(0xb);
+}
+
+static int ktti_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int  a, b, r;
+
+	r = regr + cont_map[cont];
+
+	w0(r); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9);
+	a = r1(); w2(0xc);  b = r1(); w2(9); w2(0xc); w2(9);
+	return j44(a, b);
+}
+
+static void ktti_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int  k, a, b;
+
+	for (k = 0; k < count / 2; k++) {
+		w0(0x10); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9);
+		a = r1(); w2(0xc); b = r1(); w2(9);
+		buf[2 * k] = j44(a, b);
+		a = r1(); w2(0xc); b = r1(); w2(9);
+		buf[2 * k + 1] = j44(a, b);
+	}
+}
+
+static void ktti_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k;
+
+	for (k = 0; k < count / 2; k++) {
+		w0(0x10); w2(0xb); w2(0xa); w2(3); w2(6);
+		w0(buf[2 * k]); w2(3);
+		w0(buf[2 * k + 1]); w2(6);
+		w2(0xb);
+	}
+}
+
+static void ktti_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+	w2(0xb); w2(0xa); w0(0); w2(3); w2(6);
+}
+
+static void ktti_disconnect(struct pi_adapter *pi)
+{
+	w2(0xb); w2(0xa); w0(0xa0); w2(3); w2(4);
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+static void ktti_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	dev_info(&pi->dev, "ktti, KT adapter at 0x%x, delay %d\n",
+		pi->port, pi->delay);
+}
+
+static struct pi_protocol ktti = {
+	.owner		= THIS_MODULE,
+	.name		= "ktti",
+	.max_mode	= 1,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= ktti_write_regr,
+	.read_regr	= ktti_read_regr,
+	.write_block	= ktti_write_block,
+	.read_block	= ktti_read_block,
+	.connect	= ktti_connect,
+	.disconnect	= ktti_disconnect,
+	.log_adapter	= ktti_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-ktti") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(ktti);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:14:06 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:14:06 +0100
Subject: [Linux-parport] [PATCH 11/16] pata_parport: add friq protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-12-linux@zary.sk>

Add Freecom IQ ASIC-2 protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  12 ++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/friq.c   | 263 ++++++++++++++++++++++++++++++
 3 files changed, 276 insertions(+)
 create mode 100644 drivers/ata/pata_parport/friq.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index 832ab8b00511..8a569ee0bf6a 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -120,3 +120,15 @@ config PATA_PARPORT_EPIA
 	  into your kernel, you may answer Y here to build in the protocol
 	  driver, otherwise you should answer M to build it as a loadable
 	  module. The module will be called epia.
+
+config PATA_PARPORT_FRIQ
+	tristate "Freecom IQ ASIC-2 protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for version 2 of the Freecom IQ parallel
+	  port IDE adapter.  This adapter is used by the Maxell Superdisk
+	  drive.  If you chose to build PATA_PARPORT support into your kernel, you
+	  may answer Y here to build in the protocol driver, otherwise you
+	  should answer M to build it as a loadable module. The module will be
+	  called friq. You must also have a high-level driver for the type
+	  of device that you want to support.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index 6e72778f45cb..20d05e525c95 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_PATA_PARPORT_FIT2)		+= fit2.o
 obj-$(CONFIG_PATA_PARPORT_FIT3)		+= fit3.o
 obj-$(CONFIG_PATA_PARPORT_EPAT)		+= epat.o
 obj-$(CONFIG_PATA_PARPORT_EPIA)		+= epia.o
+obj-$(CONFIG_PATA_PARPORT_FRIQ)		+= friq.o
diff --git a/drivers/ata/pata_parport/friq.c b/drivers/ata/pata_parport/friq.c
new file mode 100644
index 000000000000..73dabeb7c3d3
--- /dev/null
+++ b/drivers/ata/pata_parport/friq.c
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	friq.c	(c) 1998    Grant R. Guenther <grant at torque.net>
+ *			    Under the terms of the GNU General Public License
+ *
+ *	friq.c is a low-level protocol driver for the Freecom "IQ"
+ *	parallel port IDE adapter.   Early versions of this adapter
+ *	use the 'frpw' protocol.
+ *
+ *	Freecom uses this adapter in a battery powered external
+ *	CD-ROM drive.  It is also used in LS-120 drives by
+ *	Maxell and Panasonic, and other devices.
+ *
+ *	The battery powered drive requires software support to
+ *	control the power to the drive.  This module enables the
+ *	drive power when the high level driver (pcd) is loaded
+ *	and disables it when the module is unloaded.  Note, if
+ *	the friq module is built in to the kernel, the power
+ *	will never be switched off, so other means should be
+ *	used to conserve battery power.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+#define CMD(x)	do { w2(4); w0(0xff); w0(0xff); w0(0x73); w0(0x73);\
+		     w0(0xc9); w0(0xc9); w0(0x26); w0(0x26); w0(x); w0(x);\
+		} while (0)
+
+#define j44(l, h)	(((l >> 4) & 0x0f) | (h & 0xf0))
+
+/* cont = 0 - access the IDE register file
+ * cont = 1 - access the IDE command set
+ */
+
+static int cont_map[2] = { 0x08, 0x10 };
+
+static int friq_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int h, l, r;
+
+	r = regr + cont_map[cont];
+
+	CMD(r);
+	w2(6); l = r1();
+	w2(4); h = r1();
+	w2(4);
+
+	return j44(l, h);
+
+}
+
+static void friq_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	int r = regr + cont_map[cont];
+
+	CMD(r);
+	w0(val);
+	w2(5); w2(7); w2(5); w2(4);
+}
+
+static void friq_read_block_int(struct pi_adapter *pi, char *buf, int count, int regr)
+{
+	int h, l, k, ph;
+
+	switch (pi->mode) {
+
+	case 0:
+		CMD(regr);
+		for (k = 0; k < count; k++) {
+			w2(6); l = r1();
+			w2(4); h = r1();
+			buf[k] = j44(l, h);
+		}
+		w2(4);
+		break;
+	case 1:
+		ph = 2;
+		CMD(regr + 0xc0);
+		w0(0xff);
+		for (k = 0; k < count; k++) {
+			w2(0xa4 + ph);
+			buf[k] = r0();
+			ph = 2 - ph;
+		}
+		w2(0xac); w2(0xa4); w2(4);
+		break;
+	case 2:
+		CMD(regr + 0x80);
+		for (k = 0; k < count - 2; k++)
+			buf[k] = r4();
+		w2(0xac); w2(0xa4);
+		buf[count - 2] = r4();
+		buf[count - 1] = r4();
+		w2(4);
+		break;
+	case 3:
+		CMD(regr + 0x80);
+		for (k = 0; k < (count / 2) - 1; k++)
+			((u16 *)buf)[k] = r4w();
+		w2(0xac); w2(0xa4);
+		buf[count - 2] = r4();
+		buf[count - 1] = r4();
+		w2(4);
+		break;
+	case 4:
+		CMD(regr + 0x80);
+		for (k = 0; k < (count / 4) - 1; k++)
+			((u32 *)buf)[k] = r4l();
+		buf[count - 4] = r4();
+		buf[count - 3] = r4();
+		w2(0xac); w2(0xa4);
+		buf[count - 2] = r4();
+		buf[count - 1] = r4();
+		w2(4);
+		break;
+	}
+}
+
+static void friq_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	friq_read_block_int(pi, buf, count, 0x08);
+}
+
+static void friq_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k;
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+		CMD(8); w2(5);
+		for (k = 0; k < count; k++) {
+			w0(buf[k]);
+			w2(7); w2(5);
+		}
+		w2(4);
+		break;
+	case 2:
+		CMD(0xc8); w2(5);
+		for (k = 0; k < count; k++)
+			w4(buf[k]);
+		w2(4);
+		break;
+	case 3:
+		CMD(0xc8); w2(5);
+		for (k = 0; k < count / 2; k++)
+			w4w(((u16 *)buf)[k]);
+		w2(4);
+		break;
+	case 4:
+		CMD(0xc8); w2(5);
+		for (k = 0; k < count / 4; k++)
+			w4l(((u32 *)buf)[k]);
+		w2(4);
+		break;
+	}
+}
+
+static void friq_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+	w2(4);
+}
+
+static void friq_disconnect(struct pi_adapter *pi)
+{
+	CMD(0x20);
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+static int friq_test_proto(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	int j, k, r;
+	int e[2] = { 0, 0 };
+
+	pi->saved_r0 = r0();
+	w0(0xff); udelay(20); CMD(0x3d); /* turn the power on */
+	udelay(500);
+	w0(pi->saved_r0);
+
+	friq_connect(pi);
+	for (j = 0; j < 2; j++) {
+		friq_write_regr(pi, 0, 6, 0xa0 + j * 0x10);
+		for (k = 0; k < 256; k++) {
+			friq_write_regr(pi, 0, 2, k ^ 0xaa);
+			friq_write_regr(pi, 0, 3, k ^ 0x55);
+			if (friq_read_regr(pi, 0, 2) != (k ^ 0xaa))
+				e[j]++;
+		}
+	}
+	friq_disconnect(pi);
+
+	friq_connect(pi);
+	friq_read_block_int(pi, scratch, 512, 0x10);
+	r = 0;
+	for (k = 0; k < 128; k++)
+		if (scratch[k] != k)
+			r++;
+	friq_disconnect(pi);
+
+	if (verbose)
+		dev_info(&pi->dev, "friq: port 0x%x, mode %d, test=(%d,%d,%d)\n",
+			pi->port, pi->mode, e[0], e[1], r);
+
+	return (r || (e[0] && e[1]));
+}
+
+
+static void friq_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	static char * const mode_string[] = {
+		"4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
+
+	dev_info(&pi->dev, "friq, Freecom IQ ASIC-2 adapter at 0x%x, mode %d (%s), delay %d\n",
+		pi->port, pi->mode, mode_string[pi->mode], pi->delay);
+
+	pi->private = 1;
+	friq_connect(pi);
+	CMD(0x9e);		/* disable sleep timer */
+	friq_disconnect(pi);
+}
+
+static void friq_release_proto(struct pi_adapter *pi)
+{
+	if (pi->private) {		/* turn off the power */
+		friq_connect(pi);
+		CMD(0x1d); CMD(0x1e);
+		friq_disconnect(pi);
+		pi->private = 0;
+	}
+}
+
+static struct pi_protocol friq = {
+	.owner		= THIS_MODULE,
+	.name		= "friq",
+	.max_mode	= 5,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= friq_write_regr,
+	.read_regr	= friq_read_regr,
+	.write_block	= friq_write_block,
+	.read_block	= friq_read_block,
+	.connect	= friq_connect,
+	.disconnect	= friq_disconnect,
+	.test_proto	= friq_test_proto,
+	.log_adapter	= friq_log_adapter,
+	.release_proto	= friq_release_proto,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-friq") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(friq);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:14:07 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:14:07 +0100
Subject: [Linux-parport] [PATCH 12/16] pata_parport: add frpw protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-13-linux@zary.sk>

Add FreeCom power protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  10 +
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/frpw.c   | 292 ++++++++++++++++++++++++++++++
 3 files changed, 303 insertions(+)
 create mode 100644 drivers/ata/pata_parport/frpw.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index 8a569ee0bf6a..d8e5feaaae7a 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -132,3 +132,13 @@ config PATA_PARPORT_FRIQ
 	  should answer M to build it as a loadable module. The module will be
 	  called friq. You must also have a high-level driver for the type
 	  of device that you want to support.
+
+config PATA_PARPORT_FRPW
+	tristate "FreeCom power protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the Freecom power parallel port IDE
+	  protocol. If you chose to build PATA_PARPORT support into your kernel, you
+	  may answer Y here to build in the protocol driver, otherwise you
+	  should answer M to build it as a loadable module. The module will be
+	  called frpw.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index 20d05e525c95..136374be9613 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_PATA_PARPORT_FIT3)		+= fit3.o
 obj-$(CONFIG_PATA_PARPORT_EPAT)		+= epat.o
 obj-$(CONFIG_PATA_PARPORT_EPIA)		+= epia.o
 obj-$(CONFIG_PATA_PARPORT_FRIQ)		+= friq.o
+obj-$(CONFIG_PATA_PARPORT_FRPW)		+= frpw.o
diff --git a/drivers/ata/pata_parport/frpw.c b/drivers/ata/pata_parport/frpw.c
new file mode 100644
index 000000000000..5151d3c26361
--- /dev/null
+++ b/drivers/ata/pata_parport/frpw.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	frpw.c	(c) 1996-8  Grant R. Guenther <grant at torque.net>
+ *			    Under the terms of the GNU General Public License
+ *
+ *	frpw.c is a low-level protocol driver for the Freecom "Power"
+ *	parallel port IDE adapter.
+ *
+ *	Some applications of this adapter may require a "printer" reset
+ *	prior to loading the driver.  This can be done by loading and
+ *	unloading the "lp" driver, or it can be done by this driver
+ *	if you define FRPW_HARD_RESET.  The latter is not recommended
+ *	as it may upset devices on other ports.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+#define cec4		do { w2(0xc); w2(0xe); w2(0xe); w2(0xc); w2(4); w2(4); w2(4); } while (0)
+#define j44(l, h)	(((l >> 4) & 0x0f) | (h & 0xf0))
+
+/* cont = 0 - access the IDE register file
+ * cont = 1 - access the IDE command set
+ */
+
+static int cont_map[2] = { 0x08, 0x10 };
+
+static int frpw_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int h, l, r;
+
+	r = regr + cont_map[cont];
+
+	w2(4);
+	w0(r); cec4;
+	w2(6); l = r1();
+	w2(4); h = r1();
+	w2(4);
+
+	return j44(l, h);
+}
+
+static void frpw_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	int r = regr + cont_map[cont];
+
+	w2(4); w0(r); cec4;
+	w0(val);
+	w2(5); w2(7); w2(5); w2(4);
+}
+
+static void frpw_read_block_int(struct pi_adapter *pi, char *buf, int count, int regr)
+{
+	int h, l, k, ph;
+
+	switch (pi->mode) {
+	case 0:
+		w2(4); w0(regr); cec4;
+		for (k = 0; k < count; k++) {
+			w2(6); l = r1();
+			w2(4); h = r1();
+			buf[k] = j44(l, h);
+		}
+		w2(4);
+		break;
+	case 1:
+		ph = 2;
+		w2(4); w0(regr + 0xc0); cec4;
+		w0(0xff);
+		for (k = 0; k < count; k++) {
+			w2(0xa4 + ph);
+			buf[k] = r0();
+			ph = 2 - ph;
+		}
+		w2(0xac); w2(0xa4); w2(4);
+		break;
+	case 2:
+		w2(4); w0(regr + 0x80); cec4;
+		for (k = 0; k < count; k++)
+			buf[k] = r4();
+		w2(0xac); w2(0xa4);
+		w2(4);
+		break;
+	case 3:
+		w2(4); w0(regr + 0x80); cec4;
+		for (k = 0; k < count - 2; k++)
+			buf[k] = r4();
+		w2(0xac); w2(0xa4);
+		buf[count - 2] = r4();
+		buf[count - 1] = r4();
+		w2(4);
+		break;
+	case 4:
+		w2(4); w0(regr + 0x80); cec4;
+		for (k = 0; k < (count / 2) - 1; k++)
+			((u16 *)buf)[k] = r4w();
+		w2(0xac); w2(0xa4);
+		buf[count - 2] = r4();
+		buf[count - 1] = r4();
+		w2(4);
+		break;
+	case 5:
+		w2(4); w0(regr + 0x80); cec4;
+		for (k = 0; k < (count / 4) - 1; k++)
+			((u32 *)buf)[k] = r4l();
+		buf[count - 4] = r4();
+		buf[count - 3] = r4();
+		w2(0xac); w2(0xa4);
+		buf[count - 2] = r4();
+		buf[count - 1] = r4();
+		w2(4);
+		break;
+	}
+}
+
+static void frpw_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	frpw_read_block_int(pi, buf, count, 0x08);
+}
+
+static void frpw_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k;
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+	case 2:
+		w2(4); w0(8); cec4; w2(5);
+		for (k = 0; k < count; k++) {
+			w0(buf[k]);
+			w2(7); w2(5);
+		}
+		w2(4);
+		break;
+	case 3:
+		w2(4); w0(0xc8); cec4; w2(5);
+		for (k = 0; k < count; k++)
+			w4(buf[k]);
+		w2(4);
+		break;
+	case 4:
+		w2(4); w0(0xc8); cec4; w2(5);
+		for (k = 0; k < count / 2; k++)
+			w4w(((u16 *)buf)[k]);
+		w2(4);
+		break;
+	case 5:
+		w2(4); w0(0xc8); cec4; w2(5);
+		for (k = 0; k < count / 4; k++)
+			w4l(((u32 *)buf)[k]);
+		w2(4);
+		break;
+	}
+}
+
+static void frpw_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+	w2(4);
+}
+
+static void frpw_disconnect(struct pi_adapter *pi)
+{
+	w2(4); w0(0x20); cec4;
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+/* Stub logic to see if PNP string is available - used to distinguish
+ * between the Xilinx and ASIC implementations of the Freecom adapter.
+ *
+ * returns chip_type:   0 = Xilinx, 1 = ASIC
+ */
+
+static int frpw_test_pnp(struct pi_adapter *pi)
+{
+	int olddelay, a, b;
+
+#ifdef FRPW_HARD_RESET
+	w0(0); w2(8); udelay(50); w2(0xc);   /* parallel bus reset */
+	mdelay(1500);
+#endif
+
+	olddelay = pi->delay;
+	pi->delay = 10;
+
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+
+	w2(4); w0(4); w2(6); w2(7);
+	a = r1() & 0xff; w2(4); b = r1() & 0xff;
+	w2(0xc); w2(0xe); w2(4);
+
+	pi->delay = olddelay;
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+
+	return ((~a & 0x40) && (b & 0x40));
+}
+
+/* We use the pi->private to remember the result of the PNP test.
+ * To make this work, private = port*2 + chip.  Yes, I know it's a hack :-(
+ */
+
+static int frpw_test_proto(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	int j, k, r;
+	int e[2] = { 0, 0 };
+
+	if ((pi->private>>1) != pi->port)
+		pi->private = frpw_test_pnp(pi) + 2 * pi->port;
+
+	if (((pi->private % 2) == 0) && (pi->mode > 2)) {
+		if (verbose)
+			dev_info(&pi->dev, "frpw: Xilinx does not support mode %d\n",
+				pi->mode);
+		return 1;
+	}
+
+	if (((pi->private % 2) == 1) && (pi->mode == 2)) {
+		if (verbose)
+			dev_info(&pi->dev, "frpw: ASIC does not support mode 2\n");
+		return 1;
+	}
+
+	frpw_connect(pi);
+	for (j = 0; j < 2; j++) {
+		frpw_write_regr(pi, 0, 6, 0xa0 + j * 0x10);
+		for (k = 0; k < 256; k++) {
+			frpw_write_regr(pi, 0, 2, k ^ 0xaa);
+			frpw_write_regr(pi, 0, 3, k ^ 0x55);
+			if (frpw_read_regr(pi, 0, 2) != (k ^ 0xaa))
+				e[j]++;
+		}
+	}
+	frpw_disconnect(pi);
+
+	frpw_connect(pi);
+	frpw_read_block_int(pi, scratch, 512, 0x10);
+	r = 0;
+	for (k = 0; k < 128; k++)
+		if (scratch[k] != k)
+			r++;
+	frpw_disconnect(pi);
+
+	if (verbose)
+		dev_info(&pi->dev, "frpw: port 0x%x, chip %ld, mode %d, test=(%d,%d,%d)\n",
+			pi->port, (pi->private % 2), pi->mode, e[0], e[1], r);
+
+	return (r || (e[0] && e[1]));
+}
+
+
+static void frpw_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	static char * const mode_string[] = {
+		"4-bit", "8-bit", "EPP", "EPP-8", "EPP-16", "EPP-32" };
+
+	dev_info(&pi->dev, "frpw, Freecom (%s) adapter at 0x%x, mode %d (%s), delay %d\n",
+		((pi->private % 2) == 0) ? "Xilinx" : "ASIC", pi->port,
+		pi->mode, mode_string[pi->mode], pi->delay);
+}
+
+static struct pi_protocol frpw = {
+	.owner		= THIS_MODULE,
+	.name		= "frpw",
+	.max_mode	= 6,
+	.epp_first	= 2,
+	.default_delay	= 2,
+	.max_units	= 1,
+	.write_regr	= frpw_write_regr,
+	.read_regr	= frpw_read_regr,
+	.write_block	= frpw_write_block,
+	.read_block	= frpw_read_block,
+	.connect	= frpw_connect,
+	.disconnect	= frpw_disconnect,
+	.test_proto	= frpw_test_proto,
+	.log_adapter	= frpw_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-frpw") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(frpw);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:14:10 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:14:10 +0100
Subject: [Linux-parport] [PATCH 15/16] pata_parport: add on20 protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-16-linux@zary.sk>

Add OnSpec 90c20 protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  11 +++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/on20.c   | 136 ++++++++++++++++++++++++++++++
 3 files changed, 148 insertions(+)
 create mode 100644 drivers/ata/pata_parport/on20.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index 4505a037591a..c18757464b1d 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -165,3 +165,14 @@ config PATA_PARPORT_KTTI
 	  support into your kernel, you may answer Y here to build in the
 	  protocol driver, otherwise you should answer M to build it as a
 	  loadable module. The module will be called ktti.
+
+config PATA_PARPORT_ON20
+	tristate "OnSpec 90c20 protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the (obsolete) 90c20 parallel port
+	  IDE protocol from OnSpec (often marketed under the ValuStore brand
+	  name). If you chose to build PATA_PARPORT support into your kernel, you
+	  may answer Y here to build in the protocol driver, otherwise you
+	  should answer M to build it as a loadable module.The module will
+	  be called on20.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index 0c31cf55c96b..4358d1d946cb 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_PATA_PARPORT_FRIQ)		+= friq.o
 obj-$(CONFIG_PATA_PARPORT_FRPW)		+= frpw.o
 obj-$(CONFIG_PATA_PARPORT_KBIC)		+= kbic.o
 obj-$(CONFIG_PATA_PARPORT_KTTI)		+= ktti.o
+obj-$(CONFIG_PATA_PARPORT_ON20)		+= on20.o
diff --git a/drivers/ata/pata_parport/on20.c b/drivers/ata/pata_parport/on20.c
new file mode 100644
index 000000000000..2c0c6f9841dd
--- /dev/null
+++ b/drivers/ata/pata_parport/on20.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	on20.c	(c) 1996-8  Grant R. Guenther <grant at torque.net>
+ *			    Under the terms of the GNU General Public License.
+ *
+ *	on20.c is a low-level protocol driver for the
+ *	Onspec 90c20 parallel to IDE adapter.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+#define op(f)	do { w2(4); w0(f); w2(5); w2(0xd); w2(5); w2(0xd); w2(5); w2(4); } while (0)
+#define vl(v)	do { w2(4); w0(v); w2(5); w2(7); w2(5); w2(4); } while (0)
+
+#define j44(a, b)	(((a >> 4) & 0x0f) | (b & 0xf0))
+
+/* cont = 0 - access the IDE register file
+ * cont = 1 - access the IDE command set
+ */
+
+static int on20_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int h, l, r;
+
+	r = (regr << 2) + 1 + cont;
+
+	op(1); vl(r); op(0);
+
+	switch (pi->mode)  {
+	case 0:
+		w2(4); w2(6); l = r1();
+		w2(4); w2(6); h = r1();
+		w2(4); w2(6); w2(4); w2(6); w2(4);
+		return j44(l, h);
+	case 1:
+		w2(4); w2(0x26); r = r0();
+		w2(4); w2(0x26); w2(4);
+		return r;
+
+	}
+	return -1;
+}
+
+static void on20_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	int r = (regr << 2) + 1 + cont;
+
+	op(1); vl(r);
+	op(0); vl(val);
+	op(0); vl(val);
+}
+
+static void on20_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+
+	w2(4); w0(0); w2(0xc); w2(4); w2(6); w2(4); w2(6); w2(4);
+	if (pi->mode) {
+		op(2); vl(8); op(2); vl(9);
+	} else {
+		op(2); vl(0); op(2); vl(8);
+	}
+}
+
+static void on20_disconnect(struct pi_adapter *pi)
+{
+	w2(4); w0(7); w2(4); w2(0xc); w2(4);
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+static void on20_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k, l, h;
+
+	op(1); vl(1); op(0);
+
+	for (k = 0; k < count; k++)
+		if (pi->mode) {
+			w2(4); w2(0x26); buf[k] = r0();
+		} else {
+			w2(6); l = r1(); w2(4);
+			w2(6); h = r1(); w2(4);
+			buf[k] = j44(l, h);
+		}
+	w2(4);
+}
+
+static void on20_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k;
+
+	op(1); vl(1); op(0);
+
+	for (k = 0; k < count; k++) {
+		w2(5); w0(buf[k]); w2(7);
+	}
+	w2(4);
+}
+
+static void on20_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	static char * const mode_string[] = { "4-bit", "8-bit" };
+
+	dev_info(&pi->dev, "on20, OnSpec 90c20 at 0x%x, mode %d (%s), delay %d\n",
+		pi->port, pi->mode, mode_string[pi->mode], pi->delay);
+}
+
+static struct pi_protocol on20 = {
+	.owner		= THIS_MODULE,
+	.name		= "on20",
+	.max_mode	= 2,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= on20_write_regr,
+	.read_regr	= on20_read_regr,
+	.write_block	= on20_write_block,
+	.read_block	= on20_read_block,
+	.connect	= on20_connect,
+	.disconnect	= on20_disconnect,
+	.log_adapter	= on20_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-on20") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(on20);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:14:11 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:14:11 +0100
Subject: [Linux-parport] [PATCH 16/16] pata_parport: add on26 protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-17-linux@zary.sk>

Add OnSpec 90c26 protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  11 ++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/on26.c   | 302 ++++++++++++++++++++++++++++++
 3 files changed, 314 insertions(+)
 create mode 100644 drivers/ata/pata_parport/on26.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index c18757464b1d..5d3440f372fc 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -176,3 +176,14 @@ config PATA_PARPORT_ON20
 	  may answer Y here to build in the protocol driver, otherwise you
 	  should answer M to build it as a loadable module.The module will
 	  be called on20.
+
+config PATA_PARPORT_ON26
+	tristate "OnSpec 90c26 protocol"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the 90c26 parallel port IDE protocol
+	  from OnSpec Electronics (often marketed under the ValuStore brand
+	  name). If you chose to build PATA_PARPORT support into your kernel, you
+	  may answer Y here to build in the protocol driver, otherwise you
+	  should answer M to build it as a loadable module. The module will be
+	  called on26.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index 4358d1d946cb..2b03a5a9131a 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_PATA_PARPORT_FRPW)		+= frpw.o
 obj-$(CONFIG_PATA_PARPORT_KBIC)		+= kbic.o
 obj-$(CONFIG_PATA_PARPORT_KTTI)		+= ktti.o
 obj-$(CONFIG_PATA_PARPORT_ON20)		+= on20.o
+obj-$(CONFIG_PATA_PARPORT_ON26)		+= on26.o
diff --git a/drivers/ata/pata_parport/on26.c b/drivers/ata/pata_parport/on26.c
new file mode 100644
index 000000000000..1f224bb38b4a
--- /dev/null
+++ b/drivers/ata/pata_parport/on26.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	on26.c    (c) 1997-8  Grant R. Guenther <grant at torque.net>
+ *			      Under the terms of the GNU General Public License.
+ *
+ *	on26.c is a low-level protocol driver for the
+ *	OnSpec 90c26 parallel to IDE adapter chip.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+/* mode codes:  0  nybble reads, 8-bit writes
+ *		1  8-bit reads and writes
+ *		2  8-bit EPP mode
+ *		3  EPP-16
+ *		4  EPP-32
+ */
+
+#define j44(a, b)  (((a >> 4) & 0x0f) | (b & 0xf0))
+
+#define P1	do { w2(5); w2(0xd); w2(5); w2(0xd); w2(5); w2(4); } while (0)
+#define P2	do { w2(5); w2(7); w2(5); w2(4); } while (0)
+
+/* cont = 0 - access the IDE register file
+ * cont = 1 - access the IDE command set
+ */
+
+static int on26_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int a, b, r;
+
+	r = (regr << 2) + 1 + cont;
+
+	switch (pi->mode)  {
+	case 0:
+		w0(1); P1; w0(r); P2; w0(0); P1;
+		w2(6); a = r1(); w2(4);
+		w2(6); b = r1(); w2(4);
+		w2(6); w2(4); w2(6); w2(4);
+		return j44(a, b);
+	case 1:
+		w0(1); P1; w0(r); P2; w0(0); P1;
+		w2(0x26); a = r0(); w2(4); w2(0x26); w2(4);
+		return a;
+	case 2:
+	case 3:
+	case 4:
+		w3(1); w3(1); w2(5); w4(r); w2(4);
+		w3(0); w3(0); w2(0x24); a = r4(); w2(4);
+		w2(0x24); (void)r4(); w2(4);
+		return a;
+	}
+	return -1;
+}
+
+static void on26_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	int r = (regr<<2) + 1 + cont;
+
+	switch (pi->mode)  {
+	case 0:
+	case 1:
+		w0(1); P1; w0(r); P2; w0(0); P1;
+		w0(val); P2; w0(val); P2;
+		break;
+	case 2:
+	case 3:
+	case 4:
+		w3(1); w3(1); w2(5); w4(r); w2(4);
+		w3(0); w3(0);
+		w2(5); w4(val); w2(4);
+		w2(5); w4(val); w2(4);
+		break;
+	}
+}
+
+#define CCP(x)	do { w0(0xfe); w0(0xaa); w0(0x55); w0(0); w0(0xff);\
+		     w0(0x87); w0(0x78); w0(x); w2(4); w2(5); w2(4); w0(0xff);\
+		} while (0)
+
+static void on26_connect(struct pi_adapter *pi)
+{
+	int x;
+
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+
+	CCP(0x20);
+	x = 8;
+	if (pi->mode)
+		x = 9;
+
+	w0(2); P1; w0(8); P2;
+	w0(2); P1; w0(x); P2;
+}
+
+static void on26_disconnect(struct pi_adapter *pi)
+{
+	if (pi->mode >= 2) {
+		w3(4); w3(4); w3(4); w3(4);
+	} else {
+		w0(4); P1; w0(4); P1;
+	}
+	CCP(0x30);
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+#define	RESET_WAIT  200
+
+static int on26_test_port(struct pi_adapter *pi)  /* hard reset */
+{
+	int i, m, d, x = 0, y = 0;
+
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+
+	d = pi->delay;
+	m = pi->mode;
+	pi->delay = 5;
+	pi->mode = 0;
+
+	w2(0xc);
+
+	CCP(0x30); CCP(0);
+
+	w0(0xfe); w0(0xaa); w0(0x55); w0(0); w0(0xff);
+	i = ((r1() & 0xf0) << 4); w0(0x87);
+	i |= (r1() & 0xf0); w0(0x78);
+	w0(0x20); w2(4); w2(5);
+	i |= ((r1() & 0xf0) >> 4);
+	w2(4); w0(0xff);
+
+	if (i == 0xb5f) {
+		w0(2); P1; w0(0);   P2;
+		w0(3); P1; w0(0);   P2;
+		w0(2); P1; w0(8);   P2; udelay(100);
+		w0(2); P1; w0(0xa); P2; udelay(100);
+		w0(2); P1; w0(8);   P2; udelay(1000);
+
+		on26_write_regr(pi, 0, 6, 0xa0);
+
+		for (i = 0; i < RESET_WAIT; i++) {
+			on26_write_regr(pi, 0, 6, 0xa0);
+			x = on26_read_regr(pi, 0, 7);
+			on26_write_regr(pi, 0, 6, 0xb0);
+			y = on26_read_regr(pi, 0, 7);
+			if (!((x & 0x80) || (y & 0x80)))
+				break;
+			mdelay(100);
+		}
+
+		if (i == RESET_WAIT)
+			dev_err(&pi->dev, "on26: Device reset failed (%x,%x)\n", x, y);
+
+		w0(4); P1; w0(4); P1;
+	}
+
+	CCP(0x30);
+
+	pi->delay = d;
+	pi->mode = m;
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+
+	return 5;
+}
+
+
+static void on26_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k, a, b;
+
+	switch (pi->mode) {
+	case 0:
+		w0(1); P1; w0(1); P2; w0(2); P1; w0(0x18); P2; w0(0); P1;
+		udelay(10);
+		for (k = 0; k < count; k++) {
+			w2(6); a = r1();
+			w2(4); b = r1();
+			buf[k] = j44(a, b);
+		}
+		w0(2); P1; w0(8); P2;
+		break;
+	case 1:
+		w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1;
+		udelay(10);
+		for (k = 0; k < count / 2; k++) {
+			w2(0x26); buf[2 * k] = r0();
+			w2(0x24); buf[2 * k + 1] = r0();
+		}
+		w0(2); P1; w0(9); P2;
+		break;
+	case 2:
+		w3(1); w3(1); w2(5); w4(1); w2(4);
+		w3(0); w3(0); w2(0x24);
+		udelay(10);
+		for (k = 0; k < count; k++)
+			buf[k] = r4();
+		w2(4);
+		break;
+	case 3:
+		w3(1); w3(1); w2(5); w4(1); w2(4);
+		w3(0); w3(0); w2(0x24);
+		udelay(10);
+		for (k = 0; k < count / 2; k++)
+			((u16 *)buf)[k] = r4w();
+		w2(4);
+		break;
+	case 4:
+		w3(1); w3(1); w2(5); w4(1); w2(4);
+		w3(0); w3(0); w2(0x24);
+		udelay(10);
+		for (k = 0; k < count / 4; k++)
+			((u32 *)buf)[k] = r4l();
+		w2(4);
+		break;
+	}
+}
+
+static void on26_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k;
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+		w0(1); P1; w0(1); P2;
+		w0(2); P1; w0(0x18 + pi->mode); P2; w0(0); P1;
+		udelay(10);
+		for (k = 0; k < count / 2; k++) {
+			w2(5); w0(buf[2 * k]);
+			w2(7); w0(buf[2 * k + 1]);
+		}
+		w2(5); w2(4);
+		w0(2); P1; w0(8 + pi->mode); P2;
+		break;
+	case 2:
+		w3(1); w3(1); w2(5); w4(1); w2(4);
+		w3(0); w3(0); w2(0xc5);
+		udelay(10);
+		for (k = 0; k < count; k++)
+			w4(buf[k]);
+		w2(0xc4);
+		break;
+	case 3:
+		w3(1); w3(1); w2(5); w4(1); w2(4);
+		w3(0); w3(0); w2(0xc5);
+		udelay(10);
+		for (k = 0; k < count / 2; k++)
+			w4w(((u16 *)buf)[k]);
+		w2(0xc4);
+		break;
+	case 4:
+		w3(1); w3(1); w2(5); w4(1); w2(4);
+		w3(0); w3(0); w2(0xc5);
+		udelay(10);
+		for (k = 0; k < count / 4; k++)
+			w4l(((u32 *)buf)[k]);
+		w2(0xc4);
+		break;
+	}
+}
+
+static void on26_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	static char * const mode_string[] = {
+		"4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
+
+	dev_info(&pi->dev, "on26, OnSpec 90c26 at 0x%x, mode %d (%s), delay %d\n",
+		pi->port, pi->mode, mode_string[pi->mode], pi->delay);
+}
+
+static struct pi_protocol on26 = {
+	.owner		= THIS_MODULE,
+	.name		= "on26",
+	.max_mode	= 5,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= on26_write_regr,
+	.read_regr	= on26_read_regr,
+	.write_block	= on26_write_block,
+	.read_block	= on26_read_block,
+	.connect	= on26_connect,
+	.disconnect	= on26_disconnect,
+	.test_port	= on26_test_port,
+	.log_adapter	= on26_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-on26") },
+};
+
+MODULE_LICENSE("GPL");
+module_pata_parport_driver(on26);
-- 
Ondrej Zary



From linux at zary.sk  Sat Mar  5 12:14:08 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat,  5 Mar 2022 21:14:08 +0100
Subject: [Linux-parport] [PATCH 13/16] pata_parport: add kbic protocol driver
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220305201411.501-14-linux@zary.sk>

Add KingByte KBIC-951A/971A protocol driver.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/ata/pata_parport/Kconfig  |  12 ++
 drivers/ata/pata_parport/Makefile |   1 +
 drivers/ata/pata_parport/kbic.c   | 292 ++++++++++++++++++++++++++++++
 3 files changed, 305 insertions(+)
 create mode 100644 drivers/ata/pata_parport/kbic.c

diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
index d8e5feaaae7a..004e5cf708f1 100644
--- a/drivers/ata/pata_parport/Kconfig
+++ b/drivers/ata/pata_parport/Kconfig
@@ -142,3 +142,15 @@ config PATA_PARPORT_FRPW
 	  may answer Y here to build in the protocol driver, otherwise you
 	  should answer M to build it as a loadable module. The module will be
 	  called frpw.
+
+config PATA_PARPORT_KBIC
+	tristate "KingByte KBIC-951A/971A protocols"
+	depends on PATA_PARPORT
+	help
+	  This option enables support for the KBIC-951A and KBIC-971A parallel
+	  port IDE protocols from KingByte Information Corp. KingByte's
+	  adapters appear in many no-name portable disk and CD-ROM products,
+	  especially in Europe. If you chose to build PATA_PARPORT support into your
+	  kernel, you may answer Y here to build in the protocol driver,
+	  otherwise you should answer M to build it as a loadable module. The
+	  module will be called kbic.
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
index 136374be9613..e82fded22da3 100644
--- a/drivers/ata/pata_parport/Makefile
+++ b/drivers/ata/pata_parport/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_PATA_PARPORT_EPAT)		+= epat.o
 obj-$(CONFIG_PATA_PARPORT_EPIA)		+= epia.o
 obj-$(CONFIG_PATA_PARPORT_FRIQ)		+= friq.o
 obj-$(CONFIG_PATA_PARPORT_FRPW)		+= frpw.o
+obj-$(CONFIG_PATA_PARPORT_KBIC)		+= kbic.o
diff --git a/drivers/ata/pata_parport/kbic.c b/drivers/ata/pata_parport/kbic.c
new file mode 100644
index 000000000000..49f8a88db2a2
--- /dev/null
+++ b/drivers/ata/pata_parport/kbic.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	kbic.c    (c) 1997-8  Grant R. Guenther <grant at torque.net>
+ *			      Under the terms of the GNU General Public License.
+ *
+ *	This is a low-level driver for the KBIC-951A and KBIC-971A
+ *	parallel to IDE adapter chips from KingByte Information Systems.
+ *
+ *	The chips are almost identical, however, the wakeup code
+ *	required for the 971A interferes with the correct operation of
+ *	the 951A, so this driver registers itself twice, once for
+ *	each chip.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+
+#include "pata_parport.h"
+
+#define r12w()		(delay_p, inw(pi->port + 1) & 0xffff)
+
+#define j44(a, b)	((((a >> 4) & 0x0f) | (b & 0xf0)) ^ 0x88)
+#define j53(w)		(((w >> 3) & 0x1f) | ((w >> 4) & 0xe0))
+
+
+/* cont = 0 - access the IDE register file
+ * cont = 1 - access the IDE command set
+ */
+
+static int cont_map[2] = { 0x80, 0x40 };
+
+static int kbic_read_regr(struct pi_adapter *pi, int cont, int regr)
+{
+	int a, b, s;
+
+	s = cont_map[cont];
+
+	switch (pi->mode) {
+	case 0:
+		w0(regr | 0x18 | s); w2(4); w2(6); w2(4); w2(1); w0(8);
+		a = r1(); w0(0x28); b = r1(); w2(4);
+		return j44(a, b);
+	case 1:
+		w0(regr | 0x38 | s); w2(4); w2(6); w2(4); w2(5); w0(8);
+		a = r12w(); w2(4);
+		return j53(a);
+	case 2:
+		w0(regr | 0x08 | s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1);
+		a = r0(); w2(4);
+		return a;
+	case 3:
+	case 4:
+	case 5:
+		w0(0x20 | s); w2(4); w2(6); w2(4); w3(regr);
+		a = r4(); b = r4(); w2(4); w2(0); w2(4);
+		return a;
+	}
+	return -1;
+}
+
+static void kbic_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
+{
+	int s = cont_map[cont];
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+	case 2:
+		w0(regr | 0x10 | s); w2(4); w2(6); w2(4);
+		w0(val); w2(5); w2(4);
+		break;
+	case 3:
+	case 4:
+	case 5:
+		w0(0x20 | s); w2(4); w2(6); w2(4); w3(regr);
+		w4(val); w4(val);
+		w2(4); w2(0); w2(4);
+		break;
+	}
+}
+
+static void k951_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+	w2(4);
+}
+
+static void k951_disconnect(struct pi_adapter *pi)
+{
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+#define	CCP(x)	do { w2(0xc4); w0(0xaa); w0(0x55); w0(0); w0(0xff); w0(0x87);\
+		     w0(0x78); w0(x); w2(0xc5); w2(0xc4); w0(0xff);\
+		} while (0)
+
+static void k971_connect(struct pi_adapter *pi)
+{
+	pi->saved_r0 = r0();
+	pi->saved_r2 = r2();
+	CCP(0x20);
+	w2(4);
+}
+
+static void k971_disconnect(struct pi_adapter *pi)
+{
+	CCP(0x30);
+	w0(pi->saved_r0);
+	w2(pi->saved_r2);
+}
+
+/* counts must be congruent to 0 MOD 4, but all known applications
+ * have this property.
+ */
+
+static void kbic_read_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k, a, b;
+
+	switch (pi->mode) {
+	case 0:
+		w0(0x98); w2(4); w2(6); w2(4);
+		for (k = 0; k < count/2; k++) {
+			w2(1); w0(8);    a = r1();
+			       w0(0x28); b = r1();
+			buf[2 * k]   = j44(a, b);
+			w2(5);	   b = r1();
+			       w0(8);    a = r1();
+			buf[2 * k + 1] = j44(a, b);
+			w2(4);
+		}
+		break;
+	case 1:
+		w0(0xb8); w2(4); w2(6); w2(4);
+		for (k = 0; k < count / 4; k++) {
+			w0(0xb8);
+			w2(4); w2(5);
+			w0(8);    buf[4 * k]   = j53(r12w());
+			w0(0xb8); buf[4 * k + 1] = j53(r12w());
+			w2(4); w2(5);
+				  buf[4 * k + 3] = j53(r12w());
+			w0(8);    buf[4 * k + 2] = j53(r12w());
+		}
+		w2(4);
+		break;
+	case 2:
+		w0(0x88); w2(4); w2(6); w2(4);
+		for (k = 0; k < count / 2; k++) {
+			w2(0xa0); w2(0xa1); buf[2 * k] = r0();
+			w2(0xa5); buf[2 * k + 1] = r0();
+		}
+		w2(4);
+		break;
+	case 3:
+		w0(0xa0); w2(4); w2(6); w2(4); w3(0);
+		for (k = 0; k < count; k++)
+			buf[k] = r4();
+		w2(4); w2(0); w2(4);
+		break;
+	case 4:
+		w0(0xa0); w2(4); w2(6); w2(4); w3(0);
+		for (k = 0; k < count / 2; k++)
+			((u16 *)buf)[k] = r4w();
+		w2(4); w2(0); w2(4);
+		break;
+	case 5:
+		w0(0xa0); w2(4); w2(6); w2(4); w3(0);
+		for (k = 0; k < count / 4; k++)
+			((u32 *)buf)[k] = r4l();
+		w2(4); w2(0); w2(4);
+		break;
+	}
+}
+
+static void kbic_write_block(struct pi_adapter *pi, char *buf, int count)
+{
+	int k;
+
+	switch (pi->mode) {
+	case 0:
+	case 1:
+	case 2:
+		w0(0x90); w2(4); w2(6); w2(4);
+		for (k = 0; k < count / 2; k++) {
+			w0(buf[2 * k + 1]); w2(0); w2(4);
+			w0(buf[2 * k]);   w2(5); w2(4);
+		}
+		break;
+	case 3:
+		w0(0xa0); w2(4); w2(6); w2(4); w3(0);
+		for (k = 0; k < count / 2; k++) {
+			w4(buf[2 * k + 1]);
+			w4(buf[2 * k]);
+		}
+		w2(4); w2(0); w2(4);
+		break;
+	case 4:
+		w0(0xa0); w2(4); w2(6); w2(4); w3(0);
+		for (k = 0; k < count / 2; k++)
+			w4w(pi_swab16(buf, k));
+		w2(4); w2(0); w2(4);
+		break;
+	case 5:
+		w0(0xa0); w2(4); w2(6); w2(4); w3(0);
+		for (k = 0; k < count / 4; k++)
+			w4l(pi_swab32(buf, k));
+		w2(4); w2(0); w2(4);
+		break;
+	}
+}
+
+static void kbic_log_adapter(struct pi_adapter *pi, char *scratch, int verbose, char *chip)
+{
+	static char * const mode_string[] = {
+		"4-bit", "5/3", "8-bit", "EPP-8", "EPP_16", "EPP-32"};
+
+	dev_info(&pi->dev, "kbic, KingByte %s at 0x%x, mode %d (%s), delay %d\n",
+		chip, pi->port, pi->mode, mode_string[pi->mode], pi->delay);
+}
+
+static void k951_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	kbic_log_adapter(pi, scratch, verbose, "KBIC-951A");
+}
+
+static void k971_log_adapter(struct pi_adapter *pi, char *scratch, int verbose)
+{
+	kbic_log_adapter(pi, scratch, verbose, "KBIC-971A");
+}
+
+static struct pi_protocol k951 = {
+	.owner		= THIS_MODULE,
+	.name		= "k951",
+	.max_mode	= 6,
+	.epp_first	= 3,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= kbic_write_regr,
+	.read_regr	= kbic_read_regr,
+	.write_block	= kbic_write_block,
+	.read_block	= kbic_read_block,
+	.connect	= k951_connect,
+	.disconnect	= k951_disconnect,
+	.log_adapter	= k951_log_adapter,
+};
+
+static struct pi_protocol k971 = {
+	.owner		= THIS_MODULE,
+	.name		= "k971",
+	.max_mode	= 6,
+	.epp_first	= 3,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= kbic_write_regr,
+	.read_regr	= kbic_read_regr,
+	.write_block	= kbic_write_block,
+	.read_block	= kbic_read_block,
+	.connect	= k971_connect,
+	.disconnect	= k971_disconnect,
+	.log_adapter	= k971_log_adapter,
+	.sht		= { PATA_PARPORT_SHT("pata_parport-kbic") },
+};
+
+static int __init kbic_init(void)
+{
+	int rv;
+
+	rv = pata_parport_register_driver(&k951);
+	if (rv < 0)
+		return rv;
+	rv = pata_parport_register_driver(&k971);
+	if (rv < 0)
+		pata_parport_unregister_driver(&k951);
+	return rv;
+}
+
+static void __exit kbic_exit(void)
+{
+	pata_parport_unregister_driver(&k951);
+	pata_parport_unregister_driver(&k971);
+}
+
+MODULE_LICENSE("GPL");
+module_init(kbic_init)
+module_exit(kbic_exit)
-- 
Ondrej Zary



From hch at lst.de  Sun Mar  6 00:58:25 2022
From: hch at lst.de (Christoph Hellwig)
Date: Sun, 6 Mar 2022 09:58:25 +0100
Subject: [Linux-parport] [RFC PATCH] pata_parport: paride replacement
In-Reply-To: <20220305201411.501-1-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
Message-ID: <20220306085825.GA22425@lst.de>

Hi Ondrej,

I just took a quick glance and it seems like the actual protocol
modules still are basically almost exactly the same ones as the
paride ones.  Is there a way to just keep the existing modules?

The only big thing I noticed is the host template, but at least
for the transitional periode we could probably allocate that
dynamically in the core.  I think would reduce the amount of code
churn nicely and make review much easier.


From linux at zary.sk  Sun Mar  6 02:36:36 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sun, 6 Mar 2022 11:36:36 +0100
Subject: [Linux-parport] [RFC PATCH] pata_parport: paride replacement
In-Reply-To: <20220306085825.GA22425@lst.de>
References: <20220305201411.501-1-linux@zary.sk>
 <20220306085825.GA22425@lst.de>
Message-ID: <202203061136.36700.linux@zary.sk>

On Sunday 06 March 2022 09:58:25 Christoph Hellwig wrote:
> Hi Ondrej,
> 
> I just took a quick glance and it seems like the actual protocol
> modules still are basically almost exactly the same ones as the
> paride ones.  Is there a way to just keep the existing modules?
> 
> The only big thing I noticed is the host template, but at least
> for the transitional periode we could probably allocate that
> dynamically in the core.  I think would reduce the amount of code
> churn nicely and make review much easier.

Yes, only small changes in the protocol modules regarding (un)registration.

Getting the original modules work with pata_parport (like in 1st preview) required some hacks that break paride (disabling EXPORT_SYMBOLs in paride).

Maybe the protocol modules can be moved (git mv) from paride and then patched? A copy would be better but there's no "git cp".

-- 
Ondrej Zary


From damien.lemoal at opensource.wdc.com  Sun Mar  6 21:52:51 2022
From: damien.lemoal at opensource.wdc.com (Damien Le Moal)
Date: Mon, 7 Mar 2022 14:52:51 +0900
Subject: [Linux-parport] [PATCH 01/16] pata_parport: add core driver
 (PARIDE replacement)
In-Reply-To: <20220305201411.501-2-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
 <20220305201411.501-2-linux@zary.sk>
Message-ID: <2a79b7ac-6648-7855-fcfa-de0800c9a310@opensource.wdc.com>

On 3/6/22 05:13, Ondrej Zary wrote:
> Add pata_parport (PARIDE replacement) core libata driver.
> 
> Signed-off-by: Ondrej Zary <linux at zary.sk>
> ---
>  drivers/ata/Kconfig                     |  25 +
>  drivers/ata/Makefile                    |   2 +
>  drivers/ata/pata_parport/Kconfig        |  10 +
>  drivers/ata/pata_parport/Makefile       |   9 +
>  drivers/ata/pata_parport/pata_parport.c | 809 ++++++++++++++++++++++++
>  drivers/ata/pata_parport/pata_parport.h | 110 ++++
>  6 files changed, 965 insertions(+)
>  create mode 100644 drivers/ata/pata_parport/Kconfig
>  create mode 100644 drivers/ata/pata_parport/Makefile
>  create mode 100644 drivers/ata/pata_parport/pata_parport.c
>  create mode 100644 drivers/ata/pata_parport/pata_parport.h
> 
> diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
> index cb54631fd950..de4548471398 100644
> --- a/drivers/ata/Kconfig
> +++ b/drivers/ata/Kconfig
> @@ -1161,6 +1161,31 @@ config PATA_WINBOND_VLB
>  	  Support for the Winbond W83759A controller on Vesa Local Bus
>  	  systems.
>  
> +config PATA_PARPORT
> +	tristate "Parallel port IDE device support (PARIDE replacement)"

I would remove the "(PARIDE replacement)" from the title. If really
needed, mention it in the description that this support used to be
implemented by PARIDE. But I do not think that is necessary. The last
paragraph of the description implies that.

> +	depends on PARPORT_PC
> +	help
> +	  There are many external CD-ROM and disk devices that connect through
> +	  your computer's parallel port. Most of them are actually IDE devices
> +	  using a parallel port IDE adapter. This option enables the PATA_PARPORT
> +	  subsystem which contains drivers for many of these external drives.
> +	  Read <file:Documentation/admin-guide/blockdev/paride.rst> for more information.
> +
> +	  If you have said Y to the "Parallel-port support" configuration
> +	  option, you may share a single port between your printer and other
> +	  parallel port devices. Answer Y to build PATA_PARPORT support into your
> +	  kernel, or M if you would like to build it as a loadable module. If
> +	  your parallel port support is in a loadable module, you must build
> +	  PATA_PARPORT as a module. If you built PATA_PARPORT support into your kernel,
> +	  you may still build the individual protocol modules as loadable
> +	  modules. If you build this support as a module, it will be called pata_parport.
> +
> +	  Unlike the old PARIDE, there are no high-level drivers needed.
> +	  The IDE devices behind parallel port adapters are handled by the
> +	  ATA layer.

Several lines are too long. Rewrap please.

> +
> +source "drivers/ata/pata_parport/Kconfig"
> +
>  comment "Generic fallback / legacy drivers"
>  
>  config PATA_ACPI
> diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
> index b8aebfb14e82..bd6b5fdc004e 100644
> --- a/drivers/ata/Makefile
> +++ b/drivers/ata/Makefile
> @@ -114,6 +114,8 @@ obj-$(CONFIG_PATA_SAMSUNG_CF)	+= pata_samsung_cf.o
>  
>  obj-$(CONFIG_PATA_PXA)		+= pata_pxa.o
>  
> +obj-$(CONFIG_PATA_PARPORT)	+= pata_parport/
> +
>  # Should be last but two libata driver
>  obj-$(CONFIG_PATA_ACPI)		+= pata_acpi.o
>  # Should be last but one libata driver
> diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
> new file mode 100644
> index 000000000000..56dc6b25d5fa
> --- /dev/null
> +++ b/drivers/ata/pata_parport/Kconfig
> @@ -0,0 +1,10 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# PATA_PARPORT configuration
> +#
> +# PATA_PARPORT doesn't need PARPORT, but if PARPORT is configured as a module,
> +# PATA_PARPORT must also be a module.

This does not parse. If PARPORT is not needed, then why does how PARPORT
is compiled matter ? Something is not consistent here.

> +# PATA_PARPORT only supports PC style parports. Tough for USB or other parports...

The second sentence does not parse. What are you trying to say ?

> +
> +comment "Parallel IDE protocol modules"
> +	depends on PATA_PARPORT
> diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
> new file mode 100644
> index 000000000000..b105e1cb8dc6
> --- /dev/null
> +++ b/drivers/ata/pata_parport/Makefile
> @@ -0,0 +1,9 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Makefile for Parallel port IDE device drivers.
> +#
> +# 7 October 2000, Bartlomiej Zolnierkiewicz <bkz at linux-ide.org>
> +# Rewritten to use lists instead of if-statements.
> +#
> +
> +obj-$(CONFIG_PATA_PARPORT)		+= pata_parport.o
> diff --git a/drivers/ata/pata_parport/pata_parport.c b/drivers/ata/pata_parport/pata_parport.c
> new file mode 100644
> index 000000000000..7f814062cedd
> --- /dev/null
> +++ b/drivers/ata/pata_parport/pata_parport.c
> @@ -0,0 +1,809 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/parport.h>
> +#include "pata_parport.h"
> +
> +#define DRV_NAME "pata_parport"
> +
> +static DEFINE_IDR(parport_list);
> +static DEFINE_IDR(protocols);
> +static DEFINE_IDA(pata_parport_bus_dev_ids);
> +static DEFINE_MUTEX(pi_mutex);
> +
> +static bool probe = 1;

s/1/true to match the type.

> +module_param(probe, bool, 0644);
> +MODULE_PARM_DESC(probe, "Enable automatic device probing (0=off, 1=on [default])");
> +
> +static bool verbose;
> +module_param(verbose, bool, 0644);
> +MODULE_PARM_DESC(verbose, "Enable verbose messages (0=off [default], 1=on)");

Is this really necessary ? pr_debug() and all ata_xxx_debug() functions
can be enabled dynamically.

> +
> +#define DISCONNECT_TIMEOUT	(HZ / 10)
> +
> +static void pi_connect(struct pi_adapter *pi)
> +{
> +	del_timer_sync(&pi->timer);
> +	if (pi->claimed)
> +		return;

Nit: I would reverse the condition to avoid the return. Or add a block
line to separate the following hunk. Better readability this way, I think.

> +	pi->claimed = 1;
> +	parport_claim_or_block(pi->pardev);
> +	pi->proto->connect(pi);
> +}
> +
> +static void pi_disconnect_later(struct pi_adapter *pi)
> +{
> +	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
> +}

Is this really needed ? Not sure it helps in any way. At least the name
should be changed to reflect what this does. May be something like
pi_start_disconnect_timeout() ?

> +
> +static void pi_disconnect_timer(struct timer_list *t)
> +{
> +	struct pi_adapter *pi = from_timer(pi, t, timer);
> +
> +	if (!pi->claimed)
> +		return;

A blank line here would be nice for readability.

> +	pi->proto->disconnect(pi);
> +	parport_release(pi->pardev);
> +	pi->claimed = 0;
> +}
> +
> +/* functions taken from libata-sff.c and converted from direct port I/O */
> +static unsigned int pata_parport_devchk(struct ata_port *ap, unsigned int device)

Should this be a bool function ?

> +{
> +	struct pi_adapter *pi = ap->host->private_data;
> +	u8 nsect, lbal;
> +
> +	ap->ops->sff_dev_select(ap, device);
> +
> +	pi_connect(pi);
> +	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0x55);
> +	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
> +
> +	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0xaa);
> +	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0x55);
> +
> +	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 055);
> +	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
> +
> +	nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
> +	lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
> +	pi_disconnect_later(pi);
> +
> +	if ((nsect == 0x55) && (lbal == 0xaa))
> +		return 1;	/* we found a device */
> +
> +	return 0;		/* nothing found */
> +}
> +
> +static int pata_parport_bus_softreset(struct ata_port *ap, unsigned int devmask,
> +				      unsigned long deadline)
> +{
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	/* software reset.  causes dev0 to be selected */
> +	pi->proto->write_regr(pi, 1, 6, ap->ctl);
> +	udelay(20);	/* FIXME: flush */

Then please fix it.

> +	pi->proto->write_regr(pi, 1, 6, ap->ctl | ATA_SRST);
> +	udelay(20);	/* FIXME: flush */

Here too.

> +	pi->proto->write_regr(pi, 1, 6, ap->ctl);
> +	ap->last_ctl = ap->ctl;
> +	pi_disconnect_later(pi);
> +
> +	/* wait the port to become ready */
> +	return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
> +}
> +
> +static int pata_parport_softreset(struct ata_link *link, unsigned int *classes,
> +				  unsigned long deadline)
> +{
> +	struct ata_port *ap = link->ap;
> +	unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
> +	unsigned int devmask = 0;
> +	int rc;
> +	u8 err;
> +
> +	/* determine if device 0/1 are present */
> +	if (pata_parport_devchk(ap, 0))
> +		devmask |= (1 << 0);
> +	if (slave_possible && pata_parport_devchk(ap, 1))
> +		devmask |= (1 << 1);
> +
> +	/* select device 0 again */
> +	ap->ops->sff_dev_select(ap, 0);
> +
> +	/* issue bus reset */
> +	rc = pata_parport_bus_softreset(ap, devmask, deadline);
> +	/* if link is occupied, -ENODEV too is an error */

Please merge this comment with the one above. That will make the code
more readable (I know this is the style used by many drivers, but let's
not repeat the weird style :)).

> +	if (rc && (rc != -ENODEV || sata_scr_valid(link))) {
> +		ata_link_err(link, "SRST failed (errno=%d)\n", rc);
> +		return rc;
> +	}
> +
> +	/* determine by signature whether we have ATA or ATAPI devices */
> +	classes[0] = ata_sff_dev_classify(&link->device[0],
> +					  devmask & (1 << 0), &err);
> +	if (slave_possible && err != 0x81)
> +		classes[1] = ata_sff_dev_classify(&link->device[1],
> +						  devmask & (1 << 1), &err);
> +
> +	return 0;
> +}
> +
> +static u8 pata_parport_check_status(struct ata_port *ap)
> +{
> +	u8 status;
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
> +	pi_disconnect_later(pi);
> +
> +	return status;
> +}
> +
> +static u8 pata_parport_check_altstatus(struct ata_port *ap)
> +{
> +	u8 altstatus;
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	altstatus = pi->proto->read_regr(pi, 1, 6);
> +	pi_disconnect_later(pi);
> +
> +	return altstatus;
> +}
> +
> +static void pata_parport_dev_select(struct ata_port *ap, unsigned int device)
> +{
> +	struct pi_adapter *pi = ap->host->private_data;
> +	u8 tmp;
> +
> +	pi_connect(pi);
> +	if (device == 0)
> +		tmp = ATA_DEVICE_OBS;
> +	else
> +		tmp = ATA_DEVICE_OBS | ATA_DEV1;
> +
> +	pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tmp);
> +	pi_disconnect_later(pi);
> +	ata_sff_pause(ap);	/* needed; also flushes, for mmio */

The comment does not parse... Why is it needed ?
And pleasde move the comment above the call, with a blank line
separating it from the previous lines.

> +}
> +
> +static void pata_parport_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
> +{
> +	struct pi_adapter *pi = ap->host->private_data;
> +	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
> +
> +	pi_connect(pi);
> +	if (tf->ctl != ap->last_ctl) {
> +		pi->proto->write_regr(pi, 1, 6, tf->ctl);
> +		ap->last_ctl = tf->ctl;
> +		ata_wait_idle(ap);
> +	}
> +
> +	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
> +		pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->hob_feature);
> +		pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->hob_nsect);
> +		pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->hob_lbal);
> +		pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->hob_lbam);
> +		pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->hob_lbah);
> +	}
> +
> +	if (is_addr) {

Move this if above the previous one. Doing so, you can remove the need
for is_addr var and simplify the previous if condition.

That said, many pata drivers check that flag but it is always set by
libata core. So checking it seems useless. Need to dig into this.


> +		pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->feature);
> +		pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->nsect);
> +		pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->lbal);
> +		pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->lbam);
> +		pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->lbah);
> +	}
> +
> +	if (tf->flags & ATA_TFLAG_DEVICE)
> +		pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tf->device);
> +
> +	ata_wait_idle(ap);
> +	pi_disconnect_later(pi);
> +}
> +
> +static void pata_parport_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
> +{
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	tf->command = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
> +	tf->feature = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
> +	tf->nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
> +	tf->lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
> +	tf->lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
> +	tf->lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
> +	tf->device = pi->proto->read_regr(pi, 0, ATA_REG_DEVICE);
> +
> +	if (tf->flags & ATA_TFLAG_LBA48) {
> +		pi->proto->write_regr(pi, 1, 6, tf->ctl | ATA_HOB);
> +		tf->hob_feature = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
> +		tf->hob_nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
> +		tf->hob_lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
> +		tf->hob_lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
> +		tf->hob_lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
> +		pi->proto->write_regr(pi, 1, 6, tf->ctl);
> +		ap->last_ctl = tf->ctl;
> +	}
> +	pi_disconnect_later(pi);
> +}
> +
> +static void pata_parport_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
> +{
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	pi->proto->write_regr(pi, 0, ATA_REG_CMD, tf->command);
> +	ata_sff_pause(ap);
> +	pi_disconnect_later(pi);
> +}
> +
> +static unsigned int pata_parport_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf,
> +					   unsigned int buflen, int rw)
> +{
> +	struct ata_port *ap = qc->dev->link->ap;
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	if (rw == READ)
> +		pi->proto->read_block(pi, buf, buflen);
> +	else
> +		pi->proto->write_block(pi, buf, buflen);
> +	pi_disconnect_later(pi);
> +
> +	return buflen;
> +}
> +
> +static void pata_parport_drain_fifo(struct ata_queued_cmd *qc)
> +{
> +	int count;
> +	struct ata_port *ap;
> +	struct pi_adapter *pi;
> +	char junk[2];
> +
> +	/* We only need to flush incoming data when a command was running */
> +	if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
> +		return;
> +
> +	ap = qc->ap;
> +	pi = ap->host->private_data;
> +	/* Drain up to 64K of data before we give up this recovery method */
> +	for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
> +						&& count < 65536; count += 2) {
> +		pi_connect(pi);
> +		pi->proto->read_block(pi, junk, 2);
> +		pi_disconnect_later(pi);
> +	}
> +
> +	if (count)
> +		ata_port_dbg(ap, "drained %d bytes to clear DRQ\n", count);
> +}
> +
> +static void pata_parport_lost_interrupt(struct ata_port *ap)
> +{
> +	u8 status;
> +	struct ata_queued_cmd *qc;
> +
> +	/* Only one outstanding command per SFF channel */
> +	qc = ata_qc_from_tag(ap, ap->link.active_tag);
> +	/* We cannot lose an interrupt on a non-existent or polled command */
> +	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
> +		return;
> +	/* See if the controller thinks it is still busy - if so the command
> +	   isn't a lost IRQ but is still in progress */

Please use multi-line comment style:

/*
 * See if...
 * ...
 */

> +	status = pata_parport_check_altstatus(ap);
> +	if (status & ATA_BUSY)
> +		return;
> +
> +	/* There was a command running, we are no longer busy and we have
> +	   no interrupt. */

same

> +	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
> +	/* Run the host interrupt logic as if the interrupt had not been lost */
> +	ata_sff_port_intr(ap, qc);
> +}
> +
> +static struct ata_port_operations pata_parport_port_ops = {
> +	.qc_prep		= ata_noop_qc_prep,
> +	.qc_issue		= ata_sff_qc_issue,
> +	.qc_fill_rtf		= ata_sff_qc_fill_rtf,
> +
> +	.freeze			= ata_sff_freeze,
> +	.thaw			= ata_sff_thaw,
> +	.prereset		= ata_sff_prereset,
> +	.softreset		= pata_parport_softreset,
> +	.postreset		= ata_sff_postreset,
> +	.error_handler		= ata_sff_error_handler,
> +	.sched_eh		= ata_std_sched_eh,
> +	.end_eh			= ata_std_end_eh,
> +
> +	.sff_dev_select		= pata_parport_dev_select,
> +	.sff_check_status	= pata_parport_check_status,
> +	.sff_check_altstatus	= pata_parport_check_altstatus,
> +	.sff_tf_load		= pata_parport_tf_load,
> +	.sff_tf_read		= pata_parport_tf_read,
> +	.sff_exec_command	= pata_parport_exec_command,
> +	.sff_data_xfer		= pata_parport_data_xfer,
> +	.sff_drain_fifo		= pata_parport_drain_fifo,
> +
> +	.lost_interrupt		= pata_parport_lost_interrupt,
> +};
> +
> +static const struct ata_port_info pata_parport_port_info = {
> +	.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_POLLING,
> +	.pio_mask	= ATA_PIO0,
> +	/* No DMA */
> +	.port_ops	= &pata_parport_port_ops,
> +};
> +
> +void pi_release(struct pi_adapter *pi)
> +{
> +	parport_unregister_device(pi->pardev);
> +	if (pi->proto->release_proto)
> +		pi->proto->release_proto(pi);
> +	module_put(pi->proto->owner);
> +}
> +
> +static int default_test_proto(struct pi_adapter *pi, char *scratch)
> +{
> +	int j, k;
> +	int e[2] = { 0, 0 };
> +
> +	pi->proto->connect(pi);
> +
> +	for (j = 0; j < 2; j++) {
> +		pi->proto->write_regr(pi, 0, 6, 0xa0 + j * 0x10);
> +		for (k = 0; k < 256; k++) {
> +			pi->proto->write_regr(pi, 0, 2, k ^ 0xaa);
> +			pi->proto->write_regr(pi, 0, 3, k ^ 0x55);
> +			if (pi->proto->read_regr(pi, 0, 2) != (k ^ 0xaa))
> +				e[j]++;
> +		}
> +	}
> +	pi->proto->disconnect(pi);
> +
> +	if (verbose)
> +		dev_info(&pi->dev, "%s: port 0x%x, mode  %d, test=(%d,%d)\n",
> +		       pi->proto->name, pi->port,
> +		       pi->mode, e[0], e[1]);
> +
> +	return (e[0] && e[1]);	/* not here if both > 0 */
> +}
> +
> +static int pi_test_proto(struct pi_adapter *pi, char *scratch)
> +{
> +	int res;
> +
> +	parport_claim_or_block(pi->pardev);
> +	if (pi->proto->test_proto)
> +		res = pi->proto->test_proto(pi, scratch, verbose);
> +	else
> +		res = default_test_proto(pi, scratch);
> +	parport_release(pi->pardev);
> +
> +	return res;
> +}
> +
> +static int pi_probe_mode(struct pi_adapter *pi, int max, char *scratch)
> +{
> +	int best, range;
> +
> +	if (pi->mode != -1) {
> +		if (pi->mode >= max)
> +			return 0;
> +		range = 3;
> +		if (pi->mode >= pi->proto->epp_first)
> +			range = 8;
> +		if ((range == 8) && (pi->port % 8))

extra internal parenthesis not needed.

> +			return 0;
> +		return (!pi_test_proto(pi, scratch));
> +	}
> +	best = -1;
> +	for (pi->mode = 0; pi->mode < max; pi->mode++) {
> +		range = 3;
> +		if (pi->mode >= pi->proto->epp_first)
> +			range = 8;
> +		if ((range == 8) && (pi->port % 8))

same

> +			break;
> +		if (!pi_test_proto(pi, scratch))
> +			best = pi->mode;
> +	}
> +	pi->mode = best;
> +	return (best > -1);

same

> +}
> +
> +
> +static int pi_probe_unit(struct pi_adapter *pi, int unit, char *scratch)
> +{
> +	int max, s, e;
> +
> +	s = unit;
> +	e = s + 1;
> +
> +	if (s == -1) {
> +		s = 0;
> +		e = pi->proto->max_units;
> +	}
> +
> +	if (pi->proto->test_port) {
> +		parport_claim_or_block(pi->pardev);
> +		max = pi->proto->test_port(pi);
> +		parport_release(pi->pardev);
> +	} else
> +		max = pi->proto->max_mode;

Please add curly bracket for the else too.

> +
> +	if (pi->proto->probe_unit) {
> +		parport_claim_or_block(pi->pardev);
> +		for (pi->unit = s; pi->unit < e; pi->unit++)
> +			if (pi->proto->probe_unit(pi)) {
> +				parport_release(pi->pardev);
> +				if (pi_probe_mode(pi, max, scratch))
> +					return 1;
> +				return 0;
> +			}

Please add curly bracket for the for too. Technically not needed, but
since the "if" is over multiple lines, this will make the code more
readable (I had to recheck why the following parport_release() call was
indented like this...).

> +		parport_release(pi->pardev);
> +		return 0;
> +	}
> +
> +	if (!pi_probe_mode(pi, max, scratch))
> +		return 0;
> +	return 1;

return pi_probe_mode(pi, max, scratch); ?

> +}
> +
> +static void pata_parport_dev_release(struct device *dev)
> +{
> +	struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
> +
> +	kfree(pi);
> +}
> +
> +void pata_parport_bus_release(struct device *dev)
> +{
> +	/* nothing to do here but required to avoid warning on device removal */
> +}
> +
> +static struct bus_type pata_parport_bus_type = {
> +	.name = DRV_NAME,
> +};
> +
> +static struct device pata_parport_bus = {
> +	.init_name = DRV_NAME,
> +	.release = pata_parport_bus_release,
> +};
> +
> +struct pi_adapter *pi_init_one(struct parport *parport, struct pi_protocol *pr,
> +			       int mode, int unit, int delay)
> +{
> +	struct pardev_cb par_cb = { };
> +	char scratch[512];
> +	const struct ata_port_info *ppi[] = { &pata_parport_port_info };
> +	struct ata_host *host;
> +	struct pi_adapter *pi = kzalloc(sizeof(struct pi_adapter), GFP_KERNEL);

I would prefer hainving the pi = kzalloc() initialization right above
the "if (!pi)" below.

> +
> +	if (!pi)
> +		return NULL;
> +
> +	/* set up pi->dev before pi_probe_unit() so it can use dev_printk() */
> +	pi->dev.parent = &pata_parport_bus;
> +	pi->dev.bus = &pata_parport_bus_type;
> +	pi->dev.driver = &pr->driver;
> +	pi->dev.release = pata_parport_dev_release;
> +	pi->dev.id = ida_alloc(&pata_parport_bus_dev_ids, GFP_KERNEL);
> +	if (pi->dev.id < 0)
> +		return NULL; /* pata_parport_dev_release will do kfree(pi) */
> +	dev_set_name(&pi->dev, "pata_parport.%u", pi->dev.id);
> +	if (device_register(&pi->dev)) {
> +		put_device(&pi->dev);
> +		goto out_ida_free;
> +	}
> +
> +	pi->proto = pr;
> +
> +	/* still racy */

What is racy ?

> +	if (!try_module_get(pi->proto->owner))
> +		goto out_unreg_dev;
> +	if (pi->proto->init_proto && pi->proto->init_proto(pi) < 0)
> +		goto out_module_put;
> +
> +	pi->delay = (delay == -1) ? pi->proto->default_delay : delay;
> +	pi->mode = mode;
> +	pi->port = parport->base;
> +
> +	par_cb.private = pi;
> +	pi->pardev = parport_register_dev_model(parport, dev_name(&pi->dev),
> +						&par_cb, pi->dev.id);
> +	if (!pi->pardev)
> +		goto out_module_put;
> +
> +	if (!pi_probe_unit(pi, unit, scratch)) {
> +		dev_info(&pi->dev, "Adapter not found\n");
> +		goto out_unreg_parport;
> +	}
> +
> +	pi->proto->log_adapter(pi, scratch, verbose);
> +
> +	host = ata_host_alloc_pinfo(&pi->dev, ppi, 1);
> +	if (!host)
> +		goto out_unreg_parport;
> +	dev_set_drvdata(&pi->dev, host);
> +	host->private_data = pi;
> +
> +	ata_port_desc(host->ports[0], "port %s", pi->pardev->port->name);
> +	ata_port_desc(host->ports[0], "protocol %s", pi->proto->name);
> +
> +	timer_setup(&pi->timer, pi_disconnect_timer, 0);
> +
> +	if (ata_host_activate(host, 0, NULL, 0, &pi->proto->sht))
> +		goto out_unreg_parport;
> +
> +	return pi;
> +
> +out_unreg_parport:
> +	parport_unregister_device(pi->pardev);
> +	if (pi->proto->release_proto)
> +		pi->proto->release_proto(pi);
> +out_module_put:
> +	module_put(pi->proto->owner);
> +out_unreg_dev:
> +	device_unregister(&pi->dev);
> +out_ida_free:
> +	ida_free(&pata_parport_bus_dev_ids, pi->dev.id);
> +	return NULL;
> +}
> +
> +int pata_parport_register_driver(struct pi_protocol *pr)
> +{
> +	int error;
> +	struct parport *parport;
> +	int port_num;
> +
> +	pr->driver.bus = &pata_parport_bus_type;
> +	pr->driver.name = pr->name;
> +	error = driver_register(&pr->driver);
> +	if (error)
> +		return error;
> +
> +	mutex_lock(&pi_mutex);
> +	error = idr_alloc(&protocols, pr, 0, 0, GFP_KERNEL);
> +	if (error < 0) {
> +		driver_unregister(&pr->driver);
> +		mutex_unlock(&pi_mutex);
> +		return error;
> +	}
> +
> +	pr_info("pata_parport: protocol %s registered\n", pr->name);
> +
> +	if (probe)	/* probe all parports using this protocol */

Please move the comment inside the if and use curly brackets for the if
since its statement is multi-line.

> +		idr_for_each_entry(&parport_list, parport, port_num)
> +			pi_init_one(parport, pr, -1, 0, -1);
> +	mutex_unlock(&pi_mutex);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(pata_parport_register_driver);
> +
> +void pata_parport_unregister_driver(struct pi_protocol *pr)
> +{
> +	struct pi_protocol *pr_iter;
> +	int id = -1;
> +
> +	mutex_lock(&pi_mutex);
> +	idr_for_each_entry(&protocols, pr_iter, id)

Add curly brackets.

> +		if (pr_iter == pr)
> +			break;
> +	idr_remove(&protocols, id);
> +	mutex_unlock(&pi_mutex);
> +	pr_info("pata_parport: protocol %s removed\n", pr->name);

I do not think this message is needed.

> +	driver_unregister(&pr->driver);
> +}
> +EXPORT_SYMBOL(pata_parport_unregister_driver);
> +
> +static ssize_t new_device_store(struct bus_type *bus, const char *buf, size_t count)
> +{
> +	char port[12] = "auto";
> +	char protocol[8] = "auto";
> +	int mode = -1, unit = -1, delay = -1;
> +	struct pi_protocol *pr, *pr_wanted;
> +	struct device_driver *drv;
> +	struct parport *parport;
> +	int port_num, port_wanted, pr_num;
> +	bool ok = false;
> +
> +	if (sscanf(buf, "%11s %7s %d %d %d",
> +			port, protocol, &mode, &unit, &delay) < 1)
> +		return -EINVAL;
> +
> +	if (sscanf(port, "parport%u", &port_wanted) < 1) {
> +		if (!strcmp(port, "auto"))

Curly brackets please.
> +			port_wanted = -1;
> +		else {
> +			pr_err("invalid port name %s\n", port);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	drv = driver_find(protocol, &pata_parport_bus_type);
> +	if (!drv) {
> +		if (!strcmp(protocol, "auto"))
> +			pr_wanted = NULL;

same.

> +		else {
> +			pr_err("protocol %s not found\n", protocol);
> +			return -EINVAL;
> +		}
> +	} else
> +		pr_wanted = container_of(drv, struct pi_protocol, driver);

Here too.

> +
> +	mutex_lock(&pi_mutex);
> +	/* walk all parports */
> +	idr_for_each_entry(&parport_list, parport, port_num) {
> +		if (port_num == port_wanted || port_wanted == -1) {
> +			parport = parport_find_number(port_num);
> +			if (!parport) {
> +				pr_err("no such port %s\n", port);
> +				mutex_unlock(&pi_mutex);
> +				return -ENODEV;
> +			}
> +			/* walk all protocols */
> +			idr_for_each_entry(&protocols, pr, pr_num)

Add curly brackets to this one too.

> +				if (pr == pr_wanted || !pr_wanted)
> +					if (pi_init_one(parport, pr, mode, unit,
> +							delay))
> +						ok = true;
> +			parport_put_port(parport);
> +		}
> +	}
> +	mutex_unlock(&pi_mutex);
> +	if (!ok)
> +		return -ENODEV;
> +
> +	return count;
> +}
> +static BUS_ATTR_WO(new_device);
> +
> +static void pi_remove_one(struct device *dev)
> +{
> +	struct ata_host *host = dev_get_drvdata(dev);
> +	struct pi_adapter *pi = host->private_data;
> +
> +	ata_host_detach(host);
> +	del_timer_sync(&pi->timer);
> +	pi_release(pi);
> +	device_unregister(dev);
> +	ida_free(&pata_parport_bus_dev_ids, dev->id);
> +	/* pata_parport_dev_release will do kfree(pi) */
> +}
> +
> +static ssize_t delete_device_store(struct bus_type *bus, const char *buf, size_t count)
> +{
> +	struct device *dev;
> +	char device_name[32];
> +	int fields;
> +
> +	fields = sscanf(buf, "%31s", device_name);
> +	if (fields < 1)
> +		return -EINVAL;
> +
> +	mutex_lock(&pi_mutex);
> +	dev = bus_find_device_by_name(bus, NULL, device_name);
> +	if (!dev) {
> +		mutex_unlock(&pi_mutex);
> +		return -ENODEV;
> +	}
> +
> +	pi_remove_one(dev);
> +	mutex_unlock(&pi_mutex);
> +
> +	return count;
> +}
> +static BUS_ATTR_WO(delete_device);
> +
> +static void pata_parport_attach(struct parport *port)
> +{
> +	struct pi_protocol *pr;
> +	int pr_num, id;
> +
> +	mutex_lock(&pi_mutex);
> +	id = idr_alloc(&parport_list, port, port->number, port->number, GFP_KERNEL);
> +	if (id < 0) {
> +		mutex_unlock(&pi_mutex);
> +		return;
> +	}
> +
> +	if (probe) /* probe this port using all protocols */
> +		idr_for_each_entry(&protocols, pr, pr_num)
> +			pi_init_one(port, pr, -1, 0, -1);

Curly brackets and comment under the if.

> +	mutex_unlock(&pi_mutex);
> +}
> +
> +static int pi_remove_port(struct device *dev, void *p)
> +{
> +	struct ata_host *host = dev_get_drvdata(dev);
> +	struct pi_adapter *pi = host->private_data;
> +
> +	if (pi->pardev->port == p)
> +		pi_remove_one(dev);
> +
> +	return 0;
> +}
> +
> +static void pata_parport_detach(struct parport *port)
> +{
> +	mutex_lock(&pi_mutex);
> +	bus_for_each_dev(&pata_parport_bus_type, NULL, port, pi_remove_port);
> +	idr_remove(&parport_list, port->number);
> +	mutex_unlock(&pi_mutex);
> +}
> +
> +static struct parport_driver pata_parport_driver = {
> +	.name = DRV_NAME,
> +	.match_port = pata_parport_attach,
> +	.detach = pata_parport_detach,
> +	.devmodel = true,
> +};
> +
> +static __init int pata_parport_init(void)
> +{
> +	int error;
> +
> +	error = bus_register(&pata_parport_bus_type);
> +	if (error) {
> +		pr_err("failed to register pata_parport bus, error: %d\n", error);
> +		return error;
> +	}
> +
> +	error = device_register(&pata_parport_bus);
> +	if (error) {
> +		pr_err("failed to register pata_parport bus, error: %d\n", error);
> +		return error;

Bug. This should not be here.

> +		goto out_unregister_bus;
> +	}
> +
> +	error = bus_create_file(&pata_parport_bus_type, &bus_attr_new_device);
> +	if (error) {
> +		pr_err("unable to create sysfs file, error: %d\n", error);
> +		goto out_unregister_dev;
> +	}
> +
> +	error = bus_create_file(&pata_parport_bus_type, &bus_attr_delete_device);
> +	if (error) {
> +		pr_err("unable to create sysfs file, error: %d\n", error);
> +		goto out_remove_new;
> +	}
> +
> +	error = parport_register_driver(&pata_parport_driver);
> +	if (error) {
> +		pr_err("unable to register parport driver, error: %d\n", error);
> +		goto out_remove_del;
> +	}
> +
> +	return 0;
> +
> +out_remove_del:
> +	bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
> +out_remove_new:
> +	bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
> +out_unregister_dev:
> +	device_unregister(&pata_parport_bus);
> +out_unregister_bus:
> +	bus_unregister(&pata_parport_bus_type);
> +	return error;
> +}
> +
> +static __exit void pata_parport_exit(void)
> +{
> +	parport_unregister_driver(&pata_parport_driver);
> +	bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
> +	bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
> +	device_unregister(&pata_parport_bus);
> +	bus_unregister(&pata_parport_bus_type);
> +}
> +
> +MODULE_AUTHOR("Ondrej Zary");
> +MODULE_DESCRIPTION("driver for parallel port ATA adapters");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("paride");
> +
> +module_init(pata_parport_init);
> +module_exit(pata_parport_exit);
> diff --git a/drivers/ata/pata_parport/pata_parport.h b/drivers/ata/pata_parport/pata_parport.h
> new file mode 100644
> index 000000000000..c4201b809b20
> --- /dev/null
> +++ b/drivers/ata/pata_parport/pata_parport.h
> @@ -0,0 +1,110 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + *	paride.h	(c) 1997-8  Grant R. Guenther <grant at torque.net>
> + *				    Under the terms of the GPL.
> + *
> + * This file defines the interface for adapter chip drivers.

Which adapter ? "Parallel port IDE adapter chip", no ?

> + */
> +
> +#include <linux/libata.h>
> +
> +struct pi_adapter {
> +	struct device dev;
> +	struct pi_protocol *proto;	/* adapter protocol */
> +	int port;			/* base address of parallel port */
> +	int mode;			/* transfer mode in use */
> +	int delay;			/* adapter delay setting */
> +	int unit;			/* unit number for chained adapters */
> +	int saved_r0;			/* saved port state */
> +	int saved_r2;			/* saved port state */
> +	unsigned long private;		/* for protocol module */
> +	struct pardevice *pardev;	/* pointer to pardevice */
> +	int claimed;			/* parport has already been claimed */

Make this a bool ?

> +	struct timer_list timer;	/* disconnect timer */
> +};
> +
> +/* registers are addressed as (cont,regr)
> + *	cont: 0 for command register file, 1 for control register(s)
> + *	regr: 0-7 for register number.
> + */
> +
> +/* macros and functions exported to the protocol modules */
> +#define delay_p			(pi->delay ? udelay(pi->delay) : (void)0)
> +#define out_p(offs, byte)	do { outb(byte, pi->port + offs); delay_p; } while (0)
> +#define in_p(offs)		(delay_p, inb(pi->port + offs))
> +
> +#define w0(byte)		out_p(0, byte)
> +#define r0()			(in_p(0) & 0xff)
> +#define w1(byte)		out_p(1, byte)
> +#define r1()			(in_p(1) & 0xff)
> +#define w2(byte)		out_p(2, byte)
> +#define r2()			(in_p(2) & 0xff)
> +#define w3(byte)		out_p(3, byte)
> +#define w4(byte)		out_p(4, byte)
> +#define r4()			(in_p(4) & 0xff)
> +#define w4w(data)		do { outw(data, pi->port + 4); delay_p; } while (0)
> +#define w4l(data)		do { outl(data, pi->port + 4); delay_p; } while (0)
> +#define r4w()			(delay_p, inw(pi->port + 4) & 0xffff)
> +#define r4l()			(delay_p, inl(pi->port + 4) & 0xffffffff)

Why not align this with the others ?

> +
> +static inline u16 pi_swab16(char *b, int k)
> +{
> +	union { u16 u; char t[2]; } r;
> +
> +	r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k];
> +	return r.u;
> +}
> +
> +static inline u32 pi_swab32(char *b, int k)
> +{
> +	union { u32 u; char f[4]; } r;
> +
> +	r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k];
> +	r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2];
> +	return r.u;
> +}
> +
> +struct pi_protocol {
> +	char name[8];		/* name for this protocol */
> +
> +	int max_mode;		/* max mode number */
> +	int epp_first;		/* modes >= this use 8 ports */
> +
> +	int default_delay;	/* delay parameter if not specified */
> +	int max_units;		/* max chained units probed for */

Except maybe epp_first, I find the comments for these fields useless: no
information added.

> +
> +	void (*write_regr)(struct pi_adapter *pi, int cont, int regr, int val);
> +	int (*read_regr)(struct pi_adapter *pi, int cont, int regr);
> +	void (*write_block)(struct pi_adapter *pi, char *buf, int count);
> +	void (*read_block)(struct pi_adapter *pi, char *buf, int count);
> +
> +	void (*connect)(struct pi_adapter *pi);
> +	void (*disconnect)(struct pi_adapter *pi);
> +
> +	int (*test_port)(struct pi_adapter *pi);
> +	int (*probe_unit)(struct pi_adapter *pi);
> +	int (*test_proto)(struct pi_adapter *pi, char *scratch, int verbose);
> +	void (*log_adapter)(struct pi_adapter *pi, char *scratch, int verbose);
> +
> +	int (*init_proto)(struct pi_adapter *pi);
> +	void (*release_proto)(struct pi_adapter *pi);
> +	struct module *owner;
> +	struct device_driver driver;
> +	struct scsi_host_template sht;
> +};
> +
> +#define PATA_PARPORT_SHT ATA_PIO_SHT
> +
> +extern int pata_parport_register_driver(struct pi_protocol *pr);
> +extern void pata_parport_unregister_driver(struct pi_protocol *pr);

No need for extern.

> +
> +/**
> + * module_pata_parport_driver() - Helper macro for registering a pata_parport driver
> + * @__pi_protocol: pi_protocol struct
> + *
> + * Helper macro for pata_parport drivers which do not do anything special in module
> + * init/exit. This eliminates a lot of boilerplate. Each module may only
> + * use this macro once, and calling it replaces module_init() and module_exit()
> + */
> +#define module_pata_parport_driver(__pi_protocol) \
> +	module_driver(__pi_protocol, pata_parport_register_driver, pata_parport_unregister_driver)

Make this a static inline ?

-- 
Damien Le Moal
Western Digital Research


From linux at zary.sk  Mon Mar  7 00:55:05 2022
From: linux at zary.sk (Ondrej Zary)
Date: Mon, 7 Mar 2022 09:55:05 +0100
Subject: [Linux-parport] [PATCH 01/16] pata_parport: add core driver
 (PARIDE replacement)
In-Reply-To: <2a79b7ac-6648-7855-fcfa-de0800c9a310@opensource.wdc.com>
References: <20220305201411.501-1-linux@zary.sk>
 <20220305201411.501-2-linux@zary.sk>
 <2a79b7ac-6648-7855-fcfa-de0800c9a310@opensource.wdc.com>
Message-ID: <202203070955.05800.linux@zary.sk>

On Monday 07 March 2022, Damien Le Moal wrote:
> On 3/6/22 05:13, Ondrej Zary wrote:
> > Add pata_parport (PARIDE replacement) core libata driver.
> > 
> > Signed-off-by: Ondrej Zary <linux at zary.sk>
> > ---
> >  drivers/ata/Kconfig                     |  25 +
> >  drivers/ata/Makefile                    |   2 +
> >  drivers/ata/pata_parport/Kconfig        |  10 +
> >  drivers/ata/pata_parport/Makefile       |   9 +
> >  drivers/ata/pata_parport/pata_parport.c | 809 ++++++++++++++++++++++++
> >  drivers/ata/pata_parport/pata_parport.h | 110 ++++
> >  6 files changed, 965 insertions(+)
> >  create mode 100644 drivers/ata/pata_parport/Kconfig
> >  create mode 100644 drivers/ata/pata_parport/Makefile
> >  create mode 100644 drivers/ata/pata_parport/pata_parport.c
> >  create mode 100644 drivers/ata/pata_parport/pata_parport.h
> > 
> > diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
> > index cb54631fd950..de4548471398 100644
> > --- a/drivers/ata/Kconfig
> > +++ b/drivers/ata/Kconfig
> > @@ -1161,6 +1161,31 @@ config PATA_WINBOND_VLB
> >  	  Support for the Winbond W83759A controller on Vesa Local Bus
> >  	  systems.
> >  
> > +config PATA_PARPORT
> > +	tristate "Parallel port IDE device support (PARIDE replacement)"
> 
> I would remove the "(PARIDE replacement)" from the title. If really
> needed, mention it in the description that this support used to be
> implemented by PARIDE. But I do not think that is necessary. The last
> paragraph of the description implies that.
> 
> > +	depends on PARPORT_PC
> > +	help
> > +	  There are many external CD-ROM and disk devices that connect through
> > +	  your computer's parallel port. Most of them are actually IDE devices
> > +	  using a parallel port IDE adapter. This option enables the PATA_PARPORT
> > +	  subsystem which contains drivers for many of these external drives.
> > +	  Read <file:Documentation/admin-guide/blockdev/paride.rst> for more information.
> > +
> > +	  If you have said Y to the "Parallel-port support" configuration
> > +	  option, you may share a single port between your printer and other
> > +	  parallel port devices. Answer Y to build PATA_PARPORT support into your
> > +	  kernel, or M if you would like to build it as a loadable module. If
> > +	  your parallel port support is in a loadable module, you must build
> > +	  PATA_PARPORT as a module. If you built PATA_PARPORT support into your kernel,
> > +	  you may still build the individual protocol modules as loadable
> > +	  modules. If you build this support as a module, it will be called pata_parport.
> > +
> > +	  Unlike the old PARIDE, there are no high-level drivers needed.
> > +	  The IDE devices behind parallel port adapters are handled by the
> > +	  ATA layer.
> 
> Several lines are too long. Rewrap please.
> 
> > +
> > +source "drivers/ata/pata_parport/Kconfig"
> > +
> >  comment "Generic fallback / legacy drivers"
> >  
> >  config PATA_ACPI
> > diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
> > index b8aebfb14e82..bd6b5fdc004e 100644
> > --- a/drivers/ata/Makefile
> > +++ b/drivers/ata/Makefile
> > @@ -114,6 +114,8 @@ obj-$(CONFIG_PATA_SAMSUNG_CF)	+= pata_samsung_cf.o
> >  
> >  obj-$(CONFIG_PATA_PXA)		+= pata_pxa.o
> >  
> > +obj-$(CONFIG_PATA_PARPORT)	+= pata_parport/
> > +
> >  # Should be last but two libata driver
> >  obj-$(CONFIG_PATA_ACPI)		+= pata_acpi.o
> >  # Should be last but one libata driver
> > diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
> > new file mode 100644
> > index 000000000000..56dc6b25d5fa
> > --- /dev/null
> > +++ b/drivers/ata/pata_parport/Kconfig
> > @@ -0,0 +1,10 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +#
> > +# PATA_PARPORT configuration
> > +#
> > +# PATA_PARPORT doesn't need PARPORT, but if PARPORT is configured as a module,
> > +# PATA_PARPORT must also be a module.
> 
> This does not parse. If PARPORT is not needed, then why does how PARPORT
> is compiled matter ? Something is not consistent here.
> 
> > +# PATA_PARPORT only supports PC style parports. Tough for USB or other parports...
> 
> The second sentence does not parse. What are you trying to say ?

It's copied from paride.

> > +
> > +comment "Parallel IDE protocol modules"
> > +	depends on PATA_PARPORT
> > diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
> > new file mode 100644
> > index 000000000000..b105e1cb8dc6
> > --- /dev/null
> > +++ b/drivers/ata/pata_parport/Makefile
> > @@ -0,0 +1,9 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +#
> > +# Makefile for Parallel port IDE device drivers.
> > +#
> > +# 7 October 2000, Bartlomiej Zolnierkiewicz <bkz at linux-ide.org>
> > +# Rewritten to use lists instead of if-statements.
> > +#
> > +
> > +obj-$(CONFIG_PATA_PARPORT)		+= pata_parport.o
> > diff --git a/drivers/ata/pata_parport/pata_parport.c b/drivers/ata/pata_parport/pata_parport.c
> > new file mode 100644
> > index 000000000000..7f814062cedd
> > --- /dev/null
> > +++ b/drivers/ata/pata_parport/pata_parport.c
> > @@ -0,0 +1,809 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/parport.h>
> > +#include "pata_parport.h"
> > +
> > +#define DRV_NAME "pata_parport"
> > +
> > +static DEFINE_IDR(parport_list);
> > +static DEFINE_IDR(protocols);
> > +static DEFINE_IDA(pata_parport_bus_dev_ids);
> > +static DEFINE_MUTEX(pi_mutex);
> > +
> > +static bool probe = 1;
> 
> s/1/true to match the type.
> 
> > +module_param(probe, bool, 0644);
> > +MODULE_PARM_DESC(probe, "Enable automatic device probing (0=off, 1=on [default])");
> > +
> > +static bool verbose;
> > +module_param(verbose, bool, 0644);
> > +MODULE_PARM_DESC(verbose, "Enable verbose messages (0=off [default], 1=on)");
> 
> Is this really necessary ? pr_debug() and all ata_xxx_debug() functions
> can be enabled dynamically.

The verbose messages are for adapter chip detection. That happens before the
ata host is registered.

> > +
> > +#define DISCONNECT_TIMEOUT	(HZ / 10)
> > +
> > +static void pi_connect(struct pi_adapter *pi)
> > +{
> > +	del_timer_sync(&pi->timer);
> > +	if (pi->claimed)
> > +		return;
> 
> Nit: I would reverse the condition to avoid the return. Or add a block
> line to separate the following hunk. Better readability this way, I think.
> 
> > +	pi->claimed = 1;
> > +	parport_claim_or_block(pi->pardev);
> > +	pi->proto->connect(pi);
> > +}
> > +
> > +static void pi_disconnect_later(struct pi_adapter *pi)
> > +{
> > +	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
> > +}
> 
> Is this really needed ? Not sure it helps in any way. At least the name
> should be changed to reflect what this does. May be something like
> pi_start_disconnect_timeout() ?

Disconnect needs to happen after end of an operation so the parport is freed
for device(s) (like a printer) connected to pass-through port of a paride
device. There could be even multiple paride devices chained on one parport.

Disconnecting immediately at the end of each function does not work
(probably breaks the protocol?)

The old high-level drivers (pd, pf...) did connect and disconnect manually
on each operation (command or data transfer) but it does not seem to be
possible with libata.

> > +
> > +static void pi_disconnect_timer(struct timer_list *t)
> > +{
> > +	struct pi_adapter *pi = from_timer(pi, t, timer);
> > +
> > +	if (!pi->claimed)
> > +		return;
> 
> A blank line here would be nice for readability.
> 
> > +	pi->proto->disconnect(pi);
> > +	parport_release(pi->pardev);
> > +	pi->claimed = 0;
> > +}
> > +
> > +/* functions taken from libata-sff.c and converted from direct port I/O */
> > +static unsigned int pata_parport_devchk(struct ata_port *ap, unsigned int device)
> 
> Should this be a bool function ?

I don't know. It's copied from libata-sff.c
 
> > +{
> > +	struct pi_adapter *pi = ap->host->private_data;
> > +	u8 nsect, lbal;
> > +
> > +	ap->ops->sff_dev_select(ap, device);
> > +
> > +	pi_connect(pi);
> > +	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0x55);
> > +	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
> > +
> > +	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0xaa);
> > +	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0x55);
> > +
> > +	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 055);
> > +	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
> > +
> > +	nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
> > +	lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
> > +	pi_disconnect_later(pi);
> > +
> > +	if ((nsect == 0x55) && (lbal == 0xaa))
> > +		return 1;	/* we found a device */
> > +
> > +	return 0;		/* nothing found */
> > +}
> > +
> > +static int pata_parport_bus_softreset(struct ata_port *ap, unsigned int devmask,
> > +				      unsigned long deadline)
> > +{
> > +	struct pi_adapter *pi = ap->host->private_data;
> > +
> > +	pi_connect(pi);
> > +	/* software reset.  causes dev0 to be selected */
> > +	pi->proto->write_regr(pi, 1, 6, ap->ctl);
> > +	udelay(20);	/* FIXME: flush */
> 
> Then please fix it.

I don't know what that means. It's copied from libata-sff.c

> > +	pi->proto->write_regr(pi, 1, 6, ap->ctl | ATA_SRST);
> > +	udelay(20);	/* FIXME: flush */
> 
> Here too.
> 
> > +	pi->proto->write_regr(pi, 1, 6, ap->ctl);
> > +	ap->last_ctl = ap->ctl;
> > +	pi_disconnect_later(pi);
> > +
> > +	/* wait the port to become ready */
> > +	return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
> > +}
> > +
> > +static int pata_parport_softreset(struct ata_link *link, unsigned int *classes,
> > +				  unsigned long deadline)
> > +{
> > +	struct ata_port *ap = link->ap;
> > +	unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
> > +	unsigned int devmask = 0;
> > +	int rc;
> > +	u8 err;
> > +
> > +	/* determine if device 0/1 are present */
> > +	if (pata_parport_devchk(ap, 0))
> > +		devmask |= (1 << 0);
> > +	if (slave_possible && pata_parport_devchk(ap, 1))
> > +		devmask |= (1 << 1);
> > +
> > +	/* select device 0 again */
> > +	ap->ops->sff_dev_select(ap, 0);
> > +
> > +	/* issue bus reset */
> > +	rc = pata_parport_bus_softreset(ap, devmask, deadline);
> > +	/* if link is occupied, -ENODEV too is an error */
> 
> Please merge this comment with the one above. That will make the code
> more readable (I know this is the style used by many drivers, but let's
> not repeat the weird style :)).
> 
> > +	if (rc && (rc != -ENODEV || sata_scr_valid(link))) {
> > +		ata_link_err(link, "SRST failed (errno=%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	/* determine by signature whether we have ATA or ATAPI devices */
> > +	classes[0] = ata_sff_dev_classify(&link->device[0],
> > +					  devmask & (1 << 0), &err);
> > +	if (slave_possible && err != 0x81)
> > +		classes[1] = ata_sff_dev_classify(&link->device[1],
> > +						  devmask & (1 << 1), &err);
> > +
> > +	return 0;
> > +}
> > +
> > +static u8 pata_parport_check_status(struct ata_port *ap)
> > +{
> > +	u8 status;
> > +	struct pi_adapter *pi = ap->host->private_data;
> > +
> > +	pi_connect(pi);
> > +	status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
> > +	pi_disconnect_later(pi);
> > +
> > +	return status;
> > +}
> > +
> > +static u8 pata_parport_check_altstatus(struct ata_port *ap)
> > +{
> > +	u8 altstatus;
> > +	struct pi_adapter *pi = ap->host->private_data;
> > +
> > +	pi_connect(pi);
> > +	altstatus = pi->proto->read_regr(pi, 1, 6);
> > +	pi_disconnect_later(pi);
> > +
> > +	return altstatus;
> > +}
> > +
> > +static void pata_parport_dev_select(struct ata_port *ap, unsigned int device)
> > +{
> > +	struct pi_adapter *pi = ap->host->private_data;
> > +	u8 tmp;
> > +
> > +	pi_connect(pi);
> > +	if (device == 0)
> > +		tmp = ATA_DEVICE_OBS;
> > +	else
> > +		tmp = ATA_DEVICE_OBS | ATA_DEV1;
> > +
> > +	pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tmp);
> > +	pi_disconnect_later(pi);
> > +	ata_sff_pause(ap);	/* needed; also flushes, for mmio */
> 
> The comment does not parse... Why is it needed ?
> And pleasde move the comment above the call, with a blank line
> separating it from the previous lines.

I don't know. It's copied from libata-sff.c

> > +}
> > +
> > +static void pata_parport_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
> > +{
> > +	struct pi_adapter *pi = ap->host->private_data;
> > +	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
> > +
> > +	pi_connect(pi);
> > +	if (tf->ctl != ap->last_ctl) {
> > +		pi->proto->write_regr(pi, 1, 6, tf->ctl);
> > +		ap->last_ctl = tf->ctl;
> > +		ata_wait_idle(ap);
> > +	}
> > +
> > +	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
> > +		pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->hob_feature);
> > +		pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->hob_nsect);
> > +		pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->hob_lbal);
> > +		pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->hob_lbam);
> > +		pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->hob_lbah);
> > +	}
> > +
> > +	if (is_addr) {
> 
> Move this if above the previous one. Doing so, you can remove the need
> for is_addr var and simplify the previous if condition.
> 
> That said, many pata drivers check that flag but it is always set by
> libata core. So checking it seems useless. Need to dig into this.

It's copied from libata-sff.c which is almost libata core.

> > +		pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->feature);
> > +		pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->nsect);
> > +		pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->lbal);
> > +		pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->lbam);
> > +		pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->lbah);
> > +	}
> > +
> > +	if (tf->flags & ATA_TFLAG_DEVICE)
> > +		pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tf->device);
> > +
> > +	ata_wait_idle(ap);
> > +	pi_disconnect_later(pi);
> > +}
> > +
> > +static void pata_parport_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
> > +{
> > +	struct pi_adapter *pi = ap->host->private_data;
> > +
> > +	pi_connect(pi);
> > +	tf->command = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
> > +	tf->feature = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
> > +	tf->nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
> > +	tf->lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
> > +	tf->lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
> > +	tf->lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
> > +	tf->device = pi->proto->read_regr(pi, 0, ATA_REG_DEVICE);
> > +
> > +	if (tf->flags & ATA_TFLAG_LBA48) {
> > +		pi->proto->write_regr(pi, 1, 6, tf->ctl | ATA_HOB);
> > +		tf->hob_feature = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
> > +		tf->hob_nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
> > +		tf->hob_lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
> > +		tf->hob_lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
> > +		tf->hob_lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
> > +		pi->proto->write_regr(pi, 1, 6, tf->ctl);
> > +		ap->last_ctl = tf->ctl;
> > +	}
> > +	pi_disconnect_later(pi);
> > +}
> > +
> > +static void pata_parport_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
> > +{
> > +	struct pi_adapter *pi = ap->host->private_data;
> > +
> > +	pi_connect(pi);
> > +	pi->proto->write_regr(pi, 0, ATA_REG_CMD, tf->command);
> > +	ata_sff_pause(ap);
> > +	pi_disconnect_later(pi);
> > +}
> > +
> > +static unsigned int pata_parport_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf,
> > +					   unsigned int buflen, int rw)
> > +{
> > +	struct ata_port *ap = qc->dev->link->ap;
> > +	struct pi_adapter *pi = ap->host->private_data;
> > +
> > +	pi_connect(pi);
> > +	if (rw == READ)
> > +		pi->proto->read_block(pi, buf, buflen);
> > +	else
> > +		pi->proto->write_block(pi, buf, buflen);
> > +	pi_disconnect_later(pi);
> > +
> > +	return buflen;
> > +}
> > +
> > +static void pata_parport_drain_fifo(struct ata_queued_cmd *qc)
> > +{
> > +	int count;
> > +	struct ata_port *ap;
> > +	struct pi_adapter *pi;
> > +	char junk[2];
> > +
> > +	/* We only need to flush incoming data when a command was running */
> > +	if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
> > +		return;
> > +
> > +	ap = qc->ap;
> > +	pi = ap->host->private_data;
> > +	/* Drain up to 64K of data before we give up this recovery method */
> > +	for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
> > +						&& count < 65536; count += 2) {
> > +		pi_connect(pi);
> > +		pi->proto->read_block(pi, junk, 2);
> > +		pi_disconnect_later(pi);
> > +	}
> > +
> > +	if (count)
> > +		ata_port_dbg(ap, "drained %d bytes to clear DRQ\n", count);
> > +}
> > +
> > +static void pata_parport_lost_interrupt(struct ata_port *ap)
> > +{
> > +	u8 status;
> > +	struct ata_queued_cmd *qc;
> > +
> > +	/* Only one outstanding command per SFF channel */
> > +	qc = ata_qc_from_tag(ap, ap->link.active_tag);
> > +	/* We cannot lose an interrupt on a non-existent or polled command */
> > +	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
> > +		return;
> > +	/* See if the controller thinks it is still busy - if so the command
> > +	   isn't a lost IRQ but is still in progress */
> 
> Please use multi-line comment style:
> 
> /*
>  * See if...
>  * ...
>  */
> 
> > +	status = pata_parport_check_altstatus(ap);
> > +	if (status & ATA_BUSY)
> > +		return;
> > +
> > +	/* There was a command running, we are no longer busy and we have
> > +	   no interrupt. */
> 
> same
> 
> > +	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
> > +	/* Run the host interrupt logic as if the interrupt had not been lost */
> > +	ata_sff_port_intr(ap, qc);
> > +}
> > +
> > +static struct ata_port_operations pata_parport_port_ops = {
> > +	.qc_prep		= ata_noop_qc_prep,
> > +	.qc_issue		= ata_sff_qc_issue,
> > +	.qc_fill_rtf		= ata_sff_qc_fill_rtf,
> > +
> > +	.freeze			= ata_sff_freeze,
> > +	.thaw			= ata_sff_thaw,
> > +	.prereset		= ata_sff_prereset,
> > +	.softreset		= pata_parport_softreset,
> > +	.postreset		= ata_sff_postreset,
> > +	.error_handler		= ata_sff_error_handler,
> > +	.sched_eh		= ata_std_sched_eh,
> > +	.end_eh			= ata_std_end_eh,
> > +
> > +	.sff_dev_select		= pata_parport_dev_select,
> > +	.sff_check_status	= pata_parport_check_status,
> > +	.sff_check_altstatus	= pata_parport_check_altstatus,
> > +	.sff_tf_load		= pata_parport_tf_load,
> > +	.sff_tf_read		= pata_parport_tf_read,
> > +	.sff_exec_command	= pata_parport_exec_command,
> > +	.sff_data_xfer		= pata_parport_data_xfer,
> > +	.sff_drain_fifo		= pata_parport_drain_fifo,
> > +
> > +	.lost_interrupt		= pata_parport_lost_interrupt,
> > +};
> > +
> > +static const struct ata_port_info pata_parport_port_info = {
> > +	.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_POLLING,
> > +	.pio_mask	= ATA_PIO0,
> > +	/* No DMA */
> > +	.port_ops	= &pata_parport_port_ops,
> > +};
> > +
> > +void pi_release(struct pi_adapter *pi)
> > +{
> > +	parport_unregister_device(pi->pardev);
> > +	if (pi->proto->release_proto)
> > +		pi->proto->release_proto(pi);
> > +	module_put(pi->proto->owner);
> > +}
> > +
> > +static int default_test_proto(struct pi_adapter *pi, char *scratch)
> > +{
> > +	int j, k;
> > +	int e[2] = { 0, 0 };
> > +
> > +	pi->proto->connect(pi);
> > +
> > +	for (j = 0; j < 2; j++) {
> > +		pi->proto->write_regr(pi, 0, 6, 0xa0 + j * 0x10);
> > +		for (k = 0; k < 256; k++) {
> > +			pi->proto->write_regr(pi, 0, 2, k ^ 0xaa);
> > +			pi->proto->write_regr(pi, 0, 3, k ^ 0x55);
> > +			if (pi->proto->read_regr(pi, 0, 2) != (k ^ 0xaa))
> > +				e[j]++;
> > +		}
> > +	}
> > +	pi->proto->disconnect(pi);
> > +
> > +	if (verbose)
> > +		dev_info(&pi->dev, "%s: port 0x%x, mode  %d, test=(%d,%d)\n",
> > +		       pi->proto->name, pi->port,
> > +		       pi->mode, e[0], e[1]);
> > +
> > +	return (e[0] && e[1]);	/* not here if both > 0 */
> > +}
> > +
> > +static int pi_test_proto(struct pi_adapter *pi, char *scratch)
> > +{
> > +	int res;
> > +
> > +	parport_claim_or_block(pi->pardev);
> > +	if (pi->proto->test_proto)
> > +		res = pi->proto->test_proto(pi, scratch, verbose);
> > +	else
> > +		res = default_test_proto(pi, scratch);
> > +	parport_release(pi->pardev);
> > +
> > +	return res;
> > +}
> > +
> > +static int pi_probe_mode(struct pi_adapter *pi, int max, char *scratch)
> > +{
> > +	int best, range;
> > +
> > +	if (pi->mode != -1) {
> > +		if (pi->mode >= max)
> > +			return 0;
> > +		range = 3;
> > +		if (pi->mode >= pi->proto->epp_first)
> > +			range = 8;
> > +		if ((range == 8) && (pi->port % 8))
> 
> extra internal parenthesis not needed.
> 
> > +			return 0;
> > +		return (!pi_test_proto(pi, scratch));
> > +	}
> > +	best = -1;
> > +	for (pi->mode = 0; pi->mode < max; pi->mode++) {
> > +		range = 3;
> > +		if (pi->mode >= pi->proto->epp_first)
> > +			range = 8;
> > +		if ((range == 8) && (pi->port % 8))
> 
> same
> 
> > +			break;
> > +		if (!pi_test_proto(pi, scratch))
> > +			best = pi->mode;
> > +	}
> > +	pi->mode = best;
> > +	return (best > -1);
> 
> same
> 
> > +}
> > +
> > +
> > +static int pi_probe_unit(struct pi_adapter *pi, int unit, char *scratch)
> > +{
> > +	int max, s, e;
> > +
> > +	s = unit;
> > +	e = s + 1;
> > +
> > +	if (s == -1) {
> > +		s = 0;
> > +		e = pi->proto->max_units;
> > +	}
> > +
> > +	if (pi->proto->test_port) {
> > +		parport_claim_or_block(pi->pardev);
> > +		max = pi->proto->test_port(pi);
> > +		parport_release(pi->pardev);
> > +	} else
> > +		max = pi->proto->max_mode;
> 
> Please add curly bracket for the else too.
> 
> > +
> > +	if (pi->proto->probe_unit) {
> > +		parport_claim_or_block(pi->pardev);
> > +		for (pi->unit = s; pi->unit < e; pi->unit++)
> > +			if (pi->proto->probe_unit(pi)) {
> > +				parport_release(pi->pardev);
> > +				if (pi_probe_mode(pi, max, scratch))
> > +					return 1;
> > +				return 0;
> > +			}
> 
> Please add curly bracket for the for too. Technically not needed, but
> since the "if" is over multiple lines, this will make the code more
> readable (I had to recheck why the following parport_release() call was
> indented like this...).
> 
> > +		parport_release(pi->pardev);
> > +		return 0;
> > +	}
> > +
> > +	if (!pi_probe_mode(pi, max, scratch))
> > +		return 0;
> > +	return 1;
> 
> return pi_probe_mode(pi, max, scratch); ?
> 
> > +}
> > +
> > +static void pata_parport_dev_release(struct device *dev)
> > +{
> > +	struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
> > +
> > +	kfree(pi);
> > +}
> > +
> > +void pata_parport_bus_release(struct device *dev)
> > +{
> > +	/* nothing to do here but required to avoid warning on device removal */
> > +}
> > +
> > +static struct bus_type pata_parport_bus_type = {
> > +	.name = DRV_NAME,
> > +};
> > +
> > +static struct device pata_parport_bus = {
> > +	.init_name = DRV_NAME,
> > +	.release = pata_parport_bus_release,
> > +};
> > +
> > +struct pi_adapter *pi_init_one(struct parport *parport, struct pi_protocol *pr,
> > +			       int mode, int unit, int delay)
> > +{
> > +	struct pardev_cb par_cb = { };
> > +	char scratch[512];
> > +	const struct ata_port_info *ppi[] = { &pata_parport_port_info };
> > +	struct ata_host *host;
> > +	struct pi_adapter *pi = kzalloc(sizeof(struct pi_adapter), GFP_KERNEL);
> 
> I would prefer hainving the pi = kzalloc() initialization right above
> the "if (!pi)" below.
> 
> > +
> > +	if (!pi)
> > +		return NULL;
> > +
> > +	/* set up pi->dev before pi_probe_unit() so it can use dev_printk() */
> > +	pi->dev.parent = &pata_parport_bus;
> > +	pi->dev.bus = &pata_parport_bus_type;
> > +	pi->dev.driver = &pr->driver;
> > +	pi->dev.release = pata_parport_dev_release;
> > +	pi->dev.id = ida_alloc(&pata_parport_bus_dev_ids, GFP_KERNEL);
> > +	if (pi->dev.id < 0)
> > +		return NULL; /* pata_parport_dev_release will do kfree(pi) */
> > +	dev_set_name(&pi->dev, "pata_parport.%u", pi->dev.id);
> > +	if (device_register(&pi->dev)) {
> > +		put_device(&pi->dev);
> > +		goto out_ida_free;
> > +	}
> > +
> > +	pi->proto = pr;
> > +
> > +	/* still racy */
> 
> What is racy ?

I don't know - the comment came from paride. I'll probably just delete it.

> > +	if (!try_module_get(pi->proto->owner))
> > +		goto out_unreg_dev;
> > +	if (pi->proto->init_proto && pi->proto->init_proto(pi) < 0)
> > +		goto out_module_put;
> > +
> > +	pi->delay = (delay == -1) ? pi->proto->default_delay : delay;
> > +	pi->mode = mode;
> > +	pi->port = parport->base;
> > +
> > +	par_cb.private = pi;
> > +	pi->pardev = parport_register_dev_model(parport, dev_name(&pi->dev),
> > +						&par_cb, pi->dev.id);
> > +	if (!pi->pardev)
> > +		goto out_module_put;
> > +
> > +	if (!pi_probe_unit(pi, unit, scratch)) {
> > +		dev_info(&pi->dev, "Adapter not found\n");
> > +		goto out_unreg_parport;
> > +	}
> > +
> > +	pi->proto->log_adapter(pi, scratch, verbose);
> > +
> > +	host = ata_host_alloc_pinfo(&pi->dev, ppi, 1);
> > +	if (!host)
> > +		goto out_unreg_parport;
> > +	dev_set_drvdata(&pi->dev, host);
> > +	host->private_data = pi;
> > +
> > +	ata_port_desc(host->ports[0], "port %s", pi->pardev->port->name);
> > +	ata_port_desc(host->ports[0], "protocol %s", pi->proto->name);
> > +
> > +	timer_setup(&pi->timer, pi_disconnect_timer, 0);
> > +
> > +	if (ata_host_activate(host, 0, NULL, 0, &pi->proto->sht))
> > +		goto out_unreg_parport;
> > +
> > +	return pi;
> > +
> > +out_unreg_parport:
> > +	parport_unregister_device(pi->pardev);
> > +	if (pi->proto->release_proto)
> > +		pi->proto->release_proto(pi);
> > +out_module_put:
> > +	module_put(pi->proto->owner);
> > +out_unreg_dev:
> > +	device_unregister(&pi->dev);
> > +out_ida_free:
> > +	ida_free(&pata_parport_bus_dev_ids, pi->dev.id);
> > +	return NULL;
> > +}
> > +
> > +int pata_parport_register_driver(struct pi_protocol *pr)
> > +{
> > +	int error;
> > +	struct parport *parport;
> > +	int port_num;
> > +
> > +	pr->driver.bus = &pata_parport_bus_type;
> > +	pr->driver.name = pr->name;
> > +	error = driver_register(&pr->driver);
> > +	if (error)
> > +		return error;
> > +
> > +	mutex_lock(&pi_mutex);
> > +	error = idr_alloc(&protocols, pr, 0, 0, GFP_KERNEL);
> > +	if (error < 0) {
> > +		driver_unregister(&pr->driver);
> > +		mutex_unlock(&pi_mutex);
> > +		return error;
> > +	}
> > +
> > +	pr_info("pata_parport: protocol %s registered\n", pr->name);
> > +
> > +	if (probe)	/* probe all parports using this protocol */
> 
> Please move the comment inside the if and use curly brackets for the if
> since its statement is multi-line.
> 
> > +		idr_for_each_entry(&parport_list, parport, port_num)
> > +			pi_init_one(parport, pr, -1, 0, -1);
> > +	mutex_unlock(&pi_mutex);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL(pata_parport_register_driver);
> > +
> > +void pata_parport_unregister_driver(struct pi_protocol *pr)
> > +{
> > +	struct pi_protocol *pr_iter;
> > +	int id = -1;
> > +
> > +	mutex_lock(&pi_mutex);
> > +	idr_for_each_entry(&protocols, pr_iter, id)
> 
> Add curly brackets.
> 
> > +		if (pr_iter == pr)
> > +			break;
> > +	idr_remove(&protocols, id);
> > +	mutex_unlock(&pi_mutex);
> > +	pr_info("pata_parport: protocol %s removed\n", pr->name);
> 
> I do not think this message is needed.
> 
> > +	driver_unregister(&pr->driver);
> > +}
> > +EXPORT_SYMBOL(pata_parport_unregister_driver);
> > +
> > +static ssize_t new_device_store(struct bus_type *bus, const char *buf, size_t count)
> > +{
> > +	char port[12] = "auto";
> > +	char protocol[8] = "auto";
> > +	int mode = -1, unit = -1, delay = -1;
> > +	struct pi_protocol *pr, *pr_wanted;
> > +	struct device_driver *drv;
> > +	struct parport *parport;
> > +	int port_num, port_wanted, pr_num;
> > +	bool ok = false;
> > +
> > +	if (sscanf(buf, "%11s %7s %d %d %d",
> > +			port, protocol, &mode, &unit, &delay) < 1)
> > +		return -EINVAL;
> > +
> > +	if (sscanf(port, "parport%u", &port_wanted) < 1) {
> > +		if (!strcmp(port, "auto"))
> 
> Curly brackets please.
> > +			port_wanted = -1;
> > +		else {
> > +			pr_err("invalid port name %s\n", port);
> > +			return -EINVAL;
> > +		}
> > +	}
> > +
> > +	drv = driver_find(protocol, &pata_parport_bus_type);
> > +	if (!drv) {
> > +		if (!strcmp(protocol, "auto"))
> > +			pr_wanted = NULL;
> 
> same.
> 
> > +		else {
> > +			pr_err("protocol %s not found\n", protocol);
> > +			return -EINVAL;
> > +		}
> > +	} else
> > +		pr_wanted = container_of(drv, struct pi_protocol, driver);
> 
> Here too.
> 
> > +
> > +	mutex_lock(&pi_mutex);
> > +	/* walk all parports */
> > +	idr_for_each_entry(&parport_list, parport, port_num) {
> > +		if (port_num == port_wanted || port_wanted == -1) {
> > +			parport = parport_find_number(port_num);
> > +			if (!parport) {
> > +				pr_err("no such port %s\n", port);
> > +				mutex_unlock(&pi_mutex);
> > +				return -ENODEV;
> > +			}
> > +			/* walk all protocols */
> > +			idr_for_each_entry(&protocols, pr, pr_num)
> 
> Add curly brackets to this one too.
> 
> > +				if (pr == pr_wanted || !pr_wanted)
> > +					if (pi_init_one(parport, pr, mode, unit,
> > +							delay))
> > +						ok = true;
> > +			parport_put_port(parport);
> > +		}
> > +	}
> > +	mutex_unlock(&pi_mutex);
> > +	if (!ok)
> > +		return -ENODEV;
> > +
> > +	return count;
> > +}
> > +static BUS_ATTR_WO(new_device);
> > +
> > +static void pi_remove_one(struct device *dev)
> > +{
> > +	struct ata_host *host = dev_get_drvdata(dev);
> > +	struct pi_adapter *pi = host->private_data;
> > +
> > +	ata_host_detach(host);
> > +	del_timer_sync(&pi->timer);
> > +	pi_release(pi);
> > +	device_unregister(dev);
> > +	ida_free(&pata_parport_bus_dev_ids, dev->id);
> > +	/* pata_parport_dev_release will do kfree(pi) */
> > +}
> > +
> > +static ssize_t delete_device_store(struct bus_type *bus, const char *buf, size_t count)
> > +{
> > +	struct device *dev;
> > +	char device_name[32];
> > +	int fields;
> > +
> > +	fields = sscanf(buf, "%31s", device_name);
> > +	if (fields < 1)
> > +		return -EINVAL;
> > +
> > +	mutex_lock(&pi_mutex);
> > +	dev = bus_find_device_by_name(bus, NULL, device_name);
> > +	if (!dev) {
> > +		mutex_unlock(&pi_mutex);
> > +		return -ENODEV;
> > +	}
> > +
> > +	pi_remove_one(dev);
> > +	mutex_unlock(&pi_mutex);
> > +
> > +	return count;
> > +}
> > +static BUS_ATTR_WO(delete_device);
> > +
> > +static void pata_parport_attach(struct parport *port)
> > +{
> > +	struct pi_protocol *pr;
> > +	int pr_num, id;
> > +
> > +	mutex_lock(&pi_mutex);
> > +	id = idr_alloc(&parport_list, port, port->number, port->number, GFP_KERNEL);
> > +	if (id < 0) {
> > +		mutex_unlock(&pi_mutex);
> > +		return;
> > +	}
> > +
> > +	if (probe) /* probe this port using all protocols */
> > +		idr_for_each_entry(&protocols, pr, pr_num)
> > +			pi_init_one(port, pr, -1, 0, -1);
> 
> Curly brackets and comment under the if.
> 
> > +	mutex_unlock(&pi_mutex);
> > +}
> > +
> > +static int pi_remove_port(struct device *dev, void *p)
> > +{
> > +	struct ata_host *host = dev_get_drvdata(dev);
> > +	struct pi_adapter *pi = host->private_data;
> > +
> > +	if (pi->pardev->port == p)
> > +		pi_remove_one(dev);
> > +
> > +	return 0;
> > +}
> > +
> > +static void pata_parport_detach(struct parport *port)
> > +{
> > +	mutex_lock(&pi_mutex);
> > +	bus_for_each_dev(&pata_parport_bus_type, NULL, port, pi_remove_port);
> > +	idr_remove(&parport_list, port->number);
> > +	mutex_unlock(&pi_mutex);
> > +}
> > +
> > +static struct parport_driver pata_parport_driver = {
> > +	.name = DRV_NAME,
> > +	.match_port = pata_parport_attach,
> > +	.detach = pata_parport_detach,
> > +	.devmodel = true,
> > +};
> > +
> > +static __init int pata_parport_init(void)
> > +{
> > +	int error;
> > +
> > +	error = bus_register(&pata_parport_bus_type);
> > +	if (error) {
> > +		pr_err("failed to register pata_parport bus, error: %d\n", error);
> > +		return error;
> > +	}
> > +
> > +	error = device_register(&pata_parport_bus);
> > +	if (error) {
> > +		pr_err("failed to register pata_parport bus, error: %d\n", error);
> > +		return error;
> 
> Bug. This should not be here.
> 
> > +		goto out_unregister_bus;
> > +	}
> > +
> > +	error = bus_create_file(&pata_parport_bus_type, &bus_attr_new_device);
> > +	if (error) {
> > +		pr_err("unable to create sysfs file, error: %d\n", error);
> > +		goto out_unregister_dev;
> > +	}
> > +
> > +	error = bus_create_file(&pata_parport_bus_type, &bus_attr_delete_device);
> > +	if (error) {
> > +		pr_err("unable to create sysfs file, error: %d\n", error);
> > +		goto out_remove_new;
> > +	}
> > +
> > +	error = parport_register_driver(&pata_parport_driver);
> > +	if (error) {
> > +		pr_err("unable to register parport driver, error: %d\n", error);
> > +		goto out_remove_del;
> > +	}
> > +
> > +	return 0;
> > +
> > +out_remove_del:
> > +	bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
> > +out_remove_new:
> > +	bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
> > +out_unregister_dev:
> > +	device_unregister(&pata_parport_bus);
> > +out_unregister_bus:
> > +	bus_unregister(&pata_parport_bus_type);
> > +	return error;
> > +}
> > +
> > +static __exit void pata_parport_exit(void)
> > +{
> > +	parport_unregister_driver(&pata_parport_driver);
> > +	bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
> > +	bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
> > +	device_unregister(&pata_parport_bus);
> > +	bus_unregister(&pata_parport_bus_type);
> > +}
> > +
> > +MODULE_AUTHOR("Ondrej Zary");
> > +MODULE_DESCRIPTION("driver for parallel port ATA adapters");
> > +MODULE_LICENSE("GPL");
> > +MODULE_ALIAS("paride");
> > +
> > +module_init(pata_parport_init);
> > +module_exit(pata_parport_exit);
> > diff --git a/drivers/ata/pata_parport/pata_parport.h b/drivers/ata/pata_parport/pata_parport.h
> > new file mode 100644
> > index 000000000000..c4201b809b20
> > --- /dev/null
> > +++ b/drivers/ata/pata_parport/pata_parport.h
> > @@ -0,0 +1,110 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + *	paride.h	(c) 1997-8  Grant R. Guenther <grant at torque.net>
> > + *				    Under the terms of the GPL.
> > + *
> > + * This file defines the interface for adapter chip drivers.
> 
> Which adapter ? "Parallel port IDE adapter chip", no ?
> 
> > + */
> > +
> > +#include <linux/libata.h>
> > +
> > +struct pi_adapter {
> > +	struct device dev;
> > +	struct pi_protocol *proto;	/* adapter protocol */
> > +	int port;			/* base address of parallel port */
> > +	int mode;			/* transfer mode in use */
> > +	int delay;			/* adapter delay setting */
> > +	int unit;			/* unit number for chained adapters */
> > +	int saved_r0;			/* saved port state */
> > +	int saved_r2;			/* saved port state */
> > +	unsigned long private;		/* for protocol module */
> > +	struct pardevice *pardev;	/* pointer to pardevice */
> > +	int claimed;			/* parport has already been claimed */
> 
> Make this a bool ?
> 
> > +	struct timer_list timer;	/* disconnect timer */
> > +};
> > +
> > +/* registers are addressed as (cont,regr)
> > + *	cont: 0 for command register file, 1 for control register(s)
> > + *	regr: 0-7 for register number.
> > + */
> > +
> > +/* macros and functions exported to the protocol modules */
> > +#define delay_p			(pi->delay ? udelay(pi->delay) : (void)0)
> > +#define out_p(offs, byte)	do { outb(byte, pi->port + offs); delay_p; } while (0)
> > +#define in_p(offs)		(delay_p, inb(pi->port + offs))
> > +
> > +#define w0(byte)		out_p(0, byte)
> > +#define r0()			(in_p(0) & 0xff)
> > +#define w1(byte)		out_p(1, byte)
> > +#define r1()			(in_p(1) & 0xff)
> > +#define w2(byte)		out_p(2, byte)
> > +#define r2()			(in_p(2) & 0xff)
> > +#define w3(byte)		out_p(3, byte)
> > +#define w4(byte)		out_p(4, byte)
> > +#define r4()			(in_p(4) & 0xff)
> > +#define w4w(data)		do { outw(data, pi->port + 4); delay_p; } while (0)
> > +#define w4l(data)		do { outl(data, pi->port + 4); delay_p; } while (0)
> > +#define r4w()			(delay_p, inw(pi->port + 4) & 0xffff)
> > +#define r4l()			(delay_p, inl(pi->port + 4) & 0xffffffff)
> 
> Why not align this with the others ?

It's aligned properly in the file, only looks bad in a diff.

> > +
> > +static inline u16 pi_swab16(char *b, int k)
> > +{
> > +	union { u16 u; char t[2]; } r;
> > +
> > +	r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k];
> > +	return r.u;
> > +}
> > +
> > +static inline u32 pi_swab32(char *b, int k)
> > +{
> > +	union { u32 u; char f[4]; } r;
> > +
> > +	r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k];
> > +	r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2];
> > +	return r.u;
> > +}
> > +
> > +struct pi_protocol {
> > +	char name[8];		/* name for this protocol */
> > +
> > +	int max_mode;		/* max mode number */
> > +	int epp_first;		/* modes >= this use 8 ports */
> > +
> > +	int default_delay;	/* delay parameter if not specified */
> > +	int max_units;		/* max chained units probed for */
> 
> Except maybe epp_first, I find the comments for these fields useless: no
> information added.
> 
> > +
> > +	void (*write_regr)(struct pi_adapter *pi, int cont, int regr, int val);
> > +	int (*read_regr)(struct pi_adapter *pi, int cont, int regr);
> > +	void (*write_block)(struct pi_adapter *pi, char *buf, int count);
> > +	void (*read_block)(struct pi_adapter *pi, char *buf, int count);
> > +
> > +	void (*connect)(struct pi_adapter *pi);
> > +	void (*disconnect)(struct pi_adapter *pi);
> > +
> > +	int (*test_port)(struct pi_adapter *pi);
> > +	int (*probe_unit)(struct pi_adapter *pi);
> > +	int (*test_proto)(struct pi_adapter *pi, char *scratch, int verbose);
> > +	void (*log_adapter)(struct pi_adapter *pi, char *scratch, int verbose);
> > +
> > +	int (*init_proto)(struct pi_adapter *pi);
> > +	void (*release_proto)(struct pi_adapter *pi);
> > +	struct module *owner;
> > +	struct device_driver driver;
> > +	struct scsi_host_template sht;
> > +};
> > +
> > +#define PATA_PARPORT_SHT ATA_PIO_SHT
> > +
> > +extern int pata_parport_register_driver(struct pi_protocol *pr);
> > +extern void pata_parport_unregister_driver(struct pi_protocol *pr);
> 
> No need for extern.
> 
> > +
> > +/**
> > + * module_pata_parport_driver() - Helper macro for registering a pata_parport driver
> > + * @__pi_protocol: pi_protocol struct
> > + *
> > + * Helper macro for pata_parport drivers which do not do anything special in module
> > + * init/exit. This eliminates a lot of boilerplate. Each module may only
> > + * use this macro once, and calling it replaces module_init() and module_exit()
> > + */
> > +#define module_pata_parport_driver(__pi_protocol) \
> > +	module_driver(__pi_protocol, pata_parport_register_driver, pata_parport_unregister_driver)
> 
> Make this a static inline ?

It's a macro that expands to other macro (defined in include/linux/device/driver.h)
that expands to __init and __exit functions, module_init() and
module_exit() so we can use:

module_pata_parport_driver(on26);

instead of:

static int __init on26_init(void)
{
	return pata_parport_register_driver(&on26);
}

static void __exit on26_exit(void)
{
	pata_parport_unregister_driver(&on26);
}

module_init(on26_init)
module_exit(on26_exit)

-- 
Ondrej Zary


From damien.lemoal at opensource.wdc.com  Mon Mar  7 01:42:44 2022
From: damien.lemoal at opensource.wdc.com (Damien Le Moal)
Date: Mon, 7 Mar 2022 18:42:44 +0900
Subject: [Linux-parport] [PATCH 01/16] pata_parport: add core driver
 (PARIDE replacement)
In-Reply-To: <202203070955.05800.linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
 <20220305201411.501-2-linux@zary.sk>
 <2a79b7ac-6648-7855-fcfa-de0800c9a310@opensource.wdc.com>
 <202203070955.05800.linux@zary.sk>
Message-ID: <b7774aff-d391-5e37-58b5-abe6bc17e7df@opensource.wdc.com>

On 3/7/22 17:55, Ondrej Zary wrote:
>>> +module_param(probe, bool, 0644);
>>> +MODULE_PARM_DESC(probe, "Enable automatic device probing (0=off, 1=on [default])");
>>> +
>>> +static bool verbose;
>>> +module_param(verbose, bool, 0644);
>>> +MODULE_PARM_DESC(verbose, "Enable verbose messages (0=off [default], 1=on)");
>>
>> Is this really necessary ? pr_debug() and all ata_xxx_debug() functions
>> can be enabled dynamically.
> 
> The verbose messages are for adapter chip detection. That happens before the
> ata host is registered.

Sure. But you can still use pr_debug(). So instead of

if (verbose)
	dev_info();

simply use:

dev_dbg()

And these calls can be enabled with the standard dynamic debug control.

> 
>>> +
>>> +#define DISCONNECT_TIMEOUT	(HZ / 10)
>>> +
>>> +static void pi_connect(struct pi_adapter *pi)
>>> +{
>>> +	del_timer_sync(&pi->timer);
>>> +	if (pi->claimed)
>>> +		return;
>>
>> Nit: I would reverse the condition to avoid the return. Or add a block
>> line to separate the following hunk. Better readability this way, I think.
>>
>>> +	pi->claimed = 1;
>>> +	parport_claim_or_block(pi->pardev);
>>> +	pi->proto->connect(pi);
>>> +}
>>> +
>>> +static void pi_disconnect_later(struct pi_adapter *pi)
>>> +{
>>> +	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
>>> +}
>>
>> Is this really needed ? Not sure it helps in any way. At least the name
>> should be changed to reflect what this does. May be something like
>> pi_start_disconnect_timeout() ?
> 
> Disconnect needs to happen after end of an operation so the parport is freed
> for device(s) (like a printer) connected to pass-through port of a paride
> device. There could be even multiple paride devices chained on one parport.
> 
> Disconnecting immediately at the end of each function does not work
> (probably breaks the protocol?)
> 
> The old high-level drivers (pd, pf...) did connect and disconnect manually
> on each operation (command or data transfer) but it does not seem to be
> possible with libata.

I am not questioning how you handle the disconnect. I was only
commenting that the inline function may not be that usefull and you
could simply directly use the mod_timer() calls directly.

or

rename pi_disconnect_later() to something that better explains what the
function does.

> 
>>> +
>>> +static void pi_disconnect_timer(struct timer_list *t)
>>> +{
>>> +	struct pi_adapter *pi = from_timer(pi, t, timer);
>>> +
>>> +	if (!pi->claimed)
>>> +		return;
>>
>> A blank line here would be nice for readability.
>>
>>> +	pi->proto->disconnect(pi);
>>> +	parport_release(pi->pardev);
>>> +	pi->claimed = 0;
>>> +}
>>> +
>>> +/* functions taken from libata-sff.c and converted from direct port I/O */
>>> +static unsigned int pata_parport_devchk(struct ata_port *ap, unsigned int device)
>>
>> Should this be a bool function ?
> 
> I don't know. It's copied from libata-sff.c
>  
>>> +{
>>> +	struct pi_adapter *pi = ap->host->private_data;
>>> +	u8 nsect, lbal;
>>> +
>>> +	ap->ops->sff_dev_select(ap, device);
>>> +
>>> +	pi_connect(pi);
>>> +	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0x55);
>>> +	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
>>> +
>>> +	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0xaa);
>>> +	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0x55);
>>> +
>>> +	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 055);
>>> +	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
>>> +
>>> +	nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
>>> +	lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
>>> +	pi_disconnect_later(pi);
>>> +
>>> +	if ((nsect == 0x55) && (lbal == 0xaa))
>>> +		return 1;	/* we found a device */
>>> +
>>> +	return 0;		/* nothing found */
>>> +}
>>> +
>>> +static int pata_parport_bus_softreset(struct ata_port *ap, unsigned int devmask,
>>> +				      unsigned long deadline)
>>> +{
>>> +	struct pi_adapter *pi = ap->host->private_data;
>>> +
>>> +	pi_connect(pi);
>>> +	/* software reset.  causes dev0 to be selected */
>>> +	pi->proto->write_regr(pi, 1, 6, ap->ctl);
>>> +	udelay(20);	/* FIXME: flush */
>>
>> Then please fix it.
> 
> I don't know what that means. It's copied from libata-sff.c

OK. Will have a look there too.

> 
>>> +	pi->proto->write_regr(pi, 1, 6, ap->ctl | ATA_SRST);
>>> +	udelay(20);	/* FIXME: flush */
>>
>> Here too.
>>
>>> +	pi->proto->write_regr(pi, 1, 6, ap->ctl);
>>> +	ap->last_ctl = ap->ctl;
>>> +	pi_disconnect_later(pi);
>>> +
>>> +	/* wait the port to become ready */
>>> +	return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
>>> +}
>>> +
>>> +static int pata_parport_softreset(struct ata_link *link, unsigned int *classes,
>>> +				  unsigned long deadline)
>>> +{
>>> +	struct ata_port *ap = link->ap;
>>> +	unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
>>> +	unsigned int devmask = 0;
>>> +	int rc;
>>> +	u8 err;
>>> +
>>> +	/* determine if device 0/1 are present */
>>> +	if (pata_parport_devchk(ap, 0))
>>> +		devmask |= (1 << 0);
>>> +	if (slave_possible && pata_parport_devchk(ap, 1))
>>> +		devmask |= (1 << 1);
>>> +
>>> +	/* select device 0 again */
>>> +	ap->ops->sff_dev_select(ap, 0);
>>> +
>>> +	/* issue bus reset */
>>> +	rc = pata_parport_bus_softreset(ap, devmask, deadline);
>>> +	/* if link is occupied, -ENODEV too is an error */
>>
>> Please merge this comment with the one above. That will make the code
>> more readable (I know this is the style used by many drivers, but let's
>> not repeat the weird style :)).
>>
>>> +	if (rc && (rc != -ENODEV || sata_scr_valid(link))) {
>>> +		ata_link_err(link, "SRST failed (errno=%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	/* determine by signature whether we have ATA or ATAPI devices */
>>> +	classes[0] = ata_sff_dev_classify(&link->device[0],
>>> +					  devmask & (1 << 0), &err);
>>> +	if (slave_possible && err != 0x81)
>>> +		classes[1] = ata_sff_dev_classify(&link->device[1],
>>> +						  devmask & (1 << 1), &err);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static u8 pata_parport_check_status(struct ata_port *ap)
>>> +{
>>> +	u8 status;
>>> +	struct pi_adapter *pi = ap->host->private_data;
>>> +
>>> +	pi_connect(pi);
>>> +	status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
>>> +	pi_disconnect_later(pi);
>>> +
>>> +	return status;
>>> +}
>>> +
>>> +static u8 pata_parport_check_altstatus(struct ata_port *ap)
>>> +{
>>> +	u8 altstatus;
>>> +	struct pi_adapter *pi = ap->host->private_data;
>>> +
>>> +	pi_connect(pi);
>>> +	altstatus = pi->proto->read_regr(pi, 1, 6);
>>> +	pi_disconnect_later(pi);
>>> +
>>> +	return altstatus;
>>> +}
>>> +
>>> +static void pata_parport_dev_select(struct ata_port *ap, unsigned int device)
>>> +{
>>> +	struct pi_adapter *pi = ap->host->private_data;
>>> +	u8 tmp;
>>> +
>>> +	pi_connect(pi);
>>> +	if (device == 0)
>>> +		tmp = ATA_DEVICE_OBS;
>>> +	else
>>> +		tmp = ATA_DEVICE_OBS | ATA_DEV1;
>>> +
>>> +	pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tmp);
>>> +	pi_disconnect_later(pi);
>>> +	ata_sff_pause(ap);	/* needed; also flushes, for mmio */
>>
>> The comment does not parse... Why is it needed ?
>> And pleasde move the comment above the call, with a blank line
>> separating it from the previous lines.
> 
> I don't know. It's copied from libata-sff.c

Drop the comment then.

> 
>>> +}
>>> +
>>> +static void pata_parport_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
>>> +{
>>> +	struct pi_adapter *pi = ap->host->private_data;
>>> +	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
>>> +
>>> +	pi_connect(pi);
>>> +	if (tf->ctl != ap->last_ctl) {
>>> +		pi->proto->write_regr(pi, 1, 6, tf->ctl);
>>> +		ap->last_ctl = tf->ctl;
>>> +		ata_wait_idle(ap);
>>> +	}
>>> +
>>> +	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
>>> +		pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->hob_feature);
>>> +		pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->hob_nsect);
>>> +		pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->hob_lbal);
>>> +		pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->hob_lbam);
>>> +		pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->hob_lbah);
>>> +	}
>>> +
>>> +	if (is_addr) {
>>
>> Move this if above the previous one. Doing so, you can remove the need
>> for is_addr var and simplify the previous if condition.
>>
>> That said, many pata drivers check that flag but it is always set by
>> libata core. So checking it seems useless. Need to dig into this.
> 
> It's copied from libata-sff.c which is almost libata core.

Yes. Saw the same pattern in different drivers. Need to figure out what
is going on here. That flag really seem totally useless. Will check.
Keep the flag use for now, but at least rewrite as suggested to avoid
the need for that is_addr variable.

>>> +	struct timer_list timer;	/* disconnect timer */
>>> +};
>>> +
>>> +/* registers are addressed as (cont,regr)
>>> + *	cont: 0 for command register file, 1 for control register(s)
>>> + *	regr: 0-7 for register number.
>>> + */
>>> +
>>> +/* macros and functions exported to the protocol modules */
>>> +#define delay_p			(pi->delay ? udelay(pi->delay) : (void)0)
>>> +#define out_p(offs, byte)	do { outb(byte, pi->port + offs); delay_p; } while (0)
>>> +#define in_p(offs)		(delay_p, inb(pi->port + offs))
>>> +
>>> +#define w0(byte)		out_p(0, byte)
>>> +#define r0()			(in_p(0) & 0xff)
>>> +#define w1(byte)		out_p(1, byte)
>>> +#define r1()			(in_p(1) & 0xff)
>>> +#define w2(byte)		out_p(2, byte)
>>> +#define r2()			(in_p(2) & 0xff)
>>> +#define w3(byte)		out_p(3, byte)
>>> +#define w4(byte)		out_p(4, byte)
>>> +#define r4()			(in_p(4) & 0xff)
>>> +#define w4w(data)		do { outw(data, pi->port + 4); delay_p; } while (0)
>>> +#define w4l(data)		do { outl(data, pi->port + 4); delay_p; } while (0)
>>> +#define r4w()			(delay_p, inw(pi->port + 4) & 0xffff)
>>> +#define r4l()			(delay_p, inl(pi->port + 4) & 0xffffffff)
>>
>> Why not align this with the others ?
> 
> It's aligned properly in the file, only looks bad in a diff.
> 

OK.

>>> +
>>> +/**
>>> + * module_pata_parport_driver() - Helper macro for registering a pata_parport driver
>>> + * @__pi_protocol: pi_protocol struct
>>> + *
>>> + * Helper macro for pata_parport drivers which do not do anything special in module
>>> + * init/exit. This eliminates a lot of boilerplate. Each module may only
>>> + * use this macro once, and calling it replaces module_init() and module_exit()
>>> + */
>>> +#define module_pata_parport_driver(__pi_protocol) \
>>> +	module_driver(__pi_protocol, pata_parport_register_driver, pata_parport_unregister_driver)
>>
>> Make this a static inline ?
> 
> It's a macro that expands to other macro (defined in include/linux/device/driver.h)
> that expands to __init and __exit functions, module_init() and
> module_exit() so we can use:
> 
> module_pata_parport_driver(on26);
> 
> instead of:
> 
> static int __init on26_init(void)
> {
> 	return pata_parport_register_driver(&on26);
> }
> 
> static void __exit on26_exit(void)
> {
> 	pata_parport_unregister_driver(&on26);
> }
> 
> module_init(on26_init)
> module_exit(on26_exit)

OK.


-- 
Damien Le Moal
Western Digital Research


From hch at lst.de  Mon Mar  7 22:54:43 2022
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 8 Mar 2022 07:54:43 +0100
Subject: [Linux-parport] [RFC PATCH] pata_parport: paride replacement
In-Reply-To: <202203061136.36700.linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
 <20220306085825.GA22425@lst.de> <202203061136.36700.linux@zary.sk>
Message-ID: <20220308065443.GA24269@lst.de>

On Sun, Mar 06, 2022 at 11:36:36AM +0100, Ondrej Zary wrote:
> On Sunday 06 March 2022 09:58:25 Christoph Hellwig wrote:
> > Hi Ondrej,
> > 
> > I just took a quick glance and it seems like the actual protocol
> > modules still are basically almost exactly the same ones as the
> > paride ones.  Is there a way to just keep the existing modules?
> > 
> > The only big thing I noticed is the host template, but at least
> > for the transitional periode we could probably allocate that
> > dynamically in the core.  I think would reduce the amount of code
> > churn nicely and make review much easier.
> 
> Yes, only small changes in the protocol modules regarding (un)registration.
> 
> Getting the original modules work with pata_parport (like in 1st preview) required some hacks that break paride (disabling EXPORT_SYMBOLs in paride).
> 
> Maybe the protocol modules can be moved (git mv) from paride and then patched? A copy would be better but there's no "git cp".

Hmm, how would be break the old PARIDE code?  You'd need the new libata
support exlusive to the old PARIDE code so that only one of them can
export the registration symbols at a time.  The git-mv can happen
once the old paride code is removed after a release or two.

> 
> -- 
> Ondrej Zary
---end quoted text---


From hch at lst.de  Mon Mar  7 22:59:05 2022
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 8 Mar 2022 07:59:05 +0100
Subject: [Linux-parport] [PATCH 01/16] pata_parport: add core driver
 (PARIDE replacement)
In-Reply-To: <20220305201411.501-2-linux@zary.sk>
References: <20220305201411.501-1-linux@zary.sk>
 <20220305201411.501-2-linux@zary.sk>
Message-ID: <20220308065905.GB24269@lst.de>

> +
> +static void pata_parport_dev_release(struct device *dev)
> +{
> +	struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
> +
> +	kfree(pi);
> +}
>
> +void pata_parport_bus_release(struct device *dev)
> +{
> +	/* nothing to do here but required to avoid warning on device removal */
> +}
> +
> +static struct bus_type pata_parport_bus_type = {
> +	.name = DRV_NAME,
> +};
> +
> +static struct device pata_parport_bus = {
> +	.init_name = DRV_NAME,
> +	.release = pata_parport_bus_release,
> +};

Hmm, wouldn't it make sense to let the libata device hang off the device
in struct pardevice?


From lkp at intel.com  Tue Mar  8 09:52:40 2022
From: lkp at intel.com (kernel test robot)
Date: Wed, 9 Mar 2022 01:52:40 +0800
Subject: [Linux-parport] [PATCH 01/16] pata_parport: add core driver
 (PARIDE replacement)
In-Reply-To: <20220305201411.501-2-linux@zary.sk>
References: <20220305201411.501-2-linux@zary.sk>
Message-ID: <202203090134.f9NhVHMa-lkp@intel.com>

Hi Ondrej,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on hch-configfs/for-next]
[also build test WARNING on linux/master linus/master v5.17-rc7 next-20220308]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Ondrej-Zary/pata_parport-add-core-driver-PARIDE-replacement/20220307-142912
base:   git://git.infradead.org/users/hch/configfs.git for-next
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20220309/202203090134.f9NhVHMa-lkp at intel.com/config)
compiler: sh4-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/05539e2a04721c2710e7d1f6ae49926474bdf918
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Ondrej-Zary/pata_parport-add-core-driver-PARIDE-replacement/20220307-142912
        git checkout 05539e2a04721c2710e7d1f6ae49926474bdf918
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=sh SHELL=/bin/bash drivers/ata/pata_parport/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/ata/pata_parport/pata_parport.c:341:6: warning: no previous prototype for 'pi_release' [-Wmissing-prototypes]
     341 | void pi_release(struct pi_adapter *pi)
         |      ^~~~~~~~~~
>> drivers/ata/pata_parport/pata_parport.c:462:6: warning: no previous prototype for 'pata_parport_bus_release' [-Wmissing-prototypes]
     462 | void pata_parport_bus_release(struct device *dev)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/ata/pata_parport/pata_parport.c:476:20: warning: no previous prototype for 'pi_init_one' [-Wmissing-prototypes]
     476 | struct pi_adapter *pi_init_one(struct parport *parport, struct pi_protocol *pr,
         |                    ^~~~~~~~~~~


vim +/pi_release +341 drivers/ata/pata_parport/pata_parport.c

   340	
 > 341	void pi_release(struct pi_adapter *pi)
   342	{
   343		parport_unregister_device(pi->pardev);
   344		if (pi->proto->release_proto)
   345			pi->proto->release_proto(pi);
   346		module_put(pi->proto->owner);
   347	}
   348	
   349	static int default_test_proto(struct pi_adapter *pi, char *scratch)
   350	{
   351		int j, k;
   352		int e[2] = { 0, 0 };
   353	
   354		pi->proto->connect(pi);
   355	
   356		for (j = 0; j < 2; j++) {
   357			pi->proto->write_regr(pi, 0, 6, 0xa0 + j * 0x10);
   358			for (k = 0; k < 256; k++) {
   359				pi->proto->write_regr(pi, 0, 2, k ^ 0xaa);
   360				pi->proto->write_regr(pi, 0, 3, k ^ 0x55);
   361				if (pi->proto->read_regr(pi, 0, 2) != (k ^ 0xaa))
   362					e[j]++;
   363			}
   364		}
   365		pi->proto->disconnect(pi);
   366	
   367		if (verbose)
   368			dev_info(&pi->dev, "%s: port 0x%x, mode  %d, test=(%d,%d)\n",
   369			       pi->proto->name, pi->port,
   370			       pi->mode, e[0], e[1]);
   371	
   372		return (e[0] && e[1]);	/* not here if both > 0 */
   373	}
   374	
   375	static int pi_test_proto(struct pi_adapter *pi, char *scratch)
   376	{
   377		int res;
   378	
   379		parport_claim_or_block(pi->pardev);
   380		if (pi->proto->test_proto)
   381			res = pi->proto->test_proto(pi, scratch, verbose);
   382		else
   383			res = default_test_proto(pi, scratch);
   384		parport_release(pi->pardev);
   385	
   386		return res;
   387	}
   388	
   389	static int pi_probe_mode(struct pi_adapter *pi, int max, char *scratch)
   390	{
   391		int best, range;
   392	
   393		if (pi->mode != -1) {
   394			if (pi->mode >= max)
   395				return 0;
   396			range = 3;
   397			if (pi->mode >= pi->proto->epp_first)
   398				range = 8;
   399			if ((range == 8) && (pi->port % 8))
   400				return 0;
   401			return (!pi_test_proto(pi, scratch));
   402		}
   403		best = -1;
   404		for (pi->mode = 0; pi->mode < max; pi->mode++) {
   405			range = 3;
   406			if (pi->mode >= pi->proto->epp_first)
   407				range = 8;
   408			if ((range == 8) && (pi->port % 8))
   409				break;
   410			if (!pi_test_proto(pi, scratch))
   411				best = pi->mode;
   412		}
   413		pi->mode = best;
   414		return (best > -1);
   415	}
   416	
   417	
   418	static int pi_probe_unit(struct pi_adapter *pi, int unit, char *scratch)
   419	{
   420		int max, s, e;
   421	
   422		s = unit;
   423		e = s + 1;
   424	
   425		if (s == -1) {
   426			s = 0;
   427			e = pi->proto->max_units;
   428		}
   429	
   430		if (pi->proto->test_port) {
   431			parport_claim_or_block(pi->pardev);
   432			max = pi->proto->test_port(pi);
   433			parport_release(pi->pardev);
   434		} else
   435			max = pi->proto->max_mode;
   436	
   437		if (pi->proto->probe_unit) {
   438			parport_claim_or_block(pi->pardev);
   439			for (pi->unit = s; pi->unit < e; pi->unit++)
   440				if (pi->proto->probe_unit(pi)) {
   441					parport_release(pi->pardev);
   442					if (pi_probe_mode(pi, max, scratch))
   443						return 1;
   444					return 0;
   445				}
   446			parport_release(pi->pardev);
   447			return 0;
   448		}
   449	
   450		if (!pi_probe_mode(pi, max, scratch))
   451			return 0;
   452		return 1;
   453	}
   454	
   455	static void pata_parport_dev_release(struct device *dev)
   456	{
   457		struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
   458	
   459		kfree(pi);
   460	}
   461	
 > 462	void pata_parport_bus_release(struct device *dev)
   463	{
   464		/* nothing to do here but required to avoid warning on device removal */
   465	}
   466	
   467	static struct bus_type pata_parport_bus_type = {
   468		.name = DRV_NAME,
   469	};
   470	
   471	static struct device pata_parport_bus = {
   472		.init_name = DRV_NAME,
   473		.release = pata_parport_bus_release,
   474	};
   475	
 > 476	struct pi_adapter *pi_init_one(struct parport *parport, struct pi_protocol *pr,
   477				       int mode, int unit, int delay)
   478	{
   479		struct pardev_cb par_cb = { };
   480		char scratch[512];
   481		const struct ata_port_info *ppi[] = { &pata_parport_port_info };
   482		struct ata_host *host;
   483		struct pi_adapter *pi = kzalloc(sizeof(struct pi_adapter), GFP_KERNEL);
   484	
   485		if (!pi)
   486			return NULL;
   487	
   488		/* set up pi->dev before pi_probe_unit() so it can use dev_printk() */
   489		pi->dev.parent = &pata_parport_bus;
   490		pi->dev.bus = &pata_parport_bus_type;
   491		pi->dev.driver = &pr->driver;
   492		pi->dev.release = pata_parport_dev_release;
   493		pi->dev.id = ida_alloc(&pata_parport_bus_dev_ids, GFP_KERNEL);
   494		if (pi->dev.id < 0)
   495			return NULL; /* pata_parport_dev_release will do kfree(pi) */
   496		dev_set_name(&pi->dev, "pata_parport.%u", pi->dev.id);
   497		if (device_register(&pi->dev)) {
   498			put_device(&pi->dev);
   499			goto out_ida_free;
   500		}
   501	
   502		pi->proto = pr;
   503	
   504		/* still racy */
   505		if (!try_module_get(pi->proto->owner))
   506			goto out_unreg_dev;
   507		if (pi->proto->init_proto && pi->proto->init_proto(pi) < 0)
   508			goto out_module_put;
   509	
   510		pi->delay = (delay == -1) ? pi->proto->default_delay : delay;
   511		pi->mode = mode;
   512		pi->port = parport->base;
   513	
   514		par_cb.private = pi;
   515		pi->pardev = parport_register_dev_model(parport, dev_name(&pi->dev),
   516							&par_cb, pi->dev.id);
   517		if (!pi->pardev)
   518			goto out_module_put;
   519	
   520		if (!pi_probe_unit(pi, unit, scratch)) {
   521			dev_info(&pi->dev, "Adapter not found\n");
   522			goto out_unreg_parport;
   523		}
   524	
   525		pi->proto->log_adapter(pi, scratch, verbose);
   526	
   527		host = ata_host_alloc_pinfo(&pi->dev, ppi, 1);
   528		if (!host)
   529			goto out_unreg_parport;
   530		dev_set_drvdata(&pi->dev, host);
   531		host->private_data = pi;
   532	
   533		ata_port_desc(host->ports[0], "port %s", pi->pardev->port->name);
   534		ata_port_desc(host->ports[0], "protocol %s", pi->proto->name);
   535	
   536		timer_setup(&pi->timer, pi_disconnect_timer, 0);
   537	
   538		if (ata_host_activate(host, 0, NULL, 0, &pi->proto->sht))
   539			goto out_unreg_parport;
   540	
   541		return pi;
   542	
   543	out_unreg_parport:
   544		parport_unregister_device(pi->pardev);
   545		if (pi->proto->release_proto)
   546			pi->proto->release_proto(pi);
   547	out_module_put:
   548		module_put(pi->proto->owner);
   549	out_unreg_dev:
   550		device_unregister(&pi->dev);
   551	out_ida_free:
   552		ida_free(&pata_parport_bus_dev_ids, pi->dev.id);
   553		return NULL;
   554	}
   555	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Mar  9 00:44:06 2022
From: lkp at intel.com (kernel test robot)
Date: Wed, 9 Mar 2022 16:44:06 +0800
Subject: [Linux-parport] [PATCH 01/16] pata_parport: add core driver
 (PARIDE replacement)
In-Reply-To: <20220305201411.501-2-linux@zary.sk>
References: <20220305201411.501-2-linux@zary.sk>
Message-ID: <202203091613.dsoQnVk9-lkp@intel.com>

Hi Ondrej,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on hch-configfs/for-next]
[also build test ERROR on linux/master linus/master v5.17-rc7 next-20220308]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Ondrej-Zary/pata_parport-add-core-driver-PARIDE-replacement/20220307-142912
base:   git://git.infradead.org/users/hch/configfs.git for-next
config: ia64-allyesconfig (https://download.01.org/0day-ci/archive/20220309/202203091613.dsoQnVk9-lkp at intel.com/config)
compiler: ia64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/05539e2a04721c2710e7d1f6ae49926474bdf918
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Ondrej-Zary/pata_parport-add-core-driver-PARIDE-replacement/20220307-142912
        git checkout 05539e2a04721c2710e7d1f6ae49926474bdf918
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=ia64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   ia64-linux-ld: drivers/block/paride/paride.o: in function `pi_release':
>> (.text+0x600): multiple definition of `pi_release'; drivers/ata/pata_parport/pata_parport.o:(.text+0x36c0): first defined here

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From linux at zary.sk  Thu Mar 10 13:28:12 2022
From: linux at zary.sk (Ondrej Zary)
Date: Thu, 10 Mar 2022 22:28:12 +0100
Subject: [Linux-parport] [PATCH v0] pata_parport: add driver (PARIDE
 replacement)
Message-ID: <20220310212812.13944-1-linux@zary.sk>

Add pata_parport (PARIDE replacement) core libata driver.

The original paride protocol modules are used for now so allow them to
be compiled without old PARIDE core.

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 drivers/Makefile                   |   2 +-
 drivers/ata/Kconfig                |  22 +
 drivers/ata/Makefile               |   2 +
 drivers/ata/parport/Makefile       |   3 +
 drivers/ata/parport/pata_parport.c | 805 +++++++++++++++++++++++++++++
 drivers/ata/parport/pata_parport.h | 108 ++++
 drivers/block/paride/Kconfig       |  32 +-
 drivers/block/paride/paride.h      |   5 +
 8 files changed, 962 insertions(+), 17 deletions(-)
 create mode 100644 drivers/ata/parport/Makefile
 create mode 100644 drivers/ata/parport/pata_parport.c
 create mode 100644 drivers/ata/parport/pata_parport.h

diff --git a/drivers/Makefile b/drivers/Makefile
index a110338c860c..8ec515f3614e 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -98,7 +98,7 @@ obj-$(CONFIG_DIO)		+= dio/
 obj-$(CONFIG_SBUS)		+= sbus/
 obj-$(CONFIG_ZORRO)		+= zorro/
 obj-$(CONFIG_ATA_OVER_ETH)	+= block/aoe/
-obj-$(CONFIG_PARIDE) 		+= block/paride/
+obj-y		 		+= block/paride/
 obj-$(CONFIG_TC)		+= tc/
 obj-$(CONFIG_USB_PHY)		+= usb/
 obj-$(CONFIG_USB)		+= usb/
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index e5641e6c52ee..671c27b77a48 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -1161,6 +1161,28 @@ config PATA_WINBOND_VLB
 	  Support for the Winbond W83759A controller on Vesa Local Bus
 	  systems.
 
+config PATA_PARPORT
+	tristate "Parallel port IDE device support"
+	depends on PARPORT_PC && PARIDE=n
+	help
+	  There are many external CD-ROM and disk devices that connect through
+	  your computer's parallel port. Most of them are actually IDE devices
+	  using a parallel port IDE adapter. This option enables the
+	  PATA_PARPORT subsystem which contains drivers for many of these
+	  external drives.
+	  Read <file:Documentation/admin-guide/blockdev/paride.rst> for more
+	  information.
+
+	  If your parallel port support is in a loadable module, you must build
+	  PATA_PARPORT as a module. If you built PATA_PARPORT support into your
+	  kernel, you may still build the individual protocol modules
+	  as loadable modules. Use the old PARIDE protocol modules.
+	  If you build this support as a module, it will be called pata_parport.
+
+	  Unlike the old PARIDE, there are no high-level drivers needed.
+	  The IDE devices behind parallel port adapters are handled by the
+	  ATA layer.
+
 comment "Generic fallback / legacy drivers"
 
 config PATA_ACPI
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index b8aebfb14e82..171045578541 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -114,6 +114,8 @@ obj-$(CONFIG_PATA_SAMSUNG_CF)	+= pata_samsung_cf.o
 
 obj-$(CONFIG_PATA_PXA)		+= pata_pxa.o
 
+obj-$(CONFIG_PATA_PARPORT)	+= parport/
+
 # Should be last but two libata driver
 obj-$(CONFIG_PATA_ACPI)		+= pata_acpi.o
 # Should be last but one libata driver
diff --git a/drivers/ata/parport/Makefile b/drivers/ata/parport/Makefile
new file mode 100644
index 000000000000..3ec4a4a66e26
--- /dev/null
+++ b/drivers/ata/parport/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_PATA_PARPORT)		+= pata_parport.o
diff --git a/drivers/ata/parport/pata_parport.c b/drivers/ata/parport/pata_parport.c
new file mode 100644
index 000000000000..3ea8d824091e
--- /dev/null
+++ b/drivers/ata/parport/pata_parport.c
@@ -0,0 +1,805 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/parport.h>
+#include "pata_parport.h"
+
+#define DRV_NAME "pata_parport"
+
+static DEFINE_IDR(parport_list);
+static DEFINE_IDR(protocols);
+static DEFINE_IDA(pata_parport_bus_dev_ids);
+static DEFINE_MUTEX(pi_mutex);
+
+static bool probe = true;
+module_param(probe, bool, 0644);
+MODULE_PARM_DESC(probe, "Enable automatic device probing (0=off, 1=on [default])");
+
+static bool verbose;
+module_param(verbose, bool, 0644);
+MODULE_PARM_DESC(verbose, "Enable verbose messages (0=off [default], 1=on)");
+
+#define DISCONNECT_TIMEOUT	(HZ / 10)
+
+static void pi_connect(struct pi_adapter *pi)
+{
+	del_timer_sync(&pi->timer);
+	if (!pi->claimed) {
+		pi->claimed = true;
+		parport_claim_or_block(pi->pardev);
+		pi->proto->connect(pi);
+	}
+}
+
+static void pi_disconnect_timer(struct timer_list *t)
+{
+	struct pi_adapter *pi = from_timer(pi, t, timer);
+
+	if (pi->claimed) {
+		pi->proto->disconnect(pi);
+		parport_release(pi->pardev);
+		pi->claimed = false;
+	}
+}
+
+/* functions taken from libata-sff.c and converted from direct port I/O */
+static void pata_parport_dev_select(struct ata_port *ap, unsigned int device)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+	u8 tmp;
+
+	if (device == 0)
+		tmp = ATA_DEVICE_OBS;
+	else
+		tmp = ATA_DEVICE_OBS | ATA_DEV1;
+
+	pi_connect(pi);
+	pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tmp);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+	ata_sff_pause(ap);
+}
+
+static bool pata_parport_devchk(struct ata_port *ap, unsigned int device)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+	u8 nsect, lbal;
+
+	pata_parport_dev_select(ap, device);
+
+	pi_connect(pi);
+	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0x55);
+	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
+
+	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0xaa);
+	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0x55);
+
+	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 055);
+	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
+
+	nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
+	lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+
+	if ((nsect == 0x55) && (lbal == 0xaa))
+		return true;	/* we found a device */
+
+	return false;		/* nothing found */
+}
+
+static int pata_parport_bus_softreset(struct ata_port *ap, unsigned int devmask,
+				      unsigned long deadline)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	/* software reset.  causes dev0 to be selected */
+	pi->proto->write_regr(pi, 1, 6, ap->ctl);
+	udelay(20);
+	pi->proto->write_regr(pi, 1, 6, ap->ctl | ATA_SRST);
+	udelay(20);
+	pi->proto->write_regr(pi, 1, 6, ap->ctl);
+	ap->last_ctl = ap->ctl;
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+
+	/* wait the port to become ready */
+	return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
+}
+
+static int pata_parport_softreset(struct ata_link *link, unsigned int *classes,
+				  unsigned long deadline)
+{
+	struct ata_port *ap = link->ap;
+	unsigned int devmask = 0;
+	int rc;
+	u8 err;
+
+	/* determine if device 0/1 are present */
+	if (pata_parport_devchk(ap, 0))
+		devmask |= (1 << 0);
+	if (pata_parport_devchk(ap, 1))
+		devmask |= (1 << 1);
+
+	/* select device 0 again */
+	pata_parport_dev_select(ap, 0);
+
+	/* issue bus reset */
+	rc = pata_parport_bus_softreset(ap, devmask, deadline);
+	if (rc && rc != -ENODEV) {
+		ata_link_err(link, "SRST failed (errno=%d)\n", rc);
+		return rc;
+	}
+
+	/* determine by signature whether we have ATA or ATAPI devices */
+	classes[0] = ata_sff_dev_classify(&link->device[0],
+					  devmask & (1 << 0), &err);
+	if (err != 0x81)
+		classes[1] = ata_sff_dev_classify(&link->device[1],
+						  devmask & (1 << 1), &err);
+
+	return 0;
+}
+
+static u8 pata_parport_check_status(struct ata_port *ap)
+{
+	u8 status;
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+
+	return status;
+}
+
+static u8 pata_parport_check_altstatus(struct ata_port *ap)
+{
+	u8 altstatus;
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	altstatus = pi->proto->read_regr(pi, 1, 6);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+
+	return altstatus;
+}
+
+static void pata_parport_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	if (tf->ctl != ap->last_ctl) {
+		pi->proto->write_regr(pi, 1, 6, tf->ctl);
+		ap->last_ctl = tf->ctl;
+		ata_wait_idle(ap);
+	}
+
+	if (tf->flags & ATA_TFLAG_ISADDR) {
+		if (tf->flags & ATA_TFLAG_LBA48) {
+			pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->hob_feature);
+			pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->hob_nsect);
+			pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->hob_lbal);
+			pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->hob_lbam);
+			pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->hob_lbah);
+		}
+		pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->feature);
+		pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->nsect);
+		pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->lbal);
+		pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->lbam);
+		pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->lbah);
+	}
+
+	if (tf->flags & ATA_TFLAG_DEVICE)
+		pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tf->device);
+
+	ata_wait_idle(ap);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+}
+
+static void pata_parport_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	tf->status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
+	tf->error = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
+	tf->nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
+	tf->lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
+	tf->lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
+	tf->lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
+	tf->device = pi->proto->read_regr(pi, 0, ATA_REG_DEVICE);
+
+	if (tf->flags & ATA_TFLAG_LBA48) {
+		pi->proto->write_regr(pi, 1, 6, tf->ctl | ATA_HOB);
+		tf->hob_feature = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
+		tf->hob_nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
+		tf->hob_lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
+		tf->hob_lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
+		tf->hob_lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
+		pi->proto->write_regr(pi, 1, 6, tf->ctl);
+		ap->last_ctl = tf->ctl;
+	}
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+}
+
+static void pata_parport_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	pi->proto->write_regr(pi, 0, ATA_REG_CMD, tf->command);
+	ata_sff_pause(ap);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+}
+
+static unsigned int pata_parport_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf,
+					   unsigned int buflen, int rw)
+{
+	struct ata_port *ap = qc->dev->link->ap;
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	if (rw == READ)
+		pi->proto->read_block(pi, buf, buflen);
+	else
+		pi->proto->write_block(pi, buf, buflen);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+
+	return buflen;
+}
+
+static void pata_parport_drain_fifo(struct ata_queued_cmd *qc)
+{
+	int count;
+	struct ata_port *ap;
+	struct pi_adapter *pi;
+	char junk[2];
+
+	/* We only need to flush incoming data when a command was running */
+	if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
+		return;
+
+	ap = qc->ap;
+	pi = ap->host->private_data;
+	/* Drain up to 64K of data before we give up this recovery method */
+	for (count = 0; (pata_parport_check_status(ap) & ATA_DRQ)
+						&& count < 65536; count += 2) {
+		pi_connect(pi);
+		pi->proto->read_block(pi, junk, 2);
+		mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+	}
+
+	if (count)
+		ata_port_dbg(ap, "drained %d bytes to clear DRQ\n", count);
+}
+
+static void pata_parport_lost_interrupt(struct ata_port *ap)
+{
+	u8 status;
+	struct ata_queued_cmd *qc;
+
+	/* Only one outstanding command per SFF channel */
+	qc = ata_qc_from_tag(ap, ap->link.active_tag);
+	/* We cannot lose an interrupt on a non-existent or polled command */
+	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
+		return;
+	/*
+	 * See if the controller thinks it is still busy - if so the command
+	 * isn't a lost IRQ but is still in progress
+	 */
+	status = pata_parport_check_altstatus(ap);
+	if (status & ATA_BUSY)
+		return;
+
+	/*
+	 * There was a command running, we are no longer busy and we have
+	 * no interrupt.
+	 */
+	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
+	/* Run the host interrupt logic as if the interrupt had not been lost */
+	ata_sff_port_intr(ap, qc);
+}
+
+static struct ata_port_operations pata_parport_port_ops = {
+	.inherits		= &ata_sff_port_ops,
+
+	.softreset		= pata_parport_softreset,
+	.hardreset		= NULL,
+
+	.sff_dev_select		= pata_parport_dev_select,
+	.sff_check_status	= pata_parport_check_status,
+	.sff_check_altstatus	= pata_parport_check_altstatus,
+	.sff_tf_load		= pata_parport_tf_load,
+	.sff_tf_read		= pata_parport_tf_read,
+	.sff_exec_command	= pata_parport_exec_command,
+	.sff_data_xfer		= pata_parport_data_xfer,
+	.sff_drain_fifo		= pata_parport_drain_fifo,
+
+	.lost_interrupt		= pata_parport_lost_interrupt,
+};
+
+static const struct ata_port_info pata_parport_port_info = {
+	.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_POLLING,
+	.pio_mask	= ATA_PIO0,
+	/* No DMA */
+	.port_ops	= &pata_parport_port_ops,
+};
+
+static void pi_release(struct pi_adapter *pi)
+{
+	parport_unregister_device(pi->pardev);
+	if (pi->proto->release_proto)
+		pi->proto->release_proto(pi);
+	module_put(pi->proto->owner);
+}
+
+static int default_test_proto(struct pi_adapter *pi, char *scratch)
+{
+	int j, k;
+	int e[2] = { 0, 0 };
+
+	pi->proto->connect(pi);
+
+	for (j = 0; j < 2; j++) {
+		pi->proto->write_regr(pi, 0, 6, 0xa0 + j * 0x10);
+		for (k = 0; k < 256; k++) {
+			pi->proto->write_regr(pi, 0, 2, k ^ 0xaa);
+			pi->proto->write_regr(pi, 0, 3, k ^ 0x55);
+			if (pi->proto->read_regr(pi, 0, 2) != (k ^ 0xaa))
+				e[j]++;
+		}
+	}
+	pi->proto->disconnect(pi);
+
+	if (verbose)
+		dev_info(&pi->dev, "%s: port 0x%x, mode %d, test=(%d,%d)\n",
+		       pi->proto->name, pi->port,
+		       pi->mode, e[0], e[1]);
+
+	return e[0] && e[1];	/* not here if both > 0 */
+}
+
+static int pi_test_proto(struct pi_adapter *pi, char *scratch)
+{
+	int res;
+
+	parport_claim_or_block(pi->pardev);
+	if (pi->proto->test_proto)
+		res = pi->proto->test_proto(pi, scratch, verbose);
+	else
+		res = default_test_proto(pi, scratch);
+	parport_release(pi->pardev);
+
+	return res;
+}
+
+static bool pi_probe_mode(struct pi_adapter *pi, int max, char *scratch)
+{
+	int best, range;
+
+	if (pi->mode != -1) {
+		if (pi->mode >= max)
+			return false;
+		range = 3;
+		if (pi->mode >= pi->proto->epp_first)
+			range = 8;
+		if (range == 8 && pi->port % 8)
+			return false;
+		return !pi_test_proto(pi, scratch);
+	}
+	best = -1;
+	for (pi->mode = 0; pi->mode < max; pi->mode++) {
+		range = 3;
+		if (pi->mode >= pi->proto->epp_first)
+			range = 8;
+		if (range == 8 && pi->port % 8)
+			break;
+		if (!pi_test_proto(pi, scratch))
+			best = pi->mode;
+	}
+	pi->mode = best;
+	return best > -1;
+}
+
+static bool pi_probe_unit(struct pi_adapter *pi, int unit, char *scratch)
+{
+	int max, s, e;
+
+	s = unit;
+	e = s + 1;
+
+	if (s == -1) {
+		s = 0;
+		e = pi->proto->max_units;
+	}
+
+	if (pi->proto->test_port) {
+		parport_claim_or_block(pi->pardev);
+		max = pi->proto->test_port(pi);
+		parport_release(pi->pardev);
+	} else {
+		max = pi->proto->max_mode;
+	}
+
+	if (pi->proto->probe_unit) {
+		parport_claim_or_block(pi->pardev);
+		for (pi->unit = s; pi->unit < e; pi->unit++) {
+			if (pi->proto->probe_unit(pi)) {
+				parport_release(pi->pardev);
+				return pi_probe_mode(pi, max, scratch);
+			}
+		}
+		parport_release(pi->pardev);
+		return false;
+	}
+
+	return pi_probe_mode(pi, max, scratch);
+}
+
+static void pata_parport_dev_release(struct device *dev)
+{
+	struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
+
+	kfree(pi);
+}
+
+static void pata_parport_bus_release(struct device *dev)
+{
+	/* nothing to do here but required to avoid warning on device removal */
+}
+
+static struct bus_type pata_parport_bus_type = {
+	.name = DRV_NAME,
+};
+
+static struct device pata_parport_bus = {
+	.init_name = DRV_NAME,
+	.release = pata_parport_bus_release,
+};
+
+/* temporary for old paride protocol modules */
+static struct scsi_host_template pata_parport_sht = {
+	PATA_PARPORT_SHT("pata_parport")
+};
+
+static struct pi_adapter *pi_init_one(struct parport *parport,
+			struct pi_protocol *pr, int mode, int unit, int delay)
+{
+	struct pardev_cb par_cb = { };
+	char scratch[512];
+	const struct ata_port_info *ppi[] = { &pata_parport_port_info };
+	struct ata_host *host;
+	struct pi_adapter *pi;
+
+	pi = kzalloc(sizeof(struct pi_adapter), GFP_KERNEL);
+	if (!pi)
+		return NULL;
+
+	/* set up pi->dev before pi_probe_unit() so it can use dev_printk() */
+	pi->dev.parent = &pata_parport_bus;
+	pi->dev.bus = &pata_parport_bus_type;
+	pi->dev.driver = &pr->driver;
+	pi->dev.release = pata_parport_dev_release;
+	pi->dev.id = ida_alloc(&pata_parport_bus_dev_ids, GFP_KERNEL);
+	if (pi->dev.id < 0)
+		return NULL; /* pata_parport_dev_release will do kfree(pi) */
+	dev_set_name(&pi->dev, "pata_parport.%u", pi->dev.id);
+	if (device_register(&pi->dev)) {
+		put_device(&pi->dev);
+		goto out_ida_free;
+	}
+
+	pi->proto = pr;
+
+	if (!try_module_get(pi->proto->owner))
+		goto out_unreg_dev;
+	if (pi->proto->init_proto && pi->proto->init_proto(pi) < 0)
+		goto out_module_put;
+
+	pi->delay = (delay == -1) ? pi->proto->default_delay : delay;
+	pi->mode = mode;
+	pi->port = parport->base;
+
+	par_cb.private = pi;
+	pi->pardev = parport_register_dev_model(parport, dev_name(&pi->dev),
+						&par_cb, pi->dev.id);
+	if (!pi->pardev)
+		goto out_module_put;
+
+	if (!pi_probe_unit(pi, unit, scratch)) {
+		dev_info(&pi->dev, "Adapter not found\n");
+		goto out_unreg_parport;
+	}
+
+	pi->proto->log_adapter(pi, scratch, verbose);
+
+	host = ata_host_alloc_pinfo(&pi->dev, ppi, 1);
+	if (!host)
+		goto out_unreg_parport;
+	dev_set_drvdata(&pi->dev, host);
+	host->private_data = pi;
+
+	ata_port_desc(host->ports[0], "port %s", pi->pardev->port->name);
+	ata_port_desc(host->ports[0], "protocol %s", pi->proto->name);
+
+	timer_setup(&pi->timer, pi_disconnect_timer, 0);
+
+	if (ata_host_activate(host, 0, NULL, 0, &pata_parport_sht))
+		goto out_unreg_parport;
+
+	return pi;
+
+out_unreg_parport:
+	parport_unregister_device(pi->pardev);
+	if (pi->proto->release_proto)
+		pi->proto->release_proto(pi);
+out_module_put:
+	module_put(pi->proto->owner);
+out_unreg_dev:
+	device_unregister(&pi->dev);
+out_ida_free:
+	ida_free(&pata_parport_bus_dev_ids, pi->dev.id);
+	return NULL;
+}
+
+int pata_parport_register_driver(struct pi_protocol *pr)
+{
+	int error;
+	struct parport *parport;
+	int port_num;
+
+	pr->driver.bus = &pata_parport_bus_type;
+	pr->driver.name = pr->name;
+	error = driver_register(&pr->driver);
+	if (error)
+		return error;
+
+	mutex_lock(&pi_mutex);
+	error = idr_alloc(&protocols, pr, 0, 0, GFP_KERNEL);
+	if (error < 0) {
+		driver_unregister(&pr->driver);
+		mutex_unlock(&pi_mutex);
+		return error;
+	}
+
+	pr_info("pata_parport: protocol %s registered\n", pr->name);
+
+	if (probe) {
+		/* probe all parports using this protocol */
+		idr_for_each_entry(&parport_list, parport, port_num)
+			pi_init_one(parport, pr, -1, 0, -1);
+	}
+	mutex_unlock(&pi_mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL(pata_parport_register_driver);
+
+void pata_parport_unregister_driver(struct pi_protocol *pr)
+{
+	struct pi_protocol *pr_iter;
+	int id = -1;
+
+	mutex_lock(&pi_mutex);
+	idr_for_each_entry(&protocols, pr_iter, id) {
+		if (pr_iter == pr)
+			break;
+	}
+	idr_remove(&protocols, id);
+	mutex_unlock(&pi_mutex);
+	driver_unregister(&pr->driver);
+}
+EXPORT_SYMBOL(pata_parport_unregister_driver);
+
+static ssize_t new_device_store(struct bus_type *bus, const char *buf, size_t count)
+{
+	char port[12] = "auto";
+	char protocol[8] = "auto";
+	int mode = -1, unit = -1, delay = -1;
+	struct pi_protocol *pr, *pr_wanted;
+	struct device_driver *drv;
+	struct parport *parport;
+	int port_num, port_wanted, pr_num;
+	bool ok = false;
+
+	if (sscanf(buf, "%11s %7s %d %d %d",
+			port, protocol, &mode, &unit, &delay) < 1)
+		return -EINVAL;
+
+	if (sscanf(port, "parport%u", &port_wanted) < 1) {
+		if (!strcmp(port, "auto")) {
+			port_wanted = -1;
+		} else {
+			pr_err("invalid port name %s\n", port);
+			return -EINVAL;
+		}
+	}
+
+	drv = driver_find(protocol, &pata_parport_bus_type);
+	if (!drv) {
+		if (!strcmp(protocol, "auto")) {
+			pr_wanted = NULL;
+		} else {
+			pr_err("protocol %s not found\n", protocol);
+			return -EINVAL;
+		}
+	} else {
+		pr_wanted = container_of(drv, struct pi_protocol, driver);
+	}
+
+	mutex_lock(&pi_mutex);
+	/* walk all parports */
+	idr_for_each_entry(&parport_list, parport, port_num) {
+		if (port_num == port_wanted || port_wanted == -1) {
+			parport = parport_find_number(port_num);
+			if (!parport) {
+				pr_err("no such port %s\n", port);
+				mutex_unlock(&pi_mutex);
+				return -ENODEV;
+			}
+			/* walk all protocols */
+			idr_for_each_entry(&protocols, pr, pr_num) {
+				if (pr == pr_wanted || !pr_wanted)
+					if (pi_init_one(parport, pr, mode, unit,
+							delay))
+						ok = true;
+			}
+			parport_put_port(parport);
+		}
+	}
+	mutex_unlock(&pi_mutex);
+	if (!ok)
+		return -ENODEV;
+
+	return count;
+}
+static BUS_ATTR_WO(new_device);
+
+static void pi_remove_one(struct device *dev)
+{
+	struct ata_host *host = dev_get_drvdata(dev);
+	struct pi_adapter *pi = host->private_data;
+
+	ata_host_detach(host);
+	del_timer_sync(&pi->timer);
+	if (pi->claimed) {
+		pi->proto->disconnect(pi);
+		parport_release(pi->pardev);
+	}
+	pi_release(pi);
+	device_unregister(dev);
+	ida_free(&pata_parport_bus_dev_ids, dev->id);
+	/* pata_parport_dev_release will do kfree(pi) */
+}
+
+static ssize_t delete_device_store(struct bus_type *bus, const char *buf, size_t count)
+{
+	struct device *dev;
+	char device_name[32];
+
+	if (sscanf(buf, "%31s", device_name) < 1)
+		return -EINVAL;
+
+	mutex_lock(&pi_mutex);
+	dev = bus_find_device_by_name(bus, NULL, device_name);
+	if (!dev) {
+		mutex_unlock(&pi_mutex);
+		return -ENODEV;
+	}
+
+	pi_remove_one(dev);
+	mutex_unlock(&pi_mutex);
+
+	return count;
+}
+static BUS_ATTR_WO(delete_device);
+
+static void pata_parport_attach(struct parport *port)
+{
+	struct pi_protocol *pr;
+	int pr_num, id;
+
+	mutex_lock(&pi_mutex);
+	id = idr_alloc(&parport_list, port, port->number, port->number, GFP_KERNEL);
+	if (id < 0) {
+		mutex_unlock(&pi_mutex);
+		return;
+	}
+
+	if (probe) {
+		/* probe this port using all protocols */
+		idr_for_each_entry(&protocols, pr, pr_num)
+			pi_init_one(port, pr, -1, 0, -1);
+	}
+	mutex_unlock(&pi_mutex);
+}
+
+static int pi_remove_port(struct device *dev, void *p)
+{
+	struct ata_host *host = dev_get_drvdata(dev);
+	struct pi_adapter *pi = host->private_data;
+
+	if (pi->pardev->port == p)
+		pi_remove_one(dev);
+
+	return 0;
+}
+
+static void pata_parport_detach(struct parport *port)
+{
+	mutex_lock(&pi_mutex);
+	bus_for_each_dev(&pata_parport_bus_type, NULL, port, pi_remove_port);
+	idr_remove(&parport_list, port->number);
+	mutex_unlock(&pi_mutex);
+}
+
+static struct parport_driver pata_parport_driver = {
+	.name = DRV_NAME,
+	.match_port = pata_parport_attach,
+	.detach = pata_parport_detach,
+	.devmodel = true,
+};
+
+static __init int pata_parport_init(void)
+{
+	int error;
+
+	error = bus_register(&pata_parport_bus_type);
+	if (error) {
+		pr_err("failed to register pata_parport bus, error: %d\n", error);
+		return error;
+	}
+
+	error = device_register(&pata_parport_bus);
+	if (error) {
+		pr_err("failed to register pata_parport bus, error: %d\n", error);
+		goto out_unregister_bus;
+	}
+
+	error = bus_create_file(&pata_parport_bus_type, &bus_attr_new_device);
+	if (error) {
+		pr_err("unable to create sysfs file, error: %d\n", error);
+		goto out_unregister_dev;
+	}
+
+	error = bus_create_file(&pata_parport_bus_type, &bus_attr_delete_device);
+	if (error) {
+		pr_err("unable to create sysfs file, error: %d\n", error);
+		goto out_remove_new;
+	}
+
+	error = parport_register_driver(&pata_parport_driver);
+	if (error) {
+		pr_err("unable to register parport driver, error: %d\n", error);
+		goto out_remove_del;
+	}
+
+	return 0;
+
+out_remove_del:
+	bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
+out_remove_new:
+	bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
+out_unregister_dev:
+	device_unregister(&pata_parport_bus);
+out_unregister_bus:
+	bus_unregister(&pata_parport_bus_type);
+	return error;
+}
+
+static __exit void pata_parport_exit(void)
+{
+	parport_unregister_driver(&pata_parport_driver);
+	bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
+	bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
+	device_unregister(&pata_parport_bus);
+	bus_unregister(&pata_parport_bus_type);
+}
+
+MODULE_AUTHOR("Ondrej Zary");
+MODULE_DESCRIPTION("driver for parallel port ATA adapters");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("paride");
+
+module_init(pata_parport_init);
+module_exit(pata_parport_exit);
diff --git a/drivers/ata/parport/pata_parport.h b/drivers/ata/parport/pata_parport.h
new file mode 100644
index 000000000000..d8d45f8bc742
--- /dev/null
+++ b/drivers/ata/parport/pata_parport.h
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ *	pata_parport.h	(c) 1997-8  Grant R. Guenther <grant at torque.net>
+ *				    Under the terms of the GPL.
+ *
+ * This file defines the interface for parallell port IDE adapter chip drivers.
+ */
+
+#include <linux/libata.h>
+
+#define PI_PCD	1	/* dummy for paride protocol modules */
+
+struct pi_adapter {
+	struct device dev;
+	struct pi_protocol *proto;	/* adapter protocol */
+	int port;			/* base address of parallel port */
+	int mode;			/* transfer mode in use */
+	int delay;			/* adapter delay setting */
+	int devtype;			/* dummy for paride protocol modules */
+	char *device;			/* dummy for paride protocol modules */
+	int unit;			/* unit number for chained adapters */
+	int saved_r0;			/* saved port state */
+	int saved_r2;			/* saved port state */
+	unsigned long private;		/* for protocol module */
+	struct pardevice *pardev;	/* pointer to pardevice */
+	bool claimed;			/* parport has already been claimed */
+	struct timer_list timer;	/* disconnect timer */
+};
+
+typedef struct pi_adapter PIA;	/* for paride protocol modules */
+
+/* registers are addressed as (cont,regr)
+ *	cont: 0 for command register file, 1 for control register(s)
+ *	regr: 0-7 for register number.
+ */
+
+/* macros and functions exported to the protocol modules */
+#define delay_p			(pi->delay ? udelay(pi->delay) : (void)0)
+#define out_p(offs, byte)	do { outb(byte, pi->port + offs); delay_p; } while (0)
+#define in_p(offs)		(delay_p, inb(pi->port + offs))
+
+#define w0(byte)		out_p(0, byte)
+#define r0()			(in_p(0) & 0xff)
+#define w1(byte)		out_p(1, byte)
+#define r1()			(in_p(1) & 0xff)
+#define w2(byte)		out_p(2, byte)
+#define r2()			(in_p(2) & 0xff)
+#define w3(byte)		out_p(3, byte)
+#define w4(byte)		out_p(4, byte)
+#define r4()			(in_p(4) & 0xff)
+#define w4w(data)		do { outw(data, pi->port + 4); delay_p; } while (0)
+#define w4l(data)		do { outl(data, pi->port + 4); delay_p; } while (0)
+#define r4w()			(delay_p, inw(pi->port + 4) & 0xffff)
+#define r4l()			(delay_p, inl(pi->port + 4) & 0xffffffff)
+
+static inline u16 pi_swab16(char *b, int k)
+{
+	union { u16 u; char t[2]; } r;
+
+	r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k];
+	return r.u;
+}
+
+static inline u32 pi_swab32(char *b, int k)
+{
+	union { u32 u; char f[4]; } r;
+
+	r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k];
+	r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2];
+	return r.u;
+}
+
+struct pi_protocol {
+	char name[8];
+
+	int max_mode;
+	int epp_first;		/* modes >= this use 8 ports */
+
+	int default_delay;
+	int max_units;		/* max chained units probed for */
+
+	void (*write_regr)(struct pi_adapter *pi, int cont, int regr, int val);
+	int (*read_regr)(struct pi_adapter *pi, int cont, int regr);
+	void (*write_block)(struct pi_adapter *pi, char *buf, int count);
+	void (*read_block)(struct pi_adapter *pi, char *buf, int count);
+
+	void (*connect)(struct pi_adapter *pi);
+	void (*disconnect)(struct pi_adapter *pi);
+
+	int (*test_port)(struct pi_adapter *pi);
+	int (*probe_unit)(struct pi_adapter *pi);
+	int (*test_proto)(struct pi_adapter *pi, char *scratch, int verbose);
+	void (*log_adapter)(struct pi_adapter *pi, char *scratch, int verbose);
+
+	int (*init_proto)(struct pi_adapter *pi);
+	void (*release_proto)(struct pi_adapter *pi);
+	struct module *owner;
+	struct device_driver driver;
+	struct scsi_host_template sht;
+};
+
+#define PATA_PARPORT_SHT ATA_PIO_SHT
+
+int pata_parport_register_driver(struct pi_protocol *pr);
+void pata_parport_unregister_driver(struct pi_protocol *pr);
+/* defines for old paride protocol modules */
+#define paride_register pata_parport_register_driver
+#define paride_unregister pata_parport_unregister_driver
diff --git a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig
index a295634597ba..01e4ef3655c1 100644
--- a/drivers/block/paride/Kconfig
+++ b/drivers/block/paride/Kconfig
@@ -92,11 +92,11 @@ config PARIDE_PG
 	  later fully support this driver.
 
 comment "Parallel IDE protocol modules"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 
 config PARIDE_ATEN
 	tristate "ATEN EH-100 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the ATEN EH-100 parallel port IDE
 	  protocol. This protocol is used in some inexpensive low performance
@@ -109,7 +109,7 @@ config PARIDE_ATEN
 
 config PARIDE_BPCK
 	tristate "MicroSolutions backpack (Series 5) protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the Micro Solutions BACKPACK
 	  parallel port Series 5 IDE protocol.  (Most BACKPACK drives made
@@ -127,7 +127,7 @@ config PARIDE_BPCK
 
 config PARIDE_BPCK6
 	tristate "MicroSolutions backpack (Series 6) protocol"
-	depends on PARIDE && !64BIT
+	depends on (PARIDE || PATA_PARPORT) && !64BIT
 	help
 	  This option enables support for the Micro Solutions BACKPACK
 	  parallel port Series 6 IDE protocol.  (Most BACKPACK drives made
@@ -146,7 +146,7 @@ config PARIDE_BPCK6
 
 config PARIDE_COMM
 	tristate "DataStor Commuter protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the Commuter parallel port IDE
 	  protocol from DataStor. If you chose to build PARIDE support
@@ -157,7 +157,7 @@ config PARIDE_COMM
 
 config PARIDE_DSTR
 	tristate "DataStor EP-2000 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the EP-2000 parallel port IDE
 	  protocol from DataStor. If you chose to build PARIDE support
@@ -168,7 +168,7 @@ config PARIDE_DSTR
 
 config PARIDE_FIT2
 	tristate "FIT TD-2000 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the TD-2000 parallel port IDE
 	  protocol from Fidelity International Technology. This is a simple
@@ -181,7 +181,7 @@ config PARIDE_FIT2
 
 config PARIDE_FIT3
 	tristate "FIT TD-3000 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the TD-3000 parallel port IDE
 	  protocol from Fidelity International Technology. This protocol is
@@ -194,7 +194,7 @@ config PARIDE_FIT3
 
 config PARIDE_EPAT
 	tristate "Shuttle EPAT/EPEZ protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the EPAT parallel port IDE protocol.
 	  EPAT is a parallel port IDE adapter manufactured by Shuttle
@@ -216,7 +216,7 @@ config PARIDE_EPATC8
 
 config PARIDE_EPIA
 	tristate "Shuttle EPIA protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the (obsolete) EPIA parallel port
 	  IDE protocol from Shuttle Technology. This adapter can still be
@@ -228,7 +228,7 @@ config PARIDE_EPIA
 
 config PARIDE_FRIQ
 	tristate "Freecom IQ ASIC-2 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for version 2 of the Freecom IQ parallel
 	  port IDE adapter.  This adapter is used by the Maxell Superdisk
@@ -240,7 +240,7 @@ config PARIDE_FRIQ
 
 config PARIDE_FRPW
 	tristate "FreeCom power protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the Freecom power parallel port IDE
 	  protocol. If you chose to build PARIDE support into your kernel, you
@@ -251,7 +251,7 @@ config PARIDE_FRPW
 
 config PARIDE_KBIC
 	tristate "KingByte KBIC-951A/971A protocols"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the KBIC-951A and KBIC-971A parallel
 	  port IDE protocols from KingByte Information Corp. KingByte's
@@ -264,7 +264,7 @@ config PARIDE_KBIC
 
 config PARIDE_KTTI
 	tristate "KT PHd protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the "PHd" parallel port IDE protocol
 	  from KT Technology. This is a simple (low speed) adapter that is
@@ -277,7 +277,7 @@ config PARIDE_KTTI
 
 config PARIDE_ON20
 	tristate "OnSpec 90c20 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the (obsolete) 90c20 parallel port
 	  IDE protocol from OnSpec (often marketed under the ValuStore brand
@@ -289,7 +289,7 @@ config PARIDE_ON20
 
 config PARIDE_ON26
 	tristate "OnSpec 90c26 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the 90c26 parallel port IDE protocol
 	  from OnSpec Electronics (often marketed under the ValuStore brand
diff --git a/drivers/block/paride/paride.h b/drivers/block/paride/paride.h
index ddb9e589da7f..f3bd01a9c9ec 100644
--- a/drivers/block/paride/paride.h
+++ b/drivers/block/paride/paride.h
@@ -1,3 +1,7 @@
+#if IS_ENABLED(CONFIG_PATA_PARPORT)
+#include "../../ata/parport/pata_parport.h"
+
+#else
 #ifndef __DRIVERS_PARIDE_H__
 #define __DRIVERS_PARIDE_H__
 
@@ -170,3 +174,4 @@ void pi_unregister_driver(void *);
 
 #endif /* __DRIVERS_PARIDE_H__ */
 /* end of paride.h */
+#endif /* IS_ENABLED(CONFIG_PATA_PARPORT) */
-- 
Ondrej Zary



From damien.lemoal at opensource.wdc.com  Thu Mar 10 15:59:20 2022
From: damien.lemoal at opensource.wdc.com (Damien Le Moal)
Date: Fri, 11 Mar 2022 08:59:20 +0900
Subject: [Linux-parport] [PATCH v0] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <20220310212812.13944-1-linux@zary.sk>
References: <20220310212812.13944-1-linux@zary.sk>
Message-ID: <e41b526d-18d4-ae05-976d-3021e739cd8e@opensource.wdc.com>

On 3/11/22 06:28, Ondrej Zary wrote:
> Add pata_parport (PARIDE replacement) core libata driver.
> 
> The original paride protocol modules are used for now so allow them to
> be compiled without old PARIDE core.
> 
> Signed-off-by: Ondrej Zary <linux at zary.sk>
> ---
>  drivers/Makefile                   |   2 +-
>  drivers/ata/Kconfig                |  22 +
>  drivers/ata/Makefile               |   2 +
>  drivers/ata/parport/Makefile       |   3 +
>  drivers/ata/parport/pata_parport.c | 805 +++++++++++++++++++++++++++++
>  drivers/ata/parport/pata_parport.h | 108 ++++
>  drivers/block/paride/Kconfig       |  32 +-
>  drivers/block/paride/paride.h      |   5 +
>  8 files changed, 962 insertions(+), 17 deletions(-)
>  create mode 100644 drivers/ata/parport/Makefile
>  create mode 100644 drivers/ata/parport/pata_parport.c
>  create mode 100644 drivers/ata/parport/pata_parport.h
> 
> diff --git a/drivers/Makefile b/drivers/Makefile
> index a110338c860c..8ec515f3614e 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -98,7 +98,7 @@ obj-$(CONFIG_DIO)		+= dio/
>  obj-$(CONFIG_SBUS)		+= sbus/
>  obj-$(CONFIG_ZORRO)		+= zorro/
>  obj-$(CONFIG_ATA_OVER_ETH)	+= block/aoe/
> -obj-$(CONFIG_PARIDE) 		+= block/paride/
> +obj-y		 		+= block/paride/
>  obj-$(CONFIG_TC)		+= tc/
>  obj-$(CONFIG_USB_PHY)		+= usb/
>  obj-$(CONFIG_USB)		+= usb/
> diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
> index e5641e6c52ee..671c27b77a48 100644
> --- a/drivers/ata/Kconfig
> +++ b/drivers/ata/Kconfig
> @@ -1161,6 +1161,28 @@ config PATA_WINBOND_VLB
>  	  Support for the Winbond W83759A controller on Vesa Local Bus
>  	  systems.
>  
> +config PATA_PARPORT
> +	tristate "Parallel port IDE device support"
> +	depends on PARPORT_PC && PARIDE=n

This is very confusing. The change above this one switch paride
compilation to be unconditional, regardless of CONFIG_PARIDE value, but
here, you have the dependency to PARIDE=n. I do not understand... Please
clarify.

The commit message is also way too light given the size of this patch.
Better explanation is needed.

> +	help
> +	  There are many external CD-ROM and disk devices that connect through
> +	  your computer's parallel port. Most of them are actually IDE devices
> +	  using a parallel port IDE adapter. This option enables the
> +	  PATA_PARPORT subsystem which contains drivers for many of these
> +	  external drives.
> +	  Read <file:Documentation/admin-guide/blockdev/paride.rst> for more
> +	  information.
> +
> +	  If your parallel port support is in a loadable module, you must build
> +	  PATA_PARPORT as a module. If you built PATA_PARPORT support into your
> +	  kernel, you may still build the individual protocol modules
> +	  as loadable modules. Use the old PARIDE protocol modules.
> +	  If you build this support as a module, it will be called pata_parport.
> +
> +	  Unlike the old PARIDE, there are no high-level drivers needed.
> +	  The IDE devices behind parallel port adapters are handled by the
> +	  ATA layer.
> +
>  comment "Generic fallback / legacy drivers"
>  
>  config PATA_ACPI
> diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
> index b8aebfb14e82..171045578541 100644
> --- a/drivers/ata/Makefile
> +++ b/drivers/ata/Makefile
> @@ -114,6 +114,8 @@ obj-$(CONFIG_PATA_SAMSUNG_CF)	+= pata_samsung_cf.o
>  
>  obj-$(CONFIG_PATA_PXA)		+= pata_pxa.o
>  
> +obj-$(CONFIG_PATA_PARPORT)	+= parport/
> +
>  # Should be last but two libata driver
>  obj-$(CONFIG_PATA_ACPI)		+= pata_acpi.o
>  # Should be last but one libata driver
> diff --git a/drivers/ata/parport/Makefile b/drivers/ata/parport/Makefile
> new file mode 100644
> index 000000000000..3ec4a4a66e26
> --- /dev/null
> +++ b/drivers/ata/parport/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_PATA_PARPORT)		+= pata_parport.o
> diff --git a/drivers/ata/parport/pata_parport.c b/drivers/ata/parport/pata_parport.c
> new file mode 100644
> index 000000000000..3ea8d824091e
> --- /dev/null
> +++ b/drivers/ata/parport/pata_parport.c
> @@ -0,0 +1,805 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/parport.h>
> +#include "pata_parport.h"
> +
> +#define DRV_NAME "pata_parport"
> +
> +static DEFINE_IDR(parport_list);
> +static DEFINE_IDR(protocols);
> +static DEFINE_IDA(pata_parport_bus_dev_ids);
> +static DEFINE_MUTEX(pi_mutex);
> +
> +static bool probe = true;
> +module_param(probe, bool, 0644);
> +MODULE_PARM_DESC(probe, "Enable automatic device probing (0=off, 1=on [default])");
> +
> +static bool verbose;
> +module_param(verbose, bool, 0644);
> +MODULE_PARM_DESC(verbose, "Enable verbose messages (0=off [default], 1=on)");
> +
> +#define DISCONNECT_TIMEOUT	(HZ / 10)
> +
> +static void pi_connect(struct pi_adapter *pi)
> +{
> +	del_timer_sync(&pi->timer);
> +	if (!pi->claimed) {
> +		pi->claimed = true;
> +		parport_claim_or_block(pi->pardev);
> +		pi->proto->connect(pi);
> +	}
> +}
> +
> +static void pi_disconnect_timer(struct timer_list *t)
> +{
> +	struct pi_adapter *pi = from_timer(pi, t, timer);
> +
> +	if (pi->claimed) {
> +		pi->proto->disconnect(pi);
> +		parport_release(pi->pardev);
> +		pi->claimed = false;
> +	}
> +}
> +
> +/* functions taken from libata-sff.c and converted from direct port I/O */
> +static void pata_parport_dev_select(struct ata_port *ap, unsigned int device)
> +{
> +	struct pi_adapter *pi = ap->host->private_data;
> +	u8 tmp;
> +
> +	if (device == 0)
> +		tmp = ATA_DEVICE_OBS;
> +	else
> +		tmp = ATA_DEVICE_OBS | ATA_DEV1;
> +
> +	pi_connect(pi);
> +	pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tmp);
> +	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
> +	ata_sff_pause(ap);
> +}
> +
> +static bool pata_parport_devchk(struct ata_port *ap, unsigned int device)
> +{
> +	struct pi_adapter *pi = ap->host->private_data;
> +	u8 nsect, lbal;
> +
> +	pata_parport_dev_select(ap, device);
> +
> +	pi_connect(pi);
> +	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0x55);
> +	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
> +
> +	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0xaa);
> +	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0x55);
> +
> +	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 055);
> +	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
> +
> +	nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
> +	lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
> +	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
> +
> +	if ((nsect == 0x55) && (lbal == 0xaa))
> +		return true;	/* we found a device */
> +
> +	return false;		/* nothing found */
> +}
> +
> +static int pata_parport_bus_softreset(struct ata_port *ap, unsigned int devmask,
> +				      unsigned long deadline)
> +{
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	/* software reset.  causes dev0 to be selected */
> +	pi->proto->write_regr(pi, 1, 6, ap->ctl);
> +	udelay(20);
> +	pi->proto->write_regr(pi, 1, 6, ap->ctl | ATA_SRST);
> +	udelay(20);
> +	pi->proto->write_regr(pi, 1, 6, ap->ctl);
> +	ap->last_ctl = ap->ctl;
> +	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
> +
> +	/* wait the port to become ready */
> +	return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
> +}
> +
> +static int pata_parport_softreset(struct ata_link *link, unsigned int *classes,
> +				  unsigned long deadline)
> +{
> +	struct ata_port *ap = link->ap;
> +	unsigned int devmask = 0;
> +	int rc;
> +	u8 err;
> +
> +	/* determine if device 0/1 are present */
> +	if (pata_parport_devchk(ap, 0))
> +		devmask |= (1 << 0);
> +	if (pata_parport_devchk(ap, 1))
> +		devmask |= (1 << 1);
> +
> +	/* select device 0 again */
> +	pata_parport_dev_select(ap, 0);
> +
> +	/* issue bus reset */
> +	rc = pata_parport_bus_softreset(ap, devmask, deadline);
> +	if (rc && rc != -ENODEV) {
> +		ata_link_err(link, "SRST failed (errno=%d)\n", rc);
> +		return rc;
> +	}
> +
> +	/* determine by signature whether we have ATA or ATAPI devices */
> +	classes[0] = ata_sff_dev_classify(&link->device[0],
> +					  devmask & (1 << 0), &err);
> +	if (err != 0x81)
> +		classes[1] = ata_sff_dev_classify(&link->device[1],
> +						  devmask & (1 << 1), &err);
> +
> +	return 0;
> +}
> +
> +static u8 pata_parport_check_status(struct ata_port *ap)
> +{
> +	u8 status;
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
> +	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
> +
> +	return status;
> +}
> +
> +static u8 pata_parport_check_altstatus(struct ata_port *ap)
> +{
> +	u8 altstatus;
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	altstatus = pi->proto->read_regr(pi, 1, 6);
> +	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
> +
> +	return altstatus;
> +}
> +
> +static void pata_parport_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
> +{
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	if (tf->ctl != ap->last_ctl) {
> +		pi->proto->write_regr(pi, 1, 6, tf->ctl);
> +		ap->last_ctl = tf->ctl;
> +		ata_wait_idle(ap);
> +	}
> +
> +	if (tf->flags & ATA_TFLAG_ISADDR) {
> +		if (tf->flags & ATA_TFLAG_LBA48) {
> +			pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->hob_feature);
> +			pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->hob_nsect);
> +			pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->hob_lbal);
> +			pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->hob_lbam);
> +			pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->hob_lbah);
> +		}
> +		pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->feature);
> +		pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->nsect);
> +		pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->lbal);
> +		pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->lbam);
> +		pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->lbah);
> +	}
> +
> +	if (tf->flags & ATA_TFLAG_DEVICE)
> +		pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tf->device);
> +
> +	ata_wait_idle(ap);
> +	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
> +}
> +
> +static void pata_parport_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
> +{
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	tf->status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
> +	tf->error = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
> +	tf->nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
> +	tf->lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
> +	tf->lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
> +	tf->lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
> +	tf->device = pi->proto->read_regr(pi, 0, ATA_REG_DEVICE);
> +
> +	if (tf->flags & ATA_TFLAG_LBA48) {
> +		pi->proto->write_regr(pi, 1, 6, tf->ctl | ATA_HOB);
> +		tf->hob_feature = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
> +		tf->hob_nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
> +		tf->hob_lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
> +		tf->hob_lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
> +		tf->hob_lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
> +		pi->proto->write_regr(pi, 1, 6, tf->ctl);
> +		ap->last_ctl = tf->ctl;
> +	}
> +	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
> +}
> +
> +static void pata_parport_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
> +{
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	pi->proto->write_regr(pi, 0, ATA_REG_CMD, tf->command);
> +	ata_sff_pause(ap);
> +	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
> +}
> +
> +static unsigned int pata_parport_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf,
> +					   unsigned int buflen, int rw)
> +{
> +	struct ata_port *ap = qc->dev->link->ap;
> +	struct pi_adapter *pi = ap->host->private_data;
> +
> +	pi_connect(pi);
> +	if (rw == READ)
> +		pi->proto->read_block(pi, buf, buflen);
> +	else
> +		pi->proto->write_block(pi, buf, buflen);
> +	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
> +
> +	return buflen;
> +}
> +
> +static void pata_parport_drain_fifo(struct ata_queued_cmd *qc)
> +{
> +	int count;
> +	struct ata_port *ap;
> +	struct pi_adapter *pi;
> +	char junk[2];
> +
> +	/* We only need to flush incoming data when a command was running */
> +	if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
> +		return;
> +
> +	ap = qc->ap;
> +	pi = ap->host->private_data;
> +	/* Drain up to 64K of data before we give up this recovery method */
> +	for (count = 0; (pata_parport_check_status(ap) & ATA_DRQ)
> +						&& count < 65536; count += 2) {
> +		pi_connect(pi);
> +		pi->proto->read_block(pi, junk, 2);
> +		mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
> +	}
> +
> +	if (count)
> +		ata_port_dbg(ap, "drained %d bytes to clear DRQ\n", count);
> +}
> +
> +static void pata_parport_lost_interrupt(struct ata_port *ap)
> +{
> +	u8 status;
> +	struct ata_queued_cmd *qc;
> +
> +	/* Only one outstanding command per SFF channel */
> +	qc = ata_qc_from_tag(ap, ap->link.active_tag);
> +	/* We cannot lose an interrupt on a non-existent or polled command */
> +	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
> +		return;
> +	/*
> +	 * See if the controller thinks it is still busy - if so the command
> +	 * isn't a lost IRQ but is still in progress
> +	 */
> +	status = pata_parport_check_altstatus(ap);
> +	if (status & ATA_BUSY)
> +		return;
> +
> +	/*
> +	 * There was a command running, we are no longer busy and we have
> +	 * no interrupt.
> +	 */
> +	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
> +	/* Run the host interrupt logic as if the interrupt had not been lost */
> +	ata_sff_port_intr(ap, qc);
> +}
> +
> +static struct ata_port_operations pata_parport_port_ops = {
> +	.inherits		= &ata_sff_port_ops,
> +
> +	.softreset		= pata_parport_softreset,
> +	.hardreset		= NULL,
> +
> +	.sff_dev_select		= pata_parport_dev_select,
> +	.sff_check_status	= pata_parport_check_status,
> +	.sff_check_altstatus	= pata_parport_check_altstatus,
> +	.sff_tf_load		= pata_parport_tf_load,
> +	.sff_tf_read		= pata_parport_tf_read,
> +	.sff_exec_command	= pata_parport_exec_command,
> +	.sff_data_xfer		= pata_parport_data_xfer,
> +	.sff_drain_fifo		= pata_parport_drain_fifo,
> +
> +	.lost_interrupt		= pata_parport_lost_interrupt,
> +};
> +
> +static const struct ata_port_info pata_parport_port_info = {
> +	.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_POLLING,
> +	.pio_mask	= ATA_PIO0,
> +	/* No DMA */
> +	.port_ops	= &pata_parport_port_ops,
> +};
> +
> +static void pi_release(struct pi_adapter *pi)
> +{
> +	parport_unregister_device(pi->pardev);
> +	if (pi->proto->release_proto)
> +		pi->proto->release_proto(pi);
> +	module_put(pi->proto->owner);
> +}
> +
> +static int default_test_proto(struct pi_adapter *pi, char *scratch)
> +{
> +	int j, k;
> +	int e[2] = { 0, 0 };
> +
> +	pi->proto->connect(pi);
> +
> +	for (j = 0; j < 2; j++) {
> +		pi->proto->write_regr(pi, 0, 6, 0xa0 + j * 0x10);
> +		for (k = 0; k < 256; k++) {
> +			pi->proto->write_regr(pi, 0, 2, k ^ 0xaa);
> +			pi->proto->write_regr(pi, 0, 3, k ^ 0x55);
> +			if (pi->proto->read_regr(pi, 0, 2) != (k ^ 0xaa))
> +				e[j]++;
> +		}
> +	}
> +	pi->proto->disconnect(pi);
> +
> +	if (verbose)
> +		dev_info(&pi->dev, "%s: port 0x%x, mode %d, test=(%d,%d)\n",
> +		       pi->proto->name, pi->port,
> +		       pi->mode, e[0], e[1]);
> +
> +	return e[0] && e[1];	/* not here if both > 0 */
> +}
> +
> +static int pi_test_proto(struct pi_adapter *pi, char *scratch)
> +{
> +	int res;
> +
> +	parport_claim_or_block(pi->pardev);
> +	if (pi->proto->test_proto)
> +		res = pi->proto->test_proto(pi, scratch, verbose);
> +	else
> +		res = default_test_proto(pi, scratch);
> +	parport_release(pi->pardev);
> +
> +	return res;
> +}
> +
> +static bool pi_probe_mode(struct pi_adapter *pi, int max, char *scratch)
> +{
> +	int best, range;
> +
> +	if (pi->mode != -1) {
> +		if (pi->mode >= max)
> +			return false;
> +		range = 3;
> +		if (pi->mode >= pi->proto->epp_first)
> +			range = 8;
> +		if (range == 8 && pi->port % 8)
> +			return false;
> +		return !pi_test_proto(pi, scratch);
> +	}
> +	best = -1;
> +	for (pi->mode = 0; pi->mode < max; pi->mode++) {
> +		range = 3;
> +		if (pi->mode >= pi->proto->epp_first)
> +			range = 8;
> +		if (range == 8 && pi->port % 8)
> +			break;
> +		if (!pi_test_proto(pi, scratch))
> +			best = pi->mode;
> +	}
> +	pi->mode = best;
> +	return best > -1;
> +}
> +
> +static bool pi_probe_unit(struct pi_adapter *pi, int unit, char *scratch)
> +{
> +	int max, s, e;
> +
> +	s = unit;
> +	e = s + 1;
> +
> +	if (s == -1) {
> +		s = 0;
> +		e = pi->proto->max_units;
> +	}
> +
> +	if (pi->proto->test_port) {
> +		parport_claim_or_block(pi->pardev);
> +		max = pi->proto->test_port(pi);
> +		parport_release(pi->pardev);
> +	} else {
> +		max = pi->proto->max_mode;
> +	}
> +
> +	if (pi->proto->probe_unit) {
> +		parport_claim_or_block(pi->pardev);
> +		for (pi->unit = s; pi->unit < e; pi->unit++) {
> +			if (pi->proto->probe_unit(pi)) {
> +				parport_release(pi->pardev);
> +				return pi_probe_mode(pi, max, scratch);
> +			}
> +		}
> +		parport_release(pi->pardev);
> +		return false;
> +	}
> +
> +	return pi_probe_mode(pi, max, scratch);
> +}
> +
> +static void pata_parport_dev_release(struct device *dev)
> +{
> +	struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
> +
> +	kfree(pi);
> +}
> +
> +static void pata_parport_bus_release(struct device *dev)
> +{
> +	/* nothing to do here but required to avoid warning on device removal */
> +}
> +
> +static struct bus_type pata_parport_bus_type = {
> +	.name = DRV_NAME,
> +};
> +
> +static struct device pata_parport_bus = {
> +	.init_name = DRV_NAME,
> +	.release = pata_parport_bus_release,
> +};
> +
> +/* temporary for old paride protocol modules */
> +static struct scsi_host_template pata_parport_sht = {
> +	PATA_PARPORT_SHT("pata_parport")
> +};
> +
> +static struct pi_adapter *pi_init_one(struct parport *parport,
> +			struct pi_protocol *pr, int mode, int unit, int delay)
> +{
> +	struct pardev_cb par_cb = { };
> +	char scratch[512];
> +	const struct ata_port_info *ppi[] = { &pata_parport_port_info };
> +	struct ata_host *host;
> +	struct pi_adapter *pi;
> +
> +	pi = kzalloc(sizeof(struct pi_adapter), GFP_KERNEL);
> +	if (!pi)
> +		return NULL;
> +
> +	/* set up pi->dev before pi_probe_unit() so it can use dev_printk() */
> +	pi->dev.parent = &pata_parport_bus;
> +	pi->dev.bus = &pata_parport_bus_type;
> +	pi->dev.driver = &pr->driver;
> +	pi->dev.release = pata_parport_dev_release;
> +	pi->dev.id = ida_alloc(&pata_parport_bus_dev_ids, GFP_KERNEL);
> +	if (pi->dev.id < 0)
> +		return NULL; /* pata_parport_dev_release will do kfree(pi) */
> +	dev_set_name(&pi->dev, "pata_parport.%u", pi->dev.id);
> +	if (device_register(&pi->dev)) {
> +		put_device(&pi->dev);
> +		goto out_ida_free;
> +	}
> +
> +	pi->proto = pr;
> +
> +	if (!try_module_get(pi->proto->owner))
> +		goto out_unreg_dev;
> +	if (pi->proto->init_proto && pi->proto->init_proto(pi) < 0)
> +		goto out_module_put;
> +
> +	pi->delay = (delay == -1) ? pi->proto->default_delay : delay;
> +	pi->mode = mode;
> +	pi->port = parport->base;
> +
> +	par_cb.private = pi;
> +	pi->pardev = parport_register_dev_model(parport, dev_name(&pi->dev),
> +						&par_cb, pi->dev.id);
> +	if (!pi->pardev)
> +		goto out_module_put;
> +
> +	if (!pi_probe_unit(pi, unit, scratch)) {
> +		dev_info(&pi->dev, "Adapter not found\n");
> +		goto out_unreg_parport;
> +	}
> +
> +	pi->proto->log_adapter(pi, scratch, verbose);
> +
> +	host = ata_host_alloc_pinfo(&pi->dev, ppi, 1);
> +	if (!host)
> +		goto out_unreg_parport;
> +	dev_set_drvdata(&pi->dev, host);
> +	host->private_data = pi;
> +
> +	ata_port_desc(host->ports[0], "port %s", pi->pardev->port->name);
> +	ata_port_desc(host->ports[0], "protocol %s", pi->proto->name);
> +
> +	timer_setup(&pi->timer, pi_disconnect_timer, 0);
> +
> +	if (ata_host_activate(host, 0, NULL, 0, &pata_parport_sht))
> +		goto out_unreg_parport;
> +
> +	return pi;
> +
> +out_unreg_parport:
> +	parport_unregister_device(pi->pardev);
> +	if (pi->proto->release_proto)
> +		pi->proto->release_proto(pi);
> +out_module_put:
> +	module_put(pi->proto->owner);
> +out_unreg_dev:
> +	device_unregister(&pi->dev);
> +out_ida_free:
> +	ida_free(&pata_parport_bus_dev_ids, pi->dev.id);
> +	return NULL;
> +}
> +
> +int pata_parport_register_driver(struct pi_protocol *pr)
> +{
> +	int error;
> +	struct parport *parport;
> +	int port_num;
> +
> +	pr->driver.bus = &pata_parport_bus_type;
> +	pr->driver.name = pr->name;
> +	error = driver_register(&pr->driver);
> +	if (error)
> +		return error;
> +
> +	mutex_lock(&pi_mutex);
> +	error = idr_alloc(&protocols, pr, 0, 0, GFP_KERNEL);
> +	if (error < 0) {
> +		driver_unregister(&pr->driver);
> +		mutex_unlock(&pi_mutex);
> +		return error;
> +	}
> +
> +	pr_info("pata_parport: protocol %s registered\n", pr->name);
> +
> +	if (probe) {
> +		/* probe all parports using this protocol */
> +		idr_for_each_entry(&parport_list, parport, port_num)
> +			pi_init_one(parport, pr, -1, 0, -1);
> +	}
> +	mutex_unlock(&pi_mutex);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(pata_parport_register_driver);
> +
> +void pata_parport_unregister_driver(struct pi_protocol *pr)
> +{
> +	struct pi_protocol *pr_iter;
> +	int id = -1;
> +
> +	mutex_lock(&pi_mutex);
> +	idr_for_each_entry(&protocols, pr_iter, id) {
> +		if (pr_iter == pr)
> +			break;
> +	}
> +	idr_remove(&protocols, id);
> +	mutex_unlock(&pi_mutex);
> +	driver_unregister(&pr->driver);
> +}
> +EXPORT_SYMBOL(pata_parport_unregister_driver);
> +
> +static ssize_t new_device_store(struct bus_type *bus, const char *buf, size_t count)
> +{
> +	char port[12] = "auto";
> +	char protocol[8] = "auto";
> +	int mode = -1, unit = -1, delay = -1;
> +	struct pi_protocol *pr, *pr_wanted;
> +	struct device_driver *drv;
> +	struct parport *parport;
> +	int port_num, port_wanted, pr_num;
> +	bool ok = false;
> +
> +	if (sscanf(buf, "%11s %7s %d %d %d",
> +			port, protocol, &mode, &unit, &delay) < 1)
> +		return -EINVAL;
> +
> +	if (sscanf(port, "parport%u", &port_wanted) < 1) {
> +		if (!strcmp(port, "auto")) {
> +			port_wanted = -1;
> +		} else {
> +			pr_err("invalid port name %s\n", port);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	drv = driver_find(protocol, &pata_parport_bus_type);
> +	if (!drv) {
> +		if (!strcmp(protocol, "auto")) {
> +			pr_wanted = NULL;
> +		} else {
> +			pr_err("protocol %s not found\n", protocol);
> +			return -EINVAL;
> +		}
> +	} else {
> +		pr_wanted = container_of(drv, struct pi_protocol, driver);
> +	}
> +
> +	mutex_lock(&pi_mutex);
> +	/* walk all parports */
> +	idr_for_each_entry(&parport_list, parport, port_num) {
> +		if (port_num == port_wanted || port_wanted == -1) {
> +			parport = parport_find_number(port_num);
> +			if (!parport) {
> +				pr_err("no such port %s\n", port);
> +				mutex_unlock(&pi_mutex);
> +				return -ENODEV;
> +			}
> +			/* walk all protocols */
> +			idr_for_each_entry(&protocols, pr, pr_num) {
> +				if (pr == pr_wanted || !pr_wanted)
> +					if (pi_init_one(parport, pr, mode, unit,
> +							delay))
> +						ok = true;
> +			}
> +			parport_put_port(parport);
> +		}
> +	}
> +	mutex_unlock(&pi_mutex);
> +	if (!ok)
> +		return -ENODEV;
> +
> +	return count;
> +}
> +static BUS_ATTR_WO(new_device);
> +
> +static void pi_remove_one(struct device *dev)
> +{
> +	struct ata_host *host = dev_get_drvdata(dev);
> +	struct pi_adapter *pi = host->private_data;
> +
> +	ata_host_detach(host);
> +	del_timer_sync(&pi->timer);
> +	if (pi->claimed) {
> +		pi->proto->disconnect(pi);
> +		parport_release(pi->pardev);
> +	}
> +	pi_release(pi);
> +	device_unregister(dev);
> +	ida_free(&pata_parport_bus_dev_ids, dev->id);
> +	/* pata_parport_dev_release will do kfree(pi) */
> +}
> +
> +static ssize_t delete_device_store(struct bus_type *bus, const char *buf, size_t count)
> +{
> +	struct device *dev;
> +	char device_name[32];
> +
> +	if (sscanf(buf, "%31s", device_name) < 1)
> +		return -EINVAL;
> +
> +	mutex_lock(&pi_mutex);
> +	dev = bus_find_device_by_name(bus, NULL, device_name);
> +	if (!dev) {
> +		mutex_unlock(&pi_mutex);
> +		return -ENODEV;
> +	}
> +
> +	pi_remove_one(dev);
> +	mutex_unlock(&pi_mutex);
> +
> +	return count;
> +}
> +static BUS_ATTR_WO(delete_device);
> +
> +static void pata_parport_attach(struct parport *port)
> +{
> +	struct pi_protocol *pr;
> +	int pr_num, id;
> +
> +	mutex_lock(&pi_mutex);
> +	id = idr_alloc(&parport_list, port, port->number, port->number, GFP_KERNEL);
> +	if (id < 0) {
> +		mutex_unlock(&pi_mutex);
> +		return;
> +	}
> +
> +	if (probe) {
> +		/* probe this port using all protocols */
> +		idr_for_each_entry(&protocols, pr, pr_num)
> +			pi_init_one(port, pr, -1, 0, -1);
> +	}
> +	mutex_unlock(&pi_mutex);
> +}
> +
> +static int pi_remove_port(struct device *dev, void *p)
> +{
> +	struct ata_host *host = dev_get_drvdata(dev);
> +	struct pi_adapter *pi = host->private_data;
> +
> +	if (pi->pardev->port == p)
> +		pi_remove_one(dev);
> +
> +	return 0;
> +}
> +
> +static void pata_parport_detach(struct parport *port)
> +{
> +	mutex_lock(&pi_mutex);
> +	bus_for_each_dev(&pata_parport_bus_type, NULL, port, pi_remove_port);
> +	idr_remove(&parport_list, port->number);
> +	mutex_unlock(&pi_mutex);
> +}
> +
> +static struct parport_driver pata_parport_driver = {
> +	.name = DRV_NAME,
> +	.match_port = pata_parport_attach,
> +	.detach = pata_parport_detach,
> +	.devmodel = true,
> +};
> +
> +static __init int pata_parport_init(void)
> +{
> +	int error;
> +
> +	error = bus_register(&pata_parport_bus_type);
> +	if (error) {
> +		pr_err("failed to register pata_parport bus, error: %d\n", error);
> +		return error;
> +	}
> +
> +	error = device_register(&pata_parport_bus);
> +	if (error) {
> +		pr_err("failed to register pata_parport bus, error: %d\n", error);
> +		goto out_unregister_bus;
> +	}
> +
> +	error = bus_create_file(&pata_parport_bus_type, &bus_attr_new_device);
> +	if (error) {
> +		pr_err("unable to create sysfs file, error: %d\n", error);
> +		goto out_unregister_dev;
> +	}
> +
> +	error = bus_create_file(&pata_parport_bus_type, &bus_attr_delete_device);
> +	if (error) {
> +		pr_err("unable to create sysfs file, error: %d\n", error);
> +		goto out_remove_new;
> +	}
> +
> +	error = parport_register_driver(&pata_parport_driver);
> +	if (error) {
> +		pr_err("unable to register parport driver, error: %d\n", error);
> +		goto out_remove_del;
> +	}
> +
> +	return 0;
> +
> +out_remove_del:
> +	bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
> +out_remove_new:
> +	bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
> +out_unregister_dev:
> +	device_unregister(&pata_parport_bus);
> +out_unregister_bus:
> +	bus_unregister(&pata_parport_bus_type);
> +	return error;
> +}
> +
> +static __exit void pata_parport_exit(void)
> +{
> +	parport_unregister_driver(&pata_parport_driver);
> +	bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
> +	bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
> +	device_unregister(&pata_parport_bus);
> +	bus_unregister(&pata_parport_bus_type);
> +}
> +
> +MODULE_AUTHOR("Ondrej Zary");
> +MODULE_DESCRIPTION("driver for parallel port ATA adapters");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("paride");
> +
> +module_init(pata_parport_init);
> +module_exit(pata_parport_exit);
> diff --git a/drivers/ata/parport/pata_parport.h b/drivers/ata/parport/pata_parport.h
> new file mode 100644
> index 000000000000..d8d45f8bc742
> --- /dev/null
> +++ b/drivers/ata/parport/pata_parport.h
> @@ -0,0 +1,108 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + *	pata_parport.h	(c) 1997-8  Grant R. Guenther <grant at torque.net>
> + *				    Under the terms of the GPL.
> + *
> + * This file defines the interface for parallell port IDE adapter chip drivers.
> + */
> +
> +#include <linux/libata.h>
> +
> +#define PI_PCD	1	/* dummy for paride protocol modules */
> +
> +struct pi_adapter {
> +	struct device dev;
> +	struct pi_protocol *proto;	/* adapter protocol */
> +	int port;			/* base address of parallel port */
> +	int mode;			/* transfer mode in use */
> +	int delay;			/* adapter delay setting */
> +	int devtype;			/* dummy for paride protocol modules */
> +	char *device;			/* dummy for paride protocol modules */
> +	int unit;			/* unit number for chained adapters */
> +	int saved_r0;			/* saved port state */
> +	int saved_r2;			/* saved port state */
> +	unsigned long private;		/* for protocol module */
> +	struct pardevice *pardev;	/* pointer to pardevice */
> +	bool claimed;			/* parport has already been claimed */
> +	struct timer_list timer;	/* disconnect timer */
> +};
> +
> +typedef struct pi_adapter PIA;	/* for paride protocol modules */
> +
> +/* registers are addressed as (cont,regr)
> + *	cont: 0 for command register file, 1 for control register(s)
> + *	regr: 0-7 for register number.
> + */
> +
> +/* macros and functions exported to the protocol modules */
> +#define delay_p			(pi->delay ? udelay(pi->delay) : (void)0)
> +#define out_p(offs, byte)	do { outb(byte, pi->port + offs); delay_p; } while (0)
> +#define in_p(offs)		(delay_p, inb(pi->port + offs))
> +
> +#define w0(byte)		out_p(0, byte)
> +#define r0()			(in_p(0) & 0xff)
> +#define w1(byte)		out_p(1, byte)
> +#define r1()			(in_p(1) & 0xff)
> +#define w2(byte)		out_p(2, byte)
> +#define r2()			(in_p(2) & 0xff)
> +#define w3(byte)		out_p(3, byte)
> +#define w4(byte)		out_p(4, byte)
> +#define r4()			(in_p(4) & 0xff)
> +#define w4w(data)		do { outw(data, pi->port + 4); delay_p; } while (0)
> +#define w4l(data)		do { outl(data, pi->port + 4); delay_p; } while (0)
> +#define r4w()			(delay_p, inw(pi->port + 4) & 0xffff)
> +#define r4l()			(delay_p, inl(pi->port + 4) & 0xffffffff)
> +
> +static inline u16 pi_swab16(char *b, int k)
> +{
> +	union { u16 u; char t[2]; } r;
> +
> +	r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k];
> +	return r.u;
> +}
> +
> +static inline u32 pi_swab32(char *b, int k)
> +{
> +	union { u32 u; char f[4]; } r;
> +
> +	r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k];
> +	r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2];
> +	return r.u;
> +}
> +
> +struct pi_protocol {
> +	char name[8];
> +
> +	int max_mode;
> +	int epp_first;		/* modes >= this use 8 ports */
> +
> +	int default_delay;
> +	int max_units;		/* max chained units probed for */
> +
> +	void (*write_regr)(struct pi_adapter *pi, int cont, int regr, int val);
> +	int (*read_regr)(struct pi_adapter *pi, int cont, int regr);
> +	void (*write_block)(struct pi_adapter *pi, char *buf, int count);
> +	void (*read_block)(struct pi_adapter *pi, char *buf, int count);
> +
> +	void (*connect)(struct pi_adapter *pi);
> +	void (*disconnect)(struct pi_adapter *pi);
> +
> +	int (*test_port)(struct pi_adapter *pi);
> +	int (*probe_unit)(struct pi_adapter *pi);
> +	int (*test_proto)(struct pi_adapter *pi, char *scratch, int verbose);
> +	void (*log_adapter)(struct pi_adapter *pi, char *scratch, int verbose);
> +
> +	int (*init_proto)(struct pi_adapter *pi);
> +	void (*release_proto)(struct pi_adapter *pi);
> +	struct module *owner;
> +	struct device_driver driver;
> +	struct scsi_host_template sht;
> +};
> +
> +#define PATA_PARPORT_SHT ATA_PIO_SHT
> +
> +int pata_parport_register_driver(struct pi_protocol *pr);
> +void pata_parport_unregister_driver(struct pi_protocol *pr);
> +/* defines for old paride protocol modules */
> +#define paride_register pata_parport_register_driver
> +#define paride_unregister pata_parport_unregister_driver
> diff --git a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig
> index a295634597ba..01e4ef3655c1 100644
> --- a/drivers/block/paride/Kconfig
> +++ b/drivers/block/paride/Kconfig
> @@ -92,11 +92,11 @@ config PARIDE_PG
>  	  later fully support this driver.
>  
>  comment "Parallel IDE protocol modules"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  
>  config PARIDE_ATEN
>  	tristate "ATEN EH-100 protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the ATEN EH-100 parallel port IDE
>  	  protocol. This protocol is used in some inexpensive low performance
> @@ -109,7 +109,7 @@ config PARIDE_ATEN
>  
>  config PARIDE_BPCK
>  	tristate "MicroSolutions backpack (Series 5) protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the Micro Solutions BACKPACK
>  	  parallel port Series 5 IDE protocol.  (Most BACKPACK drives made
> @@ -127,7 +127,7 @@ config PARIDE_BPCK
>  
>  config PARIDE_BPCK6
>  	tristate "MicroSolutions backpack (Series 6) protocol"
> -	depends on PARIDE && !64BIT
> +	depends on (PARIDE || PATA_PARPORT) && !64BIT
>  	help
>  	  This option enables support for the Micro Solutions BACKPACK
>  	  parallel port Series 6 IDE protocol.  (Most BACKPACK drives made
> @@ -146,7 +146,7 @@ config PARIDE_BPCK6
>  
>  config PARIDE_COMM
>  	tristate "DataStor Commuter protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the Commuter parallel port IDE
>  	  protocol from DataStor. If you chose to build PARIDE support
> @@ -157,7 +157,7 @@ config PARIDE_COMM
>  
>  config PARIDE_DSTR
>  	tristate "DataStor EP-2000 protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the EP-2000 parallel port IDE
>  	  protocol from DataStor. If you chose to build PARIDE support
> @@ -168,7 +168,7 @@ config PARIDE_DSTR
>  
>  config PARIDE_FIT2
>  	tristate "FIT TD-2000 protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the TD-2000 parallel port IDE
>  	  protocol from Fidelity International Technology. This is a simple
> @@ -181,7 +181,7 @@ config PARIDE_FIT2
>  
>  config PARIDE_FIT3
>  	tristate "FIT TD-3000 protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the TD-3000 parallel port IDE
>  	  protocol from Fidelity International Technology. This protocol is
> @@ -194,7 +194,7 @@ config PARIDE_FIT3
>  
>  config PARIDE_EPAT
>  	tristate "Shuttle EPAT/EPEZ protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the EPAT parallel port IDE protocol.
>  	  EPAT is a parallel port IDE adapter manufactured by Shuttle
> @@ -216,7 +216,7 @@ config PARIDE_EPATC8
>  
>  config PARIDE_EPIA
>  	tristate "Shuttle EPIA protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the (obsolete) EPIA parallel port
>  	  IDE protocol from Shuttle Technology. This adapter can still be
> @@ -228,7 +228,7 @@ config PARIDE_EPIA
>  
>  config PARIDE_FRIQ
>  	tristate "Freecom IQ ASIC-2 protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for version 2 of the Freecom IQ parallel
>  	  port IDE adapter.  This adapter is used by the Maxell Superdisk
> @@ -240,7 +240,7 @@ config PARIDE_FRIQ
>  
>  config PARIDE_FRPW
>  	tristate "FreeCom power protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the Freecom power parallel port IDE
>  	  protocol. If you chose to build PARIDE support into your kernel, you
> @@ -251,7 +251,7 @@ config PARIDE_FRPW
>  
>  config PARIDE_KBIC
>  	tristate "KingByte KBIC-951A/971A protocols"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the KBIC-951A and KBIC-971A parallel
>  	  port IDE protocols from KingByte Information Corp. KingByte's
> @@ -264,7 +264,7 @@ config PARIDE_KBIC
>  
>  config PARIDE_KTTI
>  	tristate "KT PHd protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the "PHd" parallel port IDE protocol
>  	  from KT Technology. This is a simple (low speed) adapter that is
> @@ -277,7 +277,7 @@ config PARIDE_KTTI
>  
>  config PARIDE_ON20
>  	tristate "OnSpec 90c20 protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the (obsolete) 90c20 parallel port
>  	  IDE protocol from OnSpec (often marketed under the ValuStore brand
> @@ -289,7 +289,7 @@ config PARIDE_ON20
>  
>  config PARIDE_ON26
>  	tristate "OnSpec 90c26 protocol"
> -	depends on PARIDE
> +	depends on PARIDE || PATA_PARPORT
>  	help
>  	  This option enables support for the 90c26 parallel port IDE protocol
>  	  from OnSpec Electronics (often marketed under the ValuStore brand
> diff --git a/drivers/block/paride/paride.h b/drivers/block/paride/paride.h
> index ddb9e589da7f..f3bd01a9c9ec 100644
> --- a/drivers/block/paride/paride.h
> +++ b/drivers/block/paride/paride.h
> @@ -1,3 +1,7 @@
> +#if IS_ENABLED(CONFIG_PATA_PARPORT)
> +#include "../../ata/parport/pata_parport.h"
> +
> +#else
>  #ifndef __DRIVERS_PARIDE_H__
>  #define __DRIVERS_PARIDE_H__
>  
> @@ -170,3 +174,4 @@ void pi_unregister_driver(void *);
>  
>  #endif /* __DRIVERS_PARIDE_H__ */
>  /* end of paride.h */
> +#endif /* IS_ENABLED(CONFIG_PATA_PARPORT) */


-- 
Damien Le Moal
Western Digital Research



From hch at lst.de  Thu Mar 10 21:45:55 2022
From: hch at lst.de (Christoph Hellwig)
Date: Fri, 11 Mar 2022 06:45:55 +0100
Subject: [Linux-parport] [PATCH v0] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <20220310212812.13944-1-linux@zary.sk>
References: <20220310212812.13944-1-linux@zary.sk>
Message-ID: <20220311054555.GA16362@lst.de>

On Thu, Mar 10, 2022 at 10:28:12PM +0100, Ondrej Zary wrote:
> Add pata_parport (PARIDE replacement) core libata driver.
> 
> The original paride protocol modules are used for now so allow them to
> be compiled without old PARIDE core.

I agree with Damien that this needs a bit more text here.  Explaining
what kind of hardware this drives, that this will allow to eventually
drop paride, how it reuesed the low-level drivers, etc.

> +	  If your parallel port support is in a loadable module, you must build
> +	  PATA_PARPORT as a module. If you built PATA_PARPORT support into your
> +	  kernel, you may still build the individual protocol modules
> +	  as loadable modules.

I'd drop the above.  The dependencies are already enforced by Kconfig
and we don't really tend to mention this elsewhere.

> +	  Unlike the old PARIDE, there are no high-level drivers needed.
> +	  The IDE devices behind parallel port adapters are handled by the
> +	  ATA layer.

I also don't think this is needed.

> index 000000000000..3ea8d824091e
> --- /dev/null
> +++ b/drivers/ata/parport/pata_parport.c
> @@ -0,0 +1,805 @@
> +// SPDX-License-Identifier: GPL-2.0-only

Please add your copyright statement here.

> +static void pata_parport_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)

Overly long line.

> +			pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->hob_nsect);
> +			pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->hob_lbal);
> +			pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->hob_lbam);
> +			pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->hob_lbah);

Same here.

> +static void pata_parport_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)

.. and here.

And a bunch more.

> +static void pata_parport_bus_release(struct device *dev)
> +{
> +	/* nothing to do here but required to avoid warning on device removal */
> +}
> +
> +static struct bus_type pata_parport_bus_type = {
> +	.name = DRV_NAME,
> +};
> +
> +static struct device pata_parport_bus = {
> +	.init_name = DRV_NAME,
> +	.release = pata_parport_bus_release,
> +};
> +
> +/* temporary for old paride protocol modules */
> +static struct scsi_host_template pata_parport_sht = {
> +	PATA_PARPORT_SHT("pata_parport")
> +};

Did you look into my suggestion to use struct pardevice.dev instead?

> index ddb9e589da7f..f3bd01a9c9ec 100644
> --- a/drivers/block/paride/paride.h
> +++ b/drivers/block/paride/paride.h
> @@ -1,3 +1,7 @@
> +#if IS_ENABLED(CONFIG_PATA_PARPORT)
> +#include "../../ata/parport/pata_parport.h"
> +
> +#else

Maybe add a comment here?  Also this is a pretty clear indication
that pata_parport.h should be in include/linux/ at least for now.


From linux at zary.sk  Fri Mar 11 10:55:15 2022
From: linux at zary.sk (Ondrej Zary)
Date: Fri, 11 Mar 2022 19:55:15 +0100
Subject: [Linux-parport] [PATCH v0] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <e41b526d-18d4-ae05-976d-3021e739cd8e@opensource.wdc.com>
References: <20220310212812.13944-1-linux@zary.sk>
 <e41b526d-18d4-ae05-976d-3021e739cd8e@opensource.wdc.com>
Message-ID: <202203111955.15743.linux@zary.sk>

On Friday 11 March 2022 00:59:20 Damien Le Moal wrote:
> On 3/11/22 06:28, Ondrej Zary wrote:
> > Add pata_parport (PARIDE replacement) core libata driver.
> > 
> > The original paride protocol modules are used for now so allow them to
> > be compiled without old PARIDE core.
> > 
> > Signed-off-by: Ondrej Zary <linux at zary.sk>
> > ---
> >  drivers/Makefile                   |   2 +-
> >  drivers/ata/Kconfig                |  22 +
> >  drivers/ata/Makefile               |   2 +
> >  drivers/ata/parport/Makefile       |   3 +
> >  drivers/ata/parport/pata_parport.c | 805 +++++++++++++++++++++++++++++
> >  drivers/ata/parport/pata_parport.h | 108 ++++
> >  drivers/block/paride/Kconfig       |  32 +-
> >  drivers/block/paride/paride.h      |   5 +
> >  8 files changed, 962 insertions(+), 17 deletions(-)
> >  create mode 100644 drivers/ata/parport/Makefile
> >  create mode 100644 drivers/ata/parport/pata_parport.c
> >  create mode 100644 drivers/ata/parport/pata_parport.h
> > 
> > diff --git a/drivers/Makefile b/drivers/Makefile
> > index a110338c860c..8ec515f3614e 100644
> > --- a/drivers/Makefile
> > +++ b/drivers/Makefile
> > @@ -98,7 +98,7 @@ obj-$(CONFIG_DIO)		+= dio/
> >  obj-$(CONFIG_SBUS)		+= sbus/
> >  obj-$(CONFIG_ZORRO)		+= zorro/
> >  obj-$(CONFIG_ATA_OVER_ETH)	+= block/aoe/
> > -obj-$(CONFIG_PARIDE) 		+= block/paride/
> > +obj-y		 		+= block/paride/
> >  obj-$(CONFIG_TC)		+= tc/
> >  obj-$(CONFIG_USB_PHY)		+= usb/
> >  obj-$(CONFIG_USB)		+= usb/
> > diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
> > index e5641e6c52ee..671c27b77a48 100644
> > --- a/drivers/ata/Kconfig
> > +++ b/drivers/ata/Kconfig
> > @@ -1161,6 +1161,28 @@ config PATA_WINBOND_VLB
> >  	  Support for the Winbond W83759A controller on Vesa Local Bus
> >  	  systems.
> >  
> > +config PATA_PARPORT
> > +	tristate "Parallel port IDE device support"
> > +	depends on PARPORT_PC && PARIDE=n
> 
> This is very confusing. The change above this one switch paride
> compilation to be unconditional, regardless of CONFIG_PARIDE value, but
> here, you have the dependency to PARIDE=n. I do not understand... Please
> clarify.

pata_parport will use existing paride protocol modules. So the paride/ directory must be processed to compile the protocol modules (if they're enabled) even if paride is not enabled.

pata_parport and paride are mutually exclusive because the binary protocol modules are incompatible (the struct pi_adapter is different).

-- 
Ondrej Zary


From damien.lemoal at opensource.wdc.com  Sat Mar 12 00:09:54 2022
From: damien.lemoal at opensource.wdc.com (Damien Le Moal)
Date: Sat, 12 Mar 2022 17:09:54 +0900
Subject: [Linux-parport] [PATCH v0] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <202203111955.15743.linux@zary.sk>
References: <20220310212812.13944-1-linux@zary.sk>
 <e41b526d-18d4-ae05-976d-3021e739cd8e@opensource.wdc.com>
 <202203111955.15743.linux@zary.sk>
Message-ID: <c0a6065c-3e89-a4be-e257-ce25711e4368@opensource.wdc.com>

On 3/12/22 03:55, Ondrej Zary wrote:
> On Friday 11 March 2022 00:59:20 Damien Le Moal wrote:
>> On 3/11/22 06:28, Ondrej Zary wrote:
>>> Add pata_parport (PARIDE replacement) core libata driver.
>>>
>>> The original paride protocol modules are used for now so allow them to
>>> be compiled without old PARIDE core.
>>>
>>> Signed-off-by: Ondrej Zary <linux at zary.sk>
>>> ---
>>>  drivers/Makefile                   |   2 +-
>>>  drivers/ata/Kconfig                |  22 +
>>>  drivers/ata/Makefile               |   2 +
>>>  drivers/ata/parport/Makefile       |   3 +
>>>  drivers/ata/parport/pata_parport.c | 805 +++++++++++++++++++++++++++++
>>>  drivers/ata/parport/pata_parport.h | 108 ++++
>>>  drivers/block/paride/Kconfig       |  32 +-
>>>  drivers/block/paride/paride.h      |   5 +
>>>  8 files changed, 962 insertions(+), 17 deletions(-)
>>>  create mode 100644 drivers/ata/parport/Makefile
>>>  create mode 100644 drivers/ata/parport/pata_parport.c
>>>  create mode 100644 drivers/ata/parport/pata_parport.h
>>>
>>> diff --git a/drivers/Makefile b/drivers/Makefile
>>> index a110338c860c..8ec515f3614e 100644
>>> --- a/drivers/Makefile
>>> +++ b/drivers/Makefile
>>> @@ -98,7 +98,7 @@ obj-$(CONFIG_DIO)		+= dio/
>>>  obj-$(CONFIG_SBUS)		+= sbus/
>>>  obj-$(CONFIG_ZORRO)		+= zorro/
>>>  obj-$(CONFIG_ATA_OVER_ETH)	+= block/aoe/
>>> -obj-$(CONFIG_PARIDE) 		+= block/paride/
>>> +obj-y		 		+= block/paride/
>>>  obj-$(CONFIG_TC)		+= tc/
>>>  obj-$(CONFIG_USB_PHY)		+= usb/
>>>  obj-$(CONFIG_USB)		+= usb/
>>> diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
>>> index e5641e6c52ee..671c27b77a48 100644
>>> --- a/drivers/ata/Kconfig
>>> +++ b/drivers/ata/Kconfig
>>> @@ -1161,6 +1161,28 @@ config PATA_WINBOND_VLB
>>>  	  Support for the Winbond W83759A controller on Vesa Local Bus
>>>  	  systems.
>>>  
>>> +config PATA_PARPORT
>>> +	tristate "Parallel port IDE device support"
>>> +	depends on PARPORT_PC && PARIDE=n
>>
>> This is very confusing. The change above this one switch paride
>> compilation to be unconditional, regardless of CONFIG_PARIDE value, but
>> here, you have the dependency to PARIDE=n. I do not understand... Please
>> clarify.
> 
> pata_parport will use existing paride protocol modules. So the paride/ directory must be processed to compile the protocol modules (if they're enabled) even if paride is not enabled.
> 
> pata_parport and paride are mutually exclusive because the binary protocol modules are incompatible (the struct pi_adapter is different).

So if both CONFIG_PARIDE and CONFIG_PATA_PARPORT are disabled, there
should be no need to compile the core PARIDE code under block/. You
should have something like:

In drivers/Makefile:

-obj-$(CONFIG_PARIDE) 		+= block/paride/
+obj-$(CONFIG_PARIDE_CORE) 	+= block/paride/

And then have CONFIG_PARIDE and CONFIG_PATA_PARPORT select PARIDE_CORE,
with CONFIG_PARIDE and CONFIG_PATA_PARPORT being mutually exclusive
(using "depends on" as you did).

Here, I am assuming that block/paride is the core code used by both
PARIDE and PATA_PARPORT. Not sure what PARPORT_PC does nor what its
dependency on block/paride code is.


-- 
Damien Le Moal
Western Digital Research


From linux at zary.sk  Sat Mar 12 03:21:55 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat, 12 Mar 2022 12:21:55 +0100
Subject: [Linux-parport] [PATCH v0] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <c0a6065c-3e89-a4be-e257-ce25711e4368@opensource.wdc.com>
References: <20220310212812.13944-1-linux@zary.sk>
 <202203111955.15743.linux@zary.sk>
 <c0a6065c-3e89-a4be-e257-ce25711e4368@opensource.wdc.com>
Message-ID: <202203121221.56068.linux@zary.sk>


On Saturday 12 March 2022 09:09:54 Damien Le Moal wrote:
> On 3/12/22 03:55, Ondrej Zary wrote:
> > On Friday 11 March 2022 00:59:20 Damien Le Moal wrote:
> >> On 3/11/22 06:28, Ondrej Zary wrote:
> >>> Add pata_parport (PARIDE replacement) core libata driver.
> >>>
> >>> The original paride protocol modules are used for now so allow them to
> >>> be compiled without old PARIDE core.
> >>>
> >>> Signed-off-by: Ondrej Zary <linux at zary.sk>
> >>> ---
> >>>  drivers/Makefile                   |   2 +-
> >>>  drivers/ata/Kconfig                |  22 +
> >>>  drivers/ata/Makefile               |   2 +
> >>>  drivers/ata/parport/Makefile       |   3 +
> >>>  drivers/ata/parport/pata_parport.c | 805 +++++++++++++++++++++++++++++
> >>>  drivers/ata/parport/pata_parport.h | 108 ++++
> >>>  drivers/block/paride/Kconfig       |  32 +-
> >>>  drivers/block/paride/paride.h      |   5 +
> >>>  8 files changed, 962 insertions(+), 17 deletions(-)
> >>>  create mode 100644 drivers/ata/parport/Makefile
> >>>  create mode 100644 drivers/ata/parport/pata_parport.c
> >>>  create mode 100644 drivers/ata/parport/pata_parport.h
> >>>
> >>> diff --git a/drivers/Makefile b/drivers/Makefile
> >>> index a110338c860c..8ec515f3614e 100644
> >>> --- a/drivers/Makefile
> >>> +++ b/drivers/Makefile
> >>> @@ -98,7 +98,7 @@ obj-$(CONFIG_DIO)		+= dio/
> >>>  obj-$(CONFIG_SBUS)		+= sbus/
> >>>  obj-$(CONFIG_ZORRO)		+= zorro/
> >>>  obj-$(CONFIG_ATA_OVER_ETH)	+= block/aoe/
> >>> -obj-$(CONFIG_PARIDE) 		+= block/paride/
> >>> +obj-y		 		+= block/paride/
> >>>  obj-$(CONFIG_TC)		+= tc/
> >>>  obj-$(CONFIG_USB_PHY)		+= usb/
> >>>  obj-$(CONFIG_USB)		+= usb/
> >>> diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
> >>> index e5641e6c52ee..671c27b77a48 100644
> >>> --- a/drivers/ata/Kconfig
> >>> +++ b/drivers/ata/Kconfig
> >>> @@ -1161,6 +1161,28 @@ config PATA_WINBOND_VLB
> >>>  	  Support for the Winbond W83759A controller on Vesa Local Bus
> >>>  	  systems.
> >>>  
> >>> +config PATA_PARPORT
> >>> +	tristate "Parallel port IDE device support"
> >>> +	depends on PARPORT_PC && PARIDE=n
> >>
> >> This is very confusing. The change above this one switch paride
> >> compilation to be unconditional, regardless of CONFIG_PARIDE value, but
> >> here, you have the dependency to PARIDE=n. I do not understand... Please
> >> clarify.
> > 
> > pata_parport will use existing paride protocol modules. So the paride/ directory must be processed to compile the protocol modules (if they're enabled) even if paride is not enabled.
> > 
> > pata_parport and paride are mutually exclusive because the binary protocol modules are incompatible (the struct pi_adapter is different).
> 
> So if both CONFIG_PARIDE and CONFIG_PATA_PARPORT are disabled, there
> should be no need to compile the core PARIDE code under block/. You
> should have something like:
> 
> In drivers/Makefile:
> 
> -obj-$(CONFIG_PARIDE) 		+= block/paride/
> +obj-$(CONFIG_PARIDE_CORE) 	+= block/paride/
> 
> And then have CONFIG_PARIDE and CONFIG_PATA_PARPORT select PARIDE_CORE,
> with CONFIG_PARIDE and CONFIG_PATA_PARPORT being mutually exclusive
> (using "depends on" as you did).
> 
> Here, I am assuming that block/paride is the core code used by both
> PARIDE and PATA_PARPORT. Not sure what PARPORT_PC does nor what its
> dependency on block/paride code is.

There's no common core in block/paride. The block/paride/Makefile says:
obj-$(CONFIG_PARIDE)            += paride.o
obj-$(CONFIG_PARIDE_ATEN)       += aten.o
obj-$(CONFIG_PARIDE_...other protocol drivers

So if PARIDE and all protocol drivers are disabled, nothing is compiled there.

-- 
Ondrej Zary


From linux at zary.sk  Sat Mar 12 06:44:15 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sat, 12 Mar 2022 15:44:15 +0100
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
Message-ID: <20220312144415.20010-1-linux@zary.sk>

The pata_parport is a libata-based replacement of the old PARIDE
subsystem - driver for parallel port IDE devices.
It uses the original paride low-level protocol drivers but does not
need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
behind parallel port adapters are handled by the ATA layer.

This will allow paride and its high-level drivers to be removed.

paride and pata_parport are mutually exclusive because the compiled
protocol drivers are incompatible.

Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
chip).

Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
drivers - they don't handle non-multiple-of-4 block transfers
correctly. This causes problems with LS-120 drive.
There is also another bug in EPAT: EPP modes don't work unless a 4-bit
or 8-bit mode is used first (probably some initialization missing?).
Once the device is initialized, EPP works until power cycle.

So after device power on, you have to:
echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
echo pata_parport.0 >/sys/bus/pata_parport/delete_device
echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
(autoprobe will initialize correctly as it tries the slowest modes
first but you'll get the broken EPP-32 mode)

Signed-off-by: Ondrej Zary <linux at zary.sk>
---
 Documentation/admin-guide/blockdev/paride.rst |  52 ++
 drivers/Makefile                              |   2 +-
 drivers/ata/Kconfig                           |  14 +
 drivers/ata/Makefile                          |   2 +
 drivers/ata/pata_parport.c                    | 819 ++++++++++++++++++
 drivers/block/paride/Kconfig                  |  32 +-
 drivers/block/paride/paride.h                 |  13 +
 include/linux/pata_parport.h                  | 108 +++
 8 files changed, 1025 insertions(+), 17 deletions(-)
 create mode 100644 drivers/ata/pata_parport.c
 create mode 100644 include/linux/pata_parport.h

diff --git a/Documentation/admin-guide/blockdev/paride.rst b/Documentation/admin-guide/blockdev/paride.rst
index e1ce90af602a..e431a1ef41eb 100644
--- a/Documentation/admin-guide/blockdev/paride.rst
+++ b/Documentation/admin-guide/blockdev/paride.rst
@@ -2,6 +2,9 @@
 Linux and parallel port IDE devices
 ===================================
 
+Most of this document describes the old paride driver. For the new libata
+pata_parport drivrer, jump to the section 4 at the end.
+
 PARIDE v1.03   (c) 1997-8  Grant Guenther <grant at torque.net>
 
 1. Introduction
@@ -437,3 +440,52 @@ You might also find some useful information on the linux-parport
 web pages (although they are not always up to date) at
 
 	http://web.archive.org/web/%2E/http://www.torque.net/parport/
+
+4. pata_parport driver
+======================
+pata_parport is a libata-based driver that uses the same low-level protocol
+drivers as PARIDE but there are no high-level drivers (pd, pcd, pf, pt, pg).
+The IDE devices behind parallel port adapters are handled by the ATA layer.
+
+The device creation is also changed - no protocol numbers or parport I/O
+addresses are used.
+
+All parports and all protocol drivers are probed automatically unless probe=0
+parameter is used. So just "modprobe epat" is enough for a Imation SuperDisk
+drive to work.
+
+Manual device creation::
+
+	# echo "port protocol mode unit delay" >/sys/bus/pata_parport/new_device
+
+where:
+
+	======== ================================================
+	port	 parport name (or "auto" for all parports)
+	protocol protocol name (or "auto" for all protocols)
+	mode	 mode number (protocol-specific) or -1 for probe
+	unit	 unit number (see the paride documentation above)
+	delay	 I/O delay (see the paride documentation above)
+	======== ================================================
+
+If you omit the parameters from the end, defaults will be used, e.g.:
+
+Probe all parports with all protocols::
+
+	# echo auto >/sys/bus/pata_parport/new_device
+
+Probe parport0 using protocol epat and mode 4 (EPP-16)::
+
+	# echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
+
+Probe parport0 using all protocols::
+
+	# echo "parport0 auto" >/sys/bus/pata_parport/new_device
+
+Probe all parports using protoocol epat::
+
+	# echo "auto epat" >/sys/bus/pata_parport/new_device
+
+Deleting devices::
+
+	# echo pata_parport.0 >/sys/bus/pata_parport/delete_device
diff --git a/drivers/Makefile b/drivers/Makefile
index a110338c860c..8ec515f3614e 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -98,7 +98,7 @@ obj-$(CONFIG_DIO)		+= dio/
 obj-$(CONFIG_SBUS)		+= sbus/
 obj-$(CONFIG_ZORRO)		+= zorro/
 obj-$(CONFIG_ATA_OVER_ETH)	+= block/aoe/
-obj-$(CONFIG_PARIDE) 		+= block/paride/
+obj-y		 		+= block/paride/
 obj-$(CONFIG_TC)		+= tc/
 obj-$(CONFIG_USB_PHY)		+= usb/
 obj-$(CONFIG_USB)		+= usb/
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index e5641e6c52ee..ccbf6114fd53 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -1161,6 +1161,20 @@ config PATA_WINBOND_VLB
 	  Support for the Winbond W83759A controller on Vesa Local Bus
 	  systems.
 
+config PATA_PARPORT
+	tristate "Parallel port IDE device support"
+	depends on PARPORT_PC && PARIDE=n
+	help
+	  There are many external CD-ROM and disk devices that connect through
+	  your computer's parallel port. Most of them are actually IDE devices
+	  using a parallel port IDE adapter. This option enables the
+	  PATA_PARPORT subsystem which contains drivers for many of these
+	  external drives.
+	  Read <file:Documentation/admin-guide/blockdev/paride.rst> for more
+	  information.
+
+	  Use the old PARIDE protocol modules.
+
 comment "Generic fallback / legacy drivers"
 
 config PATA_ACPI
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index b8aebfb14e82..77145834a585 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -114,6 +114,8 @@ obj-$(CONFIG_PATA_SAMSUNG_CF)	+= pata_samsung_cf.o
 
 obj-$(CONFIG_PATA_PXA)		+= pata_pxa.o
 
+obj-$(CONFIG_PATA_PARPORT)	+= pata_parport.o
+
 # Should be last but two libata driver
 obj-$(CONFIG_PATA_ACPI)		+= pata_acpi.o
 # Should be last but one libata driver
diff --git a/drivers/ata/pata_parport.c b/drivers/ata/pata_parport.c
new file mode 100644
index 000000000000..783764626a27
--- /dev/null
+++ b/drivers/ata/pata_parport.c
@@ -0,0 +1,819 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2022 Ondrej Zary
+ * based on paride.c by Grant R. Guenther <grant at torque.net>
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/parport.h>
+#include <linux/pata_parport.h>
+
+#define DRV_NAME "pata_parport"
+
+static DEFINE_IDR(parport_list);
+static DEFINE_IDR(protocols);
+static DEFINE_IDA(pata_parport_bus_dev_ids);
+static DEFINE_MUTEX(pi_mutex);
+
+static bool probe = true;
+module_param(probe, bool, 0644);
+MODULE_PARM_DESC(probe, "Enable automatic device probing (0=off, 1=on [default])");
+
+static bool verbose;
+module_param(verbose, bool, 0644);
+MODULE_PARM_DESC(verbose, "Enable verbose messages (0=off [default], 1=on)");
+
+#define DISCONNECT_TIMEOUT	(HZ / 10)
+
+static void pi_connect(struct pi_adapter *pi)
+{
+	del_timer_sync(&pi->timer);
+	if (!pi->claimed) {
+		pi->claimed = true;
+		parport_claim_or_block(pi->pardev);
+		pi->proto->connect(pi);
+	}
+}
+
+static void pi_disconnect_timer(struct timer_list *t)
+{
+	struct pi_adapter *pi = from_timer(pi, t, timer);
+
+	if (pi->claimed) {
+		pi->proto->disconnect(pi);
+		parport_release(pi->pardev);
+		pi->claimed = false;
+	}
+}
+
+/* functions taken from libata-sff.c and converted from direct port I/O */
+static void pata_parport_dev_select(struct ata_port *ap, unsigned int device)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+	u8 tmp;
+
+	if (device == 0)
+		tmp = ATA_DEVICE_OBS;
+	else
+		tmp = ATA_DEVICE_OBS | ATA_DEV1;
+
+	pi_connect(pi);
+	pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tmp);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+	ata_sff_pause(ap);
+}
+
+static bool pata_parport_devchk(struct ata_port *ap, unsigned int device)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+	u8 nsect, lbal;
+
+	pata_parport_dev_select(ap, device);
+
+	pi_connect(pi);
+	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0x55);
+	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
+
+	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0xaa);
+	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0x55);
+
+	pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 055);
+	pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
+
+	nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
+	lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+
+	if ((nsect == 0x55) && (lbal == 0xaa))
+		return true;	/* we found a device */
+
+	return false;		/* nothing found */
+}
+
+static int pata_parport_bus_softreset(struct ata_port *ap, unsigned int devmask,
+				      unsigned long deadline)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	/* software reset.  causes dev0 to be selected */
+	pi->proto->write_regr(pi, 1, 6, ap->ctl);
+	udelay(20);
+	pi->proto->write_regr(pi, 1, 6, ap->ctl | ATA_SRST);
+	udelay(20);
+	pi->proto->write_regr(pi, 1, 6, ap->ctl);
+	ap->last_ctl = ap->ctl;
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+
+	/* wait the port to become ready */
+	return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
+}
+
+static int pata_parport_softreset(struct ata_link *link, unsigned int *classes,
+				  unsigned long deadline)
+{
+	struct ata_port *ap = link->ap;
+	unsigned int devmask = 0;
+	int rc;
+	u8 err;
+
+	/* determine if device 0/1 are present */
+	if (pata_parport_devchk(ap, 0))
+		devmask |= (1 << 0);
+	if (pata_parport_devchk(ap, 1))
+		devmask |= (1 << 1);
+
+	/* select device 0 again */
+	pata_parport_dev_select(ap, 0);
+
+	/* issue bus reset */
+	rc = pata_parport_bus_softreset(ap, devmask, deadline);
+	if (rc && rc != -ENODEV) {
+		ata_link_err(link, "SRST failed (errno=%d)\n", rc);
+		return rc;
+	}
+
+	/* determine by signature whether we have ATA or ATAPI devices */
+	classes[0] = ata_sff_dev_classify(&link->device[0],
+					  devmask & (1 << 0), &err);
+	if (err != 0x81)
+		classes[1] = ata_sff_dev_classify(&link->device[1],
+						  devmask & (1 << 1), &err);
+
+	return 0;
+}
+
+static u8 pata_parport_check_status(struct ata_port *ap)
+{
+	u8 status;
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+
+	return status;
+}
+
+static u8 pata_parport_check_altstatus(struct ata_port *ap)
+{
+	u8 altstatus;
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	altstatus = pi->proto->read_regr(pi, 1, 6);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+
+	return altstatus;
+}
+
+static void pata_parport_tf_load(struct ata_port *ap,
+				 const struct ata_taskfile *tf)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	if (tf->ctl != ap->last_ctl) {
+		pi->proto->write_regr(pi, 1, 6, tf->ctl);
+		ap->last_ctl = tf->ctl;
+		ata_wait_idle(ap);
+	}
+
+	if (tf->flags & ATA_TFLAG_ISADDR) {
+		if (tf->flags & ATA_TFLAG_LBA48) {
+			pi->proto->write_regr(pi, 0, ATA_REG_FEATURE,
+					      tf->hob_feature);
+			pi->proto->write_regr(pi, 0, ATA_REG_NSECT,
+					      tf->hob_nsect);
+			pi->proto->write_regr(pi, 0, ATA_REG_LBAL,
+					      tf->hob_lbal);
+			pi->proto->write_regr(pi, 0, ATA_REG_LBAM,
+					      tf->hob_lbam);
+			pi->proto->write_regr(pi, 0, ATA_REG_LBAH,
+					      tf->hob_lbah);
+		}
+		pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->feature);
+		pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->nsect);
+		pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->lbal);
+		pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->lbam);
+		pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->lbah);
+	}
+
+	if (tf->flags & ATA_TFLAG_DEVICE)
+		pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tf->device);
+
+	ata_wait_idle(ap);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+}
+
+static void pata_parport_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	tf->status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
+	tf->error = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
+	tf->nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
+	tf->lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
+	tf->lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
+	tf->lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
+	tf->device = pi->proto->read_regr(pi, 0, ATA_REG_DEVICE);
+
+	if (tf->flags & ATA_TFLAG_LBA48) {
+		pi->proto->write_regr(pi, 1, 6, tf->ctl | ATA_HOB);
+		tf->hob_feature = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
+		tf->hob_nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
+		tf->hob_lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
+		tf->hob_lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
+		tf->hob_lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
+		pi->proto->write_regr(pi, 1, 6, tf->ctl);
+		ap->last_ctl = tf->ctl;
+	}
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+}
+
+static void pata_parport_exec_command(struct ata_port *ap,
+				      const struct ata_taskfile *tf)
+{
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	pi->proto->write_regr(pi, 0, ATA_REG_CMD, tf->command);
+	ata_sff_pause(ap);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+}
+
+static unsigned int pata_parport_data_xfer(struct ata_queued_cmd *qc,
+				unsigned char *buf, unsigned int buflen, int rw)
+{
+	struct ata_port *ap = qc->dev->link->ap;
+	struct pi_adapter *pi = ap->host->private_data;
+
+	pi_connect(pi);
+	if (rw == READ)
+		pi->proto->read_block(pi, buf, buflen);
+	else
+		pi->proto->write_block(pi, buf, buflen);
+	mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+
+	return buflen;
+}
+
+static void pata_parport_drain_fifo(struct ata_queued_cmd *qc)
+{
+	int count;
+	struct ata_port *ap;
+	struct pi_adapter *pi;
+	char junk[2];
+
+	/* We only need to flush incoming data when a command was running */
+	if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
+		return;
+
+	ap = qc->ap;
+	pi = ap->host->private_data;
+	/* Drain up to 64K of data before we give up this recovery method */
+	for (count = 0; (pata_parport_check_status(ap) & ATA_DRQ)
+						&& count < 65536; count += 2) {
+		pi_connect(pi);
+		pi->proto->read_block(pi, junk, 2);
+		mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
+	}
+
+	if (count)
+		ata_port_dbg(ap, "drained %d bytes to clear DRQ\n", count);
+}
+
+static void pata_parport_lost_interrupt(struct ata_port *ap)
+{
+	u8 status;
+	struct ata_queued_cmd *qc;
+
+	/* Only one outstanding command per SFF channel */
+	qc = ata_qc_from_tag(ap, ap->link.active_tag);
+	/* We cannot lose an interrupt on a non-existent or polled command */
+	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
+		return;
+	/*
+	 * See if the controller thinks it is still busy - if so the command
+	 * isn't a lost IRQ but is still in progress
+	 */
+	status = pata_parport_check_altstatus(ap);
+	if (status & ATA_BUSY)
+		return;
+
+	/*
+	 * There was a command running, we are no longer busy and we have
+	 * no interrupt.
+	 */
+	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
+	/* Run the host interrupt logic as if the interrupt had not been lost */
+	ata_sff_port_intr(ap, qc);
+}
+
+static struct ata_port_operations pata_parport_port_ops = {
+	.inherits		= &ata_sff_port_ops,
+
+	.softreset		= pata_parport_softreset,
+	.hardreset		= NULL,
+
+	.sff_dev_select		= pata_parport_dev_select,
+	.sff_check_status	= pata_parport_check_status,
+	.sff_check_altstatus	= pata_parport_check_altstatus,
+	.sff_tf_load		= pata_parport_tf_load,
+	.sff_tf_read		= pata_parport_tf_read,
+	.sff_exec_command	= pata_parport_exec_command,
+	.sff_data_xfer		= pata_parport_data_xfer,
+	.sff_drain_fifo		= pata_parport_drain_fifo,
+
+	.lost_interrupt		= pata_parport_lost_interrupt,
+};
+
+static const struct ata_port_info pata_parport_port_info = {
+	.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_POLLING,
+	.pio_mask	= ATA_PIO0,
+	/* No DMA */
+	.port_ops	= &pata_parport_port_ops,
+};
+
+static void pi_release(struct pi_adapter *pi)
+{
+	parport_unregister_device(pi->pardev);
+	if (pi->proto->release_proto)
+		pi->proto->release_proto(pi);
+	module_put(pi->proto->owner);
+}
+
+static int default_test_proto(struct pi_adapter *pi, char *scratch)
+{
+	int j, k;
+	int e[2] = { 0, 0 };
+
+	pi->proto->connect(pi);
+
+	for (j = 0; j < 2; j++) {
+		pi->proto->write_regr(pi, 0, 6, 0xa0 + j * 0x10);
+		for (k = 0; k < 256; k++) {
+			pi->proto->write_regr(pi, 0, 2, k ^ 0xaa);
+			pi->proto->write_regr(pi, 0, 3, k ^ 0x55);
+			if (pi->proto->read_regr(pi, 0, 2) != (k ^ 0xaa))
+				e[j]++;
+		}
+	}
+	pi->proto->disconnect(pi);
+
+	if (verbose)
+		dev_info(&pi->dev, "%s: port 0x%x, mode %d, test=(%d,%d)\n",
+		       pi->proto->name, pi->port,
+		       pi->mode, e[0], e[1]);
+
+	return e[0] && e[1];	/* not here if both > 0 */
+}
+
+static int pi_test_proto(struct pi_adapter *pi, char *scratch)
+{
+	int res;
+
+	parport_claim_or_block(pi->pardev);
+	if (pi->proto->test_proto)
+		res = pi->proto->test_proto(pi, scratch, verbose);
+	else
+		res = default_test_proto(pi, scratch);
+	parport_release(pi->pardev);
+
+	return res;
+}
+
+static bool pi_probe_mode(struct pi_adapter *pi, int max, char *scratch)
+{
+	int best, range;
+
+	if (pi->mode != -1) {
+		if (pi->mode >= max)
+			return false;
+		range = 3;
+		if (pi->mode >= pi->proto->epp_first)
+			range = 8;
+		if (range == 8 && pi->port % 8)
+			return false;
+		return !pi_test_proto(pi, scratch);
+	}
+	best = -1;
+	for (pi->mode = 0; pi->mode < max; pi->mode++) {
+		range = 3;
+		if (pi->mode >= pi->proto->epp_first)
+			range = 8;
+		if (range == 8 && pi->port % 8)
+			break;
+		if (!pi_test_proto(pi, scratch))
+			best = pi->mode;
+	}
+	pi->mode = best;
+	return best > -1;
+}
+
+static bool pi_probe_unit(struct pi_adapter *pi, int unit, char *scratch)
+{
+	int max, s, e;
+
+	s = unit;
+	e = s + 1;
+
+	if (s == -1) {
+		s = 0;
+		e = pi->proto->max_units;
+	}
+
+	if (pi->proto->test_port) {
+		parport_claim_or_block(pi->pardev);
+		max = pi->proto->test_port(pi);
+		parport_release(pi->pardev);
+	} else {
+		max = pi->proto->max_mode;
+	}
+
+	if (pi->proto->probe_unit) {
+		parport_claim_or_block(pi->pardev);
+		for (pi->unit = s; pi->unit < e; pi->unit++) {
+			if (pi->proto->probe_unit(pi)) {
+				parport_release(pi->pardev);
+				return pi_probe_mode(pi, max, scratch);
+			}
+		}
+		parport_release(pi->pardev);
+		return false;
+	}
+
+	return pi_probe_mode(pi, max, scratch);
+}
+
+static void pata_parport_dev_release(struct device *dev)
+{
+	struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
+
+	kfree(pi);
+}
+
+static void pata_parport_bus_release(struct device *dev)
+{
+	/* nothing to do here but required to avoid warning on device removal */
+}
+
+static struct bus_type pata_parport_bus_type = {
+	.name = DRV_NAME,
+};
+
+static struct device pata_parport_bus = {
+	.init_name = DRV_NAME,
+	.release = pata_parport_bus_release,
+};
+
+/* temporary for old paride protocol modules */
+static struct scsi_host_template pata_parport_sht = {
+	PATA_PARPORT_SHT("pata_parport")
+};
+
+static struct pi_adapter *pi_init_one(struct parport *parport,
+			struct pi_protocol *pr, int mode, int unit, int delay)
+{
+	struct pardev_cb par_cb = { };
+	char scratch[512];
+	const struct ata_port_info *ppi[] = { &pata_parport_port_info };
+	struct ata_host *host;
+	struct pi_adapter *pi;
+
+	pi = kzalloc(sizeof(struct pi_adapter), GFP_KERNEL);
+	if (!pi)
+		return NULL;
+
+	/* set up pi->dev before pi_probe_unit() so it can use dev_printk() */
+	pi->dev.parent = &pata_parport_bus;
+	pi->dev.bus = &pata_parport_bus_type;
+	pi->dev.driver = &pr->driver;
+	pi->dev.release = pata_parport_dev_release;
+	pi->dev.id = ida_alloc(&pata_parport_bus_dev_ids, GFP_KERNEL);
+	if (pi->dev.id < 0)
+		return NULL; /* pata_parport_dev_release will do kfree(pi) */
+	dev_set_name(&pi->dev, "pata_parport.%u", pi->dev.id);
+	if (device_register(&pi->dev)) {
+		put_device(&pi->dev);
+		goto out_ida_free;
+	}
+
+	pi->proto = pr;
+
+	if (!try_module_get(pi->proto->owner))
+		goto out_unreg_dev;
+	if (pi->proto->init_proto && pi->proto->init_proto(pi) < 0)
+		goto out_module_put;
+
+	pi->delay = (delay == -1) ? pi->proto->default_delay : delay;
+	pi->mode = mode;
+	pi->port = parport->base;
+
+	par_cb.private = pi;
+	pi->pardev = parport_register_dev_model(parport, DRV_NAME, &par_cb,
+						pi->dev.id);
+	if (!pi->pardev)
+		goto out_module_put;
+
+	if (!pi_probe_unit(pi, unit, scratch)) {
+		dev_info(&pi->dev, "Adapter not found\n");
+		goto out_unreg_parport;
+	}
+
+	pi->proto->log_adapter(pi, scratch, verbose);
+
+	host = ata_host_alloc_pinfo(&pi->pardev->dev, ppi, 1);
+	if (!host)
+		goto out_unreg_parport;
+	dev_set_drvdata(&pi->dev, host);
+	host->private_data = pi;
+
+	ata_port_desc(host->ports[0], "port %s", pi->pardev->port->name);
+	ata_port_desc(host->ports[0], "protocol %s", pi->proto->name);
+
+	timer_setup(&pi->timer, pi_disconnect_timer, 0);
+
+	if (ata_host_activate(host, 0, NULL, 0, &pata_parport_sht))
+		goto out_unreg_parport;
+
+	return pi;
+
+out_unreg_parport:
+	parport_unregister_device(pi->pardev);
+	if (pi->proto->release_proto)
+		pi->proto->release_proto(pi);
+out_module_put:
+	module_put(pi->proto->owner);
+out_unreg_dev:
+	device_unregister(&pi->dev);
+out_ida_free:
+	ida_free(&pata_parport_bus_dev_ids, pi->dev.id);
+	return NULL;
+}
+
+int pata_parport_register_driver(struct pi_protocol *pr)
+{
+	int error;
+	struct parport *parport;
+	int port_num;
+
+	pr->driver.bus = &pata_parport_bus_type;
+	pr->driver.name = pr->name;
+	error = driver_register(&pr->driver);
+	if (error)
+		return error;
+
+	mutex_lock(&pi_mutex);
+	error = idr_alloc(&protocols, pr, 0, 0, GFP_KERNEL);
+	if (error < 0) {
+		driver_unregister(&pr->driver);
+		mutex_unlock(&pi_mutex);
+		return error;
+	}
+
+	pr_info("pata_parport: protocol %s registered\n", pr->name);
+
+	if (probe) {
+		/* probe all parports using this protocol */
+		idr_for_each_entry(&parport_list, parport, port_num)
+			pi_init_one(parport, pr, -1, 0, -1);
+	}
+	mutex_unlock(&pi_mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL(pata_parport_register_driver);
+
+void pata_parport_unregister_driver(struct pi_protocol *pr)
+{
+	struct pi_protocol *pr_iter;
+	int id = -1;
+
+	mutex_lock(&pi_mutex);
+	idr_for_each_entry(&protocols, pr_iter, id) {
+		if (pr_iter == pr)
+			break;
+	}
+	idr_remove(&protocols, id);
+	mutex_unlock(&pi_mutex);
+	driver_unregister(&pr->driver);
+}
+EXPORT_SYMBOL(pata_parport_unregister_driver);
+
+static ssize_t new_device_store(struct bus_type *bus, const char *buf,
+				size_t count)
+{
+	char port[12] = "auto";
+	char protocol[8] = "auto";
+	int mode = -1, unit = -1, delay = -1;
+	struct pi_protocol *pr, *pr_wanted;
+	struct device_driver *drv;
+	struct parport *parport;
+	int port_num, port_wanted, pr_num;
+	bool ok = false;
+
+	if (sscanf(buf, "%11s %7s %d %d %d",
+			port, protocol, &mode, &unit, &delay) < 1)
+		return -EINVAL;
+
+	if (sscanf(port, "parport%u", &port_wanted) < 1) {
+		if (!strcmp(port, "auto")) {
+			port_wanted = -1;
+		} else {
+			pr_err("invalid port name %s\n", port);
+			return -EINVAL;
+		}
+	}
+
+	drv = driver_find(protocol, &pata_parport_bus_type);
+	if (!drv) {
+		if (!strcmp(protocol, "auto")) {
+			pr_wanted = NULL;
+		} else {
+			pr_err("protocol %s not found\n", protocol);
+			return -EINVAL;
+		}
+	} else {
+		pr_wanted = container_of(drv, struct pi_protocol, driver);
+	}
+
+	mutex_lock(&pi_mutex);
+	/* walk all parports */
+	idr_for_each_entry(&parport_list, parport, port_num) {
+		if (port_num == port_wanted || port_wanted == -1) {
+			parport = parport_find_number(port_num);
+			if (!parport) {
+				pr_err("no such port %s\n", port);
+				mutex_unlock(&pi_mutex);
+				return -ENODEV;
+			}
+			/* walk all protocols */
+			idr_for_each_entry(&protocols, pr, pr_num) {
+				if (pr == pr_wanted || !pr_wanted)
+					if (pi_init_one(parport, pr, mode, unit,
+							delay))
+						ok = true;
+			}
+			parport_put_port(parport);
+		}
+	}
+	mutex_unlock(&pi_mutex);
+	if (!ok)
+		return -ENODEV;
+
+	return count;
+}
+static BUS_ATTR_WO(new_device);
+
+static void pi_remove_one(struct device *dev)
+{
+	struct ata_host *host = dev_get_drvdata(dev);
+	struct pi_adapter *pi = host->private_data;
+
+	ata_host_detach(host);
+	del_timer_sync(&pi->timer);
+	if (pi->claimed) {
+		pi->proto->disconnect(pi);
+		parport_release(pi->pardev);
+	}
+	pi_release(pi);
+	device_unregister(dev);
+	ida_free(&pata_parport_bus_dev_ids, dev->id);
+	/* pata_parport_dev_release will do kfree(pi) */
+}
+
+static ssize_t delete_device_store(struct bus_type *bus, const char *buf,
+				   size_t count)
+{
+	struct device *dev;
+	char device_name[32];
+
+	if (sscanf(buf, "%31s", device_name) < 1)
+		return -EINVAL;
+
+	mutex_lock(&pi_mutex);
+	dev = bus_find_device_by_name(bus, NULL, device_name);
+	if (!dev) {
+		mutex_unlock(&pi_mutex);
+		return -ENODEV;
+	}
+
+	pi_remove_one(dev);
+	mutex_unlock(&pi_mutex);
+
+	return count;
+}
+static BUS_ATTR_WO(delete_device);
+
+static void pata_parport_attach(struct parport *port)
+{
+	struct pi_protocol *pr;
+	int pr_num, id;
+
+	mutex_lock(&pi_mutex);
+	id = idr_alloc(&parport_list, port, port->number, port->number,
+		       GFP_KERNEL);
+	if (id < 0) {
+		mutex_unlock(&pi_mutex);
+		return;
+	}
+
+	if (probe) {
+		/* probe this port using all protocols */
+		idr_for_each_entry(&protocols, pr, pr_num)
+			pi_init_one(port, pr, -1, 0, -1);
+	}
+	mutex_unlock(&pi_mutex);
+}
+
+static int pi_remove_port(struct device *dev, void *p)
+{
+	struct ata_host *host = dev_get_drvdata(dev);
+	struct pi_adapter *pi = host->private_data;
+
+	if (pi->pardev->port == p)
+		pi_remove_one(dev);
+
+	return 0;
+}
+
+static void pata_parport_detach(struct parport *port)
+{
+	mutex_lock(&pi_mutex);
+	bus_for_each_dev(&pata_parport_bus_type, NULL, port, pi_remove_port);
+	idr_remove(&parport_list, port->number);
+	mutex_unlock(&pi_mutex);
+}
+
+static struct parport_driver pata_parport_driver = {
+	.name = DRV_NAME,
+	.match_port = pata_parport_attach,
+	.detach = pata_parport_detach,
+	.devmodel = true,
+};
+
+static __init int pata_parport_init(void)
+{
+	int error;
+
+	error = bus_register(&pata_parport_bus_type);
+	if (error) {
+		pr_err("failed to register pata_parport bus, error: %d\n", error);
+		return error;
+	}
+
+	error = device_register(&pata_parport_bus);
+	if (error) {
+		pr_err("failed to register pata_parport bus, error: %d\n", error);
+		goto out_unregister_bus;
+	}
+
+	error = bus_create_file(&pata_parport_bus_type, &bus_attr_new_device);
+	if (error) {
+		pr_err("unable to create sysfs file, error: %d\n", error);
+		goto out_unregister_dev;
+	}
+
+	error = bus_create_file(&pata_parport_bus_type, &bus_attr_delete_device);
+	if (error) {
+		pr_err("unable to create sysfs file, error: %d\n", error);
+		goto out_remove_new;
+	}
+
+	error = parport_register_driver(&pata_parport_driver);
+	if (error) {
+		pr_err("unable to register parport driver, error: %d\n", error);
+		goto out_remove_del;
+	}
+
+	return 0;
+
+out_remove_del:
+	bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
+out_remove_new:
+	bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
+out_unregister_dev:
+	device_unregister(&pata_parport_bus);
+out_unregister_bus:
+	bus_unregister(&pata_parport_bus_type);
+	return error;
+}
+
+static __exit void pata_parport_exit(void)
+{
+	parport_unregister_driver(&pata_parport_driver);
+	bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
+	bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
+	device_unregister(&pata_parport_bus);
+	bus_unregister(&pata_parport_bus_type);
+}
+
+MODULE_AUTHOR("Ondrej Zary");
+MODULE_DESCRIPTION("driver for parallel port ATA adapters");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("paride");
+
+module_init(pata_parport_init);
+module_exit(pata_parport_exit);
diff --git a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig
index a295634597ba..01e4ef3655c1 100644
--- a/drivers/block/paride/Kconfig
+++ b/drivers/block/paride/Kconfig
@@ -92,11 +92,11 @@ config PARIDE_PG
 	  later fully support this driver.
 
 comment "Parallel IDE protocol modules"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 
 config PARIDE_ATEN
 	tristate "ATEN EH-100 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the ATEN EH-100 parallel port IDE
 	  protocol. This protocol is used in some inexpensive low performance
@@ -109,7 +109,7 @@ config PARIDE_ATEN
 
 config PARIDE_BPCK
 	tristate "MicroSolutions backpack (Series 5) protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the Micro Solutions BACKPACK
 	  parallel port Series 5 IDE protocol.  (Most BACKPACK drives made
@@ -127,7 +127,7 @@ config PARIDE_BPCK
 
 config PARIDE_BPCK6
 	tristate "MicroSolutions backpack (Series 6) protocol"
-	depends on PARIDE && !64BIT
+	depends on (PARIDE || PATA_PARPORT) && !64BIT
 	help
 	  This option enables support for the Micro Solutions BACKPACK
 	  parallel port Series 6 IDE protocol.  (Most BACKPACK drives made
@@ -146,7 +146,7 @@ config PARIDE_BPCK6
 
 config PARIDE_COMM
 	tristate "DataStor Commuter protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the Commuter parallel port IDE
 	  protocol from DataStor. If you chose to build PARIDE support
@@ -157,7 +157,7 @@ config PARIDE_COMM
 
 config PARIDE_DSTR
 	tristate "DataStor EP-2000 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the EP-2000 parallel port IDE
 	  protocol from DataStor. If you chose to build PARIDE support
@@ -168,7 +168,7 @@ config PARIDE_DSTR
 
 config PARIDE_FIT2
 	tristate "FIT TD-2000 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the TD-2000 parallel port IDE
 	  protocol from Fidelity International Technology. This is a simple
@@ -181,7 +181,7 @@ config PARIDE_FIT2
 
 config PARIDE_FIT3
 	tristate "FIT TD-3000 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the TD-3000 parallel port IDE
 	  protocol from Fidelity International Technology. This protocol is
@@ -194,7 +194,7 @@ config PARIDE_FIT3
 
 config PARIDE_EPAT
 	tristate "Shuttle EPAT/EPEZ protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the EPAT parallel port IDE protocol.
 	  EPAT is a parallel port IDE adapter manufactured by Shuttle
@@ -216,7 +216,7 @@ config PARIDE_EPATC8
 
 config PARIDE_EPIA
 	tristate "Shuttle EPIA protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the (obsolete) EPIA parallel port
 	  IDE protocol from Shuttle Technology. This adapter can still be
@@ -228,7 +228,7 @@ config PARIDE_EPIA
 
 config PARIDE_FRIQ
 	tristate "Freecom IQ ASIC-2 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for version 2 of the Freecom IQ parallel
 	  port IDE adapter.  This adapter is used by the Maxell Superdisk
@@ -240,7 +240,7 @@ config PARIDE_FRIQ
 
 config PARIDE_FRPW
 	tristate "FreeCom power protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the Freecom power parallel port IDE
 	  protocol. If you chose to build PARIDE support into your kernel, you
@@ -251,7 +251,7 @@ config PARIDE_FRPW
 
 config PARIDE_KBIC
 	tristate "KingByte KBIC-951A/971A protocols"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the KBIC-951A and KBIC-971A parallel
 	  port IDE protocols from KingByte Information Corp. KingByte's
@@ -264,7 +264,7 @@ config PARIDE_KBIC
 
 config PARIDE_KTTI
 	tristate "KT PHd protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the "PHd" parallel port IDE protocol
 	  from KT Technology. This is a simple (low speed) adapter that is
@@ -277,7 +277,7 @@ config PARIDE_KTTI
 
 config PARIDE_ON20
 	tristate "OnSpec 90c20 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the (obsolete) 90c20 parallel port
 	  IDE protocol from OnSpec (often marketed under the ValuStore brand
@@ -289,7 +289,7 @@ config PARIDE_ON20
 
 config PARIDE_ON26
 	tristate "OnSpec 90c26 protocol"
-	depends on PARIDE
+	depends on PARIDE || PATA_PARPORT
 	help
 	  This option enables support for the 90c26 parallel port IDE protocol
 	  from OnSpec Electronics (often marketed under the ValuStore brand
diff --git a/drivers/block/paride/paride.h b/drivers/block/paride/paride.h
index ddb9e589da7f..24dcfadb782d 100644
--- a/drivers/block/paride/paride.h
+++ b/drivers/block/paride/paride.h
@@ -1,3 +1,15 @@
+/*
+ * The low-level protocol modules are used by either paride or pata_parport.
+ * These two are mutually exclusive because the compiled low-level protocol
+ * modules are not compatible.
+ * When PATA_PARPORT is enabled, include pata_parport.h instead of the rest
+ * of this file.
+ */
+
+#if IS_ENABLED(CONFIG_PATA_PARPORT)
+#include <linux/pata_parport.h>
+
+#else
 #ifndef __DRIVERS_PARIDE_H__
 #define __DRIVERS_PARIDE_H__
 
@@ -170,3 +182,4 @@ void pi_unregister_driver(void *);
 
 #endif /* __DRIVERS_PARIDE_H__ */
 /* end of paride.h */
+#endif /* IS_ENABLED(CONFIG_PATA_PARPORT) */
diff --git a/include/linux/pata_parport.h b/include/linux/pata_parport.h
new file mode 100644
index 000000000000..f1ba57bb319c
--- /dev/null
+++ b/include/linux/pata_parport.h
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ *	pata_parport.h	(c) 1997-8  Grant R. Guenther <grant at torque.net>
+ *				    Under the terms of the GPL.
+ *
+ * This file defines the interface for parallel port IDE adapter chip drivers.
+ */
+
+#include <linux/libata.h>
+
+#define PI_PCD	1	/* dummy for paride protocol modules */
+
+struct pi_adapter {
+	struct device dev;
+	struct pi_protocol *proto;	/* adapter protocol */
+	int port;			/* base address of parallel port */
+	int mode;			/* transfer mode in use */
+	int delay;			/* adapter delay setting */
+	int devtype;			/* dummy for paride protocol modules */
+	char *device;			/* dummy for paride protocol modules */
+	int unit;			/* unit number for chained adapters */
+	int saved_r0;			/* saved port state */
+	int saved_r2;			/* saved port state */
+	unsigned long private;		/* for protocol module */
+	struct pardevice *pardev;	/* pointer to pardevice */
+	bool claimed;			/* parport has already been claimed */
+	struct timer_list timer;	/* disconnect timer */
+};
+
+typedef struct pi_adapter PIA;	/* for paride protocol modules */
+
+/* registers are addressed as (cont,regr)
+ *	cont: 0 for command register file, 1 for control register(s)
+ *	regr: 0-7 for register number.
+ */
+
+/* macros and functions exported to the protocol modules */
+#define delay_p			(pi->delay ? udelay(pi->delay) : (void)0)
+#define out_p(offs, byte)	do { outb(byte, pi->port + offs); delay_p; } while (0)
+#define in_p(offs)		(delay_p, inb(pi->port + offs))
+
+#define w0(byte)		out_p(0, byte)
+#define r0()			(in_p(0) & 0xff)
+#define w1(byte)		out_p(1, byte)
+#define r1()			(in_p(1) & 0xff)
+#define w2(byte)		out_p(2, byte)
+#define r2()			(in_p(2) & 0xff)
+#define w3(byte)		out_p(3, byte)
+#define w4(byte)		out_p(4, byte)
+#define r4()			(in_p(4) & 0xff)
+#define w4w(data)		do { outw(data, pi->port + 4); delay_p; } while (0)
+#define w4l(data)		do { outl(data, pi->port + 4); delay_p; } while (0)
+#define r4w()			(delay_p, inw(pi->port + 4) & 0xffff)
+#define r4l()			(delay_p, inl(pi->port + 4) & 0xffffffff)
+
+static inline u16 pi_swab16(char *b, int k)
+{
+	union { u16 u; char t[2]; } r;
+
+	r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k];
+	return r.u;
+}
+
+static inline u32 pi_swab32(char *b, int k)
+{
+	union { u32 u; char f[4]; } r;
+
+	r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k];
+	r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2];
+	return r.u;
+}
+
+struct pi_protocol {
+	char name[8];
+
+	int max_mode;
+	int epp_first;		/* modes >= this use 8 ports */
+
+	int default_delay;
+	int max_units;		/* max chained units probed for */
+
+	void (*write_regr)(struct pi_adapter *pi, int cont, int regr, int val);
+	int (*read_regr)(struct pi_adapter *pi, int cont, int regr);
+	void (*write_block)(struct pi_adapter *pi, char *buf, int count);
+	void (*read_block)(struct pi_adapter *pi, char *buf, int count);
+
+	void (*connect)(struct pi_adapter *pi);
+	void (*disconnect)(struct pi_adapter *pi);
+
+	int (*test_port)(struct pi_adapter *pi);
+	int (*probe_unit)(struct pi_adapter *pi);
+	int (*test_proto)(struct pi_adapter *pi, char *scratch, int verbose);
+	void (*log_adapter)(struct pi_adapter *pi, char *scratch, int verbose);
+
+	int (*init_proto)(struct pi_adapter *pi);
+	void (*release_proto)(struct pi_adapter *pi);
+	struct module *owner;
+	struct device_driver driver;
+	struct scsi_host_template sht;
+};
+
+#define PATA_PARPORT_SHT ATA_PIO_SHT
+
+int pata_parport_register_driver(struct pi_protocol *pr);
+void pata_parport_unregister_driver(struct pi_protocol *pr);
+/* defines for old paride protocol modules */
+#define paride_register pata_parport_register_driver
+#define paride_unregister pata_parport_unregister_driver
-- 
Ondrej Zary



From linux at zary.sk  Sun Mar 13 12:15:17 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sun, 13 Mar 2022 20:15:17 +0100
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <20220312144415.20010-1-linux@zary.sk>
References: <20220312144415.20010-1-linux@zary.sk>
Message-ID: <202203132015.18183.linux@zary.sk>

On Saturday 12 March 2022 15:44:15 Ondrej Zary wrote:
> The pata_parport is a libata-based replacement of the old PARIDE
> subsystem - driver for parallel port IDE devices.
> It uses the original paride low-level protocol drivers but does not
> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
> behind parallel port adapters are handled by the ATA layer.
> 
> This will allow paride and its high-level drivers to be removed.
> 
> paride and pata_parport are mutually exclusive because the compiled
> protocol drivers are incompatible.
> 
> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
> chip).
> 
> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
> drivers - they don't handle non-multiple-of-4 block transfers
> correctly. This causes problems with LS-120 drive.
> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
> or 8-bit mode is used first (probably some initialization missing?).
> Once the device is initialized, EPP works until power cycle.
> 
> So after device power on, you have to:
> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
> (autoprobe will initialize correctly as it tries the slowest modes
> first but you'll get the broken EPP-32 mode)

Found a bug - the same device can be registered multiple times. Fix will be in
v2. But this revealed a bigger problem: pi_connect can sleep (uses
parport_claim_or_block) and libata does not like that.
Any ideas how to fix this?

Mar 12 18:47:13 test kernel: [  348.863534] pata_parport: protocol epat registered
Mar 12 18:47:16 test kernel: [  352.226932] (null): epat 1.02, Shuttle EPAT chip c6 at 0x378,
Mar 12 18:47:16 test kernel: [  352.226943] mode 2 (8-bit), delay 1
Mar 12 18:47:16 test kernel: [  352.255210] scsi host4: pata_parport
Mar 12 18:47:16 test kernel: [  352.255359] ata5: PATA max PIO0 port parport0 protocol epat
Mar 12 18:47:17 test kernel: [  352.489441] ata5.00: ATAPI: LS-120 COSM   04              UHD Floppy, 0270M09T, max PIO2
Mar 12 18:47:17 test kernel: [  352.572733] scsi 4:0:0:0: Direct-Access     MATSHITA LS-120 COSM   04 0270 PQ: 0 ANSI: 5
Mar 12 18:47:17 test kernel: [  352.608160] sd 4:0:0:0: Attached scsi generic sg1 type 0
Mar 12 18:47:17 test kernel: [  352.635053] sd 4:0:0:0: [sdb] Media removed, stopped polling
Mar 12 18:47:17 test kernel: [  352.658924] sd 4:0:0:0: [sdb] Attached SCSI removable disk
Mar 12 18:47:31 test kernel: [  366.811817] (null): epat 1.02, Shuttle EPAT chip c6 at 0x378,
Mar 12 18:47:31 test kernel: [  366.811828] mode 2 (8-bit), delay 1
Mar 12 18:47:31 test kernel: [  366.846397] scsi host5: pata_parport
Mar 12 18:47:31 test kernel: [  366.846557] ata6: PATA max PIO0 port parport0 protocol epat
Mar 12 18:47:31 test kernel: [  367.076726] ata6.00: ATAPI: LS-120 COSM   04              UHD Floppy, 0270M09T, max PIO2
Mar 12 18:47:31 test kernel: [  367.157050] scsi 5:0:0:0: Direct-Access     MATSHITA LS-120 COSM   04 0270 PQ: 0 ANSI: 5
Mar 12 18:47:31 test kernel: [  367.192614] sd 5:0:0:0: Attached scsi generic sg2 type 0
Mar 12 18:47:31 test kernel: [  367.219398] sd 5:0:0:0: [sdc] Media removed, stopped polling
Mar 12 18:47:31 test kernel: [  367.243247] sd 5:0:0:0: [sdc] Attached SCSI removable disk
Mar 12 18:47:32 test kernel: [  367.542155] Modules linked in: epat pata_parport nouveau snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm psmouse snd_timer snd soundcore wmi
hwmon serio_raw drm_ttm_helper 8139cp sg intel_agp i2c_dev parport_pc parport fuse
Mar 12 18:47:32 test kernel: [  367.542219] CPU: 0 PID: 17 Comm: kworker/0:1 Not tainted 5.17.0-rc2+ #441
Mar 12 18:47:32 test kernel: [  367.542227] Hardware name:  /848P-ICH5, BIOS 6.00 PG 02/03/2005
Mar 12 18:47:32 test kernel: [  367.542232] Workqueue: events_freezable_power_ disk_events_workfn
Mar 12 18:47:32 test kernel: [  367.542242] Call Trace:
Mar 12 18:47:32 test kernel: [  367.542250]  dump_stack_lvl+0x32/0x41
Mar 12 18:47:32 test kernel: [  367.542259]  ? preempt_count_add+0x4c/0x51
Mar 12 18:47:32 test kernel: [  367.542266]  dump_stack+0xd/0x10
Mar 12 18:47:32 test kernel: [  367.542271]  __schedule_bug+0x90/0xa1
Mar 12 18:47:32 test kernel: [  367.542281]  __schedule+0x3b/0x456
Mar 12 18:47:32 test kernel: [  367.542289]  schedule+0x68/0xa3
Mar 12 18:47:32 test kernel: [  367.542296]  parport_claim_or_block+0x68/0xa5 [parport]
Mar 12 18:47:32 test kernel: [  367.542307]  ? init_wait_entry+0x21/0x21
Mar 12 18:47:32 test kernel: [  367.542315]  pi_connect+0x2b/0x3e [pata_parport]
Mar 12 18:47:32 test kernel: [  367.542323]  pata_parport_check_status+0x16/0x4e [pata_parport]
Mar 12 18:47:32 test kernel: [  367.542329]  ? pata_parport_lost_interrupt+0x7c/0x7c [pata_parport]
Mar 12 18:47:32 test kernel: [  367.542336]  ata_sff_busy_wait+0x27/0x3b
Mar 12 18:47:32 test kernel: [  367.542345]  ata_wait_idle+0x12/0x14
Mar 12 18:47:32 test kernel: [  367.542350]  ata_sff_qc_issue+0x27/0x106
Mar 12 18:47:32 test kernel: [  367.542357]  ata_qc_issue+0x14b/0x16b
Mar 12 18:47:32 test kernel: [  367.542364]  __ata_scsi_queuecmd+0x1c7/0x1d4
Mar 12 18:47:32 test kernel: [  367.542369]  ? ata_scsiop_inq_83+0xb3/0xb3
Mar 12 18:47:32 test kernel: [  367.542375]  ata_scsi_queuecmd+0x36/0x5f
Mar 12 18:47:32 test kernel: [  367.542380]  scsi_queue_rq+0x577/0x69e
Mar 12 18:47:32 test kernel: [  367.542389]  blk_mq_dispatch_rq_list+0x229/0x3e4
Mar 12 18:47:32 test kernel: [  367.542395]  ? __sbitmap_get_word+0x28/0x5a
Mar 12 18:47:32 test kernel: [  367.542405]  __blk_mq_sched_dispatch_requests+0x7b/0xdb
Mar 12 18:47:32 test kernel: [  367.542411]  blk_mq_sched_dispatch_requests+0x25/0x46
Mar 12 18:47:32 test kernel: [  367.542417]  __blk_mq_run_hw_queue+0x36/0x6b
Mar 12 18:47:32 test kernel: [  367.542424]  __blk_mq_delay_run_hw_queue+0x54/0x11d
Mar 12 18:47:32 test kernel: [  367.542431]  blk_mq_run_hw_queue+0xa5/0xab
Mar 12 18:47:32 test kernel: [  367.542437]  blk_mq_sched_insert_request+0xa2/0xaa
Mar 12 18:47:32 test kernel: [  367.542443]  ? update_io_ticks+0x2a/0x5b
Mar 12 18:47:32 test kernel: [  367.542451]  blk_execute_rq_nowait+0x3f/0x47
Mar 12 18:47:32 test kernel: [  367.542457]  blk_execute_rq+0x3a/0xa4
Mar 12 18:47:32 test kernel: [  367.542463]  __scsi_execute+0x90/0x133
Mar 12 18:47:32 test kernel: [  367.542470]  scsi_test_unit_ready+0x43/0x95
Mar 12 18:47:32 test kernel: [  367.542477]  sd_check_events+0x8b/0xf6
Mar 12 18:47:32 test kernel: [  367.542483]  ? media_not_present+0x3b/0x3b
Mar 12 18:47:32 test kernel: [  367.542489]  disk_check_events+0x26/0xa3
Mar 12 18:47:32 test kernel: [  367.542495]  disk_events_workfn+0x10/0x12
Mar 12 18:47:32 test kernel: [  367.542499]  process_one_work+0x107/0x198
Mar 12 18:47:32 test kernel: [  367.542508]  worker_thread+0x151/0x1e3
Mar 12 18:47:32 test kernel: [  367.542514]  kthread+0xd2/0xd7
Mar 12 18:47:32 test kernel: [  367.542519]  ? rescuer_thread+0x1ec/0x1ec
Mar 12 18:47:32 test kernel: [  367.542525]  ? kthread_complete_and_exit+0x16/0x16
Mar 12 18:47:32 test kernel: [  367.542531]  ret_from_fork+0x19/0x28
Mar 12 18:47:32 test kernel: [  367.542540] ------------[ cut here ]------------
Mar 12 18:47:32 test kernel: [  367.542543] Voluntary context switch within RCU read-side critical section!
Mar 12 18:47:32 test kernel: [  367.542552] WARNING: CPU: 0 PID: 17 at kernel/rcu/tree_plugin.h:318 rcu_note_context_switch+0x4e/0x27f
Mar 12 18:47:32 test kernel: [  367.542568] Modules linked in: epat pata_parport nouveau snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm psmouse snd_timer snd soundcore wmi hwmon serio_raw drm_ttm_helper 8139cp sg intel_agp i2c_dev parport_pc parport fuse
Mar 12 18:47:32 test kernel: [  367.542605] CPU: 0 PID: 17 Comm: kworker/0:1 Tainted: G        W         5.17.0-rc2+ #441
Mar 12 18:47:32 test kernel: [  367.542612] Hardware name:  /848P-ICH5, BIOS 6.00 PG 02/03/2005
Mar 12 18:47:32 test kernel: [  367.542616] Workqueue: events_freezable_power_ disk_events_workfn
Mar 12 18:47:32 test kernel: [  367.542624] EIP: rcu_note_context_switch+0x4e/0x27f
Mar 12 18:47:32 test kernel: [  367.542631] Code: 80 7d e3 00 75 27 8b 86 fc 01 00 00 85 c0 7e 1d 80 3d 95 06 87 d8 00 75 14 68 43 ad 6e d8 c6 05 95 06 87 d8 01 e8 ce e9 50 00 <0f> 0b 58 64 a1 cc 86 90 d8 8b 80 fc 01 00 00 85 c0 0f 8e dc 01 00
Mar 12 18:47:32 test kernel: [  367.542637] EAX: 0000003f EBX: c10bb780 ECX: ef9939cc EDX: 00000002
Mar 12 18:47:32 test kernel: [  367.542643] ESI: c10bb780 EDI: ef997840 EBP: c1093c5c ESP: c1093c38
Mar 12 18:47:32 test kernel: [  367.542648] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 EFLAGS: 00010096
Mar 12 18:47:32 test kernel: [  367.542654] CR0: 80050033 CR2: b5126000 CR3: 0d97c000 CR4: 00000690
Mar 12 18:47:32 test kernel: [  367.542660] Call Trace:
Mar 12 18:47:32 test kernel: [  367.542665]  ? preempt_count_add+0x4c/0x51
Mar 12 18:47:32 test kernel: [  367.542672]  ? dump_stack+0xd/0x10
Mar 12 18:47:32 test kernel: [  367.542677]  ? preempt_count_add+0x4c/0x51
Mar 12 18:47:32 test kernel: [  367.542683]  __schedule+0x63/0x456
Mar 12 18:47:32 test kernel: [  367.542691]  schedule+0x68/0xa3
Mar 12 18:47:32 test kernel: [  367.542697]  parport_claim_or_block+0x68/0xa5 [parport]
Mar 12 18:47:32 test kernel: [  367.542706]  ? init_wait_entry+0x21/0x21
Mar 12 18:47:32 test kernel: [  367.542713]  pi_connect+0x2b/0x3e [pata_parport]
Mar 12 18:47:32 test kernel: [  367.542720]  pata_parport_check_status+0x16/0x4e [pata_parport]
Mar 12 18:47:32 test kernel: [  367.542726]  ? pata_parport_lost_interrupt+0x7c/0x7c [pata_parport]
Mar 12 18:47:32 test kernel: [  367.542733]  ata_sff_busy_wait+0x27/0x3b
Mar 12 18:47:32 test kernel: [  367.542740]  ata_wait_idle+0x12/0x14
Mar 12 18:47:32 test kernel: [  367.542745]  ata_sff_qc_issue+0x27/0x106
Mar 12 18:47:32 test kernel: [  367.542752]  ata_qc_issue+0x14b/0x16b
Mar 12 18:47:32 test kernel: [  367.542758]  __ata_scsi_queuecmd+0x1c7/0x1d4
Mar 12 18:47:32 test kernel: [  367.542763]  ? ata_scsiop_inq_83+0xb3/0xb3
Mar 12 18:47:32 test kernel: [  367.542769]  ata_scsi_queuecmd+0x36/0x5f
Mar 12 18:47:32 test kernel: [  367.542774]  scsi_queue_rq+0x577/0x69e
Mar 12 18:47:32 test kernel: [  367.542782]  blk_mq_dispatch_rq_list+0x229/0x3e4
Mar 12 18:47:32 test kernel: [  367.542789]  ? __sbitmap_get_word+0x28/0x5a
Mar 12 18:47:32 test kernel: [  367.542797]  __blk_mq_sched_dispatch_requests+0x7b/0xdb
Mar 12 18:47:32 test kernel: [  367.542804]  blk_mq_sched_dispatch_requests+0x25/0x46
Mar 12 18:47:32 test kernel: [  367.542809]  __blk_mq_run_hw_queue+0x36/0x6b
Mar 12 18:47:32 test kernel: [  367.542816]  __blk_mq_delay_run_hw_queue+0x54/0x11d
Mar 12 18:47:32 test kernel: [  367.542823]  blk_mq_run_hw_queue+0xa5/0xab
Mar 12 18:47:32 test kernel: [  367.542829]  blk_mq_sched_insert_request+0xa2/0xaa
Mar 12 18:47:32 test kernel: [  367.542835]  ? update_io_ticks+0x2a/0x5b
Mar 12 18:47:32 test kernel: [  367.542842]  blk_execute_rq_nowait+0x3f/0x47
Mar 12 18:47:32 test kernel: [  367.542848]  blk_execute_rq+0x3a/0xa4
Mar 12 18:47:32 test kernel: [  367.542854]  __scsi_execute+0x90/0x133
Mar 12 18:47:32 test kernel: [  367.542861]  scsi_test_unit_ready+0x43/0x95
Mar 12 18:47:32 test kernel: [  367.542868]  sd_check_events+0x8b/0xf6
Mar 12 18:47:32 test kernel: [  367.542874]  ? media_not_present+0x3b/0x3b
Mar 12 18:47:32 test kernel: [  367.542879]  disk_check_events+0x26/0xa3
Mar 12 18:47:32 test kernel: [  367.542885]  disk_events_workfn+0x10/0x12
Mar 12 18:47:32 test kernel: [  367.542890]  process_one_work+0x107/0x198
Mar 12 18:47:32 test kernel: [  367.542898]  worker_thread+0x151/0x1e3
Mar 12 18:47:32 test kernel: [  367.542904]  kthread+0xd2/0xd7
Mar 12 18:47:32 test kernel: [  367.542909]  ? rescuer_thread+0x1ec/0x1ec
Mar 12 18:47:32 test kernel: [  367.542915]  ? kthread_complete_and_exit+0x16/0x16
Mar 12 18:47:32 test kernel: [  367.542921]  ret_from_fork+0x19/0x28
Mar 12 18:47:32 test kernel: [  367.542928] ---[ end trace 0000000000000000 ]---
Mar 12 18:47:32 test kernel: [  367.650552] ------------[ cut here ]------------
Mar 12 18:47:32 test kernel: [  367.650568] DEBUG_LOCKS_WARN_ON(val > preempt_count())
Mar 12 18:47:32 test kernel: [  367.650576] WARNING: CPU: 0 PID: 17 at kernel/sched/core.c:5474 preempt_count_sub+0x3e/0x7f
Mar 12 18:47:32 test kernel: [  367.650595] Modules linked in: epat pata_parport nouveau snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm psmouse snd_timer snd soundcore wmi hwmon serio_raw drm_ttm_helper 8139cp sg intel_agp i2c_dev parport_pc parport fuse
Mar 12 18:47:32 test kernel: [  367.650641] CPU: 0 PID: 17 Comm: kworker/0:1 Tainted: G        W         5.17.0-rc2+ #441
Mar 12 18:47:32 test kernel: [  367.650649] Hardware name:  /848P-ICH5, BIOS 6.00 PG 02/03/2005
Mar 12 18:47:32 test kernel: [  367.650655] Workqueue: events_freezable_power_ disk_events_workfn
Mar 12 18:47:32 test kernel: [  367.650665] EIP: preempt_count_sub+0x3e/0x7f
Mar 12 18:47:32 test kernel: [  367.650672] Code: e2 ff ff ff 7f 39 c2 7d 25 e8 9d f4 19 00 85 c0 74 57 83 3d b4 2c 87 d8 00 75 4e 68 0a 6c 6e d8 68 db a7 6d d8 e8 3d b4 53 00 <0f> 0b eb 2e 3d fe 00 00 00 77 2b 84 d2 75 27 e8 6d f4 19 00 85 c0
Mar 12 18:47:32 test kernel: [  367.650679] EAX: 0000002a EBX: 00000000 ECX: ef9939cc EDX: 00000001
Mar 12 18:47:32 test kernel: [  367.650685] ESI: d4974000 EDI: 00000293 EBP: c1093d30 ESP: c1093d28
Mar 12 18:47:32 test kernel: [  367.650690] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 EFLAGS: 00010292
Mar 12 18:47:32 test kernel: [  367.650697] CR0: 80050033 CR2: b0eae6ec CR3: 035b5000 CR4: 00000690
Mar 12 18:47:32 test kernel: [  367.650704] Call Trace:
Mar 12 18:47:32 test kernel: [  367.650711]  _raw_spin_unlock_irqrestore+0x17/0x28
Mar 12 18:47:32 test kernel: [  367.650720]  ata_scsi_queuecmd+0x57/0x5f
Mar 12 18:47:32 test kernel: [  367.650728]  scsi_queue_rq+0x577/0x69e
Mar 12 18:47:32 test kernel: [  367.650737]  blk_mq_dispatch_rq_list+0x229/0x3e4
Mar 12 18:47:32 test kernel: [  367.650743]  ? __sbitmap_get_word+0x28/0x5a
Mar 12 18:47:32 test kernel: [  367.650753]  __blk_mq_sched_dispatch_requests+0x7b/0xdb
Mar 12 18:47:32 test kernel: [  367.650760]  blk_mq_sched_dispatch_requests+0x25/0x46
Mar 12 18:47:32 test kernel: [  367.650766]  __blk_mq_run_hw_queue+0x36/0x6b
Mar 12 18:47:32 test kernel: [  367.650774]  __blk_mq_delay_run_hw_queue+0x54/0x11d
Mar 12 18:47:32 test kernel: [  367.650781]  blk_mq_run_hw_queue+0xa5/0xab
Mar 12 18:47:32 test kernel: [  367.650788]  blk_mq_sched_insert_request+0xa2/0xaa
Mar 12 18:47:32 test kernel: [  367.650793]  ? update_io_ticks+0x2a/0x5b
Mar 12 18:47:32 test kernel: [  367.650801]  blk_execute_rq_nowait+0x3f/0x47
Mar 12 18:47:32 test kernel: [  367.650808]  blk_execute_rq+0x3a/0xa4
Mar 12 18:47:32 test kernel: [  367.650815]  __scsi_execute+0x90/0x133
Mar 12 18:47:32 test kernel: [  367.650822]  scsi_test_unit_ready+0x43/0x95
Mar 12 18:47:32 test kernel: [  367.650830]  sd_check_events+0x8b/0xf6
Mar 12 18:47:32 test kernel: [  367.650836]  ? media_not_present+0x3b/0x3b
Mar 12 18:47:32 test kernel: [  367.650842]  disk_check_events+0x26/0xa3
Mar 12 18:47:32 test kernel: [  367.650848]  disk_events_workfn+0x10/0x12
Mar 12 18:47:32 test kernel: [  367.650853]  process_one_work+0x107/0x198
Mar 12 18:47:32 test kernel: [  367.650862]  worker_thread+0x151/0x1e3
Mar 12 18:47:32 test kernel: [  367.650868]  kthread+0xd2/0xd7
Mar 12 18:47:32 test kernel: [  367.650874]  ? rescuer_thread+0x1ec/0x1ec
Mar 12 18:47:32 test kernel: [  367.650880]  ? kthread_complete_and_exit+0x16/0x16
Mar 12 18:47:32 test kernel: [  367.650886]  ret_from_fork+0x19/0x28
Mar 12 18:47:32 test kernel: [  367.650895] ---[ end trace 0000000000000000 ]---
Mar 12 18:47:32 test kernel: [  367.658169] Modules linked in: epat pata_parport nouveau snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm psmouse snd_timer snd soundcore wmi hwmon serio_raw drm_ttm_helper 8139cp sg intel_agp i2c_dev parport_pc parport fuse
Mar 12 18:47:32 test kernel: [  367.658232] CPU: 0 PID: 561 Comm: scsi_eh_5 Tainted: G        W         5.17.0-rc2+ #441
Mar 12 18:47:32 test kernel: [  367.658240] Hardware name:  /848P-ICH5, BIOS 6.00 PG 02/03/2005
Mar 12 18:47:32 test kernel: [  367.658244] Call Trace:
Mar 12 18:47:32 test kernel: [  367.658251]  dump_stack_lvl+0x32/0x41
Mar 12 18:47:32 test kernel: [  367.658260]  ? preempt_count_add+0x4c/0x51
Mar 12 18:47:32 test kernel: [  367.658266]  dump_stack+0xd/0x10
Mar 12 18:47:32 test kernel: [  367.658272]  __schedule_bug+0x90/0xa1
Mar 12 18:47:32 test kernel: [  367.658278]  __schedule+0x3b/0x456
Mar 12 18:47:32 test kernel: [  367.658286]  ? _raw_spin_lock_irqsave+0x1b/0x21
Mar 12 18:47:32 test kernel: [  367.658293]  schedule+0x68/0xa3
Mar 12 18:47:32 test kernel: [  367.658300]  parport_claim_or_block+0x68/0xa5 [parport]
Mar 12 18:47:32 test kernel: [  367.658313]  ? init_wait_entry+0x21/0x21
Mar 12 18:47:32 test kernel: [  367.658321]  pi_connect+0x2b/0x3e [pata_parport]
Mar 12 18:47:32 test kernel: [  367.658329]  pata_parport_check_status+0x16/0x4e [pata_parport]
Mar 12 18:47:32 test kernel: [  367.658338]  pata_parport_drain_fifo+0x2b/0x7c [pata_parport]
Mar 12 18:47:32 test kernel: [  367.658345]  ? ata_sff_prereset+0x7e/0x7e
Mar 12 18:47:32 test kernel: [  367.658354]  ata_sff_error_handler+0x68/0xb6
Mar 12 18:47:32 test kernel: [  367.658361]  ? pata_parport_devchk+0x11e/0x11e [pata_parport]
Mar 12 18:47:32 test kernel: [  367.658369]  ata_scsi_port_error_handler+0x1cf/0x46a
Mar 12 18:47:32 test kernel: [  367.658376]  ata_scsi_error+0x74/0x85
Mar 12 18:47:32 test kernel: [  367.658383]  scsi_error_handler+0x11a/0x461
Mar 12 18:47:32 test kernel: [  367.658391]  ? _raw_spin_lock_irqsave+0x1b/0x21
Mar 12 18:47:32 test kernel: [  367.658397]  ? _raw_spin_unlock_irqrestore+0x17/0x28
Mar 12 18:47:32 test kernel: [  367.658402]  ? __kthread_parkme+0x2c/0x70
Mar 12 18:47:32 test kernel: [  367.658409]  kthread+0xd2/0xd7
Mar 12 18:47:32 test kernel: [  367.658415]  ? scsi_eh_get_sense+0x176/0x176
Mar 12 18:47:32 test kernel: [  367.658421]  ? kthread_complete_and_exit+0x16/0x16
Mar 12 18:47:32 test kernel: [  367.658427]  ret_from_fork+0x19/0x28
Mar 12 18:47:32 test kernel: [  367.815293] sd 5:0:0:0: [sdc] Media removed, stopped polling


-- 
Ondrej Zary


From linux at zary.sk  Sun Mar 13 14:19:58 2022
From: linux at zary.sk (Ondrej Zary)
Date: Sun, 13 Mar 2022 22:19:58 +0100
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <a8189d8e-03e2-1b6f-3251-8e44e4e5e423@omp.ru>
References: <20220312144415.20010-1-linux@zary.sk>
 <a8189d8e-03e2-1b6f-3251-8e44e4e5e423@omp.ru>
Message-ID: <202203132219.59100.linux@zary.sk>

On Sunday 13 March 2022 21:38:10 Sergey Shtylyov wrote:
> Hello!
> 
> On 3/12/22 5:44 PM, Ondrej Zary wrote:
> 
> > The pata_parport is a libata-based replacement of the old PARIDE
> > subsystem - driver for parallel port IDE devices.
> > It uses the original paride low-level protocol drivers but does not
> > need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
> > behind parallel port adapters are handled by the ATA layer.
> > 
> > This will allow paride and its high-level drivers to be removed.
> > 
> > paride and pata_parport are mutually exclusive because the compiled
> > protocol drivers are incompatible.
> > 
> > Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
> > chip).
> > 
> > Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
> > drivers - they don't handle non-multiple-of-4 block transfers
> > correctly. This causes problems with LS-120 drive.
> > There is also another bug in EPAT: EPP modes don't work unless a 4-bit
> > or 8-bit mode is used first (probably some initialization missing?).
> > Once the device is initialized, EPP works until power cycle.
> > 
> > So after device power on, you have to:
> > echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
> > echo pata_parport.0 >/sys/bus/pata_parport/delete_device
> > echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
> > (autoprobe will initialize correctly as it tries the slowest modes
> > first but you'll get the broken EPP-32 mode)
> > 
> > Signed-off-by: Ondrej Zary <linux at zary.sk>
> [...]
> > diff --git a/Documentation/admin-guide/blockdev/paride.rst b/Documentation/admin-guide/blockdev/paride.rst
> > index e1ce90af602a..e431a1ef41eb 100644
> > --- a/Documentation/admin-guide/blockdev/paride.rst
> > +++ b/Documentation/admin-guide/blockdev/paride.rst
> [...]
> > diff --git a/drivers/ata/pata_parport.c b/drivers/ata/pata_parport.c
> > new file mode 100644
> > index 000000000000..783764626a27
> > --- /dev/null
> > +++ b/drivers/ata/pata_parport.c
> > @@ -0,0 +1,819 @@
> [...]
> > +static void pata_parport_lost_interrupt(struct ata_port *ap)
> > +{
> > +	u8 status;
> > +	struct ata_queued_cmd *qc;
> > +
> > +	/* Only one outstanding command per SFF channel */
> > +	qc = ata_qc_from_tag(ap, ap->link.active_tag);
> > +	/* We cannot lose an interrupt on a non-existent or polled command */
> > +	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
> > +		return;
> > +	/*
> > +	 * See if the controller thinks it is still busy - if so the command
> > +	 * isn't a lost IRQ but is still in progress
> > +	 */
> > +	status = pata_parport_check_altstatus(ap);
> > +	if (status & ATA_BUSY)
> > +		return;
> > +
> > +	/*
> > +	 * There was a command running, we are no longer busy and we have
> > +	 * no interrupt.
> > +	 */
> > +	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
> > +	/* Run the host interrupt logic as if the interrupt had not been lost */
> > +	ata_sff_port_intr(ap, qc);
> > +}
> 
>    As I said, ata_sff_lost_interrupt() could be used instead...

It couldn't be used because it calls ata_sff_altstatus().

> [...]
> > +static void pi_remove_one(struct device *dev)
> > +{
> > +	struct ata_host *host = dev_get_drvdata(dev);
> > +	struct pi_adapter *pi = host->private_data;
> > +
> > +	ata_host_detach(host);
> > +	del_timer_sync(&pi->timer);
> > +	if (pi->claimed) {
> > +		pi->proto->disconnect(pi);
> > +		parport_release(pi->pardev);
> > +	}
> 
>    This duplicates most of pci_disconnect_timer(), worth factoring out?
> 
> > +	pi_release(pi);
> > +	device_unregister(dev);
> > +	ida_free(&pata_parport_bus_dev_ids, dev->id);
> > +	/* pata_parport_dev_release will do kfree(pi) */
> > +}
> [...]
> > diff --git a/include/linux/pata_parport.h b/include/linux/pata_parport.h
> > new file mode 100644
> > index 000000000000..f1ba57bb319c
> > --- /dev/null
> > +++ b/include/linux/pata_parport.h
> > @@ -0,0 +1,108 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + *	pata_parport.h	(c) 1997-8  Grant R. Guenther <grant at torque.net>
> > + *				    Under the terms of the GPL.
> > + *
> > + * This file defines the interface for parallel port IDE adapter chip drivers.
> > + */
> > +
> > +#include <linux/libata.h>
> > +
> > +#define PI_PCD	1	/* dummy for paride protocol modules */
> > +
> > +struct pi_adapter {
> > +	struct device dev;
> > +	struct pi_protocol *proto;	/* adapter protocol */
> > +	int port;			/* base address of parallel port */
> > +	int mode;			/* transfer mode in use */
> > +	int delay;			/* adapter delay setting */
> > +	int devtype;			/* dummy for paride protocol modules */
> > +	char *device;			/* dummy for paride protocol modules */
> > +	int unit;			/* unit number for chained adapters */
> > +	int saved_r0;			/* saved port state */
> > +	int saved_r2;			/* saved port state */
> > +	unsigned long private;		/* for protocol module */
> > +	struct pardevice *pardev;	/* pointer to pardevice */
> > +	bool claimed;			/* parport has already been claimed */
> > +	struct timer_list timer;	/* disconnect timer */
> > +};
> > +
> > +typedef struct pi_adapter PIA;	/* for paride protocol modules */
> > +
> > +/* registers are addressed as (cont,regr)
> > + *	cont: 0 for command register file, 1 for control register(s)
> > + *	regr: 0-7 for register number.
> > + */
> > +
> > +/* macros and functions exported to the protocol modules */
> > +#define delay_p			(pi->delay ? udelay(pi->delay) : (void)0)
> > +#define out_p(offs, byte)	do { outb(byte, pi->port + offs); delay_p; } while (0)
> > +#define in_p(offs)		(delay_p, inb(pi->port + offs))
> > +
> > +#define w0(byte)		out_p(0, byte)
> > +#define r0()			(in_p(0) & 0xff)
> > +#define w1(byte)		out_p(1, byte)
> > +#define r1()			(in_p(1) & 0xff)
> > +#define w2(byte)		out_p(2, byte)
> > +#define r2()			(in_p(2) & 0xff)
> > +#define w3(byte)		out_p(3, byte)
> > +#define w4(byte)		out_p(4, byte)
> > +#define r4()			(in_p(4) & 0xff)
> > +#define w4w(data)		do { outw(data, pi->port + 4); delay_p; } while (0)
> > +#define w4l(data)		do { outl(data, pi->port + 4); delay_p; } while (0)
> > +#define r4w()			(delay_p, inw(pi->port + 4) & 0xffff)
> > +#define r4l()			(delay_p, inl(pi->port + 4) & 0xffffffff)
> > +
> 
>    I still don't think all this masking achieves anything...

It comes from old paride.h. I'll drop the masking. I will delete this completely after paride removal.

> > +static inline u16 pi_swab16(char *b, int k)
> > +{
> > +	union { u16 u; char t[2]; } r;
> > +
> > +	r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k];
> > +	return r.u;
> > +}
> > +
> > +static inline u32 pi_swab32(char *b, int k)
> > +{
> > +	union { u32 u; char f[4]; } r;
> > +
> > +	r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k];
> > +	r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2];
> > +	return r.u;
> 
>    Hey, I was serious about swab{16|32}p()! Please don't use home grown byte
> swapping...

This crap comes from old paride.h and we can't get rid of it without touching the protocol drivers (comm.c and kbic.c). Maybe use something like:

#define pi_swab16(char *b, int k) 	swab16p((u16 *)&b[2 * k])

but I'm not sure it's equivalent on a big-endian machine.
 
> [...]
> 
> MBR, Sergey
> 


-- 
Ondrej Zary


From axboe at kernel.dk  Sun Mar 13 16:19:30 2022
From: axboe at kernel.dk (Jens Axboe)
Date: Sun, 13 Mar 2022 17:19:30 -0600
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <202203132015.18183.linux@zary.sk>
References: <20220312144415.20010-1-linux@zary.sk>
 <202203132015.18183.linux@zary.sk>
Message-ID: <5161ed17-5f55-e851-c2e2-5340cc62fa3b@kernel.dk>

On 3/13/22 1:15 PM, Ondrej Zary wrote:
> On Saturday 12 March 2022 15:44:15 Ondrej Zary wrote:
>> The pata_parport is a libata-based replacement of the old PARIDE
>> subsystem - driver for parallel port IDE devices.
>> It uses the original paride low-level protocol drivers but does not
>> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
>> behind parallel port adapters are handled by the ATA layer.
>>
>> This will allow paride and its high-level drivers to be removed.
>>
>> paride and pata_parport are mutually exclusive because the compiled
>> protocol drivers are incompatible.
>>
>> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
>> chip).
>>
>> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
>> drivers - they don't handle non-multiple-of-4 block transfers
>> correctly. This causes problems with LS-120 drive.
>> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
>> or 8-bit mode is used first (probably some initialization missing?).
>> Once the device is initialized, EPP works until power cycle.
>>
>> So after device power on, you have to:
>> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
>> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
>> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
>> (autoprobe will initialize correctly as it tries the slowest modes
>> first but you'll get the broken EPP-32 mode)
> 
> Found a bug - the same device can be registered multiple times. Fix
> will be in v2. But this revealed a bigger problem: pi_connect can
> sleep (uses parport_claim_or_block) and libata does not like that. Any
> ideas how to fix this?

I think you'd need two things here:

- The blk-mq queue should be registered with BLK_MQ_F_BLOCKING, which
  will allow blocking off the queue_rq path.

- You need to look at making libata safe wrt calling ata_qc_issue()
  outside the lock. Should probably be fine if you just gate that on
  whether or not the queue was setup in blocking mode, as that doesn't
  currently exist in libata.

-- 
Jens Axboe



From s.shtylyov at omp.ru  Sun Mar 13 13:38:10 2022
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Sun, 13 Mar 2022 23:38:10 +0300
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <20220312144415.20010-1-linux@zary.sk>
References: <20220312144415.20010-1-linux@zary.sk>
Message-ID: <a8189d8e-03e2-1b6f-3251-8e44e4e5e423@omp.ru>

Hello!

On 3/12/22 5:44 PM, Ondrej Zary wrote:

> The pata_parport is a libata-based replacement of the old PARIDE
> subsystem - driver for parallel port IDE devices.
> It uses the original paride low-level protocol drivers but does not
> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
> behind parallel port adapters are handled by the ATA layer.
> 
> This will allow paride and its high-level drivers to be removed.
> 
> paride and pata_parport are mutually exclusive because the compiled
> protocol drivers are incompatible.
> 
> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
> chip).
> 
> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
> drivers - they don't handle non-multiple-of-4 block transfers
> correctly. This causes problems with LS-120 drive.
> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
> or 8-bit mode is used first (probably some initialization missing?).
> Once the device is initialized, EPP works until power cycle.
> 
> So after device power on, you have to:
> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
> (autoprobe will initialize correctly as it tries the slowest modes
> first but you'll get the broken EPP-32 mode)
> 
> Signed-off-by: Ondrej Zary <linux at zary.sk>
[...]
> diff --git a/Documentation/admin-guide/blockdev/paride.rst b/Documentation/admin-guide/blockdev/paride.rst
> index e1ce90af602a..e431a1ef41eb 100644
> --- a/Documentation/admin-guide/blockdev/paride.rst
> +++ b/Documentation/admin-guide/blockdev/paride.rst
[...]
> diff --git a/drivers/ata/pata_parport.c b/drivers/ata/pata_parport.c
> new file mode 100644
> index 000000000000..783764626a27
> --- /dev/null
> +++ b/drivers/ata/pata_parport.c
> @@ -0,0 +1,819 @@
[...]
> +static void pata_parport_lost_interrupt(struct ata_port *ap)
> +{
> +	u8 status;
> +	struct ata_queued_cmd *qc;
> +
> +	/* Only one outstanding command per SFF channel */
> +	qc = ata_qc_from_tag(ap, ap->link.active_tag);
> +	/* We cannot lose an interrupt on a non-existent or polled command */
> +	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
> +		return;
> +	/*
> +	 * See if the controller thinks it is still busy - if so the command
> +	 * isn't a lost IRQ but is still in progress
> +	 */
> +	status = pata_parport_check_altstatus(ap);
> +	if (status & ATA_BUSY)
> +		return;
> +
> +	/*
> +	 * There was a command running, we are no longer busy and we have
> +	 * no interrupt.
> +	 */
> +	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
> +	/* Run the host interrupt logic as if the interrupt had not been lost */
> +	ata_sff_port_intr(ap, qc);
> +}

   As I said, ata_sff_lost_interrupt() could be used instead...

[...]
> +static void pi_remove_one(struct device *dev)
> +{
> +	struct ata_host *host = dev_get_drvdata(dev);
> +	struct pi_adapter *pi = host->private_data;
> +
> +	ata_host_detach(host);
> +	del_timer_sync(&pi->timer);
> +	if (pi->claimed) {
> +		pi->proto->disconnect(pi);
> +		parport_release(pi->pardev);
> +	}

   This duplicates most of pci_disconnect_timer(), worth factoring out?

> +	pi_release(pi);
> +	device_unregister(dev);
> +	ida_free(&pata_parport_bus_dev_ids, dev->id);
> +	/* pata_parport_dev_release will do kfree(pi) */
> +}
[...]
> diff --git a/include/linux/pata_parport.h b/include/linux/pata_parport.h
> new file mode 100644
> index 000000000000..f1ba57bb319c
> --- /dev/null
> +++ b/include/linux/pata_parport.h
> @@ -0,0 +1,108 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + *	pata_parport.h	(c) 1997-8  Grant R. Guenther <grant at torque.net>
> + *				    Under the terms of the GPL.
> + *
> + * This file defines the interface for parallel port IDE adapter chip drivers.
> + */
> +
> +#include <linux/libata.h>
> +
> +#define PI_PCD	1	/* dummy for paride protocol modules */
> +
> +struct pi_adapter {
> +	struct device dev;
> +	struct pi_protocol *proto;	/* adapter protocol */
> +	int port;			/* base address of parallel port */
> +	int mode;			/* transfer mode in use */
> +	int delay;			/* adapter delay setting */
> +	int devtype;			/* dummy for paride protocol modules */
> +	char *device;			/* dummy for paride protocol modules */
> +	int unit;			/* unit number for chained adapters */
> +	int saved_r0;			/* saved port state */
> +	int saved_r2;			/* saved port state */
> +	unsigned long private;		/* for protocol module */
> +	struct pardevice *pardev;	/* pointer to pardevice */
> +	bool claimed;			/* parport has already been claimed */
> +	struct timer_list timer;	/* disconnect timer */
> +};
> +
> +typedef struct pi_adapter PIA;	/* for paride protocol modules */
> +
> +/* registers are addressed as (cont,regr)
> + *	cont: 0 for command register file, 1 for control register(s)
> + *	regr: 0-7 for register number.
> + */
> +
> +/* macros and functions exported to the protocol modules */
> +#define delay_p			(pi->delay ? udelay(pi->delay) : (void)0)
> +#define out_p(offs, byte)	do { outb(byte, pi->port + offs); delay_p; } while (0)
> +#define in_p(offs)		(delay_p, inb(pi->port + offs))
> +
> +#define w0(byte)		out_p(0, byte)
> +#define r0()			(in_p(0) & 0xff)
> +#define w1(byte)		out_p(1, byte)
> +#define r1()			(in_p(1) & 0xff)
> +#define w2(byte)		out_p(2, byte)
> +#define r2()			(in_p(2) & 0xff)
> +#define w3(byte)		out_p(3, byte)
> +#define w4(byte)		out_p(4, byte)
> +#define r4()			(in_p(4) & 0xff)
> +#define w4w(data)		do { outw(data, pi->port + 4); delay_p; } while (0)
> +#define w4l(data)		do { outl(data, pi->port + 4); delay_p; } while (0)
> +#define r4w()			(delay_p, inw(pi->port + 4) & 0xffff)
> +#define r4l()			(delay_p, inl(pi->port + 4) & 0xffffffff)
> +

   I still don't think all this masking achieves anything...

> +static inline u16 pi_swab16(char *b, int k)
> +{
> +	union { u16 u; char t[2]; } r;
> +
> +	r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k];
> +	return r.u;
> +}
> +
> +static inline u32 pi_swab32(char *b, int k)
> +{
> +	union { u32 u; char f[4]; } r;
> +
> +	r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k];
> +	r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2];
> +	return r.u;

   Hey, I was serious about swab{16|32}p()! Please don't use home grown byte
swapping...

[...]

MBR, Sergey


From linux at zary.sk  Mon Mar 14 13:25:40 2022
From: linux at zary.sk (Ondrej Zary)
Date: Mon, 14 Mar 2022 21:25:40 +0100
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <5161ed17-5f55-e851-c2e2-5340cc62fa3b@kernel.dk>
References: <20220312144415.20010-1-linux@zary.sk>
 <202203132015.18183.linux@zary.sk>
 <5161ed17-5f55-e851-c2e2-5340cc62fa3b@kernel.dk>
Message-ID: <202203142125.40532.linux@zary.sk>

On Monday 14 March 2022 00:19:30 Jens Axboe wrote:
> On 3/13/22 1:15 PM, Ondrej Zary wrote:
> > On Saturday 12 March 2022 15:44:15 Ondrej Zary wrote:
> >> The pata_parport is a libata-based replacement of the old PARIDE
> >> subsystem - driver for parallel port IDE devices.
> >> It uses the original paride low-level protocol drivers but does not
> >> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
> >> behind parallel port adapters are handled by the ATA layer.
> >>
> >> This will allow paride and its high-level drivers to be removed.
> >>
> >> paride and pata_parport are mutually exclusive because the compiled
> >> protocol drivers are incompatible.
> >>
> >> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
> >> chip).
> >>
> >> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
> >> drivers - they don't handle non-multiple-of-4 block transfers
> >> correctly. This causes problems with LS-120 drive.
> >> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
> >> or 8-bit mode is used first (probably some initialization missing?).
> >> Once the device is initialized, EPP works until power cycle.
> >>
> >> So after device power on, you have to:
> >> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
> >> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
> >> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
> >> (autoprobe will initialize correctly as it tries the slowest modes
> >> first but you'll get the broken EPP-32 mode)
> > 
> > Found a bug - the same device can be registered multiple times. Fix
> > will be in v2. But this revealed a bigger problem: pi_connect can
> > sleep (uses parport_claim_or_block) and libata does not like that. Any
> > ideas how to fix this?
> 
> I think you'd need two things here:
> 
> - The blk-mq queue should be registered with BLK_MQ_F_BLOCKING, which
>   will allow blocking off the queue_rq path.

My knowledge about blk-mq is exactly zero. After grepping the code, I guess that BLK_MQ_F_BLOCKING should be used by the block device drivers - sd and sr?
 
> - You need to look at making libata safe wrt calling ata_qc_issue()
>   outside the lock. Should probably be fine if you just gate that on
>   whether or not the queue was setup in blocking mode, as that doesn't
>   currently exist in libata.
> 


-- 
Ondrej Zary


From axboe at kernel.dk  Mon Mar 14 13:29:20 2022
From: axboe at kernel.dk (Jens Axboe)
Date: Mon, 14 Mar 2022 14:29:20 -0600
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <202203142125.40532.linux@zary.sk>
References: <20220312144415.20010-1-linux@zary.sk>
 <202203132015.18183.linux@zary.sk>
 <5161ed17-5f55-e851-c2e2-5340cc62fa3b@kernel.dk>
 <202203142125.40532.linux@zary.sk>
Message-ID: <f8c176d4-74f0-3e4f-446f-2a5f8ace3b28@kernel.dk>

On 3/14/22 2:25 PM, Ondrej Zary wrote:
> On Monday 14 March 2022 00:19:30 Jens Axboe wrote:
>> On 3/13/22 1:15 PM, Ondrej Zary wrote:
>>> On Saturday 12 March 2022 15:44:15 Ondrej Zary wrote:
>>>> The pata_parport is a libata-based replacement of the old PARIDE
>>>> subsystem - driver for parallel port IDE devices.
>>>> It uses the original paride low-level protocol drivers but does not
>>>> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
>>>> behind parallel port adapters are handled by the ATA layer.
>>>>
>>>> This will allow paride and its high-level drivers to be removed.
>>>>
>>>> paride and pata_parport are mutually exclusive because the compiled
>>>> protocol drivers are incompatible.
>>>>
>>>> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
>>>> chip).
>>>>
>>>> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
>>>> drivers - they don't handle non-multiple-of-4 block transfers
>>>> correctly. This causes problems with LS-120 drive.
>>>> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
>>>> or 8-bit mode is used first (probably some initialization missing?).
>>>> Once the device is initialized, EPP works until power cycle.
>>>>
>>>> So after device power on, you have to:
>>>> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
>>>> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
>>>> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
>>>> (autoprobe will initialize correctly as it tries the slowest modes
>>>> first but you'll get the broken EPP-32 mode)
>>>
>>> Found a bug - the same device can be registered multiple times. Fix
>>> will be in v2. But this revealed a bigger problem: pi_connect can
>>> sleep (uses parport_claim_or_block) and libata does not like that. Any
>>> ideas how to fix this?
>>
>> I think you'd need two things here:
>>
>> - The blk-mq queue should be registered with BLK_MQ_F_BLOCKING, which
>>   will allow blocking off the queue_rq path.
> 
> My knowledge about blk-mq is exactly zero. After grepping the code, I
> guess that BLK_MQ_F_BLOCKING should be used by the block device
> drivers - sd and sr?

The controller would set

->needs_blocking_queue_rq = true;

or something, and we'd default to false. And if that is set, when the
blk-mq queue is created, then we'd set BLK_MQ_F_BLOCKING upon creation
if that flag is true.

That's the block layer side. Then in libata you'd need to ensure that
you check that same setting and invoke ata_qc_issue() appropriately.

Very top level stuff, there might be more things lurking below. But
you'll probably find them as you test this stuff...

-- 
Jens Axboe



From damien.lemoal at opensource.wdc.com  Mon Mar 14 21:22:47 2022
From: damien.lemoal at opensource.wdc.com (Damien Le Moal)
Date: Tue, 15 Mar 2022 13:22:47 +0900
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <f8c176d4-74f0-3e4f-446f-2a5f8ace3b28@kernel.dk>
References: <20220312144415.20010-1-linux@zary.sk>
 <202203132015.18183.linux@zary.sk>
 <5161ed17-5f55-e851-c2e2-5340cc62fa3b@kernel.dk>
 <202203142125.40532.linux@zary.sk>
 <f8c176d4-74f0-3e4f-446f-2a5f8ace3b28@kernel.dk>
Message-ID: <8f32b2ed-13d6-c357-e417-b86a57a285db@opensource.wdc.com>

On 3/15/22 05:29, Jens Axboe wrote:
> On 3/14/22 2:25 PM, Ondrej Zary wrote:
>> On Monday 14 March 2022 00:19:30 Jens Axboe wrote:
>>> On 3/13/22 1:15 PM, Ondrej Zary wrote:
>>>> On Saturday 12 March 2022 15:44:15 Ondrej Zary wrote:
>>>>> The pata_parport is a libata-based replacement of the old PARIDE
>>>>> subsystem - driver for parallel port IDE devices.
>>>>> It uses the original paride low-level protocol drivers but does not
>>>>> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
>>>>> behind parallel port adapters are handled by the ATA layer.
>>>>>
>>>>> This will allow paride and its high-level drivers to be removed.
>>>>>
>>>>> paride and pata_parport are mutually exclusive because the compiled
>>>>> protocol drivers are incompatible.
>>>>>
>>>>> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
>>>>> chip).
>>>>>
>>>>> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
>>>>> drivers - they don't handle non-multiple-of-4 block transfers
>>>>> correctly. This causes problems with LS-120 drive.
>>>>> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
>>>>> or 8-bit mode is used first (probably some initialization missing?).
>>>>> Once the device is initialized, EPP works until power cycle.
>>>>>
>>>>> So after device power on, you have to:
>>>>> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
>>>>> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
>>>>> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
>>>>> (autoprobe will initialize correctly as it tries the slowest modes
>>>>> first but you'll get the broken EPP-32 mode)
>>>>
>>>> Found a bug - the same device can be registered multiple times. Fix
>>>> will be in v2. But this revealed a bigger problem: pi_connect can
>>>> sleep (uses parport_claim_or_block) and libata does not like that. Any
>>>> ideas how to fix this?
>>>
>>> I think you'd need two things here:
>>>
>>> - The blk-mq queue should be registered with BLK_MQ_F_BLOCKING, which
>>>   will allow blocking off the queue_rq path.
>>
>> My knowledge about blk-mq is exactly zero. After grepping the code, I
>> guess that BLK_MQ_F_BLOCKING should be used by the block device
>> drivers - sd and sr?
> 
> The controller would set
> 
> ->needs_blocking_queue_rq = true;
> 
> or something, and we'd default to false. And if that is set, when the
> blk-mq queue is created, then we'd set BLK_MQ_F_BLOCKING upon creation
> if that flag is true.
> 
> That's the block layer side. Then in libata you'd need to ensure that
> you check that same setting and invoke ata_qc_issue() appropriately.
> 
> Very top level stuff, there might be more things lurking below. But
> you'll probably find them as you test this stuff...

Yes, the ata_port spinlock being held when calling ata_qc_issue() is
mandatory. But since I am assuming that all the IDE devices connected to
this adapter are QD=1 maximum, there can only be only one command in
flight. So it may be OK to release that lock before calling pi_connect()
and retake it right after it. libsas actually does something similar
(for no good reasons in that case though).

Jens point remain though that since pi_connect() can sleep, marking the
device queue with BLK_MQ_F_BLOCKING is mandatory.

-- 
Damien Le Moal
Western Digital Research


From hch at lst.de  Tue Mar 15 01:23:01 2022
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 15 Mar 2022 09:23:01 +0100
Subject: [Linux-parport] [PATCH v0] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <202203121221.56068.linux@zary.sk>
References: <20220310212812.13944-1-linux@zary.sk>
 <202203111955.15743.linux@zary.sk>
 <c0a6065c-3e89-a4be-e257-ce25711e4368@opensource.wdc.com>
 <202203121221.56068.linux@zary.sk>
Message-ID: <20220315082301.GA3502@lst.de>

On Sat, Mar 12, 2022 at 12:21:55PM +0100, Ondrej Zary wrote:
> > Here, I am assuming that block/paride is the core code used by both
> > PARIDE and PATA_PARPORT. Not sure what PARPORT_PC does nor what its
> > dependency on block/paride code is.
> 
> There's no common core in block/paride. The block/paride/Makefile says:
> obj-$(CONFIG_PARIDE)            += paride.o
> obj-$(CONFIG_PARIDE_ATEN)       += aten.o
> obj-$(CONFIG_PARIDE_...other protocol drivers
> 
> So if PARIDE and all protocol drivers are disabled, nothing is compiled there.

Yeah.  The pattern of unconditionally descending into a subdirectory
isn't entirely uncommon.  I think this is perfectly fine here.


From hch at lst.de  Tue Mar 15 01:24:57 2022
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 15 Mar 2022 09:24:57 +0100
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <f8c176d4-74f0-3e4f-446f-2a5f8ace3b28@kernel.dk>
References: <20220312144415.20010-1-linux@zary.sk>
 <202203132015.18183.linux@zary.sk>
 <5161ed17-5f55-e851-c2e2-5340cc62fa3b@kernel.dk>
 <202203142125.40532.linux@zary.sk>
 <f8c176d4-74f0-3e4f-446f-2a5f8ace3b28@kernel.dk>
Message-ID: <20220315082457.GB3502@lst.de>

On Mon, Mar 14, 2022 at 02:29:20PM -0600, Jens Axboe wrote:
> The controller would set
> 
> ->needs_blocking_queue_rq = true;
> 
> or something, and we'd default to false. And if that is set, when the
> blk-mq queue is created, then we'd set BLK_MQ_F_BLOCKING upon creation
> if that flag is true.
> 
> That's the block layer side. Then in libata you'd need to ensure that
> you check that same setting and invoke ata_qc_issue() appropriately.
> 
> Very top level stuff, there might be more things lurking below. But
> you'll probably find them as you test this stuff...

FYI, this somewhat mistitled series:

https://lore.kernel.org/all/20220308003957.123312-1-michael.christie at oracle.com/

adds BLK_MQ_F_BLOCKING support to the scsi core.  Doing libata
should be fairly easy and can built ontop of that.


From linux at zary.sk  Tue Mar 15 11:44:44 2022
From: linux at zary.sk (Ondrej Zary)
Date: Tue, 15 Mar 2022 19:44:44 +0100
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <8f32b2ed-13d6-c357-e417-b86a57a285db@opensource.wdc.com>
References: <20220312144415.20010-1-linux@zary.sk>
 <f8c176d4-74f0-3e4f-446f-2a5f8ace3b28@kernel.dk>
 <8f32b2ed-13d6-c357-e417-b86a57a285db@opensource.wdc.com>
Message-ID: <202203151944.44834.linux@zary.sk>

On Tuesday 15 March 2022 05:22:47 Damien Le Moal wrote:
> On 3/15/22 05:29, Jens Axboe wrote:
> > On 3/14/22 2:25 PM, Ondrej Zary wrote:
> >> On Monday 14 March 2022 00:19:30 Jens Axboe wrote:
> >>> On 3/13/22 1:15 PM, Ondrej Zary wrote:
> >>>> On Saturday 12 March 2022 15:44:15 Ondrej Zary wrote:
> >>>>> The pata_parport is a libata-based replacement of the old PARIDE
> >>>>> subsystem - driver for parallel port IDE devices.
> >>>>> It uses the original paride low-level protocol drivers but does not
> >>>>> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
> >>>>> behind parallel port adapters are handled by the ATA layer.
> >>>>>
> >>>>> This will allow paride and its high-level drivers to be removed.
> >>>>>
> >>>>> paride and pata_parport are mutually exclusive because the compiled
> >>>>> protocol drivers are incompatible.
> >>>>>
> >>>>> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
> >>>>> chip).
> >>>>>
> >>>>> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
> >>>>> drivers - they don't handle non-multiple-of-4 block transfers
> >>>>> correctly. This causes problems with LS-120 drive.
> >>>>> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
> >>>>> or 8-bit mode is used first (probably some initialization missing?).
> >>>>> Once the device is initialized, EPP works until power cycle.
> >>>>>
> >>>>> So after device power on, you have to:
> >>>>> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
> >>>>> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
> >>>>> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
> >>>>> (autoprobe will initialize correctly as it tries the slowest modes
> >>>>> first but you'll get the broken EPP-32 mode)
> >>>>
> >>>> Found a bug - the same device can be registered multiple times. Fix
> >>>> will be in v2. But this revealed a bigger problem: pi_connect can
> >>>> sleep (uses parport_claim_or_block) and libata does not like that. Any
> >>>> ideas how to fix this?
> >>>
> >>> I think you'd need two things here:
> >>>
> >>> - The blk-mq queue should be registered with BLK_MQ_F_BLOCKING, which
> >>>   will allow blocking off the queue_rq path.
> >>
> >> My knowledge about blk-mq is exactly zero. After grepping the code, I
> >> guess that BLK_MQ_F_BLOCKING should be used by the block device
> >> drivers - sd and sr?
> > 
> > The controller would set
> > 
> > ->needs_blocking_queue_rq = true;
> > 
> > or something, and we'd default to false. And if that is set, when the
> > blk-mq queue is created, then we'd set BLK_MQ_F_BLOCKING upon creation
> > if that flag is true.
> > 
> > That's the block layer side. Then in libata you'd need to ensure that
> > you check that same setting and invoke ata_qc_issue() appropriately.
> > 
> > Very top level stuff, there might be more things lurking below. But
> > you'll probably find them as you test this stuff...
> 
> Yes, the ata_port spinlock being held when calling ata_qc_issue() is
> mandatory. But since I am assuming that all the IDE devices connected to
> this adapter are QD=1 maximum, there can only be only one command in
> flight. So it may be OK to release that lock before calling pi_connect()
> and retake it right after it. libsas actually does something similar
> (for no good reasons in that case though).
> 
> Jens point remain though that since pi_connect() can sleep, marking the
> device queue with BLK_MQ_F_BLOCKING is mandatory.
 
Something like this? Requires Mike's SCSI BLK_MQ_F_BLOCKING patch:
https://lore.kernel.org/all/20220308003957.123312-2-michael.christie%40oracle.com/

#define PATA_PARPORT_SHT(drv_name)      \
        ATA_PIO_SHT(drv_name),          \
        .queuecommand_blocks    = true,

static void pi_connect(struct ata_port *ap)
{
	struct pi_adapter *pi = ap->host->private_data;

	del_timer_sync(&pi->timer);
	if (!pi->claimed) {
		bool locked = spin_is_locked(ap->lock);
		pi->claimed = true;
		if (locked)
			spin_unlock(ap->lock);
		parport_claim_or_block(pi->pardev);
		if (locked)
			spin_lock(ap->lock);
		pi->proto->connect(pi);
	}
}

spin_is_locked is needed because the lock is not always held.
It seems to work - no more stack traces after device double registration (only ATA errors but that's expected).

-- 
Ondrej Zary


From axboe at kernel.dk  Tue Mar 15 11:47:32 2022
From: axboe at kernel.dk (Jens Axboe)
Date: Tue, 15 Mar 2022 12:47:32 -0600
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <202203151944.44834.linux@zary.sk>
References: <20220312144415.20010-1-linux@zary.sk>
 <f8c176d4-74f0-3e4f-446f-2a5f8ace3b28@kernel.dk>
 <8f32b2ed-13d6-c357-e417-b86a57a285db@opensource.wdc.com>
 <202203151944.44834.linux@zary.sk>
Message-ID: <1b7a45ff-31d4-4b5a-81e2-a35e7cb0b471@kernel.dk>

On 3/15/22 12:44 PM, Ondrej Zary wrote:
> On Tuesday 15 March 2022 05:22:47 Damien Le Moal wrote:
>> On 3/15/22 05:29, Jens Axboe wrote:
>>> On 3/14/22 2:25 PM, Ondrej Zary wrote:
>>>> On Monday 14 March 2022 00:19:30 Jens Axboe wrote:
>>>>> On 3/13/22 1:15 PM, Ondrej Zary wrote:
>>>>>> On Saturday 12 March 2022 15:44:15 Ondrej Zary wrote:
>>>>>>> The pata_parport is a libata-based replacement of the old PARIDE
>>>>>>> subsystem - driver for parallel port IDE devices.
>>>>>>> It uses the original paride low-level protocol drivers but does not
>>>>>>> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
>>>>>>> behind parallel port adapters are handled by the ATA layer.
>>>>>>>
>>>>>>> This will allow paride and its high-level drivers to be removed.
>>>>>>>
>>>>>>> paride and pata_parport are mutually exclusive because the compiled
>>>>>>> protocol drivers are incompatible.
>>>>>>>
>>>>>>> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
>>>>>>> chip).
>>>>>>>
>>>>>>> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
>>>>>>> drivers - they don't handle non-multiple-of-4 block transfers
>>>>>>> correctly. This causes problems with LS-120 drive.
>>>>>>> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
>>>>>>> or 8-bit mode is used first (probably some initialization missing?).
>>>>>>> Once the device is initialized, EPP works until power cycle.
>>>>>>>
>>>>>>> So after device power on, you have to:
>>>>>>> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
>>>>>>> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
>>>>>>> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
>>>>>>> (autoprobe will initialize correctly as it tries the slowest modes
>>>>>>> first but you'll get the broken EPP-32 mode)
>>>>>>
>>>>>> Found a bug - the same device can be registered multiple times. Fix
>>>>>> will be in v2. But this revealed a bigger problem: pi_connect can
>>>>>> sleep (uses parport_claim_or_block) and libata does not like that. Any
>>>>>> ideas how to fix this?
>>>>>
>>>>> I think you'd need two things here:
>>>>>
>>>>> - The blk-mq queue should be registered with BLK_MQ_F_BLOCKING, which
>>>>>   will allow blocking off the queue_rq path.
>>>>
>>>> My knowledge about blk-mq is exactly zero. After grepping the code, I
>>>> guess that BLK_MQ_F_BLOCKING should be used by the block device
>>>> drivers - sd and sr?
>>>
>>> The controller would set
>>>
>>> ->needs_blocking_queue_rq = true;
>>>
>>> or something, and we'd default to false. And if that is set, when the
>>> blk-mq queue is created, then we'd set BLK_MQ_F_BLOCKING upon creation
>>> if that flag is true.
>>>
>>> That's the block layer side. Then in libata you'd need to ensure that
>>> you check that same setting and invoke ata_qc_issue() appropriately.
>>>
>>> Very top level stuff, there might be more things lurking below. But
>>> you'll probably find them as you test this stuff...
>>
>> Yes, the ata_port spinlock being held when calling ata_qc_issue() is
>> mandatory. But since I am assuming that all the IDE devices connected to
>> this adapter are QD=1 maximum, there can only be only one command in
>> flight. So it may be OK to release that lock before calling pi_connect()
>> and retake it right after it. libsas actually does something similar
>> (for no good reasons in that case though).
>>
>> Jens point remain though that since pi_connect() can sleep, marking the
>> device queue with BLK_MQ_F_BLOCKING is mandatory.
>  
> Something like this? Requires Mike's SCSI BLK_MQ_F_BLOCKING patch:
> https://lore.kernel.org/all/20220308003957.123312-2-michael.christie%40oracle.com/
> 
> #define PATA_PARPORT_SHT(drv_name)      \
>         ATA_PIO_SHT(drv_name),          \
>         .queuecommand_blocks    = true,
> 
> static void pi_connect(struct ata_port *ap)
> {
> 	struct pi_adapter *pi = ap->host->private_data;
> 
> 	del_timer_sync(&pi->timer);
> 	if (!pi->claimed) {
> 		bool locked = spin_is_locked(ap->lock);
> 		pi->claimed = true;
> 		if (locked)
> 			spin_unlock(ap->lock);
> 		parport_claim_or_block(pi->pardev);
> 		if (locked)
> 			spin_lock(ap->lock);
> 		pi->proto->connect(pi);
> 	}
> }
> 
> spin_is_locked is needed because the lock is not always held. It seems
> to work - no more stack traces after device double registration (only
> ATA errors but that's expected).

That's a very bad paradigm. What if it is locked, but the caller isn't
the one that locked it? Would be better to either make the locking state
consistent, or provide an unlocked variant (if feasible, doesn't always
work if it's a provided helper already in a struct of ops), or even
resorting to passing in locking state as a last resort.

-- 
Jens Axboe



From linux at zary.sk  Tue Mar 15 14:17:52 2022
From: linux at zary.sk (Ondrej Zary)
Date: Tue, 15 Mar 2022 22:17:52 +0100
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <1b7a45ff-31d4-4b5a-81e2-a35e7cb0b471@kernel.dk>
References: <20220312144415.20010-1-linux@zary.sk>
 <202203151944.44834.linux@zary.sk>
 <1b7a45ff-31d4-4b5a-81e2-a35e7cb0b471@kernel.dk>
Message-ID: <202203152217.52855.linux@zary.sk>

On Tuesday 15 March 2022 19:47:32 Jens Axboe wrote:
> On 3/15/22 12:44 PM, Ondrej Zary wrote:
> > On Tuesday 15 March 2022 05:22:47 Damien Le Moal wrote:
> >> On 3/15/22 05:29, Jens Axboe wrote:
> >>> On 3/14/22 2:25 PM, Ondrej Zary wrote:
> >>>> On Monday 14 March 2022 00:19:30 Jens Axboe wrote:
> >>>>> On 3/13/22 1:15 PM, Ondrej Zary wrote:
> >>>>>> On Saturday 12 March 2022 15:44:15 Ondrej Zary wrote:
> >>>>>>> The pata_parport is a libata-based replacement of the old PARIDE
> >>>>>>> subsystem - driver for parallel port IDE devices.
> >>>>>>> It uses the original paride low-level protocol drivers but does not
> >>>>>>> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
> >>>>>>> behind parallel port adapters are handled by the ATA layer.
> >>>>>>>
> >>>>>>> This will allow paride and its high-level drivers to be removed.
> >>>>>>>
> >>>>>>> paride and pata_parport are mutually exclusive because the compiled
> >>>>>>> protocol drivers are incompatible.
> >>>>>>>
> >>>>>>> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
> >>>>>>> chip).
> >>>>>>>
> >>>>>>> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
> >>>>>>> drivers - they don't handle non-multiple-of-4 block transfers
> >>>>>>> correctly. This causes problems with LS-120 drive.
> >>>>>>> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
> >>>>>>> or 8-bit mode is used first (probably some initialization missing?).
> >>>>>>> Once the device is initialized, EPP works until power cycle.
> >>>>>>>
> >>>>>>> So after device power on, you have to:
> >>>>>>> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
> >>>>>>> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
> >>>>>>> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
> >>>>>>> (autoprobe will initialize correctly as it tries the slowest modes
> >>>>>>> first but you'll get the broken EPP-32 mode)
> >>>>>>
> >>>>>> Found a bug - the same device can be registered multiple times. Fix
> >>>>>> will be in v2. But this revealed a bigger problem: pi_connect can
> >>>>>> sleep (uses parport_claim_or_block) and libata does not like that. Any
> >>>>>> ideas how to fix this?
> >>>>>
> >>>>> I think you'd need two things here:
> >>>>>
> >>>>> - The blk-mq queue should be registered with BLK_MQ_F_BLOCKING, which
> >>>>>   will allow blocking off the queue_rq path.
> >>>>
> >>>> My knowledge about blk-mq is exactly zero. After grepping the code, I
> >>>> guess that BLK_MQ_F_BLOCKING should be used by the block device
> >>>> drivers - sd and sr?
> >>>
> >>> The controller would set
> >>>
> >>> ->needs_blocking_queue_rq = true;
> >>>
> >>> or something, and we'd default to false. And if that is set, when the
> >>> blk-mq queue is created, then we'd set BLK_MQ_F_BLOCKING upon creation
> >>> if that flag is true.
> >>>
> >>> That's the block layer side. Then in libata you'd need to ensure that
> >>> you check that same setting and invoke ata_qc_issue() appropriately.
> >>>
> >>> Very top level stuff, there might be more things lurking below. But
> >>> you'll probably find them as you test this stuff...
> >>
> >> Yes, the ata_port spinlock being held when calling ata_qc_issue() is
> >> mandatory. But since I am assuming that all the IDE devices connected to
> >> this adapter are QD=1 maximum, there can only be only one command in
> >> flight. So it may be OK to release that lock before calling pi_connect()
> >> and retake it right after it. libsas actually does something similar
> >> (for no good reasons in that case though).
> >>
> >> Jens point remain though that since pi_connect() can sleep, marking the
> >> device queue with BLK_MQ_F_BLOCKING is mandatory.
> >  
> > Something like this? Requires Mike's SCSI BLK_MQ_F_BLOCKING patch:
> > https://lore.kernel.org/all/20220308003957.123312-2-michael.christie%40oracle.com/
> > 
> > #define PATA_PARPORT_SHT(drv_name)      \
> >         ATA_PIO_SHT(drv_name),          \
> >         .queuecommand_blocks    = true,
> > 
> > static void pi_connect(struct ata_port *ap)
> > {
> > 	struct pi_adapter *pi = ap->host->private_data;
> > 
> > 	del_timer_sync(&pi->timer);
> > 	if (!pi->claimed) {
> > 		bool locked = spin_is_locked(ap->lock);
> > 		pi->claimed = true;
> > 		if (locked)
> > 			spin_unlock(ap->lock);
> > 		parport_claim_or_block(pi->pardev);
> > 		if (locked)
> > 			spin_lock(ap->lock);
> > 		pi->proto->connect(pi);
> > 	}
> > }
> > 
> > spin_is_locked is needed because the lock is not always held. It seems
> > to work - no more stack traces after device double registration (only
> > ATA errors but that's expected).
> 
> That's a very bad paradigm. What if it is locked, but the caller isn't
> the one that locked it? Would be better to either make the locking state
> consistent, or provide an unlocked variant (if feasible, doesn't always
> work if it's a provided helper already in a struct of ops), or even
> resorting to passing in locking state as a last resort.
 
libata locking seems to be very complex and our functions seem to be called with various lock states. I'm lost.

Might be easier to add connect() and disconnect() to struct ata_port_operations...

-- 
Ondrej Zary


From damien.lemoal at opensource.wdc.com  Tue Mar 15 17:19:22 2022
From: damien.lemoal at opensource.wdc.com (Damien Le Moal)
Date: Wed, 16 Mar 2022 09:19:22 +0900
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <202203152217.52855.linux@zary.sk>
References: <20220312144415.20010-1-linux@zary.sk>
 <202203151944.44834.linux@zary.sk>
 <1b7a45ff-31d4-4b5a-81e2-a35e7cb0b471@kernel.dk>
 <202203152217.52855.linux@zary.sk>
Message-ID: <61c81839-ac6a-32c1-97a8-f6fefb8642d7@opensource.wdc.com>

On 3/16/22 06:17, Ondrej Zary wrote:
>>> Something like this? Requires Mike's SCSI BLK_MQ_F_BLOCKING patch:
>>> https://lore.kernel.org/all/20220308003957.123312-2-michael.christie%40oracle.com/
>>>
>>> #define PATA_PARPORT_SHT(drv_name)      \
>>>         ATA_PIO_SHT(drv_name),          \
>>>         .queuecommand_blocks    = true,
>>>
>>> static void pi_connect(struct ata_port *ap)
>>> {
>>> 	struct pi_adapter *pi = ap->host->private_data;
>>>
>>> 	del_timer_sync(&pi->timer);
>>> 	if (!pi->claimed) {
>>> 		bool locked = spin_is_locked(ap->lock);

For the pi_connect() call in the ata_qc_issue() context, ap->lock is
always held, so this is not necessary.

If you have other pi_connect() calls in different contexts, we will need
to address these too. For internal commands during scan, ap->lock is
also always held.

>>> 		pi->claimed = true;
>>> 		if (locked)
>>> 			spin_unlock(ap->lock);

You need spin_unlock_irqrestore(). See the locking done in
ata_scsi_queuecmd() which is the starting point for issuing a command
through libata.

>>> 		parport_claim_or_block(pi->pardev);
>>> 		if (locked)
>>> 			spin_lock(ap->lock);
>>> 		pi->proto->connect(pi);
>>> 	}
>>> }
>>>
>>> spin_is_locked is needed because the lock is not always held. It seems
>>> to work - no more stack traces after device double registration (only
>>> ATA errors but that's expected).
>>
>> That's a very bad paradigm. What if it is locked, but the caller isn't
>> the one that locked it? Would be better to either make the locking state
>> consistent, or provide an unlocked variant (if feasible, doesn't always
>> work if it's a provided helper already in a struct of ops), or even
>> resorting to passing in locking state as a last resort.
>  
> libata locking seems to be very complex and our functions seem to be called with various lock states. I'm lost.
> 
> Might be easier to add connect() and disconnect() to struct ata_port_operations...

But you would not be able to call these within the ata_qc_issue()
context, which I think is necessary in your case. Also, these
connect/disconnect operations are not something defined by the ATA
protocol, so we should try to keep these hidden in the LLDD. It is
better I think to find a solution about the locking, if necessary using
a different qc_issue operation or using the queuecommand_blocks
attribute to have libata call the LLDD qc_issue without lock helds,
which should be OK (need to check).

Ideally, we should refine this ap->lock big lock to avoid it being held
throughout the entire submission path. I will try to have a look at this.


-- 
Damien Le Moal
Western Digital Research


From linux at zary.sk  Wed Mar 16 04:28:05 2022
From: linux at zary.sk (Ondrej Zary)
Date: Wed, 16 Mar 2022 12:28:05 +0100
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <68e572f6-e1b6-8d04-900d-8621f607f3bc@omp.ru>
References: <20220312144415.20010-1-linux@zary.sk>
 <202203132219.59100.linux@zary.sk>
 <68e572f6-e1b6-8d04-900d-8621f607f3bc@omp.ru>
Message-ID: <202203161228.05700.linux@zary.sk>

On Wednesday 16 March 2022, Sergey Shtylyov wrote:
> Hello!
> 
> On 3/14/22 12:19 AM, Ondrej Zary wrote:
> 
> [...]
> >>> The pata_parport is a libata-based replacement of the old PARIDE
> >>> subsystem - driver for parallel port IDE devices.
> >>> It uses the original paride low-level protocol drivers but does not
> >>> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
> >>> behind parallel port adapters are handled by the ATA layer.
> >>>
> >>> This will allow paride and its high-level drivers to be removed.
> >>>
> >>> paride and pata_parport are mutually exclusive because the compiled
> >>> protocol drivers are incompatible.
> >>>
> >>> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
> >>> chip).
> >>>
> >>> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
> >>> drivers - they don't handle non-multiple-of-4 block transfers
> >>> correctly. This causes problems with LS-120 drive.
> >>> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
> >>> or 8-bit mode is used first (probably some initialization missing?).
> >>> Once the device is initialized, EPP works until power cycle.
> >>>
> >>> So after device power on, you have to:
> >>> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
> >>> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
> >>> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
> >>> (autoprobe will initialize correctly as it tries the slowest modes
> >>> first but you'll get the broken EPP-32 mode)
> >>>
> >>> Signed-off-by: Ondrej Zary <linux at zary.sk>
> >> [...]
> >>> diff --git a/Documentation/admin-guide/blockdev/paride.rst b/Documentation/admin-guide/blockdev/paride.rst
> >>> index e1ce90af602a..e431a1ef41eb 100644
> >>> --- a/Documentation/admin-guide/blockdev/paride.rst
> >>> +++ b/Documentation/admin-guide/blockdev/paride.rst
> >> [...]
> >>> diff --git a/drivers/ata/pata_parport.c b/drivers/ata/pata_parport.c
> >>> new file mode 100644
> >>> index 000000000000..783764626a27
> >>> --- /dev/null
> >>> +++ b/drivers/ata/pata_parport.c
> >>> @@ -0,0 +1,819 @@
> >> [...]
> >>> +static void pata_parport_lost_interrupt(struct ata_port *ap)
> >>> +{
> >>> +	u8 status;
> >>> +	struct ata_queued_cmd *qc;
> >>> +
> >>> +	/* Only one outstanding command per SFF channel */
> >>> +	qc = ata_qc_from_tag(ap, ap->link.active_tag);
> >>> +	/* We cannot lose an interrupt on a non-existent or polled command */
> >>> +	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
> >>> +		return;
> >>> +	/*
> >>> +	 * See if the controller thinks it is still busy - if so the command
> >>> +	 * isn't a lost IRQ but is still in progress
> >>> +	 */
> >>> +	status = pata_parport_check_altstatus(ap);
> >>> +	if (status & ATA_BUSY)
> >>> +		return;
> >>> +
> >>> +	/*
> >>> +	 * There was a command running, we are no longer busy and we have
> >>> +	 * no interrupt.
> >>> +	 */
> >>> +	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
> >>> +	/* Run the host interrupt logic as if the interrupt had not been lost */
> >>> +	ata_sff_port_intr(ap, qc);
> >>> +}
> >>
> >>    As I said, ata_sff_lost_interrupt() could be used instead...
> > 
> > It couldn't be used because it calls ata_sff_altstatus().
> 
>    And? That one used to call the sff_check_altstatus() method (which you define)
> even before my patch:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata.git/commit/?h=for-next&id=03c0e84f9c1e166d57d06b04497e11205f48e9a8

OK, I was probably confused by ata_sff_check_status which uses ioread directly.

> [...]
> >>> diff --git a/include/linux/pata_parport.h b/include/linux/pata_parport.h
> >>> new file mode 100644
> >>> index 000000000000..f1ba57bb319c
> >>> --- /dev/null
> >>> +++ b/include/linux/pata_parport.h
> >>> @@ -0,0 +1,108 @@
> [...]
> >>> +static inline u16 pi_swab16(char *b, int k)
> >>> +{
> >>> +	union { u16 u; char t[2]; } r;
> >>> +
> >>> +	r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k];
> >>> +	return r.u;
> >>> +}
> >>> +
> >>> +static inline u32 pi_swab32(char *b, int k)
> >>> +{
> >>> +	union { u32 u; char f[4]; } r;
> >>> +
> >>> +	r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k];
> >>> +	r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2];
> >>> +	return r.u;
> >>
> >>    Hey, I was serious about swab{16|32}p()! Please don't use home grown byte
> >> swapping...
> > 
> > This crap comes from old paride.h and we can't get rid of it without touching the protocol drivers
> 
>    I don't argue about the *inline*s themselves, just about the ineffective code inside them.
> 
> > (comm.c and kbic.c). Maybe use something like:
> > 
> > #define pi_swab16(char *b, int k) 	swab16p((u16 *)&b[2 * k])
> 
> > but I'm not sure it's equivalent on a big-endian machine.
> 
>    These functions are endian-agnostic -- they swap always.
>    If you only need to swab the bytes on big-endian machines, you should use cpu_to_le*() and/or
> le*_to_cpu()...

swab16 swaps always but pi_swab16 does not on big-endian. It's probably a bug but doing the correct thing by accident. Other protocol drivers completely ignore endianness, probably because PARIDE was meant for x86 only.

> [...]
> 
> MBR, Sergey
> 



-- 
Ondrej Zary


From damien.lemoal at opensource.wdc.com  Wed Mar 16 04:44:00 2022
From: damien.lemoal at opensource.wdc.com (Damien Le Moal)
Date: Wed, 16 Mar 2022 20:44:00 +0900
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <202203161228.05700.linux@zary.sk>
References: <20220312144415.20010-1-linux@zary.sk>
 <202203132219.59100.linux@zary.sk>
 <68e572f6-e1b6-8d04-900d-8621f607f3bc@omp.ru>
 <202203161228.05700.linux@zary.sk>
Message-ID: <0015ea51-b3e9-924a-2714-61b159fc7b98@opensource.wdc.com>

On 3/16/22 20:28, Ondrej Zary wrote:
> On Wednesday 16 March 2022, Sergey Shtylyov wrote:
>> Hello!
>>
>> On 3/14/22 12:19 AM, Ondrej Zary wrote:
>>
>> [...]
>>>>> The pata_parport is a libata-based replacement of the old PARIDE
>>>>> subsystem - driver for parallel port IDE devices.
>>>>> It uses the original paride low-level protocol drivers but does not
>>>>> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
>>>>> behind parallel port adapters are handled by the ATA layer.
>>>>>
>>>>> This will allow paride and its high-level drivers to be removed.
>>>>>
>>>>> paride and pata_parport are mutually exclusive because the compiled
>>>>> protocol drivers are incompatible.
>>>>>
>>>>> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
>>>>> chip).
>>>>>
>>>>> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
>>>>> drivers - they don't handle non-multiple-of-4 block transfers
>>>>> correctly. This causes problems with LS-120 drive.
>>>>> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
>>>>> or 8-bit mode is used first (probably some initialization missing?).
>>>>> Once the device is initialized, EPP works until power cycle.
>>>>>
>>>>> So after device power on, you have to:
>>>>> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
>>>>> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
>>>>> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
>>>>> (autoprobe will initialize correctly as it tries the slowest modes
>>>>> first but you'll get the broken EPP-32 mode)
>>>>>
>>>>> Signed-off-by: Ondrej Zary <linux at zary.sk>
>>>> [...]
>>>>> diff --git a/Documentation/admin-guide/blockdev/paride.rst b/Documentation/admin-guide/blockdev/paride.rst
>>>>> index e1ce90af602a..e431a1ef41eb 100644
>>>>> --- a/Documentation/admin-guide/blockdev/paride.rst
>>>>> +++ b/Documentation/admin-guide/blockdev/paride.rst
>>>> [...]
>>>>> diff --git a/drivers/ata/pata_parport.c b/drivers/ata/pata_parport.c
>>>>> new file mode 100644
>>>>> index 000000000000..783764626a27
>>>>> --- /dev/null
>>>>> +++ b/drivers/ata/pata_parport.c
>>>>> @@ -0,0 +1,819 @@
>>>> [...]
>>>>> +static void pata_parport_lost_interrupt(struct ata_port *ap)
>>>>> +{
>>>>> +	u8 status;
>>>>> +	struct ata_queued_cmd *qc;
>>>>> +
>>>>> +	/* Only one outstanding command per SFF channel */
>>>>> +	qc = ata_qc_from_tag(ap, ap->link.active_tag);
>>>>> +	/* We cannot lose an interrupt on a non-existent or polled command */
>>>>> +	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
>>>>> +		return;
>>>>> +	/*
>>>>> +	 * See if the controller thinks it is still busy - if so the command
>>>>> +	 * isn't a lost IRQ but is still in progress
>>>>> +	 */
>>>>> +	status = pata_parport_check_altstatus(ap);
>>>>> +	if (status & ATA_BUSY)
>>>>> +		return;
>>>>> +
>>>>> +	/*
>>>>> +	 * There was a command running, we are no longer busy and we have
>>>>> +	 * no interrupt.
>>>>> +	 */
>>>>> +	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
>>>>> +	/* Run the host interrupt logic as if the interrupt had not been lost */
>>>>> +	ata_sff_port_intr(ap, qc);
>>>>> +}
>>>>
>>>>    As I said, ata_sff_lost_interrupt() could be used instead...
>>>
>>> It couldn't be used because it calls ata_sff_altstatus().
>>
>>    And? That one used to call the sff_check_altstatus() method (which you define)
>> even before my patch:
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata.git/commit/?h=for-next&id=03c0e84f9c1e166d57d06b04497e11205f48e9a8
> 
> OK, I was probably confused by ata_sff_check_status which uses ioread directly.
> 
>> [...]
>>>>> diff --git a/include/linux/pata_parport.h b/include/linux/pata_parport.h
>>>>> new file mode 100644
>>>>> index 000000000000..f1ba57bb319c
>>>>> --- /dev/null
>>>>> +++ b/include/linux/pata_parport.h
>>>>> @@ -0,0 +1,108 @@
>> [...]
>>>>> +static inline u16 pi_swab16(char *b, int k)
>>>>> +{
>>>>> +	union { u16 u; char t[2]; } r;
>>>>> +
>>>>> +	r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k];
>>>>> +	return r.u;
>>>>> +}
>>>>> +
>>>>> +static inline u32 pi_swab32(char *b, int k)
>>>>> +{
>>>>> +	union { u32 u; char f[4]; } r;
>>>>> +
>>>>> +	r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k];
>>>>> +	r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2];
>>>>> +	return r.u;
>>>>
>>>>    Hey, I was serious about swab{16|32}p()! Please don't use home grown byte
>>>> swapping...
>>>
>>> This crap comes from old paride.h and we can't get rid of it without touching the protocol drivers
>>
>>    I don't argue about the *inline*s themselves, just about the ineffective code inside them.
>>
>>> (comm.c and kbic.c). Maybe use something like:
>>>
>>> #define pi_swab16(char *b, int k) 	swab16p((u16 *)&b[2 * k])
>>
>>> but I'm not sure it's equivalent on a big-endian machine.
>>
>>    These functions are endian-agnostic -- they swap always.
>>    If you only need to swab the bytes on big-endian machines, you should use cpu_to_le*() and/or
>> le*_to_cpu()...
> 
> swab16 swaps always but pi_swab16 does not on big-endian. It's probably a bug but doing the correct thing by accident. Other protocol drivers completely ignore endianness, probably because PARIDE was meant for x86 only.

Fix that. ATA/IDE uses little endian. So all command & replies fields
should be handled with put_unaligned_lexx()/get_unaligned_lexx(), or
cpu_to_lexx() and lexx_to_cpu().

> 
>> [...]
>>
>> MBR, Sergey
>>
> 
> 
> 


-- 
Damien Le Moal
Western Digital Research


From linux at zary.sk  Wed Mar 16 05:58:06 2022
From: linux at zary.sk (Ondrej Zary)
Date: Wed, 16 Mar 2022 13:58:06 +0100
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <0015ea51-b3e9-924a-2714-61b159fc7b98@opensource.wdc.com>
References: <20220312144415.20010-1-linux@zary.sk>
 <202203161228.05700.linux@zary.sk>
 <0015ea51-b3e9-924a-2714-61b159fc7b98@opensource.wdc.com>
Message-ID: <202203161358.06506.linux@zary.sk>

On Wednesday 16 March 2022, Damien Le Moal wrote:
> On 3/16/22 20:28, Ondrej Zary wrote:
> > On Wednesday 16 March 2022, Sergey Shtylyov wrote:
> >> Hello!
> >>
> >> On 3/14/22 12:19 AM, Ondrej Zary wrote:
> >>
> >> [...]
> >>>>> The pata_parport is a libata-based replacement of the old PARIDE
> >>>>> subsystem - driver for parallel port IDE devices.
> >>>>> It uses the original paride low-level protocol drivers but does not
> >>>>> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
> >>>>> behind parallel port adapters are handled by the ATA layer.
> >>>>>
> >>>>> This will allow paride and its high-level drivers to be removed.
> >>>>>
> >>>>> paride and pata_parport are mutually exclusive because the compiled
> >>>>> protocol drivers are incompatible.
> >>>>>
> >>>>> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
> >>>>> chip).
> >>>>>
> >>>>> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
> >>>>> drivers - they don't handle non-multiple-of-4 block transfers
> >>>>> correctly. This causes problems with LS-120 drive.
> >>>>> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
> >>>>> or 8-bit mode is used first (probably some initialization missing?).
> >>>>> Once the device is initialized, EPP works until power cycle.
> >>>>>
> >>>>> So after device power on, you have to:
> >>>>> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
> >>>>> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
> >>>>> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
> >>>>> (autoprobe will initialize correctly as it tries the slowest modes
> >>>>> first but you'll get the broken EPP-32 mode)
> >>>>>
> >>>>> Signed-off-by: Ondrej Zary <linux at zary.sk>
> >>>> [...]
> >>>>> diff --git a/Documentation/admin-guide/blockdev/paride.rst b/Documentation/admin-guide/blockdev/paride.rst
> >>>>> index e1ce90af602a..e431a1ef41eb 100644
> >>>>> --- a/Documentation/admin-guide/blockdev/paride.rst
> >>>>> +++ b/Documentation/admin-guide/blockdev/paride.rst
> >>>> [...]
> >>>>> diff --git a/drivers/ata/pata_parport.c b/drivers/ata/pata_parport.c
> >>>>> new file mode 100644
> >>>>> index 000000000000..783764626a27
> >>>>> --- /dev/null
> >>>>> +++ b/drivers/ata/pata_parport.c
> >>>>> @@ -0,0 +1,819 @@
> >>>> [...]
> >>>>> +static void pata_parport_lost_interrupt(struct ata_port *ap)
> >>>>> +{
> >>>>> +	u8 status;
> >>>>> +	struct ata_queued_cmd *qc;
> >>>>> +
> >>>>> +	/* Only one outstanding command per SFF channel */
> >>>>> +	qc = ata_qc_from_tag(ap, ap->link.active_tag);
> >>>>> +	/* We cannot lose an interrupt on a non-existent or polled command */
> >>>>> +	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
> >>>>> +		return;
> >>>>> +	/*
> >>>>> +	 * See if the controller thinks it is still busy - if so the command
> >>>>> +	 * isn't a lost IRQ but is still in progress
> >>>>> +	 */
> >>>>> +	status = pata_parport_check_altstatus(ap);
> >>>>> +	if (status & ATA_BUSY)
> >>>>> +		return;
> >>>>> +
> >>>>> +	/*
> >>>>> +	 * There was a command running, we are no longer busy and we have
> >>>>> +	 * no interrupt.
> >>>>> +	 */
> >>>>> +	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
> >>>>> +	/* Run the host interrupt logic as if the interrupt had not been lost */
> >>>>> +	ata_sff_port_intr(ap, qc);
> >>>>> +}
> >>>>
> >>>>    As I said, ata_sff_lost_interrupt() could be used instead...
> >>>
> >>> It couldn't be used because it calls ata_sff_altstatus().
> >>
> >>    And? That one used to call the sff_check_altstatus() method (which you define)
> >> even before my patch:
> >>
> >> https://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata.git/commit/?h=for-next&id=03c0e84f9c1e166d57d06b04497e11205f48e9a8
> > 
> > OK, I was probably confused by ata_sff_check_status which uses ioread directly.
> > 
> >> [...]
> >>>>> diff --git a/include/linux/pata_parport.h b/include/linux/pata_parport.h
> >>>>> new file mode 100644
> >>>>> index 000000000000..f1ba57bb319c
> >>>>> --- /dev/null
> >>>>> +++ b/include/linux/pata_parport.h
> >>>>> @@ -0,0 +1,108 @@
> >> [...]
> >>>>> +static inline u16 pi_swab16(char *b, int k)
> >>>>> +{
> >>>>> +	union { u16 u; char t[2]; } r;
> >>>>> +
> >>>>> +	r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k];
> >>>>> +	return r.u;
> >>>>> +}
> >>>>> +
> >>>>> +static inline u32 pi_swab32(char *b, int k)
> >>>>> +{
> >>>>> +	union { u32 u; char f[4]; } r;
> >>>>> +
> >>>>> +	r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k];
> >>>>> +	r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2];
> >>>>> +	return r.u;
> >>>>
> >>>>    Hey, I was serious about swab{16|32}p()! Please don't use home grown byte
> >>>> swapping...
> >>>
> >>> This crap comes from old paride.h and we can't get rid of it without touching the protocol drivers
> >>
> >>    I don't argue about the *inline*s themselves, just about the ineffective code inside them.
> >>
> >>> (comm.c and kbic.c). Maybe use something like:
> >>>
> >>> #define pi_swab16(char *b, int k) 	swab16p((u16 *)&b[2 * k])
> >>
> >>> but I'm not sure it's equivalent on a big-endian machine.
> >>
> >>    These functions are endian-agnostic -- they swap always.
> >>    If you only need to swab the bytes on big-endian machines, you should use cpu_to_le*() and/or
> >> le*_to_cpu()...
> > 
> > swab16 swaps always but pi_swab16 does not on big-endian. It's probably a bug but doing the correct thing by accident. Other protocol drivers completely ignore endianness, probably because PARIDE was meant for x86 only.
> 
> Fix that. ATA/IDE uses little endian. So all command & replies fields
> should be handled with put_unaligned_lexx()/get_unaligned_lexx(), or
> cpu_to_lexx() and lexx_to_cpu().

Fortunately, most of the code uses 8-bit only accesses (registers are 8-bit and also parport HW is mostly 8-bit). Only block reads/writes in EPP-16 and EPP-32 modes seem to be affected. I'll fix that later as I'm not touching protocol drivers now.

> 
> > 
> >> [...]
> >>
> >> MBR, Sergey
> >>
> > 
> > 
> > 
> 
> 



-- 
Ondrej Zary


From s.shtylyov at omp.ru  Wed Mar 16 01:50:44 2022
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Wed, 16 Mar 2022 11:50:44 +0300
Subject: [Linux-parport] [PATCH] pata_parport: add driver (PARIDE
 replacement)
In-Reply-To: <202203132219.59100.linux@zary.sk>
References: <20220312144415.20010-1-linux@zary.sk>
 <a8189d8e-03e2-1b6f-3251-8e44e4e5e423@omp.ru>
 <202203132219.59100.linux@zary.sk>
Message-ID: <68e572f6-e1b6-8d04-900d-8621f607f3bc@omp.ru>

Hello!

On 3/14/22 12:19 AM, Ondrej Zary wrote:

[...]
>>> The pata_parport is a libata-based replacement of the old PARIDE
>>> subsystem - driver for parallel port IDE devices.
>>> It uses the original paride low-level protocol drivers but does not
>>> need the high-level drivers (pd, pcd, pf, pt, pg). The IDE devices
>>> behind parallel port adapters are handled by the ATA layer.
>>>
>>> This will allow paride and its high-level drivers to be removed.
>>>
>>> paride and pata_parport are mutually exclusive because the compiled
>>> protocol drivers are incompatible.
>>>
>>> Tested with Imation SuperDisk LS-120 and HP C4381A (both use EPAT
>>> chip).
>>>
>>> Note: EPP-32 mode is buggy in EPAT - and also in all other protocol
>>> drivers - they don't handle non-multiple-of-4 block transfers
>>> correctly. This causes problems with LS-120 drive.
>>> There is also another bug in EPAT: EPP modes don't work unless a 4-bit
>>> or 8-bit mode is used first (probably some initialization missing?).
>>> Once the device is initialized, EPP works until power cycle.
>>>
>>> So after device power on, you have to:
>>> echo "parport0 epat 0" >/sys/bus/pata_parport/new_device
>>> echo pata_parport.0 >/sys/bus/pata_parport/delete_device
>>> echo "parport0 epat 4" >/sys/bus/pata_parport/new_device
>>> (autoprobe will initialize correctly as it tries the slowest modes
>>> first but you'll get the broken EPP-32 mode)
>>>
>>> Signed-off-by: Ondrej Zary <linux at zary.sk>
>> [...]
>>> diff --git a/Documentation/admin-guide/blockdev/paride.rst b/Documentation/admin-guide/blockdev/paride.rst
>>> index e1ce90af602a..e431a1ef41eb 100644
>>> --- a/Documentation/admin-guide/blockdev/paride.rst
>>> +++ b/Documentation/admin-guide/blockdev/paride.rst
>> [...]
>>> diff --git a/drivers/ata/pata_parport.c b/drivers/ata/pata_parport.c
>>> new file mode 100644
>>> index 000000000000..783764626a27
>>> --- /dev/null
>>> +++ b/drivers/ata/pata_parport.c
>>> @@ -0,0 +1,819 @@
>> [...]
>>> +static void pata_parport_lost_interrupt(struct ata_port *ap)
>>> +{
>>> +	u8 status;
>>> +	struct ata_queued_cmd *qc;
>>> +
>>> +	/* Only one outstanding command per SFF channel */
>>> +	qc = ata_qc_from_tag(ap, ap->link.active_tag);
>>> +	/* We cannot lose an interrupt on a non-existent or polled command */
>>> +	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
>>> +		return;
>>> +	/*
>>> +	 * See if the controller thinks it is still busy - if so the command
>>> +	 * isn't a lost IRQ but is still in progress
>>> +	 */
>>> +	status = pata_parport_check_altstatus(ap);
>>> +	if (status & ATA_BUSY)
>>> +		return;
>>> +
>>> +	/*
>>> +	 * There was a command running, we are no longer busy and we have
>>> +	 * no interrupt.
>>> +	 */
>>> +	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
>>> +	/* Run the host interrupt logic as if the interrupt had not been lost */
>>> +	ata_sff_port_intr(ap, qc);
>>> +}
>>
>>    As I said, ata_sff_lost_interrupt() could be used instead...
> 
> It couldn't be used because it calls ata_sff_altstatus().

   And? That one used to call the sff_check_altstatus() method (which you define)
even before my patch:

https://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata.git/commit/?h=for-next&id=03c0e84f9c1e166d57d06b04497e11205f48e9a8

[...]
>>> diff --git a/include/linux/pata_parport.h b/include/linux/pata_parport.h
>>> new file mode 100644
>>> index 000000000000..f1ba57bb319c
>>> --- /dev/null
>>> +++ b/include/linux/pata_parport.h
>>> @@ -0,0 +1,108 @@
[...]
>>> +static inline u16 pi_swab16(char *b, int k)
>>> +{
>>> +	union { u16 u; char t[2]; } r;
>>> +
>>> +	r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k];
>>> +	return r.u;
>>> +}
>>> +
>>> +static inline u32 pi_swab32(char *b, int k)
>>> +{
>>> +	union { u32 u; char f[4]; } r;
>>> +
>>> +	r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k];
>>> +	r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2];
>>> +	return r.u;
>>
>>    Hey, I was serious about swab{16|32}p()! Please don't use home grown byte
>> swapping...
> 
> This crap comes from old paride.h and we can't get rid of it without touching the protocol drivers

   I don't argue about the *inline*s themselves, just about the ineffective code inside them.

> (comm.c and kbic.c). Maybe use something like:
> 
> #define pi_swab16(char *b, int k) 	swab16p((u16 *)&b[2 * k])

> but I'm not sure it's equivalent on a big-endian machine.

   These functions are endian-agnostic -- they swap always.
   If you only need to swab the bytes on big-endian machines, you should use cpu_to_le*() and/or
le*_to_cpu()...

[...]

MBR, Sergey


From lkp at intel.com  Fri Mar 18 20:39:29 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 19 Mar 2022 11:39:29 +0800
Subject: [Linux-parport] [linux-next:master] BUILD REGRESSION
 6d72dda014a4753974eb08950089ddf71fec4f60
Message-ID: <62355071.szvnEfxvIzY6HHmK%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
branch HEAD: 6d72dda014a4753974eb08950089ddf71fec4f60  Add linux-next specific files for 20220318

Error/Warning reports:

https://lore.kernel.org/linux-doc/202202240704.pQD40A9L-lkp at intel.com
https://lore.kernel.org/linux-doc/202202240705.t3QbMnlt-lkp at intel.com
https://lore.kernel.org/linux-doc/202203180707.vLUjjmqY-lkp at intel.com
https://lore.kernel.org/linux-media/202203160306.SfWO9QWV-lkp at intel.com
https://lore.kernel.org/linux-media/202203182100.fSdmSXzo-lkp at intel.com
https://lore.kernel.org/linux-media/202203182127.ZeZX6m5Y-lkp at intel.com
https://lore.kernel.org/llvm/202202241039.g8GKEE4O-lkp at intel.com
https://lore.kernel.org/llvm/202203110903.3xDyTUVl-lkp at intel.com
https://lore.kernel.org/llvm/202203180453.7LxvqwzJ-lkp at intel.com

Error/Warning:

Documentation/driver-api/nvdimm/nvdimm.rst:146: (SEVERE/4) Title level inconsistent:
arch/arm/kernel/ftrace.c:229:6: warning: no previous prototype for function 'prepare_ftrace_return' [-Wmissing-prototypes]
drivers/media/platform/renesas/renesas-ceu.c:1609:30: warning: unused variable 'ceu_data_rz' [-Wunused-const-variable]
drivers/media/platform/samsung/exynos4-is/fimc-isp-video.h:35:6: warning: no previous prototype for 'fimc_isp_video_device_unregister' [-Wmissing-prototypes]
drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c:3126:34: warning: unused variable 'samsung_jpeg_match' [-Wunused-const-variable]
drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c:1175:34: warning: unused variable 'c8sectpfe_match' [-Wunused-const-variable]
drivers/spi/spi-amd.c:296:21: warning: cast to smaller integer type 'enum amd_spi_versions' from 'const void *' [-Wvoid-pointer-to-enum-cast]
fs/btrfs/ordered-data.c:168: warning: expecting prototype for Add an ordered extent to the per(). Prototype was for btrfs_add_ordered_extent() instead
fs/btrfs/tree-log.c:6934: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst

Unverified Error/Warning (likely false positive, please contact us if interested):

FAILED: load BTF from vmlinux: No such file or directory
Makefile:677: arch/nds32/Makefile: No such file or directory
arch/Kconfig:10: can't open file "arch/nds32/Kconfig"
arch/alpha/include/asm/string.h:22:16: warning: '__builtin_memcpy' forming offset [40, 2051] is out of the bounds [0, 40] of object 'tag_buf' with type 'unsigned char[40]' [-Warray-bounds]
arch/arm/kernel/unwind.c:483:17: warning: Assigned value is garbage or undefined [clang-analyzer-core.uninitialized.Assign]
arch/m68k/kernel/machine_kexec.c:55: undefined reference to `m68k_mmutype'
arch/m68k/kernel/time.c:105: undefined reference to `mach_get_rtc_pll'
arch/riscv/kernel/cacheinfo.c:189:1: internal compiler error: Segmentation fault
arch/riscv/kernel/crash_dump.c:46:1: internal compiler error: Segmentation fault
arch/riscv/kernel/patch.c:133:1: internal compiler error: Segmentation fault
arch/riscv/kernel/signal.c:321:1: internal compiler error: Segmentation fault
arch/riscv/mm/extable.c:71:1: internal compiler error: Segmentation fault
arch/riscv/mm/physaddr.c:35:1: internal compiler error: Segmentation fault
arch/s390/kernel/machine_kexec.c:57:9: warning: 'memcpy' offset [0, 511] is out of the bounds [0, 0] [-Warray-bounds]
arch/sh/kernel/machvec.c:105:33: warning: array subscript 'struct sh_machine_vector[0]' is partly outside array bounds of 'long int[1]' [-Warray-bounds]
block/blk-mq-rdma.c:44:1: internal compiler error: Segmentation fault
block/blk-zoned.c:648:1: internal compiler error: Segmentation fault
block/sed-opal.c:2695:1: internal compiler error: Segmentation fault
crypto/acompress.c:198:1: internal compiler error: Segmentation fault
crypto/aead.c:303:1: internal compiler error: Segmentation fault
crypto/ahash.c:660:1: internal compiler error: Segmentation fault
crypto/akcipher.c:158:1: internal compiler error: Segmentation fault
crypto/api.c:645:1: internal compiler error: Segmentation fault
crypto/asymmetric_keys/public_key.c:412:1: internal compiler error: Segmentation fault
crypto/dh.c:280:1: internal compiler error: Segmentation fault
crypto/ecc.c:1668:1: internal compiler error: Segmentation fault
crypto/geniv.c:163:1: internal compiler error: Segmentation fault
crypto/gf128mul.c:416:1: internal compiler error: Segmentation fault
crypto/kpp.c:115:1: internal compiler error: Segmentation fault
crypto/rng.c:228:1: internal compiler error: Segmentation fault
crypto/scompress.c:305:1: internal compiler error: Segmentation fault
crypto/shash.c:627:1: internal compiler error: Segmentation fault
crypto/skcipher.c:984:1: internal compiler error: Segmentation fault
drivers/base/map.c:154:1: internal compiler error: Segmentation fault
drivers/base/power/domain_governor.c:406:1: internal compiler error: Segmentation fault
drivers/base/power/sysfs.c:838:1: internal compiler error: Segmentation fault
drivers/base/power/wakeirq.c:405:1: internal compiler error: Segmentation fault
drivers/base/regmap/regcache-flat.c:83:1: internal compiler error: Segmentation fault
drivers/base/regmap/regcache-rbtree.c:553:1: internal compiler error: Segmentation fault
drivers/base/regmap/regcache.c:785:1: internal compiler error: Segmentation fault
drivers/base/regmap/regmap-debugfs.c:692:1: internal compiler error: Segmentation fault
drivers/base/regmap/regmap-mmio.c:453:1: internal compiler error: Segmentation fault
drivers/base/regmap/regmap-sdw-mbq.c:101:1: internal compiler error: Segmentation fault
drivers/base/regmap/regmap-slimbus.c:71:1: internal compiler error: Segmentation fault
drivers/base/syscore.c:128:1: internal compiler error: Segmentation fault
drivers/char/ipmi/ipmi_bt_sm.c:696:1: internal compiler error: Segmentation fault
drivers/char/ipmi/ipmi_kcs_sm.c:536:1: internal compiler error: Segmentation fault
drivers/char/ipmi/ipmi_plat_data.c:124:1: internal compiler error: Segmentation fault
drivers/char/ipmi/ipmi_si_hotmod.c:237:1: internal compiler error: Segmentation fault
drivers/char/ipmi/ipmi_si_mem_io.c:146:1: internal compiler error: Segmentation fault
drivers/char/ipmi/ipmi_si_port_io.c:114:1: internal compiler error: Segmentation fault
drivers/char/ipmi/ipmi_smic_sm.c:585:1: internal compiler error: Segmentation fault
drivers/char/tpm/eventlog/efi.c:124:1: internal compiler error: Segmentation fault
drivers/clk/clk-composite.c:487:1: internal compiler error: Segmentation fault
drivers/clk/clk-fractional-divider.c:259:1: internal compiler error: Segmentation fault
drivers/clk/imx/clk-pll14xx.c:166:2: warning: Value stored to 'pll_div_ctl1' is never read [clang-analyzer-deadcode.DeadStores]
drivers/comedi/comedi_buf.c:691:1: internal compiler error: Segmentation fault
drivers/comedi/drivers.c:1183:1: internal compiler error: Segmentation fault
drivers/comedi/range.c:131:1: internal compiler error: Segmentation fault
drivers/crypto/ccree/cc_aead.c:2664:1: internal compiler error: Segmentation fault
drivers/crypto/ccree/cc_buffer_mgr.c:1383:1: internal compiler error: Segmentation fault
drivers/crypto/ccree/cc_cipher.c:1509:1: internal compiler error: Segmentation fault
drivers/crypto/ccree/cc_fips.c:154:1: internal compiler error: Segmentation fault
drivers/crypto/ccree/cc_hash.c:2315:1: internal compiler error: Segmentation fault
drivers/crypto/ccree/cc_pm.c:80:1: internal compiler error: Segmentation fault
drivers/crypto/ccree/cc_request_mgr.c:662:1: internal compiler error: Segmentation fault
drivers/crypto/ccree/cc_sram_mgr.c:91:1: internal compiler error: Segmentation fault
drivers/dma-buf/dma-fence-array.c:207:1: internal compiler error: Segmentation fault
drivers/dma-buf/dma-fence-chain.c:258:1: internal compiler error: Segmentation fault
drivers/dma-buf/dma-fence.c:960:1: internal compiler error: Segmentation fault
drivers/dma-buf/dma-heap.c:324:1: internal compiler error: Segmentation fault
drivers/dma/idma64.c:644: undefined reference to `devm_ioremap_resource'
drivers/firmware/efi/vars.c:1222:1: internal compiler error: Segmentation fault
drivers/firmware/turris-mox-rwtm.c:146:1: warning: Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
drivers/gpio/gpio-max730x.c:236:1: internal compiler error: Segmentation fault
drivers/gpio/gpiolib-of.c:1057:1: internal compiler error: Segmentation fault
drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_resource.c:1633:6: warning: no previous prototype for 'is_timing_changed' [-Wmissing-prototypes]
drivers/hid/hid-cmedia.c:246:1: internal compiler error: Segmentation fault
drivers/hid/hid-core.c:1665:30: warning: Although the value stored to 'field' is used in the enclosing expression, the value is never actually read from 'field' [clang-analyzer-deadcode.DeadStores]
drivers/hid/hid-debug.c:1269:1: internal compiler error: Segmentation fault
drivers/hid/hid-picolcd_debugfs.c:884:1: internal compiler error: Segmentation fault
drivers/hid/hid-picolcd_fb.c:605:1: internal compiler error: Segmentation fault
drivers/hid/hid-picolcd_leds.c:161:1: internal compiler error: Segmentation fault
drivers/hid/hid-roccat-common.c:175:1: internal compiler error: Segmentation fault
drivers/hid/hid-uclogic-params.c:1140:1: internal compiler error: Segmentation fault
drivers/hid/hid-uclogic-rdesc.c:862:1: internal compiler error: Segmentation fault
drivers/hid/usbhid/hiddev.c:945:1: internal compiler error: Segmentation fault
drivers/hwmon/nsa320-hwmon.c:114:9: warning: Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
drivers/iio/frequency/admv1014.c:703:22: sparse: sparse: dubious: x & !y
drivers/infiniband/core/addr.c:890:1: internal compiler error: Segmentation fault
drivers/infiniband/core/agent.c:221:1: internal compiler error: Segmentation fault
drivers/infiniband/core/cache.c:1675:1: internal compiler error: Segmentation fault
drivers/infiniband/core/cm_trace.c:16: internal compiler error: Segmentation fault
drivers/infiniband/core/counters.c:669:1: internal compiler error: Segmentation fault
drivers/infiniband/core/cq.c:508:1: internal compiler error: Segmentation fault
drivers/infiniband/core/ib_core_uverbs.c:367:1: internal compiler error: Segmentation fault
drivers/infiniband/core/iwpm_msg.c:846:1: internal compiler error: Segmentation fault
drivers/infiniband/core/iwpm_util.c:793:1: internal compiler error: Segmentation fault
drivers/infiniband/core/lag.c:138:1: internal compiler error: Segmentation fault
drivers/infiniband/core/mad_rmpp.c:960:1: internal compiler error: Segmentation fault
drivers/infiniband/core/mr_pool.c:82:1: internal compiler error: Segmentation fault
drivers/infiniband/core/multicast.c:906:1: internal compiler error: Segmentation fault
drivers/infiniband/core/netlink.c:331:1: internal compiler error: Segmentation fault
drivers/infiniband/core/packer.c:201:1: internal compiler error: Segmentation fault
drivers/infiniband/core/rdma_core.c:1015:1: internal compiler error: Segmentation fault
drivers/infiniband/core/restrack.c:355:1: internal compiler error: Segmentation fault
drivers/infiniband/core/rw.c:760:1: internal compiler error: Segmentation fault
drivers/infiniband/core/sa_query.c:2269:1: internal compiler error: Segmentation fault
drivers/infiniband/core/smi.c:338:1: internal compiler error: Segmentation fault
drivers/infiniband/core/sysfs.c:1475:1: internal compiler error: Segmentation fault
drivers/infiniband/core/trace.c:13: internal compiler error: Segmentation fault
drivers/infiniband/core/ud_header.c:547:1: internal compiler error: Segmentation fault
drivers/infiniband/core/umem.c:317:1: internal compiler error: Segmentation fault
drivers/infiniband/core/umem_dmabuf.c:231:1: internal compiler error: Segmentation fault
drivers/infiniband/core/umem_odp.c:517:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_cmd.c:4044:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_ioctl.c:829:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_marshall.c:215:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_std_types.c:269:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_std_types_async_fd.c:79:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_std_types_counters.c:161:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_std_types_cq.c:222:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_std_types_device.c:503:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_std_types_dm.c:116:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_std_types_flow_action.c:447:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_std_types_mr.c:385:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_std_types_qp.c:380:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_std_types_srq.c:234:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_std_types_wq.c:194:1: internal compiler error: Segmentation fault
drivers/infiniband/core/uverbs_uapi.c:734:1: internal compiler error: Segmentation fault
drivers/infiniband/core/verbs.c:3030:1: internal compiler error: Segmentation fault
drivers/infiniband/sw/siw/siw_cm.c:1956:1: internal compiler error: Segmentation fault
drivers/infiniband/sw/siw/siw_cq.c:102:1: internal compiler error: Segmentation fault
drivers/infiniband/sw/siw/siw_mem.c:449:1: internal compiler error: Segmentation fault
drivers/infiniband/sw/siw/siw_qp.c:1347:1: internal compiler error: Segmentation fault
drivers/infiniband/sw/siw/siw_qp_tx.c:1279:1: internal compiler error: Segmentation fault
drivers/infiniband/sw/siw/siw_verbs.c:1854:1: internal compiler error: Segmentation fault
drivers/input/input-poller.c:222:1: internal compiler error: Segmentation fault
drivers/input/matrix-keymap.c:202:1: internal compiler error: Segmentation fault
drivers/input/misc/adxl34x.c:911:1: internal compiler error: Segmentation fault
drivers/input/misc/cma3000_d0x.c:388:1: internal compiler error: Segmentation fault
drivers/input/rmi4/rmi_2d_sensor.c:330:1: internal compiler error: Segmentation fault
drivers/input/rmi4/rmi_f01.c:729:1: internal compiler error: Segmentation fault
drivers/input/rmi4/rmi_f03.c:328:1: internal compiler error: Segmentation fault
drivers/input/rmi4/rmi_f30.c:405:1: internal compiler error: Segmentation fault
drivers/input/rmi4/rmi_f54.c:758:1: internal compiler error: Segmentation fault
drivers/input/rmi4/rmi_f55.c:128:1: internal compiler error: Segmentation fault
drivers/input/serio/ps2-gpio.c:223:4: warning: Value stored to 'rxflags' is never read [clang-analyzer-deadcode.DeadStores]
drivers/input/touchscreen.c:207:1: internal compiler error: Segmentation fault
drivers/iommu/of_iommu.c:174:1: internal compiler error: Segmentation fault
drivers/leds/leds-ti-lmu-common.c:153:1: internal compiler error: Segmentation fault
drivers/media/common/videobuf2/frame_vector.c:235:1: internal compiler error: Segmentation fault
drivers/media/common/videobuf2/vb2-trace.c:10:1: internal compiler error: Segmentation fault
drivers/media/common/videobuf2/videobuf2-dma-contig.c:872:1: internal compiler error: Segmentation fault
drivers/media/common/videobuf2/videobuf2-dma-sg.c:680:1: internal compiler error: Segmentation fault
drivers/media/common/videobuf2/videobuf2-memops.c:129:1: internal compiler error: Segmentation fault
drivers/media/common/videobuf2/videobuf2-vmalloc.c:449:1: internal compiler error: Segmentation fault
drivers/media/platform/chips-media/coda-bit.c:1127:2: warning: Value stored to 'value' is never read [clang-analyzer-deadcode.DeadStores]
drivers/media/platform/chips-media/coda-common.c:478:38: warning: Array access (from variable 'formats') results in a null pointer dereference [clang-analyzer-core.NullDereference]
drivers/media/platform/st/stm32/dma2d/dma2d-hw.c:109:1: internal compiler error: in extract_insn, at recog.c:2770
drivers/media/platform/xilinx/xilinx-dma.c:760:1: internal compiler error: Segmentation fault
drivers/media/radio/tea575x.c:577:1: internal compiler error: Segmentation fault
drivers/media/usb/cpia2/cpia2_core.c:2434:1: internal compiler error: Segmentation fault
drivers/media/usb/cpia2/cpia2_usb.c:966:1: internal compiler error: Segmentation fault
drivers/media/usb/gspca/autogain_functions.c:165:1: internal compiler error: Segmentation fault
drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c:432:1: internal compiler error: Segmentation fault
drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c:273:1: internal compiler error: Segmentation fault
drivers/media/usb/pwc/pwc-ctrl.c:543:1: internal compiler error: Segmentation fault
drivers/media/usb/pwc/pwc-dec23.c:678:1: internal compiler error: Segmentation fault
drivers/media/usb/pwc/pwc-uncompress.c:92:1: internal compiler error: Segmentation fault
drivers/media/usb/pwc/pwc-v4l.c:1033:1: internal compiler error: Segmentation fault
drivers/media/usb/stkwebcam/stk-sensor.c:586:1: internal compiler error: Segmentation fault
drivers/media/usb/uvc/uvc_ctrl.c:2529:1: internal compiler error: Segmentation fault
drivers/media/usb/uvc/uvc_debugfs.c:105:1: internal compiler error: Segmentation fault
drivers/media/usb/uvc/uvc_entity.c:161:1: internal compiler error: Segmentation fault
drivers/media/usb/uvc/uvc_isight.c:135:1: internal compiler error: Segmentation fault
drivers/media/usb/uvc/uvc_metadata.c:176:1: internal compiler error: Segmentation fault
drivers/media/usb/uvc/uvc_queue.c:515:1: internal compiler error: Segmentation fault
drivers/media/usb/uvc/uvc_status.c:313:1: internal compiler error: Segmentation fault
drivers/media/usb/uvc/uvc_v4l2.c:1550:1: internal compiler error: Segmentation fault
drivers/media/usb/uvc/uvc_video.c:2216:1: internal compiler error: Segmentation fault
drivers/memory/brcmstb_dpfe.c:707:10: warning: Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
drivers/mfd/cs47l35-tables.c:1555:1: internal compiler error: Segmentation fault
drivers/mfd/madera-core.c:799:1: internal compiler error: Segmentation fault
drivers/mfd/mfd-core.c:440:1: internal compiler error: Segmentation fault
drivers/misc/eeprom/eeprom_93cx6.c:372:1: internal compiler error: Segmentation fault
drivers/mmc/host/litex_mmc.c:424 litex_mmc_request() error: we previously assumed 'data' could be null (see line 418)
drivers/mtd/chips/cfi_cmdset_0020.c:1401:1: internal compiler error: Segmentation fault
drivers/mtd/mtdsuper.c:202:1: internal compiler error: Segmentation fault
drivers/mtd/nand/bbt.c:131:1: internal compiler error: Segmentation fault
drivers/mtd/nand/ecc-mxic.c:523:17: warning: Value stored to 'dev' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
drivers/mtd/nand/ecc-mxic.c:595:6: warning: Branch condition evaluates to a garbage value [clang-analyzer-core.uninitialized.Branch]
drivers/mtd/nand/ecc-sw-hamming.c:660:1: internal compiler error: Segmentation fault
drivers/mtd/nand/raw/denali.c:1381:1: internal compiler error: Segmentation fault
drivers/mtd/nand/raw/nand_base.c:6466:1: internal compiler error: Segmentation fault
drivers/mtd/nand/raw/nand_hynix.c:735:1: internal compiler error: Segmentation fault
drivers/mtd/nand/raw/nand_jedec.c:139:1: internal compiler error: Segmentation fault
drivers/mtd/nand/raw/nand_legacy.c:644:1: internal compiler error: Segmentation fault
drivers/mtd/nand/raw/nand_macronix.c:334:1: internal compiler error: Segmentation fault
drivers/mtd/nand/raw/nand_micron.c:599:1: internal compiler error: Segmentation fault
drivers/mtd/nand/raw/nand_onfi.c:337:1: internal compiler error: Segmentation fault
drivers/mtd/nand/raw/nand_samsung.c:139:1: internal compiler error: Segmentation fault
drivers/mtd/nand/raw/nand_timings.c:737:1: internal compiler error: Segmentation fault
drivers/mtd/nand/raw/nand_toshiba.c:300:1: internal compiler error: Segmentation fault
drivers/net/can/dev/length.c:95:1: internal compiler error: Segmentation fault
drivers/net/can/dev/rx-offload.c:402:1: internal compiler error: Segmentation fault
drivers/net/can/dev/skb.c:254:1: internal compiler error: Segmentation fault
drivers/net/phy/mii_timestamper.c:135:1: internal compiler error: Segmentation fault
drivers/net/vxlan/vxlan_core.c:440:34: sparse: sparse: incorrect type in argument 2 (different base types)
drivers/nfc/fdp/fdp.c:756:1: internal compiler error: Segmentation fault
drivers/nvme/host/zns.c:250:1: internal compiler error: Segmentation fault
drivers/nvme/target/zns.c:612:1: internal compiler error: Segmentation fault
drivers/nvmem/sunplus-ocotp.c:74:29: sparse: sparse: symbol 'sp_otp_v0' was not declared. Should it be static?
drivers/of/kobj.c:165:1: internal compiler error: Segmentation fault
drivers/parport/daisy.c:507:1: internal compiler error: Segmentation fault
drivers/parport/ieee1284.c:789:1: internal compiler error: Segmentation fault
drivers/parport/ieee1284_ops.c:893:1: internal compiler error: Segmentation fault
drivers/parport/probe.c:274:1: internal compiler error: Segmentation fault
drivers/pci/of.c:635:1: internal compiler error: Segmentation fault
drivers/pci/vgaarb.c:213:17: warning: Value stored to 'dev' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
drivers/pcmcia/rsrc_mgr.c:70:1: internal compiler error: Segmentation fault
drivers/phy/broadcom/phy-brcm-usb.c:233:9: warning: Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
drivers/phy/phy-core-mipi-dphy.c:164:1: internal compiler error: Segmentation fault
drivers/power/supply/ip5xxx_power.c:341 ip5xxx_battery_get_property() error: uninitialized symbol 'raw'.
drivers/rtc/sysfs.c:354:1: internal compiler error: Segmentation fault
drivers/scsi/iscsi_boot_sysfs.c:554:1: internal compiler error: Segmentation fault
drivers/scsi/libiscsi.c:3788:1: internal compiler error: Segmentation fault
drivers/scsi/libiscsi_tcp.c:1246:1: internal compiler error: Segmentation fault
drivers/scsi/libsas/sas_event.c:228:1: internal compiler error: Segmentation fault
drivers/scsi/libsas/sas_task.c:37:1: internal compiler error: Segmentation fault
drivers/scsi/lpfc/lpfc_els.c:7983:38: sparse:    left side has type unsigned int
drivers/scsi/lpfc/lpfc_els.c:7983:38: sparse:    right side has type restricted __be32
drivers/scsi/lpfc/lpfc_els.c:7983:38: sparse: sparse: invalid assignment: |=
drivers/scsi/lpfc/lpfc_els.c:8504:33: sparse: sparse: incorrect type in assignment (different base types)
drivers/scsi/scsi_lib_dma.c:52:1: internal compiler error: Segmentation fault
drivers/scsi/ufs/ufs-sysfs.c:1267:1: internal compiler error: Segmentation fault
drivers/slimbus/messaging.c:365:1: internal compiler error: Segmentation fault
drivers/slimbus/stream.c:477:1: internal compiler error: Segmentation fault
drivers/ssb/driver_chipcommon.c:598:1: internal compiler error: Segmentation fault
drivers/ssb/scan.c:446:1: internal compiler error: Segmentation fault
drivers/staging/greybus/arche-apb-ctrl.c:302:10: warning: Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
drivers/target/iscsi/iscsi_target_auth.c:531:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_configfs.c:1550:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_datain_values.c:519:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_device.c:57:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_erl0.c:936:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_erl1.c:1239:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_erl2.c:429:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_login.c:1453:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_nego.c:1338:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_nodeattrib.c:253:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_parameters.c:1715:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_seq_pdu_list.c:690:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_stat.c:798:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_tmr.c:841:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_tpg.c:913:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_transport.c:54:1: internal compiler error: Segmentation fault
drivers/target/iscsi/iscsi_target_util.c:1371:1: internal compiler error: Segmentation fault
drivers/tty/serial/sunplus-uart.c:501:26: sparse: sparse: symbol 'sunplus_console_ports' was not declared. Should it be static?
drivers/tty/tty_audit.c:248:1: internal compiler error: Segmentation fault
drivers/usb/cdns3/drd.c:495:1: internal compiler error: Segmentation fault
drivers/usb/cdns3/host.c:143:1: internal compiler error: Segmentation fault
drivers/usb/chipidea/host.c:486:1: internal compiler error: Segmentation fault
drivers/usb/core/config.c:1094:1: internal compiler error: Segmentation fault
drivers/usb/core/devices.c:593:1: internal compiler error: Segmentation fault
drivers/usb/core/endpoint.c:191:1: internal compiler error: Segmentation fault
drivers/usb/core/generic.c:324:1: internal compiler error: Segmentation fault
drivers/usb/core/port.c:658:1: internal compiler error: Segmentation fault
drivers/usb/core/quirks.c:703:1: internal compiler error: Segmentation fault
drivers/usb/core/sysfs.c:1263:1: internal compiler error: Segmentation fault
drivers/usb/dwc3/debugfs.c:934:1: internal compiler error: Segmentation fault
drivers/usb/dwc3/drd.c:660:1: internal compiler error: Segmentation fault
drivers/usb/dwc3/ep0.c:1176:1: internal compiler error: Segmentation fault
drivers/usb/dwc3/gadget.c:4447:1: internal compiler error: Segmentation fault
drivers/usb/gadget/composite.c:2605:1: internal compiler error: Segmentation fault
drivers/usb/gadget/config.c:268:1: internal compiler error: Segmentation fault
drivers/usb/gadget/epautoconf.c:214:1: internal compiler error: Segmentation fault
drivers/usb/gadget/function/f_tcm.c:2333:1: internal compiler error: Segmentation fault
drivers/usb/gadget/function/storage_common.c:522:1: internal compiler error: Segmentation fault
drivers/usb/gadget/function/u_uac1_legacy.c:306:1: internal compiler error: Segmentation fault
drivers/usb/gadget/function/uvc_configfs.c:2462:1: internal compiler error: Segmentation fault
drivers/usb/gadget/function/uvc_queue.c:369:1: internal compiler error: Segmentation fault
drivers/usb/gadget/function/uvc_v4l2.c:398:1: internal compiler error: Segmentation fault
drivers/usb/gadget/function/uvc_video.c:497:1: internal compiler error: Segmentation fault
drivers/usb/gadget/functions.c:117:1: internal compiler error: Segmentation fault
drivers/usb/gadget/u_f.c:30:1: internal compiler error: Segmentation fault
drivers/usb/gadget/udc/snps_udc_core.c:3193:1: internal compiler error: Segmentation fault
drivers/usb/gadget/udc/trace.c:11: internal compiler error: Segmentation fault
drivers/usb/gadget/usbstring.c:91:1: internal compiler error: Segmentation fault
drivers/usb/host/xhci-dbg.c:35:1: internal compiler error: Segmentation fault
drivers/usb/isp1760/isp1760-udc.c:1600:1: internal compiler error: Segmentation fault
drivers/usb/mon/mon_stat.c:71:1: internal compiler error: Segmentation fault
drivers/usb/musb/musb_gadget.c:2094:1: internal compiler error: Segmentation fault
drivers/usb/musb/musb_gadget_ep0.c:1058:1: internal compiler error: Segmentation fault
drivers/usb/storage/initializers.c:94:1: internal compiler error: Segmentation fault
drivers/usb/typec/bus.c:412:1: internal compiler error: Segmentation fault
drivers/usb/typec/tcpm/tcpm.c:6457:1: internal compiler error: Segmentation fault
drivers/usb/usbip/stub_rx.c:686:1: internal compiler error: Segmentation fault
drivers/usb/usbip/stub_tx.c:453:1: internal compiler error: Segmentation fault
drivers/usb/usbip/usbip_event.c:196:1: internal compiler error: Segmentation fault
drivers/vfio/mdev/vfio_mdev.c:152:1: internal compiler error: Segmentation fault
drivers/video/fbdev/core/fb_defio.c:240:1: internal compiler error: Segmentation fault
drivers/video/fbdev/core/fbcmap.c:362:1: internal compiler error: Segmentation fault
drivers/video/fbdev/core/fbsysfs.c:544:1: internal compiler error: Segmentation fault
drivers/virtio/virtio_ring.c:2465:1: internal compiler error: Segmentation fault
drivers/w1/w1_family.c:130:1: internal compiler error: Segmentation fault
drivers/w1/w1_netlink.c:725:1: internal compiler error: Segmentation fault
drivers/watchdog/watchdog_pretimeout.c:216:1: internal compiler error: Segmentation fault
fs/afs/addr_list.c:404:1: internal compiler error: Segmentation fault
fs/afs/callback.c:228:1: internal compiler error: Segmentation fault
fs/afs/cmservice.c:672:1: internal compiler error: Segmentation fault
fs/afs/dir_edit.c:493:1: internal compiler error: Segmentation fault
fs/afs/dir_silly.c:282:1: internal compiler error: Segmentation fault
fs/afs/dynroot.c:393:1: internal compiler error: Segmentation fault
fs/afs/file.c:623:1: internal compiler error: Segmentation fault
fs/afs/flock.c:877:1: internal compiler error: Segmentation fault
fs/afs/fs_operation.c:259:1: internal compiler error: Segmentation fault
fs/afs/fs_probe.c:475:1: internal compiler error: Segmentation fault
fs/afs/mntpt.c:225:1: internal compiler error: Segmentation fault
fs/afs/server_list.c:129:1: internal compiler error: Segmentation fault
fs/afs/vl_alias.c:383:1: internal compiler error: Segmentation fault
fs/afs/vl_list.c:335:1: internal compiler error: Segmentation fault
fs/afs/vl_probe.c:292:1: internal compiler error: Segmentation fault
fs/afs/vl_rotate.c:348:1: internal compiler error: Segmentation fault
fs/afs/vlclient.c:759:1: internal compiler error: Segmentation fault
fs/afs/volume.c:428:1: internal compiler error: Segmentation fault
fs/afs/write.c:1034:1: internal compiler error: Segmentation fault
fs/afs/xattr.c:363:1: internal compiler error: Segmentation fault
fs/autofs/expire.c:620:1: internal compiler error: Segmentation fault
fs/autofs/inode.c:385:1: internal compiler error: Segmentation fault
fs/autofs/root.c:919:1: internal compiler error: Segmentation fault
fs/autofs/symlink.c:26:1: internal compiler error: Segmentation fault
fs/autofs/waitq.c:512:1: internal compiler error: Segmentation fault
fs/bad_inode.c:252:1: internal compiler error: Segmentation fault
fs/btrfs/async-thread.c:419:1: internal compiler error: Segmentation fault
fs/btrfs/block-group.c:4082:1: internal compiler error: Segmentation fault
fs/btrfs/block-rsv.c:558:1: internal compiler error: Segmentation fault
fs/btrfs/ctree.c:4779:1: internal compiler error: Segmentation fault
fs/btrfs/delalloc-space.c:486:1: internal compiler error: Segmentation fault
fs/btrfs/dev-replace.c:1332:1: internal compiler error: Segmentation fault
fs/btrfs/dir-item.c:460:1: internal compiler error: Segmentation fault
fs/btrfs/discard.c:723:1: internal compiler error: Segmentation fault
fs/btrfs/export.c:281:1: internal compiler error: Segmentation fault
fs/btrfs/file-item.c:1285:1: internal compiler error: Segmentation fault
fs/btrfs/free-space-cache.c:4116:1: internal compiler error: Segmentation fault
fs/btrfs/free-space-tree.c:1603:1: internal compiler error: Segmentation fault
fs/btrfs/inode-item.c:749:1: internal compiler error: Segmentation fault
fs/btrfs/ioctl.c:5334:1: internal compiler error: Segmentation fault
fs/btrfs/locking.c:291:1: internal compiler error: Segmentation fault
fs/btrfs/lzo.c:495:1: internal compiler error: Segmentation fault
fs/btrfs/orphan.c:58:1: internal compiler error: Segmentation fault
fs/btrfs/print-tree.c:410:1: internal compiler error: Segmentation fault
fs/btrfs/qgroup.c:4321:1: internal compiler error: Segmentation fault
fs/btrfs/raid56.c:2709:1: internal compiler error: Segmentation fault
fs/btrfs/reflink.c:911:1: internal compiler error: Segmentation fault
fs/btrfs/root-tree.c:545:1: internal compiler error: Segmentation fault
fs/btrfs/struct-funcs.c:171:1: internal compiler error: Segmentation fault
fs/btrfs/subpage.c:745:1: internal compiler error: Segmentation fault
fs/btrfs/transaction.c:2539:1: internal compiler error: Segmentation fault
fs/btrfs/tree-defrag.c:132:1: internal compiler error: Segmentation fault
fs/btrfs/tree-log.c:6828:1: internal compiler error: Segmentation fault
fs/btrfs/tree-mod-log.c:929:1: internal compiler error: Segmentation fault
fs/btrfs/ulist.c:276:1: internal compiler error: Segmentation fault
fs/btrfs/uuid-tree.c:390:1: internal compiler error: Segmentation fault
fs/btrfs/verity.c:813:1: internal compiler error: Segmentation fault
fs/btrfs/xattr.c:502:1: internal compiler error: Segmentation fault
fs/btrfs/zlib.c:462:1: internal compiler error: Segmentation fault
fs/btrfs/zoned.c:2035:1: internal compiler error: Segmentation fault
fs/btrfs/zstd.c:706:1: internal compiler error: Segmentation fault
fs/ceph/addr.c:2064:1: internal compiler error: Segmentation fault
fs/ceph/caps.c:4698:1: internal compiler error: Segmentation fault
fs/ceph/ceph_frag.c:23:1: internal compiler error: Segmentation fault
fs/ceph/debugfs.c:467:1: internal compiler error: Segmentation fault
fs/ceph/dir.c:1994:1: internal compiler error: Segmentation fault
fs/ceph/export.c:583:1: internal compiler error: Segmentation fault
fs/ceph/file.c:2596:1: internal compiler error: Segmentation fault
fs/ceph/inode.c:2438:1: internal compiler error: Segmentation fault
fs/ceph/io.c:163:1: internal compiler error: Segmentation fault
fs/ceph/ioctl.c:295:1: internal compiler error: Segmentation fault
fs/ceph/mdsmap.c:422:1: internal compiler error: Segmentation fault
fs/ceph/metric.c:344:1: internal compiler error: Segmentation fault
fs/ceph/quota.c:531:1: internal compiler error: Segmentation fault
fs/ceph/snap.c:1199:1: internal compiler error: Segmentation fault
fs/ceph/xattr.c:1399:1: internal compiler error: Segmentation fault
fs/cifs/cifs_debug.c:1066:1: internal compiler error: Segmentation fault
fs/cifs/cifs_dfs_ref.c:374:1: internal compiler error: Segmentation fault
fs/cifs/cifs_spnego.c:236:1: internal compiler error: Segmentation fault
fs/cifs/cifs_swn.c:674:1: internal compiler error: Segmentation fault
fs/cifs/cifs_unicode.c:632:1: internal compiler error: Segmentation fault
fs/cifs/cifsacl.c:1668:1: internal compiler error: Segmentation fault
fs/cifs/cifsencrypt.c:767:1: internal compiler error: Segmentation fault
fs/cifs/cifssmb.c:6055:1: internal compiler error: Segmentation fault
fs/cifs/connect.c:4498:1: internal compiler error: Segmentation fault
fs/cifs/dfs_cache.c:1661:1: internal compiler error: Segmentation fault
fs/cifs/dir.c:864:1: internal compiler error: Segmentation fault
fs/cifs/file.c:4986:1: internal compiler error: Segmentation fault
fs/cifs/fs_context.c:1764:1: internal compiler error: Segmentation fault
fs/cifs/inode.c:3014:1: internal compiler error: Segmentation fault
fs/cifs/ioctl.c:501:1: internal compiler error: Segmentation fault
fs/cifs/link.c:734:1: internal compiler error: Segmentation fault
fs/cifs/misc.c:1353:1: internal compiler error: Segmentation fault
fs/cifs/netlink.c:89:1: internal compiler error: Segmentation fault
fs/cifs/netmisc.c:1021:1: internal compiler error: Segmentation fault
fs/cifs/readdir.c:1056:1: internal compiler error: Segmentation fault
fs/cifs/sess.c:1718:1: internal compiler error: Segmentation fault
fs/cifs/smb1ops.c:1256:1: internal compiler error: Segmentation fault
fs/cifs/smb2file.c:287:1: internal compiler error: Segmentation fault
fs/cifs/smb2inode.c:750:1: internal compiler error: Segmentation fault
fs/cifs/smb2maperror.c:2481:1: internal compiler error: Segmentation fault
fs/cifs/smb2misc.c:922:1: internal compiler error: Segmentation fault
fs/cifs/smb2ops.c:5947:1: internal compiler error: Segmentation fault
fs/cifs/smb2pdu.c:5621:1: internal compiler error: Segmentation fault
fs/cifs/smb2transport.c:933:1: internal compiler error: Segmentation fault
fs/cifs/smbencrypt.c:91:1: internal compiler error: Segmentation fault
fs/cifs/trace.c:9: internal compiler error: Segmentation fault
fs/cifs/transport.c:1639:1: internal compiler error: Segmentation fault
fs/cifs/unc.c:69:1: internal compiler error: Segmentation fault
fs/coda/cache.c:118:1: internal compiler error: Segmentation fault
fs/coda/cnode.c:178:1: internal compiler error: Segmentation fault
fs/coda/dir.c:595:1: internal compiler error: Segmentation fault
fs/coda/file.c:305:1: internal compiler error: Segmentation fault
fs/coda/pioctl.c:88:1: internal compiler error: Segmentation fault
fs/coda/symlink.c:48:1: internal compiler error: Segmentation fault
fs/coda/upcall.c:961:1: internal compiler error: Segmentation fault
fs/configfs/file.c:482:1: internal compiler error: Segmentation fault
fs/configfs/inode.c:244:1: internal compiler error: Segmentation fault
fs/configfs/symlink.c:269:1: internal compiler error: Segmentation fault
fs/crypto/bio.c:194:1: internal compiler error: Segmentation fault
fs/crypto/fname.c:595:1: internal compiler error: Segmentation fault
fs/crypto/hkdf.c:182:1: internal compiler error: Segmentation fault
fs/crypto/hooks.c:430:1: internal compiler error: Segmentation fault
fs/crypto/keysetup.c:794:1: internal compiler error: Segmentation fault
fs/crypto/keysetup_v1.c:319:1: internal compiler error: Segmentation fault
fs/crypto/policy.c:818:1: internal compiler error: Segmentation fault
fs/d_path.c:448:1: internal compiler error: Segmentation fault
fs/dlm/dir.c:306:1: internal compiler error: Segmentation fault
fs/dlm/member.c:735:1: internal compiler error: Segmentation fault
fs/dlm/midcomms.c:1485:1: internal compiler error: Segmentation fault
fs/dlm/plock.c:510:1: internal compiler error: Segmentation fault
fs/dlm/rcom.c:675:1: internal compiler error: Segmentation fault
fs/dlm/recover.c:956:1: internal compiler error: Segmentation fault
fs/dlm/recoverd.c:352:1: internal compiler error: Segmentation fault
fs/dlm/requestqueue.c:167:1: internal compiler error: Segmentation fault
fs/efivarfs/inode.c:184:1: internal compiler error: Segmentation fault
fs/eventfd.c:457:1: internal compiler error: Segmentation fault
fs/exportfs/expfs.c:586:1: internal compiler error: Segmentation fault
fs/ext2/xattr_user.c:50:1: internal compiler error: Segmentation fault
fs/fhandle.c:267:1: internal compiler error: Segmentation fault
fs/fs_context.c:717:1: internal compiler error: Segmentation fault
fs/fs_pin.c:97:1: internal compiler error: Segmentation fault
fs/fs_struct.c:168:1: internal compiler error: Segmentation fault
fs/fsopen.c:469:1: internal compiler error: Segmentation fault
fs/gfs2/lock_dlm.c:1403:1: internal compiler error: Segmentation fault
fs/ioctl.c:879:1: internal compiler error: Segmentation fault
fs/kernfs/dir.c:1760:1: internal compiler error: Segmentation fault
fs/kernfs/file.c:1022:1: internal compiler error: Segmentation fault
fs/kernfs/inode.c:446:1: internal compiler error: Segmentation fault
fs/kernfs/symlink.c:153:1: internal compiler error: Segmentation fault
fs/namei.c:5051:1: internal compiler error: Segmentation fault
fs/nls/nls_base.c:548:1: internal compiler error: Segmentation fault
fs/ntfs3/attrib.c:2083:1: internal compiler error: Segmentation fault
fs/ntfs3/attrlist.c:457:1: internal compiler error: Segmentation fault
fs/ntfs3/dir.c:592:1: internal compiler error: Segmentation fault
fs/ntfs3/file.c:1253:1: internal compiler error: Segmentation fault
fs/ntfs3/frecord.c:3284:1: internal compiler error: Segmentation fault
fs/ntfs3/fslog.c:5213:1: internal compiler error: Segmentation fault
fs/ntfs3/fsntfs.c:2506:1: internal compiler error: Segmentation fault
fs/ntfs3/index.c:2584:1: internal compiler error: Segmentation fault
fs/ntfs3/inode.c:1959:1: internal compiler error: Segmentation fault
fs/ntfs3/lib/decompress_common.c:319:1: internal compiler error: Segmentation fault
fs/ntfs3/lib/lzx_decompress.c:670:1: internal compiler error: Segmentation fault
fs/ntfs3/lznt.c:453:1: internal compiler error: Segmentation fault
fs/ntfs3/namei.c:386:1: internal compiler error: Segmentation fault
fs/ntfs3/record.c:602:1: internal compiler error: Segmentation fault
fs/ntfs3/run.c:1111:1: internal compiler error: Segmentation fault
fs/ntfs3/upcase.c:104:1: internal compiler error: Segmentation fault
fs/ntfs3/xattr.c:994:1: internal compiler error: Segmentation fault
fs/ocfs2/acl.c:409:1: internal compiler error: Segmentation fault
fs/ocfs2/alloc.c:7704:1: internal compiler error: Segmentation fault
fs/ocfs2/aops.c:2469:1: internal compiler error: Segmentation fault
fs/ocfs2/blockcheck.c:604:1: internal compiler error: Segmentation fault
fs/ocfs2/buffer_head_io.c:463:1: internal compiler error: Segmentation fault
fs/ocfs2/cluster/masklog.c:174:1: internal compiler error: Segmentation fault
fs/ocfs2/cluster/netdebug.c:504:1: internal compiler error: Segmentation fault
fs/ocfs2/cluster/quorum.c:326:1: internal compiler error: Segmentation fault
fs/ocfs2/cluster/tcp.c:2138:1: internal compiler error: Segmentation fault
fs/ocfs2/dcache.c:470:1: internal compiler error: Segmentation fault
fs/ocfs2/dir.c:4459:1: internal compiler error: Segmentation fault
fs/ocfs2/dlmfs/userdlm.c:669:1: internal compiler error: Segmentation fault
fs/ocfs2/dlmglue.c:4468:1: internal compiler error: Segmentation fault
fs/ocfs2/export.c:283:1: internal compiler error: Segmentation fault
fs/ocfs2/extent_map.c:1021:1: internal compiler error: Segmentation fault
fs/ocfs2/file.c:2811:1: internal compiler error: Segmentation fault
fs/ocfs2/filecheck.c:509:1: internal compiler error: Segmentation fault
fs/ocfs2/heartbeat.c:117:1: internal compiler error: Segmentation fault
fs/ocfs2/inode.c:1658:1: internal compiler error: Segmentation fault
fs/ocfs2/ioctl.c:935:1: internal compiler error: Segmentation fault
fs/ocfs2/journal.c:2384:1: internal compiler error: Segmentation fault
fs/ocfs2/localalloc.c:1323:1: internal compiler error: Segmentation fault
fs/ocfs2/locks.c:124:1: internal compiler error: Segmentation fault
fs/ocfs2/mmap.c:176:1: internal compiler error: Segmentation fault
fs/ocfs2/move_extents.c:1079:1: internal compiler error: Segmentation fault
fs/ocfs2/namei.c:2927:1: internal compiler error: Segmentation fault
fs/ocfs2/quota_global.c:1016:1: internal compiler error: Segmentation fault
fs/ocfs2/refcounttree.c:4828:1: internal compiler error: Segmentation fault
fs/ocfs2/reservations.c:826:1: internal compiler error: Segmentation fault
fs/ocfs2/resize.c:582:1: internal compiler error: Segmentation fault
fs/ocfs2/slot_map.c:528:1: internal compiler error: Segmentation fault
fs/ocfs2/suballoc.c:2866:1: internal compiler error: Segmentation fault
fs/ocfs2/symlink.c:93:1: internal compiler error: Segmentation fault
fs/ocfs2/sysfile.c:166:1: internal compiler error: Segmentation fault
fs/ocfs2/xattr.c:7362:1: internal compiler error: Segmentation fault
fs/omfs/bitmap.c:194:1: internal compiler error: Segmentation fault
fs/omfs/dir.c:461:1: internal compiler error: Segmentation fault
fs/omfs/file.c:383:1: internal compiler error: Segmentation fault
fs/open.c:1431:1: internal compiler error: Segmentation fault
fs/overlayfs/dir.c:1315:1: internal compiler error: Segmentation fault
fs/overlayfs/export.c:872:1: internal compiler error: Segmentation fault
fs/overlayfs/inode.c:1196:1: internal compiler error: Segmentation fault
fs/overlayfs/namei.c:1191:1: internal compiler error: Segmentation fault
fs/overlayfs/readdir.c:1233:1: internal compiler error: Segmentation fault
fs/overlayfs/util.c:1062:1: internal compiler error: Segmentation fault
fs/pnode.c:602:1: internal compiler error: Segmentation fault
fs/posix_acl.c:1018:1: internal compiler error: Segmentation fault
fs/pstore/pmsg.c:94:1: internal compiler error: Segmentation fault
fs/quota/quota.c:1013:1: internal compiler error: Segmentation fault
fs/quota/quota_tree.c:740:1: internal compiler error: Segmentation fault
fs/readdir.c:384:1: internal compiler error: Segmentation fault
fs/select.c:1123:1: internal compiler error: Segmentation fault
fs/smbfs_common/cifs_md4.c:197:1: internal compiler error: Segmentation fault
fs/splice.c:1721:1: internal compiler error: Segmentation fault
fs/squashfs/decompressor_multi.c:197:1: internal compiler error: Segmentation fault
fs/squashfs/zstd_wrapper.c:144:1: internal compiler error: Segmentation fault
fs/stack.c:76:1: internal compiler error: Segmentation fault
fs/statfs.c:264:1: internal compiler error: Segmentation fault
fs/sync.c:382:1: internal compiler error: Segmentation fault
fs/unicode/utf8-core.c:217:1: internal compiler error: Segmentation fault
fs/utimes.c:164:1: internal compiler error: Segmentation fault
fs/xattr.c:1132:1: internal compiler error: Segmentation fault
include/asm-generic/io.h:464:31: warning: performing pointer arithmetic on a null pointer has undefined behavior err: false
include/linux/cacheflush.h:12:46: warning: 'struct folio' declared inside parameter list will not be visible outside of this definition or declaration
include/linux/fortify-string.h:336:4: warning: call to __read_overflow2_field declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning]
include/linux/fortify-string.h:45:33: warning: '__builtin_memcpy' offset [0, 31] is out of the bounds [0, 0] [-Warray-bounds]
include/linux/fortify-string.h:45:33: warning: '__builtin_memcpy' offset [0, 511] is out of the bounds [0, 0] [-Warray-bounds]
include/linux/module.h:274:46: internal compiler error: Segmentation fault
include/linux/rcupdate.h:414:36: error: dereferencing pointer to incomplete type 'struct css_set'
ipc/msgutil.c:184:1: internal compiler error: Segmentation fault
kernel/acct.c:602:1: internal compiler error: Segmentation fault
kernel/auditsc.c:2997:1: internal compiler error: Segmentation fault
kernel/bpf/offload.c:712:1: internal compiler error: Segmentation fault
kernel/bpf/reuseport_array.c:351:1: internal compiler error: Segmentation fault
kernel/cgroup/freezer.c:323:1: internal compiler error: Segmentation fault
kernel/dma/direct.c:631:1: internal compiler error: Segmentation fault
kernel/irq/chip.c:1599:1: internal compiler error: Segmentation fault
kernel/printk/printk_ringbuffer.c:2082:1: internal compiler error: Segmentation fault
kernel/printk/printk_safe.c:52:1: internal compiler error: Segmentation fault
kernel/range.c:165:1: internal compiler error: Segmentation fault
kernel/rcu/rcu_segcblist.c:633:1: internal compiler error: Segmentation fault
kernel/rcu/sync.c:206:1: internal compiler error: Segmentation fault
kernel/sched/core.c:5268:20: warning: no previous prototype for function 'task_sched_runtime' [-Wmissing-prototypes]
kernel/sched/core.c:8979:6: warning: no previous prototype for 'idle_task_exit' [-Wmissing-prototypes]
kernel/sched/core.c:8979:6: warning: no previous prototype for function 'idle_task_exit' [-Wmissing-prototypes]
kernel/sched/core.c:9214:5: warning: no previous prototype for 'sched_cpu_activate' [-Wmissing-prototypes]
kernel/sched/core.c:9214:5: warning: no previous prototype for function 'sched_cpu_activate' [-Wmissing-prototypes]
kernel/sched/core.c:9259:5: warning: no previous prototype for 'sched_cpu_deactivate' [-Wmissing-prototypes]
kernel/sched/core.c:9259:5: warning: no previous prototype for function 'sched_cpu_deactivate' [-Wmissing-prototypes]
kernel/sched/core.c:9334:5: warning: no previous prototype for 'sched_cpu_starting' [-Wmissing-prototypes]
kernel/sched/core.c:9334:5: warning: no previous prototype for function 'sched_cpu_starting' [-Wmissing-prototypes]
kernel/sched/core.c:9355:5: warning: no previous prototype for 'sched_cpu_wait_empty' [-Wmissing-prototypes]
kernel/sched/core.c:9355:5: warning: no previous prototype for function 'sched_cpu_wait_empty' [-Wmissing-prototypes]
kernel/sched/core.c:9397:5: warning: no previous prototype for 'sched_cpu_dying' [-Wmissing-prototypes]
kernel/sched/core.c:9397:5: warning: no previous prototype for function 'sched_cpu_dying' [-Wmissing-prototypes]
kernel/sched/core.c:9420:13: warning: no previous prototype for function 'sched_init_smp' [-Wmissing-prototypes]
kernel/sched/core.c:9453:13: warning: no previous prototype for function 'sched_init_smp' [-Wmissing-prototypes]
kernel/sched/core.c:9481:13: warning: no previous prototype for function 'sched_init' [-Wmissing-prototypes]
kernel/sched/cpuacct.c:367:1: internal compiler error: Segmentation fault
kernel/sched/cputime.c:630:1: internal compiler error: Segmentation fault
kernel/sched/deadline.c:2955:1: internal compiler error: Segmentation fault
kernel/sched/fair.c:10665:6: warning: no previous prototype for 'nohz_balance_enter_idle' [-Wmissing-prototypes]
kernel/sched/fair.c:10665:6: warning: no previous prototype for function 'nohz_balance_enter_idle' [-Wmissing-prototypes]
kernel/sched/loadavg.c:245:6: warning: no previous prototype for 'calc_load_nohz_start' [-Wmissing-prototypes]
kernel/sched/loadavg.c:245:6: warning: no previous prototype for function 'calc_load_nohz_start' [-Wmissing-prototypes]
kernel/sched/loadavg.c:258:6: warning: no previous prototype for 'calc_load_nohz_remote' [-Wmissing-prototypes]
kernel/sched/loadavg.c:258:6: warning: no previous prototype for function 'calc_load_nohz_remote' [-Wmissing-prototypes]
kernel/sched/loadavg.c:263:6: warning: no previous prototype for 'calc_load_nohz_stop' [-Wmissing-prototypes]
kernel/sched/loadavg.c:263:6: warning: no previous prototype for function 'calc_load_nohz_stop' [-Wmissing-prototypes]
kernel/sched/membarrier.c:630:1: internal compiler error: Segmentation fault
kernel/sched/rt.c:2990:1: internal compiler error: Segmentation fault
kernel/sched/sched.h:87:11: fatal error: 'asm/paravirt_api_clock.h' file not found
kernel/sched/sched.h:87:11: fatal error: asm/paravirt_api_clock.h: No such file or directory
kernel/sys.c:2706:1: internal compiler error: Segmentation fault
kernel/task_work.c:169:1: internal compiler error: Segmentation fault
kernel/trace/trace_clock.c:158:1: internal compiler error: Segmentation fault
kernel/umh.c:564:1: internal compiler error: Segmentation fault
lib/asn1_decoder.c:521:1: internal compiler error: Segmentation fault
lib/cmdline.c:275:1: internal compiler error: Segmentation fault
lib/crc-itu-t.c:66:1: internal compiler error: Segmentation fault
lib/crc16.c:64:1: internal compiler error: Segmentation fault
lib/crypto/aes.c:356:1: internal compiler error: Segmentation fault
lib/crypto/blake2s-generic.c:115:1: internal compiler error: Segmentation fault
lib/crypto/poly1305-donna32.c:205:1: internal compiler error: Segmentation fault
lib/crypto/poly1305.c:78:1: internal compiler error: Segmentation fault
lib/dim/dim.c:83:1: internal compiler error: Segmentation fault
lib/dim/net_dim.c:246:1: internal compiler error: Segmentation fault
lib/dim/rdma_dim.c:108:1: internal compiler error: Segmentation fault
lib/dynamic_queue_limits.c:138:1: internal compiler error: Segmentation fault
lib/earlycpio.c:141:1: internal compiler error: Segmentation fault
lib/extable.c:118:1: internal compiler error: Segmentation fault
lib/fdt.c:3: internal compiler error: Segmentation fault
lib/fdt_ro.c:3: internal compiler error: Segmentation fault
lib/fdt_rw.c:3: internal compiler error: Segmentation fault
lib/fdt_sw.c:3: internal compiler error: Segmentation fault
lib/fdt_wip.c:3: internal compiler error: Segmentation fault
lib/flex_proportions.c:282:1: internal compiler error: Segmentation fault
lib/interval_tree.c:17:1: internal compiler error: Segmentation fault
lib/iov_iter.c:2067:1: internal compiler error: Segmentation fault
lib/is_single_threaded.c:54:1: internal compiler error: Segmentation fault
lib/kunit/assert.c:206:1: internal compiler error: Segmentation fault
lib/linear_ranges.c:276:1: internal compiler error: Segmentation fault
lib/logic_pio.c:232:1: internal compiler error: Segmentation fault
lib/lz4/lz4_compress.c:940:1: internal compiler error: Segmentation fault
lib/lz4/lz4_decompress.c:715:1: internal compiler error: Segmentation fault
lib/lzo/lzo1x_compress.c:400:1: internal compiler error: Segmentation fault
lib/lzo/lzo1x_decompress_safe.c:294:1: internal compiler error: Segmentation fault
lib/math/rational.c:111:1: internal compiler error: Segmentation fault
lib/mpi/generic_mpih-mul2.c:47:1: internal compiler error: Segmentation fault
lib/mpi/generic_mpih-mul3.c:48:1: internal compiler error: Segmentation fault
lib/mpi/mpi-div.c:234:1: internal compiler error: Segmentation fault
lib/mpi/mpi-mod.c:157:1: internal compiler error: Segmentation fault
lib/mpi/mpi-mul.c:91:1: internal compiler error: Segmentation fault
lib/mpi/mpih-div.c:517:1: internal compiler error: Segmentation fault
lib/mpi/mpih-mul.c:509:1: internal compiler error: Segmentation fault
lib/net_utils.c:27:1: internal compiler error: Segmentation fault
lib/nlattr.c:1121:1: internal compiler error: Segmentation fault
lib/oid_registry.c:199:1: internal compiler error: Segmentation fault
lib/plist.c:173:1: internal compiler error: Segmentation fault
lib/raid6/int1.c:154:1: internal compiler error: Segmentation fault
lib/raid6/int2.c:180:1: internal compiler error: Segmentation fault
lib/raid6/int4.c:232:1: internal compiler error: Segmentation fault
lib/raid6/int8.c:336:1: internal compiler error: Segmentation fault
lib/seq_buf.c:397:1: internal compiler error: Segmentation fault
lib/stackinit_kunit.c:259:8: warning: Excessive padding in 'struct test_big_hole' (124 padding bytes, where 60 is optimal).
lib/stackinit_kunit.c:339:1: warning: Address of stack memory associated with local variable 'var' is still referred to by the global variable 'fill_start' upon returning to the caller.  This will be a dangling reference [clang-analyzer-core.StackAddressEscape]
lib/stackinit_kunit.c:339:1: warning: Address of stack memory associated with local variable 'var' is still referred to by the global variable 'target_start' upon returning to the caller.  This will be a dangling reference [clang-analyzer-core.StackAddressEscape]
lib/stackinit_kunit.c:343:1: warning: Undefined or garbage value returned to caller [clang-analyzer-core.uninitialized.UndefReturn]
lib/syscall.c:88:1: internal compiler error: Segmentation fault
lib/zlib_deflate/deflate.c:1146:1: internal compiler error: Segmentation fault
lib/zlib_deflate/deftree.c:1058:1: internal compiler error: Segmentation fault
lib/zlib_inflate/inffast.c:325:1: internal compiler error: Segmentation fault
lib/zlib_inflate/inflate.c:814:1: internal compiler error: Segmentation fault
lib/zstd/common/entropy_common.c:357:1: internal compiler error: Segmentation fault
lib/zstd/common/fse_decompress.c:386:1: internal compiler error: Segmentation fault
lib/zstd/compress/fse_compress.c:622:1: internal compiler error: Segmentation fault
lib/zstd/compress/hist.c:164:1: internal compiler error: Segmentation fault
lib/zstd/compress/huf_compress.c:904:1: internal compiler error: Segmentation fault
lib/zstd/compress/zstd_compress.c:5109:1: internal compiler error: Segmentation fault
lib/zstd/compress/zstd_compress_literals.c:158:1: internal compiler error: Segmentation fault
lib/zstd/compress/zstd_compress_sequences.c:439:1: internal compiler error: Segmentation fault
lib/zstd/compress/zstd_compress_superblock.c:852:1: internal compiler error: Segmentation fault
lib/zstd/compress/zstd_double_fast.c:519:1: internal compiler error: Segmentation fault
lib/zstd/compress/zstd_fast.c:496:1: internal compiler error: Segmentation fault
lib/zstd/compress/zstd_lazy.c:1414:1: internal compiler error: Segmentation fault
lib/zstd/compress/zstd_ldm.c:686:1: internal compiler error: Segmentation fault
lib/zstd/compress/zstd_opt.c:1354:1: internal compiler error: Segmentation fault
lib/zstd/decompress/huf_decompress.c:1205:1: internal compiler error: Segmentation fault
lib/zstd/decompress/zstd_ddict.c:241:1: internal compiler error: Segmentation fault
lib/zstd/decompress/zstd_decompress.c:2085:1: internal compiler error: Segmentation fault
lib/zstd/decompress/zstd_decompress_block.c:1540:1: internal compiler error: Segmentation fault
m68k-linux-ld: arch/m68k/kernel/machine_kexec.c:56: undefined reference to `m68k_cputype'
m68k-linux-ld: arch/m68k/kernel/time.c:110: undefined reference to `mach_set_rtc_pll'
make[1]: *** No rule to make target 'arch/nds32/Makefile'.
mips64-linux-ld: page_alloc.c:(.init.text+0x1f38): undefined reference to `node_data'
mm/folio-compat.c:153:1: internal compiler error: Segmentation fault
mm/hmm.c:602:1: internal compiler error: Segmentation fault
mm/interval_tree.c:103:1: internal compiler error: Segmentation fault
mm/mmu_notifier.c:1120:1: internal compiler error: Segmentation fault
mm/ptdump.c:165:1: internal compiler error: Segmentation fault
nd_perf.c:(.text+0x158): undefined reference to `perf_pmu_migrate_context'
nd_perf.c:(.text+0x226): undefined reference to `perf_pmu_migrate_context'
nd_perf.c:(.text+0x4f8): undefined reference to `perf_pmu_register'
nd_perf.c:(.text+0x572): undefined reference to `perf_pmu_unregister'
nd_perf.c:(.text+0x604): undefined reference to `perf_pmu_register'
nd_perf.c:(.text+0x682): undefined reference to `perf_pmu_migrate_context'
nd_perf.c:(.text+0x738): undefined reference to `perf_pmu_unregister'
net/6lowpan/iphc.c:1313:1: internal compiler error: Segmentation fault
net/6lowpan/ndisc.c:233:1: internal compiler error: Segmentation fault
net/6lowpan/nhc.c:234:1: internal compiler error: Segmentation fault
net/802/garp.c:649:1: internal compiler error: Segmentation fault
net/802/mrp.c:935:1: internal compiler error: Segmentation fault
net/ax25/ax25_addr.c:303:1: internal compiler error: Segmentation fault
net/ax25/ax25_iface.c:214:1: internal compiler error: Segmentation fault
net/ax25/ax25_in.c:451:1: internal compiler error: Segmentation fault
net/ax25/ax25_ip.c:246:1: internal compiler error: Segmentation fault
net/ax25/ax25_out.c:386:1: internal compiler error: Segmentation fault
net/ax25/ax25_std_in.c:443:1: internal compiler error: Segmentation fault
net/ax25/ax25_std_timer.c:175:1: internal compiler error: Segmentation fault
net/ax25/ax25_subr.c:288:1: internal compiler error: Segmentation fault
net/ax25/ax25_timer.c:222:1: internal compiler error: Segmentation fault
net/bridge/br_if.c:787:1: internal compiler error: Segmentation fault
net/bridge/br_switchdev.c:756:1: internal compiler error: Segmentation fault
net/caif/cfcnfg.c:612:1: internal compiler error: Segmentation fault
net/caif/cfctrl.c:634:1: internal compiler error: Segmentation fault
net/caif/cfdbgl.c:55:1: internal compiler error: Segmentation fault
net/caif/cfdgml.c:113:1: internal compiler error: Segmentation fault
net/caif/cffrml.c:197:1: internal compiler error: Segmentation fault
net/caif/cfmuxl.c:267:1: internal compiler error: Segmentation fault
net/caif/cfpkt_skbuff.c:382:1: internal compiler error: Segmentation fault
net/caif/cfrfml.c:299:1: internal compiler error: Segmentation fault
net/caif/cfserl.c:192:1: internal compiler error: Segmentation fault
net/caif/cfsrvl.c:220:1: internal compiler error: Segmentation fault
net/caif/cfutill.c:104:1: internal compiler error: Segmentation fault
net/caif/cfveil.c:101:1: internal compiler error: Segmentation fault
net/caif/cfvidl.c:65:1: internal compiler error: Segmentation fault
net/can/j1939/transport.c:2195:1: internal compiler error: Segmentation fault
net/ceph/armor.c:106:1: internal compiler error: Segmentation fault
net/ceph/auth.c:659:1: internal compiler error: Segmentation fault
net/ceph/auth_none.c:146:1: internal compiler error: Segmentation fault
net/ceph/auth_x.c:1122:1: internal compiler error: Segmentation fault
net/ceph/buffer.c:59:1: internal compiler error: Segmentation fault
net/ceph/cls_lock_client.c:431:1: internal compiler error: Segmentation fault
net/ceph/crush/crush.c:142:1: internal compiler error: Segmentation fault
net/ceph/crush/mapper.c:1099:1: internal compiler error: Segmentation fault
net/ceph/decode.c:193:1: internal compiler error: Segmentation fault
net/ceph/messenger_v1.c:1548:1: internal compiler error: Segmentation fault
net/ceph/messenger_v2.c:3581:1: internal compiler error: Segmentation fault
net/ceph/mon_client.c:1586:1: internal compiler error: Segmentation fault
net/ceph/msgpool.c:94:1: internal compiler error: Segmentation fault
net/ceph/osdmap.c:3090:1: internal compiler error: Segmentation fault
net/ceph/pagelist.c:171:1: internal compiler error: Segmentation fault
net/ceph/pagevec.c:166:1: internal compiler error: Segmentation fault
net/ceph/snapshot.c:63:1: internal compiler error: Segmentation fault
net/ceph/string_table.c:106:1: internal compiler error: Segmentation fault
net/ceph/striper.c:278:1: internal compiler error: Segmentation fault
net/core/datagram.c:838:1: internal compiler error: Segmentation fault
net/core/dev_addr_lists.c:1048:1: internal compiler error: Segmentation fault
net/core/dst.c:355:1: internal compiler error: Segmentation fault
net/core/dst_cache.c:183:1: internal compiler error: Segmentation fault
net/core/flow_offload.c:597:1: internal compiler error: Segmentation fault
net/core/gen_estimator.c:278:1: internal compiler error: Segmentation fault
net/core/gen_stats.c:485:1: internal compiler error: Segmentation fault
net/core/gro.c:770:1: internal compiler error: Segmentation fault
net/core/gro_cells.c:113:1: internal compiler error: Segmentation fault
net/core/link_watch.c:279:1: internal compiler error: Segmentation fault
net/core/lwtunnel.c:424:1: internal compiler error: Segmentation fault
net/core/net-traces.c:63:1: internal compiler error: Segmentation fault
net/core/of_net.c:170:1: internal compiler error: Segmentation fault
net/core/scm.c:367:1: internal compiler error: Segmentation fault
net/core/secure_seq.c:192:1: internal compiler error: Segmentation fault
net/core/sock.c:3928:1: internal compiler error: Segmentation fault
net/core/sock_reuseport.c:649:1: internal compiler error: Segmentation fault
net/core/stream.c:212:1: internal compiler error: Segmentation fault
net/core/timestamping.c:71:1: internal compiler error: Segmentation fault
net/core/tso.c:97:1: internal compiler error: Segmentation fault
net/core/utils.c:486:1: internal compiler error: Segmentation fault
net/dccp/ccids/ccid2.c:792:1: internal compiler error: Segmentation fault
net/dccp/input.c:739:1: internal compiler error: Segmentation fault
net/dccp/output.c:709:1: internal compiler error: Segmentation fault
net/dccp/qpolicy.c:136:1: internal compiler error: Segmentation fault
net/devres.c:95:1: internal compiler error: Segmentation fault
net/dns_resolver/dns_query.c:172:1: internal compiler error: Segmentation fault
net/ethtool/bitset.c:831:1: internal compiler error: Segmentation fault
net/ethtool/cabletest.c:433:1: internal compiler error: Segmentation fault
net/ethtool/channels.c:224:1: internal compiler error: Segmentation fault
net/ethtool/coalesce.c:341:1: internal compiler error: Segmentation fault
net/ethtool/common.c:596:1: internal compiler error: Segmentation fault
net/ethtool/eeprom.c:240:1: internal compiler error: Segmentation fault
net/ethtool/features.c:288:1: internal compiler error: Segmentation fault
net/ethtool/fec.c:310:1: internal compiler error: Segmentation fault
net/ethtool/ioctl.c:3351:1: internal compiler error: Segmentation fault
net/ethtool/linkinfo.c:154:1: internal compiler error: Segmentation fault
net/ethtool/linkmodes.c:363:1: internal compiler error: Segmentation fault
net/ethtool/linkstate.c:182:1: internal compiler error: Segmentation fault
net/ethtool/module.c:180:1: internal compiler error: Segmentation fault
net/ethtool/pause.c:186:1: internal compiler error: Segmentation fault
net/ethtool/privflags.c:201:1: internal compiler error: Segmentation fault
net/ethtool/rings.c:201:1: internal compiler error: Segmentation fault
net/ethtool/stats.c:412:1: internal compiler error: Segmentation fault
net/ethtool/strset.c:480:1: internal compiler error: Segmentation fault
net/ethtool/tunnels.c:298:1: internal compiler error: Segmentation fault
net/ethtool/wol.c:170:1: internal compiler error: Segmentation fault
net/ieee802154/6lowpan/rx.c:323:1: internal compiler error: Segmentation fault
net/ieee802154/6lowpan/tx.c:309:1: internal compiler error: Segmentation fault
net/ieee802154/header_ops.c:318:1: internal compiler error: Segmentation fault
net/ipv4/datagram.c:128:1: internal compiler error: Segmentation fault
net/ipv4/fib_semantics.c:2276:1: internal compiler error: Segmentation fault
net/ipv4/inet_connection_sock.c:1296:1: internal compiler error: Segmentation fault
net/ipv4/inet_timewait_sock.c:302:1: internal compiler error: Segmentation fault
net/ipv4/ip_forward.c:175:1: internal compiler error: Segmentation fault
net/ipv4/ip_input.c:645:1: internal compiler error: Segmentation fault
net/ipv4/ip_options.c:654:1: internal compiler error: Segmentation fault
net/ipv4/ip_sockglue.c:1794:1: internal compiler error: Segmentation fault
net/ipv4/ip_tunnel.c:1280:1: internal compiler error: Segmentation fault
net/ipv4/ipmr_base.c:437:1: internal compiler error: Segmentation fault
net/ipv4/metrics.c:92:1: internal compiler error: Segmentation fault
net/ipv4/netlink.c:33:1: internal compiler error: Segmentation fault
net/ipv4/protocol.c:70:1: internal compiler error: Segmentation fault
net/ipv4/syncookies.c:449:1: internal compiler error: Segmentation fault
net/ipv4/tcp_fastopen.c:591:1: internal compiler error: Segmentation fault
net/ipv4/tcp_input.c:5012:2: warning: Value stored to 'reason' is never read [clang-analyzer-deadcode.DeadStores]
net/ipv4/tcp_input.c:6967:1: internal compiler error: Segmentation fault
net/ipv4/tcp_minisocks.c:853:1: internal compiler error: Segmentation fault
net/ipv4/tcp_rate.c:204:1: internal compiler error: Segmentation fault
net/ipv4/tcp_recovery.c:240:1: internal compiler error: Segmentation fault
net/ipv4/tcp_timer.c:798:1: internal compiler error: Segmentation fault
net/ipv4/tcp_ulp.c:161:1: internal compiler error: Segmentation fault
net/ipv4/udp_tunnel_core.c:205:1: internal compiler error: Segmentation fault
net/ipv4/xfrm4_input.c:172:1: internal compiler error: Segmentation fault
net/ipv6/addrconf_core.c:273:1: internal compiler error: Segmentation fault
net/ipv6/datagram.c:1066:1: internal compiler error: Segmentation fault
net/ipv6/exthdrs_core.c:280:1: internal compiler error: Segmentation fault
net/ipv6/inet6_connection_sock.c:154:1: internal compiler error: Segmentation fault
net/ipv6/inet6_hashtables.c:344:1: internal compiler error: Segmentation fault
net/ipv6/ip6_checksum.c:137:1: internal compiler error: Segmentation fault
net/ipv6/ip6_input.c:573:1: internal compiler error: Segmentation fault
net/ipv6/ip6_output.c:2004:1: internal compiler error: Segmentation fault
net/ipv6/ip6_udp_tunnel.c:114:1: internal compiler error: Segmentation fault
net/ipv6/ipv6_sockglue.c:1509:1: internal compiler error: Segmentation fault
net/ipv6/mcast_snoop.c:190:1: internal compiler error: Segmentation fault
net/ipv6/output_core.c:165:1: internal compiler error: Segmentation fault
net/ipv6/protocol.c:70:1: internal compiler error: Segmentation fault
net/ipv6/rpl.c:124:1: internal compiler error: Segmentation fault
net/ipv6/syncookies.c:264:1: internal compiler error: Segmentation fault
net/ipv6/udp_offload.c:206:1: internal compiler error: Segmentation fault
net/ipv6/xfrm6_input.c:255:1: internal compiler error: Segmentation fault
net/ipv6/xfrm6_output.c:96:1: internal compiler error: Segmentation fault
net/l3mdev/l3mdev.c:310:1: internal compiler error: Segmentation fault
net/llc/llc_input.c:227:1: internal compiler error: Segmentation fault
net/llc/llc_output.c:74:1: internal compiler error: Segmentation fault
net/mac80211/aead_api.c:113:1: internal compiler error: Segmentation fault
net/mac80211/aes_cmac.c:92:1: internal compiler error: Segmentation fault
net/mac80211/aes_gmac.c:92:1: internal compiler error: Segmentation fault
net/mac80211/agg-rx.c:550:1: internal compiler error: Segmentation fault
net/mac80211/agg-tx.c:1042:1: internal compiler error: Segmentation fault
net/mac80211/airtime.c:711:1: internal compiler error: Segmentation fault
net/mac80211/chan.c:1904:1: internal compiler error: Segmentation fault
net/mac80211/debugfs.c:720:1: internal compiler error: Segmentation fault
net/mac80211/debugfs_key.c:472:1: internal compiler error: Segmentation fault
net/mac80211/debugfs_netdev.c:868:1: internal compiler error: Segmentation fault
net/mac80211/debugfs_sta.c:1078:1: internal compiler error: Segmentation fault
net/mac80211/driver-ops.c:346:1: internal compiler error: Segmentation fault
net/mac80211/ethtool.c:246:1: internal compiler error: Segmentation fault
net/mac80211/fils_aead.c:333:1: internal compiler error: Segmentation fault
net/mac80211/he.c:237:1: internal compiler error: Segmentation fault
net/mac80211/ht.c:569:1: internal compiler error: Segmentation fault
net/mac80211/iface.c:2289:1: internal compiler error: Segmentation fault
net/mac80211/key.c:1358:1: internal compiler error: Segmentation fault
net/mac80211/michael.c:83:1: internal compiler error: Segmentation fault
net/mac80211/ocb.c:245:1: internal compiler error: Segmentation fault
net/mac80211/offchannel.c:992:1: internal compiler error: Segmentation fault
net/mac80211/pm.c:201:1: internal compiler error: Segmentation fault
net/mac80211/rate.c:1010:1: internal compiler error: Segmentation fault
net/mac80211/rx.c:5023:1: internal compiler error: Segmentation fault
net/mac80211/s1g.c:198:1: internal compiler error: Segmentation fault
net/mac80211/scan.c:1448:1: internal compiler error: Segmentation fault
net/mac80211/spectmgmt.c:249:1: internal compiler error: Segmentation fault
net/mac80211/sta_info.c:2605:1: internal compiler error: Segmentation fault
net/mac80211/status.c:1286:1: internal compiler error: Segmentation fault
net/mac80211/tdls.c:2008:1: internal compiler error: Segmentation fault
net/mac80211/tkip.c:323:1: internal compiler error: Segmentation fault
net/mac80211/trace.c:13: internal compiler error: Segmentation fault
net/mac80211/tx.c:5811:1: internal compiler error: Segmentation fault
net/mac80211/util.c:4635:1: internal compiler error: Segmentation fault
net/mac80211/vht.c:697:1: internal compiler error: Segmentation fault
net/mac80211/wep.c:306:1: internal compiler error: Segmentation fault
net/mac80211/wme.c:290:1: internal compiler error: Segmentation fault
net/mac80211/wpa.c:1272:1: internal compiler error: Segmentation fault
net/ncsi/ncsi-aen.c:245:1: internal compiler error: Segmentation fault
net/ncsi/ncsi-cmd.c:406:1: internal compiler error: Segmentation fault
net/ncsi/ncsi-rsp.c:1259:1: internal compiler error: Segmentation fault
net/netlabel/netlabel_addrlist.c:367:1: internal compiler error: Segmentation fault
net/netrom/nr_dev.c:178:1: internal compiler error: Segmentation fault
net/netrom/nr_in.c:301:1: internal compiler error: Segmentation fault
net/netrom/nr_out.c:270:1: internal compiler error: Segmentation fault
net/netrom/nr_route.c:983:1: internal compiler error: Segmentation fault
net/netrom/nr_subr.c:278:1: internal compiler error: Segmentation fault
net/netrom/nr_timer.c:247:1: internal compiler error: Segmentation fault
net/nfc/hci/command.c:344:1: internal compiler error: Segmentation fault
net/nfc/hci/hcp.c:138:1: internal compiler error: Segmentation fault
net/nfc/hci/llc_nop.c:86:1: internal compiler error: Segmentation fault
net/nfc/hci/llc_shdlc.c:818:1: internal compiler error: Segmentation fault
net/openvswitch/actions.c:1623:1: internal compiler error: Segmentation fault
net/openvswitch/dp_notify.c:86:1: internal compiler error: Segmentation fault
net/openvswitch/flow.c:974:1: internal compiler error: Segmentation fault
net/openvswitch/flow_netlink.c:3667:1: internal compiler error: Segmentation fault
net/openvswitch/flow_table.c:1222:1: internal compiler error: Segmentation fault
net/openvswitch/meter.c:765:1: internal compiler error: Segmentation fault
net/openvswitch/openvswitch_trace.c:9: internal compiler error: Segmentation fault
net/openvswitch/vport-internal_dev.c:254:1: internal compiler error: Segmentation fault
net/openvswitch/vport.c:516:1: internal compiler error: Segmentation fault
net/rds/af_rds.c:963:1: internal compiler error: Segmentation fault
net/rds/bind.c:283:1: internal compiler error: Segmentation fault
net/rds/cong.c:428:1: internal compiler error: Segmentation fault
net/rds/connection.c:948:1: internal compiler error: Segmentation fault
net/rds/info.c:242:1: internal compiler error: Segmentation fault
net/rds/message.c:522:1: internal compiler error: Segmentation fault
net/rds/page.c:167:1: internal compiler error: Segmentation fault
net/rds/rdma.c:958:1: internal compiler error: Segmentation fault
net/rds/recv.c:830:1: internal compiler error: Segmentation fault
net/rds/send.c:1515:1: internal compiler error: Segmentation fault
net/rds/threads.c:311:1: internal compiler error: Segmentation fault
net/rds/transport.c:169:1: internal compiler error: Segmentation fault
net/rxrpc/call_accept.c:491:1: internal compiler error: Segmentation fault
net/rxrpc/call_event.c:446:1: internal compiler error: Segmentation fault
net/rxrpc/call_object.c:703:1: internal compiler error: Segmentation fault
net/rxrpc/conn_client.c:1121:1: internal compiler error: Segmentation fault
net/rxrpc/conn_event.c:499:1: internal compiler error: Segmentation fault
net/rxrpc/conn_object.c:486:1: internal compiler error: Segmentation fault
net/rxrpc/conn_service.c:203:1: internal compiler error: Segmentation fault
net/rxrpc/input.c:1468:1: internal compiler error: Segmentation fault
net/rxrpc/insecure.c:102:1: internal compiler error: Segmentation fault
net/rxrpc/key.c:695:1: internal compiler error: Segmentation fault
net/rxrpc/local_event.c:115:1: internal compiler error: Segmentation fault
net/rxrpc/local_object.c:467:1: internal compiler error: Segmentation fault
net/rxrpc/output.c:675:1: internal compiler error: Segmentation fault
net/rxrpc/peer_event.c:417:1: internal compiler error: Segmentation fault
net/rxrpc/peer_object.c:526:1: internal compiler error: Segmentation fault
net/rxrpc/recvmsg.c:818:1: internal compiler error: Segmentation fault
net/rxrpc/rtt.c:195:1: internal compiler error: Segmentation fault
net/rxrpc/sendmsg.c:860:1: internal compiler error: Segmentation fault
net/rxrpc/server_key.c:143:1: internal compiler error: Segmentation fault
net/rxrpc/skbuff.c:96:1: internal compiler error: Segmentation fault
net/rxrpc/utils.c:44:1: internal compiler error: Segmentation fault
net/sched/sch_fifo.c:271:1: internal compiler error: Segmentation fault
net/sched/sch_frag.c:152:1: internal compiler error: Segmentation fault
net/sched/sch_generic.c:1607:1: internal compiler error: Segmentation fault
net/sctp/associola.c:1731:1: internal compiler error: Segmentation fault
net/sctp/auth.c:1079:1: internal compiler error: Segmentation fault
net/sctp/bind_addr.c:569:1: internal compiler error: Segmentation fault
net/sctp/chunk.c:353:1: internal compiler error: Segmentation fault
net/sctp/endpointola.c:417:1: internal compiler error: Segmentation fault
net/sctp/input.c:1347:1: internal compiler error: Segmentation fault
net/sctp/inqueue.c:237:1: internal compiler error: Segmentation fault
net/sctp/ipv6.c:1217:1: internal compiler error: Segmentation fault
net/sctp/output.c:864:1: internal compiler error: Segmentation fault
net/sctp/outqueue.c:1915:1: internal compiler error: Segmentation fault
net/sctp/sm_make_chunk.c:3937:1: internal compiler error: Segmentation fault
net/sctp/sm_sideeffect.c:1818:1: internal compiler error: Segmentation fault
net/sctp/sm_statefuns.c:6677:1: internal compiler error: Segmentation fault
net/sctp/socket.c:9707:1: internal compiler error: Segmentation fault
net/sctp/stream.c:1089:1: internal compiler error: Segmentation fault
net/sctp/stream_interleave.c:1360:1: internal compiler error: Segmentation fault
net/sctp/stream_sched.c:273:1: internal compiler error: Segmentation fault
net/sctp/stream_sched_prio.c:337:1: internal compiler error: Segmentation fault
net/sctp/stream_sched_rr.c:191:1: internal compiler error: Segmentation fault
net/sctp/transport.c:853:1: internal compiler error: Segmentation fault
net/sctp/tsnmap.c:364:1: internal compiler error: Segmentation fault
net/sctp/ulpevent.c:1190:1: internal compiler error: Segmentation fault
net/sctp/ulpqueue.c:1136:1: internal compiler error: Segmentation fault
net/switchdev/switchdev.c:754:1: internal compiler error: Segmentation fault
net/tls/tls_device_fallback.c:480:1: internal compiler error: Segmentation fault
net/tls/tls_sw.c:2599:1: internal compiler error: Segmentation fault
net/tls/trace.c:9: internal compiler error: Segmentation fault
net/unix/scm.c:154:1: internal compiler error: Segmentation fault
net/vmw_vsock/af_vsock_tap.c:110:1: internal compiler error: Segmentation fault
net/vmw_vsock/virtio_transport_common.c:1352:1: internal compiler error: Segmentation fault
net/vmw_vsock/vsock_addr.c:69:1: internal compiler error: Segmentation fault
net/wireless/ap.c:60:1: internal compiler error: Segmentation fault
net/wireless/chan.c:1390:1: internal compiler error: Segmentation fault
net/wireless/debugfs.c:110:1: internal compiler error: Segmentation fault
net/wireless/ethtool.c:29:1: internal compiler error: Segmentation fault
net/wireless/ibss.c:542:1: internal compiler error: Segmentation fault
net/wireless/mesh.c:297:1: internal compiler error: Segmentation fault
net/wireless/mlme.c:1115:1: internal compiler error: Segmentation fault
net/wireless/ocb.c:88:1: internal compiler error: Segmentation fault
net/wireless/of.c:138:1: internal compiler error: Segmentation fault
net/wireless/pmsr.c:663:1: internal compiler error: Segmentation fault
net/wireless/radiotap.c:370:1: internal compiler error: Segmentation fault
net/wireless/scan.c:3223:1: internal compiler error: Segmentation fault
net/wireless/sme.c:1352:1: internal compiler error: Segmentation fault
net/wireless/sysfs.c:176:1: internal compiler error: Segmentation fault
net/wireless/trace.c:6: internal compiler error: Segmentation fault
net/wireless/util.c:2286:1: internal compiler error: Segmentation fault
net/wireless/wext-compat.c:1635:1: internal compiler error: Segmentation fault
net/wireless/wext-sme.c:397:1: internal compiler error: Segmentation fault
net/xdp/xdp_umem.c:260:1: internal compiler error: Segmentation fault
net/xdp/xsk_buff_pool.c:656:1: internal compiler error: Segmentation fault
net/xdp/xsk_queue.c:57:1: internal compiler error: Segmentation fault
net/xdp/xskmap.c:272:1: internal compiler error: Segmentation fault
net/xfrm/xfrm_algo.c:866:1: internal compiler error: Segmentation fault
net/xfrm/xfrm_hash.c:40:1: internal compiler error: Segmentation fault
net/xfrm/xfrm_ipcomp.c:373:1: internal compiler error: Segmentation fault
net/xfrm/xfrm_output.c:909:1: internal compiler error: Segmentation fault
net/xfrm/xfrm_replay.c:791:1: internal compiler error: Segmentation fault
page_alloc.c:(.init.text+0x1f18): undefined reference to `node_data'
pahole: .tmp_vmlinux.btf: No such file or directory
security/apparmor/audit.c:247:1: internal compiler error: Segmentation fault
security/apparmor/capability.c:158:1: internal compiler error: Segmentation fault
security/apparmor/domain.c:1460:1: internal compiler error: Segmentation fault
security/apparmor/file.c:711:1: internal compiler error: Segmentation fault
security/apparmor/ipc.c:218:1: internal compiler error: Segmentation fault
security/apparmor/label.c:2160:1: internal compiler error: Segmentation fault
security/apparmor/lib.c:525:1: internal compiler error: Segmentation fault
security/apparmor/match.c:792:1: internal compiler error: Segmentation fault
security/apparmor/mount.c:739:1: internal compiler error: Segmentation fault
security/apparmor/net.c:255:1: internal compiler error: Segmentation fault
security/apparmor/policy.c:1203:1: internal compiler error: Segmentation fault
security/apparmor/policy_unpack.c:1238: internal compiler error: Segmentation fault
security/apparmor/procattr.c:136:1: internal compiler error: Segmentation fault
security/apparmor/resource.c:187:1: internal compiler error: Segmentation fault
security/apparmor/secid.c:161:1: internal compiler error: Segmentation fault
security/apparmor/task.c:179:1: internal compiler error: Segmentation fault
security/integrity/digsig_asymmetric.c:157:1: internal compiler error: Segmentation fault
security/keys/request_key.c:805:1: internal compiler error: Segmentation fault
security/smack/smack_access.c:699:1: internal compiler error: Segmentation fault
sound/core/control.c:2307:1: internal compiler error: Segmentation fault
sound/core/ctljack.c:84:1: internal compiler error: Segmentation fault
sound/core/device.c:260:1: internal compiler error: Segmentation fault
sound/core/init.c:1141:1: internal compiler error: Segmentation fault
sound/core/jack.c:680:1: internal compiler error: Segmentation fault
sound/core/memalloc.c:750:1: internal compiler error: Segmentation fault
sound/core/pcm_dmaengine.c:461:1: internal compiler error: Segmentation fault
sound/core/pcm_lib.c:2529:1: internal compiler error: Segmentation fault
sound/core/pcm_memory.c:527:1: internal compiler error: Segmentation fault
sound/core/pcm_misc.c:616:1: internal compiler error: Segmentation fault
sound/core/pcm_native.c:4082:1: internal compiler error: Segmentation fault
sound/core/seq/seq_fifo.c:283:1: internal compiler error: Segmentation fault
sound/core/seq/seq_lock.c:26:1: internal compiler error: Segmentation fault
sound/core/seq/seq_memory.c:504:1: internal compiler error: Segmentation fault
sound/core/seq/seq_midi_event.c:459:1: internal compiler error: Segmentation fault
sound/core/seq/seq_ports.c:711:1: internal compiler error: Segmentation fault
sound/core/seq/seq_prioq.c:434:1: internal compiler error: Segmentation fault
sound/core/seq/seq_queue.c:726:1: internal compiler error: Segmentation fault
sound/core/seq/seq_timer.c:471:1: internal compiler error: Segmentation fault
sound/core/sound_oss.c:186:1: internal compiler error: Segmentation fault
sound/soc/bcm/bcm63xx-pcm-whistler.c:414:1: internal compiler error: Segmentation fault
sound/soc/codecs/rl6231.c:253:1: internal compiler error: Segmentation fault
sound/soc/codecs/rt5682.c:3153:1: internal compiler error: Segmentation fault
sound/soc/codecs/rt700.c:1244:1: internal compiler error: Segmentation fault
sound/soc/codecs/rt711-sdca.c:1591:1: internal compiler error: Segmentation fault
sound/soc/codecs/rt711.c:1343:1: internal compiler error: Segmentation fault
sound/soc/codecs/rt715-sdca.c:1078:1: internal compiler error: Segmentation fault
sound/soc/codecs/rt715.c:1098:1: internal compiler error: Segmentation fault
sound/soc/codecs/wcd-clsh-v2.c:903:1: internal compiler error: Segmentation fault
sound/soc/fsl/fsl_ssi_dbg.c:140:1: internal compiler error: Segmentation fault
sound/soc/generic/simple-card-utils.c:766:1: internal compiler error: Segmentation fault
sound/soc/soc-card.c:225:1: internal compiler error: Segmentation fault
sound/soc/soc-component.c:1244:1: internal compiler error: Segmentation fault
sound/soc/soc-dai.c:840:1: internal compiler error: Segmentation fault
sound/soc/soc-dapm.c:4862:1: internal compiler error: Segmentation fault
sound/soc/soc-generic-dmaengine-pcm.c:497:1: internal compiler error: Segmentation fault
sound/soc/soc-jack.c:452:1: internal compiler error: Segmentation fault
sound/soc/soc-ops.c:984:1: internal compiler error: Segmentation fault
sound/soc/soc-pcm.c:3031:1: internal compiler error: Segmentation fault
vpu_malone.c:(.text+0x205c): undefined reference to `__moddi3'
vpu_windsor.c:(.text+0x49c): undefined reference to `__moddi3'
{standard input}: Error: .size expression for xpcs_validate does not evaluate to a constant
{standard input}:1989: Error: unknown pseudo-op: `.sec'

Error/Warning ids grouped by kconfigs:

gcc_recent_errors
|-- alpha-allmodconfig
|   |-- arch-alpha-include-asm-string.h:warning:__builtin_memcpy-forming-offset-is-out-of-the-bounds-of-object-tag_buf-with-type-unsigned-char
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-iio-frequency-admv1014.c:sparse:sparse:dubious:x-y
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- alpha-allyesconfig
|   |-- arch-alpha-include-asm-string.h:warning:__builtin_memcpy-forming-offset-is-out-of-the-bounds-of-object-tag_buf-with-type-unsigned-char
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-iio-frequency-admv1014.c:sparse:sparse:dubious:x-y
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- alpha-randconfig-p001-20220318
|   |-- arch-alpha-include-asm-string.h:warning:__builtin_memcpy-forming-offset-is-out-of-the-bounds-of-object-tag_buf-with-type-unsigned-char
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- alpha-randconfig-r022-20220317
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- alpha-randconfig-r032-20220318
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- alpha-randconfig-r036-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- arc-allmodconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- arc-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- arc-defconfig
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- arc-randconfig-r005-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|-- arc-randconfig-r014-20220318
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- arc-randconfig-r015-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|-- arc-randconfig-r043-20220317
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- arc-randconfig-r043-20220318
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|   `-- pahole:.tmp_vmlinux.btf:No-such-file-or-directory
|-- arm-allmodconfig
|   |-- drivers-bus-imx-weim.c:sparse:sparse:symbol-weim_of_notifier-was-not-declared.-Should-it-be-static
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:left-side-has-type-unsigned-int
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:right-side-has-type-restricted-__be32
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:sparse:incorrect-type-in-assignment-(different-base-types)-expected-unsigned-int-usertype-linkFailureCnt-got-restricted-__be32-usertype
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:sparse:invalid-assignment:
|   |-- drivers-soc-rockchip-dtpm.c:sparse:sparse:obsolete-array-initializer-use-C99-syntax
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   `-- kernel-sched-sched.h:fatal-error:asm-paravirt_api_clock.h:No-such-file-or-directory
|-- arm-allyesconfig
|   |-- drivers-bus-imx-weim.c:sparse:sparse:symbol-weim_of_notifier-was-not-declared.-Should-it-be-static
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:left-side-has-type-unsigned-int
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:right-side-has-type-restricted-__be32
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:sparse:incorrect-type-in-assignment-(different-base-types)-expected-unsigned-int-usertype-linkFailureCnt-got-restricted-__be32-usertype
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:sparse:invalid-assignment:
|   |-- drivers-soc-rockchip-dtpm.c:sparse:sparse:obsolete-array-initializer-use-C99-syntax
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   `-- kernel-sched-sched.h:fatal-error:asm-paravirt_api_clock.h:No-such-file-or-directory
|-- arm-defconfig
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- arm-randconfig-c002-20220317
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   `-- kernel-sched-sched.h:fatal-error:asm-paravirt_api_clock.h:No-such-file-or-directory
|-- arm-randconfig-c002-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- arm-randconfig-r006-20220317
|   `-- kernel-sched-sched.h:fatal-error:asm-paravirt_api_clock.h:No-such-file-or-directory
|-- arm-randconfig-r012-20220318
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   `-- kernel-sched-sched.h:fatal-error:asm-paravirt_api_clock.h:No-such-file-or-directory
|-- arm64-allmodconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- arm64-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- arm64-defconfig
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- arm64-randconfig-c023-20220318
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- arm64-randconfig-r011-20220317
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- csky-allmodconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- csky-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- csky-defconfig
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- csky-randconfig-r026-20220318
|   |-- drivers-media-platform-samsung-exynos4-is-fimc-isp-video.h:warning:no-previous-prototype-for-fimc_isp_video_device_unregister
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- h8300-allmodconfig
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-media-platform-st-stm32-dma2d-dma2d-hw.c:internal-compiler-error:in-extract_insn-at-recog.c
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-cacheflush.h:warning:struct-folio-declared-inside-parameter-list-will-not-be-visible-outside-of-this-definition-or-declaration
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- h8300-allyesconfig
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-media-platform-st-stm32-dma2d-dma2d-hw.c:internal-compiler-error:in-extract_insn-at-recog.c
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-cacheflush.h:warning:struct-folio-declared-inside-parameter-list-will-not-be-visible-outside-of-this-definition-or-declaration
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- h8300-randconfig-c024-20220317
|   `-- drivers-media-platform-st-stm32-dma2d-dma2d-hw.c:internal-compiler-error:in-extract_insn-at-recog.c
|-- i386-allnoconfig
|   `-- Documentation-driver-api-nvdimm-nvdimm.rst:(SEVERE-)-Title-level-inconsistent:
|-- i386-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- i386-debian-10.3
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- i386-debian-10.3-kselftests
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- i386-defconfig
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- i386-randconfig-a001
|   `-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|-- i386-randconfig-a003
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- i386-randconfig-a005
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- i386-randconfig-a012
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- i386-randconfig-a014
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- i386-randconfig-a016
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- i386-randconfig-c001
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- i386-randconfig-c021
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   `-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- i386-randconfig-m021
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- i386-randconfig-s001
|   |-- drivers-gpu-drm-gma500-intel_bios.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-const-p-got-unsigned-char-noderef-usertype-__iomem
|   |-- drivers-gpu-drm-gma500-opregion.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-const-p-got-void-noderef-__iomem-assigned-base
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- i386-randconfig-s002
|   |-- drivers-gpu-drm-gma500-intel_bios.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-const-p-got-unsigned-char-noderef-usertype-__iomem
|   |-- drivers-gpu-drm-gma500-opregion.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-const-p-got-void-noderef-__iomem-assigned-base
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- ia64-allmodconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- ia64-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   `-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_migrate_context
|-- ia64-defconfig
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- ia64-randconfig-r034-20220317
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|-- m68k-allmodconfig
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   `-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- m68k-allyesconfig
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   `-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- m68k-bvme6000_defconfig
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   `-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- m68k-defconfig
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   `-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- m68k-randconfig-c004-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   `-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- m68k-randconfig-r003-20220317
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   `-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- m68k-randconfig-r013-20220318
|   |-- arch-m68k-kernel-machine_kexec.c:undefined-reference-to-m68k_mmutype
|   `-- m68k-linux-ld:arch-m68k-kernel-machine_kexec.c:undefined-reference-to-m68k_cputype
|-- m68k-randconfig-r026-20220317
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   `-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- m68k-randconfig-r035-20220317
|   |-- arch-m68k-kernel-machine_kexec.c:undefined-reference-to-m68k_mmutype
|   |-- arch-m68k-kernel-time.c:undefined-reference-to-mach_get_rtc_pll
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- m68k-linux-ld:arch-m68k-kernel-machine_kexec.c:undefined-reference-to-m68k_cputype
|   `-- m68k-linux-ld:arch-m68k-kernel-time.c:undefined-reference-to-mach_set_rtc_pll
|-- m68k-randconfig-s032-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   `-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- mips-allmodconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- mips-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- mips-randconfig-c003-20220318
|   `-- include-linux-fortify-string.h:warning:__builtin_memcpy-offset-is-out-of-the-bounds
|-- mips-randconfig-c023-20220317
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- mips-randconfig-s032-20220317
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- include-linux-fortify-string.h:warning:__builtin_memcpy-offset-is-out-of-the-bounds
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|   |-- mips64-linux-ld:page_alloc.c:(.init.text):undefined-reference-to-node_data
|   `-- page_alloc.c:(.init.text):undefined-reference-to-node_data
|-- nds32-allmodconfig
|   |-- Makefile:arch-nds32-Makefile:No-such-file-or-directory
|   |-- arch-Kconfig:can-t-open-file-arch-nds32-Kconfig
|   `-- make:No-rule-to-make-target-arch-nds32-Makefile-.
|-- nds32-allnoconfig
|   |-- Makefile:arch-nds32-Makefile:No-such-file-or-directory
|   |-- arch-Kconfig:can-t-open-file-arch-nds32-Kconfig
|   `-- make:No-rule-to-make-target-arch-nds32-Makefile-.
|-- nds32-allyesconfig
|   |-- Makefile:arch-nds32-Makefile:No-such-file-or-directory
|   |-- arch-Kconfig:can-t-open-file-arch-nds32-Kconfig
|   `-- make:No-rule-to-make-target-arch-nds32-Makefile-.
|-- nds32-buildonly-randconfig-r001-20220317
|   |-- Makefile:arch-nds32-Makefile:No-such-file-or-directory
|   |-- arch-Kconfig:can-t-open-file-arch-nds32-Kconfig
|   `-- make:No-rule-to-make-target-arch-nds32-Makefile-.
|-- nds32-defconfig
|   |-- Makefile:arch-nds32-Makefile:No-such-file-or-directory
|   `-- make:No-rule-to-make-target-arch-nds32-Makefile-.
|-- nds32-randconfig-c003-20220317
|   |-- Makefile:arch-nds32-Makefile:No-such-file-or-directory
|   |-- arch-Kconfig:can-t-open-file-arch-nds32-Kconfig
|   `-- make:No-rule-to-make-target-arch-nds32-Makefile-.
|-- nds32-randconfig-r001-20220318
|   |-- Makefile:arch-nds32-Makefile:No-such-file-or-directory
|   |-- arch-Kconfig:can-t-open-file-arch-nds32-Kconfig
|   `-- make:No-rule-to-make-target-arch-nds32-Makefile-.
|-- nios2-allmodconfig
|   |-- arch-nios2-kernel-misaligned.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-noderef-__user-to-got-unsigned-char-usertype-__pu_ptr
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- nios2-allyesconfig
|   |-- arch-nios2-kernel-misaligned.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-noderef-__user-to-got-unsigned-char-usertype-__pu_ptr
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- nios2-buildonly-randconfig-r002-20220317
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- nios2-defconfig
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- nios2-randconfig-r001-20220317
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- nios2-randconfig-r031-20220319
|   |-- ERROR:__v4l2_async_nf_add_fwnode_remote-drivers-media-platform-nxp-imx-mipi-csis.ko-undefined
|   |-- ERROR:v4l2_async_nf_cleanup-drivers-media-platform-nxp-imx-mipi-csis.ko-undefined
|   |-- ERROR:v4l2_async_nf_unregister-drivers-media-platform-nxp-imx-mipi-csis.ko-undefined
|   |-- ERROR:v4l2_async_register_subdev-drivers-media-platform-nxp-imx-mipi-csis.ko-undefined
|   |-- ERROR:v4l2_async_subdev_nf_register-drivers-media-platform-nxp-imx-mipi-csis.ko-undefined
|   |-- ERROR:v4l2_async_unregister_subdev-drivers-media-platform-nxp-imx-mipi-csis.ko-undefined
|   |-- ERROR:v4l2_get_link_freq-drivers-media-platform-nxp-imx-mipi-csis.ko-undefined
|   |-- ERROR:v4l2_subdev_call_wrappers-drivers-media-platform-nxp-imx-mipi-csis.ko-undefined
|   |-- ERROR:v4l2_subdev_get_fwnode_pad_1_to_1-drivers-media-platform-nxp-imx-mipi-csis.ko-undefined
|   `-- ERROR:v4l2_subdev_link_validate-drivers-media-platform-nxp-imx-mipi-csis.ko-undefined
|-- openrisc-randconfig-m031-20220317
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- openrisc-randconfig-m031-20220318
|   |-- FAILED:load-BTF-from-vmlinux:No-such-file-or-directory
|   |-- drivers-mmc-host-litex_mmc.c-litex_mmc_request()-error:we-previously-assumed-data-could-be-null-(see-line-)
|   |-- drivers-power-supply-ip5xxx_power.c-ip5xxx_battery_get_property()-error:uninitialized-symbol-raw-.
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- openrisc-randconfig-p002-20220317
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- openrisc-randconfig-r011-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- parisc-allmodconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- parisc-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- parisc-defconfig
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- parisc64-defconfig
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- powerpc-allmodconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:left-side-has-type-unsigned-int
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:right-side-has-type-restricted-__be32
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:sparse:incorrect-type-in-assignment-(different-base-types)-expected-unsigned-int-usertype-linkFailureCnt-got-restricted-__be32-usertype
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:sparse:invalid-assignment:
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- powerpc-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:left-side-has-type-unsigned-int
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:right-side-has-type-restricted-__be32
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:sparse:incorrect-type-in-assignment-(different-base-types)-expected-unsigned-int-usertype-linkFailureCnt-got-restricted-__be32-usertype
|   |-- drivers-scsi-lpfc-lpfc_els.c:sparse:sparse:invalid-assignment:
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- powerpc-buildonly-randconfig-r006-20220317
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|-- powerpc-holly_defconfig
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- powerpc-randconfig-r024-20220317
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- powerpc-randconfig-r035-20220318
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- powerpc64-buildonly-randconfig-r001-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- powerpc64-randconfig-p001-20220317
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|-- riscv-allmodconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- riscv-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- riscv-defconfig
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- riscv-nommu_k210_defconfig
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|-- riscv-nommu_virt_defconfig
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|-- riscv-randconfig-c003-20220313
|   |-- arch-riscv-kernel-cacheinfo.c:internal-compiler-error:Segmentation-fault
|   |-- arch-riscv-kernel-crash_dump.c:internal-compiler-error:Segmentation-fault
|   |-- arch-riscv-kernel-patch.c:internal-compiler-error:Segmentation-fault
|   |-- arch-riscv-kernel-signal.c:internal-compiler-error:Segmentation-fault
|   |-- arch-riscv-mm-extable.c:internal-compiler-error:Segmentation-fault
|   |-- arch-riscv-mm-physaddr.c:internal-compiler-error:Segmentation-fault
|   |-- block-blk-mq-rdma.c:internal-compiler-error:Segmentation-fault
|   |-- block-blk-zoned.c:internal-compiler-error:Segmentation-fault
|   |-- block-sed-opal.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-acompress.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-aead.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-ahash.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-akcipher.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-api.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-asymmetric_keys-public_key.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-dh.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-ecc.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-geniv.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-gf128mul.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-kpp.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-rng.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-scompress.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-shash.c:internal-compiler-error:Segmentation-fault
|   |-- crypto-skcipher.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-base-map.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-base-power-domain_governor.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-base-power-sysfs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-base-power-wakeirq.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-base-regmap-regcache-flat.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-base-regmap-regcache-rbtree.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-base-regmap-regcache.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-base-regmap-regmap-debugfs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-base-regmap-regmap-mmio.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-base-regmap-regmap-sdw-mbq.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-base-regmap-regmap-slimbus.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-base-syscore.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-char-ipmi-ipmi_bt_sm.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-char-ipmi-ipmi_kcs_sm.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-char-ipmi-ipmi_plat_data.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-char-ipmi-ipmi_si_hotmod.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-char-ipmi-ipmi_si_mem_io.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-char-ipmi-ipmi_si_port_io.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-char-ipmi-ipmi_smic_sm.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-char-tpm-eventlog-efi.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-clk-clk-composite.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-clk-clk-fractional-divider.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-comedi-comedi_buf.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-comedi-drivers.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-comedi-range.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-crypto-ccree-cc_aead.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-crypto-ccree-cc_buffer_mgr.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-crypto-ccree-cc_cipher.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-crypto-ccree-cc_fips.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-crypto-ccree-cc_hash.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-crypto-ccree-cc_pm.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-crypto-ccree-cc_request_mgr.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-crypto-ccree-cc_sram_mgr.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-dma-buf-dma-fence-array.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-dma-buf-dma-fence-chain.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-dma-buf-dma-fence.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-dma-buf-dma-heap.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-firmware-efi-vars.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-gpio-gpiolib-of.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-hid-hid-cmedia.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-hid-hid-debug.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-hid-hid-picolcd_debugfs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-hid-hid-picolcd_fb.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-hid-hid-picolcd_leds.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-hid-hid-roccat-common.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-hid-hid-uclogic-params.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-hid-hid-uclogic-rdesc.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-hid-usbhid-hiddev.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-addr.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-agent.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-cache.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-cm_trace.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-counters.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-cq.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-ib_core_uverbs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-iwpm_msg.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-iwpm_util.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-lag.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-mad_rmpp.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-mr_pool.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-multicast.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-netlink.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-packer.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-rdma_core.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-restrack.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-rw.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-sa_query.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-smi.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-sysfs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-trace.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-ud_header.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-umem.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-umem_dmabuf.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-umem_odp.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_cmd.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_ioctl.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_marshall.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_std_types.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_std_types_async_fd.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_std_types_counters.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_std_types_cq.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_std_types_device.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_std_types_dm.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_std_types_flow_action.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_std_types_mr.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_std_types_qp.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_std_types_srq.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_std_types_wq.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-uverbs_uapi.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-core-verbs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-sw-siw-siw_cm.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-sw-siw-siw_cq.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-sw-siw-siw_mem.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-sw-siw-siw_qp.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-sw-siw-siw_qp_tx.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-infiniband-sw-siw-siw_verbs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-input-matrix-keymap.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-input-misc-adxl34x.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-input-misc-cma3000_d.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-input-rmi4-rmi_2d_sensor.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-input-rmi4-rmi_f30.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-input-rmi4-rmi_f54.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-input-rmi4-rmi_f55.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-input-touchscreen.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-iommu-of_iommu.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-leds-leds-ti-lmu-common.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-common-videobuf2-frame_vector.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-common-videobuf2-vb2-trace.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-common-videobuf2-videobuf2-dma-contig.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-common-videobuf2-videobuf2-dma-sg.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-common-videobuf2-videobuf2-memops.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-common-videobuf2-videobuf2-vmalloc.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-platform-xilinx-xilinx-dma.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-radio-tea575x.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-cpia2-cpia2_core.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-cpia2-cpia2_usb.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-gspca-autogain_functions.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-gspca-stv06xx-stv06xx_pb0100.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-gspca-stv06xx-stv06xx_st6422.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-pwc-pwc-ctrl.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-pwc-pwc-dec23.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-pwc-pwc-uncompress.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-pwc-pwc-v4l.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-stkwebcam-stk-sensor.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-uvc-uvc_ctrl.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-uvc-uvc_debugfs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-uvc-uvc_entity.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-uvc-uvc_isight.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-uvc-uvc_metadata.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-uvc-uvc_queue.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-uvc-uvc_status.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-uvc-uvc_v4l2.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-media-usb-uvc-uvc_video.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mfd-cs47l35-tables.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mfd-madera-core.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mfd-mfd-core.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-misc-eeprom-eeprom_93cx6.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-chips-cfi_cmdset_0020.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-mtdsuper.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-bbt.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-ecc-sw-hamming.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-raw-denali.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-raw-nand_base.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-raw-nand_hynix.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-raw-nand_jedec.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-raw-nand_legacy.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-raw-nand_macronix.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-raw-nand_micron.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-raw-nand_onfi.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-raw-nand_samsung.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-raw-nand_timings.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-mtd-nand-raw-nand_toshiba.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-net-can-dev-length.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-net-can-dev-rx-offload.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-net-can-dev-skb.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-net-phy-mii_timestamper.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-nfc-fdp-fdp.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-nvme-host-zns.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-nvme-target-zns.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-of-kobj.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-parport-daisy.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-parport-ieee1284.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-parport-ieee1284_ops.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-parport-probe.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-pci-of.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-pcmcia-rsrc_mgr.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-phy-phy-core-mipi-dphy.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-rtc-sysfs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-scsi-iscsi_boot_sysfs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-scsi-libiscsi.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-scsi-libiscsi_tcp.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-scsi-libsas-sas_event.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-scsi-libsas-sas_task.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-scsi-scsi_lib_dma.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-scsi-ufs-ufs-sysfs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-slimbus-messaging.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-slimbus-stream.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-ssb-driver_chipcommon.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-ssb-scan.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_auth.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_configfs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_datain_values.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_device.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_erl0.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_erl1.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_erl2.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_login.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_nego.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_nodeattrib.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_parameters.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_seq_pdu_list.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_stat.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_tmr.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_tpg.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_transport.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-target-iscsi-iscsi_target_util.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-tty-tty_audit.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-cdns3-drd.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-cdns3-host.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-chipidea-host.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-core-config.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-core-devices.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-core-endpoint.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-core-generic.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-core-port.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-core-quirks.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-core-sysfs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-dwc3-drd.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-dwc3-ep0.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-dwc3-gadget.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-composite.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-config.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-epautoconf.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-function-f_tcm.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-function-storage_common.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-function-u_uac1_legacy.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-function-uvc_configfs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-function-uvc_queue.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-function-uvc_v4l2.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-function-uvc_video.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-functions.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-u_f.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-udc-snps_udc_core.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-udc-trace.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-gadget-usbstring.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-host-xhci-dbg.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-isp1760-isp1760-udc.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-mon-mon_stat.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-musb-musb_gadget.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-musb-musb_gadget_ep0.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-storage-initializers.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-typec-bus.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-typec-tcpm-tcpm.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-usbip-stub_rx.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-usbip-stub_tx.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-usbip-usbip_event.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-vfio-mdev-vfio_mdev.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-video-fbdev-core-fb_defio.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-video-fbdev-core-fbcmap.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-video-fbdev-core-fbsysfs.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-virtio-virtio_ring.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-w1-w1_family.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-w1-w1_netlink.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-watchdog-watchdog_pretimeout.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-addr_list.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-callback.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-cmservice.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-dir_edit.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-dir_silly.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-dynroot.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-file.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-flock.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-fs_operation.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-fs_probe.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-mntpt.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-server_list.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-vl_alias.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-vl_list.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-vl_probe.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-vl_rotate.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-vlclient.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-volume.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-write.c:internal-compiler-error:Segmentation-fault
|   |-- fs-afs-xattr.c:internal-compiler-error:Segmentation-fault
|   |-- fs-autofs-expire.c:internal-compiler-error:Segmentation-fault
|   |-- fs-autofs-inode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-autofs-root.c:internal-compiler-error:Segmentation-fault
|   |-- fs-autofs-symlink.c:internal-compiler-error:Segmentation-fault
|   |-- fs-autofs-waitq.c:internal-compiler-error:Segmentation-fault
|   |-- fs-bad_inode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-async-thread.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-block-group.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-block-rsv.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-ctree.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-delalloc-space.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-dev-replace.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-dir-item.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-discard.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-export.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-file-item.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-free-space-cache.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-free-space-tree.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-inode-item.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-ioctl.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-locking.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-lzo.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-orphan.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-print-tree.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-qgroup.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-raid56.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-reflink.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-root-tree.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-struct-funcs.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-subpage.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-transaction.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-tree-defrag.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-tree-log.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-tree-mod-log.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-ulist.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-uuid-tree.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-verity.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-xattr.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-zlib.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-zoned.c:internal-compiler-error:Segmentation-fault
|   |-- fs-btrfs-zstd.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-addr.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-caps.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-ceph_frag.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-debugfs.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-dir.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-export.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-file.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-inode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-io.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-ioctl.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-mdsmap.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-metric.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-quota.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-snap.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ceph-xattr.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-cifs_debug.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-cifs_dfs_ref.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-cifs_spnego.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-cifs_swn.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-cifs_unicode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-cifsacl.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-cifsencrypt.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-cifssmb.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-connect.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-dfs_cache.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-dir.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-file.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-fs_context.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-inode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-ioctl.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-link.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-misc.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-netlink.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-netmisc.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-readdir.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-sess.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-smb1ops.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-smb2file.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-smb2inode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-smb2maperror.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-smb2misc.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-smb2ops.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-smb2pdu.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-smb2transport.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-smbencrypt.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-trace.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-transport.c:internal-compiler-error:Segmentation-fault
|   |-- fs-cifs-unc.c:internal-compiler-error:Segmentation-fault
|   |-- fs-coda-cache.c:internal-compiler-error:Segmentation-fault
|   |-- fs-coda-cnode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-coda-dir.c:internal-compiler-error:Segmentation-fault
|   |-- fs-coda-file.c:internal-compiler-error:Segmentation-fault
|   |-- fs-coda-pioctl.c:internal-compiler-error:Segmentation-fault
|   |-- fs-coda-symlink.c:internal-compiler-error:Segmentation-fault
|   |-- fs-coda-upcall.c:internal-compiler-error:Segmentation-fault
|   |-- fs-configfs-file.c:internal-compiler-error:Segmentation-fault
|   |-- fs-configfs-inode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-configfs-symlink.c:internal-compiler-error:Segmentation-fault
|   |-- fs-crypto-bio.c:internal-compiler-error:Segmentation-fault
|   |-- fs-crypto-fname.c:internal-compiler-error:Segmentation-fault
|   |-- fs-crypto-hkdf.c:internal-compiler-error:Segmentation-fault
|   |-- fs-crypto-hooks.c:internal-compiler-error:Segmentation-fault
|   |-- fs-crypto-keysetup.c:internal-compiler-error:Segmentation-fault
|   |-- fs-crypto-keysetup_v1.c:internal-compiler-error:Segmentation-fault
|   |-- fs-crypto-policy.c:internal-compiler-error:Segmentation-fault
|   |-- fs-d_path.c:internal-compiler-error:Segmentation-fault
|   |-- fs-dlm-dir.c:internal-compiler-error:Segmentation-fault
|   |-- fs-dlm-member.c:internal-compiler-error:Segmentation-fault
|   |-- fs-dlm-midcomms.c:internal-compiler-error:Segmentation-fault
|   |-- fs-dlm-plock.c:internal-compiler-error:Segmentation-fault
|   |-- fs-dlm-rcom.c:internal-compiler-error:Segmentation-fault
|   |-- fs-dlm-recover.c:internal-compiler-error:Segmentation-fault
|   |-- fs-dlm-recoverd.c:internal-compiler-error:Segmentation-fault
|   |-- fs-dlm-requestqueue.c:internal-compiler-error:Segmentation-fault
|   |-- fs-efivarfs-inode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-exportfs-expfs.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ext2-xattr_user.c:internal-compiler-error:Segmentation-fault
|   |-- fs-fhandle.c:internal-compiler-error:Segmentation-fault
|   |-- fs-fs_context.c:internal-compiler-error:Segmentation-fault
|   |-- fs-fs_pin.c:internal-compiler-error:Segmentation-fault
|   |-- fs-fs_struct.c:internal-compiler-error:Segmentation-fault
|   |-- fs-fsopen.c:internal-compiler-error:Segmentation-fault
|   |-- fs-gfs2-lock_dlm.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ioctl.c:internal-compiler-error:Segmentation-fault
|   |-- fs-kernfs-dir.c:internal-compiler-error:Segmentation-fault
|   |-- fs-kernfs-file.c:internal-compiler-error:Segmentation-fault
|   |-- fs-kernfs-inode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-kernfs-symlink.c:internal-compiler-error:Segmentation-fault
|   |-- fs-namei.c:internal-compiler-error:Segmentation-fault
|   |-- fs-nls-nls_base.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-attrib.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-attrlist.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-dir.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-file.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-frecord.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-fslog.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-fsntfs.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-index.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-inode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-lib-decompress_common.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-lib-lzx_decompress.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-lznt.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-namei.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-record.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-run.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-upcase.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ntfs3-xattr.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-acl.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-alloc.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-aops.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-blockcheck.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-buffer_head_io.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-cluster-masklog.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-cluster-netdebug.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-cluster-quorum.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-cluster-tcp.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-dcache.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-dir.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-dlmfs-userdlm.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-dlmglue.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-export.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-extent_map.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-file.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-filecheck.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-heartbeat.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-inode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-ioctl.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-journal.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-localalloc.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-locks.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-mmap.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-move_extents.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-namei.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-quota_global.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-refcounttree.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-reservations.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-resize.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-slot_map.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-suballoc.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-symlink.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-sysfile.c:internal-compiler-error:Segmentation-fault
|   |-- fs-ocfs2-xattr.c:internal-compiler-error:Segmentation-fault
|   |-- fs-omfs-bitmap.c:internal-compiler-error:Segmentation-fault
|   |-- fs-omfs-dir.c:internal-compiler-error:Segmentation-fault
|   |-- fs-omfs-file.c:internal-compiler-error:Segmentation-fault
|   |-- fs-open.c:internal-compiler-error:Segmentation-fault
|   |-- fs-overlayfs-dir.c:internal-compiler-error:Segmentation-fault
|   |-- fs-overlayfs-export.c:internal-compiler-error:Segmentation-fault
|   |-- fs-overlayfs-inode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-overlayfs-namei.c:internal-compiler-error:Segmentation-fault
|   |-- fs-overlayfs-readdir.c:internal-compiler-error:Segmentation-fault
|   |-- fs-overlayfs-util.c:internal-compiler-error:Segmentation-fault
|   |-- fs-pnode.c:internal-compiler-error:Segmentation-fault
|   |-- fs-pstore-pmsg.c:internal-compiler-error:Segmentation-fault
|   |-- fs-quota-quota.c:internal-compiler-error:Segmentation-fault
|   |-- fs-quota-quota_tree.c:internal-compiler-error:Segmentation-fault
|   |-- fs-readdir.c:internal-compiler-error:Segmentation-fault
|   |-- fs-select.c:internal-compiler-error:Segmentation-fault
|   |-- fs-smbfs_common-cifs_md4.c:internal-compiler-error:Segmentation-fault
|   |-- fs-splice.c:internal-compiler-error:Segmentation-fault
|   |-- fs-squashfs-decompressor_multi.c:internal-compiler-error:Segmentation-fault
|   |-- fs-squashfs-zstd_wrapper.c:internal-compiler-error:Segmentation-fault
|   |-- fs-stack.c:internal-compiler-error:Segmentation-fault
|   |-- fs-statfs.c:internal-compiler-error:Segmentation-fault
|   |-- fs-sync.c:internal-compiler-error:Segmentation-fault
|   |-- fs-unicode-utf8-core.c:internal-compiler-error:Segmentation-fault
|   |-- fs-utimes.c:internal-compiler-error:Segmentation-fault
|   |-- fs-xattr.c:internal-compiler-error:Segmentation-fault
|   |-- include-linux-module.h:internal-compiler-error:Segmentation-fault
|   |-- ipc-msgutil.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-acct.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-auditsc.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-bpf-offload.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-bpf-reuseport_array.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-cgroup-freezer.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-dma-direct.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-irq-chip.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-printk-printk_ringbuffer.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-printk-printk_safe.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-range.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-rcu-rcu_segcblist.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-rcu-sync.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-sched-cpuacct.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-sched-cputime.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-sched-deadline.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-sched-membarrier.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-sched-rt.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-sys.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-task_work.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-trace-trace_clock.c:internal-compiler-error:Segmentation-fault
|   |-- kernel-umh.c:internal-compiler-error:Segmentation-fault
|   |-- lib-asn1_decoder.c:internal-compiler-error:Segmentation-fault
|   |-- lib-cmdline.c:internal-compiler-error:Segmentation-fault
|   |-- lib-crc-itu-t.c:internal-compiler-error:Segmentation-fault
|   |-- lib-crc16.c:internal-compiler-error:Segmentation-fault
|   |-- lib-crypto-aes.c:internal-compiler-error:Segmentation-fault
|   |-- lib-crypto-blake2s-generic.c:internal-compiler-error:Segmentation-fault
|   |-- lib-crypto-poly1305-donna32.c:internal-compiler-error:Segmentation-fault
|   |-- lib-crypto-poly1305.c:internal-compiler-error:Segmentation-fault
|   |-- lib-dim-dim.c:internal-compiler-error:Segmentation-fault
|   |-- lib-dim-net_dim.c:internal-compiler-error:Segmentation-fault
|   |-- lib-dim-rdma_dim.c:internal-compiler-error:Segmentation-fault
|   |-- lib-dynamic_queue_limits.c:internal-compiler-error:Segmentation-fault
|   |-- lib-earlycpio.c:internal-compiler-error:Segmentation-fault
|   |-- lib-extable.c:internal-compiler-error:Segmentation-fault
|   |-- lib-fdt.c:internal-compiler-error:Segmentation-fault
|   |-- lib-fdt_ro.c:internal-compiler-error:Segmentation-fault
|   |-- lib-fdt_rw.c:internal-compiler-error:Segmentation-fault
|   |-- lib-fdt_sw.c:internal-compiler-error:Segmentation-fault
|   |-- lib-fdt_wip.c:internal-compiler-error:Segmentation-fault
|   |-- lib-flex_proportions.c:internal-compiler-error:Segmentation-fault
|   |-- lib-interval_tree.c:internal-compiler-error:Segmentation-fault
|   |-- lib-iov_iter.c:internal-compiler-error:Segmentation-fault
|   |-- lib-is_single_threaded.c:internal-compiler-error:Segmentation-fault
|   |-- lib-kunit-assert.c:internal-compiler-error:Segmentation-fault
|   |-- lib-linear_ranges.c:internal-compiler-error:Segmentation-fault
|   |-- lib-logic_pio.c:internal-compiler-error:Segmentation-fault
|   |-- lib-lz4-lz4_compress.c:internal-compiler-error:Segmentation-fault
|   |-- lib-lz4-lz4_decompress.c:internal-compiler-error:Segmentation-fault
|   |-- lib-lzo-lzo1x_compress.c:internal-compiler-error:Segmentation-fault
|   |-- lib-lzo-lzo1x_decompress_safe.c:internal-compiler-error:Segmentation-fault
|   |-- lib-math-rational.c:internal-compiler-error:Segmentation-fault
|   |-- lib-mpi-generic_mpih-mul2.c:internal-compiler-error:Segmentation-fault
|   |-- lib-mpi-generic_mpih-mul3.c:internal-compiler-error:Segmentation-fault
|   |-- lib-mpi-mpi-div.c:internal-compiler-error:Segmentation-fault
|   |-- lib-mpi-mpi-mod.c:internal-compiler-error:Segmentation-fault
|   |-- lib-mpi-mpi-mul.c:internal-compiler-error:Segmentation-fault
|   |-- lib-mpi-mpih-div.c:internal-compiler-error:Segmentation-fault
|   |-- lib-mpi-mpih-mul.c:internal-compiler-error:Segmentation-fault
|   |-- lib-net_utils.c:internal-compiler-error:Segmentation-fault
|   |-- lib-nlattr.c:internal-compiler-error:Segmentation-fault
|   |-- lib-oid_registry.c:internal-compiler-error:Segmentation-fault
|   |-- lib-plist.c:internal-compiler-error:Segmentation-fault
|   |-- lib-raid6-int1.c:internal-compiler-error:Segmentation-fault
|   |-- lib-raid6-int2.c:internal-compiler-error:Segmentation-fault
|   |-- lib-raid6-int4.c:internal-compiler-error:Segmentation-fault
|   |-- lib-raid6-int8.c:internal-compiler-error:Segmentation-fault
|   |-- lib-seq_buf.c:internal-compiler-error:Segmentation-fault
|   |-- lib-syscall.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zlib_deflate-deflate.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zlib_deflate-deftree.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zlib_inflate-inffast.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zlib_inflate-inflate.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-common-entropy_common.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-common-fse_decompress.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-compress-fse_compress.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-compress-hist.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-compress-huf_compress.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-compress-zstd_compress.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-compress-zstd_compress_literals.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-compress-zstd_compress_sequences.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-compress-zstd_compress_superblock.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-compress-zstd_double_fast.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-compress-zstd_fast.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-compress-zstd_lazy.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-compress-zstd_ldm.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-compress-zstd_opt.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-decompress-huf_decompress.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-decompress-zstd_ddict.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-decompress-zstd_decompress.c:internal-compiler-error:Segmentation-fault
|   |-- lib-zstd-decompress-zstd_decompress_block.c:internal-compiler-error:Segmentation-fault
|   |-- mm-folio-compat.c:internal-compiler-error:Segmentation-fault
|   |-- mm-hmm.c:internal-compiler-error:Segmentation-fault
|   |-- mm-interval_tree.c:internal-compiler-error:Segmentation-fault
|   |-- mm-mmu_notifier.c:internal-compiler-error:Segmentation-fault
|   |-- mm-ptdump.c:internal-compiler-error:Segmentation-fault
|   |-- net-6lowpan-iphc.c:internal-compiler-error:Segmentation-fault
|   |-- net-6lowpan-ndisc.c:internal-compiler-error:Segmentation-fault
|   |-- net-6lowpan-nhc.c:internal-compiler-error:Segmentation-fault
|   |-- net-ax25-ax25_addr.c:internal-compiler-error:Segmentation-fault
|   |-- net-ax25-ax25_iface.c:internal-compiler-error:Segmentation-fault
|   |-- net-ax25-ax25_in.c:internal-compiler-error:Segmentation-fault
|   |-- net-ax25-ax25_ip.c:internal-compiler-error:Segmentation-fault
|   |-- net-ax25-ax25_out.c:internal-compiler-error:Segmentation-fault
|   |-- net-ax25-ax25_std_in.c:internal-compiler-error:Segmentation-fault
|   |-- net-ax25-ax25_std_timer.c:internal-compiler-error:Segmentation-fault
|   |-- net-ax25-ax25_subr.c:internal-compiler-error:Segmentation-fault
|   |-- net-ax25-ax25_timer.c:internal-compiler-error:Segmentation-fault
|   |-- net-bridge-br_if.c:internal-compiler-error:Segmentation-fault
|   |-- net-bridge-br_switchdev.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cfcnfg.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cfctrl.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cfdbgl.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cfdgml.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cffrml.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cfmuxl.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cfpkt_skbuff.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cfrfml.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cfserl.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cfsrvl.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cfutill.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cfveil.c:internal-compiler-error:Segmentation-fault
|   |-- net-caif-cfvidl.c:internal-compiler-error:Segmentation-fault
|   |-- net-can-j1939-transport.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-armor.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-auth.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-auth_none.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-auth_x.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-buffer.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-cls_lock_client.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-crush-crush.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-crush-mapper.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-decode.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-messenger_v1.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-messenger_v2.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-mon_client.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-msgpool.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-osdmap.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-pagelist.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-pagevec.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-snapshot.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-string_table.c:internal-compiler-error:Segmentation-fault
|   |-- net-ceph-striper.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-datagram.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-dev_addr_lists.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-dst.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-dst_cache.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-flow_offload.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-gen_estimator.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-gen_stats.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-gro.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-gro_cells.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-link_watch.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-lwtunnel.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-net-traces.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-of_net.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-scm.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-secure_seq.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-sock.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-sock_reuseport.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-stream.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-timestamping.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-tso.c:internal-compiler-error:Segmentation-fault
|   |-- net-core-utils.c:internal-compiler-error:Segmentation-fault
|   |-- net-dccp-ccids-ccid2.c:internal-compiler-error:Segmentation-fault
|   |-- net-dccp-input.c:internal-compiler-error:Segmentation-fault
|   |-- net-dccp-output.c:internal-compiler-error:Segmentation-fault
|   |-- net-dccp-qpolicy.c:internal-compiler-error:Segmentation-fault
|   |-- net-devres.c:internal-compiler-error:Segmentation-fault
|   |-- net-dns_resolver-dns_query.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-bitset.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-cabletest.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-channels.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-coalesce.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-common.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-eeprom.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-features.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-fec.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-ioctl.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-linkinfo.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-linkmodes.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-linkstate.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-module.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-pause.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-privflags.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-rings.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-stats.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-strset.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-tunnels.c:internal-compiler-error:Segmentation-fault
|   |-- net-ethtool-wol.c:internal-compiler-error:Segmentation-fault
|   |-- net-garp.c:internal-compiler-error:Segmentation-fault
|   |-- net-ieee802154-6lowpan-rx.c:internal-compiler-error:Segmentation-fault
|   |-- net-ieee802154-6lowpan-tx.c:internal-compiler-error:Segmentation-fault
|   |-- net-ieee802154-header_ops.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-datagram.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-fib_semantics.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-inet_connection_sock.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-inet_timewait_sock.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-ip_forward.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-ip_input.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-ip_options.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-ip_sockglue.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-ip_tunnel.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-ipmr_base.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-metrics.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-netlink.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-protocol.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-syncookies.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-tcp_fastopen.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-tcp_input.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-tcp_minisocks.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-tcp_rate.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-tcp_recovery.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-tcp_timer.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-tcp_ulp.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-udp_tunnel_core.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv4-xfrm4_input.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-addrconf_core.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-datagram.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-exthdrs_core.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-inet6_connection_sock.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-inet6_hashtables.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-ip6_checksum.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-ip6_input.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-ip6_output.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-ip6_udp_tunnel.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-ipv6_sockglue.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-mcast_snoop.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-output_core.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-protocol.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-rpl.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-syncookies.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-udp_offload.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-xfrm6_input.c:internal-compiler-error:Segmentation-fault
|   |-- net-ipv6-xfrm6_output.c:internal-compiler-error:Segmentation-fault
|   |-- net-l3mdev-l3mdev.c:internal-compiler-error:Segmentation-fault
|   |-- net-llc-llc_input.c:internal-compiler-error:Segmentation-fault
|   |-- net-llc-llc_output.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-aead_api.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-aes_cmac.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-aes_gmac.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-agg-rx.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-agg-tx.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-airtime.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-chan.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-debugfs.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-debugfs_key.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-debugfs_netdev.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-debugfs_sta.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-driver-ops.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-ethtool.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-fils_aead.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-he.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-ht.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-iface.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-key.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-michael.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-ocb.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-offchannel.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-pm.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-rate.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-rx.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-s1g.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-scan.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-spectmgmt.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-sta_info.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-status.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-tdls.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-tkip.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-trace.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-tx.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-util.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-vht.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-wep.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-wme.c:internal-compiler-error:Segmentation-fault
|   |-- net-mac80211-wpa.c:internal-compiler-error:Segmentation-fault
|   |-- net-mrp.c:internal-compiler-error:Segmentation-fault
|   |-- net-ncsi-ncsi-aen.c:internal-compiler-error:Segmentation-fault
|   |-- net-ncsi-ncsi-cmd.c:internal-compiler-error:Segmentation-fault
|   |-- net-ncsi-ncsi-rsp.c:internal-compiler-error:Segmentation-fault
|   |-- net-netlabel-netlabel_addrlist.c:internal-compiler-error:Segmentation-fault
|   |-- net-netrom-nr_dev.c:internal-compiler-error:Segmentation-fault
|   |-- net-netrom-nr_in.c:internal-compiler-error:Segmentation-fault
|   |-- net-netrom-nr_out.c:internal-compiler-error:Segmentation-fault
|   |-- net-netrom-nr_route.c:internal-compiler-error:Segmentation-fault
|   |-- net-netrom-nr_subr.c:internal-compiler-error:Segmentation-fault
|   |-- net-netrom-nr_timer.c:internal-compiler-error:Segmentation-fault
|   |-- net-nfc-hci-command.c:internal-compiler-error:Segmentation-fault
|   |-- net-nfc-hci-hcp.c:internal-compiler-error:Segmentation-fault
|   |-- net-nfc-hci-llc_nop.c:internal-compiler-error:Segmentation-fault
|   |-- net-nfc-hci-llc_shdlc.c:internal-compiler-error:Segmentation-fault
|   |-- net-openvswitch-actions.c:internal-compiler-error:Segmentation-fault
|   |-- net-openvswitch-dp_notify.c:internal-compiler-error:Segmentation-fault
|   |-- net-openvswitch-flow.c:internal-compiler-error:Segmentation-fault
|   |-- net-openvswitch-flow_netlink.c:internal-compiler-error:Segmentation-fault
|   |-- net-openvswitch-flow_table.c:internal-compiler-error:Segmentation-fault
|   |-- net-openvswitch-meter.c:internal-compiler-error:Segmentation-fault
|   |-- net-openvswitch-openvswitch_trace.c:internal-compiler-error:Segmentation-fault
|   |-- net-openvswitch-vport-internal_dev.c:internal-compiler-error:Segmentation-fault
|   |-- net-openvswitch-vport.c:internal-compiler-error:Segmentation-fault
|   |-- net-rds-af_rds.c:internal-compiler-error:Segmentation-fault
|   |-- net-rds-bind.c:internal-compiler-error:Segmentation-fault
|   |-- net-rds-cong.c:internal-compiler-error:Segmentation-fault
|   |-- net-rds-connection.c:internal-compiler-error:Segmentation-fault
|   |-- net-rds-info.c:internal-compiler-error:Segmentation-fault
|   |-- net-rds-message.c:internal-compiler-error:Segmentation-fault
|   |-- net-rds-page.c:internal-compiler-error:Segmentation-fault
|   |-- net-rds-rdma.c:internal-compiler-error:Segmentation-fault
|   |-- net-rds-recv.c:internal-compiler-error:Segmentation-fault
|   |-- net-rds-send.c:internal-compiler-error:Segmentation-fault
|   |-- net-rds-threads.c:internal-compiler-error:Segmentation-fault
|   |-- net-rds-transport.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-call_accept.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-call_event.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-call_object.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-conn_client.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-conn_event.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-conn_object.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-conn_service.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-input.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-insecure.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-key.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-local_event.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-local_object.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-output.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-peer_event.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-peer_object.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-recvmsg.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-rtt.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-sendmsg.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-server_key.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-skbuff.c:internal-compiler-error:Segmentation-fault
|   |-- net-rxrpc-utils.c:internal-compiler-error:Segmentation-fault
|   |-- net-sched-sch_fifo.c:internal-compiler-error:Segmentation-fault
|   |-- net-sched-sch_frag.c:internal-compiler-error:Segmentation-fault
|   |-- net-sched-sch_generic.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-associola.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-auth.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-bind_addr.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-chunk.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-endpointola.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-input.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-inqueue.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-ipv6.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-output.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-outqueue.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-sm_make_chunk.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-sm_sideeffect.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-sm_statefuns.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-socket.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-stream.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-stream_interleave.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-stream_sched.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-stream_sched_prio.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-stream_sched_rr.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-transport.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-tsnmap.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-ulpevent.c:internal-compiler-error:Segmentation-fault
|   |-- net-sctp-ulpqueue.c:internal-compiler-error:Segmentation-fault
|   |-- net-switchdev-switchdev.c:internal-compiler-error:Segmentation-fault
|   |-- net-tls-tls_device_fallback.c:internal-compiler-error:Segmentation-fault
|   |-- net-tls-tls_sw.c:internal-compiler-error:Segmentation-fault
|   |-- net-tls-trace.c:internal-compiler-error:Segmentation-fault
|   |-- net-unix-scm.c:internal-compiler-error:Segmentation-fault
|   |-- net-vmw_vsock-af_vsock_tap.c:internal-compiler-error:Segmentation-fault
|   |-- net-vmw_vsock-virtio_transport_common.c:internal-compiler-error:Segmentation-fault
|   |-- net-vmw_vsock-vsock_addr.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-ap.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-chan.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-debugfs.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-ethtool.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-ibss.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-mesh.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-mlme.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-ocb.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-of.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-pmsr.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-radiotap.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-scan.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-sme.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-sysfs.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-trace.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-util.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-wext-compat.c:internal-compiler-error:Segmentation-fault
|   |-- net-wireless-wext-sme.c:internal-compiler-error:Segmentation-fault
|   |-- net-xdp-xdp_umem.c:internal-compiler-error:Segmentation-fault
|   |-- net-xdp-xsk_buff_pool.c:internal-compiler-error:Segmentation-fault
|   |-- net-xdp-xsk_queue.c:internal-compiler-error:Segmentation-fault
|   |-- net-xdp-xskmap.c:internal-compiler-error:Segmentation-fault
|   |-- net-xfrm-xfrm_algo.c:internal-compiler-error:Segmentation-fault
|   |-- net-xfrm-xfrm_hash.c:internal-compiler-error:Segmentation-fault
|   |-- net-xfrm-xfrm_ipcomp.c:internal-compiler-error:Segmentation-fault
|   |-- net-xfrm-xfrm_output.c:internal-compiler-error:Segmentation-fault
|   |-- net-xfrm-xfrm_replay.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-audit.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-capability.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-domain.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-file.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-ipc.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-label.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-lib.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-match.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-mount.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-net.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-policy.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-policy_unpack.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-procattr.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-resource.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-secid.c:internal-compiler-error:Segmentation-fault
|   |-- security-apparmor-task.c:internal-compiler-error:Segmentation-fault
|   |-- security-integrity-digsig_asymmetric.c:internal-compiler-error:Segmentation-fault
|   |-- security-keys-request_key.c:internal-compiler-error:Segmentation-fault
|   |-- security-smack-smack_access.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-control.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-ctljack.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-device.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-init.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-jack.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-memalloc.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-pcm_dmaengine.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-pcm_lib.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-pcm_memory.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-pcm_misc.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-pcm_native.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-seq-seq_fifo.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-seq-seq_lock.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-seq-seq_memory.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-seq-seq_midi_event.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-seq-seq_ports.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-seq-seq_prioq.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-seq-seq_queue.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-seq-seq_timer.c:internal-compiler-error:Segmentation-fault
|   |-- sound-core-sound_oss.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-bcm-bcm63xx-pcm-whistler.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-codecs-rl6231.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-codecs-rt5682.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-codecs-rt700.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-codecs-rt711-sdca.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-codecs-rt711.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-codecs-rt715-sdca.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-codecs-rt715.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-codecs-wcd-clsh-v2.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-fsl-fsl_ssi_dbg.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-generic-simple-card-utils.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-soc-card.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-soc-component.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-soc-dai.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-soc-dapm.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-soc-generic-dmaengine-pcm.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-soc-jack.c:internal-compiler-error:Segmentation-fault
|   |-- sound-soc-soc-ops.c:internal-compiler-error:Segmentation-fault
|   `-- sound-soc-soc-pcm.c:internal-compiler-error:Segmentation-fault
|-- riscv-randconfig-r002-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_migrate_context
|   |-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_register
|   `-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_unregister
|-- riscv-randconfig-r034-20220318
|   |-- drivers-gpio-gpio-max73.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-hid-hid-vivaldi-common.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-input-input-poller.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-input-rmi4-rmi_f01.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-input-rmi4-rmi_f03.c:internal-compiler-error:Segmentation-fault
|   |-- drivers-usb-dwc3-debugfs.c:internal-compiler-error:Segmentation-fault
|   |-- fs-eventfd.c:internal-compiler-error:Segmentation-fault
|   `-- fs-posix_acl.c:internal-compiler-error:Segmentation-fault
|-- riscv-randconfig-r042-20220317
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- riscv-rv32_defconfig
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- s390-allmodconfig
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- s390-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-iio-frequency-admv1014.c:sparse:sparse:dubious:x-y
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-cacheflush.h:warning:struct-folio-declared-inside-parameter-list-will-not-be-visible-outside-of-this-definition-or-declaration
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- s390-buildonly-randconfig-r004-20220317
|   |-- arch-s390-kernel-machine_kexec.c:warning:memcpy-offset-is-out-of-the-bounds
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_migrate_context
|   |-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_register
|   `-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_unregister
|-- s390-defconfig
|   |-- arch-s390-kernel-machine_kexec.c:warning:memcpy-offset-is-out-of-the-bounds
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- s390-randconfig-c024-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- s390-randconfig-r012-20220317
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- s390-randconfig-r014-20220317
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- s390-randconfig-r044-20220317
|   |-- include-linux-fortify-string.h:warning:__builtin_memcpy-offset-is-out-of-the-bounds
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- s390-randconfig-s031-20220317
|   |-- arch-s390-kernel-machine_kexec.c:warning:memcpy-offset-is-out-of-the-bounds
|   |-- drivers-dma-idma64.c:undefined-reference-to-devm_ioremap_resource
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|-- sh-allmodconfig
|   |-- arch-sh-kernel-machvec.c:warning:array-subscript-struct-sh_machine_vector-is-partly-outside-array-bounds-of-long-int
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|   `-- standard-input:Error:unknown-pseudo-op:sec
|-- sh-allyesconfig
|   |-- arch-sh-kernel-machvec.c:warning:array-subscript-struct-sh_machine_vector-is-partly-outside-array-bounds-of-long-int
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|   `-- standard-input:Error:unknown-pseudo-op:sec
|-- sh-randconfig-r031-20220318
|   |-- arch-sh-kernel-machvec.c:warning:array-subscript-struct-sh_machine_vector-is-partly-outside-array-bounds-of-long-int
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- sh-randconfig-r034-20220318
|   |-- arch-sh-kernel-machvec.c:warning:array-subscript-struct-sh_machine_vector-is-partly-outside-array-bounds-of-long-int
|   `-- standard-input:Error:.size-expression-for-xpcs_validate-does-not-evaluate-to-a-constant
|-- sparc-allmodconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- drivers-iio-frequency-admv1014.c:sparse:sparse:dubious:x-y
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-icr_base-got-void-noderef-__iomem
|   |-- drivers-irqchip-irq-renesas-h8s.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-void-static-toplevel-ipr_base-got-void-noderef-__iomem
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- drivers-nvmem-sunplus-ocotp.c:sparse:sparse:symbol-sp_otp_v0-was-not-declared.-Should-it-be-static
|   |-- drivers-tty-serial-sunplus-uart.c:sparse:sparse:symbol-sunplus_console_ports-was-not-declared.-Should-it-be-static
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- sparc-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- sparc-buildonly-randconfig-r006-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|-- sparc64-randconfig-r004-20220318
|   |-- drivers-media-platform-samsung-exynos4-is-fimc-isp-video.h:warning:no-previous-prototype-for-fimc_isp_video_device_unregister
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|-- sparc64-randconfig-r032-20220317
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- um-i386_defconfig
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- um-x86_64_defconfig
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-allnoconfig
|   `-- Documentation-driver-api-nvdimm-nvdimm.rst:(SEVERE-)-Title-level-inconsistent:
|-- x86_64-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-defconfig
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-kexec
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-randconfig-a002
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-randconfig-a004
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-randconfig-a006
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-randconfig-a011
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-randconfig-a015
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-randconfig-c002
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-randconfig-c022
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-randconfig-m001
|   `-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|-- x86_64-randconfig-s021
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-randconfig-s022
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-rhel-8.3
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-rhel-8.3-func
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-rhel-8.3-kselftests
|   |-- drivers-net-vxlan-vxlan_core.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-unsigned-int-usertype-b-got-restricted-__be32-usertype-vni
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- x86_64-rhel-8.3-kunit
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-rcupdate.h:error:dereferencing-pointer-to-incomplete-type-struct-css_set
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-sched_cpu_wait_empty
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- xtensa-allmodconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- xtensa-allyesconfig
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|   |-- vpu_malone.c:(.text):undefined-reference-to-__moddi3
|   `-- vpu_windsor.c:(.text):undefined-reference-to-__moddi3
|-- xtensa-randconfig-p002-20220318
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
|-- xtensa-randconfig-r015-20220317
|   |-- drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_resource.c:warning:no-previous-prototype-for-is_timing_changed
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-calc_load_nohz_stop
`-- xtensa-randconfig-r023-20220318
    |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
    `-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst

clang_recent_errors
|-- arm-buildonly-randconfig-r003-20220317
|   `-- kernel-sched-sched.h:fatal-error:asm-paravirt_api_clock.h-file-not-found
|-- arm-netwinder_defconfig
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- arm-randconfig-c002-20220317
|   |-- arch-arm-kernel-ftrace.c:warning:no-previous-prototype-for-function-prepare_ftrace_return
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   `-- kernel-sched-sched.h:fatal-error:asm-paravirt_api_clock.h-file-not-found
|-- arm-randconfig-c002-20220318
|   |-- arch-arm-kernel-unwind.c:warning:Assigned-value-is-garbage-or-undefined-clang-analyzer-core.uninitialized.Assign
|   |-- drivers-hid-hid-core.c:warning:Although-the-value-stored-to-field-is-used-in-the-enclosing-expression-the-value-is-never-actually-read-from-field-clang-analyzer-deadcode.DeadStores
|   |-- drivers-input-serio-ps2-gpio.c:warning:Value-stored-to-rxflags-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-memory-brcmstb_dpfe.c:warning:Call-to-function-sprintf-is-insecure-as-it-does-not-provide-bounding-of-the-memory-buffer-or-security-checks-introduced-in-the-C11-standard.-Replace-with-analogou
|   |-- drivers-phy-broadcom-phy-brcm-usb.c:warning:Call-to-function-sprintf-is-insecure-as-it-does-not-provide-bounding-of-the-memory-buffer-or-security-checks-introduced-in-the-C11-standard.-Replace-with-an
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-fortify-string.h:warning:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|   |-- lib-stackinit_kunit.c:warning:Address-of-stack-memory-associated-with-local-variable-var-is-still-referred-to-by-the-global-variable-fill_start-upon-returning-to-the-caller.-This-will-be-a-dangling-re
|   |-- lib-stackinit_kunit.c:warning:Address-of-stack-memory-associated-with-local-variable-var-is-still-referred-to-by-the-global-variable-target_start-upon-returning-to-the-caller.-This-will-be-a-dangling-
|   |-- lib-stackinit_kunit.c:warning:Excessive-padding-in-struct-test_big_hole-(-padding-bytes-where-is-optimal).
|   `-- lib-stackinit_kunit.c:warning:Undefined-or-garbage-value-returned-to-caller-clang-analyzer-core.uninitialized.UndefReturn
|-- arm-randconfig-r025-20220317
|   `-- kernel-sched-sched.h:fatal-error:asm-paravirt_api_clock.h-file-not-found
|-- arm64-randconfig-r033-20220319
|   |-- lib-raid6-neon1.c:warning:mixing-declarations-and-code-is-incompatible-with-standards-before-C99
|   |-- lib-raid6-neon2.c:warning:mixing-declarations-and-code-is-incompatible-with-standards-before-C99
|   |-- lib-raid6-neon4.c:warning:mixing-declarations-and-code-is-incompatible-with-standards-before-C99
|   |-- lib-raid6-neon8.c:warning:mixing-declarations-and-code-is-incompatible-with-standards-before-C99
|   `-- lib-raid6-recov_neon_inner.c:warning:mixing-declarations-and-code-is-incompatible-with-standards-before-C99
|-- hexagon-buildonly-randconfig-r005-20220318
|   |-- drivers-media-platform-renesas-renesas-ceu.c:warning:unused-variable-ceu_data_rz
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- hexagon-randconfig-r015-20220317
|   `-- drivers-media-platform-samsung-s5p-jpeg-jpeg-core.c:warning:unused-variable-samsung_jpeg_match
|-- hexagon-randconfig-r034-20220317
|   `-- drivers-media-platform-st-sti-c8sectpfe-c8sectpfe-core.c:warning:unused-variable-c8sectpfe_match
|-- hexagon-randconfig-r036-20220317
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- hexagon-randconfig-r041-20220317
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- hexagon-randconfig-r041-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- hexagon-randconfig-r045-20220317
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- hexagon-randconfig-r045-20220318
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- i386-randconfig-a002
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-function-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- i386-randconfig-a004
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- i386-randconfig-a006
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- i386-randconfig-a011
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-function-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- i386-randconfig-a013
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- i386-randconfig-a015
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- i386-randconfig-c001
|   |-- drivers-hid-hid-core.c:warning:Although-the-value-stored-to-field-is-used-in-the-enclosing-expression-the-value-is-never-actually-read-from-field-clang-analyzer-deadcode.DeadStores
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|   `-- net-ipv4-tcp_input.c:warning:Value-stored-to-reason-is-never-read-clang-analyzer-deadcode.DeadStores
|-- mips-cu1830-neo_defconfig
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- mips-randconfig-c004-20220318
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- riscv-randconfig-c006-20220317
|   |-- drivers-clk-imx-clk-pll14xx.c:warning:Value-stored-to-pll_div_ctl1-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-firmware-turris-mox-rwtm.c:warning:Call-to-function-sprintf-is-insecure-as-it-does-not-provide-bounding-of-the-memory-buffer-or-security-checks-introduced-in-the-C11-standard.-Replace-with-ana
|   |-- drivers-hid-hid-core.c:warning:Although-the-value-stored-to-field-is-used-in-the-enclosing-expression-the-value-is-never-actually-read-from-field-clang-analyzer-deadcode.DeadStores
|   |-- drivers-hwmon-nsa320-hwmon.c:warning:Call-to-function-sprintf-is-insecure-as-it-does-not-provide-bounding-of-the-memory-buffer-or-security-checks-introduced-in-the-C11-standard.-Replace-with-analogous
|   |-- drivers-input-serio-ps2-gpio.c:warning:Value-stored-to-rxflags-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-chips-media-coda-bit.c:warning:Value-stored-to-value-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-chips-media-coda-common.c:warning:Array-access-(from-variable-formats-)-results-in-a-null-pointer-dereference-clang-analyzer-core.NullDereference
|   |-- drivers-media-platform-st-sti-delta-delta-debug.c:warning:Value-stored-to-delta-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-delta-delta-debug.c:warning:Value-stored-to-s-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-delta-delta-debug.c:warning:Value-stored-to-str-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-delta-delta-mjpeg-dec.c:warning:Value-stored-to-b-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-delta-delta-v4l2.c:warning:Value-stored-to-data-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-delta-delta-v4l2.c:warning:Value-stored-to-delta-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-delta-delta-v4l2.c:warning:Value-stored-to-str-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-delta-delta-v4l2.c:warning:Value-stored-to-str1-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-delta-delta-v4l2.c:warning:Value-stored-to-str2-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-hva-hva-h264.c:warning:Value-stored-to-dev-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-hva-hva-h264.c:warning:Value-stored-to-idr_pic_id-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-hva-hva-v4l2.c:warning:Value-stored-to-dev-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-hva-hva-v4l2.c:warning:Value-stored-to-frame-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-media-platform-st-sti-hva-hva-v4l2.c:warning:Value-stored-to-stream-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-mtd-nand-ecc-mxic.c:warning:Branch-condition-evaluates-to-a-garbage-value-clang-analyzer-core.uninitialized.Branch
|   |-- drivers-mtd-nand-ecc-mxic.c:warning:Value-stored-to-dev-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
|   |-- drivers-phy-broadcom-phy-brcm-usb.c:warning:Call-to-function-sprintf-is-insecure-as-it-does-not-provide-bounding-of-the-memory-buffer-or-security-checks-introduced-in-the-C11-standard.-Replace-with-an
|   |-- drivers-staging-greybus-arche-apb-ctrl.c:warning:Call-to-function-sprintf-is-insecure-as-it-does-not-provide-bounding-of-the-memory-buffer-or-security-checks-introduced-in-the-C11-standard.-Replace-wi
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- riscv-randconfig-c006-20220318
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- riscv-randconfig-r021-20220318
|   `-- include-asm-generic-io.h:warning:performing-pointer-arithmetic-on-a-null-pointer-has-undefined-behavior-err:false
|-- riscv-randconfig-r042-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-function-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- s390-randconfig-c005-20220317
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-function-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- s390-randconfig-c005-20220318
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- s390-randconfig-r002-20220317
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-function-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- s390-randconfig-r044-20220318
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-function-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- x86_64-randconfig-a001
|   |-- drivers-spi-spi-amd.c:warning:cast-to-smaller-integer-type-enum-amd_spi_versions-from-const-void
|   |-- include-linux-fortify-string.h:warning:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- x86_64-randconfig-a003
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-fortify-string.h:warning:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|-- x86_64-randconfig-a005
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-fortify-string.h:warning:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-function-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- x86_64-randconfig-a012
|   |-- fs-btrfs-ordered-data.c:warning:expecting-prototype-for-Add-an-ordered-extent-to-the-per().-Prototype-was-for-btrfs_add_ordered_extent()-instead
|   |-- fs-btrfs-tree-log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|   |-- include-linux-fortify-string.h:warning:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- x86_64-randconfig-a014
|   |-- include-linux-fortify-string.h:warning:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
|   |-- kernel-sched-fair.c:warning:no-previous-prototype-for-function-nohz_balance_enter_idle
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
|   |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
|   `-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
|-- x86_64-randconfig-a016
|   |-- include-linux-fortify-string.h:warning:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
|   |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
|   `-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
`-- x86_64-randconfig-c007
    |-- drivers-hid-hid-core.c:warning:Although-the-value-stored-to-field-is-used-in-the-enclosing-expression-the-value-is-never-actually-read-from-field-clang-analyzer-deadcode.DeadStores
    |-- drivers-pci-vgaarb.c:warning:Value-stored-to-dev-during-its-initialization-is-never-read-clang-analyzer-deadcode.DeadStores
    |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-idle_task_exit
    |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_activate
    |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_deactivate
    |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_dying
    |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_starting
    |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_cpu_wait_empty
    |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init
    |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-sched_init_smp
    |-- kernel-sched-core.c:warning:no-previous-prototype-for-function-task_sched_runtime
    |-- kernel-sched-fair.c:warning:no-previous-prototype-for-function-nohz_balance_enter_idle
    |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_remote
    |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_start
    |-- kernel-sched-loadavg.c:warning:no-previous-prototype-for-function-calc_load_nohz_stop
    `-- net-ipv4-tcp_input.c:warning:Value-stored-to-reason-is-never-read-clang-analyzer-deadcode.DeadStores

elapsed time: 768m

configs tested: 119
configs skipped: 4

gcc tested configs:
arm                              allyesconfig
arm                                 defconfig
arm                              allmodconfig
arm64                            allyesconfig
arm64                               defconfig
um                             i386_defconfig
um                           x86_64_defconfig
mips                             allyesconfig
riscv                            allyesconfig
mips                             allmodconfig
riscv                            allmodconfig
i386                          randconfig-c001
powerpc                          allmodconfig
m68k                             allyesconfig
s390                             allmodconfig
m68k                             allmodconfig
powerpc                          allyesconfig
s390                             allyesconfig
sparc                            allyesconfig
sh                               allmodconfig
xtensa                           allyesconfig
h8300                            allyesconfig
parisc                           allyesconfig
alpha                            allyesconfig
arc                              allyesconfig
nios2                            allyesconfig
m68k                       bvme6000_defconfig
powerpc                      bamboo_defconfig
sh                           se7724_defconfig
arm                           corgi_defconfig
sh                              ul2_defconfig
powerpc                       holly_defconfig
mips                       capcella_defconfig
sparc                            alldefconfig
sh                ecovec24-romimage_defconfig
arm                        clps711x_defconfig
m68k                       m5208evb_defconfig
riscv                               defconfig
sh                          rsk7201_defconfig
arm                  randconfig-c002-20220317
arm                  randconfig-c002-20220318
ia64                                defconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                                defconfig
nds32                             allnoconfig
nios2                               defconfig
csky                                defconfig
alpha                               defconfig
nds32                               defconfig
arc                                 defconfig
parisc                              defconfig
parisc64                            defconfig
s390                                defconfig
i386                             allyesconfig
i386                              debian-10.3
i386                   debian-10.3-kselftests
i386                                defconfig
sparc                               defconfig
powerpc                           allnoconfig
x86_64                        randconfig-a006
x86_64                        randconfig-a002
x86_64                        randconfig-a004
i386                          randconfig-a003
i386                          randconfig-a001
i386                          randconfig-a005
x86_64                        randconfig-a015
x86_64                        randconfig-a013
x86_64                        randconfig-a011
i386                          randconfig-a014
i386                          randconfig-a012
i386                          randconfig-a016
s390                 randconfig-r044-20220317
arc                  randconfig-r043-20220318
riscv                randconfig-r042-20220317
arc                  randconfig-r043-20220317
riscv                    nommu_k210_defconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                          rv32_defconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                                  kexec
x86_64                               rhel-8.3
x86_64                          rhel-8.3-func
x86_64                         rhel-8.3-kunit
x86_64                           allyesconfig

clang tested configs:
arm                  randconfig-c002-20220318
x86_64                        randconfig-c007
s390                 randconfig-c005-20220317
s390                 randconfig-c005-20220318
arm                  randconfig-c002-20220317
mips                 randconfig-c004-20220318
mips                 randconfig-c004-20220317
riscv                randconfig-c006-20220318
powerpc              randconfig-c003-20220318
powerpc              randconfig-c003-20220317
i386                          randconfig-c001
riscv                randconfig-c006-20220317
arm                       netwinder_defconfig
mips                     cu1830-neo_defconfig
powerpc                 mpc836x_rdk_defconfig
powerpc                     mpc512x_defconfig
powerpc                       ebony_defconfig
x86_64                        randconfig-a001
x86_64                        randconfig-a003
x86_64                        randconfig-a005
i386                          randconfig-a002
i386                          randconfig-a006
i386                          randconfig-a004
x86_64                        randconfig-a014
x86_64                        randconfig-a012
x86_64                        randconfig-a016
i386                          randconfig-a011
i386                          randconfig-a013
i386                          randconfig-a015
hexagon              randconfig-r045-20220318
hexagon              randconfig-r041-20220318
riscv                randconfig-r042-20220318
hexagon              randconfig-r041-20220317
s390                 randconfig-r044-20220318
hexagon              randconfig-r045-20220317

---
0-DAY CI Kernel Test Service
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


