doc - Fix previous commit.
[dragonfly.git] / notes / porting_drivers.txt
CommitLineData
60e7fae5 1$DragonFly: doc/notes/porting_drivers.txt,v 1.4 2008/04/06 19:08:30 pavalos Exp $
4993a92b
MD
2
3 PORTING FREEBSD DRIVERS TO DRAGONFLY
4
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.
8
e732300c
AHJ
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
12 SVN client.
13 This could be automated in the case pkgsrc's SVN client had the set of
14 patches that provide this functionality.
15
e732300c 16* Remove FBSDID declaration and '#include <sys/cdefs.h>' as well.
4993a92b
MD
17
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.
21
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
25 pccardreg.h .
26
07d0d38c
SW
27* The following kernel functions have been renamed in DragonFly:
28
29 malloc(), free() etc. -> kmalloc(), kfree() etc.
30 printf() etc. -> kprintf() etc.
31 psignal() -> ksignal()
d2da76f2 32 random() -> krandom()
07d0d38c 33
4993a92b 34* MUTEX conversion - mutexes are generally replaced by spinlocks. However,
72e64973 35 DragonFly spinlocks are more restrictive than FreeBSD mutexes so a
4993a92b
MD
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
40 thread.
41
42 Instances of <sys/mutex.h> should be replaced with <sys/spinlock.h>.
43
44 When replacing mutexes with spinlocks it is a good idea to rename
45 the structural field (typically 'mtx') to something else (typically 'spin').
46
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.
50
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.
54
72e64973
SW
55 As a rule of thumb, MTX_DEF mutexes should be replaced with exclusive,
56 recursive lockmgr locks.
57
58 So, suppose the original code is using
59 struct mtx my_mtx;
60 you'd normally rename it to
61 struct lock my_lock;
62
63 and change the initialization from something like
64 mtx_init(&my_mtx, "mymtx", "whatever", MTX_DEF);
65 to
60e7fae5 66 lockinit(&my_lock, "mylock", 0, LK_CANRECURSE);
72e64973
SW
67
68 Destroying it is trivial,
69 mtx_destroy(&my_mtx);
70 becomes
71 lockuninit(&my_lock);
72
73 You use the same function for locking and unlocking a lockmgr lock,
74 so exchange
75 mtx_lock(&my_mtx);
76 with
77 lockmgr(&my_lock, LK_EXCLUSIVE);
78 and
79 mtx_unlock(&my_mtx);
80 with
81 lockmgr(&my_lock, LK_RELEASE);
82
83 For testing the lock status, one would use
84 lockstatus(&my_lock, curthread);
85 in place of
86 mtx_owned(&my_mtx);
87
88 An
89 mtx_trylock(&my_mtx);
90 call is replaced with
91 lockmgr(&my_lock, LK_EXCLUSIVE|LK_NOWAIT);
92
93 As for mtx_assert() calls, translate them like this:
94
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)
97
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
100
101 mtx_assert(&my_mtx, MA_OWNED|MA_RECURSED);
102 mtx_assert(&my_mtx, MA_OWNED|MA_NOTRECURSED);
103
104 calls.
105
07d0d38c
SW
106* UMA conversion - generally speaking UMA should be converted to a standard
107 kmalloc.
4993a92b
MD
108
109 Note however that in FreeBSD M_NOWAIT is often used in cases where, in fact,
07d0d38c 110 the kmalloc cannot fail without blowing something up or causing a fatal
4993a92b
MD
111 (and very unexpected) I/O error. M_INTWAIT should be used for these cases.
112
113* CDEVSW conversion - see other devices. Generally speaking a major number
114 is needed and a function map needs to be specified more explicitly.
115
116 Most calls passing struct cdev pointers are dev_t's in DragonFly.
117
118 All device vectors in DragonFly pass a dev_<name>_args structure pointer
119 instead of explicit arguments.
120
121 Strategy calls - we pass BIO's and a lot of BUF fields are in the BIO
122 in FreeBSD, but left in the BUF in DragonFly. FreeBSD for some reason
123 names its struct bio pointers 'bp', its a good idea to rename them to 'bio'
124 to avoid confusion and have a struct buf *bp = bio->bio_buf; pointer to
125 access the buf.
126
d2da76f2
SW
127* MSLEEP/TSLEEP conversion. The DragonFly msleep/tsleep do not have 'PRI'
128 priorities. 0 should be used.
4993a92b 129
4993a92b
MD
130* BUS_* FUNCTIONS
131
132 bus_setup_intr() - replace INTR_TYPE_* flags with 0. There is an extra
133 argument for an interrupt interlock using the sys/serializer.h interface.
60e7fae5 134 This can either be left NULL or you can convert the spinlock(s) for
4993a92b
MD
135 the driver into serializer locks and integrate the interrupt service
136 routine with a serializer.
d2da76f2
SW
137
138* CAM CODE - cam_simq* code refcounts, so shared device queues (raid and
139 multi-channel devices) are not freed before all references have gone
140 away.