1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
3 *
4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided
5 *that the following conditions are met:
6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7 *following disclaimer.
8 *2. Redistributions in binary form must reproduce the above copyright notice,
9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided
10 *with the distribution.
11 *
12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20
21 ********************************************************************************/
22 /*******************************************************************************/
23 /** \file
24 *
25 *
26 * This file contains initiator IO related functions in TD layer
27 *
28 */
29 #include <sys/cdefs.h>
30 #include <dev/pms/config.h>
31
32 #include <dev/pms/freebsd/driver/common/osenv.h>
33 #include <dev/pms/freebsd/driver/common/ostypes.h>
34 #include <dev/pms/freebsd/driver/common/osdebug.h>
35
36 #include <dev/pms/RefTisa/sallsdk/api/sa.h>
37 #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
38 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
39
40 #include <dev/pms/RefTisa/tisa/api/titypes.h>
41 #include <dev/pms/RefTisa/tisa/api/ostiapi.h>
42 #include <dev/pms/RefTisa/tisa/api/tiapi.h>
43 #include <dev/pms/RefTisa/tisa/api/tiglobal.h>
44
45 #ifdef FDS_SM
46 #include <dev/pms/RefTisa/sat/api/sm.h>
47 #include <dev/pms/RefTisa/sat/api/smapi.h>
48 #include <dev/pms/RefTisa/sat/api/tdsmapi.h>
49 #endif
50
51 #ifdef FDS_DM
52 #include <dev/pms/RefTisa/discovery/api/dm.h>
53 #include <dev/pms/RefTisa/discovery/api/dmapi.h>
54 #include <dev/pms/RefTisa/discovery/api/tddmapi.h>
55 #endif
56
57 #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
58 #include <dev/pms/freebsd/driver/common/osstring.h>
59 #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
60
61 #ifdef INITIATOR_DRIVER
62 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
63 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
64 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
65 #endif
66
67 #ifdef TARGET_DRIVER
68 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
69 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
70 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
71 #endif
72
73 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
74 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
75
76 /*****************************************************************************
77 *! \brief tiINIIOStart
78 *
79 * Purpose: This routine is called to initiate a new SCSI request.
80 *
81 * \param tiRoot: Pointer to initiator driver/port instance.
82 * \param tiIORequest: Pointer to the I/O request context for this I/O.
83 * \param tiDeviceHandle: Pointer to device handle for this I/O.
84 * \param tiScsiRequest: Pointer to the SCSI-3 I/O request and SGL list.
85 * \param tiRequestBody: Pointer to the OS Specific module allocated storage
86 * to be used by the TD layer for executing this I/O.
87 * \param interruptContext: The interrupt context within which this function
88 * is called.
89 * \return:
90 *
91 * tiSuccess: I/O request successfully initiated.
92 * tiBusy: No resources available, try again later.
93 * tiIONoDevice: Invalid device handle.
94 * tiError: Other errors that prevent the I/O request to be started.
95 *
96 *
97 *****************************************************************************/
98 osGLOBAL bit32
tiINIIOStart(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,void * tiRequestBody,bit32 interruptContext)99 tiINIIOStart(
100 tiRoot_t *tiRoot,
101 tiIORequest_t *tiIORequest,
102 tiDeviceHandle_t *tiDeviceHandle,
103 tiScsiInitiatorRequest_t *tiScsiRequest,
104 void *tiRequestBody,
105 bit32 interruptContext
106 )
107 {
108 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
109 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
110 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
111 tdsaDeviceData_t *oneDeviceData;
112 agsaRoot_t *agRoot = agNULL;
113 agsaIORequest_t *agIORequest = agNULL;
114 agsaDevHandle_t *agDevHandle = agNULL;
115 bit32 agRequestType;
116 agsaSASRequestBody_t *agSASRequestBody = agNULL;
117 bit32 tiStatus = tiError;
118 bit32 saStatus = AGSA_RC_FAILURE;
119
120 tdIORequestBody_t *tdIORequestBody;
121 agsaSSPInitiatorRequest_t *agSSPInitiatorRequest;
122 #ifdef REMOVED
123 /* only for debugging */
124 bit32 i;
125 #endif
126
127 #ifdef SATA_ENABLE
128 #ifndef FDS_SM
129 satIOContext_t *satIOContext;
130 #endif
131 #endif
132 #ifdef FDS_SM
133 smRoot_t *smRoot = &(tdsaAllShared->smRoot);
134 smIORequest_t *smIORequest;
135 smDeviceHandle_t *smDeviceHandle;
136 smScsiInitiatorRequest_t *smSCSIRequest;
137 #endif
138
139 TDSA_INP_ENTER(tiRoot);
140 TI_DBG6(("tiINIIOStart: start\n"));
141 TI_DBG6(("tiINIIOStart:: ******* tdsaRoot %p tdsaAllShared %p \n", tdsaRoot,tdsaAllShared));
142
143 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
144
145 TI_DBG6(("tiINIIOStart: onedevicedata %p\n", oneDeviceData));
146
147 if(oneDeviceData == agNULL)
148 {
149 TI_DBG1(("tiINIIOStart: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
150 tiStatus = tiIONoDevice;
151 goto ext;
152 }
153
154 /* for hotplug */
155 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
156 oneDeviceData->tdPortContext == agNULL )
157 {
158 TI_DBG1(("tiINIIOStart: tiDeviceHandle=%p did %d DeviceData was removed\n", tiDeviceHandle, oneDeviceData->id));
159 TI_DBG6(("tiINIIOStart: device AddrHi 0x%08x AddrLo 0x%08x\n",
160 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
161 // for debugging
162 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
163 tdIORequestBody->IOCompletionFunc = itdssIOForDebugging1Completed;
164 TI_DBG6(("tiINIIOStart: IOCompletionFunc %p\n", tdIORequestBody->IOCompletionFunc));
165 tiStatus = tiIONoDevice;
166 goto ext;
167 }
168 #if 1
169 if (tiIORequest->osData == agNULL)
170 {
171 TI_DBG1(("tiINIIOStart: tiIORequest->osData is NULL, wrong\n"));
172 }
173 #endif
174
175 /* starting IO with SAS device */
176 if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
177 {
178 TI_DBG6(("tiINIIOStart: calling saSSPStart\n"));
179
180 agRoot = oneDeviceData->agRoot;
181 agDevHandle = oneDeviceData->agDevHandle;
182
183 /* OS layer has tdlayer data structure pointer in
184 tdIORequestBody_t tdIOReqBody;
185 in ccb_t in agtiapi.h
186 */
187 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
188
189 /* initialize */
190 osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));
191
192 /* let's initialize tdIOrequestBody */
193 /* initialize callback */
194 tdIORequestBody->IOCompletionFunc = itdssIOCompleted;
195
196 /* initialize tiDevhandle */
197 tdIORequestBody->tiDevHandle = tiDeviceHandle;
198
199 /* initialize tiIORequest */
200 tdIORequestBody->tiIORequest = tiIORequest;
201
202 /* save context if we need to abort later */
203 tiIORequest->tdData = tdIORequestBody;
204
205 /* initialize expDataLength */
206 tdIORequestBody->IOType.InitiatorRegIO.expDataLength
207 = tiScsiRequest->scsiCmnd.expDataLength;
208
209 tdIORequestBody->IOType.InitiatorRegIO.sglVirtualAddr
210 = tiScsiRequest->sglVirtualAddr;
211
212 /* initializes "agsaSgl_t agSgl" of "agsaDifSSPInitiatorRequest_t" */
213 tiStatus = itdssIOPrepareSGL(
214 tiRoot,
215 tdIORequestBody,
216 &tiScsiRequest->agSgl1,
217 tiScsiRequest->sglVirtualAddr
218 );
219
220 if (tiStatus != tiSuccess)
221 {
222 TI_DBG1(("tiINIIOStart: can't get SGL\n"));
223 goto ext;
224 }
225
226
227 /* initialize agIORequest */
228 agIORequest = &(tdIORequestBody->agIORequest);
229 agIORequest->osData = (void *) tdIORequestBody;
230 agIORequest->sdkData = agNULL; /* LL takes care of this */
231
232
233 /*
234 initialize
235 tdIORequestBody_t tdIORequestBody -> agSASRequestBody
236 */
237 agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
238 agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq);
239
240 agSSPInitiatorRequest->flag = 0;
241
242 /* copy cdb bytes */
243 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16);
244
245 /* copy lun field */
246 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.lun,
247 tiScsiRequest->scsiCmnd.lun.lun, 8);
248
249
250 /* setting the data length */
251 agSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength;
252 TI_DBG6(("tiINIIOStart: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength));
253
254 agSSPInitiatorRequest->firstBurstSize = 0;
255
256 /*
257 process taskattribute
258 */
259 if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_SIMPLE)
260 {
261 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
262 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_SIMPLE;
263 }
264 else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ORDERED)
265 {
266 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
267 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ORDERED;
268 }
269 else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_HEAD_OF_QUEUE)
270 {
271 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
272 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_HEAD_OF_QUEUE;
273 }
274 else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ACA)
275 {
276 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
277 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ACA;
278 }
279
280 if (tiScsiRequest->dataDirection == tiDirectionIn)
281 {
282 agRequestType = AGSA_SSP_INIT_READ;
283 TI_DBG6(("tiINIIOStart: READ\n"));
284 }
285 else if (tiScsiRequest->dataDirection == tiDirectionOut)
286 {
287 agRequestType = AGSA_SSP_INIT_WRITE;
288 TI_DBG6(("tiINIIOStart: WRITE\n"));
289 }
290 else
291 {
292 agRequestType = AGSA_REQ_TYPE_UNKNOWN;
293 TI_DBG1(("tiINIIOStart: unknown data direction\n"));
294 }
295
296 tdIORequestBody->agRequestType = agRequestType;
297
298 TI_DBG6(("tiINIIOStart: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
299 TI_DBG6(("tiINIIOStart: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
300
301 /* for debugging */
302 if (tdIORequestBody->IOCompletionFunc == agNULL)
303 {
304 TI_DBG1(("tiINIIOStart: Error!!!! IOCompletionFunc is NULL\n"));
305 }
306 saStatus = saSSPStart(agRoot,
307 agIORequest,
308 tdsaRotateQnumber(tiRoot, oneDeviceData),
309 agDevHandle,
310 agRequestType,
311 agSASRequestBody,
312 agNULL,
313 &ossaSSPCompleted);
314
315 tdIORequestBody->ioStarted = agTRUE;
316 tdIORequestBody->ioCompleted = agFALSE;
317 tdIORequestBody->reTries = 0;
318
319 if (saStatus == AGSA_RC_SUCCESS)
320 {
321 Initiator->NumIOsActive++;
322 tiStatus = tiSuccess;
323 }
324 else
325 {
326 tdIORequestBody->ioStarted = agFALSE;
327 tdIORequestBody->ioCompleted = agTRUE;
328 if (saStatus == AGSA_RC_BUSY)
329 {
330 TI_DBG4(("tiINIIOStart: saSSPStart busy\n"));
331 tiStatus = tiBusy;
332 }
333 else
334 {
335 tiStatus = tiError;
336 }
337 goto ext;
338 }
339 }
340 #ifdef FDS_SM
341 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
342 {
343 TI_DBG5(("tiINIIOStart: calling satIOStart\n"));
344 TI_DBG5(("tiINIIOStart: onedevicedata did %d\n", oneDeviceData->id));
345 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
346 /* initialize */
347 osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));
348 /* initialize tiDevhandle */
349 tdIORequestBody->tiDevHandle = tiDeviceHandle;
350 tdIORequestBody->superIOFlag = agFALSE;
351
352 tiIORequest->tdData = tdIORequestBody;
353 tdIORequestBody->tiIORequest = tiIORequest;
354 smIORequest = (smIORequest_t *)&(tdIORequestBody->smIORequest);
355 smIORequest->tdData = tdIORequestBody;
356
357 smDeviceHandle = (smDeviceHandle_t *)&(oneDeviceData->smDeviceHandle);
358 smDeviceHandle->tdData = oneDeviceData;
359
360 smSCSIRequest = (smScsiInitiatorRequest_t *)&(tdIORequestBody->SM.smSCSIRequest);
361 osti_memcpy(smSCSIRequest, tiScsiRequest, sizeof(smScsiInitiatorRequest_t));
362
363 tiStatus = smIOStart(smRoot,
364 smIORequest,
365 smDeviceHandle,
366 smSCSIRequest,
367 interruptContext);
368 /*
369 osGLOBAL bit32
370 smIOStart(
371 smRoot_t *smRoot,
372 smIORequest_t *smIORequest,
373 smDeviceHandle_t *smDeviceHandle,
374 smScsiInitiatorRequest_t *smSCSIRequest,
375 bit32 interruptContext
376 )
377
378
379 */
380 }
381 #else
382 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
383 {
384 TI_DBG5(("tiINIIOStart: calling satIOStart\n"));
385 TI_DBG5(("tiINIIOStart: onedevicedata did %d\n", oneDeviceData->id));
386
387 #ifdef SATA_ENABLE
388 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
389
390 /* initialize */
391 osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));
392
393 /* initialize tiDevhandle */
394 tdIORequestBody->tiDevHandle = tiDeviceHandle;
395
396 /* initialize tiIORequest */
397 tdIORequestBody->tiIORequest = tiIORequest;
398 tdIORequestBody->IOCompletionFunc = itdssIOForDebugging2Completed;
399
400 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
401
402 /*
403 * Need to initialize all the fields within satIOContext except
404 * reqType and satCompleteCB which will be set in sat.c depending on cmd.
405 */
406 tdIORequestBody->transport.SATA.tiSenseData.senseData = agNULL;
407 tdIORequestBody->transport.SATA.tiSenseData.senseLen = 0;
408 satIOContext->pSatDevData = &oneDeviceData->satDevData;
409 satIOContext->pFis =
410 &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
411 satIOContext->pScsiCmnd = &tiScsiRequest->scsiCmnd;
412 satIOContext->pSense = &tdIORequestBody->transport.SATA.sensePayload;
413 satIOContext->pTiSenseData = &tdIORequestBody->transport.SATA.tiSenseData;
414 satIOContext->pTiSenseData->senseData = satIOContext->pSense;
415 /* satIOContext->pSense = (scsiRspSense_t *)satIOContext->pTiSenseData->senseData; */
416 satIOContext->tiRequestBody = tiRequestBody;
417 satIOContext->interruptContext = interruptContext;
418 satIOContext->ptiDeviceHandle = tiDeviceHandle;
419 satIOContext->tiScsiXchg = tiScsiRequest;
420 satIOContext->satIntIoContext = agNULL;
421 satIOContext->satOrgIOContext = agNULL;
422 /* satIOContext->tiIORequest = tiIORequest; */
423
424 /* save context if we need to abort later */
425 tiIORequest->tdData = tdIORequestBody;
426
427 /* followings are used only for internal IO */
428 satIOContext->currentLBA = 0;
429 satIOContext->OrgTL = 0;
430
431 TI_DBG5(("tiINIIOStart: pSatDevData=%p\n", satIOContext->pSatDevData ));
432
433 tiStatus = satIOStart( tiRoot,
434 tiIORequest,
435 tiDeviceHandle,
436 tiScsiRequest,
437 satIOContext);
438 goto ext;
439 #endif
440 }
441 #endif /* else of FDS_SM */
442 else
443 {
444
445 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
446 tdIORequestBody->IOCompletionFunc = itdssIOForDebugging3Completed;
447 TI_DBG1(("tiINIIOStart: wrong unspported Device %d\n", oneDeviceData->DeviceType));
448 /*
449 error. unsupported IO
450 */
451 }
452 ext:
453 TDSA_INP_LEAVE(tiRoot);
454 return tiStatus;
455 }
456
457 #ifdef FAST_IO_TEST
458 osGLOBAL bit32
tiINIFastIOSend(void * ioh)459 tiINIFastIOSend(void *ioh)
460 {
461 bit32 saStatus, tiStatus;
462
463 saStatus = saFastSSPSend(ioh);
464 if (saStatus == AGSA_RC_SUCCESS)
465 tiStatus = tiSuccess;
466 else
467 tiStatus = tiError;
468 return tiStatus;
469 }
470
471 osGLOBAL bit32
tiINIFastIOCancel(void * ioh)472 tiINIFastIOCancel(void *ioh)
473 {
474 bit32 saStatus, tiStatus;
475
476 saStatus = saFastSSPCancel(ioh);
477 if (saStatus == AGSA_RC_SUCCESS)
478 tiStatus = tiSuccess;
479 else
480 tiStatus = tiError;
481 return tiStatus;
482 }
483
484 osGLOBAL void*
tiINIFastIOPrepare(tiRoot_t * tiRoot,void * ioHandle,agsaFastCommand_t * fc)485 tiINIFastIOPrepare(
486 tiRoot_t *tiRoot,
487 void *ioHandle,
488 agsaFastCommand_t *fc)
489 {
490 tdsaDeviceData_t *oneDeviceData;
491 tiDeviceHandle_t *tiDeviceHandle = fc->devHandle;
492 bit32 taskAttribute = fc->taskAttribute;
493 void *ioh = ioHandle;
494
495 TDSA_INP_ENTER(tiRoot);
496 TI_DBG6(("tiINIFastIOPrepare: enter\n"));
497
498 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
499 if(oneDeviceData == agNULL)
500 {
501 TI_DBG1(("tiINIFastIOPrepare: tiDeviceHandle=%p DeviceData is NULL\n",
502 tiDeviceHandle));
503 ioHandle = 0;
504 TD_ASSERT((0), "");
505 goto ext;
506 }
507 TI_DBG6(("tiINIFastIOPrepare: onedevicedata %p\n", oneDeviceData));
508
509 /* starting IO with SAS device */
510 if (oneDeviceData->DeviceType != TD_SAS_DEVICE)
511 {
512 TI_DBG1(("tiINISuperIOSend: wrong Device %d\n", oneDeviceData->DeviceType));
513 /* error: unsupported IO */
514 ioHandle = 0;
515 TD_ASSERT((0), "");
516 goto ext;
517 }
518
519 fc->agRoot = oneDeviceData->agRoot;
520 TD_ASSERT((NULL != fc->agRoot), "");
521
522 fc->devHandle = oneDeviceData->agDevHandle;
523 TD_ASSERT((NULL != fc->devHandle), "");
524 fc->safb->oneDeviceData = oneDeviceData;
525
526 /*
527 process taskattribute
528 */
529 switch (taskAttribute)
530 {
531 case TASK_SIMPLE:
532 fc->taskAttribute = TD_TASK_SIMPLE;
533 break;
534 case TASK_ORDERED:
535 fc->taskAttribute = TD_TASK_ORDERED;
536 break;
537 case TASK_HEAD_OF_QUEUE:
538 fc->taskAttribute = TD_TASK_HEAD_OF_QUEUE;
539 break;
540 case TASK_ACA:
541 fc->taskAttribute = TD_TASK_ACA;
542 break;
543 /* compile out for "iniload" */
544 }
545
546
547 TI_DBG3(("tiINIFastIOPrepare: data direction: %x\n", fc->agRequestType));
548 TI_DBG6(("tiINIFastIOPrepare: device AddrHi/Lo 0x%08x / 0x%08x\n",
549 oneDeviceData->SASAddressID.sasAddressHi,
550 oneDeviceData->SASAddressID.sasAddressLo));
551
552 fc->queueNum = tdsaRotateQnumber(tiRoot, oneDeviceData);
553
554 ioHandle = saFastSSPPrepare(ioHandle, fc, ossaFastSSPCompleted, fc->safb);
555 if (!ioHandle)
556 {
557 TI_DBG1(("tiINIFastIOPrepare: saSuperSSPSend error\n"));
558 TD_ASSERT((0), "");
559 //goto ext;
560 }
561
562 ext:
563 if (ioh && !ioHandle)
564 {
565 saFastSSPCancel(ioh);
566 }
567
568 TI_DBG6(("tiINIFastIOPrepare: leave\n"));
569
570 TDSA_INP_LEAVE(tiRoot);
571 return ioHandle;
572 } /* tiINIFastIOPrepare */
573 #endif
574
575 /*****************************************************************************
576 *
577 * tiINIIOStartDif
578 *
579 * Purpose: This routine is called to initiate a new SCSI request with
580 * DIF enable.
581 *
582 * Parameters:
583 * tiRoot: Pointer to initiator driver/port instance.
584 * tiIORequest: Pointer to the I/O request context for this I/O.
585 * tiDeviceHandle: Pointer to device handle for this I/O.
586 * tiScsiRequest: Pointer to the SCSI-3 I/O request and SGL list.
587 * tiRequestBody: Pointer to the OS Specific module allocated storage
588 * to be used by the TD layer for executing this I/O.
589 * interruptContext: The interrupt context within which this function
590 * is called.
591 * difOption: DIF option.
592 *
593 * Return:
594 *
595 * tiSuccess: I/O request successfully initiated.
596 * tiBusy: No resources available, try again later.
597 * tiIONoDevice: Invalid device handle.
598 * tiError: Other errors that prevent the I/O request to be started.
599 *
600 *
601 *****************************************************************************/
tiINIIOStartDif(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,void * tiRequestBody,bit32 interruptContext,tiDif_t * difOption)602 osGLOBAL bit32 tiINIIOStartDif(
603 tiRoot_t *tiRoot,
604 tiIORequest_t *tiIORequest,
605 tiDeviceHandle_t *tiDeviceHandle,
606 tiScsiInitiatorRequest_t *tiScsiRequest,
607 void *tiRequestBody,
608 bit32 interruptContext,
609 tiDif_t *difOption
610 )
611 {
612
613 /* This function was never used by SAS/SATA. Use tiINISuperIOStart() instead. */
614 return tiBusy;
615 }
616
617
618 /*****************************************************************************
619 *
620 * tiINISuperIOStart
621 *
622 * Purpose: This routine is called to initiate a new SCSI request.
623 *
624 * Parameters:
625 * tiRoot: Pointer to initiator driver/port instance.
626 * tiIORequest: Pointer to the I/O request context for this I/O.
627 * tiDeviceHandle: Pointer to device handle for this I/O.
628 * tiScsiRequest: Pointer to the SCSI-3 I/O request and SGL list.
629 * tiRequestBody: Pointer to the OS Specific module allocated storage
630 * to be used by the TD layer for executing this I/O.
631 * interruptContext: The interrupt context within which this function
632 * is called.
633 * Return:
634 *
635 * tiSuccess: I/O request successfully initiated.
636 * tiBusy: No resources available, try again later.
637 * tiIONoDevice: Invalid device handle.
638 * tiError: Other errors that prevent the I/O request to be started.
639 *
640 *
641 *****************************************************************************/
642 osGLOBAL bit32
tiINISuperIOStart(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiSuperScsiInitiatorRequest_t * tiScsiRequest,void * tiRequestBody,bit32 interruptContext)643 tiINISuperIOStart(
644 tiRoot_t *tiRoot,
645 tiIORequest_t *tiIORequest,
646 tiDeviceHandle_t *tiDeviceHandle,
647 tiSuperScsiInitiatorRequest_t *tiScsiRequest,
648 void *tiRequestBody,
649 bit32 interruptContext
650 )
651 {
652 tdsaRoot_t *tdsaRoot = agNULL;
653 tdsaContext_t *tdsaAllShared = agNULL;
654 itdsaIni_t *Initiator = agNULL;
655 tdsaDeviceData_t *oneDeviceData = agNULL;
656 tdIORequestBody_t *tdIORequestBody = agNULL;
657 agsaSSPInitiatorRequest_t *agSSPInitiatorRequest = agNULL;
658 agsaRoot_t *agRoot = agNULL;
659 agsaIORequest_t *agIORequest = agNULL;
660 agsaDevHandle_t *agDevHandle = agNULL;
661 agsaSASRequestBody_t *agSASRequestBody = agNULL;
662 bit32 tiStatus = tiError;
663 bit32 saStatus = AGSA_RC_FAILURE;
664 bit32 adjusted_length = 0;
665 bit32 agRequestType = 0;
666 agBOOLEAN needPlusDataLenAdjustment = agFALSE;
667 agBOOLEAN needMinusDataLenAdjustment = agFALSE;
668
669 #ifdef SATA_ENABLE
670 #ifndef FDS_SM
671 satIOContext_t *satIOContext;
672 #endif
673 #endif
674 #ifdef FDS_SM
675 smRoot_t *smRoot;
676 smIORequest_t *smIORequest;
677 smDeviceHandle_t *smDeviceHandle;
678 smSuperScsiInitiatorRequest_t *smSuperSCSIRequest;
679 #endif
680 #ifdef CCBUILD_INDIRECT_CDB
681 agsaSSPInitiatorRequestIndirect_t *agSSPInitiatorIndRequest = agNULL;
682 #endif
683 TD_ASSERT(tiRoot , "tiRoot");
684 TD_ASSERT(tiIORequest, "tiIORequest");
685 TD_ASSERT(tiDeviceHandle, "tiDeviceHandle");
686 TD_ASSERT(tiRequestBody, "tiRequestBody");
687 TD_ASSERT(tiRoot->tdData, "tiRoot->tdData");
688 TD_ASSERT(tiDeviceHandle, "tiDeviceHandle");
689
690 tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
691 TD_ASSERT(tdsaRoot, "tdsaRoot");
692
693 tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
694 TD_ASSERT(tdsaAllShared, "tdsaAllShared");
695
696 Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
697 TD_ASSERT(Initiator, "Initiator");
698
699 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
700 TD_ASSERT(oneDeviceData, "oneDeviceData");
701
702
703 #ifdef FDS_SM
704 smRoot = &(tdsaAllShared->smRoot);
705 TD_ASSERT(smRoot , "smRoot");
706 #endif
707
708
709 TI_DBG6(("tiINISuperIOStart: start\n"));
710 TI_DBG6(("tiINISuperIOStart:: ******* tdsaRoot %p tdsaAllShared %p \n", tdsaRoot,tdsaAllShared));
711
712 TI_DBG6(("tiINISuperIOStart: onedevicedata %p\n", oneDeviceData));
713
714 if (oneDeviceData == agNULL)
715 {
716 TI_DBG1(("tiINISuperIOStart: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
717 return tiIONoDevice;
718 }
719
720 /* for hotplug */
721 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
722 oneDeviceData->tdPortContext == agNULL )
723 {
724 TI_DBG1(("tiINISuperIOStart: tiDeviceHandle=%p did %d DeviceData was removed\n", tiDeviceHandle, oneDeviceData->id));
725 TI_DBG6(("tiINISuperIOStart: device AddrHi 0x%08x AddrLo 0x%08x\n",
726 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
727 // for debugging
728 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
729 tdIORequestBody->IOCompletionFunc = itdssIOForDebugging1Completed;
730 TI_DBG6(("tiINISuperIOStart: IOCompletionFunc %p\n", tdIORequestBody->IOCompletionFunc));
731 return tiIONoDevice;
732 }
733
734 #ifdef DBG
735 if (tiIORequest->osData == agNULL)
736 {
737 TI_DBG1(("tiINISuperIOStart: tiIORequest->osData is NULL, wrong\n"));
738 return tiError;
739 }
740 #endif
741 /* starting IO with SAS device */
742 if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
743 {
744 TI_DBG3(("tiINISuperIOStart: calling saSSPStart\n"));
745
746 agRoot = oneDeviceData->agRoot;
747 agDevHandle = oneDeviceData->agDevHandle;
748
749 /* OS layer has tdlayer data structure pointer in tdIORequestBody_t tdIOReqBody; in ccb_t in agtiapi.h */
750 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
751
752 /* initialize */
753 /*the tdIORequestBody has been initialized in HwBuildIo routine */
754 /*osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));*/
755
756 /* let's initialize tdIOrequestBody */
757 /* initialize callback */
758 tdIORequestBody->IOCompletionFunc = itdssIOCompleted;
759
760 /* initialize tiDevhandle */
761 tdIORequestBody->tiDevHandle = tiDeviceHandle;
762
763 /* initialize tiIORequest */
764 tdIORequestBody->tiIORequest = tiIORequest;
765
766 /* save context if we need to abort later */
767 tiIORequest->tdData = tdIORequestBody;
768
769 /* initialize expDataLength */
770 tdIORequestBody->IOType.InitiatorRegIO.expDataLength
771 = tiScsiRequest->scsiCmnd.expDataLength;
772
773 tdIORequestBody->IOType.InitiatorRegIO.sglVirtualAddr
774 = tiScsiRequest->sglVirtualAddr;
775
776 /* initialize agIORequest */
777 agIORequest = &(tdIORequestBody->agIORequest);
778 agIORequest->osData = (void *) tdIORequestBody;
779
780 /* initialize tdIORequestBody_t tdIORequestBody -> agSASRequestBody */
781 agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
782 agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq);
783
784 agSSPInitiatorRequest->flag = 0;
785 if (tiScsiRequest->flags & TI_SCSI_INITIATOR_ENCRYPT)
786 {
787 TI_DBG3(("tiINISuperIOStart: TI_SCSI_INITIATOR_ENCRYPT\n"));
788
789 /* Copy all of the relevant encrypt information */
790 agSSPInitiatorRequest->flag |= AGSA_SAS_ENABLE_ENCRYPTION;
791 TD_ASSERT( sizeof(tiEncrypt_t) == sizeof(agsaEncrypt_t) , "sizeof(tiEncrypt_t) == sizeof(agsaEncrypt_t)");
792 osti_memcpy(&agSSPInitiatorRequest->encrypt, &tiScsiRequest->Encrypt, sizeof(agsaEncrypt_t));
793 }
794
795 if ((tiScsiRequest->flags & TI_SCSI_INITIATOR_DIF) &&
796 (tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_10 ||
797 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_10 ||
798 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_6 ||
799 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_6 ||
800 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_12 ||
801 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_12 ||
802 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_16 ||
803 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_16 ))
804 {
805 TI_DBG3(("tiINISuperIOStart: TI_SCSI_INITIATOR_DIF\n"));
806 /* Copy all of the relevant DIF information */
807 agSSPInitiatorRequest->flag |= AGSA_SAS_ENABLE_DIF;
808 osti_memcpy(&agSSPInitiatorRequest->dif, &tiScsiRequest->Dif, sizeof(agsaDif_t));
809
810 /* Check if need to adjust dataLength. */
811 switch (tiScsiRequest->dataDirection)
812 {
813 case tiDirectionOut: /* Write/Outbound */
814 break;
815
816 case tiDirectionIn: /* Read/Inbound */
817 if ((agSSPInitiatorRequest->dif.flags & DIF_ACTION_FLAG_MASK) == DIF_INSERT)
818 {
819 needPlusDataLenAdjustment = agTRUE;
820 }
821 break;
822 }
823
824 /* Set SGL data len XXX This code needs to support more sector sizes */
825 /* Length adjustment for PCIe DMA only not SAS */
826 if (needPlusDataLenAdjustment == agTRUE)
827 {
828 adjusted_length = tiScsiRequest->scsiCmnd.expDataLength;
829 adjusted_length += (adjusted_length/512) * 8;
830 agSSPInitiatorRequest->dataLength = adjusted_length;
831 }
832 else if (needMinusDataLenAdjustment == agTRUE)
833 {
834 adjusted_length = tiScsiRequest->scsiCmnd.expDataLength;
835 adjusted_length -= (adjusted_length/520) * 8;
836 agSSPInitiatorRequest->dataLength = adjusted_length;
837 }
838 else
839 {
840 /* setting the data length */
841 agSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength;
842 }
843
844 /* initializes "agsaSgl_t agSgl" of "agsaDifSSPInitiatorRequest_t" */
845 tiStatus = itdssIOPrepareSGL(
846 tiRoot,
847 tdIORequestBody,
848 &tiScsiRequest->agSgl1,
849 tiScsiRequest->sglVirtualAddr
850 );
851 TI_DBG2(("tiINISuperIOStart:TI_SCSI_INITIATOR_DIF needMinusDataLenAdjustment %d needPlusDataLenAdjustment %d difAction %X\n",
852 needMinusDataLenAdjustment,
853 needPlusDataLenAdjustment,
854 agSSPInitiatorRequest->dif.flags & DIF_ACTION_FLAG_MASK));
855
856 }
857 else
858 {
859 /* setting the data length */
860 agSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength;
861
862 /* initializes "agsaSgl_t agSgl" of "agsaSSPInitiatorRequest_t" */
863 tiStatus = itdssIOPrepareSGL(
864 tiRoot,
865 tdIORequestBody,
866 &tiScsiRequest->agSgl1,
867 tiScsiRequest->sglVirtualAddr
868 );
869 }
870
871 if (tiStatus != tiSuccess)
872 {
873 TI_DBG1(("tiINISuperIOStart: can't get SGL\n"));
874 return tiStatus;
875 }
876
877 TI_DBG6(("tiINISuperIOStart: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength));
878
879 /* process taskattribute */
880 if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_SIMPLE)
881 {
882 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
883 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_SIMPLE;
884 }
885 else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ORDERED)
886 {
887 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
888 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ORDERED;
889 }
890 else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_HEAD_OF_QUEUE)
891 {
892 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
893 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_HEAD_OF_QUEUE;
894 }
895 else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ACA)
896 {
897 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
898 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ACA;
899 }
900
901 /* copy cdb bytes */
902 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16);
903 /* copy lun field */
904 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.lun, tiScsiRequest->scsiCmnd.lun.lun, 8);
905 #ifdef CCBUILD_INDIRECT_CDB
906 /* check the Indirect CDB flag */
907 if (tiScsiRequest->flags & TI_SCSI_INITIATOR_INDIRECT_CDB)
908 {
909 /* Indirect CDB */
910 if (tiScsiRequest->dataDirection == tiDirectionIn)
911 {
912 agRequestType = AGSA_SSP_INIT_READ_INDIRECT;
913 TI_DBG6(("tiINISuperIOStart: Indirect READ\n"));
914 }
915 else if (tiScsiRequest->dataDirection == tiDirectionOut)
916 {
917 agRequestType = AGSA_SSP_INIT_WRITE_INDIRECT;
918 TI_DBG6(("tiINISuperIOStart: Indirect WRITE\n"));
919 }
920 else
921 {
922 agRequestType = AGSA_REQ_TYPE_UNKNOWN;
923 TI_DBG1(("tiINISuperIOStart: unknown data direction\n"));
924 }
925 agSSPInitiatorIndRequest = &(agSASRequestBody->sspInitiatorReqIndirect);
926 /* copy the constructed SSPIU info to indirect SSPIU buffer */
927 osti_memcpy(tiScsiRequest->IndCDBBuffer, &agSSPInitiatorRequest->sspCmdIU, sizeof(agsaSSPCmdInfoUnit_t));
928 /* initialize the indirect CDB buffer address and length */
929 agSSPInitiatorIndRequest->sspInitiatorReqAddrLower32 = tiScsiRequest->IndCDBLowAddr;
930 agSSPInitiatorIndRequest->sspInitiatorReqAddrUpper32 = tiScsiRequest->IndCDBHighAddr;
931 agSSPInitiatorIndRequest->sspInitiatorReqLen = sizeof(agsaSSPCmdInfoUnit_t);
932 }
933 else
934 #endif //CCBUILD_INDIRECT_CDB
935 {
936 /* Direct CDB */
937 if (tiScsiRequest->dataDirection == tiDirectionIn)
938 {
939 agRequestType = AGSA_SSP_INIT_READ;
940 TI_DBG6(("tiINISuperIOStart: READ\n"));
941 }
942 else if (tiScsiRequest->dataDirection == tiDirectionOut)
943 {
944 agRequestType = AGSA_SSP_INIT_WRITE;
945 TI_DBG6(("tiINISuperIOStart: WRITE\n"));
946 }
947 else
948 {
949 agRequestType = AGSA_REQ_TYPE_UNKNOWN;
950 TI_DBG1(("tiINISuperIOStart: unknown data direction\n"));
951 }
952 }
953
954 tdIORequestBody->agRequestType = agRequestType;
955
956 TI_DBG6(("tiINISuperIOStart: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
957 TI_DBG6(("tiINISuperIOStart: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
958
959 #ifdef DBG
960 /* for debugging */
961 if (tdIORequestBody->IOCompletionFunc == agNULL)
962 {
963 TI_DBG1(("tiINISuperIOStart: Error!!!! IOCompletionFunc is NULL\n"));
964 return tiError;
965 }
966 #endif
967 saStatus = saSSPStart(agRoot,
968 agIORequest,
969 tdsaRotateQnumber(tiRoot, oneDeviceData),
970 agDevHandle,
971 agRequestType,
972 agSASRequestBody,
973 agNULL,
974 &ossaSSPCompleted);
975
976 if (saStatus == AGSA_RC_SUCCESS)
977 {
978 Initiator->NumIOsActive++;
979 tdIORequestBody->ioStarted = agTRUE;
980 tdIORequestBody->ioCompleted = agFALSE;
981 tiStatus = tiSuccess;
982 }
983 else
984 {
985 tdIORequestBody->ioStarted = agFALSE;
986 tdIORequestBody->ioCompleted = agTRUE;
987 if (saStatus == AGSA_RC_BUSY)
988 {
989 TI_DBG4(("tiINISuperIOStart: saSSPStart busy\n"));
990 tiStatus = tiBusy;
991 }
992 else
993 {
994 tiStatus = tiError;
995 }
996 return tiStatus;
997 }
998 }
999 #ifdef FDS_SM
1000 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
1001 {
1002 TI_DBG5(("tiINISuperIOStart: calling satIOStart\n"));
1003 TI_DBG5(("tiINISuperIOStart: onedevicedata did %d\n", oneDeviceData->id));
1004 TI_DBG5(("tiINISuperIOStart: SATA sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
1005 TI_DBG5(("tiINISuperIOStart: SATA sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
1006
1007 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
1008 /* initialize */
1009 /* the tdIORequestBody has been initialized by Storport in SRB Extension */
1010 /*osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));*/
1011 /* initialize tiDevhandle */
1012 tdIORequestBody->tiDevHandle = tiDeviceHandle;
1013 tdIORequestBody->superIOFlag = agTRUE;
1014
1015 tiIORequest->tdData = tdIORequestBody;
1016 tdIORequestBody->tiIORequest = tiIORequest;
1017 smIORequest = (smIORequest_t *)&(tdIORequestBody->smIORequest);
1018 smIORequest->tdData = tdIORequestBody;
1019 smIORequest->smData = &tdIORequestBody->smIORequestBody;
1020
1021 smDeviceHandle = (smDeviceHandle_t *)&(oneDeviceData->smDeviceHandle);
1022 smDeviceHandle->tdData = oneDeviceData;
1023
1024 smSuperSCSIRequest = (smSuperScsiInitiatorRequest_t *)&(tdIORequestBody->SM.smSuperSCSIRequest);
1025 osti_memcpy(smSuperSCSIRequest, tiScsiRequest, sizeof(smSuperScsiInitiatorRequest_t));
1026
1027 tiStatus = smSuperIOStart(smRoot,
1028 smIORequest,
1029 smDeviceHandle,
1030 smSuperSCSIRequest,
1031 oneDeviceData->SASAddressID.sasAddressHi,
1032 oneDeviceData->SASAddressID.sasAddressLo,
1033 interruptContext);
1034
1035 }
1036 #else
1037 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
1038 {
1039
1040 TI_DBG5(("tiINISuperIOStart: calling satIOStart\n"));
1041 TI_DBG5(("tiINISuperIOStart: onedevicedata did %d\n", oneDeviceData->id));
1042
1043 #ifdef SATA_ENABLE
1044 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
1045
1046 /* initialize */
1047 osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));
1048
1049 /* initialize tiDevhandle */
1050 tdIORequestBody->tiDevHandle = tiDeviceHandle;
1051
1052 /* initialize tiIORequest */
1053 tdIORequestBody->tiIORequest = tiIORequest;
1054 tdIORequestBody->IOCompletionFunc = itdssIOForDebugging2Completed;
1055
1056 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
1057
1058 /*
1059 * Need to initialize all the fields within satIOContext except
1060 * reqType and satCompleteCB which will be set in sat.c depending on cmd.
1061 */
1062 tdIORequestBody->transport.SATA.tiSenseData.senseData = agNULL;
1063 tdIORequestBody->transport.SATA.tiSenseData.senseLen = 0;
1064 satIOContext->pSatDevData = &oneDeviceData->satDevData;
1065 satIOContext->pFis =
1066 &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
1067 satIOContext->pScsiCmnd = &tiScsiRequest->scsiCmnd;
1068 satIOContext->pSense = &tdIORequestBody->transport.SATA.sensePayload;
1069 satIOContext->pTiSenseData = &tdIORequestBody->transport.SATA.tiSenseData;
1070 satIOContext->pTiSenseData->senseData = satIOContext->pSense;
1071 /* satIOContext->pSense = (scsiRspSense_t *)satIOContext->pTiSenseData->senseData; */
1072 satIOContext->tiRequestBody = tiRequestBody;
1073 satIOContext->interruptContext = interruptContext;
1074 satIOContext->ptiDeviceHandle = tiDeviceHandle;
1075 /*
1076 This code uses a kludge for the tiScsiXchg. Many subroutines in the SATA code
1077 require a tiScsiInitiatorRequest. Since it would be a lot of work to replicate
1078 those functions for a tiSuperScsiInitiatorRequest, we will use a short cut.
1079 The standard pointer will be passed, but the superIOFlag marks the real type of the structure.
1080 */
1081 satIOContext->tiScsiXchg = tiScsiRequest;
1082 satIOContext->superIOFlag = agTRUE;
1083
1084 satIOContext->satIntIoContext = agNULL;
1085 satIOContext->satOrgIOContext = agNULL;
1086 /* satIOContext->tiIORequest = tiIORequest; */
1087
1088 /* save context if we need to abort later */
1089 tiIORequest->tdData = tdIORequestBody;
1090
1091 /* followings are used only for internal IO */
1092 satIOContext->currentLBA = 0;
1093 satIOContext->OrgTL = 0;
1094
1095 TI_DBG5(("tiINISuperIOStart: pSatDevData=%p\n", satIOContext->pSatDevData ));
1096
1097 tiStatus = satIOStart( tiRoot,
1098 tiIORequest,
1099 tiDeviceHandle,
1100 satIOContext->tiScsiXchg,
1101 satIOContext);
1102
1103 return tiStatus;
1104 #endif
1105 }
1106 #endif /* else of FDS_SM */
1107
1108 else
1109 {
1110
1111 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
1112 tdIORequestBody->IOCompletionFunc = itdssIOForDebugging3Completed;
1113 TI_DBG1(("tiINISuperIOStart: wrong unspported Device %d\n", oneDeviceData->DeviceType));
1114 /*
1115 error. unsupported IO
1116 */
1117 }
1118 return tiStatus;
1119 }
1120
1121 osGLOBAL bit32
tiINISMPStart(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiSMPFrame_t * tiSMPFrame,void * tiSMPBody,bit32 interruptContext)1122 tiINISMPStart(
1123 tiRoot_t *tiRoot,
1124 tiIORequest_t *tiIORequest,
1125 tiDeviceHandle_t *tiDeviceHandle,
1126 tiSMPFrame_t *tiSMPFrame,
1127 void *tiSMPBody,
1128 bit32 interruptContext
1129 )
1130 {
1131 tdsaDeviceData_t *oneDeviceData;
1132 agsaIORequest_t *agIORequest = agNULL;
1133 tdIORequestBody_t *tdSMPRequestBody = agNULL;
1134 agsaRoot_t *agRoot = agNULL;
1135 agsaDevHandle_t *agDevHandle = agNULL;
1136 agsaSASRequestBody_t *agRequestBody = agNULL;
1137 agsaSMPFrame_t *agSMPFrame = agNULL;
1138 bit32 agRequestType;
1139 bit32 tiStatus = tiError;
1140 bit32 saStatus = AGSA_RC_FAILURE;
1141 bit32 queueNum;
1142 TDSA_INP_ENTER(tiRoot);
1143 TI_DBG6(("tiINISMPStart: start\n"));
1144 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
1145 TI_DBG6(("tiINISMPStart: onedevicedata %p\n", oneDeviceData));
1146 TI_DBG6(("tiINISMPStart: tiDeviceHandle %p\n", tiDeviceHandle));
1147 if (oneDeviceData == agNULL)
1148 {
1149 TI_DBG1(("tiINISMPStart: tiDeviceHandle=%p Expander DeviceData is NULL\n", tiDeviceHandle ));
1150 return tiError;
1151 }
1152 if (tiIORequest->osData == agNULL)
1153 {
1154 TI_DBG1(("tiINISMPStart: tiIORequest->osData is NULL, wrong\n"));
1155 return tiError;
1156 }
1157 agRoot = oneDeviceData->agRoot;
1158 agDevHandle = oneDeviceData->agDevHandle;
1159 tdSMPRequestBody = (tdIORequestBody_t *)tiSMPBody;
1160 tdSMPRequestBody->tiIORequest = tiIORequest;
1161 tiIORequest->tdData = tdSMPRequestBody;
1162 agIORequest = &(tdSMPRequestBody->agIORequest);
1163 agIORequest->osData = (void *) tdSMPRequestBody;
1164 agRequestBody = &(tdSMPRequestBody->transport.SAS.agSASRequestBody);
1165 agSMPFrame = &(agRequestBody->smpFrame);
1166 if (!DEVICE_IS_SMP_TARGET(oneDeviceData))
1167 {
1168 TI_DBG1(("tiINISMPStart: Target Device is not SMP device\n"));
1169 return tiError;
1170 }
1171 if (tiSMPFrame->flag == 0) // define DIRECT SMP at td layer?
1172 {
1173 TI_DBG6(("tiINISMPStart: Direct SMP\n"));
1174 agSMPFrame->outFrameBuf = tiSMPFrame->outFrameBuf;
1175 agSMPFrame->outFrameLen = tiSMPFrame->outFrameLen;
1176 tdhexdump("tiINISMPStart agSMPFrame", (bit8 *)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
1177 agSMPFrame->expectedRespLen = tiSMPFrame->expectedRespLen;
1178 agSMPFrame->inFrameLen = 0;
1179 agSMPFrame->flag = tiSMPFrame->flag;
1180 agRequestType = AGSA_SMP_INIT_REQ;
1181 queueNum = 0;
1182 saStatus = saSMPStart(agRoot,
1183 agIORequest,
1184 queueNum,
1185 agDevHandle,
1186 agRequestType,
1187 agRequestBody,
1188 &ossaSMPCAMCompleted
1189 );
1190 if (saStatus == AGSA_RC_SUCCESS)
1191 {
1192 tiStatus = tiSuccess;
1193 }
1194 else
1195 {
1196 if (saStatus == AGSA_RC_BUSY)
1197 {
1198 TI_DBG1(("tiINISMPStart: saSSPStart busy\n"));
1199 tiStatus = tiBusy;
1200 }
1201 else
1202 {
1203 TI_DBG1(("tiINISMPStart: saSSPStart error\n"));
1204 tiStatus = tiError;
1205 }
1206 return tiStatus;
1207 }
1208 }
1209 else
1210 {
1211 TI_DBG1(("tiINISMPStart: Indirect SMP! Not supported yet\n"));
1212 tiStatus = tiError;
1213 }
1214 return tiStatus;
1215 }
1216 #ifdef TD_INT_COALESCE
1217 osGLOBAL bit32
tiINIIOStartIntCoalesce(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,void * tiRequestBody,bit32 interruptContext,tiIntCoalesceContext_t * tiIntCoalesceCxt)1218 tiINIIOStartIntCoalesce(
1219 tiRoot_t *tiRoot,
1220 tiIORequest_t *tiIORequest,
1221 tiDeviceHandle_t *tiDeviceHandle,
1222 tiScsiInitiatorRequest_t *tiScsiRequest,
1223 void *tiRequestBody,
1224 bit32 interruptContext,
1225 tiIntCoalesceContext_t *tiIntCoalesceCxt
1226 )
1227 {
1228 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
1229 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
1230 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
1231 tdsaDeviceData_t *oneDeviceData;
1232 agsaRoot_t *agRoot = agNULL;
1233 agsaIORequest_t *agIORequest = agNULL;
1234 agsaDevHandle_t *agDevHandle = agNULL;
1235 bit32 agRequestType;
1236 agsaSASRequestBody_t *agSASRequestBody = agNULL;
1237 bit32 tiStatus = tiError;
1238 bit32 saStatus = AGSA_RC_FAILURE;
1239
1240 tdIORequestBody_t *tdIORequestBody;
1241 agsaSSPInitiatorRequest_t *agSSPInitiatorRequest;
1242 tdsaIntCoalesceContext_t *tdsaIntCoalCxt;
1243 agsaIntCoalesceContext_t *agIntCoalCxt;
1244
1245 TI_DBG1(("tiINIIOStartIntCoalesce: start\n"));
1246 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
1247
1248 TI_DBG6(("tiINIIOStartIntCoalesce: onedevicedata %p\n", oneDeviceData));
1249
1250 if(oneDeviceData == agNULL)
1251 {
1252 TI_DBG1(("tiINIIOStartIntCoalesce: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
1253 return tiIONoDevice;
1254 }
1255
1256 /* starting IO with SAS device */
1257 if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
1258 {
1259 TI_DBG6(("tiINIIOStartIntCoalesce: calling saSSPStart\n"));
1260
1261 agRoot = oneDeviceData->agRoot;
1262 agDevHandle = oneDeviceData->agDevHandle;
1263
1264 /* OS layer has tdlayer data structure pointer in
1265 tdIORequestBody_t tdIOReqBody;
1266 in ccb_t in agtiapi.h
1267 */
1268 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
1269
1270 /* let's initialize tdIOrequestBody */
1271 /* initialize callback */
1272 tdIORequestBody->IOCompletionFunc = itdssIOCompleted;
1273
1274 /* initialize tiDevhandle */
1275 tdIORequestBody->tiDevHandle = tiDeviceHandle;
1276
1277 /* initialize tiIORequest */
1278 tdIORequestBody->tiIORequest = tiIORequest;
1279
1280 /* save context if we need to abort later */
1281 tiIORequest->tdData = tdIORequestBody;
1282
1283 /* initialize expDataLength */
1284 tdIORequestBody->IOType.InitiatorRegIO.expDataLength
1285 = tiScsiRequest->scsiCmnd.expDataLength;
1286
1287 /* initializes "agsaSgl_t agSgl" of "agsaDifSSPInitiatorRequest_t" */
1288 tiStatus = itdssIOPrepareSGL(
1289 tiRoot,
1290 tdIORequestBody,
1291 &tiScsiRequest->agSgl1,
1292 tiScsiRequest->sglVirtualAddr
1293 );
1294
1295 if (tiStatus != tiSuccess)
1296 {
1297 TI_DBG1(("tiINIIOStartIntCoalesce: can't get SGL\n"));
1298 return tiStatus;
1299 }
1300
1301
1302 /* initialize agIORequest */
1303 agIORequest = &(tdIORequestBody->agIORequest);
1304 agIORequest->osData = (void *) tdIORequestBody;
1305 agIORequest->sdkData = agNULL; /* LL takes care of this */
1306
1307
1308 /*
1309 initialize
1310 tdIORequestBody_t tdIORequestBody -> agSASRequestBody
1311 */
1312 agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
1313 agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq);
1314
1315
1316 /* copy cdb bytes */
1317 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16);
1318
1319 /* copy lun field */
1320 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.lun,
1321 tiScsiRequest->scsiCmnd.lun.lun, 8);
1322
1323 /* setting the data length */
1324 agSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength;
1325 TI_DBG6(("tiINIIOStartIntCoalesce: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength));
1326
1327 agSSPInitiatorRequest->firstBurstSize = 0;
1328
1329 if (tiScsiRequest->dataDirection == tiDirectionIn)
1330 {
1331 agRequestType = AGSA_SSP_INIT_READ;
1332 TI_DBG6(("tiINIIOStartIntCoalesce: READ\n"));
1333 }
1334 else if (tiScsiRequest->dataDirection == tiDirectionOut)
1335 {
1336 agRequestType = AGSA_SSP_INIT_WRITE;
1337 TI_DBG6(("tiINIIOStartIntCoalesce: WRITE\n"));
1338 }
1339 else
1340 {
1341 agRequestType = AGSA_REQ_TYPE_UNKNOWN;
1342 TI_DBG1(("tiINIIOStartIntCoalesce: unknown data direction\n"));
1343 }
1344
1345 tdIORequestBody->agRequestType = agRequestType;
1346
1347 tdsaIntCoalCxt = (tdsaIntCoalesceContext_t *)tiIntCoalesceCxt->tdData;
1348 agIntCoalCxt = &(tdsaIntCoalCxt->agIntCoalCxt);
1349
1350
1351
1352 #ifdef LL_INT_COALESCE
1353 saStatus = saSSPStartIntCoalesce(agRoot,
1354 agIORequest,
1355 agIntCoalCxt,
1356 agDevHandle,
1357 agRequestType,
1358 agSASRequestBody,
1359 &ossaSSPCompleted);
1360 #endif
1361
1362 tdIORequestBody->ioStarted = agTRUE;
1363 tdIORequestBody->ioCompleted = agFALSE;
1364
1365 if (saStatus == AGSA_RC_SUCCESS)
1366 {
1367 Initiator->NumIOsActive++;
1368 tiStatus = tiSuccess;
1369 }
1370 else
1371 {
1372 TI_DBG1(("tiINIIOStartIntCoalesce: saSSPStart failed\n"));
1373 tdIORequestBody->ioStarted = agFALSE;
1374 tdIORequestBody->ioCompleted = agTRUE;
1375 if (saStatus == AGSA_RC_BUSY)
1376 {
1377 tiStatus = tiBusy;
1378 }
1379 else
1380 {
1381 tiStatus = tiError;
1382 }
1383 return tiStatus;
1384 }
1385 }
1386
1387 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
1388 {
1389 /*
1390 satIOStart() -> saSATAStartIntCoalesce()
1391 */
1392 TI_DBG1(("tiINIIOStartIntCoalesce: SATA not supported yet\n"));
1393 return tiStatus;
1394 }
1395 else
1396 {
1397 TI_DBG1(("tiINIIOStartIntCoalesce: wrong unspported Device %d\n", oneDeviceData->DeviceType));
1398 /*
1399 error. unsupported IO
1400 */
1401 }
1402 return tiStatus;
1403
1404
1405 }
1406
1407 osGLOBAL bit32
tiINIIOStartIntCoalesceDif(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,void * tiRequestBody,bit32 interruptContext,tiIntCoalesceContext_t * tiIntCoalesceCxt,tiDif_t * difOption)1408 tiINIIOStartIntCoalesceDif(
1409 tiRoot_t *tiRoot,
1410 tiIORequest_t *tiIORequest,
1411 tiDeviceHandle_t *tiDeviceHandle,
1412 tiScsiInitiatorRequest_t *tiScsiRequest,
1413 void *tiRequestBody,
1414 bit32 interruptContext,
1415 tiIntCoalesceContext_t *tiIntCoalesceCxt,
1416 tiDif_t *difOption
1417 )
1418 {
1419 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
1420 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
1421 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
1422 tdsaDeviceData_t *oneDeviceData;
1423 agsaRoot_t *agRoot = agNULL;
1424 agsaIORequest_t *agIORequest = agNULL;
1425 agsaDevHandle_t *agDevHandle = agNULL;
1426 bit32 agRequestType;
1427 agsaDifSSPRequestBody_t *agEdcSSPRequestBody = agNULL;
1428 bit32 tiStatus = tiError;
1429 bit32 saStatus = AGSA_RC_FAILURE;
1430
1431 tdIORequestBody_t *tdIORequestBody;
1432 agsaDifSSPInitiatorRequest_t *agEdcSSPInitiatorRequest;
1433 agsaDif_t *agEdc;
1434 bit32 agUpdateMask = 0;
1435 bit32 agVerifyMask = 0;
1436 tdsaIntCoalesceContext_t *tdsaIntCoalCxt;
1437 agsaIntCoalesceContext_t *agIntCoalCxt;
1438
1439 TI_DBG1(("tiINIIOStartIntCoalesceDif: start\n"));
1440 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
1441
1442 TI_DBG6(("tiINIIOStartIntCoalesceDif: onedevicedata %p\n", oneDeviceData));
1443
1444 if(oneDeviceData == agNULL)
1445 {
1446 TI_DBG1(("tiINIIOStartIntCoalesceDif: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
1447 return tiIONoDevice;
1448 }
1449
1450 /* starting IO with SAS device */
1451 if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
1452 {
1453 TI_DBG6(("tiINIIOStartIntCoalesceDif: calling saSSPStart\n"));
1454
1455 agRoot = oneDeviceData->agRoot;
1456 agDevHandle = oneDeviceData->agDevHandle;
1457
1458 /* OS layer has tdlayer data structure pointer in
1459 tdIORequestBody_t tdIOReqBody;
1460 in ccb_t in agtiapi.h
1461 */
1462 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
1463
1464 /* let's initialize tdIOrequestBody */
1465 /* initialize callback */
1466 tdIORequestBody->IOCompletionFunc = itdssIOCompleted;
1467
1468 /* initialize tiDevhandle */
1469 tdIORequestBody->tiDevHandle = tiDeviceHandle;
1470
1471 /* initialize tiIORequest */
1472 tdIORequestBody->tiIORequest = tiIORequest;
1473
1474 /* save context if we need to abort later */
1475 tiIORequest->tdData = tdIORequestBody;
1476
1477 /* initialize expDataLength */
1478 tdIORequestBody->IOType.InitiatorRegIO.expDataLength
1479 = tiScsiRequest->scsiCmnd.expDataLength;
1480
1481 /* initializes "agsaSgl_t agSgl" of "agsaDifSSPInitiatorRequest_t" */
1482 tiStatus = itdssIOPrepareSGL(
1483 tiRoot,
1484 tdIORequestBody,
1485 &tiScsiRequest->agSgl1,
1486 tiScsiRequest->sglVirtualAddr
1487 );
1488
1489 if (tiStatus != tiSuccess)
1490 {
1491 TI_DBG1(("tiINIIOStartIntCoalesceDif: can't get SGL\n"));
1492 return tiStatus;
1493 }
1494
1495
1496 /* initialize agIORequest */
1497 agIORequest = &(tdIORequestBody->agIORequest);
1498 agIORequest->osData = (void *) tdIORequestBody;
1499 agIORequest->sdkData = agNULL; /* LL takes care of this */
1500
1501
1502 /*
1503 initialize
1504 tdIORequestBody_t tdIORequestBody -> agSASRequestBody
1505 */
1506 agEdcSSPRequestBody = &(tdIORequestBody->transport.SAS.agEdcSSPRequestBody);
1507 agEdcSSPInitiatorRequest = &(agEdcSSPRequestBody->edcSSPInitiatorReq);
1508
1509
1510 /* copy cdb bytes */
1511 osti_memcpy(agEdcSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16);
1512
1513 /* copy lun field */
1514 osti_memcpy(agEdcSSPInitiatorRequest->sspCmdIU.lun,
1515 tiScsiRequest->scsiCmnd.lun.lun, 8);
1516
1517
1518 /* setting the data length */
1519 agEdcSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength;
1520 TI_DBG6(("tiINIIOStartIntCoalesceDif: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength));
1521
1522 agEdcSSPInitiatorRequest->firstBurstSize = 0;
1523
1524
1525 if (tiScsiRequest->dataDirection == tiDirectionIn)
1526 {
1527 agRequestType = AGSA_SSP_INIT_READ;
1528 TI_DBG1(("tiINIIOStartIntCoalesceDif: READ difAction %X\n",difOption->difAction));
1529 }
1530 else if (tiScsiRequest->dataDirection == tiDirectionOut)
1531 {
1532 agRequestType = AGSA_SSP_INIT_WRITE;
1533 TI_DBG1(("tiINIIOStartIntCoalesceDif: WRITE difAction %X\n",difOption->difAction));
1534 }
1535 else
1536 {
1537 agRequestType = AGSA_REQ_TYPE_UNKNOWN;
1538 TI_DBG1(("tiINIIOStartIntCoalesceDif: unknown data direction\n"));
1539 }
1540
1541 tdIORequestBody->agRequestType = agRequestType;
1542
1543 /* process interrupt coalesce context */
1544 tdsaIntCoalCxt = (tdsaIntCoalesceContext_t *)tiIntCoalesceCxt->tdData;
1545 agIntCoalCxt = &(tdsaIntCoalCxt->agIntCoalCxt);
1546
1547 /* process DIF */
1548
1549 agEdc = &(agEdcSSPInitiatorRequest->edc);
1550
1551 osti_memset(agEdc, 0, sizeof(agsaDif_t));
1552
1553 /* setting edcFlag */
1554 if (difOption->enableBlockCount)
1555 {
1556 /* enables block count; bit5 */
1557 agEdc->edcFlag = agEdc->edcFlag | 0x20; /* 0010 0000 */
1558 }
1559
1560 if (difOption->enableCrc)
1561 {
1562 /* enables CRC verification; bit6 */
1563 agEdc->edcFlag = agEdc->edcFlag | 0x40; /* 0100 0000 */
1564 }
1565
1566 if (difOption->enableIOSeed)
1567 {
1568
1569 }
1570 if (difOption->difAction == DIF_INSERT)
1571 {
1572 /* bit 0 - 2; 000 */
1573 agEdc->edcFlag = agEdc->edcFlag & 0xFFFFFFF8;
1574 }
1575 else if (difOption->difAction == DIF_VERIFY_FORWARD)
1576 {
1577 /* bit 0 - 2; 001 */
1578 agEdc->edcFlag = agEdc->edcFlag | 0x01;
1579 }
1580 else if (difOption->difAction == DIF_VERIFY_DELETE)
1581 {
1582 /* bit 0 - 2; 010 */
1583 agEdc->edcFlag = agEdc->edcFlag | 0x02;
1584 }
1585 else
1586 {
1587 /* DIF_VERIFY_REPLACE */
1588 /* bit 0 - 2; 011 */
1589 agEdc->edcFlag = agEdc->edcFlag | 0x04;
1590 }
1591
1592 /* set Update Mask; bit 16-21 */
1593 agUpdateMask = (difOption->tagUpdateMask) & 0x3F; /* 0011 1111 */
1594 agUpdateMask = agUpdateMask << 16;
1595 agEdc->edcFlag = agEdc->edcFlag | agUpdateMask;
1596
1597 /* set Verify Mask bit 24-29 */
1598 agVerifyMask = (difOption->tagVerifyMask) & 0x3F; /* 0011 1111 */
1599 agVerifyMask = agVerifyMask << 24;
1600 agEdc->edcFlag = agEdc->edcFlag | agVerifyMask;
1601
1602 agEdc->appTag = difOption->udtArray[0];
1603 agEdc->appTag = (agEdc->appTag << 8) | difOption->udtArray[1];
1604
1605 agEdc->lbaReferenceTag = difOption->udtArray[2];
1606 agEdc->lbaReferenceTag = (agEdc->lbaReferenceTag << 8) | difOption->udtArray[3];
1607 agEdc->lbaReferenceTag = (agEdc->lbaReferenceTag << 8) | difOption->udtArray[4];
1608 agEdc->lbaReferenceTag = (agEdc->lbaReferenceTag << 8) | difOption->udtArray[5];
1609
1610 /* currently TISA supports only 512 logical block size */
1611 agEdc->lbSize = 512;
1612
1613
1614 #ifdef LL_INT_COALESCE
1615 saStatus = saSSPStartIntCoalesceEdc(agRoot,
1616 agIORequest,
1617 agIntCoalCxt,
1618 agDevHandle,
1619 agRequestType,
1620 agEdcSSPRequestBody,
1621 &ossaSSPCompleted);
1622 #endif
1623
1624 tdIORequestBody->ioStarted = agTRUE;
1625 tdIORequestBody->ioCompleted = agFALSE;
1626
1627 if (saStatus == AGSA_RC_SUCCESS)
1628 {
1629 Initiator->NumIOsActive++;
1630 tiStatus = tiSuccess;
1631 }
1632 else
1633 {
1634 TI_DBG1(("tiINIIOStartIntCoalesceDif: saSSPStart failed\n"));
1635 tdIORequestBody->ioStarted = agFALSE;
1636 tdIORequestBody->ioCompleted = agTRUE;
1637 if (saStatus == AGSA_RC_BUSY)
1638 {
1639 tiStatus = tiBusy;
1640 }
1641 else
1642 {
1643 tiStatus = tiError;
1644 }
1645 return tiStatus;
1646 }
1647 }
1648 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
1649 {
1650 /*
1651 satIOStart() -> saSATAStartIntCoalesceEdc()
1652 */
1653 TI_DBG1(("tiINIIOStartIntCoalesceDif: SATA not supported yet\n"));
1654 return tiStatus;
1655 }
1656 else
1657 {
1658 TI_DBG1(("tiINIIOStartIntCoalesceDif: wrong unspported Device %d\n", oneDeviceData->DeviceType));
1659 /*
1660 error. unsupported IO
1661 */
1662 }
1663 return tiStatus;
1664 }
1665
1666
1667 osGLOBAL bit32
tiINIIntCoalesceInit(tiRoot_t * tiRoot,tiIntCoalesceContext_t * tiIntCoalesceCxt,bit32 count)1668 tiINIIntCoalesceInit(
1669 tiRoot_t *tiRoot,
1670 tiIntCoalesceContext_t *tiIntCoalesceCxt,
1671 bit32 count
1672 )
1673 {
1674
1675 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
1676 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
1677 agsaRoot_t *agRoot = agNULL;
1678 tdsaIntCoalesceContext_t *tdsaIntCoalCxtHead
1679 = (tdsaIntCoalesceContext_t *)tdsaAllShared->IntCoalesce;
1680 tdsaIntCoalesceContext_t *tdsaIntCoalCxt;
1681 agsaIntCoalesceContext_t *agIntCoalCxt;
1682 tdList_t *tdsaIntCoalCxtList = agNULL;
1683
1684 bit32 tiStatus = tiError;
1685
1686 TI_DBG1(("tiINIIntCoalesceInit: start\n"));
1687
1688 tdsaSingleThreadedEnter(tiRoot, TD_INTCOAL_LOCK);
1689 if (TDLIST_NOT_EMPTY(&(tdsaIntCoalCxtHead->FreeLink)))
1690 {
1691 TDLIST_DEQUEUE_FROM_HEAD(&tdsaIntCoalCxtList, &(tdsaIntCoalCxtHead->FreeLink));
1692 tdsaSingleThreadedLeave(tiRoot, TD_INTCOAL_LOCK);
1693 tdsaIntCoalCxt
1694 = TDLIST_OBJECT_BASE(tdsaIntCoalesceContext_t, FreeLink, tdsaIntCoalCxtList);
1695
1696 TI_DBG1(("tiINIIntCoalesceInit: id %d\n", tdsaIntCoalCxt->id));
1697
1698 agRoot = &(tdsaAllShared->agRootNonInt);
1699
1700 agIntCoalCxt = &(tdsaIntCoalCxt->agIntCoalCxt);
1701 tdsaIntCoalCxt->tiIntCoalesceCxt = tiIntCoalesceCxt;
1702 tiIntCoalesceCxt->tdData = tdsaIntCoalCxt;
1703 agIntCoalCxt->osData = tdsaIntCoalCxt;
1704
1705 tdsaSingleThreadedEnter(tiRoot, TD_INTCOAL_LOCK);
1706 TDLIST_ENQUEUE_AT_TAIL(&(tdsaIntCoalCxt->MainLink), &(tdsaIntCoalCxtHead->MainLink));
1707 tdsaSingleThreadedLeave(tiRoot, TD_INTCOAL_LOCK);
1708
1709 /*
1710 note: currently asynchronously call is assumed. In other words,
1711 "ossaIntCoalesceInitCB()" -> "ostiInitiatorCoalesceInitCB()" are used
1712 */
1713 #ifdef LL_INT_COALESCE
1714 tiStatus = saIntCoalesceInit(agRoot, agIntCoalCxt, count);
1715 #endif
1716
1717 TI_DBG6(("tiINIIntCoalesceInit: status %d\n", tiStatus));
1718 return tiStatus;
1719 }
1720 else
1721 {
1722 tdsaSingleThreadedLeave(tiRoot, TD_INTCOAL_LOCK);
1723 TI_DBG1(("tiINIIntCoalesceInit: no more interrupt coalesce context; return fail\n"));
1724 return tiStatus;
1725 }
1726 }
1727 #endif /* TD_INT_COALESCE */
1728
1729 /*****************************************************************************
1730 *! \brief itdssIOPrepareSGL
1731 *
1732 * Purpose: This function is called to translate TISA SGL information to the
1733 * LL layer SGL.
1734 *
1735 * \param tiRoot: Pointer to initiator driver/port instance.
1736 * \param IORequestBody: TD layer request body for the I/O.
1737 * \param tiSgl1: First TISA SGL info.
1738 * \param sglVirtualAddr: The virtual address of the first element in
1739 * tiSgl1 when tiSgl1 is used with the type tiSglList.
1740 *
1741 * \return:
1742 *
1743 * tiSuccess: SGL initialized successfully.
1744 * tiError: Failed to initialize SGL.
1745 *
1746 *
1747 *****************************************************************************/
1748 osGLOBAL FORCEINLINE bit32
itdssIOPrepareSGL(tiRoot_t * tiRoot,tdIORequestBody_t * tdIORequestBody,tiSgl_t * tiSgl1,void * sglVirtualAddr)1749 itdssIOPrepareSGL(
1750 tiRoot_t *tiRoot,
1751 tdIORequestBody_t *tdIORequestBody,
1752 tiSgl_t *tiSgl1,
1753 void *sglVirtualAddr
1754 )
1755 {
1756 agsaSgl_t *agSgl;
1757
1758 TI_DBG6(("itdssIOPrepareSGL: start\n"));
1759
1760 agSgl = &(tdIORequestBody->transport.SAS.agSASRequestBody.sspInitiatorReq.agSgl);
1761
1762 agSgl->len = 0;
1763
1764 if (tiSgl1 == agNULL)
1765 {
1766 TI_DBG1(("itdssIOPrepareSGL: Error tiSgl1 is NULL\n"));
1767 return tiError;
1768 }
1769
1770 if (tdIORequestBody->IOType.InitiatorRegIO.expDataLength == 0)
1771 {
1772 TI_DBG6(("itdssIOPrepareSGL: expDataLength is 0\n"));
1773 agSgl->sgUpper = 0;
1774 agSgl->sgLower = 0;
1775 agSgl->len = 0;
1776 CLEAR_ESGL_EXTEND(agSgl->extReserved);
1777 return tiSuccess;
1778 }
1779
1780 agSgl->sgUpper = tiSgl1->upper;
1781 agSgl->sgLower = tiSgl1->lower;
1782 agSgl->len = tiSgl1->len;
1783 agSgl->extReserved = tiSgl1->type;
1784
1785 return tiSuccess;
1786 }
1787
1788 osGLOBAL bit32
tiNumOfLunIOCTLreq(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,void * tiRequestBody,tiIOCTLPayload_t * agIOCTLPayload,void * agParam1,void * agParam2)1789 tiNumOfLunIOCTLreq(
1790 tiRoot_t *tiRoot,
1791 tiIORequest_t *tiIORequest,
1792 tiDeviceHandle_t *tiDeviceHandle,
1793 void *tiRequestBody,
1794 tiIOCTLPayload_t *agIOCTLPayload,
1795 void *agParam1,
1796 void *agParam2
1797 )
1798 {
1799 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
1800 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
1801 agsaRoot_t *agRoot = &(tdsaAllShared->agRootInt);
1802 void *respBuffer = agNULL;
1803 void *osMemHandle = agNULL;
1804 bit32 ostiMemoryStatus = 0;
1805 tdsaDeviceData_t *oneDeviceData = agNULL;
1806 agsaSSPInitiatorRequest_t *agSSPFrame = agNULL;
1807 bit32 status = IOCTL_CALL_SUCCESS;
1808 bit32 agRequestType = 0;
1809 agsaDevHandle_t *agDevHandle = agNULL;
1810 agsaIORequest_t *agIORequest = agNULL;
1811 tdIORequestBody_t *tdIORequestBody = agNULL;
1812 agsaSASRequestBody_t *agSASRequestBody = agNULL;
1813
1814 do
1815 {
1816 if((tiIORequest == agNULL) || (tiRequestBody == agNULL))
1817 {
1818 status = IOCTL_CALL_FAIL;
1819 break;
1820 }
1821 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
1822 tdIORequestBody->tiIORequest = tiIORequest;
1823
1824 /* save context if we need to abort later */
1825 tiIORequest->tdData = tdIORequestBody;
1826
1827 agIORequest = &(tdIORequestBody->agIORequest);
1828 agIORequest->osData = (void *) tdIORequestBody;
1829 agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
1830 agSSPFrame = &(agSASRequestBody->sspInitiatorReq);
1831
1832 ostiMemoryStatus = ostiAllocMemory( tiRoot,
1833 &osMemHandle,
1834 (void **)&respBuffer,
1835 &(agSSPFrame->agSgl.sgUpper),
1836 &(agSSPFrame->agSgl.sgLower),
1837 8,
1838 REPORT_LUN_LEN,
1839 agFALSE);
1840 if((ostiMemoryStatus != tiSuccess) && (respBuffer == agNULL ))
1841 {
1842 status = IOCTL_CALL_FAIL;
1843 break;
1844 }
1845
1846 osti_memset((void *)respBuffer, 0, REPORT_LUN_LEN);
1847
1848 // use FW control place in shared structure to keep the neccesary information
1849 tdsaAllShared->tdFWControlEx.virtAddr = respBuffer;
1850 tdsaAllShared->tdFWControlEx.len = REPORT_LUN_LEN;
1851 tdsaAllShared->tdFWControlEx.param1 = agParam1;
1852 tdsaAllShared->tdFWControlEx.param2 = agParam2;
1853 tdsaAllShared->tdFWControlEx.payload = agIOCTLPayload;
1854 tdsaAllShared->tdFWControlEx.inProgress = 1;
1855 agRequestType = AGSA_SSP_INIT_READ;
1856
1857 status = IOCTL_CALL_PENDING;
1858 oneDeviceData = (tdsaDeviceData_t *)(tiDeviceHandle->tdData);
1859 agDevHandle = oneDeviceData->agDevHandle;
1860
1861 agSSPFrame->sspCmdIU.cdb[0] = REPORT_LUN_OPCODE;
1862 agSSPFrame->sspCmdIU.cdb[1] = 0x0;
1863 agSSPFrame->sspCmdIU.cdb[2] = 0x0;
1864 agSSPFrame->sspCmdIU.cdb[3] = 0x0;
1865 agSSPFrame->sspCmdIU.cdb[4] = 0x0;
1866 agSSPFrame->sspCmdIU.cdb[5] = 0x0;
1867 agSSPFrame->sspCmdIU.cdb[6] = 0x0;
1868 agSSPFrame->sspCmdIU.cdb[7] = 0x0;
1869 agSSPFrame->sspCmdIU.cdb[8] = 0x0;
1870 agSSPFrame->sspCmdIU.cdb[9] = REPORT_LUN_LEN;
1871 agSSPFrame->sspCmdIU.cdb[10] = 0x0;
1872 agSSPFrame->sspCmdIU.cdb[11] = 0x0;
1873
1874 agSSPFrame->dataLength = REPORT_LUN_LEN;
1875 agSSPFrame->agSgl.len = sizeof(agsaSSPCmdInfoUnit_t);
1876 agSSPFrame->agSgl.extReserved = 0;
1877 CLEAR_ESGL_EXTEND(agSSPFrame->agSgl.extReserved);
1878
1879 status = saSSPStart(agRoot, agIORequest, 0, agDevHandle, agRequestType,agSASRequestBody,agNULL,
1880 &ossaSSPIoctlCompleted);
1881 if(status != AGSA_RC_SUCCESS)
1882 {
1883 ostiFreeMemory(tiRoot,
1884 tdsaAllShared->tdFWControlEx.virtAddr,
1885 tdsaAllShared->tdFWControlEx.len);
1886 tdsaAllShared->tdFWControlEx.payload = NULL;
1887 tdsaAllShared->tdFWControlEx.inProgress = 0;
1888 status = IOCTL_CALL_FAIL;
1889 }
1890 }while(0);
1891 return status;
1892 }
1893
1894
1895