Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  *  IBM eServer eHCA Infiniband device driver for Linux on POWER
  3  *
  4  *  PD functions
  5  *
  6  *  Authors: Christoph Raisch <raisch@de.ibm.com>
  7  *
  8  *  Copyright (c) 2005 IBM Corporation
  9  *
 10  *  All rights reserved.
 11  *
 12  *  This source code is distributed under a dual license of GPL v2.0 and OpenIB
 13  *  BSD.
 14  *
 15  * OpenIB BSD License
 16  *
 17  * Redistribution and use in source and binary forms, with or without
 18  * modification, are permitted provided that the following conditions are met:
 19  *
 20  * Redistributions of source code must retain the above copyright notice, this
 21  * list of conditions and the following disclaimer.
 22  *
 23  * Redistributions in binary form must reproduce the above copyright notice,
 24  * this list of conditions and the following disclaimer in the documentation
 25  * and/or other materials
 26  * provided with the distribution.
 27  *
 28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 29  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 31  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 32  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 35  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 36  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 38  * POSSIBILITY OF SUCH DAMAGE.
 39  */
 40 
 41 #include <asm/current.h>
 42 
 43 #include "ehca_tools.h"
 44 #include "ehca_iverbs.h"
 45 
 46 static struct kmem_cache *pd_cache;
 47 
 48 struct ib_pd *ehca_alloc_pd(struct ib_device *device,
 49                             struct ib_ucontext *context, struct ib_udata *udata)
 50 {
 51         struct ehca_pd *pd;
 52         int i;
 53 
 54         pd = kmem_cache_zalloc(pd_cache, GFP_KERNEL);
 55         if (!pd) {
 56                 ehca_err(device, "device=%p context=%p out of memory",
 57                          device, context);
 58                 return ERR_PTR(-ENOMEM);
 59         }
 60 
 61         pd->ownpid = current->tgid;
 62         for (i = 0; i < 2; i++) {
 63                 INIT_LIST_HEAD(&pd->free[i]);
 64                 INIT_LIST_HEAD(&pd->full[i]);
 65         }
 66         mutex_init(&pd->lock);
 67 
 68         /*
 69          * Kernel PD: when device = -1, 0
 70          * User   PD: when context != -1
 71          */
 72         if (!context) {
 73                 /*
 74                  * Kernel PDs after init reuses always
 75                  * the one created in ehca_shca_reopen()
 76                  */
 77                 struct ehca_shca *shca = container_of(device, struct ehca_shca,
 78                                                       ib_device);
 79                 pd->fw_pd.value = shca->pd->fw_pd.value;
 80         } else
 81                 pd->fw_pd.value = (u64)pd;
 82 
 83         return &pd->ib_pd;
 84 }
 85 
 86 int ehca_dealloc_pd(struct ib_pd *pd)
 87 {
 88         u32 cur_pid = current->tgid;
 89         struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd);
 90         int i, leftovers = 0;
 91         struct ipz_small_queue_page *page, *tmp;
 92 
 93         if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
 94             my_pd->ownpid != cur_pid) {
 95                 ehca_err(pd->device, "Invalid caller pid=%x ownpid=%x",
 96                          cur_pid, my_pd->ownpid);
 97                 return -EINVAL;
 98         }
 99 
100         for (i = 0; i < 2; i++) {
101                 list_splice(&my_pd->full[i], &my_pd->free[i]);
102                 list_for_each_entry_safe(page, tmp, &my_pd->free[i], list) {
103                         leftovers = 1;
104                         free_page(page->page);
105                         kmem_cache_free(small_qp_cache, page);
106                 }
107         }
108 
109         if (leftovers)
110                 ehca_warn(pd->device,
111                           "Some small queue pages were not freed");
112 
113         kmem_cache_free(pd_cache, my_pd);
114 
115         return 0;
116 }
117 
118 int ehca_init_pd_cache(void)
119 {
120         pd_cache = kmem_cache_create("ehca_cache_pd",
121                                      sizeof(struct ehca_pd), 0,
122                                      SLAB_HWCACHE_ALIGN,
123                                      NULL);
124         if (!pd_cache)
125                 return -ENOMEM;
126         return 0;
127 }
128 
129 void ehca_cleanup_pd_cache(void)
130 {
131         if (pd_cache)
132                 kmem_cache_destroy(pd_cache);
133 }
134 
  This page was automatically generated by the LXR engine.