Annotation of kernel/bsd/dev/ppc/drvCuda/cuda.m, revision 1.1.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: /*********
                     27: 
                     28: cuda.m
                     29: 
                     30: This file is a combination of the old cuda.c and the new pmu.m for PGE.
                     31: Cuda is based on a Motorola MC68HC05E1.
                     32: 
                     33: NOTES:
                     34: 
                     35:        "WARNING" look for this string during integration.
                     36:        cuda interrupts are cleared by reading the shift register.
                     37:        cuda has a TIP (transaction in progress) signal which the PGE seems to lack.
                     38:        PGE seems to require a "length" byte in command packets while cuda does not.
                     39:        Signals:
                     40:                TIP is asserted when 0.  System asserts this when transaction is in progress.
                     41:                BYTEACK is asserted when 0.  When data is passed from the system to Cuda,
                     42:                        a toggle indicates to Cuda that the VIA data register is full.  When
                     43:                        data is passed from Cuda to the system, a toggle indicates that the
                     44:                        system has read the data from the VIA and the VIA data register
                     45:                        is now empty.  When no transaction in progress (note TIP), this
                     46:                        line is deasserted.
                     47:                TREQ is asserted when 0.  When asserted by Cuda, this indicates to the system
                     48:                        that Cuda is making a Transaction REQUEST.  During a transaction which
                     49:                        is initiated by Cuda (as opposed to one initiated by system), this line
                     50:                        is negated prior to generating a VIA interrupt for the last byte
                     51:                        of data transacted.  When no transaction is in progress (note TIP),
                     52:                        this line is negated.
                     53: 
                     54: 
                     55: *********/
                     56: 
                     57: 
                     58: #include <sys/param.h>  //for sysctl
                     59: #include <sys/proc.h>   //for sysctl also (but not documented)
                     60: 
                     61: #import <kern/clock.h>
                     62: #import <kernserv/prototypes.h>
                     63: #import <kernserv/clock_timer.h>
                     64: #import <kernserv/ns_timer.h>
                     65: #import <sys/time.h>
                     66: #import <sys/callout.h>
                     67: #import <machdep/ppc/proc_reg.h>
                     68: #import <driverkit/generalFuncs.h>
                     69: #import <driverkit/kernelDriver.h>
                     70: #import <driverkit/interruptMsg.h>
                     71: 
                     72: #import <bsd/dev/ppc/drvPMU/pmu.h>
                     73: #import <bsd/dev/ppc/drvPMU/pmupriv.h>
                     74: #import <bsd/dev/ppc/drvPMU/pmumisc.h>
                     75: #include <sys/sysctl.h>  //for debug2, debug3, debug4 in sysctl
                     76: #import "via6522.h"
                     77: #import "cuda_hdw.h"
                     78: #import "cuda.h"        //must come after pmu definitions
                     79: 
                     80: //typedefs from cuda.c:
                     81: //
                     82: //  CudaInterruptState - internal 
                     83: //
                     84: //#define kNS_TIMEOUT_AUTOPOLL  9000000000ULL
                     85: #define kNS_TIMEOUT_AUTOPOLL  4000000000ULL
                     86: 
                     87: enum CudaInterruptState
                     88: {
                     89:     CUDA_STATE_INTERRUPT_LIMBO  = -1,       //
                     90:     CUDA_STATE_IDLE         = 0,        //
                     91:     CUDA_STATE_ATTN_EXPECTED    = 1,        //
                     92:     CUDA_STATE_TRANSMIT_EXPECTED    = 2,        //
                     93:     CUDA_STATE_RECEIVE_EXPECTED = 3         //
                     94: };
                     95: 
                     96: typedef enum CudaInterruptState CudaInterruptState;
                     97: 
                     98: 
                     99: //
                    100: //  CudaTransactionFlag - internal to cuda2.m, used to be in cuda.c
                    101: //
                    102: 
                    103: enum CudaTransactionFlag
                    104: {
                    105:     CUDA_TS_NO_REQUEST  = 0x0000,
                    106:     CUDA_TS_SYNC_RESPONSE   = 0x0001,
                    107:     CUDA_TS_ASYNC_RESPONSE  = 0x0002
                    108: };
                    109: 
                    110: typedef enum CudaTransactionFlag CudaTransactionFlag;
                    111: 
                    112: 
                    113: void gotInterruptCause(id, UInt32, UInt32, UInt8 *);
                    114: void cuda_timer_autopoll(port_t mach_port);
                    115: void timer_expired(port_t mach_port);  //WARNING... not needed by Cuda?  Was not in cuda.c
                    116: 
                    117: extern id ApplePMUId;  //in adb.m (remove this when adb becomes an indirect driver)(q8q)
                    118: 
                    119: extern void kprintf(const char *, ...);
                    120: extern void bcopy(void *, void *, int);
                    121: // extern to let us fix up the boot time.
                    122: extern void set_boot_time(void);
                    123: extern msg_send_from_kernel(msg_header_t *, int, int);
                    124: 
                    125: // Variables copied from cuda.c:
                    126: static long     cuda_state_transition_delay_ticks;
                    127: volatile CudaInterruptState cuda_interrupt_state;
                    128: volatile CudaTransactionFlag    cuda_transaction_state;
                    129: static port_t   glob_port;
                    130: 
                    131: //WARNING Hack to make pmutables.h work
                    132: extern SInt8 *cmdLengthTable;   
                    133: extern SInt8 *rspLengthTable;
                    134: 
                    135: 
                    136: CudaRequest   *cuda_request = NULL, *cuda_collided = NULL;
                    137: adb_packet_t    cuda_unsolicited;
                    138: adb_packet_t    *cuda_current_response = NULL;
                    139: 
                    140: int     cuda_transfer_count = 0;
                    141: boolean_t   cuda_is_header_transfer = FALSE;
                    142: boolean_t   cuda_is_packet_type = FALSE;
                    143: boolean_t   cuda_initted = FALSE;
                    144: boolean_t      debugging = FALSE;
                    145: boolean_t      adb_reading = FALSE;
                    146: 
                    147: static UInt8   *return_buff_pointer = NULL;
                    148: static boolean_t bImmediate_buff_needed = FALSE;
                    149: 
                    150: // for Debug
                    151: pmADBinput_func                cuda_debug_client;              // Input handler in ADB client
                    152: static VIAAddress      stat_aux_control;
                    153: static boolean_t       p = FALSE;
                    154: int    que_cuda_count;
                    155: int    cuda_glob_dbug_freeze; //Can only be asserted through debugging tool
                    156: int    cuda_glob_data1;
                    157: int    cuda_glob_data2;
                    158: int cuda_freeze_counter;  //This will become "static" after debugging phase
                    159: int cuda_freeze_prevcount;  
                    160: 
                    161: //sysctl debugging tool 
                    162: struct ctldebug debug2 = { "cuda_glob_dbug_freeze", &cuda_glob_dbug_freeze };
                    163: //struct ctldebug debug3 = { "cuda_glob_data1", &cuda_glob_data1 };
                    164: //struct ctldebug debug4 = { "cuda_glob_data2", &cuda_glob_data2 };
                    165: 
                    166: 
                    167: @implementation AppleCuda
                    168: 
                    169: // **********************************************************************************
                    170: // probe
                    171: //
                    172: // 
                    173: //
                    174: // **********************************************************************************
                    175: + (Boolean) probe : deviceDescription
                    176: {
                    177:   id dev;
                    178: 
                    179:     if (cuda_initted)
                    180:         return 1;
                    181: 
                    182:     cuda_initted = TRUE;
                    183:        que_cuda_count = 0;
                    184:        cuda_glob_dbug_freeze = 0;  // 0.  Only external debugger can change it now.
                    185:        cuda_freeze_counter = 1;  //2 vars needed to recover from BYTEACK hang
                    186:        cuda_freeze_prevcount = 0;  
                    187: 
                    188:        if ( (dev = [ self alloc ]) == nil ) {
                    189:                return NO;
                    190:        }
                    191: 
                    192:        if ([dev initFromDeviceDescription:deviceDescription] == nil) {
                    193:                return NO;
                    194:        }
                    195:        
                    196:        // tell ADB about us.  This is a global variable accessible in adb.m
                    197:        ApplePMUId = dev;
                    198: 
                    199:        set_boot_time();
                    200: 
                    201:        return YES;
                    202: }
                    203: 
                    204: 
                    205: // **********************************************************************************
                    206: // initFromDeviceDescription
                    207: //
                    208: // 
                    209: //
                    210: // **********************************************************************************
                    211: - initFromDeviceDescription:(IODeviceDescription *)deviceDescription
                    212: {
                    213: volatile unsigned char valcuda;
                    214: VIAAddress     physicalAddress;
                    215: IORange *      ioRange;
                    216: unsigned char  *cuda_temp_reg;
                    217: 
                    218: struct timeval x = {0,1000000};        // one second timeout on adb reads
                    219: 
                    220: auto_power_on = 1;     //default is to enable auto power on feature (after electrical power failure)
                    221: 
                    222: if ( [super initFromDeviceDescription:deviceDescription] == nil ) {
                    223:        [self free];
                    224:        return nil;
                    225:        }
                    226: 
                    227:   [self setDeviceKind:"Cuda Subsystem"];
                    228:   [self setLocation:NULL];
                    229:   [self setName:"Cuda"];  
                    230: 
                    231: 
                    232: ioRange = [deviceDescription memoryRangeList];
                    233: 
                    234: physicalAddress = (VIAAddress)ioRange->start;
                    235: stat_aux_control = physicalAddress;
                    236: 
                    237: //above works perfectly physicalAddress = (unsigned char*)POWERMAC_IO(PCI_VIA_BASE_PHYS);
                    238: 
                    239: 
                    240: //CUDA_REPLACE
                    241: 
                    242: 
                    243: VIA1_shift             = physicalAddress + 0x1400;     // initialize VIA addresses
                    244: VIA1_auxillaryControl  = physicalAddress + 0x1600;
                    245: 
                    246: VIA1_interruptFlag     = physicalAddress + 0x1A00;
                    247: VIA1_interruptEnable   = physicalAddress + 0x1C00;
                    248: VIA2_dataB             = physicalAddress + 0x0000;             // Hooper uses VIA 1 instead
                    249: 
                    250: 
                    251: PMack                  = kCudaAssertByteAcknowledge;   //in cuda_hdw.h is 0x10
                    252: 
                    253: 
                    254: 
                    255:     cuda_state_transition_delay_ticks = nsec_to_processor_clock_ticks(200);
                    256:        //This is just 2 ticks
                    257:     // Set the direction of the cuda signals.  ByteACk and TIP are output and
                    258:     // TREQ is an input
                    259: 
                    260:        cuda_temp_reg = physicalAddress + 0x0400;       //dataDirectionB
                    261:     *cuda_temp_reg |= (kCudaByteAcknowledgeMask | kCudaTransferInProgressMask);
                    262:     *cuda_temp_reg &= ~kCudaTransferRequestMask;
                    263: 
                    264:     *VIA1_auxillaryControl     = ( *VIA1_auxillaryControl      | kCudaTransferMode) &
                    265:                                              kCudaSystemRecieve;
                    266: 
                    267:     // Clear any posible cuda interupt.
                    268:     if ( *VIA1_shift );
                    269: 
                    270:     // Initialize the internal data.
                    271: 
                    272:     cuda_interrupt_state    = CUDA_STATE_IDLE;
                    273:     cuda_transaction_state  = CUDA_TS_NO_REQUEST;
                    274:     cuda_is_header_transfer = FALSE;
                    275:     cuda_is_packet_type = FALSE;
                    276:     cuda_transfer_count = 0;    
                    277:     cuda_current_response   = NULL;     
                    278:     
                    279:     // Terminate transaction and set idle state
                    280:     // cuda_neg_tip_and_byteack();
                    281:        *VIA2_dataB |= kCudaNegateByteAcknowledge | kCudaNegateTransferInProgress;
                    282:        eieio();
                    283:     
                    284:     // we want to delay 4 mS for ADB reset to complete
                    285:     
                    286:     delay(4000);
                    287:     
                    288:     // Clear pending interrupt if any...
                    289:     //(void)cuda_read_data();
                    290:        valcuda = *VIA1_shift; eieio();
                    291:     
                    292:     // Issue a Sync Transaction, ByteAck asserted while TIP is negated.
                    293:     // cuda_assert_byte_ack();
                    294:        *VIA2_dataB &= kCudaAssertByteAcknowledge; eieio();
                    295: 
                    296: 
                    297:     // Wait for the Sync acknowledgement, cuda to assert TREQ
                    298:     // cuda_wait_for_transfer_request_assert();
                    299:        while ( (*VIA2_dataB & kCudaTransferRequestMask) != 0 ) 
                    300:        {
                    301:                eieio();
                    302:        }
                    303:        eieio();
                    304: 
                    305:     // Wait for the Sync acknowledgement interrupt.
                    306:     // cuda_wait_for_interrupt();
                    307:        while ( (*VIA1_interruptFlag & kCudaInterruptMask) == 0 ) 
                    308:        {
                    309:                eieio();
                    310:        }
                    311:        eieio();
                    312: 
                    313: 
                    314:     // Clear pending interrupt
                    315:     //(void)cuda_read_data();
                    316:        valcuda = *VIA1_shift; eieio();
                    317: 
                    318:     // Terminate the sync cycle by Negating ByteAck
                    319:     // cuda_neg_byte_ack();
                    320:        *VIA2_dataB |= kCudaNegateByteAcknowledge; eieio();
                    321: 
                    322:     // Wait for the Sync termination acknowledgement, cuda negates TREQ.
                    323:     // cuda_wait_for_transfer_request_neg();
                    324:        while ( (*VIA2_dataB & kCudaTransferRequestMask) == 0 ) 
                    325:        {
                    326:                eieio();
                    327:        }
                    328:        eieio();
                    329: 
                    330: 
                    331:     // Wait for the Sync termination acknowledgement interrupt.
                    332:     // cuda_wait_for_interrupt();
                    333:        while ( (*VIA1_interruptFlag & kCudaInterruptMask) == 0 ) 
                    334:        {
                    335:                eieio();
                    336:        }
                    337:        eieio();
                    338: 
                    339: 
                    340:     // Terminate transaction and set idle state, TIP negate and ByteAck negate.
                    341:     // cuda_neg_transfer_in_progress();
                    342:        *VIA2_dataB |= kCudaNegateTransferInProgress; eieio();
                    343: 
                    344:     // Clear pending interrupt, if there is one...
                    345:     //(void)cuda_read_data();
                    346:        valcuda = *VIA1_shift; eieio();
                    347: 
                    348: 
                    349: 
                    350: 
                    351: 
                    352: ADBclient = NULL;
                    353: RTCclient = NULL;
                    354: debugging = FALSE;
                    355: queueHead = NULL;
                    356: queueTail = NULL;
                    357: adb_reading = FALSE;
                    358: adb_read_timeout = timeval_to_ns_time(&x);
                    359: 
                    360: //CUDA_REPLACE
                    361: // A.W. This call seems to have no counterpart in Cuda
                    362: //     Pending interrupts are cleared with cuda_read_data()
                    363:        *VIA1_interruptEnable = kCudaInterruptDisable;eieio(); // turn off any pending interrupt
                    364: valcuda = *VIA1_shift; eieio();
                    365: 
                    366: [self EnableCudaInterrupt];   // enable PGE interrupts. CUDA_REPLACE already
                    367: 
                    368: [self enableAllInterrupts];
                    369: 
                    370: //WARNING... this was moved here in new pmu.m
                    371:        if ([self startIOThread] != IO_R_SUCCESS) {
                    372:         [self free];
                    373:         return nil;
                    374:        }
                    375:        port = IOConvertPort([self interruptPort],IO_KernelIOTask,IO_Kernel);
                    376:        glob_port = port;  //needed for non-ObjC functions
                    377:        [self registerDevice];
                    378: 
                    379: 
                    380: //A.W. I don't think Cuda needs to exclude any interrupts
                    381:     //I need to set up a 5-second timer which will make sure that the Auto Poll
                    382:     // feature of Cuda is never accidentally disabled by anybody
                    383:     ns_timeout((func)cuda_timer_autopoll,(void *)port, kNS_TIMEOUT_AUTOPOLL ,CALLOUT_PRI_SOFTINT0);  // start timer
                    384: 
                    385: 
                    386: return self;
                    387: }
                    388: 
                    389: 
                    390: // **********************************************************************************
                    391: // free
                    392: //
                    393: // 
                    394: //
                    395: // **********************************************************************************
                    396: - free
                    397: {
                    398: return [ super free ];
                    399: }
                    400: 
                    401: 
                    402: // **********************************************************************************
                    403: // receiveMsg
                    404: //
                    405: // 
                    406: //
                    407: // **********************************************************************************
                    408: 
                    409: 
                    410: - (void)receiveMsg
                    411: {
                    412:        CudaMachMessage * toQueue;
                    413:        IOReturn result;
                    414:        spl_t   intstate;
                    415:        //unsigned char interruptState;
                    416: 
                    417:     //interruptState =  (*VIA2_dataB & kCudaInterruptStateMask) | (*VIA1_auxillaryControl & kCudaDirectionMask) ;
                    418:     //if ( (interruptState == kCudaIdleState) && !adb_reading ) 
                    419: 
                    420:     if  (cuda_interrupt_state == CUDA_STATE_IDLE)
                    421:     {
                    422:        
                    423: if (p) kprintf("cuda2.m::receiveMsg will Xmit now... \n");
                    424:                //localMachMessage is class variable in cuda.h 
                    425:            localMachMessage.msgHeader.msg_size = sizeof(CudaMachMessage);
                    426:         localMachMessage.msgHeader.msg_local_port = [self interruptPort];
                    427:                result = msg_receive(&localMachMessage.msgHeader, (msg_option_t)RCV_TIMEOUT, 0);
                    428: 
                    429: #ifdef OMIT
                    430:                if ( localMachMessage.msgBody.pmCallback == NULL ) 
                    431:                {
                    432:                        kprintf("ADAM: receiveMsg no callback\n");
                    433:                }
                    434: #endif
                    435: 
                    436:            if ( result == RCV_SUCCESS ) {
                    437:                        //Try Simon's suggestion
                    438:                        intstate = spltty();
                    439:                    [self StartCudaTransmission:&localMachMessage.msgBody];
                    440:                        splx(intstate);
                    441:                }
                    442:        }
                    443:     else 
                    444:     {
                    445: if (p) kprintf("cuda2.m::receiveMsg will enqueue instead \n");
                    446: 
                    447: #ifdef DEBUG
                    448:                if (cuda_glob_dbug_freeze == 1) 
                    449:                {
                    450:                        kprintf("cuda: Queued\n");
                    451:                }
                    452: #endif
                    453: 
                    454:            toQueue = (CudaMachMessage*)kalloc(sizeof(CudaMachMessage));
                    455:         toQueue->msgHeader.msg_size = sizeof(CudaMachMessage);
                    456:         toQueue->msgHeader.msg_local_port = [self interruptPort];
                    457:         result = msg_receive(&toQueue->msgHeader, (msg_option_t)RCV_TIMEOUT, 0);
                    458:         if ( result == RCV_SUCCESS ) {
                    459:                    toQueue->msgBody.prev = queueTail;
                    460:                    toQueue->msgBody.next = NULL;
                    461:                    if ( queueTail != NULL ) {
                    462:                            queueTail->msgBody.next = toQueue;
                    463:                        }
                    464:                        else 
                    465:                        {
                    466:                                queueHead = toQueue;
                    467:                        }
                    468:                        queueTail = toQueue;
                    469:                }
                    470:        }
                    471: }
                    472: 
                    473: 
                    474: 
                    475: 
                    476: 
                    477: 
                    478: 
                    479: // **********************************************************************************
                    480: // timeoutOccurred
                    481: //
                    482: // Our adb-read timer has expired after sending an adb-read command to the PMU.
                    483: // This means there is no such addressed device on the ADB bus.
                    484: // We call back to the ADB driver with a zero-characters-received response and
                    485: // dequeue our command queue and carry on.
                    486: // **********************************************************************************
                    487: - (void)timeoutOccurred
                    488: {
                    489: adb_reading = FALSE;
                    490: if ( clientRequest->pmCallback != NULL ) {             // Make the client callback
                    491:        clientRequest->pmCallback(clientRequest->pmId, clientRequest->pmRefNum, 0, NULL);
                    492:        }                                               // with zero received-length
                    493: [self CheckRequestQueue];
                    494: }
                    495: 
                    496: 
                    497: // ****************************************************************************
                    498: //      CheckRequestQueue
                    499: //      Called at interrupt time when current request is complete.  We may start
                    500: //      another request here if one is in queue, or we may re-enable PMU interrupts
                    501: //      (they were turned off in PMUStartIO) and return.
                    502: // ****************************************************************************
                    503: 
                    504: - (void)CheckRequestQueue
                    505: {
                    506:        CudaMachMessage * nextRequest;
                    507: 
                    508:        if ( queueHead == NULL ) {                         // is queue empty?
                    509: if (p) kprintf("cuda2.m::CheckRequestQueue empty \n");
                    510:         [self EnableCudaInterrupt];            // yes, enable interrupt and return
                    511:     }
                    512:        else 
                    513:        {
                    514:                que_cuda_count--;
                    515: if (p) kprintf("cuda2.m::CheckRequestQueue will dequeue \n");
                    516:         nextRequest = queueHead;                        // no, dequeue first command
                    517:         queueHead = nextRequest->msgBody.next;
                    518:            if ( queueHead == NULL ) {
                    519:                    queueTail = NULL;
                    520:                }
                    521:                bcopy (&nextRequest->msgBody, &localMachMessage.msgBody, sizeof(CudaRequest));  // copy it
                    522:         kfree(nextRequest, sizeof(CudaMachMessage));                                   // free its memory
                    523:         [self StartCudaTransmission:&localMachMessage.msgBody];                                // and send it to the Cuda
                    524:     }
                    525: }
                    526: 
                    527: 
                    528: 
                    529: 
                    530: // **********************************************************************************
                    531: // registerForADBAutopoll
                    532: //
                    533: // The ADB driver is calling to tell us that it is prepared to receive
                    534: // "unsolicited" ADB autopoll data.  The parameter tells who to call
                    535: // when we get some.
                    536: //
                    537: // **********************************************************************************
                    538: - (void)registerForADBAutopoll :(pmCallback_func)InputHandler
                    539:                                :(id)caller
                    540: {
                    541: if (p) kprintf("registerForADBAutopoll: %08x   caller: %08x\n", InputHandler, caller);
                    542:   ADBclient = InputHandler;
                    543:   cuda_debug_client = ADBclient;               // Debug use only
                    544:   ADBid = caller;
                    545: }
                    546: 
                    547: 
                    548: // **********************************************************************************
                    549: // ADBWrite
                    550: //
                    551: // **********************************************************************************
                    552: - (PMUStatus)ADBWrite  :(UInt32)DevAddr
                    553:                        :(UInt32)DevReg
                    554:                        :(UInt32)ByteCount
                    555:                        :(UInt8*)Buffer
                    556:                        :(UInt32)RefNum
                    557:                        :(id)Id
                    558:                        :(pmCallback_func)Callback
                    559: {
                    560:        CudaMachMessage request;
                    561:        msg_return_t    return_code;
                    562: 
                    563: if (p) kprintf("ADBWrite\n");
                    564:        
                    565:        if (ByteCount > 7)
                    566:        {
                    567:                kprintf("bsd-dev-ppc-drvCuda-cuda.m: ADBWrite may fail\n");
                    568:        }
                    569: 
                    570:        request.msgBody.a_cmd.a_header[0] = ADB_PACKET_ADB;
                    571:        request.msgBody.a_cmd.a_header[1] = ADB_ADBCMD_WRITE_ADB | DevAddr << 4 | DevReg;
                    572:        request.msgBody.a_cmd.a_header[2] = Buffer[0];
                    573:        request.msgBody.a_cmd.a_header[3] = Buffer[1];
                    574:        request.msgBody.a_cmd.a_header[4] = Buffer[2]; //necessary?
                    575:        request.msgBody.a_cmd.a_header[5] = Buffer[3];
                    576:        request.msgBody.a_cmd.a_header[6] = Buffer[4];
                    577:        request.msgBody.a_cmd.a_header[7] = Buffer[5];
                    578:        request.msgBody.a_cmd.a_header[8] = Buffer[6];
                    579: 
                    580:        //request.msgBody.a_cmd.a_hcount = 4; 
                    581:        request.msgBody.a_cmd.a_hcount = ByteCount + 2;
                    582:        //Dave added unlimited-length adb_writereg()
                    583: 
                    584:        request.msgBody.a_cmd.a_bcount = 0;
                    585:        request.msgBody.pmCallback = Callback;
                    586: 
                    587: #ifdef OMIT
                    588:        if (Callback == NULL)
                    589:        {
                    590:                kprintf("Cuda: ADBWrite callback is NULL\n");
                    591:        }
                    592: #endif
                    593: 
                    594:        request.msgBody.pmId = Id;
                    595:        request.msgBody.pmRefNum = RefNum;
                    596: 
                    597:        request.msgHeader.msg_simple = TRUE;
                    598:        request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                    599:        request.msgHeader.msg_remote_port = port;
                    600:        request.msgHeader.msg_local_port = PORT_NULL;
                    601:        request.msgHeader.msg_size = sizeof(CudaMachMessage);
                    602:        return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                    603: 
                    604:        if ( return_code == SEND_SUCCESS ) {
                    605:                return kPMUNoError;
                    606:        }
                    607:        else {
                    608:                return kPMUIOError;
                    609:        }
                    610: }
                    611: 
                    612: 
                    613: // **********************************************************************************
                    614: // ADBRead
                    615: //
                    616: // **********************************************************************************
                    617: - (PMUStatus)ADBRead   :(UInt32)DevAddr
                    618:                        :(UInt32)DevReg
                    619:                        :(UInt32)RefNum
                    620:             :(id)Id
                    621:                        :(pmCallback_func)Callback
                    622: {
                    623: CudaMachMessage        request;
                    624: msg_return_t   return_code;
                    625: 
                    626: request.msgBody.a_cmd.a_header[0] = ADB_PACKET_ADB;
                    627: request.msgBody.a_cmd.a_header[1] = ADB_ADBCMD_READ_ADB | DevAddr << 4 | DevReg;
                    628: request.msgBody.a_cmd.a_hcount = 2;
                    629: //request.msgBody.a_cmd.a_bsize = sizeof(request.msgBody.a_cmd.a_buffer);  
                    630: request.msgBody.a_reply.a_bsize = 8; //It's 8 in adb.h
                    631: //WARNING... try out line above 3/4/98 TitanL kernel 
                    632:  
                    633: request.msgBody.a_cmd.a_bcount = 0;
                    634: request.msgBody.pmCallback = Callback;
                    635: 
                    636: #ifdef OMIT
                    637:        if (Callback == NULL)
                    638:        {
                    639:                kprintf("Cuda: ADBRead callback is NULL\n");
                    640:        }
                    641: #endif
                    642: 
                    643: request.msgBody.pmId = Id;
                    644: request.msgBody.pmRefNum = RefNum;
                    645: 
                    646: request.msgHeader.msg_simple = TRUE;
                    647: request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                    648: request.msgHeader.msg_remote_port = port;
                    649: request.msgHeader.msg_local_port = PORT_NULL;
                    650: request.msgHeader.msg_size = sizeof(CudaMachMessage);
                    651: return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                    652: 
                    653: if ( return_code == SEND_SUCCESS ) {
                    654:        return kPMUNoError;
                    655:        }
                    656: else {
                    657:        return kPMUIOError;
                    658:        }
                    659: }
                    660: 
                    661: 
                    662: // **********************************************************************************
                    663: // ADBReset
                    664: //
                    665: // **********************************************************************************
                    666: - (PMUStatus)ADBReset  :(UInt32)RefNum
                    667:                         :(id)Id
                    668:                                                :(pmCallback_func)Callback
                    669: {
                    670:        CudaMachMessage request;
                    671:        msg_return_t    return_code;
                    672: 
                    673: kprintf("CUDA: ADBReset\n");
                    674:        request.msgBody.a_cmd.a_header[0] = ADB_PACKET_ADB;
                    675:        request.msgBody.a_cmd.a_header[1] = ADB_ADBCMD_RESET_BUS;
                    676:        request.msgBody.a_cmd.a_hcount = 2;
                    677:        request.msgBody.a_cmd.a_bcount = 0;
                    678:        request.msgBody.pmCallback = Callback;
                    679:        request.msgBody.pmId = Id;
                    680:        request.msgBody.pmRefNum = RefNum;
                    681: 
                    682:        request.msgHeader.msg_simple = TRUE;
                    683:        request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                    684:        request.msgHeader.msg_remote_port = port;
                    685:        request.msgHeader.msg_local_port = PORT_NULL;
                    686:        request.msgHeader.msg_size = sizeof(CudaMachMessage);
                    687:        return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                    688: 
                    689:        if ( return_code == SEND_SUCCESS ) {
                    690:                return kPMUNoError;
                    691:        }
                    692:        else {
                    693:                return kPMUIOError;
                    694:        }
                    695: }
                    696: 
                    697: 
                    698: // **********************************************************************************
                    699: // ADBFlush
                    700: //
                    701: // **********************************************************************************
                    702: - (PMUStatus)ADBFlush  :(UInt32)DevAddr
                    703:                        :(UInt32)RefNum
                    704:                         :(id)Id
                    705:                        :(pmCallback_func)Callback
                    706: {
                    707: CudaMachMessage        request;
                    708: msg_return_t   return_code;
                    709: 
                    710: if (p) kprintf("ADBFlush\n");
                    711: request.msgBody.a_cmd.a_header[0] = ADB_PACKET_ADB;
                    712: request.msgBody.a_cmd.a_header[1] = ADB_ADBCMD_FLUSH_ADB | (DevAddr << 4);
                    713: request.msgBody.a_cmd.a_hcount = 2;
                    714: request.msgBody.a_cmd.a_bcount = 0;
                    715: request.msgBody.pmId = Id;
                    716: request.msgBody.pmRefNum = RefNum;
                    717: request.msgBody.pmCallback = Callback;
                    718:                
                    719: request.msgHeader.msg_simple = TRUE;
                    720: request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                    721: request.msgHeader.msg_remote_port = port;
                    722: request.msgHeader.msg_local_port = PORT_NULL;
                    723: request.msgHeader.msg_size = sizeof(CudaMachMessage);
                    724: return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                    725: 
                    726: if ( return_code == SEND_SUCCESS ) {
                    727:        return kPMUNoError;
                    728:        }
                    729: else {
                    730:        return kPMUIOError;
                    731:        }
                    732: }
                    733: 
                    734: 
                    735: // **********************************************************************************
                    736: // ADBSetPollList
                    737: //  
                    738: //  
                    739: // **********************************************************************************
                    740: - (PMUStatus)ADBSetPollList    :(UInt32)PollBitField
                    741:                                :(UInt32)RefNum
                    742:                    :(id)Id
                    743:                                :(pmCallback_func)Callback
                    744: {
                    745: CudaMachMessage        request;
                    746: msg_return_t   return_code;
                    747: 
                    748: if (p) kprintf("ADBSetPollList\n");
                    749: request.msgBody.a_cmd.a_header[0] = ADB_PACKET_PSEUDO;
                    750: request.msgBody.a_cmd.a_header[1] = ADB_PSEUDOCMD_SET_DEVICE_LIST;
                    751: request.msgBody.a_cmd.a_header[2] = (PollBitField >> 8) & 0xFF;
                    752: request.msgBody.a_cmd.a_header[3] = PollBitField & 0xFF;
                    753: request.msgBody.a_cmd.a_hcount = 4;
                    754: request.msgBody.a_cmd.a_bcount = 0;
                    755: request.msgBody.pmRefNum = RefNum;
                    756: request.msgBody.pmId = Id;
                    757: request.msgBody.pmCallback = Callback;
                    758: 
                    759: #ifdef OMIT
                    760:        if (Callback == NULL)
                    761:        {
                    762:                kprintf("Cuda: ADBSetPollList callback is NULL\n");
                    763:        }
                    764: #endif
                    765: 
                    766: 
                    767: request.msgHeader.msg_simple = TRUE;
                    768: request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                    769: request.msgHeader.msg_remote_port = port;
                    770: request.msgHeader.msg_local_port = PORT_NULL;
                    771: request.msgHeader.msg_size = sizeof(CudaMachMessage);
                    772: return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                    773: 
                    774: if ( return_code == SEND_SUCCESS ) {
                    775:        return kPMUNoError;
                    776:        }
                    777: else {
                    778:        return kPMUIOError;
                    779:        }
                    780: }
                    781: 
                    782: 
                    783: 
                    784: 
                    785: // **********************************************************************************
                    786: // ADBSetFileServerMode()
                    787: //
                    788: // **********************************************************************************
                    789: - (PMUStatus)ADBSetFileServerMode       :(UInt32)RefNum
                    790:                                                :(id)Id
                    791:                                                :(pmCallback_func)Callback
                    792: 
                    793: {
                    794:        CudaMachMessage  request;
                    795:        msg_return_t    return_code;
                    796: 
                    797:        request.msgBody.a_cmd.a_header[0] = ADB_PACKET_PSEUDO;
                    798:        request.msgBody.a_cmd.a_header[1] = ADB_PSEUDOCMD_FILE_SERVER_FLAG;
                    799:        request.msgBody.a_cmd.a_header[2] = TRUE;
                    800:        request.msgBody.a_cmd.a_hcount = 3;
                    801:        request.msgBody.a_cmd.a_bcount = 0;
                    802:        request.msgBody.pmRefNum = RefNum;
                    803:        request.msgBody.pmId = Id;
                    804:        request.msgBody.pmCallback = Callback;
                    805: 
                    806:        request.msgHeader.msg_simple = TRUE;
                    807:        request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                    808:        request.msgHeader.msg_remote_port = port;
                    809:        request.msgHeader.msg_local_port = PORT_NULL;
                    810:        request.msgHeader.msg_size = sizeof(CudaMachMessage);
                    811:        return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                    812: 
                    813:        if ( return_code == SEND_SUCCESS ) {
                    814:         return kPMUNoError;
                    815:         }
                    816:        else {
                    817:         return kPMUIOError;
                    818:         }
                    819: }
                    820: 
                    821: 
                    822: // **********************************************************************************
                    823: // ADBPollEnable
                    824: //
                    825: // **********************************************************************************
                    826: - (PMUStatus)ADBPollEnable      :(UInt32)RefNum
                    827:                                 :(id)Id
                    828:                                 :(pmCallback_func)Callback
                    829: 
                    830: {
                    831: CudaMachMessage  request;
                    832: msg_return_t    return_code;
                    833: 
                    834: if (p) kprintf("ADBPollEnable\n");
                    835: request.msgBody.a_cmd.a_header[0] = ADB_PACKET_PSEUDO;
                    836: request.msgBody.a_cmd.a_header[1] = ADB_PSEUDOCMD_START_STOP_AUTO_POLL;
                    837: request.msgBody.a_cmd.a_header[2] = TRUE;
                    838: request.msgBody.a_cmd.a_hcount = 3;
                    839: request.msgBody.a_cmd.a_bcount = 0;
                    840: request.msgBody.pmRefNum = RefNum;
                    841: request.msgBody.pmId = Id;
                    842: request.msgBody.pmCallback = Callback;
                    843: 
                    844: request.msgHeader.msg_simple = TRUE;
                    845: request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                    846: request.msgHeader.msg_remote_port = port;
                    847: request.msgHeader.msg_local_port = PORT_NULL;
                    848: request.msgHeader.msg_size = sizeof(CudaMachMessage);
                    849: return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                    850: 
                    851: if ( return_code == SEND_SUCCESS ) {
                    852:         return kPMUNoError;
                    853:         }
                    854: else {
                    855:         return kPMUIOError;
                    856:         }
                    857: }
                    858: 
                    859: 
                    860: // **********************************************************************************
                    861: // ADBPollDisable
                    862: //
                    863: // **********************************************************************************
                    864: - (PMUStatus)ADBPollDisable    :(UInt32)RefNum
                    865:                                :(id)Id
                    866:                                :(pmCallback_func)Callback
                    867: {
                    868: CudaMachMessage        request;
                    869: msg_return_t   return_code;
                    870: 
                    871: if (p) kprintf("ADBPollDisable\n");
                    872: request.msgBody.a_cmd.a_header[0] = ADB_PACKET_PSEUDO;
                    873: request.msgBody.a_cmd.a_header[1] = ADB_PSEUDOCMD_START_STOP_AUTO_POLL;
                    874: request.msgBody.a_cmd.a_header[2] = FALSE;
                    875: request.msgBody.a_cmd.a_hcount = 3;
                    876: request.msgBody.a_cmd.a_bcount = 0;
                    877: request.msgBody.pmRefNum = RefNum;
                    878: request.msgBody.pmId = Id;
                    879: request.msgBody.pmCallback = Callback;
                    880: 
                    881: request.msgHeader.msg_simple = TRUE;
                    882: request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                    883: request.msgHeader.msg_remote_port = port;
                    884: request.msgHeader.msg_local_port = PORT_NULL;
                    885: request.msgHeader.msg_size = sizeof(CudaMachMessage);
                    886: return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                    887: 
                    888: if ( return_code == SEND_SUCCESS ) {
                    889:        return kPMUNoError;
                    890:        }
                    891: else {
                    892:        return kPMUIOError;
                    893:        }
                    894: }
                    895: 
                    896: 
                    897: // **********************************************************************************
                    898: // ADBSetPollRate
                    899: //
                    900: // **********************************************************************************
                    901: - (PMUStatus)ADBSetPollRate     :(UInt32)NewRate
                    902:                                :(UInt32)RefNum
                    903:                                 :(id)Id
                    904:                                 :(pmCallback_func)Callback
                    905: {
                    906: CudaMachMessage        request;
                    907: msg_return_t   return_code;
                    908: 
                    909: if (p) kprintf("ADBSetPollRate\n");
                    910: request.msgBody.a_cmd.a_header[0] = ADB_PACKET_PSEUDO;
                    911: request.msgBody.a_cmd.a_header[1] = ADB_PSEUDOCMD_SET_AUTO_RATE;
                    912: request.msgBody.a_cmd.a_header[2] = NewRate;
                    913: request.msgBody.a_cmd.a_hcount = 3;
                    914: request.msgBody.a_cmd.a_bcount = 0;
                    915: request.msgBody.pmRefNum = RefNum;
                    916: request.msgBody.pmId = Id;
                    917: request.msgBody.pmCallback = Callback;
                    918: 
                    919: request.msgHeader.msg_simple = TRUE;
                    920: request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                    921: request.msgHeader.msg_remote_port = port;
                    922: request.msgHeader.msg_local_port = PORT_NULL;
                    923: request.msgHeader.msg_size = sizeof(CudaMachMessage);
                    924: return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                    925: 
                    926: if ( return_code == SEND_SUCCESS ) {
                    927:        return kPMUNoError;
                    928:        }
                    929: else {
                    930:        return kPMUIOError;
                    931:        }
                    932: }
                    933: 
                    934: 
                    935: // **********************************************************************************
                    936: // ADBGetPollRate
                    937: //
                    938: // **********************************************************************************
                    939: - (PMUStatus)ADBGetPollRate     :(UInt32 *)CurrentRate
                    940:                                 :(UInt32)RefNum
                    941:                                 :(id)Id
                    942:                                 :(pmCallback_func)Callback
                    943: {
                    944: return kPMUNotSupported;
                    945: }
                    946: 
                    947: 
                    948: // **********************************************************************************
                    949: // ADBSetAlternateKeyboard
                    950: //
                    951: // **********************************************************************************
                    952: - (PMUStatus)ADBSetAlternateKeyboard   :(UInt32)DevAddr
                    953:                                        :(UInt32)RefNum
                    954:                                        :(id)Id
                    955:                                        :(pmCallback_func)Callback
                    956: {
                    957: return kPMUNotSupported;
                    958: }
                    959: 
                    960: 
                    961: // **********************************************************************************
                    962: // ADBinput
                    963: //
                    964: // The PGE has interrupted with ADB data.  We package this up and send
                    965: // it to our ADB client, if there is one, either as the result to its previous
                    966: // read command, or as autopoll data.
                    967: //
                    968: // Removed since cuda_process_response() does the same thing
                    969: // **********************************************************************************
                    970: 
                    971: 
                    972: // **********************************************************************************
                    973: // registerForClockTicks
                    974: //
                    975: // The RTC driver is calling to tell us that it is prepared to receive clock
                    976: // ticks every second.  The parameter block tells who to call when we get one.
                    977: //
                    978: // **********************************************************************************
                    979: - (void)registerForClockTicks  :(pmCallback_func)TickHandler
                    980:                                :(id)caller
                    981: {
                    982: RTCclient = TickHandler;
                    983: RTCid = caller;
                    984: }
                    985: 
                    986: 
                    987: // **********************************************************************************
                    988: // setRealTimeClock
                    989: //
                    990: // The RTC driver is calling to set the real time clock.  We translate this into
                    991: // a PMU command and enqueue it to our command queue.
                    992: //
                    993: // **********************************************************************************
                    994: - (PMUStatus)setRealTimeClock  :(UInt8 *)newTime
                    995:                                :(UInt32)RefNum
                    996:                    :(id)Id
                    997:                 :(pmCallback_func)Callback
                    998: {
                    999: CudaMachMessage  request;
                   1000: msg_return_t    return_code;
                   1001: 
                   1002: if (p) kprintf("ADBSetRealTimeClock\n");
                   1003: if ( newTime == NULL ) {
                   1004:        return kPMUParameterError;
                   1005:        }
                   1006: 
                   1007: request.msgBody.a_cmd.a_header[0] = ADB_PACKET_PSEUDO;
                   1008: request.msgBody.a_cmd.a_header[1] = ADB_PSEUDOCMD_SET_REAL_TIME;
                   1009: request.msgBody.a_cmd.a_hcount = 2;
                   1010: request.msgBody.a_cmd.a_buffer[0] = newTime[0];
                   1011: request.msgBody.a_cmd.a_buffer[1] = newTime[1];
                   1012: request.msgBody.a_cmd.a_buffer[2] = newTime[2];
                   1013: request.msgBody.a_cmd.a_buffer[3] = newTime[3];
                   1014: request.msgBody.a_cmd.a_bcount = 4;
                   1015: request.msgBody.pmRefNum = RefNum;
                   1016: request.msgBody.pmId = Id;
                   1017: request.msgBody.pmCallback = Callback;
                   1018: 
                   1019: request.msgHeader.msg_simple = TRUE;
                   1020: request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                   1021: request.msgHeader.msg_remote_port = port;
                   1022: request.msgHeader.msg_local_port = PORT_NULL;
                   1023: request.msgHeader.msg_size = sizeof(CudaMachMessage);
                   1024: return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                   1025: 
                   1026: if ( return_code == SEND_SUCCESS ) {
                   1027:         return kPMUNoError;
                   1028:         }
                   1029: else {
                   1030:         return kPMUIOError;
                   1031:         }
                   1032: }
                   1033: 
                   1034: 
                   1035: // **********************************************************************************
                   1036: // getRealTimeClock
                   1037: //
                   1038: // The RTC driver is calling to read the real time clock.  We translate this into
                   1039: // a PMU command and enqueue it to our command queue.
                   1040: // Called from PowerSurgeMB.m
                   1041: //
                   1042: // **********************************************************************************
                   1043: - (PMUStatus)getRealTimeClock  :(UInt8 *)currentTime
                   1044:                                 :(UInt32)RefNum
                   1045:                                    :(id)Id
                   1046:                                 :(pmCallback_func)Callback
                   1047: {
                   1048: CudaMachMessage  request;
                   1049: msg_return_t    return_code;
                   1050: 
                   1051: if (p) kprintf("ADBGetRealTimeClock\n");
                   1052: 
                   1053: request.msgBody.a_cmd.a_header[0] = ADB_PACKET_PSEUDO;
                   1054: request.msgBody.a_cmd.a_header[1] = ADB_PSEUDOCMD_GET_REAL_TIME;
                   1055: request.msgBody.a_cmd.a_hcount = 2;
                   1056: request.msgBody.a_cmd.a_bcount = 0;  //A.W. added 2/27.  Is it enough?  Response Specs:
                   1057:                                                                         //  Attention Byte
                   1058:                                                                         //  Response Type = PSEUDO
                   1059:                                                                         //  Response Flag
                   1060:                                                                         //  Command (was)
                   1061:                                                                         //  Data (Real Time Clock MSB)
                   1062:                                                                         //  Data 
                   1063:                                                                         //  Data 
                   1064:                                                                         //  Data (RTC LSB)
                   1065:                                                                         //  Idle Byte
                   1066: 
                   1067: //The a_cmd.a_buffer is filled in by cuda_transmit_data()... but I need receive_data
                   1068: //Called from PowerSurgeMB.m
                   1069: /*** following commented out because it doesn't look right
                   1070: request.msgBody.a_cmd.a_buffer[0] = currentTime[0];
                   1071: request.msgBody.a_cmd.a_buffer[1] = currentTime[1];
                   1072: request.msgBody.a_cmd.a_buffer[2] = currentTime[2];
                   1073: request.msgBody.a_cmd.a_buffer[3] = currentTime[3];
                   1074: ******/
                   1075: bImmediate_buff_needed = TRUE;
                   1076: return_buff_pointer = currentTime;
                   1077: request.msgBody.a_reply.a_bsize = 8; //It's 8 in adb.h
                   1078: 
                   1079: request.msgBody.pmRefNum = RefNum;
                   1080: request.msgBody.pmId = Id;
                   1081: request.msgBody.pmCallback = Callback;
                   1082: 
                   1083: request.msgHeader.msg_simple = TRUE;
                   1084: request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                   1085: request.msgHeader.msg_remote_port = port;
                   1086: request.msgHeader.msg_local_port = PORT_NULL;
                   1087: request.msgHeader.msg_size = sizeof(CudaMachMessage);
                   1088: return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                   1089: 
                   1090: if ( return_code == SEND_SUCCESS ) {
                   1091:         return kPMUNoError;
                   1092:         }
                   1093: else {
                   1094:         return kPMUIOError;
                   1095:         }
                   1096: }
                   1097: 
                   1098: 
                   1099: 
                   1100: // **********************************************************************************
                   1101: // setPowerupTime
                   1102: // This sets the future time (in seconds) when Cuda will power-up the system again
                   1103: // If the power is already on then nothing happens.  TRICKLE SENSE must be asserted.
                   1104: //
                   1105: // **********************************************************************************
                   1106: - (PMUStatus)setPowerupTime    :(UInt8 *)newTime
                   1107:                                :(UInt32)RefNum
                   1108:                    :(id)Id
                   1109:                 :(pmCallback_func)Callback
                   1110: {
                   1111: CudaMachMessage  request;
                   1112: msg_return_t    return_code;
                   1113: 
                   1114:        if ( newTime == NULL ) {
                   1115:                return kPMUParameterError;
                   1116:        }
                   1117: 
                   1118:        if ( auto_power_on == 0) {
                   1119:         return kPMUNoError;
                   1120:        }
                   1121: 
                   1122:        request.msgBody.a_cmd.a_header[0] = ADB_PACKET_PSEUDO;
                   1123:        request.msgBody.a_cmd.a_header[1] = ADB_PSEUDOCMD_SET_POWER_UPTIME;
                   1124:        request.msgBody.a_cmd.a_hcount = 2;
                   1125:        request.msgBody.a_cmd.a_buffer[0] = newTime[0];
                   1126:        request.msgBody.a_cmd.a_buffer[1] = newTime[1];
                   1127:        request.msgBody.a_cmd.a_buffer[2] = newTime[2];
                   1128:        request.msgBody.a_cmd.a_buffer[3] = newTime[3];
                   1129:        request.msgBody.a_cmd.a_bcount = 4;
                   1130:        request.msgBody.pmRefNum = RefNum;
                   1131:        request.msgBody.pmId = Id;
                   1132:        request.msgBody.pmCallback = Callback;
                   1133: 
                   1134:        request.msgHeader.msg_simple = TRUE;
                   1135:        request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                   1136:        request.msgHeader.msg_remote_port = port;
                   1137:        request.msgHeader.msg_local_port = PORT_NULL;
                   1138:        request.msgHeader.msg_size = sizeof(CudaMachMessage);
                   1139:        return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                   1140: 
                   1141:        if ( return_code == SEND_SUCCESS ) {
                   1142:         return kPMUNoError;
                   1143:         }
                   1144:        else {
                   1145:         return kPMUIOError;
                   1146:         }
                   1147: }
                   1148: 
                   1149: 
                   1150: // **********************************************************************************
                   1151: // CudaMisc
                   1152: //
                   1153: //
                   1154: // **********************************************************************************
                   1155: - (PMUStatus)CudaMisc          :(UInt8 *)output
                   1156:                                :(UInt32)length
                   1157:                                :(UInt32)RefNum
                   1158:                    :(id)Id
                   1159:                                :(pmCallback_func)Callback
                   1160: {
                   1161: CudaMachMessage  request;
                   1162: msg_return_t    return_code;
                   1163: int            i;
                   1164: 
                   1165: for ( i = 0; i < length; i++ ) {
                   1166:        //I should check for length < 8 but I trust callers in adb.m and PowerSurgeMB.m
                   1167:        request.msgBody.a_cmd.a_header[i] = output[i];
                   1168:        }
                   1169: 
                   1170: request.msgBody.a_cmd.a_hcount = length;
                   1171: request.msgBody.a_cmd.a_bcount = 0;
                   1172: //Don't need to worry about how big the caller's buffer is because
                   1173: // cuda's adb_packet_t buffer is 8 bytes, and it's the caller who
                   1174: // must copy the bytes in its callback function
                   1175: request.msgBody.a_reply.a_bsize = 8; //It's 8 in adb.h for adb_packet_type
                   1176: request.msgBody.pmRefNum = RefNum;
                   1177: request.msgBody.pmId = Id;
                   1178: request.msgBody.pmCallback = Callback;
                   1179: 
                   1180: request.msgHeader.msg_simple = TRUE;
                   1181: request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                   1182: request.msgHeader.msg_remote_port = port;
                   1183: request.msgHeader.msg_local_port = PORT_NULL;
                   1184: request.msgHeader.msg_size = sizeof(CudaMachMessage);
                   1185: return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                   1186: 
                   1187: if ( return_code == SEND_SUCCESS ) {
                   1188:         return kPMUNoError;
                   1189:         }
                   1190: else {
                   1191:         return kPMUIOError;
                   1192:         }
                   1193: 
                   1194: }
                   1195: 
                   1196: 
                   1197: 
                   1198: //This function calls back the ADB client (such as Mouse driver).
                   1199: -(void) cuda_process_response
                   1200: {
                   1201: 
                   1202:        if ( cuda_transaction_state == CUDA_TS_SYNC_RESPONSE ) 
                   1203:        {
                   1204:                if ( cuda_request->pmCallback != NULL ) {       // make the client callback
                   1205: 
                   1206: if (p) kprintf("cuda_process_response: pmId =  %08x, a_bcount = %08x, a_buffer = %08x\n",
                   1207: cuda_request->pmId, cuda_request->a_reply.a_bcount, cuda_request->a_reply.a_buffer);
                   1208: 
                   1209: 
                   1210:                        cuda_request->pmCallback ( cuda_request->pmId,
                   1211:                                cuda_request->pmRefNum,
                   1212:                                cuda_request->a_reply.a_bcount, 
                   1213:                                cuda_request->a_reply.a_buffer  );
                   1214:                }
                   1215:                else
                   1216:                {
                   1217:                        //It's OK to not have a callback since some callers don't care
                   1218:                        // about synchronous completion
                   1219:                        //kprintf("WARNING: Cuda process_response() has no callback\n");
                   1220:                }
                   1221:                return_buff_pointer = NULL; //for getRealTimeClock only.  a_buffer[]
                   1222:                                                                        //above is ignored by PowerSurgeMB.m
                   1223:                bImmediate_buff_needed = FALSE;
                   1224: //kprintf("cuda.m: cuda_process_response end \n");
                   1225:        }
                   1226: 
                   1227:        else 
                   1228:        {
                   1229:                if ( cuda_transaction_state == CUDA_TS_ASYNC_RESPONSE ) 
                   1230:                {
                   1231:                        if ( ADBclient != NULL ) 
                   1232:                        {               // call the client input handler
                   1233:                                cuda_freeze_counter++;
                   1234: 
                   1235: if (p) {
                   1236: kprintf("cuda2.m::cuda_process_response ASYNC \n");
                   1237: kprintf("cuda2.m::ASYNC count is %d\n", cuda_current_response->a_bcount);
                   1238: kprintf("cuda2.m::ASYNC buffer 0 is %x\n", cuda_current_response->a_buffer[0]);
                   1239: kprintf("cuda2.m::ASYNC buffer 1 is %x\n", cuda_current_response->a_buffer[1]);
                   1240: kprintf("cuda2.m::ASYNC buffer 2 is %x\n", cuda_current_response->a_buffer[2]);
                   1241: kprintf("cuda2.m::ASYNC buffer 3 is %x\n", cuda_current_response->a_buffer[3]);
                   1242: kprintf("cuda2.m::ASYNC buffer 4 is %x\n", cuda_current_response->a_buffer[4]);
                   1243: kprintf("cuda2.m::ASYNC buffer 5 is %x\n", cuda_current_response->a_buffer[5]);
                   1244: kprintf("cuda2.m::ASYNC header 0 is %x\n", cuda_current_response->a_header[0]);
                   1245: kprintf("cuda2.m::ASYNC header 1 is %x\n", cuda_current_response->a_header[1]);
                   1246: kprintf("cuda2.m::ASYNC header 2 is %x\n", cuda_current_response->a_header[2]);
                   1247: }
                   1248: 
                   1249: if (p) kprintf("cuda_process_response: ADBclient = %08x, ADBid = %08x\n", ADBclient, ADBid);
                   1250: 
                   1251: #ifdef DEBUG
                   1252:                cuda_glob_data1 = cuda_current_response->a_buffer[0];
                   1253:                cuda_glob_data2 = cuda_current_response->a_buffer[1];
                   1254:                if (cuda_glob_dbug_freeze == 1) 
                   1255:                {
                   1256:                        //kprintf("%x %x \n", cuda_glob_data1, cuda_glob_data2);
                   1257:                }
                   1258: #endif
                   1259:                                //ADBClient is the global variable that clients registered with
                   1260:  ADBclient(ADBid,
                   1261:           0,
                   1262:           (cuda_current_response->a_header[2] >> 4) & 0xf,
                   1263:           cuda_current_response->a_bcount,
                   1264:           &cuda_current_response->a_buffer[0]);
                   1265:                        }
                   1266:                }
                   1267:        }
                   1268: }
                   1269:        
                   1270: 
                   1271: // **********************************************************************************
                   1272: // readNVRAM
                   1273: //
                   1274: // The NVRAM driver is calling to read part of the NVRAM.  We translate this into
                   1275: // a PMU command and enqueue it to our command queue.
                   1276: //
                   1277: // **********************************************************************************
                   1278: - (PMUStatus) readNVRAM :(UInt32)Offset
                   1279:                         :(UInt32)Length
                   1280:                        :(UInt8 *)Buffer
                   1281:                         :(UInt32)RefNum
                   1282:                         :(id)Id
                   1283:                         :(pmCallback_func)Callback
                   1284: {
                   1285:        return kPMUNotSupported;
                   1286: }
                   1287: 
                   1288: 
                   1289: // **********************************************************************************
                   1290: // writeNVRAM
                   1291: //
                   1292: // The NVRAM driver is calling to write part of the NVRAM.  We translate this into
                   1293: // a PMU command and enqueue it to our command queue.
                   1294: //
                   1295: // **********************************************************************************
                   1296: - (PMUStatus) writeNVRAM:(UInt32)Offset
                   1297:                         :(UInt32)Length
                   1298:                        :(UInt8 *)Buffer
                   1299:                         :(UInt32)RefNum
                   1300:                         :(id)Id
                   1301:                         :(pmCallback_func)Callback
                   1302: {
                   1303:        return kPMUNotSupported;
                   1304: }
                   1305: 
                   1306: 
                   1307: // **********************************************************************************
                   1308: // registerForPowerInterrupts
                   1309: //
                   1310: // Some driver is calling to say it is prepared to receive "unsolicited" power-system
                   1311: // interrups (e.g. battery low).  The parameter block says who to call when we get one.
                   1312: //
                   1313: // **********************************************************************************
                   1314: - (void)registerForPowerInterrupts     :(pmCallback_func)buttonHandler
                   1315:                                        :(id)caller
                   1316: {
                   1317: PWRclient = buttonHandler;
                   1318: PWRid = caller;
                   1319: }
                   1320: 
                   1321: 
                   1322: // **********************************************************************************
                   1323: // sendMiscCommand
                   1324: //
                   1325: // Some driver is calling to send some miscellaneous command.  We copy this into a
                   1326: // PMU command and enqueue it to our command queue.
                   1327: // A.W. Not completed yet for Cuda commands!!
                   1328: // **********************************************************************************
                   1329: - (PMUStatus)sendMiscCommand   :(UInt32)Command
                   1330:                                :(UInt32)SLength
                   1331:                                :(UInt8 *)SBuffer
                   1332:                                :(UInt8 *)RBuffer
                   1333:                                :(UInt32)RefNum
                   1334:                                :(id)Id
                   1335:                                :(pmCallback_func)Callback
                   1336: {
                   1337: CudaMachMessage  request;
                   1338: msg_return_t    return_code;
                   1339: spl_t          interruptState;
                   1340: 
                   1341: 
                   1342:        if (Command == kPMUPmgrPWRoff)
                   1343:        {
                   1344:                //kprintf("\nCuda received power-down message\n");
                   1345:                request.msgBody.a_cmd.a_header[1] = ADB_PSEUDOCMD_POWER_DOWN;
                   1346:                auto_power_on = 0;      //console operator really wants to shut off power
                   1347:        }
                   1348:        else if (Command == kPMUresetCPU)
                   1349:        {
                   1350:                request.msgBody.a_cmd.a_header[1] = ADB_PSEUDOCMD_RESTART_SYSTEM;
                   1351:                //kprintf("\nCuda received reset message\n");
                   1352:        }
                   1353:        else
                   1354:        {
                   1355:                return kPMUParameterError;
                   1356:        }
                   1357: 
                   1358:        //A.W. 3/17/98 I found out that reboots cannot happen from within
                   1359:        // the mini-monitor because interrupts are turned off, which means
                   1360:        // Cuda cannot get the subsequent command packet bytes to reboot
                   1361:        // However, Simon says that next 2 lines are not necessary
                   1362:        // WARNING The current file is checked out from trunk, don't check in
                   1363:        interruptState = spltty();
                   1364:        splx(interruptState);
                   1365: //request.msgBody.a_reply.a_bsize = 0; //we don't expect any replies for two commands above
                   1366: request.msgBody.a_reply.a_bsize = 8; //reset fails WARNING
                   1367: request.msgBody.a_cmd.a_header[0] = ADB_PACKET_PSEUDO;
                   1368: request.msgBody.a_cmd.a_hcount = 2;
                   1369: request.msgBody.a_cmd.a_bcount = 0;
                   1370: request.msgBody.pmRefNum = RefNum;
                   1371: request.msgBody.pmId = Id;
                   1372: request.msgBody.pmCallback = Callback;
                   1373: 
                   1374: request.msgHeader.msg_simple = TRUE;
                   1375: request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                   1376: request.msgHeader.msg_remote_port = port;
                   1377: request.msgHeader.msg_local_port = PORT_NULL;
                   1378: request.msgHeader.msg_size = sizeof(CudaMachMessage);
                   1379: return_code = msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                   1380: 
                   1381: if ( return_code == SEND_SUCCESS ) {
                   1382:         return kPMUNoError;
                   1383:         }
                   1384: else {
                   1385:         return kPMUIOError;
                   1386:         }
                   1387: }
                   1388: 
                   1389: 
                   1390: // **********************************************************************************
                   1391: // StartCudaTransmission
                   1392: //
                   1393: // Called with PMU interrupts disabled. q8q
                   1394: // Transmission of the command byte is started.  The transaction will be
                   1395: // completed by the Shift Register Interrupt Service Routine.
                   1396: // **********************************************************************************
                   1397: - (void)StartCudaTransmission:(CudaRequest *)plugInMessage;
                   1398: {
                   1399: 
                   1400: 
                   1401:        if (( *VIA2_dataB & kCudaTransferRequestMask) == 0)
                   1402:        {
                   1403:                //Simon says there's a collision here
                   1404:        cuda_interrupt_state = CUDA_STATE_ATTN_EXPECTED;
                   1405:        cuda_transaction_state = CUDA_TS_ASYNC_RESPONSE;
                   1406:                [self cuda_queue: plugInMessage];
                   1407:                return;
                   1408:        }
                   1409: 
                   1410:        //MAJOR CHANGE 8/6/98... 2 lines were at beginning, IDLE didn't make sense there
                   1411:        if ( cuda_interrupt_state == CUDA_STATE_IDLE)
                   1412:        {
                   1413:        clientRequest = plugInMessage;
                   1414:        firstChar = plugInMessage->a_cmd.a_header[0];   //Should be ADB_PACKET or PSEUDO
                   1415:        charCountS1 = plugInMessage->a_cmd.a_hcount;
                   1416: 
                   1417:        dataPointer1 = &plugInMessage->a_cmd.a_header[0];
                   1418: 
                   1419:     cuda_request = plugInMessage;
                   1420:     cuda_request->a_reply.a_bcount = 0;
                   1421: 
                   1422: 
                   1423:        // cuda_set_data_direction_to_output(); //On cuda value is 0x10;
                   1424:        *VIA1_auxillaryControl |= kCudaSystemSend; eieio();
                   1425: 
                   1426:     // ADBPollDisable is handled how?
                   1427:        *VIA1_shift = firstChar;        // give it the byte (this clears any pending SR interrupt)
                   1428: 
                   1429:     // Set up the transfer state info here.
                   1430: 
                   1431:     cuda_is_header_transfer = TRUE;
                   1432:     cuda_transfer_count = 1;
                   1433: 
                   1434: 
                   1435: 
                   1436:        // *VIA2_dataB &= ~kCudaNegateTransferRequest;  // yes, assert /REQ
                   1437:        //I think I actually need to assert TIP here, not REQ.
                   1438:        //eieio();
                   1439: 
                   1440: 
                   1441:     // cuda_neg_byte_ack(); 
                   1442:        *VIA2_dataB |= kCudaNegateByteAcknowledge; eieio();
                   1443: 
                   1444:     // cuda_assert_transfer_in_progress();
                   1445:        *VIA2_dataB      &= kCudaAssertTransferInProgress; eieio();
                   1446:     
                   1447:     // The next state is going to be a transmit state, if there is
                   1448:     // no collision.  This is a requested response but call it sync.
                   1449:     
                   1450:     cuda_interrupt_state = CUDA_STATE_TRANSMIT_EXPECTED;
                   1451: 
                   1452:        //INVESTIGATE:  we get here even if there was a collision and the
                   1453:        // collision packet was put onto the queue.  In that case it means
                   1454:        // the transaction was ASYNC?
                   1455:        // This entire function is protected by splt so no interrupts should
                   1456:        // be happening at all.
                   1457:     cuda_transaction_state = CUDA_TS_SYNC_RESPONSE;
                   1458: 
                   1459:        return;
                   1460:        
                   1461:        }
                   1462: }
                   1463: 
                   1464: 
                   1465: 
                   1466: //This ISR is copied from cuda.c.  The nice thing about Cuda is that at any
                   1467: // time we can determine state of hardware by examining 3 bits.
                   1468: - (void)interruptOccurred
                   1469: {
                   1470: 
                   1471:     unsigned char   interruptState;
                   1472: 
                   1473:        *VIA2_dataB |= kCudaNegateTransferRequest;      // deassert /REQ 
                   1474: 
                   1475:     // Get the relevant signal in determining the cause of the interrupt:
                   1476:     // the shift direction, the transfer request line and the transfer
                   1477:     // request line.
                   1478: 
                   1479:     //interruptState = cuda_get_interrupt_state();
                   1480:     interruptState =  (*VIA2_dataB & kCudaInterruptStateMask) | (*VIA1_auxillaryControl & kCudaDirectionMask) ;
                   1481:        
                   1482: #ifdef DEBUG
                   1483:        if ( cuda_glob_dbug_freeze == 1)        
                   1484:        {
                   1485:                printf(" %d: ", interruptState);
                   1486:        }
                   1487: #endif
                   1488: 
                   1489:        //no use DELAY(12);     //12 microsecond delay in Ray Montagne's Cuda Manager for MacOS
                   1490: 
                   1491:     switch ( interruptState ) {
                   1492: 
                   1493:     case kCudaReceiveByte:
                   1494: if (p) kprintf("CUDA ** INTERRUPT ** RECEIVE *** \n");
                   1495:                [self cuda_receive_data];
                   1496:         break;
                   1497: 
                   1498:     case kCudaReceiveLastByte:
                   1499: if (p) kprintf("CUDA ** INTERRUPT ** RECEIVE LAST BYTE *** \n");
                   1500:                [self cuda_receive_last_byte];
                   1501:         break;
                   1502: 
                   1503:     case kCudaTransmitByte:
                   1504: if (p) kprintf("CUDA ** INTERRUPT ** TRANSMIT *** \n");
                   1505:                [self cuda_transmit_data];
                   1506:         break;
                   1507: 
                   1508:     case kCudaUnexpectedAttention:
                   1509: if (p) kprintf("CUDA ** INTERRUPT ** Unexpected Attention *** \n");
                   1510:                [self cuda_unexpected_attention];
                   1511:         break;
                   1512: 
                   1513:     case kCudaExpectedAttention:
                   1514: if (p) kprintf("CUDA ** INTERRUPT ** EXPECTED ATTENTION  *** \n");
                   1515:                [self cuda_expected_attention];
                   1516:         break;
                   1517: 
                   1518:     case kCudaIdleState:
                   1519: if (p) kprintf("CUDA ** INTERRUPT ** IDLE *** \n");
                   1520:                [self cuda_idle];
                   1521:         break;
                   1522: 
                   1523:     case kCudaCollision:
                   1524: if (p) kprintf("Cuda *** INTERRUPT *** ADB collision\n");
                   1525:                [self cuda_collision];
                   1526:         break;
                   1527: 
                   1528:     // Unknown interrupt, clear it and leave
                   1529:     default:
                   1530: if (p) kprintf("Cuda *** INTERRUPT *** ERROR\n");
                   1531:                [self cuda_error];
                   1532:         break;
                   1533:     }
                   1534: }
                   1535: 
                   1536: 
                   1537: // ****************************************************************************
                   1538: //     interruptOccurredAt
                   1539: //     PGE has interrupted.  Send the ReadInt command to find out why.
                   1540: //     When the command byte is sent, the Shift Register will interrupt.
                   1541: //     If we are mid-transaction when we find out about the interrupt,
                   1542: //     set a flag and find out why later.
                   1543: //
                   1544: //  A.W. Removed 2/11/98 because cuda only has 1 interrupt
                   1545: //
                   1546: // ****************************************************************************
                   1547: 
                   1548: 
                   1549:        
                   1550: // ****************************************************************************
                   1551: // gotInterruptCause
                   1552: // 
                   1553: // Called by the debug-mode PMU interrupt handler as the Callback function
                   1554: // after sending the kPMUreadInt command and receiving its response
                   1555: // A.W. only called by interruptOccurredAt above, so remove as well
                   1556: // ****************************************************************************
                   1557: 
                   1558: 
                   1559: // ****************************************************************************
                   1560: // EnableCudaInterrupt  used to be EnablePMUInterrupt
                   1561: // ****************************************************************************
                   1562: - (void)EnableCudaInterrupt
                   1563: {
                   1564: 
                   1565:        // cuda_enable_interrupt();     // from cuda_hdw.h
                   1566:        *VIA1_interruptEnable = kCudaInterruptEnable; 
                   1567:        eieio();
                   1568: 
                   1569: }
                   1570: 
                   1571: 
                   1572: #ifdef OMIT
                   1573: // ****************************************************************************
                   1574: // timer_expired
                   1575: //
                   1576: // Our adb-read timer has expired, so we have to notify our i/o thread by
                   1577: // enqueuing a Timeout message to its interrupt port.
                   1578: // This was only called by ADBinput() in pmu.m, but cuda doesn't have ADBinput()
                   1579: // so this method is useless for now.
                   1580: // ****************************************************************************
                   1581: void timer_expired(port_t mach_port)
                   1582: {
                   1583: PMUmachMessage request;
                   1584: 
                   1585: request.msgHeader.msg_simple = TRUE;
                   1586: request.msgHeader.msg_type = MSG_TYPE_NORMAL;
                   1587: request.msgHeader.msg_id = IO_TIMEOUT_MSG;
                   1588: request.msgHeader.msg_remote_port = mach_port;
                   1589: request.msgHeader.msg_local_port = PORT_NULL;
                   1590: request.msgHeader.msg_size = sizeof(msg_header_t);
                   1591: msg_send_from_kernel(&request.msgHeader, MSG_OPTION_NONE, 0);
                   1592: 
                   1593: }
                   1594: 
                   1595: #endif
                   1596: 
                   1597: 
                   1598: 
                   1599: // ****************************************************************************
                   1600: // cuda_timer_autopoll
                   1601: //
                   1602: // Automatic scheduling of command to make sure auto-polling is always available
                   1603: // In worst case, I may want to reset Cuda here.
                   1604: // ****************************************************************************
                   1605: void cuda_timer_autopoll(port_t mach_port)
                   1606: {  
                   1607:     CudaMachMessage request;
                   1608:        extern int      kdp_flag;
                   1609:        static int      old_kdp_flag;
                   1610:        static int      cuda_TREQ_history;
                   1611:        VIAAddress      temp_register, dataB;
                   1612:        unsigned char   interruptState;
                   1613:        //unsigned int    newTime;
                   1614: 
                   1615: #ifdef DEBUG
                   1616:        //[ApplePMUId ADBPollEnable :0:0: NULL];  //stress this one
                   1617:        //newTime = 0;
                   1618:        //[ApplePMUId getRealTimeClock :(UInt8 *)&newTime : 0: 0: NULL];
                   1619: 
                   1620:        //*stat_aux_control &= kCudaSystemRecieve; eieio();
                   1621:     ns_timeout((func)cuda_timer_autopoll,(void *)glob_port, kNS_TIMEOUT_AUTOPOLL,CALLOUT_PRI_SOFTINT0);  // start timer again for another 4 seconds
                   1622:        //Can only be set through debugging tool
                   1623:        switch (cuda_glob_dbug_freeze ) 
                   1624:        {
                   1625:                case 0:
                   1626:                        old_kdp_flag = kdp_flag;
                   1627:                        break;
                   1628:                case 1:
                   1629:                        kdp_flag |= 0x02;
                   1630:                        temp_register = stat_aux_control + 0x1600;  //auxillary
                   1631:                        dataB = stat_aux_control ;
                   1632:                interruptState =  (*dataB & kCudaInterruptStateMask) | (*temp_register & kCudaDirectionMask) ;
                   1633:                        printf("CUDA: 4-second periodic, interruptState is %x\n", interruptState);
                   1634:                        kprintf("CUDA: 4-second periodic, interruptState is %x\n", interruptState);
                   1635: 
                   1636: #ifdef OMIT_CUDA_DBUG
                   1637:                        //kprintf("istate = %x ", interruptState);
                   1638:                        //temp_register = stat_aux_control + 0x1A00;  
                   1639:                        //kprintf("ir flag = %x ", *temp_register);
                   1640:                        //eieio();
                   1641:                        temp_register   = stat_aux_control + 0x1600; //auxillary
                   1642:                        kprintf("aux= %x ", *temp_register);
                   1643:                        eieio();
                   1644:                        temp_register   = stat_aux_control;//dataB
                   1645:                        kprintf("dataB= %x ", *temp_register);
                   1646:                        eieio();
                   1647:                        temp_register   = stat_aux_control + 0x1400;    // SHIFT
                   1648:                        kprintf("shift= %x ", *temp_register);
                   1649:                        eieio();
                   1650:                        temp_register   = stat_aux_control + 0x1c00;    // Interrupt Enable
                   1651:                        kprintf("IE= %x \n", *temp_register);
                   1652:                        eieio();
                   1653: #endif
                   1654: 
                   1655:                        //put printf here so it doesn't interfere with other debugging sessions
                   1656:                        break;
                   1657:                case 2:  
                   1658:                        //May disabling Cuda debugging kprintf, but preserve "4" for debugging
                   1659:                        kdp_flag = old_kdp_flag;
                   1660:                        break;
                   1661:                case 3:
                   1662:                        cuda_glob_dbug_freeze = 1; 
                   1663:                cuda_interrupt_state = CUDA_STATE_IDLE;  //Force state change
                   1664:                        [ApplePMUId EnableCudaInterrupt];   
                   1665:                        [ApplePMUId enableAllInterrupts]; 
                   1666:                        [ApplePMUId ADBReset :0:0: NULL]; 
                   1667:                        //mouse will be in low-res mode
                   1668:                        break;
                   1669:                case 4:
                   1670:                        cuda_glob_dbug_freeze = 1;
                   1671:                        [ApplePMUId ADBPollEnable :0:0: NULL];
                   1672:                        //No side effects seen for now, but gets queued when cuda freezes
                   1673:                        break;
                   1674:                case 5:
                   1675:                        cuda_glob_dbug_freeze = 1;
                   1676:                        [ApplePMUId ADBFlush :2:0:0: NULL]; //keyboard is 2
                   1677:                        //No side effects seen for now, but gets queued when cuda freezes
                   1678:                        break;
                   1679:                case 6:
                   1680:                        cuda_glob_dbug_freeze = 1;
                   1681:                        //change data direction to input
                   1682:                        temp_register = stat_aux_control + 0x1600;
                   1683:                        *temp_register &= kCudaSystemRecieve; eieio();
                   1684:                        break;
                   1685:                case 7:
                   1686:                        cuda_glob_dbug_freeze = 1;
                   1687:                        temp_register   = stat_aux_control + 0x1400;    // SHIFT
                   1688:                        interruptState = *temp_register; eieio(); //dummy read
                   1689:                        //Simon suggests toggling the byteack too
                   1690:                        temp_register   = stat_aux_control;//dataB
                   1691:                *temp_register ^= kCudaByteAcknowledgeMask; eieio();
                   1692:                        break;
                   1693:                case 8:
                   1694:                cuda_interrupt_state = CUDA_STATE_IDLE;  //Force state change
                   1695:                        temp_register   = stat_aux_control;//dataB
                   1696:                        *temp_register &= kCudaAssertTransferInProgress;
                   1697:                        *temp_register |= kCudaNegateByteAcknowledge ;
                   1698:                        eieio();
                   1699:                        cuda_glob_dbug_freeze = 1;
                   1700:                        break;
                   1701:                case 9:
                   1702:                        cuda_glob_dbug_freeze = 1;
                   1703:                        cuda_current_response->a_buffer[0] = 0;
                   1704:                        cuda_current_response->a_buffer[1] = 0xff;
                   1705:                        cuda_debug_client(0, 0, 2, 2, &cuda_current_response->a_buffer[0]);
                   1706:                        break;
                   1707:                case 10:
                   1708:                        cuda_glob_dbug_freeze = 1;
                   1709:                        call_kdp();
                   1710:                        break;
                   1711:                case 11:
                   1712:                        cuda_glob_dbug_freeze = 1; 
                   1713:                cuda_interrupt_state = CUDA_STATE_IDLE;  //Force state change
                   1714:                        [ApplePMUId EnableCudaInterrupt];   
                   1715:                        [ApplePMUId enableAllInterrupts]; 
                   1716:                        [ApplePMUId ADBPollEnable :0 :0: NULL];    
                   1717:                        break;
                   1718:                case 12:
                   1719:                        cuda_glob_dbug_freeze = 1;
                   1720:                        temp_register   = stat_aux_control + 0x1400;    // SHIFT
                   1721:                        interruptState = *temp_register; eieio(); //dummy read
                   1722:                        break;
                   1723:                case 20: //Negate ByteAcknowledge
                   1724:                        temp_register   = stat_aux_control;//dataB
                   1725:                *temp_register |= kCudaNegateByteAcknowledge; eieio();
                   1726:                        eieio();
                   1727:                        cuda_glob_dbug_freeze = 1;
                   1728:                        break;
                   1729:                case 21:
                   1730:                        //Set ByteAcknowledge
                   1731:                        temp_register   = stat_aux_control;//dataB
                   1732:                *temp_register &= kCudaAssertByteAcknowledge; eieio();
                   1733:                        eieio();
                   1734:                        cuda_glob_dbug_freeze = 1;
                   1735:                        break;
                   1736:                case 22:
                   1737:                        //Set TIP
                   1738:                        temp_register = stat_aux_control; //dataB
                   1739:                *temp_register &= kCudaTransferInProgressMask;
                   1740:                        eieio();
                   1741:                        cuda_glob_dbug_freeze = 1;
                   1742:                        break;
                   1743:                case 23:
                   1744:                        //Negate TIP
                   1745:                        temp_register = stat_aux_control; //dataB
                   1746:                *temp_register |= kCudaNegateTransferInProgress;
                   1747:                        eieio();
                   1748:                        cuda_glob_dbug_freeze = 1;
                   1749:                        break;
                   1750:                case 24:
                   1751:                        //data direction to input
                   1752:                        temp_register   = stat_aux_control + 0x1600; //auxillary
                   1753:                *temp_register &= kCudaSystemRecieve;
                   1754:                        eieio();
                   1755:                        cuda_glob_dbug_freeze = 1;
                   1756:                        break;
                   1757:                case 25:
                   1758:                        //data direction to output
                   1759:                        temp_register   = stat_aux_control + 0x1600; //auxillary
                   1760:                *temp_register |= kCudaSystemSend;
                   1761:                        eieio();
                   1762:                        cuda_glob_dbug_freeze = 1;
                   1763:                        break;
                   1764:                case 30: //general reset
                   1765:                        {
                   1766:        temp_register = stat_aux_control + 0x0400;      //dataDirectionB
                   1767:     *temp_register |= (kCudaByteAcknowledgeMask | kCudaTransferInProgressMask);
                   1768:     *temp_register &= ~kCudaTransferRequestMask;
                   1769: 
                   1770:        temp_register   = stat_aux_control + 0x1600; //auxillary
                   1771:     *temp_register     = ( *temp_register      | kCudaTransferMode) & kCudaSystemRecieve;
                   1772: 
                   1773:     // Clear any posible cuda interupt.
                   1774:        temp_register = stat_aux_control + 0x1400;      //shift
                   1775:     if ( *temp_register );
                   1776:        eieio();
                   1777: 
                   1778:     // Initialize the internal data.
                   1779: 
                   1780:     cuda_interrupt_state    = CUDA_STATE_IDLE;
                   1781:     cuda_transaction_state  = CUDA_TS_NO_REQUEST;
                   1782:     cuda_is_header_transfer = FALSE;
                   1783:     cuda_is_packet_type = FALSE;
                   1784:     cuda_transfer_count = 0;    
                   1785:     cuda_current_response   = NULL;     
                   1786:     
                   1787:     // Terminate transaction and set idle state
                   1788:     // cuda_neg_tip_and_byteack();
                   1789:        temp_register = stat_aux_control; //dataB
                   1790:        *temp_register |= kCudaNegateByteAcknowledge | kCudaNegateTransferInProgress;
                   1791:        eieio();
                   1792:     
                   1793:     // we want to delay 4 mS for ADB reset to complete
                   1794:     
                   1795:     delay(4000);
                   1796:     
                   1797:     // Clear pending interrupt if any...
                   1798:     //(void)cuda_read_data();
                   1799:        temp_register = stat_aux_control + 0x1400; //Shift
                   1800:     if ( *temp_register ); eieio();
                   1801:     
                   1802:     // Issue a Sync Transaction, ByteAck asserted while TIP is negated.
                   1803:     // cuda_assert_byte_ack();
                   1804:        temp_register = stat_aux_control; //dataB
                   1805:        *temp_register &= kCudaAssertByteAcknowledge; eieio();
                   1806: 
                   1807: 
                   1808:     // Wait for the Sync acknowledgement, cuda to assert TREQ
                   1809:     // cuda_wait_for_transfer_request_assert();
                   1810:        while ( (*temp_register & kCudaTransferRequestMask) != 0 ) 
                   1811:        {
                   1812:                eieio();
                   1813:        }
                   1814:        eieio();
                   1815: 
                   1816:     // Wait for the Sync acknowledgement interrupt.
                   1817:     // cuda_wait_for_interrupt();
                   1818:        temp_register = stat_aux_control + 0x1A00; //VIA interrupt flag
                   1819:        while ( (*temp_register & kCudaInterruptMask) == 0 ) 
                   1820:        {
                   1821:                eieio();
                   1822:        }
                   1823:        eieio();
                   1824: 
                   1825: 
                   1826:     // Clear pending interrupt
                   1827:     //(void)cuda_read_data();
                   1828:        temp_register = stat_aux_control + 0x1400;      //shift
                   1829:     if ( *temp_register );
                   1830:        eieio();
                   1831: 
                   1832:     // Terminate the sync cycle by Negating ByteAck
                   1833:     // cuda_neg_byte_ack();
                   1834:        temp_register = stat_aux_control; //dataB
                   1835:        *temp_register |= kCudaNegateByteAcknowledge; eieio();
                   1836: 
                   1837:     // Wait for the Sync termination acknowledgement, cuda negates TREQ.
                   1838:     // cuda_wait_for_transfer_request_neg();
                   1839:        while ( (*temp_register & kCudaTransferRequestMask) == 0 ) 
                   1840:        {
                   1841:                eieio();
                   1842:        }
                   1843:        eieio();
                   1844: 
                   1845: 
                   1846:     // Wait for the Sync termination acknowledgement interrupt.
                   1847:     // cuda_wait_for_interrupt();
                   1848:        temp_register = stat_aux_control + 0x1A00; //VIA interrupt flag
                   1849:        while ( (*temp_register & kCudaInterruptMask) == 0 ) 
                   1850:        {
                   1851:                eieio();
                   1852:        }
                   1853:        eieio();
                   1854: 
                   1855: 
                   1856:     // Terminate transaction and set idle state, TIP negate and ByteAck negate.
                   1857:     // cuda_neg_transfer_in_progress();
                   1858:        temp_register = stat_aux_control; //dataB
                   1859:        *temp_register |= kCudaNegateTransferInProgress; eieio();
                   1860: 
                   1861:     // Clear pending interrupt, if there is one...
                   1862:     //(void)cuda_read_data();
                   1863:        temp_register = stat_aux_control + 0x1400;      //shift
                   1864:     if ( *temp_register );
                   1865:        eieio();
                   1866: 
                   1867: 
                   1868: 
                   1869: 
                   1870: debugging = FALSE;
                   1871: adb_reading = FALSE;
                   1872: 
                   1873: //CUDA_REPLACE
                   1874: // A.W. This call seems to have no counterpart in Cuda
                   1875: //     Pending interrupts are cleared with cuda_read_data()
                   1876:        temp_register = stat_aux_control + 0x1A00; //VIA interrupt flag
                   1877:        *temp_register = kCudaInterruptDisable;eieio(); // turn off any pending interrupt
                   1878: 
                   1879:        temp_register = stat_aux_control + 0x1400;      //shift
                   1880:     if ( *temp_register );
                   1881:        eieio();
                   1882: 
                   1883:        [ApplePMUId EnableCudaInterrupt];   
                   1884: 
                   1885:        [ApplePMUId enableAllInterrupts];
                   1886: 
                   1887:                        }
                   1888:                        break;
                   1889: 
                   1890:                case 40:
                   1891:                        //try AIX stuff
                   1892:                        temp_register = stat_aux_control; //dataB
                   1893:                *temp_register |= kCudaNegateTransferInProgress | kCudaNegateByteAcknowledge;
                   1894:                        eieio();
                   1895:                        [ApplePMUId EnableCudaInterrupt];   
                   1896:                        //[ApplePMUId enableAllInterrupts]; 
                   1897:                        [ApplePMUId ADBPollEnable :0 :0: NULL];    
                   1898:                        cuda_glob_dbug_freeze = 1;
                   1899:                        break;
                   1900: 
                   1901:                default:
                   1902:        }
                   1903: 
                   1904:        // Sept 11, 1998 Add new code to fix ADB hang problem
                   1905:        if ( cuda_freeze_counter == cuda_freeze_prevcount)
                   1906:        //Even if user never touches keyboard, this test is FALSE first time
                   1907:        {
                   1908:                //if here then that means either user has not moved ADB device for
                   1909:                // a long time or the system is hung
                   1910:                //kprintf("HH: No ADB movement so far\n");
                   1911:                //Now check TREQ (if in middle of transaction)
                   1912:                temp_register = stat_aux_control; //dataB
                   1913:                if ((*temp_register & kCudaTransferRequestMask) == 0 ) 
                   1914:                {
                   1915:                        //kprintf("HH: TREQ is 0 (asserted), incrementing flag now\n");
                   1916:                        cuda_TREQ_history++;
                   1917:                }
                   1918:                else
                   1919:                {
                   1920:                        cuda_TREQ_history = 0;
                   1921:                }
                   1922:                if ( cuda_TREQ_history == 2)  // 2 cycles already
                   1923:                {
                   1924:                        //Executing this code at any time has proven to be safe and does
                   1925:                        // not affect the operation of the high-resolution pointing devices
                   1926:                        //kprintf("HH: In recovery code now \n");
                   1927:                        printf("\nCuda: recover from transaction hang\n");
                   1928:                        temp_register = stat_aux_control; //dataB
                   1929:                *temp_register |= kCudaNegateTransferInProgress | kCudaNegateByteAcknowledge;
                   1930:                        eieio();
                   1931:                        [ApplePMUId EnableCudaInterrupt];   
                   1932:                        [ApplePMUId ADBPollEnable :0 :0: NULL];    
                   1933:                        cuda_TREQ_history = 0;
                   1934:                }
                   1935:        }
                   1936:        else
                   1937:        {
                   1938:                cuda_TREQ_history = 0;
                   1939:        }
                   1940: 
                   1941:        cuda_freeze_prevcount = cuda_freeze_counter ;  //Get ready for next 4-sec timer
                   1942: #endif  //DEBUG
                   1943: 
                   1944: 
                   1945: }
                   1946: 
                   1947: 
                   1948: // Cuda functions needed to help -interruptOccured:
                   1949: 
                   1950: 
                   1951: 
                   1952: 
                   1953: //
                   1954: //  TransmitCudaData
                   1955: //  Executes at hardware interrupt level.
                   1956: //
                   1957: 
                   1958: -(void) cuda_transmit_data
                   1959: {
                   1960:        volatile unsigned char valcuda;  //dummy, unused
                   1961:     // Clear the pending interrupt by reading the shift register.
                   1962: 
                   1963: 
                   1964:     if ( cuda_is_header_transfer ) {
                   1965:         // There are more header bytes, write one out.
                   1966:                // Initially cuda_transfer_count is 1, so for most Cuda commands
                   1967:                // that means the ADB command itself, which contains Talk, Listen, etc.
                   1968:         // cuda_write_data(cuda_request->a_cmd.a_header[cuda_transfer_count++]);
                   1969:                *VIA1_shift = cuda_request->a_cmd.a_header[cuda_transfer_count++];
                   1970: 
                   1971:         // Toggle the handshake line.
                   1972:                // a_hcount is number of bytes in command packet
                   1973:         if ( cuda_transfer_count >= cuda_request->a_cmd.a_hcount ) {
                   1974:             cuda_is_header_transfer = FALSE;
                   1975:             cuda_transfer_count = 0;
                   1976:         }
                   1977: 
                   1978:         // cuda_toggle_byte_ack();
                   1979:        *VIA2_dataB ^= kCudaByteAcknowledgeMask; eieio();
                   1980: 
                   1981: 
                   1982:     } else if ( cuda_transfer_count < cuda_request->a_cmd.a_bcount ) {
                   1983: //WARNING... find out why a_bcount above is examined during Cuda Transmit?
                   1984: 
                   1985: 
                   1986:     // There are more command bytes, write one out and update the pointer
                   1987:         // cuda_write_data(cuda_request->a_cmd.a_buffer[cuda_transfer_count++]);
                   1988:                *VIA1_shift = cuda_request->a_cmd.a_buffer[cuda_transfer_count++];
                   1989: 
                   1990:         // Toggle the handshake line.
                   1991:         // cuda_toggle_byte_ack();
                   1992:        *VIA2_dataB ^= kCudaByteAcknowledgeMask; eieio();
                   1993:     } else {
                   1994:         //(void)cuda_read_data();
                   1995:                valcuda = *VIA1_shift; eieio();
                   1996:         // There is no more command bytes, terminate the send transaction.
                   1997:         // Cuda should send a expected attention interrupt soon.
                   1998: 
                   1999:         // cuda_neg_tip_and_byteack();
                   2000:                *VIA2_dataB |= kCudaNegateByteAcknowledge | kCudaNegateTransferInProgress;
                   2001:                eieio();
                   2002: 
                   2003:         // The next interrupt should be a expected attention interrupt.
                   2004: 
                   2005:         cuda_interrupt_state = CUDA_STATE_ATTN_EXPECTED;
                   2006: 
                   2007: /**** moved to cuda_idle() portion
                   2008:                // call back the ADB layer if entire transmission packet is complete.
                   2009:                if ( clientRequest->pmCallback != NULL ) {
                   2010:             clientRequest->pmCallback(clientRequest->pmId, clientRequest->pmRefNum, 0, NULL);
                   2011: 
                   2012:                }
                   2013: *****/
                   2014: 
                   2015:     }
                   2016: }
                   2017: 
                   2018: //
                   2019: //  cuda_expected_attention
                   2020: //  Executes at hardware interrupt level.
                   2021: //
                   2022: 
                   2023: - (void)cuda_expected_attention
                   2024: {
                   2025:        volatile unsigned char valcuda;  //dummy, unused
                   2026:     
                   2027: 
                   2028:        // Clear the pending interrupt by reading the shift register.
                   2029:        // This first byte is the "attention" byte and contains no
                   2030:        //    useful data, so ignore it.  Next byte should be response
                   2031:        //    packet TYPE.
                   2032:     //(void)cuda_read_data();
                   2033:        valcuda = *VIA1_shift; eieio();
                   2034: 
                   2035:     // Allow the VIA to settle directions.. else the possibility of
                   2036:     // data corruption.
                   2037:     tick_delay(cuda_state_transition_delay_ticks);
                   2038: 
                   2039:     if ( cuda_transaction_state ==  CUDA_TS_SYNC_RESPONSE) {
                   2040:         cuda_current_response = (adb_packet_t*)&cuda_request->a_reply;
                   2041:     } else {
                   2042:         cuda_unsolicited.a_hcount = 0;
                   2043:         cuda_unsolicited.a_bcount = 0;
                   2044:         cuda_unsolicited.a_bsize = sizeof(cuda_unsolicited.a_buffer);
                   2045:         cuda_current_response = &cuda_unsolicited;
                   2046:     }
                   2047: 
                   2048:     cuda_is_header_transfer = TRUE;
                   2049:     cuda_is_packet_type = TRUE;
                   2050:     cuda_transfer_count = 0;
                   2051: 
                   2052:     // Set the shift register direction to input.
                   2053:     // cuda_set_data_direction_to_input();
                   2054:        *VIA1_auxillaryControl &= kCudaSystemRecieve; eieio();
                   2055: 
                   2056:     // Start the response packet transaction.
                   2057:     // cuda_assert_transfer_in_progress();
                   2058:        *VIA2_dataB     &= kCudaAssertTransferInProgress; eieio();
                   2059: 
                   2060:     // The next interrupt should be a receive data interrupt.
                   2061:     cuda_interrupt_state = CUDA_STATE_RECEIVE_EXPECTED;
                   2062: }
                   2063: 
                   2064: //
                   2065: //  cuda_unexpected_attention
                   2066: //  Executes at hardware interrupt level.
                   2067: //
                   2068: 
                   2069: -(void) cuda_unexpected_attention
                   2070: {
                   2071:        volatile unsigned char valcuda;  //dummy, unused
                   2072: 
                   2073:     // Clear the pending interrupt by reading the shift register.
                   2074:        // This first byte is the "attention" byte and contains no
                   2075:        //    useful data, so ignore it.  Next byte should be response
                   2076:        //    packet TYPE.
                   2077:     //(void)cuda_read_data();
                   2078:        valcuda = *VIA1_shift; eieio();
                   2079: 
                   2080:     // Get ready for a unsolicited response.
                   2081: 
                   2082:     cuda_unsolicited.a_hcount = 0;
                   2083:     cuda_unsolicited.a_bcount = 0;
                   2084:     cuda_unsolicited.a_bsize = sizeof(cuda_unsolicited.a_buffer);
                   2085:        //Try to fix jumping bug
                   2086:        bzero( cuda_unsolicited.a_buffer, cuda_unsolicited.a_bsize);
                   2087: 
                   2088: 
                   2089:     cuda_current_response = &cuda_unsolicited;
                   2090: 
                   2091:     cuda_is_header_transfer = TRUE;
                   2092:     cuda_is_packet_type = TRUE;
                   2093:     cuda_transfer_count = 0;
                   2094: 
                   2095: 
                   2096:     // Start the response packet transaction, Transaction In Progress
                   2097:     // cuda_assert_transfer_in_progress();
                   2098:        *VIA2_dataB     &= kCudaAssertTransferInProgress; eieio();
                   2099: 
                   2100:     // The next interrupt should be a receive data interrupt and the next
                   2101:     // response should be an async response.
                   2102: 
                   2103:     cuda_interrupt_state = CUDA_STATE_RECEIVE_EXPECTED;
                   2104: 
                   2105:     cuda_transaction_state = CUDA_TS_ASYNC_RESPONSE;
                   2106: }
                   2107: 
                   2108: //
                   2109: //  cuda_receive_data
                   2110: //  Executes at hardware interrupt level.
                   2111: //
                   2112: 
                   2113: -(void) cuda_receive_data
                   2114: {
                   2115: 
                   2116:        // cuda_is_packet_type is set to TRUE when cuda_(+un)expected_attention() is called
                   2117:        // The first part will be called just to read the packet type 
                   2118:     if ( cuda_is_packet_type ) {
                   2119:         unsigned char packetType;
                   2120: 
                   2121:         //packetType = cuda_read_data();
                   2122:                packetType = *VIA1_shift; eieio();
                   2123:         cuda_current_response->a_header[cuda_transfer_count++] = packetType;
                   2124: 
                   2125:         if ( packetType == ADB_PACKET_ERROR) {
                   2126:             cuda_current_response->a_hcount = 4;
                   2127:         } else {
                   2128:             cuda_current_response->a_hcount = 3;
                   2129:         }
                   2130: 
                   2131:         cuda_is_packet_type = FALSE;
                   2132: 
                   2133:         // cuda_toggle_byte_ack();
                   2134:        *VIA2_dataB ^= kCudaByteAcknowledgeMask; eieio();
                   2135: 
                   2136:     } else if ( cuda_is_header_transfer ) {  //set TRUE by cuda_(+un)expected_attention
                   2137: 
                   2138:                //This should be the Response Packet ADB Status byte (2nd byte)
                   2139:         cuda_current_response->a_header[cuda_transfer_count++] =
                   2140:                                *VIA1_shift; eieio();
                   2141:                 // cuda_read_data();
                   2142: 
                   2143:         if (cuda_transfer_count >= cuda_current_response->a_hcount) {
                   2144:             cuda_is_header_transfer = FALSE;
                   2145:             cuda_transfer_count = 0;
                   2146:         }
                   2147: 
                   2148:         // cuda_toggle_byte_ack();
                   2149:        *VIA2_dataB ^= kCudaByteAcknowledgeMask; eieio();
                   2150: 
                   2151:     } else if ( cuda_transfer_count < cuda_current_response->a_bsize ) {
                   2152:         // Still room for more bytes. Get the byte and tell Cuda to continue.
                   2153:         // Toggle the handshake line, ByteAck, to acknowledge receive.
                   2154: 
                   2155:                // a_buffer[] is the actual buffer going back to ADB.M Callback
                   2156:         cuda_current_response->a_buffer[cuda_transfer_count] =
                   2157:                                *VIA1_shift; eieio();
                   2158:                 // cuda_read_data();
                   2159: 
                   2160:                if (bImmediate_buff_needed)  //just for getRealTimeClock 
                   2161:                {
                   2162:                        if ( return_buff_pointer)
                   2163:                        {
                   2164:                                *(return_buff_pointer + cuda_transfer_count) =
                   2165:                                cuda_current_response->a_buffer[cuda_transfer_count];
                   2166:  
                   2167: //kprintf("%x ", cuda_current_response->a_buffer[cuda_transfer_count]);
                   2168:                        }
                   2169:                }
                   2170: 
                   2171:                cuda_transfer_count++;
                   2172: 
                   2173:         // cuda_toggle_byte_ack();
                   2174:        *VIA2_dataB ^= kCudaByteAcknowledgeMask; eieio();
                   2175:     } else {
                   2176:         // Cuda is still sending data but the buffer is full.
                   2177:         // Normally should not get here.  The only exceptions are open ended
                   2178:         // request such as  PRAM read...  In any event time to exit.
                   2179: 
                   2180:                // a_bcount is the actual count going back to ADB.M Callback
                   2181:         cuda_current_response->a_bcount = cuda_transfer_count;
                   2182: 
                   2183:         // cuda_read_data();
                   2184:                if (*VIA1_shift); eieio();
                   2185: 
                   2186:                //So far no hits here on kernel bootup 3/20/98
                   2187: 
                   2188:         [self cuda_process_response];  //Rewritten by D.S.
                   2189:         // cuda_neg_tip_and_byteack();
                   2190:            *VIA2_dataB |= kCudaNegateByteAcknowledge | kCudaNegateTransferInProgress;
                   2191:            eieio();
                   2192:     }
                   2193: }
                   2194: 
                   2195: //
                   2196: //  cuda_receive_last_byte
                   2197: //  Executes at hardware interrupt level.
                   2198: //
                   2199: 
                   2200: -(void) cuda_receive_last_byte
                   2201: {
                   2202:        volatile unsigned char valcuda;  //dummy, unused
                   2203: 
                   2204: 
                   2205:     if ( cuda_is_header_transfer ) {
                   2206:         cuda_current_response->a_header[cuda_transfer_count++]  =
                   2207:                        *VIA1_shift; eieio();
                   2208:             // cuda_read_data();
                   2209: 
                   2210:         cuda_transfer_count = 0;
                   2211:     } else if ( cuda_transfer_count < cuda_current_response->a_bsize ) {
                   2212: 
                   2213:         cuda_current_response->a_buffer[cuda_transfer_count] =
                   2214:                        *VIA1_shift; eieio();
                   2215: 
                   2216:                //Added 1/13/98 A.W. 
                   2217:                if (bImmediate_buff_needed)  //just for getRealTimeClock 
                   2218:                {
                   2219:                        if ( return_buff_pointer)
                   2220:                        {
                   2221:                                *(return_buff_pointer + cuda_transfer_count) =
                   2222:                                cuda_current_response->a_buffer[cuda_transfer_count];
                   2223:                        }
                   2224:                }
                   2225:                cuda_transfer_count++;
                   2226: 
                   2227:             // cuda_read_data();
                   2228:     } else {
                   2229:         /* Overrun -- ignore data */
                   2230:         //(void) cuda_read_data();
                   2231:                valcuda = *VIA1_shift; eieio();
                   2232:     }
                   2233: 
                   2234:     cuda_current_response->a_bcount = cuda_transfer_count;
                   2235: 
                   2236: //SD: acknowledge before response so polled mode can work from inside the adb handler
                   2237: 
                   2238:     // cuda_neg_tip_and_byteack();
                   2239:     *VIA2_dataB |= kCudaNegateByteAcknowledge | kCudaNegateTransferInProgress;
                   2240:     eieio();
                   2241: if (p) kprintf("cuda.m: process response in LAST BYTE, count is %d\n", cuda_transfer_count);
                   2242:     [self cuda_process_response];  //Rewritten by D.S.
                   2243: }
                   2244: 
                   2245: /* 3/19/98 A.W. added to fix collision problems */
                   2246: - (void) cuda_queue:(CudaRequest *)cuda_req
                   2247: {
                   2248:        CudaMachMessage * toQueue;
                   2249:        IOReturn result;
                   2250: 
                   2251:        que_cuda_count++;  //for debugging only
                   2252:        //For collisions, queue up the incoming request from Rhapsody system
                   2253:        // and handle Cuda's urgent request first.
                   2254:     toQueue = (CudaMachMessage*)kalloc(sizeof(CudaMachMessage));
                   2255:     toQueue->msgHeader.msg_size = sizeof(CudaMachMessage);
                   2256:     toQueue->msgHeader.msg_local_port = [self interruptPort];
                   2257:        bcopy (cuda_req, &toQueue->msgBody, sizeof(CudaRequest));       // copy it
                   2258:        toQueue->msgBody.prev = queueTail;
                   2259:        toQueue->msgBody.next = NULL;
                   2260:        if ( queueTail != NULL ) {
                   2261:           queueTail->msgBody.next = toQueue;
                   2262:        }
                   2263:        else 
                   2264:        {
                   2265:                queueHead = toQueue;
                   2266:        }
                   2267:        queueTail = toQueue;
                   2268: }
                   2269: 
                   2270: //
                   2271: //  cuda_collision
                   2272: //  Executes at hardware interrupt level.
                   2273: //
                   2274: 
                   2275: -(void) cuda_collision
                   2276: {
                   2277:        volatile unsigned char valcuda;  //dummy, unused
                   2278: 
                   2279: 
                   2280:     // Clear the pending interrupt by reading the shift register.
                   2281:     //(void)cuda_read_data();
                   2282:        valcuda = *VIA1_shift; eieio();
                   2283: 
                   2284:     // Negate TIP to abort the send.  Cuda should send a second attention
                   2285:     // interrupt to acknowledge the abort cycle.
                   2286:     // cuda_neg_transfer_in_progress();
                   2287:     *VIA2_dataB |= kCudaNegateTransferInProgress; eieio();
                   2288: 
                   2289:     // The next interrupt should be an expected attention and the next
                   2290:     // response packet should be an async response.
                   2291: 
                   2292:     cuda_interrupt_state = CUDA_STATE_ATTN_EXPECTED;
                   2293:     cuda_transaction_state = CUDA_TS_ASYNC_RESPONSE;
                   2294: 
                   2295:     /* queue the request */
                   2296:     cuda_collided = cuda_request; //WARNING... unused now, don't use this variable
                   2297: #ifdef OMIT
                   2298:     cuda_request = NULL;
                   2299: #endif
                   2300:     cuda_is_header_transfer = FALSE;
                   2301:     cuda_transfer_count = 0;
                   2302: 
                   2303:        [self cuda_queue: cuda_request];
                   2304: }
                   2305: 
                   2306: //
                   2307: //  cuda_idle
                   2308: //  Executes at hardware interrupt level.
                   2309: //  A.W. WARNING... what if this state is reached without a client callback available?
                   2310: //             what happens with unsolicited cuda events?  Should they go to the ADBRegisterAutopoll
                   2311: //             function?
                   2312: //
                   2313: 
                   2314: -(void) cuda_idle
                   2315: {
                   2316:        volatile unsigned char valcuda;  //dummy, unused
                   2317: 
                   2318:     // Clear the pending interrupt by reading the shift register.
                   2319:     //(void)cuda_read_data();
                   2320:        valcuda = *VIA1_shift; eieio();
                   2321: 
                   2322:     // Set to the idle state.
                   2323:     cuda_interrupt_state = CUDA_STATE_IDLE;
                   2324: 
                   2325:     // See if there are any pending requests.  There may be a pending request
                   2326:     // if a collision has occured.  If so do the resend.
                   2327: 
                   2328:     //if (adb_polling)
                   2329:     //return;     /* Prevent recursion */
                   2330: 
                   2331:        //if collision then that has already been queued above, so all we do
                   2332:        // now is check for it.
                   2333:            
                   2334:        [self CheckRequestQueue];
                   2335: 
                   2336: }
                   2337: 
                   2338: 
                   2339: 
                   2340: -(void) cuda_error
                   2341: {
                   2342:        unsigned char valcuda;
                   2343: 
                   2344:     kprintf("\nCUDA:{Error %d}\n", cuda_transaction_state);
                   2345: 
                   2346:     switch (cuda_transaction_state) {
                   2347:     case    CUDA_STATE_IDLE:
                   2348:         // cuda_neg_tip_and_byteack();
                   2349:        *VIA2_dataB |= kCudaNegateByteAcknowledge | kCudaNegateTransferInProgress;
                   2350:        eieio();
                   2351:         break;
                   2352: 
                   2353:     case    CUDA_STATE_TRANSMIT_EXPECTED:
                   2354:         if (cuda_is_header_transfer && cuda_transfer_count <= 1) {
                   2355:             tick_delay(cuda_state_transition_delay_ticks);
                   2356:             // cuda_neg_transfer_in_progress();
                   2357:                *VIA2_dataB |= kCudaNegateTransferInProgress; eieio();
                   2358:             // cuda_set_data_direction_to_input();
                   2359:                        *VIA1_auxillaryControl &= kCudaSystemRecieve; eieio();
                   2360:             //panic ("CUDA - TODO FORCE COMMAND BACK UP!\n");
                   2361:         } else {
                   2362:             cuda_transaction_state = CUDA_STATE_ATTN_EXPECTED;
                   2363:             // cuda_neg_tip_and_byteack();
                   2364:            *VIA2_dataB |= kCudaNegateByteAcknowledge | kCudaNegateTransferInProgress;
                   2365:            eieio();
                   2366:         }
                   2367:         break;
                   2368: 
                   2369:     case    CUDA_STATE_ATTN_EXPECTED:
                   2370:         // cuda_assert_transfer_in_progress();
                   2371:                *VIA2_dataB     &= kCudaAssertTransferInProgress; eieio();
                   2372: 
                   2373:         tick_delay(cuda_state_transition_delay_ticks);
                   2374:         // cuda_set_data_direction_to_input();
                   2375:                *VIA1_auxillaryControl &= kCudaSystemRecieve; eieio();
                   2376:         // cuda_neg_transfer_in_progress();
                   2377:        *VIA2_dataB |= kCudaNegateTransferInProgress; eieio();
                   2378:         //panic("CUDA - TODO CHECK FOR TRANSACTION TYPE AND ERROR");
                   2379:         break;
                   2380: 
                   2381:     case    CUDA_STATE_RECEIVE_EXPECTED:
                   2382:         // cuda_neg_tip_and_byteack();
                   2383:            *VIA2_dataB |= kCudaNegateByteAcknowledge | kCudaNegateTransferInProgress;
                   2384:            eieio();
                   2385:         //panic("Cuda - todo check for transaction type and error");
                   2386:         break;
                   2387: 
                   2388:     default:
                   2389:         // cuda_set_data_direction_to_input();
                   2390:                *VIA1_auxillaryControl &= kCudaSystemRecieve; eieio();
                   2391:                valcuda = *VIA1_shift; eieio();  //Ray Montagne .a indicates this may be useful
                   2392:         // cuda_neg_tip_and_byteack();
                   2393:            *VIA2_dataB |= kCudaNegateByteAcknowledge | kCudaNegateTransferInProgress;
                   2394:            eieio();
                   2395:         break;
                   2396:     }
                   2397: }
                   2398: 
                   2399: -(void) poll_device
                   2400: {
                   2401:     CudaRequest   *next;
                   2402:     int interruptflag = *VIA1_interruptFlag & kCudaInterruptMask;
                   2403:     eieio();
                   2404: 
                   2405:     if(interruptflag) {
                   2406:        [self interruptOccurred];
                   2407:        if( cuda_interrupt_state == CUDA_STATE_IDLE) {
                   2408:                        [self CheckRequestQueue];
                   2409:        }
                   2410:     }
                   2411: }
                   2412: 
                   2413: 
                   2414: @end

unix.superglobalmegacorp.com

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