aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/opticon.c
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2012-11-18 07:23:36 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-11-21 16:33:56 -0500
commit7a6ee2b02751a58b7a59a37483379ba9cddacc92 (patch)
tree599f40681d4e3efd6fa1a541d0c33bd722b2bb3d /drivers/usb/serial/opticon.c
parent32802077ce90ba955a9c50c6b27e6e6015a907bf (diff)
USB: opticon: switch to generic read implementation
Switch to the more efficient generic read implementation. Note that the generic implementation is not required to hold the tty port mutex during resume due to the read-urb free mask and write start flag. Note also that the generic resume implementation will call generic write start if there is a bulk-out end-point, but that nothing will be submitted as the write fifo is not used and is empty. Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/serial/opticon.c')
-rw-r--r--drivers/usb/serial/opticon.c141
1 files changed, 11 insertions, 130 deletions
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 8d6ece048f07..c6bfb83efb1e 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Opticon USB barcode to serial driver 2 * Opticon USB barcode to serial driver
3 * 3 *
4 * Copyright (C) 2011 - 2012 Johan Hovold <jhovold@gmail.com>
4 * Copyright (C) 2011 Martin Jansen <martin.jansen@opticon.com> 5 * Copyright (C) 2011 Martin Jansen <martin.jansen@opticon.com>
5 * Copyright (C) 2008 - 2009 Greg Kroah-Hartman <gregkh@suse.de> 6 * Copyright (C) 2008 - 2009 Greg Kroah-Hartman <gregkh@suse.de>
6 * Copyright (C) 2008 - 2009 Novell Inc. 7 * Copyright (C) 2008 - 2009 Novell Inc.
@@ -40,10 +41,7 @@ MODULE_DEVICE_TABLE(usb, id_table);
40 41
41/* This structure holds all of the individual device information */ 42/* This structure holds all of the individual device information */
42struct opticon_private { 43struct opticon_private {
43 struct urb *bulk_read_urb;
44 spinlock_t lock; /* protects the following flags */ 44 spinlock_t lock; /* protects the following flags */
45 bool throttled;
46 bool actually_throttled;
47 bool rts; 45 bool rts;
48 bool cts; 46 bool cts;
49 int outstanding_urbs; 47 int outstanding_urbs;
@@ -109,49 +107,6 @@ static void opticon_process_read_urb(struct urb *urb)
109 } 107 }
110} 108}
111 109
112static void opticon_read_bulk_callback(struct urb *urb)
113{
114 struct usb_serial_port *port = urb->context;
115 struct opticon_private *priv = usb_get_serial_port_data(port);
116 unsigned char *data = urb->transfer_buffer;
117 int status = urb->status;
118 int result;
119
120 switch (status) {
121 case 0:
122 /* success */
123 break;
124 case -ECONNRESET:
125 case -ENOENT:
126 case -ESHUTDOWN:
127 /* this urb is terminated, clean up */
128 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
129 __func__, status);
130 return;
131 default:
132 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
133 __func__, status);
134 goto exit;
135 }
136
137 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
138
139 opticon_process_read_urb(urb);
140exit:
141 spin_lock(&priv->lock);
142
143 /* Continue trying to always read if we should */
144 if (!priv->throttled) {
145 result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC);
146 if (result)
147 dev_err(&port->dev,
148 "%s - failed resubmitting read urb, error %d\n",
149 __func__, result);
150 } else
151 priv->actually_throttled = true;
152 spin_unlock(&priv->lock);
153}
154
155static int send_control_msg(struct usb_serial_port *port, u8 requesttype, 110static int send_control_msg(struct usb_serial_port *port, u8 requesttype,
156 u8 val) 111 u8 val)
157{ 112{
@@ -179,11 +134,9 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port)
179{ 134{
180 struct opticon_private *priv = usb_get_serial_port_data(port); 135 struct opticon_private *priv = usb_get_serial_port_data(port);
181 unsigned long flags; 136 unsigned long flags;
182 int result = 0; 137 int res;
183 138
184 spin_lock_irqsave(&priv->lock, flags); 139 spin_lock_irqsave(&priv->lock, flags);
185 priv->throttled = false;
186 priv->actually_throttled = false;
187 priv->rts = false; 140 priv->rts = false;
188 spin_unlock_irqrestore(&priv->lock, flags); 141 spin_unlock_irqrestore(&priv->lock, flags);
189 142
@@ -191,25 +144,17 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port)
191 send_control_msg(port, CONTROL_RTS, 0); 144 send_control_msg(port, CONTROL_RTS, 0);
192 145
193 /* clear the halt status of the enpoint */ 146 /* clear the halt status of the enpoint */
194 usb_clear_halt(port->serial->dev, priv->bulk_read_urb->pipe); 147 usb_clear_halt(port->serial->dev, port->read_urb->pipe);
148
149 res = usb_serial_generic_open(tty, port);
150 if (!res)
151 return res;
195 152
196 result = usb_submit_urb(priv->bulk_read_urb, GFP_KERNEL);
197 if (result)
198 dev_err(&port->dev,
199 "%s - failed resubmitting read urb, error %d\n",
200 __func__, result);
201 /* Request CTS line state, sometimes during opening the current 153 /* Request CTS line state, sometimes during opening the current
202 * CTS state can be missed. */ 154 * CTS state can be missed. */
203 send_control_msg(port, RESEND_CTS_STATE, 1); 155 send_control_msg(port, RESEND_CTS_STATE, 1);
204 return result;
205}
206 156
207static void opticon_close(struct usb_serial_port *port) 157 return res;
208{
209 struct opticon_private *priv = usb_get_serial_port_data(port);
210
211 /* shutdown our urbs */
212 usb_kill_urb(priv->bulk_read_urb);
213} 158}
214 159
215static void opticon_write_control_callback(struct urb *urb) 160static void opticon_write_control_callback(struct urb *urb)
@@ -346,40 +291,6 @@ static int opticon_write_room(struct tty_struct *tty)
346 return 2048; 291 return 2048;
347} 292}
348 293
349static void opticon_throttle(struct tty_struct *tty)
350{
351 struct usb_serial_port *port = tty->driver_data;
352 struct opticon_private *priv = usb_get_serial_port_data(port);
353 unsigned long flags;
354
355 spin_lock_irqsave(&priv->lock, flags);
356 priv->throttled = true;
357 spin_unlock_irqrestore(&priv->lock, flags);
358}
359
360
361static void opticon_unthrottle(struct tty_struct *tty)
362{
363 struct usb_serial_port *port = tty->driver_data;
364 struct opticon_private *priv = usb_get_serial_port_data(port);
365 unsigned long flags;
366 int result, was_throttled;
367
368 spin_lock_irqsave(&priv->lock, flags);
369 priv->throttled = false;
370 was_throttled = priv->actually_throttled;
371 priv->actually_throttled = false;
372 spin_unlock_irqrestore(&priv->lock, flags);
373
374 if (was_throttled) {
375 result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC);
376 if (result)
377 dev_err(&port->dev,
378 "%s - failed submitting read urb, error %d\n",
379 __func__, result);
380 }
381}
382
383static int opticon_tiocmget(struct tty_struct *tty) 294static int opticon_tiocmget(struct tty_struct *tty)
384{ 295{
385 struct usb_serial_port *port = tty->driver_data; 296 struct usb_serial_port *port = tty->driver_data;
@@ -495,7 +406,6 @@ static int opticon_port_probe(struct usb_serial_port *port)
495 return -ENOMEM; 406 return -ENOMEM;
496 407
497 spin_lock_init(&priv->lock); 408 spin_lock_init(&priv->lock);
498 priv->bulk_read_urb = port->read_urbs[0];
499 409
500 usb_set_serial_port_data(port, priv); 410 usb_set_serial_port_data(port, priv);
501 411
@@ -511,32 +421,6 @@ static int opticon_port_remove(struct usb_serial_port *port)
511 return 0; 421 return 0;
512} 422}
513 423
514static int opticon_suspend(struct usb_serial *serial, pm_message_t message)
515{
516 struct opticon_private *priv;
517
518 priv = usb_get_serial_port_data(serial->port[0]);
519
520 usb_kill_urb(priv->bulk_read_urb);
521 return 0;
522}
523
524static int opticon_resume(struct usb_serial *serial)
525{
526 struct usb_serial_port *port = serial->port[0];
527 struct opticon_private *priv = usb_get_serial_port_data(port);
528 int result;
529
530 mutex_lock(&port->port.mutex);
531 /* This is protected by the port mutex against close/open */
532 if (test_bit(ASYNCB_INITIALIZED, &port->port.flags))
533 result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO);
534 else
535 result = 0;
536 mutex_unlock(&port->port.mutex);
537 return result;
538}
539
540static struct usb_serial_driver opticon_device = { 424static struct usb_serial_driver opticon_device = {
541 .driver = { 425 .driver = {
542 .owner = THIS_MODULE, 426 .owner = THIS_MODULE,
@@ -549,17 +433,14 @@ static struct usb_serial_driver opticon_device = {
549 .port_probe = opticon_port_probe, 433 .port_probe = opticon_port_probe,
550 .port_remove = opticon_port_remove, 434 .port_remove = opticon_port_remove,
551 .open = opticon_open, 435 .open = opticon_open,
552 .close = opticon_close,
553 .write = opticon_write, 436 .write = opticon_write,
554 .write_room = opticon_write_room, 437 .write_room = opticon_write_room,
555 .throttle = opticon_throttle, 438 .throttle = usb_serial_generic_throttle,
556 .unthrottle = opticon_unthrottle, 439 .unthrottle = usb_serial_generic_unthrottle,
557 .ioctl = opticon_ioctl, 440 .ioctl = opticon_ioctl,
558 .tiocmget = opticon_tiocmget, 441 .tiocmget = opticon_tiocmget,
559 .tiocmset = opticon_tiocmset, 442 .tiocmset = opticon_tiocmset,
560 .suspend = opticon_suspend, 443 .process_read_urb = opticon_process_read_urb,
561 .resume = opticon_resume,
562 .read_bulk_callback = opticon_read_bulk_callback,
563}; 444};
564 445
565static struct usb_serial_driver * const serial_drivers[] = { 446static struct usb_serial_driver * const serial_drivers[] = {