| 
 |  | 
#include <sys/ci/cidriver.h>int can_doio(int bustype);
Typically this routine is called from a driver strategy routine.
1 is returned if a processor can do I/O to or from a device on the specified bus.
1 will also be returned if only one processor is present in the system.
    1           s = lockb(&lock_xxtab);
    2           disksort(&xxtab, bp);
    3           if (xxtab.b_active == 0) {
    4                   if (can_doio(MP_ATBUS))
    5                           xxstart(xxstart_arg);
    6                   else {
    7                           unlockb(&lock_xxtab, -1);
    8                           startio(xxhandle, xxstart_arg);
    9                   }
   10                   splx(s);
   11           }
   12           else {
   13                   unlockb(&lock_xxtab, s);
   14                   return;
   15           }
In line 2,
disksort(D3oddi)
is called to sort and queue block driver I/O
requests. Line 3 uses the b_active flag in the
xxtab structure to determine if the driver is performing
I/O. This flag is set in the driver's xxstart
routine to indicate that it is active. If the processor is
performing I/O, then the critical code section is unlocked
in line 13, and the routine exits.
If the driver is not already performing I/O, can_doio is called in line 4 to see if the current processor can access the I/O bus. If it can, the xxstart routine is called directly in line 5. If access to the I/O bus from the current processor is not possible, the critical code section is unlocked in line 7. The ``-1'' argument to unlockb(D3oddi) indicates that the old spl value is not immediately restored: splx(D3oddi) is called by the driver after the call to unlockb, in line 10. Then startio(D3oddi) is called in line 8 to interrupt the processor that can access the I/O bus to run the xxstart routine. The first argument to the startio routine is the handle address returned from a previous call to intralloc(D3oddi). The second argument is that passed to the xxstart routine.