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