0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/init.h>
0013 #include <linux/irq.h>
0014 #include <linux/kernel_stat.h>
0015 #include <linux/module.h>
0016 #include <linux/mutex.h>
0017 #include <linux/rculist.h>
0018 #include <linux/slab.h>
0019 #include <linux/dmapool.h>
0020
0021 #include <asm/airq.h>
0022 #include <asm/isc.h>
0023 #include <asm/cio.h>
0024
0025 #include "cio.h"
0026 #include "cio_debug.h"
0027 #include "ioasm.h"
0028
0029 static DEFINE_SPINLOCK(airq_lists_lock);
0030 static struct hlist_head airq_lists[MAX_ISC+1];
0031
0032 static struct dma_pool *airq_iv_cache;
0033
0034
0035
0036
0037
0038
0039
0040 int register_adapter_interrupt(struct airq_struct *airq)
0041 {
0042 char dbf_txt[32];
0043
0044 if (!airq->handler || airq->isc > MAX_ISC)
0045 return -EINVAL;
0046 if (!airq->lsi_ptr) {
0047 airq->lsi_ptr = cio_dma_zalloc(1);
0048 if (!airq->lsi_ptr)
0049 return -ENOMEM;
0050 airq->flags |= AIRQ_PTR_ALLOCATED;
0051 }
0052 if (!airq->lsi_mask)
0053 airq->lsi_mask = 0xff;
0054 snprintf(dbf_txt, sizeof(dbf_txt), "rairq:%p", airq);
0055 CIO_TRACE_EVENT(4, dbf_txt);
0056 isc_register(airq->isc);
0057 spin_lock(&airq_lists_lock);
0058 hlist_add_head_rcu(&airq->list, &airq_lists[airq->isc]);
0059 spin_unlock(&airq_lists_lock);
0060 return 0;
0061 }
0062 EXPORT_SYMBOL(register_adapter_interrupt);
0063
0064
0065
0066
0067
0068 void unregister_adapter_interrupt(struct airq_struct *airq)
0069 {
0070 char dbf_txt[32];
0071
0072 if (hlist_unhashed(&airq->list))
0073 return;
0074 snprintf(dbf_txt, sizeof(dbf_txt), "urairq:%p", airq);
0075 CIO_TRACE_EVENT(4, dbf_txt);
0076 spin_lock(&airq_lists_lock);
0077 hlist_del_rcu(&airq->list);
0078 spin_unlock(&airq_lists_lock);
0079 synchronize_rcu();
0080 isc_unregister(airq->isc);
0081 if (airq->flags & AIRQ_PTR_ALLOCATED) {
0082 cio_dma_free(airq->lsi_ptr, 1);
0083 airq->lsi_ptr = NULL;
0084 airq->flags &= ~AIRQ_PTR_ALLOCATED;
0085 }
0086 }
0087 EXPORT_SYMBOL(unregister_adapter_interrupt);
0088
0089 static irqreturn_t do_airq_interrupt(int irq, void *dummy)
0090 {
0091 struct tpi_info *tpi_info;
0092 struct airq_struct *airq;
0093 struct hlist_head *head;
0094
0095 set_cpu_flag(CIF_NOHZ_DELAY);
0096 tpi_info = &get_irq_regs()->tpi_info;
0097 trace_s390_cio_adapter_int(tpi_info);
0098 head = &airq_lists[tpi_info->isc];
0099 rcu_read_lock();
0100 hlist_for_each_entry_rcu(airq, head, list)
0101 if ((*airq->lsi_ptr & airq->lsi_mask) != 0)
0102 airq->handler(airq, tpi_info);
0103 rcu_read_unlock();
0104
0105 return IRQ_HANDLED;
0106 }
0107
0108 void __init init_airq_interrupts(void)
0109 {
0110 irq_set_chip_and_handler(THIN_INTERRUPT,
0111 &dummy_irq_chip, handle_percpu_irq);
0112 if (request_irq(THIN_INTERRUPT, do_airq_interrupt, 0, "AIO", NULL))
0113 panic("Failed to register AIO interrupt\n");
0114 }
0115
0116 static inline unsigned long iv_size(unsigned long bits)
0117 {
0118 return BITS_TO_LONGS(bits) * sizeof(unsigned long);
0119 }
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129 struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags,
0130 unsigned long *vec)
0131 {
0132 struct airq_iv *iv;
0133 unsigned long size;
0134
0135 iv = kzalloc(sizeof(*iv), GFP_KERNEL);
0136 if (!iv)
0137 goto out;
0138 iv->bits = bits;
0139 iv->flags = flags;
0140 size = iv_size(bits);
0141
0142 if (flags & AIRQ_IV_CACHELINE) {
0143 if ((cache_line_size() * BITS_PER_BYTE) < bits
0144 || !airq_iv_cache)
0145 goto out_free;
0146
0147 iv->vector = dma_pool_zalloc(airq_iv_cache, GFP_KERNEL,
0148 &iv->vector_dma);
0149 if (!iv->vector)
0150 goto out_free;
0151 } else if (flags & AIRQ_IV_GUESTVEC) {
0152 iv->vector = vec;
0153 } else {
0154 iv->vector = cio_dma_zalloc(size);
0155 if (!iv->vector)
0156 goto out_free;
0157 }
0158 if (flags & AIRQ_IV_ALLOC) {
0159 iv->avail = kmalloc(size, GFP_KERNEL);
0160 if (!iv->avail)
0161 goto out_free;
0162 memset(iv->avail, 0xff, size);
0163 iv->end = 0;
0164 } else
0165 iv->end = bits;
0166 if (flags & AIRQ_IV_BITLOCK) {
0167 iv->bitlock = kzalloc(size, GFP_KERNEL);
0168 if (!iv->bitlock)
0169 goto out_free;
0170 }
0171 if (flags & AIRQ_IV_PTR) {
0172 size = bits * sizeof(unsigned long);
0173 iv->ptr = kzalloc(size, GFP_KERNEL);
0174 if (!iv->ptr)
0175 goto out_free;
0176 }
0177 if (flags & AIRQ_IV_DATA) {
0178 size = bits * sizeof(unsigned int);
0179 iv->data = kzalloc(size, GFP_KERNEL);
0180 if (!iv->data)
0181 goto out_free;
0182 }
0183 spin_lock_init(&iv->lock);
0184 return iv;
0185
0186 out_free:
0187 kfree(iv->ptr);
0188 kfree(iv->bitlock);
0189 kfree(iv->avail);
0190 if (iv->flags & AIRQ_IV_CACHELINE && iv->vector)
0191 dma_pool_free(airq_iv_cache, iv->vector, iv->vector_dma);
0192 else if (!(iv->flags & AIRQ_IV_GUESTVEC))
0193 cio_dma_free(iv->vector, size);
0194 kfree(iv);
0195 out:
0196 return NULL;
0197 }
0198 EXPORT_SYMBOL(airq_iv_create);
0199
0200
0201
0202
0203
0204 void airq_iv_release(struct airq_iv *iv)
0205 {
0206 kfree(iv->data);
0207 kfree(iv->ptr);
0208 kfree(iv->bitlock);
0209 if (iv->flags & AIRQ_IV_CACHELINE)
0210 dma_pool_free(airq_iv_cache, iv->vector, iv->vector_dma);
0211 else if (!(iv->flags & AIRQ_IV_GUESTVEC))
0212 cio_dma_free(iv->vector, iv_size(iv->bits));
0213 kfree(iv->avail);
0214 kfree(iv);
0215 }
0216 EXPORT_SYMBOL(airq_iv_release);
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227 unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num)
0228 {
0229 unsigned long bit, i, flags;
0230
0231 if (!iv->avail || num == 0)
0232 return -1UL;
0233 spin_lock_irqsave(&iv->lock, flags);
0234 bit = find_first_bit_inv(iv->avail, iv->bits);
0235 while (bit + num <= iv->bits) {
0236 for (i = 1; i < num; i++)
0237 if (!test_bit_inv(bit + i, iv->avail))
0238 break;
0239 if (i >= num) {
0240
0241 for (i = 0; i < num; i++)
0242 clear_bit_inv(bit + i, iv->avail);
0243 if (bit + num >= iv->end)
0244 iv->end = bit + num + 1;
0245 break;
0246 }
0247 bit = find_next_bit_inv(iv->avail, iv->bits, bit + i + 1);
0248 }
0249 if (bit + num > iv->bits)
0250 bit = -1UL;
0251 spin_unlock_irqrestore(&iv->lock, flags);
0252 return bit;
0253 }
0254 EXPORT_SYMBOL(airq_iv_alloc);
0255
0256
0257
0258
0259
0260
0261
0262 void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num)
0263 {
0264 unsigned long i, flags;
0265
0266 if (!iv->avail || num == 0)
0267 return;
0268 spin_lock_irqsave(&iv->lock, flags);
0269 for (i = 0; i < num; i++) {
0270
0271 clear_bit_inv(bit + i, iv->vector);
0272
0273 set_bit_inv(bit + i, iv->avail);
0274 }
0275 if (bit + num >= iv->end) {
0276
0277 while (iv->end > 0 && !test_bit_inv(iv->end - 1, iv->avail))
0278 iv->end--;
0279 }
0280 spin_unlock_irqrestore(&iv->lock, flags);
0281 }
0282 EXPORT_SYMBOL(airq_iv_free);
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293 unsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start,
0294 unsigned long end)
0295 {
0296 unsigned long bit;
0297
0298
0299 bit = find_next_bit_inv(iv->vector, end, start);
0300 if (bit >= end)
0301 return -1UL;
0302 clear_bit_inv(bit, iv->vector);
0303 return bit;
0304 }
0305 EXPORT_SYMBOL(airq_iv_scan);
0306
0307 int __init airq_init(void)
0308 {
0309 airq_iv_cache = dma_pool_create("airq_iv_cache", cio_get_dma_css_dev(),
0310 cache_line_size(),
0311 cache_line_size(), PAGE_SIZE);
0312 if (!airq_iv_cache)
0313 return -ENOMEM;
0314 return 0;
0315 }