/* usb/sys/waiting.h
 *
 * (c) 2002 Simtec Electronics
 *
 * Ben Dooks
 *
 * Operating System Specific Waiting routines
 *
 * $Id: waiting.h,v 1.16 2003/08/07 22:16:25 ben Exp $
 *
 * This Library file is part of the Simtec Electronics USB stack development
 *   suite.
 * Specific licence is granted to use this file by third parties for the
 *   development of USB device drivers.
 *
 */

#ifndef __RISCOS_SYS_WAITING_H
#define __RISCOS_SYS_WAITING_H "$Id: waiting.h,v 1.16 2003/08/07 22:16:25 ben Exp $"

/** Waiting type for taskwindow
 */
#define WAITING_TYPE_POLL        2

/** Waiting type for wimp message
 */
#define WAITING_TYPE_MESSAGE     3

/** Waiting type for SWI
 */
#define WAITING_TYPE_SWI         4

/** Waiting type for APCS function call
 */
#define WAITING_TYPE_APCS        5

/** Waiting type for OS_AddCallback
 */
#define WAITING_TYPE_CALLBACK    6

/** Waiting type for use with a Wimp style poll-word-non-zero
 * @memo Waiting type for use with Wimp Poll Word Non Zero
*/
#define WAITING_TYPE_POLLWORD    7

/** Waiting type for an APCS function that is safe to call from an
 * IRQ context
*/
#define WAITING_TYPE_APCSIRQ     8

/* The range from 256 to 1023 is used by registered applications */

/* The range from 1024 onwards can be used by own modes of the
   local programs */

/* data structure definitions */
/** poll waiting structure */
struct waiting_poll_s {
  int poll_word;
};

#define wait_poll additional_information.poll

/** waiting message structure */
struct waiting_message_s {
  /* Block must be allocated by the caller inside Common
     address space */
  void *wimp_message_block;
  int destination_task_handle;
  int icon_handle;
};

#define wait_wimpmsg  additional_information.message

/** waiting swi struct */
struct waiting_swi_s {
  int swi;
  _kernel_swi_regs regs;
};

#define wait_swi additional_information.swi

typedef void (*wait_apcs_call_t)(int, int, int, int);

/** waiting apcs call struct */
struct waiting_apcs_s {
  wait_apcs_call_t      apcs_call;
  int                   a[4];
};

/* map old to new definition */
#define waiting_apcs_call  apcs_call
#define wait_apcs additional_information.apcs


struct waiting_callback_s {
  void *to;
  void *pw;
};

#define wait_callback additional_information.callback

/** waiting structure for pollword */

struct waiting_pollword_s {
  int       *pollword;     /* pointer to poll word in RMA / DA */
  int       or_value;      /* OR pollword with this value */
  int       and_value;     /* AND pollword with this value */
};

#define wait_pollword additional_information.pollword

#define USB_WAITING_UNION \
  struct waiting_poll_s poll;\
  struct waiting_message_s message;\
  struct waiting_swi_s swi;\
  struct waiting_apcs_s apcs;\
  struct waiting_callback_s callback;\
  struct waiting_pollword_s pollword;

/* routines to initalise your waiting structures */

extern int waiting_init_apcs(usb_wait_t *wait, wait_apcs_call_t call,
			     int a1, int a2, int a3, int a4);

extern int waiting_init_poll(usb_wait_t *wait);

extern int waiting_init_wimpmessage(usb_wait_t *wait, void *msg,
				 int dst_task, int dst_icon);

extern int waiting_init_swi(usb_wait_t *wait, int swi, _kernel_swi_regs *regs);

extern int waiting_init_callback(usb_wait_t *wait, void *to, void *pw);

/* check wether a waiting mode can be called from irq context */

extern int waiting_is_irqsafe(usb_wait_t *wait);

#endif /* __RISCOS_SYS_WAITING_H */
