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