* initial version released.
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-
-#ifdef CONFIG_USB_SERIAL_DEBUG
- static int debug = 1;
-#else
- static int debug;
-#endif
-
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
/*
* Version Information
u8 bMaxUnicastList;
} __attribute__ ((packed));
+static int debug;
+
/* if overridden by the user, then use their value for the size of the read and
* write urbs */
-static int buffer_size = 0;
+static int buffer_size;
/* if overridden by the user, then use the specified number of XBOFs */
static int xbof = -1;
static int ir_startup (struct usb_serial *serial);
static int ir_open (struct usb_serial_port *port, struct file *filep);
static void ir_close (struct usb_serial_port *port, struct file *filep);
-static int ir_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
-static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
-static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
-static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios);
+static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int count);
+static void ir_write_bulk_callback (struct urb *urb);
+static void ir_read_bulk_callback (struct urb *urb);
+static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
static u8 ir_baud = 0;
static u8 ir_xbof = 0;
MODULE_DEVICE_TABLE (usb, id_table);
static struct usb_driver ir_driver = {
- .owner = THIS_MODULE,
.name = "ir-usb",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.id_table = id_table,
+ .no_dynamic_id = 1,
};
-static struct usb_serial_device_type ir_device = {
- .owner = THIS_MODULE,
- .name = "IR Dongle",
+static struct usb_serial_driver ir_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ir-usb",
+ },
+ .description = "IR Dongle",
.id_table = id_table,
.num_interrupt_in = 1,
.num_bulk_in = 1,
struct irda_class_desc *desc;
int ret;
- desc = kmalloc(sizeof (struct irda_class_desc), GFP_KERNEL);
+ desc = kzalloc(sizeof (struct irda_class_desc), GFP_KERNEL);
if (desc == NULL)
return NULL;
- memset(desc, 0, sizeof(struct irda_class_desc));
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev,0),
IU_REQ_GET_CLASS_DESC,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, ifnum, desc, sizeof(*desc), HZ);
+ 0, ifnum, desc, sizeof(*desc), 1000);
dbg("%s - ret=%d", __FUNCTION__, ret);
if (ret < sizeof(*desc)) {
dbg("%s - port %d", __FUNCTION__, port->number);
/* shutdown our bulk read */
- usb_unlink_urb (port->read_urb);
+ usb_kill_urb(port->read_urb);
}
-static int ir_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
+static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int count)
{
unsigned char *transfer_buffer;
int result;
if (count == 0)
return 0;
- if (port->write_urb->status == -EINPROGRESS) {
- dbg ("%s - already writing", __FUNCTION__);
+ spin_lock_bh(&port->lock);
+ if (port->write_urb_busy) {
+ spin_unlock_bh(&port->lock);
+ dbg("%s - already writing", __FUNCTION__);
return 0;
}
+ port->write_urb_busy = 1;
+ spin_unlock_bh(&port->lock);
transfer_buffer = port->write_urb->transfer_buffer;
transfer_size = min(count, port->bulk_out_size - 1);
*transfer_buffer = ir_xbof | ir_baud;
++transfer_buffer;
- if (from_user) {
- if (copy_from_user (transfer_buffer, buf, transfer_size))
- return -EFAULT;
- } else {
- memcpy (transfer_buffer, buf, transfer_size);
- }
+ memcpy (transfer_buffer, buf, transfer_size);
usb_fill_bulk_urb (
port->write_urb,
port->write_urb->transfer_flags = URB_ZERO_PACKET;
result = usb_submit_urb (port->write_urb, GFP_ATOMIC);
- if (result)
+ if (result) {
+ port->write_urb_busy = 0;
dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
- else
+ } else
result = transfer_size;
return result;
}
-static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void ir_write_bulk_callback (struct urb *urb)
{
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
dbg("%s - port %d", __FUNCTION__, port->number);
-
+
+ port->write_urb_busy = 0;
if (urb->status) {
dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
return;
}
usb_serial_debug_data (
- __FILE__,
+ debug,
+ &port->dev,
__FUNCTION__,
urb->actual_length,
urb->transfer_buffer);
- schedule_work(&port->work);
+ usb_serial_port_softint(port);
}
-static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void ir_read_bulk_callback (struct urb *urb)
{
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct tty_struct *tty;
ir_baud = *data & 0x0f;
usb_serial_debug_data (
- __FILE__,
+ debug,
+ &port->dev,
__FUNCTION__,
urb->actual_length,
data);
*/
tty = port->tty;
+ /*
+ * FIXME: must not do this in IRQ context
+ */
tty->ldisc.receive_buf(
tty,
data+1,
return;
}
-static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
{
unsigned char *transfer_buffer;
unsigned int cflag;
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
+module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
-MODULE_PARM(xbof, "i");
+module_param(xbof, int, 0);
MODULE_PARM_DESC(xbof, "Force specific number of XBOFs");
-MODULE_PARM(buffer_size, "i");
+module_param(buffer_size, int, 0);
MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers");