linux/drivers/s390/crypto/ap_card.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright IBM Corp. 2016
   4 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
   5 *
   6 * Adjunct processor bus, card related code.
   7 */
   8
   9#define KMSG_COMPONENT "ap"
  10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  11
  12#include <linux/init.h>
  13#include <linux/slab.h>
  14#include <asm/facility.h>
  15#include <asm/sclp.h>
  16
  17#include "ap_bus.h"
  18
  19/*
  20 * AP card related attributes.
  21 */
  22static ssize_t hwtype_show(struct device *dev,
  23                           struct device_attribute *attr, char *buf)
  24{
  25        struct ap_card *ac = to_ap_card(dev);
  26
  27        return scnprintf(buf, PAGE_SIZE, "%d\n", ac->ap_dev.device_type);
  28}
  29
  30static DEVICE_ATTR_RO(hwtype);
  31
  32static ssize_t raw_hwtype_show(struct device *dev,
  33                               struct device_attribute *attr, char *buf)
  34{
  35        struct ap_card *ac = to_ap_card(dev);
  36
  37        return scnprintf(buf, PAGE_SIZE, "%d\n", ac->raw_hwtype);
  38}
  39
  40static DEVICE_ATTR_RO(raw_hwtype);
  41
  42static ssize_t depth_show(struct device *dev, struct device_attribute *attr,
  43                          char *buf)
  44{
  45        struct ap_card *ac = to_ap_card(dev);
  46
  47        return scnprintf(buf, PAGE_SIZE, "%d\n", ac->queue_depth);
  48}
  49
  50static DEVICE_ATTR_RO(depth);
  51
  52static ssize_t ap_functions_show(struct device *dev,
  53                                 struct device_attribute *attr, char *buf)
  54{
  55        struct ap_card *ac = to_ap_card(dev);
  56
  57        return scnprintf(buf, PAGE_SIZE, "0x%08X\n", ac->functions);
  58}
  59
  60static DEVICE_ATTR_RO(ap_functions);
  61
  62static ssize_t request_count_show(struct device *dev,
  63                                  struct device_attribute *attr,
  64                                  char *buf)
  65{
  66        struct ap_card *ac = to_ap_card(dev);
  67        u64 req_cnt;
  68
  69        req_cnt = 0;
  70        spin_lock_bh(&ap_queues_lock);
  71        req_cnt = atomic64_read(&ac->total_request_count);
  72        spin_unlock_bh(&ap_queues_lock);
  73        return scnprintf(buf, PAGE_SIZE, "%llu\n", req_cnt);
  74}
  75
  76static ssize_t request_count_store(struct device *dev,
  77                                   struct device_attribute *attr,
  78                                   const char *buf, size_t count)
  79{
  80        int bkt;
  81        struct ap_queue *aq;
  82        struct ap_card *ac = to_ap_card(dev);
  83
  84        spin_lock_bh(&ap_queues_lock);
  85        hash_for_each(ap_queues, bkt, aq, hnode)
  86                if (ac == aq->card)
  87                        aq->total_request_count = 0;
  88        spin_unlock_bh(&ap_queues_lock);
  89        atomic64_set(&ac->total_request_count, 0);
  90
  91        return count;
  92}
  93
  94static DEVICE_ATTR_RW(request_count);
  95
  96static ssize_t requestq_count_show(struct device *dev,
  97                                   struct device_attribute *attr, char *buf)
  98{
  99        int bkt;
 100        struct ap_queue *aq;
 101        unsigned int reqq_cnt;
 102        struct ap_card *ac = to_ap_card(dev);
 103
 104        reqq_cnt = 0;
 105        spin_lock_bh(&ap_queues_lock);
 106        hash_for_each(ap_queues, bkt, aq, hnode)
 107                if (ac == aq->card)
 108                        reqq_cnt += aq->requestq_count;
 109        spin_unlock_bh(&ap_queues_lock);
 110        return scnprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt);
 111}
 112
 113static DEVICE_ATTR_RO(requestq_count);
 114
 115static ssize_t pendingq_count_show(struct device *dev,
 116                                   struct device_attribute *attr, char *buf)
 117{
 118        int bkt;
 119        struct ap_queue *aq;
 120        unsigned int penq_cnt;
 121        struct ap_card *ac = to_ap_card(dev);
 122
 123        penq_cnt = 0;
 124        spin_lock_bh(&ap_queues_lock);
 125        hash_for_each(ap_queues, bkt, aq, hnode)
 126                if (ac == aq->card)
 127                        penq_cnt += aq->pendingq_count;
 128        spin_unlock_bh(&ap_queues_lock);
 129        return scnprintf(buf, PAGE_SIZE, "%d\n", penq_cnt);
 130}
 131
 132static DEVICE_ATTR_RO(pendingq_count);
 133
 134static ssize_t modalias_show(struct device *dev,
 135                             struct device_attribute *attr, char *buf)
 136{
 137        return scnprintf(buf, PAGE_SIZE, "ap:t%02X\n",
 138                         to_ap_dev(dev)->device_type);
 139}
 140
 141static DEVICE_ATTR_RO(modalias);
 142
 143static ssize_t config_show(struct device *dev,
 144                           struct device_attribute *attr, char *buf)
 145{
 146        struct ap_card *ac = to_ap_card(dev);
 147
 148        return scnprintf(buf, PAGE_SIZE, "%d\n", ac->config ? 1 : 0);
 149}
 150
 151static ssize_t config_store(struct device *dev,
 152                            struct device_attribute *attr,
 153                            const char *buf, size_t count)
 154{
 155        int rc = 0, cfg;
 156        struct ap_card *ac = to_ap_card(dev);
 157
 158        if (sscanf(buf, "%d\n", &cfg) != 1 || cfg < 0 || cfg > 1)
 159                return -EINVAL;
 160
 161        if (cfg && !ac->config)
 162                rc = sclp_ap_configure(ac->id);
 163        else if (!cfg && ac->config)
 164                rc = sclp_ap_deconfigure(ac->id);
 165        if (rc)
 166                return rc;
 167
 168        ac->config = cfg ? true : false;
 169
 170        return count;
 171}
 172
 173static DEVICE_ATTR_RW(config);
 174
 175static struct attribute *ap_card_dev_attrs[] = {
 176        &dev_attr_hwtype.attr,
 177        &dev_attr_raw_hwtype.attr,
 178        &dev_attr_depth.attr,
 179        &dev_attr_ap_functions.attr,
 180        &dev_attr_request_count.attr,
 181        &dev_attr_requestq_count.attr,
 182        &dev_attr_pendingq_count.attr,
 183        &dev_attr_modalias.attr,
 184        &dev_attr_config.attr,
 185        NULL
 186};
 187
 188static struct attribute_group ap_card_dev_attr_group = {
 189        .attrs = ap_card_dev_attrs
 190};
 191
 192static const struct attribute_group *ap_card_dev_attr_groups[] = {
 193        &ap_card_dev_attr_group,
 194        NULL
 195};
 196
 197static struct device_type ap_card_type = {
 198        .name = "ap_card",
 199        .groups = ap_card_dev_attr_groups,
 200};
 201
 202static void ap_card_device_release(struct device *dev)
 203{
 204        struct ap_card *ac = to_ap_card(dev);
 205
 206        kfree(ac);
 207}
 208
 209struct ap_card *ap_card_create(int id, int queue_depth, int raw_type,
 210                               int comp_type, unsigned int functions)
 211{
 212        struct ap_card *ac;
 213
 214        ac = kzalloc(sizeof(*ac), GFP_KERNEL);
 215        if (!ac)
 216                return NULL;
 217        ac->ap_dev.device.release = ap_card_device_release;
 218        ac->ap_dev.device.type = &ap_card_type;
 219        ac->ap_dev.device_type = comp_type;
 220        ac->raw_hwtype = raw_type;
 221        ac->queue_depth = queue_depth;
 222        ac->functions = functions;
 223        ac->id = id;
 224        return ac;
 225}
 226