Annotation of XNU/iokit/Families/IOFireWire/IOFWLocalROM.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:  * IOFireWireController methods to build the local device ROM.
        !            29:  */
        !            30: 
        !            31: #include <assert.h>
        !            32: 
        !            33: #define DEBUGGING_LEVEL 0      // 1 = low; 2 = high; 3 = extreme
        !            34: #define DEBUGLOG kprintf
        !            35: 
        !            36: #include <IOKit/IOWorkLoop.h>
        !            37: #include <IOKit/firewire/IOFireWireController.h>
        !            38: #include <IOKit/firewire/IOFWCommand.h>
        !            39: #include <IOKit/firewire/IOFireWireDevice.h>
        !            40: 
        !            41: static void FWCSRROMDisposeLeafEntryData(CSRROMEntryDataPtr pCSRROMEntryData);
        !            42: static void FWCSRROMDisposeEntryData(CSRROMEntryDataPtr pCSRROMEntryData);
        !            43: 
        !            44: 
        !            45: ////////////////////////////////////////////////////////////////////////////////
        !            46: //
        !            47: // FWCSRROMCreateDirectoryEntryData
        !            48: //
        !            49: //   Create a local directory entry data record.
        !            50: //
        !            51: 
        !            52: static IOReturn        FWCSRROMCreateDirectoryEntryData(
        !            53:        CSRROMDirectoryDataPtr          pParentCSRROMDirectoryData,
        !            54:        CSRROMEntryDataPtr                      *ppCSRROMEntryData,
        !            55:        UInt32                                          entryKeyValue)
        !            56: {
        !            57:     CSRROMDirectoryDataPtr     pCSRROMDirectoryData;
        !            58:     IOReturn                   status = kIOReturnSuccess;
        !            59: 
        !            60:     // Allocate memory for entry data record.
        !            61:     pCSRROMDirectoryData =
        !            62:             (CSRROMDirectoryDataPtr) IOMalloc (sizeof (CSRROMDirectoryData));
        !            63:     if (pCSRROMDirectoryData == NULL)
        !            64:             status = kIOReturnNoMemory;
        !            65: 
        !            66:     // Fill in entry data record fields.
        !            67:     if (status == kIOReturnSuccess) {
        !            68:         // Copy parent's FWIM.
        !            69:         //pCSRROMDirectoryData->csrROMEntryData.fwimID =
        !            70:         //        pParentCSRROMDirectoryData->csrROMEntryData.fwimID;
        !            71: 
        !            72:         // Set entry type and key value.
        !            73:         pCSRROMDirectoryData->csrROMEntryData.entryType = kDirectoryCSRROMEntryType;
        !            74:         pCSRROMDirectoryData->csrROMBasicEntryData.keyValue = entryKeyValue;
        !            75: 
        !            76:         // Fill in entry data.
        !            77:         pCSRROMDirectoryData->pChildCSRROMEntryData = NULL;
        !            78:         pCSRROMDirectoryData->numChildren = 0;
        !            79:     }
        !            80: 
        !            81:     // Return results.
        !            82:     if (status == kIOReturnSuccess)
        !            83:         *ppCSRROMEntryData = (CSRROMEntryDataPtr) pCSRROMDirectoryData;
        !            84:     else
        !            85:         *ppCSRROMEntryData = NULL;
        !            86: 
        !            87:     return (status);
        !            88: }
        !            89: 
        !            90: ////////////////////////////////////////////////////////////////////////////////
        !            91: //
        !            92: // FWCSRROMCreateImmediateEntryData
        !            93: //
        !            94: //   Create a local immediate entry data record.
        !            95: //
        !            96: 
        !            97: static IOReturn        FWCSRROMCreateImmediateEntryData(
        !            98:        CSRROMDirectoryDataPtr          pParentCSRROMDirectoryData,
        !            99:        CSRROMEntryDataPtr              *ppCSRROMEntryData,
        !           100:        UInt32                          entryKeyValue,
        !           101:        UInt8 *                         pEntryData)
        !           102: {
        !           103:        CSRROMImmediateDataPtr          pCSRROMImmediateData;
        !           104:        IOReturn                        status = kIOReturnSuccess;
        !           105: 
        !           106:        // Allocate memory for entry data record.
        !           107:        pCSRROMImmediateData =
        !           108:                (CSRROMImmediateDataPtr) IOMalloc (sizeof (CSRROMImmediateData));
        !           109:        if (pCSRROMImmediateData == NULL)
        !           110:             status = kIOReturnNoMemory;
        !           111: 
        !           112:        // Fill in entry data record fields.
        !           113:        if (status == kIOReturnSuccess) {
        !           114:             // Copy parent's FWIM.
        !           115:             //pCSRROMImmediateData->csrROMEntryData.fwimID =
        !           116:             //        pParentCSRROMDirectoryData->csrROMEntryData.fwimID;
        !           117: 
        !           118:             // Set entry type and key value.
        !           119:             pCSRROMImmediateData->csrROMEntryData.entryType = kImmediateCSRROMEntryType;
        !           120:             pCSRROMImmediateData->csrROMBasicEntryData.keyValue = entryKeyValue;
        !           121: 
        !           122:             // Fill in entry data.
        !           123:             pCSRROMImmediateData->immediateData = (*((UInt32 *) pEntryData)) >> 8;
        !           124:        }
        !           125: 
        !           126:        // Return results.
        !           127:        if (status == kIOReturnSuccess)
        !           128:             *ppCSRROMEntryData = (CSRROMEntryDataPtr) pCSRROMImmediateData;
        !           129:        else
        !           130:             *ppCSRROMEntryData = NULL;
        !           131: 
        !           132:        return (status);
        !           133: }
        !           134: 
        !           135: ////////////////////////////////////////////////////////////////////////////////
        !           136: //
        !           137: // FWCSRROMCreateLeafEntryData
        !           138: //
        !           139: //   Create a local leaf entry data record.
        !           140: //
        !           141: 
        !           142: static IOReturn        FWCSRROMCreateLeafEntryData(
        !           143:        CSRROMDirectoryDataPtr          pParentCSRROMDirectoryData,
        !           144:        CSRROMEntryDataPtr              *ppCSRROMEntryData,
        !           145:        UInt32                          entryKeyValue,
        !           146:        UInt8 *                         pEntryData,
        !           147:        UInt32                          entrySize)
        !           148: {
        !           149:     CSRROMLeafDataPtr  pCSRROMLeafData = NULL;
        !           150:     UInt8 *            leafStorage;
        !           151:     UInt32             leafDataSize;
        !           152:     IOReturn           status = kIOReturnSuccess;
        !           153: 
        !           154:     // Allocate memory for entry data record.
        !           155:     pCSRROMLeafData = (CSRROMLeafDataPtr) IOMalloc (sizeof (CSRROMLeafData));
        !           156:     if (pCSRROMLeafData == NULL)
        !           157:         status = kIOReturnNoMemory;
        !           158: 
        !           159:     // Allocate leaf storage.
        !           160:     if (status == kIOReturnSuccess) {
        !           161:         leafDataSize = (entrySize + 3) & (~0x03);
        !           162:         leafStorage = (UInt8 *)IOMalloc (leafDataSize);
        !           163:         if (leafStorage != NULL) {
        !           164:             *((UInt32 *) (leafStorage + leafDataSize - 4)) = 0;
        !           165:             pCSRROMLeafData->leafData = leafStorage;
        !           166:             pCSRROMLeafData->leafDataSize = leafDataSize;
        !           167:         }
        !           168:         else
        !           169:             status = kIOReturnNoMemory;
        !           170:     }
        !           171: 
        !           172:     // Fill in entry data record fields.
        !           173:     if (status == kIOReturnSuccess) {
        !           174:         // Copy parent's FWIM.
        !           175:         //pCSRROMLeafData->csrROMEntryData.fwimID =
        !           176:         //        pParentCSRROMDirectoryData->csrROMEntryData.fwimID;
        !           177: 
        !           178:         // Set entry type and key value.
        !           179:         pCSRROMLeafData->csrROMEntryData.entryType = kLeafCSRROMEntryType;
        !           180:         pCSRROMLeafData->csrROMBasicEntryData.keyValue = entryKeyValue;
        !           181: 
        !           182:         // Fill in entry data.
        !           183:         bcopy (pEntryData, pCSRROMLeafData->leafData, entrySize);
        !           184:     }
        !           185: 
        !           186:     // Clean up on error.
        !           187:     if (status != kIOReturnSuccess) {
        !           188:         if (pCSRROMLeafData != NULL)
        !           189:             FWCSRROMDisposeLeafEntryData ((CSRROMEntryDataPtr) pCSRROMLeafData);
        !           190:     }
        !           191: 
        !           192:     // Return results.
        !           193:     if (status == kIOReturnSuccess)
        !           194:         *ppCSRROMEntryData = (CSRROMEntryDataPtr) pCSRROMLeafData;
        !           195:     else
        !           196:         *ppCSRROMEntryData = NULL;
        !           197: 
        !           198:     return (status);
        !           199: }
        !           200: 
        !           201: 
        !           202: ////////////////////////////////////////////////////////////////////////////////
        !           203: //
        !           204: // FWCSRROMCreateOffsetEntryData
        !           205: //
        !           206: //   Create a local offset entry data record.
        !           207: //
        !           208: 
        !           209: static IOReturn        FWCSRROMCreateOffsetEntryData(
        !           210:        CSRROMDirectoryDataPtr  pParentCSRROMDirectoryData,
        !           211:        CSRROMEntryDataPtr      *ppCSRROMEntryData,
        !           212:        UInt32                  entryKeyValue,
        !           213:        FWAddressPtr            pFWAddress)
        !           214: {
        !           215:     CSRROMOffsetDataPtr        pCSRROMOffsetData;
        !           216:     IOReturn           status = kIOReturnSuccess;
        !           217: 
        !           218:     // Check address range and alignment.
        !           219:     if ((pFWAddress->addressHi != kCSRRegisterSpaceBaseAddressHi) ||
        !           220:         (pFWAddress->addressLo < kCSRROMBaseAddress) ||
        !           221:         (pFWAddress->addressLo >= 0xF4000000)) {
        !           222:         status = kIOReturnBadArgument;
        !           223:     }
        !           224:     else if ((pFWAddress->addressLo & 0x03) != 0) {
        !           225:         status = kIOReturnNotAligned;
        !           226:     }
        !           227: 
        !           228:     // Allocate memory for entry data record.
        !           229:     if (status == kIOReturnSuccess) {
        !           230:         pCSRROMOffsetData =
        !           231:                 (CSRROMOffsetDataPtr) IOMalloc (sizeof (CSRROMOffsetData));
        !           232:         if (pCSRROMOffsetData == NULL)
        !           233:             status = kIOReturnNoMemory;
        !           234:     }
        !           235: 
        !           236:     // Fill in entry data record fields.
        !           237:     if (status == kIOReturnSuccess) {
        !           238:         // Copy parent's FWIM.
        !           239:         //pCSRROMOffsetData->csrROMEntryData.fwimID =
        !           240:         //        pParentCSRROMDirectoryData->csrROMEntryData.fwimID;
        !           241: 
        !           242:         // Set entry type and key value.
        !           243:         pCSRROMOffsetData->csrROMEntryData.entryType = kOffsetCSRROMEntryType;
        !           244:         pCSRROMOffsetData->csrROMBasicEntryData.keyValue = entryKeyValue;
        !           245: 
        !           246:         // Fill in entry data.
        !           247:         pCSRROMOffsetData->address = pFWAddress->addressLo;
        !           248:     }
        !           249: 
        !           250:     // Return results.
        !           251:     if (status == kIOReturnSuccess)
        !           252:         *ppCSRROMEntryData = (CSRROMEntryDataPtr) pCSRROMOffsetData;
        !           253:     else
        !           254:         *ppCSRROMEntryData = NULL;
        !           255: 
        !           256:     return (status);
        !           257: }
        !           258: 
        !           259: ////////////////////////////////////////////////////////////////////////////////
        !           260: //
        !           261: // FWCSRROMDisposeDirectoryEntryData
        !           262: //
        !           263: //   Dispose of a local directory entry data record.
        !           264: //
        !           265: 
        !           266: static void FWCSRROMDisposeDirectoryEntryData(CSRROMEntryDataPtr pCSRROMEntryData)
        !           267: {
        !           268:     CSRROMDirectoryDataPtr             pCSRROMDirectoryData;
        !           269:     CSRROMEntryDataPtr         pChildCSRROMEntryData, pNextCSRROMEntryData;
        !           270:     UInt32                             numChildren, childNum;
        !           271: 
        !           272:     if (pCSRROMEntryData != NULL) {
        !           273:         // Recast entry data.
        !           274:         pCSRROMDirectoryData = (CSRROMDirectoryDataPtr) pCSRROMEntryData;
        !           275: 
        !           276:         // Deallocate all children entry data records.
        !           277:         pChildCSRROMEntryData = pCSRROMDirectoryData->pChildCSRROMEntryData;
        !           278:         numChildren = pCSRROMDirectoryData->numChildren;
        !           279:         for (childNum = 0; childNum < numChildren; childNum++) {
        !           280:             // Get next child entry data record.
        !           281:             pNextCSRROMEntryData = pChildCSRROMEntryData->pNextCSRROMEntryData;
        !           282: 
        !           283:             // Deallocate current child entry data record.
        !           284:             FWCSRROMDisposeEntryData (pChildCSRROMEntryData);
        !           285: 
        !           286:             // Go to next child entry data.
        !           287:             pChildCSRROMEntryData = pNextCSRROMEntryData;
        !           288:         }
        !           289: 
        !           290:         // Deallocate memory for entry data record.
        !           291:         IOFree(pCSRROMEntryData, sizeof(CSRROMDirectoryData));
        !           292:     }
        !           293: }
        !           294: 
        !           295: ////////////////////////////////////////////////////////////////////////////////
        !           296: //
        !           297: // FWCSRROMDisposeImmediateEntryData
        !           298: //
        !           299: //   Dispose of a local immediate entry data record.
        !           300: //
        !           301: 
        !           302: static void FWCSRROMDisposeImmediateEntryData(CSRROMEntryDataPtr pCSRROMEntryData)
        !           303: {
        !           304:     // Deallocate memory for entry data record.
        !           305:     if (pCSRROMEntryData != NULL)
        !           306:         IOFree (pCSRROMEntryData, sizeof(CSRROMImmediateData));
        !           307: }
        !           308: 
        !           309: ////////////////////////////////////////////////////////////////////////////////
        !           310: //
        !           311: // FWCSRROMDisposeLeafEntryData
        !           312: //
        !           313: //   Dispose of a local leaf entry data record.
        !           314: //
        !           315: 
        !           316: static void FWCSRROMDisposeLeafEntryData(CSRROMEntryDataPtr pCSRROMEntryData)
        !           317: {
        !           318:     CSRROMLeafDataPtr                  pCSRROMLeafData;
        !           319:     if (pCSRROMEntryData != NULL) {
        !           320:         // Recast entry data.
        !           321:         pCSRROMLeafData = (CSRROMLeafDataPtr) pCSRROMEntryData;
        !           322: 
        !           323:         // Deallocate leaf data storage.
        !           324:         if (pCSRROMLeafData->leafData != NULL)
        !           325:             IOFree(pCSRROMLeafData->leafData, pCSRROMLeafData->leafDataSize);
        !           326: 
        !           327:         // Deallocate memory for entry data record.
        !           328:         IOFree(pCSRROMEntryData, sizeof(CSRROMLeafData));
        !           329:     }
        !           330: }
        !           331: 
        !           332: ////////////////////////////////////////////////////////////////////////////////
        !           333: //
        !           334: // FWCSRROMDisposeOffsetEntryData
        !           335: //
        !           336: //   Dispose of a local offset entry data record.
        !           337: //
        !           338: 
        !           339: static void FWCSRROMDisposeOffsetEntryData(CSRROMEntryDataPtr pCSRROMEntryData)
        !           340: {
        !           341:     // Deallocate memory for entry data record.
        !           342:     if (pCSRROMEntryData != NULL)
        !           343:         IOFree (pCSRROMEntryData, sizeof(CSRROMOffsetData));
        !           344: }
        !           345: 
        !           346: 
        !           347: ////////////////////////////////////////////////////////////////////////////////
        !           348: //
        !           349: // FWCSRROMDisposeEntryData
        !           350: //
        !           351: //   Dispose of a local entry data record.
        !           352: //
        !           353: 
        !           354: static void FWCSRROMDisposeEntryData(CSRROMEntryDataPtr pCSRROMEntryData)
        !           355: {
        !           356:     if (pCSRROMEntryData != NULL) {
        !           357:         switch (pCSRROMEntryData->entryType) {
        !           358:         case kImmediateCSRROMEntryType :
        !           359:             FWCSRROMDisposeImmediateEntryData (pCSRROMEntryData);
        !           360:             break;
        !           361: 
        !           362:         case kOffsetCSRROMEntryType :
        !           363:             FWCSRROMDisposeOffsetEntryData (pCSRROMEntryData);
        !           364:             break;
        !           365: 
        !           366:         case kLeafCSRROMEntryType :
        !           367:             FWCSRROMDisposeLeafEntryData (pCSRROMEntryData);
        !           368:             break;
        !           369: 
        !           370:         case kDirectoryCSRROMEntryType :
        !           371:             FWCSRROMDisposeDirectoryEntryData (pCSRROMEntryData);
        !           372:             break;
        !           373: 
        !           374:         default :
        !           375:                   break;
        !           376:         }
        !           377:     }
        !           378: }
        !           379: 
        !           380: 
        !           381: ////////////////////////////////////////////////////////////////////////////////
        !           382: //
        !           383: // FWCSRROMInsertEntryData
        !           384: //
        !           385: //   This routine inserts a CSR ROM entry data record into the local CSR ROM
        !           386: // tree.
        !           387: //
        !           388: 
        !           389: static void FWCSRROMInsertEntryData(
        !           390:        CSRROMDirectoryDataPtr          pParentCSRROMDirectoryData,
        !           391:        CSRROMEntryDataPtr                      pCSRROMEntryData)
        !           392: {
        !           393:     CSRROMEntryDataPtr pFirstCSRROMEntryData, pPrevCSRROMEntryData, pNextCSRROMEntryData;
        !           394: 
        !           395:     // Get the first entry data record in the parent directory's list.
        !           396:     pFirstCSRROMEntryData = pParentCSRROMDirectoryData->pChildCSRROMEntryData;
        !           397: 
        !           398:     // Insert entry into list.
        !           399:     if (pFirstCSRROMEntryData != NULL) {
        !           400:         pPrevCSRROMEntryData = pFirstCSRROMEntryData->pPrevCSRROMEntryData;
        !           401:         pNextCSRROMEntryData = pFirstCSRROMEntryData;
        !           402: 
        !           403:         pPrevCSRROMEntryData->pNextCSRROMEntryData = pCSRROMEntryData;
        !           404:         pCSRROMEntryData->pPrevCSRROMEntryData = pPrevCSRROMEntryData;
        !           405: 
        !           406:         pNextCSRROMEntryData->pPrevCSRROMEntryData = pCSRROMEntryData;
        !           407:         pCSRROMEntryData->pNextCSRROMEntryData = pNextCSRROMEntryData;
        !           408:     }
        !           409:     else {
        !           410:         pParentCSRROMDirectoryData->pChildCSRROMEntryData = pCSRROMEntryData;
        !           411: 
        !           412:         pCSRROMEntryData->pPrevCSRROMEntryData = pCSRROMEntryData;
        !           413:         pCSRROMEntryData->pNextCSRROMEntryData = pCSRROMEntryData;
        !           414:     }
        !           415: 
        !           416:     pCSRROMEntryData->pParentCSRROMEntryData = (CSRROMEntryDataPtr) pParentCSRROMDirectoryData;
        !           417:     pParentCSRROMDirectoryData->numChildren++;
        !           418: }
        !           419: 
        !           420: ////////////////////////////////////////////////////////////////////////////////
        !           421: //
        !           422: // FWCSRROMEntrySize
        !           423: //
        !           424: // Calculate size of entry (including children)
        !           425: //
        !           426: 
        !           427: static int FWCSRROMEntrySize(CSRROMEntryDataPtr        pCSRROMEntryData)
        !           428: {
        !           429:     CSRROMEntryDataPtr         pChildCSRROMEntryData;
        !           430:     CSRROMLeafDataPtr          pCSRROMLeafData;
        !           431:     CSRROMDirectoryDataPtr     pCSRROMDirectoryData;
        !           432:     UInt32                     numChildren;
        !           433:     UInt32                     i;
        !           434:     int                                size = 0;
        !           435: 
        !           436:     // Compute entry key type, value, and data.
        !           437:     switch (pCSRROMEntryData->entryType) {
        !           438:         case kImmediateCSRROMEntryType :
        !           439:             break;
        !           440: 
        !           441:         case kOffsetCSRROMEntryType :
        !           442:             break;
        !           443: 
        !           444:         case kLeafCSRROMEntryType :
        !           445:             pCSRROMLeafData = (CSRROMLeafDataPtr) pCSRROMEntryData;
        !           446:             size = (pCSRROMLeafData->leafDataSize >> 2) + 1;
        !           447:             break;
        !           448: 
        !           449:         case kDirectoryCSRROMEntryType :
        !           450:             pCSRROMDirectoryData = (CSRROMDirectoryDataPtr) pCSRROMEntryData;
        !           451:             numChildren = pCSRROMDirectoryData->numChildren;
        !           452:             size = 1;
        !           453: 
        !           454:             pChildCSRROMEntryData = pCSRROMDirectoryData->pChildCSRROMEntryData;
        !           455:             size += numChildren;
        !           456:             for (i = 0; i < numChildren; i++) {
        !           457:                 size += FWCSRROMEntrySize(pChildCSRROMEntryData);
        !           458:                 pChildCSRROMEntryData = pChildCSRROMEntryData->pNextCSRROMEntryData;
        !           459:             }
        !           460: 
        !           461:             break;
        !           462: 
        !           463:         default :
        !           464:             //zzz should we do anything on error?
        !           465:             break;
        !           466:     }
        !           467: 
        !           468:     return (size);
        !           469: }
        !           470: 
        !           471: ////////////////////////////////////////////////////////////////////////////////
        !           472: //
        !           473: // FWCSRROMInstantiateEntry
        !           474: //
        !           475: //   Instantiate and entry in the local CSR ROM.
        !           476: //
        !           477: 
        !           478: static void FWCSRROMInstantiateEntry(CSRROMEntryDataPtr pCSRROMEntryData,
        !           479:        UInt32  **ppCSRROMStorage, UInt32 *pEntryLocation)
        !           480: {
        !           481:     CSRROMEntryDataPtr         pChildCSRROMEntryData;
        !           482:     CSRROMImmediateDataPtr     pCSRROMImmediateData;
        !           483:     CSRROMOffsetDataPtr                pCSRROMOffsetData;
        !           484:     CSRROMLeafDataPtr          pCSRROMLeafData;
        !           485:     CSRROMDirectoryDataPtr     pCSRROMDirectoryData;
        !           486:     UInt32                     *pCSRROMStorage = *ppCSRROMStorage;
        !           487:     UInt32                     *pCSRROMDirectoryStorage;
        !           488:     UInt32                     *pHeader;
        !           489:     UInt32                     crc16;
        !           490:     UInt32                     entryOffset;
        !           491:     UInt32                     entryValue;
        !           492:     UInt32                     entryKeyType, entryKeyValue;
        !           493:     UInt32                     numChildren;
        !           494:     UInt32                     i;
        !           495: 
        !           496:     // Compute entry key type, value, and data.
        !           497:     switch (pCSRROMEntryData->entryType) {
        !           498:         case kImmediateCSRROMEntryType :
        !           499:             pCSRROMImmediateData = (CSRROMImmediateDataPtr) pCSRROMEntryData;
        !           500:             entryKeyType = kCSRImmediateKeyType;
        !           501:             entryKeyValue = pCSRROMImmediateData->csrROMBasicEntryData.keyValue;
        !           502:             entryValue = pCSRROMImmediateData->immediateData;
        !           503:             *pEntryLocation =
        !           504:                     ((entryKeyType << kCSREntryKeyTypePhase) & kCSREntryKeyType) |
        !           505:                     ((entryKeyValue << kCSREntryKeyValuePhase) & kCSREntryKeyValue) |
        !           506:                     ((entryValue << kCSREntryValuePhase) & kCSREntryValue);
        !           507:             break;
        !           508: 
        !           509:         case kOffsetCSRROMEntryType :
        !           510:             pCSRROMOffsetData = (CSRROMOffsetDataPtr) pCSRROMEntryData;
        !           511:             entryKeyType = kCSROffsetKeyType;
        !           512:             entryKeyValue = pCSRROMOffsetData->csrROMBasicEntryData.keyValue;
        !           513:             entryOffset =
        !           514:                     (pCSRROMOffsetData->address - kCSRRegisterSpaceBaseAddressLo) >> 2;
        !           515:             *pEntryLocation =
        !           516:                     ((entryKeyType << kCSREntryKeyTypePhase) & kCSREntryKeyType) |
        !           517:                     ((entryKeyValue << kCSREntryKeyValuePhase) & kCSREntryKeyValue) |
        !           518:                     ((entryOffset << kCSREntryValuePhase) & kCSREntryValue);
        !           519:             break;
        !           520: 
        !           521:         case kLeafCSRROMEntryType :
        !           522:             pCSRROMLeafData = (CSRROMLeafDataPtr) pCSRROMEntryData;
        !           523:             entryKeyType = kCSRLeafKeyType;
        !           524:             entryKeyValue = pCSRROMLeafData->csrROMBasicEntryData.keyValue;
        !           525:             entryOffset = pCSRROMStorage - pEntryLocation;
        !           526:             *pEntryLocation =
        !           527:                     ((entryKeyType << kCSREntryKeyTypePhase) & kCSREntryKeyType) |
        !           528:                     ((entryKeyValue << kCSREntryKeyValuePhase) & kCSREntryKeyValue) |
        !           529:                     ((entryOffset << kCSREntryValuePhase) & kCSREntryValue);
        !           530: 
        !           531:             crc16 = FWComputeCRC16 ((UInt32 *) pCSRROMLeafData->leafData,
        !           532:                                                             pCSRROMLeafData->leafDataSize/4);
        !           533: 
        !           534:             *pCSRROMStorage++ =
        !           535:                     (((pCSRROMLeafData->leafDataSize >> 2) << kCSRLeafDirLengthPhase) &
        !           536:                                 kCSRLeafDirLength) |
        !           537:                     ((crc16 << kCSRLeafDirCRCPhase) & kCSRLeafDirCRC);
        !           538: 
        !           539:             bcopy(pCSRROMLeafData->leafData, pCSRROMStorage, pCSRROMLeafData->leafDataSize);
        !           540:             pCSRROMStorage =
        !           541:                     (UInt32 *) ((UInt8 *) pCSRROMStorage + pCSRROMLeafData->leafDataSize);
        !           542:             break;
        !           543: 
        !           544:         case kDirectoryCSRROMEntryType :
        !           545:             pCSRROMDirectoryData = (CSRROMDirectoryDataPtr) pCSRROMEntryData;
        !           546:             entryKeyType = kCSRDirectoryKeyType;
        !           547:             entryKeyValue = pCSRROMDirectoryData->csrROMBasicEntryData.keyValue;
        !           548:             entryOffset = pCSRROMStorage - pEntryLocation;
        !           549:             if (pEntryLocation != NULL) {
        !           550:                     *pEntryLocation =
        !           551:                             ((entryKeyType << kCSREntryKeyTypePhase) & kCSREntryKeyType) |
        !           552:                             ((entryKeyValue << kCSREntryKeyValuePhase) & kCSREntryKeyValue) |
        !           553:                             ((entryOffset << kCSREntryValuePhase) & kCSREntryValue);
        !           554:             }
        !           555: 
        !           556:             numChildren = pCSRROMDirectoryData->numChildren;
        !           557:             pHeader = pCSRROMStorage;
        !           558:             pCSRROMStorage++;
        !           559: 
        !           560:             pChildCSRROMEntryData = pCSRROMDirectoryData->pChildCSRROMEntryData;
        !           561:             pCSRROMDirectoryStorage = pCSRROMStorage;
        !           562:             pCSRROMStorage += numChildren;
        !           563:             for (i = 0; i < numChildren; i++) {
        !           564:                 FWCSRROMInstantiateEntry (pChildCSRROMEntryData, &pCSRROMStorage, pCSRROMDirectoryStorage++);
        !           565:                 pChildCSRROMEntryData = pChildCSRROMEntryData->pNextCSRROMEntryData;
        !           566:             }
        !           567: 
        !           568:             crc16 = FWComputeCRC16 (pHeader + 1, numChildren);
        !           569:             *pHeader =
        !           570:                     ((numChildren << kCSRLeafDirLengthPhase) & kCSRLeafDirLength) |
        !           571:                     ((crc16 << kCSRLeafDirCRCPhase) & kCSRLeafDirCRC);
        !           572: 
        !           573:             break;
        !           574: 
        !           575:         default :
        !           576:             //zzz should we do anything on error?
        !           577:             break;
        !           578:     }
        !           579: 
        !           580:     // Update ROM storage.
        !           581:     *ppCSRROMStorage = pCSRROMStorage;
        !           582: }
        !           583: 
        !           584: ////////////////////////////////////////////////////////////////////////////////
        !           585: //
        !           586: // CSRROMGetRootDirectory
        !           587: //
        !           588: //   Return the Entry ID of the root directory for our ROM.
        !           589: //
        !           590: 
        !           591: IOReturn IOFireWireController::CSRROMGetRootDirectory(CSRROMEntryID *pCSRROMEntryID)
        !           592: {
        !           593:     CSRROMEntryID                              csrROMEntryID;
        !           594:     CSRROMEntryIDDataPtr               pCSRROMEntryIDData;
        !           595:     CSRROMLocalIDDataPtr               pCSRROMLocalIDData;
        !           596:     IOReturn                   status = kIOReturnSuccess;
        !           597: 
        !           598:     // Get the output entry ID and allocate if invalid.
        !           599:     csrROMEntryID = *pCSRROMEntryID;
        !           600:     if (csrROMEntryID == kInvalidCSRROMEntryID) {
        !           601:         csrROMEntryID = FWCSRROMCreateEntryID ();
        !           602:         if (csrROMEntryID == kInvalidCSRROMEntryID)
        !           603:                 status = kIOReturnNoMemory;
        !           604:     }
        !           605: 
        !           606:     // Set to root directory.
        !           607:     if (status == kIOReturnSuccess) {
        !           608:         pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) csrROMEntryID;
        !           609:         // Invalidate output entry ID type if it's not local.
        !           610:         if ((pCSRROMEntryIDData->entryType != kInvalidCSRROMEntryIDType) &&
        !           611:                 (pCSRROMEntryIDData->entryType != kLocalCSRROMEntryIDType)) {
        !           612:             FWCSRROMInvalidateEntryIDType (csrROMEntryID);
        !           613:         }
        !           614: 
        !           615:         // Recast entry ID data.
        !           616:         pCSRROMLocalIDData = (CSRROMLocalIDDataPtr) pCSRROMEntryIDData;
        !           617: 
        !           618:         // Make entry ID reference local root directory.
        !           619:         pCSRROMLocalIDData->csrROMEntryIDData.entryType = kLocalCSRROMEntryIDType;
        !           620:         pCSRROMLocalIDData->pCSRROMEntryData =
        !           621:                 (CSRROMEntryDataPtr) &fCSRROMRootDirectory;
        !           622:         *pCSRROMEntryID = csrROMEntryID;
        !           623:     }
        !           624:     return (status);
        !           625: }
        !           626: 
        !           627: ////////////////////////////////////////////////////////////////////////////////
        !           628: //
        !           629: // CSRROMCreateEntry
        !           630: //
        !           631: //   Create an entry in the local CSR Configuration ROM.
        !           632: //
        !           633: 
        !           634: IOReturn IOFireWireController::CSRROMCreateEntry(
        !           635:        CSRROMEntryID parentCSRROMEntryID, CSRROMEntryID *pCSRROMEntryID,
        !           636:        UInt32 entryType, UInt32 entryKeyValue, void *entryData, UInt32 entrySize)
        !           637: {
        !           638:     CSRROMEntryID              csrROMEntryID;
        !           639:     CSRROMEntryIDDataPtr       pCSRROMEntryIDData;
        !           640:     CSRROMLocalIDDataPtr       pParentCSRROMLocalIDData;
        !           641:     CSRROMLocalIDDataPtr       pCSRROMLocalIDData;
        !           642:     CSRROMDirectoryDataPtr     pParentCSRROMDirectoryData;
        !           643:     CSRROMEntryDataPtr         pNewCSRROMEntryData = NULL;
        !           644:     bool                       csrROMEntryIDAllocated = false;
        !           645:     IOReturn                   status = kIOReturnSuccess;
        !           646: 
        !           647:     // Get and validate parent directory.
        !           648:     pParentCSRROMLocalIDData = (CSRROMLocalIDDataPtr) parentCSRROMEntryID;
        !           649:     if (pParentCSRROMLocalIDData->csrROMEntryIDData.entryType == kLocalCSRROMEntryIDType) {
        !           650:         pParentCSRROMDirectoryData =
        !           651:                 (CSRROMDirectoryDataPtr) pParentCSRROMLocalIDData->pCSRROMEntryData;
        !           652:         if (pParentCSRROMDirectoryData->csrROMEntryData.entryType != kDirectoryCSRROMEntryType)
        !           653:             status = kIOReturnBadArgument;
        !           654:     }
        !           655:     else {
        !           656:         status = kIOReturnBadArgument;
        !           657:     }
        !           658: 
        !           659:     // Get the output entry ID and allocate if invalid.
        !           660:     if (status == kIOReturnSuccess) {
        !           661:         csrROMEntryID = *pCSRROMEntryID;
        !           662:         if (csrROMEntryID == kInvalidCSRROMEntryID) {
        !           663:             csrROMEntryID = FWCSRROMCreateEntryID ();
        !           664:             if (csrROMEntryID != kInvalidCSRROMEntryID)
        !           665:                 csrROMEntryIDAllocated = true;
        !           666:             else
        !           667:                 status = kIOReturnNoMemory;
        !           668:         }
        !           669: 
        !           670:         if (csrROMEntryID != kInvalidCSRROMEntryID)
        !           671:             pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) csrROMEntryID;
        !           672:     }
        !           673: 
        !           674:     // If output entry ID is not local, invalidate it.
        !           675:     if (status == kIOReturnSuccess) {
        !           676:         if ((pCSRROMEntryIDData->entryType != kInvalidCSRROMEntryIDType) &&
        !           677:                 (pCSRROMEntryIDData->entryType != kLocalCSRROMEntryIDType)) {
        !           678:             FWCSRROMInvalidateEntryIDType (csrROMEntryID);
        !           679:         }
        !           680:     }
        !           681: 
        !           682:     // Create the requested type of entry data record.
        !           683:     if (status == kIOReturnSuccess) {
        !           684:         switch (entryType) {
        !           685:             case kImmediateCSRROMEntryType :
        !           686:                 status = FWCSRROMCreateImmediateEntryData (pParentCSRROMDirectoryData,
        !           687:                                                         &pNewCSRROMEntryData,
        !           688:                                                         entryKeyValue,
        !           689:                                                         (UInt8 *) entryData);
        !           690:                 break;
        !           691: 
        !           692:             case kOffsetCSRROMEntryType :
        !           693:                 status = FWCSRROMCreateOffsetEntryData (pParentCSRROMDirectoryData,
        !           694:                                                         &pNewCSRROMEntryData,
        !           695:                                                         entryKeyValue,
        !           696:                                                         (FWAddressPtr) entryData);
        !           697:                 break;
        !           698: 
        !           699:             case kLeafCSRROMEntryType :
        !           700:                 status = FWCSRROMCreateLeafEntryData (pParentCSRROMDirectoryData,
        !           701:                                                         &pNewCSRROMEntryData,
        !           702:                                                         entryKeyValue,
        !           703:                                                         (UInt8 *) entryData,
        !           704:                                                         entrySize);
        !           705:                 break;
        !           706: 
        !           707:             case kDirectoryCSRROMEntryType :
        !           708:                 status = FWCSRROMCreateDirectoryEntryData (pParentCSRROMDirectoryData,
        !           709:                                                             &pNewCSRROMEntryData,
        !           710:                                                             entryKeyValue);
        !           711:                 break;
        !           712: 
        !           713:             default :
        !           714:                 status = kIOReturnBadArgument;
        !           715:                 break;
        !           716:         }
        !           717:     }
        !           718: 
        !           719:     // Insert new entry into CSR Configuration ROM.
        !           720:     if (status == kIOReturnSuccess)
        !           721:         FWCSRROMInsertEntryData (pParentCSRROMDirectoryData, pNewCSRROMEntryData);
        !           722: 
        !           723:     // Set ID to reference new entry.
        !           724:     if (status == kIOReturnSuccess) {
        !           725:         pCSRROMLocalIDData = (CSRROMLocalIDDataPtr) pCSRROMEntryIDData;
        !           726:         pCSRROMLocalIDData->csrROMEntryIDData.entryType = kLocalCSRROMEntryIDType;
        !           727:         pCSRROMLocalIDData->pCSRROMEntryData = pNewCSRROMEntryData;
        !           728:     }
        !           729: 
        !           730:     // Clean up on error.
        !           731:     if (status != kIOReturnSuccess) {
        !           732:         if (pNewCSRROMEntryData != NULL)
        !           733:             FWCSRROMDisposeEntryData (pNewCSRROMEntryData);
        !           734: 
        !           735:         if (csrROMEntryIDAllocated)
        !           736:             FWCSRROMDisposeEntryID (csrROMEntryID);
        !           737:     }
        !           738: 
        !           739:     // Return results.
        !           740:     if (status == kIOReturnSuccess)
        !           741:         *pCSRROMEntryID = csrROMEntryID;
        !           742: 
        !           743:     return (status);
        !           744: }
        !           745: 
        !           746: ////////////////////////////////////////////////////////////////////////////////
        !           747: //
        !           748: // UpdateROM()
        !           749: //
        !           750: //   Instantiate the local CSR ROM.
        !           751: //   Always causes at least one bus reset.
        !           752: //
        !           753: 
        !           754: IOReturn IOFireWireController::UpdateROM()
        !           755: {
        !           756:     CSRROMDirectoryDataPtr     pCSRROMDirectoryData;
        !           757:     CSRROMImmediateDataPtr     pCSRROMImmediateData;
        !           758:     UInt32                     *pCSRROMStorage;
        !           759:     UInt32                     busInfoBlockSize;
        !           760:     UInt32                     *pHeader;
        !           761:     UInt32                     romSize;
        !           762:     UInt32                     crc16;
        !           763:     OSData *                   rom;
        !           764:     IOReturn                   ret;
        !           765: 
        !           766:     // Update CSR ROM generation.
        !           767:     //zzz assumes first entry is generation value.
        !           768:     pCSRROMDirectoryData = &fCSRROMRootDirectory;
        !           769:     pCSRROMImmediateData =
        !           770:             (CSRROMImmediateDataPtr) pCSRROMDirectoryData->pChildCSRROMEntryData;
        !           771:     if (pCSRROMImmediateData->csrROMBasicEntryData.keyValue == kCSRGenerationKey)
        !           772:             pCSRROMImmediateData->immediateData++;
        !           773: 
        !           774:     busInfoBlockSize = (fROMHeader[0] & kCSRBusInfoBlockLength) >>
        !           775:                                                     kCSRBusInfoBlockLengthPhase;
        !           776:     romSize = FWCSRROMEntrySize((CSRROMEntryDataPtr) pCSRROMDirectoryData) + 
        !           777:        busInfoBlockSize;
        !           778: kprintf("Rom size: %d\n", romSize);
        !           779:     rom = OSData::withCapacity((romSize+1)*4);
        !           780:     if(!rom)
        !           781:        return kIOReturnNoMemory;
        !           782:     pHeader = (UInt32 *)IOMalloc((romSize+1)*4);
        !           783:     if(!pHeader) {
        !           784:         rom->release();
        !           785:        return kIOReturnNoMemory;
        !           786:     }
        !           787: 
        !           788:     // Recursively build configuration ROM.
        !           789:     bcopy(fROMHeader, pHeader, 4*(busInfoBlockSize+1));
        !           790:     pCSRROMStorage = pHeader + busInfoBlockSize + 1;
        !           791:     FWCSRROMInstantiateEntry((CSRROMEntryDataPtr) pCSRROMDirectoryData,
        !           792:                                         &pCSRROMStorage, NULL);
        !           793: 
        !           794:     // Reconstruct Bus Info Block header.
        !           795: 
        !           796:     crc16 = FWComputeCRC16 (pHeader + 1, romSize);
        !           797:     *pHeader =
        !           798:             ((busInfoBlockSize << kCSRBusInfoBlockLengthPhase) & kCSRBusInfoBlockLength) |
        !           799:             ((romSize << kCSRROMCRCLengthPhase) & kCSRROMCRCLength) |
        !           800:             ((crc16 << kCSRROMCRCValuePhase) & kCSRROMCRCValue);
        !           801:     rom->appendBytes(pHeader, (romSize+1)*4);
        !           802:     IOFree(pHeader, (romSize+1)*4);
        !           803:     setProperty(gFireWireROM, rom);
        !           804: 
        !           805:         // If we have a FWIM that is fully FSL 1.1 compatible, use the set CSR ROM function.
        !           806:         // Otherwise just reset the bus.
        !           807: #if 0
        !           808:                 // Tell the FWIM to use this new CSR ROM data (and reset the bus)
        !           809:                 //zzz Should support other (larger) ROM sizes
        !           810:                 status = FWSetCSRROM (pHeader, (romSize+1)*4);
        !           811: #endif
        !           812: kprintf("old romspace: 0x%x\n", fROMAddrSpace);
        !           813:     if(fROMAddrSpace) {
        !           814:         freeAddress(fROMAddrSpace);
        !           815:         fROMAddrSpace->release();
        !           816:         fROMAddrSpace = NULL;
        !           817:     }
        !           818:     fROMAddrSpace = IOFWPseudoAddressSpace::simpleRead(
        !           819:                FWAddress(kCSRRegisterSpaceBaseAddressHi, kCSRROMBaseAddress),
        !           820:                 (romSize+1)*4, rom->getBytesNoCopy());
        !           821:     ret = allocAddress(fROMAddrSpace);
        !           822: 
        !           823:     return (ret);
        !           824: }
        !           825: 

unix.superglobalmegacorp.com

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