Print this page
    
NEX-1890 update oce from source provided by Emulex
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/io/fibre-channel/fca/oce/oce_buf.c
          +++ new/usr/src/uts/common/io/fibre-channel/fca/oce/oce_buf.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  
    | 
      ↓ open down ↓ | 
    11 lines elided | 
    
      ↑ open up ↑ | 
  
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22      -/* Copyright © 2003-2011 Emulex. All rights reserved.  */
       22 +/*
       23 + * Copyright (c) 2009-2012 Emulex. All rights reserved.
       24 + * Use is subject to license terms.
       25 + */
  23   26  
       27 +
  24   28  /*
  25   29   * Source file containing the implementation of Driver buffer management
  26   30   * and related helper functions
  27   31   */
  28   32  #include <oce_impl.h>
  29   33  
  30   34  static ddi_dma_attr_t oce_dma_buf_attr = {
  31   35          DMA_ATTR_V0,            /* version number */
  32   36          0x0000000000000000ull,  /* low address */
  33   37          0xFFFFFFFFFFFFFFFFull,  /* high address */
  34   38          0x00000000FFFFFFFFull,  /* dma counter max */
  35   39          OCE_DMA_ALIGNMENT,      /* alignment */
  36   40          0x00000FFF,             /* burst sizes */
  37   41          0x00000001,             /* minimum transfer size */
  38   42          0x00000000FFFFFFFFull,  /* maximum transfer size */
  39   43          0xFFFFFFFFFFFFFFFFull,  /* maximum segment size */
  40   44          1,                      /* scatter/gather list length */
  41   45          0x00000001,             /* granularity */
  42   46          0                       /* DMA flags */
  43   47  };
  44   48  
  45   49  static ddi_device_acc_attr_t oce_dma_buf_accattr = {
  46   50          DDI_DEVICE_ATTR_V0,
  47   51          DDI_NEVERSWAP_ACC,
  48   52          DDI_STRICTORDER_ACC,
  49   53  };
  50   54  
  51   55  
  
    | 
      ↓ open down ↓ | 
    18 lines elided | 
    
      ↑ open up ↑ | 
  
  52   56  /*
  53   57   * function to allocate a dma buffer for mapping memory va-pa
  54   58   *
  55   59   * dev - software handle to device
  56   60   * size - size of the memory to map
  57   61   * flags - DDI_DMA_CONSISTENT/DDI_DMA_STREAMING
  58   62   *
  59   63   * return pointer to a oce_dma_buf_t structure handling the map
  60   64   *      NULL => failure
  61   65   */
  62      -oce_dma_buf_t *
  63      -oce_alloc_dma_buffer(struct oce_dev *dev,
       66 +int
       67 +oce_alloc_dma_buffer(struct oce_dev *dev, oce_dma_buf_t *dbuf,
  64   68      uint32_t size, ddi_dma_attr_t *dma_attr, uint32_t flags)
  65   69  {
  66      -        oce_dma_buf_t  *dbuf;
  67      -        ddi_dma_cookie_t cookie;
  68      -        uint32_t count;
  69   70          size_t actual_len;
  70   71          int ret = 0;
  71   72  
  72   73          ASSERT(size > 0);
  73   74          /* if NULL use default */
  74   75          if (dma_attr == NULL) {
  75   76                  dma_attr = &oce_dma_buf_attr;
  76   77          }
  77   78  
  78      -        dbuf = kmem_zalloc(sizeof (oce_dma_buf_t), KM_NOSLEEP);
  79      -        if (dbuf == NULL) {
  80      -                return (NULL);
  81      -        }
  82      -
  83   79          /* allocate dma handle */
  84   80          ret = ddi_dma_alloc_handle(dev->dip, dma_attr,
  85   81              DDI_DMA_DONTWAIT, NULL, &dbuf->dma_handle);
  86   82          if (ret != DDI_SUCCESS) {
  87      -                oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
       83 +                oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
  88   84                      "Failed to allocate DMA handle");
  89   85                  goto handle_fail;
  90   86          }
  91   87          /* allocate the DMA-able memory */
  92   88          ret = ddi_dma_mem_alloc(dbuf->dma_handle, size, &oce_dma_buf_accattr,
  93      -            flags, DDI_DMA_DONTWAIT, NULL, &dbuf->base,
  94      -            &actual_len, &dbuf->acc_handle);
       89 +            (flags & DDI_DMA_STREAMING) ?
       90 +            DDI_DMA_STREAMING : DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL,
       91 +            &dbuf->base, &actual_len, &dbuf->acc_handle);
  95   92          if (ret != DDI_SUCCESS) {
  96      -                oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
  97      -                    "Failed to allocate DMA memory");
       93 +                oce_log(dev, CE_NOTE, MOD_CONFIG,
       94 +                    "Failed to allocate DMA memory: 0x%x bytes", size);
  98   95                  goto alloc_fail;
  99   96          }
 100   97  
 101   98          /* bind handle */
 102   99          ret = ddi_dma_addr_bind_handle(dbuf->dma_handle,
 103  100              (struct as *)0, dbuf->base, actual_len,
 104      -            DDI_DMA_RDWR | flags,
 105      -            DDI_DMA_DONTWAIT, NULL, &cookie, &count);
      101 +            flags,
      102 +            DDI_DMA_DONTWAIT, NULL, &dbuf->cookie, &dbuf->ncookies);
 106  103          if (ret != DDI_DMA_MAPPED) {
 107      -                oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
      104 +                oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
 108  105                      "Failed to bind dma handle");
 109  106                  goto bind_fail;
 110  107          }
 111  108          bzero(dbuf->base, actual_len);
 112      -        dbuf->addr = cookie.dmac_laddress;
      109 +        dbuf->addr = dbuf->cookie.dmac_laddress;
 113  110          dbuf->size = actual_len;
 114  111          /* usable length */
 115  112          dbuf->len  = size;
 116  113          dbuf->num_pages = OCE_NUM_PAGES(size);
 117      -        return (dbuf);
      114 +        return (DDI_SUCCESS);
 118  115  
 119  116  bind_fail:
 120  117          ddi_dma_mem_free(&dbuf->acc_handle);
 121  118  alloc_fail:
 122  119          ddi_dma_free_handle(&dbuf->dma_handle);
 123  120  handle_fail:
 124      -        kmem_free(dbuf, sizeof (oce_dma_buf_t));
 125      -        return (NULL);
      121 +        return (ret);
 126  122  } /* oce_dma_alloc_buffer */
 127  123  
 128  124  /*
 129  125   * function to delete a dma buffer
 130  126   *
 131  127   * dev - software handle to device
 132  128   * dbuf - dma obj  to delete
 133  129   *
 134  130   * return none
 135  131   */
 136  132  void
 137  133  oce_free_dma_buffer(struct oce_dev *dev, oce_dma_buf_t *dbuf)
 138  134  {
  
    | 
      ↓ open down ↓ | 
    3 lines elided | 
    
      ↑ open up ↑ | 
  
 139  135          _NOTE(ARGUNUSED(dev));
 140  136  
 141  137          if (dbuf == NULL) {
 142  138                  return;
 143  139          }
 144  140          if (dbuf->dma_handle != NULL) {
 145  141                  (void) ddi_dma_unbind_handle(dbuf->dma_handle);
 146  142          }
 147  143          if (dbuf->acc_handle != NULL) {
 148  144                  ddi_dma_mem_free(&dbuf->acc_handle);
      145 +                dbuf->acc_handle = NULL;
 149  146          }
 150  147          if (dbuf->dma_handle != NULL) {
 151  148                  ddi_dma_free_handle(&dbuf->dma_handle);
      149 +                dbuf->dma_handle = NULL;
 152  150          }
 153      -        kmem_free(dbuf, sizeof (oce_dma_buf_t));
 154  151  } /* oce_free_dma_buffer */
 155  152  
 156  153  /*
 157  154   * function to create a ring buffer
 158  155   *
 159  156   * dev - software handle to the device
 160  157   * num_items - number of items in the ring
 161  158   * item_size - size of an individual item in the ring
 162  159   * flags - DDI_DMA_CONSISTENT/DDI_DMA_STREAMING for ring memory
 163  160   *
 164  161   * return pointer to a ring_buffer structure, NULL on failure
 165  162   */
 166  163  oce_ring_buffer_t *
 167      -create_ring_buffer(struct oce_dev *dev,
      164 +oce_create_ring_buffer(struct oce_dev *dev,
 168  165      uint32_t num_items, uint32_t item_size, uint32_t flags)
 169  166  {
 170  167          oce_ring_buffer_t *ring;
 171      -        uint32_t size;
      168 +        int ret;
 172  169  
 173  170          /* allocate the ring buffer */
 174  171          ring = kmem_zalloc(sizeof (oce_ring_buffer_t), KM_NOSLEEP);
 175  172          if (ring == NULL) {
 176  173                  return (NULL);
 177  174          }
 178  175  
 179  176          /* get the dbuf defining the ring */
 180      -        size = num_items * item_size;
 181      -        ring->dbuf = oce_alloc_dma_buffer(dev, size, NULL, flags);
 182      -        if (ring->dbuf  == NULL) {
 183      -                oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
 184      -                    "Ring buffer allocation failed");
      177 +        ret = oce_alloc_dma_buffer(dev, &ring->dbuf, num_items *item_size,
      178 +            NULL, flags);
      179 +        if (ret != DDI_SUCCESS) {
      180 +                oce_log(dev, CE_WARN, MOD_CONFIG,
      181 +                    "Ring buffer allocation failed 0x%x", ret);
 185  182                  goto dbuf_fail;
 186  183          }
 187  184  
 188  185          /* fill the rest of the ring */
 189  186          ring->num_items = num_items;
 190  187          ring->item_size = item_size;
 191  188          ring->num_used  = 0;
 192  189          return (ring);
 193  190  
 194  191  dbuf_fail:
 195  192          kmem_free(ring, sizeof (oce_ring_buffer_t));
 196  193          return (NULL);
 197  194  } /* create_ring_buffer */
 198  195  
 199  196  /*
 200  197   * function to destroy a ring buffer
 201  198   *
 202  199   * dev - software handle to teh device
 203  200   * ring - the ring buffer to delete
  
    | 
      ↓ open down ↓ | 
    9 lines elided | 
    
      ↑ open up ↑ | 
  
 204  201   *
 205  202   * return none
 206  203   */
 207  204  void
 208  205  destroy_ring_buffer(struct oce_dev *dev, oce_ring_buffer_t *ring)
 209  206  {
 210  207          ASSERT(dev != NULL);
 211  208          ASSERT(ring !=  NULL);
 212  209  
 213  210          /* free the dbuf associated with the ring */
 214      -        oce_free_dma_buffer(dev, ring->dbuf);
 215      -        ring->dbuf = NULL;
      211 +        oce_free_dma_buffer(dev, &ring->dbuf);
 216  212  
 217  213          /* free the ring itself */
 218  214          kmem_free(ring, sizeof (oce_ring_buffer_t));
 219  215  } /* destroy_ring_buffer */
 220  216  
 221  217  
 222  218  /*
 223  219   * function to enable the fma flags
 224  220   * fm_caps - FM capability flags
 225  221   *
 226  222   * return none
 227  223   */
 228  224  
 229  225  void
 230  226  oce_set_dma_fma_flags(int fm_caps)
 231  227  {
 232  228          if (fm_caps == DDI_FM_NOT_CAPABLE) {
 233  229                  return;
 234  230          }
 235  231  
 236  232          oce_dma_buf_accattr.devacc_attr_access = DDI_DEFAULT_ACC;
 237  233  
 238  234          if (DDI_FM_DMA_ERR_CAP(fm_caps)) {
 239  235                  oce_dma_buf_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
 240  236  
 241  237          } else {
 242  238                  oce_dma_buf_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
 243  239  
 244  240          }
 245  241  } /* oce_set_dma_fma_flags */
  
    | 
      ↓ open down ↓ | 
    20 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX