help with DVB driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello all,

I have a linux driver for a 4-input DVB card. I have two other ASI
cards that transmit data and the 4 receivers of DVB card receive the
data. When I make the driver, it installs fine. dmesg shows everything
alright. The test applications run perfectly okay too. After that, I
tried testing the driver. So, I stopped and started the transmitters
and receivers several times. After certain attempts (no pattern really)
to stop and start, the machine completely freezes. I have to manually
power the machine down. But, when I use only one ASI card (one
transmitter and two receivers on the DVB card), it all works fine.  I
am running Fedora Core 4.

Can anyone help me debug the code? Or else, at least, shed some light
on the debugging side of it. Any help is appreciated. I can post the
driver code as well if anyone likes to see it. I am guessing its
the interrupts that are not being released properly.

Please find the interrupt request code in here and let me know if there's anything unusual that you experts may find.

static irqreturn_t
dvbm_qlf_irq_handler (int irq,
   void *dev_id,
   struct pt_regs *regs)
{
   int i;
   struct master_dev *card = dev_id;
   struct list_head *p = &card->iface_list;
   struct master_iface *iface;
   unsigned int dmaintsrc = readl (card->bridge_addr + LSDMA_INTSRC);
   unsigned int status, interrupting_iface = 0;

   for (i = 0; i < 4; i++) {
       p = p->next;

       iface = list_entry (p, struct master_iface, list);


       /* Check and Clear ASI interrupts */
       spin_lock (&card->irq_lock);
       status = readl (card->core_addr + DVBM_QLF_ICSR(i));

       if ((status & DVBM_QLF_ICSR_ISMASK) != 0) {
           writel (status, card->core_addr + DVBM_QLF_ICSR(i));

           if (status & DVBM_QLF_ICSR_RXCDIS) {
               set_bit (ASI_EVENT_RX_CARRIER_ORDER, &iface->events);
               interrupting_iface |= (0x1 << i);
           }
           if (status & DVBM_QLF_ICSR_RXAOSIS) {
               set_bit (ASI_EVENT_RX_AOS_ORDER, &iface->events);
               interrupting_iface |= (0x1 << i);
           }
           if (status & DVBM_QLF_ICSR_RXLOSIS) {
               set_bit (ASI_EVENT_RX_LOS_ORDER, &iface->events);
               interrupting_iface |= (0x1 << i);
           }
           if (status & DVBM_QLF_ICSR_RXOIS) {
               set_bit (ASI_EVENT_RX_FIFO_ORDER, &iface->events);
               interrupting_iface |= (0x1 << i);
           }
           if (status & DVBM_QLF_ICSR_RXDIS) {
               set_bit (ASI_EVENT_RX_DATA_ORDER, &iface->events);
               interrupting_iface |= (0x1 << i);
           }
       }

       spin_unlock (&card->irq_lock);

       /* Check and Clear DMA interrupts */
       if (dmaintsrc & LSDMA_INTSRC_CH(i)) {

           /* Read the interrupt type and clear it */
           spin_lock (&card->irq_lock);
           status = readl (card->bridge_addr + LSDMA_CSR(i));
           writel (status, card->bridge_addr + LSDMA_CSR(i));
           spin_unlock (&card->irq_lock);

           /* Increment the buffer pointer */
           if (status & LSDMA_CH_CSR_INTSRCBUFFER) {
               lsdma_advance (iface->dma);
               if (lsdma_rx_isempty (iface->dma)) {
                   set_bit (ASI_EVENT_RX_BUFFER_ORDER, &iface->events);
               }
           }

           /* Flag end-of-chain */
           if (status & LSDMA_CH_CSR_INTSRCDONE) {
               set_bit (0, &iface->dma_done);
           }

           /* Flag DMA abort */
           if (status & LSDMA_CH_CSR_INTSRCSTOP) {
               set_bit (0, &iface->dma_done);
           }

           interrupting_iface |= (0x1 << i);
       }


       if (interrupting_iface & (0x1 << i)) {
           wake_up (&iface->queue);
       }
   }

   if (interrupting_iface) {
       /* Dummy read to flush PCI posted writes */
       readl (card->bridge_addr + LSDMA_INTMSK);
       return IRQ_HANDLED;
   }
   return IRQ_NONE;
}

Thanks a lot,

DB





_______________________________________________

linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux