GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / char / pcmcia / scr24x_cs.c
1 /*
2  * SCR24x PCMCIA Smart Card Reader Driver
3  *
4  * Copyright (C) 2005-2006 TL Sudheendran
5  * Copyright (C) 2016 Lubomir Rintel
6  *
7  * Derived from "scr24x_v4.2.6_Release.tar.gz" driver by TL Sudheendran.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2, or (at your option)
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; see the file COPYING.  If not, write to
21  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #include <linux/device.h>
25 #include <linux/module.h>
26 #include <linux/delay.h>
27 #include <linux/cdev.h>
28 #include <linux/slab.h>
29 #include <linux/fs.h>
30 #include <linux/io.h>
31 #include <linux/uaccess.h>
32
33 #include <pcmcia/cistpl.h>
34 #include <pcmcia/ds.h>
35
36 #define CCID_HEADER_SIZE        10
37 #define CCID_LENGTH_OFFSET      1
38 #define CCID_MAX_LEN            271
39
40 #define SCR24X_DATA(n)          (1 + n)
41 #define SCR24X_CMD_STATUS       7
42 #define CMD_START               0x40
43 #define CMD_WRITE_BYTE          0x41
44 #define CMD_READ_BYTE           0x42
45 #define STATUS_BUSY             0x80
46
47 struct scr24x_dev {
48         struct device *dev;
49         struct cdev c_dev;
50         unsigned char buf[CCID_MAX_LEN];
51         int devno;
52         struct mutex lock;
53         struct kref refcnt;
54         u8 __iomem *regs;
55 };
56
57 #define SCR24X_DEVS 8
58 static DECLARE_BITMAP(scr24x_minors, SCR24X_DEVS);
59
60 static struct class *scr24x_class;
61 static dev_t scr24x_devt;
62
63 static void scr24x_delete(struct kref *kref)
64 {
65         struct scr24x_dev *dev = container_of(kref, struct scr24x_dev,
66                                                                 refcnt);
67
68         kfree(dev);
69 }
70
71 static int scr24x_wait_ready(struct scr24x_dev *dev)
72 {
73         u_char status;
74         int timeout = 100;
75
76         do {
77                 status = ioread8(dev->regs + SCR24X_CMD_STATUS);
78                 if (!(status & STATUS_BUSY))
79                         return 0;
80
81                 msleep(20);
82         } while (--timeout);
83
84         return -EIO;
85 }
86
87 static int scr24x_open(struct inode *inode, struct file *filp)
88 {
89         struct scr24x_dev *dev = container_of(inode->i_cdev,
90                                 struct scr24x_dev, c_dev);
91
92         kref_get(&dev->refcnt);
93         filp->private_data = dev;
94
95         return nonseekable_open(inode, filp);
96 }
97
98 static int scr24x_release(struct inode *inode, struct file *filp)
99 {
100         struct scr24x_dev *dev = filp->private_data;
101
102         /* We must not take the dev->lock here as scr24x_delete()
103          * might be called to remove the dev structure altogether.
104          * We don't need the lock anyway, since after the reference
105          * acquired in probe() is released in remove() the chrdev
106          * is already unregistered and noone can possibly acquire
107          * a reference via open() anymore. */
108         kref_put(&dev->refcnt, scr24x_delete);
109         return 0;
110 }
111
112 static int read_chunk(struct scr24x_dev *dev, size_t offset, size_t limit)
113 {
114         size_t i, y;
115         int ret;
116
117         for (i = offset; i < limit; i += 5) {
118                 iowrite8(CMD_READ_BYTE, dev->regs + SCR24X_CMD_STATUS);
119                 ret = scr24x_wait_ready(dev);
120                 if (ret < 0)
121                         return ret;
122
123                 for (y = 0; y < 5 && i + y < limit; y++)
124                         dev->buf[i + y] = ioread8(dev->regs + SCR24X_DATA(y));
125         }
126
127         return 0;
128 }
129
130 static ssize_t scr24x_read(struct file *filp, char __user *buf, size_t count,
131                                                                 loff_t *ppos)
132 {
133         struct scr24x_dev *dev = filp->private_data;
134         int ret;
135         int len;
136
137         if (count < CCID_HEADER_SIZE)
138                 return -EINVAL;
139
140         if (mutex_lock_interruptible(&dev->lock))
141                 return -ERESTARTSYS;
142
143         if (!dev->dev) {
144                 ret = -ENODEV;
145                 goto out;
146         }
147
148         ret = scr24x_wait_ready(dev);
149         if (ret < 0)
150                 goto out;
151         len = CCID_HEADER_SIZE;
152         ret = read_chunk(dev, 0, len);
153         if (ret < 0)
154                 goto out;
155
156         len += le32_to_cpu(*(__le32 *)(&dev->buf[CCID_LENGTH_OFFSET]));
157         if (len > sizeof(dev->buf)) {
158                 ret = -EIO;
159                 goto out;
160         }
161         ret = read_chunk(dev, CCID_HEADER_SIZE, len);
162         if (ret < 0)
163                 goto out;
164
165         if (len < count)
166                 count = len;
167
168         if (copy_to_user(buf, dev->buf, count)) {
169                 ret = -EFAULT;
170                 goto out;
171         }
172
173         ret = count;
174 out:
175         mutex_unlock(&dev->lock);
176         return ret;
177 }
178
179 static ssize_t scr24x_write(struct file *filp, const char __user *buf,
180                                         size_t count, loff_t *ppos)
181 {
182         struct scr24x_dev *dev = filp->private_data;
183         size_t i, y;
184         int ret;
185
186         if (mutex_lock_interruptible(&dev->lock))
187                 return -ERESTARTSYS;
188
189         if (!dev->dev) {
190                 ret = -ENODEV;
191                 goto out;
192         }
193
194         if (count > sizeof(dev->buf)) {
195                 ret = -EINVAL;
196                 goto out;
197         }
198
199         if (copy_from_user(dev->buf, buf, count)) {
200                 ret = -EFAULT;
201                 goto out;
202         }
203
204         ret = scr24x_wait_ready(dev);
205         if (ret < 0)
206                 goto out;
207
208         iowrite8(CMD_START, dev->regs + SCR24X_CMD_STATUS);
209         ret = scr24x_wait_ready(dev);
210         if (ret < 0)
211                 goto out;
212
213         for (i = 0; i < count; i += 5) {
214                 for (y = 0; y < 5 && i + y < count; y++)
215                         iowrite8(dev->buf[i + y], dev->regs + SCR24X_DATA(y));
216
217                 iowrite8(CMD_WRITE_BYTE, dev->regs + SCR24X_CMD_STATUS);
218                 ret = scr24x_wait_ready(dev);
219                 if (ret < 0)
220                         goto out;
221         }
222
223         ret = count;
224 out:
225         mutex_unlock(&dev->lock);
226         return ret;
227 }
228
229 static const struct file_operations scr24x_fops = {
230         .owner          = THIS_MODULE,
231         .read           = scr24x_read,
232         .write          = scr24x_write,
233         .open           = scr24x_open,
234         .release        = scr24x_release,
235         .llseek         = no_llseek,
236 };
237
238 static int scr24x_config_check(struct pcmcia_device *link, void *priv_data)
239 {
240         if (resource_size(link->resource[PCMCIA_IOPORT_0]) != 0x11)
241                 return -ENODEV;
242         return pcmcia_request_io(link);
243 }
244
245 static int scr24x_probe(struct pcmcia_device *link)
246 {
247         struct scr24x_dev *dev;
248         int ret;
249
250         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
251         if (!dev)
252                 return -ENOMEM;
253
254         dev->devno = find_first_zero_bit(scr24x_minors, SCR24X_DEVS);
255         if (dev->devno >= SCR24X_DEVS) {
256                 ret = -EBUSY;
257                 goto err;
258         }
259
260         mutex_init(&dev->lock);
261         kref_init(&dev->refcnt);
262
263         link->priv = dev;
264         link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
265
266         ret = pcmcia_loop_config(link, scr24x_config_check, NULL);
267         if (ret < 0)
268                 goto err;
269
270         dev->dev = &link->dev;
271         dev->regs = devm_ioport_map(&link->dev,
272                                 link->resource[PCMCIA_IOPORT_0]->start,
273                                 resource_size(link->resource[PCMCIA_IOPORT_0]));
274         if (!dev->regs) {
275                 ret = -EIO;
276                 goto err;
277         }
278
279         cdev_init(&dev->c_dev, &scr24x_fops);
280         dev->c_dev.owner = THIS_MODULE;
281         dev->c_dev.ops = &scr24x_fops;
282         ret = cdev_add(&dev->c_dev, MKDEV(MAJOR(scr24x_devt), dev->devno), 1);
283         if (ret < 0)
284                 goto err;
285
286         ret = pcmcia_enable_device(link);
287         if (ret < 0) {
288                 pcmcia_disable_device(link);
289                 goto err;
290         }
291
292         device_create(scr24x_class, NULL, MKDEV(MAJOR(scr24x_devt), dev->devno),
293                       NULL, "scr24x%d", dev->devno);
294
295         dev_info(&link->dev, "SCR24x Chip Card Interface\n");
296         return 0;
297
298 err:
299         if (dev->devno < SCR24X_DEVS)
300                 clear_bit(dev->devno, scr24x_minors);
301         kfree (dev);
302         return ret;
303 }
304
305 static void scr24x_remove(struct pcmcia_device *link)
306 {
307         struct scr24x_dev *dev = (struct scr24x_dev *)link->priv;
308
309         device_destroy(scr24x_class, MKDEV(MAJOR(scr24x_devt), dev->devno));
310         mutex_lock(&dev->lock);
311         pcmcia_disable_device(link);
312         cdev_del(&dev->c_dev);
313         clear_bit(dev->devno, scr24x_minors);
314         dev->dev = NULL;
315         mutex_unlock(&dev->lock);
316
317         kref_put(&dev->refcnt, scr24x_delete);
318 }
319
320 static const struct pcmcia_device_id scr24x_ids[] = {
321         PCMCIA_DEVICE_PROD_ID12("HP", "PC Card Smart Card Reader",
322                                         0x53cb94f9, 0xbfdf89a5),
323         PCMCIA_DEVICE_PROD_ID1("SCR241 PCMCIA", 0x6271efa3),
324         PCMCIA_DEVICE_PROD_ID1("SCR243 PCMCIA", 0x2054e8de),
325         PCMCIA_DEVICE_PROD_ID1("SCR24x PCMCIA", 0x54a33665),
326         PCMCIA_DEVICE_NULL
327 };
328 MODULE_DEVICE_TABLE(pcmcia, scr24x_ids);
329
330 static struct pcmcia_driver scr24x_driver = {
331         .owner          = THIS_MODULE,
332         .name           = "scr24x_cs",
333         .probe          = scr24x_probe,
334         .remove         = scr24x_remove,
335         .id_table       = scr24x_ids,
336 };
337
338 static int __init scr24x_init(void)
339 {
340         int ret;
341
342         scr24x_class = class_create(THIS_MODULE, "scr24x");
343         if (IS_ERR(scr24x_class))
344                 return PTR_ERR(scr24x_class);
345
346         ret = alloc_chrdev_region(&scr24x_devt, 0, SCR24X_DEVS, "scr24x");
347         if (ret < 0)  {
348                 class_destroy(scr24x_class);
349                 return ret;
350         }
351
352         ret = pcmcia_register_driver(&scr24x_driver);
353         if (ret < 0) {
354                 unregister_chrdev_region(scr24x_devt, SCR24X_DEVS);
355                 class_destroy(scr24x_class);
356         }
357
358         return ret;
359 }
360
361 static void __exit scr24x_exit(void)
362 {
363         pcmcia_unregister_driver(&scr24x_driver);
364         unregister_chrdev_region(scr24x_devt, SCR24X_DEVS);
365         class_destroy(scr24x_class);
366 }
367
368 module_init(scr24x_init);
369 module_exit(scr24x_exit);
370
371 MODULE_AUTHOR("Lubomir Rintel");
372 MODULE_DESCRIPTION("SCR24x PCMCIA Smart Card Reader Driver");
373 MODULE_LICENSE("GPL");