#ifdef __LP64__ 
#ifdef CONFIG_64BIT 
sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num){	u32 iova_space_mask;	u32 iova_space_size;	int iov_order, tcnfg;#if SBA_AGP_SUPPORT	int agp_found = 0;#endif	/*	** Firmware programs the base and size of a "safe IOVA space"	** (one that doesn't overlap memory or LMMIO space) in the	** IBASE and IMASK registers.	*/	ioc->ibase = READ_REG(ioc->ioc_hpa + IOC_IBASE);	iova_space_size = ~(READ_REG(ioc->ioc_hpa + IOC_IMASK) & 0xFFFFFFFFUL) + 1;	if ((ioc->ibase < 0xfed00000UL) && ((ioc->ibase + iova_space_size) > 0xfee00000UL)) {		printk("WARNING: IOV space overlaps local config and interrupt message, truncating\n");		iova_space_size /= 2;	}	/*	** iov_order is always based on a 1GB IOVA space since we want to	** turn on the other half for AGP GART.	*/	iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT));	ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);	DBG_INIT("%s() hpa 0x%lx IOV %dMB (%d bits)\n",		__FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20,		iov_order + PAGE_SHIFT);	ioc->pdir_base = (void *) __get_free_pages(GFP_KERNEL,						   get_order(ioc->pdir_size));	if (!ioc->pdir_base)		panic("Couldn't allocate I/O Page Table\n");	memset(ioc->pdir_base, 0, ioc->pdir_size);	DBG_INIT("%s() pdir %p size %x\n",			__FUNCTION__, ioc->pdir_base, ioc->pdir_size);#if SBA_HINT_SUPPORT	ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;	ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT));	DBG_INIT("	hint_shift_pdir %x hint_mask_pdir %lx\n",		ioc->hint_shift_pdir, ioc->hint_mask_pdir);#endif	WARN_ON((((unsigned long) ioc->pdir_base) & PAGE_MASK) != (unsigned long) ioc->pdir_base);	WRITE_REG(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE);	/* build IMASK for IOC and Elroy */	iova_space_mask =  0xffffffff;	iova_space_mask <<= (iov_order + PAGE_SHIFT);	ioc->imask = iova_space_mask;#ifdef ZX1_SUPPORT	ioc->iovp_mask = ~(iova_space_mask + PAGE_SIZE - 1);#endif	sba_dump_tlb(ioc->ioc_hpa);	setup_ibase_imask(sba, ioc, ioc_num);	WRITE_REG(ioc->imask, ioc->ioc_hpa + IOC_IMASK);#ifdef __LP64__	/*	** Setting the upper bits makes checking for bypass addresses	** a little faster later on.	*/	ioc->imask |= 0xFFFFFFFF00000000UL;#endif	/* Set I/O PDIR Page size to system page size */	switch (PAGE_SHIFT) {		case 12: tcnfg = 0; break;	/*  4K */		case 13: tcnfg = 1; break;	/*  8K */		case 14: tcnfg = 2; break;	/* 16K */		case 16: tcnfg = 3; break;	/* 64K */		default:			panic(__FILE__ "Unsupported system page size %d",				1 << PAGE_SHIFT);			break;	}	WRITE_REG(tcnfg, ioc->ioc_hpa + IOC_TCNFG);	/*	** Program the IOC's ibase and enable IOVA translation	** Bit zero == enable bit.	*/	WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa + IOC_IBASE);	/*	** Clear I/O TLB of any possible entries.	** (Yes. This is a bit paranoid...but so what)	*/	WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM);#if SBA_AGP_SUPPORT	/*	** If an AGP device is present, only use half of the IOV space	** for PCI DMA.  Unfortunately we can't know ahead of time	** whether GART support will actually be used, for now we	** can just key on any AGP device found in the system.	** We program the next pdir index after we stop w/ a key for	** the GART code to handshake on.	*/	device=NULL;	for (lba = sba->child; lba; lba = lba->sibling) {		if (IS_QUICKSILVER(lba))			break;	}	if (lba) {		DBG_INIT("%s: Reserving half of IOVA space for AGP GART support\n", __FUNCTION__);		ioc->pdir_size /= 2;		((u64 *)ioc->pdir_base)[PDIR_INDEX(iova_space_size/2)] = SBA_IOMMU_COOKIE;	} else {		DBG_INIT("%s: No GART needed - no AGP controller found\n", __FUNCTION__);	}#endif /* 0 */}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/64908ad95c34f25849412d6d4735ac10f8fb6575/sba_iommu.c/buggy/drivers/parisc/sba_iommu.c