static int mk_conf_addr(struct pci_bus *pbus, unsigned int devfn, int where, struct pci_controller *hose, unsigned long *pci_addr, unsigned char *type1) { u8 bus = pbus->number; unsigned long addr; DBG_CFG(("mk_conf_addr(bus=%d,devfn=0x%x,hose=%d,where=0x%x," " pci_addr=0x%p, type1=0x%p)\n", bus, devfn, hose->index, where, pci_addr, type1)); /* Type 1 configuration cycle for *ALL* busses. */ *type1 = 1; if (!pbus->parent) /* No parent means peer PCI bus. */ bus = 0; addr = (bus << 16) | (devfn << 8) | (where); addr <<= 5; /* swizzle for SPARSE */ addr |= hose->config_space_base; *pci_addr = addr; DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); return 0; }
static void conf_write(unsigned long addr, unsigned int value, unsigned char type1, struct pci_controller *hose) { unsigned long flags; unsigned long mid = MCPCIA_HOSE2MID(hose->index); unsigned int stat0, temp, cpu; cpu = smp_processor_id(); local_irq_save(flags); /* avoid getting hit by machine check */ /* Reset status register to avoid losing errors. */ stat0 = *(vuip)MCPCIA_CAP_ERR(mid); *(vuip)MCPCIA_CAP_ERR(mid) = stat0; mb(); temp = *(vuip)MCPCIA_CAP_ERR(mid); DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", mid, stat0)); draina(); mcheck_expected(cpu) = 1; mcheck_extra(cpu) = mid; mb(); /* Access configuration space. */ *((vuip)addr) = value; mb(); mb(); /* magic */ temp = *(vuip)MCPCIA_CAP_ERR(mid); /* read to force the write */ mcheck_expected(cpu) = 0; mb(); DBG_CFG(("conf_write(): finished\n")); local_irq_restore(flags); }
static int mk_conf_addr(struct pci_dev *dev, int where, struct pci_controler *hose, unsigned long *pci_addr, unsigned char *type1) { u8 bus = dev->bus->number; u8 devfn = dev->devfn; unsigned long addr; DBG_CFG(("mk_conf_addr(bus=%d,devfn=0x%x,hose=%d,where=0x%x," " pci_addr=0x%p, type1=0x%p)\n", bus, devfn, hose->index, where, pci_addr, type1)); /* Type 1 configuration cycle for *ALL* busses. */ *type1 = 1; if (dev->bus->number == hose->first_busno) bus = 0; addr = (bus << 16) | (devfn << 8) | (where); addr <<= 5; /* swizzle for SPARSE */ addr |= hose->config_space_base; *pci_addr = addr; DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); return 0; }
static int mk_conf_addr(u8 bus, u8 device_fn, u8 where, struct linux_hose_info *hose, unsigned long *pci_addr, unsigned char *type1) { unsigned long addr; if (!pci_probe_enabled) return -1; DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, " "pci_addr=0x%p, type1=0x%p)\n", bus, device_fn, where, pci_addr, type1)); *type1 = (bus != 0); if (hose->pci_first_busno == bus) bus = 0; addr = (bus << 16) | (device_fn << 8) | where; addr |= hose->pci_config_space; *pci_addr = addr; DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); return 0; }
static int mercury_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA; u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus,devfn); if ((pos > 255) || (devfn > 255)) return -EINVAL; DBG_CFG("%s(%x+%2x) <- 0x%x (c)\n", __func__, tok, pos, data); LBA_CFG_TR4_ADDR_SETUP(d, tok | pos); switch(size) { case 1: WRITE_REG8 (data, data_reg + (pos & 3)); break; case 2: WRITE_REG16(data, data_reg + (pos & 2)); break; case 4: WRITE_REG32(data, data_reg); break; } /* flush posted write */ lba_t32 = READ_U32(d->hba.base_addr + LBA_PCI_CFG_ADDR); return 0; }
static int mercury_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus, devfn); void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA; if ((pos > 255) || (devfn > 255)) return -EINVAL; LBA_CFG_TR4_ADDR_SETUP(d, tok | pos); switch(size) { case 1: *data = READ_REG8(data_reg + (pos & 3)); break; case 2: *data = READ_REG16(data_reg + (pos & 2)); break; case 4: *data = READ_REG32(data_reg); break; break; } DBG_CFG("mercury_cfg_read(%x+%2x) -> 0x%x\n", tok, pos, *data); return 0; }
static unsigned int conf_read(unsigned long addr, unsigned char type1, struct pci_controller *hose) { unsigned long flags; unsigned long mid = MCPCIA_HOSE2MID(hose->index); unsigned int stat0, value, temp, cpu; cpu = smp_processor_id(); local_irq_save(flags); DBG_CFG(("conf_read(addr=0x%lx, type1=%d, hose=%d)\n", addr, type1, mid)); /* Reset status register to avoid losing errors. */ stat0 = *(vuip)MCPCIA_CAP_ERR(mid); *(vuip)MCPCIA_CAP_ERR(mid) = stat0; mb(); temp = *(vuip)MCPCIA_CAP_ERR(mid); DBG_CFG(("conf_read: MCPCIA_CAP_ERR(%d) was 0x%x\n", mid, stat0)); mb(); draina(); mcheck_expected(cpu) = 1; mcheck_taken(cpu) = 0; mcheck_extra(cpu) = mid; mb(); /* Access configuration space. */ value = *((vuip)addr); mb(); mb(); /* magic */ if (mcheck_taken(cpu)) { mcheck_taken(cpu) = 0; value = 0xffffffffU; mb(); } mcheck_expected(cpu) = 0; mb(); DBG_CFG(("conf_read(): finished\n")); local_irq_restore(flags); return value; }
static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus, devfn); void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA; if ((pos > 255) || (devfn > 255)) return -EINVAL; /* FIXME: B2K/C3600 workaround is always use old method... */ /* if (!LBA_SKIP_PROBE(d)) */ { /* original - Generate config cycle on broken elroy with risk we will miss PCI bus errors. */ *data = lba_rd_cfg(d, tok, pos, size); DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __func__, tok, pos, *data); return 0; } if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->busn_res.start, devfn, d)) { DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __func__, tok, pos); /* either don't want to look or know device isn't present. */ *data = ~0U; return(0); } /* Basic Algorithm ** Should only get here on fully working LBA rev. ** This is how simple the code should have been. */ LBA_CFG_ADDR_SETUP(d, tok | pos); switch(size) { case 1: *data = READ_REG8 (data_reg + (pos & 3)); break; case 2: *data = READ_REG16(data_reg + (pos & 2)); break; case 4: *data = READ_REG32(data_reg); break; } DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __func__, tok, pos, *data); return 0; }
static int mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr, u8 *type1) { *type1 = (bus == 0) ? 0 : 1; *pci_addr = (bus << 16) | (device_fn << 8) | (where) | POLARIS_DENSE_CONFIG_BASE; DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x," " returning address 0x%p\n" bus, device_fn, where, *pci_addr)); return 0; }
static int elroy_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus,devfn); if ((pos > 255) || (devfn > 255)) return -EINVAL; if (!LBA_SKIP_PROBE(d)) { /* Original Workaround */ lba_wr_cfg(d, tok, pos, (u32) data, size); DBG_CFG("%s(%x+%2x) = 0x%x (a)\n", __func__, tok, pos,data); return 0; } if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->busn_res.start, devfn, d))) { DBG_CFG("%s(%x+%2x) = 0x%x (b)\n", __func__, tok, pos,data); return 1; /* New Workaround */ } DBG_CFG("%s(%x+%2x) = 0x%x (c)\n", __func__, tok, pos, data); /* Basic Algorithm */ LBA_CFG_ADDR_SETUP(d, tok | pos); switch(size) { case 1: WRITE_REG8 (data, d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & 3)); break; case 2: WRITE_REG16(data, d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & 2)); break; case 4: WRITE_REG32(data, d->hba.base_addr + LBA_PCI_CFG_DATA); break; } /* flush posted write */ lba_t32 = READ_REG32(d->hba.base_addr + LBA_PCI_CFG_ADDR); return 0; }
static int mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr, u8 *type1) { u8 bus = dev->bus->number; u8 device_fn = dev->devfn; *type1 = (bus == 0) ? 0 : 1; *pci_addr = (bus << 16) | (device_fn << 8) | (where) | POLARIS_DENSE_CONFIG_BASE; DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x," " returning address 0x%p\n" bus, device_fn, where, *pci_addr)); return 0; }