• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/linux/linux-2.6/drivers/infiniband/hw/ipath/
1/*
2 * Copyright (c) 2006 QLogic, Corporation. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses.  You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 *     Redistribution and use in source and binary forms, with or
11 *     without modification, are permitted provided that the following
12 *     conditions are met:
13 *
14 *      - Redistributions of source code must retain the above
15 *        copyright notice, this list of conditions and the following
16 *        disclaimer.
17 *
18 *      - Redistributions in binary form must reproduce the above
19 *        copyright notice, this list of conditions and the following
20 *        disclaimer in the documentation and/or other materials
21 *        provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33#include <rdma/ib_verbs.h>
34
35#include "ipath_verbs.h"
36
37#define BAD_DMA_ADDRESS ((u64) 0)
38
39/*
40 * The following functions implement driver specific replacements
41 * for the ib_dma_*() functions.
42 *
43 * These functions return kernel virtual addresses instead of
44 * device bus addresses since the driver uses the CPU to copy
45 * data instead of using hardware DMA.
46 */
47
48static int ipath_mapping_error(struct ib_device *dev, u64 dma_addr)
49{
50	return dma_addr == BAD_DMA_ADDRESS;
51}
52
53static u64 ipath_dma_map_single(struct ib_device *dev,
54			        void *cpu_addr, size_t size,
55			        enum dma_data_direction direction)
56{
57	BUG_ON(!valid_dma_direction(direction));
58	return (u64) cpu_addr;
59}
60
61static void ipath_dma_unmap_single(struct ib_device *dev,
62				   u64 addr, size_t size,
63				   enum dma_data_direction direction)
64{
65	BUG_ON(!valid_dma_direction(direction));
66}
67
68static u64 ipath_dma_map_page(struct ib_device *dev,
69			      struct page *page,
70			      unsigned long offset,
71			      size_t size,
72			      enum dma_data_direction direction)
73{
74	u64 addr;
75
76	BUG_ON(!valid_dma_direction(direction));
77
78	if (offset + size > PAGE_SIZE) {
79		addr = BAD_DMA_ADDRESS;
80		goto done;
81	}
82
83	addr = (u64) page_address(page);
84	if (addr)
85		addr += offset;
86	/* TODO: handle highmem pages */
87
88done:
89	return addr;
90}
91
92static void ipath_dma_unmap_page(struct ib_device *dev,
93				 u64 addr, size_t size,
94				 enum dma_data_direction direction)
95{
96	BUG_ON(!valid_dma_direction(direction));
97}
98
99static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sg, int nents,
100			enum dma_data_direction direction)
101{
102	u64 addr;
103	int i;
104	int ret = nents;
105
106	BUG_ON(!valid_dma_direction(direction));
107
108	for (i = 0; i < nents; i++) {
109		addr = (u64) page_address(sg[i].page);
110		/* TODO: handle highmem pages */
111		if (!addr) {
112			ret = 0;
113			break;
114		}
115	}
116	return ret;
117}
118
119static void ipath_unmap_sg(struct ib_device *dev,
120			   struct scatterlist *sg, int nents,
121			   enum dma_data_direction direction)
122{
123	BUG_ON(!valid_dma_direction(direction));
124}
125
126static u64 ipath_sg_dma_address(struct ib_device *dev, struct scatterlist *sg)
127{
128	u64 addr = (u64) page_address(sg->page);
129
130	if (addr)
131		addr += sg->offset;
132	return addr;
133}
134
135static unsigned int ipath_sg_dma_len(struct ib_device *dev,
136				     struct scatterlist *sg)
137{
138	return sg->length;
139}
140
141static void ipath_sync_single_for_cpu(struct ib_device *dev,
142				      u64 addr,
143				      size_t size,
144				      enum dma_data_direction dir)
145{
146}
147
148static void ipath_sync_single_for_device(struct ib_device *dev,
149					 u64 addr,
150					 size_t size,
151					 enum dma_data_direction dir)
152{
153}
154
155static void *ipath_dma_alloc_coherent(struct ib_device *dev, size_t size,
156				      u64 *dma_handle, gfp_t flag)
157{
158	struct page *p;
159	void *addr = NULL;
160
161	p = alloc_pages(flag, get_order(size));
162	if (p)
163		addr = page_address(p);
164	if (dma_handle)
165		*dma_handle = (u64) addr;
166	return addr;
167}
168
169static void ipath_dma_free_coherent(struct ib_device *dev, size_t size,
170				    void *cpu_addr, u64 dma_handle)
171{
172	free_pages((unsigned long) cpu_addr, get_order(size));
173}
174
175struct ib_dma_mapping_ops ipath_dma_mapping_ops = {
176	ipath_mapping_error,
177	ipath_dma_map_single,
178	ipath_dma_unmap_single,
179	ipath_dma_map_page,
180	ipath_dma_unmap_page,
181	ipath_map_sg,
182	ipath_unmap_sg,
183	ipath_sg_dma_address,
184	ipath_sg_dma_len,
185	ipath_sync_single_for_cpu,
186	ipath_sync_single_for_device,
187	ipath_dma_alloc_coherent,
188	ipath_dma_free_coherent
189};
190