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