Annotation of XNU/iokit/Families/IOFireWire/IOFireWireController.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:  * 27 April 99 wgulland created.
                     27:  *
                     28:  */
                     29: 
                     30: #include <IOKit/assert.h>
                     31: 
                     32: #define DEBUGGING_LEVEL 0      // 1 = low; 2 = high; 3 = extreme
                     33: #define DEBUGLOG kprintf
                     34: 
                     35: #include <IOKit/IOWorkLoop.h>
                     36: #include <IOKit/IOTimerEventSource.h>
                     37: #include <IOKit/IOKitKeys.h>
                     38: 
                     39: #include <IOKit/firewire/IOFireWireController.h>
                     40: #include <IOKit/firewire/IOFWCommand.h>
                     41: #include <IOKit/firewire/IOFireWireDevice.h>
                     42: #include <IOKit/firewire/IOFWDCLProgram.h>
                     43: #include <IOKit/firewire/IOFWLocalIsochPort.h>
                     44: #include <IOKit/firewire/IOFWAddressSpace.h>
                     45: #include <IOKit/IOBufferMemoryDescriptor.h>
                     46: 
                     47: #define kDevicePruneDelay 1000 // 1000 milliseconds
                     48: 
                     49: #define FWAddressToID(addr) (addr & 63)
                     50: 
                     51: const OSSymbol *gFireWireROM;
                     52: const OSSymbol *gFireWireNodeID;
                     53: const OSSymbol *gFireWireSelfIDs;
                     54: const OSSymbol *gFireWireUnit_Spec_ID;
                     55: const OSSymbol *gFireWireUnit_SW_Version;
                     56: const OSSymbol *gFireWireVendor_ID;
                     57: const OSSymbol *gFireWire_GUID;
                     58: const OSSymbol *gFireWireSpeed;
                     59: 
                     60: const IORegistryPlane * IOFireWireController::gIOFireWirePlane = NULL;
                     61: 
                     62: enum ReadROMState {
                     63:     kReadROMSize,
                     64:     kReadingROM
                     65: };
                     66: 
                     67: struct NodeScan {
                     68:     IOFireWireController *     fControl;
                     69:     FWAddress                  fAddr;
                     70:     UInt32 *                   fBuf;
                     71:     UInt32 *                   fSelfIDs;
                     72:     int                                fNumSelfIDs;
                     73:     ReadROMState               fState;
                     74:     IOFWReadQuadCommand *      fCmd;
                     75:     UInt32                     fROMHdr;
                     76:     int                                fROMSize;
                     77:     int                                fRead;
                     78: };
                     79: 
                     80: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                     81: //Utility functions
                     82: 
                     83: #define super IOFireWireBus
                     84: 
                     85: OSDefineMetaClass( IOFireWireController, IOFireWireBus )
                     86: OSDefineAbstractStructors(IOFireWireController, IOFireWireBus)
                     87: 
                     88: static void doneReset(void *refcon, IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd)
                     89: {
                     90:     fwCmd->release();
                     91: }
                     92: 
                     93: void IOFireWireController::readROMGlue(void *refcon, IOReturn status,
                     94:                        IOFireWireNub *device, IOFWCommand *fwCmd)
                     95: {
                     96:     NodeScan *scan = (NodeScan *)refcon;
                     97:     scan->fControl->readDeviceROM(scan, status);
                     98: }
                     99: 
                    100: IOReturn IOFireWireController::execCommand(OSObject * obj, void *field0, 
                    101:                                void *field1, void *field2, void *field3)
                    102: {
                    103:     // obj is the IOFireWireController, if we need that
                    104: 
                    105:     IOFWCommand *cmd = (IOFWCommand *)field0;
                    106: //kprintf("Executing command 0x%x\n", cmd);
                    107:     return cmd->execute();
                    108: }
                    109: 
                    110: void IOFireWireController::clockTick(OSObject *obj, IOTimerEventSource *src)
                    111: {
                    112:     IOFireWireController *me = (IOFireWireController *)obj;
                    113: 
                    114:     me->pruneDevices();
                    115: }
                    116: IOWorkLoop * IOFireWireController::createWorkLoop()
                    117: {
                    118:     IOWorkLoop * wrkLoop;
                    119: 
                    120:     wrkLoop = new IOWorkLoop;
                    121:     if ( wrkLoop == NULL ) {
                    122:         return NULL;
                    123:     }
                    124: 
                    125:     if ( wrkLoop->init() != true ) {
                    126:         return NULL;
                    127:     }
                    128: 
                    129:     return wrkLoop;
                    130: }
                    131: 
                    132: bool IOFireWireController::init(OSDictionary * dict)
                    133: {
                    134:     if(!super::init(dict))
                    135:         return false;
                    136: 
                    137:     // Create firewire symbols.
                    138:     gFireWireROM = OSSymbol::withCString("FireWire Device ROM");
                    139:     gFireWireNodeID = OSSymbol::withCString("FireWire Node ID");
                    140:     gFireWireSelfIDs = OSSymbol::withCString("FireWire Self IDs");
                    141:     gFireWireUnit_Spec_ID = OSSymbol::withCString("Unit_Spec_ID");
                    142:     gFireWireUnit_SW_Version = OSSymbol::withCString("Unit_SW_Version");
                    143:     gFireWireVendor_ID = OSSymbol::withCString("Vendor_ID");
                    144:     gFireWire_GUID = OSSymbol::withCString("GUID");
                    145:     gFireWireSpeed = OSSymbol::withCString("FireWire Speed");
                    146: 
                    147:     if(NULL == gIOFireWirePlane) {
                    148:         gIOFireWirePlane = IORegistryEntry::makePlane( kIOFireWirePlane );
                    149:     }
                    150: 
                    151:     fLocalAddresses = OSSet::withCapacity(3);  // Local ROM + CSR registers + SBP-2 ORBs
                    152:     if(fLocalAddresses)
                    153:         fSpaceIterator =  OSCollectionIterator::withCollection(fLocalAddresses);
                    154: 
                    155:     fAllocatedChannels = OSSet::withCapacity(1);       // DV channel.
                    156:     if(fAllocatedChannels)
                    157:         fAllocChannelIterator =  OSCollectionIterator::withCollection(fAllocatedChannels);
                    158: 
                    159:     fLastTrans = kMaxPendingTransfers-1;
                    160:     fTransAllocLock = IOLockAlloc();
                    161:     fChannelLock = IOLockAlloc();
                    162: 
                    163:     return (gFireWireROM != NULL &&  gFireWireNodeID != NULL &&
                    164:         fChannelLock != NULL && fTransAllocLock != NULL &&
                    165:         gFireWireUnit_Spec_ID != NULL && gFireWireUnit_SW_Version != NULL && 
                    166:        fLocalAddresses != NULL && fSpaceIterator != NULL &&
                    167:             fAllocatedChannels != NULL && fAllocChannelIterator != NULL);
                    168: }
                    169: 
                    170: bool IOFireWireController::startWorkLoop()
                    171: {
                    172:     OSData *rom;
                    173:     UInt16 crc16;
                    174:     IOReturn status;
                    175:     CSRROMEntryID csrROMRootEntryID = kInvalidCSRROMEntryID;
                    176:     CSRROMEntryID csrROMEntryID = kInvalidCSRROMEntryID;
                    177:     UInt32 immediateEntry;
                    178: 
                    179: 
                    180: kprintf("Local GUID = 0x%x:0x%x\n", (UInt32)(fUniqueID >> 32), (UInt32)(fUniqueID & 0xffffffff));
                    181: 
                    182:     // Build local device ROM
                    183:     rom = OSData::withCapacity(20); // smallest possible real ROM
                    184:     if(!rom)
                    185:        return false;
                    186: 
                    187:     // Allocate address space for Configuration ROM and fill in Bus Info
                    188:     // block.
                    189:     fROMHeader[1] = kFWBIBBusName;
                    190:     fROMHeader[2] =
                    191:             kFWBIBIrmc | kFWBIBCmc | kFWBIBIsc | (8 << kFWBIBMaxRecPhase);
                    192:     fROMHeader[3] = fUniqueID >> 32;
                    193:     fROMHeader[4] = fUniqueID & 0xffffffff;
                    194: 
                    195:     crc16 = FWComputeCRC16 (&fROMHeader[1], 4);
                    196:     fROMHeader[0] = 0x04040000 | crc16;
                    197: 
                    198:     rom->appendBytes(fROMHeader, 20);
                    199:     setProperty(gFireWireROM, rom);
                    200:     rom->release(); // XXX -- svail: added.
                    201: 
                    202:     // Create root directory in FWIM data.//zzz should we have one for each FWIM or just one???
                    203:     fCSRROMRootDirectory.csrROMEntryData.pParentCSRROMEntryData = NULL;
                    204:     fCSRROMRootDirectory.csrROMEntryData.pPrevCSRROMEntryData = NULL;
                    205:     fCSRROMRootDirectory.csrROMEntryData.pNextCSRROMEntryData = NULL;
                    206:     fCSRROMRootDirectory.csrROMEntryData.entryType =
                    207:             kDirectoryCSRROMEntryType;
                    208:     //fCSRROMRootDirectory->csrROMEntryData.fwimID = fwimID;
                    209:     //fCSRROMRootDirectory.csrROMEntryData.pEntryLocation = NULL;
                    210:     fCSRROMRootDirectory.csrROMBasicEntryData.keyValue = 0;
                    211:     fCSRROMRootDirectory.pChildCSRROMEntryData = NULL;
                    212:     fCSRROMRootDirectory.numChildren = 0;
                    213: 
                    214:     status = CSRROMGetRootDirectory (&csrROMRootEntryID);
                    215: 
                    216:     // Set our CSR ROM generation.
                    217:     if (status == kIOReturnSuccess) {
                    218:         immediateEntry = 0;
                    219:         status = CSRROMCreateEntry (csrROMRootEntryID,
                    220:                                     &csrROMEntryID,
                    221:                                     kImmediateCSRROMEntryType,
                    222:                                     kCSRGenerationKey,
                    223:                                     (UInt8 *) &immediateEntry,
                    224:                                     3);
                    225:     }
                    226: 
                    227:     // Set our module vendor ID.
                    228:     if (status == kIOReturnSuccess) {
                    229:         immediateEntry = 0x00A040 << 8;
                    230:         status = CSRROMCreateEntry (csrROMRootEntryID,
                    231:                                     &csrROMEntryID,
                    232:                                     kImmediateCSRROMEntryType,
                    233:                                     kCSRModuleVendorIDKey,
                    234:                                     (UInt8 *) &immediateEntry,
                    235:                                     3);
                    236:     }
                    237: 
                    238:     // Set our capabilities.
                    239:     if (status == kIOReturnSuccess) {
                    240:         immediateEntry = 0x000083C0 << 8;//zzz need real values.
                    241:         status = CSRROMCreateEntry (csrROMRootEntryID,
                    242:                                     &csrROMEntryID,
                    243:                                     kImmediateCSRROMEntryType,
                    244:                                     kCSRNodeCapabilitiesKey,
                    245:                                     (UInt8 *) &immediateEntry,
                    246:                                     3);
                    247:     }
                    248: 
                    249:     // Set our node unique ID.
                    250:     if (status == kIOReturnSuccess) {
                    251:         status = CSRROMCreateEntry (csrROMRootEntryID,
                    252:                                     &csrROMEntryID,
                    253:                                     kLeafCSRROMEntryType,
                    254:                                     kCSRNodeUniqueIdKey,
                    255:                                     &fUniqueID,
                    256:                                     8);
                    257:     }
                    258: 
                    259:     // Will instantiate at end (causes a bus reset).
                    260:     // Clean up ROM entry references
                    261:     if (csrROMRootEntryID != kInvalidCSRROMEntryID)
                    262:         FWCSRROMDisposeEntryID (csrROMRootEntryID);
                    263: 
                    264:     if (csrROMEntryID != kInvalidCSRROMEntryID)
                    265:         FWCSRROMDisposeEntryID (csrROMEntryID);
                    266: 
                    267:     // Create command gate, start probing etc.
                    268:     fGate = IOCommandGate::commandGate(this, execCommand);
                    269:     if(!fGate)
                    270:        return false;
                    271: 
                    272:     // Create Timer Event source
                    273:     fTimer = IOTimerEventSource::timerEventSource(this, clockTick);
                    274:     if(!fTimer)
                    275:        return false;
                    276: 
                    277:     fWorkLoop = createWorkLoop();
                    278:     fWorkLoop->addEventSource(fGate);
                    279:     fWorkLoop->addEventSource(fTimer);
                    280: 
                    281: 
                    282:     IOFWUpdateROM *reset = new IOFWUpdateROM;
                    283:     if(reset) {
                    284:         if(reset->initWithController(this, doneReset, NULL))
                    285:             reset->submit();
                    286:        else {
                    287:             reset->release();
                    288:             reset = NULL;
                    289:        }
                    290:     }
                    291: 
                    292:     return fWorkLoop != NULL && reset != NULL;
                    293: }
                    294: 
                    295: IOWorkLoop *IOFireWireController::getWorkLoop() const
                    296: {
                    297:     return fWorkLoop;
                    298: }
                    299: 
                    300: AsyncPendingTrans *IOFireWireController::allocTrans(bool sleepOK)
                    301: {
                    302:     unsigned int i;
                    303:     unsigned int tran;
                    304: 
                    305:     do {
                    306:         IOTakeLock(fTransAllocLock);
                    307:         tran = fLastTrans;
                    308:         for(i=0; i<kMaxPendingTransfers; i++) {
                    309:             AsyncPendingTrans *t;
                    310:             tran++;
                    311:             if(tran >= kMaxPendingTransfers)
                    312:                 tran = 0;
                    313:             t = &fTrans[tran];
                    314:             if(!t->fInUse) {
                    315:                 t->fHandler = NULL;
                    316:                 t->fInUse = true;
                    317:                 t->fTCode = tran;
                    318:                 fLastTrans = tran;
                    319:                 IOUnlock(fTransAllocLock);
                    320:                 return t;
                    321:             }
                    322:         }
                    323:         IOUnlock(fTransAllocLock);
                    324:         IOLog("Out of FireWire read request codes!\n");
                    325:         if(!sleepOK)
                    326:             break;
                    327:         IOSleep(10);
                    328:     } while (true);
                    329:     return NULL;
                    330: }
                    331: 
                    332: void IOFireWireController::freeTrans(AsyncPendingTrans *trans)
                    333: {
                    334:     // No lock needed - can't have two users of a tcode.
                    335:     trans->fInUse = false;
                    336: }
                    337: 
                    338: 
                    339: void IOFireWireController::readDeviceROM(NodeScan *scan, IOReturn status)
                    340: {
                    341:     bool done = true;
                    342:     if(status != kIOReturnSuccess) {
                    343:        // If status isn't bus reset, make a dummy registry entry.
                    344:         if(status == kIOFireWireBusReset)
                    345:             return;
                    346: 
                    347:         OSDictionary *propTable;
                    348:         UInt32 nodeID = FWAddressToID(scan->fAddr.nodeID);
                    349:         OSObject * prop;
                    350:         propTable = OSDictionary::withCapacity(3);
                    351:         prop = OSNumber::withNumber(scan->fAddr.nodeID, 16);
                    352:         propTable->setObject(gFireWireNodeID, prop);
                    353:         prop->release();
                    354: 
                    355:         prop = OSNumber::withNumber((scan->fSelfIDs[0] & kFWSelfID0SP) >> kFWSelfID0SPPhase, 32);
                    356:         propTable->setObject(gFireWireSpeed, prop);
                    357:         prop->release();
                    358: 
                    359:         prop = OSData::withBytes(scan->fSelfIDs, scan->fNumSelfIDs*sizeof(UInt32));
                    360:         propTable->setObject(gFireWireSelfIDs, prop);
                    361:         prop->release();
                    362: 
                    363:         IORegistryEntry * newPhy;
                    364:         newPhy = new IORegistryEntry;
                    365:        if(newPhy) {
                    366:             if(!newPhy->init(propTable)) {
                    367:                 newPhy->release();     
                    368:                newPhy = NULL;
                    369:             }
                    370:        }
                    371:         fNodes[nodeID] = newPhy;
                    372:         if(propTable)
                    373:             propTable->release();
                    374:         fNumROMReads--;
                    375:         if(fNumROMReads == 0) {
                    376:             fTimer->enable();
                    377:             fTimer->setTimeoutMS(kDevicePruneDelay);   // One second
                    378:         }
                    379: 
                    380:         if(scan->fBuf)
                    381:             IOFree(scan->fBuf, scan->fROMSize);
                    382:         scan->fCmd->release();
                    383:         IOFree(scan, sizeof(*scan));
                    384:         return;
                    385:     }
                    386: 
                    387:     if(scan->fState == kReadROMSize) {
                    388:        if( ((scan->fROMHdr & kCSRBusInfoBlockLength) >> kCSRBusInfoBlockLengthPhase) == 1) {
                    389:             // Minimal ROM
                    390:             scan->fROMSize = 4;
                    391:             done = true;
                    392:        }
                    393:        else {
                    394:             scan->fROMSize = 4*((scan->fROMHdr & kCSRROMCRCLength) >> kCSRROMCRCLengthPhase) + 4;
                    395:             scan->fBuf = (UInt32 *)IOMalloc(scan->fROMSize);
                    396:             *scan->fBuf = scan->fROMHdr;
                    397:             scan->fRead = 4;
                    398:             if(scan->fROMSize > 4) {
                    399:                 scan->fState = kReadingROM;
                    400:                 scan->fAddr.addressLo = kCSRROMBaseAddress+4;
                    401:                 scan->fCmd->reinit(scan->fAddr, scan->fBuf+1, scan->fROMSize/4-1,
                    402:                                                             &readROMGlue, scan, true);
                    403:                 scan->fCmd->execute();
                    404:                 done = false;
                    405:             }
                    406:             else
                    407:                done = true;
                    408:        }
                    409:     }
                    410:     if(done) {
                    411:        // Check if node exists, if not create it
                    412: #if (DEBUGGING_LEVEL > 0)
                    413:        DEBUGLOG("Finished reading ROM for node 0x%x\n", scan->fNodeID);
                    414: #endif
                    415:         OSDictionary *         propTable = NULL;
                    416:         IOFireWireDevice *     newDevice = NULL;
                    417:         OSData *               rom = NULL;
                    418:         do {
                    419:             CSRNodeUniqueID guid;
                    420:             OSIterator *childIterator;
                    421:             if(scan->fROMSize >= 20)
                    422:                guid = *(CSRNodeUniqueID *)(scan->fBuf+3);
                    423:             else
                    424:                 guid = scan->fROMHdr;  // Best we can do.
                    425:             if(scan->fROMSize == 4)
                    426:                 rom = OSData::withBytes(&scan->fROMHdr, 4);
                    427:             else
                    428:                 rom = OSData::withBytes(scan->fBuf, scan->fROMSize);
                    429:             childIterator = getClientIterator();
                    430:             if( childIterator) {
                    431:                 IOFireWireDevice * found;
                    432:                while( (found = (IOFireWireDevice *) childIterator->getNextObject())) {
                    433:                     if(found->fUniqueID == guid) {
                    434:                        newDevice = found;
                    435:                         break;
                    436:                     }
                    437:                }
                    438:                 childIterator->release();
                    439:             }
                    440: 
                    441:             if(newDevice) {
                    442:                // Just update device properties.
                    443:                newDevice->setNodeROM(fBusGeneration, scan->fAddr.nodeID, fLocalNodeID,
                    444:                        rom, scan->fSelfIDs, scan->fNumSelfIDs);
                    445:                newDevice->retain();    // match release, since not newly created.
                    446:             }
                    447:             else {
                    448:                 OSObject * prop;
                    449:                 propTable = OSDictionary::withCapacity(6);
                    450:                 if (!propTable)
                    451:                     continue;
                    452: 
                    453:                 prop = OSNumber::withNumber(guid, 64);
                    454:                 propTable->setObject(gFireWire_GUID, prop);
                    455:                 prop->release();
                    456:                 prop = OSNumber::withNumber((scan->fSelfIDs[0] & kFWSelfID0SP) >> kFWSelfID0SPPhase, 32);
                    457:                 propTable->setObject(gFireWireSpeed, prop);
                    458:                 prop->release();
                    459:                 newDevice = createDeviceNub(propTable);
                    460:                 if (!newDevice)
                    461:                     continue;
                    462:                 propTable->release();  // done with it after init
                    463:                 propTable = NULL;
                    464: 
                    465:                 if (!newDevice->attach(this))
                    466:                     continue;
                    467:                 newDevice->setNodeROM(fBusGeneration, scan->fAddr.nodeID, fLocalNodeID,
                    468:                         rom, scan->fSelfIDs, scan->fNumSelfIDs);
                    469:                 newDevice->registerService();
                    470:             }
                    471:             if(fIRMNodeID == scan->fAddr.nodeID) {
                    472:                 IOFWIsochChannel *found;
                    473:                fIRMDevice = newDevice;
                    474:                // Tell all active ioschronous channels to re-allocate bandwidth
                    475:                 IOTakeLock(fChannelLock);
                    476:                 fAllocChannelIterator->reset();
                    477:                 while( (found = (IOFWIsochChannel *) fAllocChannelIterator->getNextObject())) {
                    478:                     found->handleBusReset();
                    479:                 }
                    480:                 IOUnlock(fChannelLock);
                    481:             }
                    482:             UInt32 nodeID = FWAddressToID(scan->fAddr.nodeID);
                    483:             fNodes[nodeID] = newDevice;
                    484:             fNodes[nodeID]->retain();
                    485:        } while (false);
                    486:         if (propTable)
                    487:             propTable->release();
                    488:         if (newDevice)
                    489:             newDevice->release();
                    490:         if (rom)
                    491:             rom->release();
                    492:         if(scan->fBuf)
                    493:             IOFree(scan->fBuf, scan->fROMSize);
                    494:         scan->fCmd->release();
                    495:         IOFree(scan, sizeof(*scan));
                    496:         fNumROMReads--;
                    497:         if(fNumROMReads == 0) {
                    498:             fTimer->enable();
                    499:             fTimer->setTimeoutMS(kDevicePruneDelay);   // One second
                    500:         }
                    501:     }
                    502: }
                    503: 
                    504: 
                    505: //
                    506: // Hardware detected a bus reset.
                    507: // At this point we don't know what the hardware addresses are
                    508: void IOFireWireController::processBusReset()
                    509: {
                    510:     clock_get_uptime(&fResetTime);     // Update even if we're already processing a reset
                    511: 
                    512:     if(!fInReset) {
                    513:         fInReset = true;
                    514:         unsigned int i;
                    515: 
                    516:         fTimer->cancelTimeout();
                    517: 
                    518:         // Set all current device nodeIDs to something invalid
                    519:         OSIterator *childIterator;
                    520:         childIterator = getClientIterator();
                    521:         if( childIterator) {
                    522:             IOFireWireDevice * found;
                    523:             while( (found = (IOFireWireDevice *) childIterator->getNextObject())) {
                    524:                 found->setNodeROM(fBusGeneration, kFWBadNodeID, kFWBadNodeID, NULL, NULL, 0);
                    525:             }
                    526:             childIterator->release();
                    527:         }
                    528: 
                    529: 
                    530:         // Invalidate current topology and speed map
                    531:         fBusGeneration++;
                    532:         bzero(fSpeedCodes, sizeof(fSpeedCodes));
                    533: 
                    534:         // Zap all outstanding async requests
                    535:         for(i=0; i<kMaxPendingTransfers; i++) {
                    536:             AsyncPendingTrans *t = &fTrans[i];
                    537:             if(t->fInUse) {
                    538:                 IOFWAsyncCommand * cmd = t->fHandler;
                    539:                 if(cmd) {
                    540:                     cmd->gotPacket(this, kFWResponseBusResetError, NULL, 0);
                    541:                 }
                    542:             }
                    543:         }
                    544: 
                    545:        // Clear out the old firewire plane
                    546:         if(fNodes[fRootNodeID]) {
                    547:             fNodes[fRootNodeID]->detachAll(gIOFireWirePlane);
                    548:        }
                    549:         for(i=0; i<=fRootNodeID; i++) {
                    550:             if(fNodes[i]) {
                    551:                fNodes[i]->release();
                    552:                fNodes[i] = NULL;
                    553:             }
                    554:        }
                    555:     }
                    556: }
                    557: 
                    558: //
                    559: // SelfID packets received after reset.
                    560: void IOFireWireController::processSelfIDs(UInt32 *IDs, int numIDs, UInt32 *ownIDs, int numOwnIDs)
                    561: {
                    562:     OSObject *prop;
                    563:     int i;
                    564:     UInt32 id;
                    565:     UInt32 nodeID;
                    566:     UInt16 irmID, ourID;
                    567: 
                    568: #if 0
                    569: for(i=0; i<numIDs; i++)
                    570:     IOLog("ID %d: 0x%x <-> 0x%x\n", i, IDs[2*i], ~IDs[2*i+1]);
                    571: 
                    572: for(i=0; i<numOwnIDs; i++)
                    573:     IOLog("Own ID %d: 0x%x <-> 0x%x\n", i, ownIDs[2*i], ~ownIDs[2*i+1]);
                    574: #endif
                    575:     // If not processing a reset, then we should be
                    576:     // This can happen if we get two resets in quick succession
                    577:     if(!fInReset)
                    578:         processBusReset();
                    579:     fInReset = false;
                    580:     fNumROMReads = 0;
                    581: 
                    582:     // Update the registry entry for our local nodeID,
                    583:     // which will have been updated by the device driver.
                    584:     prop = OSNumber::withNumber(fLocalNodeID, 16);
                    585:     setProperty(gFireWireNodeID, prop);
                    586:     prop->release();
                    587:     prop = OSNumber::withNumber((ownIDs[0] & kFWSelfID0SP) >> kFWSelfID0SPPhase, 32);
                    588:     setProperty(gFireWireSpeed, prop);
                    589:     prop->release();
                    590: 
                    591:     // Initialize root node to be our node, we'll update it below to be the highest node ID.
                    592:     fRootNodeID = ourID = (*ownIDs & kFWPhyPacketPhyID) >> kFWPhyPacketPhyIDPhase;
                    593: 
                    594:     fNodes[ourID] = this;
                    595:     retain();
                    596: 
                    597:     // Copy over the selfIDs, checking validity and merging in our selfIDs if they aren't
                    598:     // already in the list.
                    599:     SInt16 prevID = -1;        // Impossible ID.
                    600:     UInt32 *idPtr = fSelfIDs;
                    601:     for(i=0; i<numIDs; i++) {
                    602:         UInt32 id = IDs[2*i];
                    603:         UInt16 currID = (id & kFWPhyPacketPhyID) >> kFWPhyPacketPhyIDPhase;
                    604: 
                    605:         if(id != ~IDs[2*i+1]) {
                    606:             IOLog("Bad SelfID packet %d: 0x%x != 0x%x!\n", i, id, ~IDs[2*i+1]);
                    607:             resetBus();        // Could wait a bit in case somebody else spots the bad packet
                    608:             return;
                    609:         }
                    610:         if(currID != prevID) {
                    611:             // Check for ownids not in main list
                    612:             if(prevID < ourID && currID > ourID) {
                    613:                int j;
                    614:                fNodeIDs[ourID] = idPtr;
                    615:                 for(j=0; j<numOwnIDs; j++)
                    616:                     *idPtr++ = ownIDs[2*j];
                    617:             }
                    618:             fNodeIDs[currID] = idPtr;
                    619:             prevID = currID;
                    620:             if(fRootNodeID < currID)
                    621:                 fRootNodeID = currID;
                    622:         }
                    623:        *idPtr++ = id;
                    624:     }
                    625:     // Check for ownids at end & not in main list
                    626:     if(prevID < ourID) {
                    627:         int j;
                    628:         fNodeIDs[ourID] = idPtr;
                    629:         for(j=0; j<numOwnIDs; j++)
                    630:             *idPtr++ = ownIDs[2*j];
                    631:     }
                    632:     // Stick a known elephant at the end.
                    633:     fNodeIDs[fRootNodeID+1] = idPtr;
                    634: 
                    635:     buildTopology(false);
                    636: 
                    637:     prop = OSData::withBytes(fNodeIDs[ourID], numOwnIDs*sizeof(UInt32));
                    638:     setProperty(gFireWireSelfIDs, prop);
                    639:     prop->release();
                    640: 
                    641:     // Ask each device for its GUID.
                    642:     // In the completion handler we'll match the new IDs to existing
                    643:     // nubs and create new ones.
                    644: #if (DEBUGGING_LEVEL > 0)
                    645:     for(i=0; i<numIDs; i++) {
                    646:         id = IDs[2*i];
                    647:         if(id != ~IDs[2*i+1]) {
                    648:             DEBUGLOG("Bad SelfID: 0x%x <-> 0x%x\n", id, ~IDs[2*i+1]);
                    649:             continue;
                    650:         }
                    651:        DEBUGLOG("SelfID: 0x%x\n", id);
                    652:     }
                    653:     DEBUGLOG("Our ID: 0x%x\n", *ownIDs);
                    654: #endif
                    655:     irmID = 0;
                    656:     for(i=0; i<=fRootNodeID; i++) {
                    657:        if(i == ourID)
                    658:             continue;  // Skip ourself!
                    659:         id = *fNodeIDs[i];
                    660:         // Get nodeID.
                    661:         nodeID = (id & kFWSelfIDPhyID) >> kFWSelfIDPhyIDPhase;
                    662:         nodeID |= kFWLocalBusAddress>>kCSRNodeIDPhase;
                    663: 
                    664:         if((id & (kFWSelfID0C | kFWSelfID0L)) == (kFWSelfID0C | kFWSelfID0L)) {
                    665:             kprintf("IRM contender: %x\n", nodeID);
                    666:             if(nodeID > irmID)
                    667:                irmID = nodeID;
                    668:        }
                    669: 
                    670:         // Read ROM header if link is active (MacOS8 turns link on, why?)
                    671:        if(true) { //id & kFWSelfID0L) {
                    672:             NodeScan *scan;
                    673:             scan = (NodeScan *)IOMalloc(sizeof(*scan));
                    674:             fNumROMReads++;
                    675: 
                    676:             scan->fControl = this;
                    677:             scan->fAddr.nodeID = nodeID;
                    678:             scan->fAddr.addressHi = kCSRRegisterSpaceBaseAddressHi;
                    679:             scan->fAddr.addressLo = kCSRBIBHeaderAddress;
                    680:             scan->fSelfIDs = fNodeIDs[i];
                    681:             scan->fNumSelfIDs = fNodeIDs[i+1] - fNodeIDs[i];
                    682:             scan->fState = kReadROMSize;
                    683:             scan->fCmd = new IOFWReadQuadCommand;
                    684:             scan->fCmd->initAll(this, NULL, scan->fAddr, &scan->fROMHdr, 1, 
                    685:                                                &readROMGlue, scan, true);
                    686:             scan->fBuf = NULL;
                    687:             scan->fCmd->execute();
                    688:        }
                    689:     }
                    690:     if(irmID != 0)
                    691:         fIRMNodeID = irmID;
                    692:     else
                    693:         fIRMNodeID = kFWBadNodeID;
                    694:     if(fNumROMReads == 0) {
                    695:         fTimer->enable();
                    696:         fTimer->setTimeoutMS(kDevicePruneDelay);       // One second
                    697:     }
                    698: }
                    699: 
                    700: void IOFireWireController::buildTopology(bool doFWPlane)
                    701: {
                    702:     int i;
                    703:     IORegistryEntry *root;
                    704:     struct FWNodeScan
                    705:     {
                    706:         int nodeID;
                    707:         int childrenRemaining;
                    708:         IORegistryEntry *node;
                    709:     };
                    710:     FWNodeScan scanList[kFWMaxNodeHops];
                    711:     FWNodeScan *level;
                    712:     root = fNodes[fRootNodeID];
                    713:     level = scanList;
                    714: 
                    715:     // First build the topology.
                    716:     for(i=fRootNodeID; i>=0; i--) {
                    717:         UInt32 id0;
                    718:         UInt8 speedCode;
                    719:         IORegistryEntry *node = fNodes[i];
                    720:         id0 = *fNodeIDs[i];
                    721:         int children = 0;
                    722:         UInt32 port;
                    723:         port = (id0 & kFWSelfID0P0) >> kFWSelfID0P0Phase;
                    724:         if(port == kFWSelfIDPortStatusChild)
                    725:             children++;
                    726:         port = (id0 & kFWSelfID0P1) >> kFWSelfID0P1Phase;
                    727:         if(port == kFWSelfIDPortStatusChild)
                    728:             children++;
                    729:         port = (id0 & kFWSelfID0P2) >> kFWSelfID0P2Phase;
                    730:         if(port == kFWSelfIDPortStatusChild)
                    731:             children++;
                    732: 
                    733:         // Add node to bottom of tree
                    734:         level->nodeID = i;
                    735:         level->childrenRemaining = children;
                    736:         level->node = node;
                    737: 
                    738:         // Add node's self speed to speedmap
                    739:         speedCode = (id0 & kFWSelfID0SP) >> kFWSelfID0SPPhase;
                    740:         fSpeedCodes[(kFWMaxNodesPerBus + 1)*i + i] = speedCode;
                    741: 
                    742:         // Add to parent
                    743:         // Compute rest of this node's speed map entries unless it's the root.
                    744:         // We only need to compute speeds between this node and all higher node numbers.
                    745:         // These speeds will be the minimum of this node's speed and the speed between
                    746:         // this node's parent and the other higher numbered nodes.
                    747:         if (i != fRootNodeID) {
                    748:             int parentNodeNum, scanNodeNum;
                    749:             parentNodeNum = (level-1)->nodeID;
                    750:             if(doFWPlane)
                    751:                 node->attachToParent((level-1)->node, gIOFireWirePlane);
                    752:             for (scanNodeNum = i + 1; scanNodeNum <= fRootNodeID; scanNodeNum++) {
                    753:                 UInt8 scanSpeedCode;
                    754:                 // Get speed code between parent and scan node.
                    755:                 scanSpeedCode =
                    756:                         fSpeedCodes[(kFWMaxNodesPerBus + 1)*parentNodeNum + scanNodeNum];
                    757: 
                    758:                 // Set speed map entry to minimum of scan speed and node's speed.
                    759:                 if (speedCode < scanSpeedCode)
                    760:                         scanSpeedCode = speedCode;
                    761:                 fSpeedCodes[(kFWMaxNodesPerBus + 1)*i + scanNodeNum] = scanSpeedCode;
                    762:                 fSpeedCodes[(kFWMaxNodesPerBus + 1)*scanNodeNum + i] = scanSpeedCode;
                    763:             }
                    764:         }
                    765:         // Find next child port.
                    766:         if (i > 0) {
                    767:             while (level->childrenRemaining == 0) {
                    768:                 // Go up one level in tree.
                    769:                 level--;
                    770: 
                    771:                 // One less child to scan.
                    772:                 level->childrenRemaining--;
                    773:             }
                    774:             // Go down one level in tree.
                    775:             level++;
                    776:         }
                    777:     }
                    778: 
                    779: 
                    780:     if(doFWPlane) {
                    781:        IOLog("FireWire Speed map:\n");
                    782:         for(i=0; i <= fRootNodeID; i++) {
                    783:             int j;
                    784:             for(j=0; j <= fRootNodeID; j++) {
                    785:                 IOLog("%d ", fSpeedCodes[(kFWMaxNodesPerBus + 1)*i + j]);
                    786:             }
                    787:             IOLog("\n");
                    788:         }
                    789:     }
                    790:     // Finally attach the full topology into the IOKit registry
                    791:     if(doFWPlane)
                    792:         root->attachToParent(IORegistryEntry::getRegistryRoot(), gIOFireWirePlane);
                    793: }
                    794: 
                    795: void IOFireWireController::pruneDevices()
                    796: {
                    797:     OSIterator *childIterator;
                    798:     childIterator = getClientIterator();
                    799:     if( childIterator) {
                    800:         IOFireWireDevice * found;
                    801:         while( (found = (IOFireWireDevice *) childIterator->getNextObject())) {
                    802:             if(found->fNodeID == kFWBadNodeID) {
                    803:                 found->terminate();
                    804:             }
                    805:         }
                    806:         childIterator->release();
                    807:     }
                    808: 
                    809:     buildTopology(true);
                    810: }
                    811: 
                    812: ////////////////////////////////////////////////////////////////////////////////
                    813: //
                    814: // processWriteRequest
                    815: //
                    816: //   process quad and block writes.
                    817: //
                    818: void IOFireWireController::processWriteRequest(UInt16 sourceID, UInt32 tLabel,
                    819:                        UInt32 *hdr, void *buf, int len)
                    820: {
                    821:     UInt32 ret = kFWResponseAddressError;
                    822:     FWAddress addr((hdr[1] & kFWAsynchDestinationOffsetHigh) >> kFWAsynchDestinationOffsetHighPhase, hdr[2]);
                    823:     IOFWAddressSpace * found;
                    824:     fSpaceIterator->reset();
                    825:     while( (found = (IOFWAddressSpace *) fSpaceIterator->getNextObject())) {
                    826:         ret = found->doWrite(sourceID, addr, len, buf, false);
                    827:         if(ret != kFWResponseAddressError)
                    828:             break;
                    829:     }
                    830:     asyncWriteResponse(sourceID, FWSpeed(sourceID), tLabel, ret, addr.addressHi);
                    831: }
                    832: 
                    833: ////////////////////////////////////////////////////////////////////////////////
                    834: //
                    835: // processLockRequest
                    836: //
                    837: //   process 32 and 64 bit locks.
                    838: //
                    839: void IOFireWireController::processLockRequest(UInt16 sourceID, UInt32 tLabel,
                    840:                        UInt32 *hdr, void *buf, int len)
                    841: {
                    842:     UInt32 oldVal[2];
                    843:     UInt32 ret = kFWResponseAddressError;
                    844:     bool ok;
                    845:     int size;
                    846:     int i;
                    847:     int type = (hdr[3] &  kFWAsynchExtendedTCode) >> kFWAsynchExtendedTCodePhase;
                    848:     FWAddress addr((hdr[1] & kFWAsynchDestinationOffsetHigh) >> kFWAsynchDestinationOffsetHighPhase, hdr[2]);
                    849:     IOFWAddressSpace * found;
                    850:     IOMemoryDescriptor *desc = NULL;
                    851:     IOByteCount offset;
                    852: 
                    853: 
                    854:     size = len/8;      // Depends on type, but right for 'compare and swap'
                    855: 
                    856:     fSpaceIterator->reset();
                    857:     while( (found = (IOFWAddressSpace *) fSpaceIterator->getNextObject())) {
                    858:         ret = found->doRead(sourceID, addr, size*4, &desc, &offset, true);
                    859:         if(ret != kFWResponseAddressError)
                    860:             break;
                    861:     }
                    862:     if(NULL != desc) {
                    863:         desc->readBytes(offset,oldVal, size*4);
                    864:         switch (type) {
                    865:             case kFWExtendedTCodeCompareSwap:
                    866:                 ok = true;
                    867:                 for(i=0; i<size; i++)
                    868:                     ok = ok && oldVal[i] == ((UInt32 *)buf)[i];
                    869:                 if(ok)
                    870:                     ret = found->doWrite(sourceID, addr, size*4, (UInt32 *)buf+size, true);
                    871:                 break;
                    872: 
                    873:             default:
                    874:                 ret = kFWResponseTypeError;
                    875:         }
                    876:         asyncLockResponse(sourceID, FWSpeed(sourceID), tLabel, ret, type, oldVal, size*4);
                    877:     }
                    878:     else {
                    879:         oldVal[0] = 0xdeadbabe;
                    880:         asyncLockResponse(sourceID, FWSpeed(sourceID), tLabel, ret, type, oldVal, 4);
                    881:     }
                    882: }
                    883: 
                    884: ////////////////////////////////////////////////////////////////////////////////
                    885: //
                    886: // processRcvPacket
                    887: //
                    888: //   Dispatch received Async packet based on tCode.
                    889: //
                    890: void IOFireWireController::processRcvPacket(UInt32 *data, int size)
                    891: {
                    892: #if 0
                    893:     int i;
                    894: kprintf("Received packet 0x%x size %d\n", data, size);
                    895:     for(i=0; i<size; i++) {
                    896:        kprintf("0x%x ", data[i]);
                    897:     }
                    898:     kprintf("\n");
                    899: #endif
                    900:     UInt32     tCode, tLabel;
                    901:     UInt32     quad0;
                    902:     UInt16     sourceID;
                    903: 
                    904:     // Get first quad.
                    905:     quad0 = *data;
                    906: 
                    907:     tCode = (quad0 & kFWPacketTCode) >> kFWPacketTCodePhase;
                    908:     tLabel = (quad0 & kFWAsynchTLabel) >> kFWAsynchTLabelPhase;
                    909:     sourceID = (data[1] & kFWAsynchSourceID) >> kFWAsynchSourceIDPhase;
                    910: 
                    911:     // Dispatch processing based on tCode.
                    912:     switch (tCode)
                    913:     {
                    914:         case kFWTCodeWriteQuadlet :
                    915: #if (DEBUGGING_LEVEL > 0)
                    916:             DEBUGLOG("WriteQuadlet: addr 0x%x:0x%x\n", 
                    917:                (data[1] & kFWAsynchDestinationOffsetHigh) >> kFWAsynchDestinationOffsetHighPhase, data[2]);
                    918: #endif
                    919:             processWriteRequest(sourceID, tLabel, data, &data[3], 4);
                    920:             break;
                    921: 
                    922:         case kFWTCodeWriteBlock :
                    923: #if (DEBUGGING_LEVEL > 0)
                    924:             DEBUGLOG("WriteBlock: addr 0x%x:0x%x\n", 
                    925:                (data[1] & kFWAsynchDestinationOffsetHigh) >> kFWAsynchDestinationOffsetHighPhase, data[2]);
                    926: #endif
                    927:             processWriteRequest(sourceID, tLabel, data, &data[4],
                    928:                        (data[3] & kFWAsynchDataLength) >> kFWAsynchDataLengthPhase);
                    929:             break;
                    930: 
                    931:         case kFWTCodeWriteResponse :
                    932:             if(fTrans[tLabel].fInUse) {
                    933:                 IOFWAsyncCommand * cmd = fTrans[tLabel].fHandler;
                    934:                cmd->gotPacket(this,
                    935:                        (data[1] & kFWAsynchRCode)>>kFWAsynchRCodePhase, 0, 0);
                    936:             }
                    937:             else {
                    938: #if (DEBUGGING_LEVEL > 0)
                    939:                DEBUGLOG("WriteResponse: label %d isn't in use!!\n", tLabel);
                    940: #endif
                    941:             }
                    942:             break;
                    943: 
                    944:         case kFWTCodeReadQuadlet :
                    945: #if (DEBUGGING_LEVEL > 0)
                    946:             DEBUGLOG("ReadQuadlet: addr 0x%x:0x%x\n", 
                    947:                (data[1] & kFWAsynchDestinationOffsetHigh) >> kFWAsynchDestinationOffsetHighPhase, data[2]);
                    948: #endif
                    949:             {
                    950:                 // Rather inefficiently search for a matching address space
                    951:                 UInt32 ret = kFWResponseAddressError;
                    952:                 FWAddress addr((data[1] & kFWAsynchDestinationOffsetHigh) >> kFWAsynchDestinationOffsetHighPhase, data[2]);
                    953:                 IOFWAddressSpace * found;
                    954:                 IOMemoryDescriptor *buf = NULL;
                    955:                IOByteCount offset;
                    956:                 fSpaceIterator->reset();
                    957:                 while( (found = (IOFWAddressSpace *) fSpaceIterator->getNextObject())) {
                    958:                     ret = found->doRead(sourceID, addr, 4, &buf, &offset, false);
                    959:                     if(ret != kFWResponseAddressError)
                    960:                         break;
                    961:                 }
                    962:                 if(NULL != buf) {
                    963:                     IOByteCount lengthOfSegment;
                    964:                     asyncReadQuadResponse(sourceID, FWSpeed(sourceID), tLabel, ret,
                    965:                        *(UInt32 *)buf->getVirtualSegment(offset, &lengthOfSegment));
                    966:                 }
                    967:                 else {
                    968:                     asyncReadQuadResponse(sourceID, FWSpeed(sourceID),
                    969:                                        tLabel, ret, 0xdeadbeef);
                    970:                 }
                    971:             }
                    972:             break;
                    973: 
                    974:         case kFWTCodeReadBlock :
                    975: #if (DEBUGGING_LEVEL > 0)
                    976:             DEBUGLOG("ReadBlock: addr 0x%x:0x%x len %d\n", 
                    977:                (data[1] & kFWAsynchDestinationOffsetHigh) >> kFWAsynchDestinationOffsetHighPhase, data[2],
                    978:                (data[3] & kFWAsynchDataLength) >> kFWAsynchDataLengthPhase);
                    979: #endif
                    980:             {
                    981:                 // Rather inefficiently search for a matching address space
                    982:                 IOReturn ret = kFWResponseAddressError;
                    983:                 int length = (data[3] & kFWAsynchDataLength) >> kFWAsynchDataLengthPhase ;
                    984:                 FWAddress addr((data[1] & kFWAsynchDestinationOffsetHigh) >> 
                    985:                        kFWAsynchDestinationOffsetHighPhase, data[2]);
                    986:                 IOFWAddressSpace * found;
                    987:                 IOMemoryDescriptor *buf = NULL;
                    988:                IOByteCount offset;
                    989:                 fSpaceIterator->reset();
                    990:                 while( (found = (IOFWAddressSpace *) fSpaceIterator->getNextObject())) {
                    991:                     ret = found->doRead(sourceID, addr, length, &buf, &offset, false);
                    992:                     if(ret != kFWResponseAddressError)
                    993:                         break;
                    994:                 }
                    995:                 if(NULL != buf) {
                    996:                     asyncReadResponse(sourceID, FWSpeed(sourceID),
                    997:                                        tLabel, ret, buf, offset, length);
                    998:                 }
                    999:                 else {
                   1000:                     UInt32 bad = 0xcafebabe;
                   1001:                     asyncReadResponse(sourceID, FWSpeed(sourceID),
                   1002:                                        tLabel, ret, &bad, 4);
                   1003:                 }
                   1004:             }
                   1005:             break;
                   1006: 
                   1007:         case kFWTCodeReadQuadletResponse :
                   1008:             if(fTrans[tLabel].fInUse) {
                   1009:                 IOFWAsyncCommand * cmd = fTrans[tLabel].fHandler;
                   1010:                cmd->gotPacket(this, (data[1] & kFWAsynchRCode)>>kFWAsynchRCodePhase,
                   1011:                                                                        (UInt8*)(data+3), 4);
                   1012:             }
                   1013:             else {
                   1014: #if (DEBUGGING_LEVEL > 0)
                   1015:                DEBUGLOG("ReadQuadletResponse: label %d isn't in use!!\n", tLabel);
                   1016: #endif
                   1017:             }
                   1018:             break;
                   1019: 
                   1020:         case kFWTCodeReadBlockResponse :
                   1021:         case kFWTCodeLockResponse :
                   1022:             if(fTrans[tLabel].fInUse) {
                   1023:                 IOFWAsyncCommand * cmd = fTrans[tLabel].fHandler;
                   1024:                cmd->gotPacket(this, (data[1] & kFWAsynchRCode)>>kFWAsynchRCodePhase,
                   1025:                        (UInt8*)(data+4), (data[3] & kFWAsynchDataLength)>>kFWAsynchDataLengthPhase);
                   1026:             }
                   1027:             else {
                   1028: #if (DEBUGGING_LEVEL > 0)
                   1029:                DEBUGLOG("ReadBlock/LockResponse: label %d isn't in use!!\n", tLabel);
                   1030: #endif
                   1031:             }
                   1032:             break;
                   1033: 
                   1034:         case kFWTCodeLock :
                   1035: #if (DEBUGGING_LEVEL > 0)
                   1036:             DEBUGLOG("Lock type %d: addr 0x%x:0x%x\n", 
                   1037:                (data[3] & kFWAsynchExtendedTCode) >> kFWAsynchExtendedTCodePhase,
                   1038:                (data[1] & kFWAsynchDestinationOffsetHigh) >> kFWAsynchDestinationOffsetHighPhase,
                   1039:                data[2]);
                   1040: #endif
                   1041:             processLockRequest(sourceID, tLabel, data, &data[4],
                   1042:                        (data[3] & kFWAsynchDataLength) >> kFWAsynchDataLengthPhase);
                   1043: 
                   1044:             break;
                   1045: 
                   1046:         case kFWTCodeIsochronousBlock :
                   1047: #if (DEBUGGING_LEVEL > 0)
                   1048:             DEBUGLOG("Async Stream Packet\n");
                   1049: #endif
                   1050:             break;
                   1051: 
                   1052:         default :
                   1053: #if (DEBUGGING_LEVEL > 0)
                   1054:             DEBUGLOG("Unexpected tcode in Asyncrecv: %d\n", tCode);
                   1055: #endif
                   1056:             break;
                   1057:     }  
                   1058: }
                   1059: 
                   1060: IOReturn IOFireWireController::allocAddress(IOFWAddressSpace *space)
                   1061: {
                   1062:     /*
                   1063:      * Lots of scope for optimizations here, perhaps building a hash table for
                   1064:      * addresses etc.
                   1065:      * Drivers may want to override this if their hardware can match addresses
                   1066:      * without CPU intervention.
                   1067:      */
                   1068:     if(!fLocalAddresses->setObject(space))
                   1069:         return kIOReturnNoMemory;
                   1070:     else
                   1071:         return kIOReturnSuccess;
                   1072: }
                   1073: 
                   1074: void IOFireWireController::freeAddress(IOFWAddressSpace *space)
                   1075: {
                   1076:     fLocalAddresses->removeObject(space);
                   1077: }
                   1078: 
                   1079: void IOFireWireController::addAllocatedChannel(IOFWIsochChannel *channel)
                   1080: {
                   1081:     IOTakeLock(fChannelLock);
                   1082:     fAllocatedChannels->setObject(channel);
                   1083:     IOUnlock(fChannelLock);
                   1084: }
                   1085: 
                   1086: void IOFireWireController::removeAllocatedChannel(IOFWIsochChannel *channel)
                   1087: {
                   1088:     IOTakeLock(fChannelLock);
                   1089:     fAllocatedChannels->removeObject(channel);
                   1090:     IOUnlock(fChannelLock);
                   1091: }
                   1092: 
                   1093: 
                   1094: IOFireWireDevice * IOFireWireController::nodeIDtoDevice(UInt16 nodeID)
                   1095: {
                   1096:     OSIterator *childIterator;
                   1097:     IOFireWireDevice * found = NULL;
                   1098: 
                   1099:     childIterator = getClientIterator();
                   1100: 
                   1101:     if( childIterator) {
                   1102:         while( (found = (IOFireWireDevice *) childIterator->getNextObject())) {
                   1103:             if(found->fNodeID == nodeID)
                   1104:                break;
                   1105:         }
                   1106:         childIterator->release();
                   1107:     }
                   1108:     return found;
                   1109: }
                   1110: 
                   1111: IOFireWireDevice *IOFireWireController::createDeviceNub(OSDictionary *propTable)
                   1112: {
                   1113:     IOFireWireDevice *newDevice;
                   1114:     newDevice = new IOFireWireDevice;
                   1115: 
                   1116:     if (!newDevice)
                   1117:        return NULL;
                   1118:     if(!newDevice->init(propTable)) {
                   1119:        newDevice->release();
                   1120:         return NULL;
                   1121:     }
                   1122:     return newDevice;
                   1123: }
                   1124: 
                   1125: IOFWIsochChannel *IOFireWireController::createIsochChannel(
                   1126:        bool doIRM, UInt32 bandwidth, IOFWSpeed prefSpeed,
                   1127:        FWIsochChannelForceStopNotificationProc stopProc, void *stopRefCon)
                   1128: {
                   1129:     IOFWIsochChannel *channel;
                   1130: 
                   1131:     channel = new IOFWIsochChannel;
                   1132:     if(!channel)
                   1133:        return NULL;
                   1134: 
                   1135:     if(!channel->init(this, doIRM, bandwidth, prefSpeed, stopProc, stopRefCon)) {
                   1136:        channel->release();
                   1137:        channel = NULL;
                   1138:     }
                   1139:     return channel;
                   1140: }
                   1141: 
                   1142: IOFWIsochPort *IOFireWireController::createLocalIsochPort(bool talking,
                   1143:         DCLCommandStruct *opcodes, DCLTaskInfo *info,
                   1144:        UInt32 startEvent, UInt32 startState, UInt32 startMask)
                   1145: {
                   1146:     IOFWLocalIsochPort *port;
                   1147:     IODCLProgram *program;
                   1148: 
                   1149:     program = createDCLProgram(talking, opcodes, info, startEvent, startState, startMask);
                   1150:     if(!program)
                   1151:        return NULL;
                   1152: 
                   1153:     port = new IOFWLocalIsochPort;
                   1154:     if(!port) {
                   1155:        program->release();
                   1156:        return NULL;
                   1157:     }
                   1158: 
                   1159:     if(!port->init(program, this)) {
                   1160:        port->release();
                   1161:        port = NULL;
                   1162:     }
                   1163: 
                   1164:     return port;
                   1165: }
                   1166: 
                   1167: // How big (as a power of two) can packets sent to/received from the node be?
                   1168: int IOFireWireController::maxPackLog(bool forSend, UInt16 nodeAddress) const
                   1169: {
                   1170:     return 9+FWSpeed(nodeAddress);
                   1171: }
                   1172: 
                   1173: // How big (as a power of two) can packets sent from A to B be?
                   1174: int IOFireWireController::maxPackLog(UInt16 nodeA, UInt16 nodeB) const
                   1175: {
                   1176:     return 9+FWSpeed(nodeA, nodeB);
                   1177: }
                   1178: 

unix.superglobalmegacorp.com

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