lkml.org 
[lkml]   [2003]   [May]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
Subject[PATCH 2.5] irq fixes for wavelan_cs/netwave_cs
From
	Hi,

This patch for 2.5.68-bk11 will fix the irq handler of some
obsolete wireless drivers (wavelan, wavelan_cs and netwave_cs) plus
assorted fixes. All those drivers have been tested on a SMP box.

Have fun...

Jean


diff -u -p linux/drivers/net/wireless-badirq/netwave_cs.c linux/drivers/net/wireless/netwave_cs.c
--- linux/drivers/net/wireless-badirq/netwave_cs.c Thu May 1 15:55:19 2003
+++ linux/drivers/net/wireless/netwave_cs.c Thu May 1 16:49:47 2003
@@ -227,7 +227,7 @@ static int netwave_start_xmit( struct sk
static int netwave_rx( struct net_device *dev);

/* Interrupt routines */
-static void netwave_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t netwave_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static void netwave_watchdog(struct net_device *);

/* Statistics */
@@ -1456,7 +1456,7 @@ static int netwave_start_xmit(struct sk_
* ready to transmit another packet.
* 3. A command has completed execution.
*/
-static void netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs) {
+static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs) {
ioaddr_t iobase;
u_char *ramBase;
struct net_device *dev = (struct net_device *)dev_id;
@@ -1465,7 +1465,7 @@ static void netwave_interrupt(int irq, v
int i;

if (!netif_device_present(dev))
- return;
+ return IRQ_NONE;

iobase = dev->base_addr;
ramBase = priv->ramBase;
@@ -1476,7 +1476,7 @@ static void netwave_interrupt(int irq, v

wait_WOC(iobase);
if (!(inb(iobase+NETWAVE_REG_CCSR) & 0x02))
- break; /* None of the interrupt sources asserted */
+ break; /* None of the interrupt sources asserted (normal exit) */

status = inb(iobase + NETWAVE_REG_ASR);

@@ -1569,6 +1569,8 @@ static void netwave_interrupt(int irq, v
}
*/
}
+ /* Handled if we looped at least one time - Jean II */
+ return IRQ_RETVAL(i);
} /* netwave_interrupt */

/*
diff -u -p linux/drivers/net/wireless-badirq/wavelan.c linux/drivers/net/wireless/wavelan.c
--- linux/drivers/net/wireless-badirq/wavelan.c Thu May 1 15:55:19 2003
+++ linux/drivers/net/wireless/wavelan.c Thu May 1 18:21:04 2003
@@ -2884,10 +2884,6 @@ static inline int wv_packet_write(device
length);
#endif

- /* Do we need some padding? */
- if (clen < ETH_ZLEN)
- clen = ETH_ZLEN;
-
spin_lock_irqsave(&lp->spinlock, flags);

/* Check nothing bad has happened */
@@ -3008,12 +3004,6 @@ static int wavelan_packet_xmit(struct sk
(unsigned) skb);
#endif

- if (skb->len < ETH_ZLEN) {
- skb = skb_padto(skb, ETH_ZLEN);
- if (skb == NULL)
- return 0;
- }
-
/*
* Block a timer-based transmit from overlapping.
* In other words, prevent reentering this routine.
@@ -3035,6 +3025,17 @@ static int wavelan_packet_xmit(struct sk
if (skb->next)
printk(KERN_INFO "skb has next\n");
#endif
+
+ /* Do we need some padding? */
+ /* Note : on wireless the propagation time is in the order of 1us,
+ * and we don't have the Ethernet specific requirement of beeing
+ * able to detect collisions, therefore in theory we don't really
+ * need to pad. Jean II */
+ if (skb->len < ETH_ZLEN) {
+ skb = skb_padto(skb, ETH_ZLEN);
+ if (skb == NULL)
+ return 0;
+ }

/* Write packet on the card */
if(wv_packet_write(dev, skb->data, skb->len))
diff -u -p linux/drivers/net/wireless-badirq/wavelan_cs.c linux/drivers/net/wireless/wavelan_cs.c
--- linux/drivers/net/wireless-badirq/wavelan_cs.c Thu May 1 15:55:19 2003
+++ linux/drivers/net/wireless/wavelan_cs.c Thu May 1 18:08:17 2003
@@ -3581,10 +3581,6 @@ wv_packet_write(device * dev,

spin_lock_irqsave(&lp->spinlock, flags);

- /* Check if we need some padding */
- if(clen < ETH_ZLEN)
- clen = ETH_ZLEN;
-
/* Write the length of data buffer followed by the buffer */
outb(xmtdata_base & 0xff, PIORL(base));
outb(((xmtdata_base >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
@@ -3664,6 +3660,17 @@ wavelan_packet_xmit(struct sk_buff * skb
printk(KERN_INFO "skb has next\n");
#endif

+ /* Check if we need some padding */
+ /* Note : on wireless the propagation time is in the order of 1us,
+ * and we don't have the Ethernet specific requirement of beeing
+ * able to detect collisions, therefore in theory we don't really
+ * need to pad. Jean II */
+ if (skb->len < ETH_ZLEN) {
+ skb = skb_padto(skb, ETH_ZLEN);
+ if (skb == NULL)
+ return 0;
+ }
+
wv_packet_write(dev, skb->data, skb->len);

dev_kfree_skb(skb);
@@ -4644,7 +4651,7 @@ wv_flush_stale_links(void)
* ready to transmit another packet.
* 3. A command has completed execution.
*/
-static void
+static irqreturn_t
wavelan_interrupt(int irq,
void * dev_id,
struct pt_regs * regs)
@@ -4661,7 +4668,7 @@ wavelan_interrupt(int irq,
printk(KERN_WARNING "wavelan_interrupt(): irq %d for unknown device.\n",
irq);
#endif
- return;
+ return IRQ_NONE;
}

#ifdef DEBUG_INTERRUPT_TRACE
@@ -4883,6 +4890,24 @@ wavelan_interrupt(int irq,
#ifdef DEBUG_INTERRUPT_TRACE
printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name);
#endif
+
+ /* We always return IRQ_HANDLED, because we will receive empty
+ * interrupts under normal operations. Anyway, it doesn't matter
+ * as we are dealing with an ISA interrupt that can't be shared.
+ *
+ * Explanation : under heavy receive, the following happens :
+ * ->wavelan_interrupt()
+ * (status0 & SR0_INTERRUPT) != 0
+ * ->wv_packet_rcv()
+ * (status0 & SR0_INTERRUPT) != 0
+ * ->wv_packet_rcv()
+ * (status0 & SR0_INTERRUPT) == 0 // i.e. no more event
+ * <-wavelan_interrupt()
+ * ->wavelan_interrupt()
+ * (status0 & SR0_INTERRUPT) == 0 // i.e. empty interrupt
+ * <-wavelan_interrupt()
+ * Jean II */
+ return IRQ_HANDLED;
} /* wv_interrupt */

/*------------------------------------------------------------------*/
diff -u -p linux/drivers/net/wireless-badirq/wavelan_cs.p.h linux/drivers/net/wireless/wavelan_cs.p.h
--- linux/drivers/net/wireless-badirq/wavelan_cs.p.h Mon Mar 24 14:01:18 2003
+++ linux/drivers/net/wireless/wavelan_cs.p.h Thu May 1 17:55:25 2003
@@ -686,11 +686,6 @@ void wv_roam_init(struct net_device *dev
void wv_roam_cleanup(struct net_device *dev);
#endif /* WAVELAN_ROAMING */

-/* ----------------------- MISC SUBROUTINES ------------------------ */
-static void
- cs_error(client_handle_t, /* Report error to cardmgr */
- int,
- int);
/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
static inline u_char /* data */
hasr_read(u_long); /* Read the host interface : base address */
@@ -791,7 +786,7 @@ static void
wv_pcmcia_release(u_long), /* Remove a device */
wv_flush_stale_links(void); /* "detach" all possible devices */
/* ---------------------- INTERRUPT HANDLING ---------------------- */
-static void
+static irqreturn_t
wavelan_interrupt(int, /* Interrupt handler */
void *,
struct pt_regs *);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:35    [W:0.035 / U:0.264 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site