Commit 5e556524 authored by Jean Tourrilhes's avatar Jean Tourrilhes Committed by Linus Torvalds

[PATCH] irq fixes for wavelan_cs/netwave_cs

        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.
parent 9808d508
......@@ -227,7 +227,7 @@ static int netwave_start_xmit( struct sk_buff *skb, struct net_device *dev);
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_buff *skb, struct net_device *dev) {
* 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, void* dev_id, struct pt_regs *regs) {
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, void* dev_id, struct pt_regs *regs) {
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, void* dev_id, struct pt_regs *regs) {
}
*/
}
/* Handled if we looped at least one time - Jean II */
return IRQ_RETVAL(i);
} /* netwave_interrupt */
/*
......
......@@ -2884,10 +2884,6 @@ static inline int wv_packet_write(device * dev, void *buf, short length)
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_buff *skb, device * dev)
(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.
......@@ -3036,6 +3026,17 @@ static int wavelan_packet_xmit(struct sk_buff *skb, device * dev)
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))
return 1; /* We failed */
......
......@@ -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 */
/*------------------------------------------------------------------*/
......
......@@ -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 *);
......
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