aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/mos7720.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-07-22 06:09:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-22 16:03:22 -0400
commit95da310e66ee8090119596c70ca8432e57f9a97f (patch)
tree7f18c30e9c9ad4d7d53df6453fa338be06f09a85 /drivers/usb/serial/mos7720.c
parent1aa3692da57c773e5c76de55c5c4a953962d360e (diff)
usb_serial: API all change
USB serial likes to use port->tty back pointers for the real work it does and to do so without any actual locking. Unfortunately when you consider hangup events, hangup/parallel reopen or even worse hangup followed by parallel close events the tty->port and port->tty pointers are not guaranteed to be the same as port->tty is the active tty while tty->port is the port the tty may or may not still be attached to. So rework the entire API to pass the tty struct. For console cases we need to pass both for now. This shows up multiple drivers that immediately crash with USB console some of which have been fixed in the process. Longer term we need a proper tty as console abstraction Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb/serial/mos7720.c')
-rw-r--r--drivers/usb/serial/mos7720.c87
1 files changed, 35 insertions, 52 deletions
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 50f1fe263338..d47f0814ce2d 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -218,7 +218,7 @@ static void mos7720_bulk_in_callback(struct urb *urb)
218 218
219 data = urb->transfer_buffer; 219 data = urb->transfer_buffer;
220 220
221 tty = port->tty; 221 tty = port->port.tty;
222 if (tty && urb->actual_length) { 222 if (tty && urb->actual_length) {
223 tty_buffer_request_room(tty, urb->actual_length); 223 tty_buffer_request_room(tty, urb->actual_length);
224 tty_insert_flip_string(tty, data, urb->actual_length); 224 tty_insert_flip_string(tty, data, urb->actual_length);
@@ -264,7 +264,7 @@ static void mos7720_bulk_out_data_callback(struct urb *urb)
264 264
265 dbg("Entering ........."); 265 dbg("Entering .........");
266 266
267 tty = mos7720_port->port->tty; 267 tty = mos7720_port->port->port.tty;
268 268
269 if (tty && mos7720_port->open) 269 if (tty && mos7720_port->open)
270 tty_wakeup(tty); 270 tty_wakeup(tty);
@@ -320,7 +320,8 @@ static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value,
320 return status; 320 return status;
321} 321}
322 322
323static int mos7720_open(struct usb_serial_port *port, struct file * filp) 323static int mos7720_open(struct tty_struct *tty,
324 struct usb_serial_port *port, struct file * filp)
324{ 325{
325 struct usb_serial *serial; 326 struct usb_serial *serial;
326 struct usb_serial_port *port0; 327 struct usb_serial_port *port0;
@@ -443,14 +444,12 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
443 data = 0x0c; 444 data = 0x0c;
444 send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); 445 send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
445 446
446//Matrix
447
448 /* force low_latency on so that our tty_push actually forces * 447 /* force low_latency on so that our tty_push actually forces *
449 * the data through,otherwise it is scheduled, and with * 448 * the data through,otherwise it is scheduled, and with *
450 * high data rates (like with OHCI) data can get lost. */ 449 * high data rates (like with OHCI) data can get lost. */
451 450
452 if (port->tty) 451 if (tty)
453 port->tty->low_latency = 1; 452 tty->low_latency = 1;
454 453
455 /* see if we've set up our endpoint info yet * 454 /* see if we've set up our endpoint info yet *
456 * (can't set it up in mos7720_startup as the * 455 * (can't set it up in mos7720_startup as the *
@@ -515,8 +514,9 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
515 * system, 514 * system,
516 * Otherwise we return a negative error number. 515 * Otherwise we return a negative error number.
517 */ 516 */
518static int mos7720_chars_in_buffer(struct usb_serial_port *port) 517static int mos7720_chars_in_buffer(struct tty_struct *tty)
519{ 518{
519 struct usb_serial_port *port = tty->driver_data;
520 int i; 520 int i;
521 int chars = 0; 521 int chars = 0;
522 struct moschip_port *mos7720_port; 522 struct moschip_port *mos7720_port;
@@ -537,7 +537,8 @@ static int mos7720_chars_in_buffer(struct usb_serial_port *port)
537 return chars; 537 return chars;
538} 538}
539 539
540static void mos7720_close(struct usb_serial_port *port, struct file *filp) 540static void mos7720_close(struct tty_struct *tty,
541 struct usb_serial_port *port, struct file *filp)
541{ 542{
542 struct usb_serial *serial; 543 struct usb_serial *serial;
543 struct moschip_port *mos7720_port; 544 struct moschip_port *mos7720_port;
@@ -588,8 +589,9 @@ static void mos7720_close(struct usb_serial_port *port, struct file *filp)
588 dbg("Leaving %s", __func__); 589 dbg("Leaving %s", __func__);
589} 590}
590 591
591static void mos7720_break(struct usb_serial_port *port, int break_state) 592static void mos7720_break(struct tty_struct *tty, int break_state)
592{ 593{
594 struct usb_serial_port *port = tty->driver_data;
593 unsigned char data; 595 unsigned char data;
594 struct usb_serial *serial; 596 struct usb_serial *serial;
595 struct moschip_port *mos7720_port; 597 struct moschip_port *mos7720_port;
@@ -621,8 +623,9 @@ static void mos7720_break(struct usb_serial_port *port, int break_state)
621 * If successful, we return the amount of room that we have for this port 623 * If successful, we return the amount of room that we have for this port
622 * Otherwise we return a negative error number. 624 * Otherwise we return a negative error number.
623 */ 625 */
624static int mos7720_write_room(struct usb_serial_port *port) 626static int mos7720_write_room(struct tty_struct *tty)
625{ 627{
628 struct usb_serial_port *port = tty->driver_data;
626 struct moschip_port *mos7720_port; 629 struct moschip_port *mos7720_port;
627 int room = 0; 630 int room = 0;
628 int i; 631 int i;
@@ -645,8 +648,8 @@ static int mos7720_write_room(struct usb_serial_port *port)
645 return room; 648 return room;
646} 649}
647 650
648static int mos7720_write(struct usb_serial_port *port, 651static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port,
649 const unsigned char *data, int count) 652 const unsigned char *data, int count)
650{ 653{
651 int status; 654 int status;
652 int i; 655 int i;
@@ -719,10 +722,10 @@ exit:
719 return bytes_sent; 722 return bytes_sent;
720} 723}
721 724
722static void mos7720_throttle(struct usb_serial_port *port) 725static void mos7720_throttle(struct tty_struct *tty)
723{ 726{
727 struct usb_serial_port *port = tty->driver_data;
724 struct moschip_port *mos7720_port; 728 struct moschip_port *mos7720_port;
725 struct tty_struct *tty;
726 int status; 729 int status;
727 730
728 dbg("%s- port %d\n", __func__, port->number); 731 dbg("%s- port %d\n", __func__, port->number);
@@ -739,16 +742,10 @@ static void mos7720_throttle(struct usb_serial_port *port)
739 742
740 dbg("%s: Entering ..........", __func__); 743 dbg("%s: Entering ..........", __func__);
741 744
742 tty = port->tty;
743 if (!tty) {
744 dbg("%s - no tty available", __func__);
745 return;
746 }
747
748 /* if we are implementing XON/XOFF, send the stop character */ 745 /* if we are implementing XON/XOFF, send the stop character */
749 if (I_IXOFF(tty)) { 746 if (I_IXOFF(tty)) {
750 unsigned char stop_char = STOP_CHAR(tty); 747 unsigned char stop_char = STOP_CHAR(tty);
751 status = mos7720_write(port, &stop_char, 1); 748 status = mos7720_write(tty, port, &stop_char, 1);
752 if (status <= 0) 749 if (status <= 0)
753 return; 750 return;
754 } 751 }
@@ -764,11 +761,11 @@ static void mos7720_throttle(struct usb_serial_port *port)
764 } 761 }
765} 762}
766 763
767static void mos7720_unthrottle(struct usb_serial_port *port) 764static void mos7720_unthrottle(struct tty_struct *tty)
768{ 765{
769 struct tty_struct *tty; 766 struct usb_serial_port *port = tty->driver_data;
770 int status;
771 struct moschip_port *mos7720_port = usb_get_serial_port_data(port); 767 struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
768 int status;
772 769
773 if (mos7720_port == NULL) 770 if (mos7720_port == NULL)
774 return; 771 return;
@@ -780,16 +777,10 @@ static void mos7720_unthrottle(struct usb_serial_port *port)
780 777
781 dbg("%s: Entering ..........", __func__); 778 dbg("%s: Entering ..........", __func__);
782 779
783 tty = port->tty;
784 if (!tty) {
785 dbg("%s - no tty available", __func__);
786 return;
787 }
788
789 /* if we are implementing XON/XOFF, send the start character */ 780 /* if we are implementing XON/XOFF, send the start character */
790 if (I_IXOFF(tty)) { 781 if (I_IXOFF(tty)) {
791 unsigned char start_char = START_CHAR(tty); 782 unsigned char start_char = START_CHAR(tty);
792 status = mos7720_write(port, &start_char, 1); 783 status = mos7720_write(tty, port, &start_char, 1);
793 if (status <= 0) 784 if (status <= 0)
794 return; 785 return;
795 } 786 }
@@ -1011,12 +1002,12 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port,
1011 * This routine is called to set the UART on the device to match 1002 * This routine is called to set the UART on the device to match
1012 * the specified new settings. 1003 * the specified new settings.
1013 */ 1004 */
1014static void change_port_settings(struct moschip_port *mos7720_port, 1005static void change_port_settings(struct tty_struct *tty,
1006 struct moschip_port *mos7720_port,
1015 struct ktermios *old_termios) 1007 struct ktermios *old_termios)
1016{ 1008{
1017 struct usb_serial_port *port; 1009 struct usb_serial_port *port;
1018 struct usb_serial *serial; 1010 struct usb_serial *serial;
1019 struct tty_struct *tty;
1020 int baud; 1011 int baud;
1021 unsigned cflag; 1012 unsigned cflag;
1022 unsigned iflag; 1013 unsigned iflag;
@@ -1042,8 +1033,6 @@ static void change_port_settings(struct moschip_port *mos7720_port,
1042 return; 1033 return;
1043 } 1034 }
1044 1035
1045 tty = mos7720_port->port->tty;
1046
1047 dbg("%s: Entering ..........", __func__); 1036 dbg("%s: Entering ..........", __func__);
1048 1037
1049 lData = UART_LCR_WLEN8; 1038 lData = UART_LCR_WLEN8;
@@ -1198,14 +1187,13 @@ static void change_port_settings(struct moschip_port *mos7720_port,
1198 * this function is called by the tty driver when it wants to change the 1187 * this function is called by the tty driver when it wants to change the
1199 * termios structure. 1188 * termios structure.
1200 */ 1189 */
1201static void mos7720_set_termios(struct usb_serial_port *port, 1190static void mos7720_set_termios(struct tty_struct *tty,
1202 struct ktermios *old_termios) 1191 struct usb_serial_port *port, struct ktermios *old_termios)
1203{ 1192{
1204 int status; 1193 int status;
1205 unsigned int cflag; 1194 unsigned int cflag;
1206 struct usb_serial *serial; 1195 struct usb_serial *serial;
1207 struct moschip_port *mos7720_port; 1196 struct moschip_port *mos7720_port;
1208 struct tty_struct *tty;
1209 1197
1210 serial = port->serial; 1198 serial = port->serial;
1211 1199
@@ -1214,9 +1202,6 @@ static void mos7720_set_termios(struct usb_serial_port *port,
1214 if (mos7720_port == NULL) 1202 if (mos7720_port == NULL)
1215 return; 1203 return;
1216 1204
1217 tty = port->tty;
1218
1219
1220 if (!mos7720_port->open) { 1205 if (!mos7720_port->open) {
1221 dbg("%s - port not opened", __func__); 1206 dbg("%s - port not opened", __func__);
1222 return; 1207 return;
@@ -1237,7 +1222,7 @@ static void mos7720_set_termios(struct usb_serial_port *port,
1237 dbg("%s - port %d", __func__, port->number); 1222 dbg("%s - port %d", __func__, port->number);
1238 1223
1239 /* change the port settings to the new ones specified */ 1224 /* change the port settings to the new ones specified */
1240 change_port_settings(mos7720_port, old_termios); 1225 change_port_settings(tty, mos7720_port, old_termios);
1241 1226
1242 if(!port->read_urb) { 1227 if(!port->read_urb) {
1243 dbg("%s","URB KILLED !!!!!\n"); 1228 dbg("%s","URB KILLED !!!!!\n");
@@ -1264,13 +1249,13 @@ static void mos7720_set_termios(struct usb_serial_port *port,
1264 * transmit holding register is empty. This functionality 1249 * transmit holding register is empty. This functionality
1265 * allows an RS485 driver to be written in user space. 1250 * allows an RS485 driver to be written in user space.
1266 */ 1251 */
1267static int get_lsr_info(struct moschip_port *mos7720_port, 1252static int get_lsr_info(struct tty_struct *tty, struct moschip_port *mos7720_port,
1268 unsigned int __user *value) 1253 unsigned int __user *value)
1269{ 1254{
1270 int count; 1255 int count;
1271 unsigned int result = 0; 1256 unsigned int result = 0;
1272 1257
1273 count = mos7720_chars_in_buffer(mos7720_port->port); 1258 count = mos7720_chars_in_buffer(tty);
1274 if (count == 0) { 1259 if (count == 0) {
1275 dbg("%s -- Empty", __func__); 1260 dbg("%s -- Empty", __func__);
1276 result = TIOCSER_TEMT; 1261 result = TIOCSER_TEMT;
@@ -1290,7 +1275,7 @@ static int get_number_bytes_avail(struct moschip_port *mos7720_port,
1290 unsigned int __user *value) 1275 unsigned int __user *value)
1291{ 1276{
1292 unsigned int result = 0; 1277 unsigned int result = 0;
1293 struct tty_struct *tty = mos7720_port->port->tty; 1278 struct tty_struct *tty = mos7720_port->port->port.tty;
1294 1279
1295 if (!tty) 1280 if (!tty)
1296 return -ENOIOCTLCMD; 1281 return -ENOIOCTLCMD;
@@ -1407,9 +1392,10 @@ static int get_serial_info(struct moschip_port *mos7720_port,
1407 return 0; 1392 return 0;
1408} 1393}
1409 1394
1410static int mos7720_ioctl(struct usb_serial_port *port, struct file *file, 1395static int mos7720_ioctl(struct tty_struct *tty, struct file *file,
1411 unsigned int cmd, unsigned long arg) 1396 unsigned int cmd, unsigned long arg)
1412{ 1397{
1398 struct usb_serial_port *port = tty->driver_data;
1413 struct moschip_port *mos7720_port; 1399 struct moschip_port *mos7720_port;
1414 struct async_icount cnow; 1400 struct async_icount cnow;
1415 struct async_icount cprev; 1401 struct async_icount cprev;
@@ -1431,9 +1417,10 @@ static int mos7720_ioctl(struct usb_serial_port *port, struct file *file,
1431 1417
1432 case TIOCSERGETLSR: 1418 case TIOCSERGETLSR:
1433 dbg("%s (%d) TIOCSERGETLSR", __func__, port->number); 1419 dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
1434 return get_lsr_info(mos7720_port, (unsigned int __user *)arg); 1420 return get_lsr_info(tty, mos7720_port, (unsigned int __user *)arg);
1435 return 0; 1421 return 0;
1436 1422
1423 /* FIXME: These should be using the mode methods */
1437 case TIOCMBIS: 1424 case TIOCMBIS:
1438 case TIOCMBIC: 1425 case TIOCMBIC:
1439 case TIOCMSET: 1426 case TIOCMSET:
@@ -1452,10 +1439,6 @@ static int mos7720_ioctl(struct usb_serial_port *port, struct file *file,
1452 return get_serial_info(mos7720_port, 1439 return get_serial_info(mos7720_port,
1453 (struct serial_struct __user *)arg); 1440 (struct serial_struct __user *)arg);
1454 1441
1455 case TIOCSSERIAL:
1456 dbg("%s (%d) TIOCSSERIAL", __func__, port->number);
1457 break;
1458
1459 case TIOCMIWAIT: 1442 case TIOCMIWAIT:
1460 dbg("%s (%d) TIOCMIWAIT", __func__, port->number); 1443 dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
1461 cprev = mos7720_port->icount; 1444 cprev = mos7720_port->icount;