diff options
author | Oliver Neukum <oneukum@suse.de> | 2007-05-07 06:09:33 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-12 19:29:51 -0400 |
commit | 1abdeeb1d566f74bc5b3e68447d91c8c37d47942 (patch) | |
tree | eac1e0f7359572a48eedd079302aae651329e874 /drivers/usb/serial/generic.c | |
parent | 39892da44b21b5362eb848ca424d73a25ccc488f (diff) |
USB: generic usb serial to new buffering scheme
the generic driver also had its own buffering.
Signed-off-by: Oliver Neukum <oneukum@suse.de_
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/generic.c')
-rw-r--r-- | drivers/usb/serial/generic.c | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index b90ef3f70f4c..b09bed4b77d3 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -281,45 +281,54 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port) | |||
281 | return (chars); | 281 | return (chars); |
282 | } | 282 | } |
283 | 283 | ||
284 | /* Push data to tty layer and resubmit the bulk read URB */ | 284 | |
285 | static void flush_and_resubmit_read_urb (struct usb_serial_port *port) | 285 | static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) |
286 | { | 286 | { |
287 | struct usb_serial *serial = port->serial; | ||
288 | struct urb *urb = port->read_urb; | 287 | struct urb *urb = port->read_urb; |
289 | struct tty_struct *tty = port->tty; | 288 | struct usb_serial *serial = port->serial; |
290 | int result; | 289 | int result; |
291 | 290 | ||
292 | /* Push data to tty */ | ||
293 | if (tty && urb->actual_length) { | ||
294 | tty_buffer_request_room(tty, urb->actual_length); | ||
295 | tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length); | ||
296 | tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */ | ||
297 | } | ||
298 | |||
299 | /* Continue reading from device */ | 291 | /* Continue reading from device */ |
300 | usb_fill_bulk_urb (port->read_urb, serial->dev, | 292 | usb_fill_bulk_urb (urb, serial->dev, |
301 | usb_rcvbulkpipe (serial->dev, | 293 | usb_rcvbulkpipe (serial->dev, |
302 | port->bulk_in_endpointAddress), | 294 | port->bulk_in_endpointAddress), |
303 | port->read_urb->transfer_buffer, | 295 | urb->transfer_buffer, |
304 | port->read_urb->transfer_buffer_length, | 296 | urb->transfer_buffer_length, |
305 | ((serial->type->read_bulk_callback) ? | 297 | ((serial->type->read_bulk_callback) ? |
306 | serial->type->read_bulk_callback : | 298 | serial->type->read_bulk_callback : |
307 | usb_serial_generic_read_bulk_callback), port); | 299 | usb_serial_generic_read_bulk_callback), port); |
308 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | 300 | result = usb_submit_urb(urb, mem_flags); |
309 | if (result) | 301 | if (result) |
310 | dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); | 302 | dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); |
311 | } | 303 | } |
312 | 304 | ||
305 | /* Push data to tty layer and resubmit the bulk read URB */ | ||
306 | static void flush_and_resubmit_read_urb (struct usb_serial_port *port) | ||
307 | { | ||
308 | struct urb *urb = port->read_urb; | ||
309 | struct tty_struct *tty = port->tty; | ||
310 | int room; | ||
311 | |||
312 | /* Push data to tty */ | ||
313 | if (tty && urb->actual_length) { | ||
314 | room = tty_buffer_request_room(tty, urb->actual_length); | ||
315 | if (room) { | ||
316 | tty_insert_flip_string(tty, urb->transfer_buffer, room); | ||
317 | tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */ | ||
318 | } | ||
319 | } | ||
320 | |||
321 | resubmit_read_urb(port, GFP_ATOMIC); | ||
322 | } | ||
323 | |||
313 | void usb_serial_generic_read_bulk_callback (struct urb *urb) | 324 | void usb_serial_generic_read_bulk_callback (struct urb *urb) |
314 | { | 325 | { |
315 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 326 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
316 | unsigned char *data = urb->transfer_buffer; | 327 | unsigned char *data = urb->transfer_buffer; |
317 | int is_throttled; | ||
318 | unsigned long flags; | ||
319 | 328 | ||
320 | dbg("%s - port %d", __FUNCTION__, port->number); | 329 | dbg("%s - port %d", __FUNCTION__, port->number); |
321 | 330 | ||
322 | if (urb->status) { | 331 | if (unlikely(urb->status != 0)) { |
323 | dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); | 332 | dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); |
324 | return; | 333 | return; |
325 | } | 334 | } |
@@ -327,21 +336,11 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb) | |||
327 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); | 336 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); |
328 | 337 | ||
329 | /* Throttle the device if requested by tty */ | 338 | /* Throttle the device if requested by tty */ |
330 | if (urb->actual_length) { | 339 | spin_lock(&port->lock); |
331 | spin_lock_irqsave(&port->lock, flags); | 340 | if (!(port->throttled = port->throttle_req)) |
332 | is_throttled = port->throttled = port->throttle_req; | 341 | /* Handle data and continue reading from device */ |
333 | spin_unlock_irqrestore(&port->lock, flags); | 342 | flush_and_resubmit_read_urb(port); |
334 | if (is_throttled) { | 343 | spin_unlock(&port->lock); |
335 | /* Let the received data linger in the read URB; | ||
336 | * usb_serial_generic_unthrottle() will pick it | ||
337 | * up later. */ | ||
338 | dbg("%s - throttling device", __FUNCTION__); | ||
339 | return; | ||
340 | } | ||
341 | } | ||
342 | |||
343 | /* Handle data and continue reading from device */ | ||
344 | flush_and_resubmit_read_urb(port); | ||
345 | } | 344 | } |
346 | EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); | 345 | EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); |
347 | 346 | ||
@@ -388,8 +387,8 @@ void usb_serial_generic_unthrottle (struct usb_serial_port *port) | |||
388 | spin_unlock_irqrestore(&port->lock, flags); | 387 | spin_unlock_irqrestore(&port->lock, flags); |
389 | 388 | ||
390 | if (was_throttled) { | 389 | if (was_throttled) { |
391 | /* Handle pending data and resume reading from device */ | 390 | /* Resume reading from device */ |
392 | flush_and_resubmit_read_urb(port); | 391 | resubmit_read_urb(port, GFP_KERNEL); |
393 | } | 392 | } |
394 | } | 393 | } |
395 | 394 | ||