From: viro@parcelfarce.linux.theplanet.co.uk parport_gsc.c turned into proper parisc driver; instead of scanning the list of ports upon rmmod in search of ones that had been created by us, we do cleanup where it belongs - in parisc driver ->remove(). --- 25-akpm/drivers/parport/parport_gsc.c | 50 ++++++++++++++++++---------------- 1 files changed, 27 insertions(+), 23 deletions(-) diff -puN drivers/parport/parport_gsc.c~PP3-parport_gsc-RC1 drivers/parport/parport_gsc.c --- 25/drivers/parport/parport_gsc.c~PP3-parport_gsc-RC1 Wed Jan 14 13:50:49 2004 +++ 25-akpm/drivers/parport/parport_gsc.c Wed Jan 14 13:50:49 2004 @@ -445,6 +445,7 @@ static int __initdata parport_count; static int __devinit parport_init_chip(struct parisc_device *dev) { + struct parport *p; unsigned long port; if (!dev->irq) { @@ -467,13 +468,36 @@ static int __devinit parport_init_chip(s printk("%s: enhanced parport-modes not supported.\n", __FUNCTION__); } - if (parport_gsc_probe_port(port, 0, dev->irq, - /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, NULL)) + p = parport_gsc_probe_port(port, 0, dev->irq, + /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, NULL); + if (p) parport_count++; + dev->dev.driver_data = p; return 0; } +static void __devexit parport_remove_chip(struct parisc_device *dev) +{ + struct parport *p = dev->dev.driver_data; + if (p) { + struct parport_gsc_private *priv = p->private_data; + struct parport_operations *ops = p->ops; + if (p->dma != PARPORT_DMA_NONE) + free_dma(p->dma); + if (p->irq != PARPORT_IRQ_NONE) + free_irq(p->irq, p); + parport_proc_unregister(p); + if (priv->dma_buf) + pci_free_consistent(priv->dev, PAGE_SIZE, + priv->dma_buf, + priv->dma_handle); + kfree (p->private_data); + parport_unregister_port(p); + kfree (ops); /* hope no-one cached it */ + } +} + static struct parisc_device_id parport_tbl[] = { { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x74 }, { 0, } @@ -485,6 +509,7 @@ static struct parisc_driver parport_driv .name = "Parallel", .id_table = parport_tbl, .probe = parport_init_chip, + .remove = parport_remove_chip, }; int __devinit parport_gsc_init(void) @@ -494,27 +519,6 @@ int __devinit parport_gsc_init(void) static void __devexit parport_gsc_exit(void) { - struct parport *p = parport_enumerate(), *tmp; - while (p) { - tmp = p->next; - if (p->modes & PARPORT_MODE_PCSPP) { - struct parport_gsc_private *priv = p->private_data; - struct parport_operations *ops = p->ops; - if (p->dma != PARPORT_DMA_NONE) - free_dma(p->dma); - if (p->irq != PARPORT_IRQ_NONE) - free_irq(p->irq, p); - parport_proc_unregister(p); - if (priv->dma_buf) - pci_free_consistent(priv->dev, PAGE_SIZE, - priv->dma_buf, - priv->dma_handle); - kfree (p->private_data); - parport_unregister_port(p); - kfree (ops); /* hope no-one cached it */ - } - p = tmp; - } unregister_parisc_driver(&parport_driver); } _