[mpeg2] Re: Porting kfir for kernel 2.6

Anssi Hannula anssi.hannula at gmail.com
Sat Feb 19 13:09:57 CET 2005


Klaus Schmidinger wrote:
> Anssi Hannula wrote:
> 
>> Klaus Schmidinger wrote:
>>
>>> After letting it run for a while suddenly this happened:
>>>
>>> Feb 18 15:19:42 video kernel: irq 5: nobody cared!
>>>
>>> Do you have any idea what might be the problem here?
>>
>> "irq #: nobody cared" is triggered when 99000 of 100000 IRQs are not 
>> handled, e.g. kfir_irq returns IRQ_NONE instead of IRQ_HANDLED. There 
>> was a "return 0" where should've been IRQ_NONE, but AFAIK that 
>> couldn't have been the cause of this error. Try this patch with 
>> debug=1 and test it with 100000+ interrupts. I added some debug 
>> printk's around return IRQ_NONE ("unhandled irq", "was audio irq", 
>> "was video irq").
> 
> Done - log attached.
> 

Try this patch (against kfir-2.6-driver.tar.bz2).

-- 
Anssi Hannula
-------------- next part --------------
--- kfir/driver/kfir.c	2005-02-18 16:40:27.000000000 +0200
+++ kfir-rev3-irq-fix/driver/kfir.c	2005-02-19 14:03:42.000000000 +0200
@@ -1899,161 +1825,141 @@ static void KfProcessGenericModeInterrup
 		// Get int counter once more.
 		kfir->KfState.IntCnt = KfirRegRead(KFIR_ADR_INTERRUPT_CNT);
 	} while (kfir->KfState.OldIntCnt != kfir->KfState.IntCnt);
-	dbprintk(KERN_DEBUG
-		 "kfir: KfProcessGenericModeInterrupt done...\n");
+	dbprintk(KERN_DEBUG "kfir: KfProcessGenericModeInterrupt done...\n");
 	return;
 }
 
 static irqreturn_t kfir_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct kfir_dev *kfir = (struct kfir_dev *) dev_id;
+	struct kfir_dev *kfir = (struct kfir_dev *)dev_id;
 	u32 plxstat;
 	u32 altstat, altmask;
 	u32 val;
-	int count = 0;
 	dbprintk(KERN_DEBUG "kfir: kfir_irq called\n");
 
-	while (1) {
-		plxstat = rplxl(PLX9054_INT_CNTRL_STS);
-		wplxl(PLX9054_INT_CNTRL_STS, plxstat);
-		dbprintk(KERN_DEBUG "kfir: irq_stat=%08x\n", plxstat);
-
-		if (!
-		    (plxstat &
-		     (LOCAL_INT_ACTIVE | DMA0_INT_ACTIVE | (1 << 14))))
-			return 0;
-
-		/* Error on PCI bus ? */
-		if (plxstat & (1 << 14)) {
-			pci_read_config_dword(kfir->pdev, PCI_COMMAND,
-					      &val);
-			if (val & 0xf8000000)
-				pci_write_config_dword(kfir->pdev,
-						       PCI_COMMAND, val);
-		}
-
-		/* Altera Interrupt ? */
-		if (plxstat & LOCAL_INT_ACTIVE) {
-			dbprintk(KERN_DEBUG "kfir: local int\n");
-			altstat = raltl(ALT_ADR_INT_REG_CLR) & 0xff;
-
-			// audio interrupt
-			if (altstat & ALT_D_INT_REQ_CLR_ADSP_INT) {
-				dbprintk(KERN_DEBUG "kfir: ADSP int\n");
-				waltl(ALT_ADR_INT_REG_CLR, altstat);
-
-				altmask = raltl(ALT_ADR_INT_MASK) & 0xFF;
-				// Mask Audio Int.
-				altmask &= ~ALT_D_INT_REQ_CLR_ADSP_INT;
-				waltl(ALT_ADR_INT_MASK, altmask);
-
-				if (kfir->Params.StreamType !=
-				    VT_KFIR_VIDEO_ES) {
-					// nothing for 5E version
-				}
-				KfirRegWrite(KFIR_ADR_AUDIO_INT_ACK, 1);
-			}
-			// video interrupt
-			if (altstat & ALT_D_INT_REQ_CLR_KFIR_INT) {
-				waltl(ALT_ADR_INT_REG_CLR, altstat);
-				if (kfir->mode == KFIR_GENERIC_MODE)
-					KfProcessGenericModeInterrupt
-					    (kfir);
-			}
+	plxstat = rplxl(PLX9054_INT_CNTRL_STS);
+	wplxl(PLX9054_INT_CNTRL_STS, plxstat);
+	dbprintk(KERN_DEBUG "kfir: irq_stat=%08x\n", plxstat);
+
+	if (!(plxstat & (LOCAL_INT_ACTIVE | DMA0_INT_ACTIVE | (1 << 14))))
+		return IRQ_NONE;
+
+	/* Error on PCI bus ? */
+	if (plxstat & (1 << 14)) {
+		pci_read_config_dword(kfir->pdev, PCI_COMMAND, &val);
+		if (val & 0xf8000000)
+			pci_write_config_dword(kfir->pdev, PCI_COMMAND, val);
+	}
+
+	/* Altera Interrupt ? */
+	if (plxstat & LOCAL_INT_ACTIVE) {
+		dbprintk(KERN_DEBUG "kfir: local int\n");
+		altstat = raltl(ALT_ADR_INT_REG_CLR) & 0xff;
+
+		// audio interrupt
+		if (altstat & ALT_D_INT_REQ_CLR_ADSP_INT) {
+			dbprintk(KERN_DEBUG "kfir: ADSP int\n");
+			waltl(ALT_ADR_INT_REG_CLR, altstat);
+
+			altmask = raltl(ALT_ADR_INT_MASK) & 0xFF;
+			// Mask Audio Int.
+			altmask &= ~ALT_D_INT_REQ_CLR_ADSP_INT;
+			waltl(ALT_ADR_INT_MASK, altmask);
+
+/*			if (kfir->Params.StreamType != VT_KFIR_VIDEO_ES) {
+				// nothing for 5E version
+			}*/
+			KfirRegWrite(KFIR_ADR_AUDIO_INT_ACK, 1);
+		}
+		// video interrupt
+		if (altstat & ALT_D_INT_REQ_CLR_KFIR_INT) {
+			waltl(ALT_ADR_INT_REG_CLR, altstat);
+			if (kfir->mode == KFIR_GENERIC_MODE)
+				KfProcessGenericModeInterrupt(kfir);
 		}
+	}
 
-		if (kfir->mode == KFIR_GENERIC_MODE) {
-			// DMA0 interrupt?
-			if (plxstat & DMA0_INT_ACTIVE) {
-				DWORD Data;
-				int free;
-
-				// Clear DMA 0 interrupt.
-				Data = rplxl(PLX9054_DMA_CMD_STS);
-				Data |= DMA0_CLEAR_INT;
-				Data &= ~DMA0_ENABLE;	// disable it.
-				wplxl(PLX9054_DMA_CMD_STS, Data);
-
-				if (kfir->KfState.KfirEReady ==
-				    KFIR_D_EREADY_SEQ_END) {
-				}
-				if (kfir->KfState.KfirEReady ==
-				    KFIR_D_EREADY_READY) {
-					printk(KERN_INFO
-					       "kfir: kfir ready\n");
-					//kfir->recording=0;
-				}
-				if (kfir->recording == 1) {
-					free = kfir->readp - kfir->writep;
-					if (free <= 0)
-						free += MPGBUFSIZE;
-					if (free > MUX_DMA_LENGTH) {
-						memcpy(kfir->mpgbuf +
-						       kfir->writep,
-						       kfir->dmabuf,
-						       MUX_DMA_LENGTH);
-						kfir->writep +=
-						    MUX_DMA_LENGTH;
-						kfir->writep &=
-						    (MPGBUFSIZE - 1);
-						wake_up(&kfir->wq);
+	if (kfir->mode == KFIR_GENERIC_MODE) {
+		// DMA0 interrupt?
+		if (plxstat & DMA0_INT_ACTIVE) {
+			DWORD Data;
+			int free;
+
+			// Clear DMA 0 interrupt.
+			Data = rplxl(PLX9054_DMA_CMD_STS);
+			Data |= DMA0_CLEAR_INT;
+			Data &= ~DMA0_ENABLE;	// disable it.
+			wplxl(PLX9054_DMA_CMD_STS, Data);
+
+/*			if (kfir->KfState.KfirEReady ==
+				KFIR_D_EREADY_SEQ_END) {
+			}*/
+			if (kfir->KfState.KfirEReady == KFIR_D_EREADY_READY) {
+				printk(KERN_INFO "kfir: kfir ready\n");
+				//kfir->recording=0;
+			}
+			if (kfir->recording == 1) {
+				free = kfir->readp - kfir->writep;
+				if (free <= 0)
+					free += MPGBUFSIZE;
+				if (free > MUX_DMA_LENGTH) {
+					memcpy(kfir->mpgbuf + kfir->writep,
+					       kfir->dmabuf, MUX_DMA_LENGTH);
+					kfir->writep += MUX_DMA_LENGTH;
+					kfir->writep &= (MPGBUFSIZE - 1);
+					wake_up(&kfir->wq);
 
-					}	// else we have an overflow!!
+				}	// else we have an overflow!!
+			}
+			if (kfir->recording == 2) {
+				int i;
+				u8 *ptr;
+				u32 val;
+
+				if (kfir->Params.StreamType ==
+				    VT_KFIR_TRANSPORT) {
+					kfir->recording = 0;
+					break;
 				}
-				if (kfir->recording == 2) {
-					int i;
-					u8 *ptr;
-					u32 val;
 
-					if (kfir->Params.StreamType ==
-					    VT_KFIR_TRANSPORT) {
+				for (i = 0; i < MUX_DMA_LENGTH - 3; i++) {
+					ptr = kfir->dmabuf + i;
+					val = ((ptr[0] << 24) |
+					       (ptr[1] << 16) |
+					       (ptr[2] << 8) | ptr[3]);
+
+					if (val == 0x000001b7) {
+						daprintk(KERN_DEBUG
+							 "kfir: end code 1 found at %d\n",
+							 i);
+						//kfir->recording=0;
+						//break;
+					}
+					if (val == 0x000001b9) {
+						daprintk(KERN_DEBUG
+							 "kfir: end code 2 found at %d\n",
+							 i);
 						kfir->recording = 0;
 						break;
 					}
 
-					for (i = 0; i < MUX_DMA_LENGTH - 3;
-					     i++) {
-						ptr = kfir->dmabuf + i;
-						val = ((ptr[0] << 24) |
-						       (ptr[1] << 16) |
-						       (ptr[2] << 8) |
-						       ptr[3]);
-
-						if (val == 0x000001b7) {
-							daprintk(KERN_DEBUG
-								 "kfir: end code 1 found at %d\n",
-								 i);
-							//kfir->recording=0;
-							//break;
-						}
-						if (val == 0x000001b9) {
-							daprintk(KERN_DEBUG
-								 "kfir: end code 2 found at %d\n",
-								 i);
-							kfir->recording =
-							    0;
-							break;
-						}
-
-					}
-
 				}
-				if (kfir->recording)
-					start_dma0(kfir);
 
 			}
+			if (kfir->recording)
+				start_dma0(kfir);
 
 		}
-		if ((++count) > 10) {
-			printk(KERN_INFO "kfir: irq loop\n");
-			wplxl(PLX9054_INT_CNTRL_STS, 0);
-		}
+
 	}
+/*	if ((++count) > 10) {
+		printk(KERN_INFO "kfir: irq loop\n");
+		wplxl(PLX9054_INT_CNTRL_STS, 0);
+	}*/
 	dbprintk(KERN_DEBUG "kfir: kfir_irq done\n");
 	return IRQ_HANDLED;
 }
 
-
 static int init_plx9054(struct kfir_dev *kfir)
 {
 	u32 val;


More information about the mpeg2 mailing list