Commit feea1db2 authored by Maciej W. Rozycki's avatar Maciej W. Rozycki Committed by Jeff Garzik

[PATCH] defxx: Use irqreturn_t for the interrupt handler

This is a fix for the interrupt handler in the defxx driver to use
irqreturn_t.  Beside the obvious fix of returning a proper status at all,
it actually checks board registers as appropriate for determining if an
interrupt has been recorded in the bus-specific interface logic.

The patch also includes an obvious one-line fix for SET_NETDEV_DEV needed
for the EISA variation, for which I've decided there is no point in sending
separately.
Signed-off-by: default avatarMaciej W. Rozycki <macro@linux-mips.org>
Cc: Jeff Garzik <jgarzik@pobox.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
parent 16b110c3
...@@ -191,6 +191,7 @@ ...@@ -191,6 +191,7 @@
* Feb 2001 davej PCI enable cleanups. * Feb 2001 davej PCI enable cleanups.
* 04 Aug 2003 macro Converted to the DMA API. * 04 Aug 2003 macro Converted to the DMA API.
* 14 Aug 2004 macro Fix device names reported. * 14 Aug 2004 macro Fix device names reported.
* 14 Jun 2005 macro Use irqreturn_t.
*/ */
/* Include files */ /* Include files */
...@@ -217,8 +218,8 @@ ...@@ -217,8 +218,8 @@
/* Version information string should be updated prior to each new release! */ /* Version information string should be updated prior to each new release! */
#define DRV_NAME "defxx" #define DRV_NAME "defxx"
#define DRV_VERSION "v1.07" #define DRV_VERSION "v1.08"
#define DRV_RELDATE "2004/08/14" #define DRV_RELDATE "2005/06/14"
static char version[] __devinitdata = static char version[] __devinitdata =
DRV_NAME ": " DRV_VERSION " " DRV_RELDATE DRV_NAME ": " DRV_VERSION " " DRV_RELDATE
...@@ -247,7 +248,8 @@ static int dfx_close(struct net_device *dev); ...@@ -247,7 +248,8 @@ static int dfx_close(struct net_device *dev);
static void dfx_int_pr_halt_id(DFX_board_t *bp); static void dfx_int_pr_halt_id(DFX_board_t *bp);
static void dfx_int_type_0_process(DFX_board_t *bp); static void dfx_int_type_0_process(DFX_board_t *bp);
static void dfx_int_common(struct net_device *dev); static void dfx_int_common(struct net_device *dev);
static void dfx_interrupt(int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t dfx_interrupt(int irq, void *dev_id,
struct pt_regs *regs);
static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev); static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev);
static void dfx_ctl_set_multicast_list(struct net_device *dev); static void dfx_ctl_set_multicast_list(struct net_device *dev);
...@@ -437,6 +439,7 @@ static int __devinit dfx_init_one_pci_or_eisa(struct pci_dev *pdev, long ioaddr) ...@@ -437,6 +439,7 @@ static int __devinit dfx_init_one_pci_or_eisa(struct pci_dev *pdev, long ioaddr)
} }
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
if (pdev != NULL)
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
bp = dev->priv; bp = dev->priv;
...@@ -1225,7 +1228,7 @@ static int dfx_open(struct net_device *dev) ...@@ -1225,7 +1228,7 @@ static int dfx_open(struct net_device *dev)
/* Register IRQ - support shared interrupts by passing device ptr */ /* Register IRQ - support shared interrupts by passing device ptr */
ret = request_irq(dev->irq, (void *)dfx_interrupt, SA_SHIRQ, dev->name, dev); ret = request_irq(dev->irq, dfx_interrupt, SA_SHIRQ, dev->name, dev);
if (ret) { if (ret) {
printk(KERN_ERR "%s: Requested IRQ %d is busy\n", dev->name, dev->irq); printk(KERN_ERR "%s: Requested IRQ %d is busy\n", dev->name, dev->irq);
return ret; return ret;
...@@ -1685,7 +1688,7 @@ static void dfx_int_common(struct net_device *dev) ...@@ -1685,7 +1688,7 @@ static void dfx_int_common(struct net_device *dev)
* Interrupt processing routine * Interrupt processing routine
* *
* Returns: * Returns:
* None * Whether a valid interrupt was seen.
* *
* Arguments: * Arguments:
* irq - interrupt vector * irq - interrupt vector
...@@ -1699,7 +1702,8 @@ static void dfx_int_common(struct net_device *dev) ...@@ -1699,7 +1702,8 @@ static void dfx_int_common(struct net_device *dev)
* structure context. * structure context.
* *
* Return Codes: * Return Codes:
* None * IRQ_HANDLED - an IRQ was handled.
* IRQ_NONE - no IRQ was handled.
* *
* Assumptions: * Assumptions:
* The interrupt acknowledgement at the hardware level (eg. ACKing the PIC * The interrupt acknowledgement at the hardware level (eg. ACKing the PIC
...@@ -1712,60 +1716,70 @@ static void dfx_int_common(struct net_device *dev) ...@@ -1712,60 +1716,70 @@ static void dfx_int_common(struct net_device *dev)
* Interrupts are disabled, then reenabled at the adapter. * Interrupts are disabled, then reenabled at the adapter.
*/ */
static void dfx_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t dfx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct net_device *dev = dev_id; struct net_device *dev = dev_id;
DFX_board_t *bp; /* private board structure pointer */ DFX_board_t *bp; /* private board structure pointer */
u8 tmp; /* used for disabling/enabling ints */
/* Get board pointer only if device structure is valid */ /* Get board pointer only if device structure is valid */
bp = dev->priv; bp = dev->priv;
spin_lock(&bp->lock);
/* See if we're already servicing an interrupt */ /* See if we're already servicing an interrupt */
/* Service adapter interrupts */ /* Service adapter interrupts */
if (bp->bus_type == DFX_BUS_TYPE_PCI) if (bp->bus_type == DFX_BUS_TYPE_PCI) {
{ u32 status;
/* Disable PDQ-PFI interrupts at PFI */
dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL, PFI_MODE_M_DMA_ENB); dfx_port_read_long(bp, PFI_K_REG_STATUS, &status);
if (!(status & PFI_STATUS_M_PDQ_INT))
return IRQ_NONE;
/* Call interrupt service routine for this adapter */ spin_lock(&bp->lock);
/* Disable PDQ-PFI interrupts at PFI */
dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL,
PFI_MODE_M_DMA_ENB);
/* Call interrupt service routine for this adapter */
dfx_int_common(dev); dfx_int_common(dev);
/* Clear PDQ interrupt status bit and reenable interrupts */ /* Clear PDQ interrupt status bit and reenable interrupts */
dfx_port_write_long(bp, PFI_K_REG_STATUS,
dfx_port_write_long(bp, PFI_K_REG_STATUS, PFI_STATUS_M_PDQ_INT); PFI_STATUS_M_PDQ_INT);
dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL, dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL,
(PFI_MODE_M_PDQ_INT_ENB + PFI_MODE_M_DMA_ENB)); (PFI_MODE_M_PDQ_INT_ENB |
} PFI_MODE_M_DMA_ENB));
else
{
/* Disable interrupts at the ESIC */
dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &tmp); spin_unlock(&bp->lock);
tmp &= ~PI_CONFIG_STAT_0_M_INT_ENB; } else {
dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, tmp); u8 status;
/* Call interrupt service routine for this adapter */ dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &status);
if (!(status & PI_CONFIG_STAT_0_M_PEND))
return IRQ_NONE;
spin_lock(&bp->lock);
/* Disable interrupts at the ESIC */
status &= ~PI_CONFIG_STAT_0_M_INT_ENB;
dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, status);
/* Call interrupt service routine for this adapter */
dfx_int_common(dev); dfx_int_common(dev);
/* Reenable interrupts at the ESIC */ /* Reenable interrupts at the ESIC */
dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &status);
dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &tmp); status |= PI_CONFIG_STAT_0_M_INT_ENB;
tmp |= PI_CONFIG_STAT_0_M_INT_ENB; dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, status);
dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, tmp);
}
spin_unlock(&bp->lock); spin_unlock(&bp->lock);
} }
return IRQ_HANDLED;
}
/* /*
* ===================== * =====================
......
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