#define SWAB
#ifdef SWAB
#define XORBIT0(x)	((u_char *) (((unsigned long) (x))^1))
#define SWAPSHORT(x)	(swab(x))
#else SWAB
#define XORBIT0(x)	(x)
#define SWAPSHORT(x)	(x)
#endif SWAB


#define	OBUFSIZE	3056
#define IBUFSIZE	1024
#define NSMOCTLINES	8

#define BITFLAG(i)	(((u_char)1) << ((int) (i)))

#define IOPORTBASE		0x240
#define DMABASE			0xF40000
#define IOPORTTOUNIT(reg)	((((int)(reg)-MBIO_VA)-IOPORTBASE) >> 1)
#define SETSMOCTBASEPAGE   	(smoct_basepage = ((DMABASE >> pageshift) \
			| (chipType == CHIPTYPE_68020 ? V_NONCACHED : 0)))
#define MINORTOPHYPG(min)   	(((min) << 1) + smoct_basepage)
#define PHYPGINCR		2
#define ULTOMINOR(unit, line)	(((unit) << 3) + (line))
#define MINORTOUNIT(minor)	((minor) >> 3)
#define MINORTOLINE(minor)	((minor) & 0x7)



/* Errors (see table in manual): */
#define	ADDRESS	0x01	/* bit 0: USART Addressing Error */
#define	TIME	0x02	/* bit 1: USART Timeout Error */
#define	DATA	0x04	/* bit 2: USART Data Error */
#define	PARITY	0x08	/* bit 3: USART Found Parity Error */
#define	OVERRUN	0x10	/* bit 4: USART Found Overrun Error */
#define	FRAME	0x20	/* bit 5: USART Found Framing Error */


/* Commands */
enum smoct_cmd {
	UMODREG,	/* 00:	Set USART Mode Registers */
	UCMDREG,	/* 01:	Set USART Command Register */
	XONMASKEN,	/* 02:	Set XON/XOFF Mask/Enables */
	XONCHARS,	/* 03:	Set XON/XOFF Characters */
	SENDBLK0,	/* 04:	Send Block 0 */
	SENDBLK1,	/* 05:	Send Block 1 */
	SENDIMMED,	/* 06:	Send Immediate Character */
	SENDBRK,	/* 07:	Send Break */
	INPDLY,		/* 08:	Set Input Delay Time */
	INPHIWAT,	/* 09:	Set Input High Water Mark */
	IMMEDINT,	/* 0a:	Set Immediate Input Interrupt */
	INTSTATB0,	/* 0b:	Set Int on Status Bits 0 Mask */
	INTSTATB1,	/* 0c:	Set Int on Status Bits 1 Mask */
	INTINP,		/* 0d:	Set Interrupt -- Inputs */
	INTOUTP,	/* 0e:	Set Interrupt -- Outputs */
	INTSTAT,	/* 0f:	Set Interrupt -- Status */
	INTPAR,		/* 10:	Set Interrupt -- Parity Error */
	CLRINT,		/* 11:	Clear Interrupt */
	MULTLOCK	/* 12:	Allow Multibus Lock Operation */
};

/* Interrupt Source Flags */
#define	OUTPDONE	0x01	/* bit 0: output done interrupt */
#define	INPUT		0x02	/* bit 1: input interrupt */
#define	STATCHG		0x04	/* bit 2: status change interrupt */
#define	PARERRINT	0x08	/* bit 3: parity error interrupt */
#define	ANYINTR		0x0F	/* any of the above */

#ifdef SWAB
struct smoct {
	/* these have to be swabbed */
	char	so_obuf0[OBUFSIZE];	/* 0000: Output Buffer 0	*/
	char	so_obuf1[OBUFSIZE];	/* 0bf0: Output Buffer 1	*/
	char	so_ibuf[IBUFSIZE];	/* 17e0: Input Buffer		*/
	char	so_ebuf[IBUFSIZE];	/* 1be0: Error Buffer		*/

	/* the u_shorts below have to be swabbed */
	u_char	so_cmd;			/* 1fe1: Command Code		*/
	u_char	so_1fe0;		/* 1fe0: pad			*/
	u_short	so_cmddata;		/* 1fe3-2: Command Data		*/
	u_char	so_cmdstat;		/* 1fe5: Command Status		*/
	u_char	so_1fe4;		/* 1fe4: pad			*/
	u_char	so_usartstat;		/* 1fe7: Status from USART	*/
	u_char	so_1fe6;		/* 1fe6: pad			*/
	u_short	so_ifilptr;		/* 1fe9-8: Input Filling Pointer*/
	u_short	so_iempptr;		/* 1feb-a: Input Emptying Pointer*/
	u_short	so_rcvovfl;		/* 1fed-c: Receive Buffer Ovfl Count*/
	u_char	so_intsrc;		/* 1fef: Interrupt Source Flag	*/
	u_char	so_1fee;		/* 1fee: pad			*/
	u_char	so_obusy;		/* 1ff1: Output Busy		*/
	u_char	so_1ff0;		/* 1ff0: pad			*/
	u_char	so_ostopped;		/* 1ff3: Output Stopped		*/
	u_char	so_1ff2;		/* 1ff2: pad			*/
	u_char	so_parerr;		/* 1ff5: Parity Error		*/
	u_char	so_1ff4;		/* 1ff4: pad			*/
	u_char  so_1ff6_b[6];		/* 1ff6-b: pad			*/
	u_short	so_firmrev;		/* 1ffd-c: Firmware Revision Number */
	u_char	so_portintstat;		/* 1fff: Port Interrupt Status Flags */
	u_char	so_1ffe;		/* 1ffe: pad			*/
} *smoct;
#else SWAB
struct smoct {
	char	so_obuf0[OBUFSIZE];	/* 0000: Output Buffer 0	*/
	char	so_obuf1[OBUFSIZE];	/* 0bf0: Output Buffer 1	*/
	char	so_ibuf[IBUFSIZE];	/* 17e0: Input Buffer		*/
	char	so_ebuf[IBUFSIZE];	/* 1be0: Error Buffer		*/
	u_char	so_1fe0;		/* 1fe0: pad			*/
	u_char	so_cmd;			/* 1fe1: Command Code		*/
	u_short	so_cmddata;		/* 1fe2-3: Command Data		*/
	u_char	so_1fe4;		/* 1fe4: pad			*/
	u_char	so_cmdstat;		/* 1fe5: Command Status		*/
	u_char	so_1fe6;		/* 1fe6: pad			*/
	u_char	so_usartstat;		/* 1fe7: Status from USART	*/
	u_short	so_ifilptr;		/* 1fe8-9: Input Filling Pointer*/
	u_short	so_iempptr;		/* 1fea-b: Input Emptying Pointer*/
	u_short	so_rcvovfl;		/* 1fec-d: Receive Buffer Ovfl Count*/
	u_char	so_1fee;		/* 1fee: pad			*/
	u_char	so_intsrc;		/* 1fef: Interrupt Source Flag	*/
	u_char	so_1ff0;		/* 1ff0: pad			*/
	u_char	so_obusy;		/* 1ff1: Output Busy		*/
	u_char	so_1ff2;		/* 1ff2: pad			*/
	u_char	so_ostopped;		/* 1ff3: Output Stopped		*/
	u_char	so_1ff4;		/* 1ff4: pad			*/
	u_char	so_parerr;		/* 1ff5: Parity Error		*/
	u_char  so_1ff6_b[6];		/* 1ff6-b: pad			*/
	u_short	so_firmrev;		/* 1ffc-d: Firmware Revision Number */
	u_char	so_1ffe;		/* 1ffe: pad			*/
	u_char	so_portintstat;		/* 1fff: Port Interrupt Status Flags */
} *smoct;
#endif SWAB

u_char *smoct_ioport[NSMOCT];			/* one bit per channel */



/* params to smoct commands and other software slush */
struct smoct_param {
	u_short	sp_umodreg;	/* software copy of USART Mode Registers */
	u_char	sp_ucmdreg;	/* software copy of USART Command Register */
	u_char	sp_state;	/* buffer state */
	u_short sp_xonmasken;	/* XON/XOFF Mask/Enables in use */
	u_short	sp_xonchars;	/* XON/XOFF Characters (HOB is XON, LOB XOFF) */
	u_short sp_sendblk0;	/* Send Block 0 length */
	u_short	sp_sendblk1;	/* Send Block 1 length */
	u_short	sp_inpdly;	/* Input Delay Time */
	u_short	sp_inphiwat;	/* Input High Water Mark */
	u_short sp_immedint;	/* Immediate Input Interrupt mask/value */
	u_char	sp_intstatb0;	/* Intr on Status Bits 0 Mask */
	u_char	sp_intstatb1;	/* Intr on Status Bits 1 Mask */
	u_short	sp_intinp;	/* Interrupt level/vector -- inputs */
	u_short	sp_intoutp;	/* Interrupt level/vector -- outputs */
	u_short	sp_intstat;	/* Interrupt level/vector -- status */
	u_short sp_intpar;	/* Interrupt level/vector -- parity error */

	enum smoct_cmd	sp_lastocmd;	/* last output command sent */

} smoct_param[ULTOMINOR(NSMOCT,0)];



enum xo_enables {	/* XON/XOFF mask/enables */
	XONXOFF,	/* bit 0: respond to XON/XOFF */
	HIWATXOFF,	/* bit 1: send an XOFF if input passes high water mark */
	RTSCTL		/* bit 2: use RTS signal for flow control (don't use
			XON/XOFF if you use this) */

			/* the other bits don't mean anything */
};

/* for sp_state */
#define	BUF0USED	0x01
#define BUF1USED	0x02
#define BUF0THEN1	0x04	/* only meaningful when both buffers in use */
#define BUFSTATE	0x07
