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

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /**
        !            26:  * Copyright (c) 1994-1996 NeXT Software, Inc. All rights reserved. 
        !            27:  * Copyright 1997 Apple Computer Inc. All Rights Reserved.
        !            28:  * @author  Martin Minow    mailto:[email protected]
        !            29:  * @revision   1997.02.13  Initial conversion from AMDPCSCSIDriver sources.
        !            30:  *
        !            31:  * Apple96SCSI.h - top-level API for Apple 53C96 (Curio/DBDMA) SCSI adaptor.
        !            32:  * Apple96SCSI is closely based on Doug Mitchell's AMD 53C974/79C974 driver.
        !            33:  *
        !            34:  * Edit History
        !            35:  * 1997.02.13  MM  Initial conversion from AMDPCSCSIDriver sources.
        !            36:  * 1997.03.24  MM  Normalized against AppleMeshSCSI.h
        !            37:  * 1997.11.12  MM  Added support for scatter-gather lists.
        !            38:  */
        !            39: #define APPLE96_ALWAYS_ASSERT          0
        !            40: #define APPLE96_ENABLE_GET_SET         1
        !            41: #define VERY_SERIOUS_DEBUGGING         0       /* Log each method entry and exit */
        !            42: #define SERIOUS_DEBUGGING              0       /* Log command, buffer, etc operation */
        !            43: #define LOG_COMMAND_AND_RESULT         0       /* Log command and results */
        !            44: #define LOG_ERROR_RECOVERY             0       /* Log during error recovery */
        !            45: #define LOG_RESULT_ON_ERROR            0       /* Log all errors, even expected ones */
        !            46: #define DUMP_USER_BUFFER               0       /* Set to buffer length to dump */
        !            47: #define TIMESTAMP_AT_IOCOMPLETE                0
        !            48: /*
        !            49:  * Radar 2005639. Tell SCSIDisk how many threads to create.
        !            50:  */
        !            51: #define MAX_CLIENT_THREADS             1       /* Ask SCSIDisk to create threads */
        !            52: #define ENABLE_DISCONNECT              FALSE   /* TEMP TEMP TEMP */
        !            53: #define ENABLE_TAGGED_QUEUEING         FALSE   /* TEMP TEMP TEMP */
        !            54: // #define USE_CURIO_METHODS           1       /* TEMP TEMP TEMP */
        !            55: #define USE_CURIO_METHODS              0       /* Default to inline */
        !            56: #define WRITE_CHIP_OPERATION_INTO_TIMESTAMP_LOG 1
        !            57: #define APPLE96_ENABLE_GET_SET         1       /* Enable management ioctl's */
        !            58: #ifndef VERY_SERIOUS_DEBUGGING
        !            59: #define VERY_SERIOUS_DEBUGGING         0
        !            60: #endif
        !            61: #ifndef USE_CURIO_METHODS
        !            62: #define USE_CURIO_METHODS              0
        !            63: #endif
        !            64: #ifndef WRITE_CHIP_OPERATION_INTO_TIMESTAMP_LOG
        !            65: #define WRITE_CHIP_OPERATION_INTO_TIMESTAMP_LOG 0
        !            66: #endif
        !            67: #ifndef APPLE96_ALWAYS_ASSERT
        !            68: #define APPLE96_ALWAYS_ASSERT          0
        !            69: #endif
        !            70: #if VERY_SERIOUS_DEBUGGING
        !            71: #undef SERIOUS_DEBUGGING
        !            72: #define SERIOUS_DEBUGGING              1
        !            73: #endif
        !            74: #ifndef SERIOUS_DEBUGGING
        !            75: #define SERIOUS_DEBUGGING              0
        !            76: #endif
        !            77: #ifndef LOG_COMMAND_AND_RESULT
        !            78: #define LOG_COMMAND_AND_RESULT         0
        !            79: #endif
        !            80: #ifndef LOG_ERROR_RECOVERY
        !            81: #define LOG_ERROR_RECOVERY             0
        !            82: #endif
        !            83: #ifndef TIMESTAMP_AT_IOCOMPLETE
        !            84: #define TIMESTAMP_AT_IOCOMPLETE                0
        !            85: #endif
        !            86: #ifndef MAX_CLIENT_THREADS
        !            87: #define MAX_CLIENT_THREADS             6       /* Radar 2005639 */
        !            88: #endif
        !            89: 
        !            90: #undef NDEBUG  /* Enable ASSERT macro */
        !            91: 
        !            92: #import <driverkit/IODirectDevice.h>
        !            93: #import <driverkit/IOSCSIController.h>
        !            94: #import <driverkit/scsiTypes.h>
        !            95: #import <driverkit/IOPower.h>
        !            96: #import "Apple96Types.h"
        !            97: #import "Apple96Curio.h"
        !            98: #import "Apple96DBDMADefs.h"
        !            99: #import "Timestamp.h"
        !           100: #import "Apple96DDM.h"
        !           101: 
        !           102: @interface Apple96_SCSI : IOSCSIController <IOPower>
        !           103: {
        !           104:     /*
        !           105:      * These globals locate the hardware interface registers in logical and physical
        !           106:      * address spaces.
        !           107:      */
        !           108:     PhysicalAddress    gSCSIPhysicalAddress;   /* -> NCR registers (physical)  */
        !           109:     volatile UInt8     *gSCSILogicalAddress;   /* -> NCR registers (logical)   */
        !           110:     UInt32             gSCSIRegisterLength;    /* == Size of NCR registers     */
        !           111:     
        !           112:     PhysicalAddress    gDBDMAPhysicalAddress;  /* -> DBDMA registers (physical) */
        !           113:     DBDMAChannelRegisters   *gDBDMALogicalAddress;  /* -> DBDMA registers (logical) */
        !           114:     UInt32             gDBDMARegisterLength;   /* == Size of DBDMA registers   */
        !           115: 
        !           116:     PhysicalAddress    gDBDMAChannelAddress;   /* -> DBDMA channel area (physical) */
        !           117:     DBDMADescriptor    *gChannelCommandArea;   /* -> DBDMA channel area (logical)  */
        !           118:     UInt32             gChannelCommandAreaSize; /* == DBDMA channel allocated size */
        !           119:     UInt32             gDBDMADescriptorMax;    /* Number of DATA descriptors   */
        !           120:     
        !           121:     UInt32             gPageSize;              /* Logical page size            */
        !           122:     UInt32             gPageMask;              /* Logical page size - 1        */
        !           123:     
        !           124:     /*
        !           125:      * Autosense I/O requests write into this permanently-allocated area. Then, we copy
        !           126:      * the sense data to the caller's SCSI command parameter block. The autosense area
        !           127:      * is at the end of the descriptor area.
        !           128:      */
        !           129:     esense_reply_t     *gAutosenseArea;        /* -> Autosense area (logical)  */
        !           130:     PhysicalAddress    gAutosenseAddress;      /* Used to autosense DMA        */
        !           131:     
        !           132:     /*
        !           133:      * This is the message port that the kernel uses to signal hardware interrupts.
        !           134:      */
        !           135:     port_t             gKernelInterruptPort;
        !           136: 
        !           137:     /*
        !           138:      * Commands are passed from exported methods to the I/O thread
        !           139:      * via gIncomingCommandQueue, which is protected by gIncomingCommandLock.
        !           140:      * 
        !           141:      * Commands which are disconnected but not complete are kept
        !           142:      * in gDisconnectedCommandQueue.
        !           143:      *
        !           144:      * Commands which have been dequeued from gIncomingCommandQueue by the 
        !           145:      * I/O thread but which have not been started because a command is currently
        !           146:      * active on the bus are kept in gPendingCommandQueue. This queue also
        !           147:      * holds commands pushed back when we lose arbitration.
        !           148:      *
        !           149:      * The currently active command, if any, is kept in gActiveCommand.
        !           150:      * Only commandBufs with op == kCommandExecute are ever placed in
        !           151:      * gActiveCommand.
        !           152:      */
        !           153:     queue_head_t       gIncomingCommandQueue;
        !           154:     id                 gIncomingCommandLock;   /* NXLock for gIncomingCommandQueue */
        !           155:     queue_head_t       gPendingCommandQueue;
        !           156:     queue_head_t       gDisconnectedCommandQueue;
        !           157:     /*
        !           158:      * This is the command we're currently execution. If NULL, the Macintosh is idle
        !           159:      * (or all commands are disconnected). Normally, gCurrentTarget and gCurrentLUN
        !           160:      * track the values in the active command's associated SCSI request. They are set
        !           161:      * to kInvalidTarget and kInvalidLUN at initialization, command deactivation,
        !           162:      * command complete, and command disconnect. They are set to valid values (with no
        !           163:      * active command) during reselection. This is tricky, so look carefully at the code.
        !           164:      */ 
        !           165:     CommandBuffer      *gActiveCommand;        /* -> The currently executing command */
        !           166:     UInt32             gCurrentTarget;         /* == The current target bus ID */
        !           167:     UInt32             gCurrentLUN;            /* == The current target LUN    */
        !           168:        
        !           169:     /*
        !           170:      * Global option flags, accessible via instance table or setIntValues. Note: some of
        !           171:      * these are intended for debugging. However, users may need to disable command
        !           172:      * queuing, synchronous, or fast to handle device or bus limitations. The
        !           173:      * architecture-specific initialization "looks" at the device to determine whether
        !           174:      * specific features (such as synchronous) are supported.
        !           175:      * gOptionAutoSenseEnable      Debug only, normally set
        !           176:      * gOptionCmdQueueEnable       Enable tagged queuing.
        !           177:      * gOptionSyncModeEnable       Enable synchronous transfers (clear if problems)
        !           178:      * gOptionFastModeEnable       Enable fast transfers (clear if problems)
        !           179:      * gOptionDisconnectEnable     Debug only, normally set.
        !           180:      * gOptionExtendTiming     Extended selection timing (debug, unused)
        !           181:      * gOptionSyncModeSupportedByHardware  Set if this NCR chip supports synchronous.
        !           182:      * gOptionFastModeSupportedByHardware  Set if this NCR chip supports fast mode.
        !           183:      * gFlagIOThreadRunning        Set when I/O thread is initialized. Needed
        !           184:      *                 for shutdown.
        !           185:      * gFlagBusBusy            Set in the state machine when we are apparently
        !           186:      *                 connected to a target (even for target selection).
        !           187:      *                 Cleared in the interrupt service routine on
        !           188:      *                 a disconnected or bus reset interrupt state.
        !           189:      * gFlagCheckForAnotherInterrupt   Set in the interrupt service routine on
        !           190:      *                 entrance to the bus finite-state automaton.
        !           191:      *                 Automaton functions clear this to force an
        !           192:      *                 exit from the ISR when it expects a long bus
        !           193:      *                 operation.
        !           194:      */
        !           195:     unsigned   gOptionAutoSenseEnable          : 1,
        !           196:                gOptionCmdQueueEnable           : 1,
        !           197:                gOptionSyncModeEnable           : 1,
        !           198:                gOptionFastModeEnable           : 1,
        !           199:                gOptionExtendTiming             : 1,
        !           200:                gOptionDisconnectEnable         : 1,
        !           201:                gOptionSyncModeSupportedByHardware : 1,
        !           202:                gOptionFastModeSupportedByHardware : 1,
        !           203:                gFlagIOThreadRunning            : 1,    /* Set at init          */
        !           204:                gFlagBusBusy                    : 1,
        !           205:                gFlagCheckForAnotherInterrupt   : 1,    /* Loop through ISR     */
        !           206:                gFlagNeedAnotherInterrupt       : 1,    /* mikej                */
        !           207:                pad                             : 20;
        !           208:     UInt32     scsiClockRate;              /* in MHz       */
        !           209: 
        !           210:     /*
        !           211:      * Array of active I/O counters, one counter per lun per target. If command
        !           212:      * queueing is disabled, the max value of each counter is 1. gActiveCount is
        !           213:      * the sum of all elements in activeArray.
        !           214:      */
        !           215:     UInt8      gActiveArray[SCSI_NTARGETS][SCSI_NLUNS];
        !           216:     UInt32     gActiveCount;   
        !           217: 
        !           218:     /*
        !           219:      * These variables change during SCSI I/O operation.
        !           220:      */
        !           221:     BusState           gBusState;          /* The overall state automaton  */
        !           222:     /*
        !           223:      * These variables manage Message In bus phase. Because the message in handler
        !           224:      * uses programmed I/O, gMsgInCount, gMsgInIndex, and gMsgInState are actually
        !           225:      * local variables to the message reader, and are here for debugging convenience.
        !           226:      */
        !           227:     signed int         gMsgInCount;    /* Message bytes still to read  */
        !           228:     MsgInState         gMsgInState;    /* How are we handling messages */
        !           229:     UInt32             gMsgInIndex;    /* -> free spot in gMsgInBuffer */
        !           230:     UInt8              gMsgInBuffer[kMessageInBufferLength];
        !           231:     /*
        !           232:      * These variables manage Message Out bus phase. To send a message,
        !           233:      * write it into the buffer, starting at gMsgOutSendIndex and set ATN.
        !           234:      * When the target enters Message Out phase, write the bytes into the
        !           235:      * NCR fifo starting at gMsgOutStoreIndex. When the transfer completes
        !           236:      * with MSG parity error, use the residual count to "back up" gMsgOutSendIndex
        !           237:      * to resend the message.
        !           238:      */
        !           239:     UInt8      *gMsgOutPtr;        /* -> free spot in gMsgOutBuffer    */
        !           240:     UInt8      *gMsgPutPtr;        /* -> next byte to send     */
        !           241:     UInt8      gMsgOutBuffer[kMessageOutBufferLength];
        !           242:     UInt8      gLastMsgOut[2];     /* Has last message out specifier   */
        !           243:     /*
        !           244:      * Hardware related variables
        !           245:      */
        !           246:     UInt8      gInitiatorID;       /* Our SCSI ID          */
        !           247:     UInt8      gInitiatorIDMask;   /* BusID bitmask for selection  */
        !           248: //    UInt8    gSelectionTimeout;  /* In MESH 10 msec units    */
        !           249:     UInt32     gClockFrequency;    /* For selection timeout    */
        !           250:     
        !           251:     /*
        !           252:      * commandBuf->queueTag for next I/O. This is never zero; for all requests
        !           253:      * involving a T/L/Q nexus, a queue tag of zero indicates a nontagged command.
        !           254:      */
        !           255:     UInt8      gNextQueueTag;
        !           256:     
        !           257:     /*
        !           258:      * Shadow current chip values.
        !           259:      * gSaveStatus     rSTA register at last interrupt.
        !           260:      * gSaveSeqStep        rSQS register at last interrupt
        !           261:      * gSaveInterrupt      rINT register at last interrupt.
        !           262:      * gCurrentBusPhase    The last bus phase (for error recovery)
        !           263:      * gLastSelectionTimeout   Last selection timeout we stored in Curio
        !           264:      * gLastSynchronousOffset  Last synchronous offset we stored in Curio.
        !           265:      * gLastSynchronousPeriod  Last synchronous perioud we stored in Curio.
        !           266:      */
        !           267:     UInt8      gSaveStatus;
        !           268:     UInt8      gSaveSeqStep;
        !           269:     UInt8      gSaveInterrupt;
        !           270:     UInt8      gCurrentBusPhase;   /* Last known SCSI phase    */
        !           271:     UInt8      gLastSelectionTimeout;  /* Chip selection timeout   */
        !           272:     UInt8      gLastSynchronousOffset; /* Synchronous transfer offset  */
        !           273:     UInt8      gLastSynchronousPeriod; /* Synchronous period shadow    */
        !           274:     /*
        !           275:      * Per-target information.
        !           276:      */
        !           277:     PerTargetData   gPerTargetData[SCSI_NTARGETS];
        !           278:        
        !           279:     /*
        !           280:      * Statistics support.
        !           281:      */
        !           282:     UInt32     gMaxQueueLen;
        !           283:     UInt32     gQueueLenTotal;
        !           284:     UInt32     gTotalCommands;
        !           285: }
        !           286: 
        !           287: /**
        !           288:  * Public methods
        !           289:  */
        !           290: /**
        !           291:  * Initialize the SCSI driver.
        !           292:  */
        !           293: + (Boolean) probe   : deviceDescription;
        !           294: /**
        !           295:  * Shutdown the driver.
        !           296:  */
        !           297: - free;
        !           298: 
        !           299: /*
        !           300:  * Execute a SCSI request using a single logical address range.
        !           301:  * This is compatible with earlier DriverKit implementations.
        !           302:  * @param scsiReq   The SCSI request command record, including the
        !           303:  *     target device and LUN, the command to execute,
        !           304:  *     and various control flags.
        !           305:  * @param buffer    The data buffer, if any. This may be NULL if
        !           306:  *     no data phase is expected.
        !           307:  * @param client    The client task that "owns" the memory buffer.
        !           308:  * @return  Return a bus adaptor specific error status.
        !           309:  */
        !           310: - (sc_status_t) executeRequest : (IOSCSIRequest *) scsiReq 
        !           311:         buffer                 : (void *) buffer 
        !           312:         client                 : (vm_task_t) client;
        !           313: 
        !           314: /*
        !           315:  * Execute a SCSI request using an IOMemoryDescriptor. This allows callers to
        !           316:  * provide (kernel-resident) logical scatter-gather lists. For compatibility
        !           317:  * with existing implementations, the low-level SCSI device driver must first
        !           318:  * ensure that executeRequest:ioMemoryDescriptor is supported by executing:
        !           319:  *  [controller respondsToSelector : executeRequest:ioMemoryDescriptor]
        !           320:  * @param scsiReq   The SCSI request command record, including the
        !           321:  *     target device and LUN, the command to execute,
        !           322:  *     and various control flags.
        !           323:  * @param ioMemoryDescriptor The data buffer(s), if any. This may be NULL if
        !           324:  *     no data phase is expected.
        !           325:  * @param client    The client task that "owns" the memory buffer.
        !           326:  * @return  Return a bus adaptor specific error status.
        !           327:  */
        !           328: - (sc_status_t) executeRequest
        !           329:                                : (IOSCSIRequest *) scsiReq 
        !           330:     ioMemoryDescriptor         : (IOMemoryDescriptor *) ioMemoryDescriptor;
        !           331: 
        !           332: - (sc_status_t) resetSCSIBus;
        !           333: 
        !           334: /**
        !           335:  * Reset the SCSI bus.
        !           336:  */
        !           337: - (sc_status_t) resetSCSIBus;
        !           338: /**
        !           339:  * Reset statistics buffers.
        !           340:  */
        !           341: - (void)    resetStats;
        !           342: 
        !           343: - (unsigned)   numQueueSamples;
        !           344: 
        !           345: - (unsigned)   sumQueueLengths;
        !           346: 
        !           347: - (unsigned)   maxQueueLength;
        !           348: 
        !           349: /**
        !           350:  * interruptOccurred is a public method called by the I/O
        !           351:  * thread in IODirectDevice when an interrupt occurs.
        !           352:  */
        !           353: - (void)    interruptOccurred;
        !           354: 
        !           355: /**
        !           356:  * timeoutOccurred is a public method called by the I/O
        !           357:  * thread in IODirectDevice when it receives a timeout
        !           358:  * message.
        !           359:  */
        !           360: - (void)    timeoutOccurred;
        !           361: 
        !           362: #if APPLE96_ENABLE_GET_SET
        !           363: 
        !           364: - (IOReturn) setIntValues      : (unsigned *)parameterArray
        !           365:           forParameter         : (IOParameterName)parameterName
        !           366:              count             : (unsigned)count;
        !           367: - (IOReturn) getIntValues      : (unsigned *)parameterArray
        !           368:           forParameter         : (IOParameterName)parameterName
        !           369:              count             : (unsigned *)count;    // in/out
        !           370: /*
        !           371:  * get/setIntValues parameters.
        !           372:  */
        !           373: #define APPLE96_AUTOSENSE              "AutoSense"
        !           374: #define APPLE96_CMD_QUEUE              "CmdQueue"
        !           375: #define APPLE96_SYNC                   "Synchronous"
        !           376: #define APPLE96_FAST_SCSI              "FastSCSI"
        !           377: #define APPLE96_RESET_TARGETS          "ResetTargets"
        !           378: #define APPLE96_RESET_TIMESTAMP                "ResetTimestamp"
        !           379: #define APPLE96_ENABLE_TIMESTAMP       "EnableTimestamp"
        !           380: #define APPLE96_DISABLE_TIMESTAMP      "DisableTimestamp"
        !           381: #define APPLE96_PRESERVE_FIRST_TIMESTAMP "PreserveFirstTimestamp"
        !           382: #define APPLE96_PRESERVE_LAST_TIMESTAMP        "PreserveLastTimestamp"
        !           383: #define APPLE96_READ_TIMESTAMP         "ReadTimestamp"
        !           384: #define APPLE96_STORE_TIMESTAMP                "StoreTimestamp"
        !           385: /*
        !           386:  * Radar 2005639. Tell SCSIDisk how many threads to create.
        !           387:  * Allow access to the enable disconnect option.
        !           388:  */
        !           389: #define APPLE96_ENABLE_DISCONNECT      "EnableDisconnect"
        !           390: #define APPLE_MAX_THREADS              "ClientThreads"
        !           391: 
        !           392: /*
        !           393:  * Recording and setting timestamps may be done using getIntValues (this permits
        !           394:  * access from non-privileged tasks.
        !           395:  *  ResetTimestamp     Clear the timestamp vector - do this before starting
        !           396:  *                     a sequence (no parameters)
        !           397:  *  EnableTimestamp    Start recording (no parameters) (default)
        !           398:  *  DisableTimestamp   Stop recording (no parameters)
        !           399:  *  PreserveFirstTimestamp  Stop recording when the buffer fills (until it is emptied)
        !           400:  *  PreserveLastTimestamp   Discard old values when new arrive (default)
        !           401:  *  ReadTimestamp      Read a vector of timestamps (see sample below)
        !           402:  *  StoreTimestamp     Store a timestamp (from user mode) (see sample below)
        !           403:  * ReadTimestamp copies timestamps from the internal database to user-specified vector.
        !           404:  * Because getIntValues parameters are defined in int units, the code is slighthly
        !           405:  * non-obvious:
        !           406:  *  TimestampDataRecord myTimestamps[123];
        !           407:  *  unsigned       count;
        !           408:  *  count = sizeof (myTimestamps) / sizeof (unsigned);
        !           409:  *  [scsiDevice getIntValues
        !           410:  *                     : (unsigned int *) myTimestamps
        !           411:  *     forParameter    : APPLE96_READ_TIMESTAMP
        !           412:  *     count           : &count
        !           413:  *  ];
        !           414:  *  count = (count * sizeof (unsigned)) / sizeof (TimestampDataRecord);
        !           415:  *  for (i = 0; i < count; i++) {
        !           416:  *                     Process(myTimestamps[i]);
        !           417:  *  }
        !           418:  * Applications can store timestamps using one of three parameter formats:
        !           419:  *  unsigned       paramVector[4];
        !           420:  * Tag only -- the library will supply the event time
        !           421:  *  paramVector[0] = kMyTagValue;
        !           422:  *  [scsiDevice getIntValues
        !           423:  *                     : paramVector
        !           424:  *     forParameter    : "StoreTimestamp"
        !           425:  *     count           : 1
        !           426:  *  ];
        !           427:  * Tag plus value:
        !           428:  *  paramVector[0] = kMyTagValue;
        !           429:  *  paramVector[1] = 123456;
        !           430:  *  [scsiDevice getIntValues
        !           431:  *                     : paramVector
        !           432:  *     forParameter    : "StoreTimestamp"
        !           433:  *     count           : 2
        !           434:  *  ];
        !           435:  * Tag plus value + time:
        !           436:  *  paramVector[0] = kMyTagValue;
        !           437:  *  paramVector[1] = 123456;
        !           438:  *  IOGetTimestamp((ns_time_t *) &paramVector[2]);
        !           439:  *  [scsiDevice getIntValues
        !           440:  *                     : paramVector
        !           441:  *     forParameter    : "StoreTimestamp"
        !           442:  *     count           : 4
        !           443:  *  ];
        !           444:  * Note that you can combine tag only with tag plus value plus time to measure
        !           445:  * user->device latency.
        !           446:  */
        !           447: 
        !           448: #endif /* APPLE96_ENABLE_GET_SET */
        !           449: 
        !           450: @end
        !           451: 
        !           452: 

unix.superglobalmegacorp.com

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