Hi,
On Thu, 16 Sep 2004 at 13:17, Pawlowski Julian wrote:
> Everytime I try to unload the HFC module with "modprobe -r" I got
a
> kernel panic and the complete server hangs up so I need to do a hard
> reset.
I had the same problem here. It seemed to happen especially when the
HFC-card shares an IRQ line with other devices (network card and sound
card in my case).
Please try the attached patch. It shuts down the card and it's
interrupt handler more cleanly, and fixed the problem for me.
cu
Reinhard
-------------- next part --------------
--- zaphfc.c
+++ zaphfc.c
@@ -80,15 +80,31 @@
spin_lock_irqsave(&hfctmp->lock,flags);
printk(KERN_INFO "zaphfc: shutting down card at
%p.\n",hfctmp->pci_io);
+
+ /* Clear interrupt mask */
hfctmp->regs.int_m2 = 0;
hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
+ /* Reset pending interrupts */
+ hfc_inb(hfctmp, hfc_INT_S1);
+
+ /* Wait for interrupts that might still be pending */
+ spin_unlock_irqrestore(&hfctmp->lock, flags);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout((30 * HZ) / 1000); // wait 30 ms
+ spin_lock_irqsave(&hfctmp->lock,flags);
+
+ /* Remove interrupt handler */
+ free_irq(hfc_dev_list->irq, hfc_dev_list);
+ /* Soft-reset the card */
hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET); // softreset on
-// set_current_state(TASK_UNINTERRUPTIBLE);
-// schedule_timeout((30 * HZ) / 1000); // wait 30 ms
- udelay(30);
+ spin_unlock_irqrestore(&hfctmp->lock, flags);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout((30 * HZ) / 1000); // wait 30 ms
+ spin_lock_irqsave(&hfctmp->lock,flags);
+
hfc_outb(hfctmp,hfc_CIRM,0); // softreset off
pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, 0); // disable memio
and bustmaster
@@ -97,6 +113,7 @@
kfree(hfctmp->fifomem);
}
iounmap((void *) hfctmp->pci_io);
+ hfctmp->pci_io = NULL;
if (hfctmp->pcidev != NULL) {
pci_disable_device(hfctmp->pcidev);
}
@@ -105,7 +122,6 @@
kfree(hfctmp->ztdev);
printk(KERN_INFO "unregistered from zaptel.\n");
}
- free_irq(hfc_dev_list->irq, hfc_dev_list);
spin_unlock_irqrestore(&hfctmp->lock,flags);
}
@@ -556,6 +572,12 @@
#endif
}
+ if (!hfctmp->pci_io) {
+ printk(KERN_WARNING "%s: IO-mem disabled, cannot handle
interrupt\n",
+ __FUNCTION__);
+ return IRQ_NONE;
+ }
+
spin_lock_irqsave(&hfctmp->lock, flags);
stat = hfc_inb(hfctmp, hfc_STATUS);
if ((stat & hfc_STATUS_ANYINT) == 0) {