|
|
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: *
24: * IOSCSIParallelCommand.cpp
25: *
26: */
27:
28: #include <IOKit/IOSyncer.h>
29:
30: #include <IOKit/scsi/IOSCSIParallelInterface.h>
31: #include <libkern/OSAtomic.h>
32:
33: #undef super
34: #define super IOSCSICommand
35:
36: OSDefineMetaClassAndStructors( IOSCSIParallelCommand, IOSCSICommand )
37: OSDefineMetaClassAndAbstractStructors( IOSCSICommand, IOCDBCommand )
38: OSDefineMetaClassAndAbstractStructors( IOCDBCommand, OSObject )
39:
40: IOSCSIDevice *IOSCSIParallelCommand::getDevice(IOSCSIDevice *)
41: {
42: return (IOSCSIDevice *)device;
43: }
44:
45: void *IOSCSIParallelCommand::getClientData()
46: {
47: return clientData;
48: }
49:
50: void *IOSCSIParallelCommand::getCommandData()
51: {
52: return commandPrivateData;
53: }
54:
55: UInt32 IOSCSIParallelCommand::getCmdType()
56: {
57: return cmdType;
58: }
59:
60: IOSCSICommand *IOSCSIParallelCommand::getOriginalCmd()
61: {
62: return origCommand;
63: }
64:
65: UInt32 IOSCSIParallelCommand::getSequenceNumber()
66: {
67: return sequenceNumber;
68: }
69:
70: void IOSCSIParallelCommand::getTargetLun( SCSITargetLun *forTargetLun )
71: {
72: if ( device )
73: {
74: *forTargetLun = device->targetLun;
75: }
76: else
77: {
78: bzero( forTargetLun, sizeof( SCSITargetLun ) );
79: }
80: }
81:
82:
83:
84: void IOSCSIParallelCommand::setTimeout( UInt32 timeoutMS )
85: {
86: timeout = timeoutMS;
87: }
88:
89: UInt32 IOSCSIParallelCommand::getTimeout()
90: {
91: return timeout;
92: }
93:
94:
95: void IOSCSIParallelCommand::setResults( SCSIResults *srcResults )
96: {
97: results = *srcResults;
98:
99: if ( getCmdType() == kSCSICommandExecute )
100: {
101: if ( results.bytesTransferred < xferCount )
102: {
103: if ( results.returnCode == kIOReturnSuccess )
104: {
105: results.returnCode = kIOReturnUnderrun;
106: }
107: }
108: }
109: }
110:
111: IOReturn IOSCSIParallelCommand::getResults( SCSIResults *dstResults )
112: {
113: if ( dstResults != 0 )
114: {
115: *dstResults = results;
116: }
117:
118: return results.returnCode;
119: }
120:
121: void IOSCSIParallelCommand::setQueueInfo( UInt32 forQueueType, UInt32 forQueuePosition )
122: {
123: queueType = forQueueType;
124: queuePosition = forQueuePosition;
125: }
126:
127: void IOSCSIParallelCommand::getQueueInfo( UInt32 *forQueueType, UInt32 *forQueuePosition = 0 )
128: {
129: if ( forQueueType != 0 ) *forQueueType = queueType;
130: if ( forQueuePosition != 0 ) *forQueuePosition = queuePosition;
131: }
132:
133: void IOSCSIParallelCommand::setPointers( IOMemoryDescriptor *clientDesc, UInt32 transferCount, bool isWrite, bool isSense = false )
134: {
135: if ( isSense == false )
136: {
137: xferDesc = clientDesc;
138: xferCount = transferCount;
139: xferDirection = isWrite;
140: }
141: else
142: {
143: senseData = clientDesc;
144: senseLength = transferCount;
145: }
146: }
147:
148: void IOSCSIParallelCommand::getPointers( IOMemoryDescriptor **clientDesc, UInt32 *transferCount, bool *isWrite, bool isSense = false )
149: {
150: if ( clientDesc != NULL )
151: {
152: *clientDesc = (isSense == false) ? xferDesc : senseData;
153: }
154:
155: if ( transferCount != NULL )
156: {
157: *transferCount = (isSense == false) ? xferCount : senseLength;
158: }
159:
160: if ( isWrite != NULL )
161: {
162: *isWrite = (isSense == false) ? xferDirection : false;
163: }
164: }
165:
166: void IOSCSIParallelCommand::setCDB( SCSICDBInfo *clientSCSICmd )
167: {
168: scsiCmd = *clientSCSICmd;
169: }
170:
171: void IOSCSIParallelCommand::getCDB( SCSICDBInfo *clientSCSICmd )
172: {
173: *clientSCSICmd = scsiCmd;
174: }
175:
176: void IOSCSIParallelCommand::setCallback( void *clientTarget, CallbackFn clientSCSIDoneFn, void *clientRefcon )
177: {
178: completionInfo.async.target = clientTarget;
179: completionInfo.async.callback = clientSCSIDoneFn;
180: completionInfo.async.refcon = clientRefcon;
181: }
182:
183: bool IOSCSIParallelCommand::execute( UInt32 *cmdSequenceNumber )
184: {
185: bool isSync;
186:
187: do
188: {
189: sequenceNumber = OSIncrementAtomic( (SInt32 *)&controller->sequenceNumber );
190: }
191: while ( sequenceNumber == 0 );
192:
193: if ( cmdSequenceNumber != 0 )
194: {
195: *cmdSequenceNumber = sequenceNumber;
196: }
197:
198: list = (queue_head_t *)device->deviceGate;
199:
200: isSync = (completionInfo.async.callback == 0);
201:
202: if ( isSync )
203: {
204: completionInfo.sync.lock = IOSyncer::create();
205: }
206:
207: device->submitCommand( kSCSICommandExecute, this );
208:
209: if ( isSync )
210: {
211: completionInfo.sync.lock->wait();
212: }
213:
214: return true;
215:
216: }
217:
218: void IOSCSIParallelCommand::abort( UInt32 sequenceNumber )
219: {
220: device->submitCommand( kSCSICommandAbort, this, sequenceNumber );
221: }
222:
223: void IOSCSIParallelCommand::complete()
224: {
225: if ( device )
226: {
227: device->completeCommand( this );
228: }
229: else
230: {
231: controller->completeCommand( this );
232: }
233: }
234:
235: /*------------------- Generic CDB Interface -----------------------------------------------*/
236:
237: void IOSCSIParallelCommand::getCDB( CDBInfo *cdbInfo )
238: {
239: SCSICDBInfo scsiCDBInfo;
240:
241: bzero( cdbInfo, sizeof(CDBInfo) );
242:
243: getCDB( &scsiCDBInfo );
244: cdbInfo->cdb = scsiCDBInfo.cdb;
245: cdbInfo->cdbLength = scsiCDBInfo.cdbLength;
246: }
247:
248: void IOSCSIParallelCommand::setCDB( CDBInfo *cdbInfo )
249: {
250: SCSICDBInfo scsiCDBInfo;
251:
252: bzero( &scsiCDBInfo, sizeof(SCSICDBInfo) );
253:
254: scsiCDBInfo.cdbLength = cdbInfo->cdbLength;
255: scsiCDBInfo.cdb = cdbInfo->cdb;
256: setCDB( &scsiCDBInfo );
257: }
258:
259: IOReturn IOSCSIParallelCommand::getResults( CDBResults *cdbResults )
260: {
261: SCSIResults scsiResults;
262: IOReturn rc;
263:
264: rc = getResults( &scsiResults );
265:
266: if ( cdbResults != 0 )
267: {
268: bzero( &cdbResults, sizeof(CDBResults) );
269:
270: cdbResults->returnCode = scsiResults.returnCode;
271: cdbResults->bytesTransferred = scsiResults.bytesTransferred;
272: cdbResults->requestSenseDone = scsiResults.returnCode;
273: cdbResults->requestSenseLength = scsiResults.requestSenseLength;
274: }
275:
276: return rc;
277: }
278:
279:
280: IOCDBDevice *IOSCSIParallelCommand::getDevice( IOCDBDevice * )
281: {
282: return (IOCDBDevice *)device;
283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.