Annotation of XNU/iokit/Families/IOFireWire/IOFireWireDevice.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:  * 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: }

unix.superglobalmegacorp.com

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