/* * The bits_wide parameter accommodates the limitations of the HW/SW which * use these bits: * Legacy PA I/O (GSC/NIO): 5 bits (architected EIM register) * V-class (EPIC): 6 bits * N/L/A-class (iosapic): 8 bits * PCI 2.2 MSI: 16 bits * Some PCI devices: 32 bits (Symbios SCSI/ATM/HyperFabric) * * On the service provider side: * o PA 1.1 (and PA2.0 narrow mode) 5-bits (width of EIR register) * o PA 2.0 wide mode 6-bits (per processor) * o IA64 8-bits (0-256 total) * * So a Legacy PA I/O device on a PA 2.0 box can't use all the bits supported * by the processor...and the N/L-class I/O subsystem supports more bits than * PA2.0 has. The first case is the problem. */ int txn_alloc_irq(unsigned int bits_wide) { int irq; /* never return irq 0 cause that's the interval timer */ for (irq = CPU_IRQ_BASE + 1; irq <= CPU_IRQ_MAX; irq++) { if (cpu_claim_irq(irq, NULL, NULL) < 0) continue; if ((irq - CPU_IRQ_BASE) >= (1 << bits_wide)) continue; return irq; } /* unlikely, but be prepared */ return -1; }
int txn_alloc_irq(unsigned int bits_wide) { int irq; for (irq = CPU_IRQ_BASE + 1; irq <= CPU_IRQ_MAX; irq++) { if (cpu_claim_irq(irq, NULL, NULL) < 0) continue; if ((irq - CPU_IRQ_BASE) >= (1 << bits_wide)) continue; return irq; } return -1; }
int txn_claim_irq(int irq) { return cpu_claim_irq(irq, NULL, NULL) ? -1 : irq; }