Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Jul 1998 23:38:54 -0700
From:      Mike Smith <mike@smith.net.au>
To:        randal@comtest.com
Cc:        Mike Smith <mike@smith.net.au>, Peter Dufault <dufault@hda.com>, john@ece.arizona.edu (John Galbraith), FreeBSD-hardware@FreeBSD.ORG
Subject:   Re: GPIB drivers? 
Message-ID:  <199807230638.XAA00669@antipodes.cdrom.com>
In-Reply-To: Your message of "Wed, 22 Jul 1998 14:55:55 -1000." <199807230102.PAA23783@oldyeller.comtest.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
> On 22 Jul 98, at 17:07, Mike Smith wrote:
> 
> > > Freds driver is using copyin/copyout in the ioctl().
> > > So is this bad to do this(copyin/out) here?
> > 
> > It's bad insofar as using ioctl() for data transfer is generally
> > considered the wrong way to do it.  You should be using read and write
> > to do data transfer.
> 
> If not for data transfer how about configuring the driver settings like; 
> timeout, bus timing, end of line char,...?

ioctl() exists for out-of-band activities, so yes, it's perfectly 
suited for that.  Think of it as the "control channel".

> > > 	case GPIBWRITE:
> > > 		error=copyin(gd->count,&count,sizeof(count));
> > >         	if (error!=0) return(error); 
> > 
> > This should use fuword()
> 
> I checked the fuword() manpage sound good.  I guess i could use also 
> suword() to return values to userspace?

Correct; make sure you always check the return value from it.  A better 
construct than the one above is:

	if ((error = foobar(...)))
		return(error);

This makes it clear that the test/return are a single action (though 
lots of people don't like assignments in tests...)

> > > The standard read/write calls are using uiomove().
> > 
> > ... which is how IMHO it should be done.
> > 
> > > I am not familiar with these issues but the driver does work.  Why is bad 
> > > to use copyin/out vs. uiomove?  I would appreciate any input.
> > 
> > copyin/out precludes calling the driver from elsewhere within the 
> > kernel, and if you use it in a read/write/strategy routine, it means 
> > you can't handle readv/writev easily.  (The latter are a godsend if 
> > you're trying to do scatter-gather style I/O).
> 
> Not familiar with this (scatter-gather)concept, something I should learn?

If, for example, your application is using an internal buffering scheme 
where you have data split into small buffers (eg. you are using a set 
of buffer chains because you are performing several sets of decoupled 
signal processing), and you wish to populate possibly many of these 
buffers at once (rather than making lots of read() calls, you can 
construct an array of iovec structures and pass the address and length 
of each of the buffers in a single readv() call.  See the manpage for 
more details.  If your application is performance-sensitive, avoiding 
lots of system calls (or a copy to/from a flat buffer) can be important.

For example, in a data-processing application I was working on a while 
back, we had a stackable module architecture where data was received 
from the hardware into fixed-size buffers, which were pushed onto the 
input queue of the first module, and then the module queue kicked, 
which would ripple the buffers down the stack.  Eventuall some number 
of buffers would come off the bottom.  The buffers themselves were 
relatively small (usually around 100 bytes, up to about 512 or so tops) 
but the actual data rate was very high (1MB/s and up).  Making 2000 
syscalls a second to read the data, and another 1000 or so to commit it 
to the next processing stage was hurting a lot.  On top of that, the 
next stage was in a pipe, and small pipe writes are very inefficient.

So instead, we used readv() to fill as much of the freelist with buffers 
as possible, and at the other end writev() to push as many of them into 
the pipe at once as possible.

> > The real problem is that GPIB is a bus, not a device.  The GPIB driver 
> > should be a bus controller, not a device, and it should have multiple 
> > instances of a peripheral driver hung off it (one for each device on 
> > the bus).
> > 
> > You'd then open each peripheral and implicitly anything you wrote to/
> > read from that peripheral would go to the device in question.
> > 
> > This would make it much cleaner, eg. to support multiple processes 
> > talking to multiple devices on the bus, as well as to embed some 
> > intelligence into the kernel for some devices.
> 
> You said it.  That is exactly how I would like it to be done.  I do have 
> plans to make the application multi-treaded.  My client does want to 
> control several devices from multiple processes.  I didn't mention this 
> before because I was trying to do one step at a time, but I guess I just 
> have to rewrite the whole driver from the beginning to do something like 
> this.

Not at all.  The bulk of the driver is the stuff that talks to the 
hardware; the infrastructure on top is pretty simple.

If you have a deadline, by all means work with what you have.  When you 
have a little more time, bring the matter back up and we can talk about 
how you might go about splitting the driver to busify it.

-- 
\\  Sometimes you're ahead,       \\  Mike Smith
\\  sometimes you're behind.      \\  mike@smith.net.au
\\  The race is long, and in the  \\  msmith@freebsd.org
\\  end it's only with yourself.  \\  msmith@cdrom.com



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hardware" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199807230638.XAA00669>