diff options
Diffstat (limited to 'drivers/usb/serial')
43 files changed, 1919 insertions, 1512 deletions
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 6d106e74265e..2cbfab3716e5 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -364,7 +364,7 @@ static int aircable_attach(struct usb_serial *serial) | |||
364 | return 0; | 364 | return 0; |
365 | } | 365 | } |
366 | 366 | ||
367 | static void aircable_shutdown(struct usb_serial *serial) | 367 | static void aircable_release(struct usb_serial *serial) |
368 | { | 368 | { |
369 | 369 | ||
370 | struct usb_serial_port *port = serial->port[0]; | 370 | struct usb_serial_port *port = serial->port[0]; |
@@ -375,7 +375,6 @@ static void aircable_shutdown(struct usb_serial *serial) | |||
375 | if (priv) { | 375 | if (priv) { |
376 | serial_buf_free(priv->tx_buf); | 376 | serial_buf_free(priv->tx_buf); |
377 | serial_buf_free(priv->rx_buf); | 377 | serial_buf_free(priv->rx_buf); |
378 | usb_set_serial_port_data(port, NULL); | ||
379 | kfree(priv); | 378 | kfree(priv); |
380 | } | 379 | } |
381 | } | 380 | } |
@@ -601,7 +600,7 @@ static struct usb_serial_driver aircable_device = { | |||
601 | .num_ports = 1, | 600 | .num_ports = 1, |
602 | .attach = aircable_attach, | 601 | .attach = aircable_attach, |
603 | .probe = aircable_probe, | 602 | .probe = aircable_probe, |
604 | .shutdown = aircable_shutdown, | 603 | .release = aircable_release, |
605 | .write = aircable_write, | 604 | .write = aircable_write, |
606 | .write_room = aircable_write_room, | 605 | .write_room = aircable_write_room, |
607 | .write_bulk_callback = aircable_write_bulk_callback, | 606 | .write_bulk_callback = aircable_write_bulk_callback, |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index b7eacad4d48c..7033b031b443 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -90,11 +90,10 @@ static int debug; | |||
90 | 90 | ||
91 | /* function prototypes for a Belkin USB Serial Adapter F5U103 */ | 91 | /* function prototypes for a Belkin USB Serial Adapter F5U103 */ |
92 | static int belkin_sa_startup(struct usb_serial *serial); | 92 | static int belkin_sa_startup(struct usb_serial *serial); |
93 | static void belkin_sa_shutdown(struct usb_serial *serial); | 93 | static void belkin_sa_release(struct usb_serial *serial); |
94 | static int belkin_sa_open(struct tty_struct *tty, | 94 | static int belkin_sa_open(struct tty_struct *tty, |
95 | struct usb_serial_port *port, struct file *filp); | 95 | struct usb_serial_port *port, struct file *filp); |
96 | static void belkin_sa_close(struct tty_struct *tty, | 96 | static void belkin_sa_close(struct usb_serial_port *port); |
97 | struct usb_serial_port *port, struct file *filp); | ||
98 | static void belkin_sa_read_int_callback(struct urb *urb); | 97 | static void belkin_sa_read_int_callback(struct urb *urb); |
99 | static void belkin_sa_set_termios(struct tty_struct *tty, | 98 | static void belkin_sa_set_termios(struct tty_struct *tty, |
100 | struct usb_serial_port *port, struct ktermios * old); | 99 | struct usb_serial_port *port, struct ktermios * old); |
@@ -143,7 +142,7 @@ static struct usb_serial_driver belkin_device = { | |||
143 | .tiocmget = belkin_sa_tiocmget, | 142 | .tiocmget = belkin_sa_tiocmget, |
144 | .tiocmset = belkin_sa_tiocmset, | 143 | .tiocmset = belkin_sa_tiocmset, |
145 | .attach = belkin_sa_startup, | 144 | .attach = belkin_sa_startup, |
146 | .shutdown = belkin_sa_shutdown, | 145 | .release = belkin_sa_release, |
147 | }; | 146 | }; |
148 | 147 | ||
149 | 148 | ||
@@ -198,14 +197,13 @@ static int belkin_sa_startup(struct usb_serial *serial) | |||
198 | } | 197 | } |
199 | 198 | ||
200 | 199 | ||
201 | static void belkin_sa_shutdown(struct usb_serial *serial) | 200 | static void belkin_sa_release(struct usb_serial *serial) |
202 | { | 201 | { |
203 | struct belkin_sa_private *priv; | 202 | struct belkin_sa_private *priv; |
204 | int i; | 203 | int i; |
205 | 204 | ||
206 | dbg("%s", __func__); | 205 | dbg("%s", __func__); |
207 | 206 | ||
208 | /* stop reads and writes on all ports */ | ||
209 | for (i = 0; i < serial->num_ports; ++i) { | 207 | for (i = 0; i < serial->num_ports; ++i) { |
210 | /* My special items, the standard routines free my urbs */ | 208 | /* My special items, the standard routines free my urbs */ |
211 | priv = usb_get_serial_port_data(serial->port[i]); | 209 | priv = usb_get_serial_port_data(serial->port[i]); |
@@ -244,8 +242,7 @@ exit: | |||
244 | } /* belkin_sa_open */ | 242 | } /* belkin_sa_open */ |
245 | 243 | ||
246 | 244 | ||
247 | static void belkin_sa_close(struct tty_struct *tty, | 245 | static void belkin_sa_close(struct usb_serial_port *port) |
248 | struct usb_serial_port *port, struct file *filp) | ||
249 | { | 246 | { |
250 | dbg("%s port %d", __func__, port->number); | 247 | dbg("%s port %d", __func__, port->number); |
251 | 248 | ||
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 83bbb5bca2ef..ba555c528cc6 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c | |||
@@ -59,23 +59,22 @@ static int usb_serial_device_probe(struct device *dev) | |||
59 | retval = -ENODEV; | 59 | retval = -ENODEV; |
60 | goto exit; | 60 | goto exit; |
61 | } | 61 | } |
62 | if (port->dev_state != PORT_REGISTERING) | ||
63 | goto exit; | ||
62 | 64 | ||
63 | driver = port->serial->type; | 65 | driver = port->serial->type; |
64 | if (driver->port_probe) { | 66 | if (driver->port_probe) { |
65 | if (!try_module_get(driver->driver.owner)) { | ||
66 | dev_err(dev, "module get failed, exiting\n"); | ||
67 | retval = -EIO; | ||
68 | goto exit; | ||
69 | } | ||
70 | retval = driver->port_probe(port); | 67 | retval = driver->port_probe(port); |
71 | module_put(driver->driver.owner); | ||
72 | if (retval) | 68 | if (retval) |
73 | goto exit; | 69 | goto exit; |
74 | } | 70 | } |
75 | 71 | ||
76 | retval = device_create_file(dev, &dev_attr_port_number); | 72 | retval = device_create_file(dev, &dev_attr_port_number); |
77 | if (retval) | 73 | if (retval) { |
74 | if (driver->port_remove) | ||
75 | retval = driver->port_remove(port); | ||
78 | goto exit; | 76 | goto exit; |
77 | } | ||
79 | 78 | ||
80 | minor = port->number; | 79 | minor = port->number; |
81 | tty_register_device(usb_serial_tty_driver, minor, dev); | 80 | tty_register_device(usb_serial_tty_driver, minor, dev); |
@@ -98,19 +97,15 @@ static int usb_serial_device_remove(struct device *dev) | |||
98 | if (!port) | 97 | if (!port) |
99 | return -ENODEV; | 98 | return -ENODEV; |
100 | 99 | ||
100 | if (port->dev_state != PORT_UNREGISTERING) | ||
101 | return retval; | ||
102 | |||
101 | device_remove_file(&port->dev, &dev_attr_port_number); | 103 | device_remove_file(&port->dev, &dev_attr_port_number); |
102 | 104 | ||
103 | driver = port->serial->type; | 105 | driver = port->serial->type; |
104 | if (driver->port_remove) { | 106 | if (driver->port_remove) |
105 | if (!try_module_get(driver->driver.owner)) { | ||
106 | dev_err(dev, "module get failed, exiting\n"); | ||
107 | retval = -EIO; | ||
108 | goto exit; | ||
109 | } | ||
110 | retval = driver->port_remove(port); | 107 | retval = driver->port_remove(port); |
111 | module_put(driver->driver.owner); | 108 | |
112 | } | ||
113 | exit: | ||
114 | minor = port->number; | 109 | minor = port->number; |
115 | tty_unregister_device(usb_serial_tty_driver, minor); | 110 | tty_unregister_device(usb_serial_tty_driver, minor); |
116 | dev_info(dev, "%s converter now disconnected from ttyUSB%d\n", | 111 | dev_info(dev, "%s converter now disconnected from ttyUSB%d\n", |
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index ab4cc277aa65..2830766f5b39 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c | |||
@@ -262,32 +262,40 @@ error: kfree(priv); | |||
262 | return r; | 262 | return r; |
263 | } | 263 | } |
264 | 264 | ||
265 | static void ch341_close(struct tty_struct *tty, struct usb_serial_port *port, | 265 | static int ch341_carrier_raised(struct usb_serial_port *port) |
266 | struct file *filp) | 266 | { |
267 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
268 | if (priv->line_status & CH341_BIT_DCD) | ||
269 | return 1; | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static void ch341_dtr_rts(struct usb_serial_port *port, int on) | ||
267 | { | 274 | { |
268 | struct ch341_private *priv = usb_get_serial_port_data(port); | 275 | struct ch341_private *priv = usb_get_serial_port_data(port); |
269 | unsigned long flags; | 276 | unsigned long flags; |
270 | unsigned int c_cflag; | ||
271 | 277 | ||
272 | dbg("%s - port %d", __func__, port->number); | 278 | dbg("%s - port %d", __func__, port->number); |
279 | /* drop DTR and RTS */ | ||
280 | spin_lock_irqsave(&priv->lock, flags); | ||
281 | if (on) | ||
282 | priv->line_control |= CH341_BIT_RTS | CH341_BIT_DTR; | ||
283 | else | ||
284 | priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR); | ||
285 | spin_unlock_irqrestore(&priv->lock, flags); | ||
286 | ch341_set_handshake(port->serial->dev, priv->line_control); | ||
287 | wake_up_interruptible(&priv->delta_msr_wait); | ||
288 | } | ||
289 | |||
290 | static void ch341_close(struct usb_serial_port *port) | ||
291 | { | ||
292 | dbg("%s - port %d", __func__, port->number); | ||
273 | 293 | ||
274 | /* shutdown our urbs */ | 294 | /* shutdown our urbs */ |
275 | dbg("%s - shutting down urbs", __func__); | 295 | dbg("%s - shutting down urbs", __func__); |
276 | usb_kill_urb(port->write_urb); | 296 | usb_kill_urb(port->write_urb); |
277 | usb_kill_urb(port->read_urb); | 297 | usb_kill_urb(port->read_urb); |
278 | usb_kill_urb(port->interrupt_in_urb); | 298 | usb_kill_urb(port->interrupt_in_urb); |
279 | |||
280 | if (tty) { | ||
281 | c_cflag = tty->termios->c_cflag; | ||
282 | if (c_cflag & HUPCL) { | ||
283 | /* drop DTR and RTS */ | ||
284 | spin_lock_irqsave(&priv->lock, flags); | ||
285 | priv->line_control = 0; | ||
286 | spin_unlock_irqrestore(&priv->lock, flags); | ||
287 | ch341_set_handshake(port->serial->dev, 0); | ||
288 | } | ||
289 | } | ||
290 | wake_up_interruptible(&priv->delta_msr_wait); | ||
291 | } | 299 | } |
292 | 300 | ||
293 | 301 | ||
@@ -302,7 +310,6 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
302 | dbg("ch341_open()"); | 310 | dbg("ch341_open()"); |
303 | 311 | ||
304 | priv->baud_rate = DEFAULT_BAUD_RATE; | 312 | priv->baud_rate = DEFAULT_BAUD_RATE; |
305 | priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; | ||
306 | 313 | ||
307 | r = ch341_configure(serial->dev, priv); | 314 | r = ch341_configure(serial->dev, priv); |
308 | if (r) | 315 | if (r) |
@@ -322,7 +329,7 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
322 | if (r) { | 329 | if (r) { |
323 | dev_err(&port->dev, "%s - failed submitting interrupt urb," | 330 | dev_err(&port->dev, "%s - failed submitting interrupt urb," |
324 | " error %d\n", __func__, r); | 331 | " error %d\n", __func__, r); |
325 | ch341_close(tty, port, NULL); | 332 | ch341_close(port); |
326 | return -EPROTO; | 333 | return -EPROTO; |
327 | } | 334 | } |
328 | 335 | ||
@@ -343,9 +350,6 @@ static void ch341_set_termios(struct tty_struct *tty, | |||
343 | 350 | ||
344 | dbg("ch341_set_termios()"); | 351 | dbg("ch341_set_termios()"); |
345 | 352 | ||
346 | if (!tty || !tty->termios) | ||
347 | return; | ||
348 | |||
349 | baud_rate = tty_get_baud_rate(tty); | 353 | baud_rate = tty_get_baud_rate(tty); |
350 | 354 | ||
351 | priv->baud_rate = baud_rate; | 355 | priv->baud_rate = baud_rate; |
@@ -568,6 +572,8 @@ static struct usb_serial_driver ch341_device = { | |||
568 | .usb_driver = &ch341_driver, | 572 | .usb_driver = &ch341_driver, |
569 | .num_ports = 1, | 573 | .num_ports = 1, |
570 | .open = ch341_open, | 574 | .open = ch341_open, |
575 | .dtr_rts = ch341_dtr_rts, | ||
576 | .carrier_raised = ch341_carrier_raised, | ||
571 | .close = ch341_close, | 577 | .close = ch341_close, |
572 | .ioctl = ch341_ioctl, | 578 | .ioctl = ch341_ioctl, |
573 | .set_termios = ch341_set_termios, | 579 | .set_termios = ch341_set_termios, |
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 19e24045b137..247b61bfb7f4 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -169,7 +169,9 @@ static int usb_console_setup(struct console *co, char *options) | |||
169 | kfree(tty); | 169 | kfree(tty); |
170 | } | 170 | } |
171 | } | 171 | } |
172 | 172 | /* So we know not to kill the hardware on a hangup on this | |
173 | port. We have also bumped the use count by one so it won't go | ||
174 | idle */ | ||
173 | port->console = 1; | 175 | port->console = 1; |
174 | retval = 0; | 176 | retval = 0; |
175 | 177 | ||
@@ -182,7 +184,7 @@ free_tty: | |||
182 | kfree(tty); | 184 | kfree(tty); |
183 | reset_open_count: | 185 | reset_open_count: |
184 | port->port.count = 0; | 186 | port->port.count = 0; |
185 | goto out; | 187 | goto out; |
186 | } | 188 | } |
187 | 189 | ||
188 | static void usb_console_write(struct console *co, | 190 | static void usb_console_write(struct console *co, |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index e8d5133ce9c8..2b9eeda62bfe 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Silicon Laboratories CP2101/CP2102 USB to RS232 serial adaptor driver | 2 | * Silicon Laboratories CP210x USB to RS232 serial adaptor driver |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Craig Shelley (craig@microtron.org.uk) | 4 | * Copyright (C) 2005 Craig Shelley (craig@microtron.org.uk) |
5 | * | 5 | * |
@@ -27,44 +27,46 @@ | |||
27 | /* | 27 | /* |
28 | * Version Information | 28 | * Version Information |
29 | */ | 29 | */ |
30 | #define DRIVER_VERSION "v0.08" | 30 | #define DRIVER_VERSION "v0.09" |
31 | #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" | 31 | #define DRIVER_DESC "Silicon Labs CP210x RS232 serial adaptor driver" |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Function Prototypes | 34 | * Function Prototypes |
35 | */ | 35 | */ |
36 | static int cp2101_open(struct tty_struct *, struct usb_serial_port *, | 36 | static int cp210x_open(struct tty_struct *, struct usb_serial_port *, |
37 | struct file *); | 37 | struct file *); |
38 | static void cp2101_cleanup(struct usb_serial_port *); | 38 | static void cp210x_cleanup(struct usb_serial_port *); |
39 | static void cp2101_close(struct tty_struct *, struct usb_serial_port *, | 39 | static void cp210x_close(struct usb_serial_port *); |
40 | struct file*); | 40 | static void cp210x_get_termios(struct tty_struct *, |
41 | static void cp2101_get_termios(struct tty_struct *, | ||
42 | struct usb_serial_port *port); | 41 | struct usb_serial_port *port); |
43 | static void cp2101_get_termios_port(struct usb_serial_port *port, | 42 | static void cp210x_get_termios_port(struct usb_serial_port *port, |
44 | unsigned int *cflagp, unsigned int *baudp); | 43 | unsigned int *cflagp, unsigned int *baudp); |
45 | static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *, | 44 | static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *, |
46 | struct ktermios*); | 45 | struct ktermios*); |
47 | static int cp2101_tiocmget(struct tty_struct *, struct file *); | 46 | static int cp210x_tiocmget(struct tty_struct *, struct file *); |
48 | static int cp2101_tiocmset(struct tty_struct *, struct file *, | 47 | static int cp210x_tiocmset(struct tty_struct *, struct file *, |
49 | unsigned int, unsigned int); | 48 | unsigned int, unsigned int); |
50 | static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *, | 49 | static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *, |
51 | unsigned int, unsigned int); | 50 | unsigned int, unsigned int); |
52 | static void cp2101_break_ctl(struct tty_struct *, int); | 51 | static void cp210x_break_ctl(struct tty_struct *, int); |
53 | static int cp2101_startup(struct usb_serial *); | 52 | static int cp210x_startup(struct usb_serial *); |
54 | static void cp2101_shutdown(struct usb_serial *); | 53 | static void cp210x_disconnect(struct usb_serial *); |
55 | 54 | ||
56 | static int debug; | 55 | static int debug; |
57 | 56 | ||
58 | static struct usb_device_id id_table [] = { | 57 | static struct usb_device_id id_table [] = { |
59 | { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */ | 58 | { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */ |
60 | { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ | 59 | { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ |
60 | { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ | ||
61 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ | 61 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ |
62 | { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ | ||
62 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ | 63 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ |
63 | { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ | 64 | { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ |
64 | { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ | 65 | { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ |
65 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ | 66 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ |
66 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ | 67 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ |
67 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ | 68 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ |
69 | { USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */ | ||
68 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ | 70 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ |
69 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ | 71 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ |
70 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ | 72 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ |
@@ -85,10 +87,12 @@ static struct usb_device_id id_table [] = { | |||
85 | { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ | 87 | { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ |
86 | { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ | 88 | { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ |
87 | { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ | 89 | { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ |
90 | { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */ | ||
88 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ | 91 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ |
89 | { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ | 92 | { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ |
90 | { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */ | 93 | { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */ |
91 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ | 94 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ |
95 | { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ | ||
92 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ | 96 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ |
93 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ | 97 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ |
94 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ | 98 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ |
@@ -99,7 +103,9 @@ static struct usb_device_id id_table [] = { | |||
99 | { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */ | 103 | { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */ |
100 | { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */ | 104 | { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */ |
101 | { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */ | 105 | { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */ |
106 | { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */ | ||
102 | { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ | 107 | { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ |
108 | { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ | ||
103 | { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ | 109 | { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ |
104 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ | 110 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ |
105 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ | 111 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ |
@@ -108,53 +114,70 @@ static struct usb_device_id id_table [] = { | |||
108 | 114 | ||
109 | MODULE_DEVICE_TABLE(usb, id_table); | 115 | MODULE_DEVICE_TABLE(usb, id_table); |
110 | 116 | ||
111 | static struct usb_driver cp2101_driver = { | 117 | static struct usb_driver cp210x_driver = { |
112 | .name = "cp2101", | 118 | .name = "cp210x", |
113 | .probe = usb_serial_probe, | 119 | .probe = usb_serial_probe, |
114 | .disconnect = usb_serial_disconnect, | 120 | .disconnect = usb_serial_disconnect, |
115 | .id_table = id_table, | 121 | .id_table = id_table, |
116 | .no_dynamic_id = 1, | 122 | .no_dynamic_id = 1, |
117 | }; | 123 | }; |
118 | 124 | ||
119 | static struct usb_serial_driver cp2101_device = { | 125 | static struct usb_serial_driver cp210x_device = { |
120 | .driver = { | 126 | .driver = { |
121 | .owner = THIS_MODULE, | 127 | .owner = THIS_MODULE, |
122 | .name = "cp2101", | 128 | .name = "cp210x", |
123 | }, | 129 | }, |
124 | .usb_driver = &cp2101_driver, | 130 | .usb_driver = &cp210x_driver, |
125 | .id_table = id_table, | 131 | .id_table = id_table, |
126 | .num_ports = 1, | 132 | .num_ports = 1, |
127 | .open = cp2101_open, | 133 | .open = cp210x_open, |
128 | .close = cp2101_close, | 134 | .close = cp210x_close, |
129 | .break_ctl = cp2101_break_ctl, | 135 | .break_ctl = cp210x_break_ctl, |
130 | .set_termios = cp2101_set_termios, | 136 | .set_termios = cp210x_set_termios, |
131 | .tiocmget = cp2101_tiocmget, | 137 | .tiocmget = cp210x_tiocmget, |
132 | .tiocmset = cp2101_tiocmset, | 138 | .tiocmset = cp210x_tiocmset, |
133 | .attach = cp2101_startup, | 139 | .attach = cp210x_startup, |
134 | .shutdown = cp2101_shutdown, | 140 | .disconnect = cp210x_disconnect, |
135 | }; | 141 | }; |
136 | 142 | ||
137 | /* Config request types */ | 143 | /* Config request types */ |
138 | #define REQTYPE_HOST_TO_DEVICE 0x41 | 144 | #define REQTYPE_HOST_TO_DEVICE 0x41 |
139 | #define REQTYPE_DEVICE_TO_HOST 0xc1 | 145 | #define REQTYPE_DEVICE_TO_HOST 0xc1 |
140 | 146 | ||
141 | /* Config SET requests. To GET, add 1 to the request number */ | 147 | /* Config request codes */ |
142 | #define CP2101_UART 0x00 /* Enable / Disable */ | 148 | #define CP210X_IFC_ENABLE 0x00 |
143 | #define CP2101_BAUDRATE 0x01 /* (BAUD_RATE_GEN_FREQ / baudrate) */ | 149 | #define CP210X_SET_BAUDDIV 0x01 |
144 | #define CP2101_BITS 0x03 /* 0x(0)(databits)(parity)(stopbits) */ | 150 | #define CP210X_GET_BAUDDIV 0x02 |
145 | #define CP2101_BREAK 0x05 /* On / Off */ | 151 | #define CP210X_SET_LINE_CTL 0x03 |
146 | #define CP2101_CONTROL 0x07 /* Flow control line states */ | 152 | #define CP210X_GET_LINE_CTL 0x04 |
147 | #define CP2101_MODEMCTL 0x13 /* Modem controls */ | 153 | #define CP210X_SET_BREAK 0x05 |
148 | #define CP2101_CONFIG_6 0x19 /* 6 bytes of config data ??? */ | 154 | #define CP210X_IMM_CHAR 0x06 |
149 | 155 | #define CP210X_SET_MHS 0x07 | |
150 | /* CP2101_UART */ | 156 | #define CP210X_GET_MDMSTS 0x08 |
157 | #define CP210X_SET_XON 0x09 | ||
158 | #define CP210X_SET_XOFF 0x0A | ||
159 | #define CP210X_SET_EVENTMASK 0x0B | ||
160 | #define CP210X_GET_EVENTMASK 0x0C | ||
161 | #define CP210X_SET_CHAR 0x0D | ||
162 | #define CP210X_GET_CHARS 0x0E | ||
163 | #define CP210X_GET_PROPS 0x0F | ||
164 | #define CP210X_GET_COMM_STATUS 0x10 | ||
165 | #define CP210X_RESET 0x11 | ||
166 | #define CP210X_PURGE 0x12 | ||
167 | #define CP210X_SET_FLOW 0x13 | ||
168 | #define CP210X_GET_FLOW 0x14 | ||
169 | #define CP210X_EMBED_EVENTS 0x15 | ||
170 | #define CP210X_GET_EVENTSTATE 0x16 | ||
171 | #define CP210X_SET_CHARS 0x19 | ||
172 | |||
173 | /* CP210X_IFC_ENABLE */ | ||
151 | #define UART_ENABLE 0x0001 | 174 | #define UART_ENABLE 0x0001 |
152 | #define UART_DISABLE 0x0000 | 175 | #define UART_DISABLE 0x0000 |
153 | 176 | ||
154 | /* CP2101_BAUDRATE */ | 177 | /* CP210X_(SET|GET)_BAUDDIV */ |
155 | #define BAUD_RATE_GEN_FREQ 0x384000 | 178 | #define BAUD_RATE_GEN_FREQ 0x384000 |
156 | 179 | ||
157 | /* CP2101_BITS */ | 180 | /* CP210X_(SET|GET)_LINE_CTL */ |
158 | #define BITS_DATA_MASK 0X0f00 | 181 | #define BITS_DATA_MASK 0X0f00 |
159 | #define BITS_DATA_5 0X0500 | 182 | #define BITS_DATA_5 0X0500 |
160 | #define BITS_DATA_6 0X0600 | 183 | #define BITS_DATA_6 0X0600 |
@@ -174,11 +197,11 @@ static struct usb_serial_driver cp2101_device = { | |||
174 | #define BITS_STOP_1_5 0x0001 | 197 | #define BITS_STOP_1_5 0x0001 |
175 | #define BITS_STOP_2 0x0002 | 198 | #define BITS_STOP_2 0x0002 |
176 | 199 | ||
177 | /* CP2101_BREAK */ | 200 | /* CP210X_SET_BREAK */ |
178 | #define BREAK_ON 0x0000 | 201 | #define BREAK_ON 0x0000 |
179 | #define BREAK_OFF 0x0001 | 202 | #define BREAK_OFF 0x0001 |
180 | 203 | ||
181 | /* CP2101_CONTROL */ | 204 | /* CP210X_(SET_MHS|GET_MDMSTS) */ |
182 | #define CONTROL_DTR 0x0001 | 205 | #define CONTROL_DTR 0x0001 |
183 | #define CONTROL_RTS 0x0002 | 206 | #define CONTROL_RTS 0x0002 |
184 | #define CONTROL_CTS 0x0010 | 207 | #define CONTROL_CTS 0x0010 |
@@ -189,13 +212,13 @@ static struct usb_serial_driver cp2101_device = { | |||
189 | #define CONTROL_WRITE_RTS 0x0200 | 212 | #define CONTROL_WRITE_RTS 0x0200 |
190 | 213 | ||
191 | /* | 214 | /* |
192 | * cp2101_get_config | 215 | * cp210x_get_config |
193 | * Reads from the CP2101 configuration registers | 216 | * Reads from the CP210x configuration registers |
194 | * 'size' is specified in bytes. | 217 | * 'size' is specified in bytes. |
195 | * 'data' is a pointer to a pre-allocated array of integers large | 218 | * 'data' is a pointer to a pre-allocated array of integers large |
196 | * enough to hold 'size' bytes (with 4 bytes to each integer) | 219 | * enough to hold 'size' bytes (with 4 bytes to each integer) |
197 | */ | 220 | */ |
198 | static int cp2101_get_config(struct usb_serial_port *port, u8 request, | 221 | static int cp210x_get_config(struct usb_serial_port *port, u8 request, |
199 | unsigned int *data, int size) | 222 | unsigned int *data, int size) |
200 | { | 223 | { |
201 | struct usb_serial *serial = port->serial; | 224 | struct usb_serial *serial = port->serial; |
@@ -211,9 +234,6 @@ static int cp2101_get_config(struct usb_serial_port *port, u8 request, | |||
211 | return -ENOMEM; | 234 | return -ENOMEM; |
212 | } | 235 | } |
213 | 236 | ||
214 | /* For get requests, the request number must be incremented */ | ||
215 | request++; | ||
216 | |||
217 | /* Issue the request, attempting to read 'size' bytes */ | 237 | /* Issue the request, attempting to read 'size' bytes */ |
218 | result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | 238 | result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), |
219 | request, REQTYPE_DEVICE_TO_HOST, 0x0000, | 239 | request, REQTYPE_DEVICE_TO_HOST, 0x0000, |
@@ -236,12 +256,12 @@ static int cp2101_get_config(struct usb_serial_port *port, u8 request, | |||
236 | } | 256 | } |
237 | 257 | ||
238 | /* | 258 | /* |
239 | * cp2101_set_config | 259 | * cp210x_set_config |
240 | * Writes to the CP2101 configuration registers | 260 | * Writes to the CP210x configuration registers |
241 | * Values less than 16 bits wide are sent directly | 261 | * Values less than 16 bits wide are sent directly |
242 | * 'size' is specified in bytes. | 262 | * 'size' is specified in bytes. |
243 | */ | 263 | */ |
244 | static int cp2101_set_config(struct usb_serial_port *port, u8 request, | 264 | static int cp210x_set_config(struct usb_serial_port *port, u8 request, |
245 | unsigned int *data, int size) | 265 | unsigned int *data, int size) |
246 | { | 266 | { |
247 | struct usb_serial *serial = port->serial; | 267 | struct usb_serial *serial = port->serial; |
@@ -292,21 +312,21 @@ static int cp2101_set_config(struct usb_serial_port *port, u8 request, | |||
292 | } | 312 | } |
293 | 313 | ||
294 | /* | 314 | /* |
295 | * cp2101_set_config_single | 315 | * cp210x_set_config_single |
296 | * Convenience function for calling cp2101_set_config on single data values | 316 | * Convenience function for calling cp210x_set_config on single data values |
297 | * without requiring an integer pointer | 317 | * without requiring an integer pointer |
298 | */ | 318 | */ |
299 | static inline int cp2101_set_config_single(struct usb_serial_port *port, | 319 | static inline int cp210x_set_config_single(struct usb_serial_port *port, |
300 | u8 request, unsigned int data) | 320 | u8 request, unsigned int data) |
301 | { | 321 | { |
302 | return cp2101_set_config(port, request, &data, 2); | 322 | return cp210x_set_config(port, request, &data, 2); |
303 | } | 323 | } |
304 | 324 | ||
305 | /* | 325 | /* |
306 | * cp2101_quantise_baudrate | 326 | * cp210x_quantise_baudrate |
307 | * Quantises the baud rate as per AN205 Table 1 | 327 | * Quantises the baud rate as per AN205 Table 1 |
308 | */ | 328 | */ |
309 | static unsigned int cp2101_quantise_baudrate(unsigned int baud) { | 329 | static unsigned int cp210x_quantise_baudrate(unsigned int baud) { |
310 | if (baud <= 56) baud = 0; | 330 | if (baud <= 56) baud = 0; |
311 | else if (baud <= 300) baud = 300; | 331 | else if (baud <= 300) baud = 300; |
312 | else if (baud <= 600) baud = 600; | 332 | else if (baud <= 600) baud = 600; |
@@ -343,7 +363,7 @@ static unsigned int cp2101_quantise_baudrate(unsigned int baud) { | |||
343 | return baud; | 363 | return baud; |
344 | } | 364 | } |
345 | 365 | ||
346 | static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, | 366 | static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port, |
347 | struct file *filp) | 367 | struct file *filp) |
348 | { | 368 | { |
349 | struct usb_serial *serial = port->serial; | 369 | struct usb_serial *serial = port->serial; |
@@ -351,7 +371,7 @@ static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
351 | 371 | ||
352 | dbg("%s - port %d", __func__, port->number); | 372 | dbg("%s - port %d", __func__, port->number); |
353 | 373 | ||
354 | if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) { | 374 | if (cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_ENABLE)) { |
355 | dev_err(&port->dev, "%s - Unable to enable UART\n", | 375 | dev_err(&port->dev, "%s - Unable to enable UART\n", |
356 | __func__); | 376 | __func__); |
357 | return -EPROTO; | 377 | return -EPROTO; |
@@ -373,17 +393,17 @@ static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
373 | } | 393 | } |
374 | 394 | ||
375 | /* Configure the termios structure */ | 395 | /* Configure the termios structure */ |
376 | cp2101_get_termios(tty, port); | 396 | cp210x_get_termios(tty, port); |
377 | 397 | ||
378 | /* Set the DTR and RTS pins low */ | 398 | /* Set the DTR and RTS pins low */ |
379 | cp2101_tiocmset_port(tty ? (struct usb_serial_port *) tty->driver_data | 399 | cp210x_tiocmset_port(tty ? (struct usb_serial_port *) tty->driver_data |
380 | : port, | 400 | : port, |
381 | NULL, TIOCM_DTR | TIOCM_RTS, 0); | 401 | NULL, TIOCM_DTR | TIOCM_RTS, 0); |
382 | 402 | ||
383 | return 0; | 403 | return 0; |
384 | } | 404 | } |
385 | 405 | ||
386 | static void cp2101_cleanup(struct usb_serial_port *port) | 406 | static void cp210x_cleanup(struct usb_serial_port *port) |
387 | { | 407 | { |
388 | struct usb_serial *serial = port->serial; | 408 | struct usb_serial *serial = port->serial; |
389 | 409 | ||
@@ -398,8 +418,7 @@ static void cp2101_cleanup(struct usb_serial_port *port) | |||
398 | } | 418 | } |
399 | } | 419 | } |
400 | 420 | ||
401 | static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port, | 421 | static void cp210x_close(struct usb_serial_port *port) |
402 | struct file *filp) | ||
403 | { | 422 | { |
404 | dbg("%s - port %d", __func__, port->number); | 423 | dbg("%s - port %d", __func__, port->number); |
405 | 424 | ||
@@ -410,23 +429,23 @@ static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port, | |||
410 | 429 | ||
411 | mutex_lock(&port->serial->disc_mutex); | 430 | mutex_lock(&port->serial->disc_mutex); |
412 | if (!port->serial->disconnected) | 431 | if (!port->serial->disconnected) |
413 | cp2101_set_config_single(port, CP2101_UART, UART_DISABLE); | 432 | cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_DISABLE); |
414 | mutex_unlock(&port->serial->disc_mutex); | 433 | mutex_unlock(&port->serial->disc_mutex); |
415 | } | 434 | } |
416 | 435 | ||
417 | /* | 436 | /* |
418 | * cp2101_get_termios | 437 | * cp210x_get_termios |
419 | * Reads the baud rate, data bits, parity, stop bits and flow control mode | 438 | * Reads the baud rate, data bits, parity, stop bits and flow control mode |
420 | * from the device, corrects any unsupported values, and configures the | 439 | * from the device, corrects any unsupported values, and configures the |
421 | * termios structure to reflect the state of the device | 440 | * termios structure to reflect the state of the device |
422 | */ | 441 | */ |
423 | static void cp2101_get_termios(struct tty_struct *tty, | 442 | static void cp210x_get_termios(struct tty_struct *tty, |
424 | struct usb_serial_port *port) | 443 | struct usb_serial_port *port) |
425 | { | 444 | { |
426 | unsigned int baud; | 445 | unsigned int baud; |
427 | 446 | ||
428 | if (tty) { | 447 | if (tty) { |
429 | cp2101_get_termios_port(tty->driver_data, | 448 | cp210x_get_termios_port(tty->driver_data, |
430 | &tty->termios->c_cflag, &baud); | 449 | &tty->termios->c_cflag, &baud); |
431 | tty_encode_baud_rate(tty, baud, baud); | 450 | tty_encode_baud_rate(tty, baud, baud); |
432 | } | 451 | } |
@@ -434,15 +453,15 @@ static void cp2101_get_termios(struct tty_struct *tty, | |||
434 | else { | 453 | else { |
435 | unsigned int cflag; | 454 | unsigned int cflag; |
436 | cflag = 0; | 455 | cflag = 0; |
437 | cp2101_get_termios_port(port, &cflag, &baud); | 456 | cp210x_get_termios_port(port, &cflag, &baud); |
438 | } | 457 | } |
439 | } | 458 | } |
440 | 459 | ||
441 | /* | 460 | /* |
442 | * cp2101_get_termios_port | 461 | * cp210x_get_termios_port |
443 | * This is the heart of cp2101_get_termios which always uses a &usb_serial_port. | 462 | * This is the heart of cp210x_get_termios which always uses a &usb_serial_port. |
444 | */ | 463 | */ |
445 | static void cp2101_get_termios_port(struct usb_serial_port *port, | 464 | static void cp210x_get_termios_port(struct usb_serial_port *port, |
446 | unsigned int *cflagp, unsigned int *baudp) | 465 | unsigned int *cflagp, unsigned int *baudp) |
447 | { | 466 | { |
448 | unsigned int cflag, modem_ctl[4]; | 467 | unsigned int cflag, modem_ctl[4]; |
@@ -451,17 +470,17 @@ static void cp2101_get_termios_port(struct usb_serial_port *port, | |||
451 | 470 | ||
452 | dbg("%s - port %d", __func__, port->number); | 471 | dbg("%s - port %d", __func__, port->number); |
453 | 472 | ||
454 | cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); | 473 | cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2); |
455 | /* Convert to baudrate */ | 474 | /* Convert to baudrate */ |
456 | if (baud) | 475 | if (baud) |
457 | baud = cp2101_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); | 476 | baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); |
458 | 477 | ||
459 | dbg("%s - baud rate = %d", __func__, baud); | 478 | dbg("%s - baud rate = %d", __func__, baud); |
460 | *baudp = baud; | 479 | *baudp = baud; |
461 | 480 | ||
462 | cflag = *cflagp; | 481 | cflag = *cflagp; |
463 | 482 | ||
464 | cp2101_get_config(port, CP2101_BITS, &bits, 2); | 483 | cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); |
465 | cflag &= ~CSIZE; | 484 | cflag &= ~CSIZE; |
466 | switch (bits & BITS_DATA_MASK) { | 485 | switch (bits & BITS_DATA_MASK) { |
467 | case BITS_DATA_5: | 486 | case BITS_DATA_5: |
@@ -486,14 +505,14 @@ static void cp2101_get_termios_port(struct usb_serial_port *port, | |||
486 | cflag |= CS8; | 505 | cflag |= CS8; |
487 | bits &= ~BITS_DATA_MASK; | 506 | bits &= ~BITS_DATA_MASK; |
488 | bits |= BITS_DATA_8; | 507 | bits |= BITS_DATA_8; |
489 | cp2101_set_config(port, CP2101_BITS, &bits, 2); | 508 | cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); |
490 | break; | 509 | break; |
491 | default: | 510 | default: |
492 | dbg("%s - Unknown number of data bits, using 8", __func__); | 511 | dbg("%s - Unknown number of data bits, using 8", __func__); |
493 | cflag |= CS8; | 512 | cflag |= CS8; |
494 | bits &= ~BITS_DATA_MASK; | 513 | bits &= ~BITS_DATA_MASK; |
495 | bits |= BITS_DATA_8; | 514 | bits |= BITS_DATA_8; |
496 | cp2101_set_config(port, CP2101_BITS, &bits, 2); | 515 | cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); |
497 | break; | 516 | break; |
498 | } | 517 | } |
499 | 518 | ||
@@ -516,20 +535,20 @@ static void cp2101_get_termios_port(struct usb_serial_port *port, | |||
516 | __func__); | 535 | __func__); |
517 | cflag &= ~PARENB; | 536 | cflag &= ~PARENB; |
518 | bits &= ~BITS_PARITY_MASK; | 537 | bits &= ~BITS_PARITY_MASK; |
519 | cp2101_set_config(port, CP2101_BITS, &bits, 2); | 538 | cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); |
520 | break; | 539 | break; |
521 | case BITS_PARITY_SPACE: | 540 | case BITS_PARITY_SPACE: |
522 | dbg("%s - parity = SPACE (not supported, disabling parity)", | 541 | dbg("%s - parity = SPACE (not supported, disabling parity)", |
523 | __func__); | 542 | __func__); |
524 | cflag &= ~PARENB; | 543 | cflag &= ~PARENB; |
525 | bits &= ~BITS_PARITY_MASK; | 544 | bits &= ~BITS_PARITY_MASK; |
526 | cp2101_set_config(port, CP2101_BITS, &bits, 2); | 545 | cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); |
527 | break; | 546 | break; |
528 | default: | 547 | default: |
529 | dbg("%s - Unknown parity mode, disabling parity", __func__); | 548 | dbg("%s - Unknown parity mode, disabling parity", __func__); |
530 | cflag &= ~PARENB; | 549 | cflag &= ~PARENB; |
531 | bits &= ~BITS_PARITY_MASK; | 550 | bits &= ~BITS_PARITY_MASK; |
532 | cp2101_set_config(port, CP2101_BITS, &bits, 2); | 551 | cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); |
533 | break; | 552 | break; |
534 | } | 553 | } |
535 | 554 | ||
@@ -542,7 +561,7 @@ static void cp2101_get_termios_port(struct usb_serial_port *port, | |||
542 | dbg("%s - stop bits = 1.5 (not supported, using 1 stop bit)", | 561 | dbg("%s - stop bits = 1.5 (not supported, using 1 stop bit)", |
543 | __func__); | 562 | __func__); |
544 | bits &= ~BITS_STOP_MASK; | 563 | bits &= ~BITS_STOP_MASK; |
545 | cp2101_set_config(port, CP2101_BITS, &bits, 2); | 564 | cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); |
546 | break; | 565 | break; |
547 | case BITS_STOP_2: | 566 | case BITS_STOP_2: |
548 | dbg("%s - stop bits = 2", __func__); | 567 | dbg("%s - stop bits = 2", __func__); |
@@ -552,11 +571,11 @@ static void cp2101_get_termios_port(struct usb_serial_port *port, | |||
552 | dbg("%s - Unknown number of stop bits, using 1 stop bit", | 571 | dbg("%s - Unknown number of stop bits, using 1 stop bit", |
553 | __func__); | 572 | __func__); |
554 | bits &= ~BITS_STOP_MASK; | 573 | bits &= ~BITS_STOP_MASK; |
555 | cp2101_set_config(port, CP2101_BITS, &bits, 2); | 574 | cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); |
556 | break; | 575 | break; |
557 | } | 576 | } |
558 | 577 | ||
559 | cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); | 578 | cp210x_get_config(port, CP210X_GET_FLOW, modem_ctl, 16); |
560 | if (modem_ctl[0] & 0x0008) { | 579 | if (modem_ctl[0] & 0x0008) { |
561 | dbg("%s - flow control = CRTSCTS", __func__); | 580 | dbg("%s - flow control = CRTSCTS", __func__); |
562 | cflag |= CRTSCTS; | 581 | cflag |= CRTSCTS; |
@@ -568,7 +587,7 @@ static void cp2101_get_termios_port(struct usb_serial_port *port, | |||
568 | *cflagp = cflag; | 587 | *cflagp = cflag; |
569 | } | 588 | } |
570 | 589 | ||
571 | static void cp2101_set_termios(struct tty_struct *tty, | 590 | static void cp210x_set_termios(struct tty_struct *tty, |
572 | struct usb_serial_port *port, struct ktermios *old_termios) | 591 | struct usb_serial_port *port, struct ktermios *old_termios) |
573 | { | 592 | { |
574 | unsigned int cflag, old_cflag; | 593 | unsigned int cflag, old_cflag; |
@@ -583,13 +602,13 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
583 | tty->termios->c_cflag &= ~CMSPAR; | 602 | tty->termios->c_cflag &= ~CMSPAR; |
584 | cflag = tty->termios->c_cflag; | 603 | cflag = tty->termios->c_cflag; |
585 | old_cflag = old_termios->c_cflag; | 604 | old_cflag = old_termios->c_cflag; |
586 | baud = cp2101_quantise_baudrate(tty_get_baud_rate(tty)); | 605 | baud = cp210x_quantise_baudrate(tty_get_baud_rate(tty)); |
587 | 606 | ||
588 | /* If the baud rate is to be updated*/ | 607 | /* If the baud rate is to be updated*/ |
589 | if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { | 608 | if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { |
590 | dbg("%s - Setting baud rate to %d baud", __func__, | 609 | dbg("%s - Setting baud rate to %d baud", __func__, |
591 | baud); | 610 | baud); |
592 | if (cp2101_set_config_single(port, CP2101_BAUDRATE, | 611 | if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV, |
593 | ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { | 612 | ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { |
594 | dbg("Baud rate requested not supported by device\n"); | 613 | dbg("Baud rate requested not supported by device\n"); |
595 | baud = tty_termios_baud_rate(old_termios); | 614 | baud = tty_termios_baud_rate(old_termios); |
@@ -600,7 +619,7 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
600 | 619 | ||
601 | /* If the number of data bits is to be updated */ | 620 | /* If the number of data bits is to be updated */ |
602 | if ((cflag & CSIZE) != (old_cflag & CSIZE)) { | 621 | if ((cflag & CSIZE) != (old_cflag & CSIZE)) { |
603 | cp2101_get_config(port, CP2101_BITS, &bits, 2); | 622 | cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); |
604 | bits &= ~BITS_DATA_MASK; | 623 | bits &= ~BITS_DATA_MASK; |
605 | switch (cflag & CSIZE) { | 624 | switch (cflag & CSIZE) { |
606 | case CS5: | 625 | case CS5: |
@@ -624,19 +643,19 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
624 | dbg("%s - data bits = 9", __func__); | 643 | dbg("%s - data bits = 9", __func__); |
625 | break;*/ | 644 | break;*/ |
626 | default: | 645 | default: |
627 | dbg("cp2101 driver does not " | 646 | dbg("cp210x driver does not " |
628 | "support the number of bits requested," | 647 | "support the number of bits requested," |
629 | " using 8 bit mode\n"); | 648 | " using 8 bit mode\n"); |
630 | bits |= BITS_DATA_8; | 649 | bits |= BITS_DATA_8; |
631 | break; | 650 | break; |
632 | } | 651 | } |
633 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) | 652 | if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) |
634 | dbg("Number of data bits requested " | 653 | dbg("Number of data bits requested " |
635 | "not supported by device\n"); | 654 | "not supported by device\n"); |
636 | } | 655 | } |
637 | 656 | ||
638 | if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { | 657 | if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { |
639 | cp2101_get_config(port, CP2101_BITS, &bits, 2); | 658 | cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); |
640 | bits &= ~BITS_PARITY_MASK; | 659 | bits &= ~BITS_PARITY_MASK; |
641 | if (cflag & PARENB) { | 660 | if (cflag & PARENB) { |
642 | if (cflag & PARODD) { | 661 | if (cflag & PARODD) { |
@@ -647,13 +666,13 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
647 | dbg("%s - parity = EVEN", __func__); | 666 | dbg("%s - parity = EVEN", __func__); |
648 | } | 667 | } |
649 | } | 668 | } |
650 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) | 669 | if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) |
651 | dbg("Parity mode not supported " | 670 | dbg("Parity mode not supported " |
652 | "by device\n"); | 671 | "by device\n"); |
653 | } | 672 | } |
654 | 673 | ||
655 | if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { | 674 | if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { |
656 | cp2101_get_config(port, CP2101_BITS, &bits, 2); | 675 | cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); |
657 | bits &= ~BITS_STOP_MASK; | 676 | bits &= ~BITS_STOP_MASK; |
658 | if (cflag & CSTOPB) { | 677 | if (cflag & CSTOPB) { |
659 | bits |= BITS_STOP_2; | 678 | bits |= BITS_STOP_2; |
@@ -662,13 +681,13 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
662 | bits |= BITS_STOP_1; | 681 | bits |= BITS_STOP_1; |
663 | dbg("%s - stop bits = 1", __func__); | 682 | dbg("%s - stop bits = 1", __func__); |
664 | } | 683 | } |
665 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) | 684 | if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) |
666 | dbg("Number of stop bits requested " | 685 | dbg("Number of stop bits requested " |
667 | "not supported by device\n"); | 686 | "not supported by device\n"); |
668 | } | 687 | } |
669 | 688 | ||
670 | if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { | 689 | if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { |
671 | cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); | 690 | cp210x_get_config(port, CP210X_GET_FLOW, modem_ctl, 16); |
672 | dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", | 691 | dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", |
673 | __func__, modem_ctl[0], modem_ctl[1], | 692 | __func__, modem_ctl[0], modem_ctl[1], |
674 | modem_ctl[2], modem_ctl[3]); | 693 | modem_ctl[2], modem_ctl[3]); |
@@ -688,19 +707,19 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
688 | dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", | 707 | dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", |
689 | __func__, modem_ctl[0], modem_ctl[1], | 708 | __func__, modem_ctl[0], modem_ctl[1], |
690 | modem_ctl[2], modem_ctl[3]); | 709 | modem_ctl[2], modem_ctl[3]); |
691 | cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16); | 710 | cp210x_set_config(port, CP210X_SET_FLOW, modem_ctl, 16); |
692 | } | 711 | } |
693 | 712 | ||
694 | } | 713 | } |
695 | 714 | ||
696 | static int cp2101_tiocmset (struct tty_struct *tty, struct file *file, | 715 | static int cp210x_tiocmset (struct tty_struct *tty, struct file *file, |
697 | unsigned int set, unsigned int clear) | 716 | unsigned int set, unsigned int clear) |
698 | { | 717 | { |
699 | struct usb_serial_port *port = tty->driver_data; | 718 | struct usb_serial_port *port = tty->driver_data; |
700 | return cp2101_tiocmset_port(port, file, set, clear); | 719 | return cp210x_tiocmset_port(port, file, set, clear); |
701 | } | 720 | } |
702 | 721 | ||
703 | static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *file, | 722 | static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *file, |
704 | unsigned int set, unsigned int clear) | 723 | unsigned int set, unsigned int clear) |
705 | { | 724 | { |
706 | unsigned int control = 0; | 725 | unsigned int control = 0; |
@@ -726,10 +745,10 @@ static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *file, | |||
726 | 745 | ||
727 | dbg("%s - control = 0x%.4x", __func__, control); | 746 | dbg("%s - control = 0x%.4x", __func__, control); |
728 | 747 | ||
729 | return cp2101_set_config(port, CP2101_CONTROL, &control, 2); | 748 | return cp210x_set_config(port, CP210X_SET_MHS, &control, 2); |
730 | } | 749 | } |
731 | 750 | ||
732 | static int cp2101_tiocmget (struct tty_struct *tty, struct file *file) | 751 | static int cp210x_tiocmget (struct tty_struct *tty, struct file *file) |
733 | { | 752 | { |
734 | struct usb_serial_port *port = tty->driver_data; | 753 | struct usb_serial_port *port = tty->driver_data; |
735 | unsigned int control; | 754 | unsigned int control; |
@@ -737,7 +756,7 @@ static int cp2101_tiocmget (struct tty_struct *tty, struct file *file) | |||
737 | 756 | ||
738 | dbg("%s - port %d", __func__, port->number); | 757 | dbg("%s - port %d", __func__, port->number); |
739 | 758 | ||
740 | cp2101_get_config(port, CP2101_CONTROL, &control, 1); | 759 | cp210x_get_config(port, CP210X_GET_MDMSTS, &control, 1); |
741 | 760 | ||
742 | result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) | 761 | result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) |
743 | |((control & CONTROL_RTS) ? TIOCM_RTS : 0) | 762 | |((control & CONTROL_RTS) ? TIOCM_RTS : 0) |
@@ -751,7 +770,7 @@ static int cp2101_tiocmget (struct tty_struct *tty, struct file *file) | |||
751 | return result; | 770 | return result; |
752 | } | 771 | } |
753 | 772 | ||
754 | static void cp2101_break_ctl (struct tty_struct *tty, int break_state) | 773 | static void cp210x_break_ctl (struct tty_struct *tty, int break_state) |
755 | { | 774 | { |
756 | struct usb_serial_port *port = tty->driver_data; | 775 | struct usb_serial_port *port = tty->driver_data; |
757 | unsigned int state; | 776 | unsigned int state; |
@@ -763,17 +782,17 @@ static void cp2101_break_ctl (struct tty_struct *tty, int break_state) | |||
763 | state = BREAK_ON; | 782 | state = BREAK_ON; |
764 | dbg("%s - turning break %s", __func__, | 783 | dbg("%s - turning break %s", __func__, |
765 | state == BREAK_OFF ? "off" : "on"); | 784 | state == BREAK_OFF ? "off" : "on"); |
766 | cp2101_set_config(port, CP2101_BREAK, &state, 2); | 785 | cp210x_set_config(port, CP210X_SET_BREAK, &state, 2); |
767 | } | 786 | } |
768 | 787 | ||
769 | static int cp2101_startup(struct usb_serial *serial) | 788 | static int cp210x_startup(struct usb_serial *serial) |
770 | { | 789 | { |
771 | /* CP2101 buffers behave strangely unless device is reset */ | 790 | /* cp210x buffers behave strangely unless device is reset */ |
772 | usb_reset_device(serial->dev); | 791 | usb_reset_device(serial->dev); |
773 | return 0; | 792 | return 0; |
774 | } | 793 | } |
775 | 794 | ||
776 | static void cp2101_shutdown(struct usb_serial *serial) | 795 | static void cp210x_disconnect(struct usb_serial *serial) |
777 | { | 796 | { |
778 | int i; | 797 | int i; |
779 | 798 | ||
@@ -781,21 +800,21 @@ static void cp2101_shutdown(struct usb_serial *serial) | |||
781 | 800 | ||
782 | /* Stop reads and writes on all ports */ | 801 | /* Stop reads and writes on all ports */ |
783 | for (i = 0; i < serial->num_ports; ++i) | 802 | for (i = 0; i < serial->num_ports; ++i) |
784 | cp2101_cleanup(serial->port[i]); | 803 | cp210x_cleanup(serial->port[i]); |
785 | } | 804 | } |
786 | 805 | ||
787 | static int __init cp2101_init(void) | 806 | static int __init cp210x_init(void) |
788 | { | 807 | { |
789 | int retval; | 808 | int retval; |
790 | 809 | ||
791 | retval = usb_serial_register(&cp2101_device); | 810 | retval = usb_serial_register(&cp210x_device); |
792 | if (retval) | 811 | if (retval) |
793 | return retval; /* Failed to register */ | 812 | return retval; /* Failed to register */ |
794 | 813 | ||
795 | retval = usb_register(&cp2101_driver); | 814 | retval = usb_register(&cp210x_driver); |
796 | if (retval) { | 815 | if (retval) { |
797 | /* Failed to register */ | 816 | /* Failed to register */ |
798 | usb_serial_deregister(&cp2101_device); | 817 | usb_serial_deregister(&cp210x_device); |
799 | return retval; | 818 | return retval; |
800 | } | 819 | } |
801 | 820 | ||
@@ -805,14 +824,14 @@ static int __init cp2101_init(void) | |||
805 | return 0; | 824 | return 0; |
806 | } | 825 | } |
807 | 826 | ||
808 | static void __exit cp2101_exit(void) | 827 | static void __exit cp210x_exit(void) |
809 | { | 828 | { |
810 | usb_deregister(&cp2101_driver); | 829 | usb_deregister(&cp210x_driver); |
811 | usb_serial_deregister(&cp2101_device); | 830 | usb_serial_deregister(&cp210x_device); |
812 | } | 831 | } |
813 | 832 | ||
814 | module_init(cp2101_init); | 833 | module_init(cp210x_init); |
815 | module_exit(cp2101_exit); | 834 | module_exit(cp210x_exit); |
816 | 835 | ||
817 | MODULE_DESCRIPTION(DRIVER_DESC); | 836 | MODULE_DESCRIPTION(DRIVER_DESC); |
818 | MODULE_VERSION(DRIVER_VERSION); | 837 | MODULE_VERSION(DRIVER_VERSION); |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index dd501bb63ed6..336523fd7366 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -58,11 +58,11 @@ static int debug; | |||
58 | 58 | ||
59 | /* Function prototypes */ | 59 | /* Function prototypes */ |
60 | static int cyberjack_startup(struct usb_serial *serial); | 60 | static int cyberjack_startup(struct usb_serial *serial); |
61 | static void cyberjack_shutdown(struct usb_serial *serial); | 61 | static void cyberjack_disconnect(struct usb_serial *serial); |
62 | static void cyberjack_release(struct usb_serial *serial); | ||
62 | static int cyberjack_open(struct tty_struct *tty, | 63 | static int cyberjack_open(struct tty_struct *tty, |
63 | struct usb_serial_port *port, struct file *filp); | 64 | struct usb_serial_port *port, struct file *filp); |
64 | static void cyberjack_close(struct tty_struct *tty, | 65 | static void cyberjack_close(struct usb_serial_port *port); |
65 | struct usb_serial_port *port, struct file *filp); | ||
66 | static int cyberjack_write(struct tty_struct *tty, | 66 | static int cyberjack_write(struct tty_struct *tty, |
67 | struct usb_serial_port *port, const unsigned char *buf, int count); | 67 | struct usb_serial_port *port, const unsigned char *buf, int count); |
68 | static int cyberjack_write_room(struct tty_struct *tty); | 68 | static int cyberjack_write_room(struct tty_struct *tty); |
@@ -95,7 +95,8 @@ static struct usb_serial_driver cyberjack_device = { | |||
95 | .id_table = id_table, | 95 | .id_table = id_table, |
96 | .num_ports = 1, | 96 | .num_ports = 1, |
97 | .attach = cyberjack_startup, | 97 | .attach = cyberjack_startup, |
98 | .shutdown = cyberjack_shutdown, | 98 | .disconnect = cyberjack_disconnect, |
99 | .release = cyberjack_release, | ||
99 | .open = cyberjack_open, | 100 | .open = cyberjack_open, |
100 | .close = cyberjack_close, | 101 | .close = cyberjack_close, |
101 | .write = cyberjack_write, | 102 | .write = cyberjack_write, |
@@ -149,17 +150,25 @@ static int cyberjack_startup(struct usb_serial *serial) | |||
149 | return 0; | 150 | return 0; |
150 | } | 151 | } |
151 | 152 | ||
152 | static void cyberjack_shutdown(struct usb_serial *serial) | 153 | static void cyberjack_disconnect(struct usb_serial *serial) |
153 | { | 154 | { |
154 | int i; | 155 | int i; |
155 | 156 | ||
156 | dbg("%s", __func__); | 157 | dbg("%s", __func__); |
157 | 158 | ||
158 | for (i = 0; i < serial->num_ports; ++i) { | 159 | for (i = 0; i < serial->num_ports; ++i) |
159 | usb_kill_urb(serial->port[i]->interrupt_in_urb); | 160 | usb_kill_urb(serial->port[i]->interrupt_in_urb); |
161 | } | ||
162 | |||
163 | static void cyberjack_release(struct usb_serial *serial) | ||
164 | { | ||
165 | int i; | ||
166 | |||
167 | dbg("%s", __func__); | ||
168 | |||
169 | for (i = 0; i < serial->num_ports; ++i) { | ||
160 | /* My special items, the standard routines free my urbs */ | 170 | /* My special items, the standard routines free my urbs */ |
161 | kfree(usb_get_serial_port_data(serial->port[i])); | 171 | kfree(usb_get_serial_port_data(serial->port[i])); |
162 | usb_set_serial_port_data(serial->port[i], NULL); | ||
163 | } | 172 | } |
164 | } | 173 | } |
165 | 174 | ||
@@ -185,8 +194,7 @@ static int cyberjack_open(struct tty_struct *tty, | |||
185 | return result; | 194 | return result; |
186 | } | 195 | } |
187 | 196 | ||
188 | static void cyberjack_close(struct tty_struct *tty, | 197 | static void cyberjack_close(struct usb_serial_port *port) |
189 | struct usb_serial_port *port, struct file *filp) | ||
190 | { | 198 | { |
191 | dbg("%s - port %d", __func__, port->number); | 199 | dbg("%s - port %d", __func__, port->number); |
192 | 200 | ||
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index e568710b263f..9734085fd2fe 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -171,11 +171,11 @@ struct cypress_buf { | |||
171 | static int cypress_earthmate_startup(struct usb_serial *serial); | 171 | static int cypress_earthmate_startup(struct usb_serial *serial); |
172 | static int cypress_hidcom_startup(struct usb_serial *serial); | 172 | static int cypress_hidcom_startup(struct usb_serial *serial); |
173 | static int cypress_ca42v2_startup(struct usb_serial *serial); | 173 | static int cypress_ca42v2_startup(struct usb_serial *serial); |
174 | static void cypress_shutdown(struct usb_serial *serial); | 174 | static void cypress_release(struct usb_serial *serial); |
175 | static int cypress_open(struct tty_struct *tty, | 175 | static int cypress_open(struct tty_struct *tty, |
176 | struct usb_serial_port *port, struct file *filp); | 176 | struct usb_serial_port *port, struct file *filp); |
177 | static void cypress_close(struct tty_struct *tty, | 177 | static void cypress_close(struct usb_serial_port *port); |
178 | struct usb_serial_port *port, struct file *filp); | 178 | static void cypress_dtr_rts(struct usb_serial_port *port, int on); |
179 | static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, | 179 | static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, |
180 | const unsigned char *buf, int count); | 180 | const unsigned char *buf, int count); |
181 | static void cypress_send(struct usb_serial_port *port); | 181 | static void cypress_send(struct usb_serial_port *port); |
@@ -215,9 +215,10 @@ static struct usb_serial_driver cypress_earthmate_device = { | |||
215 | .id_table = id_table_earthmate, | 215 | .id_table = id_table_earthmate, |
216 | .num_ports = 1, | 216 | .num_ports = 1, |
217 | .attach = cypress_earthmate_startup, | 217 | .attach = cypress_earthmate_startup, |
218 | .shutdown = cypress_shutdown, | 218 | .release = cypress_release, |
219 | .open = cypress_open, | 219 | .open = cypress_open, |
220 | .close = cypress_close, | 220 | .close = cypress_close, |
221 | .dtr_rts = cypress_dtr_rts, | ||
221 | .write = cypress_write, | 222 | .write = cypress_write, |
222 | .write_room = cypress_write_room, | 223 | .write_room = cypress_write_room, |
223 | .ioctl = cypress_ioctl, | 224 | .ioctl = cypress_ioctl, |
@@ -241,9 +242,10 @@ static struct usb_serial_driver cypress_hidcom_device = { | |||
241 | .id_table = id_table_cyphidcomrs232, | 242 | .id_table = id_table_cyphidcomrs232, |
242 | .num_ports = 1, | 243 | .num_ports = 1, |
243 | .attach = cypress_hidcom_startup, | 244 | .attach = cypress_hidcom_startup, |
244 | .shutdown = cypress_shutdown, | 245 | .release = cypress_release, |
245 | .open = cypress_open, | 246 | .open = cypress_open, |
246 | .close = cypress_close, | 247 | .close = cypress_close, |
248 | .dtr_rts = cypress_dtr_rts, | ||
247 | .write = cypress_write, | 249 | .write = cypress_write, |
248 | .write_room = cypress_write_room, | 250 | .write_room = cypress_write_room, |
249 | .ioctl = cypress_ioctl, | 251 | .ioctl = cypress_ioctl, |
@@ -267,9 +269,10 @@ static struct usb_serial_driver cypress_ca42v2_device = { | |||
267 | .id_table = id_table_nokiaca42v2, | 269 | .id_table = id_table_nokiaca42v2, |
268 | .num_ports = 1, | 270 | .num_ports = 1, |
269 | .attach = cypress_ca42v2_startup, | 271 | .attach = cypress_ca42v2_startup, |
270 | .shutdown = cypress_shutdown, | 272 | .release = cypress_release, |
271 | .open = cypress_open, | 273 | .open = cypress_open, |
272 | .close = cypress_close, | 274 | .close = cypress_close, |
275 | .dtr_rts = cypress_dtr_rts, | ||
273 | .write = cypress_write, | 276 | .write = cypress_write, |
274 | .write_room = cypress_write_room, | 277 | .write_room = cypress_write_room, |
275 | .ioctl = cypress_ioctl, | 278 | .ioctl = cypress_ioctl, |
@@ -613,7 +616,7 @@ static int cypress_ca42v2_startup(struct usb_serial *serial) | |||
613 | } /* cypress_ca42v2_startup */ | 616 | } /* cypress_ca42v2_startup */ |
614 | 617 | ||
615 | 618 | ||
616 | static void cypress_shutdown(struct usb_serial *serial) | 619 | static void cypress_release(struct usb_serial *serial) |
617 | { | 620 | { |
618 | struct cypress_private *priv; | 621 | struct cypress_private *priv; |
619 | 622 | ||
@@ -626,7 +629,6 @@ static void cypress_shutdown(struct usb_serial *serial) | |||
626 | if (priv) { | 629 | if (priv) { |
627 | cypress_buf_free(priv->buf); | 630 | cypress_buf_free(priv->buf); |
628 | kfree(priv); | 631 | kfree(priv); |
629 | usb_set_serial_port_data(serial->port[0], NULL); | ||
630 | } | 632 | } |
631 | } | 633 | } |
632 | 634 | ||
@@ -656,11 +658,7 @@ static int cypress_open(struct tty_struct *tty, | |||
656 | priv->rx_flags = 0; | 658 | priv->rx_flags = 0; |
657 | spin_unlock_irqrestore(&priv->lock, flags); | 659 | spin_unlock_irqrestore(&priv->lock, flags); |
658 | 660 | ||
659 | /* raise both lines and set termios */ | 661 | /* Set termios */ |
660 | spin_lock_irqsave(&priv->lock, flags); | ||
661 | priv->line_control = CONTROL_DTR | CONTROL_RTS; | ||
662 | priv->cmd_ctrl = 1; | ||
663 | spin_unlock_irqrestore(&priv->lock, flags); | ||
664 | result = cypress_write(tty, port, NULL, 0); | 662 | result = cypress_write(tty, port, NULL, 0); |
665 | 663 | ||
666 | if (result) { | 664 | if (result) { |
@@ -694,76 +692,42 @@ static int cypress_open(struct tty_struct *tty, | |||
694 | __func__, result); | 692 | __func__, result); |
695 | cypress_set_dead(port); | 693 | cypress_set_dead(port); |
696 | } | 694 | } |
697 | 695 | port->port.drain_delay = 256; | |
698 | return result; | 696 | return result; |
699 | } /* cypress_open */ | 697 | } /* cypress_open */ |
700 | 698 | ||
699 | static void cypress_dtr_rts(struct usb_serial_port *port, int on) | ||
700 | { | ||
701 | struct cypress_private *priv = usb_get_serial_port_data(port); | ||
702 | /* drop dtr and rts */ | ||
703 | priv = usb_get_serial_port_data(port); | ||
704 | spin_lock_irq(&priv->lock); | ||
705 | if (on == 0) | ||
706 | priv->line_control = 0; | ||
707 | else | ||
708 | priv->line_control = CONTROL_DTR | CONTROL_RTS; | ||
709 | priv->cmd_ctrl = 1; | ||
710 | spin_unlock_irq(&priv->lock); | ||
711 | cypress_write(NULL, port, NULL, 0); | ||
712 | } | ||
701 | 713 | ||
702 | static void cypress_close(struct tty_struct *tty, | 714 | static void cypress_close(struct usb_serial_port *port) |
703 | struct usb_serial_port *port, struct file *filp) | ||
704 | { | 715 | { |
705 | struct cypress_private *priv = usb_get_serial_port_data(port); | 716 | struct cypress_private *priv = usb_get_serial_port_data(port); |
706 | unsigned int c_cflag; | ||
707 | int bps; | ||
708 | long timeout; | ||
709 | wait_queue_t wait; | ||
710 | 717 | ||
711 | dbg("%s - port %d", __func__, port->number); | 718 | dbg("%s - port %d", __func__, port->number); |
712 | 719 | ||
713 | /* wait for data to drain from buffer */ | ||
714 | spin_lock_irq(&priv->lock); | ||
715 | timeout = CYPRESS_CLOSING_WAIT; | ||
716 | init_waitqueue_entry(&wait, current); | ||
717 | add_wait_queue(&tty->write_wait, &wait); | ||
718 | for (;;) { | ||
719 | set_current_state(TASK_INTERRUPTIBLE); | ||
720 | if (cypress_buf_data_avail(priv->buf) == 0 | ||
721 | || timeout == 0 || signal_pending(current) | ||
722 | /* without mutex, allowed due to harmless failure mode */ | ||
723 | || port->serial->disconnected) | ||
724 | break; | ||
725 | spin_unlock_irq(&priv->lock); | ||
726 | timeout = schedule_timeout(timeout); | ||
727 | spin_lock_irq(&priv->lock); | ||
728 | } | ||
729 | set_current_state(TASK_RUNNING); | ||
730 | remove_wait_queue(&tty->write_wait, &wait); | ||
731 | /* clear out any remaining data in the buffer */ | ||
732 | cypress_buf_clear(priv->buf); | ||
733 | spin_unlock_irq(&priv->lock); | ||
734 | |||
735 | /* writing is potentially harmful, lock must be taken */ | 720 | /* writing is potentially harmful, lock must be taken */ |
736 | mutex_lock(&port->serial->disc_mutex); | 721 | mutex_lock(&port->serial->disc_mutex); |
737 | if (port->serial->disconnected) { | 722 | if (port->serial->disconnected) { |
738 | mutex_unlock(&port->serial->disc_mutex); | 723 | mutex_unlock(&port->serial->disc_mutex); |
739 | return; | 724 | return; |
740 | } | 725 | } |
741 | /* wait for characters to drain from device */ | 726 | cypress_buf_clear(priv->buf); |
742 | if (tty) { | ||
743 | bps = tty_get_baud_rate(tty); | ||
744 | if (bps > 1200) | ||
745 | timeout = max((HZ * 2560) / bps, HZ / 10); | ||
746 | else | ||
747 | timeout = 2 * HZ; | ||
748 | schedule_timeout_interruptible(timeout); | ||
749 | } | ||
750 | |||
751 | dbg("%s - stopping urbs", __func__); | 727 | dbg("%s - stopping urbs", __func__); |
752 | usb_kill_urb(port->interrupt_in_urb); | 728 | usb_kill_urb(port->interrupt_in_urb); |
753 | usb_kill_urb(port->interrupt_out_urb); | 729 | usb_kill_urb(port->interrupt_out_urb); |
754 | 730 | ||
755 | if (tty) { | ||
756 | c_cflag = tty->termios->c_cflag; | ||
757 | if (c_cflag & HUPCL) { | ||
758 | /* drop dtr and rts */ | ||
759 | priv = usb_get_serial_port_data(port); | ||
760 | spin_lock_irq(&priv->lock); | ||
761 | priv->line_control = 0; | ||
762 | priv->cmd_ctrl = 1; | ||
763 | spin_unlock_irq(&priv->lock); | ||
764 | cypress_write(tty, port, NULL, 0); | ||
765 | } | ||
766 | } | ||
767 | 731 | ||
768 | if (stats) | 732 | if (stats) |
769 | dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", | 733 | dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 38ba4ea8b6bf..f4808091c47c 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -422,7 +422,6 @@ struct digi_port { | |||
422 | int dp_throttled; | 422 | int dp_throttled; |
423 | int dp_throttle_restart; | 423 | int dp_throttle_restart; |
424 | wait_queue_head_t dp_flush_wait; | 424 | wait_queue_head_t dp_flush_wait; |
425 | int dp_in_close; /* close in progress */ | ||
426 | wait_queue_head_t dp_close_wait; /* wait queue for close */ | 425 | wait_queue_head_t dp_close_wait; /* wait queue for close */ |
427 | struct work_struct dp_wakeup_work; | 426 | struct work_struct dp_wakeup_work; |
428 | struct usb_serial_port *dp_port; | 427 | struct usb_serial_port *dp_port; |
@@ -456,11 +455,13 @@ static int digi_write_room(struct tty_struct *tty); | |||
456 | static int digi_chars_in_buffer(struct tty_struct *tty); | 455 | static int digi_chars_in_buffer(struct tty_struct *tty); |
457 | static int digi_open(struct tty_struct *tty, struct usb_serial_port *port, | 456 | static int digi_open(struct tty_struct *tty, struct usb_serial_port *port, |
458 | struct file *filp); | 457 | struct file *filp); |
459 | static void digi_close(struct tty_struct *tty, struct usb_serial_port *port, | 458 | static void digi_close(struct usb_serial_port *port); |
460 | struct file *filp); | 459 | static int digi_carrier_raised(struct usb_serial_port *port); |
460 | static void digi_dtr_rts(struct usb_serial_port *port, int on); | ||
461 | static int digi_startup_device(struct usb_serial *serial); | 461 | static int digi_startup_device(struct usb_serial *serial); |
462 | static int digi_startup(struct usb_serial *serial); | 462 | static int digi_startup(struct usb_serial *serial); |
463 | static void digi_shutdown(struct usb_serial *serial); | 463 | static void digi_disconnect(struct usb_serial *serial); |
464 | static void digi_release(struct usb_serial *serial); | ||
464 | static void digi_read_bulk_callback(struct urb *urb); | 465 | static void digi_read_bulk_callback(struct urb *urb); |
465 | static int digi_read_inb_callback(struct urb *urb); | 466 | static int digi_read_inb_callback(struct urb *urb); |
466 | static int digi_read_oob_callback(struct urb *urb); | 467 | static int digi_read_oob_callback(struct urb *urb); |
@@ -510,6 +511,8 @@ static struct usb_serial_driver digi_acceleport_2_device = { | |||
510 | .num_ports = 3, | 511 | .num_ports = 3, |
511 | .open = digi_open, | 512 | .open = digi_open, |
512 | .close = digi_close, | 513 | .close = digi_close, |
514 | .dtr_rts = digi_dtr_rts, | ||
515 | .carrier_raised = digi_carrier_raised, | ||
513 | .write = digi_write, | 516 | .write = digi_write, |
514 | .write_room = digi_write_room, | 517 | .write_room = digi_write_room, |
515 | .write_bulk_callback = digi_write_bulk_callback, | 518 | .write_bulk_callback = digi_write_bulk_callback, |
@@ -522,7 +525,8 @@ static struct usb_serial_driver digi_acceleport_2_device = { | |||
522 | .tiocmget = digi_tiocmget, | 525 | .tiocmget = digi_tiocmget, |
523 | .tiocmset = digi_tiocmset, | 526 | .tiocmset = digi_tiocmset, |
524 | .attach = digi_startup, | 527 | .attach = digi_startup, |
525 | .shutdown = digi_shutdown, | 528 | .disconnect = digi_disconnect, |
529 | .release = digi_release, | ||
526 | }; | 530 | }; |
527 | 531 | ||
528 | static struct usb_serial_driver digi_acceleport_4_device = { | 532 | static struct usb_serial_driver digi_acceleport_4_device = { |
@@ -548,7 +552,8 @@ static struct usb_serial_driver digi_acceleport_4_device = { | |||
548 | .tiocmget = digi_tiocmget, | 552 | .tiocmget = digi_tiocmget, |
549 | .tiocmset = digi_tiocmset, | 553 | .tiocmset = digi_tiocmset, |
550 | .attach = digi_startup, | 554 | .attach = digi_startup, |
551 | .shutdown = digi_shutdown, | 555 | .disconnect = digi_disconnect, |
556 | .release = digi_release, | ||
552 | }; | 557 | }; |
553 | 558 | ||
554 | 559 | ||
@@ -1328,6 +1333,19 @@ static int digi_chars_in_buffer(struct tty_struct *tty) | |||
1328 | 1333 | ||
1329 | } | 1334 | } |
1330 | 1335 | ||
1336 | static void digi_dtr_rts(struct usb_serial_port *port, int on) | ||
1337 | { | ||
1338 | /* Adjust DTR and RTS */ | ||
1339 | digi_set_modem_signals(port, on * (TIOCM_DTR|TIOCM_RTS), 1); | ||
1340 | } | ||
1341 | |||
1342 | static int digi_carrier_raised(struct usb_serial_port *port) | ||
1343 | { | ||
1344 | struct digi_port *priv = usb_get_serial_port_data(port); | ||
1345 | if (priv->dp_modem_signals & TIOCM_CD) | ||
1346 | return 1; | ||
1347 | return 0; | ||
1348 | } | ||
1331 | 1349 | ||
1332 | static int digi_open(struct tty_struct *tty, struct usb_serial_port *port, | 1350 | static int digi_open(struct tty_struct *tty, struct usb_serial_port *port, |
1333 | struct file *filp) | 1351 | struct file *filp) |
@@ -1336,7 +1354,6 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
1336 | unsigned char buf[32]; | 1354 | unsigned char buf[32]; |
1337 | struct digi_port *priv = usb_get_serial_port_data(port); | 1355 | struct digi_port *priv = usb_get_serial_port_data(port); |
1338 | struct ktermios not_termios; | 1356 | struct ktermios not_termios; |
1339 | unsigned long flags = 0; | ||
1340 | 1357 | ||
1341 | dbg("digi_open: TOP: port=%d, open_count=%d", | 1358 | dbg("digi_open: TOP: port=%d, open_count=%d", |
1342 | priv->dp_port_num, port->port.count); | 1359 | priv->dp_port_num, port->port.count); |
@@ -1345,26 +1362,6 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
1345 | if (digi_startup_device(port->serial) != 0) | 1362 | if (digi_startup_device(port->serial) != 0) |
1346 | return -ENXIO; | 1363 | return -ENXIO; |
1347 | 1364 | ||
1348 | spin_lock_irqsave(&priv->dp_port_lock, flags); | ||
1349 | |||
1350 | /* don't wait on a close in progress for non-blocking opens */ | ||
1351 | if (priv->dp_in_close && (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) { | ||
1352 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); | ||
1353 | return -EAGAIN; | ||
1354 | } | ||
1355 | |||
1356 | /* wait for a close in progress to finish */ | ||
1357 | while (priv->dp_in_close) { | ||
1358 | cond_wait_interruptible_timeout_irqrestore( | ||
1359 | &priv->dp_close_wait, DIGI_RETRY_TIMEOUT, | ||
1360 | &priv->dp_port_lock, flags); | ||
1361 | if (signal_pending(current)) | ||
1362 | return -EINTR; | ||
1363 | spin_lock_irqsave(&priv->dp_port_lock, flags); | ||
1364 | } | ||
1365 | |||
1366 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); | ||
1367 | |||
1368 | /* read modem signals automatically whenever they change */ | 1365 | /* read modem signals automatically whenever they change */ |
1369 | buf[0] = DIGI_CMD_READ_INPUT_SIGNALS; | 1366 | buf[0] = DIGI_CMD_READ_INPUT_SIGNALS; |
1370 | buf[1] = priv->dp_port_num; | 1367 | buf[1] = priv->dp_port_num; |
@@ -1387,16 +1384,11 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
1387 | not_termios.c_iflag = ~tty->termios->c_iflag; | 1384 | not_termios.c_iflag = ~tty->termios->c_iflag; |
1388 | digi_set_termios(tty, port, ¬_termios); | 1385 | digi_set_termios(tty, port, ¬_termios); |
1389 | } | 1386 | } |
1390 | |||
1391 | /* set DTR and RTS */ | ||
1392 | digi_set_modem_signals(port, TIOCM_DTR|TIOCM_RTS, 1); | ||
1393 | |||
1394 | return 0; | 1387 | return 0; |
1395 | } | 1388 | } |
1396 | 1389 | ||
1397 | 1390 | ||
1398 | static void digi_close(struct tty_struct *tty, struct usb_serial_port *port, | 1391 | static void digi_close(struct usb_serial_port *port) |
1399 | struct file *filp) | ||
1400 | { | 1392 | { |
1401 | DEFINE_WAIT(wait); | 1393 | DEFINE_WAIT(wait); |
1402 | int ret; | 1394 | int ret; |
@@ -1411,28 +1403,9 @@ static void digi_close(struct tty_struct *tty, struct usb_serial_port *port, | |||
1411 | if (port->serial->disconnected) | 1403 | if (port->serial->disconnected) |
1412 | goto exit; | 1404 | goto exit; |
1413 | 1405 | ||
1414 | /* do cleanup only after final close on this port */ | ||
1415 | spin_lock_irq(&priv->dp_port_lock); | ||
1416 | priv->dp_in_close = 1; | ||
1417 | spin_unlock_irq(&priv->dp_port_lock); | ||
1418 | |||
1419 | /* tell line discipline to process only XON/XOFF */ | ||
1420 | tty->closing = 1; | ||
1421 | |||
1422 | /* wait for output to drain */ | ||
1423 | if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) | ||
1424 | tty_wait_until_sent(tty, DIGI_CLOSE_TIMEOUT); | ||
1425 | |||
1426 | /* flush driver and line discipline buffers */ | ||
1427 | tty_driver_flush_buffer(tty); | ||
1428 | tty_ldisc_flush(tty); | ||
1429 | |||
1430 | if (port->serial->dev) { | 1406 | if (port->serial->dev) { |
1431 | /* wait for transmit idle */ | 1407 | /* FIXME: Transmit idle belongs in the wait_unti_sent path */ |
1432 | if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) | 1408 | digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT); |
1433 | digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT); | ||
1434 | /* drop DTR and RTS */ | ||
1435 | digi_set_modem_signals(port, 0, 0); | ||
1436 | 1409 | ||
1437 | /* disable input flow control */ | 1410 | /* disable input flow control */ |
1438 | buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; | 1411 | buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; |
@@ -1477,11 +1450,9 @@ static void digi_close(struct tty_struct *tty, struct usb_serial_port *port, | |||
1477 | /* shutdown any outstanding bulk writes */ | 1450 | /* shutdown any outstanding bulk writes */ |
1478 | usb_kill_urb(port->write_urb); | 1451 | usb_kill_urb(port->write_urb); |
1479 | } | 1452 | } |
1480 | tty->closing = 0; | ||
1481 | exit: | 1453 | exit: |
1482 | spin_lock_irq(&priv->dp_port_lock); | 1454 | spin_lock_irq(&priv->dp_port_lock); |
1483 | priv->dp_write_urb_in_use = 0; | 1455 | priv->dp_write_urb_in_use = 0; |
1484 | priv->dp_in_close = 0; | ||
1485 | wake_up_interruptible(&priv->dp_close_wait); | 1456 | wake_up_interruptible(&priv->dp_close_wait); |
1486 | spin_unlock_irq(&priv->dp_port_lock); | 1457 | spin_unlock_irq(&priv->dp_port_lock); |
1487 | mutex_unlock(&port->serial->disc_mutex); | 1458 | mutex_unlock(&port->serial->disc_mutex); |
@@ -1560,7 +1531,6 @@ static int digi_startup(struct usb_serial *serial) | |||
1560 | priv->dp_throttled = 0; | 1531 | priv->dp_throttled = 0; |
1561 | priv->dp_throttle_restart = 0; | 1532 | priv->dp_throttle_restart = 0; |
1562 | init_waitqueue_head(&priv->dp_flush_wait); | 1533 | init_waitqueue_head(&priv->dp_flush_wait); |
1563 | priv->dp_in_close = 0; | ||
1564 | init_waitqueue_head(&priv->dp_close_wait); | 1534 | init_waitqueue_head(&priv->dp_close_wait); |
1565 | INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); | 1535 | INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); |
1566 | priv->dp_port = serial->port[i]; | 1536 | priv->dp_port = serial->port[i]; |
@@ -1589,16 +1559,23 @@ static int digi_startup(struct usb_serial *serial) | |||
1589 | } | 1559 | } |
1590 | 1560 | ||
1591 | 1561 | ||
1592 | static void digi_shutdown(struct usb_serial *serial) | 1562 | static void digi_disconnect(struct usb_serial *serial) |
1593 | { | 1563 | { |
1594 | int i; | 1564 | int i; |
1595 | dbg("digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt()); | 1565 | dbg("digi_disconnect: TOP, in_interrupt()=%ld", in_interrupt()); |
1596 | 1566 | ||
1597 | /* stop reads and writes on all ports */ | 1567 | /* stop reads and writes on all ports */ |
1598 | for (i = 0; i < serial->type->num_ports + 1; i++) { | 1568 | for (i = 0; i < serial->type->num_ports + 1; i++) { |
1599 | usb_kill_urb(serial->port[i]->read_urb); | 1569 | usb_kill_urb(serial->port[i]->read_urb); |
1600 | usb_kill_urb(serial->port[i]->write_urb); | 1570 | usb_kill_urb(serial->port[i]->write_urb); |
1601 | } | 1571 | } |
1572 | } | ||
1573 | |||
1574 | |||
1575 | static void digi_release(struct usb_serial *serial) | ||
1576 | { | ||
1577 | int i; | ||
1578 | dbg("digi_release: TOP, in_interrupt()=%ld", in_interrupt()); | ||
1602 | 1579 | ||
1603 | /* free the private data structures for all ports */ | 1580 | /* free the private data structures for all ports */ |
1604 | /* number of regular ports + 1 for the out-of-band port */ | 1581 | /* number of regular ports + 1 for the out-of-band port */ |
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index c709ec474a80..80cb3471adbe 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -81,8 +81,7 @@ static int debug; | |||
81 | /* function prototypes for an empeg-car player */ | 81 | /* function prototypes for an empeg-car player */ |
82 | static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port, | 82 | static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port, |
83 | struct file *filp); | 83 | struct file *filp); |
84 | static void empeg_close(struct tty_struct *tty, struct usb_serial_port *port, | 84 | static void empeg_close(struct usb_serial_port *port); |
85 | struct file *filp); | ||
86 | static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port, | 85 | static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port, |
87 | const unsigned char *buf, | 86 | const unsigned char *buf, |
88 | int count); | 87 | int count); |
@@ -91,7 +90,6 @@ static int empeg_chars_in_buffer(struct tty_struct *tty); | |||
91 | static void empeg_throttle(struct tty_struct *tty); | 90 | static void empeg_throttle(struct tty_struct *tty); |
92 | static void empeg_unthrottle(struct tty_struct *tty); | 91 | static void empeg_unthrottle(struct tty_struct *tty); |
93 | static int empeg_startup(struct usb_serial *serial); | 92 | static int empeg_startup(struct usb_serial *serial); |
94 | static void empeg_shutdown(struct usb_serial *serial); | ||
95 | static void empeg_set_termios(struct tty_struct *tty, | 93 | static void empeg_set_termios(struct tty_struct *tty, |
96 | struct usb_serial_port *port, struct ktermios *old_termios); | 94 | struct usb_serial_port *port, struct ktermios *old_termios); |
97 | static void empeg_write_bulk_callback(struct urb *urb); | 95 | static void empeg_write_bulk_callback(struct urb *urb); |
@@ -125,7 +123,6 @@ static struct usb_serial_driver empeg_device = { | |||
125 | .throttle = empeg_throttle, | 123 | .throttle = empeg_throttle, |
126 | .unthrottle = empeg_unthrottle, | 124 | .unthrottle = empeg_unthrottle, |
127 | .attach = empeg_startup, | 125 | .attach = empeg_startup, |
128 | .shutdown = empeg_shutdown, | ||
129 | .set_termios = empeg_set_termios, | 126 | .set_termios = empeg_set_termios, |
130 | .write = empeg_write, | 127 | .write = empeg_write, |
131 | .write_room = empeg_write_room, | 128 | .write_room = empeg_write_room, |
@@ -181,8 +178,7 @@ static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
181 | } | 178 | } |
182 | 179 | ||
183 | 180 | ||
184 | static void empeg_close(struct tty_struct *tty, struct usb_serial_port *port, | 181 | static void empeg_close(struct usb_serial_port *port) |
185 | struct file *filp) | ||
186 | { | 182 | { |
187 | dbg("%s - port %d", __func__, port->number); | 183 | dbg("%s - port %d", __func__, port->number); |
188 | 184 | ||
@@ -429,12 +425,6 @@ static int empeg_startup(struct usb_serial *serial) | |||
429 | } | 425 | } |
430 | 426 | ||
431 | 427 | ||
432 | static void empeg_shutdown(struct usb_serial *serial) | ||
433 | { | ||
434 | dbg("%s", __func__); | ||
435 | } | ||
436 | |||
437 | |||
438 | static void empeg_set_termios(struct tty_struct *tty, | 428 | static void empeg_set_termios(struct tty_struct *tty, |
439 | struct usb_serial_port *port, struct ktermios *old_termios) | 429 | struct usb_serial_port *port, struct ktermios *old_termios) |
440 | { | 430 | { |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index d9fcdaedf389..3dc3768ca71c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -47,7 +47,7 @@ | |||
47 | /* | 47 | /* |
48 | * Version Information | 48 | * Version Information |
49 | */ | 49 | */ |
50 | #define DRIVER_VERSION "v1.4.3" | 50 | #define DRIVER_VERSION "v1.5.0" |
51 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" | 51 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" |
52 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" | 52 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" |
53 | 53 | ||
@@ -82,17 +82,20 @@ struct ftdi_private { | |||
82 | int rx_processed; | 82 | int rx_processed; |
83 | unsigned long rx_bytes; | 83 | unsigned long rx_bytes; |
84 | 84 | ||
85 | __u16 interface; /* FT2232C port interface (0 for FT232/245) */ | 85 | __u16 interface; /* FT2232C, FT2232H or FT4232H port interface |
86 | (0 for FT232/245) */ | ||
86 | 87 | ||
87 | speed_t force_baud; /* if non-zero, force the baud rate to | 88 | speed_t force_baud; /* if non-zero, force the baud rate to |
88 | this value */ | 89 | this value */ |
89 | int force_rtscts; /* if non-zero, force RTS-CTS to always | 90 | int force_rtscts; /* if non-zero, force RTS-CTS to always |
90 | be enabled */ | 91 | be enabled */ |
91 | 92 | ||
93 | unsigned int latency; /* latency setting in use */ | ||
92 | spinlock_t tx_lock; /* spinlock for transmit state */ | 94 | spinlock_t tx_lock; /* spinlock for transmit state */ |
93 | unsigned long tx_bytes; | 95 | unsigned long tx_bytes; |
94 | unsigned long tx_outstanding_bytes; | 96 | unsigned long tx_outstanding_bytes; |
95 | unsigned long tx_outstanding_urbs; | 97 | unsigned long tx_outstanding_urbs; |
98 | unsigned short max_packet_size; | ||
96 | }; | 99 | }; |
97 | 100 | ||
98 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ | 101 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ |
@@ -163,6 +166,7 @@ static struct usb_device_id id_table_combined [] = { | |||
163 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, | 166 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, |
164 | { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, | 167 | { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, |
165 | { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, | 168 | { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, |
169 | { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) }, | ||
166 | { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, | 170 | { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, |
167 | { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, | 171 | { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, |
168 | { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, | 172 | { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, |
@@ -672,6 +676,7 @@ static struct usb_device_id id_table_combined [] = { | |||
672 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, | 676 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, |
673 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), | 677 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), |
674 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 678 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
679 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, | ||
675 | { }, /* Optional parameter entry */ | 680 | { }, /* Optional parameter entry */ |
676 | { } /* Terminating entry */ | 681 | { } /* Terminating entry */ |
677 | }; | 682 | }; |
@@ -692,12 +697,13 @@ static const char *ftdi_chip_name[] = { | |||
692 | [FT232BM] = "FT232BM", | 697 | [FT232BM] = "FT232BM", |
693 | [FT2232C] = "FT2232C", | 698 | [FT2232C] = "FT2232C", |
694 | [FT232RL] = "FT232RL", | 699 | [FT232RL] = "FT232RL", |
700 | [FT2232H] = "FT2232H", | ||
701 | [FT4232H] = "FT4232H" | ||
695 | }; | 702 | }; |
696 | 703 | ||
697 | 704 | ||
698 | /* Constants for read urb and write urb */ | 705 | /* Constants for read urb and write urb */ |
699 | #define BUFSZ 512 | 706 | #define BUFSZ 512 |
700 | #define PKTSZ 64 | ||
701 | 707 | ||
702 | /* rx_flags */ | 708 | /* rx_flags */ |
703 | #define THROTTLED 0x01 | 709 | #define THROTTLED 0x01 |
@@ -714,13 +720,12 @@ static const char *ftdi_chip_name[] = { | |||
714 | /* function prototypes for a FTDI serial converter */ | 720 | /* function prototypes for a FTDI serial converter */ |
715 | static int ftdi_sio_probe(struct usb_serial *serial, | 721 | static int ftdi_sio_probe(struct usb_serial *serial, |
716 | const struct usb_device_id *id); | 722 | const struct usb_device_id *id); |
717 | static void ftdi_shutdown(struct usb_serial *serial); | ||
718 | static int ftdi_sio_port_probe(struct usb_serial_port *port); | 723 | static int ftdi_sio_port_probe(struct usb_serial_port *port); |
719 | static int ftdi_sio_port_remove(struct usb_serial_port *port); | 724 | static int ftdi_sio_port_remove(struct usb_serial_port *port); |
720 | static int ftdi_open(struct tty_struct *tty, | 725 | static int ftdi_open(struct tty_struct *tty, |
721 | struct usb_serial_port *port, struct file *filp); | 726 | struct usb_serial_port *port, struct file *filp); |
722 | static void ftdi_close(struct tty_struct *tty, | 727 | static void ftdi_close(struct usb_serial_port *port); |
723 | struct usb_serial_port *port, struct file *filp); | 728 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on); |
724 | static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | 729 | static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, |
725 | const unsigned char *buf, int count); | 730 | const unsigned char *buf, int count); |
726 | static int ftdi_write_room(struct tty_struct *tty); | 731 | static int ftdi_write_room(struct tty_struct *tty); |
@@ -743,6 +748,8 @@ static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base); | |||
743 | static unsigned short int ftdi_232am_baud_to_divisor(int baud); | 748 | static unsigned short int ftdi_232am_baud_to_divisor(int baud); |
744 | static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base); | 749 | static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base); |
745 | static __u32 ftdi_232bm_baud_to_divisor(int baud); | 750 | static __u32 ftdi_232bm_baud_to_divisor(int baud); |
751 | static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base); | ||
752 | static __u32 ftdi_2232h_baud_to_divisor(int baud); | ||
746 | 753 | ||
747 | static struct usb_serial_driver ftdi_sio_device = { | 754 | static struct usb_serial_driver ftdi_sio_device = { |
748 | .driver = { | 755 | .driver = { |
@@ -758,6 +765,7 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
758 | .port_remove = ftdi_sio_port_remove, | 765 | .port_remove = ftdi_sio_port_remove, |
759 | .open = ftdi_open, | 766 | .open = ftdi_open, |
760 | .close = ftdi_close, | 767 | .close = ftdi_close, |
768 | .dtr_rts = ftdi_dtr_rts, | ||
761 | .throttle = ftdi_throttle, | 769 | .throttle = ftdi_throttle, |
762 | .unthrottle = ftdi_unthrottle, | 770 | .unthrottle = ftdi_unthrottle, |
763 | .write = ftdi_write, | 771 | .write = ftdi_write, |
@@ -770,7 +778,6 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
770 | .ioctl = ftdi_ioctl, | 778 | .ioctl = ftdi_ioctl, |
771 | .set_termios = ftdi_set_termios, | 779 | .set_termios = ftdi_set_termios, |
772 | .break_ctl = ftdi_break_ctl, | 780 | .break_ctl = ftdi_break_ctl, |
773 | .shutdown = ftdi_shutdown, | ||
774 | }; | 781 | }; |
775 | 782 | ||
776 | 783 | ||
@@ -836,6 +843,36 @@ static __u32 ftdi_232bm_baud_to_divisor(int baud) | |||
836 | return ftdi_232bm_baud_base_to_divisor(baud, 48000000); | 843 | return ftdi_232bm_baud_base_to_divisor(baud, 48000000); |
837 | } | 844 | } |
838 | 845 | ||
846 | static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base) | ||
847 | { | ||
848 | static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; | ||
849 | __u32 divisor; | ||
850 | int divisor3; | ||
851 | |||
852 | /* hi-speed baud rate is 10-bit sampling instead of 16-bit */ | ||
853 | divisor3 = (base / 10 / baud) * 8; | ||
854 | |||
855 | divisor = divisor3 >> 3; | ||
856 | divisor |= (__u32)divfrac[divisor3 & 0x7] << 14; | ||
857 | /* Deal with special cases for highest baud rates. */ | ||
858 | if (divisor == 1) | ||
859 | divisor = 0; | ||
860 | else if (divisor == 0x4001) | ||
861 | divisor = 1; | ||
862 | /* | ||
863 | * Set this bit to turn off a divide by 2.5 on baud rate generator | ||
864 | * This enables baud rates up to 12Mbaud but cannot reach below 1200 | ||
865 | * baud with this bit set | ||
866 | */ | ||
867 | divisor |= 0x00020000; | ||
868 | return divisor; | ||
869 | } | ||
870 | |||
871 | static __u32 ftdi_2232h_baud_to_divisor(int baud) | ||
872 | { | ||
873 | return ftdi_2232h_baud_base_to_divisor(baud, 120000000); | ||
874 | } | ||
875 | |||
839 | #define set_mctrl(port, set) update_mctrl((port), (set), 0) | 876 | #define set_mctrl(port, set) update_mctrl((port), (set), 0) |
840 | #define clear_mctrl(port, clear) update_mctrl((port), 0, (clear)) | 877 | #define clear_mctrl(port, clear) update_mctrl((port), 0, (clear)) |
841 | 878 | ||
@@ -994,6 +1031,19 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, | |||
994 | baud = 9600; | 1031 | baud = 9600; |
995 | } | 1032 | } |
996 | break; | 1033 | break; |
1034 | case FT2232H: /* FT2232H chip */ | ||
1035 | case FT4232H: /* FT4232H chip */ | ||
1036 | if ((baud <= 12000000) & (baud >= 1200)) { | ||
1037 | div_value = ftdi_2232h_baud_to_divisor(baud); | ||
1038 | } else if (baud < 1200) { | ||
1039 | div_value = ftdi_232bm_baud_to_divisor(baud); | ||
1040 | } else { | ||
1041 | dbg("%s - Baud rate too high!", __func__); | ||
1042 | div_value = ftdi_232bm_baud_to_divisor(9600); | ||
1043 | div_okay = 0; | ||
1044 | baud = 9600; | ||
1045 | } | ||
1046 | break; | ||
997 | } /* priv->chip_type */ | 1047 | } /* priv->chip_type */ |
998 | 1048 | ||
999 | if (div_okay) { | 1049 | if (div_okay) { |
@@ -1037,7 +1087,54 @@ static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) | |||
1037 | return rv; | 1087 | return rv; |
1038 | } | 1088 | } |
1039 | 1089 | ||
1090 | static int write_latency_timer(struct usb_serial_port *port) | ||
1091 | { | ||
1092 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
1093 | struct usb_device *udev = port->serial->dev; | ||
1094 | char buf[1]; | ||
1095 | int rv = 0; | ||
1096 | int l = priv->latency; | ||
1097 | |||
1098 | if (priv->flags & ASYNC_LOW_LATENCY) | ||
1099 | l = 1; | ||
1100 | |||
1101 | dbg("%s: setting latency timer = %i", __func__, l); | ||
1102 | |||
1103 | rv = usb_control_msg(udev, | ||
1104 | usb_sndctrlpipe(udev, 0), | ||
1105 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | ||
1106 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | ||
1107 | l, priv->interface, | ||
1108 | buf, 0, WDR_TIMEOUT); | ||
1109 | |||
1110 | if (rv < 0) | ||
1111 | dev_err(&port->dev, "Unable to write latency timer: %i\n", rv); | ||
1112 | return rv; | ||
1113 | } | ||
1114 | |||
1115 | static int read_latency_timer(struct usb_serial_port *port) | ||
1116 | { | ||
1117 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
1118 | struct usb_device *udev = port->serial->dev; | ||
1119 | unsigned short latency = 0; | ||
1120 | int rv = 0; | ||
1121 | |||
1040 | 1122 | ||
1123 | dbg("%s", __func__); | ||
1124 | |||
1125 | rv = usb_control_msg(udev, | ||
1126 | usb_rcvctrlpipe(udev, 0), | ||
1127 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST, | ||
1128 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, | ||
1129 | 0, priv->interface, | ||
1130 | (char *) &latency, 1, WDR_TIMEOUT); | ||
1131 | |||
1132 | if (rv < 0) { | ||
1133 | dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); | ||
1134 | return -EIO; | ||
1135 | } | ||
1136 | return latency; | ||
1137 | } | ||
1041 | 1138 | ||
1042 | static int get_serial_info(struct usb_serial_port *port, | 1139 | static int get_serial_info(struct usb_serial_port *port, |
1043 | struct serial_struct __user *retinfo) | 1140 | struct serial_struct __user *retinfo) |
@@ -1097,6 +1194,7 @@ static int set_serial_info(struct tty_struct *tty, | |||
1097 | priv->custom_divisor = new_serial.custom_divisor; | 1194 | priv->custom_divisor = new_serial.custom_divisor; |
1098 | 1195 | ||
1099 | tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1196 | tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1197 | write_latency_timer(port); | ||
1100 | 1198 | ||
1101 | check_and_exit: | 1199 | check_and_exit: |
1102 | if ((old_priv.flags & ASYNC_SPD_MASK) != | 1200 | if ((old_priv.flags & ASYNC_SPD_MASK) != |
@@ -1146,14 +1244,29 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
1146 | if (interfaces > 1) { | 1244 | if (interfaces > 1) { |
1147 | int inter; | 1245 | int inter; |
1148 | 1246 | ||
1149 | /* Multiple interfaces. Assume FT2232C. */ | 1247 | /* Multiple interfaces.*/ |
1150 | priv->chip_type = FT2232C; | 1248 | if (version == 0x0800) { |
1249 | priv->chip_type = FT4232H; | ||
1250 | /* Hi-speed - baud clock runs at 120MHz */ | ||
1251 | priv->baud_base = 120000000 / 2; | ||
1252 | } else if (version == 0x0700) { | ||
1253 | priv->chip_type = FT2232H; | ||
1254 | /* Hi-speed - baud clock runs at 120MHz */ | ||
1255 | priv->baud_base = 120000000 / 2; | ||
1256 | } else | ||
1257 | priv->chip_type = FT2232C; | ||
1258 | |||
1151 | /* Determine interface code. */ | 1259 | /* Determine interface code. */ |
1152 | inter = serial->interface->altsetting->desc.bInterfaceNumber; | 1260 | inter = serial->interface->altsetting->desc.bInterfaceNumber; |
1153 | if (inter == 0) | 1261 | if (inter == 0) { |
1154 | priv->interface = PIT_SIOA; | 1262 | priv->interface = INTERFACE_A; |
1155 | else | 1263 | } else if (inter == 1) { |
1156 | priv->interface = PIT_SIOB; | 1264 | priv->interface = INTERFACE_B; |
1265 | } else if (inter == 2) { | ||
1266 | priv->interface = INTERFACE_C; | ||
1267 | } else if (inter == 3) { | ||
1268 | priv->interface = INTERFACE_D; | ||
1269 | } | ||
1157 | /* BM-type devices have a bug where bcdDevice gets set | 1270 | /* BM-type devices have a bug where bcdDevice gets set |
1158 | * to 0x200 when iSerialNumber is 0. */ | 1271 | * to 0x200 when iSerialNumber is 0. */ |
1159 | if (version < 0x500) { | 1272 | if (version < 0x500) { |
@@ -1181,6 +1294,45 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
1181 | } | 1294 | } |
1182 | 1295 | ||
1183 | 1296 | ||
1297 | /* Determine the maximum packet size for the device. This depends on the chip | ||
1298 | * type and the USB host capabilities. The value should be obtained from the | ||
1299 | * device descriptor as the chip will use the appropriate values for the host.*/ | ||
1300 | static void ftdi_set_max_packet_size(struct usb_serial_port *port) | ||
1301 | { | ||
1302 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
1303 | struct usb_serial *serial = port->serial; | ||
1304 | struct usb_device *udev = serial->dev; | ||
1305 | |||
1306 | struct usb_interface *interface = serial->interface; | ||
1307 | struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; | ||
1308 | |||
1309 | unsigned num_endpoints; | ||
1310 | int i = 0; | ||
1311 | |||
1312 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; | ||
1313 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); | ||
1314 | |||
1315 | /* NOTE: some customers have programmed FT232R/FT245R devices | ||
1316 | * with an endpoint size of 0 - not good. In this case, we | ||
1317 | * want to override the endpoint descriptor setting and use a | ||
1318 | * value of 64 for wMaxPacketSize */ | ||
1319 | for (i = 0; i < num_endpoints; i++) { | ||
1320 | dev_info(&udev->dev, "Endpoint %d MaxPacketSize %d\n", i+1, | ||
1321 | interface->cur_altsetting->endpoint[i].desc.wMaxPacketSize); | ||
1322 | ep_desc = &interface->cur_altsetting->endpoint[i].desc; | ||
1323 | if (ep_desc->wMaxPacketSize == 0) { | ||
1324 | ep_desc->wMaxPacketSize = cpu_to_le16(0x40); | ||
1325 | dev_info(&udev->dev, "Overriding wMaxPacketSize on endpoint %d\n", i); | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1329 | /* set max packet size based on descriptor */ | ||
1330 | priv->max_packet_size = ep_desc->wMaxPacketSize; | ||
1331 | |||
1332 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); | ||
1333 | } | ||
1334 | |||
1335 | |||
1184 | /* | 1336 | /* |
1185 | * *************************************************************************** | 1337 | * *************************************************************************** |
1186 | * Sysfs Attribute | 1338 | * Sysfs Attribute |
@@ -1192,27 +1344,13 @@ static ssize_t show_latency_timer(struct device *dev, | |||
1192 | { | 1344 | { |
1193 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1345 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1194 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1346 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1195 | struct usb_device *udev = port->serial->dev; | 1347 | if (priv->flags & ASYNC_LOW_LATENCY) |
1196 | unsigned short latency = 0; | 1348 | return sprintf(buf, "1\n"); |
1197 | int rv = 0; | 1349 | else |
1198 | 1350 | return sprintf(buf, "%i\n", priv->latency); | |
1199 | |||
1200 | dbg("%s", __func__); | ||
1201 | |||
1202 | rv = usb_control_msg(udev, | ||
1203 | usb_rcvctrlpipe(udev, 0), | ||
1204 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST, | ||
1205 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, | ||
1206 | 0, priv->interface, | ||
1207 | (char *) &latency, 1, WDR_TIMEOUT); | ||
1208 | |||
1209 | if (rv < 0) { | ||
1210 | dev_err(dev, "Unable to read latency timer: %i\n", rv); | ||
1211 | return -EIO; | ||
1212 | } | ||
1213 | return sprintf(buf, "%i\n", latency); | ||
1214 | } | 1351 | } |
1215 | 1352 | ||
1353 | |||
1216 | /* Write a new value of the latency timer, in units of milliseconds. */ | 1354 | /* Write a new value of the latency timer, in units of milliseconds. */ |
1217 | static ssize_t store_latency_timer(struct device *dev, | 1355 | static ssize_t store_latency_timer(struct device *dev, |
1218 | struct device_attribute *attr, const char *valbuf, | 1356 | struct device_attribute *attr, const char *valbuf, |
@@ -1220,25 +1358,13 @@ static ssize_t store_latency_timer(struct device *dev, | |||
1220 | { | 1358 | { |
1221 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1359 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1222 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1360 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1223 | struct usb_device *udev = port->serial->dev; | ||
1224 | char buf[1]; | ||
1225 | int v = simple_strtoul(valbuf, NULL, 10); | 1361 | int v = simple_strtoul(valbuf, NULL, 10); |
1226 | int rv = 0; | 1362 | int rv = 0; |
1227 | 1363 | ||
1228 | dbg("%s: setting latency timer = %i", __func__, v); | 1364 | priv->latency = v; |
1229 | 1365 | rv = write_latency_timer(port); | |
1230 | rv = usb_control_msg(udev, | 1366 | if (rv < 0) |
1231 | usb_sndctrlpipe(udev, 0), | ||
1232 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | ||
1233 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | ||
1234 | v, priv->interface, | ||
1235 | buf, 0, WDR_TIMEOUT); | ||
1236 | |||
1237 | if (rv < 0) { | ||
1238 | dev_err(dev, "Unable to write latency timer: %i\n", rv); | ||
1239 | return -EIO; | 1367 | return -EIO; |
1240 | } | ||
1241 | |||
1242 | return count; | 1368 | return count; |
1243 | } | 1369 | } |
1244 | 1370 | ||
@@ -1290,7 +1416,9 @@ static int create_sysfs_attrs(struct usb_serial_port *port) | |||
1290 | if ((!retval) && | 1416 | if ((!retval) && |
1291 | (priv->chip_type == FT232BM || | 1417 | (priv->chip_type == FT232BM || |
1292 | priv->chip_type == FT2232C || | 1418 | priv->chip_type == FT2232C || |
1293 | priv->chip_type == FT232RL)) { | 1419 | priv->chip_type == FT232RL || |
1420 | priv->chip_type == FT2232H || | ||
1421 | priv->chip_type == FT4232H)) { | ||
1294 | retval = device_create_file(&port->dev, | 1422 | retval = device_create_file(&port->dev, |
1295 | &dev_attr_latency_timer); | 1423 | &dev_attr_latency_timer); |
1296 | } | 1424 | } |
@@ -1309,7 +1437,9 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) | |||
1309 | device_remove_file(&port->dev, &dev_attr_event_char); | 1437 | device_remove_file(&port->dev, &dev_attr_event_char); |
1310 | if (priv->chip_type == FT232BM || | 1438 | if (priv->chip_type == FT232BM || |
1311 | priv->chip_type == FT2232C || | 1439 | priv->chip_type == FT2232C || |
1312 | priv->chip_type == FT232RL) { | 1440 | priv->chip_type == FT232RL || |
1441 | priv->chip_type == FT2232H || | ||
1442 | priv->chip_type == FT4232H) { | ||
1313 | device_remove_file(&port->dev, &dev_attr_latency_timer); | 1443 | device_remove_file(&port->dev, &dev_attr_latency_timer); |
1314 | } | 1444 | } |
1315 | } | 1445 | } |
@@ -1392,6 +1522,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1392 | usb_set_serial_port_data(port, priv); | 1522 | usb_set_serial_port_data(port, priv); |
1393 | 1523 | ||
1394 | ftdi_determine_type(port); | 1524 | ftdi_determine_type(port); |
1525 | ftdi_set_max_packet_size(port); | ||
1526 | read_latency_timer(port); | ||
1395 | create_sysfs_attrs(port); | 1527 | create_sysfs_attrs(port); |
1396 | return 0; | 1528 | return 0; |
1397 | } | 1529 | } |
@@ -1460,18 +1592,6 @@ static int ftdi_mtxorb_hack_setup(struct usb_serial *serial) | |||
1460 | return 0; | 1592 | return 0; |
1461 | } | 1593 | } |
1462 | 1594 | ||
1463 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect | ||
1464 | * it is called when the usb device is disconnected | ||
1465 | * | ||
1466 | * usbserial:usb_serial_disconnect | ||
1467 | * calls __serial_close for each open of the port | ||
1468 | * shutdown is called then (ie ftdi_shutdown) | ||
1469 | */ | ||
1470 | static void ftdi_shutdown(struct usb_serial *serial) | ||
1471 | { | ||
1472 | dbg("%s", __func__); | ||
1473 | } | ||
1474 | |||
1475 | static void ftdi_sio_priv_release(struct kref *k) | 1595 | static void ftdi_sio_priv_release(struct kref *k) |
1476 | { | 1596 | { |
1477 | struct ftdi_private *priv = container_of(k, struct ftdi_private, kref); | 1597 | struct ftdi_private *priv = container_of(k, struct ftdi_private, kref); |
@@ -1514,6 +1634,8 @@ static int ftdi_open(struct tty_struct *tty, | |||
1514 | if (tty) | 1634 | if (tty) |
1515 | tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1635 | tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1516 | 1636 | ||
1637 | write_latency_timer(port); | ||
1638 | |||
1517 | /* No error checking for this (will get errors later anyway) */ | 1639 | /* No error checking for this (will get errors later anyway) */ |
1518 | /* See ftdi_sio.h for description of what is reset */ | 1640 | /* See ftdi_sio.h for description of what is reset */ |
1519 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1641 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
@@ -1529,11 +1651,6 @@ static int ftdi_open(struct tty_struct *tty, | |||
1529 | if (tty) | 1651 | if (tty) |
1530 | ftdi_set_termios(tty, port, tty->termios); | 1652 | ftdi_set_termios(tty, port, tty->termios); |
1531 | 1653 | ||
1532 | /* FIXME: Flow control might be enabled, so it should be checked - | ||
1533 | we have no control of defaults! */ | ||
1534 | /* Turn on RTS and DTR since we are not flow controlling by default */ | ||
1535 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1536 | |||
1537 | /* Not throttled */ | 1654 | /* Not throttled */ |
1538 | spin_lock_irqsave(&priv->rx_lock, flags); | 1655 | spin_lock_irqsave(&priv->rx_lock, flags); |
1539 | priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); | 1656 | priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); |
@@ -1558,6 +1675,30 @@ static int ftdi_open(struct tty_struct *tty, | |||
1558 | } /* ftdi_open */ | 1675 | } /* ftdi_open */ |
1559 | 1676 | ||
1560 | 1677 | ||
1678 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | ||
1679 | { | ||
1680 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
1681 | char buf[1]; | ||
1682 | |||
1683 | mutex_lock(&port->serial->disc_mutex); | ||
1684 | if (!port->serial->disconnected) { | ||
1685 | /* Disable flow control */ | ||
1686 | if (!on && usb_control_msg(port->serial->dev, | ||
1687 | usb_sndctrlpipe(port->serial->dev, 0), | ||
1688 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | ||
1689 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | ||
1690 | 0, priv->interface, buf, 0, | ||
1691 | WDR_TIMEOUT) < 0) { | ||
1692 | dev_err(&port->dev, "error from flowcontrol urb\n"); | ||
1693 | } | ||
1694 | /* drop RTS and DTR */ | ||
1695 | if (on) | ||
1696 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1697 | else | ||
1698 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1699 | } | ||
1700 | mutex_unlock(&port->serial->disc_mutex); | ||
1701 | } | ||
1561 | 1702 | ||
1562 | /* | 1703 | /* |
1563 | * usbserial:__serial_close only calls ftdi_close if the point is open | 1704 | * usbserial:__serial_close only calls ftdi_close if the point is open |
@@ -1567,31 +1708,12 @@ static int ftdi_open(struct tty_struct *tty, | |||
1567 | * | 1708 | * |
1568 | */ | 1709 | */ |
1569 | 1710 | ||
1570 | static void ftdi_close(struct tty_struct *tty, | 1711 | static void ftdi_close(struct usb_serial_port *port) |
1571 | struct usb_serial_port *port, struct file *filp) | ||
1572 | { /* ftdi_close */ | 1712 | { /* ftdi_close */ |
1573 | unsigned int c_cflag = tty->termios->c_cflag; | ||
1574 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1713 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1575 | char buf[1]; | ||
1576 | 1714 | ||
1577 | dbg("%s", __func__); | 1715 | dbg("%s", __func__); |
1578 | 1716 | ||
1579 | mutex_lock(&port->serial->disc_mutex); | ||
1580 | if (c_cflag & HUPCL && !port->serial->disconnected) { | ||
1581 | /* Disable flow control */ | ||
1582 | if (usb_control_msg(port->serial->dev, | ||
1583 | usb_sndctrlpipe(port->serial->dev, 0), | ||
1584 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | ||
1585 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | ||
1586 | 0, priv->interface, buf, 0, | ||
1587 | WDR_TIMEOUT) < 0) { | ||
1588 | dev_err(&port->dev, "error from flowcontrol urb\n"); | ||
1589 | } | ||
1590 | |||
1591 | /* drop RTS and DTR */ | ||
1592 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1593 | } /* Note change no line if hupcl is off */ | ||
1594 | mutex_unlock(&port->serial->disc_mutex); | ||
1595 | 1717 | ||
1596 | /* cancel any scheduled reading */ | 1718 | /* cancel any scheduled reading */ |
1597 | cancel_delayed_work_sync(&priv->rx_work); | 1719 | cancel_delayed_work_sync(&priv->rx_work); |
@@ -1644,8 +1766,8 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1644 | if (data_offset > 0) { | 1766 | if (data_offset > 0) { |
1645 | /* Original sio needs control bytes too... */ | 1767 | /* Original sio needs control bytes too... */ |
1646 | transfer_size += (data_offset * | 1768 | transfer_size += (data_offset * |
1647 | ((count + (PKTSZ - 1 - data_offset)) / | 1769 | ((count + (priv->max_packet_size - 1 - data_offset)) / |
1648 | (PKTSZ - data_offset))); | 1770 | (priv->max_packet_size - data_offset))); |
1649 | } | 1771 | } |
1650 | 1772 | ||
1651 | buffer = kmalloc(transfer_size, GFP_ATOMIC); | 1773 | buffer = kmalloc(transfer_size, GFP_ATOMIC); |
@@ -1667,7 +1789,7 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1667 | if (data_offset > 0) { | 1789 | if (data_offset > 0) { |
1668 | /* Original sio requires control byte at start of | 1790 | /* Original sio requires control byte at start of |
1669 | each packet. */ | 1791 | each packet. */ |
1670 | int user_pktsz = PKTSZ - data_offset; | 1792 | int user_pktsz = priv->max_packet_size - data_offset; |
1671 | int todo = count; | 1793 | int todo = count; |
1672 | unsigned char *first_byte = buffer; | 1794 | unsigned char *first_byte = buffer; |
1673 | const unsigned char *current_position = buf; | 1795 | const unsigned char *current_position = buf; |
@@ -1748,11 +1870,6 @@ static void ftdi_write_bulk_callback(struct urb *urb) | |||
1748 | 1870 | ||
1749 | dbg("%s - port %d", __func__, port->number); | 1871 | dbg("%s - port %d", __func__, port->number); |
1750 | 1872 | ||
1751 | if (status) { | ||
1752 | dbg("nonzero write bulk status received: %d", status); | ||
1753 | return; | ||
1754 | } | ||
1755 | |||
1756 | priv = usb_get_serial_port_data(port); | 1873 | priv = usb_get_serial_port_data(port); |
1757 | if (!priv) { | 1874 | if (!priv) { |
1758 | dbg("%s - bad port private data pointer - exiting", __func__); | 1875 | dbg("%s - bad port private data pointer - exiting", __func__); |
@@ -1763,13 +1880,18 @@ static void ftdi_write_bulk_callback(struct urb *urb) | |||
1763 | data_offset = priv->write_offset; | 1880 | data_offset = priv->write_offset; |
1764 | if (data_offset > 0) { | 1881 | if (data_offset > 0) { |
1765 | /* Subtract the control bytes */ | 1882 | /* Subtract the control bytes */ |
1766 | countback -= (data_offset * DIV_ROUND_UP(countback, PKTSZ)); | 1883 | countback -= (data_offset * DIV_ROUND_UP(countback, priv->max_packet_size)); |
1767 | } | 1884 | } |
1768 | spin_lock_irqsave(&priv->tx_lock, flags); | 1885 | spin_lock_irqsave(&priv->tx_lock, flags); |
1769 | --priv->tx_outstanding_urbs; | 1886 | --priv->tx_outstanding_urbs; |
1770 | priv->tx_outstanding_bytes -= countback; | 1887 | priv->tx_outstanding_bytes -= countback; |
1771 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 1888 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
1772 | 1889 | ||
1890 | if (status) { | ||
1891 | dbg("nonzero write bulk status received: %d", status); | ||
1892 | return; | ||
1893 | } | ||
1894 | |||
1773 | usb_serial_port_softint(port); | 1895 | usb_serial_port_softint(port); |
1774 | } /* ftdi_write_bulk_callback */ | 1896 | } /* ftdi_write_bulk_callback */ |
1775 | 1897 | ||
@@ -1865,7 +1987,7 @@ static void ftdi_read_bulk_callback(struct urb *urb) | |||
1865 | 1987 | ||
1866 | /* count data bytes, but not status bytes */ | 1988 | /* count data bytes, but not status bytes */ |
1867 | countread = urb->actual_length; | 1989 | countread = urb->actual_length; |
1868 | countread -= 2 * DIV_ROUND_UP(countread, PKTSZ); | 1990 | countread -= 2 * DIV_ROUND_UP(countread, priv->max_packet_size); |
1869 | spin_lock_irqsave(&priv->rx_lock, flags); | 1991 | spin_lock_irqsave(&priv->rx_lock, flags); |
1870 | priv->rx_bytes += countread; | 1992 | priv->rx_bytes += countread; |
1871 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 1993 | spin_unlock_irqrestore(&priv->rx_lock, flags); |
@@ -1938,7 +2060,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
1938 | 2060 | ||
1939 | need_flip = 0; | 2061 | need_flip = 0; |
1940 | for (packet_offset = priv->rx_processed; | 2062 | for (packet_offset = priv->rx_processed; |
1941 | packet_offset < urb->actual_length; packet_offset += PKTSZ) { | 2063 | packet_offset < urb->actual_length; packet_offset += priv->max_packet_size) { |
1942 | int length; | 2064 | int length; |
1943 | 2065 | ||
1944 | /* Compare new line status to the old one, signal if different/ | 2066 | /* Compare new line status to the old one, signal if different/ |
@@ -1953,7 +2075,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
1953 | priv->prev_status = new_status; | 2075 | priv->prev_status = new_status; |
1954 | } | 2076 | } |
1955 | 2077 | ||
1956 | length = min_t(u32, PKTSZ, urb->actual_length-packet_offset)-2; | 2078 | length = min_t(u32, priv->max_packet_size, urb->actual_length-packet_offset)-2; |
1957 | if (length < 0) { | 2079 | if (length < 0) { |
1958 | dev_err(&port->dev, "%s - bad packet length: %d\n", | 2080 | dev_err(&port->dev, "%s - bad packet length: %d\n", |
1959 | __func__, length+2); | 2081 | __func__, length+2); |
@@ -1984,6 +2106,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
1984 | if (data[packet_offset+1] & FTDI_RS_BI) { | 2106 | if (data[packet_offset+1] & FTDI_RS_BI) { |
1985 | error_flag = TTY_BREAK; | 2107 | error_flag = TTY_BREAK; |
1986 | dbg("BREAK received"); | 2108 | dbg("BREAK received"); |
2109 | usb_serial_handle_break(port); | ||
1987 | } | 2110 | } |
1988 | if (data[packet_offset+1] & FTDI_RS_PE) { | 2111 | if (data[packet_offset+1] & FTDI_RS_PE) { |
1989 | error_flag = TTY_PARITY; | 2112 | error_flag = TTY_PARITY; |
@@ -1998,8 +2121,11 @@ static void ftdi_process_read(struct work_struct *work) | |||
1998 | /* Note that the error flag is duplicated for | 2121 | /* Note that the error flag is duplicated for |
1999 | every character received since we don't know | 2122 | every character received since we don't know |
2000 | which character it applied to */ | 2123 | which character it applied to */ |
2001 | tty_insert_flip_char(tty, | 2124 | if (!usb_serial_handle_sysrq_char(port, |
2002 | data[packet_offset + i], error_flag); | 2125 | data[packet_offset + i])) |
2126 | tty_insert_flip_char(tty, | ||
2127 | data[packet_offset + i], | ||
2128 | error_flag); | ||
2003 | } | 2129 | } |
2004 | need_flip = 1; | 2130 | need_flip = 1; |
2005 | } | 2131 | } |
@@ -2305,6 +2431,8 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2305 | case FT232BM: | 2431 | case FT232BM: |
2306 | case FT2232C: | 2432 | case FT2232C: |
2307 | case FT232RL: | 2433 | case FT232RL: |
2434 | case FT2232H: | ||
2435 | case FT4232H: | ||
2308 | /* the 8U232AM returns a two byte value (the sio is a 1 byte | 2436 | /* the 8U232AM returns a two byte value (the sio is a 1 byte |
2309 | value) - in the same format as the data returned from the in | 2437 | value) - in the same format as the data returned from the in |
2310 | point */ | 2438 | point */ |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 12330fa1c095..f1d440a728a3 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -10,7 +10,7 @@ | |||
10 | * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side, | 10 | * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side, |
11 | * USB on the other. | 11 | * USB on the other. |
12 | * | 12 | * |
13 | * Thanx to FTDI (http://www.ftdi.co.uk) for so kindly providing details | 13 | * Thanx to FTDI (http://www.ftdichip.com) for so kindly providing details |
14 | * of the protocol required to talk to the device and ongoing assistence | 14 | * of the protocol required to talk to the device and ongoing assistence |
15 | * during development. | 15 | * during development. |
16 | * | 16 | * |
@@ -28,11 +28,15 @@ | |||
28 | #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ | 28 | #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ |
29 | #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ | 29 | #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ |
30 | #define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ | 30 | #define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ |
31 | #define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ | ||
31 | #define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ | 32 | #define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ |
32 | #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ | 33 | #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ |
33 | #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ | 34 | #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ |
34 | #define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 */ | 35 | #define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 */ |
35 | 36 | ||
37 | /* Larsen and Brusgaard AltiTrack/USBtrack */ | ||
38 | #define LARSENBRUSGAARD_VID 0x0FD8 | ||
39 | #define LB_ALTITRACK_PID 0x0001 | ||
36 | 40 | ||
37 | /* www.canusb.com Lawicel CANUSB device */ | 41 | /* www.canusb.com Lawicel CANUSB device */ |
38 | #define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ | 42 | #define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ |
@@ -873,6 +877,11 @@ | |||
873 | #define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */ | 877 | #define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */ |
874 | #define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */ | 878 | #define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */ |
875 | 879 | ||
880 | /* Interface indicies for FT2232, FT2232H and FT4232H devices*/ | ||
881 | #define INTERFACE_A 1 | ||
882 | #define INTERFACE_B 2 | ||
883 | #define INTERFACE_C 3 | ||
884 | #define INTERFACE_D 4 | ||
876 | 885 | ||
877 | /* | 886 | /* |
878 | * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 | 887 | * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 |
@@ -1036,6 +1045,8 @@ typedef enum { | |||
1036 | FT232BM = 3, | 1045 | FT232BM = 3, |
1037 | FT2232C = 4, | 1046 | FT2232C = 4, |
1038 | FT232RL = 5, | 1047 | FT232RL = 5, |
1048 | FT2232H = 6, | ||
1049 | FT4232H = 7 | ||
1039 | } ftdi_chip_type_t; | 1050 | } ftdi_chip_type_t; |
1040 | 1051 | ||
1041 | typedef enum { | 1052 | typedef enum { |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 586d30ff450b..8839f1c70b7f 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Garmin GPS driver | 2 | * Garmin GPS driver |
3 | * | 3 | * |
4 | * Copyright (C) 2006,2007 Hermann Kneissel herkne@users.sourceforge.net | 4 | * Copyright (C) 2006-2009 Hermann Kneissel herkne@users.sourceforge.net |
5 | * | 5 | * |
6 | * The latest version of the driver can be found at | 6 | * The latest version of the driver can be found at |
7 | * http://sourceforge.net/projects/garmin-gps/ | 7 | * http://sourceforge.net/projects/garmin-gps/ |
@@ -51,7 +51,7 @@ static int debug; | |||
51 | */ | 51 | */ |
52 | 52 | ||
53 | #define VERSION_MAJOR 0 | 53 | #define VERSION_MAJOR 0 |
54 | #define VERSION_MINOR 31 | 54 | #define VERSION_MINOR 33 |
55 | 55 | ||
56 | #define _STR(s) #s | 56 | #define _STR(s) #s |
57 | #define _DRIVER_VERSION(a, b) "v" _STR(a) "." _STR(b) | 57 | #define _DRIVER_VERSION(a, b) "v" _STR(a) "." _STR(b) |
@@ -129,7 +129,6 @@ struct garmin_data { | |||
129 | __u8 state; | 129 | __u8 state; |
130 | __u16 flags; | 130 | __u16 flags; |
131 | __u8 mode; | 131 | __u8 mode; |
132 | __u8 ignorePkts; | ||
133 | __u8 count; | 132 | __u8 count; |
134 | __u8 pkt_id; | 133 | __u8 pkt_id; |
135 | __u32 serial_num; | 134 | __u32 serial_num; |
@@ -141,8 +140,6 @@ struct garmin_data { | |||
141 | __u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */ | 140 | __u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */ |
142 | __u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */ | 141 | __u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */ |
143 | __u8 privpkt[4*6]; | 142 | __u8 privpkt[4*6]; |
144 | atomic_t req_count; | ||
145 | atomic_t resp_count; | ||
146 | spinlock_t lock; | 143 | spinlock_t lock; |
147 | struct list_head pktlist; | 144 | struct list_head pktlist; |
148 | }; | 145 | }; |
@@ -170,6 +167,8 @@ struct garmin_data { | |||
170 | #define FLAGS_BULK_IN_ACTIVE 0x0020 | 167 | #define FLAGS_BULK_IN_ACTIVE 0x0020 |
171 | #define FLAGS_BULK_IN_RESTART 0x0010 | 168 | #define FLAGS_BULK_IN_RESTART 0x0010 |
172 | #define FLAGS_THROTTLED 0x0008 | 169 | #define FLAGS_THROTTLED 0x0008 |
170 | #define APP_REQ_SEEN 0x0004 | ||
171 | #define APP_RESP_SEEN 0x0002 | ||
173 | #define CLEAR_HALT_REQUIRED 0x0001 | 172 | #define CLEAR_HALT_REQUIRED 0x0001 |
174 | 173 | ||
175 | #define FLAGS_QUEUING 0x0100 | 174 | #define FLAGS_QUEUING 0x0100 |
@@ -184,20 +183,16 @@ struct garmin_data { | |||
184 | 183 | ||
185 | 184 | ||
186 | /* function prototypes */ | 185 | /* function prototypes */ |
187 | static void gsp_next_packet(struct garmin_data *garmin_data_p); | 186 | static int gsp_next_packet(struct garmin_data *garmin_data_p); |
188 | static int garmin_write_bulk(struct usb_serial_port *port, | 187 | static int garmin_write_bulk(struct usb_serial_port *port, |
189 | const unsigned char *buf, int count, | 188 | const unsigned char *buf, int count, |
190 | int dismiss_ack); | 189 | int dismiss_ack); |
191 | 190 | ||
192 | /* some special packets to be send or received */ | 191 | /* some special packets to be send or received */ |
193 | static unsigned char const GARMIN_START_SESSION_REQ[] | 192 | static unsigned char const GARMIN_START_SESSION_REQ[] |
194 | = { 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0 }; | 193 | = { 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0 }; |
195 | static unsigned char const GARMIN_START_SESSION_REQ2[] | ||
196 | = { 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 }; | ||
197 | static unsigned char const GARMIN_START_SESSION_REPLY[] | 194 | static unsigned char const GARMIN_START_SESSION_REPLY[] |
198 | = { 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0 }; | 195 | = { 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0 }; |
199 | static unsigned char const GARMIN_SESSION_ACTIVE_REPLY[] | ||
200 | = { 0, 0, 0, 0, 17, 0, 0, 0, 4, 0, 0, 0, 0, 16, 0, 0 }; | ||
201 | static unsigned char const GARMIN_BULK_IN_AVAIL_REPLY[] | 196 | static unsigned char const GARMIN_BULK_IN_AVAIL_REPLY[] |
202 | = { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 }; | 197 | = { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 }; |
203 | static unsigned char const GARMIN_APP_LAYER_REPLY[] | 198 | static unsigned char const GARMIN_APP_LAYER_REPLY[] |
@@ -233,13 +228,6 @@ static struct usb_driver garmin_driver = { | |||
233 | }; | 228 | }; |
234 | 229 | ||
235 | 230 | ||
236 | static inline int noResponseFromAppLayer(struct garmin_data *garmin_data_p) | ||
237 | { | ||
238 | return atomic_read(&garmin_data_p->req_count) == | ||
239 | atomic_read(&garmin_data_p->resp_count); | ||
240 | } | ||
241 | |||
242 | |||
243 | static inline int getLayerId(const __u8 *usbPacket) | 231 | static inline int getLayerId(const __u8 *usbPacket) |
244 | { | 232 | { |
245 | return __le32_to_cpup((__le32 *)(usbPacket)); | 233 | return __le32_to_cpup((__le32 *)(usbPacket)); |
@@ -325,8 +313,11 @@ static int pkt_add(struct garmin_data *garmin_data_p, | |||
325 | state = garmin_data_p->state; | 313 | state = garmin_data_p->state; |
326 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | 314 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); |
327 | 315 | ||
316 | dbg("%s - added: pkt: %d - %d bytes", | ||
317 | __func__, pkt->seq, data_length); | ||
318 | |||
328 | /* in serial mode, if someone is waiting for data from | 319 | /* in serial mode, if someone is waiting for data from |
329 | the device, iconvert and send the next packet to tty. */ | 320 | the device, convert and send the next packet to tty. */ |
330 | if (result && (state == STATE_GSP_WAIT_DATA)) | 321 | if (result && (state == STATE_GSP_WAIT_DATA)) |
331 | gsp_next_packet(garmin_data_p); | 322 | gsp_next_packet(garmin_data_p); |
332 | } | 323 | } |
@@ -411,7 +402,7 @@ static int gsp_send_ack(struct garmin_data *garmin_data_p, __u8 pkt_id) | |||
411 | /* | 402 | /* |
412 | * called for a complete packet received from tty layer | 403 | * called for a complete packet received from tty layer |
413 | * | 404 | * |
414 | * the complete packet (pkzid ... cksum) is in garmin_data_p->inbuf starting | 405 | * the complete packet (pktid ... cksum) is in garmin_data_p->inbuf starting |
415 | * at GSP_INITIAL_OFFSET. | 406 | * at GSP_INITIAL_OFFSET. |
416 | * | 407 | * |
417 | * count - number of bytes in the input buffer including space reserved for | 408 | * count - number of bytes in the input buffer including space reserved for |
@@ -501,7 +492,6 @@ static int gsp_receive(struct garmin_data *garmin_data_p, | |||
501 | unsigned long flags; | 492 | unsigned long flags; |
502 | int offs = 0; | 493 | int offs = 0; |
503 | int ack_or_nak_seen = 0; | 494 | int ack_or_nak_seen = 0; |
504 | int i = 0; | ||
505 | __u8 *dest; | 495 | __u8 *dest; |
506 | int size; | 496 | int size; |
507 | /* dleSeen: set if last byte read was a DLE */ | 497 | /* dleSeen: set if last byte read was a DLE */ |
@@ -519,8 +509,8 @@ static int gsp_receive(struct garmin_data *garmin_data_p, | |||
519 | skip = garmin_data_p->flags & FLAGS_GSP_SKIP; | 509 | skip = garmin_data_p->flags & FLAGS_GSP_SKIP; |
520 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | 510 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); |
521 | 511 | ||
522 | dbg("%s - dle=%d skip=%d size=%d count=%d", | 512 | /* dbg("%s - dle=%d skip=%d size=%d count=%d", |
523 | __func__, dleSeen, skip, size, count); | 513 | __func__, dleSeen, skip, size, count); */ |
524 | 514 | ||
525 | if (size == 0) | 515 | if (size == 0) |
526 | size = GSP_INITIAL_OFFSET; | 516 | size = GSP_INITIAL_OFFSET; |
@@ -568,7 +558,6 @@ static int gsp_receive(struct garmin_data *garmin_data_p, | |||
568 | } else if (!skip) { | 558 | } else if (!skip) { |
569 | 559 | ||
570 | if (dleSeen) { | 560 | if (dleSeen) { |
571 | dbg("non-masked DLE at %d - restarting", i); | ||
572 | size = GSP_INITIAL_OFFSET; | 561 | size = GSP_INITIAL_OFFSET; |
573 | dleSeen = 0; | 562 | dleSeen = 0; |
574 | } | 563 | } |
@@ -599,19 +588,19 @@ static int gsp_receive(struct garmin_data *garmin_data_p, | |||
599 | else | 588 | else |
600 | garmin_data_p->flags &= ~FLAGS_GSP_DLESEEN; | 589 | garmin_data_p->flags &= ~FLAGS_GSP_DLESEEN; |
601 | 590 | ||
602 | if (ack_or_nak_seen) | ||
603 | garmin_data_p->state = STATE_GSP_WAIT_DATA; | ||
604 | |||
605 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | 591 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); |
606 | 592 | ||
607 | if (ack_or_nak_seen) | 593 | if (ack_or_nak_seen) { |
608 | gsp_next_packet(garmin_data_p); | 594 | if (gsp_next_packet(garmin_data_p) > 0) |
595 | garmin_data_p->state = STATE_ACTIVE; | ||
596 | else | ||
597 | garmin_data_p->state = STATE_GSP_WAIT_DATA; | ||
598 | } | ||
609 | return count; | 599 | return count; |
610 | } | 600 | } |
611 | 601 | ||
612 | 602 | ||
613 | 603 | ||
614 | |||
615 | /* | 604 | /* |
616 | * Sends a usb packet to the tty | 605 | * Sends a usb packet to the tty |
617 | * | 606 | * |
@@ -733,29 +722,28 @@ static int gsp_send(struct garmin_data *garmin_data_p, | |||
733 | } | 722 | } |
734 | 723 | ||
735 | 724 | ||
736 | |||
737 | |||
738 | |||
739 | /* | 725 | /* |
740 | * Process the next pending data packet - if there is one | 726 | * Process the next pending data packet - if there is one |
741 | */ | 727 | */ |
742 | static void gsp_next_packet(struct garmin_data *garmin_data_p) | 728 | static int gsp_next_packet(struct garmin_data *garmin_data_p) |
743 | { | 729 | { |
730 | int result = 0; | ||
744 | struct garmin_packet *pkt = NULL; | 731 | struct garmin_packet *pkt = NULL; |
745 | 732 | ||
746 | while ((pkt = pkt_pop(garmin_data_p)) != NULL) { | 733 | while ((pkt = pkt_pop(garmin_data_p)) != NULL) { |
747 | dbg("%s - next pkt: %d", __func__, pkt->seq); | 734 | dbg("%s - next pkt: %d", __func__, pkt->seq); |
748 | if (gsp_send(garmin_data_p, pkt->data, pkt->size) > 0) { | 735 | result = gsp_send(garmin_data_p, pkt->data, pkt->size); |
736 | if (result > 0) { | ||
749 | kfree(pkt); | 737 | kfree(pkt); |
750 | return; | 738 | return result; |
751 | } | 739 | } |
752 | kfree(pkt); | 740 | kfree(pkt); |
753 | } | 741 | } |
742 | return result; | ||
754 | } | 743 | } |
755 | 744 | ||
756 | 745 | ||
757 | 746 | ||
758 | |||
759 | /****************************************************************************** | 747 | /****************************************************************************** |
760 | * garmin native mode | 748 | * garmin native mode |
761 | ******************************************************************************/ | 749 | ******************************************************************************/ |
@@ -888,14 +876,6 @@ static int garmin_clear(struct garmin_data *garmin_data_p) | |||
888 | unsigned long flags; | 876 | unsigned long flags; |
889 | int status = 0; | 877 | int status = 0; |
890 | 878 | ||
891 | struct usb_serial_port *port = garmin_data_p->port; | ||
892 | |||
893 | if (port != NULL && atomic_read(&garmin_data_p->resp_count)) { | ||
894 | /* send a terminate command */ | ||
895 | status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ, | ||
896 | sizeof(GARMIN_STOP_TRANSFER_REQ), 1); | ||
897 | } | ||
898 | |||
899 | /* flush all queued data */ | 879 | /* flush all queued data */ |
900 | pkt_clear(garmin_data_p); | 880 | pkt_clear(garmin_data_p); |
901 | 881 | ||
@@ -908,16 +888,12 @@ static int garmin_clear(struct garmin_data *garmin_data_p) | |||
908 | } | 888 | } |
909 | 889 | ||
910 | 890 | ||
911 | |||
912 | |||
913 | |||
914 | |||
915 | static int garmin_init_session(struct usb_serial_port *port) | 891 | static int garmin_init_session(struct usb_serial_port *port) |
916 | { | 892 | { |
917 | unsigned long flags; | ||
918 | struct usb_serial *serial = port->serial; | 893 | struct usb_serial *serial = port->serial; |
919 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); | 894 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); |
920 | int status = 0; | 895 | int status = 0; |
896 | int i = 0; | ||
921 | 897 | ||
922 | if (status == 0) { | 898 | if (status == 0) { |
923 | usb_kill_urb(port->interrupt_in_urb); | 899 | usb_kill_urb(port->interrupt_in_urb); |
@@ -931,30 +907,25 @@ static int garmin_init_session(struct usb_serial_port *port) | |||
931 | __func__, status); | 907 | __func__, status); |
932 | } | 908 | } |
933 | 909 | ||
910 | /* | ||
911 | * using the initialization method from gpsbabel. See comments in | ||
912 | * gpsbabel/jeeps/gpslibusb.c gusb_reset_toggles() | ||
913 | */ | ||
934 | if (status == 0) { | 914 | if (status == 0) { |
935 | dbg("%s - starting session ...", __func__); | 915 | dbg("%s - starting session ...", __func__); |
936 | garmin_data_p->state = STATE_ACTIVE; | 916 | garmin_data_p->state = STATE_ACTIVE; |
937 | status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ, | ||
938 | sizeof(GARMIN_START_SESSION_REQ), 0); | ||
939 | 917 | ||
940 | if (status >= 0) { | 918 | for (i = 0; i < 3; i++) { |
941 | |||
942 | spin_lock_irqsave(&garmin_data_p->lock, flags); | ||
943 | garmin_data_p->ignorePkts++; | ||
944 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
945 | |||
946 | /* not needed, but the win32 driver does it too ... */ | ||
947 | status = garmin_write_bulk(port, | 919 | status = garmin_write_bulk(port, |
948 | GARMIN_START_SESSION_REQ2, | 920 | GARMIN_START_SESSION_REQ, |
949 | sizeof(GARMIN_START_SESSION_REQ2), 0); | 921 | sizeof(GARMIN_START_SESSION_REQ), 0); |
950 | if (status >= 0) { | 922 | |
951 | status = 0; | 923 | if (status < 0) |
952 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 924 | break; |
953 | garmin_data_p->ignorePkts++; | ||
954 | spin_unlock_irqrestore(&garmin_data_p->lock, | ||
955 | flags); | ||
956 | } | ||
957 | } | 925 | } |
926 | |||
927 | if (status > 0) | ||
928 | status = 0; | ||
958 | } | 929 | } |
959 | 930 | ||
960 | return status; | 931 | return status; |
@@ -962,8 +933,6 @@ static int garmin_init_session(struct usb_serial_port *port) | |||
962 | 933 | ||
963 | 934 | ||
964 | 935 | ||
965 | |||
966 | |||
967 | static int garmin_open(struct tty_struct *tty, | 936 | static int garmin_open(struct tty_struct *tty, |
968 | struct usb_serial_port *port, struct file *filp) | 937 | struct usb_serial_port *port, struct file *filp) |
969 | { | 938 | { |
@@ -977,8 +946,6 @@ static int garmin_open(struct tty_struct *tty, | |||
977 | garmin_data_p->mode = initial_mode; | 946 | garmin_data_p->mode = initial_mode; |
978 | garmin_data_p->count = 0; | 947 | garmin_data_p->count = 0; |
979 | garmin_data_p->flags = 0; | 948 | garmin_data_p->flags = 0; |
980 | atomic_set(&garmin_data_p->req_count, 0); | ||
981 | atomic_set(&garmin_data_p->resp_count, 0); | ||
982 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | 949 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); |
983 | 950 | ||
984 | /* shutdown any bulk reads that might be going on */ | 951 | /* shutdown any bulk reads that might be going on */ |
@@ -993,8 +960,7 @@ static int garmin_open(struct tty_struct *tty, | |||
993 | } | 960 | } |
994 | 961 | ||
995 | 962 | ||
996 | static void garmin_close(struct tty_struct *tty, | 963 | static void garmin_close(struct usb_serial_port *port) |
997 | struct usb_serial_port *port, struct file *filp) | ||
998 | { | 964 | { |
999 | struct usb_serial *serial = port->serial; | 965 | struct usb_serial *serial = port->serial; |
1000 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); | 966 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); |
@@ -1007,6 +973,7 @@ static void garmin_close(struct tty_struct *tty, | |||
1007 | return; | 973 | return; |
1008 | 974 | ||
1009 | mutex_lock(&port->serial->disc_mutex); | 975 | mutex_lock(&port->serial->disc_mutex); |
976 | |||
1010 | if (!port->serial->disconnected) | 977 | if (!port->serial->disconnected) |
1011 | garmin_clear(garmin_data_p); | 978 | garmin_clear(garmin_data_p); |
1012 | 979 | ||
@@ -1014,25 +981,17 @@ static void garmin_close(struct tty_struct *tty, | |||
1014 | usb_kill_urb(port->read_urb); | 981 | usb_kill_urb(port->read_urb); |
1015 | usb_kill_urb(port->write_urb); | 982 | usb_kill_urb(port->write_urb); |
1016 | 983 | ||
1017 | if (!port->serial->disconnected) { | 984 | /* keep reset state so we know that we must start a new session */ |
1018 | if (noResponseFromAppLayer(garmin_data_p) || | 985 | if (garmin_data_p->state != STATE_RESET) |
1019 | ((garmin_data_p->flags & CLEAR_HALT_REQUIRED) != 0)) { | ||
1020 | process_resetdev_request(port); | ||
1021 | garmin_data_p->state = STATE_RESET; | ||
1022 | } else { | ||
1023 | garmin_data_p->state = STATE_DISCONNECTED; | ||
1024 | } | ||
1025 | } else { | ||
1026 | garmin_data_p->state = STATE_DISCONNECTED; | 986 | garmin_data_p->state = STATE_DISCONNECTED; |
1027 | } | 987 | |
1028 | mutex_unlock(&port->serial->disc_mutex); | 988 | mutex_unlock(&port->serial->disc_mutex); |
1029 | } | 989 | } |
1030 | 990 | ||
991 | |||
1031 | static void garmin_write_bulk_callback(struct urb *urb) | 992 | static void garmin_write_bulk_callback(struct urb *urb) |
1032 | { | 993 | { |
1033 | unsigned long flags; | ||
1034 | struct usb_serial_port *port = urb->context; | 994 | struct usb_serial_port *port = urb->context; |
1035 | int status = urb->status; | ||
1036 | 995 | ||
1037 | if (port) { | 996 | if (port) { |
1038 | struct garmin_data *garmin_data_p = | 997 | struct garmin_data *garmin_data_p = |
@@ -1040,20 +999,13 @@ static void garmin_write_bulk_callback(struct urb *urb) | |||
1040 | 999 | ||
1041 | dbg("%s - port %d", __func__, port->number); | 1000 | dbg("%s - port %d", __func__, port->number); |
1042 | 1001 | ||
1043 | if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer) | 1002 | if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer)) { |
1044 | && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) { | ||
1045 | gsp_send_ack(garmin_data_p, | ||
1046 | ((__u8 *)urb->transfer_buffer)[4]); | ||
1047 | } | ||
1048 | 1003 | ||
1049 | if (status) { | 1004 | if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { |
1050 | dbg("%s - nonzero write bulk status received: %d", | 1005 | gsp_send_ack(garmin_data_p, |
1051 | __func__, status); | 1006 | ((__u8 *)urb->transfer_buffer)[4]); |
1052 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1007 | } |
1053 | garmin_data_p->flags |= CLEAR_HALT_REQUIRED; | ||
1054 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
1055 | } | 1008 | } |
1056 | |||
1057 | usb_serial_port_softint(port); | 1009 | usb_serial_port_softint(port); |
1058 | } | 1010 | } |
1059 | 1011 | ||
@@ -1109,7 +1061,11 @@ static int garmin_write_bulk(struct usb_serial_port *port, | |||
1109 | urb->transfer_flags |= URB_ZERO_PACKET; | 1061 | urb->transfer_flags |= URB_ZERO_PACKET; |
1110 | 1062 | ||
1111 | if (GARMIN_LAYERID_APPL == getLayerId(buffer)) { | 1063 | if (GARMIN_LAYERID_APPL == getLayerId(buffer)) { |
1112 | atomic_inc(&garmin_data_p->req_count); | 1064 | |
1065 | spin_lock_irqsave(&garmin_data_p->lock, flags); | ||
1066 | garmin_data_p->flags |= APP_REQ_SEEN; | ||
1067 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
1068 | |||
1113 | if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { | 1069 | if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { |
1114 | pkt_clear(garmin_data_p); | 1070 | pkt_clear(garmin_data_p); |
1115 | garmin_data_p->state = STATE_GSP_WAIT_DATA; | 1071 | garmin_data_p->state = STATE_GSP_WAIT_DATA; |
@@ -1141,6 +1097,9 @@ static int garmin_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1141 | 1097 | ||
1142 | usb_serial_debug_data(debug, &port->dev, __func__, count, buf); | 1098 | usb_serial_debug_data(debug, &port->dev, __func__, count, buf); |
1143 | 1099 | ||
1100 | if (garmin_data_p->state == STATE_RESET) | ||
1101 | return -EIO; | ||
1102 | |||
1144 | /* check for our private packets */ | 1103 | /* check for our private packets */ |
1145 | if (count >= GARMIN_PKTHDR_LENGTH) { | 1104 | if (count >= GARMIN_PKTHDR_LENGTH) { |
1146 | len = PRIVPKTSIZ; | 1105 | len = PRIVPKTSIZ; |
@@ -1185,7 +1144,7 @@ static int garmin_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1185 | break; | 1144 | break; |
1186 | 1145 | ||
1187 | case PRIV_PKTID_RESET_REQ: | 1146 | case PRIV_PKTID_RESET_REQ: |
1188 | atomic_inc(&garmin_data_p->req_count); | 1147 | process_resetdev_request(port); |
1189 | break; | 1148 | break; |
1190 | 1149 | ||
1191 | case PRIV_PKTID_SET_DEF_MODE: | 1150 | case PRIV_PKTID_SET_DEF_MODE: |
@@ -1201,8 +1160,6 @@ static int garmin_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1201 | } | 1160 | } |
1202 | } | 1161 | } |
1203 | 1162 | ||
1204 | garmin_data_p->ignorePkts = 0; | ||
1205 | |||
1206 | if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { | 1163 | if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { |
1207 | return gsp_receive(garmin_data_p, buf, count); | 1164 | return gsp_receive(garmin_data_p, buf, count); |
1208 | } else { /* MODE_NATIVE */ | 1165 | } else { /* MODE_NATIVE */ |
@@ -1225,31 +1182,33 @@ static int garmin_write_room(struct tty_struct *tty) | |||
1225 | static void garmin_read_process(struct garmin_data *garmin_data_p, | 1182 | static void garmin_read_process(struct garmin_data *garmin_data_p, |
1226 | unsigned char *data, unsigned data_length) | 1183 | unsigned char *data, unsigned data_length) |
1227 | { | 1184 | { |
1185 | unsigned long flags; | ||
1186 | |||
1228 | if (garmin_data_p->flags & FLAGS_DROP_DATA) { | 1187 | if (garmin_data_p->flags & FLAGS_DROP_DATA) { |
1229 | /* abort-transfer cmd is actice */ | 1188 | /* abort-transfer cmd is actice */ |
1230 | dbg("%s - pkt dropped", __func__); | 1189 | dbg("%s - pkt dropped", __func__); |
1231 | } else if (garmin_data_p->state != STATE_DISCONNECTED && | 1190 | } else if (garmin_data_p->state != STATE_DISCONNECTED && |
1232 | garmin_data_p->state != STATE_RESET) { | 1191 | garmin_data_p->state != STATE_RESET) { |
1233 | 1192 | ||
1234 | /* remember any appl.layer packets, so we know | ||
1235 | if a reset is required or not when closing | ||
1236 | the device */ | ||
1237 | if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY, | ||
1238 | sizeof(GARMIN_APP_LAYER_REPLY))) { | ||
1239 | atomic_inc(&garmin_data_p->resp_count); | ||
1240 | } | ||
1241 | |||
1242 | /* if throttling is active or postprecessing is required | 1193 | /* if throttling is active or postprecessing is required |
1243 | put the received data in the input queue, otherwise | 1194 | put the received data in the input queue, otherwise |
1244 | send it directly to the tty port */ | 1195 | send it directly to the tty port */ |
1245 | if (garmin_data_p->flags & FLAGS_QUEUING) { | 1196 | if (garmin_data_p->flags & FLAGS_QUEUING) { |
1246 | pkt_add(garmin_data_p, data, data_length); | 1197 | pkt_add(garmin_data_p, data, data_length); |
1247 | } else if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { | 1198 | } else if (getLayerId(data) == GARMIN_LAYERID_APPL) { |
1248 | if (getLayerId(data) == GARMIN_LAYERID_APPL) | 1199 | |
1200 | spin_lock_irqsave(&garmin_data_p->lock, flags); | ||
1201 | garmin_data_p->flags |= APP_RESP_SEEN; | ||
1202 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
1203 | |||
1204 | if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { | ||
1249 | pkt_add(garmin_data_p, data, data_length); | 1205 | pkt_add(garmin_data_p, data, data_length); |
1250 | } else { | 1206 | } else { |
1251 | send_to_tty(garmin_data_p->port, data, data_length); | 1207 | send_to_tty(garmin_data_p->port, data, |
1208 | data_length); | ||
1209 | } | ||
1252 | } | 1210 | } |
1211 | /* ignore system layer packets ... */ | ||
1253 | } | 1212 | } |
1254 | } | 1213 | } |
1255 | 1214 | ||
@@ -1364,8 +1323,6 @@ static void garmin_read_int_callback(struct urb *urb) | |||
1364 | } else { | 1323 | } else { |
1365 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1324 | spin_lock_irqsave(&garmin_data_p->lock, flags); |
1366 | garmin_data_p->flags |= FLAGS_BULK_IN_ACTIVE; | 1325 | garmin_data_p->flags |= FLAGS_BULK_IN_ACTIVE; |
1367 | /* do not send this packet to the user */ | ||
1368 | garmin_data_p->ignorePkts = 1; | ||
1369 | spin_unlock_irqrestore(&garmin_data_p->lock, | 1326 | spin_unlock_irqrestore(&garmin_data_p->lock, |
1370 | flags); | 1327 | flags); |
1371 | } | 1328 | } |
@@ -1392,17 +1349,7 @@ static void garmin_read_int_callback(struct urb *urb) | |||
1392 | __func__, garmin_data_p->serial_num); | 1349 | __func__, garmin_data_p->serial_num); |
1393 | } | 1350 | } |
1394 | 1351 | ||
1395 | if (garmin_data_p->ignorePkts) { | 1352 | garmin_read_process(garmin_data_p, data, urb->actual_length); |
1396 | /* this reply belongs to a request generated by the driver, | ||
1397 | ignore it. */ | ||
1398 | dbg("%s - pkt ignored (%d)", | ||
1399 | __func__, garmin_data_p->ignorePkts); | ||
1400 | spin_lock_irqsave(&garmin_data_p->lock, flags); | ||
1401 | garmin_data_p->ignorePkts--; | ||
1402 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
1403 | } else { | ||
1404 | garmin_read_process(garmin_data_p, data, urb->actual_length); | ||
1405 | } | ||
1406 | 1353 | ||
1407 | port->interrupt_in_urb->dev = port->serial->dev; | 1354 | port->interrupt_in_urb->dev = port->serial->dev; |
1408 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 1355 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -1528,7 +1475,7 @@ static int garmin_attach(struct usb_serial *serial) | |||
1528 | } | 1475 | } |
1529 | 1476 | ||
1530 | 1477 | ||
1531 | static void garmin_shutdown(struct usb_serial *serial) | 1478 | static void garmin_disconnect(struct usb_serial *serial) |
1532 | { | 1479 | { |
1533 | struct usb_serial_port *port = serial->port[0]; | 1480 | struct usb_serial_port *port = serial->port[0]; |
1534 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); | 1481 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); |
@@ -1537,8 +1484,17 @@ static void garmin_shutdown(struct usb_serial *serial) | |||
1537 | 1484 | ||
1538 | usb_kill_urb(port->interrupt_in_urb); | 1485 | usb_kill_urb(port->interrupt_in_urb); |
1539 | del_timer_sync(&garmin_data_p->timer); | 1486 | del_timer_sync(&garmin_data_p->timer); |
1487 | } | ||
1488 | |||
1489 | |||
1490 | static void garmin_release(struct usb_serial *serial) | ||
1491 | { | ||
1492 | struct usb_serial_port *port = serial->port[0]; | ||
1493 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); | ||
1494 | |||
1495 | dbg("%s", __func__); | ||
1496 | |||
1540 | kfree(garmin_data_p); | 1497 | kfree(garmin_data_p); |
1541 | usb_set_serial_port_data(port, NULL); | ||
1542 | } | 1498 | } |
1543 | 1499 | ||
1544 | 1500 | ||
@@ -1557,7 +1513,8 @@ static struct usb_serial_driver garmin_device = { | |||
1557 | .throttle = garmin_throttle, | 1513 | .throttle = garmin_throttle, |
1558 | .unthrottle = garmin_unthrottle, | 1514 | .unthrottle = garmin_unthrottle, |
1559 | .attach = garmin_attach, | 1515 | .attach = garmin_attach, |
1560 | .shutdown = garmin_shutdown, | 1516 | .disconnect = garmin_disconnect, |
1517 | .release = garmin_release, | ||
1561 | .write = garmin_write, | 1518 | .write = garmin_write, |
1562 | .write_room = garmin_write_room, | 1519 | .write_room = garmin_write_room, |
1563 | .write_bulk_callback = garmin_write_bulk_callback, | 1520 | .write_bulk_callback = garmin_write_bulk_callback, |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 4cec9906ccf3..932d6241b787 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -63,7 +63,8 @@ struct usb_serial_driver usb_serial_generic_device = { | |||
63 | .id_table = generic_device_ids, | 63 | .id_table = generic_device_ids, |
64 | .usb_driver = &generic_driver, | 64 | .usb_driver = &generic_driver, |
65 | .num_ports = 1, | 65 | .num_ports = 1, |
66 | .shutdown = usb_serial_generic_shutdown, | 66 | .disconnect = usb_serial_generic_disconnect, |
67 | .release = usb_serial_generic_release, | ||
67 | .throttle = usb_serial_generic_throttle, | 68 | .throttle = usb_serial_generic_throttle, |
68 | .unthrottle = usb_serial_generic_unthrottle, | 69 | .unthrottle = usb_serial_generic_unthrottle, |
69 | .resume = usb_serial_generic_resume, | 70 | .resume = usb_serial_generic_resume, |
@@ -184,13 +185,94 @@ int usb_serial_generic_resume(struct usb_serial *serial) | |||
184 | } | 185 | } |
185 | EXPORT_SYMBOL_GPL(usb_serial_generic_resume); | 186 | EXPORT_SYMBOL_GPL(usb_serial_generic_resume); |
186 | 187 | ||
187 | void usb_serial_generic_close(struct tty_struct *tty, | 188 | void usb_serial_generic_close(struct usb_serial_port *port) |
188 | struct usb_serial_port *port, struct file *filp) | ||
189 | { | 189 | { |
190 | dbg("%s - port %d", __func__, port->number); | 190 | dbg("%s - port %d", __func__, port->number); |
191 | generic_cleanup(port); | 191 | generic_cleanup(port); |
192 | } | 192 | } |
193 | 193 | ||
194 | static int usb_serial_multi_urb_write(struct tty_struct *tty, | ||
195 | struct usb_serial_port *port, const unsigned char *buf, int count) | ||
196 | { | ||
197 | unsigned long flags; | ||
198 | struct urb *urb; | ||
199 | unsigned char *buffer; | ||
200 | int status; | ||
201 | int towrite; | ||
202 | int bwrite = 0; | ||
203 | |||
204 | dbg("%s - port %d", __func__, port->number); | ||
205 | |||
206 | if (count == 0) | ||
207 | dbg("%s - write request of 0 bytes", __func__); | ||
208 | |||
209 | while (count > 0) { | ||
210 | towrite = (count > port->bulk_out_size) ? | ||
211 | port->bulk_out_size : count; | ||
212 | spin_lock_irqsave(&port->lock, flags); | ||
213 | if (port->urbs_in_flight > | ||
214 | port->serial->type->max_in_flight_urbs) { | ||
215 | spin_unlock_irqrestore(&port->lock, flags); | ||
216 | dbg("%s - write limit hit\n", __func__); | ||
217 | return bwrite; | ||
218 | } | ||
219 | port->tx_bytes_flight += towrite; | ||
220 | port->urbs_in_flight++; | ||
221 | spin_unlock_irqrestore(&port->lock, flags); | ||
222 | |||
223 | buffer = kmalloc(towrite, GFP_ATOMIC); | ||
224 | if (!buffer) { | ||
225 | dev_err(&port->dev, | ||
226 | "%s ran out of kernel memory for urb ...\n", __func__); | ||
227 | goto error_no_buffer; | ||
228 | } | ||
229 | |||
230 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
231 | if (!urb) { | ||
232 | dev_err(&port->dev, "%s - no more free urbs\n", | ||
233 | __func__); | ||
234 | goto error_no_urb; | ||
235 | } | ||
236 | |||
237 | /* Copy data */ | ||
238 | memcpy(buffer, buf + bwrite, towrite); | ||
239 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
240 | towrite, buffer); | ||
241 | /* fill the buffer and send it */ | ||
242 | usb_fill_bulk_urb(urb, port->serial->dev, | ||
243 | usb_sndbulkpipe(port->serial->dev, | ||
244 | port->bulk_out_endpointAddress), | ||
245 | buffer, towrite, | ||
246 | usb_serial_generic_write_bulk_callback, port); | ||
247 | |||
248 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
249 | if (status) { | ||
250 | dev_err(&port->dev, | ||
251 | "%s - failed submitting write urb, error %d\n", | ||
252 | __func__, status); | ||
253 | goto error; | ||
254 | } | ||
255 | |||
256 | /* This urb is the responsibility of the host driver now */ | ||
257 | usb_free_urb(urb); | ||
258 | dbg("%s write: %d", __func__, towrite); | ||
259 | count -= towrite; | ||
260 | bwrite += towrite; | ||
261 | } | ||
262 | return bwrite; | ||
263 | |||
264 | error: | ||
265 | usb_free_urb(urb); | ||
266 | error_no_urb: | ||
267 | kfree(buffer); | ||
268 | error_no_buffer: | ||
269 | spin_lock_irqsave(&port->lock, flags); | ||
270 | port->urbs_in_flight--; | ||
271 | port->tx_bytes_flight -= towrite; | ||
272 | spin_unlock_irqrestore(&port->lock, flags); | ||
273 | return bwrite; | ||
274 | } | ||
275 | |||
194 | int usb_serial_generic_write(struct tty_struct *tty, | 276 | int usb_serial_generic_write(struct tty_struct *tty, |
195 | struct usb_serial_port *port, const unsigned char *buf, int count) | 277 | struct usb_serial_port *port, const unsigned char *buf, int count) |
196 | { | 278 | { |
@@ -208,6 +290,11 @@ int usb_serial_generic_write(struct tty_struct *tty, | |||
208 | /* only do something if we have a bulk out endpoint */ | 290 | /* only do something if we have a bulk out endpoint */ |
209 | if (serial->num_bulk_out) { | 291 | if (serial->num_bulk_out) { |
210 | unsigned long flags; | 292 | unsigned long flags; |
293 | |||
294 | if (serial->type->max_in_flight_urbs) | ||
295 | return usb_serial_multi_urb_write(tty, port, | ||
296 | buf, count); | ||
297 | |||
211 | spin_lock_irqsave(&port->lock, flags); | 298 | spin_lock_irqsave(&port->lock, flags); |
212 | if (port->write_urb_busy) { | 299 | if (port->write_urb_busy) { |
213 | spin_unlock_irqrestore(&port->lock, flags); | 300 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -253,20 +340,26 @@ int usb_serial_generic_write(struct tty_struct *tty, | |||
253 | /* no bulk out, so return 0 bytes written */ | 340 | /* no bulk out, so return 0 bytes written */ |
254 | return 0; | 341 | return 0; |
255 | } | 342 | } |
343 | EXPORT_SYMBOL_GPL(usb_serial_generic_write); | ||
256 | 344 | ||
257 | int usb_serial_generic_write_room(struct tty_struct *tty) | 345 | int usb_serial_generic_write_room(struct tty_struct *tty) |
258 | { | 346 | { |
259 | struct usb_serial_port *port = tty->driver_data; | 347 | struct usb_serial_port *port = tty->driver_data; |
260 | struct usb_serial *serial = port->serial; | 348 | struct usb_serial *serial = port->serial; |
349 | unsigned long flags; | ||
261 | int room = 0; | 350 | int room = 0; |
262 | 351 | ||
263 | dbg("%s - port %d", __func__, port->number); | 352 | dbg("%s - port %d", __func__, port->number); |
264 | 353 | spin_lock_irqsave(&port->lock, flags); | |
265 | /* FIXME: Locking */ | 354 | if (serial->type->max_in_flight_urbs) { |
266 | if (serial->num_bulk_out) { | 355 | if (port->urbs_in_flight < serial->type->max_in_flight_urbs) |
267 | if (!(port->write_urb_busy)) | 356 | room = port->bulk_out_size * |
268 | room = port->bulk_out_size; | 357 | (serial->type->max_in_flight_urbs - |
358 | port->urbs_in_flight); | ||
359 | } else if (serial->num_bulk_out && !(port->write_urb_busy)) { | ||
360 | room = port->bulk_out_size; | ||
269 | } | 361 | } |
362 | spin_unlock_irqrestore(&port->lock, flags); | ||
270 | 363 | ||
271 | dbg("%s - returns %d", __func__, room); | 364 | dbg("%s - returns %d", __func__, room); |
272 | return room; | 365 | return room; |
@@ -277,11 +370,16 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) | |||
277 | struct usb_serial_port *port = tty->driver_data; | 370 | struct usb_serial_port *port = tty->driver_data; |
278 | struct usb_serial *serial = port->serial; | 371 | struct usb_serial *serial = port->serial; |
279 | int chars = 0; | 372 | int chars = 0; |
373 | unsigned long flags; | ||
280 | 374 | ||
281 | dbg("%s - port %d", __func__, port->number); | 375 | dbg("%s - port %d", __func__, port->number); |
282 | 376 | ||
283 | /* FIXME: Locking */ | 377 | if (serial->type->max_in_flight_urbs) { |
284 | if (serial->num_bulk_out) { | 378 | spin_lock_irqsave(&port->lock, flags); |
379 | chars = port->tx_bytes_flight; | ||
380 | spin_unlock_irqrestore(&port->lock, flags); | ||
381 | } else if (serial->num_bulk_out) { | ||
382 | /* FIXME: Locking */ | ||
285 | if (port->write_urb_busy) | 383 | if (port->write_urb_busy) |
286 | chars = port->write_urb->transfer_buffer_length; | 384 | chars = port->write_urb->transfer_buffer_length; |
287 | } | 385 | } |
@@ -291,7 +389,8 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) | |||
291 | } | 389 | } |
292 | 390 | ||
293 | 391 | ||
294 | static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) | 392 | void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port, |
393 | gfp_t mem_flags) | ||
295 | { | 394 | { |
296 | struct urb *urb = port->read_urb; | 395 | struct urb *urb = port->read_urb; |
297 | struct usb_serial *serial = port->serial; | 396 | struct usb_serial *serial = port->serial; |
@@ -312,25 +411,28 @@ static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) | |||
312 | "%s - failed resubmitting read urb, error %d\n", | 411 | "%s - failed resubmitting read urb, error %d\n", |
313 | __func__, result); | 412 | __func__, result); |
314 | } | 413 | } |
414 | EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb); | ||
315 | 415 | ||
316 | /* Push data to tty layer and resubmit the bulk read URB */ | 416 | /* Push data to tty layer and resubmit the bulk read URB */ |
317 | static void flush_and_resubmit_read_urb(struct usb_serial_port *port) | 417 | static void flush_and_resubmit_read_urb(struct usb_serial_port *port) |
318 | { | 418 | { |
319 | struct urb *urb = port->read_urb; | 419 | struct urb *urb = port->read_urb; |
320 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 420 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
321 | int room; | 421 | char *ch = (char *)urb->transfer_buffer; |
422 | int i; | ||
423 | |||
424 | if (!tty) | ||
425 | goto done; | ||
322 | 426 | ||
323 | /* Push data to tty */ | 427 | /* Push data to tty */ |
324 | if (tty && urb->actual_length) { | 428 | for (i = 0; i < urb->actual_length; i++, ch++) { |
325 | room = tty_buffer_request_room(tty, urb->actual_length); | 429 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
326 | if (room) { | 430 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); |
327 | tty_insert_flip_string(tty, urb->transfer_buffer, room); | ||
328 | tty_flip_buffer_push(tty); | ||
329 | } | ||
330 | } | 431 | } |
432 | tty_flip_buffer_push(tty); | ||
331 | tty_kref_put(tty); | 433 | tty_kref_put(tty); |
332 | 434 | done: | |
333 | resubmit_read_urb(port, GFP_ATOMIC); | 435 | usb_serial_generic_resubmit_read_urb(port, GFP_ATOMIC); |
334 | } | 436 | } |
335 | 437 | ||
336 | void usb_serial_generic_read_bulk_callback(struct urb *urb) | 438 | void usb_serial_generic_read_bulk_callback(struct urb *urb) |
@@ -364,12 +466,24 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); | |||
364 | 466 | ||
365 | void usb_serial_generic_write_bulk_callback(struct urb *urb) | 467 | void usb_serial_generic_write_bulk_callback(struct urb *urb) |
366 | { | 468 | { |
469 | unsigned long flags; | ||
367 | struct usb_serial_port *port = urb->context; | 470 | struct usb_serial_port *port = urb->context; |
368 | int status = urb->status; | 471 | int status = urb->status; |
369 | 472 | ||
370 | dbg("%s - port %d", __func__, port->number); | 473 | dbg("%s - port %d", __func__, port->number); |
371 | 474 | ||
372 | port->write_urb_busy = 0; | 475 | if (port->serial->type->max_in_flight_urbs) { |
476 | spin_lock_irqsave(&port->lock, flags); | ||
477 | --port->urbs_in_flight; | ||
478 | port->tx_bytes_flight -= urb->transfer_buffer_length; | ||
479 | if (port->urbs_in_flight < 0) | ||
480 | port->urbs_in_flight = 0; | ||
481 | spin_unlock_irqrestore(&port->lock, flags); | ||
482 | } else { | ||
483 | /* Handle the case for single urb mode */ | ||
484 | port->write_urb_busy = 0; | ||
485 | } | ||
486 | |||
373 | if (status) { | 487 | if (status) { |
374 | dbg("%s - nonzero write bulk status received: %d", | 488 | dbg("%s - nonzero write bulk status received: %d", |
375 | __func__, status); | 489 | __func__, status); |
@@ -409,11 +523,36 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty) | |||
409 | 523 | ||
410 | if (was_throttled) { | 524 | if (was_throttled) { |
411 | /* Resume reading from device */ | 525 | /* Resume reading from device */ |
412 | resubmit_read_urb(port, GFP_KERNEL); | 526 | usb_serial_generic_resubmit_read_urb(port, GFP_KERNEL); |
527 | } | ||
528 | } | ||
529 | |||
530 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) | ||
531 | { | ||
532 | if (port->sysrq && port->console) { | ||
533 | if (ch && time_before(jiffies, port->sysrq)) { | ||
534 | handle_sysrq(ch, tty_port_tty_get(&port->port)); | ||
535 | port->sysrq = 0; | ||
536 | return 1; | ||
537 | } | ||
538 | port->sysrq = 0; | ||
539 | } | ||
540 | return 0; | ||
541 | } | ||
542 | EXPORT_SYMBOL_GPL(usb_serial_handle_sysrq_char); | ||
543 | |||
544 | int usb_serial_handle_break(struct usb_serial_port *port) | ||
545 | { | ||
546 | if (!port->sysrq) { | ||
547 | port->sysrq = jiffies + HZ*5; | ||
548 | return 1; | ||
413 | } | 549 | } |
550 | port->sysrq = 0; | ||
551 | return 0; | ||
414 | } | 552 | } |
553 | EXPORT_SYMBOL_GPL(usb_serial_handle_break); | ||
415 | 554 | ||
416 | void usb_serial_generic_shutdown(struct usb_serial *serial) | 555 | void usb_serial_generic_disconnect(struct usb_serial *serial) |
417 | { | 556 | { |
418 | int i; | 557 | int i; |
419 | 558 | ||
@@ -424,3 +563,7 @@ void usb_serial_generic_shutdown(struct usb_serial *serial) | |||
424 | generic_cleanup(serial->port[i]); | 563 | generic_cleanup(serial->port[i]); |
425 | } | 564 | } |
426 | 565 | ||
566 | void usb_serial_generic_release(struct usb_serial *serial) | ||
567 | { | ||
568 | dbg("%s", __func__); | ||
569 | } | ||
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index fb4a73d090f6..0191693625d6 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -207,8 +207,7 @@ static void edge_bulk_out_cmd_callback(struct urb *urb); | |||
207 | /* function prototypes for the usbserial callbacks */ | 207 | /* function prototypes for the usbserial callbacks */ |
208 | static int edge_open(struct tty_struct *tty, struct usb_serial_port *port, | 208 | static int edge_open(struct tty_struct *tty, struct usb_serial_port *port, |
209 | struct file *filp); | 209 | struct file *filp); |
210 | static void edge_close(struct tty_struct *tty, struct usb_serial_port *port, | 210 | static void edge_close(struct usb_serial_port *port); |
211 | struct file *filp); | ||
212 | static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, | 211 | static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, |
213 | const unsigned char *buf, int count); | 212 | const unsigned char *buf, int count); |
214 | static int edge_write_room(struct tty_struct *tty); | 213 | static int edge_write_room(struct tty_struct *tty); |
@@ -225,7 +224,8 @@ static int edge_tiocmget(struct tty_struct *tty, struct file *file); | |||
225 | static int edge_tiocmset(struct tty_struct *tty, struct file *file, | 224 | static int edge_tiocmset(struct tty_struct *tty, struct file *file, |
226 | unsigned int set, unsigned int clear); | 225 | unsigned int set, unsigned int clear); |
227 | static int edge_startup(struct usb_serial *serial); | 226 | static int edge_startup(struct usb_serial *serial); |
228 | static void edge_shutdown(struct usb_serial *serial); | 227 | static void edge_disconnect(struct usb_serial *serial); |
228 | static void edge_release(struct usb_serial *serial); | ||
229 | 229 | ||
230 | #include "io_tables.h" /* all of the devices that this driver supports */ | 230 | #include "io_tables.h" /* all of the devices that this driver supports */ |
231 | 231 | ||
@@ -965,7 +965,7 @@ static int edge_open(struct tty_struct *tty, | |||
965 | 965 | ||
966 | if (!edge_port->txfifo.fifo) { | 966 | if (!edge_port->txfifo.fifo) { |
967 | dbg("%s - no memory", __func__); | 967 | dbg("%s - no memory", __func__); |
968 | edge_close(tty, port, filp); | 968 | edge_close(port); |
969 | return -ENOMEM; | 969 | return -ENOMEM; |
970 | } | 970 | } |
971 | 971 | ||
@@ -975,7 +975,7 @@ static int edge_open(struct tty_struct *tty, | |||
975 | 975 | ||
976 | if (!edge_port->write_urb) { | 976 | if (!edge_port->write_urb) { |
977 | dbg("%s - no memory", __func__); | 977 | dbg("%s - no memory", __func__); |
978 | edge_close(tty, port, filp); | 978 | edge_close(port); |
979 | return -ENOMEM; | 979 | return -ENOMEM; |
980 | } | 980 | } |
981 | 981 | ||
@@ -1099,8 +1099,7 @@ static void block_until_tx_empty(struct edgeport_port *edge_port) | |||
1099 | * edge_close | 1099 | * edge_close |
1100 | * this function is called by the tty driver when a port is closed | 1100 | * this function is called by the tty driver when a port is closed |
1101 | *****************************************************************************/ | 1101 | *****************************************************************************/ |
1102 | static void edge_close(struct tty_struct *tty, | 1102 | static void edge_close(struct usb_serial_port *port) |
1103 | struct usb_serial_port *port, struct file *filp) | ||
1104 | { | 1103 | { |
1105 | struct edgeport_serial *edge_serial; | 1104 | struct edgeport_serial *edge_serial; |
1106 | struct edgeport_port *edge_port; | 1105 | struct edgeport_port *edge_port; |
@@ -3195,21 +3194,16 @@ static int edge_startup(struct usb_serial *serial) | |||
3195 | 3194 | ||
3196 | 3195 | ||
3197 | /**************************************************************************** | 3196 | /**************************************************************************** |
3198 | * edge_shutdown | 3197 | * edge_disconnect |
3199 | * This function is called whenever the device is removed from the usb bus. | 3198 | * This function is called whenever the device is removed from the usb bus. |
3200 | ****************************************************************************/ | 3199 | ****************************************************************************/ |
3201 | static void edge_shutdown(struct usb_serial *serial) | 3200 | static void edge_disconnect(struct usb_serial *serial) |
3202 | { | 3201 | { |
3203 | struct edgeport_serial *edge_serial = usb_get_serial_data(serial); | 3202 | struct edgeport_serial *edge_serial = usb_get_serial_data(serial); |
3204 | int i; | ||
3205 | 3203 | ||
3206 | dbg("%s", __func__); | 3204 | dbg("%s", __func__); |
3207 | 3205 | ||
3208 | /* stop reads and writes on all ports */ | 3206 | /* stop reads and writes on all ports */ |
3209 | for (i = 0; i < serial->num_ports; ++i) { | ||
3210 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
3211 | usb_set_serial_port_data(serial->port[i], NULL); | ||
3212 | } | ||
3213 | /* free up our endpoint stuff */ | 3207 | /* free up our endpoint stuff */ |
3214 | if (edge_serial->is_epic) { | 3208 | if (edge_serial->is_epic) { |
3215 | usb_kill_urb(edge_serial->interrupt_read_urb); | 3209 | usb_kill_urb(edge_serial->interrupt_read_urb); |
@@ -3220,9 +3214,24 @@ static void edge_shutdown(struct usb_serial *serial) | |||
3220 | usb_free_urb(edge_serial->read_urb); | 3214 | usb_free_urb(edge_serial->read_urb); |
3221 | kfree(edge_serial->bulk_in_buffer); | 3215 | kfree(edge_serial->bulk_in_buffer); |
3222 | } | 3216 | } |
3217 | } | ||
3218 | |||
3219 | |||
3220 | /**************************************************************************** | ||
3221 | * edge_release | ||
3222 | * This function is called when the device structure is deallocated. | ||
3223 | ****************************************************************************/ | ||
3224 | static void edge_release(struct usb_serial *serial) | ||
3225 | { | ||
3226 | struct edgeport_serial *edge_serial = usb_get_serial_data(serial); | ||
3227 | int i; | ||
3228 | |||
3229 | dbg("%s", __func__); | ||
3230 | |||
3231 | for (i = 0; i < serial->num_ports; ++i) | ||
3232 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
3223 | 3233 | ||
3224 | kfree(edge_serial); | 3234 | kfree(edge_serial); |
3225 | usb_set_serial_data(serial, NULL); | ||
3226 | } | 3235 | } |
3227 | 3236 | ||
3228 | 3237 | ||
diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index 7eb9d67b81b6..9241d3147513 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h | |||
@@ -117,7 +117,8 @@ static struct usb_serial_driver edgeport_2port_device = { | |||
117 | .throttle = edge_throttle, | 117 | .throttle = edge_throttle, |
118 | .unthrottle = edge_unthrottle, | 118 | .unthrottle = edge_unthrottle, |
119 | .attach = edge_startup, | 119 | .attach = edge_startup, |
120 | .shutdown = edge_shutdown, | 120 | .disconnect = edge_disconnect, |
121 | .release = edge_release, | ||
121 | .ioctl = edge_ioctl, | 122 | .ioctl = edge_ioctl, |
122 | .set_termios = edge_set_termios, | 123 | .set_termios = edge_set_termios, |
123 | .tiocmget = edge_tiocmget, | 124 | .tiocmget = edge_tiocmget, |
@@ -145,7 +146,8 @@ static struct usb_serial_driver edgeport_4port_device = { | |||
145 | .throttle = edge_throttle, | 146 | .throttle = edge_throttle, |
146 | .unthrottle = edge_unthrottle, | 147 | .unthrottle = edge_unthrottle, |
147 | .attach = edge_startup, | 148 | .attach = edge_startup, |
148 | .shutdown = edge_shutdown, | 149 | .disconnect = edge_disconnect, |
150 | .release = edge_release, | ||
149 | .ioctl = edge_ioctl, | 151 | .ioctl = edge_ioctl, |
150 | .set_termios = edge_set_termios, | 152 | .set_termios = edge_set_termios, |
151 | .tiocmget = edge_tiocmget, | 153 | .tiocmget = edge_tiocmget, |
@@ -173,7 +175,8 @@ static struct usb_serial_driver edgeport_8port_device = { | |||
173 | .throttle = edge_throttle, | 175 | .throttle = edge_throttle, |
174 | .unthrottle = edge_unthrottle, | 176 | .unthrottle = edge_unthrottle, |
175 | .attach = edge_startup, | 177 | .attach = edge_startup, |
176 | .shutdown = edge_shutdown, | 178 | .disconnect = edge_disconnect, |
179 | .release = edge_release, | ||
177 | .ioctl = edge_ioctl, | 180 | .ioctl = edge_ioctl, |
178 | .set_termios = edge_set_termios, | 181 | .set_termios = edge_set_termios, |
179 | .tiocmget = edge_tiocmget, | 182 | .tiocmget = edge_tiocmget, |
@@ -200,7 +203,8 @@ static struct usb_serial_driver epic_device = { | |||
200 | .throttle = edge_throttle, | 203 | .throttle = edge_throttle, |
201 | .unthrottle = edge_unthrottle, | 204 | .unthrottle = edge_unthrottle, |
202 | .attach = edge_startup, | 205 | .attach = edge_startup, |
203 | .shutdown = edge_shutdown, | 206 | .disconnect = edge_disconnect, |
207 | .release = edge_release, | ||
204 | .ioctl = edge_ioctl, | 208 | .ioctl = edge_ioctl, |
205 | .set_termios = edge_set_termios, | 209 | .set_termios = edge_set_termios, |
206 | .tiocmget = edge_tiocmget, | 210 | .tiocmget = edge_tiocmget, |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 513b25e044c1..e8bc42f92e79 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -102,7 +102,7 @@ struct edgeport_port { | |||
102 | __u8 shadow_mcr; | 102 | __u8 shadow_mcr; |
103 | __u8 shadow_lsr; | 103 | __u8 shadow_lsr; |
104 | __u8 lsr_mask; | 104 | __u8 lsr_mask; |
105 | __u32 ump_read_timeout; /* Number of miliseconds the UMP will | 105 | __u32 ump_read_timeout; /* Number of milliseconds the UMP will |
106 | wait without data before completing | 106 | wait without data before completing |
107 | a read short */ | 107 | a read short */ |
108 | int baud_rate; | 108 | int baud_rate; |
@@ -2009,8 +2009,7 @@ release_es_lock: | |||
2009 | return status; | 2009 | return status; |
2010 | } | 2010 | } |
2011 | 2011 | ||
2012 | static void edge_close(struct tty_struct *tty, | 2012 | static void edge_close(struct usb_serial_port *port) |
2013 | struct usb_serial_port *port, struct file *filp) | ||
2014 | { | 2013 | { |
2015 | struct edgeport_serial *edge_serial; | 2014 | struct edgeport_serial *edge_serial; |
2016 | struct edgeport_port *edge_port; | 2015 | struct edgeport_port *edge_port; |
@@ -2664,7 +2663,7 @@ cleanup: | |||
2664 | return -ENOMEM; | 2663 | return -ENOMEM; |
2665 | } | 2664 | } |
2666 | 2665 | ||
2667 | static void edge_shutdown(struct usb_serial *serial) | 2666 | static void edge_disconnect(struct usb_serial *serial) |
2668 | { | 2667 | { |
2669 | int i; | 2668 | int i; |
2670 | struct edgeport_port *edge_port; | 2669 | struct edgeport_port *edge_port; |
@@ -2674,12 +2673,22 @@ static void edge_shutdown(struct usb_serial *serial) | |||
2674 | for (i = 0; i < serial->num_ports; ++i) { | 2673 | for (i = 0; i < serial->num_ports; ++i) { |
2675 | edge_port = usb_get_serial_port_data(serial->port[i]); | 2674 | edge_port = usb_get_serial_port_data(serial->port[i]); |
2676 | edge_remove_sysfs_attrs(edge_port->port); | 2675 | edge_remove_sysfs_attrs(edge_port->port); |
2676 | } | ||
2677 | } | ||
2678 | |||
2679 | static void edge_release(struct usb_serial *serial) | ||
2680 | { | ||
2681 | int i; | ||
2682 | struct edgeport_port *edge_port; | ||
2683 | |||
2684 | dbg("%s", __func__); | ||
2685 | |||
2686 | for (i = 0; i < serial->num_ports; ++i) { | ||
2687 | edge_port = usb_get_serial_port_data(serial->port[i]); | ||
2677 | edge_buf_free(edge_port->ep_out_buf); | 2688 | edge_buf_free(edge_port->ep_out_buf); |
2678 | kfree(edge_port); | 2689 | kfree(edge_port); |
2679 | usb_set_serial_port_data(serial->port[i], NULL); | ||
2680 | } | 2690 | } |
2681 | kfree(usb_get_serial_data(serial)); | 2691 | kfree(usb_get_serial_data(serial)); |
2682 | usb_set_serial_data(serial, NULL); | ||
2683 | } | 2692 | } |
2684 | 2693 | ||
2685 | 2694 | ||
@@ -2916,7 +2925,8 @@ static struct usb_serial_driver edgeport_1port_device = { | |||
2916 | .throttle = edge_throttle, | 2925 | .throttle = edge_throttle, |
2917 | .unthrottle = edge_unthrottle, | 2926 | .unthrottle = edge_unthrottle, |
2918 | .attach = edge_startup, | 2927 | .attach = edge_startup, |
2919 | .shutdown = edge_shutdown, | 2928 | .disconnect = edge_disconnect, |
2929 | .release = edge_release, | ||
2920 | .port_probe = edge_create_sysfs_attrs, | 2930 | .port_probe = edge_create_sysfs_attrs, |
2921 | .ioctl = edge_ioctl, | 2931 | .ioctl = edge_ioctl, |
2922 | .set_termios = edge_set_termios, | 2932 | .set_termios = edge_set_termios, |
@@ -2945,7 +2955,8 @@ static struct usb_serial_driver edgeport_2port_device = { | |||
2945 | .throttle = edge_throttle, | 2955 | .throttle = edge_throttle, |
2946 | .unthrottle = edge_unthrottle, | 2956 | .unthrottle = edge_unthrottle, |
2947 | .attach = edge_startup, | 2957 | .attach = edge_startup, |
2948 | .shutdown = edge_shutdown, | 2958 | .disconnect = edge_disconnect, |
2959 | .release = edge_release, | ||
2949 | .port_probe = edge_create_sysfs_attrs, | 2960 | .port_probe = edge_create_sysfs_attrs, |
2950 | .ioctl = edge_ioctl, | 2961 | .ioctl = edge_ioctl, |
2951 | .set_termios = edge_set_termios, | 2962 | .set_termios = edge_set_termios, |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index cd62825a9ac3..2545d45ce16f 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -76,11 +76,9 @@ static int initial_wait; | |||
76 | /* Function prototypes for an ipaq */ | 76 | /* Function prototypes for an ipaq */ |
77 | static int ipaq_open(struct tty_struct *tty, | 77 | static int ipaq_open(struct tty_struct *tty, |
78 | struct usb_serial_port *port, struct file *filp); | 78 | struct usb_serial_port *port, struct file *filp); |
79 | static void ipaq_close(struct tty_struct *tty, | 79 | static void ipaq_close(struct usb_serial_port *port); |
80 | struct usb_serial_port *port, struct file *filp); | ||
81 | static int ipaq_calc_num_ports(struct usb_serial *serial); | 80 | static int ipaq_calc_num_ports(struct usb_serial *serial); |
82 | static int ipaq_startup(struct usb_serial *serial); | 81 | static int ipaq_startup(struct usb_serial *serial); |
83 | static void ipaq_shutdown(struct usb_serial *serial); | ||
84 | static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, | 82 | static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, |
85 | const unsigned char *buf, int count); | 83 | const unsigned char *buf, int count); |
86 | static int ipaq_write_bulk(struct usb_serial_port *port, | 84 | static int ipaq_write_bulk(struct usb_serial_port *port, |
@@ -577,7 +575,6 @@ static struct usb_serial_driver ipaq_device = { | |||
577 | .close = ipaq_close, | 575 | .close = ipaq_close, |
578 | .attach = ipaq_startup, | 576 | .attach = ipaq_startup, |
579 | .calc_num_ports = ipaq_calc_num_ports, | 577 | .calc_num_ports = ipaq_calc_num_ports, |
580 | .shutdown = ipaq_shutdown, | ||
581 | .write = ipaq_write, | 578 | .write = ipaq_write, |
582 | .write_room = ipaq_write_room, | 579 | .write_room = ipaq_write_room, |
583 | .chars_in_buffer = ipaq_chars_in_buffer, | 580 | .chars_in_buffer = ipaq_chars_in_buffer, |
@@ -714,8 +711,7 @@ error: | |||
714 | } | 711 | } |
715 | 712 | ||
716 | 713 | ||
717 | static void ipaq_close(struct tty_struct *tty, | 714 | static void ipaq_close(struct usb_serial_port *port) |
718 | struct usb_serial_port *port, struct file *filp) | ||
719 | { | 715 | { |
720 | struct ipaq_private *priv = usb_get_serial_port_data(port); | 716 | struct ipaq_private *priv = usb_get_serial_port_data(port); |
721 | 717 | ||
@@ -992,11 +988,6 @@ static int ipaq_startup(struct usb_serial *serial) | |||
992 | return usb_reset_configuration(serial->dev); | 988 | return usb_reset_configuration(serial->dev); |
993 | } | 989 | } |
994 | 990 | ||
995 | static void ipaq_shutdown(struct usb_serial *serial) | ||
996 | { | ||
997 | dbg("%s", __func__); | ||
998 | } | ||
999 | |||
1000 | static int __init ipaq_init(void) | 991 | static int __init ipaq_init(void) |
1001 | { | 992 | { |
1002 | int retval; | 993 | int retval; |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index da2a2b46644a..29ad038b9c8d 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -302,23 +302,17 @@ static int ipw_open(struct tty_struct *tty, | |||
302 | return 0; | 302 | return 0; |
303 | } | 303 | } |
304 | 304 | ||
305 | static void ipw_close(struct tty_struct *tty, | 305 | static void ipw_dtr_rts(struct usb_serial_port *port, int on) |
306 | struct usb_serial_port *port, struct file *filp) | ||
307 | { | 306 | { |
308 | struct usb_device *dev = port->serial->dev; | 307 | struct usb_device *dev = port->serial->dev; |
309 | int result; | 308 | int result; |
310 | 309 | ||
311 | if (tty_hung_up_p(filp)) { | ||
312 | dbg("%s: tty_hung_up_p ...", __func__); | ||
313 | return; | ||
314 | } | ||
315 | |||
316 | /*--1: drop the dtr */ | 310 | /*--1: drop the dtr */ |
317 | dbg("%s:dropping dtr", __func__); | 311 | dbg("%s:dropping dtr", __func__); |
318 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 312 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
319 | IPW_SIO_SET_PIN, | 313 | IPW_SIO_SET_PIN, |
320 | USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, | 314 | USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, |
321 | IPW_PIN_CLRDTR, | 315 | on ? IPW_PIN_SETDTR : IPW_PIN_CLRDTR, |
322 | 0, | 316 | 0, |
323 | NULL, | 317 | NULL, |
324 | 0, | 318 | 0, |
@@ -332,7 +326,7 @@ static void ipw_close(struct tty_struct *tty, | |||
332 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 326 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
333 | IPW_SIO_SET_PIN, USB_TYPE_VENDOR | | 327 | IPW_SIO_SET_PIN, USB_TYPE_VENDOR | |
334 | USB_RECIP_INTERFACE | USB_DIR_OUT, | 328 | USB_RECIP_INTERFACE | USB_DIR_OUT, |
335 | IPW_PIN_CLRRTS, | 329 | on ? IPW_PIN_SETRTS : IPW_PIN_CLRRTS, |
336 | 0, | 330 | 0, |
337 | NULL, | 331 | NULL, |
338 | 0, | 332 | 0, |
@@ -340,7 +334,12 @@ static void ipw_close(struct tty_struct *tty, | |||
340 | if (result < 0) | 334 | if (result < 0) |
341 | dev_err(&port->dev, | 335 | dev_err(&port->dev, |
342 | "dropping rts failed (error = %d)\n", result); | 336 | "dropping rts failed (error = %d)\n", result); |
337 | } | ||
343 | 338 | ||
339 | static void ipw_close(struct usb_serial_port *port) | ||
340 | { | ||
341 | struct usb_device *dev = port->serial->dev; | ||
342 | int result; | ||
344 | 343 | ||
345 | /*--3: purge */ | 344 | /*--3: purge */ |
346 | dbg("%s:sending purge", __func__); | 345 | dbg("%s:sending purge", __func__); |
@@ -461,6 +460,7 @@ static struct usb_serial_driver ipw_device = { | |||
461 | .num_ports = 1, | 460 | .num_ports = 1, |
462 | .open = ipw_open, | 461 | .open = ipw_open, |
463 | .close = ipw_close, | 462 | .close = ipw_close, |
463 | .dtr_rts = ipw_dtr_rts, | ||
464 | .port_probe = ipw_probe, | 464 | .port_probe = ipw_probe, |
465 | .port_remove = ipw_disconnect, | 465 | .port_remove = ipw_disconnect, |
466 | .write = ipw_write, | 466 | .write = ipw_write, |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 4e2cda93da59..66009b6b763a 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -88,8 +88,7 @@ static int xbof = -1; | |||
88 | static int ir_startup (struct usb_serial *serial); | 88 | static int ir_startup (struct usb_serial *serial); |
89 | static int ir_open(struct tty_struct *tty, struct usb_serial_port *port, | 89 | static int ir_open(struct tty_struct *tty, struct usb_serial_port *port, |
90 | struct file *filep); | 90 | struct file *filep); |
91 | static void ir_close(struct tty_struct *tty, struct usb_serial_port *port, | 91 | static void ir_close(struct usb_serial_port *port); |
92 | struct file *filep); | ||
93 | static int ir_write(struct tty_struct *tty, struct usb_serial_port *port, | 92 | static int ir_write(struct tty_struct *tty, struct usb_serial_port *port, |
94 | const unsigned char *buf, int count); | 93 | const unsigned char *buf, int count); |
95 | static void ir_write_bulk_callback (struct urb *urb); | 94 | static void ir_write_bulk_callback (struct urb *urb); |
@@ -346,8 +345,7 @@ static int ir_open(struct tty_struct *tty, | |||
346 | return result; | 345 | return result; |
347 | } | 346 | } |
348 | 347 | ||
349 | static void ir_close(struct tty_struct *tty, | 348 | static void ir_close(struct usb_serial_port *port) |
350 | struct usb_serial_port *port, struct file * filp) | ||
351 | { | 349 | { |
352 | dbg("%s - port %d", __func__, port->number); | 350 | dbg("%s - port %d", __func__, port->number); |
353 | 351 | ||
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 4473d442b2aa..96873a7a32b0 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
@@ -40,7 +40,7 @@ static int debug; | |||
40 | /* | 40 | /* |
41 | * Version Information | 41 | * Version Information |
42 | */ | 42 | */ |
43 | #define DRIVER_VERSION "v0.5" | 43 | #define DRIVER_VERSION "v0.10" |
44 | #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" | 44 | #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" |
45 | 45 | ||
46 | static struct usb_device_id id_table[] = { | 46 | static struct usb_device_id id_table[] = { |
@@ -70,7 +70,6 @@ static void read_rxcmd_callback(struct urb *urb); | |||
70 | struct iuu_private { | 70 | struct iuu_private { |
71 | spinlock_t lock; /* store irq state */ | 71 | spinlock_t lock; /* store irq state */ |
72 | wait_queue_head_t delta_msr_wait; | 72 | wait_queue_head_t delta_msr_wait; |
73 | u8 line_control; | ||
74 | u8 line_status; | 73 | u8 line_status; |
75 | u8 termios_initialized; | 74 | u8 termios_initialized; |
76 | int tiostatus; /* store IUART SIGNAL for tiocmget call */ | 75 | int tiostatus; /* store IUART SIGNAL for tiocmget call */ |
@@ -122,8 +121,8 @@ static int iuu_startup(struct usb_serial *serial) | |||
122 | return 0; | 121 | return 0; |
123 | } | 122 | } |
124 | 123 | ||
125 | /* Shutdown function */ | 124 | /* Release function */ |
126 | static void iuu_shutdown(struct usb_serial *serial) | 125 | static void iuu_release(struct usb_serial *serial) |
127 | { | 126 | { |
128 | struct usb_serial_port *port = serial->port[0]; | 127 | struct usb_serial_port *port = serial->port[0]; |
129 | struct iuu_private *priv = usb_get_serial_port_data(port); | 128 | struct iuu_private *priv = usb_get_serial_port_data(port); |
@@ -651,32 +650,33 @@ static int iuu_bulk_write(struct usb_serial_port *port) | |||
651 | unsigned long flags; | 650 | unsigned long flags; |
652 | int result; | 651 | int result; |
653 | int i; | 652 | int i; |
653 | int buf_len; | ||
654 | char *buf_ptr = port->write_urb->transfer_buffer; | 654 | char *buf_ptr = port->write_urb->transfer_buffer; |
655 | dbg("%s - enter", __func__); | 655 | dbg("%s - enter", __func__); |
656 | 656 | ||
657 | spin_lock_irqsave(&priv->lock, flags); | ||
657 | *buf_ptr++ = IUU_UART_ESC; | 658 | *buf_ptr++ = IUU_UART_ESC; |
658 | *buf_ptr++ = IUU_UART_TX; | 659 | *buf_ptr++ = IUU_UART_TX; |
659 | *buf_ptr++ = priv->writelen; | 660 | *buf_ptr++ = priv->writelen; |
660 | 661 | ||
661 | memcpy(buf_ptr, priv->writebuf, | 662 | memcpy(buf_ptr, priv->writebuf, priv->writelen); |
662 | priv->writelen); | 663 | buf_len = priv->writelen; |
664 | priv->writelen = 0; | ||
665 | spin_unlock_irqrestore(&priv->lock, flags); | ||
663 | if (debug == 1) { | 666 | if (debug == 1) { |
664 | for (i = 0; i < priv->writelen; i++) | 667 | for (i = 0; i < buf_len; i++) |
665 | sprintf(priv->dbgbuf + i*2 , | 668 | sprintf(priv->dbgbuf + i*2 , |
666 | "%02X", priv->writebuf[i]); | 669 | "%02X", priv->writebuf[i]); |
667 | priv->dbgbuf[priv->writelen+i*2] = 0; | 670 | priv->dbgbuf[buf_len+i*2] = 0; |
668 | dbg("%s - writing %i chars : %s", __func__, | 671 | dbg("%s - writing %i chars : %s", __func__, |
669 | priv->writelen, priv->dbgbuf); | 672 | buf_len, priv->dbgbuf); |
670 | } | 673 | } |
671 | usb_fill_bulk_urb(port->write_urb, port->serial->dev, | 674 | usb_fill_bulk_urb(port->write_urb, port->serial->dev, |
672 | usb_sndbulkpipe(port->serial->dev, | 675 | usb_sndbulkpipe(port->serial->dev, |
673 | port->bulk_out_endpointAddress), | 676 | port->bulk_out_endpointAddress), |
674 | port->write_urb->transfer_buffer, priv->writelen + 3, | 677 | port->write_urb->transfer_buffer, buf_len + 3, |
675 | iuu_rxcmd, port); | 678 | iuu_rxcmd, port); |
676 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | 679 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); |
677 | spin_lock_irqsave(&priv->lock, flags); | ||
678 | priv->writelen = 0; | ||
679 | spin_unlock_irqrestore(&priv->lock, flags); | ||
680 | usb_serial_port_softint(port); | 680 | usb_serial_port_softint(port); |
681 | return result; | 681 | return result; |
682 | } | 682 | } |
@@ -770,14 +770,10 @@ static int iuu_uart_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
770 | return -ENOMEM; | 770 | return -ENOMEM; |
771 | 771 | ||
772 | spin_lock_irqsave(&priv->lock, flags); | 772 | spin_lock_irqsave(&priv->lock, flags); |
773 | if (priv->writelen > 0) { | 773 | |
774 | /* buffer already filled but not commited */ | ||
775 | spin_unlock_irqrestore(&priv->lock, flags); | ||
776 | return 0; | ||
777 | } | ||
778 | /* fill the buffer */ | 774 | /* fill the buffer */ |
779 | memcpy(priv->writebuf, buf, count); | 775 | memcpy(priv->writebuf + priv->writelen, buf, count); |
780 | priv->writelen = count; | 776 | priv->writelen += count; |
781 | spin_unlock_irqrestore(&priv->lock, flags); | 777 | spin_unlock_irqrestore(&priv->lock, flags); |
782 | 778 | ||
783 | return count; | 779 | return count; |
@@ -819,7 +815,7 @@ static int iuu_uart_on(struct usb_serial_port *port) | |||
819 | buf[0] = IUU_UART_ENABLE; | 815 | buf[0] = IUU_UART_ENABLE; |
820 | buf[1] = (u8) ((IUU_BAUD_9600 >> 8) & 0x00FF); | 816 | buf[1] = (u8) ((IUU_BAUD_9600 >> 8) & 0x00FF); |
821 | buf[2] = (u8) (0x00FF & IUU_BAUD_9600); | 817 | buf[2] = (u8) (0x00FF & IUU_BAUD_9600); |
822 | buf[3] = (u8) (0x0F0 & IUU_TWO_STOP_BITS) | (0x07 & IUU_PARITY_EVEN); | 818 | buf[3] = (u8) (0x0F0 & IUU_ONE_STOP_BIT) | (0x07 & IUU_PARITY_EVEN); |
823 | 819 | ||
824 | status = bulk_immediate(port, buf, 4); | 820 | status = bulk_immediate(port, buf, 4); |
825 | if (status != IUU_OPERATION_OK) { | 821 | if (status != IUU_OPERATION_OK) { |
@@ -946,19 +942,59 @@ static int iuu_uart_baud(struct usb_serial_port *port, u32 baud, | |||
946 | return status; | 942 | return status; |
947 | } | 943 | } |
948 | 944 | ||
949 | static int set_control_lines(struct usb_device *dev, u8 value) | 945 | static void iuu_set_termios(struct tty_struct *tty, |
946 | struct usb_serial_port *port, struct ktermios *old_termios) | ||
950 | { | 947 | { |
951 | return 0; | 948 | const u32 supported_mask = CMSPAR|PARENB|PARODD; |
949 | |||
950 | unsigned int cflag = tty->termios->c_cflag; | ||
951 | int status; | ||
952 | u32 actual; | ||
953 | u32 parity; | ||
954 | int csize = CS7; | ||
955 | int baud = 9600; /* Fixed for the moment */ | ||
956 | u32 newval = cflag & supported_mask; | ||
957 | |||
958 | /* compute the parity parameter */ | ||
959 | parity = 0; | ||
960 | if (cflag & CMSPAR) { /* Using mark space */ | ||
961 | if (cflag & PARODD) | ||
962 | parity |= IUU_PARITY_SPACE; | ||
963 | else | ||
964 | parity |= IUU_PARITY_MARK; | ||
965 | } else if (!(cflag & PARENB)) { | ||
966 | parity |= IUU_PARITY_NONE; | ||
967 | csize = CS8; | ||
968 | } else if (cflag & PARODD) | ||
969 | parity |= IUU_PARITY_ODD; | ||
970 | else | ||
971 | parity |= IUU_PARITY_EVEN; | ||
972 | |||
973 | parity |= (cflag & CSTOPB ? IUU_TWO_STOP_BITS : IUU_ONE_STOP_BIT); | ||
974 | |||
975 | /* set it */ | ||
976 | status = iuu_uart_baud(port, | ||
977 | (clockmode == 2) ? 16457 : 9600 * boost / 100, | ||
978 | &actual, parity); | ||
979 | |||
980 | /* set the termios value to the real one, so the user now what has | ||
981 | * changed. We support few fields so its easies to copy the old hw | ||
982 | * settings back over and then adjust them | ||
983 | */ | ||
984 | if (old_termios) | ||
985 | tty_termios_copy_hw(tty->termios, old_termios); | ||
986 | if (status != 0) /* Set failed - return old bits */ | ||
987 | return; | ||
988 | /* Re-encode speed, parity and csize */ | ||
989 | tty_encode_baud_rate(tty, baud, baud); | ||
990 | tty->termios->c_cflag &= ~(supported_mask|CSIZE); | ||
991 | tty->termios->c_cflag |= newval | csize; | ||
952 | } | 992 | } |
953 | 993 | ||
954 | static void iuu_close(struct tty_struct *tty, | 994 | static void iuu_close(struct usb_serial_port *port) |
955 | struct usb_serial_port *port, struct file *filp) | ||
956 | { | 995 | { |
957 | /* iuu_led (port,255,0,0,0); */ | 996 | /* iuu_led (port,255,0,0,0); */ |
958 | struct usb_serial *serial; | 997 | struct usb_serial *serial; |
959 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
960 | unsigned long flags; | ||
961 | unsigned int c_cflag; | ||
962 | 998 | ||
963 | serial = port->serial; | 999 | serial = port->serial; |
964 | if (!serial) | 1000 | if (!serial) |
@@ -968,17 +1004,6 @@ static void iuu_close(struct tty_struct *tty, | |||
968 | 1004 | ||
969 | iuu_uart_off(port); | 1005 | iuu_uart_off(port); |
970 | if (serial->dev) { | 1006 | if (serial->dev) { |
971 | if (tty) { | ||
972 | c_cflag = tty->termios->c_cflag; | ||
973 | if (c_cflag & HUPCL) { | ||
974 | /* drop DTR and RTS */ | ||
975 | priv = usb_get_serial_port_data(port); | ||
976 | spin_lock_irqsave(&priv->lock, flags); | ||
977 | priv->line_control = 0; | ||
978 | spin_unlock_irqrestore(&priv->lock, flags); | ||
979 | set_control_lines(port->serial->dev, 0); | ||
980 | } | ||
981 | } | ||
982 | /* free writebuf */ | 1007 | /* free writebuf */ |
983 | /* shutdown our urbs */ | 1008 | /* shutdown our urbs */ |
984 | dbg("%s - shutting down urbs", __func__); | 1009 | dbg("%s - shutting down urbs", __func__); |
@@ -1154,7 +1179,7 @@ static int iuu_open(struct tty_struct *tty, | |||
1154 | if (result) { | 1179 | if (result) { |
1155 | dev_err(&port->dev, "%s - failed submitting read urb," | 1180 | dev_err(&port->dev, "%s - failed submitting read urb," |
1156 | " error %d\n", __func__, result); | 1181 | " error %d\n", __func__, result); |
1157 | iuu_close(tty, port, NULL); | 1182 | iuu_close(port); |
1158 | return -EPROTO; | 1183 | return -EPROTO; |
1159 | } else { | 1184 | } else { |
1160 | dbg("%s - rxcmd OK", __func__); | 1185 | dbg("%s - rxcmd OK", __func__); |
@@ -1175,8 +1200,9 @@ static struct usb_serial_driver iuu_device = { | |||
1175 | .read_bulk_callback = iuu_uart_read_callback, | 1200 | .read_bulk_callback = iuu_uart_read_callback, |
1176 | .tiocmget = iuu_tiocmget, | 1201 | .tiocmget = iuu_tiocmget, |
1177 | .tiocmset = iuu_tiocmset, | 1202 | .tiocmset = iuu_tiocmset, |
1203 | .set_termios = iuu_set_termios, | ||
1178 | .attach = iuu_startup, | 1204 | .attach = iuu_startup, |
1179 | .shutdown = iuu_shutdown, | 1205 | .release = iuu_release, |
1180 | }; | 1206 | }; |
1181 | 1207 | ||
1182 | static int __init iuu_init(void) | 1208 | static int __init iuu_init(void) |
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 00daa8f7759a..2594b8743d3f 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -1298,8 +1298,16 @@ static inline void stop_urb(struct urb *urb) | |||
1298 | usb_kill_urb(urb); | 1298 | usb_kill_urb(urb); |
1299 | } | 1299 | } |
1300 | 1300 | ||
1301 | static void keyspan_close(struct tty_struct *tty, | 1301 | static void keyspan_dtr_rts(struct usb_serial_port *port, int on) |
1302 | struct usb_serial_port *port, struct file *filp) | 1302 | { |
1303 | struct keyspan_port_private *p_priv = usb_get_serial_port_data(port); | ||
1304 | |||
1305 | p_priv->rts_state = on; | ||
1306 | p_priv->dtr_state = on; | ||
1307 | keyspan_send_setup(port, 0); | ||
1308 | } | ||
1309 | |||
1310 | static void keyspan_close(struct usb_serial_port *port) | ||
1303 | { | 1311 | { |
1304 | int i; | 1312 | int i; |
1305 | struct usb_serial *serial = port->serial; | 1313 | struct usb_serial *serial = port->serial; |
@@ -1336,7 +1344,6 @@ static void keyspan_close(struct tty_struct *tty, | |||
1336 | stop_urb(p_priv->out_urbs[i]); | 1344 | stop_urb(p_priv->out_urbs[i]); |
1337 | } | 1345 | } |
1338 | } | 1346 | } |
1339 | tty_port_tty_set(&port->port, NULL); | ||
1340 | } | 1347 | } |
1341 | 1348 | ||
1342 | /* download the firmware to a pre-renumeration device */ | 1349 | /* download the firmware to a pre-renumeration device */ |
@@ -2682,7 +2689,7 @@ static int keyspan_startup(struct usb_serial *serial) | |||
2682 | return 0; | 2689 | return 0; |
2683 | } | 2690 | } |
2684 | 2691 | ||
2685 | static void keyspan_shutdown(struct usb_serial *serial) | 2692 | static void keyspan_disconnect(struct usb_serial *serial) |
2686 | { | 2693 | { |
2687 | int i, j; | 2694 | int i, j; |
2688 | struct usb_serial_port *port; | 2695 | struct usb_serial_port *port; |
@@ -2722,6 +2729,17 @@ static void keyspan_shutdown(struct usb_serial *serial) | |||
2722 | usb_free_urb(p_priv->out_urbs[j]); | 2729 | usb_free_urb(p_priv->out_urbs[j]); |
2723 | } | 2730 | } |
2724 | } | 2731 | } |
2732 | } | ||
2733 | |||
2734 | static void keyspan_release(struct usb_serial *serial) | ||
2735 | { | ||
2736 | int i; | ||
2737 | struct usb_serial_port *port; | ||
2738 | struct keyspan_serial_private *s_priv; | ||
2739 | |||
2740 | dbg("%s", __func__); | ||
2741 | |||
2742 | s_priv = usb_get_serial_data(serial); | ||
2725 | 2743 | ||
2726 | /* dbg("Freeing serial->private."); */ | 2744 | /* dbg("Freeing serial->private."); */ |
2727 | kfree(s_priv); | 2745 | kfree(s_priv); |
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 38b4582e0734..3107ed15af64 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h | |||
@@ -38,11 +38,11 @@ | |||
38 | static int keyspan_open (struct tty_struct *tty, | 38 | static int keyspan_open (struct tty_struct *tty, |
39 | struct usb_serial_port *port, | 39 | struct usb_serial_port *port, |
40 | struct file *filp); | 40 | struct file *filp); |
41 | static void keyspan_close (struct tty_struct *tty, | 41 | static void keyspan_close (struct usb_serial_port *port); |
42 | struct usb_serial_port *port, | 42 | static void keyspan_dtr_rts (struct usb_serial_port *port, int on); |
43 | struct file *filp); | ||
44 | static int keyspan_startup (struct usb_serial *serial); | 43 | static int keyspan_startup (struct usb_serial *serial); |
45 | static void keyspan_shutdown (struct usb_serial *serial); | 44 | static void keyspan_disconnect (struct usb_serial *serial); |
45 | static void keyspan_release (struct usb_serial *serial); | ||
46 | static int keyspan_write_room (struct tty_struct *tty); | 46 | static int keyspan_write_room (struct tty_struct *tty); |
47 | 47 | ||
48 | static int keyspan_write (struct tty_struct *tty, | 48 | static int keyspan_write (struct tty_struct *tty, |
@@ -562,6 +562,7 @@ static struct usb_serial_driver keyspan_1port_device = { | |||
562 | .num_ports = 1, | 562 | .num_ports = 1, |
563 | .open = keyspan_open, | 563 | .open = keyspan_open, |
564 | .close = keyspan_close, | 564 | .close = keyspan_close, |
565 | .dtr_rts = keyspan_dtr_rts, | ||
565 | .write = keyspan_write, | 566 | .write = keyspan_write, |
566 | .write_room = keyspan_write_room, | 567 | .write_room = keyspan_write_room, |
567 | .set_termios = keyspan_set_termios, | 568 | .set_termios = keyspan_set_termios, |
@@ -569,7 +570,8 @@ static struct usb_serial_driver keyspan_1port_device = { | |||
569 | .tiocmget = keyspan_tiocmget, | 570 | .tiocmget = keyspan_tiocmget, |
570 | .tiocmset = keyspan_tiocmset, | 571 | .tiocmset = keyspan_tiocmset, |
571 | .attach = keyspan_startup, | 572 | .attach = keyspan_startup, |
572 | .shutdown = keyspan_shutdown, | 573 | .disconnect = keyspan_disconnect, |
574 | .release = keyspan_release, | ||
573 | }; | 575 | }; |
574 | 576 | ||
575 | static struct usb_serial_driver keyspan_2port_device = { | 577 | static struct usb_serial_driver keyspan_2port_device = { |
@@ -582,6 +584,7 @@ static struct usb_serial_driver keyspan_2port_device = { | |||
582 | .num_ports = 2, | 584 | .num_ports = 2, |
583 | .open = keyspan_open, | 585 | .open = keyspan_open, |
584 | .close = keyspan_close, | 586 | .close = keyspan_close, |
587 | .dtr_rts = keyspan_dtr_rts, | ||
585 | .write = keyspan_write, | 588 | .write = keyspan_write, |
586 | .write_room = keyspan_write_room, | 589 | .write_room = keyspan_write_room, |
587 | .set_termios = keyspan_set_termios, | 590 | .set_termios = keyspan_set_termios, |
@@ -589,7 +592,8 @@ static struct usb_serial_driver keyspan_2port_device = { | |||
589 | .tiocmget = keyspan_tiocmget, | 592 | .tiocmget = keyspan_tiocmget, |
590 | .tiocmset = keyspan_tiocmset, | 593 | .tiocmset = keyspan_tiocmset, |
591 | .attach = keyspan_startup, | 594 | .attach = keyspan_startup, |
592 | .shutdown = keyspan_shutdown, | 595 | .disconnect = keyspan_disconnect, |
596 | .release = keyspan_release, | ||
593 | }; | 597 | }; |
594 | 598 | ||
595 | static struct usb_serial_driver keyspan_4port_device = { | 599 | static struct usb_serial_driver keyspan_4port_device = { |
@@ -602,6 +606,7 @@ static struct usb_serial_driver keyspan_4port_device = { | |||
602 | .num_ports = 4, | 606 | .num_ports = 4, |
603 | .open = keyspan_open, | 607 | .open = keyspan_open, |
604 | .close = keyspan_close, | 608 | .close = keyspan_close, |
609 | .dtr_rts = keyspan_dtr_rts, | ||
605 | .write = keyspan_write, | 610 | .write = keyspan_write, |
606 | .write_room = keyspan_write_room, | 611 | .write_room = keyspan_write_room, |
607 | .set_termios = keyspan_set_termios, | 612 | .set_termios = keyspan_set_termios, |
@@ -609,7 +614,8 @@ static struct usb_serial_driver keyspan_4port_device = { | |||
609 | .tiocmget = keyspan_tiocmget, | 614 | .tiocmget = keyspan_tiocmget, |
610 | .tiocmset = keyspan_tiocmset, | 615 | .tiocmset = keyspan_tiocmset, |
611 | .attach = keyspan_startup, | 616 | .attach = keyspan_startup, |
612 | .shutdown = keyspan_shutdown, | 617 | .disconnect = keyspan_disconnect, |
618 | .release = keyspan_release, | ||
613 | }; | 619 | }; |
614 | 620 | ||
615 | #endif | 621 | #endif |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index bf1ae247da66..d0b12e40c2b1 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -651,6 +651,35 @@ static int keyspan_pda_chars_in_buffer(struct tty_struct *tty) | |||
651 | } | 651 | } |
652 | 652 | ||
653 | 653 | ||
654 | static void keyspan_pda_dtr_rts(struct usb_serial_port *port, int on) | ||
655 | { | ||
656 | struct usb_serial *serial = port->serial; | ||
657 | |||
658 | if (serial->dev) { | ||
659 | if (on) | ||
660 | keyspan_pda_set_modem_info(serial, (1<<7) | (1<< 2)); | ||
661 | else | ||
662 | keyspan_pda_set_modem_info(serial, 0); | ||
663 | } | ||
664 | } | ||
665 | |||
666 | static int keyspan_pda_carrier_raised(struct usb_serial_port *port) | ||
667 | { | ||
668 | struct usb_serial *serial = port->serial; | ||
669 | unsigned char modembits; | ||
670 | |||
671 | /* If we can read the modem status and the DCD is low then | ||
672 | carrier is not raised yet */ | ||
673 | if (keyspan_pda_get_modem_info(serial, &modembits) >= 0) { | ||
674 | if (!(modembits & (1>>6))) | ||
675 | return 0; | ||
676 | } | ||
677 | /* Carrier raised, or we failed (eg disconnected) so | ||
678 | progress accordingly */ | ||
679 | return 1; | ||
680 | } | ||
681 | |||
682 | |||
654 | static int keyspan_pda_open(struct tty_struct *tty, | 683 | static int keyspan_pda_open(struct tty_struct *tty, |
655 | struct usb_serial_port *port, struct file *filp) | 684 | struct usb_serial_port *port, struct file *filp) |
656 | { | 685 | { |
@@ -682,13 +711,6 @@ static int keyspan_pda_open(struct tty_struct *tty, | |||
682 | priv->tx_room = room; | 711 | priv->tx_room = room; |
683 | priv->tx_throttled = room ? 0 : 1; | 712 | priv->tx_throttled = room ? 0 : 1; |
684 | 713 | ||
685 | /* the normal serial device seems to always turn on DTR and RTS here, | ||
686 | so do the same */ | ||
687 | if (tty && (tty->termios->c_cflag & CBAUD)) | ||
688 | keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2)); | ||
689 | else | ||
690 | keyspan_pda_set_modem_info(serial, 0); | ||
691 | |||
692 | /*Start reading from the device*/ | 714 | /*Start reading from the device*/ |
693 | port->interrupt_in_urb->dev = serial->dev; | 715 | port->interrupt_in_urb->dev = serial->dev; |
694 | rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | 716 | rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
@@ -700,19 +722,11 @@ static int keyspan_pda_open(struct tty_struct *tty, | |||
700 | error: | 722 | error: |
701 | return rc; | 723 | return rc; |
702 | } | 724 | } |
703 | 725 | static void keyspan_pda_close(struct usb_serial_port *port) | |
704 | |||
705 | static void keyspan_pda_close(struct tty_struct *tty, | ||
706 | struct usb_serial_port *port, struct file *filp) | ||
707 | { | 726 | { |
708 | struct usb_serial *serial = port->serial; | 727 | struct usb_serial *serial = port->serial; |
709 | 728 | ||
710 | if (serial->dev) { | 729 | if (serial->dev) { |
711 | /* the normal serial device seems to always shut | ||
712 | off DTR and RTS now */ | ||
713 | if (tty->termios->c_cflag & HUPCL) | ||
714 | keyspan_pda_set_modem_info(serial, 0); | ||
715 | |||
716 | /* shutdown our bulk reads and writes */ | 730 | /* shutdown our bulk reads and writes */ |
717 | usb_kill_urb(port->write_urb); | 731 | usb_kill_urb(port->write_urb); |
718 | usb_kill_urb(port->interrupt_in_urb); | 732 | usb_kill_urb(port->interrupt_in_urb); |
@@ -795,7 +809,7 @@ static int keyspan_pda_startup(struct usb_serial *serial) | |||
795 | return 0; | 809 | return 0; |
796 | } | 810 | } |
797 | 811 | ||
798 | static void keyspan_pda_shutdown(struct usb_serial *serial) | 812 | static void keyspan_pda_release(struct usb_serial *serial) |
799 | { | 813 | { |
800 | dbg("%s", __func__); | 814 | dbg("%s", __func__); |
801 | 815 | ||
@@ -839,6 +853,8 @@ static struct usb_serial_driver keyspan_pda_device = { | |||
839 | .usb_driver = &keyspan_pda_driver, | 853 | .usb_driver = &keyspan_pda_driver, |
840 | .id_table = id_table_std, | 854 | .id_table = id_table_std, |
841 | .num_ports = 1, | 855 | .num_ports = 1, |
856 | .dtr_rts = keyspan_pda_dtr_rts, | ||
857 | .carrier_raised = keyspan_pda_carrier_raised, | ||
842 | .open = keyspan_pda_open, | 858 | .open = keyspan_pda_open, |
843 | .close = keyspan_pda_close, | 859 | .close = keyspan_pda_close, |
844 | .write = keyspan_pda_write, | 860 | .write = keyspan_pda_write, |
@@ -853,7 +869,7 @@ static struct usb_serial_driver keyspan_pda_device = { | |||
853 | .tiocmget = keyspan_pda_tiocmget, | 869 | .tiocmget = keyspan_pda_tiocmget, |
854 | .tiocmset = keyspan_pda_tiocmset, | 870 | .tiocmset = keyspan_pda_tiocmset, |
855 | .attach = keyspan_pda_startup, | 871 | .attach = keyspan_pda_startup, |
856 | .shutdown = keyspan_pda_shutdown, | 872 | .release = keyspan_pda_release, |
857 | }; | 873 | }; |
858 | 874 | ||
859 | 875 | ||
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index fcd9082f3e7f..0f44bb8e8d4f 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -73,11 +73,11 @@ static int debug; | |||
73 | * Function prototypes | 73 | * Function prototypes |
74 | */ | 74 | */ |
75 | static int klsi_105_startup(struct usb_serial *serial); | 75 | static int klsi_105_startup(struct usb_serial *serial); |
76 | static void klsi_105_shutdown(struct usb_serial *serial); | 76 | static void klsi_105_disconnect(struct usb_serial *serial); |
77 | static void klsi_105_release(struct usb_serial *serial); | ||
77 | static int klsi_105_open(struct tty_struct *tty, | 78 | static int klsi_105_open(struct tty_struct *tty, |
78 | struct usb_serial_port *port, struct file *filp); | 79 | struct usb_serial_port *port, struct file *filp); |
79 | static void klsi_105_close(struct tty_struct *tty, | 80 | static void klsi_105_close(struct usb_serial_port *port); |
80 | struct usb_serial_port *port, struct file *filp); | ||
81 | static int klsi_105_write(struct tty_struct *tty, | 81 | static int klsi_105_write(struct tty_struct *tty, |
82 | struct usb_serial_port *port, const unsigned char *buf, int count); | 82 | struct usb_serial_port *port, const unsigned char *buf, int count); |
83 | static void klsi_105_write_bulk_callback(struct urb *urb); | 83 | static void klsi_105_write_bulk_callback(struct urb *urb); |
@@ -132,7 +132,8 @@ static struct usb_serial_driver kl5kusb105d_device = { | |||
132 | .tiocmget = klsi_105_tiocmget, | 132 | .tiocmget = klsi_105_tiocmget, |
133 | .tiocmset = klsi_105_tiocmset, | 133 | .tiocmset = klsi_105_tiocmset, |
134 | .attach = klsi_105_startup, | 134 | .attach = klsi_105_startup, |
135 | .shutdown = klsi_105_shutdown, | 135 | .disconnect = klsi_105_disconnect, |
136 | .release = klsi_105_release, | ||
136 | .throttle = klsi_105_throttle, | 137 | .throttle = klsi_105_throttle, |
137 | .unthrottle = klsi_105_unthrottle, | 138 | .unthrottle = klsi_105_unthrottle, |
138 | }; | 139 | }; |
@@ -316,7 +317,7 @@ err_cleanup: | |||
316 | } /* klsi_105_startup */ | 317 | } /* klsi_105_startup */ |
317 | 318 | ||
318 | 319 | ||
319 | static void klsi_105_shutdown(struct usb_serial *serial) | 320 | static void klsi_105_disconnect(struct usb_serial *serial) |
320 | { | 321 | { |
321 | int i; | 322 | int i; |
322 | 323 | ||
@@ -326,33 +327,36 @@ static void klsi_105_shutdown(struct usb_serial *serial) | |||
326 | for (i = 0; i < serial->num_ports; ++i) { | 327 | for (i = 0; i < serial->num_ports; ++i) { |
327 | struct klsi_105_private *priv = | 328 | struct klsi_105_private *priv = |
328 | usb_get_serial_port_data(serial->port[i]); | 329 | usb_get_serial_port_data(serial->port[i]); |
329 | unsigned long flags; | ||
330 | 330 | ||
331 | if (priv) { | 331 | if (priv) { |
332 | /* kill our write urb pool */ | 332 | /* kill our write urb pool */ |
333 | int j; | 333 | int j; |
334 | struct urb **write_urbs = priv->write_urb_pool; | 334 | struct urb **write_urbs = priv->write_urb_pool; |
335 | spin_lock_irqsave(&priv->lock, flags); | ||
336 | 335 | ||
337 | for (j = 0; j < NUM_URBS; j++) { | 336 | for (j = 0; j < NUM_URBS; j++) { |
338 | if (write_urbs[j]) { | 337 | if (write_urbs[j]) { |
339 | /* FIXME - uncomment the following | 338 | usb_kill_urb(write_urbs[j]); |
340 | * usb_kill_urb call when the host | ||
341 | * controllers get fixed to set | ||
342 | * urb->dev = NULL after the urb is | ||
343 | * finished. Otherwise this call | ||
344 | * oopses. */ | ||
345 | /* usb_kill_urb(write_urbs[j]); */ | ||
346 | kfree(write_urbs[j]->transfer_buffer); | ||
347 | usb_free_urb(write_urbs[j]); | 339 | usb_free_urb(write_urbs[j]); |
348 | } | 340 | } |
349 | } | 341 | } |
350 | spin_unlock_irqrestore(&priv->lock, flags); | ||
351 | kfree(priv); | ||
352 | usb_set_serial_port_data(serial->port[i], NULL); | ||
353 | } | 342 | } |
354 | } | 343 | } |
355 | } /* klsi_105_shutdown */ | 344 | } /* klsi_105_disconnect */ |
345 | |||
346 | |||
347 | static void klsi_105_release(struct usb_serial *serial) | ||
348 | { | ||
349 | int i; | ||
350 | |||
351 | dbg("%s", __func__); | ||
352 | |||
353 | for (i = 0; i < serial->num_ports; ++i) { | ||
354 | struct klsi_105_private *priv = | ||
355 | usb_get_serial_port_data(serial->port[i]); | ||
356 | |||
357 | kfree(priv); | ||
358 | } | ||
359 | } /* klsi_105_release */ | ||
356 | 360 | ||
357 | static int klsi_105_open(struct tty_struct *tty, | 361 | static int klsi_105_open(struct tty_struct *tty, |
358 | struct usb_serial_port *port, struct file *filp) | 362 | struct usb_serial_port *port, struct file *filp) |
@@ -447,8 +451,7 @@ exit: | |||
447 | } /* klsi_105_open */ | 451 | } /* klsi_105_open */ |
448 | 452 | ||
449 | 453 | ||
450 | static void klsi_105_close(struct tty_struct *tty, | 454 | static void klsi_105_close(struct usb_serial_port *port) |
451 | struct usb_serial_port *port, struct file *filp) | ||
452 | { | 455 | { |
453 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | 456 | struct klsi_105_private *priv = usb_get_serial_port_data(port); |
454 | int rc; | 457 | int rc; |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index c148544953b3..6db0e561f680 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -69,11 +69,10 @@ static int debug; | |||
69 | 69 | ||
70 | /* Function prototypes */ | 70 | /* Function prototypes */ |
71 | static int kobil_startup(struct usb_serial *serial); | 71 | static int kobil_startup(struct usb_serial *serial); |
72 | static void kobil_shutdown(struct usb_serial *serial); | 72 | static void kobil_release(struct usb_serial *serial); |
73 | static int kobil_open(struct tty_struct *tty, | 73 | static int kobil_open(struct tty_struct *tty, |
74 | struct usb_serial_port *port, struct file *filp); | 74 | struct usb_serial_port *port, struct file *filp); |
75 | static void kobil_close(struct tty_struct *tty, struct usb_serial_port *port, | 75 | static void kobil_close(struct usb_serial_port *port); |
76 | struct file *filp); | ||
77 | static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port, | 76 | static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port, |
78 | const unsigned char *buf, int count); | 77 | const unsigned char *buf, int count); |
79 | static int kobil_write_room(struct tty_struct *tty); | 78 | static int kobil_write_room(struct tty_struct *tty); |
@@ -118,7 +117,7 @@ static struct usb_serial_driver kobil_device = { | |||
118 | .id_table = id_table, | 117 | .id_table = id_table, |
119 | .num_ports = 1, | 118 | .num_ports = 1, |
120 | .attach = kobil_startup, | 119 | .attach = kobil_startup, |
121 | .shutdown = kobil_shutdown, | 120 | .release = kobil_release, |
122 | .ioctl = kobil_ioctl, | 121 | .ioctl = kobil_ioctl, |
123 | .set_termios = kobil_set_termios, | 122 | .set_termios = kobil_set_termios, |
124 | .tiocmget = kobil_tiocmget, | 123 | .tiocmget = kobil_tiocmget, |
@@ -202,17 +201,13 @@ static int kobil_startup(struct usb_serial *serial) | |||
202 | } | 201 | } |
203 | 202 | ||
204 | 203 | ||
205 | static void kobil_shutdown(struct usb_serial *serial) | 204 | static void kobil_release(struct usb_serial *serial) |
206 | { | 205 | { |
207 | int i; | 206 | int i; |
208 | dbg("%s - port %d", __func__, serial->port[0]->number); | 207 | dbg("%s - port %d", __func__, serial->port[0]->number); |
209 | 208 | ||
210 | for (i = 0; i < serial->num_ports; ++i) { | 209 | for (i = 0; i < serial->num_ports; ++i) |
211 | while (serial->port[i]->port.count > 0) | ||
212 | kobil_close(NULL, serial->port[i], NULL); | ||
213 | kfree(usb_get_serial_port_data(serial->port[i])); | 210 | kfree(usb_get_serial_port_data(serial->port[i])); |
214 | usb_set_serial_port_data(serial->port[i], NULL); | ||
215 | } | ||
216 | } | 211 | } |
217 | 212 | ||
218 | 213 | ||
@@ -346,11 +341,11 @@ static int kobil_open(struct tty_struct *tty, | |||
346 | } | 341 | } |
347 | 342 | ||
348 | 343 | ||
349 | static void kobil_close(struct tty_struct *tty, | 344 | static void kobil_close(struct usb_serial_port *port) |
350 | struct usb_serial_port *port, struct file *filp) | ||
351 | { | 345 | { |
352 | dbg("%s - port %d", __func__, port->number); | 346 | dbg("%s - port %d", __func__, port->number); |
353 | 347 | ||
348 | /* FIXME: Add rts/dtr methods */ | ||
354 | if (port->write_urb) { | 349 | if (port->write_urb) { |
355 | usb_kill_urb(port->write_urb); | 350 | usb_kill_urb(port->write_urb); |
356 | usb_free_urb(port->write_urb); | 351 | usb_free_urb(port->write_urb); |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 82930a7d5093..d8825e159aa5 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -92,11 +92,11 @@ static int debug; | |||
92 | * Function prototypes | 92 | * Function prototypes |
93 | */ | 93 | */ |
94 | static int mct_u232_startup(struct usb_serial *serial); | 94 | static int mct_u232_startup(struct usb_serial *serial); |
95 | static void mct_u232_shutdown(struct usb_serial *serial); | 95 | static void mct_u232_release(struct usb_serial *serial); |
96 | static int mct_u232_open(struct tty_struct *tty, | 96 | static int mct_u232_open(struct tty_struct *tty, |
97 | struct usb_serial_port *port, struct file *filp); | 97 | struct usb_serial_port *port, struct file *filp); |
98 | static void mct_u232_close(struct tty_struct *tty, | 98 | static void mct_u232_close(struct usb_serial_port *port); |
99 | struct usb_serial_port *port, struct file *filp); | 99 | static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); |
100 | static void mct_u232_read_int_callback(struct urb *urb); | 100 | static void mct_u232_read_int_callback(struct urb *urb); |
101 | static void mct_u232_set_termios(struct tty_struct *tty, | 101 | static void mct_u232_set_termios(struct tty_struct *tty, |
102 | struct usb_serial_port *port, struct ktermios *old); | 102 | struct usb_serial_port *port, struct ktermios *old); |
@@ -140,6 +140,7 @@ static struct usb_serial_driver mct_u232_device = { | |||
140 | .num_ports = 1, | 140 | .num_ports = 1, |
141 | .open = mct_u232_open, | 141 | .open = mct_u232_open, |
142 | .close = mct_u232_close, | 142 | .close = mct_u232_close, |
143 | .dtr_rts = mct_u232_dtr_rts, | ||
143 | .throttle = mct_u232_throttle, | 144 | .throttle = mct_u232_throttle, |
144 | .unthrottle = mct_u232_unthrottle, | 145 | .unthrottle = mct_u232_unthrottle, |
145 | .read_int_callback = mct_u232_read_int_callback, | 146 | .read_int_callback = mct_u232_read_int_callback, |
@@ -148,7 +149,7 @@ static struct usb_serial_driver mct_u232_device = { | |||
148 | .tiocmget = mct_u232_tiocmget, | 149 | .tiocmget = mct_u232_tiocmget, |
149 | .tiocmset = mct_u232_tiocmset, | 150 | .tiocmset = mct_u232_tiocmset, |
150 | .attach = mct_u232_startup, | 151 | .attach = mct_u232_startup, |
151 | .shutdown = mct_u232_shutdown, | 152 | .release = mct_u232_release, |
152 | }; | 153 | }; |
153 | 154 | ||
154 | 155 | ||
@@ -406,7 +407,7 @@ static int mct_u232_startup(struct usb_serial *serial) | |||
406 | } /* mct_u232_startup */ | 407 | } /* mct_u232_startup */ |
407 | 408 | ||
408 | 409 | ||
409 | static void mct_u232_shutdown(struct usb_serial *serial) | 410 | static void mct_u232_release(struct usb_serial *serial) |
410 | { | 411 | { |
411 | struct mct_u232_private *priv; | 412 | struct mct_u232_private *priv; |
412 | int i; | 413 | int i; |
@@ -416,12 +417,9 @@ static void mct_u232_shutdown(struct usb_serial *serial) | |||
416 | for (i = 0; i < serial->num_ports; ++i) { | 417 | for (i = 0; i < serial->num_ports; ++i) { |
417 | /* My special items, the standard routines free my urbs */ | 418 | /* My special items, the standard routines free my urbs */ |
418 | priv = usb_get_serial_port_data(serial->port[i]); | 419 | priv = usb_get_serial_port_data(serial->port[i]); |
419 | if (priv) { | 420 | kfree(priv); |
420 | usb_set_serial_port_data(serial->port[i], NULL); | ||
421 | kfree(priv); | ||
422 | } | ||
423 | } | 421 | } |
424 | } /* mct_u232_shutdown */ | 422 | } /* mct_u232_release */ |
425 | 423 | ||
426 | static int mct_u232_open(struct tty_struct *tty, | 424 | static int mct_u232_open(struct tty_struct *tty, |
427 | struct usb_serial_port *port, struct file *filp) | 425 | struct usb_serial_port *port, struct file *filp) |
@@ -496,29 +494,29 @@ error: | |||
496 | return retval; | 494 | return retval; |
497 | } /* mct_u232_open */ | 495 | } /* mct_u232_open */ |
498 | 496 | ||
499 | 497 | static void mct_u232_dtr_rts(struct usb_serial_port *port, int on) | |
500 | static void mct_u232_close(struct tty_struct *tty, | ||
501 | struct usb_serial_port *port, struct file *filp) | ||
502 | { | 498 | { |
503 | unsigned int c_cflag; | ||
504 | unsigned int control_state; | 499 | unsigned int control_state; |
505 | struct mct_u232_private *priv = usb_get_serial_port_data(port); | 500 | struct mct_u232_private *priv = usb_get_serial_port_data(port); |
506 | dbg("%s port %d", __func__, port->number); | ||
507 | 501 | ||
508 | if (tty) { | 502 | mutex_lock(&port->serial->disc_mutex); |
509 | c_cflag = tty->termios->c_cflag; | 503 | if (!port->serial->disconnected) { |
510 | mutex_lock(&port->serial->disc_mutex); | 504 | /* drop DTR and RTS */ |
511 | if (c_cflag & HUPCL && !port->serial->disconnected) { | 505 | spin_lock_irq(&priv->lock); |
512 | /* drop DTR and RTS */ | 506 | if (on) |
513 | spin_lock_irq(&priv->lock); | 507 | priv->control_state |= TIOCM_DTR | TIOCM_RTS; |
508 | else | ||
514 | priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); | 509 | priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); |
515 | control_state = priv->control_state; | 510 | control_state = priv->control_state; |
516 | spin_unlock_irq(&priv->lock); | 511 | spin_unlock_irq(&priv->lock); |
517 | mct_u232_set_modem_ctrl(port->serial, control_state); | 512 | mct_u232_set_modem_ctrl(port->serial, control_state); |
518 | } | ||
519 | mutex_unlock(&port->serial->disc_mutex); | ||
520 | } | 513 | } |
514 | mutex_unlock(&port->serial->disc_mutex); | ||
515 | } | ||
521 | 516 | ||
517 | static void mct_u232_close(struct usb_serial_port *port) | ||
518 | { | ||
519 | dbg("%s port %d", __func__, port->number); | ||
522 | 520 | ||
523 | if (port->serial->dev) { | 521 | if (port->serial->dev) { |
524 | /* shutdown our urbs */ | 522 | /* shutdown our urbs */ |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 24e3b5d4b4d4..bfc5ce000ef9 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -533,8 +533,7 @@ static int mos7720_chars_in_buffer(struct tty_struct *tty) | |||
533 | return chars; | 533 | return chars; |
534 | } | 534 | } |
535 | 535 | ||
536 | static void mos7720_close(struct tty_struct *tty, | 536 | static void mos7720_close(struct usb_serial_port *port) |
537 | struct usb_serial_port *port, struct file *filp) | ||
538 | { | 537 | { |
539 | struct usb_serial *serial; | 538 | struct usb_serial *serial; |
540 | struct moschip_port *mos7720_port; | 539 | struct moschip_port *mos7720_port; |
@@ -1522,19 +1521,16 @@ static int mos7720_startup(struct usb_serial *serial) | |||
1522 | return 0; | 1521 | return 0; |
1523 | } | 1522 | } |
1524 | 1523 | ||
1525 | static void mos7720_shutdown(struct usb_serial *serial) | 1524 | static void mos7720_release(struct usb_serial *serial) |
1526 | { | 1525 | { |
1527 | int i; | 1526 | int i; |
1528 | 1527 | ||
1529 | /* free private structure allocated for serial port */ | 1528 | /* free private structure allocated for serial port */ |
1530 | for (i = 0; i < serial->num_ports; ++i) { | 1529 | for (i = 0; i < serial->num_ports; ++i) |
1531 | kfree(usb_get_serial_port_data(serial->port[i])); | 1530 | kfree(usb_get_serial_port_data(serial->port[i])); |
1532 | usb_set_serial_port_data(serial->port[i], NULL); | ||
1533 | } | ||
1534 | 1531 | ||
1535 | /* free private structure allocated for serial device */ | 1532 | /* free private structure allocated for serial device */ |
1536 | kfree(usb_get_serial_data(serial)); | 1533 | kfree(usb_get_serial_data(serial)); |
1537 | usb_set_serial_data(serial, NULL); | ||
1538 | } | 1534 | } |
1539 | 1535 | ||
1540 | static struct usb_driver usb_driver = { | 1536 | static struct usb_driver usb_driver = { |
@@ -1559,7 +1555,7 @@ static struct usb_serial_driver moschip7720_2port_driver = { | |||
1559 | .throttle = mos7720_throttle, | 1555 | .throttle = mos7720_throttle, |
1560 | .unthrottle = mos7720_unthrottle, | 1556 | .unthrottle = mos7720_unthrottle, |
1561 | .attach = mos7720_startup, | 1557 | .attach = mos7720_startup, |
1562 | .shutdown = mos7720_shutdown, | 1558 | .release = mos7720_release, |
1563 | .ioctl = mos7720_ioctl, | 1559 | .ioctl = mos7720_ioctl, |
1564 | .set_termios = mos7720_set_termios, | 1560 | .set_termios = mos7720_set_termios, |
1565 | .write = mos7720_write, | 1561 | .write = mos7720_write, |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 84fb1dcd30dc..c40f95c1951c 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -238,7 +238,7 @@ static int mos7840_set_reg_sync(struct usb_serial_port *port, __u16 reg, | |||
238 | { | 238 | { |
239 | struct usb_device *dev = port->serial->dev; | 239 | struct usb_device *dev = port->serial->dev; |
240 | val = val & 0x00ff; | 240 | val = val & 0x00ff; |
241 | dbg("mos7840_set_reg_sync offset is %x, value %x\n", reg, val); | 241 | dbg("mos7840_set_reg_sync offset is %x, value %x", reg, val); |
242 | 242 | ||
243 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ, | 243 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ, |
244 | MCS_WR_RTYPE, val, reg, NULL, 0, | 244 | MCS_WR_RTYPE, val, reg, NULL, 0, |
@@ -260,7 +260,7 @@ static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg, | |||
260 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, | 260 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, |
261 | MCS_RD_RTYPE, 0, reg, val, VENDOR_READ_LENGTH, | 261 | MCS_RD_RTYPE, 0, reg, val, VENDOR_READ_LENGTH, |
262 | MOS_WDR_TIMEOUT); | 262 | MOS_WDR_TIMEOUT); |
263 | dbg("mos7840_get_reg_sync offset is %x, return val %x\n", reg, *val); | 263 | dbg("mos7840_get_reg_sync offset is %x, return val %x", reg, *val); |
264 | *val = (*val) & 0x00ff; | 264 | *val = (*val) & 0x00ff; |
265 | return ret; | 265 | return ret; |
266 | } | 266 | } |
@@ -282,18 +282,18 @@ static int mos7840_set_uart_reg(struct usb_serial_port *port, __u16 reg, | |||
282 | if (port->serial->num_ports == 4) { | 282 | if (port->serial->num_ports == 4) { |
283 | val |= (((__u16) port->number - | 283 | val |= (((__u16) port->number - |
284 | (__u16) (port->serial->minor)) + 1) << 8; | 284 | (__u16) (port->serial->minor)) + 1) << 8; |
285 | dbg("mos7840_set_uart_reg application number is %x\n", val); | 285 | dbg("mos7840_set_uart_reg application number is %x", val); |
286 | } else { | 286 | } else { |
287 | if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) { | 287 | if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) { |
288 | val |= (((__u16) port->number - | 288 | val |= (((__u16) port->number - |
289 | (__u16) (port->serial->minor)) + 1) << 8; | 289 | (__u16) (port->serial->minor)) + 1) << 8; |
290 | dbg("mos7840_set_uart_reg application number is %x\n", | 290 | dbg("mos7840_set_uart_reg application number is %x", |
291 | val); | 291 | val); |
292 | } else { | 292 | } else { |
293 | val |= | 293 | val |= |
294 | (((__u16) port->number - | 294 | (((__u16) port->number - |
295 | (__u16) (port->serial->minor)) + 2) << 8; | 295 | (__u16) (port->serial->minor)) + 2) << 8; |
296 | dbg("mos7840_set_uart_reg application number is %x\n", | 296 | dbg("mos7840_set_uart_reg application number is %x", |
297 | val); | 297 | val); |
298 | } | 298 | } |
299 | } | 299 | } |
@@ -315,24 +315,24 @@ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg, | |||
315 | int ret = 0; | 315 | int ret = 0; |
316 | __u16 Wval; | 316 | __u16 Wval; |
317 | 317 | ||
318 | /* dbg("application number is %4x \n", | 318 | /* dbg("application number is %4x", |
319 | (((__u16)port->number - (__u16)(port->serial->minor))+1)<<8); */ | 319 | (((__u16)port->number - (__u16)(port->serial->minor))+1)<<8); */ |
320 | /* Wval is same as application number */ | 320 | /* Wval is same as application number */ |
321 | if (port->serial->num_ports == 4) { | 321 | if (port->serial->num_ports == 4) { |
322 | Wval = | 322 | Wval = |
323 | (((__u16) port->number - (__u16) (port->serial->minor)) + | 323 | (((__u16) port->number - (__u16) (port->serial->minor)) + |
324 | 1) << 8; | 324 | 1) << 8; |
325 | dbg("mos7840_get_uart_reg application number is %x\n", Wval); | 325 | dbg("mos7840_get_uart_reg application number is %x", Wval); |
326 | } else { | 326 | } else { |
327 | if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) { | 327 | if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) { |
328 | Wval = (((__u16) port->number - | 328 | Wval = (((__u16) port->number - |
329 | (__u16) (port->serial->minor)) + 1) << 8; | 329 | (__u16) (port->serial->minor)) + 1) << 8; |
330 | dbg("mos7840_get_uart_reg application number is %x\n", | 330 | dbg("mos7840_get_uart_reg application number is %x", |
331 | Wval); | 331 | Wval); |
332 | } else { | 332 | } else { |
333 | Wval = (((__u16) port->number - | 333 | Wval = (((__u16) port->number - |
334 | (__u16) (port->serial->minor)) + 2) << 8; | 334 | (__u16) (port->serial->minor)) + 2) << 8; |
335 | dbg("mos7840_get_uart_reg application number is %x\n", | 335 | dbg("mos7840_get_uart_reg application number is %x", |
336 | Wval); | 336 | Wval); |
337 | } | 337 | } |
338 | } | 338 | } |
@@ -346,11 +346,11 @@ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg, | |||
346 | static void mos7840_dump_serial_port(struct moschip_port *mos7840_port) | 346 | static void mos7840_dump_serial_port(struct moschip_port *mos7840_port) |
347 | { | 347 | { |
348 | 348 | ||
349 | dbg("***************************************\n"); | 349 | dbg("***************************************"); |
350 | dbg("SpRegOffset is %2x\n", mos7840_port->SpRegOffset); | 350 | dbg("SpRegOffset is %2x", mos7840_port->SpRegOffset); |
351 | dbg("ControlRegOffset is %2x \n", mos7840_port->ControlRegOffset); | 351 | dbg("ControlRegOffset is %2x", mos7840_port->ControlRegOffset); |
352 | dbg("DCRRegOffset is %2x \n", mos7840_port->DcrRegOffset); | 352 | dbg("DCRRegOffset is %2x", mos7840_port->DcrRegOffset); |
353 | dbg("***************************************\n"); | 353 | dbg("***************************************"); |
354 | 354 | ||
355 | } | 355 | } |
356 | 356 | ||
@@ -474,12 +474,12 @@ static void mos7840_control_callback(struct urb *urb) | |||
474 | goto exit; | 474 | goto exit; |
475 | } | 475 | } |
476 | 476 | ||
477 | dbg("%s urb buffer size is %d\n", __func__, urb->actual_length); | 477 | dbg("%s urb buffer size is %d", __func__, urb->actual_length); |
478 | dbg("%s mos7840_port->MsrLsr is %d port %d\n", __func__, | 478 | dbg("%s mos7840_port->MsrLsr is %d port %d", __func__, |
479 | mos7840_port->MsrLsr, mos7840_port->port_num); | 479 | mos7840_port->MsrLsr, mos7840_port->port_num); |
480 | data = urb->transfer_buffer; | 480 | data = urb->transfer_buffer; |
481 | regval = (__u8) data[0]; | 481 | regval = (__u8) data[0]; |
482 | dbg("%s data is %x\n", __func__, regval); | 482 | dbg("%s data is %x", __func__, regval); |
483 | if (mos7840_port->MsrLsr == 0) | 483 | if (mos7840_port->MsrLsr == 0) |
484 | mos7840_handle_new_msr(mos7840_port, regval); | 484 | mos7840_handle_new_msr(mos7840_port, regval); |
485 | else if (mos7840_port->MsrLsr == 1) | 485 | else if (mos7840_port->MsrLsr == 1) |
@@ -538,7 +538,7 @@ static void mos7840_interrupt_callback(struct urb *urb) | |||
538 | __u16 wval, wreg = 0; | 538 | __u16 wval, wreg = 0; |
539 | int status = urb->status; | 539 | int status = urb->status; |
540 | 540 | ||
541 | dbg("%s", " : Entering\n"); | 541 | dbg("%s", " : Entering"); |
542 | 542 | ||
543 | switch (status) { | 543 | switch (status) { |
544 | case 0: | 544 | case 0: |
@@ -570,7 +570,7 @@ static void mos7840_interrupt_callback(struct urb *urb) | |||
570 | * Byte 5 FIFO status for both */ | 570 | * Byte 5 FIFO status for both */ |
571 | 571 | ||
572 | if (length && length > 5) { | 572 | if (length && length > 5) { |
573 | dbg("%s \n", "Wrong data !!!"); | 573 | dbg("%s", "Wrong data !!!"); |
574 | return; | 574 | return; |
575 | } | 575 | } |
576 | 576 | ||
@@ -587,17 +587,17 @@ static void mos7840_interrupt_callback(struct urb *urb) | |||
587 | (__u16) (serial->minor)) + 1) << 8; | 587 | (__u16) (serial->minor)) + 1) << 8; |
588 | if (mos7840_port->open) { | 588 | if (mos7840_port->open) { |
589 | if (sp[i] & 0x01) { | 589 | if (sp[i] & 0x01) { |
590 | dbg("SP%d No Interrupt !!!\n", i); | 590 | dbg("SP%d No Interrupt !!!", i); |
591 | } else { | 591 | } else { |
592 | switch (sp[i] & 0x0f) { | 592 | switch (sp[i] & 0x0f) { |
593 | case SERIAL_IIR_RLS: | 593 | case SERIAL_IIR_RLS: |
594 | dbg("Serial Port %d: Receiver status error or ", i); | 594 | dbg("Serial Port %d: Receiver status error or ", i); |
595 | dbg("address bit detected in 9-bit mode\n"); | 595 | dbg("address bit detected in 9-bit mode"); |
596 | mos7840_port->MsrLsr = 1; | 596 | mos7840_port->MsrLsr = 1; |
597 | wreg = LINE_STATUS_REGISTER; | 597 | wreg = LINE_STATUS_REGISTER; |
598 | break; | 598 | break; |
599 | case SERIAL_IIR_MS: | 599 | case SERIAL_IIR_MS: |
600 | dbg("Serial Port %d: Modem status change\n", i); | 600 | dbg("Serial Port %d: Modem status change", i); |
601 | mos7840_port->MsrLsr = 0; | 601 | mos7840_port->MsrLsr = 0; |
602 | wreg = MODEM_STATUS_REGISTER; | 602 | wreg = MODEM_STATUS_REGISTER; |
603 | break; | 603 | break; |
@@ -689,7 +689,7 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
689 | 689 | ||
690 | mos7840_port = urb->context; | 690 | mos7840_port = urb->context; |
691 | if (!mos7840_port) { | 691 | if (!mos7840_port) { |
692 | dbg("%s", "NULL mos7840_port pointer \n"); | 692 | dbg("%s", "NULL mos7840_port pointer"); |
693 | mos7840_port->read_urb_busy = false; | 693 | mos7840_port->read_urb_busy = false; |
694 | return; | 694 | return; |
695 | } | 695 | } |
@@ -702,41 +702,41 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
702 | 702 | ||
703 | port = (struct usb_serial_port *)mos7840_port->port; | 703 | port = (struct usb_serial_port *)mos7840_port->port; |
704 | if (mos7840_port_paranoia_check(port, __func__)) { | 704 | if (mos7840_port_paranoia_check(port, __func__)) { |
705 | dbg("%s", "Port Paranoia failed \n"); | 705 | dbg("%s", "Port Paranoia failed"); |
706 | mos7840_port->read_urb_busy = false; | 706 | mos7840_port->read_urb_busy = false; |
707 | return; | 707 | return; |
708 | } | 708 | } |
709 | 709 | ||
710 | serial = mos7840_get_usb_serial(port, __func__); | 710 | serial = mos7840_get_usb_serial(port, __func__); |
711 | if (!serial) { | 711 | if (!serial) { |
712 | dbg("%s\n", "Bad serial pointer "); | 712 | dbg("%s", "Bad serial pointer"); |
713 | mos7840_port->read_urb_busy = false; | 713 | mos7840_port->read_urb_busy = false; |
714 | return; | 714 | return; |
715 | } | 715 | } |
716 | 716 | ||
717 | dbg("%s\n", "Entering... \n"); | 717 | dbg("%s", "Entering... "); |
718 | 718 | ||
719 | data = urb->transfer_buffer; | 719 | data = urb->transfer_buffer; |
720 | 720 | ||
721 | dbg("%s", "Entering ........... \n"); | 721 | dbg("%s", "Entering ..........."); |
722 | 722 | ||
723 | if (urb->actual_length) { | 723 | if (urb->actual_length) { |
724 | tty = tty_port_tty_get(&mos7840_port->port->port); | 724 | tty = tty_port_tty_get(&mos7840_port->port->port); |
725 | if (tty) { | 725 | if (tty) { |
726 | tty_buffer_request_room(tty, urb->actual_length); | 726 | tty_buffer_request_room(tty, urb->actual_length); |
727 | tty_insert_flip_string(tty, data, urb->actual_length); | 727 | tty_insert_flip_string(tty, data, urb->actual_length); |
728 | dbg(" %s \n", data); | 728 | dbg(" %s ", data); |
729 | tty_flip_buffer_push(tty); | 729 | tty_flip_buffer_push(tty); |
730 | tty_kref_put(tty); | 730 | tty_kref_put(tty); |
731 | } | 731 | } |
732 | mos7840_port->icount.rx += urb->actual_length; | 732 | mos7840_port->icount.rx += urb->actual_length; |
733 | smp_wmb(); | 733 | smp_wmb(); |
734 | dbg("mos7840_port->icount.rx is %d:\n", | 734 | dbg("mos7840_port->icount.rx is %d:", |
735 | mos7840_port->icount.rx); | 735 | mos7840_port->icount.rx); |
736 | } | 736 | } |
737 | 737 | ||
738 | if (!mos7840_port->read_urb) { | 738 | if (!mos7840_port->read_urb) { |
739 | dbg("%s", "URB KILLED !!!\n"); | 739 | dbg("%s", "URB KILLED !!!"); |
740 | mos7840_port->read_urb_busy = false; | 740 | mos7840_port->read_urb_busy = false; |
741 | return; | 741 | return; |
742 | } | 742 | } |
@@ -777,16 +777,16 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) | |||
777 | spin_unlock(&mos7840_port->pool_lock); | 777 | spin_unlock(&mos7840_port->pool_lock); |
778 | 778 | ||
779 | if (status) { | 779 | if (status) { |
780 | dbg("nonzero write bulk status received:%d\n", status); | 780 | dbg("nonzero write bulk status received:%d", status); |
781 | return; | 781 | return; |
782 | } | 782 | } |
783 | 783 | ||
784 | if (mos7840_port_paranoia_check(mos7840_port->port, __func__)) { | 784 | if (mos7840_port_paranoia_check(mos7840_port->port, __func__)) { |
785 | dbg("%s", "Port Paranoia failed \n"); | 785 | dbg("%s", "Port Paranoia failed"); |
786 | return; | 786 | return; |
787 | } | 787 | } |
788 | 788 | ||
789 | dbg("%s \n", "Entering ........."); | 789 | dbg("%s", "Entering ........."); |
790 | 790 | ||
791 | tty = tty_port_tty_get(&mos7840_port->port->port); | 791 | tty = tty_port_tty_get(&mos7840_port->port->port); |
792 | if (tty && mos7840_port->open) | 792 | if (tty && mos7840_port->open) |
@@ -830,15 +830,17 @@ static int mos7840_open(struct tty_struct *tty, | |||
830 | struct moschip_port *mos7840_port; | 830 | struct moschip_port *mos7840_port; |
831 | struct moschip_port *port0; | 831 | struct moschip_port *port0; |
832 | 832 | ||
833 | dbg ("%s enter", __func__); | ||
834 | |||
833 | if (mos7840_port_paranoia_check(port, __func__)) { | 835 | if (mos7840_port_paranoia_check(port, __func__)) { |
834 | dbg("%s", "Port Paranoia failed \n"); | 836 | dbg("%s", "Port Paranoia failed"); |
835 | return -ENODEV; | 837 | return -ENODEV; |
836 | } | 838 | } |
837 | 839 | ||
838 | serial = port->serial; | 840 | serial = port->serial; |
839 | 841 | ||
840 | if (mos7840_serial_paranoia_check(serial, __func__)) { | 842 | if (mos7840_serial_paranoia_check(serial, __func__)) { |
841 | dbg("%s", "Serial Paranoia failed \n"); | 843 | dbg("%s", "Serial Paranoia failed"); |
842 | return -ENODEV; | 844 | return -ENODEV; |
843 | } | 845 | } |
844 | 846 | ||
@@ -891,20 +893,20 @@ static int mos7840_open(struct tty_struct *tty, | |||
891 | Data = 0x0; | 893 | Data = 0x0; |
892 | status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data); | 894 | status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data); |
893 | if (status < 0) { | 895 | if (status < 0) { |
894 | dbg("Reading Spreg failed\n"); | 896 | dbg("Reading Spreg failed"); |
895 | return -1; | 897 | return -1; |
896 | } | 898 | } |
897 | Data |= 0x80; | 899 | Data |= 0x80; |
898 | status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); | 900 | status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); |
899 | if (status < 0) { | 901 | if (status < 0) { |
900 | dbg("writing Spreg failed\n"); | 902 | dbg("writing Spreg failed"); |
901 | return -1; | 903 | return -1; |
902 | } | 904 | } |
903 | 905 | ||
904 | Data &= ~0x80; | 906 | Data &= ~0x80; |
905 | status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); | 907 | status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); |
906 | if (status < 0) { | 908 | if (status < 0) { |
907 | dbg("writing Spreg failed\n"); | 909 | dbg("writing Spreg failed"); |
908 | return -1; | 910 | return -1; |
909 | } | 911 | } |
910 | /* End of block to be checked */ | 912 | /* End of block to be checked */ |
@@ -913,7 +915,7 @@ static int mos7840_open(struct tty_struct *tty, | |||
913 | status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, | 915 | status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, |
914 | &Data); | 916 | &Data); |
915 | if (status < 0) { | 917 | if (status < 0) { |
916 | dbg("Reading Controlreg failed\n"); | 918 | dbg("Reading Controlreg failed"); |
917 | return -1; | 919 | return -1; |
918 | } | 920 | } |
919 | Data |= 0x08; /* Driver done bit */ | 921 | Data |= 0x08; /* Driver done bit */ |
@@ -921,7 +923,7 @@ static int mos7840_open(struct tty_struct *tty, | |||
921 | status = mos7840_set_reg_sync(port, | 923 | status = mos7840_set_reg_sync(port, |
922 | mos7840_port->ControlRegOffset, Data); | 924 | mos7840_port->ControlRegOffset, Data); |
923 | if (status < 0) { | 925 | if (status < 0) { |
924 | dbg("writing Controlreg failed\n"); | 926 | dbg("writing Controlreg failed"); |
925 | return -1; | 927 | return -1; |
926 | } | 928 | } |
927 | /* do register settings here */ | 929 | /* do register settings here */ |
@@ -932,21 +934,21 @@ static int mos7840_open(struct tty_struct *tty, | |||
932 | Data = 0x00; | 934 | Data = 0x00; |
933 | status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); | 935 | status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); |
934 | if (status < 0) { | 936 | if (status < 0) { |
935 | dbg("disableing interrupts failed\n"); | 937 | dbg("disabling interrupts failed"); |
936 | return -1; | 938 | return -1; |
937 | } | 939 | } |
938 | /* Set FIFO_CONTROL_REGISTER to the default value */ | 940 | /* Set FIFO_CONTROL_REGISTER to the default value */ |
939 | Data = 0x00; | 941 | Data = 0x00; |
940 | status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); | 942 | status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); |
941 | if (status < 0) { | 943 | if (status < 0) { |
942 | dbg("Writing FIFO_CONTROL_REGISTER failed\n"); | 944 | dbg("Writing FIFO_CONTROL_REGISTER failed"); |
943 | return -1; | 945 | return -1; |
944 | } | 946 | } |
945 | 947 | ||
946 | Data = 0xcf; | 948 | Data = 0xcf; |
947 | status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); | 949 | status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); |
948 | if (status < 0) { | 950 | if (status < 0) { |
949 | dbg("Writing FIFO_CONTROL_REGISTER failed\n"); | 951 | dbg("Writing FIFO_CONTROL_REGISTER failed"); |
950 | return -1; | 952 | return -1; |
951 | } | 953 | } |
952 | 954 | ||
@@ -1043,12 +1045,12 @@ static int mos7840_open(struct tty_struct *tty, | |||
1043 | * (can't set it up in mos7840_startup as the * | 1045 | * (can't set it up in mos7840_startup as the * |
1044 | * structures were not set up at that time.) */ | 1046 | * structures were not set up at that time.) */ |
1045 | 1047 | ||
1046 | dbg("port number is %d \n", port->number); | 1048 | dbg("port number is %d", port->number); |
1047 | dbg("serial number is %d \n", port->serial->minor); | 1049 | dbg("serial number is %d", port->serial->minor); |
1048 | dbg("Bulkin endpoint is %d \n", port->bulk_in_endpointAddress); | 1050 | dbg("Bulkin endpoint is %d", port->bulk_in_endpointAddress); |
1049 | dbg("BulkOut endpoint is %d \n", port->bulk_out_endpointAddress); | 1051 | dbg("BulkOut endpoint is %d", port->bulk_out_endpointAddress); |
1050 | dbg("Interrupt endpoint is %d \n", port->interrupt_in_endpointAddress); | 1052 | dbg("Interrupt endpoint is %d", port->interrupt_in_endpointAddress); |
1051 | dbg("port's number in the device is %d\n", mos7840_port->port_num); | 1053 | dbg("port's number in the device is %d", mos7840_port->port_num); |
1052 | mos7840_port->read_urb = port->read_urb; | 1054 | mos7840_port->read_urb = port->read_urb; |
1053 | 1055 | ||
1054 | /* set up our bulk in urb */ | 1056 | /* set up our bulk in urb */ |
@@ -1061,7 +1063,7 @@ static int mos7840_open(struct tty_struct *tty, | |||
1061 | mos7840_port->read_urb->transfer_buffer_length, | 1063 | mos7840_port->read_urb->transfer_buffer_length, |
1062 | mos7840_bulk_in_callback, mos7840_port); | 1064 | mos7840_bulk_in_callback, mos7840_port); |
1063 | 1065 | ||
1064 | dbg("mos7840_open: bulkin endpoint is %d\n", | 1066 | dbg("mos7840_open: bulkin endpoint is %d", |
1065 | port->bulk_in_endpointAddress); | 1067 | port->bulk_in_endpointAddress); |
1066 | mos7840_port->read_urb_busy = true; | 1068 | mos7840_port->read_urb_busy = true; |
1067 | response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL); | 1069 | response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL); |
@@ -1087,9 +1089,11 @@ static int mos7840_open(struct tty_struct *tty, | |||
1087 | mos7840_port->icount.tx = 0; | 1089 | mos7840_port->icount.tx = 0; |
1088 | mos7840_port->icount.rx = 0; | 1090 | mos7840_port->icount.rx = 0; |
1089 | 1091 | ||
1090 | dbg("\n\nusb_serial serial:%p mos7840_port:%p\n usb_serial_port port:%p\n\n", | 1092 | dbg("usb_serial serial:%p mos7840_port:%p\n usb_serial_port port:%p", |
1091 | serial, mos7840_port, port); | 1093 | serial, mos7840_port, port); |
1092 | 1094 | ||
1095 | dbg ("%s leave", __func__); | ||
1096 | |||
1093 | return 0; | 1097 | return 0; |
1094 | 1098 | ||
1095 | } | 1099 | } |
@@ -1112,16 +1116,16 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty) | |||
1112 | unsigned long flags; | 1116 | unsigned long flags; |
1113 | struct moschip_port *mos7840_port; | 1117 | struct moschip_port *mos7840_port; |
1114 | 1118 | ||
1115 | dbg("%s \n", " mos7840_chars_in_buffer:entering ..........."); | 1119 | dbg("%s", " mos7840_chars_in_buffer:entering ..........."); |
1116 | 1120 | ||
1117 | if (mos7840_port_paranoia_check(port, __func__)) { | 1121 | if (mos7840_port_paranoia_check(port, __func__)) { |
1118 | dbg("%s", "Invalid port \n"); | 1122 | dbg("%s", "Invalid port"); |
1119 | return 0; | 1123 | return 0; |
1120 | } | 1124 | } |
1121 | 1125 | ||
1122 | mos7840_port = mos7840_get_port_private(port); | 1126 | mos7840_port = mos7840_get_port_private(port); |
1123 | if (mos7840_port == NULL) { | 1127 | if (mos7840_port == NULL) { |
1124 | dbg("%s \n", "mos7840_break:leaving ..........."); | 1128 | dbg("%s", "mos7840_break:leaving ..........."); |
1125 | return 0; | 1129 | return 0; |
1126 | } | 1130 | } |
1127 | 1131 | ||
@@ -1135,54 +1139,12 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty) | |||
1135 | 1139 | ||
1136 | } | 1140 | } |
1137 | 1141 | ||
1138 | /************************************************************************ | ||
1139 | * | ||
1140 | * mos7840_block_until_tx_empty | ||
1141 | * | ||
1142 | * This function will block the close until one of the following: | ||
1143 | * 1. TX count are 0 | ||
1144 | * 2. The mos7840 has stopped | ||
1145 | * 3. A timeout of 3 seconds without activity has expired | ||
1146 | * | ||
1147 | ************************************************************************/ | ||
1148 | static void mos7840_block_until_tx_empty(struct tty_struct *tty, | ||
1149 | struct moschip_port *mos7840_port) | ||
1150 | { | ||
1151 | int timeout = HZ / 10; | ||
1152 | int wait = 30; | ||
1153 | int count; | ||
1154 | |||
1155 | while (1) { | ||
1156 | |||
1157 | count = mos7840_chars_in_buffer(tty); | ||
1158 | |||
1159 | /* Check for Buffer status */ | ||
1160 | if (count <= 0) | ||
1161 | return; | ||
1162 | |||
1163 | /* Block the thread for a while */ | ||
1164 | interruptible_sleep_on_timeout(&mos7840_port->wait_chase, | ||
1165 | timeout); | ||
1166 | |||
1167 | /* No activity.. count down section */ | ||
1168 | wait--; | ||
1169 | if (wait == 0) { | ||
1170 | dbg("%s - TIMEOUT", __func__); | ||
1171 | return; | ||
1172 | } else { | ||
1173 | /* Reset timeout value back to seconds */ | ||
1174 | wait = 30; | ||
1175 | } | ||
1176 | } | ||
1177 | } | ||
1178 | |||
1179 | /***************************************************************************** | 1142 | /***************************************************************************** |
1180 | * mos7840_close | 1143 | * mos7840_close |
1181 | * this function is called by the tty driver when a port is closed | 1144 | * this function is called by the tty driver when a port is closed |
1182 | *****************************************************************************/ | 1145 | *****************************************************************************/ |
1183 | 1146 | ||
1184 | static void mos7840_close(struct tty_struct *tty, | 1147 | static void mos7840_close(struct usb_serial_port *port) |
1185 | struct usb_serial_port *port, struct file *filp) | ||
1186 | { | 1148 | { |
1187 | struct usb_serial *serial; | 1149 | struct usb_serial *serial; |
1188 | struct moschip_port *mos7840_port; | 1150 | struct moschip_port *mos7840_port; |
@@ -1190,16 +1152,16 @@ static void mos7840_close(struct tty_struct *tty, | |||
1190 | int j; | 1152 | int j; |
1191 | __u16 Data; | 1153 | __u16 Data; |
1192 | 1154 | ||
1193 | dbg("%s\n", "mos7840_close:entering..."); | 1155 | dbg("%s", "mos7840_close:entering..."); |
1194 | 1156 | ||
1195 | if (mos7840_port_paranoia_check(port, __func__)) { | 1157 | if (mos7840_port_paranoia_check(port, __func__)) { |
1196 | dbg("%s", "Port Paranoia failed \n"); | 1158 | dbg("%s", "Port Paranoia failed"); |
1197 | return; | 1159 | return; |
1198 | } | 1160 | } |
1199 | 1161 | ||
1200 | serial = mos7840_get_usb_serial(port, __func__); | 1162 | serial = mos7840_get_usb_serial(port, __func__); |
1201 | if (!serial) { | 1163 | if (!serial) { |
1202 | dbg("%s", "Serial Paranoia failed \n"); | 1164 | dbg("%s", "Serial Paranoia failed"); |
1203 | return; | 1165 | return; |
1204 | } | 1166 | } |
1205 | 1167 | ||
@@ -1223,35 +1185,31 @@ static void mos7840_close(struct tty_struct *tty, | |||
1223 | } | 1185 | } |
1224 | } | 1186 | } |
1225 | 1187 | ||
1226 | if (serial->dev) | ||
1227 | /* flush and block until tx is empty */ | ||
1228 | mos7840_block_until_tx_empty(tty, mos7840_port); | ||
1229 | |||
1230 | /* While closing port, shutdown all bulk read, write * | 1188 | /* While closing port, shutdown all bulk read, write * |
1231 | * and interrupt read if they exists */ | 1189 | * and interrupt read if they exists */ |
1232 | if (serial->dev) { | 1190 | if (serial->dev) { |
1233 | if (mos7840_port->write_urb) { | 1191 | if (mos7840_port->write_urb) { |
1234 | dbg("%s", "Shutdown bulk write\n"); | 1192 | dbg("%s", "Shutdown bulk write"); |
1235 | usb_kill_urb(mos7840_port->write_urb); | 1193 | usb_kill_urb(mos7840_port->write_urb); |
1236 | } | 1194 | } |
1237 | if (mos7840_port->read_urb) { | 1195 | if (mos7840_port->read_urb) { |
1238 | dbg("%s", "Shutdown bulk read\n"); | 1196 | dbg("%s", "Shutdown bulk read"); |
1239 | usb_kill_urb(mos7840_port->read_urb); | 1197 | usb_kill_urb(mos7840_port->read_urb); |
1240 | mos7840_port->read_urb_busy = false; | 1198 | mos7840_port->read_urb_busy = false; |
1241 | } | 1199 | } |
1242 | if ((&mos7840_port->control_urb)) { | 1200 | if ((&mos7840_port->control_urb)) { |
1243 | dbg("%s", "Shutdown control read\n"); | 1201 | dbg("%s", "Shutdown control read"); |
1244 | /*/ usb_kill_urb (mos7840_port->control_urb); */ | 1202 | /*/ usb_kill_urb (mos7840_port->control_urb); */ |
1245 | } | 1203 | } |
1246 | } | 1204 | } |
1247 | /* if(mos7840_port->ctrl_buf != NULL) */ | 1205 | /* if(mos7840_port->ctrl_buf != NULL) */ |
1248 | /* kfree(mos7840_port->ctrl_buf); */ | 1206 | /* kfree(mos7840_port->ctrl_buf); */ |
1249 | port0->open_ports--; | 1207 | port0->open_ports--; |
1250 | dbg("mos7840_num_open_ports in close%d:in port%d\n", | 1208 | dbg("mos7840_num_open_ports in close%d:in port%d", |
1251 | port0->open_ports, port->number); | 1209 | port0->open_ports, port->number); |
1252 | if (port0->open_ports == 0) { | 1210 | if (port0->open_ports == 0) { |
1253 | if (serial->port[0]->interrupt_in_urb) { | 1211 | if (serial->port[0]->interrupt_in_urb) { |
1254 | dbg("%s", "Shutdown interrupt_in_urb\n"); | 1212 | dbg("%s", "Shutdown interrupt_in_urb"); |
1255 | usb_kill_urb(serial->port[0]->interrupt_in_urb); | 1213 | usb_kill_urb(serial->port[0]->interrupt_in_urb); |
1256 | } | 1214 | } |
1257 | } | 1215 | } |
@@ -1271,7 +1229,7 @@ static void mos7840_close(struct tty_struct *tty, | |||
1271 | 1229 | ||
1272 | mos7840_port->open = 0; | 1230 | mos7840_port->open = 0; |
1273 | 1231 | ||
1274 | dbg("%s \n", "Leaving ............"); | 1232 | dbg("%s", "Leaving ............"); |
1275 | } | 1233 | } |
1276 | 1234 | ||
1277 | /************************************************************************ | 1235 | /************************************************************************ |
@@ -1326,17 +1284,17 @@ static void mos7840_break(struct tty_struct *tty, int break_state) | |||
1326 | struct usb_serial *serial; | 1284 | struct usb_serial *serial; |
1327 | struct moschip_port *mos7840_port; | 1285 | struct moschip_port *mos7840_port; |
1328 | 1286 | ||
1329 | dbg("%s \n", "Entering ..........."); | 1287 | dbg("%s", "Entering ..........."); |
1330 | dbg("mos7840_break: Start\n"); | 1288 | dbg("mos7840_break: Start"); |
1331 | 1289 | ||
1332 | if (mos7840_port_paranoia_check(port, __func__)) { | 1290 | if (mos7840_port_paranoia_check(port, __func__)) { |
1333 | dbg("%s", "Port Paranoia failed \n"); | 1291 | dbg("%s", "Port Paranoia failed"); |
1334 | return; | 1292 | return; |
1335 | } | 1293 | } |
1336 | 1294 | ||
1337 | serial = mos7840_get_usb_serial(port, __func__); | 1295 | serial = mos7840_get_usb_serial(port, __func__); |
1338 | if (!serial) { | 1296 | if (!serial) { |
1339 | dbg("%s", "Serial Paranoia failed \n"); | 1297 | dbg("%s", "Serial Paranoia failed"); |
1340 | return; | 1298 | return; |
1341 | } | 1299 | } |
1342 | 1300 | ||
@@ -1356,7 +1314,7 @@ static void mos7840_break(struct tty_struct *tty, int break_state) | |||
1356 | 1314 | ||
1357 | /* FIXME: no locking on shadowLCR anywhere in driver */ | 1315 | /* FIXME: no locking on shadowLCR anywhere in driver */ |
1358 | mos7840_port->shadowLCR = data; | 1316 | mos7840_port->shadowLCR = data; |
1359 | dbg("mcs7840_break mos7840_port->shadowLCR is %x\n", | 1317 | dbg("mcs7840_break mos7840_port->shadowLCR is %x", |
1360 | mos7840_port->shadowLCR); | 1318 | mos7840_port->shadowLCR); |
1361 | mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, | 1319 | mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, |
1362 | mos7840_port->shadowLCR); | 1320 | mos7840_port->shadowLCR); |
@@ -1380,17 +1338,17 @@ static int mos7840_write_room(struct tty_struct *tty) | |||
1380 | unsigned long flags; | 1338 | unsigned long flags; |
1381 | struct moschip_port *mos7840_port; | 1339 | struct moschip_port *mos7840_port; |
1382 | 1340 | ||
1383 | dbg("%s \n", " mos7840_write_room:entering ..........."); | 1341 | dbg("%s", " mos7840_write_room:entering ..........."); |
1384 | 1342 | ||
1385 | if (mos7840_port_paranoia_check(port, __func__)) { | 1343 | if (mos7840_port_paranoia_check(port, __func__)) { |
1386 | dbg("%s", "Invalid port \n"); | 1344 | dbg("%s", "Invalid port"); |
1387 | dbg("%s \n", " mos7840_write_room:leaving ..........."); | 1345 | dbg("%s", " mos7840_write_room:leaving ..........."); |
1388 | return -1; | 1346 | return -1; |
1389 | } | 1347 | } |
1390 | 1348 | ||
1391 | mos7840_port = mos7840_get_port_private(port); | 1349 | mos7840_port = mos7840_get_port_private(port); |
1392 | if (mos7840_port == NULL) { | 1350 | if (mos7840_port == NULL) { |
1393 | dbg("%s \n", "mos7840_break:leaving ..........."); | 1351 | dbg("%s", "mos7840_break:leaving ..........."); |
1394 | return -1; | 1352 | return -1; |
1395 | } | 1353 | } |
1396 | 1354 | ||
@@ -1430,16 +1388,16 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1430 | /* __u16 Data; */ | 1388 | /* __u16 Data; */ |
1431 | const unsigned char *current_position = data; | 1389 | const unsigned char *current_position = data; |
1432 | unsigned char *data1; | 1390 | unsigned char *data1; |
1433 | dbg("%s \n", "entering ..........."); | 1391 | dbg("%s", "entering ..........."); |
1434 | /* dbg("mos7840_write: mos7840_port->shadowLCR is %x\n", | 1392 | /* dbg("mos7840_write: mos7840_port->shadowLCR is %x", |
1435 | mos7840_port->shadowLCR); */ | 1393 | mos7840_port->shadowLCR); */ |
1436 | 1394 | ||
1437 | #ifdef NOTMOS7840 | 1395 | #ifdef NOTMOS7840 |
1438 | Data = 0x00; | 1396 | Data = 0x00; |
1439 | status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data); | 1397 | status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data); |
1440 | mos7840_port->shadowLCR = Data; | 1398 | mos7840_port->shadowLCR = Data; |
1441 | dbg("mos7840_write: LINE_CONTROL_REGISTER is %x\n", Data); | 1399 | dbg("mos7840_write: LINE_CONTROL_REGISTER is %x", Data); |
1442 | dbg("mos7840_write: mos7840_port->shadowLCR is %x\n", | 1400 | dbg("mos7840_write: mos7840_port->shadowLCR is %x", |
1443 | mos7840_port->shadowLCR); | 1401 | mos7840_port->shadowLCR); |
1444 | 1402 | ||
1445 | /* Data = 0x03; */ | 1403 | /* Data = 0x03; */ |
@@ -1453,32 +1411,32 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1453 | /* status = mos7840_set_uart_reg(port,DIVISOR_LATCH_LSB,Data); */ | 1411 | /* status = mos7840_set_uart_reg(port,DIVISOR_LATCH_LSB,Data); */ |
1454 | Data = 0x00; | 1412 | Data = 0x00; |
1455 | status = mos7840_get_uart_reg(port, DIVISOR_LATCH_LSB, &Data); | 1413 | status = mos7840_get_uart_reg(port, DIVISOR_LATCH_LSB, &Data); |
1456 | dbg("mos7840_write:DLL value is %x\n", Data); | 1414 | dbg("mos7840_write:DLL value is %x", Data); |
1457 | 1415 | ||
1458 | Data = 0x0; | 1416 | Data = 0x0; |
1459 | status = mos7840_get_uart_reg(port, DIVISOR_LATCH_MSB, &Data); | 1417 | status = mos7840_get_uart_reg(port, DIVISOR_LATCH_MSB, &Data); |
1460 | dbg("mos7840_write:DLM value is %x\n", Data); | 1418 | dbg("mos7840_write:DLM value is %x", Data); |
1461 | 1419 | ||
1462 | Data = Data & ~SERIAL_LCR_DLAB; | 1420 | Data = Data & ~SERIAL_LCR_DLAB; |
1463 | dbg("mos7840_write: mos7840_port->shadowLCR is %x\n", | 1421 | dbg("mos7840_write: mos7840_port->shadowLCR is %x", |
1464 | mos7840_port->shadowLCR); | 1422 | mos7840_port->shadowLCR); |
1465 | status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); | 1423 | status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); |
1466 | #endif | 1424 | #endif |
1467 | 1425 | ||
1468 | if (mos7840_port_paranoia_check(port, __func__)) { | 1426 | if (mos7840_port_paranoia_check(port, __func__)) { |
1469 | dbg("%s", "Port Paranoia failed \n"); | 1427 | dbg("%s", "Port Paranoia failed"); |
1470 | return -1; | 1428 | return -1; |
1471 | } | 1429 | } |
1472 | 1430 | ||
1473 | serial = port->serial; | 1431 | serial = port->serial; |
1474 | if (mos7840_serial_paranoia_check(serial, __func__)) { | 1432 | if (mos7840_serial_paranoia_check(serial, __func__)) { |
1475 | dbg("%s", "Serial Paranoia failed \n"); | 1433 | dbg("%s", "Serial Paranoia failed"); |
1476 | return -1; | 1434 | return -1; |
1477 | } | 1435 | } |
1478 | 1436 | ||
1479 | mos7840_port = mos7840_get_port_private(port); | 1437 | mos7840_port = mos7840_get_port_private(port); |
1480 | if (mos7840_port == NULL) { | 1438 | if (mos7840_port == NULL) { |
1481 | dbg("%s", "mos7840_port is NULL\n"); | 1439 | dbg("%s", "mos7840_port is NULL"); |
1482 | return -1; | 1440 | return -1; |
1483 | } | 1441 | } |
1484 | 1442 | ||
@@ -1490,7 +1448,7 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1490 | if (!mos7840_port->busy[i]) { | 1448 | if (!mos7840_port->busy[i]) { |
1491 | mos7840_port->busy[i] = 1; | 1449 | mos7840_port->busy[i] = 1; |
1492 | urb = mos7840_port->write_urb_pool[i]; | 1450 | urb = mos7840_port->write_urb_pool[i]; |
1493 | dbg("\nURB:%d", i); | 1451 | dbg("URB:%d", i); |
1494 | break; | 1452 | break; |
1495 | } | 1453 | } |
1496 | } | 1454 | } |
@@ -1525,7 +1483,7 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1525 | mos7840_bulk_out_data_callback, mos7840_port); | 1483 | mos7840_bulk_out_data_callback, mos7840_port); |
1526 | 1484 | ||
1527 | data1 = urb->transfer_buffer; | 1485 | data1 = urb->transfer_buffer; |
1528 | dbg("\nbulkout endpoint is %d", port->bulk_out_endpointAddress); | 1486 | dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress); |
1529 | 1487 | ||
1530 | /* send it down the pipe */ | 1488 | /* send it down the pipe */ |
1531 | status = usb_submit_urb(urb, GFP_ATOMIC); | 1489 | status = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -1540,7 +1498,7 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1540 | bytes_sent = transfer_size; | 1498 | bytes_sent = transfer_size; |
1541 | mos7840_port->icount.tx += transfer_size; | 1499 | mos7840_port->icount.tx += transfer_size; |
1542 | smp_wmb(); | 1500 | smp_wmb(); |
1543 | dbg("mos7840_port->icount.tx is %d:\n", mos7840_port->icount.tx); | 1501 | dbg("mos7840_port->icount.tx is %d:", mos7840_port->icount.tx); |
1544 | exit: | 1502 | exit: |
1545 | return bytes_sent; | 1503 | return bytes_sent; |
1546 | 1504 | ||
@@ -1559,11 +1517,11 @@ static void mos7840_throttle(struct tty_struct *tty) | |||
1559 | int status; | 1517 | int status; |
1560 | 1518 | ||
1561 | if (mos7840_port_paranoia_check(port, __func__)) { | 1519 | if (mos7840_port_paranoia_check(port, __func__)) { |
1562 | dbg("%s", "Invalid port \n"); | 1520 | dbg("%s", "Invalid port"); |
1563 | return; | 1521 | return; |
1564 | } | 1522 | } |
1565 | 1523 | ||
1566 | dbg("- port %d\n", port->number); | 1524 | dbg("- port %d", port->number); |
1567 | 1525 | ||
1568 | mos7840_port = mos7840_get_port_private(port); | 1526 | mos7840_port = mos7840_get_port_private(port); |
1569 | 1527 | ||
@@ -1571,11 +1529,11 @@ static void mos7840_throttle(struct tty_struct *tty) | |||
1571 | return; | 1529 | return; |
1572 | 1530 | ||
1573 | if (!mos7840_port->open) { | 1531 | if (!mos7840_port->open) { |
1574 | dbg("%s\n", "port not opened"); | 1532 | dbg("%s", "port not opened"); |
1575 | return; | 1533 | return; |
1576 | } | 1534 | } |
1577 | 1535 | ||
1578 | dbg("%s", "Entering .......... \n"); | 1536 | dbg("%s", "Entering .........."); |
1579 | 1537 | ||
1580 | /* if we are implementing XON/XOFF, send the stop character */ | 1538 | /* if we are implementing XON/XOFF, send the stop character */ |
1581 | if (I_IXOFF(tty)) { | 1539 | if (I_IXOFF(tty)) { |
@@ -1609,7 +1567,7 @@ static void mos7840_unthrottle(struct tty_struct *tty) | |||
1609 | struct moschip_port *mos7840_port = mos7840_get_port_private(port); | 1567 | struct moschip_port *mos7840_port = mos7840_get_port_private(port); |
1610 | 1568 | ||
1611 | if (mos7840_port_paranoia_check(port, __func__)) { | 1569 | if (mos7840_port_paranoia_check(port, __func__)) { |
1612 | dbg("%s", "Invalid port \n"); | 1570 | dbg("%s", "Invalid port"); |
1613 | return; | 1571 | return; |
1614 | } | 1572 | } |
1615 | 1573 | ||
@@ -1621,7 +1579,7 @@ static void mos7840_unthrottle(struct tty_struct *tty) | |||
1621 | return; | 1579 | return; |
1622 | } | 1580 | } |
1623 | 1581 | ||
1624 | dbg("%s", "Entering .......... \n"); | 1582 | dbg("%s", "Entering .........."); |
1625 | 1583 | ||
1626 | /* if we are implementing XON/XOFF, send the start character */ | 1584 | /* if we are implementing XON/XOFF, send the start character */ |
1627 | if (I_IXOFF(tty)) { | 1585 | if (I_IXOFF(tty)) { |
@@ -1706,7 +1664,7 @@ static int mos7840_tiocmset(struct tty_struct *tty, struct file *file, | |||
1706 | 1664 | ||
1707 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr); | 1665 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr); |
1708 | if (status < 0) { | 1666 | if (status < 0) { |
1709 | dbg("setting MODEM_CONTROL_REGISTER Failed\n"); | 1667 | dbg("setting MODEM_CONTROL_REGISTER Failed"); |
1710 | return status; | 1668 | return status; |
1711 | } | 1669 | } |
1712 | 1670 | ||
@@ -1775,11 +1733,11 @@ static int mos7840_calc_baud_rate_divisor(int baudRate, int *divisor, | |||
1775 | custom++; | 1733 | custom++; |
1776 | *divisor = custom; | 1734 | *divisor = custom; |
1777 | 1735 | ||
1778 | dbg(" Baud %d = %d\n", baudrate, custom); | 1736 | dbg(" Baud %d = %d", baudrate, custom); |
1779 | return 0; | 1737 | return 0; |
1780 | } | 1738 | } |
1781 | 1739 | ||
1782 | dbg("%s\n", " Baud calculation Failed..."); | 1740 | dbg("%s", " Baud calculation Failed..."); |
1783 | return -1; | 1741 | return -1; |
1784 | #endif | 1742 | #endif |
1785 | } | 1743 | } |
@@ -1805,16 +1763,16 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, | |||
1805 | 1763 | ||
1806 | port = (struct usb_serial_port *)mos7840_port->port; | 1764 | port = (struct usb_serial_port *)mos7840_port->port; |
1807 | if (mos7840_port_paranoia_check(port, __func__)) { | 1765 | if (mos7840_port_paranoia_check(port, __func__)) { |
1808 | dbg("%s", "Invalid port \n"); | 1766 | dbg("%s", "Invalid port"); |
1809 | return -1; | 1767 | return -1; |
1810 | } | 1768 | } |
1811 | 1769 | ||
1812 | if (mos7840_serial_paranoia_check(port->serial, __func__)) { | 1770 | if (mos7840_serial_paranoia_check(port->serial, __func__)) { |
1813 | dbg("%s", "Invalid Serial \n"); | 1771 | dbg("%s", "Invalid Serial"); |
1814 | return -1; | 1772 | return -1; |
1815 | } | 1773 | } |
1816 | 1774 | ||
1817 | dbg("%s", "Entering .......... \n"); | 1775 | dbg("%s", "Entering .........."); |
1818 | 1776 | ||
1819 | number = mos7840_port->port->number - mos7840_port->port->serial->minor; | 1777 | number = mos7840_port->port->number - mos7840_port->port->serial->minor; |
1820 | 1778 | ||
@@ -1830,7 +1788,7 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, | |||
1830 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, | 1788 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, |
1831 | Data); | 1789 | Data); |
1832 | if (status < 0) { | 1790 | if (status < 0) { |
1833 | dbg("Writing spreg failed in set_serial_baud\n"); | 1791 | dbg("Writing spreg failed in set_serial_baud"); |
1834 | return -1; | 1792 | return -1; |
1835 | } | 1793 | } |
1836 | #endif | 1794 | #endif |
@@ -1843,7 +1801,7 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, | |||
1843 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, | 1801 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, |
1844 | Data); | 1802 | Data); |
1845 | if (status < 0) { | 1803 | if (status < 0) { |
1846 | dbg("Writing spreg failed in set_serial_baud\n"); | 1804 | dbg("Writing spreg failed in set_serial_baud"); |
1847 | return -1; | 1805 | return -1; |
1848 | } | 1806 | } |
1849 | #endif | 1807 | #endif |
@@ -1858,14 +1816,14 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, | |||
1858 | status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, | 1816 | status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, |
1859 | &Data); | 1817 | &Data); |
1860 | if (status < 0) { | 1818 | if (status < 0) { |
1861 | dbg("reading spreg failed in set_serial_baud\n"); | 1819 | dbg("reading spreg failed in set_serial_baud"); |
1862 | return -1; | 1820 | return -1; |
1863 | } | 1821 | } |
1864 | Data = (Data & 0x8f) | clk_sel_val; | 1822 | Data = (Data & 0x8f) | clk_sel_val; |
1865 | status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, | 1823 | status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, |
1866 | Data); | 1824 | Data); |
1867 | if (status < 0) { | 1825 | if (status < 0) { |
1868 | dbg("Writing spreg failed in set_serial_baud\n"); | 1826 | dbg("Writing spreg failed in set_serial_baud"); |
1869 | return -1; | 1827 | return -1; |
1870 | } | 1828 | } |
1871 | /* Calculate the Divisor */ | 1829 | /* Calculate the Divisor */ |
@@ -1881,11 +1839,11 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, | |||
1881 | 1839 | ||
1882 | /* Write the divisor */ | 1840 | /* Write the divisor */ |
1883 | Data = (unsigned char)(divisor & 0xff); | 1841 | Data = (unsigned char)(divisor & 0xff); |
1884 | dbg("set_serial_baud Value to write DLL is %x\n", Data); | 1842 | dbg("set_serial_baud Value to write DLL is %x", Data); |
1885 | mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data); | 1843 | mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data); |
1886 | 1844 | ||
1887 | Data = (unsigned char)((divisor & 0xff00) >> 8); | 1845 | Data = (unsigned char)((divisor & 0xff00) >> 8); |
1888 | dbg("set_serial_baud Value to write DLM is %x\n", Data); | 1846 | dbg("set_serial_baud Value to write DLM is %x", Data); |
1889 | mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data); | 1847 | mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data); |
1890 | 1848 | ||
1891 | /* Disable access to divisor latch */ | 1849 | /* Disable access to divisor latch */ |
@@ -1923,12 +1881,12 @@ static void mos7840_change_port_settings(struct tty_struct *tty, | |||
1923 | port = (struct usb_serial_port *)mos7840_port->port; | 1881 | port = (struct usb_serial_port *)mos7840_port->port; |
1924 | 1882 | ||
1925 | if (mos7840_port_paranoia_check(port, __func__)) { | 1883 | if (mos7840_port_paranoia_check(port, __func__)) { |
1926 | dbg("%s", "Invalid port \n"); | 1884 | dbg("%s", "Invalid port"); |
1927 | return; | 1885 | return; |
1928 | } | 1886 | } |
1929 | 1887 | ||
1930 | if (mos7840_serial_paranoia_check(port->serial, __func__)) { | 1888 | if (mos7840_serial_paranoia_check(port->serial, __func__)) { |
1931 | dbg("%s", "Invalid Serial \n"); | 1889 | dbg("%s", "Invalid Serial"); |
1932 | return; | 1890 | return; |
1933 | } | 1891 | } |
1934 | 1892 | ||
@@ -1941,7 +1899,7 @@ static void mos7840_change_port_settings(struct tty_struct *tty, | |||
1941 | return; | 1899 | return; |
1942 | } | 1900 | } |
1943 | 1901 | ||
1944 | dbg("%s", "Entering .......... \n"); | 1902 | dbg("%s", "Entering .........."); |
1945 | 1903 | ||
1946 | lData = LCR_BITS_8; | 1904 | lData = LCR_BITS_8; |
1947 | lStop = LCR_STOP_1; | 1905 | lStop = LCR_STOP_1; |
@@ -2001,7 +1959,7 @@ static void mos7840_change_port_settings(struct tty_struct *tty, | |||
2001 | ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); | 1959 | ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); |
2002 | mos7840_port->shadowLCR |= (lData | lParity | lStop); | 1960 | mos7840_port->shadowLCR |= (lData | lParity | lStop); |
2003 | 1961 | ||
2004 | dbg("mos7840_change_port_settings mos7840_port->shadowLCR is %x\n", | 1962 | dbg("mos7840_change_port_settings mos7840_port->shadowLCR is %x", |
2005 | mos7840_port->shadowLCR); | 1963 | mos7840_port->shadowLCR); |
2006 | /* Disable Interrupts */ | 1964 | /* Disable Interrupts */ |
2007 | Data = 0x00; | 1965 | Data = 0x00; |
@@ -2043,7 +2001,7 @@ static void mos7840_change_port_settings(struct tty_struct *tty, | |||
2043 | 2001 | ||
2044 | if (!baud) { | 2002 | if (!baud) { |
2045 | /* pick a default, any default... */ | 2003 | /* pick a default, any default... */ |
2046 | dbg("%s\n", "Picked default baud..."); | 2004 | dbg("%s", "Picked default baud..."); |
2047 | baud = 9600; | 2005 | baud = 9600; |
2048 | } | 2006 | } |
2049 | 2007 | ||
@@ -2066,7 +2024,7 @@ static void mos7840_change_port_settings(struct tty_struct *tty, | |||
2066 | } | 2024 | } |
2067 | wake_up(&mos7840_port->delta_msr_wait); | 2025 | wake_up(&mos7840_port->delta_msr_wait); |
2068 | mos7840_port->delta_msr_cond = 1; | 2026 | mos7840_port->delta_msr_cond = 1; |
2069 | dbg("mos7840_change_port_settings mos7840_port->shadowLCR is End %x\n", | 2027 | dbg("mos7840_change_port_settings mos7840_port->shadowLCR is End %x", |
2070 | mos7840_port->shadowLCR); | 2028 | mos7840_port->shadowLCR); |
2071 | 2029 | ||
2072 | return; | 2030 | return; |
@@ -2086,16 +2044,16 @@ static void mos7840_set_termios(struct tty_struct *tty, | |||
2086 | unsigned int cflag; | 2044 | unsigned int cflag; |
2087 | struct usb_serial *serial; | 2045 | struct usb_serial *serial; |
2088 | struct moschip_port *mos7840_port; | 2046 | struct moschip_port *mos7840_port; |
2089 | dbg("mos7840_set_termios: START\n"); | 2047 | dbg("mos7840_set_termios: START"); |
2090 | if (mos7840_port_paranoia_check(port, __func__)) { | 2048 | if (mos7840_port_paranoia_check(port, __func__)) { |
2091 | dbg("%s", "Invalid port \n"); | 2049 | dbg("%s", "Invalid port"); |
2092 | return; | 2050 | return; |
2093 | } | 2051 | } |
2094 | 2052 | ||
2095 | serial = port->serial; | 2053 | serial = port->serial; |
2096 | 2054 | ||
2097 | if (mos7840_serial_paranoia_check(serial, __func__)) { | 2055 | if (mos7840_serial_paranoia_check(serial, __func__)) { |
2098 | dbg("%s", "Invalid Serial \n"); | 2056 | dbg("%s", "Invalid Serial"); |
2099 | return; | 2057 | return; |
2100 | } | 2058 | } |
2101 | 2059 | ||
@@ -2109,7 +2067,7 @@ static void mos7840_set_termios(struct tty_struct *tty, | |||
2109 | return; | 2067 | return; |
2110 | } | 2068 | } |
2111 | 2069 | ||
2112 | dbg("%s\n", "setting termios - "); | 2070 | dbg("%s", "setting termios - "); |
2113 | 2071 | ||
2114 | cflag = tty->termios->c_cflag; | 2072 | cflag = tty->termios->c_cflag; |
2115 | 2073 | ||
@@ -2124,7 +2082,7 @@ static void mos7840_set_termios(struct tty_struct *tty, | |||
2124 | mos7840_change_port_settings(tty, mos7840_port, old_termios); | 2082 | mos7840_change_port_settings(tty, mos7840_port, old_termios); |
2125 | 2083 | ||
2126 | if (!mos7840_port->read_urb) { | 2084 | if (!mos7840_port->read_urb) { |
2127 | dbg("%s", "URB KILLED !!!!!\n"); | 2085 | dbg("%s", "URB KILLED !!!!!"); |
2128 | return; | 2086 | return; |
2129 | } | 2087 | } |
2130 | 2088 | ||
@@ -2190,7 +2148,7 @@ static int mos7840_set_modem_info(struct moschip_port *mos7840_port, | |||
2190 | 2148 | ||
2191 | port = (struct usb_serial_port *)mos7840_port->port; | 2149 | port = (struct usb_serial_port *)mos7840_port->port; |
2192 | if (mos7840_port_paranoia_check(port, __func__)) { | 2150 | if (mos7840_port_paranoia_check(port, __func__)) { |
2193 | dbg("%s", "Invalid port \n"); | 2151 | dbg("%s", "Invalid port"); |
2194 | return -1; | 2152 | return -1; |
2195 | } | 2153 | } |
2196 | 2154 | ||
@@ -2235,7 +2193,7 @@ static int mos7840_set_modem_info(struct moschip_port *mos7840_port, | |||
2235 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); | 2193 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); |
2236 | unlock_kernel(); | 2194 | unlock_kernel(); |
2237 | if (status < 0) { | 2195 | if (status < 0) { |
2238 | dbg("setting MODEM_CONTROL_REGISTER Failed\n"); | 2196 | dbg("setting MODEM_CONTROL_REGISTER Failed"); |
2239 | return -1; | 2197 | return -1; |
2240 | } | 2198 | } |
2241 | 2199 | ||
@@ -2320,7 +2278,7 @@ static int mos7840_ioctl(struct tty_struct *tty, struct file *file, | |||
2320 | int mosret = 0; | 2278 | int mosret = 0; |
2321 | 2279 | ||
2322 | if (mos7840_port_paranoia_check(port, __func__)) { | 2280 | if (mos7840_port_paranoia_check(port, __func__)) { |
2323 | dbg("%s", "Invalid port \n"); | 2281 | dbg("%s", "Invalid port"); |
2324 | return -1; | 2282 | return -1; |
2325 | } | 2283 | } |
2326 | 2284 | ||
@@ -2420,9 +2378,8 @@ static int mos7840_calc_num_ports(struct usb_serial *serial) | |||
2420 | { | 2378 | { |
2421 | int mos7840_num_ports = 0; | 2379 | int mos7840_num_ports = 0; |
2422 | 2380 | ||
2423 | dbg("numberofendpoints: %d \n", | 2381 | dbg("numberofendpoints: cur %d, alt %d", |
2424 | (int)serial->interface->cur_altsetting->desc.bNumEndpoints); | 2382 | (int)serial->interface->cur_altsetting->desc.bNumEndpoints, |
2425 | dbg("numberofendpoints: %d \n", | ||
2426 | (int)serial->interface->altsetting->desc.bNumEndpoints); | 2383 | (int)serial->interface->altsetting->desc.bNumEndpoints); |
2427 | if (serial->interface->cur_altsetting->desc.bNumEndpoints == 5) { | 2384 | if (serial->interface->cur_altsetting->desc.bNumEndpoints == 5) { |
2428 | mos7840_num_ports = serial->num_ports = 2; | 2385 | mos7840_num_ports = serial->num_ports = 2; |
@@ -2431,7 +2388,7 @@ static int mos7840_calc_num_ports(struct usb_serial *serial) | |||
2431 | serial->num_bulk_out = 4; | 2388 | serial->num_bulk_out = 4; |
2432 | mos7840_num_ports = serial->num_ports = 4; | 2389 | mos7840_num_ports = serial->num_ports = 4; |
2433 | } | 2390 | } |
2434 | 2391 | dbg ("mos7840_num_ports = %d", mos7840_num_ports); | |
2435 | return mos7840_num_ports; | 2392 | return mos7840_num_ports; |
2436 | } | 2393 | } |
2437 | 2394 | ||
@@ -2446,22 +2403,24 @@ static int mos7840_startup(struct usb_serial *serial) | |||
2446 | int i, status; | 2403 | int i, status; |
2447 | 2404 | ||
2448 | __u16 Data; | 2405 | __u16 Data; |
2449 | dbg("%s \n", " mos7840_startup :entering.........."); | 2406 | dbg("%s", "mos7840_startup :Entering.........."); |
2450 | 2407 | ||
2451 | if (!serial) { | 2408 | if (!serial) { |
2452 | dbg("%s\n", "Invalid Handler"); | 2409 | dbg("%s", "Invalid Handler"); |
2453 | return -1; | 2410 | return -1; |
2454 | } | 2411 | } |
2455 | 2412 | ||
2456 | dev = serial->dev; | 2413 | dev = serial->dev; |
2457 | 2414 | ||
2458 | dbg("%s\n", "Entering..."); | 2415 | dbg("%s", "Entering..."); |
2416 | dbg ("mos7840_startup: serial = %p", serial); | ||
2459 | 2417 | ||
2460 | /* we set up the pointers to the endpoints in the mos7840_open * | 2418 | /* we set up the pointers to the endpoints in the mos7840_open * |
2461 | * function, as the structures aren't created yet. */ | 2419 | * function, as the structures aren't created yet. */ |
2462 | 2420 | ||
2463 | /* set up port private structures */ | 2421 | /* set up port private structures */ |
2464 | for (i = 0; i < serial->num_ports; ++i) { | 2422 | for (i = 0; i < serial->num_ports; ++i) { |
2423 | dbg ("mos7840_startup: configuring port %d............", i); | ||
2465 | mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); | 2424 | mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); |
2466 | if (mos7840_port == NULL) { | 2425 | if (mos7840_port == NULL) { |
2467 | dev_err(&dev->dev, "%s - Out of memory\n", __func__); | 2426 | dev_err(&dev->dev, "%s - Out of memory\n", __func__); |
@@ -2519,10 +2478,10 @@ static int mos7840_startup(struct usb_serial *serial) | |||
2519 | status = mos7840_get_reg_sync(serial->port[i], | 2478 | status = mos7840_get_reg_sync(serial->port[i], |
2520 | mos7840_port->ControlRegOffset, &Data); | 2479 | mos7840_port->ControlRegOffset, &Data); |
2521 | if (status < 0) { | 2480 | if (status < 0) { |
2522 | dbg("Reading ControlReg failed status-0x%x\n", status); | 2481 | dbg("Reading ControlReg failed status-0x%x", status); |
2523 | break; | 2482 | break; |
2524 | } else | 2483 | } else |
2525 | dbg("ControlReg Reading success val is %x, status%d\n", | 2484 | dbg("ControlReg Reading success val is %x, status%d", |
2526 | Data, status); | 2485 | Data, status); |
2527 | Data |= 0x08; /* setting driver done bit */ | 2486 | Data |= 0x08; /* setting driver done bit */ |
2528 | Data |= 0x04; /* sp1_bit to have cts change reflect in | 2487 | Data |= 0x04; /* sp1_bit to have cts change reflect in |
@@ -2532,10 +2491,10 @@ static int mos7840_startup(struct usb_serial *serial) | |||
2532 | status = mos7840_set_reg_sync(serial->port[i], | 2491 | status = mos7840_set_reg_sync(serial->port[i], |
2533 | mos7840_port->ControlRegOffset, Data); | 2492 | mos7840_port->ControlRegOffset, Data); |
2534 | if (status < 0) { | 2493 | if (status < 0) { |
2535 | dbg("Writing ControlReg failed(rx_disable) status-0x%x\n", status); | 2494 | dbg("Writing ControlReg failed(rx_disable) status-0x%x", status); |
2536 | break; | 2495 | break; |
2537 | } else | 2496 | } else |
2538 | dbg("ControlReg Writing success(rx_disable) status%d\n", | 2497 | dbg("ControlReg Writing success(rx_disable) status%d", |
2539 | status); | 2498 | status); |
2540 | 2499 | ||
2541 | /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 | 2500 | /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 |
@@ -2544,48 +2503,48 @@ static int mos7840_startup(struct usb_serial *serial) | |||
2544 | status = mos7840_set_reg_sync(serial->port[i], | 2503 | status = mos7840_set_reg_sync(serial->port[i], |
2545 | (__u16) (mos7840_port->DcrRegOffset + 0), Data); | 2504 | (__u16) (mos7840_port->DcrRegOffset + 0), Data); |
2546 | if (status < 0) { | 2505 | if (status < 0) { |
2547 | dbg("Writing DCR0 failed status-0x%x\n", status); | 2506 | dbg("Writing DCR0 failed status-0x%x", status); |
2548 | break; | 2507 | break; |
2549 | } else | 2508 | } else |
2550 | dbg("DCR0 Writing success status%d\n", status); | 2509 | dbg("DCR0 Writing success status%d", status); |
2551 | 2510 | ||
2552 | Data = 0x05; | 2511 | Data = 0x05; |
2553 | status = mos7840_set_reg_sync(serial->port[i], | 2512 | status = mos7840_set_reg_sync(serial->port[i], |
2554 | (__u16) (mos7840_port->DcrRegOffset + 1), Data); | 2513 | (__u16) (mos7840_port->DcrRegOffset + 1), Data); |
2555 | if (status < 0) { | 2514 | if (status < 0) { |
2556 | dbg("Writing DCR1 failed status-0x%x\n", status); | 2515 | dbg("Writing DCR1 failed status-0x%x", status); |
2557 | break; | 2516 | break; |
2558 | } else | 2517 | } else |
2559 | dbg("DCR1 Writing success status%d\n", status); | 2518 | dbg("DCR1 Writing success status%d", status); |
2560 | 2519 | ||
2561 | Data = 0x24; | 2520 | Data = 0x24; |
2562 | status = mos7840_set_reg_sync(serial->port[i], | 2521 | status = mos7840_set_reg_sync(serial->port[i], |
2563 | (__u16) (mos7840_port->DcrRegOffset + 2), Data); | 2522 | (__u16) (mos7840_port->DcrRegOffset + 2), Data); |
2564 | if (status < 0) { | 2523 | if (status < 0) { |
2565 | dbg("Writing DCR2 failed status-0x%x\n", status); | 2524 | dbg("Writing DCR2 failed status-0x%x", status); |
2566 | break; | 2525 | break; |
2567 | } else | 2526 | } else |
2568 | dbg("DCR2 Writing success status%d\n", status); | 2527 | dbg("DCR2 Writing success status%d", status); |
2569 | 2528 | ||
2570 | /* write values in clkstart0x0 and clkmulti 0x20 */ | 2529 | /* write values in clkstart0x0 and clkmulti 0x20 */ |
2571 | Data = 0x0; | 2530 | Data = 0x0; |
2572 | status = mos7840_set_reg_sync(serial->port[i], | 2531 | status = mos7840_set_reg_sync(serial->port[i], |
2573 | CLK_START_VALUE_REGISTER, Data); | 2532 | CLK_START_VALUE_REGISTER, Data); |
2574 | if (status < 0) { | 2533 | if (status < 0) { |
2575 | dbg("Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status); | 2534 | dbg("Writing CLK_START_VALUE_REGISTER failed status-0x%x", status); |
2576 | break; | 2535 | break; |
2577 | } else | 2536 | } else |
2578 | dbg("CLK_START_VALUE_REGISTER Writing success status%d\n", status); | 2537 | dbg("CLK_START_VALUE_REGISTER Writing success status%d", status); |
2579 | 2538 | ||
2580 | Data = 0x20; | 2539 | Data = 0x20; |
2581 | status = mos7840_set_reg_sync(serial->port[i], | 2540 | status = mos7840_set_reg_sync(serial->port[i], |
2582 | CLK_MULTI_REGISTER, Data); | 2541 | CLK_MULTI_REGISTER, Data); |
2583 | if (status < 0) { | 2542 | if (status < 0) { |
2584 | dbg("Writing CLK_MULTI_REGISTER failed status-0x%x\n", | 2543 | dbg("Writing CLK_MULTI_REGISTER failed status-0x%x", |
2585 | status); | 2544 | status); |
2586 | goto error; | 2545 | goto error; |
2587 | } else | 2546 | } else |
2588 | dbg("CLK_MULTI_REGISTER Writing success status%d\n", | 2547 | dbg("CLK_MULTI_REGISTER Writing success status%d", |
2589 | status); | 2548 | status); |
2590 | 2549 | ||
2591 | /* write value 0x0 to scratchpad register */ | 2550 | /* write value 0x0 to scratchpad register */ |
@@ -2593,11 +2552,11 @@ static int mos7840_startup(struct usb_serial *serial) | |||
2593 | status = mos7840_set_uart_reg(serial->port[i], | 2552 | status = mos7840_set_uart_reg(serial->port[i], |
2594 | SCRATCH_PAD_REGISTER, Data); | 2553 | SCRATCH_PAD_REGISTER, Data); |
2595 | if (status < 0) { | 2554 | if (status < 0) { |
2596 | dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", | 2555 | dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x", |
2597 | status); | 2556 | status); |
2598 | break; | 2557 | break; |
2599 | } else | 2558 | } else |
2600 | dbg("SCRATCH_PAD_REGISTER Writing success status%d\n", | 2559 | dbg("SCRATCH_PAD_REGISTER Writing success status%d", |
2601 | status); | 2560 | status); |
2602 | 2561 | ||
2603 | /* Zero Length flag register */ | 2562 | /* Zero Length flag register */ |
@@ -2608,30 +2567,30 @@ static int mos7840_startup(struct usb_serial *serial) | |||
2608 | status = mos7840_set_reg_sync(serial->port[i], | 2567 | status = mos7840_set_reg_sync(serial->port[i], |
2609 | (__u16) (ZLP_REG1 + | 2568 | (__u16) (ZLP_REG1 + |
2610 | ((__u16)mos7840_port->port_num)), Data); | 2569 | ((__u16)mos7840_port->port_num)), Data); |
2611 | dbg("ZLIP offset%x\n", | 2570 | dbg("ZLIP offset %x", |
2612 | (__u16) (ZLP_REG1 + | 2571 | (__u16) (ZLP_REG1 + |
2613 | ((__u16) mos7840_port->port_num))); | 2572 | ((__u16) mos7840_port->port_num))); |
2614 | if (status < 0) { | 2573 | if (status < 0) { |
2615 | dbg("Writing ZLP_REG%d failed status-0x%x\n", | 2574 | dbg("Writing ZLP_REG%d failed status-0x%x", |
2616 | i + 2, status); | 2575 | i + 2, status); |
2617 | break; | 2576 | break; |
2618 | } else | 2577 | } else |
2619 | dbg("ZLP_REG%d Writing success status%d\n", | 2578 | dbg("ZLP_REG%d Writing success status%d", |
2620 | i + 2, status); | 2579 | i + 2, status); |
2621 | } else { | 2580 | } else { |
2622 | Data = 0xff; | 2581 | Data = 0xff; |
2623 | status = mos7840_set_reg_sync(serial->port[i], | 2582 | status = mos7840_set_reg_sync(serial->port[i], |
2624 | (__u16) (ZLP_REG1 + | 2583 | (__u16) (ZLP_REG1 + |
2625 | ((__u16)mos7840_port->port_num) - 0x1), Data); | 2584 | ((__u16)mos7840_port->port_num) - 0x1), Data); |
2626 | dbg("ZLIP offset%x\n", | 2585 | dbg("ZLIP offset %x", |
2627 | (__u16) (ZLP_REG1 + | 2586 | (__u16) (ZLP_REG1 + |
2628 | ((__u16) mos7840_port->port_num) - 0x1)); | 2587 | ((__u16) mos7840_port->port_num) - 0x1)); |
2629 | if (status < 0) { | 2588 | if (status < 0) { |
2630 | dbg("Writing ZLP_REG%d failed status-0x%x\n", | 2589 | dbg("Writing ZLP_REG%d failed status-0x%x", |
2631 | i + 1, status); | 2590 | i + 1, status); |
2632 | break; | 2591 | break; |
2633 | } else | 2592 | } else |
2634 | dbg("ZLP_REG%d Writing success status%d\n", | 2593 | dbg("ZLP_REG%d Writing success status%d", |
2635 | i + 1, status); | 2594 | i + 1, status); |
2636 | 2595 | ||
2637 | } | 2596 | } |
@@ -2645,15 +2604,16 @@ static int mos7840_startup(struct usb_serial *serial) | |||
2645 | goto error; | 2604 | goto error; |
2646 | } | 2605 | } |
2647 | } | 2606 | } |
2607 | dbg ("mos7840_startup: all ports configured..........."); | ||
2648 | 2608 | ||
2649 | /* Zero Length flag enable */ | 2609 | /* Zero Length flag enable */ |
2650 | Data = 0x0f; | 2610 | Data = 0x0f; |
2651 | status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); | 2611 | status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); |
2652 | if (status < 0) { | 2612 | if (status < 0) { |
2653 | dbg("Writing ZLP_REG5 failed status-0x%x\n", status); | 2613 | dbg("Writing ZLP_REG5 failed status-0x%x", status); |
2654 | goto error; | 2614 | goto error; |
2655 | } else | 2615 | } else |
2656 | dbg("ZLP_REG5 Writing success status%d\n", status); | 2616 | dbg("ZLP_REG5 Writing success status%d", status); |
2657 | 2617 | ||
2658 | /* setting configuration feature to one */ | 2618 | /* setting configuration feature to one */ |
2659 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 2619 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
@@ -2673,19 +2633,19 @@ error: | |||
2673 | } | 2633 | } |
2674 | 2634 | ||
2675 | /**************************************************************************** | 2635 | /**************************************************************************** |
2676 | * mos7840_shutdown | 2636 | * mos7840_disconnect |
2677 | * This function is called whenever the device is removed from the usb bus. | 2637 | * This function is called whenever the device is removed from the usb bus. |
2678 | ****************************************************************************/ | 2638 | ****************************************************************************/ |
2679 | 2639 | ||
2680 | static void mos7840_shutdown(struct usb_serial *serial) | 2640 | static void mos7840_disconnect(struct usb_serial *serial) |
2681 | { | 2641 | { |
2682 | int i; | 2642 | int i; |
2683 | unsigned long flags; | 2643 | unsigned long flags; |
2684 | struct moschip_port *mos7840_port; | 2644 | struct moschip_port *mos7840_port; |
2685 | dbg("%s \n", " shutdown :entering.........."); | 2645 | dbg("%s", " disconnect :entering.........."); |
2686 | 2646 | ||
2687 | if (!serial) { | 2647 | if (!serial) { |
2688 | dbg("%s", "Invalid Handler \n"); | 2648 | dbg("%s", "Invalid Handler"); |
2689 | return; | 2649 | return; |
2690 | } | 2650 | } |
2691 | 2651 | ||
@@ -2702,14 +2662,45 @@ static void mos7840_shutdown(struct usb_serial *serial) | |||
2702 | mos7840_port->zombie = 1; | 2662 | mos7840_port->zombie = 1; |
2703 | spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); | 2663 | spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); |
2704 | usb_kill_urb(mos7840_port->control_urb); | 2664 | usb_kill_urb(mos7840_port->control_urb); |
2665 | } | ||
2666 | } | ||
2667 | |||
2668 | dbg("%s", "Thank u :: "); | ||
2669 | |||
2670 | } | ||
2671 | |||
2672 | /**************************************************************************** | ||
2673 | * mos7840_release | ||
2674 | * This function is called when the usb_serial structure is freed. | ||
2675 | ****************************************************************************/ | ||
2676 | |||
2677 | static void mos7840_release(struct usb_serial *serial) | ||
2678 | { | ||
2679 | int i; | ||
2680 | struct moschip_port *mos7840_port; | ||
2681 | dbg("%s", " release :entering.........."); | ||
2682 | |||
2683 | if (!serial) { | ||
2684 | dbg("%s", "Invalid Handler"); | ||
2685 | return; | ||
2686 | } | ||
2687 | |||
2688 | /* check for the ports to be closed,close the ports and disconnect */ | ||
2689 | |||
2690 | /* free private structure allocated for serial port * | ||
2691 | * stop reads and writes on all ports */ | ||
2692 | |||
2693 | for (i = 0; i < serial->num_ports; ++i) { | ||
2694 | mos7840_port = mos7840_get_port_private(serial->port[i]); | ||
2695 | dbg("mos7840_port %d = %p", i, mos7840_port); | ||
2696 | if (mos7840_port) { | ||
2705 | kfree(mos7840_port->ctrl_buf); | 2697 | kfree(mos7840_port->ctrl_buf); |
2706 | kfree(mos7840_port->dr); | 2698 | kfree(mos7840_port->dr); |
2707 | kfree(mos7840_port); | 2699 | kfree(mos7840_port); |
2708 | } | 2700 | } |
2709 | mos7840_set_port_private(serial->port[i], NULL); | ||
2710 | } | 2701 | } |
2711 | 2702 | ||
2712 | dbg("%s\n", "Thank u :: "); | 2703 | dbg("%s", "Thank u :: "); |
2713 | 2704 | ||
2714 | } | 2705 | } |
2715 | 2706 | ||
@@ -2747,7 +2738,8 @@ static struct usb_serial_driver moschip7840_4port_device = { | |||
2747 | .tiocmget = mos7840_tiocmget, | 2738 | .tiocmget = mos7840_tiocmget, |
2748 | .tiocmset = mos7840_tiocmset, | 2739 | .tiocmset = mos7840_tiocmset, |
2749 | .attach = mos7840_startup, | 2740 | .attach = mos7840_startup, |
2750 | .shutdown = mos7840_shutdown, | 2741 | .disconnect = mos7840_disconnect, |
2742 | .release = mos7840_release, | ||
2751 | .read_bulk_callback = mos7840_bulk_in_callback, | 2743 | .read_bulk_callback = mos7840_bulk_in_callback, |
2752 | .read_int_callback = mos7840_interrupt_callback, | 2744 | .read_int_callback = mos7840_interrupt_callback, |
2753 | }; | 2745 | }; |
@@ -2760,7 +2752,7 @@ static int __init moschip7840_init(void) | |||
2760 | { | 2752 | { |
2761 | int retval; | 2753 | int retval; |
2762 | 2754 | ||
2763 | dbg("%s \n", " mos7840_init :entering.........."); | 2755 | dbg("%s", " mos7840_init :entering.........."); |
2764 | 2756 | ||
2765 | /* Register with the usb serial */ | 2757 | /* Register with the usb serial */ |
2766 | retval = usb_serial_register(&moschip7840_4port_device); | 2758 | retval = usb_serial_register(&moschip7840_4port_device); |
@@ -2768,14 +2760,14 @@ static int __init moschip7840_init(void) | |||
2768 | if (retval) | 2760 | if (retval) |
2769 | goto failed_port_device_register; | 2761 | goto failed_port_device_register; |
2770 | 2762 | ||
2771 | dbg("%s\n", "Entring..."); | 2763 | dbg("%s", "Entering..."); |
2772 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" | 2764 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" |
2773 | DRIVER_DESC "\n"); | 2765 | DRIVER_DESC "\n"); |
2774 | 2766 | ||
2775 | /* Register with the usb */ | 2767 | /* Register with the usb */ |
2776 | retval = usb_register(&io_driver); | 2768 | retval = usb_register(&io_driver); |
2777 | if (retval == 0) { | 2769 | if (retval == 0) { |
2778 | dbg("%s\n", "Leaving..."); | 2770 | dbg("%s", "Leaving..."); |
2779 | return 0; | 2771 | return 0; |
2780 | } | 2772 | } |
2781 | usb_serial_deregister(&moschip7840_4port_device); | 2773 | usb_serial_deregister(&moschip7840_4port_device); |
@@ -2790,13 +2782,13 @@ failed_port_device_register: | |||
2790 | static void __exit moschip7840_exit(void) | 2782 | static void __exit moschip7840_exit(void) |
2791 | { | 2783 | { |
2792 | 2784 | ||
2793 | dbg("%s \n", " mos7840_exit :entering.........."); | 2785 | dbg("%s", " mos7840_exit :entering.........."); |
2794 | 2786 | ||
2795 | usb_deregister(&io_driver); | 2787 | usb_deregister(&io_driver); |
2796 | 2788 | ||
2797 | usb_serial_deregister(&moschip7840_4port_device); | 2789 | usb_serial_deregister(&moschip7840_4port_device); |
2798 | 2790 | ||
2799 | dbg("%s\n", "Entring..."); | 2791 | dbg("%s", "Entering..."); |
2800 | } | 2792 | } |
2801 | 2793 | ||
2802 | module_init(moschip7840_init); | 2794 | module_init(moschip7840_init); |
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index bcdcbb822705..f5f3751a888c 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c | |||
@@ -98,8 +98,7 @@ static int navman_open(struct tty_struct *tty, | |||
98 | return result; | 98 | return result; |
99 | } | 99 | } |
100 | 100 | ||
101 | static void navman_close(struct tty_struct *tty, | 101 | static void navman_close(struct usb_serial_port *port) |
102 | struct usb_serial_port *port, struct file *filp) | ||
103 | { | 102 | { |
104 | dbg("%s - port %d", __func__, port->number); | 103 | dbg("%s - port %d", __func__, port->number); |
105 | 104 | ||
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index df6539712726..56857ddbd70b 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
@@ -66,14 +66,14 @@ static int debug; | |||
66 | /* function prototypes */ | 66 | /* function prototypes */ |
67 | static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port, | 67 | static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port, |
68 | struct file *filp); | 68 | struct file *filp); |
69 | static void omninet_close(struct tty_struct *tty, struct usb_serial_port *port, | 69 | static void omninet_close(struct usb_serial_port *port); |
70 | struct file *filp); | ||
71 | static void omninet_read_bulk_callback(struct urb *urb); | 70 | static void omninet_read_bulk_callback(struct urb *urb); |
72 | static void omninet_write_bulk_callback(struct urb *urb); | 71 | static void omninet_write_bulk_callback(struct urb *urb); |
73 | static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, | 72 | static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, |
74 | const unsigned char *buf, int count); | 73 | const unsigned char *buf, int count); |
75 | static int omninet_write_room(struct tty_struct *tty); | 74 | static int omninet_write_room(struct tty_struct *tty); |
76 | static void omninet_shutdown(struct usb_serial *serial); | 75 | static void omninet_disconnect(struct usb_serial *serial); |
76 | static void omninet_release(struct usb_serial *serial); | ||
77 | static int omninet_attach(struct usb_serial *serial); | 77 | static int omninet_attach(struct usb_serial *serial); |
78 | 78 | ||
79 | static struct usb_device_id id_table[] = { | 79 | static struct usb_device_id id_table[] = { |
@@ -109,7 +109,8 @@ static struct usb_serial_driver zyxel_omninet_device = { | |||
109 | .write_room = omninet_write_room, | 109 | .write_room = omninet_write_room, |
110 | .read_bulk_callback = omninet_read_bulk_callback, | 110 | .read_bulk_callback = omninet_read_bulk_callback, |
111 | .write_bulk_callback = omninet_write_bulk_callback, | 111 | .write_bulk_callback = omninet_write_bulk_callback, |
112 | .shutdown = omninet_shutdown, | 112 | .disconnect = omninet_disconnect, |
113 | .release = omninet_release, | ||
113 | }; | 114 | }; |
114 | 115 | ||
115 | 116 | ||
@@ -189,8 +190,7 @@ static int omninet_open(struct tty_struct *tty, | |||
189 | return result; | 190 | return result; |
190 | } | 191 | } |
191 | 192 | ||
192 | static void omninet_close(struct tty_struct *tty, | 193 | static void omninet_close(struct usb_serial_port *port) |
193 | struct usb_serial_port *port, struct file *filp) | ||
194 | { | 194 | { |
195 | dbg("%s - port %d", __func__, port->number); | 195 | dbg("%s - port %d", __func__, port->number); |
196 | usb_kill_urb(port->read_urb); | 196 | usb_kill_urb(port->read_urb); |
@@ -347,13 +347,22 @@ static void omninet_write_bulk_callback(struct urb *urb) | |||
347 | } | 347 | } |
348 | 348 | ||
349 | 349 | ||
350 | static void omninet_shutdown(struct usb_serial *serial) | 350 | static void omninet_disconnect(struct usb_serial *serial) |
351 | { | 351 | { |
352 | struct usb_serial_port *wport = serial->port[1]; | 352 | struct usb_serial_port *wport = serial->port[1]; |
353 | struct usb_serial_port *port = serial->port[0]; | 353 | |
354 | dbg("%s", __func__); | 354 | dbg("%s", __func__); |
355 | 355 | ||
356 | usb_kill_urb(wport->write_urb); | 356 | usb_kill_urb(wport->write_urb); |
357 | } | ||
358 | |||
359 | |||
360 | static void omninet_release(struct usb_serial *serial) | ||
361 | { | ||
362 | struct usb_serial_port *port = serial->port[0]; | ||
363 | |||
364 | dbg("%s", __func__); | ||
365 | |||
357 | kfree(usb_get_serial_port_data(port)); | 366 | kfree(usb_get_serial_port_data(port)); |
358 | } | 367 | } |
359 | 368 | ||
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index b500ad10b758..336bba79ad32 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c | |||
@@ -173,8 +173,7 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
173 | return result; | 173 | return result; |
174 | } | 174 | } |
175 | 175 | ||
176 | static void opticon_close(struct tty_struct *tty, struct usb_serial_port *port, | 176 | static void opticon_close(struct usb_serial_port *port) |
177 | struct file *filp) | ||
178 | { | 177 | { |
179 | struct opticon_private *priv = usb_get_serial_data(port->serial); | 178 | struct opticon_private *priv = usb_get_serial_data(port->serial); |
180 | 179 | ||
@@ -464,7 +463,7 @@ error: | |||
464 | return retval; | 463 | return retval; |
465 | } | 464 | } |
466 | 465 | ||
467 | static void opticon_shutdown(struct usb_serial *serial) | 466 | static void opticon_disconnect(struct usb_serial *serial) |
468 | { | 467 | { |
469 | struct opticon_private *priv = usb_get_serial_data(serial); | 468 | struct opticon_private *priv = usb_get_serial_data(serial); |
470 | 469 | ||
@@ -472,9 +471,16 @@ static void opticon_shutdown(struct usb_serial *serial) | |||
472 | 471 | ||
473 | usb_kill_urb(priv->bulk_read_urb); | 472 | usb_kill_urb(priv->bulk_read_urb); |
474 | usb_free_urb(priv->bulk_read_urb); | 473 | usb_free_urb(priv->bulk_read_urb); |
474 | } | ||
475 | |||
476 | static void opticon_release(struct usb_serial *serial) | ||
477 | { | ||
478 | struct opticon_private *priv = usb_get_serial_data(serial); | ||
479 | |||
480 | dbg("%s", __func__); | ||
481 | |||
475 | kfree(priv->bulk_in_buffer); | 482 | kfree(priv->bulk_in_buffer); |
476 | kfree(priv); | 483 | kfree(priv); |
477 | usb_set_serial_data(serial, NULL); | ||
478 | } | 484 | } |
479 | 485 | ||
480 | static int opticon_suspend(struct usb_interface *intf, pm_message_t message) | 486 | static int opticon_suspend(struct usb_interface *intf, pm_message_t message) |
@@ -525,7 +531,8 @@ static struct usb_serial_driver opticon_device = { | |||
525 | .close = opticon_close, | 531 | .close = opticon_close, |
526 | .write = opticon_write, | 532 | .write = opticon_write, |
527 | .write_room = opticon_write_room, | 533 | .write_room = opticon_write_room, |
528 | .shutdown = opticon_shutdown, | 534 | .disconnect = opticon_disconnect, |
535 | .release = opticon_release, | ||
529 | .throttle = opticon_throttle, | 536 | .throttle = opticon_throttle, |
530 | .unthrottle = opticon_unthrottle, | 537 | .unthrottle = opticon_unthrottle, |
531 | .ioctl = opticon_ioctl, | 538 | .ioctl = opticon_ioctl, |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 7817b82889ca..575816e6ba37 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -43,12 +43,16 @@ | |||
43 | #include <linux/usb/serial.h> | 43 | #include <linux/usb/serial.h> |
44 | 44 | ||
45 | /* Function prototypes */ | 45 | /* Function prototypes */ |
46 | static int option_probe(struct usb_serial *serial, | ||
47 | const struct usb_device_id *id); | ||
46 | static int option_open(struct tty_struct *tty, struct usb_serial_port *port, | 48 | static int option_open(struct tty_struct *tty, struct usb_serial_port *port, |
47 | struct file *filp); | 49 | struct file *filp); |
48 | static void option_close(struct tty_struct *tty, struct usb_serial_port *port, | 50 | static void option_close(struct usb_serial_port *port); |
49 | struct file *filp); | 51 | static void option_dtr_rts(struct usb_serial_port *port, int on); |
52 | |||
50 | static int option_startup(struct usb_serial *serial); | 53 | static int option_startup(struct usb_serial *serial); |
51 | static void option_shutdown(struct usb_serial *serial); | 54 | static void option_disconnect(struct usb_serial *serial); |
55 | static void option_release(struct usb_serial *serial); | ||
52 | static int option_write_room(struct tty_struct *tty); | 56 | static int option_write_room(struct tty_struct *tty); |
53 | 57 | ||
54 | static void option_instat_callback(struct urb *urb); | 58 | static void option_instat_callback(struct urb *urb); |
@@ -61,7 +65,7 @@ static void option_set_termios(struct tty_struct *tty, | |||
61 | static int option_tiocmget(struct tty_struct *tty, struct file *file); | 65 | static int option_tiocmget(struct tty_struct *tty, struct file *file); |
62 | static int option_tiocmset(struct tty_struct *tty, struct file *file, | 66 | static int option_tiocmset(struct tty_struct *tty, struct file *file, |
63 | unsigned int set, unsigned int clear); | 67 | unsigned int set, unsigned int clear); |
64 | static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *port); | 68 | static int option_send_setup(struct usb_serial_port *port); |
65 | static int option_suspend(struct usb_serial *serial, pm_message_t message); | 69 | static int option_suspend(struct usb_serial *serial, pm_message_t message); |
66 | static int option_resume(struct usb_serial *serial); | 70 | static int option_resume(struct usb_serial *serial); |
67 | 71 | ||
@@ -201,9 +205,9 @@ static int option_resume(struct usb_serial *serial); | |||
201 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 | 205 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 |
202 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 | 206 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 |
203 | #define NOVATELWIRELESS_PRODUCT_U727 0x5010 | 207 | #define NOVATELWIRELESS_PRODUCT_U727 0x5010 |
208 | #define NOVATELWIRELESS_PRODUCT_MC760 0x6000 | ||
204 | 209 | ||
205 | /* FUTURE NOVATEL PRODUCTS */ | 210 | /* FUTURE NOVATEL PRODUCTS */ |
206 | #define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0X6000 | ||
207 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 | 211 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 |
208 | #define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000 | 212 | #define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000 |
209 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001 | 213 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001 |
@@ -304,6 +308,10 @@ static int option_resume(struct usb_serial *serial); | |||
304 | #define DLINK_PRODUCT_DWM_652 0x3e04 | 308 | #define DLINK_PRODUCT_DWM_652 0x3e04 |
305 | 309 | ||
306 | 310 | ||
311 | /* TOSHIBA PRODUCTS */ | ||
312 | #define TOSHIBA_VENDOR_ID 0x0930 | ||
313 | #define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 | ||
314 | |||
307 | static struct usb_device_id option_ids[] = { | 315 | static struct usb_device_id option_ids[] = { |
308 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 316 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
309 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 317 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
@@ -421,7 +429,7 @@ static struct usb_device_id option_ids[] = { | |||
421 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ | 429 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ |
422 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ | 430 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ |
423 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ | 431 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ |
424 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, /* Novatel EVDO product */ | 432 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */ |
425 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ | 433 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ |
426 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ | 434 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ |
427 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ | 435 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ |
@@ -522,6 +530,7 @@ static struct usb_device_id option_ids[] = { | |||
522 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 530 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
523 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 531 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
524 | { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ | 532 | { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ |
533 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ | ||
525 | { } /* Terminating entry */ | 534 | { } /* Terminating entry */ |
526 | }; | 535 | }; |
527 | MODULE_DEVICE_TABLE(usb, option_ids); | 536 | MODULE_DEVICE_TABLE(usb, option_ids); |
@@ -549,8 +558,10 @@ static struct usb_serial_driver option_1port_device = { | |||
549 | .usb_driver = &option_driver, | 558 | .usb_driver = &option_driver, |
550 | .id_table = option_ids, | 559 | .id_table = option_ids, |
551 | .num_ports = 1, | 560 | .num_ports = 1, |
561 | .probe = option_probe, | ||
552 | .open = option_open, | 562 | .open = option_open, |
553 | .close = option_close, | 563 | .close = option_close, |
564 | .dtr_rts = option_dtr_rts, | ||
554 | .write = option_write, | 565 | .write = option_write, |
555 | .write_room = option_write_room, | 566 | .write_room = option_write_room, |
556 | .chars_in_buffer = option_chars_in_buffer, | 567 | .chars_in_buffer = option_chars_in_buffer, |
@@ -558,7 +569,8 @@ static struct usb_serial_driver option_1port_device = { | |||
558 | .tiocmget = option_tiocmget, | 569 | .tiocmget = option_tiocmget, |
559 | .tiocmset = option_tiocmset, | 570 | .tiocmset = option_tiocmset, |
560 | .attach = option_startup, | 571 | .attach = option_startup, |
561 | .shutdown = option_shutdown, | 572 | .disconnect = option_disconnect, |
573 | .release = option_release, | ||
562 | .read_int_callback = option_instat_callback, | 574 | .read_int_callback = option_instat_callback, |
563 | .suspend = option_suspend, | 575 | .suspend = option_suspend, |
564 | .resume = option_resume, | 576 | .resume = option_resume, |
@@ -624,13 +636,25 @@ static void __exit option_exit(void) | |||
624 | module_init(option_init); | 636 | module_init(option_init); |
625 | module_exit(option_exit); | 637 | module_exit(option_exit); |
626 | 638 | ||
639 | static int option_probe(struct usb_serial *serial, | ||
640 | const struct usb_device_id *id) | ||
641 | { | ||
642 | /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ | ||
643 | if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && | ||
644 | serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && | ||
645 | serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) | ||
646 | return -ENODEV; | ||
647 | |||
648 | return 0; | ||
649 | } | ||
650 | |||
627 | static void option_set_termios(struct tty_struct *tty, | 651 | static void option_set_termios(struct tty_struct *tty, |
628 | struct usb_serial_port *port, struct ktermios *old_termios) | 652 | struct usb_serial_port *port, struct ktermios *old_termios) |
629 | { | 653 | { |
630 | dbg("%s", __func__); | 654 | dbg("%s", __func__); |
631 | /* Doesn't support option setting */ | 655 | /* Doesn't support option setting */ |
632 | tty_termios_copy_hw(tty->termios, old_termios); | 656 | tty_termios_copy_hw(tty->termios, old_termios); |
633 | option_send_setup(tty, port); | 657 | option_send_setup(port); |
634 | } | 658 | } |
635 | 659 | ||
636 | static int option_tiocmget(struct tty_struct *tty, struct file *file) | 660 | static int option_tiocmget(struct tty_struct *tty, struct file *file) |
@@ -669,7 +693,7 @@ static int option_tiocmset(struct tty_struct *tty, struct file *file, | |||
669 | portdata->rts_state = 0; | 693 | portdata->rts_state = 0; |
670 | if (clear & TIOCM_DTR) | 694 | if (clear & TIOCM_DTR) |
671 | portdata->dtr_state = 0; | 695 | portdata->dtr_state = 0; |
672 | return option_send_setup(tty, port); | 696 | return option_send_setup(port); |
673 | } | 697 | } |
674 | 698 | ||
675 | /* Write */ | 699 | /* Write */ |
@@ -897,10 +921,6 @@ static int option_open(struct tty_struct *tty, | |||
897 | 921 | ||
898 | dbg("%s", __func__); | 922 | dbg("%s", __func__); |
899 | 923 | ||
900 | /* Set some sane defaults */ | ||
901 | portdata->rts_state = 1; | ||
902 | portdata->dtr_state = 1; | ||
903 | |||
904 | /* Reset low level data toggle and start reading from endpoints */ | 924 | /* Reset low level data toggle and start reading from endpoints */ |
905 | for (i = 0; i < N_IN_URB; i++) { | 925 | for (i = 0; i < N_IN_URB; i++) { |
906 | urb = portdata->in_urbs[i]; | 926 | urb = portdata->in_urbs[i]; |
@@ -936,37 +956,43 @@ static int option_open(struct tty_struct *tty, | |||
936 | usb_pipeout(urb->pipe), 0); */ | 956 | usb_pipeout(urb->pipe), 0); */ |
937 | } | 957 | } |
938 | 958 | ||
939 | option_send_setup(tty, port); | 959 | option_send_setup(port); |
940 | 960 | ||
941 | return 0; | 961 | return 0; |
942 | } | 962 | } |
943 | 963 | ||
944 | static void option_close(struct tty_struct *tty, | 964 | static void option_dtr_rts(struct usb_serial_port *port, int on) |
945 | struct usb_serial_port *port, struct file *filp) | ||
946 | { | 965 | { |
947 | int i; | ||
948 | struct usb_serial *serial = port->serial; | 966 | struct usb_serial *serial = port->serial; |
949 | struct option_port_private *portdata; | 967 | struct option_port_private *portdata; |
950 | 968 | ||
951 | dbg("%s", __func__); | 969 | dbg("%s", __func__); |
952 | portdata = usb_get_serial_port_data(port); | 970 | portdata = usb_get_serial_port_data(port); |
971 | mutex_lock(&serial->disc_mutex); | ||
972 | portdata->rts_state = on; | ||
973 | portdata->dtr_state = on; | ||
974 | if (serial->dev) | ||
975 | option_send_setup(port); | ||
976 | mutex_unlock(&serial->disc_mutex); | ||
977 | } | ||
953 | 978 | ||
954 | portdata->rts_state = 0; | ||
955 | portdata->dtr_state = 0; | ||
956 | 979 | ||
957 | if (serial->dev) { | 980 | static void option_close(struct usb_serial_port *port) |
958 | mutex_lock(&serial->disc_mutex); | 981 | { |
959 | if (!serial->disconnected) | 982 | int i; |
960 | option_send_setup(tty, port); | 983 | struct usb_serial *serial = port->serial; |
961 | mutex_unlock(&serial->disc_mutex); | 984 | struct option_port_private *portdata; |
985 | |||
986 | dbg("%s", __func__); | ||
987 | portdata = usb_get_serial_port_data(port); | ||
962 | 988 | ||
989 | if (serial->dev) { | ||
963 | /* Stop reading/writing urbs */ | 990 | /* Stop reading/writing urbs */ |
964 | for (i = 0; i < N_IN_URB; i++) | 991 | for (i = 0; i < N_IN_URB; i++) |
965 | usb_kill_urb(portdata->in_urbs[i]); | 992 | usb_kill_urb(portdata->in_urbs[i]); |
966 | for (i = 0; i < N_OUT_URB; i++) | 993 | for (i = 0; i < N_OUT_URB; i++) |
967 | usb_kill_urb(portdata->out_urbs[i]); | 994 | usb_kill_urb(portdata->out_urbs[i]); |
968 | } | 995 | } |
969 | tty_port_tty_set(&port->port, NULL); | ||
970 | } | 996 | } |
971 | 997 | ||
972 | /* Helper functions used by option_setup_urbs */ | 998 | /* Helper functions used by option_setup_urbs */ |
@@ -1032,28 +1058,24 @@ static void option_setup_urbs(struct usb_serial *serial) | |||
1032 | * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN | 1058 | * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN |
1033 | * CDC. | 1059 | * CDC. |
1034 | */ | 1060 | */ |
1035 | static int option_send_setup(struct tty_struct *tty, | 1061 | static int option_send_setup(struct usb_serial_port *port) |
1036 | struct usb_serial_port *port) | ||
1037 | { | 1062 | { |
1038 | struct usb_serial *serial = port->serial; | 1063 | struct usb_serial *serial = port->serial; |
1039 | struct option_port_private *portdata; | 1064 | struct option_port_private *portdata; |
1040 | int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; | 1065 | int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; |
1066 | int val = 0; | ||
1041 | dbg("%s", __func__); | 1067 | dbg("%s", __func__); |
1042 | 1068 | ||
1043 | portdata = usb_get_serial_port_data(port); | 1069 | portdata = usb_get_serial_port_data(port); |
1044 | 1070 | ||
1045 | if (tty) { | 1071 | if (portdata->dtr_state) |
1046 | int val = 0; | 1072 | val |= 0x01; |
1047 | if (portdata->dtr_state) | 1073 | if (portdata->rts_state) |
1048 | val |= 0x01; | 1074 | val |= 0x02; |
1049 | if (portdata->rts_state) | ||
1050 | val |= 0x02; | ||
1051 | 1075 | ||
1052 | return usb_control_msg(serial->dev, | 1076 | return usb_control_msg(serial->dev, |
1053 | usb_rcvctrlpipe(serial->dev, 0), | 1077 | usb_rcvctrlpipe(serial->dev, 0), |
1054 | 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT); | 1078 | 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT); |
1055 | } | ||
1056 | return 0; | ||
1057 | } | 1079 | } |
1058 | 1080 | ||
1059 | static int option_startup(struct usb_serial *serial) | 1081 | static int option_startup(struct usb_serial *serial) |
@@ -1129,7 +1151,14 @@ static void stop_read_write_urbs(struct usb_serial *serial) | |||
1129 | } | 1151 | } |
1130 | } | 1152 | } |
1131 | 1153 | ||
1132 | static void option_shutdown(struct usb_serial *serial) | 1154 | static void option_disconnect(struct usb_serial *serial) |
1155 | { | ||
1156 | dbg("%s", __func__); | ||
1157 | |||
1158 | stop_read_write_urbs(serial); | ||
1159 | } | ||
1160 | |||
1161 | static void option_release(struct usb_serial *serial) | ||
1133 | { | 1162 | { |
1134 | int i, j; | 1163 | int i, j; |
1135 | struct usb_serial_port *port; | 1164 | struct usb_serial_port *port; |
@@ -1137,8 +1166,6 @@ static void option_shutdown(struct usb_serial *serial) | |||
1137 | 1166 | ||
1138 | dbg("%s", __func__); | 1167 | dbg("%s", __func__); |
1139 | 1168 | ||
1140 | stop_read_write_urbs(serial); | ||
1141 | |||
1142 | /* Now free them */ | 1169 | /* Now free them */ |
1143 | for (i = 0; i < serial->num_ports; ++i) { | 1170 | for (i = 0; i < serial->num_ports; ++i) { |
1144 | port = serial->port[i]; | 1171 | port = serial->port[i]; |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index ba551f00f16f..3cece27325e7 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -143,8 +143,7 @@ struct oti6858_control_pkt { | |||
143 | /* function prototypes */ | 143 | /* function prototypes */ |
144 | static int oti6858_open(struct tty_struct *tty, | 144 | static int oti6858_open(struct tty_struct *tty, |
145 | struct usb_serial_port *port, struct file *filp); | 145 | struct usb_serial_port *port, struct file *filp); |
146 | static void oti6858_close(struct tty_struct *tty, | 146 | static void oti6858_close(struct usb_serial_port *port); |
147 | struct usb_serial_port *port, struct file *filp); | ||
148 | static void oti6858_set_termios(struct tty_struct *tty, | 147 | static void oti6858_set_termios(struct tty_struct *tty, |
149 | struct usb_serial_port *port, struct ktermios *old); | 148 | struct usb_serial_port *port, struct ktermios *old); |
150 | static int oti6858_ioctl(struct tty_struct *tty, struct file *file, | 149 | static int oti6858_ioctl(struct tty_struct *tty, struct file *file, |
@@ -160,7 +159,7 @@ static int oti6858_tiocmget(struct tty_struct *tty, struct file *file); | |||
160 | static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, | 159 | static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, |
161 | unsigned int set, unsigned int clear); | 160 | unsigned int set, unsigned int clear); |
162 | static int oti6858_startup(struct usb_serial *serial); | 161 | static int oti6858_startup(struct usb_serial *serial); |
163 | static void oti6858_shutdown(struct usb_serial *serial); | 162 | static void oti6858_release(struct usb_serial *serial); |
164 | 163 | ||
165 | /* functions operating on buffers */ | 164 | /* functions operating on buffers */ |
166 | static struct oti6858_buf *oti6858_buf_alloc(unsigned int size); | 165 | static struct oti6858_buf *oti6858_buf_alloc(unsigned int size); |
@@ -195,7 +194,7 @@ static struct usb_serial_driver oti6858_device = { | |||
195 | .write_room = oti6858_write_room, | 194 | .write_room = oti6858_write_room, |
196 | .chars_in_buffer = oti6858_chars_in_buffer, | 195 | .chars_in_buffer = oti6858_chars_in_buffer, |
197 | .attach = oti6858_startup, | 196 | .attach = oti6858_startup, |
198 | .shutdown = oti6858_shutdown, | 197 | .release = oti6858_release, |
199 | }; | 198 | }; |
200 | 199 | ||
201 | struct oti6858_private { | 200 | struct oti6858_private { |
@@ -622,67 +621,30 @@ static int oti6858_open(struct tty_struct *tty, | |||
622 | if (result != 0) { | 621 | if (result != 0) { |
623 | dev_err(&port->dev, "%s(): usb_submit_urb() failed" | 622 | dev_err(&port->dev, "%s(): usb_submit_urb() failed" |
624 | " with error %d\n", __func__, result); | 623 | " with error %d\n", __func__, result); |
625 | oti6858_close(tty, port, NULL); | 624 | oti6858_close(port); |
626 | return -EPROTO; | 625 | return -EPROTO; |
627 | } | 626 | } |
628 | 627 | ||
629 | /* setup termios */ | 628 | /* setup termios */ |
630 | if (tty) | 629 | if (tty) |
631 | oti6858_set_termios(tty, port, &tmp_termios); | 630 | oti6858_set_termios(tty, port, &tmp_termios); |
632 | 631 | port->port.drain_delay = 256; /* FIXME: check the FIFO length */ | |
633 | return 0; | 632 | return 0; |
634 | } | 633 | } |
635 | 634 | ||
636 | static void oti6858_close(struct tty_struct *tty, | 635 | static void oti6858_close(struct usb_serial_port *port) |
637 | struct usb_serial_port *port, struct file *filp) | ||
638 | { | 636 | { |
639 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 637 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
640 | unsigned long flags; | 638 | unsigned long flags; |
641 | long timeout; | ||
642 | wait_queue_t wait; | ||
643 | 639 | ||
644 | dbg("%s(port = %d)", __func__, port->number); | 640 | dbg("%s(port = %d)", __func__, port->number); |
645 | 641 | ||
646 | /* wait for data to drain from the buffer */ | ||
647 | spin_lock_irqsave(&priv->lock, flags); | 642 | spin_lock_irqsave(&priv->lock, flags); |
648 | timeout = 30 * HZ; /* PL2303_CLOSING_WAIT */ | ||
649 | init_waitqueue_entry(&wait, current); | ||
650 | add_wait_queue(&tty->write_wait, &wait); | ||
651 | dbg("%s(): entering wait loop", __func__); | ||
652 | for (;;) { | ||
653 | set_current_state(TASK_INTERRUPTIBLE); | ||
654 | if (oti6858_buf_data_avail(priv->buf) == 0 | ||
655 | || timeout == 0 || signal_pending(current) | ||
656 | || port->serial->disconnected) | ||
657 | break; | ||
658 | spin_unlock_irqrestore(&priv->lock, flags); | ||
659 | timeout = schedule_timeout(timeout); | ||
660 | spin_lock_irqsave(&priv->lock, flags); | ||
661 | } | ||
662 | set_current_state(TASK_RUNNING); | ||
663 | remove_wait_queue(&tty->write_wait, &wait); | ||
664 | dbg("%s(): after wait loop", __func__); | ||
665 | |||
666 | /* clear out any remaining data in the buffer */ | 643 | /* clear out any remaining data in the buffer */ |
667 | oti6858_buf_clear(priv->buf); | 644 | oti6858_buf_clear(priv->buf); |
668 | spin_unlock_irqrestore(&priv->lock, flags); | 645 | spin_unlock_irqrestore(&priv->lock, flags); |
669 | 646 | ||
670 | /* wait for characters to drain from the device */ | 647 | dbg("%s(): after buf_clear()", __func__); |
671 | /* (this is long enough for the entire 256 byte */ | ||
672 | /* pl2303 hardware buffer to drain with no flow */ | ||
673 | /* control for data rates of 1200 bps or more, */ | ||
674 | /* for lower rates we should really know how much */ | ||
675 | /* data is in the buffer to compute a delay */ | ||
676 | /* that is not unnecessarily long) */ | ||
677 | /* FIXME | ||
678 | bps = tty_get_baud_rate(tty); | ||
679 | if (bps > 1200) | ||
680 | timeout = max((HZ*2560)/bps,HZ/10); | ||
681 | else | ||
682 | */ | ||
683 | timeout = 2*HZ; | ||
684 | schedule_timeout_interruptible(timeout); | ||
685 | dbg("%s(): after schedule_timeout_interruptible()", __func__); | ||
686 | 648 | ||
687 | /* cancel scheduled setup */ | 649 | /* cancel scheduled setup */ |
688 | cancel_delayed_work(&priv->delayed_setup_work); | 650 | cancel_delayed_work(&priv->delayed_setup_work); |
@@ -694,15 +656,6 @@ static void oti6858_close(struct tty_struct *tty, | |||
694 | usb_kill_urb(port->write_urb); | 656 | usb_kill_urb(port->write_urb); |
695 | usb_kill_urb(port->read_urb); | 657 | usb_kill_urb(port->read_urb); |
696 | usb_kill_urb(port->interrupt_in_urb); | 658 | usb_kill_urb(port->interrupt_in_urb); |
697 | |||
698 | /* | ||
699 | if (tty && (tty->termios->c_cflag) & HUPCL) { | ||
700 | // drop DTR and RTS | ||
701 | spin_lock_irqsave(&priv->lock, flags); | ||
702 | priv->pending_setup.control &= ~CONTROL_MASK; | ||
703 | spin_unlock_irqrestore(&priv->lock, flags); | ||
704 | } | ||
705 | */ | ||
706 | } | 659 | } |
707 | 660 | ||
708 | static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, | 661 | static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, |
@@ -829,7 +782,7 @@ static int oti6858_ioctl(struct tty_struct *tty, struct file *file, | |||
829 | } | 782 | } |
830 | 783 | ||
831 | 784 | ||
832 | static void oti6858_shutdown(struct usb_serial *serial) | 785 | static void oti6858_release(struct usb_serial *serial) |
833 | { | 786 | { |
834 | struct oti6858_private *priv; | 787 | struct oti6858_private *priv; |
835 | int i; | 788 | int i; |
@@ -841,7 +794,6 @@ static void oti6858_shutdown(struct usb_serial *serial) | |||
841 | if (priv) { | 794 | if (priv) { |
842 | oti6858_buf_free(priv->buf); | 795 | oti6858_buf_free(priv->buf); |
843 | kfree(priv); | 796 | kfree(priv); |
844 | usb_set_serial_port_data(serial->port[i], NULL); | ||
845 | } | 797 | } |
846 | } | 798 | } |
847 | } | 799 | } |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 751a533a4347..ec6c132a25b5 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -652,69 +652,41 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
652 | kfree(buf); | 652 | kfree(buf); |
653 | } | 653 | } |
654 | 654 | ||
655 | static void pl2303_close(struct tty_struct *tty, | 655 | static void pl2303_dtr_rts(struct usb_serial_port *port, int on) |
656 | struct usb_serial_port *port, struct file *filp) | 656 | { |
657 | struct pl2303_private *priv = usb_get_serial_port_data(port); | ||
658 | unsigned long flags; | ||
659 | u8 control; | ||
660 | |||
661 | spin_lock_irqsave(&priv->lock, flags); | ||
662 | /* Change DTR and RTS */ | ||
663 | if (on) | ||
664 | priv->line_control |= (CONTROL_DTR | CONTROL_RTS); | ||
665 | else | ||
666 | priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); | ||
667 | control = priv->line_control; | ||
668 | spin_unlock_irqrestore(&priv->lock, flags); | ||
669 | set_control_lines(port->serial->dev, control); | ||
670 | } | ||
671 | |||
672 | static void pl2303_close(struct usb_serial_port *port) | ||
657 | { | 673 | { |
658 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 674 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
659 | unsigned long flags; | 675 | unsigned long flags; |
660 | unsigned int c_cflag; | ||
661 | int bps; | ||
662 | long timeout; | ||
663 | wait_queue_t wait; | ||
664 | 676 | ||
665 | dbg("%s - port %d", __func__, port->number); | 677 | dbg("%s - port %d", __func__, port->number); |
666 | 678 | ||
667 | /* wait for data to drain from the buffer */ | ||
668 | spin_lock_irqsave(&priv->lock, flags); | 679 | spin_lock_irqsave(&priv->lock, flags); |
669 | timeout = PL2303_CLOSING_WAIT; | ||
670 | init_waitqueue_entry(&wait, current); | ||
671 | add_wait_queue(&tty->write_wait, &wait); | ||
672 | for (;;) { | ||
673 | set_current_state(TASK_INTERRUPTIBLE); | ||
674 | if (pl2303_buf_data_avail(priv->buf) == 0 || | ||
675 | timeout == 0 || signal_pending(current) || | ||
676 | port->serial->disconnected) | ||
677 | break; | ||
678 | spin_unlock_irqrestore(&priv->lock, flags); | ||
679 | timeout = schedule_timeout(timeout); | ||
680 | spin_lock_irqsave(&priv->lock, flags); | ||
681 | } | ||
682 | set_current_state(TASK_RUNNING); | ||
683 | remove_wait_queue(&tty->write_wait, &wait); | ||
684 | /* clear out any remaining data in the buffer */ | 680 | /* clear out any remaining data in the buffer */ |
685 | pl2303_buf_clear(priv->buf); | 681 | pl2303_buf_clear(priv->buf); |
686 | spin_unlock_irqrestore(&priv->lock, flags); | 682 | spin_unlock_irqrestore(&priv->lock, flags); |
687 | 683 | ||
688 | /* wait for characters to drain from the device */ | ||
689 | /* (this is long enough for the entire 256 byte */ | ||
690 | /* pl2303 hardware buffer to drain with no flow */ | ||
691 | /* control for data rates of 1200 bps or more, */ | ||
692 | /* for lower rates we should really know how much */ | ||
693 | /* data is in the buffer to compute a delay */ | ||
694 | /* that is not unnecessarily long) */ | ||
695 | bps = tty_get_baud_rate(tty); | ||
696 | if (bps > 1200) | ||
697 | timeout = max((HZ*2560)/bps, HZ/10); | ||
698 | else | ||
699 | timeout = 2*HZ; | ||
700 | schedule_timeout_interruptible(timeout); | ||
701 | |||
702 | /* shutdown our urbs */ | 684 | /* shutdown our urbs */ |
703 | dbg("%s - shutting down urbs", __func__); | 685 | dbg("%s - shutting down urbs", __func__); |
704 | usb_kill_urb(port->write_urb); | 686 | usb_kill_urb(port->write_urb); |
705 | usb_kill_urb(port->read_urb); | 687 | usb_kill_urb(port->read_urb); |
706 | usb_kill_urb(port->interrupt_in_urb); | 688 | usb_kill_urb(port->interrupt_in_urb); |
707 | 689 | ||
708 | if (tty) { | ||
709 | c_cflag = tty->termios->c_cflag; | ||
710 | if (c_cflag & HUPCL) { | ||
711 | /* drop DTR and RTS */ | ||
712 | spin_lock_irqsave(&priv->lock, flags); | ||
713 | priv->line_control = 0; | ||
714 | spin_unlock_irqrestore(&priv->lock, flags); | ||
715 | set_control_lines(port->serial->dev, 0); | ||
716 | } | ||
717 | } | ||
718 | } | 690 | } |
719 | 691 | ||
720 | static int pl2303_open(struct tty_struct *tty, | 692 | static int pl2303_open(struct tty_struct *tty, |
@@ -748,7 +720,7 @@ static int pl2303_open(struct tty_struct *tty, | |||
748 | if (result) { | 720 | if (result) { |
749 | dev_err(&port->dev, "%s - failed submitting read urb," | 721 | dev_err(&port->dev, "%s - failed submitting read urb," |
750 | " error %d\n", __func__, result); | 722 | " error %d\n", __func__, result); |
751 | pl2303_close(tty, port, NULL); | 723 | pl2303_close(port); |
752 | return -EPROTO; | 724 | return -EPROTO; |
753 | } | 725 | } |
754 | 726 | ||
@@ -758,9 +730,10 @@ static int pl2303_open(struct tty_struct *tty, | |||
758 | if (result) { | 730 | if (result) { |
759 | dev_err(&port->dev, "%s - failed submitting interrupt urb," | 731 | dev_err(&port->dev, "%s - failed submitting interrupt urb," |
760 | " error %d\n", __func__, result); | 732 | " error %d\n", __func__, result); |
761 | pl2303_close(tty, port, NULL); | 733 | pl2303_close(port); |
762 | return -EPROTO; | 734 | return -EPROTO; |
763 | } | 735 | } |
736 | port->port.drain_delay = 256; | ||
764 | return 0; | 737 | return 0; |
765 | } | 738 | } |
766 | 739 | ||
@@ -821,6 +794,14 @@ static int pl2303_tiocmget(struct tty_struct *tty, struct file *file) | |||
821 | return result; | 794 | return result; |
822 | } | 795 | } |
823 | 796 | ||
797 | static int pl2303_carrier_raised(struct usb_serial_port *port) | ||
798 | { | ||
799 | struct pl2303_private *priv = usb_get_serial_port_data(port); | ||
800 | if (priv->line_status & UART_DCD) | ||
801 | return 1; | ||
802 | return 0; | ||
803 | } | ||
804 | |||
824 | static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | 805 | static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) |
825 | { | 806 | { |
826 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 807 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
@@ -897,7 +878,7 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state) | |||
897 | dbg("%s - error sending break = %d", __func__, result); | 878 | dbg("%s - error sending break = %d", __func__, result); |
898 | } | 879 | } |
899 | 880 | ||
900 | static void pl2303_shutdown(struct usb_serial *serial) | 881 | static void pl2303_release(struct usb_serial *serial) |
901 | { | 882 | { |
902 | int i; | 883 | int i; |
903 | struct pl2303_private *priv; | 884 | struct pl2303_private *priv; |
@@ -909,7 +890,6 @@ static void pl2303_shutdown(struct usb_serial *serial) | |||
909 | if (priv) { | 890 | if (priv) { |
910 | pl2303_buf_free(priv->buf); | 891 | pl2303_buf_free(priv->buf); |
911 | kfree(priv); | 892 | kfree(priv); |
912 | usb_set_serial_port_data(serial->port[i], NULL); | ||
913 | } | 893 | } |
914 | } | 894 | } |
915 | } | 895 | } |
@@ -946,6 +926,8 @@ static void pl2303_update_line_status(struct usb_serial_port *port, | |||
946 | spin_lock_irqsave(&priv->lock, flags); | 926 | spin_lock_irqsave(&priv->lock, flags); |
947 | priv->line_status = data[status_idx]; | 927 | priv->line_status = data[status_idx]; |
948 | spin_unlock_irqrestore(&priv->lock, flags); | 928 | spin_unlock_irqrestore(&priv->lock, flags); |
929 | if (priv->line_status & UART_BREAK_ERROR) | ||
930 | usb_serial_handle_break(port); | ||
949 | wake_up_interruptible(&priv->delta_msr_wait); | 931 | wake_up_interruptible(&priv->delta_msr_wait); |
950 | } | 932 | } |
951 | 933 | ||
@@ -1056,7 +1038,8 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1056 | if (line_status & UART_OVERRUN_ERROR) | 1038 | if (line_status & UART_OVERRUN_ERROR) |
1057 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 1039 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
1058 | for (i = 0; i < urb->actual_length; ++i) | 1040 | for (i = 0; i < urb->actual_length; ++i) |
1059 | tty_insert_flip_char(tty, data[i], tty_flag); | 1041 | if (!usb_serial_handle_sysrq_char(port, data[i])) |
1042 | tty_insert_flip_char(tty, data[i], tty_flag); | ||
1060 | tty_flip_buffer_push(tty); | 1043 | tty_flip_buffer_push(tty); |
1061 | } | 1044 | } |
1062 | tty_kref_put(tty); | 1045 | tty_kref_put(tty); |
@@ -1125,6 +1108,8 @@ static struct usb_serial_driver pl2303_device = { | |||
1125 | .num_ports = 1, | 1108 | .num_ports = 1, |
1126 | .open = pl2303_open, | 1109 | .open = pl2303_open, |
1127 | .close = pl2303_close, | 1110 | .close = pl2303_close, |
1111 | .dtr_rts = pl2303_dtr_rts, | ||
1112 | .carrier_raised = pl2303_carrier_raised, | ||
1128 | .write = pl2303_write, | 1113 | .write = pl2303_write, |
1129 | .ioctl = pl2303_ioctl, | 1114 | .ioctl = pl2303_ioctl, |
1130 | .break_ctl = pl2303_break_ctl, | 1115 | .break_ctl = pl2303_break_ctl, |
@@ -1137,7 +1122,7 @@ static struct usb_serial_driver pl2303_device = { | |||
1137 | .write_room = pl2303_write_room, | 1122 | .write_room = pl2303_write_room, |
1138 | .chars_in_buffer = pl2303_chars_in_buffer, | 1123 | .chars_in_buffer = pl2303_chars_in_buffer, |
1139 | .attach = pl2303_startup, | 1124 | .attach = pl2303_startup, |
1140 | .shutdown = pl2303_shutdown, | 1125 | .release = pl2303_release, |
1141 | }; | 1126 | }; |
1142 | 1127 | ||
1143 | static int __init pl2303_init(void) | 1128 | static int __init pl2303_init(void) |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 913225c61610..032f7aeb40a4 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -1,7 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | USB Driver for Sierra Wireless | 2 | USB Driver for Sierra Wireless |
3 | 3 | ||
4 | Copyright (C) 2006, 2007, 2008 Kevin Lloyd <klloyd@sierrawireless.com> | 4 | Copyright (C) 2006, 2007, 2008 Kevin Lloyd <klloyd@sierrawireless.com>, |
5 | |||
6 | Copyright (C) 2008, 2009 Elina Pasheva, Matthew Safar, Rory Filer | ||
7 | <linux@sierrawireless.com> | ||
5 | 8 | ||
6 | IMPORTANT DISCLAIMER: This driver is not commercially supported by | 9 | IMPORTANT DISCLAIMER: This driver is not commercially supported by |
7 | Sierra Wireless. Use at your own risk. | 10 | Sierra Wireless. Use at your own risk. |
@@ -14,8 +17,8 @@ | |||
14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> | 17 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> |
15 | */ | 18 | */ |
16 | 19 | ||
17 | #define DRIVER_VERSION "v.1.3.3" | 20 | #define DRIVER_VERSION "v.1.3.7" |
18 | #define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>" | 21 | #define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer" |
19 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" | 22 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" |
20 | 23 | ||
21 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
@@ -26,23 +29,32 @@ | |||
26 | #include <linux/module.h> | 29 | #include <linux/module.h> |
27 | #include <linux/usb.h> | 30 | #include <linux/usb.h> |
28 | #include <linux/usb/serial.h> | 31 | #include <linux/usb/serial.h> |
29 | #include <linux/usb/ch9.h> | ||
30 | 32 | ||
31 | #define SWIMS_USB_REQUEST_SetPower 0x00 | 33 | #define SWIMS_USB_REQUEST_SetPower 0x00 |
32 | #define SWIMS_USB_REQUEST_SetNmea 0x07 | 34 | #define SWIMS_USB_REQUEST_SetNmea 0x07 |
33 | 35 | ||
34 | /* per port private data */ | 36 | #define N_IN_URB 8 |
35 | #define N_IN_URB 4 | 37 | #define N_OUT_URB 64 |
36 | #define N_OUT_URB 4 | ||
37 | #define IN_BUFLEN 4096 | 38 | #define IN_BUFLEN 4096 |
38 | 39 | ||
40 | #define MAX_TRANSFER (PAGE_SIZE - 512) | ||
41 | /* MAX_TRANSFER is chosen so that the VM is not stressed by | ||
42 | allocations > PAGE_SIZE and the number of packets in a page | ||
43 | is an integer 512 is the largest possible packet on EHCI */ | ||
44 | |||
39 | static int debug; | 45 | static int debug; |
40 | static int nmea; | 46 | static int nmea; |
41 | 47 | ||
48 | /* Used in interface blacklisting */ | ||
49 | struct sierra_iface_info { | ||
50 | const u32 infolen; /* number of interface numbers on blacklist */ | ||
51 | const u8 *ifaceinfo; /* pointer to the array holding the numbers */ | ||
52 | }; | ||
53 | |||
42 | static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) | 54 | static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) |
43 | { | 55 | { |
44 | int result; | 56 | int result; |
45 | dev_dbg(&udev->dev, "%s", __func__); | 57 | dev_dbg(&udev->dev, "%s\n", __func__); |
46 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 58 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
47 | SWIMS_USB_REQUEST_SetPower, /* __u8 request */ | 59 | SWIMS_USB_REQUEST_SetPower, /* __u8 request */ |
48 | USB_TYPE_VENDOR, /* __u8 request type */ | 60 | USB_TYPE_VENDOR, /* __u8 request type */ |
@@ -57,7 +69,7 @@ static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) | |||
57 | static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) | 69 | static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) |
58 | { | 70 | { |
59 | int result; | 71 | int result; |
60 | dev_dbg(&udev->dev, "%s", __func__); | 72 | dev_dbg(&udev->dev, "%s\n", __func__); |
61 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 73 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
62 | SWIMS_USB_REQUEST_SetNmea, /* __u8 request */ | 74 | SWIMS_USB_REQUEST_SetNmea, /* __u8 request */ |
63 | USB_TYPE_VENDOR, /* __u8 request type */ | 75 | USB_TYPE_VENDOR, /* __u8 request type */ |
@@ -71,18 +83,39 @@ static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) | |||
71 | 83 | ||
72 | static int sierra_calc_num_ports(struct usb_serial *serial) | 84 | static int sierra_calc_num_ports(struct usb_serial *serial) |
73 | { | 85 | { |
74 | int result; | 86 | int num_ports = 0; |
75 | int *num_ports = usb_get_serial_data(serial); | 87 | u8 ifnum, numendpoints; |
76 | dev_dbg(&serial->dev->dev, "%s", __func__); | ||
77 | 88 | ||
78 | result = *num_ports; | 89 | dev_dbg(&serial->dev->dev, "%s\n", __func__); |
79 | 90 | ||
80 | if (result) { | 91 | ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; |
81 | kfree(num_ports); | 92 | numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints; |
82 | usb_set_serial_data(serial, NULL); | ||
83 | } | ||
84 | 93 | ||
85 | return result; | 94 | /* Dummy interface present on some SKUs should be ignored */ |
95 | if (ifnum == 0x99) | ||
96 | num_ports = 0; | ||
97 | else if (numendpoints <= 3) | ||
98 | num_ports = 1; | ||
99 | else | ||
100 | num_ports = (numendpoints-1)/2; | ||
101 | return num_ports; | ||
102 | } | ||
103 | |||
104 | static int is_blacklisted(const u8 ifnum, | ||
105 | const struct sierra_iface_info *blacklist) | ||
106 | { | ||
107 | const u8 *info; | ||
108 | int i; | ||
109 | |||
110 | if (blacklist) { | ||
111 | info = blacklist->ifaceinfo; | ||
112 | |||
113 | for (i = 0; i < blacklist->infolen; i++) { | ||
114 | if (info[i] == ifnum) | ||
115 | return 1; | ||
116 | } | ||
117 | } | ||
118 | return 0; | ||
86 | } | 119 | } |
87 | 120 | ||
88 | static int sierra_calc_interface(struct usb_serial *serial) | 121 | static int sierra_calc_interface(struct usb_serial *serial) |
@@ -90,7 +123,7 @@ static int sierra_calc_interface(struct usb_serial *serial) | |||
90 | int interface; | 123 | int interface; |
91 | struct usb_interface *p_interface; | 124 | struct usb_interface *p_interface; |
92 | struct usb_host_interface *p_host_interface; | 125 | struct usb_host_interface *p_host_interface; |
93 | dev_dbg(&serial->dev->dev, "%s", __func__); | 126 | dev_dbg(&serial->dev->dev, "%s\n", __func__); |
94 | 127 | ||
95 | /* Get the interface structure pointer from the serial struct */ | 128 | /* Get the interface structure pointer from the serial struct */ |
96 | p_interface = serial->interface; | 129 | p_interface = serial->interface; |
@@ -111,23 +144,12 @@ static int sierra_probe(struct usb_serial *serial, | |||
111 | { | 144 | { |
112 | int result = 0; | 145 | int result = 0; |
113 | struct usb_device *udev; | 146 | struct usb_device *udev; |
114 | int *num_ports; | ||
115 | u8 ifnum; | 147 | u8 ifnum; |
116 | u8 numendpoints; | ||
117 | |||
118 | dev_dbg(&serial->dev->dev, "%s", __func__); | ||
119 | |||
120 | num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL); | ||
121 | if (!num_ports) | ||
122 | return -ENOMEM; | ||
123 | 148 | ||
124 | ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; | ||
125 | numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints; | ||
126 | udev = serial->dev; | 149 | udev = serial->dev; |
150 | dev_dbg(&udev->dev, "%s\n", __func__); | ||
127 | 151 | ||
128 | /* Figure out the interface number from the serial structure */ | ||
129 | ifnum = sierra_calc_interface(serial); | 152 | ifnum = sierra_calc_interface(serial); |
130 | |||
131 | /* | 153 | /* |
132 | * If this interface supports more than 1 alternate | 154 | * If this interface supports more than 1 alternate |
133 | * select the 2nd one | 155 | * select the 2nd one |
@@ -139,23 +161,25 @@ static int sierra_probe(struct usb_serial *serial, | |||
139 | usb_set_interface(udev, ifnum, 1); | 161 | usb_set_interface(udev, ifnum, 1); |
140 | } | 162 | } |
141 | 163 | ||
142 | /* Dummy interface present on some SKUs should be ignored */ | 164 | /* ifnum could have changed - by calling usb_set_interface */ |
143 | if (ifnum == 0x99) | 165 | ifnum = sierra_calc_interface(serial); |
144 | *num_ports = 0; | ||
145 | else if (numendpoints <= 3) | ||
146 | *num_ports = 1; | ||
147 | else | ||
148 | *num_ports = (numendpoints-1)/2; | ||
149 | 166 | ||
150 | /* | 167 | if (is_blacklisted(ifnum, |
151 | * save off our num_ports info so that we can use it in the | 168 | (struct sierra_iface_info *)id->driver_info)) { |
152 | * calc_num_ports callback | 169 | dev_dbg(&serial->dev->dev, |
153 | */ | 170 | "Ignoring blacklisted interface #%d\n", ifnum); |
154 | usb_set_serial_data(serial, (void *)num_ports); | 171 | return -ENODEV; |
172 | } | ||
155 | 173 | ||
156 | return result; | 174 | return result; |
157 | } | 175 | } |
158 | 176 | ||
177 | static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; | ||
178 | static const struct sierra_iface_info direct_ip_interface_blacklist = { | ||
179 | .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces), | ||
180 | .ifaceinfo = direct_ip_non_serial_ifaces, | ||
181 | }; | ||
182 | |||
159 | static struct usb_device_id id_table [] = { | 183 | static struct usb_device_id id_table [] = { |
160 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | 184 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ |
161 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 185 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
@@ -188,9 +212,11 @@ static struct usb_device_id id_table [] = { | |||
188 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ | 212 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ |
189 | { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ | 213 | { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ |
190 | { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ | 214 | { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ |
191 | { USB_DEVICE(0x1199, 0x683C) }, /* Sierra Wireless MC8790 */ | 215 | /* Sierra Wireless MC8790, MC8791, MC8792 Composite */ |
192 | { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8790 */ | 216 | { USB_DEVICE(0x1199, 0x683C) }, |
193 | { USB_DEVICE(0x1199, 0x683E) }, /* Sierra Wireless MC8790 */ | 217 | { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8791 Composite */ |
218 | /* Sierra Wireless MC8790, MC8791, MC8792 */ | ||
219 | { USB_DEVICE(0x1199, 0x683E) }, | ||
194 | { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ | 220 | { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ |
195 | { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ | 221 | { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ |
196 | { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ | 222 | { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ |
@@ -211,6 +237,10 @@ static struct usb_device_id id_table [] = { | |||
211 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ | 237 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ |
212 | { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ | 238 | { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ |
213 | 239 | ||
240 | { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ | ||
241 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist | ||
242 | }, | ||
243 | |||
214 | { } | 244 | { } |
215 | }; | 245 | }; |
216 | MODULE_DEVICE_TABLE(usb, id_table); | 246 | MODULE_DEVICE_TABLE(usb, id_table); |
@@ -229,7 +259,6 @@ struct sierra_port_private { | |||
229 | 259 | ||
230 | /* Input endpoints and buffers for this port */ | 260 | /* Input endpoints and buffers for this port */ |
231 | struct urb *in_urbs[N_IN_URB]; | 261 | struct urb *in_urbs[N_IN_URB]; |
232 | char *in_buffer[N_IN_URB]; | ||
233 | 262 | ||
234 | /* Settings for the port */ | 263 | /* Settings for the port */ |
235 | int rts_state; /* Handshaking pins (outputs) */ | 264 | int rts_state; /* Handshaking pins (outputs) */ |
@@ -240,66 +269,59 @@ struct sierra_port_private { | |||
240 | int ri_state; | 269 | int ri_state; |
241 | }; | 270 | }; |
242 | 271 | ||
243 | static int sierra_send_setup(struct tty_struct *tty, | 272 | static int sierra_send_setup(struct usb_serial_port *port) |
244 | struct usb_serial_port *port) | ||
245 | { | 273 | { |
246 | struct usb_serial *serial = port->serial; | 274 | struct usb_serial *serial = port->serial; |
247 | struct sierra_port_private *portdata; | 275 | struct sierra_port_private *portdata; |
248 | __u16 interface = 0; | 276 | __u16 interface = 0; |
277 | int val = 0; | ||
249 | 278 | ||
250 | dev_dbg(&port->dev, "%s", __func__); | 279 | dev_dbg(&port->dev, "%s\n", __func__); |
251 | 280 | ||
252 | portdata = usb_get_serial_port_data(port); | 281 | portdata = usb_get_serial_port_data(port); |
253 | 282 | ||
254 | if (tty) { | 283 | if (portdata->dtr_state) |
255 | int val = 0; | 284 | val |= 0x01; |
256 | if (portdata->dtr_state) | 285 | if (portdata->rts_state) |
257 | val |= 0x01; | 286 | val |= 0x02; |
258 | if (portdata->rts_state) | ||
259 | val |= 0x02; | ||
260 | |||
261 | /* If composite device then properly report interface */ | ||
262 | if (serial->num_ports == 1) { | ||
263 | interface = sierra_calc_interface(serial); | ||
264 | |||
265 | /* Control message is sent only to interfaces with | ||
266 | * interrupt_in endpoints | ||
267 | */ | ||
268 | if (port->interrupt_in_urb) { | ||
269 | /* send control message */ | ||
270 | return usb_control_msg(serial->dev, | ||
271 | usb_rcvctrlpipe(serial->dev, 0), | ||
272 | 0x22, 0x21, val, interface, | ||
273 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | /* Otherwise the need to do non-composite mapping */ | ||
278 | else { | ||
279 | if (port->bulk_out_endpointAddress == 2) | ||
280 | interface = 0; | ||
281 | else if (port->bulk_out_endpointAddress == 4) | ||
282 | interface = 1; | ||
283 | else if (port->bulk_out_endpointAddress == 5) | ||
284 | interface = 2; | ||
285 | 287 | ||
288 | /* If composite device then properly report interface */ | ||
289 | if (serial->num_ports == 1) { | ||
290 | interface = sierra_calc_interface(serial); | ||
291 | /* Control message is sent only to interfaces with | ||
292 | * interrupt_in endpoints | ||
293 | */ | ||
294 | if (port->interrupt_in_urb) { | ||
295 | /* send control message */ | ||
286 | return usb_control_msg(serial->dev, | 296 | return usb_control_msg(serial->dev, |
287 | usb_rcvctrlpipe(serial->dev, 0), | 297 | usb_rcvctrlpipe(serial->dev, 0), |
288 | 0x22, 0x21, val, interface, | 298 | 0x22, 0x21, val, interface, |
289 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 299 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
290 | |||
291 | } | 300 | } |
292 | } | 301 | } |
293 | 302 | ||
303 | /* Otherwise the need to do non-composite mapping */ | ||
304 | else { | ||
305 | if (port->bulk_out_endpointAddress == 2) | ||
306 | interface = 0; | ||
307 | else if (port->bulk_out_endpointAddress == 4) | ||
308 | interface = 1; | ||
309 | else if (port->bulk_out_endpointAddress == 5) | ||
310 | interface = 2; | ||
311 | return usb_control_msg(serial->dev, | ||
312 | usb_rcvctrlpipe(serial->dev, 0), | ||
313 | 0x22, 0x21, val, interface, | ||
314 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
315 | } | ||
294 | return 0; | 316 | return 0; |
295 | } | 317 | } |
296 | 318 | ||
297 | static void sierra_set_termios(struct tty_struct *tty, | 319 | static void sierra_set_termios(struct tty_struct *tty, |
298 | struct usb_serial_port *port, struct ktermios *old_termios) | 320 | struct usb_serial_port *port, struct ktermios *old_termios) |
299 | { | 321 | { |
300 | dev_dbg(&port->dev, "%s", __func__); | 322 | dev_dbg(&port->dev, "%s\n", __func__); |
301 | tty_termios_copy_hw(tty->termios, old_termios); | 323 | tty_termios_copy_hw(tty->termios, old_termios); |
302 | sierra_send_setup(tty, port); | 324 | sierra_send_setup(port); |
303 | } | 325 | } |
304 | 326 | ||
305 | static int sierra_tiocmget(struct tty_struct *tty, struct file *file) | 327 | static int sierra_tiocmget(struct tty_struct *tty, struct file *file) |
@@ -308,7 +330,7 @@ static int sierra_tiocmget(struct tty_struct *tty, struct file *file) | |||
308 | unsigned int value; | 330 | unsigned int value; |
309 | struct sierra_port_private *portdata; | 331 | struct sierra_port_private *portdata; |
310 | 332 | ||
311 | dev_dbg(&port->dev, "%s", __func__); | 333 | dev_dbg(&port->dev, "%s\n", __func__); |
312 | portdata = usb_get_serial_port_data(port); | 334 | portdata = usb_get_serial_port_data(port); |
313 | 335 | ||
314 | value = ((portdata->rts_state) ? TIOCM_RTS : 0) | | 336 | value = ((portdata->rts_state) ? TIOCM_RTS : 0) | |
@@ -338,7 +360,18 @@ static int sierra_tiocmset(struct tty_struct *tty, struct file *file, | |||
338 | portdata->rts_state = 0; | 360 | portdata->rts_state = 0; |
339 | if (clear & TIOCM_DTR) | 361 | if (clear & TIOCM_DTR) |
340 | portdata->dtr_state = 0; | 362 | portdata->dtr_state = 0; |
341 | return sierra_send_setup(tty, port); | 363 | return sierra_send_setup(port); |
364 | } | ||
365 | |||
366 | static void sierra_release_urb(struct urb *urb) | ||
367 | { | ||
368 | struct usb_serial_port *port; | ||
369 | if (urb) { | ||
370 | port = urb->context; | ||
371 | dev_dbg(&port->dev, "%s: %p\n", __func__, urb); | ||
372 | kfree(urb->transfer_buffer); | ||
373 | usb_free_urb(urb); | ||
374 | } | ||
342 | } | 375 | } |
343 | 376 | ||
344 | static void sierra_outdat_callback(struct urb *urb) | 377 | static void sierra_outdat_callback(struct urb *urb) |
@@ -348,14 +381,14 @@ static void sierra_outdat_callback(struct urb *urb) | |||
348 | int status = urb->status; | 381 | int status = urb->status; |
349 | unsigned long flags; | 382 | unsigned long flags; |
350 | 383 | ||
351 | dev_dbg(&port->dev, "%s - port %d", __func__, port->number); | 384 | dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number); |
352 | 385 | ||
353 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | 386 | /* free up the transfer buffer, as usb_free_urb() does not do this */ |
354 | kfree(urb->transfer_buffer); | 387 | kfree(urb->transfer_buffer); |
355 | 388 | ||
356 | if (status) | 389 | if (status) |
357 | dev_dbg(&port->dev, "%s - nonzero write bulk status " | 390 | dev_dbg(&port->dev, "%s - nonzero write bulk status " |
358 | "received: %d", __func__, status); | 391 | "received: %d\n", __func__, status); |
359 | 392 | ||
360 | spin_lock_irqsave(&portdata->lock, flags); | 393 | spin_lock_irqsave(&portdata->lock, flags); |
361 | --portdata->outstanding_urbs; | 394 | --portdata->outstanding_urbs; |
@@ -373,50 +406,61 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
373 | unsigned long flags; | 406 | unsigned long flags; |
374 | unsigned char *buffer; | 407 | unsigned char *buffer; |
375 | struct urb *urb; | 408 | struct urb *urb; |
376 | int status; | 409 | size_t writesize = min((size_t)count, (size_t)MAX_TRANSFER); |
410 | int retval = 0; | ||
411 | |||
412 | /* verify that we actually have some data to write */ | ||
413 | if (count == 0) | ||
414 | return 0; | ||
377 | 415 | ||
378 | portdata = usb_get_serial_port_data(port); | 416 | portdata = usb_get_serial_port_data(port); |
379 | 417 | ||
380 | dev_dbg(&port->dev, "%s: write (%d chars)", __func__, count); | 418 | dev_dbg(&port->dev, "%s: write (%zd bytes)\n", __func__, writesize); |
381 | 419 | ||
382 | spin_lock_irqsave(&portdata->lock, flags); | 420 | spin_lock_irqsave(&portdata->lock, flags); |
421 | dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__, | ||
422 | portdata->outstanding_urbs); | ||
383 | if (portdata->outstanding_urbs > N_OUT_URB) { | 423 | if (portdata->outstanding_urbs > N_OUT_URB) { |
384 | spin_unlock_irqrestore(&portdata->lock, flags); | 424 | spin_unlock_irqrestore(&portdata->lock, flags); |
385 | dev_dbg(&port->dev, "%s - write limit hit\n", __func__); | 425 | dev_dbg(&port->dev, "%s - write limit hit\n", __func__); |
386 | return 0; | 426 | return 0; |
387 | } | 427 | } |
388 | portdata->outstanding_urbs++; | 428 | portdata->outstanding_urbs++; |
429 | dev_dbg(&port->dev, "%s - 1, outstanding_urbs: %d\n", __func__, | ||
430 | portdata->outstanding_urbs); | ||
389 | spin_unlock_irqrestore(&portdata->lock, flags); | 431 | spin_unlock_irqrestore(&portdata->lock, flags); |
390 | 432 | ||
391 | buffer = kmalloc(count, GFP_ATOMIC); | 433 | buffer = kmalloc(writesize, GFP_ATOMIC); |
392 | if (!buffer) { | 434 | if (!buffer) { |
393 | dev_err(&port->dev, "out of memory\n"); | 435 | dev_err(&port->dev, "out of memory\n"); |
394 | count = -ENOMEM; | 436 | retval = -ENOMEM; |
395 | goto error_no_buffer; | 437 | goto error_no_buffer; |
396 | } | 438 | } |
397 | 439 | ||
398 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 440 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
399 | if (!urb) { | 441 | if (!urb) { |
400 | dev_err(&port->dev, "no more free urbs\n"); | 442 | dev_err(&port->dev, "no more free urbs\n"); |
401 | count = -ENOMEM; | 443 | retval = -ENOMEM; |
402 | goto error_no_urb; | 444 | goto error_no_urb; |
403 | } | 445 | } |
404 | 446 | ||
405 | memcpy(buffer, buf, count); | 447 | memcpy(buffer, buf, writesize); |
406 | 448 | ||
407 | usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); | 449 | usb_serial_debug_data(debug, &port->dev, __func__, writesize, buffer); |
408 | 450 | ||
409 | usb_fill_bulk_urb(urb, serial->dev, | 451 | usb_fill_bulk_urb(urb, serial->dev, |
410 | usb_sndbulkpipe(serial->dev, | 452 | usb_sndbulkpipe(serial->dev, |
411 | port->bulk_out_endpointAddress), | 453 | port->bulk_out_endpointAddress), |
412 | buffer, count, sierra_outdat_callback, port); | 454 | buffer, writesize, sierra_outdat_callback, port); |
455 | |||
456 | /* Handle the need to send a zero length packet */ | ||
457 | urb->transfer_flags |= URB_ZERO_PACKET; | ||
413 | 458 | ||
414 | /* send it down the pipe */ | 459 | /* send it down the pipe */ |
415 | status = usb_submit_urb(urb, GFP_ATOMIC); | 460 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
416 | if (status) { | 461 | if (retval) { |
417 | dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " | 462 | dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " |
418 | "with status = %d\n", __func__, status); | 463 | "with status = %d\n", __func__, retval); |
419 | count = status; | ||
420 | goto error; | 464 | goto error; |
421 | } | 465 | } |
422 | 466 | ||
@@ -424,7 +468,7 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
424 | * really free it when it is finished with it */ | 468 | * really free it when it is finished with it */ |
425 | usb_free_urb(urb); | 469 | usb_free_urb(urb); |
426 | 470 | ||
427 | return count; | 471 | return writesize; |
428 | error: | 472 | error: |
429 | usb_free_urb(urb); | 473 | usb_free_urb(urb); |
430 | error_no_urb: | 474 | error_no_urb: |
@@ -432,8 +476,10 @@ error_no_urb: | |||
432 | error_no_buffer: | 476 | error_no_buffer: |
433 | spin_lock_irqsave(&portdata->lock, flags); | 477 | spin_lock_irqsave(&portdata->lock, flags); |
434 | --portdata->outstanding_urbs; | 478 | --portdata->outstanding_urbs; |
479 | dev_dbg(&port->dev, "%s - 2. outstanding_urbs: %d\n", __func__, | ||
480 | portdata->outstanding_urbs); | ||
435 | spin_unlock_irqrestore(&portdata->lock, flags); | 481 | spin_unlock_irqrestore(&portdata->lock, flags); |
436 | return count; | 482 | return retval; |
437 | } | 483 | } |
438 | 484 | ||
439 | static void sierra_indat_callback(struct urb *urb) | 485 | static void sierra_indat_callback(struct urb *urb) |
@@ -445,33 +491,39 @@ static void sierra_indat_callback(struct urb *urb) | |||
445 | unsigned char *data = urb->transfer_buffer; | 491 | unsigned char *data = urb->transfer_buffer; |
446 | int status = urb->status; | 492 | int status = urb->status; |
447 | 493 | ||
448 | dbg("%s: %p", __func__, urb); | ||
449 | |||
450 | endpoint = usb_pipeendpoint(urb->pipe); | 494 | endpoint = usb_pipeendpoint(urb->pipe); |
451 | port = urb->context; | 495 | port = urb->context; |
496 | |||
497 | dev_dbg(&port->dev, "%s: %p\n", __func__, urb); | ||
452 | 498 | ||
453 | if (status) { | 499 | if (status) { |
454 | dev_dbg(&port->dev, "%s: nonzero status: %d on" | 500 | dev_dbg(&port->dev, "%s: nonzero status: %d on" |
455 | " endpoint %02x.", __func__, status, endpoint); | 501 | " endpoint %02x\n", __func__, status, endpoint); |
456 | } else { | 502 | } else { |
457 | if (urb->actual_length) { | 503 | if (urb->actual_length) { |
458 | tty = tty_port_tty_get(&port->port); | 504 | tty = tty_port_tty_get(&port->port); |
505 | |||
459 | tty_buffer_request_room(tty, urb->actual_length); | 506 | tty_buffer_request_room(tty, urb->actual_length); |
460 | tty_insert_flip_string(tty, data, urb->actual_length); | 507 | tty_insert_flip_string(tty, data, urb->actual_length); |
461 | tty_flip_buffer_push(tty); | 508 | tty_flip_buffer_push(tty); |
509 | |||
462 | tty_kref_put(tty); | 510 | tty_kref_put(tty); |
463 | } else | 511 | usb_serial_debug_data(debug, &port->dev, __func__, |
512 | urb->actual_length, data); | ||
513 | } else { | ||
464 | dev_dbg(&port->dev, "%s: empty read urb" | 514 | dev_dbg(&port->dev, "%s: empty read urb" |
465 | " received", __func__); | 515 | " received\n", __func__); |
466 | |||
467 | /* Resubmit urb so we continue receiving */ | ||
468 | if (port->port.count && status != -ESHUTDOWN) { | ||
469 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
470 | if (err) | ||
471 | dev_err(&port->dev, "resubmit read urb failed." | ||
472 | "(%d)\n", err); | ||
473 | } | 516 | } |
474 | } | 517 | } |
518 | |||
519 | /* Resubmit urb so we continue receiving */ | ||
520 | if (port->port.count && status != -ESHUTDOWN && status != -EPERM) { | ||
521 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
522 | if (err) | ||
523 | dev_err(&port->dev, "resubmit read urb failed." | ||
524 | "(%d)\n", err); | ||
525 | } | ||
526 | |||
475 | return; | 527 | return; |
476 | } | 528 | } |
477 | 529 | ||
@@ -483,8 +535,7 @@ static void sierra_instat_callback(struct urb *urb) | |||
483 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); | 535 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); |
484 | struct usb_serial *serial = port->serial; | 536 | struct usb_serial *serial = port->serial; |
485 | 537 | ||
486 | dev_dbg(&port->dev, "%s", __func__); | 538 | dev_dbg(&port->dev, "%s: urb %p port %p has data %p\n", __func__, |
487 | dev_dbg(&port->dev, "%s: urb %p port %p has data %p", __func__, | ||
488 | urb, port, portdata); | 539 | urb, port, portdata); |
489 | 540 | ||
490 | if (status == 0) { | 541 | if (status == 0) { |
@@ -504,7 +555,7 @@ static void sierra_instat_callback(struct urb *urb) | |||
504 | sizeof(struct usb_ctrlrequest)); | 555 | sizeof(struct usb_ctrlrequest)); |
505 | struct tty_struct *tty; | 556 | struct tty_struct *tty; |
506 | 557 | ||
507 | dev_dbg(&port->dev, "%s: signal x%x", __func__, | 558 | dev_dbg(&port->dev, "%s: signal x%x\n", __func__, |
508 | signals); | 559 | signals); |
509 | 560 | ||
510 | old_dcd_state = portdata->dcd_state; | 561 | old_dcd_state = portdata->dcd_state; |
@@ -519,20 +570,20 @@ static void sierra_instat_callback(struct urb *urb) | |||
519 | tty_hangup(tty); | 570 | tty_hangup(tty); |
520 | tty_kref_put(tty); | 571 | tty_kref_put(tty); |
521 | } else { | 572 | } else { |
522 | dev_dbg(&port->dev, "%s: type %x req %x", | 573 | dev_dbg(&port->dev, "%s: type %x req %x\n", |
523 | __func__, req_pkt->bRequestType, | 574 | __func__, req_pkt->bRequestType, |
524 | req_pkt->bRequest); | 575 | req_pkt->bRequest); |
525 | } | 576 | } |
526 | } else | 577 | } else |
527 | dev_dbg(&port->dev, "%s: error %d", __func__, status); | 578 | dev_dbg(&port->dev, "%s: error %d\n", __func__, status); |
528 | 579 | ||
529 | /* Resubmit urb so we continue receiving IRQ data */ | 580 | /* Resubmit urb so we continue receiving IRQ data */ |
530 | if (status != -ESHUTDOWN) { | 581 | if (port->port.count && status != -ESHUTDOWN && status != -ENOENT) { |
531 | urb->dev = serial->dev; | 582 | urb->dev = serial->dev; |
532 | err = usb_submit_urb(urb, GFP_ATOMIC); | 583 | err = usb_submit_urb(urb, GFP_ATOMIC); |
533 | if (err) | 584 | if (err) |
534 | dev_dbg(&port->dev, "%s: resubmit intr urb " | 585 | dev_err(&port->dev, "%s: resubmit intr urb " |
535 | "failed. (%d)", __func__, err); | 586 | "failed. (%d)\n", __func__, err); |
536 | } | 587 | } |
537 | } | 588 | } |
538 | 589 | ||
@@ -542,7 +593,7 @@ static int sierra_write_room(struct tty_struct *tty) | |||
542 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); | 593 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); |
543 | unsigned long flags; | 594 | unsigned long flags; |
544 | 595 | ||
545 | dev_dbg(&port->dev, "%s - port %d", __func__, port->number); | 596 | dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number); |
546 | 597 | ||
547 | /* try to give a good number back based on if we have any free urbs at | 598 | /* try to give a good number back based on if we have any free urbs at |
548 | * this point in time */ | 599 | * this point in time */ |
@@ -557,67 +608,99 @@ static int sierra_write_room(struct tty_struct *tty) | |||
557 | return 2048; | 608 | return 2048; |
558 | } | 609 | } |
559 | 610 | ||
560 | static int sierra_open(struct tty_struct *tty, | 611 | static void sierra_stop_rx_urbs(struct usb_serial_port *port) |
561 | struct usb_serial_port *port, struct file *filp) | ||
562 | { | 612 | { |
563 | struct sierra_port_private *portdata; | ||
564 | struct usb_serial *serial = port->serial; | ||
565 | int i; | 613 | int i; |
566 | struct urb *urb; | 614 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); |
567 | int result; | ||
568 | 615 | ||
569 | portdata = usb_get_serial_port_data(port); | 616 | for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) |
617 | usb_kill_urb(portdata->in_urbs[i]); | ||
570 | 618 | ||
571 | dev_dbg(&port->dev, "%s", __func__); | 619 | usb_kill_urb(port->interrupt_in_urb); |
620 | } | ||
572 | 621 | ||
573 | /* Set some sane defaults */ | 622 | static int sierra_submit_rx_urbs(struct usb_serial_port *port, gfp_t mem_flags) |
574 | portdata->rts_state = 1; | 623 | { |
575 | portdata->dtr_state = 1; | 624 | int ok_cnt; |
625 | int err = -EINVAL; | ||
626 | int i; | ||
627 | struct urb *urb; | ||
628 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); | ||
576 | 629 | ||
577 | /* Reset low level data toggle and start reading from endpoints */ | 630 | ok_cnt = 0; |
578 | for (i = 0; i < N_IN_URB; i++) { | 631 | for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) { |
579 | urb = portdata->in_urbs[i]; | 632 | urb = portdata->in_urbs[i]; |
580 | if (!urb) | 633 | if (!urb) |
581 | continue; | 634 | continue; |
582 | if (urb->dev != serial->dev) { | 635 | err = usb_submit_urb(urb, mem_flags); |
583 | dev_dbg(&port->dev, "%s: dev %p != %p", | 636 | if (err) { |
584 | __func__, urb->dev, serial->dev); | 637 | dev_err(&port->dev, "%s: submit urb failed: %d\n", |
585 | continue; | 638 | __func__, err); |
639 | } else { | ||
640 | ok_cnt++; | ||
586 | } | 641 | } |
642 | } | ||
587 | 643 | ||
588 | /* | 644 | if (ok_cnt && port->interrupt_in_urb) { |
589 | * make sure endpoint data toggle is synchronized with the | 645 | err = usb_submit_urb(port->interrupt_in_urb, mem_flags); |
590 | * device | 646 | if (err) { |
591 | */ | 647 | dev_err(&port->dev, "%s: submit intr urb failed: %d\n", |
592 | usb_clear_halt(urb->dev, urb->pipe); | 648 | __func__, err); |
593 | |||
594 | result = usb_submit_urb(urb, GFP_KERNEL); | ||
595 | if (result) { | ||
596 | dev_err(&port->dev, "submit urb %d failed (%d) %d\n", | ||
597 | i, result, urb->transfer_buffer_length); | ||
598 | } | 649 | } |
599 | } | 650 | } |
600 | 651 | ||
601 | sierra_send_setup(tty, port); | 652 | if (ok_cnt > 0) /* at least one rx urb submitted */ |
653 | return 0; | ||
654 | else | ||
655 | return err; | ||
656 | } | ||
602 | 657 | ||
603 | /* start up the interrupt endpoint if we have one */ | 658 | static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint, |
604 | if (port->interrupt_in_urb) { | 659 | int dir, void *ctx, int len, |
605 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | 660 | gfp_t mem_flags, |
606 | if (result) | 661 | usb_complete_t callback) |
607 | dev_err(&port->dev, "submit irq_in urb failed %d\n", | 662 | { |
608 | result); | 663 | struct urb *urb; |
664 | u8 *buf; | ||
665 | |||
666 | if (endpoint == -1) | ||
667 | return NULL; | ||
668 | |||
669 | urb = usb_alloc_urb(0, mem_flags); | ||
670 | if (urb == NULL) { | ||
671 | dev_dbg(&serial->dev->dev, "%s: alloc for endpoint %d failed\n", | ||
672 | __func__, endpoint); | ||
673 | return NULL; | ||
609 | } | 674 | } |
610 | return 0; | 675 | |
676 | buf = kmalloc(len, mem_flags); | ||
677 | if (buf) { | ||
678 | /* Fill URB using supplied data */ | ||
679 | usb_fill_bulk_urb(urb, serial->dev, | ||
680 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | ||
681 | buf, len, callback, ctx); | ||
682 | |||
683 | /* debug */ | ||
684 | dev_dbg(&serial->dev->dev, "%s %c u : %p d:%p\n", __func__, | ||
685 | dir == USB_DIR_IN ? 'i' : 'o', urb, buf); | ||
686 | } else { | ||
687 | dev_dbg(&serial->dev->dev, "%s %c u:%p d:%p\n", __func__, | ||
688 | dir == USB_DIR_IN ? 'i' : 'o', urb, buf); | ||
689 | |||
690 | sierra_release_urb(urb); | ||
691 | urb = NULL; | ||
692 | } | ||
693 | |||
694 | return urb; | ||
611 | } | 695 | } |
612 | 696 | ||
613 | static void sierra_close(struct tty_struct *tty, | 697 | static void sierra_close(struct usb_serial_port *port) |
614 | struct usb_serial_port *port, struct file *filp) | ||
615 | { | 698 | { |
616 | int i; | 699 | int i; |
617 | struct usb_serial *serial = port->serial; | 700 | struct usb_serial *serial = port->serial; |
618 | struct sierra_port_private *portdata; | 701 | struct sierra_port_private *portdata; |
619 | 702 | ||
620 | dev_dbg(&port->dev, "%s", __func__); | 703 | dev_dbg(&port->dev, "%s\n", __func__); |
621 | portdata = usb_get_serial_port_data(port); | 704 | portdata = usb_get_serial_port_data(port); |
622 | 705 | ||
623 | portdata->rts_state = 0; | 706 | portdata->rts_state = 0; |
@@ -626,27 +709,85 @@ static void sierra_close(struct tty_struct *tty, | |||
626 | if (serial->dev) { | 709 | if (serial->dev) { |
627 | mutex_lock(&serial->disc_mutex); | 710 | mutex_lock(&serial->disc_mutex); |
628 | if (!serial->disconnected) | 711 | if (!serial->disconnected) |
629 | sierra_send_setup(tty, port); | 712 | sierra_send_setup(port); |
630 | mutex_unlock(&serial->disc_mutex); | 713 | mutex_unlock(&serial->disc_mutex); |
631 | 714 | ||
632 | /* Stop reading/writing urbs */ | 715 | /* Stop reading urbs */ |
633 | for (i = 0; i < N_IN_URB; i++) | 716 | sierra_stop_rx_urbs(port); |
634 | usb_kill_urb(portdata->in_urbs[i]); | 717 | /* .. and release them */ |
718 | for (i = 0; i < N_IN_URB; i++) { | ||
719 | sierra_release_urb(portdata->in_urbs[i]); | ||
720 | portdata->in_urbs[i] = NULL; | ||
721 | } | ||
635 | } | 722 | } |
723 | } | ||
636 | 724 | ||
637 | usb_kill_urb(port->interrupt_in_urb); | 725 | static int sierra_open(struct tty_struct *tty, |
638 | tty_port_tty_set(&port->port, NULL); | 726 | struct usb_serial_port *port, struct file *filp) |
727 | { | ||
728 | struct sierra_port_private *portdata; | ||
729 | struct usb_serial *serial = port->serial; | ||
730 | int i; | ||
731 | int err; | ||
732 | int endpoint; | ||
733 | struct urb *urb; | ||
734 | |||
735 | portdata = usb_get_serial_port_data(port); | ||
736 | |||
737 | dev_dbg(&port->dev, "%s\n", __func__); | ||
738 | |||
739 | /* Set some sane defaults */ | ||
740 | portdata->rts_state = 1; | ||
741 | portdata->dtr_state = 1; | ||
742 | |||
743 | |||
744 | endpoint = port->bulk_in_endpointAddress; | ||
745 | for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) { | ||
746 | urb = sierra_setup_urb(serial, endpoint, USB_DIR_IN, port, | ||
747 | IN_BUFLEN, GFP_KERNEL, | ||
748 | sierra_indat_callback); | ||
749 | portdata->in_urbs[i] = urb; | ||
750 | } | ||
751 | /* clear halt condition */ | ||
752 | usb_clear_halt(serial->dev, | ||
753 | usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN); | ||
754 | |||
755 | err = sierra_submit_rx_urbs(port, GFP_KERNEL); | ||
756 | if (err) { | ||
757 | /* get rid of everything as in close */ | ||
758 | sierra_close(port); | ||
759 | return err; | ||
760 | } | ||
761 | sierra_send_setup(port); | ||
762 | |||
763 | return 0; | ||
764 | } | ||
765 | |||
766 | |||
767 | static void sierra_dtr_rts(struct usb_serial_port *port, int on) | ||
768 | { | ||
769 | struct usb_serial *serial = port->serial; | ||
770 | struct sierra_port_private *portdata; | ||
771 | |||
772 | portdata = usb_get_serial_port_data(port); | ||
773 | portdata->rts_state = on; | ||
774 | portdata->dtr_state = on; | ||
775 | |||
776 | if (serial->dev) { | ||
777 | mutex_lock(&serial->disc_mutex); | ||
778 | if (!serial->disconnected) | ||
779 | sierra_send_setup(port); | ||
780 | mutex_unlock(&serial->disc_mutex); | ||
781 | } | ||
639 | } | 782 | } |
640 | 783 | ||
641 | static int sierra_startup(struct usb_serial *serial) | 784 | static int sierra_startup(struct usb_serial *serial) |
642 | { | 785 | { |
643 | struct usb_serial_port *port; | 786 | struct usb_serial_port *port; |
644 | struct sierra_port_private *portdata; | 787 | struct sierra_port_private *portdata; |
645 | struct urb *urb; | ||
646 | int i; | 788 | int i; |
647 | int j; | ||
648 | 789 | ||
649 | dev_dbg(&serial->dev->dev, "%s", __func__); | 790 | dev_dbg(&serial->dev->dev, "%s\n", __func__); |
650 | 791 | ||
651 | /* Set Device mode to D0 */ | 792 | /* Set Device mode to D0 */ |
652 | sierra_set_power_state(serial->dev, 0x0000); | 793 | sierra_set_power_state(serial->dev, 0x0000); |
@@ -661,51 +802,25 @@ static int sierra_startup(struct usb_serial *serial) | |||
661 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); | 802 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); |
662 | if (!portdata) { | 803 | if (!portdata) { |
663 | dev_dbg(&port->dev, "%s: kmalloc for " | 804 | dev_dbg(&port->dev, "%s: kmalloc for " |
664 | "sierra_port_private (%d) failed!.", | 805 | "sierra_port_private (%d) failed!.\n", |
665 | __func__, i); | 806 | __func__, i); |
666 | return -ENOMEM; | 807 | return -ENOMEM; |
667 | } | 808 | } |
668 | spin_lock_init(&portdata->lock); | 809 | spin_lock_init(&portdata->lock); |
669 | for (j = 0; j < N_IN_URB; j++) { | 810 | /* Set the port private data pointer */ |
670 | portdata->in_buffer[j] = kmalloc(IN_BUFLEN, GFP_KERNEL); | ||
671 | if (!portdata->in_buffer[j]) { | ||
672 | for (--j; j >= 0; j--) | ||
673 | kfree(portdata->in_buffer[j]); | ||
674 | kfree(portdata); | ||
675 | return -ENOMEM; | ||
676 | } | ||
677 | } | ||
678 | |||
679 | usb_set_serial_port_data(port, portdata); | 811 | usb_set_serial_port_data(port, portdata); |
680 | |||
681 | /* initialize the in urbs */ | ||
682 | for (j = 0; j < N_IN_URB; ++j) { | ||
683 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
684 | if (urb == NULL) { | ||
685 | dev_dbg(&port->dev, "%s: alloc for in " | ||
686 | "port failed.", __func__); | ||
687 | continue; | ||
688 | } | ||
689 | /* Fill URB using supplied data. */ | ||
690 | usb_fill_bulk_urb(urb, serial->dev, | ||
691 | usb_rcvbulkpipe(serial->dev, | ||
692 | port->bulk_in_endpointAddress), | ||
693 | portdata->in_buffer[j], IN_BUFLEN, | ||
694 | sierra_indat_callback, port); | ||
695 | portdata->in_urbs[j] = urb; | ||
696 | } | ||
697 | } | 812 | } |
698 | 813 | ||
699 | return 0; | 814 | return 0; |
700 | } | 815 | } |
701 | 816 | ||
702 | static void sierra_shutdown(struct usb_serial *serial) | 817 | static void sierra_disconnect(struct usb_serial *serial) |
703 | { | 818 | { |
704 | int i, j; | 819 | int i; |
705 | struct usb_serial_port *port; | 820 | struct usb_serial_port *port; |
706 | struct sierra_port_private *portdata; | 821 | struct sierra_port_private *portdata; |
707 | 822 | ||
708 | dev_dbg(&serial->dev->dev, "%s", __func__); | 823 | dev_dbg(&serial->dev->dev, "%s\n", __func__); |
709 | 824 | ||
710 | for (i = 0; i < serial->num_ports; ++i) { | 825 | for (i = 0; i < serial->num_ports; ++i) { |
711 | port = serial->port[i]; | 826 | port = serial->port[i]; |
@@ -714,12 +829,6 @@ static void sierra_shutdown(struct usb_serial *serial) | |||
714 | portdata = usb_get_serial_port_data(port); | 829 | portdata = usb_get_serial_port_data(port); |
715 | if (!portdata) | 830 | if (!portdata) |
716 | continue; | 831 | continue; |
717 | |||
718 | for (j = 0; j < N_IN_URB; j++) { | ||
719 | usb_kill_urb(portdata->in_urbs[j]); | ||
720 | usb_free_urb(portdata->in_urbs[j]); | ||
721 | kfree(portdata->in_buffer[j]); | ||
722 | } | ||
723 | kfree(portdata); | 832 | kfree(portdata); |
724 | usb_set_serial_port_data(port, NULL); | 833 | usb_set_serial_port_data(port, NULL); |
725 | } | 834 | } |
@@ -737,13 +846,14 @@ static struct usb_serial_driver sierra_device = { | |||
737 | .probe = sierra_probe, | 846 | .probe = sierra_probe, |
738 | .open = sierra_open, | 847 | .open = sierra_open, |
739 | .close = sierra_close, | 848 | .close = sierra_close, |
849 | .dtr_rts = sierra_dtr_rts, | ||
740 | .write = sierra_write, | 850 | .write = sierra_write, |
741 | .write_room = sierra_write_room, | 851 | .write_room = sierra_write_room, |
742 | .set_termios = sierra_set_termios, | 852 | .set_termios = sierra_set_termios, |
743 | .tiocmget = sierra_tiocmget, | 853 | .tiocmget = sierra_tiocmget, |
744 | .tiocmset = sierra_tiocmset, | 854 | .tiocmset = sierra_tiocmset, |
745 | .attach = sierra_startup, | 855 | .attach = sierra_startup, |
746 | .shutdown = sierra_shutdown, | 856 | .disconnect = sierra_disconnect, |
747 | .read_int_callback = sierra_instat_callback, | 857 | .read_int_callback = sierra_instat_callback, |
748 | }; | 858 | }; |
749 | 859 | ||
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 5e7528cc81a8..3c249d8e8b8e 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c | |||
@@ -356,7 +356,7 @@ cleanup: | |||
356 | } | 356 | } |
357 | 357 | ||
358 | /* call when the device plug out. free all the memory alloced by probe */ | 358 | /* call when the device plug out. free all the memory alloced by probe */ |
359 | static void spcp8x5_shutdown(struct usb_serial *serial) | 359 | static void spcp8x5_release(struct usb_serial *serial) |
360 | { | 360 | { |
361 | int i; | 361 | int i; |
362 | struct spcp8x5_private *priv; | 362 | struct spcp8x5_private *priv; |
@@ -366,7 +366,6 @@ static void spcp8x5_shutdown(struct usb_serial *serial) | |||
366 | if (priv) { | 366 | if (priv) { |
367 | free_ringbuf(priv->buf); | 367 | free_ringbuf(priv->buf); |
368 | kfree(priv); | 368 | kfree(priv); |
369 | usb_set_serial_port_data(serial->port[i] , NULL); | ||
370 | } | 369 | } |
371 | } | 370 | } |
372 | } | 371 | } |
@@ -446,66 +445,47 @@ static void spcp8x5_set_workMode(struct usb_device *dev, u16 value, | |||
446 | "RTSCTS usb_control_msg(enable flowctrl) = %d\n", ret); | 445 | "RTSCTS usb_control_msg(enable flowctrl) = %d\n", ret); |
447 | } | 446 | } |
448 | 447 | ||
448 | static int spcp8x5_carrier_raised(struct usb_serial_port *port) | ||
449 | { | ||
450 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | ||
451 | if (priv->line_status & MSR_STATUS_LINE_DCD) | ||
452 | return 1; | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static void spcp8x5_dtr_rts(struct usb_serial_port *port, int on) | ||
457 | { | ||
458 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | ||
459 | unsigned long flags; | ||
460 | u8 control; | ||
461 | |||
462 | spin_lock_irqsave(&priv->lock, flags); | ||
463 | if (on) | ||
464 | priv->line_control = MCR_CONTROL_LINE_DTR | ||
465 | | MCR_CONTROL_LINE_RTS; | ||
466 | else | ||
467 | priv->line_control &= ~ (MCR_CONTROL_LINE_DTR | ||
468 | | MCR_CONTROL_LINE_RTS); | ||
469 | control = priv->line_control; | ||
470 | spin_unlock_irqrestore(&priv->lock, flags); | ||
471 | spcp8x5_set_ctrlLine(port->serial->dev, control , priv->type); | ||
472 | } | ||
473 | |||
449 | /* close the serial port. We should wait for data sending to device 1st and | 474 | /* close the serial port. We should wait for data sending to device 1st and |
450 | * then kill all urb. */ | 475 | * then kill all urb. */ |
451 | static void spcp8x5_close(struct tty_struct *tty, | 476 | static void spcp8x5_close(struct usb_serial_port *port) |
452 | struct usb_serial_port *port, struct file *filp) | ||
453 | { | 477 | { |
454 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | 478 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); |
455 | unsigned long flags; | 479 | unsigned long flags; |
456 | unsigned int c_cflag; | ||
457 | int bps; | ||
458 | long timeout; | ||
459 | wait_queue_t wait; | ||
460 | int result; | 480 | int result; |
461 | 481 | ||
462 | dbg("%s - port %d", __func__, port->number); | 482 | dbg("%s - port %d", __func__, port->number); |
463 | 483 | ||
464 | /* wait for data to drain from the buffer */ | ||
465 | spin_lock_irqsave(&priv->lock, flags); | 484 | spin_lock_irqsave(&priv->lock, flags); |
466 | timeout = SPCP8x5_CLOSING_WAIT; | ||
467 | init_waitqueue_entry(&wait, current); | ||
468 | add_wait_queue(&tty->write_wait, &wait); | ||
469 | for (;;) { | ||
470 | set_current_state(TASK_INTERRUPTIBLE); | ||
471 | if (ringbuf_avail_data(priv->buf) == 0 || | ||
472 | timeout == 0 || signal_pending(current)) | ||
473 | break; | ||
474 | spin_unlock_irqrestore(&priv->lock, flags); | ||
475 | timeout = schedule_timeout(timeout); | ||
476 | spin_lock_irqsave(&priv->lock, flags); | ||
477 | } | ||
478 | set_current_state(TASK_RUNNING); | ||
479 | remove_wait_queue(&tty->write_wait, &wait); | ||
480 | |||
481 | /* clear out any remaining data in the buffer */ | 485 | /* clear out any remaining data in the buffer */ |
482 | clear_ringbuf(priv->buf); | 486 | clear_ringbuf(priv->buf); |
483 | spin_unlock_irqrestore(&priv->lock, flags); | 487 | spin_unlock_irqrestore(&priv->lock, flags); |
484 | 488 | ||
485 | /* wait for characters to drain from the device (this is long enough | ||
486 | * for the entire all byte spcp8x5 hardware buffer to drain with no | ||
487 | * flow control for data rates of 1200 bps or more, for lower rates we | ||
488 | * should really know how much data is in the buffer to compute a delay | ||
489 | * that is not unnecessarily long) */ | ||
490 | bps = tty_get_baud_rate(tty); | ||
491 | if (bps > 1200) | ||
492 | timeout = max((HZ*2560) / bps, HZ/10); | ||
493 | else | ||
494 | timeout = 2*HZ; | ||
495 | set_current_state(TASK_INTERRUPTIBLE); | ||
496 | schedule_timeout(timeout); | ||
497 | |||
498 | /* clear control lines */ | ||
499 | if (tty) { | ||
500 | c_cflag = tty->termios->c_cflag; | ||
501 | if (c_cflag & HUPCL) { | ||
502 | spin_lock_irqsave(&priv->lock, flags); | ||
503 | priv->line_control = 0; | ||
504 | spin_unlock_irqrestore(&priv->lock, flags); | ||
505 | spcp8x5_set_ctrlLine(port->serial->dev, 0 , priv->type); | ||
506 | } | ||
507 | } | ||
508 | |||
509 | /* kill urb */ | 489 | /* kill urb */ |
510 | if (port->write_urb != NULL) { | 490 | if (port->write_urb != NULL) { |
511 | result = usb_unlink_urb(port->write_urb); | 491 | result = usb_unlink_urb(port->write_urb); |
@@ -665,13 +645,6 @@ static int spcp8x5_open(struct tty_struct *tty, | |||
665 | if (ret) | 645 | if (ret) |
666 | return ret; | 646 | return ret; |
667 | 647 | ||
668 | spin_lock_irqsave(&priv->lock, flags); | ||
669 | if (tty && (tty->termios->c_cflag & CBAUD)) | ||
670 | priv->line_control = MCR_DTR | MCR_RTS; | ||
671 | else | ||
672 | priv->line_control = 0; | ||
673 | spin_unlock_irqrestore(&priv->lock, flags); | ||
674 | |||
675 | spcp8x5_set_ctrlLine(serial->dev, priv->line_control , priv->type); | 648 | spcp8x5_set_ctrlLine(serial->dev, priv->line_control , priv->type); |
676 | 649 | ||
677 | /* Setup termios */ | 650 | /* Setup termios */ |
@@ -691,9 +664,10 @@ static int spcp8x5_open(struct tty_struct *tty, | |||
691 | port->read_urb->dev = serial->dev; | 664 | port->read_urb->dev = serial->dev; |
692 | ret = usb_submit_urb(port->read_urb, GFP_KERNEL); | 665 | ret = usb_submit_urb(port->read_urb, GFP_KERNEL); |
693 | if (ret) { | 666 | if (ret) { |
694 | spcp8x5_close(tty, port, NULL); | 667 | spcp8x5_close(port); |
695 | return -EPROTO; | 668 | return -EPROTO; |
696 | } | 669 | } |
670 | port->port.drain_delay = 256; | ||
697 | return 0; | 671 | return 0; |
698 | } | 672 | } |
699 | 673 | ||
@@ -1033,6 +1007,8 @@ static struct usb_serial_driver spcp8x5_device = { | |||
1033 | .num_ports = 1, | 1007 | .num_ports = 1, |
1034 | .open = spcp8x5_open, | 1008 | .open = spcp8x5_open, |
1035 | .close = spcp8x5_close, | 1009 | .close = spcp8x5_close, |
1010 | .dtr_rts = spcp8x5_dtr_rts, | ||
1011 | .carrier_raised = spcp8x5_carrier_raised, | ||
1036 | .write = spcp8x5_write, | 1012 | .write = spcp8x5_write, |
1037 | .set_termios = spcp8x5_set_termios, | 1013 | .set_termios = spcp8x5_set_termios, |
1038 | .ioctl = spcp8x5_ioctl, | 1014 | .ioctl = spcp8x5_ioctl, |
@@ -1043,7 +1019,7 @@ static struct usb_serial_driver spcp8x5_device = { | |||
1043 | .write_bulk_callback = spcp8x5_write_bulk_callback, | 1019 | .write_bulk_callback = spcp8x5_write_bulk_callback, |
1044 | .chars_in_buffer = spcp8x5_chars_in_buffer, | 1020 | .chars_in_buffer = spcp8x5_chars_in_buffer, |
1045 | .attach = spcp8x5_startup, | 1021 | .attach = spcp8x5_startup, |
1046 | .shutdown = spcp8x5_shutdown, | 1022 | .release = spcp8x5_release, |
1047 | }; | 1023 | }; |
1048 | 1024 | ||
1049 | static int __init spcp8x5_init(void) | 1025 | static int __init spcp8x5_init(void) |
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c index 69879e437940..6157fac9366b 100644 --- a/drivers/usb/serial/symbolserial.c +++ b/drivers/usb/serial/symbolserial.c | |||
@@ -152,8 +152,7 @@ static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
152 | return result; | 152 | return result; |
153 | } | 153 | } |
154 | 154 | ||
155 | static void symbol_close(struct tty_struct *tty, struct usb_serial_port *port, | 155 | static void symbol_close(struct usb_serial_port *port) |
156 | struct file *filp) | ||
157 | { | 156 | { |
158 | struct symbol_private *priv = usb_get_serial_data(port->serial); | 157 | struct symbol_private *priv = usb_get_serial_data(port->serial); |
159 | 158 | ||
@@ -268,7 +267,7 @@ error: | |||
268 | return retval; | 267 | return retval; |
269 | } | 268 | } |
270 | 269 | ||
271 | static void symbol_shutdown(struct usb_serial *serial) | 270 | static void symbol_disconnect(struct usb_serial *serial) |
272 | { | 271 | { |
273 | struct symbol_private *priv = usb_get_serial_data(serial); | 272 | struct symbol_private *priv = usb_get_serial_data(serial); |
274 | 273 | ||
@@ -276,9 +275,16 @@ static void symbol_shutdown(struct usb_serial *serial) | |||
276 | 275 | ||
277 | usb_kill_urb(priv->int_urb); | 276 | usb_kill_urb(priv->int_urb); |
278 | usb_free_urb(priv->int_urb); | 277 | usb_free_urb(priv->int_urb); |
278 | } | ||
279 | |||
280 | static void symbol_release(struct usb_serial *serial) | ||
281 | { | ||
282 | struct symbol_private *priv = usb_get_serial_data(serial); | ||
283 | |||
284 | dbg("%s", __func__); | ||
285 | |||
279 | kfree(priv->int_buffer); | 286 | kfree(priv->int_buffer); |
280 | kfree(priv); | 287 | kfree(priv); |
281 | usb_set_serial_data(serial, NULL); | ||
282 | } | 288 | } |
283 | 289 | ||
284 | static struct usb_driver symbol_driver = { | 290 | static struct usb_driver symbol_driver = { |
@@ -300,7 +306,8 @@ static struct usb_serial_driver symbol_device = { | |||
300 | .attach = symbol_startup, | 306 | .attach = symbol_startup, |
301 | .open = symbol_open, | 307 | .open = symbol_open, |
302 | .close = symbol_close, | 308 | .close = symbol_close, |
303 | .shutdown = symbol_shutdown, | 309 | .disconnect = symbol_disconnect, |
310 | .release = symbol_release, | ||
304 | .throttle = symbol_throttle, | 311 | .throttle = symbol_throttle, |
305 | .unthrottle = symbol_unthrottle, | 312 | .unthrottle = symbol_unthrottle, |
306 | }; | 313 | }; |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 0a64bac306ee..991d8232e376 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -97,11 +97,10 @@ struct ti_device { | |||
97 | /* Function Declarations */ | 97 | /* Function Declarations */ |
98 | 98 | ||
99 | static int ti_startup(struct usb_serial *serial); | 99 | static int ti_startup(struct usb_serial *serial); |
100 | static void ti_shutdown(struct usb_serial *serial); | 100 | static void ti_release(struct usb_serial *serial); |
101 | static int ti_open(struct tty_struct *tty, struct usb_serial_port *port, | 101 | static int ti_open(struct tty_struct *tty, struct usb_serial_port *port, |
102 | struct file *file); | 102 | struct file *file); |
103 | static void ti_close(struct tty_struct *tty, struct usb_serial_port *port, | 103 | static void ti_close(struct usb_serial_port *port); |
104 | struct file *file); | ||
105 | static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, | 104 | static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, |
106 | const unsigned char *data, int count); | 105 | const unsigned char *data, int count); |
107 | static int ti_write_room(struct tty_struct *tty); | 106 | static int ti_write_room(struct tty_struct *tty); |
@@ -231,7 +230,7 @@ static struct usb_serial_driver ti_1port_device = { | |||
231 | .id_table = ti_id_table_3410, | 230 | .id_table = ti_id_table_3410, |
232 | .num_ports = 1, | 231 | .num_ports = 1, |
233 | .attach = ti_startup, | 232 | .attach = ti_startup, |
234 | .shutdown = ti_shutdown, | 233 | .release = ti_release, |
235 | .open = ti_open, | 234 | .open = ti_open, |
236 | .close = ti_close, | 235 | .close = ti_close, |
237 | .write = ti_write, | 236 | .write = ti_write, |
@@ -259,7 +258,7 @@ static struct usb_serial_driver ti_2port_device = { | |||
259 | .id_table = ti_id_table_5052, | 258 | .id_table = ti_id_table_5052, |
260 | .num_ports = 2, | 259 | .num_ports = 2, |
261 | .attach = ti_startup, | 260 | .attach = ti_startup, |
262 | .shutdown = ti_shutdown, | 261 | .release = ti_release, |
263 | .open = ti_open, | 262 | .open = ti_open, |
264 | .close = ti_close, | 263 | .close = ti_close, |
265 | .write = ti_write, | 264 | .write = ti_write, |
@@ -474,7 +473,7 @@ free_tdev: | |||
474 | } | 473 | } |
475 | 474 | ||
476 | 475 | ||
477 | static void ti_shutdown(struct usb_serial *serial) | 476 | static void ti_release(struct usb_serial *serial) |
478 | { | 477 | { |
479 | int i; | 478 | int i; |
480 | struct ti_device *tdev = usb_get_serial_data(serial); | 479 | struct ti_device *tdev = usb_get_serial_data(serial); |
@@ -487,12 +486,10 @@ static void ti_shutdown(struct usb_serial *serial) | |||
487 | if (tport) { | 486 | if (tport) { |
488 | ti_buf_free(tport->tp_write_buf); | 487 | ti_buf_free(tport->tp_write_buf); |
489 | kfree(tport); | 488 | kfree(tport); |
490 | usb_set_serial_port_data(serial->port[i], NULL); | ||
491 | } | 489 | } |
492 | } | 490 | } |
493 | 491 | ||
494 | kfree(tdev); | 492 | kfree(tdev); |
495 | usb_set_serial_data(serial, NULL); | ||
496 | } | 493 | } |
497 | 494 | ||
498 | 495 | ||
@@ -647,8 +644,7 @@ release_lock: | |||
647 | } | 644 | } |
648 | 645 | ||
649 | 646 | ||
650 | static void ti_close(struct tty_struct *tty, struct usb_serial_port *port, | 647 | static void ti_close(struct usb_serial_port *port) |
651 | struct file *file) | ||
652 | { | 648 | { |
653 | struct ti_device *tdev; | 649 | struct ti_device *tdev; |
654 | struct ti_port *tport; | 650 | struct ti_port *tport; |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index f331e2bde88a..d595aa5586a7 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -141,6 +141,14 @@ static void destroy_serial(struct kref *kref) | |||
141 | if (serial->minor != SERIAL_TTY_NO_MINOR) | 141 | if (serial->minor != SERIAL_TTY_NO_MINOR) |
142 | return_serial(serial); | 142 | return_serial(serial); |
143 | 143 | ||
144 | serial->type->release(serial); | ||
145 | |||
146 | for (i = 0; i < serial->num_ports; ++i) { | ||
147 | port = serial->port[i]; | ||
148 | if (port) | ||
149 | put_device(&port->dev); | ||
150 | } | ||
151 | |||
144 | /* If this is a "fake" port, we have to clean it up here, as it will | 152 | /* If this is a "fake" port, we have to clean it up here, as it will |
145 | * not get cleaned up in port_release() as it was never registered with | 153 | * not get cleaned up in port_release() as it was never registered with |
146 | * the driver core */ | 154 | * the driver core */ |
@@ -148,9 +156,8 @@ static void destroy_serial(struct kref *kref) | |||
148 | for (i = serial->num_ports; | 156 | for (i = serial->num_ports; |
149 | i < serial->num_port_pointers; ++i) { | 157 | i < serial->num_port_pointers; ++i) { |
150 | port = serial->port[i]; | 158 | port = serial->port[i]; |
151 | if (!port) | 159 | if (port) |
152 | continue; | 160 | port_free(port); |
153 | port_free(port); | ||
154 | } | 161 | } |
155 | } | 162 | } |
156 | 163 | ||
@@ -238,9 +245,11 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
238 | goto bailout_interface_put; | 245 | goto bailout_interface_put; |
239 | mutex_unlock(&serial->disc_mutex); | 246 | mutex_unlock(&serial->disc_mutex); |
240 | } | 247 | } |
241 | |||
242 | mutex_unlock(&port->mutex); | 248 | mutex_unlock(&port->mutex); |
243 | return 0; | 249 | /* Now do the correct tty layer semantics */ |
250 | retval = tty_port_block_til_ready(&port->port, tty, filp); | ||
251 | if (retval == 0) | ||
252 | return 0; | ||
244 | 253 | ||
245 | bailout_interface_put: | 254 | bailout_interface_put: |
246 | usb_autopm_put_interface(serial->interface); | 255 | usb_autopm_put_interface(serial->interface); |
@@ -259,64 +268,89 @@ bailout_serial_put: | |||
259 | return retval; | 268 | return retval; |
260 | } | 269 | } |
261 | 270 | ||
262 | static void serial_close(struct tty_struct *tty, struct file *filp) | 271 | /** |
272 | * serial_do_down - shut down hardware | ||
273 | * @port: port to shut down | ||
274 | * | ||
275 | * Shut down a USB port unless it is the console. We never shut down the | ||
276 | * console hardware as it will always be in use. | ||
277 | * | ||
278 | * Don't free any resources at this point | ||
279 | */ | ||
280 | static void serial_do_down(struct usb_serial_port *port) | ||
263 | { | 281 | { |
264 | struct usb_serial_port *port = tty->driver_data; | 282 | struct usb_serial_driver *drv = port->serial->type; |
265 | struct usb_serial *serial; | 283 | struct usb_serial *serial; |
266 | struct module *owner; | 284 | struct module *owner; |
267 | int count; | ||
268 | 285 | ||
269 | if (!port) | 286 | /* The console is magical, do not hang up the console hardware |
287 | or there will be tears */ | ||
288 | if (port->console) | ||
270 | return; | 289 | return; |
271 | 290 | ||
272 | dbg("%s - port %d", __func__, port->number); | ||
273 | |||
274 | mutex_lock(&port->mutex); | 291 | mutex_lock(&port->mutex); |
275 | serial = port->serial; | 292 | serial = port->serial; |
276 | owner = serial->type->driver.owner; | 293 | owner = serial->type->driver.owner; |
277 | 294 | ||
278 | if (port->port.count == 0) { | 295 | if (drv->close) |
279 | mutex_unlock(&port->mutex); | 296 | drv->close(port); |
280 | return; | ||
281 | } | ||
282 | 297 | ||
283 | if (port->port.count == 1) | ||
284 | /* only call the device specific close if this | ||
285 | * port is being closed by the last owner. Ensure we do | ||
286 | * this before we drop the port count. The call is protected | ||
287 | * by the port mutex | ||
288 | */ | ||
289 | serial->type->close(tty, port, filp); | ||
290 | |||
291 | if (port->port.count == (port->console ? 2 : 1)) { | ||
292 | struct tty_struct *tty = tty_port_tty_get(&port->port); | ||
293 | if (tty) { | ||
294 | /* We must do this before we drop the port count to | ||
295 | zero. */ | ||
296 | if (tty->driver_data) | ||
297 | tty->driver_data = NULL; | ||
298 | tty_port_tty_set(&port->port, NULL); | ||
299 | tty_kref_put(tty); | ||
300 | } | ||
301 | } | ||
302 | |||
303 | --port->port.count; | ||
304 | count = port->port.count; | ||
305 | mutex_unlock(&port->mutex); | 298 | mutex_unlock(&port->mutex); |
306 | put_device(&port->dev); | 299 | } |
300 | |||
301 | /** | ||
302 | * serial_do_free - free resources post close/hangup | ||
303 | * @port: port to free up | ||
304 | * | ||
305 | * Do the resource freeing and refcount dropping for the port. We must | ||
306 | * be careful about ordering and we must avoid freeing up the console. | ||
307 | */ | ||
308 | |||
309 | static void serial_do_free(struct usb_serial_port *port) | ||
310 | { | ||
311 | struct usb_serial *serial; | ||
312 | struct module *owner; | ||
313 | |||
314 | /* The console is magical, do not hang up the console hardware | ||
315 | or there will be tears */ | ||
316 | if (port->console) | ||
317 | return; | ||
307 | 318 | ||
319 | serial = port->serial; | ||
320 | owner = serial->type->driver.owner; | ||
321 | put_device(&port->dev); | ||
308 | /* Mustn't dereference port any more */ | 322 | /* Mustn't dereference port any more */ |
309 | if (count == 0) { | 323 | mutex_lock(&serial->disc_mutex); |
310 | mutex_lock(&serial->disc_mutex); | 324 | if (!serial->disconnected) |
311 | if (!serial->disconnected) | 325 | usb_autopm_put_interface(serial->interface); |
312 | usb_autopm_put_interface(serial->interface); | 326 | mutex_unlock(&serial->disc_mutex); |
313 | mutex_unlock(&serial->disc_mutex); | ||
314 | } | ||
315 | usb_serial_put(serial); | 327 | usb_serial_put(serial); |
316 | |||
317 | /* Mustn't dereference serial any more */ | 328 | /* Mustn't dereference serial any more */ |
318 | if (count == 0) | 329 | module_put(owner); |
319 | module_put(owner); | 330 | } |
331 | |||
332 | static void serial_close(struct tty_struct *tty, struct file *filp) | ||
333 | { | ||
334 | struct usb_serial_port *port = tty->driver_data; | ||
335 | |||
336 | dbg("%s - port %d", __func__, port->number); | ||
337 | |||
338 | |||
339 | if (tty_port_close_start(&port->port, tty, filp) == 0) | ||
340 | return; | ||
341 | |||
342 | serial_do_down(port); | ||
343 | tty_port_close_end(&port->port, tty); | ||
344 | tty_port_tty_set(&port->port, NULL); | ||
345 | serial_do_free(port); | ||
346 | } | ||
347 | |||
348 | static void serial_hangup(struct tty_struct *tty) | ||
349 | { | ||
350 | struct usb_serial_port *port = tty->driver_data; | ||
351 | serial_do_down(port); | ||
352 | tty_port_hangup(&port->port); | ||
353 | serial_do_free(port); | ||
320 | } | 354 | } |
321 | 355 | ||
322 | static int serial_write(struct tty_struct *tty, const unsigned char *buf, | 356 | static int serial_write(struct tty_struct *tty, const unsigned char *buf, |
@@ -648,6 +682,29 @@ static struct usb_serial_driver *search_serial_device( | |||
648 | return NULL; | 682 | return NULL; |
649 | } | 683 | } |
650 | 684 | ||
685 | static int serial_carrier_raised(struct tty_port *port) | ||
686 | { | ||
687 | struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); | ||
688 | struct usb_serial_driver *drv = p->serial->type; | ||
689 | if (drv->carrier_raised) | ||
690 | return drv->carrier_raised(p); | ||
691 | /* No carrier control - don't block */ | ||
692 | return 1; | ||
693 | } | ||
694 | |||
695 | static void serial_dtr_rts(struct tty_port *port, int on) | ||
696 | { | ||
697 | struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); | ||
698 | struct usb_serial_driver *drv = p->serial->type; | ||
699 | if (drv->dtr_rts) | ||
700 | drv->dtr_rts(p, on); | ||
701 | } | ||
702 | |||
703 | static const struct tty_port_operations serial_port_ops = { | ||
704 | .carrier_raised = serial_carrier_raised, | ||
705 | .dtr_rts = serial_dtr_rts, | ||
706 | }; | ||
707 | |||
651 | int usb_serial_probe(struct usb_interface *interface, | 708 | int usb_serial_probe(struct usb_interface *interface, |
652 | const struct usb_device_id *id) | 709 | const struct usb_device_id *id) |
653 | { | 710 | { |
@@ -841,6 +898,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
841 | if (!port) | 898 | if (!port) |
842 | goto probe_error; | 899 | goto probe_error; |
843 | tty_port_init(&port->port); | 900 | tty_port_init(&port->port); |
901 | port->port.ops = &serial_port_ops; | ||
844 | port->serial = serial; | 902 | port->serial = serial; |
845 | spin_lock_init(&port->lock); | 903 | spin_lock_init(&port->lock); |
846 | mutex_init(&port->mutex); | 904 | mutex_init(&port->mutex); |
@@ -995,10 +1053,15 @@ int usb_serial_probe(struct usb_interface *interface, | |||
995 | 1053 | ||
996 | dev_set_name(&port->dev, "ttyUSB%d", port->number); | 1054 | dev_set_name(&port->dev, "ttyUSB%d", port->number); |
997 | dbg ("%s - registering %s", __func__, dev_name(&port->dev)); | 1055 | dbg ("%s - registering %s", __func__, dev_name(&port->dev)); |
1056 | port->dev_state = PORT_REGISTERING; | ||
998 | retval = device_register(&port->dev); | 1057 | retval = device_register(&port->dev); |
999 | if (retval) | 1058 | if (retval) { |
1000 | dev_err(&port->dev, "Error registering port device, " | 1059 | dev_err(&port->dev, "Error registering port device, " |
1001 | "continuing\n"); | 1060 | "continuing\n"); |
1061 | port->dev_state = PORT_UNREGISTERED; | ||
1062 | } else { | ||
1063 | port->dev_state = PORT_REGISTERED; | ||
1064 | } | ||
1002 | } | 1065 | } |
1003 | 1066 | ||
1004 | usb_serial_console_init(debug, minor); | 1067 | usb_serial_console_init(debug, minor); |
@@ -1062,31 +1125,38 @@ void usb_serial_disconnect(struct usb_interface *interface) | |||
1062 | serial->disconnected = 1; | 1125 | serial->disconnected = 1; |
1063 | mutex_unlock(&serial->disc_mutex); | 1126 | mutex_unlock(&serial->disc_mutex); |
1064 | 1127 | ||
1065 | /* Unfortunately, many of the sub-drivers expect the port structures | ||
1066 | * to exist when their shutdown method is called, so we have to go | ||
1067 | * through this awkward two-step unregistration procedure. | ||
1068 | */ | ||
1069 | for (i = 0; i < serial->num_ports; ++i) { | 1128 | for (i = 0; i < serial->num_ports; ++i) { |
1070 | port = serial->port[i]; | 1129 | port = serial->port[i]; |
1071 | if (port) { | 1130 | if (port) { |
1072 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 1131 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
1073 | if (tty) { | 1132 | if (tty) { |
1133 | /* The hangup will occur asynchronously but | ||
1134 | the object refcounts will sort out all the | ||
1135 | cleanup */ | ||
1074 | tty_hangup(tty); | 1136 | tty_hangup(tty); |
1075 | tty_kref_put(tty); | 1137 | tty_kref_put(tty); |
1076 | } | 1138 | } |
1077 | kill_traffic(port); | 1139 | kill_traffic(port); |
1078 | cancel_work_sync(&port->work); | 1140 | cancel_work_sync(&port->work); |
1079 | device_del(&port->dev); | 1141 | if (port->dev_state == PORT_REGISTERED) { |
1080 | } | 1142 | |
1081 | } | 1143 | /* Make sure the port is bound so that the |
1082 | serial->type->shutdown(serial); | 1144 | * driver's port_remove method is called. |
1083 | for (i = 0; i < serial->num_ports; ++i) { | 1145 | */ |
1084 | port = serial->port[i]; | 1146 | if (!port->dev.driver) { |
1085 | if (port) { | 1147 | int rc; |
1086 | put_device(&port->dev); | 1148 | |
1087 | serial->port[i] = NULL; | 1149 | port->dev.driver = |
1150 | &serial->type->driver; | ||
1151 | rc = device_bind_driver(&port->dev); | ||
1152 | } | ||
1153 | port->dev_state = PORT_UNREGISTERING; | ||
1154 | device_del(&port->dev); | ||
1155 | port->dev_state = PORT_UNREGISTERED; | ||
1156 | } | ||
1088 | } | 1157 | } |
1089 | } | 1158 | } |
1159 | serial->type->disconnect(serial); | ||
1090 | 1160 | ||
1091 | /* let the last holder of this object | 1161 | /* let the last holder of this object |
1092 | * cause it to be cleaned up */ | 1162 | * cause it to be cleaned up */ |
@@ -1135,6 +1205,7 @@ static const struct tty_operations serial_ops = { | |||
1135 | .open = serial_open, | 1205 | .open = serial_open, |
1136 | .close = serial_close, | 1206 | .close = serial_close, |
1137 | .write = serial_write, | 1207 | .write = serial_write, |
1208 | .hangup = serial_hangup, | ||
1138 | .write_room = serial_write_room, | 1209 | .write_room = serial_write_room, |
1139 | .ioctl = serial_ioctl, | 1210 | .ioctl = serial_ioctl, |
1140 | .set_termios = serial_set_termios, | 1211 | .set_termios = serial_set_termios, |
@@ -1147,6 +1218,7 @@ static const struct tty_operations serial_ops = { | |||
1147 | .proc_fops = &serial_proc_fops, | 1218 | .proc_fops = &serial_proc_fops, |
1148 | }; | 1219 | }; |
1149 | 1220 | ||
1221 | |||
1150 | struct tty_driver *usb_serial_tty_driver; | 1222 | struct tty_driver *usb_serial_tty_driver; |
1151 | 1223 | ||
1152 | static int __init usb_serial_init(void) | 1224 | static int __init usb_serial_init(void) |
@@ -1262,7 +1334,8 @@ static void fixup_generic(struct usb_serial_driver *device) | |||
1262 | set_to_generic_if_null(device, chars_in_buffer); | 1334 | set_to_generic_if_null(device, chars_in_buffer); |
1263 | set_to_generic_if_null(device, read_bulk_callback); | 1335 | set_to_generic_if_null(device, read_bulk_callback); |
1264 | set_to_generic_if_null(device, write_bulk_callback); | 1336 | set_to_generic_if_null(device, write_bulk_callback); |
1265 | set_to_generic_if_null(device, shutdown); | 1337 | set_to_generic_if_null(device, disconnect); |
1338 | set_to_generic_if_null(device, release); | ||
1266 | } | 1339 | } |
1267 | 1340 | ||
1268 | int usb_serial_register(struct usb_serial_driver *driver) | 1341 | int usb_serial_register(struct usb_serial_driver *driver) |
diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c index 6c9cbb59552a..614800972dc3 100644 --- a/drivers/usb/serial/usb_debug.c +++ b/drivers/usb/serial/usb_debug.c | |||
@@ -15,7 +15,19 @@ | |||
15 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
16 | #include <linux/usb/serial.h> | 16 | #include <linux/usb/serial.h> |
17 | 17 | ||
18 | #define URB_DEBUG_MAX_IN_FLIGHT_URBS 4000 | ||
18 | #define USB_DEBUG_MAX_PACKET_SIZE 8 | 19 | #define USB_DEBUG_MAX_PACKET_SIZE 8 |
20 | #define USB_DEBUG_BRK_SIZE 8 | ||
21 | static char USB_DEBUG_BRK[USB_DEBUG_BRK_SIZE] = { | ||
22 | 0x00, | ||
23 | 0xff, | ||
24 | 0x01, | ||
25 | 0xfe, | ||
26 | 0x00, | ||
27 | 0xfe, | ||
28 | 0x01, | ||
29 | 0xff, | ||
30 | }; | ||
19 | 31 | ||
20 | static struct usb_device_id id_table [] = { | 32 | static struct usb_device_id id_table [] = { |
21 | { USB_DEVICE(0x0525, 0x127a) }, | 33 | { USB_DEVICE(0x0525, 0x127a) }, |
@@ -38,6 +50,32 @@ static int usb_debug_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
38 | return usb_serial_generic_open(tty, port, filp); | 50 | return usb_serial_generic_open(tty, port, filp); |
39 | } | 51 | } |
40 | 52 | ||
53 | /* This HW really does not support a serial break, so one will be | ||
54 | * emulated when ever the break state is set to true. | ||
55 | */ | ||
56 | static void usb_debug_break_ctl(struct tty_struct *tty, int break_state) | ||
57 | { | ||
58 | struct usb_serial_port *port = tty->driver_data; | ||
59 | if (!break_state) | ||
60 | return; | ||
61 | usb_serial_generic_write(tty, port, USB_DEBUG_BRK, USB_DEBUG_BRK_SIZE); | ||
62 | } | ||
63 | |||
64 | static void usb_debug_read_bulk_callback(struct urb *urb) | ||
65 | { | ||
66 | struct usb_serial_port *port = urb->context; | ||
67 | |||
68 | if (urb->actual_length == USB_DEBUG_BRK_SIZE && | ||
69 | memcmp(urb->transfer_buffer, USB_DEBUG_BRK, | ||
70 | USB_DEBUG_BRK_SIZE) == 0) { | ||
71 | usb_serial_handle_break(port); | ||
72 | usb_serial_generic_resubmit_read_urb(port, GFP_ATOMIC); | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | usb_serial_generic_read_bulk_callback(urb); | ||
77 | } | ||
78 | |||
41 | static struct usb_serial_driver debug_device = { | 79 | static struct usb_serial_driver debug_device = { |
42 | .driver = { | 80 | .driver = { |
43 | .owner = THIS_MODULE, | 81 | .owner = THIS_MODULE, |
@@ -46,6 +84,9 @@ static struct usb_serial_driver debug_device = { | |||
46 | .id_table = id_table, | 84 | .id_table = id_table, |
47 | .num_ports = 1, | 85 | .num_ports = 1, |
48 | .open = usb_debug_open, | 86 | .open = usb_debug_open, |
87 | .max_in_flight_urbs = URB_DEBUG_MAX_IN_FLIGHT_URBS, | ||
88 | .break_ctl = usb_debug_break_ctl, | ||
89 | .read_bulk_callback = usb_debug_read_bulk_callback, | ||
49 | }; | 90 | }; |
50 | 91 | ||
51 | static int __init debug_init(void) | 92 | static int __init debug_init(void) |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 5ac414bda718..f5d0f64dcc52 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -38,8 +38,7 @@ | |||
38 | /* function prototypes for a handspring visor */ | 38 | /* function prototypes for a handspring visor */ |
39 | static int visor_open(struct tty_struct *tty, struct usb_serial_port *port, | 39 | static int visor_open(struct tty_struct *tty, struct usb_serial_port *port, |
40 | struct file *filp); | 40 | struct file *filp); |
41 | static void visor_close(struct tty_struct *tty, struct usb_serial_port *port, | 41 | static void visor_close(struct usb_serial_port *port); |
42 | struct file *filp); | ||
43 | static int visor_write(struct tty_struct *tty, struct usb_serial_port *port, | 42 | static int visor_write(struct tty_struct *tty, struct usb_serial_port *port, |
44 | const unsigned char *buf, int count); | 43 | const unsigned char *buf, int count); |
45 | static int visor_write_room(struct tty_struct *tty); | 44 | static int visor_write_room(struct tty_struct *tty); |
@@ -48,7 +47,7 @@ static void visor_unthrottle(struct tty_struct *tty); | |||
48 | static int visor_probe(struct usb_serial *serial, | 47 | static int visor_probe(struct usb_serial *serial, |
49 | const struct usb_device_id *id); | 48 | const struct usb_device_id *id); |
50 | static int visor_calc_num_ports(struct usb_serial *serial); | 49 | static int visor_calc_num_ports(struct usb_serial *serial); |
51 | static void visor_shutdown(struct usb_serial *serial); | 50 | static void visor_release(struct usb_serial *serial); |
52 | static void visor_write_bulk_callback(struct urb *urb); | 51 | static void visor_write_bulk_callback(struct urb *urb); |
53 | static void visor_read_bulk_callback(struct urb *urb); | 52 | static void visor_read_bulk_callback(struct urb *urb); |
54 | static void visor_read_int_callback(struct urb *urb); | 53 | static void visor_read_int_callback(struct urb *urb); |
@@ -203,7 +202,7 @@ static struct usb_serial_driver handspring_device = { | |||
203 | .attach = treo_attach, | 202 | .attach = treo_attach, |
204 | .probe = visor_probe, | 203 | .probe = visor_probe, |
205 | .calc_num_ports = visor_calc_num_ports, | 204 | .calc_num_ports = visor_calc_num_ports, |
206 | .shutdown = visor_shutdown, | 205 | .release = visor_release, |
207 | .write = visor_write, | 206 | .write = visor_write, |
208 | .write_room = visor_write_room, | 207 | .write_room = visor_write_room, |
209 | .write_bulk_callback = visor_write_bulk_callback, | 208 | .write_bulk_callback = visor_write_bulk_callback, |
@@ -228,7 +227,7 @@ static struct usb_serial_driver clie_5_device = { | |||
228 | .attach = clie_5_attach, | 227 | .attach = clie_5_attach, |
229 | .probe = visor_probe, | 228 | .probe = visor_probe, |
230 | .calc_num_ports = visor_calc_num_ports, | 229 | .calc_num_ports = visor_calc_num_ports, |
231 | .shutdown = visor_shutdown, | 230 | .release = visor_release, |
232 | .write = visor_write, | 231 | .write = visor_write, |
233 | .write_room = visor_write_room, | 232 | .write_room = visor_write_room, |
234 | .write_bulk_callback = visor_write_bulk_callback, | 233 | .write_bulk_callback = visor_write_bulk_callback, |
@@ -324,8 +323,7 @@ exit: | |||
324 | } | 323 | } |
325 | 324 | ||
326 | 325 | ||
327 | static void visor_close(struct tty_struct *tty, | 326 | static void visor_close(struct usb_serial_port *port) |
328 | struct usb_serial_port *port, struct file *filp) | ||
329 | { | 327 | { |
330 | struct visor_private *priv = usb_get_serial_port_data(port); | 328 | struct visor_private *priv = usb_get_serial_port_data(port); |
331 | unsigned char *transfer_buffer; | 329 | unsigned char *transfer_buffer; |
@@ -920,7 +918,7 @@ static int clie_5_attach(struct usb_serial *serial) | |||
920 | return generic_startup(serial); | 918 | return generic_startup(serial); |
921 | } | 919 | } |
922 | 920 | ||
923 | static void visor_shutdown(struct usb_serial *serial) | 921 | static void visor_release(struct usb_serial *serial) |
924 | { | 922 | { |
925 | struct visor_private *priv; | 923 | struct visor_private *priv; |
926 | int i; | 924 | int i; |
@@ -929,10 +927,7 @@ static void visor_shutdown(struct usb_serial *serial) | |||
929 | 927 | ||
930 | for (i = 0; i < serial->num_ports; i++) { | 928 | for (i = 0; i < serial->num_ports; i++) { |
931 | priv = usb_get_serial_port_data(serial->port[i]); | 929 | priv = usb_get_serial_port_data(serial->port[i]); |
932 | if (priv) { | 930 | kfree(priv); |
933 | usb_set_serial_port_data(serial->port[i], NULL); | ||
934 | kfree(priv); | ||
935 | } | ||
936 | } | 931 | } |
937 | } | 932 | } |
938 | 933 | ||
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 5335d3211c07..8d126dd7a02e 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -144,11 +144,10 @@ static int whiteheat_firmware_attach(struct usb_serial *serial); | |||
144 | 144 | ||
145 | /* function prototypes for the Connect Tech WhiteHEAT serial converter */ | 145 | /* function prototypes for the Connect Tech WhiteHEAT serial converter */ |
146 | static int whiteheat_attach(struct usb_serial *serial); | 146 | static int whiteheat_attach(struct usb_serial *serial); |
147 | static void whiteheat_shutdown(struct usb_serial *serial); | 147 | static void whiteheat_release(struct usb_serial *serial); |
148 | static int whiteheat_open(struct tty_struct *tty, | 148 | static int whiteheat_open(struct tty_struct *tty, |
149 | struct usb_serial_port *port, struct file *filp); | 149 | struct usb_serial_port *port, struct file *filp); |
150 | static void whiteheat_close(struct tty_struct *tty, | 150 | static void whiteheat_close(struct usb_serial_port *port); |
151 | struct usb_serial_port *port, struct file *filp); | ||
152 | static int whiteheat_write(struct tty_struct *tty, | 151 | static int whiteheat_write(struct tty_struct *tty, |
153 | struct usb_serial_port *port, | 152 | struct usb_serial_port *port, |
154 | const unsigned char *buf, int count); | 153 | const unsigned char *buf, int count); |
@@ -190,7 +189,7 @@ static struct usb_serial_driver whiteheat_device = { | |||
190 | .id_table = id_table_std, | 189 | .id_table = id_table_std, |
191 | .num_ports = 4, | 190 | .num_ports = 4, |
192 | .attach = whiteheat_attach, | 191 | .attach = whiteheat_attach, |
193 | .shutdown = whiteheat_shutdown, | 192 | .release = whiteheat_release, |
194 | .open = whiteheat_open, | 193 | .open = whiteheat_open, |
195 | .close = whiteheat_close, | 194 | .close = whiteheat_close, |
196 | .write = whiteheat_write, | 195 | .write = whiteheat_write, |
@@ -618,7 +617,7 @@ no_command_buffer: | |||
618 | } | 617 | } |
619 | 618 | ||
620 | 619 | ||
621 | static void whiteheat_shutdown(struct usb_serial *serial) | 620 | static void whiteheat_release(struct usb_serial *serial) |
622 | { | 621 | { |
623 | struct usb_serial_port *command_port; | 622 | struct usb_serial_port *command_port; |
624 | struct usb_serial_port *port; | 623 | struct usb_serial_port *port; |
@@ -712,8 +711,7 @@ exit: | |||
712 | } | 711 | } |
713 | 712 | ||
714 | 713 | ||
715 | static void whiteheat_close(struct tty_struct *tty, | 714 | static void whiteheat_close(struct usb_serial_port *port) |
716 | struct usb_serial_port *port, struct file *filp) | ||
717 | { | 715 | { |
718 | struct whiteheat_private *info = usb_get_serial_port_data(port); | 716 | struct whiteheat_private *info = usb_get_serial_port_data(port); |
719 | struct whiteheat_urb_wrap *wrap; | 717 | struct whiteheat_urb_wrap *wrap; |
@@ -723,31 +721,7 @@ static void whiteheat_close(struct tty_struct *tty, | |||
723 | 721 | ||
724 | dbg("%s - port %d", __func__, port->number); | 722 | dbg("%s - port %d", __func__, port->number); |
725 | 723 | ||
726 | mutex_lock(&port->serial->disc_mutex); | ||
727 | /* filp is NULL when called from usb_serial_disconnect */ | ||
728 | if ((filp && (tty_hung_up_p(filp))) || port->serial->disconnected) { | ||
729 | mutex_unlock(&port->serial->disc_mutex); | ||
730 | return; | ||
731 | } | ||
732 | mutex_unlock(&port->serial->disc_mutex); | ||
733 | |||
734 | tty->closing = 1; | ||
735 | |||
736 | /* | ||
737 | * Not currently in use; tty_wait_until_sent() calls | ||
738 | * serial_chars_in_buffer() which deadlocks on the second semaphore | ||
739 | * acquisition. This should be fixed at some point. Greg's been | ||
740 | * notified. | ||
741 | if ((filp->f_flags & (O_NDELAY | O_NONBLOCK)) == 0) { | ||
742 | tty_wait_until_sent(tty, CLOSING_DELAY); | ||
743 | } | ||
744 | */ | ||
745 | |||
746 | tty_driver_flush_buffer(tty); | ||
747 | tty_ldisc_flush(tty); | ||
748 | |||
749 | firm_report_tx_done(port); | 724 | firm_report_tx_done(port); |
750 | |||
751 | firm_close(port); | 725 | firm_close(port); |
752 | 726 | ||
753 | /* shutdown our bulk reads and writes */ | 727 | /* shutdown our bulk reads and writes */ |
@@ -775,10 +749,7 @@ static void whiteheat_close(struct tty_struct *tty, | |||
775 | } | 749 | } |
776 | spin_unlock_irq(&info->lock); | 750 | spin_unlock_irq(&info->lock); |
777 | mutex_unlock(&info->deathwarrant); | 751 | mutex_unlock(&info->deathwarrant); |
778 | |||
779 | stop_command_port(port->serial); | 752 | stop_command_port(port->serial); |
780 | |||
781 | tty->closing = 0; | ||
782 | } | 753 | } |
783 | 754 | ||
784 | 755 | ||