aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/generic.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/generic.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/generic.c')
-rw-r--r--drivers/usb/serial/generic.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 537f12a027c2..5128018c2766 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -112,7 +112,8 @@ void usb_serial_generic_deregister (void)
112#endif 112#endif
113} 113}
114 114
115int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) 115int usb_serial_generic_open(struct tty_struct *tty,
116 struct usb_serial_port *port, struct file *filp)
116{ 117{
117 struct usb_serial *serial = port->serial; 118 struct usb_serial *serial = port->serial;
118 int result = 0; 119 int result = 0;
@@ -123,8 +124,8 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
123 /* force low_latency on so that our tty_push actually forces the data through, 124 /* force low_latency on so that our tty_push actually forces the data through,
124 otherwise it is scheduled, and with high data rates (like with OHCI) data 125 otherwise it is scheduled, and with high data rates (like with OHCI) data
125 can get lost. */ 126 can get lost. */
126 if (port->tty) 127 if (tty)
127 port->tty->low_latency = 1; 128 tty->low_latency = 1;
128 129
129 /* clear the throttle flags */ 130 /* clear the throttle flags */
130 spin_lock_irqsave(&port->lock, flags); 131 spin_lock_irqsave(&port->lock, flags);
@@ -152,7 +153,7 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
152} 153}
153EXPORT_SYMBOL_GPL(usb_serial_generic_open); 154EXPORT_SYMBOL_GPL(usb_serial_generic_open);
154 155
155static void generic_cleanup (struct usb_serial_port *port) 156static void generic_cleanup(struct usb_serial_port *port)
156{ 157{
157 struct usb_serial *serial = port->serial; 158 struct usb_serial *serial = port->serial;
158 159
@@ -182,7 +183,7 @@ int usb_serial_generic_resume(struct usb_serial *serial)
182#endif 183#endif
183 for (i = 0; i < serial->num_ports; i++) { 184 for (i = 0; i < serial->num_ports; i++) {
184 port = serial->port[i]; 185 port = serial->port[i];
185 if (port->open_count && port->read_urb) { 186 if (port->port.count && port->read_urb) {
186 r = usb_submit_urb(port->read_urb, GFP_NOIO); 187 r = usb_submit_urb(port->read_urb, GFP_NOIO);
187 if (r < 0) 188 if (r < 0)
188 c++; 189 c++;
@@ -192,13 +193,15 @@ int usb_serial_generic_resume(struct usb_serial *serial)
192 return c ? -EIO : 0; 193 return c ? -EIO : 0;
193} 194}
194 195
195void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp) 196void usb_serial_generic_close(struct tty_struct *tty,
197 struct usb_serial_port *port, struct file * filp)
196{ 198{
197 dbg("%s - port %d", __func__, port->number); 199 dbg("%s - port %d", __func__, port->number);
198 generic_cleanup (port); 200 generic_cleanup (port);
199} 201}
200 202
201int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *buf, int count) 203int usb_serial_generic_write(struct tty_struct *tty,
204 struct usb_serial_port *port, const unsigned char *buf, int count)
202{ 205{
203 struct usb_serial *serial = port->serial; 206 struct usb_serial *serial = port->serial;
204 int result; 207 int result;
@@ -255,8 +258,9 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *
255 return 0; 258 return 0;
256} 259}
257 260
258int usb_serial_generic_write_room (struct usb_serial_port *port) 261int usb_serial_generic_write_room (struct tty_struct *tty)
259{ 262{
263 struct usb_serial_port *port = tty->driver_data;
260 struct usb_serial *serial = port->serial; 264 struct usb_serial *serial = port->serial;
261 int room = 0; 265 int room = 0;
262 266
@@ -272,8 +276,9 @@ int usb_serial_generic_write_room (struct usb_serial_port *port)
272 return room; 276 return room;
273} 277}
274 278
275int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port) 279int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
276{ 280{
281 struct usb_serial_port *port = tty->driver_data;
277 struct usb_serial *serial = port->serial; 282 struct usb_serial *serial = port->serial;
278 int chars = 0; 283 int chars = 0;
279 284
@@ -286,7 +291,7 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
286 } 291 }
287 292
288 dbg("%s - returns %d", __func__, chars); 293 dbg("%s - returns %d", __func__, chars);
289 return (chars); 294 return chars;
290} 295}
291 296
292 297
@@ -311,10 +316,10 @@ static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
311} 316}
312 317
313/* Push data to tty layer and resubmit the bulk read URB */ 318/* Push data to tty layer and resubmit the bulk read URB */
314static void flush_and_resubmit_read_urb (struct usb_serial_port *port) 319static void flush_and_resubmit_read_urb(struct usb_serial_port *port)
315{ 320{
316 struct urb *urb = port->read_urb; 321 struct urb *urb = port->read_urb;
317 struct tty_struct *tty = port->tty; 322 struct tty_struct *tty = port->port.tty;
318 int room; 323 int room;
319 324
320 /* Push data to tty */ 325 /* Push data to tty */
@@ -329,7 +334,7 @@ static void flush_and_resubmit_read_urb (struct usb_serial_port *port)
329 resubmit_read_urb(port, GFP_ATOMIC); 334 resubmit_read_urb(port, GFP_ATOMIC);
330} 335}
331 336
332void usb_serial_generic_read_bulk_callback (struct urb *urb) 337void usb_serial_generic_read_bulk_callback(struct urb *urb)
333{ 338{
334 struct usb_serial_port *port = urb->context; 339 struct usb_serial_port *port = urb->context;
335 unsigned char *data = urb->transfer_buffer; 340 unsigned char *data = urb->transfer_buffer;
@@ -357,7 +362,7 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb)
357} 362}
358EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); 363EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
359 364
360void usb_serial_generic_write_bulk_callback (struct urb *urb) 365void usb_serial_generic_write_bulk_callback(struct urb *urb)
361{ 366{
362 struct usb_serial_port *port = urb->context; 367 struct usb_serial_port *port = urb->context;
363 int status = urb->status; 368 int status = urb->status;
@@ -374,8 +379,9 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb)
374} 379}
375EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); 380EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
376 381
377void usb_serial_generic_throttle (struct usb_serial_port *port) 382void usb_serial_generic_throttle(struct tty_struct *tty)
378{ 383{
384 struct usb_serial_port *port = tty->driver_data;
379 unsigned long flags; 385 unsigned long flags;
380 386
381 dbg("%s - port %d", __func__, port->number); 387 dbg("%s - port %d", __func__, port->number);
@@ -387,8 +393,9 @@ void usb_serial_generic_throttle (struct usb_serial_port *port)
387 spin_unlock_irqrestore(&port->lock, flags); 393 spin_unlock_irqrestore(&port->lock, flags);
388} 394}
389 395
390void usb_serial_generic_unthrottle (struct usb_serial_port *port) 396void usb_serial_generic_unthrottle(struct tty_struct *tty)
391{ 397{
398 struct usb_serial_port *port = tty->driver_data;
392 int was_throttled; 399 int was_throttled;
393 unsigned long flags; 400 unsigned long flags;
394 401