Skip to contentSkip to conversation

CFT/RFC: New cardbus resource allocation

PATCH Russell King 2 participants 5 messages Nov 6, 2002 – Nov 11, 2002

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

The following is an experimental patch adjusts the way we allocate resouces for PCMCIA cards in cardbus devices.

When a PCMCIA driver wishes to claim resources for a card, the original code used to use an in-kernel structured list to find a free area of memory, mostly ignoring the Linux resource subsystem (although it did make use of the resource subsystem, it's racy.)

The following patch changes this. We instead use the PCI resource code to allocate a resource of the requested size, alignment, and offset from the parent bus of the cardbus bridge.

Why do we need the size, alignment and offset?

Some PCMCIA devices have specific requirements for IO addresses; some cards only decode 10 bits, and expect these 10 bits to be one of a selection of addresses. This means that the top 6 bits are ignored, and can be any value. However, the lower 10 bits must be one of a fixed set of values, eg 0x3f8, 0x3e8, 0x2f8, 0x2e8.

Hence, 0x3f8, 0x7f8, 0xbf8 etc are all possible values, which obviously gives you an alignment of (1 << 10) and an offset of 0x3f8.

(Appologies in advance if I've messed this patch up - it got dug it out of a pile of other patches in this area.)

drivers/pci/pci.c +1 -0
diff -ur orig/drivers/pci/pci.c linux/drivers/pci/pci.c
@@ -659,6 +659,7 @@
 EXPORT_SYMBOL(pci_clear_mwi);
 EXPORT_SYMBOL(pci_set_dma_mask);
 EXPORT_SYMBOL(pci_dac_set_dma_mask);
+EXPORT_SYMBOL(pci_alloc_parent_resource);
 EXPORT_SYMBOL(pci_assign_resource);
 EXPORT_SYMBOL(pci_find_parent_resource);
 
drivers/pci/setup-res.c +47 -6

72 lines not on this page · raw message

drivers/pcmcia/cardbus.c +102 -0

105 lines not on this page · raw message

drivers/pcmcia/cs.c +1 -0
diff -ur orig/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
@@ -483,6 +483,7 @@
     cb_release_cis_mem(s);
     cb_free(s);
 #endif
+    release_cis_mem(s);
     s->functions = 0;
     if (s->config) {
 	kfree(s->config);
drivers/pcmcia/rsrc_mgr.c +41 -74

203 lines not on this page · raw message

Signature · 2 lines
Russell King ([email protected])                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html
#1 lore raw

Gah, sorry - should've mentioned - this patch is against plain 2.5.46.

Signature · 2 lines
Russell King ([email protected])                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html
#2 lore raw
In reply to Russell King
Quoted 3 lines · Russell King

The following patch changes this. We instead use the PCI resource code to allocate a resource of the requested size, alignment, and offset from the parent bus of the cardbus bridge.

Looks quite reasonable.
Note that we don't need 2 similar functions in setup-res.c - pci_assign_resource() can be easily converted to use your pci_alloc_parent_resource(), and pci_assign_bus_resource() can be killed then.

Ivan.

#3 lore raw
Quoted 5 lines · Ivan Kokshaysky

Looks quite reasonable.
Note that we don't need 2 similar functions in setup-res.c - pci_assign_resource() can be easily converted to use your pci_alloc_parent_resource(), and pci_assign_bus_resource() can be killed then.

I looked at that and decided it wasn't practical. pci_assign_resource() needs the parent resource to pass it down to the architecture specific layers. Unfortunately, trying to get that out of pci_alloc_parent_resource() makes the API rather disgusting IMHO.

Signature · 2 lines
Russell King ([email protected])                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html
#4 lore raw
Quoted 11 lines · Russell King
Quoted 5 lines · Ivan Kokshaysky

Looks quite reasonable.
Note that we don't need 2 similar functions in setup-res.c - pci_assign_resource() can be easily converted to use your pci_alloc_parent_resource(), and pci_assign_bus_resource() can be killed then.

I looked at that and decided it wasn't practical. pci_assign_resource() needs the parent resource to pass it down to the architecture specific layers. Unfortunately, trying to get that out of pci_alloc_parent_resource() makes the API rather disgusting IMHO.

Sigh. The API is already broken - passing parent resource to pcibios_update_resource() is not only pointless (since we have res->parent), but extremely misleading.
Almost all architectures declare
void
pcibios_update_resource(struct pci_dev *dev, struct resource *root,

							      ^^^^
			struct resource *res, int resource)

Obviously root != parent.
Vast majority of archs do not use `root' arg, but some do:

mips64/mips-boards/generic/pci.c
mips64/sgi-ip27/ip27-pci.c
mips/ite-boards/generic/it8172_pci.c
mips/mips-boards/generic/pci.c
ia64/pci/pci.c

All of these use exactly the same code:

pcibios_update_resource(struct pci_dev *dev, struct resource *root,
struct resource *res, int resource)

{
	unsigned long where, size;
	u32 reg;

	where = PCI_BASE_ADDRESS_0 + (resource * 4);
	size = res->end - res->start;
	pci_read_config_dword(dev, where, &reg);
	reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
	pci_write_config_dword(dev, where, reg);
}

Which is wrong if the `root' is a pointer to the PCI or CardBus bridge resource.

The arg 2 to pcibios_update_resource() must be removed...

Ivan.