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
  16#include "ap_bus.h"
  17#include "ap_asm.h"
  18
  19/*
  20 * AP card related attributes.
  21 */
  22static ssize_t ap_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 snprintf(buf, PAGE_SIZE, "%d\n", ac->ap_dev.device_type);
  28}
  29
  30static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
  31
  32static ssize_t ap_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 snprintf(buf, PAGE_SIZE, "%d\n", ac->raw_hwtype);
  38}
  39
  40static DEVICE_ATTR(raw_hwtype, 0444, ap_raw_hwtype_show, NULL);
  41
  42static ssize_t ap_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 snprintf(buf, PAGE_SIZE, "%d\n", ac->queue_depth);
  48}
  49
  50static DEVICE_ATTR(depth, 0444, ap_depth_show, NULL);
  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 snprintf(buf, PAGE_SIZE, "0x%08X\n", ac->functions);
  58}
  59
  60static DEVICE_ATTR(ap_functions, 0444, ap_functions_show, NULL);
  61
  62static ssize_t ap_req_count_show(struct device *dev,
  63                                 struct device_attribute *attr,
  64                                 char *buf)
  65{
  66        struct ap_card *ac = to_ap_card(dev);
  67        unsigned int req_cnt;
  68
  69        req_cnt = 0;
  70        spin_lock_bh(&ap_list_lock);
  71        req_cnt = atomic_read(&ac->total_request_count);
  72        spin_unlock_bh(&ap_list_lock);
  73        return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt);
  74}
  75
  76static ssize_t ap_req_count_store(struct device *dev,
  77                                  struct device_attribute *attr,
  78                                  const char *buf, size_t count)
  79{
  80        struct ap_card *ac = to_ap_card(dev);
  81        struct ap_queue *aq;
  82
  83        spin_lock_bh(&ap_list_lock);
  84        for_each_ap_queue(aq, ac)
  85                aq->total_request_count = 0;
  86        spin_unlock_bh(&ap_list_lock);
  87        atomic_set(&ac->total_request_count, 0);
  88
  89        return count;
  90}
  91
  92static DEVICE_ATTR(request_count, 0644, ap_req_count_show, ap_req_count_store);
  93
  94static ssize_t ap_requestq_count_show(struct device *dev,
  95                                      struct device_attribute *attr, char *buf)
  96{
  97        struct ap_card *ac = to_ap_card(dev);
  98        struct ap_queue *aq;
  99        unsigned int reqq_cnt;
 100
 101        reqq_cnt = 0;
 102        spin_lock_bh(&ap_list_lock);
 103        for_each_ap_queue(aq, ac)
 104                reqq_cnt += aq->requestq_count;
 105        spin_unlock_bh(&ap_list_lock);
 106        return snprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt);
 107}
 108
 109static DEVICE_ATTR(requestq_count, 0444, ap_requestq_count_show, NULL);
 110
 111static ssize_t ap_pendingq_count_show(struct device *dev,
 112                                      struct device_attribute *attr, char *buf)
 113{
 114        struct ap_card *ac = to_ap_card(dev);
 115        struct ap_queue *aq;
 116        unsigned int penq_cnt;
 117
 118        penq_cnt = 0;
 119        spin_lock_bh(&ap_list_lock);
 120        for_each_ap_queue(aq, ac)
 121                penq_cnt += aq->pendingq_count;
 122        spin_unlock_bh(&ap_list_lock);
 123        return snprintf(buf, PAGE_SIZE, "%d\n", penq_cnt);
 124}
 125
 126static DEVICE_ATTR(pendingq_count, 0444, ap_pendingq_count_show, NULL);
 127
 128static ssize_t ap_modalias_show(struct device *dev,
 129                                struct device_attribute *attr, char *buf)
 130{
 131        return sprintf(buf, "ap:t%02X\n", to_ap_dev(dev)->device_type);
 132}
 133
 134static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL);
 135
 136static struct attribute *ap_card_dev_attrs[] = {
 137        &dev_attr_hwtype.attr,
 138        &dev_attr_raw_hwtype.attr,
 139        &dev_attr_depth.attr,
 140        &dev_attr_ap_functions.attr,
 141        &dev_attr_request_count.attr,
 142        &dev_attr_requestq_count.attr,
 143        &dev_attr_pendingq_count.attr,
 144        &dev_attr_modalias.attr,
 145        NULL
 146};
 147
 148static struct attribute_group ap_card_dev_attr_group = {
 149        .attrs = ap_card_dev_attrs
 150};
 151
 152static const struct attribute_group *ap_card_dev_attr_groups[] = {
 153        &ap_card_dev_attr_group,
 154        NULL
 155};
 156
 157static struct device_type ap_card_type = {
 158        .name = "ap_card",
 159        .groups = ap_card_dev_attr_groups,
 160};
 161
 162static void ap_card_device_release(struct device *dev)
 163{
 164        struct ap_card *ac = to_ap_card(dev);
 165
 166        if (!list_empty(&ac->list)) {
 167                spin_lock_bh(&ap_list_lock);
 168                list_del_init(&ac->list);
 169                spin_unlock_bh(&ap_list_lock);
 170        }
 171        kfree(ac);
 172}
 173
 174struct ap_card *ap_card_create(int id, int queue_depth, int device_type,
 175                               unsigned int functions)
 176{
 177        struct ap_card *ac;
 178
 179        ac = kzalloc(sizeof(*ac), GFP_KERNEL);
 180        if (!ac)
 181                return NULL;
 182        INIT_LIST_HEAD(&ac->queues);
 183        ac->ap_dev.device.release = ap_card_device_release;
 184        ac->ap_dev.device.type = &ap_card_type;
 185        ac->ap_dev.device_type = device_type;
 186        /* CEX6 toleration: map to CEX5 */
 187        if (device_type == AP_DEVICE_TYPE_CEX6)
 188                ac->ap_dev.device_type = AP_DEVICE_TYPE_CEX5;
 189        ac->raw_hwtype = device_type;
 190        ac->queue_depth = queue_depth;
 191        ac->functions = functions;
 192        ac->id = id;
 193        return ac;
 194}
 195