#ifndef __INC_POS_PEXEC_DEVICE_H
#define __INC_POS_PEXEC_DEVICE_H
/*******************************************************************
 Includes Release 24
 (C) Copyright 1995-1997 proDAD
     All Rights Reserved

 $AUT Holger Burkarth
 $DAT >>Device.h<<   16 Mar 1997    19:16:29 - (C) ProDAD
*******************************************************************/
#ifndef __INC_POS_PEXEC_LIBRARY_H
#include <pExec/Library.h>
#endif
#ifndef __INC_POS_PEXEC_MSGPORT_H
#include <pExec/MsgPort.h>
#endif


/*----------------------------------
-----------------------------------*/
struct pOS_Device
{
  struct pOS_Library dd_Library;
};


/*----------------------------------
-----------------------------------*/
struct pOS_Unit
{
  struct pOS_MsgPort unit_MsgPort; /* queue for unprocessed messages */
                            /* instance of msgport is recommended */
  UBYTE   unit_Flags;
  UBYTE   unit_Num;         /* kann vom Device für eigene Zwecke verwendet werden */
  UWORD   unit_OpenCnt;     /* number of active opens */
};


enum pOS_UnitFlags
{
  UNITF_Active  =0x01, /* BeginIO-Task is working */
  UNITF_InTask  =0x02, /* Unit-Task is working */
  UNITF_Quit    =0x04, /* quit Unit-Task */
  UNITF_Stopped =0x08, /* Unit-Task is CMD_STOP */
  UNITF_NeedSig =0x10  /* Unit-Task need WackUp-Signal */
};




/*----------------------------------
-----------------------------------*/
struct pOS_IORequest
{
  struct pOS_Message  io_Message;
  struct pOS_Device  *io_Device;   /* device node pointer  */
  struct pOS_Unit    *io_Unit;     /* unit (driver private) */
  UWORD               io_Command;   /* (enum pOS_IOReqCommands) */
  UBYTE               io_Flags;     /* (enum pOS_IOReqFlags) */
  SBYTE               io_Error;     /* (enum pOS_IOReqErrors) */
};


/*----------------------------------
-----------------------------------*/
struct pOS_IOStdReq
{
  struct pOS_Message  io_Message;
  struct pOS_Device  *io_Device;   /* device node pointer  */
  struct pOS_Unit    *io_Unit;     /* unit (driver private)*/
  UWORD               io_Command;   /* (enum pOS_IOReqCommands) */
  UBYTE               io_Flags;     /* (enum pOS_IOReqFlags) */
  SBYTE               io_Error;     /* (enum pOS_IOReqErrors) */
  ULONG               io_Actual;    /* actual number of bytes transferred */
  ULONG               io_Length;    /* requested number bytes transferred */
  APTR                io_Data;      /* points to data area */
  ULONG               io_Offset;    /* offset for block structured devices */
  ULONG               io_OPad;
  UBYTE               io_Pad[8];
};





enum pOS_IOReqFlags
{
  IOREQB_Quick   = 0,

  IOREQF_Quick   = 0x01,
  IOREQF_IntSig  = 0x02, /* für Device-eigene interne Zwecke */

  IOREQF_Pending = 0x80
};


enum pOS_IOReqErrors
{
  IOERR_None       = 0,
  IOERR_OpenFail   =-1, /* device/unit failed to open */
  IOERR_Aborted    =-2, /* request terminated early [after AbortIO()] */
  IOERR_NoCMD      =-3, /* command not supported by device */
  IOERR_BadLength  =-4, /* not a valid length (usually IO_LENGTH) */
  IOERR_BadAddress =-5, /* invalid address (misaligned or bad range) */
  IOERR_UnitBusy   =-6, /* device opens ok, but requested unit is busy */
  IOERR_Selftest   =-7, /* hardware failed self-test */
  IOERR_NoMem      =-8, /* not enough memory */
  IOERR_NoSubCMD   =-9  /* sub-command not supported by device */
};


enum pOS_IOReqCommands
{
  CMD_INVALID   = 0,
  CMD_RESET     = 1,
  CMD_READ      = 2,
  CMD_WRITE     = 3,
  CMD_UPDATE    = 4,
  CMD_CLEAR     = 5,
  CMD_STOP      = 6,
  CMD_START     = 7,
  CMD_FLUSH     = 8,

  CMD_NONSTD    = 9,
  CMD_INFO      = 0x7ffe
};








/*----------------------------------
 Rückwärtsgerichtete Struktur, DevBase
 steht auf dem Ende der Struct.
-----------------------------------*/
struct pOS_StdDeviceFunction
{
  struct pOS_LibraryFunction Reserved2[8];

  VOID  (*AbortIO_func)(_R_LB struct pOS_Device*,_R_A0 struct pOS_IORequest*);
  UBYTE _d5[8];
  VOID  (*BeginIO_func)(_R_LB struct pOS_Device*,_R_A0 struct pOS_IORequest*);
  UBYTE _d4[8];

  struct pOS_LibraryFunction Reserved1[8];

  struct pOS_SegmentLst* (*Expunge_func)(_R_LB struct pOS_Device*);
  UBYTE _d3[8];
  VOID  (*Close_func)(_R_LB struct pOS_Device*,_R_A0 struct pOS_IORequest*);
  UBYTE _d2[8];
  BOOL  (*Open_func)(_R_LB struct pOS_Device*,_R_A0 struct pOS_IORequest*,_R_D0 ULONG unitNr,_R_D1 ULONG flags);
  UBYTE _d1[8];
}; /* => DeviceBase */


#define _pOS_GetStdDeviceFunction(dev) \
 ( (struct pOS_StdDeviceFunction*)((ULONG)(dev) - sizeof(struct pOS_StdDeviceFunction)) )

#define _pOS_GetDeviceFunction(dev,index) \
 ( (struct pOS_LibraryFunction*)((ULONG)(dev) - (index)*sizeof(struct pOS_LibraryFunction)) )



#endif
