/* * Function: _interrupt * * Purpose: * Interrupt Handler. * Mask all interrupts on device and wake up interrupt * thread. It is assumed that the interrupt thread unmasks * interrupts again when interrupt handling is complete. * Parameters: * ctrl - BDE control structure for this device. * Returns: * Nothing */ static void _cmic_interrupt(bde_ctrl_t *ctrl) { int d; uint32_t mask = 0, stat, imask = 0, fmask = 0; d = (((uint8 *)ctrl - (uint8 *)_devices) / sizeof (bde_ctrl_t)); /* Check for secondary interrupt handler */ if (lkbde_irq_mask_get(d, &mask, &fmask) < 0) { fmask = 0; } if (fmask != 0) { imask = mask & ~fmask; /* Check for pending user mode interrupts */ stat = user_bde->read(d, CMIC_IRQ_STAT); if ((stat & imask) == 0) { /* All handled in kernel mode */ lkbde_irq_mask_set(d, CMIC_IRQ_MASK, imask, 0); return; } } lkbde_irq_mask_set(d, CMIC_IRQ_MASK, 0, 0); atomic_set(&_interrupt_has_taken_place, 1); #ifdef BDE_LINUX_NON_INTERRUPTIBLE wake_up(&_interrupt_wq); #else wake_up_interruptible(&_interrupt_wq); #endif }
static void _cmicd_interrupt(bde_ctrl_t *ctrl) { int d; int cmc = BDE_CMICD_PCIE_CMC; uint32 stat, mask = 0, fmask = 0, imask = 0; bde_inst_resource_t *res; d = (((uint8 *)ctrl - (uint8 *)_devices) / sizeof (bde_ctrl_t)); res = &_bde_inst_resource[ctrl->inst]; lkbde_irq_mask_get(d, &mask, &fmask); while (fmask) { stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT0_OFFSET(cmc)); imask = mask & ~fmask; if (stat & imask) { break; } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT1_OFFSET(cmc)); mask = user_bde->read(d, CMIC_CMCx_PCIE_IRQ_MASK1_OFFSET(cmc)); if (stat & mask) { break; } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT2_OFFSET(cmc)); mask = user_bde->read(d, CMIC_CMCx_PCIE_IRQ_MASK2_OFFSET(cmc)); if (stat & mask) { break; } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT3_OFFSET(cmc)); mask = user_bde->read(d, CMIC_CMCx_PCIE_IRQ_MASK3_OFFSET(cmc)); if (stat & mask) { break; } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT4_OFFSET(cmc)); mask = user_bde->read(d, CMIC_CMCx_PCIE_IRQ_MASK4_OFFSET(cmc)); if (stat & mask) { break; } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT5_OFFSET(cmc)); mask = user_bde->read(d, CMIC_CMCx_PCIE_IRQ_MASK5_OFFSET(cmc)); if (stat & mask) { break; } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT6_OFFSET(cmc)); mask = user_bde->read(d, CMIC_CMCx_PCIE_IRQ_MASK6_OFFSET(cmc)); if (stat & mask) { break; } return; } lkbde_irq_mask_set(d, CMIC_CMCx_PCIE_IRQ_MASK0_OFFSET(cmc), 0, 0); user_bde->write(d, CMIC_CMCx_PCIE_IRQ_MASK1_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_PCIE_IRQ_MASK2_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_PCIE_IRQ_MASK3_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_PCIE_IRQ_MASK4_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_PCIE_IRQ_MASK5_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_PCIE_IRQ_MASK6_OFFSET(cmc), 0); atomic_set(&res->intr, 1); #ifdef BDE_LINUX_NON_INTERRUPTIBLE wake_up(&res->intr_wq); #else wake_up_interruptible(&res->intr_wq); #endif }
static void _cmicm_interrupt(bde_ctrl_t *ctrl) { int d; int cmc = BDE_CMICM_PCIE_CMC; uint32 stat, mask = 0, fmask = 0, imask = 0; d = (((uint8 *)ctrl - (uint8 *)_devices) / sizeof (bde_ctrl_t)); lkbde_irq_mask_get(d, &mask, &fmask); while (fmask) { stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT0_OFFSET(cmc)); imask = mask & ~fmask; if (stat & imask) { break; } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT1_OFFSET(cmc)); mask = user_bde->read(d, CMIC_CMCx_PCIE_IRQ_MASK1_OFFSET(cmc)); if (stat & mask) { break; } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT2_OFFSET(cmc)); mask = user_bde->read(d, CMIC_CMCx_PCIE_IRQ_MASK2_OFFSET(cmc)); if (stat & mask) { break; } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT3_OFFSET(cmc)); mask = user_bde->read(d, CMIC_CMCx_PCIE_IRQ_MASK3_OFFSET(cmc)); if (stat & mask) { break; } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT4_OFFSET(cmc)); mask = user_bde->read(d, CMIC_CMCx_PCIE_IRQ_MASK4_OFFSET(cmc)); if (stat & mask) { break; } return; } if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { lkbde_irq_mask_set(d, CMIC_CMCx_UC0_IRQ_MASK0_OFFSET(cmc), 0, 0); user_bde->write(d, CMIC_CMCx_UC0_IRQ_MASK1_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_UC0_IRQ_MASK2_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_UC0_IRQ_MASK3_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_UC0_IRQ_MASK4_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_UC0_IRQ_MASK0_OFFSET(1), 0); user_bde->write(d, CMIC_CMCx_UC0_IRQ_MASK0_OFFSET(2), 0); } else { lkbde_irq_mask_set(d, CMIC_CMCx_PCIE_IRQ_MASK0_OFFSET(cmc), 0, 0); user_bde->write(d, CMIC_CMCx_PCIE_IRQ_MASK1_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_PCIE_IRQ_MASK2_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_PCIE_IRQ_MASK3_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_PCIE_IRQ_MASK4_OFFSET(cmc), 0); user_bde->write(d, CMIC_CMCx_PCIE_IRQ_MASK0_OFFSET(1), 0); user_bde->write(d, CMIC_CMCx_PCIE_IRQ_MASK0_OFFSET(2), 0); } atomic_set(&_interrupt_has_taken_place, 1); #ifdef BDE_LINUX_NON_INTERRUPTIBLE wake_up(&_interrupt_wq); #else wake_up_interruptible(&_interrupt_wq); #endif }