of: Always use 'struct device.of_node' to get device node pointer.
[safe/jmp/linux-2.6] / drivers / atm / fore200e.c
index a7c0ed3..593a03a 100644 (file)
@@ -1,6 +1,4 @@
 /*
-  $Id: fore200e.c,v 1.5 2000/04/14 10:10:34 davem Exp $
-
   A FORE Systems 200E-series driver for ATM on Linux.
   Christophe Lizzi (lizzi@cnam.fr), October 1999-March 2003.
 
@@ -38,6 +36,7 @@
 #include <linux/atm_suni.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/firmware.h>
 #include <asm/io.h>
 #include <asm/string.h>
 #include <asm/page.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
 
-#ifdef CONFIG_ATM_FORE200E_SBA
+#ifdef CONFIG_SBUS
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <asm/idprom.h>
-#include <asm/sbus.h>
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 #include <asm/pgtable.h>
@@ -97,8 +97,8 @@
 #if 1
 #define ASSERT(expr)     if (!(expr)) { \
                             printk(FORE200E "assertion failed! %s[%d]: %s\n", \
-                                   __FUNCTION__, __LINE__, #expr); \
-                            panic(FORE200E "%s", __FUNCTION__); \
+                                   __func__, __LINE__, #expr); \
+                            panic(FORE200E "%s", __func__); \
                         }
 #else
 #define ASSERT(expr)     do {} while (0)
@@ -384,9 +384,6 @@ fore200e_shutdown(struct fore200e* fore200e)
     case FORE200E_STATE_START_FW:
        /* nothing to do for that state */
 
-    case FORE200E_STATE_LOAD_FW:
-       /* nothing to do for that state */
-
     case FORE200E_STATE_RESET:
        /* nothing to do for that state */
 
@@ -407,7 +404,7 @@ fore200e_shutdown(struct fore200e* fore200e)
 }
 
 
-#ifdef CONFIG_ATM_FORE200E_PCA
+#ifdef CONFIG_PCI
 
 static u32 fore200e_pca_read(volatile u32 __iomem *addr)
 {
@@ -660,256 +657,198 @@ fore200e_pca_proc_read(struct fore200e* fore200e, char *page)
                   pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
 }
 
-#endif /* CONFIG_ATM_FORE200E_PCA */
+#endif /* CONFIG_PCI */
 
 
-#ifdef CONFIG_ATM_FORE200E_SBA
+#ifdef CONFIG_SBUS
 
-static u32
-fore200e_sba_read(volatile u32 __iomem *addr)
+static u32 fore200e_sba_read(volatile u32 __iomem *addr)
 {
     return sbus_readl(addr);
 }
 
-
-static void
-fore200e_sba_write(u32 val, volatile u32 __iomem *addr)
+static void fore200e_sba_write(u32 val, volatile u32 __iomem *addr)
 {
     sbus_writel(val, addr);
 }
 
-
-static u32
-fore200e_sba_dma_map(struct fore200e* fore200e, void* virt_addr, int size, int direction)
+static u32 fore200e_sba_dma_map(struct fore200e *fore200e, void* virt_addr, int size, int direction)
 {
-    u32 dma_addr = sbus_map_single((struct sbus_dev*)fore200e->bus_dev, virt_addr, size, direction);
+       struct of_device *op = fore200e->bus_dev;
+       u32 dma_addr;
 
-    DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d, direction = %d --> dma_addr = 0x%08x\n",
-           virt_addr, size, direction, dma_addr);
+       dma_addr = dma_map_single(&op->dev, virt_addr, size, direction);
+
+       DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d, direction = %d --> dma_addr = 0x%08x\n",
+               virt_addr, size, direction, dma_addr);
     
-    return dma_addr;
+       return dma_addr;
 }
 
-
-static void
-fore200e_sba_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
+static void fore200e_sba_dma_unmap(struct fore200e *fore200e, u32 dma_addr, int size, int direction)
 {
-    DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n",
-           dma_addr, size, direction);
+       struct of_device *op = fore200e->bus_dev;
 
-    sbus_unmap_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction);
-}
+       DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n",
+               dma_addr, size, direction);
 
+       dma_unmap_single(&op->dev, dma_addr, size, direction);
+}
 
-static void
-fore200e_sba_dma_sync_for_cpu(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
+static void fore200e_sba_dma_sync_for_cpu(struct fore200e *fore200e, u32 dma_addr, int size, int direction)
 {
-    DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
+       struct of_device *op = fore200e->bus_dev;
+
+       DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
     
-    sbus_dma_sync_single_for_cpu((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction);
+       dma_sync_single_for_cpu(&op->dev, dma_addr, size, direction);
 }
 
-static void
-fore200e_sba_dma_sync_for_device(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
+static void fore200e_sba_dma_sync_for_device(struct fore200e *fore200e, u32 dma_addr, int size, int direction)
 {
-    DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
-
-    sbus_dma_sync_single_for_device((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction);
-}
+       struct of_device *op = fore200e->bus_dev;
 
+       DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
 
-/* allocate a DVMA consistent chunk of memory intended to act as a communication mechanism
-   (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */
+       dma_sync_single_for_device(&op->dev, dma_addr, size, direction);
+}
 
-static int
-fore200e_sba_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk,
-                            int size, int nbr, int alignment)
+/* Allocate a DVMA consistent chunk of memory intended to act as a communication mechanism
+ * (to hold descriptors, status, queues, etc.) shared by the driver and the adapter.
+ */
+static int fore200e_sba_dma_chunk_alloc(struct fore200e *fore200e, struct chunk *chunk,
+                                       int size, int nbr, int alignment)
 {
-    chunk->alloc_size = chunk->align_size = size * nbr;
+       struct of_device *op = fore200e->bus_dev;
 
-    /* returned chunks are page-aligned */
-    chunk->alloc_addr = sbus_alloc_consistent((struct sbus_dev*)fore200e->bus_dev,
-                                             chunk->alloc_size,
-                                             &chunk->dma_addr);
+       chunk->alloc_size = chunk->align_size = size * nbr;
 
-    if ((chunk->alloc_addr == NULL) || (chunk->dma_addr == 0))
-       return -ENOMEM;
+       /* returned chunks are page-aligned */
+       chunk->alloc_addr = dma_alloc_coherent(&op->dev, chunk->alloc_size,
+                                              &chunk->dma_addr, GFP_ATOMIC);
 
-    chunk->align_addr = chunk->alloc_addr;
+       if ((chunk->alloc_addr == NULL) || (chunk->dma_addr == 0))
+               return -ENOMEM;
+
+       chunk->align_addr = chunk->alloc_addr;
     
-    return 0;
+       return 0;
 }
 
-
 /* free a DVMA consistent chunk of memory */
-
-static void
-fore200e_sba_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
+static void fore200e_sba_dma_chunk_free(struct fore200e *fore200e, struct chunk *chunk)
 {
-    sbus_free_consistent((struct sbus_dev*)fore200e->bus_dev,
-                        chunk->alloc_size,
-                        chunk->alloc_addr,
-                        chunk->dma_addr);
-}
+       struct of_device *op = fore200e->bus_dev;
 
+       dma_free_coherent(&op->dev, chunk->alloc_size,
+                         chunk->alloc_addr, chunk->dma_addr);
+}
 
-static void
-fore200e_sba_irq_enable(struct fore200e* fore200e)
+static void fore200e_sba_irq_enable(struct fore200e *fore200e)
 {
-    u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
-    fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr);
+       u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
+       fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr);
 }
 
-
-static int
-fore200e_sba_irq_check(struct fore200e* fore200e)
+static int fore200e_sba_irq_check(struct fore200e *fore200e)
 {
-    return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ;
+       return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ;
 }
 
-
-static void
-fore200e_sba_irq_ack(struct fore200e* fore200e)
+static void fore200e_sba_irq_ack(struct fore200e *fore200e)
 {
-    u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
-    fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr);
+       u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
+       fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr);
 }
 
-
-static void
-fore200e_sba_reset(struct fore200e* fore200e)
+static void fore200e_sba_reset(struct fore200e *fore200e)
 {
-    fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr);
-    fore200e_spin(10);
-    fore200e->bus->write(0, fore200e->regs.sba.hcr);
+       fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr);
+       fore200e_spin(10);
+       fore200e->bus->write(0, fore200e->regs.sba.hcr);
 }
 
-
-static int __init
-fore200e_sba_map(struct fore200e* fore200e)
+static int __init fore200e_sba_map(struct fore200e *fore200e)
 {
-    struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev;
-    unsigned int bursts;
+       struct of_device *op = fore200e->bus_dev;
+       unsigned int bursts;
 
-    /* gain access to the SBA specific registers  */
-    fore200e->regs.sba.hcr = sbus_ioremap(&sbus_dev->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR");
-    fore200e->regs.sba.bsr = sbus_ioremap(&sbus_dev->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR");
-    fore200e->regs.sba.isr = sbus_ioremap(&sbus_dev->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR");
-    fore200e->virt_base    = sbus_ioremap(&sbus_dev->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM");
+       /* gain access to the SBA specific registers  */
+       fore200e->regs.sba.hcr = of_ioremap(&op->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR");
+       fore200e->regs.sba.bsr = of_ioremap(&op->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR");
+       fore200e->regs.sba.isr = of_ioremap(&op->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR");
+       fore200e->virt_base    = of_ioremap(&op->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM");
 
-    if (fore200e->virt_base == NULL) {
-       printk(FORE200E "unable to map RAM of device %s\n", fore200e->name);
-       return -EFAULT;
-    }
+       if (!fore200e->virt_base) {
+               printk(FORE200E "unable to map RAM of device %s\n", fore200e->name);
+               return -EFAULT;
+       }
 
-    DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
+       DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
     
-    fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */
+       fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */
 
-    /* get the supported DVMA burst sizes */
-    bursts = prom_getintdefault(sbus_dev->bus->prom_node, "burst-sizes", 0x00);
+       /* get the supported DVMA burst sizes */
+       bursts = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0x00);
 
-    if (sbus_can_dma_64bit(sbus_dev))
-       sbus_set_sbus64(sbus_dev, bursts);
+       if (sbus_can_dma_64bit())
+               sbus_set_sbus64(&op->dev, bursts);
 
-    fore200e->state = FORE200E_STATE_MAP;
-    return 0;
+       fore200e->state = FORE200E_STATE_MAP;
+       return 0;
 }
 
-
-static void
-fore200e_sba_unmap(struct fore200e* fore200e)
+static void fore200e_sba_unmap(struct fore200e *fore200e)
 {
-    sbus_iounmap(fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH);
-    sbus_iounmap(fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH);
-    sbus_iounmap(fore200e->regs.sba.isr, SBA200E_ISR_LENGTH);
-    sbus_iounmap(fore200e->virt_base,    SBA200E_RAM_LENGTH);
-}
+       struct of_device *op = fore200e->bus_dev;
 
+       of_iounmap(&op->resource[0], fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH);
+       of_iounmap(&op->resource[1], fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH);
+       of_iounmap(&op->resource[2], fore200e->regs.sba.isr, SBA200E_ISR_LENGTH);
+       of_iounmap(&op->resource[3], fore200e->virt_base,    SBA200E_RAM_LENGTH);
+}
 
-static int __init
-fore200e_sba_configure(struct fore200e* fore200e)
+static int __init fore200e_sba_configure(struct fore200e *fore200e)
 {
-    fore200e->state = FORE200E_STATE_CONFIGURE;
-    return 0;
+       fore200e->state = FORE200E_STATE_CONFIGURE;
+       return 0;
 }
 
-
-static struct fore200e* __init
-fore200e_sba_detect(const struct fore200e_bus* bus, int index)
+static int __init fore200e_sba_prom_read(struct fore200e *fore200e, struct prom_data *prom)
 {
-    struct fore200e*          fore200e;
-    struct sbus_bus* sbus_bus;
-    struct sbus_dev* sbus_dev = NULL;
-    
-    unsigned int     count = 0;
-    
-    for_each_sbus (sbus_bus) {
-       for_each_sbusdev (sbus_dev, sbus_bus) {
-           if (strcmp(sbus_dev->prom_name, SBA200E_PROM_NAME) == 0) {
-               if (count >= index)
-                   goto found;
-               count++;
-           }
-       }
-    }
-    return NULL;
-    
-  found:
-    if (sbus_dev->num_registers != 4) {
-       printk(FORE200E "this %s device has %d instead of 4 registers\n",
-              bus->model_name, sbus_dev->num_registers);
-       return NULL;
-    }
-
-    fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
-    if (fore200e == NULL)
-       return NULL;
+       struct of_device *op = fore200e->bus_dev;
+       const u8 *prop;
+       int len;
 
-    fore200e->bus     = bus;
-    fore200e->bus_dev = sbus_dev;
-    fore200e->irq     = sbus_dev->irqs[ 0 ];
+       prop = of_get_property(op->dev.of_node, "madaddrlo2", &len);
+       if (!prop)
+               return -ENODEV;
+       memcpy(&prom->mac_addr[4], prop, 4);
 
-    fore200e->phys_base = (unsigned long)sbus_dev;
+       prop = of_get_property(op->dev.of_node, "madaddrhi4", &len);
+       if (!prop)
+               return -ENODEV;
+       memcpy(&prom->mac_addr[2], prop, 4);
 
-    sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1);
+       prom->serial_number = of_getintprop_default(op->dev.of_node,
+                                                   "serialnumber", 0);
+       prom->hw_revision = of_getintprop_default(op->dev.of_node,
+                                                 "promversion", 0);
     
-    return fore200e;
+       return 0;
 }
 
-
-static int __init
-fore200e_sba_prom_read(struct fore200e* fore200e, struct prom_data* prom)
+static int fore200e_sba_proc_read(struct fore200e *fore200e, char *page)
 {
-    struct sbus_dev* sbus_dev = (struct sbus_dev*) fore200e->bus_dev;
-    int                       len;
+       struct of_device *op = fore200e->bus_dev;
+       const struct linux_prom_registers *regs;
 
-    len = prom_getproperty(sbus_dev->prom_node, "macaddrlo2", &prom->mac_addr[ 4 ], 4);
-    if (len < 0)
-       return -EBUSY;
+       regs = of_get_property(op->dev.of_node, "reg", NULL);
 
-    len = prom_getproperty(sbus_dev->prom_node, "macaddrhi4", &prom->mac_addr[ 2 ], 4);
-    if (len < 0)
-       return -EBUSY;
-    
-    prom_getproperty(sbus_dev->prom_node, "serialnumber",
-                    (char*)&prom->serial_number, sizeof(prom->serial_number));
-    
-    prom_getproperty(sbus_dev->prom_node, "promversion",
-                    (char*)&prom->hw_revision, sizeof(prom->hw_revision));
-    
-    return 0;
+       return sprintf(page, "   SBUS slot/device:\t\t%d/'%s'\n",
+                      (regs ? regs->which_io : 0), op->dev.of_node->name);
 }
-
-
-static int
-fore200e_sba_proc_read(struct fore200e* fore200e, char *page)
-{
-    struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev;
-
-    return sprintf(page, "   SBUS slot/device:\t\t%d/'%s'\n", sbus_dev->slot, sbus_dev->prom_name);
-}
-#endif /* CONFIG_ATM_FORE200E_SBA */
+#endif /* CONFIG_SBUS */
 
 
 static void
@@ -1502,9 +1441,9 @@ fore200e_open(struct atm_vcc *vcc)
     /* pseudo-CBR bandwidth requested? */
     if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
        
-       down(&fore200e->rate_sf);
+       mutex_lock(&fore200e->rate_mtx);
        if (fore200e->available_cell_rate < vcc->qos.txtp.max_pcr) {
-           up(&fore200e->rate_sf);
+           mutex_unlock(&fore200e->rate_mtx);
 
            kfree(fore200e_vcc);
            vc_map->vcc = NULL;
@@ -1513,7 +1452,7 @@ fore200e_open(struct atm_vcc *vcc)
 
        /* reserve bandwidth */
        fore200e->available_cell_rate -= vcc->qos.txtp.max_pcr;
-       up(&fore200e->rate_sf);
+       mutex_unlock(&fore200e->rate_mtx);
     }
     
     vcc->itf = vcc->dev->number;
@@ -1599,9 +1538,9 @@ fore200e_close(struct atm_vcc* vcc)
     /* release reserved bandwidth, if any */
     if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
 
-       down(&fore200e->rate_sf);
+       mutex_lock(&fore200e->rate_mtx);
        fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
-       up(&fore200e->rate_sf);
+       mutex_unlock(&fore200e->rate_mtx);
 
        clear_bit(ATM_VF_HASQOS, &vcc->flags);
     }
@@ -1858,7 +1797,7 @@ fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *op
 
 
 static int
-fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
+fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, unsigned int optlen)
 {
     /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
     
@@ -1990,19 +1929,19 @@ fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg)
     if (fore200e_getstats(fore200e) < 0)
        return -EIO;
 
-    tmp.section_bip = cpu_to_be32(fore200e->stats->oc3.section_bip8_errors);
-    tmp.line_bip    = cpu_to_be32(fore200e->stats->oc3.line_bip24_errors);
-    tmp.path_bip    = cpu_to_be32(fore200e->stats->oc3.path_bip8_errors);
-    tmp.line_febe   = cpu_to_be32(fore200e->stats->oc3.line_febe_errors);
-    tmp.path_febe   = cpu_to_be32(fore200e->stats->oc3.path_febe_errors);
-    tmp.corr_hcs    = cpu_to_be32(fore200e->stats->oc3.corr_hcs_errors);
-    tmp.uncorr_hcs  = cpu_to_be32(fore200e->stats->oc3.ucorr_hcs_errors);
-    tmp.tx_cells    = cpu_to_be32(fore200e->stats->aal0.cells_transmitted)  +
-                     cpu_to_be32(fore200e->stats->aal34.cells_transmitted) +
-                     cpu_to_be32(fore200e->stats->aal5.cells_transmitted);
-    tmp.rx_cells    = cpu_to_be32(fore200e->stats->aal0.cells_received)     +
-                     cpu_to_be32(fore200e->stats->aal34.cells_received)    +
-                     cpu_to_be32(fore200e->stats->aal5.cells_received);
+    tmp.section_bip = be32_to_cpu(fore200e->stats->oc3.section_bip8_errors);
+    tmp.line_bip    = be32_to_cpu(fore200e->stats->oc3.line_bip24_errors);
+    tmp.path_bip    = be32_to_cpu(fore200e->stats->oc3.path_bip8_errors);
+    tmp.line_febe   = be32_to_cpu(fore200e->stats->oc3.line_febe_errors);
+    tmp.path_febe   = be32_to_cpu(fore200e->stats->oc3.path_febe_errors);
+    tmp.corr_hcs    = be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors);
+    tmp.uncorr_hcs  = be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors);
+    tmp.tx_cells    = be32_to_cpu(fore200e->stats->aal0.cells_transmitted)  +
+                     be32_to_cpu(fore200e->stats->aal34.cells_transmitted) +
+                     be32_to_cpu(fore200e->stats->aal5.cells_transmitted);
+    tmp.rx_cells    = be32_to_cpu(fore200e->stats->aal0.cells_received)     +
+                     be32_to_cpu(fore200e->stats->aal34.cells_received)    +
+                     be32_to_cpu(fore200e->stats->aal5.cells_received);
 
     if (arg)
        return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0;       
@@ -2064,16 +2003,16 @@ fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags)
 
     if ((qos->txtp.traffic_class == ATM_CBR) && (qos->txtp.max_pcr > 0)) {
 
-       down(&fore200e->rate_sf);
+       mutex_lock(&fore200e->rate_mtx);
        if (fore200e->available_cell_rate + vcc->qos.txtp.max_pcr < qos->txtp.max_pcr) {
-           up(&fore200e->rate_sf);
+           mutex_unlock(&fore200e->rate_mtx);
            return -EAGAIN;
        }
 
        fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
        fore200e->available_cell_rate -= qos->txtp.max_pcr;
 
-       up(&fore200e->rate_sf);
+       mutex_unlock(&fore200e->rate_mtx);
        
        memcpy(&vcc->qos, qos, sizeof(struct atm_qos));
        
@@ -2127,12 +2066,10 @@ fore200e_get_esi(struct fore200e* fore200e)
        return -EBUSY;
     }
        
-    printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %02x:%02x:%02x:%02x:%02x:%02x\n", 
+    printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %pM\n",
           fore200e->name, 
           (prom->hw_revision & 0xFF) + '@',    /* probably meaningless with SBA boards */
-          prom->serial_number & 0xFFFF,
-          prom->mac_addr[ 2 ], prom->mac_addr[ 3 ], prom->mac_addr[ 4 ],
-          prom->mac_addr[ 5 ], prom->mac_addr[ 6 ], prom->mac_addr[ 7 ]);
+          prom->serial_number & 0xFFFF, &prom->mac_addr[2]);
        
     for (i = 0; i < ESI_LEN; i++) {
        fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ];
@@ -2437,7 +2374,7 @@ fore200e_init_cmd_queue(struct fore200e* fore200e)
 }
 
 
-static void __init
+static void __devinit
 fore200e_param_bs_queue(struct fore200e* fore200e,
                        enum buffer_scheme scheme, enum buffer_magn magn,
                        int queue_length, int pool_size, int supply_blksize)
@@ -2459,7 +2396,7 @@ fore200e_initialize(struct fore200e* fore200e)
 
     DPRINTK(2, "device %s being initialized\n", fore200e->name);
 
-    init_MUTEX(&fore200e->rate_sf);
+    mutex_init(&fore200e->rate_mtx);
     spin_lock_init(&fore200e->q_lock);
 
     cpq = fore200e->cp_queues = fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET;
@@ -2554,13 +2491,54 @@ fore200e_monitor_puts(struct fore200e* fore200e, char* str)
     while (fore200e_monitor_getc(fore200e) >= 0);
 }
 
+#ifdef __LITTLE_ENDIAN
+#define FW_EXT ".bin"
+#else
+#define FW_EXT "_ecd.bin2"
+#endif
 
 static int __devinit
-fore200e_start_fw(struct fore200e* fore200e)
-{
-    int               ok;
-    char              cmd[ 48 ];
-    struct fw_header* fw_header = (struct fw_header*) fore200e->bus->fw_data;
+fore200e_load_and_start_fw(struct fore200e* fore200e)
+{
+    const struct firmware *firmware;
+    struct device *device;
+    struct fw_header *fw_header;
+    const __le32 *fw_data;
+    u32 fw_size;
+    u32 __iomem *load_addr;
+    char buf[48];
+    int err = -ENODEV;
+
+    if (strcmp(fore200e->bus->model_name, "PCA-200E") == 0)
+       device = &((struct pci_dev *) fore200e->bus_dev)->dev;
+#ifdef CONFIG_SBUS
+    else if (strcmp(fore200e->bus->model_name, "SBA-200E") == 0)
+       device = &((struct of_device *) fore200e->bus_dev)->dev;
+#endif
+    else
+       return err;
+
+    sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT);
+    if ((err = request_firmware(&firmware, buf, device)) < 0) {
+       printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name);
+       return err;
+    }
+
+    fw_data = (__le32 *) firmware->data;
+    fw_size = firmware->size / sizeof(u32);
+    fw_header = (struct fw_header *) firmware->data;
+    load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset);
+
+    DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n",
+           fore200e->name, load_addr, fw_size);
+
+    if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) {
+       printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name);
+       goto release;
+    }
+
+    for (; fw_size--; fw_data++, load_addr++)
+       fore200e->bus->write(le32_to_cpu(*fw_data), load_addr);
 
     DPRINTK(2, "device %s firmware being started\n", fore200e->name);
 
@@ -2569,46 +2547,22 @@ fore200e_start_fw(struct fore200e* fore200e)
     fore200e_spin(100);
 #endif
 
-    sprintf(cmd, "\rgo %x\r", le32_to_cpu(fw_header->start_offset));
-
-    fore200e_monitor_puts(fore200e, cmd);
+    sprintf(buf, "\rgo %x\r", le32_to_cpu(fw_header->start_offset));
+    fore200e_monitor_puts(fore200e, buf);
 
-    ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000);
-    if (ok == 0) {
+    if (fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000) == 0) {
        printk(FORE200E "device %s firmware didn't start\n", fore200e->name);
-       return -ENODEV;
+       goto release;
     }
 
     printk(FORE200E "device %s firmware started\n", fore200e->name);
 
     fore200e->state = FORE200E_STATE_START_FW;
-    return 0;
-}
-
-
-static int __devinit
-fore200e_load_fw(struct fore200e* fore200e)
-{
-    u32* fw_data = (u32*) fore200e->bus->fw_data;
-    u32  fw_size = (u32) *fore200e->bus->fw_size / sizeof(u32);
-
-    struct fw_header* fw_header = (struct fw_header*) fw_data;
-
-    u32 __iomem *load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset);
+    err = 0;
 
-    DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n", 
-           fore200e->name, load_addr, fw_size);
-
-    if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) {
-       printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name);
-       return -ENODEV;
-    }
-
-    for (; fw_size--; fw_data++, load_addr++)
-       fore200e->bus->write(le32_to_cpu(*fw_data), load_addr);
-
-    fore200e->state = FORE200E_STATE_LOAD_FW;
-    return 0;
+release:
+    release_firmware(firmware);
+    return err;
 }
 
 
@@ -2654,10 +2608,7 @@ fore200e_init(struct fore200e* fore200e)
     if (fore200e_reset(fore200e, 1) < 0)
        return -ENODEV;
 
-    if (fore200e_load_fw(fore200e) < 0)
-       return -ENODEV;
-
-    if (fore200e_start_fw(fore200e) < 0)
+    if (fore200e_load_and_start_fw(fore200e) < 0)
        return -ENODEV;
 
     if (fore200e_initialize(fore200e) < 0)
@@ -2691,7 +2642,67 @@ fore200e_init(struct fore200e* fore200e)
     return 0;
 }
 
+#ifdef CONFIG_SBUS
+static int __devinit fore200e_sba_probe(struct of_device *op,
+                                       const struct of_device_id *match)
+{
+       const struct fore200e_bus *bus = match->data;
+       struct fore200e *fore200e;
+       static int index = 0;
+       int err;
+
+       fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
+       if (!fore200e)
+               return -ENOMEM;
+
+       fore200e->bus = bus;
+       fore200e->bus_dev = op;
+       fore200e->irq = op->irqs[0];
+       fore200e->phys_base = op->resource[0].start;
+
+       sprintf(fore200e->name, "%s-%d", bus->model_name, index);
+
+       err = fore200e_init(fore200e);
+       if (err < 0) {
+               fore200e_shutdown(fore200e);
+               kfree(fore200e);
+               return err;
+       }
+
+       index++;
+       dev_set_drvdata(&op->dev, fore200e);
 
+       return 0;
+}
+
+static int __devexit fore200e_sba_remove(struct of_device *op)
+{
+       struct fore200e *fore200e = dev_get_drvdata(&op->dev);
+
+       fore200e_shutdown(fore200e);
+       kfree(fore200e);
+
+       return 0;
+}
+
+static const struct of_device_id fore200e_sba_match[] = {
+       {
+               .name = SBA200E_PROM_NAME,
+               .data = (void *) &fore200e_bus[1],
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, fore200e_sba_match);
+
+static struct of_platform_driver fore200e_sba_driver = {
+       .name           = "fore_200e",
+       .match_table    = fore200e_sba_match,
+       .probe          = fore200e_sba_probe,
+       .remove         = __devexit_p(fore200e_sba_remove),
+};
+#endif
+
+#ifdef CONFIG_PCI
 static int __devinit
 fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
 {
@@ -2758,7 +2769,6 @@ static void __devexit fore200e_pca_remove_one(struct pci_dev *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] },
@@ -2775,67 +2785,40 @@ static struct pci_driver fore200e_pca_driver = {
 };
 #endif
 
-
-static int __init
-fore200e_module_init(void)
+static int __init fore200e_module_init(void)
 {
-    const struct fore200e_bus* bus;
-    struct       fore200e*     fore200e;
-    int                        index;
-
-    printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n");
-
-    /* for each configured bus interface */
-    for (bus = fore200e_bus; bus->model_name; bus++) {
-
-       /* detect all boards present on that bus */
-       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, 
-                  fore200e->phys_base, fore200e_irq_itoa(fore200e->irq));
-
-           sprintf(fore200e->name, "%s-%d", bus->model_name, index);
+       int err;
 
-           if (fore200e_init(fore200e) < 0) {
+       printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n");
 
-               fore200e_shutdown(fore200e);
-               break;
-           }
-
-           list_add(&fore200e->entry, &fore200e_boards);
-       }
-    }
+#ifdef CONFIG_SBUS
+       err = of_register_driver(&fore200e_sba_driver, &of_bus_type);
+       if (err)
+               return err;
+#endif
 
-#ifdef CONFIG_ATM_FORE200E_PCA
-    if (!pci_register_driver(&fore200e_pca_driver))
-       return 0;
+#ifdef CONFIG_PCI
+       err = pci_register_driver(&fore200e_pca_driver);
 #endif
 
-    if (!list_empty(&fore200e_boards))
-       return 0;
+#ifdef CONFIG_SBUS
+       if (err)
+               of_unregister_driver(&fore200e_sba_driver);
+#endif
 
-    return -ENODEV;
+       return err;
 }
 
-
-static void __exit
-fore200e_module_cleanup(void)
+static void __exit fore200e_module_cleanup(void)
 {
-    struct fore200e *fore200e, *next;
-
-#ifdef CONFIG_ATM_FORE200E_PCA
-    pci_unregister_driver(&fore200e_pca_driver);
+#ifdef CONFIG_PCI
+       pci_unregister_driver(&fore200e_pca_driver);
+#endif
+#ifdef CONFIG_SBUS
+       of_unregister_driver(&fore200e_sba_driver);
 #endif
-
-    list_for_each_entry_safe(fore200e, next, &fore200e_boards, entry) {
-       fore200e_shutdown(fore200e);
-       kfree(fore200e);
-    }
-    DPRINTK(1, "module being removed\n");
 }
 
-
 static int
 fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
 {
@@ -2862,13 +2845,12 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
                "   interrupt line:\t\t%s\n"
                "   physical base address:\t0x%p\n"
                "   virtual base address:\t0x%p\n"
-               "   factory address (ESI):\t%02x:%02x:%02x:%02x:%02x:%02x\n"
+               "   factory address (ESI):\t%pM\n"
                "   board serial number:\t\t%d\n\n",
                fore200e_irq_itoa(fore200e->irq),
                (void*)fore200e->phys_base,
                fore200e->virt_base,
-               fore200e->esi[0], fore200e->esi[1], fore200e->esi[2],
-               fore200e->esi[3], fore200e->esi[4], fore200e->esi[5],
+               fore200e->esi,
                fore200e->esi[4] * 256 + fore200e->esi[5]);
 
        return len;
@@ -2923,8 +2905,8 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
        u32 media_index    = FORE200E_MEDIA_INDEX(fore200e->bus->read(&fore200e->cp_queues->media_type));
        u32 oc3_index;
 
-       if ((media_index < 0) || (media_index > 4))
-           media_index = 5;
+       if (media_index > 4)
+               media_index = 5;
        
        switch (fore200e->loop_mode) {
            case ATM_LM_NONE:    oc3_index = 0;
@@ -2968,8 +2950,8 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
                       "  4b5b:\n"
                       "     crc_header_errors:\t\t%10u\n"
                       "     framing_errors:\t\t%10u\n",
-                      cpu_to_be32(fore200e->stats->phy.crc_header_errors),
-                      cpu_to_be32(fore200e->stats->phy.framing_errors));
+                      be32_to_cpu(fore200e->stats->phy.crc_header_errors),
+                      be32_to_cpu(fore200e->stats->phy.framing_errors));
     
     if (!left--)
        return sprintf(page, "\n"
@@ -2981,13 +2963,13 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
                       "     path_febe_errors:\t\t%10u\n"
                       "     corr_hcs_errors:\t\t%10u\n"
                       "     ucorr_hcs_errors:\t\t%10u\n",
-                      cpu_to_be32(fore200e->stats->oc3.section_bip8_errors),
-                      cpu_to_be32(fore200e->stats->oc3.path_bip8_errors),
-                      cpu_to_be32(fore200e->stats->oc3.line_bip24_errors),
-                      cpu_to_be32(fore200e->stats->oc3.line_febe_errors),
-                      cpu_to_be32(fore200e->stats->oc3.path_febe_errors),
-                      cpu_to_be32(fore200e->stats->oc3.corr_hcs_errors),
-                      cpu_to_be32(fore200e->stats->oc3.ucorr_hcs_errors));
+                      be32_to_cpu(fore200e->stats->oc3.section_bip8_errors),
+                      be32_to_cpu(fore200e->stats->oc3.path_bip8_errors),
+                      be32_to_cpu(fore200e->stats->oc3.line_bip24_errors),
+                      be32_to_cpu(fore200e->stats->oc3.line_febe_errors),
+                      be32_to_cpu(fore200e->stats->oc3.path_febe_errors),
+                      be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors),
+                      be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors));
 
     if (!left--)
        return sprintf(page,"\n"
@@ -2998,12 +2980,12 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
                       "     vpi no conn:\t\t%10u\n"
                       "     vci out of range:\t\t%10u\n"
                       "     vci no conn:\t\t%10u\n",
-                      cpu_to_be32(fore200e->stats->atm.cells_transmitted),
-                      cpu_to_be32(fore200e->stats->atm.cells_received),
-                      cpu_to_be32(fore200e->stats->atm.vpi_bad_range),
-                      cpu_to_be32(fore200e->stats->atm.vpi_no_conn),
-                      cpu_to_be32(fore200e->stats->atm.vci_bad_range),
-                      cpu_to_be32(fore200e->stats->atm.vci_no_conn));
+                      be32_to_cpu(fore200e->stats->atm.cells_transmitted),
+                      be32_to_cpu(fore200e->stats->atm.cells_received),
+                      be32_to_cpu(fore200e->stats->atm.vpi_bad_range),
+                      be32_to_cpu(fore200e->stats->atm.vpi_no_conn),
+                      be32_to_cpu(fore200e->stats->atm.vci_bad_range),
+                      be32_to_cpu(fore200e->stats->atm.vci_no_conn));
     
     if (!left--)
        return sprintf(page,"\n"
@@ -3011,9 +2993,9 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
                       "     TX:\t\t\t%10u\n"
                       "     RX:\t\t\t%10u\n"
                       "     dropped:\t\t\t%10u\n",
-                      cpu_to_be32(fore200e->stats->aal0.cells_transmitted),
-                      cpu_to_be32(fore200e->stats->aal0.cells_received),
-                      cpu_to_be32(fore200e->stats->aal0.cells_dropped));
+                      be32_to_cpu(fore200e->stats->aal0.cells_transmitted),
+                      be32_to_cpu(fore200e->stats->aal0.cells_received),
+                      be32_to_cpu(fore200e->stats->aal0.cells_dropped));
     
     if (!left--)
        return sprintf(page,"\n"
@@ -3029,15 +3011,15 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
                       "       RX:\t\t\t%10u\n"
                       "       dropped:\t\t\t%10u\n"
                       "       protocol errors:\t\t%10u\n",
-                      cpu_to_be32(fore200e->stats->aal34.cells_transmitted),
-                      cpu_to_be32(fore200e->stats->aal34.cells_received),
-                      cpu_to_be32(fore200e->stats->aal34.cells_dropped),
-                      cpu_to_be32(fore200e->stats->aal34.cells_crc_errors),
-                      cpu_to_be32(fore200e->stats->aal34.cells_protocol_errors),
-                      cpu_to_be32(fore200e->stats->aal34.cspdus_transmitted),
-                      cpu_to_be32(fore200e->stats->aal34.cspdus_received),
-                      cpu_to_be32(fore200e->stats->aal34.cspdus_dropped),
-                      cpu_to_be32(fore200e->stats->aal34.cspdus_protocol_errors));
+                      be32_to_cpu(fore200e->stats->aal34.cells_transmitted),
+                      be32_to_cpu(fore200e->stats->aal34.cells_received),
+                      be32_to_cpu(fore200e->stats->aal34.cells_dropped),
+                      be32_to_cpu(fore200e->stats->aal34.cells_crc_errors),
+                      be32_to_cpu(fore200e->stats->aal34.cells_protocol_errors),
+                      be32_to_cpu(fore200e->stats->aal34.cspdus_transmitted),
+                      be32_to_cpu(fore200e->stats->aal34.cspdus_received),
+                      be32_to_cpu(fore200e->stats->aal34.cspdus_dropped),
+                      be32_to_cpu(fore200e->stats->aal34.cspdus_protocol_errors));
     
     if (!left--)
        return sprintf(page,"\n"
@@ -3053,15 +3035,15 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
                       "       dropped:\t\t\t%10u\n"
                       "       CRC errors:\t\t%10u\n"
                       "       protocol errors:\t\t%10u\n",
-                      cpu_to_be32(fore200e->stats->aal5.cells_transmitted),
-                      cpu_to_be32(fore200e->stats->aal5.cells_received),
-                      cpu_to_be32(fore200e->stats->aal5.cells_dropped),
-                      cpu_to_be32(fore200e->stats->aal5.congestion_experienced),
-                      cpu_to_be32(fore200e->stats->aal5.cspdus_transmitted),
-                      cpu_to_be32(fore200e->stats->aal5.cspdus_received),
-                      cpu_to_be32(fore200e->stats->aal5.cspdus_dropped),
-                      cpu_to_be32(fore200e->stats->aal5.cspdus_crc_errors),
-                      cpu_to_be32(fore200e->stats->aal5.cspdus_protocol_errors));
+                      be32_to_cpu(fore200e->stats->aal5.cells_transmitted),
+                      be32_to_cpu(fore200e->stats->aal5.cells_received),
+                      be32_to_cpu(fore200e->stats->aal5.cells_dropped),
+                      be32_to_cpu(fore200e->stats->aal5.congestion_experienced),
+                      be32_to_cpu(fore200e->stats->aal5.cspdus_transmitted),
+                      be32_to_cpu(fore200e->stats->aal5.cspdus_received),
+                      be32_to_cpu(fore200e->stats->aal5.cspdus_dropped),
+                      be32_to_cpu(fore200e->stats->aal5.cspdus_crc_errors),
+                      be32_to_cpu(fore200e->stats->aal5.cspdus_protocol_errors));
     
     if (!left--)
        return sprintf(page,"\n"
@@ -3072,11 +3054,11 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
                       "     large b2:\t\t\t%10u\n"
                       "     RX PDUs:\t\t\t%10u\n"
                       "     TX PDUs:\t\t\t%10lu\n",
-                      cpu_to_be32(fore200e->stats->aux.small_b1_failed),
-                      cpu_to_be32(fore200e->stats->aux.large_b1_failed),
-                      cpu_to_be32(fore200e->stats->aux.small_b2_failed),
-                      cpu_to_be32(fore200e->stats->aux.large_b2_failed),
-                      cpu_to_be32(fore200e->stats->aux.rpd_alloc_failed),
+                      be32_to_cpu(fore200e->stats->aux.small_b1_failed),
+                      be32_to_cpu(fore200e->stats->aux.large_b1_failed),
+                      be32_to_cpu(fore200e->stats->aux.small_b2_failed),
+                      be32_to_cpu(fore200e->stats->aux.large_b2_failed),
+                      be32_to_cpu(fore200e->stats->aux.rpd_alloc_failed),
                       fore200e->tx_sat);
     
     if (!left--)
@@ -3143,19 +3125,9 @@ static const struct atmdev_ops fore200e_ops =
 };
 
 
-#ifdef CONFIG_ATM_FORE200E_PCA
-extern const unsigned char _fore200e_pca_fw_data[];
-extern const unsigned int  _fore200e_pca_fw_size;
-#endif
-#ifdef CONFIG_ATM_FORE200E_SBA
-extern const unsigned char _fore200e_sba_fw_data[];
-extern const unsigned int  _fore200e_sba_fw_size;
-#endif
-
 static const struct fore200e_bus fore200e_bus[] = {
-#ifdef CONFIG_ATM_FORE200E_PCA
+#ifdef CONFIG_PCI
     { "PCA-200E", "pca200e", 32, 4, 32, 
-      _fore200e_pca_fw_data, &_fore200e_pca_fw_size,
       fore200e_pca_read,
       fore200e_pca_write,
       fore200e_pca_dma_map,
@@ -3164,7 +3136,6 @@ static const struct fore200e_bus fore200e_bus[] = {
       fore200e_pca_dma_sync_for_device,
       fore200e_pca_dma_chunk_alloc,
       fore200e_pca_dma_chunk_free,
-      NULL,
       fore200e_pca_configure,
       fore200e_pca_map,
       fore200e_pca_reset,
@@ -3176,9 +3147,8 @@ static const struct fore200e_bus fore200e_bus[] = {
       fore200e_pca_proc_read,
     },
 #endif
-#ifdef CONFIG_ATM_FORE200E_SBA
+#ifdef CONFIG_SBUS
     { "SBA-200E", "sba200e", 32, 64, 32,
-      _fore200e_sba_fw_data, &_fore200e_sba_fw_size,
       fore200e_sba_read,
       fore200e_sba_write,
       fore200e_sba_dma_map,
@@ -3187,7 +3157,6 @@ static const struct fore200e_bus fore200e_bus[] = {
       fore200e_sba_dma_sync_for_device,
       fore200e_sba_dma_chunk_alloc,
       fore200e_sba_dma_chunk_free,
-      fore200e_sba_detect, 
       fore200e_sba_configure,
       fore200e_sba_map,
       fore200e_sba_reset,
@@ -3202,6 +3171,14 @@ static const struct fore200e_bus fore200e_bus[] = {
     {}
 };
 
-#ifdef MODULE_LICENSE
 MODULE_LICENSE("GPL");
+#ifdef CONFIG_PCI
+#ifdef __LITTLE_ENDIAN__
+MODULE_FIRMWARE("pca200e.bin");
+#else
+MODULE_FIRMWARE("pca200e_ecd.bin2");
+#endif
+#endif /* CONFIG_PCI */
+#ifdef CONFIG_SBUS
+MODULE_FIRMWARE("sba200e_ecd.bin2");
 #endif