Showing error 1096

User: Jiri Slaby
Error type: Double Lock
Error type description: Some lock is locked twice unintentionally in a sequence
File location: drivers/usb/serial/digi_acceleport.c
Line in file: 645
Project: Linux Kernel
Project version: 2.6.28
Tools: Clang Static Analyzer (3.0)
Smatch (1.59)
Entered: 2012-04-17 12:29:30 UTC


Source:

 615 *
 616 *  Write commands on the out of band port.  Commands are 4
 617 *  bytes each, multiple commands can be sent at once, and
 618 *  no command will be split across USB packets.  Returns 0
 619 *  if successful, -EINTR if interrupted while sleeping and
 620 *  the interruptible flag is true, or a negative error
 621 *  returned by usb_submit_urb.
 622 */
 623
 624static int digi_write_oob_command(struct usb_serial_port *port,
 625        unsigned char *buf, int count, int interruptible)
 626{
 627
 628        int ret = 0;
 629        int len;
 630        struct usb_serial_port *oob_port = (struct usb_serial_port *)((struct digi_serial *)(usb_get_serial_data(port->serial)))->ds_oob_port;
 631        struct digi_port *oob_priv = usb_get_serial_port_data(oob_port);
 632        unsigned long flags = 0;
 633
 634        dbg("digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, count);
 635
 636        spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
 637        while (count > 0) {
 638                while (oob_port->write_urb->status == -EINPROGRESS
 639                        || oob_priv->dp_write_urb_in_use) {
 640                        cond_wait_interruptible_timeout_irqrestore(
 641                                &oob_port->write_wait, DIGI_RETRY_TIMEOUT,
 642                                &oob_priv->dp_port_lock, flags);
 643                        if (interruptible && signal_pending(current))
 644                                return -EINTR;
 645                        spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
 646                }
 647
 648                /* len must be a multiple of 4, so commands are not split */
 649                len = min(count, oob_port->bulk_out_size);
 650                if (len > 4)
 651                        len &= ~3;
 652                memcpy(oob_port->write_urb->transfer_buffer, buf, len);
 653                oob_port->write_urb->transfer_buffer_length = len;
 654                oob_port->write_urb->dev = port->serial->dev;
 655                ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);
Show full sources