Subject: Re: PCI device driver interface changes
To: Charles M. Hannum <mycroft@mit.edu>
From: Chris G Demetriou <Chris_G_Demetriou@UX2.SP.CS.CMU.EDU>
List: current-users
Date: 03/27/1996 01:09:34
Charles:

Thanks for your comments.  Some of them would have best been addressed
_before_ i committed these changes, so i can do nothing but wonder why
you didn't make any comment on this proposal at all when i sent it to
you 10 days ago, yet were able to comment almost instantly when i
committed it...


> 		   u_int           pa_intrswiz;
> 		   pcitag_t        pa_intrtag;
> 
> You haven't specified what these two values *are*.

They are only to be used in the way specified, by drivers.  drivers
and driver-writers are specifically _not_ supposed to know or care
what they are, except that they are to use them in the way mentioned.

The notes that I provided were _not_ for PCI bus interface (i.e. PCI
bus for a new port) implementors; there are several piece of
information missing that they would find useful.  Similarly, those
notes are not intended to document the internals of the PCI code, and
those bits are part of the 'internals' that must, unfortunately, be
exported as "mostly-opaque" tokens to drivers.

(Basically, i couldn't figure out a better way to do what they do, and
keep implementation sane.  I specifically wanted to avoid a recursive
solution to the problem...  And no, i've not told you what the problem
is, here.  8-)


> 	   This function is always successful.  If the arguments are
> 	   invalid, behaviour is undefined.
> 
> Those two statements seem to conflict.  If the input values don't make
> any sense, doing something is almost certainly worse than panicking,
> and doing nothing could allow a bug to go unnoticed or some more
> obscure error to occur.

Success or failure implies return.  "behaviour is undefined" means,
among other things, that it may never return.

"Seem to" does not mean "do."  8-)

In general, the following statement is true:
	If you provide bogus arguments, the kernel may crash.
(That is specifically _not_ true, for pci_devinfo(), however.)


>    void            *pci_intr_establish __P((pci_chipset_tag_t pc,
> 		       pci_intr_handle_t ih, int level, int (*func)(void *),
> 		       void *arg)); 
> 
> Doesn't PCI allow for both level- and edge-triggered interrupts?  I
> think this also needs an IST_* constant.

I can honestly say "I have no idea."  I'll look it up in the PCI spec
tomorrow, and DTRT if necessary.  You should have mentioned this before.


>    int     pci_mem_find __P((pci_chipset_tag_t pc, pcitag_t tag, int off,
> 	       bus_mem_addr_t *membase, bus_mem_size_t *memsize,
> 	       int *cacheable));
> 
> 	   Examine the PCI configuration space Base Address register at
> 	   offset 'off' in the configuration space of the device named by
> 	   'pc' and 'tag,' and fill in the variables pointed to by
> 	   'membase' and 'memsize' with the information found there.
> 	   'off' must be 4-byte aligned
> 
> Does it return a physical or virtual address?  How do I convert
> between the two?

bus_mem_addr_t's are bus physical addresses, i.e. physical addresses
on the given bus.  This may be distinct from physical addresses on the
system bus, and from virtual addresses on the system bus.

To convert from a bus physical address to a system virtual address,
you should use bus_mem_map().  Currently, there is no interface to
convert from a bus physical address to a system physical address, and
i plan to address that within a few weeks.  The only time you should
need the bus PA -> system PA translation is when allowing mmap() of
device memory, which isn't a concern for any of the devices that
currently use the bus_*() interfaces.  (There are several other
bus_*() interfaces which should be there 'eventually,' but which
aren't currently provided, including but not limited to: repetitive
I/O ops, bus memory copy ops, bus memory PA -> sys PA translation op.
I've known, and stated, this for a while.)


Some more, relatively random, information:

PCI bus PAs on the i386 are the same as system bus PAs on the i386.
VAs are whatever is necessary to map the physical pages, and are
dynamically determined.  On the Alpha, PCI bus PAs are _not_ the same
as system bus PAs, but system bus PAs for PCI addresses may or may not
be the same as VAs for PCI addresses, and on many alpha systems there
are multiple system bus PAs that correspond to a single PCI bus PA...


cgd