Subject: Re: FreeBSD's /dev on NetBSD
To: None <tech-kern@netbsd.org>
From: Hans Petter Selasky <hselasky@c2i.net>
List: tech-kern
Date: 08/13/2005 19:59:59
On Saturday 13 August 2005 17:13, Rui Paulo wrote:
> On 2005.08.13 17:08:17 +0000, Hans Petter Selasky wrote:
> | > Cloning devices are supported on NetBSD - e.g. /dev/bpf or /dev/ptmx
> | > are such cloning devices.  The nodes in /dev are not created indeed,
> | > but actual nodes are rarely needed anyway.
> |
> | Are you sure that this cloning process is dynamic. To me it looks very
> | much like bpf sets up "n" fixed units:
>
> Not on 3.0+.
>
> | # ls /dev/bpf*
> | /dev/bpf0 /dev/bpf1 /dev/bpf2 /dev/bpf3 /dev/bpf4 /dev/bpf5 /dev/bpf6
> | /dev/bpf7
> |
> | crw-------  1 root  wheel  23, 0 Aug 12 14:42 /dev/bpf0
> | crw-------  1 root  wheel  23, 1 Aug 12 14:42 /dev/bpf1
> | crw-------  1 root  wheel  23, 2 Aug 12 14:42 /dev/bpf2
> | crw-------  1 root  wheel  23, 3 Aug 12 14:42 /dev/bpf3
> | crw-------  1 root  wheel  23, 4 Aug 12 14:42 /dev/bpf4
> | crw-------  1 root  wheel  23, 5 Aug 12 14:42 /dev/bpf5
> | crw-------  1 root  wheel  23, 6 Aug 12 14:42 /dev/bpf6
> | crw-------  1 root  wheel  23, 7 Aug 12 14:42 /dev/bpf7
>
> proton> ls /dev/bpf*                                                       
> [~] /dev/bpf   /dev/bpf0@
> proton> ls -l /dev/bpf0                                                    
> [~] lrwx------  1 root  wheel  3 Jun 18 02:27 /dev/bpf0@ -> bpf
>
> | When I look at the source code I find the following:
> |
> | int
> | bpfopen(dev, flag, mode, p)
> |         dev_t dev;
> |         int flag;
> |         int mode;
> |         struct proc *p;
> | {
> |         struct bpf_d *d;
> |
> |         if (minor(dev) >= NBPFILTER)
> |                 return (ENXIO);
> |         /*
> |          * Each minor can be opened by only one process.  If the
> | requested * minor is in use, return EBUSY.
> |          */
> |         d = &bpf_dtab[minor(dev)];
> |                       ^^^^^^ does "specfs" assign minor
> |                              when one opens "/dev/bpf" ?
> |
> |         if (!D_ISFREE(d))
> |                 return (EBUSY);
>
> int
> bpfopen(dev, flag, mode, p)
>         dev_t dev;
>         int flag;
>         int mode;
>         struct proc *p;
> {
>         struct bpf_d *d;
>         struct file *fp;
>         int error, fd;
>
>         /* falloc() will use the descriptor for us. */
>         if ((error = falloc(p, &fp, &fd)) != 0)
>                 return error;
>
>         d = malloc(sizeof(*d), M_DEVBUF, M_WAITOK);
>         (void)memset(d, 0, sizeof(*d));
>         d->bd_bufsize = bpf_bufsize;
>         d->bd_seesent = 1;
>         d->bd_pid = p->p_pid;
>         callout_init(&d->bd_callout);
>
>         simple_lock(&bpf_slock);
>         LIST_INSERT_HEAD(&bpf_list, d, bd_list);
>         simple_unlock(&bpf_slock);
>
>         return fdclone(p, fp, fd, flag, &bpf_fileops, d);
>         ^^^^^^^
> }
>
> | To me it looks that one has to open /dev/bpfN.
> |
> | # cat /dev/bpf
> | cat: /dev/bpf: No such file or directory
>
> proton# cat /dev/bpf                                                       
> [~] cat: /dev/bpf: Invalid argument
>
> | Maybe it has got something to do with the version I am using:
>
> Yes. :)
>

Thanks for the pointer. But from what I see this does not fit FreeBSD 5/6/7 
very well. But I was thinking. For example the USB drivers. Isn't it better 
that the device code is implemented like on FreeBSD 5/6/7 ? Then the code 
looks cleaner and the drivers take up less space. Probably all the #ifdef's 
take up just as much space as the implementation of FreeBSD's /dev .

Speaking about the USB system, I have rewritten the USB driver from scratch, 
put it under per-controller mutexes, and have a suggesting for a new USB API, 
though I still support the old one.

Maybe I am a little too quick to say this, but doesn't the whole USB system 
just use splnet/splx to protect data structures? On a multiprocessor system, 
isn't things going to crash after a while, hence more than one CPU can enter 
into the code that is protected by splnet/splx ? So actually it is time they 
implement mutexes in NetBSD too?

Here is a link to the FreeBSD version: There is only a few things I know about 
that needs to be changed, and all the principles are in place, and there is 
in locking order reversal problems. Each USB transfer can be protected by a 
custom mutex.

Download the three files below into a new directory and type 
"make install"  (to uninstall type "make deinstall") (FreeBSD 5/6/7 only)
http://home.c2i.net/hselasky/isdn4bsd/privat/usb/Makefile
http://home.c2i.net/hselasky/isdn4bsd/privat/usb/new_usb_1_5_4.diff.bz2
http://home.c2i.net/hselasky/isdn4bsd/privat/usb/new_usb_1_5_4.tar.bz2

--HPS