Annotation of XNU/iokit/Families/IOFireWire/IOFWCommand.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 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.