/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = SCSIADD.H
 *
 * DESCRIPTIVE NAME = IBM2SCSI.ADD - Adapter Driver for IBM scsi adapters.
 *                    Main header file.
 *
 *
 * VERSION = V2.0
 *
 * DATE
 *
 * DESCRIPTION  Defines ADD stuff (great word, stuff)
 *
 *
*/


/*--------------------------------------------------------------------*/
/*   Debug macros                                                     */
/*--------------------------------------------------------------------*/


#ifdef INFORM
   #define INFMSG(msg)                          \
      dprintf((char far *)msg);
#else
   #define INFMSG(msg)
#endif


#ifdef DEBUG
   #define ERRMSG(msg)                          \
      dprintf((char far *)msg);                 \
      _asm {int 3};
#else
   #define ERRMSG(msg)
#endif


#ifdef INFORM
   #define INFMSG1(msg,p1)                      \
      dprintf((char far *)msg,p1);
#else
   #define INFMSG1(msg,p1)
#endif

#ifdef INFORM
   #define PRTBUF(b,l)                          \
      dprintf("%z\n\r",b,l);
#else
   #define PRTBUF(msg)
#endif

#ifdef DEBUG
   #define ERRMSG1(msg,p1)                      \
      dprintf((char far *)msg,p1);              \
      _asm {int 3}
#else
   #define ERRMSG1(msg,p1)
#endif

#ifdef DEBUG
   #define DBSTOP()                             \
      _asm {int 3}
#else
   #define DBSTOP()
#endif


/*---------------------------------------------------------------------------*/
/*     BUG     BUG     BUG     BUG     BUG     BUG     BUG     BUG     BUG   */
/*                                                                           */
/* The following macro which is used to turn on and off the diagnostic panel */
/* rightmost light as a disk activity light incorporates an output to port   */
/* 4fh.  This fixes a planar problem on the model 95 which causes an         */
/* unexplanable trap in this device driver.  DO NOT REMOVE THEM !!!!!        */
/*                                                                           */
/*     BUG     BUG     BUG     BUG     BUG     BUG     BUG     BUG     BUG   */
/*---------------------------------------------------------------------------*/

#define SAVE_REGS  _asm {              \
                      _asm pushf       \
                      _asm cli         \
                      _asm push  ax    \
                      _asm push  dx    \
                   }

#define RESTORE_REGS  _asm {           \
                         _asm pop  dx  \
                         _asm pop  ax  \
                         _asm popf     \
                      }


#define SETPANEL(val)  _asm {                   \
                        _asm mov   al, (val)    \
                        _asm mov   dx, 108h     \
                        _asm out   dx, al       \
                        _asm mov   dx, 4fh      \
                        _asm out   dx, al       \
                        _asm out   dx, al       \
                        _asm out   dx, al       \
                        _asm out   dx, al       \
                       }

#define  DISK_ACTIVITY_LED_ON               \
      _asm {                                \
         _asm mov  dx, 92h                  \
         _asm in   al, dx                   \
         _asm or   al, ledmask_on           \
         _asm out  dx, al                   \
      }

#define  DISK_ACTIVITY_LED_OFF              \
      _asm {                                \
         _asm mov  dx, 92h                  \
         _asm in   al, dx                   \
         _asm and  al, ledmask_off          \
         _asm out  dx, al                   \
      }

#define LED_ON(npDCB)                                     \
                                                          \
   if ((npDCB)->UnitInfo.UnitType == UIB_TYPE_DISK) {     \
      SAVE_REGS;                                          \
      DISK_ACTIVITY_LED_ON;                               \
      LedCnt++;                                           \
      if (ADDStatus & LED) {                              \
         SETPANEL(0ffh);                                  \
      }                                                   \
      RESTORE_REGS;                                       \
   }


#define LED_OFF(npDCB)                                   \
                                                         \
   if ((npDCB)->UnitInfo.UnitType == UIB_TYPE_DISK) {    \
      SAVE_REGS;                                         \
      if (LedCnt>0) LedCnt--;                            \
      if (!LedCnt) {                                     \
         DISK_ACTIVITY_LED_OFF;                          \
         if (ADDStatus & LED) {                          \
            SETPANEL(020h);                              \
         }                                               \
      }                                                  \
      RESTORE_REGS;                                      \
   }


#define CLI()     _asm{cli}
#define STI()     _asm{sti}
#define CLC()     _asm{clc}
#define STC()     _asm{stc}

#define SAVEIF()    _asm{                \
                      _asm   pushf       \
                      _asm   cli         \
                    }

#define RESTOREIF() _asm{popf}

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

#define TRACE(e,p) if (TraceIORBs) Trace(e,p);


/*-------------------------------------------------------------------*/
/* Macro to build a control element.  Note that it will set the no   */
/* disconnect bit if the adapter has only one device attached.  Some */
/* control elements don't have this bit defined.  In those cases do  */
/* not use this macro.                                               */
/*-------------------------------------------------------------------*/

#define INITCTRLEL(el,sz,fn,npdcb,piorb)                                      \
                                                                              \
   el.ReqH.length       = sz;                                                 \
   el.ReqH.type         = 0;                                                  \
   el.ReqH.rsvd1        = 0;                                                  \
   el.ReqH.ci           = fn;                                                 \
   el.ReqH.dstid        = (ACBTbl[npdcb->ai].unit << 8) + npdcb->EntityID;    \
   el.ReqH.srcid        = SYSTEM_UNIT;                                        \
   el.ReqH.corrid       = (ULONG)piorb;                                       \
   el.ReqH.optctrl      = (ACBTbl[npdcb->ai].cDev == 1 &&                     \
                          !(ACBTbl[npdcb->ai].np1stDCB->status & UNITCMDQ)) ? \
                             OP_ND : 0;



#define INITARSENSE(el,piorb,npdcb)                                   \
                                                                      \
   if (((PIORB)piorb)->RequestControl & IORB_REQ_STATUSBLOCK) {       \
      InitAutoReqSense((PIORB)piorb,(PSTDHEAD)&el,npdcb);             \
   }                                                                  \
   else {                                                             \
      el.ReqH.optctrl        |= OP_ARSENSE;                           \
      el.arsense.ppSenseData = ppData + (USHORT)&(npdcb->SenseData);  \
      el.arsense.cSenseBytes = sizeof(SCSI_REQSENSE_DATA);            \
   }


#define LOGSYSTEMERROR() ;

#define CLEAREXCP(ai) WriteReg(ACBTbl[(ai)].baseIO+REG_BCR, \
                        (ReadReg(ACBTbl[(ai)].baseIO+REG_BCR) | BCR_CLREXCP))

/*--------------------------------------------------------------------*/
/*   Forward typedefs                                                 */
/*--------------------------------------------------------------------*/

typedef struct _SCBH NEAR *NPSCBH;
typedef struct _CALLTBL  CALLTBL, NEAR *NPCALLTBL;

/**********************************************************************/
/*   Local structure types                                            */
/**********************************************************************/

/*--------------------------------------------------------------------*/
/* SCB pool structures.                                               */
/*--------------------------------------------------------------------*/

typedef struct _SCBCTRL {
   NPSCBH      npNextSCBH;   /* ptr to next SCB control block         */
   USHORT      status;       /* SCB entry status                      */
   ULONG       ppSCB;        /* physical address of this SCB entry    */
   PIORB       pIORB;        /* ptr to owning IORB                    */

}  SCBCTRL;

typedef struct _SCBH {       /* SCB control structure (used in SCB pool) */

   SCBCTRL     scbctrl;      /* SCB pool control header                  */
   SCB         scb;          /* actual SCB                               */

} SCBH;

/* SCB status equates. */

#define DCBSCB      0x0001   /* this is the dev table SCB entry          */

/*---------------------------------------------*/
/* Device Control Block (DCB).                 */
/*---------------------------------------------*/

typedef struct _DCB {

   UNITINFO           UnitInfo;     /* ADD device unitinfo structure          */
   USHORT             state;        /* current device state                   */
   USHORT             status;       /* current unit status                    */
   PIORB              pActiveIORB;  /* ptr to the active IORB group           */
   PIORB              pWorkQ;       /* ptr to the IORB queue                  */
   PIORB              pDevCtrlIORB; /* ptr to device control IORB             */
   ULONG              Timeout;      /* timeout value for device (locate mode) */
   ULONG              cSectors;     /* Disk sectors                           */ /*@V95775*/
   ULONG              cCylinders;   /* disk cylinders                         *//*@V95775*/
   USHORT             cHeads;       /* Disk heads                             *//*@V95775*/
   USHORT             spt;          /* Disk sectors per track                 *//*@V95775*/
   USHORT             cbps;         /* bytes per sector                       *//*@V95775*/

   UCHAR              ldn;          /* logical device number (locate mode)    */
   UCHAR              isr;          /* ISR for this interrupt (locate mode)   */
   UCHAR              bus;          /* adapter bus (move mode)                */
   UCHAR              EntityID;     /* Entity ID   (move mode)                */

   NPCALLTBL          npCallTbl;    /* ptr IORB call table                    */
   USHORT             ai;           /* adapter index into ACB table array     */

   PSCB               pFailSCB;     /* far ptr to failing SCB (locate mode)   */

   PUNITINFO          pChangedInfo; /* ptr to changed unit info               */
   SCBH               ResSCBH;      /* reserved SCB                           */
   SCB                SenseSCB;     /* GetSense data SCB                      */
   TSB                tsb;          /* Command Complete Status Block (TSB)    */
   SCSI_REQSENSE_DATA SenseData;    /* our own sense data area                */

} DCB, near *NPDCB;

/* status equates */

#define  UNITTODISABLED    0x0001    /* adapter timeout disabled              */
#define  UNITCMDQ          0x0002    /* supports command queueing             */
#define  UNITPOFF          0x0004    /* power off                             */
#define  UNITSCBBUSY       0x0008    /* reserved SCB is in use                */
#define  UNITALLOCATED     0x0010    /* unit allocated                        */
#define  UNITDEVCTRL       0x0020    /* some device control IORB is active    */
#define  UNITCHANGED       0x0040    /* info has been changed                 */
#define  UNITWIDE          0x0080    /* unit is a wide (16 bit) unit          */
#define  UNITLOCKED        0x0100    /* unit media has been locked            */
#define  UNITNOSYNC        0x0200    /* unit should send no synchrounous msgs */
#define  UNITRESTART       0x0400    /* unit is restarting                    */
#define  UNITGMTRYSET      0x0800    /* unit disk geometry calculated         *//*@V95775*/

/* state equates */

#define  IDLE              0x0000  /* idle                                    */
#define  WAITONINT         0x0001  /* work started, waiting on interrupt      */
#define  WAITONSENSE       0x0002  /* waiting for int to get sense data       */
#define  WAITONABORT       0x0003  /* waiting for int on an abort             */
#define  WAITONRESET       0x0004  /* wait for an int on a reset              */
#define  WAITONSETTIMEOUT  0x0005  /* waiting for int on set timeout          */
#define  WAITONSTARTUNIT   0x0006  /* wait for int on start unit              */


/*------------------------------*/
/* Adapter Control Block (ACB)  */
/*------------------------------*/

typedef struct _ACB {

   USHORT      id;          /* adpater ID (POS)                               */
   USHORT      status;      /* adapter status flags                           */
   USHORT      unit;        /* unit # for move mode                           */
   USHORT      baseIO;      /* Base I/O address                               */
   USHORT      cDev;        /* count of devices on this adapter               */
   USHORT      cBus;        /* count of busses on this adapter                */
   UCHAR       iBus;        /* internal bus information                       */
   UCHAR       eBus;        /* external bus information                       */
   ULONG       ph;          /* pipe handle for move mode                      */
   NPDCB       np1stDCB;    /* ptr to first DCB                               */
   USHORT      uCodeLevel;  /* uCode level on card                            */
   USHORT      AFlags;      /* ADD adapterinfo flags                          */
   UCHAR       isr;         /* isr from last interrupt                        */
   UCHAR       bsr;         /* bsr from last interrupt                        */
   UCHAR       TargetID;    /* SCSI Target ID for adapter                     */
   UCHAR       resetcount;  /* counter for ldn assgns for reset (locate mode) */
   USHORT      cCmds;       /* # overlapped I/O commands (corvette)           */
   USHORT      slot;        /* slot, 0-planar (-1 unknown)                    *//*@D2623*/

} ACB, near *NPACB;


/* Adapter Status flags (status) */

#define RESETINPROGRESS   0x0001 /* adapter reset sequence is in progress    */
#define RESETCOMPLETE     0x0002 /* adp reset int recvd, reset in progress   */
#define ENABLEMOVEMODE    0x0004 /* attempt to enable move mode (init time)  */
#define ADAPTERDEFECTIVE  0x0008 /* adapter is defective                     */
#define MOVEMODE          0x0010 /* adapter is operating in move mode        */
#define PIPEREG           0x0020 /* pipe has been registered w/delivery srv  */
#define UNITNUMALLOC      0x0040 /* unit # allocated by delivery service     */
#define PROCESS_SIGNAL    0x0080 /* currently processing a move mode signal  */
#define OPINPROGRESS      0x0100 /* some adapter operation in progress       */

/* Bus information (iBus & eBus) */

#define BUS_WIDE            0x01   // bus is wide (16 bit)
#define BUS_FAST            0x02   // bus is fast (synchronous)

/*-----------------------------------*/
/* ADD workspace area in the IORB.   */
/* For locate mode use ADDAREA, for  */
/* move mode use ADDAREA2.           */
/*-----------------------------------*/

typedef struct _ADDAREA {
   USHORT        Status;          /* IORB ADD status bits                     */
   NPSCBH        npSCBH;          /* ptr to 1st SCB attached to this IORB     */
   USHORT        cRetries;        /* # of retries left before error           */
   USHORT        cSCBs;           /* count of SCBs attached to this IORB      */
   USHORT        cSGs;            /* # of SG groups of 16 processed (alloc)   */
   USHORT  (NEAR *npfnCallOut)(); /* ptr to call out routine (local work TBD) */
   ULONG         NextRBA;         /* next RBA to process for incomplete req.  */

} ADDAREA, far *PADDAREA;

typedef struct _ADDAREA2 {

   USHORT        Status;          /* IORB ADD status bits                     */
   NPDCB         npDCB;           /* DCB for this IORB                        */
   USHORT        cRetries;        /* number of retries left before error      */
   USHORT        cEl;             /* count of elements completed (++ on int)  */
   USHORT        R1;              /* unused                                   */
   USHORT  (NEAR *npfnCallOut)(); /* ptr to call out routine (local work TBD) */
   USHORT  (NEAR *npfnPass)();    /* rtne to call if element ends w/o error   */
   USHORT  (NEAR *npfnFail)();    /* rtne to call if element ends with error  */

} ADDAREA2, far *PADDAREA2;

/* Status defines for IORB status in ADDWorkSpace (in IORB) */

#define IORBLAST        0x0001  /* this is last IORB in logical group         */
#define IORBINCOMPLT    0x0002  /* The IORB is not fully ready                */
                                /*   if 0 then the IORB is fully ready        */
                                /*      1 then not fully ready.               */
#define IORBUSERSENSBUF 0x0004  /* Sense data written to user buffer          */
#define IORBCALLOUT     0x0008  /* npfnCallOut should be called               */
#define IORBSCBLONG     0x0010  /* 1st SCB is a long SCB                      */
#define IORBABORTDONE   0x0020  /* an abort has been issued once              */
#define IORBCALLOUTERR  0x0040  /* do IORB callout even if error found        */
#define IORBPASSTHRUSCB 0x0080  /* IORB is passthru SCB                       */
#define IORBNOGROUP     0x0100  /* Don't group this IORB with others          */
#define IORBRESTARTQ    0x0200  /* send reactivate bit for move mode queue    */
#define IORBSTARTING    0x0400  /* IORB is in process of being started        */
#define IORBINTERRUPT   0x0800  /* IORB has received interrupt (multi-stage)  */

/* macro for accessing the workspace in the iorb.  */

#define IORBWRKSP(ptr,field)                                 \
   ((PADDAREA)((PIORB)##ptr)->ADDWorkSpace)->##field

#define IORBWRKSP2(ptr,field)                                \
   ((PADDAREA2)((PIORB)##ptr)->ADDWorkSpace)->##field


/*-------------------------------------------*/
/* Trace buffer event record for debug trace */
/*-------------------------------------------*/

typedef struct _TRACEINFO {
   USHORT event;                  /* trace event        */
   USHORT unit;                   /* unit               */
   PIORB  pIORB;                  /* IORB               */
   UCHAR  cm;                     /* command modifier   */
   UCHAR  cc;                     /* command code       */
   USHORT status;                 /* IORB status field  */
   USHORT ec;                     /* IORB error field   */
   NPSCBH npSCBH;                 /* SCB (our header)   */

} TRACEINFO, near *NPTRACEINFO;

/* Events for tracing (event field) */

#define  TR_RECEIVED     0x0001
#define  TR_QUEUED       0x0002
#define  TR_DEQUEUED     0x0003
#define  TR_STARTED      0x0004
#define  TR_FINISHED     0x0005


/*-------------------------------------------*/
/* Call table structure for IORB call table  */
/*-------------------------------------------*/

typedef struct _CALLTBL {
   USHORT        control;         /* control bits                       */
   USHORT        maxcm;           /* maximum command modifier supported */
   USHORT  (NEAR *npFunc)();      /* function pointer                   */

}  CALLTBL, NEAR *NPCALLTBL;

/* control bits */

#define  NEEDDCB     0x0001  /* DCB is needed for this command          */
#define  NEEDALLOC   0x0002  /* unit must be allocated for this command */

#define  DFLTCTRL       NEEDDCB+NEEDALLOC

/*-------------------------------------------------*/
/* DD table for info filled in by DevHelp_AttachDD */
/*-------------------------------------------------*/

typedef struct _DDTABLE {

   CHAR    res1[6];                /* old real mode stuff  */
   USHORT  (FAR *DeliveryADD)();   /* entry point          */
   USHORT  pDS;                    /* DS value for DD      */

} DDTABLE, NEAR *NPDDTABLE;

/*------------------------------------*/
/* EBDA Dynamic area header structure */
/*------------------------------------*/

typedef struct _EBDAHDR {

   NPBYTE   NextHdr;      /* offset to next header        */
   USHORT   AdpID;        /* Adapter ID/block identifier  */

} EBDAHDR, FAR *PEBDAHDR;

/*-----------------*/
/* SCSI data table */
/*-----------------*/

typedef struct _SCSIDATATBL {

   EBDAHDR  ebdahdr;     /* dynamic data area header                         */
   UCHAR    cAdapters;   /* count of instances                               */
   UCHAR    LastStat;    /* last CBIOS status                                */
   UCHAR    FirstDrive;  /* 1st scsi drive unit (normally 80h)               */
   UCHAR    cDrives;     /* count of scsi drives installed                   */
   UCHAR    ledmask;     /* LED mask                                         */
   UCHAR    cOther;      /* count of non hardfile devices                    */
   USHORT   DriveTbl;    /* offset from start of data table to drive info    */
   USHORT   OtherTbl;    /* offset from start of table to other device info  */
   ULONG    Int76Chain;  /* IRQ 14h vector save area                         */
   UCHAR    presence;    /* presence indicators                              */
   UCHAR    cTypes;      /* count of unique device types installed           */
   USHORT   TypeTbl;     /* offset from start of table to the type table     */

} SCSIDATATBL, FAR *PSCSIDATATBL;

#define    LEDMASK     0xc0     /* led mask bits       */

/*------------------------------------------------------------------*/
/* SCSI instance information records. Adapter specific information. */
/* The second one is for the new table format.                      */
/*------------------------------------------------------------------*/

typedef struct _SCSIADPINFO {

   UCHAR    status;     /* current status                                    */
   UCHAR    dmaarb;     /* DMA arbitration level                             */
   UCHAR    isr;        /* last interrupt status register value              */
   UCHAR    maxbusy;    /* max time busy active after power on reset (1 s)   */
   UCHAR    intoff;     /* time from EOI to interrupt inactive (1 us)        */
   UCHAR    cardio;     /* address select byte (added to 3540h for actual)   */
   USHORT   pwait;      /* max wait time limit for c/abios                   */
   USHORT   drgt;       /* synchrounous data rate and global command t/o     */
   USHORT   scatgat;    /* offset from start of table to scatter gather area */
   UCHAR    scb[36];    /* scb buffer                                        */
   UCHAR    tsb[32];    /* tsb buffer                                        */

} SCSIADPINFO, FAR *PSCSIADPINFO;

typedef struct _SCSIADPINFO2 {                                                  /*@D2623*/
                                                                                /*@D2623*/
   UCHAR    status;     /* current status                                    */ /*@D2623*/
   UCHAR    rsvd;       /* reserved for word alignment                       */ /*@D2623*/
   UCHAR    dmaarb;     /* DMA arbitration level                             */ /*@D2623*/
   UCHAR    isr;        /* last interrupt status register value              */ /*@D2623*/
   UCHAR    maxbusy;    /* max time busy active after power on reset (1 s)   */ /*@D2623*/
   UCHAR    intoff;     /* time from EOI to interrupt inactive (1 us)        */ /*@D2623*/
   USHORT   cardio;     /* address select byte (added to 3540h for actual)   */ /*@D2623*/
   UCHAR    slot;       /* slot information                                  */ /*@D2623*/
   UCHAR    info;       /* card information byte                             */ /*@D2623*/
   USHORT   pwait;      /* max wait time limit for c/abios                   */ /*@D2623*/
   USHORT   drgt;       /* synchrounous data rate and global command t/o     */ /*@D2623*/
   USHORT   scatgat;    /* offset from start of table to scatter gather area */ /*@D2623*/
   UCHAR    scb[36];    /* scb buffer                                        */ /*@D2623*/
   UCHAR    tsb[32];    /* tsb buffer                                        */ /*@D2623*/
                                                                                /*@D2623*/
} SCSIADPINFO2, FAR *PSCSIADPINFO2;                                             /*@D2623*/

/* status defines  */

#define CORVETTE  0x80     /* this is a corvette adapter */
#define SYSINT    0x40     /* interrupt has occurred     */
#define CIP       0x20     /* command is in progress     */
#define RIP       0x10     /* Reset in progress          */
#define RETRIES   0x08     /* retries enabled            */
#define IBEN      0x04     /* intelligent buffer enabled */
#define IB        0x02     /* buffer supported           */
#define USABLE    0x01     /* adapter is usable          */

/* slot info byte */

#define SLOT_PSEUDO  0x80  /* instance in a pseudo slot (planar)   */           /*@D2623*/
#define SLOT_RSVD    0x70  /* reserved.                            */           /*@D2623*/
#define SLOT_NUMBER  0x0f  /* slot # (0 indicates planar)          */           /*@D2623*/


/*---------------------------------------------------------------*/
/* Device Information Records. Each scsi device has one of these */
/* Size changed to 5 bytes to support SCSI 2 table format.  For  */
/* old table just use 1st 4 bytes.                               */
/*---------------------------------------------------------------*/

typedef struct _DIR {

   UCHAR    dir[5];        /* 5 byte entry (no real field names)        */

} DIR, FAR *PDIR;

#define DEVNUM  0xf0  /* byte 0 - logical device number                     */
#define RM      0x08  /* byte 0 - removable media (when set)                */
#define CARDNUM 0x07  /* byte 0 - card number (instance index)              */
#define BIG     0x80  /* byte 1 - big hardfile indicator (rsvd in SCSI 2)   */
#define LUN     0x70  /* byte 1 - scsi LUN                                  */
#define RSVD1   0x08  /* byte 1 - reserved                                  */
#define PUN     0x07  /* byte 1 - scsi target ID (PUN)                      */
#define PUN_2   0x0f  /* byte 1 - scsi target ID for SCSI 2 table           */  /*@D2623*/
#define NPO     0x80  /* byte 2 - not powered on (never set)                */
#define DEFECT  0x40  /* byte 2 - device is defective                       */
#define HARDBCR 0x20  /* byte 2 - hard bcr in progress                      */
#define TOBCR   0x10  /* byte 2 - timeout bcr in progress                   */
#define REQACT  0x08  /* byte 2 - request is active                         */
#define ALLOC   0x04  /* byte 2 - device has been allocated                 */
#define BUFFER  0x02  /* byte 2 - intelligent buffer enabled                */
#define TOG     0x01  /* byte 2 - toggle bit for CBIOS                      */
#define GTRES   0x80  /* byte 3 - global timeout resolution (0 sec, 1 min)  */
#define GTOV    0x7f  /* byte 3 - global timeout value                      */
#define RSVD2   0xf0  /* byte 4 - SCSI 2 reserved                           */  /*@D2623*/
#define BUSNUM  0x0f  /* byte 4 - SCSI 2 bus number (0-internal,1-external) */  /*@D2623*/

/*---------------------------*/
/* POS information structure */
/*---------------------------*/

typedef struct _POSINFO {

   USHORT id;           /* adapter ID                                       */
   UCHAR  pr3;          /* POS register 3                                   */
   UCHAR  pr2;          /* POS register 2                                   */
   UCHAR  irq;          /* IRQ level                                        */
   UCHAR  pr4;          /* POS register 4                                   */
   USHORT slot_rev;     /* slot size (bits 15-12) and revision level (11-0) */
   UCHAR  cLunsDev;     /* # LUNs per device                                */
   UCHAR  cDevSup;      /* # of devices supported                           */
   UCHAR  pacing;       /* DMA pacing factor                                */
   UCHAR  cLDNs;        /* number of LDNs supported (16)                    */
   UCHAR  eoioff;       /* us wait for eoi to adapter and eoi to system     */
   UCHAR  maxbusy;      /* max busy for reset in seconds                    */
   USHORT ibs;          /* intelligent buffer status                        */
   USHORT retry;        /* retry status                                     */
   UCHAR  pr4b;         /* POS register 4b                                  */
   UCHAR  pr3b;         /* POS register 3b                                  */
   UCHAR  pr6;          /* POS register 6                                   */
   UCHAR  pr5;          /* POS register 5                                   */
   USHORT cCmds;        /* number of overlapped commands allowed            */

} POSINFO, FAR *PPOSINFO, NEAR *NPPOSINFO;


/*-------------------------------------------------------*/
/* Structure for Corvette surrogate and signalling areas */
/*-------------------------------------------------------*/

typedef struct _CTRLAREA {

   USHORT ssf;             /* surrogate start of free      */
   USHORT ses;             /* surrogate enqueue status     */
   USHORT sse;             /* surrogate start of elements  */
   USHORT sds;             /* surrogate dequeue status     */
   ULONG  signal;          /* signalling area              */

} CTRLAREA, NEAR *NPCTRLAREA;

/*--------------------------------------------------------*//*@V95775*/
/* Master boot record structures.                         *//*@V95775*/
/*--------------------------------------------------------*//*@V95775*/
                                                            /*@V95775*/
                                                            /*@V95775*/
typedef struct _PARTITIONENTRY                              /*@V95775*/
{                                                           /*@V95775*/
   UCHAR        BootIndicator;                              /*@V95775*/
   UCHAR        BegHead;                                    /*@V95775*/
   USHORT       BegSector:6;                                /*@V95775*/
   USHORT       BegCylinder:10;                             /*@V95775*/
   UCHAR        SysIndicator;                               /*@V95775*/
   UCHAR        EndHead;                                    /*@V95775*/
   USHORT       EndSector:6;                                /*@V95775*/
   USHORT       EndCylinder:10;                             /*@V95775*/
   ULONG        RelativeSectors;                            /*@V95775*/
   ULONG        NumSectors;                                 /*@V95775*/
} PARTITIONENTRY;                                           /*@V95775*/
                                                            /*@V95775*/
typedef struct _MBR                                         /*@V95775*/
{                                                           /*@V95775*/
   UCHAR          Pad[0x1BE];                               /*@V95775*/
   PARTITIONENTRY PartitionTable[4];                        /*@V95775*/
   USHORT         Signature;                                /*@V95775*/
} MBR;                                                      /*@V95775*/


/*--------------------------------------------------------------------------*/
/* macro to start/update the adapter timeout value.  If the value is > than */
/* the current timer value then update the timer value, otherwise ignore it */
/*--------------------------------------------------------------------------*/

#define STARTTIMEOUT(ai,val)                   \
   if ((val) > *(Timers+(ai))) {               \
      *(Timers+(ai)) = (val);                  \
   }

/**********************************************************************/
/*   Local defines and constants                                      */
/**********************************************************************/

#define MAX_SUPPORTED_ADAPTERS   8        /* max # supported adptrs REN5274 */

#define TRANSCB    ABFC_SCSIP_TRANSFER_SCB
#define RB_TSCB    NPABRB_SCSIP_TRANSFERSCB  /* short version               */
#define PPASSTHRU  PIORB_ADAPTER_PASSTHRU    /* short version               */
#define FIRST      0x0000                    /* for freeing only first SCB  */
#define ALL        0x0001                    /* free all SCBs in this chain */
#define HIGH       0x0000                    /* High priority               */
#define LOW        0x0100                    /* Low priority                */

/*--------------------------------*/
/* return codes - for general use */
/*--------------------------------*/

#define NOERROR    0x0000            /* no error                        */
#define ERROR      0x8000            /* generic error indicator         */
#define FATAL      0x0001            /* error indicator bits fatal      */
#define NONFATAL   0x0002            /* not fatal (quiet install fail)  */


#ifdef DEBUG
   #define FIXEDSIZE    0x1000    /* size of fixed data    */
#else
   #define FIXEDSIZE    0x0300    /* size of fixed data    */
#endif

#define MAXSEGSIZE  0x10000L                     /* 64K */
#define MEMPOOLSIZE MAXSEGSIZE-FIXEDSIZE-6000 /* changed 4600 to 4700 REN5274*/


/*-----------------------*/
/* Callout return codes  */
/*-----------------------*/

#define  COMPLETE        0001    /* req is done completely                */
#define  NORESOURCE      0002    /* req was unable to allocate resources  */
#define  INCOMPLETE      0003    /* req is partially completed            */
#define  READY           0004    /* req is ready to be started            */

/*-------------------------------------------------------*/
/* Interrupt status equates, used in interrupt handler.  */
/*-------------------------------------------------------*/

#define OURINT         0x0001    /* this is our interrupt.                  */
#define STARTWORK      0x0002    /* try to start more work.                 */
#define SAMEIORB       0x0004    /* start the same IORB (0 for new IORB)    */
#define ENDCURRENT     0x0008    /* end the current IORB                    */
#define SUSPENDQUE     0x0010    /* device command queue has been suspended */
#define RESTARTSENT    0x0020    /* a queue restart has been sent           */

/*-------------------*/
/* ADDStatus equates */
/*-------------------*/

#define INITDONE       0x0001    /* init is done                           */
#define NOTIMEOUTS     0x0002    /* no software timeouts                   */
#define IRQSET         0x0004    /* IRQ has been set                       */
#define ADDTRACE       0x0008    /* trace option is on                     */
#define INTTIME        0x8000    /* processing an interrupt                */
#define LED            0x0010    /* LED is to be operated                  */
#define DELIV_ATTACHED 0x0020    /* we have attached to the delivery ADD   */
#define SWITCHDRIVES   0x0040    /* switch drives for selectable boot      */
#define TRIBBLEPATCH   0x0080    /* try to patch tribble cards             */
#define SCSI2TABLE     0x0100    /* SCSI 2 table found in EBDA.            */   /*@D2623*/


/*-----------------*/
/* General defines */
/*-----------------*/

#define AID_CORVETTE   0x8efc    /* Corvette adapter ID            */
#define AID_TRIBBLE    0x8efe    /* Tribble adapter ID             */
#define ADAPTERDEVICE  0x0f      /* adapter device LDN             */
#define ADAPTER_EOI    0xe0

#define MAXRESETS      3         /* max resets attempted per retry */
#define MAX_TIMEOUT    8192      /* max timeout in locate mode     */

#define SCSISTATUSMASK 0x1e      /* mask off all bits except scsi status bits */

#define CHKCOND        0x02      /* check condition       */

#define ADDNAME        "IBMSCSI$"
#define DELIVNAME      "DELIVRY$"
#define DFLT_TO        45        /* 45 second default timeout (hdware dflt)  */
#define DFLT_QS        8         /* 8 element default queue size             */
#define DFLT_PS        1024      /* default pipe size for move mode          */
#define FRONT          0         /* front of queue                           */
#define BACK           1         /* rear of queue                            */
#define MAXTRACE       20        /* maximum trace elements stored            */
#define IOBASEADDR     0x3540    /* 1st base IO address                      */


/*---------------------------------------------*/
/* Logical device assignment table bit defines */
/*---------------------------------------------*/

#define LDA_SCSIID     0x000f    /* device scsi ID (target ID)         */
#define LDA_LUN        0x0070    /* device LUN                         */
#define LDA_BUS        0x0f00    /* bus #                              */
#define LDA_ASSIGN     0x8000    /* device has been assigned (valid)   */
#define LDA_TARGET     0x4000    /* device is a target mode device     */


/*----------------------------------------------*/
/* Adapter register offsets and bit definitions */
/*----------------------------------------------*/

#define REG_BSR         0x07     /* basic status register                    */
#define BSR_BUSY        0x01     /* busy                                     */
#define BSR_INTREQ      0x02     /* interrupt is pending                     */
#define BSR_EXCP        0x10     /* exception has been raised                */
#define BSR_EXCPSTAT    0xe0     /* exception bits                           */
#define BSR_EXCP_CC     0x00     /* channel check                            */
#define BSR_EXCP_HF     0x20     /* hardware failure                         */
#define BSR_EXCP_IC     0x40     /* invalid cmd, low-level mgmt req failure  */
#define BSR_EXCP_IS     0x60     /* invalid adapter state                    */
#define BSR_EXCP_PC     0x80     /* pipe corrupted                           */
#define BSR_EXCP_PE     0xa0     /* pipe control error                       */

#define REG_ISR         0x06     /* interrupt status register                */
#define ISR_IDMASK      0xf0     /* interrupt ID mask                        */
#define ISR_DEVMASK     0x0f     /* device ID mask                           */

#define REG_AR          0x04     /* attention register                       */

#define REG_BCR         0x05     /* basic status register                    */
#define BCR_CLRONRD     0x40     /* bcr - clear EOI on bsr read              */
#define BCR_RESET       0x80     /* bcr - reset                              */
#define BCR_CLREXCP     0x20     /* bcr - clear exception                    */

#define CC_SUCCESS      0x01     /* SCB completed with success               */
#define CC_IMMSUCCESS   0x0a     /* immediate command completed successfully */
#define CC_RETRY        0x05     /* SCB completed with success after retries */
#define CC_ERROR        0x0C     /* SCB completed with success               */
#define CC_PARMERR      0x0e     /* invalid commmand or parameter            */

/*--------------------------------------------------------------*/
/* Adapter commands, for attention register, and immediate SCBs */
/*--------------------------------------------------------------*/

#define CMD_IMMEDIATE  0x10        /* start immediate SCB                   */
#define CMD_NORMSCB    0x30        /* start normal length SCB               */
#define CMD_LONGSCB    0x40        /* start long SCB                        */
#define CMD_MGMTREQ    0x90        /* management request                    */
#define CMD_SIGNAL     0xd0        /* move mode signal                      */
#define SCB_RESET      0x00000400L /* reset immediate SCB                   */
#define SCB_FEATURE    0x0000040cL /* set feature control                   */
#define SCB_SETDMAPAC  0x0064040dL /* set dma pacing factor immd SCB (100%) */
#define SCB_ASSIGN     0x0000040eL /* assign device LDN                     */
#define SCB_ABORT      0x0000040fL /* abort immediate SCB                   */

#define RESETTIMEOUT   0x20        /* allow 32 seconds for reset to timeout */


/*------------------*/
/* SCB type defines */
/*------------------*/

#define SCB_READ      0x00   /* read                 */
#define SCB_WRITE     0x01   /* write                */
#define SCB_READV     0x02   /* read verify          */
#define SCB_WRITEV    0x03   /* write verify         */
#define SCB_CMDSENSE  0x04   /* get sense data       */
#define SCB_DEVICECAP 0x05   /* get device capacity  */
#define SCB_DEVICEINQ 0x06   /* get inquiry data     */
#define SCB_SENDOTHER 0x07   /* send othter scsi     */
#define SCB_PREFETCH  0x08   /* prefetch data        */


/*---------------------------------------------------*/
/* Sense Data defines - returned by ProcessSenseData */
/*---------------------------------------------------*/

#define ACTION_DONE           0x00  /* I/O done, end it (may have ec set)    */
#define ACTION_ABORT          0x01  /* Abort all I/O on the device           */
#define ACTION_RETRY          0x02  /* Retry the I/O                         */
#define ACTION_RECOVERED      0x03  /* I/O ended with a recovered error      */
#define ACTION_STARTUNIT      0x04  /* restart the unit                      */
#define SCSI_UNIQUE_SENSEDATA 0x7f  /* unique sense data indictr (not an rc) */

/*----------------------------------------------*/
/* Process TSB defines - returned by ProcessTSB */
/*----------------------------------------------*/

#define RETRY          0x0000  /* Retry the I/O                  */
#define IGNORE         0x0001  /* Ignore the error               */
#define FAIL           0x0002  /* Fail the I/O                   */
#define RESETADAPTER   0x0003  /* Reset the adapter              */
#define PURGE          0x0004  /* Purge all I/O for this device  */


/*------------------------------------------------*/
/* New TSB define. Negotiation error, do a retry  */
/*------------------------------------------------*/

#define RC_NEGOTIATE_ERROR 0x1000     /* error was a negotiate error */

