ARPDAS_QNX6 1.0
subbusd.c
Go to the documentation of this file.
00001 #include <errno.h>
00002 #include <stdio.h>
00003 #include <stddef.h>
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #include <unistd.h>
00007 #include <sys/iofunc.h>
00008 #include <sys/dispatch.h>
00009 #include <fcntl.h>
00010 #include <ctype.h>
00011 #include <signal.h>
00012 #include "nortlib.h"
00013 #include "company.h"
00014 #include "subbusd_int.h"
00015 #include "nl_assert.h"
00016 #include "oui.h"
00017 
00018 static resmgr_connect_funcs_t    connect_funcs;
00019 static resmgr_io_funcs_t         io_funcs;
00020 static iofunc_attr_t             attr;
00021 #define DEVNAME "/dev/" COMPANY "/subbus"
00022 
00023 static int SB_Shutdown = 0;
00024 
00025 static int subbus_write(resmgr_context_t *ctp, io_write_t *msg,
00026                RESMGR_OCB_T *ocb) {
00027   SB_Shutdown = 1;
00028   return iofunc_write_default(ctp, msg, ocb);
00029 }
00030 
00031 static int subbus_io_msg(resmgr_context_t *ctp, io_msg_t *msg,
00032                RESMGR_OCB_T *ocb) {
00033   subbusd_req_t sbdmsg;
00034   int nb, nb_exp;
00035   
00036   nb = MsgRead(ctp->rcvid, &sbdmsg, sizeof(sbdmsg), 0);
00037   if ( nb < sizeof(subbusd_req_hdr_t) ||
00038        sbdmsg.sbhdr.iohdr.mgrid != SUBBUSD_MGRID ||
00039        sbdmsg.sbhdr.sb_kw != SB_KW)
00040     return ENOSYS;
00041   /* check the size of the incoming message */
00042   switch ( sbdmsg.sbhdr.command ) {
00043     case SBC_WRITEACK:
00044     case SBC_WRITECACHE:
00045       nb_exp = sizeof(subbusd_req_data0); break;
00046     case SBC_SETCMDENBL:
00047     case SBC_SETCMDSTRB:
00048     case SBC_SETFAIL:
00049     case SBC_READACK:
00050     case SBC_READCACHE:
00051       nb_exp = sizeof(subbusd_req_data1); break;
00052     case SBC_READSW:
00053     case SBC_READFAIL:
00054     case SBC_GETCAPS:
00055     case SBC_TICK:
00056     case SBC_DISARM:
00057       nb_exp = 0; break;
00058     case SBC_QUIT:
00059       SB_Shutdown = 1;
00060       nb_exp = 0; break;
00061     case SBC_INTATT:
00062       nb_exp = sizeof(subbusd_req_data2); break;
00063     case SBC_INTDET:
00064       nb_exp = sizeof(subbusd_req_data3); break;
00065     case SBC_MREAD:
00066       nb_exp = 3*sizeof(unsigned short);
00067       if ( nb >= nb_exp ) {
00068         nl_assert( sbdmsg.data.d4.req_len >= nb_exp );
00069         nb_exp = sbdmsg.data.d4.req_len;
00070       }
00071       break;
00072     default:
00073       return ENOSYS;
00074   }
00075   nb_exp += sizeof(subbusd_req_hdr_t);
00076   if ( nb < nb_exp )
00077     nl_error( 4, "Received short message for command %d: Expected %d received %d",
00078       sbdmsg.sbhdr.command, nb_exp, nb );
00079   incoming_sbreq( ctp->rcvid, &sbdmsg );
00080   return (_RESMGR_NOREPLY);
00081 }
00082 
00083 void sigint_handler( int sig ) {
00084   SB_Shutdown = 1;
00085 }
00086 
00087 int main(int argc, char **argv) {
00088   resmgr_attr_t        resmgr_attr;
00089   dispatch_t           *dpp;
00090   dispatch_context_t   *ctp;
00091   int                  id;
00092 
00093   oui_init_options(argc, argv);
00094   sb_cache_init();
00095 
00096   /* initialize dispatch interface */
00097   if((dpp = dispatch_create()) == NULL) {
00098       nl_error(3,
00099               "%s: Unable to allocate dispatch handle.\n",
00100               argv[0]);
00101       return EXIT_FAILURE;
00102   }
00103 
00104   /* initialize resource manager attributes */
00105   memset(&resmgr_attr, 0, sizeof resmgr_attr);
00106   resmgr_attr.nparts_max = 1;
00107   resmgr_attr.msg_max_size = 2048;
00108 
00109   /* initialize functions for handling messages */
00110   iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs, 
00111                    _RESMGR_IO_NFUNCS, &io_funcs);
00112 
00113   io_funcs.msg = subbus_io_msg;
00114   io_funcs.write = subbus_write; // For Quit only
00115 
00116   /* initialize attribute structure used by the device */
00117   iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);
00118 
00119   /* attach our device name */
00120   id = resmgr_attach(
00121           dpp,            /* dispatch handle        */
00122           &resmgr_attr,   /* resource manager attrs */
00123           DEVNAME,        /* device name            */
00124           _FTYPE_ANY,     /* open type              */
00125           0,              /* flags                  */
00126           &connect_funcs, /* connect routines       */
00127           &io_funcs,      /* I/O routines           */
00128           &attr);         /* handle                 */
00129   if (id == -1)
00130       nl_error( 3, "%s: Unable to attach name.\n", argv[0]);
00131   init_subbus(dpp);
00132   nl_error( 0, "Initialized" );
00133 
00134   signal( SIGINT, sigint_handler );
00135   signal( SIGHUP, sigint_handler );
00136 
00137   /* allocate a context structure */
00138   ctp = dispatch_context_alloc(dpp);
00139 
00140   /* start the resource manager message loop */
00141   while (1) {
00142     if((ctp = dispatch_block(ctp)) == NULL) {
00143       if (errno == EINTR) break;
00144       nl_error( 3, "block error: %s", strerror(errno));
00145       return EXIT_FAILURE;
00146     }
00147     dispatch_handler(ctp);
00148     if (SB_Shutdown == 1 && ctp->resmgr_context.rcvid == 0
00149           && attr.count == 0)
00150       break;
00151   }
00152   nl_error( 0, "Shutting down" );
00153   shutdown_subbus();
00154   return 0;
00155 }
00156 
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines