Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Jan 1997 00:05:43 -0500
From:      "Brian J. McGovern" <mcgovern@spoon.beta.com>
To:        msmith@atrad.adelaide.edu.au
Cc:        hackers@freebsd.org
Subject:   The continuting email...
Message-ID:  <199701300505.AAA09649@spoon.beta.com>

next in thread | raw e-mail | index | archive | help
>Do you read Dilbert?   If it weren't for your other comments, I would have
>to say that you were trained management.  You need to lift your eyes a
>little and look at the longer-term benefits of a given exercise.

There are long term benefits, and there are short term realities. The long
term benefits is that I may get good at this. The short term reality is that
I have a certain length of time to aquire the information to do this. If the
time required is excessive, or unrealistic, it makes a better choice to either
hire someone to do it, or wait for someone else to do it, and put my energies
where not only will I have efficiency, but I'll have success. Perhaps it is
being "trained management", but you'll notice that the number of learned people
working with FreeBSD that could develop a userful driver is nearly nil compared
to the number of people running FreeBSD. Why is that? They all put their 
resources where it will gain them the most. Many people, like myself, have
limited time, and a lot to do.

>> Ok, so one bad example ;p But, still, I've noted a good chunk of the
>> technical docs in the handbook always seems to be a release out of
>> date. Again, perhaps its something that can be undertaken.

>Writing documentation is lots of work.  Tina and her ilk are a rare
>resource.

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
whole, b.) A _serious_ understanding of what you're writing about (unless you
opt to sound like you're clueless, or be wrong, etc), and c.) understanding
of the mechanism to write the documentation. Right now, I would say that
I fail in all cases. a.) is covered by the fact I don't deal with the 
developers regularly. I should, and I try, but it doesn't happen. b.) This
is optional, based on what I'd try to document. Workings of a service, like
tftpd? Sure, no problem. Give me two hours on a Saturday... Working of a 
device driver interface? Yeah, right... Give me a year. c.) Some one was
nice enough to point out the appropriate man pages for writing man pages.
Given a weekend of tinkering with it, I'm sure I could figure it out. But,
theres 8-10 hours right there. Is documentation what I'd be _most_ useful at?

>> And you'll never start on your first till you think you
>> can do it.

>*This* is your failing point, and it is annoyingly common.  Given "you can
>never know until you try", your attitude means that you will _never_learn_
>because without an ironclad guarantee of success, you'll never make the
>effort.  An attitude like that is a guarantee of failure.

It depends on your definition of ironclad guarantee of success. When I start
any project at work, I have a fairly good idea of what I'm going to do, and how
to get there. So long as I maintain at least one path to reach my goal, I will
continue to plug away at it. If I don't have one, and a reasonable amount
of investigation doesn't give me a new path. The project goes on "hold" 
indefinately until I can find a new path to pursue.

Also, in lieu of another comment earlier that I wanted to drop over the sake of
arguement (but it applies here, so I'll bring it back up), I did once (about
2 weeks ago) post about getting my ficticious 'foo' driver installed in the
kernel to the hackers list. I got one (1) reply from someone with a handbook
section to check out. I downloaded it, printed it, and followed the steps. 
Didn't work. Queried hackers as to why it didn't work. I think it was Jordan
who replied that the section in question (excuse my fuzziness on the _exact_
answer, but its been awhile, and I didn't pay much attention beyond the
basic meaning of the message) was for FreeBSD versions through 2.1.5 or 2.1.6.
As I was running 2.2-BETA on all my machines (trying, in my minimalist way
to find any bugs for the pending release - of which I've submitted 3-4 minor
ones to date [so I don't bang on the machines as hard as some..]), the handbook
section became useless. As no one else answered that and future messages on
the subject, and the docs were out of date, I no longer had a path. Hence, it
went on hold till I saw enough people mentioning the things I saw, and I
summarized it in an opinion message....

>> A lack of documentation makes it infinately more difficult. 

>I would assert that the mailing lists are a form of interactive
>documentation that transcends anything that can be statically
>committed to any media.

As per the message above, it doesn't always work. Timing becomes critical. 
People become critical. If your timing is off (someone takes a day off, or
mail is lost, etc), or the one person who has a good answer isn't available,
it doesn't work. 

However, if that person was to do a brain-dump on to a white paper. Not even
documentation per say, but their thoughts on the hows, whys, and wheres, it 
would at least provide a static source for some place to start.

>> But, like my original
>> message said, if I _am_ able to learn something useful, and return an equal 
>> amount, or more time on development than what you took to teach me, its a 
>> win all around.

>Your offerings would be gratefully accepted, believe you me 8)
As I would like to offer. Again, I really don't want to argue with anyone. My
merest dialog (originally) was to stress that static, written, up to date
documentation would allow people (such as myself) to learn these things
at their own pace, in their own time. Then, once their ready, their newly
found skill sets would be available to assist the development goals.  However,
I see it taking an initial capital of properly trained people to provide static
documentation for this purpose.


>> Unfortunately, my time to tinker with such things is limited. I've
>> banged out some test code in the past (simple device reads, writes,
>> etc), but don't have a weekend to figure out how to stick it in the
>> kernel. And until I know I have a weekend to make a concerted
>> effort, I won't bother anyone with the newbie question. Why ask the
>> question if the answer would be useless?

>How can you make an assessment like that when you claim ignorance?
>Perhaps integrating your driver is a 5-minute task?  Will you let your
>timidity hold you back?

Because I have already sunk over a week (80 hours) in to just reading up
on how to properly write a driver. I have looked at other drivers, and I can
usually anticipate my learning curve. If it were a five minute task, please,
surprise me. However, I think 10 hours over a weekend that I can dedicate to
it would really be a more realistic number. I'll probably need more in the
long run. And no, its not timidity thats holding me back. Its my desire to
bring completion to the things I start. I despise not finishing things on
schedule (management again?)

>> When the time comes, I'll ask. However, I'd also like to keep the
>> number of questions I have to ask to a bare minimum. I'd rather have
>> it be "I'm doing XYZPDQ, and it blows up in such and such a way. Can
>> any one see any obvious problem", than "What do I do now?".

>I think "I have some device driver routines, how do I glue them together
>so that the kernel can use them" is a pretty straightforward question.
>I could (and would happily) answer that in a fashion that you should be
>able to do something with directly.

But, you're also making two assumptions. One, that I am in fact ready, and
two, that I would like the answer. That was not the point of my
original posting. The point of my original posting was that via good docs,
a.) The question would (should?) never have to be asked in the first place 
(siting driver writing as an example), b.) the system, overall, would
be better documented, and c.) It provides 'newbies' with a unified set of 
documentation for how to go about a task, so that the learning curve will
be as greatly reduced as possible (read: dump the tinkering and show
me how to do something useful).

>> For me to grow beyond copying an example in the book, I really need
>> to understand _why_ I'm doing what i'm doing.

>Why not ask them then?  The authors of the code you're fretting about 
>(or at the very least people that understand it) are all around, and most
>are easily approachable.

I don't disagree with this. However, it comes back to time, timing, effort,
and energy. Time, as in I only have limited time, and if I spend the time I 
have trying to find the right person to talk to, wait for replies, etc, the
time I have to actually WORK on something is gone, and we all have to
wait till the next cycle (which, by then, would cause me to forget the
answer anyways :) ). Timing, as in if the "right" person isn't available, 
whether you even get an answer becomes shaky at best. Effort, as in which is
easier? Asking all the right questions, or reading up to get a base 
understanding, and THEN asking about what you don't get. Energy, as in see
"Time".

Also, I oft feel (as others do), that if I were high guru on a mountain,
and someone came to me and asked "How do I program in C?", the answer would
not be a 30 hour class. It would be "Why not get a book on it". Likewise,
a simple question stands a far better chance of being answered (correctly),
than a "I don't have a clue, save me" question. That is the type of question
that people who expect answers on silver platters will ask. It is the
type of question that, personally, I don't think should ever need to be
asked _provided there is an alternate source for the information_.


>> Reading someone else's chunk of code doesn't tell you WHY they
>> implemented something a certain way... Good commenting would, but if
>> all the code in the world had sufficient commenting, we wouldn't be
> having this discussion :)

>Reading the code in its larger context will often make obvious why something
>was implemented in a particular fashion.  Often "expediency" is the only
>succinct answer 8)
See "time" (above)

>> Tomorrow, whilest I'm at work, I will write some code for a pseudo-device
>> driver I wish to call foo. I will write routines for fooinit, fooread, 
>> and foowrite. According to the documentation I've read, I should be able to 
>> leave the open and close routines set to (I guess NULL ?) nothing. fooinit
>> will also exist, but will just contain a printf to announce the presence of
>> the pseudo-driver. The driver will be a character driver, with major number
>> of 20. Minor number will represent buffer numbers, each buffer will be 1K
>> in length. Writes to a buffer will set the string. Reads will return it (if
>> the full length is specified). Optionally, I'll use the offset attributes
>> to allow multiple reads and writes. Lastly, all of these routines will
>> be in a file called foodev.c.

>Ok, sounds like a plan.

>> Now, based on my reading, and what I've seen in some of the drivers
>> I _have_ looked at, I believe that I'll have to set a cdevsw structure up,
>> and it looks like a struct isa_driver. I also see probe() and attach()
>> routines that I have not seen documentation on before in the books I have
>> read. I see devfs support thrown in... Looks kinky. Probably will need help
>> there eventually... 

>Ok.

>> Anyhow, want to lecture me on what some of these things are, whats required,
>> whats optional, and how my stuff will fit in the cosmic scheme of things?

>Sure; I'll keep it cc'd to -hackers so that others can snipe at my ignorance,
>and if you save all of these messages, you should have an excellent reference
>on which to base your documentation.

>I'll restrict myself to ISA drivers, as these are where I'm most familiar.
>PCI drivers are generally similar, but have an easier time in some
>regards.

>I'll use your 'foo' driver as an example.

 ====

>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?

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?
(BTW: I noted to jordan that the ssys.* set in -BETA had trailing
garbage at the end. I don't know if it means the set is corrupt
and I'm missing something)

>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?

>static int
>fooprobe(struct isa_device *dev)

>It is legitimate to alter the contents of the fields in the isa_device
>structure, if new values are determined by probing for the hardware.
>Note that the id_irq field is a bitmask, not a numeric value.  The
>probe routine should not emit any text unless it comes up against
>something particularly alarming.

Ok. id_irq is a bitmask. I'll have to save my other questions once I can
find struct isa_device. I am currently assuming that this contains the
info in the kernel config file when called. Same for a pseudo-device?

>
>The probe routine is called once per instance of the driver in the
>configuration file.
>
>Attach is called, again once per instance of the driver in the config,
>when the device has been successfully probed and does not conflict.
Does the driver make the call as to the conflict? Or does the system look
at the struct isa_device, and if a conflict occurs, not call the probe
and attach routines?

>
>static int
>fooattach(struct isa_device *dev)
>
>The attach routine should build any local data structures required for
>management of the device.  It is traditional for the attach routine to
>emit a line like :
>
>foo0: Snarklewacker 200, rotating Floib, no BoBoBoBoB.
>
>The startup code will have already emitted a line like :
>
>foo0 at 0x10-20 irq 1 iomem 0x12345 on isa
>
Ok. This smells like the init routines I'm used to seeing.


>Once internal state for the driver has been established, you add an entry
>to the device switch for the driver.  In the case of a character device, 
>the following fragment is normally used :
>
>    dev = makedev(CDEV_MAJOR,0);
>    cdevsw_add(&dev,&foo_cdevsw,NULL);
>

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? Once I'm done with driver foo,
I'd like to start work on an ISA multi-modem card thats being prepped
by Cisco for inclusion in to their routers (the modem modules, not the ISA
cards). I'll need to run SLIP and PPP across the link. the _documentation I
have_ says I'll have to make it a little more special than a "normal" character
device...

>Where CDEV_MAJOR is the major device number assigned to the driver
>(normally #defined somewhere obvious).
>
>A typical cdevsw initialisation might look like :
>
>static d_open_t         fooopen;
>static d_close_t        fooclose;
>static d_read_t         fooread;
>static d_write_t        foowrite;
>static d_ioctl_t        fooioctl;
>static d_select_t       fooselect;
>
>#define CDEV_MAJOR      20
>static struct cdevsw foo_cdevsw =
>{
>    fooopen,          fooclose,       fooread,        foowrite,
>    fooioctl,         nullstop,       nullreset,      nodevtotty,
>    fooselect,        nommap,         NULL,           driver_name,
>    NULL, -1
>};
>

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?

>Note that some of the placeholders are "no*" and some are "null*" - I
>think that this is laziness on someone's part 8(
Again, see the note above. Docs on what they "should be" could help fix this :)

>
>To create a devfs device node :
>
>	sc->devfs_token = devfs_add_devsw(&foo_cdevsw, unit,
>					DEV_CHR, UID_ROOT, GID_WHEEL,
>					0660, "foo%d", unit);
>
>This returns a token which is saved (here) in the devfs_token field in
>the device's softc structure (the per-device state structure).  The
>cdevsw structure defines the driver's entrypoints, unit is the unit
>number associated with the device node (you can encode major/minor
>data here if you wish), DEV_CHR indicates a character device node, the
>UID_ROOT, GID_WHEEL and 0660 entries set the ownership/permissions on
>the new device node, and the remaining arguments are printf-style,
>with a format string and parameters for the format string which yield
>the name of the device node.
>
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?

>You can call this several times to create multiple nodes for a single
>instance of the driver.

Ok. I assume this means that it'll generate the same major numbers with
appropriate minor numbers?
>
>
> ====
>
>That should get you probing and attached; keep us in touch!
>
>> 	-Brian
>

I appreciate the help to date. Again, my goal is not to argue, but to
assist. Can't assist without knowledge, can't gain knowledge without
documentation (I despise cultural learning. Too much pure data
gets damaged in the retelling...)

>- -- 
>]] Mike Smith, Software Engineer        msmith@gsoft.com.au             [[
>]] Genesis Software                     genesis@gsoft.com.au            [[
>]] High-speed data acquisition and      (GSM mobile)     0411-222-496   [[
>]] realtime instrument control.         (ph)          +61-8-8267-3493   [[
>]] Unix hardware collector.             "Where are your PEZ?" The Tick  [[
>
>------- End of Forwarded Message
>
>



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