Hi Josip
On Mon, Oct 27, 2008 at 10:20:21AM +0100, Josip Rodin wrote:
> On Mon, Oct 27, 2008 at 09:36:39AM +0100, Gaudenz Steinlin wrote:
> > 1. Install the kernel package from http://people.debian.org/~gaudenz/sparc
> >and test if this fixes the problem. This is the same kernel as currently
> >in unstable with the problematic change removed. Please also test this
> >kernel if you are not affected by the change to see if the removal of
> > the
> >problematic change has any ill side effects.
>
> Could you extract the relevant patch from that package and send it over?
> I've no idea if our modern packaged kernels work on my machine, and I don't
> see any point in having to test both of those at once.
I've attached the patch against 2.6.26 up to 2.26.5 and the patch against
2.26.6.
But kernels before 2.6.26-rcX should work without any problem. So testing is
only
useful if you are running a modern kernel. The patch just reverts the
problematic
changes. Older kernels without the changes should be fine.
Gaudenz
--
Ever tried. Ever failed. No matter.
Try again. Fail again. Fail better.
~ Samuel Beckett ~
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 2db2148..dbf2fc2 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -350,7 +350,8 @@ static void pci_parse_of_addrs(struct of_device *op,
struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
struct device_node *node,
- struct pci_bus *bus, int devfn)
+ struct pci_bus *bus, int devfn,
+ int host_controller)
{
struct dev_archdata *sd;
struct pci_dev *dev;
@@ -389,28 +390,43 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
dev->devfn = devfn;
dev->multifunction = 0; /* maybe a lie? */
- dev->vendor = of_getintprop_default(node, "vendor-id", 0x);
- dev->device = of_getintprop_default(node, "device-id", 0x);
- dev->subsystem_vendor =
- of_getintprop_default(node, "subsystem-vendor-id", 0);
- dev->subsystem_device =
- of_getintprop_default(node, "subsystem-id", 0);
-
- dev->cfg_size = pci_cfg_space_size(dev);
-
- /* We can't actually use the firmware value, we have
- * to read what is in the register right now. One
- * reason is that in the case of IDE interfaces the
- * firmware can sample the value before the the IDE
- * interface is programmed into native mode.
- */
- pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
- dev->class = class >> 8;
- dev->revision = class & 0xff;
-
- sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
- dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ if (host_controller) {
+ if (tlb_type != hypervisor) {
+ pci_read_config_word(dev, PCI_VENDOR_ID,
+ &dev->vendor);
+ pci_read_config_word(dev, PCI_DEVICE_ID,
+ &dev->device);
+ } else {
+ dev->vendor = PCI_VENDOR_ID_SUN;
+ dev->device = 0x80f0;
+ }
+ dev->cfg_size = 256;
+ dev->class = PCI_CLASS_BRIDGE_HOST << 8;
+ sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
+ 0x00, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ } else {
+ dev->vendor = of_getintprop_default(node, "vendor-id", 0x);
+ dev->device = of_getintprop_default(node, "device-id", 0x);
+ dev->subsystem_vendor =
+ of_getintprop_default(node, "subsystem-vendor-id", 0);
+ dev->subsystem_device =
+ of_getintprop_default(node, "subsystem-id", 0);
+
+ dev->cfg_size = pci_cfg_space_size(dev);
+
+ /* We can't actually use the firmware value, we have
+ * to read what is in the register right now. One
+ * reason is that in the case of IDE interfaces the
+ * firmware can sample the value before the the IDE
+ * interface is programmed into native mode.
+ */
+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
+ dev->class = class >> 8;
+ dev->revision = class & 0xff;
+ sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
+ dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ }
if (ofpci_verbose)
printk("class: 0x%x device name: %s\n",
dev->class, pci_name(dev));
@@ -425,21 +441,26 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
dev->current_state = 4; /* unknown power state */
dev->error_state = pci_channel_io_normal;
- if (!strcmp(node->name, "pci")) {
- /* a PCI-PCI bridge */
+ if (host_controller) {
dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
dev->rom_base_reg = PCI_ROM_ADDRESS1;
- } else if (!strcmp(type, "cardbus")) {
- dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
+ dev->irq = PCI_IRQ_NONE;
} else {
- dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
- dev->rom_base_reg = PCI_ROM_ADDRESS;
+ if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
+ /* a PCI-PCI bridge */
+ dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
+ dev->rom_base_reg = PCI_ROM_ADDRESS1;
+ } else if (!strcmp(type, "cardbus")) {
+ dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
+ } else {
+ dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
+ dev->rom_base_reg = PCI_ROM_ADDRESS;