[PATCH] Char: correct pci_get_device changes

Commits 881a8c120a and
efe1ec2783 corrects pci device matching in
only one way; it no longer oopses/crashes, despite hotplug is not solved
in these changes.

Whenever pci_find_device -> pci_get_device change is performed, also
pci_dev_get and pci_dev_put should be in most cases called to properly
handle hotplug.  This patch does exactly this thing -- increase refcount
to let kernel know, that we are using this piece of HW just now.

It affects moxa and rio char drivers.

Cc: <R.E.Wolff@BitWizard.nl>
Acked-by: Amit Gud <gud@eth.net>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Jiri Slaby 2006-10-21 10:24:01 -07:00 committed by Linus Torvalds
parent 7b7fc708b5
commit 86fbf1486a
3 changed files with 19 additions and 0 deletions

View File

@ -130,6 +130,7 @@ static moxa_isa_board_conf moxa_isa_boards[] =
typedef struct _moxa_pci_devinfo { typedef struct _moxa_pci_devinfo {
ushort busNum; ushort busNum;
ushort devNum; ushort devNum;
struct pci_dev *pdev;
} moxa_pci_devinfo; } moxa_pci_devinfo;
typedef struct _moxa_board_conf { typedef struct _moxa_board_conf {
@ -324,6 +325,9 @@ static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf
board->busType = MOXA_BUS_TYPE_PCI; board->busType = MOXA_BUS_TYPE_PCI;
board->pciInfo.busNum = p->bus->number; board->pciInfo.busNum = p->bus->number;
board->pciInfo.devNum = p->devfn >> 3; board->pciInfo.devNum = p->devfn >> 3;
board->pciInfo.pdev = p;
/* don't lose the reference in the next pci_get_device iteration */
pci_dev_get(p);
return (0); return (0);
} }
@ -493,6 +497,11 @@ static void __exit moxa_exit(void)
if (tty_unregister_driver(moxaDriver)) if (tty_unregister_driver(moxaDriver))
printk("Couldn't unregister MOXA Intellio family serial driver\n"); printk("Couldn't unregister MOXA Intellio family serial driver\n");
put_tty_driver(moxaDriver); put_tty_driver(moxaDriver);
for (i = 0; i < MAX_BOARDS; i++)
if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI)
pci_dev_put(moxa_boards[i].pciInfo.pdev);
if (verbose) if (verbose)
printk("Done\n"); printk("Done\n");
} }

View File

@ -44,6 +44,7 @@
** the host. ** the host.
*/ */
struct Host { struct Host {
struct pci_dev *pdev;
unsigned char Type; /* RIO_EISA, RIO_MCA, ... */ unsigned char Type; /* RIO_EISA, RIO_MCA, ... */
unsigned char Ivec; /* POLLED or ivec number */ unsigned char Ivec; /* POLLED or ivec number */
unsigned char Mode; /* Control stuff */ unsigned char Mode; /* Control stuff */

View File

@ -1017,6 +1017,10 @@ static int __init rio_init(void)
rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum);
fix_rio_pci(pdev); fix_rio_pci(pdev);
p->RIOHosts[p->RIONumHosts].pdev = pdev;
pci_dev_get(pdev);
p->RIOLastPCISearch = 0; p->RIOLastPCISearch = 0;
p->RIONumHosts++; p->RIONumHosts++;
found++; found++;
@ -1066,6 +1070,9 @@ static int __init rio_init(void)
((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24);
rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum);
p->RIOHosts[p->RIONumHosts].pdev = pdev;
pci_dev_get(pdev);
p->RIOLastPCISearch = 0; p->RIOLastPCISearch = 0;
p->RIONumHosts++; p->RIONumHosts++;
found++; found++;
@ -1181,6 +1188,8 @@ static void __exit rio_exit(void)
} }
/* It is safe/allowed to del_timer a non-active timer */ /* It is safe/allowed to del_timer a non-active timer */
del_timer(&hp->timer); del_timer(&hp->timer);
if (hp->Type == RIO_PCI)
pci_dev_put(hp->pdev);
} }
if (misc_deregister(&rio_fw_device) < 0) { if (misc_deregister(&rio_fw_device) < 0) {