Loading arch/sparc64/kernel/pci.c +89 −30 Original line number Diff line number Diff line Loading @@ -368,7 +368,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; Loading Loading @@ -400,6 +401,13 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->devfn = devfn; dev->multifunction = 0; /* maybe a lie? */ if (host_controller) { dev->vendor = 0x108e; dev->device = 0x8000; dev->subsystem_vendor = 0x0000; dev->subsystem_device = 0x0000; dev->cfg_size = 256; } else { dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); dev->device = of_getintprop_default(node, "device-id", 0xffff); dev->subsystem_vendor = Loading @@ -408,24 +416,32 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, of_getintprop_default(node, "subsystem-id", 0); dev->cfg_size = pci_cfg_space_size(dev); } sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); /* dev->class = of_getintprop_default(node, "class-code", 0); */ /* 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. if (host_controller) { dev->class = PCI_CLASS_BRIDGE_HOST << 8; } else { /* 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; } printk(" class: 0x%x\n", dev->class); dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; if (host_controller) { dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; dev->rom_base_reg = PCI_ROM_ADDRESS1; dev->irq = PCI_IRQ_NONE; } else { if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { /* a PCI-PCI bridge */ dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; Loading @@ -440,7 +456,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, if (dev->irq == 0xffffffff) dev->irq = PCI_IRQ_NONE; } } pci_parse_of_addrs(sd->op, node, dev); printk(" adding to system ...\n"); Loading Loading @@ -632,7 +648,7 @@ static void __init pci_of_scan_bus(struct pci_pbm_info *pbm, devfn = (reg[0] >> 8) & 0xff; /* create a new pci_dev for this device */ dev = of_create_pci_dev(pbm, child, bus, devfn); dev = of_create_pci_dev(pbm, child, bus, devfn, 0); if (!dev) continue; printk("PCI: dev header type: %x\n", dev->hdr_type); Loading Loading @@ -677,10 +693,49 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) pci_bus_register_of_sysfs(child_bus); } int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, int where, int size, u32 *value) { static u8 fake_pci_config[] = { 0x8e, 0x10, /* Vendor: 0x108e (Sun) */ 0x00, 0x80, /* Device: 0x8000 (PBM) */ 0x46, 0x01, /* Command: 0x0146 (SERR, PARITY, MASTER, MEM) */ 0xa0, 0x22, /* Status: 0x02a0 (DEVSEL_MED, FB2B, 66MHZ) */ 0x00, 0x00, 0x00, 0x06, /* Class: 0x06000000 host bridge */ 0x00, /* Cacheline: 0x00 */ 0x40, /* Latency: 0x40 */ 0x00, /* Header-Type: 0x00 normal */ }; *value = 0; if (where >= 0 && where < sizeof(fake_pci_config) && (where + size) >= 0 && (where + size) < sizeof(fake_pci_config) && size <= sizeof(u32)) { while (size--) { *value <<= 8; *value |= fake_pci_config[where + size]; } } return PCIBIOS_SUCCESSFUL; } int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, int where, int size, u32 value) { return PCIBIOS_SUCCESSFUL; } struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm) { struct pci_controller_info *p = pbm->parent; struct device_node *node = pbm->prom_node; struct pci_dev *host_pdev; struct pci_bus *bus; printk("PCI: Scanning PBM %s\n", node->full_name); Loading @@ -698,6 +753,10 @@ struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm) bus->resource[0] = &pbm->io_space; bus->resource[1] = &pbm->mem_space; /* Create the dummy host bridge and link it in. */ host_pdev = of_create_pci_dev(pbm, node, bus, 0x00, 1); bus->self = host_pdev; pci_of_scan_bus(pbm, node, bus); pci_bus_add_devices(bus); pci_bus_register_of_sysfs(bus); Loading arch/sparc64/kernel/pci_impl.h +9 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,15 @@ extern int pci_num_controllers; extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); extern int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, int where, int size, u32 *value); extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, int where, int size, u32 value); /* Error reporting support. */ extern void pci_scan_for_target_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); extern void pci_scan_for_master_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); Loading arch/sparc64/kernel/pci_psycho.c +7 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,10 @@ static int psycho_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, u16 tmp16; u8 tmp8; if (bus_dev == pbm->pci_bus && devfn == 0x00) return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, size, value); switch (size) { case 1: *value = 0xff; Loading Loading @@ -171,6 +175,9 @@ static int psycho_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned char bus = bus_dev->number; u32 *addr; if (bus_dev == pbm->pci_bus && devfn == 0x00) return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, size, value); addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where); if (!addr) return PCIBIOS_SUCCESSFUL; Loading arch/sparc64/kernel/pci_sabre.c +12 −0 Original line number Diff line number Diff line Loading @@ -319,6 +319,12 @@ static int __sabre_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, static int sabre_read_pci_cfg(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) { struct pci_pbm_info *pbm = bus->sysdata; if (bus == pbm->pci_bus && devfn == 0x00) return pci_host_bridge_read_pci_cfg(bus, devfn, where, size, value); if (!bus->number && sabre_out_of_range(devfn)) { switch (size) { case 1: Loading Loading @@ -435,6 +441,12 @@ static int __sabre_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, static int sabre_write_pci_cfg(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { struct pci_pbm_info *pbm = bus->sysdata; if (bus == pbm->pci_bus && devfn == 0x00) return pci_host_bridge_write_pci_cfg(bus, devfn, where, size, value); if (bus->number) return __sabre_write_pci_cfg(bus, devfn, where, size, value); Loading arch/sparc64/kernel/pci_schizo.c +6 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,9 @@ static int schizo_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, u16 tmp16; u8 tmp8; if (bus_dev == pbm->pci_bus && devfn == 0x00) return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, size, value); switch (size) { case 1: *value = 0xff; Loading Loading @@ -178,6 +181,9 @@ static int schizo_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned char bus = bus_dev->number; u32 *addr; if (bus_dev == pbm->pci_bus && devfn == 0x00) return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, size, value); addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); if (!addr) return PCIBIOS_SUCCESSFUL; Loading Loading
arch/sparc64/kernel/pci.c +89 −30 Original line number Diff line number Diff line Loading @@ -368,7 +368,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; Loading Loading @@ -400,6 +401,13 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->devfn = devfn; dev->multifunction = 0; /* maybe a lie? */ if (host_controller) { dev->vendor = 0x108e; dev->device = 0x8000; dev->subsystem_vendor = 0x0000; dev->subsystem_device = 0x0000; dev->cfg_size = 256; } else { dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); dev->device = of_getintprop_default(node, "device-id", 0xffff); dev->subsystem_vendor = Loading @@ -408,24 +416,32 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, of_getintprop_default(node, "subsystem-id", 0); dev->cfg_size = pci_cfg_space_size(dev); } sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); /* dev->class = of_getintprop_default(node, "class-code", 0); */ /* 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. if (host_controller) { dev->class = PCI_CLASS_BRIDGE_HOST << 8; } else { /* 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; } printk(" class: 0x%x\n", dev->class); dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; if (host_controller) { dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; dev->rom_base_reg = PCI_ROM_ADDRESS1; dev->irq = PCI_IRQ_NONE; } else { if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { /* a PCI-PCI bridge */ dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; Loading @@ -440,7 +456,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, if (dev->irq == 0xffffffff) dev->irq = PCI_IRQ_NONE; } } pci_parse_of_addrs(sd->op, node, dev); printk(" adding to system ...\n"); Loading Loading @@ -632,7 +648,7 @@ static void __init pci_of_scan_bus(struct pci_pbm_info *pbm, devfn = (reg[0] >> 8) & 0xff; /* create a new pci_dev for this device */ dev = of_create_pci_dev(pbm, child, bus, devfn); dev = of_create_pci_dev(pbm, child, bus, devfn, 0); if (!dev) continue; printk("PCI: dev header type: %x\n", dev->hdr_type); Loading Loading @@ -677,10 +693,49 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) pci_bus_register_of_sysfs(child_bus); } int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, int where, int size, u32 *value) { static u8 fake_pci_config[] = { 0x8e, 0x10, /* Vendor: 0x108e (Sun) */ 0x00, 0x80, /* Device: 0x8000 (PBM) */ 0x46, 0x01, /* Command: 0x0146 (SERR, PARITY, MASTER, MEM) */ 0xa0, 0x22, /* Status: 0x02a0 (DEVSEL_MED, FB2B, 66MHZ) */ 0x00, 0x00, 0x00, 0x06, /* Class: 0x06000000 host bridge */ 0x00, /* Cacheline: 0x00 */ 0x40, /* Latency: 0x40 */ 0x00, /* Header-Type: 0x00 normal */ }; *value = 0; if (where >= 0 && where < sizeof(fake_pci_config) && (where + size) >= 0 && (where + size) < sizeof(fake_pci_config) && size <= sizeof(u32)) { while (size--) { *value <<= 8; *value |= fake_pci_config[where + size]; } } return PCIBIOS_SUCCESSFUL; } int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, int where, int size, u32 value) { return PCIBIOS_SUCCESSFUL; } struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm) { struct pci_controller_info *p = pbm->parent; struct device_node *node = pbm->prom_node; struct pci_dev *host_pdev; struct pci_bus *bus; printk("PCI: Scanning PBM %s\n", node->full_name); Loading @@ -698,6 +753,10 @@ struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm) bus->resource[0] = &pbm->io_space; bus->resource[1] = &pbm->mem_space; /* Create the dummy host bridge and link it in. */ host_pdev = of_create_pci_dev(pbm, node, bus, 0x00, 1); bus->self = host_pdev; pci_of_scan_bus(pbm, node, bus); pci_bus_add_devices(bus); pci_bus_register_of_sysfs(bus); Loading
arch/sparc64/kernel/pci_impl.h +9 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,15 @@ extern int pci_num_controllers; extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); extern int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, int where, int size, u32 *value); extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, int where, int size, u32 value); /* Error reporting support. */ extern void pci_scan_for_target_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); extern void pci_scan_for_master_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); Loading
arch/sparc64/kernel/pci_psycho.c +7 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,10 @@ static int psycho_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, u16 tmp16; u8 tmp8; if (bus_dev == pbm->pci_bus && devfn == 0x00) return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, size, value); switch (size) { case 1: *value = 0xff; Loading Loading @@ -171,6 +175,9 @@ static int psycho_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned char bus = bus_dev->number; u32 *addr; if (bus_dev == pbm->pci_bus && devfn == 0x00) return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, size, value); addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where); if (!addr) return PCIBIOS_SUCCESSFUL; Loading
arch/sparc64/kernel/pci_sabre.c +12 −0 Original line number Diff line number Diff line Loading @@ -319,6 +319,12 @@ static int __sabre_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, static int sabre_read_pci_cfg(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) { struct pci_pbm_info *pbm = bus->sysdata; if (bus == pbm->pci_bus && devfn == 0x00) return pci_host_bridge_read_pci_cfg(bus, devfn, where, size, value); if (!bus->number && sabre_out_of_range(devfn)) { switch (size) { case 1: Loading Loading @@ -435,6 +441,12 @@ static int __sabre_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, static int sabre_write_pci_cfg(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { struct pci_pbm_info *pbm = bus->sysdata; if (bus == pbm->pci_bus && devfn == 0x00) return pci_host_bridge_write_pci_cfg(bus, devfn, where, size, value); if (bus->number) return __sabre_write_pci_cfg(bus, devfn, where, size, value); Loading
arch/sparc64/kernel/pci_schizo.c +6 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,9 @@ static int schizo_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, u16 tmp16; u8 tmp8; if (bus_dev == pbm->pci_bus && devfn == 0x00) return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, size, value); switch (size) { case 1: *value = 0xff; Loading Loading @@ -178,6 +181,9 @@ static int schizo_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned char bus = bus_dev->number; u32 *addr; if (bus_dev == pbm->pci_bus && devfn == 0x00) return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, size, value); addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); if (!addr) return PCIBIOS_SUCCESSFUL; Loading