|
|
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: * IOSCSIParallelController.cpp
24: *
25: */
26:
27: #include <IOKit/scsi/IOSCSIParallelInterface.h>
28: #include <IOKit/IOSyncer.h>
29:
30: #undef super
31: #define super IOService
32:
33: OSDefineMetaClass( IOSCSIParallelController, IOService )
34: OSDefineAbstractStructors( IOSCSIParallelController, IOService );
35:
36: #define round(x,y) (((int)(x) + (y) - 1) & ~((y)-1))
37:
38: /*
39: *
40: *
41: */
42: bool IOSCSIParallelController::start( IOService *forProvider )
43: {
44: provider = forProvider;
45:
46: if ( provider->open( this ) != true )
47: {
48: return false;
49: }
50:
51: if ( createWorkLoop() != true )
52: {
53: return false;
54: }
55:
56: if ( configureController() == false )
57: {
58: provider->close( this );
59: return false;
60: }
61:
62: initQueues();
63:
64: if ( scanSCSIBus() == false )
65: {
66: provider->close( this );
67: return false;
68: }
69:
70: return true;
71: }
72:
73: /*
74: *
75: *
76: *
77: */
78: bool IOSCSIParallelController::scanSCSIBus()
79: {
80: SCSITargetLun targetLun;
81: UInt32 i;
82:
83: targetLun.lun = 0;
84:
85: for ( i=0; i < controllerInfo.maxTargetsSupported; i++ )
86: {
87: targetLun.target = i;
88: probeTarget( targetLun );
89: }
90:
91: return true;
92: }
93:
94: /*
95: *
96: *
97: *
98: */
99: bool IOSCSIParallelController::probeTarget( SCSITargetLun targetLun )
100: {
101: IOSCSIParallelDevice *device;
102: UInt32 i;
103:
104: if ( targetLun.target == controllerInfo.initiatorId )
105: {
106: return false;
107: }
108:
109: if ( workLoopRequest( kWorkLoopInitTarget, *(UInt32 *)&targetLun ) == false )
110: {
111: releaseTarget( targetLun );
112: return false;
113: }
114:
115: for ( i=0; i < controllerInfo.maxLunsSupported; i++ )
116: {
117: targetLun.lun = i;
118:
119: device = createDevice();
120: if ( device == 0 )
121: {
122: break;
123: }
124:
125: if ( device->init( this, targetLun ) == false )
126: {
127: releaseDevice( device );
128: break;
129: }
130:
131: if ( workLoopRequest( kWorkLoopInitDevice, (UInt32)device ) == false )
132: {
133: releaseDevice( device );
134: }
135:
136: // IOLog("Target %d Lun %d - created\n\r", targetLun.target, targetLun.lun );
137:
138: if ( device->probeTargetLun() != kIOReturnSuccess )
139: {
140: // IOLog("Target %d Lun %d - no response\n\r", targetLun.target, targetLun.lun );
141:
142: releaseDevice( device );
143:
144: if ( i == 0 ) break;
145: }
146: }
147:
148: if ( i == 0 )
149: {
150: releaseTarget( targetLun );
151: return false;
152: }
153:
154: queue_iterate( &targets[targetLun.target].deviceList, device, IOSCSIParallelDevice *, nextDevice )
155: {
156: device->setupTarget();
157: device->attach( this );
158: device->registerService();
159: }
160:
161: return true;
162: }
163:
164: /*
165: *
166: *
167: *
168: */
169: bool IOSCSIParallelController::initTarget( SCSITargetLun targetLun )
170: {
171: SCSITarget *target;
172:
173: target = &targets[targetLun.target];
174:
175: assert ( target->clientSem == 0 );
176: assert ( target->targetSem == 0 );
177:
178: bzero( target, sizeof(SCSITarget) );
179:
180: queue_init( &targets[targetLun.target].deviceList );
181:
182: target->clientSem = IORWLockAlloc();
183: target->targetSem = IORWLockAlloc();
184: if( (target->targetSem == 0) || (target->clientSem == 0))
185: {
186: return false;
187: }
188: target->commandLimitSave = target->commandLimit = 1;
189:
190: target->targetParmsCurrent.transferWidth = 1;
191:
192: if ( controllerInfo.targetPrivateDataSize != 0 )
193: {
194: target->targetPrivateData = IOMallocContiguous( controllerInfo.targetPrivateDataSize, 16, 0 );
195: if ( target->targetPrivateData == 0 )
196: {
197: return false;
198: }
199: }
200:
201: if ( controllerInfo.tagAllocationMethod == kTagAllocationPerTarget )
202: {
203: target->tagArray = (UInt32 *)IOMalloc( tagArraySize );
204: if ( target->tagArray == 0 )
205: {
206: return false;
207: }
208: bzero( target->tagArray, tagArraySize );
209: }
210:
211: return true;
212: }
213:
214: /*
215: *
216: *
217: *
218: */
219: void IOSCSIParallelController::releaseTarget( SCSITargetLun targetLun )
220: {
221: SCSITarget *target;
222:
223: workLoopRequest( kWorkLoopReleaseTarget, *(UInt32 *)&targetLun );
224:
225: target = &targets[targetLun.target];
226: if ( target->tagArray != 0 )
227: {
228: IOFree( target->tagArray, tagArraySize );
229: target->tagArray = 0;
230: }
231:
232: if ( target->targetPrivateData != 0 )
233: {
234: IOFreeContiguous( target->targetPrivateData, controllerInfo.targetPrivateDataSize );
235: target->targetPrivateData = 0;
236: }
237:
238: if ( target->clientSem != 0 )
239: {
240: IORWLockFree( target->clientSem );
241: }
242: if ( target->targetSem != 0 )
243: {
244: IORWLockFree( target->targetSem );
245: }
246: }
247:
248: /*
249: *
250: *
251: *
252: */
253: void IOSCSIParallelController::releaseDevice( IOSCSIParallelDevice *device )
254: {
255: workLoopRequest( kWorkLoopReleaseDevice, (UInt32) device );
256:
257: device->release();
258: }
259:
260: /*
261: *
262: *
263: *
264: */
265: bool IOSCSIParallelController::workLoopRequest( WorkLoopReqType type, UInt32 p1, UInt32 p2, UInt32 p3 )
266: {
267: WorkLoopRequest workLoopReq;
268:
269: bzero( &workLoopReq, sizeof(WorkLoopRequest) );
270: workLoopReq.type = type;
271: workLoopReq.sync = IOSyncer::create();
272:
273: workLoopReqGate->runCommand( &workLoopReq, (void *)p1, (void *)p2, (void *)p3 );
274:
275: workLoopReq.sync->wait();
276:
277: return( workLoopReq.rc );
278: }
279:
280:
281: /*
282: *
283: *
284: *
285: */
286: void IOSCSIParallelController::workLoopProcessRequest( WorkLoopRequest *workLoopReq, void *p1, void *p2, void *p3 )
287: {
288: bool rc = true;
289: IOSCSIParallelDevice *device;
290: SCSITargetLun targetLun;
291:
292: switch ( workLoopReq->type )
293: {
294: case kWorkLoopInitTarget:
295: targetLun = *(SCSITargetLun *)&p1;
296: rc = initTarget( targetLun );
297: if ( rc == false )
298: {
299: break;
300: }
301: rc = allocateTarget( targetLun );
302: break;
303:
304: case kWorkLoopReleaseTarget:
305: targetLun = *(SCSITargetLun *) &p1;
306: if ( queue_empty( &targets[targetLun.target].deviceList ) != true )
307: {
308: IOLog("IOSCSIParallelController()::Target %d deleted with lun(s) active!\n\r",
309: targetLun.target );
310: }
311: deallocateTarget( targetLun );
312: break;
313:
314: case kWorkLoopInitDevice:
315: device = (IOSCSIParallelDevice *) p1;
316: addDevice( device );
317: rc = allocateLun( device->targetLun );
318: break;
319:
320: case kWorkLoopReleaseDevice:
321: device = (IOSCSIParallelDevice *) p1;
322: deleteDevice( device );
323: deallocateLun( device->targetLun );
324: break;
325: }
326:
327: workLoopReq->rc = rc;
328: workLoopReq->sync->signal();
329: }
330:
331: /*
332: *
333: *
334: *
335: */
336: void IOSCSIParallelController::addDevice( IOSCSIParallelDevice *forDevice )
337: {
338: UInt32 targetID;
339:
340: targetID = forDevice->targetLun.target;
341:
342: forDevice->target = &targets[targetID];
343: queue_enter( &targets[targetID].deviceList, forDevice, IOSCSIParallelDevice *, nextDevice );
344: }
345:
346: /*
347: *
348: *
349: *
350: */
351: void IOSCSIParallelController::deleteDevice( IOSCSIParallelDevice *forDevice )
352: {
353: queue_head_t *deviceList;
354: IOSCSIParallelDevice *device;
355: UInt32 targetID;
356:
357: targetID = forDevice->targetLun.target;
358:
359: deviceList = &targets[targetID].deviceList;
360:
361: queue_iterate( deviceList, device, IOSCSIParallelDevice *, nextDevice )
362: {
363: if ( device == forDevice )
364: {
365: queue_remove( &targets[targetID].deviceList, device, IOSCSIParallelDevice *, nextDevice );
366: break;
367: }
368: }
369: }
370:
371: /*
372: *
373: *
374: *
375: */
376: bool IOSCSIParallelController::allocateTarget( SCSITargetLun targetLun )
377: {
378: return true;
379: }
380:
381: /*
382: *
383: *
384: *
385: */
386: void IOSCSIParallelController::deallocateTarget( SCSITargetLun targetLun )
387: {
388: }
389:
390: /*
391: *
392: *
393: *
394: */
395: bool IOSCSIParallelController::allocateLun( SCSITargetLun targetLun )
396: {
397: return true;
398: }
399:
400: /*
401: *
402: *
403: *
404: */
405: void IOSCSIParallelController::deallocateLun( SCSITargetLun targetLun )
406: {
407: }
408:
409:
410: /*
411: *
412: *
413: *
414: */
415: void *IOSCSIParallelController::getTargetData( SCSITargetLun targetLun )
416: {
417: return targets[targetLun.target].targetPrivateData;
418: }
419:
420: /*
421: *
422: *
423: *
424: */
425: void *IOSCSIParallelController::getLunData( SCSITargetLun targetLun )
426: {
427: queue_head_t *deviceList;
428: IOSCSIParallelDevice *device;
429:
430: deviceList = &targets[targetLun.target].deviceList;
431:
432: queue_iterate( deviceList, device, IOSCSIParallelDevice *, nextDevice )
433: {
434: if ( device->targetLun.lun == targetLun.lun )
435: {
436: return device->devicePrivateData;
437: }
438: }
439: return 0;
440: }
441:
442:
443:
444: /*
445: *
446: *
447: *
448: */
449: IOSCSIParallelDevice *IOSCSIParallelController::createDevice()
450: {
451: return new IOSCSIParallelDevice;
452: }
453:
454:
455: /*
456: *
457: *
458: *
459: */
460: void IOSCSIParallelController::initQueues()
461: {
462: UInt32 i;
463:
464: for ( i=0; i < controllerInfo.maxTargetsSupported; i++ )
465: {
466: queue_init( &targets[i].deviceList );
467: }
468:
469: resetCmd = allocCommand( 0 );
470: resetCmd->cmdType = kSCSICommandBusReset;
471:
472: timer( timerEvent );
473: }
474:
475: /*
476: *
477: *
478: *
479: */
480: void IOSCSIParallelController::reset()
481: {
482: IOSCSIParallelDevice *device;
483: UInt32 i;
484:
485: if ( busResetState != kStateIssue )
486: {
487: return;
488: }
489:
490: busResetState = kStateActive;
491:
492: for (i=0; i < controllerInfo.maxTargetsSupported; i++ )
493: {
494: queue_iterate( &targets[i].deviceList, device, IOSCSIParallelDevice *, nextDevice )
495: {
496: if ( device->client != 0 )
497: {
498: device->client->message( kSCSIClientMsgBusReset, device );
499: }
500: }
501: }
502:
503: resetCommand( resetCmd );
504: }
505:
506: /*
507: *
508: *
509: *
510: */
511: bool IOSCSIParallelController::checkBusReset()
512: {
513: if ( busResetState == kStateIdle )
514: {
515: return false;
516: }
517: if ( busResetState == kStateIssue )
518: {
519: reset();
520: }
521: return true;
522: }
523:
524:
525: /*
526: *
527: *
528: *
529: */
530: void IOSCSIParallelController::resetOccurred()
531: {
532: UInt32 i;
533: IOSCSIParallelDevice *device;
534: SCSITarget *target;
535: SCSIClientMessage clientMsg;
536:
537: for (i=0; i < controllerInfo.maxTargetsSupported; i++ )
538: {
539: target = &targets[i];
540:
541: target->commandLimit = target->commandLimitSave;
542: target->reqSenseCount = 0;
543: target->reqSenseState = kStateIdle;
544: target->negotiateState = kStateIssue;
545:
546: target->targetParmsCurrent.transferPeriodpS = 0;
547: target->targetParmsCurrent.transferOffset = 0;
548: target->targetParmsCurrent.transferWidth = 1;
549:
550: noDisconnectCmd = 0;
551:
552: clientMsg = ( busResetState != kStateActive ) ? kSCSIClientMsgBusReset : kSCSIClientMsgNone;
553:
554: queue_iterate( &target->deviceList, device, IOSCSIParallelDevice *, nextDevice )
555: {
556: device->resetOccurred( clientMsg );
557: }
558: }
559:
560: resetTimer = (kSCSIResetIntervalmS / kSCSITimerIntervalmS + 1);
561: }
562:
563:
564: /*
565: *
566: *
567: */
568: void IOSCSIParallelController::timer( IOTimerEventSource * /* timer */ )
569: {
570: UInt32 i;
571: IOSCSIParallelDevice *device;
572:
573:
574: if ( disableTimer )
575: {
576: if ( !--disableTimer )
577: {
578: disableTimeoutOccurred();
579: }
580: }
581:
582: if ( resetTimer )
583: {
584: if ( !--resetTimer )
585: {
586: for (i=0; i < controllerInfo.maxTargetsSupported; i++ )
587: {
588: queue_iterate( &targets[i].deviceList, device, IOSCSIParallelDevice *, nextDevice )
589: {
590: device->resetComplete();
591: }
592: }
593:
594: }
595: }
596: else
597: {
598: for (i=0; i < controllerInfo.maxTargetsSupported; i++ )
599: {
600: queue_iterate( &targets[i].deviceList, device, IOSCSIParallelDevice *, nextDevice )
601: {
602: device->timer();
603: }
604: }
605: }
606:
607: timerEvent->setTimeoutMS(kSCSITimerIntervalmS);
608: }
609:
610:
611: /*
612: *
613: *
614: *
615: */
616: void IOSCSIParallelController::completeCommand( IOSCSIParallelCommand *scsiCmd )
617: {
618: switch ( scsiCmd->cmdType )
619: {
620: case kSCSICommandBusReset:
621: resetOccurred();
622: busResetState = kStateIdle;
623: break;
624: default:
625: ;
626: }
627: }
628:
629:
630: /*
631: *
632: *
633: *
634: */
635: bool IOSCSIParallelController::createWorkLoop()
636: {
637: workLoop = new IOWorkLoop;
638: if ( workLoop == NULL )
639: {
640: return false;
641: }
642:
643: if ( workLoop->init() != true )
644: {
645: return false;
646: }
647:
648: timerEvent = IOTimerEventSource::timerEventSource( this, (IOTimerEventSource::Action) &IOSCSIParallelController::timer );
649: if ( timerEvent == NULL )
650: {
651: return false;
652: }
653:
654: if ( workLoop->addEventSource( timerEvent ) != kIOReturnSuccess )
655: {
656: return false;
657: }
658:
659:
660: dispatchEvent = IOInterruptEventSource::interruptEventSource( this,
661: (IOInterruptEventAction) &IOSCSIParallelController::dispatch,
662: 0 );
663: if ( dispatchEvent == 0 )
664: {
665: return false;
666: }
667:
668: if ( workLoop->addEventSource( dispatchEvent ) != kIOReturnSuccess )
669: {
670: return false;
671: }
672:
673: workLoopReqGate = IOCommandGate::commandGate( this, (IOCommandGate::Action) &IOSCSIParallelController::workLoopProcessRequest );
674: if ( workLoopReqGate == NULL )
675: {
676: return false;
677: }
678:
679: if ( workLoop->addEventSource( workLoopReqGate ) != kIOReturnSuccess )
680: {
681: return false;
682: }
683:
684:
685: return true;
686: }
687:
688: /*
689: *
690: *
691: *
692: */
693: IOSCSIParallelCommand *IOSCSIParallelController::findCommandWithNexus( SCSITargetLun targetLun, UInt32 tagValue = (UInt32)-1 )
694: {
695: IOSCSIParallelDevice *device;
696:
697: device = findDeviceWithTargetLun( targetLun );
698: if ( device == 0 )
699: {
700: return NULL;
701: }
702:
703: return device->findCommandWithNexus( tagValue );
704: }
705:
706:
707: /*
708: *
709: *
710: *
711: */
712: IOSCSIParallelDevice *IOSCSIParallelController::findDeviceWithTargetLun( SCSITargetLun targetLun )
713: {
714: IOSCSIParallelDevice *device;
715:
716: if ( targetLun.target > controllerInfo.maxTargetsSupported || targetLun.lun > controllerInfo.maxLunsSupported )
717: {
718: return 0;
719: }
720:
721: queue_iterate( &targets[targetLun.target].deviceList, device, IOSCSIParallelDevice *, nextDevice )
722: {
723: if ( device->targetLun.lun == targetLun.lun )
724: {
725: return device;
726: }
727: }
728: return 0;
729: }
730:
731:
732: /*
733: *
734: *
735: *
736: */
737: bool IOSCSIParallelController::configureController()
738: {
739: UInt32 targetsSize;
740:
741: if ( configure( provider, &controllerInfo ) == false )
742: {
743: return false;
744: }
745:
746: controllerInfo.commandPrivateDataSize = round( controllerInfo.commandPrivateDataSize, 16 );
747:
748: if ( controllerInfo.maxCommandsPerController == 0 ) controllerInfo.maxCommandsPerController = (UInt32) -1;
749: if ( controllerInfo.maxCommandsPerTarget == 0 ) controllerInfo.maxCommandsPerTarget = (UInt32) -1;
750: if ( controllerInfo.maxCommandsPerLun == 0 ) controllerInfo.maxCommandsPerLun = (UInt32) -1;
751:
752: targetsSize = controllerInfo.maxTargetsSupported * sizeof(SCSITarget);
753: targets = (SCSITarget *)IOMalloc( targetsSize );
754: bzero( targets, targetsSize );
755:
756: commandLimit = commandLimitSave = controllerInfo.maxCommandsPerController;
757:
758: tagArraySize = (controllerInfo.maxTags / 32 + ((controllerInfo.maxTags % 32) ? 1 : 0)) * sizeof(UInt32);
759:
760: if ( controllerInfo.tagAllocationMethod == kTagAllocationPerController )
761: {
762: tagArray = (UInt32 *)IOMalloc( tagArraySize );
763: bzero( tagArray, tagArraySize );
764: }
765:
766: return true;
767: }
768:
769: /*
770: *
771: *
772: *
773: */
774: void IOSCSIParallelController::setCommandLimit( UInt32 newCommandLimit )
775: {
776: if ( newCommandLimit == 0 ) controllerInfo.maxCommandsPerController = (UInt32) -1;
777:
778: commandLimit = commandLimitSave = controllerInfo.maxCommandsPerController;
779: }
780:
781: /*
782: *
783: *
784: *
785: */
786: IOWorkLoop *IOSCSIParallelController::getWorkLoop() const
787: {
788: return workLoop;
789: }
790:
791: /*
792: *
793: *
794: *
795: */
796: void IOSCSIParallelController::disableCommands( UInt32 disableTimeoutmS )
797: {
798: commandDisable = true;
799:
800: disableTimer = ( disableTimeoutmS != 0 ) ? (disableTimeoutmS / kSCSITimerIntervalmS + 1) : 0;
801: }
802:
803:
804: /*
805: *
806: *
807: *
808: */
809: void IOSCSIParallelController::disableCommands()
810: {
811: UInt32 disableTimeout;
812:
813: commandDisable = true;
814:
815: disableTimeout = kSCSIDisableTimeoutmS;
816:
817: if ( noDisconnectCmd != 0 )
818: {
819: disableTimeout = noDisconnectCmd->getTimeout();
820: if ( disableTimeout != 0 ) disableTimeout += kSCSIDisableTimeoutmS;
821: }
822:
823: disableTimer = ( disableTimeout != 0 ) ? (disableTimeout / kSCSITimerIntervalmS + 1) : 0;
824: }
825:
826: /*
827: *
828: *
829: *
830: */
831: void IOSCSIParallelController::disableTimeoutOccurred()
832: {
833: busResetState = kStateIssue;
834: dispatchRequest();
835: }
836:
837:
838: /*
839: *
840: *
841: *
842: */
843: void IOSCSIParallelController::rescheduleCommand( IOSCSICommand *forSCSICmd )
844: {
845: IOSCSIParallelCommand *scsiCmd = (IOSCSIParallelCommand *)forSCSICmd;
846: IOSCSIParallelDevice *device = (IOSCSIParallelDevice *) scsiCmd->getDevice(kIOSCSIDevice);
847:
848: device->rescheduleCommand( scsiCmd );
849: }
850:
851: /*
852: *
853: *
854: *
855: */
856: void IOSCSIParallelController::enableCommands()
857: {
858: commandDisable = false;
859:
860: disableTimer = 0;
861:
862: dispatchRequest();
863: }
864:
865: /*
866: *
867: *
868: *
869: */
870: void IOSCSIParallelController::dispatchRequest()
871: {
872: dispatchEvent->interruptOccurred(0, 0, 0);
873: }
874:
875:
876: /*
877: *
878: *
879: *
880: */
881: void IOSCSIParallelController::dispatch()
882: {
883: SCSITarget *target;
884: IOSCSIParallelDevice *device;
885: UInt32 dispatchAction;
886: UInt32 lunsActive = 0;
887: UInt32 i;
888:
889: if ( checkBusReset() == true )
890: {
891: goto dispatch_Exit;
892: }
893:
894: for ( i = 0; i < controllerInfo.maxTargetsSupported; i++ )
895: {
896: target = &targets[i];
897:
898: if ( target->state == kStateActive )
899: {
900: lunsActive = 0;
901:
902: queue_iterate( &target->deviceList, device, IOSCSIParallelDevice *, nextDevice )
903: {
904: if ( device->dispatch( &dispatchAction ) == true )
905: {
906: lunsActive++;
907: }
908:
909: switch ( dispatchAction )
910: {
911: case kDispatchNextLun:
912: ;
913: case kDispatchNextTarget:
914: break;
915: case kDispatchStop:
916: goto dispatch_Exit;
917: }
918: }
919: if ( lunsActive == 0 )
920: {
921: target->state = kStateIdle;
922: }
923: }
924: }
925:
926: dispatch_Exit:
927: ;
928: }
929:
930: /*
931: *
932: *
933: *
934: */
935: IOSCSIParallelCommand *IOSCSIParallelController::allocCommand(UInt32 clientDataSize )
936: {
937: IOSCSIParallelCommand *cmd;
938: UInt32 size;
939:
940: size = controllerInfo.commandPrivateDataSize + round(clientDataSize, 16);
941:
942: cmd = new IOSCSIParallelCommand;
943: if ( !cmd )
944: {
945: return 0;
946: }
947: cmd->init();
948:
949: if ( size )
950: {
951: cmd->dataArea = (void *)IOMallocContiguous( (vm_size_t)size, 16, 0 );
952: if ( !cmd->dataArea )
953: {
954: cmd->release();
955: return 0;
956: }
957:
958: bzero( cmd->dataArea, size );
959:
960: cmd->dataSize = size;
961:
962: if ( controllerInfo.commandPrivateDataSize )
963: {
964: cmd->commandPrivateData = cmd->dataArea;
965: }
966: if ( clientDataSize )
967: {
968: cmd->clientData = (void *)((UInt8 *)cmd->dataArea + controllerInfo.commandPrivateDataSize);
969: }
970: }
971:
972: cmd->controller = this;
973:
974: return cmd;
975: }
976:
977: /*
978: *
979: *
980: *
981: */
982: void IOSCSIParallelController::free()
983: {
984: UInt32 targetsSize;
985: UInt32 i;
986:
987: if ( timerEvent != 0 ) timerEvent->release();
988:
989: if ( workLoopReqGate != 0 ) workLoopReqGate->release();
990:
991: if ( dispatchEvent != 0 ) dispatchEvent->release();
992:
993: if ( resetCmd != 0 ) resetCmd->release();
994:
995: if ( workLoop != 0 ) workLoop->release();
996:
997: if ( targets != 0 )
998: {
999: for ( i=0; i < controllerInfo.maxTargetsSupported; i++ )
1000: {
1001: if ( targets[i].targetPrivateData != 0 )
1002: {
1003: IOFreeContiguous( targets[i].targetPrivateData, controllerInfo.targetPrivateDataSize );
1004: }
1005: }
1006:
1007: targetsSize = controllerInfo.maxTargetsSupported * sizeof(SCSITarget);
1008: IOFree( targets, targetsSize );
1009: }
1010:
1011: if ( tagArray != 0 ) IOFree( tagArray, tagArraySize );
1012:
1013: super::free();
1014: }
1015:
1016: /*
1017: *
1018: *
1019: *
1020: */
1021: void IOSCSIParallelCommand::free()
1022: {
1023: if ( dataArea )
1024: {
1025: IOFreeContiguous( dataArea, dataSize );
1026: }
1027:
1028: OSObject::free();
1029: }
1030:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.