/*! * \fn int xnintr_detach (xnintr_t *intr) * \brief Detach an interrupt object. * * Detach an interrupt object previously attached by * xnintr_attach(). After this operation is completed, no more IRQs * are directed to the object's ISR, but the interrupt object itself * remains valid. A detached interrupt object can be attached again by * a subsequent call to xnintr_attach(). * * @param intr The descriptor address of the interrupt object to * detach. * * @return 0 is returned on success. Otherwise: * * - -EINVAL is returned if a low-level error occurred while detaching * the interrupt, or if the interrupt object was not attached. In both * cases, no action is performed. * * @note The caller <b>must not</b> hold nklock when invoking this service, * this would cause deadlocks. * * Environments: * * This service can be called from: * * - Kernel module initialization/cleanup code * - Kernel-based task * * Rescheduling: never. */ int xnintr_detach(xnintr_t *intr) { int ret; spl_t s; trace_mark(xn_nucleus, irq_detach, "irq %u", intr->irq); xnlock_get_irqsave(&intrlock, s); if (!__testbits(intr->flags, XN_ISR_ATTACHED)) { ret = -EINVAL; goto out; } __clrbits(intr->flags, XN_ISR_ATTACHED); ret = xnintr_irq_detach(intr); if (ret) goto out; xnintr_stat_counter_dec(); out: xnlock_put_irqrestore(&intrlock, s); return ret; }
/*! * \fn int xnintr_detach (xnintr_t *intr) * \brief Detach an interrupt object. * * Detach an interrupt object previously attached by * xnintr_attach(). After this operation is completed, no more IRQs * are directed to the object's ISR, but the interrupt object itself * remains valid. A detached interrupt object can be attached again by * a subsequent call to xnintr_attach(). * * @param intr The descriptor address of the interrupt object to * detach. * * @return 0 is returned on success. Otherwise: * * - -EINVAL is returned if a low-level error occurred while detaching * the interrupt, or if the interrupt object was not attached. In both * cases, no action is performed. * * @note The caller <b>must not</b> hold nklock when invoking this service, * this would cause deadlocks. * * Environments: * * This service can be called from: * * - Kernel module initialization/cleanup code * - Kernel-based task * * Rescheduling: never. */ int xnintr_detach(xnintr_t *intr) { int ret; trace_mark(xn_nucleus, irq_detach, "irq %u", intr->irq); down(&intrlock); if (!__testbits(intr->flags, XN_ISR_ATTACHED)) { ret = -EINVAL; goto out; } __clrbits(intr->flags, XN_ISR_ATTACHED); ret = xnintr_irq_detach(intr); if (ret) goto out; xnintr_stat_counter_dec(); out: up(&intrlock); return ret; }
int xnintr_detach(xnintr_t *intr) { int err; spl_t s; xnlock_get_irqsave(&intrlock, s); err = xnintr_irq_detach(intr); xnlock_put_irqrestore(&intrlock, s); return err; }