init_bh, remove_bh, mark_bh, disable_bh, enable_bh - split-
     half interrupt handling


     #include <linux/interrupt.h>

     void init_bh(int nr, void (*routine))(void));
     void remove_bh(int nr));
     void mark_bh(int nr));
     void disable_bh(int nr));
     void enable_bh(int nr));


     Split-half handling is a  means  of  dividing  an  interrupt
     handler  into  two  sections, one of which (known as the top
     half') is time-critical and one of which (the bottom  half')
     is not.

     The top half (the handler  registered  with  request_irq(9))
     normally  moves data between the device and a memory buffer,
     ensures that the device is in a sane state, and little else.
     While the top half of a handler is running, the IRQ is ques-
     tion is blocked; if it is a fast interrupt handler (i.e., it
     has SA_INTERRUPT set), all interrupts are disabled.

     The bottom half does whatever remains to  be  done.   Bottom
     halves  run  with  interrupts  enabled,  although  a locking
     mechanism ensures that only one bottom half will be  running
     at a given time.  Bottom halves are run by do_bottom_half(),
     which is called from schedule() and ret_from_sys_call().

     init_bh() installs routine() as bottom half  number  nr.  It
     operates by adding an entry to the bh_base[] table, and set-
     ting the appropriate bit of the bh_mask vector.  Rather than
     specifying  a  number explicitly, one should add an entry to
     the anonymous enum in include/linux/interrupt.h.

     remove_bh() removes bottom half number nr from the  list  of
     bottom  halves.   It  removes  the  entry from bh_base[] and
     clears the appropriate bit of bh_mask.

     mark_bh() requests that the kernel run the specified  bottom
     half  at  the first available opportunity.  This function is
     normally called from the top half of an  interrupt  handler.
     It  operates by setting the appropriate bit of the bh_active

     disable_bh() disables bottom half number nr by clearing  the
     appropriate  bit  of bh_mask.  This function also increments
     bh_mask_count[nr], which is used to ensure that nested calls
     to  disable_bh() must be matched by an equal number of calls
     to enable_bh().

     enable_bh() enables a bottom  half  previously  disabled  by
     disable_bh().   This  function decrements bh_mask_count[nr].
     Then, if that value is zero, the specified  bottom  half  is
     enabled by setting the appropriate bit of bh_mask.


     No value is returned.


     Linux 2.0+.  init_bh() and remove_bh() were not  present  in
     older  versions  on  Linux.  Under those versions, bh_base[]
     and bh_mask must be modified by hand.


     request_irq(9), queue_task(9)

     include/asm*/softirq.h,           include/linux/interrupt.h,

     Kernel Korner in issue 26 of The Linux  Journal  includes  a
     discussion  of split-half interrupts under Linux.  An online
     copy    of    this    article    can     be     found     at


     Neil Moore <>


     Only 32 bottom halves are allowed.  Increasing  this  number
     requires  changing the size of bh_base[] and bh_mask_count[]
     in kernel/softirq.c, and changing bh_active and bh_mask  (in
     the  same  file)  to a larger type.  A better solution, how-
     ever, would be to consolidate multiple bottom halves into  a
     single  one  by  using  task  queues.  See queue_task(9) for