summaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/keyspan_pda.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/keyspan_pda.c')
-rw-r--r--drivers/usb/serial/keyspan_pda.c284
1 files changed, 145 insertions, 139 deletions
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index ff54203944c..040040a267d 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -10,8 +10,9 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
- *
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
+ *
* (09/07/2001) gkh
* cleaned up the Xircom support. Added ids for Entregra device which is
* the same as the Xircom device. Enabled the code to be compiled for
@@ -21,23 +22,24 @@
* support for Xircom PGSDB9
*
* (05/31/2001) gkh
- * switched from using spinlock to a semaphore, which fixes lots of problems.
+ * switched from using spinlock to a semaphore, which fixes lots of
+ * problems.
*
* (04/08/2001) gb
* Identify version on module load.
- *
+ *
* (11/01/2000) Adam J. Richter
* usb_device_id table support
- *
+ *
* (10/05/2000) gkh
* Fixed bug with urb->dev not being set properly, now that the usb
* core needs it.
- *
+ *
* (08/28/2000) gkh
* Added locks for SMP safeness.
- * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more
+ * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more
* than once.
- *
+ *
* (07/20/2000) borchers
* - keyspan_pda_write no longer sleeps if it is called on interrupt time;
* PPP and the line discipline with stty echo on can call write on
@@ -55,14 +57,14 @@
* than done directly from the callback to avoid the race in write_chan
* - keyspan_pda_chars_in_buffer also indicates its buffer is full if the
* urb status is -EINPROGRESS, meaning it cannot write at the moment
- *
+ *
* (07/19/2000) gkh
* Added module_init and module_exit functions to handle the fact that this
* driver is a loadable module now.
*
* (03/26/2000) gkh
* Split driver up into device specific pieces.
- *
+ *
*/
@@ -76,18 +78,14 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
-#include <asm/uaccess.h>
+#include <linux/firmware.h>
+#include <linux/ihex.h>
+#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
static int debug;
-struct ezusb_hex_record {
- __u16 address;
- __u8 data_size;
- __u8 data[16];
-};
-
/* make a simple define to handle if we are compiling keyspan_pda or xircom support */
#if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE)
#define KEYSPAN
@@ -100,14 +98,6 @@ struct ezusb_hex_record {
#undef XIRCOM
#endif
-#ifdef KEYSPAN
-#include "keyspan_pda_fw.h"
-#endif
-
-#ifdef XIRCOM
-#include "xircom_pgs_fw.h"
-#endif
-
/*
* Version Information
*/
@@ -147,7 +137,7 @@ static struct usb_device_id id_table_combined [] = {
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
static struct usb_driver keyspan_pda_driver = {
.name = "keyspan_pda",
@@ -171,9 +161,9 @@ static struct usb_device_id id_table_fake [] = {
#ifdef XIRCOM
static struct usb_device_id id_table_fake_xircom [] = {
- { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
- { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
- { }
+ { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
+ { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
+ { }
};
#endif
@@ -183,7 +173,7 @@ static void keyspan_pda_wakeup_write(struct work_struct *work)
container_of(work, struct keyspan_pda_private, wakeup_work);
struct usb_serial_port *port = priv->port;
- tty_wakeup(port->tty);
+ tty_wakeup(port->port.tty);
}
static void keyspan_pda_request_unthrottle(struct work_struct *work)
@@ -196,7 +186,7 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work)
dbg(" request_unthrottle");
/* ask the device to tell us when the tx buffer becomes
sufficiently empty */
- result = usb_control_msg(serial->dev,
+ result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
7, /* request_unthrottle */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE
@@ -207,17 +197,16 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work)
0,
2000);
if (result < 0)
- dbg("%s - error %d from usb_control_msg",
+ dbg("%s - error %d from usb_control_msg",
__func__, result);
}
-static void keyspan_pda_rx_interrupt (struct urb *urb)
+static void keyspan_pda_rx_interrupt(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
- struct tty_struct *tty = port->tty;
+ struct tty_struct *tty = port->port.tty;
unsigned char *data = urb->transfer_buffer;
- int i;
int retval;
int status = urb->status;
struct keyspan_pda_private *priv;
@@ -240,14 +229,13 @@ static void keyspan_pda_rx_interrupt (struct urb *urb)
goto exit;
}
- /* see if the message is data or a status interrupt */
+ /* see if the message is data or a status interrupt */
switch (data[0]) {
case 0:
/* rest of message is rx data */
if (urb->actual_length) {
- for (i = 1; i < urb->actual_length ; ++i) {
- tty_insert_flip_char(tty, data[i], 0);
- }
+ tty_insert_flip_string(tty, data + 1,
+ urb->actual_length - 1);
tty_flip_buffer_push(tty);
}
break;
@@ -271,14 +259,14 @@ static void keyspan_pda_rx_interrupt (struct urb *urb)
}
exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
- err ("%s - usb_submit_urb failed with result %d",
+ err("%s - usb_submit_urb failed with result %d",
__func__, retval);
}
-static void keyspan_pda_rx_throttle (struct usb_serial_port *port)
+static void keyspan_pda_rx_throttle(struct tty_struct *tty)
{
/* stop receiving characters. We just turn off the URB request, and
let chars pile up in the device. If we're doing hardware
@@ -286,14 +274,15 @@ static void keyspan_pda_rx_throttle (struct usb_serial_port *port)
fills up. If we're doing XON/XOFF, this would be a good time to
send an XOFF, although it might make sense to foist that off
upon the device too. */
-
+ struct usb_serial_port *port = tty->driver_data;
dbg("keyspan_pda_rx_throttle port %d", port->number);
usb_kill_urb(port->interrupt_in_urb);
}
-static void keyspan_pda_rx_unthrottle (struct usb_serial_port *port)
+static void keyspan_pda_rx_unthrottle(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
/* just restart the receive interrupt URB */
dbg("keyspan_pda_rx_unthrottle port %d", port->number);
port->interrupt_in_urb->dev = port->serial->dev;
@@ -303,32 +292,52 @@ static void keyspan_pda_rx_unthrottle (struct usb_serial_port *port)
}
-static speed_t keyspan_pda_setbaud (struct usb_serial *serial, speed_t baud)
+static speed_t keyspan_pda_setbaud(struct usb_serial *serial, speed_t baud)
{
int rc;
int bindex;
- switch(baud) {
- case 110: bindex = 0; break;
- case 300: bindex = 1; break;
- case 1200: bindex = 2; break;
- case 2400: bindex = 3; break;
- case 4800: bindex = 4; break;
- case 9600: bindex = 5; break;
- case 19200: bindex = 6; break;
- case 38400: bindex = 7; break;
- case 57600: bindex = 8; break;
- case 115200: bindex = 9; break;
- default:
- bindex = 5; /* Default to 9600 */
- baud = 9600;
+ switch (baud) {
+ case 110:
+ bindex = 0;
+ break;
+ case 300:
+ bindex = 1;
+ break;
+ case 1200:
+ bindex = 2;
+ break;
+ case 2400:
+ bindex = 3;
+ break;
+ case 4800:
+ bindex = 4;
+ break;
+ case 9600:
+ bindex = 5;
+ break;
+ case 19200:
+ bindex = 6;
+ break;
+ case 38400:
+ bindex = 7;
+ break;
+ case 57600:
+ bindex = 8;
+ break;
+ case 115200:
+ bindex = 9;
+ break;
+ default:
+ bindex = 5; /* Default to 9600 */
+ baud = 9600;
}
/* rather than figure out how to sleep while waiting for this
to complete, I just use the "legacy" API. */
rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
0, /* set baud */
- USB_TYPE_VENDOR
+ USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
| USB_DIR_OUT, /* type */
bindex, /* value */
@@ -342,8 +351,9 @@ static speed_t keyspan_pda_setbaud (struct usb_serial *serial, speed_t baud)
}
-static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state)
+static void keyspan_pda_break_ctl(struct tty_struct *tty, int break_state)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
int value;
int result;
@@ -353,11 +363,11 @@ static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state
else
value = 0; /* clear break */
result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- 4, /* set break */
- USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
- value, 0, NULL, 0, 2000);
+ 4, /* set break */
+ USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ value, 0, NULL, 0, 2000);
if (result < 0)
- dbg("%s - error %d from usb_control_msg",
+ dbg("%s - error %d from usb_control_msg",
__func__, result);
/* there is something funky about this.. the TCSBRK that 'cu' performs
ought to translate into a break_ctl(-1),break_ctl(0) pair HZ/4
@@ -366,8 +376,8 @@ static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state
}
-static void keyspan_pda_set_termios (struct usb_serial_port *port,
- struct ktermios *old_termios)
+static void keyspan_pda_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
{
struct usb_serial *serial = port->serial;
speed_t speed;
@@ -392,7 +402,7 @@ static void keyspan_pda_set_termios (struct usb_serial_port *port,
For now, just do baud. */
- speed = tty_get_baud_rate(port->tty);
+ speed = tty_get_baud_rate(tty);
speed = keyspan_pda_setbaud(serial, speed);
if (speed == 0) {
@@ -402,8 +412,8 @@ static void keyspan_pda_set_termios (struct usb_serial_port *port,
}
/* Only speed can change so copy the old h/w parameters
then encode the new speed */
- tty_termios_copy_hw(port->tty->termios, old_termios);
- tty_encode_baud_rate(port->tty, speed, speed);
+ tty_termios_copy_hw(tty->termios, old_termios);
+ tty_encode_baud_rate(tty, speed, speed);
}
@@ -420,7 +430,7 @@ static int keyspan_pda_get_modem_info(struct usb_serial *serial,
3, /* get pins */
USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN,
0, 0, &data, 1, 2000);
- if (rc > 0)
+ if (rc >= 0)
*value = data;
return rc;
}
@@ -437,8 +447,9 @@ static int keyspan_pda_set_modem_info(struct usb_serial *serial,
return rc;
}
-static int keyspan_pda_tiocmget(struct usb_serial_port *port, struct file *file)
+static int keyspan_pda_tiocmget(struct tty_struct *tty, struct file *file)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
int rc;
unsigned char status;
@@ -457,9 +468,10 @@ static int keyspan_pda_tiocmget(struct usb_serial_port *port, struct file *file)
return value;
}
-static int keyspan_pda_tiocmset(struct usb_serial_port *port, struct file *file,
+static int keyspan_pda_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
+ struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
int rc;
unsigned char status;
@@ -481,23 +493,8 @@ static int keyspan_pda_tiocmset(struct usb_serial_port *port, struct file *file,
return rc;
}
-static int keyspan_pda_ioctl(struct usb_serial_port *port, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- switch (cmd) {
- case TIOCMIWAIT:
- /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
- /* TODO */
- case TIOCGICOUNT:
- /* return count of modemline transitions */
- return 0; /* TODO */
- }
-
- return -ENOIOCTLCMD;
-}
-
-static int keyspan_pda_write(struct usb_serial_port *port,
- const unsigned char *buf, int count)
+static int keyspan_pda_write(struct tty_struct *tty,
+ struct usb_serial_port *port, const unsigned char *buf, int count)
{
struct usb_serial *serial = port->serial;
int request_unthrottle = 0;
@@ -513,10 +510,10 @@ static int keyspan_pda_write(struct usb_serial_port *port,
select() or poll() too) until we receive that unthrottle interrupt.
Block if we can't write anything at all, otherwise write as much as
we can. */
- dbg("keyspan_pda_write(%d)",count);
+ dbg("keyspan_pda_write(%d)", count);
if (count == 0) {
dbg(" write request of 0 bytes");
- return (0);
+ return 0;
}
/* we might block because of:
@@ -543,7 +540,7 @@ static int keyspan_pda_write(struct usb_serial_port *port,
scheduler time, since usb_control_msg() sleeps. */
if (count > priv->tx_room && !in_interrupt()) {
unsigned char room;
- rc = usb_control_msg(serial->dev,
+ rc = usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
6, /* write_room */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE
@@ -574,7 +571,7 @@ static int keyspan_pda_write(struct usb_serial_port *port,
if (count) {
/* now transfer data */
- memcpy (port->write_urb->transfer_buffer, buf, count);
+ memcpy(port->write_urb->transfer_buffer, buf, count);
/* send the data out the bulk port */
port->write_urb->transfer_buffer_length = count;
@@ -586,8 +583,7 @@ static int keyspan_pda_write(struct usb_serial_port *port,
dbg(" usb_submit_urb(write bulk) failed");
goto exit;
}
- }
- else {
+ } else {
/* There wasn't any room left, so we are throttled until
the buffer empties a bit */
request_unthrottle = 1;
@@ -606,7 +602,7 @@ exit:
}
-static void keyspan_pda_write_bulk_callback (struct urb *urb)
+static void keyspan_pda_write_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct keyspan_pda_private *priv;
@@ -619,22 +615,21 @@ static void keyspan_pda_write_bulk_callback (struct urb *urb)
}
-static int keyspan_pda_write_room (struct usb_serial_port *port)
+static int keyspan_pda_write_room(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct keyspan_pda_private *priv;
-
priv = usb_get_serial_port_data(port);
-
/* used by n_tty.c for processing of tabs and such. Giving it our
conservative guess is probably good enough, but needs testing by
running a console through the device. */
-
- return (priv->tx_room);
+ return priv->tx_room;
}
-static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port)
+static int keyspan_pda_chars_in_buffer(struct tty_struct *tty)
{
+ struct usb_serial_port *port = tty->driver_data;
struct keyspan_pda_private *priv;
unsigned long flags;
int ret = 0;
@@ -652,7 +647,8 @@ static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port)
}
-static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
+static int keyspan_pda_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
unsigned char room;
@@ -684,8 +680,8 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
/* the normal serial device seems to always turn on DTR and RTS here,
so do the same */
- if (port->tty->termios->c_cflag & CBAUD)
- keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2) );
+ if (tty && (tty->termios->c_cflag & CBAUD))
+ keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2));
else
keyspan_pda_set_modem_info(serial, 0);
@@ -702,13 +698,15 @@ error:
}
-static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
+static void keyspan_pda_close(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
if (serial->dev) {
- /* the normal serial device seems to always shut off DTR and RTS now */
- if (port->tty->termios->c_cflag & HUPCL)
+ /* the normal serial device seems to always shut
+ off DTR and RTS now */
+ if (tty->termios->c_cflag & HUPCL)
keyspan_pda_set_modem_info(serial, 0);
/* shutdown our bulk reads and writes */
@@ -719,50 +717,59 @@ static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
/* download the firmware to a "fake" device (pre-renumeration) */
-static int keyspan_pda_fake_startup (struct usb_serial *serial)
+static int keyspan_pda_fake_startup(struct usb_serial *serial)
{
int response;
- const struct ezusb_hex_record *record = NULL;
+ const char *fw_name;
+ const struct ihex_binrec *record;
+ const struct firmware *fw;
/* download the firmware here ... */
response = ezusb_set_reset(serial, 1);
+ if (0) { ; }
#ifdef KEYSPAN
- if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID)
- record = &keyspan_pda_firmware[0];
+ else if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID)
+ fw_name = "keyspan_pda/keyspan_pda.fw";
#endif
#ifdef XIRCOM
- if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) ||
- (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID))
- record = &xircom_pgs_firmware[0];
+ else if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) ||
+ (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID))
+ fw_name = "keyspan_pda/xircom_pgs.fw";
#endif
- if (record == NULL) {
+ else {
err("%s: unknown vendor, aborting.", __func__);
return -ENODEV;
}
+ if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) {
+ err("failed to load firmware \"%s\"\n", fw_name);
+ return -ENOENT;
+ }
+ record = (const struct ihex_binrec *)fw->data;
- while(record->address != 0xffff) {
- response = ezusb_writememory(serial, record->address,
+ while (record) {
+ response = ezusb_writememory(serial, be32_to_cpu(record->addr),
(unsigned char *)record->data,
- record->data_size, 0xa0);
+ be16_to_cpu(record->len), 0xa0);
if (response < 0) {
err("ezusb_writememory failed for Keyspan PDA "
"firmware (%d %04X %p %d)",
- response,
- record->address, record->data, record->data_size);
+ response, be32_to_cpu(record->addr),
+ record->data, be16_to_cpu(record->len));
break;
}
- record++;
+ record = ihex_next_binrec(record);
}
+ release_firmware(fw);
/* bring device out of reset. Renumeration will occur in a moment
and the new device will bind to the real driver */
response = ezusb_set_reset(serial, 0);
/* we want this device to fail to have a driver assigned to it. */
- return (1);
+ return 1;
}
-static int keyspan_pda_startup (struct usb_serial *serial)
+static int keyspan_pda_startup(struct usb_serial *serial)
{
struct keyspan_pda_private *priv;
@@ -772,20 +779,20 @@ static int keyspan_pda_startup (struct usb_serial *serial)
priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL);
if (!priv)
- return (1); /* error */
+ return 1; /* error */
usb_set_serial_port_data(serial->port[0], priv);
init_waitqueue_head(&serial->port[0]->write_wait);
INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write);
INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle);
priv->serial = serial;
priv->port = serial->port[0];
- return (0);
+ return 0;
}
-static void keyspan_pda_shutdown (struct usb_serial *serial)
+static void keyspan_pda_shutdown(struct usb_serial *serial)
{
dbg("%s", __func__);
-
+
kfree(usb_get_serial_port_data(serial->port[0]));
}
@@ -835,7 +842,6 @@ static struct usb_serial_driver keyspan_pda_device = {
.chars_in_buffer = keyspan_pda_chars_in_buffer,
.throttle = keyspan_pda_rx_throttle,
.unthrottle = keyspan_pda_rx_unthrottle,
- .ioctl = keyspan_pda_ioctl,
.set_termios = keyspan_pda_set_termios,
.break_ctl = keyspan_pda_break_ctl,
.tiocmget = keyspan_pda_tiocmget,
@@ -845,7 +851,7 @@ static struct usb_serial_driver keyspan_pda_device = {
};
-static int __init keyspan_pda_init (void)
+static int __init keyspan_pda_init(void)
{
int retval;
retval = usb_serial_register(&keyspan_pda_device);
@@ -866,7 +872,7 @@ static int __init keyspan_pda_init (void)
goto failed_usb_register;
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
-failed_usb_register:
+failed_usb_register:
#ifdef XIRCOM
usb_serial_deregister(&xircom_pgs_fake_device);
failed_xircom_register:
@@ -883,15 +889,15 @@ failed_pda_register:
}
-static void __exit keyspan_pda_exit (void)
+static void __exit keyspan_pda_exit(void)
{
- usb_deregister (&keyspan_pda_driver);
- usb_serial_deregister (&keyspan_pda_device);
+ usb_deregister(&keyspan_pda_driver);
+ usb_serial_deregister(&keyspan_pda_device);
#ifdef KEYSPAN
- usb_serial_deregister (&keyspan_pda_fake_device);
+ usb_serial_deregister(&keyspan_pda_fake_device);
#endif
#ifdef XIRCOM
- usb_serial_deregister (&xircom_pgs_fake_device);
+ usb_serial_deregister(&xircom_pgs_fake_device);
#endif
}
@@ -899,8 +905,8 @@ static void __exit keyspan_pda_exit (void)
module_init(keyspan_pda_init);
module_exit(keyspan_pda_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);