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);
}
示例#3
0
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;
}
示例#4
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;
}
示例#5
0
文件: lba_pci.c 项目: 020gzh/linux
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;
}
示例#6
0
文件: lba_pci.c 项目: 020gzh/linux
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;
}
示例#8
0
文件: lba_pci.c 项目: 020gzh/linux
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;
}
示例#9
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;
}
示例#10
0
文件: lba_pci.c 项目: 020gzh/linux
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;
}
示例#11
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;
}