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