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 ******************************************************************************/
22 /******************************************************************************
23 This program is part of PMC-Sierra initiator/target device driver.
24 The functions here are commonly used by different type of drivers that support
25 PMC-Sierra storage network initiator hardware.
26 ******************************************************************************/
29 MALLOC_DEFINE( M_PMC_MMAL, "agtiapi_MemAlloc malloc",
30 "allocated from agtiapi_MemAlloc as simple malloc case" );
33 /*****************************************************************************
37 Busy wait for number of mili-seconds
39 U32 MiliSeconds (IN) Number of mili-seconds to delay
42 *****************************************************************************/
43 STATIC void agtiapi_DelayMSec( U32 MiliSeconds )
45 DELAY(MiliSeconds * 1000); // DELAY takes in usecs
48 /******************************************************************************
51 Preallocation handling
52 Allocate DMA memory which will be divided among proper pointers in
53 agtiapi_MemAlloc() later
55 ag_card_info_t *thisCardInst (IN)
57 AGTIAPI_SUCCESS - success
59 ******************************************************************************/
60 STATIC agBOOLEAN agtiapi_typhAlloc( ag_card_info_t *thisCardInst )
62 struct agtiapi_softc *pmsc = thisCardInst->pCard;
65 if( bus_dma_tag_create( agNULL, // parent
68 BUS_SPACE_MAXADDR, // lowaddr
69 BUS_SPACE_MAXADDR, // highaddr
72 pmsc->typhn, // maxsize (size)
73 1, // number of segments
74 pmsc->typhn, // maxsegsize
78 &pmsc->typh_dmat ) ) {
79 printf( "agtiapi_typhAlloc: Can't create no-cache mem tag\n" );
83 if( bus_dmamem_alloc( pmsc->typh_dmat,
85 BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE,
86 &pmsc->typh_mapp ) ) {
87 printf( "agtiapi_typhAlloc: Cannot allocate cache mem %d\n",
92 if ( bus_dmamap_load( pmsc->typh_dmat,
96 agtiapi_MemoryCB, // try reuse of CB for same goal
98 0 ) || !pmsc->typh_busaddr ) {
99 for( ; wait < 20; wait++ ) {
100 if( pmsc->typh_busaddr ) break;
104 if( ! pmsc->typh_busaddr ) {
105 printf( "agtiapi_typhAlloc: cache mem won't load %d\n",
114 return AGTIAPI_SUCCESS;
118 /******************************************************************************
119 agtiapi_InitResource()
121 Mapping PCI memory space
122 Allocate and initialize per card based resource
124 ag_card_info_t *pCardInfo (IN)
126 AGTIAPI_SUCCESS - success
129 ******************************************************************************/
130 STATIC agBOOLEAN agtiapi_InitResource( ag_card_info_t *thisCardInst )
132 struct agtiapi_softc *pmsc = thisCardInst->pCard;
133 device_t devx = thisCardInst->pPCIDev;
135 //AGTIAPI_PRINTK( "agtiapi_InitResource: begin; pointer values %p / %p \n",
136 // devx, thisCardInst );
137 // no IO mapped card implementation, we'll implement memory mapping
139 if( agtiapi_typhAlloc( thisCardInst ) == AGTIAPI_FAIL ) {
140 printf( "agtiapi_InitResource: failed call to agtiapi_typhAlloc \n" );
144 AGTIAPI_PRINTK( "agtiapi_InitResource: dma alloc MemSpan %p -- %p\n",
145 (void*) pmsc->typh_busaddr,
146 (void*) ( (U32_64)pmsc->typh_busaddr + pmsc->typhn ) );
148 // logical BARs for SPC:
149 // bar 0 and 1 - logical BAR0
150 // bar 2 and 3 - logical BAR1
151 // bar4 - logical BAR2
152 // bar5 - logical BAR3
153 // Skiping the assignments for bar 1 and bar 3 (making bar 0, 2 64-bit):
155 U32 lBar = 0; // logicalBar
156 for (bar = 0; bar < PCI_NUMBER_BARS; bar++) {
157 if ((bar==1) || (bar==3))
159 thisCardInst->pciMemBaseRIDSpc[lBar] = PCIR_BAR(bar);
160 thisCardInst->pciMemBaseRscSpc[lBar] =
161 bus_alloc_resource_any( devx,
163 &(thisCardInst->pciMemBaseRIDSpc[lBar]),
165 AGTIAPI_PRINTK( "agtiapi_InitResource: bus_alloc_resource_any rtn %p \n",
166 thisCardInst->pciMemBaseRscSpc[lBar] );
167 if ( thisCardInst->pciMemBaseRscSpc[lBar] != NULL ) {
168 thisCardInst->pciMemVirtAddrSpc[lBar] =
169 (caddr_t)rman_get_virtual(
170 thisCardInst->pciMemBaseRscSpc[lBar] );
171 thisCardInst->pciMemBaseSpc[lBar] =
172 bus_get_resource_start( devx, SYS_RES_MEMORY,
173 thisCardInst->pciMemBaseRIDSpc[lBar]);
174 thisCardInst->pciMemSizeSpc[lBar] =
175 bus_get_resource_count( devx, SYS_RES_MEMORY,
176 thisCardInst->pciMemBaseRIDSpc[lBar] );
177 AGTIAPI_PRINTK( "agtiapi_InitResource: PCI: bar %d, lBar %d "
178 "VirtAddr=%lx, len=%d\n", bar, lBar,
179 (long unsigned int)thisCardInst->pciMemVirtAddrSpc[lBar],
180 thisCardInst->pciMemSizeSpc[lBar] );
183 thisCardInst->pciMemVirtAddrSpc[lBar] = 0;
184 thisCardInst->pciMemBaseSpc[lBar] = 0;
185 thisCardInst->pciMemSizeSpc[lBar] = 0;
189 thisCardInst->pciMemVirtAddr = thisCardInst->pciMemVirtAddrSpc[0];
190 thisCardInst->pciMemSize = thisCardInst->pciMemSizeSpc[0];
191 thisCardInst->pciMemBase = thisCardInst->pciMemBaseSpc[0];
193 // Allocate all TI data structure required resources.
196 ag_resource_info_t *pRscInfo;
197 pRscInfo = &thisCardInst->tiRscInfo;
198 pRscInfo->tiLoLevelResource.loLevelOption.pciFunctionNumber =
199 pci_get_function( devx );
205 ticksPerSec = tvtohz( &tv );
206 int uSecPerTick = 1000000/USEC_PER_TICK;
208 if (pRscInfo->tiLoLevelResource.loLevelMem.count != 0) {
209 //AGTIAPI_INIT("agtiapi_InitResource: loLevelMem count = %d\n",
210 // pRscInfo->tiLoLevelResource.loLevelMem.count);
212 // adjust tick value to meet Linux requirement
213 pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick = uSecPerTick;
214 AGTIAPI_PRINTK( "agtiapi_InitResource: "
215 "pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick"
217 pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick );
218 for( numVal = 0; numVal < pRscInfo->tiLoLevelResource.loLevelMem.count;
220 if( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength ==
222 AGTIAPI_PRINTK("agtiapi_InitResource: skip ZERO %d\n", numVal);
226 // check for 64 bit alignment
227 if ( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment <
228 AGTIAPI_64BIT_ALIGN ) {
229 AGTIAPI_PRINTK("agtiapi_InitResource: set ALIGN %d\n", numVal);
230 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment =
233 if( ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
234 & (BIT(0) | BIT(1))) == TI_DMA_MEM) ||
235 ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
236 & (BIT(0) | BIT(1))) == TI_CACHED_DMA_MEM)) {
237 if ( thisCardInst->dmaIndex >=
238 sizeof(thisCardInst->tiDmaMem) /
239 sizeof(thisCardInst->tiDmaMem[0]) ) {
240 AGTIAPI_PRINTK( "Invalid dmaIndex %d ERROR\n",
241 thisCardInst->dmaIndex );
244 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type =
246 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
251 if( agtiapi_MemAlloc( thisCardInst,
252 &thisCardInst->tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr,
253 &thisCardInst->tiDmaMem[thisCardInst->dmaIndex].dmaPhysAddr,
254 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
255 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].
257 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].
259 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
260 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type,
261 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment)
262 != AGTIAPI_SUCCESS ) {
265 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].memSize =
266 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength;
267 //AGTIAPI_INIT("agtiapi_InitResource: LoMem %d dmaIndex=%d DMA virt"
268 // " %p, phys 0x%x, length %d align %d\n",
269 // numVal, pCardInfo->dmaIndex,
270 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
271 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].physAddrLower,
272 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
273 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment);
274 thisCardInst->dmaIndex++;
276 else if ( (pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type &
277 (BIT(0) | BIT(1))) == TI_CACHED_MEM) {
278 if (thisCardInst->cacheIndex >=
279 sizeof(thisCardInst->tiCachedMem) /
280 sizeof(thisCardInst->tiCachedMem[0])) {
281 AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n",
282 thisCardInst->cacheIndex );
285 if ( agtiapi_MemAlloc( thisCardInst,
286 &thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
287 (vm_paddr_t *)agNULL,
288 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
291 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
293 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment)
294 != AGTIAPI_SUCCESS ) {
298 //AGTIAPI_INIT("agtiapi_InitResource: LoMem %d cacheIndex=%d CACHED "
299 // "vaddr %p / %p, length %d align %d\n",
300 // numVal, pCardInfo->cacheIndex,
301 // pCardInfo->tiCachedMem[pCardInfo->cacheIndex],
302 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
303 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
304 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment);
306 thisCardInst->cacheIndex++;
308 else if ( ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
309 & (BIT(0) | BIT(1))) == TI_DMA_MEM_CHIP)) {
310 // not expecting this case, print warning that should get attention
311 printf( "RED ALARM: we need a BAR for TI_DMA_MEM_CHIP, ignoring!" );
314 printf( "agtiapi_InitResource: Unknown required memory type %d "
316 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type);
321 // end: TI data structure resources ...
323 // begin: tiInitiatorResource
324 if ( pmsc->flags & AGTIAPI_INITIATOR ) {
325 if ( pRscInfo->tiInitiatorResource.initiatorMem.count != 0 ) {
326 //AGTIAPI_INIT("agtiapi_InitResource: initiatorMem count = %d\n",
327 // pRscInfo->tiInitiatorResource.initiatorMem.count);
329 (U32)( pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick
331 if( pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick
333 pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick =
334 (numVal + 1) * uSecPerTick;
336 pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick =
337 numVal * uSecPerTick;
339 numVal < pRscInfo->tiInitiatorResource.initiatorMem.count;
341 // check for 64 bit alignment
342 if( pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
343 alignment < AGTIAPI_64BIT_ALIGN ) {
344 pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
345 alignment = AGTIAPI_64BIT_ALIGN;
347 if( thisCardInst->cacheIndex >=
348 sizeof( thisCardInst->tiCachedMem) /
349 sizeof( thisCardInst->tiCachedMem[0])) {
350 AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n",
351 thisCardInst->cacheIndex );
354 // initiator memory is cached, no check is needed
355 if( agtiapi_MemAlloc( thisCardInst,
356 (void *)&thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
357 (vm_paddr_t *)agNULL,
358 &pRscInfo->tiInitiatorResource.initiatorMem.
359 tdCachedMem[numVal].virtPtr,
362 pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
365 pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
367 != AGTIAPI_SUCCESS) {
370 // AGTIAPI_INIT("agtiapi_InitResource: IniMem %d cacheIndex=%d CACHED "
371 // "vaddr %p / %p, length %d align 0x%x\n",
373 // pCardInfo->cacheIndex,
374 // pCardInfo->tiCachedMem[pCardInfo->cacheIndex],
375 // pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
377 //pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
379 // pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
381 thisCardInst->cacheIndex++;
385 // end: tiInitiatorResource
387 // begin: tiTdSharedMem
388 if (pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength != 0) {
389 // check for 64 bit alignment
390 if( pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment <
391 AGTIAPI_64BIT_ALIGN ) {
392 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment = AGTIAPI_64BIT_ALIGN;
394 if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type & (BIT(0) | BIT(1)))
396 if( thisCardInst->dmaIndex >=
397 sizeof(thisCardInst->tiDmaMem) / sizeof(thisCardInst->tiDmaMem[0]) ) {
398 AGTIAPI_PRINTK( "Invalid dmaIndex %d ERROR\n", thisCardInst->dmaIndex);
401 if( agtiapi_MemAlloc( thisCardInst, (void *)&thisCardInst->
402 tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr,
403 &thisCardInst->tiDmaMem[thisCardInst->dmaIndex].
405 &pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
406 &pRscInfo->tiSharedMem.tdSharedCachedMem1.
408 &pRscInfo->tiSharedMem.tdSharedCachedMem1.
410 pRscInfo->tiSharedMem.tdSharedCachedMem1.
413 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment)
417 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].memSize =
418 pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength +
419 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment;
420 // printf( "agtiapi_InitResource: SharedMem DmaIndex=%d DMA "
421 // "virt %p / %p, phys 0x%x, align %d\n",
422 // thisCardInst->dmaIndex,
423 // thisCardInst->tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr,
424 // pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
425 // pRscInfo->tiSharedMem.tdSharedCachedMem1.physAddrLower,
426 // pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment);
427 thisCardInst->dmaIndex++;
429 else if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type &
432 if( thisCardInst->cacheIndex >=
433 sizeof(thisCardInst->tiCachedMem) /
434 sizeof(thisCardInst->tiCachedMem[0]) ) {
435 AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n", thisCardInst->cacheIndex);
438 if( agtiapi_MemAlloc( thisCardInst, (void *)&thisCardInst->
439 tiCachedMem[thisCardInst->cacheIndex],
440 (vm_paddr_t *)agNULL,
441 &pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
445 tiSharedMem.tdSharedCachedMem1.totalLength,
447 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment)
450 // printf( "agtiapi_InitResource: SharedMem cacheIndex=%d CACHED "
451 // "vaddr %p / %p, length %d align 0x%x\n",
452 // thisCardInst->cacheIndex,
453 // thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
454 // pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
455 // pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength,
456 // pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment);
457 AGTIAPI_PRINTK( "agtiapi_InitResource: SharedMem cacheIndex=%d CACHED "
458 "vaddr %p / %p, length %d align 0x%x\n",
459 thisCardInst->cacheIndex,
460 thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
461 pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
462 pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength,
463 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment );
464 thisCardInst->cacheIndex++;
467 AGTIAPI_PRINTK( "agtiapi_InitResource: "
468 "Unknown required memory type ERROR!\n" );
472 // end: tiTdSharedMem
473 DELAY( 200000 ); // or use AGTIAPI_INIT_MDELAY(200);
474 return AGTIAPI_SUCCESS;
475 } // agtiapi_InitResource() ends here
477 /******************************************************************************
478 agtiapi_ScopeDMARes()
480 Determine the amount of DMA (non-cache) memory resources which will be
481 required for a card ( and necessarily allocated in agtiapi_InitResource() )
483 ag_card_info_t *thisCardInst (IN)
485 size of DMA memory which call to agtiapi_InitResource() will consume
487 this funcion mirrors the flow of agtiapi_InitResource()
488 results are stored in agtiapi_softc fields
489 ******************************************************************************/
490 STATIC int agtiapi_ScopeDMARes( ag_card_info_t *thisCardInst )
492 struct agtiapi_softc *pmsc = thisCardInst->pCard;
493 U32 lAllMem = 0; // total memory count; typhn
494 U32 lTmpAlign, lTmpType, lTmpLen;
498 ag_resource_info_t *pRscInfo;
499 pRscInfo = &thisCardInst->tiRscInfo;
501 if (pRscInfo->tiLoLevelResource.loLevelMem.count != 0) {
502 for( numVal = 0; numVal < pRscInfo->tiLoLevelResource.loLevelMem.count;
504 if( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength ==
506 printf( "agtiapi_ScopeDMARes: skip ZERO %d\n", numVal );
509 // check for 64 bit alignment
510 lTmpAlign = pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment;
511 if( lTmpAlign < AGTIAPI_64BIT_ALIGN ) {
512 AGTIAPI_PRINTK("agtiapi_ScopeDMARes: set ALIGN %d\n", numVal);
513 //pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment =
514 lTmpAlign = AGTIAPI_64BIT_ALIGN;
516 if( ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
517 & (BIT(0) | BIT(1))) == TI_DMA_MEM) ||
518 ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
519 & (BIT(0) | BIT(1))) == TI_CACHED_DMA_MEM)) {
520 //thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type =
523 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
528 if( lTmpType == TI_DMA_MEM ) {
530 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength;
531 lAllMem += lTmpLen + lTmpAlign;
533 //printf( "agtiapi_ScopeDMARes: call 1 0x%x\n", lAllMem );
535 else if ( ( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type &
536 (BIT(0) | BIT(1)) ) == TI_CACHED_MEM ) {
537 // these are not the droids we're looking for
538 if( thisCardInst->cacheIndex >=
539 sizeof(thisCardInst->tiCachedMem) /
540 sizeof(thisCardInst->tiCachedMem[0]) ) {
541 AGTIAPI_PRINTK( "agtiapi_ScopeDMARes: Invalid cacheIndex %d ERROR\n",
542 thisCardInst->cacheIndex );
547 printf( "agtiapi_ScopeDMARes: Unknown required memory type %d "
549 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type );
554 // end: TI data structure resources ...
556 // nothing for tiInitiatorResource
558 // begin: tiTdSharedMem
559 if (pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength != 0) {
560 // check for 64 bit alignment
561 lTmpAlign = pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment;
562 if( lTmpAlign < AGTIAPI_64BIT_ALIGN ) {
563 //pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment=AGTIAPI_64BIT_ALIGN;
564 lTmpAlign = AGTIAPI_64BIT_ALIGN;
566 if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type & (BIT(0) | BIT(1)))
568 lTmpLen = pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength;
569 lAllMem += lTmpLen + lTmpAlign;
570 // printf( "agtiapi_ScopeDMARes: call 4D 0x%x\n", lAllMem );
572 else if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type &
575 printf( "agtiapi_ScopeDMARes: Unknown required memory type ERROR!\n" );
578 // end: tiTdSharedMem
580 pmsc->typhn = lAllMem;
583 } // agtiapi_ScopeDMARes() ends here
586 STATIC void agtiapi_ReleasePCIMem( ag_card_info_t *pCardInfo ) {
589 struct resource *tmpRsc = NULL;
591 dev = pCardInfo->pPCIDev;
593 for (bar=0; bar < PCI_NUMBER_BARS; bar++) { // clean up PCI resource
594 tmpRid = pCardInfo->pciMemBaseRIDSpc[bar];
595 tmpRsc = pCardInfo->pciMemBaseRscSpc[bar];
596 if (tmpRsc != NULL) { // Release PCI resources
597 bus_release_resource( dev, SYS_RES_MEMORY, tmpRid, tmpRsc );
604 /******************************************************************************
607 Handle various memory allocation requests.
609 ag_card_info_t *pCardInfo (IN) Pointer to card info structure
610 void **VirtAlloc (OUT) Allocated memory virtual address
611 dma_addr_t *pDmaAddr (OUT) Allocated dma memory physical address
612 void **VirtAddr (OUT) Aligned memory virtual address
613 U32 *pPhysAddrUp (OUT) Allocated memory physical upper 32 bits
614 U32 *pPhysAddrLow (OUT) Allocated memory physical lower 32 bits
615 U32 MemSize (IN) Allocated memory size
616 U32 Type (IN) Type of memory required
617 U32 Align (IN) Required memory alignment
619 AGTIAPI_SUCCESS - success
621 ******************************************************************************/
622 STATIC agBOOLEAN agtiapi_MemAlloc( ag_card_info_t *thisCardInst,
624 vm_paddr_t *pDmaAddr,
632 U32_64 alignOffset = 0;
634 alignOffset = Align - 1;
636 // printf( "agtiapi_MemAlloc: debug find mem TYPE, %d vs. CACHE %d, DMA %d \n",
637 // ( Type & ( BIT(0) | BIT(1) ) ), TI_CACHED_MEM, TI_DMA_MEM );
639 if ((Type & (BIT(0) | BIT(1))) == TI_CACHED_MEM) {
640 *VirtAlloc = malloc( MemSize + Align, M_PMC_MMAL, M_ZERO | M_NOWAIT );
641 *VirtAddr = (void *)(((U32_64)*VirtAlloc + alignOffset) & ~alignOffset);
644 struct agtiapi_softc *pmsc = thisCardInst->pCard; // get card reference
646 // find virt index value
647 *VirtAlloc = (void*)( (U64)pmsc->typh_mem + pmsc->typhIdx );
648 *VirtAddr = (void *)( ( (U32_64)*VirtAlloc + alignOffset) & ~alignOffset );
649 if( *VirtAddr != *VirtAlloc )
650 residAlign = (U64)*VirtAddr - (U64)*VirtAlloc; // find alignment needed
651 pmsc->typhIdx += residAlign + MemSize; // update index
652 residAlign = 0; // reset variable for reuse
653 // find phys index val
654 pDmaAddr = (vm_paddr_t*)( (U64)pmsc->typh_busaddr + pmsc->tyPhsIx );
655 vm_paddr_t *lPhysAligned =
656 (vm_paddr_t*)( ( (U64)pDmaAddr + alignOffset ) & ~alignOffset );
657 if( lPhysAligned != pDmaAddr )
658 residAlign = (U64)lPhysAligned - (U64)pDmaAddr; // find alignment needed
659 pmsc->tyPhsIx += residAlign + MemSize; // update index
660 *pPhysAddrUp = HIGH_32_BITS( (U64)lPhysAligned );
661 *pPhysAddrLow = LOW_32_BITS( (U64)lPhysAligned );
662 //printf( "agtiapi_MemAlloc: physIx 0x%x size 0x%x resid:0x%x "
663 // "addr:0x%p addrAligned:0x%p Align:0x%x\n",
664 // pmsc->tyPhsIx, MemSize, residAlign, pDmaAddr, lPhysAligned,
668 AGTIAPI_PRINTK( "agtiapi_MemAlloc memory allocation ERROR x%x\n",
669 Type & (U32)(BIT(0) | BIT(1)));
672 return AGTIAPI_SUCCESS;
676 /******************************************************************************
680 Free agtiapi_MemAlloc() allocated memory
682 ag_card_info_t *pCardInfo (IN) Pointer to card info structure
684 ******************************************************************************/
685 STATIC void agtiapi_MemFree( ag_card_info_t *pCardInfo )
689 // release memory vs. alloc in agtiapi_MemAlloc; cached case
690 for( idx = 0; idx < pCardInfo->cacheIndex; idx++ ) {
691 if( pCardInfo->tiCachedMem[idx] ) {
692 free( pCardInfo->tiCachedMem[idx], M_PMC_MMAL );
693 AGTIAPI_PRINTK( "agtiapi_MemFree: TI_CACHED_MEM Mem[%d] %p\n",
694 idx, pCardInfo->tiCachedMem[idx] );
698 // release memory vs. alloc in agtiapi_typhAlloc; used in agtiapi_MemAlloc
699 struct agtiapi_softc *pmsc = pCardInfo->pCard; // get card reference
700 if( pmsc->typh_busaddr != 0 ) {
701 bus_dmamap_unload( pmsc->typh_dmat, pmsc->typh_mapp );
703 if( pmsc->typh_mem != NULL ) {
704 bus_dmamem_free( pmsc->typh_dmat, pmsc->typh_mem, pmsc->typh_mapp );
706 if( pmsc->typh_dmat != NULL ) {
707 bus_dma_tag_destroy( pmsc->typh_dmat );
710 // pCardInfo->dmaIndex
711 // pCardInfo->tiDmaMem[idx].dmaVirtAddr
712 // pCardInfo->tiDmaMem[idx].memSize
713 // pCardInfo->tiDmaMem[idx].type == TI_CACHED_DMA_MEM
714 // pCardInfo->tiDmaMem[idx].type == TI_DMA_MEM
716 /* This code is redundant. Commenting out for now to maintain a placekeeper.
717 Free actually takes place in agtiapi_ReleaseHBA as calls on osti_dmat. dm
718 // release possible lower layer dynamic memory
719 for( idx = 0; idx < AGTIAPI_DYNAMIC_MAX; idx++ ) {
720 if( pCardInfo->dynamicMem[idx].dmaVirtAddr != NULL ) {
721 printf( "agtiapi_MemFree: dynMem[%d] virtAddr"
722 " %p / %lx size: %d\n",
723 idx, pCardInfo->dynamicMem[idx].dmaVirtAddr,
724 (long unsigned int)pCardInfo->dynamicMem[idx].dmaPhysAddr,
725 pCardInfo->dynamicMem[idx].memSize );
726 if( pCardInfo->dynamicMem[idx].dmaPhysAddr )
727 some form of free call would go here (
728 pCardInfo->dynamicMem[idx].dmaVirtAddr,
729 pCardInfo->dynamicMem[idx].memSize, ... );
731 free case for cacheable memory would go here
738 /******************************************************************************
741 sets thisCardInst->cardIdIndex to structure variant consistent with card.
742 ag_card_type[idx].vendorId we already determined is PCI_VENDOR_ID_PMC_SIERRA.
745 ag_card_info_t *thisCardInst,
749 other values are not as good
751 This implementation is tailored to FreeBSD in alignment with the probe
752 functionality of the FreeBSD environment.
753 ******************************************************************************/
754 STATIC int agtiapi_ProbeCard( device_t dev,
755 ag_card_info_t *thisCardInst,
759 static U32 cardMap[4] = { 0, 0, 0, 0 };
760 u_int16_t agtiapi_dev; // PCI device ID
761 AGTIAPI_PRINTK("agtiapi_ProbeCard: start\n");
763 if ( ! atomic_cmpset_32( &cardMap[thisCard], 0, 5 ) ) { // card already ran
764 AGTIAPI_PRINTK( "We'll only ID this card once -- %d\n", thisCard );
765 return 2; // error return value; card already ran this function
768 agtiapi_dev = pci_get_device( dev ); // get PCI device ID
769 for( idx = 0; idx < COUNT(ag_card_type); idx++ )
771 if( ag_card_type[idx].deviceId == agtiapi_dev )
773 memset( (void *)&agCardInfoList[ thisCard ], 0,
774 sizeof(ag_card_info_t) );
775 thisCardInst->cardIdIndex = idx;
776 thisCardInst->pPCIDev = dev;
777 thisCardInst->cardNameIndex = ag_card_type[idx].cardNameIndex;
778 thisCardInst->cardID =
779 pci_read_config( dev, ag_card_type[idx].membar, 4 ); // memAddr
780 AGTIAPI_PRINTK("agtiapi_ProbeCard: We've got PMC SAS, probe successful %p / %p\n",
781 thisCardInst->pPCIDev, thisCardInst );
783 "agtiapi PCI Probe Vendor ID : 0x%x Device ID : 0x%x\n",
784 pci_get_vendor(dev), agtiapi_dev );
785 device_set_desc( dev, ag_card_names[ag_card_type[idx].cardNameIndex] );