Annotation of XNU/iokit/Families/IOFireWire/IOFWUtils.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * Copyright (c) 1999 Apple Computer, Inc.  All rights reserved.
        !            24:  *
        !            25:  * HISTORY
        !            26:  * 3 June 99 wgulland created.
        !            27:  *
        !            28:  * Useful stuff called from several different FireWire objects.
        !            29:  */
        !            30: #include <IOKit/assert.h>
        !            31: #include <IOKit/IOLib.h>
        !            32: #include <IOKit/firewire/IOFWRegs.h>
        !            33: #include <IOKit/firewire/IOFireWirePriv.h>
        !            34: 
        !            35: ////////////////////////////////////////////////////////////////////////////////
        !            36: //
        !            37: // FWComputeCRC16
        !            38: //
        !            39: //   This proc computes a CRC 16 check.
        !            40: //
        !            41: 
        !            42: UInt16 FWComputeCRC16(UInt32 *pQuads, UInt32 numQuads)
        !            43: {
        !            44:     SInt32     shift;
        !            45:     UInt32     sum;
        !            46:     UInt32     crc16;
        !            47:     UInt32     quadNum;
        !            48:     UInt32     quad;
        !            49: 
        !            50:     // Compute CRC 16 over all quads.
        !            51:     crc16 = 0;
        !            52:     for (quadNum = 0; quadNum < numQuads; quadNum++) {
        !            53:         quad = *pQuads++;
        !            54:         for (shift = 28; shift >= 0; shift -= 4) {
        !            55:             sum = ((crc16 >> 12) ^ (quad >> shift)) & 0x0F;
        !            56:             crc16 = (crc16 << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
        !            57:         }
        !            58:     }
        !            59: 
        !            60:     return (crc16 & 0xFFFF);
        !            61: }
        !            62: 
        !            63: 
        !            64: ////////////////////////////////////////////////////////////////////////////////
        !            65: //
        !            66: // FWCSRROMInvalidateEntryIDType
        !            67: //
        !            68: //   Invalidate a CSR ROM entry ID.  This will deallocate any memory allocated
        !            69: // for the ID excluding the ID data record itself.
        !            70: //
        !            71: // Probably only thing needed is to release reference to the ROM.
        !            72: //
        !            73: 
        !            74: void  FWCSRROMInvalidateEntryIDType(CSRROMEntryID csrROMEntryID)
        !            75: {
        !            76:     CSRROMEntryIDDataPtr               pCSRROMEntryIDData;
        !            77: 
        !            78:     if (csrROMEntryID != kInvalidCSRROMEntryID)
        !            79:     {
        !            80:         pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) csrROMEntryID;
        !            81: 
        !            82:         switch (pCSRROMEntryIDData->entryType)
        !            83:         {
        !            84:                 case kLocalCSRROMEntryIDType :
        !            85:                         break;
        !            86: 
        !            87:                 case kRemoteCSRROMEntryIDType :
        !            88: 
        !            89:                         break;
        !            90: 
        !            91:                 default :
        !            92:                         break;
        !            93:         }
        !            94: 
        !            95:         // Entry is now invalid.
        !            96:         pCSRROMEntryIDData->entryType = kInvalidCSRROMEntryIDType;
        !            97:     }
        !            98: }
        !            99: 
        !           100: ////////////////////////////////////////////////////////////////////////////////
        !           101: //
        !           102: // FWCSRROMCreateEntryID
        !           103: //
        !           104: //   Allocate memory for a CSR ROM entry ID.
        !           105: //zzz could be a little more efficient computing allocation size.
        !           106: //
        !           107: 
        !           108: CSRROMEntryID  FWCSRROMCreateEntryID(void)
        !           109: {
        !           110:     CSRROMEntryID              csrROMEntryID = kInvalidCSRROMEntryID;
        !           111:     CSRROMEntryIDDataPtr       pCSRROMEntryIDData;
        !           112:     UInt32                     maxSize;
        !           113: 
        !           114:     // Determine maximum size of all entry types.
        !           115:     // Need enough for local ID type.
        !           116:     maxSize = sizeof (CSRROMLocalIDData);
        !           117:     if (sizeof (CSRROMRemoteIDData) > maxSize)
        !           118:         maxSize = sizeof (CSRROMRemoteIDData);
        !           119: 
        !           120:     // Allocate the data.
        !           121:     pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) IOMalloc (maxSize);
        !           122:     if (pCSRROMEntryIDData != NULL) {
        !           123:         pCSRROMEntryIDData->entryType = kInvalidCSRROMEntryIDType;
        !           124:         csrROMEntryID = (CSRROMEntryID) pCSRROMEntryIDData;
        !           125:     }
        !           126:     return (csrROMEntryID);
        !           127: }
        !           128: 
        !           129: ////////////////////////////////////////////////////////////////////////////////
        !           130: //
        !           131: // FWCSRROMDisposeEntryID
        !           132: //
        !           133: //   Deallocate memory for a CSR ROM entry ID.
        !           134: //
        !           135: 
        !           136: void  FWCSRROMDisposeEntryID(CSRROMEntryID csrROMEntryID)
        !           137: {
        !           138:     CSRROMEntryIDDataPtr pCSRROMEntryIDData;
        !           139: 
        !           140:     if (csrROMEntryID != kInvalidCSRROMEntryID) {
        !           141:         UInt32 maxSize;
        !           142: 
        !           143:         // Determine maximum size of all entry types.
        !           144:         // Need enough for local ID type.
        !           145:         maxSize = sizeof (CSRROMLocalIDData);
        !           146:         if (sizeof (CSRROMRemoteIDData) > maxSize)
        !           147:             maxSize = sizeof (CSRROMRemoteIDData);
        !           148:         pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) csrROMEntryID;
        !           149: 
        !           150:         // Invalidate entry.
        !           151:         FWCSRROMInvalidateEntryIDType (csrROMEntryID);
        !           152: 
        !           153:         // Deallocate entry.
        !           154:         IOFree(pCSRROMEntryIDData, maxSize);
        !           155:     }
        !           156: }
        !           157: 
        !           158: ////////////////////////////////////////////////////////////////////////////////
        !           159: //
        !           160: // FWCSRROMCreateRemoteEntryID
        !           161: //
        !           162: //   Create a remote CSR ROM entry ID.
        !           163: //
        !           164: 
        !           165: static IOReturn        FWCSRROMCreateRemoteEntryID(
        !           166:        CSRROMEntryID                   *pCSRROMEntryID,
        !           167:        const UInt32 *                  data,
        !           168:        UInt32                          *physicalPath,
        !           169:        UInt32                          pathSize)
        !           170: {
        !           171:     CSRROMEntryID                      csrROMEntryID = *pCSRROMEntryID;
        !           172:     CSRROMEntryIDDataPtr               pCSRROMEntryIDData;
        !           173:     CSRROMRemoteIDDataPtr              pCSRROMRemoteIDData;
        !           174: 
        !           175:     // Allocate an entry ID if given entry ID is invalid.
        !           176:     if (csrROMEntryID == kInvalidCSRROMEntryID) {
        !           177:         csrROMEntryID = FWCSRROMCreateEntryID ();
        !           178:         // If entry ID is still invalid, there must have been a memory error.
        !           179:         if (csrROMEntryID == kInvalidCSRROMEntryID)
        !           180:             return kIOReturnNoMemory;
        !           181:    }
        !           182: 
        !           183: 
        !           184:     // Get data from ID.
        !           185:     pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) csrROMEntryID;
        !           186:     pCSRROMRemoteIDData = (CSRROMRemoteIDDataPtr) pCSRROMEntryIDData;
        !           187: 
        !           188:     // If entry is not a remote type, invalidate its type.
        !           189:     if ((pCSRROMEntryIDData->entryType != kRemoteCSRROMEntryIDType) &&
        !           190:         (pCSRROMEntryIDData->entryType != kInvalidCSRROMEntryIDType)) {
        !           191:         FWCSRROMInvalidateEntryIDType (csrROMEntryID);
        !           192:     }
        !           193: 
        !           194:     // Make entry a remote type.
        !           195:     pCSRROMEntryIDData->entryType = kRemoteCSRROMEntryIDType;
        !           196: 
        !           197: 
        !           198:     // Copy directory paths and data pointer
        !           199:     pCSRROMRemoteIDData->data = data;
        !           200:     bcopy (physicalPath, pCSRROMRemoteIDData->physicalPath, pathSize * sizeof (UInt32));
        !           201:     pCSRROMRemoteIDData->pathSize = pathSize;
        !           202: 
        !           203:     // Return entry ID.
        !           204:     *pCSRROMEntryID = csrROMEntryID;
        !           205: 
        !           206:     return (kIOReturnSuccess);
        !           207: }
        !           208: 
        !           209: ////////////////////////////////////////////////////////////////////////////////
        !           210: //
        !           211: // FWCSRROMDisposeIterator
        !           212: //
        !           213: //   Dispose of storage allocated for iterator.
        !           214: //
        !           215: 
        !           216: void FWCSRROMDisposeIterator(CSRROMEntryIterator csrROMIterator)
        !           217: {
        !           218:     CSRROMEntryIteratorRecPtr  pIteratorRec;
        !           219: 
        !           220:     // Deallocate if iterator is valid.
        !           221:     if (csrROMIterator != kInvalidCSRROMIterator) {
        !           222:         // Get iterator record.
        !           223:         pIteratorRec = (CSRROMEntryIteratorRecPtr) csrROMIterator;
        !           224: 
        !           225:         // Deallocate iterator record.
        !           226:         IOFree (pIteratorRec, sizeof (CSRROMEntryIteratorRec));
        !           227:     }
        !           228: }
        !           229: 
        !           230: 
        !           231: ////////////////////////////////////////////////////////////////////////////////
        !           232: //
        !           233: // FWCSRROMSetIterator
        !           234: //
        !           235: //   Set current path and relationship of iterator.
        !           236: //zzz should support all entry ID types.
        !           237: //zzz should support kIterateRoot
        !           238: //
        !           239: 
        !           240: IOReturn FWCSRROMSetIterator(
        !           241:        CSRROMEntryIterator                     csrROMIterator,
        !           242:        CSRROMEntryID                           csrROMEntryID,
        !           243:        CSRROMIterationOp                       relationship)
        !           244: {
        !           245:     CSRROMEntryIteratorRecPtr  pIteratorRec;
        !           246:     CSRROMEntryIDDataPtr               pCSRROMEntryIDData;
        !           247:     CSRROMRemoteIDDataPtr              pCSRROMRemoteIDData;
        !           248: 
        !           249:     // Get CSR ROM search iterator record.
        !           250:     pIteratorRec = (CSRROMEntryIteratorRecPtr) csrROMIterator;
        !           251: 
        !           252:     // Set to given entry.
        !           253:     if (csrROMEntryID != kInvalidCSRROMEntryID) {
        !           254:         // Get entry data from ID.
        !           255:         pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) csrROMEntryID;
        !           256: 
        !           257:         if (pCSRROMEntryIDData->entryType == kRemoteCSRROMEntryIDType) {
        !           258:             // Recast entry data.
        !           259:             pCSRROMRemoteIDData = (CSRROMRemoteIDDataPtr) pCSRROMEntryIDData;
        !           260: 
        !           261:             // Copy physical path.
        !           262:             bcopy (pCSRROMRemoteIDData->physicalPath,
        !           263:                                             pIteratorRec->physicalPath,
        !           264:                                             pCSRROMRemoteIDData->pathSize * sizeof (UInt32));
        !           265: 
        !           266:             // Copy data pointer and path depth
        !           267:             pIteratorRec->data = pCSRROMRemoteIDData->data;
        !           268:             pIteratorRec->pathSize = pCSRROMRemoteIDData->pathSize;
        !           269:         }
        !           270:     }
        !           271: 
        !           272:     // Set to given relationship.
        !           273:     if (relationship != kIterateContinue)
        !           274:             pIteratorRec->relationship = relationship;
        !           275: 
        !           276:     return (kIOReturnSuccess);
        !           277: }
        !           278: 
        !           279: 
        !           280: ////////////////////////////////////////////////////////////////////////////////
        !           281: //
        !           282: // FWCSRROMEntrySearch
        !           283: //
        !           284: //   Search for the next ROM entry that matches the search criteria.
        !           285: //zzz need to check the search type in the criteria record and the relationship
        !           286: //zzz could be more efficient.  should make and use more defs.
        !           287: //zzz need to return information on what exactly was found
        !           288: //zzz fill in entry value better
        !           289: //zzz should break this up
        !           290: //zzz should support all entry ID types.
        !           291: //
        !           292: 
        !           293: // zzz
        !           294: // Made a quick fix here so that if we are searching for Unit Directories (key d1)
        !           295: // we will ignore any Instance Directories (key d8) because they contain redundant
        !           296: // pointers to Unit Directories.  This is almost surely not the best soltution.
        !           297: 
        !           298: IOReturn FWCSRROMEntrySearch(
        !           299:     CSRROMEntryIterator                csrROMIterator,
        !           300:     CSRROMIterationOp          relationship,
        !           301:     CSRROMEntryID              *pCSRROMEntryID,
        !           302:     int                        *pDone,
        !           303:     CSRROMSearchCriteriaPtr    pSearchCriteria,
        !           304:     UInt8 *                    pEntryValue,
        !           305:     UInt32                     *pEntrySize)
        !           306: {
        !           307:     CSRROMEntryIteratorRecPtr  pIteratorRec;
        !           308:     UInt32                             currentAddress, entryValueAddress;
        !           309:     UInt32                             pathSize;
        !           310:     UInt32                             directoryEnd;
        !           311:     UInt32                             address;
        !           312:     UInt32                             directoryHeader, directoryEntry;
        !           313:     UInt32                             leafEntry;
        !           314:     UInt32                             keyType, keyValue;
        !           315:     UInt32                             keyTypeBit, keyValueBitHi, keyValueBitLo;
        !           316:     UInt32                             returnedEntrySize;
        !           317:     bool                               found, done;
        !           318:     IOReturn                   status = kIOReturnSuccess;
        !           319: 
        !           320: //zzz Part of the Instance Directory hack
        !           321:     bool                               unitDirSearch;
        !           322:     bool                               ignoreInstanceDir;
        !           323: 
        !           324:     // If we are searching for Unit Directories (in FWExpertLoader.c/FWUpdateDevice)
        !           325:     // then just don't go down any Instance Directories (key d8), because we'll find a
        !           326:     // redundant pointer to the Unit Directory in there.
        !           327: 
        !           328:     unitDirSearch = (pSearchCriteria->csrROMSearchType == kCSRROMSearchForKey) &&
        !           329:             (pSearchCriteria->keyType == kCSRDirectoryKeyTypeBit) &&
        !           330:             (pSearchCriteria->keyHi == kCSRUnitDirectoryKeyHiBit) &&
        !           331:             (pSearchCriteria->keyLo == kCSRUnitDirectoryKeyLoBit);
        !           332: 
        !           333:     // Get CSR ROM search iterator record.
        !           334:     pIteratorRec = (CSRROMEntryIteratorRecPtr) csrROMIterator;
        !           335: 
        !           336:     // Read the current directory length.  First, get base address of current
        !           337:     // directory by going up one node in the directory path.  Special case
        !           338:     // when we're in the root directory.  Second, read the directory length
        !           339:     // at the base address.
        !           340:     pathSize = pIteratorRec->pathSize;
        !           341:     if (pathSize > 2) {
        !           342:         address = pIteratorRec->physicalPath[pathSize - 2];
        !           343:         directoryEntry = pIteratorRec->data[address];
        !           344:         address += (directoryEntry & 0x00FFFFFF);
        !           345:     }
        !           346:     else {
        !           347:         address = pIteratorRec->physicalPath[0];
        !           348:     }
        !           349:     directoryHeader = pIteratorRec->data[address];
        !           350:     directoryEnd = address + ((directoryHeader >> 16) + 1);
        !           351: 
        !           352:     // Loop until we've found what we're looking for, or we've searched
        !           353:     // everything.
        !           354:     found = false;
        !           355:     done = false;
        !           356:     while ((!found) && (!done)) {
        !           357:         // Read our current location.
        !           358:         pathSize = pIteratorRec->pathSize;
        !           359:         currentAddress = pIteratorRec->physicalPath[pathSize - 1];
        !           360: 
        !           361:         // Check if search was reset.
        !           362:         if (pIteratorRec->reset) {
        !           363:             pIteratorRec->reset = false;
        !           364:         }
        !           365:         else {
        !           366:             // Read directory entry at current address.
        !           367:             //zzz should have some address defs.
        !           368:             directoryEntry = pIteratorRec->data[currentAddress];
        !           369:             // If the current directory entry is a directory, add it to
        !           370:             // the path.  Otherwise, go to next directory entry.
        !           371:             keyType = (directoryEntry & 0xC0000000) >> 30;
        !           372: //zzz
        !           373: //The Instance Directory hack
        !           374:             ignoreInstanceDir = (directoryEntry >> 24) == 0xd8;
        !           375: //zzz
        !           376:             if ((keyType == kCSRDirectoryKeyType) && !ignoreInstanceDir) {
        !           377:                 // Go to and read directory header.
        !           378:                 //zzz should do this the right way if offset > 1024.
        !           379:                 currentAddress += (directoryEntry & 0x00FFFFFF);
        !           380:                 directoryHeader = pIteratorRec->data[currentAddress];
        !           381:                 // Add directory to path and set location to first
        !           382:                 // entry in directory.
        !           383:                 pathSize++;
        !           384: 
        !           385:                 directoryEnd =
        !           386:                         currentAddress + ((directoryHeader >> 16) + 1);
        !           387: 
        !           388:                 currentAddress += 1;
        !           389:             }
        !           390:             else {
        !           391:                 currentAddress += 1;
        !           392:             }
        !           393:         }
        !           394: 
        !           395:         // If we're past the end of the current directory, take it out
        !           396:         // of path.
        !           397:         while ((currentAddress >= directoryEnd) && (!done)) {
        !           398:             pathSize--;
        !           399:             currentAddress = pIteratorRec->physicalPath[pathSize - 1] + 1;
        !           400: 
        !           401:             // Read the current directory length.
        !           402:             if (pathSize > 2) {
        !           403:                 address = pIteratorRec->physicalPath[pathSize - 2];
        !           404:                 directoryEntry = pIteratorRec->data[address];
        !           405:                 address += (directoryEntry & 0x00FFFFFF);
        !           406:             }
        !           407:             else {
        !           408:                 address = pIteratorRec->physicalPath[0];
        !           409:             }
        !           410:             directoryHeader = pIteratorRec->data[address];
        !           411:             directoryEnd = address + ((directoryHeader >> 16) + 1);
        !           412:             if (pathSize < 2) {
        !           413:                 done = true;
        !           414:             }
        !           415:         }
        !           416:         // If we're not done searching, check the current directory entry
        !           417:         // against the search criteria.
        !           418:         if (!done) {
        !           419:             directoryEntry = pIteratorRec->data[currentAddress];
        !           420:             // Read key type and value.
        !           421:             keyType = (directoryEntry & 0xC0000000) >> 30;
        !           422:             keyValue = (directoryEntry & 0x3F000000) >> 24;
        !           423: 
        !           424:             // Convert to bit flag.
        !           425:             keyTypeBit = 1 << keyType;
        !           426:             if (keyValue > 31) {
        !           427:                 keyValueBitHi = 1 << (keyValue - 32);
        !           428:                 keyValueBitLo = 0;
        !           429:             }
        !           430:             else {
        !           431:                 keyValueBitHi = 0;
        !           432:                 keyValueBitLo = 1 << keyValue;
        !           433:             }
        !           434: 
        !           435:             // Compare bit flags against search criteria.
        !           436: 
        !           437:             if ((keyTypeBit & pSearchCriteria->keyType) &&
        !           438:                     ((keyValueBitHi & pSearchCriteria->keyHi) ||
        !           439:                                 (keyValueBitLo & pSearchCriteria->keyLo))) {
        !           440:                 switch (keyType) {
        !           441:                     case kCSRImmediateKeyType :
        !           442:                         if ((pEntrySize != NULL) && (pEntryValue != NULL)) {
        !           443:                                 // Determine size of data.
        !           444:                                 if (*pEntrySize < 4)
        !           445:                                         returnedEntrySize = *pEntrySize;
        !           446:                                 else
        !           447:                                         returnedEntrySize = 4;
        !           448: 
        !           449:                                 // Copy data.//zzz not right.
        !           450:                                 //zzz need def here.
        !           451:                                 *((UInt32 *) pEntryValue) =
        !           452:                                         directoryEntry & 0x00FFFFFF;
        !           453: 
        !           454:                                 // Return size.
        !           455:                                 *pEntrySize = returnedEntrySize;
        !           456:                         }
        !           457:                         break;
        !           458: 
        !           459:                     case kCSROffsetKeyType :
        !           460:                         if ((pEntrySize != NULL) && (pEntryValue != NULL)) {
        !           461:                                 // Determine size of data.
        !           462:                                 if (*pEntrySize < 4)
        !           463:                                         returnedEntrySize = *pEntrySize;
        !           464:                                 else
        !           465:                                         returnedEntrySize = 4;
        !           466: 
        !           467:                                 // Copy data.//zzz not right.
        !           468:                                 //zzz need def here.
        !           469:                                 *((UInt32 *) pEntryValue) =
        !           470:                                         directoryEntry & kCSREntryValue;
        !           471: 
        !           472:                                 // Return size.
        !           473:                                 *pEntrySize = returnedEntrySize;
        !           474:                         }
        !           475:                         break;
        !           476: 
        !           477:                     case kCSRLeafKeyType :
        !           478:                         if ((pEntrySize != NULL) && (pEntryValue != NULL)) {
        !           479:                             // Get address of leaf.
        !           480:                             //zzz need to do indirect stuff right.
        !           481:                             entryValueAddress = currentAddress + (directoryEntry & kCSREntryValue);
        !           482: 
        !           483:                             // Get size of leaf.
        !           484:                             leafEntry = pIteratorRec->data[entryValueAddress];
        !           485:                             returnedEntrySize = (leafEntry >> 16) * sizeof (UInt32);
        !           486:                             entryValueAddress += 1;
        !           487:                             // Determine size of data.
        !           488:                             if (returnedEntrySize > *pEntrySize)
        !           489:                                 returnedEntrySize = *pEntrySize;
        !           490:                             // Copy data.
        !           491:                             bcopy(&pIteratorRec->data[entryValueAddress], pEntryValue, returnedEntrySize);
        !           492:                             // Return size.
        !           493:                             *pEntrySize = returnedEntrySize;
        !           494:                         }
        !           495: 
        !           496:                         break;
        !           497: 
        !           498:                     case kCSRDirectoryKeyType ://zzz
        !           499:                         break;
        !           500: 
        !           501:                     default : //zzz
        !           502:                         break;
        !           503:                 }
        !           504: 
        !           505:                 found = true;
        !           506:             }
        !           507:         }
        !           508: 
        !           509:         // Update current address.
        !           510:         pIteratorRec->physicalPath[pathSize - 1] = currentAddress;
        !           511:         pIteratorRec->pathSize = pathSize;
        !           512:     }
        !           513: 
        !           514:     // Return CSR ROM entry ID.
        !           515:     if (pCSRROMEntryID != NULL) {
        !           516:         if (!done) {
        !           517:             status = FWCSRROMCreateRemoteEntryID
        !           518:                                     (pCSRROMEntryID,
        !           519:                                                 pIteratorRec->data,
        !           520:                                                 pIteratorRec->physicalPath,
        !           521:                                                 pIteratorRec->pathSize);
        !           522:         }
        !           523:         else {
        !           524:             if (*pCSRROMEntryID != kInvalidCSRROMEntryID)
        !           525:                     FWCSRROMDisposeEntryID (*pCSRROMEntryID);
        !           526:             *pCSRROMEntryID = kInvalidCSRROMEntryID;
        !           527:         }
        !           528:     }
        !           529: 
        !           530:     *pDone = done;
        !           531:     return (status);
        !           532: }
        !           533: 
        !           534: 

unix.superglobalmegacorp.com

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