stat.2: Fix minor identation issue
[dragonfly.git] / doc / porting_drivers.txt
CommitLineData
4993a92b
MD
1 PORTING FREEBSD DRIVERS TO DRAGONFLY
2
3* Copy the driver code to the appropriate DragonFly directory. For example,
d00c6212 4 a disk driver /usr/src/sys/dev/blah in FreeBSD would likely be
4993a92b
MD
5 /usr/src/sys/dev/disk/blah in DragonFly.
6
efb850f9 7* Keep all the SVN IDs in the files as a future reference point. dports' SVN
45fa0bf8 8 will do that by default. When using the FreeBSD git repo, please note the
efb850f9
SW
9 files' IDs manually, either in the files themselves or in the commit message.
10 The general idea is that it must not get lost.
e732300c 11
4993a92b
MD
12* Driver local #include's probably use a <dev/blah/blah.h> path. These
13 need to be changed to "blah.h". '.' is not included in the #include
14 path in FreeBSD builds, but it is in DragonFly builds.
15
16* Other #include's may reference things in <dev/...> which in DragonFly
17 reside in <bus/...>. In particular, dev/pccard becomes bus/pccard.
18 Note that defines in FreeBSD's pccard_cis.h reside in DragonFly's
19 pccardreg.h .
20
07d0d38c
SW
21* The following kernel functions have been renamed in DragonFly:
22
23 malloc(), free() etc. -> kmalloc(), kfree() etc.
24 printf() etc. -> kprintf() etc.
25 psignal() -> ksignal()
d2da76f2 26 random() -> krandom()
07d0d38c 27
4993a92b 28* MUTEX conversion - mutexes are generally replaced by spinlocks. However,
72e64973 29 DragonFly spinlocks are more restrictive than FreeBSD mutexes so a
4993a92b
MD
30 direct replacement is not necessarily appropriate in all cases. A lockmgr
31 lock should be used when a direct replacement is not appropriate.
32 In particular, DragonFly does not allow recursive exclusive spinlocks
33 and does not allow multiple exclusive spinlocks to be held by any given
34 thread.
35
36 Instances of <sys/mutex.h> should be replaced with <sys/spinlock.h>.
37
d00c6212 38 When replacing mutexes with spinlocks it is a good idea to rename
4993a92b
MD
39 the structural field (typically 'mtx') to something else (typically 'spin').
40
41 The &Giant mutex is typically converted to get_mplock() and rel_mplock().
42 However, there are places where FreeBSD unlocks giant around some code and
43 then relocks giant... those should simply be removed.
44
45 FreeBSD has weird callout + mutex functions. DragonFly does not integrate
46 the two. Instead, the driver in DragonFly must obtain the spinlocks
47 in question in the callback routine.
48
72e64973
SW
49 As a rule of thumb, MTX_DEF mutexes should be replaced with exclusive,
50 recursive lockmgr locks.
51
d00c6212 52 So, suppose the original code is using
72e64973
SW
53 struct mtx my_mtx;
54 you'd normally rename it to
55 struct lock my_lock;
56
57 and change the initialization from something like
58 mtx_init(&my_mtx, "mymtx", "whatever", MTX_DEF);
59 to
60e7fae5 60 lockinit(&my_lock, "mylock", 0, LK_CANRECURSE);
72e64973
SW
61
62 Destroying it is trivial,
63 mtx_destroy(&my_mtx);
64 becomes
65 lockuninit(&my_lock);
66
67 You use the same function for locking and unlocking a lockmgr lock,
68 so exchange
69 mtx_lock(&my_mtx);
70 with
71 lockmgr(&my_lock, LK_EXCLUSIVE);
72 and
73 mtx_unlock(&my_mtx);
74 with
75 lockmgr(&my_lock, LK_RELEASE);
76
77 For testing the lock status, one would use
78 lockstatus(&my_lock, curthread);
79 in place of
80 mtx_owned(&my_mtx);
81
82 An
83 mtx_trylock(&my_mtx);
84 call is replaced with
a9ea4065 85 lockmgr_try(&my_lock, LK_EXCLUSIVE);
72e64973
SW
86
87 As for mtx_assert() calls, translate them like this:
88
89 mtx_assert(&my_mtx, MA_OWNED) -> KKASSERT(lockstatus(&my_lock, curthread) != 0)
90 mtx_assert(&my_mtx, MA_NOTOWNED) -> KKASSERT(lockstatus(&my_lock, curthread) == 0)
91
92 In DragonFly, lockstatus() does not return information about whether there have been
93 recursive lock acquisitions, so there is no generic way to emulate the
94
95 mtx_assert(&my_mtx, MA_OWNED|MA_RECURSED);
96 mtx_assert(&my_mtx, MA_OWNED|MA_NOTRECURSED);
97
98 calls.
4b3fb495
FT
99
100* rwlock conversion: Use lockmgr locks
d00c6212 101
07d0d38c
SW
102* UMA conversion - generally speaking UMA should be converted to a standard
103 kmalloc.
4993a92b
MD
104
105 Note however that in FreeBSD M_NOWAIT is often used in cases where, in fact,
07d0d38c 106 the kmalloc cannot fail without blowing something up or causing a fatal
4993a92b
MD
107 (and very unexpected) I/O error. M_INTWAIT should be used for these cases.
108
109* CDEVSW conversion - see other devices. Generally speaking a major number
110 is needed and a function map needs to be specified more explicitly.
111
112 Most calls passing struct cdev pointers are dev_t's in DragonFly.
113
114 All device vectors in DragonFly pass a dev_<name>_args structure pointer
115 instead of explicit arguments.
116
117 Strategy calls - we pass BIO's and a lot of BUF fields are in the BIO
118 in FreeBSD, but left in the BUF in DragonFly. FreeBSD for some reason
119 names its struct bio pointers 'bp', its a good idea to rename them to 'bio'
120 to avoid confusion and have a struct buf *bp = bio->bio_buf; pointer to
121 access the buf.
122
d2da76f2
SW
123* MSLEEP/TSLEEP conversion. The DragonFly msleep/tsleep do not have 'PRI'
124 priorities. 0 should be used.
4993a92b 125
4993a92b
MD
126* BUS_* FUNCTIONS
127
128 bus_setup_intr() - replace INTR_TYPE_* flags with 0. There is an extra
129 argument for an interrupt interlock using the sys/serializer.h interface.
60e7fae5 130 This can either be left NULL or you can convert the spinlock(s) for
4993a92b
MD
131 the driver into serializer locks and integrate the interrupt service
132 routine with a serializer.
d2da76f2
SW
133
134* CAM CODE - cam_simq* code refcounts, so shared device queues (raid and
135 multi-channel devices) are not freed before all references have gone
136 away.
317f6748 137
de612e47
FT
138* UNRHDR functions - DragonFly uses a more generic idr(9) subsystem
139 compatible with the Linux API of the same name
140
141 This LWN article describes it in details: http://lwn.net/Articles/103209/
142
143 A typical conversion looks like this:
144
145 #include <sys/idr.h>
146
147 free_unr() has to be replaced by idr_remove()
148
149 alloc_unr() has to be replaced by a code sequence using idr_pre_get and
150 idr_get_new such as this one:
151
152 retry:
153 if (idr_pre_get(xxx) ==0) {
154 kprintf("Memory allocation error\n");
155 return error;
156 }
157 spin_lock(xxx);
158 ret = idr_get_new(xxx);
159 spin_unlock(xxx);
160 if (ret == EAGAIN)
161 goto retry;
162
4dd401bd 163* MPASS macro - Replace it with KKASSERT
2764c241 164
cf396422
FT
165
166* PROC_LOCK / PROC_UNLOCK: to be determined on a case-by-case basis
167
168 Some of the time these macros can be removed entirely
169
170 In some cases, some locking must be done; lwkt_gettoken(&proc_token)
171 and the corresponding lwkt_reltoken() call should be good replacements
172
173 It is not a good idea to blindly implement these macros globally, some
174 particular proc subsystem locking semantics differ enough between FreeBSD
175 and DragonFly that this would cause problems
176
d00c6212 177* In DragonFly 5.1 format specifier %b was replaced by args safe "%pb%i" version
178 that only needs argument swapping. Replacement functions where not added.
179
180 kvcprintf("reg=%pb%i\n", "\10\2BITTWO\1BITONE\n", 3);
181
182* In DragonFly 5.1 format specifier %r was removed from kprintf. As a
183 replacement function makedev_unit_b32() was added.
184
185 - Unit suffix encoded as base32 for make_dev() device creation:
186
187 char tbuf[MAKEDEV_MINNBUF];
188
189 kbd->kb_dev = make_dev(&kbd_ops, kbd->kb_index,
190 UID_ROOT, GID_WHEEL, 0600, "kbd%s",
191 makedev_unit_b32(tbuf, kbd->kb_index));
192
193 - For single character case the hex2ascii() can be used to avoid buffers:
194
195 kprintf("%c\n", hex2ascii(n % base));
cf396422 196
2764c241
AHJ
197* In DragonFly 3.3 format specifier %D was removed from kprintf. As a
198 replacement functions kether_ntoa() and hexncpy() were added.
199
200 - Ethernet address (MAC) to its hexadecimal form:
201
202 char ethstr[ETHER_ADDRSTRLEN + 1];
203 u_char hwaddr[6];
204
205 kprintf("MAC address %s\n", kether_ntoa(hwaddr, ethstr)
206
207 - Generic conversion (block of bytes to hexadecimal form):
208
209 char hexstr[18];
210 u_char mydata[6] = {1, 2, 3, 4, 5 ,6};
211
212 /*
213 * Below statement would print:
214 *
215 * 01-02-03-04-05-06
216 */
217 kprintf("%s\n", hexncpy(mydata, 6, hexstr, HEX_NCPYLEN(6), "-"));
4b3fb495
FT
218
219* TAILQ_XXX_SAFE
220
221 Use TAILQ_XXX_MUTABLE; the macros have the same effect, only the name is
222 different
223
224* kern_yield()
225
226 Replace by lwkt_yield()
227
228* vm_page_lock() and vm_page_unlock()
229
230 Not needed on DragonFly, remove these calls
231
232* vm_pager_get_pages()
233
234 Removed, use vm_pager_get_page() instead
235
236* VPO_BUSY
237
238 Replace by PG_BUSY
239
240* kern_psignal()
241
242 Replace by ksignal()