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#include <CoreFoundation/CoreFoundation.h>
24
25#include "FWDebugging.h"
26#include "IOFireWireSBP2LibORB.h"
27#include "IOFireWireSBP2LibLogin.h"
28#include "IOFireWireSBP2LibMgmtORB.h"
29
30__BEGIN_DECLS
31#include <IOKit/iokitmig.h>
32__END_DECLS
33
34//
35// static interface table for IOFireWireSBP2LibMgmtORBInterface
36//
37
38IOFireWireSBP2LibMgmtORBInterface IOFireWireSBP2LibMgmtORB::sIOFireWireSBP2LibMgmtORBInterface =
39{
40    0,
41	&IOFireWireSBP2LibMgmtORB::staticQueryInterface,
42	&IOFireWireSBP2LibMgmtORB::staticAddRef,
43	&IOFireWireSBP2LibMgmtORB::staticRelease,
44	1, 0, // version/revision
45	&IOFireWireSBP2LibMgmtORB::staticSubmitORB,
46	&IOFireWireSBP2LibMgmtORB::staticSetORBCallback,
47	&IOFireWireSBP2LibMgmtORB::staticSetRefCon,
48	&IOFireWireSBP2LibMgmtORB::staticGetRefCon,
49	&IOFireWireSBP2LibMgmtORB::staticSetCommandFunction,
50	&IOFireWireSBP2LibMgmtORB::staticSetManageeORB,
51	&IOFireWireSBP2LibMgmtORB::staticSetManageeLogin,
52	&IOFireWireSBP2LibMgmtORB::staticSetResponseBuffer
53
54};
55
56// alloc
57//
58// static allocator, called by factory method
59
60IUnknownVTbl ** IOFireWireSBP2LibMgmtORB::alloc( io_connect_t connection,
61											     mach_port_t asyncPort )
62{
63    IOReturn					status = kIOReturnSuccess;
64	IOFireWireSBP2LibMgmtORB *	me;
65	IUnknownVTbl ** 			interface = NULL;
66
67	if( status == kIOReturnSuccess )
68	{
69		me = new IOFireWireSBP2LibMgmtORB();
70		if( me == NULL )
71			status = kIOReturnError;
72	}
73
74	if( status == kIOReturnSuccess )
75	{
76		status = me->init( connection, asyncPort );
77	}
78
79	if( status != kIOReturnSuccess )
80		delete me;
81
82	if( status == kIOReturnSuccess )
83	{
84		// we return an interface here. queryInterface will not be called. call addRef here
85		me->addRef();
86		interface = (IUnknownVTbl **) &me->fIOFireWireSBP2LibMgmtORBInterface.pseudoVTable;
87	}
88
89	return interface;
90}
91
92// ctor
93//
94//
95
96IOFireWireSBP2LibMgmtORB::IOFireWireSBP2LibMgmtORB( void )
97{
98	// init cf plugin ref counting
99	fRefCount = 0;
100	fConnection = 0;
101	fMgmtORBRef = 0;
102	fRefCon = 0;
103	fORBCallbackRoutine = NULL;
104	fORBCallbackRefCon = NULL;
105
106	// create test driver interface map
107	fIOFireWireSBP2LibMgmtORBInterface.pseudoVTable
108								= (IUnknownVTbl *) &sIOFireWireSBP2LibMgmtORBInterface;
109	fIOFireWireSBP2LibMgmtORBInterface.obj = this;
110
111}
112
113// init
114//
115//
116
117IOReturn IOFireWireSBP2LibMgmtORB::init( io_connect_t connection, mach_port_t asyncPort )
118{
119	IOReturn status = kIOReturnSuccess;
120
121	fConnection = connection;
122	fAsyncPort = asyncPort;
123
124	FWLOG(( "IOFireWireSBP2LibMgmtORB : fConnection %d, fAsyncPort %d\n",
125												fConnection, fAsyncPort ));
126
127	if( !fConnection || !fAsyncPort )
128		status = kIOReturnError;
129
130	if( status == kIOReturnSuccess )
131	{
132		uint32_t len = 1;
133		status = IOConnectCallScalarMethod( connection,
134											kIOFWSBP2UserClientCreateMgmtORB,
135											NULL, 0, &fMgmtORBRef, &len );
136		if( status != kIOReturnSuccess )
137			fMgmtORBRef = 0; // just to make sure
138
139		#if __LP64__
140			FWLOG(( "IOFireWireSBP2LibMgmtORB<%p> :  status = 0x%08x = fMgmtORBRef 0x%016llx\n", this, status, fMgmtORBRef ));
141		#else
142			FWLOG(( "IOFireWireSBP2LibMgmtORB<%p> :  status = 0x%08x = fMgmtORBRef 0x%016llx\n", this, status, fMgmtORBRef ));
143		#endif
144	}
145
146	if( status == kIOReturnSuccess )
147	{
148		io_async_ref64_t asyncRef;
149		mach_msg_type_number_t	size = 0;
150
151		asyncRef[kIOAsyncCalloutFuncIndex]	= (uint64_t)&IOFireWireSBP2LibMgmtORB::staticORBCompletion;
152		asyncRef[kIOAsyncCalloutRefconIndex]	= (uint64_t)this;
153
154		uint64_t params[1];
155		params[0] = fMgmtORBRef;
156
157		status = IOConnectCallAsyncScalarMethod( fConnection, kIOFWSBP2UserClientSetMgmtORBCallback, fAsyncPort, asyncRef, 3, params, 1, NULL, &size  );
158	}
159
160	return status;
161}
162
163// dtor
164//
165//
166
167IOFireWireSBP2LibMgmtORB::~IOFireWireSBP2LibMgmtORB()
168{
169	if( fMgmtORBRef )
170	{
171		IOReturn status = kIOReturnSuccess;
172
173		uint32_t len = 0;
174		status = IOConnectCallScalarMethod( fConnection,
175											kIOFWSBP2UserClientReleaseMgmtORB,
176											&fMgmtORBRef, 1, NULL, &len );
177		FWLOG(( "IOFireWireSBP2LibMgmtORB : release orb status = 0x%08x\n", status ));
178	}
179}
180
181
182//////////////////////////////////////////////////////////////////
183// IUnknown methods
184//
185
186// queryInterface
187//
188//
189
190HRESULT IOFireWireSBP2LibMgmtORB::staticQueryInterface( void * self, REFIID iid, void **ppv )
191{
192	return getThis(self)->queryInterface( iid, ppv );
193}
194
195HRESULT IOFireWireSBP2LibMgmtORB::queryInterface( REFIID iid, void **ppv )
196{
197    CFUUIDRef uuid = CFUUIDCreateFromUUIDBytes(NULL, iid);
198    HRESULT result = S_OK;
199
200	if( CFEqual(uuid, IUnknownUUID) ||  CFEqual(uuid, kIOFireWireSBP2LibMgmtORBInterfaceID) )
201	{
202        *ppv = &fIOFireWireSBP2LibMgmtORBInterface;
203        addRef();
204    }
205    else
206        *ppv = 0;
207
208    if( !*ppv )
209        result = E_NOINTERFACE;
210
211    CFRelease( uuid );
212
213    return result;
214}
215
216// addRef
217//
218//
219
220UInt32 IOFireWireSBP2LibMgmtORB::staticAddRef( void * self )
221{
222	return getThis(self)->addRef();
223}
224
225UInt32 IOFireWireSBP2LibMgmtORB::addRef()
226{
227    fRefCount += 1;
228    return fRefCount;
229}
230
231// release
232//
233//
234
235UInt32 IOFireWireSBP2LibMgmtORB::staticRelease( void * self )
236{
237	return getThis(self)->release();
238}
239
240UInt32 IOFireWireSBP2LibMgmtORB::release( void )
241{
242	UInt32 retVal = fRefCount;
243
244	if( 1 == fRefCount-- )
245	{
246		delete this;
247    }
248
249	return retVal;
250}
251
252//////////////////////////////////////////////////////////////////
253// IOFireWireSBP2LibMgmtORB methods
254
255// submitORB
256//
257//
258
259IOReturn IOFireWireSBP2LibMgmtORB::staticSubmitORB( void * self )
260{
261	return getThis(self)->submitORB();
262}
263
264IOReturn IOFireWireSBP2LibMgmtORB::submitORB( void )
265{
266	IOReturn status = kIOReturnSuccess;
267
268	FWLOG(( "IOFireWireSBP2LibMgmtORB : submitORB\n" ));
269
270	uint32_t len = 0;
271	status = IOConnectCallScalarMethod( fConnection,
272										kIOFWSBP2UserClientSubmitMgmtORB,
273										&fMgmtORBRef, 1, NULL, &len );
274	return status;
275}
276
277// setORBCallback
278//
279//
280
281void IOFireWireSBP2LibMgmtORB::staticSetORBCallback( void * self, void * refCon,
282													IOFWSBP2ORBAppendCallback callback )
283{
284	getThis(self)->setORBCallback( refCon, callback );
285}
286
287void IOFireWireSBP2LibMgmtORB::setORBCallback( void * refCon,
288													IOFWSBP2ORBAppendCallback callback )
289{
290	fORBCallbackRoutine = callback;
291	fORBCallbackRefCon = refCon;
292}
293
294// setRefCon
295//
296//
297
298void IOFireWireSBP2LibMgmtORB::staticSetRefCon( void * self, void * refCon )
299{
300	getThis(self)->setRefCon( refCon );
301}
302
303void IOFireWireSBP2LibMgmtORB::setRefCon( void * refCon )
304{
305	fRefCon = refCon;
306}
307
308// getRefCon
309//
310//
311
312void * IOFireWireSBP2LibMgmtORB::staticGetRefCon( void * self )
313{
314	return getThis(self)->getRefCon();
315}
316
317void * IOFireWireSBP2LibMgmtORB::getRefCon( void )
318{
319	return fRefCon;
320}
321
322// setCommandFunction
323//
324//
325
326IOReturn IOFireWireSBP2LibMgmtORB::staticSetCommandFunction
327										( void * self, UInt32 function )
328{
329	return getThis(self)->setCommandFunction( function );
330}
331
332IOReturn IOFireWireSBP2LibMgmtORB::setCommandFunction( UInt32 function )
333{
334	IOReturn status = kIOReturnSuccess;
335
336	if( fMgmtORBRef == 0 )
337		status = kIOReturnError;
338
339	if( status == kIOReturnSuccess )
340	{
341		uint32_t len = 0;
342		uint64_t params[2];
343
344		params[0] = fMgmtORBRef;
345		params[1] = function;
346
347		status = IOConnectCallScalarMethod
348						( fConnection,
349						  kIOFWSBP2UserClientMgmtORBSetCommandFunction,
350						  params, 2, NULL, &len );
351
352		FWLOG(( "IOFireWireSBP2LibMgmtORB : setCommandFunction = 0x%08x\n", (uint32_t)function ));
353	}
354
355	return status;
356}
357
358
359// setManageeORB
360//
361//
362
363IOReturn IOFireWireSBP2LibMgmtORB::staticSetManageeORB( void * self, void * orb )
364{
365	return getThis(self)->setManageeORB( orb );
366}
367
368IOReturn IOFireWireSBP2LibMgmtORB::setManageeORB( void * orb )
369{
370	IOReturn status = kIOReturnSuccess;
371
372	if( fMgmtORBRef == 0 )
373		status = kIOReturnError;
374
375	UInt32 orbRef;
376
377	if( orb == NULL )
378		orbRef = 0;
379	else
380		orbRef = IOFireWireSBP2LibORB::getThis(orb)->getORBRef();
381
382	if( status == kIOReturnSuccess )
383	{
384		uint32_t len = 0;
385		uint64_t params[2];
386
387		params[0] = fMgmtORBRef;
388		params[1] = orbRef;
389
390		status = IOConnectCallScalarMethod
391						( fConnection,
392						  kIOFWSBP2UserClientMgmtORBSetManageeORB,
393						  params, 2, NULL, &len );
394	}
395
396	return status;
397}
398
399// setManageeLogin
400//
401//
402
403IOReturn IOFireWireSBP2LibMgmtORB::staticSetManageeLogin( void * self, void * login )
404{
405	return getThis(self)->setManageeLogin( login );
406}
407
408IOReturn IOFireWireSBP2LibMgmtORB::setManageeLogin( void * login )
409{
410	IOReturn status = kIOReturnSuccess;
411
412	if( fMgmtORBRef == 0 )
413		status = kIOReturnError;
414
415	UInt32 loginRef;
416
417	if( login == NULL )
418		loginRef = 0;
419	else
420		loginRef = IOFireWireSBP2LibLogin::getThis(login)->getLoginRef();
421
422	if( status == kIOReturnSuccess )
423	{
424		uint32_t len = 0;
425		uint64_t params[2];
426
427		params[0] = fMgmtORBRef;
428		params[1] = loginRef;
429
430		status = IOConnectCallScalarMethod
431						( fConnection,
432						  kIOFWSBP2UserClientMgmtORBSetManageeLogin,
433						  params, 2, NULL, &len );
434	}
435
436	return status;
437}
438
439// setResponseBuffer
440//
441//
442
443IOReturn IOFireWireSBP2LibMgmtORB::staticSetResponseBuffer
444								( void * self, void * buf, UInt32 len )
445{
446	return getThis(self)->setResponseBuffer( buf, len );
447}
448
449IOReturn IOFireWireSBP2LibMgmtORB::setResponseBuffer( void * buf, UInt32 len )
450{
451	IOReturn status = kIOReturnSuccess;
452
453	if( fMgmtORBRef == 0 )
454		status = kIOReturnError;
455
456	if( status == kIOReturnSuccess )
457	{
458		uint32_t len = 0;
459		uint64_t params[3];
460
461		params[0] = fMgmtORBRef;
462		params[1] = (uint64_t)buf;
463		params[2] = len;
464
465		status = IOConnectCallScalarMethod
466						( fConnection,
467						  kIOFWSBP2UserClientMgmtORBSetResponseBuffer,
468						  params, 3, NULL, &len );
469	}
470
471	return status;
472}
473
474//////////////////////////////////////////////////////////////////
475// callback methods
476
477void IOFireWireSBP2LibMgmtORB::staticORBCompletion( void *refcon, IOReturn result,
478													io_user_reference_t *args, int numArgs  )
479{
480	((IOFireWireSBP2LibMgmtORB*)refcon)->ORBCompletion( result, args, numArgs );
481}
482
483void IOFireWireSBP2LibMgmtORB::ORBCompletion( IOReturn result, io_user_reference_t *args, int numArgs )
484{
485	FWLOG(( "IOFireWireSBP2LibMgmtORB<%p> : ORBCompletion - fORBCallbackRoutine = %p, args = %p numArgs = %d\n",
486		this, fORBCallbackRoutine, args, numArgs ));
487
488	if( fORBCallbackRoutine != NULL )
489		(fORBCallbackRoutine)( fORBCallbackRefCon, (IOReturn)args[0], (void*)fRefCon );
490}
491