/* Set the status reg busy bit and transfer length */ BTE_PRINTKV(("IBLS = 0x%lx\n", IBLS_BUSY | transfer_size)); BTE_LNSTAT_STORE(bte, IBLS_BUSY | transfer_size);  
bte_result_t bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification){	u64 transfer_size;	u64 transfer_stat;	struct bteinfo_s *bte;	bte_result_t bte_status;	unsigned long irq_flags;	unsigned long itc_end = 0;	struct bteinfo_s *btes_to_try[MAX_INTERFACES_TO_TRY];	int bte_if_index;	int bte_pri, bte_sec;	BTE_PRINTK(("bte_copy(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%p)\n",		    src, dest, len, mode, notification));	if (len == 0) {		return BTE_SUCCESS;	}	BUG_ON((len & L1_CACHE_MASK) ||		 (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK));	BUG_ON(!(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT)));	/* CPU 0 (per node) tries bte0 first, CPU 1 try bte1 first */	if (cpuid_to_subnode(smp_processor_id()) == 0) {		bte_pri = 0;		bte_sec = 1;	} else {		bte_pri = 1;		bte_sec = 0;	}	if (mode & BTE_USE_DEST) {		/* try remote then local */		btes_to_try[0] = bte_if_on_node(NASID_GET(dest), bte_pri);		btes_to_try[1] = bte_if_on_node(NASID_GET(dest), bte_sec);		if (mode & BTE_USE_ANY) {			btes_to_try[2] = bte_if_on_node(get_nasid(), bte_pri);			btes_to_try[3] = bte_if_on_node(get_nasid(), bte_sec);		} else {			btes_to_try[2] = NULL;			btes_to_try[3] = NULL;		}	} else {		/* try local then remote */		btes_to_try[0] = bte_if_on_node(get_nasid(), bte_pri);		btes_to_try[1] = bte_if_on_node(get_nasid(), bte_sec);		if (mode & BTE_USE_ANY) {			btes_to_try[2] = bte_if_on_node(NASID_GET(dest), bte_pri);			btes_to_try[3] = bte_if_on_node(NASID_GET(dest), bte_sec);		} else {			btes_to_try[2] = NULL;			btes_to_try[3] = NULL;		}	}retry_bteop:	do {		local_irq_save(irq_flags);		bte_if_index = 0;		/* Attempt to lock one of the BTE interfaces. */		while (bte_if_index < MAX_INTERFACES_TO_TRY) {			bte = btes_to_try[bte_if_index++];			if (bte == NULL) {				continue;			}			if (spin_trylock(&bte->spinlock)) {				if (!(*bte->most_rcnt_na & BTE_WORD_AVAILABLE) ||				    (BTE_LNSTAT_LOAD(bte) & BTE_ACTIVE)) {					/* Got the lock but BTE still busy */					spin_unlock(&bte->spinlock);				} else {					/* we got the lock and it's not busy */					break;				}			}			bte = NULL;		}		if (bte != NULL) {			break;		}		local_irq_restore(irq_flags);		if (!(mode & BTE_WACQUIRE)) {			return BTEFAIL_NOTAVAIL;		}	} while (1);	if (notification == NULL) {		/* User does not want to be notified. */		bte->most_rcnt_na = &bte->notify;	} else {		bte->most_rcnt_na = notification;	}	/* Calculate the number of cache lines to transfer. */	transfer_size = ((len >> L1_CACHE_SHIFT) & BTE_LEN_MASK);	/* Initialize the notification to a known value. */	*bte->most_rcnt_na = BTE_WORD_BUSY;	/* Set the status reg busy bit and transfer length */	BTE_PRINTKV(("IBLS = 0x%lx\n", IBLS_BUSY | transfer_size));	BTE_LNSTAT_STORE(bte, IBLS_BUSY | transfer_size);	/* Set the source and destination registers */	BTE_PRINTKV(("IBSA = 0x%lx)\n", (TO_PHYS(src))));	BTE_SRC_STORE(bte, TO_PHYS(src));	BTE_PRINTKV(("IBDA = 0x%lx)\n", (TO_PHYS(dest))));	BTE_DEST_STORE(bte, TO_PHYS(dest));	/* Set the notification register */	BTE_PRINTKV(("IBNA = 0x%lx)\n",		     TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na))));	BTE_NOTIF_STORE(bte,			TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na)));	/* Initiate the transfer */	BTE_PRINTK(("IBCT = 0x%lx)\n", BTE_VALID_MODE(mode)));	BTE_CTRL_STORE(bte, BTE_VALID_MODE(mode));	itc_end = ia64_get_itc() + (40000000 * local_cpu_data->cyc_per_usec);	spin_unlock_irqrestore(&bte->spinlock, irq_flags);	if (notification != NULL) {		return BTE_SUCCESS;	}	while ((transfer_stat = *bte->most_rcnt_na) == BTE_WORD_BUSY) {		if (ia64_get_itc() > itc_end) {			BTE_PRINTK(("BTE timeout nasid 0x%x bte%d IBLS = 0x%lx na 0x%lx\n",				NASID_GET(bte->bte_base_addr), bte->bte_num,				BTE_LNSTAT_LOAD(bte), *bte->most_rcnt_na) );			bte->bte_error_count++;			bte->bh_error = IBLS_ERROR;			bte_error_handler((unsigned long)NODEPDA(bte->bte_cnode));			*bte->most_rcnt_na = BTE_WORD_AVAILABLE;			goto retry_bteop;		}	}	BTE_PRINTKV((" Delay Done.  IBLS = 0x%lx, most_rcnt_na = 0x%lx\n",		     BTE_LNSTAT_LOAD(bte), *bte->most_rcnt_na));	if (transfer_stat & IBLS_ERROR) {		bte_status = transfer_stat & ~IBLS_ERROR;	} else {		bte_status = BTE_SUCCESS;	}	*bte->most_rcnt_na = BTE_WORD_AVAILABLE;	BTE_PRINTK(("Returning status is 0x%lx and most_rcnt_na is 0x%lx\n",		    BTE_LNSTAT_LOAD(bte), *bte->most_rcnt_na));	return bte_status;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/95ff439a517835aa2bdf725fafbb025a63984289/bte.c/clean/arch/ia64/sn/kernel/bte.c