]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/serial/usb-serial.c
USB: usb dev_set_name() instead of dev->bus_id
[linux-2.6-omap-h63xx.git] / drivers / usb / serial / usb-serial.c
index 9bf01a5efc84adaaec0145ca24076421b64db558..717e376795e4c7f7f2ed258f770ecd512bab7fba 100644 (file)
@@ -81,7 +81,7 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po
        unsigned int i, j;
        int good_spot;
 
-       dbg("%s %d", __FUNCTION__, num_ports);
+       dbg("%s %d", __func__, num_ports);
 
        *minor = 0;
        mutex_lock(&table_lock);
@@ -101,7 +101,7 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po
 
                *minor = i;
                j = 0;
-               dbg("%s - minor base = %d", __FUNCTION__, *minor);
+               dbg("%s - minor base = %d", __func__, *minor);
                for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) {
                        serial_table[i] = serial;
                        serial->port[j++]->number = i;
@@ -117,7 +117,7 @@ static void return_serial(struct usb_serial *serial)
 {
        int i;
 
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
 
        if (serial == NULL)
                return;
@@ -135,7 +135,7 @@ static void destroy_serial(struct kref *kref)
 
        serial = to_usb_serial(kref);
 
-       dbg("%s - %s", __FUNCTION__, serial->type->description);
+       dbg("%s - %s", __func__, serial->type->description);
 
        serial->type->shutdown(serial);
 
@@ -187,7 +187,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
        unsigned int portNumber;
        int retval;
        
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
 
        /* get the serial object associated with this tty pointer */
        serial = usb_serial_get_by_index(tty->index);
@@ -225,16 +225,21 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
                        goto bailout_mutex_unlock;
                }
 
+               retval = usb_autopm_get_interface(serial->interface);
+               if (retval)
+                       goto bailout_module_put;
                /* only call the device specific open if this 
                 * is the first time the port is opened */
                retval = serial->type->open(port, filp);
                if (retval)
-                       goto bailout_module_put;
+                       goto bailout_interface_put;
        }
 
        mutex_unlock(&port->mutex);
        return 0;
 
+bailout_interface_put:
+       usb_autopm_put_interface(serial->interface);
 bailout_module_put:
        module_put(serial->type->driver.owner);
 bailout_mutex_unlock:
@@ -254,7 +259,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
        if (!port)
                return;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        mutex_lock(&port->mutex);
 
@@ -264,17 +269,21 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
        }
 
        --port->open_count;
-       if (port->open_count == 0) {
+       if (port->open_count == 0)
                /* only call the device specific close if this 
                 * port is being closed by the last owner */
                port->serial->type->close(port, filp);
 
+       if (port->open_count == (port->console? 1 : 0)) {
                if (port->tty) {
                        if (port->tty->driver_data)
                                port->tty->driver_data = NULL;
                        port->tty = NULL;
                }
+       }
 
+       if (port->open_count == 0) {
+               usb_autopm_put_interface(port->serial->interface);
                module_put(port->serial->type->driver.owner);
        }
 
@@ -287,16 +296,14 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int
        struct usb_serial_port *port = tty->driver_data;
        int retval = -ENODEV;
 
-       if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED)
+       if (port->serial->dev->state == USB_STATE_NOTATTACHED)
                goto exit;
 
-       dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
+       dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
 
-       if (!port->open_count) {
-               retval = -EINVAL;
-               dbg("%s - port not opened", __FUNCTION__);
-               goto exit;
-       }
+       /* open_count is managed under the mutex lock for the tty so cannot
+           drop to zero until after the last close completes */
+       WARN_ON(!port->open_count);
 
        /* pass on to the driver specific version of this function */
        retval = port->serial->type->write(port, buf, count);
@@ -308,61 +315,28 @@ exit:
 static int serial_write_room (struct tty_struct *tty) 
 {
        struct usb_serial_port *port = tty->driver_data;
-       int retval = -ENODEV;
-
-       if (!port)
-               goto exit;
-
-       dbg("%s - port %d", __FUNCTION__, port->number);
-
-       if (!port->open_count) {
-               dbg("%s - port not open", __FUNCTION__);
-               goto exit;
-       }
-
+       dbg("%s - port %d", __func__, port->number);
+       WARN_ON(!port->open_count);
        /* pass on to the driver specific version of this function */
-       retval = port->serial->type->write_room(port);
-
-exit:
-       return retval;
+       return port->serial->type->write_room(port);
 }
 
 static int serial_chars_in_buffer (struct tty_struct *tty) 
 {
        struct usb_serial_port *port = tty->driver_data;
-       int retval = -ENODEV;
-
-       if (!port)
-               goto exit;
-
-       dbg("%s = port %d", __FUNCTION__, port->number);
-
-       if (!port->open_count) {
-               dbg("%s - port not open", __FUNCTION__);
-               goto exit;
-       }
+       dbg("%s = port %d", __func__, port->number);
 
+       WARN_ON(!port->open_count);
        /* pass on to the driver specific version of this function */
-       retval = port->serial->type->chars_in_buffer(port);
-
-exit:
-       return retval;
+       return port->serial->type->chars_in_buffer(port);
 }
 
 static void serial_throttle (struct tty_struct * tty)
 {
        struct usb_serial_port *port = tty->driver_data;
+       dbg("%s - port %d", __func__, port->number);
 
-       if (!port)
-               return;
-
-       dbg("%s - port %d", __FUNCTION__, port->number);
-
-       if (!port->open_count) {
-               dbg ("%s - port not open", __FUNCTION__);
-               return;
-       }
-
+       WARN_ON(!port->open_count);
        /* pass on to the driver specific version of this function */
        if (port->serial->type->throttle)
                port->serial->type->throttle(port);
@@ -371,17 +345,9 @@ static void serial_throttle (struct tty_struct * tty)
 static void serial_unthrottle (struct tty_struct * tty)
 {
        struct usb_serial_port *port = tty->driver_data;
+       dbg("%s - port %d", __func__, port->number);
 
-       if (!port)
-               return;
-
-       dbg("%s - port %d", __FUNCTION__, port->number);
-
-       if (!port->open_count) {
-               dbg("%s - port not open", __FUNCTION__);
-               return;
-       }
-
+       WARN_ON(!port->open_count);
        /* pass on to the driver specific version of this function */
        if (port->serial->type->unthrottle)
                port->serial->type->unthrottle(port);
@@ -392,62 +358,47 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in
        struct usb_serial_port *port = tty->driver_data;
        int retval = -ENODEV;
 
-       if (!port)
-               goto exit;
-
-       dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
+       dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
 
-       if (!port->open_count) {
-               dbg ("%s - port not open", __FUNCTION__);
-               goto exit;
-       }
+       WARN_ON(!port->open_count);
 
        /* pass on to the driver specific version of this function if it is available */
-       if (port->serial->type->ioctl)
+       if (port->serial->type->ioctl) {
+               lock_kernel();
                retval = port->serial->type->ioctl(port, file, cmd, arg);
+               unlock_kernel();
+       }
        else
                retval = -ENOIOCTLCMD;
-
-exit:
        return retval;
 }
 
 static void serial_set_termios (struct tty_struct *tty, struct ktermios * old)
 {
        struct usb_serial_port *port = tty->driver_data;
+       dbg("%s - port %d", __func__, port->number);
 
-       if (!port)
-               return;
-
-       dbg("%s - port %d", __FUNCTION__, port->number);
-
-       if (!port->open_count) {
-               dbg("%s - port not open", __FUNCTION__);
-               return;
-       }
-
+       WARN_ON(!port->open_count);
        /* pass on to the driver specific version of this function if it is available */
        if (port->serial->type->set_termios)
                port->serial->type->set_termios(port, old);
+       else
+               tty_termios_copy_hw(tty->termios, old);
 }
 
 static void serial_break (struct tty_struct *tty, int break_state)
 {
        struct usb_serial_port *port = tty->driver_data;
 
-       if (!port)
-               return;
-
-       dbg("%s - port %d", __FUNCTION__, port->number);
-
-       if (!port->open_count) {
-               dbg("%s - port not open", __FUNCTION__);
-               return;
-       }
+       dbg("%s - port %d", __func__, port->number);
 
+       WARN_ON(!port->open_count);
        /* pass on to the driver specific version of this function if it is available */
-       if (port->serial->type->break_ctl)
+       if (port->serial->type->break_ctl) {
+               lock_kernel();
                port->serial->type->break_ctl(port, break_state);
+               unlock_kernel();
+       }
 }
 
 static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data)
@@ -458,7 +409,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int
        off_t begin = 0;
        char tmp[40];
 
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
        length += sprintf (page, "usbserinfo:1.0 driver:2.0\n");
        for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) {
                serial = usb_serial_get_by_index(i);
@@ -501,19 +452,11 @@ static int serial_tiocmget (struct tty_struct *tty, struct file *file)
 {
        struct usb_serial_port *port = tty->driver_data;
 
-       if (!port)
-               return -ENODEV;
-
-       dbg("%s - port %d", __FUNCTION__, port->number);
-
-       if (!port->open_count) {
-               dbg("%s - port not open", __FUNCTION__);
-               return -ENODEV;
-       }
+       dbg("%s - port %d", __func__, port->number);
 
+       WARN_ON(!port->open_count);
        if (port->serial->type->tiocmget)
                return port->serial->type->tiocmget(port, file);
-
        return -EINVAL;
 }
 
@@ -522,19 +465,11 @@ static int serial_tiocmset (struct tty_struct *tty, struct file *file,
 {
        struct usb_serial_port *port = tty->driver_data;
 
-       if (!port)
-               return -ENODEV;
-
-       dbg("%s - port %d", __FUNCTION__, port->number);
-
-       if (!port->open_count) {
-               dbg("%s - port not open", __FUNCTION__);
-               return -ENODEV;
-       }
+       dbg("%s - port %d", __func__, port->number);
 
+       WARN_ON(!port->open_count);
        if (port->serial->type->tiocmset)
                return port->serial->type->tiocmset(port, file, set, clear);
-
        return -EINVAL;
 }
 
@@ -554,7 +489,7 @@ static void usb_serial_port_work(struct work_struct *work)
                container_of(work, struct usb_serial_port, work);
        struct tty_struct *tty;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
        
        if (!port)
                return;
@@ -570,7 +505,7 @@ static void port_release(struct device *dev)
 {
        struct usb_serial_port *port = to_usb_serial_port(dev);
 
-       dbg ("%s - %s", __FUNCTION__, dev->bus_id);
+       dbg ("%s - %s", __func__, dev_name(dev));
        port_free(port);
 }
 
@@ -578,6 +513,17 @@ static void kill_traffic(struct usb_serial_port *port)
 {
        usb_kill_urb(port->read_urb);
        usb_kill_urb(port->write_urb);
+       /*
+        * This is tricky.
+        * Some drivers submit the read_urb in the
+        * handler for the write_urb or vice versa
+        * this order determines the order in which
+        * usb_kill_urb() must be used to reliably
+        * kill the URBs. As it is unknown here,
+        * both orders must be used in turn.
+        * The call below is not redundant.
+        */
+       usb_kill_urb(port->read_urb);
        usb_kill_urb(port->interrupt_in_urb);
        usb_kill_urb(port->interrupt_out_urb);
 }
@@ -605,13 +551,14 @@ static struct usb_serial * create_serial (struct usb_device *dev,
 
        serial = kzalloc(sizeof(*serial), GFP_KERNEL);
        if (!serial) {
-               dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);
+               dev_err(&dev->dev, "%s - out of memory\n", __func__);
                return NULL;
        }
        serial->dev = usb_get_dev(dev);
        serial->type = driver;
        serial->interface = interface;
        kref_init(&serial->kref);
+       mutex_init(&serial->disc_mutex);
 
        return serial;
 }
@@ -651,16 +598,14 @@ exit:
 
 static struct usb_serial_driver *search_serial_device(struct usb_interface *iface)
 {
-       struct list_head *p;
        const struct usb_device_id *id;
-       struct usb_serial_driver *t;
+       struct usb_serial_driver *drv;
 
        /* Check if the usb id matches a known device */
-       list_for_each(p, &usb_serial_driver_list) {
-               t = list_entry(p, struct usb_serial_driver, driver_list);
-               id = get_iface_id(t, iface);
+       list_for_each_entry(drv, &usb_serial_driver_list, driver_list) {
+               id = get_iface_id(drv, iface);
                if (id)
-                       return t;
+                       return drv;
        }
 
        return NULL;
@@ -701,7 +646,7 @@ int usb_serial_probe(struct usb_interface *interface,
        serial = create_serial (dev, interface, type);
        if (!serial) {
                unlock_kernel();
-               dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__);
+               dev_err(&interface->dev, "%s - out of memory\n", __func__);
                return -ENOMEM;
        }
 
@@ -800,9 +745,6 @@ int usb_serial_probe(struct usb_interface *interface,
        /* END HORRIBLE HACK FOR PL2303 */
 #endif
 
-       /* found all that we need */
-       dev_info(&interface->dev, "%s converter detected\n", type->description);
-
 #ifdef CONFIG_USB_SERIAL_GENERIC
        if (type == &usb_serial_generic_device) {
                num_ports = num_bulk_out;
@@ -836,6 +778,10 @@ int usb_serial_probe(struct usb_interface *interface,
        serial->num_interrupt_in = num_interrupt_in;
        serial->num_interrupt_out = num_interrupt_out;
 
+       /* found all that we need */
+       dev_info(&interface->dev, "%s converter detected\n",
+                       type->description);
+
        /* create our ports, we need as many as the max endpoints */
        /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */
        max_endpoints = max(num_bulk_in, num_bulk_out);
@@ -845,7 +791,7 @@ int usb_serial_probe(struct usb_interface *interface,
        serial->num_port_pointers = max_endpoints;
        unlock_kernel();
 
-       dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints);
+       dbg("%s - setting up %d port structures for this device", __func__, max_endpoints);
        for (i = 0; i < max_endpoints; ++i) {
                port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
                if (!port)
@@ -992,8 +938,8 @@ int usb_serial_probe(struct usb_interface *interface,
                port->dev.bus = &usb_serial_bus_type;
                port->dev.release = &port_release;
 
-               snprintf (&port->dev.bus_id[0], sizeof(port->dev.bus_id), "ttyUSB%d", port->number);
-               dbg ("%s - registering %s", __FUNCTION__, port->dev.bus_id);
+               dev_set_name(&port->dev, "ttyUSB%d", port->number);
+               dbg ("%s - registering %s", __func__, dev_name(&port->dev));
                retval = device_register(&port->dev);
                if (retval)
                        dev_err(&port->dev, "Error registering port device, "
@@ -1052,22 +998,24 @@ void usb_serial_disconnect(struct usb_interface *interface)
        struct usb_serial_port *port;
 
        usb_serial_console_disconnect(serial);
-       dbg ("%s", __FUNCTION__);
+       dbg ("%s", __func__);
 
+       mutex_lock(&serial->disc_mutex);
        usb_set_intfdata (interface, NULL);
-       if (serial) {
-               for (i = 0; i < serial->num_ports; ++i) {
-                       port = serial->port[i];
-                       if (port) {
-                               if (port->tty)
-                                       tty_hangup(port->tty);
-                               kill_traffic(port);
-                       }
+       /* must set a flag, to signal subdrivers */
+       serial->disconnected = 1;
+       for (i = 0; i < serial->num_ports; ++i) {
+               port = serial->port[i];
+               if (port) {
+                       if (port->tty)
+                               tty_hangup(port->tty);
+                       kill_traffic(port);
                }
-               /* let the last holder of this object 
-                * cause it to be cleaned up */
-               usb_serial_put(serial);
        }
+       /* let the last holder of this object
+        * cause it to be cleaned up */
+       mutex_unlock(&serial->disc_mutex);
+       usb_serial_put(serial);
        dev_info(dev, "device disconnected\n");
 }
 
@@ -1077,9 +1025,6 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
        struct usb_serial_port *port;
        int i, r = 0;
 
-       if (!serial) /* device has been disconnected */
-               return 0;
-
        for (i = 0; i < serial->num_ports; ++i) {
                port = serial->port[i];
                if (port)
@@ -1097,7 +1042,9 @@ int usb_serial_resume(struct usb_interface *intf)
 {
        struct usb_serial *serial = usb_get_intfdata(intf);
 
-       return serial->type->resume(serial);
+       if (serial->type->resume)
+               return serial->type->resume(serial);
+       return 0;
 }
 EXPORT_SYMBOL(usb_serial_resume);
 
@@ -1135,7 +1082,7 @@ static int __init usb_serial_init(void)
 
        result = bus_register(&usb_serial_bus_type);
        if (result) {
-               err("%s - registering bus driver failed", __FUNCTION__);
+               err("%s - registering bus driver failed", __func__);
                goto exit_bus;
        }
 
@@ -1149,24 +1096,26 @@ static int __init usb_serial_init(void)
        usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        usb_serial_tty_driver->init_termios = tty_std_termios;
        usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+       usb_serial_tty_driver->init_termios.c_ispeed = 9600;
+       usb_serial_tty_driver->init_termios.c_ospeed = 9600;
        tty_set_operations(usb_serial_tty_driver, &serial_ops);
        result = tty_register_driver(usb_serial_tty_driver);
        if (result) {
-               err("%s - tty_register_driver failed", __FUNCTION__);
+               err("%s - tty_register_driver failed", __func__);
                goto exit_reg_driver;
        }
 
        /* register the USB driver */
        result = usb_register(&usb_serial_driver);
        if (result < 0) {
-               err("%s - usb_register failed", __FUNCTION__);
+               err("%s - usb_register failed", __func__);
                goto exit_tty;
        }
 
        /* register the generic driver, if we should */
        result = usb_serial_generic_register(debug);
        if (result < 0) {
-               err("%s - registering generic driver failed", __FUNCTION__);
+               err("%s - registering generic driver failed", __func__);
                goto exit_generic;
        }
 
@@ -1184,7 +1133,7 @@ exit_reg_driver:
        bus_unregister(&usb_serial_bus_type);
 
 exit_bus:
-       err ("%s - returning with error %d", __FUNCTION__, result);
+       err ("%s - returning with error %d", __func__, result);
        put_tty_driver(usb_serial_tty_driver);
        return result;
 }
@@ -1225,6 +1174,7 @@ static void fixup_generic(struct usb_serial_driver *device)
        set_to_generic_if_null(device, read_bulk_callback);
        set_to_generic_if_null(device, write_bulk_callback);
        set_to_generic_if_null(device, shutdown);
+       set_to_generic_if_null(device, resume);
 }
 
 int usb_serial_register(struct usb_serial_driver *driver) /* must be called with BKL held */