The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/pms/freebsd/driver/common/lxutil.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 /******************************************************************************
   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 ******************************************************************************/
   28 
   29 
   30 MALLOC_DEFINE( M_PMC_MMAL, "agtiapi_MemAlloc malloc",
   31                "allocated from agtiapi_MemAlloc as simple malloc case" );
   32 
   33 
   34 /*****************************************************************************
   35 agtiapi_DelayMSec()
   36 
   37 Purpose:
   38   Busy wait for number of mili-seconds
   39 Parameters:
   40   U32 MiliSeconds (IN)  Number of mili-seconds to delay
   41 Return:
   42 Note:
   43 *****************************************************************************/
   44 STATIC void agtiapi_DelayMSec( U32 MiliSeconds )
   45 {
   46   DELAY(MiliSeconds * 1000);  // DELAY takes in usecs
   47 }
   48 
   49 /******************************************************************************
   50 agtiapi_typhAlloc()
   51 Purpose:
   52   Preallocation handling
   53   Allocate DMA memory which will be divided among proper pointers in
   54    agtiapi_MemAlloc() later
   55 Parameters:
   56   ag_card_info_t *thisCardInst (IN)
   57 Return:
   58   AGTIAPI_SUCCESS - success
   59   AGTIAPI_FAIL    - fail
   60 ******************************************************************************/
   61 STATIC agBOOLEAN agtiapi_typhAlloc( ag_card_info_t *thisCardInst )
   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 /******************************************************************************
  120 agtiapi_InitResource()
  121 Purpose:
  122   Mapping PCI memory space
  123   Allocate and initialize per card based resource
  124 Parameters: 
  125   ag_card_info_t *pCardInfo (IN)  
  126 Return:
  127   AGTIAPI_SUCCESS - success
  128   AGTIAPI_FAIL    - fail
  129 Note:    
  130 ******************************************************************************/
  131 STATIC agBOOLEAN agtiapi_InitResource( ag_card_info_t *thisCardInst )
  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;
  199   pRscInfo->tiLoLevelResource.loLevelOption.pciFunctionNumber =
  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",
  218                     pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick );
  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 <
  229            AGTIAPI_64BIT_ALIGN ) {
  230         AGTIAPI_PRINTK("agtiapi_InitResource: set ALIGN %d\n", numVal);
  231         pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment =
  232           AGTIAPI_64BIT_ALIGN;
  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
  250         TI_DMA_MEM;
  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,
  260               pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
  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 =
  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++;
  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,
  292                pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
  293                TI_CACHED_MEM,
  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 =
  330         (U32)( pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick
  331                / uSecPerTick );
  332       if( pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick
  333           % uSecPerTick > 0 )
  334         pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick =
  335           (numVal + 1) * uSecPerTick;
  336       else
  337         pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick =
  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 ) {
  345           pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
  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,
  359               &pRscInfo->tiInitiatorResource.initiatorMem.
  360               tdCachedMem[numVal].virtPtr,
  361               (U32 *)agNULL,
  362               (U32 *)agNULL,
  363               pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
  364               totalLength,
  365               TI_CACHED_MEM,
  366               pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
  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
  391     if( pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment < 
  392         AGTIAPI_64BIT_ALIGN ) {
  393       pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment = AGTIAPI_64BIT_ALIGN;
  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,
  406                             &pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr, 
  407                             &pRscInfo->tiSharedMem.tdSharedCachedMem1.
  408                             physAddrUpper, 
  409                             &pRscInfo->tiSharedMem.tdSharedCachedMem1.
  410                             physAddrLower, 
  411                             pRscInfo->tiSharedMem.tdSharedCachedMem1.
  412                             totalLength, 
  413                             TI_DMA_MEM,
  414                             pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment)
  415           != AGTIAPI_SUCCESS )
  416         return AGTIAPI_FAIL;
  417 
  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++;
  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,
  442                             &pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr, 
  443                             (U32 *)agNULL,
  444                             (U32 *)agNULL,
  445                             pRscInfo->
  446                             tiSharedMem.tdSharedCachedMem1.totalLength, 
  447                             TI_CACHED_MEM,
  448                             pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment)
  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],
  462                       pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
  463                       pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength,
  464                       pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment );
  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 /******************************************************************************
  479 agtiapi_ScopeDMARes()
  480 Purpose:
  481   Determine the amount of DMA (non-cache) memory resources which will be
  482   required for a card ( and necessarily allocated in agtiapi_InitResource() )
  483 Parameters: 
  484   ag_card_info_t *thisCardInst (IN)  
  485 Return:
  486   size of DMA memory which call to agtiapi_InitResource() will consume  
  487 Note:
  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 )
  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
  527         TI_DMA_MEM;
  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 
  587 STATIC void agtiapi_ReleasePCIMem( ag_card_info_t *pCardInfo ) {
  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 /******************************************************************************
  606 agtiapi_MemAlloc()
  607 Purpose:
  608   Handle various memory allocation requests.
  609 Parameters: 
  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
  619 Return:
  620   AGTIAPI_SUCCESS - success
  621   AGTIAPI_FAIL    - fail
  622 ******************************************************************************/
  623 STATIC agBOOLEAN agtiapi_MemAlloc( ag_card_info_t *thisCardInst,
  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 /******************************************************************************
  678 agtiapi_MemFree()
  679 
  680 Purpose:
  681   Free agtiapi_MemAlloc() allocated memory
  682 Parameters: 
  683   ag_card_info_t *pCardInfo (IN)  Pointer to card info structure
  684 Return: none
  685 ******************************************************************************/
  686 STATIC void agtiapi_MemFree( ag_card_info_t *pCardInfo )
  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 /******************************************************************************
  740 agtiapi_ProbeCard()
  741 Purpose:
  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.
  744 Parameters:
  745   device_t dev,
  746   ag_card_info_t *thisCardInst,
  747   int thisCard
  748 Return:
  749   0 - success
  750   other values are not as good
  751 Note:
  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,
  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 

Cache object: f01d755920085ddc8415941eec528e78


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.