1 $DragonFly: doc/notes/porting_drivers.txt,v 1.4 2008/04/06 19:08:30 pavalos Exp $
3 PORTING FREEBSD DRIVERS TO DRAGONFLY
5 * Copy the driver code to the appropriate DragonFly directory. For example,
6 a disk driver /usr/src/sys/dev/blah in FreeBSD would likely be
7 /usr/src/sys/dev/disk/blah in DragonFly.
9 * Keep all the CVS ids in the files for future reference point. If the files
10 don't have it, please add it to them. You can find them out from CVSWeb
11 repository or by checking out the specific source files with the FreeBSD
13 This could be automated in the case pkgsrc's SVN client had the set of
14 patches that provide this functionality.
16 * Remove FBSDID declaration and '#include <sys/cdefs.h>' as well.
18 * Driver local #include's probably use a <dev/blah/blah.h> path. These
19 need to be changed to "blah.h". '.' is not included in the #include
20 path in FreeBSD builds, but it is in DragonFly builds.
22 * Other #include's may reference things in <dev/...> which in DragonFly
23 reside in <bus/...>. In particular, dev/pccard becomes bus/pccard.
24 Note that defines in FreeBSD's pccard_cis.h reside in DragonFly's
27 * The following kernel functions have been renamed in DragonFly:
29 malloc(), free() etc. -> kmalloc(), kfree() etc.
30 printf() etc. -> kprintf() etc.
31 psignal() -> ksignal()
34 * MUTEX conversion - mutexes are generally replaced by spinlocks. However,
35 DragonFly spinlocks are more restrictive than FreeBSD mutexes so a
36 direct replacement is not necessarily appropriate in all cases. A lockmgr
37 lock should be used when a direct replacement is not appropriate.
38 In particular, DragonFly does not allow recursive exclusive spinlocks
39 and does not allow multiple exclusive spinlocks to be held by any given
42 Instances of <sys/mutex.h> should be replaced with <sys/spinlock.h>.
44 When replacing mutexes with spinlocks it is a good idea to rename
45 the structural field (typically 'mtx') to something else (typically 'spin').
47 The &Giant mutex is typically converted to get_mplock() and rel_mplock().
48 However, there are places where FreeBSD unlocks giant around some code and
49 then relocks giant... those should simply be removed.
51 FreeBSD has weird callout + mutex functions. DragonFly does not integrate
52 the two. Instead, the driver in DragonFly must obtain the spinlocks
53 in question in the callback routine.
55 As a rule of thumb, MTX_DEF mutexes should be replaced with exclusive,
56 recursive lockmgr locks.
58 So, suppose the original code is using
60 you'd normally rename it to
63 and change the initialization from something like
64 mtx_init(&my_mtx, "mymtx", "whatever", MTX_DEF);
66 lockinit(&my_lock, "mylock", 0, LK_CANRECURSE);
68 Destroying it is trivial,
73 You use the same function for locking and unlocking a lockmgr lock,
77 lockmgr(&my_lock, LK_EXCLUSIVE);
81 lockmgr(&my_lock, LK_RELEASE);
83 For testing the lock status, one would use
84 lockstatus(&my_lock, curthread);
91 lockmgr(&my_lock, LK_EXCLUSIVE|LK_NOWAIT);
93 As for mtx_assert() calls, translate them like this:
95 mtx_assert(&my_mtx, MA_OWNED) -> KKASSERT(lockstatus(&my_lock, curthread) != 0)
96 mtx_assert(&my_mtx, MA_NOTOWNED) -> KKASSERT(lockstatus(&my_lock, curthread) == 0)
98 In DragonFly, lockstatus() does not return information about whether there have been
99 recursive lock acquisitions, so there is no generic way to emulate the
101 mtx_assert(&my_mtx, MA_OWNED|MA_RECURSED);
102 mtx_assert(&my_mtx, MA_OWNED|MA_NOTRECURSED);
106 * rwlock conversion: Use lockmgr locks
108 * UMA conversion - generally speaking UMA should be converted to a standard
111 Note however that in FreeBSD M_NOWAIT is often used in cases where, in fact,
112 the kmalloc cannot fail without blowing something up or causing a fatal
113 (and very unexpected) I/O error. M_INTWAIT should be used for these cases.
115 * CDEVSW conversion - see other devices. Generally speaking a major number
116 is needed and a function map needs to be specified more explicitly.
118 Most calls passing struct cdev pointers are dev_t's in DragonFly.
120 All device vectors in DragonFly pass a dev_<name>_args structure pointer
121 instead of explicit arguments.
123 Strategy calls - we pass BIO's and a lot of BUF fields are in the BIO
124 in FreeBSD, but left in the BUF in DragonFly. FreeBSD for some reason
125 names its struct bio pointers 'bp', its a good idea to rename them to 'bio'
126 to avoid confusion and have a struct buf *bp = bio->bio_buf; pointer to
129 * MSLEEP/TSLEEP conversion. The DragonFly msleep/tsleep do not have 'PRI'
130 priorities. 0 should be used.
134 bus_setup_intr() - replace INTR_TYPE_* flags with 0. There is an extra
135 argument for an interrupt interlock using the sys/serializer.h interface.
136 This can either be left NULL or you can convert the spinlock(s) for
137 the driver into serializer locks and integrate the interrupt service
138 routine with a serializer.
140 * CAM CODE - cam_simq* code refcounts, so shared device queues (raid and
141 multi-channel devices) are not freed before all references have gone
144 * callout_drain() should be replaced by callout_stop_sync()
146 * UNRHDR functions - DragonFly uses a more generic idr(9) subsystem
147 compatible with the Linux API of the same name
149 This LWN article describes it in details: http://lwn.net/Articles/103209/
151 A typical conversion looks like this:
155 free_unr() has to be replaced by idr_remove()
157 alloc_unr() has to be replaced by a code sequence using idr_pre_get and
158 idr_get_new such as this one:
161 if (idr_pre_get(xxx) ==0) {
162 kprintf("Memory allocation error\n");
166 ret = idr_get_new(xxx);
171 * MPASS macro - Replace it with KKASSERT
174 * PROC_LOCK / PROC_UNLOCK: to be determined on a case-by-case basis
176 Some of the time these macros can be removed entirely
178 In some cases, some locking must be done; lwkt_gettoken(&proc_token)
179 and the corresponding lwkt_reltoken() call should be good replacements
181 It is not a good idea to blindly implement these macros globally, some
182 particular proc subsystem locking semantics differ enough between FreeBSD
183 and DragonFly that this would cause problems
186 * In DragonFly 3.3 format specifier %D was removed from kprintf. As a
187 replacement functions kether_ntoa() and hexncpy() were added.
189 - Ethernet address (MAC) to its hexadecimal form:
191 char ethstr[ETHER_ADDRSTRLEN + 1];
194 kprintf("MAC address %s\n", kether_ntoa(hwaddr, ethstr)
196 - Generic conversion (block of bytes to hexadecimal form):
199 u_char mydata[6] = {1, 2, 3, 4, 5 ,6};
202 * Below statement would print:
206 kprintf("%s\n", hexncpy(mydata, 6, hexstr, HEX_NCPYLEN(6), "-"));
210 Use TAILQ_XXX_MUTABLE; the macros have the same effect, only the name is
215 Replace by lwkt_yield()
217 * vm_page_lock() and vm_page_unlock()
219 Not needed on DragonFly, remove these calls
221 * vm_pager_get_pages()
223 Removed, use vm_pager_get_page() instead