Annotation of XNU/iokit/Families/IOFireWire/IOFWCommand.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * Copyright (c) 1999 Apple Computer, Inc.  All rights reserved.
        !            24:  *
        !            25:  * HISTORY
        !            26:  * 27 May 99 wgulland created.
        !            27:  *
        !            28:  */
        !            29: #include <IOKit/assert.h>
        !            30: #include <IOKit/IOSyncer.h>
        !            31: #include <IOKit/firewire/IOFWCommand.h>
        !            32: #include <IOKit/firewire/IOFireWireController.h>
        !            33: #include <IOKit/firewire/IOFireWireNub.h>
        !            34: 
        !            35: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            36: 
        !            37: #define super OSObject
        !            38: 
        !            39: OSDefineMetaClass( IOFWCommand, OSObject )
        !            40: OSDefineAbstractStructors(IOFWCommand, OSObject)
        !            41: 
        !            42: bool IOFWCommand::initWithGate(IOCommandGate *gate)
        !            43: {
        !            44:     if(!super::init())
        !            45:         return false;
        !            46: 
        !            47:     fGate = gate;
        !            48:     return true;
        !            49: }
        !            50: 
        !            51: IOReturn IOFWCommand::submit()
        !            52: {
        !            53:     IOReturn res;
        !            54:     if(fSync) {
        !            55:         fSyncWakeup = IOSyncer::create();
        !            56:         if(!fSyncWakeup)
        !            57:             return kIOReturnNoMemory;
        !            58:     }
        !            59:     fStatus = kIOReturnBusy;
        !            60:     res = fGate->runCommand(this, 0, 0);
        !            61:     if(res == kIOReturnBusy)
        !            62:         res = kIOReturnSuccess;
        !            63:     if(fSync) {
        !            64:        if(res == kIOReturnSuccess)
        !            65:             fSyncWakeup->wait();
        !            66:        else {
        !            67:             fSyncWakeup->release();
        !            68:             fSyncWakeup->release();
        !            69:             fSyncWakeup = NULL;
        !            70:        }
        !            71:     }
        !            72:     return res;
        !            73: }
        !            74: 
        !            75: IOReturn IOFWCommand::complete(IOReturn status)
        !            76: {
        !            77:     return fStatus = status;
        !            78: }
        !            79: 
        !            80: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            81: 
        !            82: #undef super
        !            83: #define super IOFWCommand
        !            84: 
        !            85: OSDefineMetaClass( IOFWBusCommand, IOFWCommand )
        !            86: OSDefineAbstractStructors(IOFWBusCommand, IOFWCommand)
        !            87: 
        !            88: bool IOFWBusCommand::initWithController(IOFireWireController *control, FWBusCallback completion, void *refcon)
        !            89: {
        !            90:     if(!super::initWithGate(control->getGate()))
        !            91:        return false;
        !            92: 
        !            93:     fControl = control;
        !            94:     fSync = completion == NULL;
        !            95:     fComplete = completion;
        !            96:     fRefCon = refcon;
        !            97:     return true;
        !            98: }
        !            99: 
        !           100: IOReturn IOFWBusCommand::reinit(FWBusCallback completion, void *refcon)
        !           101: {
        !           102:     if(fStatus == kIOReturnBusy)
        !           103:        return fStatus;
        !           104: 
        !           105:     fSync = completion == NULL;
        !           106:     fComplete = completion;
        !           107:     fRefCon = refcon;
        !           108:     return kIOReturnSuccess;
        !           109: }
        !           110: 
        !           111: 
        !           112: IOReturn IOFWBusCommand::complete(IOReturn state)
        !           113: {
        !           114:     state = super::complete(state);
        !           115:     if(fSync)
        !           116:         fSyncWakeup->signal();
        !           117:     else if(fComplete)
        !           118:        (*fComplete)(fRefCon, state, fControl, this);
        !           119:     return state;
        !           120: }
        !           121: 
        !           122: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           123: 
        !           124: #undef super
        !           125: #define super IOFWBusCommand
        !           126: 
        !           127: OSDefineMetaClassAndStructors(IOFWAllocAddressCommand, IOFWBusCommand)
        !           128: 
        !           129: bool IOFWAllocAddressCommand::initWithSpace(IOFireWireNub *device,
        !           130:        IOFWAddressSpace *space, FWBusCallback completion, void *refcon)
        !           131: {
        !           132:     IOFireWireController *control = device->fControl;
        !           133:     if(!super::initWithController(control, completion, refcon))
        !           134:        return false;
        !           135:     fSpace = space;
        !           136:     return true;
        !           137: }
        !           138: 
        !           139: IOReturn IOFWAllocAddressCommand::reinit(IOFWAddressSpace *space, 
        !           140:                                FWBusCallback completion, void *refcon)
        !           141: {
        !           142:     IOReturn res;
        !           143:     res = super::reinit(completion, refcon);
        !           144:     if(res != kIOReturnSuccess)
        !           145:        return res;
        !           146:     fSpace = space;
        !           147:     return kIOReturnSuccess;
        !           148: }
        !           149: 
        !           150: IOReturn IOFWAllocAddressCommand::execute()
        !           151: {
        !           152:     return complete(fControl->allocAddress(fSpace));
        !           153: }
        !           154: 
        !           155: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           156: 
        !           157: #undef super
        !           158: #define super IOFWBusCommand
        !           159: 
        !           160: OSDefineMetaClassAndStructors(IOFWDeallocAddressCommand, IOFWBusCommand)
        !           161: 
        !           162: bool IOFWDeallocAddressCommand::initWithSpace(IOFireWireNub *device,
        !           163:        IOFWAddressSpace *space, FWBusCallback completion, void *refcon)
        !           164: {
        !           165:     IOFireWireController *control = device->fControl;
        !           166:     if(!super::initWithController(control, completion, refcon))
        !           167:        return false;
        !           168:     fSpace = space;
        !           169:     return true;
        !           170: }
        !           171: 
        !           172: IOReturn IOFWDeallocAddressCommand::reinit(IOFWAddressSpace *space, 
        !           173:                                FWBusCallback completion, void *refcon)
        !           174: {
        !           175:     IOReturn res;
        !           176:     res = super::reinit(completion, refcon);
        !           177:     if(res != kIOReturnSuccess)
        !           178:        return res;
        !           179:     fSpace = space;
        !           180:     return kIOReturnSuccess;
        !           181: }
        !           182: 
        !           183: IOReturn IOFWDeallocAddressCommand::execute()
        !           184: {
        !           185:     fControl->freeAddress(fSpace);
        !           186:     return complete(kIOReturnSuccess);
        !           187: }
        !           188: 
        !           189: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           190: 
        !           191: #undef super
        !           192: #define super IOFWBusCommand
        !           193: 
        !           194: OSDefineMetaClassAndStructors(IOFWUpdateROM, IOFWBusCommand)
        !           195: 
        !           196: IOReturn IOFWUpdateROM::execute()
        !           197: {
        !           198:     IOReturn res;
        !           199:     res = fControl->UpdateROM();
        !           200:     if(res == kIOReturnSuccess)
        !           201:         res = fControl->resetBus();
        !           202:     return complete(res);
        !           203: }
        !           204: 
        !           205: bool IOFWUpdateROM::initWithController(IOFireWireController *control, 
        !           206:        FWBusCallback completion, void *refcon)
        !           207: {
        !           208:     return super::initWithController(control, completion, refcon);
        !           209: }
        !           210: 
        !           211: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           212: #undef super
        !           213: #define super IOFWCommand
        !           214: 
        !           215: OSDefineMetaClass( IOFWAsyncCommand, IOFWCommand )
        !           216: OSDefineAbstractStructors(IOFWAsyncCommand, IOFWCommand)
        !           217: 
        !           218: bool IOFWAsyncCommand::initAll(IOFireWireController *control,
        !           219:        IOFireWireNub *device, FWAddress devAddress,
        !           220:        IOMemoryDescriptor *hostMem, FWDeviceCallback completion,
        !           221:        void *refcon, bool failOnReset)
        !           222: {
        !           223:     if(!super::initWithGate(control->getGate()))
        !           224:        return false;
        !           225:     fControl = control;
        !           226:     fDevice = device;
        !           227:     fMemDesc = hostMem;
        !           228:     fComplete = completion;
        !           229:     fRefCon = refcon;
        !           230: 
        !           231:     if(device) {
        !           232:         fGeneration = device->fGeneration;
        !           233:         fNodeID = device->fNodeID;
        !           234:         fAddressHi = devAddress.addressHi;
        !           235:         fAddressLo = devAddress.addressLo;
        !           236:     }
        !           237:     else {
        !           238:         fGeneration = control->getGeneration();
        !           239:         fNodeID = devAddress.nodeID;
        !           240:         fAddressHi = devAddress.addressHi;
        !           241:         fAddressLo = devAddress.addressLo;
        !           242:     }
        !           243:     if(hostMem)
        !           244:         fSize = hostMem->getLength();
        !           245:     fBytesTransferred = 0;
        !           246:     fSpeed = fControl->FWSpeed(fNodeID);
        !           247:     fMaxPack = 1 << fControl->maxPackLog(true, fNodeID);
        !           248:     fFailOnReset = failOnReset;
        !           249:     fSync = completion == NULL;
        !           250:     fTrans = fControl->allocTrans();
        !           251:     return fTrans != NULL;
        !           252: }
        !           253: 
        !           254: IOReturn IOFWAsyncCommand::reinit(FWAddress devAddress, IOMemoryDescriptor *hostMem,
        !           255:                        FWDeviceCallback completion, void *refcon, bool failOnReset)
        !           256: {
        !           257:     if(fStatus == kIOReturnBusy)
        !           258:        return fStatus;
        !           259: 
        !           260:     fComplete = completion;
        !           261:     fRefCon = refcon;
        !           262: 
        !           263:     if(fDevice) {
        !           264:         fGeneration = fDevice->fGeneration;
        !           265:         fNodeID = fDevice->fNodeID;
        !           266:         fAddressHi = devAddress.addressHi;
        !           267:         fAddressLo = devAddress.addressLo;
        !           268:     }
        !           269:     else {
        !           270:         fGeneration = fControl->getGeneration();
        !           271:         fNodeID = devAddress.nodeID;
        !           272:         fAddressHi = devAddress.addressHi;
        !           273:         fAddressLo = devAddress.addressLo;
        !           274:     }
        !           275:     if(hostMem)
        !           276:         fSize = hostMem->getLength();
        !           277:     fBytesTransferred = 0;
        !           278:     fSpeed = fControl->FWSpeed(fNodeID);
        !           279:     fMaxPack = 1 << fControl->maxPackLog(true, fNodeID);
        !           280:     fFailOnReset = failOnReset;
        !           281:     fSync = completion == NULL;
        !           282:     if(!fTrans) {
        !           283:         fTrans = fControl->allocTrans();
        !           284:         if(!fTrans)
        !           285:             return fStatus = kIOReturnNoResources;
        !           286:     }
        !           287:     else
        !           288:        fTrans->fHandler = NULL;        // Not in mid execution.
        !           289:     return fStatus = kIOReturnSuccess;
        !           290: }
        !           291: 
        !           292: IOReturn IOFWAsyncCommand::complete(IOReturn status)
        !           293: {
        !           294:     status = super::complete(status);
        !           295:     if(fSync)
        !           296:         fSyncWakeup->signal();
        !           297:     else if(fComplete)
        !           298:        (*fComplete)(fRefCon, status, fDevice, this);
        !           299: 
        !           300:     // The completion routine might have reinited and executed the command,
        !           301:     // in which case don't free the transaction record.
        !           302:     if(fTrans && fStatus != kIOReturnBusy) {
        !           303:         fControl->freeTrans(fTrans);
        !           304:         fTrans = NULL;
        !           305:     }
        !           306:     release(); // We are finished, release retain() from execute().
        !           307:     return status;
        !           308: }
        !           309: 
        !           310: void IOFWAsyncCommand::gotAck(int ackCode)
        !           311: {
        !           312:     int rcode;
        !           313:     if(ackCode == kFWAckPending) {
        !           314:        // This shouldn't happen.
        !           315:        kprintf("Command 0x%x received Ack code %d\n", this, ackCode);
        !           316:        return;
        !           317:     }
        !           318:     switch (ackCode) {
        !           319:         case kFWAckComplete:
        !           320:        rcode = kFWResponseComplete;
        !           321:         break;
        !           322: 
        !           323:     // Device is still busy after several hardware retries - give up!
        !           324:     case kFWAckBusyX:
        !           325:     case kFWAckBusyA:
        !           326:     case kFWAckBusyB:
        !           327:     // Device isn't acking at all - give up!
        !           328:     case kFWAckTimeout:
        !           329:        rcode = kFWResponseAddressError;// Don't retry
        !           330:         break;
        !           331: 
        !           332:     default:
        !           333:         rcode = kFWResponseTypeError;  // Block transfers will try quad now
        !           334:     }
        !           335:     gotPacket(fControl, rcode, NULL, 0);
        !           336: }
        !           337: 
        !           338: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           339: #undef super
        !           340: #define super IOFWAsyncCommand
        !           341: 
        !           342: OSDefineMetaClassAndStructors(IOFWReadCommand, IOFWAsyncCommand)
        !           343: 
        !           344: void IOFWReadCommand::gotPacket(IOFireWireController* control,
        !           345:                                int rcode, UInt8* data, int size)
        !           346: {
        !           347:     if(rcode != kFWResponseComplete) {
        !           348:         //kprintf("Received rcode %d for read command 0x%x, nodeID %x\n", rcode, this, fNodeID);
        !           349:         if(rcode == kFWResponseTypeError && fMaxPack > 4) {
        !           350:             // try reading a quad at a time
        !           351:             fMaxPack = 4;
        !           352:             size = 0;
        !           353:         }
        !           354:         else {
        !           355:             complete(kIOFireWireResponseBase+rcode);
        !           356:             return;
        !           357:         }
        !           358:     }
        !           359:     else {
        !           360:         fMemDesc->writeBytes(fBytesTransferred, data, size);
        !           361:         fSize -= size;
        !           362:        fBytesTransferred += size;
        !           363:     }
        !           364: 
        !           365:     if(fSize > 0) {
        !           366:         int transfer;
        !           367:         fAddressLo += size;
        !           368:         if(!fControl->checkGeneration(fGeneration)) {
        !           369:             complete(kIOFireWireBusReset);
        !           370:         }
        !           371: 
        !           372:         transfer = fSize;
        !           373:         if(transfer > fMaxPack)
        !           374:             transfer = fMaxPack;
        !           375: 
        !           376:         fControl->asyncRead(fNodeID, fAddressHi,
        !           377:                         fAddressLo, fSpeed, fTrans->fTCode, transfer, this);
        !           378:     }
        !           379:     else {
        !           380:         complete(kIOReturnSuccess);
        !           381:     }
        !           382: }
        !           383: 
        !           384: bool IOFWReadCommand::initAll(IOFireWireNub *device, FWAddress devAddress,
        !           385:        IOMemoryDescriptor *hostMem, FWDeviceCallback completion,
        !           386:        void *refcon, bool failOnReset)
        !           387: {
        !           388:     if(!super::initAll(device->fControl, device, devAddress,
        !           389:        hostMem, completion, refcon, failOnReset))
        !           390:        return false;
        !           391: 
        !           392:     return true;
        !           393: 
        !           394: }
        !           395: 
        !           396: IOReturn IOFWReadCommand::reinit(FWAddress devAddress,
        !           397:        IOMemoryDescriptor *hostMem,
        !           398:        FWDeviceCallback completion, void *refcon, bool failOnReset)
        !           399: {
        !           400:     return super::reinit(devAddress,
        !           401:        hostMem, completion, refcon, failOnReset);
        !           402: }
        !           403: 
        !           404: IOReturn IOFWReadCommand::execute()
        !           405: {
        !           406:     int transfer;
        !           407: 
        !           408:     // Make sure object survives until complete() is called!
        !           409:     retain();
        !           410:     fStatus = kIOReturnBusy;
        !           411: 
        !           412:     // Do this when we're in execute, not before,
        !           413:     // so that Reset handling knows which commands are waiting a response.
        !           414:     fTrans->fHandler = this;
        !           415: 
        !           416:     if(!fControl->checkGeneration(fGeneration)) {
        !           417:         return complete(kIOFireWireBusReset);
        !           418:     }
        !           419: 
        !           420:     transfer = fSize;
        !           421:     if(transfer > fMaxPack)
        !           422:        transfer = fMaxPack;
        !           423: 
        !           424:     fControl->asyncRead(fNodeID, fAddressHi,
        !           425:                     fAddressLo, fSpeed, fTrans->fTCode, transfer, this);
        !           426: 
        !           427:     return (kIOReturnBusy);
        !           428: }
        !           429: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           430: #undef super
        !           431: #define super IOFWAsyncCommand
        !           432: 
        !           433: OSDefineMetaClassAndStructors(IOFWReadQuadCommand, IOFWAsyncCommand)
        !           434: void IOFWReadQuadCommand::gotPacket(IOFireWireController* control,
        !           435:                                int rcode, UInt8* data, int size)
        !           436: {
        !           437:     if(rcode != kFWResponseComplete) {
        !           438:         //kprintf("Received rcode %d for read command 0x%x, nodeID %x\n", rcode, this, fNodeID);
        !           439:         if(rcode == kFWResponseTypeError && fMaxPack > 4) {
        !           440:             // try reading a quad at a time
        !           441:             fMaxPack = 4;
        !           442:             size = 0;
        !           443:         }
        !           444:         else {
        !           445:             complete(kIOFireWireResponseBase+rcode);
        !           446:             return;
        !           447:         }
        !           448:     }
        !           449:     else {
        !           450:         int i;
        !           451:         UInt32 *src = (UInt32 *)data;
        !           452:         for(i=0; i<size/4; i++)
        !           453:             *fQuads++ = *src++;
        !           454:         fSize -= size;
        !           455:     }
        !           456: 
        !           457:     if(fSize > 0) {
        !           458:         int transfer;
        !           459: 
        !           460:         fAddressLo += size;
        !           461:         if(!fControl->checkGeneration(fGeneration)) {
        !           462:             complete(kIOFireWireBusReset);
        !           463:         }
        !           464:         transfer = fSize;
        !           465:         if(transfer > fMaxPack)
        !           466:             transfer = fMaxPack;
        !           467: 
        !           468:         fControl->asyncRead(fNodeID, fAddressHi,
        !           469:                         fAddressLo, fSpeed, fTrans->fTCode, transfer, this);
        !           470:     }
        !           471:     else {
        !           472:         complete(kIOReturnSuccess);
        !           473:     }
        !           474: }
        !           475: 
        !           476: bool IOFWReadQuadCommand::initAll(IOFireWireController *control, 
        !           477:        IOFireWireNub *device, FWAddress devAddress,
        !           478:        UInt32 *quads, int numQuads, FWDeviceCallback completion,
        !           479:        void *refcon, bool failOnReset)
        !           480: {
        !           481:     if(!super::initAll(control, device, devAddress,
        !           482:        NULL, completion, refcon, failOnReset))
        !           483:        return false;
        !           484:     fSize = 4*numQuads;
        !           485:     fQuads = quads;
        !           486:     return true;
        !           487: }
        !           488: 
        !           489: IOReturn IOFWReadQuadCommand::reinit(FWAddress devAddress,
        !           490:        UInt32 *quads, int numQuads, FWDeviceCallback completion,
        !           491:                                        void *refcon, bool failOnReset)
        !           492: {
        !           493:     IOReturn res;
        !           494:     res = super::reinit(devAddress,
        !           495:        NULL, completion, refcon, failOnReset);
        !           496:     if(res != kIOReturnSuccess)
        !           497:        return res;
        !           498: 
        !           499:     fSize = 4*numQuads;
        !           500:     fQuads = quads;
        !           501:     return res;
        !           502: }
        !           503: 
        !           504: IOReturn IOFWReadQuadCommand::execute()
        !           505: {
        !           506:     int transfer;
        !           507: 
        !           508:     // Make sure object survives until complete() is called!
        !           509:     retain();
        !           510:     fStatus = kIOReturnBusy;
        !           511: 
        !           512:     // Do this when we're in execute, not before,
        !           513:     // so that Reset handling knows which commands are waiting a response.
        !           514:     fTrans->fHandler = this;
        !           515: 
        !           516:     if(!fControl->checkGeneration(fGeneration)) {
        !           517:         return complete(kIOFireWireBusReset);
        !           518:     }
        !           519:     transfer = fSize;
        !           520:     if(transfer > fMaxPack)
        !           521:        transfer = fMaxPack;
        !           522: 
        !           523:     fControl->asyncRead(fNodeID, fAddressHi,
        !           524:                     fAddressLo, fSpeed, fTrans->fTCode, transfer, this);
        !           525: 
        !           526:     return (kIOReturnBusy);
        !           527: }
        !           528: 
        !           529: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           530: #undef super
        !           531: #define super IOFWAsyncCommand
        !           532: 
        !           533: OSDefineMetaClassAndStructors(IOFWWriteCommand, IOFWAsyncCommand)
        !           534: 
        !           535: void IOFWWriteCommand::gotPacket(IOFireWireController* control,
        !           536:                                int rcode, UInt8* data, int size)
        !           537: {
        !           538:     if(rcode != kFWResponseComplete) {
        !           539:         //kprintf("Received rcode %d for command 0x%x\n", rcode, this);
        !           540:         if(rcode == kFWResponseTypeError && fMaxPack > 4) {
        !           541:             // try writing a quad at a time
        !           542:             fMaxPack = 4;
        !           543:             fPackSize = 0;
        !           544:         }
        !           545:         else {
        !           546:             complete(kIOFireWireResponseBase+rcode);
        !           547:             return;
        !           548:         }
        !           549:     }
        !           550:     else {
        !           551:        fBytesTransferred += fPackSize;
        !           552:         fSize -= fPackSize;
        !           553:     }
        !           554: 
        !           555:     if(fSize > 0) {
        !           556:         fAddressLo += fPackSize;
        !           557: 
        !           558:         if(!fControl->checkGeneration(fGeneration)) {
        !           559:             complete(kIOFireWireBusReset);
        !           560:         }
        !           561: 
        !           562:         fPackSize = fSize;
        !           563:         if(fPackSize > fMaxPack)
        !           564:             fPackSize = fMaxPack;
        !           565: 
        !           566:         fControl->asyncWrite(fNodeID, fAddressHi, fAddressLo, fSpeed,
        !           567:             fTrans->fTCode, fMemDesc, fPackSize, this);
        !           568: 
        !           569:     }
        !           570:     else {
        !           571:         complete(kIOReturnSuccess);
        !           572:     }
        !           573: }
        !           574: 
        !           575: bool IOFWWriteCommand::initAll(IOFireWireNub *device, FWAddress devAddress,
        !           576:        IOMemoryDescriptor *hostMem, FWDeviceCallback completion,
        !           577:        void *refcon, bool failOnReset)
        !           578: {
        !           579:     if(!super::initAll(device->fControl, device, devAddress,
        !           580:        hostMem, completion, refcon, failOnReset))
        !           581:        return false;
        !           582:     return true;
        !           583: }
        !           584: 
        !           585: IOReturn IOFWWriteCommand::reinit(FWAddress devAddress,
        !           586:        IOMemoryDescriptor *hostMem,
        !           587:        FWDeviceCallback completion, void *refcon, bool failOnReset)
        !           588: {
        !           589:     return super::reinit(devAddress,
        !           590:        hostMem, completion, refcon, failOnReset);
        !           591: }
        !           592: 
        !           593: IOReturn IOFWWriteCommand::execute()
        !           594: {
        !           595:     // Make sure object survives until complete() is called!
        !           596:     retain();
        !           597:     fStatus = kIOReturnBusy;
        !           598: 
        !           599:     // Do this when we're in execute, not before,
        !           600:     // so that Reset handling knows which commands are waiting a response.
        !           601:     fTrans->fHandler = this;
        !           602: 
        !           603:     if(!fControl->checkGeneration(fGeneration)) {
        !           604:         return complete(kIOFireWireBusReset);
        !           605:     }
        !           606: 
        !           607:     fPackSize = fSize;
        !           608:     if(fPackSize > fMaxPack)
        !           609:        fPackSize = fMaxPack;
        !           610: 
        !           611:     fControl->asyncWrite(fNodeID, fAddressHi, fAddressLo, fSpeed, 
        !           612:        fTrans->fTCode, fMemDesc, fPackSize, this);
        !           613: 
        !           614:     return (kIOReturnBusy);
        !           615: }
        !           616: 
        !           617: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           618: #undef super
        !           619: #define super IOFWAsyncCommand
        !           620: 
        !           621: OSDefineMetaClassAndStructors(IOFWWriteQuadCommand, IOFWAsyncCommand)
        !           622: void IOFWWriteQuadCommand::gotPacket(IOFireWireController* control,
        !           623:                                int rcode, UInt8* data, int size)
        !           624: {
        !           625:     if(rcode != kFWResponseComplete) {
        !           626:         //kprintf("Received rcode %d for command 0x%x\n", rcode, this);
        !           627:         if(rcode == kFWResponseTypeError && fMaxPack > 4) {
        !           628:             // try writing a quad at a time
        !           629:             fMaxPack = 4;
        !           630:             fPackSize = 0;
        !           631:         }
        !           632:         else {
        !           633:             complete(kIOFireWireResponseBase+rcode);
        !           634:             return;
        !           635:         }
        !           636:     }
        !           637:     else {
        !           638:         fQPtr += fPackSize/4;
        !           639:         fSize -= fPackSize;
        !           640:     }
        !           641: 
        !           642:     if(fSize > 0) {
        !           643:         fAddressLo += fPackSize;
        !           644: 
        !           645:         if(!fControl->checkGeneration(fGeneration)) {
        !           646:             complete(kIOFireWireBusReset);
        !           647:         }
        !           648: 
        !           649:         fPackSize = fSize;
        !           650:         if(fPackSize > fMaxPack)
        !           651:             fPackSize = fMaxPack;
        !           652: 
        !           653:         fControl->asyncWrite(fNodeID, fAddressHi, fAddressLo,
        !           654:             fSpeed, fTrans->fTCode, fQPtr, fPackSize, this);
        !           655:     }
        !           656:     else {
        !           657:         complete(kIOReturnSuccess);
        !           658:     }
        !           659: }
        !           660: 
        !           661: bool IOFWWriteQuadCommand::initAll(IOFireWireController *control, 
        !           662:        IOFireWireNub *device, FWAddress devAddress,
        !           663:        UInt32 *quads, int numQuads, FWDeviceCallback completion,
        !           664:        void *refcon, bool failOnReset)
        !           665: {
        !           666:     int i;
        !           667:     if(numQuads > 2)
        !           668:        return false;
        !           669: 
        !           670:     if(!super::initAll(control, device, devAddress,
        !           671:        NULL, completion, refcon, failOnReset))
        !           672:        return false;
        !           673:     fSize = 4*numQuads;
        !           674:     for(i=0; i<numQuads; i++)
        !           675:         fQuads[i] = *quads++;
        !           676:     fQPtr = fQuads;
        !           677:     return true;
        !           678: }
        !           679: 
        !           680: IOReturn IOFWWriteQuadCommand::reinit(FWAddress devAddress,
        !           681:        UInt32 *quads, int numQuads, FWDeviceCallback completion,
        !           682:                                        void *refcon, bool failOnReset)
        !           683: {
        !           684:     IOReturn res;
        !           685:     int i;
        !           686:     if(numQuads > 2)
        !           687:        return kIOReturnUnsupported;
        !           688:     res = super::reinit(devAddress,
        !           689:        NULL, completion, refcon, failOnReset);
        !           690:     if(res != kIOReturnSuccess)
        !           691:        return res;
        !           692: 
        !           693:     fSize = 4*numQuads;
        !           694:     for(i=0; i<numQuads; i++)
        !           695:         fQuads[i] = *quads++;
        !           696:     fQPtr = fQuads;
        !           697:     return res;
        !           698: }
        !           699: 
        !           700: IOReturn IOFWWriteQuadCommand::execute()
        !           701: {
        !           702:     // Make sure object survives until complete() is called!
        !           703:     retain();
        !           704:     fStatus = kIOReturnBusy;
        !           705: 
        !           706:     // Do this when we're in execute, not before,
        !           707:     // so that Reset handling knows which commands are waiting a response.
        !           708:     fTrans->fHandler = this;
        !           709: 
        !           710:     if(!fControl->checkGeneration(fGeneration)) {
        !           711:         return complete(kIOFireWireBusReset);
        !           712:     }
        !           713: 
        !           714:     fPackSize = fSize;
        !           715:     if(fPackSize > fMaxPack)
        !           716:        fPackSize = fMaxPack;
        !           717: 
        !           718:     fControl->asyncWrite(fNodeID, fAddressHi, fAddressLo,
        !           719:        fSpeed, fTrans->fTCode, fQPtr, fPackSize, this);
        !           720: 
        !           721:     return (kIOReturnBusy);
        !           722: }
        !           723: 
        !           724: 
        !           725: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           726: #undef super
        !           727: #define super IOFWAsyncCommand
        !           728: 
        !           729: OSDefineMetaClassAndStructors(IOFWCompareAndSwapCommand, IOFWAsyncCommand)
        !           730: 
        !           731: void IOFWCompareAndSwapCommand::gotPacket(IOFireWireController* control,
        !           732:                                int rcode, UInt8* data, int size)
        !           733: {
        !           734:     int i;
        !           735:     if(rcode != kFWResponseComplete) {
        !           736:         kprintf("Received rcode %d for lock command 0x%x, nodeID %x\n", rcode, this, fNodeID);
        !           737:         complete(kIOFireWireResponseBase+rcode);
        !           738:         return;
        !           739:     }
        !           740:     for(i=0; i<size/4; i++) {
        !           741:        fOldVal[i] = ((UInt32 *)data)[i];
        !           742:     }
        !           743:     complete(kIOReturnSuccess);
        !           744: }
        !           745: 
        !           746: bool IOFWCompareAndSwapCommand::initAll(IOFireWireNub *device, FWAddress devAddress,
        !           747:        const UInt32 *cmpVal, const UInt32 *newVal, int size, FWDeviceCallback completion,
        !           748:        void *refcon, bool failOnReset)
        !           749: {
        !           750:     int i;
        !           751:     if(!super::initAll(device->fControl, device, devAddress,
        !           752:        NULL, completion, refcon, failOnReset))
        !           753:        return false;
        !           754:     for(i=0; i<size; i++) {
        !           755:         fInputVals[i] = cmpVal[i];
        !           756:         fInputVals[size+i] = newVal[i];
        !           757:     }
        !           758:     fSize = 8*size;
        !           759:     return true;
        !           760: }
        !           761: 
        !           762: IOReturn IOFWCompareAndSwapCommand::execute()
        !           763: {
        !           764:     // Make sure object survives until complete() is called!
        !           765:     retain();
        !           766:     if(!fControl->checkGeneration(fGeneration)) {
        !           767:         return complete(kIOFireWireBusReset);
        !           768:     }
        !           769: 
        !           770:     fStatus = kIOReturnBusy;
        !           771: 
        !           772:     // Do this when we're in execute, not before,
        !           773:     // so that Reset handling knows which commands are waiting a response.
        !           774:     fTrans->fHandler = this;
        !           775: 
        !           776:     fControl->asyncLock(fNodeID, fAddressHi, fAddressLo, fSpeed,
        !           777:                fTrans->fTCode, kFWExtendedTCodeCompareSwap,
        !           778:                fInputVals, fSize, this);
        !           779: 
        !           780:     return (kIOReturnBusy);
        !           781: }
        !           782: 
        !           783: bool IOFWCompareAndSwapCommand::locked(UInt32 *oldVal)
        !           784: {
        !           785:     int i;
        !           786:     bool ret = true;
        !           787:     for(i = 0; i<fSize/8; i++) {
        !           788:         ret = ret && (fInputVals[i] == fOldVal[i]);
        !           789:        oldVal[i] = fOldVal[i];
        !           790:     }
        !           791:     return ret;
        !           792: }

unix.superglobalmegacorp.com

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