static void myri_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct myri_eth *mp = (struct myri_eth *) dev->priv; unsigned long lregs = mp->lregs; struct myri_channel *chan = &mp->shmem->channel; u32 status; status = sbus_readl(lregs + LANAI_ISTAT); DIRQ(("myri_interrupt: status[%08x] ", status)); if (status & ISTAT_HOST) { u32 softstate; DIRQ(("IRQ_DISAB ")); myri_disable_irq(lregs, mp->cregs); softstate = sbus_readl(&chan->state); DIRQ(("state[%08x] ", softstate)); if (softstate != STATE_READY) { DIRQ(("myri_not_so_happy ")); myri_is_not_so_happy(mp); } DIRQ(("\nmyri_rx: ")); myri_rx(mp, dev); DIRQ(("\nistat=ISTAT_HOST ")); sbus_writel(ISTAT_HOST, lregs + LANAI_ISTAT); DIRQ(("IRQ_ENAB ")); myri_enable_irq(lregs, mp->cregs); } DIRQ(("\n")); }
static int myri_do_handshake(struct myri_eth *mp) { struct myri_shmem __iomem *shmem = mp->shmem; void __iomem *cregs = mp->cregs; struct myri_channel __iomem *chan = &shmem->channel; int tick = 0; DET(("myri_do_handshake: ")); if (sbus_readl(&chan->state) == STATE_READY) { DET(("Already STATE_READY, failed.\n")); return -1; /* We're hosed... */ } myri_disable_irq(mp->lregs, cregs); while (tick++ < 25) { u32 softstate; /* Wake it up. */ DET(("shakedown, CONTROL_WON, ")); sbus_writel(1, &shmem->shakedown); sbus_writel(CONTROL_WON, cregs + MYRICTRL_CTRL); softstate = sbus_readl(&chan->state); DET(("chanstate[%08x] ", softstate)); if (softstate == STATE_READY) { DET(("wakeup successful, ")); break; } if (softstate != STATE_WFN) { DET(("not WFN setting that, ")); sbus_writel(STATE_WFN, &chan->state); } udelay(20); } myri_enable_irq(mp->lregs, cregs); if (tick > 25) { DET(("25 ticks we lose, failure.\n")); return -1; } DET(("success\n")); return 0; }
static irqreturn_t myri_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; struct myri_eth *mp = netdev_priv(dev); void __iomem *lregs = mp->lregs; struct myri_channel __iomem *chan = &mp->shmem->channel; unsigned long flags; u32 status; int handled = 0; spin_lock_irqsave(&mp->irq_lock, flags); status = sbus_readl(lregs + LANAI_ISTAT); DIRQ(("myri_interrupt: status[%08x] ", status)); if (status & ISTAT_HOST) { u32 softstate; handled = 1; DIRQ(("IRQ_DISAB ")); myri_disable_irq(lregs, mp->cregs); softstate = sbus_readl(&chan->state); DIRQ(("state[%08x] ", softstate)); if (softstate != STATE_READY) { DIRQ(("myri_not_so_happy ")); myri_is_not_so_happy(mp); } DIRQ(("\nmyri_rx: ")); myri_rx(mp, dev); DIRQ(("\nistat=ISTAT_HOST ")); sbus_writel(ISTAT_HOST, lregs + LANAI_ISTAT); DIRQ(("IRQ_ENAB ")); myri_enable_irq(lregs, mp->cregs); } DIRQ(("\n")); spin_unlock_irqrestore(&mp->irq_lock, flags); return IRQ_RETVAL(handled); }