Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright IBM Corp. 2016
0004  * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
0005  *
0006  * Adjunct processor bus, card related code.
0007  */
0008 
0009 #define KMSG_COMPONENT "ap"
0010 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
0011 
0012 #include <linux/init.h>
0013 #include <linux/slab.h>
0014 #include <asm/facility.h>
0015 #include <asm/sclp.h>
0016 
0017 #include "ap_bus.h"
0018 
0019 /*
0020  * AP card related attributes.
0021  */
0022 static ssize_t hwtype_show(struct device *dev,
0023                struct device_attribute *attr, char *buf)
0024 {
0025     struct ap_card *ac = to_ap_card(dev);
0026 
0027     return scnprintf(buf, PAGE_SIZE, "%d\n", ac->ap_dev.device_type);
0028 }
0029 
0030 static DEVICE_ATTR_RO(hwtype);
0031 
0032 static ssize_t raw_hwtype_show(struct device *dev,
0033                    struct device_attribute *attr, char *buf)
0034 {
0035     struct ap_card *ac = to_ap_card(dev);
0036 
0037     return scnprintf(buf, PAGE_SIZE, "%d\n", ac->raw_hwtype);
0038 }
0039 
0040 static DEVICE_ATTR_RO(raw_hwtype);
0041 
0042 static ssize_t depth_show(struct device *dev, struct device_attribute *attr,
0043               char *buf)
0044 {
0045     struct ap_card *ac = to_ap_card(dev);
0046 
0047     return scnprintf(buf, PAGE_SIZE, "%d\n", ac->queue_depth);
0048 }
0049 
0050 static DEVICE_ATTR_RO(depth);
0051 
0052 static ssize_t ap_functions_show(struct device *dev,
0053                  struct device_attribute *attr, char *buf)
0054 {
0055     struct ap_card *ac = to_ap_card(dev);
0056 
0057     return scnprintf(buf, PAGE_SIZE, "0x%08X\n", ac->functions);
0058 }
0059 
0060 static DEVICE_ATTR_RO(ap_functions);
0061 
0062 static ssize_t request_count_show(struct device *dev,
0063                   struct device_attribute *attr,
0064                   char *buf)
0065 {
0066     struct ap_card *ac = to_ap_card(dev);
0067     u64 req_cnt;
0068 
0069     req_cnt = 0;
0070     spin_lock_bh(&ap_queues_lock);
0071     req_cnt = atomic64_read(&ac->total_request_count);
0072     spin_unlock_bh(&ap_queues_lock);
0073     return scnprintf(buf, PAGE_SIZE, "%llu\n", req_cnt);
0074 }
0075 
0076 static ssize_t request_count_store(struct device *dev,
0077                    struct device_attribute *attr,
0078                    const char *buf, size_t count)
0079 {
0080     int bkt;
0081     struct ap_queue *aq;
0082     struct ap_card *ac = to_ap_card(dev);
0083 
0084     spin_lock_bh(&ap_queues_lock);
0085     hash_for_each(ap_queues, bkt, aq, hnode)
0086         if (ac == aq->card)
0087             aq->total_request_count = 0;
0088     spin_unlock_bh(&ap_queues_lock);
0089     atomic64_set(&ac->total_request_count, 0);
0090 
0091     return count;
0092 }
0093 
0094 static DEVICE_ATTR_RW(request_count);
0095 
0096 static ssize_t requestq_count_show(struct device *dev,
0097                    struct device_attribute *attr, char *buf)
0098 {
0099     int bkt;
0100     struct ap_queue *aq;
0101     unsigned int reqq_cnt;
0102     struct ap_card *ac = to_ap_card(dev);
0103 
0104     reqq_cnt = 0;
0105     spin_lock_bh(&ap_queues_lock);
0106     hash_for_each(ap_queues, bkt, aq, hnode)
0107         if (ac == aq->card)
0108             reqq_cnt += aq->requestq_count;
0109     spin_unlock_bh(&ap_queues_lock);
0110     return scnprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt);
0111 }
0112 
0113 static DEVICE_ATTR_RO(requestq_count);
0114 
0115 static ssize_t pendingq_count_show(struct device *dev,
0116                    struct device_attribute *attr, char *buf)
0117 {
0118     int bkt;
0119     struct ap_queue *aq;
0120     unsigned int penq_cnt;
0121     struct ap_card *ac = to_ap_card(dev);
0122 
0123     penq_cnt = 0;
0124     spin_lock_bh(&ap_queues_lock);
0125     hash_for_each(ap_queues, bkt, aq, hnode)
0126         if (ac == aq->card)
0127             penq_cnt += aq->pendingq_count;
0128     spin_unlock_bh(&ap_queues_lock);
0129     return scnprintf(buf, PAGE_SIZE, "%d\n", penq_cnt);
0130 }
0131 
0132 static DEVICE_ATTR_RO(pendingq_count);
0133 
0134 static ssize_t modalias_show(struct device *dev,
0135                  struct device_attribute *attr, char *buf)
0136 {
0137     return scnprintf(buf, PAGE_SIZE, "ap:t%02X\n",
0138              to_ap_dev(dev)->device_type);
0139 }
0140 
0141 static DEVICE_ATTR_RO(modalias);
0142 
0143 static ssize_t config_show(struct device *dev,
0144                struct device_attribute *attr, char *buf)
0145 {
0146     struct ap_card *ac = to_ap_card(dev);
0147 
0148     return scnprintf(buf, PAGE_SIZE, "%d\n", ac->config ? 1 : 0);
0149 }
0150 
0151 static ssize_t config_store(struct device *dev,
0152                 struct device_attribute *attr,
0153                 const char *buf, size_t count)
0154 {
0155     int rc = 0, cfg;
0156     struct ap_card *ac = to_ap_card(dev);
0157 
0158     if (sscanf(buf, "%d\n", &cfg) != 1 || cfg < 0 || cfg > 1)
0159         return -EINVAL;
0160 
0161     if (cfg && !ac->config)
0162         rc = sclp_ap_configure(ac->id);
0163     else if (!cfg && ac->config)
0164         rc = sclp_ap_deconfigure(ac->id);
0165     if (rc)
0166         return rc;
0167 
0168     ac->config = cfg ? true : false;
0169 
0170     ap_send_config_uevent(&ac->ap_dev, ac->config);
0171 
0172     return count;
0173 }
0174 
0175 static DEVICE_ATTR_RW(config);
0176 
0177 static ssize_t chkstop_show(struct device *dev,
0178                 struct device_attribute *attr, char *buf)
0179 {
0180     struct ap_card *ac = to_ap_card(dev);
0181 
0182     return scnprintf(buf, PAGE_SIZE, "%d\n", ac->chkstop ? 1 : 0);
0183 }
0184 
0185 static DEVICE_ATTR_RO(chkstop);
0186 
0187 static ssize_t max_msg_size_show(struct device *dev,
0188                  struct device_attribute *attr, char *buf)
0189 {
0190     struct ap_card *ac = to_ap_card(dev);
0191 
0192     return scnprintf(buf, PAGE_SIZE, "%u\n", ac->maxmsgsize);
0193 }
0194 
0195 static DEVICE_ATTR_RO(max_msg_size);
0196 
0197 static struct attribute *ap_card_dev_attrs[] = {
0198     &dev_attr_hwtype.attr,
0199     &dev_attr_raw_hwtype.attr,
0200     &dev_attr_depth.attr,
0201     &dev_attr_ap_functions.attr,
0202     &dev_attr_request_count.attr,
0203     &dev_attr_requestq_count.attr,
0204     &dev_attr_pendingq_count.attr,
0205     &dev_attr_modalias.attr,
0206     &dev_attr_config.attr,
0207     &dev_attr_chkstop.attr,
0208     &dev_attr_max_msg_size.attr,
0209     NULL
0210 };
0211 
0212 static struct attribute_group ap_card_dev_attr_group = {
0213     .attrs = ap_card_dev_attrs
0214 };
0215 
0216 static const struct attribute_group *ap_card_dev_attr_groups[] = {
0217     &ap_card_dev_attr_group,
0218     NULL
0219 };
0220 
0221 static struct device_type ap_card_type = {
0222     .name = "ap_card",
0223     .groups = ap_card_dev_attr_groups,
0224 };
0225 
0226 static void ap_card_device_release(struct device *dev)
0227 {
0228     struct ap_card *ac = to_ap_card(dev);
0229 
0230     kfree(ac);
0231 }
0232 
0233 struct ap_card *ap_card_create(int id, int queue_depth, int raw_type,
0234                    int comp_type, unsigned int functions, int ml)
0235 {
0236     struct ap_card *ac;
0237 
0238     ac = kzalloc(sizeof(*ac), GFP_KERNEL);
0239     if (!ac)
0240         return NULL;
0241     ac->ap_dev.device.release = ap_card_device_release;
0242     ac->ap_dev.device.type = &ap_card_type;
0243     ac->ap_dev.device_type = comp_type;
0244     ac->raw_hwtype = raw_type;
0245     ac->queue_depth = queue_depth;
0246     ac->functions = functions;
0247     ac->id = id;
0248     ac->maxmsgsize = ml > 0 ?
0249         ml * AP_TAPQ_ML_FIELD_CHUNK_SIZE : AP_DEFAULT_MAX_MSG_SIZE;
0250 
0251     return ac;
0252 }