Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
infiniband
hw
amso1100
c2_alloc.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2004 Topspin Communications. All rights reserved.
3
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4
*
5
* This software is available to you under a choice of one of two
6
* licenses. You may choose to be licensed under the terms of the GNU
7
* General Public License (GPL) Version 2, available from the file
8
* COPYING in the main directory of this source tree, or the
9
* OpenIB.org BSD license below:
10
*
11
* Redistribution and use in source and binary forms, with or
12
* without modification, are permitted provided that the following
13
* conditions are met:
14
*
15
* - Redistributions of source code must retain the above
16
* copyright notice, this list of conditions and the following
17
* disclaimer.
18
*
19
* - Redistributions in binary form must reproduce the above
20
* copyright notice, this list of conditions and the following
21
* disclaimer in the documentation and/or other materials
22
* provided with the distribution.
23
*
24
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
* SOFTWARE.
32
*/
33
34
#include <linux/errno.h>
35
#include <linux/bitmap.h>
36
37
#include "
c2.h
"
38
39
static
int
c2_alloc_mqsp_chunk(
struct
c2_dev
*c2dev,
gfp_t
gfp_mask
,
40
struct
sp_chunk
**
head
)
41
{
42
int
i
;
43
struct
sp_chunk
*new_head;
44
dma_addr_t
dma_addr
;
45
46
new_head =
dma_alloc_coherent
(&c2dev->
pcidev
->dev,
PAGE_SIZE
,
47
&dma_addr, gfp_mask);
48
if
(new_head ==
NULL
)
49
return
-
ENOMEM
;
50
51
new_head->
dma_addr
=
dma_addr
;
52
dma_unmap_addr_set
(new_head,
mapping
, new_head->
dma_addr
);
53
54
new_head->
next
=
NULL
;
55
new_head->
head
= 0;
56
57
/* build list where each index is the next free slot */
58
for
(i = 0;
59
i < (
PAGE_SIZE
-
sizeof
(
struct
sp_chunk
) -
60
sizeof
(
u16
)) /
sizeof
(
u16
) - 1;
61
i++) {
62
new_head->
shared_ptr
[
i
] = i + 1;
63
}
64
/* terminate list */
65
new_head->
shared_ptr
[
i
] = 0xFFFF;
66
67
*head = new_head;
68
return
0;
69
}
70
71
int
c2_init_mqsp_pool
(
struct
c2_dev
*c2dev,
gfp_t
gfp_mask,
72
struct
sp_chunk
**root)
73
{
74
return
c2_alloc_mqsp_chunk(c2dev, gfp_mask, root);
75
}
76
77
void
c2_free_mqsp_pool
(
struct
c2_dev
*c2dev,
struct
sp_chunk
*root)
78
{
79
struct
sp_chunk
*
next
;
80
81
while
(root) {
82
next = root->
next
;
83
dma_free_coherent
(&c2dev->
pcidev
->dev,
PAGE_SIZE
, root,
84
dma_unmap_addr
(root,
mapping
));
85
root =
next
;
86
}
87
}
88
89
__be16
*
c2_alloc_mqsp
(
struct
c2_dev
*c2dev,
struct
sp_chunk
*head,
90
dma_addr_t
*dma_addr,
gfp_t
gfp_mask)
91
{
92
u16
mqsp;
93
94
while
(head) {
95
mqsp = head->
head
;
96
if
(mqsp != 0xFFFF) {
97
head->
head
= head->
shared_ptr
[mqsp];
98
break
;
99
}
else
if
(head->
next
==
NULL
) {
100
if
(c2_alloc_mqsp_chunk(c2dev, gfp_mask, &head->
next
) ==
101
0) {
102
head = head->
next
;
103
mqsp = head->
head
;
104
head->
head
= head->
shared_ptr
[mqsp];
105
break
;
106
}
else
107
return
NULL
;
108
}
else
109
head = head->
next
;
110
}
111
if
(head) {
112
*dma_addr = head->
dma_addr
+
113
((
unsigned
long
) &(head->
shared_ptr
[mqsp]) -
114
(
unsigned
long
) head);
115
pr_debug
(
"%s addr %p dma_addr %llx\n"
, __func__,
116
&(head->shared_ptr[mqsp]), (
unsigned
long
long
) *dma_addr);
117
return
(
__force
__be16
*) &(head->shared_ptr[mqsp]);
118
}
119
return
NULL
;
120
}
121
122
void
c2_free_mqsp
(
__be16
*mqsp)
123
{
124
struct
sp_chunk
*
head
;
125
u16
idx
;
126
127
/* The chunk containing this ptr begins at the page boundary */
128
head = (
struct
sp_chunk
*) ((
unsigned
long
) mqsp &
PAGE_MASK
);
129
130
/* Link head to new mqsp */
131
*mqsp = (
__force
__be16
) head->
head
;
132
133
/* Compute the shared_ptr index */
134
idx = ((
unsigned
long
) mqsp & ~
PAGE_MASK
) >> 1;
135
idx -= (
unsigned
long
) &(((
struct
sp_chunk
*) 0)->
shared_ptr
[0]) >> 1;
136
137
/* Point this index at the head */
138
head->
shared_ptr
[
idx
] = head->
head
;
139
140
/* Point head at this index */
141
head->
head
=
idx
;
142
}
Generated on Thu Jan 10 2013 13:37:13 for Linux Kernel by
1.8.2