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