ia64/linux-2.6.18-xen.hg

annotate arch/alpha/kernel/sys_dp264.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 * linux/arch/alpha/kernel/sys_dp264.c
ian@0 3 *
ian@0 4 * Copyright (C) 1995 David A Rusling
ian@0 5 * Copyright (C) 1996, 1999 Jay A Estabrook
ian@0 6 * Copyright (C) 1998, 1999 Richard Henderson
ian@0 7 *
ian@0 8 * Modified by Christopher C. Chimelis, 2001 to
ian@0 9 * add support for the addition of Shark to the
ian@0 10 * Tsunami family.
ian@0 11 *
ian@0 12 * Code supporting the DP264 (EV6+TSUNAMI).
ian@0 13 */
ian@0 14
ian@0 15 #include <linux/kernel.h>
ian@0 16 #include <linux/types.h>
ian@0 17 #include <linux/mm.h>
ian@0 18 #include <linux/sched.h>
ian@0 19 #include <linux/pci.h>
ian@0 20 #include <linux/init.h>
ian@0 21 #include <linux/bitops.h>
ian@0 22
ian@0 23 #include <asm/ptrace.h>
ian@0 24 #include <asm/system.h>
ian@0 25 #include <asm/dma.h>
ian@0 26 #include <asm/irq.h>
ian@0 27 #include <asm/mmu_context.h>
ian@0 28 #include <asm/io.h>
ian@0 29 #include <asm/pgtable.h>
ian@0 30 #include <asm/core_tsunami.h>
ian@0 31 #include <asm/hwrpb.h>
ian@0 32 #include <asm/tlbflush.h>
ian@0 33
ian@0 34 #include "proto.h"
ian@0 35 #include "irq_impl.h"
ian@0 36 #include "pci_impl.h"
ian@0 37 #include "machvec_impl.h"
ian@0 38
ian@0 39
ian@0 40 /* Note mask bit is true for ENABLED irqs. */
ian@0 41 static unsigned long cached_irq_mask;
ian@0 42 /* dp264 boards handle at max four CPUs */
ian@0 43 static unsigned long cpu_irq_affinity[4] = { 0UL, 0UL, 0UL, 0UL };
ian@0 44
ian@0 45 DEFINE_SPINLOCK(dp264_irq_lock);
ian@0 46
ian@0 47 static void
ian@0 48 tsunami_update_irq_hw(unsigned long mask)
ian@0 49 {
ian@0 50 register tsunami_cchip *cchip = TSUNAMI_cchip;
ian@0 51 unsigned long isa_enable = 1UL << 55;
ian@0 52 register int bcpu = boot_cpuid;
ian@0 53
ian@0 54 #ifdef CONFIG_SMP
ian@0 55 volatile unsigned long *dim0, *dim1, *dim2, *dim3;
ian@0 56 unsigned long mask0, mask1, mask2, mask3, dummy;
ian@0 57
ian@0 58 mask &= ~isa_enable;
ian@0 59 mask0 = mask & cpu_irq_affinity[0];
ian@0 60 mask1 = mask & cpu_irq_affinity[1];
ian@0 61 mask2 = mask & cpu_irq_affinity[2];
ian@0 62 mask3 = mask & cpu_irq_affinity[3];
ian@0 63
ian@0 64 if (bcpu == 0) mask0 |= isa_enable;
ian@0 65 else if (bcpu == 1) mask1 |= isa_enable;
ian@0 66 else if (bcpu == 2) mask2 |= isa_enable;
ian@0 67 else mask3 |= isa_enable;
ian@0 68
ian@0 69 dim0 = &cchip->dim0.csr;
ian@0 70 dim1 = &cchip->dim1.csr;
ian@0 71 dim2 = &cchip->dim2.csr;
ian@0 72 dim3 = &cchip->dim3.csr;
ian@0 73 if (!cpu_possible(0)) dim0 = &dummy;
ian@0 74 if (!cpu_possible(1)) dim1 = &dummy;
ian@0 75 if (!cpu_possible(2)) dim2 = &dummy;
ian@0 76 if (!cpu_possible(3)) dim3 = &dummy;
ian@0 77
ian@0 78 *dim0 = mask0;
ian@0 79 *dim1 = mask1;
ian@0 80 *dim2 = mask2;
ian@0 81 *dim3 = mask3;
ian@0 82 mb();
ian@0 83 *dim0;
ian@0 84 *dim1;
ian@0 85 *dim2;
ian@0 86 *dim3;
ian@0 87 #else
ian@0 88 volatile unsigned long *dimB;
ian@0 89 if (bcpu == 0) dimB = &cchip->dim0.csr;
ian@0 90 else if (bcpu == 1) dimB = &cchip->dim1.csr;
ian@0 91 else if (bcpu == 2) dimB = &cchip->dim2.csr;
ian@0 92 else dimB = &cchip->dim3.csr;
ian@0 93
ian@0 94 *dimB = mask | isa_enable;
ian@0 95 mb();
ian@0 96 *dimB;
ian@0 97 #endif
ian@0 98 }
ian@0 99
ian@0 100 static void
ian@0 101 dp264_enable_irq(unsigned int irq)
ian@0 102 {
ian@0 103 spin_lock(&dp264_irq_lock);
ian@0 104 cached_irq_mask |= 1UL << irq;
ian@0 105 tsunami_update_irq_hw(cached_irq_mask);
ian@0 106 spin_unlock(&dp264_irq_lock);
ian@0 107 }
ian@0 108
ian@0 109 static void
ian@0 110 dp264_disable_irq(unsigned int irq)
ian@0 111 {
ian@0 112 spin_lock(&dp264_irq_lock);
ian@0 113 cached_irq_mask &= ~(1UL << irq);
ian@0 114 tsunami_update_irq_hw(cached_irq_mask);
ian@0 115 spin_unlock(&dp264_irq_lock);
ian@0 116 }
ian@0 117
ian@0 118 static unsigned int
ian@0 119 dp264_startup_irq(unsigned int irq)
ian@0 120 {
ian@0 121 dp264_enable_irq(irq);
ian@0 122 return 0; /* never anything pending */
ian@0 123 }
ian@0 124
ian@0 125 static void
ian@0 126 dp264_end_irq(unsigned int irq)
ian@0 127 {
ian@0 128 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
ian@0 129 dp264_enable_irq(irq);
ian@0 130 }
ian@0 131
ian@0 132 static void
ian@0 133 clipper_enable_irq(unsigned int irq)
ian@0 134 {
ian@0 135 spin_lock(&dp264_irq_lock);
ian@0 136 cached_irq_mask |= 1UL << (irq - 16);
ian@0 137 tsunami_update_irq_hw(cached_irq_mask);
ian@0 138 spin_unlock(&dp264_irq_lock);
ian@0 139 }
ian@0 140
ian@0 141 static void
ian@0 142 clipper_disable_irq(unsigned int irq)
ian@0 143 {
ian@0 144 spin_lock(&dp264_irq_lock);
ian@0 145 cached_irq_mask &= ~(1UL << (irq - 16));
ian@0 146 tsunami_update_irq_hw(cached_irq_mask);
ian@0 147 spin_unlock(&dp264_irq_lock);
ian@0 148 }
ian@0 149
ian@0 150 static unsigned int
ian@0 151 clipper_startup_irq(unsigned int irq)
ian@0 152 {
ian@0 153 clipper_enable_irq(irq);
ian@0 154 return 0; /* never anything pending */
ian@0 155 }
ian@0 156
ian@0 157 static void
ian@0 158 clipper_end_irq(unsigned int irq)
ian@0 159 {
ian@0 160 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
ian@0 161 clipper_enable_irq(irq);
ian@0 162 }
ian@0 163
ian@0 164 static void
ian@0 165 cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
ian@0 166 {
ian@0 167 int cpu;
ian@0 168
ian@0 169 for (cpu = 0; cpu < 4; cpu++) {
ian@0 170 unsigned long aff = cpu_irq_affinity[cpu];
ian@0 171 if (cpu_isset(cpu, affinity))
ian@0 172 aff |= 1UL << irq;
ian@0 173 else
ian@0 174 aff &= ~(1UL << irq);
ian@0 175 cpu_irq_affinity[cpu] = aff;
ian@0 176 }
ian@0 177 }
ian@0 178
ian@0 179 static void
ian@0 180 dp264_set_affinity(unsigned int irq, cpumask_t affinity)
ian@0 181 {
ian@0 182 spin_lock(&dp264_irq_lock);
ian@0 183 cpu_set_irq_affinity(irq, affinity);
ian@0 184 tsunami_update_irq_hw(cached_irq_mask);
ian@0 185 spin_unlock(&dp264_irq_lock);
ian@0 186 }
ian@0 187
ian@0 188 static void
ian@0 189 clipper_set_affinity(unsigned int irq, cpumask_t affinity)
ian@0 190 {
ian@0 191 spin_lock(&dp264_irq_lock);
ian@0 192 cpu_set_irq_affinity(irq - 16, affinity);
ian@0 193 tsunami_update_irq_hw(cached_irq_mask);
ian@0 194 spin_unlock(&dp264_irq_lock);
ian@0 195 }
ian@0 196
ian@0 197 static struct hw_interrupt_type dp264_irq_type = {
ian@0 198 .typename = "DP264",
ian@0 199 .startup = dp264_startup_irq,
ian@0 200 .shutdown = dp264_disable_irq,
ian@0 201 .enable = dp264_enable_irq,
ian@0 202 .disable = dp264_disable_irq,
ian@0 203 .ack = dp264_disable_irq,
ian@0 204 .end = dp264_end_irq,
ian@0 205 .set_affinity = dp264_set_affinity,
ian@0 206 };
ian@0 207
ian@0 208 static struct hw_interrupt_type clipper_irq_type = {
ian@0 209 .typename = "CLIPPER",
ian@0 210 .startup = clipper_startup_irq,
ian@0 211 .shutdown = clipper_disable_irq,
ian@0 212 .enable = clipper_enable_irq,
ian@0 213 .disable = clipper_disable_irq,
ian@0 214 .ack = clipper_disable_irq,
ian@0 215 .end = clipper_end_irq,
ian@0 216 .set_affinity = clipper_set_affinity,
ian@0 217 };
ian@0 218
ian@0 219 static void
ian@0 220 dp264_device_interrupt(unsigned long vector, struct pt_regs * regs)
ian@0 221 {
ian@0 222 #if 1
ian@0 223 printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n");
ian@0 224 #else
ian@0 225 unsigned long pld;
ian@0 226 unsigned int i;
ian@0 227
ian@0 228 /* Read the interrupt summary register of TSUNAMI */
ian@0 229 pld = TSUNAMI_cchip->dir0.csr;
ian@0 230
ian@0 231 /*
ian@0 232 * Now for every possible bit set, work through them and call
ian@0 233 * the appropriate interrupt handler.
ian@0 234 */
ian@0 235 while (pld) {
ian@0 236 i = ffz(~pld);
ian@0 237 pld &= pld - 1; /* clear least bit set */
ian@0 238 if (i == 55)
ian@0 239 isa_device_interrupt(vector, regs);
ian@0 240 else
ian@0 241 handle_irq(16 + i, 16 + i, regs);
ian@0 242 #if 0
ian@0 243 TSUNAMI_cchip->dir0.csr = 1UL << i; mb();
ian@0 244 tmp = TSUNAMI_cchip->dir0.csr;
ian@0 245 #endif
ian@0 246 }
ian@0 247 #endif
ian@0 248 }
ian@0 249
ian@0 250 static void
ian@0 251 dp264_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
ian@0 252 {
ian@0 253 int irq;
ian@0 254
ian@0 255 irq = (vector - 0x800) >> 4;
ian@0 256
ian@0 257 /*
ian@0 258 * The SRM console reports PCI interrupts with a vector calculated by:
ian@0 259 *
ian@0 260 * 0x900 + (0x10 * DRIR-bit)
ian@0 261 *
ian@0 262 * So bit 16 shows up as IRQ 32, etc.
ian@0 263 *
ian@0 264 * On DP264/BRICK/MONET, we adjust it down by 16 because at least
ian@0 265 * that many of the low order bits of the DRIR are not used, and
ian@0 266 * so we don't count them.
ian@0 267 */
ian@0 268 if (irq >= 32)
ian@0 269 irq -= 16;
ian@0 270
ian@0 271 handle_irq(irq, regs);
ian@0 272 }
ian@0 273
ian@0 274 static void
ian@0 275 clipper_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
ian@0 276 {
ian@0 277 int irq;
ian@0 278
ian@0 279 irq = (vector - 0x800) >> 4;
ian@0 280
ian@0 281 /*
ian@0 282 * The SRM console reports PCI interrupts with a vector calculated by:
ian@0 283 *
ian@0 284 * 0x900 + (0x10 * DRIR-bit)
ian@0 285 *
ian@0 286 * So bit 16 shows up as IRQ 32, etc.
ian@0 287 *
ian@0 288 * CLIPPER uses bits 8-47 for PCI interrupts, so we do not need
ian@0 289 * to scale down the vector reported, we just use it.
ian@0 290 *
ian@0 291 * Eg IRQ 24 is DRIR bit 8, etc, etc
ian@0 292 */
ian@0 293 handle_irq(irq, regs);
ian@0 294 }
ian@0 295
ian@0 296 static void __init
ian@0 297 init_tsunami_irqs(struct hw_interrupt_type * ops, int imin, int imax)
ian@0 298 {
ian@0 299 long i;
ian@0 300 for (i = imin; i <= imax; ++i) {
ian@0 301 irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
ian@0 302 irq_desc[i].chip = ops;
ian@0 303 }
ian@0 304 }
ian@0 305
ian@0 306 static void __init
ian@0 307 dp264_init_irq(void)
ian@0 308 {
ian@0 309 outb(0, DMA1_RESET_REG);
ian@0 310 outb(0, DMA2_RESET_REG);
ian@0 311 outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
ian@0 312 outb(0, DMA2_MASK_REG);
ian@0 313
ian@0 314 if (alpha_using_srm)
ian@0 315 alpha_mv.device_interrupt = dp264_srm_device_interrupt;
ian@0 316
ian@0 317 tsunami_update_irq_hw(0);
ian@0 318
ian@0 319 init_i8259a_irqs();
ian@0 320 init_tsunami_irqs(&dp264_irq_type, 16, 47);
ian@0 321 }
ian@0 322
ian@0 323 static void __init
ian@0 324 clipper_init_irq(void)
ian@0 325 {
ian@0 326 outb(0, DMA1_RESET_REG);
ian@0 327 outb(0, DMA2_RESET_REG);
ian@0 328 outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
ian@0 329 outb(0, DMA2_MASK_REG);
ian@0 330
ian@0 331 if (alpha_using_srm)
ian@0 332 alpha_mv.device_interrupt = clipper_srm_device_interrupt;
ian@0 333
ian@0 334 tsunami_update_irq_hw(0);
ian@0 335
ian@0 336 init_i8259a_irqs();
ian@0 337 init_tsunami_irqs(&clipper_irq_type, 24, 63);
ian@0 338 }
ian@0 339
ian@0 340
ian@0 341 /*
ian@0 342 * PCI Fixup configuration.
ian@0 343 *
ian@0 344 * Summary @ TSUNAMI_CSR_DIM0:
ian@0 345 * Bit Meaning
ian@0 346 * 0-17 Unused
ian@0 347 *18 Interrupt SCSI B (Adaptec 7895 builtin)
ian@0 348 *19 Interrupt SCSI A (Adaptec 7895 builtin)
ian@0 349 *20 Interrupt Line D from slot 2 PCI0
ian@0 350 *21 Interrupt Line C from slot 2 PCI0
ian@0 351 *22 Interrupt Line B from slot 2 PCI0
ian@0 352 *23 Interrupt Line A from slot 2 PCI0
ian@0 353 *24 Interrupt Line D from slot 1 PCI0
ian@0 354 *25 Interrupt Line C from slot 1 PCI0
ian@0 355 *26 Interrupt Line B from slot 1 PCI0
ian@0 356 *27 Interrupt Line A from slot 1 PCI0
ian@0 357 *28 Interrupt Line D from slot 0 PCI0
ian@0 358 *29 Interrupt Line C from slot 0 PCI0
ian@0 359 *30 Interrupt Line B from slot 0 PCI0
ian@0 360 *31 Interrupt Line A from slot 0 PCI0
ian@0 361 *
ian@0 362 *32 Interrupt Line D from slot 3 PCI1
ian@0 363 *33 Interrupt Line C from slot 3 PCI1
ian@0 364 *34 Interrupt Line B from slot 3 PCI1
ian@0 365 *35 Interrupt Line A from slot 3 PCI1
ian@0 366 *36 Interrupt Line D from slot 2 PCI1
ian@0 367 *37 Interrupt Line C from slot 2 PCI1
ian@0 368 *38 Interrupt Line B from slot 2 PCI1
ian@0 369 *39 Interrupt Line A from slot 2 PCI1
ian@0 370 *40 Interrupt Line D from slot 1 PCI1
ian@0 371 *41 Interrupt Line C from slot 1 PCI1
ian@0 372 *42 Interrupt Line B from slot 1 PCI1
ian@0 373 *43 Interrupt Line A from slot 1 PCI1
ian@0 374 *44 Interrupt Line D from slot 0 PCI1
ian@0 375 *45 Interrupt Line C from slot 0 PCI1
ian@0 376 *46 Interrupt Line B from slot 0 PCI1
ian@0 377 *47 Interrupt Line A from slot 0 PCI1
ian@0 378 *48-52 Unused
ian@0 379 *53 PCI0 NMI (from Cypress)
ian@0 380 *54 PCI0 SMI INT (from Cypress)
ian@0 381 *55 PCI0 ISA Interrupt (from Cypress)
ian@0 382 *56-60 Unused
ian@0 383 *61 PCI1 Bus Error
ian@0 384 *62 PCI0 Bus Error
ian@0 385 *63 Reserved
ian@0 386 *
ian@0 387 * IdSel
ian@0 388 * 5 Cypress Bridge I/O
ian@0 389 * 6 SCSI Adaptec builtin
ian@0 390 * 7 64 bit PCI option slot 0 (all busses)
ian@0 391 * 8 64 bit PCI option slot 1 (all busses)
ian@0 392 * 9 64 bit PCI option slot 2 (all busses)
ian@0 393 * 10 64 bit PCI option slot 3 (not bus 0)
ian@0 394 */
ian@0 395
ian@0 396 static int __init
ian@0 397 isa_irq_fixup(struct pci_dev *dev, int irq)
ian@0 398 {
ian@0 399 u8 irq8;
ian@0 400
ian@0 401 if (irq > 0)
ian@0 402 return irq;
ian@0 403
ian@0 404 /* This interrupt is routed via ISA bridge, so we'll
ian@0 405 just have to trust whatever value the console might
ian@0 406 have assigned. */
ian@0 407 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
ian@0 408
ian@0 409 return irq8 & 0xf;
ian@0 410 }
ian@0 411
ian@0 412 static int __init
ian@0 413 dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
ian@0 414 {
ian@0 415 static char irq_tab[6][5] __initdata = {
ian@0 416 /*INT INTA INTB INTC INTD */
ian@0 417 { -1, -1, -1, -1, -1}, /* IdSel 5 ISA Bridge */
ian@0 418 { 16+ 3, 16+ 3, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/
ian@0 419 { 16+15, 16+15, 16+14, 16+13, 16+12}, /* IdSel 7 slot 0 */
ian@0 420 { 16+11, 16+11, 16+10, 16+ 9, 16+ 8}, /* IdSel 8 slot 1 */
ian@0 421 { 16+ 7, 16+ 7, 16+ 6, 16+ 5, 16+ 4}, /* IdSel 9 slot 2 */
ian@0 422 { 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0} /* IdSel 10 slot 3 */
ian@0 423 };
ian@0 424 const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
ian@0 425 struct pci_controller *hose = dev->sysdata;
ian@0 426 int irq = COMMON_TABLE_LOOKUP;
ian@0 427
ian@0 428 if (irq > 0)
ian@0 429 irq += 16 * hose->index;
ian@0 430
ian@0 431 return isa_irq_fixup(dev, irq);
ian@0 432 }
ian@0 433
ian@0 434 static int __init
ian@0 435 monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
ian@0 436 {
ian@0 437 static char irq_tab[13][5] __initdata = {
ian@0 438 /*INT INTA INTB INTC INTD */
ian@0 439 { 45, 45, 45, 45, 45}, /* IdSel 3 21143 PCI1 */
ian@0 440 { -1, -1, -1, -1, -1}, /* IdSel 4 unused */
ian@0 441 { -1, -1, -1, -1, -1}, /* IdSel 5 unused */
ian@0 442 { 47, 47, 47, 47, 47}, /* IdSel 6 SCSI PCI1 */
ian@0 443 { -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */
ian@0 444 { -1, -1, -1, -1, -1}, /* IdSel 8 P2P PCI1 */
ian@0 445 #if 1
ian@0 446 { 28, 28, 29, 30, 31}, /* IdSel 14 slot 4 PCI2*/
ian@0 447 { 24, 24, 25, 26, 27}, /* IdSel 15 slot 5 PCI2*/
ian@0 448 #else
ian@0 449 { -1, -1, -1, -1, -1}, /* IdSel 9 unused */
ian@0 450 { -1, -1, -1, -1, -1}, /* IdSel 10 unused */
ian@0 451 #endif
ian@0 452 { 40, 40, 41, 42, 43}, /* IdSel 11 slot 1 PCI0*/
ian@0 453 { 36, 36, 37, 38, 39}, /* IdSel 12 slot 2 PCI0*/
ian@0 454 { 32, 32, 33, 34, 35}, /* IdSel 13 slot 3 PCI0*/
ian@0 455 { 28, 28, 29, 30, 31}, /* IdSel 14 slot 4 PCI2*/
ian@0 456 { 24, 24, 25, 26, 27} /* IdSel 15 slot 5 PCI2*/
ian@0 457 };
ian@0 458 const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5;
ian@0 459
ian@0 460 return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
ian@0 461 }
ian@0 462
ian@0 463 static u8 __init
ian@0 464 monet_swizzle(struct pci_dev *dev, u8 *pinp)
ian@0 465 {
ian@0 466 struct pci_controller *hose = dev->sysdata;
ian@0 467 int slot, pin = *pinp;
ian@0 468
ian@0 469 if (!dev->bus->parent) {
ian@0 470 slot = PCI_SLOT(dev->devfn);
ian@0 471 }
ian@0 472 /* Check for the built-in bridge on hose 1. */
ian@0 473 else if (hose->index == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) {
ian@0 474 slot = PCI_SLOT(dev->devfn);
ian@0 475 } else {
ian@0 476 /* Must be a card-based bridge. */
ian@0 477 do {
ian@0 478 /* Check for built-in bridge on hose 1. */
ian@0 479 if (hose->index == 1 &&
ian@0 480 PCI_SLOT(dev->bus->self->devfn) == 8) {
ian@0 481 slot = PCI_SLOT(dev->devfn);
ian@0 482 break;
ian@0 483 }
ian@0 484 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)) ;
ian@0 485
ian@0 486 /* Move up the chain of bridges. */
ian@0 487 dev = dev->bus->self;
ian@0 488 /* Slot of the next bridge. */
ian@0 489 slot = PCI_SLOT(dev->devfn);
ian@0 490 } while (dev->bus->self);
ian@0 491 }
ian@0 492 *pinp = pin;
ian@0 493 return slot;
ian@0 494 }
ian@0 495
ian@0 496 static int __init
ian@0 497 webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
ian@0 498 {
ian@0 499 static char irq_tab[13][5] __initdata = {
ian@0 500 /*INT INTA INTB INTC INTD */
ian@0 501 { -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */
ian@0 502 { -1, -1, -1, -1, -1}, /* IdSel 8 unused */
ian@0 503 { 29, 29, 29, 29, 29}, /* IdSel 9 21143 #1 */
ian@0 504 { -1, -1, -1, -1, -1}, /* IdSel 10 unused */
ian@0 505 { 30, 30, 30, 30, 30}, /* IdSel 11 21143 #2 */
ian@0 506 { -1, -1, -1, -1, -1}, /* IdSel 12 unused */
ian@0 507 { -1, -1, -1, -1, -1}, /* IdSel 13 unused */
ian@0 508 { 35, 35, 34, 33, 32}, /* IdSel 14 slot 0 */
ian@0 509 { 39, 39, 38, 37, 36}, /* IdSel 15 slot 1 */
ian@0 510 { 43, 43, 42, 41, 40}, /* IdSel 16 slot 2 */
ian@0 511 { 47, 47, 46, 45, 44}, /* IdSel 17 slot 3 */
ian@0 512 };
ian@0 513 const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5;
ian@0 514
ian@0 515 return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
ian@0 516 }
ian@0 517
ian@0 518 static int __init
ian@0 519 clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
ian@0 520 {
ian@0 521 static char irq_tab[7][5] __initdata = {
ian@0 522 /*INT INTA INTB INTC INTD */
ian@0 523 { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */
ian@0 524 { 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */
ian@0 525 { 16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 3 slot 3 */
ian@0 526 { 16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 4 slot 4 */
ian@0 527 { 16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 5 slot 5 */
ian@0 528 { 16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 6 slot 6 */
ian@0 529 { -1, -1, -1, -1, -1} /* IdSel 7 ISA Bridge */
ian@0 530 };
ian@0 531 const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;
ian@0 532 struct pci_controller *hose = dev->sysdata;
ian@0 533 int irq = COMMON_TABLE_LOOKUP;
ian@0 534
ian@0 535 if (irq > 0)
ian@0 536 irq += 16 * hose->index;
ian@0 537
ian@0 538 return isa_irq_fixup(dev, irq);
ian@0 539 }
ian@0 540
ian@0 541 static void __init
ian@0 542 dp264_init_pci(void)
ian@0 543 {
ian@0 544 common_init_pci();
ian@0 545 SMC669_Init(0);
ian@0 546 }
ian@0 547
ian@0 548 static void __init
ian@0 549 monet_init_pci(void)
ian@0 550 {
ian@0 551 common_init_pci();
ian@0 552 SMC669_Init(1);
ian@0 553 es1888_init();
ian@0 554 }
ian@0 555
ian@0 556 static void __init
ian@0 557 webbrick_init_arch(void)
ian@0 558 {
ian@0 559 tsunami_init_arch();
ian@0 560
ian@0 561 /* Tsunami caches 4 PTEs at a time; DS10 has only 1 hose. */
ian@0 562 hose_head->sg_isa->align_entry = 4;
ian@0 563 hose_head->sg_pci->align_entry = 4;
ian@0 564 }
ian@0 565
ian@0 566
ian@0 567 /*
ian@0 568 * The System Vectors
ian@0 569 */
ian@0 570
ian@0 571 struct alpha_machine_vector dp264_mv __initmv = {
ian@0 572 .vector_name = "DP264",
ian@0 573 DO_EV6_MMU,
ian@0 574 DO_DEFAULT_RTC,
ian@0 575 DO_TSUNAMI_IO,
ian@0 576 .machine_check = tsunami_machine_check,
ian@0 577 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
ian@0 578 .min_io_address = DEFAULT_IO_BASE,
ian@0 579 .min_mem_address = DEFAULT_MEM_BASE,
ian@0 580 .pci_dac_offset = TSUNAMI_DAC_OFFSET,
ian@0 581
ian@0 582 .nr_irqs = 64,
ian@0 583 .device_interrupt = dp264_device_interrupt,
ian@0 584
ian@0 585 .init_arch = tsunami_init_arch,
ian@0 586 .init_irq = dp264_init_irq,
ian@0 587 .init_rtc = common_init_rtc,
ian@0 588 .init_pci = dp264_init_pci,
ian@0 589 .kill_arch = tsunami_kill_arch,
ian@0 590 .pci_map_irq = dp264_map_irq,
ian@0 591 .pci_swizzle = common_swizzle,
ian@0 592 };
ian@0 593 ALIAS_MV(dp264)
ian@0 594
ian@0 595 struct alpha_machine_vector monet_mv __initmv = {
ian@0 596 .vector_name = "Monet",
ian@0 597 DO_EV6_MMU,
ian@0 598 DO_DEFAULT_RTC,
ian@0 599 DO_TSUNAMI_IO,
ian@0 600 .machine_check = tsunami_machine_check,
ian@0 601 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
ian@0 602 .min_io_address = DEFAULT_IO_BASE,
ian@0 603 .min_mem_address = DEFAULT_MEM_BASE,
ian@0 604 .pci_dac_offset = TSUNAMI_DAC_OFFSET,
ian@0 605
ian@0 606 .nr_irqs = 64,
ian@0 607 .device_interrupt = dp264_device_interrupt,
ian@0 608
ian@0 609 .init_arch = tsunami_init_arch,
ian@0 610 .init_irq = dp264_init_irq,
ian@0 611 .init_rtc = common_init_rtc,
ian@0 612 .init_pci = monet_init_pci,
ian@0 613 .kill_arch = tsunami_kill_arch,
ian@0 614 .pci_map_irq = monet_map_irq,
ian@0 615 .pci_swizzle = monet_swizzle,
ian@0 616 };
ian@0 617
ian@0 618 struct alpha_machine_vector webbrick_mv __initmv = {
ian@0 619 .vector_name = "Webbrick",
ian@0 620 DO_EV6_MMU,
ian@0 621 DO_DEFAULT_RTC,
ian@0 622 DO_TSUNAMI_IO,
ian@0 623 .machine_check = tsunami_machine_check,
ian@0 624 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
ian@0 625 .min_io_address = DEFAULT_IO_BASE,
ian@0 626 .min_mem_address = DEFAULT_MEM_BASE,
ian@0 627 .pci_dac_offset = TSUNAMI_DAC_OFFSET,
ian@0 628
ian@0 629 .nr_irqs = 64,
ian@0 630 .device_interrupt = dp264_device_interrupt,
ian@0 631
ian@0 632 .init_arch = webbrick_init_arch,
ian@0 633 .init_irq = dp264_init_irq,
ian@0 634 .init_rtc = common_init_rtc,
ian@0 635 .init_pci = common_init_pci,
ian@0 636 .kill_arch = tsunami_kill_arch,
ian@0 637 .pci_map_irq = webbrick_map_irq,
ian@0 638 .pci_swizzle = common_swizzle,
ian@0 639 };
ian@0 640
ian@0 641 struct alpha_machine_vector clipper_mv __initmv = {
ian@0 642 .vector_name = "Clipper",
ian@0 643 DO_EV6_MMU,
ian@0 644 DO_DEFAULT_RTC,
ian@0 645 DO_TSUNAMI_IO,
ian@0 646 .machine_check = tsunami_machine_check,
ian@0 647 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
ian@0 648 .min_io_address = DEFAULT_IO_BASE,
ian@0 649 .min_mem_address = DEFAULT_MEM_BASE,
ian@0 650 .pci_dac_offset = TSUNAMI_DAC_OFFSET,
ian@0 651
ian@0 652 .nr_irqs = 64,
ian@0 653 .device_interrupt = dp264_device_interrupt,
ian@0 654
ian@0 655 .init_arch = tsunami_init_arch,
ian@0 656 .init_irq = clipper_init_irq,
ian@0 657 .init_rtc = common_init_rtc,
ian@0 658 .init_pci = common_init_pci,
ian@0 659 .kill_arch = tsunami_kill_arch,
ian@0 660 .pci_map_irq = clipper_map_irq,
ian@0 661 .pci_swizzle = common_swizzle,
ian@0 662 };
ian@0 663
ian@0 664 /* Sharks strongly resemble Clipper, at least as far
ian@0 665 * as interrupt routing, etc, so we're using the
ian@0 666 * same functions as Clipper does
ian@0 667 */
ian@0 668
ian@0 669 struct alpha_machine_vector shark_mv __initmv = {
ian@0 670 .vector_name = "Shark",
ian@0 671 DO_EV6_MMU,
ian@0 672 DO_DEFAULT_RTC,
ian@0 673 DO_TSUNAMI_IO,
ian@0 674 .machine_check = tsunami_machine_check,
ian@0 675 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
ian@0 676 .min_io_address = DEFAULT_IO_BASE,
ian@0 677 .min_mem_address = DEFAULT_MEM_BASE,
ian@0 678 .pci_dac_offset = TSUNAMI_DAC_OFFSET,
ian@0 679
ian@0 680 .nr_irqs = 64,
ian@0 681 .device_interrupt = dp264_device_interrupt,
ian@0 682
ian@0 683 .init_arch = tsunami_init_arch,
ian@0 684 .init_irq = clipper_init_irq,
ian@0 685 .init_rtc = common_init_rtc,
ian@0 686 .init_pci = common_init_pci,
ian@0 687 .kill_arch = tsunami_kill_arch,
ian@0 688 .pci_map_irq = clipper_map_irq,
ian@0 689 .pci_swizzle = common_swizzle,
ian@0 690 };
ian@0 691
ian@0 692 /* No alpha_mv alias for webbrick/monet/clipper, since we compile them
ian@0 693 in unconditionally with DP264; setup_arch knows how to cope. */