/*
* Infinity Unlimited USB Phoenix driver
*
* Copyright (C) 2007 Alain Degreffe (eczema@ecze.com)
*
* Original code taken from iuutool (Copyright (C) 2006 Juan Carlos Borrás)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* And tested with help of WB Electronics
*
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "iuu_phoenix.h"
#include <linux/random.h>
#ifdef CONFIG_USB_SERIAL_DEBUG
static int debug = 1;
#else
static int debug;
#endif
/*
* Version Information
*/
#define DRIVER_VERSION "v0.5"
#define DRIVER_DESC "Infinity USB Unlimited Phoenix driver"
static struct usb_device_id id_table[] = {
{USB_DEVICE(IUU_USB_VENDOR_ID, IUU_USB_PRODUCT_ID)},
{} /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver iuu_driver = {
.name = "iuu_phoenix",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.id_table = id_table,
.no_dynamic_id = 1,
};
/* turbo parameter */
static int boost = 100;
static int clockmode = 1;
static int cdmode = 1;
static int iuu_cardin;
static int iuu_cardout;
static int xmas;
static void read_rxcmd_callback(struct urb *urb);
struct iuu_private {
spinlock_t lock; /* store irq state */
wait_queue_head_t delta_msr_wait;
u8 line_control;
u8 line_status;
u8 termios_initialized;
int tiostatus; /* store IUART SIGNAL for tiocmget call */
u8 reset; /* if 1 reset is needed */
int poll; /* number of poll */
u8 *writebuf; /* buffer for writing to device */
int writelen; /* num of byte to write to device */
u8 *buf; /* used for initialize speed */
u8 *dbgbuf; /* debug buffer */
u8 len;
};
static void iuu_free_buf(struct iuu_private *priv)
{
kfree(priv->buf);
kfree(priv->dbgbuf);
kfree(priv->writebuf);
}
static int iuu_alloc_buf(struct iuu_private *priv)
{
priv->buf = kzalloc(256, GFP_KERNEL);
priv->dbgbuf = kzalloc(256, GFP_KERNEL);
priv->writebuf = kzalloc(256, GFP_KERNEL);
if (!priv->buf || !priv->dbgbuf || !priv->writebuf) {
iuu_free_buf(priv);
dbg("%s problem allocation buffer", __FUNCTION__);
return -ENOMEM;
}
dbg("%s - Privates buffers allocation success", __FUNCTION__);
return 0;
}
static int iuu_startup(struct usb_serial *serial)
{
struct iuu_private *priv;
priv = kza