linux/drivers/s390/cio/qdio_setup.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * qdio queue initialization
   4 *
   5 * Copyright IBM Corp. 2008
   6 * Author(s): Jan Glauber <jang@linux.vnet.ibm.com>
   7 */
   8#include <linux/kernel.h>
   9#include <linux/slab.h>
  10#include <linux/export.h>
  11#include <linux/io.h>
  12
  13#include <asm/ebcdic.h>
  14#include <asm/qdio.h>
  15
  16#include "cio.h"
  17#include "css.h"
  18#include "device.h"
  19#include "ioasm.h"
  20#include "chsc.h"
  21#include "qdio.h"
  22#include "qdio_debug.h"
  23
  24#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer))
  25
  26static struct kmem_cache *qdio_q_cache;
  27static struct kmem_cache *qdio_aob_cache;
  28
  29struct qaob *qdio_allocate_aob(void)
  30{
  31        return kmem_cache_zalloc(qdio_aob_cache, GFP_ATOMIC);
  32}
  33EXPORT_SYMBOL_GPL(qdio_allocate_aob);
  34
  35void qdio_release_aob(struct qaob *aob)
  36{
  37        kmem_cache_free(qdio_aob_cache, aob);
  38}
  39EXPORT_SYMBOL_GPL(qdio_release_aob);
  40
  41/**
  42 * qdio_free_buffers() - free qdio buffers
  43 * @buf: array of pointers to qdio buffers
  44 * @count: number of qdio buffers to free
  45 */
  46void qdio_free_buffers(struct qdio_buffer **buf, unsigned int count)
  47{
  48        int pos;
  49
  50        for (pos = 0; pos < count; pos += QBUFF_PER_PAGE)
  51                free_page((unsigned long) buf[pos]);
  52}
  53EXPORT_SYMBOL_GPL(qdio_free_buffers);
  54
  55/**
  56 * qdio_alloc_buffers() - allocate qdio buffers
  57 * @buf: array of pointers to qdio buffers
  58 * @count: number of qdio buffers to allocate
  59 */
  60int qdio_alloc_buffers(struct qdio_buffer **buf, unsigned int count)
  61{
  62        int pos;
  63
  64        for (pos = 0; pos < count; pos += QBUFF_PER_PAGE) {
  65                buf[pos] = (void *) get_zeroed_page(GFP_KERNEL);
  66                if (!buf[pos]) {
  67                        qdio_free_buffers(buf, count);
  68                        return -ENOMEM;
  69                }
  70        }
  71        for (pos = 0; pos < count; pos++)
  72                if (pos % QBUFF_PER_PAGE)
  73                        buf[pos] = buf[pos - 1] + 1;
  74        return 0;
  75}
  76EXPORT_SYMBOL_GPL(qdio_alloc_buffers);
  77
  78/**
  79 * qdio_reset_buffers() - reset qdio buffers
  80 * @buf: array of pointers to qdio buffers
  81 * @count: number of qdio buffers that will be zeroed
  82 */
  83void qdio_reset_buffers(struct qdio_buffer **buf, unsigned int count)
  84{
  85        int pos;
  86
  87        for (pos = 0; pos < count; pos++)
  88                memset(buf[pos], 0, sizeof(struct qdio_buffer));
  89}
  90EXPORT_SYMBOL_GPL(qdio_reset_buffers);
  91
  92static void __qdio_free_queues(struct qdio_q **queues, unsigned int count)
  93{
  94        struct qdio_q *q;
  95        unsigned int i;
  96
  97        for (i = 0; i < count; i++) {
  98                q = queues[i];
  99                free_page((unsigned long) q->slib);
 100                kmem_cache_free(qdio_q_cache, q);
 101        }
 102}
 103
 104void qdio_free_queues(struct qdio_irq *irq_ptr)
 105{
 106        __qdio_free_queues(irq_ptr->input_qs, irq_ptr->max_input_qs);
 107        irq_ptr->max_input_qs = 0;
 108
 109        __qdio_free_queues(irq_ptr->output_qs, irq_ptr->max_output_qs);
 110        irq_ptr->max_output_qs = 0;
 111}
 112
 113static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues)
 114{
 115        struct qdio_q *q;
 116        int i;
 117
 118        for (i = 0; i < nr_queues; i++) {
 119                q = kmem_cache_zalloc(qdio_q_cache, GFP_KERNEL);
 120                if (!q) {
 121                        __qdio_free_queues(irq_ptr_qs, i);
 122                        return -ENOMEM;
 123                }
 124
 125                q->slib = (struct slib *) __get_free_page(GFP_KERNEL);
 126                if (!q->slib) {
 127                        kmem_cache_free(qdio_q_cache, q);
 128                        __qdio_free_queues(irq_ptr_qs, i);
 129                        return -ENOMEM;
 130                }
 131                irq_ptr_qs[i] = q;
 132        }
 133        return 0;
 134}
 135
 136int qdio_allocate_qs(struct qdio_irq *irq_ptr, int nr_input_qs, int nr_output_qs)
 137{
 138        int rc;
 139
 140        rc = __qdio_allocate_qs(irq_ptr->input_qs, nr_input_qs);
 141        if (rc)
 142                return rc;
 143
 144        rc = __qdio_allocate_qs(irq_ptr->output_qs, nr_output_qs);
 145        if (rc) {
 146                __qdio_free_queues(irq_ptr->input_qs, nr_input_qs);
 147                return rc;
 148        }
 149
 150        irq_ptr->max_input_qs = nr_input_qs;
 151        irq_ptr->max_output_qs = nr_output_qs;
 152        return 0;
 153}
 154
 155static void setup_queues_misc(struct qdio_q *q, struct qdio_irq *irq_ptr,
 156                              qdio_handler_t *handler, int i)
 157{
 158        struct slib *slib = q->slib;
 159
 160        /* queue must be cleared for qdio_establish */
 161        memset(q, 0, sizeof(*q));
 162        memset(slib, 0, PAGE_SIZE);
 163        q->slib = slib;
 164        q->irq_ptr = irq_ptr;
 165        q->mask = 1 << (31 - i);
 166        q->nr = i;
 167        q->handler = handler;
 168}
 169
 170static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr,
 171                                struct qdio_buffer **sbals_array, int i)
 172{
 173        struct qdio_q *prev;
 174        int j;
 175
 176        DBF_HEX(&q, sizeof(void *));
 177        q->sl = (struct sl *)((char *)q->slib + PAGE_SIZE / 2);
 178
 179        /* fill in sbal */
 180        for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++)
 181                q->sbal[j] = *sbals_array++;
 182
 183        /* fill in slib */
 184        if (i > 0) {
 185                prev = (q->is_input_q) ? irq_ptr->input_qs[i - 1]
 186                        : irq_ptr->output_qs[i - 1];
 187                prev->slib->nsliba = (unsigned long)q->slib;
 188        }
 189
 190        q->slib->sla = (unsigned long)q->sl;
 191        q->slib->slsba = (unsigned long)&q->slsb.val[0];
 192
 193        /* fill in sl */
 194        for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++)
 195                q->sl->element[j].sbal = virt_to_phys(q->sbal[j]);
 196}
 197
 198static void setup_queues(struct qdio_irq *irq_ptr,
 199                         struct qdio_initialize *qdio_init)
 200{
 201        struct qdio_q *q;
 202        int i;
 203
 204        for_each_input_queue(irq_ptr, q, i) {
 205                DBF_EVENT("inq:%1d", i);
 206                setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i);
 207
 208                q->is_input_q = 1;
 209
 210                setup_storage_lists(q, irq_ptr,
 211                                    qdio_init->input_sbal_addr_array[i], i);
 212        }
 213
 214        for_each_output_queue(irq_ptr, q, i) {
 215                DBF_EVENT("outq:%1d", i);
 216                setup_queues_misc(q, irq_ptr, qdio_init->output_handler, i);
 217
 218                q->is_input_q = 0;
 219                setup_storage_lists(q, irq_ptr,
 220                                    qdio_init->output_sbal_addr_array[i], i);
 221        }
 222}
 223
 224static void check_and_setup_qebsm(struct qdio_irq *irq_ptr,
 225                                  unsigned char qdioac, unsigned long token)
 226{
 227        if (!(irq_ptr->qib.rflags & QIB_RFLAGS_ENABLE_QEBSM))
 228                goto no_qebsm;
 229        if (!(qdioac & AC1_SC_QEBSM_AVAILABLE) ||
 230            (!(qdioac & AC1_SC_QEBSM_ENABLED)))
 231                goto no_qebsm;
 232
 233        irq_ptr->sch_token = token;
 234
 235        DBF_EVENT("V=V:1");
 236        DBF_EVENT("%8lx", irq_ptr->sch_token);
 237        return;
 238
 239no_qebsm:
 240        irq_ptr->sch_token = 0;
 241        irq_ptr->qib.rflags &= ~QIB_RFLAGS_ENABLE_QEBSM;
 242        DBF_EVENT("noV=V");
 243}
 244
 245/*
 246 * If there is a qdio_irq we use the chsc_page and store the information
 247 * in the qdio_irq, otherwise we copy it to the specified structure.
 248 */
 249int qdio_setup_get_ssqd(struct qdio_irq *irq_ptr,
 250                        struct subchannel_id *schid,
 251                        struct qdio_ssqd_desc *data)
 252{
 253        struct chsc_ssqd_area *ssqd;
 254        int rc;
 255
 256        DBF_EVENT("getssqd:%4x", schid->sch_no);
 257        if (!irq_ptr) {
 258                ssqd = (struct chsc_ssqd_area *)__get_free_page(GFP_KERNEL);
 259                if (!ssqd)
 260                        return -ENOMEM;
 261        } else {
 262                ssqd = (struct chsc_ssqd_area *)irq_ptr->chsc_page;
 263        }
 264
 265        rc = chsc_ssqd(*schid, ssqd);
 266        if (rc)
 267                goto out;
 268
 269        if (!(ssqd->qdio_ssqd.flags & CHSC_FLAG_QDIO_CAPABILITY) ||
 270            !(ssqd->qdio_ssqd.flags & CHSC_FLAG_VALIDITY) ||
 271            (ssqd->qdio_ssqd.sch != schid->sch_no))
 272                rc = -EINVAL;
 273
 274        if (!rc)
 275                memcpy(data, &ssqd->qdio_ssqd, sizeof(*data));
 276
 277out:
 278        if (!irq_ptr)
 279                free_page((unsigned long)ssqd);
 280
 281        return rc;
 282}
 283
 284void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr)
 285{
 286        unsigned char qdioac;
 287        int rc;
 288
 289        rc = qdio_setup_get_ssqd(irq_ptr, &irq_ptr->schid, &irq_ptr->ssqd_desc);
 290        if (rc) {
 291                DBF_ERROR("%4x ssqd ERR", irq_ptr->schid.sch_no);
 292                DBF_ERROR("rc:%x", rc);
 293                /* all flags set, worst case */
 294                qdioac = AC1_SIGA_INPUT_NEEDED | AC1_SIGA_OUTPUT_NEEDED |
 295                         AC1_SIGA_SYNC_NEEDED;
 296        } else
 297                qdioac = irq_ptr->ssqd_desc.qdioac1;
 298
 299        check_and_setup_qebsm(irq_ptr, qdioac, irq_ptr->ssqd_desc.sch_token);
 300        irq_ptr->qdioac1 = qdioac;
 301        DBF_EVENT("ac 1:%2x 2:%4x", qdioac, irq_ptr->ssqd_desc.qdioac2);
 302        DBF_EVENT("3:%4x qib:%4x", irq_ptr->ssqd_desc.qdioac3, irq_ptr->qib.ac);
 303}
 304
 305static void qdio_fill_qdr_desc(struct qdesfmt0 *desc, struct qdio_q *queue)
 306{
 307        desc->sliba = virt_to_phys(queue->slib);
 308        desc->sla = virt_to_phys(queue->sl);
 309        desc->slsba = virt_to_phys(&queue->slsb);
 310
 311        desc->akey = PAGE_DEFAULT_KEY >> 4;
 312        desc->bkey = PAGE_DEFAULT_KEY >> 4;
 313        desc->ckey = PAGE_DEFAULT_KEY >> 4;
 314        desc->dkey = PAGE_DEFAULT_KEY >> 4;
 315}
 316
 317static void setup_qdr(struct qdio_irq *irq_ptr,
 318                      struct qdio_initialize *qdio_init)
 319{
 320        struct qdesfmt0 *desc = &irq_ptr->qdr->qdf0[0];
 321        int i;
 322
 323        memset(irq_ptr->qdr, 0, sizeof(struct qdr));
 324
 325        irq_ptr->qdr->qfmt = qdio_init->q_format;
 326        irq_ptr->qdr->ac = qdio_init->qdr_ac;
 327        irq_ptr->qdr->iqdcnt = qdio_init->no_input_qs;
 328        irq_ptr->qdr->oqdcnt = qdio_init->no_output_qs;
 329        irq_ptr->qdr->iqdsz = sizeof(struct qdesfmt0) / 4; /* size in words */
 330        irq_ptr->qdr->oqdsz = sizeof(struct qdesfmt0) / 4;
 331        irq_ptr->qdr->qiba = virt_to_phys(&irq_ptr->qib);
 332        irq_ptr->qdr->qkey = PAGE_DEFAULT_KEY >> 4;
 333
 334        for (i = 0; i < qdio_init->no_input_qs; i++)
 335                qdio_fill_qdr_desc(desc++, irq_ptr->input_qs[i]);
 336
 337        for (i = 0; i < qdio_init->no_output_qs; i++)
 338                qdio_fill_qdr_desc(desc++, irq_ptr->output_qs[i]);
 339}
 340
 341static void setup_qib(struct qdio_irq *irq_ptr,
 342                      struct qdio_initialize *init_data)
 343{
 344        memset(&irq_ptr->qib, 0, sizeof(irq_ptr->qib));
 345
 346        irq_ptr->qib.qfmt = init_data->q_format;
 347        irq_ptr->qib.pfmt = init_data->qib_param_field_format;
 348
 349        irq_ptr->qib.rflags = init_data->qib_rflags;
 350        if (css_general_characteristics.qebsm)
 351                irq_ptr->qib.rflags |= QIB_RFLAGS_ENABLE_QEBSM;
 352
 353        if (init_data->no_input_qs)
 354                irq_ptr->qib.isliba =
 355                        (unsigned long)(irq_ptr->input_qs[0]->slib);
 356        if (init_data->no_output_qs)
 357                irq_ptr->qib.osliba =
 358                        (unsigned long)(irq_ptr->output_qs[0]->slib);
 359        memcpy(irq_ptr->qib.ebcnam, dev_name(&irq_ptr->cdev->dev), 8);
 360        ASCEBC(irq_ptr->qib.ebcnam, 8);
 361
 362        if (init_data->qib_param_field)
 363                memcpy(irq_ptr->qib.parm, init_data->qib_param_field,
 364                       sizeof(irq_ptr->qib.parm));
 365}
 366
 367int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data)
 368{
 369        struct ccw_device *cdev = irq_ptr->cdev;
 370        struct ciw *ciw;
 371
 372        irq_ptr->qdioac1 = 0;
 373        memset(&irq_ptr->ccw, 0, sizeof(irq_ptr->ccw));
 374        memset(&irq_ptr->ssqd_desc, 0, sizeof(irq_ptr->ssqd_desc));
 375        memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat));
 376
 377        irq_ptr->debugfs_dev = NULL;
 378        irq_ptr->sch_token = irq_ptr->perf_stat_enabled = 0;
 379        irq_ptr->state = QDIO_IRQ_STATE_INACTIVE;
 380
 381        irq_ptr->int_parm = init_data->int_parm;
 382        irq_ptr->nr_input_qs = init_data->no_input_qs;
 383        irq_ptr->nr_output_qs = init_data->no_output_qs;
 384        ccw_device_get_schid(cdev, &irq_ptr->schid);
 385        setup_queues(irq_ptr, init_data);
 386
 387        irq_ptr->irq_poll = init_data->irq_poll;
 388        set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state);
 389
 390        setup_qib(irq_ptr, init_data);
 391
 392        /* fill input and output descriptors */
 393        setup_qdr(irq_ptr, init_data);
 394
 395        /* qdr, qib, sls, slsbs, slibs, sbales are filled now */
 396
 397        /* set our IRQ handler */
 398        spin_lock_irq(get_ccwdev_lock(cdev));
 399        irq_ptr->orig_handler = cdev->handler;
 400        cdev->handler = qdio_int_handler;
 401        spin_unlock_irq(get_ccwdev_lock(cdev));
 402
 403        /* get qdio commands */
 404        ciw = ccw_device_get_ciw(cdev, CIW_TYPE_EQUEUE);
 405        if (!ciw) {
 406                DBF_ERROR("%4x NO EQ", irq_ptr->schid.sch_no);
 407                return -EINVAL;
 408        }
 409        irq_ptr->equeue = *ciw;
 410
 411        ciw = ccw_device_get_ciw(cdev, CIW_TYPE_AQUEUE);
 412        if (!ciw) {
 413                DBF_ERROR("%4x NO AQ", irq_ptr->schid.sch_no);
 414                return -EINVAL;
 415        }
 416        irq_ptr->aqueue = *ciw;
 417
 418        return 0;
 419}
 420
 421void qdio_shutdown_irq(struct qdio_irq *irq)
 422{
 423        struct ccw_device *cdev = irq->cdev;
 424
 425        /* restore IRQ handler */
 426        spin_lock_irq(get_ccwdev_lock(cdev));
 427        cdev->handler = irq->orig_handler;
 428        cdev->private->intparm = 0;
 429        spin_unlock_irq(get_ccwdev_lock(cdev));
 430}
 431
 432void qdio_print_subchannel_info(struct qdio_irq *irq_ptr)
 433{
 434        dev_info(&irq_ptr->cdev->dev,
 435                 "qdio: %s on SC %x using AI:%d QEBSM:%d PRI:%d TDD:%d SIGA:%s%s%s\n",
 436                 (irq_ptr->qib.qfmt == QDIO_QETH_QFMT) ? "OSA" :
 437                        ((irq_ptr->qib.qfmt == QDIO_ZFCP_QFMT) ? "ZFCP" : "HS"),
 438                 irq_ptr->schid.sch_no,
 439                 is_thinint_irq(irq_ptr),
 440                 (irq_ptr->sch_token) ? 1 : 0,
 441                 pci_out_supported(irq_ptr) ? 1 : 0,
 442                 css_general_characteristics.aif_tdd,
 443                 qdio_need_siga_in(irq_ptr) ? "R" : " ",
 444                 qdio_need_siga_out(irq_ptr) ? "W" : " ",
 445                 qdio_need_siga_sync(irq_ptr) ? "S" : " ");
 446}
 447
 448int __init qdio_setup_init(void)
 449{
 450        int rc;
 451
 452        qdio_q_cache = kmem_cache_create("qdio_q", sizeof(struct qdio_q),
 453                                         256, 0, NULL);
 454        if (!qdio_q_cache)
 455                return -ENOMEM;
 456
 457        qdio_aob_cache = kmem_cache_create("qdio_aob",
 458                                        sizeof(struct qaob),
 459                                        sizeof(struct qaob),
 460                                        0,
 461                                        NULL);
 462        if (!qdio_aob_cache) {
 463                rc = -ENOMEM;
 464                goto free_qdio_q_cache;
 465        }
 466
 467        /* Check for OSA/FCP thin interrupts (bit 67). */
 468        DBF_EVENT("thinint:%1d",
 469                  (css_general_characteristics.aif_osa) ? 1 : 0);
 470
 471        /* Check for QEBSM support in general (bit 58). */
 472        DBF_EVENT("cssQEBSM:%1d", css_general_characteristics.qebsm);
 473        rc = 0;
 474out:
 475        return rc;
 476free_qdio_q_cache:
 477        kmem_cache_destroy(qdio_q_cache);
 478        goto out;
 479}
 480
 481void qdio_setup_exit(void)
 482{
 483        kmem_cache_destroy(qdio_aob_cache);
 484        kmem_cache_destroy(qdio_q_cache);
 485}
 486