X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fserial%2Fipw.c;h=d3b9a351cef8ae9f3ecbf585e27d225b1665fc43;hb=refs%2Fheads%2Fvserver;hp=20977939271c8dc5a850fb8897a263757825505c;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 209779392..d3b9a351c 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c @@ -46,9 +46,8 @@ #include #include #include -#include +#include #include -#include "usb-serial.h" /* * Version Information @@ -153,21 +152,20 @@ static struct usb_device_id usb_ipw_ids[] = { MODULE_DEVICE_TABLE(usb, usb_ipw_ids); static struct usb_driver usb_ipw_driver = { - .owner = THIS_MODULE, .name = "ipwtty", .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, .id_table = usb_ipw_ids, + .no_dynamic_id = 1, }; static int debug; -static void ipw_read_bulk_callback(struct urb *urb, struct pt_regs *regs) +static void ipw_read_bulk_callback(struct urb *urb) { struct usb_serial_port *port = urb->context; unsigned char *data = urb->transfer_buffer; struct tty_struct *tty; - int i; int result; dbg("%s - port %d", __FUNCTION__, port->number); @@ -181,14 +179,8 @@ static void ipw_read_bulk_callback(struct urb *urb, struct pt_regs *regs) tty = port->tty; if (tty && urb->actual_length) { - for (i = 0; i < urb->actual_length ; ++i) { - /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { - tty_flip_buffer_push(tty); - } - /* this doesn't actually push the data through unless tty->low_latency is set */ - tty_insert_flip_char(tty, data[i], 0); - } + tty_buffer_request_room(tty, urb->actual_length); + tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } @@ -214,10 +206,9 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) dbg("%s", __FUNCTION__); - buf_flow_init = kmalloc(16, GFP_KERNEL); + buf_flow_init = kmemdup(buf_flow_static, 16, GFP_KERNEL); if (!buf_flow_init) return -ENOMEM; - memcpy(buf_flow_init, buf_flow_static, 16); if (port->tty) port->tty->low_latency = 1; @@ -232,7 +223,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) 0, /* index */ NULL, 0, - 100*HZ); + 100000); if (result < 0) dev_err(&port->dev, "Init of modem failed (error = %d)", result); @@ -260,7 +251,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) 0, /* index */ NULL, 0, - 100*HZ); + 100000); if (result < 0) dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)", result); @@ -273,7 +264,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) 0, buf_flow_init, 0x10, - 200*HZ); + 200000); if (result < 0) dev_err(&port->dev, "initial flowcontrol failed (error = %d)", result); @@ -287,7 +278,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) 0, NULL, 0, - 200*HZ); + 200000); if (result < 0) dev_err(&port->dev, "setting dtr failed (error = %d)", result); @@ -300,7 +291,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) 0, NULL, 0, - 200*HZ); + 200000); if (result < 0) dev_err(&port->dev, "setting dtr failed (error = %d)", result); @@ -327,7 +318,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) 0, NULL, 0, - 200*HZ); + 200000); if (result < 0) dev_err(&port->dev, "dropping dtr failed (error = %d)", result); @@ -339,7 +330,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) 0, NULL, 0, - 200*HZ); + 200000); if (result < 0) dev_err(&port->dev, "dropping rts failed (error = %d)", result); @@ -352,7 +343,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) 0, NULL, 0, - 200*HZ); + 200000); if (result < 0) dev_err(&port->dev, "purge failed (error = %d)", result); @@ -365,7 +356,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) 0, /* index */ NULL, 0, - 100*HZ); + 100000); if (result < 0) dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)", result); @@ -375,16 +366,18 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) usb_kill_urb(port->write_urb); } -static void ipw_write_bulk_callback(struct urb *urb, struct pt_regs *regs) +static void ipw_write_bulk_callback(struct urb *urb) { struct usb_serial_port *port = urb->context; dbg("%s", __FUNCTION__); + port->write_urb_busy = 0; + if (urb->status) dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); - schedule_work(&port->work); + usb_serial_port_softint(port); } static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int count) @@ -399,16 +392,21 @@ static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int dbg("%s - write request of 0 bytes", __FUNCTION__); return 0; } - - /* Racy and broken, FIXME properly! */ - if (port->write_urb->status == -EINPROGRESS) + + 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); count = min(count, port->bulk_out_size); memcpy(port->bulk_out_buffer, buf, count); dbg("%s count now:%d", __FUNCTION__, count); - + usb_fill_bulk_urb(port->write_urb, dev, usb_sndbulkpipe(dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, @@ -418,6 +416,7 @@ static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int ret = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (ret != 0) { + port->write_urb_busy = 0; dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __FUNCTION__, ret); return ret; } @@ -437,10 +436,12 @@ static int ipw_disconnect(struct usb_serial_port *port) return 0; } -static struct usb_serial_device_type ipw_device = { - .owner = THIS_MODULE, - .name = "IPWireless converter", - .short_name = "ipw", +static struct usb_serial_driver ipw_device = { + .driver = { + .owner = THIS_MODULE, + .name = "ipw", + }, + .description = "IPWireless converter", .id_table = usb_ipw_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 1, @@ -457,7 +458,7 @@ static struct usb_serial_device_type ipw_device = { -int usb_ipw_init(void) +static int usb_ipw_init(void) { int retval; @@ -473,7 +474,7 @@ int usb_ipw_init(void) return 0; } -void usb_ipw_exit(void) +static void usb_ipw_exit(void) { usb_deregister(&usb_ipw_driver); usb_serial_deregister(&ipw_device);