|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.