Annotation of kernel/bsd/dev/ppc/adb.m, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /*
        !            26:  * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991  
        !            27:  *              All Rights Reserved 
        !            28:  *  
        !            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. 
        !            34:  *
        !            35:  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
        !            36:  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
        !            37:  * FOR A PARTICULAR PURPOSE. 
        !            38:  *  
        !            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. 
        !            44:  * 
        !            45:  */
        !            46: /*
        !            47:  * Copyright 1996 1995 by Apple Computer, Inc. 1997 1996 1995 1994 1993 1992 1991  
        !            48:  *              All Rights Reserved 
        !            49:  *  
        !            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. 
        !            55:  *  
        !            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. 
        !            59:  *  
        !            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. 
        !            65:  */
        !            66: /*
        !            67:  * MKLINUX-1.0DR2
        !            68:  */
        !            69: 
        !            70: /*
        !            71:  * ADB Driver - used internally by ADB device drivers
        !            72:  *
        !            73:  * Currently this is heavily tied to the design  of
        !            74:  * the CUDA hardware and MACH driver
        !            75:  */
        !            76: 
        !            77: 
        !            78: #include <mach_kdb.h>
        !            79: #include <mach/mach_types.h>
        !            80: #include <machdep/ppc/powermac.h>  //for HasPMU() definition
        !            81: #include <sys/tty.h>
        !            82: #include <sys/conf.h>
        !            83: #include "busses.h"
        !            84: #include "adb.h"
        !            85: #include "adb_io.h"
        !            86: #include "drvPMU/pmu.h"
        !            87: 
        !            88: void waitForCallback(void);
        !            89: void ADBcallback(id, UInt32, UInt32, UInt8 *);
        !            90: void ADBReadCallback(id, UInt32, UInt32, UInt8 *);
        !            91: void ADBReadCallback2(id, UInt32, UInt32, UInt8 *);
        !            92: void inputHandler(id, UInt32, UInt32, UInt32, UInt8*);
        !            93: 
        !            94: id             PMUdriver = NULL;
        !            95: UInt8          read_buffer[8];
        !            96: int            read_length;
        !            97: boolean_t       adb_initted = FALSE;
        !            98: int             adb_count = 0;
        !            99: 
        !           100: adb_request_t   *adb_queue_root = NULL, *adb_queue_end = NULL;
        !           101: 
        !           102: #define ADB_POOL_COUNT  16
        !           103: 
        !           104: adb_device_t    adb_devices[ADB_DEVICE_COUNT];
        !           105: adb_request_t   adb_async_requests[ADB_POOL_COUNT], *adb_async_pool;
        !           106: boolean_t adb_hardware = FALSE;
        !           107: 
        !           108: 
        !           109: void adbattach( struct bus_device *device);
        !           110: int adbprobe(caddr_t addr, void *ui);
        !           111: 
        !           112: struct bus_device   *adb_info[NADB];
        !           113: 
        !           114: void
        !           115: InitializeADB(void)
        !           116: {
        !           117: 
        !           118:     if (adb_hardware == FALSE) {
        !           119:        [PMUdriver registerForADBAutopoll:inputHandler:(id)NULL];
        !           120:        adb_hardware = TRUE;
        !           121:        adbprobe(0, 0);
        !           122:    }
        !           123: }
        !           124: 
        !           125: 
        !           126: static int
        !           127: adb_is_dev_present(unsigned short addr)
        !           128: {
        !           129:     struct adb_device   *devp = &adb_devices[addr];
        !           130:     unsigned short value;
        !           131:     int retval;
        !           132: 
        !           133: //kprintf("adb_is_dev_present: addr = %08x, devp = %08x\n", addr, devp);
        !           134: 
        !           135:     retval = adb_readreg(addr, 3, &value);
        !           136: 
        !           137: //kprintf("adb_is_dev_present: retval = %08x, ADB_RET_TIMEOUT = %08x\n",
        !           138: //     retval, ADB_RET_TIMEOUT);
        !           139: 
        !           140: #if notdef_next // DEBUG
        !           141:     if (retval != ADB_RET_TIMEOUT)
        !           142:         printf("adb_is_dev_present(%2d) returned %d\n", addr, retval);
        !           143: #endif /* DEBUG */
        !           144:     if (retval != ADB_RET_TIMEOUT) {
        !           145: 
        !           146: //kprintf("adb_is_dev_present: value = %08x\n", value);
        !           147: 
        !           148:         devp->a_dev_addr = (value >> 8) & 0xf;
        !           149:         devp->a_dev_orighandler = devp->a_dev_handler = (value & 0xff);
        !           150:         devp->a_flags |= ADB_FLAGS_PRESENT;
        !           151:         return TRUE;
        !           152:     }
        !           153: 
        !           154:     return FALSE;
        !           155: }
        !           156: 
        !           157: int
        !           158: adb_set_handler(struct adb_device *devp, int handler)
        !           159: {
        !           160:     unsigned long   retval;
        !           161:     unsigned short value;
        !           162: 
        !           163:     retval = adb_readreg(devp->a_addr, 3, &value);
        !           164: 
        !           165:     if (retval != ADB_RET_OK) 
        !           166:        return( retval);
        !           167: 
        !           168:     value = (value & 0xF000) | handler;
        !           169: 
        !           170:     retval = adb_writereg(devp->a_addr, 3, value);
        !           171: 
        !           172:     if (retval != ADB_RET_OK)
        !           173:        return( retval);
        !           174: 
        !           175:     retval = adb_readreg(devp->a_addr, 3, &value);
        !           176: 
        !           177:     if (retval != ADB_RET_OK)
        !           178:        return( retval);
        !           179: 
        !           180:     if( (value & 0xFF) != handler)
        !           181:        retval = ADB_RET_UNEXPECTED_RESULT;
        !           182: 
        !           183:     /* Update to new handler/id */
        !           184:     devp->a_dev_handler = (value & 0xff);
        !           185: 
        !           186: 
        !           187:     return( retval);
        !           188: }
        !           189: 
        !           190: static void
        !           191: adb_move_dev(unsigned short from, unsigned short to)
        !           192: {
        !           193:     int addr;
        !           194:     adb_writereg(from, 3, ((to << 8) | 0xfe));
        !           195: 
        !           196:     addr = adb_devices[to].a_addr;
        !           197:     adb_devices[to] = adb_devices[from];
        !           198:     adb_devices[to].a_addr = addr;
        !           199:     adb_devices[from].a_flags = 0;
        !           200:     
        !           201:     return;
        !           202: }
        !           203: 
        !           204: static boolean_t 
        !           205: adb_find_unresolved_dev(unsigned short *devnum)
        !           206: {
        !           207:     int i;
        !           208:     struct adb_device   *devp;
        !           209: 
        !           210:     devp = &adb_devices[1];
        !           211: 
        !           212:     for (i = 1; i < ADB_DEVICE_COUNT; i++, devp++) {
        !           213:         if (devp->a_flags & ADB_FLAGS_UNRESOLVED) {
        !           214:             *devnum = i;
        !           215:             return  TRUE;
        !           216:         }
        !           217:     }
        !           218: 
        !           219:     return FALSE;
        !           220: }
        !           221: 
        !           222: static int
        !           223: adb_find_freedev(void)
        !           224: {
        !           225:     struct adb_device   *devp;
        !           226:     int i;
        !           227: 
        !           228:     for (i = ADB_DEVICE_COUNT-1; i >= 1; i--) {
        !           229:         devp = &adb_devices[i];
        !           230: 
        !           231:         if ((devp->a_flags & ADB_FLAGS_PRESENT) == 0) 
        !           232:             return i;
        !           233:     }
        !           234: 
        !           235:     panic("ADB: Cannot find a free ADB slot for reassignment!");
        !           236:     return -1;
        !           237: }
        !           238: 
        !           239: int
        !           240: adbprobe(caddr_t addr, void *ui)
        !           241: {
        !           242:     unsigned short devnum, freenum, devlist;
        !           243:     struct adb_device   *devp;
        !           244:     int i;
        !           245:     spl_t   s;
        !           246: 
        !           247: //kprintf("adbprobe: Begining\n");
        !           248: 
        !           249:     if (adb_initted)
        !           250:         return 1;
        !           251: 
        !           252: //kprintf("adbprobe: Not initted\n");
        !           253: 
        !           254:     for (i = 0; i < ADB_POOL_COUNT; i++) {
        !           255:         adb_async_requests[i].a_next = adb_async_pool;
        !           256:         adb_async_pool = &adb_async_requests[i];
        !           257:     }
        !           258: 
        !           259:     s = spltty();
        !           260: 
        !           261:     /* Kill the auto poll until a new dev id's have been setup */
        !           262: 
        !           263:        if ( [PMUdriver ADBPollDisable:(UInt32)current_thread():0:ADBcallback] == kPMUNoError ) {
        !           264:                waitForCallback();
        !           265:                }
        !           266:     /*
        !           267:      * Send a ADB bus reset - reply is sent after bus has reset,
        !           268:      * so there is no need to wait for the reset to complete.
        !           269:      */
        !           270: 
        !           271:        if ( [PMUdriver ADBReset:(UInt32)current_thread():0:ADBcallback] == kPMUNoError ) {
        !           272:                waitForCallback();
        !           273:                }
        !           274:     /*
        !           275:      * Okay, now attempt reassign the
        !           276:      * bus 
        !           277:      */
        !           278: 
        !           279: //kprintf("adbprobe: probing\n");
        !           280: 
        !           281:     /* Skip 0 -- its special! */
        !           282:     for (i = 1; i < ADB_DEVICE_COUNT; i++) {
        !           283:         adb_devices[i].a_addr = i;
        !           284: 
        !           285: //kprintf("adbprobe: probing %x\n", i);
        !           286: 
        !           287:         if (adb_is_dev_present(i)) {
        !           288: 
        !           289: //kprintf("adbprobe: adb_is_dev_present\n");
        !           290: 
        !           291:             adb_devices[i].a_dev_type = i;
        !           292:             adb_devices[i].a_flags |= ADB_FLAGS_UNRESOLVED;
        !           293:         }
        !           294:     }
        !           295: 
        !           296:     /* Now attempt to reassign the addresses */
        !           297:     while (adb_find_unresolved_dev(&devnum)) {
        !           298:         freenum = adb_find_freedev();
        !           299:         adb_move_dev(devnum, freenum);
        !           300: 
        !           301:         if (!adb_is_dev_present(freenum)) {
        !           302:             /* It didn't move.. damn! */
        !           303:             adb_devices[devnum].a_flags &= ~ADB_FLAGS_UNRESOLVED;
        !           304:             printf("WARNING : ADB DEVICE %d having problems "
        !           305:                    "probing!\n", devnum);
        !           306:             continue;
        !           307:         }
        !           308: 
        !           309:         if (!adb_is_dev_present(devnum)) {
        !           310:             /* no more at this address, good !*/
        !           311:             /* Move it back.. */
        !           312: 
        !           313:             adb_move_dev(freenum, devnum);
        !           314: 
        !           315:             /* Check the device to talk again.. */
        !           316:             (void) adb_is_dev_present(devnum);
        !           317:             adb_devices[devnum].a_flags &= ~ADB_FLAGS_UNRESOLVED;
        !           318:         } else {
        !           319:             /* Found another device at the address, leave
        !           320:              * the first device moved to one side and set up
        !           321:              * newly found device for probing
        !           322:              */
        !           323:             /* device_present already called on freenum above */
        !           324:             adb_devices[freenum].a_flags &= ~ADB_FLAGS_UNRESOLVED;
        !           325: 
        !           326:             /* device_present already called on devnum above */
        !           327:             adb_devices[devnum].a_dev_type = devnum;
        !           328:             adb_devices[devnum].a_flags |= ADB_FLAGS_UNRESOLVED;
        !           329: #if 0
        !           330:             printf("Found hidden device at %d, previous device "
        !           331:                    "moved to %d\n", devnum, freenum);
        !           332: #endif /* DEBUG */
        !           333:         }
        !           334:     }
        !           335: 
        !           336:     /*
        !           337:      * Now build up a dev list bitmap and total device count
        !           338:      */
        !           339: 
        !           340:     devp = adb_devices;
        !           341:     devlist = 0;
        !           342: 
        !           343:     for (i = 0; i < ADB_DEVICE_COUNT; i++, devp++) {
        !           344:         if ((devp->a_flags & ADB_FLAGS_PRESENT) == 0)
        !           345:             continue;
        !           346: 
        !           347:         devlist |= (1<<i);
        !           348:         adb_count++;
        !           349:     }
        !           350: 
        !           351: 
        !           352:     // ADBSetPollList calls the callback before it returns when
        !           353:     // autopolling is off.
        !           354:        if (HasPMU())
        !           355:        {
        !           356:        [PMUdriver ADBSetPollList:devlist:0:0:NULL];
        !           357:                //PG&E doesn't perform this hardware operation immediately
        !           358:                //   so it's OK not to wait for callback
        !           359:        }
        !           360:        else
        !           361:        if ( [PMUdriver ADBSetPollList:devlist:(UInt32)current_thread():0:ADBcallback] == kPMUNoError)
        !           362:        {
        !           363:         waitForCallback(); 
        !           364:        }
        !           365: 
        !           366: 
        !           367:     if ( [PMUdriver ADBSetPollRate:11:(UInt32)current_thread():0:ADBcallback] == kPMUNoError ) {
        !           368:       waitForCallback();
        !           369:     }
        !           370: 
        !           371:     if ( [PMUdriver ADBPollEnable:(UInt32)current_thread():0:ADBcallback] == kPMUNoError ) {
        !           372:       waitForCallback();
        !           373:     }
        !           374: 
        !           375:     if ( [PMUdriver ADBSetFileServerMode:(UInt32)current_thread():0:ADBcallback] == kPMUNoError ) {
        !           376:       waitForCallback();
        !           377:     }
        !           378: 
        !           379: 
        !           380:     adb_initted = TRUE;
        !           381:     splx(s);
        !           382: 
        !           383:     return 1;
        !           384: }
        !           385: 
        !           386: void
        !           387: adbattach( struct bus_device *device)
        !           388: {
        !           389:     int i;
        !           390:     adb_device_t    *devp = &adb_devices[0];
        !           391: 
        !           392:     printf("\nadb0: %d devices on bus.\n", adb_count);
        !           393:     for (i = 0; i < ADB_DEVICE_COUNT; i++, devp++) {
        !           394:         if (devp->a_flags & ADB_FLAGS_PRESENT) {
        !           395:             printf("    %d: ", i);
        !           396:             switch (devp->a_dev_type) {
        !           397:             case    ADB_DEV_PROTECT:
        !           398:                 printf("security device");
        !           399:                 break;
        !           400:             case    ADB_DEV_KEYBOARD:
        !           401:                 printf("keyboard");
        !           402:                 break;
        !           403:             case    ADB_DEV_MOUSE:
        !           404:                 printf("mouse");
        !           405:                 break;
        !           406:             case    ADB_DEV_TABLET:
        !           407:                 printf("tablet");
        !           408:                 break;
        !           409:             case    ADB_DEV_MODEM:
        !           410:                 printf("modem");
        !           411:                 break;
        !           412:             case    ADB_DEV_APPL:
        !           413:                 printf("application device");
        !           414:                 break;
        !           415:             default:
        !           416:                 printf("unknown device id=%d", i);
        !           417:             }
        !           418:             printf("\n");
        !           419:         }
        !           420:     }
        !           421: }
        !           422: 
        !           423: /*
        !           424:  * adbopen
        !           425:  *
        !           426:  */
        !           427: 
        !           428: io_return_t
        !           429: adbopen(dev_t dev, dev_mode_t flag, io_req_t ior)
        !           430: {
        !           431:     return  D_SUCCESS;
        !           432: }
        !           433: 
        !           434: void
        !           435: adbclose(dev_t dev)
        !           436: {
        !           437:     return;
        !           438: }
        !           439: 
        !           440: io_return_t
        !           441: adbread(dev_t dev, io_req_t ior)
        !           442: {
        !           443:     return  D_INVALID_OPERATION;
        !           444: }
        !           445: 
        !           446: io_return_t
        !           447: adbwrite(dev_t dev, io_req_t ior)
        !           448: {
        !           449:     return  D_INVALID_OPERATION;
        !           450: }
        !           451: 
        !           452: boolean_t
        !           453: adbportdeath(dev_t dev, ipc_port_t port)
        !           454: {
        !           455:     return  FALSE;
        !           456: }
        !           457: 
        !           458: #if 0
        !           459: io_return_t
        !           460: adbgetstatus(dev_t dev, dev_flavor_t flavor, dev_status_t data,
        !           461:     mach_msg_type_number_t *status_count)
        !           462: {
        !           463: /* DS1
        !           464:     struct  adb_info *info = (struct adb_info *) data;
        !           465:     struct adb_device *devp;
        !           466:     int i;
        !           467: 
        !           468:     switch (flavor) {
        !           469:     case    ADB_GET_INFO:
        !           470:         devp = adb_devices; 
        !           471:             for (i = 0; i < ADB_DEVICE_COUNT; i++, devp++) {
        !           472:             if ((devp->a_flags & ADB_FLAGS_PRESENT) == 0)
        !           473:                 continue;
        !           474: 
        !           475:             info->a_addr = devp->a_addr;
        !           476:             info->a_type = devp->a_dev_type;
        !           477:             info->a_handler = devp->a_dev_handler;
        !           478:             info->a_orighandler = devp->a_dev_orighandler;
        !           479:             info++;
        !           480:         }
        !           481:         *status_count = (sizeof(struct adb_info)*adb_count)/sizeof(int);
        !           482:         break;
        !           483: 
        !           484:     case    ADB_GET_COUNT:
        !           485:         *((unsigned int *) data) = adb_count;
        !           486:         *status_count = 1;
        !           487:         break;
        !           488: 
        !           489:     case    ADB_READ_DATA: {
        !           490:         struct adb_regdata *reg = (struct adb_regdata *) data;
        !           491: 
        !           492:         reg->a_count = adb_reg_data.a_reply.a_bcount;
        !           493:         bcopy((char *) adb_reg_data.a_reply.a_buffer,
        !           494:             (char *) reg->a_buffer, adb_reg_data.a_reply.a_bcount);
        !           495:         *status_count = (sizeof(struct adb_regdata))/sizeof(int);
        !           496:     }
        !           497:         break;
        !           498:             
        !           499:     default:
        !           500:         return  D_INVALID_OPERATION;
        !           501:     }
        !           502: DS1 */
        !           503:     return  D_SUCCESS;
        !           504: }
        !           505: 
        !           506: io_return_t
        !           507: adbsetstatus(dev_t dev, dev_flavor_t flavor, dev_status_t data,
        !           508:     mach_msg_type_number_t status_count)
        !           509: {
        !           510: /* DS1
        !           511:     struct adb_info *info = (struct adb_info *) data;
        !           512:     struct adb_device *devp;
        !           513: 
        !           514:     switch (flavor) {
        !           515:     case    ADB_SET_HANDLER:
        !           516:         if (info->a_addr < 1 || info->a_addr >= ADB_DEVICE_COUNT)
        !           517:             return  D_NO_SUCH_DEVICE;
        !           518: 
        !           519:         devp = &adb_devices[info->a_addr];
        !           520:         adb_set_handler(devp, info->a_handler);
        !           521:         if (devp->a_dev_handler != info->a_handler)
        !           522:             return  D_READ_ONLY;
        !           523:         break;
        !           524: 
        !           525:     case    ADB_READ_REG: {
        !           526:         struct adb_regdata *reg = (struct adb_regdata *) data;
        !           527: 
        !           528:         adb_init_request(&adb_reg_data);
        !           529:         ADB_BUILD_CMD2(&adb_reg_data, ADB_PACKET_ADB,
        !           530:             (ADB_ADBCMD_READ_ADB|(reg->a_addr<<4)|reg->a_reg));
        !           531:         
        !           532:         adb_send(&adb_reg_data, TRUE);
        !           533: 
        !           534:         if (adb_reg_data.a_result != ADB_RET_OK) 
        !           535:             return D_IO_ERROR;
        !           536: 
        !           537:     }
        !           538:         break;
        !           539: 
        !           540:     case    ADB_WRITE_REG: {
        !           541:         struct adb_regdata *reg = (struct adb_regdata *) data;
        !           542: 
        !           543:         adb_init_request(&adb_reg_data);
        !           544:         ADB_BUILD_CMD2_BUFFER(&adb_reg_data, ADB_PACKET_ADB,
        !           545:             (ADB_ADBCMD_WRITE_ADB|(reg->a_addr<<4)|reg->a_reg),
        !           546:             reg->a_count, &reg->a_buffer);
        !           547: 
        !           548:         adb_send(&adb_reg_data, TRUE);
        !           549: 
        !           550:         if (adb_reg_data.a_result != ADB_RET_OK) 
        !           551:             return D_IO_ERROR;
        !           552:     }
        !           553:         break;
        !           554: 
        !           555:     default:
        !           556:         return  D_INVALID_OPERATION;
        !           557:     }
        !           558: DS1 */
        !           559:     return  D_SUCCESS;
        !           560: }
        !           561: #endif
        !           562: 
        !           563: /*
        !           564:  * Register a routine which is to send events from all
        !           565:  * devices matching a given type.
        !           566:  */
        !           567: 
        !           568: void
        !           569: adb_register_handler(int type,
        !           570:         void (*handler)(int number, unsigned char *packet, int count, void * ssp))
        !           571: {
        !           572:     int dev;
        !           573:     adb_device_t    *devp;
        !           574: 
        !           575: //kprintf("adb_register_handler: type = %08x, handler = %08x\n",
        !           576: //     type, handler);
        !           577: 
        !           578:     for (dev = 0; dev < ADB_DEVICE_COUNT; dev++) {
        !           579:         devp = &adb_devices[dev];
        !           580: 
        !           581: //kprintf("adb_register_handler: dev = %08x, devp = %08x, devp->a_dev_type = %08x\n", dev, devp, devp->a_dev_type);
        !           582: 
        !           583:         if (devp->a_dev_type != type)
        !           584:             continue;
        !           585: 
        !           586:         devp->a_flags |= ADB_FLAGS_REGISTERED;
        !           587:         devp->a_handler = handler;
        !           588:     }
        !           589: }
        !           590: 
        !           591: /* 
        !           592:  * Register a routine to handle a dev at a specific address
        !           593:  */
        !           594: 
        !           595: void
        !           596: adb_register_dev(int devnum, void (*handler)(int number, unsigned char *packet, int count, void * ssp))
        !           597: {
        !           598:     adb_device_t    *devp;
        !           599: 
        !           600:     if (devnum < 0 || devnum > ADB_DEVICE_COUNT)
        !           601:         panic("adb_register: addr is out of range.");
        !           602: 
        !           603:     devp = &adb_devices[devnum];
        !           604: 
        !           605:     devp->a_flags |= ADB_FLAGS_REGISTERED;
        !           606:     devp->a_handler = handler;
        !           607: }
        !           608: 
        !           609: 
        !           610: static void    (*oldHandlers[ ADB_DEVICE_COUNT ])(int number, unsigned char *buffer, int bytes, void * ssp);
        !           611: 
        !           612: void
        !           613: borrow_adb( void (*handler)(int number, unsigned char *packet, int count, void * ssp))
        !           614: {
        !           615:     int dev;
        !           616:     adb_device_t    *devp;
        !           617: 
        !           618:     for (dev = 1; dev < ADB_DEVICE_COUNT; dev++) {
        !           619:         devp = &adb_devices[dev];
        !           620: 
        !           621:        if( devp->a_flags & ADB_FLAGS_REGISTERED)
        !           622:            oldHandlers[ dev] = devp->a_handler;
        !           623:        else
        !           624:            oldHandlers[ dev] = 0;
        !           625: 
        !           626:         devp->a_flags |= ADB_FLAGS_REGISTERED;
        !           627:         devp->a_handler = handler;
        !           628:     }
        !           629: }
        !           630: 
        !           631: void
        !           632: return_adb( void )
        !           633: {
        !           634: 
        !           635:     int dev;
        !           636:     adb_device_t    *devp;
        !           637: 
        !           638:     for (dev = 1; dev < ADB_DEVICE_COUNT; dev++) {
        !           639: 
        !           640:         devp = &adb_devices[dev];
        !           641: 
        !           642:        if( oldHandlers[ dev] ) {
        !           643:            devp->a_flags |= ADB_FLAGS_REGISTERED;
        !           644:            devp->a_handler = oldHandlers[ dev];
        !           645:        } else
        !           646:            devp->a_flags &= ~ADB_FLAGS_REGISTERED;
        !           647:     }
        !           648: }
        !           649: 
        !           650: 
        !           651: #if 0
        !           652: /* DS2...
        !           653: void
        !           654: adb_done(adb_request_t *req)
        !           655: {
        !           656:     adb_packet_t    *pack = &req->a_reply;
        !           657: DS2 */
        !           658:     /* Note, adb_busy is not reset because the CUDA chip
        !           659:      * needs time to settle back into an idle state.
        !           660:      * adb_busy will be reset in adb_next_request() when
        !           661:      * the CUDA driver is ready for the next one.
        !           662:      */
        !           663: /* DS2
        !           664:     if (req->a_flags & ADB_IS_ASYNC) {
        !           665:         req->a_next = adb_async_pool;
        !           666:         adb_async_pool = req;
        !           667:         return;
        !           668:     }
        !           669: 
        !           670:     req->a_flags |= ADB_DONE;
        !           671: 
        !           672:     if (!adb_polling) {
        !           673:         if (req->a_done)
        !           674:             req->a_done(req);
        !           675:         else    thread_wakeup((event_t) req);
        !           676:     }
        !           677: }
        !           678: 
        !           679: void
        !           680: adb_unsolicited_done(adb_packet_t *pack, void * ssp)
        !           681: {
        !           682:     adb_device_t    *devp;
        !           683:     int devnum;
        !           684: 
        !           685: DS2 */
        !           686:     /* adb_next_request() will reset this when CUDA
        !           687:      * asks for the next request.. until then the bus
        !           688:      * has to become idle
        !           689:      */
        !           690: /* DS2
        !           691:     adb_busy = TRUE;
        !           692: 
        !           693:     devnum = pack->a_header[2] >> 4;
        !           694:     devp = &adb_devices[devnum];
        !           695: 
        !           696:     if (devp->a_flags & ADB_FLAGS_REGISTERED)
        !           697:         devp->a_handler(devnum, pack->a_buffer, pack->a_bcount, ssp);
        !           698: }
        !           699: ...DS2 */
        !           700: 
        !           701: #endif
        !           702: 
        !           703: int
        !           704: adb_readreg(int number, int reg, unsigned short *value)
        !           705: {
        !           706:   if ([PMUdriver ADBRead:number :reg :(UInt32)current_thread() :0 :ADBReadCallback] != kPMUNoError) {
        !           707:     return ADB_RET_UNEXPECTED_RESULT;
        !           708:   }
        !           709: 
        !           710:   waitForCallback();
        !           711: 
        !           712:   if ( read_length ) {
        !           713:     *value = (read_buffer[0] << 8) | read_buffer[1];
        !           714:     return ADB_RET_OK;
        !           715:   }
        !           716:   else {
        !           717:     return ADB_RET_TIMEOUT;
        !           718:   }
        !           719: }
        !           720: 
        !           721: int
        !           722: adb_readreg2(int number, int reg, unsigned char *buffer, int *length)
        !           723: {
        !           724:   if ([PMUdriver ADBRead:number :reg :(UInt32)current_thread() :0 :ADBReadCallback2] != kPMUNoError) {
        !           725:     return ADB_RET_UNEXPECTED_RESULT;
        !           726:   }
        !           727:   waitForCallback();
        !           728: 
        !           729:   *length = read_length;
        !           730:   if ( read_length ) {
        !           731:     int i;
        !           732:     for ( i = 0; i < read_length; i++ ) {
        !           733:       buffer[i] = read_buffer[i];
        !           734:     }
        !           735:     if ( reg == 3 ) {                          // snoop on reads from reg 3
        !           736:       adb_devices[number].a_dev_handler = read_buffer[1];
        !           737:     }
        !           738:     
        !           739:     return ADB_RET_OK;
        !           740:   }
        !           741:   else {
        !           742:     return ADB_RET_TIMEOUT;
        !           743:   }
        !           744:   
        !           745: }
        !           746: 
        !           747: 
        !           748: int
        !           749: adb_flush(int number)
        !           750: {
        !           751:   if ([PMUdriver ADBFlush: number :(UInt32)current_thread() :0 :ADBReadCallback] != kPMUNoError) {
        !           752:     return ADB_RET_UNEXPECTED_RESULT;
        !           753:   }
        !           754:   
        !           755:   waitForCallback();
        !           756:   
        !           757:   return ADB_RET_OK;
        !           758: }
        !           759: 
        !           760: int
        !           761: adb_writereg(int number, int reg, unsigned short value)
        !           762: {
        !           763:   UInt8 buffer[2];
        !           764:   
        !           765:   buffer[0] = value >> 8;
        !           766:   buffer[1] = value & 0xff;
        !           767:   
        !           768:   if ([PMUdriver ADBWrite:number :reg :2 :buffer :(UInt32)current_thread() :0 :ADBcallback] != kPMUNoError) {
        !           769:     return ADB_RET_UNEXPECTED_RESULT;
        !           770:   }
        !           771: 
        !           772:   waitForCallback();
        !           773:   return ADB_RET_OK;
        !           774: }
        !           775: 
        !           776: int
        !           777: adb_writereg2(int number, int reg, unsigned char *buffer, int length)
        !           778: {
        !           779:   if ([PMUdriver ADBWrite:number :reg :length :buffer :(UInt32)current_thread() :0 :ADBcallback] != kPMUNoError) {
        !           780:     return ADB_RET_UNEXPECTED_RESULT;
        !           781:   }
        !           782: 
        !           783:   waitForCallback();
        !           784:   return ADB_RET_OK;
        !           785: }
        !           786: 
        !           787: void
        !           788: adb_writereg_async(int number, int reg, unsigned short value)
        !           789: {
        !           790:   UInt8 buffer[2];
        !           791:   
        !           792:   buffer[0] = value >> 8;
        !           793:   buffer[1] = value & 0xff;
        !           794:   
        !           795:   if ([PMUdriver ADBWrite:number :reg :2 :buffer :0 :0:NULL] != kPMUNoError) {
        !           796:     return;
        !           797:   }
        !           798: 
        !           799:   return;
        !           800: }
        !           801: 
        !           802: #if 0
        !           803: /* DS1
        !           804: void
        !           805: adb_send(adb_request_t *adb, boolean_t wait)
        !           806: {
        !           807:     spl_t   s;
        !           808: 
        !           809:     if (!adb_polling)
        !           810:         s  = spltty();
        !           811: 
        !           812:     adb->a_reply.a_bsize = sizeof(adb->a_reply.a_buffer);
        !           813: 
        !           814:     if (wait)
        !           815:         adb->a_done = NULL;
        !           816: 
        !           817:     adb->a_flags &= ~ADB_DONE;
        !           818:     adb->a_next = NULL;
        !           819: 
        !           820:     if (adb_busy) {
        !           821:         if (adb_queue_root == NULL)
        !           822:             adb_queue_root = adb_queue_end = adb;
        !           823:         else {
        !           824:             adb_queue_end->a_next = adb;
        !           825:             adb_queue_end = adb;
        !           826:         }
        !           827:         if (adb_polling) {
        !           828:             adb_hardware->ao_poll();
        !           829:             if ((adb->a_flags & ADB_DONE) == 0) 
        !           830:                 panic("adb_send: request did not complete?!?");
        !           831:         }
        !           832:     } else {
        !           833:         adb_busy = TRUE;
        !           834:         adb_hardware->ao_send(adb);
        !           835:     }
        !           836: 
        !           837:     if (wait && !adb_polling) {
        !           838:         simple_lock(&adb->a_lock);
        !           839:        // simon: was thread_sleep_simple_lock
        !           840:         thread_sleep((event_t) adb, simple_lock_addr(adb->a_lock), TRUE);
        !           841:     }
        !           842: 
        !           843:     if (!adb_polling)
        !           844:         splx(s);
        !           845: }
        !           846: adb_request_t *
        !           847: adb_next_request()
        !           848: {
        !           849:     adb_request_t   *adb;
        !           850: 
        !           851:     adb = adb_queue_root;
        !           852: 
        !           853:     if (adb) {
        !           854:         adb_queue_root = adb_queue_root->a_next;
        !           855:         if (adb_queue_root == NULL)
        !           856:             adb_queue_end = NULL;
        !           857:         adb_busy = TRUE;
        !           858:     } else  adb_busy = FALSE;
        !           859: 
        !           860: 
        !           861:     return adb;
        !           862: }
        !           863: void
        !           864: adb_poll(void)
        !           865: {
        !           866:     boolean_t   save_poll = adb_polling;
        !           867: 
        !           868:     adb_polling = TRUE;
        !           869: 
        !           870:     adb_hardware->ao_poll();
        !           871: 
        !           872:     adb_polling = save_poll;
        !           873: }
        !           874: DS1 */
        !           875: 
        !           876: #endif
        !           877: 
        !           878: // The PMU driver is finished sending the last command.
        !           879: // Wake up the thread that is waiting.
        !           880: void ADBcallback(id unused, UInt32 refnum, UInt32 length, UInt8* buffer)
        !           881: {
        !           882:   clear_wait(refnum,0,FALSE);
        !           883: }
        !           884: 
        !           885: 
        !           886: // The PMU driver has received data from the PMU that is the result of our
        !           887: // previous read.  Copy the data and wake up the thread.
        !           888: void ADBReadCallback(id unused, UInt32 refnum, UInt32 length, UInt8* buffer)
        !           889: {
        !           890:   if (buffer != NULL) {
        !           891:     read_buffer[0] = *buffer;
        !           892:     read_buffer[1] = *(buffer+1);
        !           893:   }
        !           894:   
        !           895:   read_length = length;
        !           896:   
        !           897:   clear_wait(refnum,0,FALSE);
        !           898: }
        !           899: 
        !           900: 
        !           901: // The PMU driver has received data from the PMU that is the result of our
        !           902: // previous read.  Copy the data and wake up the thread.
        !           903: void ADBReadCallback2(id unused, UInt32 refnum, UInt32 length, UInt8* buffer)
        !           904: {
        !           905:   int i;
        !           906:   
        !           907:   for ( i = 0; i < length; i++ ) {
        !           908:     read_buffer[i] = buffer[i];
        !           909:   }
        !           910:   read_length = length;
        !           911:   
        !           912:   clear_wait(refnum,0,FALSE);
        !           913: }
        !           914: 
        !           915: 
        !           916: // We have sent a command to the PMU driver with current_thread as the refnum.
        !           917: // Sleep until it has sent the command to the PMU.
        !           918: void waitForCallback(void)
        !           919: {
        !           920:   assert_wait(current_thread(), FALSE);
        !           921:   thread_block();
        !           922: }
        !           923: 
        !           924: // Called by the keyboard driver.  Interrupts are off.  Call PMU/Cuda
        !           925: // to let it service any interrupts.
        !           926: void CheckADBPoll(void)
        !           927: {
        !           928:   [PMUdriver poll_device];
        !           929: }
        !           930: 
        !           931: 
        !           932: // Autopoll data has arrived from the PMU.
        !           933: void inputHandler(id unused, UInt32 refnum, UInt32 devnum, UInt32 length, UInt8* buffer)
        !           934: {
        !           935:   adb_device_t *devp;
        !           936: 
        !           937: //kprintf("inputHandler: refnum: %08x, devnum = %08x, length = %08x, buffer = %08x\n", refnum, devnum, length, buffer);
        !           938: //kprintf("buffer[0] = %02x, buffer[1] = %02x\n", buffer[0], buffer[1]);
        !           939: 
        !           940:   devp = &adb_devices[devnum];
        !           941: 
        !           942: //kprintf("devp = %08x, devp->a_handler = %08x\n", devp, devp->a_handler);
        !           943:   
        !           944:   if (devp->a_flags & ADB_FLAGS_REGISTERED) {
        !           945:     devp->a_handler(devnum, buffer, length, 0);
        !           946:   } 
        !           947: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.