diff -Nru a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c --- a/drivers/usb/serial/belkin_sa.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/belkin_sa.c Wed Feb 27 00:27:05 2002 @@ -207,8 +207,6 @@ dbg(__FUNCTION__" port %d", port->number); - down (&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -230,8 +228,6 @@ } exit: - up (&port->sem); - return retval; } /* belkin_sa_open */ @@ -249,8 +245,6 @@ dbg(__FUNCTION__" port %d", port->number); - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -262,8 +256,6 @@ } port->open_count = 0; } - - up (&port->sem); } /* belkin_sa_close */ diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c --- a/drivers/usb/serial/cyberjack.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/cyberjack.c Wed Feb 27 00:27:05 2002 @@ -151,8 +151,6 @@ dbg(__FUNCTION__ " - port %d", port->number); - down (&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -179,8 +177,6 @@ dbg(__FUNCTION__ " - usb_submit_urb(int urb)"); } - up (&port->sem); - return result; } @@ -188,8 +184,6 @@ { dbg(__FUNCTION__ " - port %d", port->number); - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -201,8 +195,6 @@ } port->open_count = 0; } - - up (&port->sem); } static int cyberjack_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count) @@ -225,19 +217,15 @@ return (0); } - down (&port->sem); - if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) { /* To much data for buffer. Reset buffer. */ priv->wrfilled=0; - up (&port->sem); return (0); } /* Copy data */ if (from_user) { if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count)) { - up (&port->sem); return -EFAULT; } } else { @@ -280,7 +268,6 @@ /* Throw away data. No better idea what to do with it. */ priv->wrfilled=0; priv->wrsent=0; - up (&port->sem); return 0; } @@ -295,7 +282,6 @@ } } - up (&port->sem); return (count); } @@ -435,8 +421,6 @@ return; } - down (&port->sem); - dbg(__FUNCTION__ " - transmitting data (frame n)"); length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ? @@ -462,7 +446,6 @@ /* Throw away data. No better idea what to do with it. */ priv->wrfilled=0; priv->wrsent=0; - up (&port->sem); queue_task(&port->tqueue, &tq_immediate); mark_bh(IMMEDIATE_BH); return; @@ -480,7 +463,6 @@ priv->wrsent=0; } - up (&port->sem); queue_task(&port->tqueue, &tq_immediate); mark_bh(IMMEDIATE_BH); return; diff -Nru a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c --- a/drivers/usb/serial/empeg.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/empeg.c Wed Feb 27 00:27:05 2002 @@ -157,8 +157,6 @@ dbg(__FUNCTION__ " - port %d", port->number); - down (&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -189,8 +187,6 @@ } - up (&port->sem); - return result; } @@ -208,8 +204,6 @@ if (!serial) return; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -220,8 +214,6 @@ port->open_count = 0; } - up (&port->sem); - /* Uncomment the following line if you want to see some statistics in your syslog */ /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */ } @@ -462,15 +454,7 @@ static void empeg_throttle (struct usb_serial_port *port) { dbg(__FUNCTION__ " - port %d", port->number); - - down (&port->sem); - usb_unlink_urb (port->read_urb); - - up (&port->sem); - - return; - } @@ -480,8 +464,6 @@ dbg(__FUNCTION__ " - port %d", port->number); - down (&port->sem); - port->read_urb->dev = port->serial->dev; result = usb_submit_urb(port->read_urb, GFP_KERNEL); @@ -489,10 +471,7 @@ if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); - up (&port->sem); - return; - } diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c --- a/drivers/usb/serial/ftdi_sio.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/ftdi_sio.c Wed Feb 27 00:27:05 2002 @@ -319,8 +319,6 @@ dbg(__FUNCTION__); - down (&port->sem); - ++port->open_count; if (port->open_count == 1){ @@ -361,7 +359,6 @@ err(__FUNCTION__ " - failed submitting read urb, error %d", result); } - up (&port->sem); return result; } /* ftdi_sio_open */ @@ -374,7 +371,6 @@ dbg( __FUNCTION__); - down (&port->sem); --port->open_count; if (port->open_count <= 0) { @@ -411,9 +407,6 @@ tty_hangup(port->tty); } } - - up (&port->sem); - } /* ftdi_sio_close */ @@ -447,8 +440,6 @@ return (0); } - down(&port->sem); - count += data_offset; count = (count > port->bulk_out_size) ? port->bulk_out_size : count; @@ -456,7 +447,6 @@ if (from_user) { if (copy_from_user(port->write_urb->transfer_buffer + data_offset, buf, count - data_offset )){ - up (&port->sem); return -EFAULT; } } else { @@ -482,14 +472,11 @@ result = usb_submit_urb(port->write_urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting write urb, error %d", result); - up (&port->sem); return 0; } - up (&port->sem); dbg(__FUNCTION__ " write returning: %d", count - data_offset); return (count - data_offset); - } /* ftdi_sio_write */ static void ftdi_sio_write_bulk_callback (struct urb *urb) diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c --- a/drivers/usb/serial/ipaq.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/ipaq.c Wed Feb 27 00:27:05 2002 @@ -109,8 +109,6 @@ dbg(__FUNCTION__ " - port %d", port->number); - down(&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -198,8 +196,6 @@ } } - up(&port->sem); - return result; enomem: @@ -224,8 +220,6 @@ serial = get_usb_serial(port, __FUNCTION__); if (!serial) return; - - down (&port->sem); --port->open_count; @@ -243,8 +237,6 @@ port->open_count = 0; } - up (&port->sem); - /* Uncomment the following line if you want to see some statistics in your syslog */ /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */ } diff -Nru a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c --- a/drivers/usb/serial/ir-usb.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/ir-usb.c Wed Feb 27 00:27:05 2002 @@ -252,8 +252,6 @@ dbg("%s - port %d", __FUNCTION__, port->number); - down (&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -293,9 +291,6 @@ if (result) err("%s - failed submitting read urb, error %d", __FUNCTION__, result); } - - up (&port->sem); - return result; } @@ -312,8 +307,6 @@ if (!serial) return; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -324,7 +317,6 @@ port->open_count = 0; } - up (&port->sem); } static int ir_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count) diff -Nru a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c --- a/drivers/usb/serial/keyspan.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/keyspan.c Wed Feb 27 00:27:05 2002 @@ -861,10 +861,8 @@ dbg("keyspan_open called for port%d.\n", port->number); - down (&port->sem); already_active = port->open_count; ++port->open_count; - up (&port->sem); if (already_active) return 0; @@ -926,8 +924,6 @@ p_priv->out_flip = 0; p_priv->in_flip = 0; - down (&port->sem); - if (--port->open_count <= 0) { if (serial->dev) { /* Stop reading/writing urbs */ @@ -941,7 +937,6 @@ port->open_count = 0; port->tty = 0; } - up (&port->sem); } diff -Nru a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c --- a/drivers/usb/serial/keyspan_pda.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/keyspan_pda.c Wed Feb 27 00:27:05 2002 @@ -662,8 +662,6 @@ int rc = 0; struct keyspan_pda_private *priv; - down (&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -707,12 +705,9 @@ } - - up (&port->sem); return rc; error: --port->open_count; - up (&port->sem); return rc; } @@ -721,8 +716,6 @@ { struct usb_serial *serial = port->serial; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -737,8 +730,6 @@ } port->open_count = 0; } - - up (&port->sem); } diff -Nru a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c --- a/drivers/usb/serial/kl5kusb105.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/kl5kusb105.c Wed Feb 27 00:27:05 2002 @@ -358,8 +358,6 @@ dbg(__FUNCTION__" port %d", port->number); - down (&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -437,8 +435,6 @@ } exit: - up (&port->sem); - return retval; } /* klsi_105_open */ @@ -455,8 +451,6 @@ if(!serial) return; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -482,8 +476,6 @@ port->open_count = 0; info("kl5kusb105 port stats: %ld bytes in, %ld bytes out", priv->bytes_in, priv->bytes_out); } - - up (&port->sem); } /* klsi_105_close */ @@ -505,9 +497,6 @@ dbg(__FUNCTION__ " - port %d", port->number); - down (&port->sem); /* to lock against someone else trying to - take an URB we just selected from the pool */ - while (count > 0) { /* try to find a free urb (write 0 bytes if none) */ struct urb *urb = NULL; @@ -543,7 +532,6 @@ if (from_user) { if (copy_from_user(urb->transfer_buffer + KLSI_105_DATA_OFFSET, buf, size)) { - up (&port->sem); return -EFAULT; } } else { @@ -578,7 +566,6 @@ count -= size; } exit: - up (&port->sem); priv->bytes_out+=bytes_sent; return bytes_sent; /* that's how much we wrote */ @@ -1021,34 +1008,21 @@ static void klsi_105_throttle (struct usb_serial_port *port) { - dbg(__FUNCTION__ " - port %d", port->number); - - down (&port->sem); - usb_unlink_urb (port->read_urb); - - up (&port->sem); - - return; } + static void klsi_105_unthrottle (struct usb_serial_port *port) { int result; dbg(__FUNCTION__ " - port %d", port->number); - down (&port->sem); - port->read_urb->dev = port->serial->dev; result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); - - up (&port->sem); - - return; } diff -Nru a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c --- a/drivers/usb/serial/mct_u232.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/mct_u232.c Wed Feb 27 00:27:05 2002 @@ -341,8 +341,6 @@ dbg(__FUNCTION__" port %d", port->number); - down (&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -398,8 +396,6 @@ } exit: - up (&port->sem); - return 0; } /* mct_u232_open */ @@ -408,8 +404,6 @@ { dbg(__FUNCTION__" port %d", port->number); - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -421,8 +415,6 @@ } port->open_count = 0; } - - up (&port->sem); } /* mct_u232_close */ @@ -454,16 +446,12 @@ bytes_sent = 0; while (count > 0) { - - down (&port->sem); - size = (count > port->bulk_out_size) ? port->bulk_out_size : count; usb_serial_debug_data (__FILE__, __FUNCTION__, size, buf); if (from_user) { if (copy_from_user(port->write_urb->transfer_buffer, buf, size)) { - up (&port->sem); return -EFAULT; } } @@ -486,11 +474,8 @@ if (result) { err(__FUNCTION__ " - failed submitting write urb, error %d", result); - up (&port->sem); return result; } - - up (&port->sem); bytes_sent += size; if (write_blocking) diff -Nru a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c --- a/drivers/usb/serial/omninet.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/omninet.c Wed Feb 27 00:27:05 2002 @@ -157,8 +157,6 @@ if (!serial) return -ENODEV; - down (&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -166,7 +164,6 @@ if( !od ) { err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct omninet_data)); port->open_count = 0; - up (&port->sem); return -ENOMEM; } @@ -184,8 +181,6 @@ err(__FUNCTION__ " - failed submitting read urb, error %d", result); } - up (&port->sem); - return result; } @@ -204,8 +199,6 @@ if (!serial) return; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -220,8 +213,6 @@ if (od) kfree(od); } - - up (&port->sem); } diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c --- a/drivers/usb/serial/pl2303.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/pl2303.c Wed Feb 27 00:27:05 2002 @@ -367,8 +367,6 @@ dbg (__FUNCTION__ " - port %d", port->number); - down (&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -407,7 +405,6 @@ result = usb_submit_urb (port->read_urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting read urb, error %d", result); - up (&port->sem); pl2303_close (port, NULL); return -EPROTO; } @@ -417,12 +414,10 @@ result = usb_submit_urb (port->interrupt_in_urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting interrupt urb, error %d", result); - up (&port->sem); pl2303_close (port, NULL); return -EPROTO; } } - up (&port->sem); return 0; } @@ -442,8 +437,6 @@ dbg (__FUNCTION__ " - port %d", port->number); - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { if (serial->dev) { @@ -478,8 +471,6 @@ } port->open_count = 0; } - - up (&port->sem); } static int set_modem_info (struct usb_serial_port *port, unsigned int cmd, unsigned int *value) diff -Nru a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c --- a/drivers/usb/serial/usbserial.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/usbserial.c Wed Feb 27 00:27:05 2002 @@ -1,7 +1,7 @@ /* * USB Serial Converter driver * - * Copyright (C) 1999 - 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) * Copyright (c) 2000 Peter Berger (pberger@brimson.com) * Copyright (c) 2000 Al Borchers (borchers@steinerpoint.com) * @@ -15,6 +15,13 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (02/26/2002) gkh + * Moved all locking into the main serial_* functions, instead of having + * the individual drivers have to grab the port semaphore. This should + * reduce races. + * Reworked the MOD_INC logic a bit to always increment and decrement, even + * if the generic driver is being used. + * * (10/10/2001) gkh * usb_serial_disconnect() now sets the serial->dev pointer is to NULL to * help prevent child drivers from accessing the device since it is now @@ -337,6 +344,7 @@ /* All of the device info needed for the Generic Serial Converter */ static struct usb_serial_device_type generic_device = { + owner: THIS_MODULE, name: "Generic", id_table: generic_device_ids, num_interrupt_in: NUM_DONT_CARE, @@ -345,13 +353,6 @@ num_ports: 1, shutdown: generic_shutdown, }; - -#define if_generic_do(x) \ - if ((serial->vendor == vendor) && \ - (serial->product == product)) \ - x -#else -#define if_generic_do(x) #endif @@ -392,8 +393,6 @@ static struct termios * serial_termios[SERIAL_TTY_MINORS]; static struct termios * serial_termios_locked[SERIAL_TTY_MINORS]; static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ - - static LIST_HEAD(usb_serial_driver_list); @@ -402,7 +401,6 @@ return serial_table[minor]; } - static struct usb_serial *get_free_serial (int num_ports, unsigned int *minor) { struct usb_serial *serial = NULL; @@ -439,7 +437,6 @@ return NULL; } - static void return_serial (struct usb_serial *serial) { int i; @@ -456,7 +453,6 @@ return; } - #ifdef USES_EZUSB_FUNCTIONS /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ #define CPUCS_REG 0x7F92 @@ -483,7 +479,6 @@ return result; } - int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit) { int response; @@ -497,7 +492,6 @@ #endif /* USES_EZUSB_FUNCTIONS */ - /***************************************************************************** * Driver tty interface functions *****************************************************************************/ @@ -516,266 +510,293 @@ /* get the serial object associated with this tty pointer */ serial = get_serial_by_minor (minor(tty->device)); - if (serial_paranoia_check (serial, __FUNCTION__)) { + if (serial_paranoia_check (serial, __FUNCTION__)) return -ENODEV; - } /* set up our port structure making the tty driver remember our port object, and us it */ portNumber = minor(tty->device) - serial->minor; port = &serial->port[portNumber]; tty->driver_data = port; + + down (&port->sem); port->tty = tty; + /* lock this module before we call it */ + if (serial->type->owner) + __MOD_INC_USE_COUNT(serial->type->owner); + /* pass on to the driver specific version of this function if it is available */ - if (serial->type->open) { - if (serial->type->owner) - __MOD_INC_USE_COUNT(serial->type->owner); + if (serial->type->open) retval = serial->type->open(port, filp); - if (retval) - __MOD_DEC_USE_COUNT(serial->type->owner); - } else { + else retval = generic_open(port, filp); - } + if (retval) + __MOD_DEC_USE_COUNT(serial->type->owner); + + up (&port->sem); return retval; } - static void serial_close(struct tty_struct *tty, struct file * filp) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); - if (!serial) { + if (!serial) return; - } + + down (&port->sem); dbg(__FUNCTION__ " - port %d", port->number); + if (tty->driver_data == NULL) { + /* disconnect beat us to the punch here, so handle it gracefully */ + goto exit; + } if (!port->open_count) { dbg (__FUNCTION__ " - port not opened"); - return; + goto exit_no_mod_dec; } /* pass on to the driver specific version of this function if it is available */ - if (serial->type->close) { + if (serial->type->close) serial->type->close(port, filp); - if (serial->type->owner) - __MOD_DEC_USE_COUNT(serial->type->owner); - } else { + else generic_close(port, filp); - } -} +exit: + if (serial->type->owner) + __MOD_DEC_USE_COUNT(serial->type->owner); + +exit_no_mod_dec: + up (&port->sem); +} static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); + int retval = -EINVAL; - if (!serial) { + if (!serial) return -ENODEV; - } - + + down (&port->sem); + dbg(__FUNCTION__ " - port %d, %d byte(s)", port->number, count); if (!port->open_count) { dbg (__FUNCTION__ " - port not opened"); - return -EINVAL; + goto exit; } /* pass on to the driver specific version of this function if it is available */ - if (serial->type->write) { - return (serial->type->write(port, from_user, buf, count)); - } else { - return (generic_write(port, from_user, buf, count)); - } -} + if (serial->type->write) + retval = serial->type->write(port, from_user, buf, count); + else + retval = generic_write(port, from_user, buf, count); +exit: + up (&port->sem); + return retval; +} static int serial_write_room (struct tty_struct *tty) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); + int retval = -EINVAL; - if (!serial) { + if (!serial) return -ENODEV; - } + + down (&port->sem); dbg(__FUNCTION__ " - port %d", port->number); - + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); - return -EINVAL; + goto exit; } /* pass on to the driver specific version of this function if it is available */ - if (serial->type->write_room) { - return (serial->type->write_room(port)); - } else { - return (generic_write_room(port)); - } + if (serial->type->write_room) + retval = serial->type->write_room(port); + else + retval = generic_write_room(port); + +exit: + up (&port->sem); + return retval; } - static int serial_chars_in_buffer (struct tty_struct *tty) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); + int retval = -EINVAL; - if (!serial) { + if (!serial) return -ENODEV; - } + + down (&port->sem); + + dbg(__FUNCTION__ " - port %d", port->number); if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); - return -EINVAL; + goto exit; } /* pass on to the driver specific version of this function if it is available */ - if (serial->type->chars_in_buffer) { - return (serial->type->chars_in_buffer(port)); - } else { - return (generic_chars_in_buffer(port)); - } -} + if (serial->type->chars_in_buffer) + retval = serial->type->chars_in_buffer(port); + else + retval = generic_chars_in_buffer(port); +exit: + up (&port->sem); + return retval; +} static void serial_throttle (struct tty_struct * tty) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); - if (!serial) { + if (!serial) return; - } + + down (&port->sem); dbg(__FUNCTION__ " - port %d", port->number); if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); - return; + goto exit; } /* pass on to the driver specific version of this function */ - if (serial->type->throttle) { + if (serial->type->throttle) serial->type->throttle(port); - } - return; +exit: + up (&port->sem); } - static void serial_unthrottle (struct tty_struct * tty) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); - if (!serial) { + if (!serial) return; - } + + down (&port->sem); dbg(__FUNCTION__ " - port %d", port->number); if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); - return; + goto exit; } /* pass on to the driver specific version of this function */ - if (serial->type->unthrottle) { + if (serial->type->unthrottle) serial->type->unthrottle(port); - } - return; +exit: + up (&port->sem); } - static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); + int retval = -ENODEV; - if (!serial) { + if (!serial) return -ENODEV; - } + + down (&port->sem); dbg(__FUNCTION__ " - port %d, cmd 0x%.4x", port->number, cmd); if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); - return -ENODEV; + goto exit; } /* pass on to the driver specific version of this function if it is available */ - if (serial->type->ioctl) { - return (serial->type->ioctl(port, file, cmd, arg)); - } else { - return -ENOIOCTLCMD; - } -} + if (serial->type->ioctl) + retval = serial->type->ioctl(port, file, cmd, arg); + else + retval = -ENOIOCTLCMD; +exit: + up (&port->sem); + return retval; +} static void serial_set_termios (struct tty_struct *tty, struct termios * old) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); - if (!serial) { + if (!serial) return; - } + + down (&port->sem); dbg(__FUNCTION__ " - port %d", port->number); if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); - return; + goto exit; } /* pass on to the driver specific version of this function if it is available */ - if (serial->type->set_termios) { + if (serial->type->set_termios) serial->type->set_termios(port, old); - } - - return; -} +exit: + up (&port->sem); +} static void serial_break (struct tty_struct *tty, int break_state) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); - if (!serial) { + if (!serial) return; - } + + down (&port->sem); dbg(__FUNCTION__ " - port %d", port->number); if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); - return; + goto exit; } - /* pass on to the driver specific version of this function if it is - available */ - if (serial->type->break_ctl) { + /* pass on to the driver specific version of this function if it is available */ + if (serial->type->break_ctl) serial->type->break_ctl(port, break_state); - } -} +exit: + up (&port->sem); +} static void serial_shutdown (struct usb_serial *serial) { - if (serial->type->shutdown) { + if (serial->type->shutdown) serial->type->shutdown(serial); - } else { + else generic_shutdown(serial); - } } - - /***************************************************************************** * generic devices specific driver functions *****************************************************************************/ @@ -787,13 +808,8 @@ if (port_paranoia_check (port, __FUNCTION__)) return -ENODEV; - /* only increment our usage count, if this device is _really_ a generic device */ - if_generic_do(MOD_INC_USE_COUNT); - dbg(__FUNCTION__ " - port %d", port->number); - down (&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -819,20 +835,15 @@ } } - up (&port->sem); - return result; } - static void generic_close (struct usb_serial_port *port, struct file * filp) { struct usb_serial *serial = port->serial; dbg(__FUNCTION__ " - port %d", port->number); - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -845,14 +856,8 @@ } port->open_count = 0; } - - up (&port->sem); - - /* only decrement our usage count, if this device is _really_ a generic device */ - if_generic_do(MOD_DEC_USE_COUNT); } - static int generic_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count) { struct usb_serial *serial = port->serial; @@ -907,7 +912,6 @@ return (0); } - static int generic_write_room (struct usb_serial_port *port) { struct usb_serial *serial = port->serial; @@ -924,7 +928,6 @@ return (room); } - static int generic_chars_in_buffer (struct usb_serial_port *port) { struct usb_serial *serial = port->serial; @@ -941,7 +944,6 @@ return (chars); } - static void generic_read_bulk_callback (struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -992,7 +994,6 @@ err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); } - static void generic_write_bulk_callback (struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -1016,7 +1017,6 @@ return; } - static void generic_shutdown (struct usb_serial *serial) { int i; @@ -1025,13 +1025,13 @@ /* stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { - while (serial->port[i].open_count > 0) { + down (&serial->port[i].sem); + while (serial->port[i].open_count > 0) generic_close (&serial->port[i], NULL); - } + up (&serial->port[i].sem); } } - static void port_softint(void *private) { struct usb_serial_port *port = (struct usb_serial_port *)private; @@ -1053,8 +1053,6 @@ wake_up_interruptible(&tty->write_wait); } - - static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) { @@ -1080,7 +1078,6 @@ int max_endpoints; const struct usb_device_id *id_pattern = NULL; - /* loop through our list of known serial converters, and see if this device matches. */ found = 0; @@ -1331,7 +1328,6 @@ return NULL; } - static void usb_serial_disconnect(struct usb_device *dev, void *ptr) { struct usb_serial *serial = (struct usb_serial *) ptr; @@ -1341,8 +1337,10 @@ if (serial) { /* fail all future close/read/write/ioctl/etc calls */ for (i = 0; i < serial->num_ports; ++i) { + down (&serial->port[i].sem); if (serial->port[i].tty != NULL) serial->port[i].tty->driver_data = NULL; + up (&serial->port[i].sem); } serial->dev = NULL; diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c --- a/drivers/usb/serial/visor.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/visor.c Wed Feb 27 00:27:05 2002 @@ -264,8 +264,6 @@ return -ENODEV; } - down (&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -289,8 +287,6 @@ err(__FUNCTION__ " - failed submitting read urb, error %d", result); } - up (&port->sem); - return result; } @@ -309,8 +305,6 @@ if (!serial) return; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -334,8 +328,6 @@ } port->open_count = 0; } - up (&port->sem); - /* Uncomment the following line if you want to see some statistics in your syslog */ /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */ } @@ -539,16 +531,8 @@ static void visor_throttle (struct usb_serial_port *port) { - dbg(__FUNCTION__ " - port %d", port->number); - - down (&port->sem); - usb_unlink_urb (port->read_urb); - - up (&port->sem); - - return; } @@ -558,16 +542,10 @@ dbg(__FUNCTION__ " - port %d", port->number); - down (&port->sem); - port->read_urb->dev = port->serial->dev; result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); - - up (&port->sem); - - return; } diff -Nru a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c --- a/drivers/usb/serial/whiteheat.c Wed Feb 27 00:27:05 2002 +++ b/drivers/usb/serial/whiteheat.c Wed Feb 27 00:27:05 2002 @@ -306,8 +306,6 @@ dbg(__FUNCTION__" - port %d", port->number); - down (&port->sem); - ++port->open_count; if (port->open_count == 1) { @@ -354,16 +352,12 @@ } dbg(__FUNCTION__ " - exit"); - up (&port->sem); - return retval; error_exit: --port->open_count; dbg(__FUNCTION__ " - error_exit"); - up (&port->sem); - return retval; } @@ -374,7 +368,6 @@ dbg(__FUNCTION__ " - port %d", port->number); - down (&port->sem); --port->open_count; if (port->open_count <= 0) { @@ -391,7 +384,6 @@ usb_unlink_urb (port->read_urb); port->open_count = 0; } - up (&port->sem); } @@ -410,8 +402,6 @@ dbg(__FUNCTION__ " -port %d", port->number); - down (&port->sem); - if ((!port->tty) || (!port->tty->termios)) { dbg(__FUNCTION__" - no tty structures"); goto exit; @@ -492,7 +482,6 @@ whiteheat_send_cmd (port->serial, WHITEHEAT_SETUP_PORT, (__u8 *)&port_settings, sizeof(port_settings)); exit: - up (&port->sem); return; }