Esempio n. 1
0
/*
 * Allocate "count" contiguous Bridge Address Translation Entries
 * on the specified bridge to be used for PCI to XTALK mappings.
 * Indices in rm map range from 1..num_entries.  Indicies returned
 * to caller range from 0..num_entries-1.
 *
 * Return the start index on success, -1 on failure.
 */
int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count)
{
	int status = 0;
	uint64_t flag;

	flag = pcibr_lock(pcibus_info);
	status = alloc_ate_resource(&pcibus_info->pbi_int_ate_resource, count);

	if (status < 0) {
		/* Failed to allocate */
		pcibr_unlock(pcibus_info, flag);
		return -1;
	}

	pcibr_unlock(pcibus_info, flag);

	return status;
}
Esempio n. 2
0
void pcibr_ate_free(struct pcibus_info *pcibus_info, int index)
{

	volatile uint64_t ate;
	int count;
	uint64_t flags;

	if (pcibr_invalidate_ate) {
		/* For debugging purposes, clear the valid bit in the ATE */
		ate = *pcibr_ate_addr(pcibus_info, index);
		count = pcibus_info->pbi_int_ate_resource.ate[index];
		ate_write(pcibus_info, index, count, (ate & ~PCI32_ATE_V));
	}

	flags = pcibr_lock(pcibus_info);
	free_ate_resource(&pcibus_info->pbi_int_ate_resource, index);
	pcibr_unlock(pcibus_info, flags);
}
Esempio n. 3
0
void
ate_thaw(pcibr_dmamap_t pcibr_dmamap,
	 int ate_index,
#if PCIBR_FREEZE_TIME
	 bridge_ate_t ate,
	 int ate_total,
	 unsigned freeze_time_start,
#endif
	 unsigned *cmd_regs,
	 unsigned s)
{
    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
    int                     dma_slot = pcibr_dmamap->bd_slot;
    int                     slot;
    bridge_t               *bridge = pcibr_soft->bs_base;
    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;

    unsigned                cmd_reg;

#if PCIBR_FREEZE_TIME
    unsigned                freeze_time;
    static unsigned         max_freeze_time = 0;
    static unsigned         max_ate_total;
#endif

    if (!ext_ates)
	return;

    /* restore cmd regs */
    for (slot = pcibr_soft->bs_min_slot; 
		slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
	if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER) {
		if ( IS_PIC_SOFT(pcibr_soft) ) {
			pcibr_slot_config_set(bridge, slot, PCI_CFG_COMMAND/4, cmd_reg);
		}
		else {
			if (io_get_sh_swapper(NASID_GET(bridge))) {
				bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = __swab32(cmd_reg);
			}
			else {
//				BUG(); /* Does this really work if called when io_get_sh_swapper = 0? */
//				bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg;
				pcibr_slot_config_set(bridge, slot, PCI_CFG_COMMAND/4, cmd_reg);
			}
		}
	}
    }
    pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY;
    atomic_inc(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));

#if PCIBR_FREEZE_TIME
    freeze_time = get_timestamp() - freeze_time_start;

    if ((max_freeze_time < freeze_time) ||
	(max_ate_total < ate_total)) {
	if (max_freeze_time < freeze_time)
	    max_freeze_time = freeze_time;
	if (max_ate_total < ate_total)
	    max_ate_total = ate_total;
	pcibr_unlock(pcibr_soft, s);
	printk( "%s: pci freeze time %d usec for %d ATEs\n"
		"\tfirst ate: %R\n",
		pcibr_soft->bs_name,
		freeze_time * 1000 / 1250,
		ate_total,
		ate, ate_bits);
    } else
#endif
	pcibr_unlock(pcibr_soft, s);
}