diff options
Diffstat (limited to 'drivers/usb/serial/belkin_sa.c')
-rw-r--r-- | drivers/usb/serial/belkin_sa.c | 130 |
1 files changed, 65 insertions, 65 deletions
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 1295e44e3f1c..36df35295db2 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2000 William Greathouse (wgreathouse@smva.com) | 4 | * Copyright (C) 2000 William Greathouse (wgreathouse@smva.com) |
5 | * Copyright (C) 2000-2001 Greg Kroah-Hartman (greg@kroah.com) | 5 | * Copyright (C) 2000-2001 Greg Kroah-Hartman (greg@kroah.com) |
6 | * Copyright (C) 2010 Johan Hovold (jhovold@gmail.com) | ||
6 | * | 7 | * |
7 | * This program is largely derived from work by the linux-usb group | 8 | * This program is largely derived from work by the linux-usb group |
8 | * and associated source files. Please see the usb/serial files for | 9 | * and associated source files. Please see the usb/serial files for |
@@ -84,7 +85,7 @@ static int debug; | |||
84 | /* | 85 | /* |
85 | * Version Information | 86 | * Version Information |
86 | */ | 87 | */ |
87 | #define DRIVER_VERSION "v1.2" | 88 | #define DRIVER_VERSION "v1.3" |
88 | #define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>" | 89 | #define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>" |
89 | #define DRIVER_DESC "USB Belkin Serial converter driver" | 90 | #define DRIVER_DESC "USB Belkin Serial converter driver" |
90 | 91 | ||
@@ -95,6 +96,7 @@ static int belkin_sa_open(struct tty_struct *tty, | |||
95 | struct usb_serial_port *port); | 96 | struct usb_serial_port *port); |
96 | static void belkin_sa_close(struct usb_serial_port *port); | 97 | static void belkin_sa_close(struct usb_serial_port *port); |
97 | static void belkin_sa_read_int_callback(struct urb *urb); | 98 | static void belkin_sa_read_int_callback(struct urb *urb); |
99 | static void belkin_sa_process_read_urb(struct urb *urb); | ||
98 | static void belkin_sa_set_termios(struct tty_struct *tty, | 100 | static void belkin_sa_set_termios(struct tty_struct *tty, |
99 | struct usb_serial_port *port, struct ktermios * old); | 101 | struct usb_serial_port *port, struct ktermios * old); |
100 | static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state); | 102 | static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state); |
@@ -112,7 +114,6 @@ static const struct usb_device_id id_table_combined[] = { | |||
112 | { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) }, | 114 | { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) }, |
113 | { } /* Terminating entry */ | 115 | { } /* Terminating entry */ |
114 | }; | 116 | }; |
115 | |||
116 | MODULE_DEVICE_TABLE(usb, id_table_combined); | 117 | MODULE_DEVICE_TABLE(usb, id_table_combined); |
117 | 118 | ||
118 | static struct usb_driver belkin_driver = { | 119 | static struct usb_driver belkin_driver = { |
@@ -120,7 +121,7 @@ static struct usb_driver belkin_driver = { | |||
120 | .probe = usb_serial_probe, | 121 | .probe = usb_serial_probe, |
121 | .disconnect = usb_serial_disconnect, | 122 | .disconnect = usb_serial_disconnect, |
122 | .id_table = id_table_combined, | 123 | .id_table = id_table_combined, |
123 | .no_dynamic_id = 1, | 124 | .no_dynamic_id = 1, |
124 | }; | 125 | }; |
125 | 126 | ||
126 | /* All of the device info needed for the serial converters */ | 127 | /* All of the device info needed for the serial converters */ |
@@ -136,7 +137,7 @@ static struct usb_serial_driver belkin_device = { | |||
136 | .open = belkin_sa_open, | 137 | .open = belkin_sa_open, |
137 | .close = belkin_sa_close, | 138 | .close = belkin_sa_close, |
138 | .read_int_callback = belkin_sa_read_int_callback, | 139 | .read_int_callback = belkin_sa_read_int_callback, |
139 | /* How we get the status info */ | 140 | .process_read_urb = belkin_sa_process_read_urb, |
140 | .set_termios = belkin_sa_set_termios, | 141 | .set_termios = belkin_sa_set_termios, |
141 | .break_ctl = belkin_sa_break_ctl, | 142 | .break_ctl = belkin_sa_break_ctl, |
142 | .tiocmget = belkin_sa_tiocmget, | 143 | .tiocmget = belkin_sa_tiocmget, |
@@ -145,7 +146,6 @@ static struct usb_serial_driver belkin_device = { | |||
145 | .release = belkin_sa_release, | 146 | .release = belkin_sa_release, |
146 | }; | 147 | }; |
147 | 148 | ||
148 | |||
149 | struct belkin_sa_private { | 149 | struct belkin_sa_private { |
150 | spinlock_t lock; | 150 | spinlock_t lock; |
151 | unsigned long control_state; | 151 | unsigned long control_state; |
@@ -196,62 +196,43 @@ static int belkin_sa_startup(struct usb_serial *serial) | |||
196 | return 0; | 196 | return 0; |
197 | } | 197 | } |
198 | 198 | ||
199 | |||
200 | static void belkin_sa_release(struct usb_serial *serial) | 199 | static void belkin_sa_release(struct usb_serial *serial) |
201 | { | 200 | { |
202 | struct belkin_sa_private *priv; | ||
203 | int i; | 201 | int i; |
204 | 202 | ||
205 | dbg("%s", __func__); | 203 | dbg("%s", __func__); |
206 | 204 | ||
207 | for (i = 0; i < serial->num_ports; ++i) { | 205 | for (i = 0; i < serial->num_ports; ++i) |
208 | /* My special items, the standard routines free my urbs */ | 206 | kfree(usb_get_serial_port_data(serial->port[i])); |
209 | priv = usb_get_serial_port_data(serial->port[i]); | ||
210 | kfree(priv); | ||
211 | } | ||
212 | } | 207 | } |
213 | 208 | ||
214 | 209 | static int belkin_sa_open(struct tty_struct *tty, | |
215 | static int belkin_sa_open(struct tty_struct *tty, | ||
216 | struct usb_serial_port *port) | 210 | struct usb_serial_port *port) |
217 | { | 211 | { |
218 | int retval = 0; | 212 | int retval; |
219 | 213 | ||
220 | dbg("%s port %d", __func__, port->number); | 214 | dbg("%s port %d", __func__, port->number); |
221 | 215 | ||
222 | /*Start reading from the device*/ | ||
223 | /* TODO: Look at possibility of submitting multiple URBs to device to | ||
224 | * enhance buffering. Win trace shows 16 initial read URBs. | ||
225 | */ | ||
226 | port->read_urb->dev = port->serial->dev; | ||
227 | retval = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
228 | if (retval) { | ||
229 | dev_err(&port->dev, "usb_submit_urb(read bulk) failed\n"); | ||
230 | goto exit; | ||
231 | } | ||
232 | |||
233 | port->interrupt_in_urb->dev = port->serial->dev; | ||
234 | retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | 216 | retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
235 | if (retval) { | 217 | if (retval) { |
236 | usb_kill_urb(port->read_urb); | ||
237 | dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); | 218 | dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); |
219 | return retval; | ||
238 | } | 220 | } |
239 | 221 | ||
240 | exit: | 222 | retval = usb_serial_generic_open(tty, port); |
241 | return retval; | 223 | if (retval) |
242 | } /* belkin_sa_open */ | 224 | usb_kill_urb(port->interrupt_in_urb); |
243 | 225 | ||
226 | return retval; | ||
227 | } | ||
244 | 228 | ||
245 | static void belkin_sa_close(struct usb_serial_port *port) | 229 | static void belkin_sa_close(struct usb_serial_port *port) |
246 | { | 230 | { |
247 | dbg("%s port %d", __func__, port->number); | 231 | dbg("%s port %d", __func__, port->number); |
248 | 232 | ||
249 | /* shutdown our bulk reads and writes */ | 233 | usb_serial_generic_close(port); |
250 | usb_kill_urb(port->write_urb); | ||
251 | usb_kill_urb(port->read_urb); | ||
252 | usb_kill_urb(port->interrupt_in_urb); | 234 | usb_kill_urb(port->interrupt_in_urb); |
253 | } /* belkin_sa_close */ | 235 | } |
254 | |||
255 | 236 | ||
256 | static void belkin_sa_read_int_callback(struct urb *urb) | 237 | static void belkin_sa_read_int_callback(struct urb *urb) |
257 | { | 238 | { |
@@ -310,31 +291,7 @@ static void belkin_sa_read_int_callback(struct urb *urb) | |||
310 | else | 291 | else |
311 | priv->control_state &= ~TIOCM_CD; | 292 | priv->control_state &= ~TIOCM_CD; |
312 | 293 | ||
313 | /* Now to report any errors */ | ||
314 | priv->last_lsr = data[BELKIN_SA_LSR_INDEX]; | 294 | priv->last_lsr = data[BELKIN_SA_LSR_INDEX]; |
315 | #if 0 | ||
316 | /* | ||
317 | * fill in the flip buffer here, but I do not know the relation | ||
318 | * to the current/next receive buffer or characters. I need | ||
319 | * to look in to this before committing any code. | ||
320 | */ | ||
321 | if (priv->last_lsr & BELKIN_SA_LSR_ERR) { | ||
322 | tty = tty_port_tty_get(&port->port); | ||
323 | /* Overrun Error */ | ||
324 | if (priv->last_lsr & BELKIN_SA_LSR_OE) { | ||
325 | } | ||
326 | /* Parity Error */ | ||
327 | if (priv->last_lsr & BELKIN_SA_LSR_PE) { | ||
328 | } | ||
329 | /* Framing Error */ | ||
330 | if (priv->last_lsr & BELKIN_SA_LSR_FE) { | ||
331 | } | ||
332 | /* Break Indicator */ | ||
333 | if (priv->last_lsr & BELKIN_SA_LSR_BI) { | ||
334 | } | ||
335 | tty_kref_put(tty); | ||
336 | } | ||
337 | #endif | ||
338 | spin_unlock_irqrestore(&priv->lock, flags); | 295 | spin_unlock_irqrestore(&priv->lock, flags); |
339 | exit: | 296 | exit: |
340 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 297 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -343,6 +300,53 @@ exit: | |||
343 | "result %d\n", __func__, retval); | 300 | "result %d\n", __func__, retval); |
344 | } | 301 | } |
345 | 302 | ||
303 | static void belkin_sa_process_read_urb(struct urb *urb) | ||
304 | { | ||
305 | struct usb_serial_port *port = urb->context; | ||
306 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); | ||
307 | struct tty_struct *tty; | ||
308 | unsigned char *data = urb->transfer_buffer; | ||
309 | unsigned long flags; | ||
310 | unsigned char status; | ||
311 | char tty_flag; | ||
312 | |||
313 | /* Update line status */ | ||
314 | tty_flag = TTY_NORMAL; | ||
315 | |||
316 | spin_lock_irqsave(&priv->lock, flags); | ||
317 | status = priv->last_lsr; | ||
318 | priv->last_lsr &= ~BELKIN_SA_LSR_ERR; | ||
319 | spin_unlock_irqrestore(&priv->lock, flags); | ||
320 | |||
321 | if (!urb->actual_length) | ||
322 | return; | ||
323 | |||
324 | tty = tty_port_tty_get(&port->port); | ||
325 | if (!tty) | ||
326 | return; | ||
327 | |||
328 | if (status & BELKIN_SA_LSR_ERR) { | ||
329 | /* Break takes precedence over parity, which takes precedence | ||
330 | * over framing errors. */ | ||
331 | if (status & BELKIN_SA_LSR_BI) | ||
332 | tty_flag = TTY_BREAK; | ||
333 | else if (status & BELKIN_SA_LSR_PE) | ||
334 | tty_flag = TTY_PARITY; | ||
335 | else if (status & BELKIN_SA_LSR_FE) | ||
336 | tty_flag = TTY_FRAME; | ||
337 | dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag); | ||
338 | |||
339 | /* Overrun is special, not associated with a char. */ | ||
340 | if (status & BELKIN_SA_LSR_OE) | ||
341 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
342 | } | ||
343 | |||
344 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | ||
345 | urb->actual_length); | ||
346 | tty_flip_buffer_push(tty); | ||
347 | tty_kref_put(tty); | ||
348 | } | ||
349 | |||
346 | static void belkin_sa_set_termios(struct tty_struct *tty, | 350 | static void belkin_sa_set_termios(struct tty_struct *tty, |
347 | struct usb_serial_port *port, struct ktermios *old_termios) | 351 | struct usb_serial_port *port, struct ktermios *old_termios) |
348 | { | 352 | { |
@@ -482,8 +486,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty, | |||
482 | spin_lock_irqsave(&priv->lock, flags); | 486 | spin_lock_irqsave(&priv->lock, flags); |
483 | priv->control_state = control_state; | 487 | priv->control_state = control_state; |
484 | spin_unlock_irqrestore(&priv->lock, flags); | 488 | spin_unlock_irqrestore(&priv->lock, flags); |
485 | } /* belkin_sa_set_termios */ | 489 | } |
486 | |||
487 | 490 | ||
488 | static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state) | 491 | static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state) |
489 | { | 492 | { |
@@ -494,7 +497,6 @@ static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state) | |||
494 | dev_err(&port->dev, "Set break_ctl %d\n", break_state); | 497 | dev_err(&port->dev, "Set break_ctl %d\n", break_state); |
495 | } | 498 | } |
496 | 499 | ||
497 | |||
498 | static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file) | 500 | static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file) |
499 | { | 501 | { |
500 | struct usb_serial_port *port = tty->driver_data; | 502 | struct usb_serial_port *port = tty->driver_data; |
@@ -511,7 +513,6 @@ static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file) | |||
511 | return control_state; | 513 | return control_state; |
512 | } | 514 | } |
513 | 515 | ||
514 | |||
515 | static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file, | 516 | static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file, |
516 | unsigned int set, unsigned int clear) | 517 | unsigned int set, unsigned int clear) |
517 | { | 518 | { |
@@ -583,7 +584,6 @@ failed_usb_serial_register: | |||
583 | return retval; | 584 | return retval; |
584 | } | 585 | } |
585 | 586 | ||
586 | |||
587 | static void __exit belkin_sa_exit (void) | 587 | static void __exit belkin_sa_exit (void) |
588 | { | 588 | { |
589 | usb_deregister(&belkin_driver); | 589 | usb_deregister(&belkin_driver); |