Annotation of kernel/bsd/dev/ppc/drvUSBCMD/driverservices.c, revision 1.1.1.2

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: // Get Prototypes of the Exported Services First,...
                     26: 
                     27: #include "driverservices.h"
                     28: #include "rhap_local.h"
                     29: 
                     30: // The Driver Services Follow,...
                     31: 
                     32: /////////////////////////////////////////////////////////////////////////////////
                     33: //
                     34: //     Queues
                     35: //
                     36: //
                     37: 
                     38: /*-------------------------------------------------------------------------------
                     39: 
                     40: Routine:       PBQueueInit     -       Initialize a Queue (@ NON-Interrupt-lvl and SIH-lvl)
                     41: 
                     42: -------------------------------------------------------------------------------*/
                     43: 
                     44: OSErr PBQueueInit(QHdrPtr qHeader)
                     45: {
                     46:        qHeader -> qHead = nil;
                     47:        qHeader -> qTail = nil;
                     48:        qHeader -> qFlags = 0x0000;
                     49:        
                     50:        return noErr;
                     51: }
                     52: 
                     53: /*-------------------------------------------------------------------------------
                     54: 
                     55: Routine:       PBQueueCreate   -       Initialize a Queue (@ NON-Interrupt lvl)
                     56: 
                     57: -------------------------------------------------------------------------------*/
                     58: 
                     59: OSErr PBQueueCreate(QHdrPtr *qHeader)
                     60: {
                     61:        Ptr **theQueue;
                     62:        
                     63:        if (CurrentExecutionLevel() != kTaskLevel)
                     64:        {
                     65:                // SysDebugStr ((StringPtr)"\pPBQueueCreate not called at Task Level!");
                     66:                // 11/30/98 Adam return -1;
                     67:        }
                     68:        
                     69:        *qHeader = nil;
                     70:        theQueue = (Ptr **)PoolAllocateResident (sizeof(QHdr)+sizeof(short)+sizeof(Ptr),true);
                     71:        if (theQueue != nil)
                     72:        {
                     73:                // Store orig ptr in first 4 bytes.
                     74:                *theQueue = (Ptr *)theQueue;
                     75:                theQueue++;
                     76:                
                     77:                // Are we not aligned?
                     78:                if ( ((UInt32)theQueue & 3) == 0 )
                     79:                {
                     80:                        short *pattern = (short *)theQueue;
                     81:                        
                     82:                        *pattern++      = 0x4D4E;
                     83:                        *qHeader        = (QHdrPtr)pattern;
                     84:                        return noErr;
                     85:                }
                     86:                else
                     87:                {
                     88:                        *qHeader        = (QHdrPtr)theQueue;
                     89:                        return noErr;
                     90:                }
                     91:        }
                     92:        else
                     93:                return mFulErr;
                     94: }
                     95: 
                     96: /*-------------------------------------------------------------------------------
                     97: 
                     98: Routine:       PBQueueDelete   -       Finalize a Queue (@ NON-Interrupt lvl)
                     99: 
                    100: -------------------------------------------------------------------------------*/
                    101: 
                    102: OSErr PBQueueDelete(QHdrPtr qHeader)
                    103: {
                    104:        Ptr       **theMemory;
                    105:        UInt16 *pattern = (UInt16 *)qHeader;
                    106:        
                    107:        if (CurrentExecutionLevel() != kTaskLevel)
                    108:        {
                    109:                // SysDebugStr ((StringPtr)"\pPBQueueDelete not called at Task Level!");
                    110:                return -1;
                    111:        }
                    112:        
                    113:        if (*--pattern == 0x4D4E)
                    114:                qHeader = (QHdrPtr)((UInt32)(qHeader) - sizeof(UInt16));
                    115:                
                    116:        theMemory = (Ptr **)qHeader;
                    117:        theMemory--;
                    118:        
                    119:        if (*theMemory != (Ptr *)theMemory)
                    120:        {
                    121:                // SysDebugStr ((StringPtr)"\pPBQueueDelete not a Queue Header!");
                    122:                return -1;
                    123:        }
                    124: 
                    125:        (void)PoolDeallocate(theMemory);
                    126:        return noErr;
                    127: }
                    128: 
                    129: /*-------------------------------------------------------------------------------
                    130: 
                    131: Routine:       PBEnqueueLast   -       Add an IOPB to the end of a Request Queue. (@ Any Exec-lvl)
                    132:                                                                (Optimized for queue size of 1 or less)
                    133: 
                    134: -------------------------------------------------------------------------------*/
                    135: 
                    136: OSErr PBEnqueueLast(QElemPtr qElement, QHdrPtr qHeader)
                    137: {
                    138:        QElemPtr currElemPtr;
                    139:        UInt16 sr;
                    140:        
                    141:        // New element will be at end of queue.
                    142:        qElement -> qLink = nil;
                    143: 
                    144:        // Currently an empty queue?
                    145:        while ( qHeader -> qHead == nil )
                    146:        {
                    147:                if (CompareAndSwap ((UInt32) nil, (UInt32) qElement, (UInt32 *) &qHeader->qHead))
                    148:                        return noErr;
                    149:        }
                    150:        
                    151:        // Multi-element queue,...
                    152:        
                    153:        // Do it the sure, but slow way.
                    154:        sr = Disable68kInterrupts();
                    155: 
                    156:        // Entire queue empty?
                    157:        if ( qHeader -> qHead == nil )
                    158:        {
                    159:                // Add at head of queue
                    160:                qHeader -> qHead = qElement;
                    161:        }
                    162:        else
                    163:        {
                    164:                // Else, Get first element in queue.
                    165:                currElemPtr     = (QElemPtr)qHeader->qHead;
                    166:                
                    167:                // Move toward the end of the queue,...
                    168:                while ( currElemPtr -> qLink != nil )
                    169:                {       
                    170:                        currElemPtr     = currElemPtr -> qLink;
                    171:                }
                    172:        
                    173:                currElemPtr -> qLink = qElement;
                    174:        }
                    175:        
                    176:        Restore68kInterrupts(sr);
                    177:        return noErr;
                    178: }
                    179: 
                    180: /*-------------------------------------------------------------------------------
                    181: 
                    182: Routine:       PBEnqueue       -       Add an IOPB to Head of Request Queue. (@ Any Exec-lvl)
                    183: 
                    184: Function:      Returns (nothing)
                    185:                        
                    186: Result:                void    
                    187: -------------------------------------------------------------------------------*/
                    188: 
                    189: void PBEnqueue(QElemPtr qElement, QHdrPtr qHeader)
                    190: {
                    191:        do {
                    192:                qElement -> qLink = qHeader->qHead;
                    193:        } while (CompareAndSwap ((UInt32) qElement->qLink, (UInt32) qElement,
                    194:                                                                                        (UInt32 *) &qHeader->qHead) == false);
                    195: }
                    196: 
                    197: 
                    198: /*-------------------------------------------------------------------------------
                    199: 
                    200: Routine:       PBDequeue       -       Remove an IOPB from a Request Queue.  (@ Any Exec-lvl)
                    201: 
                    202: Function:      Returns (nothing)
                    203:                        
                    204: Result:                void    
                    205: -------------------------------------------------------------------------------*/
                    206: 
                    207: static OSErr PBDequeueSync(QElemPtr qElement, QHdrPtr qHeader)
                    208: {
                    209:        QElemPtr prevElemPtr, currElemPtr;
                    210:        OSErr    result = noErr;
                    211:        UInt16  sr;
                    212:        
                    213:        // Validate params.
                    214:        if ( (qElement == nil) || (qHeader == nil) )
                    215:                return paramErr;
                    216:                
                    217:        sr = Disable68kInterrupts();
                    218:        
                    219:        currElemPtr = (QElemPtr)qHeader->qHead;
                    220:        prevElemPtr = nil;
                    221:        
                    222:        // Find the one we want.
                    223:        while ( currElemPtr && (currElemPtr != qElement) )
                    224:        {
                    225:                // Advance the cause.
                    226:                prevElemPtr = currElemPtr;
                    227:                currElemPtr = currElemPtr -> qLink;
                    228:        }
                    229:        
                    230:        // We find it?
                    231:        if ( currElemPtr )
                    232:        {
                    233:                // Middle of the queue somewhere?
                    234:                if ( prevElemPtr )
                    235:                        prevElemPtr -> qLink = currElemPtr ->qLink;
                    236:                else
                    237:                        qHeader->qHead = currElemPtr ->qLink;
                    238:                
                    239:                currElemPtr -> qLink = nil;
                    240:        }
                    241:        else
                    242:                result = qErr; // not on the list.
                    243:        
                    244:        Restore68kInterrupts(sr);
                    245:        return result;
                    246: }
                    247: 
                    248: 
                    249: OSErr PBDequeue(QElemPtr qElement, QHdrPtr qHeader)
                    250: {
                    251:        // Optimize for common case of 1 element on the queue.
                    252:        
                    253:        // First one on the queue?
                    254:        while ( qHeader -> qHead == qElement )
                    255:        {
                    256:                // If the element is still at the head of the queue,... Remove it, and we are done.
                    257:                if (CompareAndSwap ((UInt32) qElement,
                    258:                                                        (UInt32) qElement -> qLink,
                    259:                                                        (UInt32 *) &qHeader->qHead) == true)
                    260:                {
                    261:                        qElement -> qLink = nil;
                    262: 
                    263:                        return noErr;
                    264:                }
                    265:        }
                    266:        
                    267:        // Multiple elements on the queue.
                    268:        return PBDequeueSync (qElement, qHeader);
                    269: }
                    270: 
                    271: /*-------------------------------------------------------------------------------
                    272: 
                    273: Routine:       PBDequeueFirst  -       Remove First Element on a Queue  (@ Any Exec-lvl)
                    274: 
                    275: Result:                noErr or qErr
                    276: -------------------------------------------------------------------------------*/
                    277: 
                    278: OSErr PBDequeueFirst(QHdrPtr qHeader, QElemPtr *theFirstqElem)
                    279: {
                    280:        QElemPtr qElement;
                    281: 
                    282:        do {
                    283:                // Get Queue Head Ptr
                    284:                qElement = qHeader -> qHead;
                    285:                
                    286:                // Empty Queue?
                    287:                if ( qElement == nil )
                    288:                {
                    289:                        if ( theFirstqElem )
                    290:                                *theFirstqElem = nil;
                    291:                                
                    292:                        return qErr;    
                    293:                }
                    294:                
                    295:                // If the element is still at the head of the queue,... Remove it, and we are done.
                    296:                if (CompareAndSwap ((UInt32) qElement,
                    297:                                                        (UInt32) qElement -> qLink,
                    298:                                                        (UInt32 *) &qHeader->qHead) == true)
                    299:                {
                    300:                        if ( theFirstqElem )
                    301:                                *theFirstqElem = qElement;
                    302:                                
                    303:                        qElement -> qLink = nil;
                    304: 
                    305:                        return noErr;
                    306:                }
                    307:        } while (1);
                    308: }
                    309: 
                    310: /*-------------------------------------------------------------------------------
                    311: 
                    312: Routine:       PBDequeueLast   -       Remove Last Element on a Queue  (@ Any Exec-lvl)
                    313: 
                    314: Result:                noErr or qErr
                    315: -------------------------------------------------------------------------------*/
                    316: 
                    317: OSErr PBDequeueLast(QHdrPtr qHeader, QElemPtr *theLastqElem)
                    318: {
                    319:        QElemPtr currElemPtr, prevElemPtr;
                    320:        OSErr   result = noErr;
                    321:        UInt16 sr;
                    322:        
                    323:        if ( theLastqElem )
                    324:                *theLastqElem = nil;
                    325:                
                    326:        sr = Disable68kInterrupts();
                    327: 
                    328:        // Get Queue Head Ptr and our initial previous ptr
                    329:        if ((prevElemPtr = qHeader -> qHead) == nil)
                    330:                result = qErr; // q is empty
                    331:        else
                    332:        {
                    333:                // Get head of queue
                    334:                currElemPtr     = (QElemPtr)qHeader->qHead;
                    335:                
                    336:                // Move toward the end of the queue,...
                    337:                while ( currElemPtr -> qLink != nil )
                    338:                {       
                    339:                        prevElemPtr     = currElemPtr;
                    340:                        currElemPtr     = currElemPtr ->qLink;
                    341:                }
                    342:        
                    343:                // Remove last one from the queue.
                    344:                prevElemPtr->qLink = nil;
                    345:                
                    346:                // If last was also the first, nil out qheader.
                    347:                if ( currElemPtr == qHeader -> qHead )
                    348:                        qHeader -> qHead = nil;
                    349:        
                    350:                // Return last element to caller.
                    351:                if ( theLastqElem )
                    352:                        *theLastqElem = currElemPtr;
                    353:        }
                    354:        
                    355:        Restore68kInterrupts(sr);
                    356:        return result;
                    357: }

unix.superglobalmegacorp.com

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