/* usb/waiting.h
 *
 * (c) 2002 Simtec Electronics
 *
 * Ben Dooks
 *
 * USB waiting header
 *
 * $Id: waiting.h,v 1.16 2003/08/06 15:56:11 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 __USB_WAITING_H
#define __USB_WAITING_H "$Id: waiting.h,v 1.16 2003/08/06 15:56:11 ben Exp $"

struct usb_wait_s;
typedef struct usb_wait_s usb_wait_t;

/* get any system specific waiting types */
#include "usb/sys/waiting.h"

/* Definition is public */
#define WAITING_RESULT_OK                   (0)
#define WAITING_RESULT_ILLEGAL_WAITING_TYPE (-1)
#define WAITING_RESULT_ILLEGAL_PARAMETER    (-2)
#define WAITING_RESULT_STILL_WAITING        (-3)
#define WAITING_RESULT_NO_RESOURCES         (-4)

/* ---------- waiting modes ---------- */
/* Common types are using the range from 0 to 255 */
/* Returns immediately if no access is possible or no result available.
   This is usually handled by the local program but is also used to return
   actual state of a waiting handle */
/* Definition is public */

/** Waiting type for immediate return
 */
#define WAITING_TYPE_RETURN      0

/** Waiting type for busy waiting
 */
#define WAITING_TYPE_LOOP        1

/* Special at semaphor dropping. Sets dropping flag and leaves
   without waiting */
#define WAITING_TYPE_SEMAPHOR_RETURN_DROP 256

#ifndef USB_WAITING_UNION
#error USB_WAITING_UNION is not defined
#endif

/** waiting struct
 */
struct usb_wait_s {
  int size;
  int mode;
  /* Must be marked as voilatile at some compilers */
  int result;
  int loop_flag;

  union {
    USB_WAITING_UNION
  } additional_information;
};

/* define wait_data to point to the union's name, for easier typing */

#define wait_data  additional_information

/* definitions of the functions we are going to use */

/** initialize waiting structure
 */
extern int usb_wait_init(usb_wait_t *, int);

/** get waiting state
 */
extern int usb_wait_getstate(usb_wait_t *, int *);

/** perform a given wait
 */
extern int usb_wait_do(usb_wait_t *, int *);

/** inform waiting task
 */
extern int usb_wait_inform(usb_wait_t *, int);

/** copy one waiting struct to another
*
*/
extern int usb_wait_copy(usb_wait_t *dst, usb_wait_t *src);

#endif /* __USB_WAITING_H */
