ssu100.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. /*
  2. * usb-serial driver for Quatech SSU-100
  3. *
  4. * based on ftdi_sio.c and the original serqt_usb.c from Quatech
  5. *
  6. */
  7. #include <linux/errno.h>
  8. #include <linux/init.h>
  9. #include <linux/slab.h>
  10. #include <linux/tty.h>
  11. #include <linux/tty_driver.h>
  12. #include <linux/tty_flip.h>
  13. #include <linux/module.h>
  14. #include <linux/serial.h>
  15. #include <linux/usb.h>
  16. #include <linux/usb/serial.h>
  17. #include <linux/serial_reg.h>
  18. #include <linux/uaccess.h>
  19. #define QT_OPEN_CLOSE_CHANNEL 0xca
  20. #define QT_SET_GET_DEVICE 0xc2
  21. #define QT_SET_GET_REGISTER 0xc0
  22. #define QT_GET_SET_PREBUF_TRIG_LVL 0xcc
  23. #define QT_SET_ATF 0xcd
  24. #define QT_GET_SET_UART 0xc1
  25. #define QT_TRANSFER_IN 0xc0
  26. #define QT_HW_FLOW_CONTROL_MASK 0xc5
  27. #define QT_SW_FLOW_CONTROL_MASK 0xc6
  28. #define SERIAL_MSR_MASK 0xf0
  29. #define SERIAL_CRTSCTS ((UART_MCR_RTS << 8) | UART_MSR_CTS)
  30. #define SERIAL_EVEN_PARITY (UART_LCR_PARITY | UART_LCR_EPAR)
  31. #define MAX_BAUD_RATE 460800
  32. #define ATC_DISABLED 0x00
  33. #define DUPMODE_BITS 0xc0
  34. #define RR_BITS 0x03
  35. #define LOOPMODE_BITS 0x41
  36. #define RS232_MODE 0x00
  37. #define RTSCTS_TO_CONNECTOR 0x40
  38. #define CLKS_X4 0x02
  39. #define FULLPWRBIT 0x00000080
  40. #define NEXT_BOARD_POWER_BIT 0x00000004
  41. static int debug = 1;
  42. /* Version Information */
  43. #define DRIVER_VERSION "v0.1"
  44. #define DRIVER_DESC "Quatech SSU-100 USB to Serial Driver"
  45. #define USB_VENDOR_ID_QUATECH 0x061d /* Quatech VID */
  46. #define QUATECH_SSU100 0xC020 /* SSU100 */
  47. static const struct usb_device_id id_table[] = {
  48. {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100)},
  49. {} /* Terminating entry */
  50. };
  51. MODULE_DEVICE_TABLE(usb, id_table);
  52. static struct usb_driver ssu100_driver = {
  53. .name = "ssu100",
  54. .probe = usb_serial_probe,
  55. .disconnect = usb_serial_disconnect,
  56. .id_table = id_table,
  57. .suspend = usb_serial_suspend,
  58. .resume = usb_serial_resume,
  59. .no_dynamic_id = 1,
  60. .supports_autosuspend = 1,
  61. };
  62. struct ssu100_port_private {
  63. spinlock_t status_lock;
  64. u8 shadowLSR;
  65. u8 shadowMSR;
  66. wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
  67. unsigned short max_packet_size;
  68. };
  69. static void ssu100_release(struct usb_serial *serial)
  70. {
  71. struct ssu100_port_private *priv = usb_get_serial_port_data(*serial->port);
  72. dbg("%s", __func__);
  73. kfree(priv);
  74. }
  75. static inline int ssu100_control_msg(struct usb_device *dev,
  76. u8 request, u16 data, u16 index)
  77. {
  78. return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
  79. request, 0x40, data, index,
  80. NULL, 0, 300);
  81. }
  82. static inline int ssu100_setdevice(struct usb_device *dev, u8 *data)
  83. {
  84. u16 x = ((u16)(data[1] << 8) | (u16)(data[0]));
  85. return ssu100_control_msg(dev, QT_SET_GET_DEVICE, x, 0);
  86. }
  87. static inline int ssu100_getdevice(struct usb_device *dev, u8 *data)
  88. {
  89. return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
  90. QT_SET_GET_DEVICE, 0xc0, 0, 0,
  91. data, 3, 300);
  92. }
  93. static inline int ssu100_getregister(struct usb_device *dev,
  94. unsigned short uart,
  95. unsigned short reg,
  96. u8 *data)
  97. {
  98. return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
  99. QT_SET_GET_REGISTER, 0xc0, reg,
  100. uart, data, sizeof(*data), 300);
  101. }
  102. static inline int ssu100_setregister(struct usb_device *dev,
  103. unsigned short uart,
  104. u16 data)
  105. {
  106. u16 value = (data << 8) | UART_MCR;
  107. return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
  108. QT_SET_GET_REGISTER, 0x40, value, uart,
  109. NULL, 0, 300);
  110. }
  111. #define set_mctrl(dev, set) update_mctrl((dev), (set), 0)
  112. #define clear_mctrl(dev, clear) update_mctrl((dev), 0, (clear))
  113. /* these do not deal with device that have more than 1 port */
  114. static inline int update_mctrl(struct usb_device *dev, unsigned int set,
  115. unsigned int clear)
  116. {
  117. unsigned urb_value;
  118. int result;
  119. if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) {
  120. dbg("%s - DTR|RTS not being set|cleared", __func__);
  121. return 0; /* no change */
  122. }
  123. clear &= ~set; /* 'set' takes precedence over 'clear' */
  124. urb_value = 0;
  125. if (set & TIOCM_DTR)
  126. urb_value |= UART_MCR_DTR;
  127. if (set & TIOCM_RTS)
  128. urb_value |= UART_MCR_RTS;
  129. result = ssu100_setregister(dev, 0, urb_value);
  130. if (result < 0)
  131. dbg("%s Error from MODEM_CTRL urb", __func__);
  132. return result;
  133. }
  134. static int ssu100_initdevice(struct usb_device *dev)
  135. {
  136. u8 *data;
  137. int result = 0;
  138. dbg("%s", __func__);
  139. data = kzalloc(3, GFP_KERNEL);
  140. if (!data)
  141. return -ENOMEM;
  142. result = ssu100_getdevice(dev, data);
  143. if (result < 0) {
  144. dbg("%s - get_device failed %i", __func__, result);
  145. goto out;
  146. }
  147. data[1] &= ~FULLPWRBIT;
  148. result = ssu100_setdevice(dev, data);
  149. if (result < 0) {
  150. dbg("%s - setdevice failed %i", __func__, result);
  151. goto out;
  152. }
  153. result = ssu100_control_msg(dev, QT_GET_SET_PREBUF_TRIG_LVL, 128, 0);
  154. if (result < 0) {
  155. dbg("%s - set prebuffer level failed %i", __func__, result);
  156. goto out;
  157. }
  158. result = ssu100_control_msg(dev, QT_SET_ATF, ATC_DISABLED, 0);
  159. if (result < 0) {
  160. dbg("%s - set ATFprebuffer level failed %i", __func__, result);
  161. goto out;
  162. }
  163. result = ssu100_getdevice(dev, data);
  164. if (result < 0) {
  165. dbg("%s - get_device failed %i", __func__, result);
  166. goto out;
  167. }
  168. data[0] &= ~(RR_BITS | DUPMODE_BITS);
  169. data[0] |= CLKS_X4;
  170. data[1] &= ~(LOOPMODE_BITS);
  171. data[1] |= RS232_MODE;
  172. result = ssu100_setdevice(dev, data);
  173. if (result < 0) {
  174. dbg("%s - setdevice failed %i", __func__, result);
  175. goto out;
  176. }
  177. out: kfree(data);
  178. return result;
  179. }
  180. static void ssu100_set_termios(struct tty_struct *tty,
  181. struct usb_serial_port *port,
  182. struct ktermios *old_termios)
  183. {
  184. struct usb_device *dev = port->serial->dev;
  185. struct ktermios *termios = tty->termios;
  186. u16 baud, divisor, remainder;
  187. unsigned int cflag = termios->c_cflag;
  188. u16 urb_value = 0; /* will hold the new flags */
  189. int result;
  190. dbg("%s", __func__);
  191. if (cflag & PARENB) {
  192. if (cflag & PARODD)
  193. urb_value |= UART_LCR_PARITY;
  194. else
  195. urb_value |= SERIAL_EVEN_PARITY;
  196. }
  197. switch (cflag & CSIZE) {
  198. case CS5:
  199. urb_value |= UART_LCR_WLEN5;
  200. break;
  201. case CS6:
  202. urb_value |= UART_LCR_WLEN6;
  203. break;
  204. case CS7:
  205. urb_value |= UART_LCR_WLEN7;
  206. break;
  207. default:
  208. case CS8:
  209. urb_value |= UART_LCR_WLEN8;
  210. break;
  211. }
  212. baud = tty_get_baud_rate(tty);
  213. if (!baud)
  214. baud = 9600;
  215. dbg("%s - got baud = %d\n", __func__, baud);
  216. divisor = MAX_BAUD_RATE / baud;
  217. remainder = MAX_BAUD_RATE % baud;
  218. if (((remainder * 2) >= baud) && (baud != 110))
  219. divisor++;
  220. urb_value = urb_value << 8;
  221. result = ssu100_control_msg(dev, QT_GET_SET_UART, divisor, urb_value);
  222. if (result < 0)
  223. dbg("%s - set uart failed", __func__);
  224. if (cflag & CRTSCTS)
  225. result = ssu100_control_msg(dev, QT_HW_FLOW_CONTROL_MASK,
  226. SERIAL_CRTSCTS, 0);
  227. else
  228. result = ssu100_control_msg(dev, QT_HW_FLOW_CONTROL_MASK,
  229. 0, 0);
  230. if (result < 0)
  231. dbg("%s - set HW flow control failed", __func__);
  232. if (I_IXOFF(tty) || I_IXON(tty)) {
  233. u16 x = ((u16)(START_CHAR(tty) << 8) | (u16)(STOP_CHAR(tty)));
  234. result = ssu100_control_msg(dev, QT_SW_FLOW_CONTROL_MASK,
  235. x, 0);
  236. } else
  237. result = ssu100_control_msg(dev, QT_SW_FLOW_CONTROL_MASK,
  238. 0, 0);
  239. if (result < 0)
  240. dbg("%s - set SW flow control failed", __func__);
  241. }
  242. static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port)
  243. {
  244. struct usb_device *dev = port->serial->dev;
  245. struct ssu100_port_private *priv = usb_get_serial_port_data(port);
  246. u8 *data;
  247. int result;
  248. unsigned long flags;
  249. dbg("%s - port %d", __func__, port->number);
  250. data = kzalloc(2, GFP_KERNEL);
  251. if (!data)
  252. return -ENOMEM;
  253. result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
  254. QT_OPEN_CLOSE_CHANNEL,
  255. QT_TRANSFER_IN, 0x01,
  256. 0, data, 2, 300);
  257. if (result < 0) {
  258. dbg("%s - open failed %i", __func__, result);
  259. kfree(data);
  260. return result;
  261. }
  262. spin_lock_irqsave(&priv->status_lock, flags);
  263. priv->shadowLSR = data[0] & (UART_LSR_OE | UART_LSR_PE |
  264. UART_LSR_FE | UART_LSR_BI);
  265. priv->shadowMSR = data[1] & (UART_MSR_CTS | UART_MSR_DSR |
  266. UART_MSR_RI | UART_MSR_DCD);
  267. spin_unlock_irqrestore(&priv->status_lock, flags);
  268. kfree(data);
  269. /* set to 9600 */
  270. result = ssu100_control_msg(dev, QT_GET_SET_UART, 0x30, 0x0300);
  271. if (result < 0)
  272. dbg("%s - set uart failed", __func__);
  273. if (tty)
  274. ssu100_set_termios(tty, port, tty->termios);
  275. return usb_serial_generic_open(tty, port);
  276. }
  277. static void ssu100_close(struct usb_serial_port *port)
  278. {
  279. dbg("%s", __func__);
  280. usb_serial_generic_close(port);
  281. }
  282. static int get_serial_info(struct usb_serial_port *port,
  283. struct serial_struct __user *retinfo)
  284. {
  285. struct serial_struct tmp;
  286. if (!retinfo)
  287. return -EFAULT;
  288. memset(&tmp, 0, sizeof(tmp));
  289. tmp.line = port->serial->minor;
  290. tmp.port = 0;
  291. tmp.irq = 0;
  292. tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
  293. tmp.xmit_fifo_size = port->bulk_out_size;
  294. tmp.baud_base = 9600;
  295. tmp.close_delay = 5*HZ;
  296. tmp.closing_wait = 30*HZ;
  297. if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
  298. return -EFAULT;
  299. return 0;
  300. }
  301. static int ssu100_ioctl(struct tty_struct *tty, struct file *file,
  302. unsigned int cmd, unsigned long arg)
  303. {
  304. struct usb_serial_port *port = tty->driver_data;
  305. struct ssu100_port_private *priv = usb_get_serial_port_data(port);
  306. dbg("%s cmd 0x%04x", __func__, cmd);
  307. switch (cmd) {
  308. case TIOCGSERIAL:
  309. return get_serial_info(port,
  310. (struct serial_struct __user *) arg);
  311. case TIOCMIWAIT:
  312. while (priv != NULL) {
  313. u8 prevMSR = priv->shadowMSR & SERIAL_MSR_MASK;
  314. interruptible_sleep_on(&priv->delta_msr_wait);
  315. /* see if a signal did it */
  316. if (signal_pending(current))
  317. return -ERESTARTSYS;
  318. else {
  319. u8 diff = (priv->shadowMSR & SERIAL_MSR_MASK) ^ prevMSR;
  320. if (!diff)
  321. return -EIO; /* no change => error */
  322. /* Return 0 if caller wanted to know about
  323. these bits */
  324. if (((arg & TIOCM_RNG) && (diff & UART_MSR_RI)) ||
  325. ((arg & TIOCM_DSR) && (diff & UART_MSR_DSR)) ||
  326. ((arg & TIOCM_CD) && (diff & UART_MSR_DCD)) ||
  327. ((arg & TIOCM_CTS) && (diff & UART_MSR_CTS)))
  328. return 0;
  329. }
  330. }
  331. return 0;
  332. default:
  333. break;
  334. }
  335. dbg("%s arg not supported", __func__);
  336. return -ENOIOCTLCMD;
  337. }
  338. static void ssu100_set_max_packet_size(struct usb_serial_port *port)
  339. {
  340. struct ssu100_port_private *priv = usb_get_serial_port_data(port);
  341. struct usb_serial *serial = port->serial;
  342. struct usb_device *udev = serial->dev;
  343. struct usb_interface *interface = serial->interface;
  344. struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc;
  345. unsigned num_endpoints;
  346. int i;
  347. unsigned long flags;
  348. num_endpoints = interface->cur_altsetting->desc.bNumEndpoints;
  349. dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints);
  350. for (i = 0; i < num_endpoints; i++) {
  351. dev_info(&udev->dev, "Endpoint %d MaxPacketSize %d\n", i+1,
  352. interface->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
  353. ep_desc = &interface->cur_altsetting->endpoint[i].desc;
  354. }
  355. /* set max packet size based on descriptor */
  356. spin_lock_irqsave(&priv->status_lock, flags);
  357. priv->max_packet_size = ep_desc->wMaxPacketSize;
  358. spin_unlock_irqrestore(&priv->status_lock, flags);
  359. dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size);
  360. }
  361. static int ssu100_attach(struct usb_serial *serial)
  362. {
  363. struct ssu100_port_private *priv;
  364. struct usb_serial_port *port = *serial->port;
  365. dbg("%s", __func__);
  366. priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  367. if (!priv) {
  368. dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__,
  369. sizeof(*priv));
  370. return -ENOMEM;
  371. }
  372. spin_lock_init(&priv->status_lock);
  373. init_waitqueue_head(&priv->delta_msr_wait);
  374. usb_set_serial_port_data(port, priv);
  375. ssu100_set_max_packet_size(port);
  376. return ssu100_initdevice(serial->dev);
  377. }
  378. static int ssu100_tiocmget(struct tty_struct *tty, struct file *file)
  379. {
  380. struct usb_serial_port *port = tty->driver_data;
  381. struct usb_device *dev = port->serial->dev;
  382. u8 *d;
  383. int r;
  384. dbg("%s\n", __func__);
  385. d = kzalloc(2, GFP_KERNEL);
  386. if (!d)
  387. return -ENOMEM;
  388. r = ssu100_getregister(dev, 0, UART_MCR, d);
  389. if (r < 0)
  390. goto mget_out;
  391. r = ssu100_getregister(dev, 0, UART_MSR, d+1);
  392. if (r < 0)
  393. goto mget_out;
  394. r = (d[0] & UART_MCR_DTR ? TIOCM_DTR : 0) |
  395. (d[0] & UART_MCR_RTS ? TIOCM_RTS : 0) |
  396. (d[1] & UART_MSR_CTS ? TIOCM_CTS : 0) |
  397. (d[1] & UART_MSR_DCD ? TIOCM_CAR : 0) |
  398. (d[1] & UART_MSR_RI ? TIOCM_RI : 0) |
  399. (d[1] & UART_MSR_DSR ? TIOCM_DSR : 0);
  400. mget_out:
  401. kfree(d);
  402. return r;
  403. }
  404. static int ssu100_tiocmset(struct tty_struct *tty, struct file *file,
  405. unsigned int set, unsigned int clear)
  406. {
  407. struct usb_serial_port *port = tty->driver_data;
  408. struct usb_device *dev = port->serial->dev;
  409. dbg("%s\n", __func__);
  410. return update_mctrl(dev, set, clear);
  411. }
  412. static void ssu100_dtr_rts(struct usb_serial_port *port, int on)
  413. {
  414. struct usb_device *dev = port->serial->dev;
  415. dbg("%s\n", __func__);
  416. mutex_lock(&port->serial->disc_mutex);
  417. if (!port->serial->disconnected) {
  418. /* Disable flow control */
  419. if (!on &&
  420. ssu100_setregister(dev, 0, 0) < 0)
  421. dev_err(&port->dev, "error from flowcontrol urb\n");
  422. /* drop RTS and DTR */
  423. if (on)
  424. set_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
  425. else
  426. clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
  427. }
  428. mutex_unlock(&port->serial->disc_mutex);
  429. }
  430. static int ssu100_process_packet(struct tty_struct *tty,
  431. struct usb_serial_port *port,
  432. struct ssu100_port_private *priv,
  433. char *packet, int len)
  434. {
  435. int i;
  436. char flag;
  437. char *ch;
  438. dbg("%s - port %d", __func__, port->number);
  439. if ((len >= 4) &&
  440. (packet[0] == 0x1b) && (packet[1] == 0x1b) &&
  441. ((packet[2] == 0x00) || (packet[2] == 0x01))) {
  442. if (packet[2] == 0x00)
  443. priv->shadowLSR = packet[3] & (UART_LSR_OE |
  444. UART_LSR_PE |
  445. UART_LSR_FE |
  446. UART_LSR_BI);
  447. if (packet[2] == 0x01) {
  448. priv->shadowMSR = packet[3];
  449. wake_up_interruptible(&priv->delta_msr_wait);
  450. }
  451. len -= 4;
  452. ch = packet + 4;
  453. } else
  454. ch = packet;
  455. if (!len)
  456. return 0; /* status only */
  457. if (port->port.console && port->sysrq) {
  458. for (i = 0; i < len; i++, ch++) {
  459. if (!usb_serial_handle_sysrq_char(tty, port, *ch))
  460. tty_insert_flip_char(tty, *ch, flag);
  461. }
  462. } else
  463. tty_insert_flip_string_fixed_flag(tty, ch, flag, len);
  464. return len;
  465. }
  466. static void ssu100_process_read_urb(struct urb *urb)
  467. {
  468. struct usb_serial_port *port = urb->context;
  469. struct ssu100_port_private *priv = usb_get_serial_port_data(port);
  470. char *data = (char *)urb->transfer_buffer;
  471. struct tty_struct *tty;
  472. int count = 0;
  473. int i;
  474. int len;
  475. dbg("%s", __func__);
  476. tty = tty_port_tty_get(&port->port);
  477. if (!tty)
  478. return;
  479. for (i = 0; i < urb->actual_length; i += priv->max_packet_size) {
  480. len = min_t(int, urb->actual_length - i, priv->max_packet_size);
  481. count += ssu100_process_packet(tty, port, priv, &data[i], len);
  482. }
  483. if (count)
  484. tty_flip_buffer_push(tty);
  485. tty_kref_put(tty);
  486. }
  487. static struct usb_serial_driver ssu100_device = {
  488. .driver = {
  489. .owner = THIS_MODULE,
  490. .name = "ssu100",
  491. },
  492. .description = DRIVER_DESC,
  493. .id_table = id_table,
  494. .usb_driver = &ssu100_driver,
  495. .num_ports = 1,
  496. .bulk_in_size = 256,
  497. .bulk_out_size = 256,
  498. .open = ssu100_open,
  499. .close = ssu100_close,
  500. .attach = ssu100_attach,
  501. .release = ssu100_release,
  502. .dtr_rts = ssu100_dtr_rts,
  503. .process_read_urb = ssu100_process_read_urb,
  504. .tiocmget = ssu100_tiocmget,
  505. .tiocmset = ssu100_tiocmset,
  506. .ioctl = ssu100_ioctl,
  507. .set_termios = ssu100_set_termios,
  508. };
  509. static int __init ssu100_init(void)
  510. {
  511. int retval;
  512. dbg("%s", __func__);
  513. /* register with usb-serial */
  514. retval = usb_serial_register(&ssu100_device);
  515. if (retval)
  516. goto failed_usb_sio_register;
  517. retval = usb_register(&ssu100_driver);
  518. if (retval)
  519. goto failed_usb_register;
  520. printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
  521. DRIVER_DESC "\n");
  522. return 0;
  523. failed_usb_register:
  524. usb_serial_deregister(&ssu100_device);
  525. failed_usb_sio_register:
  526. return retval;
  527. }
  528. static void __exit ssu100_exit(void)
  529. {
  530. usb_deregister(&ssu100_driver);
  531. usb_serial_deregister(&ssu100_device);
  532. }
  533. module_init(ssu100_init);
  534. module_exit(ssu100_exit);
  535. MODULE_DESCRIPTION(DRIVER_DESC);
  536. MODULE_LICENSE("GPL");
  537. module_param(debug, bool, S_IRUGO | S_IWUSR);
  538. MODULE_PARM_DESC(debug, "Debug enabled or not");