2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
26 * Permission to use, copy, modify, and distribute this software and
27 * its documentation for any purpose and without fee is hereby granted,
28 * provided that the above copyright notice appears in all copies and
29 * that both the copyright notice and this permission notice appear in
30 * supporting documentation.
32 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
33 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
34 * FOR A PARTICULAR PURPOSE.
36 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
37 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
38 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
39 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
40 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44 * Copyright 1996 1995 by Apple Computer, Inc. 1997 1996 1995 1994 1993 1992 1991
47 * Permission to use, copy, modify, and distribute this software and
48 * its documentation for any purpose and without fee is hereby granted,
49 * provided that the above copyright notice appears in all copies and
50 * that both the copyright notice and this permission notice appear in
51 * supporting documentation.
53 * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
54 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
55 * FOR A PARTICULAR PURPOSE.
57 * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
58 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
59 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
60 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
61 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
67 * 18 June 1998 sdouglas Start IOKit version.
68 * 16 Nov 1998 suurballe Port to c++
72 #include <mach/mach_types.h>
74 #include "IOADBControllerUserClient.h"
75 #include <IOKit/adb/IOADBController.h>
76 #include <IOKit/adb/IOADBDevice.h>
77 #include <libkern/c++/OSSymbol.h>
78 #include <libkern/c++/OSNumber.h>
79 #include <IOKit/IOLib.h>
80 #include <IOKit/pwr_mgt/RootDomain.h>
81 #include "IOADBBusPriv.h"
83 bool ADBhasRoot( OSObject
*, void *, IOService
* );
84 void doProbe ( thread_call_param_t
, thread_call_param_t
);
86 #define kTenSeconds 10000000
88 #define super IOADBBus
90 OSDefineMetaClass(IOADBController
,IOADBBus
)
91 OSDefineAbstractStructors(IOADBController
,IOADBBus
)
94 // **********************************************************************************
97 // **********************************************************************************
98 bool IOADBController::start ( IOService
* nub
)
100 if( !super::start(nub
)) {
108 // creates the probe thread for when we wake up:
109 probeThread
= thread_call_allocate((thread_call_func_t
)doProbe
, (thread_call_param_t
)this);
110 if (probeThread
== NULL
) {
111 IOLog("IOADBController::start fails to call thread_call_allocate \n");
115 addNotification( gIOPublishNotification
,serviceMatching("IOPMrootDomain"), // look for the Root Domain
116 (IOServiceNotificationHandler
)ADBhasRoot
, this, 0 );
125 // **********************************************************************************
128 // The Root Power Domain has registered.
129 // Register as an interested driver so we find out when the system is
130 // going to sleep and waking up.
131 // **********************************************************************************
132 bool ADBhasRoot( OSObject
* us
, void *, IOService
* yourDevice
)
134 if ( yourDevice
!= NULL
) {
135 ((IOADBController
*)us
)->rootDomain
= (IOPMrootDomain
*)yourDevice
;
136 ((IOADBController
*)us
)->rootDomain
->registerInterestedDriver((IOService
*) us
);
142 //*********************************************************************************
143 // powerStateWillChangeTo
145 // We are notified here of power changes in the root domain.
147 // If power is going down in the root domain, then the system is going to
148 // sleep, and we tear down the ADB stack.
149 //*********************************************************************************
151 IOReturn
IOADBController::powerStateWillChangeTo ( IOPMPowerFlags theFlags
, unsigned long, IOService
*)
154 if ( ! (theFlags
& kIOPMPowerOn
) && ! (theFlags
& kIOPMDoze
) ) {
156 for ( i
= 1; i
< ADB_DEVICE_COUNT
; i
++ ) {
157 if( adbDevices
[ i
] != NULL
) {
158 if ( adbDevices
[ i
]->nub
) {
159 adbDevices
[ i
]->nub
->terminate(kIOServiceRequired
| kIOServiceSynchronous
);
160 adbDevices
[ i
]->nub
->release();
162 IOFree( adbDevices
[ i
], sizeof (ADBDeviceControl
));
163 adbDevices
[ i
] = NULL
;
167 return IOPMAckImplied
;
170 //*********************************************************************************
171 // powerStateDidChangeTo
173 // We are notified here of power changes in the root domain
175 // If power is has been brought up, then the system is waking from sleep.
176 // We re-probe the bus
177 //*********************************************************************************
178 IOReturn
IOADBController::powerStateDidChangeTo ( IOPMPowerFlags theFlags
, unsigned long, IOService
*)
180 if ( (theFlags
& kIOPMPowerOn
) || (theFlags
& kIOPMDoze
) ) {
182 thread_call_enter(probeThread
);
187 return IOPMAckImplied
;
191 void doProbe ( thread_call_param_t arg
, thread_call_param_t
)
193 ((IOADBController
*)arg
)->probeBus();
194 ((IOADBController
*)arg
)->rootDomain
->acknowledgePowerChange((IOService
*)arg
);
198 // **********************************************************************************
201 // **********************************************************************************
202 bool IOADBController::probeAddress ( IOADBAddress addr
)
205 ADBDeviceControl
* deviceInfo
;
210 err
= readFromDevice(addr
,3,(UInt8
*)&value
,&length
);
212 if (err
== ADB_RET_OK
) {
213 if( NULL
== (deviceInfo
= adbDevices
[ addr
])) {
215 deviceInfo
= (ADBDeviceControl
*)IOMalloc(sizeof(ADBDeviceControl
));
216 bzero(deviceInfo
, sizeof(ADBDeviceControl
));
218 adbDevices
[ addr
] = deviceInfo
;
219 deviceInfo
->defaultAddress
= addr
;
220 deviceInfo
->handlerID
= deviceInfo
->defaultHandlerID
= (value
& 0xff);
222 deviceInfo
->address
= addr
;
224 return( (err
== ADB_RET_OK
));
228 // **********************************************************************************
231 // **********************************************************************************
232 unsigned int IOADBController::firstBit ( unsigned int mask
)
236 while( 0 == (mask
& (1 << bit
))) {
243 // **********************************************************************************
246 // **********************************************************************************
247 bool IOADBController::moveDeviceFrom ( IOADBAddress from
, IOADBAddress to
, bool check
)
255 value
= ((to
<< 8) | ADB_DEVCMD_CHANGE_ID
);
257 err
= writeToDevice(from
,3,(UInt8
*)&value
,&length
);
259 adbDevices
[ to
] = adbDevices
[ from
];
261 moved
= probeAddress(to
);
263 if( moved
|| (!check
)) {
264 adbDevices
[ from
] = NULL
;
267 adbDevices
[ to
] = NULL
;
274 // **********************************************************************************
277 // **********************************************************************************
278 IOReturn
IOADBController::probeBus ( void )
281 UInt32 unresolvedAddrs
;
283 IOADBAddress freeNum
, devNum
;
284 IOADBDevice
* newDev
;
285 OSDictionary
* newProps
;
287 const OSNumber
* object
;
288 const OSSymbol
* key
;
290 /* Kill the auto poll until a new dev id's have been setup */
291 setAutoPollEnable(false);
294 * Send a ADB bus reset - reply is sent after bus has reset,
295 * so there is no need to wait for the reset to complete.
301 * Okay, now attempt reassign the
308 /* Skip 0 -- it's special! */
309 for (i
= 1; i
< ADB_DEVICE_COUNT
; i
++) {
310 if( probeAddress(i
) ) {
311 unresolvedAddrs
|= ( 1 << i
);
312 freeAddrs
&= ~( 1 << i
);
316 /* Now attempt to reassign the addresses */
317 while( unresolvedAddrs
) {
319 panic("ADB: Cannot find a free ADB slot for reassignment!");
322 freeNum
= firstBit(freeAddrs
);
323 devNum
= firstBit(unresolvedAddrs
);
325 if( !moveDeviceFrom(devNum
, freeNum
, true) ) {
327 /* It didn't move.. bad! */
328 IOLog("WARNING : ADB DEVICE %d having problems "
329 "probing!\n", devNum
);
332 if( probeAddress(devNum
) ) {
333 /* Found another device at the address, leave
334 * the first device moved to one side and set up
335 * newly found device for probing
337 freeAddrs
&= ~( 1 << freeNum
);
343 /* no more at this address, good !*/
345 moveDeviceFrom(freeNum
,devNum
,false);
349 unresolvedAddrs
&= ~( 1 << devNum
);
353 IOLog("ADB present:%lx\n", (freeAddrs
^ 0xfffe));
355 setAutoPollList(freeAddrs
^ 0xfffe);
357 setAutoPollPeriod(11111);
359 setAutoPollEnable(true);
362 for ( i
= 1; i
< ADB_DEVICE_COUNT
; i
++ ) {
363 if( 0 == adbDevices
[ i
] ) {
366 newDev
= new IOADBDevice
; // make a nub
367 if ( newDev
== NULL
) {
370 adbDevices
[ i
]->nub
= newDev
; // keep a pointer to it
372 newProps
= OSDictionary::withCapacity( 10 ); // create a property table for it
373 if ( newProps
== NULL
) {
378 key
= OSSymbol::withCString(ADBaddressProperty
); // make key/object for address
385 object
= OSNumber::withNumber((unsigned long long)adbDevices
[i
]->address
,8);
386 if ( object
== NULL
) {
392 newProps
->setObject(key
, (OSObject
*)object
); // put it in newProps
396 key
= OSSymbol::withCString(ADBhandlerIDProperty
); // make key/object for handlerID
402 object
= OSNumber::withNumber((unsigned long long)adbDevices
[i
]->handlerID
,8);
403 if ( object
== NULL
) {
409 newProps
->setObject(key
, (OSObject
*)object
); // put it in newProps
413 key
= OSSymbol::withCString(ADBdefAddressProperty
); // make key/object for default addr
419 object
= OSNumber::withNumber((unsigned long long)adbDevices
[i
]->defaultAddress
,8);
420 if ( object
== NULL
) {
426 newProps
->setObject(key
, (OSObject
*)object
); // put it in newProps
430 key
= OSSymbol::withCString(ADBdefHandlerProperty
); // make key/object for default h id
436 object
= OSNumber::withNumber((unsigned long long)adbDevices
[i
]->defaultHandlerID
,8);
437 if ( object
== NULL
) {
443 newProps
->setObject(key
, (OSObject
*)object
); // put it in newProps
447 if ( ! newDev
->init(newProps
,adbDevices
[i
]) ) { // give it to our new nub
448 kprintf("adb nub init failed\n");
453 sprintf(nameStr
,"%x-%02x",adbDevices
[i
]->defaultAddress
,adbDevices
[i
]->handlerID
);
454 newDev
->setName(nameStr
);
455 sprintf(nameStr
, "%x", adbDevices
[i
]->defaultAddress
);
456 newDev
->setLocation(nameStr
);
458 newProps
->release(); // we're done with it
459 if ( !newDev
->attach(this) ) {
460 kprintf("adb nub attach failed\n");
465 newDev
->registerService();
468 return kIOReturnSuccess
;
472 // **********************************************************************************
475 // **********************************************************************************
476 void autopollHandler ( IOService
* us
, UInt8 adbCommand
, IOByteCount length
, UInt8
* data
)
478 ((IOADBController
*)us
)->packet(data
,length
,adbCommand
);
482 // **********************************************************************************
485 // **********************************************************************************
486 void IOADBController::packet ( UInt8
* data
, IOByteCount length
, UInt8 adbCommand
)
488 ADBDeviceControl
* deviceInfo
;
490 deviceInfo
= adbDevices
[ adbCommand
>> 4 ];
491 if( deviceInfo
!= NULL
) {
492 if( deviceInfo
->owner
!= NULL
) {
493 deviceInfo
->handler(deviceInfo
->owner
, adbCommand
, length
, data
);
497 // new device arrival?
498 // IOLog("IOADBBus: new device @%x\n", address);
503 // **********************************************************************************
506 // **********************************************************************************
507 bool IOADBController::matchNubWithPropertyTable( IOService
* device
, OSDictionary
* propTable
)
509 bool matched
= false;
511 ADBDeviceControl
* deviceInfo
= (ADBDeviceControl
*)(((IOADBDevice
*)device
)->busRef());
515 X
= propTable
->getObject("ADB Match");
519 keys
= ((OSString
*)X
)->getCStringNoCopy();
524 if( deviceInfo
->defaultAddress
!= strtol(keys
, (char **) &keys
, 16)) {
528 if( *keys
++ == '-' ) {
529 if( deviceInfo
->defaultHandlerID
!= strtol(keys
, (char **) &keys
, 16)) {
542 // **********************************************************************************
545 // **********************************************************************************
546 IOReturn
IOADBController::setOwner ( void * device
, IOService
* client
, ADB_callback_func handler
)
548 ADBDeviceControl
* deviceInfo
= (ADBDeviceControl
*)device
;
550 deviceInfo
->handler
= handler
;
551 deviceInfo
->owner
= client
;
552 return kIOReturnSuccess
;
556 // **********************************************************************************
559 // **********************************************************************************
560 IOReturn
IOADBController::clearOwner ( void * device
)
562 ADBDeviceControl
* deviceInfo
= (ADBDeviceControl
*)device
;
563 kprintf("IOADBController::clearOwner\n");
565 deviceInfo
->owner
= NULL
;
566 deviceInfo
->handler
= NULL
;
567 return kIOReturnSuccess
;
571 // **********************************************************************************
574 // Called by the user client
575 // **********************************************************************************
576 IOReturn
IOADBController::claimDevice (unsigned long ADBaddress
, IOService
* client
, ADB_callback_func handler
)
578 if ( claimed_devices
[ADBaddress
] == true ) { // is this address already claimed by the user?
579 return kIOReturnExclusiveAccess
; // yes
581 if ( adbDevices
[ADBaddress
] == NULL
) { // no, is there a device at that address?
582 return kIOReturnNoDevice
; // no
584 if (adbDevices
[ADBaddress
]->handler
!= NULL
) { // yes, is it already owned by the kernel?
585 return kIOReturnExclusiveAccess
; // yes
587 claimed_devices
[ADBaddress
] = true; // no, user can have it
588 return kIOReturnSuccess
;
592 // **********************************************************************************
595 // Called by the user client
596 // **********************************************************************************
597 IOReturn
IOADBController::releaseDevice (unsigned long ADBaddress
)
599 if ( claimed_devices
[ADBaddress
] == false ) {
600 return kIOReturnBadArgument
;
603 claimed_devices
[ADBaddress
] = false;
605 return kIOReturnSuccess
;
609 // **********************************************************************************
612 // Called by the user client
613 // **********************************************************************************
614 IOReturn
IOADBController::readDeviceForUser (unsigned long address
, unsigned long adbRegister
,
615 UInt8
* data
, IOByteCount
* length
)
617 if ( claimed_devices
[address
] == false ) {
618 return kIOReturnBadArgument
;
621 return (readFromDevice((IOADBAddress
)address
,(IOADBRegister
)adbRegister
,data
,length
));
625 // **********************************************************************************
626 // writeDeviceForUser
628 // Called by the user client
629 // **********************************************************************************
630 IOReturn
IOADBController::writeDeviceForUser (unsigned long address
, unsigned long adbRegister
,
631 UInt8
* data
, IOByteCount
* length
)
633 if ( claimed_devices
[address
] == false ) {
634 return kIOReturnBadArgument
;
637 return (writeToDevice((IOADBAddress
)address
,(IOADBRegister
)adbRegister
,data
,length
));
641 // **********************************************************************************
644 // **********************************************************************************
645 IOADBAddress
IOADBController::address ( ADBDeviceControl
* busRef
)
647 return busRef
->address
;
651 // **********************************************************************************
654 // **********************************************************************************
655 IOADBAddress
IOADBController::defaultAddress ( ADBDeviceControl
* busRef
)
657 return busRef
->defaultAddress
;
661 // **********************************************************************************
664 // **********************************************************************************
665 UInt8
IOADBController::handlerID ( ADBDeviceControl
* busRef
)
667 return busRef
->handlerID
;
671 // **********************************************************************************
674 // **********************************************************************************
675 UInt8
IOADBController::defaultHandlerID ( ADBDeviceControl
* busRef
)
677 return busRef
->defaultHandlerID
;
681 // **********************************************************************************
684 // **********************************************************************************
685 IOReturn
IOADBController::cancelAllIO ( void )
687 return kIOReturnSuccess
;
691 // **********************************************************************************
694 // **********************************************************************************
695 IOReturn
IOADBController::flush ( ADBDeviceControl
* busRef
)
697 return(flushDevice(busRef
->address
));
701 // **********************************************************************************
704 // **********************************************************************************
705 IOReturn
IOADBController::readRegister ( ADBDeviceControl
* busRef
, IOADBRegister adbRegister
,
706 UInt8
* data
, IOByteCount
* length
)
708 return readFromDevice(busRef
->address
,adbRegister
,data
,length
);
712 // **********************************************************************************
715 // **********************************************************************************
716 IOReturn
IOADBController::writeRegister ( ADBDeviceControl
* busRef
, IOADBRegister adbRegister
,
717 UInt8
* data
, IOByteCount
* length
)
719 return writeToDevice(busRef
->address
,adbRegister
,data
,length
);
723 // **********************************************************************************
726 // **********************************************************************************
727 IOReturn
IOADBController::setHandlerID ( ADBDeviceControl
* deviceInfo
, UInt8 handlerID
)
732 IOADBAddress addr
= deviceInfo
->address
;
735 err
= readFromDevice(addr
,3,(UInt8
*)&value
,&length
);
741 value
= (value
& 0xf000) | handlerID
| (addr
<< 8);
742 length
= sizeof(value
);
743 err
= writeToDevice(addr
,3,(UInt8
*)&value
,&length
);
745 length
= sizeof(value
);
746 err
= readFromDevice(addr
,3,(UInt8
*)&value
,&length
);
748 if ( err
== kIOReturnSuccess
) {
749 deviceInfo
->handlerID
= value
& 0xff;
752 if ( deviceInfo
->handlerID
== handlerID
) {
753 err
= kIOReturnSuccess
;
756 err
= kIOReturnNoResources
;
763 // **********************************************************************************
764 // getURLComponentUnit
766 // **********************************************************************************
767 int IOADBController::getURLComponentUnit ( IOService
* device
, char * path
, int maxLen
)
769 ADBDeviceControl
* deviceInfo
= (ADBDeviceControl
*)((IOADBDevice
*)device
)->busRef();
772 sprintf( path
, "%x", deviceInfo
->address
);
781 // **********************************************************************************
784 // **********************************************************************************
785 IOReturn
IOADBController::newUserClient( task_t owningTask
, void * /* security_id */, UInt32 type
, IOUserClient
** handler
)
787 IOReturn err
= kIOReturnSuccess
;
788 IOADBControllerUserClient
* client
;
790 client
= IOADBControllerUserClient::withTask(owningTask
);
792 if( !client
|| (false == client
->attach( this )) ||
793 (false == client
->start( this )) ) {
795 client
->detach( this );
799 err
= kIOReturnNoMemory
;