Skip to contentSkip to conversation

allow pci primary peer busses to have parents

BKPATCH James Bottomley 2 participants 4 messages Dec 4, 2002 – Dec 5, 2002 PCI

lore
Share & tools
lore
#0 lore raw

Now that the generic device model allows a coherent bus tree to be built, there are certain architectures that hang the PCI primary busses off another bus (I need this patch for parisc, but I'm sure infiniband would have similar issues).

This patch allows the allocation of parented pci primary peer busses so that they slot correctly into the device model.

James

You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.

===================================================================

[email protected], 2002-12-03 09:28:37-06:00, [email protected]
allow pci primary busses to have parents in the device model

 drivers/pci/probe.c |    7 ++++---
 include/linux/pci.h |   12 ++++++++++--
 2 files changed, 14 insertions(+), 5 deletions(-)
drivers/pci/probe.c +1 -1
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
@@ -547,7 +547,7 @@
 	return 0;
 }
 
-struct pci_bus * __devinit pci_alloc_primary_bus(int bus)
+struct pci_bus * __devinit pci_alloc_primary_bus_parented(struct device 

*parent, int bus)
{
struct pci_bus *b;

@@ -566,6 +566,7 @@
memset(b->dev,0,sizeof(*(b->dev)));
sprintf(b->dev->bus_id,"pci%d",bus);
strcpy(b->dev->name,"Host/PCI Bridge");
+ b->dev->parent = parent;
device_register(b->dev);

b->number = b->secondary = bus;
@@ -574,9 +575,9 @@
return b;
}

-struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
+struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata)
{
- struct pci_bus *b = pci_alloc_primary_bus(bus);
+ struct pci_bus *b = pci_alloc_primary_bus_parented(parent, bus);
if (b) {
b->sysdata = sysdata;
b->ops = ops;

include/linux/pci.h +1 -2
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
@@ -520,8 +520,16 @@
 /* Generic PCI functions used internally */
 
 int pci_bus_exists(const struct list_head *list, int nr);
-struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
-struct pci_bus *pci_alloc_primary_bus(int bus);
+struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct 

pci_ops *ops, void *sysdata);
+static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
+{
+ return pci_scan_bus_parented(NULL, bus, ops, sysdata);
+}
+struct pci_bus *pci_alloc_primary_bus_parented(struct device * parent, int bus);
+static inline struct pci_bus *pci_alloc_primary_bus(int bus)
+{
+ return pci_alloc_primary_bus_parented(NULL, bus);
+}
struct pci_dev *pci_scan_slot(struct pci_dev *temp);
int pci_proc_attach_device(struct pci_dev *dev);
int pci_proc_detach_device(struct pci_dev *dev);

===================================================================

This BitKeeper patch contains the following changesets:
1.927
## Wrapped with gzip_uu ##

begin 664 bkpatch568 M'XL(`$HW[CT``\U6:V_3,!3]7/^**_%EC"7U(\].G<9+@)A@&MHGA"HW,6NV M-*ELIS1_CO7R>C&:,LV@413Q9)S?>\YQ_<X>02G1NG1X%R=3\DC>%T;.QIH MN5257Y2^L4J5ZE+Y63W'IR=UC4^'LWJNAF[!\-G;X2(KO(74JK)%=>9Q/_1# M2C#V6-IL!DNES6C?+&:L9<+-1J<O'QU>O3TA)#Q&)[/9'6F/B@+XS&QM5[* M,C>'TL[*NO*MEI69*RL=A'85VG)*.5XABP4-HY9%-(C;C.6,R8"IG/(@B8+K M;[RUER,\9AS(<*DI0D5G+PYJ<\!LJ'C^I)J.>#(2L4>C$:7@^!^N%0J> M</`H>09_E\MSDH$LR_H+H.2PT,5<ZDN8-L8H@Z5@AEB@WPD#105VIB!7RR)3 M,*]S59*W$"%-<GPM./'N^2.$2DH.,&$V4^6A46>?95-:OS9YZ=?ZK,UUX;;< M=<5PH>LI"M+3"Q@6YZ%(VU"@OFV:Y"J@4\DRFH8AS;;HN3$IXU2PD,=AW*)" M,4-@VR4OJJQL<C4LBZKYZM+YLYOBIP%M&1-QU$9<)(E4/$]#F49!N@W=IJ0W MT-&1[SK]3547-?_?3U)45T<GC=:&E-D/K;%A3\WC:^;CS\E^K195X3.XHA M<I'$-.Z\P.FO5HA'X5VL$(G_D<K]WS'CS]I?MC;Q^OVYT'6.0%Z@^,O.D' M8W6360=T@@!A%R83!Z4J^CE'(YM<471DQZWRG>N5EX!W^WG]Y"/=50?8X$H MP0*#J7>,=Y!'P#C*^;[""2..R#=\<@)I/5?>KOP8V$]0(3XFT/EG61PZZY M-+FT\K&#D/80W#"XC6'JT&Y7X6=91WF_\]:P_WYS?%@Z]_%2!N/,8Y2VD0 M1*U(61)U1@K%@XS$*'C\OW22.]MN&6F-(\R$A?L7EX(S^UL#_K&OWL92T M18:+D("";85W[F6';V2@E6UTM<%R[TZ/CO;Z=-WR:T3?U]*_^^D!MX^/NY#\
H+?W.ZO#YE<D6'"M*'8G59R"^[[(+T\S'TSQA:(XI^0$X3;EMB@H````` `
end

#1 lore raw
Quoted 1 line · James Bottomley

Now that the generic device model allows a coherent bus tree to be built

Unfortunately it doesn't. Currently those legacy, PnP, EISA devices all have virtual parents, which has nothing to do with reality. Modern systems (including most PCs) hang these buses off PCI bus using PCI-to-{E}ISA bridge. Such systems must be able to register these buses upon discovery of the ISA bridges (from pci layer), and use them as a parent device for legacy/isa/pnp stuff. This will be absolutely required if DMA operations are moved from pci_dev to the generic device.

Review

Quoted 10 lines

-struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
+struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata)
{

(quoted diff) +1 -1
-	struct pci_bus *b = pci_alloc_primary_bus(bus);
+	struct pci_bus *b = pci_alloc_primary_bus_parented(parent, bus);
 	if (b) {
 		b->sysdata = sysdata;
 		b->ops = ops;

The `sysdata' arg already contains info about parent host-to-pci controller on many platforms. I don't think that we need to duplicate it with another one.
I was thinking about something like this instead of `sysdata':

struct io_controller { /* Level 0 I/O controller */

	... arch specific fields ...;
	... generic fields ...;	/* like `index' */
	struct device dev;
}

Ivan.

#2 lore raw
Quoted 1 line · James Bottomley

Now that the generic device model allows a coherent bus tree to be built

Quoted 1 line · [email protected] said:

Unfortunately it doesn't.

OK, consider the phrase for architectures with subordinate PCI busses added.

Quoted 7 lines · [email protected] said:

Currently those legacy, PnP, EISA devices all have virtual parents,
which has nothing to do with reality. Modern systems (including most PCs) hang these buses off PCI bus using PCI-to-{E}ISA bridge. Such systems must be able to register these buses upon discovery of the ISA bridges (from pci layer), and use them as a parent device for legacy/ isa/pnp stuff. This will be absolutely required if DMA operations are moved from pci_dev to the generic device.

Well, we are moving in this direction. I've already done the conversion for MCA. Marc Zyngier has done it for EISA. I believe someone is looking at PnP ISA. ISA, as a non-probe'able bus fits into the legacy bus scheme anyway.

Quoted 4 lines

The `sysdata' arg already contains info about parent host-to-pci controller on many platforms. I don't think that we need to duplicate it with another one. I was thinking about something like this instead of `sysdata':

That's PCI specific. We need a coherent tree in the generic model. To do this, the PCI parent information has to be available just using the struct device, without having to cast it to pci_dev and look at pci specific fields.

This is a simplification requirement for machines whose IOMMUs lie on other bus types above the PCI busses. You have to be able to walk up the device tree until you find the IOMMU. Since you're sharing the implementation with the non-PCI busses, you need to be able to do this in a generic manner.

James

#3 lore raw
Quoted 7 lines · James Bottomley
Quoted 2 lines · [email protected] said:

isa/pnp stuff. This will be absolutely required if DMA operations are moved from pci_dev to the generic device.

Well, we are moving in this direction. I've already done the conversion for MCA. Marc Zyngier has done it for EISA. I believe someone is looking at PnP ISA. ISA, as a non-probe'able bus fits into the legacy bus scheme anyway.

Nice to know. :-)
Current approach with initcalls doesn't work - basically, only architecture specific code knows what bus types are primary and therefore should be initialized first. IOW, it would be good to have something like you've suggested for PCI for any bus type:

XXX_bus_init(struct device *parent, int busnum)

Quoted 6 lines
Quoted 4 lines

The `sysdata' arg already contains info about parent host-to-pci controller on many platforms. I don't think that we need to duplicate it with another one. I was thinking about something like this instead of `sysdata':

That's PCI specific.

Actually it isn't. It just happens to be that sysdata == pci_controller on pci-based machines. However, these structures have very little to do with PCI - it's all about IOMMUs, various address ranges and other host-specific data.

Quoted 3 lines

We need a coherent tree in the generic model. To do
this, the PCI parent information has to be available just using the struct device, without having to cast it to pci_dev and look at pci specific fields.

Of course.

Quoted 2 lines

This is a simplification requirement for machines whose IOMMUs lie on other bus types above the PCI busses.

That's why I suggested io_controller' name, but I can live with just sysdata' as well. :-)

Quoted 3 lines

You have to be able to walk up the device
tree until you find the IOMMU. Since you're sharing the implementation with the non-PCI busses, you need to be able to do this in a generic manner.

Right, but walking up the entire tree every time is rather painful. Things like pci^H^H^Hdma_map_{single,sg} are supposed to be fast, so I'd like to gather IOMMU and other info directly from struct device * passed as argument to these functions.

Ivan.