Print this page
NEX-1890 update oce from source provided by Emulex


   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /* Copyright © 2003-2011 Emulex. All rights reserved.  */



  23 

  24 /*
  25  * Source file containing the implementation of Driver buffer management
  26  * and related helper functions
  27  */
  28 #include <oce_impl.h>
  29 
  30 static ddi_dma_attr_t oce_dma_buf_attr = {
  31         DMA_ATTR_V0,            /* version number */
  32         0x0000000000000000ull,  /* low address */
  33         0xFFFFFFFFFFFFFFFFull,  /* high address */
  34         0x00000000FFFFFFFFull,  /* dma counter max */
  35         OCE_DMA_ALIGNMENT,      /* alignment */
  36         0x00000FFF,             /* burst sizes */
  37         0x00000001,             /* minimum transfer size */
  38         0x00000000FFFFFFFFull,  /* maximum transfer size */
  39         0xFFFFFFFFFFFFFFFFull,  /* maximum segment size */
  40         1,                      /* scatter/gather list length */
  41         0x00000001,             /* granularity */
  42         0                       /* DMA flags */
  43 };
  44 
  45 static ddi_device_acc_attr_t oce_dma_buf_accattr = {
  46         DDI_DEVICE_ATTR_V0,
  47         DDI_NEVERSWAP_ACC,
  48         DDI_STRICTORDER_ACC,
  49 };
  50 
  51 
  52 /*
  53  * function to allocate a dma buffer for mapping memory va-pa
  54  *
  55  * dev - software handle to device
  56  * size - size of the memory to map
  57  * flags - DDI_DMA_CONSISTENT/DDI_DMA_STREAMING
  58  *
  59  * return pointer to a oce_dma_buf_t structure handling the map
  60  *      NULL => failure
  61  */
  62 oce_dma_buf_t *
  63 oce_alloc_dma_buffer(struct oce_dev *dev,
  64     uint32_t size, ddi_dma_attr_t *dma_attr, uint32_t flags)
  65 {
  66         oce_dma_buf_t  *dbuf;
  67         ddi_dma_cookie_t cookie;
  68         uint32_t count;
  69         size_t actual_len;
  70         int ret = 0;
  71 
  72         ASSERT(size > 0);
  73         /* if NULL use default */
  74         if (dma_attr == NULL) {
  75                 dma_attr = &oce_dma_buf_attr;
  76         }
  77 
  78         dbuf = kmem_zalloc(sizeof (oce_dma_buf_t), KM_NOSLEEP);
  79         if (dbuf == NULL) {
  80                 return (NULL);
  81         }
  82 
  83         /* allocate dma handle */
  84         ret = ddi_dma_alloc_handle(dev->dip, dma_attr,
  85             DDI_DMA_DONTWAIT, NULL, &dbuf->dma_handle);
  86         if (ret != DDI_SUCCESS) {
  87                 oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
  88                     "Failed to allocate DMA handle");
  89                 goto handle_fail;
  90         }
  91         /* allocate the DMA-able memory */
  92         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);

  95         if (ret != DDI_SUCCESS) {
  96                 oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
  97                     "Failed to allocate DMA memory");
  98                 goto alloc_fail;
  99         }
 100 
 101         /* bind handle */
 102         ret = ddi_dma_addr_bind_handle(dbuf->dma_handle,
 103             (struct as *)0, dbuf->base, actual_len,
 104             DDI_DMA_RDWR | flags,
 105             DDI_DMA_DONTWAIT, NULL, &cookie, &count);
 106         if (ret != DDI_DMA_MAPPED) {
 107                 oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
 108                     "Failed to bind dma handle");
 109                 goto bind_fail;
 110         }
 111         bzero(dbuf->base, actual_len);
 112         dbuf->addr = cookie.dmac_laddress;
 113         dbuf->size = actual_len;
 114         /* usable length */
 115         dbuf->len  = size;
 116         dbuf->num_pages = OCE_NUM_PAGES(size);
 117         return (dbuf);
 118 
 119 bind_fail:
 120         ddi_dma_mem_free(&dbuf->acc_handle);
 121 alloc_fail:
 122         ddi_dma_free_handle(&dbuf->dma_handle);
 123 handle_fail:
 124         kmem_free(dbuf, sizeof (oce_dma_buf_t));
 125         return (NULL);
 126 } /* oce_dma_alloc_buffer */
 127 
 128 /*
 129  * function to delete a dma buffer
 130  *
 131  * dev - software handle to device
 132  * dbuf - dma obj  to delete
 133  *
 134  * return none
 135  */
 136 void
 137 oce_free_dma_buffer(struct oce_dev *dev, oce_dma_buf_t *dbuf)
 138 {
 139         _NOTE(ARGUNUSED(dev));
 140 
 141         if (dbuf == NULL) {
 142                 return;
 143         }
 144         if (dbuf->dma_handle != NULL) {
 145                 (void) ddi_dma_unbind_handle(dbuf->dma_handle);
 146         }
 147         if (dbuf->acc_handle != NULL) {
 148                 ddi_dma_mem_free(&dbuf->acc_handle);

 149         }
 150         if (dbuf->dma_handle != NULL) {
 151                 ddi_dma_free_handle(&dbuf->dma_handle);

 152         }
 153         kmem_free(dbuf, sizeof (oce_dma_buf_t));
 154 } /* oce_free_dma_buffer */
 155 
 156 /*
 157  * function to create a ring buffer
 158  *
 159  * dev - software handle to the device
 160  * num_items - number of items in the ring
 161  * item_size - size of an individual item in the ring
 162  * flags - DDI_DMA_CONSISTENT/DDI_DMA_STREAMING for ring memory
 163  *
 164  * return pointer to a ring_buffer structure, NULL on failure
 165  */
 166 oce_ring_buffer_t *
 167 create_ring_buffer(struct oce_dev *dev,
 168     uint32_t num_items, uint32_t item_size, uint32_t flags)
 169 {
 170         oce_ring_buffer_t *ring;
 171         uint32_t size;
 172 
 173         /* allocate the ring buffer */
 174         ring = kmem_zalloc(sizeof (oce_ring_buffer_t), KM_NOSLEEP);
 175         if (ring == NULL) {
 176                 return (NULL);
 177         }
 178 
 179         /* 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");
 185                 goto dbuf_fail;
 186         }
 187 
 188         /* fill the rest of the ring */
 189         ring->num_items = num_items;
 190         ring->item_size = item_size;
 191         ring->num_used  = 0;
 192         return (ring);
 193 
 194 dbuf_fail:
 195         kmem_free(ring, sizeof (oce_ring_buffer_t));
 196         return (NULL);
 197 } /* create_ring_buffer */
 198 
 199 /*
 200  * function to destroy a ring buffer
 201  *
 202  * dev - software handle to teh device
 203  * ring - the ring buffer to delete
 204  *
 205  * return none
 206  */
 207 void
 208 destroy_ring_buffer(struct oce_dev *dev, oce_ring_buffer_t *ring)
 209 {
 210         ASSERT(dev != NULL);
 211         ASSERT(ring !=  NULL);
 212 
 213         /* free the dbuf associated with the ring */
 214         oce_free_dma_buffer(dev, ring->dbuf);
 215         ring->dbuf = NULL;
 216 
 217         /* free the ring itself */
 218         kmem_free(ring, sizeof (oce_ring_buffer_t));
 219 } /* destroy_ring_buffer */
 220 
 221 
 222 /*
 223  * function to enable the fma flags
 224  * fm_caps - FM capability flags
 225  *
 226  * return none
 227  */
 228 
 229 void
 230 oce_set_dma_fma_flags(int fm_caps)
 231 {
 232         if (fm_caps == DDI_FM_NOT_CAPABLE) {
 233                 return;
 234         }
 235 


   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009-2012 Emulex. All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 
  28 /*
  29  * Source file containing the implementation of Driver buffer management
  30  * and related helper functions
  31  */
  32 #include <oce_impl.h>
  33 
  34 static ddi_dma_attr_t oce_dma_buf_attr = {
  35         DMA_ATTR_V0,            /* version number */
  36         0x0000000000000000ull,  /* low address */
  37         0xFFFFFFFFFFFFFFFFull,  /* high address */
  38         0x00000000FFFFFFFFull,  /* dma counter max */
  39         OCE_DMA_ALIGNMENT,      /* alignment */
  40         0x00000FFF,             /* burst sizes */
  41         0x00000001,             /* minimum transfer size */
  42         0x00000000FFFFFFFFull,  /* maximum transfer size */
  43         0xFFFFFFFFFFFFFFFFull,  /* maximum segment size */
  44         1,                      /* scatter/gather list length */
  45         0x00000001,             /* granularity */
  46         0                       /* DMA flags */
  47 };
  48 
  49 static ddi_device_acc_attr_t oce_dma_buf_accattr = {
  50         DDI_DEVICE_ATTR_V0,
  51         DDI_NEVERSWAP_ACC,
  52         DDI_STRICTORDER_ACC,
  53 };
  54 
  55 
  56 /*
  57  * function to allocate a dma buffer for mapping memory va-pa
  58  *
  59  * dev - software handle to device
  60  * size - size of the memory to map
  61  * flags - DDI_DMA_CONSISTENT/DDI_DMA_STREAMING
  62  *
  63  * return pointer to a oce_dma_buf_t structure handling the map
  64  *      NULL => failure
  65  */
  66 int
  67 oce_alloc_dma_buffer(struct oce_dev *dev, oce_dma_buf_t *dbuf,
  68     uint32_t size, ddi_dma_attr_t *dma_attr, uint32_t flags)
  69 {



  70         size_t actual_len;
  71         int ret = 0;
  72 
  73         ASSERT(size > 0);
  74         /* if NULL use default */
  75         if (dma_attr == NULL) {
  76                 dma_attr = &oce_dma_buf_attr;
  77         }
  78 





  79         /* allocate dma handle */
  80         ret = ddi_dma_alloc_handle(dev->dip, dma_attr,
  81             DDI_DMA_DONTWAIT, NULL, &dbuf->dma_handle);
  82         if (ret != DDI_SUCCESS) {
  83                 oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
  84                     "Failed to allocate DMA handle");
  85                 goto handle_fail;
  86         }
  87         /* allocate the DMA-able memory */
  88         ret = ddi_dma_mem_alloc(dbuf->dma_handle, size, &oce_dma_buf_accattr,
  89             (flags & DDI_DMA_STREAMING) ?
  90             DDI_DMA_STREAMING : DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL,
  91             &dbuf->base, &actual_len, &dbuf->acc_handle);
  92         if (ret != DDI_SUCCESS) {
  93                 oce_log(dev, CE_NOTE, MOD_CONFIG,
  94                     "Failed to allocate DMA memory: 0x%x bytes", size);
  95                 goto alloc_fail;
  96         }
  97 
  98         /* bind handle */
  99         ret = ddi_dma_addr_bind_handle(dbuf->dma_handle,
 100             (struct as *)0, dbuf->base, actual_len,
 101             flags,
 102             DDI_DMA_DONTWAIT, NULL, &dbuf->cookie, &dbuf->ncookies);
 103         if (ret != DDI_DMA_MAPPED) {
 104                 oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
 105                     "Failed to bind dma handle");
 106                 goto bind_fail;
 107         }
 108         bzero(dbuf->base, actual_len);
 109         dbuf->addr = dbuf->cookie.dmac_laddress;
 110         dbuf->size = actual_len;
 111         /* usable length */
 112         dbuf->len  = size;
 113         dbuf->num_pages = OCE_NUM_PAGES(size);
 114         return (DDI_SUCCESS);
 115 
 116 bind_fail:
 117         ddi_dma_mem_free(&dbuf->acc_handle);
 118 alloc_fail:
 119         ddi_dma_free_handle(&dbuf->dma_handle);
 120 handle_fail:
 121         return (ret);

 122 } /* oce_dma_alloc_buffer */
 123 
 124 /*
 125  * function to delete a dma buffer
 126  *
 127  * dev - software handle to device
 128  * dbuf - dma obj  to delete
 129  *
 130  * return none
 131  */
 132 void
 133 oce_free_dma_buffer(struct oce_dev *dev, oce_dma_buf_t *dbuf)
 134 {
 135         _NOTE(ARGUNUSED(dev));
 136 
 137         if (dbuf == NULL) {
 138                 return;
 139         }
 140         if (dbuf->dma_handle != NULL) {
 141                 (void) ddi_dma_unbind_handle(dbuf->dma_handle);
 142         }
 143         if (dbuf->acc_handle != NULL) {
 144                 ddi_dma_mem_free(&dbuf->acc_handle);
 145                 dbuf->acc_handle = NULL;
 146         }
 147         if (dbuf->dma_handle != NULL) {
 148                 ddi_dma_free_handle(&dbuf->dma_handle);
 149                 dbuf->dma_handle = NULL;
 150         }

 151 } /* oce_free_dma_buffer */
 152 
 153 /*
 154  * function to create a ring buffer
 155  *
 156  * dev - software handle to the device
 157  * num_items - number of items in the ring
 158  * item_size - size of an individual item in the ring
 159  * flags - DDI_DMA_CONSISTENT/DDI_DMA_STREAMING for ring memory
 160  *
 161  * return pointer to a ring_buffer structure, NULL on failure
 162  */
 163 oce_ring_buffer_t *
 164 oce_create_ring_buffer(struct oce_dev *dev,
 165     uint32_t num_items, uint32_t item_size, uint32_t flags)
 166 {
 167         oce_ring_buffer_t *ring;
 168         int ret;
 169 
 170         /* allocate the ring buffer */
 171         ring = kmem_zalloc(sizeof (oce_ring_buffer_t), KM_NOSLEEP);
 172         if (ring == NULL) {
 173                 return (NULL);
 174         }
 175 
 176         /* get the dbuf defining the ring */
 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);
 182                 goto dbuf_fail;
 183         }
 184 
 185         /* fill the rest of the ring */
 186         ring->num_items = num_items;
 187         ring->item_size = item_size;
 188         ring->num_used  = 0;
 189         return (ring);
 190 
 191 dbuf_fail:
 192         kmem_free(ring, sizeof (oce_ring_buffer_t));
 193         return (NULL);
 194 } /* create_ring_buffer */
 195 
 196 /*
 197  * function to destroy a ring buffer
 198  *
 199  * dev - software handle to teh device
 200  * ring - the ring buffer to delete
 201  *
 202  * return none
 203  */
 204 void
 205 destroy_ring_buffer(struct oce_dev *dev, oce_ring_buffer_t *ring)
 206 {
 207         ASSERT(dev != NULL);
 208         ASSERT(ring !=  NULL);
 209 
 210         /* free the dbuf associated with the ring */
 211         oce_free_dma_buffer(dev, &ring->dbuf);

 212 
 213         /* free the ring itself */
 214         kmem_free(ring, sizeof (oce_ring_buffer_t));
 215 } /* destroy_ring_buffer */
 216 
 217 
 218 /*
 219  * function to enable the fma flags
 220  * fm_caps - FM capability flags
 221  *
 222  * return none
 223  */
 224 
 225 void
 226 oce_set_dma_fma_flags(int fm_caps)
 227 {
 228         if (fm_caps == DDI_FM_NOT_CAPABLE) {
 229                 return;
 230         }
 231