|
|
1.1 ! root 1: {\rtf0\nextcset {\fonttbl{\f41487\fnil Ohlfs;}{\f21\fswiss ! 2: Helvetica;}{\f3\fswiss Helvetica;}} ! 3: \paperw12240\paperh15840 \margl1800\margr1800\margt0\margb0 ! 4: \pgnstart1\ftnstart1 \deftab31680 \sectd\sbknone \linemod0\linex0 ! 5: \ftnbj \headery0\footery0 \cols1 {\header \pard \li0\ri0\fi0\qc\sl320 ! 6: \plain \f3 \par ! 7: \par ! 8: \par ! 9: \par ! 10: }{\footer \pard \li0\ri0\fi0\qc\sl320 \plain \f3 \par ! 11: \par ! 12: \par ! 13: \par ! 14: }\pard \li0\ri0\fi0\qc\sl280 \tx360 \tx6120 \plain \f21\fs36\b ! 15: Driverkit Disk Classes\par ! 16: 16 April, 1993\par ! 17: \par ! 18: \pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 19: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 20: \tx8260 \par ! 21: \par ! 22: \par ! 23: Outline:\par ! 24: \par ! 25: \'b7 Introduction\par ! 26: \par ! 27: \'b7 The volCheck module\par ! 28: \par ! 29: \'b7 IODiskReadingAndWriting protocol\par ! 30: \par ! 31: \'b7 IOPhysicalDiskMethods protocol\par ! 32: \par ! 33: \'b7 Interfacing to cdevsw and bdevsw\par ! 34: \par ! 35: \'b7 I/O thread architecture\par ! 36: \par ! 37: \'b7 Q & A\par ! 38: \par ! 39: \par ! 40: \page \pard \li0\ri0\fi0\qc\sl280 \tx360 \tx1080 \tx1800 ! 41: \tx2520 \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 ! 42: \tx7560 \tx8260 \par ! 43: Class Hierarchy\par ! 44: \pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 45: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 46: \tx8260 \par ! 47: \par ! 48: \par ! 49: \par ! 50: \par ! 51: \pard \keep \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 52: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 53: \tx8260 \par ! 54: \pard \keep \li0\ri0\fi0\qc\sl280 \tx360 \tx1080 \tx1800 ! 55: \tx2520 \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 ! 56: \tx7560 \tx8260 \par ! 57: \pard \keep \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 58: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 59: \tx8260 \par ! 60: \par ! 61: \page \pard \li0\ri0\fi0\qc\sl280 \tx360 \tx1080 \tx1800 ! 62: \tx2520 \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 ! 63: \tx7560 \tx8260 \par ! 64: \par ! 65: The volCheck module\par ! 66: \pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 67: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 68: \tx8260 \par ! 69: \par ! 70: \par ! 71: \par ! 72: \par ! 73: \'b7 Disk Insertion detection\par ! 74: \par ! 75: \'b7 Automount\par ! 76: \par ! 77: \'b7 Alert panels\par ! 78: \par ! 79: \'b7 abort notification\par ! 80: \par ! 81: \par ! 82: \page IODiskReadingAndWriting protocol\par ! 83: \pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 84: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 85: \tx8260 \par ! 86: \par ! 87: \f-24049\fs24\b0 @protocol IODiskReadingAndWriting\par ! 88: \par ! 89: - (IOReturn) readAt\tab \tab : (unsigned)offset \par ! 90: \tab \tab \tab \tab length : (unsigned)length \par ! 91: \tab \tab \tab \tab buffer : (unsigned char *)buffer\par ! 92: \tab \tab \tab \tab actualLength : (unsigned *)actualLength ! 93: \par ! 94: \tab \tab \tab \tab client : (vm_task_t)client;\par ! 95: \par ! 96: - (IOReturn) readAsyncAt\tab : (unsigned)offset \par ! 97: \tab \tab \tab \tab length : (unsigned)length \par ! 98: \tab \tab \tab \tab buffer : (unsigned char *)buffer\par ! 99: \tab \tab \tab \tab pending : (void *)pending\par ! 100: \tab \tab \tab \tab client : (vm_task_t)client;\par ! 101: \tab \tab \par ! 102: - (IOReturn) writeAt\tab \tab : (unsigned)offset \par ! 103: \tab \tab \tab \tab length : (unsigned)length \par ! 104: \tab \tab \tab \tab buffer : (unsigned char *)buffer\par ! 105: \tab \tab \tab \tab actualLength : (unsigned *)actualLength ! 106: \par ! 107: \tab \tab \tab \tab client : (vm_task_t)client;\par ! 108: \tab \tab \par ! 109: - (IOReturn) writeAsyncAt\tab : (unsigned)offset \par ! 110: \tab \tab \tab \tab length : (unsigned)length \par ! 111: \tab \tab \tab \tab buffer : (unsigned char *)buffer\par ! 112: \tab \tab \tab \tab pending : (void *)pending\par ! 113: \tab \tab \tab \tab client : (vm_task_t)client;\par ! 114: \par ! 115: @end\par ! 116: \f21\fs36\b \par ! 117: \par ! 118: \page \pard \li0\ri0\fi0\qc\sl280 \tx360 \tx1080 \tx1800 ! 119: \tx2520 \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 ! 120: \tx7560 \tx8260 IOPhysicalDiskMethods protocol\par ! 121: \pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 122: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 123: \tx8260 \par ! 124: \f-24049\fs24\b0 @protocol IOPhysicalDiskMethods\par ! 125: \par ! 126: /*\par ! 127: * Get physical parameters (dev_size, block_size, etc.) ! 128: from\par ! 129: * new disk. Called upon disk insertion detection, or ! 130: other\par ! 131: * transition to RS_READY, or other change of state ! 132: of\par ! 133: * disk (like a transition to "formatted").\par ! 134: */\par ! 135: - (IOReturn)updatePhysicalParameters;\par ! 136: \par ! 137: /*\par ! 138: * Called by volCheck thread when WS has told us that ! 139: a\par ! 140: * requested disk is not present. Pending I/Os which ! 141: require\par ! 142: * a disk to be present must be aborted.\par ! 143: */\par ! 144: - (void)abortRequest;\par ! 145: \par ! 146: /*\par ! 147: * Called by the volCheck thread when a transition ! 148: to\par ! 149: * "ready" is detected. Pending I/Os which require a ! 150: disk\par ! 151: * may proceed.\par ! 152: */\par ! 153: - (void)diskBecameReady;\par ! 154: \par ! 155: /*\par ! 156: * Inquire if disk is present; if not, and 'prompt' ! 157: is TRUE,\par ! 158: * ask for it. \par ! 159: * Returns IO_R_NODISK if:\par ! 160: * prompt TRUE, disk not present, and user cancels\par ! 161: * request for disk.\par ! 162: * prompt FALSE, disk not present.\par ! 163: * Else returns IO_R_SUCCESS.\par ! 164: */\par ! 165: - (IOReturn)isDiskReady\tab : (BOOL)prompt;\par ! 166: \par ! 167: \page \par ! 168: /*\par ! 169: * Device-specific eject method, only called on physical\par ! 170: * device.\par ! 171: */\par ! 172: - (IOReturn) ejectPhysical;\par ! 173: \par ! 174: /*\par ! 175: * Determine basic state of device. This method should ! 176: NOT\par ! 177: * implement any retries. It also should not return\par ! 178: * RS_EJECTING (That's only used in the lastReadyState\par ! 179: * instance variable).\par ! 180: */\par ! 181: - (IODiskReadyState)updateReadyState;\par ! 182: \par ! 183: @end\par ! 184: \f21\fs36\b \par ! 185: \par ! 186: \f-24049\fs24\b0 /*\par ! 187: * Basic "usefulness" state of drive.\par ! 188: */\par ! 189: typedef enum \{\par ! 190: \tab IO_Ready, \tab \tab // Ready for r/w operations\par ! 191: \tab IO_NotReady,\tab \tab // not ready (spinning up ! 192: or busy)\par ! 193: \tab IO_NoDisk, \tab \tab // no disk present\par ! 194: \tab IO_Ejecting\tab \tab // eject in progress\par ! 195: \} IODiskReadyState;\par ! 196: \f21\fs36\b \par ! 197: \page \pard \li0\ri0\fi0\qc\sl280 \tx360 \tx1080 \tx1800 ! 198: \tx2520 \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 ! 199: \tx7560 \tx8260 Kernel "Glue" Layer\par ! 200: \pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 201: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 202: \tx8260 \par ! 203: \par ! 204: This struct provides mapping between dev_t and id:\par ! 205: \par ! 206: \f-24049\fs24\b0 typedef struct \{\par ! 207: \tab id liveId;\tab \tab \tab // instance for live partition\par ! 208: \tab id partitionId[NPART-1];\tab // for block and raw ! 209: devices\par ! 210: \tab dev_t rawDev;\tab \tab \tab // used by volCheck ! 211: logic\par ! 212: \tab dev_t blockDev;\tab \tab // ditto\par ! 213: \} IODevAndIdInfo;\par ! 214: \f21\fs36\b \par ! 215: \par ! 216: \'b7 Allocated in glue layer module, one per physical\par ! 217: disk\par ! 218: \par ! 219: \'b7 Each instance of IODisk (or subclass) contains a ! 220: \par ! 221: pointer to the associated IODevAndIdInfo.\par ! 222: \par ! 223: \'b7 rawDev and blockDev initialized in device-\par ! 224: specific routine in kernel glue layer, typically\par ! 225: called from +probe or +initialize.\par ! 226: \par ! 227: \'b7 Id fields initialized by IODiskPartition (drivers\par ! 228: don't need to worry about these).\par ! 229: \par ! 230: \par ! 231: \page \pard \li0\ri0\fi0\qc\sl280 \tx360 \tx1080 \tx1800 ! 232: \tx2520 \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 ! 233: \tx7560 \tx8260 I/O Threads\par ! 234: \pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 235: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 236: \tx8260 \par ! 237: Instance variables:\par ! 238: \par ! 239: \pard \li380\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 240: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 241: \tx8260 \f-24049\fs24\b0 queue_head_t\tab ioQueueDisk;\tab ! 242: // for I/Os requiring disk \par ! 243: queue_head_t\tab ioQueueNodisk;\tab // for other I/O\par ! 244: id \tab \tab \tab ioQLock;\tab \tab // NXConditionLock ! 245: - \par ! 246: \tab \tab \tab \tab \tab \tab // protects the queues; ! 247: I/O\par ! 248: \tab \tab \tab \tab \tab \tab // thread(s) sleeps on ! 249: this\par ! 250: \par ! 251: /*\par ! 252: * Values for ioQLock.condition.\par ! 253: */\par ! 254: typedef enum \{ IOQueuesEmpty, WorkAvailable \}; \par ! 255: \pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 256: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 257: \tx8260 \par ! 258: \f21\fs36\b \par ! 259: Command Buffer:\par ! 260: \f-24049\fs24\b0 \par ! 261: \pard \li380\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 262: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 263: \tx8260 typedef struct \{\par ! 264: \tab /* \par ! 265: \tab * device-specific stuff here which defines one ! 266: I/O.\par ! 267: \tab * For example, block number, transfer count,\par ! 268: \tab * return status, etc.\par ! 269: \tab */\par ! 270: \par ! 271: \tab /* \par ! 272: \tab * cmdLock is what an exported method blocks on\par ! 273: \tab * when waiting for the I/O thread to process ! 274: this\par ! 275: \tab * command.\par ! 276: \tab */\par ! 277: \tab NXConditionLock\tab cmdLock;\par ! 278: \par ! 279: \tab /*\par ! 280: \tab * This determines whether the operation is \par ! 281: \tab * synchronous or async.\par ! 282: \tab */\par ! 283: \tab void \tab \tab \tab *pending;\par ! 284: \} commandBuf;\par ! 285: \page \pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 286: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 287: \tx8260 \par ! 288: \f21\fs36\b Exported method:\par ! 289: \par ! 290: \pard \li380\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 291: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 292: \tx8260 \f-24049\fs24\b0 \{\par ! 293: \tab Cons up a commandBuffer for this I/O;\par ! 294: \par ! 295: \tab /*\par ! 296: \tab * Enqueue on appropriate I/O queue and wake up ! 297: I/O\par ! 298: \tab * thread.\par ! 299: \tab */\par ! 300: \tab if this I/O requires disk \{\par ! 301: \tab \tab enqueue on ioQueueDisk;\par ! 302: \tab \}\par ! 303: \tab else \{\par ! 304: \tab \tab enqueue on ioQueueNodisk;\par ! 305: \tab \}\par ! 306: \tab [ioQLock lock];\par ! 307: \tab [ioQLock unlockWith:WorkAvailable];\par ! 308: \par ! 309: \tab /*\par ! 310: \tab * Wait for I/O complete.\par ! 311: \tab */\par ! 312: \tab [commandBuffer.cmdLock lockWhen:YES];\par ! 313: \pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 314: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 315: \tx8260 \}\par ! 316: \par ! 317: \f21\fs36\b \par ! 318: \page \par ! 319: I/O thread:\par ! 320: \par ! 321: \par ! 322: \pard \li380\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 323: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 324: \tx8260 \f-24049\fs24\b0 \{\par ! 325: \tab initialize;\par ! 326: \tab while(1) \{\par ! 327: \tab \tab [ioQLock lockWhen: WorkAvailable];\par ! 328: \tab \tab [ioQLock unlock];\par ! 329: \tab \tab process everything on ioQueueNodisk;\par ! 330: \tab \tab if((lastReadyState != IO_RS_NODISK) &&\par ! 331: \tab (lastReadyState != IO_RS_EJECTING)) ! 332: \{\par ! 333: \tab \tab \tab process everything in ioQueueDisk;\par ! 334: \tab \tab else \{\par ! 335: \tab \tab \tab if ioQueueDisk non-empty \{\par ! 336: \tab \tab \tab [self requestInsertionPanelForDiskType];\par ! 337: \tab \tab \tab \}\par ! 338: \tab \tab \}\par ! 339: \tab \tab [ioQLock unlockWith:<current queue state>];\par ! 340: \tab \}\par ! 341: \}\par ! 342: \par ! 343: \page \par ! 344: \pard \li0\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 345: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 346: \tx8260 \f21\fs36\b To process one commandBuf:\par ! 347: \par ! 348: \pard \li380\ri0\fi0\sl280 \tx360 \tx1080 \tx1800 \tx2520 ! 349: \tx3240 \tx3960 \tx4680 \tx5400 \tx6120 \tx6840 \tx7560 ! 350: \tx8260 \f-24049\fs24\b0 \{\par ! 351: \tab perform device-specific I/O described in\par ! 352: \tab \tab commandBuf;\par ! 353: \tab if(commandBuf.pending) \{\par ! 354: \tab \tab /*\par ! 355: \tab \tab * Async operation. \par ! 356: \tab \tab */\par ! 357: \tab \tab [self completeTransfer:commandBuf.pending\par ! 358: \tab \tab \tab \tab \tab withStatus:...\par ! 359: \tab \tab \tab \tab \tab actualLength:...];\par ! 360: \tab \}\par ! 361: \tab else \{\par ! 362: \tab \tab /*\par ! 363: \tab \tab * Wake up client.\par ! 364: \tab \tab */\par ! 365: \tab \tab [commandBuf.cmdLock lock];\par ! 366: \tab \tab [commandBuf.cmdLock unlockWith:YES];\par ! 367: \tab \} \par ! 368: \}\par ! 369: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.