Resent-Date: Sun, 31 Jan 1999 21:29:13 +0100 (MET)
From: "Chris Sumner" <chris@cpsumner.freeserve.co.uk>
Date: 31 Jan 99 20:21:14 +0000
Subject: Patch for 2.2.0pre7 for whippet-serial
To: linux-m68k@lists.linux-m68k.org
Resent-From: linux-m68k@phil.uni-sb.de


diff -ur -X /root/exclude-file linux-2.2.0pre7/arch/m68k/config.in linux-2.2.0pre7patch/arch/m68k/config.in
--- linux-2.2.0pre7/arch/m68k/config.in	Sun Jan 31 01:38:32 1999
+++ linux-2.2.0pre7patch/arch/m68k/config.in	Sun Jan 31 19:36:02 1999
@@ -280,7 +280,9 @@
 fi
 if [ "$CONFIG_AMIGA" = "y" ]; then
   tristate 'Amiga builtin serial support' CONFIG_AMIGA_BUILTIN_SERIAL
-  bool 'Hisoft Whippet PCMCIA serial support' CONFIG_WHIPPET
+  if [ "$CONFIG_AMIGA_PCMCIA" = "y" ]; then
+    tristate 'Hisoft Whippet PCMCIA serial support' CONFIG_WHIPPET_SERIAL
+  fi
 fi
 if [ "$CONFIG_ZORRO" = "y" ]; then
   tristate 'GVP IO-Extender support' CONFIG_GVPIOEXT
Only in linux-2.2.0pre7/arch/m68k/kernel: m68k_defs.h
diff -ur -X /root/exclude-file linux-2.2.0pre7/drivers/char/Makefile linux-2.2.0pre7patch/drivers/char/Makefile
--- linux-2.2.0pre7/drivers/char/Makefile	Sun Jan 31 01:33:48 1999
+++ linux-2.2.0pre7patch/drivers/char/Makefile	Sun Jan 31 19:35:41 1999
@@ -113,9 +113,14 @@
   endif
 endif
 
-ifeq ($(CONFIG_WHIPPET),y)
+ifeq ($(CONFIG_WHIPPET_SERIAL),y)
 L_OBJS += ser_whippet.o
 S = y
+else
+  ifeq ($(CONFIG_WHIPPET_SERIAL),m)
+  M_OBJS += ser_whippet.o
+  SM = y
+  endif
 endif
 
 ifeq ($(CONFIG_HPDCA),y)
diff -ur -X /root/exclude-file linux-2.2.0pre7/drivers/char/m68kserial.c linux-2.2.0pre7patch/drivers/char/m68kserial.c
--- linux-2.2.0pre7/drivers/char/m68kserial.c	Sun Jan 31 01:30:08 1999
+++ linux-2.2.0pre7patch/drivers/char/m68kserial.c	Sun Jan 31 19:35:47 1999
@@ -1484,7 +1484,7 @@
 #ifdef CONFIG_MULTIFACE_III_TTY
 	    multiface_init();
 #endif
-#ifdef CONFIG_WHIPPET
+#ifdef CONFIG_WHIPPET_SERIAL
             whippet_init();
 #endif
 	    break;
diff -ur -X /root/exclude-file linux-2.2.0pre7/drivers/char/ser_whippet.c linux-2.2.0pre7patch/drivers/char/ser_whippet.c
--- linux-2.2.0pre7/drivers/char/ser_whippet.c	Tue Nov 24 23:49:30 1998
+++ linux-2.2.0pre7patch/drivers/char/ser_whippet.c	Sun Jan 31 19:43:06 1999
@@ -1,11 +1,11 @@
-#define WHIPPET_VER "2.1.124"
-#define WHIPPET_REV 3
-#define WHIPPET_DATE "8/Nov/1998"
+#define WHIPPET_VER "2.2.0pre7"
+#define WHIPPET_REV 0
+#define WHIPPET_DATE "31/Jan/1999"
 
 /*
- * ser_whippet.c - version 2.1.124 - revision 3 - date 8/Nov/1998
+ * ser_whippet.c - version info as above
  *
- * Copyright (C) 1997,98 Chris Sumner (chris@barbecue.demon.co.uk)
+ * Copyright (C) 1997,98,99 Chris Sumner (chris@cpsumner.freeserve.co.uk)
  *
  * This is a driver for the Hisoft Whippet PCMCIA serial port for
  * the Amiga. (16c550b UART)
@@ -16,23 +16,29 @@
  *
  * Modified:
  *
- *   31/Jul/98 - Changed email address
  *   11/Feb/98 - General tidying up
  *   31/Mar/98 - More tidying up
  *    7/Apr/98 - Fixed nasty little bug concerning gayle ints
  *    8/Apr/98 - Changed PCMCIA access timings to 100ns
+ *   31/Jul/98 - Changed email address
  *    2/Nov/98 - Fixed to work with 2.1.124
  *    7/Nov/98 - Added support for ASYNC_SPD_SHI and _WARP
  *    8/Nov/98 - Fixed a few small bugs
+ *   20/Nov/98 - Re-structured code a bit and tidied up
+ *   21/Nov/98 - Added support for modules
+ *   22/Nov/98 - Fixed inverted DCD bug
+ *   23/Nov/98 - Re-structured interrupt code and fixed a few bugs - (2.1.127)
+ *   31/Jan/99 - Changed email (again) and modified for 2.2.0pre7
  *
  * To Do:
  *
  *   - Test at 230k4 and 460k8 rates
- *   - Dynamic changing of fifo trigger level (via ioctl ?)
- *   - Handling of card insertion and removal?
- *   - Add support for modules
+ *   - Dynamic changing of fifo trigger level (via ioctl? via overrun count?)
+ *   - Handling of card insertion and removal (more than just shout at user!)
  */
 
+#include <linux/module.h>
+
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
@@ -55,26 +61,7 @@
 
 #include "ser_whippet.h"
 
-#define WHIPPET_DEBUG	1	/* Remove this when the driver is finished */
-#undef WHIPPET_DEBUG
-
-#define FIFO_SIZE 16		/* Size of hardware send and receive FIFOs */
-
-#define FIFO_TRIGGER_LEVEL	FIFO_TRIG_14	/* dynamic??? */
-				/*
-				 * There are 4 receiver FIFO-interrupt *
-				 * trigger levels (FIFO_TRIG_x), that  *
-				 * indicates how many bytes are to be  *
-				 * allowed in the receiver-FIFO before *
-				 * an interrupt is generated:          *
-				 *                x =  1 =  1 byte     *
-				 *                x =  4 =  4 bytes    *
-				 *                x =  8 =  8 bytes    *
-				 *                x = 14 = 14 bytes    *
-				 * 14 works for me, but if you keep    *
-				 * getting overruns try lowering this  *
-				 * value one step at a time.           *
-				 */
+#define WHIPPET_DEBUG	0	/* debug level */
 
 #define ser_DTRon(uart)  (uart->MCR |=  DTR)
 #define ser_RTSon(uart)  (uart->MCR |=  RTS)
@@ -119,15 +106,17 @@
 	ser_get_modem_info,
 	ser_set_modem_info,
 	ser_ioctl,
-	ser_stop_receive, ser_trans_empty, NULL
+	ser_stop_receive,
+	ser_trans_empty,
+	NULL
 };
 
 static int whippet_baud_table[20] = {
-	/* B0     */ 0,		/* Never use this value !!! */
+	/* B0     */ 0,
 	/* B50    */ 9216,
 	/* B75    */ 6144,
-	/* B110   */ 4189,	/* There's a little rounding on this one */
-	/* B134   */ 3439,	/* some rounding here too */
+	/* B110   */ 4189,	/* 110.00238 */
+	/* B134.5 */ 3426,	/* 134.50087 */
 	/* B150   */ 3072,
 	/* B200   */ 2304,
 	/* B300   */ 1536,
@@ -149,22 +138,50 @@
 static volatile struct GAYLE *gayle;		/* gayle register struct */
 static volatile struct WHIPPET *whippet;	/* whippet regs struct */
 
+static int fifo_trig_level=FIFO_TRIG_4;		/* can be changed */
+
+/*
+ * There are 4 receiver FIFO-interrupt trigger levels (FIFO_TRIG_x), that
+ * indicates how many bytes are to be allowed in the receiver-FIFO before
+ * an interrupt is generated:
+ *                x =  1 =  1 byte
+ *                x =  4 =  4 bytes
+ *                x =  8 =  8 bytes
+ *                x = 14 = 14 bytes
+ * If you keep getting overruns try lowering this value one step at a time.
+ */
 
 /***** start of ser_interrupt() - Handler for serial interrupt. *****/
 
 static void ser_interrupt(int irq, void *data, struct pt_regs *regs)
 {
 struct m68k_async_struct *info = data;
-u_char iir,lsr,gayleint;
+u_char iir,ier,lsr,gayleirq = gayle->intreq;
 
-	if (((gayleint=gayle->intreq) & ~GAYLE_IRQ_IDE)==0) return;
+	if ((gayleirq & 0x7c)==0) return;	/* quick exit */
+
+	if (gayleirq & 0x5c) {
+		gayle->intreq = ((gayleirq & 0x5c) ^ 0x5c) | (GAYLE_IRQ_IDE | GAYLE_IRQ_SC);
+		printk("gayle->intreq = 0x%02x; gayle->inten = 0x%02x\n",gayleirq, gayle->inten);
+		if (gayleirq & GAYLE_IRQ_CCDET) {
+			if (gayle->cardstatus & GAYLE_CS_CCDET) {
+				printk("Card inserted! Don't do that!\n");
+			} else {
+				printk("Card removed! Don't do that!\n");
+			}
+		}
+	}
+
+	if ((gayleirq & GAYLE_IRQ_SC)==0) return;
 
 /* If we got here, then there is an interrupt waiting for us to service */
 
+	iir = whippet->IIR;
+
+/* Disable UART interrupts for now... */
+
+	ier = whippet->IER; whippet->IER = 0;
 
-startint:
-	gayleint=gayle->intreq;
-	iir=whippet->IIR;
 	while (!(iir & IRQ_PEND)) {	/* loop until no more ints */
 
 		switch (iir & (IRQ_ID1 | IRQ_ID2 | IRQ_ID3)) {
@@ -181,13 +198,14 @@
 
 				lsr = whippet->LSR;
 				while (lsr & DR) {
-					u_char err = 0;
+					u_char err;
 					ch = whippet->RBR;
 
 					if (lsr & BI)      err = TTY_BREAK;
 					else if (lsr & PE) err = TTY_PARITY;
 					else if (lsr & OE) err = TTY_OVERRUN;
 					else if (lsr & FE) err = TTY_FRAME;
+					else err = 0;
 
 					rs_receive_char(info, ch, err);
 					lsr = whippet->LSR;
@@ -197,29 +215,30 @@
 
 			case IRQ_THRE:	/* Transmitter holding register empty */
 			{
-				int fifo_space = 16;
+				int fifo_space = FIFO_SIZE;
 
 	/* If the uart is ready to receive data and there are chars in */
 	/* the queue we transfer all we can to the uart's FIFO         */
 
-				if (info->xmit_cnt <= 0    ||
-				    info->tty->stopped     ||
-				    info->tty->hw_stopped) {
-
+				if (rs_no_more_tx(info)) {
+#if WHIPPET_DEBUG
+					printk("rs_no_more_tx()\n");
+#endif
 		/* Disable transmitter empty interrupt */
-					whippet->IER &= ~(ETHREI);
+					ier &= ~(ETHREI);
 
-		/* Need to send a char to acknowledge the interrupt */
-					whippet->THR = 0;
-
-		/* or Read IIR to acknowledge the interrupt ?!? */
-/*					(void)whippet->IIR; */
+		/* Read IIR to acknowledge the interrupt */
+					(void)whippet->IIR;
 					break;
 				}
 
 		/* Handle software flow control */
 				if (info->x_char) {
+#if WHIPPET_DEBUG
+					printk("Flow: X%s\n",(info->x_char == 19) ? "OFF" : "ON");
+#endif
 					whippet->THR = info->x_char;
+					info->icount.tx++;
 					info->x_char = 0;
 					fifo_space--;
 				}
@@ -228,18 +247,25 @@
 				while (fifo_space > 0) {
 					fifo_space--;
 					whippet->THR = info->xmit_buf[info->xmit_tail++];
-
 					info->xmit_tail &= (SERIAL_XMIT_SIZE-1);
+					info->icount.tx++;
 					if (--info->xmit_cnt == 0) break;
 				}
-
-
+#if WHIPPET_DEBUG
+				if (fifo_space == 0) printk("fifo full\n");
+#endif
 		/* Don't need THR interrupts any more */
 				if (info->xmit_cnt == 0) {
-					whippet->IER &= ~(ETHREI);
+#if WHIPPET_DEBUG
+					printk("TX ints OFF\n");
+#endif
+					ier &= ~(ETHREI);
 				}
 
 				if (info->xmit_cnt < WAKEUP_CHARS) {
+#if WHIPPET_DEBUG
+					printk("rs_sched_event()\n");
+#endif
 					rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
 				}
 			}
@@ -250,20 +276,30 @@
 				u_char msr = whippet->MSR;
 
 				if (info->flags & ASYNC_INITIALIZED) {
-					if (msr & DCTS)
-						rs_check_cts(info, (msr & CTS));	/* active high */
+					if (msr & DCTS) {
+#if WHIPPET_DEBUG
+						printk("CTS = %s\n",(msr & CTS) ? "ON" : "OFF");
+#endif
+						rs_check_cts(info, (msr & CTS));
+					}
 					if (msr & DDCD)
-						rs_dcd_changed(info, !(msr & DCD));	/* active low */
+						rs_dcd_changed(info, (msr & DCD));
 				}
 			}
 			break;
 
 		} /* switch (iir) */
+
 		iir = whippet->IIR;
 	} /* while IRQ_PEND */
 
-	gayle->intreq=((gayleint & 0x2c) ^ 0x2c) | 0xc0;
-	if (!(whippet->IIR & IRQ_PEND)) goto startint;		/* My oh my! A 'GOTO'! */
+/* Acknowledge gayle STATUS_CHANGE interrupt */
+
+	gayle->intreq = ((gayleirq & GAYLE_IRQ_SC) ^ GAYLE_IRQ_SC) | GAYLE_IRQ_IDE;
+
+/* Re-enable UART interrupts */
+
+	whippet->IER = ier;
 }
 
 /***** end of ser_interrupt() *****/
@@ -282,9 +318,11 @@
 /* Set DTR and RTS */
 	whippet->MCR |= (DTR | RTS);
 
-/* Enable interrupts. IF_EXTER irq has already been enabled in whippet_init()*/
-/* DON'T enable ETHREI here because there is nothing to send yet (murray) */
+/* Enable interrupts. IF_PORTS irq has already been enabled in whippet_init()*/
+/* DON'T enable ETHREI here because there is nothing to send yet (murray)    */
 	whippet->IER |= (ERDAI | ELSI | EMSI);
+
+	MOD_INC_USE_COUNT;
 }
 
 /***** end of ser_init() *****/
@@ -298,10 +336,10 @@
 	printk("ser_deinit()\n");
 #endif
 	/* Wait for the uart to get empty */
-	while(!((whippet->LSR) & TEMT)) {
+	while (!((whippet->LSR) & TEMT)) {
 	}
 
-	while((whippet->LSR) & DR) {
+	while ((whippet->LSR) & DR) {
 		(void)whippet->RBR;
 	}
 
@@ -311,6 +349,8 @@
 
 	ser_RTSoff(whippet);
 	if (!leave_dtr)	ser_DTRoff(whippet);
+
+	MOD_DEC_USE_COUNT;
 }
 
 /***** end of ser_deinit() *****/
@@ -328,7 +368,7 @@
 static void ser_enab_tx_int(struct m68k_async_struct *info, int enab_flag)
 {
 #if WHIPPET_DEBUG
-	printk("ser_enab_tx_int(%d)\n",enab_flag);
+	printk("ser_enab_tx_int(%s)\n",(enab_flag) ? "ON" : "OFF");
 #endif
 	if (enab_flag)	whippet->IER |= ETHREI;
 	else		whippet->IER &= ~(ETHREI);
@@ -373,10 +413,6 @@
 	if (cflag & CLOCAL)	info->flags &= ~ASYNC_CHECK_CD;
 	else			info->flags |= ASYNC_CHECK_CD;
 
-#ifdef WHIPPET_DEBUG
-	printk("Changing to baud-rate %i\n", baud);
-#endif
-
 	if (baud & CBAUDEX) {
 		baud &= ~CBAUDEX;
 		if (baud < 1 || baud > 2)
@@ -402,7 +438,7 @@
 			div = whippet_baud_table[baud];
 	}
 
-#ifdef WHIPPET_DEBUG
+#if WHIPPET_DEBUG
 	printk("divisor=%d, baud rate=%d\n",div,(div==0)? -1 : WHIPPET_BAUD_BASE/div);
 #endif
 
@@ -456,7 +492,7 @@
 static void ser_throttle(struct m68k_async_struct *info, int status)
 {
 #if WHIPPET_DEBUG
-	printk("ser_throttle()\n");
+	printk("ser_throttle(rts=%s)\n", (status) ? "OFF" : "ON");
 #endif
 	if (status)	ser_RTSoff(whippet);
 	else		ser_RTSon(whippet);
@@ -470,7 +506,7 @@
 static void ser_set_break(struct m68k_async_struct *info, int break_flag)
 {
 #if WHIPPET_DEBUG
-	printk("ser_set_break()\n");
+	printk("ser_set_break(%s)\n", (break_flag) ? "ON" : "OFF");
 #endif
 	if (break_flag)	whippet->LCR |= SET_BREAK;
 	else		whippet->LCR &= ~SET_BREAK;
@@ -504,7 +540,7 @@
 {
 unsigned char msr, mcr;
 
-#if WHIPPET_DEBUG
+#if WHIPPET_DEBUG > 1
 	printk("ser_get_modem()\n");
 #endif
 
@@ -512,11 +548,11 @@
 	mcr = whippet->MCR;	/* The DTR and RTS are located in the */
 				/* ModemControlRegister ...           */
 
-	return(
+	return (
 		((mcr & DTR) ? TIOCM_DTR : 0) |
 		((mcr & RTS) ? TIOCM_RTS : 0) |
 
-		((msr & DCD) ? 0 : TIOCM_CAR) | /* DCD is active low */
+		((msr & DCD) ? TIOCM_CAR : 0) |
 		((msr & CTS) ? TIOCM_CTS : 0) |
 		((msr & DSR) ? TIOCM_DSR : 0) |
 		((msr & RING_I) ? TIOCM_RNG : 0)
@@ -532,7 +568,7 @@
 			      int new_rts)
 {
 #if WHIPPET_DEBUG
-	printk("ser_set_modem()\n");
+	printk("ser_set_modem(dtr=%s, rts=%s)\n",(new_dtr == 0) ? "OFF" : "ON",(new_rts == 0) ? "OFF" : "ON");
 #endif
 
 	if (new_dtr == 0)	ser_DTRoff(whippet);
@@ -582,67 +618,115 @@
 /*	switch(cmd) {
 		case:
 	}*/
-	return(-ENOIOCTLCMD);
+	return -ENOIOCTLCMD;
 }
 
 /***** end of ser_ioctl() *****/
 
 
+/***** start of ser_reset_port() *****/
+
+void ser_reset_port(void)
+{
+#if WHIPPET_DEBUG
+	printk("ser_reset_port()\n");
+#endif
+/*
+ * Try and reset the serial port to a default state
+ */
+	whippet->IER = 0x00;	/* disable interrupts */
+	(void)whippet->IIR;	/* clear any pending misc interrupts */
+	(void)whippet->LSR;	/* clear any pending LSR interrupts */
+	(void)whippet->MSR;	/* clear any pending MSR interrupts */
+
+/*
+ * Set the serial port to a default setting of 8N1 - 9600
+ */
+	whippet->LCR = (data_8bit | DLAB);
+	whippet->DLM = 0;
+	whippet->DLL = 48;
+	whippet->LCR = (data_8bit);
+
+/*
+ * Set the rx FIFO-trigger count.
+ */
+	whippet->FCR = (RCVR_FIFO_RES | FIFO_ENA |
+			XMIT_FIFO_RES | fifo_trig_level );
+	whippet->MCR = 0;
+}
+
+/***** end of ser_reset_port() *****/
+
+
 /***** start of whippet_init() *****/
 
 /*
  * Detect and initialize any Whippet found in the system.
  */
 
+static int line;	/* The line assigned to us by register_serial() */
+
+static struct m68k_async_struct *amiga_info;	/* our async struct */
+
 int whippet_init(void)
 {
-int line;	/* The line assigned to us by register_serial() */
-
+unsigned long flags;
 struct serial_struct req;
 struct m68k_async_struct *info;
-	
+
 #if WHIPPET_DEBUG
 	printk("whippet_init()\n");
 #endif
-
 	if (!(MACH_IS_AMIGA))
 		return -ENODEV;
 
 	if ((amiga_model!=AMI_1200) && (amiga_model!=AMI_600))
 		return -ENODEV;
 
-	if (!(AMIGAHW_PRESENT(PCMCIA)))
+	if (!(AMIGAHW_PRESENT(PCMCIA)))	/* might be missing, you never know! */
 		return -ENODEV;
 
-	gayle=(struct GAYLE *)(zTwoBase + GAYLE_ADDRESS);
-	whippet=(struct WHIPPET *)(zTwoBase + WHIPPET_PHYSADDR);
-
-	printk("Probing for Whippet serial port... (v%s r%i - %s)\n",WHIPPET_VER, WHIPPET_REV, WHIPPET_DATE);
-
-/* Test gayle cardstatus bits for presence of a card */
+/*
+ * Initialise hardware structure pointers
+ */
+	gayle = (struct GAYLE *)(zTwoBase + GAYLE_ADDRESS);
+	whippet = (struct WHIPPET *)(zTwoBase + WHIPPET_PHYSADDR);
 
-	if (gayle->cardstatus & GAYLE_CS_CCDET) {
 #if WHIPPET_DEBUG
-		printk("PCMCIA Card detected\n");
+	printk("gayle->cardstatus = 0x%02x\n",gayle->cardstatus);
+	printk("gayle->intreq = 0x%02x\n",gayle->intreq);
+	printk("gayle->inten  = 0x%02x\n",gayle->inten);
+	printk("gayle->config = 0x%02x\n",gayle->config);
 #endif
-	} else {
+	printk("Probing for Whippet serial port... (v%s r%i - %s)\n",WHIPPET_VER, WHIPPET_REV, WHIPPET_DATE);
+
+/*
+ * Test gayle cardstatus bits for presence of a card
+ */
+	if (!(gayle->cardstatus & GAYLE_CS_CCDET)) {
 		printk("No PCMCIA Card detected\n");
 		return -ENODEV;
+#if WHIPPET_DEBUG
+	} else { printk("PCMCIA Card detected\n");
+#endif
 	}
 
-/* Card detected, but is it a Whippet??? Let's try and find out... */
-/* (is there a better test than this?)                             */
+/*
+ * Card detected, but is it a Whippet??? Let's try and find out...
+ */
 	{
 	u_char ch1,ch2;
-		whippet->SCR=0x42;
-		whippet->IER=0x00;
+		whippet->SCR = 0x42;
+		whippet->IER = 0x00;
 		ch1=whippet->SCR;	/* should be 0x42 */
-		whippet->SCR=0x99;
-		whippet->IER=0x00;
+		whippet->SCR = 0x99;
+		whippet->IER = 0x00;
 		ch2=whippet->SCR;	/* should be 0x99 */
 		if ((ch1!=0x42) || (ch2!=0x99)) return -ENODEV;
 	}
 
+	ser_reset_port();	/* initialise the serial port */
+
 /*
  * Set the necessary tty-stuff.
  */
@@ -655,75 +739,99 @@
 		return -EBUSY;
 	}
 
-	info = &rs_table[line];		/* set info == struct *m68k_async_struct */
+	info = &rs_table[line];	/* set info == struct *m68k_async_struct */
 
-	info->nr_uarts = 1;			/* one UART (necessary?) */
-	info->sw = &whippet_ser_switch;		/* switch functions      */
+	info->nr_uarts = 1;			/* one UART         */
+	info->sw = &whippet_ser_switch;		/* switch functions */
+	info->icount.cts = info->icount.dsr = 0;
+	info->icount.rng = info->icount.dcd = 0;
+	info->icount.rx = info->icount.tx = 0;
+	info->icount.frame = info->icount.parity = 0;
+	info->icount.overrun = info->icount.brk = 0;
 
-	/* Install ISR - level 2 - data is struct *m68k_async_struct */
+	amiga_info = info;	/* initialise our static async struct */
 
-	request_irq(IRQ_AMIGA_PORTS, ser_interrupt, 0, "whippet serial", info);
-
-
-/* try and reset the serial to some default state, cos gayle reset don't work */
-
-	whippet->IER = 0x00;
-	whippet->FCR = 0x00;
-	whippet->LCR = 0x00;
-	(void)whippet->LSR;	/* read */
-	(void)whippet->MSR;	/* read */
-	(void)whippet->IIR;	/* read */
-
-	whippet->IER = 0x00;
-	whippet->FCR = 0x00;
-	whippet->LCR = 0x00;
-	(void)whippet->LSR;	/* read */
-	(void)whippet->MSR;	/* read */
-	(void)whippet->IIR;	/* read */
+/*
+ * Clear any spurious interrupts in gayle
+ */
+	gayle->intreq = ((gayle->intreq & 0x6c) ^ 0x6c) | GAYLE_IRQ_IDE;
 
 /*
- * Set the uarts to a default setting of 8N1 - 9600
+ * Install ISR - level 2 - data is struct *m68k_async_struct
  */
+	request_irq(IRQ_AMIGA_PORTS, ser_interrupt, 0, "whippet serial", info);
 
-	whippet->LCR = (data_8bit | DLAB);
-	whippet->DLM = 0;
-	whippet->DLL = 48;
-	whippet->LCR = (data_8bit);
+	save_flags(flags);
+	cli();
+
+#if WHIPPET_DEBUG
+	printk("gayle->cardstatus = 0x%02x\n",gayle->cardstatus);
+	printk("gayle->intreq = 0x%02x\n",gayle->intreq);
+	printk("gayle->inten  = 0x%02x\n",gayle->inten);
+	printk("gayle->config = 0x%02x\n",gayle->config);
+#endif
 
 /*
- * Enable + reset both the tx and rx FIFO's.
- * Set the rx FIFO-trigger count.
+ * Enable status_change interrupts in gayle
  */
 
-	whippet->FCR = (FIFO_ENA | RCVR_FIFO_RES | XMIT_FIFO_RES | FIFO_TRIGGER_LEVEL );
+	gayle->inten |= GAYLE_IRQ_SC;
+	gayle->cardstatus = GAYLE_CS_WR | GAYLE_CS_DA;
+	gayle->config = 0;
 
+#if WHIPPET_DEBUG
+	printk("gayle->cardstatus = 0x%02x\n",gayle->cardstatus);
+	printk("gayle->intreq = 0x%02x\n",gayle->intreq);
+	printk("gayle->inten  = 0x%02x\n",gayle->inten);
+	printk("gayle->config = 0x%02x\n",gayle->config);
+#endif
 
-/* Wait for the uarts to get empty */
+	restore_flags(flags);
 
-	while(!((whippet->LSR) & TEMT))	{
 #if WHIPPET_DEBUG
-	printk("Waiting for transmitter to finish\n");
+	printk("Detected Whippet Serial Port at 0x%08x (ttyS%i)\n",(int)whippet,line);
 #endif
-	}
+	return 0;
+}
 
+/***** end of whippet_init() *****/
 
-/*
- * Disable all uart interrupts (they will be re-enabled in ser_init when
- *  they are needed).
- */
-	whippet->IER = 0x00;
 
-	gayle->intreq = ((gayle->intreq & 0x2c) ^ 0x2c) | 0xc0;
-	gayle->inten = GAYLE_IRQ_IDE | GAYLE_IRQ_SC;
-	gayle->cardstatus = GAYLE_CS_WR | GAYLE_CS_DA;	/* necessary?? */
-	gayle->config = GAYLE_CFG_100NS;
+/***** Module functions *****/
 
-/* Print confirmation of whippet detection (only if debug) */
+#ifdef MODULE
+int init_module(void)
+{
+	return whippet_init();
+}
 
+void cleanup_module(void)
+{
 #if WHIPPET_DEBUG
-	printk("Detected Whippet Serial Port at 0x%08x (ttyS%i)\n",(int)whippet,line);
+	printk("Closing Whippet Device!\n");
+#endif
+	unregister_serial(line);
+
+#if WHIPPET_DEBUG
+	printk("gayle->cardstatus = 0x%02x\n",gayle->cardstatus);
+	printk("gayle->intreq = 0x%02x\n",gayle->intreq);
+	printk("gayle->inten  = 0x%02x\n",gayle->inten);
+	printk("gayle->config = 0x%02x\n",gayle->config);
 #endif
-	return(0);
+	ser_reset_port();
+
+	gayle->cardstatus = 0;
+	gayle->intreq = ((gayle->intreq & 0x6c) ^ 0x6c) | GAYLE_IRQ_IDE;
+	gayle->inten &= GAYLE_IRQ_IDE;
+
+#if WHIPPET_DEBUG
+	printk("gayle->cardstatus = 0x%02x\n",gayle->cardstatus);
+	printk("gayle->intreq = 0x%02x\n",gayle->intreq);
+	printk("gayle->inten  = 0x%02x\n",gayle->inten);
+	printk("gayle->config = 0x%02x\n",gayle->config);
+#endif
+	free_irq(IRQ_AMIGA_PORTS,amiga_info);
 }
+#endif
 
-/***** end of whippet_init() *****/
+/***** end of Module functions *****/
diff -ur -X /root/exclude-file linux-2.2.0pre7/drivers/char/ser_whippet.h linux-2.2.0pre7patch/drivers/char/ser_whippet.h
--- linux-2.2.0pre7/drivers/char/ser_whippet.h	Tue Nov 24 23:49:31 1998
+++ linux-2.2.0pre7patch/drivers/char/ser_whippet.h	Sun Jan 31 19:43:19 1999
@@ -2,7 +2,7 @@
  * Defines for the Hisoft Whippet serial port for the Amiga 600/1200
  * range of computers.
  *
- * This code is (C) 1997,98 Chris Sumner (chris@barbecue.demon.co.uk),
+ * This code is (C) 1997,98 Chris Sumner (chris@cpsumner.freeserve.co.uk),
  * based on 16c552.h and ser_ioext.h which are (C) 1995 Jes Sorensen.
  * (jds@kom.auc.dk)
  */
@@ -10,27 +10,27 @@
 #ifndef _SER_WHIPPET_H_
 #define _SER_WHIPPET_H_
 
-#define UART_CLK (7372800)
-#define WHIPPET_BAUD_BASE (UART_CLK / 16)
+#define UART_CLK             7372800
+#define WHIPPET_BAUD_BASE   (UART_CLK / 16)
 
-#define WHIPPET_PHYSADDR (0xA30600)	/* from whippet.device */
+#define WHIPPET_PHYSADDR    (0xA30600)	/* from whippet.device */
 
 struct WHIPPET {
-	u_char	RBR;		/* Reciever Buffer Register */
-	u_char	pad0[0xfff];
-	u_char	IER;		/* Interrupt Enable Register */
+	u_char  RBR;		/* Reciever Buffer Register */
+	u_char  pad0[0xfff];
+	u_char  IER;		/* Interrupt Enable Register */
 	u_char  pad1[0xfff];
-	u_char	IIR;		/* Interrupt Identification Register */
-	u_char	pad2[0xfff];
-	u_char	LCR;		/* Line Control Register */
-	u_char	pad3[0xfff];
-	u_char	MCR;		/* Modem Control Register */
-	u_char	pad4[0xfff];
-	u_char	LSR;		/* Line Status Register */
-	u_char	pad5[0xfff];
-	u_char	MSR;		/* Modem Status Register */
-	u_char	pad6[0xfff];
-	u_char	SCR;		/* Scratch Register */
+	u_char  IIR;		/* Interrupt Identification Register */
+	u_char  pad2[0xfff];
+	u_char  LCR;		/* Line Control Register */
+	u_char  pad3[0xfff];
+	u_char  MCR;		/* Modem Control Register */
+	u_char  pad4[0xfff];
+	u_char  LSR;		/* Line Status Register */
+	u_char  pad5[0xfff];
+	u_char  MSR;		/* Modem Status Register */
+	u_char  pad6[0xfff];
+	u_char  SCR;		/* Scratch Register */
 };
 
 #define THR RBR   /* Transmitter Holding Register */
@@ -42,7 +42,7 @@
  * Bit-defines for the various registers.
  */
 
-/* IER - Interrupt Enable Register*/
+/* IER - Interrupt Enable Register */
 
 #define ERDAI         (1<<0)
 #define ETHREI        (1<<1)
@@ -58,11 +58,11 @@
 #define FIFO_ENA0     (1<<6) /* Both these are set when FCR(1<<0)=1 */
 #define FIFO_ENA1     (1<<7)
 
-#define IRQ_RLS  (IRQ_ID1 | IRQ_ID2)
-#define IRQ_RDA  (IRQ_ID2)
-#define IRQ_CTI  (IRQ_ID2 | IRQ_ID3)
-#define IRQ_THRE (IRQ_ID1)
-#define IRQ_MS   0
+#define IRQ_RLS   (IRQ_ID1 | IRQ_ID2)
+#define IRQ_RDA    IRQ_ID2
+#define IRQ_CTI   (IRQ_ID2 | IRQ_ID3)
+#define IRQ_THRE   IRQ_ID1
+#define IRQ_MS     0
 
 /* FCR - FIFO Control Register */
 
@@ -76,7 +76,9 @@
 #define FIFO_TRIG_1   0x00
 #define FIFO_TRIG_4   RCVR_TRIG_LSB
 #define FIFO_TRIG_8   RCVR_TRIG_MSB
-#define FIFO_TRIG_14  RCVR_TRIG_LSB|RCVR_TRIG_MSB
+#define FIFO_TRIG_14 (RCVR_TRIG_LSB | RCVR_TRIG_MSB)
+
+#define FIFO_SIZE     16
 
 /* LCR - Line Control Register */
 
diff -ur -X /root/exclude-file linux-2.2.0pre7/drivers/char/tty_io.c linux-2.2.0pre7patch/drivers/char/tty_io.c
--- linux-2.2.0pre7/drivers/char/tty_io.c	Sun Jan 31 01:38:47 1999
+++ linux-2.2.0pre7patch/drivers/char/tty_io.c	Sun Jan 31 19:38:45 1999
@@ -2142,7 +2142,7 @@
     defined(CONFIG_AMIGA_BUILTIN_SERIAL) || defined(CONFIG_GVIOEXT) || \
     defined(CONFIG_MULTIFACE_III_TTY) || defined(CONFIG_USERIAL) || \
     defined(CONFIG_MVME162_SCC) || defined(CONFIG_BVME6000_SCC) || \
-    defined(CONFIG_MAC_SCC) || defined(CONFIG_HPDCA) || defined(CONFIG_WHIPPET)
+    defined(CONFIG_MAC_SCC) || defined(CONFIG_HPDCA) || defined(CONFIG_WHIPPET_SERIAL)
 	rs_init();
 #endif
 #ifdef CONFIG_MAC_SERIAL

-- 
Chris Sumner

