ARPDAS_QNX6 1.0
hint.c
Go to the documentation of this file.
00001 /* hint.c provides all the interrupt functionality (except the
00002    handler itself.
00003 */
00004 #include <stdlib.h>
00005 #include <errno.h>
00006 #include <sys/neutrino.h>
00007 #include <hw/inout.h>
00008 #include "nortlib.h"
00009 #include "subbus.h"
00010 #include "sc104.h"
00011 
00012 static int expint_iid = -1;
00013 int expint_irq = 9;
00014 
00015 #define MAX_IRQ_104 12
00016 static unsigned short irq104[ MAX_IRQ_104 ] = {
00017   0, 0, 0, 0x21, 0x22, 0x23, 0x24, 0x25, 0, 0x20, 0x26, 0x27
00018 };
00019 
00020 static int read_one_irq( char **s ) {
00021   int ans;
00022   char *t;
00023 
00024   t = *s;
00025   if ( t == 0 || *t == '\0' ) return 0;
00026   ans = strtoul( t, s, 10 );
00027   if ( t == *s ) ans = 0;
00028   if ( **s == ':' ) (*s)++;
00029   return ans;
00030 }
00031 
00032 void process_IRQs( char *t ) {
00033   expint_irq = read_one_irq( &t );
00034   //spare_irq = read_one_irq( &t );
00035   //pfail_irq = read_one_irq( &t );
00036 }
00037 
00038 static int int_init( int irq, unsigned short enable, int bit,
00039            int coid, short code, int value ) {
00040   unsigned short cfg_word, cfg_val, cfg_mask;
00041   int iid;
00042   struct sigevent intr_event;
00043 
00044   if ( irq < 0 || irq >= MAX_IRQ_104 || irq104[ irq ] == 0 )
00045     nl_error( 3, "IRQ %d is invalid", irq );
00046   intr_event.sigev_notify = SIGEV_PULSE;
00047   intr_event.sigev_coid = coid;
00048   intr_event.sigev_priority = SIGEV_PULSE_PRIO_INHERIT;
00049   intr_event.sigev_code = code;
00050   intr_event.sigev_value.sival_int = value;
00051   iid = InterruptAttachEvent(expint_irq, &intr_event,
00052       _NTO_INTR_FLAGS_PROCESS | _NTO_INTR_FLAGS_TRK_MSK );
00053   if (iid == -1)
00054     nl_error( 3, "Unable to attach IRQ %d: errno %d", irq, errno);
00055   else
00056     nl_error( -2, "Interrupt %d attached: coid=%d code=%d val=%d",
00057       irq, coid, code, value );
00058   InterruptUnmask( irq, iid );
00059   if ( subbus_subfunction == SB_SYSCON104 ) {
00060     /* It is theoretically possible to run these cards on a
00061        cable off of an older syscon, so I won't die hard if
00062        this isn't syscon104.
00063     */
00064     cfg_val = irq104[ irq ] & ~0x20;
00065     cfg_val = ( cfg_val << bit ) | enable;
00066     cfg_mask = ( 7 << bit ) | enable;
00067     cfg_word = ( in16( 0x312 ) & ~cfg_mask ) | cfg_val;
00068     nl_error( -2, "SC104 writing CPA word %04X", cfg_word );
00069     out16( 0x312, cfg_word );
00070   }
00071   return iid;
00072 }
00073 
00074 static void int_reset( int iid, unsigned short mask ) {
00075   if ( iid != -1 ) InterruptDetach( iid );
00076   if ( subbus_subfunction == SB_SYSCON104 ) {
00077     unsigned short cfg_word = ( in16( 0x312 ) & ~mask );
00078     out16( 0x312, cfg_word );
00079   }
00080 }
00081 
00082 void expint_init( int coid, short code, int value ) {
00083   expint_iid = int_init( expint_irq, 0x20, 0, coid, code, value );
00084 }
00085 
00086 void expint_reset(void) {
00087   int_reset( expint_iid, 0x3F );
00088 }
00089 
00090 void expint_svc(void) {
00091   service_expint(NULL,0,0,NULL);
00092   InterruptUnmask( expint_irq, expint_iid );
00093 }
00094 
00095 #ifdef IRQ_SUPPORT
00096   static int spare_iid = -1;
00097   static int pfail_iid = -1;
00098   int spare_irq = 0;
00099   int pfail_irq = 0;
00100 
00101   void spare_init( void ) {
00102     spare_iid = int_init( spare_irq, 0x2000, 10, spare_handler );
00103   }
00104 
00105   void spare_reset( void ) {
00106     int_reset( spare_iid, 0x3C00 );
00107   }
00108 
00109   void pfail_init( void ) {
00110     if ( pfail_proxy == 0 ) {
00111       pfail_proxy = qnx_proxy_attach( 0, NULL, 0, -1 );
00112       outp( 0x316, 0); /* reset the lowpower signal */
00113       if ( pfail_proxy == -1 )
00114         nl_error( 3, "Unable to attach proxy for pfail" );
00115       pfail_iid = int_init( pfail_irq, 0x200, 6, pfail_handler );
00116     }
00117   }
00118 
00119   void pfail_reset( void ) {
00120     int_reset( pfail_iid, 0x3C0 );
00121     set_failure(1);
00122     if ( qnx_proxy_detach( pfail_proxy ) ) {
00123       nl_error(1, "Error detaching pfail_proxy");
00124     }
00125     pfail_proxy = 0;
00126   }
00127 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines