/*
** $Source: /m/lerppu/u3/projects/Dec93/ohtatcp/amitcp/devices/rhslip/slip_device.h,v $
** $State: Exp $
** $Revision: 37.2 $
** $Date: 1992/08/25 16:43:51 $
** $Author: kcd $
**
** SANA-II Example device driver C include file
**
** (C) Copyright 1992 Commodore-Amiga, Inc.
*/

#include <exec/types.h>
#include <exec/devices.h>
#include <exec/ports.h>
#include <exec/semaphores.h>
#include <exec/memory.h>
#include <dos.h>
#include "devices/sana2.h"
#include <devices/serial.h>

/*
** Choose here if you want slip or compressed slip
*/
#ifndef CSLIP
#define CSLIP	1
#endif

#if CSLIP
#include "cslip.h"
#else
#define MAX_HDR     0
#endif

/*
** Stacksize and Priority of the Unit Process
*/
#define SLIP_STACKSIZE 4000
#define SLIP_PRI 5

/*
** Maximum Transmission Unit
*/
#define SLIP_MTU 1006
#define BUF_SLOP 4

/*
** Max # of Units allowed
*/
#define SD_MAXUNITS 8

/*
** Message passed to the Unit Process at
** startup time.
*/
struct StartupMessage
{
	struct Message	Msg;
	struct Unit	*Unit;
	struct Device	*Device;
};

/*
** Device Data Structure
*/
struct SLIPDevice
{
    struct Library	 sd_Device;
    UBYTE		 sd_Flags;
    UBYTE		 sd_Pad1;
    struct Library	*sd_SysBase;
    struct Library	*sd_DOSBase;
    ULONG		 sd_DosTag[10];
    BPTR		 sd_SegList;
    struct Unit 	*sd_Units[SD_MAXUNITS];
    struct SignalSemaphore sd_Lock;
    struct StartupMessage sd_Startup;
};

/*
** Typedef's for the SANA-II callback functions.
** Rhialto: It would be nice to specify the registers explicitly,
** instead of hoping the compiler options include ARGS=REGS, and that
** the compiler selected registers would match the requirements.
*/
#ifdef __SASC
#define ASM	      __asm
#define REG(x)        register __ ## x
#else
#error Please define ASM and REG for your compiler
#endif

typedef BOOL (*ASM SANA2_CFB)(REG(a0) APTR to, REG(a1) APTR from, REG(d0) LONG length);
typedef BOOL (*ASM SANA2_CTB)(REG(a0) APTR to, REG(a1) APTR from, REG(d0) LONG length);

struct BufferManagement
{
    struct MinNode	bm_Node;
    SANA2_CFB		bm_CopyFromBuffer;
    SANA2_CTB		bm_CopyToBuffer;
};

struct SuperS2PTStats
{
    struct MinNode		ss_Node;
    ULONG			ss_PType;
    struct Sana2PacketTypeStats ss_Stats;
};

/*
** Unit Data Structure
*/
struct SLIPDevUnit
{
    struct Unit 		 sdu_Unit;		/* Standard Unit Structure */
    UBYTE			 sdu_UnitNum;		/* Unit number */
    UBYTE			 sdu_Reserved0; 	/* Padding */
    struct Device		*sdu_Device;		/* Pointer to our device node */
    ULONG			 sdu_StAddr;		/* Our current address */
    ULONG			 sdu_HwAddr;		/* Our "hardware" address (Rhialto)*/
    ULONG			 sdu_BaudRate;		/* Serial baud rate */
    ULONG			 sdu_SerUnitNum;	/* Serial driver unit number */
    BOOL			 sdu_NoMore;		/* ??? */
    BOOL			 sdu_Escape;		/* SLIP Decode state */
    ULONG			 sdu_State;		/* Various state information */
    struct IOExtSer		*sdu_SerRx;		/* Serial IORequest for CMD_READ's */
    struct IOExtSer		*sdu_SerTx;		/* Serial IORequest for CMD_WRITE's */
    struct MsgPort		*sdu_RxPort;		/* Serial CMD_READ IORequest reply port */
    struct MsgPort		*sdu_TxPort;		/* Serial CMD_WRITE IORequest reply port */
    UBYTE			*sdu_RxBuff;		/* Buffer for holding decoded packets */
    UBYTE			*sdu_RxBuffPtr; 	/* Current place in decode buffer */
    UBYTE			*sdu_TxBuff;		/* Temporary buffer for hold unencoded outgoing packets */
    UBYTE			*sdu_RxSLIP;		/* Two buffers that hold packets encoded */
    UBYTE			*sdu_TxSLIP;		/* in SLIP format. */
    struct Process		*sdu_Proc;		/* NB: This points to the Task, not the MsgPort */
    struct SignalSemaphore	 sdu_ListLock;		/* A Semaphore for access to all of our queues. */
    struct MinList		 sdu_Rx;		/* Pending CMD_READ's */
    struct MinList		 sdu_RxOrph;		/* Pending CMD_READORPHAN's */
    struct MinList		 sdu_Tx;		/* Pending CMD_WRITE's */
    struct MinList		 sdu_Events;		/* Pending S2_ONEVENT's */
    struct SuperS2PTStats	*sdu_IPTrack;		/* For tracking IP packets */
    struct MinList		 sdu_Track;		/* List of packet types being tracked */
    struct MinList		 sdu_BuffMgmt;		/* List of Callback routines */
    struct Sana2DeviceStats	 sdu_Stats;		/* Global device statistics */
    UBYTE			 sdu_SerDevName[32];	/* Name of the serial driver to use */
#if CSLIP
    struct slcompress		 sdu_slcompress;
#endif
};

/*
** State bits for sdu_State
*/

#define SLIPUB_CONFIG 0
#define SLIPUB_ONLINE 1
#define SLIPUB_SETCONFIG 2
#define SLIPUB_CD 3
#define SLIPUB_EXCLUSIVE 4
#define SLIPUB_7WIRE 5

#define SLIPUF_CONFIG		(1<<SLIPUB_CONFIG)
#define SLIPUF_ONLINE		(1<<SLIPUB_ONLINE)
#define SLIPUF_SETCONFIG	(1<<SLIPUB_SETCONFIG)
#define SLIPUF_CD		(1<<SLIPUB_CD)
#define SLIPUF_EXCLUSIVE	(1<<SLIPUB_EXCLUSIVE)
#define SLIPUF_7WIRE		(1<<SLIPUB_7WIRE)

/*
** Device Name
*/

#if CSLIP
#define SLIPDEVNAME "rhcslip.device"
#else
#define SLIPDEVNAME "rhslip.device"
#endif
extern char SLIPName[];

/*
** Packet Encoding Bytes
*/

#define SLIP_END     192
#define SLIP_ESC     219
#define SLIP_ESC_END 220
#define SLIP_ESC_ESC 221

/*
** Compiler Magic
**
** (Rhialto) This is terrible!!! That people write code like this!
** How can you be sure the compiler won't use A6 for a register variable
** somewhere and make it unusable in the functions that it calls?
** (in fact, SAS/C 6.2 does something that, in ReadConfig..., when it
** first calls an Exec function and then a DOS function)
*/

#ifdef notdef
#define SLIPBase ((struct SLIPDevice *)__builtin_getreg(14))    /* Avoid the pre-processor problem */
#else
#define SLIPBase	ExtDeviceBase
#endif

#define SysBase 	(SLIPBase->sd_SysBase)
#define DOSBase 	(SLIPBase->sd_DOSBase)

