patch-2.3.99-pre6 linux/drivers/atm/fore200e.c
Next file: linux/drivers/atm/fore200e.h
Previous file: linux/drivers/atm/eni.h
Back to the patch index
Back to the overall index
- Lines: 269
- Date:
Fri Apr 14 09:37:10 2000
- Orig file:
v2.3.99-pre5/linux/drivers/atm/fore200e.c
- Orig date:
Tue Apr 11 15:09:16 2000
diff -u --recursive --new-file v2.3.99-pre5/linux/drivers/atm/fore200e.c linux/drivers/atm/fore200e.c
@@ -1,8 +1,8 @@
/*
- $Id: fore200e.c,v 1.2 2000/03/21 21:19:24 davem Exp $
+ $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-February 2000.
+ Christophe Lizzi (lizzi@cnam.fr), October 1999-March 2000.
Based on the PCA-200E driver from Uwe Dannowski (Uwe.Dannowski@inf.tu-dresden.de).
@@ -32,10 +32,11 @@
#include <linux/init.h>
#include <linux/capability.h>
#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
#include <linux/atmdev.h>
#include <linux/sonet.h>
#include <linux/atm_suni.h>
-#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/string.h>
#include <asm/segment.h>
@@ -66,7 +67,7 @@
#define FORE200E_52BYTE_AAL0_SDU
#endif
-#define FORE200E_VERSION "0.2b"
+#define FORE200E_VERSION "0.2d"
#define FORE200E "fore200e: "
@@ -444,6 +445,7 @@
}
+
#ifdef CONFIG_ATM_FORE200E_PCA
static u32 fore200e_pca_read(volatile u32* addr)
@@ -477,7 +479,8 @@
static void
fore200e_pca_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
{
- DPRINTK(3, "PCI DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
+ DPRINTK(3, "PCI DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d\n",
+ dma_addr, size, direction);
pci_unmap_single((struct pci_dev*)fore200e->bus_dev, dma_addr, size, direction);
}
@@ -496,7 +499,8 @@
(to hold descriptors, status, queues, etc.) shared by the driver and the adapter */
static int
-fore200e_pca_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int nbr, int alignment)
+fore200e_pca_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk,
+ int size, int nbr, int alignment)
{
#if defined(__sparc_v9__)
/* returned chunks are page-aligned */
@@ -659,6 +663,7 @@
sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1);
+ pci_enable_device(pci_dev);
pci_set_master(pci_dev);
return fore200e;
@@ -756,7 +761,8 @@
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);
+ DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n",
+ dma_addr, size, direction);
sbus_unmap_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction);
}
@@ -775,7 +781,8 @@
(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)
+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;
@@ -1234,15 +1241,25 @@
}
DPRINTK(3, "valid interrupt on device %c\n", fore200e->name[9]);
- fore200e_irq_rx(fore200e);
+ tasklet_schedule(&fore200e->tasklet);
+
+ fore200e->bus->irq_ack(fore200e);
+}
+
+
+static void
+fore200e_tasklet(unsigned long data)
+{
+ struct fore200e* fore200e = (struct fore200e*) data;
+ fore200e_irq_rx(fore200e);
+
if (fore200e->host_txq.txing)
fore200e_irq_tx(fore200e);
-
- fore200e->bus->irq_ack(fore200e);
}
+
static int
fore200e_select_scheme(struct atm_vcc* vcc)
{
@@ -1400,7 +1417,7 @@
if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
return 0;
- set_bit(ATM_VF_ADDR,&vcc->flags);
+ set_bit(ATM_VF_ADDR, &vcc->flags);
vcc->itf = vcc->dev->number;
DPRINTK(2, "opening %d.%d.%d:%d QoS = (tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
@@ -1463,7 +1480,7 @@
fore200e_vcc->tx_min_pdu = fore200e_vcc->rx_min_pdu = 65536;
fore200e_vcc->tx_max_pdu = fore200e_vcc->rx_max_pdu = 0;
- clear_bit(ATM_VF_READY,&vcc->flags);
+ set_bit(ATM_VF_READY, &vcc->flags);
return 0;
}
@@ -1489,6 +1506,8 @@
fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
up(&fore200e->rate_sf);
}
+
+ clear_bit(ATM_VF_READY, &vcc->flags);
}
@@ -1506,7 +1525,7 @@
struct host_txq_entry* entry;
struct tpd* tpd;
struct tpd_haddr tpd_haddr;
- unsigned long flags;
+ //unsigned long flags;
int retry = CONFIG_ATM_FORE200E_TX_RETRY;
int tx_copy = 0;
int tx_len = skb->len;
@@ -1531,7 +1550,7 @@
retry_here:
- spin_lock_irqsave(&fore200e->tx_lock, flags);
+ tasklet_disable(&fore200e->tasklet);
entry = &txq->host_entry[ txq->head ];
@@ -1542,7 +1561,7 @@
if (*entry->status != STATUS_FREE) {
- spin_unlock_irqrestore(&fore200e->tx_lock, flags);
+ tasklet_enable(&fore200e->tasklet);
/* retry once again? */
if(--retry > 0)
@@ -1582,7 +1601,7 @@
entry->data = kmalloc(tx_len, GFP_ATOMIC | GFP_DMA);
if (entry->data == NULL) {
- spin_unlock_irqrestore(&fore200e->tx_lock, flags);
+ tasklet_enable(&fore200e->tasklet);
if (vcc->pop)
vcc->pop(vcc, skb);
else
@@ -1606,10 +1625,10 @@
FORE200E_NEXT_ENTRY(txq->head, QUEUE_SIZE_TX);
txq->txing++;
- spin_unlock_irqrestore(&fore200e->tx_lock, flags);
-
+ tasklet_enable(&fore200e->tasklet);
+
/* ensure DMA synchronisation */
- fore200e->bus->dma_sync(fore200e, tpd->tsd[ 0 ].buffer, tpd->tsd[ 0 ].length, FORE200E_DMA_TODEVICE);
+ fore200e->bus->dma_sync(fore200e, tpd->tsd[ 0 ].buffer, tpd->tsd[ 0 ].length, FORE200E_DMA_TODEVICE);
DPRINTK(3, "tx on %d.%d.%d:%d, len = %u (%u)\n",
vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
@@ -1934,8 +1953,7 @@
return put_user(fore200e->loop_mode, (int*)arg) ? -EFAULT : 0;
case ATM_QUERYLOOP:
- return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int*)arg) ?
- -EFAULT : 0;
+ return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int*)arg) ? -EFAULT : 0;
}
return -ENOSYS; /* not implemented */
@@ -1976,7 +1994,7 @@
/* update rate control parameters */
fore200e_rate_ctrl(qos, &fore200e_vcc->rate);
- set_bit(ATM_VF_HASQOS,&vcc->flags);
+ set_bit(ATM_VF_HASQOS, &vcc->flags);
return 0;
}
@@ -1997,6 +2015,8 @@
printk(FORE200E "IRQ %s reserved for device %s\n",
fore200e_irq_itoa(fore200e->irq), fore200e->name);
+ tasklet_init(&fore200e->tasklet, fore200e_tasklet, (unsigned long)fore200e);
+
fore200e->state = FORE200E_STATE_IRQ;
return 0;
}
@@ -2338,7 +2358,6 @@
DPRINTK(2, "device %s being initialized\n", fore200e->name);
- spin_lock_init(&fore200e->tx_lock);
init_MUTEX(&fore200e->rate_sf);
cpq = fore200e->cp_queues = (struct cp_queues*) (fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET);
@@ -2714,7 +2733,7 @@
if (media_index < 0 || media_index > 4)
media_index = 5;
- switch(fore200e->loop_mode) {
+ switch (fore200e->loop_mode) {
case ATM_LM_NONE: oc3_index = 0;
break;
case ATM_LM_LOC_PHY: oc3_index = 1;
@@ -2900,21 +2919,24 @@
#ifdef MODULE
-unsigned int
-init_module(void)
+static unsigned int __init
+fore200e_module_init(void)
{
DPRINTK(1, "module loaded\n");
return fore200e_detect() == 0;
}
-void
-cleanup_module(void)
+static void __exit
+fore200e_module_cleanup(void)
{
while (fore200e_boards) {
fore200e_cleanup(&fore200e_boards);
}
DPRINTK(1, "module being removed\n");
}
+
+module_init(fore200e_module_init);
+module_exit(fore200e_module_cleanup);
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)