/* ps_structs.h
 *
 * Definitions for the structured data types used in the SCSI Device Driver.
 *
 * $Header: /smsa/bsd:include/dev/ps_structs.h:bsd  1.22  $
 * $Source: /smsa/bsd:include/dev/ps_structs.h: $
 *
 * Copyright (c) 1989 Acorn Computers Ltd., Cambridge, England
 *
 */

#ifndef	__dev_ps_structs_h
#define	__dev_ps_structs_h

#ifndef	__sys_types_h
#include "../sys/types.h"
#endif
#ifndef	__sys_buf_h
#include "../sys/buf.h"
#endif

#define word_size(n) (((n)+3)&~3)

typedef struct { /* SCSI Command Descriptor */
  u_char  cdb[12];   /* command block                           */
  u_char  target;    /* logical device number                   */
  u_char  lun;       /* logical unit number                     */
  int     xfer;      /* number of bytes not transferred         */
  char   *addr;      /* ARM address for transfer                */
  int     flags;     /* state info for the command              */
} SCSI_Command;


#define SENSE      (20)
#define DEVICES     (7)
#define LUNS        (8)
#define MAX_SLOTS   (4)			/* a lot of flag words make this assumption */

typedef struct {
  char      *addr;
  int        len;
} Ptr;

typedef struct {
  Ptr            saved;    /* pointer values for restore          */
  Ptr            ptr;      /* current copy values                 */
  u_int		 base;     /* number of bytes in transfer         */
  u_char	 head;     /* start of chain of Podule Buffers    */
  u_char	 current;  /* which buffer is being filled        */
  u_char	 tail;     /* end of chain of allocated buffers   */
  u_char	 count;    /* number of buffers allocated         */
  u_char	 scratch;  /* scratch buffer                      */
  u_int		 flags;    /* ubiquitous                          */
} SCSI_Transfer;

/* flags for SCSI Transfer */
#define X_READ          (1<<0)
#define X_RESTORE       (1<<1)
#define X_COMPLETE      (1<<2)
#define X_INTERRUPT     (1<<3)
#define X_JUNK          (1<<4)
#define X_PREPARED      (1<<5)
#define X_COPYING       (1<<6)
#define X_NEEDS_RESTORE (1<<7)
#define X_DISCONNECTED  (1<<8)


typedef struct scsi_context *SCSI_ContextRef;	/* dummy */
typedef void (*Callback_Fn)(struct scsi_context *);

typedef struct scsi_context {	/* SCSI Context Descriptor */
  struct scsi_context *next;
  SCSI_Command         cmd;
  u_char               status;	/* command status                    */
       /* above handled by Hardware Irq Handler */
  u_char               sys;	/* id number of the issuing system   */
  SCSI_Transfer        xfer;	/* record of transfer                */
  int                  timeout;	/* timeout period for this cmd       */
  int                  retry;	/* number of times to try            */
  struct buf          *cbp;	/* buf to use for iodone()           */
  Callback_Fn          fn;	/* function to call on completion    */
  u_char               sense[SENSE]; /* sense information */
} SCSI_Context;

typedef struct {
  struct buf ibp;		/* private struct buf for use by
				   internal commands */
  struct buf *pending;		/* head of linked list of pending commands */
  SCSI_Context wc;		/* working context */
  SCSI_Context ic;		/* internal context */
  int io_cnt;			/* count of transfers */
  int s_current;		/* sort value of currently executing cmd */
  struct buf *sl_head;		/* start of sorting list */
  struct buf*sl_tail;		/* end of sorting list */
  u_char flags;
} SCSI_Cmd;

/*
 * flags for above structure
 */
#define C_BUSY		 (1 << 0)	/* private struct buf is in use */
#define C_LONG		 (1 << 1)	/* command is long lived */
#define C_RAISE_INACTIVE (1 << 2)	/* raise DEVICE_INACTIVE soft irq
					 * when command finishes */

typedef struct scsi_info {
  struct scsi_info   *next;
  char		      lun;	/* until this area is defined */
  u_short	      size;	/* size of the device specific record */
  int                 data;	/* scratch space for device */
  char               *rec;	/* device specific record */
} SCSI_Info;

typedef struct {
  SCSI_Context  *context;	/* chain of pending commands for this target */
  SCSI_Context  *failed;	/* points to a command which was unsatisfactory */
  u_char	 opening;	/* bitmap of luns in process of opening */
  u_char	 open_waiting;	/* bitmap of luns awaiting open mutex */
  u_char	 escape_open;	/* bitmap of luns that are open in
				   ESCAPE mode */
  u_char	 log_attention;	/* bitmap of luns that do not expect
				   unit ATTENTION */
  u_char	 info_valid;	/* bitmap of luns with valid info record */
  u_char	 busy;		/* bitmap of current business */
  u_char	 type;		/* device type */
  u_char	 flags;		/* state info for target */
  char		 dk_id;		/* unique id for index into disk info
				   tables (for iostat) */
  SCSI_Cmd      *LUN_Cmd[LUNS]; /* list of pending commands, one per lun */
  SCSI_Info      info;		/* chain of info records for attatched LUNs */
  SCSI_Context   req_sense;	/* used for performing internal request senses */
} SCSI_Target;

typedef SCSI_Context Connection[DEVICES];

/* SBIC Administration */
typedef struct {
  volatile u_char reg;
  u_char pad[3];
} SCSI_Reg;

typedef struct {
  union { /* control register */
    SCSI_Reg address;
    SCSI_Reg aux_status;
  } rc;
  SCSI_Reg rd; /* data register */
} SCSI_Chip;

/* Podule RAM allocation section */
#define SCSI_PAGE   0x01000
#define SCSI_RAM    0x10000
#define SCSI_PAGES  (SCSI_RAM / SCSI_PAGE)

typedef struct {
  int     count;		/* number of bytes of data in the buffer */
  u_char  next;			/* next page in the chain */
  u_char  flags;		/* obligatory */
} SCSI_Ram;

typedef struct scsi_system {
  int            id;		/* SCSI Podule Slot */
  SCSI_Chip     *chip;		/* address of the SBIC */
  int            h_state;	/* state of Hardware Irq Handler */
  int            s_state;	/* state of Soft Irq Handler */
  volatile u_char *dmac;	/* address of DMAC */
  int            d_state;	/* state of DMA Controller */
  SCSI_Context  *current;	/* currently active connection */
  SCSI_Context  *new_context;	/* fresh command */
  SCSI_Context  *complete;	/* completed connections */
  SCSI_Context  *connect[DEVICES]; /* potentially pending connections */
  SCSI_Target    target[DEVICES]; /* potentially attatched devices */
  SCSI_Ram       ram[SCSI_PAGES]; /* Podule RAM Allocation data structure */
  SCSI_Context   dummy;		/* dummy context for handling errors */
  u_char         command;       /* SBIC command to use (S&T or S&T w/ATN) */
  u_char	 active_targets; /* count of active targets */
} SCSI_Desc, *SCSI_System;

extern SCSI_System ps_sys[]; /* declaration of the global data structure */

/* SCSI Status Codes */
#define S_GOOD_STATUS           0x00
#define S_CHECK_CONDITION       0x02
#define S_TIMEOUT               0x04
#define S_BUSY                  0x08
#define S_RESERVATION_CONFLICT  0x10
#define S_EXPIRED               0x20
#define S_PARITY_ERROR          0x40
#define S_KILLED                0x80
#define S_ABORTED               0x81

#define min(a,b) ((a) < (b)) ? (a) : (b)

/* The SCSI trace package macros reside here because this .h file is included by all the source files */
#if 0
#define	SCSI_TRACE_SIZE	10000
#endif

#if	defined(SCSI_TRACE_SIZE)
#define SCSI_TRACE(s) ScsiTrace(s, __FILE__, __LINE__)
#define SCSI_TRACE_OPAQUE1(x0)          ScsiTraceOpaque(0x1,x0, 0, 0, 0,__FILE__,__LINE__)
#define SCSI_TRACE_OPAQUE2(x0,x1)       ScsiTraceOpaque(0x3,x0,x1, 0, 0,__FILE__,__LINE__)
#define SCSI_TRACE_OPAQUE3(x0,x1,x2)    ScsiTraceOpaque(0x7,x0,x1,x2, 0,__FILE__,__LINE__)
#define SCSI_TRACE_OPAQUE4(x0,x1,x2,x3) ScsiTraceOpaque(0xF,x0,x1,x2,x3,__FILE__,__LINE__)
#define SCSI_TRACE_TARGET(s, t_id, lun) ScsiTraceTarget(s, __FILE__, __LINE__, t_id, lun)
#define SCSI_TRACE_BUF(bp) ScsiTraceBuf(bp, __FILE__, __LINE__)
#define SCSI_TRACE_CMD(cmd) ScsiTraceCMD(cmd, __FILE__, __LINE__)
extern void ScsiTrace(), ScsiTraceTarget(), ScsiTraceBuf(),
  	ScsiTraceCMD(), ScsiTraceOpaque();
extern DumpTraceBuffer();
#else
#define SCSI_TRACE(s)
#define SCSI_TRACE_OPAQUE1(x0)
#define SCSI_TRACE_OPAQUE2(x0, x1)
#define SCSI_TRACE_OPAQUE3(x0, x1, x2)
#define SCSI_TRACE_OPAQUE4(x0, x1, x2, x3)
#define SCSI_TRACE_TARGET(s, t_id, lun)
#define SCSI_TRACE_BUF(bp)
#define SCSI_TRACE_CMD(cmd)
#endif SCSI_TRACE_SIZE

#endif/*__dev_ps_structs_h*/

/* EOF ps_structs.h */
