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