xref: /freebsd/sys/dev/pms/freebsd/driver/ini/src/osapi.c (revision ab00ac327a66a53edaac95b536b209db3ae2cd9f)
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 /******************************************************************************
25 PMC-Sierra TISA Initiator Device Driver for Linux 2.x.x.
26 
27 Module Name:
28   osapi.c
29 Abstract:
30   Linux iSCSI/FC Initiator driver module itsdk required OS functions
31 Environment:
32   Part of oslayer module, Kernel or loadable module
33 
34 *******************************************************************************
35 ostiInitiatorEvent()
36 
37 Purpose:
38   TI layer call back to OSlayer to inform events
39 Parameters:
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
45 Return:
46 Note:
47   TBD, further event process required.
48 ******************************************************************************/
49 void 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 /******************************************************************************
255 ostiInitiatorIOCompleted()
256 
257 Purpose:
258   IO request completion call back
259 Parameters:
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
266 Returns:
267 Note:
268 ******************************************************************************/
269 void
270 ostiInitiatorIOCompleted(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
353 osGLOBAL void
354 ostidisableEncryption(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 */
362 osGLOBAL //FORCEINLINE
363 tiDeviceHandle_t*
364 ostiGetDevHandleFromSasAddr(
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 /******************************************************************************
405 ostiInitiatorSMPCompleted()
406 
407 Purpose:
408   IO request completion call back
409 Parameters:
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
416 Returns:
417 Note:
418 ******************************************************************************/
419 void
420 ostiInitiatorSMPCompleted(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
458 void
459 osti_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);
495 err:
496   return;
497 } /* osti_FastIOCb */
498 #endif
499 
500 
501 /******************************************************************************
502 ostiSingleThreadedEnter()
503 
504 Purpose:
505   Critical region code excution protection.
506 Parameters:
507   tiRoot_t *ptiRoot (IN)  Pointer to tiRoot data structure
508   U32 queueId (IN)     spinlock Id
509 Returns:
510 Note:
511   Lock is held by oslayer.
512 ******************************************************************************/
513 void
514 ostiSingleThreadedEnter(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 /******************************************************************************
522 ostiSingleThreadedLeave()
523 
524 Purpose:
525   Restore multi-threading environment.
526 Parameters:
527   tiRoot_t *ptiRoot (IN)  Pointer to the tiRoot data structure
528   U32 queueId (IN)     spinlock Id
529 Returns:
530 Note:
531   Lock is held by oslayer.
532 ******************************************************************************/
533 void
534 ostiSingleThreadedLeave(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 
541 osGLOBAL tiDeviceHandle_t*
542 ostiMapToDevHandle(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 
581 void
582 ostiEnter(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 
609 void
610 ostiLeave(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 
637 osGLOBAL FORCEINLINE bit8
638 ostiBitScanForward(
639                   tiRoot_t   *root,
640                   bit32      *Index,
641                   bit32       Mask
642                   )
643 {
644   return 1;
645 
646 }
647 
648 #ifdef REMOVED
649 osGLOBAL sbit32
650 ostiAtomicIncrement(
651                    tiRoot_t        *root,
652                    sbit32 volatile *Addend
653                    )
654 {
655   return 1;
656 
657 }
658 
659 osGLOBAL sbit32
660 ostiAtomicDecrement(
661                    tiRoot_t        *root,
662                    sbit32 volatile *Addend
663                    )
664 {
665 
666   return 1;
667 
668 }
669 
670 osGLOBAL sbit32
671 ostiAtomicBitClear(
672                  tiRoot_t         *root,
673                  sbit32 volatile  *Destination,
674                  sbit32            Value
675                  )
676 {
677 
678   return 0;
679 
680 }
681 
682 osGLOBAL sbit32
683 ostiAtomicBitSet(
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 
697 osGLOBAL sbit32
698 ostiAtomicExchange(
699                    tiRoot_t        *root,
700                    sbit32 volatile *Target,
701                    sbit32           Value
702                    )
703 {
704   return 0;
705 
706 }
707 #endif
708 
709 osGLOBAL FORCEINLINE sbit32
710 ostiInterlockedExchange(
711                        tiRoot_t        *root,
712                        sbit32 volatile *Target,
713                        sbit32           Value
714                        )
715 {
716   return 0;
717 }
718 
719 osGLOBAL FORCEINLINE sbit32
720 ostiInterlockedIncrement(
721                        tiRoot_t        *root,
722                        sbit32 volatile *Addend
723                        )
724 {
725   return 0;
726 }
727 
728 osGLOBAL FORCEINLINE sbit32
729 ostiInterlockedDecrement(
730                          tiRoot_t         *root,
731                          sbit32 volatile  *Addend
732                          )
733 {
734   return 0;
735 }
736 
737 osGLOBAL FORCEINLINE sbit32
738 ostiInterlockedAnd(
739                    tiRoot_t         *root,
740                    sbit32 volatile  *Destination,
741                    sbit32            Value
742                    )
743 {
744   return 0;
745 }
746 
747 osGLOBAL FORCEINLINE sbit32
748 ostiInterlockedOr(
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.
760 osGLOBAL bit32
761 ostiSetDeviceQueueDepth( 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.
781 osGLOBAL void
782 ostiGetSenseKeyCount(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 
792 osGLOBAL void
793 ostiGetSCSIStatusCount(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 
804 osGLOBAL void ostiPCI_TRIGGER( tiRoot_t *tiRoot )
805 {
806   ostiChipReadBit32Ext(tiRoot, 0, 0x5C);
807 
808 }
809 
810 osGLOBAL bit32
811 ostiNumOfLUNIOCTLreq(  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