help with PCI drivers

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 would like to see it. I am guessing its the interrupts that are not being released properly.

Thanks,

DB

Code for Interrupt handling----

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 events); interrupting_iface |= (0x1 events); interrupting_iface |= (0x1 events); interrupting_iface |= (0x1 events); interrupting_iface |= (0x1 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 bridge_addr + LSDMA_INTMSK); return IRQ_HANDLED; } return IRQ_NONE; }

Reply to
db
Loading thread data ...

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.