|
|
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: * 21 May 99 wgulland created. ! 27: * ! 28: */ ! 29: ! 30: #define DEBUGGING_LEVEL 0 // 1 = low; 2 = high; 3 = extreme ! 31: #define DEBUGLOG kprintf ! 32: #include <IOKit/assert.h> ! 33: ! 34: #include <IOKit/IOMessage.h> ! 35: #include <IOKit/firewire/IOFireWireDevice.h> ! 36: #include <IOKit/firewire/IOFireWireUnit.h> ! 37: #include <IOKit/firewire/IOFireWireController.h> ! 38: ! 39: #define super IOFireWireNub ! 40: ! 41: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 42: ! 43: OSDefineMetaClassAndStructors(IOFireWireDevice, IOFireWireNub) ! 44: ! 45: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 46: ! 47: bool IOFireWireDevice::attach(IOService *provider) ! 48: { ! 49: assert(OSDynamicCast(IOFireWireController, provider)); ! 50: if( !super::attach(provider)) ! 51: return (false); ! 52: fControl = (IOFireWireController *)provider; ! 53: ! 54: return(true); ! 55: } ! 56: ! 57: void IOFireWireDevice::setNodeROM(UInt32 gen, UInt16 nodeID, UInt16 localID, ! 58: OSData *rom, UInt32 *selfIDs, int numSelfIDs) ! 59: { ! 60: OSObject *prop; ! 61: OSArray *strings; ! 62: IOMessage mess; ! 63: int i; ! 64: UInt32 newROMSize; ! 65: const UInt32 *newROM; ! 66: ! 67: fNodeID = nodeID; ! 68: fLocalNodeID = localID; ! 69: fGeneration = gen; ! 70: prop = OSNumber::withNumber(nodeID, 16); ! 71: setProperty(gFireWireNodeID, prop); ! 72: prop->release(); ! 73: ! 74: // Notify clients of current state ! 75: mess = kIOMessageServiceIsResumed; ! 76: if(nodeID == 0xffff) ! 77: mess = kIOMessageServiceIsSuspended; ! 78: messageClients( mess ); ! 79: ! 80: if(!rom) ! 81: return; ! 82: ! 83: // Store selfIDs ! 84: fNumSelfIDs = numSelfIDs; ! 85: for(i=0; i<numSelfIDs; i++) { ! 86: fSelfIDs[i] = selfIDs[i]; ! 87: } ! 88: prop = OSData::withBytes(fSelfIDs, numSelfIDs*sizeof(UInt32)); ! 89: setProperty(gFireWireSelfIDs, prop); ! 90: prop->release(); ! 91: ! 92: // Process new ROM ! 93: ! 94: newROMSize = rom->getLength()/4; ! 95: newROM = (UInt32 *)rom->getBytesNoCopy(); ! 96: ! 97: if(newROMSize == fROMSize) { ! 98: if(!bcmp(newROM, fROM, newROMSize*4)) ! 99: return; // ROM unchanged ! 100: } ! 101: ! 102: setProperty(gFireWireROM, rom); ! 103: fROMSize = newROMSize; ! 104: fROM = newROM; ! 105: ! 106: if(fROMSize > 3) { ! 107: UInt32 vendorID = fROM[3] >> 8; ! 108: prop = OSNumber::withNumber(vendorID, 32); ! 109: setProperty(gFireWireVendor_ID, prop); ! 110: prop->release(); ! 111: } ! 112: if(fROMSize < 6) ! 113: return; // Done. ! 114: ! 115: strings = OSArray::withCapacity(3); ! 116: // search for a unit directory - should create a nub for each one ! 117: //zzz should search for nodes/modules if there are no unit directories. ! 118: CSRROMEntryIterator csrUnitIterator = kInvalidCSRROMIterator; ! 119: CSRROMEntryID csrROMEntryID = kInvalidCSRROMEntryID; ! 120: CSRROMSearchCriteria unitSearchCriteria; ! 121: int doneUnits; ! 122: IOReturn error; ! 123: ! 124: unitSearchCriteria.csrROMSearchType = kCSRROMSearchForKey; ! 125: unitSearchCriteria.keyType = kCSRDirectoryKeyTypeBit; ! 126: unitSearchCriteria.keyHi = kCSRUnitDirectoryKeyHiBit; ! 127: unitSearchCriteria.keyLo = kCSRUnitDirectoryKeyLoBit; ! 128: ! 129: // Create CSR ROM search iterator. ! 130: error = CSRROMCreateIterator (&csrUnitIterator); ! 131: doneUnits = !(error == kIOReturnSuccess); // don't search if we couldn't create the iterator ! 132: ! 133: /////////////////////////////// ! 134: // look for units ! 135: ! 136: while ( !doneUnits ) { ! 137: // Search for a unit directory. ! 138: error = FWCSRROMEntrySearch (csrUnitIterator, ! 139: kIterateContinue, ! 140: &csrROMEntryID, ! 141: &doneUnits, ! 142: &unitSearchCriteria, ! 143: NULL, ! 144: NULL); ! 145: if(error != kIOReturnSuccess) ! 146: doneUnits = true; ! 147: if(doneUnits) ! 148: break; ! 149: ! 150: CSRROMEntryIterator csrROMIterator = NULL; ! 151: CSRROMSearchCriteria searchCriteria; ! 152: UInt32 unitSpecID; ! 153: UInt32 unitSoftwareVersion; ! 154: UInt32 csrROMEntrySize; ! 155: IOReturn status, stat2; ! 156: int done; ! 157: ! 158: //////////////////////////////////////////////////////////////////////////// ! 159: // ! 160: // Get unit spec ID. ! 161: // ! 162: ! 163: // Create a CSR ROM iterator. ! 164: status = CSRROMCreateIterator(&csrROMIterator); ! 165: ! 166: // Set it to unit directory. ! 167: if (status == kIOReturnSuccess) { ! 168: status = FWCSRROMSetIterator(csrROMIterator, csrROMEntryID, kIterateDescendants); ! 169: } ! 170: ! 171: // Search for unit spec ID. ! 172: //zzz what if none preset??? ! 173: if (status == kIOReturnSuccess) { ! 174: searchCriteria.csrROMSearchType = kCSRROMSearchForKey; ! 175: searchCriteria.keyType = kCSRImmediateKeyTypeBit; ! 176: searchCriteria.keyHi = kCSRUnitSpecIdKeyHiBit; ! 177: searchCriteria.keyLo = kCSRUnitSpecIdKeyLoBit; ! 178: csrROMEntrySize = sizeof (UInt32); ! 179: status = ! 180: FWCSRROMEntrySearch ! 181: (csrROMIterator, ! 182: kIterateContinue, ! 183: NULL, ! 184: &done, ! 185: &searchCriteria, ! 186: (UInt8 *) &unitSpecID, ! 187: &csrROMEntrySize); ! 188: ! 189: if ((status == kIOReturnSuccess) && (done)) ! 190: status = kIOReturnNoDevice;//zzz is this right? ! 191: } ! 192: ! 193: // Clean up iterator. ! 194: if (csrROMIterator != kInvalidCSRROMIterator) { ! 195: FWCSRROMDisposeIterator (csrROMIterator); ! 196: csrROMIterator = kInvalidCSRROMIterator; ! 197: } ! 198: ! 199: //////////////////////////////////////////////////////////////////////////// ! 200: // ! 201: // Get unit software version. ! 202: // ! 203: ! 204: // Create a CSR ROM iterator. ! 205: if (status == kIOReturnSuccess) { ! 206: status = CSRROMCreateIterator(&csrROMIterator); ! 207: } ! 208: ! 209: // Set it to unit directory. ! 210: if (status == kIOReturnSuccess){ ! 211: status = FWCSRROMSetIterator ! 212: (csrROMIterator, csrROMEntryID, kIterateDescendants); ! 213: } ! 214: ! 215: // Search for the software version. ! 216: if (status == kIOReturnSuccess) { ! 217: searchCriteria.csrROMSearchType = kCSRROMSearchForKey; ! 218: searchCriteria.keyType = kCSRImmediateKeyTypeBit; ! 219: searchCriteria.keyHi = kCSRUnitSwVersionKeyHiBit; ! 220: searchCriteria.keyLo = kCSRUnitSwVersionKeyLoBit; ! 221: csrROMEntrySize = sizeof (UInt32); ! 222: status = ! 223: FWCSRROMEntrySearch ! 224: (csrROMIterator, ! 225: kIterateContinue, ! 226: NULL, ! 227: &done, ! 228: &searchCriteria, ! 229: (UInt8 *) &unitSoftwareVersion, ! 230: &csrROMEntrySize); ! 231: ! 232: if ((status == kIOReturnSuccess) && (done)) ! 233: status = kIOReturnNoDevice;//zzz is this right? ! 234: } ! 235: ! 236: // Clean up iterator. ! 237: if (csrROMIterator != kInvalidCSRROMIterator) { ! 238: FWCSRROMDisposeIterator (csrROMIterator); ! 239: csrROMIterator = kInvalidCSRROMIterator; ! 240: } ! 241: ! 242: // Search for text strings. ! 243: searchCriteria.csrROMSearchType = kCSRROMSearchForKey; ! 244: searchCriteria.keyType = kCSRLeafKeyTypeBit; ! 245: searchCriteria.keyHi = kCSRTextualDescriptorKeyHiBit; ! 246: searchCriteria.keyLo = kCSRTextualDescriptorKeyLoBit; ! 247: char text[128]; ! 248: done = false; ! 249: // Create a CSR ROM iterator. ! 250: stat2 = CSRROMCreateIterator(&csrROMIterator); ! 251: while (stat2 == kIOReturnSuccess && !done) { ! 252: unsigned int i; ! 253: csrROMEntrySize = sizeof (text)-1; ! 254: stat2 = ! 255: FWCSRROMEntrySearch ! 256: (csrROMIterator, ! 257: kIterateDescendants, ! 258: NULL, ! 259: &done, ! 260: &searchCriteria, ! 261: (UInt8 *) text, ! 262: &csrROMEntrySize); ! 263: if(stat2 == kIOReturnSuccess && !done) { ! 264: // Skip leading zeros in text ! 265: for(i=0; i<csrROMEntrySize; i++) ! 266: if(text[i]) ! 267: break; ! 268: text[csrROMEntrySize] = 0; ! 269: if(strings) { ! 270: OSString * astring = OSString::withCString(text+i); ! 271: if ( astring ) { ! 272: strings->setObject(astring); ! 273: astring->release(); ! 274: } ! 275: } ! 276: } ! 277: ! 278: } ! 279: // Clean up iterator. ! 280: if (csrROMIterator != kInvalidCSRROMIterator) { ! 281: FWCSRROMDisposeIterator (csrROMIterator); ! 282: csrROMIterator = kInvalidCSRROMIterator; ! 283: } ! 284: ! 285: // Add entry to registry. ! 286: if (status == kIOReturnSuccess) { ! 287: OSDictionary * propTable = 0; ! 288: IOFireWireUnit * newDevice = 0; ! 289: do { ! 290: propTable = OSDictionary::withCapacity(5); ! 291: if (!propTable) ! 292: continue; ! 293: /* ! 294: * Set the IOMatchCategory so that things that want to connect to ! 295: * the device still can even if it already has IOFireWireUnits attached ! 296: */ ! 297: prop = OSSymbol::withCString("FireWire Unit"); ! 298: propTable->setObject(gIOMatchCategoryKey, prop); ! 299: prop->release(); ! 300: ! 301: prop = OSNumber::withNumber(unitSpecID, 32); ! 302: propTable->setObject(gFireWireUnit_Spec_ID, prop); ! 303: prop->release(); ! 304: prop = OSNumber::withNumber(unitSoftwareVersion, 32); ! 305: propTable->setObject(gFireWireUnit_SW_Version, prop); ! 306: prop->release(); ! 307: ! 308: // Copy over matching properties from Device ! 309: prop = getProperty(gFireWireVendor_ID); ! 310: if(prop) ! 311: propTable->setObject(gFireWireVendor_ID, prop); ! 312: prop = getProperty(gFireWire_GUID); ! 313: if(prop) ! 314: propTable->setObject(gFireWire_GUID, prop); ! 315: ! 316: newDevice = new IOFireWireUnit; ! 317: ! 318: if (!newDevice || !newDevice->init(propTable)) ! 319: break; ! 320: if (!newDevice->attach(this)) ! 321: break; ! 322: newDevice->registerService(); ! 323: } while (false); ! 324: if(newDevice) ! 325: newDevice->release(); ! 326: if(propTable) ! 327: propTable->release(); ! 328: } ! 329: if(strings) { ! 330: setProperty("Description", strings); ! 331: strings->release(); ! 332: } ! 333: } ! 334: // Clean up iterator and entryID 'object' ! 335: if (csrUnitIterator != kInvalidCSRROMIterator) { ! 336: FWCSRROMDisposeIterator (csrUnitIterator); ! 337: csrUnitIterator = kInvalidCSRROMIterator; ! 338: } ! 339: if(csrROMEntryID != kInvalidCSRROMEntryID) { ! 340: FWCSRROMDisposeEntryID(csrROMEntryID); ! 341: csrROMEntryID = kInvalidCSRROMEntryID; ! 342: } ! 343: ! 344: } ! 345: ! 346: /* ! 347: * Create an iterator for the device ROM ! 348: */ ! 349: IOReturn IOFireWireDevice::CSRROMCreateIterator (CSRROMEntryIterator *pCSRROMIterator) ! 350: { ! 351: CSRROMEntryIteratorRecPtr pIteratorRec; ! 352: UInt32 hdrSize; ! 353: ! 354: // Allocate memory for iterator record. ! 355: pIteratorRec = (CSRROMEntryIteratorRecPtr)IOMalloc (sizeof (CSRROMEntryIteratorRec)); ! 356: if (pIteratorRec == NULL) ! 357: return kIOReturnNoMemory; ! 358: ! 359: // Fill in other record fields. ! 360: // Set relationship to descendants. ! 361: pIteratorRec->relationship = kIterateDescendants; ! 362: // Find start of root directory. ! 363: hdrSize = ((fROM[0] & kCSRBusInfoBlockLength) >> kCSRBusInfoBlockLengthPhase) + 1; ! 364: pIteratorRec->data = fROM; ! 365: pIteratorRec->logicalPath[0] = 0; ! 366: pIteratorRec->physicalPath[0] = hdrSize; ! 367: ! 368: pIteratorRec->logicalPath[1] = 0; ! 369: pIteratorRec->physicalPath[1] = pIteratorRec->physicalPath[0] + 1; ! 370: ! 371: pIteratorRec->pathSize = 2; ! 372: pIteratorRec->reset = true; ! 373: ! 374: // Return iterator. ! 375: *pCSRROMIterator = (CSRROMEntryIterator) pIteratorRec; ! 376: ! 377: return (kIOReturnSuccess); ! 378: } ! 379: ! 380: /** ! 381: ** Matching methods ! 382: **/ ! 383: bool IOFireWireDevice::matchPropertyTable(OSDictionary * table) ! 384: { ! 385: // ! 386: // If the service object wishes to compare some of its properties in its ! 387: // property table against the supplied matching dictionary, ! 388: // it should do so in this method and return truth on success. ! 389: // ! 390: if (!super::matchPropertyTable(table)) return false; ! 391: ! 392: // We return success if the following expression is true -- individual ! 393: // comparisions evaluate to truth if the named property is not present ! 394: // in the supplied matching dictionary. ! 395: ! 396: return compareProperty(table, gFireWireVendor_ID) && ! 397: compareProperty(table, gFireWire_GUID); ! 398: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.