1/*
2 *  IOFWLocalIsochPort.cpp
3 *  IOFireWireFamily
4 *
5 *  Created by Niels on Tue Mar 25 2003.
6 *  Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
7 *
8 *	$ Log:IOFWLocalIsochPort.cpp,v $
9 */
10
11#import "IOFWLocalIsochPort.h"
12#import "IOFWDCLProgram.h"
13#import "IOFireWireController.h"
14#import "FWDebugging.h"
15
16OSDefineMetaClassAndStructors(IOFWLocalIsochPort, IOFWIsochPort)
17OSMetaClassDefineReservedUnused(IOFWLocalIsochPort, 0);
18OSMetaClassDefineReservedUnused(IOFWLocalIsochPort, 1);
19
20bool
21IOFWLocalIsochPort::init (
22		IODCLProgram *			program,
23		IOFireWireController *	control)
24{
25	if ( ! IOFWIsochPort::init( ) )
26		return false;
27
28	fProgram = program; // belongs to us.
29
30	fControl = control;
31
32	return true;
33}
34
35void IOFWLocalIsochPort::free()
36{
37	if ( fProgram )
38	{
39		fProgram->stop() ;
40
41		fProgram->release () ;
42		fProgram = NULL ;
43	}
44
45	IOFWIsochPort::free();
46}
47
48// Return maximum speed and channels supported
49// (bit n set = chan n supported)
50IOReturn IOFWLocalIsochPort::getSupported(IOFWSpeed &maxSpeed, UInt64 &chanSupported)
51{
52	maxSpeed = kFWSpeedMaximum;
53	chanSupported = ~(UInt64)0;
54	return kIOReturnSuccess;
55}
56
57/*
58 * Allocate hardware resources for port, via workloop
59 * Then compile program, not on workloop.
60 */
61IOReturn IOFWLocalIsochPort::allocatePort(IOFWSpeed speed, UInt32 chan)
62{
63	IOReturn res;
64
65	res = fProgram->allocateHW(speed, chan);
66
67	if(kIOReturnSuccess != res)
68		return res;
69
70	return fProgram->compile(speed, chan);	// Not on workloop
71}
72
73IOReturn IOFWLocalIsochPort::releasePort()
74{
75	IOReturn res;
76
77//	fControl->closeGate();
78	res = fProgram->releaseHW();
79//	fControl->openGate();
80	return res;
81}
82
83IOReturn IOFWLocalIsochPort::start()
84{
85	IOReturn res;
86
87//	fControl->closeGate();
88	res = fProgram->start();
89//	fControl->openGate();
90	return res;
91}
92
93IOReturn IOFWLocalIsochPort::stop()
94{
95//	fControl->closeGate();
96	fProgram->stop();
97//	fControl->openGate();
98	return kIOReturnSuccess;
99}
100
101IOReturn IOFWLocalIsochPort::notify( IOFWDCLNotificationType notificationType,
102	DCLCommand** dclCommandList, UInt32 numDCLCommands)
103{
104	IOReturn res;
105
106	res = fProgram->notify(notificationType,
107								dclCommandList, numDCLCommands);
108	return res;
109}
110
111void
112IOFWLocalIsochPort::printDCLProgram (
113	const DCLCommand *		dcl,
114	UInt32					count,
115	void (*printFN)( const char *format, ...),
116	unsigned 				lineDelayMS )
117{
118	const DCLCommand *	currentDCL = dcl ;
119	UInt32 				index		= 0 ;
120
121#if FIRELOG
122	if( printFN == NULL )
123	{
124		printFN = FireLog;
125	}
126#endif
127
128	if( printFN == NULL )
129	{
130		// nothing to print if there's no printer function
131		return;
132	}
133
134	(*printFN)("printDCLProgram program %p, count %x\n", currentDCL, count) ;
135
136	while ( ( count == 0 || index < count ) && currentDCL )
137	{
138		(*printFN)("#%x  @%p   next=%p, cmplrData=%p, op=%u ",
139			index,
140			currentDCL,
141			currentDCL->pNextDCLCommand,
142			currentDCL->compilerData,
143			(int) currentDCL->opcode) ;
144
145		switch(currentDCL->opcode & ~kFWDCLOpFlagMask)
146		{
147			case kDCLSendPacketStartOp:
148			//case kDCLSendPacketWithHeaderStartOp:
149			case kDCLSendPacketOp:
150			case kDCLReceivePacketStartOp:
151			case kDCLReceivePacketOp:
152				(*printFN)("(DCLTransferPacket) buffer=%p, size=%u",
153					((DCLTransferPacket*)currentDCL)->buffer,
154					(int)((DCLTransferPacket*)currentDCL)->size) ;
155				break ;
156
157			case kDCLSendBufferOp:
158			case kDCLReceiveBufferOp:
159				(*printFN)("(DCLTransferBuffer) buffer=%p, size=%lu, packetSize=%08X, bufferOffset=%08lX",
160					((DCLTransferBuffer*)currentDCL)->buffer,
161					((DCLTransferBuffer*)currentDCL)->size,
162					((DCLTransferBuffer*)currentDCL)->packetSize,
163					(UInt32)((DCLTransferBuffer*)currentDCL)->bufferOffset) ;
164				break ;
165
166			case kDCLCallProcOp:
167				(*printFN)("(DCLCallProc) proc=%p, procData=%08lX",
168					((DCLCallProc*)currentDCL)->proc,
169					((DCLCallProc*)currentDCL)->procData ) ;
170				break ;
171
172			case kDCLLabelOp:
173				(*printFN)("(DCLLabel)") ;
174				break ;
175
176			case kDCLJumpOp:
177				(*printFN)("(DCLJump) pJumpDCLLabel=%p",
178					((DCLJump*)currentDCL)->pJumpDCLLabel) ;
179				break ;
180
181			case kDCLSetTagSyncBitsOp:
182				(*printFN)("(DCLSetTagSyncBits) tagBits=%04lX, syncBits=%04lX",
183					(UInt32)((DCLSetTagSyncBits*)currentDCL)->tagBits,
184					(UInt32)((DCLSetTagSyncBits*)currentDCL)->syncBits) ;
185				break ;
186
187			case kDCLUpdateDCLListOp:
188				(*printFN)("(DCLUpdateDCLList) dclCommandList=%p, numDCLCommands=%lud\n",
189					((DCLUpdateDCLList*)currentDCL)->dclCommandList,
190					((DCLUpdateDCLList*)currentDCL)->numDCLCommands) ;
191
192				for(UInt32 listIndex=0; listIndex < ((DCLUpdateDCLList*)currentDCL)->numDCLCommands; ++listIndex)
193				{
194					(*printFN)("%p ", (((DCLUpdateDCLList*)currentDCL)->dclCommandList)[listIndex]) ;
195					if ( listIndex % 10 == 0 )
196						(*printFN)("\n") ;
197					IOSleep(8) ;
198				}
199
200				(*printFN)("\n") ;
201				break ;
202
203			case kDCLPtrTimeStampOp:
204				(*printFN)("(DCLPtrTimeStamp) timeStampPtr=%p",
205					((DCLPtrTimeStamp*)currentDCL)->timeStampPtr) ;
206				break ;
207
208			case kDCLSkipCycleOp:
209				(*printFN)("(DCLSkipCycleOp)") ;
210				break ;
211
212			case kDCLNuDCLLeaderOp:
213				(*printFN)("(DCLNuDCLLeaderOp) DCL pool=%p", ((DCLNuDCLLeader*)currentDCL)->program ) ;
214				break ;
215		}
216
217		(*printFN)("\n") ;
218
219		currentDCL = currentDCL->pNextDCLCommand ;
220		++index ;
221
222		if ( lineDelayMS )
223		{
224			IOSleep( lineDelayMS ) ;
225		}
226	}
227
228	if ( count > 0 )
229	{
230		if ( index != count )
231			(*printFN)("unexpected end of program\n") ;
232
233		if ( currentDCL != NULL )
234			(*printFN)("program too long for count\n") ;
235	}
236}
237
238IOReturn
239IOFWLocalIsochPort::setIsochResourceFlags (
240	IOFWIsochResourceFlags		flags )
241{
242	fProgram->setIsochResourceFlags( flags ) ;
243	return kIOReturnSuccess ;
244}
245
246IODCLProgram *
247IOFWLocalIsochPort::getProgramRef() const
248{
249	fProgram->retain() ;
250	return fProgram ;
251}
252
253IOReturn
254IOFWLocalIsochPort::synchronizeWithIO()
255{
256	return fProgram->synchronizeWithIO() ;
257}
258