X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fatm%2Ffore200e.c;h=05983a312d504033745e65938cd87899c75e0605;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=b2f13752cb518998e65652091534ea087a1470f3;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index b2f13752c..05983a312 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -95,10 +96,6 @@ #define FORE200E_NEXT_ENTRY(index, modulo) (index = ++(index) % (modulo)) - -#define MSECS(ms) (((ms)*HZ/1000)+1) - - #if 1 #define ASSERT(expr) if (!(expr)) { \ printk(FORE200E "assertion failed! %s[%d]: %s\n", \ @@ -113,7 +110,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"); @@ -181,14 +178,12 @@ fore200e_irq_itoa(int irq) static void* -fore200e_kmalloc(int size, int flags) +fore200e_kmalloc(int size, gfp_t flags) { - void* chunk = kmalloc(size, flags); + void *chunk = kzalloc(size, flags); - if (chunk) - memset(chunk, 0x00, size); - else - printk(FORE200E "kmalloc() failed, requested size = %d, flags = 0x%x\n", size, flags); + if (!chunk) + printk(FORE200E "kmalloc() failed, requested size = %d, flags = 0x%x\n", size, flags); return chunk; } @@ -245,7 +240,7 @@ fore200e_chunk_free(struct fore200e* fore200e, struct chunk* chunk) static void fore200e_spin(int msecs) { - unsigned long timeout = jiffies + MSECS(msecs); + unsigned long timeout = jiffies + msecs_to_jiffies(msecs); while (time_before(jiffies, timeout)); } @@ -253,7 +248,7 @@ fore200e_spin(int msecs) static int fore200e_poll(struct fore200e* fore200e, volatile u32* addr, u32 val, int msecs) { - unsigned long timeout = jiffies + MSECS(msecs); + unsigned long timeout = jiffies + msecs_to_jiffies(msecs); int ok; mb(); @@ -275,9 +270,9 @@ fore200e_poll(struct fore200e* fore200e, volatile u32* addr, u32 val, int msecs) static int -fore200e_io_poll(struct fore200e* fore200e, volatile u32* addr, u32 val, int msecs) +fore200e_io_poll(struct fore200e* fore200e, volatile u32 __iomem *addr, u32 val, int msecs) { - unsigned long timeout = jiffies + MSECS(msecs); + unsigned long timeout = jiffies + msecs_to_jiffies(msecs); int ok; do { @@ -347,7 +342,7 @@ fore200e_reset(struct fore200e* fore200e, int diag) { int ok; - fore200e->cp_monitor = (struct cp_monitor*)(fore200e->virt_base + FORE200E_CP_MONITOR_OFFSET); + fore200e->cp_monitor = fore200e->virt_base + FORE200E_CP_MONITOR_OFFSET; fore200e->bus->write(BSTAT_COLD_START, &fore200e->cp_monitor->bstat); @@ -386,8 +381,7 @@ fore200e_shutdown(struct fore200e* fore200e) switch(fore200e->state) { case FORE200E_STATE_COMPLETE: - if (fore200e->stats) - kfree(fore200e->stats); + kfree(fore200e->stats); case FORE200E_STATE_IRQ: free_irq(fore200e->irq, fore200e->atm_dev); @@ -440,7 +434,7 @@ fore200e_shutdown(struct fore200e* fore200e) #ifdef CONFIG_ATM_FORE200E_PCA -static u32 fore200e_pca_read(volatile u32* addr) +static u32 fore200e_pca_read(volatile u32 __iomem *addr) { /* on big-endian hosts, the board is configured to convert the endianess of slave RAM accesses */ @@ -448,7 +442,7 @@ static u32 fore200e_pca_read(volatile u32* addr) } -static void fore200e_pca_write(u32 val, volatile u32* addr) +static void fore200e_pca_write(u32 val, volatile u32 __iomem *addr) { /* on big-endian hosts, the board is configured to convert the endianess of slave RAM accesses */ @@ -561,7 +555,7 @@ fore200e_pca_reset(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_pca_map(struct fore200e* fore200e) { DPRINTK(2, "device %s being mapped in memory\n", fore200e->name); @@ -576,9 +570,9 @@ fore200e_pca_map(struct fore200e* fore200e) DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base); /* gain access to the PCA specific registers */ - fore200e->regs.pca.hcr = (u32*)(fore200e->virt_base + PCA200E_HCR_OFFSET); - fore200e->regs.pca.imr = (u32*)(fore200e->virt_base + PCA200E_IMR_OFFSET); - fore200e->regs.pca.psr = (u32*)(fore200e->virt_base + PCA200E_PSR_OFFSET); + fore200e->regs.pca.hcr = fore200e->virt_base + PCA200E_HCR_OFFSET; + fore200e->regs.pca.imr = fore200e->virt_base + PCA200E_IMR_OFFSET; + fore200e->regs.pca.psr = fore200e->virt_base + PCA200E_PSR_OFFSET; fore200e->state = FORE200E_STATE_MAP; return 0; @@ -595,7 +589,7 @@ fore200e_pca_unmap(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_pca_configure(struct fore200e* fore200e) { struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev; @@ -636,39 +630,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) { @@ -689,7 +650,7 @@ fore200e_pca_prom_read(struct fore200e* fore200e, struct prom_data* prom) *entry->status = STATUS_PENDING; - fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.prom_block.opcode); + fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.prom_block.opcode); ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400); @@ -730,14 +691,14 @@ fore200e_pca_proc_read(struct fore200e* fore200e, char *page) #ifdef CONFIG_ATM_FORE200E_SBA static u32 -fore200e_sba_read(volatile u32* addr) +fore200e_sba_read(volatile u32 __iomem *addr) { return sbus_readl(addr); } static void -fore200e_sba_write(u32 val, volatile u32* addr) +fore200e_sba_write(u32 val, volatile u32 __iomem *addr) { sbus_writel(val, addr); } @@ -856,10 +817,10 @@ fore200e_sba_map(struct fore200e* fore200e) unsigned int bursts; /* gain access to the SBA specific registers */ - fore200e->regs.sba.hcr = (u32*)sbus_ioremap(&sbus_dev->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR"); - fore200e->regs.sba.bsr = (u32*)sbus_ioremap(&sbus_dev->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR"); - fore200e->regs.sba.isr = (u32*)sbus_ioremap(&sbus_dev->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR"); - fore200e->virt_base = (u32*)sbus_ioremap(&sbus_dev->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM"); + 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"); if (fore200e->virt_base == NULL) { printk(FORE200E "unable to map RAM of device %s\n", fore200e->name); @@ -884,10 +845,10 @@ fore200e_sba_map(struct fore200e* fore200e) static void fore200e_sba_unmap(struct fore200e* fore200e) { - sbus_iounmap((ulong)fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH); - sbus_iounmap((ulong)fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH); - sbus_iounmap((ulong)fore200e->regs.sba.isr, SBA200E_ISR_LENGTH); - sbus_iounmap((ulong)fore200e->virt_base, SBA200E_RAM_LENGTH); + 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); } @@ -999,8 +960,7 @@ fore200e_tx_irq(struct fore200e* fore200e) entry, txq->tail, entry->vc_map, entry->skb); /* free copy of misaligned data */ - if (entry->data) - kfree(entry->data); + kfree(entry->data); /* remove DMA mapping */ fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length, @@ -1026,7 +986,7 @@ fore200e_tx_irq(struct fore200e* fore200e) /* when a vcc is closed, some PDUs may be still pending in the tx queue. if the same vcc is immediately re-opened, those pending PDUs must not be popped after the completion of their emission, as they refer - to the prior incarnation of that vcc. otherwise, vcc->sk->sk_wmem_alloc + to the prior incarnation of that vcc. otherwise, sk_atm(vcc)->sk_wmem_alloc would be decremented by the size of the (unrelated) skb, possibly leading to a negative sk->sk_wmem_alloc count, ultimately freezing the vcc. we thus bind the tx entry to the current incarnation of the vcc @@ -1053,8 +1013,8 @@ fore200e_tx_irq(struct fore200e* fore200e) } #if 1 /* race fixed by the above incarnation mechanism, but... */ - if (atomic_read(&vcc->sk->sk_wmem_alloc) < 0) { - atomic_set(&vcc->sk->sk_wmem_alloc, 0); + if (atomic_read(&sk_atm(vcc)->sk_wmem_alloc) < 0) { + atomic_set(&sk_atm(vcc)->sk_wmem_alloc, 0); } #endif /* check error condition */ @@ -1214,7 +1174,7 @@ fore200e_push_rpd(struct fore200e* fore200e, struct atm_vcc* vcc, struct rpd* rp return -ENOMEM; } - do_gettimeofday(&skb->stamp); + __net_timestamp(skb); #ifdef FORE200E_52BYTE_AAL0_SDU if (cell_header) { @@ -1257,12 +1217,12 @@ fore200e_push_rpd(struct fore200e* fore200e, struct atm_vcc* vcc, struct rpd* rp return -ENOMEM; } - ASSERT(atomic_read(&vcc->sk->sk_wmem_alloc) >= 0); + ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0); vcc->push(vcc, skb); atomic_inc(&vcc->stats->rx); - ASSERT(atomic_read(&vcc->sk->sk_wmem_alloc) >= 0); + ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0); return 0; } @@ -1477,12 +1437,12 @@ fore200e_activate_vcin(struct fore200e* fore200e, int activate, struct atm_vcc* #endif /* the MTU is not used by the cp, except in the case of AAL0 */ fore200e->bus->write(mtu, &entry->cp_entry->cmd.activate_block.mtu); - fore200e->bus->write(*(u32*)&vpvc, (u32*)&entry->cp_entry->cmd.activate_block.vpvc); - fore200e->bus->write(*(u32*)&activ_opcode, (u32*)&entry->cp_entry->cmd.activate_block.opcode); + fore200e->bus->write(*(u32*)&vpvc, (u32 __iomem *)&entry->cp_entry->cmd.activate_block.vpvc); + fore200e->bus->write(*(u32*)&activ_opcode, (u32 __iomem *)&entry->cp_entry->cmd.activate_block.opcode); } else { - fore200e->bus->write(*(u32*)&vpvc, (u32*)&entry->cp_entry->cmd.deactivate_block.vpvc); - fore200e->bus->write(*(u32*)&deactiv_opcode, (u32*)&entry->cp_entry->cmd.deactivate_block.opcode); + fore200e->bus->write(*(u32*)&vpvc, (u32 __iomem *)&entry->cp_entry->cmd.deactivate_block.vpvc); + fore200e->bus->write(*(u32*)&deactiv_opcode, (u32 __iomem *)&entry->cp_entry->cmd.deactivate_block.opcode); } ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400); @@ -1699,7 +1659,7 @@ fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb) unsigned long flags; ASSERT(vcc); - ASSERT(atomic_read(&vcc->sk->sk_wmem_alloc) >= 0); + ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0); ASSERT(fore200e); ASSERT(fore200e_vcc); @@ -1779,7 +1739,7 @@ fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb) /* retry once again? */ if (--retry > 0) { - schedule(); + udelay(50); goto retry_here; } @@ -1858,7 +1818,7 @@ fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb) tpd_haddr.haddr = entry->tpd_dma >> TPD_HADDR_SHIFT; /* shift the address, as we are in a bitfield */ *entry->status = STATUS_PENDING; - fore200e->bus->write(*(u32*)&tpd_haddr, (u32*)&entry->cp_entry->tpd_haddr); + fore200e->bus->write(*(u32*)&tpd_haddr, (u32 __iomem *)&entry->cp_entry->tpd_haddr); spin_unlock_irqrestore(&fore200e->q_lock, flags); @@ -1893,7 +1853,7 @@ fore200e_getstats(struct fore200e* fore200e) *entry->status = STATUS_PENDING; - fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.stats_block.opcode); + fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.stats_block.opcode); ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400); @@ -1996,7 +1956,7 @@ fore200e_set_oc3(struct fore200e* fore200e, u32 reg, u32 value, u32 mask) *entry->status = STATUS_PENDING; - fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.oc3_block.opcode); + fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.oc3_block.opcode); ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400); @@ -2165,7 +2125,7 @@ fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags) } -static int __init +static int __devinit fore200e_irq_request(struct fore200e* fore200e) { if (request_irq(fore200e->irq, fore200e_interrupt, SA_SHIRQ, fore200e->name, fore200e->atm_dev) < 0) { @@ -2188,7 +2148,7 @@ fore200e_irq_request(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_get_esi(struct fore200e* fore200e) { struct prom_data* prom = fore200e_kmalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA); @@ -2220,7 +2180,7 @@ fore200e_get_esi(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_alloc_rx_buf(struct fore200e* fore200e) { int scheme, magn, nbr, size, i; @@ -2285,13 +2245,13 @@ fore200e_alloc_rx_buf(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init_bs_queue(struct fore200e* fore200e) { int scheme, magn, i; struct host_bsq* bsq; - struct cp_bsq_entry* cp_entry; + struct cp_bsq_entry __iomem * cp_entry; for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) { for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) { @@ -2321,8 +2281,8 @@ fore200e_init_bs_queue(struct fore200e* fore200e) } /* get the base address of the cp resident buffer supply queue entries */ - cp_entry = (struct cp_bsq_entry*)(fore200e->virt_base + - fore200e->bus->read(&fore200e->cp_queues->cp_bsq[ scheme ][ magn ])); + cp_entry = fore200e->virt_base + + fore200e->bus->read(&fore200e->cp_queues->cp_bsq[ scheme ][ magn ]); /* fill the host resident and cp resident buffer supply queue entries */ for (i = 0; i < QUEUE_SIZE_BS; i++) { @@ -2348,11 +2308,11 @@ fore200e_init_bs_queue(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init_rx_queue(struct fore200e* fore200e) { struct host_rxq* rxq = &fore200e->host_rxq; - struct cp_rxq_entry* cp_entry; + struct cp_rxq_entry __iomem * cp_entry; int i; DPRINTK(2, "receive queue is being initialized\n"); @@ -2378,8 +2338,7 @@ fore200e_init_rx_queue(struct fore200e* fore200e) } /* get the base address of the cp resident rx queue entries */ - cp_entry = (struct cp_rxq_entry*)(fore200e->virt_base + - fore200e->bus->read(&fore200e->cp_queues->cp_rxq)); + cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_rxq); /* fill the host resident and cp resident rx entries */ for (i=0; i < QUEUE_SIZE_RX; i++) { @@ -2409,11 +2368,11 @@ fore200e_init_rx_queue(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init_tx_queue(struct fore200e* fore200e) { struct host_txq* txq = &fore200e->host_txq; - struct cp_txq_entry* cp_entry; + struct cp_txq_entry __iomem * cp_entry; int i; DPRINTK(2, "transmit queue is being initialized\n"); @@ -2439,8 +2398,7 @@ fore200e_init_tx_queue(struct fore200e* fore200e) } /* get the base address of the cp resident tx queue entries */ - cp_entry = (struct cp_txq_entry*)(fore200e->virt_base + - fore200e->bus->read(&fore200e->cp_queues->cp_txq)); + cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_txq); /* fill the host resident and cp resident tx entries */ for (i=0; i < QUEUE_SIZE_TX; i++) { @@ -2473,11 +2431,11 @@ fore200e_init_tx_queue(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init_cmd_queue(struct fore200e* fore200e) { struct host_cmdq* cmdq = &fore200e->host_cmdq; - struct cp_cmdq_entry* cp_entry; + struct cp_cmdq_entry __iomem * cp_entry; int i; DPRINTK(2, "command queue is being initialized\n"); @@ -2492,8 +2450,7 @@ fore200e_init_cmd_queue(struct fore200e* fore200e) } /* get the base address of the cp resident cmd queue entries */ - cp_entry = (struct cp_cmdq_entry*)(fore200e->virt_base + - fore200e->bus->read(&fore200e->cp_queues->cp_cmdq)); + cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_cmdq); /* fill the host resident and cp resident cmd entries */ for (i=0; i < QUEUE_SIZE_CMD; i++) { @@ -2521,7 +2478,7 @@ fore200e_param_bs_queue(struct fore200e* fore200e, enum buffer_scheme scheme, enum buffer_magn magn, int queue_length, int pool_size, int supply_blksize) { - struct bs_spec* bs_spec = &fore200e->cp_queues->init.bs_spec[ scheme ][ magn ]; + struct bs_spec __iomem * bs_spec = &fore200e->cp_queues->init.bs_spec[ scheme ][ magn ]; fore200e->bus->write(queue_length, &bs_spec->queue_length); fore200e->bus->write(fore200e_rx_buf_size[ scheme ][ magn ], &bs_spec->buffer_size); @@ -2530,10 +2487,10 @@ fore200e_param_bs_queue(struct fore200e* fore200e, } -static int __init +static int __devinit fore200e_initialize(struct fore200e* fore200e) { - struct cp_queues* cpq; + struct cp_queues __iomem * cpq; int ok, scheme, magn; DPRINTK(2, "device %s being initialized\n", fore200e->name); @@ -2541,7 +2498,7 @@ fore200e_initialize(struct fore200e* fore200e) init_MUTEX(&fore200e->rate_sf); spin_lock_init(&fore200e->q_lock); - cpq = fore200e->cp_queues = (struct cp_queues*) (fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET); + cpq = fore200e->cp_queues = fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET; /* enable cp to host interrupts */ fore200e->bus->write(1, &cpq->imask); @@ -2582,10 +2539,10 @@ fore200e_initialize(struct fore200e* fore200e) } -static void __init +static void __devinit fore200e_monitor_putc(struct fore200e* fore200e, char c) { - struct cp_monitor* monitor = fore200e->cp_monitor; + struct cp_monitor __iomem * monitor = fore200e->cp_monitor; #if 0 printk("%c", c); @@ -2594,11 +2551,11 @@ fore200e_monitor_putc(struct fore200e* fore200e, char c) } -static int __init +static int __devinit fore200e_monitor_getc(struct fore200e* fore200e) { - struct cp_monitor* monitor = fore200e->cp_monitor; - unsigned long timeout = jiffies + MSECS(50); + struct cp_monitor __iomem * monitor = fore200e->cp_monitor; + unsigned long timeout = jiffies + msecs_to_jiffies(50); int c; while (time_before(jiffies, timeout)) { @@ -2619,7 +2576,7 @@ fore200e_monitor_getc(struct fore200e* fore200e) } -static void __init +static void __devinit fore200e_monitor_puts(struct fore200e* fore200e, char* str) { while (*str) { @@ -2634,7 +2591,7 @@ fore200e_monitor_puts(struct fore200e* fore200e, char* str) } -static int __init +static int __devinit fore200e_start_fw(struct fore200e* fore200e) { int ok; @@ -2665,7 +2622,7 @@ fore200e_start_fw(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_load_fw(struct fore200e* fore200e) { u32* fw_data = (u32*) fore200e->bus->fw_data; @@ -2673,7 +2630,7 @@ fore200e_load_fw(struct fore200e* fore200e) struct fw_header* fw_header = (struct fw_header*) fw_data; - u32* load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset); + u32 __iomem *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); @@ -2691,7 +2648,7 @@ fore200e_load_fw(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_register(struct fore200e* fore200e) { struct atm_dev* atm_dev; @@ -2718,7 +2675,7 @@ fore200e_register(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init(struct fore200e* fore200e) { if (fore200e_register(fore200e) < 0) @@ -2764,26 +2721,111 @@ fore200e_init(struct fore200e* fore200e) return -EBUSY; fore200e_supply(fore200e); - + /* all done, board initialization is now complete */ fore200e->state = FORE200E_STATE_COMPLETE; 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); + + 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, @@ -2797,15 +2839,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_register_driver(&fore200e_pca_driver)) + return 0; +#endif + + if (!list_empty(&fore200e_boards)) + return 0; + return -ENODEV; } @@ -2813,11 +2858,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"); @@ -2854,7 +2902,7 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) " board serial number:\t\t%d\n\n", fore200e_irq_itoa(fore200e->irq), (void*)fore200e->phys_base, - (void*)fore200e->virt_base, + fore200e->virt_base, fore200e->esi[0], fore200e->esi[1], fore200e->esi[2], fore200e->esi[3], fore200e->esi[4], fore200e->esi[5], fore200e->esi[4] * 256 + fore200e->esi[5]); @@ -2938,7 +2986,7 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) } if (!left--) { - struct cp_monitor* cp_monitor = fore200e->cp_monitor; + struct cp_monitor __iomem * cp_monitor = fore200e->cp_monitor; return sprintf(page, "\n\n" @@ -3152,7 +3200,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,