Ignore:
Timestamp:
Mar 3, 2011, 8:59:04 PM (14 years ago)
Author:
David Azarewicz
Message:

interrupt fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • GPL/branches/uniaud32-2.1.x/lib32/irq.c

    r519 r546  
    4545
    4646static IRQ_SLOT         arSlots[MAX_IRQ_SLOTS] = { 0 };
    47 static ULONG           eoiIrq[255] = {0};
     47static ULONG               eoiIrq[255] = {0};
    4848
    4949
     
    5252static IRQ_SLOT *FindSlot(unsigned irq)
    5353{
    54     IRQ_SLOT      *pSlot;
    55 
    56     for( pSlot = arSlots; pSlot != &arSlots[MAX_IRQ_SLOTS]; pSlot++ )
    57     {
    58         if( pSlot->irqNo == irq )   return pSlot;
    59     }
    60 
    61     return NULL;
     54        IRQ_SLOT          *pSlot;
     55
     56        for( pSlot = arSlots; pSlot != &arSlots[MAX_IRQ_SLOTS]; pSlot++ )
     57        {
     58                if( pSlot->irqNo == irq )       return pSlot;
     59        }
     60
     61        return NULL;
    6262}
    6363
     
    6767
    6868int request_irq(unsigned irq, irq_handler_t handler,
    69                     unsigned long x0, const char *x1, void *x2)
    70 {
    71     IRQ_SLOT    *pSlot = FindSlot(irq & 0xff);
    72     unsigned    u, uSlotNo = (unsigned)-1;
    73     if( !pSlot )
    74     {
    75         // find empty slot
    76         for( uSlotNo = 0; uSlotNo < MAX_IRQ_SLOTS; uSlotNo++ )
    77         {
    78             if( arSlots[uSlotNo].flHandlers == 0 )
    79             {
    80                 pSlot = &arSlots[uSlotNo];      break;
    81             }
    82         }
    83 
    84     }
    85 
    86     if( pSlot )
    87     {
    88         if(RMRequestIRQ(/*hResMgr,*/ irq , (x0 & SA_SHIRQ) != 0) == FALSE) {
    89             rprintf(("RMRequestIRQ failed for irq %d", irq));
    90             //  return 0;
    91         }
    92 
    93         for( u = 0; u < MAX_SHAREDIRQS; u++ )
    94         {
    95             if( pSlot->irqHandlers[u].handler == NULL )
    96             {
    97                 pSlot->irqNo = irq & 0xff;
    98                 pSlot->irqHandlers[u].handler = handler;
    99                 pSlot->irqHandlers[u].x0 = x0;
    100                 pSlot->irqHandlers[u].x1 = (char *)x1;
    101                 pSlot->irqHandlers[u].x2 = x2;
    102 
    103                 if( pSlot->flHandlers != 0 ||
    104                    ALSA_SetIrq( irq & 0xff, uSlotNo, (x0 & SA_SHIRQ) != 0) )
    105                 {
    106                     pSlot->flHandlers |= 1 << u;
    107                     return 0;
    108                 }
    109 
    110                 break;
    111             }
    112         }
    113     }
    114 
    115     rprintf(("request_irq: Unable to register irq handler for irq %d\n", irq & 0xff ));
    116     return 1;
     69                        unsigned long ulSharedFlag, const char *pchName, void *pUserData)
     70{
     71        IRQ_SLOT        *pSlot = FindSlot(irq & 0xff);
     72        unsigned        u, uSlotNo = (unsigned)-1;
     73        ULONG hRes;
     74
     75        dprintf(("request_irq: Enter for irq %d", irq & 0xff ));
     76        if ( !pSlot ) {
     77                // find empty slot
     78                for( uSlotNo = 0; uSlotNo < MAX_IRQ_SLOTS; uSlotNo++ ) {
     79                        if( arSlots[uSlotNo].flHandlers == 0 ) {
     80                                pSlot = &arSlots[uSlotNo];
     81                                break;
     82                        }
     83                }
     84        }
     85
     86        if ( pSlot ) {
     87                hRes = NULL;
     88                if (RMRequestIRQ(irq, (ulSharedFlag & SA_SHIRQ) != 0, &hRes) == FALSE) {
     89                        rprintf(("RMRequestIRQ failed for irq %d", irq));
     90                        //      return 0;
     91                }
     92                pSlot->irqNo = irq & 0xff;
     93                pSlot->hRes = hRes;
     94
     95                for ( u = 0; u < MAX_SHAREDIRQS; u++ ) {
     96                        if ( pSlot->irqHandlers[u].handler == NULL ) {
     97                                pSlot->irqHandlers[u].handler = handler;
     98                                pSlot->irqHandlers[u].x0 = ulSharedFlag;
     99                                pSlot->irqHandlers[u].x1 = (char *)pchName;
     100                                pSlot->irqHandlers[u].x2 = pUserData;
     101
     102                                if( pSlot->flHandlers != 0 || ALSA_SetIrq( irq & 0xff, uSlotNo, (ulSharedFlag & SA_SHIRQ) != 0) ) {
     103                                        pSlot->flHandlers |= 1 << u;
     104                                        return 0;
     105                                }
     106
     107                                break;
     108                        }
     109                }
     110        }
     111
     112        rprintf(("request_irq: Unable to register irq handler for irq %d", irq & 0xff ));
     113        return 1;
    117114}
    118115
     
    122119void free_irq(unsigned int irq, void *userdata)
    123120{
    124     unsigned    u;
    125     IRQ_SLOT    *pSlot;
    126 
    127     if( (pSlot = FindSlot(irq)) != NULL )
    128     {
    129         for( u = 0; u < MAX_SHAREDIRQS; u++ )
    130         {
    131             if( pSlot->irqHandlers[u].x2 == userdata )
    132             {
    133                 pSlot->flHandlers &= ~(1 << u);
    134                 if( pSlot->flHandlers == 0 )
    135                 {
    136                     ALSA_FreeIrq(pSlot->irqNo);
    137                     pSlot->irqNo = 0;
    138                     //    pSlot->fEOI = 0;
    139                 }
    140 
    141                 pSlot->irqHandlers[u].handler = NULL;
    142                 pSlot->irqHandlers[u].x0 = 0;
    143                 pSlot->irqHandlers[u].x1 = NULL;
    144                 pSlot->irqHandlers[u].x2 = NULL;
    145 
    146                 return;
    147 
    148             }
    149         }
    150     }
     121        unsigned        u;
     122        IRQ_SLOT        *pSlot;
     123
     124        if( (pSlot = FindSlot(irq&0xff)) != NULL ) {
     125                for( u = 0; u < MAX_SHAREDIRQS; u++ ) {
     126                        if( pSlot->irqHandlers[u].x2 == userdata ) {
     127                                pSlot->flHandlers &= ~(1 << u);
     128                                if( pSlot->flHandlers == 0 ) {
     129                                        dprintf(("free_irq: irq %d", irq & 0xff ));
     130                                        ALSA_FreeIrq(pSlot->irqNo);
     131                                        pSlot->irqNo = 0;
     132                                        RMDeallocateIRQ(pSlot->hRes);
     133                                        pSlot->hRes = NULL;
     134                                        // pSlot->fEOI = 0;
     135                                }
     136
     137                                pSlot->irqHandlers[u].handler = NULL;
     138                                pSlot->irqHandlers[u].x0 = 0;
     139                                pSlot->irqHandlers[u].x1 = NULL;
     140                                pSlot->irqHandlers[u].x2 = NULL;
     141
     142                                return;
     143
     144                        }
     145                }
     146        }
    151147}
    152148
     
    156152void eoi_irq(unsigned int irq)
    157153{
    158     /*(void)irq; */
    159     /*
    160     IRQ_SLOT   *pSlot = FindSlot(irq);
    161 
    162     if( pSlot )        pSlot->fEOI = 1;
    163     */
    164     eoiIrq[irq & 0xff]++;
     154        /*(void)irq; */
     155        /*
     156        IRQ_SLOT       *pSlot = FindSlot(irq);
     157
     158        if( pSlot )    pSlot->fEOI = 1;
     159        */
     160        eoiIrq[irq & 0xff]++;
    165161}
    166162
     
    170166BOOL process_interrupt(ULONG ulSlotNo, ULONG *pulIrq)
    171167{
    172     unsigned    u;
    173     int rc;
    174     IRQ_SLOT    *pSlot;
     168        unsigned        u;
     169        int rc;
     170        IRQ_SLOT        *pSlot;
    175171
    176172        //dprintf(("enter int proc %d %d",ulSlotNo, *pulIrq));
    177173
    178     if(fSuspended)
    179     {//If our device is suspended, then we can't receive interrupts, so it must
    180         //be for some other device
    181         //Don't pass it to the linux handler as the device doesn't respond as expected
    182         //when suspended
    183         dprintf(("Slot %d IRQ %d suspended",ulSlotNo, *pulIrq));
    184         return FALSE;
    185     }
    186 
    187     if( ulSlotNo < MAX_IRQ_SLOTS )
    188     {
    189         pSlot = &arSlots[ulSlotNo];
    190 
    191         for( u = 0; u < MAX_SHAREDIRQS; u++ )
    192         {
    193             if(pSlot && pSlot->irqHandlers[u].handler )
    194             {
    195                 fInInterrupt = TRUE;
     174        if(fSuspended)
     175        {//If our device is suspended, then we can't receive interrupts, so it must
     176                //be for some other device
     177                //Don't pass it to the linux handler as the device doesn't respond as expected
     178                //when suspended
     179                dprintf(("Slot %d IRQ %d suspended",ulSlotNo, *pulIrq));
     180                return FALSE;
     181        }
     182
     183        if( ulSlotNo < MAX_IRQ_SLOTS )
     184        {
     185                pSlot = &arSlots[ulSlotNo];
     186
     187                for( u = 0; u < MAX_SHAREDIRQS; u++ )
     188                {
     189                        if(pSlot && pSlot->irqHandlers[u].handler )
     190                        {
     191                                fInInterrupt = TRUE;
    196192#if 0
    197                 rc = pSlot->irqHandlers[u].handler(pSlot->irqNo,
    198                                                    pSlot->irqHandlers[u].x2, 0);
     193                                rc = pSlot->irqHandlers[u].handler(pSlot->irqNo,
     194                                                                                                   pSlot->irqHandlers[u].x2, 0);
    199195#else
    200                 rc = pSlot->irqHandlers[u].handler(pSlot->irqNo,
    201                                                    pSlot->irqHandlers[u].x2);
     196                                rc = pSlot->irqHandlers[u].handler(pSlot->irqNo,
     197                                                                                                   pSlot->irqHandlers[u].x2);
    202198#endif
    203199
    204                 // HDA Hardware generates controller interrupts and stream interrupts
    205                 // the uniaud16 driver only cares about stream interrupts.
    206                 // azx_interrupt in alsa-kernel/pci/hda/hda_intel.c will return rc 2 if
    207                 // the interrupt is from the  controller. There is no need to call uniaud16
     200                                // HDA Hardware generates controller interrupts and stream interrupts
     201                                // the uniaud16 driver only cares about stream interrupts.
     202                                // azx_interrupt in alsa-kernel/pci/hda/hda_intel.c will return rc 2 if
     203                                // the interrupt is from the  controller. There is no need to call uniaud16
    208204                                // for these interrupts
    209                 if ( rc == 2 ) {
    210                     fInInterrupt = FALSE;
    211                     *pulIrq = pSlot->irqNo;
    212                     eoiIrq[pSlot->irqNo] = 0;
    213                     return TRUE;
    214                 }
    215 
    216                 if (rc == 1) eoi_irq(pSlot->irqNo);
    217                 rc = (eoiIrq[pSlot->irqNo] > 0);
    218                 fInInterrupt = FALSE;
    219 
    220                 if( rc /*== 1 || pSlot->fEOI*/ ) {
    221 
    222                     *pulIrq = pSlot->irqNo;
    223                     //      pSlot->fEOI = 0;
    224 
    225                     //ok, this interrupt was intended for us; notify the 16 bits MMPM/2 driver
    226                     OSS32_ProcessIRQ();
     205                                if ( rc == 2 ) {
     206                                        fInInterrupt = FALSE;
     207                                        *pulIrq = pSlot->irqNo;
     208                                        eoiIrq[pSlot->irqNo] = 0;
     209                                        return TRUE;
     210                                }
     211
     212                                if (rc == 1) eoi_irq(pSlot->irqNo);
     213                                rc = (eoiIrq[pSlot->irqNo] > 0);
     214                                fInInterrupt = FALSE;
     215
     216                                if( rc /*== 1 || pSlot->fEOI*/ ) {
     217
     218                                        *pulIrq = pSlot->irqNo;
     219                                        //              pSlot->fEOI = 0;
     220
     221                                        //ok, this interrupt was intended for us; notify the 16 bits MMPM/2 driver
     222                                        OSS32_ProcessIRQ();
    227223                                        //dprintf(("exit(1) int proc %d %d",ulSlotNo, *pulIrq));
    228                     eoiIrq[pSlot->irqNo] = 0;
    229                     return TRUE;
    230                 }
    231             }
    232         }
    233     }
     224                                        eoiIrq[pSlot->irqNo] = 0;
     225                                        return TRUE;
     226                                }
     227                        }
     228                }
     229        }
    234230        //dprintf(("exit(0) int proc %d %d",ulSlotNo, *pulIrq));
    235231
    236     return FALSE;
     232        return FALSE;
    237233}
    238234
     
    242238int in_interrupt()
    243239{
    244     return fInInterrupt;
     240        return fInInterrupt;
    245241}
    246242
     
    250246void disable_irq(int irq)
    251247{
    252     dprintf(("disable_irq %d NOT implemented", irq));
    253 }
    254 
    255 //******************************************************************************
    256 //******************************************************************************
    257 
     248        dprintf(("disable_irq %d NOT implemented", irq));
     249}
     250
     251//******************************************************************************
     252//******************************************************************************
     253
Note: See TracChangeset for help on using the changeset viewer.