Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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);
		}
	}
}