diff options
Diffstat (limited to 'drivers/usb/serial/sierra.c')
-rw-r--r-- | drivers/usb/serial/sierra.c | 97 |
1 files changed, 43 insertions, 54 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 913225c61610..1319b8968d82 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -240,57 +240,39 @@ struct sierra_port_private { | |||
240 | int ri_state; | 240 | int ri_state; |
241 | }; | 241 | }; |
242 | 242 | ||
243 | static int sierra_send_setup(struct tty_struct *tty, | 243 | static int sierra_send_setup(struct usb_serial_port *port) |
244 | struct usb_serial_port *port) | ||
245 | { | 244 | { |
246 | struct usb_serial *serial = port->serial; | 245 | struct usb_serial *serial = port->serial; |
247 | struct sierra_port_private *portdata; | 246 | struct sierra_port_private *portdata; |
248 | __u16 interface = 0; | 247 | __u16 interface = 0; |
248 | int val = 0; | ||
249 | 249 | ||
250 | dev_dbg(&port->dev, "%s", __func__); | 250 | dev_dbg(&port->dev, "%s", __func__); |
251 | 251 | ||
252 | portdata = usb_get_serial_port_data(port); | 252 | portdata = usb_get_serial_port_data(port); |
253 | 253 | ||
254 | if (tty) { | 254 | if (portdata->dtr_state) |
255 | int val = 0; | 255 | val |= 0x01; |
256 | if (portdata->dtr_state) | 256 | if (portdata->rts_state) |
257 | val |= 0x01; | 257 | val |= 0x02; |
258 | if (portdata->rts_state) | 258 | |
259 | val |= 0x02; | 259 | /* If composite device then properly report interface */ |
260 | 260 | if (serial->num_ports == 1) | |
261 | /* If composite device then properly report interface */ | 261 | interface = sierra_calc_interface(serial); |
262 | if (serial->num_ports == 1) { | 262 | |
263 | interface = sierra_calc_interface(serial); | 263 | /* Otherwise the need to do non-composite mapping */ |
264 | 264 | else { | |
265 | /* Control message is sent only to interfaces with | 265 | if (port->bulk_out_endpointAddress == 2) |
266 | * interrupt_in endpoints | 266 | interface = 0; |
267 | */ | 267 | else if (port->bulk_out_endpointAddress == 4) |
268 | if (port->interrupt_in_urb) { | 268 | interface = 1; |
269 | /* send control message */ | 269 | else if (port->bulk_out_endpointAddress == 5) |
270 | return usb_control_msg(serial->dev, | 270 | interface = 2; |
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 | |||
286 | return usb_control_msg(serial->dev, | ||
287 | usb_rcvctrlpipe(serial->dev, 0), | ||
288 | 0x22, 0x21, val, interface, | ||
289 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
290 | |||
291 | } | ||
292 | } | 271 | } |
293 | 272 | return usb_control_msg(serial->dev, | |
273 | usb_rcvctrlpipe(serial->dev, 0), | ||
274 | 0x22, 0x21, val, interface, | ||
275 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
294 | return 0; | 276 | return 0; |
295 | } | 277 | } |
296 | 278 | ||
@@ -299,7 +281,7 @@ static void sierra_set_termios(struct tty_struct *tty, | |||
299 | { | 281 | { |
300 | dev_dbg(&port->dev, "%s", __func__); | 282 | dev_dbg(&port->dev, "%s", __func__); |
301 | tty_termios_copy_hw(tty->termios, old_termios); | 283 | tty_termios_copy_hw(tty->termios, old_termios); |
302 | sierra_send_setup(tty, port); | 284 | sierra_send_setup(port); |
303 | } | 285 | } |
304 | 286 | ||
305 | static int sierra_tiocmget(struct tty_struct *tty, struct file *file) | 287 | static int sierra_tiocmget(struct tty_struct *tty, struct file *file) |
@@ -338,7 +320,7 @@ static int sierra_tiocmset(struct tty_struct *tty, struct file *file, | |||
338 | portdata->rts_state = 0; | 320 | portdata->rts_state = 0; |
339 | if (clear & TIOCM_DTR) | 321 | if (clear & TIOCM_DTR) |
340 | portdata->dtr_state = 0; | 322 | portdata->dtr_state = 0; |
341 | return sierra_send_setup(tty, port); | 323 | return sierra_send_setup(port); |
342 | } | 324 | } |
343 | 325 | ||
344 | static void sierra_outdat_callback(struct urb *urb) | 326 | static void sierra_outdat_callback(struct urb *urb) |
@@ -598,7 +580,7 @@ static int sierra_open(struct tty_struct *tty, | |||
598 | } | 580 | } |
599 | } | 581 | } |
600 | 582 | ||
601 | sierra_send_setup(tty, port); | 583 | sierra_send_setup(port); |
602 | 584 | ||
603 | /* start up the interrupt endpoint if we have one */ | 585 | /* start up the interrupt endpoint if we have one */ |
604 | if (port->interrupt_in_urb) { | 586 | if (port->interrupt_in_urb) { |
@@ -610,32 +592,38 @@ static int sierra_open(struct tty_struct *tty, | |||
610 | return 0; | 592 | return 0; |
611 | } | 593 | } |
612 | 594 | ||
613 | static void sierra_close(struct tty_struct *tty, | 595 | static void sierra_dtr_rts(struct usb_serial_port *port, int on) |
614 | struct usb_serial_port *port, struct file *filp) | ||
615 | { | 596 | { |
616 | int i; | ||
617 | struct usb_serial *serial = port->serial; | 597 | struct usb_serial *serial = port->serial; |
618 | struct sierra_port_private *portdata; | 598 | struct sierra_port_private *portdata; |
619 | 599 | ||
620 | dev_dbg(&port->dev, "%s", __func__); | ||
621 | portdata = usb_get_serial_port_data(port); | 600 | portdata = usb_get_serial_port_data(port); |
622 | 601 | portdata->rts_state = on; | |
623 | portdata->rts_state = 0; | 602 | portdata->dtr_state = on; |
624 | portdata->dtr_state = 0; | ||
625 | 603 | ||
626 | if (serial->dev) { | 604 | if (serial->dev) { |
627 | mutex_lock(&serial->disc_mutex); | 605 | mutex_lock(&serial->disc_mutex); |
628 | if (!serial->disconnected) | 606 | if (!serial->disconnected) |
629 | sierra_send_setup(tty, port); | 607 | sierra_send_setup(port); |
630 | mutex_unlock(&serial->disc_mutex); | 608 | mutex_unlock(&serial->disc_mutex); |
609 | } | ||
610 | } | ||
611 | |||
612 | static void sierra_close(struct usb_serial_port *port) | ||
613 | { | ||
614 | int i; | ||
615 | struct usb_serial *serial = port->serial; | ||
616 | struct sierra_port_private *portdata; | ||
631 | 617 | ||
618 | dev_dbg(&port->dev, "%s", __func__); | ||
619 | portdata = usb_get_serial_port_data(port); | ||
620 | |||
621 | if (serial->dev) { | ||
632 | /* Stop reading/writing urbs */ | 622 | /* Stop reading/writing urbs */ |
633 | for (i = 0; i < N_IN_URB; i++) | 623 | for (i = 0; i < N_IN_URB; i++) |
634 | usb_kill_urb(portdata->in_urbs[i]); | 624 | usb_kill_urb(portdata->in_urbs[i]); |
635 | } | 625 | } |
636 | |||
637 | usb_kill_urb(port->interrupt_in_urb); | 626 | usb_kill_urb(port->interrupt_in_urb); |
638 | tty_port_tty_set(&port->port, NULL); | ||
639 | } | 627 | } |
640 | 628 | ||
641 | static int sierra_startup(struct usb_serial *serial) | 629 | static int sierra_startup(struct usb_serial *serial) |
@@ -737,6 +725,7 @@ static struct usb_serial_driver sierra_device = { | |||
737 | .probe = sierra_probe, | 725 | .probe = sierra_probe, |
738 | .open = sierra_open, | 726 | .open = sierra_open, |
739 | .close = sierra_close, | 727 | .close = sierra_close, |
728 | .dtr_rts = sierra_dtr_rts, | ||
740 | .write = sierra_write, | 729 | .write = sierra_write, |
741 | .write_room = sierra_write_room, | 730 | .write_room = sierra_write_room, |
742 | .set_termios = sierra_set_termios, | 731 | .set_termios = sierra_set_termios, |