X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fserial%2Fir-usb.c;h=8fdf486e346528a2d36363003e1e133dcf9e6310;hb=refs%2Fheads%2Fvserver;hp=0adcbb1f813b4595a77092fe36560fb8099cec25;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 0adcbb1f8..8fdf486e3 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -46,7 +46,6 @@ * initial version released. */ -#include #include #include #include @@ -58,14 +57,7 @@ #include #include #include - -#ifdef CONFIG_USB_SERIAL_DEBUG - static int debug = 1; -#else - static int debug; -#endif - -#include "usb-serial.h" +#include /* * Version Information @@ -101,19 +93,21 @@ struct irda_class_desc { 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; @@ -130,17 +124,20 @@ static struct usb_device_id id_table [] = { 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, @@ -186,15 +183,14 @@ static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, 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)) { @@ -327,10 +323,10 @@ static void ir_close (struct usb_serial_port *port, struct file * filp) 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; @@ -346,10 +342,14 @@ static int ir_write (struct usb_serial_port *port, int from_user, const unsigned 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); @@ -364,12 +364,7 @@ static int ir_write (struct usb_serial_port *port, int from_user, const unsigned *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, @@ -384,35 +379,38 @@ static int ir_write (struct usb_serial_port *port, int from_user, const unsigned 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; @@ -439,7 +437,8 @@ static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs) ir_baud = *data & 0x0f; usb_serial_debug_data ( - __FILE__, + debug, + &port->dev, __FUNCTION__, urb->actual_length, data); @@ -452,6 +451,9 @@ static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs) */ tty = port->tty; + /* + * FIXME: must not do this in IRQ context + */ tty->ldisc.receive_buf( tty, data+1, @@ -495,7 +497,7 @@ static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs) 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; @@ -614,10 +616,10 @@ MODULE_AUTHOR(DRIVER_AUTHOR); 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");