aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/empeg.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-07-22 06:09:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-22 16:03:22 -0400
commit95da310e66ee8090119596c70ca8432e57f9a97f (patch)
tree7f18c30e9c9ad4d7d53df6453fa338be06f09a85 /drivers/usb/serial/empeg.c
parent1aa3692da57c773e5c76de55c5c4a953962d360e (diff)
usb_serial: API all change
USB serial likes to use port->tty back pointers for the real work it does and to do so without any actual locking. Unfortunately when you consider hangup events, hangup/parallel reopen or even worse hangup followed by parallel close events the tty->port and port->tty pointers are not guaranteed to be the same as port->tty is the active tty while tty->port is the port the tty may or may not still be attached to. So rework the entire API to pass the tty struct. For console cases we need to pass both for now. This shows up multiple drivers that immediately crash with USB console some of which have been fixed in the process. Longer term we need a proper tty as console abstraction Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb/serial/empeg.c')
-rw-r--r--drivers/usb/serial/empeg.c78
1 files changed, 30 insertions, 48 deletions
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index c5ec309a3cb1..47ebdf5fad8e 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -31,7 +31,7 @@
31 * Moved MOD_DEC_USE_COUNT to end of empeg_close(). 31 * Moved MOD_DEC_USE_COUNT to end of empeg_close().
32 * 32 *
33 * (12/03/2000) gb 33 * (12/03/2000) gb
34 * Added port->tty->ldisc.set_termios(port->tty, NULL) to empeg_open() 34 * Added port->port.tty->ldisc.set_termios(port->port.tty, NULL) to empeg_open()
35 * This notifies the tty driver that the termios have changed. 35 * This notifies the tty driver that the termios have changed.
36 * 36 *
37 * (11/13/2000) gb 37 * (11/13/2000) gb
@@ -77,22 +77,18 @@ static int debug;
77#define EMPEG_PRODUCT_ID 0x0001 77#define EMPEG_PRODUCT_ID 0x0001
78 78
79/* function prototypes for an empeg-car player */ 79/* function prototypes for an empeg-car player */
80static int empeg_open (struct usb_serial_port *port, struct file *filp); 80static int empeg_open (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
81static void empeg_close (struct usb_serial_port *port, struct file *filp); 81static void empeg_close (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
82static int empeg_write (struct usb_serial_port *port, 82static int empeg_write (struct tty_struct *tty, struct usb_serial_port *port,
83 const unsigned char *buf, 83 const unsigned char *buf,
84 int count); 84 int count);
85static int empeg_write_room (struct usb_serial_port *port); 85static int empeg_write_room (struct tty_struct *tty);
86static int empeg_chars_in_buffer (struct usb_serial_port *port); 86static int empeg_chars_in_buffer (struct tty_struct *tty);
87static void empeg_throttle (struct usb_serial_port *port); 87static void empeg_throttle (struct tty_struct *tty);
88static void empeg_unthrottle (struct usb_serial_port *port); 88static void empeg_unthrottle (struct tty_struct *tty);
89static int empeg_startup (struct usb_serial *serial); 89static int empeg_startup (struct usb_serial *serial);
90static void empeg_shutdown (struct usb_serial *serial); 90static void empeg_shutdown (struct usb_serial *serial);
91static int empeg_ioctl (struct usb_serial_port *port, 91static void empeg_set_termios (struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios);
92 struct file * file,
93 unsigned int cmd,
94 unsigned long arg);
95static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
96static void empeg_write_bulk_callback (struct urb *urb); 92static void empeg_write_bulk_callback (struct urb *urb);
97static void empeg_read_bulk_callback (struct urb *urb); 93static void empeg_read_bulk_callback (struct urb *urb);
98 94
@@ -125,7 +121,6 @@ static struct usb_serial_driver empeg_device = {
125 .unthrottle = empeg_unthrottle, 121 .unthrottle = empeg_unthrottle,
126 .attach = empeg_startup, 122 .attach = empeg_startup,
127 .shutdown = empeg_shutdown, 123 .shutdown = empeg_shutdown,
128 .ioctl = empeg_ioctl,
129 .set_termios = empeg_set_termios, 124 .set_termios = empeg_set_termios,
130 .write = empeg_write, 125 .write = empeg_write,
131 .write_room = empeg_write_room, 126 .write_room = empeg_write_room,
@@ -145,7 +140,8 @@ static int bytes_out;
145/****************************************************************************** 140/******************************************************************************
146 * Empeg specific driver functions 141 * Empeg specific driver functions
147 ******************************************************************************/ 142 ******************************************************************************/
148static int empeg_open (struct usb_serial_port *port, struct file *filp) 143static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port,
144 struct file *filp)
149{ 145{
150 struct usb_serial *serial = port->serial; 146 struct usb_serial *serial = port->serial;
151 int result = 0; 147 int result = 0;
@@ -153,7 +149,7 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp)
153 dbg("%s - port %d", __func__, port->number); 149 dbg("%s - port %d", __func__, port->number);
154 150
155 /* Force default termio settings */ 151 /* Force default termio settings */
156 empeg_set_termios (port, NULL) ; 152 empeg_set_termios (tty, port, NULL) ;
157 153
158 bytes_in = 0; 154 bytes_in = 0;
159 bytes_out = 0; 155 bytes_out = 0;
@@ -178,7 +174,8 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp)
178} 174}
179 175
180 176
181static void empeg_close (struct usb_serial_port *port, struct file * filp) 177static void empeg_close(struct tty_struct *tty, struct usb_serial_port *port,
178 struct file * filp)
182{ 179{
183 dbg("%s - port %d", __func__, port->number); 180 dbg("%s - port %d", __func__, port->number);
184 181
@@ -189,7 +186,7 @@ static void empeg_close (struct usb_serial_port *port, struct file * filp)
189} 186}
190 187
191 188
192static int empeg_write (struct usb_serial_port *port, const unsigned char *buf, int count) 189static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count)
193{ 190{
194 struct usb_serial *serial = port->serial; 191 struct usb_serial *serial = port->serial;
195 struct urb *urb; 192 struct urb *urb;
@@ -203,7 +200,6 @@ static int empeg_write (struct usb_serial_port *port, const unsigned char *buf,
203 dbg("%s - port %d", __func__, port->number); 200 dbg("%s - port %d", __func__, port->number);
204 201
205 while (count > 0) { 202 while (count > 0) {
206
207 /* try to find a free urb in our list of them */ 203 /* try to find a free urb in our list of them */
208 urb = NULL; 204 urb = NULL;
209 205
@@ -262,15 +258,14 @@ static int empeg_write (struct usb_serial_port *port, const unsigned char *buf,
262 bytes_out += transfer_size; 258 bytes_out += transfer_size;
263 259
264 } 260 }
265
266exit: 261exit:
267 return bytes_sent; 262 return bytes_sent;
268
269} 263}
270 264
271 265
272static int empeg_write_room (struct usb_serial_port *port) 266static int empeg_write_room(struct tty_struct *tty)
273{ 267{
268 struct usb_serial_port *port = tty->driver_data;
274 unsigned long flags; 269 unsigned long flags;
275 int i; 270 int i;
276 int room = 0; 271 int room = 0;
@@ -278,25 +273,22 @@ static int empeg_write_room (struct usb_serial_port *port)
278 dbg("%s - port %d", __func__, port->number); 273 dbg("%s - port %d", __func__, port->number);
279 274
280 spin_lock_irqsave (&write_urb_pool_lock, flags); 275 spin_lock_irqsave (&write_urb_pool_lock, flags);
281
282 /* tally up the number of bytes available */ 276 /* tally up the number of bytes available */
283 for (i = 0; i < NUM_URBS; ++i) { 277 for (i = 0; i < NUM_URBS; ++i) {
284 if (write_urb_pool[i]->status != -EINPROGRESS) { 278 if (write_urb_pool[i]->status != -EINPROGRESS) {
285 room += URB_TRANSFER_BUFFER_SIZE; 279 room += URB_TRANSFER_BUFFER_SIZE;
286 } 280 }
287 } 281 }
288
289 spin_unlock_irqrestore (&write_urb_pool_lock, flags); 282 spin_unlock_irqrestore (&write_urb_pool_lock, flags);
290
291 dbg("%s - returns %d", __func__, room); 283 dbg("%s - returns %d", __func__, room);
292 284 return room;
293 return (room);
294 285
295} 286}
296 287
297 288
298static int empeg_chars_in_buffer (struct usb_serial_port *port) 289static int empeg_chars_in_buffer(struct tty_struct *tty)
299{ 290{
291 struct usb_serial_port *port = tty->driver_data;
300 unsigned long flags; 292 unsigned long flags;
301 int i; 293 int i;
302 int chars = 0; 294 int chars = 0;
@@ -356,7 +348,7 @@ static void empeg_read_bulk_callback (struct urb *urb)
356 348
357 usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); 349 usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
358 350
359 tty = port->tty; 351 tty = port->port.tty;
360 352
361 if (urb->actual_length) { 353 if (urb->actual_length) {
362 tty_buffer_request_room(tty, urb->actual_length); 354 tty_buffer_request_room(tty, urb->actual_length);
@@ -386,27 +378,24 @@ static void empeg_read_bulk_callback (struct urb *urb)
386} 378}
387 379
388 380
389static void empeg_throttle (struct usb_serial_port *port) 381static void empeg_throttle(struct tty_struct *tty)
390{ 382{
383 struct usb_serial_port *port = tty->driver_data;
391 dbg("%s - port %d", __func__, port->number); 384 dbg("%s - port %d", __func__, port->number);
392 usb_kill_urb(port->read_urb); 385 usb_kill_urb(port->read_urb);
393} 386}
394 387
395 388
396static void empeg_unthrottle (struct usb_serial_port *port) 389static void empeg_unthrottle(struct tty_struct *tty)
397{ 390{
391 struct usb_serial_port *port = tty->driver_data;
398 int result; 392 int result;
399
400 dbg("%s - port %d", __func__, port->number); 393 dbg("%s - port %d", __func__, port->number);
401 394
402 port->read_urb->dev = port->serial->dev; 395 port->read_urb->dev = port->serial->dev;
403
404 result = usb_submit_urb(port->read_urb, GFP_ATOMIC); 396 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
405
406 if (result) 397 if (result)
407 dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result); 398 dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result);
408
409 return;
410} 399}
411 400
412 401
@@ -436,17 +425,10 @@ static void empeg_shutdown (struct usb_serial *serial)
436} 425}
437 426
438 427
439static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) 428static void empeg_set_termios(struct tty_struct *tty,
440{ 429 struct usb_serial_port *port, struct ktermios *old_termios)
441 dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
442
443 return -ENOIOCTLCMD;
444}
445
446
447static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
448{ 430{
449 struct ktermios *termios = port->tty->termios; 431 struct ktermios *termios = tty->termios;
450 dbg("%s - port %d", __func__, port->number); 432 dbg("%s - port %d", __func__, port->number);
451 433
452 /* 434 /*
@@ -491,8 +473,8 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol
491 * this is bad as it opens up the possibility of dropping bytes 473 * this is bad as it opens up the possibility of dropping bytes
492 * on the floor. We don't want to drop bytes on the floor. :) 474 * on the floor. We don't want to drop bytes on the floor. :)
493 */ 475 */
494 port->tty->low_latency = 1; 476 tty->low_latency = 1;
495 tty_encode_baud_rate(port->tty, 115200, 115200); 477 tty_encode_baud_rate(tty, 115200, 115200);
496} 478}
497 479
498 480