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

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /**
        !            26:  * Copyright (c) 1994-1996 NeXT Software, Inc.  All rights reserved. 
        !            27:  * Copyright 1997 Apple Computer Inc. All Rights Reserved.
        !            28:  * @author  Martin Minow    mailto:[email protected]
        !            29:  * @revision   1997.02.18  Initial conversion from AMDPCSCSIDriver sources.
        !            30:  *
        !            31:  * Apple96SCSI.h - "Main" public methods for the 53C96 PCI SCSI interface.
        !            32:  * Apple96SCSI is closely based on Doug Mitchell's AMD 53C974/79C974 driver.
        !            33:  *
        !            34:  * Hmm, these methods are probably common to all SCSI implementations.
        !            35:  *
        !            36:  * Edit History
        !            37:  * 1998.07.29   MM     Disable logRegisters on command timeout.
        !            38:  * 1997.02.13  MM              Initial conversion from AMDPCSCSIDriver sources. 
        !            39:  * 1997.11.12  MM      Added support for scatter-gather lists.
        !            40:  */
        !            41: #import "Apple96SCSI.h"
        !            42: #import "Apple96SCSIPrivate.h"
        !            43: #import "Apple96CurioPrivate.h"
        !            44: #import "Apple96CurioPublic.h"
        !            45: #import "Apple96CurioDBDMA.h"
        !            46: #import "Apple96Hardware.h"
        !            47: #import "Apple96HWPrivate.h"
        !            48: #import "Apple96ISR.h"
        !            49: #import "bringup.h"
        !            50: #import <mach/message.h>
        !            51: #import <driverkit/generalFuncs.h>
        !            52: #import <driverkit/interruptMsg.h>
        !            53: #import <driverkit/align.h>
        !            54: #import <driverkit/kernelDriver.h>
        !            55: #import <kernserv/prototypes.h>
        !            56: #import <driverkit/IOSimpleMemoryDescriptor.h>
        !            57: /* string.h defines bzero */
        !            58: #import <string.h>
        !            59: 
        !            60: 
        !            61: @implementation Apple96_SCSI
        !            62: 
        !            63: /*
        !            64:  * Create and initialize one instance of Apple96_SCSI. The work is done by
        !            65:  * architecture- and chip-specific modules. 
        !            66:  */
        !            67: + (Boolean)            probe   : deviceDescription
        !            68: {
        !            69:                Apple96_SCSI            *inst = [self alloc];
        !            70:                Boolean                         result;
        !            71: 
        !            72:                ENTRY("Spr probe");
        !            73:                MakeTimestampRecord(512);               /* TBS: contitionally compile */
        !            74:                /*
        !            75:                 * Perform device-specific initialization -- free the instance
        !            76:                 * on failure.
        !            77:                 */
        !            78:                if ([inst hardwareInitialization : deviceDescription] == nil) {
        !            79:                        result = NO;
        !            80:                }
        !            81:                else {
        !            82:                        result = YES;
        !            83:                }
        !            84:                RESULT(result);
        !            85:                return (result);
        !            86: }
        !            87: 
        !            88: - free
        !            89: {
        !            90:                CommandBuffer           cmdBuf;
        !            91:                
        !            92:                ENTRY("Sfr free");
        !            93:                /*
        !            94:                 * First kill the I/O thread if running. 
        !            95:                 */
        !            96:                if (gFlagIOThreadRunning) {
        !            97:                        cmdBuf.op = kCommandAbortRequest;
        !            98:                        cmdBuf.scsiReq = NULL;
        !            99:                        [self executeCmdBuf:&cmdBuf];
        !           100:                }       
        !           101:                if (gIncomingCommandLock != NULL) {
        !           102:                        [gIncomingCommandLock free];
        !           103:                }
        !           104:                [self dbdmaTerminate];  /* Free up DBDMA memory */
        !           105:                EXIT();
        !           106:                return [super free];
        !           107: }
        !           108: 
        !           109: 
        !           110: /*
        !           111:  * Return required DMA alignment for current architecture.
        !           112:  */
        !           113: - (void)getDMAAlignment : (IODMAAlignment *)alignment;
        !           114: {
        !           115:     alignment->readStart   = DBDMA_ReadStartAlignment;
        !           116:     alignment->writeStart  = DBDMA_WriteStartAlignment;
        !           117:     alignment->readLength  = DBDMA_ReadLengthAlignment;
        !           118:     alignment->writeLength = DBDMA_WriteLengthAlignment;
        !           119: }
        !           120: 
        !           121: /*
        !           122:  * Statistics support.
        !           123:  */
        !           124: - (unsigned int) numQueueSamples
        !           125: {
        !           126:     return (gTotalCommands);
        !           127: }
        !           128: 
        !           129: 
        !           130: - (unsigned int) sumQueueLengths
        !           131: {
        !           132:     return (gQueueLenTotal);
        !           133: }
        !           134: 
        !           135: 
        !           136: - (unsigned int) maxQueueLength
        !           137: {
        !           138:     return (gMaxQueueLen);
        !           139: }
        !           140: 
        !           141: 
        !           142: - (void)resetStats
        !           143: {
        !           144:     gTotalCommands = 0;
        !           145:     gQueueLenTotal = 0;
        !           146:     gMaxQueueLen   = 0;
        !           147: }
        !           148: 
        !           149: /**
        !           150:  * Do a SCSI command, as specified by an IOSCSIRequest. All the 
        !           151:  * work is done by the I/O thread.
        !           152:  * @param   scsiReq    The request to execute
        !           153:  * @param   buffer     The data buffer to transfer to/from, if any
        !           154:  * @param   client     The data buffer owner task (for VM munging) 
        !           155:  *
        !           156:  * This method is called from IOSCSIDevice
        !           157:  */
        !           158: - (sc_status_t) executeRequest
        !           159:                                        : (IOSCSIRequest *) scsiReq
        !           160:            buffer  : (void *) buffer 
        !           161:            client  : (vm_task_t) client
        !           162: {
        !           163:        IOMemoryDescriptor  *mem = NULL;
        !           164:        sc_status_t     scsiStatus = SR_IOST_GOOD;  /* Fool compiler */
        !           165: 
        !           166:        ENTRY("Ser executeRequest");
        !           167:        /*
        !           168:         * Create a simple I/O memory descriptor for this client,
        !           169:         * then toss it to the common method.
        !           170:         */
        !           171:        if (buffer != NULL) {
        !           172:             mem = [[IOSimpleMemoryDescriptor alloc]
        !           173:                         initWithAddress : (void *) buffer
        !           174:                         length          : scsiReq->maxTransfer
        !           175:                     ];
        !           176:             [mem setClient : client];
        !           177:        }
        !           178:        scsiStatus = [self executeRequest
        !           179:                        : scsiReq
        !           180:                ioMemoryDescriptor : mem
        !           181:            ];
        !           182:        if (mem != NULL) {
        !           183:            [mem release];
        !           184:        }
        !           185:        RESULT(scsiReq->bytesTransferred);
        !           186:        return (scsiStatus);
        !           187: }
        !           188: 
        !           189: /*
        !           190:  * Execute a SCSI request using an IOMemoryDescriptor. This allows callers to
        !           191:  * provide (kernel-resident) logical scatter-gather lists. For compatibility
        !           192:  * with existing implementations, the low-level SCSI device driver must first
        !           193:  * ensure that executeRequest:ioMemoryDescriptor is supported by executing:
        !           194:  *  [controller respondsToSelector : executeRequest:ioMemoryDescriptor]
        !           195:  */
        !           196: - (sc_status_t) executeRequest
        !           197:                    : (IOSCSIRequest *) scsiReq 
        !           198:        ioMemoryDescriptor  : (IOMemoryDescriptor *) ioMemoryDescriptor 
        !           199: {
        !           200:                CommandBuffer           commandBuffer;
        !           201: 
        !           202:        ENTRY("Sem executeRequest (IOMemoryDescriptor)");
        !           203:                TAG("Ser", scsiReq->maxTransfer);
        !           204:                ddmExported("executeRequest: cmdBuf 0x%x maxTransfer 0x%x\n", 
        !           205:                        &commandBuffer,
        !           206:                        scsiReq->maxTransfer,
        !           207:                        3,4,5
        !           208:                );
        !           209:        if (ioMemoryDescriptor != NULL) {
        !           210:            [ioMemoryDescriptor setMaxSegmentCount : kMaxDMATransfer];
        !           211:            [ioMemoryDescriptor state : &commandBuffer.savedDataState];
        !           212:        }
        !           213:                bzero(&commandBuffer, sizeof(CommandBuffer));
        !           214:                commandBuffer.op                        = kCommandExecute;
        !           215:                commandBuffer.scsiReq           = scsiReq;
        !           216:        commandBuffer.mem       = ioMemoryDescriptor;
        !           217:        scsiReq->driverStatus       = SR_IOST_INVALID;  /* "In progress"    */
        !           218:                [self executeCmdBuf : &commandBuffer];
        !           219:                ddmExported("executeRequest: cmdBuf 0x%x complete; driverStatus %s\n", 
        !           220:                        &commandBuffer,
        !           221:                        IOFindNameForValue(scsiReq->driverStatus, IOScStatusStrings),
        !           222:                        3,4,5
        !           223:                );
        !           224:                RESULT(commandBuffer.scsiReq->bytesTransferred);
        !           225: #if TIMESTAMP_AT_IOCOMPLETE
        !           226:                [self logTimestamp : "I/O complete"];   /* After RETURN macro */
        !           227: #endif
        !           228:                return (commandBuffer.scsiReq->driverStatus);
        !           229: }
        !           230: 
        !           231: /**
        !           232:  *  Reset the SCSI bus. All the work is done by the I/O thread.
        !           233:  */
        !           234: - (sc_status_t) resetSCSIBus
        !           235: {
        !           236:                CommandBuffer           commandBuffer;
        !           237: 
        !           238:                ENTRY("Sre resetSCSIBus");
        !           239:                ddmExported("resetSCSIBus: cmdBuf 0x%x\n",
        !           240:                        &commandBuffer,
        !           241:                        2, 3,4,5
        !           242:                );
        !           243: 
        !           244:                commandBuffer.op                        = kCommandResetBus;
        !           245:                commandBuffer.scsiReq           = NULL;
        !           246: 
        !           247:                [self executeCmdBuf:&commandBuffer];
        !           248:                ddmExported("resetSCSIBus: cmdBuf 0x%x DONE\n",
        !           249:                        &commandBuffer,
        !           250:                        2, 3,4,5
        !           251:                );
        !           252:                RESULT(SR_IOST_GOOD);
        !           253:        return (SR_IOST_GOOD);          /* can not fail */
        !           254: }
        !           255: 
        !           256: /*
        !           257:  * The following 6 methods are all called from the I/O thread in IODirectDevice. 
        !           258:  */
        !           259:  
        !           260: /*
        !           261:  * Called from the I/O thread when it receives an interrupt message.
        !           262:  * Currently all work is done by chip-specific module; maybe we should 
        !           263:  * put this method there....
        !           264:  */
        !           265: - (void) interruptOccurred
        !           266: {
        !           267:                ENTRY("Sin interruptOccurred");
        !           268:                /*
        !           269:                 * Note: the following compiles because ENTRY ends with "do {"
        !           270:                 */
        !           271: #if DDM_DEBUG
        !           272:     {
        !           273:                /*
        !           274:                 * calculate interrupt service time if enabled.
        !           275:                 */
        !           276:                ns_time_t                       startTime;
        !           277:                unsigned                        elapsedNSec = 0;
        !           278: 
        !           279:                if (IODDMMasks[APPLE96_DDM_INDEX] & DDM_INTR) {
        !           280:                        IOGetTimestamp(&startTime);
        !           281:                }
        !           282:                ddmInterrupt("interruptOccurred: TOP\n", 1,2,3,4,5);
        !           283: #endif DDM_DEBUG
        !           284:                [self hardwareInterrupt];
        !           285: #if DDM_DEBUG
        !           286:                if (IODDMMasks[APPLE96_DDM_INDEX] & DDM_INTR) {
        !           287:                        ns_time_t       endTime;
        !           288:                        
        !           289:                        IOGetTimestamp(&endTime);
        !           290:                        elapsedNSec = (unsigned) (endTime - startTime);
        !           291:                }
        !           292:                ddmInterrupt("interruptOccurred: DONE; elapsed time %d.%03d us\n", 
        !           293:                        elapsedNSec / 1000U,
        !           294:                        elapsedNSec - ((elapsedNSec / 1000U) * 1000U),
        !           295:                        3,4,5
        !           296:                );
        !           297:     }
        !           298: #endif DDM_DEBUG
        !           299: //             [self enableInterrupt:0];
        !           300: //             [self enableAllInterrupts ];
        !           301:                EXIT();
        !           302: }
        !           303: 
        !           304: /*
        !           305:  * These three should not occur; they are here as error traps. All three are 
        !           306:  * called out from the I/O thread upon receipt of messages which it should
        !           307:  * not be seeing.
        !           308:  */
        !           309: - (void)interruptOccurredAt:(int)localNum
        !           310: {
        !           311:                IOLog("%s: interruptOccurredAt:%d\n", [self name], localNum);
        !           312: }
        !           313: 
        !           314: - (void)otherOccurred:(int)id
        !           315: {
        !           316:                IOLog("%s: otherOccurred:%d\n", [self name], id);
        !           317: }
        !           318: 
        !           319: - (void)receiveMsg
        !           320: {
        !           321:                IOLog("%s: receiveMsg\n", [self name]);
        !           322:                
        !           323:                /*
        !           324:                 * We have to let IODirectDevice take care of this (i.e., dequeue the
        !           325:                 * bogus message).
        !           326:                 */
        !           327:                [super receiveMsg];
        !           328: }
        !           329: 
        !           330: /*
        !           331:  * Used in -timeoutOccurred to determine if specified cmdBuf has timed out.
        !           332:  * Returns YES if timeout, else NO.
        !           333:  */
        !           334: static inline Boolean
        !           335: isCmdTimedOut(
        !           336:                CommandBuffer           *cmdBuf,
        !           337:                ns_time_t                       now
        !           338:     )
        !           339: {
        !           340:                IOSCSIRequest           *scsiReq;
        !           341:                ns_time_t                       expire;
        !           342:                Boolean                         result;
        !           343: 
        !           344:                ENTRY("Sit isCmdTimedOut");
        !           345:                scsiReq = cmdBuf->scsiReq;
        !           346:        expire  = cmdBuf->startTime + 
        !           347:                        (1000000000ULL * (unsigned long long) scsiReq->timeoutLength);
        !           348:                result = (now > expire);
        !           349: #if 0
        !           350:                if (result) {
        !           351:                        IOLog("%s: command timeout, target %d exceeded %d\n"
        !           352:                "drvApple96SCSI",   /* Can't use [self name] here */
        !           353:                                (int) scsiReq->target,
        !           354:                                (int) scsiReq->timeoutLength
        !           355:                        );
        !           356:                }
        !           357: #endif
        !           358:                RESULT(result);
        !           359:                return (result);
        !           360: }
        !           361: 
        !           362: /*
        !           363:  * Called from the I/O thread when it receives a timeout
        !           364:  * message. We send these messages ourself from serviceTimeoutInterrupt().
        !           365:  */
        !           366: - (void) timeoutOccurred
        !           367: {
        !           368:                ns_time_t                       now;
        !           369:                Boolean                         cmdTimedOut = NO;
        !           370:                CommandBuffer           *cmdBuf = gActiveCommand;
        !           371:                CommandBuffer           *nextCmdBuf;
        !           372: 
        !           373:                ENTRY("Sto timeoutOccurred");
        !           374:                ddmThread("timeoutOccurred: TOP\n", 1,2,3,4,5);
        !           375:                IOGetTimestamp(&now);
        !           376: #if 0 /* Disable. Part of Radar 2261237 */
        !           377:                [self logRegisters : TRUE  reason : "TimeoutOccurred"];
        !           378: #endif /* Disable. Part of Radar 2261237 */
        !           379: // ** ** **
        !           380: // ** ** ** Umm, is there a race-condition here? Can gActiveCommand be changed
        !           381: // ** ** ** out from under us by an interrupt or does the O.S. ensure that
        !           382: // ** ** ** these methods are single-threaded? Also, note that the bus
        !           383: // ** ** ** is likely to be stuck if there is a very slow device
        !           384: // ** ** ** such as a Format or Tape Rewind ongoing. This needs to be
        !           385: // ** ** ** updated to use the Copland (and/or SCSI Manager 4.3) algorithms.
        !           386: // ** ** **
        !           387:                /*
        !           388:                 *  Scan gActiveCommand and disconnectQ looking for tardy I/Os.
        !           389:                 */
        !           390:                if (cmdBuf != NULL) {
        !           391:                        if (isCmdTimedOut(cmdBuf, now)) {
        !           392:                                ddmThread("gActiveCommand TIMEOUT, cmd 0x%x\n", 
        !           393:                                        cmdBuf, 2,3,4,5);
        !           394:                                gActiveCommand = NULL;
        !           395:                                /*
        !           396:                                 * ** ** ** Umm, what about abort commands?
        !           397:                                 */
        !           398:                                ASSERT(cmdBuf->scsiReq != NULL);
        !           399:                [self ioComplete
        !           400:                            : cmdBuf
        !           401:                    finalStatus : SR_IOST_IOTO
        !           402:                ];
        !           403:                                cmdTimedOut = YES;
        !           404:                        }
        !           405:                }
        !           406:                /*
        !           407:                 * ** ** **
        !           408:                 * ** ** ** Umm, disconnected commands should timeout only
        !           409:                 * ** ** ** when the bus is idle. Otherwise, we can timeout
        !           410:                 * ** ** ** a command whose only fault is that other commands
        !           411:                 * ** ** ** saturated the bus.
        !           412:                 */
        !           413:                cmdBuf = (CommandBuffer *) queue_first(&gDisconnectedCommandQueue);
        !           414:                while (queue_end(&gDisconnectedCommandQueue, (queue_entry_t) cmdBuf) == 0) {
        !           415:                        if (isCmdTimedOut(cmdBuf, now)) {
        !           416:                                ddmThread("disconnected cmd timeout, cmd 0x%x\n",  cmdBuf, 2,3,4,5);
        !           417:                        
        !           418:                                /*
        !           419:                                 *  Remove cmdBuf from disconnectQ and complete it.
        !           420:                                 */
        !           421:                                nextCmdBuf = (CommandBuffer *) queue_next(&cmdBuf->link);
        !           422:                                queue_remove(&gDisconnectedCommandQueue, cmdBuf, CommandBuffer *, link);
        !           423:                                ASSERT(cmdBuf->scsiReq != NULL);
        !           424:                [self ioComplete
        !           425:                            : cmdBuf
        !           426:                    finalStatus : SR_IOST_IOTO
        !           427:                ];
        !           428:                                cmdBuf = nextCmdBuf;
        !           429:                                cmdTimedOut = YES;
        !           430:                        }
        !           431:                        else {
        !           432:                                cmdBuf = (CommandBuffer *) queue_next(&cmdBuf->link);
        !           433:                        }
        !           434:                }
        !           435:                /*
        !           436:                 * ** ** **
        !           437:                 * ** ** ** This is a really big hammer -- and will cause problems
        !           438:                 * ** ** ** with tape drives. It may also cause data loss.
        !           439:                 * ** ** **
        !           440:                 * Reset bus. This also completes all I/Os in disconnectQ with
        !           441:                 * status CS_Reset.
        !           442:                 */
        !           443:                if (cmdTimedOut) {
        !           444:                        [self logRegisters : TRUE reason : "Command timeout"];
        !           445:                        [self threadResetBus:NULL];
        !           446:                }
        !           447:                ddmThread("timeoutOccurred: DONE\n", 1,2,3,4,5);
        !           448:                EXIT();
        !           449: }
        !           450: 
        !           451: /*
        !           452:  * Process all commands in gIncomingCommandQueue. At most one of these will become
        !           453:  * gActiveCommand. The remainder of kCommandExecute commands go to gPendingCommandQueue. Other
        !           454:  * types of commands (such as bus reset) are executed immediately.
        !           455:  *
        !           456:  * This method is called from IODirectDevice.
        !           457:  * ** ** **
        !           458:  * ** ** ** Note that we don't have a concept of frozen queue.
        !           459:  * ** ** **
        !           460:  */
        !           461: - (void) commandRequestOccurred
        !           462: {
        !           463:                CommandBuffer           *cmdBuf;
        !           464:                CommandBuffer           *pendCmd;
        !           465: 
        !           466:                ENTRY("Sco commandRequestOccurred");
        !           467:                ddmThread("commandRequestOccurred: top\n", 1,2,3,4,5);
        !           468:                [gIncomingCommandLock lock];
        !           469:                while (queue_empty(&gIncomingCommandQueue) == FALSE) {
        !           470:                        cmdBuf = (CommandBuffer *) queue_first(&gIncomingCommandQueue);
        !           471:                        queue_remove(&gIncomingCommandQueue, cmdBuf, CommandBuffer *, link);
        !           472:                        [gIncomingCommandLock unlock];
        !           473:                        switch (cmdBuf->op) {
        !           474:                        case kCommandResetBus:
        !           475:                                /* 
        !           476:                                 * Note all active and disconnected commands will
        !           477:                                 * be terminted.
        !           478:                                 */
        !           479:                                [self threadResetBus : "Reset Command Received"];
        !           480:                [self ioComplete
        !           481:                            : cmdBuf
        !           482:                    finalStatus : SR_IOST_RESET
        !           483:                ];
        !           484:                                break;
        !           485:                        case kCommandAbortRequest:
        !           486:                                /*
        !           487:                                 * 1. Abort all active, pending, and disconnected
        !           488:                 *  commands.
        !           489:                                 * 2. Notify caller of completion.
        !           490:                                 * 3. Self-terminate.
        !           491:                                 */
        !           492:                [self abortAllCommands : SR_IOST_INT];
        !           493:                                pendCmd = (CommandBuffer *) queue_first(&gPendingCommandQueue);
        !           494:                                while (queue_end(&gPendingCommandQueue, (queue_entry_t) pendCmd) == FALSE) {
        !           495:                    [self ioComplete
        !           496:                                : pendCmd
        !           497:                        finalStatus : SR_IOST_INT
        !           498:                    ];
        !           499:                                        pendCmd = (CommandBuffer *) queue_next(&pendCmd->link);
        !           500:                                }
        !           501:                                [cmdBuf->cmdLock lock];
        !           502:                                [cmdBuf->cmdLock unlockWith:CMD_COMPLETE];
        !           503:                                ddmEntry("-Method: commandRequestOccurred", 1, 2, 3, 4, 5);
        !           504:                                IOExitThread();
        !           505:                                /* not reached */
        !           506:                        case kCommandExecute:
        !           507:                                [self threadExecuteRequest:cmdBuf];
        !           508:                                break;
        !           509:                                
        !           510:                        }
        !           511:                        [gIncomingCommandLock lock];
        !           512:                }
        !           513:                [gIncomingCommandLock unlock];
        !           514:                ddmThread("commandRequestOccurred: DONE\n", 1,2,3,4,5);
        !           515:                EXIT();
        !           516: }
        !           517: 
        !           518: 
        !           519: /*
        !           520:  * Power management methods. All we care about is power off, when we must 
        !           521:  * reset the SCSI bus due to the Compaq BIOS's lack of a SCSI reset, which
        !           522:  * causes a hang if we have set up targets for sync data transfer mode.
        !           523:  */
        !           524: - (IOReturn) getPowerState : (PMPowerState *) state_p
        !           525: {
        !           526:                ddmExported("getPowerState called\n", 1,2,3,4,5);
        !           527:                return IO_R_UNSUPPORTED;
        !           528: }
        !           529: 
        !           530: - (IOReturn) setPowerState : (PMPowerState) state
        !           531: {
        !           532: #ifdef DEBUG
        !           533:                IOLog("%s: received setPowerState: with %x\n", [self name],
        !           534:                        (unsigned)state);
        !           535: #endif DEBUG
        !           536:                if (state == PM_OFF) {
        !           537:                        // [self scsiReset];
        !           538:                        // ** ** ** TBS: [self powerDown];
        !           539:                        return IO_R_SUCCESS;
        !           540:                }
        !           541:                return IO_R_UNSUPPORTED;
        !           542: }
        !           543: 
        !           544: - (IOReturn) getPowerManagement : (PMPowerManagementState *) state_p
        !           545: {
        !           546:                ddmExported("getPowerManagement called\n", 1,2,3,4,5);
        !           547:                return IO_R_UNSUPPORTED;
        !           548: }
        !           549: 
        !           550: - (IOReturn) setPowerManagement : (PMPowerManagementState) state
        !           551: {
        !           552:                ddmExported("setPowerManagement called\n", 1,2,3,4,5);
        !           553:                return IO_R_UNSUPPORTED;
        !           554: }
        !           555: 
        !           556: #if APPLE96_ENABLE_GET_SET
        !           557: 
        !           558: /**
        !           559:  * Called by clients (and user-interaction) to configure the device.
        !           560:  */
        !           561: - (IOReturn) setIntValues
        !           562:                                                : (unsigned *)          parameterArray
        !           563:        forParameter    : (IOParameterName) parameterName
        !           564:        count           : (unsigned int)    count
        !           565: {
        !           566:                IOReturn                ioReturn = IO_R_INVALID_ARG;
        !           567:                
        !           568:                /* Radar 1670762 ENTRY("Ssi setIntValues"); */
        !           569:                ddmExported("setIntValues %s, count %u\n",
        !           570:                                parameterName,
        !           571:                                count,
        !           572:                                3, 4, 5
        !           573:                        );
        !           574:                if (strcmp(parameterName, APPLE96_AUTOSENSE) == 0) {
        !           575:                        if (count == 1) {
        !           576:                                gOptionAutoSenseEnable = (parameterArray[0] ? 1 : 0);
        !           577:                                IOLog("%s: autoSense %s\n", [self name], 
        !           578:                                        (gOptionAutoSenseEnable ? "Enabled" : "Disabled"));
        !           579:                                ioReturn = IO_R_SUCCESS;
        !           580:                        }
        !           581:                }
        !           582:                else if (strcmp(parameterName, APPLE96_ENABLE_DISCONNECT) == 0) { /* Radar 2005639 */
        !           583:                        if (count == 1) {
        !           584:                                gOptionDisconnectEnable = (parameterArray[0] ? 1 : 0);
        !           585:                                IOLog("%s: disconnect %s\n", [self name], 
        !           586:                                        (gOptionDisconnectEnable ? "Enabled" : "Disabled"));
        !           587:                                ioReturn = IO_R_SUCCESS;
        !           588:                        }
        !           589:                }
        !           590:                else if (strcmp(parameterName, APPLE96_CMD_QUEUE) == 0) {
        !           591:                        if (count == 1) {
        !           592:                                gOptionCmdQueueEnable = (parameterArray[0] ? 1 : 0);
        !           593:                                IOLog("%s: cmdQueue %s\n", [self name], 
        !           594:                                        (gOptionCmdQueueEnable ? "Enabled" : "Disabled"));
        !           595:                                ioReturn = IO_R_SUCCESS;
        !           596:                        }
        !           597:                }
        !           598:                else if (strcmp(parameterName, APPLE96_SYNC) == 0) {
        !           599:                        if (count == 1) {
        !           600:                                gOptionSyncModeEnable = (parameterArray[0] ? 1 : 0);
        !           601:                                IOLog("%s: syncMode %s\n", [self name], 
        !           602:                                        (gOptionSyncModeEnable ? "Enabled" : "Disabled"));
        !           603:                                ioReturn = IO_R_SUCCESS;
        !           604:                        }
        !           605:                }
        !           606:                else if (strcmp(parameterName, APPLE96_FAST_SCSI) == 0) {
        !           607:                        if (count == 1) {
        !           608:                                gOptionFastModeEnable = (parameterArray[0] ? 1 : 0);
        !           609:                                IOLog("%s: fastMode %s\n", [self name], 
        !           610:                                        (gOptionFastModeEnable ? "Enabled" : "Disabled"));
        !           611:                                ioReturn = IO_R_SUCCESS;
        !           612:                        }
        !           613:                }
        !           614:                else if (strcmp(parameterName, APPLE96_RESET_TARGETS) == 0) {
        !           615:                        if (count == 0) {
        !           616:                                int                                     target;
        !           617:                        
        !           618:                                /*
        !           619:                                 * Re-enable sync and command queueing. The
        !           620:                                 * disable bits persist after a reset.
        !           621:                                 */
        !           622:                                for (target = 0; target < SCSI_NTARGETS; target++) {
        !           623:                                        PerTargetData           *perTargetPtr;
        !           624:                
        !           625:                                        perTargetPtr = &gPerTargetData[target];
        !           626:                    perTargetPtr->cmdQueueDisable   = FALSE;
        !           627:                    perTargetPtr->selectATNDisable  = FALSE;
        !           628:                                        perTargetPtr->maxQueue                  = 0;
        !           629:                                }
        !           630:                                IOLog("%s: Per Target disable flags cleared\n", [self name]);
        !           631:                                ioReturn = IO_R_SUCCESS;
        !           632:                        }
        !           633:                }
        !           634:                else if (strcmp(parameterName, APPLE96_RESET_TIMESTAMP) == 0) {
        !           635:                        ResetTimestampIndex();
        !           636:                        ioReturn = IO_R_SUCCESS;
        !           637:                }
        !           638:                else if (strcmp(parameterName, APPLE96_ENABLE_TIMESTAMP) == 0) {
        !           639:                        EnableTimestamp(TRUE);
        !           640:                        ioReturn = IO_R_SUCCESS;
        !           641:                }
        !           642:                else if (strcmp(parameterName, APPLE96_DISABLE_TIMESTAMP) == 0) {
        !           643:                        EnableTimestamp(FALSE);
        !           644:                        ioReturn = IO_R_SUCCESS;
        !           645:                }
        !           646:                else if (strcmp(parameterName, APPLE96_PRESERVE_FIRST_TIMESTAMP) == 0) {
        !           647:                        PreserveTimestamp(TRUE);
        !           648:                        ioReturn = IO_R_SUCCESS;
        !           649:                }
        !           650:                else if (strcmp(parameterName, APPLE96_PRESERVE_LAST_TIMESTAMP) == 0) {
        !           651:                        PreserveTimestamp(FALSE);
        !           652:                        ioReturn = IO_R_SUCCESS;
        !           653:                }
        !           654:                else {
        !           655:                        ioReturn = [super setIntValues
        !           656:                                                                        : parameterArray
        !           657:                    forParameter    : parameterName
        !           658:                                        count                   : count
        !           659:                                ];
        !           660:                }
        !           661:                /* Radar 1670762 RESULT(ioReturn); */
        !           662:                return (ioReturn);
        !           663: }
        !           664: 
        !           665: /**
        !           666:  * Called by clients and user-interaction to retrieve information from
        !           667:  * the device. Note that non-privileged clients can call getIntValues
        !           668:  * and it may be used to *set* timestamp parameters.
        !           669:  */
        !           670: - (IOReturn) getIntValues
        !           671:                                                        : (unsigned *)          parameterArray
        !           672:        forParameter        : (IOParameterName) parameterName
        !           673:                count                           : (unsigned *)          count;          /* in/out       */
        !           674: {
        !           675:                IOReturn                        ioReturn = IO_R_INVALID_ARG;
        !           676:                
        !           677:                /* Radar 1670762 ENTRY("Sgi getIntValues"); */
        !           678:                if (strcmp(parameterName, APPLE96_AUTOSENSE) == 0) {
        !           679:                        if (*count == 1) {
        !           680:                                parameterArray[0] = gOptionAutoSenseEnable;
        !           681:                                ioReturn = IO_R_SUCCESS;
        !           682:                        }
        !           683:                }
        !           684:                else if (strcmp(parameterName, APPLE96_CMD_QUEUE) == 0) {
        !           685:                        if (*count == 1) {
        !           686:                                parameterArray[0] = gOptionCmdQueueEnable;
        !           687:                                ioReturn = IO_R_SUCCESS;
        !           688:                        }
        !           689:                }
        !           690:                else if (strcmp(parameterName, APPLE96_SYNC) == 0) {
        !           691:                        if (*count == 1) {
        !           692:                                parameterArray[0] = gOptionSyncModeEnable;
        !           693:                                ioReturn = IO_R_SUCCESS;
        !           694:                        }
        !           695:                }
        !           696:                else if (strcmp(parameterName, APPLE96_FAST_SCSI) == 0) {
        !           697:                        if (*count == 1) {
        !           698:                                parameterArray[0] = gOptionFastModeEnable;
        !           699:                                ioReturn = IO_R_SUCCESS;
        !           700:                        }
        !           701:                }
        !           702:                else if (strcmp(parameterName, APPLE96_ENABLE_DISCONNECT) == 0) { /* Radar 2005639 */
        !           703:                        if (*count == 1) {
        !           704:                                parameterArray[0] = gOptionDisconnectEnable;
        !           705:                                ioReturn = IO_R_SUCCESS;
        !           706:                        }
        !           707:                }
        !           708:                else if (strcmp(parameterName, APPLE_MAX_THREADS) == 0) { /* Radar 2005639 */
        !           709:                        if (*count == 1) {
        !           710:                                parameterArray[0] = MAX_CLIENT_THREADS;
        !           711:                                ioReturn = IO_R_SUCCESS;
        !           712:                        }
        !           713:                }
        !           714:                else if (strcmp(parameterName, APPLE96_RESET_TIMESTAMP) == 0) {
        !           715:                        ResetTimestampIndex();
        !           716:                        ioReturn = IO_R_SUCCESS;
        !           717:                }
        !           718:                else if (strcmp(parameterName, APPLE96_ENABLE_TIMESTAMP) == 0) {
        !           719:                        EnableTimestamp(TRUE);
        !           720:                        ioReturn = IO_R_SUCCESS;
        !           721:                }
        !           722:                else if (strcmp(parameterName, APPLE96_DISABLE_TIMESTAMP) == 0) {
        !           723:                        EnableTimestamp(FALSE);
        !           724:                        ioReturn = IO_R_SUCCESS;
        !           725:                }
        !           726:                else if (strcmp(parameterName, APPLE96_PRESERVE_FIRST_TIMESTAMP) == 0) {
        !           727:                        PreserveTimestamp(TRUE);
        !           728:                        ioReturn = IO_R_SUCCESS;
        !           729:                }
        !           730:                else if (strcmp(parameterName, APPLE96_PRESERVE_LAST_TIMESTAMP) == 0) {
        !           731:                        PreserveTimestamp(FALSE);
        !           732:                        ioReturn = IO_R_SUCCESS;
        !           733:                }
        !           734:                else if (strcmp(parameterName, APPLE96_STORE_TIMESTAMP) == 0) {
        !           735:                        /*
        !           736:                         * Count
        !           737:                         *              1: tag, <zero>, current time
        !           738:                         *              2: tag, value, current time
        !           739:                         *              4: tag, value, user's time
        !           740:                         */
        !           741:                        switch (*count) {
        !           742:                        case 1:
        !           743:                                StoreTimestamp(parameterArray[0], 0);
        !           744:                                ioReturn = IO_R_SUCCESS;
        !           745:                                break;
        !           746:                        case 2:
        !           747:                                StoreTimestamp(parameterArray[0], parameterArray[1]);
        !           748:                                ioReturn = IO_R_SUCCESS;
        !           749:                                break;
        !           750:                        case 4:
        !           751:                                StoreNSecTimestamp(
        !           752:                                        parameterArray[0],
        !           753:                                        parameterArray[1],
        !           754:                                        *((ns_time_t *) &parameterArray[2])
        !           755:                                );
        !           756:                                ioReturn = IO_R_SUCCESS;
        !           757:                                break;
        !           758:                        default:
        !           759:                                break;  /* Failure */
        !           760:                        }
        !           761:                }
        !           762:                else if (strcmp(parameterName, APPLE96_READ_TIMESTAMP) == 0) {
        !           763:                        /*
        !           764:                         * Read the timestamp array:
        !           765:                         *      parameterArray  -> result buffer (TimestampDataRecord vector)
        !           766:                         *      count                   -> maximum number of integers to return
        !           767:                         *                                      <- set to the actual number of integers returned.
        !           768:                         * Note that, because count is a number of integers, clients should
        !           769:                         * call this as follows:
        !           770:                         *              TimestampDataRecord             myTimestamps[123];
        !           771:                         *              unsigned                                count;
        !           772:                         *              count = sizeof (myTimestamps) / sizeof (unsigned);
        !           773:                         *              [scsiDevice getIntValues
        !           774:                         *                                              : (unsigned int *) myTimestamps
        !           775:                         *                      forParameter    : APPLE96_READ_TIMESTAMP
        !           776:                         *                      count                   : &count
        !           777:                         *              ];
        !           778:                         *              count = (count * sizeof (unsigned)) / sizeof (TimestampDataRecord);
        !           779:                         *              for (i = 0; i < count; i++) {
        !           780:                         *                      Process(myTimestamps[i]);
        !           781:                         *              }
        !           782:                         */
        !           783:                        unsigned        vectorSize = ((*count) * sizeof(unsigned))
        !           784:                                                                / sizeof (TimestampDataRecord);
        !           785:                        ReadTimestampVector((TimestampDataPtr) parameterArray, &vectorSize);
        !           786:                        *count = (vectorSize * sizeof (TimestampDataRecord))
        !           787:                                                                / sizeof (unsigned);
        !           788:                        ioReturn = IO_R_SUCCESS;
        !           789:                }
        !           790:                else {
        !           791:                        ioReturn = [super getIntValues : parameterArray
        !           792:                                forParameter : parameterName
        !           793:                                count : count];
        !           794:                }
        !           795:                /* RESULT(ioReturn); */
        !           796:                return (ioReturn);
        !           797: }                                      
        !           798: 
        !           799: 
        !           800: #endif /* APPLE96_ENABLE_GET_SET */
        !           801: 
        !           802: @end   /* Apple96_SCSI */
        !           803: 

unix.superglobalmegacorp.com

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