Annotation of XNU/iokit/Families/IOFireWire/IOFireWireDevice.cpp, revision 1.1.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.