diff --git a/sinqhm/sinqhm_srv_routines.c b/sinqhm/sinqhm_srv_routines.c deleted file mode 100755 index 3ffaed88..00000000 --- a/sinqhm/sinqhm_srv_routines.c +++ /dev/null @@ -1,3320 +0,0 @@ -#define IDENT "1B06" -/* -** +--------------------------------------------------------------+ -** | Paul Scherrer Institute | -** | SINQ Division | -** | | -** | This software may be used freely by non-profit organizations.| -** | It may be copied provided that the name of P.S.I. and of the | -** | author is included. Neither P.S.I. nor the author assume any | -** | responsibility for the use of this software outside of P.S.I.| -** +--------------------------------------------------------------+ -** -** Module Name . . . . . . . . : [...SinqHM]SinqHM_srv_routines.c -** -** Author . . . . . . . . . . : D. Maden -** Date of creation . . . . . . : Dec 1996 -** -** Updates: -** 1A01 12-Dec-1996 DM Initial version. -** 1A06 16-Jul-1997 DM Flush fibre-optic FIFO on SQHM_ZERO and SQHM_WRITE. -** 1B01 11-Jun-1999 DM Add SQHM__HRPT mode. -** 1B02 10-Aug-1999 DM Make Lwl_hdr_daq_mask/Lwl_hdr_daq_soll dependent -** on the instrument. -**--------------------------------------------------------------------------- -** SinqHM_srv_routines.c is part of the SINQ Histogram Memory process -** which will run in a front-end processor and perform the necessary -** operations for a SINQ multi-detector. It provides various utility routines. -** -** To compile this program for VxWorks on PSS123, use: -** - ccvx SinqHM_srv_routines.c -** where - ccvx = ccppc -O0 \ - -mcpu=603 \ - -I${WIND_BASE}/target/h \ - -fno-builtin \ - -fno-for-scope \ - -nostdinc \ - -DCPU=PPC603 \ - -D_GNU_TOOL \ - -gdwarf -c -Wimplicit -**==================================================================== -*/ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* -**==================== Global Definitions ===================================== -*/ -#include "SinqHM_def.h" -#include "SinqHM_gbl.h" -#include "vmio10_def.h" - - extern char *vxWorksVersion; /* Version string of vxWorks */ - extern char *creationDate; /* Creation Date string of vxWorks */ -/*========================== Define some prototypes ================*/ -/* - -**============================================================================= -** Routines in this Module: -** -** SinqHM_routines_setup_id : copy some ident information to global vars. -** -** catch_int_signal : SIGINT signal catching routine. -** catch_machine_check : SIGBUS signal catching routine. -** catch_signal : Signal catching routine. -** chk_config_alloc : Check a configuration request and allocate memory. -** cleanup_children : Find out which child(ren) have exited. -** close_down_offspring : Close down FILLER and, possibly, other children. -** do_SQHM__HM_DIG_alloc: SQHM__HM_DIG aux routine for chk_config_alloc. -** do_SQHM__HRPT_alloc : SQHM__HRPT aux routine for chk_config_alloc. -** do_SQHM__TOF_alloc : SQHM__TOF aux routine for chk_config_alloc. -** do_SQHM__TRANS_alloc : SQHM__TRANS aux routine for chk_config_alloc. -** do_command : Routine to handle a network command. -** do_daq : Action routine for SINQHM_DAQ command. -** do_project : Read projected histogram data. -** do_read : Read a block of the histogram memory. -** do_write : Write a block of the histogram memory. -** do_zero : Action routine for SINQHM_ZERO command. -** failInet : Call to report fatal network failure. -** failInet_port : Call to failInet with an extra parameter. -** free_HM_memory : Release any allocated data structures. -** getErrno : Get local copy of errno. -** get_pid : Get our process ID (= TaskID under VxWorks). -** kill_children : Send stop signals to all children to stop them. -** lwl_Fifo_Flush : Flush out any data in the fibre-optic FIFO. -** lwl_Packet_Read : Read out current packet from the fibre-optic FIFO. -** make_child : Make a child process and activate it. -** make_filler : Make the filler process and activate it. -** net_flush : Flush out data from socket. -** process_coinc_tsi : Process a "coincidence" type TSI packet. -** process_no_coinc_tsi : Process a "normal" type TSI packet. -** rply_status_send : Send a reply status message to client. -** rply_status_setup : Setup a reply status message to client. -** rply_status_setup_and_send : Setup & send a reply status msg to client. -** selectNewBuffer : Move to new buffer in SQHM_TRANS mode. -** setupLevelGenerator : Set up VMIO10 module for generating timing signals. -** setup_inet_info : Used to get Internet Node name and addr from system. -** sleep : Go to sleep for a bit. -** StrJoin : join 2 strings. -**============================================================================== -*/ - void SinqHM_routines_setup_id () { -/* ======================== -** Simply copy some ident information to global variables -** for use by the SQHM_IDENT request. -*/ - StrJoin (Sqhm_rout_ident, sizeof (Sqhm_rout_ident), IDENT, ""); - StrJoin (Sqhm_rout_date, sizeof (Sqhm_rout_date), __DATE__, ", "); - StrJoin (Sqhm_rout_date, sizeof (Sqhm_rout_date), Sqhm_rout_date, __TIME__); - } -/* -**--------------------------------------------------------------------------*/ - void catch_int_signal (int signo) { -/* ================ -** Action Routine for catching SIGINT signals. This is a signal -** from the parent to get its child to exit. An exit will be performed. -*/ - int i, is; - pid_t my_pid; - - my_pid = get_pid (); - /* - ** Try to find our index by searching the PID list - */ - if (my_pid == Filler_pid) { - if (FillTimer_active) { /* If Filler, kill off timer */ - is = timer_cancel (FillTimerId); - if (is != 0) printf ("Problem cancelling FillTimer\n"); - is = timer_delete (FillTimerId); - if (is != 0) printf ("Problem deleting FillTimer\n"); - FillTimer_active = False; - } - }else { - for (i = MAX_CLIENTS; i > 0; i--) if (my_pid == Child_pid[i]) break; - if (i > 0) { - if (Child_rw_skt[i] != 0) { - printf ("\nClosing r/w socket of task %s\n", Tsk_name[i]); - close (Child_rw_skt[i]); - Child_rw_skt[i] = 0; - } - if (Child_cnct_skt[i] != 0) { - printf ("\nClosing connect socket of task %s\n", Tsk_name[i]); - close (Child_cnct_skt[i]); - Child_cnct_skt[i] = 0; - } - } - } - - if (Dbg_lev0) printf ("catch_int_signal: Signal %d received by PID 0x%x.\n", - signo, my_pid); - switch (signo) { - case SIGINT: /* A SIGINT signal has been received. Exit. */ - exit (KER__SUCCESS); - break; - default: - printf ("catch_int_signal: Unexpected signal %d received by PID 0x%x.\n", - signo, my_pid); - } - } -/* -**--------------------------------------------------------------------------*/ - void catch_machine_check (int signo) { -/* =================== -*/ - longjmp (Vmio_trap_env, 1); /* Return to trapped code */ - } -/* -**-------------------------------------------------------------------------- -*/ - void catch_signal (int signo) { -/* ============ -** Action Routine for catching signals from Child Processes. -*/ - pid_t my_pid; - - my_pid = get_pid (); - if (Dbg_lev0) printf ("catch_signal: Signal %d received by PID 0x%x.\n", - signo, my_pid); - switch (signo) { - case SIGUSR1: /* A child is about to exit. */ - Cnt_SIGUSR1++; - sleep (1); /* Give it a chance to disappear! */ - break; - default: - printf ("catch_signal: Unexpected signal received by PID 0x%x: %d.\n", - my_pid, signo); - } - } -/* -**--------------------------------------------------------------------------*/ - int chk_config_alloc ( -/* ================ -*/ int skt, - struct req_buff_struct *request, - struct rply_buff_struct *reply) { -/* -** -** Routine to check a configuration request and reserve the -** space for the histogram data. -** Return OK if configuration request OK. -** ERROR if error. -*/ - int i, mask, s_stat; - - Hm_mode_ALL = ntohl (request->u.cnfg.mode); /* The histogramming mode */ - - Hm_mode = Hm_mode_ALL & (~SQHM__SUB_MODE_MSK); - Hm_mode_DEBUG = Hm_mode_ALL & SQHM__DEBUG; - Hm_mode_UD = Hm_mode_ALL & SQHM__UD; - Hm_mode_BO = Hm_mode_ALL & SQHM__BO_MSK; - Hm_mode_STROBO = Hm_mode_ALL & SQHM__STROBO; - Hm_mode_REFLECT = Hm_mode_ALL & SQHM__REFLECT; - Hm_mode_NO_STAT = Hm_mode_ALL & SQHM__NO_STAT; - - switch (Hm_mode) { - /*----------------------------*/ - case SQHM__TRANS: - s_stat = do_SQHM__TRANS_alloc (request, reply); - if (s_stat != OK) return ERROR; - break; - /*----------------------------*/ - case SQHM__HM_DIG: - s_stat = do_SQHM__HM_DIG_alloc (request, reply); - if (s_stat != OK) return ERROR; - break; - /*----------------------------*/ - case SQHM__HRPT: - s_stat = do_SQHM__HRPT_alloc (request, reply); - if (s_stat != OK) return ERROR; - break; - /*----------------------------*/ - case SQHM__HM_PSD: - printf ("\nchk_config_alloc: " - "histogramming mode SQHM__HM_PSD is not yet supported.\n"); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Unsupported hist mem mode"); - return ERROR; - break; - /*----------------------------*/ - case SQHM__TOF: - s_stat = do_SQHM__TOF_alloc (skt, request, reply); - if (s_stat != OK) return ERROR; - break; - /*----------------------------*/ - default: - printf ("\nchk_config_alloc: " - "unrecognised histogramming mode: %d.\n", Hm_mode); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Unrecognised hist mem mode"); - return ERROR; - /*----------------------------*/ - } - Cfgn_done = 1; - return OK; - } -/* -**--------------------------------------------------------------------------*/ - void cleanup_children () { -/* ================ -** Find out which child(ren) have exited and update the -** list of task PID's so the associated task slot becomes -** free. -** -** If FILLER has fallen off, then any active children will -** be told to exit and we shall set our state to "deconfig". -*/ - int i, status, n_active; - char *t_name; - pid_t pid; - - if (Filler_pid != 0) { - if (Dbg_lev0) printf ("\n ... checking state of %s ...", Filler_name); - t_name = taskName (Filler_pid); - if (t_name == NULL) { - if (Dbg_lev0) printf (" it has exited."); - Filler_pid = 0; - }else { - if (Dbg_lev0) printf (" it is still active."); - } - } - - n_active = 0; - for (i = 1; i <= MAX_CLIENTS; i++) { - if (Child_pid[i] != 0) { - if (Dbg_lev0) printf ("\n ... checking state of SRV_%02d ...", i); - t_name = taskName (Child_pid[i]); - if (t_name == NULL) { - if (Dbg_lev0) printf (" it has exited."); - Child_pid[i] = 0; - }else { - if (Dbg_lev0) printf (" it is still active."); - n_active += 1; - } - } - } - Cnt_SIGUSR1 = 0; - - if ((Filler_pid == 0) && (n_active > 0)) { /* Must we force a de-config? */ - for (;;) { /* Loop for ever till programmed */ - printf ("\n\007hmFill has terminated abnormally. A de-configure must" - "be forced\n" - "This has not yet been programmed.\n" - "Re-boot the histogram memory!!\n"); - sleep (5); - } - } - } -/* -**--------------------------------------------------------------------------*/ - int close_down_offspring ( -/* ==================== -*/ struct req_buff_struct *request, - struct rply_buff_struct *reply) { -/* -** Close down FILLER and, if directed, other children too. -*/ - int i, j; - int n_children = 0, new_c = 0; - - n_children = 0; /* See if any server children are active */ - for (i = 1; i <= MAX_CLIENTS; i++) { - if (Child_pid[i] != 0) n_children += 1; - } - if (n_children > 0) { /* If so, only proceed if asked to be ruthless */ - if (ntohl (request->u.decnfg.sub_code) == 0) { - printf ("\nDe-configure error. "); - if (n_children == 1) printf ("1 server is"); - if (n_children != 1) printf ("%d servers are", n_children); - printf (" still active.\n"); - return KER__BAD_STATE; - }else { - if (n_children == 1) printf (" -- 1 server is still active. It"); - if (n_children != 1) printf (" -- %d servers are still active. They", - n_children); - printf (" will be terminated.\n"); - } - } - - kill_children (); /* Kill FILLER and any server children */ - sleep (1); /* Give them chance to exit */ - cleanup_children (); /* Update the PIDs */ - - for (j = 0; j < n_children; j++) { /* Check to see if all gone */ - if (Filler_pid == 0) new_c = 0; else new_c = 1; /* Count remainder */ - for (i = MAX_CLIENTS; i > 0; i--) { - if (Child_pid[i] != 0) new_c += 1; - } - if (new_c == 0) break; - sleep (1); - cleanup_children (); - } - if (new_c != 0) { - printf (" ... failed to tidy up. %d children still active.\n", new_c); - return KER__BAD_STATE; - }else { - return KER__SUCCESS; - } - } -/* -**--------------------------------------------------------------------------*/ - int do_SQHM__HM_DIG_alloc ( -/* ===================== -*/ struct req_buff_struct *request, - struct rply_buff_struct *reply) { -/* -** Routine to allocate memory for the SQHM__HM_DIG -** configure request. -** -*/ - int i; - - N_hists = ntohl (request->u.cnfg.u.hm_dig.n_hists); /* The # of - ** histograms (used in strobo (gummi) - ** and Up/Down mode). - */ - Lo_bin = ntohl (request->u.cnfg.u.hm_dig.lo_bin); /* The index of - ** first bin in histogram - */ - N_bins = ntohl (request->u.cnfg.u.hm_dig.num_bins); /* The # of bins - ** in each histogram - */ - Bytes_per_bin = ntohl (request->u.cnfg.u.hm_dig.bytes_per_bin); /* The # of - ** bytes per bin - */ - Compress = ntohl (request->u.cnfg.u.hm_dig.compress); /* The compression - ** factor - */ - Curr_hist = 0; /* The selected histogram */ - if (Compress == 0) Compress = 1; - if (Bytes_per_bin == 0) Bytes_per_bin = 4; - - if (N_hists > N_HISTS_MAX) { - printf ("do_SQHM__HM_DIG_alloc: Illegal number of histograms: %d.\n", - N_hists); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad number of histograms"); - return ERROR; - }else if (Hm_mode_UD && (N_hists & 1)) { - printf ("do_SQHM__HM_DIG_alloc: SQHM_UD is set.\n" - " Number of histograms should be multiple of 2.\n" - " %d is therefore illegal.\n", N_hists); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Number of histograms not multiple of 2"); - return ERROR; - }else if (Hm_mode_STROBO && (N_hists & 15)) { - printf ("do_SQHM__HM_DIG_alloc: SQHM_STROBO is set.\n" - " Number of histograms should be multiple of 16.\n" - " %d is therefore illegal.\n", N_hists); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Number of histograms not multiple of 16"); - return ERROR; - }else if (Hm_mode_UD && Hm_mode_STROBO && (N_hists & 31)) { - printf ("do_SQHM__HM_DIG_alloc: SQHM_UD and SQHM_STROBO are both set.\n" - " Number of histograms should be multiple of 32.\n" - " %d is therefore illegal.\n", N_hists); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Number of histograms not multiple of 32"); - return ERROR; - } - - if (Lo_bin > N_BINS_MAX) { - printf ("do_SQHM__HM_DIG_alloc: Illegal first bin: %d.\n", Lo_bin); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad first bin"); - return ERROR; - } - - if (N_bins > (N_BINS_MAX + 1)) { - printf ("do_SQHM__HM_DIG_alloc: Illegal number of bins: %d.\n", N_bins); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad # bins"); - return ERROR; - } - - Hi_bin = Lo_bin + N_bins - 1; - if (Hi_bin > N_BINS_MAX) { - printf ("do_SQHM__HM_DIG_alloc: Illegal first-bin and/or number-of-bins:" - " %d %d.\n", Lo_bin, N_bins); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad bin definition"); - return ERROR; - } - - if ((Bytes_per_bin != 1) && (Bytes_per_bin != 2) && (Bytes_per_bin != 4)) { - printf ("do_SQHM__HM_DIG_alloc: Illegal bin width: %d.\n", Bytes_per_bin); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad bytes-per-bin"); - return ERROR; - } - - Total_bytes = N_hists * N_bins * Bytes_per_bin; - if (Total_bytes > N_TOTAL_BYTES) { /* Check it's not too much */ - printf ("do_SQHM__HM_DIG_alloc: Illegal overall size: %d.\n", Total_bytes); - printf (" Permitted max: %d.\n", N_TOTAL_BYTES); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Total histogram size too big"); - return ERROR; - } - - printf ("\n Histogramming mode is \"SQHM__HM_DIG\"\n"); - printf (" Number of histograms = %5d\n", N_hists); - printf (" First bin = %5d\n", Lo_bin); - printf (" Number of bins = %5d\n", N_bins); - printf (" Bytes per bin = %5d\n", Bytes_per_bin); - printf (" Bin compression factor = %5d\n", Compress); - if (Hm_mode_UD != 0) - printf (" Up/Down mode selected\n"); - if (Hm_mode_STROBO != 0) - printf (" Stroboscopic mode selected\n"); - if (Hm_mode_REFLECT != 0) - printf (" Histograms will be reflected\n"); - printf (" Bin-overflow action is "); - switch (Hm_mode_BO) { - case SQHM__BO_IGN: printf ("\"Ignore\"\n"); break; - case SQHM__BO_SMAX: printf ("\"Stop-at-Max\"\n"); break; - case SQHM__BO_CNT: printf ("\"Count\"\n"); break; - default: printf ("\"Undefined\"\n"); - } - - i = memFindMax (); /* Get size of biggest free memory block */ - if (i > Total_bytes) { - Hist_base_addr = calloc (Total_bytes, sizeof (char)); - }else { - Hist_base_addr = NULL; - } - if (Hist_base_addr == NULL) { - printf ("\007do_SQHM__HM_DIG_alloc:\n" - " Unable to reserve %d bytes of memory!\n" - " Largest block available = %d.\n", Total_bytes, i); - rply_status_setup (reply, KER__BAD_ALLOC, i, - "Failed to get buffer for histograms"); - return ERROR; - } - Cnts_lo = Cnts_hi = 0; - N_events = N_skipped = N_no_coin_tsi = N_coin_tsi = 0; - Print_hdr = True; - - printf (" Histogram base address = 0x%08x\n", Hist_base_addr); - printf (" SQHM__HM_DIG mode configured.\n"); - return OK; - } -/* -**--------------------------------------------------------------------------*/ - int do_SQHM__HRPT_alloc ( -/* =================== -*/ struct req_buff_struct *request, - struct rply_buff_struct *reply) { -/* -** Routine to allocate memory for the SQHM__HRPT -** configure request. -** -*/ - int i; - - N_hists = ntohl (request->u.cnfg.u.hm_dig.n_hists); /* The # of - ** histograms (used in strobo (gummi) - ** and Up/Down mode). - */ - Lo_bin = ntohl (request->u.cnfg.u.hm_dig.lo_bin); /* The index of - ** first bin in histogram - */ - N_bins = ntohl (request->u.cnfg.u.hm_dig.num_bins); /* The # of bins - ** in each histogram - */ - Bytes_per_bin = ntohl (request->u.cnfg.u.hm_dig.bytes_per_bin); /* The # of - ** bytes per bin - */ - Compress = ntohl (request->u.cnfg.u.hm_dig.compress); /* The compression - ** factor - */ - Curr_hist = 0; /* The selected histogram */ - if (Compress == 0) Compress = 1; - if (Bytes_per_bin == 0) Bytes_per_bin = 4; - - if (N_hists > N_HISTS_MAX) { - printf ("do_SQHM__HRPT_alloc: Illegal number of histograms: %d.\n", - N_hists); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad number of histograms"); - return ERROR; - }else if (Hm_mode_UD && (N_hists & 1)) { - printf ("do_SQHM__HRPT_alloc: SQHM_UD is set.\n" - " Number of histograms should be multiple of 2.\n" - " %d is therefore illegal.\n", N_hists); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Number of histograms not multiple of 2"); - return ERROR; - }else if (Hm_mode_STROBO && (N_hists & 15)) { - printf ("do_SQHM__HRPT_alloc: SQHM_STROBO is set.\n" - " Number of histograms should be multiple of 16.\n" - " %d is therefore illegal.\n", N_hists); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Number of histograms not multiple of 16"); - return ERROR; - }else if (Hm_mode_UD && Hm_mode_STROBO && (N_hists & 31)) { - printf ("do_SQHM__HRPT_alloc: SQHM_UD and SQHM_STROBO are both set.\n" - " Number of histograms should be multiple of 32.\n" - " %d is therefore illegal.\n", N_hists); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Number of histograms not multiple of 32"); - return ERROR; - } - - if (Lo_bin > N_BINS_MAX) { - printf ("do_SQHM__HRPT_alloc: Illegal first bin: %d.\n", Lo_bin); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad first bin"); - return ERROR; - } - - if (N_bins > (N_BINS_MAX + 1)) { - printf ("do_SQHM__HRPT_alloc: Illegal number of bins: %d.\n", N_bins); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad # bins"); - return ERROR; - } - - Hi_bin = Lo_bin + N_bins - 1; - if (Hi_bin > N_BINS_MAX) { - printf ("do_SQHM__HRPT_alloc: Illegal first-bin and/or number-of-bins:" - " %d %d.\n", Lo_bin, N_bins); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad bin definition"); - return ERROR; - } - - if ((Bytes_per_bin != 1) && (Bytes_per_bin != 2) && (Bytes_per_bin != 4)) { - printf ("do_SQHM__HRPT_alloc: Illegal bin width: %d.\n", Bytes_per_bin); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad bytes-per-bin"); - return ERROR; - } - - Total_bytes = N_hists * N_bins * Bytes_per_bin; - if (Total_bytes > N_TOTAL_BYTES) { /* Check it's not too much */ - printf ("do_SQHM__HRPT_alloc: Illegal overall size: %d.\n", Total_bytes); - printf (" Permitted max: %d.\n", N_TOTAL_BYTES); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Total histogram size too big"); - return ERROR; - } - - printf ("\n Histogramming mode is \"SQHM__HRPT\"\n"); - printf (" Number of histograms = %5d\n", N_hists); - printf (" First bin = %5d\n", Lo_bin); - printf (" Number of bins = %5d\n", N_bins); - printf (" Bytes per bin = %5d\n", Bytes_per_bin); - printf (" Bin compression factor = %5d\n", Compress); - if (Hm_mode_UD != 0) - printf (" Up/Down mode selected\n"); - if (Hm_mode_STROBO != 0) - printf (" Stroboscopic mode selected\n"); - if (Hm_mode_REFLECT != 0) - printf (" Histograms will be reflected\n"); - printf (" Bin-overflow action is "); - switch (Hm_mode_BO) { - case SQHM__BO_IGN: printf ("\"Ignore\"\n"); break; - case SQHM__BO_SMAX: printf ("\"Stop-at-Max\"\n"); break; - case SQHM__BO_CNT: printf ("\"Count\"\n"); break; - default: printf ("\"Undefined\"\n"); - } - - i = memFindMax (); /* Get size of biggest free memory block */ - if (i > Total_bytes) { - Hist_base_addr = calloc (Total_bytes, sizeof (char)); - Frame_base_addr = calloc (((N_bins + 2) * Bytes_per_bin), sizeof (char)); - }else { - Hist_base_addr = NULL; - Frame_base_addr = NULL; - } - if (Hist_base_addr == NULL) { - free_HM_memory (NULL); - printf ("\007do_SQHM__HRPT_alloc:\n" - " Unable to reserve %d bytes of memory!\n" - " Largest block available = %d.\n", Total_bytes, i); - rply_status_setup (reply, KER__BAD_ALLOC, i, - "Failed to get buffer for histograms"); - return ERROR; - } - if (Frame_base_addr == NULL) { - free_HM_memory (NULL); - printf ("\007do_SQHM__HRPT_alloc:\n" - " Unable to reserve %d bytes of memory for frame buffer!\n" - " Largest block available = %d.\n", ((N_bins + 2) * Bytes_per_bin), i); - rply_status_setup (reply, KER__BAD_ALLOC, i, - "Failed to get frame buffer"); - return ERROR; - } - Cnts_lo = Cnts_hi = 0; - N_events = N_skipped = N_no_coin_tsi = N_coin_tsi = 0; - Print_hdr = True; - - printf (" Histogram base address = 0x%08x\n", Hist_base_addr); - printf (" Frame buffer base address = 0x%08x\n", Frame_base_addr); - printf (" SQHM__HRPT mode configured.\n"); - return OK; - } -/* -**--------------------------------------------------------------------------*/ - int do_SQHM__TRANS_alloc ( -/* ==================== -*/ struct req_buff_struct *request, - struct rply_buff_struct *reply) { -/* -** Routine to allocate memory for the SQHM__TRANS -** configure request. -*/ - int i; - - N_hists = ntohl (request->u.cnfg.u.trans.n_buffs); /* The # of buffers */ - N_bins = ntohl (request->u.cnfg.u.trans.n_bytes); /* The buffer size */ - Bytes_per_bin = 1; - Curr_hist = 0; /* Start with the first buffer */ - Bytes_free = N_bins; - - Lo_cntr = Lo_bin = Hi_bin = Compress = Cnts_lo = Cnts_hi = 0; - - if ((N_hists == 0) || (N_hists > N_HISTS_MAX)) { - printf ("do_SQHM__TRANS_alloc: Illegal number of buffers: %d.\n", - N_hists); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad number of buffers"); - return ERROR; - } - - if ((N_bins < 23) || (N_bins > (N_BINS_MAX + 1))) { - printf ("do_SQHM__TRANS_alloc: Illegal buffer size: %d.\n", N_bins); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Illegal buffer size"); - return ERROR; - } - - Total_bytes = N_hists * (N_bins + 4); - if (Total_bytes > N_TOTAL_BYTES) { /* Check it's not too much */ - printf ("do_SQHM__TRANS_alloc: Illegal overall size: %d.\n", Total_bytes); - printf (" Permitted max: %d.\n", N_TOTAL_BYTES); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Total buffer size too big"); - return ERROR; - } - - printf ("\n Histogramming mode is \"SQHM__TRANS\"\n"); - printf (" Number of buffers = %5d\n", N_hists); - printf (" Buffer size = %5d bytes\n", N_bins); - - i = memFindMax (); /* Get size of biggest free memory block */ - if (i > Total_bytes) { - Hist_base_addr = calloc (Total_bytes, sizeof (char)); - }else { - Hist_base_addr = NULL; - } - if (Hist_base_addr == NULL) { - printf ("\007do_SQHM__TRANS_alloc:\n" - " Unable to reserve %d bytes of memory!\n" - " Largest block available = %d.\n", Total_bytes, i); - rply_status_setup (reply, KER__BAD_ALLOC, i, - "Failed to get space for buffers"); - return ERROR; - } - - Tran_buff_base = Hist_base_addr; - Next_char = Tran_buff_base + 4; - printf (" Buffer base address = 0x%08x\n", Hist_base_addr); - printf (" SQHM__TRANS mode configured.\n"); - return OK; - } -/* -**--------------------------------------------------------------------------*/ - int do_SQHM__TOF_alloc ( -/* ================== -*/ int skt, - struct req_buff_struct *request, - struct rply_buff_struct *reply) { -/* -** Routine to allocate memory for the SQHM__TOF -** configure request. -** -** Definitions: -** Edge-Array -** An 'edge-array' is a structure which specifies the lower edge -** of each bin in the histogram. This is to allow variable width -** histogram bins. -** Counter Bank -** A 'counter bank' is a contiguous group of counters, all of -** which share the same parameters. In particular, all the counters -** in the bank have the same number of bins and same bin edges. -*/ - int i, j, k, n_bytes_got; - uint n_extra_bytes, n_banks, com2, nchar; - uint first, n_cntrs, edge_indx, bytes_per_bin; - uint n_bins, flag, edge_0, edge_1, bin_span, top_edge; - uint bytes_needed, sizeof_edge_arr; - uint time_span, n_total_bins; - struct tof_edge_info *edge_info_pntr; - struct tof_edge_arr *edge_arr_pntr; - struct tof_bank *bank_pntr; - void *nxt_hist_addr; - struct req_buff_struct *my_rqst; - char *p_addr, buff[64]; - - Total_bytes = 0; - - n_extra_bytes = ntohl (request->u.cnfg.u.tof.n_extra_bytes); /* The # of - ** extra bytes needed to be read from - ** the client to complete the configure - ** request. - */ - if (n_extra_bytes == 0) { - my_rqst = request; - }else { - /* - ** There is extra data to be read. Get buffer space for the - ** extra stuff plus space to copy over what has already been - ** read so that everything is in a contiguous buffer. - */ - bytes_needed = n_extra_bytes + sizeof (*request); - bytes_needed = (bytes_needed + 3) & (~3); /* Round up to multiple of 4 */ - p_addr = calloc (bytes_needed, sizeof (char)); - if (p_addr == NULL) { - printf ("\007do_SQHM__TOF_alloc:\n" - " cannot allocate memory for extra config data!\n"); - net_flush (skt, n_extra_bytes); - rply_status_setup (reply, KER__BAD_ALLOC, 0, - "Failed to get buffer for extra config data"); - return ERROR; - } - memcpy (p_addr, request, sizeof (*request)); /* Copy in what has already - ** been read. - */ - my_rqst = (struct req_buff_struct *) p_addr; - - bytes_needed = n_extra_bytes; /* And read the rest */ - p_addr = p_addr + sizeof (*request); - while (bytes_needed > 0) { - n_bytes_got = recv (skt, p_addr, bytes_needed, 0); - if (n_bytes_got <= 0) break; - Rw_bytes_got += n_bytes_got; - bytes_needed -= n_bytes_got; - p_addr += n_bytes_got; - } - if (n_bytes_got < 0) { - printf ("\007" - "%s -- R/W-Socket recv error\n", Tsk_name[0]); - printf ("%s -- Connection will be closed.\n", Tsk_name[0]); - rply_status_setup (reply, KER__BAD_VALUE, 0, "recv failed"); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - } - - printf ("\n Histogramming mode is \"SQHM__TOF\"\n"); - - if (Hm_mode_UD != 0) - printf (" Up/Down mode selected\n"); - if (Hm_mode_STROBO != 0) - printf (" Stroboscopic mode selected\n"); - printf (" Bin-overflow action is "); - switch (Hm_mode_BO) { - case SQHM__BO_IGN: printf ("\"Ignore\"\n"); break; - case SQHM__BO_SMAX: printf ("\"Stop-at-Max\"\n"); break; - case SQHM__BO_CNT: printf ("\"Count\"\n"); break; - default: printf ("\"Undefined\"\n"); - } - - N_tof_edges = ntohs (my_rqst->u.cnfg.u.tof.n_edges); /* The # of - ** different 'edge-arrays' which are - ** to be defined. - */ - printf (" Number of Edge Arrays = %2d\n", N_tof_edges); - if (N_tof_edges > MAX_TOF_EDGE) { - printf ("do_SQHM__TOF_alloc: Illegal number of edge-arrays: %u.\n", - N_tof_edges); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Too many edge-arrays"); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - - n_banks = ntohs (my_rqst->u.cnfg.u.tof.n_banks); /* The # of - ** 'banks' of counters which are - ** to be defined. - */ - printf (" Number of Counter Banks = %2d\n", n_banks); - if (n_banks == 0) { - rply_status_setup (reply, KER__BAD_VALUE, 0, "Illegal n_banks"); - printf ("do_SQHM__TOF_alloc: Illegal number of banks: %u.\n", - n_banks); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - - Tof_dts_soll = ntohl (my_rqst->u.cnfg.u.tof.preset_delay); /* The - ** required "Delay-Time-to-Start" */ - if ((Tof_dts_soll & (~LWL_TSI_DTS_MSK)) != 0) { - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad Delay-Time-to-Start"); - printf ("do_SQHM__TOF_alloc: Delay-Time-to-Start illegal: 0x%x\n", - Tof_dts_soll); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - com2 = open ("/tyCo/1", O_RDWR, 0); /* Send DTS to MDI via COM2 port */ - if (com2 == ERROR) { - rply_status_setup (reply, KER__BAD_VALUE, 0, "COM2 open failed"); - printf ("do_SQHM__TOF_alloc: error opening COM2 port. " - "Delay-Time-to-Start not set.\n"); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - }else { - ioctl (com2, FIOBAUDRATE, 9600); - write (com2, "\r", 1); - write (com2, "RMT 1\r", 6); - nchar = sprintf (buff, "DT %d\r", Tof_dts_soll); - if (write (com2, buff, nchar) != nchar) { - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Setting D-T-to-S failed"); - printf ("do_SQHM__TOF_alloc: error setting Delay-Time-to-Start.\n"); - if (n_extra_bytes != 0) free (my_rqst); - close (com2); - return ERROR; - }else { - printf (" Delay-Time-to-Start = %d\n", Tof_dts_soll); - } - close (com2); - } - /* - ** Loop over all the edge arrays - */ - edge_arr_pntr = &my_rqst->u.cnfg.u.tof.edge_0; - for (i = 0; i < N_tof_edges; i++) { - n_bins = ntohl (edge_arr_pntr->n_bins); - flag = ntohl (edge_arr_pntr->flag); - edge_0 = ntohl (edge_arr_pntr->edges[0]); - edge_1 = ntohl (edge_arr_pntr->edges[1]); - printf (" Edge Array %d:\n", i); - printf (" Number of bins = %5d\n", n_bins); - printf (" Flag = %5d\n", flag); - printf (" Lower edge = %5d\n", edge_0); - if ((n_bins == 0) || (n_bins > MAX_TOF_NBINS)) { - printf ("do_SQHM__TOF_alloc: Illegal # bins: %u.\n", - n_bins); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad number of bins"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - if ((edge_0 & (~LWL_HDR_TS_MASK)) != 0) { - printf ("do_SQHM__TOF_alloc: histog start is > 20 bits: %u\n", - edge_0); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Bin edges overflow 20 bits"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - if ((edge_1 & (~LWL_HDR_TS_MASK)) != 0) { - printf ("do_SQHM__TOF_alloc: first bin is > 20 bits: %u\n", - edge_1); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "First bin overflows 20 bits"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - bytes_needed = OffsetOf (struct tof_edge_info, edges) + - ((n_bins + 1) * sizeof (int)); - Tof_edges[i] = calloc (bytes_needed, sizeof (char)); /* Allocate space for - ** edge-array structure */ - if (Tof_edges[i] == NULL) { - printf ("do_SQHM__TOF_alloc: unable to alloc memory for edge array.\n"); - rply_status_setup (reply, KER__BAD_ALLOC, 0, - "Failed to get memory for edge-array"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - Tof_edges[i]->n_bins = n_bins; - Tof_edges[i]->flag = flag; - if ((flag & FLAG__VAR_BIN) == 0) { /* Fixed width bins? */ - printf (" Bin width = %5d\n", (edge_1 - edge_0)); - if (edge_0 >= edge_1) { /* Yes. Check bin width */ - printf ("do_SQHM__TOF_alloc: bin width is zero or negative!\n"); - rply_status_setup (reply, KER__BAD_VALUE, 0, "illegal bin width"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - bin_span = edge_1 - edge_0; - Tof_edges[i]->bin_span = bin_span; - top_edge = edge_0 + (n_bins * bin_span) - 1; - if ((top_edge & (~LWL_HDR_TS_MASK)) != 0) { - printf ("do_SQHM__TOF_alloc: histog last bin is > 20 bits: %u\n", - top_edge); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Last bin overflows 20 bits"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - for (j=0; j <= n_bins; j++) Tof_edges[i]->edges[j] = edge_0+j*bin_span; - Tof_edges[i]->hi_edge = top_edge; - sizeof_edge_arr = OffsetOf (struct tof_edge_arr, edges) + - 2 * sizeof (uint); - }else { - /* Variable width bins */ - bin_span = edge_1 - edge_0; /* Note: even though the edges are - ** defined as variable, they may, in - ** fact, all be the same width. Check - ** for this so that we can make a brief - ** report rather than listing all - ** the bin edges. - */ - Tof_edges[i]->bin_span = 0; - Tof_edges[i]->edges[0] = edge_0; - for (j = 1; j <= n_bins; j++) { - Tof_edges[i]->edges[j] = ntohl (edge_arr_pntr->edges[j]); - if ((Tof_edges[i]->edges[j] & (~LWL_HDR_TS_MASK)) != 0) { - printf ("do_SQHM__TOF_alloc: histog bin is > 20 bits: %d %u\n", - j, Tof_edges[i]->edges[j]); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Bin edge overflows 20 bits"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - if (Tof_edges[i]->edges[j-1] >= Tof_edges[i]->edges[j]) { - printf ("do_SQHM__TOF_alloc: bin edges are not in sequence: %d %d\n", - i, j); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Bin edges not in sequence"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - if ((Tof_edges[i]->edges[j] - Tof_edges[i]->edges[j-1]) != bin_span) - bin_span = 0; /* Set bin_span to zero if bin widths really are - ** variable */ - } - if (bin_span != 0) { - printf (" Variable width bins but width of all bins = %d\n", - bin_span); - }else { - printf (" Variable width bins. Upper bin edges are:\n"); - for (j = 1; j <= n_bins; j += 10) { - for (k = 0; ((k + j) <= n_bins) && (k < 10); k++) - printf ("%7d", Tof_edges[i]->edges[j+k]); - printf ("\n"); - } - } - Tof_edges[i]->hi_edge = Tof_edges[i]->edges[n_bins] - 1; - sizeof_edge_arr = OffsetOf (struct tof_edge_arr, edges) + - ((n_bins + 1) * sizeof (uint)); - } - edge_arr_pntr = (struct tof_edge_arr *) ( /* Move to next edge array */ - (char *) edge_arr_pntr + sizeof_edge_arr); - } - /* - ** Loop over all the counter banks - */ - bank_pntr = (struct tof_bank *) edge_arr_pntr; - - for (i = 0; i < n_banks; i++) { - - first = ntohs (bank_pntr->first); - n_cntrs = ntohs (bank_pntr->n_cntrs); - edge_indx = ntohs (bank_pntr->edge_indx); - bytes_per_bin = ntohs (bank_pntr->bytes_per_bin); - - printf (" Counter Bank %d:\n", i); - printf (" Number of counters = %5d\n", n_cntrs); - printf (" First counter = %5d\n", first); - if (N_tof_edges > 1) { - printf (" Edge array #%d\n", edge_indx); - } - printf (" Bytes per bin = %5d\n", bytes_per_bin); - - if (first >= MAX_TOF_CNTR) { - printf ("do_SQHM__TOF_alloc: Illegal first counter number: %u.\n", - first); - rply_status_setup (reply, KER__BAD_VALUE, 0, - "Bad first counter number"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - - if ((n_cntrs == 0) || ((first+n_cntrs) > MAX_TOF_CNTR)) { - printf ("do_SQHM__TOF_alloc: Illegal # counters: %u %u.\n", - first, n_cntrs); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad # counters"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - - if (edge_indx >= N_tof_edges) { - printf ("do_SQHM__TOF_alloc: Illegal edge index: %u.\n", - edge_indx); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad edge-array index"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - edge_info_pntr = Tof_edges[edge_indx]; - n_bins = edge_info_pntr->n_bins; - flag = edge_info_pntr->flag; - - if (bytes_per_bin == 0) bytes_per_bin = 4; - if ((bytes_per_bin != 1) && - (bytes_per_bin != 2) && - (bytes_per_bin != 4)) { - printf ("do_SQHM__TOF_alloc: Illegal bytes per bin: %d.\n", - bytes_per_bin); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad bytes-per-bin"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - - Total_bytes += (n_cntrs * n_bins * bytes_per_bin); - if (Hm_mode_UD != 0) Total_bytes += (n_cntrs * n_bins * bytes_per_bin); - - for (j = first; j < (first + n_cntrs); j++) { - if (Tof_descr[j] != NULL) { - printf ("do_SQHM__TOF_alloc: Doubly defined counter: %d.\n", - (j)); - rply_status_setup (reply, KER__BAD_VALUE, 0, "Doubly defined counter"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - Tof_descr[j] = calloc (1, sizeof (struct tof_histog)); - if (Tof_descr[j] == NULL) { - printf ("do_SQHM__TOF_alloc: unable to alloc memory for " - "histogram structure.\n"); - rply_status_setup (reply, KER__BAD_ALLOC, 0, - "Failed to get buffer for Tof_descr structure"); - free_HM_memory (NULL); - if (n_extra_bytes != 0) free (my_rqst); - return ERROR; - } - Tof_descr[j]->cntr_nmbr = first + j; - Tof_descr[j]->lo_edge = edge_info_pntr->edges[0]; - Tof_descr[j]->hi_edge = edge_info_pntr->hi_edge; - Tof_descr[j]->flag = flag; - Tof_descr[j]->bytes_per_bin = bytes_per_bin; - Tof_descr[j]->n_bins = n_bins; - Tof_descr[j]->cnt_early_up = 0; - Tof_descr[j]->cnt_late_up = 0; - Tof_descr[j]->cnt_early_down = 0; - Tof_descr[j]->cnt_late_down = 0; - Tof_descr[j]->bin_edge = edge_info_pntr->edges; - Tof_descr[j]->u.b_bin_data = NULL; - } - - if (i == 0) { /* Use the first counter bank to define some .. */ - N_hists = n_cntrs; /* .. globals since we expect there usually to .. */ - /* .. be only 1 counter bank. */ - N_bins = n_bins; - Lo_cntr = first; - Lo_bin = edge_info_pntr->edges[0]; - Hi_bin = edge_info_pntr->hi_edge; - Compress = ((flag & FLAG__VAR_BIN) == 0) ? - edge_info_pntr->edges[1] - edge_info_pntr->edges[0] : - 0; - Bytes_per_bin = bytes_per_bin; - Cnts_lo = Cnts_hi = 0; - } - - bank_pntr++; /* Move to next counter bank */ - } - - if (n_extra_bytes != 0) free (my_rqst); - - i = memFindMax (); /* Get size of biggest free memory block */ - if (i > Total_bytes) { - Hist_base_addr = calloc (Total_bytes, sizeof (char)); - }else { - Hist_base_addr = NULL; - } - if (Hist_base_addr == NULL) { - printf ("\007do_SQHM__TOF_alloc:\n" - " Unable to reserve %d bytes of memory!\n" - " Largest block available = %d.\n", Total_bytes, i); - rply_status_setup (reply, KER__BAD_ALLOC, i, - "Failed to get buffer for histograms"); - reply->sub_status = htonl (i); - return ERROR; - } - nxt_hist_addr = Hist_base_addr; - for (i = 0; i < MAX_TOF_CNTR; i++) { - if (Tof_descr[i] != NULL) { - Tof_descr[i]->u.b_bin_data = nxt_hist_addr; - j = Tof_descr[i]->n_bins * Tof_descr[i]->bytes_per_bin; - if (Hm_mode_UD != 0) j = j * 2; - nxt_hist_addr += j; - } - } - Cnts_lo = Cnts_hi = 0; - N_events = N_skipped = N_no_coin_tsi = N_coin_tsi = 0; - Print_hdr = True; - - printf (" Histogram base address = 0x%08x\n", Hist_base_addr); - printf (" SQHM__TOF mode configured.\n"); - return OK; - } -/* -**--------------------------------------------------------------------------*/ - int do_command ( -/* ========== -*/ int index, - int skt, - int pkt_size, - struct req_buff_struct *rqst, - struct rply_buff_struct *reply) { -/* -** Action routine for an SQHM_??? command. -** The command is processed (including returning a -** status response message). -*/ - int status, indx, is, suspendMode, i, j, sub_cmnd; - int txt_len, txt_offset, bytes_to_go; - int my_first_bin, my_nbins, my_bytes_per_bin, my_hist_no; - int my_sub_code, my_x_lo, my_nx, my_y_lo, my_ny, my_xdim, my_h_slct; - time_t secs; - char *msge, *p_buff, *p_txt; - - reply->bigend = htonl (0x12345678); /* Put in the "endian" flag. */ - rply_status_setup (reply, KER__SUCCESS, 0, "All OK"); - - switch (ntohl (rqst->cmnd)) { - - case SQHM_CLOSE: /* Close the connection. */ - return ERROR; /* Do nothing. */ - - case SQHM_CNCT: /* Make a new connection. */ - printf ("%s -- connecting ..", Tsk_name[index]); - - time (&secs); - secs = secs - Sqhm_start_time; - reply->u.cnct.up_time = htonl (secs); - - if (Cfgn_done == 0) { /* Check we've been configured */ - printf ("\007 but not yet configured!\n"); - is = rply_status_setup_and_send (skt, reply, KER__BAD_STATE, 0, - "Not configured"); - }else if (index != 0) { - printf ("\007 but not issued to SinqHM-master!\n"); - is = rply_status_setup_and_send (skt, reply, KER__BAD_STATE, 0, - "Not SinqHM-master"); - }else { - pkt_size = ntohl (rqst->u.cnct.max_pkt); - if ((pkt_size < 1024) || (pkt_size > 8192)) pkt_size = 8192; - pkt_size = pkt_size & ~3; /* Ensure pkt_size is multiple of 4 */ - indx = make_child (SinqHM_server, - ntohl (rqst->u.cnct.strt_mode), - pkt_size); - if (indx <= 0) { /* Child created and ready? */ - printf ("\n\007%s -- creation of child failed: %d.\n", - Tsk_name[0], indx); - switch (indx) { - case -1: msge = "Spawn failed"; break; - case -2: msge = "No more ports"; break; - case -3: msge = "Time-out of child start-up"; break; - case -4: msge = "Child could not get started"; break; - default: msge = "Bad status from make_child"; - } - is = rply_status_setup_and_send (skt, reply, KER__BAD_CREATE, - indx, msge); - }else { /* Yes, child is up and ready. */ - reply->u.cnct.port = htonl (Port_base + indx); - reply->u.cnct.pkt_size = htonl (pkt_size); - reply->u.cnct.hm_mode = htonl (Hm_mode_ALL); - reply->u.cnct.n_hists = htonl (N_hists); - reply->u.cnct.num_bins = htonl (N_bins); - reply->u.cnct.bytes_per_bin = htonl (Bytes_per_bin); - reply->u.cnct.curr_hist = htonl (Curr_hist); - reply->u.cnct.max_block = htonl (memFindMax ()); /* Max free mem */ - reply->u.cnct.total_bytes = htonl (Total_bytes); - reply->u.cnct.lo_cntr = htonl (Lo_cntr); - reply->u.cnct.lo_bin = htonl (Lo_bin); - reply->u.cnct.compress = htonl (Compress); - printf (" %s started. Packet size = %d.\n", Tsk_name[indx], pkt_size); - is = rply_status_send (skt, reply); - } - } - if (is != OK) - printf ("\n%s -- send of status reply failed.\n", Tsk_name[index]); - return is; - - case SQHM_CONFIG: - printf ("%s: Configure ..", Tsk_name[index]); - if (Cfgn_done) { - is = rply_status_setup_and_send (skt, reply, KER__BAD_STATE, 0, - "Already configured"); - printf ("\007 already configured!\n"); - return ERROR; - } - - free_HM_memory (NULL); /* There should be no memory allocated but - ** go and release it anyway! - */ - is = chk_config_alloc (skt, rqst, reply); /* No, check config msg .. */ - if (is != OK) { /* .. and alloc mem */ - rply_status_send (skt, reply); - return ERROR; - } - - suspendMode = (Hm_mode_DEBUG != 0) ? 1 : 0; /* The mode for Filler */ - is = make_filler (suspendMode); /* If OK so far, start FILLER. */ - if (is <= 0) { /* Was FILLER created OK? */ - rply_status_setup_and_send (skt, reply, KER__BAD_CREATE, is, /* No */ - "Filler creation failed"); - printf ("\n%s -- creation of FILLER failed: %d.\n", - Tsk_name[index], status); - free_HM_memory (NULL); - Cfgn_done = 0; - return ERROR; - }else { /* Yes, child is up and ready. */ - printf (" .. configuration complete, %s has been started.\n", - Filler_name); - is = rply_status_send (skt, reply); - if (is != OK) - printf ("\n%s -- send of status reply failed.\n", Tsk_name[index]); - return is; - } - - case SQHM_DAQ: /* Start or stop data acquisition. */ - printf ("%s: DAQ", Tsk_name[index]); - if (!Cfgn_done) { /* Configured yet? */ - rply_status_setup_and_send (skt, reply, KER__BAD_STATE, 0, /* No */ - "Not configured"); - printf ("\007: not configured!\n"); - return ERROR; - } - sub_cmnd = ntohl (rqst->u.daq.sub_cmnd); - if (sub_cmnd == DAQ__CLR) printf ("/DAQ__CLR:"); - if (sub_cmnd == DAQ__GO) printf ("/DAQ__GO:"); - if (sub_cmnd == DAQ__INH) printf ("/DAQ__INH:"); - if (sub_cmnd == DAQ__STOP) printf ("/DAQ__STOP:"); - if (sub_cmnd == DAQ__TST) printf ("/DAQ__TST:"); - - do_daq (reply, index, sub_cmnd); - - if (SinqHM_Dsbl_Mask == 0) { - printf (" data acquisition is active.\n"); - }else { - printf (" data acquisition is inhibited.\n"); - } - - is = rply_status_send (skt, reply); - if (is != OK) - printf ("\n%s -- send of status reply failed.\n", Tsk_name[index]); - return is; - - case SQHM_DBG: /* Set debug parameters. */ - Dbg_mask = ntohl (rqst->u.dbg.mask); - Dbg_lev0 = ((Dbg_mask & 1) != 0) ? 1 : 0; - Dbg_lev1 = ((Dbg_mask & 2) != 0) ? 1 : 0; - Dbg_lev2 = ((Dbg_mask & 4) != 0) ? 1 : 0; - Dbg_lev3 = ((Dbg_mask & 8) != 0) ? 1 : 0; - printf ("%s: Debug mask = 0x%x\n", Tsk_name[index], Dbg_mask); - is = rply_status_setup_and_send (skt, reply, KER__SUCCESS, 0, NULL); - if (is != OK) - printf ("\n%s -- send of status reply failed.\n", Tsk_name[index]); - return is; - - case SQHM_DECONFIG: /* Close down FILLER (and any servers)? */ - printf ("%s: De-configure", Tsk_name[index]); - if (!Cfgn_done) { /* Anything to do? */ - printf (" -- already de-configured!\n"); - is = rply_status_setup_and_send (skt, reply, KER__SUCCESS, 0, NULL); - }else if (index != 0) { - printf ("\007 -- not issued to SinqHM-master!\n"); - is = rply_status_setup_and_send (skt, reply, KER__BAD_STATE, 0, - "Not SinqHM-master"); - }else { - is = close_down_offspring (rqst, reply); - if (is == KER__SUCCESS) { - printf (" done.\n"); - Cfgn_done = 0; - is = rply_status_setup_and_send (skt, reply, KER__SUCCESS, 0, NULL); - }else { - printf ("\n\007Failed! Problem terminating children.\n"); - is = rply_status_setup_and_send (skt, reply, KER__BAD_STATE, is, - "Problem terminating children"); - } - free_HM_memory (NULL); /* Release all reserved memory */ - } - if (is != OK) - printf ("\n%s -- send of status reply failed.\n", Tsk_name[index]); - return is; - - case SQHM_EXIT: /* Rundown */ - printf ("%s: Run-down", Tsk_name[index]); - if (index != 0) { - printf ("\007 -- not issued to SinqHM-master!\n"); - is = rply_status_setup_and_send (skt, reply, KER__BAD_STATE, 0, - "Not SinqHM-master"); - }else { - rqst->u.decnfg.sub_code = htonl (1); /* Set "harshness" = 1 */ - is = close_down_offspring (rqst, reply); - if (is == KER__SUCCESS) { - printf (" done.\n"); - Cfgn_done = 0; - is = rply_status_setup_and_send (skt, reply, KER__SUCCESS, 0, NULL); - }else { - printf ("\007 -- warning -- problem terminating children.\n"); - is = rply_status_setup_and_send (skt, reply, KER__BAD_STATE, is, - "Problem terminating children"); - } - free_HM_memory (NULL); /* Release all reserved memory */ - } - if (is != OK) - printf ("\n%s -- send of status reply failed.\n", Tsk_name[index]); - return OK; - - case SQHM_IDENT: /* Give info on software identification. */ - txt_len = IDENT_MSGE_LEN; - txt_offset = 0; - p_buff = calloc (txt_len, 1); /* Get a buffer for text info */ - if (p_buff == NULL) { - printf ("\n\007%s -- SQHM_IDENT: failed to get buffer!\n", - Tsk_name[index]); - rply_status_setup_and_send (skt, reply, KER__BAD_ALLOC, 0, - "Failed to get buffer for composing Ident"); - return ERROR; - } - time (&secs); - secs = secs - Sqhm_start_time; - reply->u.ident.up_time = htonl (secs); - reply->u.ident.n_extra_bytes = htonl (IDENT_MSGE_LEN); - p_txt = p_buff; - - reply->u.ident.offset_vxWorks_ident = htons (txt_offset); - StrJoin (p_txt, txt_len, vxWorksVersion, ""); - i = strlen (p_txt) + 1; - txt_offset += i; p_txt += i; txt_len -= i; - - reply->u.ident.offset_vxWorks_date = htons (txt_offset); - StrJoin (p_txt, txt_len, creationDate, ""); - i = strlen (p_txt) + 1; - txt_offset += i; p_txt += i; txt_len -= i; - - reply->u.ident.offset_instr = htons (txt_offset); - StrJoin (p_txt, txt_len, Instr_name, ""); - i = strlen (p_txt) + 1; - txt_offset += i; p_txt += i; txt_len -= i; - - reply->u.ident.offset_def_ident = htons (txt_offset); - StrJoin (p_txt, txt_len, Def_ident, ""); - i = strlen (p_txt) + 1; - txt_offset += i; p_txt += i; txt_len -= i; - - reply->u.ident.offset_sinqhm_main_ident = htons (txt_offset); - StrJoin (p_txt, txt_len, Sqhm_main_ident, ""); - i = strlen (p_txt) + 1; - txt_offset += i; p_txt += i; txt_len -= i; - - reply->u.ident.offset_sinqhm_main_date = htons (txt_offset); - StrJoin (p_txt, txt_len, Sqhm_main_date, ""); - i = strlen (p_txt) + 1; - txt_offset += i; p_txt += i; txt_len -= i; - - reply->u.ident.offset_sinqhm_server_ident = htons (txt_offset); - StrJoin (p_txt, txt_len, Sqhm_serv_ident, ""); - i = strlen (p_txt) + 1; - txt_offset += i; p_txt += i; txt_len -= i; - - reply->u.ident.offset_sinqhm_server_date = htons (txt_offset); - StrJoin (p_txt, txt_len, Sqhm_serv_date, ""); - i = strlen (p_txt) + 1; - txt_offset += i; p_txt += i; txt_len -= i; - - reply->u.ident.offset_sinqhm_filler_ident = htons (txt_offset); - StrJoin (p_txt, txt_len, Sqhm_fill_ident, ""); - i = strlen (p_txt) + 1; - txt_offset += i; p_txt += i; txt_len -= i; - - reply->u.ident.offset_sinqhm_filler_date = htons (txt_offset); - StrJoin (p_txt, txt_len, Sqhm_fill_date, ""); - i = strlen (p_txt) + 1; - txt_offset += i; p_txt += i; txt_len -= i; - - reply->u.ident.offset_sinqhm_routines_ident = htons (txt_offset); - StrJoin (p_txt, txt_len, Sqhm_rout_ident, ""); - i = strlen (p_txt) + 1; - txt_offset += i; p_txt += i; txt_len -= i; - - reply->u.ident.offset_sinqhm_routines_date = htons (txt_offset); - StrJoin (p_txt, txt_len, Sqhm_rout_date, ""); - i = strlen (p_txt) + 1; - txt_offset += i; p_txt += i; txt_len -= i; - - is = rply_status_send (skt, reply); - /* - ** Now send the data - */ - p_txt = p_buff; - bytes_to_go = IDENT_MSGE_LEN; - while (bytes_to_go > 0) { - i = (bytes_to_go > pkt_size) ? pkt_size : bytes_to_go; - is = send (skt, p_txt, i, 0); - if (is > 0) { - Rw_bytes_put += is; - bytes_to_go -= is; - p_txt += is; - }else { - free (p_buff); - printf ("\n\007%s -- SQHM_IDENT: failed to send extra data!\n", - Tsk_name[index]); - return ERROR; /* Fatal error on send */ - } - } - free (p_buff); - return OK; - - case SQHM_PROJECT: /* Read a projected "rectangle" of the HM. */ - if (Cfgn_done == 0) { /* Check we've been configured */ - printf ("\007%s -- projecting but not yet configured!\n", Tsk_name[index]); - is = rply_status_setup_and_send (skt, reply, KER__BAD_STATE, 0, - "Not configured"); - return ERROR; - }else { - if (Dbg_lev0) printf ("%s -- projecting ..", Tsk_name[index]); - my_sub_code = ntohl (rqst->u.project.sub_code); - my_x_lo = ntohl (rqst->u.project.x_lo); - my_nx = ntohl (rqst->u.project.nx); - my_y_lo = ntohl (rqst->u.project.y_lo); - my_ny = ntohl (rqst->u.project.ny); - my_xdim = ntohl (rqst->u.project.xdim); - my_h_slct = ntohl (rqst->u.project.nhist); - is = do_project (index, reply, skt, pkt_size, - my_sub_code, my_x_lo, my_nx, my_y_lo, my_ny, my_xdim, my_h_slct); - if (is != OK) { - printf ("\n%s -- SQHM_PROJECT fatal error sending status reply or " - "histo data.\n", Tsk_name[index]); - }else { - if (Dbg_lev0) printf (" done.\n"); - } - return is; - } - - case SQHM_READ: /* Read a section of the HM. */ - if (Cfgn_done == 0) { /* Check we've been configured */ - printf ("\007%s -- reading but not yet configured!\n", Tsk_name[index]); - is = rply_status_setup_and_send (skt, reply, KER__BAD_STATE, 0, - "Not configured"); - return ERROR; - }else { - if (Dbg_lev0) printf ("%s -- reading ..", Tsk_name[index]); - my_hist_no = ntohl (rqst->u.read.hist_no); - my_first_bin = ntohl (rqst->u.read.first_bin); - my_nbins = ntohl (rqst->u.read.n_bins); - is = do_read (index, reply, skt, pkt_size, - my_nbins, my_first_bin, my_hist_no); - if (is != OK) { - printf ("\n%s -- SQHM_READ fatal error sending status reply or " - "histo data.\n", Tsk_name[index]); - }else { - if (Dbg_lev0) printf (" done.\n"); - } - return is; - } - - case SQHM_SELECT: /* SQHM_SELECT still needs to be programmed. */ - printf ("%s: Select ..\n", Tsk_name[index]); - is = rply_status_setup_and_send (skt, - reply, KER__BAD_VALUE, 0, "Not yet available!"); - if (is != OK) { - printf ("\n%s -- send of status reply failed.\n", Tsk_name[index]); - }else { - printf (" has been ignored but acknowledged.\n"); - } - return is; - - case SQHM_STATUS: /* Get-Status request */ - if (Dbg_lev0) printf ("%s: Status ..", Tsk_name[index]); - /* - ** Build up info - */ - reply->status = htonl (KER__SUCCESS); /* Indicate success */ - strcpy ((char *) &reply->sub_status, /* Set up the Ident */ - SINQHM_DEF_ID); /* This does not need htonl! */ - reply->u.status.max_n_hists = htonl (N_HISTS_MAX); - reply->u.status.max_num_bins = htonl (N_BINS_MAX + 1); - reply->u.status.max_srvrs = MAX_CLIENTS; - reply->u.status.max_block = htonl (memFindMax ()); /* Max free mem */ - if (Cfgn_done == 0) { - reply->u.status.cfg_state = 0; - reply->u.status.n_hists = 0; - reply->u.status.curr_hist = 0; - reply->u.status.num_bins = 0; - reply->u.status.act_srvrs = 0; - reply->u.status.bytes_per_bin = 0; - reply->u.status.compress = 0; - reply->u.status.daq_now = 0; - reply->u.status.filler_mask = 0; - reply->u.status.tsi_status = 0; - reply->u.status.flags = 0; - reply->u.status.dt_or_dts.both = 0; - reply->u.status.num_bad_events = 0; - }else { - reply->u.status.cfg_state = htonl (Hm_mode_ALL); - reply->u.status.n_hists = htons (N_hists); - reply->u.status.curr_hist = htons (Curr_hist); - reply->u.status.num_bins = htonl (N_bins); - - for (j = 0, i = MAX_CLIENTS; i > 0; i--) if (Child_pid[i] != 0) j++; - reply->u.status.act_srvrs = j; - - reply->u.status.bytes_per_bin = Bytes_per_bin; - reply->u.status.compress = Compress; - reply->u.status.daq_now = htons (SinqHM_Dsbl_Mask); - reply->u.status.filler_mask = htons (Server_masks[0]); - reply->u.status.tsi_status = htons (Tsi_status_info); - reply->u.status.flags = htons (Tsi_flags); - reply->u.status.dt_or_dts.both = htonl (Dt_or_dts.both); - reply->u.status.num_bad_events = htonl (Num_bad_events); - } - time (&secs); - secs = secs - Sqhm_start_time; - reply->u.status.up_time = htonl (secs); - - is = rply_status_send (skt, reply); - if (Dbg_lev0) { - if (is != OK) { - printf ("\n%s -- send of status reply failed.\n", Tsk_name[index]); - }else { - printf (" has been sent.\n"); - } - } - return is; - - case SQHM_WRITE: /* Write a section of the HM. - ** - ** NOTE: always call do_write, even if not configured - ** ==== since network data has always to be read. - */ - printf ("%s: writing ..", Tsk_name[index]); - my_hist_no = ntohl (rqst->u.write.hist_no); - my_first_bin = ntohl (rqst->u.write.first_bin); - my_nbins = ntohl (rqst->u.write.n_bins); - my_bytes_per_bin = ntohl (rqst->u.write.bytes_per_bin); - is = do_write (index, rqst, reply, skt, pkt_size, - my_nbins, my_first_bin, my_bytes_per_bin, my_hist_no); - if (is != OK) { - printf ("\n%s -- send of status reply failed.\n", Tsk_name[index]); - }else { - printf (" done.\n"); - } - return is; - - case SQHM_ZERO: - if (Cfgn_done == 0) { /* Check we've been configured */ - printf ("\007%s -- zeroing but not yet configured!\n", Tsk_name[index]); - is = rply_status_setup_and_send (skt, reply, KER__BAD_STATE, 0, - "Not configured"); - return ERROR; - }else { - printf ("%s -- zeroing ..", Tsk_name[index]); - - my_hist_no = ntohl (rqst->u.zero.hist_no); - my_first_bin = ntohl (rqst->u.zero.first_bin); - my_nbins = ntohl (rqst->u.zero.n_bins); - - do_zero (reply, index, my_nbins, my_first_bin, my_hist_no); - is = rply_status_send (skt, reply); - if (is != OK) { - printf ("\n%s -- send of status reply failed.\n", Tsk_name[index]); - }else { - printf (" done.\n"); - } - return is; - } - - default: - printf ("%s: Unrecognised command received ..\n", Tsk_name[index]); - is = rply_status_setup_and_send (skt, - reply, KER__BAD_VALUE, 0, "Unrecognised command!"); - if (is != OK) { - printf ("\n%s -- send of status reply failed.\n", Tsk_name[index]); - }else { - printf (" it has been acknowledged.\n"); - } - return is; - } - printf ("\007Software error in do_command - switch statement completed!\n"); - return ERROR; - } -/* -**--------------------------------------------------------------------------*/ - void do_daq ( -/* ====== -*/ struct rply_buff_struct *reply, - int index, - int sub_cmnd) { -/* -** Action routine for SQHM_DAQ command. Send a -** message to SinqHM-filler to get the command done. -** -** To send a message to SinqHM-filler: -** a) Claim Sem_Filler to gain access to the messageQ to filler; -** b) Set Filler_flag = 1 to warn SinqHM-filler that a message -** is coming. If SinqHM-filler is taking data, this gets it -** to break out of its data acquisition loop and wait for -** a message. This is to avoid SinqHM-filler having to do -** a system call in its innermost daq loop. -** c) Send the message with msgQSend (remembering to set up the -** index in the message correctly so that SinqHM-filler knows -** to whom it should send a reply). -** d) Wait for the reply with msgQReceive. -** e) Release Sem_Filler. -*/ - int is, status; - char recd[80]; - struct msg_to_filler_struct msg; - - reply->status = htonl (KER__SUCCESS); /* Assume success */ - reply->u.daq.daq_was = htons (SinqHM_Dsbl_Mask); /* Return old daq state */ - reply->u.daq.filler_mask = htons (Server_masks[0]); /* Filler's mask */ - reply->u.daq.server_mask = htons (Server_masks[index]); /* Server's mask */ - - if (sub_cmnd == DAQ__TST) { /* DAQ__TST is special - we just give the .. - ** .. caller a snapshot without invoking .. - ** .. SinqHM-filler. */ - reply->u.daq.daq_now = reply->u.daq.daq_was; - return; - } - - if (Dbg_lev0) printf ("\nDO_DAQ_%02d - claiming Sem_Filler\n", index); - if (Use_sem_tmo) { - is = (int) semTake (Sem_Filler, Sem_tmo); - }else { - is = (int) semTake (Sem_Filler, WAIT_FOREVER); - } - if (Dbg_lev0) - printf ("DO_DAQ_%02d - completed Sem_Filler claim: %d\n", index, is); - if (is != OK) { - kill (Parent_pid, SIGUSR1); /* Inform parent that we are in trouble */ - sprintf (recd, "DO_DAQ_%02d - sem claim err\n", index); - perror (recd); - exit (KER__BAD_VALUE); - } - - Filler_flag = 1; /* Warn SinqHM-filler that a message is coming */ - - msg.u.uu.cmnd = sub_cmnd; - msg.u.uu.index = index; - is = msgQSend (MsgQ_to_filler, - (char *) &msg, - sizeof (msg), - WAIT_FOREVER, MSG_PRI_NORMAL); - if (is != OK) { - printf ("do_daq -- error status from msgQSend: %d\n", is); - exit (KER__BAD_VALUE); - } - is = msgQReceive (MsgQ_to_server[index], - (char *) &msg, - sizeof (msg), - WAIT_FOREVER); - if (is <= 0) { - printf ("do_daq -- error status from msgQReceive: %d\n", is); - exit (KER__BAD_VALUE); - } - /* Complete the status response message */ - reply->u.daq.daq_now = htons (msg.u.uu.new_mask); /* New daq state */ - - if (Dbg_lev0) printf ("DO_DAQ_%02d - releasing sem\n", index); - is = (int) semGive (Sem_Filler); /* Release the semaphore */ - if (Dbg_lev0) - printf ("DO_DAQ_%02d - completed sem release: %d\n", index, is); - if (is != OK) { - kill (Parent_pid, SIGUSR1); /* Inform parent that we are in trouble */ - sprintf (recd, "DO_DAQ_%02d - sem release err\n", index); - perror (recd); - exit (KER__BAD_VALUE); - } - } -/* -**--------------------------------------------------------------------------*/ - int do_project ( -/* ========== -*/ int index, - struct rply_buff_struct *rply_bf, - int rw_skt, - int pkt_size, - uint sub_code, - uint x_lo, - uint nx, - uint y_lo, - uint ny, - uint xdim, - uint h_slct) { -/* -** Read a "rectangular" region of Hist Mem and send it -** to the client. -*/ - register int i, j, offs; - register uint my_bin_lo, my_bin_hi; - register uint my_hist_lo, my_hist_hi; - - uint my_xdim, eff_nhists; - int my_nbins, is, status, bytes_to_go, nput, nxtbin, nb; - int my_daq_save; - struct rply_buff_struct dummy_rply; - uchar *buff_pntr, *last_byte; - uchar buff[pkt_size]; - - register union { - void *base; - uchar *ch; - usint *i2; - uint *i4; - } my_pntr, hm_pntr; - - rply_status_setup (rply_bf, KER__BAD_VALUE, 0, "Bad argument"); /* Assume .. - ** .. we shall find a bad arg */ -/*-------------------------------------------------------------------- -** The SQHM_PROJECT command is histogram mode dependent. Switch -** accordingly. -*/ - switch (Hm_mode) { - /*-----------------------------------------------------------*/ - case SQHM__HM_DIG: /* SQHM__HM_DIG and SQHM__HRPT are handled the same. */ - case SQHM__HRPT: - if ((sub_code & PROJECT__1_DIM) == 0) { /* Check for pseudo-2-dim mode */ - /* Non-pseudo-2-dim mode. Check the args */ - my_hist_lo = y_lo; - if (my_hist_lo >= N_hists) { - printf ("\n\007%s -- SQHM_PROJECT: Bad y_lo!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - my_hist_hi = (ny != 0) ? (y_lo + ny - 1) : (N_hists - 1); - if ((my_hist_hi < my_hist_lo) || (my_hist_hi >= N_hists)) { - printf ("\n\007%s -- SQHM_PROJECT: Bad ny!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - my_bin_lo = x_lo; - if (my_bin_lo >= N_bins) { - printf ("\n\007%s -- SQHM_PROJECT: Bad x_lo!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - my_bin_hi = (nx != 0) ? (x_lo + nx - 1) : (N_bins - 1); - if ((my_bin_hi < my_bin_lo) || (my_bin_hi >= N_bins)) { - printf ("\n\007%s -- SQHM_PROJECT: Bad nx!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - }else { /* It is pseudo-2-dim mode */ - if (h_slct >= N_hists) { - printf ("\n\007%s -- SQHM_PROJECT: Bad h_slct!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - if ((xdim == 0) || - (xdim > N_bins) || - ((N_bins % xdim) != 0)) { - printf ("\n\007%s -- SQHM_PROJECT: Bad xdim!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - eff_nhists = N_bins/xdim; - my_hist_lo = y_lo; - if (my_hist_lo >= eff_nhists) { - printf ("\n\007%s -- SQHM_PROJECT: Bad y_lo!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - my_hist_hi = (ny != 0) ? (y_lo + ny - 1) : (eff_nhists - 1); - if ((my_hist_hi < my_hist_lo) || (my_hist_hi >= eff_nhists)) { - printf ("\n\007%s -- SQHM_PROJECT: Bad ny!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - my_bin_lo = x_lo; - if (my_bin_lo >= xdim) { - printf ("\n\007%s -- SQHM_PROJECT: Bad x_lo!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - my_bin_hi = (nx != 0) ? (x_lo + nx - 1) : (xdim - 1); - if ((my_bin_hi < my_bin_lo) || (my_bin_hi >= xdim)) { - printf ("\n\007%s -- SQHM_PROJECT: Bad nx!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - } - /* - ** All the arguments are OK. Drop through to common code - ** for reserving buffer space. - */ - break; - /*-----------------------------------------------------------*/ - case SQHM__TOF: /* Time-of-Flight Mode */ - - if ((sub_code & PROJECT__1_DIM) != 0) { - printf ("\n\007%s -- SQHM_PROJECT: SQHM__TOF+PROJECT__1_DIM not yet " - "implemented!\n", Tsk_name[index]); - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__BAD_VALUE, 0, - "Not yet implemented"); - return OK; - } - /* Check the arguments */ - my_hist_lo = y_lo; - if (my_hist_lo >= MAX_TOF_CNTR) { - printf ("\n\007%s -- SQHM_PROJECT: Bad y_lo!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - my_hist_hi = (ny != 0) ? (y_lo + ny - 1) : (N_hists - 1); - if ((my_hist_hi < my_hist_lo) || (my_hist_hi >= MAX_TOF_CNTR)) { - printf ("\n\007%s -- SQHM_PROJECT: Bad ny!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - /* - ** Check that all hists are defined - */ - for (i = my_hist_lo; i <= my_hist_hi; i++) { - if (Tof_descr[i] == NULL) { - printf ("\n\007%s -- SQHM_PROJECT: Bad counter range!\n", - Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - } - /* - ** Check that all have the same edge array. - */ - for (i = (my_hist_lo + 1); i <= my_hist_hi; i++) { - if (Tof_descr[i]->bin_edge != Tof_descr[i-1]->bin_edge) { - printf ("\n\007%s -- SQHM_PROJECT: Bad histogram edges!\n", - Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - } - - my_bin_lo = x_lo; - if (my_bin_lo >= Tof_descr[my_hist_lo]->n_bins) { - printf ("\n\007%s -- SQHM_PROJECT: Bad x_lo!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - my_bin_hi = (nx != 0) ? - (x_lo + nx - 1) : (Tof_descr[my_hist_lo]->n_bins - 1); - if ((my_bin_hi < my_bin_lo) || - (my_bin_hi >= Tof_descr[my_hist_lo]->n_bins)) { - printf ("\n\007%s -- SQHM_PROJECT: Bad nx!\n", Tsk_name[index]); - is = rply_status_send (rw_skt, rply_bf); - return OK; - } - /* - ** All the arguments are OK. Drop through to common code - ** for reserving buffer space. - */ - break; - /*-----------------------------------------------------------*/ - default: /* SQHM_PROJECT is not supported in other modes. */ - printf ("\n\007%s -- SQHM_PROJECT: bad Hm_mode!\n", Tsk_name[index]); - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__BAD_VALUE, 0, - "Bad Hm_mode"); - return OK; - } -/*------------------------------------------------------------------------- -*/ /* - ** All the arguments have been checked. Reserve some space - ** for projecting the data. The amount of space that we - ** need for the projection depends on whether the - ** projection is onto the x-axis or y-axis. - */ - my_nbins = ((sub_code & PROJECT__ON_Y) == 0) ? - (my_bin_hi - my_bin_lo + 1) : (my_hist_hi - my_hist_lo + 1); - - my_pntr.base = calloc (my_nbins, sizeof (uint)); - if (my_pntr.base == NULL) { - printf ("\n\007%s -- SQHM_PROJECT: failed to get buffer!\n", - Tsk_name[index]); - rply_status_setup_and_send (rw_skt, rply_bf, KER__BAD_ALLOC, 0, - "Failed to get buffer for projecting data"); - return OK; - } - /*----------------------------------------------------- - ** We got some buffer space so inhibit data acqu ... - */ - my_daq_save = SinqHM_Dsbl_Mask & Server_masks[index]; /* Remember the .. - ** .. state of our .. - ** .. inhibit bit */ - if (my_daq_save == 0) do_daq (&dummy_rply, index, DAQ__INH); - /*----------------------------------------------------- - ** ... then do the projection ... - */ - switch (Hm_mode) { - - case SQHM__HM_DIG: /* HM_DIG & HRPT Mode */ - case SQHM__HRPT: - if ((sub_code & PROJECT__1_DIM) == 0) { /* Check for pseudo-2-dim mode */ - /* Non-pseudo-2-dim mode. Do a simple proj'n */ - if ((sub_code & PROJECT__ON_Y) == 0) { - for (i = my_hist_lo; i <= my_hist_hi; i++) { - hm_pntr.base = Hist_base_addr + (i * N_bins * Bytes_per_bin); - for (j = my_bin_lo; j <= my_bin_hi; j++) { - switch (Bytes_per_bin) { - case 1: my_pntr.i4[j-my_bin_lo] += hm_pntr.ch[j]; break; - case 2: my_pntr.i4[j-my_bin_lo] += hm_pntr.i2[j]; break; - case 4: my_pntr.i4[j-my_bin_lo] += hm_pntr.i4[j]; - } - } - } - }else { - for (i = my_hist_lo; i <= my_hist_hi; i++) { - hm_pntr.base = Hist_base_addr + (i * N_bins * Bytes_per_bin); - offs = i - my_hist_lo; - for (j = my_bin_lo; j <= my_bin_hi; j++) { - switch (Bytes_per_bin) { - case 1: my_pntr.i4[offs] += hm_pntr.ch[j]; break; - case 2: my_pntr.i4[offs] += hm_pntr.i2[j]; break; - case 4: my_pntr.i4[offs] += hm_pntr.i4[j]; - } - } - } - } - }else { /* It is pseudo-2-dim mode */ - hm_pntr.base = Hist_base_addr + (h_slct * N_bins * Bytes_per_bin); - if ((sub_code & PROJECT__ON_Y) == 0) { - for (i = my_hist_lo; i <= my_hist_hi; i++) { - for (j = my_bin_lo; j <= my_bin_hi; j++) { - switch (Bytes_per_bin) { - case 1: my_pntr.i4[j-my_bin_lo] += hm_pntr.ch[xdim*i+j]; break; - case 2: my_pntr.i4[j-my_bin_lo] += hm_pntr.i2[xdim*i+j]; break; - case 4: my_pntr.i4[j-my_bin_lo] += hm_pntr.i4[xdim*i+j]; - } - } - } - }else { - for (i = my_hist_lo; i <= my_hist_hi; i++) { - offs = i - my_hist_lo; - for (j = my_bin_lo; j <= my_bin_hi; j++) { - switch (Bytes_per_bin) { - case 1: my_pntr.i4[offs] += hm_pntr.ch[xdim*i+j]; break; - case 2: my_pntr.i4[offs] += hm_pntr.i2[xdim*i+j]; break; - case 4: my_pntr.i4[offs] += hm_pntr.i4[xdim*i+j]; - } - } - } - } - } - break; - - case SQHM__TOF: /* Time-of-Flight Mode */ - if ((sub_code & PROJECT__ON_Y) == 0) { - for (i = my_hist_lo; i <= my_hist_hi; i++) { - hm_pntr.base = (void *) Tof_descr[i]->u.l_bin_data; - for (j = my_bin_lo; j <= my_bin_hi; j++) { - switch (Bytes_per_bin) { - case 1: my_pntr.i4[j-my_bin_lo] += hm_pntr.ch[j]; break; - case 2: my_pntr.i4[j-my_bin_lo] += hm_pntr.i2[j]; break; - case 4: my_pntr.i4[j-my_bin_lo] += hm_pntr.i4[j]; - } - } - } - }else { - for (i = my_hist_lo; i <= my_hist_hi; i++) { - hm_pntr.base = (void *) Tof_descr[i]->u.l_bin_data; - offs = i - my_hist_lo; - for (j = my_bin_lo; j <= my_bin_hi; j++) { - switch (Bytes_per_bin) { - case 1: my_pntr.i4[offs] += hm_pntr.ch[j]; break; - case 2: my_pntr.i4[offs] += hm_pntr.i2[j]; break; - case 4: my_pntr.i4[offs] += hm_pntr.i4[j]; - } - } - } - } - break; - - default: - } - /*----------------------------------------------------- - ** ... projection complete so let Filler continue and - ** send data back to client. - */ - if (my_daq_save == 0) do_daq (&dummy_rply, index, DAQ__CLR); - - rply_bf->u.project.n_bins = htonl (my_nbins); - rply_bf->u.project.bytes_per_bin = htonl (sizeof (uint)); - rply_bf->u.project.cnts_lo = htonl (Cnts_lo); - rply_bf->u.project.cnts_hi = htonl (Cnts_hi); - - if (rply_bf->bigend != 0x12345678) { /* If byte swapping needed, ... - ** .. then swap them! */ - for (i = 0; i < my_nbins; i++) my_pntr.i4[i] = htonl (my_pntr.i4[i]); - } - - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__SUCCESS, 0, NULL); - - bytes_to_go = my_nbins * sizeof (uint); - buff_pntr = (uchar *) my_pntr.base; - - while (bytes_to_go > 0) { - nput = (bytes_to_go > pkt_size) ? pkt_size : bytes_to_go; - is = send (rw_skt, buff_pntr, nput, 0); - if (is > 0) { - Rw_bytes_put += is; - bytes_to_go -= is; - buff_pntr += is; - }else { - free (my_pntr.base); - return ERROR; /* Fatal error on send */ - } - } - free (my_pntr.base); /* Release our bit of memory */ - - return OK; - } -/* -**--------------------------------------------------------------------------*/ - int do_read ( -/* ======= -*/ int index, - struct rply_buff_struct *rply_bf, - int rw_skt, - int pkt_size, - uint nbins, - uint first, - uint hist_no) { -/* -** Read a consecutive region of 'nbins' bins of the Hist Mem -** starting with bin 'first' and send it to the client. -*/ - register int i, my_fstbin, my_topbin; - int is, my_nbins, status, bytes_to_go, nput, nxtbin, nb; - int my_daq_save; - struct rply_buff_struct dummy_rply; - uchar *buff_pntr, *last_byte; - uchar buff[pkt_size]; - - register union { - void *base; - uchar *ch; - usint *i2; - uint *i4; - } my_pntr, hm_pntr; - - rply_status_setup (rply_bf, KER__BAD_VALUE, 0, "Bad argument"); /* Assume .. - ** .. we shall find a bad arg */ -/*-------------------------------------------------------------------- -** SQHM__TRANS mode is a special case since we must always suspend -** data acq so that we can move FILLER on to the next buffer safely -** and take a private copy of the current buffer. -*/ - if (Hm_mode == SQHM__TRANS) { - /* - ** SQHM__TRANS mode: start by ensuring user's buffer size is OK. - */ - nbins = nbins & (~3); /* Ensure is a multiple of 4 */ - if (nbins < 16) { - if (Dbg_lev0) printf ("\n"); - printf ("\007%s -- SQHM_READ: bad NBINS!\n", Tsk_name[index]); - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__BAD_VALUE, 0, - "\"n_bins\" < 16"); - return OK; - } - /* - ** Ensure data acq is disabled - */ - my_daq_save = SinqHM_Dsbl_Mask & Server_masks[index]; /* Remember the .. - ** .. state of our inhibit bit */ - if (my_daq_save == 0) do_daq (&dummy_rply, index, DAQ__INH); - /* - ** Now we can manipulate the buffer "safely". Actually, - ** we should really use semaphore access to the buffer - ** pointers since another SinqHM client could be running - ** in parallel with us. We shall ignore this refinement - ** for the time being! - */ - hm_pntr.base = Tran_buff_base; - last_byte = Next_char; - selectNewBuffer (last_byte); /* Move data acquisition to next buffer */ - - bytes_to_go = (last_byte - hm_pntr.ch + 4) & (~3); - my_pntr.base = malloc (bytes_to_go); - if (buff_pntr == NULL) { - rply_status_setup_and_send (rw_skt, rply_bf, KER__BAD_ALLOC, 0, - "Failed to get buffer for data transfer"); - return OK; - } - *my_pntr.i4 = htonl (*hm_pntr.i4); - memcpy (my_pntr.ch+4, hm_pntr.ch+4, bytes_to_go-4); - /* - ** Copy complete so let Filler continue. - */ - if (my_daq_save == 0) do_daq (&dummy_rply, index, DAQ__CLR); - - if (bytes_to_go > nbins) bytes_to_go = nbins; - /* - ** Everything seems to be OK. - ** Tell client he's about to get some data! - */ - rply_bf->u.read.first_bin = htonl (0); - rply_bf->u.read.n_bins = htonl (bytes_to_go); - rply_bf->u.read.bytes_per_bin = htonl (1); - rply_bf->u.read.cnts_lo = htonl (0); - rply_bf->u.read.cnts_hi = htonl (0); - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__SUCCESS, 0, NULL); - /* - ** Now send the data - */ - buff_pntr = my_pntr.ch; - while (bytes_to_go > 0) { - nput = (bytes_to_go > pkt_size) ? pkt_size : bytes_to_go; - is = send (rw_skt, buff_pntr, nput, 0); - if (is > 0) { - Rw_bytes_put += is; - bytes_to_go -= is; - buff_pntr += is; - }else { - free (my_pntr.base); - return ERROR; /* Fatal error on send */ - } - } - free (my_pntr.base); - return OK; - } -/*-------------------------------------------------------------------- -** Non-transparent mode: Start by checking arguments. -*/ - if ((hist_no == -1) && (first == -1) && (nbins == -1)) { - my_fstbin = 0; - my_nbins = N_hists * N_bins; - }else { - if (nbins < 0) { - if (Dbg_lev0) printf ("\n"); - printf ("\007%s -- SQHM_READ: bad NBINS!\n", Tsk_name[index]); - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__BAD_VALUE, 0, - "\"n_bins\" < 0"); - return OK; - } - if (first < 0) { - if (Dbg_lev0) printf ("\n"); - printf ("\007%s -- SQHM_READ: bad FIRST!\n", Tsk_name[index]); - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__BAD_VALUE, 0, - "\"first_bin\" < 0"); - return OK; - } - my_nbins = nbins; - if (hist_no == -1) { - my_fstbin = first; - my_topbin = my_fstbin + my_nbins; - if ((my_topbin <= 0) || (my_topbin > N_hists * N_bins)) { - if (Dbg_lev0) printf ("\n"); - printf ("\007%s -- SQHM_READ: bad parameters!\n", Tsk_name[index]); - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__BAD_VALUE, 0, - "Bad parameters"); - return OK; - } - }else { - if ((hist_no < 0) || (hist_no >= N_hists)) { - if (Dbg_lev0) printf ("\n"); - printf ("\007%s -- SQHM_READ: bad HIST_NO!\n", Tsk_name[index]); - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__BAD_VALUE, 0, - "Bad \"hist_no\""); - return OK; - } - my_fstbin = (hist_no * N_bins) + first; - my_topbin = my_fstbin + my_nbins; - } - } - /* - ** The args are OK. - ** Tell client he's about to get some data! - */ - rply_bf->u.read.first_bin = htonl (my_fstbin); - rply_bf->u.read.n_bins = htonl (my_nbins); - rply_bf->u.read.bytes_per_bin = htonl (Bytes_per_bin); - rply_bf->u.read.cnts_lo = htonl (Cnts_lo); - rply_bf->u.read.cnts_hi = htonl (Cnts_hi); - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__SUCCESS, 0, NULL); - /* - ** See if we can reserve some space for making a - ** copy of the histogram data. - */ - my_pntr.base = NULL; - i = memFindMax (); /* Get size of biggest free memory block */ - if (i > (my_nbins * Bytes_per_bin)) my_pntr.base = - malloc (my_nbins * Bytes_per_bin); - /* - ** If we got a private buffer, inhibit Filler whilst we - ** make a quick copy. - */ - if (my_pntr.base != NULL) { - /* - ** We got a private copy - */ - my_daq_save = SinqHM_Dsbl_Mask & Server_masks[index]; /* Remember the .. - ** .. state of our .. - ** .. inhibit bit */ - if (my_daq_save == 0) do_daq (&dummy_rply, index, DAQ__INH); - memcpy (my_pntr.base, - ((char *) Hist_base_addr) + (my_fstbin * Bytes_per_bin), - (my_nbins * Bytes_per_bin)); - /* - ** Copy complete so let Filler continue. - */ - if (my_daq_save == 0) do_daq (&dummy_rply, index, DAQ__CLR); - bytes_to_go = my_nbins * Bytes_per_bin; - buff_pntr = (char *) my_pntr.base; - - while (bytes_to_go > 0) { - nput = (bytes_to_go > pkt_size) ? pkt_size : bytes_to_go; - is = send (rw_skt, buff_pntr, nput, 0); - if (is > 0) { - Rw_bytes_put += is; - bytes_to_go -= is; - buff_pntr += is; - }else { - free (my_pntr.base); - return ERROR; /* Fatal error on send */ - } - } - free (my_pntr.base); /* Release our bit of memory */ - }else { - /* - ** We did not get a private copy. We'll have to copy - ** out of the HM area as we send - this would cause a much - ** longer inhibit of Filler so we let Filler keep running. - ** If the user wants unskewed data, he must inhibit DAQ - ** first using DAQ__INH. - */ - bytes_to_go = my_nbins * Bytes_per_bin; - nxtbin = my_fstbin; - - my_pntr.base = buff; - hm_pntr.base = Hist_base_addr; - - while (bytes_to_go > 0) { - nput = (bytes_to_go > pkt_size) ? pkt_size : bytes_to_go; - nb = nput/Bytes_per_bin; - switch (Bytes_per_bin) { - case 1: - for (i=0; i 0) { - is = send (rw_skt, buff_pntr, nput, 0); - if (is > 0) { - Rw_bytes_put += is; - nput -= is; - bytes_to_go -= is; - buff_pntr += is; - }else { - return ERROR; /* Fatal error on send */ - } - } - nxtbin += nb; - } - } - return OK; - } -/* -**--------------------------------------------------------------------------*/ - int do_write ( -/* ======== -*/ int index, - struct req_buff_struct *req_bf, - struct rply_buff_struct *rply_bf, - int rw_skt, - int pkt_size, - int nbins, - int first, - int bytes_per_bin, - int hist_no) { -/* -** Preset a consecutive region of the Hist Mem. The number of -** bins to preset is 'nbins' starting with bin 'first'. The -** data for the bins is read from the client. -*/ - int i, is, status, bytes_to_come, nget; - uchar *b_pntr; - usint *w_pntr; - uint *l_pntr; - - if ((nbins <= 0) || (bytes_per_bin <= 0)) { /* If nothing to do, do nothing! */ - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__SUCCESS, 0, NULL); - return is; - } - /* - ** Check that we've been configured. If not, flush the data from - ** the client and return an error. - */ - if (Cfgn_done == 0) { - printf ("\007 but not yet configured!\n"); - net_flush (rw_skt, nbins * bytes_per_bin); - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__BAD_STATE, 0, - "Not configured!"); - return ERROR; - } - /* - ** Check that parameters are valid. - */ - if ((bytes_per_bin != Bytes_per_bin) || - (first < 0) || - ((first+nbins) > (N_hists*N_bins))) { - printf ("\007 but invalid parameters!\n"); - net_flush (rw_skt, nbins * bytes_per_bin); - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__BAD_VALUE, 0, - "Bad \"first_bin\", \"n_bins\" or \"bytes_per_bin\"!"); - return ERROR; - } - - bytes_to_come = nbins * Bytes_per_bin; - b_pntr = (char *) Hist_base_addr; - while (bytes_to_come > 0) { - nget = (bytes_to_come > pkt_size) ? pkt_size : bytes_to_come; - is = recv (rw_skt, b_pntr, nget, 0); - if (is > 0) { - Rw_bytes_got += is; - bytes_to_come -= is; - b_pntr += is; - }else { - net_flush (rw_skt, bytes_to_come); - is = rply_status_setup_and_send (rw_skt, rply_bf, KER__BAD_RECV, is, - "DO_WRITE: recv error status"); - return ERROR; - } - } - - if (0x12345678 != ntohl (0x12345678)) { /* Swap bytes, if necessary */ - switch (Bytes_per_bin) { - case 1: - break; - case 2: - w_pntr = (usint *) Hist_base_addr; - for (i=0; istatus = KER__BAD_VALUE; /* Assume we shall find a bad arg */ - if ((hist_no == -1) && (first_bin == -1) && (nbins == -1)) { - my_first_bin = 0; - my_nbins = N_hists * N_bins; - my_topbin = my_first_bin + my_nbins; - }else { - if (nbins < 0) return; - if (first_bin < 0) return; - if (hist_no == -1) { - my_first_bin = first_bin; - my_nbins = nbins; - my_topbin = my_first_bin + my_nbins; - if ((my_topbin <= 0) || (my_topbin > N_hists * N_bins)) return; - }else { - if ((hist_no < 0) || (hist_no >= N_hists)) return; - my_first_bin = (hist_no * N_bins) + first_bin; - my_topbin = my_first_bin + my_nbins; - } - } - - reply->status = KER__SUCCESS; /* The args are OK -- inhibit Filler */ - - my_daq_save = SinqHM_Dsbl_Mask & Server_masks[index]; /* Remember the .. - ** .. state of our .. - ** .. inhibit bit */ - if (my_daq_save == 0) { - do_daq (&dummy_rply, index, DAQ__INH); - } - - switch (Bytes_per_bin) { - case 1: - b_pntr = (uchar *) Hist_base_addr; - for (i = my_first_bin; i < my_topbin; i++) b_pntr[i] = 0; - break; - case 2: - w_pntr = (usint *) Hist_base_addr; - for (i = my_first_bin; i < my_topbin; i++) w_pntr[i] = 0; - break; - case 4: - l_pntr = (uint *) Hist_base_addr; - for (i = my_first_bin; i < my_topbin; i++) l_pntr[i] = 0; - break; - } - Cnts_lo = Cnts_hi = 0; - N_events = N_skipped = N_no_coin_tsi = N_coin_tsi = 0; - Print_hdr = True; - - lwl_Fifo_Flush (); /* Ensure the fibre-optic FIFO is empty */ - - if (my_daq_save == 0) { - do_daq (&dummy_rply, index, DAQ__CLR); /* Remove our inhibit on Filler */ - } - } -/* -**--------------------------------------------------------------------------*/ - void failInet (char *text) { -/* ======== -** Output the given text and exit the process. -*/ - int my_errno; - - getErrno (&my_errno); - printf ("### Internet Error ###\n"); - printf (" ### errno = %d.\n", my_errno); - perror (text); - exit (EXIT_FAILURE); - } -/*--------------------------------------------------------------------------*/ - void failInet_port (char *text, int port) { -/* ============= -** Call to failInet with an extra parameter. -*/ - char my_buff[132]; - - kill (Parent_pid, SIGUSR1); /* Inform the parent that we are in trouble */ - - sprintf (my_buff, text, port); - failInet (my_buff); - } -/* -**--------------------------------------------------------------------------*/ - void free_HM_memory (void *extras) { -/* =============== -** Free any memory allocated for TOF histograms -*/ - int i; - /* - ** Release a possible pending buffer - */ - free (extras); - /* - ** Release any allocated histogram buffer - */ - free (Hist_base_addr); - Hist_base_addr = NULL; - free (Frame_base_addr); - Frame_base_addr = NULL; - /* - ** Release the tof_edge_info structures - */ - for (i = 0; i < MAX_TOF_EDGE; i++) { - free (Tof_edges[i]); - Tof_edges[i] = NULL; - } - /* - ** Release the tof_edge_info structures - */ - for (i = 0; i < MAX_TOF_CNTR; i++) { - free (Tof_descr[i]); - Tof_descr[i] = NULL; - } - } -/* -**--------------------------------------------------------------------------*/ - void getErrno (int *his_errno) { -/* ======== -*/ - *his_errno = errno; /* Make copy of errno */ - return; - } -/* -**--------------------------------------------------------------------------*/ - pid_t get_pid () { -/* ======= -*/ - int my_tid; - - my_tid = taskIdSelf (); - - return (pid_t) my_tid; - } -/* -**--------------------------------------------------------------------------*/ - void kill_children () { -/* ============= -** Send signals to all our offspring to cause them to terminate -*/ - int i, is; - - if (Filler_pid != 0) { - printf (" .. closing down %s ..", Filler_name); - is = kill (Filler_pid, SIGINT); - if (is == ERROR) printf ("Bad status killing FILLER.\n"); - } - for (i = MAX_CLIENTS; i > 0; i--) { - if (Child_pid[i] != 0) { - printf ("\n Terminating %s ..", Tsk_name[i]); - is = kill (Child_pid[i], SIGINT); - if (is == ERROR) printf ("Bad status killing server.\n"); - } - } - } -/* -**--------------------------------------------------------------------------*/ - void lwl_Fifo_Flush () { -/* ============== -** Flush out any data in the fibre-optic FIFO. -*/ - register int i; - register uint *my_lwl_fifo; - register union { - uint ui4; - usint ui2[2]; - uchar byte[4]; - } lwl_hdr; - uchar my_buff[32]; - - my_lwl_fifo = Lwl_fifo; - /* - ** Note: The following loop runs at a rate of about 570 nsec - ** per cycle. Since it takes 2 executions of the loop to - ** read 1 packet in Hist Mode and this corresponds to - ** 6 bytes, this loop should manage to empty the FIFO - ** for neutron rates below about 875 kHz. This - ** corresponds to a data rate over the fibre-optic link - ** of 5.2 Mbyte/sec. Since the link can theoretically - ** go faster than this, the code sets a finite limit - ** for itself and, if the limit is hit, flushes to the - ** end of a packet. - */ - for (i = 0; i < 10000000; i++) { - lwl_hdr.ui4 = *my_lwl_fifo; - if (lwl_hdr.ui4 == LWL_FIFO_EMPTY) return; - } - /* - ** We did not succeed in emptying the FIFO. We are therefore - ** likely to be in trouble!! However, we shall try our best - ** to please by finding a header marker and then flushing to - ** the end of that packet to leave things tidy. - */ - for (i = 0; i < 100; i++) { - lwl_hdr.ui4 = *my_lwl_fifo; - if (lwl_hdr.ui4 == LWL_FIFO_EMPTY) return; - if (lwl_hdr.byte[0] != 0) { /* Packet header? */ - lwl_Packet_Read (lwl_hdr.ui4, my_buff); /* Yes! Flush and .. */ - break; /* .. quit */ - } - } - return; - } -/* -**--------------------------------------------------------------------------*/ - int lwl_Packet_Read (uint hdr, uchar *buff) { -/* =============== -** Read current packet from the fibre-optic FIFO. -** is the packet header and is used to calculate -** the amount of reading required. The data (including -** the header) is copied into *buff, which must be at -** least 22 bytes long. -** Return value: Number of bytes read (including 4 bytes for hdr). -*/ - register uint *my_lwl_fifo; - register union { - uint ui4; - usint ui2[2]; - uchar byte[4]; - } lwl_data; - - int i, do_print, bytes_read = 4; - ULONG tick_now; - static ULONG lPF_tick[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - static int lPF_indx = 0; - static int lPF_clockRate = 0; - static int lPF_skipped = 0; - - if (lPF_clockRate == 0) lPF_clockRate = sysClkRateGet (); /* Ticks/second */ - my_lwl_fifo = Lwl_fifo; - - lwl_data.ui4 = hdr; - buff[0] = lwl_data.byte[0]; - buff[1] = lwl_data.byte[1]; - buff[2] = lwl_data.byte[2]; - buff[3] = lwl_data.byte[3]; - /* - ** Switch according to header type ... - */ - switch (hdr & LWL_HDR_TYPE_MASK) { - case LWL_HM_NC_C9: /* Cases with 18 more bytes .. - ** .. Also includes LWL_HM_CO_C9 - ** .. LWL_SM_NC_C9 - ** .. LWL_SM_CO_C9 - */ - lwl_data.ui4 = *my_lwl_fifo; /* Read remaining bytes */ - buff[bytes_read++] = lwl_data.byte[2]; - buff[bytes_read++] = lwl_data.byte[3]; - - case LWL_HM_NC_C8: /* Cases with 16 more bytes .. - ** .. Also includes LWL_HM_CO_C8 - ** .. LWL_SM_NC_C8 - ** .. LWL_SM_CO_C8 - */ - lwl_data.ui4 = *my_lwl_fifo; /* Read remaining bytes */ - buff[bytes_read++] = lwl_data.byte[2]; - buff[bytes_read++] = lwl_data.byte[3]; - - case LWL_HM_NC_C7: /* Cases with 14 more bytes .. - ** .. Also includes LWL_HM_CO_C7 - ** .. LWL_SM_NC_C7 - ** .. LWL_SM_CO_C7 - */ - lwl_data.ui4 = *my_lwl_fifo; /* Read remaining bytes */ - buff[bytes_read++] = lwl_data.byte[2]; - buff[bytes_read++] = lwl_data.byte[3]; - - case LWL_HM_NC_C6: /* Cases with 12 more bytes .. - ** .. Also includes LWL_HM_CO_C6 - ** .. LWL_SM_NC_C6 - ** .. LWL_SM_CO_C6 - */ - lwl_data.ui4 = *my_lwl_fifo; /* Read remaining bytes */ - buff[bytes_read++] = lwl_data.byte[2]; - buff[bytes_read++] = lwl_data.byte[3]; - - case LWL_HM_NC_C5: /* Cases with 10 more bytes .. - ** .. Also includes LWL_HM_CO_C5 - ** .. LWL_SM_NC_C5 - ** .. LWL_SM_CO_C5 - */ - lwl_data.ui4 = *my_lwl_fifo; /* Read remaining bytes */ - buff[bytes_read++] = lwl_data.byte[2]; - buff[bytes_read++] = lwl_data.byte[3]; - - case LWL_HM_NC_C4: /* Cases with 8 more bytes .. - ** .. Also includes LWL_HM_CO_C4 - ** .. LWL_SM_NC_C4 - ** .. LWL_SM_CO_C4 - */ - lwl_data.ui4 = *my_lwl_fifo; /* Read remaining bytes */ - buff[bytes_read++] = lwl_data.byte[2]; - buff[bytes_read++] = lwl_data.byte[3]; - - case LWL_HM_NC_C3: /* Cases with 6 more bytes .. - ** .. Also includes LWL_HM_CO_C3 - ** .. LWL_SM_NC_C3 - ** .. LWL_SM_CO_C3 - */ - case LWL_TSI_HM_C: /* Other cases with 6 more bytes .. - ** .. Also includes LWL_TSI_SM_C - */ - lwl_data.ui4 = *my_lwl_fifo; /* Read remaining bytes */ - buff[bytes_read++] = lwl_data.byte[2]; - buff[bytes_read++] = lwl_data.byte[3]; - - case LWL_HM_NC_C2: /* Cases with 4 more bytes .. - ** .. Also includes LWL_HM_CO_C2 - ** .. LWL_SM_NC_C2 - ** .. LWL_SM_CO_C2 - */ - lwl_data.ui4 = *my_lwl_fifo; /* Read remaining bytes */ - buff[bytes_read++] = lwl_data.byte[2]; - buff[bytes_read++] = lwl_data.byte[3]; - - case LWL_HM_NC_C1: /* Cases with 2 more bytes .. - ** .. Also includes LWL_HM_NC_C1 - */ - case LWL_TR_C1: /* Other cases with 2 more bytes */ - case LWL_TR_C2: /* Also includes LWL_TOF_C1 - LWL_TOF_C9 */ - case LWL_TR_C3: - case LWL_TR_C4: - case LWL_TR_C5: - case LWL_TR_C6: - case LWL_TR_C7: - case LWL_TR_C8: - case LWL_TR_C9: - - case LWL_TSI_TR: /* Yet more cases with 2 more bytes .. - ** .. Also includes LWL_TSI_HM_NC - ** .. LWL_TSI_TOF - ** .. LWL_TSI_SM_NC - */ - lwl_data.ui4 = *my_lwl_fifo; /* Read remaining bytes */ - buff[bytes_read++] = lwl_data.byte[2]; - buff[bytes_read++] = lwl_data.byte[3]; - - case LWL_FIFO_EMPTY: /* FIFO empty - no more bytes */ - break; - - default: - /* - ** Suppress messages if too many! Record times of last - ** 10 messages to see if this one should be printed. - */ - tick_now = tickGet (); - - if (lPF_indx == 9) { /* Only suppress after 10th message */ - if ((tick_now - lPF_tick[0]) > (5 * 60 * lPF_clockRate)) { - do_print = True; /* No more than 10 message per 5 mins */ - for (i = 0; i < 9; i++) lPF_tick[i] = lPF_tick[i+1]; - lPF_tick[9] = tick_now; - }else if ((tick_now - lPF_tick[9]) > (60 * lPF_clockRate)) { - do_print = True; /* No more than 1 message per min */ - for (i = 0; i < 9; i++) lPF_tick[i] = lPF_tick[i+1]; - lPF_tick[9] = tick_now; - }else { - do_print = False; /* Suppress this message */ - lPF_skipped++; - } - }else { - do_print = True; - lPF_tick[lPF_indx] = tick_now; - lPF_indx++; - } - - if (do_print) { - printf ("lwl_Packet_Read -- unrecognised packet header 0x%08x\n", hdr); - if (lPF_skipped > 0) { - printf ("lwl_Packet_Read -- %d packets skipped\n", lPF_skipped); - } - lPF_skipped = 0; - } - } - return bytes_read; - } -/* -**--------------------------------------------------------------------------*/ - int make_child (int (* proc) (), int flag, int pkt_size) { -/* ========== -** Find a free child index, create a child process and -** invoke procedure proc in the child procedure. -** Return value > 0 if child successfully created; -** = 0 if this is the child which is executing; -** = -1 if error returned by fork; -** = -2 if there are too many children already; -** = -3 if time-out waiting for child to signal. -** = -4 the child indicated a start-up error. -*/ - int i, status, tmo; - pid_t created_pid; - char tsknam[20]; -/* -** Find a free PID index. Zero is not a permitted value. -*/ - for (i = 1; i <= MAX_CLIENTS; i++) { - if (Child_pid[i] == 0) break; - } - - if (i <= MAX_CLIENTS) { /* Free index found? */ - Cnt_SIGUSR1 = 0; - semTake (Sem_Server, NO_WAIT); /* Ensure that Sem_Server is claimed. .. - ** .. Child will release it when ready */ - Child_exit_status[i] = 0; /* Zero child's status indicator */ - sprintf (tsknam, "hmSrv%02d", i); - created_pid = taskSpawn ( /* Make a child */ - tsknam, /* Name */ - 100, /* Priority */ - VX_FP_TASK, /* Options - fl.pt. usage assumed */ - 20000, /* Stack size */ - proc, /* The entry point */ - flag, - i, - pkt_size, 0,0,0,0,0,0,0); - if (created_pid == ERROR) { /* Error? */ - return -1; /* Yes. */ - }else { /* Parent */ - Child_pid[i] = created_pid; - tmo = 1000; /* Normally give child 1000 ticks to .. - ** .. get going */ - if (flag != 0) { - tmo = WAIT_FOREVER; /* But in debug mode, wait forever! */ - } - status = semTake (Sem_Server, tmo); /* Wait for child to get going */ - if (status == ERROR) { /* Timeout? */ - taskDelete (Child_pid[i]); /* Yes, kill child. */ - Child_pid[i] = 0; - return -3; /* Return with error. */ - }else { /* No timeout so child is ready. */ - if (Child_exit_status[i] == 0) { /* Did the child have startup a .. - ** .. problem */ - return i; /* No, so return its index */ - }else { - return -4; /* Yes, so return error */ - } - } - } - } - return -2; /* There are already too many children. */ - } -/* -**--------------------------------------------------------------------------*/ - int make_filler (int suspendMode) { -/* =========== -** Create a child process to execute the FILLER procedure. -** Return value = 1 if FILLER successfully created; -** = 0 if this is FILLER which is executing; -** = -1 if error returned by fork; -** = -2 if FILLER already running; -** = -3 if time-out waiting for FILLER to signal. -*/ - int i, status, tmo; - int created_pid; - - if (Filler_pid == 0) { - Cnt_SIGUSR1 = 0; - semTake (Sem_Filler, NO_WAIT); /* Ensure that Sem_Filler is claimed. .. - ** .. FILLER will release it when set up */ - - sprintf (Filler_name, "hmFill%04d", Port_base); - created_pid = taskSpawn ( /* Make a child */ - Filler_name, /* Name */ - 250, /* Priority (0=highest, 255=lowest ) */ - VX_FP_TASK, /* Options - fl.pt. usage assumed */ - 20000, /* Stack size */ - SinqHM_filler, /* The entry point */ - suspendMode, - 0,0,0,0,0,0,0,0,0); - if (created_pid == ERROR) { /* Error? */ - return -1; /* Yes. */ - }else { /* No */ - Filler_pid = created_pid; - tmo = 1000; /* Normally give FILLER 1000 ticks to .. - ** .. get going */ - if (suspendMode != 0) { - tmo = WAIT_FOREVER; /* But in debug mode, wait forever! */ - } - if (Dbg_lev0) printf ("make_filler: waiting for %s to get going ..\n", - Filler_name); - status = semTake (Sem_Filler, tmo); /* Wait for FILLER to get going */ - if (status == ERROR) { /* Timeout? */ - taskDelete (Filler_pid); /* Yes, kill FILLER. */ - Filler_pid = 0; - return -3; /* Return with error. */ - }else { /* No timeout so FILLER is ready. */ - if (Dbg_lev0) - printf ("make_filler: %s is up and running.\n", Filler_name); - semGive (Sem_Filler); /* Release Sem_Filler */ - return 1; - } - } - } - return -2; /* FILLER already active. A configure has been repeated. */ - } -/* -**--------------------------------------------------------------------------*/ - int net_flush (int skt, int nbytes) { -/* ========= -*/ - int is, bytes_to_come, nget; - char buff[1024]; - - bytes_to_come = nbytes; - while (bytes_to_come > 0) { - nget = (bytes_to_come > sizeof (buff)) ? sizeof (buff) : bytes_to_come; - is = recv (skt, buff, nget, 0); - if (is > 0) { - bytes_to_come -= is; - }else { - return ERROR; - } - } - return OK; - } -/* -**--------------------------------------------------------------------------*/ - void process_coinc_tsi ( -/* ================= -*/ uint hdr) { - -/* Routine to process a "coincidence" Timing-Status-Info -** Packet. These packets have 10 bytes altogether. The first -** 4 bytes are in hdr. -*/ - int i, j, is; - register union { - uint ui4; - usint ui2[2]; - uchar ui1[4]; - } lwl_data; - - usint words[3]; - - for (j=0; j<3; j++) { /* Get the remaining 6 bytes */ - for (i=0; i<1000; i++) { - lwl_data.ui4 = *Lwl_fifo; /* Get the last 16 bits */ - if (lwl_data.ui4 != LWL_FIFO_EMPTY) break; - taskDelay (0); /* But wait if FIFO is slow! */ - } - if (lwl_data.ui4 == LWL_FIFO_EMPTY) { - printf ("Time-out getting last 6 bytes of a \"coincidence\" " - "TSI packet!\n"); - return; - } - words[j] = lwl_data.ui2[1]; - } - - N_coin_tsi++; - Dt_or_dts.both = hdr & LWL_TSI_DT_MSK; - Nrl_active = ((hdr & LWL_HDR_NRL_MASK) != 0) ? True : False; - Daq_active = ((hdr & Lwl_hdr_daq_mask) == Lwl_hdr_daq_soll) ? True : False; - Tsi_status_info = words[0]; - - Tsi_flags = (Nrl_active) ? STATUS_FLAGS__NRL : 0; - if ((hdr & LWL_HDR_PF_MASK) != 0) Tsi_flags |= STATUS_FLAGS__PF; - if ((hdr & LWL_HDR_SWC_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SWC; - if (Daq_active) Tsi_flags |= STATUS_FLAGS__DAQ; - if ((hdr & LWL_HDR_SYNC0_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SYNC0; - if ((hdr & LWL_HDR_SYNC1_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SYNC1; - if ((hdr & LWL_HDR_SYNC2_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SYNC2; - if ((hdr & LWL_HDR_SYNC3_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SYNC3; - if ((hdr & LWL_HDR_UD_MASK) != 0) Tsi_flags |= STATUS_FLAGS__UD; - if ((hdr & LWL_HDR_GU_MASK) != 0) Tsi_flags |= STATUS_FLAGS__GU; - - lwl_data.ui2[0] = words[1]; - lwl_data.ui2[1] = words[2]; - Num_bad_events = lwl_data.ui4; - } -/* -**--------------------------------------------------------------------------*/ - void process_no_coinc_tsi ( -/* ==================== -*/ uint hdr) { - -/* Routine to process a "normal" Timing-Status-Info Packet. -** These packets have 6 bytes altogether. The first 4 bytes are -** in hdr. -*/ - int i; - register union { - uint ui4; - usint ui2[2]; - uchar ui1[4]; - } lwl_data; - - for (i=0; i<1000; i++) { - lwl_data.ui4 = *Lwl_fifo; /* Get the last 16 bits */ - if (lwl_data.ui4 != LWL_FIFO_EMPTY) break; - taskDelay (0); /* But wait if FIFO is slow! */ - } - if (lwl_data.ui4 == LWL_FIFO_EMPTY) { - printf ("Time-out getting last 16 bits of a \"normal\" TSI packet!\n"); - return; - } - N_no_coin_tsi++; - Dt_or_dts.both = hdr & LWL_TSI_DT_MSK; - Nrl_active = ((hdr & LWL_HDR_NRL_MASK) != 0) ? True : False; - Daq_active = ((hdr & Lwl_hdr_daq_mask) == Lwl_hdr_daq_soll) ? True : False; - Tsi_status_info = lwl_data.ui2[1]; - - Tsi_flags = (Nrl_active) ? STATUS_FLAGS__NRL : 0; - if ((hdr & LWL_HDR_PF_MASK) != 0) Tsi_flags |= STATUS_FLAGS__PF; - if ((hdr & LWL_HDR_SWC_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SWC; - if (Daq_active) Tsi_flags |= STATUS_FLAGS__DAQ; - if ((hdr & LWL_HDR_SYNC0_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SYNC0; - if ((hdr & LWL_HDR_SYNC1_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SYNC1; - if ((hdr & LWL_HDR_SYNC2_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SYNC2; - if ((hdr & LWL_HDR_SYNC3_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SYNC3; - if ((hdr & LWL_HDR_UD_MASK) != 0) Tsi_flags |= STATUS_FLAGS__UD; - if ((hdr & LWL_HDR_GU_MASK) != 0) Tsi_flags |= STATUS_FLAGS__GU; - } -/* -**--------------------------------------------------------------------------*/ - int rply_status_send ( -/* ================ -*/ int skt, - struct rply_buff_struct *rply_bf) { - - int is; - - is = send (skt, (char *) rply_bf, sizeof (*rply_bf), 0); - if (is == sizeof (*rply_bf)) { - Rw_bytes_put += is; - return OK; - }else { - return ERROR; - } - } -/* -**-------------------------------------------------------------------------- -** rply_status_setup: Routine to set up a Status-response to client. -** If is not NULL, will be copied -** to the message field of the response. Otherwise, -** only the status and sub_status fields will be -** set up. -*/ - void rply_status_setup ( -/* ================= -*/ struct rply_buff_struct *rply_bf, - int status, - int sub_status, - char *msg) { - - rply_bf->bigend = htonl (0x12345678); - rply_bf->status = htonl (status); - rply_bf->sub_status = htonl (sub_status); - if (msg != NULL) { - if (strlen (msg) < sizeof (rply_bf->u.message)) { - strcpy (rply_bf->u.message, msg); - }else { - strcpy (rply_bf->u.message, "Message overflow!"); - } - } - } -/* -**--------------------------------------------------------------------------*/ - int rply_status_setup_and_send ( -/* ========================== -*/ int skt, - struct rply_buff_struct *rply_bf, - int status, - int sub_status, - char *msg) { - - int is; - - rply_status_setup (rply_bf, status, sub_status, msg); - is = rply_status_send (skt, rply_bf); - - return is; - } -/* -**--------------------------------------------------------------------------*/ - uchar *selectNewBuffer (uchar *nxt) { -/* =============== -** -** Move to new buffer in SQHM_TRANS mode. -** -** *nxt = next free byte in current buffer. -** Return value is first free byte in next buffer. -*/ - int i; - /* - ** Close off the current buffer - */ - *nxt = 0; - i = nxt - Tran_buff_base; /* Get number of bytes used in this buffer */ - memcpy (Tran_buff_base, &i, sizeof (i)); /* Put at front of buffer */ - /* - ** Move to next buffer - */ - Curr_hist++; - if (Curr_hist > N_hists) Curr_hist = 0; - Tran_buff_base = ((uchar *) Hist_base_addr) + (Curr_hist * N_bins); - Next_char = Tran_buff_base + 4; - return Next_char; - } -/* -**--------------------------------------------------------------------------*/ - void setupLevelGenerator (int use_level_gen, char *base_addr) { -/* =================== -** Set up VME access to a VMIO10 module at address 0x1900 -** to be used for generating timing signals. -** -** If (use_level_gen == 0), the level generator will not -** be used. The VME address will point to a memory -** location. -*/ - STATUS status; - char aux; - void (* sig_status) (int); - - if (use_level_gen == 0) { - VmioBase = Vmio_Dummy; - printf ("Timing signal generation via VMIO10 module disabled.\n"); - return; - } - if (base_addr == NULL) { - status = sysBusToLocalAdrs (VME_AM_USR_SHORT_IO, (char *) VMIO_BASE_ADDR, - (char **) &VmioBase); - }else { - status = sysBusToLocalAdrs (VME_AM_USR_SHORT_IO, base_addr, - (char **) &VmioBase); - } - if (status != OK) { - printf ("Error status from sysBusToLocalAdrs -- VMIO10 disabled.\n"); - VmioBase = Vmio_Dummy; - return; - } - /* - ** The "setjmp" and "signal" stuff it to trap a possible machine - ** check if the VMIO10 module is absent. This is rather obscure - ** code -- sorry about that but blame Unix thinking, not me, if - ** you don't like it! - */ - sig_status = signal (SIGBUS, catch_machine_check); - if (setjmp (Vmio_trap_env) != 0) { - /* - ** We get to this code only if the VMIO10 module is absent. - */ - printf ("\007Bus error detected on trying to access the VMIO10 module!\n" - "Timing signals will not be generated via the VMIO10.\n"); - VmioBase = Vmio_Dummy; - return; - } - /* - ** Now set up Ports A & B of the VMIO10, i.e. the first Z8536-CIO. - ** If the module is absent, the first access will trap and exit via - ** the "setjmp" condition block above. - ** - ** Start with a "reset" .. - */ - aux = VmioBase[VMIO_AB_CNTL]; /* Read Cntrl to ensure not State 1 */ - VmioBase[VMIO_AB_CNTL] = 0x00; /* Write zero to Cntrl to ensure not in .. - ** .. "Reset State" */ - aux = VmioBase[VMIO_AB_CNTL]; /* Read Cntrl to ensure State 0 */ - VmioBase[VMIO_AB_CNTL] = Z8536_MICR; /* Select the Mstr Int Ctrl Reg */ - VmioBase[VMIO_AB_CNTL] = 0x01; /* Set the reset bit */ - VmioBase[VMIO_AB_CNTL] = 0x00; /* Then clr it to complete reset */ - /* - ** Now set polarity and direction .. - */ - VmioBase[VMIO_AB_CNTL] = Z8536_DPPR_A; /* Port A Data Path Pol */ - VmioBase[VMIO_AB_CNTL] = 0x00; /* Non-inverting */ - VmioBase[VMIO_AB_CNTL] = Z8536_DPPR_B; /* Port B Data Path Pol */ - VmioBase[VMIO_AB_CNTL] = 0x00; /* Non-inverting */ - - VmioBase[VMIO_AB_CNTL] = Z8536_DDR_A; /* Port A Data Direction */ - VmioBase[VMIO_AB_CNTL] = 0x00; /* All bits output */ - VmioBase[VMIO_AB_CNTL] = Z8536_DDR_B; /* Port B Data Direction */ - VmioBase[VMIO_AB_CNTL] = 0x00; /* All bits output */ - /* - ** Now enable Ports A & B .. - */ - VmioBase[VMIO_AB_CNTL] = Z8536_MCCR; /* Select Master Config Ctrl Reg */ - VmioBase[VMIO_AB_CNTL] = 0x84; - /* - ** Finally zero Ports A & B .. - */ - VmioBase[VMIO_PORT_A] = 0x00; - VmioBase[VMIO_PORT_B] = 0x00; - - sig_status = signal (SIGBUS, SIG_DFL); /* Reset trap handler to default */ - - printf ("Timing signal generation via VMIO10 module enabled.\n"); - return; - } -/* -**-------------------------------------------------------------------------- -** setup_inet_info: Get Internet Nodename and Address from System. -*/ - void setup_inet_info ( -/* =============== -*/ char *host, - int host_size, - char *addr, - int addr_size) { - - int status; - struct in_addr my_addr; - char my_addr_c[INET_ADDR_LEN]; - - status = gethostname (host, host_size); - if (status != 0) StrJoin (host, host_size, "Undefined", ""); - - my_addr.s_addr = hostGetByName (host); - inet_ntoa_b (my_addr, my_addr_c); - StrJoin (addr, addr_size, my_addr_c, ""); - } -/*--------------------------------------------------------------------------*/ - int sleep (int secs) { -/* ===== -** Go to sleep for secs seconds. -*/ - int ticks; - - ticks = secs * sysClkRateGet (); - taskDelay (ticks); - return 0; - } -/* -**--------------------------------------------------------------------------- -** StrJoin - join 2 strings. -** -** The routine joins 2 strings, checking for total string -** length and ensuring the result will be zero terminated. -** The "result" arg may be the same as "str_a" or "str_b". -** -** Note: strncat is used exclusively rather than -** strncpy to be sure result is always -** null terminated. -*/ - char *StrJoin ( -/* ======= -*/ char *result, - int result_size, - char *str_a, - char *str_b) { - - int i, size, size_a, size_b; - - size = result_size - 1; - - if (size < 0) return result; - - if (result == str_a) { /* Are the result and str_a the same? */ - size_a = strlen (str_a); /* Yes */ - if (size_a > size) { /* Check sizes anyway. */ - result[size] = NIL; /* Truncate str_a. No room for str_b! */ - }else { - size = size - strlen (result); /* And append str_b */ - if (size > 0) { - strncat (result, str_b, size); - } - } - }else if (result == str_b) { /* Are the result and str_b the same? */ - size_a = strlen (str_a); /* Yes, this is a bit complicated! */ - size_b = strlen (str_b); - if (size_a >= size) { /* If str_a completely fills result, .. */ - result[0] = NIL; /* .. then just copy in str_a */ - strncat (result, str_a, size); - }else { - /* - ** Otherwise, str_b must first be moved to - ** make room for str_a and then str_a must - ** be put at the front of the result. - */ - if ((size_a + size_b) > size) size_b = size - size_a; - result[size_a+size_b] = NIL; - for (i = (size_b-1); i >= 0; i--) result[size_a+i] = str_b[i]; - memcpy (result, str_a, size_a); - } - }else { /* Result is neither str_a nor str_b so .. */ - result[0] = NIL; /* .. str_a needs to be copied */ - strncat (result, str_a, size); - size = size - strlen (result); /* And str_a appended */ - if (size > 0) strncat (result, str_b, size); - } - return result; - } -/*===================================== End of SinqHM_srv_routines.c ========*/