diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-19 16:39:21 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-19 16:39:21 -0400 |
| commit | 8fdb7e9f612b7c6ba6c3ba460c14263b5ce90f79 (patch) | |
| tree | 09f007a62475c22546ba693e5171024cc67fb38c /drivers/usb/serial/generic.c | |
| parent | fc7f99cf36ebae853639dabb43bc2f0098c59aef (diff) | |
| parent | 4cb80cda51ff950614701fb30c9d4e583fe5a31f (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (45 commits)
USB: gadget/multi: cdc_do_config: remove redundant check
usb: r8a66597-hcd: fix removed from an attached hub
USB: xhci: Make endpoint interval debugging clearer.
USB: Fix usb_fill_int_urb for SuperSpeed devices
USB: cp210x: Remove double usb_control_msg from cp210x_set_config
USB: Remove last bit of CONFIG_USB_BERRY_CHARGE
USB: gadget: add gadget controller number for s3c-hsotg driver
USB: ftdi_sio: Fix locking for change_speed() function
USB: g_mass_storage: fixed module name in Kconfig
USB: gadget: f_mass_storage::fsg_bind(): fix error handling
USB: g_mass_storage: fix section mismatch warnings
USB: gadget: fix Blackfin builds after gadget cleansing
USB: goku_udc: remove potential null dereference
USB: option.c: Add Pirelli VID/PID and indicate Pirelli's modem interface is 0xff
USB: serial: Fix module name typo for qcaux Kconfig entry.
usb: cdc-wdm: Fix deadlock between write and resume
usb: cdc-wdm: Fix order in disconnect and fix locking
usb: cdc-wdm:Fix loss of data due to autosuspend
usb: cdc-wdm: Fix submission of URB after suspension
usb: cdc-wdm: Fix race between disconnect and debug messages
...
Diffstat (limited to 'drivers/usb/serial/generic.c')
| -rw-r--r-- | drivers/usb/serial/generic.c | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 89fac36684c5..f804acb138ec 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
| @@ -130,7 +130,7 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port | |||
| 130 | spin_unlock_irqrestore(&port->lock, flags); | 130 | spin_unlock_irqrestore(&port->lock, flags); |
| 131 | 131 | ||
| 132 | /* if we have a bulk endpoint, start reading from it */ | 132 | /* if we have a bulk endpoint, start reading from it */ |
| 133 | if (serial->num_bulk_in) { | 133 | if (port->bulk_in_size) { |
| 134 | /* Start reading from the device */ | 134 | /* Start reading from the device */ |
| 135 | usb_fill_bulk_urb(port->read_urb, serial->dev, | 135 | usb_fill_bulk_urb(port->read_urb, serial->dev, |
| 136 | usb_rcvbulkpipe(serial->dev, | 136 | usb_rcvbulkpipe(serial->dev, |
| @@ -159,10 +159,10 @@ static void generic_cleanup(struct usb_serial_port *port) | |||
| 159 | dbg("%s - port %d", __func__, port->number); | 159 | dbg("%s - port %d", __func__, port->number); |
| 160 | 160 | ||
| 161 | if (serial->dev) { | 161 | if (serial->dev) { |
| 162 | /* shutdown any bulk reads that might be going on */ | 162 | /* shutdown any bulk transfers that might be going on */ |
| 163 | if (serial->num_bulk_out) | 163 | if (port->bulk_out_size) |
| 164 | usb_kill_urb(port->write_urb); | 164 | usb_kill_urb(port->write_urb); |
| 165 | if (serial->num_bulk_in) | 165 | if (port->bulk_in_size) |
| 166 | usb_kill_urb(port->read_urb); | 166 | usb_kill_urb(port->read_urb); |
| 167 | } | 167 | } |
| 168 | } | 168 | } |
| @@ -333,15 +333,15 @@ int usb_serial_generic_write(struct tty_struct *tty, | |||
| 333 | 333 | ||
| 334 | dbg("%s - port %d", __func__, port->number); | 334 | dbg("%s - port %d", __func__, port->number); |
| 335 | 335 | ||
| 336 | /* only do something if we have a bulk out endpoint */ | ||
| 337 | if (!port->bulk_out_size) | ||
| 338 | return -ENODEV; | ||
| 339 | |||
| 336 | if (count == 0) { | 340 | if (count == 0) { |
| 337 | dbg("%s - write request of 0 bytes", __func__); | 341 | dbg("%s - write request of 0 bytes", __func__); |
| 338 | return 0; | 342 | return 0; |
| 339 | } | 343 | } |
| 340 | 344 | ||
| 341 | /* only do something if we have a bulk out endpoint */ | ||
| 342 | if (!serial->num_bulk_out) | ||
| 343 | return 0; | ||
| 344 | |||
| 345 | if (serial->type->max_in_flight_urbs) | 345 | if (serial->type->max_in_flight_urbs) |
| 346 | return usb_serial_multi_urb_write(tty, port, | 346 | return usb_serial_multi_urb_write(tty, port, |
| 347 | buf, count); | 347 | buf, count); |
| @@ -364,14 +364,19 @@ int usb_serial_generic_write_room(struct tty_struct *tty) | |||
| 364 | int room = 0; | 364 | int room = 0; |
| 365 | 365 | ||
| 366 | dbg("%s - port %d", __func__, port->number); | 366 | dbg("%s - port %d", __func__, port->number); |
| 367 | |||
| 368 | if (!port->bulk_out_size) | ||
| 369 | return 0; | ||
| 370 | |||
| 367 | spin_lock_irqsave(&port->lock, flags); | 371 | spin_lock_irqsave(&port->lock, flags); |
| 368 | if (serial->type->max_in_flight_urbs) { | 372 | if (serial->type->max_in_flight_urbs) { |
| 369 | if (port->urbs_in_flight < serial->type->max_in_flight_urbs) | 373 | if (port->urbs_in_flight < serial->type->max_in_flight_urbs) |
| 370 | room = port->bulk_out_size * | 374 | room = port->bulk_out_size * |
| 371 | (serial->type->max_in_flight_urbs - | 375 | (serial->type->max_in_flight_urbs - |
| 372 | port->urbs_in_flight); | 376 | port->urbs_in_flight); |
| 373 | } else if (serial->num_bulk_out) | 377 | } else { |
| 374 | room = kfifo_avail(&port->write_fifo); | 378 | room = kfifo_avail(&port->write_fifo); |
| 379 | } | ||
| 375 | spin_unlock_irqrestore(&port->lock, flags); | 380 | spin_unlock_irqrestore(&port->lock, flags); |
| 376 | 381 | ||
| 377 | dbg("%s - returns %d", __func__, room); | 382 | dbg("%s - returns %d", __func__, room); |
| @@ -382,15 +387,18 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) | |||
| 382 | { | 387 | { |
| 383 | struct usb_serial_port *port = tty->driver_data; | 388 | struct usb_serial_port *port = tty->driver_data; |
| 384 | struct usb_serial *serial = port->serial; | 389 | struct usb_serial *serial = port->serial; |
| 385 | int chars = 0; | ||
| 386 | unsigned long flags; | 390 | unsigned long flags; |
| 391 | int chars; | ||
| 387 | 392 | ||
| 388 | dbg("%s - port %d", __func__, port->number); | 393 | dbg("%s - port %d", __func__, port->number); |
| 389 | 394 | ||
| 395 | if (!port->bulk_out_size) | ||
| 396 | return 0; | ||
| 397 | |||
| 390 | spin_lock_irqsave(&port->lock, flags); | 398 | spin_lock_irqsave(&port->lock, flags); |
| 391 | if (serial->type->max_in_flight_urbs) | 399 | if (serial->type->max_in_flight_urbs) |
| 392 | chars = port->tx_bytes_flight; | 400 | chars = port->tx_bytes_flight; |
| 393 | else if (serial->num_bulk_out) | 401 | else |
| 394 | chars = kfifo_len(&port->write_fifo); | 402 | chars = kfifo_len(&port->write_fifo); |
| 395 | spin_unlock_irqrestore(&port->lock, flags); | 403 | spin_unlock_irqrestore(&port->lock, flags); |
| 396 | 404 | ||
| @@ -415,11 +423,13 @@ void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port, | |||
| 415 | ((serial->type->read_bulk_callback) ? | 423 | ((serial->type->read_bulk_callback) ? |
| 416 | serial->type->read_bulk_callback : | 424 | serial->type->read_bulk_callback : |
| 417 | usb_serial_generic_read_bulk_callback), port); | 425 | usb_serial_generic_read_bulk_callback), port); |
| 426 | |||
| 418 | result = usb_submit_urb(urb, mem_flags); | 427 | result = usb_submit_urb(urb, mem_flags); |
| 419 | if (result) | 428 | if (result && result != -EPERM) { |
| 420 | dev_err(&port->dev, | 429 | dev_err(&port->dev, |
| 421 | "%s - failed resubmitting read urb, error %d\n", | 430 | "%s - failed resubmitting read urb, error %d\n", |
| 422 | __func__, result); | 431 | __func__, result); |
| 432 | } | ||
| 423 | } | 433 | } |
| 424 | EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb); | 434 | EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb); |
| 425 | 435 | ||
| @@ -498,23 +508,18 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) | |||
| 498 | if (port->urbs_in_flight < 0) | 508 | if (port->urbs_in_flight < 0) |
| 499 | port->urbs_in_flight = 0; | 509 | port->urbs_in_flight = 0; |
| 500 | spin_unlock_irqrestore(&port->lock, flags); | 510 | spin_unlock_irqrestore(&port->lock, flags); |
| 501 | |||
| 502 | if (status) { | ||
| 503 | dbg("%s - nonzero multi-urb write bulk status " | ||
| 504 | "received: %d", __func__, status); | ||
| 505 | return; | ||
| 506 | } | ||
| 507 | } else { | 511 | } else { |
| 508 | port->write_urb_busy = 0; | 512 | port->write_urb_busy = 0; |
| 509 | 513 | ||
| 510 | if (status) { | 514 | if (status) |
| 511 | dbg("%s - nonzero multi-urb write bulk status " | ||
| 512 | "received: %d", __func__, status); | ||
| 513 | kfifo_reset_out(&port->write_fifo); | 515 | kfifo_reset_out(&port->write_fifo); |
| 514 | } else | 516 | else |
| 515 | usb_serial_generic_write_start(port); | 517 | usb_serial_generic_write_start(port); |
| 516 | } | 518 | } |
| 517 | 519 | ||
| 520 | if (status) | ||
| 521 | dbg("%s - non-zero urb status: %d", __func__, status); | ||
| 522 | |||
| 518 | usb_serial_port_softint(port); | 523 | usb_serial_port_softint(port); |
| 519 | } | 524 | } |
| 520 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); | 525 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); |
