From: Joerg Dorchain <dorchain@wirbel.com>
Subject: L68K: parport-amiga for 2.1.120
To: linux-m68k@phil.uni-sb.de (Linux Liste),
        Jes.Sorensen@cern.ch (Jes Sorensen)
Date: Thu, 10 Sep 1998 09:09:21 +0200 (MEST)
Sender: owner-linux-m68k@phil.uni-sb.de

Hi,

this is parport_amiag for 2.1.120. Sorry, but it overlaps with Andreas´ patch.
Perhaps you can get away when you install this patch first. Anyway the rejects
should be trivial.

Joerg

diff -urN -X /home/joerg/linux/exclude-diff /home/joerg/v2.1/linux-2.1.119/drivers/char/lp.c linux/drivers/char/lp.c
--- /home/joerg/v2.1/linux-2.1.119/drivers/char/lp.c	Sun Aug 30 13:33:56 1998
+++ linux/drivers/char/lp.c	Mon Aug 31 14:39:23 1998
@@ -94,7 +94,7 @@
 #include <linux/delay.h>
 
 #include <linux/parport.h>
-#undef LP_STATS
+#define LP_STATS
 #undef LP_NEED_CAREFUL
 #include <linux/lp.h>
 
@@ -126,7 +126,7 @@
 #define LP_READY(minor, status) ((status) & LP_PBUSY)
 #endif
 
-#undef LP_DEBUG
+#define LP_DEBUG
 #undef LP_READ_DEBUG
 
 /* --- parport support ----------------------------------------- */
@@ -211,7 +211,7 @@
 #endif
 	/* must wait before taking strobe high, and after taking strobe
 	   low, according spec.  Some printers need it, others don't. */
-#ifndef __sparc__
+#if !defined(__sparc__) && !defined(__mc68000__)
 	while (wait != LP_WAIT(minor)) /* FIXME: should be a udelay() */
 		wait++;
 #else
@@ -219,7 +219,7 @@
 #endif
 	/* control port takes strobe high */
 	w_ctr(minor, LP_PSELECP | LP_PINITP | LP_PSTROBE);
-#ifndef __sparc__
+#if !defined(__sparc__) && !defined(__mc68000__)
 	while (wait)			/* FIXME: should be a udelay() */
 		wait--;
 #else
@@ -316,6 +316,7 @@
 	unsigned long total_bytes_written = 0;
 	unsigned long bytes_written;
 	struct lp_struct *lp = &lp_table[minor];
+	unsigned long flags;
 
 	if (minor >= LP_NO)
 		return -ENXIO;
@@ -384,6 +385,11 @@
 					current->timeout = jiffies + LP_TIME(minor);
 					lp_schedule (minor);
 				} else {
+					/* Replace cli()/sti() by
+					  cli()/restore_flags.
+					  It's a must for other architectures
+					  and doesn't break i386 */
+					save_flags(flags);
 					cli();
 					if (LP_PREEMPTED(minor))
 					{
@@ -394,7 +400,7 @@
 						 * envinroment to avoid parport sharing
 						 * starvation.
 						 */
-						sti();
+						restore_flags(flags);
 						goto lp_polling;
 					}
 					if (!lp_table[minor].irq_detected)
@@ -402,7 +408,7 @@
 						current->timeout = jiffies + LP_TIMEOUT_INTERRUPT;
 						interruptible_sleep_on(&lp->wait_q);
 					}
-					sti();
+					restore_flags(flags);
 				}
 			}
 		}
diff -urN -X /home/joerg/linux/exclude-diff /home/joerg/v2.1/linux-2.1.119/drivers/misc/Makefile linux/drivers/misc/Makefile
--- /home/joerg/v2.1/linux-2.1.119/drivers/misc/Makefile	Mon Feb 23 21:26:49 1998
+++ linux/drivers/misc/Makefile	Mon Aug 31 14:39:23 1998
@@ -37,6 +37,13 @@
       M_OBJS += parport_ax.o
     endif
   endif
+  ifeq ($(CONFIG_PARPORT_AMIGA),y)
+    LX_OBJS += parport_amiga.o
+  else
+    ifeq ($(CONFIG_PARPORT_AMIGA),m)
+      M_OBJS += parport_amiga.o
+    endif
+  endif
   LX_OBJS += parport_init.o
 else
   ifeq ($(CONFIG_PARPORT),m)
@@ -52,6 +59,9 @@
   endif
   ifeq ($(CONFIG_PARPORT_AX),m)
     M_OBJS += parport_ax.o
+  endif
+  ifeq ($(CONFIG_PARPORT_AMIGA),m)
+    M_OBJS += parport_amiga.o
   endif
 endif
 
diff -urN -X /home/joerg/linux/exclude-diff /home/joerg/v2.1/linux-2.1.119/drivers/misc/parport_amiga.c linux/drivers/misc/parport_amiga.c
--- /home/joerg/v2.1/linux-2.1.119/drivers/misc/parport_amiga.c	Thu Jan  1 01:00:00 1970
+++ linux/drivers/misc/parport_amiga.c	Tue Sep  1 11:45:22 1998
@@ -0,0 +1,306 @@
+/* Low-level parallel port routines for the Amiga buildin port
+ *
+ * Author: Joerg Dorchain <dorchain@wirbel.com>
+ *
+ * This is a complete rewrite of the code, but based heaviy upon the old
+ * lp_intern. code.
+ *
+ * The built-in Amiga parallel port provides one port at a fixed address
+ * with 8 bisdirecttional data lines (D0 - D7) and 3 bidirectional status
+ * lines (BUSY, POUT, SEL), 1 output control line /STROBE (raised automatically in
+ * hardware when the data register is accessed), and 1 input control line
+ * /ACK, able to cause an interrupt, but both not directly settable by
+ * software.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/parport.h>
+#include <asm/setup.h>
+#include <asm/amigahw.h>
+#include <asm/irq.h>
+#include <asm/amigaints.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define DPRINTK printk
+#else
+static inline int DPRINTK() {return 0;}
+#endif
+
+static struct parport *this_port = NULL;
+
+static void amiga_write_data(struct parport *p, unsigned char data)
+{
+DPRINTK("write_data %c\n",data);
+	/* Triggers also /STROBE. This behavior cannot be changed */
+	ciaa.prb = data;
+}
+
+static unsigned char amiga_read_data(struct parport *p)
+{
+	/* Triggers also /STROBE. This behavior cannot be changed */
+	return ciaa.prb;
+}
+
+#if 0
+static unsigned char control_pc_to_amiga(unsigned char control)
+{
+	unsigned char ret = 0;
+
+	if (control & PARPORT_CONTROL_DIRECTION) /* XXX: What is this? */
+		;
+	if (control & PARPORT_CONTROL_INTEN) /* XXX: What is INTEN? */
+		;
+	if (control & PARPORT_CONTROL_SELECT) /* XXX: What is SELECP? */
+		;
+	if (control & PARPORT_CONTROL_INIT) /* INITP */
+		/* reset connected to cpu reset pin */;
+	if (control & PARPORT_CONTROL_AUTOFD) /* AUTOLF */
+		/* Not connected */;
+	if (control & PARPORT_CONTROL_STROBE) /* Strobe */
+		/* Handled only directly by hardware */;
+	return ret;
+}
+#endif
+
+static unsigned char control_amiga_to_pc(unsigned char control)
+{
+	return PARPORT_CONTROL_INTEN | PARPORT_CONTROL_SELECT |
+	      PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_STROBE;
+	/* fake value: interrupt enable, select in, no reset,
+	no autolf, no strobe - seems to be closest the wiring diagram */
+}
+
+static void amiga_write_control(struct parport *p, unsigned char control)
+{
+DPRINTK("write_control %02x\n",control);
+	/* No implementation possible */
+}
+	
+static unsigned char amiga_read_control( struct parport *p)
+{
+DPRINTK("read_control \n");
+	return control_amiga_to_pc(0);
+}
+
+static unsigned char amiga_frob_control( struct parport *p, unsigned char mask, unsigned char val)
+{
+	unsigned char old;
+
+DPRINTK("frob_control mask %02x, value %02x\n",mask,val);
+	old = amiga_read_control(p);
+	amiga_write_control(p, (old & ~mask) ^ val);
+	return old;
+}
+
+
+static unsigned char status_pc_to_amiga(unsigned char status)
+{
+	unsigned char ret = 1;
+
+	if (status & PARPORT_STATUS_BUSY) /* Busy */
+		ret &= ~1;
+	if (status & PARPORT_STATUS_ACK) /* Ack */
+		/* handled in hardware */;
+	if (status & PARPORT_STATUS_PAPEROUT) /* PaperOut */
+		ret |= 2;
+	if (status & PARPORT_STATUS_SELECT) /* select */
+		ret |= 4;
+	if (status & PARPORT_STATUS_ERROR) /* error */
+		/* not connected */;
+	return ret;
+}
+
+static unsigned char status_amiga_to_pc(unsigned char status)
+{
+	unsigned char ret = PARPORT_STATUS_BUSY | PARPORT_STATUS_ACK | PARPORT_STATUS_ERROR;
+
+	if (status & 1) /* Busy */
+		ret &= ~PARPORT_STATUS_BUSY;
+	if (status & 2) /* PaperOut */
+		ret |= PARPORT_STATUS_PAPEROUT;
+	if (status & 4) /* Selected */
+		ret |= PARPORT_STATUS_SELECT;
+	/* the rest is not connected or handled autonomously in hardware */
+
+	return ret;
+}
+
+static void amiga_write_status( struct parport *p, unsigned char status)
+{
+DPRINTK("write_status %02x\n",status);
+	ciab.pra |= (ciab.pra & 0xf8) | status_pc_to_amiga(status);
+}
+
+static unsigned char amiga_read_status(struct parport *p)
+{
+	unsigned char status;
+
+	status = status_amiga_to_pc(ciab.pra & 7);
+DPRINTK("read_status %02x\n", status);
+	return status;
+}
+
+static void amiga_change_mode( struct parport *p, int m)
+{
+	/* XXX: This port only has one mode, and I am
+	not sure about the corresponding PC-style mode*/
+}
+
+/* as this ports irq handling is already done, we use a generic funktion */
+
+static void amiga_release_resources(struct parport *p)
+{
+DPRINTK("realease_resources\n");
+	if (p->irq != PARPORT_IRQ_NONE)
+		free_irq(IRQ_AMIGA_CIAA_FLG, p);
+}
+
+static int amiga_claim_resources(struct parport *p)
+{
+DPRINTK("claim_resources\n");
+	return request_irq(IRQ_AMIGA_CIAA_FLG, parport_intr_func, 0, p->name, p);
+}
+
+static void amiga_init_state(struct parport_state *s)
+{
+	s->u.amiga.data = 0;
+	s->u.amiga.datadir = 255;
+	s->u.amiga.status = 0;
+	s->u.amiga.statusdir = 0;
+}
+
+static void amiga_save_state(struct parport *p, struct parport_state *s)
+{
+	s->u.amiga.data = ciaa.prb;
+	s->u.amiga.datadir = ciaa.ddrb;
+	s->u.amiga.status = ciab.pra & 7;
+	s->u.amiga.statusdir = ciab.ddra & 7;
+}
+
+static void amiga_restore_state(struct parport *p, struct parport_state *s)
+{
+	ciaa.prb = s->u.amiga.data;
+	ciaa.ddrb = s->u.amiga.datadir;
+	ciab.pra |= (ciab.pra & 0xf8) | s->u.amiga.status;
+	ciab.ddra |= (ciab.ddra & 0xf8) | s->u.amiga.statusdir;
+}
+
+static void amiga_enable_irq(struct parport *p)
+{
+	enable_irq(IRQ_AMIGA_CIAA_FLG);
+}
+
+static void amiga_disable_irq(struct parport *p)
+{
+	disable_irq(IRQ_AMIGA_CIAA_FLG);
+}
+
+static int amiga_examine_irq(struct parport *p)
+{
+	return 1; /* if an interrupt happened, we know it is ours */
+}
+
+static void amiga_inc_use_count(void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void amiga_dec_use_count(void)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+static struct parport_operations pp_amiga_ops = {
+	amiga_write_data,
+	amiga_read_data,
+
+	amiga_write_control,
+	amiga_read_control,
+	amiga_frob_control,
+
+	NULL, /* write_econtrol */
+	NULL, /* read_econtrol */
+	NULL, /* frob_econtrol */
+
+	amiga_write_status,
+	amiga_read_status,
+
+	NULL, /* write fifo */
+	NULL, /* read fifo */
+
+	amiga_change_mode,
+
+
+	amiga_release_resources,
+	amiga_claim_resources,
+
+
+	NULL, /* epp_write_data */
+	NULL, /* epp_read_data */
+	NULL, /* epp_write_addr */
+	NULL, /* epp_read_addr */
+	NULL, /* epp_check_timeout */
+
+	NULL, /* epp_write_block */
+	NULL, /* epp_read_block */
+
+	NULL, /* ecp_write_block */
+	NULL, /* ecp_read_block */
+
+	amiga_init_state,
+	amiga_save_state,
+	amiga_restore_state,
+
+	amiga_enable_irq,
+	amiga_disable_irq,
+	amiga_examine_irq,
+
+	amiga_inc_use_count,
+	amiga_dec_use_count
+};
+
+/* ----------- Initialisation code --------------------------------- */
+
+__initfunc(int parport_amiga_init(void))
+{
+	struct parport *p;
+
+	if (MACH_IS_AMIGA && AMIGAHW_PRESENT(AMI_PARALLEL)) {
+		ciaa.ddrb = 0xff;
+		ciab.ddra &= 0xf8;
+		if (!(p = parport_register_port((unsigned long)&ciaa.prb,
+					IRQ_AMIGA_CIAA_FLG, PARPORT_DMA_NONE,
+					&pp_amiga_ops)))
+			return 0;
+		this_port = p;
+		printk(KERN_INFO "%s: Amiga built-in port using irq\n", p->name);
+		/* XXX: set operating mode */
+		parport_proc_register(p);
+		p->flags |= PARPORT_FLAG_COMA;
+
+		if (parport_probe_hook)
+			(*parport_probe_hook)(p);
+		return 1;
+
+	}
+	return 0;
+}
+
+#ifdef MODULE
+int init_module(void)
+{
+	return ! parport_amiga_init();
+}
+
+void cleanup_module(void)
+{
+	if (!(this_port->flags & PARPORT_FLAG_COMA))
+		parport_quiesce(this_port);
+	parport_proc_unregister(this_port);
+	parport_unregister_port(this_port);
+}
+#endif
+
+
diff -urN -X /home/joerg/linux/exclude-diff /home/joerg/v2.1/linux-2.1.119/drivers/misc/parport_ax.c linux/drivers/misc/parport_ax.c
--- /home/joerg/v2.1/linux-2.1.119/drivers/misc/parport_ax.c	Mon Aug 10 17:37:16 1998
+++ linux/drivers/misc/parport_ax.c	Tue Sep  1 10:54:07 1998
@@ -50,12 +50,6 @@
 #define CONFIGB		0x401
 #define ECONTROL	0x402
 
-static void
-parport_ax_null_intr_func(int irq, void *dev_id, struct pt_regs *regs)
-{
-	/* NULL function - Does nothing */
-}
-
 void
 parport_ax_write_epp(struct parport *p, unsigned char d)
 {
@@ -206,7 +200,7 @@
 {
 	if (p->irq != PARPORT_IRQ_NONE) {
 		parport_ax_disable_irq(p);
-		free_irq(p->irq, NULL);
+		free_irq(p->irq, p);
 	}
 	release_region(p->base, p->size);
 	if (p->modes & PARPORT_MODE_PCECR)
@@ -220,8 +214,8 @@
 {
 	/* FIXME check that resources are free */
 	if (p->irq != PARPORT_IRQ_NONE) {
-		request_irq(p->irq, parport_ax_null_intr_func,
-			    0, p->name, NULL);
+		request_irq(p->irq, parport_intr_func,
+			    0, p->name, p);
 		parport_ax_enable_irq(p);
 	}
 	request_region(p->base, p->size, p->name);
diff -urN -X /home/joerg/linux/exclude-diff /home/joerg/v2.1/linux-2.1.119/drivers/misc/parport_init.c linux/drivers/misc/parport_init.c
--- /home/joerg/v2.1/linux-2.1.119/drivers/misc/parport_init.c	Thu Dec 11 06:23:33 1902
+++ linux/drivers/misc/parport_init.c	Tue Sep  1 11:24:45 1998
@@ -122,6 +122,9 @@
 #ifdef CONFIG_PARPORT_AX
 	parport_ax_init();
 #endif
+#ifdef CONFIG_PARPORT_AMIGA
+	parport_amiga_init();
+#endif
 	return 0;
 }
 #endif
@@ -143,6 +146,7 @@
 EXPORT_SYMBOL(parport_proc_unregister);
 EXPORT_SYMBOL(parport_probe_hook);
 EXPORT_SYMBOL(parport_parse_irqs);
+EXPORT_SYMBOL(parport_intr_func);
 
 void inc_parport_count(void)
 {
diff -urN -X /home/joerg/linux/exclude-diff /home/joerg/v2.1/linux-2.1.119/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c
--- /home/joerg/v2.1/linux-2.1.119/drivers/misc/parport_pc.c	Mon Aug 10 17:37:16 1998
+++ linux/drivers/misc/parport_pc.c	Tue Sep  1 10:52:26 1998
@@ -53,11 +53,6 @@
    than PARPORT_MAX (in <linux/parport.h>).  */
 #define PARPORT_PC_MAX_PORTS  8
 
-static void parport_pc_null_intr_func(int irq, void *dev_id, struct pt_regs *regs)
-{
-	/* Null function - does nothing */
-}
-
 void parport_pc_write_epp(struct parport *p, unsigned char d)
 {
 	outb(d, p->base+EPPDATA);
@@ -173,7 +168,7 @@
 void parport_pc_release_resources(struct parport *p)
 {
 	if (p->irq != PARPORT_IRQ_NONE)
-		free_irq(p->irq, NULL);
+		free_irq(p->irq, p);
 	release_region(p->base, p->size);
 	if (p->modes & PARPORT_MODE_PCECR)
 		release_region(p->base+0x400, 3);
@@ -183,7 +178,7 @@
 {
 	int err;
 	if (p->irq != PARPORT_IRQ_NONE)
-		if ((err = request_irq(p->irq, parport_pc_null_intr_func, 0, p->name, NULL)) != 0) return err;
+		if ((err = request_irq(p->irq, parport_intr_func, 0, p->name, p)) != 0) return err;
 	request_region(p->base, p->size, p->name);
 	if (p->modes & PARPORT_MODE_PCECR)
 		request_region(p->base+0x400, 3, p->name);
diff -urN -X /home/joerg/linux/exclude-diff /home/joerg/v2.1/linux-2.1.119/drivers/misc/parport_procfs.c linux/drivers/misc/parport_procfs.c
--- /home/joerg/v2.1/linux-2.1.119/drivers/misc/parport_procfs.c	Mon Aug 10 17:37:16 1998
+++ linux/drivers/misc/parport_procfs.c	Tue Sep  1 10:29:25 1998
@@ -35,6 +35,8 @@
 					  unsigned long count, void *data)
 {
 	int retval = -EINVAL;
+/* changing irqs doesn't make sense on m68k. Besides, it wouldn't work the way below */
+#ifndef __mc68000__
 	int newirq = PARPORT_IRQ_NONE;
 	struct parport *pp = (struct parport *)data;
 	int oldirq = pp->irq;
@@ -96,6 +98,7 @@
 	spin_unlock_irqrestore (&pp->lock, flags);
 
 out:
+#endif
 	return retval;
 }
 
diff -urN -X /home/joerg/linux/exclude-diff /home/joerg/v2.1/linux-2.1.119/drivers/misc/parport_share.c linux/drivers/misc/parport_share.c
--- /home/joerg/v2.1/linux-2.1.119/drivers/misc/parport_share.c	Mon Aug 10 17:37:16 1998
+++ linux/drivers/misc/parport_share.c	Tue Sep  1 11:09:27 1998
@@ -55,10 +55,15 @@
 	return portlist;
 }
 
-void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs)
+void parport_intr_func(int irq, void *dev_id, struct pt_regs *regs)
 {
-	/* Null function - does nothing.  IRQs are pointed here whenever
-	   there is no real handler for them.  */
+	/* Generic function. This has always to be done. If some hardware
+	   needs black magic before or after the high level call,
+	   implement an own function. */
+	struct parport *p = dev_id;
+
+	if ( p && p->cad && p->cad->irq_func )
+		(*p->cad->irq_func)(irq, p->cad->private, regs);
 }
 
 struct parport *parport_register_port(unsigned long base, int irq, int dma,
@@ -355,19 +360,7 @@
 	port->cad = dev;
 	spin_unlock_irqrestore(&port->lock, flags);
 
-	/* Swap the IRQ handlers. */
-	if (port->irq != PARPORT_IRQ_NONE) {
-		if (oldcad && oldcad->irq_func) {
-			free_irq(port->irq, oldcad->private);
-			request_irq(port->irq, parport_null_intr_func,
-				    SA_INTERRUPT, port->name, NULL);
-		}
-		if (dev->irq_func) {
-			free_irq(port->irq, NULL);
-			request_irq(port->irq, dev->irq_func,
-				    SA_INTERRUPT, dev->name, dev->private);
-		}
-	}
+	/* irqs are done by low level driver */
 
 	/* Restore control registers */
 	port->ops->restore_state(port, dev->state);
@@ -457,13 +450,6 @@
 
 	/* Save control registers */
 	port->ops->save_state(port, dev->state);
-
-	/* Point IRQs somewhere harmless. */
-	if (port->irq != PARPORT_IRQ_NONE && dev->irq_func) {
-		free_irq(port->irq, dev->private);
-		request_irq(port->irq, parport_null_intr_func,
-			    SA_INTERRUPT, port->name, NULL);
- 	}
 
 	/* If anybody is waiting, find out who's been there longest and
 	   then wake them up. (Note: no locking required) */
diff -urN -X /home/joerg/linux/exclude-diff /home/joerg/v2.1/linux-2.1.119/include/linux/parport.h linux/include/linux/parport.h
--- /home/joerg/v2.1/linux-2.1.119/include/linux/parport.h	Mon Aug 10 17:38:36 1998
+++ linux/include/linux/parport.h	Tue Sep  1 18:18:15 1998
@@ -78,11 +78,19 @@
 	unsigned int ecr;
 };
 
+struct amiga_parport_state {
+	unsigned char data;	/* ciaa.prb */
+	unsigned char datadir;	/* ciaa.ddrb */
+	unsigned char status;	/* ciab.pra & 7 */
+	unsigned char statusdir;/* ciab.ddrb & 7 */
+};
+
 struct parport_state {
 	union {
 		struct pc_parport_state pc;
 		/* ARC has no state. */
 		/* AX uses same state information as PC */
+		struct amiga_parport_state amiga;
 		void *misc; 
 	} u;
 };
@@ -293,6 +301,9 @@
 	parport_release(dev);
 	return parport_claim_or_block(dev);
 }
+
+/* irq helper function */
+extern void parport_intr_func(int irq, void *dev_id, struct pt_regs *regs);
 
 /* Flags used to identify what a device does. */
 #define PARPORT_DEV_TRAN	        0x0000  /* We're transient. */

--- linux-old/arch/m68k/config.in	Tue Sep  8 18:27:47 1998
+++ linux/arch/m68k/config.in	Mon Aug 31 14:39:23 1998
@@ -103,6 +102,15 @@
   fi
 fi
 bool '/proc/hardware support' CONFIG_PROC_HARDWARE
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  tristate 'Parallel port support (disables old lp driver!)' CONFIG_PARPORT
+  if [ "$CONFIG_PARPORT" != "n" ]; then
+    if [ "$CONFIG_AMIGA" != "n" ]; then
+      dep_tristate '   Amiga builtin port' CONFIG_PARPORT_AMIGA $CONFIG_PARPORT
+    fi
+  fi
+fi
 endmenu
 
 source drivers/block/Config.in
@@ -259,9 +266,16 @@
   define_bool CONFIG_NVRAM y
 fi
 
-tristate 'Parallel printer support' CONFIG_M68K_PRINTER
-if [ "$CONFIG_ZORRO" = "y" ]; then
-  dep_tristate 'Multiface Card III parallel support' CONFIG_MULTIFACE_III_LP $CONFIG_PRINTER
+if [ "$CONFIG_PARPORT" = "n" ]; then
+  tristate 'Parallel printer support' CONFIG_M68K_PRINTER
+  if [ "$CONFIG_ZORRO" = "y" ]; then
+    dep_tristate 'Multiface Card III parallel support' CONFIG_MULTIFACE_III_LP $CONFIG_PRINTER
+  fi
+else
+  dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
+  if [ "$CONFIG_PRINTER" != "n" ]; then
+    bool '  Support IEEE1284 status readback' CONFIG_PRINTER_READBACK
+  fi
 fi
 if [ "$CONFIG_AMIGA" = "y" ]; then
   tristate 'Amiga mouse support' CONFIG_AMIGAMOUSE
