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