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 TB misc. functions
27 *
28 */
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 #include <dev/pms/config.h>
32
33 #include <dev/pms/freebsd/driver/common/osenv.h>
34 #include <dev/pms/freebsd/driver/common/ostypes.h>
35 #include <dev/pms/freebsd/driver/common/osdebug.h>
36
37 #include <dev/pms/RefTisa/sallsdk/api/sa.h>
38 #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
39 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
40
41 #include <dev/pms/RefTisa/tisa/api/titypes.h>
42 #include <dev/pms/RefTisa/tisa/api/ostiapi.h>
43 #include <dev/pms/RefTisa/tisa/api/tiapi.h>
44 #include <dev/pms/RefTisa/tisa/api/tiglobal.h>
45
46 #ifdef FDS_SM
47 #include <dev/pms/RefTisa/sat/api/sm.h>
48 #include <dev/pms/RefTisa/sat/api/smapi.h>
49 #include <dev/pms/RefTisa/sat/api/tdsmapi.h>
50 #endif
51
52 #ifdef FDS_DM
53 #include <dev/pms/RefTisa/discovery/api/dm.h>
54 #include <dev/pms/RefTisa/discovery/api/dmapi.h>
55 #include <dev/pms/RefTisa/discovery/api/tddmapi.h>
56 #endif
57
58 #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
59 #include <dev/pms/freebsd/driver/common/osstring.h>
60 #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
61
62 #ifdef INITIATOR_DRIVER
63 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
64 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
65 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
66 #endif
67
68 #ifdef TARGET_DRIVER
69 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
70 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
71 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
72 #endif
73
74 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
75 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
76
77 /*****************************************************************************
78 *! \brief tiINIIOAbort
79 *
80 * Purpose: This function is called to abort an I/O request previously started
81 * by a call to tiINIIOStart() or tiINIIOStartDif() .
82 *
83 * \param tiRoot: Pointer to initiator driver/port instance.
84 * \param taskTag: Pointer to the associated task to be aborted
85 *
86 * \return:
87 *
88 * tiSuccess: I/O request successfully initiated.
89 * tiBusy: No resources available, try again later.
90 * tiIONoDevice: Invalid device handle.
91 * tiError: Other errors that prevent the I/O request to be
92 * started.
93 *
94 *****************************************************************************/
95 #ifdef INITIATOR_DRIVER /*TBD: INITIATOR SPECIFIC API in tiapi.h (TP)*/
96 osGLOBAL bit32
97 tiINIIOAbort(
98 tiRoot_t *tiRoot,
99 tiIORequest_t *taskTag
100 )
101 {
102 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
103 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
104 agsaRoot_t *agRoot = agNULL;
105 tdIORequestBody_t *tdIORequestBody = agNULL;
106 agsaIORequest_t *agIORequest = agNULL;
107 bit32 sasStatus = AGSA_RC_FAILURE;
108 tdsaDeviceData_t *oneDeviceData;
109 bit32 status= tiError;
110 agsaIORequest_t *agAbortIORequest;
111 tdIORequestBody_t *tdAbortIORequestBody;
112 bit32 PhysUpper32;
113 bit32 PhysLower32;
114 bit32 memAllocStatus;
115 void *osMemHandle;
116 agsaDevHandle_t *agDevHandle = agNULL;
117 #ifdef FDS_SM
118 smRoot_t *smRoot;
119 tdIORequestBody_t *ToBeAbortedtdIORequestBody;
120 smIORequest_t *ToBeAborted = agNULL;
121 #endif
122 TI_DBG2(("tiINIIOAbort: start\n"));
123
124 if(taskTag == agNULL)
125 {
126 TI_DBG1(("tiINIIOAbort: taskTag is NULL\n"));
127 return tiError;
128 }
129
130 agRoot = &(tdsaAllShared->agRootNonInt);
131 tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData;
132 agIORequest = &(tdIORequestBody->agIORequest);
133 oneDeviceData = tdIORequestBody->tiDevHandle->tdData;
134
135 if(oneDeviceData == agNULL)
136 {
137 TI_DBG1(("tiINIIOAbort: DeviceData is NULL\n"));
138 return tiSuccess;
139 }
140
141 agDevHandle = oneDeviceData->agDevHandle;
142
143 TI_DBG2(("tiINIIOAbort: did %d\n", oneDeviceData->id));
144
145 /* for hotplug */
146 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
147 oneDeviceData->tdPortContext == agNULL )
148 {
149 TI_DBG1(("tiINIIOAbort: NO Device did %d\n", oneDeviceData->id ));
150 TI_DBG1(("tiINIIOAbort: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
151 TI_DBG1(("tiINIIOAbort: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
152 return tiError;
153 }
154
155 /* allocating agIORequest for abort itself */
156 memAllocStatus = ostiAllocMemory(
157 tiRoot,
158 &osMemHandle,
159 (void **)&tdAbortIORequestBody,
160 &PhysUpper32,
161 &PhysLower32,
162 8,
163 sizeof(tdIORequestBody_t),
164 agTRUE
165 );
166 if (memAllocStatus != tiSuccess)
167 {
168 /* let os process IO */
169 TI_DBG1(("tiINIIOAbort: ostiAllocMemory failed...\n"));
170 return tiError;
171 }
172
173 if (tdAbortIORequestBody == agNULL)
174 {
175 /* let os process IO */
176 TI_DBG1(("tiINIIOAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
177 return tiError;
178 }
179
180 /* setup task management structure */
181 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
182 /* setting callback */
183 tdAbortIORequestBody->IOCompletionFunc = itdssIOAbortedHandler;
184 tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
185
186 /* initialize agIORequest */
187 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
188 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
189 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
190
191 /* remember IO to be aborted */
192 tdAbortIORequestBody->tiIOToBeAbortedRequest = taskTag;
193
194 if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
195 {
196 sasStatus = saSSPAbort(agRoot,
197 agAbortIORequest,
198 tdsaRotateQnumber(tiRoot, oneDeviceData),
199 agDevHandle,
200 0/* flag */,
201 agIORequest,
202 agNULL);
203
204 if (sasStatus == AGSA_RC_SUCCESS)
205 {
206 return tiSuccess;
207 }
208 else
209 {
210 return tiError;
211 }
212 }
213
214 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
215 {
216 TI_DBG2(("tiINIIOAbort: calling satIOAbort() oneDeviceData=%p\n", oneDeviceData));
217 #ifdef FDS_SM
218 smRoot = &(tdsaAllShared->smRoot);
219 if ( taskTag != agNULL)
220 {
221 ToBeAbortedtdIORequestBody = (tdIORequestBody_t *)taskTag->tdData;
222 ToBeAborted = &(ToBeAbortedtdIORequestBody->smIORequest);
223 status = smIOAbort(smRoot, ToBeAborted);
224 return status;
225 }
226 else
227 {
228 TI_DBG1(("tiINIIOAbort: taskTag is NULL!!!\n"));
229 return tiError;
230 }
231
232 #else
233
234 #ifdef SATA_ENABLE
235 status = satIOAbort(tiRoot, taskTag );
236 #endif
237
238 return status;
239 #endif /* else FDS_SM */
240 }
241
242 else
243 {
244 return tiError;
245 }
246
247 }
248
249 osGLOBAL bit32
250 tiINIIOAbortAll(
251 tiRoot_t *tiRoot,
252 tiDeviceHandle_t *tiDeviceHandle
253 )
254 {
255 agsaRoot_t *agRoot = agNULL;
256 tdsaDeviceData_t *oneDeviceData = agNULL;
257 bit32 status = tiError;
258 #ifdef FDS_SM
259 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
260 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
261 smRoot_t *smRoot = &(tdsaAllShared->smRoot);
262 smDeviceHandle_t *smDeviceHandle;
263 #endif
264
265 TI_DBG1(("tiINIIOAbortAll: start\n"));
266
267 if (tiDeviceHandle == agNULL)
268 {
269 TI_DBG1(("tiINIIOAbortAll: tiDeviceHandle is NULL!!!\n"));
270 return tiError;
271 }
272
273 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
274
275 if (oneDeviceData == agNULL)
276 {
277 TI_DBG1(("tiINIIOAbortAll: oneDeviceData is NULL!!!\n"));
278 return tiError;
279 }
280
281 /* for hotplug */
282 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
283 oneDeviceData->tdPortContext == agNULL )
284 {
285 TI_DBG1(("tiINIIOAbortAll: NO Device did %d\n", oneDeviceData->id ));
286 TI_DBG1(("tiINIIOAbortAll: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
287 TI_DBG1(("tiINIIOAbortAll: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
288 return tiError;
289 }
290
291 agRoot = oneDeviceData->agRoot;
292
293 if (agRoot == agNULL)
294 {
295 TI_DBG1(("tiINIIOAbortAll: agRoot is NULL!!!\n"));
296 return tiError;
297 }
298
299 /* this is processed in ossaSSPAbortCB, ossaSATAAbortCB, ossaSMPAbortCB */
300 if (oneDeviceData->OSAbortAll == agTRUE)
301 {
302 TI_DBG1(("tiINIIOAbortAll: already pending!!!\n"));
303 return tiBusy;
304 }
305 else
306 {
307 oneDeviceData->OSAbortAll = agTRUE;
308 }
309
310 #ifdef FDS_SM
311 if ( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_SMP_TARGET(oneDeviceData))
312 {
313 status = tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
314 }
315 else if (DEVICE_IS_SATA_DEVICE(oneDeviceData) ||
316 DEVICE_IS_STP_TARGET(oneDeviceData)
317 )
318 {
319 TI_DBG2(("tiINIIOAbortAll: calling smIOAbortAll\n"));
320 smDeviceHandle = (smDeviceHandle_t *)&(oneDeviceData->smDeviceHandle);
321 smDeviceHandle->tdData = oneDeviceData;
322 status = smIOAbortAll(smRoot, smDeviceHandle);
323 }
324 else
325 {
326 TI_DBG1(("tiINIIOAbortAll: unknow device type!!! 0x%x\n", oneDeviceData->target_ssp_stp_smp));
327 status = AGSA_RC_FAILURE;
328 }
329 #else
330 status = tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
331 #endif
332
333 return status;
334
335 }
336 #endif /* INITIATOR_DRIVER */
337
338 /*****************************************************************************
339 *! \brief tdsaAbortAll
340 *
341 * Purpose: This function is called to abort an all pending I/O request on a
342 * device
343 *
344 * \param tiRoot: Pointer to initiator driver/port instance.
345 * \param agRoot: Pointer to chip/driver Instance.
346 * \param oneDeviceData: Pointer to the device
347 *
348 * \return:
349 *
350 * None
351 *
352 *****************************************************************************/
353 osGLOBAL bit32
354 tdsaAbortAll(
355 tiRoot_t *tiRoot,
356 agsaRoot_t *agRoot,
357 tdsaDeviceData_t *oneDeviceData
358 )
359 {
360 agsaIORequest_t *agAbortIORequest = agNULL;
361 tdIORequestBody_t *tdAbortIORequestBody = agNULL;
362 bit32 PhysUpper32;
363 bit32 PhysLower32;
364 bit32 memAllocStatus;
365 void *osMemHandle;
366 bit32 status = AGSA_RC_FAILURE;
367
368 TI_DBG1(("tdsaAbortAll: did %d\n", oneDeviceData->id));
369
370 /* allocating agIORequest for abort itself */
371 memAllocStatus = ostiAllocMemory(
372 tiRoot,
373 &osMemHandle,
374 (void **)&tdAbortIORequestBody,
375 &PhysUpper32,
376 &PhysLower32,
377 8,
378 sizeof(tdIORequestBody_t),
379 agTRUE
380 );
381 if (memAllocStatus != tiSuccess)
382 {
383 /* let os process IO */
384 TI_DBG1(("tdsaAbortAll: ostiAllocMemory failed...\n"));
385 return tiError;
386 }
387
388 if (tdAbortIORequestBody == agNULL)
389 {
390 /* let os process IO */
391 TI_DBG1(("tdsaAbortAll: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
392 return tiError;
393 }
394
395 /* setup task management structure */
396 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
397 /* setting callback but not used later */
398 tdAbortIORequestBody->IOCompletionFunc = agNULL;
399 //tdAbortIORequestBody->IOCompletionFunc = itdssIOAbortedHandler;
400
401 tdAbortIORequestBody->tiDevHandle = (tiDeviceHandle_t *)&(oneDeviceData->tiDeviceHandle);
402
403 /* initialize agIORequest */
404 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
405 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
406 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
407
408 if ( DEVICE_IS_SSP_TARGET(oneDeviceData))
409 {
410 /* SSPAbort */
411 status = saSSPAbort(agRoot,
412 agAbortIORequest,
413 tdsaRotateQnumber(tiRoot, oneDeviceData), //0,
414 oneDeviceData->agDevHandle,
415 1, /* abort all */
416 agNULL,
417 agNULL
418 );
419 }
420 else if (DEVICE_IS_SATA_DEVICE(oneDeviceData) ||
421 DEVICE_IS_STP_TARGET(oneDeviceData)
422 )
423 {
424 /* SATAAbort*/
425 if (oneDeviceData->satDevData.IDDeviceValid == agFALSE)
426 {
427 TI_DBG2(("tdsaAbortAll: saSATAAbort\n"));
428 status = saSATAAbort(agRoot,
429 agAbortIORequest,
430 0,
431 oneDeviceData->agDevHandle,
432 1, /* abort all */
433 agNULL,
434 agNULL
435 );
436 }
437 else
438 {
439 TI_DBG2(("tdsaAbortAll: saSATAAbort IDDeviceValid\n"));
440 status = saSATAAbort(agRoot,
441 agAbortIORequest,
442 tdsaRotateQnumber(tiRoot, oneDeviceData), //0,
443 oneDeviceData->agDevHandle,
444 1, /* abort all */
445 agNULL,
446 agNULL
447 );
448 }
449 }
450 else if (DEVICE_IS_SMP_TARGET(oneDeviceData))
451 {
452 /* SMPAbort*/
453 TI_DBG2(("tdsaAbortAll: saSMPAbort \n"));
454 status = saSMPAbort(agRoot,
455 agAbortIORequest,
456 tdsaRotateQnumber(tiRoot, oneDeviceData), //0,
457 oneDeviceData->agDevHandle,
458 1, /* abort all */
459 agNULL,
460 agNULL
461 );
462 }
463 else
464 {
465 TI_DBG1(("tdsaAbortAll: unknown device type!!! 0x%x\n", oneDeviceData->target_ssp_stp_smp));
466 status = AGSA_RC_FAILURE;
467 }
468
469 if (status == AGSA_RC_SUCCESS)
470 {
471 return tiSuccess;
472 }
473 else
474 {
475 TI_DBG1(("tdsaAbortAll: failed status=%d\n", status));
476 //failed to send abort command, we need to free the memory
477 ostiFreeMemory(
478 tiRoot,
479 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle,
480 sizeof(tdIORequestBody_t)
481 );
482 return tiError;
483 }
484
485 }
486
487
488
489 /*****************************************************************************
490 *! \brief tiCOMReset
491 *
492 * Purpose: This function is called to trigger soft or hard reset
493 *
494 * \param tiRoot: Pointer to initiator driver/port instance.
495 * \param option: Options
496 *
497 * \return:
498 *
499 * None
500 *
501 *****************************************************************************/
502 osGLOBAL void
503 tiCOMReset(
504 tiRoot_t *tiRoot,
505 bit32 option
506 )
507 {
508 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
509 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
510 agsaRoot_t *agRoot = agNULL;
511
512
513 #ifdef TI_GETFOR_ONRESET
514 agsaControllerStatus_t controllerStatus;
515 agsaForensicData_t forensicData;
516 bit32 once = 1;
517 bit32 status;
518 #endif /* TI_GETFOR_ONRESET */
519
520 TI_DBG1(("tiCOMReset: start option 0x%x\n",option));
521 tdsaAllShared->resetCount++;
522 TI_DBG2(("tiCOMReset: reset count %d\n", tdsaAllShared->resetCount));
523
524 agRoot = &(tdsaAllShared->agRootNonInt);
525
526 if (tdsaAllShared->flags.resetInProgress == agTRUE)
527 {
528 TI_DBG1(("tiCOMReset : Reset is already in progress : \n"));
529
530 /* don't do anything : just return */
531 return;
532 }
533
534 tdsaAllShared->flags.resetInProgress = agTRUE;
535
536 #ifdef TI_GETFOR_ONRESET
537 saGetControllerStatus(agRoot, &controllerStatus);
538 if(controllerStatus.fatalErrorInfo.errorInfo1)
539 {
540
541 bit8 * DirectData = (bit8 * )tdsaAllShared->FatalErrorData;
542 forensicData.DataType = TYPE_FATAL;
543 forensicData.dataBuf.directLen = (8 * 1024);
544 forensicData.dataBuf.directOffset = 0; /* current offset */
545 forensicData.dataBuf.readLen = 0; /* Data read */
546 getmoreData:
547 forensicData.dataBuf.directData = DirectData;
548 status = saGetForensicData( agRoot, agNULL, &forensicData);
549 TI_DBG1(("tiCOMReset:status %d readLen 0x%x directLen 0x%x directOffset 0x%x\n",
550 status,
551 forensicData.dataBuf.readLen,
552 forensicData.dataBuf.directLen,
553 forensicData.dataBuf.directOffset));
554
555 if( forensicData.dataBuf.readLen == forensicData.dataBuf.directLen && !status && once)
556 {
557 DirectData += forensicData.dataBuf.readLen;
558 goto getmoreData;
559 }
560 TI_DBG1(("tiCOMReset:saGetForensicData type %d read 0x%x bytes\n", forensicData.DataType, forensicData.dataBuf.directOffset ));
561 }
562
563 #endif /* TI_GETFOR_ONRESET */
564 if (option == tiSoftReset)
565 {
566 /* soft reset */
567 TI_DBG6(("tiCOMReset: soft reset\n"));
568 saHwReset(agRoot, AGSA_SOFT_RESET, 0);
569 return;
570 }
571 else
572 {
573 saHwReset(agRoot, AGSA_SOFT_RESET, 0);
574 #ifdef NOT_YET
575 /* hard reset */
576 saHwReset(agRoot, AGSA_CHIP_RESET, 0);
577 #endif
578 }
579 return;
580 }
581
582
583 /*****************************************************************************/
584 /*! \biref tiINIReportErrorToEventLog
585 *
586 * Purpose: This function is called to report errors that needs to be logged
587 * into event log.
588 *
589 * \param tiRoot: Pointer to initiator specific root data structure for this
590 * instance of the driver.
591 * \param agEventData: Event data structure.
592 *
593 * \return None.
594 *
595 */
596 /*****************************************************************************/
597 #ifdef INITIATOR_DRIVER
598 osGLOBAL bit32
599 tiINIReportErrorToEventLog(
600 tiRoot_t *tiRoot,
601 tiEVTData_t *agEventData
602 )
603 {
604 TI_DBG6(("tiINIReportErrorToEventLog: start\n"));
605 return tiError;
606 }
607 #endif /* INITIATOR_DRIVER */
608
609 /*****************************************************************************/
610 /*! \brief ossaReenableInterrupts
611 *
612 *
613 * Purpose: This routine is called to enable interrupt
614 *
615 *
616 * \param agRoot: Pointer to chip/driver Instance.
617 * \param outboundChannelNum: Zero-base channel number
618 *
619 *
620 * \return None.
621 *
622 * \note - The scope is shared target and initiator.
623 *
624 */
625 /*****************************************************************************/
626 #ifndef ossaReenableInterrupts
627 osGLOBAL void
628 ossaReenableInterrupts(
629 agsaRoot_t *agRoot,
630 bit32 outboundChannelNum
631 )
632 {
633 tdsaRootOsData_t *osData = (tdsaRootOsData_t *) (agRoot->osData);
634
635 ostiInterruptEnable(
636 osData->tiRoot,
637 outboundChannelNum
638 );
639 return;
640 }
641
642 #endif
643
644
645
646
647 /*
648 1. initiator
649 send task management
650 call saSSPAbort()
651
652 2. Target
653 call saSSPAbort()
654
655 */
656
657 /*****************************************************************************
658 *! \brief tiINITaskManagement
659 *
660 * Purpose: This routine is called to explicitly ask the Transport Dependent
661 * Layer to issue a Task Management command to a device.
662 *
663 * \param tiRoot: Pointer to driver instance
664 * \param tiDeviveHandle: Pointer to the device handle for this session.
665 * \param task: SAM-2 task management request.
666 * \param lun: Pointer to the SCSI-3 LUN information
667 * when applicable. Set to zero when not applicable.
668 * \param taskTag: Pointer to the associated task where the task
669 * management command is to be applied. Set to agNULL
670 * if not applicable for the specific Task Management
671 * task.
672 * \param currentTaskTag: The current context or task tag for this task. This
673 * task tag will be passed back in ostiInitiatorEvent()
674 * when this task management is completed.
675 *
676 * \return:
677 * tiSuccess TM request successfully initiated.
678 * tiBusy No resources available, try again later.
679 * tiIONoDevice Invalid device handle.
680 * tiError Other errors that prevent the TM request to be started.
681 *
682 *****************************************************************************/
683 /*
684 warm reset->smp phy control(hard reset) or saLocalPhyControl(AGSA_PHY_HARD_RESET)
685
686 */
687 #ifdef INITIATOR_DRIVER
688 osGLOBAL bit32
689 tiINITaskManagement (
690 tiRoot_t *tiRoot,
691 tiDeviceHandle_t *tiDeviceHandle,
692 bit32 task,
693 tiLUN_t *lun,
694 tiIORequest_t *taskTag, /* being aborted one */
695 tiIORequest_t *currentTaskTag /* task management itself */
696 )
697 {
698
699 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
700 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
701 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
702 agsaRoot_t *agRoot = agNULL;
703 bit32 tiStatus = tiError;
704 bit32 notImplemented = agFALSE;
705 tdsaDeviceData_t *oneDeviceData = agNULL;
706 void *osMemHandle;
707 tdIORequestBody_t *TMtdIORequestBody;
708 bit32 PhysUpper32;
709 bit32 PhysLower32;
710 bit32 memAllocStatus;
711 bit32 agRequestType;
712 agsaIORequest_t *agIORequest = agNULL; /* task management itself */
713 agsaIORequest_t *agTMRequest = agNULL; /* IO being task managed */
714 agsaDevHandle_t *agDevHandle = agNULL;
715 agsaSASRequestBody_t *agSASRequestBody = agNULL;
716 agsaSSPScsiTaskMgntReq_t *agSSPTaskMgntRequest;
717 bit32 saStatus;
718 tdIORequestBody_t *tdIORequestBody;
719 #ifdef FDS_SM
720 smRoot_t *smRoot;
721 smDeviceHandle_t *smDeviceHandle;
722 smIORequest_t *ToBeAborted = agNULL;
723 smIORequest_t *TaskManagement;
724 tdIORequestBody_t *ToBeAbortedtdIORequestBody;
725 tdIORequestBody_t *SMTMtdIORequestBody;
726 void *SMosMemHandle;
727 bit32 SMPhysUpper32;
728 bit32 SMPhysLower32;
729 bit32 SMmemAllocStatus;
730 #endif
731
732 TI_DBG2(("tiINITaskManagement: start\n"));
733
734 /* just for testing only */
735 #ifdef REMOVED
736 //start temp
737 if(tiDeviceHandle == agNULL)
738 {
739 TI_DBG1(("tiINITaskManagement: tiDeviceHandle is NULL\n"));
740 return tiError;
741 }
742
743 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
744 if(oneDeviceData == agNULL)
745 {
746 TI_DBG1(("tiINITaskManagement: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle));
747 return tiError;
748 }
749 TI_DBG1(("tiINITaskManagement: did %d\n", oneDeviceData->id ));
750 return tiError;
751 //end temp
752
753 // just for testing
754 if (task == AG_LOGICAL_UNIT_RESET)
755 {
756 TI_DBG1(("tiINITaskManagement: failing LUN RESET for testing\n"));
757 return tiError;
758 }
759
760 #endif
761
762 switch(task)
763 {
764 case AG_ABORT_TASK:
765 TI_DBG6(("tiINITaskManagement: ABORT_TASK\n"));
766 break;
767 case AG_ABORT_TASK_SET:
768 TI_DBG6(("tiINITaskManagement: ABORT_TASK_SET\n"));
769 break;
770 case AG_CLEAR_ACA:
771 TI_DBG6(("tiINITaskManagement: CLEAR_ACA\n"));
772 break;
773 case AG_CLEAR_TASK_SET:
774 TI_DBG6(("tiINITaskManagement: CLEAR_TASK_SET\n"));
775 break;
776 case AG_LOGICAL_UNIT_RESET:
777 TI_DBG6(("tiINITaskManagement: LOGICAL_UNIT_RESET\n"));
778 break;
779 case AG_TARGET_WARM_RESET:
780 TI_DBG6(("tiINITaskManagement: TARGET_WARM_RESET\n"));
781 break;
782 case AG_QUERY_TASK:
783 TI_DBG6(("tiINITaskManagement: QUERY_TASK\n"));
784 break;
785 default:
786 TI_DBG1(("tiINITaskManagement: notImplemented 0x%0x !!!\n",task));
787 notImplemented = agTRUE;
788 break;
789 }
790
791 if (notImplemented)
792 {
793 TI_DBG1(("tiINITaskManagement: not implemented 0x%0x !!!\n",task));
794 return tiStatus;
795 }
796
797 if(tiDeviceHandle == agNULL)
798 {
799 TI_DBG1(("tiINITaskManagement: tiDeviceHandle is NULL\n"));
800 return tiError;
801 }
802
803 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
804 if(oneDeviceData == agNULL)
805 {
806 TI_DBG1(("tiINITaskManagement: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle));
807 return tiIONoDevice;
808 }
809
810 /* for hotplug */
811 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
812 oneDeviceData->tdPortContext == agNULL )
813 {
814 TI_DBG1(("tiINITaskManagement: NO Device did %d Addr 0x%08x:0x%08x\n", oneDeviceData->id , oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
815 return tiIONoDevice;
816 }
817
818 /* 1. call tiINIOAbort()
819 2. call tdssTaskXmit()
820 */
821
822 if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
823 {
824 agRoot = oneDeviceData->agRoot;
825 agDevHandle = oneDeviceData->agDevHandle;
826 TI_DBG1(("tiINITaskManagement: SAS Device\n"));
827
828 /*
829 WARM_RESET is experimental code.
830 Needs more testing and debugging
831 */
832 if (task == AG_TARGET_WARM_RESET)
833 {
834 agsaContext_t *agContext;
835 tdsaDeviceData_t *tdsaDeviceData;
836
837 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
838 currentTaskTag->tdData = tdsaDeviceData;
839 agContext = &(tdsaDeviceData->agDeviceResetContext);
840 agContext->osData = currentTaskTag;
841
842 TI_DBG2(("tiINITaskManagement: did %d device reset for SAS\n", oneDeviceData->id));
843 saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, SA_DS_IN_RECOVERY);
844
845 /* warm reset by saLocalPhyControl or SMP PHY control */
846 if (oneDeviceData->directlyAttached == agTRUE)
847 {
848 TI_DBG2(("tiINITaskManagement: device reset directly attached\n"));
849 saLocalPhyControl(agRoot,
850 agContext,
851 tdsaRotateQnumber(tiRoot, oneDeviceData),
852 oneDeviceData->phyID,
853 AGSA_PHY_HARD_RESET,
854 agNULL
855 );
856 return tiSuccess;
857 }
858 else
859 {
860 TI_DBG2(("tiINITaskManagement: device reset expander attached\n"));
861 saStatus = tdsaPhyControlSend(tiRoot,
862 oneDeviceData,
863 SMP_PHY_CONTROL_HARD_RESET,
864 currentTaskTag,
865 tdsaRotateQnumber(tiRoot, oneDeviceData)
866 );
867 return saStatus;
868 }
869 }
870 else
871 {
872 /* task management */
873 TI_DBG6(("tiINITaskManagement: making task management frame \n"));
874 /* 1. create task management frame
875 2. sends it using "saSSPStart()"
876 */
877 /* Allocate memory for task management */
878 memAllocStatus = ostiAllocMemory(
879 tiRoot,
880 &osMemHandle,
881 (void **)&TMtdIORequestBody,
882 &PhysUpper32,
883 &PhysLower32,
884 8,
885 sizeof(tdIORequestBody_t),
886 agTRUE
887 );
888
889 if (memAllocStatus != tiSuccess)
890 {
891 TI_DBG1(("tiINITaskManagement: ostiAllocMemory failed...\n"));
892 return tiError;
893 }
894
895 if (TMtdIORequestBody == agNULL)
896 {
897 TI_DBG1(("tiINITaskManagement: ostiAllocMemory returned NULL TMIORequestBody\n"));
898 return tiError;
899 }
900
901 /* initialize */
902 osti_memset(TMtdIORequestBody, 0, sizeof(tdIORequestBody_t));
903
904 /* setup task management structure */
905 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
906 TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = currentTaskTag;
907 TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = taskTag;
908
909 /* let's initialize tdIOrequestBody */
910 /* initialize jump table */
911
912 /* direct callback for task management */
913 TMtdIORequestBody->IOCompletionFunc = itdssTaskCompleted;
914 /* to be removed */
915 /* TMtdIORequestBody->IOCompletionFunc = itdssIOCompleted; */
916
917 /* initialize tiDevhandle */
918 TMtdIORequestBody->tiDevHandle = tiDeviceHandle;
919
920 /* initialize tiIORequest */
921 TMtdIORequestBody->tiIORequest = currentTaskTag;
922 /* save context if we need to abort later */
923 currentTaskTag->tdData = TMtdIORequestBody;
924
925 /* initialize agIORequest */
926 agIORequest = &(TMtdIORequestBody->agIORequest);
927 agIORequest->osData = (void *) TMtdIORequestBody;
928 agIORequest->sdkData = agNULL; /* SA takes care of this */
929
930 /* request type */
931 agRequestType = AGSA_SSP_TASK_MGNT_REQ;
932 TMtdIORequestBody->agRequestType = AGSA_SSP_TASK_MGNT_REQ;
933 /*
934 initialize
935 tdIORequestBody_t tdIORequestBody -> agSASRequestBody
936 */
937 agSASRequestBody = &(TMtdIORequestBody->transport.SAS.agSASRequestBody);
938 agSSPTaskMgntRequest = &(agSASRequestBody->sspTaskMgntReq);
939
940 TI_DBG2(("tiINITaskManagement: did %d LUN reset for SAS\n", oneDeviceData->id));
941 /* fill up LUN field */
942 if (lun == agNULL)
943 {
944 osti_memset(agSSPTaskMgntRequest->lun, 0, 8);
945 }
946 else
947 {
948 osti_memcpy(agSSPTaskMgntRequest->lun, lun->lun, 8);
949 }
950
951 /* default: unconditionally set device state to SA_DS_IN_RECOVERY
952 bit1 (DS) bit0 (ADS)
953 bit1: 1 bit0: 0
954 */
955 agSSPTaskMgntRequest->tmOption = 2;
956
957 /* sets taskMgntFunction field */
958 switch(task)
959 {
960 case AG_ABORT_TASK:
961 agSSPTaskMgntRequest->taskMgntFunction = AGSA_ABORT_TASK;
962 /* For abort task management, unconditionally set device state to SA_DS_IN_RECOVERY
963 and if can't find, set device state to SA_DS_IN_RECOVERY
964 bit1 (DS) bit0 (ADS)
965 bit1: 1; bit0: 1
966 */
967 agSSPTaskMgntRequest->tmOption = 3;
968 break;
969 case AG_ABORT_TASK_SET:
970 agSSPTaskMgntRequest->taskMgntFunction = AGSA_ABORT_TASK_SET;
971 break;
972 case AG_CLEAR_ACA:
973 agSSPTaskMgntRequest->taskMgntFunction = AGSA_CLEAR_ACA;
974 break;
975 case AG_CLEAR_TASK_SET:
976 agSSPTaskMgntRequest->taskMgntFunction = AGSA_CLEAR_TASK_SET;
977 break;
978 case AG_LOGICAL_UNIT_RESET:
979 agSSPTaskMgntRequest->taskMgntFunction = AGSA_LOGICAL_UNIT_RESET;
980 break;
981 case AG_QUERY_TASK:
982 agSSPTaskMgntRequest->taskMgntFunction = AGSA_QUERY_TASK;
983 break;
984 default:
985 TI_DBG1(("tiINITaskManagement: notImplemented task\n"));
986 break;
987 }
988
989 if (task == AGSA_ABORT_TASK || task == AGSA_QUERY_TASK)
990 {
991 /* set agTMRequest, which is IO being task managed */
992 tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData;
993 if (tdIORequestBody == agNULL)
994 {
995 /* to be aborted IO has been completed. */
996 /* free up allocated memory */
997 TI_DBG1(("tiINITaskManagement: IO has been completed\n"));
998 ostiFreeMemory(
999 tiRoot,
1000 osMemHandle,
1001 sizeof(tdIORequestBody_t)
1002 );
1003 return tiIONoDevice;
1004 }
1005 else
1006 {
1007 agTMRequest = &(tdIORequestBody->agIORequest);
1008 }
1009 }
1010 else
1011 {
1012 /*
1013 For LUN RESET, WARM_RESET, ABORT_TASK_SET, CLEAR_ACA and CLEAR_TASK_SET
1014 no tag to be managed.
1015 Therefore, set it to zero.
1016 */
1017 agSSPTaskMgntRequest->tagOfTaskToBeManaged = 0;
1018 agTMRequest = agNULL;
1019
1020 }
1021
1022 TDLIST_INIT_HDR(&TMtdIORequestBody->EsglPageList);
1023 /* debuggging */
1024 if (TMtdIORequestBody->IOCompletionFunc == agNULL)
1025 {
1026 TI_DBG1(("tiINITaskManagement: Error!!!!! IOCompletionFunc is NULL\n"));
1027 }
1028 saStatus = saSSPStart(agRoot,
1029 agIORequest, /* task management itself */
1030 tdsaRotateQnumber(tiRoot, oneDeviceData),
1031 agDevHandle,
1032 agRequestType,
1033 agSASRequestBody, /* task management itself */
1034 agTMRequest, /* io to be aborted if exits */
1035 &ossaSSPCompleted);
1036
1037
1038 if (saStatus == AGSA_RC_SUCCESS)
1039 {
1040 Initiator->NumIOsActive++;
1041 tiStatus = tiSuccess;
1042 }
1043 else
1044 {
1045 TI_DBG1(("tiINITaskManagement: saSSPStart failed 0x%x\n",saStatus));
1046 /* free up allocated memory */
1047 ostiFreeMemory(
1048 tiRoot,
1049 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
1050 sizeof(tdIORequestBody_t)
1051 );
1052 if (saStatus == AGSA_RC_FAILURE)
1053 {
1054 tiStatus = tiError;
1055 }
1056 else
1057 {
1058 /* AGSA_RC_BUSY */
1059 tiStatus = tiBusy;
1060 }
1061 }
1062 }
1063 } /* end of sas device */
1064
1065 #ifdef FDS_SM
1066 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
1067 {
1068 agsaContext_t *agContext = agNULL;
1069
1070 /* save the task tag in tdsaDeviceData_t structure, for handling PORT_RESET_COMPLETE hw event */
1071 agContext = &(oneDeviceData->agDeviceResetContext);
1072 agContext->osData = currentTaskTag;
1073
1074 #ifdef REMOVED
1075 /* for directly attached SATA, do localphycontrol for LUN and target reset, not smTaskManagement*/
1076 if (oneDeviceData->directlyAttached == agTRUE &&
1077 (task == AG_LOGICAL_UNIT_RESET || task == AG_TARGET_WARM_RESET))
1078 {
1079 agRoot = oneDeviceData->agRoot;
1080 agDevHandle = oneDeviceData->agDevHandle;
1081
1082 currentTaskTag->tdData = oneDeviceData;
1083
1084 if (task == AG_LOGICAL_UNIT_RESET)
1085 {
1086 if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
1087 lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
1088 {
1089 TI_DBG1(("tiINITaskManagement: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n",
1090 tiDeviceHandle));
1091 return tiError;
1092 }
1093 }
1094 saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, SA_DS_IN_RECOVERY);
1095 tiStatus = saLocalPhyControl(agRoot, agContext, tdsaRotateQnumber(tiRoot, oneDeviceData), oneDeviceData->phyID, AGSA_PHY_HARD_RESET, agNULL);
1096 }
1097 else
1098 #endif
1099 {
1100 smRoot = &(tdsaAllShared->smRoot);
1101 smDeviceHandle = &(oneDeviceData->smDeviceHandle);
1102 TI_DBG1(("tiINITaskManagement: FDS_SM SATA Device\n"));
1103
1104 if ( taskTag != agNULL)
1105 {
1106 ToBeAbortedtdIORequestBody = (tdIORequestBody_t *)taskTag->tdData;
1107 ToBeAborted = &(ToBeAbortedtdIORequestBody->smIORequest);
1108 }
1109 SMmemAllocStatus = ostiAllocMemory(
1110 tiRoot,
1111 &SMosMemHandle,
1112 (void **)&SMTMtdIORequestBody,
1113 &SMPhysUpper32,
1114 &SMPhysLower32,
1115 8,
1116 sizeof(tdIORequestBody_t),
1117 agTRUE
1118 );
1119 if (SMmemAllocStatus != tiSuccess)
1120 {
1121 TI_DBG1(("tiINITaskManagement: ostiAllocMemory failed... loc 2\n"));
1122 return tiError;
1123 }
1124
1125 if (SMTMtdIORequestBody == agNULL)
1126 {
1127 TI_DBG1(("tiINITaskManagement: ostiAllocMemory returned NULL TMIORequestBody loc 2\n"));
1128 return tiError;
1129 }
1130
1131 /* initialize */
1132 osti_memset(SMTMtdIORequestBody, 0, sizeof(tdIORequestBody_t));
1133
1134 /* setup task management structure */
1135 SMTMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = SMosMemHandle;
1136 SMTMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = currentTaskTag;
1137 SMTMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = taskTag;
1138
1139 /* initialize tiDevhandle */
1140 SMTMtdIORequestBody->tiDevHandle = tiDeviceHandle;
1141
1142 /* initialize tiIORequest */
1143 SMTMtdIORequestBody->tiIORequest = currentTaskTag;
1144 /* save context if we need to abort later */
1145 currentTaskTag->tdData = SMTMtdIORequestBody;
1146
1147 TaskManagement = &(SMTMtdIORequestBody->smIORequest);
1148
1149 TaskManagement->tdData = SMTMtdIORequestBody;
1150 TaskManagement->smData = &SMTMtdIORequestBody->smIORequestBody;
1151
1152 tiStatus = smTaskManagement(smRoot,
1153 smDeviceHandle,
1154 task,
1155 (smLUN_t*)lun,
1156 ToBeAborted,
1157 TaskManagement
1158 );
1159 if (tiStatus != SM_RC_SUCCESS)
1160 {
1161 TI_DBG1(("tiINITaskManagement: smTaskManagement failed... loc 2\n"));
1162 /* free up allocated memory */
1163 ostiFreeMemory(
1164 tiRoot,
1165 SMTMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
1166 sizeof(tdIORequestBody_t)
1167 );
1168 }
1169 } /* else */
1170 }
1171 #else
1172 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
1173 {
1174 agRoot = oneDeviceData->agRoot;
1175 agDevHandle = oneDeviceData->agDevHandle;
1176 TI_DBG1(("tiINITaskManagement: not FDS_SM SATA Device\n"));
1177 /*
1178 WARM_RESET is experimental
1179 Needs more testing and debugging
1180 Soft reset for SATA as LUN RESET tends not to work.
1181 Let's do hard reset
1182 */
1183 if (task == AG_LOGICAL_UNIT_RESET || task == AG_TARGET_WARM_RESET)
1184 {
1185
1186 agsaContext_t *agContext;
1187 satDeviceData_t *satDevData;
1188 tdsaDeviceData_t *tdsaDeviceData;
1189
1190 TI_DBG2(("tiINITaskManagement: did %d LUN reset or device reset for SATA\n", oneDeviceData->id));
1191 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
1192 satDevData = &tdsaDeviceData->satDevData;
1193 currentTaskTag->tdData = tdsaDeviceData;
1194 agContext = &(tdsaDeviceData->agDeviceResetContext);
1195 agContext->osData = currentTaskTag;
1196
1197
1198 if (task == AG_LOGICAL_UNIT_RESET)
1199 {
1200 if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
1201 lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
1202 {
1203 TI_DBG1(("tiINITaskManagement: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n",
1204 tiDeviceHandle));
1205 return tiError;
1206 }
1207
1208 /*
1209 * Check if there is other TM request pending
1210 */
1211 if (satDevData->satTmTaskTag != agNULL)
1212 {
1213 TI_DBG1(("tiINITaskManagement: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
1214 tiDeviceHandle));
1215 return tiError;
1216 }
1217 }
1218 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
1219 satDevData->satAbortAfterReset = agFALSE;
1220
1221 saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, SA_DS_IN_RECOVERY);
1222
1223 /*
1224 warm reset by saLocalPhyControl or SMP PHY control
1225 */
1226 if (oneDeviceData->directlyAttached == agTRUE)
1227 {
1228 TI_DBG1(("tiINITaskManagement: LUN reset or device reset directly attached\n"));
1229 saLocalPhyControl(agRoot, agContext, tdsaRotateQnumber(tiRoot, oneDeviceData), oneDeviceData->phyID, AGSA_PHY_HARD_RESET, agNULL);
1230 return tiSuccess;
1231 }
1232 else
1233 {
1234 TI_DBG1(("tiINITaskManagement: LUN reset or device reset expander attached\n"));
1235 saStatus = tdsaPhyControlSend(tiRoot,
1236 oneDeviceData,
1237 SMP_PHY_CONTROL_HARD_RESET,
1238 currentTaskTag,
1239 tdsaRotateQnumber(tiRoot, oneDeviceData)
1240 );
1241 return saStatus;
1242 }
1243 }
1244 else
1245 {
1246 TI_DBG2(("tiINITaskManagement: calling satTM().\n"));
1247 /* allocation tdIORequestBody and pass it to satTM() */
1248 memAllocStatus = ostiAllocMemory(
1249 tiRoot,
1250 &osMemHandle,
1251 (void **)&TMtdIORequestBody,
1252 &PhysUpper32,
1253 &PhysLower32,
1254 8,
1255 sizeof(tdIORequestBody_t),
1256 agTRUE
1257 );
1258
1259 if (memAllocStatus != tiSuccess)
1260 {
1261 TI_DBG1(("tiINITaskManagement: ostiAllocMemory failed... loc 2\n"));
1262 return tiError;
1263 }
1264
1265 if (TMtdIORequestBody == agNULL)
1266 {
1267 TI_DBG1(("tiINITaskManagement: ostiAllocMemory returned NULL TMIORequestBody loc 2\n"));
1268 return tiError;
1269
1270 }
1271
1272 /* initialize */
1273 osti_memset(TMtdIORequestBody, 0, sizeof(tdIORequestBody_t));
1274
1275 /* setup task management structure */
1276 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
1277 TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = currentTaskTag;
1278 TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = taskTag;
1279
1280 /* initialize tiDevhandle */
1281 TMtdIORequestBody->tiDevHandle = tiDeviceHandle;
1282
1283 /* initialize tiIORequest */
1284 TMtdIORequestBody->tiIORequest = currentTaskTag;
1285 /* save context if we need to abort later */
1286 currentTaskTag->tdData = TMtdIORequestBody;
1287
1288 /* initialize agIORequest */
1289 agIORequest = &(TMtdIORequestBody->agIORequest);
1290 agIORequest->osData = (void *) TMtdIORequestBody;
1291 agIORequest->sdkData = agNULL; /* SA takes care of this */
1292
1293
1294 #ifdef SATA_ENABLE
1295 tiStatus = satTM( tiRoot,
1296 tiDeviceHandle,
1297 task,
1298 lun,
1299 taskTag,
1300 currentTaskTag,
1301 TMtdIORequestBody,
1302 agTRUE
1303 );
1304 #endif
1305 }
1306 }
1307 #endif /* FDS_SM else*/
1308
1309 return tiStatus;
1310 }
1311 #endif /* INITIATOR_DRIVER */
1312
1313 #ifdef PASSTHROUGH
1314 osGLOBAL bit32
1315 tiCOMPassthroughCmndStart(
1316 tiRoot_t *tiRoot,
1317 tiPassthroughRequest_t *tiPassthroughRequest,
1318 tiDeviceHandle_t *tiDeviceHandle,
1319 tiPassthroughCmnd_t *tiPassthroughCmnd,
1320 void *tiPassthroughBody,
1321 tiPortalContext_t *tiportalContext,
1322 ostiPassthroughCmndEvent_t agEventCB
1323 )
1324 {
1325 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
1326 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
1327 tdsaDeviceData_t *oneDeviceData;
1328 agsaRoot_t *agRoot = agNULL;
1329 agsaIORequest_t *agIORequest = agNULL;
1330 agsaDevHandle_t *agDevHandle = agNULL;
1331 bit32 agRequestType;
1332 agsaSASRequestBody_t *agSASRequestBody = agNULL;
1333
1334 tdPassthroughCmndBody_t *tdPTCmndBody;
1335 tdssSMPRequestBody_t *tdssSMPRequestBody;
1336 agsaSMPFrame_t *agSMPFrame;
1337 agsaSSPVSFrame_t *agSSPVendorFrame; /* RMC */
1338 bit32 SMPFn, SMPFnResult, SMPFrameLen;
1339 bit32 tiStatus = tiError;
1340 bit32 saStatus = AGSA_RC_FAILURE;
1341 tdsaPortStartInfo_t *tdsaPortStartInfo;
1342 tdsaPortContext_t *tdsaPortContext;
1343
1344 TI_DBG2(("tiCOMPassthroughCmndStart: start\n"));
1345
1346 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
1347
1348 TI_DBG6(("tiCOMPassthroughCmndStart: onedevicedata %p\n", oneDeviceData));
1349
1350
1351 tdPTCmndBody = (tdPassthroughCmndBody_t *)tiPassthroughBody;
1352
1353
1354 if (tiPassthroughCmnd->passthroughCmnd != tiSMPCmnd ||
1355 tiPassthroughCmnd->passthroughCmnd != tiRMCCmnd)
1356 {
1357 return tiNotSupported;
1358 }
1359
1360
1361 if (oneDeviceData == agNULL && tiPassthroughCmnd->passthroughCmnd != tiSMPCmnd)
1362 {
1363 TI_DBG1(("tiCOMPassthroughCmndStart: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
1364 return tiIONoDevice;
1365 }
1366
1367 /* starting IO with SAS device */
1368 if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
1369 {
1370 if (tiPassthroughCmnd->passthroughCmnd == tiSMPCmnd)
1371 {
1372 TI_DBG2(("tiCOMPassthroughCmndStart: SMP\n"));
1373 if (oneDeviceData == agNULL)
1374 {
1375 tdsaPortStartInfo = (tdsaPortStartInfo_t *)tiportalContext->tdData;
1376 tdsaPortContext = tdsaPortStartInfo->portContext;
1377 agRoot = tdsaPortContext->agRoot;
1378 }
1379 else
1380 {
1381 agRoot = oneDeviceData->agRoot;
1382 agDevHandle = oneDeviceData->agDevHandle;
1383 }
1384
1385
1386 tdssSMPRequestBody = &(tdPTCmndBody->protocol.SMP.SMPBody);
1387 agSASRequestBody = &(tdssSMPRequestBody->agSASRequestBody);
1388 agSMPFrame = &(agSASRequestBody->smpFrame);
1389
1390 /* saves callback function */
1391 tdPTCmndBody->EventCB = agEventCB;
1392
1393 /* initialize command type */
1394 tdPTCmndBody->tiPassthroughCmndType = tiSMPCmnd;
1395
1396 /* initialize tipassthroughrequest */
1397 tdPTCmndBody->tiPassthroughRequest = tiPassthroughRequest;
1398 tiPassthroughRequest->tdData = tdPTCmndBody;
1399
1400 /* initialize tiDevhandle */
1401 tdPTCmndBody->tiDevHandle = tiDeviceHandle;
1402
1403 /* fill in SMP header */
1404 agSMPFrame->frameHeader.smpFrameType
1405 = tiPassthroughCmnd->protocol.SMP.SMPHeader.smpFrameType;
1406 agSMPFrame->frameHeader.smpFunction
1407 = tiPassthroughCmnd->protocol.SMP.SMPHeader.smpFunction;
1408 agSMPFrame->frameHeader.smpFunctionResult
1409 = tiPassthroughCmnd->protocol.SMP.SMPHeader.smpFunctionResult;
1410 agSMPFrame->frameHeader.smpReserved
1411 = tiPassthroughCmnd->protocol.SMP.SMPHeader.smpReserved;
1412
1413 if (tiPassthroughCmnd->protocol.SMP.IT == SMP_INITIATOR)
1414 {
1415 agRequestType = AGSA_SMP_INIT_REQ;
1416 }
1417 else
1418 {
1419 agRequestType = AGSA_SMP_TGT_RESPONSE;
1420 /* this is only for SMP target */
1421 agSMPFrame->phyId = tiPassthroughCmnd->protocol.SMP.phyID;
1422 }
1423
1424 /* fill in payload */
1425 /* assumption: SMP payload is in tisgl1 */
1426 agSMPFrame->frameAddrUpper32 = tiPassthroughCmnd->tiSgl.upper;
1427 agSMPFrame->frameAddrLower32 = tiPassthroughCmnd->tiSgl.lower;
1428
1429 /* This length excluding SMP header (4 bytes) and CRC field */
1430 agSMPFrame->frameLen = tiPassthroughCmnd->tiSgl.len;
1431
1432 /* initialize agIORequest */
1433 /*
1434 Compare:
1435 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
1436 */
1437 agIORequest = &(tdssSMPRequestBody->agIORequest);
1438 agIORequest->osData = (void *) tdPTCmndBody;
1439 agIORequest->sdkData = agNULL; /* LL takes care of this */
1440
1441
1442
1443 /* not work yet because of high priority q */
1444 saStatus = saSMPStart(
1445 agRoot,
1446 agIORequest,
1447 agDevHandle,
1448 agRequestType,
1449 agSASRequestBody,
1450 &ossaSMPCompleted
1451 );
1452
1453 if (saStatus == AGSA_RC_SUCCESS)
1454 {
1455 tiStatus = tiSuccess;
1456 }
1457 else if (saStatus == AGSA_RC_FAILURE)
1458 {
1459 TI_DBG1(("tiCOMPassthroughCmndStart: saSMPStart failed\n"));
1460 tiStatus = tiError;
1461 }
1462 else
1463 {
1464 /* AGSA_RC_BUSY */
1465 TI_DBG1(("tiCOMPassthroughCmndStart: saSMPStart busy\n"));
1466 tiStatus = tiBusy;
1467 }
1468 return tiStatus;
1469
1470
1471 #ifdef TO_DO
1472 /* fill in SMP header */
1473 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR)
1474 {
1475 agSMPFrame->frameHeader.smpFrameType = SMP_REQUEST; /* SMP REQUEST */
1476 agRequestType = AGSA_SMP_INIT_REQ;
1477 }
1478 else
1479 {
1480 /* SMP target */
1481 agSMPFrame->frameHeader.smpFrameType = SMP_RESPONSE; /* SMP RESPONSE */
1482 agRequestType = AGSA_SMP_TGT_RESPONSE;
1483 switch (tdPTCmndBody->protocol.SMP.SMPFnResult)
1484 {
1485 case tiSMPFunctionAccepted:
1486 SMPFnResult = SMP_FUNCTION_ACCEPTED;
1487 break;
1488 case tiUnknownSMPFunction:
1489 SMPFnResult = UNKNOWN_SMP_FUNCTION;
1490 break;
1491 case tiSMPFunctionFailed:
1492 SMPFnResult = SMP_FUNCTION_FAILED;
1493 break;
1494 case tiInvalidRequestFrameLength:
1495 SMPFnResult = INVALID_REQUEST_FRAME_LENGTH;
1496 break;
1497 case tiPhyDoesNotExist:
1498 SMPFnResult =PHY_DOES_NOT_EXIST;
1499 break;
1500 case tiIndexDoesNotExist:
1501 SMPFnResult = INDEX_DOES_NOT_EXIST;
1502 break;
1503 case tiPhyDoesNotSupportSATA:
1504 SMPFnResult = PHY_DOES_NOT_SUPPORT_SATA;
1505 break;
1506 case tiUnknownPhyOperation:
1507 SMPFnResult = UNKNOWN_PHY_OPERATION;
1508 break;
1509 case tiUnknownPhyTestFunction:
1510 SMPFnResult = UNKNOWN_PHY_TEST_FUNCTION;
1511 break;
1512 case tiPhyTestFunctionInProgress:
1513 SMPFnResult = PHY_TEST_FUNCTION_IN_PROGRESS;
1514 break;
1515 case tiPhyVacant:
1516 SMPFnResult = PHY_VACANT;
1517 break;
1518
1519 default:
1520 TI_DBG1(("tiCOMPassthroughCmndStart: unknown SMP function result %d\n", tdPTCmndBody->protocol.SMP.SMPFnResult));
1521 return tiError;
1522 }
1523 agSMPFrame->frameHeader.smpFunctionResult = SMPFnResult;
1524 }
1525
1526 /* common */
1527 switch (tdPTCmndBody->protocol.SMP.SMPFn)
1528 {
1529 case tiGeneral:
1530 SMPFn = SMP_REPORT_GENERAL;
1531 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR)
1532 {
1533 SMPFrameLen = 0;
1534 }
1535 else
1536 {
1537 SMPFrameLen = sizeof(smpRespReportGeneral_t);
1538 }
1539 break;
1540
1541 case tiManufacturerInfo:
1542 SMPFn = SMP_REPORT_MANUFACTURE_INFORMATION;
1543 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR)
1544 {
1545 SMPFrameLen = 0;
1546 }
1547 else
1548 {
1549 SMPFrameLen = sizeof(smpRespReportManufactureInfo_t);
1550 }
1551 break;
1552
1553 case tiDiscover:
1554 SMPFn = SMP_DISCOVER;
1555 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR)
1556 {
1557 SMPFrameLen = sizeof(smpReqDiscover_t);
1558 }
1559 else
1560 {
1561 SMPFrameLen = sizeof(smpRespDiscover_t);
1562 }
1563 break;
1564
1565 case tiReportPhyErrLog:
1566 SMPFn = SMP_REPORT_PHY_ERROR_LOG;
1567 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR)
1568 {
1569 SMPFrameLen = 8;
1570 }
1571 else
1572 {
1573 SMPFrameLen = 24;
1574 }
1575 break;
1576
1577 case tiReportPhySATA:
1578 SMPFn = SMP_REPORT_PHY_SATA;
1579 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR)
1580 {
1581 SMPFrameLen = sizeof(SmpReqReportPhySata_t);
1582 }
1583 else
1584 {
1585 SMPFrameLen = sizeof(SmpRespReportPhySata_t);
1586 }
1587 break;
1588
1589 case tiReportRteInfo:
1590 SMPFn = SMP_REPORT_ROUTING_INFORMATION;
1591 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR)
1592 {
1593 SMPFrameLen = sizeof(SmpReqReportRouteTable_t);
1594 }
1595 else
1596 {
1597 SMPFrameLen = sizeof(SmpRespReportRouteTable_t);
1598 }
1599 break;
1600
1601 case tiConfigureRteInfo:
1602 SMPFn = SMP_CONFIGURE_ROUTING_INFORMATION;
1603 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR)
1604 {
1605 SMPFrameLen = sizeof(SmpReqConfigureRouteInformation_t);
1606 }
1607 else
1608 {
1609 SMPFrameLen = 0;
1610 }
1611 break;
1612
1613 case tiPhyCtrl:
1614 SMPFn = SMP_PHY_CONTROL;
1615 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR)
1616 {
1617 SMPFrameLen = sizeof(SmpReqPhyControl_t);
1618 }
1619 else
1620 {
1621 SMPFrameLen = 0;
1622 }
1623 break;
1624
1625 case tiPhyTestFn:
1626 SMPFn = SMP_PHY_TEST_FUNCTION;
1627 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR)
1628 {
1629 SMPFrameLen = 36;
1630 }
1631 else
1632 {
1633 SMPFrameLen = 0;
1634 }
1635 break;
1636
1637 case tiPMC:
1638 SMPFn = SMP_PMC_SPECIFIC;
1639 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR)
1640 {
1641 SMPFrameLen = 0;
1642 }
1643 else
1644 {
1645 SMPFrameLen = 0;
1646 }
1647 break;
1648
1649
1650 default:
1651 TI_DBG1(("tiCOMPassthroughCmndStart: unknown SMP function %d\n", tdPTCmndBody->protocol.SMP.SMPFn));
1652 return tiError;
1653 }
1654 agSMPFrame->frameHeader.smpFunction = SMPFn;
1655
1656
1657 /* assumption: SMP payload is in tisgl1 */
1658 agSMPFrame->frameAddrUpper32 = tdPTCmndBody->tiSgl.upper;
1659 agSMPFrame->frameAddrLower32 = tdPTCmndBody->tiSgl.lower;
1660
1661 /* This length excluding SMP header (4 bytes) and CRC field */
1662 agSMPFrame->frameLen = SMPFrameLen;
1663
1664
1665
1666
1667
1668
1669 #endif
1670
1671
1672 }
1673 else if (tiPassthroughCmnd->passthroughCmnd == tiRMCCmnd)
1674 {
1675 TI_DBG2(("tiCOMPassthroughCmndStart: RMC\n"));
1676 }
1677 else
1678 {
1679 TI_DBG1(("tiCOMPassthroughCmndStart: unknown protocol %d\n", tiPassthroughCmnd->passthroughCmnd));
1680 }
1681
1682
1683 }
1684 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
1685 {
1686 TI_DBG1(("tiCOMPassthroughCmndStart: error !!! no SATA support\n"));
1687 return tiError;
1688 }
1689 else
1690 {
1691 TI_DBG1(("tiCOMPassthroughCmndStart: error !!! unknown devietype %d\n", oneDeviceData->DeviceType));
1692 return tiError;
1693
1694 }
1695
1696 return tiSuccess;
1697 }
1698
1699
1700 osGLOBAL bit32
1701 tiCOMPassthroughCmndAbort(
1702 tiRoot_t *tiRoot,
1703 tiPassthroughRequest_t *taskTag
1704 )
1705 {
1706 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
1707 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
1708 agsaRoot_t *agRoot = agNULL;
1709 tdPassthroughCmndBody_t *tdPTCmndBody = agNULL;
1710 tdssSMPRequestBody_t *tdssSMPRequestBody = agNULL;
1711 agsaIORequest_t *agIORequest = agNULL;
1712 bit32 saStatus, tiStatus = tiError;
1713
1714 TI_DBG2(("tiCOMPassthroughCmndAbort: start\n"));
1715
1716 agRoot = &(tdsaAllShared->agRootNonInt);
1717 tdPTCmndBody = (tdPassthroughCmndBody_t *)taskTag->tdData;
1718
1719 if (tdPTCmndBody->tiPassthroughCmndType == tiSMPCmnd)
1720 {
1721 tdssSMPRequestBody = &(tdPTCmndBody->protocol.SMP.SMPBody);
1722 agIORequest = &(tdssSMPRequestBody->agIORequest);
1723
1724 saStatus = saSMPAbort(agRoot, agIORequest);
1725
1726 if (saStatus == AGSA_RC_SUCCESS)
1727 {
1728 tiStatus = tiSuccess;
1729 }
1730 else if (saStatus == AGSA_RC_FAILURE)
1731 {
1732 TI_DBG1(("tiCOMPassthroughCmndAbort: saSMPAbort failed\n"));
1733 tiStatus = tiError;
1734 }
1735 else
1736 {
1737 /* AGSA_RC_BUSY */
1738 TI_DBG1(("tiCOMPassthroughCmndAbort: saSMPAbort busy\n"));
1739 tiStatus = tiBusy;
1740 }
1741 return tiStatus;
1742 }
1743 else if (tdPTCmndBody->tiPassthroughCmndType == tiRMCCmnd)
1744 {
1745 TI_DBG1(("tiCOMPassthroughCmndAbort: RMC passthrough command type, not yet\n"));
1746
1747 }
1748 else
1749 {
1750 TI_DBG1(("tiCOMPassthroughCmndAbort: unknown passthrough command type %d\n", tdPTCmndBody->tiPassthroughCmndType));
1751 return tiStatus;
1752 }
1753
1754
1755 }
1756
1757 osGLOBAL bit32
1758 tiINIPassthroughCmndRemoteAbort(
1759 tiRoot_t *tiRoot,
1760 tiDeviceHandle_t *tiDeviceHandle,
1761 tiPassthroughRequest_t *taskTag,
1762 tiPassthroughRequest_t *currentTaskTag,
1763 tiPortalContext_t *tiportalContext
1764 )
1765 {
1766 TI_DBG2(("tiINIPassthroughCmndRemoteAbort: start\n"));
1767 /*
1768 for SMP, nothing. Can't abot remotely
1769 */
1770 return tiSuccess;
1771 }
1772 #endif /* PASSTHROUGH */
1773
1774
1775 /*****************************************************************************
1776 *! \brief tiCOMShutDown
1777 *
1778 * Purpose: This function is called to shutdown the initiator and/or target
1779 * operation. Following the completion of this call, the state is
1780 * equivalent to the state prior to tiCOMInit()
1781 *
1782 * \param tiRoot: Pointer to root data structure.
1783 *
1784 * \return None
1785 *
1786 *
1787 *****************************************************************************/
1788 osGLOBAL void
1789 tiCOMShutDown( tiRoot_t *tiRoot)
1790 {
1791 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
1792 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
1793
1794 // #define TI_GETFOR_ONSHUTDOWN
1795 #ifdef TI_GETFOR_ONSHUTDOWN
1796 agsaForensicData_t forensicData;
1797 bit32 once = 1;
1798 bit32 status;
1799 #endif /* TI_GETFOR_ONSHUTDOWN */
1800
1801 agsaRoot_t *agRoot = agNULL;
1802
1803 TI_DBG1(("tiCOMShutDown: start\n"));
1804
1805
1806 agRoot = &(tdsaAllShared->agRootNonInt);
1807 /*
1808 1. free up cardID
1809 2. call saHwShutdown()
1810 3. tdInitEsgl(tiRoot);
1811 4. tdsaResetComMemFlags(tiRoot)
1812 5. ostiPortEvent()
1813 */
1814
1815 tdsaFreeCardID(tiRoot, tdsaAllShared->CardID);
1816
1817 #ifdef TI_GETFOR_ONSHUTDOWN
1818 forensicData.DataType = TYPE_NON_FATAL;
1819 forensicData.dataBuf.directLen = (8 * 1024);
1820 forensicData.dataBuf.directOffset = 0; /* current offset */
1821 forensicData.dataBuf.directData = agNULL;
1822 forensicData.dataBuf.readLen = 0; /* Data read */
1823
1824 getmoreData:
1825 status = saGetForensicData( agRoot, agNULL, &forensicData);
1826
1827 TI_DBG1(("tiCOMShutDown:readLen 0x%x directLen 0x%x directOffset 0x%x\n",
1828 forensicData.dataBuf.readLen,
1829 forensicData.dataBuf.directLen,
1830 forensicData.dataBuf.directOffset));
1831 if( forensicData.dataBuf.readLen == forensicData.dataBuf.directLen && !status && once)
1832 {
1833 goto getmoreData;
1834 }
1835
1836 TI_DBG1(("tiCOMShutDown:saGetForensicData type %d read 0x%x bytes\n", forensicData.DataType, forensicData.dataBuf.directOffset ));
1837 #endif /* TI_GETFOR_ONSHUTDOWN */
1838
1839 saHwShutdown(agRoot);
1840
1841 /* resets all the relevant flags */
1842 tdsaResetComMemFlags(tiRoot);
1843
1844 /*
1845 * send an event to the oslayer
1846 */
1847 ostiPortEvent (
1848 tiRoot,
1849 tiPortShutdown,
1850 tiSuccess,
1851 agNULL
1852 );
1853
1854 return;
1855 }
1856
1857 #ifdef INITIATOR_DRIVER
1858 osGLOBAL void
1859 tiINITimerTick( tiRoot_t *tiRoot )
1860 {
1861 /*
1862 no timer is used in SAS TD layer.
1863 Therefore, this function is null.
1864 */
1865 // TI_DBG2(("tiINITimerTick: start\n"));
1866 /*itdsaProcessTimers(tiRoot);*/
1867 return;
1868 }
1869 #endif
1870
1871 /*****************************************************************************/
1872 /*! \brief ossaDisableInterrupts
1873 *
1874 *
1875 * Purpose: This routine is called to disable interrupt
1876 *
1877 *
1878 * \param agRoot: Pointer to chip/driver Instance.
1879 * \param outboundChannelNum: Zero-base channel number
1880 *
1881 *
1882 * \return None.
1883 *
1884 * \note - The scope is shared target and initiator.
1885 *
1886 */
1887 /*****************************************************************************/
1888 #ifndef ossaDisableInterrupts
1889 osGLOBAL void
1890 ossaDisableInterrupts(
1891 agsaRoot_t *agRoot,
1892 bit32 outboundChannelNum
1893 )
1894 {
1895 tdsaRootOsData_t *osData = (tdsaRootOsData_t *) (agRoot->osData);
1896
1897 ostiInterruptDisable(
1898 osData->tiRoot,
1899 outboundChannelNum
1900 );
1901 return;
1902 }
1903
1904 #endif
1905
1906
1907 osGLOBAL void
1908 tiCOMFrameReadBlock(
1909 tiRoot_t *tiRoot,
1910 void *agFrame,
1911 bit32 FrameOffset,
1912 void *FrameBuffer,
1913 bit32 FrameBufLen )
1914 {
1915 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
1916 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
1917 agsaRoot_t *agRoot = agNULL;
1918
1919 TI_DBG6(("tiCOMFrameReadBlock: start\n"));
1920
1921
1922 agRoot = &(tdsaAllShared->agRootNonInt);
1923
1924
1925 TI_DBG6(("tiCOMFrameReadBlock: start\n"));
1926
1927 saFrameReadBlock(agRoot, agFrame, FrameOffset, FrameBuffer, FrameBufLen);
1928
1929 return;
1930 }
1931
1932
1933
1934 /*****************************************************************************
1935 *! \brief tiINITransportRecovery
1936 *
1937 * Purpose: This routine is called to explicitly ask the Transport Dependent
1938 * Layer to initiate the recovery for the transport/protocol specific
1939 * error for a specific device connection.
1940 *
1941 * \param tiRoot: Pointer to driver instance
1942 * \param tiDeviveHandle: Pointer to the device handle for this session.
1943 *
1944 * \return: None
1945 *
1946 *
1947 *****************************************************************************/
1948 #ifdef INITIATOR_DRIVER
1949 osGLOBAL void
1950 tiINITransportRecovery (
1951 tiRoot_t *tiRoot,
1952 tiDeviceHandle_t *tiDeviceHandle
1953 )
1954 {
1955 agsaRoot_t *agRoot = agNULL;
1956 tdsaDeviceData_t *oneDeviceData = agNULL;
1957 tdsaPortContext_t *onePortContext = agNULL;
1958 tiPortalContext_t *tiPortalContext = agNULL;
1959 tiIORequest_t *currentTaskTag;
1960 agsaDevHandle_t *agDevHandle = agNULL;
1961
1962 TI_DBG1(("tiINITransportRecovery: start\n"));
1963
1964 if (tiDeviceHandle == agNULL)
1965 {
1966 TI_DBG1(("tiINITransportRecovery: tiDeviceHandle is NULL\n"));
1967
1968 return;
1969 }
1970
1971 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
1972
1973 if (oneDeviceData == agNULL)
1974 {
1975 TI_DBG1(("tiINITransportRecovery: oneDeviceData is NULL\n"));
1976 return;
1977 }
1978
1979 /* for hotplug */
1980 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
1981 oneDeviceData->tdPortContext == agNULL )
1982 {
1983 TI_DBG1(("tiINITransportRecovery: NO Device did %d\n", oneDeviceData->id ));
1984 TI_DBG1(("tiINITransportRecovery: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
1985 TI_DBG1(("tiINITransportRecovery: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
1986 return;
1987 }
1988
1989 onePortContext = oneDeviceData->tdPortContext;
1990
1991 if (onePortContext == agNULL)
1992 {
1993 TI_DBG1(("tiINITransportRecovery: onePortContext is NULL\n"));
1994 return;
1995 }
1996
1997 tiPortalContext = onePortContext->tiPortalContext;
1998 currentTaskTag = &(oneDeviceData->TransportRecoveryIO);
1999 currentTaskTag->osData = agNULL;
2000 agRoot = oneDeviceData->agRoot;
2001 agDevHandle = oneDeviceData->agDevHandle;
2002
2003 if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
2004 {
2005 agsaContext_t *agContext;
2006 currentTaskTag->tdData = oneDeviceData;
2007 agContext = &(oneDeviceData->agDeviceResetContext);
2008 agContext->osData = currentTaskTag;
2009 oneDeviceData->TRflag = agTRUE;
2010
2011 TI_DBG2(("tiINITransportRecovery: SAS device\n"));
2012 saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, SA_DS_IN_RECOVERY);
2013
2014 if (oneDeviceData->directlyAttached == agTRUE)
2015 {
2016 TI_DBG2(("tiINITransportRecovery: saLocalPhyControl\n"));
2017 saLocalPhyControl(agRoot, agContext, tdsaRotateQnumber(tiRoot, oneDeviceData), oneDeviceData->phyID, AGSA_PHY_HARD_RESET, agNULL);
2018 ostiInitiatorEvent(tiRoot,
2019 tiPortalContext,
2020 tiDeviceHandle,
2021 tiIntrEventTypeTransportRecovery,
2022 tiRecStarted,
2023 agNULL
2024 );
2025
2026 return;
2027 }
2028 else
2029 {
2030 TI_DBG2(("tiINITransportRecovery: device reset expander attached\n"));
2031 tdsaPhyControlSend(tiRoot,
2032 oneDeviceData,
2033 SMP_PHY_CONTROL_HARD_RESET,
2034 currentTaskTag,
2035 tdsaRotateQnumber(tiRoot, oneDeviceData)
2036 );
2037 ostiInitiatorEvent(tiRoot,
2038 tiPortalContext,
2039 tiDeviceHandle,
2040 tiIntrEventTypeTransportRecovery,
2041 tiRecStarted,
2042 agNULL
2043 );
2044 return;
2045 }
2046 }
2047 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
2048 {
2049 agsaContext_t *agContext;
2050 currentTaskTag->tdData = oneDeviceData;
2051 agContext = &(oneDeviceData->agDeviceResetContext);
2052 agContext->osData = currentTaskTag;
2053 oneDeviceData->TRflag = agTRUE;
2054
2055 TI_DBG2(("tiINITransportRecovery: SATA device\n"));
2056 saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, SA_DS_IN_RECOVERY);
2057
2058 if (oneDeviceData->directlyAttached == agTRUE)
2059 {
2060 TI_DBG2(("tiINITransportRecovery: saLocalPhyControl\n"));
2061 saLocalPhyControl(agRoot, agContext, tdsaRotateQnumber(tiRoot, oneDeviceData), oneDeviceData->phyID, AGSA_PHY_LINK_RESET, agNULL);
2062 ostiInitiatorEvent(tiRoot,
2063 tiPortalContext,
2064 tiDeviceHandle,
2065 tiIntrEventTypeTransportRecovery,
2066 tiRecStarted,
2067 agNULL
2068 );
2069
2070 return;
2071 }
2072 else
2073 {
2074 TI_DBG2(("tiINITransportRecovery: device reset expander attached\n"));
2075 tdsaPhyControlSend(tiRoot,
2076 oneDeviceData,
2077 SMP_PHY_CONTROL_LINK_RESET,
2078 currentTaskTag,
2079 tdsaRotateQnumber(tiRoot, oneDeviceData)
2080 );
2081 ostiInitiatorEvent(tiRoot,
2082 tiPortalContext,
2083 tiDeviceHandle,
2084 tiIntrEventTypeTransportRecovery,
2085 tiRecStarted,
2086 agNULL
2087 );
2088 return;
2089 }
2090 }
2091 else
2092 {
2093 TI_DBG1(("tiINITransportRecovery: wrong device type %d\n", oneDeviceData->DeviceType));
2094 }
2095
2096
2097 return;
2098 }
2099 #endif
2100
2101 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
2102 /*****************************************************************************
2103 *! \brief tdsaPhyControlSend
2104 *
2105 * Purpose: This function sends Phy Control to a device.
2106 *
2107 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
2108 * instance.
2109 * \param oneDeviceData: Pointer to the device data.
2110 * \param phyId: Phy Identifier.
2111 * \param queueNumber: bits 0-15: inbound queue number.
2112 * bits 16-31: outbound queue number.
2113 *
2114 * \return:
2115 * Status
2116 *
2117 * \note:
2118 *
2119 *****************************************************************************/
2120 /* phyop of interest
2121 SMP_PHY_CONTROL_HARD_RESET or SMP_PHY_CONTROL_CLEAR_AFFILIATION
2122 if CurrentTaskTag == agNULL, clear affiliation
2123 if CurrentTaskTag != agNULL, PHY_CONTROL (device reset)
2124
2125 */
2126 osGLOBAL bit32
2127 tdsaPhyControlSend(
2128 tiRoot_t *tiRoot,
2129 tdsaDeviceData_t *oneDeviceData, /* taget disk */
2130 bit8 phyOp,
2131 tiIORequest_t *CurrentTaskTag,
2132 bit32 queueNumber
2133 )
2134 {
2135 return 0;
2136 }
2137 #endif
2138
2139 #ifdef TARGET_DRIVER
2140 /*****************************************************************************
2141 *! \brief tdsaPhyControlSend
2142 *
2143 * Purpose: This function sends Phy Control to a device.
2144 *
2145 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
2146 * instance.
2147 * \param oneDeviceData: Pointer to the device data.
2148 * \param phyId: Phy Identifier.
2149 * \param queueNumber: bits 0-15: inbound queue number.
2150 * bits 16-31: outbound queue number.
2151 *
2152 * \return:
2153 * Status
2154 *
2155 * \note:
2156 *
2157 *****************************************************************************/
2158 /* phyop of interest
2159 SMP_PHY_CONTROL_HARD_RESET or SMP_PHY_CONTROL_CLEAR_AFFILIATION
2160 if CurrentTaskTag == agNULL, clear affiliation
2161 if CurrentTaskTag != agNULL, PHY_CONTROL (device reset)
2162
2163 */
2164 osGLOBAL bit32
2165 tdsaPhyControlSend(
2166 tiRoot_t *tiRoot,
2167 tdsaDeviceData_t *oneDeviceData, /* taget disk */
2168 bit8 phyOp,
2169 tiIORequest_t *CurrentTaskTag,
2170 bit32 queueNumber
2171 )
2172 {
2173 return 0;
2174 }
2175 #endif
2176
2177
2178 #ifdef INITIATOR_DRIVER
2179 /*****************************************************************************
2180 *! \brief tdsaPhyControlSend
2181 *
2182 * Purpose: This function sends Phy Control to a device.
2183 *
2184 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
2185 * instance.
2186 * \param oneDeviceData: Pointer to the device data.
2187 * \param phyId: Phy Identifier.
2188 * \param queueNumber: bits 0-15: inbound queue number.
2189 * bits 16-31: outbound queue number.
2190 *
2191 * \return:
2192 * Status
2193 *
2194 * \note:
2195 *
2196 *****************************************************************************/
2197 /* phyop of interest
2198 SMP_PHY_CONTROL_HARD_RESET or SMP_PHY_CONTROL_CLEAR_AFFILIATION
2199 if CurrentTaskTag == agNULL, clear affiliation
2200 if CurrentTaskTag != agNULL, PHY_CONTROL (device reset)
2201
2202 */
2203 osGLOBAL bit32
2204 tdsaPhyControlSend(
2205 tiRoot_t *tiRoot,
2206 tdsaDeviceData_t *oneDeviceData, /* taget disk */
2207 bit8 phyOp,
2208 tiIORequest_t *CurrentTaskTag,
2209 bit32 queueNumber
2210 )
2211 {
2212 agsaRoot_t *agRoot;
2213 tdsaDeviceData_t *oneExpDeviceData;
2214 tdsaPortContext_t *onePortContext;
2215 smpReqPhyControl_t smpPhyControlReq;
2216 bit8 phyID;
2217 bit32 status;
2218
2219 TI_DBG3(("tdsaPhyControlSend: start\n"));
2220
2221 agRoot = oneDeviceData->agRoot;
2222 onePortContext = oneDeviceData->tdPortContext;
2223 oneExpDeviceData = oneDeviceData->ExpDevice;
2224 phyID = oneDeviceData->phyID;
2225
2226 if (oneDeviceData->directlyAttached == agTRUE)
2227 {
2228 TI_DBG1(("tdsaPhyControlSend: Error!!! deivce is directly attached\n"));
2229 return AGSA_RC_FAILURE;
2230 }
2231 if (onePortContext == agNULL)
2232 {
2233 TI_DBG1(("tdsaPhyControlSend: Error!!! portcontext is NULL\n"));
2234 return AGSA_RC_FAILURE;
2235 }
2236
2237 if (oneExpDeviceData == agNULL)
2238 {
2239 TI_DBG1(("tdsaPhyControlSend: Error!!! expander is NULL\n"));
2240 return AGSA_RC_FAILURE;
2241 }
2242
2243 if (phyOp == SMP_PHY_CONTROL_HARD_RESET)
2244 {
2245 TI_DBG3(("tdsaPhyControlSend: SMP_PHY_CONTROL_HARD_RESET\n"));
2246 }
2247 if (phyOp == SMP_PHY_CONTROL_LINK_RESET)
2248 {
2249 TI_DBG3(("tdsaPhyControlSend: SMP_PHY_CONTROL_LINK_RESET\n"));
2250 }
2251 if (phyOp == SMP_PHY_CONTROL_CLEAR_AFFILIATION)
2252 {
2253 TI_DBG3(("tdsaPhyControlSend: SMP_PHY_CONTROL_CLEAR_AFFILIATION\n"));
2254 }
2255 TI_DBG3(("tdsaPhyControlSend: target device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
2256 TI_DBG3(("tdsaPhyControlSend: target device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
2257 TI_DBG3(("tdsaPhyControlSend: expander AddrHi 0x%08x\n", oneExpDeviceData->SASAddressID.sasAddressHi));
2258 TI_DBG3(("tdsaPhyControlSend: expander AddrLo 0x%08x\n", oneExpDeviceData->SASAddressID.sasAddressLo));
2259 TI_DBG3(("tdsaPhyControlSend: did %d expander did %d phyid %d\n", oneDeviceData->id, oneExpDeviceData->id, phyID));
2260
2261
2262 osti_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t));
2263
2264 /* fill in SMP payload */
2265 smpPhyControlReq.phyIdentifier = phyID;
2266 smpPhyControlReq.phyOperation = phyOp;
2267
2268 status = tdSMPStart(
2269 tiRoot,
2270 agRoot,
2271 oneExpDeviceData,
2272 SMP_PHY_CONTROL,
2273 (bit8 *)&smpPhyControlReq,
2274 sizeof(smpReqPhyControl_t),
2275 AGSA_SMP_INIT_REQ,
2276 CurrentTaskTag,
2277 queueNumber
2278 );
2279 return status;
2280 }
2281 #endif
2282
2283 /*****************************************************************************
2284 *! \brief tdsaPhyControlFailureRespRcvd
2285 *
2286 * Purpose: This function processes the failure of Phy Control response.
2287 *
2288 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
2289 * instance.
2290 * \param agRoot: Pointer to chip/driver Instance.
2291 * \param oneDeviceData: Pointer to the device data.
2292 * \param frameHeader: Pointer to SMP frame header.
2293 * \param frameHandle: A Handle used to refer to the response frame
2294 *
2295 * \return:
2296 * None
2297 *
2298 * \note:
2299 *
2300 *****************************************************************************/
2301 osGLOBAL void
2302 tdsaPhyControlFailureRespRcvd(
2303 tiRoot_t *tiRoot,
2304 agsaRoot_t *agRoot,
2305 tdsaDeviceData_t *oneDeviceData,
2306 tdssSMPFrameHeader_t *frameHeader,
2307 agsaFrameHandle_t frameHandle,
2308 tiIORequest_t *CurrentTaskTag
2309 )
2310 {
2311 #if defined(INITIATOR_DRIVER) || defined(TD_DEBUG_ENABLE)
2312 tdsaDeviceData_t *TargetDeviceData = agNULL;
2313 #endif
2314 #ifdef TD_DEBUG_ENABLE
2315 satDeviceData_t *pSatDevData = agNULL;
2316 #endif
2317 // agsaDevHandle_t *agDevHandle = agNULL;
2318
2319 TI_DBG1(("tdsaPhyControlFailureRespRcvd: start\n"));
2320
2321 TI_DBG3(("tdsaPhyControlFailureRespRcvd: expander device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
2322 TI_DBG3(("tdsaPhyControlFailureRespRcvd: expander device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
2323
2324 if (CurrentTaskTag != agNULL )
2325 {
2326 /* This was set in tiINITaskmanagement() */
2327 #if defined(INITIATOR_DRIVER) || defined(TD_DEBUG_ENABLE)
2328 TargetDeviceData = (tdsaDeviceData_t *)CurrentTaskTag->tdData;
2329 #endif
2330 #ifdef TD_DEBUG_ENABLE
2331 pSatDevData = (satDeviceData_t *)&(TargetDeviceData->satDevData);
2332 #endif
2333 // agDevHandle = TargetDeviceData->agDevHandle;
2334 TI_DBG2(("tdsaPhyControlFailureRespRcvd: target AddrHi 0x%08x\n", TargetDeviceData->SASAddressID.sasAddressHi));
2335 TI_DBG2(("tdsaPhyControlFailureRespRcvd: target AddrLo 0x%08x\n", TargetDeviceData->SASAddressID.sasAddressLo));
2336
2337 #ifdef TD_DEBUG_ENABLE
2338 TI_DBG2(("tdsaPhyControlFailureRespRcvd: satPendingIO %d satNCQMaxIO %d\n", pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
2339 TI_DBG2(("tdsaPhyControlFailureRespRcvd: satPendingNCQIO %d satPendingNONNCQIO %d\n", pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
2340 #endif
2341 }
2342
2343 #ifdef INITIATOR_DRIVER
2344 if (CurrentTaskTag != agNULL )
2345 {
2346 TI_DBG1(("tdsaPhyControlRespRcvd: callback to OS layer with failure\n"));
2347 if (TargetDeviceData->TRflag == agTRUE)
2348 {
2349 TargetDeviceData->TRflag = agFALSE;
2350 ostiInitiatorEvent(tiRoot,
2351 TargetDeviceData->tdPortContext->tiPortalContext,
2352 &(TargetDeviceData->tiDeviceHandle),
2353 tiIntrEventTypeTransportRecovery,
2354 tiRecFailed ,
2355 agNULL
2356 );
2357 }
2358 else
2359 {
2360 ostiInitiatorEvent( tiRoot,
2361 NULL,
2362 NULL,
2363 tiIntrEventTypeTaskManagement,
2364 tiTMFailed,
2365 CurrentTaskTag );
2366 }
2367 }
2368 #endif
2369 return;
2370 }
2371 /*****************************************************************************
2372 *! \brief tdsaPhyControlRespRcvd
2373 *
2374 * Purpose: This function processes Phy Control response.
2375 *
2376 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
2377 * instance.
2378 * \param agRoot: Pointer to chip/driver Instance.
2379 * \param oneDeviceData: Pointer to the device data.
2380 * \param frameHeader: Pointer to SMP frame header.
2381 * \param frameHandle: A Handle used to refer to the response frame
2382 *
2383 * \return:
2384 * None
2385 *
2386 * \note:
2387 *
2388 *****************************************************************************/
2389 osGLOBAL void
2390 tdsaPhyControlRespRcvd(
2391 tiRoot_t *tiRoot,
2392 agsaRoot_t *agRoot,
2393 agsaIORequest_t *agIORequest,
2394 tdsaDeviceData_t *oneDeviceData,
2395 tdssSMPFrameHeader_t *frameHeader,
2396 agsaFrameHandle_t frameHandle,
2397 tiIORequest_t *CurrentTaskTag
2398 )
2399 {
2400 #if defined(INITIATOR_DRIVER) || defined(TD_DEBUG_ENABLE)
2401 tdsaDeviceData_t *TargetDeviceData = agNULL;
2402 #endif
2403 #ifdef INITIATOR_DRIVER
2404 satDeviceData_t *pSatDevData = agNULL;
2405 agsaDevHandle_t *agDevHandle = agNULL;
2406 #endif
2407
2408 TI_DBG3(("tdsaPhyControlRespRcvd: start\n"));
2409
2410 TI_DBG3(("tdsaPhyControlRespRcvd: expander device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
2411 TI_DBG3(("tdsaPhyControlRespRcvd: expander device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
2412
2413 if (CurrentTaskTag != agNULL )
2414 {
2415 /* This was set in tiINITaskmanagement() */
2416 #if defined(INITIATOR_DRIVER) || defined(TD_DEBUG_ENABLE)
2417 TargetDeviceData = (tdsaDeviceData_t *)CurrentTaskTag->tdData;
2418 #endif
2419 #ifdef INITIATOR_DRIVER
2420 pSatDevData = (satDeviceData_t *)&(TargetDeviceData->satDevData);
2421 agDevHandle = TargetDeviceData->agDevHandle;
2422 #endif
2423 TI_DBG2(("tdsaPhyControlRespRcvd: target AddrHi 0x%08x\n", TargetDeviceData->SASAddressID.sasAddressHi));
2424 TI_DBG2(("tdsaPhyControlRespRcvd: target AddrLo 0x%08x\n", TargetDeviceData->SASAddressID.sasAddressLo));
2425
2426 #ifdef INITIATOR_DRIVER
2427 TI_DBG2(("tdsaPhyControlRespRcvd: satPendingIO %d satNCQMaxIO %d\n", pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
2428 TI_DBG2(("tdsaPhyControlRespRcvd: satPendingNCQIO %d satPendingNONNCQIO %d\n", pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
2429 #endif
2430 }
2431
2432 #ifdef INITIATOR_DRIVER
2433 /* no payload */
2434 if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2435 {
2436 TI_DBG3(("tdsaPhyControlRespRcvd: SMP success\n"));
2437
2438 /* warm reset or clear affiliation is done
2439 call ostiInitiatorEvent()
2440 */
2441 if (CurrentTaskTag != agNULL )
2442 {
2443 TI_DBG3(("tdsaPhyControlRespRcvd: callback to OS layer with success\n"));
2444 pSatDevData->satDriveState = SAT_DEV_STATE_NORMAL;
2445 saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, TargetDeviceData), agDevHandle, SA_DS_OPERATIONAL);
2446
2447 if (TargetDeviceData->TRflag == agTRUE)
2448 {
2449 TargetDeviceData->TRflag = agFALSE;
2450 ostiInitiatorEvent(tiRoot,
2451 TargetDeviceData->tdPortContext->tiPortalContext,
2452 &(TargetDeviceData->tiDeviceHandle),
2453 tiIntrEventTypeTransportRecovery,
2454 tiRecOK,
2455 agNULL
2456 );
2457 }
2458 else
2459 {
2460 agDevHandle = TargetDeviceData->agDevHandle;
2461 if (agDevHandle == agNULL)
2462 {
2463 TI_DBG1(("tdsaPhyControlRespRcvd: wrong, agDevHandle is NULL\n"));
2464 }
2465 ostiInitiatorEvent( tiRoot,
2466 NULL,
2467 NULL,
2468 tiIntrEventTypeTaskManagement,
2469 tiTMOK,
2470 CurrentTaskTag );
2471 }
2472 }
2473
2474 }
2475 else
2476 {
2477 TI_DBG1(("tdsaPhyControlRespRcvd: SMP failure; result %d\n", frameHeader->smpFunctionResult));
2478 /* warm reset or clear affiliation is done
2479 */
2480 if (CurrentTaskTag != agNULL )
2481 {
2482 TI_DBG1(("tdsaPhyControlRespRcvd: callback to OS layer with failure\n"));
2483 if (TargetDeviceData->TRflag == agTRUE)
2484 {
2485 TargetDeviceData->TRflag = agFALSE;
2486 ostiInitiatorEvent(tiRoot,
2487 TargetDeviceData->tdPortContext->tiPortalContext,
2488 &(TargetDeviceData->tiDeviceHandle),
2489 tiIntrEventTypeTransportRecovery,
2490 tiRecFailed ,
2491 agNULL
2492 );
2493 }
2494 else
2495 {
2496 ostiInitiatorEvent( tiRoot,
2497 NULL,
2498 NULL,
2499 tiIntrEventTypeTaskManagement,
2500 tiTMFailed,
2501 CurrentTaskTag );
2502 }
2503 }
2504
2505 }
2506 #endif
2507 return;
2508 }
2509
2510
2511 #ifdef TARGET_DRIVER
2512 /*****************************************************************************
2513 *! \brief ttdsaAbortAll
2514 *
2515 * Purpose: This function is called to abort an all pending I/O request on a
2516 * device
2517 *
2518 * \param tiRoot: Pointer to initiator driver/port instance.
2519 * \param agRoot: Pointer to chip/driver Instance.
2520 * \param oneDeviceData: Pointer to the device
2521 *
2522 * \return:
2523 *
2524 * None
2525 *
2526 *****************************************************************************/
2527 /*
2528 for abort itself,
2529 should we allocate tdAbortIORequestBody or get one from ttdsaXchg_t?
2530 Currently, we allocate tdAbortIORequestBody.
2531 */
2532 osGLOBAL void
2533 ttdsaAbortAll(
2534 tiRoot_t *tiRoot,
2535 agsaRoot_t *agRoot,
2536 tdsaDeviceData_t *oneDeviceData
2537 )
2538 {
2539 agsaIORequest_t *agAbortIORequest = agNULL;
2540 tdIORequestBody_t *tdAbortIORequestBody = agNULL;
2541 bit32 PhysUpper32;
2542 bit32 PhysLower32;
2543 bit32 memAllocStatus;
2544 void *osMemHandle;
2545
2546 TI_DBG3(("tdsaAbortAll: start\n"));
2547
2548 TI_DBG3(("tdsaAbortAll: did %d\n", oneDeviceData->id));
2549
2550
2551 /* allocating agIORequest for abort itself */
2552 memAllocStatus = ostiAllocMemory(
2553 tiRoot,
2554 &osMemHandle,
2555 (void **)&tdAbortIORequestBody,
2556 &PhysUpper32,
2557 &PhysLower32,
2558 8,
2559 sizeof(tdIORequestBody_t),
2560 agTRUE
2561 );
2562 if (memAllocStatus != tiSuccess)
2563 {
2564 /* let os process IO */
2565 TI_DBG1(("tdsaAbortAll: ostiAllocMemory failed...\n"));
2566 return;
2567 }
2568
2569 if (tdAbortIORequestBody == agNULL)
2570 {
2571 /* let os process IO */
2572 TI_DBG1(("tdsaAbortAll: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
2573 return;
2574 }
2575
2576 /* setup task management structure */
2577 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
2578 /* setting callback */
2579 /* not needed; it is already set to be ossaSSPAbortCB() */
2580 tdAbortIORequestBody->IOCompletionFunc = ttdssIOAbortedHandler;
2581
2582 tdAbortIORequestBody->tiDevHandle = (tiDeviceHandle_t *)&(oneDeviceData->tiDeviceHandle);
2583
2584 /* initialize agIORequest */
2585 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
2586 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
2587 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
2588
2589 /* SSPAbort */
2590 saSSPAbort(agRoot,
2591 agAbortIORequest,
2592 0,
2593 oneDeviceData->agDevHandle,
2594 1, /* abort all */
2595 agNULL,
2596 agNULL
2597 );
2598 return;
2599 }
2600 #endif /* TARGET_DRIVER */
2601
2602
2603 osGLOBAL void
2604 tdsaDeregisterDevicesInPort(
2605 tiRoot_t *tiRoot,
2606 tdsaPortContext_t *onePortContext
2607 )
2608 {
2609 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
2610 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
2611 tdsaDeviceData_t *oneDeviceData = agNULL;
2612 tdList_t *DeviceListList;
2613 agsaRoot_t *agRoot = agNULL;
2614
2615 agRoot = &(tdsaAllShared->agRootNonInt);
2616
2617 TI_DBG1(("tdsaDeregisterDevicesInPort: start\n"));
2618
2619 /* find a device's existence */
2620 DeviceListList = tdsaAllShared->MainDeviceList.flink;
2621 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
2622 {
2623 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
2624 if (oneDeviceData == agNULL)
2625 {
2626 TI_DBG1(("tdsaDeregisterDevicesInPort: oneDeviceData is NULL!!!\n"));
2627 return;
2628 }
2629 if (oneDeviceData->tdPortContext == onePortContext)
2630 {
2631 TI_DBG3(("tdsaDeregisterDevicesInPort: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id));
2632 if ( !( DEVICE_IS_SMP_TARGET(oneDeviceData) && oneDeviceData->directlyAttached == agTRUE))
2633 {
2634 saDeregisterDeviceHandle(agRoot, agNULL, oneDeviceData->agDevHandle, tdsaRotateQnumber(tiRoot, oneDeviceData));
2635 }
2636 else
2637 {
2638 TI_DBG1(("tdsaDeregisterDevicesInPort: keeping\n"));
2639 oneDeviceData->registered = agTRUE;
2640 }
2641 }
2642 DeviceListList = DeviceListList->flink;
2643 }
2644
2645 TI_DBG3(("tdsaDeregisterDevicesInPort: end\n"));
2646
2647 return;
2648 }
2649
2650 /******************** for debugging only ***************************/
2651 osGLOBAL void
2652 tdsaPrintSwConfig(
2653 agsaSwConfig_t *SwConfig
2654 )
2655 {
2656 if (SwConfig == agNULL)
2657 {
2658 TI_DBG6(("tdsaPrintSwConfig: SwConfig is NULL\n"));
2659 return;
2660 }
2661 else
2662 {
2663 TI_DBG6(("SwConfig->maxActiveIOs %d\n", SwConfig->maxActiveIOs));
2664 TI_DBG6(("SwConfig->smpReqTimeout %d\n", SwConfig->smpReqTimeout));
2665 }
2666
2667 return;
2668
2669 }
2670
2671 osGLOBAL void
2672 tdsaPrintHwConfig(
2673 agsaHwConfig_t *HwConfig
2674 )
2675 {
2676 if (HwConfig == agNULL)
2677 {
2678 TI_DBG6(("tdsaPrintHwConfig: HwConfig is NULL\n"));
2679 return;
2680 }
2681 else
2682 {
2683 TI_DBG6(("HwConfig->phyCount %d\n", HwConfig->phyCount));
2684 }
2685 return;
2686 }
2687
2688 osGLOBAL void
2689 tdssPrintSASIdentify(
2690 agsaSASIdentify_t *id
2691 )
2692 {
2693 if (id == agNULL)
2694 {
2695 TI_DBG1(("tdsaPrintSASIdentify: ID is NULL\n"));
2696 return;
2697 }
2698 else
2699 {
2700 TI_DBG6(("SASID->sspTargetPort %d\n", SA_IDFRM_IS_SSP_TARGET(id)?1:0));
2701 TI_DBG6(("SASID->stpTargetPort %d\n", SA_IDFRM_IS_STP_TARGET(id)?1:0));
2702 TI_DBG6(("SASID->smpTargetPort %d\n", SA_IDFRM_IS_SMP_TARGET(id)?1:0));
2703 TI_DBG6(("SASID->sspInitiatorPort %d\n", SA_IDFRM_IS_SSP_INITIATOR(id)?1:0));
2704 TI_DBG6(("SASID->stpInitiatorPort %d\n", SA_IDFRM_IS_STP_INITIATOR(id)?1:0));
2705 TI_DBG6(("SASID->smpInitiatorPort %d\n", SA_IDFRM_IS_SMP_INITIATOR(id)?1:0));
2706 TI_DBG6(("SASID->deviceType %d\n", SA_IDFRM_GET_DEVICETTYPE(id)));
2707 TI_DBG6(("SASID->sasAddressHi 0x%x\n", SA_IDFRM_GET_SAS_ADDRESSHI(id)));
2708 TI_DBG6(("SASID->sasAddressLo 0x%x\n", SA_IDFRM_GET_SAS_ADDRESSLO(id)));
2709 TI_DBG6(("SASID->phyIdentifier 0x%x\n", id->phyIdentifier));
2710
2711 }
2712
2713 return;
2714 }
2715
2716 osGLOBAL void
2717 tdsaInitTimerHandler(
2718 tiRoot_t *tiRoot,
2719 void *timerData
2720 )
2721 {
2722
2723 TI_DBG6(("tdsaInitTimerHandler: start\n"));
2724 return;
2725 }
2726
2727 /*
2728 type: 1 portcontext 2 devicedata
2729 flag: 1 FreeLink 2 MainLink
2730 */
2731
2732 osGLOBAL void
2733 print_tdlist_flink(tdList_t *hdr, int type, int flag)
2734 {
2735 tdList_t *hdr_tmp1 = NULL;
2736 #ifdef TD_DEBUG_ENABLE
2737 tdsaPortContext_t *ele1;
2738 #endif
2739 #ifdef REMOVED
2740 tdsaDeviceData_t *ele2;
2741 #endif
2742 hdr_tmp1 = hdr;
2743
2744 if (type == 1 && flag == 1)
2745 {
2746 TI_DBG6(("PortContext and FreeLink\n"));
2747 }
2748 else if (type != 1 && flag == 1)
2749 {
2750 TI_DBG6(("DeviceData and FreeLink\n"));
2751 }
2752 else if (type == 1 && flag != 1)
2753 {
2754 TI_DBG6(("PortContext and MainLink\n"));
2755 }
2756 else
2757 {
2758 TI_DBG6(("DeviceData and MainLink\n"));
2759 }
2760 if (type == 1)
2761 {
2762 do
2763 {
2764 /* data structure type variable = (data structure type, file name, header of the tdList) */
2765 if (flag == 1)
2766 {
2767 #ifdef TD_DEBUG_ENABLE
2768 ele1 = TDLIST_OBJECT_BASE(tdsaPortContext_t, FreeLink, hdr_tmp1);
2769 #endif
2770 }
2771 else
2772 {
2773 #ifdef TD_DEBUG_ENABLE
2774 ele1 = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, hdr_tmp1);
2775 #endif
2776 }
2777 TI_DBG6(("flist ele %d\n", ele1->id));
2778 TI_DBG6(("flist ele %p\n", ele1));
2779 hdr_tmp1 = hdr_tmp1->flink;
2780 } while (hdr_tmp1 != hdr);
2781 }
2782 else
2783 {
2784 do
2785 {
2786 /* data structure type variable = (data structure type, file name, header of the tdList) */
2787 #ifdef REMOVED
2788 if (flag == 1)
2789 {
2790 ele2 = TDLIST_OBJECT_BASE(tdsaDeviceData_t, FreeLink, hdr_tmp1);
2791 }
2792 else
2793 {
2794 ele2 = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, hdr_tmp1);
2795 }
2796 TI_DBG6(("flist ele %d\n", ele2->id));
2797 TI_DBG6(("flist ele %p\n", ele2));
2798 #endif
2799 hdr_tmp1 = hdr_tmp1->flink;
2800 } while (hdr_tmp1 != hdr);
2801 }
2802 TI_DBG6(("\n"));
2803 }
2804
2805 /* not verified yet. 6/15/2005 */
2806 osGLOBAL void
2807 print_tdlist_blink(tdList_t *hdr, int flag)
2808 {
2809 tdList_t *hdr_tmp1 = NULL;
2810 #ifdef REMOVED
2811 tdsaPortContext_t *ele1;
2812 #endif
2813 hdr_tmp1 = hdr;
2814
2815 do
2816 {
2817 /* data structure type variable = (data structure type, file name, header of the tdList) */
2818 #ifdef REMOVED
2819 if (flag == 1)
2820 {
2821 ele1 = TDLIST_OBJECT_BASE(tdsaPortContext_t, FreeLink, hdr_tmp1);
2822 }
2823 else
2824 {
2825 ele1 = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, hdr_tmp1);
2826 }
2827 TI_DBG6(("blist ele %d\n", ele1->id));
2828 #endif
2829
2830 hdr_tmp1 = hdr_tmp1->blink;
2831 } while (hdr_tmp1 != hdr);
2832 }
2833
2834
2835 /** hexidecimal dump */
2836 void tdhexdump(const char *ptitle, bit8 *pbuf, int len)
2837 {
2838 int i;
2839 TI_DBG2(("%s - hexdump(len=%d):\n", ptitle, (int)len));
2840 if (!pbuf)
2841 {
2842 TI_DBG1(("pbuf is NULL\n"));
2843 return;
2844 }
2845 for (i = 0; i < len; )
2846 {
2847 if (len - i > 4)
2848 {
2849 TI_DBG2((" 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", pbuf[i], pbuf[i+1], pbuf[i+2], pbuf[i+3]));
2850 i += 4;
2851 }
2852 else
2853 {
2854 TI_DBG2((" 0x%02x,", pbuf[i]));
2855 i++;
2856 }
2857 }
2858 TI_DBG2(("\n"));
2859 }
2860
2861 void
2862 tdsaSingleThreadedEnter(tiRoot_t *ptiRoot, bit32 queueId)
2863 {
2864 tdsaRoot_t * tiroot = agNULL;
2865 bit32 offset = 0;
2866 TD_ASSERT(ptiRoot,"ptiRoot");
2867 tiroot = ptiRoot->tdData;
2868
2869 offset = tiroot->tdsaAllShared.MaxNumLLLocks + tiroot->tdsaAllShared.MaxNumOSLocks;
2870
2871 ostiSingleThreadedEnter(ptiRoot, queueId + offset);
2872 }
2873
2874 void
2875 tdsaSingleThreadedLeave(tiRoot_t *ptiRoot, bit32 queueId)
2876 {
2877 tdsaRoot_t * tiroot = agNULL;
2878 bit32 offset = 0;
2879
2880 TD_ASSERT(ptiRoot,"ptiRoot");
2881 tiroot = ptiRoot->tdData;
2882
2883 offset = tiroot->tdsaAllShared.MaxNumLLLocks + tiroot->tdsaAllShared.MaxNumOSLocks;
2884
2885 ostiSingleThreadedLeave(ptiRoot, queueId + offset);
2886 }
2887
2888 #ifdef PERF_COUNT
2889 void
2890 tdsaEnter(tiRoot_t *ptiRoot, int io)
2891 {
2892 ostiEnter(ptiRoot, 1, io);
2893 }
2894
2895 void
2896 tdsaLeave(tiRoot_t *ptiRoot, int io)
2897 {
2898 ostiLeave(ptiRoot, 1, io);
2899 }
2900 #endif
2901
Cache object: d247b79a6e21977a72c6c1eee1ad4611
|