1 /******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
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
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.
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
21 ******************************************************************************/
23 /******************************************************************************
24 This program is part of PMC-Sierra initiator/target device driver.
25 The functions here are commonly used by different type of drivers that support
26 PMC-Sierra storage network initiator hardware.
27 ******************************************************************************/
30 MALLOC_DEFINE( M_PMC_MMAL, "agtiapi_MemAlloc malloc",
31 "allocated from agtiapi_MemAlloc as simple malloc case" );
34 /*****************************************************************************
38 Busy wait for number of mili-seconds
40 U32 MiliSeconds (IN) Number of mili-seconds to delay
43 *****************************************************************************/
44 STATIC void agtiapi_DelayMSec( U32 MiliSeconds )
46 DELAY(MiliSeconds * 1000); // DELAY takes in usecs
49 /******************************************************************************
52 Preallocation handling
53 Allocate DMA memory which will be divided among proper pointers in
54 agtiapi_MemAlloc() later
56 ag_card_info_t *thisCardInst (IN)
58 AGTIAPI_SUCCESS - success
60 ******************************************************************************/
61 STATIC agBOOLEAN agtiapi_typhAlloc( ag_card_info_t *thisCardInst )
63 struct agtiapi_softc *pmsc = thisCardInst->pCard;
66 if( bus_dma_tag_create( agNULL, // parent
69 BUS_SPACE_MAXADDR, // lowaddr
70 BUS_SPACE_MAXADDR, // highaddr
73 pmsc->typhn, // maxsize (size)
74 1, // number of segments
75 pmsc->typhn, // maxsegsize
79 &pmsc->typh_dmat ) ) {
80 printf( "agtiapi_typhAlloc: Can't create no-cache mem tag\n" );
84 if( bus_dmamem_alloc( pmsc->typh_dmat,
86 BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE,
87 &pmsc->typh_mapp ) ) {
88 printf( "agtiapi_typhAlloc: Cannot allocate cache mem %d\n",
93 if ( bus_dmamap_load( pmsc->typh_dmat,
97 agtiapi_MemoryCB, // try reuse of CB for same goal
99 0 ) || !pmsc->typh_busaddr ) {
100 for( ; wait < 20; wait++ ) {
101 if( pmsc->typh_busaddr ) break;
105 if( ! pmsc->typh_busaddr ) {
106 printf( "agtiapi_typhAlloc: cache mem won't load %d\n",
115 return AGTIAPI_SUCCESS;
119 /******************************************************************************
120 agtiapi_InitResource()
122 Mapping PCI memory space
123 Allocate and initialize per card based resource
125 ag_card_info_t *pCardInfo (IN)
127 AGTIAPI_SUCCESS - success
130 ******************************************************************************/
131 STATIC agBOOLEAN agtiapi_InitResource( ag_card_info_t *thisCardInst )
133 struct agtiapi_softc *pmsc = thisCardInst->pCard;
134 device_t devx = thisCardInst->pPCIDev;
136 //AGTIAPI_PRINTK( "agtiapi_InitResource: begin; pointer values %p / %p \n",
137 // devx, thisCardInst );
138 // no IO mapped card implementation, we'll implement memory mapping
140 if( agtiapi_typhAlloc( thisCardInst ) == AGTIAPI_FAIL ) {
141 printf( "agtiapi_InitResource: failed call to agtiapi_typhAlloc \n" );
145 AGTIAPI_PRINTK( "agtiapi_InitResource: dma alloc MemSpan %p -- %p\n",
146 (void*) pmsc->typh_busaddr,
147 (void*) ( (U32_64)pmsc->typh_busaddr + pmsc->typhn ) );
149 // logical BARs for SPC:
150 // bar 0 and 1 - logical BAR0
151 // bar 2 and 3 - logical BAR1
152 // bar4 - logical BAR2
153 // bar5 - logical BAR3
154 // Skiping the assignments for bar 1 and bar 3 (making bar 0, 2 64-bit):
156 U32 lBar = 0; // logicalBar
157 for (bar = 0; bar < PCI_NUMBER_BARS; bar++) {
158 if ((bar==1) || (bar==3))
160 thisCardInst->pciMemBaseRIDSpc[lBar] = PCIR_BAR(bar);
161 thisCardInst->pciMemBaseRscSpc[lBar] =
162 bus_alloc_resource_any( devx,
164 &(thisCardInst->pciMemBaseRIDSpc[lBar]),
166 AGTIAPI_PRINTK( "agtiapi_InitResource: bus_alloc_resource_any rtn %p \n",
167 thisCardInst->pciMemBaseRscSpc[lBar] );
168 if ( thisCardInst->pciMemBaseRscSpc[lBar] != NULL ) {
169 thisCardInst->pciMemVirtAddrSpc[lBar] =
170 (caddr_t)rman_get_virtual(
171 thisCardInst->pciMemBaseRscSpc[lBar] );
172 thisCardInst->pciMemBaseSpc[lBar] =
173 bus_get_resource_start( devx, SYS_RES_MEMORY,
174 thisCardInst->pciMemBaseRIDSpc[lBar]);
175 thisCardInst->pciMemSizeSpc[lBar] =
176 bus_get_resource_count( devx, SYS_RES_MEMORY,
177 thisCardInst->pciMemBaseRIDSpc[lBar] );
178 AGTIAPI_PRINTK( "agtiapi_InitResource: PCI: bar %d, lBar %d "
179 "VirtAddr=%lx, len=%d\n", bar, lBar,
180 (long unsigned int)thisCardInst->pciMemVirtAddrSpc[lBar],
181 thisCardInst->pciMemSizeSpc[lBar] );
184 thisCardInst->pciMemVirtAddrSpc[lBar] = 0;
185 thisCardInst->pciMemBaseSpc[lBar] = 0;
186 thisCardInst->pciMemSizeSpc[lBar] = 0;
190 thisCardInst->pciMemVirtAddr = thisCardInst->pciMemVirtAddrSpc[0];
191 thisCardInst->pciMemSize = thisCardInst->pciMemSizeSpc[0];
192 thisCardInst->pciMemBase = thisCardInst->pciMemBaseSpc[0];
194 // Allocate all TI data structure required resources.
197 ag_resource_info_t *pRscInfo;
198 pRscInfo = &thisCardInst->tiRscInfo;
199 pRscInfo->tiLoLevelResource.loLevelOption.pciFunctionNumber =
200 pci_get_function( devx );
206 ticksPerSec = tvtohz( &tv );
207 int uSecPerTick = 1000000/USEC_PER_TICK;
209 if (pRscInfo->tiLoLevelResource.loLevelMem.count != 0) {
210 //AGTIAPI_INIT("agtiapi_InitResource: loLevelMem count = %d\n",
211 // pRscInfo->tiLoLevelResource.loLevelMem.count);
213 // adjust tick value to meet Linux requirement
214 pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick = uSecPerTick;
215 AGTIAPI_PRINTK( "agtiapi_InitResource: "
216 "pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick"
218 pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick );
219 for( numVal = 0; numVal < pRscInfo->tiLoLevelResource.loLevelMem.count;
221 if( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength ==
223 AGTIAPI_PRINTK("agtiapi_InitResource: skip ZERO %d\n", numVal);
227 // check for 64 bit alignment
228 if ( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment <
229 AGTIAPI_64BIT_ALIGN ) {
230 AGTIAPI_PRINTK("agtiapi_InitResource: set ALIGN %d\n", numVal);
231 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment =
234 if( ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
235 & (BIT(0) | BIT(1))) == TI_DMA_MEM) ||
236 ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
237 & (BIT(0) | BIT(1))) == TI_CACHED_DMA_MEM)) {
238 if ( thisCardInst->dmaIndex >=
239 sizeof(thisCardInst->tiDmaMem) /
240 sizeof(thisCardInst->tiDmaMem[0]) ) {
241 AGTIAPI_PRINTK( "Invalid dmaIndex %d ERROR\n",
242 thisCardInst->dmaIndex );
245 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type =
247 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
252 if( agtiapi_MemAlloc( thisCardInst,
253 &thisCardInst->tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr,
254 &thisCardInst->tiDmaMem[thisCardInst->dmaIndex].dmaPhysAddr,
255 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
256 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].
258 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].
260 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
261 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type,
262 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment)
263 != AGTIAPI_SUCCESS ) {
266 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].memSize =
267 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength;
268 //AGTIAPI_INIT("agtiapi_InitResource: LoMem %d dmaIndex=%d DMA virt"
269 // " %p, phys 0x%x, length %d align %d\n",
270 // numVal, pCardInfo->dmaIndex,
271 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
272 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].physAddrLower,
273 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
274 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment);
275 thisCardInst->dmaIndex++;
277 else if ( (pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type &
278 (BIT(0) | BIT(1))) == TI_CACHED_MEM) {
279 if (thisCardInst->cacheIndex >=
280 sizeof(thisCardInst->tiCachedMem) /
281 sizeof(thisCardInst->tiCachedMem[0])) {
282 AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n",
283 thisCardInst->cacheIndex );
286 if ( agtiapi_MemAlloc( thisCardInst,
287 &thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
288 (vm_paddr_t *)agNULL,
289 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
292 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
294 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment)
295 != AGTIAPI_SUCCESS ) {
299 //AGTIAPI_INIT("agtiapi_InitResource: LoMem %d cacheIndex=%d CACHED "
300 // "vaddr %p / %p, length %d align %d\n",
301 // numVal, pCardInfo->cacheIndex,
302 // pCardInfo->tiCachedMem[pCardInfo->cacheIndex],
303 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
304 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
305 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment);
307 thisCardInst->cacheIndex++;
309 else if ( ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
310 & (BIT(0) | BIT(1))) == TI_DMA_MEM_CHIP)) {
311 // not expecting this case, print warning that should get attention
312 printf( "RED ALARM: we need a BAR for TI_DMA_MEM_CHIP, ignoring!" );
315 printf( "agtiapi_InitResource: Unknown required memory type %d "
317 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type);
322 // end: TI data structure resources ...
324 // begin: tiInitiatorResource
325 if ( pmsc->flags & AGTIAPI_INITIATOR ) {
326 if ( pRscInfo->tiInitiatorResource.initiatorMem.count != 0 ) {
327 //AGTIAPI_INIT("agtiapi_InitResource: initiatorMem count = %d\n",
328 // pRscInfo->tiInitiatorResource.initiatorMem.count);
330 (U32)( pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick
332 if( pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick
334 pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick =
335 (numVal + 1) * uSecPerTick;
337 pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick =
338 numVal * uSecPerTick;
340 numVal < pRscInfo->tiInitiatorResource.initiatorMem.count;
342 // check for 64 bit alignment
343 if( pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
344 alignment < AGTIAPI_64BIT_ALIGN ) {
345 pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
346 alignment = AGTIAPI_64BIT_ALIGN;
348 if( thisCardInst->cacheIndex >=
349 sizeof( thisCardInst->tiCachedMem) /
350 sizeof( thisCardInst->tiCachedMem[0])) {
351 AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n",
352 thisCardInst->cacheIndex );
355 // initiator memory is cached, no check is needed
356 if( agtiapi_MemAlloc( thisCardInst,
357 (void *)&thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
358 (vm_paddr_t *)agNULL,
359 &pRscInfo->tiInitiatorResource.initiatorMem.
360 tdCachedMem[numVal].virtPtr,
363 pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
366 pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
368 != AGTIAPI_SUCCESS) {
371 // AGTIAPI_INIT("agtiapi_InitResource: IniMem %d cacheIndex=%d CACHED "
372 // "vaddr %p / %p, length %d align 0x%x\n",
374 // pCardInfo->cacheIndex,
375 // pCardInfo->tiCachedMem[pCardInfo->cacheIndex],
376 // pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
378 //pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
380 // pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
382 thisCardInst->cacheIndex++;
386 // end: tiInitiatorResource
388 // begin: tiTdSharedMem
389 if (pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength != 0) {
390 // check for 64 bit alignment
391 if( pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment <
392 AGTIAPI_64BIT_ALIGN ) {
393 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment = AGTIAPI_64BIT_ALIGN;
395 if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type & (BIT(0) | BIT(1)))
397 if( thisCardInst->dmaIndex >=
398 sizeof(thisCardInst->tiDmaMem) / sizeof(thisCardInst->tiDmaMem[0]) ) {
399 AGTIAPI_PRINTK( "Invalid dmaIndex %d ERROR\n", thisCardInst->dmaIndex);
402 if( agtiapi_MemAlloc( thisCardInst, (void *)&thisCardInst->
403 tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr,
404 &thisCardInst->tiDmaMem[thisCardInst->dmaIndex].
406 &pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
407 &pRscInfo->tiSharedMem.tdSharedCachedMem1.
409 &pRscInfo->tiSharedMem.tdSharedCachedMem1.
411 pRscInfo->tiSharedMem.tdSharedCachedMem1.
414 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment)
418 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].memSize =
419 pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength +
420 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment;
421 // printf( "agtiapi_InitResource: SharedMem DmaIndex=%d DMA "
422 // "virt %p / %p, phys 0x%x, align %d\n",
423 // thisCardInst->dmaIndex,
424 // thisCardInst->tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr,
425 // pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
426 // pRscInfo->tiSharedMem.tdSharedCachedMem1.physAddrLower,
427 // pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment);
428 thisCardInst->dmaIndex++;
430 else if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type &
433 if( thisCardInst->cacheIndex >=
434 sizeof(thisCardInst->tiCachedMem) /
435 sizeof(thisCardInst->tiCachedMem[0]) ) {
436 AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n", thisCardInst->cacheIndex);
439 if( agtiapi_MemAlloc( thisCardInst, (void *)&thisCardInst->
440 tiCachedMem[thisCardInst->cacheIndex],
441 (vm_paddr_t *)agNULL,
442 &pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
446 tiSharedMem.tdSharedCachedMem1.totalLength,
448 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment)
451 // printf( "agtiapi_InitResource: SharedMem cacheIndex=%d CACHED "
452 // "vaddr %p / %p, length %d align 0x%x\n",
453 // thisCardInst->cacheIndex,
454 // thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
455 // pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
456 // pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength,
457 // pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment);
458 AGTIAPI_PRINTK( "agtiapi_InitResource: SharedMem cacheIndex=%d CACHED "
459 "vaddr %p / %p, length %d align 0x%x\n",
460 thisCardInst->cacheIndex,
461 thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
462 pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
463 pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength,
464 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment );
465 thisCardInst->cacheIndex++;
468 AGTIAPI_PRINTK( "agtiapi_InitResource: "
469 "Unknown required memory type ERROR!\n" );
473 // end: tiTdSharedMem
474 DELAY( 200000 ); // or use AGTIAPI_INIT_MDELAY(200);
475 return AGTIAPI_SUCCESS;
476 } // agtiapi_InitResource() ends here
478 /******************************************************************************
479 agtiapi_ScopeDMARes()
481 Determine the amount of DMA (non-cache) memory resources which will be
482 required for a card ( and necessarily allocated in agtiapi_InitResource() )
484 ag_card_info_t *thisCardInst (IN)
486 size of DMA memory which call to agtiapi_InitResource() will consume
488 this funcion mirrors the flow of agtiapi_InitResource()
489 results are stored in agtiapi_softc fields
490 ******************************************************************************/
491 STATIC int agtiapi_ScopeDMARes( ag_card_info_t *thisCardInst )
493 struct agtiapi_softc *pmsc = thisCardInst->pCard;
494 U32 lAllMem = 0; // total memory count; typhn
495 U32 lTmpAlign, lTmpType, lTmpLen;
499 ag_resource_info_t *pRscInfo;
500 pRscInfo = &thisCardInst->tiRscInfo;
502 if (pRscInfo->tiLoLevelResource.loLevelMem.count != 0) {
503 for( numVal = 0; numVal < pRscInfo->tiLoLevelResource.loLevelMem.count;
505 if( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength ==
507 printf( "agtiapi_ScopeDMARes: skip ZERO %d\n", numVal );
510 // check for 64 bit alignment
511 lTmpAlign = pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment;
512 if( lTmpAlign < AGTIAPI_64BIT_ALIGN ) {
513 AGTIAPI_PRINTK("agtiapi_ScopeDMARes: set ALIGN %d\n", numVal);
514 //pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment =
515 lTmpAlign = AGTIAPI_64BIT_ALIGN;
517 if( ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
518 & (BIT(0) | BIT(1))) == TI_DMA_MEM) ||
519 ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
520 & (BIT(0) | BIT(1))) == TI_CACHED_DMA_MEM)) {
521 //thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type =
524 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
529 if( lTmpType == TI_DMA_MEM ) {
531 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength;
532 lAllMem += lTmpLen + lTmpAlign;
534 //printf( "agtiapi_ScopeDMARes: call 1 0x%x\n", lAllMem );
536 else if ( ( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type &
537 (BIT(0) | BIT(1)) ) == TI_CACHED_MEM ) {
538 // these are not the droids we're looking for
539 if( thisCardInst->cacheIndex >=
540 sizeof(thisCardInst->tiCachedMem) /
541 sizeof(thisCardInst->tiCachedMem[0]) ) {
542 AGTIAPI_PRINTK( "agtiapi_ScopeDMARes: Invalid cacheIndex %d ERROR\n",
543 thisCardInst->cacheIndex );
548 printf( "agtiapi_ScopeDMARes: Unknown required memory type %d "
550 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type );
555 // end: TI data structure resources ...
557 // nothing for tiInitiatorResource
559 // begin: tiTdSharedMem
560 if (pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength != 0) {
561 // check for 64 bit alignment
562 lTmpAlign = pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment;
563 if( lTmpAlign < AGTIAPI_64BIT_ALIGN ) {
564 //pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment=AGTIAPI_64BIT_ALIGN;
565 lTmpAlign = AGTIAPI_64BIT_ALIGN;
567 if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type & (BIT(0) | BIT(1)))
569 lTmpLen = pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength;
570 lAllMem += lTmpLen + lTmpAlign;
571 // printf( "agtiapi_ScopeDMARes: call 4D 0x%x\n", lAllMem );
573 else if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type &
576 printf( "agtiapi_ScopeDMARes: Unknown required memory type ERROR!\n" );
579 // end: tiTdSharedMem
581 pmsc->typhn = lAllMem;
584 } // agtiapi_ScopeDMARes() ends here
587 STATIC void agtiapi_ReleasePCIMem( ag_card_info_t *pCardInfo ) {
590 struct resource *tmpRsc = NULL;
592 dev = pCardInfo->pPCIDev;
594 for (bar=0; bar < PCI_NUMBER_BARS; bar++) { // clean up PCI resource
595 tmpRid = pCardInfo->pciMemBaseRIDSpc[bar];
596 tmpRsc = pCardInfo->pciMemBaseRscSpc[bar];
597 if (tmpRsc != NULL) { // Release PCI resources
598 bus_release_resource( dev, SYS_RES_MEMORY, tmpRid, tmpRsc );
605 /******************************************************************************
608 Handle various memory allocation requests.
610 ag_card_info_t *pCardInfo (IN) Pointer to card info structure
611 void **VirtAlloc (OUT) Allocated memory virtual address
612 dma_addr_t *pDmaAddr (OUT) Allocated dma memory physical address
613 void **VirtAddr (OUT) Aligned memory virtual address
614 U32 *pPhysAddrUp (OUT) Allocated memory physical upper 32 bits
615 U32 *pPhysAddrLow (OUT) Allocated memory physical lower 32 bits
616 U32 MemSize (IN) Allocated memory size
617 U32 Type (IN) Type of memory required
618 U32 Align (IN) Required memory alignment
620 AGTIAPI_SUCCESS - success
622 ******************************************************************************/
623 STATIC agBOOLEAN agtiapi_MemAlloc( ag_card_info_t *thisCardInst,
625 vm_paddr_t *pDmaAddr,
633 U32_64 alignOffset = 0;
635 alignOffset = Align - 1;
637 // printf( "agtiapi_MemAlloc: debug find mem TYPE, %d vs. CACHE %d, DMA %d \n",
638 // ( Type & ( BIT(0) | BIT(1) ) ), TI_CACHED_MEM, TI_DMA_MEM );
640 if ((Type & (BIT(0) | BIT(1))) == TI_CACHED_MEM) {
641 *VirtAlloc = malloc( MemSize + Align, M_PMC_MMAL, M_ZERO | M_NOWAIT );
642 *VirtAddr = (void *)(((U32_64)*VirtAlloc + alignOffset) & ~alignOffset);
645 struct agtiapi_softc *pmsc = thisCardInst->pCard; // get card reference
647 // find virt index value
648 *VirtAlloc = (void*)( (U64)pmsc->typh_mem + pmsc->typhIdx );
649 *VirtAddr = (void *)( ( (U32_64)*VirtAlloc + alignOffset) & ~alignOffset );
650 if( *VirtAddr != *VirtAlloc )
651 residAlign = (U64)*VirtAddr - (U64)*VirtAlloc; // find alignment needed
652 pmsc->typhIdx += residAlign + MemSize; // update index
653 residAlign = 0; // reset variable for reuse
654 // find phys index val
655 pDmaAddr = (vm_paddr_t*)( (U64)pmsc->typh_busaddr + pmsc->tyPhsIx );
656 vm_paddr_t *lPhysAligned =
657 (vm_paddr_t*)( ( (U64)pDmaAddr + alignOffset ) & ~alignOffset );
658 if( lPhysAligned != pDmaAddr )
659 residAlign = (U64)lPhysAligned - (U64)pDmaAddr; // find alignment needed
660 pmsc->tyPhsIx += residAlign + MemSize; // update index
661 *pPhysAddrUp = HIGH_32_BITS( (U64)lPhysAligned );
662 *pPhysAddrLow = LOW_32_BITS( (U64)lPhysAligned );
663 //printf( "agtiapi_MemAlloc: physIx 0x%x size 0x%x resid:0x%x "
664 // "addr:0x%p addrAligned:0x%p Align:0x%x\n",
665 // pmsc->tyPhsIx, MemSize, residAlign, pDmaAddr, lPhysAligned,
669 AGTIAPI_PRINTK( "agtiapi_MemAlloc memory allocation ERROR x%x\n",
670 Type & (U32)(BIT(0) | BIT(1)));
673 return AGTIAPI_SUCCESS;
677 /******************************************************************************
681 Free agtiapi_MemAlloc() allocated memory
683 ag_card_info_t *pCardInfo (IN) Pointer to card info structure
685 ******************************************************************************/
686 STATIC void agtiapi_MemFree( ag_card_info_t *pCardInfo )
690 // release memory vs. alloc in agtiapi_MemAlloc; cached case
691 for( idx = 0; idx < pCardInfo->cacheIndex; idx++ ) {
692 if( pCardInfo->tiCachedMem[idx] ) {
693 free( pCardInfo->tiCachedMem[idx], M_PMC_MMAL );
694 AGTIAPI_PRINTK( "agtiapi_MemFree: TI_CACHED_MEM Mem[%d] %p\n",
695 idx, pCardInfo->tiCachedMem[idx] );
699 // release memory vs. alloc in agtiapi_typhAlloc; used in agtiapi_MemAlloc
700 struct agtiapi_softc *pmsc = pCardInfo->pCard; // get card reference
701 if( pmsc->typh_busaddr != 0 ) {
702 bus_dmamap_unload( pmsc->typh_dmat, pmsc->typh_mapp );
704 if( pmsc->typh_mem != NULL ) {
705 bus_dmamem_free( pmsc->typh_dmat, pmsc->typh_mem, pmsc->typh_mapp );
707 if( pmsc->typh_dmat != NULL ) {
708 bus_dma_tag_destroy( pmsc->typh_dmat );
711 // pCardInfo->dmaIndex
712 // pCardInfo->tiDmaMem[idx].dmaVirtAddr
713 // pCardInfo->tiDmaMem[idx].memSize
714 // pCardInfo->tiDmaMem[idx].type == TI_CACHED_DMA_MEM
715 // pCardInfo->tiDmaMem[idx].type == TI_DMA_MEM
717 /* This code is redundant. Commenting out for now to maintain a placekeeper.
718 Free actually takes place in agtiapi_ReleaseHBA as calls on osti_dmat. dm
719 // release possible lower layer dynamic memory
720 for( idx = 0; idx < AGTIAPI_DYNAMIC_MAX; idx++ ) {
721 if( pCardInfo->dynamicMem[idx].dmaVirtAddr != NULL ) {
722 printf( "agtiapi_MemFree: dynMem[%d] virtAddr"
723 " %p / %lx size: %d\n",
724 idx, pCardInfo->dynamicMem[idx].dmaVirtAddr,
725 (long unsigned int)pCardInfo->dynamicMem[idx].dmaPhysAddr,
726 pCardInfo->dynamicMem[idx].memSize );
727 if( pCardInfo->dynamicMem[idx].dmaPhysAddr )
728 some form of free call would go here (
729 pCardInfo->dynamicMem[idx].dmaVirtAddr,
730 pCardInfo->dynamicMem[idx].memSize, ... );
732 free case for cacheable memory would go here
739 /******************************************************************************
742 sets thisCardInst->cardIdIndex to structure variant consistent with card.
743 ag_card_type[idx].vendorId we already determined is PCI_VENDOR_ID_PMC_SIERRA.
746 ag_card_info_t *thisCardInst,
750 other values are not as good
752 This implementation is tailored to FreeBSD in alignment with the probe
753 functionality of the FreeBSD environment.
754 ******************************************************************************/
755 STATIC int agtiapi_ProbeCard( device_t dev,
756 ag_card_info_t *thisCardInst,
760 u_int16_t agtiapi_vendor; // PCI vendor ID
761 u_int16_t agtiapi_dev; // PCI device ID
762 AGTIAPI_PRINTK("agtiapi_ProbeCard: start\n");
764 agtiapi_vendor = pci_get_vendor( dev ); // get PCI vendor ID
765 agtiapi_dev = pci_get_device( dev ); // get PCI device ID
766 for( idx = 0; idx < COUNT(ag_card_type); idx++ )
768 if ( ag_card_type[idx].deviceId == agtiapi_dev &&
769 ag_card_type[idx].vendorId == agtiapi_vendor)
771 memset( (void *)&agCardInfoList[ thisCard ], 0,
772 sizeof(ag_card_info_t) );
773 thisCardInst->cardIdIndex = idx;
774 thisCardInst->pPCIDev = dev;
775 thisCardInst->cardNameIndex = ag_card_type[idx].cardNameIndex;
776 thisCardInst->cardID =
777 pci_read_config( dev, ag_card_type[idx].membar, 4 ); // memAddr
778 AGTIAPI_PRINTK("agtiapi_ProbeCard: We've got PMC SAS, probe successful %p / %p\n",
779 thisCardInst->pPCIDev, thisCardInst );
780 device_set_desc( dev, ag_card_names[ag_card_type[idx].cardNameIndex] );