xref: /linux/drivers/s390/crypto/zcrypt_card.c (revision 812141a9fe61446c948a71456c58090ac11a6d14)
1*812141a9SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0+
2e28d2af4SIngo Tuchscherer /*
3e28d2af4SIngo Tuchscherer  *  zcrypt 2.1.0
4e28d2af4SIngo Tuchscherer  *
5e28d2af4SIngo Tuchscherer  *  Copyright IBM Corp. 2001, 2012
6e28d2af4SIngo Tuchscherer  *  Author(s): Robert Burroughs
7e28d2af4SIngo Tuchscherer  *	       Eric Rossman (edrossma@us.ibm.com)
8e28d2af4SIngo Tuchscherer  *	       Cornelia Huck <cornelia.huck@de.ibm.com>
9e28d2af4SIngo Tuchscherer  *
10e28d2af4SIngo Tuchscherer  *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11e28d2af4SIngo Tuchscherer  *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12e28d2af4SIngo Tuchscherer  *				  Ralph Wuerthner <rwuerthn@de.ibm.com>
13e28d2af4SIngo Tuchscherer  *  MSGTYPE restruct:		  Holger Dengler <hd@linux.vnet.ibm.com>
14e28d2af4SIngo Tuchscherer  *
15e28d2af4SIngo Tuchscherer  * This program is free software; you can redistribute it and/or modify
16e28d2af4SIngo Tuchscherer  * it under the terms of the GNU General Public License as published by
17e28d2af4SIngo Tuchscherer  * the Free Software Foundation; either version 2, or (at your option)
18e28d2af4SIngo Tuchscherer  * any later version.
19e28d2af4SIngo Tuchscherer  *
20e28d2af4SIngo Tuchscherer  * This program is distributed in the hope that it will be useful,
21e28d2af4SIngo Tuchscherer  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22e28d2af4SIngo Tuchscherer  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23e28d2af4SIngo Tuchscherer  * GNU General Public License for more details.
24e28d2af4SIngo Tuchscherer  */
25e28d2af4SIngo Tuchscherer 
26e28d2af4SIngo Tuchscherer #include <linux/module.h>
27e28d2af4SIngo Tuchscherer #include <linux/init.h>
28e28d2af4SIngo Tuchscherer #include <linux/interrupt.h>
29e28d2af4SIngo Tuchscherer #include <linux/miscdevice.h>
30e28d2af4SIngo Tuchscherer #include <linux/fs.h>
31e28d2af4SIngo Tuchscherer #include <linux/proc_fs.h>
32e28d2af4SIngo Tuchscherer #include <linux/seq_file.h>
33e28d2af4SIngo Tuchscherer #include <linux/compat.h>
34e28d2af4SIngo Tuchscherer #include <linux/slab.h>
35e28d2af4SIngo Tuchscherer #include <linux/atomic.h>
36e28d2af4SIngo Tuchscherer #include <linux/uaccess.h>
37e28d2af4SIngo Tuchscherer #include <linux/hw_random.h>
38e28d2af4SIngo Tuchscherer #include <linux/debugfs.h>
39e28d2af4SIngo Tuchscherer #include <asm/debug.h>
40e28d2af4SIngo Tuchscherer 
41e28d2af4SIngo Tuchscherer #include "zcrypt_debug.h"
42e28d2af4SIngo Tuchscherer #include "zcrypt_api.h"
43e28d2af4SIngo Tuchscherer 
44e28d2af4SIngo Tuchscherer #include "zcrypt_msgtype6.h"
45e28d2af4SIngo Tuchscherer #include "zcrypt_msgtype50.h"
46e28d2af4SIngo Tuchscherer 
47e28d2af4SIngo Tuchscherer /*
48e28d2af4SIngo Tuchscherer  * Device attributes common for all crypto card devices.
49e28d2af4SIngo Tuchscherer  */
50e28d2af4SIngo Tuchscherer 
51e28d2af4SIngo Tuchscherer static ssize_t zcrypt_card_type_show(struct device *dev,
52e28d2af4SIngo Tuchscherer 				     struct device_attribute *attr, char *buf)
53e28d2af4SIngo Tuchscherer {
54e28d2af4SIngo Tuchscherer 	struct zcrypt_card *zc = to_ap_card(dev)->private;
55e28d2af4SIngo Tuchscherer 
56e28d2af4SIngo Tuchscherer 	return snprintf(buf, PAGE_SIZE, "%s\n", zc->type_string);
57e28d2af4SIngo Tuchscherer }
58e28d2af4SIngo Tuchscherer 
59e28d2af4SIngo Tuchscherer static DEVICE_ATTR(type, 0444, zcrypt_card_type_show, NULL);
60e28d2af4SIngo Tuchscherer 
61e28d2af4SIngo Tuchscherer static ssize_t zcrypt_card_online_show(struct device *dev,
62e28d2af4SIngo Tuchscherer 				       struct device_attribute *attr,
63e28d2af4SIngo Tuchscherer 				       char *buf)
64e28d2af4SIngo Tuchscherer {
65e28d2af4SIngo Tuchscherer 	struct zcrypt_card *zc = to_ap_card(dev)->private;
66e28d2af4SIngo Tuchscherer 
67e28d2af4SIngo Tuchscherer 	return snprintf(buf, PAGE_SIZE, "%d\n", zc->online);
68e28d2af4SIngo Tuchscherer }
69e28d2af4SIngo Tuchscherer 
70e28d2af4SIngo Tuchscherer static ssize_t zcrypt_card_online_store(struct device *dev,
71e28d2af4SIngo Tuchscherer 					struct device_attribute *attr,
72e28d2af4SIngo Tuchscherer 					const char *buf, size_t count)
73e28d2af4SIngo Tuchscherer {
74e28d2af4SIngo Tuchscherer 	struct zcrypt_card *zc = to_ap_card(dev)->private;
75e28d2af4SIngo Tuchscherer 	struct zcrypt_queue *zq;
76e28d2af4SIngo Tuchscherer 	int online, id;
77e28d2af4SIngo Tuchscherer 
78e28d2af4SIngo Tuchscherer 	if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1)
79e28d2af4SIngo Tuchscherer 		return -EINVAL;
80e28d2af4SIngo Tuchscherer 
81e28d2af4SIngo Tuchscherer 	zc->online = online;
82e28d2af4SIngo Tuchscherer 	id = zc->card->id;
83cccd85bfSHarald Freudenberger 
84cccd85bfSHarald Freudenberger 	ZCRYPT_DBF(DBF_INFO, "card=%02x online=%d\n", id, online);
85cccd85bfSHarald Freudenberger 
86e28d2af4SIngo Tuchscherer 	spin_lock(&zcrypt_list_lock);
87e28d2af4SIngo Tuchscherer 	list_for_each_entry(zq, &zc->zqueues, list)
88e28d2af4SIngo Tuchscherer 		zcrypt_queue_force_online(zq, online);
89e28d2af4SIngo Tuchscherer 	spin_unlock(&zcrypt_list_lock);
90e28d2af4SIngo Tuchscherer 	return count;
91e28d2af4SIngo Tuchscherer }
92e28d2af4SIngo Tuchscherer 
93e28d2af4SIngo Tuchscherer static DEVICE_ATTR(online, 0644, zcrypt_card_online_show,
94e28d2af4SIngo Tuchscherer 		   zcrypt_card_online_store);
95e28d2af4SIngo Tuchscherer 
96e28d2af4SIngo Tuchscherer static struct attribute *zcrypt_card_attrs[] = {
97e28d2af4SIngo Tuchscherer 	&dev_attr_type.attr,
98e28d2af4SIngo Tuchscherer 	&dev_attr_online.attr,
99e28d2af4SIngo Tuchscherer 	NULL,
100e28d2af4SIngo Tuchscherer };
101e28d2af4SIngo Tuchscherer 
1029731c0a9SArvind Yadav static const struct attribute_group zcrypt_card_attr_group = {
103e28d2af4SIngo Tuchscherer 	.attrs = zcrypt_card_attrs,
104e28d2af4SIngo Tuchscherer };
105e28d2af4SIngo Tuchscherer 
106e28d2af4SIngo Tuchscherer struct zcrypt_card *zcrypt_card_alloc(void)
107e28d2af4SIngo Tuchscherer {
108e28d2af4SIngo Tuchscherer 	struct zcrypt_card *zc;
109e28d2af4SIngo Tuchscherer 
110e28d2af4SIngo Tuchscherer 	zc = kzalloc(sizeof(struct zcrypt_card), GFP_KERNEL);
111e28d2af4SIngo Tuchscherer 	if (!zc)
112e28d2af4SIngo Tuchscherer 		return NULL;
113e28d2af4SIngo Tuchscherer 	INIT_LIST_HEAD(&zc->list);
114e28d2af4SIngo Tuchscherer 	INIT_LIST_HEAD(&zc->zqueues);
115e28d2af4SIngo Tuchscherer 	kref_init(&zc->refcount);
116e28d2af4SIngo Tuchscherer 	return zc;
117e28d2af4SIngo Tuchscherer }
118e28d2af4SIngo Tuchscherer EXPORT_SYMBOL(zcrypt_card_alloc);
119e28d2af4SIngo Tuchscherer 
120e28d2af4SIngo Tuchscherer void zcrypt_card_free(struct zcrypt_card *zc)
121e28d2af4SIngo Tuchscherer {
122e28d2af4SIngo Tuchscherer 	kfree(zc);
123e28d2af4SIngo Tuchscherer }
124e28d2af4SIngo Tuchscherer EXPORT_SYMBOL(zcrypt_card_free);
125e28d2af4SIngo Tuchscherer 
126e28d2af4SIngo Tuchscherer static void zcrypt_card_release(struct kref *kref)
127e28d2af4SIngo Tuchscherer {
128e28d2af4SIngo Tuchscherer 	struct zcrypt_card *zdev =
129e28d2af4SIngo Tuchscherer 		container_of(kref, struct zcrypt_card, refcount);
130e28d2af4SIngo Tuchscherer 	zcrypt_card_free(zdev);
131e28d2af4SIngo Tuchscherer }
132e28d2af4SIngo Tuchscherer 
133e28d2af4SIngo Tuchscherer void zcrypt_card_get(struct zcrypt_card *zc)
134e28d2af4SIngo Tuchscherer {
135e28d2af4SIngo Tuchscherer 	kref_get(&zc->refcount);
136e28d2af4SIngo Tuchscherer }
137e28d2af4SIngo Tuchscherer EXPORT_SYMBOL(zcrypt_card_get);
138e28d2af4SIngo Tuchscherer 
139e28d2af4SIngo Tuchscherer int zcrypt_card_put(struct zcrypt_card *zc)
140e28d2af4SIngo Tuchscherer {
141e28d2af4SIngo Tuchscherer 	return kref_put(&zc->refcount, zcrypt_card_release);
142e28d2af4SIngo Tuchscherer }
143e28d2af4SIngo Tuchscherer EXPORT_SYMBOL(zcrypt_card_put);
144e28d2af4SIngo Tuchscherer 
145e28d2af4SIngo Tuchscherer /**
146e28d2af4SIngo Tuchscherer  * zcrypt_card_register() - Register a crypto card device.
147e28d2af4SIngo Tuchscherer  * @zc: Pointer to a crypto card device
148e28d2af4SIngo Tuchscherer  *
149e28d2af4SIngo Tuchscherer  * Register a crypto card device. Returns 0 if successful.
150e28d2af4SIngo Tuchscherer  */
151e28d2af4SIngo Tuchscherer int zcrypt_card_register(struct zcrypt_card *zc)
152e28d2af4SIngo Tuchscherer {
153e28d2af4SIngo Tuchscherer 	int rc;
154e28d2af4SIngo Tuchscherer 
155e28d2af4SIngo Tuchscherer 	rc = sysfs_create_group(&zc->card->ap_dev.device.kobj,
156e28d2af4SIngo Tuchscherer 				&zcrypt_card_attr_group);
157e28d2af4SIngo Tuchscherer 	if (rc)
158e28d2af4SIngo Tuchscherer 		return rc;
159e28d2af4SIngo Tuchscherer 
160e28d2af4SIngo Tuchscherer 	spin_lock(&zcrypt_list_lock);
161e28d2af4SIngo Tuchscherer 	list_add_tail(&zc->list, &zcrypt_card_list);
162e28d2af4SIngo Tuchscherer 	spin_unlock(&zcrypt_list_lock);
163e28d2af4SIngo Tuchscherer 
164e28d2af4SIngo Tuchscherer 	zc->online = 1;
165cccd85bfSHarald Freudenberger 
166cccd85bfSHarald Freudenberger 	ZCRYPT_DBF(DBF_INFO, "card=%02x register online=1\n", zc->card->id);
167cccd85bfSHarald Freudenberger 
168e28d2af4SIngo Tuchscherer 	return rc;
169e28d2af4SIngo Tuchscherer }
170e28d2af4SIngo Tuchscherer EXPORT_SYMBOL(zcrypt_card_register);
171e28d2af4SIngo Tuchscherer 
172e28d2af4SIngo Tuchscherer /**
173e28d2af4SIngo Tuchscherer  * zcrypt_card_unregister(): Unregister a crypto card device.
174e28d2af4SIngo Tuchscherer  * @zc: Pointer to crypto card device
175e28d2af4SIngo Tuchscherer  *
176e28d2af4SIngo Tuchscherer  * Unregister a crypto card device.
177e28d2af4SIngo Tuchscherer  */
178e28d2af4SIngo Tuchscherer void zcrypt_card_unregister(struct zcrypt_card *zc)
179e28d2af4SIngo Tuchscherer {
180cccd85bfSHarald Freudenberger 	ZCRYPT_DBF(DBF_INFO, "card=%02x unregister\n", zc->card->id);
181cccd85bfSHarald Freudenberger 
182e28d2af4SIngo Tuchscherer 	spin_lock(&zcrypt_list_lock);
183e28d2af4SIngo Tuchscherer 	list_del_init(&zc->list);
184e28d2af4SIngo Tuchscherer 	spin_unlock(&zcrypt_list_lock);
185e28d2af4SIngo Tuchscherer 	sysfs_remove_group(&zc->card->ap_dev.device.kobj,
186e28d2af4SIngo Tuchscherer 			   &zcrypt_card_attr_group);
187e28d2af4SIngo Tuchscherer }
188e28d2af4SIngo Tuchscherer EXPORT_SYMBOL(zcrypt_card_unregister);
189