Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

globmem.cc

Go to the documentation of this file.
00001 /*************************************************************************
00002 * File: globmem.cc                                                       *
00003 * Authors: Fred Proctor, Will Shackleford                                *
00004 * Purpose: C++ file for the Communication Management System(CMS).        *
00005 * Includes:                                                              *
00006 *          1. Member functions for class GLOBMEM.                        *
00007 * Note: GLOBMEM is used for communication between multiple VxWorks       *
00008 * boards in a single backplane.                                          *
00009 *************************************************************************/
00010 
00011 /* Include Files */
00012 #ifdef EXTERN_C_STD_HEADERS
00013 extern "C"
00014 {
00015 #endif
00016 
00017 #include <string.h>             /* memcpy(), memset(), strtol() */
00018 #include <stddef.h>             /* size_t */
00019 #include <stdlib.h>             /* calloc() */
00020 #include <ctype.h>              /* isdigit(), toupper(), tolower() */
00021 #include <math.h>               /* fabs() */
00022 
00023 #ifdef VXWORKS
00024 #include "vxWorks.h"
00025 #include "sysLib.h"             /* sysBusToLocalAdrs() */
00026 #include "taskLib.h"            /* taskLock() */
00027 #include "semLib.h"
00028 #include "semSmLib.h"
00029 #include "objLib.h"
00030 #include "vme.h"                /* VME_AM_STD_USR_DATA */
00031 #endif
00032 
00033 #ifdef EXTERN_C_STD_HEADERS
00034 }
00035 #endif
00036 
00037 
00038 
00039 #ifdef VXWORKS
00040 extern "C"
00041 {
00042 #ifndef POWERPC
00043 #include "spinlock.h"           /* _access functions */
00044 #endif
00045 #include "bus_lock.h"
00046 #include "dma.h"
00047 }
00048 #endif
00049 
00050 #include "cms.hh"               /* class CMS */
00051 #include "globmem.hh"           /* class GLOBMEM */
00052 #include "timer.hh"             /* class RCS_TIMER */
00053 #include "rcs_prnt.hh"          /* rcs_print_error() */
00054 
00055 #define SEM_DELAY_EPSILON  (1.0E-6)
00056 #define DEFAULT_SEM_DELAY (1.0E-3)
00057 #define SEM_CHECK_TIME_EPSILON (1.0E-7)
00058 
00059 #if defined(WIN32) && defined(USE_BIT3)
00060 #include "btapi.h"
00061 #endif
00062 
00063 /* External data */
00064 unsigned long (*get_physical_address_func) (char *)
00065   = (unsigned long (*)(char *)) NULL;
00066 
00067 
00068 /* Global Definitions. */
00069 static int
00070 convert2lower (char *dest, char *src, int len)
00071 {
00072   int i;
00073   for (i = 0; i < len; i++)
00074     {
00075       if (src[i] == 0)
00076         {
00077           dest[i] = 0;
00078           return i;
00079         }
00080       dest[i] = tolower (src[i]);
00081     }
00082   return i;
00083 }
00084 
00085 static int
00086 convert2upper (char *dest, char *src, int len)
00087 {
00088   int i;
00089   for (i = 0; i < len; i++)
00090     {
00091       if (src[i] == 0)
00092         {
00093           dest[i] = 0;
00094           return i;
00095         }
00096       dest[i] = toupper (src[i]);
00097     }
00098   return i;
00099 }
00100 
00101 /* GLOBMEM Member Functions */
00102 
00103 #ifdef VXWORKS
00104 int RCS_BOARD_TYPE = UNKNOWN_BOARD_TYPE;
00105 int usrSmObjInitInitialized = 0;
00106 int VxMP_Option_Installed = 0;
00107 int dma_being_used = 0;
00108 #endif
00109 
00110 
00111 /* Constructor used by cms_config. */
00112 GLOBMEM::GLOBMEM (char *bufline, char *procline, int set_to_server,
00113                   int set_to_master):
00114 CMS (bufline, procline, set_to_server)
00115 {
00116   int address_space_code = 0;
00117   RCS_TIMER timer (1.0);
00118   char *address_equation;
00119   char *semdelay_equation;
00120   physical_address = 0;
00121   skip_area = 0;
00122   local_locks = (char *) NULL;
00123   physmem_handle = (PHYSMEM_HANDLE *) NULL;
00124   sem_delay = DEFAULT_SEM_DELAY;
00125   half_size = size / 2;
00126   half_offset = size / 2;
00127 #ifdef VXWORKS
00128   board_type = RCS_BOARD_TYPE;
00129   use_dma = 0;
00130   bl_info = 0;
00131   dma_info = 0;
00132 #endif
00133   lock_bus = 0;
00134 
00135   char *board_type_eq = NULL;
00136 #ifdef VXWORKS
00137   if (NULL != (board_type_eq = sysModel ()))
00138     {
00139       if (!strncmp (board_type_eq, "MVME162", 7))
00140         {
00141           board_type = VX_MVME162_BOARD_TYPE;
00142         }
00143     }
00144 #endif
00145 
00146 #ifdef VXWORKS
00147   if (NULL != (board_type_eq = strstr (buflineupper, "BD_TYPE=")))
00148     {
00149       board_type_eq += 8;
00150       if (!strncmp (board_type_eq, "MVME162", 7))
00151         {
00152           board_type = VX_MVME162_BOARD_TYPE;
00153         }
00154     }
00155 
00156   if (NULL != (board_type_eq = strstr (proclineupper, "BD_TYPE=")))
00157     {
00158       board_type_eq += 8;
00159       if (!strncmp (board_type_eq, "MVME162", 7))
00160         {
00161           board_type = VX_MVME162_BOARD_TYPE;
00162         }
00163     }
00164 
00165 #endif
00166 
00167 
00168 #ifdef VXWORKS
00169 
00170   if (NULL != strstr (buflineupper, "LOCK_BUS"))
00171     {
00172       if (board_type == UNKNOWN_BOARD_TYPE)
00173         {
00174           rcs_print_error
00175             ("Can not use lock_bus option with unknown board type.\n");
00176         }
00177       else
00178         {
00179           lock_bus = 1;
00180           total_connections = 0;
00181         }
00182     }
00183   lock_task = 1;
00184   if (NULL != strstr (buflineupper, "NO_TASK_LOCK"))
00185     {
00186       lock_task = 0;
00187     }
00188   if (NULL != strstr (proclineupper, "NO_TASK_LOCK"))
00189     {
00190       lock_task = 0;
00191     }
00192 
00193   use_test_and_set=1;
00194   if (NULL != strstr (buflineupper, "NO_TEST_AND_SET"))
00195     {
00196       use_test_and_set = 0;
00197     }
00198 
00199   if (NULL != strstr (proclineupper, "USE_DMA"))
00200     {
00201       if (board_type == UNKNOWN_BOARD_TYPE)
00202         {
00203           rcs_print_error
00204             ("Can not use lock_bus option with unknown board type.\n");
00205         }
00206       else
00207         {
00208           use_dma = 1;
00209         }
00210     }
00211 #endif
00212 
00213   if (total_connections <= connection_number && !lock_bus)
00214     {
00215       rcs_print_error
00216         ("GLOBMEM: connection number(%d) must be less than total connections (%d).\n",
00217          connection_number, total_connections);
00218       status = CMS_CONFIG_ERROR;
00219       return;
00220     }
00221 
00222   address_type = INVALID_ADDRESS_TYPE;
00223   convert2upper (address_type_name, ProcessName, CMS_CONFIG_LINELEN);
00224   strcat (address_type_name, "_ADDR=");
00225   if (NULL != (address_equation = strstr (buflineupper, address_type_name)))
00226     {
00227       physical_address =
00228         get_physical_address (address_equation + strlen (address_type_name));
00229       address_type = PROCESS_SPECIFIC_ADDRESS;
00230     }
00231   if (address_type == INVALID_ADDRESS_TYPE)
00232     {
00233       convert2upper (address_type_name, ProcessHost, CMS_CONFIG_LINELEN);
00234       strcat (address_type_name, "_ADDR=");
00235       if (NULL !=
00236           (address_equation = strstr (buflineupper, address_type_name)))
00237         {
00238           physical_address =
00239             get_physical_address (address_equation +
00240                                   strlen (address_type_name));
00241           address_type = HOST_SPECIFIC_ADDRESS;
00242         }
00243     }
00244 #if defined(VXWORKS) || defined(linuxVME)
00245   if (address_type == INVALID_ADDRESS_TYPE)
00246     {
00247       strcpy (address_type_name, "VME_ADDR=");
00248       if (NULL !=
00249           (address_equation = strstr (buflineupper, address_type_name)))
00250         {
00251           physical_address =
00252             get_physical_address (address_equation +
00253                                   strlen (address_type_name));
00254           address_type = VME_ADDRESS;
00255           strcpy (address_type_name, "VME_CODE=");
00256           address_space_code = 0;
00257           if (NULL !=
00258               (address_equation = strstr (buflineupper, address_type_name)))
00259             {
00260               address_space_code = (unsigned long)
00261                 strtol (address_equation + strlen (address_type_name),
00262                         (char **) NULL, 0);
00263             }
00264         }
00265     }
00266 #endif
00267 #if defined(MSDOS) || defined(WIN32) || defined(_WINDOWS)
00268   if (address_type == INVALID_ADDRESS_TYPE)
00269     {
00270       strcpy (address_type_name, "EISA_ADDR=");
00271       if (NULL !=
00272           (address_equation = strstr (buflineupper, address_type_name)))
00273         {
00274           physical_address =
00275             get_physical_address (address_equation +
00276                                   strlen (address_type_name));
00277           address_type = EISA_ADDRESS;
00278         }
00279     }
00280 
00281   if (address_type == INVALID_ADDRESS_TYPE)
00282     {
00283       strcpy (address_type_name, "ISA_ADDR=");
00284       if (NULL !=
00285           (address_equation = strstr (buflineupper, address_type_name)))
00286         {
00287           physical_address =
00288             get_physical_address (address_equation +
00289                                   strlen (address_type_name));
00290           address_type = ISA_ADDRESS;
00291         }
00292     }
00293 
00294   if (address_type == INVALID_ADDRESS_TYPE)
00295     {
00296       strcpy (address_type_name, "PCI_ADDR=");
00297       if (NULL !=
00298           (address_equation = strstr (buflineupper, address_type_name)))
00299         {
00300           physical_address =
00301             get_physical_address (address_equation +
00302                                   strlen (address_type_name));
00303           address_type = PCI_ADDRESS;
00304         }
00305     }
00306 #endif
00307   if (address_type == INVALID_ADDRESS_TYPE)
00308     {
00309       strcpy (address_type_name, "GENERIC_ADDR=");
00310       if (NULL !=
00311           (address_equation = strstr (buflineupper, address_type_name)))
00312         {
00313           physical_address =
00314             get_physical_address (address_equation +
00315                                   strlen (address_type_name));
00316           address_type = GENERIC_ADDRESS;
00317         }
00318     }
00319 
00320 #if defined(USE_BIT3) && defined(WIN32)
00321   unit = 0;
00322   remote_address = 0;
00323   bt_type = BT_DEV_DEFAULT;
00324   bt_use_mmap = 0;
00325 
00326 
00327   if (physical_address > 0)
00328     {
00329       remote_address = physical_address;
00330     }
00331 
00332   strcpy (address_type_name, "BIT3_OFFSET=");
00333   if (NULL != (address_equation = strstr (buflineupper, address_type_name)))
00334     {
00335       physical_address = remote_address =
00336         get_physical_address (address_equation + strlen (address_type_name));
00337       address_type = GENERIC_ADDRESS;
00338     }
00339 
00340   strcpy (address_type_name, "BIT3_UNIT=");
00341   if (NULL != (address_equation = strstr (buflineupper, address_type_name)))
00342     {
00343       unit = strtol (address_equation + strlen (address_type_name), NULL, 0);
00344     }
00345 
00346   if (NULL != strstr (buflineupper, "BIT3_USE_MMAP"))
00347     {
00348       bt_use_mmap = 1;
00349     }
00350 
00351   /* Open the unit */
00352   bt_status = bt_open (&btd,
00353                        bt_gen_name (unit, bt_type, &devname[0],
00354                                     BT_MAX_DEV_NAME), BT_RD | BT_WR);
00355   if (BT_SUCCESS != bt_status)
00356     {
00357       bt_perror (btd, bt_status, "Could not open the Bit3 device. ");
00358       status = CMS_MISC_ERROR;
00359       return;
00360     }
00361 
00362   /* Clear any outstanding errors */
00363   bt_status = bt_clrerr (btd);
00364   if (BT_SUCCESS != bt_status)
00365     {
00366       bt_perror (btd, bt_status,
00367                  "Could not clear errors from the Bit3 device. ");
00368       (void) bt_close (btd);
00369       status = CMS_MISC_ERROR;
00370       return;
00371     }
00372 
00373 #if 0
00374   /* Disable byte/word swapping */
00375   bt_status = bt_set_info (btd, BT_INFO_SWAP, BT_SWAP_NONE);
00376   if (BT_SUCCESS != bt_status)
00377     {
00378       bt_perror (btd, bt_status,
00379                  "Could not set BT_INFO_SWAP to BT_SWAP_NONE ");
00380       (void) bt_close (btd);
00381       status = CMS_MISC_ERROR;
00382       return;
00383     }
00384 #endif
00385 
00386   if (!bt_use_mmap)
00387     {
00388       physmem_handle = new PHYSMEM_HANDLE (btd, remote_address, size, 0);
00389     }
00390   else
00391     {
00392       /* Do the actual mmap */
00393       bt_status = bt_mmap (btd, &remote_p, remote_address, size,
00394                            BT_RD | BT_WR, BT_SWAP_DEFAULT);
00395       if (BT_SUCCESS != bt_status)
00396         {
00397           bt_perror (btd, bt_status,
00398                      "Could not memory map the Bit3 device. ");
00399           (void) bt_close (btd);
00400           status = CMS_MISC_ERROR;
00401           return;
00402         }
00403       physical_address = (unsigned long) remote_p;
00404 
00405       physmem_handle = new PHYSMEM_HANDLE ();
00406       physmem_handle->size = size;
00407       physmem_handle->local_address = (char *) physical_address;
00408       physmem_handle->swap_mode = 1;
00409       physmem_handle->using_bit3 = 1;
00410     }
00411 
00412 #endif
00413 
00414 
00415 
00416 
00417   if (address_type == INVALID_ADDRESS_TYPE)
00418     {
00419       rcs_print_error ("GLOBMEM: No applicable address specified.\n");
00420       status = CMS_CONFIG_ERROR;
00421       return;
00422     }
00423 
00424 #ifndef USE_BIT3
00425   if (0 == physical_address)
00426     {
00427       rcs_print_error ("GLOBMEM: physical address is zero.\n");
00428       status = CMS_CONFIG_ERROR;
00429       return;
00430     }
00431 #endif
00432 
00433 
00434 #ifdef VXWORKS
00435   if (lock_bus)
00436     {
00437       bl_info = getBusLockInfo (board_type, physical_address);
00438       if (NULL == bl_info)
00439         {
00440           rcs_print_error
00441             ("Can't get bus lock info for board type %d, and address 0x%X\n",
00442              board_type, physical_address);
00443           status = CMS_CONFIG_ERROR;
00444           return;
00445         }
00446     }
00447 
00448   if (use_dma)
00449     {
00450       dma_info = getDMAInfo (board_type, physical_address);
00451       if (NULL == dma_info)
00452         {
00453           rcs_print_error
00454             ("Can't get DMA info for board type %d, and address 0x%X\n",
00455              board_type, physical_address);
00456           status = CMS_CONFIG_ERROR;
00457           use_dma = 0;
00458           return;
00459         }
00460     }
00461 
00462   if (use_dma && lock_bus)
00463     {
00464       rcs_print_error
00465         ("GLOBMEM: Can't use DMA and use the bus lock for mutual exclusion.\n");
00466       status = CMS_CONFIG_ERROR;
00467       use_dma = 0;
00468       return;
00469     }
00470 
00471   if (use_dma && neutral)
00472     {
00473       rcs_print_error ("GLOBMEM:: Can't use DMA with neutral buffers.\n");
00474       status = CMS_CONFIG_ERROR;
00475       use_dma = 0;
00476       return;
00477     }
00478 
00479   if (use_dma && queuing_enabled)
00480     {
00481       rcs_print_error ("GLOBMEM: Can't use DMA with queued buffers.\n");
00482       status = CMS_CONFIG_ERROR;
00483       use_dma = 0;
00484       return;
00485     }
00486 
00487   /* if(use_dma && dma_being_used)
00488      {
00489      rcs_print_error("DMA already used by another process/buffer.\n");
00490      rcs_print_error("Only 1 NMLConnection can use DMA per board.\n");
00491      status = CMS_CONFIG_ERROR;
00492      use_dma = 0;
00493      return;
00494      }
00495    */
00496   if (use_dma)
00497     {
00498       dma_being_used = 1;
00499     }
00500 
00501 #endif
00502 
00503 #if !defined(USE_BIT3) || !defined(WIN32)
00504 
00505   physmem_handle = new PHYSMEM_HANDLE (physical_address,
00506                                        address_space_code, size);
00507 
00508 #endif
00509 
00510   if (1 == set_to_master)
00511     {
00512       is_local_master = 1;
00513     }
00514   else if (-1 == set_to_master)
00515     {
00516       is_local_master = 0;
00517     }
00518 
00519   if (NULL != (semdelay_equation = strstr (proclineupper, "SEMDELAY=")))
00520     {
00521       sem_delay = strtod (semdelay_equation + 9, (char **) NULL);
00522     }
00523   else if (NULL != (semdelay_equation = strstr (buflineupper, "SEMDELAY=")))
00524     {
00525       sem_delay = strtod (semdelay_equation + 9, (char **) NULL);
00526     }
00527 
00528   /* if this is the master, clear the buffer */
00529   if (is_local_master)
00530     {
00531       physmem_handle->memsetf (0, 0, size);
00532     }
00533   local_locks = (char *) NULL;
00534   int remainder;
00535   if (split_buffer)
00536     {
00537       remainder = (physical_address + total_connections + 2) % 4;
00538       skip_area = total_connections + 2;
00539     }
00540   else
00541     {
00542       remainder = (physical_address + total_connections) % 4;
00543       skip_area = total_connections;
00544     }
00545   if (remainder)
00546     {
00547       skip_area += (4 - remainder);
00548     }
00549   local_locks = (char *) malloc ((long) total_connections);
00550 
00551 #ifdef VXWORKS
00552   bsem = 0;
00553 #endif
00554 
00555   if (min_compatible_version > 2.58 || min_compatible_version < 1E-6)
00556     {
00557       if (is_local_master)
00558         {
00559           physmem_handle->write (BufferName, 31);
00560 #ifdef VXWORKS
00561           if (NULL != strstr (buflineupper, "BSEM"))
00562             {
00563               if (VxMP_Option_Installed)
00564                 {
00565 #if 0
00566                   if (!usrSmObjInitInitialized)
00567                     {
00568                       if (OK == usrSmObjInit (NULL))
00569                         {
00570                           usrSmObjInitInitialized = 1;
00571                         }
00572                       else
00573                         {
00574                           rcs_print_error ("usrSmObjInit error %d %s",
00575                                            errno, strerror (errno));
00576                         }
00577                     }
00578                   if (usrSmObjInitInitialized)
00579                     {
00580                       physmem_handle->offset = 32;
00581                       bsem = semBSmCreate (0, SEM_EMPTY);
00582                       void *glob_bsem = smObjLocalToGlobal ((void *) bsem);
00583                       physmem_handle->write (&glob_bsem, sizeof (void *));
00584                     }
00585 #endif
00586                 }
00587             }
00588 #endif
00589         }
00590       else
00591         {
00592           char buf_name_check[32];
00593           physmem_handle->read (buf_name_check, 31);
00594           buf_name_check[31] = 0;
00595           if (buf_name_check[0] != BufferName[0]
00596               && !isalnum (buf_name_check[0]))
00597             {
00598               rcs_print_error
00599                 ("GLOBMEM: buffer not initialized, start master.\n");
00600               status = CMS_NO_MASTER_ERROR;
00601               return;
00602             }
00603           if (strncmp (buf_name_check, BufferName, 31))
00604             {
00605               rcs_print_error
00606                 ("GLOBMEM: Buffers %s and %s may have conflicting addresses..\n",
00607                  buf_name_check, BufferName);
00608               status = CMS_MISC_ERROR;
00609               return;
00610             }
00611 #ifdef VXWORKS
00612           if (NULL != strstr (buflineupper, "BSEM"))
00613             {
00614               if (VxMP_Option_Installed)
00615                 {
00616 #if 0
00617                   if (!usrSmObjInitInitialized)
00618                     {
00619                       if (OK == usrSmObjInit (NULL))
00620                         {
00621                           usrSmObjInitInitialized = 1;
00622                         }
00623                       else
00624                         {
00625                           rcs_print_error ("usrSmObjInit error %d %s",
00626                                            errno, strerror (errno));
00627                         }
00628                     }
00629                   if (usrSmObjInitInitialized)
00630                     {
00631                       physmem_handle->offset = 32;
00632                       void *glob_bsem = NULL;
00633                       physmem_handle->read (&glob_bsem, sizeof (void *));
00634                       bsem = (SEM_ID) smObjGlobalToLocal (glob_bsem);
00635                     }
00636 #endif
00637                 }
00638             }
00639 #endif
00640         }
00641       skip_area += 36;
00642       physical_address += 36;
00643     }
00644 
00645   if (total_subdivisions <= 0)
00646     {
00647       total_subdivisions = 1;
00648     }
00649 
00650   if (split_buffer)
00651     {
00652       if (neutral)
00653         {
00654           max_message_size =
00655             (size_without_diagnostics / 2) - skip_area - encoded_header_size;
00656           max_encoded_message_size =
00657             size_without_diagnostics - skip_area - total_connections -
00658             encoded_header_size;
00659           guaranteed_message_space = max_message_size / 4;
00660         }
00661       else
00662         {
00663           max_message_size =
00664             (size_without_diagnostics / 2) - skip_area - sizeof (CMS_HEADER);
00665           max_encoded_message_size = 4 * max_message_size;
00666           guaranteed_message_space = max_message_size;
00667         }
00668     }
00669   else
00670     {
00671       subdiv_size =
00672         (size_without_diagnostics - skip_area) / total_subdivisions;
00673       subdiv_size -= (subdiv_size % 4);
00674       if (neutral)
00675         {
00676           max_message_size = subdiv_size - encoded_header_size;
00677           max_encoded_message_size = subdiv_size - encoded_header_size;
00678           guaranteed_message_space = max_message_size / 4;
00679         }
00680       else
00681         {
00682           max_message_size = subdiv_size - sizeof (CMS_HEADER);
00683           max_encoded_message_size = 4 * max_message_size;
00684           guaranteed_message_space = max_message_size;
00685         }
00686     }
00687 
00688   if (enc_max_size > 0 && enc_max_size < max_encoded_message_size)
00689     {
00690       max_encoded_message_size = enc_max_size;
00691     }
00692 
00693   handle_to_global_data = physmem_handle;
00694   fast_mode = split_buffer && !neutral && !queuing_enabled &&
00695     timeout < SEM_CHECK_TIME_EPSILON && timeout >= 0.0;
00696 #ifdef VXWORKS
00697   my_lock = (char *) physical_address + connection_number;
00698   toggle_bit_address = (char *) physical_address + total_connections;
00699   was_read_address = (char *) physical_address + total_connections + 1;
00700 #endif
00701 
00702 
00703 
00704 
00705 #if 0
00706   rcs_print ("GLOBMEM: size = %ld\n", size);
00707   rcs_print ("GLOBMEM: size = %ld\n", size);
00708   rcs_print ("GLOBMEM: total_connections = %ld\n", total_connections);
00709   rcs_print ("GLOBMEM: skip_area = %d\n", skip_area);
00710   rcs_print ("GLOBMEM: max_message_size = %ld\n", max_message_size);
00711   rcs_print ("GLOBMEM: max_encoded_message_size = %ld\n",
00712              max_encoded_message_size);
00713   rcs_print ("GLOBMEM: guaranteed_message_space = %ld\n", max_message_size);
00714 #endif
00715 }
00716 
00717 /* Destructor. */
00718 GLOBMEM::~GLOBMEM ()
00719 {
00720 
00721 #if defined(WIN32) && defined(USE_BIT3)
00722 
00723   if (bt_use_mmap)
00724     {
00725       /* Release the mmap resources */
00726       bt_status = bt_unmmap (btd, remote_p, size);
00727       if (BT_SUCCESS != bt_status)
00728         {
00729           bt_perror (btd, bt_status, "Could not release the memory map. ");
00730           (void) bt_close (btd);
00731           return;
00732         }
00733     }
00734 
00735   /* Check for Adaptor bt_status errors */
00736   bt_status = bt_chkerr (btd);
00737   if (BT_SUCCESS != bt_status)
00738     {
00739       bt_perror (btd, bt_status, "Memory mapped read failed. ");
00740       (void) bt_close (btd);
00741       return;
00742     }
00743 
00744   /* Close the device */
00745   bt_status = bt_close (btd);
00746   if (BT_SUCCESS != bt_status)
00747     {
00748       bt_perror (btd, bt_status, "Could not close the Bit3 device. ");
00749       return;
00750     }
00751 
00752 #endif
00753 
00754   if (NULL != physmem_handle)
00755     {
00756       if (delete_totally)
00757         {
00758           physmem_handle->memsetf (0, 0, size);
00759         }
00760       delete physmem_handle;
00761       physmem_handle = (PHYSMEM_HANDLE *) NULL;
00762     }
00763   if (NULL != local_locks)
00764     {
00765       free (local_locks);
00766       local_locks = (char *) NULL;
00767     }
00768 #ifdef VXWORKS
00769   if (NULL != bl_info)
00770     {
00771       freeBusLockInfo (bl_info);
00772     }
00773   if (NULL != dma_info)
00774     {
00775       freeDMAInfo (dma_info);
00776       dma_being_used = 0;
00777     }
00778 #endif
00779 }
00780 
00781 unsigned long
00782 GLOBMEM::get_physical_address (char *_address_string)
00783 {
00784   if (NULL != get_physical_address_func)
00785     {
00786       return (get_physical_address_func (_address_string));
00787     }
00788   if (NULL == _address_string)
00789     {
00790       return (0);
00791     }
00792   if (isdigit (_address_string[0]))
00793     {
00794       return ((unsigned long) strtoul (_address_string, (char **) NULL, 0));
00795     }
00796   /* Handle other ways of specifying an address. */
00797 
00798 
00799 #if 0
00800   // Get the address for the OLD Bit3
00801   //  defined(MSDOS) && defined(USE_BIT3)
00802   char *bit3_str = "BIT3DP(";
00803   long bit3_str_len = strlen (bit3_str);
00804 
00805   /* Is it a bit3 address that can be found autimatically */
00806   if (strlen (_address_string) >= bit3_str_len)
00807     {
00808       if (!memcmp (_address_string, bit3_str, bit3_str_len))
00809         {
00810           long board_number;
00811           char *second_arg;
00812           long offset;
00813           if (isdigit (_address_string[5]))
00814             {
00815               board_number = strtol (_address_string + 5, &second_arg, 0);
00816               if (',' == second_arg[0])
00817                 {
00818                   offset = strtol (second_arg + 1, NULL, 0);
00819                 }
00820               else
00821                 {
00822                   offset = 0;
00823                 }
00824             }
00825           else
00826             {
00827               board_number = 0;
00828               offset = 0;
00829             }
00830           return (get_bit3_dp_address (board_number, offset, size));
00831         }
00832     }
00833 
00834   bit3_str = "BIT3RR(";
00835   bit3_str_len = strlen (bit3_str);
00836 
00837   /* Is it a bit3 address that can be found autimatically */
00838   if (strlen (_address_string) >= bit3_str_len)
00839     {
00840       if (!memcmp (_address_string, bit3_str, bit3_str_len))
00841         {
00842           long board_number;
00843           char *second_arg;
00844           long offset;
00845           if (isdigit (_address_string[5]))
00846             {
00847               board_number = strtol (_address_string + 5, &second_arg, 0);
00848               if (',' == second_arg[0])
00849                 {
00850                   offset = strtol (second_arg + 1, NULL, 0);
00851                 }
00852               else
00853                 {
00854                   offset = 0;
00855                 }
00856             }
00857           else
00858             {
00859               board_number = 0;
00860               offset = 0;
00861             }
00862           return (get_bit3_rr_address (board_number, offset, size));
00863         }
00864     }
00865 #endif
00866 
00867   /* No Way Found. */
00868   return (0);
00869 }
00870 
00871 
00872 
00873 /* Access the global memory buffer. */
00874 CMS_STATUS
00875 GLOBMEM::main_access (void *_user_data)
00876 {
00877   if ((blocking_timeout > 1e-6 || blocking_timeout < -1e-6))
00878     {
00879       rcs_print_error (" Can not call blocking_read when using GLOBMEM.\n");
00880       return (status = CMS_NO_BLOCKING_SEM_ERROR);
00881     }
00882 
00883   /* check pointers */
00884   char was_read_byte;
00885   write_just_completed = 0;
00886   read_only = ((internal_access_type == CMS_CHECK_IF_READ_ACCESS) ||
00887                (internal_access_type == CMS_READ_ACCESS) ||
00888                (internal_access_type == CMS_PEEK_ACCESS));
00889 
00890 #ifdef VXWORKS
00891   if (use_dma)
00892     {
00893       int dma_status = checkForDMADone (dma_info);
00894       double time_diff = 0;
00895       double start_time = 0;
00896       if (timeout > 1e-6)
00897         {
00898           start_time = etime ();
00899         }
00900       while (1 != dma_status)
00901         {
00902           if (dma_status < 0)
00903             {
00904               status = CMS_MISC_ERROR;
00905               return (status);
00906             }
00907           time_diff = etime () - start_time;
00908           if (time_diff >= (timeout / 2))
00909             {
00910               rcs_print_error ("Timed out waiting for DMA Ready!\n");
00911               status = CMS_TIMED_OUT;
00912               return (status);
00913             }
00914           dma_status = checkForDMADone (dma_info);
00915         }
00916     }
00917 #endif
00918 
00919   /* acquire  access */
00920   if (get_access () == -1)
00921     {
00922       return (status);
00923     }
00924 
00925   physmem_handle->offset = 0;
00926 
00927   /* Perform access function. */
00928   internal_access (physmem_handle, _user_data);
00929 
00930 
00931   if (!read_only && status > 0)
00932     {
00933       write_just_completed = 1;
00934     }
00935   /* give up  access */
00936   if (release_access () == -1)
00937     {
00938       return (status);
00939     }
00940   if (split_buffer && !read_only)
00941     {
00942       was_read_byte = 0;
00943       if (min_compatible_version > 2.58 || min_compatible_version < 1E-6)
00944         {
00945           physmem_handle->offset = total_connections + 37;
00946         }
00947       else
00948         {
00949           physmem_handle->offset = total_connections + 1;
00950         }
00951       if (-1 == physmem_handle->write (&was_read_byte, 1))
00952         {
00953           rcs_print_error ("GLOBMEM: can not set was read flag.\n");
00954           release_access ();
00955           return (status = CMS_MISC_ERROR);
00956         }
00957     }
00958   return (status);
00959 }
00960 
00961 
00962 int
00963 GLOBMEM::get_access ()
00964 {
00965 #ifdef VXWORKS
00966   register char *ptr;
00967   register char *base = (char *) physical_address;
00968 #endif
00969   char write_char;
00970   double start_time, time;
00971   int semaphores_clear = 1;
00972 
00973   if (physmem_handle == NULL)
00974     {
00975       rcs_print_error ("GLOBMEM: No handle to physical memory.\n");
00976       status = CMS_MISC_ERROR;
00977       return (-1);
00978     }
00979 
00980 #ifdef VXWORKS
00981   if(use_test_and_set)
00982     {
00983       char *tas_address = physmem_handle->local_address + 36;
00984       if(timeout > 0)
00985         {
00986           start_time = etime();
00987         }
00988       while(1)
00989         {
00990           if(vxTas(tas_address) == TRUE)
00991             {
00992               // got it
00993               return 0;
00994             }
00995           if(timeout > 0)
00996             {
00997               if(etime() - start_time > timeout)
00998                 {
00999                   status = CMS_TIMED_OUT;
01000                   return(-1);
01001                 }
01002             }
01003           else if(timeout == 0)
01004             {
01005               status = CMS_TIMED_OUT;
01006               return -1;
01007             }
01008           if(sem_delay > SEM_DELAY_EPSILON)
01009             {
01010               esleep(sem_delay);
01011             }
01012         }
01013     }
01014 #endif
01015           
01016 
01017 #ifdef VXWORKS
01018   if (lock_task)
01019     {
01020       taskLock ();
01021     }
01022 #endif
01023 
01024 #ifdef VXWORKS
01025   if (lock_bus)
01026     {
01027       return enableBusLock (bl_info);
01028     }
01029 #endif
01030   if (read_only)
01031     {
01032       if (split_buffer)
01033         {
01034           char four = 4;
01035           physmem_handle->offset = connection_number + 36;
01036           if (-1 == physmem_handle->write (&four, 1))
01037             {
01038               status = CMS_MISC_ERROR;
01039               rcs_print_error
01040                 ("GLOBMEM: Error occured while reading physical memory.\n");
01041               return (-1);
01042             }
01043           physmem_handle->offset = total_connections + 36;
01044           if (-1 == physmem_handle->read (&toggle_bit, 1))
01045             {
01046               status = CMS_MISC_ERROR;
01047               rcs_print_error
01048                 ("GLOBMEM: Error occured while reading physical memory.\n");
01049               return (-1);
01050             }
01051           write_char = 2 + toggle_bit;
01052         }
01053       else
01054         {
01055           write_char = 2;
01056         }
01057     }
01058   else
01059     {
01060       physmem_handle->offset = total_connections + 36;
01061       if (-1 == physmem_handle->read (&toggle_bit, 1))
01062         {
01063           status = CMS_MISC_ERROR;
01064           rcs_print_error
01065             ("GLOBMEM: Error occured while reading physical memory.\n");
01066           return (-1);
01067         }
01068       write_char = 1;
01069     }
01070 
01071 #ifdef VXWORKS
01072   ptr = base + connection_number;
01073   *ptr = write_char;
01074 #else
01075   physmem_handle->offset = connection_number + 36;
01076   if (-1 == physmem_handle->write (&write_char, 1))
01077     {
01078       status = CMS_MISC_ERROR;
01079       release_access ();
01080       rcs_print_error
01081         ("GLOBMEM: Error occured while writing to physical memory.\n");
01082       return (-1);
01083     }
01084 #endif
01085   if (split_buffer && read_only)
01086     {
01087       return 0;
01088     }
01089 #ifdef VXWORKS
01090   memcpy (local_locks, base, total_connections);
01091 #else
01092   physmem_handle->offset = 36;
01093   if (-1 == physmem_handle->read (local_locks, total_connections))
01094     {
01095       status = CMS_MISC_ERROR;
01096       release_access ();
01097       rcs_print_error
01098         ("GLOBMEM: Error occured while reading physical memory.\n");
01099       return (-1);
01100     }
01101 #endif
01102   semaphores_clear = 1;
01103   for (int i = 0; i < total_connections; i++)
01104     {
01105       if (0 != local_locks[i])
01106         {
01107           if (i != connection_number &&
01108               !(read_only && local_locks[i] > 1) &&
01109               !(split_buffer && 2 + toggle_bit == local_locks[i]))
01110             {
01111               semaphores_clear = 0;
01112               break;
01113             }
01114         }
01115     }
01116   if (semaphores_clear)
01117     {
01118       return 0;
01119     }
01120 
01121   time = start_time = etime ();
01122   do
01123     {
01124       if (split_buffer)
01125         {
01126           physmem_handle->offset = total_connections + 36;
01127           if (-1 == physmem_handle->read (&toggle_bit, 1))
01128             {
01129               status = CMS_MISC_ERROR;
01130               release_access ();
01131               rcs_print_error
01132                 ("GLOBMEM: Error occured while reading physical memory.\n");
01133               return (-1);
01134             }
01135         }
01136 #ifdef VXWORKS
01137       memcpy (local_locks, base, total_connections);
01138 #else
01139       physmem_handle->offset = 36;
01140       if (-1 == physmem_handle->read (local_locks, total_connections))
01141         {
01142           status = CMS_MISC_ERROR;
01143           release_access ();
01144           rcs_print_error
01145             ("GLOBMEM: Error occured while reading physical memory.\n");
01146           return (-1);
01147         }
01148 #endif
01149       semaphores_clear = 1;
01150       for (int i = 0; i < total_connections; i++)
01151         {
01152           if (0 != local_locks[i])
01153             {
01154               if (i != connection_number &&
01155                   !(read_only && local_locks[i] > 1) &&
01156                   !(split_buffer && 2 + toggle_bit == local_locks[i]))
01157                 {
01158                   semaphores_clear = 0;
01159                   break;
01160                 }
01161             }
01162         }
01163       if (semaphores_clear)
01164         {
01165           return (0);
01166         }
01167       if (fabs (timeout) < SEM_CHECK_TIME_EPSILON)
01168         {
01169           break;
01170         }
01171       if (sem_delay > SEM_DELAY_EPSILON)
01172         {
01173           release_access ();
01174 #ifdef VXWORKS
01175           if (lock_task)
01176             {
01177               taskUnlock ();
01178             }
01179 #endif
01180           esleep (sem_delay);
01181 #ifdef VXWORKS
01182           if (lock_task)
01183             {
01184               taskLock ();
01185             }
01186 #endif
01187           if (min_compatible_version > 2.58 || min_compatible_version < 1E-6)
01188             {
01189               physmem_handle->offset = connection_number + 36;
01190             }
01191           else
01192             {
01193               physmem_handle->offset = connection_number;
01194             }
01195           if (-1 == physmem_handle->write (&write_char, 1))
01196             {
01197               status = CMS_MISC_ERROR;
01198               release_access ();
01199               rcs_print_error
01200                 ("GLOBMEM: Error occured while writing to physical memory.\n");
01201               return (-1);
01202             }
01203         }
01204       time = etime ();
01205     }
01206   while (time - start_time < timeout || timeout < 0);
01207 
01208   status = CMS_TIMED_OUT;
01209   release_access ();
01210   rcs_print_error
01211     ("GLOBMEM: Timed out after %lf seconds waiting for access to %s at %lf.\n",
01212      time - start_time, BufferName, time);
01213   return (-1);
01214 }
01215 
01216 int
01217 GLOBMEM::release_access ()
01218 {
01219   char zero = 0;
01220   if (NULL == physmem_handle)
01221     {
01222       status = CMS_MISC_ERROR;
01223       return (-1);
01224     }
01225 
01226 
01227 
01228 #ifdef VXWORKS
01229   if (lock_bus)
01230     {
01231       return disableBusLock (bl_info);
01232     }
01233 #endif
01234 
01235 #ifdef VXWORKS
01236   if(use_test_and_set)
01237     {
01238       long * tas_address = (long *)
01239         ((char *) physmem_handle->local_address + 36);
01240       *tas_address = 0;
01241       return 0;
01242     }
01243 #endif
01244 
01245   if (split_buffer &&
01246       (internal_access_type == CMS_WRITE_ACCESS ||
01247        internal_access_type == CMS_WRITE_IF_READ_ACCESS) &&
01248       status > 0 && write_just_completed)
01249     {
01250       toggle_bit = !toggle_bit;
01251       if (min_compatible_version > 2.58 || min_compatible_version < 1E-6)
01252         {
01253           physmem_handle->offset = total_connections + 36;
01254         }
01255       else
01256         {
01257           physmem_handle->offset = total_connections;
01258         }
01259       if (-1 == physmem_handle->write (&toggle_bit, 1))
01260         {
01261           rcs_print_error
01262             ("GLOBMEM: Error occured while reading physical memory.\n");
01263           status = CMS_MISC_ERROR;
01264           return (-1);
01265         }
01266     }
01267   if (min_compatible_version > 2.58 || min_compatible_version < 1E-6)
01268     {
01269       physmem_handle->offset = connection_number + 36;
01270     }
01271   else
01272     {
01273       physmem_handle->offset = connection_number;
01274     }
01275   if (-1 == physmem_handle->write (&zero, 1))
01276     {
01277       rcs_print_error
01278         ("GLOBMEM: Error occured while writing to physical memory.\n");
01279       rcs_print_error ("GLOBMEM: Can not release physical memory.\n");
01280       status = CMS_MISC_ERROR;
01281       return (-1);
01282     }
01283 #ifdef VXWORKS
01284   if (lock_task)
01285     {
01286       taskUnlock ();
01287     }
01288 #endif
01289 
01290   return (0);
01291 }
01292 
01293 static unsigned long zero = 0;
01294 static unsigned long one = 0x01010101;
01295 
01296 #ifdef VXWORKS
01297 
01298 int
01299 GLOBMEM::check_if_transfers_complete ()
01300 {
01301   if (!use_dma)
01302     {
01303       return 1;
01304     }
01305   else
01306     {
01307       return checkForDMADone (dma_info);
01308     }
01309 }
01310 
01311 CMS_STATUS
01312 GLOBMEM::write (void *user_data)
01313 {
01314   register char *ptr;
01315   register char current_lock;
01316   register int semaphores_clear;
01317   char was_read_byte = 0;
01318 
01319   if (use_dma)
01320     {
01321       int dma_status = checkForDMADone (dma_info);
01322       double time_diff = 0;
01323       double start_time = 0;
01324       if (timeout > 1e-6)
01325         {
01326           start_time = etime ();
01327         }
01328       while (1 != dma_status)
01329         {
01330           if (dma_status < 0)
01331             {
01332               status = CMS_MISC_ERROR;
01333               return (status);
01334             }
01335           time_diff = etime () - start_time;
01336           if (time_diff >= (timeout / 2))
01337             {
01338               rcs_print_error ("Timed out waiting for DMA Ready!");
01339               status = CMS_TIMED_OUT;
01340               return (status);
01341             }
01342           dma_status = checkForDMADone (dma_info);
01343         }
01344       if (DMAClearScheduledTransfersList (dma_info) < 0)
01345         {
01346           rcs_print_error ("DMAClearScheduledTransfers error.\n");
01347           status = CMS_MISC_ERROR;
01348           return (status);
01349         }
01350 
01351       disable_final_write_raw_for_dma = 1;
01352       if (get_access () < 0)
01353         {
01354           return (status);
01355         }
01356       read_only = 0;
01357       if (split_buffer)
01358         {
01359           toggle_bit = *toggle_bit_address;
01360           if (internal_access_type == CMS_WRITE_IF_READ_ACCESS)
01361             {
01362               if (min_compatible_version > 2.58
01363                   || min_compatible_version < 1e-6)
01364                 {
01365                   physmem_handle->offset = total_connections + 37;
01366                 }
01367               else
01368                 {
01369                   physmem_handle->offset = total_connections + 1;
01370                 }
01371               physmem_handle->read (&was_read_byte, 1);
01372               header.was_read = (was_read_byte == toggle_bit + 1);
01373               if (!header.was_read)
01374                 {
01375                   status = CMS_WRITE_WAS_BLOCKED;
01376                   release_access ();
01377                   return (status);
01378                 }
01379               internal_access_type = CMS_WRITE_ACCESS;
01380             }
01381           if (read_only == toggle_bit)
01382             {
01383               physmem_handle->offset = skip_area;
01384               physmem_handle->size = half_size;
01385             }
01386           else
01387             {
01388               physmem_handle->offset = half_offset;
01389               physmem_handle->size = size;
01390             }
01391         }
01392       else
01393         {
01394           physmem_handle->offset = skip_area;
01395           physmem_handle->size = size;
01396         }
01397       write_raw (user_data);
01398       if (DMAScheduleLocalToVMETransfer
01399           (dma_info,
01400            (void
01401             *) ((unsigned long) (physmem_handle->local_address +
01402                                  physmem_handle->offset +
01403                                  sizeof (CMS_HEADER))), user_data,
01404            header.in_buffer_size) < 0)
01405         {
01406           rcs_print_error ("DMAScheduleLocalToVMETransfer error.");
01407           status = CMS_MISC_ERROR;
01408           return (status);
01409         }
01410       if (split_buffer)
01411         {
01412           toggle_bit = !toggle_bit;
01413           if (toggle_bit)
01414             {
01415               if (DMAScheduleLocalToVMETransfer
01416                   (dma_info, toggle_bit_address, &one, 1) < 0)
01417                 {
01418                   rcs_print_error ("DMAScheduleLocalToVMETransfer error.");
01419                   status = CMS_MISC_ERROR;
01420                   return (status);
01421                 }
01422             }
01423           else
01424             {
01425               if (DMAScheduleLocalToVMETransfer
01426                   (dma_info, toggle_bit_address, &zero, 1) < 0)
01427                 {
01428                   rcs_print_error ("DMAScheduleLocalToVMETransfer error.");
01429                   status = CMS_MISC_ERROR;
01430                   return (status);
01431                 }
01432             }
01433 
01434         }
01435       if (DMAScheduleLocalToVMETransfer (dma_info, my_lock, &zero, 1) < 0)
01436         {
01437           rcs_print_error ("DMAScheduleLocalToVMETransfer error.");
01438           status = CMS_MISC_ERROR;
01439           return (status);
01440         }
01441       if (DMAStartTransfers (dma_info))
01442         {
01443           rcs_print_error ("DMAStartTransfers error.");
01444           status = CMS_MISC_ERROR;
01445           return (status);
01446         }
01447       return (status);
01448     }
01449 
01450   if (fast_mode)
01451     {
01452       if (lock_bus)
01453         {
01454           enableBusLock (bl_info);
01455           toggle_bit = *toggle_bit_address;
01456         }
01457       else
01458         {
01459           *my_lock = 1;
01460           toggle_bit = *toggle_bit_address;
01461 
01462           semaphores_clear = 1;
01463           ptr = (char *) physical_address;
01464           for (; ptr < toggle_bit_address; ptr++)
01465             {
01466               if (0 != (current_lock = *ptr))
01467                 {
01468                   if (ptr != my_lock && !(2 + toggle_bit == current_lock))
01469                     {
01470                       semaphores_clear = 0;
01471                       break;
01472                     }
01473                 }
01474             }
01475           if (!semaphores_clear)
01476             {
01477               *my_lock = 0;
01478               status = CMS_TIMED_OUT;
01479               return (status);
01480             }
01481         }
01482 
01483       if (!toggle_bit)
01484         {
01485           physmem_handle->offset = skip_area;
01486           physmem_handle->size = half_size;
01487         }
01488       else
01489         {
01490           physmem_handle->offset = half_offset;
01491           physmem_handle->size = size;
01492         }
01493 
01494       /* Perform access function. */
01495       write_raw (user_data);
01496 
01497 
01498       if (status > 0)
01499         {
01500           *was_read_address = 0;
01501           *toggle_bit_address = !toggle_bit;
01502         }
01503       if (lock_bus)
01504         {
01505           disableBusLock (bl_info);
01506         }
01507       else
01508         {
01509           *my_lock = 0;
01510         }
01511       if (((int) bsem) > 0 && ((int) bsem) != ERROR)
01512         {
01513           if (OK != semFlush (bsem))
01514             {
01515               rcs_print_error ("semFlush returned ERROR. %d %s\n",
01516                                errno, strerror (errno));
01517             }
01518         }
01519       return (status);
01520     }
01521   internal_access_type = CMS_WRITE_ACCESS;
01522   main_access (user_data);
01523   if (((int) bsem) > 0 && ((int) bsem) != ERROR)
01524     {
01525       if (OK != semFlush (bsem))
01526         {
01527           rcs_print_error ("semFlush returned ERROR. %d %s\n",
01528                            errno, strerror (errno));
01529         }
01530     }
01531   return (status);
01532 }
01533 
01534 
01535 
01536 CMS_STATUS
01537 GLOBMEM::write_if_read (void *user_data)
01538 {
01539   register char *ptr;
01540   register char current_lock;
01541   register int semaphores_clear;
01542   if (fast_mode)
01543     {
01544       if (lock_bus)
01545         {
01546           enableBusLock (bl_info);
01547           toggle_bit = *toggle_bit_address;
01548         }
01549       else
01550         {
01551           *my_lock = 1;
01552           toggle_bit = *toggle_bit_address;
01553 
01554           semaphores_clear = 1;
01555           ptr = (char *) physical_address;
01556           for (; ptr < toggle_bit_address; ptr++)
01557             {
01558               if (0 != (current_lock = *ptr))
01559                 {
01560                   if (ptr != my_lock && !(2 + toggle_bit == current_lock))
01561                     {
01562                       semaphores_clear = 0;
01563                       break;
01564                     }
01565                 }
01566             }
01567           if (!semaphores_clear)
01568             {
01569               *my_lock = 0;
01570               status = CMS_TIMED_OUT;
01571               return (status);
01572             }
01573         }
01574 
01575       if (!toggle_bit)
01576         {
01577           physmem_handle->offset = skip_area;
01578           physmem_handle->size = half_size;
01579         }
01580       else
01581         {
01582           physmem_handle->offset = half_offset;
01583           physmem_handle->size = size;
01584         }
01585 
01586       if (!(*was_read_address))
01587         {
01588           *my_lock = 0;
01589           return (status = CMS_WRITE_WAS_BLOCKED);
01590         }
01591 
01592       /* Perform access function. */
01593       write (user_data);
01594 
01595 
01596       if (status > 0)
01597         {
01598           *was_read_address = 0;
01599           *toggle_bit_address = !toggle_bit;
01600         }
01601       if (lock_bus)
01602         {
01603           disableBusLock (bl_info);
01604         }
01605       else
01606         {
01607           *my_lock = 0;
01608         }
01609       return (status);
01610     }
01611   internal_access_type = CMS_WRITE_IF_READ_ACCESS;
01612   main_access (user_data);
01613   if (((int) bsem) > 0 && ((int) bsem) != ERROR)
01614     {
01615       if (OK != semFlush (bsem))
01616         {
01617           rcs_print_error ("semFlush returned ERROR. %d %s\n",
01618                            errno, strerror (errno));
01619         }
01620     }
01621   return (status);
01622 }
01623 
01624 static int bread_not_implemented_error_printed = 0;
01625 CMS_STATUS
01626 GLOBMEM::blocking_read (double btimeout)
01627 {
01628   if (btimeout < 1e-6 && btimeout > -1e-6)
01629     {
01630       return read ();
01631     }
01632   if (!bread_not_implemented_error_printed)
01633     {
01634       rcs_print_error ("BLOCKING READ NOT IMPLEMENTED FOR GLOBMEM.\n");
01635       bread_not_implemented_error_printed = 1;
01636     }
01637   status = CMS_NO_IMPLEMENTATION_ERROR;
01638 #if 0
01639   register char *ptr;
01640   register char current_lock;
01641   register int semaphores_clear;
01642   if (fast_mode)
01643     {
01644       *my_lock = 4;
01645       *my_lock = 2 + (toggle_bit = *toggle_bit_address);
01646       if (toggle_bit)
01647         {
01648           physmem_handle->offset = skip_area;
01649           physmem_handle->size = half_size;
01650         }
01651       else
01652         {
01653           physmem_handle->offset = half_offset;
01654           physmem_handle->size = size;
01655         }
01656 
01657       /* Perform access function. */
01658       read_raw ();
01659 
01660       *my_lock = 0;
01661       if (status == CMS_READ_OLD && ((int) bsem) > 0 && btimeout > 1e-6
01662           || btimeout < -1e-6)
01663         {
01664           int ticks = (int) (btimeout * sysClkRateGet ());
01665           if (btimeout < 0)
01666             {
01667               ticks = WAIT_FOREVER;
01668             }
01669           if (OK != semTake (bsem, ticks))
01670             {
01671               if (ticks > 0 && errno == S_objLib_OBJ_TIMEOUT)
01672                 {
01673                   status = CMS_TIMED_OUT;
01674                   return (status);
01675                 }
01676               else
01677                 {
01678                   rcs_print_error ("semTake returned ERROR. %d %s",
01679                                    errno, strerror (errno));
01680                   status = CMS_MISC_ERROR;
01681                   return (status);
01682                 }
01683             }
01684           *my_lock = 4;
01685           *my_lock = 2 + (toggle_bit = *toggle_bit_address);
01686           if (toggle_bit)
01687             {
01688               physmem_handle->offset = skip_area;
01689               physmem_handle->size = half_size;
01690             }
01691           else
01692             {
01693               physmem_handle->offset = half_offset;
01694               physmem_handle->size = size;
01695             }
01696 
01697           /* Perform access function. */
01698           read_raw ();
01699 
01700           *my_lock = 0;
01701         }
01702       return (status);
01703     }
01704   internal_access_type = CMS_READ_ACCESS;
01705   main_access (data);
01706   if (status == CMS_READ_OLD && bsem > 0 && btimeout > 1e-6
01707       || btimeout < -1e-6)
01708     {
01709       int ticks = (int) (btimeout * sysClkRateGet ());
01710       if (btimeout < 0)
01711         {
01712           ticks = WAIT_FOREVER;
01713         }
01714       if (OK != semTake (bsem, ticks))
01715         {
01716           if (ticks > 0 && errno == S_objLib_OBJ_TIMEOUT)
01717             {
01718               status = CMS_TIMED_OUT;
01719               return (status);
01720             }
01721           else
01722             {
01723               rcs_print_error ("semTake returned ERROR. %d %s",
01724                                errno, strerror (errno));
01725               status = CMS_MISC_ERROR;
01726               return (status);
01727             }
01728         }
01729       main_access (data);
01730     }
01731 #endif
01732   return (status);
01733 }
01734 
01735 CMS_STATUS
01736 GLOBMEM::read ()
01737 {
01738   if (fast_mode)
01739     {
01740       if (lock_bus)
01741         {
01742           enableBusLock (bl_info);
01743           toggle_bit = *toggle_bit_address;
01744         }
01745       else
01746         {
01747           *my_lock = 4;
01748           *my_lock = 2 + (toggle_bit = *toggle_bit_address);
01749         }
01750 
01751       if (toggle_bit)
01752         {
01753           physmem_handle->offset = skip_area;
01754           physmem_handle->size = half_size;
01755         }
01756       else
01757         {
01758           physmem_handle->offset = half_offset;
01759           physmem_handle->size = size;
01760         }
01761 
01762       /* Perform access function. */
01763       read_raw ();
01764 
01765       if (lock_bus)
01766         {
01767           disableBusLock (bl_info);
01768         }
01769       else
01770         {
01771           *my_lock = 0;
01772         }
01773       return (status);
01774     }
01775   internal_access_type = CMS_READ_ACCESS;
01776   main_access (data);
01777   return (status);
01778 }
01779 
01780 CMS_STATUS
01781 GLOBMEM::peek ()
01782 {
01783   if (fast_mode)
01784     {
01785       if (lock_bus)
01786         {
01787           enableBusLock (bl_info);
01788           toggle_bit = *toggle_bit_address;
01789         }
01790       else
01791         {
01792           *my_lock = 4;
01793           *my_lock = 2 + (toggle_bit = *toggle_bit_address);
01794         }
01795 
01796       if (toggle_bit)
01797         {
01798           physmem_handle->offset = skip_area;
01799           physmem_handle->size = half_size;
01800         }
01801       else
01802         {
01803           physmem_handle->offset = half_offset;
01804           physmem_handle->size = size;
01805         }
01806 
01807       /* Perform access function. */
01808       read_raw ();
01809 
01810       if (lock_bus)
01811         {
01812           disableBusLock (bl_info);
01813         }
01814       else
01815         {
01816           *my_lock = 0;
01817         }
01818       return (status);
01819     }
01820   internal_access_type = CMS_PEEK_ACCESS;
01821   main_access (data);
01822   return (status);
01823 }
01824 
01825 #endif

Generated on Sun Dec 2 15:56:49 2001 for rcslib by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001