tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: PCI extended configuration support
On 2015/09/28 22:41, Christos Zoulas wrote:
> On Sep 28, 7:51pm, msaitoh%execsw.org@localhost (Masanobu SAITOH) wrote:
> -- Subject: Re: PCI extended configuration support
>
> | On 2015/09/27 11:03, Christos Zoulas wrote:
> | > In article <5604D1BE.3080502%execsw.org@localhost>,
> | > Masanobu SAITOH <msaitoh%execsw.org@localhost> wrote:
> | >> On 2015/09/11 19:44, Masanobu SAITOH wrote:
> | >>
> | >> More machines support the extended configuration area than before.
> | >>
> | >> Is it OK to commit?
> | >
> | > LGTM, but since this is not performance critical can't we centralize the
>
> | > range test and do it in a wrapper?
> |
> | We have no good idea... :-(
>
> I meant instead of editing each of the drivers edit the pci_machdep.h file
> of each arch from:
>
> #define pci_conf_read(c, t, r) \
> (*(c)->pc_conf_read)((c)->pc_conf_v, (t), (r))
> #define pci_conf_write(c, t, r, v) \
> (*(c)->pc_conf_write)((c)->pc_conf_v, (t), (r), (v))
>
> to:
>
> static __inline pcireg_t pci_conf_read(void *_cpv, pcitag_t _tag, int _offset) {
> if ((unsigned int)_offset >= PCI_CONF_SIZE)
> return (pcireg_t)-1;
> return *((c)->pc_conf_read)(
> ((struct <arch>_pci_chipset *)_cpv)->pc_conf_v, _tag, _offset);
> }
>
> static __inline void pci_conf_write(void *_cpv, pcitag_t _tag, int _offset) {
> if ((unsigned int)_offset >= PCI_CONF_SIZE)
> return;
> return *((c)->pc_conf_write)(
> ((struct <arch>_pci_chipset *)_cpv)->pc_conf_v, _tag, _offset);
> }
>
> Or you could even make a macro of it in pci_var.h like:
>
> #define PCI_ARCH_CONF_READ(c, t, r) \
> do { \
> if ((unsigned int)(r) >= PCI_CONF_SIZE) \
> return (pcireg_t) -1; \
> return *((c)->pc_conf_read)((c), (t), (r)); \
> while (/*CONSTCOND*/0)
>
> And then change the macro in arch/include/pci_machdep.h to:
>
> #define pci_conf_read(c, t, r) PCI_ARCH_CONF_READ(c, t, r)
>
> Or you could just centralize the machdep macro to pci_var.h, and put it
> around ifdefs so that the machdep code can override it:
>
> #ifndef pci_conf_read
> #define pci_conf_read(c, t, r) \
> do { \
> if ((unsigned int)(r) >= PCI_CONF_SIZE) \
> return (pcireg_t) -1; \
> return *((c)->pc_conf_read)((c), (t), (r)); \
> while (/*CONSTCOND*/0)
> #endif
The size of accessible area is not fixed and it's machine
(SoC or implement of PCI bus) dependent, so it should be done
in ((c)->pc_conf_read)(). Or use function like:
if ((unsigned int)(r) >= pci_conf_size()) \
return (pcireg_t) -1; \
pci_conf_read() have to call chip dependent function. I think
it's not good idea to call chip dependent function in pci_conf_size()
and ((c)->pci_conf_read)() twice. And, NOT all archs have pc_conf_read().
I think writing pci's commom API function with a macro is not good for
kernel module.
> | > Plus this can't be negative so perhaps
> | > it should be unsigned or checked for < 0 too??
> | >
> | > + if (reg >= PCI_CONF_SIZE)
> | > + return (pcireg_t) -1;
> | > +
> |
> | Done.
>
> I think you missed some...
Fixed. Thanks.
> | > Finally a few more constants could be defined instead
> | > of hard-coded values....
> | >
> | > + switch (pcie_devtype) {
> | > + case 0x4: /* Root Port of PCI Express Root Complex */
> | > + case 0xa: /* Root Complex Event Collector */
> |
> | Done.
>
> Thanks!
>
> christos
Final diff:
http://ftp.netbsd.org/pub/NetBSD/misc/nonaka/tmp/20150929-nbsd-pci-extconf-support.diff
--
-----------------------------------------------
SAITOH Masanobu (msaitoh%execsw.org@localhost
msaitoh%netbsd.org@localhost)
Home |
Main Index |
Thread Index |
Old Index