|
|
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.