Date: Thu, 30 Jan 1997 09:13:54 -0600 From: "Eric L. Hernes" <erich@lodgenet.com> To: "Brian J. McGovern" <mcgovern@spoon.beta.com> Cc: msmith@atrad.adelaide.edu.au, hackers@freebsd.org Subject: Re: The continuting email... Message-ID: <199701301513.JAA29351@jake.lodgenet.com> In-Reply-To: Your message of "Thu, 30 Jan 1997 00:05:43 EST." <199701300505.AAA09649@spoon.beta.com>
next in thread | previous in thread | raw e-mail | index | archive | help
"Brian J. McGovern" writes: > >I'd be more than happy to hammer out documentation. I do it quite frequently. >However, doing documentation requires a.) Coordination with the group as a If you're serious about writing some of this down. I'd let you have the driver writer's guide as a starting point. Its the out-of-date doc we've all been refering to ;-) When I first started learning drivers, I wanted the same doc you're looking for. I even scribbled down a few notes. The thing that I've found out about documenting is that as you get further up the curve, different things are important. I lose sight of what might be a big stumbling block for a beginner. Then as you get higher and higher, free time gets harder and harder to come by (or maybe its just my attention defecit syndrome ;-)). And you're sitting there trying to make sense out of your notes and then you finally say, screw it, I'm going to walk the dog, or go to the bar, or go hunging, or ..., I'll just answer a few questions on -hackers ;-) > >>Driver initialisation is seperated into two parts, known as 'probe' and >>'attach'. The purpose of the 'probe' routine is to ascertain whether >>the hardware is present, and optionally determine its configuration. > >>Probe/attach for ISA device drivers is triggered by the presence of a >>non-static isa_driver structure in the driver; at least the first three >>fields should be initialised, with the probe and attach routines and the >>name of the driver : > >Ok. I know the what. Any particular reason it has to be non-static? I assume >to cause it to blow up if there is another driver with the same name, but, >am I correct? because that's the one piece of information used to bolt your driver into the kernel. well, that and the interrupt handler, if any. have a look at ioconf.c in the kernel compile directory sometime. (yet another obscure source reference ;-)) > >Secondly, what are the fields after the first 3? > >Also, I did a grep for "isa_driver" in /usr/include via a find (ie - >grep "isa_driver" `find .` to no avail. Which header should I include? The kernel is mostly a self-contained critter that can be placed *anywhere* no /usr/include is usually necessary. In fact /usr/include/{sys,machine,net,netinet} are symlinks into the kernel tree, if it exists. Most if not all ISA stuff is in sys/i386/isa/*** including all device drivers, header files, and bus driver sources proper. `struct isa_driver' is in sys/i386/isa/isa_device.h > >>struct isa_driver foodriver = { fooprobe, fooattach, "foo"}; > >>The 'fooprobe' function is called during startup to determine whether >>the device is present or not. It should return zero if the probe >>for the hardware failed, or the size of the I/O space occupied by >>the device if the probe succeeded. > >Please define "size of the I/O space". To me, this can mean many >things, probably all of which are wrong. Is it the number of ports a >device uses? Amount of memory (shared or otherwise)? And how about >our simulated pseudo device, which won't control hardware, but might >have a few K in buffers? In the i386 architecture, there are really four different ways to get data to/from a device: 1) I/O space, or I/O mapped IO, 2) shared memory segment, or memory mapped IO, 3) DMA, 4) interrupts. I/O mapped IO is accomplished via the inb/outb family of instructions. These are conveniently wrapped up in machine/cpu_func.h so that in your code you can just outb(someaddr, someval). NOTE that if you're porting some code from linux, they have the args reversed! If our device has the config line: `device ep0 at isa? port 0x300 net irq 10 vector epintr' `port 0x300' is the address in the IO space. Memory mapped IO is a region usually in the 640K-1M range that the device shares with the OS. In the config line `device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr' `iomem 0xd0000' sets the memory mapped IO address. You can set pointers to this physical addr, and do bcopy's bzero's etc. You will have to make sure that you are accessing the memory via a `kernel virtual address', or you'll panic. The isa_device pointer handed to probe() and attach are a KVA. If you want to see the physical addr, use kvtop(). DMA (on the isa bus) is accomplished by isa_dma* family of functions. There is no docs on this, so you'll have to grep in sys/i386/isa for their use :( Or use the source in sys/i386/isa/isa.c The line: `device cx0 at isa? port 0x240 net irq 15 drq 7 vector cxintr' shows that this device uses DMA channel 7. There's a pretty good section in the handbook on DMA. Interrupts are just a signaling mechanism, similar to signals in user processes. But they add a lot of concurrency issues to a driver. The line `device fea0 at isa? net irq ? vector feaintr' shows that the driver can figure out the IRQ from the card, and the interrupt handler is `feaintr', which must be non-static. > >Ok. Looks clear enough. I'm assuming we're still in attach here... I'm >also assuming that block devices would call bdevsw_add (wrong name i think, >but I think I get the idea). How about STREAMS types or tty type devices that >are linked off through a line protocol? There are no STREAMS. Network drivers are quite different from standard character drivers, but they are also documented better in the 4.4BSD book. Most of the multi-line serial drivers are derrived from sio. There is a slight bit of glue required to get the driver to work with line disciplines, but thats covered in the 4.4 book too (I think) Other than that its just a character driver. In fact for the first phase of development, I'd be inclined to get it working as a standard char device, then when that's working, go for the line discipline stuff. But then I've never written one either. > >Ok. Some of it makes sense. Is there a blank generic one that gives the >appropriate order? For instance, I see nullstop and nullreset. There should >also be a poll routine in there some where? Is it a NULL? a no? a -1? Poll is SysV, BSD uses select for similar operations. For a ttydriver, I think you can safely set this to the generic `ttselect' and have it work. >> >Ok. Is creating a devfs node mandatory? I know people would like to move to >it, but when/is it required? What makes the decision if it is optional? Not mandatory, you should respect the `DEVFS' pre-processor macro. like: #ifdef DEVFS <do devfs stuff> #endif eric. -- erich@lodgenet.com http://rrnet.com/~erich erich@rrnet.com
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199701301513.JAA29351>