FreeBSD kernel pms device code
lxutil.c
Go to the documentation of this file.
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/* $FreeBSD$ */
23/******************************************************************************
24This program is part of PMC-Sierra initiator/target device driver.
25The functions here are commonly used by different type of drivers that support
26PMC-Sierra storage network initiator hardware.
27******************************************************************************/
28
29
30MALLOC_DEFINE( M_PMC_MMAL, "agtiapi_MemAlloc malloc",
31 "allocated from agtiapi_MemAlloc as simple malloc case" );
32
33
34/*****************************************************************************
35agtiapi_DelayMSec()
36
37Purpose:
38 Busy wait for number of mili-seconds
39Parameters:
40 U32 MiliSeconds (IN) Number of mili-seconds to delay
41Return:
42Note:
43*****************************************************************************/
44STATIC void agtiapi_DelayMSec( U32 MiliSeconds )
45{
46 DELAY(MiliSeconds * 1000); // DELAY takes in usecs
47}
48
49/******************************************************************************
50agtiapi_typhAlloc()
51Purpose:
52 Preallocation handling
53 Allocate DMA memory which will be divided among proper pointers in
54 agtiapi_MemAlloc() later
55Parameters:
56 ag_card_info_t *thisCardInst (IN)
57Return:
58 AGTIAPI_SUCCESS - success
59 AGTIAPI_FAIL - fail
60******************************************************************************/
62{
63 struct agtiapi_softc *pmsc = thisCardInst->pCard;
64 int wait = 0;
65
66 if( bus_dma_tag_create( bus_get_dma_tag(pmsc->my_dev), // parent
67 32, // alignment
68 0, // boundary
69 BUS_SPACE_MAXADDR, // lowaddr
70 BUS_SPACE_MAXADDR, // highaddr
71 NULL, // filter
72 NULL, // filterarg
73 pmsc->typhn, // maxsize (size)
74 1, // number of segments
75 pmsc->typhn, // maxsegsize
76 0, // flags
77 NULL, // lockfunc
78 NULL, // lockarg
79 &pmsc->typh_dmat ) ) {
80 printf( "agtiapi_typhAlloc: Can't create no-cache mem tag\n" );
81 return AGTIAPI_FAIL;
82 }
83
84 if( bus_dmamem_alloc( pmsc->typh_dmat,
85 &pmsc->typh_mem,
86 BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE,
87 &pmsc->typh_mapp ) ) {
88 printf( "agtiapi_typhAlloc: Cannot allocate cache mem %d\n",
89 pmsc->typhn );
90 return AGTIAPI_FAIL;
91 }
92
93 if ( bus_dmamap_load( pmsc->typh_dmat,
94 pmsc->typh_mapp,
95 pmsc->typh_mem,
96 pmsc->typhn,
97 agtiapi_MemoryCB, // try reuse of CB for same goal
98 &pmsc->typh_busaddr,
99 0 ) || !pmsc->typh_busaddr ) {
100 for( ; wait < 20; wait++ ) {
101 if( pmsc->typh_busaddr ) break;
102 DELAY( 50000 );
103 }
104
105 if( ! pmsc->typh_busaddr ) {
106 printf( "agtiapi_typhAlloc: cache mem won't load %d\n",
107 pmsc->typhn );
108 return AGTIAPI_FAIL;
109 }
110 }
111
112 pmsc->typhIdx = 0;
113 pmsc->tyPhsIx = 0;
114
115 return AGTIAPI_SUCCESS;
116}
117
118
119/******************************************************************************
120agtiapi_InitResource()
121Purpose:
122 Mapping PCI memory space
123 Allocate and initialize per card based resource
124Parameters:
125 ag_card_info_t *pCardInfo (IN)
126Return:
127 AGTIAPI_SUCCESS - success
128 AGTIAPI_FAIL - fail
129Note:
130******************************************************************************/
132{
133 struct agtiapi_softc *pmsc = thisCardInst->pCard;
134 device_t devx = thisCardInst->pPCIDev;
135
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
139
140 if( agtiapi_typhAlloc( thisCardInst ) == AGTIAPI_FAIL ) {
141 printf( "agtiapi_InitResource: failed call to agtiapi_typhAlloc \n" );
142 return AGTIAPI_FAIL;
143 }
144
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 ) );
148
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):
155 U32 bar;
156 U32 lBar = 0; // logicalBar
157 for (bar = 0; bar < PCI_NUMBER_BARS; bar++) {
158 if ((bar==1) || (bar==3))
159 continue;
160 thisCardInst->pciMemBaseRIDSpc[lBar] = PCIR_BAR(bar);
161 thisCardInst->pciMemBaseRscSpc[lBar] =
162 bus_alloc_resource_any( devx,
163 SYS_RES_MEMORY,
164 &(thisCardInst->pciMemBaseRIDSpc[lBar]),
165 RF_ACTIVE );
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] );
182 }
183 else {
184 thisCardInst->pciMemVirtAddrSpc[lBar] = 0;
185 thisCardInst->pciMemBaseSpc[lBar] = 0;
186 thisCardInst->pciMemSizeSpc[lBar] = 0;
187 }
188 lBar++;
189 }
190 thisCardInst->pciMemVirtAddr = thisCardInst->pciMemVirtAddrSpc[0];
191 thisCardInst->pciMemSize = thisCardInst->pciMemSizeSpc[0];
192 thisCardInst->pciMemBase = thisCardInst->pciMemBaseSpc[0];
193
194 // Allocate all TI data structure required resources.
195 // tiLoLevelResource
196 U32 numVal;
197 ag_resource_info_t *pRscInfo;
198 pRscInfo = &thisCardInst->tiRscInfo;
200 pci_get_function( devx );
201
202 struct timeval tv;
203 tv.tv_sec = 1;
204 tv.tv_usec = 0;
205 int ticksPerSec;
206 ticksPerSec = tvtohz( &tv );
207 int uSecPerTick = 1000000/USEC_PER_TICK;
208
209 if (pRscInfo->tiLoLevelResource.loLevelMem.count != 0) {
210 //AGTIAPI_INIT("agtiapi_InitResource: loLevelMem count = %d\n",
211 // pRscInfo->tiLoLevelResource.loLevelMem.count);
212
213 // adjust tick value to meet Linux requirement
214 pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick = uSecPerTick;
215 AGTIAPI_PRINTK( "agtiapi_InitResource: "
216 "pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick"
217 " 0x%x\n",
219 for( numVal = 0; numVal < pRscInfo->tiLoLevelResource.loLevelMem.count;
220 numVal++ ) {
221 if( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength ==
222 0 ) {
223 AGTIAPI_PRINTK("agtiapi_InitResource: skip ZERO %d\n", numVal);
224 continue;
225 }
226
227 // check for 64 bit alignment
228 if ( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment <
230 AGTIAPI_PRINTK("agtiapi_InitResource: set ALIGN %d\n", numVal);
231 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment =
233 }
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 );
243 return AGTIAPI_FAIL;
244 }
245 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type =
246#ifdef CACHED_DMA
247 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
248 & (BIT(0) | BIT(1));
249#else
251#endif
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].
257 physAddrUpper,
258 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].
259 physAddrLower,
261 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type,
262 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment)
263 != AGTIAPI_SUCCESS ) {
264 return AGTIAPI_FAIL;
265 }
266 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].memSize =
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++;
276 }
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 );
284 return AGTIAPI_FAIL;
285 }
286 if ( agtiapi_MemAlloc( thisCardInst,
287 &thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
288 (vm_paddr_t *)agNULL,
289 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
290 (U32 *)agNULL,
291 (U32 *)agNULL,
294 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment)
295 != AGTIAPI_SUCCESS ) {
296 return AGTIAPI_FAIL;
297 }
298
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);
306
307 thisCardInst->cacheIndex++;
308 }
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!" );
313 }
314 else {
315 printf( "agtiapi_InitResource: Unknown required memory type %d "
316 "ERROR!\n",
317 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type);
318 return AGTIAPI_FAIL;
319 }
320 }
321 }
322 // end: TI data structure resources ...
323
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);
329 numVal =
331 / uSecPerTick );
333 % uSecPerTick > 0 )
335 (numVal + 1) * uSecPerTick;
336 else
338 numVal * uSecPerTick;
339 for ( numVal = 0;
340 numVal < pRscInfo->tiInitiatorResource.initiatorMem.count;
341 numVal++ ) {
342 // check for 64 bit alignment
343 if( pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
344 alignment < AGTIAPI_64BIT_ALIGN ) {
346 alignment = AGTIAPI_64BIT_ALIGN;
347 }
348 if( thisCardInst->cacheIndex >=
349 sizeof( thisCardInst->tiCachedMem) /
350 sizeof( thisCardInst->tiCachedMem[0])) {
351 AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n",
352 thisCardInst->cacheIndex );
353 return AGTIAPI_FAIL;
354 }
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,
360 tdCachedMem[numVal].virtPtr,
361 (U32 *)agNULL,
362 (U32 *)agNULL,
364 totalLength,
367 alignment)
368 != AGTIAPI_SUCCESS) {
369 return AGTIAPI_FAIL;
370 }
371 // AGTIAPI_INIT("agtiapi_InitResource: IniMem %d cacheIndex=%d CACHED "
372 // "vaddr %p / %p, length %d align 0x%x\n",
373 // numVal,
374 // pCardInfo->cacheIndex,
375 // pCardInfo->tiCachedMem[pCardInfo->cacheIndex],
376 // pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
377 // virtPtr,
378 //pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
379 // totalLength,
380 // pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
381 // alignment);
382 thisCardInst->cacheIndex++;
383 }
384 }
385 }
386 // end: tiInitiatorResource
387
388 // begin: tiTdSharedMem
389 if (pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength != 0) {
390 // check for 64 bit alignment
394 }
395 if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type & (BIT(0) | BIT(1)))
396 == TI_DMA_MEM ) {
397 if( thisCardInst->dmaIndex >=
398 sizeof(thisCardInst->tiDmaMem) / sizeof(thisCardInst->tiDmaMem[0]) ) {
399 AGTIAPI_PRINTK( "Invalid dmaIndex %d ERROR\n", thisCardInst->dmaIndex);
400 return AGTIAPI_FAIL;
401 }
402 if( agtiapi_MemAlloc( thisCardInst, (void *)&thisCardInst->
403 tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr,
404 &thisCardInst->tiDmaMem[thisCardInst->dmaIndex].
405 dmaPhysAddr,
408 physAddrUpper,
410 physAddrLower,
412 totalLength,
415 != AGTIAPI_SUCCESS )
416 return AGTIAPI_FAIL;
417
418 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].memSize =
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++;
429 }
430 else if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type &
431 (BIT(0) | BIT(1)))
432 == TI_CACHED_MEM ) {
433 if( thisCardInst->cacheIndex >=
434 sizeof(thisCardInst->tiCachedMem) /
435 sizeof(thisCardInst->tiCachedMem[0]) ) {
436 AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n", thisCardInst->cacheIndex);
437 return AGTIAPI_FAIL;
438 }
439 if( agtiapi_MemAlloc( thisCardInst, (void *)&thisCardInst->
440 tiCachedMem[thisCardInst->cacheIndex],
441 (vm_paddr_t *)agNULL,
443 (U32 *)agNULL,
444 (U32 *)agNULL,
445 pRscInfo->
446 tiSharedMem.tdSharedCachedMem1.totalLength,
449 != AGTIAPI_SUCCESS )
450 return AGTIAPI_FAIL;
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],
465 thisCardInst->cacheIndex++;
466 }
467 else {
468 AGTIAPI_PRINTK( "agtiapi_InitResource: "
469 "Unknown required memory type ERROR!\n" );
470 return AGTIAPI_FAIL;
471 }
472 }
473 // end: tiTdSharedMem
474 DELAY( 200000 ); // or use AGTIAPI_INIT_MDELAY(200);
475 return AGTIAPI_SUCCESS;
476} // agtiapi_InitResource() ends here
477
478/******************************************************************************
479agtiapi_ScopeDMARes()
480Purpose:
481 Determine the amount of DMA (non-cache) memory resources which will be
482 required for a card ( and necessarily allocated in agtiapi_InitResource() )
483Parameters:
484 ag_card_info_t *thisCardInst (IN)
485Return:
486 size of DMA memory which call to agtiapi_InitResource() will consume
487Note:
488 this funcion mirrors the flow of agtiapi_InitResource()
489 results are stored in agtiapi_softc fields
490******************************************************************************/
492{
493 struct agtiapi_softc *pmsc = thisCardInst->pCard;
494 U32 lAllMem = 0; // total memory count; typhn
495 U32 lTmpAlign, lTmpType, lTmpLen;
496
497 // tiLoLevelResource
498 U32 numVal;
499 ag_resource_info_t *pRscInfo;
500 pRscInfo = &thisCardInst->tiRscInfo;
501
502 if (pRscInfo->tiLoLevelResource.loLevelMem.count != 0) {
503 for( numVal = 0; numVal < pRscInfo->tiLoLevelResource.loLevelMem.count;
504 numVal++ ) {
505 if( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength ==
506 0 ) {
507 printf( "agtiapi_ScopeDMARes: skip ZERO %d\n", numVal );
508 continue;
509 }
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;
516 }
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 =
522 lTmpType =
523#ifdef CACHED_DMA
524 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
525 & (BIT(0) | BIT(1));
526#else
528#endif
529 if( lTmpType == TI_DMA_MEM ) {
530 lTmpLen =
531 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength;
532 lAllMem += lTmpLen + lTmpAlign;
533 }
534 //printf( "agtiapi_ScopeDMARes: call 1 0x%x\n", lAllMem );
535 }
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 );
544 return lAllMem;
545 }
546 }
547 else {
548 printf( "agtiapi_ScopeDMARes: Unknown required memory type %d "
549 "ERROR!\n",
550 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type );
551 return lAllMem;
552 }
553 }
554 }
555 // end: TI data structure resources ...
556
557 // nothing for tiInitiatorResource
558
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;
566 }
567 if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type & (BIT(0) | BIT(1)))
568 == TI_DMA_MEM ) {
569 lTmpLen = pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength;
570 lAllMem += lTmpLen + lTmpAlign;
571 // printf( "agtiapi_ScopeDMARes: call 4D 0x%x\n", lAllMem );
572 }
573 else if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type &
574 (BIT(0) | BIT(1)))
575 != TI_CACHED_MEM ) {
576 printf( "agtiapi_ScopeDMARes: Unknown required memory type ERROR!\n" );
577 }
578 }
579 // end: tiTdSharedMem
580
581 pmsc->typhn = lAllMem;
582 return lAllMem;
583
584} // agtiapi_ScopeDMARes() ends here
585
586
588 U32 bar = 0;
589 int tmpRid = 0;
590 struct resource *tmpRsc = NULL;
591 device_t dev;
592 dev = pCardInfo->pPCIDev;
593
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 );
599 }
600 }
601 return;
602}
603
604
605/******************************************************************************
606agtiapi_MemAlloc()
607Purpose:
608 Handle various memory allocation requests.
609Parameters:
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
619Return:
620 AGTIAPI_SUCCESS - success
621 AGTIAPI_FAIL - fail
622******************************************************************************/
624 void **VirtAlloc,
625 vm_paddr_t *pDmaAddr,
626 void **VirtAddr,
627 U32 *pPhysAddrUp,
628 U32 *pPhysAddrLow,
629 U32 MemSize,
630 U32 Type,
631 U32 Align )
632{
633 U32_64 alignOffset = 0;
634 if( Align )
635 alignOffset = Align - 1;
636
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 );
639
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);
643 }
644 else {
645 struct agtiapi_softc *pmsc = thisCardInst->pCard; // get card reference
646 U32 residAlign = 0;
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,
666 // Align );
667 }
668 if ( !*VirtAlloc ) {
669 AGTIAPI_PRINTK( "agtiapi_MemAlloc memory allocation ERROR x%x\n",
670 Type & (U32)(BIT(0) | BIT(1)));
671 return AGTIAPI_FAIL;
672 }
673 return AGTIAPI_SUCCESS;
674}
675
676
677/******************************************************************************
678agtiapi_MemFree()
679
680Purpose:
681 Free agtiapi_MemAlloc() allocated memory
682Parameters:
683 ag_card_info_t *pCardInfo (IN) Pointer to card info structure
684Return: none
685******************************************************************************/
687{
688 U32 idx;
689
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] );
696 }
697 }
698
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 );
703 }
704 if( pmsc->typh_mem != NULL ) {
705 bus_dmamem_free( pmsc->typh_dmat, pmsc->typh_mem, pmsc->typh_mapp );
706 }
707 if( pmsc->typh_dmat != NULL ) {
708 bus_dma_tag_destroy( pmsc->typh_dmat );
709 }
710//reference values:
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
716
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, ... );
731 else
732 free case for cacheable memory would go here
733 }
734 }
735*/
736 return;
737}
738
739/******************************************************************************
740agtiapi_ProbeCard()
741Purpose:
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.
744Parameters:
745 device_t dev,
746 ag_card_info_t *thisCardInst,
747 int thisCard
748Return:
749 0 - success
750 other values are not as good
751Note:
752 This implementation is tailored to FreeBSD in alignment with the probe
753 functionality of the FreeBSD environment.
754******************************************************************************/
755STATIC int agtiapi_ProbeCard( device_t dev,
756 ag_card_info_t *thisCardInst,
757 int thisCard )
758{
759 int idx;
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");
763
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++ )
767 {
768 if ( ag_card_type[idx].deviceId == agtiapi_dev &&
769 ag_card_type[idx].vendorId == agtiapi_vendor)
770 { // device ID match
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] );
781 return 0;
782 }
783 }
784 return 1;
785}
786
static void agtiapi_MemoryCB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
Definition: agtiapi.c:1590
static ag_card_info_t agCardInfoList[AGTIAPI_MAX_CARDS]
Definition: agtiapi.c:216
#define LOW_32_BITS(addr)
Definition: lxcommon.h:571
#define AGTIAPI_INITIATOR
Definition: lxcommon.h:116
#define USEC_PER_TICK
Definition: lxcommon.h:52
#define HIGH_32_BITS(addr)
Definition: lxcommon.h:572
#define AGTIAPI_PRINTK(format, a...)
Definition: lxcommon.h:517
#define COUNT(arr)
Definition: lxcommon.h:586
#define AGTIAPI_64BIT_ALIGN
Definition: lxcommon.h:53
static char const *const ag_card_names[]
Definition: lxcommon.h:316
ag_card_id_t ag_card_type[]
Definition: lxcommon.h:236
STATIC void agtiapi_DelayMSec(U32 MiliSeconds)
Definition: lxutil.c:44
STATIC agBOOLEAN agtiapi_InitResource(ag_card_info_t *thisCardInst)
Definition: lxutil.c:131
STATIC void agtiapi_ReleasePCIMem(ag_card_info_t *pCardInfo)
Definition: lxutil.c:587
MALLOC_DEFINE(M_PMC_MMAL, "agtiapi_MemAlloc malloc", "allocated from agtiapi_MemAlloc as simple malloc case")
STATIC agBOOLEAN agtiapi_MemAlloc(ag_card_info_t *thisCardInst, void **VirtAlloc, vm_paddr_t *pDmaAddr, void **VirtAddr, U32 *pPhysAddrUp, U32 *pPhysAddrLow, U32 MemSize, U32 Type, U32 Align)
Definition: lxutil.c:623
STATIC int agtiapi_ScopeDMARes(ag_card_info_t *thisCardInst)
Definition: lxutil.c:491
STATIC void agtiapi_MemFree(ag_card_info_t *pCardInfo)
Definition: lxutil.c:686
STATIC int agtiapi_ProbeCard(device_t dev, ag_card_info_t *thisCardInst, int thisCard)
Definition: lxutil.c:755
STATIC agBOOLEAN agtiapi_typhAlloc(ag_card_info_t *thisCardInst)
Definition: lxutil.c:61
#define NULL
Definition: ostypes.h:142
#define STATIC
Definition: ostypes.h:78
unsigned long long U64
Definition: ostypes.h:126
#define agNULL
Definition: ostypes.h:151
unsigned long U32_64
Definition: ostypes.h:125
#define agBOOLEAN
Definition: ostypes.h:146
#define AGTIAPI_FAIL
Definition: ostypes.h:155
#define AGTIAPI_SUCCESS
Definition: ostypes.h:154
unsigned int U32
Definition: ostypes.h:124
#define BIT(x)
Definition: ostypes.h:165
S32 cardNameIndex
Definition: lxcommon.h:221
U32 cardIdIndex
Definition: lxcommon.h:402
device_t pPCIDev
Definition: lxcommon.h:398
S32 cardNameIndex
Definition: lxcommon.h:400
U32 pciMemSize
Definition: lxcommon.h:407
U32 cacheIndex
Definition: lxcommon.h:424
void * tiCachedMem[AGTIAPI_CACHE_MEM_LIST_MAX]
Definition: lxcommon.h:436
caddr_t pciMemVirtAddr
Definition: lxcommon.h:406
U32_64 pciMemBase
Definition: lxcommon.h:405
ag_resource_info_t tiRscInfo
Definition: lxcommon.h:437
ag_dma_addr_t tiDmaMem[AGTIAPI_DMA_MEM_LIST_MAX]
Definition: lxcommon.h:426
void * pCard
Definition: lxcommon.h:399
bit32 type
Definition: lxcommon.h:377
vm_paddr_t dmaPhysAddr
Definition: lxcommon.h:375
void * dmaVirtAddr
Definition: lxcommon.h:374
tiTdSharedMem_t tiSharedMem
Definition: lxcommon.h:368
tiInitiatorResource_t tiInitiatorResource
Definition: lxcommon.h:366
tiLoLevelResource_t tiLoLevelResource
Definition: lxcommon.h:365
bus_dmamap_t typh_mapp
Definition: agtiapi.h:298
bus_dma_tag_t typh_dmat
Definition: agtiapi.h:297
ag_card_info_t * pCardInfo
Definition: agtiapi.h:343
bus_addr_t typh_busaddr
Definition: agtiapi.h:296
device_t my_dev
Definition: agtiapi.h:259
void * typh_mem
Definition: agtiapi.h:295
bit32 count
Definition: titypes.h:353
tiMem_t tdCachedMem[6]
Definition: titypes.h:354
bit32 usecsPerTick
Definition: titypes.h:359
tiInitiatorOption_t initiatorOption
Definition: titypes.h:369
tiInitiatorMem_t initiatorMem
Definition: titypes.h:370
bit32 count
Definition: titypes.h:82
tiMem_t mem[MAX_LL_LAYER_MEM_DESCRIPTORS]
Definition: titypes.h:83
bit32 pciFunctionNumber
Definition: titypes.h:91
bit32 usecsPerTick
Definition: titypes.h:88
tiLoLevelOption_t loLevelOption
Definition: titypes.h:106
tiLoLevelMem_t loLevelMem
Definition: titypes.h:107
bit32 totalLength
Definition: titypes.h:72
void * virtPtr
Definition: titypes.h:68
bit32 type
Definition: titypes.h:76
bit32 alignment
Definition: titypes.h:75
tiMem_t tdSharedCachedMem1
Definition: titypes.h:112
#define TI_DMA_MEM_CHIP
Definition: tidefs.h:89
#define TI_DMA_MEM
Definition: tidefs.h:86
#define TI_CACHED_MEM
Definition: tidefs.h:87
#define TI_CACHED_DMA_MEM
Definition: tidefs.h:88