PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/usb/serial/cyberjack.c

https://github.com/gby/linux
C | 421 lines | 293 code | 81 blank | 47 comment | 28 complexity | d37f90111e462f87caae5088c34b59f5 MD5 | raw file
  1. /*
  2. * REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver
  3. *
  4. * Copyright (C) 2001 REINER SCT
  5. * Author: Matthias Bruestle
  6. *
  7. * Contact: support@reiner-sct.com (see MAINTAINERS)
  8. *
  9. * This program is largely derived from work by the linux-usb group
  10. * and associated source files. Please see the usb/serial files for
  11. * individual credits and copyrights.
  12. *
  13. * This program is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License as published by
  15. * the Free Software Foundation; either version 2 of the License, or
  16. * (at your option) any later version.
  17. *
  18. * Thanks to Greg Kroah-Hartman (greg@kroah.com) for his help and
  19. * patience.
  20. *
  21. * In case of problems, please write to the contact e-mail address
  22. * mentioned above.
  23. *
  24. * Please note that later models of the cyberjack reader family are
  25. * supported by a libusb-based userspace device driver.
  26. *
  27. * Homepage: http://www.reiner-sct.de/support/treiber_cyberjack.php#linux
  28. */
  29. #include <linux/kernel.h>
  30. #include <linux/errno.h>
  31. #include <linux/slab.h>
  32. #include <linux/tty.h>
  33. #include <linux/tty_driver.h>
  34. #include <linux/tty_flip.h>
  35. #include <linux/module.h>
  36. #include <linux/spinlock.h>
  37. #include <linux/uaccess.h>
  38. #include <linux/usb.h>
  39. #include <linux/usb/serial.h>
  40. #define CYBERJACK_LOCAL_BUF_SIZE 32
  41. #define DRIVER_AUTHOR "Matthias Bruestle"
  42. #define DRIVER_DESC "REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver"
  43. #define CYBERJACK_VENDOR_ID 0x0C4B
  44. #define CYBERJACK_PRODUCT_ID 0x0100
  45. /* Function prototypes */
  46. static int cyberjack_port_probe(struct usb_serial_port *port);
  47. static int cyberjack_port_remove(struct usb_serial_port *port);
  48. static int cyberjack_open(struct tty_struct *tty,
  49. struct usb_serial_port *port);
  50. static void cyberjack_close(struct usb_serial_port *port);
  51. static int cyberjack_write(struct tty_struct *tty,
  52. struct usb_serial_port *port, const unsigned char *buf, int count);
  53. static int cyberjack_write_room(struct tty_struct *tty);
  54. static void cyberjack_read_int_callback(struct urb *urb);
  55. static void cyberjack_read_bulk_callback(struct urb *urb);
  56. static void cyberjack_write_bulk_callback(struct urb *urb);
  57. static const struct usb_device_id id_table[] = {
  58. { USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) },
  59. { } /* Terminating entry */
  60. };
  61. MODULE_DEVICE_TABLE(usb, id_table);
  62. static struct usb_serial_driver cyberjack_device = {
  63. .driver = {
  64. .owner = THIS_MODULE,
  65. .name = "cyberjack",
  66. },
  67. .description = "Reiner SCT Cyberjack USB card reader",
  68. .id_table = id_table,
  69. .num_ports = 1,
  70. .num_bulk_out = 1,
  71. .port_probe = cyberjack_port_probe,
  72. .port_remove = cyberjack_port_remove,
  73. .open = cyberjack_open,
  74. .close = cyberjack_close,
  75. .write = cyberjack_write,
  76. .write_room = cyberjack_write_room,
  77. .read_int_callback = cyberjack_read_int_callback,
  78. .read_bulk_callback = cyberjack_read_bulk_callback,
  79. .write_bulk_callback = cyberjack_write_bulk_callback,
  80. };
  81. static struct usb_serial_driver * const serial_drivers[] = {
  82. &cyberjack_device, NULL
  83. };
  84. struct cyberjack_private {
  85. spinlock_t lock; /* Lock for SMP */
  86. short rdtodo; /* Bytes still to read */
  87. unsigned char wrbuf[5*64]; /* Buffer for collecting data to write */
  88. short wrfilled; /* Overall data size we already got */
  89. short wrsent; /* Data already sent */
  90. };
  91. static int cyberjack_port_probe(struct usb_serial_port *port)
  92. {
  93. struct cyberjack_private *priv;
  94. int result;
  95. priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL);
  96. if (!priv)
  97. return -ENOMEM;
  98. spin_lock_init(&priv->lock);
  99. priv->rdtodo = 0;
  100. priv->wrfilled = 0;
  101. priv->wrsent = 0;
  102. usb_set_serial_port_data(port, priv);
  103. result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
  104. if (result)
  105. dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
  106. return 0;
  107. }
  108. static int cyberjack_port_remove(struct usb_serial_port *port)
  109. {
  110. struct cyberjack_private *priv;
  111. usb_kill_urb(port->interrupt_in_urb);
  112. priv = usb_get_serial_port_data(port);
  113. kfree(priv);
  114. return 0;
  115. }
  116. static int cyberjack_open(struct tty_struct *tty,
  117. struct usb_serial_port *port)
  118. {
  119. struct cyberjack_private *priv;
  120. unsigned long flags;
  121. dev_dbg(&port->dev, "%s - usb_clear_halt\n", __func__);
  122. usb_clear_halt(port->serial->dev, port->write_urb->pipe);
  123. priv = usb_get_serial_port_data(port);
  124. spin_lock_irqsave(&priv->lock, flags);
  125. priv->rdtodo = 0;
  126. priv->wrfilled = 0;
  127. priv->wrsent = 0;
  128. spin_unlock_irqrestore(&priv->lock, flags);
  129. return 0;
  130. }
  131. static void cyberjack_close(struct usb_serial_port *port)
  132. {
  133. usb_kill_urb(port->write_urb);
  134. usb_kill_urb(port->read_urb);
  135. }
  136. static int cyberjack_write(struct tty_struct *tty,
  137. struct usb_serial_port *port, const unsigned char *buf, int count)
  138. {
  139. struct device *dev = &port->dev;
  140. struct cyberjack_private *priv = usb_get_serial_port_data(port);
  141. unsigned long flags;
  142. int result;
  143. int wrexpected;
  144. if (count == 0) {
  145. dev_dbg(dev, "%s - write request of 0 bytes\n", __func__);
  146. return 0;
  147. }
  148. if (!test_and_clear_bit(0, &port->write_urbs_free)) {
  149. dev_dbg(dev, "%s - already writing\n", __func__);
  150. return 0;
  151. }
  152. spin_lock_irqsave(&priv->lock, flags);
  153. if (count+priv->wrfilled > sizeof(priv->wrbuf)) {
  154. /* To much data for buffer. Reset buffer. */
  155. priv->wrfilled = 0;
  156. spin_unlock_irqrestore(&priv->lock, flags);
  157. set_bit(0, &port->write_urbs_free);
  158. return 0;
  159. }
  160. /* Copy data */
  161. memcpy(priv->wrbuf + priv->wrfilled, buf, count);
  162. usb_serial_debug_data(dev, __func__, count, priv->wrbuf + priv->wrfilled);
  163. priv->wrfilled += count;
  164. if (priv->wrfilled >= 3) {
  165. wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
  166. dev_dbg(dev, "%s - expected data: %d\n", __func__, wrexpected);
  167. } else
  168. wrexpected = sizeof(priv->wrbuf);
  169. if (priv->wrfilled >= wrexpected) {
  170. /* We have enough data to begin transmission */
  171. int length;
  172. dev_dbg(dev, "%s - transmitting data (frame 1)\n", __func__);
  173. length = (wrexpected > port->bulk_out_size) ?
  174. port->bulk_out_size : wrexpected;
  175. memcpy(port->write_urb->transfer_buffer, priv->wrbuf, length);
  176. priv->wrsent = length;
  177. /* set up our urb */
  178. port->write_urb->transfer_buffer_length = length;
  179. /* send the data out the bulk port */
  180. result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
  181. if (result) {
  182. dev_err(&port->dev,
  183. "%s - failed submitting write urb, error %d\n",
  184. __func__, result);
  185. /* Throw away data. No better idea what to do with it. */
  186. priv->wrfilled = 0;
  187. priv->wrsent = 0;
  188. spin_unlock_irqrestore(&priv->lock, flags);
  189. set_bit(0, &port->write_urbs_free);
  190. return 0;
  191. }
  192. dev_dbg(dev, "%s - priv->wrsent=%d\n", __func__, priv->wrsent);
  193. dev_dbg(dev, "%s - priv->wrfilled=%d\n", __func__, priv->wrfilled);
  194. if (priv->wrsent >= priv->wrfilled) {
  195. dev_dbg(dev, "%s - buffer cleaned\n", __func__);
  196. memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
  197. priv->wrfilled = 0;
  198. priv->wrsent = 0;
  199. }
  200. }
  201. spin_unlock_irqrestore(&priv->lock, flags);
  202. return count;
  203. }
  204. static int cyberjack_write_room(struct tty_struct *tty)
  205. {
  206. /* FIXME: .... */
  207. return CYBERJACK_LOCAL_BUF_SIZE;
  208. }
  209. static void cyberjack_read_int_callback(struct urb *urb)
  210. {
  211. struct usb_serial_port *port = urb->context;
  212. struct cyberjack_private *priv = usb_get_serial_port_data(port);
  213. struct device *dev = &port->dev;
  214. unsigned char *data = urb->transfer_buffer;
  215. int status = urb->status;
  216. int result;
  217. /* the urb might have been killed. */
  218. if (status)
  219. return;
  220. usb_serial_debug_data(dev, __func__, urb->actual_length, data);
  221. /* React only to interrupts signaling a bulk_in transfer */
  222. if (urb->actual_length == 4 && data[0] == 0x01) {
  223. short old_rdtodo;
  224. /* This is a announcement of coming bulk_ins. */
  225. unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3;
  226. spin_lock(&priv->lock);
  227. old_rdtodo = priv->rdtodo;
  228. if (old_rdtodo > SHRT_MAX - size) {
  229. dev_dbg(dev, "To many bulk_in urbs to do.\n");
  230. spin_unlock(&priv->lock);
  231. goto resubmit;
  232. }
  233. /* "+=" is probably more fault tolerant than "=" */
  234. priv->rdtodo += size;
  235. dev_dbg(dev, "%s - rdtodo: %d\n", __func__, priv->rdtodo);
  236. spin_unlock(&priv->lock);
  237. if (!old_rdtodo) {
  238. result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
  239. if (result)
  240. dev_err(dev, "%s - failed resubmitting read urb, error %d\n",
  241. __func__, result);
  242. dev_dbg(dev, "%s - usb_submit_urb(read urb)\n", __func__);
  243. }
  244. }
  245. resubmit:
  246. result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
  247. if (result)
  248. dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
  249. dev_dbg(dev, "%s - usb_submit_urb(int urb)\n", __func__);
  250. }
  251. static void cyberjack_read_bulk_callback(struct urb *urb)
  252. {
  253. struct usb_serial_port *port = urb->context;
  254. struct cyberjack_private *priv = usb_get_serial_port_data(port);
  255. struct device *dev = &port->dev;
  256. unsigned char *data = urb->transfer_buffer;
  257. short todo;
  258. int result;
  259. int status = urb->status;
  260. usb_serial_debug_data(dev, __func__, urb->actual_length, data);
  261. if (status) {
  262. dev_dbg(dev, "%s - nonzero read bulk status received: %d\n",
  263. __func__, status);
  264. return;
  265. }
  266. if (urb->actual_length) {
  267. tty_insert_flip_string(&port->port, data, urb->actual_length);
  268. tty_flip_buffer_push(&port->port);
  269. }
  270. spin_lock(&priv->lock);
  271. /* Reduce urbs to do by one. */
  272. priv->rdtodo -= urb->actual_length;
  273. /* Just to be sure */
  274. if (priv->rdtodo < 0)
  275. priv->rdtodo = 0;
  276. todo = priv->rdtodo;
  277. spin_unlock(&priv->lock);
  278. dev_dbg(dev, "%s - rdtodo: %d\n", __func__, todo);
  279. /* Continue to read if we have still urbs to do. */
  280. if (todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/) {
  281. result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
  282. if (result)
  283. dev_err(dev, "%s - failed resubmitting read urb, error %d\n",
  284. __func__, result);
  285. dev_dbg(dev, "%s - usb_submit_urb(read urb)\n", __func__);
  286. }
  287. }
  288. static void cyberjack_write_bulk_callback(struct urb *urb)
  289. {
  290. struct usb_serial_port *port = urb->context;
  291. struct cyberjack_private *priv = usb_get_serial_port_data(port);
  292. struct device *dev = &port->dev;
  293. int status = urb->status;
  294. set_bit(0, &port->write_urbs_free);
  295. if (status) {
  296. dev_dbg(dev, "%s - nonzero write bulk status received: %d\n",
  297. __func__, status);
  298. return;
  299. }
  300. spin_lock(&priv->lock);
  301. /* only do something if we have more data to send */
  302. if (priv->wrfilled) {
  303. int length, blksize, result;
  304. dev_dbg(dev, "%s - transmitting data (frame n)\n", __func__);
  305. length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
  306. port->bulk_out_size : (priv->wrfilled - priv->wrsent);
  307. memcpy(port->write_urb->transfer_buffer,
  308. priv->wrbuf + priv->wrsent, length);
  309. priv->wrsent += length;
  310. /* set up our urb */
  311. port->write_urb->transfer_buffer_length = length;
  312. /* send the data out the bulk port */
  313. result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
  314. if (result) {
  315. dev_err(dev, "%s - failed submitting write urb, error %d\n",
  316. __func__, result);
  317. /* Throw away data. No better idea what to do with it. */
  318. priv->wrfilled = 0;
  319. priv->wrsent = 0;
  320. goto exit;
  321. }
  322. dev_dbg(dev, "%s - priv->wrsent=%d\n", __func__, priv->wrsent);
  323. dev_dbg(dev, "%s - priv->wrfilled=%d\n", __func__, priv->wrfilled);
  324. blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
  325. if (priv->wrsent >= priv->wrfilled ||
  326. priv->wrsent >= blksize) {
  327. dev_dbg(dev, "%s - buffer cleaned\n", __func__);
  328. memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
  329. priv->wrfilled = 0;
  330. priv->wrsent = 0;
  331. }
  332. }
  333. exit:
  334. spin_unlock(&priv->lock);
  335. usb_serial_port_softint(port);
  336. }
  337. module_usb_serial_driver(serial_drivers, id_table);
  338. MODULE_AUTHOR(DRIVER_AUTHOR);
  339. MODULE_DESCRIPTION(DRIVER_DESC);
  340. MODULE_LICENSE("GPL");