1285242Sachim/*******************************************************************************
2285242Sachim*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3285242Sachim*
4285242Sachim*Redistribution and use in source and binary forms, with or without modification, are permitted provided
5285242Sachim*that the following conditions are met:
6285242Sachim*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7285242Sachim*following disclaimer.
8285242Sachim*2. Redistributions in binary form must reproduce the above copyright notice,
9285242Sachim*this list of conditions and the following disclaimer in the documentation and/or other materials provided
10285242Sachim*with the distribution.
11285242Sachim*
12285242Sachim*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13285242Sachim*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14285242Sachim*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15285242Sachim*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16285242Sachim*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17285242Sachim*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18285242Sachim*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19285242Sachim*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20285242Sachim*
21285242Sachim* $FreeBSD$
22285242Sachim*
23285242Sachim*******************************************************************************/
24285242Sachim/******************************************************************************
25285242SachimPMC-Sierra TISA Initiator Device Driver for Linux 2.x.x.
26285242Sachim
27285242SachimModule Name:
28285242Sachim  osapi.c
29285242SachimAbstract:
30285242Sachim  Linux iSCSI/FC Initiator driver module itsdk required OS functions
31285242SachimEnvironment:
32285242Sachim  Part of oslayer module, Kernel or loadable module
33285242Sachim
34285242Sachim*******************************************************************************
35285242SachimostiInitiatorEvent()
36285242Sachim
37285242SachimPurpose:
38285242Sachim  TI layer call back to OSlayer to inform events
39285242SachimParameters:
40285242Sachim  tiRoot_t *ptiRoot (IN)               Pointer to HBA data structure
41285242Sachim  tiDeviceHandle_t *ptiDevHandle (IN)  Pointer to device handle
42285242Sachim  tiIntrEvenType_t evenType (IN)       Event type
43285242Sachim  tiIntrEventStatus_t evetStatus (IN)  Event status
44285242Sachim  void *parm (IN)                      pointer to even specific data
45285242SachimReturn:
46285242SachimNote:
47285242Sachim  TBD, further event process required.
48285242Sachim******************************************************************************/
49285242Sachimvoid ostiInitiatorEvent( tiRoot_t *ptiRoot,
50285242Sachim                         tiPortalContext_t *ptiPortalContext,
51285242Sachim                         tiDeviceHandle_t *ptiDevHandle,
52285242Sachim                         tiIntrEventType_t eventType,
53285242Sachim                         U32 eventStatus,
54285242Sachim                         void *parm )
55285242Sachim{
56285242Sachim  ag_portal_data_t *pPortalData;
57285242Sachim  ag_portal_info_t *pPortalInfo;
58285242Sachim  struct agtiapi_softc *pCard = TIROOT_TO_CARD( ptiRoot );
59285242Sachim  ccb_t     *pccb;
60285242Sachim  ccb_t     *pTMccb;
61285242Sachim  ccb_t     *ccbIO;
62285242Sachim
63285242Sachim#ifdef  AGTIAPI_EVENT_LOG
64285242Sachim  AGTIAPI_PRINTK("Initiator Event:\n");
65285242Sachim  AGTIAPI_PRINTK("DevHandle %p, eventType 0x%x, eventStatus 0x%x\n",
66285242Sachim                 ptiDevHandle, eventType, eventStatus);
67285242Sachim  AGTIAPI_PRINTK("Parameter: %s\n", (char *)parm);
68285242Sachim#endif
69285242Sachim
70285242Sachim  AGTIAPI_PRINTK("ostiInitiatorEvent: eventType 0x%x eventStatus 0x%x\n", eventType, eventStatus);
71285242Sachim
72285242Sachim  switch (eventType)
73285242Sachim  {
74285242Sachim  case tiIntrEventTypeCnxError:
75285242Sachim       if (eventStatus == tiCnxUp)
76285242Sachim       {
77285242Sachim         AGTIAPI_PRINTK("tiIntrEventTypeCnxError - tiCnxUp!\n");
78285242Sachim       }
79285242Sachim       if (eventStatus == tiCnxDown)
80285242Sachim       {
81285242Sachim         AGTIAPI_PRINTK("tiIntrEventTypeCnxError - tiCnxDown!\n");
82285242Sachim       }
83285242Sachim       break;
84285242Sachim  case tiIntrEventTypeDiscovery:
85285242Sachim       pPortalData = PORTAL_CONTEXT_TO_PORTALDATA(ptiPortalContext);
86285242Sachim       pCard->flags |= AGTIAPI_CB_DONE;
87285242Sachim       if (eventStatus == tiDiscOK)
88285242Sachim       {
89285242Sachim         AGTIAPI_PRINTK("eventStatus - tiDiscOK\n");
90285242Sachim         AGTIAPI_PRINTK("ostiInitiatorEvent: pcard %d eventStatus - tiDiscOK\n", pCard->cardNo );
91285242Sachim         PORTAL_STATUS(pPortalData) |= AGTIAPI_DISC_COMPLETE;
92285242Sachim#ifndef HOTPLUG_SUPPORT
93285242Sachim         if (!(pCard->flags & AGTIAPI_INIT_TIME))
94285242Sachim#else
95285242Sachim         if (TRUE)
96285242Sachim#endif
97285242Sachim         {
98285242Sachim
99285242Sachim           agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo,
100285242Sachim                                tiIntrEventTypeDiscovery, tiDiscOK);
101285242Sachim           PORTAL_STATUS(pPortalData) |=
102285242Sachim             (AGTIAPI_DISC_DONE | AGTIAPI_PORT_LINK_UP);
103285242Sachim         }
104285242Sachim         /* Trigger CheckIOTimeout */
105285242Sachim         callout_reset(&pCard->IO_timer, 20*hz, agtiapi_CheckIOTimeout, pCard);
106285242Sachim       }
107285242Sachim       else if (eventStatus == tiDiscFailed)
108285242Sachim       {
109285242Sachim         AGTIAPI_PRINTK("eventStatus - tiDiscFailed\n");
110285242Sachim         agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo,
111285242Sachim                              tiIntrEventTypeDiscovery, tiDiscFailed);
112285242Sachim         PORTAL_STATUS(pPortalData) &= ~AGTIAPI_DISC_DONE;
113285242Sachim       }
114285242Sachim       AGTIAPI_PRINTK("tiIntrEventTypeDiscovery - portal %p, status 0x%x\n",
115285242Sachim         pPortalData,
116285242Sachim         PORTAL_STATUS(pPortalData));
117285242Sachim       break;
118285242Sachim  case tiIntrEventTypeDeviceChange:
119285242Sachim       AGTIAPI_PRINTK("tiIntrEventTypeDeviceChange - portal %p es %d\n",
120285242Sachim                      ptiPortalContext->osData, eventStatus);
121285242Sachim       pPortalData = PORTAL_CONTEXT_TO_PORTALDATA(ptiPortalContext);
122285242Sachim       pPortalInfo = &pPortalData->portalInfo;
123285242Sachim#ifndef HOTPLUG_SUPPORT
124285242Sachim       if (!(pCard->flags & AGTIAPI_INIT_TIME))
125285242Sachim#else
126285242Sachim       if (TRUE)
127285242Sachim#endif
128285242Sachim       {
129285242Sachim         agtiapi_GetDevHandle(pCard, pPortalInfo, tiIntrEventTypeDeviceChange,
130285242Sachim                              eventStatus);
131285242Sachim//         agtiapi_StartIO(pCard);
132285242Sachim       }
133285242Sachim       break;
134285242Sachim  case tiIntrEventTypeTransportRecovery:
135285242Sachim       AGTIAPI_PRINTK("tiIntrEventTypeTransportRecovery!\n");
136285242Sachim       break;
137285242Sachim  case tiIntrEventTypeTaskManagement:
138285242Sachim       AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement!\n");
139285242Sachim       pccb = (pccb_t)((tiIORequest_t *)parm)->osData;
140285242Sachim       if (pccb->flags & TASK_TIMEOUT)
141285242Sachim       {
142285242Sachim         AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: TM timeout!\n");
143285242Sachim         agtiapi_FreeTMCCB(pCard, pccb);
144285242Sachim       }
145285242Sachim       else
146285242Sachim       {
147285242Sachim         pccb->flags |= AGTIAPI_CB_DONE;
148285242Sachim         if (eventStatus == tiTMOK)
149285242Sachim         {
150285242Sachim           pccb->flags |= TASK_SUCCESS;
151285242Sachim           AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: pTMccb %p flag %x \n",
152285242Sachim                          pccb, pccb->flags);
153285242Sachim
154285242Sachim           /* Incase of TM_DEV_RESET, issue LocalAbort to abort pending IO */
155285242Sachim           if (pccb->flags & DEV_RESET)
156285242Sachim           {
157285242Sachim               AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: Target Reset\n");
158285242Sachim               ccbIO = pccb->pccbIO;
159285242Sachim               AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: IO to be aborted locally %p flag %x \n",
160285242Sachim                          ccbIO, ccbIO->flags);
161285242Sachim               if (ccbIO->startTime == 0) /* IO has been completed. No local abort */
162285242Sachim               {
163285242Sachim               }
164285242Sachim               else if (tiINIIOAbort(&pCard->tiRoot, &ccbIO->tiIORequest) != tiSuccess)
165285242Sachim               {
166285242Sachim                   AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: Local Abort failed\n");
167285242Sachim                   /* TODO: call Soft reset here */
168285242Sachim               }
169285242Sachim           }
170285242Sachim          else if (eventStatus == tiTMFailed)
171285242Sachim          {
172285242Sachim               ccbIO = pccb->pccbIO;
173285242Sachim               if (ccbIO->startTime == 0) /* IO has been completed. */
174285242Sachim               {
175299081Spfg                   AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: TM failed because IO has been completed! pTMccb %p flag %x \n",
176285242Sachim                                   pccb, pccb->flags);
177285242Sachim               }
178285242Sachim               else
179285242Sachim               {
180285242Sachim              AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: TM failed! pTMccb %p flag %x \n",
181285242Sachim                             pccb, pccb->flags);
182285242Sachim               /* TODO:*/
183285242Sachim              /* if TM_ABORT_TASK, call TM_TARGET_RESET */
184285242Sachim              /* if TM_TARGET_RESET, call Soft_Reset */
185285242Sachim               }
186285242Sachim          }
187285242Sachim          /* Free TM_DEV_RESET ccb */
188285242Sachim          agtiapi_FreeTMCCB(pCard, pccb);
189285242Sachim         }
190285242Sachim        }
191285242Sachim       break;
192285242Sachim  case tiIntrEventTypeLocalAbort:
193285242Sachim        AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort!\n");
194285242Sachim        pccb = (pccb_t)((tiIORequest_t *)parm)->osData;
195285242Sachim        pccb->flags |= AGTIAPI_CB_DONE;
196285242Sachim        if (eventStatus == tiAbortOK)
197285242Sachim        {
198285242Sachim            AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: taskTag pccb %p flag %x \n",
199285242Sachim                           pccb, pccb->flags);
200285242Sachim            /* If this was LocalAbort for TM ABORT_TASK, issue TM_DEV_RESET */
201285242Sachim            if (pccb->flags & TASK_MANAGEMENT)
202285242Sachim            {
203285242Sachim                if ((pTMccb = agtiapi_GetCCB(pCard)) == NULL)
204285242Sachim                {
205285242Sachim                    AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: TM resource unavailable!\n");
206285242Sachim                    /* TODO: SoftReset here? */
207285242Sachim                }
208285242Sachim                pTMccb->pmcsc = pCard;
209285242Sachim                pTMccb->targetId = pccb->targetId;
210285242Sachim                pTMccb->devHandle = pccb->devHandle;
211285242Sachim
212285242Sachim                /* save pending io to issue local abort at Task mgmt CB */
213285242Sachim                pTMccb->pccbIO = pccb->pccbIO;
214285242Sachim                pTMccb->flags &= ~(TASK_SUCCESS | ACTIVE);
215285242Sachim                pTMccb->flags |= DEV_RESET;
216285242Sachim                if (tiINITaskManagement(&pCard->tiRoot,
217285242Sachim                                        pccb->devHandle,
218285242Sachim                                        AG_TARGET_WARM_RESET,
219285242Sachim                                        &pccb->tiSuperScsiRequest.scsiCmnd.lun,
220285242Sachim                                        &pccb->tiIORequest,
221285242Sachim                                        &pTMccb->tiIORequest)
222285242Sachim                    == tiSuccess)
223285242Sachim                {
224285242Sachim                    AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: TM_TARGET_RESET request success ccb %p, pTMccb %p\n",
225285242Sachim                                   pccb, pTMccb);
226285242Sachim                    pTMccb->startTime = ticks;
227285242Sachim                }
228285242Sachim                else
229285242Sachim                {
230285242Sachim                    AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: TM_TARGET_RESET request failed ccb %p, pTMccb %p\n",
231285242Sachim                                   pccb, pTMccb);
232285242Sachim                    agtiapi_FreeTMCCB(pCard, pTMccb);
233285242Sachim                    /* TODO: SoftReset here? */
234285242Sachim                }
235285242Sachim                /* Free ABORT_TASK TM ccb */
236285242Sachim                agtiapi_FreeTMCCB(pCard, pccb);
237285242Sachim            }
238285242Sachim        }
239285242Sachim        else if (eventStatus == tiAbortFailed)
240285242Sachim        {
241285242Sachim            /* TODO: */
242285242Sachim            /* If TM_ABORT_TASK fails, issue TM_DEV_RESET */
243285242Sachim            /* if TM_DEV_RESET fails, issue Soft_Reset */
244285242Sachim            AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: Abort Failed pccb %p\n", pccb);
245285242Sachim       }
246285242Sachim       break;
247285242Sachim  default:
248285242Sachim       AGTIAPI_PRINTK("tiIntrEventType default!\n");
249285242Sachim       break;
250285242Sachim  }
251285242Sachim}
252285242Sachim
253285242Sachim
254285242Sachim/******************************************************************************
255285242SachimostiInitiatorIOCompleted()
256285242Sachim
257285242SachimPurpose:
258285242Sachim  IO request completion call back
259285242SachimParameters:
260285242Sachim  tiRoot_t *ptiRoot (IN)               Pointer to the HBA tiRoot
261285242Sachim  tiIORequest_t *ptiIORequest (IN)     Pointer to the tiIORequest structure
262285242Sachim  tiIOStatus_t IOStatus (IN)           I/O complated status
263285242Sachim  U32 statusDetail (IN)                Additional information on status
264285242Sachim  tiSenseData_t *pSensedata (IN)       Sense data buffer pointer
265285242Sachim  U32 context (IN)                     Interrupt dealing context
266285242SachimReturns:
267285242SachimNote:
268285242Sachim******************************************************************************/
269285242Sachimvoid
270285242SachimostiInitiatorIOCompleted(tiRoot_t      *ptiRoot,
271285242Sachim                               tiIORequest_t *ptiIORequest,
272285242Sachim                               tiIOStatus_t  IOStatus,
273285242Sachim                               U32           statusDetail,
274285242Sachim                               tiSenseData_t *pSenseData,
275285242Sachim                               U32           context )
276285242Sachim{
277285242Sachim  struct agtiapi_softc  *pCard;
278285242Sachim  ccb_t      *pccb;
279285242Sachim
280285242Sachim  pCard = TIROOT_TO_CARD(ptiRoot);
281285242Sachim  pccb = (ccb_t *)ptiIORequest->osData;
282285242Sachim
283285242Sachim  AGTIAPI_IO( "ostiInitiatorIOCompleted: start\n" );
284285242Sachim
285285242Sachim  if (IOStatus == tiIODifError)
286285242Sachim  {
287285242Sachim    return;
288285242Sachim  }
289285242Sachim  OSTI_OUT_ENTER(ptiRoot);
290285242Sachim
291285242Sachim  pccb->ccbStatus  = (U16)IOStatus;
292285242Sachim  pccb->scsiStatus = statusDetail;
293285242Sachim
294285242Sachim  if ((IOStatus == tiIOSuccess) && (statusDetail == SCSI_CHECK_CONDITION))
295285242Sachim  {
296285242Sachim    if (pSenseData == (tiSenseData_t *)agNULL)
297285242Sachim    {
298285242Sachim      AGTIAPI_PRINTK( "ostiInitiatorIOCompleted: "
299285242Sachim                      "check condition without sense data!\n" );
300285242Sachim    }
301285242Sachim    else
302285242Sachim    {
303285242Sachim      union ccb *ccb = pccb->ccb;
304285242Sachim      struct ccb_scsiio *csio = &ccb->csio;
305285242Sachim      int sense_len = 0;
306285242Sachim      if (pccb->senseLen > pSenseData->senseLen)
307285242Sachim      {
308285242Sachim        csio->sense_resid = pccb->senseLen - pSenseData->senseLen;
309285242Sachim      }
310285242Sachim      else
311285242Sachim      {
312285242Sachim        csio->sense_resid = 0;
313285242Sachim      }
314285242Sachim      sense_len = MIN( pSenseData->senseLen,
315285242Sachim                       pccb->senseLen - csio->sense_resid );
316295861Spfg      bzero(&csio->sense_data, sizeof(csio->sense_data));
317285242Sachim      AGTIAPI_PRINTK("ostiInitiatorIOCompleted: check condition copying\n");
318285242Sachim      memcpy( (void *)pccb->pSenseData,
319285242Sachim              pSenseData->senseData,
320285242Sachim              sense_len );
321285242Sachim      agtiapi_hexdump( "ostiInitiatorIOCompleted check condition",
322285242Sachim                       (bit8 *)&csio->sense_data, sense_len );
323285242Sachim    }
324285242Sachim  }
325285242Sachim  if ((IOStatus == tiIOFailed) && (statusDetail == tiDetailAborted))
326285242Sachim  {
327285242Sachim    AGTIAPI_PRINTK("ostiInitiatorIOCompleted - aborted ccb %p, flag %x\n",
328285242Sachim                   pccb, pccb->flags);
329285242Sachim    /* indicate aborted IO completion */
330285242Sachim    pccb->startTime = 0;
331285242Sachim    agtiapi_Done(pCard, pccb);
332285242Sachim  }
333285242Sachim  else
334285242Sachim  {
335285242Sachim#ifdef AGTIAPI_SA
336285242Sachim    /*
337285242Sachim     * SAS no data command does not trigger interrupt.
338285242Sachim     * Command is completed in tdlayer and IO completion is called directly.
339285242Sachim     * The completed IO therefore is not post processed.
340285242Sachim     * Flag is raised and TDTimer will check and process IO for SAS.
341285242Sachim     * This is a temporary solution. - Eddie, 07-17-2006
342285242Sachim     */
343285242Sachim    pCard->flags |= AGTIAPI_FLAG_UP;
344285242Sachim#endif
345285242Sachim    pccb->flags  |= REQ_DONE;
346285242Sachim    agtiapi_QueueCCB(pCard, &pCard->ccbDoneHead, &pCard->ccbDoneTail
347285242Sachim                     AG_CARD_LOCAL_LOCK(&pCard->doneLock), pccb);
348285242Sachim  }
349285242Sachim  OSTI_OUT_LEAVE(ptiRoot);
350285242Sachim  return;
351285242Sachim}
352285242Sachim#ifdef HIALEAH_ENCRYPTION
353285242SachimosGLOBAL void
354285242SachimostidisableEncryption(tiRoot_t *ptiRoot)
355285242Sachim{
356285242Sachim  struct agtiapi_softc  *pCard;
357285242Sachim  pCard = TIROOT_TO_CARD(ptiRoot);
358285242Sachim  pCard->encrypt=agFALSE;
359285242Sachim}
360285242Sachim#endif
361285242Sachim/* device Handle */
362285242SachimosGLOBAL //FORCEINLINE
363285242SachimtiDeviceHandle_t*
364285242SachimostiGetDevHandleFromSasAddr(
365285242Sachim  tiRoot_t    *root,
366285242Sachim  unsigned char *sas_addr
367285242Sachim)
368285242Sachim{
369285242Sachim  int i;
370285242Sachim  unsigned long x;
371285242Sachim
372285242Sachim  ag_portal_data_t           *pPortal = NULL;
373285242Sachim  tiDeviceHandle_t *devHandle = NULL;
374285242Sachim  struct agtiapi_softc *pCard = TIROOT_TO_CARD(root);
375285242Sachim  bit8 sas_addr_hi[4], sas_addr_lo[4];
376285242Sachim
377285242Sachim
378285242Sachim  for(i=0; i<4; i++)
379285242Sachim  {
380285242Sachim  	sas_addr_hi[i] = sas_addr[3-i];
381285242Sachim  }
382285242Sachim
383285242Sachim  for(i=0; i<4; i++)
384285242Sachim  {
385285242Sachim  	sas_addr_lo[i] = sas_addr[7-i];
386285242Sachim  }
387285242Sachim
388285242Sachim    /* Retrieve the handles for each portal */
389285242Sachim  for (x=0; x < pCard->portCount; x++)
390285242Sachim  {
391285242Sachim    pPortal = &pCard->pPortalData[x];
392285242Sachim    devHandle = tiINIGetExpDeviceHandleBySasAddress(&pCard->tiRoot,
393285242Sachim                    &pPortal->portalInfo.tiPortalContext,
394285242Sachim					*(bit32*)sas_addr_hi,
395285242Sachim					*(bit32*)sas_addr_lo,
396285242Sachim					(bit32)1024/*gMaxTargets*/);
397285242Sachim	if(devHandle != NULL)
398285242Sachim		break;
399285242Sachim  }
400285242Sachim  return devHandle;
401285242Sachim
402285242Sachim  return NULL;
403285242Sachim}
404285242Sachim/******************************************************************************
405285242SachimostiInitiatorSMPCompleted()
406285242Sachim
407285242SachimPurpose:
408285242Sachim  IO request completion call back
409285242SachimParameters:
410285242Sachim  tiRoot_t *ptiRoot (IN)               Pointer to the HBA tiRoot
411285242Sachim  tiIORequest_t *ptiSMPRequest (IN)    Pointer to the SMP request structure
412285242Sachim  tiIOStatus_t IOStatus (IN)           I/O complated status
413285242Sachim  U32 tiSMPInfoLen (IN)                Number of bytes of response frame len
414285242Sachim  tiFrameHandle    (IN)                Handle that referes to response frame
415285242Sachim  U32 context (IN)                     Interrupt dealing context
416285242SachimReturns:
417285242SachimNote:
418285242Sachim******************************************************************************/
419285242Sachimvoid
420285242SachimostiInitiatorSMPCompleted(tiRoot_t      *ptiRoot,
421285242Sachim                          tiIORequest_t *ptiSMPRequest,
422285242Sachim                          tiSMPStatus_t  smpStatus,
423285242Sachim                          bit32          tiSMPInfoLen,
424285242Sachim                          void           *tiFrameHandle,
425285242Sachim                          bit32          context)
426285242Sachim{
427285242Sachim  struct agtiapi_softc  *pCard;
428285242Sachim  ccb_t      *pccb;
429285242Sachim  pCard = TIROOT_TO_CARD(ptiRoot);
430285242Sachim  pccb = (ccb_t *)ptiSMPRequest->osData;
431285242Sachim
432285242Sachim  AGTIAPI_PRINTK("ostiInitiatorSMPCompleted: start\n");
433285242Sachim
434285242Sachim  OSTI_OUT_ENTER(ptiRoot);
435285242Sachim  pccb->ccbStatus  = (U16)smpStatus;
436285242Sachim  if(smpStatus != tiSMPSuccess)
437285242Sachim  {
438285242Sachim    AGTIAPI_PRINTK("ostiInitiatorSMPCompleted: SMP Error\n");
439285242Sachim  }
440285242Sachim  else
441285242Sachim  {
442285242Sachim    union ccb *ccb = pccb->ccb;
443285242Sachim    struct ccb_smpio *csmpio = &ccb->smpio;
444285242Sachim    memcpy(csmpio->smp_response, tiFrameHandle, tiSMPInfoLen);
445285242Sachim    csmpio->smp_response_len = tiSMPInfoLen;
446299081Spfg    agtiapi_hexdump("ostiInitiatorSMPCompleted: Response Payload in CAM", (bit8 *)csmpio->smp_response, csmpio->smp_response_len);
447285242Sachim  }
448285242Sachim  pccb->flags  |= REQ_DONE;
449285242Sachim  agtiapi_QueueCCB(pCard, &pCard->smpDoneHead, &pCard->smpDoneTail
450285242Sachim                     AG_CARD_LOCAL_LOCK(&pCard->doneSMPLock), pccb);
451285242Sachim  AGTIAPI_PRINTK("ostiInitiatorSMPCompleted: Done\n");
452285242Sachim  OSTI_OUT_LEAVE(ptiRoot);
453285242Sachim
454285242Sachim  return;
455285242Sachim}
456285242Sachim
457285242Sachim#ifdef FAST_IO_TEST
458285242Sachimvoid
459285242Sachimosti_FastIOCb(tiRoot_t      *ptiRoot,
460285242Sachim              void          *arg,
461285242Sachim              tiIOStatus_t  IOStatus,
462285242Sachim              U32           statusDetail)
463285242Sachim{
464285242Sachim  ccb_t     *pccb = (ccb_t*)arg;
465285242Sachim  ag_card_t *pCard;
466285242Sachim
467285242Sachim  static int callNum = 0;
468285242Sachim
469285242Sachim  callNum++;
470285242Sachim
471285242Sachim  BUG_ON(!pccb);
472285242Sachim
473285242Sachim  if ((callNum % CMDS_PER_IO_DUP) != 0)
474285242Sachim  {
475285242Sachim    goto err;
476285242Sachim  }
477285242Sachim
478285242Sachim  pccb->ccbStatus = IOStatus;
479285242Sachim  pccb->scsiStatus = statusDetail;
480285242Sachim
481285242Sachim  /* pccb->pSenseData is copied already */
482285242Sachim
483285242Sachim  if (pccb->flags & AGTIAPI_ABORT)
484285242Sachim  {
485285242Sachim    AGTIAPI_PRINTK("agtiapi_SuperIOCb: aborted ccb %p, flag %x\n",
486285242Sachim                   pccb, pccb->flags);
487285242Sachim    pccb->startTime = 0;     /* indicate aborted IO completion */
488285242Sachim    BUG_ON(1);
489285242Sachim    goto err;
490285242Sachim  }
491285242Sachim  pCard = TIROOT_TO_CARD(ptiRoot);
492285242Sachim  pccb->flags |= REQ_DONE;
493285242Sachim  agtiapi_QueueCCB(pCard, &pCard->ccbDoneHead, &pCard->ccbDoneTail
494285242Sachim                   AG_CARD_LOCAL_LOCK(&pCard->doneLock), pccb);
495285242Sachimerr:
496285242Sachim  return;
497285242Sachim} /* osti_FastIOCb */
498285242Sachim#endif
499285242Sachim
500285242Sachim
501285242Sachim/******************************************************************************
502285242SachimostiSingleThreadedEnter()
503285242Sachim
504285242SachimPurpose:
505285242Sachim  Critical region code excution protection.
506285242SachimParameters:
507285242Sachim  tiRoot_t *ptiRoot (IN)  Pointer to tiRoot data structure
508285242Sachim  U32 queueId (IN)     spinlock Id
509285242SachimReturns:
510285242SachimNote:
511285242Sachim  Lock is held by oslayer.
512285242Sachim******************************************************************************/
513285242Sachimvoid
514285242SachimostiSingleThreadedEnter(tiRoot_t *ptiRoot, U32 queueId)
515285242Sachim{
516285242Sachim  struct agtiapi_softc *pCard = TIROOT_TO_CARD(ptiRoot);
517285242Sachim  mtx_lock( &pCard->STLock[queueId] ); // review: need irq save? ##
518285242Sachim}
519285242Sachim
520285242Sachim
521285242Sachim/******************************************************************************
522285242SachimostiSingleThreadedLeave()
523285242Sachim
524285242SachimPurpose:
525285242Sachim  Restore multi-threading environment.
526285242SachimParameters:
527285242Sachim  tiRoot_t *ptiRoot (IN)  Pointer to the tiRoot data structure
528285242Sachim  U32 queueId (IN)     spinlock Id
529285242SachimReturns:
530285242SachimNote:
531285242Sachim  Lock is held by oslayer.
532285242Sachim******************************************************************************/
533285242Sachimvoid
534285242SachimostiSingleThreadedLeave(tiRoot_t *ptiRoot, U32 queueId)
535285242Sachim{
536285242Sachim  struct agtiapi_softc *pCard = TIROOT_TO_CARD(ptiRoot);
537285242Sachim  mtx_unlock( &pCard->STLock[queueId] ); // review: need irq restore? ##
538285242Sachim}
539285242Sachim
540285242Sachim
541285242SachimosGLOBAL tiDeviceHandle_t*
542285242SachimostiMapToDevHandle(tiRoot_t  *root,
543285242Sachim                          bit8      pathId,
544285242Sachim                          bit8      targetId,
545285242Sachim                          bit8      LUN
546285242Sachim                          )
547285242Sachim{
548285242Sachim  tiDeviceHandle_t    *dev      = NULL;
549285242Sachim  struct agtiapi_softc          *pCard;
550285242Sachim  bit32               offset;
551285242Sachim
552285242Sachim  pCard = TIROOT_TO_CARD(root);
553285242Sachim
554285242Sachim  offset = pathId * pCard->tgtCount + targetId;
555285242Sachim
556285242Sachim  if (offset > (pCard->tgtCount - 1) )
557285242Sachim  {
558285242Sachim    dev = NULL;
559285242Sachim  }
560285242Sachim  else
561285242Sachim  {
562285242Sachim    dev = pCard->pDevList[offset].pDevHandle;
563285242Sachim  }
564285242Sachim
565285242Sachim  return dev;
566285242Sachim}
567285242Sachim
568285242Sachim
569285242Sachim
570285242Sachim#ifdef PERF_COUNT
571285242Sachim
572285242Sachim#ifdef AGTIAPI_LOCAL_LOCK
573285242Sachim#define OSTI_SPIN_LOCK(lock)              spin_lock(lock)
574285242Sachim#define OSTI_SPIN_UNLOCK(lock)            spin_unlock(lock)
575285242Sachim#else
576285242Sachim#define OSTI_SPIN_LOCK(lock)
577285242Sachim#define OSTI_SPIN_UNLOCK(lock)
578285242Sachim#endif
579285242Sachim
580285242Sachim
581285242Sachimvoid
582285242SachimostiEnter(tiRoot_t *ptiRoot, U32 layer, int io)
583285242Sachim{
584285242Sachim  ag_card_t *pCard = ((ag_card_info_t*)ptiRoot->osData)->pCard;
585285242Sachim  int ini = ((pCard->flags & AGTIAPI_INIT_TIME) == AGTIAPI_INIT_TIME);
586285242Sachim
587285242Sachim  BUG_ON((io != 0 && io != 1) || (layer != 0 && layer != 1 && layer != 2));
588285242Sachim  if (!ini)
589285242Sachim  {
590285242Sachim    unsigned long long cycles = get_cycles();
591285242Sachim
592285242Sachim    OSTI_SPIN_LOCK(&pCard->latLock);
593285242Sachim    BUG_ON(pCard->callLevel[io] >= sizeof(pCard->layer[0]) /
594285242Sachim                                     sizeof(pCard->layer[0][0]));
595285242Sachim    if (pCard->callLevel[io] > 0)
596285242Sachim    {
597285242Sachim      unsigned int prev_layer = pCard->layer[io][pCard->callLevel[io] - 1];
598285242Sachim
599285242Sachim      pCard->totalCycles[io][prev_layer] += cycles -
600285242Sachim                                             pCard->enterCycles[io][prev_layer];
601285242Sachim    }
602285242Sachim    pCard->enterCycles[io][layer] = cycles;
603285242Sachim    pCard->layer[io][pCard->callLevel[io]] = layer;
604285242Sachim    pCard->callLevel[io]++;
605285242Sachim    OSTI_SPIN_UNLOCK(&pCard->latLock);
606285242Sachim  }
607285242Sachim}
608285242Sachim
609285242Sachimvoid
610285242SachimostiLeave(tiRoot_t *ptiRoot, U32 layer, int io)
611285242Sachim{
612285242Sachim  ag_card_t *pCard = ((ag_card_info_t*)ptiRoot->osData)->pCard;
613285242Sachim  int ini = ((pCard->flags & AGTIAPI_INIT_TIME) == AGTIAPI_INIT_TIME);
614285242Sachim
615285242Sachim  BUG_ON((io != 0 && io != 1) || (layer != 0 && layer != 1 && layer != 2));
616285242Sachim  if (!ini)
617285242Sachim  {
618285242Sachim    unsigned long long cycles = get_cycles();
619285242Sachim
620285242Sachim    OSTI_SPIN_LOCK(&pCard->latLock);
621285242Sachim    pCard->callLevel[io]--;
622285242Sachim
623285242Sachim    BUG_ON(pCard->callLevel[io] < 0);
624285242Sachim    BUG_ON(pCard->layer[io][pCard->callLevel[io]] != layer);
625285242Sachim
626285242Sachim    pCard->totalCycles[io][layer] += cycles - pCard->enterCycles[io][layer];
627285242Sachim    if (pCard->callLevel[io] > 0)
628285242Sachim      pCard->enterCycles[io][pCard->layer[io][pCard->callLevel[io] - 1]] =
629285242Sachim        cycles;
630285242Sachim    OSTI_SPIN_UNLOCK(&pCard->latLock);
631285242Sachim  }
632285242Sachim}
633285242Sachim#endif
634285242Sachim
635285242Sachim
636285242Sachim
637285242SachimosGLOBAL FORCEINLINE bit8
638285242SachimostiBitScanForward(
639285242Sachim                  tiRoot_t   *root,
640285242Sachim                  bit32      *Index,
641285242Sachim                  bit32       Mask
642285242Sachim                  )
643285242Sachim{
644285242Sachim  return 1;
645285242Sachim
646285242Sachim}
647285242Sachim
648285242Sachim#ifdef REMOVED
649285242SachimosGLOBAL sbit32
650285242SachimostiAtomicIncrement(
651285242Sachim                   tiRoot_t        *root,
652285242Sachim                   sbit32 volatile *Addend
653285242Sachim                   )
654285242Sachim{
655285242Sachim  return 1;
656285242Sachim
657285242Sachim}
658285242Sachim
659285242SachimosGLOBAL sbit32
660285242SachimostiAtomicDecrement(
661285242Sachim                   tiRoot_t        *root,
662285242Sachim                   sbit32 volatile *Addend
663285242Sachim                   )
664285242Sachim{
665285242Sachim
666285242Sachim  return 1;
667285242Sachim
668285242Sachim}
669285242Sachim
670285242SachimosGLOBAL sbit32
671285242SachimostiAtomicBitClear(
672285242Sachim                 tiRoot_t         *root,
673285242Sachim                 sbit32 volatile  *Destination,
674285242Sachim                 sbit32            Value
675285242Sachim                 )
676285242Sachim{
677285242Sachim
678285242Sachim  return 0;
679285242Sachim
680285242Sachim}
681285242Sachim
682285242SachimosGLOBAL sbit32
683285242SachimostiAtomicBitSet(
684285242Sachim                tiRoot_t         *root,
685285242Sachim                sbit32 volatile  *Destination,
686285242Sachim                sbit32            Value
687285242Sachim                )
688285242Sachim{
689285242Sachim  return 0;
690285242Sachim
691285242Sachim  /*
692285242Sachim   set_bit(Value, (volatile unsigned long *)Destination);
693285242Sachim   return 0;
694285242Sachim  */
695285242Sachim}
696285242Sachim
697285242SachimosGLOBAL sbit32
698285242SachimostiAtomicExchange(
699285242Sachim                   tiRoot_t        *root,
700285242Sachim                   sbit32 volatile *Target,
701285242Sachim                   sbit32           Value
702285242Sachim                   )
703285242Sachim{
704285242Sachim  return 0;
705285242Sachim
706285242Sachim}
707285242Sachim#endif
708285242Sachim
709285242SachimosGLOBAL FORCEINLINE sbit32
710285242SachimostiInterlockedExchange(
711285242Sachim                       tiRoot_t        *root,
712285242Sachim                       sbit32 volatile *Target,
713285242Sachim                       sbit32           Value
714285242Sachim                       )
715285242Sachim{
716285242Sachim  return 0;
717285242Sachim}
718285242Sachim
719285242SachimosGLOBAL FORCEINLINE sbit32
720285242SachimostiInterlockedIncrement(
721285242Sachim                       tiRoot_t        *root,
722285242Sachim                       sbit32 volatile *Addend
723285242Sachim                       )
724285242Sachim{
725285242Sachim  return 0;
726285242Sachim}
727285242Sachim
728285242SachimosGLOBAL FORCEINLINE sbit32
729285242SachimostiInterlockedDecrement(
730285242Sachim                         tiRoot_t         *root,
731285242Sachim                         sbit32 volatile  *Addend
732285242Sachim                         )
733285242Sachim{
734285242Sachim  return 0;
735285242Sachim}
736285242Sachim
737285242SachimosGLOBAL FORCEINLINE sbit32
738285242SachimostiInterlockedAnd(
739285242Sachim                   tiRoot_t         *root,
740285242Sachim                   sbit32 volatile  *Destination,
741285242Sachim                   sbit32            Value
742285242Sachim                   )
743285242Sachim{
744285242Sachim  return 0;
745285242Sachim}
746285242Sachim
747285242SachimosGLOBAL FORCEINLINE sbit32
748285242SachimostiInterlockedOr(
749285242Sachim                   tiRoot_t         *root,
750285242Sachim                   sbit32 volatile  *Destination,
751285242Sachim                   sbit32            Value
752285242Sachim                   )
753285242Sachim{
754285242Sachim  return 0;
755285242Sachim}
756285242Sachim
757285242Sachim// this is just stub code to allow compile and use of the module ...
758285242Sachim// now that a call to this function has been added with windows specific
759285242Sachim// intentions.
760285242SachimosGLOBAL bit32
761285242SachimostiSetDeviceQueueDepth( tiRoot_t *tiRoot,
762285242Sachim                         tiIORequest_t  *tiIORequest,
763285242Sachim                         bit32           QueueDepth
764285242Sachim                         )
765285242Sachim{
766285242Sachim  bit32 retVal = 0;
767285242Sachim  struct agtiapi_softc *pCard = TIROOT_TO_CARD(tiRoot);
768285242Sachim  ccb_t *pccb = (ccb_t *) tiIORequest->osData;
769285242Sachim  tiDeviceHandle_t *tiDeviceHandle = pccb->devHandle;
770285242Sachim  ag_device_t *pDevice = (ag_device_t *)tiDeviceHandle->osData;
771285242Sachim  AGTIAPI_PRINTK( "ostiSetDeviceQueueDepth stub only: root%p, req%p, qdeep%d\n",
772285242Sachim                  tiRoot, tiIORequest, QueueDepth );
773285242Sachim  pDevice->qdepth = QueueDepth;
774285242Sachim  return retVal;
775285242Sachim}
776285242Sachim
777285242Sachim
778285242Sachim// this is just stub code to allow compile and use of the module ...
779285242Sachim// now that a call to this function has been added with windows specific
780285242Sachim// intentions.
781285242SachimosGLOBAL void
782285242SachimostiGetSenseKeyCount(tiRoot_t  *root,
783285242Sachim                     bit32      fIsClear,
784285242Sachim                     void      *SenseKeyCount,
785285242Sachim                     bit32      length
786285242Sachim                     )
787285242Sachim{
788285242Sachim  AGTIAPI_PRINTK( "ostiGetSenseKeyCount stub only: rt%p, fcl%d, kyCt%p, ln%d\n",
789285242Sachim                  root, fIsClear, SenseKeyCount, length );
790285242Sachim}
791285242Sachim
792285242SachimosGLOBAL void
793285242SachimostiGetSCSIStatusCount(tiRoot_t  *root,
794285242Sachim                              bit32      fIsClear,
795285242Sachim                              void      *ScsiStatusCount,
796285242Sachim                              bit32      length
797285242Sachim                              )
798285242Sachim{
799285242Sachim AGTIAPI_PRINTK( "ostiGetSCSIStatusCount: stub only rt%p, fcl%d, kyCt%p, ln%d\n",
800285242Sachim                 root, fIsClear, ScsiStatusCount, length );
801285242Sachim
802285242Sachim}
803285242Sachim
804285242SachimosGLOBAL void ostiPCI_TRIGGER( tiRoot_t *tiRoot )
805285242Sachim{
806285242Sachim  ostiChipReadBit32Ext(tiRoot, 0, 0x5C);
807285242Sachim
808285242Sachim}
809285242Sachim
810285242SachimosGLOBAL bit32
811285242SachimostiNumOfLUNIOCTLreq(  tiRoot_t          *root,
812285242Sachim                              void              *param1,
813285242Sachim                              void              *param2,
814285242Sachim                              void              **tiRequestBody,
815285242Sachim                              tiIORequest_t     **tiIORequest
816285242Sachim                              )
817285242Sachim{
818285242Sachim  bit32		status = IOCTL_CALL_SUCCESS;
819285242Sachim  pccb_t pccb;
820285242Sachim  AGTIAPI_PRINTK("ostiNumOfLUNIOCTLreq: start\n");
821285242Sachim  struct agtiapi_softc *pCard = TIROOT_TO_CARD(root);
822285242Sachim    /* get a ccb */
823285242Sachim  if ((pccb = agtiapi_GetCCB(pCard)) == NULL)
824285242Sachim  {
825285242Sachim    printf("ostiNumOfLUNIOCTLreq - GetCCB ERROR\n");
826285242Sachim    status = IOCTL_CALL_FAIL;
827285242Sachim    //BUG_ON(1);
828285242Sachim  }
829285242Sachim
830285242Sachim  *tiIORequest = (tiIORequest_t*)&pccb->tiIORequest;
831285242Sachim  *tiRequestBody = &pccb->tdIOReqBody;
832285242Sachim  AGTIAPI_PRINTK("ostiNumOfLUNIOCTLreq:end\n");
833285242Sachim  return status;
834285242Sachim}
835285242Sachim
836