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* $FreeBSD$
22*
23*******************************************************************************/
24/******************************************************************************
25PMC-Sierra TISA Initiator Device Driver for Linux 2.x.x.
26
27Module Name:
28  osapi.c
29Abstract:
30  Linux iSCSI/FC Initiator driver module itsdk required OS functions
31Environment:
32  Part of oslayer module, Kernel or loadable module
33
34*******************************************************************************
35ostiInitiatorEvent()
36
37Purpose:
38  TI layer call back to OSlayer to inform events
39Parameters:
40  tiRoot_t *ptiRoot (IN)               Pointer to HBA data structure
41  tiDeviceHandle_t *ptiDevHandle (IN)  Pointer to device handle
42  tiIntrEvenType_t evenType (IN)       Event type
43  tiIntrEventStatus_t evetStatus (IN)  Event status
44  void *parm (IN)                      pointer to even specific data
45Return:
46Note:
47  TBD, further event process required.
48******************************************************************************/
49void ostiInitiatorEvent( tiRoot_t *ptiRoot,
50                         tiPortalContext_t *ptiPortalContext,
51                         tiDeviceHandle_t *ptiDevHandle,
52                         tiIntrEventType_t eventType,
53                         U32 eventStatus,
54                         void *parm )
55{
56  ag_portal_data_t *pPortalData;
57  ag_portal_info_t *pPortalInfo;
58  struct agtiapi_softc *pCard = TIROOT_TO_CARD( ptiRoot );
59  ccb_t     *pccb;
60  ccb_t     *pTMccb;
61  ccb_t     *ccbIO;
62
63#ifdef  AGTIAPI_EVENT_LOG
64  AGTIAPI_PRINTK("Initiator Event:\n");
65  AGTIAPI_PRINTK("DevHandle %p, eventType 0x%x, eventStatus 0x%x\n",
66                 ptiDevHandle, eventType, eventStatus);
67  AGTIAPI_PRINTK("Parameter: %s\n", (char *)parm);
68#endif
69
70  AGTIAPI_PRINTK("ostiInitiatorEvent: eventType 0x%x eventStatus 0x%x\n", eventType, eventStatus);
71
72  switch (eventType)
73  {
74  case tiIntrEventTypeCnxError:
75       if (eventStatus == tiCnxUp)
76       {
77         AGTIAPI_PRINTK("tiIntrEventTypeCnxError - tiCnxUp!\n");
78       }
79       if (eventStatus == tiCnxDown)
80       {
81         AGTIAPI_PRINTK("tiIntrEventTypeCnxError - tiCnxDown!\n");
82       }
83       break;
84  case tiIntrEventTypeDiscovery:
85       pPortalData = PORTAL_CONTEXT_TO_PORTALDATA(ptiPortalContext);
86       pCard->flags |= AGTIAPI_CB_DONE;
87       if (eventStatus == tiDiscOK)
88       {
89         AGTIAPI_PRINTK("eventStatus - tiDiscOK\n");
90         AGTIAPI_PRINTK("ostiInitiatorEvent: pcard %d eventStatus - tiDiscOK\n", pCard->cardNo );
91         PORTAL_STATUS(pPortalData) |= AGTIAPI_DISC_COMPLETE;
92#ifndef HOTPLUG_SUPPORT
93         if (!(pCard->flags & AGTIAPI_INIT_TIME))
94#else
95         if (TRUE)
96#endif
97         {
98
99           agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo,
100                                tiIntrEventTypeDiscovery, tiDiscOK);
101           PORTAL_STATUS(pPortalData) |=
102             (AGTIAPI_DISC_DONE | AGTIAPI_PORT_LINK_UP);
103         }
104         /* Trigger CheckIOTimeout */
105         callout_reset(&pCard->IO_timer, 20*hz, agtiapi_CheckIOTimeout, pCard);
106       }
107       else if (eventStatus == tiDiscFailed)
108       {
109         AGTIAPI_PRINTK("eventStatus - tiDiscFailed\n");
110         agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo,
111                              tiIntrEventTypeDiscovery, tiDiscFailed);
112         PORTAL_STATUS(pPortalData) &= ~AGTIAPI_DISC_DONE;
113       }
114       AGTIAPI_PRINTK("tiIntrEventTypeDiscovery - portal %p, status 0x%x\n",
115         pPortalData,
116         PORTAL_STATUS(pPortalData));
117       break;
118  case tiIntrEventTypeDeviceChange:
119       AGTIAPI_PRINTK("tiIntrEventTypeDeviceChange - portal %p es %d\n",
120                      ptiPortalContext->osData, eventStatus);
121       pPortalData = PORTAL_CONTEXT_TO_PORTALDATA(ptiPortalContext);
122       pPortalInfo = &pPortalData->portalInfo;
123#ifndef HOTPLUG_SUPPORT
124       if (!(pCard->flags & AGTIAPI_INIT_TIME))
125#else
126       if (TRUE)
127#endif
128       {
129         agtiapi_GetDevHandle(pCard, pPortalInfo, tiIntrEventTypeDeviceChange,
130                              eventStatus);
131//         agtiapi_StartIO(pCard);
132       }
133       break;
134  case tiIntrEventTypeTransportRecovery:
135       AGTIAPI_PRINTK("tiIntrEventTypeTransportRecovery!\n");
136       break;
137  case tiIntrEventTypeTaskManagement:
138       AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement!\n");
139       pccb = (pccb_t)((tiIORequest_t *)parm)->osData;
140       if (pccb->flags & TASK_TIMEOUT)
141       {
142         AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: TM timeout!\n");
143         agtiapi_FreeTMCCB(pCard, pccb);
144       }
145       else
146       {
147         pccb->flags |= AGTIAPI_CB_DONE;
148         if (eventStatus == tiTMOK)
149         {
150           pccb->flags |= TASK_SUCCESS;
151           AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: pTMccb %p flag %x \n",
152                          pccb, pccb->flags);
153
154           /* Incase of TM_DEV_RESET, issue LocalAbort to abort pending IO */
155           if (pccb->flags & DEV_RESET)
156           {
157               AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: Target Reset\n");
158               ccbIO = pccb->pccbIO;
159               AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: IO to be aborted locally %p flag %x \n",
160                          ccbIO, ccbIO->flags);
161               if (ccbIO->startTime == 0) /* IO has been completed. No local abort */
162               {
163               }
164               else if (tiINIIOAbort(&pCard->tiRoot, &ccbIO->tiIORequest) != tiSuccess)
165               {
166                   AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: Local Abort failed\n");
167                   /* TODO: call Soft reset here */
168               }
169           }
170          else if (eventStatus == tiTMFailed)
171          {
172               ccbIO = pccb->pccbIO;
173               if (ccbIO->startTime == 0) /* IO has been completed. */
174               {
175                   AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: TM failed because IO has been completed! pTMccb %p flag %x \n",
176                                   pccb, pccb->flags);
177               }
178               else
179               {
180              AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: TM failed! pTMccb %p flag %x \n",
181                             pccb, pccb->flags);
182               /* TODO:*/
183              /* if TM_ABORT_TASK, call TM_TARGET_RESET */
184              /* if TM_TARGET_RESET, call Soft_Reset */
185               }
186          }
187          /* Free TM_DEV_RESET ccb */
188          agtiapi_FreeTMCCB(pCard, pccb);
189         }
190        }
191       break;
192  case tiIntrEventTypeLocalAbort:
193        AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort!\n");
194        pccb = (pccb_t)((tiIORequest_t *)parm)->osData;
195        pccb->flags |= AGTIAPI_CB_DONE;
196        if (eventStatus == tiAbortOK)
197        {
198            AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: taskTag pccb %p flag %x \n",
199                           pccb, pccb->flags);
200            /* If this was LocalAbort for TM ABORT_TASK, issue TM_DEV_RESET */
201            if (pccb->flags & TASK_MANAGEMENT)
202            {
203                if ((pTMccb = agtiapi_GetCCB(pCard)) == NULL)
204                {
205                    AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: TM resource unavailable!\n");
206                    /* TODO: SoftReset here? */
207                }
208                pTMccb->pmcsc = pCard;
209                pTMccb->targetId = pccb->targetId;
210                pTMccb->devHandle = pccb->devHandle;
211
212                /* save pending io to issue local abort at Task mgmt CB */
213                pTMccb->pccbIO = pccb->pccbIO;
214                pTMccb->flags &= ~(TASK_SUCCESS | ACTIVE);
215                pTMccb->flags |= DEV_RESET;
216                if (tiINITaskManagement(&pCard->tiRoot,
217                                        pccb->devHandle,
218                                        AG_TARGET_WARM_RESET,
219                                        &pccb->tiSuperScsiRequest.scsiCmnd.lun,
220                                        &pccb->tiIORequest,
221                                        &pTMccb->tiIORequest)
222                    == tiSuccess)
223                {
224                    AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: TM_TARGET_RESET request success ccb %p, pTMccb %p\n",
225                                   pccb, pTMccb);
226                    pTMccb->startTime = ticks;
227                }
228                else
229                {
230                    AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: TM_TARGET_RESET request failed ccb %p, pTMccb %p\n",
231                                   pccb, pTMccb);
232                    agtiapi_FreeTMCCB(pCard, pTMccb);
233                    /* TODO: SoftReset here? */
234                }
235                /* Free ABORT_TASK TM ccb */
236                agtiapi_FreeTMCCB(pCard, pccb);
237            }
238        }
239        else if (eventStatus == tiAbortFailed)
240        {
241            /* TODO: */
242            /* If TM_ABORT_TASK fails, issue TM_DEV_RESET */
243            /* if TM_DEV_RESET fails, issue Soft_Reset */
244            AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: Abort Failed pccb %p\n", pccb);
245       }
246       break;
247  default:
248       AGTIAPI_PRINTK("tiIntrEventType default!\n");
249       break;
250  }
251}
252
253
254/******************************************************************************
255ostiInitiatorIOCompleted()
256
257Purpose:
258  IO request completion call back
259Parameters:
260  tiRoot_t *ptiRoot (IN)               Pointer to the HBA tiRoot
261  tiIORequest_t *ptiIORequest (IN)     Pointer to the tiIORequest structure
262  tiIOStatus_t IOStatus (IN)           I/O complated status
263  U32 statusDetail (IN)                Additional information on status
264  tiSenseData_t *pSensedata (IN)       Sense data buffer pointer
265  U32 context (IN)                     Interrupt dealing context
266Returns:
267Note:
268******************************************************************************/
269void
270ostiInitiatorIOCompleted(tiRoot_t      *ptiRoot,
271                               tiIORequest_t *ptiIORequest,
272                               tiIOStatus_t  IOStatus,
273                               U32           statusDetail,
274                               tiSenseData_t *pSenseData,
275                               U32           context )
276{
277  struct agtiapi_softc  *pCard;
278  ccb_t      *pccb;
279
280  pCard = TIROOT_TO_CARD(ptiRoot);
281  pccb = (ccb_t *)ptiIORequest->osData;
282
283  AGTIAPI_IO( "ostiInitiatorIOCompleted: start\n" );
284
285  if (IOStatus == tiIODifError)
286  {
287    return;
288  }
289  OSTI_OUT_ENTER(ptiRoot);
290
291  pccb->ccbStatus  = (U16)IOStatus;
292  pccb->scsiStatus = statusDetail;
293
294  if ((IOStatus == tiIOSuccess) && (statusDetail == SCSI_CHECK_CONDITION))
295  {
296    if (pSenseData == (tiSenseData_t *)agNULL)
297    {
298      AGTIAPI_PRINTK( "ostiInitiatorIOCompleted: "
299                      "check condition without sense data!\n" );
300    }
301    else
302    {
303      union ccb *ccb = pccb->ccb;
304      struct ccb_scsiio *csio = &ccb->csio;
305      int sense_len = 0;
306      if (pccb->senseLen > pSenseData->senseLen)
307      {
308        csio->sense_resid = pccb->senseLen - pSenseData->senseLen;
309      }
310      else
311      {
312        csio->sense_resid = 0;
313      }
314      sense_len = MIN( pSenseData->senseLen,
315                       pccb->senseLen - csio->sense_resid );
316      bzero(&csio->sense_data, sizeof(csio->sense_data));
317      AGTIAPI_PRINTK("ostiInitiatorIOCompleted: check condition copying\n");
318      memcpy( (void *)pccb->pSenseData,
319              pSenseData->senseData,
320              sense_len );
321      agtiapi_hexdump( "ostiInitiatorIOCompleted check condition",
322                       (bit8 *)&csio->sense_data, sense_len );
323    }
324  }
325  if ((IOStatus == tiIOFailed) && (statusDetail == tiDetailAborted))
326  {
327    AGTIAPI_PRINTK("ostiInitiatorIOCompleted - aborted ccb %p, flag %x\n",
328                   pccb, pccb->flags);
329    /* indicate aborted IO completion */
330    pccb->startTime = 0;
331    agtiapi_Done(pCard, pccb);
332  }
333  else
334  {
335#ifdef AGTIAPI_SA
336    /*
337     * SAS no data command does not trigger interrupt.
338     * Command is completed in tdlayer and IO completion is called directly.
339     * The completed IO therefore is not post processed.
340     * Flag is raised and TDTimer will check and process IO for SAS.
341     * This is a temporary solution. - Eddie, 07-17-2006
342     */
343    pCard->flags |= AGTIAPI_FLAG_UP;
344#endif
345    pccb->flags  |= REQ_DONE;
346    agtiapi_QueueCCB(pCard, &pCard->ccbDoneHead, &pCard->ccbDoneTail
347                     AG_CARD_LOCAL_LOCK(&pCard->doneLock), pccb);
348  }
349  OSTI_OUT_LEAVE(ptiRoot);
350  return;
351}
352#ifdef HIALEAH_ENCRYPTION
353osGLOBAL void
354ostidisableEncryption(tiRoot_t *ptiRoot)
355{
356  struct agtiapi_softc  *pCard;
357  pCard = TIROOT_TO_CARD(ptiRoot);
358  pCard->encrypt=agFALSE;
359}
360#endif
361/* device Handle */
362osGLOBAL //FORCEINLINE
363tiDeviceHandle_t*
364ostiGetDevHandleFromSasAddr(
365  tiRoot_t    *root,
366  unsigned char *sas_addr
367)
368{
369  int i;
370  unsigned long x;
371
372  ag_portal_data_t           *pPortal = NULL;
373  tiDeviceHandle_t *devHandle = NULL;
374  struct agtiapi_softc *pCard = TIROOT_TO_CARD(root);
375  bit8 sas_addr_hi[4], sas_addr_lo[4];
376
377
378  for(i=0; i<4; i++)
379  {
380  	sas_addr_hi[i] = sas_addr[3-i];
381  }
382
383  for(i=0; i<4; i++)
384  {
385  	sas_addr_lo[i] = sas_addr[7-i];
386  }
387
388    /* Retrieve the handles for each portal */
389  for (x=0; x < pCard->portCount; x++)
390  {
391    pPortal = &pCard->pPortalData[x];
392    devHandle = tiINIGetExpDeviceHandleBySasAddress(&pCard->tiRoot,
393                    &pPortal->portalInfo.tiPortalContext,
394					*(bit32*)sas_addr_hi,
395					*(bit32*)sas_addr_lo,
396					(bit32)1024/*gMaxTargets*/);
397	if(devHandle != NULL)
398		break;
399  }
400  return devHandle;
401
402  return NULL;
403}
404/******************************************************************************
405ostiInitiatorSMPCompleted()
406
407Purpose:
408  IO request completion call back
409Parameters:
410  tiRoot_t *ptiRoot (IN)               Pointer to the HBA tiRoot
411  tiIORequest_t *ptiSMPRequest (IN)    Pointer to the SMP request structure
412  tiIOStatus_t IOStatus (IN)           I/O complated status
413  U32 tiSMPInfoLen (IN)                Number of bytes of response frame len
414  tiFrameHandle    (IN)                Handle that referes to response frame
415  U32 context (IN)                     Interrupt dealing context
416Returns:
417Note:
418******************************************************************************/
419void
420ostiInitiatorSMPCompleted(tiRoot_t      *ptiRoot,
421                          tiIORequest_t *ptiSMPRequest,
422                          tiSMPStatus_t  smpStatus,
423                          bit32          tiSMPInfoLen,
424                          void           *tiFrameHandle,
425                          bit32          context)
426{
427  struct agtiapi_softc  *pCard;
428  ccb_t      *pccb;
429  pCard = TIROOT_TO_CARD(ptiRoot);
430  pccb = (ccb_t *)ptiSMPRequest->osData;
431
432  AGTIAPI_PRINTK("ostiInitiatorSMPCompleted: start\n");
433
434  OSTI_OUT_ENTER(ptiRoot);
435  pccb->ccbStatus  = (U16)smpStatus;
436  if(smpStatus != tiSMPSuccess)
437  {
438    AGTIAPI_PRINTK("ostiInitiatorSMPCompleted: SMP Error\n");
439  }
440  else
441  {
442    union ccb *ccb = pccb->ccb;
443    struct ccb_smpio *csmpio = &ccb->smpio;
444    memcpy(csmpio->smp_response, tiFrameHandle, tiSMPInfoLen);
445    csmpio->smp_response_len = tiSMPInfoLen;
446    agtiapi_hexdump("ostiInitiatorSMPCompleted: Response Payload in CAM", (bit8 *)csmpio->smp_response, csmpio->smp_response_len);
447  }
448  pccb->flags  |= REQ_DONE;
449  agtiapi_QueueCCB(pCard, &pCard->smpDoneHead, &pCard->smpDoneTail
450                     AG_CARD_LOCAL_LOCK(&pCard->doneSMPLock), pccb);
451  AGTIAPI_PRINTK("ostiInitiatorSMPCompleted: Done\n");
452  OSTI_OUT_LEAVE(ptiRoot);
453
454  return;
455}
456
457#ifdef FAST_IO_TEST
458void
459osti_FastIOCb(tiRoot_t      *ptiRoot,
460              void          *arg,
461              tiIOStatus_t  IOStatus,
462              U32           statusDetail)
463{
464  ccb_t     *pccb = (ccb_t*)arg;
465  ag_card_t *pCard;
466
467  static int callNum = 0;
468
469  callNum++;
470
471  BUG_ON(!pccb);
472
473  if ((callNum % CMDS_PER_IO_DUP) != 0)
474  {
475    goto err;
476  }
477
478  pccb->ccbStatus = IOStatus;
479  pccb->scsiStatus = statusDetail;
480
481  /* pccb->pSenseData is copied already */
482
483  if (pccb->flags & AGTIAPI_ABORT)
484  {
485    AGTIAPI_PRINTK("agtiapi_SuperIOCb: aborted ccb %p, flag %x\n",
486                   pccb, pccb->flags);
487    pccb->startTime = 0;     /* indicate aborted IO completion */
488    BUG_ON(1);
489    goto err;
490  }
491  pCard = TIROOT_TO_CARD(ptiRoot);
492  pccb->flags |= REQ_DONE;
493  agtiapi_QueueCCB(pCard, &pCard->ccbDoneHead, &pCard->ccbDoneTail
494                   AG_CARD_LOCAL_LOCK(&pCard->doneLock), pccb);
495err:
496  return;
497} /* osti_FastIOCb */
498#endif
499
500
501/******************************************************************************
502ostiSingleThreadedEnter()
503
504Purpose:
505  Critical region code excution protection.
506Parameters:
507  tiRoot_t *ptiRoot (IN)  Pointer to tiRoot data structure
508  U32 queueId (IN)     spinlock Id
509Returns:
510Note:
511  Lock is held by oslayer.
512******************************************************************************/
513void
514ostiSingleThreadedEnter(tiRoot_t *ptiRoot, U32 queueId)
515{
516  struct agtiapi_softc *pCard = TIROOT_TO_CARD(ptiRoot);
517  mtx_lock( &pCard->STLock[queueId] ); // review: need irq save? ##
518}
519
520
521/******************************************************************************
522ostiSingleThreadedLeave()
523
524Purpose:
525  Restore multi-threading environment.
526Parameters:
527  tiRoot_t *ptiRoot (IN)  Pointer to the tiRoot data structure
528  U32 queueId (IN)     spinlock Id
529Returns:
530Note:
531  Lock is held by oslayer.
532******************************************************************************/
533void
534ostiSingleThreadedLeave(tiRoot_t *ptiRoot, U32 queueId)
535{
536  struct agtiapi_softc *pCard = TIROOT_TO_CARD(ptiRoot);
537  mtx_unlock( &pCard->STLock[queueId] ); // review: need irq restore? ##
538}
539
540
541osGLOBAL tiDeviceHandle_t*
542ostiMapToDevHandle(tiRoot_t  *root,
543                          bit8      pathId,
544                          bit8      targetId,
545                          bit8      LUN
546                          )
547{
548  tiDeviceHandle_t    *dev      = NULL;
549  struct agtiapi_softc          *pCard;
550  bit32               offset;
551
552  pCard = TIROOT_TO_CARD(root);
553
554  offset = pathId * pCard->tgtCount + targetId;
555
556  if (offset > (pCard->tgtCount - 1) )
557  {
558    dev = NULL;
559  }
560  else
561  {
562    dev = pCard->pDevList[offset].pDevHandle;
563  }
564
565  return dev;
566}
567
568
569
570#ifdef PERF_COUNT
571
572#ifdef AGTIAPI_LOCAL_LOCK
573#define OSTI_SPIN_LOCK(lock)              spin_lock(lock)
574#define OSTI_SPIN_UNLOCK(lock)            spin_unlock(lock)
575#else
576#define OSTI_SPIN_LOCK(lock)
577#define OSTI_SPIN_UNLOCK(lock)
578#endif
579
580
581void
582ostiEnter(tiRoot_t *ptiRoot, U32 layer, int io)
583{
584  ag_card_t *pCard = ((ag_card_info_t*)ptiRoot->osData)->pCard;
585  int ini = ((pCard->flags & AGTIAPI_INIT_TIME) == AGTIAPI_INIT_TIME);
586
587  BUG_ON((io != 0 && io != 1) || (layer != 0 && layer != 1 && layer != 2));
588  if (!ini)
589  {
590    unsigned long long cycles = get_cycles();
591
592    OSTI_SPIN_LOCK(&pCard->latLock);
593    BUG_ON(pCard->callLevel[io] >= sizeof(pCard->layer[0]) /
594                                     sizeof(pCard->layer[0][0]));
595    if (pCard->callLevel[io] > 0)
596    {
597      unsigned int prev_layer = pCard->layer[io][pCard->callLevel[io] - 1];
598
599      pCard->totalCycles[io][prev_layer] += cycles -
600                                             pCard->enterCycles[io][prev_layer];
601    }
602    pCard->enterCycles[io][layer] = cycles;
603    pCard->layer[io][pCard->callLevel[io]] = layer;
604    pCard->callLevel[io]++;
605    OSTI_SPIN_UNLOCK(&pCard->latLock);
606  }
607}
608
609void
610ostiLeave(tiRoot_t *ptiRoot, U32 layer, int io)
611{
612  ag_card_t *pCard = ((ag_card_info_t*)ptiRoot->osData)->pCard;
613  int ini = ((pCard->flags & AGTIAPI_INIT_TIME) == AGTIAPI_INIT_TIME);
614
615  BUG_ON((io != 0 && io != 1) || (layer != 0 && layer != 1 && layer != 2));
616  if (!ini)
617  {
618    unsigned long long cycles = get_cycles();
619
620    OSTI_SPIN_LOCK(&pCard->latLock);
621    pCard->callLevel[io]--;
622
623    BUG_ON(pCard->callLevel[io] < 0);
624    BUG_ON(pCard->layer[io][pCard->callLevel[io]] != layer);
625
626    pCard->totalCycles[io][layer] += cycles - pCard->enterCycles[io][layer];
627    if (pCard->callLevel[io] > 0)
628      pCard->enterCycles[io][pCard->layer[io][pCard->callLevel[io] - 1]] =
629        cycles;
630    OSTI_SPIN_UNLOCK(&pCard->latLock);
631  }
632}
633#endif
634
635
636
637osGLOBAL FORCEINLINE bit8
638ostiBitScanForward(
639                  tiRoot_t   *root,
640                  bit32      *Index,
641                  bit32       Mask
642                  )
643{
644  return 1;
645
646}
647
648#ifdef REMOVED
649osGLOBAL sbit32
650ostiAtomicIncrement(
651                   tiRoot_t        *root,
652                   sbit32 volatile *Addend
653                   )
654{
655  return 1;
656
657}
658
659osGLOBAL sbit32
660ostiAtomicDecrement(
661                   tiRoot_t        *root,
662                   sbit32 volatile *Addend
663                   )
664{
665
666  return 1;
667
668}
669
670osGLOBAL sbit32
671ostiAtomicBitClear(
672                 tiRoot_t         *root,
673                 sbit32 volatile  *Destination,
674                 sbit32            Value
675                 )
676{
677
678  return 0;
679
680}
681
682osGLOBAL sbit32
683ostiAtomicBitSet(
684                tiRoot_t         *root,
685                sbit32 volatile  *Destination,
686                sbit32            Value
687                )
688{
689  return 0;
690
691  /*
692   set_bit(Value, (volatile unsigned long *)Destination);
693   return 0;
694  */
695}
696
697osGLOBAL sbit32
698ostiAtomicExchange(
699                   tiRoot_t        *root,
700                   sbit32 volatile *Target,
701                   sbit32           Value
702                   )
703{
704  return 0;
705
706}
707#endif
708
709osGLOBAL FORCEINLINE sbit32
710ostiInterlockedExchange(
711                       tiRoot_t        *root,
712                       sbit32 volatile *Target,
713                       sbit32           Value
714                       )
715{
716  return 0;
717}
718
719osGLOBAL FORCEINLINE sbit32
720ostiInterlockedIncrement(
721                       tiRoot_t        *root,
722                       sbit32 volatile *Addend
723                       )
724{
725  return 0;
726}
727
728osGLOBAL FORCEINLINE sbit32
729ostiInterlockedDecrement(
730                         tiRoot_t         *root,
731                         sbit32 volatile  *Addend
732                         )
733{
734  return 0;
735}
736
737osGLOBAL FORCEINLINE sbit32
738ostiInterlockedAnd(
739                   tiRoot_t         *root,
740                   sbit32 volatile  *Destination,
741                   sbit32            Value
742                   )
743{
744  return 0;
745}
746
747osGLOBAL FORCEINLINE sbit32
748ostiInterlockedOr(
749                   tiRoot_t         *root,
750                   sbit32 volatile  *Destination,
751                   sbit32            Value
752                   )
753{
754  return 0;
755}
756
757// this is just stub code to allow compile and use of the module ...
758// now that a call to this function has been added with windows specific
759// intentions.
760osGLOBAL bit32
761ostiSetDeviceQueueDepth( tiRoot_t *tiRoot,
762                         tiIORequest_t  *tiIORequest,
763                         bit32           QueueDepth
764                         )
765{
766  bit32 retVal = 0;
767  struct agtiapi_softc *pCard = TIROOT_TO_CARD(tiRoot);
768  ccb_t *pccb = (ccb_t *) tiIORequest->osData;
769  tiDeviceHandle_t *tiDeviceHandle = pccb->devHandle;
770  ag_device_t *pDevice = (ag_device_t *)tiDeviceHandle->osData;
771  AGTIAPI_PRINTK( "ostiSetDeviceQueueDepth stub only: root%p, req%p, qdeep%d\n",
772                  tiRoot, tiIORequest, QueueDepth );
773  pDevice->qdepth = QueueDepth;
774  return retVal;
775}
776
777
778// this is just stub code to allow compile and use of the module ...
779// now that a call to this function has been added with windows specific
780// intentions.
781osGLOBAL void
782ostiGetSenseKeyCount(tiRoot_t  *root,
783                     bit32      fIsClear,
784                     void      *SenseKeyCount,
785                     bit32      length
786                     )
787{
788  AGTIAPI_PRINTK( "ostiGetSenseKeyCount stub only: rt%p, fcl%d, kyCt%p, ln%d\n",
789                  root, fIsClear, SenseKeyCount, length );
790}
791
792osGLOBAL void
793ostiGetSCSIStatusCount(tiRoot_t  *root,
794                              bit32      fIsClear,
795                              void      *ScsiStatusCount,
796                              bit32      length
797                              )
798{
799 AGTIAPI_PRINTK( "ostiGetSCSIStatusCount: stub only rt%p, fcl%d, kyCt%p, ln%d\n",
800                 root, fIsClear, ScsiStatusCount, length );
801
802}
803
804osGLOBAL void ostiPCI_TRIGGER( tiRoot_t *tiRoot )
805{
806  ostiChipReadBit32Ext(tiRoot, 0, 0x5C);
807
808}
809
810osGLOBAL bit32
811ostiNumOfLUNIOCTLreq(  tiRoot_t          *root,
812                              void              *param1,
813                              void              *param2,
814                              void              **tiRequestBody,
815                              tiIORequest_t     **tiIORequest
816                              )
817{
818  bit32		status = IOCTL_CALL_SUCCESS;
819  pccb_t pccb;
820  AGTIAPI_PRINTK("ostiNumOfLUNIOCTLreq: start\n");
821  struct agtiapi_softc *pCard = TIROOT_TO_CARD(root);
822    /* get a ccb */
823  if ((pccb = agtiapi_GetCCB(pCard)) == NULL)
824  {
825    printf("ostiNumOfLUNIOCTLreq - GetCCB ERROR\n");
826    status = IOCTL_CALL_FAIL;
827    //BUG_ON(1);
828  }
829
830  *tiIORequest = (tiIORequest_t*)&pccb->tiIORequest;
831  *tiRequestBody = &pccb->tdIOReqBody;
832  AGTIAPI_PRINTK("ostiNumOfLUNIOCTLreq:end\n");
833  return status;
834}
835
836