Annotation of kernel/bsd/dev/ppc/drvApple96_SCSI/Apple96SCSI.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:  * 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.