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