Commit e0698e4f authored by Chas Williams's avatar Chas Williams Committed by David S. Miller

[ATM]: fore200e: rewrite to eliminate pci_find_device() but preserve sbus support

this patch correctly removes the pci_find_device() used by the fore200e
driver.  the __init/__exit remains a bit clunky since we need to preserve
sbus support.
Signed-off-by: default avatarChas Williams <chas@cmf.nrl.navy.mil>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8ee8110e
......@@ -114,7 +114,7 @@
static const struct atmdev_ops fore200e_ops;
static const struct fore200e_bus fore200e_bus[];
static struct fore200e* fore200e_boards = NULL;
static LIST_HEAD(fore200e_boards);
MODULE_AUTHOR("Christophe Lizzi - credits to Uwe Dannowski and Heikki Vatiainen");
......@@ -637,39 +637,6 @@ fore200e_pca_configure(struct fore200e* fore200e)
}
static struct fore200e* __init
fore200e_pca_detect(const struct fore200e_bus* bus, int index)
{
struct fore200e* fore200e;
struct pci_dev* pci_dev = NULL;
int count = index;
do {
pci_dev = pci_find_device(PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, pci_dev);
if (pci_dev == NULL)
return NULL;
} while (count--);
if (pci_enable_device(pci_dev))
return NULL;
fore200e = fore200e_kmalloc(sizeof(struct fore200e), GFP_KERNEL);
if (fore200e == NULL)
return NULL;
fore200e->bus = bus;
fore200e->bus_dev = pci_dev;
fore200e->irq = pci_dev->irq;
fore200e->phys_base = pci_resource_start(pci_dev, 0);
sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1);
pci_set_master(pci_dev);
return fore200e;
}
static int __init
fore200e_pca_prom_read(struct fore200e* fore200e, struct prom_data* prom)
{
......@@ -2768,20 +2735,107 @@ fore200e_init(struct fore200e* fore200e)
return 0;
}
static int __devinit
fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
{
const struct fore200e_bus* bus = (struct fore200e_bus*) pci_ent->driver_data;
struct fore200e* fore200e;
int err = 0;
static int index = 0;
if (pci_enable_device(pci_dev)) {
err = -EINVAL;
goto out;
}
fore200e = fore200e_kmalloc(sizeof(struct fore200e), GFP_KERNEL);
if (fore200e == NULL) {
err = -ENOMEM;
goto out_disable;
}
fore200e->bus = bus;
fore200e->bus_dev = pci_dev;
fore200e->irq = pci_dev->irq;
fore200e->phys_base = pci_resource_start(pci_dev, 0);
sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1);
pci_set_master(pci_dev);
printk(FORE200E "device %s found at 0x%lx, IRQ %s\n",
fore200e->bus->model_name,
fore200e->phys_base, fore200e_irq_itoa(fore200e->irq));
sprintf(fore200e->name, "%s-%d", bus->model_name, index);
err = fore200e_init(fore200e);
if (err < 0) {
fore200e_shutdown(fore200e);
goto out_free;
}
++index;
pci_set_drvdata(pci_dev, fore200e);
out:
return err;
out_free:
kfree(fore200e);
out_disable:
pci_disable_device(pci_dev);
goto out;
}
static void __devexit fore200e_pca_remove_one(struct pci_dev *pci_dev)
{
struct fore200e *fore200e;
fore200e = pci_get_drvdata(pci_dev);
list_del(&fore200e->entry);
fore200e_shutdown(fore200e);
kfree(fore200e);
pci_disable_device(pci_dev);
}
#ifdef CONFIG_ATM_FORE200E_PCA
static struct pci_device_id fore200e_pca_tbl[] = {
{ PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, PCI_ANY_ID, PCI_ANY_ID,
0, 0, (unsigned long) &fore200e_bus[0] },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, fore200e_pca_tbl);
static struct pci_driver fore200e_pca_driver = {
.name = "fore_200e",
.probe = fore200e_pca_detect,
.remove = __devexit_p(fore200e_pca_remove_one),
.id_table = fore200e_pca_tbl,
};
#endif
static int __init
fore200e_module_init(void)
{
const struct fore200e_bus* bus;
struct fore200e* fore200e;
int index, link;
int index;
printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n");
/* for each configured bus interface */
for (link = 0, bus = fore200e_bus; bus->model_name; bus++) {
for (bus = fore200e_bus; bus->model_name; bus++) {
/* detect all boards present on that bus */
for (index = 0; (fore200e = bus->detect(bus, index)); index++) {
for (index = 0; bus->detect && (fore200e = bus->detect(bus, index)); index++) {
printk(FORE200E "device %s found at 0x%lx, IRQ %s\n",
fore200e->bus->model_name,
......@@ -2795,15 +2849,18 @@ fore200e_module_init(void)
break;
}
link++;
fore200e->next = fore200e_boards;
fore200e_boards = fore200e;
list_add(&fore200e->entry, &fore200e_boards);
}
}
if (link)
return 0;
#ifdef CONFIG_ATM_FORE200E_PCA
if (!pci_module_init(&fore200e_pca_driver))
return 0;
#endif
if (!list_empty(&fore200e_boards))
return 0;
return -ENODEV;
}
......@@ -2811,11 +2868,14 @@ fore200e_module_init(void)
static void __exit
fore200e_module_cleanup(void)
{
while (fore200e_boards) {
struct fore200e* fore200e = fore200e_boards;
struct fore200e *fore200e, *next;
#ifdef CONFIG_ATM_FORE200E_PCA
pci_unregister_driver(&fore200e_pca_driver);
#endif
list_for_each_entry_safe(fore200e, next, &fore200e_boards, entry) {
fore200e_shutdown(fore200e);
fore200e_boards = fore200e->next;
kfree(fore200e);
}
DPRINTK(1, "module being removed\n");
......@@ -3150,7 +3210,7 @@ static const struct fore200e_bus fore200e_bus[] = {
fore200e_pca_dma_sync_for_device,
fore200e_pca_dma_chunk_alloc,
fore200e_pca_dma_chunk_free,
fore200e_pca_detect,
NULL,
fore200e_pca_configure,
fore200e_pca_map,
fore200e_pca_reset,
......
......@@ -841,7 +841,7 @@ typedef struct fore200e_vc_map {
/* per-device data */
typedef struct fore200e {
struct fore200e* next; /* next device */
struct list_head entry; /* next device */
const struct fore200e_bus* bus; /* bus-dependent code and data */
union fore200e_regs regs; /* bus-dependent registers */
struct atm_dev* atm_dev; /* ATM device */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment