|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.