aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucy McCoy <lucy@keyspan.com>2007-05-18 15:10:41 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-07-12 19:29:45 -0400
commit0ca1268e109acf6d71507398cb95cab2e670b654 (patch)
treee73f21cb8313651b9e3616c601868ef09fbc6382
parent87e71b473ee199cf4b7b7a0ce890cd01f45e3a0e (diff)
USB Serial Keyspan: add support for USA-49WG & USA-28XG
Add support for Keyspan adapters: USA-49WG and USA-28XG Signed-off-by: Lucy P. McCoy <lucy@keyspan.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/serial/keyspan.c414
-rw-r--r--drivers/usb/serial/keyspan.h74
-rw-r--r--drivers/usb/serial/keyspan_usa67msg.h254
3 files changed, 709 insertions, 33 deletions
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index e6966f12ed5a..fa91ddee2458 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -115,12 +115,13 @@ static int debug;
115/* 115/*
116 * Version Information 116 * Version Information
117 */ 117 */
118#define DRIVER_VERSION "v1.1.4" 118#define DRIVER_VERSION "v1.1.5"
119#define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu" 119#define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu"
120#define DRIVER_DESC "Keyspan USB to Serial Converter Driver" 120#define DRIVER_DESC "Keyspan USB to Serial Converter Driver"
121 121
122#define INSTAT_BUFLEN 32 122#define INSTAT_BUFLEN 32
123#define GLOCONT_BUFLEN 64 123#define GLOCONT_BUFLEN 64
124#define INDAT49W_BUFLEN 512
124 125
125 /* Per device and per port private data */ 126 /* Per device and per port private data */
126struct keyspan_serial_private { 127struct keyspan_serial_private {
@@ -129,9 +130,15 @@ struct keyspan_serial_private {
129 struct urb *instat_urb; 130 struct urb *instat_urb;
130 char instat_buf[INSTAT_BUFLEN]; 131 char instat_buf[INSTAT_BUFLEN];
131 132
133 /* added to support 49wg, where data from all 4 ports comes in on 1 EP */
134 /* and high-speed supported */
135 struct urb *indat_urb;
136 char indat_buf[INDAT49W_BUFLEN];
137
132 /* XXX this one probably will need a lock */ 138 /* XXX this one probably will need a lock */
133 struct urb *glocont_urb; 139 struct urb *glocont_urb;
134 char glocont_buf[GLOCONT_BUFLEN]; 140 char glocont_buf[GLOCONT_BUFLEN];
141 char ctrl_buf[8]; // for EP0 control message
135}; 142};
136 143
137struct keyspan_port_private { 144struct keyspan_port_private {
@@ -179,12 +186,13 @@ struct keyspan_port_private {
179 186
180 187
181/* Include Keyspan message headers. All current Keyspan Adapters 188/* Include Keyspan message headers. All current Keyspan Adapters
182 make use of one of four message formats which are referred 189 make use of one of five message formats which are referred
183 to as USA-26, USA-28 and USA-49, USA-90 by Keyspan and within this driver. */ 190 to as USA-26, USA-28, USA-49, USA-90, USA-67 by Keyspan and within this driver. */
184#include "keyspan_usa26msg.h" 191#include "keyspan_usa26msg.h"
185#include "keyspan_usa28msg.h" 192#include "keyspan_usa28msg.h"
186#include "keyspan_usa49msg.h" 193#include "keyspan_usa49msg.h"
187#include "keyspan_usa90msg.h" 194#include "keyspan_usa90msg.h"
195#include "keyspan_usa67msg.h"
188 196
189 197
190/* Functions used by new usb-serial code. */ 198/* Functions used by new usb-serial code. */
@@ -850,13 +858,89 @@ static void usa49_indat_callback(struct urb *urb)
850 } 858 }
851} 859}
852 860
861static void usa49wg_indat_callback(struct urb *urb)
862{
863 int i, len, x, err;
864 struct usb_serial *serial;
865 struct usb_serial_port *port;
866 struct tty_struct *tty;
867 unsigned char *data = urb->transfer_buffer;
868
869 dbg ("%s", __FUNCTION__);
870
871 serial = urb->context;
872
873 if (urb->status) {
874 dbg("%s - nonzero status: %x", __FUNCTION__, urb->status);
875 return;
876 }
877
878 /* inbound data is in the form P#, len, status, data */
879 i = 0;
880 len = 0;
881
882 if (urb->actual_length) {
883 while (i < urb->actual_length) {
884
885 /* Check port number from message*/
886 if (data[i] >= serial->num_ports) {
887 dbg ("%s - Unexpected port number %d",
888 __FUNCTION__, data[i]);
889 return;
890 }
891 port = serial->port[data[i++]];
892 tty = port->tty;
893 len = data[i++];
894
895 /* 0x80 bit is error flag */
896 if ((data[i] & 0x80) == 0) {
897 /* no error on any byte */
898 i++;
899 for (x = 1; x < len ; ++x)
900 if (port->open_count)
901 tty_insert_flip_char(tty,
902 data[i++], 0);
903 else
904 i++;
905 } else {
906 /*
907 * some bytes had errors, every byte has status
908 */
909 for (x = 0; x + 1 < len; x += 2) {
910 int stat = data[i], flag = 0;
911 if (stat & RXERROR_OVERRUN)
912 flag |= TTY_OVERRUN;
913 if (stat & RXERROR_FRAMING)
914 flag |= TTY_FRAME;
915 if (stat & RXERROR_PARITY)
916 flag |= TTY_PARITY;
917 /* XXX should handle break (0x10) */
918 if (port->open_count)
919 tty_insert_flip_char(tty,
920 data[i+1], flag);
921 i += 2;
922 }
923 }
924 if (port->open_count)
925 tty_flip_buffer_push(tty);
926 }
927 }
928
929 /* Resubmit urb so we continue receiving */
930 urb->dev = serial->dev;
931
932 err = usb_submit_urb(urb, GFP_ATOMIC);
933 if (err != 0)
934 dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err);
935}
936
853/* not used, usa-49 doesn't have per-port control endpoints */ 937/* not used, usa-49 doesn't have per-port control endpoints */
854static void usa49_outcont_callback(struct urb *urb) 938static void usa49_outcont_callback(struct urb *urb)
855{ 939{
856 dbg ("%s", __FUNCTION__); 940 dbg ("%s", __FUNCTION__);
857} 941}
858 942
859static void usa90_indat_callback(struct urb *urb) 943static void usa90_indat_callback(struct urb *urb)
860{ 944{
861 int i, err; 945 int i, err;
862 int endpoint; 946 int endpoint;
@@ -869,7 +953,6 @@ static void usa90_indat_callback(struct urb *urb)
869 953
870 endpoint = usb_pipeendpoint(urb->pipe); 954 endpoint = usb_pipeendpoint(urb->pipe);
871 955
872
873 if (urb->status) { 956 if (urb->status) {
874 dbg("%s - nonzero status: %x on endpoint %d.", 957 dbg("%s - nonzero status: %x on endpoint %d.",
875 __FUNCTION__, urb->status, endpoint); 958 __FUNCTION__, urb->status, endpoint);
@@ -995,6 +1078,87 @@ static void usa90_outcont_callback(struct urb *urb)
995 } 1078 }
996} 1079}
997 1080
1081/* Status messages from the 28xg */
1082static void usa67_instat_callback(struct urb *urb)
1083{
1084 int err;
1085 unsigned char *data = urb->transfer_buffer;
1086 struct keyspan_usa67_portStatusMessage *msg;
1087 struct usb_serial *serial;
1088 struct usb_serial_port *port;
1089 struct keyspan_port_private *p_priv;
1090 int old_dcd_state;
1091
1092 dbg ("%s", __FUNCTION__);
1093
1094 serial = urb->context;
1095
1096 if (urb->status) {
1097 dbg("%s - nonzero status: %x", __FUNCTION__, urb->status);
1098 return;
1099 }
1100
1101 if (urb->actual_length != sizeof(struct keyspan_usa67_portStatusMessage)) {
1102 dbg("%s - bad length %d", __FUNCTION__, urb->actual_length);
1103 return;
1104 }
1105
1106
1107 /* Now do something useful with the data */
1108 msg = (struct keyspan_usa67_portStatusMessage *)data;
1109
1110 /* Check port number from message and retrieve private data */
1111 if (msg->port >= serial->num_ports) {
1112 dbg ("%s - Unexpected port number %d", __FUNCTION__, msg->port);
1113 return;
1114 }
1115
1116 port = serial->port[msg->port];
1117 p_priv = usb_get_serial_port_data(port);
1118
1119 /* Update handshaking pin state information */
1120 old_dcd_state = p_priv->dcd_state;
1121 p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
1122 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
1123
1124 if (port->tty && !C_CLOCAL(port->tty)
1125 && old_dcd_state != p_priv->dcd_state) {
1126 if (old_dcd_state)
1127 tty_hangup(port->tty);
1128 /* else */
1129 /* wake_up_interruptible(&p_priv->open_wait); */
1130 }
1131
1132 /* Resubmit urb so we continue receiving */
1133 urb->dev = serial->dev;
1134 err = usb_submit_urb(urb, GFP_ATOMIC);
1135 if (err != 0)
1136 dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err);
1137}
1138
1139static void usa67_glocont_callback(struct urb *urb)
1140{
1141 struct usb_serial *serial;
1142 struct usb_serial_port *port;
1143 struct keyspan_port_private *p_priv;
1144 int i;
1145
1146 dbg ("%s", __FUNCTION__);
1147
1148 serial = urb->context;
1149 for (i = 0; i < serial->num_ports; ++i) {
1150 port = serial->port[i];
1151 p_priv = usb_get_serial_port_data(port);
1152
1153 if (p_priv->resend_cont) {
1154 dbg ("%s - sending setup", __FUNCTION__);
1155 keyspan_usa67_send_setup(serial, port,
1156 p_priv->resend_cont - 1);
1157 break;
1158 }
1159 }
1160}
1161
998static int keyspan_write_room (struct usb_serial_port *port) 1162static int keyspan_write_room (struct usb_serial_port *port)
999{ 1163{
1000 struct keyspan_port_private *p_priv; 1164 struct keyspan_port_private *p_priv;
@@ -1311,6 +1475,11 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
1311 return NULL; 1475 return NULL;
1312 } 1476 }
1313 1477
1478 if (endpoint == 0) {
1479 /* control EP filled in when used */
1480 return urb;
1481 }
1482
1314 ep_desc = find_ep(serial, endpoint); 1483 ep_desc = find_ep(serial, endpoint);
1315 if (!ep_desc) { 1484 if (!ep_desc) {
1316 /* leak the urb, something's wrong and the callers don't care */ 1485 /* leak the urb, something's wrong and the callers don't care */
@@ -1380,6 +1549,14 @@ static struct callbacks {
1380 .outdat_callback = usa2x_outdat_callback, 1549 .outdat_callback = usa2x_outdat_callback,
1381 .inack_callback = usa28_inack_callback, 1550 .inack_callback = usa28_inack_callback,
1382 .outcont_callback = usa90_outcont_callback, 1551 .outcont_callback = usa90_outcont_callback,
1552 }, {
1553 /* msg_usa67 callbacks */
1554 .instat_callback = usa67_instat_callback,
1555 .glocont_callback = usa67_glocont_callback,
1556 .indat_callback = usa26_indat_callback,
1557 .outdat_callback = usa2x_outdat_callback,
1558 .inack_callback = usa26_inack_callback,
1559 .outcont_callback = usa26_outcont_callback,
1383 } 1560 }
1384}; 1561};
1385 1562
@@ -1410,6 +1587,11 @@ static void keyspan_setup_urbs(struct usb_serial *serial)
1410 serial, s_priv->instat_buf, INSTAT_BUFLEN, 1587 serial, s_priv->instat_buf, INSTAT_BUFLEN,
1411 cback->instat_callback); 1588 cback->instat_callback);
1412 1589
1590 s_priv->indat_urb = keyspan_setup_urb
1591 (serial, d_details->indat_endpoint, USB_DIR_IN,
1592 serial, s_priv->indat_buf, INDAT49W_BUFLEN,
1593 usa49wg_indat_callback);
1594
1413 s_priv->glocont_urb = keyspan_setup_urb 1595 s_priv->glocont_urb = keyspan_setup_urb
1414 (serial, d_details->glocont_endpoint, USB_DIR_OUT, 1596 (serial, d_details->glocont_endpoint, USB_DIR_OUT,
1415 serial, s_priv->glocont_buf, GLOCONT_BUFLEN, 1597 serial, s_priv->glocont_buf, GLOCONT_BUFLEN,
@@ -1685,8 +1867,8 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
1685 } 1867 }
1686 1868
1687 /* Save reset port val for resend. 1869 /* Save reset port val for resend.
1688 Don't overwrite resend for close condition. */ 1870 Don't overwrite resend for open/close condition. */
1689 if (p_priv->resend_cont != 3) 1871 if ((reset_port + 1) > p_priv->resend_cont)
1690 p_priv->resend_cont = reset_port + 1; 1872 p_priv->resend_cont = reset_port + 1;
1691 if (this_urb->status == -EINPROGRESS) { 1873 if (this_urb->status == -EINPROGRESS) {
1692 /* dbg ("%s - already writing", __FUNCTION__); */ 1874 /* dbg ("%s - already writing", __FUNCTION__); */
@@ -1836,8 +2018,8 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
1836 } 2018 }
1837 2019
1838 /* Save reset port val for resend. 2020 /* Save reset port val for resend.
1839 Don't overwrite resend for close condition. */ 2021 Don't overwrite resend for open/close condition. */
1840 if (p_priv->resend_cont != 3) 2022 if ((reset_port + 1) > p_priv->resend_cont)
1841 p_priv->resend_cont = reset_port + 1; 2023 p_priv->resend_cont = reset_port + 1;
1842 if (this_urb->status == -EINPROGRESS) { 2024 if (this_urb->status == -EINPROGRESS) {
1843 dbg ("%s already writing", __FUNCTION__); 2025 dbg ("%s already writing", __FUNCTION__);
@@ -1940,11 +2122,11 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
1940 struct usb_serial_port *port, 2122 struct usb_serial_port *port,
1941 int reset_port) 2123 int reset_port)
1942{ 2124{
1943 struct keyspan_usa49_portControlMessage msg; 2125 struct keyspan_usa49_portControlMessage msg;
2126 struct usb_ctrlrequest *dr = NULL;
1944 struct keyspan_serial_private *s_priv; 2127 struct keyspan_serial_private *s_priv;
1945 struct keyspan_port_private *p_priv; 2128 struct keyspan_port_private *p_priv;
1946 const struct keyspan_device_details *d_details; 2129 const struct keyspan_device_details *d_details;
1947 int glocont_urb;
1948 struct urb *this_urb; 2130 struct urb *this_urb;
1949 int err, device_port; 2131 int err, device_port;
1950 2132
@@ -1954,10 +2136,9 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
1954 p_priv = usb_get_serial_port_data(port); 2136 p_priv = usb_get_serial_port_data(port);
1955 d_details = s_priv->device_details; 2137 d_details = s_priv->device_details;
1956 2138
1957 glocont_urb = d_details->glocont_endpoint;
1958 this_urb = s_priv->glocont_urb; 2139 this_urb = s_priv->glocont_urb;
1959 2140
1960 /* Work out which port within the device is being setup */ 2141 /* Work out which port within the device is being setup */
1961 device_port = port->number - port->serial->minor; 2142 device_port = port->number - port->serial->minor;
1962 2143
1963 dbg("%s - endpoint %d port %d (%d)",__FUNCTION__, usb_pipeendpoint(this_urb->pipe), port->number, device_port); 2144 dbg("%s - endpoint %d port %d (%d)",__FUNCTION__, usb_pipeendpoint(this_urb->pipe), port->number, device_port);
@@ -1969,9 +2150,10 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
1969 } 2150 }
1970 2151
1971 /* Save reset port val for resend. 2152 /* Save reset port val for resend.
1972 Don't overwrite resend for close condition. */ 2153 Don't overwrite resend for open/close condition. */
1973 if (p_priv->resend_cont != 3) 2154 if ((reset_port + 1) > p_priv->resend_cont)
1974 p_priv->resend_cont = reset_port + 1; 2155 p_priv->resend_cont = reset_port + 1;
2156
1975 if (this_urb->status == -EINPROGRESS) { 2157 if (this_urb->status == -EINPROGRESS) {
1976 /* dbg ("%s - already writing", __FUNCTION__); */ 2158 /* dbg ("%s - already writing", __FUNCTION__); */
1977 mdelay(5); 2159 mdelay(5);
@@ -2083,20 +2265,39 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
2083 msg.dtr = p_priv->dtr_state; 2265 msg.dtr = p_priv->dtr_state;
2084 2266
2085 p_priv->resend_cont = 0; 2267 p_priv->resend_cont = 0;
2086 memcpy (this_urb->transfer_buffer, &msg, sizeof(msg)); 2268
2269 /* if the device is a 49wg, we send control message on usb control EP 0 */
2270
2271 if (d_details->product_id == keyspan_usa49wg_product_id) {
2272 dr = (void *)(s_priv->ctrl_buf);
2273 dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT;
2274 dr->bRequest = 0xB0; /* 49wg control message */;
2275 dr->wValue = 0;
2276 dr->wIndex = 0;
2277 dr->wLength = cpu_to_le16(sizeof(msg));
2278
2279 memcpy (s_priv->glocont_buf, &msg, sizeof(msg));
2280
2281 usb_fill_control_urb(this_urb, serial->dev, usb_sndctrlpipe(serial->dev, 0),
2282 (unsigned char *)dr, s_priv->glocont_buf, sizeof(msg),
2283 usa49_glocont_callback, serial);
2284
2285 } else {
2286 memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
2087 2287
2088 /* send the data out the device on control endpoint */ 2288 /* send the data out the device on control endpoint */
2089 this_urb->transfer_buffer_length = sizeof(msg); 2289 this_urb->transfer_buffer_length = sizeof(msg);
2090 2290
2091 this_urb->dev = serial->dev; 2291 this_urb->dev = serial->dev;
2292 }
2092 if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) { 2293 if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
2093 dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__, err); 2294 dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__, err);
2094 } 2295 }
2095#if 0 2296#if 0
2096 else { 2297 else {
2097 dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __FUNCTION__, 2298 dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __FUNCTION__,
2098 outcont_urb, this_urb->transfer_buffer_length, 2299 outcont_urb, this_urb->transfer_buffer_length,
2099 usb_pipeendpoint(this_urb->pipe)); 2300 usb_pipeendpoint(this_urb->pipe));
2100 } 2301 }
2101#endif 2302#endif
2102 2303
@@ -2241,6 +2442,154 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial,
2241 return (0); 2442 return (0);
2242} 2443}
2243 2444
2445static int keyspan_usa67_send_setup(struct usb_serial *serial,
2446 struct usb_serial_port *port,
2447 int reset_port)
2448{
2449 struct keyspan_usa67_portControlMessage msg;
2450 struct keyspan_serial_private *s_priv;
2451 struct keyspan_port_private *p_priv;
2452 const struct keyspan_device_details *d_details;
2453 struct urb *this_urb;
2454 int err, device_port;
2455
2456 dbg ("%s", __FUNCTION__);
2457
2458 s_priv = usb_get_serial_data(serial);
2459 p_priv = usb_get_serial_port_data(port);
2460 d_details = s_priv->device_details;
2461
2462 this_urb = s_priv->glocont_urb;
2463
2464 /* Work out which port within the device is being setup */
2465 device_port = port->number - port->serial->minor;
2466
2467 /* Make sure we have an urb then send the message */
2468 if (this_urb == NULL) {
2469 dbg("%s - oops no urb for port %d.", __FUNCTION__,
2470 port->number);
2471 return -1;
2472 }
2473
2474 /* Save reset port val for resend.
2475 Don't overwrite resend for open/close condition. */
2476 if ((reset_port + 1) > p_priv->resend_cont)
2477 p_priv->resend_cont = reset_port + 1;
2478 if (this_urb->status == -EINPROGRESS) {
2479 /* dbg ("%s - already writing", __FUNCTION__); */
2480 mdelay(5);
2481 return(-1);
2482 }
2483
2484 memset(&msg, 0, sizeof(struct keyspan_usa67_portControlMessage));
2485
2486 msg.port = device_port;
2487
2488 /* Only set baud rate if it's changed */
2489 if (p_priv->old_baud != p_priv->baud) {
2490 p_priv->old_baud = p_priv->baud;
2491 msg.setClocking = 0xff;
2492 if (d_details->calculate_baud_rate
2493 (p_priv->baud, d_details->baudclk, &msg.baudHi,
2494 &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE ) {
2495 dbg("%s - Invalid baud rate %d requested, using 9600.", __FUNCTION__,
2496 p_priv->baud);
2497 msg.baudLo = 0;
2498 msg.baudHi = 125; /* Values for 9600 baud */
2499 msg.prescaler = 10;
2500 }
2501 msg.setPrescaler = 0xff;
2502 }
2503
2504 msg.lcr = (p_priv->cflag & CSTOPB) ? STOPBITS_678_2 : STOPBITS_5678_1;
2505 switch (p_priv->cflag & CSIZE) {
2506 case CS5:
2507 msg.lcr |= USA_DATABITS_5;
2508 break;
2509 case CS6:
2510 msg.lcr |= USA_DATABITS_6;
2511 break;
2512 case CS7:
2513 msg.lcr |= USA_DATABITS_7;
2514 break;
2515 case CS8:
2516 msg.lcr |= USA_DATABITS_8;
2517 break;
2518 }
2519 if (p_priv->cflag & PARENB) {
2520 /* note USA_PARITY_NONE == 0 */
2521 msg.lcr |= (p_priv->cflag & PARODD)?
2522 USA_PARITY_ODD: USA_PARITY_EVEN;
2523 }
2524 msg.setLcr = 0xff;
2525
2526 msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
2527 msg.xonFlowControl = 0;
2528 msg.setFlowControl = 0xff;
2529 msg.forwardingLength = 16;
2530 msg.xonChar = 17;
2531 msg.xoffChar = 19;
2532
2533 if (reset_port == 1) {
2534 /* Opening port */
2535 msg._txOn = 1;
2536 msg._txOff = 0;
2537 msg.txFlush = 0;
2538 msg.txBreak = 0;
2539 msg.rxOn = 1;
2540 msg.rxOff = 0;
2541 msg.rxFlush = 1;
2542 msg.rxForward = 0;
2543 msg.returnStatus = 0;
2544 msg.resetDataToggle = 0xff;
2545 } else if (reset_port == 2) {
2546 /* Closing port */
2547 msg._txOn = 0;
2548 msg._txOff = 1;
2549 msg.txFlush = 0;
2550 msg.txBreak = 0;
2551 msg.rxOn = 0;
2552 msg.rxOff = 1;
2553 msg.rxFlush = 1;
2554 msg.rxForward = 0;
2555 msg.returnStatus = 0;
2556 msg.resetDataToggle = 0;
2557 } else {
2558 /* Sending intermediate configs */
2559 msg._txOn = (! p_priv->break_on);
2560 msg._txOff = 0;
2561 msg.txFlush = 0;
2562 msg.txBreak = (p_priv->break_on);
2563 msg.rxOn = 0;
2564 msg.rxOff = 0;
2565 msg.rxFlush = 0;
2566 msg.rxForward = 0;
2567 msg.returnStatus = 0;
2568 msg.resetDataToggle = 0x0;
2569 }
2570
2571 /* Do handshaking outputs */
2572 msg.setTxTriState_setRts = 0xff;
2573 msg.txTriState_rts = p_priv->rts_state;
2574
2575 msg.setHskoa_setDtr = 0xff;
2576 msg.hskoa_dtr = p_priv->dtr_state;
2577
2578 p_priv->resend_cont = 0;
2579
2580 memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
2581
2582 /* send the data out the device on control endpoint */
2583 this_urb->transfer_buffer_length = sizeof(msg);
2584 this_urb->dev = serial->dev;
2585
2586 err = usb_submit_urb(this_urb, GFP_ATOMIC);
2587 if (err != 0)
2588 dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__,
2589 err);
2590 return (0);
2591}
2592
2244static void keyspan_send_setup(struct usb_serial_port *port, int reset_port) 2593static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
2245{ 2594{
2246 struct usb_serial *serial = port->serial; 2595 struct usb_serial *serial = port->serial;
@@ -2265,6 +2614,9 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
2265 case msg_usa90: 2614 case msg_usa90:
2266 keyspan_usa90_send_setup(serial, port, reset_port); 2615 keyspan_usa90_send_setup(serial, port, reset_port);
2267 break; 2616 break;
2617 case msg_usa67:
2618 keyspan_usa67_send_setup(serial, port, reset_port);
2619 break;
2268 } 2620 }
2269} 2621}
2270 2622
@@ -2313,9 +2665,19 @@ static int keyspan_startup (struct usb_serial *serial)
2313 2665
2314 keyspan_setup_urbs(serial); 2666 keyspan_setup_urbs(serial);
2315 2667
2316 s_priv->instat_urb->dev = serial->dev; 2668 if (s_priv->instat_urb != NULL) {
2317 if ((err = usb_submit_urb(s_priv->instat_urb, GFP_KERNEL)) != 0) { 2669 s_priv->instat_urb->dev = serial->dev;
2318 dbg("%s - submit instat urb failed %d", __FUNCTION__, err); 2670 err = usb_submit_urb(s_priv->instat_urb, GFP_KERNEL);
2671 if (err != 0)
2672 dbg("%s - submit instat urb failed %d", __FUNCTION__,
2673 err);
2674 }
2675 if (s_priv->indat_urb != NULL) {
2676 s_priv->indat_urb->dev = serial->dev;
2677 err = usb_submit_urb(s_priv->indat_urb, GFP_KERNEL);
2678 if (err != 0)
2679 dbg("%s - submit indat urb failed %d", __FUNCTION__,
2680 err);
2319 } 2681 }
2320 2682
2321 return (0); 2683 return (0);
@@ -2335,6 +2697,7 @@ static void keyspan_shutdown (struct usb_serial *serial)
2335 /* Stop reading/writing urbs */ 2697 /* Stop reading/writing urbs */
2336 stop_urb(s_priv->instat_urb); 2698 stop_urb(s_priv->instat_urb);
2337 stop_urb(s_priv->glocont_urb); 2699 stop_urb(s_priv->glocont_urb);
2700 stop_urb(s_priv->indat_urb);
2338 for (i = 0; i < serial->num_ports; ++i) { 2701 for (i = 0; i < serial->num_ports; ++i) {
2339 port = serial->port[i]; 2702 port = serial->port[i];
2340 p_priv = usb_get_serial_port_data(port); 2703 p_priv = usb_get_serial_port_data(port);
@@ -2348,6 +2711,7 @@ static void keyspan_shutdown (struct usb_serial *serial)
2348 2711
2349 /* Now free them */ 2712 /* Now free them */
2350 usb_free_urb(s_priv->instat_urb); 2713 usb_free_urb(s_priv->instat_urb);
2714 usb_free_urb(s_priv->indat_urb);
2351 usb_free_urb(s_priv->glocont_urb); 2715 usb_free_urb(s_priv->glocont_urb);
2352 for (i = 0; i < serial->num_ports; ++i) { 2716 for (i = 0; i < serial->num_ports; ++i) {
2353 port = serial->port[i]; 2717 port = serial->port[i];
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index c6830cbdc6df..8a0d17401529 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -99,6 +99,10 @@ static int keyspan_usa90_send_setup (struct usb_serial *serial,
99 struct usb_serial_port *port, 99 struct usb_serial_port *port,
100 int reset_port); 100 int reset_port);
101 101
102static int keyspan_usa67_send_setup (struct usb_serial *serial,
103 struct usb_serial_port *port,
104 int reset_port);
105
102/* Struct used for firmware - increased size of data section 106/* Struct used for firmware - increased size of data section
103 to allow Keyspan's 'C' firmware struct to be used unmodified */ 107 to allow Keyspan's 'C' firmware struct to be used unmodified */
104struct ezusb_hex_record { 108struct ezusb_hex_record {
@@ -229,15 +233,17 @@ struct ezusb_hex_record {
229#define keyspan_usa28_product_id 0x010f 233#define keyspan_usa28_product_id 0x010f
230#define keyspan_usa28x_product_id 0x0110 234#define keyspan_usa28x_product_id 0x0110
231#define keyspan_usa28xa_product_id 0x0115 235#define keyspan_usa28xa_product_id 0x0115
236#define keyspan_usa28xb_product_id 0x0110
237#define keyspan_usa28xg_product_id 0x0135
232#define keyspan_usa49w_product_id 0x010a 238#define keyspan_usa49w_product_id 0x010a
233#define keyspan_usa49wlc_product_id 0x012a 239#define keyspan_usa49wlc_product_id 0x012a
234 240#define keyspan_usa49wg_product_id 0x0131
235 241
236struct keyspan_device_details { 242struct keyspan_device_details {
237 /* product ID value */ 243 /* product ID value */
238 int product_id; 244 int product_id;
239 245
240 enum {msg_usa26, msg_usa28, msg_usa49, msg_usa90} msg_format; 246 enum {msg_usa26, msg_usa28, msg_usa49, msg_usa90, msg_usa67} msg_format;
241 247
242 /* Number of physical ports */ 248 /* Number of physical ports */
243 int num_ports; 249 int num_ports;
@@ -264,6 +270,9 @@ struct keyspan_device_details {
264 /* Endpoint used for input status */ 270 /* Endpoint used for input status */
265 int instat_endpoint; 271 int instat_endpoint;
266 272
273 /* Endpoint used for input data 49WG only */
274 int indat_endpoint;
275
267 /* Endpoint used for global control functions */ 276 /* Endpoint used for global control functions */
268 int glocont_endpoint; 277 int glocont_endpoint;
269 278
@@ -287,6 +296,7 @@ static const struct keyspan_device_details usa18x_device_details = {
287 .inack_endpoints = {0x85}, 296 .inack_endpoints = {0x85},
288 .outcont_endpoints = {0x05}, 297 .outcont_endpoints = {0x05},
289 .instat_endpoint = 0x87, 298 .instat_endpoint = 0x87,
299 .indat_endpoint = -1,
290 .glocont_endpoint = 0x07, 300 .glocont_endpoint = 0x07,
291 .calculate_baud_rate = keyspan_usa19w_calc_baud, 301 .calculate_baud_rate = keyspan_usa19w_calc_baud,
292 .baudclk = KEYSPAN_USA18X_BAUDCLK, 302 .baudclk = KEYSPAN_USA18X_BAUDCLK,
@@ -303,6 +313,7 @@ static const struct keyspan_device_details usa19_device_details = {
303 .inack_endpoints = {0x83}, 313 .inack_endpoints = {0x83},
304 .outcont_endpoints = {0x03}, 314 .outcont_endpoints = {0x03},
305 .instat_endpoint = 0x84, 315 .instat_endpoint = 0x84,
316 .indat_endpoint = -1,
306 .glocont_endpoint = -1, 317 .glocont_endpoint = -1,
307 .calculate_baud_rate = keyspan_usa19_calc_baud, 318 .calculate_baud_rate = keyspan_usa19_calc_baud,
308 .baudclk = KEYSPAN_USA19_BAUDCLK, 319 .baudclk = KEYSPAN_USA19_BAUDCLK,
@@ -319,6 +330,7 @@ static const struct keyspan_device_details usa19qi_device_details = {
319 .inack_endpoints = {0x83}, 330 .inack_endpoints = {0x83},
320 .outcont_endpoints = {0x03}, 331 .outcont_endpoints = {0x03},
321 .instat_endpoint = 0x84, 332 .instat_endpoint = 0x84,
333 .indat_endpoint = -1,
322 .glocont_endpoint = -1, 334 .glocont_endpoint = -1,
323 .calculate_baud_rate = keyspan_usa28_calc_baud, 335 .calculate_baud_rate = keyspan_usa28_calc_baud,
324 .baudclk = KEYSPAN_USA19_BAUDCLK, 336 .baudclk = KEYSPAN_USA19_BAUDCLK,
@@ -335,6 +347,7 @@ static const struct keyspan_device_details mpr_device_details = {
335 .inack_endpoints = {0x83}, 347 .inack_endpoints = {0x83},
336 .outcont_endpoints = {0x03}, 348 .outcont_endpoints = {0x03},
337 .instat_endpoint = 0x84, 349 .instat_endpoint = 0x84,
350 .indat_endpoint = -1,
338 .glocont_endpoint = -1, 351 .glocont_endpoint = -1,
339 .calculate_baud_rate = keyspan_usa28_calc_baud, 352 .calculate_baud_rate = keyspan_usa28_calc_baud,
340 .baudclk = KEYSPAN_USA19_BAUDCLK, 353 .baudclk = KEYSPAN_USA19_BAUDCLK,
@@ -351,6 +364,7 @@ static const struct keyspan_device_details usa19qw_device_details = {
351 .inack_endpoints = {0x85}, 364 .inack_endpoints = {0x85},
352 .outcont_endpoints = {0x05}, 365 .outcont_endpoints = {0x05},
353 .instat_endpoint = 0x87, 366 .instat_endpoint = 0x87,
367 .indat_endpoint = -1,
354 .glocont_endpoint = 0x07, 368 .glocont_endpoint = 0x07,
355 .calculate_baud_rate = keyspan_usa19w_calc_baud, 369 .calculate_baud_rate = keyspan_usa19w_calc_baud,
356 .baudclk = KEYSPAN_USA19W_BAUDCLK, 370 .baudclk = KEYSPAN_USA19W_BAUDCLK,
@@ -367,6 +381,7 @@ static const struct keyspan_device_details usa19w_device_details = {
367 .inack_endpoints = {0x85}, 381 .inack_endpoints = {0x85},
368 .outcont_endpoints = {0x05}, 382 .outcont_endpoints = {0x05},
369 .instat_endpoint = 0x87, 383 .instat_endpoint = 0x87,
384 .indat_endpoint = -1,
370 .glocont_endpoint = 0x07, 385 .glocont_endpoint = 0x07,
371 .calculate_baud_rate = keyspan_usa19w_calc_baud, 386 .calculate_baud_rate = keyspan_usa19w_calc_baud,
372 .baudclk = KEYSPAN_USA19W_BAUDCLK, 387 .baudclk = KEYSPAN_USA19W_BAUDCLK,
@@ -383,6 +398,7 @@ static const struct keyspan_device_details usa19hs_device_details = {
383 .inack_endpoints = {-1}, 398 .inack_endpoints = {-1},
384 .outcont_endpoints = {0x02}, 399 .outcont_endpoints = {0x02},
385 .instat_endpoint = 0x82, 400 .instat_endpoint = 0x82,
401 .indat_endpoint = -1,
386 .glocont_endpoint = -1, 402 .glocont_endpoint = -1,
387 .calculate_baud_rate = keyspan_usa19hs_calc_baud, 403 .calculate_baud_rate = keyspan_usa19hs_calc_baud,
388 .baudclk = KEYSPAN_USA19HS_BAUDCLK, 404 .baudclk = KEYSPAN_USA19HS_BAUDCLK,
@@ -399,6 +415,7 @@ static const struct keyspan_device_details usa28_device_details = {
399 .inack_endpoints = {0x85, 0x86}, 415 .inack_endpoints = {0x85, 0x86},
400 .outcont_endpoints = {0x05, 0x06}, 416 .outcont_endpoints = {0x05, 0x06},
401 .instat_endpoint = 0x87, 417 .instat_endpoint = 0x87,
418 .indat_endpoint = -1,
402 .glocont_endpoint = 0x07, 419 .glocont_endpoint = 0x07,
403 .calculate_baud_rate = keyspan_usa28_calc_baud, 420 .calculate_baud_rate = keyspan_usa28_calc_baud,
404 .baudclk = KEYSPAN_USA28_BAUDCLK, 421 .baudclk = KEYSPAN_USA28_BAUDCLK,
@@ -415,6 +432,7 @@ static const struct keyspan_device_details usa28x_device_details = {
415 .inack_endpoints = {0x85, 0x86}, 432 .inack_endpoints = {0x85, 0x86},
416 .outcont_endpoints = {0x05, 0x06}, 433 .outcont_endpoints = {0x05, 0x06},
417 .instat_endpoint = 0x87, 434 .instat_endpoint = 0x87,
435 .indat_endpoint = -1,
418 .glocont_endpoint = 0x07, 436 .glocont_endpoint = 0x07,
419 .calculate_baud_rate = keyspan_usa19w_calc_baud, 437 .calculate_baud_rate = keyspan_usa19w_calc_baud,
420 .baudclk = KEYSPAN_USA28X_BAUDCLK, 438 .baudclk = KEYSPAN_USA28X_BAUDCLK,
@@ -431,11 +449,28 @@ static const struct keyspan_device_details usa28xa_device_details = {
431 .inack_endpoints = {0x85, 0x86}, 449 .inack_endpoints = {0x85, 0x86},
432 .outcont_endpoints = {0x05, 0x06}, 450 .outcont_endpoints = {0x05, 0x06},
433 .instat_endpoint = 0x87, 451 .instat_endpoint = 0x87,
452 .indat_endpoint = -1,
434 .glocont_endpoint = 0x07, 453 .glocont_endpoint = 0x07,
435 .calculate_baud_rate = keyspan_usa19w_calc_baud, 454 .calculate_baud_rate = keyspan_usa19w_calc_baud,
436 .baudclk = KEYSPAN_USA28X_BAUDCLK, 455 .baudclk = KEYSPAN_USA28X_BAUDCLK,
437}; 456};
438 457
458static const struct keyspan_device_details usa28xg_device_details = {
459 .product_id = keyspan_usa28xg_product_id,
460 .msg_format = msg_usa67,
461 .num_ports = 2,
462 .indat_endp_flip = 0,
463 .outdat_endp_flip = 0,
464 .indat_endpoints = {0x84, 0x88},
465 .outdat_endpoints = {0x02, 0x06},
466 .inack_endpoints = {-1, -1},
467 .outcont_endpoints = {-1, -1},
468 .instat_endpoint = 0x81,
469 .indat_endpoint = -1,
470 .glocont_endpoint = 0x01,
471 .calculate_baud_rate = keyspan_usa19w_calc_baud,
472 .baudclk = KEYSPAN_USA28X_BAUDCLK,
473};
439/* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */ 474/* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */
440 475
441static const struct keyspan_device_details usa49w_device_details = { 476static const struct keyspan_device_details usa49w_device_details = {
@@ -449,6 +484,7 @@ static const struct keyspan_device_details usa49w_device_details = {
449 .inack_endpoints = {-1, -1, -1, -1}, 484 .inack_endpoints = {-1, -1, -1, -1},
450 .outcont_endpoints = {-1, -1, -1, -1}, 485 .outcont_endpoints = {-1, -1, -1, -1},
451 .instat_endpoint = 0x87, 486 .instat_endpoint = 0x87,
487 .indat_endpoint = -1,
452 .glocont_endpoint = 0x07, 488 .glocont_endpoint = 0x07,
453 .calculate_baud_rate = keyspan_usa19w_calc_baud, 489 .calculate_baud_rate = keyspan_usa19w_calc_baud,
454 .baudclk = KEYSPAN_USA49W_BAUDCLK, 490 .baudclk = KEYSPAN_USA49W_BAUDCLK,
@@ -465,11 +501,29 @@ static const struct keyspan_device_details usa49wlc_device_details = {
465 .inack_endpoints = {-1, -1, -1, -1}, 501 .inack_endpoints = {-1, -1, -1, -1},
466 .outcont_endpoints = {-1, -1, -1, -1}, 502 .outcont_endpoints = {-1, -1, -1, -1},
467 .instat_endpoint = 0x87, 503 .instat_endpoint = 0x87,
504 .indat_endpoint = -1,
468 .glocont_endpoint = 0x07, 505 .glocont_endpoint = 0x07,
469 .calculate_baud_rate = keyspan_usa19w_calc_baud, 506 .calculate_baud_rate = keyspan_usa19w_calc_baud,
470 .baudclk = KEYSPAN_USA19W_BAUDCLK, 507 .baudclk = KEYSPAN_USA19W_BAUDCLK,
471}; 508};
472 509
510static const struct keyspan_device_details usa49wg_device_details = {
511 .product_id = keyspan_usa49wg_product_id,
512 .msg_format = msg_usa49,
513 .num_ports = 4,
514 .indat_endp_flip = 0,
515 .outdat_endp_flip = 0,
516 .indat_endpoints = {-1, -1, -1, -1}, /* single 'global' data in EP */
517 .outdat_endpoints = {0x01, 0x02, 0x04, 0x06},
518 .inack_endpoints = {-1, -1, -1, -1},
519 .outcont_endpoints = {-1, -1, -1, -1},
520 .instat_endpoint = 0x81,
521 .indat_endpoint = 0x88,
522 .glocont_endpoint = 0x00, /* uses control EP */
523 .calculate_baud_rate = keyspan_usa19w_calc_baud,
524 .baudclk = KEYSPAN_USA19W_BAUDCLK,
525};
526
473static const struct keyspan_device_details *keyspan_devices[] = { 527static const struct keyspan_device_details *keyspan_devices[] = {
474 &usa18x_device_details, 528 &usa18x_device_details,
475 &usa19_device_details, 529 &usa19_device_details,
@@ -481,9 +535,11 @@ static const struct keyspan_device_details *keyspan_devices[] = {
481 &usa28_device_details, 535 &usa28_device_details,
482 &usa28x_device_details, 536 &usa28x_device_details,
483 &usa28xa_device_details, 537 &usa28xa_device_details,
538 &usa28xg_device_details,
484 /* 28xb not required as it renumerates as a 28x */ 539 /* 28xb not required as it renumerates as a 28x */
485 &usa49w_device_details, 540 &usa49w_device_details,
486 &usa49wlc_device_details, 541 &usa49wlc_device_details,
542 &usa49wg_device_details,
487 NULL, 543 NULL,
488}; 544};
489 545
@@ -510,8 +566,11 @@ static struct usb_device_id keyspan_ids_combined[] = {
510 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, 566 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
511 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, 567 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
512 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, 568 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) },
569 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) },
570 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xg_product_id) },
513 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)}, 571 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)},
514 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, 572 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)},
573 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wg_product_id)},
515 { } /* Terminating entry */ 574 { } /* Terminating entry */
516}; 575};
517 576
@@ -557,12 +616,15 @@ static struct usb_device_id keyspan_2port_ids[] = {
557 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, 616 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
558 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, 617 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
559 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, 618 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) },
619 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) },
620 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xg_product_id) },
560 { } /* Terminating entry */ 621 { } /* Terminating entry */
561}; 622};
562 623
563static struct usb_device_id keyspan_4port_ids[] = { 624static struct usb_device_id keyspan_4port_ids[] = {
564 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id) }, 625 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id) },
565 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, 626 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)},
627 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wg_product_id)},
566 { } /* Terminating entry */ 628 { } /* Terminating entry */
567}; 629};
568 630
@@ -573,7 +635,6 @@ static struct usb_serial_driver keyspan_pre_device = {
573 .name = "keyspan_no_firm", 635 .name = "keyspan_no_firm",
574 }, 636 },
575 .description = "Keyspan - (without firmware)", 637 .description = "Keyspan - (without firmware)",
576 .usb_driver = &keyspan_driver,
577 .id_table = keyspan_pre_ids, 638 .id_table = keyspan_pre_ids,
578 .num_interrupt_in = NUM_DONT_CARE, 639 .num_interrupt_in = NUM_DONT_CARE,
579 .num_bulk_in = NUM_DONT_CARE, 640 .num_bulk_in = NUM_DONT_CARE,
@@ -588,7 +649,6 @@ static struct usb_serial_driver keyspan_1port_device = {
588 .name = "keyspan_1", 649 .name = "keyspan_1",
589 }, 650 },
590 .description = "Keyspan 1 port adapter", 651 .description = "Keyspan 1 port adapter",
591 .usb_driver = &keyspan_driver,
592 .id_table = keyspan_1port_ids, 652 .id_table = keyspan_1port_ids,
593 .num_interrupt_in = NUM_DONT_CARE, 653 .num_interrupt_in = NUM_DONT_CARE,
594 .num_bulk_in = NUM_DONT_CARE, 654 .num_bulk_in = NUM_DONT_CARE,
@@ -616,7 +676,6 @@ static struct usb_serial_driver keyspan_2port_device = {
616 .name = "keyspan_2", 676 .name = "keyspan_2",
617 }, 677 },
618 .description = "Keyspan 2 port adapter", 678 .description = "Keyspan 2 port adapter",
619 .usb_driver = &keyspan_driver,
620 .id_table = keyspan_2port_ids, 679 .id_table = keyspan_2port_ids,
621 .num_interrupt_in = NUM_DONT_CARE, 680 .num_interrupt_in = NUM_DONT_CARE,
622 .num_bulk_in = NUM_DONT_CARE, 681 .num_bulk_in = NUM_DONT_CARE,
@@ -644,11 +703,10 @@ static struct usb_serial_driver keyspan_4port_device = {
644 .name = "keyspan_4", 703 .name = "keyspan_4",
645 }, 704 },
646 .description = "Keyspan 4 port adapter", 705 .description = "Keyspan 4 port adapter",
647 .usb_driver = &keyspan_driver,
648 .id_table = keyspan_4port_ids, 706 .id_table = keyspan_4port_ids,
649 .num_interrupt_in = NUM_DONT_CARE, 707 .num_interrupt_in = NUM_DONT_CARE,
650 .num_bulk_in = 5, 708 .num_bulk_in = NUM_DONT_CARE,
651 .num_bulk_out = 5, 709 .num_bulk_out = NUM_DONT_CARE,
652 .num_ports = 4, 710 .num_ports = 4,
653 .open = keyspan_open, 711 .open = keyspan_open,
654 .close = keyspan_close, 712 .close = keyspan_close,
diff --git a/drivers/usb/serial/keyspan_usa67msg.h b/drivers/usb/serial/keyspan_usa67msg.h
new file mode 100644
index 000000000000..20fa3e2f7187
--- /dev/null
+++ b/drivers/usb/serial/keyspan_usa67msg.h
@@ -0,0 +1,254 @@
1/*
2 usa67msg.h
3
4 Copyright (c) 1998-2007 InnoSys Incorporated. All Rights Reserved
5 This file is available under a BSD-style copyright
6
7 Keyspan USB Async Firmware to run on Anchor FX1
8
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are
11 met:
12
13 1. Redistributions of source code must retain this licence text
14 without modification, this list of conditions, and the following
15 disclaimer. The following copyright notice must appear immediately at
16 the beginning of all source files:
17
18 Copyright (c) 1998-2007 InnoSys Incorporated. All Rights Reserved
19
20 This file is available under a BSD-style copyright
21
22 2. Redistributions in binary form must reproduce the above copyright
23 notice, this list of conditions and the following disclaimer in the
24 documentation and/or other materials provided with the distribution.
25
26 3. The name of InnoSys Incorprated may not be used to endorse or promote
27 products derived from this software without specific prior written
28 permission.
29
30 THIS SOFTWARE IS PROVIDED BY INNOSYS CORP. ``AS IS'' AND ANY EXPRESS OR
31 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
33 NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
34 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
37 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 SUCH DAMAGE.
41
42 Fourth revision: This message format supports the USA28XG
43
44 Buffer formats for RX/TX data messages are not defined by
45 a structure, but are described here:
46
47 USB OUT (host -> USAxx, transmit) messages contain a
48 REQUEST_ACK indicator (set to 0xff to request an ACK at the
49 completion of transmit; 0x00 otherwise), followed by data:
50
51 RQSTACK DAT DAT DAT ...
52
53 with a total data length of up to 63.
54
55 USB IN (USAxx -> host, receive) messages begin with a status
56 byte in which the 0x80 bit is either:
57
58 (a) 0x80 bit clear
59 indicates that the bytes following it are all data
60 bytes:
61
62 STAT DATA DATA DATA DATA DATA ...
63
64 for a total of up to 63 DATA bytes,
65
66 or:
67
68 (b) 0x80 bit set
69 indiates that the bytes following alternate data and
70 status bytes:
71
72 STAT DATA STAT DATA STAT DATA STAT DATA ...
73
74 for a total of up to 32 DATA bytes.
75
76 The valid bits in the STAT bytes are:
77
78 OVERRUN 0x02
79 PARITY 0x04
80 FRAMING 0x08
81 BREAK 0x10
82
83 Notes:
84
85 (1) The OVERRUN bit can appear in either (a) or (b) format
86 messages, but the but the PARITY/FRAMING/BREAK bits
87 only appear in (b) format messages.
88 (2) For the host to determine the exact point at which the
89 overrun occurred (to identify the point in the data
90 stream at which the data was lost), it needs to count
91 128 characters, starting at the first character of the
92 message in which OVERRUN was reported; the lost character(s)
93 would have been received between the 128th and 129th
94 characters.
95 (3) An RX data message in which the first byte has 0x80 clear
96 serves as a "break off" indicator.
97
98 revision history:
99
100 1999feb10 add reportHskiaChanges to allow us to ignore them
101 1999feb10 add txAckThreshold for fast+loose throughput enhancement
102 1999mar30 beef up support for RX error reporting
103 1999apr14 add resetDataToggle to control message
104 2000jan04 merge with usa17msg.h
105 2000jun01 add extended BSD-style copyright text
106 2001jul05 change message format to improve OVERRUN case
107 2002jun05 update copyright date, improve comments
108 2006feb06 modify for FX1 chip
109
110*/
111
112#ifndef __USA67MSG__
113#define __USA67MSG__
114
115
116// all things called "ControlMessage" are sent on the 'control' endpoint
117
118typedef struct keyspan_usa67_portControlMessage
119{
120 u8 port; // 0 or 1 (selects port)
121 /*
122 there are three types of "commands" sent in the control message:
123
124 1. configuration changes which must be requested by setting
125 the corresponding "set" flag (and should only be requested
126 when necessary, to reduce overhead on the device):
127 */
128 u8 setClocking, // host requests baud rate be set
129 baudLo, // host does baud divisor calculation
130 baudHi, // baudHi is only used for first port (gives lower rates)
131 externalClock_txClocking,
132 // 0=internal, other=external
133
134 setLcr, // host requests lcr be set
135 lcr, // use PARITY, STOPBITS, DATABITS below
136
137 setFlowControl, // host requests flow control be set
138 ctsFlowControl, // 1=use CTS flow control, 0=don't
139 xonFlowControl, // 1=use XON/XOFF flow control, 0=don't
140 xonChar, // specified in current character format
141 xoffChar, // specified in current character format
142
143 setTxTriState_setRts,
144 // host requests TX tri-state be set
145 txTriState_rts, // 1=active (normal), 0=tristate (off)
146
147 setHskoa_setDtr,
148 // host requests HSKOA output be set
149 hskoa_dtr, // 1=on, 0=off
150
151 setPrescaler, // host requests prescalar be set (default: 13)
152 prescaler; // specified as N/8; values 8-ff are valid
153 // must be set any time internal baud rate is set;
154 // must not be set when external clocking is used
155
156 /*
157 3. configuration data which is simply used as is (no overhead,
158 but must be specified correctly in every host message).
159 */
160 u8 forwardingLength, // forward when this number of chars available
161 reportHskiaChanges_dsrFlowControl,
162 // 1=normal; 0=ignore external clock
163 // 1=use DSR flow control, 0=don't
164 txAckThreshold, // 0=not allowed, 1=normal, 2-255 deliver ACK faster
165 loopbackMode; // 0=no loopback, 1=loopback enabled
166
167 /*
168 4. commands which are flags only; these are processed in order
169 (so that, e.g., if both _txOn and _txOff flags are set, the
170 port ends in a TX_OFF state); any non-zero value is respected
171 */
172 u8 _txOn, // enable transmitting (and continue if there's data)
173 _txOff, // stop transmitting
174 txFlush, // toss outbound data
175 txBreak, // turn on break (cleared by _txOn)
176 rxOn, // turn on receiver
177 rxOff, // turn off receiver
178 rxFlush, // toss inbound data
179 rxForward, // forward all inbound data, NOW (as if fwdLen==1)
180 returnStatus, // return current status (even if it hasn't changed)
181 resetDataToggle;// reset data toggle state to DATA0
182
183} keyspan_usa67_portControlMessage;
184
185// defines for bits in lcr
186#define USA_DATABITS_5 0x00
187#define USA_DATABITS_6 0x01
188#define USA_DATABITS_7 0x02
189#define USA_DATABITS_8 0x03
190#define STOPBITS_5678_1 0x00 // 1 stop bit for all byte sizes
191#define STOPBITS_5_1p5 0x04 // 1.5 stop bits for 5-bit byte
192#define STOPBITS_678_2 0x04 // 2 stop bits for 6/7/8-bit byte
193#define USA_PARITY_NONE 0x00
194#define USA_PARITY_ODD 0x08
195#define USA_PARITY_EVEN 0x18
196#define PARITY_1 0x28
197#define PARITY_0 0x38
198
199// all things called "StatusMessage" are sent on the status endpoint
200
201typedef struct keyspan_usa67_portStatusMessage // one for each port
202{
203 u8 port, // 0=first, 1=second, other=see below
204 hskia_cts, // reports HSKIA pin
205 gpia_dcd, // reports GPIA pin
206 _txOff, // port has been disabled (by host)
207 _txXoff, // port is in XOFF state (either host or RX XOFF)
208 txAck, // indicates a TX message acknowledgement
209 rxEnabled, // as configured by rxOn/rxOff 1=on, 0=off
210 controlResponse;// 1=a control message has been processed
211} keyspan_usa67_portStatusMessage;
212
213// bits in RX data message when STAT byte is included
214#define RXERROR_OVERRUN 0x02
215#define RXERROR_PARITY 0x04
216#define RXERROR_FRAMING 0x08
217#define RXERROR_BREAK 0x10
218
219typedef struct keyspan_usa67_globalControlMessage
220{
221 u8 port, // 3
222 sendGlobalStatus, // 2=request for two status responses
223 resetStatusToggle, // 1=reset global status toggle
224 resetStatusCount; // a cycling value
225} keyspan_usa67_globalControlMessage;
226
227typedef struct keyspan_usa67_globalStatusMessage
228{
229 u8 port, // 3
230 sendGlobalStatus, // from request, decremented
231 resetStatusCount; // as in request
232} keyspan_usa67_globalStatusMessage;
233
234typedef struct keyspan_usa67_globalDebugMessage
235{
236 u8 port, // 2
237 a,
238 b,
239 c,
240 d;
241} keyspan_usa67_globalDebugMessage;
242
243// ie: the maximum length of an FX1 endpoint buffer
244#define MAX_DATA_LEN 64
245
246// update status approx. 60 times a second (16.6666 ms)
247#define STATUS_UPDATE_INTERVAL 16
248
249// status rationing tuning value (each port gets checked each n ms)
250#define STATUS_RATION 10
251
252#endif
253
254