Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 28577
b: refs/heads/master
c: 83821d3
h: refs/heads/master
i:
  28575: f4422a4
v: v3
  • Loading branch information
Mark Maule authored and Greg Kroah-Hartman committed Jun 21, 2006
1 parent 459b983 commit 3cf1278
Show file tree
Hide file tree
Showing 12 changed files with 402 additions and 122 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 10083072bfabc40bc47306e512c158c57cf55c2e
refs/heads/master: 83821d3f558dc651e555d62182ed0c95651f41a6
9 changes: 1 addition & 8 deletions trunk/arch/ia64/sn/kernel/io_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ static int max_pcibus_number = 255; /* Default highest pci bus number */
*/

static dma_addr_t
sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size)
sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type)
{
return 0;
}
Expand Down Expand Up @@ -457,13 +457,6 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
pcidev_info->pdi_sn_irq_info = NULL;
kfree(sn_irq_info);
}

/*
* MSI currently not supported on altix. Remove this when
* the MSI abstraction patches are integrated into the kernel
* (sometime after 2.6.16 releases)
*/
dev->no_msi = 1;
}

/*
Expand Down
135 changes: 77 additions & 58 deletions trunk/arch/ia64/sn/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info);

int sn_force_interrupt_flag = 1;
extern int sn_ioif_inited;
static struct list_head **sn_irq_lh;
struct list_head **sn_irq_lh;
static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */

static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget,
u64 sn_irq_info,
u64 sn_intr_alloc(nasid_t local_nasid, int local_widget,
struct sn_irq_info *sn_irq_info,
int req_irq, nasid_t req_nasid,
int req_slice)
{
Expand All @@ -40,12 +40,13 @@ static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget,

SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT,
(u64) SAL_INTR_ALLOC, (u64) local_nasid,
(u64) local_widget, (u64) sn_irq_info, (u64) req_irq,
(u64) local_widget, __pa(sn_irq_info), (u64) req_irq,
(u64) req_nasid, (u64) req_slice);

return ret_stuff.status;
}

static inline void sn_intr_free(nasid_t local_nasid, int local_widget,
void sn_intr_free(nasid_t local_nasid, int local_widget,
struct sn_irq_info *sn_irq_info)
{
struct ia64_sal_retval ret_stuff;
Expand Down Expand Up @@ -112,73 +113,91 @@ static void sn_end_irq(unsigned int irq)

static void sn_irq_info_free(struct rcu_head *head);

static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info,
nasid_t nasid, int slice)
{
struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
int cpuid, cpuphys;
int vector;
int cpuphys;
int64_t bridge;
int local_widget, status;
nasid_t local_nasid;
struct sn_irq_info *new_irq_info;
struct sn_pcibus_provider *pci_provider;

cpuid = first_cpu(mask);
cpuphys = cpu_physical_id(cpuid);
new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC);
if (new_irq_info == NULL)
return NULL;

list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
sn_irq_lh[irq], list) {
u64 bridge;
int local_widget, status;
nasid_t local_nasid;
struct sn_irq_info *new_irq_info;
struct sn_pcibus_provider *pci_provider;

new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC);
if (new_irq_info == NULL)
break;
memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info));

bridge = (u64) new_irq_info->irq_bridge;
if (!bridge) {
kfree(new_irq_info);
break; /* irq is not a device interrupt */
}
memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info));

local_nasid = NASID_GET(bridge);
bridge = (u64) new_irq_info->irq_bridge;
if (!bridge) {
kfree(new_irq_info);
return NULL; /* irq is not a device interrupt */
}

if (local_nasid & 1)
local_widget = TIO_SWIN_WIDGETNUM(bridge);
else
local_widget = SWIN_WIDGETNUM(bridge);
local_nasid = NASID_GET(bridge);

/* Free the old PROM new_irq_info structure */
sn_intr_free(local_nasid, local_widget, new_irq_info);
/* Update kernels new_irq_info with new target info */
unregister_intr_pda(new_irq_info);
if (local_nasid & 1)
local_widget = TIO_SWIN_WIDGETNUM(bridge);
else
local_widget = SWIN_WIDGETNUM(bridge);

/* allocate a new PROM new_irq_info struct */
status = sn_intr_alloc(local_nasid, local_widget,
__pa(new_irq_info), irq,
cpuid_to_nasid(cpuid),
cpuid_to_slice(cpuid));
vector = sn_irq_info->irq_irq;
/* Free the old PROM new_irq_info structure */
sn_intr_free(local_nasid, local_widget, new_irq_info);
/* Update kernels new_irq_info with new target info */
unregister_intr_pda(new_irq_info);

/* SAL call failed */
if (status) {
kfree(new_irq_info);
break;
}
/* allocate a new PROM new_irq_info struct */
status = sn_intr_alloc(local_nasid, local_widget,
new_irq_info, vector,
nasid, slice);

/* SAL call failed */
if (status) {
kfree(new_irq_info);
return NULL;
}

new_irq_info->irq_cpuid = cpuid;
register_intr_pda(new_irq_info);
cpuphys = nasid_slice_to_cpuid(nasid, slice);
new_irq_info->irq_cpuid = cpuphys;
register_intr_pda(new_irq_info);

pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type];
if (pci_provider && pci_provider->target_interrupt)
(pci_provider->target_interrupt)(new_irq_info);
pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type];

/*
* If this represents a line interrupt, target it. If it's
* an msi (irq_int_bit < 0), it's already targeted.
*/
if (new_irq_info->irq_int_bit >= 0 &&
pci_provider && pci_provider->target_interrupt)
(pci_provider->target_interrupt)(new_irq_info);

spin_lock(&sn_irq_info_lock);
list_replace_rcu(&sn_irq_info->list, &new_irq_info->list);
spin_unlock(&sn_irq_info_lock);
call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
spin_lock(&sn_irq_info_lock);
list_replace_rcu(&sn_irq_info->list, &new_irq_info->list);
spin_unlock(&sn_irq_info_lock);
call_rcu(&sn_irq_info->rcu, sn_irq_info_free);

#ifdef CONFIG_SMP
set_irq_affinity_info((irq & 0xff), cpuphys, 0);
set_irq_affinity_info((vector & 0xff), cpuphys, 0);
#endif
}

return new_irq_info;
}

static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
{
struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
nasid_t nasid;
int slice;

nasid = cpuid_to_nasid(first_cpu(mask));
slice = cpuid_to_slice(first_cpu(mask));

list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
sn_irq_lh[irq], list)
(void)sn_retarget_vector(sn_irq_info, nasid, slice);
}

struct hw_interrupt_type irq_type_sn = {
Expand Down
10 changes: 6 additions & 4 deletions trunk/arch/ia64/sn/pci/pci_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#include <linux/module.h>
#include <asm/dma.h>
#include <asm/sn/pcibr_provider.h>
#include <asm/sn/intr.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
#include <asm/sn/sn_sal.h>
Expand Down Expand Up @@ -113,7 +113,8 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size,
* resources.
*/

*dma_handle = provider->dma_map_consistent(pdev, phys_addr, size);
*dma_handle = provider->dma_map_consistent(pdev, phys_addr, size,
SN_DMA_ADDR_PHYS);
if (!*dma_handle) {
printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__);
free_pages((unsigned long)cpuaddr, get_order(size));
Expand Down Expand Up @@ -176,7 +177,7 @@ dma_addr_t sn_dma_map_single(struct device *dev, void *cpu_addr, size_t size,
BUG_ON(dev->bus != &pci_bus_type);

phys_addr = __pa(cpu_addr);
dma_addr = provider->dma_map(pdev, phys_addr, size);
dma_addr = provider->dma_map(pdev, phys_addr, size, SN_DMA_ADDR_PHYS);
if (!dma_addr) {
printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__);
return 0;
Expand Down Expand Up @@ -260,7 +261,8 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
for (i = 0; i < nhwentries; i++, sg++) {
phys_addr = SG_ENT_PHYS_ADDRESS(sg);
sg->dma_address = provider->dma_map(pdev,
phys_addr, sg->length);
phys_addr, sg->length,
SN_DMA_ADDR_PHYS);

if (!sg->dma_address) {
printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__);
Expand Down
Loading

0 comments on commit 3cf1278

Please sign in to comment.