Ejemplo n.º 1
0
/* Unregister an interrupt handler.  */
PUBLIC void rm_irq_handler( const irq_hook_t* hook ) {
  const int irq = hook->irq; 
  const int id = hook->id;
  irq_hook_t **line;

  if( irq < 0 || irq >= NR_IRQ_VECTORS ) 
	panic("invalid call to rm_irq_handler: %d",  irq);

  /* remove the hook  */
  line = &irq_handlers[irq];
  while( (*line) != NULL ) {
	if((*line)->id == id) {
		(*line) = (*line)->next;
		if (irq_actids[irq] & id)
			irq_actids[irq] &= ~id;
    	}
    	else {
		line = &(*line)->next;
    	}
  }

  /* Disable the irq if there are no other handlers registered.
   * If the irq is shared, reenable it if there is no active handler.
   */
  if (irq_handlers[irq] == NULL) {
	hw_intr_mask(irq);
	hw_intr_not_used(irq);
  }
  else if (irq_actids[irq] == 0) {
	hw_intr_unmask(irq);
  }
}
Ejemplo n.º 2
0
/* Unregister an interrupt handler.  */
PUBLIC void rm_irq_handler( irq_hook_t* hook ) {
    int irq = hook->irq;
    int id = hook->id;
    irq_hook_t **line;

    if( irq < 0 || irq >= NR_IRQ_VECTORS )
        minix_panic("invalid call to rm_irq_handler", irq);

    /* disable the irq.  */
    irq_actids[hook->irq] |= hook->id;
    hw_intr_mask(hook->irq);

    /* remove the hook.  */
    line = &irq_handlers[irq];

    while( (*line) != NULL ) {
        if((*line)->id == id) {
            (*line) = (*line)->next;
            if(!irq_handlers[irq])
                irq_use &= ~(1 << irq);
            if (irq_actids[irq] & id)
                irq_actids[irq] &= ~id;
            return;
        }
        line = &(*line)->next;
    }
    /* When the handler is not found, normally return here. */
}
Ejemplo n.º 3
0
/*
 * The function first disables interrupt is need be and restores the state at
 * the end. Before returning, it unmasks the IRQ if and only if all active ID
 * bits are cleared, and restart a process.
 */
PUBLIC void irq_handle(int irq)
{
    irq_hook_t * hook;

    /* here we need not to get this IRQ until all the handlers had a say */
    hw_intr_mask(irq);
    hook = irq_handlers[irq];

    /* Call list of handlers for an IRQ. */
    while( hook != NULL ) {
        /* For each handler in the list, mark it active by setting its ID bit,
         * call the function, and unmark it if the function returns true.
         */
        irq_actids[irq] |= hook->id;

        /* Call the hooked function. */
        if( (*hook->handler)(hook) )
            irq_actids[hook->irq] &= ~hook->id;

        /* Next hooked function. */
        hook = hook->next;
    }

    /* reenable the IRQ only if there is no active handler */
    if (irq_actids[irq] == 0)
        hw_intr_unmask(irq);
}
Ejemplo n.º 4
0
/* Return true if the interrupt was enabled before call.  */
PUBLIC int disable_irq(const irq_hook_t *hook)
{
  if(irq_actids[hook->irq] & hook->id)  /* already disabled */
    return 0;
  irq_actids[hook->irq] |= hook->id;
  hw_intr_mask(hook->irq);
  return TRUE;
}
Ejemplo n.º 5
0
/*
 * The function first disables interrupt is need be and restores the state at
 * the end. Before returning, it unmasks the IRQ if and only if all active ID
 * bits are cleared, and restart a process.
 */
PUBLIC void irq_handle(int irq)
{
  irq_hook_t * hook;

  /* here we need not to get this IRQ until all the handlers had a say */
  assert(irq >= 0 && irq < NR_IRQ_VECTORS);
  hw_intr_mask(irq);
  hook = irq_handlers[irq];

  /* Check for spurious interrupts. */
  if(hook == NULL) {
      static int nspurious[NR_IRQ_VECTORS], report_interval = 100;
      nspurious[irq]++;
      if(nspurious[irq] == 1 || !(nspurious[irq] % report_interval)) {
      	printf("irq_handle: spurious irq %d (count: %d); keeping masked\n",
		irq, nspurious[irq]);
	if(report_interval < INT_MAX/2)
		report_interval *= 2;
      }
      return;
  }

  /* Call list of handlers for an IRQ. */
  while( hook != NULL ) {
    /* For each handler in the list, mark it active by setting its ID bit,
     * call the function, and unmark it if the function returns true.
     */
    irq_actids[irq] |= hook->id;
    
    /* Call the hooked function. */
    if( (*hook->handler)(hook) )
      irq_actids[hook->irq] &= ~hook->id;
    
    /* Next hooked function. */
    hook = hook->next;
  }

  /* reenable the IRQ only if there is no active handler */
  if (irq_actids[irq] == 0)
	  hw_intr_unmask(irq);

  hw_intr_ack(irq);
}