Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | |
2 | Writing SBUS Drivers | |
3 | ||
4 | David S. Miller (davem@redhat.com) | |
5 | ||
6 | The SBUS driver interfaces of the Linux kernel have been | |
7 | revamped completely for 2.4.x for several reasons. Foremost were | |
8 | performance and complexity concerns. This document details these | |
9 | new interfaces and how they are used to write an SBUS device driver. | |
10 | ||
11 | SBUS drivers need to include <asm/sbus.h> to get access | |
12 | to functions and structures described here. | |
13 | ||
14 | Probing and Detection | |
15 | ||
16 | Each SBUS device inside the machine is described by a | |
17 | structure called "struct sbus_dev". Likewise, each SBUS bus | |
18 | found in the system is described by a "struct sbus_bus". For | |
19 | each SBUS bus, the devices underneath are hung in a tree-like | |
20 | fashion off of the bus structure. | |
21 | ||
22 | The SBUS device structure contains enough information | |
23 | for you to implement your device probing algorithm and obtain | |
24 | the bits necessary to run your device. The most commonly | |
25 | used members of this structure, and their typical usage, | |
26 | will be detailed below. | |
27 | ||
992caacf ML |
28 | Here is a piece of skeleton code for performing a device |
29 | probe in an SBUS driver under Linux: | |
1da177e4 | 30 | |
9eccf1b3 | 31 | static int __devinit mydevice_probe_one(struct sbus_dev *sdev) |
1da177e4 | 32 | { |
9eccf1b3 DM |
33 | struct mysdevice *mp = kzalloc(sizeof(*mp), GFP_KERNEL); |
34 | ||
35 | if (!mp) | |
36 | return -ENODEV; | |
37 | ||
38 | ... | |
39 | dev_set_drvdata(&sdev->ofdev.dev, mp); | |
40 | return 0; | |
1da177e4 LT |
41 | ... |
42 | } | |
43 | ||
9eccf1b3 DM |
44 | static int __devinit mydevice_probe(struct of_device *dev, |
45 | const struct of_device_id *match) | |
1da177e4 | 46 | { |
9eccf1b3 DM |
47 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); |
48 | ||
49 | return mydevice_probe_one(sdev); | |
1da177e4 LT |
50 | } |
51 | ||
9eccf1b3 | 52 | static int __devexit mydevice_remove(struct of_device *dev) |
1da177e4 | 53 | { |
9eccf1b3 DM |
54 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); |
55 | struct mydevice *mp = dev_get_drvdata(&dev->dev); | |
1da177e4 | 56 | |
9eccf1b3 | 57 | return mydevice_remove_one(sdev, mp); |
1da177e4 LT |
58 | } |
59 | ||
9eccf1b3 DM |
60 | static struct of_device_id mydevice_match[] = { |
61 | { | |
62 | .name = "mydevice", | |
63 | }, | |
64 | {}, | |
65 | }; | |
66 | ||
67 | MODULE_DEVICE_TABLE(of, mydevice_match); | |
1da177e4 | 68 | |
9eccf1b3 DM |
69 | static struct of_platform_driver mydevice_driver = { |
70 | .name = "mydevice", | |
71 | .match_table = mydevice_match, | |
72 | .probe = mydevice_probe, | |
73 | .remove = __devexit_p(mydevice_remove), | |
74 | }; | |
75 | ||
76 | static int __init mydevice_init(void) | |
77 | { | |
78 | return of_register_driver(&mydevice_driver, &sbus_bus_type); | |
79 | } | |
80 | ||
81 | static void __exit mydevice_exit(void) | |
82 | { | |
83 | of_unregister_driver(&mydevice_driver); | |
84 | } | |
85 | ||
86 | module_init(mydevice_init); | |
87 | module_exit(mydevice_exit); | |
88 | ||
89 | The mydevice_match table is a series of entries which | |
90 | describes what SBUS devices your driver is meant for. In the | |
91 | simplest case you specify a string for the 'name' field. Every | |
92 | SBUS device with a 'name' property matching your string will | |
93 | be passed one-by-one to your .probe method. | |
94 | ||
95 | You should store away your device private state structure | |
96 | pointer in the drvdata area so that you can retrieve it later on | |
97 | in your .remove method. | |
98 | ||
99 | Any memory allocated, registers mapped, IRQs registered, | |
100 | etc. must be undone by your .remove method so that all resources | |
d6bc8ac9 | 101 | of your device are released by the time it returns. |
9eccf1b3 DM |
102 | |
103 | You should _NOT_ use the for_each_sbus(), for_each_sbusdev(), | |
104 | and for_all_sbusdev() interfaces. They are deprecated, will be | |
105 | removed, and no new driver should reference them ever. | |
1da177e4 LT |
106 | |
107 | Mapping and Accessing I/O Registers | |
108 | ||
109 | Each SBUS device structure contains an array of descriptors | |
110 | which describe each register set. We abuse struct resource for that. | |
111 | They each correspond to the "reg" properties provided by the OBP firmware. | |
112 | ||
113 | Before you can access your device's registers you must map | |
114 | them. And later if you wish to shutdown your driver (for module | |
115 | unload or similar) you must unmap them. You must treat them as | |
116 | a resource, which you allocate (map) before using and free up | |
117 | (unmap) when you are done with it. | |
118 | ||
119 | The mapping information is stored in an opaque value | |
120 | typed as an "unsigned long". This is the type of the return value | |
121 | of the mapping interface, and the arguments to the unmapping | |
122 | interface. Let's say you want to map the first set of registers. | |
123 | Perhaps part of your driver software state structure looks like: | |
124 | ||
125 | struct mydevice { | |
126 | unsigned long control_regs; | |
127 | ... | |
128 | struct sbus_dev *sdev; | |
129 | ... | |
130 | }; | |
131 | ||
132 | At initialization time you then use the sbus_ioremap | |
133 | interface to map in your registers, like so: | |
134 | ||
135 | static void init_one_mydevice(struct sbus_dev *sdev) | |
136 | { | |
137 | struct mydevice *mp; | |
138 | ... | |
139 | ||
140 | mp->control_regs = sbus_ioremap(&sdev->resource[0], 0, | |
141 | CONTROL_REGS_SIZE, "mydevice regs"); | |
142 | if (!mp->control_regs) { | |
143 | /* Failure, cleanup and return. */ | |
144 | } | |
145 | } | |
146 | ||
147 | Second argument to sbus_ioremap is an offset for | |
148 | cranky devices with broken OBP PROM. The sbus_ioremap uses only | |
149 | a start address and flags from the resource structure. | |
150 | Therefore it is possible to use the same resource to map | |
151 | several sets of registers or even to fabricate a resource | |
152 | structure if driver gets physical address from some private place. | |
153 | This practice is discouraged though. Use whatever OBP PROM | |
154 | provided to you. | |
155 | ||
156 | And here is how you might unmap these registers later at | |
157 | driver shutdown or module unload time, using the sbus_iounmap | |
158 | interface: | |
159 | ||
160 | static void mydevice_unmap_regs(struct mydevice *mp) | |
161 | { | |
162 | sbus_iounmap(mp->control_regs, CONTROL_REGS_SIZE); | |
163 | } | |
164 | ||
165 | Finally, to actually access your registers there are 6 | |
166 | interface routines at your disposal. Accesses are byte (8 bit), | |
167 | word (16 bit), or longword (32 bit) sized. Here they are: | |
168 | ||
169 | u8 sbus_readb(unsigned long reg) /* read byte */ | |
170 | u16 sbus_readw(unsigned long reg) /* read word */ | |
171 | u32 sbus_readl(unsigned long reg) /* read longword */ | |
172 | void sbus_writeb(u8 value, unsigned long reg) /* write byte */ | |
173 | void sbus_writew(u16 value, unsigned long reg) /* write word */ | |
174 | void sbus_writel(u32 value, unsigned long reg) /* write longword */ | |
175 | ||
176 | So, let's say your device has a control register of some sort | |
177 | at offset zero. The following might implement resetting your device: | |
178 | ||
179 | #define CONTROL 0x00UL | |
180 | ||
181 | #define CONTROL_RESET 0x00000001 /* Reset hardware */ | |
182 | ||
183 | static void mydevice_reset(struct mydevice *mp) | |
184 | { | |
185 | sbus_writel(CONTROL_RESET, mp->regs + CONTROL); | |
186 | } | |
187 | ||
188 | Or perhaps there is a data port register at an offset of | |
189 | 16 bytes which allows you to read bytes from a fifo in the device: | |
190 | ||
191 | #define DATA 0x10UL | |
192 | ||
193 | static u8 mydevice_get_byte(struct mydevice *mp) | |
194 | { | |
195 | return sbus_readb(mp->regs + DATA); | |
196 | } | |
197 | ||
198 | It's pretty straightforward, and clueful readers may have | |
199 | noticed that these interfaces mimick the PCI interfaces of the | |
200 | Linux kernel. This was not by accident. | |
201 | ||
202 | WARNING: | |
203 | ||
204 | DO NOT try to treat these opaque register mapping | |
205 | values as a memory mapped pointer to some structure | |
206 | which you can dereference. | |
207 | ||
208 | It may be memory mapped, it may not be. In fact it | |
209 | could be a physical address, or it could be the time | |
210 | of day xor'd with 0xdeadbeef. :-) | |
211 | ||
212 | Whatever it is, it's an implementation detail. The | |
213 | interface was done this way to shield the driver | |
214 | author from such complexities. | |
215 | ||
216 | Doing DVMA | |
217 | ||
218 | SBUS devices can perform DMA transactions in a way similar | |
219 | to PCI but dissimilar to ISA, e.g. DMA masters supply address. | |
220 | In contrast to PCI, however, that address (a bus address) is | |
221 | translated by IOMMU before a memory access is performed and therefore | |
222 | it is virtual. Sun calls this procedure DVMA. | |
223 | ||
224 | Linux supports two styles of using SBUS DVMA: "consistent memory" | |
225 | and "streaming DVMA". CPU view of consistent memory chunk is, well, | |
226 | consistent with a view of a device. Think of it as an uncached memory. | |
227 | Typically this way of doing DVMA is not very fast and drivers use it | |
228 | mostly for control blocks or queues. On some CPUs we cannot flush or | |
229 | invalidate individual pages or cache lines and doing explicit flushing | |
230 | over ever little byte in every control block would be wasteful. | |
231 | ||
232 | Streaming DVMA is a preferred way to transfer large amounts of data. | |
233 | This process works in the following way: | |
234 | 1. a CPU stops accessing a certain part of memory, | |
235 | flushes its caches covering that memory; | |
236 | 2. a device does DVMA accesses, then posts an interrupt; | |
237 | 3. CPU invalidates its caches and starts to access the memory. | |
238 | ||
239 | A single streaming DVMA operation can touch several discontiguous | |
240 | regions of a virtual bus address space. This is called a scatter-gather | |
241 | DVMA. | |
242 | ||
243 | [TBD: Why do not we neither Solaris attempt to map disjoint pages | |
244 | into a single virtual chunk with the help of IOMMU, so that non SG | |
245 | DVMA masters would do SG? It'd be very helpful for RAID.] | |
246 | ||
247 | In order to perform a consistent DVMA a driver does something | |
248 | like the following: | |
249 | ||
250 | char *mem; /* Address in the CPU space */ | |
251 | u32 busa; /* Address in the SBus space */ | |
252 | ||
253 | mem = (char *) sbus_alloc_consistent(sdev, MYMEMSIZE, &busa); | |
254 | ||
255 | Then mem is used when CPU accesses this memory and u32 | |
256 | is fed to the device so that it can do DVMA. This is typically | |
257 | done with an sbus_writel() into some device register. | |
258 | ||
259 | Do not forget to free the DVMA resources once you are done: | |
260 | ||
261 | sbus_free_consistent(sdev, MYMEMSIZE, mem, busa); | |
262 | ||
263 | Streaming DVMA is more interesting. First you allocate some | |
264 | memory suitable for it or pin down some user pages. Then it all works | |
265 | like this: | |
266 | ||
267 | char *mem = argumen1; | |
268 | unsigned int size = argument2; | |
269 | u32 busa; /* Address in the SBus space */ | |
270 | ||
271 | *mem = 1; /* CPU can access */ | |
272 | busa = sbus_map_single(sdev, mem, size); | |
273 | if (busa == 0) ....... | |
274 | ||
275 | /* Tell the device to use busa here */ | |
276 | /* CPU cannot access the memory without sbus_dma_sync_single() */ | |
277 | ||
278 | sbus_unmap_single(sdev, busa, size); | |
279 | if (*mem == 0) .... /* CPU can access again */ | |
280 | ||
281 | It is possible to retain mappings and ask the device to | |
282 | access data again and again without calling sbus_unmap_single. | |
283 | However, CPU caches must be invalidated with sbus_dma_sync_single | |
284 | before such access. | |
285 | ||
286 | [TBD but what about writeback caches here... do we have any?] | |
287 | ||
288 | There is an equivalent set of functions doing the same thing | |
289 | only with several memory segments at once for devices capable of | |
290 | scatter-gather transfers. Use the Source, Luke. | |
291 | ||
292 | Examples | |
293 | ||
294 | drivers/net/sunhme.c | |
295 | This is a complicated driver which illustrates many concepts | |
296 | discussed above and plus it handles both PCI and SBUS boards. | |
297 | ||
298 | drivers/scsi/esp.c | |
299 | Check it out for scatter-gather DVMA. | |
300 | ||
301 | drivers/sbus/char/bpp.c | |
302 | A non-DVMA device. | |
303 | ||
304 | drivers/net/sunlance.c | |
305 | Lance driver abuses consistent mappings for data transfer. | |
306 | It is a nifty trick which we do not particularly recommend... | |
307 | Just check it out and know that it's legal. |