diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/parisc/ccio-rm-dma.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/parisc/ccio-rm-dma.c')
-rw-r--r-- | drivers/parisc/ccio-rm-dma.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c new file mode 100644 index 000000000000..57e6385976e2 --- /dev/null +++ b/drivers/parisc/ccio-rm-dma.c | |||
@@ -0,0 +1,201 @@ | |||
1 | /* | ||
2 | * ccio-rm-dma.c: | ||
3 | * DMA management routines for first generation cache-coherent machines. | ||
4 | * "Real Mode" operation refers to U2/Uturn chip operation. The chip | ||
5 | * can perform coherency checks w/o using the I/O MMU. That's all we | ||
6 | * need until support for more than 4GB phys mem is needed. | ||
7 | * | ||
8 | * This is the trivial case - basically what x86 does. | ||
9 | * | ||
10 | * Drawbacks of using Real Mode are: | ||
11 | * o outbound DMA is slower since one isn't using the prefetching | ||
12 | * U2 can do for outbound DMA. | ||
13 | * o Ability to do scatter/gather in HW is also lost. | ||
14 | * o only known to work with PCX-W processor. (eg C360) | ||
15 | * (PCX-U/U+ are not coherent with U2 in real mode.) | ||
16 | * | ||
17 | * | ||
18 | * This program is free software; you can redistribute it and/or modify | ||
19 | * it under the terms of the GNU General Public License as published by | ||
20 | * the Free Software Foundation; either version 2 of the License, or | ||
21 | * (at your option) any later version. | ||
22 | * | ||
23 | * | ||
24 | * Original version/author: | ||
25 | * CVSROOT=:pserver:anonymous@198.186.203.37:/cvsroot/linux-parisc | ||
26 | * cvs -z3 co linux/arch/parisc/kernel/dma-rm.c | ||
27 | * | ||
28 | * (C) Copyright 2000 Philipp Rumpf <prumpf@tux.org> | ||
29 | * | ||
30 | * | ||
31 | * Adopted for The Puffin Group's parisc-linux port by Grant Grundler. | ||
32 | * (C) Copyright 2000 Grant Grundler <grundler@puffin.external.hp.com> | ||
33 | * | ||
34 | */ | ||
35 | |||
36 | #include <linux/types.h> | ||
37 | #include <linux/init.h> | ||
38 | #include <linux/mm.h> | ||
39 | #include <linux/string.h> | ||
40 | #include <linux/pci.h> | ||
41 | |||
42 | #include <asm/uaccess.h> | ||
43 | |||
44 | #include <asm/io.h> | ||
45 | #include <asm/hardware.h> | ||
46 | #include <asm/page.h> | ||
47 | |||
48 | /* Only chose "ccio" since that's what HP-UX calls it.... | ||
49 | ** Make it easier for folks to migrate from one to the other :^) | ||
50 | */ | ||
51 | #define MODULE_NAME "ccio" | ||
52 | |||
53 | #define U2_IOA_RUNWAY 0x580 | ||
54 | #define U2_BC_GSC 0x501 | ||
55 | #define UTURN_IOA_RUNWAY 0x581 | ||
56 | #define UTURN_BC_GSC 0x502 | ||
57 | |||
58 | #define IS_U2(id) ( \ | ||
59 | (((id)->hw_type == HPHW_IOA) && ((id)->hversion == U2_IOA_RUNWAY)) || \ | ||
60 | (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == U2_BC_GSC)) \ | ||
61 | ) | ||
62 | |||
63 | #define IS_UTURN(id) ( \ | ||
64 | (((id)->hw_type == HPHW_IOA) && ((id)->hversion == UTURN_IOA_RUNWAY)) || \ | ||
65 | (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == UTURN_BC_GSC)) \ | ||
66 | ) | ||
67 | |||
68 | static int ccio_dma_supported( struct pci_dev *dev, u64 mask) | ||
69 | { | ||
70 | if (dev == NULL) { | ||
71 | printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n"); | ||
72 | BUG(); | ||
73 | return(0); | ||
74 | } | ||
75 | |||
76 | /* only support 32-bit devices (ie PCI/GSC) */ | ||
77 | return((int) (mask >= 0xffffffffUL)); | ||
78 | } | ||
79 | |||
80 | |||
81 | static void *ccio_alloc_consistent(struct pci_dev *dev, size_t size, | ||
82 | dma_addr_t *handle) | ||
83 | { | ||
84 | void *ret; | ||
85 | |||
86 | ret = (void *)__get_free_pages(GFP_ATOMIC, get_order(size)); | ||
87 | |||
88 | if (ret != NULL) { | ||
89 | memset(ret, 0, size); | ||
90 | *handle = virt_to_phys(ret); | ||
91 | } | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | static void ccio_free_consistent(struct pci_dev *dev, size_t size, | ||
96 | void *vaddr, dma_addr_t handle) | ||
97 | { | ||
98 | free_pages((unsigned long)vaddr, get_order(size)); | ||
99 | } | ||
100 | |||
101 | static dma_addr_t ccio_map_single(struct pci_dev *dev, void *ptr, size_t size, | ||
102 | int direction) | ||
103 | { | ||
104 | return virt_to_phys(ptr); | ||
105 | } | ||
106 | |||
107 | static void ccio_unmap_single(struct pci_dev *dev, dma_addr_t dma_addr, | ||
108 | size_t size, int direction) | ||
109 | { | ||
110 | /* Nothing to do */ | ||
111 | } | ||
112 | |||
113 | |||
114 | static int ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction) | ||
115 | { | ||
116 | int tmp = nents; | ||
117 | |||
118 | /* KISS: map each buffer separately. */ | ||
119 | while (nents) { | ||
120 | sg_dma_address(sglist) = ccio_map_single(dev, sglist->address, sglist->length, direction); | ||
121 | sg_dma_len(sglist) = sglist->length; | ||
122 | nents--; | ||
123 | sglist++; | ||
124 | } | ||
125 | |||
126 | return tmp; | ||
127 | } | ||
128 | |||
129 | |||
130 | static void ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction) | ||
131 | { | ||
132 | #if 0 | ||
133 | while (nents) { | ||
134 | ccio_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction); | ||
135 | nents--; | ||
136 | sglist++; | ||
137 | } | ||
138 | return; | ||
139 | #else | ||
140 | /* Do nothing (copied from current ccio_unmap_single() :^) */ | ||
141 | #endif | ||
142 | } | ||
143 | |||
144 | |||
145 | static struct pci_dma_ops ccio_ops = { | ||
146 | ccio_dma_supported, | ||
147 | ccio_alloc_consistent, | ||
148 | ccio_free_consistent, | ||
149 | ccio_map_single, | ||
150 | ccio_unmap_single, | ||
151 | ccio_map_sg, | ||
152 | ccio_unmap_sg, | ||
153 | NULL, /* dma_sync_single_for_cpu : NOP for U2 */ | ||
154 | NULL, /* dma_sync_single_for_device : NOP for U2 */ | ||
155 | NULL, /* dma_sync_sg_for_cpu : ditto */ | ||
156 | NULL, /* dma_sync_sg_for_device : ditto */ | ||
157 | }; | ||
158 | |||
159 | |||
160 | /* | ||
161 | ** Determine if u2 should claim this chip (return 0) or not (return 1). | ||
162 | ** If so, initialize the chip and tell other partners in crime they | ||
163 | ** have work to do. | ||
164 | */ | ||
165 | static int | ||
166 | ccio_probe(struct parisc_device *dev) | ||
167 | { | ||
168 | printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME, | ||
169 | dev->id.hversion == U2_BC_GSC ? "U2" : "UTurn", | ||
170 | dev->hpa); | ||
171 | |||
172 | /* | ||
173 | ** FIXME - should check U2 registers to verify it's really running | ||
174 | ** in "Real Mode". | ||
175 | */ | ||
176 | |||
177 | #if 0 | ||
178 | /* will need this for "Virtual Mode" operation */ | ||
179 | ccio_hw_init(ccio_dev); | ||
180 | ccio_common_init(ccio_dev); | ||
181 | #endif | ||
182 | hppa_dma_ops = &ccio_ops; | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | static struct parisc_device_id ccio_tbl[] = { | ||
187 | { HPHW_BCPORT, HVERSION_REV_ANY_ID, U2_BC_GSC, 0xc }, | ||
188 | { HPHW_BCPORT, HVERSION_REV_ANY_ID, UTURN_BC_GSC, 0xc }, | ||
189 | { 0, } | ||
190 | }; | ||
191 | |||
192 | static struct parisc_driver ccio_driver = { | ||
193 | .name = "U2/Uturn", | ||
194 | .id_table = ccio_tbl, | ||
195 | .probe = ccio_probe, | ||
196 | }; | ||
197 | |||
198 | void __init ccio_init(void) | ||
199 | { | ||
200 | register_parisc_driver(&ccio_driver); | ||
201 | } | ||