From owner-freebsd-hardware Wed Jul 22 23:40:02 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id XAA21058 for freebsd-hardware-outgoing; Wed, 22 Jul 1998 23:40:02 -0700 (PDT) (envelope-from owner-freebsd-hardware@FreeBSD.ORG) Received: from antipodes.cdrom.com (castles163.castles.com [208.214.165.163]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id XAA21025 for ; Wed, 22 Jul 1998 23:39:54 -0700 (PDT) (envelope-from mike@antipodes.cdrom.com) Received: from antipodes.cdrom.com (localhost [127.0.0.1]) by antipodes.cdrom.com (8.8.8/8.8.5) with ESMTP id XAA00669; Wed, 22 Jul 1998 23:38:54 -0700 (PDT) Message-Id: <199807230638.XAA00669@antipodes.cdrom.com> X-Mailer: exmh version 2.0zeta 7/24/97 To: randal@comtest.com cc: Mike Smith , Peter Dufault , john@ece.arizona.edu (John Galbraith), FreeBSD-hardware@FreeBSD.ORG Subject: Re: GPIB drivers? In-reply-to: Your message of "Wed, 22 Jul 1998 14:55:55 -1000." <199807230102.PAA23783@oldyeller.comtest.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Date: Wed, 22 Jul 1998 23:38:54 -0700 From: Mike Smith Sender: owner-freebsd-hardware@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org > 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