/*
 * nasd_od_vx.c
 *
 * I/O for vxworks NASD.
 *
 * Authors: Jim Zelenka, Marc Unangst
 */
/*
 * Copyright (c) of Carnegie Mellon University, 1997,1998,1999.
 *
 * Permission to reproduce, use, and prepare derivative works of
 * this software for internal use is granted provided the copyright
 * and "No Warranty" statements are included with all reproductions
 * and derivative works. This software may also be redistributed
 * without charge provided that the copyright and "No Warranty"
 * statements are included in all redistributions.
 *
 * NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS.
 * CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
 * EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED
 * TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY
 * OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE
 * MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT
 * TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
 */


#include <nasd/nasd_options.h>
#include <nasd/nasd_drive_options.h>
#include <nasd/nasd_types.h>
#include <nasd/nasd_freelist.h>
#include <nasd/nasd_itypes.h>
#include <nasd/nasd_mem.h>
#include <nasd/nasd_cache.h>
#include <nasd/nasd_common.h>
#include <nasd/nasd_timer.h>
#include <nasd/nasd_control.h>
#define NASD_DRIVE_IO_MODULE 1
#include <nasd/nasd_drive_io.h>

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <vxWorks.h>
#include <semLib.h>

SEM_ID nasd_u_flushsem;

void
nasd_od_uio_flush_proc(
  nasd_threadarg_t  ignored)
{
  nasd_status_t rc;
  int ret;
  char c;
  int tick_delay;

  NASD_IO_PEND_LOCK();
  nasd_u_flushproc_running = 1;
  NASD_IO_PEND_UNLOCK();
  NASD_BROADCAST_COND(nasd_u_run_cond);

  /* hopefully sysClkRate doesn't change (much) */
  tick_delay = sysClkRateGet() * 5;

  while(1) {
    ret = semTake(nasd_u_flushsem, tick_delay);
    if(ret) {
      NASD_ASSERT(errno == S_objlib_OBJ_TIMEOUT);
    }
    NASD_IO_INC_STAT(auto_flush);
    rc = nasd_odc_flush_dirty(0);
    NASD_ASSERT(rc == NASD_SUCCESS);
  }
  NASD_IO_PEND_LOCK();
  nasd_u_flushproc_running = 0;
  NASD_BROADCAST_COND(nasd_u_run_cond);
  NASD_IO_PEND_UNLOCK();
}

void
nasd_u_stop_flush_proc(
  void  *ignored)
{
  int ret;

  nasd_odc_dirty_kick();
  NASD_THREADGROUP_INDICATE_SHUTDOWN(&nasd_u_flushproc_threadgroup);
  nasd_odc_dirtythread_force = 1;

  ret = semGive(nasd_u_flushsem);
  if (ret) {
    NASD_PANIC();
  }

#if MJU_DEBUG
  fprintf(stderr, "stop_flush_proc: wait for shutdown\n");
#endif /* MJU_DEBUG */
  NASD_THREADGROUP_WAIT_STOP(&nasd_u_flushproc_threadgroup);
#if MJU_DEBUG
  fprintf(stderr, "stop_flush_proc: done waiting for shutdown\n");
#endif /* MJU_DEBUG */
}

nasd_status_t
nasd_od_io_init(
  char  *devname)
{
  nasd_u_flushsem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
  if(!nasd_u_flushsem) {
    nasd_printf("ERROR %d from semBCreate()\n", errno);
    return NASD_FAIL;
  }
}

/* Local Variables:  */
/* indent-tabs-mode: nil */
/* tab-width: 2 */
/* End: */
