File:  [DragonFly] / doc / notes / porting_drivers.txt
Revision 1.1: download - view: text, annotated - select for diffs
Sun Dec 3 20:49:59 2006 UTC (8 years, 8 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
Add an internal document describing (in a very incomplete way at the moment)
how to port a driver from FreeBSD.

$DragonFly: doc/notes/porting_drivers.txt,v 1.1 2006/12/03 20:49:59 dillon Exp $


* Copy the driver code to the appropriate DragonFly directory.  For example,
  a disk driver /usr/src/sys/dev/blah in FreeBSD would likely be 
  /usr/src/sys/dev/disk/blah in DragonFly.

* Edit all source files and move the FBSDID declaration into a comment
  (removing the declaration but leave the CVS id in the comment).  Remove
  the #include <sys/cdefs.h> as well.

* Driver local #include's probably use a <dev/blah/blah.h> path.  These
  need to be changed to "blah.h".   '.' is not included in the #include
  path in FreeBSD builds, but it is in DragonFly builds.

* Other #include's may reference things in <dev/...> which in DragonFly
  reside in <bus/...>.  In particular, dev/pccard becomes bus/pccard.
  Note that defines in FreeBSD's pccard_cis.h reside in DragonFly's
  pccardreg.h .

* MUTEX conversion - mutexes are generally replaced by spinlocks.  However,
  DragonFly spinlocks are more restriction then FreeBSD mutexes so a
  direct replacement is not necessarily appropriate in all cases.  A lockmgr
  lock should be used when a direct replacement is not appropriate.
  In particular, DragonFly does not allow recursive exclusive spinlocks
  and does not allow multiple exclusive spinlocks to be held by any given

  Instances of <sys/mutex.h> should be replaced with <sys/spinlock.h>.

  When replacing mutexes with spinlocks it is a good idea to rename 
  the structural field (typically 'mtx') to something else (typically 'spin').

  The &Giant mutex is typically converted to get_mplock() and rel_mplock().
  However, there are places where FreeBSD unlocks giant around some code and
  then relocks giant... those should simply be removed.

  FreeBSD has weird callout + mutex functions.  DragonFly does not integrate
  the two.  Instead, the driver in DragonFly must obtain the spinlocks
  in question in the callback routine.

* UMA conversion - generally speaking UMA should be converted to a stanard

  Note however that in FreeBSD M_NOWAIT is often used in cases where, in fact,
  the malloc cannot fail without blowing something up or causing a fatal
  (and very unexpected) I/O error.  M_INTWAIT should be used for these cases.

* CDEVSW conversion - see other devices.  Generally speaking a major number
  is needed and a function map needs to be specified more explicitly.

  Most calls passing struct cdev pointers are dev_t's in DragonFly.

  All device vectors in DragonFly pass a dev_<name>_args structure pointer
  instead of explicit arguments.

  Strategy calls - we pass BIO's and a lot of BUF fields are in the BIO
  in FreeBSD, but left in the BUF in DragonFly.  FreeBSD for some reason
  names its struct bio pointers 'bp', its a good idea to rename them to 'bio'
  to avoid confusion and have a struct buf *bp = bio->bio_buf; pointer to
  access the buf.

* TSLEEP conversion.  The DragonFly tsleep does not have 'PRI' priorities.
  0 should be used.


  bus_setup_intr() - replace INTR_TYPE_* flags with 0.  There is an extra
  argument for an interrupt interlock using the sys/serializer.h interface.
  This can either be left NULL or you can convert the genera spinlock(s) for
  the driver into serializer locks and integrate the interrupt service
  routine with a serializer.