kobil_sct.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. /*
  2. * KOBIL USB Smart Card Terminal Driver
  3. *
  4. * Copyright (C) 2002 KOBIL Systems GmbH
  5. * Author: Thomas Wahrenbruch
  6. *
  7. * Contact: linuxusb@kobil.de
  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. * Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus
  22. * (Adapter K), B1 Professional and KAAN Professional (Adapter B)
  23. */
  24. #include <linux/kernel.h>
  25. #include <linux/errno.h>
  26. #include <linux/init.h>
  27. #include <linux/slab.h>
  28. #include <linux/tty.h>
  29. #include <linux/tty_driver.h>
  30. #include <linux/tty_flip.h>
  31. #include <linux/module.h>
  32. #include <linux/spinlock.h>
  33. #include <linux/uaccess.h>
  34. #include <linux/usb.h>
  35. #include <linux/usb/serial.h>
  36. #include <linux/ioctl.h>
  37. #include "kobil_sct.h"
  38. static bool debug;
  39. /* Version Information */
  40. #define DRIVER_VERSION "21/05/2004"
  41. #define DRIVER_AUTHOR "KOBIL Systems GmbH - http://www.kobil.com"
  42. #define DRIVER_DESC "KOBIL USB Smart Card Terminal Driver (experimental)"
  43. #define KOBIL_VENDOR_ID 0x0D46
  44. #define KOBIL_ADAPTER_B_PRODUCT_ID 0x2011
  45. #define KOBIL_ADAPTER_K_PRODUCT_ID 0x2012
  46. #define KOBIL_USBTWIN_PRODUCT_ID 0x0078
  47. #define KOBIL_KAAN_SIM_PRODUCT_ID 0x0081
  48. #define KOBIL_TIMEOUT 500
  49. #define KOBIL_BUF_LENGTH 300
  50. /* Function prototypes */
  51. static int kobil_startup(struct usb_serial *serial);
  52. static void kobil_release(struct usb_serial *serial);
  53. static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port);
  54. static void kobil_close(struct usb_serial_port *port);
  55. static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
  56. const unsigned char *buf, int count);
  57. static int kobil_write_room(struct tty_struct *tty);
  58. static int kobil_ioctl(struct tty_struct *tty,
  59. unsigned int cmd, unsigned long arg);
  60. static int kobil_tiocmget(struct tty_struct *tty);
  61. static int kobil_tiocmset(struct tty_struct *tty,
  62. unsigned int set, unsigned int clear);
  63. static void kobil_read_int_callback(struct urb *urb);
  64. static void kobil_write_callback(struct urb *purb);
  65. static void kobil_set_termios(struct tty_struct *tty,
  66. struct usb_serial_port *port, struct ktermios *old);
  67. static void kobil_init_termios(struct tty_struct *tty);
  68. static const struct usb_device_id id_table[] = {
  69. { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) },
  70. { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_K_PRODUCT_ID) },
  71. { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_USBTWIN_PRODUCT_ID) },
  72. { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_KAAN_SIM_PRODUCT_ID) },
  73. { } /* Terminating entry */
  74. };
  75. MODULE_DEVICE_TABLE(usb, id_table);
  76. static struct usb_serial_driver kobil_device = {
  77. .driver = {
  78. .owner = THIS_MODULE,
  79. .name = "kobil",
  80. },
  81. .description = "KOBIL USB smart card terminal",
  82. .id_table = id_table,
  83. .num_ports = 1,
  84. .attach = kobil_startup,
  85. .release = kobil_release,
  86. .ioctl = kobil_ioctl,
  87. .set_termios = kobil_set_termios,
  88. .init_termios = kobil_init_termios,
  89. .tiocmget = kobil_tiocmget,
  90. .tiocmset = kobil_tiocmset,
  91. .open = kobil_open,
  92. .close = kobil_close,
  93. .write = kobil_write,
  94. .write_room = kobil_write_room,
  95. .read_int_callback = kobil_read_int_callback,
  96. };
  97. static struct usb_serial_driver * const serial_drivers[] = {
  98. &kobil_device, NULL
  99. };
  100. struct kobil_private {
  101. int write_int_endpoint_address;
  102. int read_int_endpoint_address;
  103. unsigned char buf[KOBIL_BUF_LENGTH]; /* buffer for the APDU to send */
  104. int filled; /* index of the last char in buf */
  105. int cur_pos; /* index of the next char to send in buf */
  106. __u16 device_type;
  107. };
  108. static int kobil_startup(struct usb_serial *serial)
  109. {
  110. int i;
  111. struct kobil_private *priv;
  112. struct usb_device *pdev;
  113. struct usb_host_config *actconfig;
  114. struct usb_interface *interface;
  115. struct usb_host_interface *altsetting;
  116. struct usb_host_endpoint *endpoint;
  117. priv = kmalloc(sizeof(struct kobil_private), GFP_KERNEL);
  118. if (!priv)
  119. return -ENOMEM;
  120. priv->filled = 0;
  121. priv->cur_pos = 0;
  122. priv->device_type = le16_to_cpu(serial->dev->descriptor.idProduct);
  123. switch (priv->device_type) {
  124. case KOBIL_ADAPTER_B_PRODUCT_ID:
  125. printk(KERN_DEBUG "KOBIL B1 PRO / KAAN PRO detected\n");
  126. break;
  127. case KOBIL_ADAPTER_K_PRODUCT_ID:
  128. printk(KERN_DEBUG
  129. "KOBIL KAAN Standard Plus / SecOVID Reader Plus detected\n");
  130. break;
  131. case KOBIL_USBTWIN_PRODUCT_ID:
  132. printk(KERN_DEBUG "KOBIL USBTWIN detected\n");
  133. break;
  134. case KOBIL_KAAN_SIM_PRODUCT_ID:
  135. printk(KERN_DEBUG "KOBIL KAAN SIM detected\n");
  136. break;
  137. }
  138. usb_set_serial_port_data(serial->port[0], priv);
  139. /* search for the necessary endpoints */
  140. pdev = serial->dev;
  141. actconfig = pdev->actconfig;
  142. interface = actconfig->interface[0];
  143. altsetting = interface->cur_altsetting;
  144. endpoint = altsetting->endpoint;
  145. for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
  146. endpoint = &altsetting->endpoint[i];
  147. if (usb_endpoint_is_int_out(&endpoint->desc)) {
  148. dbg("%s Found interrupt out endpoint. Address: %d",
  149. __func__, endpoint->desc.bEndpointAddress);
  150. priv->write_int_endpoint_address =
  151. endpoint->desc.bEndpointAddress;
  152. }
  153. if (usb_endpoint_is_int_in(&endpoint->desc)) {
  154. dbg("%s Found interrupt in endpoint. Address: %d",
  155. __func__, endpoint->desc.bEndpointAddress);
  156. priv->read_int_endpoint_address =
  157. endpoint->desc.bEndpointAddress;
  158. }
  159. }
  160. return 0;
  161. }
  162. static void kobil_release(struct usb_serial *serial)
  163. {
  164. int i;
  165. for (i = 0; i < serial->num_ports; ++i)
  166. kfree(usb_get_serial_port_data(serial->port[i]));
  167. }
  168. static void kobil_init_termios(struct tty_struct *tty)
  169. {
  170. /* Default to echo off and other sane device settings */
  171. tty->termios->c_lflag = 0;
  172. tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
  173. tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
  174. /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
  175. tty->termios->c_oflag &= ~ONLCR;
  176. }
  177. static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
  178. {
  179. int result = 0;
  180. struct kobil_private *priv;
  181. unsigned char *transfer_buffer;
  182. int transfer_buffer_length = 8;
  183. int write_urb_transfer_buffer_length = 8;
  184. priv = usb_get_serial_port_data(port);
  185. /* allocate memory for transfer buffer */
  186. transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
  187. if (!transfer_buffer)
  188. return -ENOMEM;
  189. /* allocate write_urb */
  190. if (!port->write_urb) {
  191. dbg("%s - port %d Allocating port->write_urb",
  192. __func__, port->number);
  193. port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
  194. if (!port->write_urb) {
  195. dbg("%s - port %d usb_alloc_urb failed",
  196. __func__, port->number);
  197. kfree(transfer_buffer);
  198. return -ENOMEM;
  199. }
  200. }
  201. /* allocate memory for write_urb transfer buffer */
  202. port->write_urb->transfer_buffer =
  203. kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
  204. if (!port->write_urb->transfer_buffer) {
  205. kfree(transfer_buffer);
  206. usb_free_urb(port->write_urb);
  207. port->write_urb = NULL;
  208. return -ENOMEM;
  209. }
  210. /* get hardware version */
  211. result = usb_control_msg(port->serial->dev,
  212. usb_rcvctrlpipe(port->serial->dev, 0),
  213. SUSBCRequest_GetMisc,
  214. USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
  215. SUSBCR_MSC_GetHWVersion,
  216. 0,
  217. transfer_buffer,
  218. transfer_buffer_length,
  219. KOBIL_TIMEOUT
  220. );
  221. dbg("%s - port %d Send get_HW_version URB returns: %i",
  222. __func__, port->number, result);
  223. dbg("Harware version: %i.%i.%i",
  224. transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]);
  225. /* get firmware version */
  226. result = usb_control_msg(port->serial->dev,
  227. usb_rcvctrlpipe(port->serial->dev, 0),
  228. SUSBCRequest_GetMisc,
  229. USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
  230. SUSBCR_MSC_GetFWVersion,
  231. 0,
  232. transfer_buffer,
  233. transfer_buffer_length,
  234. KOBIL_TIMEOUT
  235. );
  236. dbg("%s - port %d Send get_FW_version URB returns: %i",
  237. __func__, port->number, result);
  238. dbg("Firmware version: %i.%i.%i",
  239. transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]);
  240. if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
  241. priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
  242. /* Setting Baudrate, Parity and Stopbits */
  243. result = usb_control_msg(port->serial->dev,
  244. usb_rcvctrlpipe(port->serial->dev, 0),
  245. SUSBCRequest_SetBaudRateParityAndStopBits,
  246. USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
  247. SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity |
  248. SUSBCR_SPASB_1StopBit,
  249. 0,
  250. transfer_buffer,
  251. 0,
  252. KOBIL_TIMEOUT
  253. );
  254. dbg("%s - port %d Send set_baudrate URB returns: %i",
  255. __func__, port->number, result);
  256. /* reset all queues */
  257. result = usb_control_msg(port->serial->dev,
  258. usb_rcvctrlpipe(port->serial->dev, 0),
  259. SUSBCRequest_Misc,
  260. USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
  261. SUSBCR_MSC_ResetAllQueues,
  262. 0,
  263. transfer_buffer,
  264. 0,
  265. KOBIL_TIMEOUT
  266. );
  267. dbg("%s - port %d Send reset_all_queues URB returns: %i",
  268. __func__, port->number, result);
  269. }
  270. if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
  271. priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
  272. priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
  273. /* start reading (Adapter B 'cause PNP string) */
  274. result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
  275. dbg("%s - port %d Send read URB returns: %i",
  276. __func__, port->number, result);
  277. }
  278. kfree(transfer_buffer);
  279. return 0;
  280. }
  281. static void kobil_close(struct usb_serial_port *port)
  282. {
  283. /* FIXME: Add rts/dtr methods */
  284. if (port->write_urb) {
  285. usb_poison_urb(port->write_urb);
  286. kfree(port->write_urb->transfer_buffer);
  287. usb_free_urb(port->write_urb);
  288. port->write_urb = NULL;
  289. }
  290. usb_kill_urb(port->interrupt_in_urb);
  291. }
  292. static void kobil_read_int_callback(struct urb *urb)
  293. {
  294. int result;
  295. struct usb_serial_port *port = urb->context;
  296. struct tty_struct *tty;
  297. unsigned char *data = urb->transfer_buffer;
  298. int status = urb->status;
  299. /* char *dbg_data; */
  300. if (status) {
  301. dbg("%s - port %d Read int status not zero: %d",
  302. __func__, port->number, status);
  303. return;
  304. }
  305. tty = tty_port_tty_get(&port->port);
  306. if (tty && urb->actual_length) {
  307. /* BEGIN DEBUG */
  308. /*
  309. dbg_data = kzalloc((3 * purb->actual_length + 10)
  310. * sizeof(char), GFP_KERNEL);
  311. if (! dbg_data) {
  312. return;
  313. }
  314. for (i = 0; i < purb->actual_length; i++) {
  315. sprintf(dbg_data +3*i, "%02X ", data[i]);
  316. }
  317. dbg(" <-- %s", dbg_data);
  318. kfree(dbg_data);
  319. */
  320. /* END DEBUG */
  321. tty_insert_flip_string(tty, data, urb->actual_length);
  322. tty_flip_buffer_push(tty);
  323. }
  324. tty_kref_put(tty);
  325. result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
  326. dbg("%s - port %d Send read URB returns: %i",
  327. __func__, port->number, result);
  328. }
  329. static void kobil_write_callback(struct urb *purb)
  330. {
  331. }
  332. static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
  333. const unsigned char *buf, int count)
  334. {
  335. int length = 0;
  336. int result = 0;
  337. int todo = 0;
  338. struct kobil_private *priv;
  339. if (count == 0) {
  340. dbg("%s - port %d write request of 0 bytes",
  341. __func__, port->number);
  342. return 0;
  343. }
  344. priv = usb_get_serial_port_data(port);
  345. if (count > (KOBIL_BUF_LENGTH - priv->filled)) {
  346. dbg("%s - port %d Error: write request bigger than buffer size", __func__, port->number);
  347. return -ENOMEM;
  348. }
  349. /* Copy data to buffer */
  350. memcpy(priv->buf + priv->filled, buf, count);
  351. usb_serial_debug_data(debug, &port->dev, __func__, count,
  352. priv->buf + priv->filled);
  353. priv->filled = priv->filled + count;
  354. /* only send complete block. TWIN, KAAN SIM and adapter K
  355. use the same protocol. */
  356. if (((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) ||
  357. ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4)))) {
  358. /* stop reading (except TWIN and KAAN SIM) */
  359. if ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID)
  360. || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID))
  361. usb_kill_urb(port->interrupt_in_urb);
  362. todo = priv->filled - priv->cur_pos;
  363. while (todo > 0) {
  364. /* max 8 byte in one urb (endpoint size) */
  365. length = (todo < 8) ? todo : 8;
  366. /* copy data to transfer buffer */
  367. memcpy(port->write_urb->transfer_buffer,
  368. priv->buf + priv->cur_pos, length);
  369. usb_fill_int_urb(port->write_urb,
  370. port->serial->dev,
  371. usb_sndintpipe(port->serial->dev,
  372. priv->write_int_endpoint_address),
  373. port->write_urb->transfer_buffer,
  374. length,
  375. kobil_write_callback,
  376. port,
  377. 8
  378. );
  379. priv->cur_pos = priv->cur_pos + length;
  380. result = usb_submit_urb(port->write_urb, GFP_NOIO);
  381. dbg("%s - port %d Send write URB returns: %i",
  382. __func__, port->number, result);
  383. todo = priv->filled - priv->cur_pos;
  384. if (todo > 0)
  385. msleep(24);
  386. }
  387. priv->filled = 0;
  388. priv->cur_pos = 0;
  389. /* start reading (except TWIN and KAAN SIM) */
  390. if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
  391. priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
  392. result = usb_submit_urb(port->interrupt_in_urb,
  393. GFP_NOIO);
  394. dbg("%s - port %d Send read URB returns: %i",
  395. __func__, port->number, result);
  396. }
  397. }
  398. return count;
  399. }
  400. static int kobil_write_room(struct tty_struct *tty)
  401. {
  402. /* FIXME */
  403. return 8;
  404. }
  405. static int kobil_tiocmget(struct tty_struct *tty)
  406. {
  407. struct usb_serial_port *port = tty->driver_data;
  408. struct kobil_private *priv;
  409. int result;
  410. unsigned char *transfer_buffer;
  411. int transfer_buffer_length = 8;
  412. priv = usb_get_serial_port_data(port);
  413. if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID
  414. || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
  415. /* This device doesn't support ioctl calls */
  416. return -EINVAL;
  417. }
  418. /* allocate memory for transfer buffer */
  419. transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
  420. if (!transfer_buffer)
  421. return -ENOMEM;
  422. result = usb_control_msg(port->serial->dev,
  423. usb_rcvctrlpipe(port->serial->dev, 0),
  424. SUSBCRequest_GetStatusLineState,
  425. USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
  426. 0,
  427. 0,
  428. transfer_buffer,
  429. transfer_buffer_length,
  430. KOBIL_TIMEOUT);
  431. dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x",
  432. __func__, port->number, result, transfer_buffer[0]);
  433. result = 0;
  434. if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0)
  435. result = TIOCM_DSR;
  436. kfree(transfer_buffer);
  437. return result;
  438. }
  439. static int kobil_tiocmset(struct tty_struct *tty,
  440. unsigned int set, unsigned int clear)
  441. {
  442. struct usb_serial_port *port = tty->driver_data;
  443. struct kobil_private *priv;
  444. int result;
  445. int dtr = 0;
  446. int rts = 0;
  447. unsigned char *transfer_buffer;
  448. int transfer_buffer_length = 8;
  449. /* FIXME: locking ? */
  450. priv = usb_get_serial_port_data(port);
  451. if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID
  452. || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
  453. /* This device doesn't support ioctl calls */
  454. return -EINVAL;
  455. }
  456. /* allocate memory for transfer buffer */
  457. transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
  458. if (!transfer_buffer)
  459. return -ENOMEM;
  460. if (set & TIOCM_RTS)
  461. rts = 1;
  462. if (set & TIOCM_DTR)
  463. dtr = 1;
  464. if (clear & TIOCM_RTS)
  465. rts = 0;
  466. if (clear & TIOCM_DTR)
  467. dtr = 0;
  468. if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) {
  469. if (dtr != 0)
  470. dbg("%s - port %d Setting DTR",
  471. __func__, port->number);
  472. else
  473. dbg("%s - port %d Clearing DTR",
  474. __func__, port->number);
  475. result = usb_control_msg(port->serial->dev,
  476. usb_rcvctrlpipe(port->serial->dev, 0),
  477. SUSBCRequest_SetStatusLinesOrQueues,
  478. USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
  479. ((dtr != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR),
  480. 0,
  481. transfer_buffer,
  482. 0,
  483. KOBIL_TIMEOUT);
  484. } else {
  485. if (rts != 0)
  486. dbg("%s - port %d Setting RTS",
  487. __func__, port->number);
  488. else
  489. dbg("%s - port %d Clearing RTS",
  490. __func__, port->number);
  491. result = usb_control_msg(port->serial->dev,
  492. usb_rcvctrlpipe(port->serial->dev, 0),
  493. SUSBCRequest_SetStatusLinesOrQueues,
  494. USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
  495. ((rts != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS),
  496. 0,
  497. transfer_buffer,
  498. 0,
  499. KOBIL_TIMEOUT);
  500. }
  501. dbg("%s - port %d Send set_status_line URB returns: %i",
  502. __func__, port->number, result);
  503. kfree(transfer_buffer);
  504. return (result < 0) ? result : 0;
  505. }
  506. static void kobil_set_termios(struct tty_struct *tty,
  507. struct usb_serial_port *port, struct ktermios *old)
  508. {
  509. struct kobil_private *priv;
  510. int result;
  511. unsigned short urb_val = 0;
  512. int c_cflag = tty->termios->c_cflag;
  513. speed_t speed;
  514. priv = usb_get_serial_port_data(port);
  515. if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
  516. priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
  517. /* This device doesn't support ioctl calls */
  518. *tty->termios = *old;
  519. return;
  520. }
  521. speed = tty_get_baud_rate(tty);
  522. switch (speed) {
  523. case 1200:
  524. urb_val = SUSBCR_SBR_1200;
  525. break;
  526. default:
  527. speed = 9600;
  528. case 9600:
  529. urb_val = SUSBCR_SBR_9600;
  530. break;
  531. }
  532. urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits :
  533. SUSBCR_SPASB_1StopBit;
  534. if (c_cflag & PARENB) {
  535. if (c_cflag & PARODD)
  536. urb_val |= SUSBCR_SPASB_OddParity;
  537. else
  538. urb_val |= SUSBCR_SPASB_EvenParity;
  539. } else
  540. urb_val |= SUSBCR_SPASB_NoParity;
  541. tty->termios->c_cflag &= ~CMSPAR;
  542. tty_encode_baud_rate(tty, speed, speed);
  543. result = usb_control_msg(port->serial->dev,
  544. usb_rcvctrlpipe(port->serial->dev, 0),
  545. SUSBCRequest_SetBaudRateParityAndStopBits,
  546. USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
  547. urb_val,
  548. 0,
  549. NULL,
  550. 0,
  551. KOBIL_TIMEOUT
  552. );
  553. }
  554. static int kobil_ioctl(struct tty_struct *tty,
  555. unsigned int cmd, unsigned long arg)
  556. {
  557. struct usb_serial_port *port = tty->driver_data;
  558. struct kobil_private *priv = usb_get_serial_port_data(port);
  559. unsigned char *transfer_buffer;
  560. int transfer_buffer_length = 8;
  561. int result;
  562. if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
  563. priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
  564. /* This device doesn't support ioctl calls */
  565. return -ENOIOCTLCMD;
  566. switch (cmd) {
  567. case TCFLSH:
  568. transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL);
  569. if (!transfer_buffer)
  570. return -ENOBUFS;
  571. result = usb_control_msg(port->serial->dev,
  572. usb_rcvctrlpipe(port->serial->dev, 0),
  573. SUSBCRequest_Misc,
  574. USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
  575. SUSBCR_MSC_ResetAllQueues,
  576. 0,
  577. NULL, /* transfer_buffer, */
  578. 0,
  579. KOBIL_TIMEOUT
  580. );
  581. dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __func__, port->number, result);
  582. kfree(transfer_buffer);
  583. return (result < 0) ? -EIO: 0;
  584. default:
  585. return -ENOIOCTLCMD;
  586. }
  587. }
  588. module_usb_serial_driver(serial_drivers, id_table);
  589. MODULE_AUTHOR(DRIVER_AUTHOR);
  590. MODULE_DESCRIPTION(DRIVER_DESC);
  591. MODULE_LICENSE("GPL");
  592. module_param(debug, bool, S_IRUGO | S_IWUSR);
  593. MODULE_PARM_DESC(debug, "Debug enabled or not");