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 |
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);