|
|
#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.