static irqreturn_t c4_handle_interrupt(avmcard *card) { unsigned long flags; u32 status; spin_lock_irqsave(&card->lock, flags); status = c4inmeml(card->mbase+DOORBELL); if (status & DBELL_RESET_HOST) { u_int i; c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c); spin_unlock_irqrestore(&card->lock, flags); if (card->nlogcontr == 0) return IRQ_HANDLED; printk(KERN_ERR "%s: unexpected reset\n", card->name); for (i=0; i < card->nr_controllers; i++) { avmctrl_info *cinfo = &card->ctrlinfo[i]; memset(cinfo->version, 0, sizeof(cinfo->version)); spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); spin_unlock_irqrestore(&card->lock, flags); capi_ctr_down(&cinfo->capi_ctrl); } card->nlogcontr = 0; return IRQ_HANDLED; } status &= (DBELL_UP_HOST | DBELL_DOWN_HOST); if (!status) { spin_unlock_irqrestore(&card->lock, flags); return IRQ_HANDLED; } c4outmeml(card->mbase+DOORBELL, status); if ((status & DBELL_UP_HOST) != 0) { card->dma->recvlen = c4inmeml(card->mbase+MBOX_UP_LEN); c4outmeml(card->mbase+MBOX_UP_LEN, 0); c4_handle_rx(card); card->dma->recvlen = 0; c4outmeml(card->mbase+MBOX_UP_LEN, card->dma->recvbuf.size); c4outmeml(card->mbase+DOORBELL, DBELL_UP_ARM); } if ((status & DBELL_DOWN_HOST) != 0) { card->csr &= ~DBELL_DOWN_ARM; c4_dispatch_tx(card); } else if (card->csr & DBELL_DOWN_HOST) { if (c4inmeml(card->mbase+MBOX_DOWN_LEN) == 0) { card->csr &= ~DBELL_DOWN_ARM; c4_dispatch_tx(card); } } spin_unlock_irqrestore(&card->lock, flags); return IRQ_HANDLED; }
static void c4_handle_interrupt(avmcard *card) { __u32 status = c4inmeml(card->mbase+DOORBELL); if (status & DBELL_RESET_HOST) { int i; c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c); if (card->nlogcontr == 0) return; printk(KERN_ERR "%s: unexpected reset\n", card->name); for (i=0; i < 4; i++) { avmctrl_info *cinfo = &card->ctrlinfo[i]; memset(cinfo->version, 0, sizeof(cinfo->version)); if (cinfo->capi_ctrl) cinfo->capi_ctrl->reseted(cinfo->capi_ctrl); } card->nlogcontr = 0; return; } status &= (DBELL_UP_HOST | DBELL_DOWN_HOST); if (!status) return; c4outmeml(card->mbase+DOORBELL, status); if ((status & DBELL_UP_HOST) != 0) { card->dma->recvlen = c4inmeml(card->mbase+MBOX_UP_LEN); c4outmeml(card->mbase+MBOX_UP_LEN, 0); c4_handle_rx(card); card->dma->recvlen = 0; c4outmeml(card->mbase+MBOX_UP_LEN, card->dma->recvbuf.size); c4outmeml(card->mbase+DOORBELL, DBELL_UP_ARM); } if ((status & DBELL_DOWN_HOST) != 0) { card->csr &= ~DBELL_DOWN_ARM; c4_dispatch_tx(card); } else if (card->csr & DBELL_DOWN_HOST) { if (c4inmeml(card->mbase+MBOX_DOWN_LEN) == 0) { card->csr &= ~DBELL_DOWN_ARM; c4_dispatch_tx(card); } } }