ARPDAS_QNX6 1.0
interrupt.c
Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <string.h>
00003 #include <errno.h>
00004 #include "subbusd_int.h"
00005 #include "sc104.h"
00006 #include "nl_assert.h"
00007 
00008 int service_expint( message_context_t * ctp, int code,
00009                      unsigned flags, void * handle ) {
00010   int i, bitno, bit;
00011   unsigned short mask;
00012 
00013   for ( i = 0; i < MAX_REGIONS && regions[i].address != 0; i++ ) {
00014     if ( regions[i].bits != 0 ) {
00015       mask = sbrb( regions[i].address ) & regions[i].bits;
00016       for ( bitno = 0, bit = 1; i < 7 && mask; bitno++, bit <<= 1 ) {
00017         if ( mask & bit ) {
00018           card_def *cd = regions[i].def[bitno];
00019           if (cd != NULL) {
00020             int rv = MsgDeliverEvent( cd->owner, &cd->event );
00021             unsigned short addr;
00022             unsigned int bn;
00023             if ( rv == -1 ) {
00024               switch (errno) {
00025                 case EBADF:
00026                 case ESRCH:
00027                   nl_error( 1,
00028                     "Process attached to '%s' interrupt not found",
00029                     cd->cardID );
00030                   rv = expint_detach( cd->owner, cd->cardID, &addr, &bn );
00031                   nl_assert( rv == EOK );
00032                   nl_assert( bitno == bn );
00033                   break;
00034                 default:
00035                   nl_error( 4, "Unexpected error %d from MsgDeliverEvent: %s",
00036                       errno, strerror(errno));
00037               }
00038             } else {
00039               nl_error(-2, "Interrupt delivered" );
00040             }
00041           } else nl_error( 2, "Unexpected interrupt in service_expint()");
00042           mask &= ~bit;
00043         }
00044       }
00045     }
00046   }
00047   return 0;
00048 }
00049 
00050 int int_attach(int rcvid, subbusd_req_t *req) {
00051   card_def *cd;
00052   subbusd_req_data2 *ireq = &req->data.d2;
00053   int rv;
00054   
00055   if ( ireq->region != 0x40 ) {
00056     nl_error( 2, "Requested interrupt region incompatible with hardware." );
00057     return EADDRNOTAVAIL;
00058   }
00059   rv = expint_attach( rcvid, ireq->cardID, ireq->address, ireq->region,
00060           &ireq->event, &cd );
00061   if ( rv != 0 ) return rv;
00062 
00063   /* Now program the card! */
00064   { unsigned short prog;
00065     prog = ( (ireq->region & 6) << 2 ) | 0x20 | cd->bitno;
00066     if ( sbwra( cd->address, 0 )    == 0 ||
00067          sbwra( cd->address, prog ) == 0 )
00068       nl_error( 1, "No acknowledge programming %s(0x%03X)",
00069         cd->cardID, cd->address );
00070     else nl_error( -2, "Card %s assigned bit %d", cd->cardID,
00071           cd->bitno );
00072   }
00073   service_expint(NULL,0,0,NULL);
00074 
00075   return EOK;
00076 }
00077 
00078 int int_detach(int rcvid, subbusd_req_t *req) {
00079   subbusd_req_data2 *ireq = &req->data.d2;
00080   unsigned short addr;
00081   unsigned int bn;
00082   int rv = expint_detach( rcvid, ireq->cardID, &addr, &bn );
00083   if (rv != 0) return rv;
00084   if ( sbwra( addr, 0 ) == 0 )
00085     nl_error( 1, "No acknowledge unprogramming %s (0x%03X)",
00086       ireq->cardID, addr );
00087   return EOK;
00088 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines