2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
29 * Permission to use, copy, modify, and distribute this software and
30 * its documentation for any purpose and without fee is hereby granted,
31 * provided that the above copyright notice appears in all copies and
32 * that both the copyright notice and this permission notice appear in
33 * supporting documentation.
35 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
36 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
37 * FOR A PARTICULAR PURPOSE.
39 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
40 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
41 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
42 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
43 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
47 * Copyright 1996 1995 by Apple Computer, Inc. 1997 1996 1995 1994 1993 1992 1991
50 * Permission to use, copy, modify, and distribute this software and
51 * its documentation for any purpose and without fee is hereby granted,
52 * provided that the above copyright notice appears in all copies and
53 * that both the copyright notice and this permission notice appear in
54 * supporting documentation.
56 * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
57 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
58 * FOR A PARTICULAR PURPOSE.
60 * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
61 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
62 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
63 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
64 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
70 * 18 June 1998 sdouglas Start IOKit version.
71 * 16 Nov 1998 suurballe Port to c++
75 #include <mach/mach_types.h>
77 #include "IOADBControllerUserClient.h"
78 #include <IOKit/adb/IOADBController.h>
79 #include <IOKit/adb/IOADBDevice.h>
80 #include <libkern/c++/OSSymbol.h>
81 #include <libkern/c++/OSNumber.h>
82 #include <IOKit/IOLib.h>
83 #include <IOKit/pwr_mgt/RootDomain.h>
84 #include "IOADBBusPriv.h"
86 bool ADBhasRoot( OSObject
*, void *, IOService
* );
87 void doProbe ( thread_call_param_t
, thread_call_param_t
);
89 #define kTenSeconds 10000000
91 #define super IOADBBus
93 OSDefineMetaClass(IOADBController
,IOADBBus
)
94 OSDefineAbstractStructors(IOADBController
,IOADBBus
)
97 // **********************************************************************************
100 // **********************************************************************************
101 bool IOADBController::start ( IOService
* nub
)
103 if( !super::start(nub
)) {
111 // creates the probe thread for when we wake up:
112 probeThread
= thread_call_allocate((thread_call_func_t
)doProbe
, (thread_call_param_t
)this);
113 if (probeThread
== NULL
) {
114 IOLog("IOADBController::start fails to call thread_call_allocate \n");
118 addNotification( gIOPublishNotification
,serviceMatching("IOPMrootDomain"), // look for the Root Domain
119 (IOServiceNotificationHandler
)ADBhasRoot
, this, 0 );
128 // **********************************************************************************
131 // The Root Power Domain has registered.
132 // Register as an interested driver so we find out when the system is
133 // going to sleep and waking up.
134 // **********************************************************************************
135 bool ADBhasRoot( OSObject
* us
, void *, IOService
* yourDevice
)
137 if ( yourDevice
!= NULL
) {
138 ((IOADBController
*)us
)->rootDomain
= (IOPMrootDomain
*)yourDevice
;
139 ((IOADBController
*)us
)->rootDomain
->registerInterestedDriver((IOService
*) us
);
145 //*********************************************************************************
146 // powerStateWillChangeTo
148 // We are notified here of power changes in the root domain.
150 // If power is going down in the root domain, then the system is going to
151 // sleep, and we tear down the ADB stack.
152 //*********************************************************************************
154 IOReturn
IOADBController::powerStateWillChangeTo ( IOPMPowerFlags theFlags
, unsigned long, IOService
*)
157 if ( ! (theFlags
& kIOPMPowerOn
) && ! (theFlags
& kIOPMDoze
) ) {
159 for ( i
= 1; i
< ADB_DEVICE_COUNT
; i
++ ) {
160 if( adbDevices
[ i
] != NULL
) {
161 if ( adbDevices
[ i
]->nub
) {
162 adbDevices
[ i
]->nub
->terminate(kIOServiceRequired
| kIOServiceSynchronous
);
163 adbDevices
[ i
]->nub
->release();
165 IOFree( adbDevices
[ i
], sizeof (ADBDeviceControl
));
166 adbDevices
[ i
] = NULL
;
170 return IOPMAckImplied
;
173 //*********************************************************************************
174 // powerStateDidChangeTo
176 // We are notified here of power changes in the root domain
178 // If power is has been brought up, then the system is waking from sleep.
179 // We re-probe the bus
180 //*********************************************************************************
181 IOReturn
IOADBController::powerStateDidChangeTo ( IOPMPowerFlags theFlags
, unsigned long, IOService
*)
183 if ( (theFlags
& kIOPMPowerOn
) || (theFlags
& kIOPMDoze
) ) {
185 thread_call_enter(probeThread
);
190 return IOPMAckImplied
;
194 void doProbe ( thread_call_param_t arg
, thread_call_param_t
)
196 ((IOADBController
*)arg
)->probeBus();
197 ((IOADBController
*)arg
)->rootDomain
->acknowledgePowerChange((IOService
*)arg
);
201 // **********************************************************************************
204 // **********************************************************************************
205 bool IOADBController::probeAddress ( IOADBAddress addr
)
208 ADBDeviceControl
* deviceInfo
;
213 err
= readFromDevice(addr
,3,(UInt8
*)&value
,&length
);
215 if (err
== ADB_RET_OK
) {
216 if( NULL
== (deviceInfo
= adbDevices
[ addr
])) {
218 deviceInfo
= (ADBDeviceControl
*)IOMalloc(sizeof(ADBDeviceControl
));
219 bzero(deviceInfo
, sizeof(ADBDeviceControl
));
221 adbDevices
[ addr
] = deviceInfo
;
222 deviceInfo
->defaultAddress
= addr
;
223 deviceInfo
->handlerID
= deviceInfo
->defaultHandlerID
= (value
& 0xff);
225 deviceInfo
->address
= addr
;
227 return( (err
== ADB_RET_OK
));
231 // **********************************************************************************
234 // **********************************************************************************
235 unsigned int IOADBController::firstBit ( unsigned int mask
)
239 while( 0 == (mask
& (1 << bit
))) {
246 // **********************************************************************************
249 // **********************************************************************************
250 bool IOADBController::moveDeviceFrom ( IOADBAddress from
, IOADBAddress to
, bool check
)
258 value
= ((to
<< 8) | ADB_DEVCMD_CHANGE_ID
);
260 err
= writeToDevice(from
,3,(UInt8
*)&value
,&length
);
262 adbDevices
[ to
] = adbDevices
[ from
];
264 moved
= probeAddress(to
);
266 if( moved
|| (!check
)) {
267 adbDevices
[ from
] = NULL
;
270 adbDevices
[ to
] = NULL
;
277 // **********************************************************************************
280 // **********************************************************************************
281 IOReturn
IOADBController::probeBus ( void )
284 UInt32 unresolvedAddrs
;
286 IOADBAddress freeNum
, devNum
;
287 IOADBDevice
* newDev
;
288 OSDictionary
* newProps
;
290 const OSNumber
* object
;
291 const OSSymbol
* key
;
293 /* Kill the auto poll until a new dev id's have been setup */
294 setAutoPollEnable(false);
297 * Send a ADB bus reset - reply is sent after bus has reset,
298 * so there is no need to wait for the reset to complete.
304 * Okay, now attempt reassign the
311 /* Skip 0 -- it's special! */
312 for (i
= 1; i
< ADB_DEVICE_COUNT
; i
++) {
313 if( probeAddress(i
) ) {
314 unresolvedAddrs
|= ( 1 << i
);
315 freeAddrs
&= ~( 1 << i
);
319 /* Now attempt to reassign the addresses */
320 while( unresolvedAddrs
) {
322 panic("ADB: Cannot find a free ADB slot for reassignment!");
325 freeNum
= firstBit(freeAddrs
);
326 devNum
= firstBit(unresolvedAddrs
);
328 if( !moveDeviceFrom(devNum
, freeNum
, true) ) {
330 /* It didn't move.. bad! */
331 IOLog("WARNING : ADB DEVICE %d having problems "
332 "probing!\n", devNum
);
335 if( probeAddress(devNum
) ) {
336 /* Found another device at the address, leave
337 * the first device moved to one side and set up
338 * newly found device for probing
340 freeAddrs
&= ~( 1 << freeNum
);
346 /* no more at this address, good !*/
348 moveDeviceFrom(freeNum
,devNum
,false);
352 unresolvedAddrs
&= ~( 1 << devNum
);
356 IOLog("ADB present:%lx\n", (freeAddrs
^ 0xfffe));
358 setAutoPollList(freeAddrs
^ 0xfffe);
360 setAutoPollPeriod(11111);
362 setAutoPollEnable(true);
365 for ( i
= 1; i
< ADB_DEVICE_COUNT
; i
++ ) {
366 if( 0 == adbDevices
[ i
] ) {
369 newDev
= new IOADBDevice
; // make a nub
370 if ( newDev
== NULL
) {
373 adbDevices
[ i
]->nub
= newDev
; // keep a pointer to it
375 newProps
= OSDictionary::withCapacity( 10 ); // create a property table for it
376 if ( newProps
== NULL
) {
381 key
= OSSymbol::withCString(ADBaddressProperty
); // make key/object for address
388 object
= OSNumber::withNumber((unsigned long long)adbDevices
[i
]->address
,8);
389 if ( object
== NULL
) {
395 newProps
->setObject(key
, (OSObject
*)object
); // put it in newProps
399 key
= OSSymbol::withCString(ADBhandlerIDProperty
); // make key/object for handlerID
405 object
= OSNumber::withNumber((unsigned long long)adbDevices
[i
]->handlerID
,8);
406 if ( object
== NULL
) {
412 newProps
->setObject(key
, (OSObject
*)object
); // put it in newProps
416 key
= OSSymbol::withCString(ADBdefAddressProperty
); // make key/object for default addr
422 object
= OSNumber::withNumber((unsigned long long)adbDevices
[i
]->defaultAddress
,8);
423 if ( object
== NULL
) {
429 newProps
->setObject(key
, (OSObject
*)object
); // put it in newProps
433 key
= OSSymbol::withCString(ADBdefHandlerProperty
); // make key/object for default h id
439 object
= OSNumber::withNumber((unsigned long long)adbDevices
[i
]->defaultHandlerID
,8);
440 if ( object
== NULL
) {
446 newProps
->setObject(key
, (OSObject
*)object
); // put it in newProps
450 if ( ! newDev
->init(newProps
,adbDevices
[i
]) ) { // give it to our new nub
451 kprintf("adb nub init failed\n");
456 sprintf(nameStr
,"%x-%02x",adbDevices
[i
]->defaultAddress
,adbDevices
[i
]->handlerID
);
457 newDev
->setName(nameStr
);
458 sprintf(nameStr
, "%x", adbDevices
[i
]->defaultAddress
);
459 newDev
->setLocation(nameStr
);
461 newProps
->release(); // we're done with it
462 if ( !newDev
->attach(this) ) {
463 kprintf("adb nub attach failed\n");
468 newDev
->registerService();
471 return kIOReturnSuccess
;
475 // **********************************************************************************
478 // **********************************************************************************
479 void autopollHandler ( IOService
* us
, UInt8 adbCommand
, IOByteCount length
, UInt8
* data
)
481 ((IOADBController
*)us
)->packet(data
,length
,adbCommand
);
485 // **********************************************************************************
488 // **********************************************************************************
489 void IOADBController::packet ( UInt8
* data
, IOByteCount length
, UInt8 adbCommand
)
491 ADBDeviceControl
* deviceInfo
;
493 deviceInfo
= adbDevices
[ adbCommand
>> 4 ];
494 if( deviceInfo
!= NULL
) {
495 if( deviceInfo
->owner
!= NULL
) {
496 deviceInfo
->handler(deviceInfo
->owner
, adbCommand
, length
, data
);
500 // new device arrival?
501 // IOLog("IOADBBus: new device @%x\n", address);
506 // **********************************************************************************
509 // **********************************************************************************
510 bool IOADBController::matchNubWithPropertyTable( IOService
* device
, OSDictionary
* propTable
)
512 bool matched
= false;
514 ADBDeviceControl
* deviceInfo
= (ADBDeviceControl
*)(((IOADBDevice
*)device
)->busRef());
518 X
= propTable
->getObject("ADB Match");
522 keys
= ((OSString
*)X
)->getCStringNoCopy();
527 if( deviceInfo
->defaultAddress
!= strtol(keys
, (char **) &keys
, 16)) {
531 if( *keys
++ == '-' ) {
532 if( deviceInfo
->defaultHandlerID
!= strtol(keys
, (char **) &keys
, 16)) {
545 // **********************************************************************************
548 // **********************************************************************************
549 IOReturn
IOADBController::setOwner ( void * device
, IOService
* client
, ADB_callback_func handler
)
551 ADBDeviceControl
* deviceInfo
= (ADBDeviceControl
*)device
;
553 deviceInfo
->handler
= handler
;
554 deviceInfo
->owner
= client
;
555 return kIOReturnSuccess
;
559 // **********************************************************************************
562 // **********************************************************************************
563 IOReturn
IOADBController::clearOwner ( void * device
)
565 ADBDeviceControl
* deviceInfo
= (ADBDeviceControl
*)device
;
566 kprintf("IOADBController::clearOwner\n");
568 deviceInfo
->owner
= NULL
;
569 deviceInfo
->handler
= NULL
;
570 return kIOReturnSuccess
;
574 // **********************************************************************************
577 // Called by the user client
578 // **********************************************************************************
579 IOReturn
IOADBController::claimDevice (unsigned long ADBaddress
, IOService
* client
, ADB_callback_func handler
)
581 if ( claimed_devices
[ADBaddress
] == true ) { // is this address already claimed by the user?
582 return kIOReturnExclusiveAccess
; // yes
584 if ( adbDevices
[ADBaddress
] == NULL
) { // no, is there a device at that address?
585 return kIOReturnNoDevice
; // no
587 if (adbDevices
[ADBaddress
]->handler
!= NULL
) { // yes, is it already owned by the kernel?
588 return kIOReturnExclusiveAccess
; // yes
590 claimed_devices
[ADBaddress
] = true; // no, user can have it
591 return kIOReturnSuccess
;
595 // **********************************************************************************
598 // Called by the user client
599 // **********************************************************************************
600 IOReturn
IOADBController::releaseDevice (unsigned long ADBaddress
)
602 if ( claimed_devices
[ADBaddress
] == false ) {
603 return kIOReturnBadArgument
;
606 claimed_devices
[ADBaddress
] = false;
608 return kIOReturnSuccess
;
612 // **********************************************************************************
615 // Called by the user client
616 // **********************************************************************************
617 IOReturn
IOADBController::readDeviceForUser (unsigned long address
, unsigned long adbRegister
,
618 UInt8
* data
, IOByteCount
* length
)
620 if ( claimed_devices
[address
] == false ) {
621 return kIOReturnBadArgument
;
624 return (readFromDevice((IOADBAddress
)address
,(IOADBRegister
)adbRegister
,data
,length
));
628 // **********************************************************************************
629 // writeDeviceForUser
631 // Called by the user client
632 // **********************************************************************************
633 IOReturn
IOADBController::writeDeviceForUser (unsigned long address
, unsigned long adbRegister
,
634 UInt8
* data
, IOByteCount
* length
)
636 if ( claimed_devices
[address
] == false ) {
637 return kIOReturnBadArgument
;
640 return (writeToDevice((IOADBAddress
)address
,(IOADBRegister
)adbRegister
,data
,length
));
644 // **********************************************************************************
647 // **********************************************************************************
648 IOADBAddress
IOADBController::address ( ADBDeviceControl
* busRef
)
650 return busRef
->address
;
654 // **********************************************************************************
657 // **********************************************************************************
658 IOADBAddress
IOADBController::defaultAddress ( ADBDeviceControl
* busRef
)
660 return busRef
->defaultAddress
;
664 // **********************************************************************************
667 // **********************************************************************************
668 UInt8
IOADBController::handlerID ( ADBDeviceControl
* busRef
)
670 return busRef
->handlerID
;
674 // **********************************************************************************
677 // **********************************************************************************
678 UInt8
IOADBController::defaultHandlerID ( ADBDeviceControl
* busRef
)
680 return busRef
->defaultHandlerID
;
684 // **********************************************************************************
687 // **********************************************************************************
688 IOReturn
IOADBController::cancelAllIO ( void )
690 return kIOReturnSuccess
;
694 // **********************************************************************************
697 // **********************************************************************************
698 IOReturn
IOADBController::flush ( ADBDeviceControl
* busRef
)
700 return(flushDevice(busRef
->address
));
704 // **********************************************************************************
707 // **********************************************************************************
708 IOReturn
IOADBController::readRegister ( ADBDeviceControl
* busRef
, IOADBRegister adbRegister
,
709 UInt8
* data
, IOByteCount
* length
)
711 return readFromDevice(busRef
->address
,adbRegister
,data
,length
);
715 // **********************************************************************************
718 // **********************************************************************************
719 IOReturn
IOADBController::writeRegister ( ADBDeviceControl
* busRef
, IOADBRegister adbRegister
,
720 UInt8
* data
, IOByteCount
* length
)
722 return writeToDevice(busRef
->address
,adbRegister
,data
,length
);
726 // **********************************************************************************
729 // **********************************************************************************
730 IOReturn
IOADBController::setHandlerID ( ADBDeviceControl
* deviceInfo
, UInt8 handlerID
)
735 IOADBAddress addr
= deviceInfo
->address
;
738 err
= readFromDevice(addr
,3,(UInt8
*)&value
,&length
);
744 value
= (value
& 0xf000) | handlerID
| (addr
<< 8);
745 length
= sizeof(value
);
746 err
= writeToDevice(addr
,3,(UInt8
*)&value
,&length
);
748 length
= sizeof(value
);
749 err
= readFromDevice(addr
,3,(UInt8
*)&value
,&length
);
751 if ( err
== kIOReturnSuccess
) {
752 deviceInfo
->handlerID
= value
& 0xff;
755 if ( deviceInfo
->handlerID
== handlerID
) {
756 err
= kIOReturnSuccess
;
759 err
= kIOReturnNoResources
;
766 // **********************************************************************************
767 // getURLComponentUnit
769 // **********************************************************************************
770 int IOADBController::getURLComponentUnit ( IOService
* device
, char * path
, int maxLen
)
772 ADBDeviceControl
* deviceInfo
= (ADBDeviceControl
*)((IOADBDevice
*)device
)->busRef();
775 sprintf( path
, "%x", deviceInfo
->address
);
784 // **********************************************************************************
787 // **********************************************************************************
788 IOReturn
IOADBController::newUserClient( task_t owningTask
, void * /* security_id */, UInt32 type
, IOUserClient
** handler
)
790 IOReturn err
= kIOReturnSuccess
;
791 IOADBControllerUserClient
* client
;
793 client
= IOADBControllerUserClient::withTask(owningTask
);
795 if( !client
|| (false == client
->attach( this )) ||
796 (false == client
->start( this )) ) {
798 client
->detach( this );
802 err
= kIOReturnNoMemory
;