|
|
1.1 root 1: VolumeCheck notes
2:
3: * Panel requests
4:
5: -- DiskObject detects "disk not present"
6: -- DiskObject calls vol_panel_disk_num(abort_fcn, queue_ptr)
7: -- either
8: -- Disk is inserted. volCheck thread detects via checkReady:
9: -- WS sends abort. vol driver calls abort_fcn.
10:
11: -- can't have I/O thread(s) block waiting for insertion detection - all
12: threads might evetually block, leaving no thread to do checkReady.
13:
14:
15: * Insertion detect
16: -- driver maintains readyState as instance. calls to checkReady: return
17: immediately if state = ready, else do some I/O to find state.
18: -- volCheck thread calls checkReady: once per second if state != ready.
19: -- if transition to ready, call vol_notify_dev if no panel request
20: pending. Call diskPresent: regardless.
21: -- if state was ejecting, and is now ready, bump per-dev counter. If
22: limit exceeded, vol_panel_request(PR_RT_EJECT_REQ).
23:
24: DiskObject subclass's read/write methods verify readyState = ready before
25: proceeding. if not ready, call vol_panel_disk_num(abort_fcn, queue_ptr)....
26:
27: readyState transitions
28:
29: lastReadyState init'd by subclass, then only changed by volCheck!!!
30:
31: init: RS_NOTREADY or RS_NODISK (by subclass)
32:
33: RS_NOTREADY, RS_NODISK
34: ==> RS_READY when checkReady, called by volCheck, determines
35: that hardware is ready. Done by volCheck.
36:
37: RS_READY
38: ==> RS_NOTREADY on error. Done by volCheck in
39: volCheckNotReady().
40: ==> RS_EJECTING when I/O thread grabs eject cmd from ioQ.
41: Done by volCheck in volCheckEjecting().
42:
43: RS_EJECTING
44: ==> RS_NODISK when volCheck sees a RS_NODISK or RS_NOTREADY.
45: Done by volCheck.
46:
47: * in DiskObject subclass:
48:
49: generic exported method:
50: if this I/O requires no disk
51: enqueue on queue_(always)
52: else
53: enqueue on queue_(needs_disk)
54: wakeup I/O thread (queueLock)
55:
56: generic I/O thread (floppy I/O thread or SCSI disk thread...) {
57:
58: while(1) {
59: sleep on queueLock;
60: process everything on queue_(always);
61: if state != RS_EJECTING, RS_NODISK
62: process everything in queue_(needs_disk)
63: else {
64: if anything in queue_(needs_disk)
65: [self requestDisk:]
66: }
67: }
68: }
69:
70: abortRequest (from volCheck thread, from vol driver, from WSM):
71: pass down to I/O thread (via queue_always).
72: I/O thread does ioComplete on everything in queue_(needs_disk);
73:
74: diskPresent: (called by volCheck thread on disk insert detect
75: just wakeup I/O thread. It'll process everything in queue_(needs_disk).
76:
77: * in volCheck:
78:
79: state per registered removable drive {
80: readyState_t last_readyState;
81: dev_t dev;
82: boolean_t is_ejecting;
83: int eject_counter;
84: boolean_t eject_request_pending;
85: boolean_t disk_request_pending;
86: }
87: A queue of these is set up, one element per removable drive at
88: registerDisk: time.
89:
90: while(1) {
91: for each abort request in queue (from WSM) {
92: [driver_id abortRequest:]
93: disk_request_pending = FALSE for that drive;
94: }
95:
96: for each registered removable drive {
97: switch last_readyState {
98: RS_READY:
99: if is_ejecting {
100: checkReady;
101: switch new state {
102: RS_READY:
103: if(!eject_request_pending) {
104: bump eject_counter;
105: if exceeded {
106: make eject_request;
107: eject_request_pending = TRUE;
108: }
109: }
110: break;
111: RS_NOTREADY:
112: RS_NODISK:
113: default:
114: if(eject_request_pending) {
115: cancel panel;
116: eject_request_pending = FALSE;
117: }
118: }
119: }
120: else no action;
121:
122: default (no disk, not ready):
123: checkReady;
124: switch new state {
125: RS_READY:
126: if(disk_request_pending)
127: cancel panel;
128: else
129: vol_notify_dev();
130: [driver_id diskPresent:]; // REGARDLESS
131: [NXDisk probe:]
132: break;
133: default:
134: no action;
135: }
136: break;
137: } /* switch last ready state */
138: } /* for each drive */
139: sleep(one second);
140: }
141:
142: /*
143: * Called by vol driver
144: */
145: volCheckAbort(param = id of device? ptr to volCheckEntry?) {
146: add an abortRequest to volCheck's abortReqQueue;
147: }
148:
149: /*
150: * Called by DiskObject subclass
151: */
152: requestDisk {
153: if(!disk_request_pending) {
154: vol_panel_dev();
155: disk_request_pending = TRUE;
156: }
157: }
158:
159: exception conditions:
160: -- eject request pending, disk still ready
161: volCheck thread knows isEjecting. Counts 'n' "ready" states. requests
162: eject panel.
163:
164: -- panel request pending, disk detected.
165: volCheck knows requestPending; detects transition to RS_READY.
166: invokes driver's diskPresent:
167: driver's I/O thread wakes up, sees RS_READY, processes everything in
168: queue_(needs_disk).
169:
170: -- panel request pending, WS sends abort message
171: volCheckabort calls driver's abortRequest:
172: driver's abortReqeust:
173: pass down to I/O thread.
174: I/O thread ioComplete's everything on queue_(needs_disk).
175:
176:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.