|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: // Get Prototypes of the Exported Services First,...
26:
27: #include "driverservices.h"
28: #include "rhap_local.h"
29:
30: // The Driver Services Follow,...
31:
32: /////////////////////////////////////////////////////////////////////////////////
33: //
34: // Queues
35: //
36: //
37:
38: /*-------------------------------------------------------------------------------
39:
40: Routine: PBQueueInit - Initialize a Queue (@ NON-Interrupt-lvl and SIH-lvl)
41:
42: -------------------------------------------------------------------------------*/
43:
44: OSErr PBQueueInit(QHdrPtr qHeader)
45: {
46: qHeader -> qHead = nil;
47: qHeader -> qTail = nil;
48: qHeader -> qFlags = 0x0000;
49:
50: return noErr;
51: }
52:
53: /*-------------------------------------------------------------------------------
54:
55: Routine: PBQueueCreate - Initialize a Queue (@ NON-Interrupt lvl)
56:
57: -------------------------------------------------------------------------------*/
58:
59: OSErr PBQueueCreate(QHdrPtr *qHeader)
60: {
61: Ptr **theQueue;
62:
63: if (CurrentExecutionLevel() != kTaskLevel)
64: {
65: // SysDebugStr ((StringPtr)"\pPBQueueCreate not called at Task Level!");
66: // 11/30/98 Adam return -1;
67: }
68:
69: *qHeader = nil;
70: theQueue = (Ptr **)PoolAllocateResident (sizeof(QHdr)+sizeof(short)+sizeof(Ptr),true);
71: if (theQueue != nil)
72: {
73: // Store orig ptr in first 4 bytes.
74: *theQueue = (Ptr *)theQueue;
75: theQueue++;
76:
77: // Are we not aligned?
78: if ( ((UInt32)theQueue & 3) == 0 )
79: {
80: short *pattern = (short *)theQueue;
81:
82: *pattern++ = 0x4D4E;
83: *qHeader = (QHdrPtr)pattern;
84: return noErr;
85: }
86: else
87: {
88: *qHeader = (QHdrPtr)theQueue;
89: return noErr;
90: }
91: }
92: else
93: return mFulErr;
94: }
95:
96: /*-------------------------------------------------------------------------------
97:
98: Routine: PBQueueDelete - Finalize a Queue (@ NON-Interrupt lvl)
99:
100: -------------------------------------------------------------------------------*/
101:
102: OSErr PBQueueDelete(QHdrPtr qHeader)
103: {
104: Ptr **theMemory;
105: UInt16 *pattern = (UInt16 *)qHeader;
106:
107: if (CurrentExecutionLevel() != kTaskLevel)
108: {
109: // SysDebugStr ((StringPtr)"\pPBQueueDelete not called at Task Level!");
110: return -1;
111: }
112:
113: if (*--pattern == 0x4D4E)
114: qHeader = (QHdrPtr)((UInt32)(qHeader) - sizeof(UInt16));
115:
116: theMemory = (Ptr **)qHeader;
117: theMemory--;
118:
119: if (*theMemory != (Ptr *)theMemory)
120: {
121: // SysDebugStr ((StringPtr)"\pPBQueueDelete not a Queue Header!");
122: return -1;
123: }
124:
125: (void)PoolDeallocate(theMemory);
126: return noErr;
127: }
128:
129: /*-------------------------------------------------------------------------------
130:
131: Routine: PBEnqueueLast - Add an IOPB to the end of a Request Queue. (@ Any Exec-lvl)
132: (Optimized for queue size of 1 or less)
133:
134: -------------------------------------------------------------------------------*/
135:
136: OSErr PBEnqueueLast(QElemPtr qElement, QHdrPtr qHeader)
137: {
138: QElemPtr currElemPtr;
139: UInt16 sr;
140:
141: // New element will be at end of queue.
142: qElement -> qLink = nil;
143:
144: // Currently an empty queue?
145: while ( qHeader -> qHead == nil )
146: {
147: if (CompareAndSwap ((UInt32) nil, (UInt32) qElement, (UInt32 *) &qHeader->qHead))
148: return noErr;
149: }
150:
151: // Multi-element queue,...
152:
153: // Do it the sure, but slow way.
154: sr = Disable68kInterrupts();
155:
156: // Entire queue empty?
157: if ( qHeader -> qHead == nil )
158: {
159: // Add at head of queue
160: qHeader -> qHead = qElement;
161: }
162: else
163: {
164: // Else, Get first element in queue.
165: currElemPtr = (QElemPtr)qHeader->qHead;
166:
167: // Move toward the end of the queue,...
168: while ( currElemPtr -> qLink != nil )
169: {
170: currElemPtr = currElemPtr -> qLink;
171: }
172:
173: currElemPtr -> qLink = qElement;
174: }
175:
176: Restore68kInterrupts(sr);
177: return noErr;
178: }
179:
180: /*-------------------------------------------------------------------------------
181:
182: Routine: PBEnqueue - Add an IOPB to Head of Request Queue. (@ Any Exec-lvl)
183:
184: Function: Returns (nothing)
185:
186: Result: void
187: -------------------------------------------------------------------------------*/
188:
189: void PBEnqueue(QElemPtr qElement, QHdrPtr qHeader)
190: {
191: do {
192: qElement -> qLink = qHeader->qHead;
193: } while (CompareAndSwap ((UInt32) qElement->qLink, (UInt32) qElement,
194: (UInt32 *) &qHeader->qHead) == false);
195: }
196:
197:
198: /*-------------------------------------------------------------------------------
199:
200: Routine: PBDequeue - Remove an IOPB from a Request Queue. (@ Any Exec-lvl)
201:
202: Function: Returns (nothing)
203:
204: Result: void
205: -------------------------------------------------------------------------------*/
206:
207: static OSErr PBDequeueSync(QElemPtr qElement, QHdrPtr qHeader)
208: {
209: QElemPtr prevElemPtr, currElemPtr;
210: OSErr result = noErr;
211: UInt16 sr;
212:
213: // Validate params.
214: if ( (qElement == nil) || (qHeader == nil) )
215: return paramErr;
216:
217: sr = Disable68kInterrupts();
218:
219: currElemPtr = (QElemPtr)qHeader->qHead;
220: prevElemPtr = nil;
221:
222: // Find the one we want.
223: while ( currElemPtr && (currElemPtr != qElement) )
224: {
225: // Advance the cause.
226: prevElemPtr = currElemPtr;
227: currElemPtr = currElemPtr -> qLink;
228: }
229:
230: // We find it?
231: if ( currElemPtr )
232: {
233: // Middle of the queue somewhere?
234: if ( prevElemPtr )
235: prevElemPtr -> qLink = currElemPtr ->qLink;
236: else
237: qHeader->qHead = currElemPtr ->qLink;
238:
239: currElemPtr -> qLink = nil;
240: }
241: else
242: result = qErr; // not on the list.
243:
244: Restore68kInterrupts(sr);
245: return result;
246: }
247:
248:
249: OSErr PBDequeue(QElemPtr qElement, QHdrPtr qHeader)
250: {
251: // Optimize for common case of 1 element on the queue.
252:
253: // First one on the queue?
254: while ( qHeader -> qHead == qElement )
255: {
256: // If the element is still at the head of the queue,... Remove it, and we are done.
257: if (CompareAndSwap ((UInt32) qElement,
258: (UInt32) qElement -> qLink,
259: (UInt32 *) &qHeader->qHead) == true)
260: {
261: qElement -> qLink = nil;
262:
263: return noErr;
264: }
265: }
266:
267: // Multiple elements on the queue.
268: return PBDequeueSync (qElement, qHeader);
269: }
270:
271: /*-------------------------------------------------------------------------------
272:
273: Routine: PBDequeueFirst - Remove First Element on a Queue (@ Any Exec-lvl)
274:
275: Result: noErr or qErr
276: -------------------------------------------------------------------------------*/
277:
278: OSErr PBDequeueFirst(QHdrPtr qHeader, QElemPtr *theFirstqElem)
279: {
280: QElemPtr qElement;
281:
282: do {
283: // Get Queue Head Ptr
284: qElement = qHeader -> qHead;
285:
286: // Empty Queue?
287: if ( qElement == nil )
288: {
289: if ( theFirstqElem )
290: *theFirstqElem = nil;
291:
292: return qErr;
293: }
294:
295: // If the element is still at the head of the queue,... Remove it, and we are done.
296: if (CompareAndSwap ((UInt32) qElement,
297: (UInt32) qElement -> qLink,
298: (UInt32 *) &qHeader->qHead) == true)
299: {
300: if ( theFirstqElem )
301: *theFirstqElem = qElement;
302:
303: qElement -> qLink = nil;
304:
305: return noErr;
306: }
307: } while (1);
308: }
309:
310: /*-------------------------------------------------------------------------------
311:
312: Routine: PBDequeueLast - Remove Last Element on a Queue (@ Any Exec-lvl)
313:
314: Result: noErr or qErr
315: -------------------------------------------------------------------------------*/
316:
317: OSErr PBDequeueLast(QHdrPtr qHeader, QElemPtr *theLastqElem)
318: {
319: QElemPtr currElemPtr, prevElemPtr;
320: OSErr result = noErr;
321: UInt16 sr;
322:
323: if ( theLastqElem )
324: *theLastqElem = nil;
325:
326: sr = Disable68kInterrupts();
327:
328: // Get Queue Head Ptr and our initial previous ptr
329: if ((prevElemPtr = qHeader -> qHead) == nil)
330: result = qErr; // q is empty
331: else
332: {
333: // Get head of queue
334: currElemPtr = (QElemPtr)qHeader->qHead;
335:
336: // Move toward the end of the queue,...
337: while ( currElemPtr -> qLink != nil )
338: {
339: prevElemPtr = currElemPtr;
340: currElemPtr = currElemPtr ->qLink;
341: }
342:
343: // Remove last one from the queue.
344: prevElemPtr->qLink = nil;
345:
346: // If last was also the first, nil out qheader.
347: if ( currElemPtr == qHeader -> qHead )
348: qHeader -> qHead = nil;
349:
350: // Return last element to caller.
351: if ( theLastqElem )
352: *theLastqElem = currElemPtr;
353: }
354:
355: Restore68kInterrupts(sr);
356: return result;
357: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.