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