diff options
Diffstat (limited to 'arch/ia64/sn/pci/pcibr/pcibr_ate.c')
-rw-r--r-- | arch/ia64/sn/pci/pcibr/pcibr_ate.c | 177 |
1 files changed, 0 insertions, 177 deletions
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c deleted file mode 100644 index b67bb4cb73ff..000000000000 --- a/arch/ia64/sn/pci/pcibr/pcibr_ate.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001-2006 Silicon Graphics, Inc. All rights reserved. - */ - -#include <linux/types.h> -#include <asm/sn/sn_sal.h> -#include <asm/sn/pcibr_provider.h> -#include <asm/sn/pcibus_provider_defs.h> -#include <asm/sn/pcidev.h> - -int pcibr_invalidate_ate; /* by default don't invalidate ATE on free */ - -/* - * mark_ate: Mark the ate as either free or inuse. - */ -static void mark_ate(struct ate_resource *ate_resource, int start, int number, - u64 value) -{ - u64 *ate = ate_resource->ate; - int index; - int length = 0; - - for (index = start; length < number; index++, length++) - ate[index] = value; -} - -/* - * find_free_ate: Find the first free ate index starting from the given - * index for the desired consecutive count. - */ -static int find_free_ate(struct ate_resource *ate_resource, int start, - int count) -{ - u64 *ate = ate_resource->ate; - int index; - int start_free; - - for (index = start; index < ate_resource->num_ate;) { - if (!ate[index]) { - int i; - int free; - free = 0; - start_free = index; /* Found start free ate */ - for (i = start_free; i < ate_resource->num_ate; i++) { - if (!ate[i]) { /* This is free */ - if (++free == count) - return start_free; - } else { - index = i + 1; - break; - } - } - if (i >= ate_resource->num_ate) - return -1; - } else - index++; /* Try next ate */ - } - - return -1; -} - -/* - * free_ate_resource: Free the requested number of ATEs. - */ -static inline void free_ate_resource(struct ate_resource *ate_resource, - int start) -{ - mark_ate(ate_resource, start, ate_resource->ate[start], 0); - if ((ate_resource->lowest_free_index > start) || - (ate_resource->lowest_free_index < 0)) - ate_resource->lowest_free_index = start; -} - -/* - * alloc_ate_resource: Allocate the requested number of ATEs. - */ -static inline int alloc_ate_resource(struct ate_resource *ate_resource, - int ate_needed) -{ - int start_index; - - /* - * Check for ate exhaustion. - */ - if (ate_resource->lowest_free_index < 0) - return -1; - - /* - * Find the required number of free consecutive ates. - */ - start_index = - find_free_ate(ate_resource, ate_resource->lowest_free_index, - ate_needed); - if (start_index >= 0) - mark_ate(ate_resource, start_index, ate_needed, ate_needed); - - ate_resource->lowest_free_index = - find_free_ate(ate_resource, ate_resource->lowest_free_index, 1); - - return start_index; -} - -/* - * 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. Indices 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; - unsigned long flags; - - spin_lock_irqsave(&pcibus_info->pbi_lock, flags); - status = alloc_ate_resource(&pcibus_info->pbi_int_ate_resource, count); - spin_unlock_irqrestore(&pcibus_info->pbi_lock, flags); - - return status; -} - -/* - * Setup an Address Translation Entry as specified. Use either the Bridge - * internal maps or the external map RAM, as appropriate. - */ -static inline u64 __iomem *pcibr_ate_addr(struct pcibus_info *pcibus_info, - int ate_index) -{ - if (ate_index < pcibus_info->pbi_int_ate_size) { - return pcireg_int_ate_addr(pcibus_info, ate_index); - } - panic("pcibr_ate_addr: invalid ate_index 0x%x", ate_index); -} - -/* - * Update the ate. - */ -inline void -ate_write(struct pcibus_info *pcibus_info, int ate_index, int count, - volatile u64 ate) -{ - while (count-- > 0) { - if (ate_index < pcibus_info->pbi_int_ate_size) { - pcireg_int_ate_set(pcibus_info, ate_index, ate); - } else { - panic("ate_write: invalid ate_index 0x%x", ate_index); - } - ate_index++; - ate += IOPGSIZE; - } - - pcireg_tflush_get(pcibus_info); /* wait until Bridge PIO complete */ -} - -void pcibr_ate_free(struct pcibus_info *pcibus_info, int index) -{ - - volatile u64 ate; - int count; - unsigned long 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)); - } - - spin_lock_irqsave(&pcibus_info->pbi_lock, flags); - free_ate_resource(&pcibus_info->pbi_int_ate_resource, index); - spin_unlock_irqrestore(&pcibus_info->pbi_lock, flags); -} |