xref: /linux/drivers/s390/crypto/zcrypt_card.c (revision 40501c70e3f09e8018bf08457502a3a7b2d5a406)
1812141a9SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0+
2e28d2af4SIngo Tuchscherer /*
3e28d2af4SIngo Tuchscherer  *  Copyright IBM Corp. 2001, 2012
4e28d2af4SIngo Tuchscherer  *  Author(s): Robert Burroughs
5e28d2af4SIngo Tuchscherer  *	       Eric Rossman (edrossma@us.ibm.com)
6e28d2af4SIngo Tuchscherer  *	       Cornelia Huck <cornelia.huck@de.ibm.com>
7e28d2af4SIngo Tuchscherer  *
8e28d2af4SIngo Tuchscherer  *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
9e28d2af4SIngo Tuchscherer  *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
10e28d2af4SIngo Tuchscherer  *				  Ralph Wuerthner <rwuerthn@de.ibm.com>
11e28d2af4SIngo Tuchscherer  *  MSGTYPE restruct:		  Holger Dengler <hd@linux.vnet.ibm.com>
12e28d2af4SIngo Tuchscherer  */
13e28d2af4SIngo Tuchscherer 
14e28d2af4SIngo Tuchscherer #include <linux/module.h>
15e28d2af4SIngo Tuchscherer #include <linux/init.h>
16e28d2af4SIngo Tuchscherer #include <linux/interrupt.h>
17e28d2af4SIngo Tuchscherer #include <linux/miscdevice.h>
18e28d2af4SIngo Tuchscherer #include <linux/fs.h>
19e28d2af4SIngo Tuchscherer #include <linux/proc_fs.h>
20e28d2af4SIngo Tuchscherer #include <linux/seq_file.h>
21e28d2af4SIngo Tuchscherer #include <linux/compat.h>
22e28d2af4SIngo Tuchscherer #include <linux/slab.h>
23e28d2af4SIngo Tuchscherer #include <linux/atomic.h>
24e28d2af4SIngo Tuchscherer #include <linux/uaccess.h>
25e28d2af4SIngo Tuchscherer #include <linux/hw_random.h>
26e28d2af4SIngo Tuchscherer #include <linux/debugfs.h>
27e28d2af4SIngo Tuchscherer #include <asm/debug.h>
28e28d2af4SIngo Tuchscherer 
29e28d2af4SIngo Tuchscherer #include "zcrypt_debug.h"
30e28d2af4SIngo Tuchscherer #include "zcrypt_api.h"
31e28d2af4SIngo Tuchscherer 
32e28d2af4SIngo Tuchscherer #include "zcrypt_msgtype6.h"
33e28d2af4SIngo Tuchscherer #include "zcrypt_msgtype50.h"
34e28d2af4SIngo Tuchscherer 
35e28d2af4SIngo Tuchscherer /*
36e28d2af4SIngo Tuchscherer  * Device attributes common for all crypto card devices.
37e28d2af4SIngo Tuchscherer  */
38e28d2af4SIngo Tuchscherer 
39ac2b96f3SHarald Freudenberger static ssize_t type_show(struct device *dev,
40e28d2af4SIngo Tuchscherer 			 struct device_attribute *attr, char *buf)
41e28d2af4SIngo Tuchscherer {
42e28d2af4SIngo Tuchscherer 	struct zcrypt_card *zc = to_ap_card(dev)->private;
43e28d2af4SIngo Tuchscherer 
44*40501c70SHarald Freudenberger 	return scnprintf(buf, PAGE_SIZE, "%s\n", zc->type_string);
45e28d2af4SIngo Tuchscherer }
46e28d2af4SIngo Tuchscherer 
47ac2b96f3SHarald Freudenberger static DEVICE_ATTR_RO(type);
48e28d2af4SIngo Tuchscherer 
49ac2b96f3SHarald Freudenberger static ssize_t online_show(struct device *dev,
50e28d2af4SIngo Tuchscherer 			   struct device_attribute *attr,
51e28d2af4SIngo Tuchscherer 			   char *buf)
52e28d2af4SIngo Tuchscherer {
53e28d2af4SIngo Tuchscherer 	struct zcrypt_card *zc = to_ap_card(dev)->private;
54e28d2af4SIngo Tuchscherer 
55*40501c70SHarald Freudenberger 	return scnprintf(buf, PAGE_SIZE, "%d\n", zc->online);
56e28d2af4SIngo Tuchscherer }
57e28d2af4SIngo Tuchscherer 
58ac2b96f3SHarald Freudenberger static ssize_t online_store(struct device *dev,
59e28d2af4SIngo Tuchscherer 			    struct device_attribute *attr,
60e28d2af4SIngo Tuchscherer 			    const char *buf, size_t count)
61e28d2af4SIngo Tuchscherer {
62e28d2af4SIngo Tuchscherer 	struct zcrypt_card *zc = to_ap_card(dev)->private;
63e28d2af4SIngo Tuchscherer 	struct zcrypt_queue *zq;
64e28d2af4SIngo Tuchscherer 	int online, id;
65e28d2af4SIngo Tuchscherer 
66e28d2af4SIngo Tuchscherer 	if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1)
67e28d2af4SIngo Tuchscherer 		return -EINVAL;
68e28d2af4SIngo Tuchscherer 
69e28d2af4SIngo Tuchscherer 	zc->online = online;
70e28d2af4SIngo Tuchscherer 	id = zc->card->id;
71cccd85bfSHarald Freudenberger 
72cccd85bfSHarald Freudenberger 	ZCRYPT_DBF(DBF_INFO, "card=%02x online=%d\n", id, online);
73cccd85bfSHarald Freudenberger 
74e28d2af4SIngo Tuchscherer 	spin_lock(&zcrypt_list_lock);
75e28d2af4SIngo Tuchscherer 	list_for_each_entry(zq, &zc->zqueues, list)
76e28d2af4SIngo Tuchscherer 		zcrypt_queue_force_online(zq, online);
77e28d2af4SIngo Tuchscherer 	spin_unlock(&zcrypt_list_lock);
78e28d2af4SIngo Tuchscherer 	return count;
79e28d2af4SIngo Tuchscherer }
80e28d2af4SIngo Tuchscherer 
81ac2b96f3SHarald Freudenberger static DEVICE_ATTR_RW(online);
82e28d2af4SIngo Tuchscherer 
83ac2b96f3SHarald Freudenberger static ssize_t load_show(struct device *dev,
844a07750bSHarald Freudenberger 			 struct device_attribute *attr,
854a07750bSHarald Freudenberger 			 char *buf)
864a07750bSHarald Freudenberger {
874a07750bSHarald Freudenberger 	struct zcrypt_card *zc = to_ap_card(dev)->private;
884a07750bSHarald Freudenberger 
89*40501c70SHarald Freudenberger 	return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&zc->load));
904a07750bSHarald Freudenberger }
914a07750bSHarald Freudenberger 
92ac2b96f3SHarald Freudenberger static DEVICE_ATTR_RO(load);
934a07750bSHarald Freudenberger 
94e28d2af4SIngo Tuchscherer static struct attribute *zcrypt_card_attrs[] = {
95e28d2af4SIngo Tuchscherer 	&dev_attr_type.attr,
96e28d2af4SIngo Tuchscherer 	&dev_attr_online.attr,
974a07750bSHarald Freudenberger 	&dev_attr_load.attr,
98e28d2af4SIngo Tuchscherer 	NULL,
99e28d2af4SIngo Tuchscherer };
100e28d2af4SIngo Tuchscherer 
1019731c0a9SArvind Yadav static const struct attribute_group zcrypt_card_attr_group = {
102e28d2af4SIngo Tuchscherer 	.attrs = zcrypt_card_attrs,
103e28d2af4SIngo Tuchscherer };
104e28d2af4SIngo Tuchscherer 
105e28d2af4SIngo Tuchscherer struct zcrypt_card *zcrypt_card_alloc(void)
106e28d2af4SIngo Tuchscherer {
107e28d2af4SIngo Tuchscherer 	struct zcrypt_card *zc;
108e28d2af4SIngo Tuchscherer 
109e28d2af4SIngo Tuchscherer 	zc = kzalloc(sizeof(struct zcrypt_card), GFP_KERNEL);
110e28d2af4SIngo Tuchscherer 	if (!zc)
111e28d2af4SIngo Tuchscherer 		return NULL;
112e28d2af4SIngo Tuchscherer 	INIT_LIST_HEAD(&zc->list);
113e28d2af4SIngo Tuchscherer 	INIT_LIST_HEAD(&zc->zqueues);
114e28d2af4SIngo Tuchscherer 	kref_init(&zc->refcount);
115e28d2af4SIngo Tuchscherer 	return zc;
116e28d2af4SIngo Tuchscherer }
117e28d2af4SIngo Tuchscherer EXPORT_SYMBOL(zcrypt_card_alloc);
118e28d2af4SIngo Tuchscherer 
119e28d2af4SIngo Tuchscherer void zcrypt_card_free(struct zcrypt_card *zc)
120e28d2af4SIngo Tuchscherer {
121e28d2af4SIngo Tuchscherer 	kfree(zc);
122e28d2af4SIngo Tuchscherer }
123e28d2af4SIngo Tuchscherer EXPORT_SYMBOL(zcrypt_card_free);
124e28d2af4SIngo Tuchscherer 
125e28d2af4SIngo Tuchscherer static void zcrypt_card_release(struct kref *kref)
126e28d2af4SIngo Tuchscherer {
127e28d2af4SIngo Tuchscherer 	struct zcrypt_card *zdev =
128e28d2af4SIngo Tuchscherer 		container_of(kref, struct zcrypt_card, refcount);
129e28d2af4SIngo Tuchscherer 	zcrypt_card_free(zdev);
130e28d2af4SIngo Tuchscherer }
131e28d2af4SIngo Tuchscherer 
132e28d2af4SIngo Tuchscherer void zcrypt_card_get(struct zcrypt_card *zc)
133e28d2af4SIngo Tuchscherer {
134e28d2af4SIngo Tuchscherer 	kref_get(&zc->refcount);
135e28d2af4SIngo Tuchscherer }
136e28d2af4SIngo Tuchscherer EXPORT_SYMBOL(zcrypt_card_get);
137e28d2af4SIngo Tuchscherer 
138e28d2af4SIngo Tuchscherer int zcrypt_card_put(struct zcrypt_card *zc)
139e28d2af4SIngo Tuchscherer {
140e28d2af4SIngo Tuchscherer 	return kref_put(&zc->refcount, zcrypt_card_release);
141e28d2af4SIngo Tuchscherer }
142e28d2af4SIngo Tuchscherer EXPORT_SYMBOL(zcrypt_card_put);
143e28d2af4SIngo Tuchscherer 
144e28d2af4SIngo Tuchscherer /**
145e28d2af4SIngo Tuchscherer  * zcrypt_card_register() - Register a crypto card device.
146e28d2af4SIngo Tuchscherer  * @zc: Pointer to a crypto card device
147e28d2af4SIngo Tuchscherer  *
148e28d2af4SIngo Tuchscherer  * Register a crypto card device. Returns 0 if successful.
149e28d2af4SIngo Tuchscherer  */
150e28d2af4SIngo Tuchscherer int zcrypt_card_register(struct zcrypt_card *zc)
151e28d2af4SIngo Tuchscherer {
152e28d2af4SIngo Tuchscherer 	int rc;
153e28d2af4SIngo Tuchscherer 
154e28d2af4SIngo Tuchscherer 	rc = sysfs_create_group(&zc->card->ap_dev.device.kobj,
155e28d2af4SIngo Tuchscherer 				&zcrypt_card_attr_group);
156e28d2af4SIngo Tuchscherer 	if (rc)
157e28d2af4SIngo Tuchscherer 		return rc;
158e28d2af4SIngo Tuchscherer 
159e28d2af4SIngo Tuchscherer 	spin_lock(&zcrypt_list_lock);
160e28d2af4SIngo Tuchscherer 	list_add_tail(&zc->list, &zcrypt_card_list);
161e28d2af4SIngo Tuchscherer 	spin_unlock(&zcrypt_list_lock);
162e28d2af4SIngo Tuchscherer 
163e28d2af4SIngo Tuchscherer 	zc->online = 1;
164cccd85bfSHarald Freudenberger 
165cccd85bfSHarald Freudenberger 	ZCRYPT_DBF(DBF_INFO, "card=%02x register online=1\n", zc->card->id);
166cccd85bfSHarald Freudenberger 
167e28d2af4SIngo Tuchscherer 	return rc;
168e28d2af4SIngo Tuchscherer }
169e28d2af4SIngo Tuchscherer EXPORT_SYMBOL(zcrypt_card_register);
170e28d2af4SIngo Tuchscherer 
171e28d2af4SIngo Tuchscherer /**
172e28d2af4SIngo Tuchscherer  * zcrypt_card_unregister(): Unregister a crypto card device.
173e28d2af4SIngo Tuchscherer  * @zc: Pointer to crypto card device
174e28d2af4SIngo Tuchscherer  *
175e28d2af4SIngo Tuchscherer  * Unregister a crypto card device.
176e28d2af4SIngo Tuchscherer  */
177e28d2af4SIngo Tuchscherer void zcrypt_card_unregister(struct zcrypt_card *zc)
178e28d2af4SIngo Tuchscherer {
179cccd85bfSHarald Freudenberger 	ZCRYPT_DBF(DBF_INFO, "card=%02x unregister\n", zc->card->id);
180cccd85bfSHarald Freudenberger 
181e28d2af4SIngo Tuchscherer 	spin_lock(&zcrypt_list_lock);
182e28d2af4SIngo Tuchscherer 	list_del_init(&zc->list);
183e28d2af4SIngo Tuchscherer 	spin_unlock(&zcrypt_list_lock);
184e28d2af4SIngo Tuchscherer 	sysfs_remove_group(&zc->card->ap_dev.device.kobj,
185e28d2af4SIngo Tuchscherer 			   &zcrypt_card_attr_group);
186e28d2af4SIngo Tuchscherer }
187e28d2af4SIngo Tuchscherer EXPORT_SYMBOL(zcrypt_card_unregister);
188