Re: free free irq and Oops on cat /proc/interrupts (2)

From: Sergey Vlasov
Date: Sat Sep 17 2005 - 14:54:24 EST


On Sat, Sep 17, 2005 at 11:28:39PM +0400, Manu Abraham wrote:
> >Here is the next problem - you must give free_irq() the same pointer
> >that you have passed to request_irq(). So you need a way to get from
> >a struct pci_dev for your device to the corresponding struct
> >mantis_pci. This is done as follows:
> >
> >1) In your mantis_pci_probe(), when you have initialized the device
> >successfully, put the pointer to you data structure into the PCI
> >device structure:
> >
> > pci_set_drvdata(pdev, mantis);
> >
> >2) In mantis_pci_remove() (and later in other PCI driver functions,
> >like suspend/resume) get this pointer back:
> >
> > struct mantis_pci *mantis = pci_get_drvdata(pdev);
> >
> >
> I had already done this ..

Yes...

> >Then use that pointer where you need it (e.g., in free_irq()).

But not this - which is what really causes the problem.

> static void __devexit mantis_pci_remove(struct pci_dev *pdev)
> {
> struct mantis_pci *mantis = pci_get_drvdata(pdev);
> if (mantis == NULL) {
> dprintk(verbose, MANTIS_ERROR, 1, "Aeio, MAntis NULL ptr");
> return;
> }
> dprintk(verbose, MANTIS_ERROR, 1, "Removing -->Mantis irq: %d, \
> latency: %d\n memory: 0x%lx, mmio: 0x%p",
> pdev->irq, mantis->latency, mantis->mantis_addr,
> mantis->mantis_mmio);
>
> free_irq(pdev->irq, pdev);

This should be

free_irq(pdev->irq, mantis);

> // release_mem_region(pci_resource_start(pdev, 0),
> // pci_resource_len(pdev, 0));
> pci_release_regions(pdev);
> pci_set_drvdata(pdev, NULL);
> pci_disable_device(pdev);
> kfree(mantis);
> }

Attachment: pgp00000.pgp
Description: PGP signature