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