|
|
1.1 root 1: /*
2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
24: *
25: * HISTORY
26: *
27: */
28:
29: #include <IOKit/firewire/IOFWDCLTranslator.h>
30:
31: ////////////////////////////////////////////////////////////////////////////////
32: //
33: // FWDCLReceivePacketStart
34: //
35: // This routine runs a DCL receive packet start command.
36: //
37:
38: static void DCLReceivePacketStart(
39: DCLCommandPtr *ppCurrentDCLCommand,
40: UInt32 packetHeader,
41: UInt8 * *pPacketBuffer,
42: UInt32 *pPacketSize,
43: bool *pGetNextPacket)
44: {
45: DCLTransferPacketPtr pDCLTransferPacket;
46: UInt8 * transferBuffer;
47: UInt8 * packetBuffer;
48: SInt32 transferSize, packetSize;
49:
50: // Recast DCL command.
51: pDCLTransferPacket = (DCLTransferPacketPtr) *ppCurrentDCLCommand;
52:
53: // Get some parameters.
54: transferBuffer = (UInt8 *)pDCLTransferPacket->buffer;
55: transferSize = pDCLTransferPacket->size - sizeof (UInt32);
56: packetSize = *pPacketSize;
57: if (transferSize > packetSize)
58: transferSize = packetSize;
59: packetBuffer = *pPacketBuffer;
60:
61: // Transfer the packet data.
62: *((UInt32 *) transferBuffer) = packetHeader;
63: transferBuffer += sizeof (UInt32);
64: if (transferSize > 0) {
65: bcopy (packetBuffer, transferBuffer, transferSize);
66: packetSize -= transferSize;
67: packetBuffer += transferSize;
68: }
69:
70: // Check if we need another packet.
71: *pGetNextPacket = true;
72: if (pDCLTransferPacket->pNextDCLCommand != NULL)
73: {
74: if ((pDCLTransferPacket->pNextDCLCommand->opcode & ~kFWDCLOpFlagMask) ==
75: kDCLReceivePacketOp)
76: {
77: *pGetNextPacket = false;
78: }
79: }
80:
81: // Update parameters.
82: *ppCurrentDCLCommand = pDCLTransferPacket->pNextDCLCommand;
83: *pPacketBuffer = packetBuffer;
84: *pPacketSize = packetSize;
85: }
86:
87:
88: ////////////////////////////////////////////////////////////////////////////////
89: //
90: // DCLReceivePacket
91: //
92: // This routine runs a DCL receive packet command.
93: //
94:
95: static void DCLReceivePacket(
96: DCLCommandPtr *ppCurrentDCLCommand,
97: UInt32 packetHeader,
98: UInt8 * *pPacketBuffer,
99: UInt32 *pPacketSize,
100: bool *pGetNextPacket)
101: {
102: DCLTransferPacketPtr pDCLTransferPacket;
103: UInt8 * transferBuffer;
104: UInt8 * packetBuffer;
105: UInt32 transferSize, packetSize;
106:
107: // Recast DCL command.
108: pDCLTransferPacket = (DCLTransferPacketPtr) *ppCurrentDCLCommand;
109:
110: // Get some parameters.
111: transferBuffer = (UInt8 *)pDCLTransferPacket->buffer;
112: transferSize = pDCLTransferPacket->size;
113: packetSize = *pPacketSize;
114: if (transferSize > packetSize)
115: transferSize = packetSize;
116: packetBuffer = *pPacketBuffer;
117:
118: // Transfer the packet data.
119: if (transferSize > 0)
120: {
121: bcopy (packetBuffer, transferBuffer, transferSize);
122: packetSize -= transferSize;
123: packetBuffer += transferSize;
124: }
125:
126: // Check if we need another packet.
127: *pGetNextPacket = true;
128: if (pDCLTransferPacket->pNextDCLCommand != NULL)
129: {
130: if ((pDCLTransferPacket->pNextDCLCommand->opcode & ~kFWDCLOpFlagMask) ==
131: kDCLReceivePacketOp)
132: {
133: *pGetNextPacket = false;
134: }
135: }
136:
137: // Update parameters.
138: *ppCurrentDCLCommand = pDCLTransferPacket->pNextDCLCommand;
139: *pPacketBuffer = packetBuffer;
140: *pPacketSize = packetSize;
141: }
142:
143:
144: ////////////////////////////////////////////////////////////////////////////////
145: //
146: // FWDCLReceiveBuffer
147: //
148: // This routine runs a DCL receive buffer command.
149: //zzz should we include packet header?
150: //zzz should we clip off end of packet when buffer is filled?
151: //
152:
153: static void DCLReceiveBuffer(
154: DCLCommandPtr *ppCurrentDCLCommand,
155: UInt32 packetHeader,
156: UInt8 * *pPacketBuffer,
157: UInt32 *pPacketSize,
158: bool *pGetNextPacket)
159: {
160: DCLTransferBufferPtr pDCLTransferBuffer;
161: UInt8 * buffer;
162: UInt32 bufferOffset, bufferSize;
163: UInt32 bufferSizeLeft;
164: UInt8 * packetBuffer;
165: UInt32 packetSize;
166: UInt32 transferSize;
167:
168: // Recast current DCL command.
169: pDCLTransferBuffer = (DCLTransferBufferPtr) *ppCurrentDCLCommand;
170:
171: // Get some parameters.
172: buffer = (UInt8 *)pDCLTransferBuffer->buffer;
173: bufferOffset = pDCLTransferBuffer->bufferOffset;
174: bufferSize = pDCLTransferBuffer->size;
175: packetBuffer = *pPacketBuffer;
176: packetSize = *pPacketSize;
177:
178: // Compute size of transfer.
179: bufferSizeLeft = bufferSize - bufferOffset;
180: if (bufferSizeLeft > packetSize)
181: transferSize = packetSize;
182: else
183: transferSize = bufferSizeLeft;
184:
185: // Transfer the packet data.
186: if (transferSize > 0)
187: {
188: bcopy (packetBuffer, buffer + bufferOffset, transferSize);
189:
190: packetBuffer += transferSize;
191: packetSize -= transferSize;
192: bufferOffset += transferSize;
193: }
194:
195: // Check if we're done with this DCL or need another packet.
196: if (bufferOffset == bufferSize)
197: {
198: *ppCurrentDCLCommand = pDCLTransferBuffer->pNextDCLCommand;
199: *pGetNextPacket = false;
200: }
201: else
202: {
203: *pGetNextPacket = true;
204: }
205:
206: // Update parameters.
207: pDCLTransferBuffer->bufferOffset = bufferOffset;
208: *pPacketBuffer = packetBuffer;
209: *pPacketSize = packetSize;
210: }
211:
212: ////////////////////////////////////////////////////////////////////////////////
213: //
214: // DCLSendPacket
215: //
216: // This routine runs a DCL send packet command.
217: //
218:
219: static void DCLSendPacket(
220: DCLCommandPtr *ppCurrentDCLCommand,
221: UInt8 * *pPacketBuffer,
222: UInt32 *pPacketSize,
223: bool *pGetNextPacket)
224: {
225: DCLTransferPacketPtr pDCLTransferPacket;
226: UInt8 * transferBuffer;
227: UInt8 * packetBuffer;
228: UInt32 transferSize, packetSize;
229:
230: // Recast DCL command.
231: pDCLTransferPacket = (DCLTransferPacketPtr) *ppCurrentDCLCommand;
232:
233: // Get some parameters.
234: transferBuffer = (UInt8 *)pDCLTransferPacket->buffer;
235: transferSize = pDCLTransferPacket->size;
236: packetSize = *pPacketSize;
237: packetBuffer = *pPacketBuffer + packetSize;
238:
239: // Transfer the packet data.
240: bcopy (transferBuffer, packetBuffer, transferSize);
241: packetSize += transferSize;
242:
243: // Check if we need another packet.
244: *pGetNextPacket = true;
245: if (pDCLTransferPacket->pNextDCLCommand != NULL)
246: {
247: if ((pDCLTransferPacket->pNextDCLCommand->opcode & ~kFWDCLOpFlagMask) ==
248: kDCLSendPacketOp)
249: {
250: *pGetNextPacket = false;
251: }
252: }
253:
254: // Update parameters.
255: *ppCurrentDCLCommand = pDCLTransferPacket->pNextDCLCommand;
256: *pPacketSize = packetSize;
257: }
258:
259:
260: ////////////////////////////////////////////////////////////////////////////////
261: //
262: // DCLSendBuffer
263: //
264: // This routine runs a DCL send buffer command.
265: //zzz should we clip off end of packet when buffer is emptied?
266: //
267:
268: static void DCLSendBuffer(
269: DCLCommandPtr *ppCurrentDCLCommand,
270: UInt8 * *pPacketBuffer,
271: UInt32 *pPacketSize,
272: bool *pGetNextPacket)
273: {
274: DCLTransferBufferPtr pDCLTransferBuffer;
275: UInt8 * buffer;
276: UInt32 bufferOffset, bufferSize;
277: UInt32 bufferSizeLeft;
278: UInt8 * packetBuffer;
279: UInt32 packetSize;
280: UInt32 transferPacketSize;
281: UInt32 transferSize;
282:
283: // Recast current DCL command.
284: pDCLTransferBuffer = (DCLTransferBufferPtr) *ppCurrentDCLCommand;
285:
286: // Get some parameters.
287: buffer = (UInt8 *)pDCLTransferBuffer->buffer;
288: bufferOffset = pDCLTransferBuffer->bufferOffset;
289: bufferSize = pDCLTransferBuffer->size;
290: packetSize = *pPacketSize;
291: packetBuffer = *pPacketBuffer + packetSize;
292: transferPacketSize = pDCLTransferBuffer->packetSize;
293:
294: // Compute size of transfer.
295: bufferSizeLeft = bufferSize - bufferOffset;
296: if (bufferSizeLeft > transferPacketSize)
297: transferSize = transferPacketSize;
298: else
299: transferSize = bufferSizeLeft;
300:
301: // Transfer the packet data.
302: if (transferSize > 0)
303: {
304: bcopy (buffer + bufferOffset, packetBuffer, transferSize);
305:
306: packetSize += transferSize;
307: bufferOffset += transferSize;
308: }
309:
310: // Check if we're done with this DCL or need another packet.
311: //zzz is this the best way to do this?
312: //zzz what if the next transfer command is a transfer packet command?
313: if (bufferOffset == bufferSize)
314: {
315: *ppCurrentDCLCommand = pDCLTransferBuffer->pNextDCLCommand;
316: *pGetNextPacket = false;
317: }
318: else
319: {
320: *pGetNextPacket = true;
321: }
322:
323: // Update parameters.
324: pDCLTransferBuffer->bufferOffset = bufferOffset;
325: *pPacketSize = packetSize;
326: }
327:
328: ////////////////////////////////////////////////////////////////////////////////
329: //
330: // FWRunTranslatedDCLEngine
331: //
332: // This routine runs the current DCL command using the given packet. It will
333: // update the current DCL command, packet buffer pointer, packet size, and will
334: // set get next packet to true if it needs another packet.
335: //zzz maybe a vector table would be nice
336: //zzz implement rest of DCL commands.
337: //
338:
339: static void RunListeningDCLEngine(
340: DCLCommandPtr *ppCurrentDCLCommand,
341: UInt32 packetHeader,
342: UInt8 * *pPacketBuffer,
343: UInt32 *pPacketSize,
344: bool *pGetNextPacket)
345: {
346: DCLCommandPtr pCurrentDCLCommand;
347: DCLCallProcPtr pDCLCallProc;
348: DCLJumpPtr pDCLJump;
349:
350: // Run the current DCL command.
351: pCurrentDCLCommand = *ppCurrentDCLCommand;
352: switch (pCurrentDCLCommand->opcode & ~kFWDCLOpFlagMask)
353: {
354: case kDCLReceivePacketStartOp :
355: DCLReceivePacketStart (
356: &pCurrentDCLCommand,
357: packetHeader,
358: pPacketBuffer,
359: pPacketSize,
360: pGetNextPacket);
361: break;
362:
363: case kDCLReceivePacketOp :
364: DCLReceivePacket (
365: &pCurrentDCLCommand,
366: packetHeader,
367: pPacketBuffer,
368: pPacketSize,
369: pGetNextPacket);
370: break;
371:
372: case kDCLReceiveBufferOp :
373: DCLReceiveBuffer (
374: &pCurrentDCLCommand,
375: packetHeader,
376: pPacketBuffer,
377: pPacketSize,
378: pGetNextPacket);
379: break;
380:
381: case kDCLCallProcOp :
382: pDCLCallProc = (DCLCallProcPtr) pCurrentDCLCommand;
383: // Call the handler if there is one.
384: if (pDCLCallProc->proc != NULL)
385: (*(pDCLCallProc->proc)) ((DCLCommandPtr) pDCLCallProc);
386:
387: pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand;
388: *pGetNextPacket = false;
389: break;
390:
391: case kDCLJumpOp :
392: pDCLJump = (DCLJumpPtr) pCurrentDCLCommand;
393: pCurrentDCLCommand = (DCLCommandPtr) pDCLJump->pJumpDCLLabel;
394: *pGetNextPacket = false;
395: break;
396:
397: default :
398: pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand;
399: *pGetNextPacket = false;
400: break;
401: }
402:
403: // Update current DCL command.
404: *ppCurrentDCLCommand = pCurrentDCLCommand;
405: }
406:
407: ////////////////////////////////////////////////////////////////////////////////
408: //
409: // FWRunTranslatedTalkingDCLEngine
410: //
411: // This routine runs the current DCL command using the given packet. It will
412: // update the current DCL command, packet buffer pointer, packet size, and will
413: // set get next packet to true if it needs another packet.
414: //zzz maybe a vector table would be nice
415: //
416:
417: static void RunTalkingDCLEngine(
418: UInt32 * packetHeader,
419: DCLCommandPtr *ppCurrentDCLCommand,
420: UInt8 * *pPacketBuffer,
421: UInt32 *pPacketSize,
422: bool *pGetNextPacket)
423: {
424: DCLCommandPtr pCurrentDCLCommand;
425: DCLCallProcPtr pDCLCallProc;
426: DCLJumpPtr pDCLJump;
427: DCLSetTagSyncBitsPtr pDCLSetTagSyncBits;
428:
429: // Run the current DCL command.
430: pCurrentDCLCommand = *ppCurrentDCLCommand;
431: switch (pCurrentDCLCommand->opcode & ~kFWDCLOpFlagMask)
432: {
433: case kDCLSendPacketStartOp :
434: case kDCLSendPacketOp :
435: DCLSendPacket (
436: &pCurrentDCLCommand,
437: pPacketBuffer,
438: pPacketSize,
439: pGetNextPacket);
440: break;
441:
442: case kDCLSendBufferOp :
443: DCLSendBuffer (
444: &pCurrentDCLCommand,
445: pPacketBuffer,
446: pPacketSize,
447: pGetNextPacket);
448: break;
449:
450: case kDCLCallProcOp :
451: pDCLCallProc = (DCLCallProcPtr) pCurrentDCLCommand;
452: // Call the handler if there is one.
453: if (pDCLCallProc->proc != NULL)
454: (*(pDCLCallProc->proc)) ((DCLCommandPtr) pDCLCallProc);
455: pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand;
456: *pGetNextPacket = false;
457: break;
458:
459: case kDCLJumpOp :
460: pDCLJump = (DCLJumpPtr) pCurrentDCLCommand;
461: pCurrentDCLCommand = (DCLCommandPtr) pDCLJump->pJumpDCLLabel;
462: *pGetNextPacket = false;
463: break;
464:
465: case kDCLLabelOp :
466: pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand;
467: *pGetNextPacket = false;
468: break;
469:
470: case kDCLSetTagSyncBitsOp :
471: pDCLSetTagSyncBits = (DCLSetTagSyncBitsPtr) pCurrentDCLCommand;
472: *packetHeader &= ~(kFWIsochTag | kFWIsochSy);
473: *packetHeader |= (pDCLSetTagSyncBits->tagBits << kFWIsochTagPhase);
474: *packetHeader |= (pDCLSetTagSyncBits->syncBits << kFWIsochSyPhase);
475: pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand;
476: *pGetNextPacket = false;
477: break;
478:
479: default :
480: pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand;
481: *pGetNextPacket = false;
482: break;
483: }
484:
485: // Update current DCL command.
486: *ppCurrentDCLCommand = pCurrentDCLCommand;
487: }
488:
489: OSDefineMetaClass( IODCLTranslator, IODCLProgram )
490: OSDefineAbstractStructors(IODCLTranslator, IODCLProgram)
491:
492: bool IODCLTranslator::init(DCLCommandPtr toInterpret)
493: {
494: if(!IODCLProgram::init())
495: return false;
496:
497: // Allocate buffers etc. for programs
498:
499: fToInterpret = toInterpret;
500: return true;
501: }
502:
503: IOReturn IODCLTranslator::notify(UInt32 notificationType,
504: DCLCommandPtr *dclCommandList, UInt32 numDCLCommands)
505: {
506: return kIOReturnSuccess; // Nothing to do, we're interpreting anyway
507: }
508:
509: IOReturn IODCLTranslator::allocateHW(IOFWSpeed speed, UInt32 chan)
510: {
511: if(!fHWProgram)
512: return kIOReturnInternalError;
513: return fHWProgram->allocateHW(speed, chan);
514: }
515: IOReturn IODCLTranslator::releaseHW()
516: {
517: if(!fHWProgram)
518: return kIOReturnInternalError;
519: return fHWProgram->releaseHW();
520: }
521:
522: void IODCLTranslator::stop()
523: {
524: fHWProgram->stop();
525: }
526:
527: void IODCLTranslator::ListeningDCLPingPongProc(DCLCommandPtr pDCLCommand)
528: {
529: IODCLTranslator * me;
530: DCLCommandPtr pCurrentDCLCommand;
531: DCLTransferPacketPtr pDCLTransferPacket;
532: UInt8 * packetBuffer;
533: UInt32 packetHeader;
534: UInt32 packetSize;
535: UInt32 packetNum;
536: bool getNextPacket;
537:
538: me = (IODCLTranslator *)((DCLCallProcPtr)pDCLCommand)->procData;
539: pCurrentDCLCommand = me->fCurrentDCLCommand;
540: pDCLTransferPacket = &me->fTransfers[me->fPingCount * kNumPacketsPerPingPong];
541: // Run all packets through DCL program.
542: for (packetNum = 0;
543: ((packetNum < kNumPacketsPerPingPong) && (pCurrentDCLCommand != NULL));
544: packetNum++) {
545: // Compute packet size.
546: packetBuffer = (UInt8 *)pDCLTransferPacket->buffer;
547: packetHeader = *((UInt32 *) packetBuffer);
548: packetBuffer += sizeof (UInt32);
549: packetSize = (packetHeader & kFWIsochDataLength) >> kFWIsochDataLengthPhase;
550:
551: // Run this packet through DCL program.
552: getNextPacket = false;
553: while ((!getNextPacket) && (pCurrentDCLCommand != NULL)) {
554: RunListeningDCLEngine (
555: &pCurrentDCLCommand,
556: packetHeader,
557: &packetBuffer,
558: &packetSize,
559: &getNextPacket);
560: }
561:
562: // Update for next packet.
563: pDCLTransferPacket++;
564: }
565:
566: // Update DCL translation data.
567: me->fCurrentDCLCommand = pCurrentDCLCommand;
568: me->fPingCount++;
569: if(me->fPingCount > kNumPingPongs)
570: me->fPingCount = 0;
571: }
572:
573: void IODCLTranslator::TalkingDCLPingPongProc(DCLCommandPtr pDCLCommand)
574: {
575: IODCLTranslator * me;
576: DCLCommandPtr pCurrentDCLCommand;
577: DCLTransferPacketPtr pDCLTransferPacket;
578: UInt8 * packetBuffer;
579: UInt32 packetHeader;
580: UInt32 packetSize;
581: UInt32 packetNum;
582: bool getNextPacket;
583:
584: me = (IODCLTranslator *)((DCLCallProcPtr)pDCLCommand)->procData;
585: pCurrentDCLCommand = me->fCurrentDCLCommand;
586: pDCLTransferPacket = &me->fTransfers[me->fPingCount * kNumPacketsPerPingPong];
587: // Run all packets through DCL program.
588: for (packetNum = 0;
589: ((packetNum < kNumPacketsPerPingPong) && (pCurrentDCLCommand != NULL));
590: packetNum++) {
591: // Compute packet size.
592: packetBuffer = (UInt8 *)pDCLTransferPacket->buffer;
593: packetSize = sizeof (UInt32);
594:
595: // Run this packet through DCL program.
596: getNextPacket = false;
597: while ((!getNextPacket) && (pCurrentDCLCommand != NULL)) {
598: RunTalkingDCLEngine (&(me->fPacketHeader),
599: &pCurrentDCLCommand,
600: &packetBuffer,
601: &packetSize,
602: &getNextPacket);
603: }
604: // Update packet header.
605: packetSize -= 4;//zzz not the best way
606: packetHeader =
607: (packetSize << kFWIsochDataLengthPhase) |
608: (me->fPacketHeader & ~(kFWIsochDataLength));
609: *((UInt32 *) packetBuffer) = packetHeader;
610:
611: // Update send packet DCL.
612: packetSize += 4;//zzz really, not the best way
613: // Change the transfer packet command.
614: pDCLTransferPacket->size = packetSize;
615: // Send notification to DCL compiler.
616: me->fHWProgram->notify(kFWDCLModifyNotification,
617: (DCLCommandPtr *) pDCLTransferPacket, 1);
618:
619: // Update for next packet.
620: pDCLTransferPacket++;
621: }
622:
623: // Update DCL translation data.
624: me->fCurrentDCLCommand = pCurrentDCLCommand;
625: me->fPingCount++;
626: if(me->fPingCount > kNumPingPongs)
627: me->fPingCount = 0;
628: }
629:
630: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
631: OSDefineMetaClassAndStructors(IODCLTranslateTalk, IODCLTranslator)
632:
633: IOReturn IODCLTranslateTalk::compile(IOFWSpeed speed, UInt32 chan)
634: {
635: int pingPongNum;
636: int packetNum;
637: DCLTransferPacketPtr pDCLTransferPacket = &fTransfers[0];
638: DCLCallProcPtr pDCLPingPongProc = &fCalls[0];
639: UInt8 *pingPongBuffer = fBuffer;
640:
641: if(!fHWProgram)
642: return kIOReturnInternalError;
643:
644: fPacketHeader = chan << kFWIsochChanNumPhase;
645:
646: // Create label for start of loop.
647: fStartLabel.pNextDCLCommand = (DCLCommandPtr)pDCLTransferPacket;
648: fStartLabel.opcode = kDCLLabelOp;
649:
650: // Create kNumPingPongs ping pong buffer lists of kNumPacketsPerPingPong
651: // packets each.
652: for (pingPongNum = 0; pingPongNum < kNumPingPongs; pingPongNum++) {
653: // Create transfer DCL for each packet.
654: for (packetNum = 0; packetNum < kNumPacketsPerPingPong; packetNum++) {
655: // Receive one packet up to kMaxIsochPacketSize bytes.
656: pDCLTransferPacket->pNextDCLCommand = (DCLCommandPtr)(pDCLTransferPacket+1);
657: pDCLTransferPacket->opcode = kDCLSendPacketWithHeaderStartOp | kFWDCLOpDynamicFlag;
658: pDCLTransferPacket->buffer = pingPongBuffer;
659: pDCLTransferPacket->size = kMaxIsochPacketSize;
660: pingPongBuffer += kMaxIsochPacketSize;
661: pDCLTransferPacket++;
662: }
663: // Correct next opcode for last transfer op.
664: (pDCLTransferPacket-1)->pNextDCLCommand = (DCLCommandPtr)pDCLPingPongProc;
665: // Call the ping pong proc.
666: pDCLPingPongProc->pNextDCLCommand = (DCLCommandPtr) pDCLTransferPacket;
667: pDCLPingPongProc->opcode = kDCLCallProcOp;
668: pDCLPingPongProc->proc = TalkingDCLPingPongProc;
669: pDCLPingPongProc->procData = (UInt32) this;
670: pDCLPingPongProc++;
671: }
672: // Correct next opcode for last call op.
673: (pDCLPingPongProc-1)->pNextDCLCommand = (DCLCommandPtr)&fJumpToStart;
674:
675: // Loop to start of ping pong.
676: fJumpToStart.pNextDCLCommand = NULL;
677: fJumpToStart.opcode = kDCLJumpOp | kFWDCLOpDynamicFlag;
678: fJumpToStart.pJumpDCLLabel = &fStartLabel;
679:
680: return fHWProgram->compile(speed, chan);
681: }
682:
683: IOReturn IODCLTranslateTalk::start()
684: {
685: int i;
686: fPingCount = 0;
687: // Prime all buffers
688: for(i=0; i<kNumPingPongs; i++) {
689: TalkingDCLPingPongProc((DCLCommandPtr)&fCalls[i]);
690: }
691: return fHWProgram->start();
692: }
693:
694: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
695: OSDefineMetaClassAndStructors(IODCLTranslateListen, IODCLTranslator)
696:
697: IOReturn IODCLTranslateListen::compile(IOFWSpeed speed, UInt32 chan)
698: {
699: int pingPongNum;
700: int packetNum;
701: DCLTransferPacketPtr pDCLTransferPacket = &fTransfers[0];
702: DCLCallProcPtr pDCLPingPongProc = &fCalls[0];
703: UInt8 *pingPongBuffer = fBuffer;
704:
705: if(!fHWProgram)
706: return kIOReturnInternalError;
707:
708: fPacketHeader = chan << kFWIsochChanNumPhase;
709:
710: // Create label for start of loop.
711: fStartLabel.pNextDCLCommand = (DCLCommandPtr)pDCLTransferPacket;
712: fStartLabel.opcode = kDCLLabelOp;
713:
714: // Create kNumPingPongs ping pong buffer lists of kNumPacketsPerPingPong
715: // packets each.
716: for (pingPongNum = 0; pingPongNum < kNumPingPongs; pingPongNum++) {
717: // Create transfer DCL for each packet.
718: for (packetNum = 0; packetNum < kNumPacketsPerPingPong; packetNum++) {
719: // Receive one packet up to kMaxIsochPacketSize bytes.
720: pDCLTransferPacket->pNextDCLCommand = (DCLCommandPtr)(pDCLTransferPacket+1);
721: pDCLTransferPacket->opcode = kDCLReceivePacketStartOp | kFWDCLOpDynamicFlag;
722: pDCLTransferPacket->buffer = pingPongBuffer;
723: pDCLTransferPacket->size = kMaxIsochPacketSize;
724: pingPongBuffer += kMaxIsochPacketSize;
725: pDCLTransferPacket++;
726: }
727: // Correct next opcode for last transfer op.
728: (pDCLTransferPacket-1)->pNextDCLCommand = (DCLCommandPtr)pDCLPingPongProc;
729: // Call the ping pong proc.
730: pDCLPingPongProc->pNextDCLCommand = (DCLCommandPtr) pDCLTransferPacket;
731: pDCLPingPongProc->opcode = kDCLCallProcOp;
732: pDCLPingPongProc->proc = ListeningDCLPingPongProc;
733: pDCLPingPongProc->procData = (UInt32) this;
734: pDCLPingPongProc++;
735: }
736: // Correct next opcode for last call op.
737: (pDCLPingPongProc-1)->pNextDCLCommand = (DCLCommandPtr)&fJumpToStart;
738:
739: // Loop to start of ping pong.
740: fJumpToStart.pNextDCLCommand = NULL;
741: fJumpToStart.opcode = kDCLJumpOp | kFWDCLOpDynamicFlag;
742: fJumpToStart.pJumpDCLLabel = &fStartLabel;
743:
744: return fHWProgram->compile(speed, chan);
745: }
746:
747: IOReturn IODCLTranslateListen::start()
748: {
749: fPingCount = 0;
750: return fHWProgram->start();
751: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.