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 __init
mcpcia_probe_hose(int h)
{
	int cpu = smp_processor_id();
	int mid = MCPCIA_HOSE2MID(h);
	unsigned int pci_rev;

	/* Gotta be REAL careful.  If hose is absent, we get an mcheck.  */

	mb();
	mb();
	draina();
	wrmces(7);

	mcheck_expected(cpu) = 2;	/* indicates probing */
	mcheck_taken(cpu) = 0;
	mcheck_extra(cpu) = mid;
	mb();

	/* Access the bus revision word. */
	pci_rev = *(vuip)MCPCIA_REV(mid);

	mb();
	mb();  /* magic */
	if (mcheck_taken(cpu)) {
		mcheck_taken(cpu) = 0;
		pci_rev = 0xffffffff;
		mb();
	}
	mcheck_expected(cpu) = 0;
	mb();

	return (pci_rev >> 16) == PCI_CLASS_BRIDGE_HOST;
}
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;
}
예제 #4
0
void
mcpcia_machine_check(unsigned long vector, unsigned long la_ptr,
		     struct pt_regs * regs)
{
	struct el_common *mchk_header;
	struct el_MCPCIA_uncorrected_frame_mcheck *mchk_logout;
	unsigned int cpu = smp_processor_id();
	int expected;

	mchk_header = (struct el_common *)la_ptr;
	mchk_logout = (struct el_MCPCIA_uncorrected_frame_mcheck *)la_ptr;
	expected = mcheck_expected(cpu);

	mb();
	mb();  /* magic */
	draina();

	switch (expected) {
	case 0:
	    {
		/* FIXME: how do we figure out which hose the
		   error was on?  */	
		struct pci_controler *hose;
		for (hose = hose_head; hose; hose = hose->next)
			mcpcia_pci_clr_err(MCPCIA_HOSE2MID(hose->index));
		break;
	    }
	case 1:
		mcpcia_pci_clr_err(mcheck_extra(cpu));
		break;
	default:
		/* Otherwise, we're being called from mcpcia_probe_hose
		   and there's no hose clear an error from.  */
		break;
	}

	wrmces(0x7);
	mb();

	process_mcheck_info(vector, la_ptr, regs, "MCPCIA", expected != 0);
	if (!expected && vector != 0x620 && vector != 0x630) {
		mcpcia_print_uncorrectable(mchk_logout);
		mcpcia_print_system_area(la_ptr);
	}
}