mstiinf.c



/* --------------------------------------------------------------------
FILE MSTIINTF.C
MSTI data acquisition program. 
LRE 10-19-94
LRE 3-1-95 Added continuous read to buffer.
------------------------------------------------------------------ */

#include <fcntl.h>
#include <stdio.h>
#include "./idr_io.h"
#include "../mstitst.h"

/* Function prototypes */

void do_rd_data_to_file(ikonbuf_t **, to_ikonmsg_t *, int, int ) ;
int do_rd_cont_to_buf(ikonbuf_t **, to_ikonmsg_t *, int ) ;
int stop_rd_cont_to_buf(int) ; 
int read_to_buf(ikonbuf_t **, to_ikonmsg_t *, int) ;
int rd_cont_to_buf(ikonbuf_t **, to_ikonmsg_t *, int) ; 
int wr_buf_to_file(ikonbuf_t **, to_ikonmsg_t *, int, int) ;
int do_fill_bufs(ikonbuf_t **, to_ikonmsg_t *) ;
int setup_buf_mem(ikonbuf_t **, int *) ;
int get_buf_mem(int *) ;
int attach_buf_mem(ikonbuf_t **, int *) ;
int lock_buf_mem(ikonbuf_t **, int *) ;
int release_buf_mem(ikonbuf_t **, int *) ;
int detach_buf_mem(ikonbuf_t **) ;
int unlock_buf_mem(int *) ;
int remove_buf_mem(int *) ;
int setup_dr11(long int, int) ; 
int setup_wr_file(to_ikonmsg_t *) ; 
int close_wr_file(int) ; 
int setup_sem() ;
int remove_sem(int) ;
int setup_msg() ;
int remove_msg(int) ;
int send_reply_msg(int, int) ;


/* -----------------------------------------------------------------------
main
--------------------------------------------------------------------- */

main() 
{

   int error_num, sem_id, msg_id, i, cont_rd_data_type ; 
   int doing_cont_rd = 0 ;
   int Buf_Id[NUM_BUFS] ;
   ikonbuf_t *Buf_ptr[NUM_BUFS] ; 
   to_ikonmsg_t cmd_msg ;

   if( (msg_id = setup_msg()) < 0 ) exit(1) ; 

   if( (sem_id = setup_sem()) < 0 ) {
       remove_msg(msg_id) ;
       exit(2) ; }

   if(setup_buf_mem(Buf_ptr, Buf_Id) != 0) {
       remove_msg(msg_id) ;
       remove_sem(sem_id) ;
       exit(3) ; }

   /* main message loop */

while(1)
{
   puts("shmtst waiting for msg.") ;
   if( (error_num = msgrcv(msg_id, &cmd_msg.msg_type, TO_IKON_MSG_LEN, 
                   MSG_TO_IKON, MSG_NOERROR)) < 0) {
       i = errno ;
       printf("msgrcv returned %d. errno %d.\n", error_num, i) ; 
       remove_msg(msg_id) ;
       remove_sem(sem_id) ;
       release_buf_mem(Buf_ptr, Buf_Id) ;
       exit(4) ; }

   switch(cmd_msg.cmd)
   {
      case RD_DATA_TO_FILE_CMD :

        if(doing_cont_rd != 0) {
           error_num = stop_rd_cont_to_buf(sem_id) ; }
        do_rd_data_to_file(Buf_ptr, &cmd_msg, sem_id, msg_id) ;
        if(doing_cont_rd != 0) {
           cmd_msg.data_type = cont_rd_data_type ;
           error_num = do_rd_cont_to_buf(Buf_ptr, &cmd_msg, sem_id) ; }
        break ;

      case RD_TO_BUF_CMD :

        error_num = do_rd_cont_to_buf(Buf_ptr, &cmd_msg, sem_id) ;
        cont_rd_data_type = cmd_msg.data_type ;
        doing_cont_rd = -1 ; 
        if(error_num != MSTI_OK) doing_cont_rd = 0 ; 
        send_reply_msg(msg_id, error_num) ; 
        break ;

      case QUIT_RD_TO_BUF_CMD :

        error_num = MSTI_OK ;
        if(doing_cont_rd != 0) {
           error_num = stop_rd_cont_to_buf(sem_id) ; 
           doing_cont_rd = 0 ; }
        send_reply_msg(msg_id, error_num) ; 
        break ;

      case FILL_BUFS_CMD :

        error_num = MSTI_OK ;
        if(doing_cont_rd == 0) {
           error_num = do_fill_bufs(Buf_ptr, &cmd_msg) ; }
        else {
           error_num = MSTI_BUSY_ERR ; }
        send_reply_msg(msg_id, error_num) ; 
        break ;

      case QUIT_CMD :
          puts("Quitting mstiintf program.") ;
          if(doing_cont_rd != 0) {
             error_num = stop_rd_cont_to_buf(sem_id) ; }
          remove_sem(sem_id) ;
          remove_msg(msg_id) ;
          release_buf_mem(Buf_ptr, Buf_Id) ;
          exit(1) ;
          break ;

      default :
          printf("Ignoring unknown command %d.", cmd_msg.cmd ) ;
          send_reply_msg(msg_id, MSTI_UNK_CMD_ERR) ; 
          break ;

   } /* end case */

} /* end while(1) main message loop */

} /* End of main() */

/* ------------------------------------------------------------------
setup_buf_mem
---------------------------------------------------------------- */

int setup_buf_mem(ikonbuf_t *Buf_ptr[NUM_BUFS], int Buf_Id[NUM_BUFS]) 
{

   if(get_buf_mem(Buf_Id) != 0) return(-1) ;

   if(attach_buf_mem(Buf_ptr, Buf_Id) != 0) 
     {
       remove_buf_mem(Buf_Id) ;
       return(-1) ;
     }

   if(lock_buf_mem(Buf_ptr, Buf_Id) != 0) 
     {
       detach_buf_mem(Buf_ptr) ;
       remove_buf_mem(Buf_Id) ;
       return(-1) ;
     }

   return(0) ; /* End of setup_buf_mem */
}

/* ------------------------------------------------------------------
release_buf_mem
---------------------------------------------------------------- */

int release_buf_mem(ikonbuf_t *Buf_ptr[NUM_BUFS], int Buf_Id[NUM_BUFS]) 
{
   int error_num = 0 ;

   error_num = unlock_buf_mem(Buf_Id) ;

   error_num |= detach_buf_mem(Buf_ptr) ;

   error_num |= remove_buf_mem(Buf_Id) ;

   if(error_num != 0) return(-1); /* End of release_buf_mem */

   return(0) ;
}

/* -----------------------------------------------------------------
read_to_buf
-----------------------------------------------------------------*/ 

int read_to_buf(ikonbuf_t *Buf_ptr[NUM_BUFS], to_ikonmsg_t *cmd_msg, 
                  int sem_id)
{
  union {char ch[256] ; u_long ulg[64] ; } arg ;
  int filedes, loop_cnt, sys_errno, iii ;   
  int ii = 0 ; 

  struct sembuf wait_sem_0[1] = {
            0, -1, 0  /* Wait for sem 0 set by write */
   } ;

  struct sembuf inc_sem_1[1] = {
            1, 1, 0  /* Increment sem 1 for write */
   } ;

      /* Open the DR11 */
  if( (filedes = open(IKON_DEV_NAME, O_RDWR, 0666)) < 0 ) 
    {
      sys_errno = errno ;
      printf("Unable to open dr11. errno %d.\n", sys_errno) ;
      return(-1) ;
    }
  
      /* Setup for GO */
  arg.ulg[0] = IDR_GO ;

     /* Only RT_DAT or ST_DAT allowed.  Setup default to ST_DAT */
  if(cmd_msg->data_type != RT_DAT) cmd_msg->data_type = ST_DAT ;

     /* Initialize the DR11 */
  if(setup_dr11((long int) cmd_msg->data_type, filedes) != 0) 
    {
      puts("Aborting read to buffer.\n") ;
      return(-1) ;
    }

     /* Wait for wr_buf_to_file ready */

   if( (iii = semop(sem_id, &wait_sem_0[0], 1)) < 0) 
     {
       sys_errno = errno ;
       printf("Wait for sem 0 returned %d. errno %d.\n", iii, sys_errno) ;
       return(-1) ;
     }

    /* Start FIFO input */
  if( (ii = ioctl(filedes,IDRIO_IMM_PULSE,arg.ulg)) != 0) 
    {
        sys_errno = errno ;
        printf("Go failed. errno %d. Sys_errno = %d. Continuing.\n", 
                    ii, sys_errno) ;
     }

    /* Go DMA the data. */
  for(loop_cnt=0; loop_cnt<(cmd_msg->num_frames * 2); loop_cnt++)
    {
      if( (ii = read(filedes,Buf_ptr[loop_cnt % NUM_BUFS],BUFF_SIZE)) 
               != BUFF_SIZE)
       {
           sys_errno = errno ;
        printf("Read returned %d. Loop number %d. errno %d. Quitting read.\n", 
                ii, loop_cnt, sys_errno) ;
           loop_cnt = (cmd_msg->num_frames * 2) ;
       }
        /* Tell wr_buf_to_file a buffer is available */
      semop(sem_id, &inc_sem_1[0], 1) ;  
     }

    /* Done - turn things off. */
  if( (ii = ioctl(filedes,IDRIO_BLOCK_END,arg.ulg)) != 0) 
    {
        sys_errno = errno ;
        printf("Block end failed. errno %d. sys_errno = %d. Continuing.\n",
                     ii, sys_errno) ;
     }

   /* Close the DR11 */
  if(close(filedes) < 0) 
    {
        ii = errno ;
        printf("Close DR11 failed. errno %d. Continuing.\n", ii) ;
     }

      /* Wait for wr_buf_to_file finished */

   if( (iii = semop(sem_id, &wait_sem_0[0], 1)) < 0) 
     {
       sys_errno = errno ;
       printf("Wait for write finished sem 0 returned %d. errno %d.\n", 
                iii, sys_errno) ;
     }
  
return(ii) ;

} /* End of read_to_buf */

/* --------------------------------------------------------------------
setup_wr_file
------------------------------------------------------------------- */

int setup_wr_file(to_ikonmsg_t *cmd_msg) 
{
  int filedes, ii ;

     /* Create the output file. */
  if(creat(cmd_msg->msg, 0666) < 0) 
    {
        ii = errno ;
        printf("Unable to create output file. errno %d.\n", ii) ;
        return(-1) ;
     }

    /* Open the output file */
  if( (filedes = open(cmd_msg->msg, O_RDWR)) < 0 ) 
    {
        ii = errno ;
        printf("Unable to open output file. errno %d.\n", ii) ;
        return(-1) ;
     }
  return(filedes) ;
}

/* --------------------------------------------------------------------
wr_buf_to_file
------------------------------------------------------------------- */

int wr_buf_to_file(ikonbuf_t *Buf_ptr[NUM_BUFS], to_ikonmsg_t *cmd_msg, 
                    int filedes, int sem_id)
{
  int ii, iii, loop_cnt ;

  struct sembuf set_sem_0[1] = {
            0, 1, 0 /* Increment sem 0 so read will start */
   } ;

  struct sembuf wait_sem_1[1] = {
            1, -1, 0  /* Wait for read to fill buffer */
   } ;

    /* Tell read we're ready to go */
  if( (iii = semop(sem_id, &set_sem_0[0], 1)) < 0) 
    {
      ii = errno ;
      printf("Set sem 0 returned %d. errno %d.\n", iii, ii) ;
    }


  for(loop_cnt=0; loop_cnt<(cmd_msg->num_frames * 2); loop_cnt++)
    {
      if( (iii = semop(sem_id, &wait_sem_1[0], 1)) < 0) 
         {
           ii = errno ;
           printf("Wait for sem 0 returned %d. errno %d.\n", iii, ii) ;
           return(-1) ;
         }
      if(write(filedes,Buf_ptr[loop_cnt % NUM_BUFS],BUFF_SIZE) 
                      != BUFF_SIZE) 
        {
           ii = errno ;
           printf("Write to output file failed. errno %d.\n", ii) ;
           close(filedes) ;
           return(-1) ;
        }
    }

    /* Tell read we're done */
  if( (iii = semop(sem_id, &set_sem_0[0], 1)) < 0) 
    {
      ii = errno ;
      printf("Set sem 0 returned %d. errno %d.\n", iii, ii) ;
    }

return(0) ;

} /* End of wr_buf_to_file */

/* ----------------------------------------------------------------
close_wr_file
-------------------------------------------------------------- */

int close_wr_file(int filedes) 
{
  int ii ;

  if(close(filedes) < 0)
    {
        ii = errno ;
        printf("Unable to close output file. errno %d.\n", ii) ;
        return(-1) ;
     }

return(0) ;

} /* End of close_wr_file */

/* ----------------------------------------------------------------
get_buf_mem
-------------------------------------------------------------- */

int get_buf_mem(int Buf_Id[NUM_BUFS]) 
{
   key_t Ikon_Buf_Key[NUM_BUFS] ;
   int loop_cnt, ii ;
   char key_file_name[80], file_num[17] ;

   for(loop_cnt=0; loop_cnt<NUM_BUFS; loop_cnt++)
     {
       strcpy(key_file_name, SHM_KEY_FILE) ;
       sprintf(file_num, "%d", loop_cnt) ;
       strcat(key_file_name, file_num) ;
       if( (Ikon_Buf_Key[loop_cnt] = ftok(key_file_name, (char) 1 )) < 0) 
         {
            ii = errno ;
            printf("Couldn't get key. errno %d. Exiting!\n", ii) ;
            return(-1) ;
         }
     }

   for(loop_cnt=0; loop_cnt<NUM_BUFS; loop_cnt++)
     {
      if( (Buf_Id[loop_cnt] = shmget(Ikon_Buf_Key[loop_cnt], 
                      BUFF_SIZE, PERMS | IPC_CREAT)) < 0)  
        { 
          ii = errno ;
          for(--loop_cnt; loop_cnt>=0; loop_cnt--)
            {
             shmctl(Buf_Id[loop_cnt], IPC_RMID, (struct shmid_ds *) 0) ;
            } 
          printf("Couldn't get buffer ID. errno %d. Exiting!\n", ii) ;
          return(-1) ;
        }
     }
 return(0) ;
} /* End of get_buf_mem */

/* ------------------------------------------------------------------
attach_buf_mem
---------------------------------------------------------------- */

int attach_buf_mem(ikonbuf_t *Buf_ptr[NUM_BUFS], int Buf_Id[NUM_BUFS]) 
{
  int loop_cnt, ii ;  

  for(loop_cnt=0; loop_cnt<NUM_BUFS; loop_cnt++)
     {
       if( (Buf_ptr[loop_cnt] = (ikonbuf_t *) shmat(Buf_Id[loop_cnt], 
                                  (char *) 0, 0)) == (ikonbuf_t *) -1)
        {
          ii = errno ;
          for(--loop_cnt; loop_cnt>=0; loop_cnt--)
            {
               shmdt(Buf_ptr[loop_cnt]) ;
             } 
          printf("Couldn't get buffer ptr. errno %d. Exiting!\n", ii) ;
          return(-1) ;
        }
     }
  return(0) ; /* End of attach_buf_mem */
}

/* ------------------------------------------------------------------
lock_buf_mem
---------------------------------------------------------------- */

int lock_buf_mem(ikonbuf_t *Buf_ptr[NUM_BUFS], int Buf_Id[NUM_BUFS]) 
{
  int loop_cnt, ii ;  

  for(loop_cnt=0; loop_cnt<NUM_BUFS; loop_cnt++)
     {
       if( (shmctl(Buf_Id[loop_cnt], SHM_LOCK, (struct shmid_ds *) 0)) < 0)
        {
          ii = errno ;
          for(--loop_cnt; loop_cnt>=0; loop_cnt--)
            {
              shmctl(Buf_Id[loop_cnt], SHM_UNLOCK, (struct shmid_ds *) 0) ;
               shmdt(Buf_ptr[loop_cnt]) ;
             } 
          printf("Couldn't lock buffer ptr. errno %d. Exiting!\n", ii) ;
          return(-1) ;
        }
     }
  return(0) ; /* End of lock_buf_mem */
}

/* ------------------------------------------------------------------
detach_buf_mem
---------------------------------------------------------------- */

int detach_buf_mem(ikonbuf_t *Buf_ptr[NUM_BUFS])
{
  int loop_cnt, ii ;  
  int Ret_Val = 0 ;

  for(loop_cnt=0; loop_cnt<NUM_BUFS; loop_cnt++)
     {
       if (shmdt(Buf_ptr[loop_cnt]) < 0)
        {
          ii = errno ;
          Ret_Val = -1 ;
          printf("Can't detach Buffer %d. errno %d.\n", loop_cnt, ii) ;
        }
     }
  return(Ret_Val) ; /* End of detach_buf_mem */
}

/* ------------------------------------------------------------------
remove_buf_mem
---------------------------------------------------------------- */

int remove_buf_mem(int Buf_Id[NUM_BUFS]) 
{
  int loop_cnt, ii ;  
  int Ret_Val = 0 ;

  for(loop_cnt=0; loop_cnt<NUM_BUFS; loop_cnt++)
     {
       if((shmctl(Buf_Id[loop_cnt], IPC_RMID, (struct shmid_ds *) 0)) < 0)
        {
          ii = errno ;
          Ret_Val = -1 ;
          printf("Can't remove Buffer %d. errno %d.\n", loop_cnt, ii) ;
        }
     }
  return(Ret_Val) ; /* End of remove_buf_mem */
}

/* ------------------------------------------------------------------
unlock_buf_mem
---------------------------------------------------------------- */

int unlock_buf_mem(int Buf_Id[NUM_BUFS]) 
{
  int loop_cnt, ii ;  
  int Ret_Val = 0 ;

  for(loop_cnt=0; loop_cnt<NUM_BUFS; loop_cnt++)
     {
       if((shmctl(Buf_Id[loop_cnt], SHM_UNLOCK, (struct shmid_ds *) 0)) < 0)
        {
          ii = errno ;
          Ret_Val = -1 ;
          printf("Can't unlock Buffer %d. errno %d.\n", loop_cnt, ii) ;
        }
     }
  return(Ret_Val) ; /* End of unlock_buf_mem */
}

/* -----------------------------------------------------------------
setup_dr11 
-----------------------------------------------------------------*/ 

int setup_dr11(long int data_type, int filedes) 
{
  union {char ch[256] ; u_long ulg[64] ; } arg ;
  int ii, sys_errno ;   

   /* Set manual mode */

  if( (ii = ioctl(filedes,IDRIO_MANUAL,arg.ulg)) != 0) 
    {
        sys_errno = errno ;
        printf("Set DR11 manual mode failed. errno %d. sys_errno %d\n",
             ii, sys_errno) ;
        return(-1) ;
    }

     /* Setup DR11 mode register. */
      /* Default ready timing
         Fast input FIFO timing
         CYCLE REQ B disabled
         No swap bytes
         Rising edge cycle request polarity
         BUSY active lo
         Slowest speed
         Disable range counter in DR11 latched functions reg */

  arg.ulg[0] = (IDR_BDIS | IDR_FMOD | IDR_SPD_0 | IDR_RDISX) ;
  if( (ii = ioctl(filedes,IDRIO_SET_MODE,arg.ulg)) != 0) 
    {
        sys_errno = errno ;
        printf("DR11 set manual mode failed. errno %d. sys_errno %d.\n", 
               ii, sys_errno) ;
        return(-1) ;
     }

    /*   Data type commanded to MSTI interface. */

  arg.ulg[0] =  data_type ;
  if( (ii = ioctl(filedes,IDRIO_IMM_FCN,arg.ulg)) != 0) 
    {
        sys_errno = errno ;
        printf("DR11 set data type failed. errno %d. sys_errno %d.\n",
                ii, sys_errno) ;
        return(-1) ;
     }

    /* Reset MSTI interface. */

  arg.ulg[0] = IDR_INIT ;
  if( (ii = ioctl(filedes,IDRIO_IMM_PULSE,arg.ulg)) != 0) 
    {
        sys_errno = errno ;
        printf("DR11 init failed. errno %d. sys_errno %d.\n", 
                   ii, sys_errno) ;
        return(-1) ;
     }

     /* Not going to use it, but set the range count anyway. */

  arg.ulg[0] = (BUFF_SIZE / 2) - 1 ; /* Word count - 1 */
  ii = ioctl(filedes,IDRIO_SET_RANGE,arg.ulg) ;

  if( (ii = ioctl(filedes,IDRIO_START_READ,arg.ulg)) != 0) 
    {
        sys_errno = errno ;
        printf("DR11 start read failed. errno %d. sys_errno %d.\n",
                 ii, sys_errno) ;
        return(-1) ;
     }

  return(0) ;

} /* End of setup_dr11 */

/* -----------------------------------------------------------------------
setup_sem
--------------------------------------------------------------------- */
int setup_sem()
{
  int sem_id, ii ;
  key_t Ikon_Sem_Key ;

  if( (Ikon_Sem_Key = ftok(SEM_KEY_FILE, (char) 1 )) < 0) 
     {
        ii = errno ;
        printf("Couldn't get semaphore key. errno %d. Exiting!\n", ii) ;
        return(-1) ;
      }

  if( (sem_id = semget(Ikon_Sem_Key, 
                 NUM_SEMS, PERMS | IPC_CREAT)) < 0)  
      { 
        ii = errno ;
        printf("Couldn't get semaphore ID. errno %d. Exiting!\n", ii) ;
        return(-1) ;
      }

  return(sem_id) ;
  
} /* End of setup_sem */

/* -----------------------------------------------------------------------
remove_sem
--------------------------------------------------------------------- */
int remove_sem(int sem_id)
{
  int ii ;

  if(semctl(sem_id, 0, IPC_RMID, 0) < 0)  
      { 
        ii = errno ;
        printf("Couldn't remove semaphore. errno %d.\n", ii) ;
        return(-1) ;
      }
 
  return(0) ;
 
} /* End of remove_sem */

/* -----------------------------------------------------------------------
setup_msg
--------------------------------------------------------------------- */
int setup_msg()
{
  int msg_id, ii ;
  key_t Ikon_Msg_Key ;

  if( (Ikon_Msg_Key = ftok(MSG_KEY_FILE, (char) 1 )) < 0) 
     {
        ii = errno ;
        printf("Couldn't get message queue key. errno %d. Exiting!\n", ii) ;
        return(-1) ;
      }

  if( (msg_id = msgget(Ikon_Msg_Key, PERMS | IPC_CREAT)) < 0)  
      { 
        ii = errno ;
        printf("Couldn't get message queue ID. errno %d. Exiting!\n", ii) ;
        return(-1) ;
      }

  return(msg_id) ;
  
} /* End of setup_msg */

/* -----------------------------------------------------------------------
remove_msg
--------------------------------------------------------------------- */
int remove_msg(int msg_id)
{
  int ii ;

  if(msgctl(msg_id, IPC_RMID, (struct msqid_ds *) 0) < 0)  
      { 
        ii = errno ;
        printf("Couldn't remove message queue. errno %d.\n", ii) ;
        return(-1) ;
      }
 
  return(0) ;
 
} /* End of remove_sem */

/* -----------------------------------------------------------------------
send_reply_msg
--------------------------------------------------------------------- */
int send_reply_msg(int msg_id, int status) 
{
   from_ikonmsg_t reply_msg ;

   reply_msg.msg_type = MSG_FROM_IKON ;
   reply_msg.status = status ;

   msgsnd(msg_id, &reply_msg.msg_type, FROM_IKON_MSG_LEN, 0) ;
   return(0) ;
}

/* -----------------------------------------------------------------
rd_cont_to_buf
-----------------------------------------------------------------*/ 

int rd_cont_to_buf(ikonbuf_t *Buf_ptr[NUM_BUFS], to_ikonmsg_t *cmd_msg, 
                  int sem_id)
{
  union {char ch[256] ; u_long ulg[64] ; } arg ;
  int filedes, loop_cnt, sys_errno, iii ;   
  int ii = 0 ; 

  struct sembuf clr_sem_0[1] = {
            0, -1, 0  /* clr sem 0 when done */
   } ;

  struct sembuf set_sem_0[1] = {
            0, 1, 0  /* set sem 0 when starting */
   } ;

  struct sembuf clr_sem_1[1] = {
            1, -1, 0  /* clr sem 1 when done */
   } ;

  struct sembuf set_sem_1[1] = {
            1, 1, 0  /* set sem 1 on error to quit. */
   } ;

      /* Open the DR11 */
  if( (filedes = open(IKON_DEV_NAME, O_RDWR, 0666)) < 0 ) 
    {
      sys_errno = errno ;
      printf("Unable to open dr11. errno %d.\n", sys_errno) ;
      return(-1) ;
    }
  
      /* Setup for GO */
  arg.ulg[0] = IDR_GO ;

     /* Only RT_DAT or ST_DAT allowed.  Setup default to ST_DAT */
  if(cmd_msg->data_type != RT_DAT) cmd_msg->data_type = ST_DAT ;

     /* Initialize the DR11 */
  if(setup_dr11((long int) cmd_msg->data_type, filedes) != 0) 
    {
      puts("Aborting read to buffer.\n") ;
      return(-1) ;
    }

    /* Start FIFO input */
  if( (ii = ioctl(filedes,IDRIO_IMM_PULSE,arg.ulg)) != 0) 
    {
        sys_errno = errno ;
        printf("Go failed. errno %d. Sys_errno = %d. Continuing.\n", 
                    ii, sys_errno) ;
     }

        /* Tell main we're running */
  semop(sem_id, &set_sem_0[0], 1) ;  

  while(semctl(sem_id, 1, GETVAL, 0) == 0)
  {
      /* Go DMA the data. */
    for(loop_cnt=0; loop_cnt<NUM_BUFS; loop_cnt++)
      {
        if( (ii = read(filedes,Buf_ptr[loop_cnt],BUFF_SIZE)) 
                 != BUFF_SIZE)
         {
             sys_errno = errno ;
             printf("Cont read returned %d. errno %d. Quitting read.\n", 
                  ii, sys_errno) ;
             loop_cnt = NUM_BUFS ;
             semop(sem_id, &set_sem_1[0], 1) ;  
         }
       } /* end for loop_cnt */
   } /* end while */

    /* Done - turn things off. */
  if( (ii = ioctl(filedes,IDRIO_BLOCK_END,arg.ulg)) != 0) 
    {
        sys_errno = errno ;
        printf("Block end failed. errno %d. sys_errno = %d. Continuing.\n",
                     ii, sys_errno) ;
     }

   /* Close the DR11 */
  if(close(filedes) < 0) 
    {
        ii = errno ;
        printf("Close DR11 failed. errno %d. Continuing.\n", ii) ;
     }

        /* Tell main we're done */
  semop(sem_id, &clr_sem_0[0], 1) ;  
  semop(sem_id, &clr_sem_1[0], 1) ;  
  
return(ii) ;

} /* End of rd_cont_to_buf */

/* -----------------------------------------------------------------
do_rd_data_to_file
-----------------------------------------------------------------*/ 

void do_rd_data_to_file(ikonbuf_t *Buf_ptr[NUM_BUFS], to_ikonmsg_t *cmd_msg, 
                  int sem_id, int msg_id)
{
   int error_num, wr_filedes ; 
   pid_t file_write_pid ; 


   if( (wr_filedes = setup_wr_file(cmd_msg)) < 0 ) { 
         puts("Can't open write file.") ;
         send_reply_msg(msg_id, MSTI_FOPEN_ERR) ; }
   else {
     if( (file_write_pid = fork1()) < 0) {
         error_num = errno ;
         send_reply_msg(msg_id, MSTI_FORK_ERR) ;
         printf("Can't fork. error %d.\n", error_num) ; }

     else if (file_write_pid == 0)  /* Child process - go write file */ 
       {

         if( (error_num = wr_buf_to_file(Buf_ptr, cmd_msg, 
                          wr_filedes, sem_id)) != 0) {
             printf("Write to file error. %d", error_num) ; }

       /*      send_reply_msg(msg_id, MSTI_WR_ERR) ; }    
         else send_reply_msg(msg_id, MSTI_OK) ; */    
          
        exit(error_num) ;
       }

     else      /* parent process */ 
       {
         if( (error_num = read_to_buf(Buf_ptr, cmd_msg, sem_id)) 
                   != 0) {
            send_reply_msg(msg_id, MSTI_RD_ERR) ;
            printf("Read to buf error. %d", error_num) ; }    
         else send_reply_msg(msg_id, MSTI_OK) ;     

             /* even if write has finished we're going to kill -- just to
                make sure no orphans are out there */ 
         kill(file_write_pid, SIGKILL) ;
        }

     fchmod(wr_filedes, 0666) ;
     close_wr_file(wr_filedes) ; 
    }

} /* End of do_rd_data_to_file */

/* -----------------------------------------------------------------
do_rd_cont_to_buf
-----------------------------------------------------------------*/ 

int do_rd_cont_to_buf(ikonbuf_t *Buf_ptr[NUM_BUFS], to_ikonmsg_t *cmd_msg, 
                  int sem_id) 
{
   int error_num, loop_cnt ;
   pid_t cont_rd_pid ; 


     if(semctl(sem_id, 0, GETVAL, 0) == 0) { 
         if( (cont_rd_pid = fork1()) < 0) {
           error_num = errno ;
           printf("Can't fork. error %d.\n", error_num) ; 
           error_num = MSTI_FORK_ERR ; }

         else if (cont_rd_pid == 0) /* Child process - go read cont */ 
              {
              if( (error_num = rd_cont_to_buf(Buf_ptr, cmd_msg, 
                            sem_id)) != 0) {
                 printf("Continuous read to buffer error. %d", error_num) ; }
               exit(error_num) ;
               }

         else      /* parent process */ 
           {
             for(loop_cnt=0; loop_cnt<4; loop_cnt++)
              {
                if(semctl(sem_id, 0, GETVAL, 0) != 1) { 
                    error_num = MSTI_CONT_RD_ERR ; 
                    sleep(1) ; }
                else { 
                    error_num = MSTI_OK ;     
                    loop_cnt = 4 ; }
              }
            }

       } /* If not already doing cont read */

         /* else already running. Send ok */
       else error_num = MSTI_OK ;     

     return(error_num) ;

} /* End of do_rd_cont_to_buf */

/* -----------------------------------------------------------------
stop_rd_cont_to_buf
-----------------------------------------------------------------*/ 

int stop_rd_cont_to_buf(int sem_id)  
{
   int error_num, loop_cnt ;

   struct sembuf set_sem_1[1] = {
            1, 1, 0  /* set sem 1 to quit. */
   } ;


   if(semctl(sem_id, 1, GETVAL, 0) == 0) { 
       semop(sem_id, &set_sem_1[0], 1) ;  }
   for(loop_cnt=0; loop_cnt<4; loop_cnt++)
    {
     if((semctl(sem_id, 0, GETVAL, 0)) | (semctl(sem_id, 1, GETVAL, 0)) != 0)
        { 
        error_num = MSTI_CONT_RD_ERR ; 
        sleep(1) ; }
     else { 
        error_num = MSTI_OK ;     
        loop_cnt = 4 ; }
    }

   return(error_num) ;

} /* end of stop_rd_cont_to_buf */

/* -----------------------------------------------------------------
do_fill_bufs
-----------------------------------------------------------------*/ 

int do_fill_bufs(ikonbuf_t *Buf_ptr[NUM_BUFS], to_ikonmsg_t *cmd_msg)  
{
  union {char ch[256] ; u_long ulg[64] ; } arg ;
  int filedes, loop_cnt, sys_errno, iii ;   
  int ii = 0 ; 

      /* Open the DR11 */
  if( (filedes = open(IKON_DEV_NAME, O_RDWR, 0666)) < 0 ) 
    {
      sys_errno = errno ;
      printf("Unable to open dr11. errno %d.\n", sys_errno) ;
      return(-1) ;
    }
  
      /* Setup for GO */
  arg.ulg[0] = IDR_GO ;

     /* Only RT_DAT or ST_DAT allowed.  Setup default to ST_DAT */
  if(cmd_msg->data_type != RT_DAT) cmd_msg->data_type = ST_DAT ;

     /* Initialize the DR11 */
  if(setup_dr11((long int) cmd_msg->data_type, filedes) != 0) 
    {
      puts("Aborting read to buffer.\n") ;
      return(-1) ;
    }

    /* Start FIFO input */
  if( (ii = ioctl(filedes,IDRIO_IMM_PULSE,arg.ulg)) != 0) 
    {
        sys_errno = errno ;
        printf("Go failed. errno %d. Sys_errno = %d. Continuing.\n", 
                    ii, sys_errno) ;
     }

      /* Go DMA the data. */
    for(loop_cnt=0; loop_cnt<NUM_BUFS; loop_cnt++)
      {
        if( (ii = read(filedes,Buf_ptr[loop_cnt],BUFF_SIZE)) 
                 != BUFF_SIZE)
         {
             sys_errno = errno ;
             printf("Cont read returned %d. errno %d. Quitting read.\n", 
                  ii, sys_errno) ;
             loop_cnt = NUM_BUFS ;
         }
       } /* end for loop_cnt */

    /* Done - turn things off. */
  if( (ii = ioctl(filedes,IDRIO_BLOCK_END,arg.ulg)) != 0) 
    {
        sys_errno = errno ;
        printf("Block end failed. errno %d. sys_errno = %d. Continuing.\n",
                     ii, sys_errno) ;
     }

   /* Close the DR11 */
  if(close(filedes) < 0) 
    {
        ii = errno ;
        printf("Close DR11 failed. errno %d. Continuing.\n", ii) ;
     }

return(ii) ;

} /* End of do_fill_bufs */