1
2			    README.DRAGONFLY
3
4		Porting low level drivers from FreeBSD
5
6    * Fixup #include lines.
7
8      <dev/pci/blah.h>  -> <bus/pci/blah.h>
9      <dev/blah/blah.h> -> <dev/netif/blah/blah.h>
10      <net80211/blah.h> -> <netproto/802_11/blah.h>
11
12      remove <machine/bus.h>
13      remove <machine/resource.h>
14      add    <sys/stdbool.h>
15      add    <net/ifq_var.h>
16
17    * Simple API changes
18
19      malloc	   -> kmalloc
20      free	   -> kfree
21      printf	   -> kprintf
22      pci_find_cap -> pci_find_extcap
23
24      In kmalloc calls, M_NOWAIT -> M_INTWAIT
25      In mbuf related calls, M_NOWAIT -> MB_DONTWAIT
26
27      verify that M_NOWAIT is not used in any mbuf related calls.
28
29    * mbuf related calls
30
31      m_collapse(m, M_NOWAIT, blah)	->	m_defrag(m, MB_DONTWAIT)
32      m_getjcl(...)			->	just fix to use MB_DONTWAIT
33
34      bus_dmamap_load_mbuf_sg(dmat, map, m, segs, &nsegs, BUS_DMA_NOWAIT) ->
35	bus_dmamap_load_mbuf_segment(dmat, map, m, segs, maxscatter,
36					&nsegs, BUS_DMA_NOWAIT);
37
38	The maxscatter argument depends on the driver, '1' if you do not
39	know.
40
41    * netif interface
42
43      IFQ_SET_MAXLEN(), ifp->if_snd.ifq_drv_maxlen = blah, IFQ_SET_READY() ->
44	ifq_set_maxlen(&ifp->if_snd, blah)
45
46      if_start() and if_ioctl() have an additional argument.
47
48	  void blah_start(struct ifnet *, struct ifaltq_subque *);
49	  int  blah_ioctl(struct ifnet *, ulong, caddr_t, struct ucred *);
50
51	  In this situation the additional argument can usually be ignored.
52
53      if_inc_counter(ifp, BLAH, 1)		->  ++ifp->if_blah
54      if_inc_counter(ifp, IFCOUNTER_OERRORS, 1) -> ++ifp->if_oerrors;
55
56      if_drv_flags used with IFF_DRV_RUNNING   ->
57      if_flags used used with IFF_RUNNING
58
59      if_drv_flags used with IFF_DRV_OACTIVE  ->
60      ifq_is_oactive(), ifq_set_oactive(), ifq_clr_oactive() as appropriate.
61
62      Be very careful here, review your patches to make sure you aren't
63      testing the wrong field against the IFF_* macro.  All OACTIVE chanages
64      must use our API calls and not test the flag(s) directly.
65
66    * Change all struct mtx and related locking api calls and macros
67      to use struct lock (lockmgr locks).
68
69      struct mtx	->	struct lock
70
71      lockmgr(lk, LK_EXCUSIVE)
72      lockmgr(lk, LK_RELEASE)
73      lockinit(lk, wmesg, flags)		(typcally 0 or LK_CANRECURSE)
74      KKASSERT(lockstatus(lk) == LK_EXCUSIVE)	(asserting held)
75      KKASSERT(lockstatus(lk) != LK_EXCUSIVE)	(asserting not held)
76
77    * msleep() calls typically have to become lksleep() calls.  However,
78      in these situations the wlan_global_serializer might also be held
79      and must be released, so it is best to wrap it in your own blahsleep()
80      function which does this in addition to the lksleep():
81
82	blah_sleep(struct blah_softc *sc, void *wchan,
83		   int flags, const char *wmsg, int timo)
84	{
85		int iws;
86		int error;
87
88		iws = wlan_is_serialized()
89		if (iws)
90			wlan_serialize_exit();
91		error = lksleep(wchan, appropriatelock, flags, wmsg, timo);
92		if (iws)
93			wlan_serialize_enter();
94		return error;
95	}
96
97    * Firmware loading and/or the general network init function may have
98      to release wlan_global_serializer similarly to how the blah_sleep()
99      releases it for the duration of the init function and firmware load.
100
101    * You may need a modevent infrastructure for module loading.  See the
102      original driver for code or one of the drivers already ported, like
103      netif/ath or netif/iwn
104
105    * SYSCTL macros in FreeBSD may have a CTLFLAG_RWTUN which for us is
106      just CTLFLAG_RW plus an additional TUNABLE* macro (see netif/ath
107      for examples).
108
109    * taskq_start_threads() API is slightly different.
110
111      taskqueue_start_threads(tq, 1, 0, name) ->
112      taskqueue_start_threads(tq, 1, TDPRI_KERN_DAEMON, -1, name)
113
114    * bus_setup_intr() is different.
115
116      bus_setup_intr(dev, irq, INTR_TYPE_NET | INTR_MPSAFE,
117			NULL, intrfunc, sc, &handle)		->
118      bus_setup_intr(dev, irq, INTR_MPSAFE,
119			intrfunc, sc, &handle, &wlan_global_serializer)
120
121    * callout API.  callout_init_mtx() is already macrod to
122      callout_init_lk().
123
124      callout_stop()	-> callout_stop_sync()
125      callout_sched()	-> must be converted to the proper callout_reset(...)
126			   call (function must be re-provided).
127
128    * bus_dma_tag_create() API is dfferent.
129
130      bus_dma_tag_create(tag, alignment,
131			 0,
132			 BUS_SPACE_MAXADDR_32BIT,
133			 BUS_SPACE_MAXADDR,
134			 NULL, NULL,
135			 size, 1, size,
136			 BUS_DMA_NOWAIT,
137			 NULL, NULL,
138			 &dma->tag)			-> to
139
140      bus_dma_tag_create(tag, alignment,
141			 0,
142			 BUS_SPACE_MAXADDR_32BIT,
143			 BUS_SPACE_MAXADDR,
144			 NULL, NULL,
145			 size, 1, size,
146			 BUS_DMA_NOWAIT, &dma->tag);
147
148    * device_printf() may be used with "%6D".  This is effectively asking
149      to print an ether address, but it required hacking gcc to actually
150      accept the "%6D" in a __printflike() function.  So instead, rename
151      any such calls to blahdev_printf() and write a blahdev_printf()
152      function (see athdev_printf() in netif/ath for an example).
153
154