[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: Maciej W. Rozycki <macro@linux-mips.org> Cc: Jeff Garzik <jgarzik@pobox.com> Signed-off-by: Andrew Morton <akpm@osdl.org>
This commit is contained in:
Родитель
16b110c3fd
Коммит
feea1db26e
|
@ -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 @@
|
||||||
|
|
||||||
/* 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);
|
||||||
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,7 +439,8 @@ static int __devinit dfx_init_one_pci_or_eisa(struct pci_dev *pdev, long ioaddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_MODULE_OWNER(dev);
|
SET_MODULE_OWNER(dev);
|
||||||
SET_NETDEV_DEV(dev, &pdev->dev);
|
if (pdev != NULL)
|
||||||
|
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||||
|
|
||||||
bp = dev->priv;
|
bp = dev->priv;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -1680,13 +1683,13 @@ static void dfx_int_common(struct net_device *dev)
|
||||||
* =================
|
* =================
|
||||||
* = dfx_interrupt =
|
* = dfx_interrupt =
|
||||||
* =================
|
* =================
|
||||||
*
|
*
|
||||||
* Overview:
|
* Overview:
|
||||||
* Interrupt processing routine
|
* Interrupt processing routine
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* None
|
* Whether a valid interrupt was seen.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* irq - interrupt vector
|
* irq - interrupt vector
|
||||||
* dev_id - pointer to device information
|
* dev_id - pointer to device information
|
||||||
|
@ -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)
|
||||||
* 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;
|
||||||
|
|
||||||
|
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 */
|
/* 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;
|
||||||
|
|
||||||
|
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 */
|
/* 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);
|
||||||
|
status |= PI_CONFIG_STAT_0_M_INT_ENB;
|
||||||
|
dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, status);
|
||||||
|
|
||||||
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;
|
|
||||||
dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock(&bp->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* =====================
|
* =====================
|
||||||
|
|
Загрузка…
Ссылка в новой задаче