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