Annotation of kernel/bsd/dev/ppc/drvApple96_SCSI/Apple96Hardware.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.13      Initial conversion from AMDPCSCSIDriver sources.
                     30:  *
                     31:  * Set tabs every 4 characters.
                     32:  *
                     33:  * AppleMeshHardware.m - Architecture-specific methods for Apple96 SCSI driver.
                     34:  *
                     35:  * Edit History
                     36:  * 1997.02.13  MM              Initial conversion from AMDPCSCSIDriver sources. 
                     37:  */
                     38: #import "Apple96SCSI.h"
                     39: #import "Apple96SCSIPrivate.h"
                     40: #import "Apple96Hardware.h"
                     41: #import "Apple96HWPrivate.h"
                     42: #import "Apple96ConfigKeys.h"
                     43: #import "Apple96Curio.h"
                     44: #import "Apple96CurioPublic.h"
                     45: #import "MacSCSICommand.h"
                     46: #import "bringup.h"
                     47: #import <driverkit/generalFuncs.h>
                     48: #import <driverkit/kernelDriver.h>
                     49: #import        <driverkit/align.h>
                     50: #import <bsd/dev/scsireg.h>
                     51: // #import <mach/mach.h>
                     52: // #import <mach/mach_error.h>
                     53: #import <mach/kern_return.h>
                     54: #import <kernserv/prototypes.h>
                     55: 
                     56: static int             getConfigParam(
                     57:        id                  configTable,
                     58:        const char          *paramName
                     59:     );
                     60: static unsigned int    GetSCSICommandLength(
                     61:        const cdb_t         *cdbPtr,
                     62:        unsigned int        defaultLength
                     63:     );
                     64: 
                     65: 
                     66: /**
                     67:  * These are the hardware-specific methods that are not explicitly
                     68:  * tied to Mesh and DBDMA.
                     69:  */
                     70: 
                     71: @implementation Apple96_SCSI(Hardware)
                     72: 
                     73: /**
                     74:  * Perform architecture-specific initialization: fetch the device's
                     75:  * bus address and interrupt port number. Also, allocate one page
                     76:  * of memory for the channel command. (Strictly speaking, we don't
                     77:  * need an entire page, but we can use the rest of the page for
                     78:  * a permanent status log).
                     79:  *
                     80:  * @param      deviceDescription       Specify the device to initialize.
                     81:  * @return     self                    [self free] if failure.
                     82:  */
                     83: - hardwareInitialization
                     84:                : deviceDescription
                     85: {
                     86:        IOReturn        ioReturn        = IO_R_SUCCESS;
                     87:        id              result          = self;
                     88:        kern_return_t   kernelReturn;
                     89:        UInt8           lun;
                     90:        id              configTable;
                     91:        const char      *configValue;
                     92:        UInt8           deviceNumber;
                     93:        UInt8           functionNumber;
                     94:        UInt8           busNumber;
                     95:                
                     96:        ENTRY("Hhi hardwareInitialization");
                     97:        ddmInit("%s: hardwareInitialization\n",
                     98:                "Apple96SCSI",
                     99:                2,3,4,5
                    100:        );
                    101:        configTable = [deviceDescription configTable];
                    102:        ASSERT(configTable != NULL);
                    103:        configValue = [configTable valueForStringKey: "Bus Type"];
                    104:        if (configValue == NULL) {
                    105:            IOLog("%s: No bus type in configuration table\n",
                    106:                        "Apple96SCSI"
                    107:                );
                    108:            ioReturn = IO_R_NO_DEVICE;
                    109:        }
                    110:        ddmInit("Bus type: \"%s\"\n", configValue, 2, 3, 4, 5);
                    111:        if (configValue == NULL || strcmp(configValue, "PPC") != 0) {
                    112:            IOLog("%s: Unsupported bus type \"%s\" in configuration table\n",
                    113:                        "Apple96SCSI",
                    114:                        configValue ? configValue :"null"
                    115:                );
                    116:            ioReturn = IO_R_NO_DEVICE;
                    117:        }
                    118:        if (ioReturn == IO_R_SUCCESS) {
                    119: #if 0 // ** ** ** Need correct definition ** ** **
                    120:            ioReturn = [deviceDescription getPCIDevice
                    121:                                : &deviceNumber
                    122:                function        : &functionNumber
                    123:                bus             : &busNumber];
                    124: #else
                    125:            deviceNumber = 00;
                    126:            functionNumber = 00;
                    127:            busNumber = 00;
                    128:            kernelReturn = 0;
                    129: #endif
                    130:            if (ioReturn != IO_R_SUCCESS) {
                    131:                IOLog("%s: Can't get PCI device information: %s\n",
                    132:                            "Apple96SCSI",
                    133:                            [self stringFromReturn : ioReturn]
                    134:                    );
                    135:            }
                    136:        }
                    137:        if (ioReturn == IO_R_SUCCESS) {
                    138: #if 0
                    139:            IOLog("%s: Hardware device found at"
                    140:                        " bus %u, device %u, function %u, interrupt %u\n",
                    141:                        "Apple96SCSI",
                    142:                        busNumber,
                    143:                        deviceNumber,
                    144:                        functionNumber,
                    145:                        0
                    146: //                     [deviceDescription interrupt]
                    147:            );
                    148: #endif
                    149:        }
                    150:        if (configValue != NULL) {
                    151:            [configTable freeString : configValue];
                    152:            configValue = NULL;
                    153:        }
                    154:        if (ioReturn == IO_R_SUCCESS) {
                    155:            ioReturn = [self hardwareAllocateHardwareAndChannelMemory : deviceDescription];
                    156:        }
                    157:        if (ioReturn == IO_R_SUCCESS) {
                    158:            /*
                    159:             * Initialize gPerTargetData[] and the dbdma channel area.
                    160:             */
                    161:            [self initializePerTargetData];
                    162:            /*
                    163:             * All of the addresses are established. Check that the hardware
                    164:             * is present and working.
                    165:             */
                    166:            ioReturn = [self hardwareChipSelfTest];
                    167:        }
                    168:        if (ioReturn == IO_R_SUCCESS) {
                    169:            /*
                    170:             * Tell the superclass to initialize our I/O thread. After this,
                    171:             * we should be able to execute SCSI requests.
                    172:             */
                    173:            if ([super initFromDeviceDescription:deviceDescription] == NULL) {
                    174:                IOLog("%s: Host Adaptor was not initialized. Fatal\n",
                    175:                            "Apple96SCSI"
                    176:                    );
                    177:                ioReturn = IO_R_NO_DEVICE;
                    178:            }
                    179:        }
                    180:        if (ioReturn == IO_R_SUCCESS) {
                    181:            ddmInit("Init: I/O thread running\n", 1, 2, 3, 4, 5);
                    182:            gFlagIOThreadRunning = 1;
                    183:            /*
                    184:             * Initialize local variables. Note that activeArray and 
                    185:             * perTarget arrays are zeroed by objc runtime.
                    186:             */
                    187:            queue_init(&gDisconnectedCommandQueue);
                    188:            queue_init(&gIncomingCommandQueue);
                    189:            queue_init(&gPendingCommandQueue);
                    190:            gIncomingCommandLock = [[NXLock alloc] init];
                    191:            gActiveCommand = NULL;
                    192:            [self resetStats];
                    193:            gOptionDisconnectEnable     = ENABLE_DISCONNECT;
                    194:            gOptionCmdQueueEnable       = ENABLE_TAGGED_QUEUEING;
                    195:            gNextQueueTag               = QUEUE_TAG_NONTAGGED + 1;
                    196:            gInitiatorID                = kInitiatorIDDefault;
                    197:            /*
                    198:             * Initiator bus ID as a bitmask for selection.
                    199:             */
                    200:            gInitiatorIDMask            = (1 << gInitiatorID);
                    201:            /*
                    202:             * Reserve the initiator ID for all LUNs.
                    203:             */
                    204:            for (lun = 0; lun < SCSI_NLUNS; lun++) {
                    205:                [self reserveTarget
                    206:                                        : gInitiatorID 
                    207:                        lun             : lun
                    208:                        forOwner        : self
                    209:                    ];
                    210:            }
                    211:            /*
                    212:             * get tagged command queueing, sync mode, fast mode enables from
                    213:             * configTable.
                    214:             */
                    215: #ifdef CRAP    /* this requires "inspector" support:   */
                    216:            gOptionCmdQueueEnable = getConfigParam(configTable, CMD_QUEUE_ENABLE);
                    217: #endif /* CRAP */
                    218:            /*
                    219:             * Note: the external bus on PCI Mac's do not support synchronous
                    220:             * and/or fast modes. This code should be modified to read the
                    221:             * chip version id and configure sync/fast accordingly.
                    222:             */
                    223: #if 0  /* Enable for 8100 internal bus */
                    224:            gOptionSyncModeEnable = getConfigParam(configTable, SYNC_ENABLE);
                    225:            gOptionFastModeEnable = getConfigParam(configTable, FAST_ENABLE);
                    226: #else
                    227:            gOptionSyncModeEnable = 0;
                    228:            gOptionFastModeEnable = 0;
                    229: #endif
                    230:            gOptionExtendTiming   = getConfigParam(configTable, EXTENDED_TIMING);
                    231:            gOptionAutoSenseEnable = AUTO_SENSE_ENABLE; // from bringup.h
                    232:            /*
                    233:             * Get internal version of interruptPort; set the port queue 
                    234:             * length to the maximum size. It is not clear if we want
                    235:             * to do this.
                    236:             */
                    237:            gKernelInterruptPort = IOConvertPort(
                    238:                [self interruptPort],
                    239:                IO_KernelIOTask,
                    240:                IO_Kernel
                    241:            );
                    242: #if 0 // ** ** ** Need correct header file ** ** **
                    243:            kernelReturn = port_set_backlog(
                    244:                task_self(),
                    245:                [self interruptPort],
                    246:                PORT_BACKLOG_MAX
                    247:            );
                    248:            if (kernelReturn != KERN_SUCCESS) {
                    249:                IOLog("%s: warning, port_set_backlog error %d (%s)\n",
                    250:                        [self name],
                    251:                        kernelReturn,
                    252:                        mach_error_string(kernelReturn)
                    253:                    );
                    254:            }
                    255: #endif
                    256:            /*
                    257:             * Initialize the chip and reset the bus.
                    258:             */
                    259:            ioReturn = [self hardwareReset : TRUE       reason : NULL];
                    260: 
                    261:        }
                    262:        if (ioReturn == IO_R_SUCCESS) {
                    263:            /*
                    264:             * OK, we're ready to roll.
                    265:             */
                    266:            [self enableInterrupt:0];
                    267: //         [self enableAllInterrupts ];
                    268:            [self registerDevice];
                    269:        }
                    270:        else {
                    271:            /*
                    272:             * Do we need to free the locks and similar?
                    273:             */
                    274:            [self free];
                    275:            result = NULL;
                    276:        }
                    277:        RESULT(result);
                    278:        return (result);
                    279: }
                    280: 
                    281: /**
                    282:  * Initialize sync mode to async for all targets at start and
                    283:  * after bus reset.
                    284:  */
                    285: - (void)    initializePerTargetData
                    286: {
                    287:        UInt8               target;
                    288: 
                    289:        ENTRY("His initializeTargetSyncMode");
                    290:        for (target = 0; target < SCSI_NTARGETS; target++) {
                    291:            [self renegotiateSyncMode : target];
                    292:            gPerTargetData[ target ].inquiry_7 = 0;
                    293:        }
                    294:        EXIT();
                    295: }
                    296: 
                    297: /**
                    298:  * Initialize the synchronous data transfer state for a target.
                    299:  */
                    300: - (void)    renegotiateSyncMode
                    301:                        : (UInt8) target
                    302: {
                    303:        ENTRY("Hrs renegotiateSyncMode");
                    304:        EXIT();
                    305: }
                    306: 
                    307: /**
                    308:  * Reusable CURIO init function. This includes a SCSI reset.
                    309:  * Handling of ioComplete of active and disconnected commands must be done
                    310:  * elsewhere. Returns IO_R_SUCCESS if successful. This is called
                    311:  * from a Task thread. It will disable and re-enable interrupts.
                    312:  * Reason is for error logging.
                    313:  */
                    314: - (IOReturn) hardwareReset
                    315:                    : (Boolean) resetSCSIBus
                    316:            reason  : (const char *) reason
                    317: {
                    318:        ENTRY("HHr hardwareReset");
                    319:        if (reason != NULL) {
                    320:            IOLog("%s: Bus Reset (%s)\n",
                    321:                [self name],
                    322:                reason
                    323:            );
                    324:        }
                    325:        /*
                    326:         * First of all, reset the hardware.
                    327:         */
                    328:        [self curioHardwareReset : resetSCSIBus     reason : reason];
                    329:        /*
                    330:         * Kill all disconnected, pending, and incoming I/O requests.
                    331:         */
                    332:        [self abortAllCommands : SR_IOST_RESET];
                    333:        RESULT(IO_R_SUCCESS);
                    334:        return (IO_R_SUCCESS);  
                    335: }
                    336: 
                    337: 
                    338: /*
                    339:  * Start a SCSI transaction for the specified command. ActiveCmd must be 
                    340:  * NULL. A return of kHardwareStartRejected indicates that caller may try
                    341:  * again with another command; kHardwareStartBusy indicates a condition
                    342:  * other than (activeCmd != NULL) which prevents the processing of the command.
                    343:  */
                    344: - (HardwareStartResult) hardwareStart
                    345:                        : (CommandBuffer *) cmdBuf
                    346: {   
                    347:        IOSCSIRequest       *scsiReq;
                    348:        HardwareStartResult result                      = kHardwareStartOK;
                    349:        cdb_t                   *cdbp;
                    350:        Boolean                 okToDisconnect  = gOptionDisconnectEnable;
                    351: //     Boolean                 okToDisconnect  = TRUE;
                    352:        Boolean                 okToQueue               = gOptionCmdQueueEnable;
                    353:        UInt8                   msgByte;
                    354:        
                    355:        ENTRY("Hst hardwareStart");
                    356:        /*
                    357:         * We do not have a current command here.
                    358:         */
                    359:        ASSERT(cmdBuf != NULL && cmdBuf->scsiReq != NULL);
                    360:        scsiReq = cmdBuf->scsiReq;
                    361:        cdbp = &scsiReq->cdb;
                    362:        ddmChip("hardwareStart[%d.%d] cmdBuf = 0x%x opcode %s\n",
                    363:            scsiReq->target,
                    364:            scsiReq->lun,
                    365:            cmdBuf, 
                    366:            IOFindNameForValue(cdbp->cdb_opcode, IOSCSIOpcodeStrings),
                    367:            5);
                    368:        cmdBuf->cdbLength = GetSCSICommandLength(cdbp, scsiReq->cdbLength);
                    369:        if (cmdBuf->cdbLength == 0) {
                    370:            /*
                    371:             * Failure: we can't determine the length of this command.
                    372:             */
                    373:            [self ioComplete
                    374:                                : cmdBuf
                    375:                finalStatus     : SR_IOST_CMDREJ
                    376:            ];
                    377:            ddmChip("hardwareStart rejected: invalid cdb length\n", 1, 2, 3, 4, 5);
                    378:                    result = kHardwareStartRejected;
                    379:        }
                    380:        if (result == kHardwareStartOK) {
                    381:            /*
                    382:             * Peek at the control byte (the last byte in the command).
                    383:             */
                    384:            msgByte = ((UInt8 *) cdbp)[cmdBuf->cdbLength - 1];
                    385:            if ((msgByte & CTRL_LINKFLAG) != CTRL_NOLINK) {
                    386:                /*
                    387:                 * Failure: we don't support linked commands.
                    388:                 */
                    389:                [self ioComplete
                    390:                                        : cmdBuf
                    391:                        finalStatus     : SR_IOST_CMDREJ
                    392:                ];
                    393:                ddmChip("hardwareStart rejected: linked command\n", 1, 2, 3, 4, 5);
                    394:                result = kHardwareStartRejected;
                    395:            }
                    396:        }
                    397:        if (result == kHardwareStartOK) {
                    398:            /*
                    399:             * Autosense always renegotiates synchronous transfer mode.
                    400:             * This is necessary as the target might have been reset
                    401:             * or hit with a power-cycle.
                    402:             */
                    403:            if (cmdBuf->flagIsAutosense) {
                    404:                        [self renegotiateSyncMode : gCurrentTarget];
                    405:                        okToDisconnect = FALSE;
                    406:            }
                    407:            else {
                    408:                /*
                    409:                 * This is a real command. Setup the user data
                    410:                 * pointers and counters and build a SCSI request
                    411:                 * channel command list.
                    412:                 *
                    413:                 * First, peek at the command for some special cases.
                    414:                 */
                    415:                cmdBuf->queueTag = QUEUE_TAG_NONTAGGED; /* No tag just yet  */
                    416:                switch (cdbp->cdb_opcode) {
                    417:                case kScsiCmdInquiry:
                    418:                    /*
                    419:                     * The first command SCSIDisk sends us is an Inquiry
                    420:                     * command. This never gets retried, so avoid a possible 
                    421:                     * reject of a command queue tag. Avoid this hack if
                    422:                     * there are any other commands outstanding for this
                    423:                     * target/lun.
                    424:                     */
                    425:                    if (gActiveArray[scsiReq->target][scsiReq->lun] == 0) {
                    426:                        scsiReq->cmdQueueDisable = TRUE;
                    427:                    }
                    428:                    okToDisconnect = FALSE;
                    429:                    break;
                    430:                case kScsiCmdRequestSense:
                    431:                    /*
                    432:                     * Always force sync renegotiation on any Request Sense to 
                    433:                     * catch independent target power cycles.
                    434:                     * (Synch renegotiation needed should be set after all
                    435:                     * target-detected errors -- fix needed in MessageIn).
                    436:                     * Sense is always issued with disconnect disabled to
                    437:                     * maintain T/L/Q nexus.
                    438:                     *
                    439:                     * Watch it: request sense from a client is incompatible
                    440:                     * with tagged queuing.
                    441:                     */
                    442:                    [self renegotiateSyncMode : gCurrentTarget];
                    443:                    okToDisconnect      = FALSE;
                    444:                    break;
                    445:     
                    446:                case kScsiCmdTestUnitReady:
                    447:                case kScsiCmdReadCapacity:
                    448:                    okToDisconnect = FALSE;
                    449:                    break;
                    450:                }
                    451:            }
                    452: 
                    453:            if ( scsiReq->disconnect == FALSE )         /* If this req doesn't want */
                    454:                        okToDisconnect = FALSE;                         /* it, clear disconnect.    */
                    455: 
                    456:                okToQueue       &= okToDisconnect
                    457:                                        && (scsiReq->cmdQueueDisable == FALSE)
                    458:                                        && (gPerTargetData[ scsiReq->target ].inquiry_7 & 0x02);
                    459: 
                    460:            cmdBuf->flagActive              = 0;        /* Init flags for this command  */
                    461:            /*
                    462:             * Make sure that the chip is stable before we try to start
                    463:             * a request.
                    464:             */
                    465:            /*
                    466:             * Currently, the only expected reason we return kHardwareStartBusy
                    467:             * is if we have a reselect pending.
                    468:             * ** ** ** I don't think this can happen ** ** **
                    469:             */
                    470:            if (gFlagBusBusy) {
                    471:                queue_enter(&gPendingCommandQueue, cmdBuf, CommandBuffer *, link);
                    472:                ddmChip("hardwareStart deferred: bus busy\n", 1, 2, 3, 4, 5);
                    473:                result = kHardwareStartBusy;
                    474:            }
                    475:        }
                    476:        if (result == kHardwareStartOK) {
                    477:            if (gActiveCommand != NULL) {
                    478:                /*
                    479:                 * This should never happen. It ensures that there are
                    480:                 * no race conditions that reselect us between the time
                    481:                 * threadExecuteRequest looked at gActiveCommand and the
                    482:                 * time we disabled interrupts.
                    483:                 */
                    484:                queue_enter(&gPendingCommandQueue, cmdBuf, CommandBuffer *, link);
                    485:                ddmChip("hardwareStart deferred: there is an active command\n", 1, 2, 3, 4, 5);
                    486:                result = kHardwareStartBusy;
                    487:            }
                    488:        }
                    489:        if (result == kHardwareStartOK) {
                    490:            /*
                    491:             * Activate this command - if we fail later, we'll de-activate it.
                    492:             */
                    493: #if SERIOUS_DEBUGGING
                    494:            /*
                    495:             * If we're reading, preset the buffer to a known data.
                    496:             */
                    497:            if (cmdBuf->scsiReq != NULL
                    498:             && cmdBuf->scsiReq->read
                    499:             && cmdBuf->buffer != NULL
                    500:             && (((UInt32) cmdBuf->buffer) & 0x03) == 0) {
                    501:                int             i;
                    502:                UInt32          *ptr = (UInt32 *) cmdBuf->buffer;
                    503:                for (i = 0; i < cmdBuf->scsiReq->maxTransfer; i += sizeof (UInt32)) {
                    504:                    *ptr++ = 0xDEADBEEF;
                    505:                }
                    506:            }
                    507: #endif /* SERIOUS_DEBUGGING */
                    508: #if SERIOUS_DEBUGGING || LOG_COMMAND_AND_RESULT
                    509:            [self logCommand
                    510:                        : cmdBuf
                    511:                logMemory   : FALSE
                    512:                reason  : "Command at commandStart"
                    513:            ];
                    514: #endif /* SERIOUS_DEBUGGING || LOG_COMMAND_AND_RESULT */
                    515:            ASSERT(gActiveCommand == NULL);
                    516:            [self activateCommand : cmdBuf];
                    517:            ASSERT(scsiReq->target == gCurrentTarget && scsiReq->lun == gCurrentLUN);
                    518:            /* MESH only: [self clearChannelCommandResults];    */
                    519:            /*
                    520:             * Reset the message out buffer pointers.
                    521:             */
                    522:            gMsgOutPtr = gMsgOutBuffer;
                    523:            gMsgPutPtr = gMsgOutBuffer;
                    524:            msgByte = kScsiMsgIdentify | scsiReq->lun;
                    525:            if (okToDisconnect)
                    526:                msgByte |= kScsiMsgEnableDisconnectMask;
                    527:            *gMsgOutPtr++ = msgByte;
                    528:            /*
                    529:             * According to the SCSI Spec, the tag command immediately
                    530:             * follows the selection.
                    531:             */
                    532:            /*
                    533:             * Note that autosense is issued on the current tag.
                    534:             * The command was initialized with QUEUE_TAG_NONTAGGED.
                    535:             */
                    536:                /***** Driver Kit supports only simple queue tags.      *****/
                    537:            if ( okToQueue ) {
                    538:                                /* Avoid using tag QUEUE_TAG_NONTAGGED (zero).  */
                    539:                        cmdBuf->queueTag = gNextQueueTag;
                    540:                        if (++gNextQueueTag == QUEUE_TAG_NONTAGGED) {
                    541:                                gNextQueueTag++;
                    542:                        }
                    543:                        *gMsgOutPtr++   = kScsiMsgSimpleQueueTag;
                    544:                        *gMsgOutPtr++   = cmdBuf->queueTag;
                    545:            }
                    546:            if (cmdBuf->flagIsAutosense == 0) {
                    547:                cmdBuf->currentDataIndex    = 0;
                    548:                cmdBuf->savedDataIndex      = 0;
                    549:                if (gActiveCommand->mem != NULL) {
                    550:                    [gActiveCommand->mem setPosition : 0];  /* Needed?  */
                    551:                }
                    552:                scsiReq->driverStatus       = SR_IOST_INVALID;
                    553:                scsiReq->totalTime          = 0ULL;
                    554:                scsiReq->latentTime         = 0ULL;
                    555:            }
                    556:            [self hardwareStartSCSIRequest];
                    557:            IOGetTimestamp(&cmdBuf->startTime);
                    558:        }
                    559:        RESULT(result);
                    560:        return (result);
                    561: }
                    562: 
                    563: 
                    564: @end /* Apple96_SCSI(Hardware) */
                    565: 
                    566: 
                    567: 
                    568: /*
                    569:  * Obtain a YES/NO type parameter from the config table.
                    570:  * @param   configTable The table to examine.
                    571:  * @param   paramName  The parameter to look for.
                    572:  * @result  Zero if missing from the table or the table value is
                    573:  *     not YES. One if present in the table and the table
                    574:  *     value is YES.
                    575:  */
                    576: static int                  getConfigParam(
                    577:        id                      configTable,
                    578:        const char              *paramName
                    579:     )
                    580: {
                    581:        const char              *value;
                    582:        int                     result = 0; // default if not present in table
                    583:        
                    584:        ENTRY("Hgc getConfigParam");
                    585:        value = [configTable valueForStringKey:paramName];
                    586:        if (value != NULL) {
                    587:            if (strcmp(value, "YES") == 0) {
                    588:                result = 1;
                    589:            }
                    590:            [configTable freeString:value];
                    591:        }
                    592:        RESULT(result);
                    593:        return (result);
                    594: }
                    595: 
                    596: static unsigned int
                    597: GetSCSICommandLength(
                    598:        const cdb_t             *cdbPtr,
                    599:        unsigned int            defaultLength
                    600:     )
                    601: {
                    602:        unsigned int            result;
                    603:        
                    604:        /*
                    605:         * Warning: don't use sizeof here - the compiler rounds the
                    606:         * value up to the next word boundary.
                    607:         */
                    608:        switch (((UInt8 *) cdbPtr)[0] & 0xE0) {
                    609:        case (0 << 5):
                    610:            result = 6;
                    611:            break;
                    612:        case (1 << 5):
                    613:        case (2 << 5):
                    614:            result = 10;
                    615:            break;
                    616:        case (5 << 5):
                    617:            result = 12;
                    618:            break;
                    619:        case (6 << 5):
                    620:            result = (defaultLength != 0) ? defaultLength : 6;
                    621:            break;
                    622:        case (7 << 5):
                    623:            result = (defaultLength != 0) ? defaultLength : 10;
                    624:            break;
                    625:        default:
                    626:            result = 0;
                    627:            break;
                    628:        }
                    629:        return (result);
                    630: }

unix.superglobalmegacorp.com

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