Annotation of kernel/bsd/dev/ppc/drvApple96_SCSI/Apple96HWPrivate.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:  * Apple96PCISCSI.m - Architecture-specific methods for Apple96 SCSI driver.
                     32:  *
                     33:  * Edit History
                     34:  * 1997.02.13  MM              Initial conversion from AMDPCSCSIDriver sources. 
                     35:  * 1997.07.31  MM              Radar 1670762: Correct transfer length for > 64K transfers.
                     36:  *                                             rewrote hardwareGetNextContiguousPhysicalTransferRange.
                     37:  *                                             This no longer combines adjacent physical pages, which
                     38:  *                                             greatly simplifies hardwareInitializeRequestCCL (which was
                     39:  *                                             also rewritten). Remove hard-wired logical page size values.
                     40:  */
                     41: #import "Apple96SCSI.h"
                     42: #import <driverkit/generalFuncs.h>
                     43: #import <driverkit/kernelDriver.h>
                     44: #import        <driverkit/align.h>
                     45: #import <kernserv/prototypes.h>
                     46: #import <mach/kern_return.h>
                     47: #import <mach/mach_interface.h>
                     48: #import "Apple96SCSIPrivate.h"
                     49: #import "Apple96HWPrivate.h"
                     50: #import "Apple96CurioDBDMA.h"
                     51: #import "Apple96CurioPrivate.h"
                     52: #import "bringup.h"
                     53: #import "Apple96Curio.h"
                     54: #import "MacSCSICommand.h"
                     55: /* bzero is defined in string.h */
                     56: #import <string.h>
                     57: 
                     58: enum {
                     59:        kCURIORegisterBase      = 0,
                     60:        kDBDMARegisterBase      = 1
                     61: };
                     62: 
                     63: /**
                     64:  * These are the hardware-specific methods.
                     65:  */
                     66: @implementation Apple96_SCSI(HardwarePrivate)
                     67: 
                     68: /**
                     69:  * Fetch the device's bus address and allocate one page
                     70:  * of memory for the channel command. (Strictly speaking, we don't
                     71:  * need an entire page, but we can use the rest of the page for
                     72:  * a permanent status log).
                     73:  *
                     74:  * @param      deviceDescription       Specify the device to initialize.
                     75:  * @return     IO_R_SUCCESS if successful, else an error status.
                     76:  */
                     77: - (IOReturn) hardwareAllocateHardwareAndChannelMemory
                     78:                                                : deviceDescription
                     79: {
                     80:                IOReturn                        ioReturn = IO_R_SUCCESS;
                     81:                enum {
                     82:                        kCurioRegisterBase      = 0,
                     83:                        kDBDMARegisterBase      = 1,
                     84:                        kNumberRegisters        = 2
                     85:                };
                     86:                                
                     87:                ENTRY("Hal hardwareAllocateHardwareAndChannelMemory");
                     88:                gSCSIPhysicalAddress    = 0;
                     89:                gSCSIRegisterLength             = 0;
                     90:                gSCSILogicalAddress             = NULL;
                     91:                gDBDMAPhysicalAddress   = 0;
                     92:                gDBDMARegisterLength    = 0;
                     93:                gDBDMALogicalAddress    = NULL;
                     94:                /*
                     95:                 * Set the default selection timeout to the MESH value (10 msec units).
                     96:                 */
                     97:        //      gSelectionTimeout               = 250 / 10;
                     98:                /*
                     99:                 * Retrieve the system-wide logical page size and define a mask that
                    100:                 * contains only the low-order bits. Part of Radar 1670762.
                    101:                 */
                    102:                gPageSize                               = page_size;
                    103:                gPageMask                               = gPageSize - 1;
                    104:                /*
                    105:                 * Allocate a page of wired-down memory in the kernel. Although
                    106:                 * Driver Kit provides a memory allocator, IOMalloc, it does
                    107:                 * not guarantee page alignment. Thus, we call the Mach kernel
                    108:                 * routine. According to the description of kalloc(), 4096 is
                    109:                 * the smallest amount of memory we can allocate. The channel
                    110:                 * command area will fit into the start of this area and the
                    111:                 * autosense area will be placed at the end.
                    112:                 */
                    113:                gChannelCommandAreaSize = gPageSize;
                    114:                gChannelCommandArea = (DBDMADescriptor *) kalloc(gChannelCommandAreaSize);
                    115:                if (gChannelCommandArea == NULL) {
                    116:            IOLog("%s: Cannot allocate channel command area %d bytes, fatal.\n",
                    117:                                [self name],
                    118:                                gChannelCommandAreaSize
                    119:                        );
                    120:                        ioReturn = IO_R_NO_MEMORY;
                    121:                }
                    122:                if (ioReturn == IO_R_SUCCESS) {
                    123:                        if (IOIsAligned(gChannelCommandArea, gPageSize) == 0) {
                    124:                IOLog("%s: Command area at %08x is not page-aligned.\n",
                    125:                                        [self name],
                    126:                                        (UInt32) gChannelCommandArea
                    127:                                );
                    128:                                ioReturn = IO_R_NO_MEMORY;
                    129:                        }
                    130:                }
                    131:                if (ioReturn == IO_R_SUCCESS) {
                    132: 
                    133:                        /*
                    134:                         * Curio-specific: use the high-end of the descriptor area for
                    135:                         * the bit bucket and autosense buffer.
                    136:                         */
                    137:                        UInt32                  autosenseSize;
                    138:                        
                    139:                        autosenseSize = kMaxAutosenseByteCount;
                    140:                        gAutosenseArea = (esense_reply_t *)
                    141:                                (((UInt32) gChannelCommandArea)
                    142:                                + gChannelCommandAreaSize
                    143:                                - autosenseSize);
                    144:                        /*
                    145:                         * Determine the number of DBDMA descriptors that fit in
                    146:                         * the channel command area.
                    147:                         */
                    148:                        gDBDMADescriptorMax = (gChannelCommandAreaSize - autosenseSize)
                    149:                                                                / sizeof (DBDMADescriptor);
                    150:                        /*
                    151:                         * Fetch the logical and physical addresses for the
                    152:                         * Curio and DBDMA chips.
                    153:                         */
                    154: #if 0
                    155:            do {
                    156:                IORange     *memoryRangeList;
                    157:                UInt32      numMemoryRanges;
                    158:                int     i;
                    159: 
                    160:                        memoryRangeList         = [deviceDescription memoryRangeList];
                    161:                        numMemoryRanges         = [deviceDescription numMemoryRanges];
                    162:                        for (i = 0; i < numMemoryRanges; i++) {
                    163:                    ddmDMA("%s: memory range[%d] %08x (%d)\n",
                    164:                                        [self name],
                    165:                                        i,
                    166:                                        memoryRangeList[i].start,
                    167:                                        memoryRangeList[i].size
                    168:                                );
                    169:                        }
                    170:                        if (numMemoryRanges != kNumberRegisters) {
                    171:                    ddmDMA("%s: Expect %d memory ranges, got %d. Fatal.\n",
                    172:                                        [self name],
                    173:                                        kNumberRegisters,
                    174:                                        numMemoryRanges
                    175:                                );
                    176:                                ioReturn = IO_R_INVALID;        /* This "can't happen"  */
                    177:                        }
                    178:            } while (0);
                    179: #endif
                    180:                }
                    181: #if 0
                    182:                if (ioReturn == IO_R_SUCCESS) {         
                    183:                        /*
                    184:                         * We know that the first range describes the SCSI chip,
                    185:                         * and the second range describes the DBDMA chip.
                    186:                         */
                    187:            gSCSIPhysicalAddress    = (PhysicalAddress) memoryRangeList[kCURIORegisterBase].start;
                    188:                        gSCSIRegisterLength             = memoryRangeList[kCURIORegisterBase].size;
                    189:            gDBDMAPhysicalAddress   = (PhysicalAddress) memoryRangeList[kDBDMARegisterBase].start;
                    190:            gDBDMARegisterLength    = memoryRangeList[kDBDMARegisterBase].size;
                    191:                        /*
                    192:                         * Weave together the logical and physical addresses.
                    193:                         * First, map the SCSI and DBDMA chips into our address space.
                    194:                         */
                    195:                        ioReturn = IOMapPhysicalIntoIOTask(
                    196:                                                (UInt32) gSCSIPhysicalAddress,
                    197:                                                gSCSIRegisterLength,
                    198:                                                (vm_offset_t *) &gSCSILogicalAddress
                    199:                                        );
                    200:                        if (ioReturn != IO_R_SUCCESS) {
                    201:                ddmDMA("%s: Mapping SCSI chip at %08x [%d] to virtual address:"
                    202:                                        " error %d (%s), fatal.\n",
                    203:                                        [self name],
                    204:                                        gSCSIPhysicalAddress,
                    205:                                        gSCSIRegisterLength,
                    206:                                        ioReturn,
                    207:                                        [self stringFromReturn:ioReturn]
                    208:                                );
                    209:                        }
                    210:                }
                    211:                if (ioReturn == IO_R_SUCCESS) {         
                    212:                        ioReturn = IOMapPhysicalIntoIOTask(
                    213:                                                (UInt32) gDBDMAPhysicalAddress,
                    214:                                                gDBDMARegisterLength,
                    215:                                                (vm_offset_t *) &gDBDMALogicalAddress
                    216:                                        );
                    217:                        if (ioReturn != IO_R_SUCCESS) {
                    218:                ddmDMA("%s: Mapping DBDMA at %08x [%d] to virtual address:"
                    219:                                        " error %d (%s), fatal.\n",
                    220:                                        [self name],
                    221:                                        gDBDMAPhysicalAddress,
                    222:                                        gDBDMARegisterLength,
                    223:                                        ioReturn,
                    224:                                        [self stringFromReturn:ioReturn]
                    225:                                );
                    226:                        }
                    227:                }
                    228: #else
                    229:                /*
                    230:                 * Temp (?) Use hard-wired addresses until the registry is complete.
                    231:                 */
                    232:                if (ioReturn == IO_R_SUCCESS) {         
                    233:            gSCSILogicalAddress     = (UInt8 *) PCI_ASC_BASE_PHYS;
                    234:            gSCSIPhysicalAddress    = (PhysicalAddress) PCI_ASC_BASE_PHYS;
                    235:            gSCSIRegisterLength = 0x100;
                    236:            gDBDMALogicalAddress    = (DBDMAChannelRegisters *) PCI_DMA_BASE_PHYS;
                    237:            gDBDMAPhysicalAddress   = (PhysicalAddress) PCI_DMA_BASE_PHYS;
                    238:            gDBDMARegisterLength    = 0x20;
                    239:                }
                    240: #endif
                    241:                if (ioReturn == IO_R_SUCCESS) {         
                    242:                        /*
                    243:                         * Ensure that the addresses are valid.
                    244:                         */
                    245: #if 0 /* probe_rb is not present (yet?) */
                    246:                        ASSERT(probe_rb((UInt8 *) gSCSILogicalAddress) == 0);
                    247:                        ASSERT(probe_rb((UInt8 *) gDBDMALogicalAddress) == 0);
                    248: #endif
                    249:                        /*
                    250:                         * Get the physical address corresponding the DBDMA channel area.
                    251:                         */
                    252:                        ioReturn = IOPhysicalFromVirtual(
                    253:                                                IOVmTaskSelf(),
                    254:                                                (vm_offset_t) gChannelCommandArea,
                    255:                                                (vm_offset_t *) &gDBDMAChannelAddress
                    256:                                        );
                    257:                        if (ioReturn != IO_R_SUCCESS) {
                    258:                IOLog("%s: Mapping channel at %08x to physical address: error %d (%s), fatal.\n",
                    259:                                        [self name],
                    260:                                        (UInt32) gChannelCommandArea,
                    261:                                        ioReturn,
                    262:                                        [self stringFromReturn:ioReturn]
                    263:                                );
                    264:                        }
                    265:                }
                    266:                if (ioReturn == IO_R_SUCCESS) {
                    267:                        gAutosenseAddress = gDBDMAChannelAddress
                    268:                                + (((UInt32) gAutosenseArea) - ((UInt32) gChannelCommandArea));
                    269:                        [self initializeChannelProgram];
                    270:                }
                    271:                /*
                    272:                 * What do we do on failure? Should we try to deallocate the stuff
                    273:                 * we created, or will the system do this for us?
                    274:                 */
                    275:                RESULT(ioReturn);
                    276:                return (ioReturn);
                    277: }
                    278: 
                    279: /**
                    280:  * Perform one-time-only channel command program initialization.
                    281:  */
                    282: - (void) initializeChannelProgram
                    283: {
                    284:                ENTRY("Hic initializeChanelProgram");
                    285:                /*
                    286:                 * Set the interrupt, branch, and wait DBDMA registers.
                    287:                 * Caution: the following MESH interrupt register bits are
                    288:                 * reverse polarity and are in a different position.
                    289:                 * The pattern is: 0x00MM00VV, where MM is a mask byte
                    290:                 * and VV is a value byte to match.
                    291:                 *      0x80    means NO errors                 (kMeshIntrError)
                    292:                 *      0x40    means NO exceptions             (kMeshIntrException)
                    293:                 *      0x20    means NO command done   (kMeshIntrCmdDone)
                    294:                 *      Branch Select is used with BRANCH_FALSE
                    295:                 */
                    296:                DBDMASetInterruptSelect(0x00000000);    /* Never let DBDMA interrupt    */
                    297:                DBDMASetWaitSelect(0x00200020);                 /* Wait until command done              */
                    298:                DBDMASetBranchSelect(0x00000000);               /* Never branch on error                */
                    299:                EXIT();
                    300: }
                    301: 
                    302: /**
                    303:  * When a (legitimate) data phase starts, this method is called to configure
                    304:  * the DBDMA Channel Command list. Autosense is simple (as we "cannot" be
                    305:  * called more than once), while ordinary data transfers are arbitrarily complex.
                    306:  */
                    307: - (IOReturn) hardwareInitializeCCL
                    308: {
                    309:                IOReturn                        ioReturn;
                    310:                
                    311:                ENTRY("Hcc hardwareInitializeCCL");
                    312:                ASSERT(gActiveCommand != NULL && gActiveCommand->scsiReq != NULL);
                    313:                /**
                    314:                 * First, make sure that the DBDMA chip is idle.
                    315:                 */
                    316:        DBDMAreset();
                    317:        DBDMAspinUntilIdle();
                    318:                if (gActiveCommand->flagIsAutosense) {
                    319:                        UInt32                          actualAutosenseTransferLength;
                    320:                        /*
                    321:                         * This should be provided by the client (and checked that it is
                    322:                         * less than or equal to kMaxAutosenseByteCount). Note that this
                    323:                         * sequence is duplicated in Apple96Curio.m.
                    324:                         */
                    325:                        actualAutosenseTransferLength = sizeof (esense_reply_t);
                    326:                        ASSERT(actualAutosenseTransferLength <= kMaxAutosenseByteCount);
                    327:                        ASSERT(actualAutosenseTransferLength <= 255);
                    328:                        bzero(gAutosenseArea, actualAutosenseTransferLength);
                    329:                        MakeCCDescriptor(
                    330:                                &gChannelCommandArea[0],
                    331:                                INPUT_LAST | actualAutosenseTransferLength,
                    332:                                (UInt32) gAutosenseAddress
                    333:                        );
                    334:                        MakeCCDescriptor(&gChannelCommandArea[1], STOP_CMD, 0);
                    335:                        flush_cache_v((vm_offset_t) gChannelCommandArea, sizeof (DBDMADescriptor) * 2);
                    336:                        gActiveCommand->thisTransferLength = actualAutosenseTransferLength;
                    337:                        ioReturn = IO_R_SUCCESS;
                    338:                }
                    339:                else {
                    340:                        ioReturn = [self hardwareInitializeRequestCCL];
                    341:                }
                    342:                RESULT(ioReturn);
                    343:                return (ioReturn);
                    344: }
                    345: 
                    346: /**
                    347:  * Initialize the data transfer channel command list for a normal SCSI command.
                    348:  * This is not an optimal implementation, but it simplifies maintaining a
                    349:  * common code base with the NuBus Curio/AMIC hardware interface.
                    350:  * Note that the last DBDMA command must be INPUT_LAST or OUTPUT_LAST to handle
                    351:  * synchronous transfer odd-byte disconnect. 
                    352:  *
                    353:  * Significantly revised for Radar 1670762.
                    354:  */
                    355: - (IOReturn) hardwareInitializeRequestCCL
                    356: {
                    357:                CommandBuffer           *cmdBuf;
                    358:                IOSCSIRequest           *scsiReq;
                    359:        DBDMADescriptor     *descriptorPtr;     /* -> the current data descriptor   */
                    360:        DBDMADescriptor     *descriptorMax;     /* -> beyond the last data descr.   */
                    361:                IOReturn                        ioReturn = IO_R_SUCCESS;
                    362:                UInt32                          dbdmaOp;                        /* Opcode for DBDMA request                     */
                    363:        unsigned int    rangeByteCount;
                    364:        unsigned int    actualRanges;
                    365:        unsigned int    i;
                    366: #define kMaxPhysicalRange   16
                    367:        PhysicalRange       range[kMaxPhysicalRange];
                    368:                
                    369:                ENTRY("Hir hardwareInitializeRequestCCL");
                    370:                ASSERT(gActiveCommand != NULL && gActiveCommand->scsiReq != NULL);
                    371:                cmdBuf = gActiveCommand;
                    372:                scsiReq = cmdBuf->scsiReq;
                    373:                ASSERT(scsiReq->target == gCurrentTarget && scsiReq->lun == gCurrentLUN);
                    374:                /*
                    375:                 * Select the correct DBDMA command for this command.
                    376:                 */
                    377:                if (scsiReq->read) {
                    378:                        dbdmaOp                         = INPUT_MORE;
                    379:                }
                    380:                else {
                    381:                        dbdmaOp                         = OUTPUT_MORE;
                    382:                }
                    383:                /*
                    384:                 * How many descriptors can we store (need some slop for the terminator commands).
                    385:                 * Get a pointer to the first free descriptor and the total number of bytes left
                    386:                 * to transfer in this I/O request.
                    387:                 */
                    388:                descriptorPtr                   = gChannelCommandArea;
                    389:                descriptorMax                   = &descriptorPtr[gDBDMADescriptorMax];
                    390:                /*
                    391:                 * cmdBuf->thisTransferLength will contain the actual number of bytes we
                    392:                 * intend to transfer in this DMA request, which is needed when DMA completes
                    393:                 * to recover the residual transfer length.
                    394:                 */
                    395:        cmdBuf->thisTransferLength  = 0;
                    396:        ddmDMA("Req CCL, start %8d, max size %8d\n",
                    397:                                cmdBuf->currentDataIndex,
                    398:                                scsiReq->maxTransfer - cmdBuf->currentDataIndex,
                    399:                                3, 4, 5
                    400:                        );
                    401: /* + Radar xxxxxx -- Use IOMemoryDescriptors */
                    402:        while (descriptorPtr < descriptorMax
                    403:            && cmdBuf->thisTransferLength < kMaxDMATransfer) {
                    404:            rangeByteCount = [cmdBuf->mem getPhysicalRanges
                    405:                                    : kMaxPhysicalRange
                    406:                    maxByteCount    : (kMaxDMATransfer - cmdBuf->thisTransferLength)
                    407:                    newPosition     : NULL
                    408:                    actualRanges    : &actualRanges
                    409:                    physicalRanges  : range
                    410:                ];
                    411: #if 0
                    412:            IOLog("rangeByteCount %d, actualRanges %d, range[0] = %08x, %d\n",
                    413:                rangeByteCount, actualRanges,
                    414:                (UInt32) range[0].address,
                    415:                range[0].length
                    416:                                        );
                    417: #endif
                    418:            if (rangeByteCount == 0) {
                    419:                break;
                    420:                                }
                    421:            for (i = 0; i < actualRanges; i++) {
                    422: #if 0
                    423:            IOLog("%d: %08x for %d\n",
                    424:                i, (UInt32) range[i].address, range[i].length);
                    425: #endif
                    426: #if 1
                    427:            if (range[i].length == 0) {
                    428:                IOLog("%d: %08x for %d\n",
                    429:                i, (UInt32) range[i].address, range[i].length);
                    430:                [self logIOMemoryDescriptor : "Bogus length"];
                    431:                MakeCCDescriptor(descriptorPtr + 1, STOP_CMD, 0);
                    432:                [self logChannelCommandArea : "Bogus length"];
                    433:                IOPanic("Bogus length\n");
                    434:                        }
                    435: #endif
                    436:                MakeCCDescriptor(descriptorPtr,
                    437:                    (dbdmaOp | range[i].length),
                    438:                    (unsigned int) range[i].address
                    439:                                );
                    440:            descriptorPtr++;
                    441:                        }
                    442:            cmdBuf->thisTransferLength += rangeByteCount;
                    443:                        }
                    444: /* - Radar xxxxxx -- Use IOMemoryDescriptors */
                    445:                if (descriptorPtr > gChannelCommandArea) {
                    446:                        /*
                    447:                         * We stored at least one descriptor. Change the last one so it
                    448:                         * is an INPUT_LAST or OUTPUT_LAST.
                    449:                         */
                    450:                        SetCCOperation(
                    451:                                &descriptorPtr[-1],
                    452:                                GetCCOperation(&descriptorPtr[-1]) ^ OUTPUT_LAST
                    453:                        );
                    454:                } /* Set "last operation" bit in the command */
                    455:                MakeCCDescriptor(descriptorPtr, STOP_CMD, 0);
                    456:                descriptorPtr++;
                    457:                ASSERT(descriptorPtr < &gChannelCommandArea[gDBDMADescriptorMax]);
                    458:                flush_cache_v(
                    459:                        (vm_offset_t) gChannelCommandArea,
                    460:                        ((UInt32) descriptorPtr) - ((UInt32) gChannelCommandArea)
                    461:                );
                    462: #if 0  // ddmDMA
                    463:        IOLog("DMA setup, %d descriptors: thisTransferLength %d\n",
                    464:                        descriptorPtr - gChannelCommandArea,
                    465:                        cmdBuf->thisTransferLength,
                    466:                        3, 4, 5
                    467:                );
                    468: #endif
                    469:                RESULT(ioReturn);
                    470:                return (ioReturn);
                    471: }
                    472: 
                    473: 
                    474: /**
                    475:  * Start a request after [self hardwareStart] has figured out what to do.
                    476:  */
                    477: - (void)    hardwareStartSCSIRequest
                    478: {
                    479:                register CommandBuffer  *cmdBuf;
                    480:                IOSCSIRequest                   *scsiReq;
                    481:                UInt8                                   selectCmd;
                    482: 
                    483:                ENTRY("Hsr hardwareStartSCSIRequest");
                    484:                ASSERT(gActiveCommand != NULL && gActiveCommand->scsiReq != NULL);
                    485:                cmdBuf                                  = gActiveCommand;
                    486:                scsiReq                                 = cmdBuf->scsiReq;
                    487:                ASSERT(scsiReq->target == gCurrentTarget && scsiReq->lun == gCurrentLUN);
                    488:                /*
                    489:                 * Flush the fifo, then load synchronous registers and the target bus ID
                    490:                 */
                    491:        CURIOflushFifo();
                    492:        CURIOsetDestinationID(scsiReq->target);
                    493:                /*
                    494:                 * Put the contents of the message buffer into the fifo. The Curio makes this
                    495:                 * slightly messy. The command depends on the number of message bytes. The
                    496:                 * "select ATN and stop" case only occurs when we negotiate synchronous transfers.
                    497:                 */
                    498:                switch (gMsgOutPtr - gMsgPutPtr) {
                    499:                case 0:                         /* Select, no ATN, send CDB             */
                    500:                        gLastMsgOut[0] = gLastMsgOut[1] = kScsiMsgNop;
                    501:                        selectCmd = cSlctNoAtn;
                    502:                        break;                                                  
                    503:        case 1:                 /* Select, ATN, 1 Msg, send CDB */
                    504:                        gLastMsgOut[0] = gMsgPutPtr[0];
                    505:                        gLastMsgOut[1] = kScsiMsgNop;
                    506:                        selectCmd = cSlctAtn;
                    507:                        break;
                    508:        case 3:                 /* Select, ATN, 3 Msg, send CDB */
                    509:                        gLastMsgOut[0] = gMsgPutPtr[0];
                    510:                        gLastMsgOut[1] = gMsgPutPtr[1];
                    511:                        selectCmd = cSlctAtn3;
                    512:                        break;
                    513:                default:                                /* Select, ATN, 1 Msg, stop             */
                    514:                        gLastMsgOut[0] = gMsgPutPtr[0];
                    515:                        gLastMsgOut[1] = kScsiMsgNop;
                    516:                        selectCmd = cSlctAtnStp;
                    517:                        break;
                    518:                }
                    519:                if ((gMsgOutPtr - gMsgPutPtr) > 3
                    520:                 || (cmdBuf->flagIsAutosense == FALSE
                    521:                  && (gMsgOutPtr - gMsgPutPtr) + gActiveCommand->cdbLength >= 16)) {
                    522:            CURIOputByteIntoFifo(*gMsgPutPtr++);
                    523:                        selectCmd = cSlctAtnStp;
                    524:                }
                    525:                else {
                    526:                        while (gMsgPutPtr < gMsgOutPtr) {
                    527:                CURIOputByteIntoFifo(*gMsgPutPtr++);
                    528:                        }
                    529:                }
                    530:                if (selectCmd != cSlctAtnStp) {
                    531:            CURIOputCommandIntoFifo();
                    532:        }   
                    533:                /* ** ** **
                    534:                 * ** ** ** Can a caller override the default timeout?
                    535:                 * ** ** **
                    536:                 */
                    537: //     CURIOsetSelectionTimeout(gSelectionTimeout);
                    538:                /*
                    539:                 * Initialize the finite state automaton and start the Curio.
                    540:                 */
                    541:                gBusState = SCS_SELECTING;
                    542:                gCurrentBusPhase = kBusPhaseBusFree;
                    543:        CURIOsetCommandRegister(selectCmd);
                    544:                EXIT();
                    545: }
                    546: 
                    547: - (void) clearChannelCommandResults
                    548: {
                    549:                ENTRY("Hcc clearChannelCommandResults");
                    550:                EXIT();
                    551: }
                    552: 
                    553: /**
                    554:  * Debug log channel command area
                    555:  */
                    556: - (void) logChannelCommandArea
                    557:                        : (const char *) reason
                    558: {
                    559: #if DEBUG
                    560:        DBDMADescriptor     *descriptorPtr;     /* -> the current data descriptor   */
                    561:        DBDMADescriptor     *descriptorMax;     /* -> beyond the last data descr.   */
                    562:                UInt32                          operation;
                    563:                UInt32                          address;
                    564:                UInt32                          cmdDep;
                    565:                UInt32                          result;
                    566:                UInt32                          status;
                    567:                const char                      *opName;
                    568:                const char                      *keyName;
                    569:        const char          *intName    = "";
                    570:        const char          *branchName = "";
                    571:        const char          *waitName   = "";
                    572:                Boolean                         first;
                    573:                
                    574:                ENTRY("Dlo logChannelCommandArea");
                    575:                status = DBDMAGetChannelStatus();
                    576:                if (reason != NULL) {
                    577:                        IOLog("%s: *** %s\n", [self name], reason);
                    578:                }
                    579:                IOLog("%s: *** DBDMA sts %08x, cmdPtr %08x,"
                    580:                        " branchSel %08x, byteCount %08x, ccl @ %08x\n",
                    581:                        [self name],
                    582:                        status,
                    583:                        DBDMAGetCommandPtr(),
                    584:                        (UInt32) DBDMAGetBranchSelect(),
                    585:                        (UInt32) DBDMAGetWaitSelect(),
                    586:                        (UInt32) gChannelCommandArea
                    587:                );
                    588:                if ((status & 0x00008000) != 0) {
                    589:                        IOLog("%s: *** status: run\n", [self name]);
                    590:                }
                    591:                if ((status & 0x00004000) != 0) {
                    592:                        IOLog("%s: *** status: pause\n", [self name]);
                    593:                }
                    594:                if ((status & 0x00002000) != 0) {
                    595:                        IOLog("%s: *** status: flush\n", [self name]);
                    596:                }
                    597:                if ((status & 0x00001000) != 0) {
                    598:                        IOLog("%s: *** status: wake\n", [self name]);
                    599:                }
                    600:                if ((status & 0x00000800) != 0) {
                    601:                        IOLog("%s: *** status: dead\n", [self name]);
                    602:                }
                    603:                if ((status & 0x00000400) != 0) {
                    604:                        IOLog("%s: *** status: active\n", [self name]);
                    605:                }
                    606:                if ((status & 0x000000100) != 0) {
                    607:                        IOLog("%s: *** status: bt\n", [self name]);
                    608:                }
                    609:                if ((status & 0xFFFF02FF) != 0) {
                    610:                        IOLog("%s: *** other status set\n", [self name]);
                    611:                }
                    612:                descriptorPtr                   = gChannelCommandArea;
                    613:                descriptorMax                   = &descriptorPtr[gDBDMADescriptorMax];
                    614:                for (; descriptorPtr < descriptorMax; descriptorPtr++) {
                    615:                        operation       = GetCCOperation(descriptorPtr);
                    616:                        address         = GetCCAddress(descriptorPtr);
                    617:                        cmdDep          = GetCCCmdDep(descriptorPtr);
                    618:                        result          = GetCCResult(descriptorPtr);
                    619:            IOLog("%s: *** dma[%2d]: op %08x, addr %08x, cmddep %08x, res %08x\n",
                    620:                                [self name],
                    621:                                descriptorPtr - gChannelCommandArea,
                    622:                                operation,
                    623:                                address,
                    624:                                cmdDep,
                    625:                                result
                    626:                        );
                    627:                        switch (operation & kdbdmaCmdMask) {
                    628:                        case OUTPUT_MORE:               opName = "Output More";         break;
                    629:                        case OUTPUT_LAST:               opName = "Output Last";         break;
                    630:                        case INPUT_MORE:                opName = "Input More";          break;
                    631:                        case INPUT_LAST:                opName = "Input Last";          break;
                    632:                        case STORE_QUAD:                opName = "Store Quad";          break;
                    633:                        case LOAD_QUAD:                 opName = "Load Quad";           break;
                    634:                        case NOP_CMD:                   opName = "NOP";                         break;
                    635:                        case STOP_CMD:                  opName = "Stop";                        break;
                    636:                        default:                                opName = "Op Unknown";          break;
                    637:                        }
                    638:                        switch (operation & kdbdmaKeyMask) {
                    639:                        case KEY_STREAM0:               keyName = "Stream 0";           break;
                    640:                        case KEY_STREAM1:               keyName = "Stream 1";           break;
                    641:                        case KEY_STREAM2:               keyName = "Stream 2";           break;
                    642:                        case KEY_STREAM3:               keyName = "Stream 3";           break;
                    643:                        case KEY_REGS:                  keyName = "Regs";                       break;
                    644:                        case KEY_SYSTEM:                keyName = "System";                     break;
                    645:                        case KEY_DEVICE:                keyName = "System";                     break;
                    646:                        default:                                keyName = "Unknown";            break;
                    647:                        }
                    648:                        switch (operation & kdbdmaIMask) {
                    649:                        case kIntNever:                 intName = "never";                      break;
                    650:                        case kIntIfTrue:                intName = "if True";            break;
                    651:                        case kIntIfFalse:               intName = "if False";           break;
                    652:            case kIntAlways:        intName = "always";         break;
                    653:                        }
                    654:                        switch (operation & kdbdmaBMask) {
                    655:                        case kBranchNever:              branchName = "never";           break;
                    656:                        case kBranchIfTrue:             branchName = "if True";         break;
                    657:            case kBranchIfFalse:    branchName = "if False";    break;
                    658:                        case kBranchAlways:             branchName      = "always";             break;
                    659:                        }
                    660:                        switch (operation & kdbdmaWMask) {
                    661:                        case kWaitNever:                waitName = "never";                     break;
                    662:                        case kWaitIfTrue:               waitName = "if True";           break;
                    663:                        case kWaitIfFalse:              waitName = "if False";          break;
                    664:                        case kWaitAlways:               waitName = "always";            break;
                    665:                        }
                    666:                        IOLog("%s: ***    [%2d]: op %s, key %s, int %s, branch %s, wait %s, count %d,"
                    667:                                " residual %d, status %04x",
                    668:                                [self name],
                    669:                                descriptorPtr - gChannelCommandArea,
                    670:                                opName,
                    671:                                keyName,
                    672:                                intName,
                    673:                                branchName,
                    674:                                waitName,
                    675:                                (operation & kdbdmaReqCountMask),
                    676:                                result & kdbdmaResCountMask,
                    677:                                (result & kdbdmaXferStatusMask) >> 16
                    678:                        );
                    679:                        first = TRUE;
                    680:                        if ((result & kdbdmaXferStatusMask) == 0) {
                    681:                                IOLog(" (no status)\n");
                    682:                        }
                    683:                        else {
                    684:                                if ((result & kXferStatusRun) != 0) {
                    685:                                        IOLog(": Run");
                    686:                                        result &= ~kXferStatusRun;
                    687:                                        first = FALSE;
                    688:                                }
                    689:                                if ((result & kXferStatusPause) != 0) {
                    690:                                        IOLog("%s Pause", (first) ? ":" : ",");
                    691:                                        result &= kXferStatusPause;
                    692:                                        first = FALSE;
                    693:                                }
                    694:                                if ((result & kXferStatusFlush) != 0) {
                    695:                                        IOLog("%s Flush", (first) ? ":" : ",");
                    696:                                        result &= kXferStatusFlush;
                    697:                                        first = FALSE;
                    698:                                }
                    699:                                if ((result & kXferStatusWake) != 0) {
                    700:                                        IOLog("%s Wake", (first) ? ":" : ",");
                    701:                                        result &= kXferStatusWake;
                    702:                                        first = FALSE;
                    703:                                }
                    704:                                if ((result & kXferStatusDead) != 0) {
                    705:                                        IOLog("%s Dead", (first) ? ":" : ",");
                    706:                                        result &= kXferStatusDead;
                    707:                                        first = FALSE;
                    708:                                }
                    709:                                if ((result & kXferStatusActive) != 0) {
                    710:                                        IOLog("%s Active", (first) ? ":" : ",");
                    711:                                        result &= kXferStatusActive;
                    712:                                        first = FALSE;
                    713:                                }
                    714:                                if ((result & kXferStatusBt) != 0) {
                    715:                                        IOLog("%s Branch True", (first) ? ":" : ",");
                    716:                                        result &= kXferStatusBt;
                    717:                                        first = FALSE;
                    718:                                }
                    719:                                if (result != 0) {
                    720:                                        IOLog("%s Other", (first) ? ":" : ",");
                    721:                                }
                    722:                                IOLog("\n");
                    723:                        }
                    724:                        if ((operation & kdbdmaCmdMask) == STOP_CMD || operation == 0) {
                    725:                                break;
                    726:                        }
                    727:                }
                    728:                EXIT();
                    729: #endif /* DEBUG */
                    730: }
                    731: 
                    732: - (void)           logIOMemoryDescriptor
                    733:            : (const char *) info
                    734: {
                    735: #if DEBUG
                    736:     const char *intro  = " \"";
                    737:     const char *outro  = "\"";
                    738:     IOMemoryDescriptorState    state;
                    739: 
                    740:     if (gActiveCommand != NULL && gActiveCommand->mem != NULL) {
                    741:        [gActiveCommand->mem state : &state];
                    742:        if (info == NULL || info[0] == '\0') {
                    743:        info = intro = outro = "";
                    744:        }
                    745:        IOLog("IOMemoryDescriptor%s%s%s: %d offset in %d, %d maxSeg\n",
                    746:            intro, info, outro,
                    747:            [gActiveCommand->mem currentOffset],
                    748:            [gActiveCommand->mem totalByteCount],
                    749:            [gActiveCommand->mem maxSegmentCount]
                    750:        );
                    751:        IOLog("IOMemoryDescriptor%s%s%s: range %d, logical %d in %d, physical %d in %d\n",
                    752:            intro, info, outro,
                    753:            state.rangeIndex,
                    754:            state.logicalOffset,
                    755:            state.ioRange.size,
                    756:            state.physicalOffset,
                    757:            state.physical.length
                    758:        );
                    759:     }
                    760:     else {
                    761:        IOLog("Null IOMemoryDescriptor\n");
                    762:     }
                    763: #endif /* DEBUG */
                    764: }
                    765: 
                    766: 
                    767: @end /* Apple96_SCSI(HardwarePrivate) */
                    768: 

unix.superglobalmegacorp.com

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