aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/generic.c
diff options
context:
space:
mode:
authorOliver Neukum <oneukum@suse.de>2007-05-07 06:09:33 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-07-12 19:29:51 -0400
commit1abdeeb1d566f74bc5b3e68447d91c8c37d47942 (patch)
treeeac1e0f7359572a48eedd079302aae651329e874 /drivers/usb/serial/generic.c
parent39892da44b21b5362eb848ca424d73a25ccc488f (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.c69
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
285static void flush_and_resubmit_read_urb (struct usb_serial_port *port) 285static 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 */
306static 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
313void usb_serial_generic_read_bulk_callback (struct urb *urb) 324void 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}
346EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); 345EXPORT_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