aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/generic.c')
-rw-r--r--drivers/usb/serial/generic.c97
1 files changed, 59 insertions, 38 deletions
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 4f8282ad7720..88a2c7dce335 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -69,6 +69,7 @@ struct usb_serial_driver usb_serial_generic_device = {
69 .shutdown = usb_serial_generic_shutdown, 69 .shutdown = usb_serial_generic_shutdown,
70 .throttle = usb_serial_generic_throttle, 70 .throttle = usb_serial_generic_throttle,
71 .unthrottle = usb_serial_generic_unthrottle, 71 .unthrottle = usb_serial_generic_unthrottle,
72 .resume = usb_serial_generic_resume,
72}; 73};
73 74
74static int generic_probe(struct usb_interface *interface, 75static int generic_probe(struct usb_interface *interface,
@@ -169,6 +170,23 @@ static void generic_cleanup (struct usb_serial_port *port)
169 } 170 }
170} 171}
171 172
173int usb_serial_generic_resume(struct usb_serial *serial)
174{
175 struct usb_serial_port *port;
176 int i, c = 0, r;
177
178 for (i = 0; i < serial->num_ports; i++) {
179 port = serial->port[i];
180 if (port->open_count && port->read_urb) {
181 r = usb_submit_urb(port->read_urb, GFP_NOIO);
182 if (r < 0)
183 c++;
184 }
185 }
186
187 return c ? -EIO : 0;
188}
189
172void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp) 190void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp)
173{ 191{
174 dbg("%s - port %d", __FUNCTION__, port->number); 192 dbg("%s - port %d", __FUNCTION__, port->number);
@@ -263,79 +281,82 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
263 return (chars); 281 return (chars);
264} 282}
265 283
266/* Push data to tty layer and resubmit the bulk read URB */ 284
267static 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)
268{ 286{
269 struct usb_serial *serial = port->serial;
270 struct urb *urb = port->read_urb; 287 struct urb *urb = port->read_urb;
271 struct tty_struct *tty = port->tty; 288 struct usb_serial *serial = port->serial;
272 int result; 289 int result;
273 290
274 /* Push data to tty */
275 if (tty && urb->actual_length) {
276 tty_buffer_request_room(tty, urb->actual_length);
277 tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length);
278 tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */
279 }
280
281 /* Continue reading from device */ 291 /* Continue reading from device */
282 usb_fill_bulk_urb (port->read_urb, serial->dev, 292 usb_fill_bulk_urb (urb, serial->dev,
283 usb_rcvbulkpipe (serial->dev, 293 usb_rcvbulkpipe (serial->dev,
284 port->bulk_in_endpointAddress), 294 port->bulk_in_endpointAddress),
285 port->read_urb->transfer_buffer, 295 urb->transfer_buffer,
286 port->read_urb->transfer_buffer_length, 296 urb->transfer_buffer_length,
287 ((serial->type->read_bulk_callback) ? 297 ((serial->type->read_bulk_callback) ?
288 serial->type->read_bulk_callback : 298 serial->type->read_bulk_callback :
289 usb_serial_generic_read_bulk_callback), port); 299 usb_serial_generic_read_bulk_callback), port);
290 result = usb_submit_urb(port->read_urb, GFP_ATOMIC); 300 result = usb_submit_urb(urb, mem_flags);
291 if (result) 301 if (result)
292 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);
293} 303}
294 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
295void usb_serial_generic_read_bulk_callback (struct urb *urb) 324void usb_serial_generic_read_bulk_callback (struct urb *urb)
296{ 325{
297 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 326 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
298 unsigned char *data = urb->transfer_buffer; 327 unsigned char *data = urb->transfer_buffer;
299 int is_throttled; 328 int status = urb->status;
300 unsigned long flags;
301 329
302 dbg("%s - port %d", __FUNCTION__, port->number); 330 dbg("%s - port %d", __FUNCTION__, port->number);
303 331
304 if (urb->status) { 332 if (unlikely(status != 0)) {
305 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); 333 dbg("%s - nonzero read bulk status received: %d",
334 __FUNCTION__, status);
306 return; 335 return;
307 } 336 }
308 337
309 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); 338 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
310 339
311 /* Throttle the device if requested by tty */ 340 /* Throttle the device if requested by tty */
312 if (urb->actual_length) { 341 spin_lock(&port->lock);
313 spin_lock_irqsave(&port->lock, flags); 342 if (!(port->throttled = port->throttle_req))
314 is_throttled = port->throttled = port->throttle_req; 343 /* Handle data and continue reading from device */
315 spin_unlock_irqrestore(&port->lock, flags); 344 flush_and_resubmit_read_urb(port);
316 if (is_throttled) { 345 spin_unlock(&port->lock);
317 /* Let the received data linger in the read URB;
318 * usb_serial_generic_unthrottle() will pick it
319 * up later. */
320 dbg("%s - throttling device", __FUNCTION__);
321 return;
322 }
323 }
324
325 /* Handle data and continue reading from device */
326 flush_and_resubmit_read_urb(port);
327} 346}
328EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); 347EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
329 348
330void usb_serial_generic_write_bulk_callback (struct urb *urb) 349void usb_serial_generic_write_bulk_callback (struct urb *urb)
331{ 350{
332 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 351 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
352 int status = urb->status;
333 353
334 dbg("%s - port %d", __FUNCTION__, port->number); 354 dbg("%s - port %d", __FUNCTION__, port->number);
335 355
336 port->write_urb_busy = 0; 356 port->write_urb_busy = 0;
337 if (urb->status) { 357 if (status) {
338 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 358 dbg("%s - nonzero write bulk status received: %d",
359 __FUNCTION__, status);
339 return; 360 return;
340 } 361 }
341 362
@@ -370,8 +391,8 @@ void usb_serial_generic_unthrottle (struct usb_serial_port *port)
370 spin_unlock_irqrestore(&port->lock, flags); 391 spin_unlock_irqrestore(&port->lock, flags);
371 392
372 if (was_throttled) { 393 if (was_throttled) {
373 /* Handle pending data and resume reading from device */ 394 /* Resume reading from device */
374 flush_and_resubmit_read_urb(port); 395 resubmit_read_urb(port, GFP_KERNEL);
375 } 396 }
376} 397}
377 398